FreeBSD ZFS
The Zettabyte File System
|
#include <sys/types.h>
#include <sys/param.h>
#include <sys/time.h>
#include <sys/systm.h>
#include <sys/sysmacros.h>
#include <sys/resource.h>
#include <sys/vfs.h>
#include <sys/vnode.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <sys/kmem.h>
#include <sys/cmn_err.h>
#include <sys/errno.h>
#include <sys/unistd.h>
#include <sys/sdt.h>
#include <sys/fs/zfs.h>
#include <sys/policy.h>
#include <sys/zfs_znode.h>
#include <sys/zfs_fuid.h>
#include <sys/zfs_acl.h>
#include <sys/zfs_dir.h>
#include <sys/zfs_vfsops.h>
#include <sys/dmu.h>
#include <sys/dnode.h>
#include <sys/zap.h>
#include <sys/sa.h>
#include <acl/acl_common.h>
Go to the source code of this file.
Defines | |
#define | ALLOW ACE_ACCESS_ALLOWED_ACE_TYPE |
#define | DENY ACE_ACCESS_DENIED_ACE_TYPE |
#define | MAX_ACE_TYPE ACE_SYSTEM_ALARM_CALLBACK_OBJECT_ACE_TYPE |
#define | MIN_ACE_TYPE ALLOW |
#define | OWNING_GROUP (ACE_GROUP|ACE_IDENTIFIER_GROUP) |
#define | EVERYONE_ALLOW_MASK |
#define | EVERYONE_DENY_MASK |
#define | OWNER_ALLOW_MASK |
#define | ZFS_CHECKED_MASKS |
#define | WRITE_MASK_DATA (ACE_WRITE_DATA|ACE_APPEND_DATA|ACE_WRITE_NAMED_ATTRS) |
#define | WRITE_MASK_ATTRS |
#define | WRITE_MASK (WRITE_MASK_DATA|WRITE_MASK_ATTRS) |
#define | OGE_CLEAR |
#define | OKAY_MASK_BITS |
#define | ALL_INHERIT |
#define | RESTRICTED_CLEAR (ACE_WRITE_ACL|ACE_WRITE_OWNER) |
#define | V4_ACL_WIDE_FLAGS |
#define | ZFS_ACL_WIDE_FLAGS |
#define | ALL_MODE_EXECS (S_IXUSR | S_IXGRP | S_IXOTH) |
Functions | |
static uint16_t | zfs_ace_v0_get_type (void *acep) |
static uint16_t | zfs_ace_v0_get_flags (void *acep) |
static uint32_t | zfs_ace_v0_get_mask (void *acep) |
static uint64_t | zfs_ace_v0_get_who (void *acep) |
static void | zfs_ace_v0_set_type (void *acep, uint16_t type) |
static void | zfs_ace_v0_set_flags (void *acep, uint16_t flags) |
static void | zfs_ace_v0_set_mask (void *acep, uint32_t mask) |
static void | zfs_ace_v0_set_who (void *acep, uint64_t who) |
static size_t | zfs_ace_v0_size (void *acep) |
static size_t | zfs_ace_v0_abstract_size (void) |
static int | zfs_ace_v0_mask_off (void) |
static int | zfs_ace_v0_data (void *acep, void **datap) |
static uint16_t | zfs_ace_fuid_get_type (void *acep) |
static uint16_t | zfs_ace_fuid_get_flags (void *acep) |
static uint32_t | zfs_ace_fuid_get_mask (void *acep) |
static uint64_t | zfs_ace_fuid_get_who (void *args) |
static void | zfs_ace_fuid_set_type (void *acep, uint16_t type) |
static void | zfs_ace_fuid_set_flags (void *acep, uint16_t flags) |
static void | zfs_ace_fuid_set_mask (void *acep, uint32_t mask) |
static void | zfs_ace_fuid_set_who (void *arg, uint64_t who) |
static size_t | zfs_ace_fuid_size (void *acep) |
static size_t | zfs_ace_fuid_abstract_size (void) |
static int | zfs_ace_fuid_mask_off (void) |
static int | zfs_ace_fuid_data (void *acep, void **datap) |
static int | zfs_acl_version (int version) |
static int | zfs_acl_version_zp (znode_t *zp) |
zfs_acl_t * | zfs_acl_alloc (int vers) |
zfs_acl_node_t * | zfs_acl_node_alloc (size_t bytes) |
static void | zfs_acl_node_free (zfs_acl_node_t *aclnode) |
static void | zfs_acl_release_nodes (zfs_acl_t *aclp) |
void | zfs_acl_free (zfs_acl_t *aclp) |
static boolean_t | zfs_acl_valid_ace_type (uint_t type, uint_t flags) |
static boolean_t | zfs_ace_valid (vtype_t obj_type, zfs_acl_t *aclp, uint16_t type, uint16_t iflags) |
static void * | zfs_acl_next_ace (zfs_acl_t *aclp, void *start, uint64_t *who, uint32_t *access_mask, uint16_t *iflags, uint16_t *type) |
static uint64_t | zfs_ace_walk (void *datap, uint64_t cookie, int aclcnt, uint16_t *flags, uint16_t *type, uint32_t *mask) |
static zfs_acl_node_t * | zfs_acl_curr_node (zfs_acl_t *aclp) |
int | zfs_copy_ace_2_fuid (zfsvfs_t *zfsvfs, vtype_t obj_type, zfs_acl_t *aclp, void *datap, zfs_ace_t *z_acl, uint64_t aclcnt, size_t *size, zfs_fuid_info_t **fuidp, cred_t *cr) |
Copy ACE to internal ZFS format. | |
static void | zfs_copy_fuid_2_ace (zfsvfs_t *zfsvfs, zfs_acl_t *aclp, cred_t *cr, void *datap, int filter) |
Copy ZFS ACEs to fixed size ace_t layout. | |
static int | zfs_copy_ace_2_oldace (vtype_t obj_type, zfs_acl_t *aclp, ace_t *acep, zfs_oldace_t *z_acl, int aclcnt, size_t *size) |
void | zfs_acl_xform (znode_t *zp, zfs_acl_t *aclp, cred_t *cr) |
Convert old ACL format to new. | |
static uint32_t | zfs_unix_to_v4 (uint32_t access_mask) |
Convert unix access mask to v4 access mask. | |
static void | zfs_set_ace (zfs_acl_t *aclp, void *acep, uint32_t access_mask, uint16_t access_type, uint64_t fuid, uint16_t entry_type) |
uint64_t | zfs_mode_compute (uint64_t fmode, zfs_acl_t *aclp, uint64_t *pflags, uint64_t fuid, uint64_t fgid) |
Determine mode of file based on ACL. | |
static int | zfs_acl_node_read (znode_t *zp, boolean_t have_lock, zfs_acl_t **aclpp, boolean_t will_modify) |
Read an external acl object. | |
void | zfs_acl_data_locator (void **dataptr, uint32_t *length, uint32_t buflen, boolean_t start, void *userdata) |
int | zfs_acl_chown_setattr (znode_t *zp) |
int | zfs_aclset_common (znode_t *zp, zfs_acl_t *aclp, cred_t *cr, dmu_tx_t *tx) |
Common code for setting ACLs. | |
static void | zfs_acl_chmod (vtype_t vtype, uint64_t mode, boolean_t trim, zfs_acl_t *aclp) |
int | zfs_acl_chmod_setattr (znode_t *zp, zfs_acl_t **aclp, uint64_t mode) |
static void | zfs_restricted_update (zfsvfs_t *zfsvfs, zfs_acl_t *aclp, void *acep) |
Strip off write_owner and write_acl. | |
static int | zfs_ace_can_use (vtype_t vtype, uint16_t acep_flags) |
Should ACE be inherited? | |
static zfs_acl_t * | zfs_acl_inherit (zfsvfs_t *zfsvfs, vtype_t vtype, zfs_acl_t *paclp, uint64_t mode, boolean_t *need_chmod) |
Inherit inheritable ACEs from parent. | |
int | zfs_acl_ids_create (znode_t *dzp, int flag, vattr_t *vap, cred_t *cr, vsecattr_t *vsecp, zfs_acl_ids_t *acl_ids) |
Create file system object initial permissions including inheritable ACEs. | |
void | zfs_acl_ids_free (zfs_acl_ids_t *acl_ids) |
Free ACL and fuid_infop, but not the acl_ids structure. | |
boolean_t | zfs_acl_ids_overquota (zfsvfs_t *zfsvfs, zfs_acl_ids_t *acl_ids) |
int | zfs_getacl (znode_t *zp, vsecattr_t *vsecp, boolean_t skipaclchk, cred_t *cr) |
Retrieve a files ACL. | |
int | zfs_vsec_2_aclp (zfsvfs_t *zfsvfs, vtype_t obj_type, vsecattr_t *vsecp, cred_t *cr, zfs_fuid_info_t **fuidp, zfs_acl_t **zaclp) |
int | zfs_setacl (znode_t *zp, vsecattr_t *vsecp, boolean_t skipaclchk, cred_t *cr) |
Set a file's ACL. | |
static int | zfs_zaccess_dataset_check (znode_t *zp, uint32_t v4_mode) |
Check accesses of interest (AoI) against attributes of the dataset such as read-only. | |
static int | zfs_zaccess_aces_check (znode_t *zp, uint32_t *working_mode, boolean_t anyaccess, cred_t *cr) |
The primary usage of this function is to loop through all of the ACEs in the znode, determining what accesses of interest (AoI) to the caller are allowed or denied. | |
boolean_t | zfs_has_access (znode_t *zp, cred_t *cr) |
Return true if any access whatsoever granted, we don't actually care what access is granted. | |
static int | zfs_zaccess_common (znode_t *zp, uint32_t v4_mode, uint32_t *working_mode, boolean_t *check_privs, boolean_t skipaclchk, cred_t *cr) |
static int | zfs_zaccess_append (znode_t *zp, uint32_t *working_mode, boolean_t *check_privs, cred_t *cr) |
int | zfs_fastaccesschk_execute (znode_t *zdp, cred_t *cr) |
int | zfs_zaccess (znode_t *zp, int mode, int flags, boolean_t skipaclchk, cred_t *cr) |
Determine whether Access should be granted/denied. | |
int | zfs_zaccess_rwx (znode_t *zp, mode_t mode, int flags, cred_t *cr) |
Translate traditional unix VREAD/VWRITE/VEXEC mode into native ACL format and call zfs_zaccess() | |
int | zfs_zaccess_unix (znode_t *zp, mode_t mode, cred_t *cr) |
Access function for secpolicy_vnode_setattr. | |
static int | zfs_delete_final_check (znode_t *zp, znode_t *dzp, mode_t available_perms, cred_t *cr) |
int | zfs_zaccess_delete (znode_t *dzp, znode_t *zp, cred_t *cr) |
Determine whether Access should be granted/deny, without consulting least priv subsystem. | |
int | zfs_zaccess_rename (znode_t *sdzp, znode_t *szp, znode_t *tdzp, znode_t *tzp, cred_t *cr) |
External ACL (Old ZPL Version) Compatibility | |
Provided for compatibility with older ZPL versions in order to determine if the file used to have an external ACL and what version of ACL previously existed on the file. Would really be nice to not need this, sigh. | |
uint64_t | zfs_external_acl (znode_t *zp) |
static int | zfs_acl_znode_info (znode_t *zp, int *aclsize, int *aclcount, zfs_acl_phys_t *aclphys) |
Determine size of ACL in bytes. | |
int | zfs_znode_acl_version (znode_t *zp) |
Variables | |
static acl_ops_t | zfs_acl_v0_ops |
static acl_ops_t | zfs_acl_fuid_ops |
#define ALL_INHERIT |
#define EVERYONE_ALLOW_MASK |
#define EVERYONE_DENY_MASK |
#define MAX_ACE_TYPE ACE_SYSTEM_ALARM_CALLBACK_OBJECT_ACE_TYPE |
#define OGE_CLEAR |
#define OKAY_MASK_BITS |
#define OWNER_ALLOW_MASK |
#define V4_ACL_WIDE_FLAGS |
#define WRITE_MASK_ATTRS |
#define WRITE_MASK_DATA (ACE_WRITE_DATA|ACE_APPEND_DATA|ACE_WRITE_NAMED_ATTRS) |
#define ZFS_ACL_WIDE_FLAGS |
#define ZFS_CHECKED_MASKS |
static int zfs_ace_can_use | ( | vtype_t | vtype, |
uint16_t | acep_flags | ||
) | [static] |
static size_t zfs_ace_fuid_abstract_size | ( | void | ) | [static] |
static int zfs_ace_fuid_data | ( | void * | acep, |
void ** | datap | ||
) | [static] |
static uint16_t zfs_ace_fuid_get_flags | ( | void * | acep | ) | [static] |
static uint32_t zfs_ace_fuid_get_mask | ( | void * | acep | ) | [static] |
static uint16_t zfs_ace_fuid_get_type | ( | void * | acep | ) | [static] |
static uint64_t zfs_ace_fuid_get_who | ( | void * | args | ) | [static] |
static void zfs_ace_fuid_set_flags | ( | void * | acep, |
uint16_t | flags | ||
) | [static] |
static void zfs_ace_fuid_set_mask | ( | void * | acep, |
uint32_t | mask | ||
) | [static] |
static void zfs_ace_fuid_set_type | ( | void * | acep, |
uint16_t | type | ||
) | [static] |
static void zfs_ace_fuid_set_who | ( | void * | arg, |
uint64_t | who | ||
) | [static] |
static int zfs_ace_v0_data | ( | void * | acep, |
void ** | datap | ||
) | [static] |
static uint16_t zfs_ace_v0_get_flags | ( | void * | acep | ) | [static] |
static uint32_t zfs_ace_v0_get_mask | ( | void * | acep | ) | [static] |
static uint16_t zfs_ace_v0_get_type | ( | void * | acep | ) | [static] |
static uint64_t zfs_ace_v0_get_who | ( | void * | acep | ) | [static] |
static void zfs_ace_v0_set_flags | ( | void * | acep, |
uint16_t | flags | ||
) | [static] |
static void zfs_ace_v0_set_mask | ( | void * | acep, |
uint32_t | mask | ||
) | [static] |
static void zfs_ace_v0_set_type | ( | void * | acep, |
uint16_t | type | ||
) | [static] |
static void zfs_ace_v0_set_who | ( | void * | acep, |
uint64_t | who | ||
) | [static] |
static boolean_t zfs_ace_valid | ( | vtype_t | obj_type, |
zfs_acl_t * | aclp, | ||
uint16_t | type, | ||
uint16_t | iflags | ||
) | [static] |
static uint64_t zfs_ace_walk | ( | void * | datap, |
uint64_t | cookie, | ||
int | aclcnt, | ||
uint16_t * | flags, | ||
uint16_t * | type, | ||
uint32_t * | mask | ||
) | [static] |
static void zfs_acl_chmod | ( | vtype_t | vtype, |
uint64_t | mode, | ||
boolean_t | trim, | ||
zfs_acl_t * | aclp | ||
) | [static] |
static zfs_acl_node_t* zfs_acl_curr_node | ( | zfs_acl_t * | aclp | ) | [static] |
void zfs_acl_data_locator | ( | void ** | dataptr, |
uint32_t * | length, | ||
uint32_t | buflen, | ||
boolean_t | start, | ||
void * | userdata | ||
) |
int zfs_acl_ids_create | ( | znode_t * | dzp, |
int | flag, | ||
vattr_t * | vap, | ||
cred_t * | cr, | ||
vsecattr_t * | vsecp, | ||
zfs_acl_ids_t * | acl_ids | ||
) |
void zfs_acl_ids_free | ( | zfs_acl_ids_t * | acl_ids | ) |
boolean_t zfs_acl_ids_overquota | ( | zfsvfs_t * | zfsvfs, |
zfs_acl_ids_t * | acl_ids | ||
) |
static void* zfs_acl_next_ace | ( | zfs_acl_t * | aclp, |
void * | start, | ||
uint64_t * | who, | ||
uint32_t * | access_mask, | ||
uint16_t * | iflags, | ||
uint16_t * | type | ||
) | [static] |
zfs_acl_node_t* zfs_acl_node_alloc | ( | size_t | bytes | ) |
static void zfs_acl_node_free | ( | zfs_acl_node_t * | aclnode | ) | [static] |
static void zfs_acl_release_nodes | ( | zfs_acl_t * | aclp | ) | [static] |
static boolean_t zfs_acl_valid_ace_type | ( | uint_t | type, |
uint_t | flags | ||
) | [static] |
static int zfs_acl_znode_info | ( | znode_t * | zp, |
int * | aclsize, | ||
int * | aclcount, | ||
zfs_acl_phys_t * | aclphys | ||
) | [static] |
int zfs_copy_ace_2_fuid | ( | zfsvfs_t * | zfsvfs, |
vtype_t | obj_type, | ||
zfs_acl_t * | aclp, | ||
void * | datap, | ||
zfs_ace_t * | z_acl, | ||
uint64_t | aclcnt, | ||
size_t * | size, | ||
zfs_fuid_info_t ** | fuidp, | ||
cred_t * | cr | ||
) |
static int zfs_copy_ace_2_oldace | ( | vtype_t | obj_type, |
zfs_acl_t * | aclp, | ||
ace_t * | acep, | ||
zfs_oldace_t * | z_acl, | ||
int | aclcnt, | ||
size_t * | size | ||
) | [static] |
int zfs_fastaccesschk_execute | ( | znode_t * | zdp, |
cred_t * | cr | ||
) |
int zfs_getacl | ( | znode_t * | zp, |
vsecattr_t * | vsecp, | ||
boolean_t | skipaclchk, | ||
cred_t * | cr | ||
) |
boolean_t zfs_has_access | ( | znode_t * | zp, |
cred_t * | cr | ||
) |
uint64_t zfs_mode_compute | ( | uint64_t | fmode, |
zfs_acl_t * | aclp, | ||
uint64_t * | pflags, | ||
uint64_t | fuid, | ||
uint64_t | fgid | ||
) |
static void zfs_set_ace | ( | zfs_acl_t * | aclp, |
void * | acep, | ||
uint32_t | access_mask, | ||
uint16_t | access_type, | ||
uint64_t | fuid, | ||
uint16_t | entry_type | ||
) | [static] |
int zfs_setacl | ( | znode_t * | zp, |
vsecattr_t * | vsecp, | ||
boolean_t | skipaclchk, | ||
cred_t * | cr | ||
) |
static uint32_t zfs_unix_to_v4 | ( | uint32_t | access_mask | ) | [static] |
int zfs_vsec_2_aclp | ( | zfsvfs_t * | zfsvfs, |
vtype_t | obj_type, | ||
vsecattr_t * | vsecp, | ||
cred_t * | cr, | ||
zfs_fuid_info_t ** | fuidp, | ||
zfs_acl_t ** | zaclp | ||
) |
int zfs_zaccess | ( | znode_t * | zp, |
int | mode, | ||
int | flags, | ||
boolean_t | skipaclchk, | ||
cred_t * | cr | ||
) |
static int zfs_zaccess_aces_check | ( | znode_t * | zp, |
uint32_t * | working_mode, | ||
boolean_t | anyaccess, | ||
cred_t * | cr | ||
) | [static] |
The primary usage of this function is to loop through all of the ACEs in the znode, determining what accesses of interest (AoI) to the caller are allowed or denied.
The AoI are expressed as bits in the working_mode parameter. As each ACE is processed, bits covered by that ACE are removed from the working_mode. This removal facilitates two things. The first is that when the working mode is empty (= 0), we know we've looked at all the AoI. The second is that the ACE interpretation rules don't allow a later ACE to undo something granted or denied by an earlier ACE. Removing the discovered access or denial enforces this rule. At the end of processing the ACEs, all AoI that were found to be denied are placed into the working_mode, giving the caller a mask of denied accesses. Returns: 0 if all AoI granted EACCESS if the denied mask is non-zero other error if abnormal failure (e.g., IO error)
A secondary usage of the function is to determine if any of the AoI are granted. If an ACE grants any access in the working_mode, we immediately short circuit out of the function. This mode is chosen by setting anyaccess to B_TRUE. The working_mode is not a denied access mask upon exit if the function is used in this manner.
static int zfs_zaccess_append | ( | znode_t * | zp, |
uint32_t * | working_mode, | ||
boolean_t * | check_privs, | ||
cred_t * | cr | ||
) | [static] |
static int zfs_zaccess_common | ( | znode_t * | zp, |
uint32_t | v4_mode, | ||
uint32_t * | working_mode, | ||
boolean_t * | check_privs, | ||
boolean_t | skipaclchk, | ||
cred_t * | cr | ||
) | [static] |
static int zfs_zaccess_dataset_check | ( | znode_t * | zp, |
uint32_t | v4_mode | ||
) | [static] |
Determine whether Access should be granted/deny, without consulting least priv subsystem.
The following chart is the recommended NFSv4 enforcement for ability to delete an object.
------------------------------------------------------- | Parent Dir | Target Object Permissions | | permissions | | ------------------------------------------------------- | | ACL Allows | ACL Denies| Delete | | | Delete | Delete | unspecified| ------------------------------------------------------- | ACL Allows | Permit | Permit | Permit | | DELETE_CHILD | | ------------------------------------------------------- | ACL Denies | Permit | Deny | Deny | | DELETE_CHILD | | | | ------------------------------------------------------- | ACL specifies | | | | | only allow | Permit | Permit | Permit | | write and | | | | | execute | | | | ------------------------------------------------------- | ACL denies | | | | | write and | Permit | Deny | Deny | | execute | | | | ------------------------------------------------------- ^ | No search privilege, can't even look up file?
int zfs_zaccess_rwx | ( | znode_t * | zp, |
mode_t | mode, | ||
int | flags, | ||
cred_t * | cr | ||
) |
Translate traditional unix VREAD/VWRITE/VEXEC mode into native ACL format and call zfs_zaccess()
int zfs_zaccess_unix | ( | znode_t * | zp, |
mode_t | mode, | ||
cred_t * | cr | ||
) |
acl_ops_t zfs_acl_fuid_ops [static] |
acl_ops_t zfs_acl_v0_ops [static] |