diff options
author | Jeremy Allison <jra@samba.org> | 2002-03-11 23:50:56 +0000 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2002-03-11 23:50:56 +0000 |
commit | 8098b5d2fd75514664547e22a06bd5fc1aea357d (patch) | |
tree | da1eca7152d547fcc99e8525a1798574e88adb94 | |
parent | 3e616cf09cde59c5288c0c5856faec46d039eafe (diff) | |
download | samba-8098b5d2fd75514664547e22a06bd5fc1aea357d.tar.gz samba-8098b5d2fd75514664547e22a06bd5fc1aea357d.tar.xz samba-8098b5d2fd75514664547e22a06bd5fc1aea357d.zip |
Added POSIX ACL layer into the vfs.
Jeremy.
-rw-r--r-- | source/include/proto.h | 28 | ||||
-rw-r--r-- | source/include/smb.h | 2 | ||||
-rw-r--r-- | source/include/vfs.h | 27 | ||||
-rw-r--r-- | source/smbd/open.c | 2 | ||||
-rw-r--r-- | source/smbd/posix_acls.c | 130 | ||||
-rw-r--r-- | source/smbd/vfs-wrap.c | 116 | ||||
-rw-r--r-- | source/smbd/vfs.c | 92 |
7 files changed, 323 insertions, 74 deletions
diff --git a/source/include/proto.h b/source/include/proto.h index c13ddd0908f..63f1a9b6ab4 100644 --- a/source/include/proto.h +++ b/source/include/proto.h @@ -4395,9 +4395,9 @@ int reply_pipe_close(connection_struct *conn, char *inbuf,char *outbuf); size_t get_nt_acl(files_struct *fsp, SEC_DESC **ppdesc); BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd); -int chmod_acl(const char *name, mode_t mode); -int fchmod_acl(int fd, mode_t mode); -BOOL directory_has_default_acl(const char *fname); +int chmod_acl(connection_struct *conn, const char *name, mode_t mode); +int fchmod_acl(files_struct *fsp, int fd, mode_t mode); +BOOL directory_has_default_acl(connection_struct *conn, const char *fname); /*The following definitions come from smbd/process.c */ @@ -4628,6 +4628,28 @@ BOOL vfswrap_fset_nt_acl(files_struct *fsp, int fd, uint32 security_info_sent, S BOOL vfswrap_set_nt_acl(files_struct *fsp, char *name, uint32 security_info_sent, SEC_DESC *psd); int vfswrap_chmod_acl(connection_struct *conn, char *name, mode_t mode); int vfswrap_fchmod_acl(files_struct *fsp, int fd, mode_t mode); +int vfswrap_sys_acl_get_entry(struct connection_struct *conn, SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p); +int vfswrap_sys_acl_get_tag_type(struct connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p); +int vfswrap_sys_acl_get_permset(struct connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p); +void * vfswrap_sys_acl_get_qualifier(struct connection_struct *conn, SMB_ACL_ENTRY_T entry_d); +SMB_ACL_T vfswrap_sys_acl_get_file(struct connection_struct *conn, const char *path_p, SMB_ACL_TYPE_T type); +SMB_ACL_T vfswrap_sys_acl_get_fd(struct files_struct *fsp, int fd); +int vfswrap_sys_acl_clear_perms(struct connection_struct *conn, SMB_ACL_PERMSET_T permset); +int vfswrap_sys_acl_add_perm(struct connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm); +char * vfswrap_sys_acl_to_text(struct connection_struct *conn, SMB_ACL_T theacl, ssize_t *plen); +SMB_ACL_T vfswrap_sys_acl_init(struct connection_struct *conn, int count); +int vfswrap_sys_acl_create_entry(struct connection_struct *conn, SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry); +int vfswrap_sys_acl_set_tag_type(struct connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype); +int vfswrap_sys_acl_set_qualifier(struct connection_struct *conn, SMB_ACL_ENTRY_T entry, void *qual); +int vfswrap_sys_acl_set_permset(struct connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset); +int vfswrap_sys_acl_valid(struct connection_struct *conn, SMB_ACL_T theacl ); +int vfswrap_sys_acl_set_file(struct connection_struct *conn, const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl); +int vfswrap_sys_acl_set_fd(struct files_struct *fsp, int fd, SMB_ACL_T theacl); +int vfswrap_sys_acl_delete_def_file(struct connection_struct *conn, const char *path); +int vfswrap_sys_acl_get_perm(struct connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm); +int vfswrap_sys_acl_free_text(struct connection_struct *conn, char *text); +int vfswrap_sys_acl_free_acl(struct connection_struct *conn, SMB_ACL_T posix_acl); +int vfswrap_sys_acl_free_qualifier(struct connection_struct *conn, void *qualifier, SMB_ACL_TAG_T tagtype); /*The following definitions come from smbwrapper/realcalls.c */ diff --git a/source/include/smb.h b/source/include/smb.h index cf5efe2c7a1..28e58970014 100644 --- a/source/include/smb.h +++ b/source/include/smb.h @@ -438,6 +438,7 @@ typedef struct /* Include VFS stuff */ +#include "smb_acls.h" #include "vfs.h" typedef struct connection_struct @@ -1649,6 +1650,5 @@ struct unix_error_map { #define SAFE_NETBIOS_CHARS ". -_" #include "nsswitch/winbindd_nss.h" -#include "smb_acls.h" #endif /* _SMB_H */ diff --git a/source/include/vfs.h b/source/include/vfs.h index ee4bdea6022..71c70e0e622 100644 --- a/source/include/vfs.h +++ b/source/include/vfs.h @@ -40,7 +40,8 @@ */ /* Changed to version 2 for CIFS UNIX extensions (mknod and link added). JRA. */ -#define SMB_VFS_INTERFACE_VERSION 2 +/* Changed to version 3 for POSIX acl extensions. JRA. */ +#define SMB_VFS_INTERFACE_VERSION 3 /* VFS operations structure */ @@ -104,7 +105,29 @@ struct vfs_ops { int (*chmod_acl)(struct connection_struct *conn, char *name, mode_t mode); int (*fchmod_acl)(struct files_struct *fsp, int fd, mode_t mode); - + + int (*sys_acl_get_entry)(struct connection_struct *conn, SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p); + int (*sys_acl_get_tag_type)(struct connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p); + int (*sys_acl_get_permset)(struct connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p); + void * (*sys_acl_get_qualifier)(struct connection_struct *conn, SMB_ACL_ENTRY_T entry_d); + SMB_ACL_T (*sys_acl_get_file)(struct connection_struct *conn, const char *path_p, SMB_ACL_TYPE_T type); + SMB_ACL_T (*sys_acl_get_fd)(struct files_struct *fsp, int fd); + int (*sys_acl_clear_perms)(struct connection_struct *conn, SMB_ACL_PERMSET_T permset); + int (*sys_acl_add_perm)(struct connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm); + char * (*sys_acl_to_text)(struct connection_struct *conn, SMB_ACL_T theacl, ssize_t *plen); + SMB_ACL_T (*sys_acl_init)(struct connection_struct *conn, int count); + int (*sys_acl_create_entry)(struct connection_struct *conn, SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry); + int (*sys_acl_set_tag_type)(struct connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype); + int (*sys_acl_set_qualifier)(struct connection_struct *conn, SMB_ACL_ENTRY_T entry, void *qual); + int (*sys_acl_set_permset)(struct connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset); + int (*sys_acl_valid)(struct connection_struct *conn, SMB_ACL_T theacl ); + int (*sys_acl_set_file)(struct connection_struct *conn, const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl); + int (*sys_acl_set_fd)(struct files_struct *fsp, int fd, SMB_ACL_T theacl); + int (*sys_acl_delete_def_file)(struct connection_struct *conn, const char *path); + int (*sys_acl_get_perm)(struct connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm); + int (*sys_acl_free_text)(struct connection_struct *conn, char *text); + int (*sys_acl_free_acl)(struct connection_struct *conn, SMB_ACL_T posix_acl); + int (*sys_acl_free_qualifier)(struct connection_struct *conn, void *qualifier, SMB_ACL_TAG_T tagtype); }; struct vfs_options { diff --git a/source/smbd/open.c b/source/smbd/open.c index 8b895bc4626..f264d8f622a 100644 --- a/source/smbd/open.c +++ b/source/smbd/open.c @@ -815,7 +815,7 @@ flags=0x%X flags2=0x%X mode=0%o returned %d\n", */ if ((flags2 & O_CREAT) && lp_inherit_acls(SNUM(conn)) && - (def_acl = directory_has_default_acl(dos_to_unix(parent_dirname(fname),False)))) + (def_acl = directory_has_default_acl(conn, dos_to_unix(parent_dirname(fname),False)))) mode = 0777; DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o\n", diff --git a/source/smbd/posix_acls.c b/source/smbd/posix_acls.c index e8a1820db9d..6d072dd753d 100644 --- a/source/smbd/posix_acls.c +++ b/source/smbd/posix_acls.c @@ -154,13 +154,13 @@ static void print_canon_ace_list(const char *name, canon_ace *ace_list) Map POSIX ACL perms to canon_ace permissions (a mode_t containing only S_(R|W|X)USR bits). ****************************************************************************/ -static mode_t convert_permset_to_mode_t(SMB_ACL_PERMSET_T permset) +static mode_t convert_permset_to_mode_t(connection_struct *conn, SMB_ACL_PERMSET_T permset) { mode_t ret = 0; - ret |= (sys_acl_get_perm(permset, SMB_ACL_READ) ? S_IRUSR : 0); - ret |= (sys_acl_get_perm(permset, SMB_ACL_WRITE) ? S_IWUSR : 0); - ret |= (sys_acl_get_perm(permset, SMB_ACL_EXECUTE) ? S_IXUSR : 0); + ret |= (conn->vfs_ops.sys_acl_get_perm(conn, permset, SMB_ACL_READ) ? S_IRUSR : 0); + ret |= (conn->vfs_ops.sys_acl_get_perm(conn, permset, SMB_ACL_WRITE) ? S_IWUSR : 0); + ret |= (conn->vfs_ops.sys_acl_get_perm(conn, permset, SMB_ACL_EXECUTE) ? S_IXUSR : 0); return ret; } @@ -188,20 +188,20 @@ static mode_t unix_perms_to_acl_perms(mode_t mode, int r_mask, int w_mask, int x an SMB_ACL_PERMSET_T. ****************************************************************************/ -static int map_acl_perms_to_permset(mode_t mode, SMB_ACL_PERMSET_T *p_permset) +static int map_acl_perms_to_permset(connection_struct *conn, mode_t mode, SMB_ACL_PERMSET_T *p_permset) { - if (sys_acl_clear_perms(*p_permset) == -1) + if (conn->vfs_ops.sys_acl_clear_perms(conn, *p_permset) == -1) return -1; if (mode & S_IRUSR) { - if (sys_acl_add_perm(*p_permset, SMB_ACL_READ) == -1) + if (conn->vfs_ops.sys_acl_add_perm(conn, *p_permset, SMB_ACL_READ) == -1) return -1; } if (mode & S_IWUSR) { - if (sys_acl_add_perm(*p_permset, SMB_ACL_WRITE) == -1) + if (conn->vfs_ops.sys_acl_add_perm(conn, *p_permset, SMB_ACL_WRITE) == -1) return -1; } if (mode & S_IXUSR) { - if (sys_acl_add_perm(*p_permset, SMB_ACL_EXECUTE) == -1) + if (conn->vfs_ops.sys_acl_add_perm(conn, *p_permset, SMB_ACL_EXECUTE) == -1) return -1; } return 0; @@ -1425,6 +1425,7 @@ static canon_ace *canonicalise_acl( files_struct *fsp, SMB_ACL_T posix_acl, SMB_ DOM_SID *powner, DOM_SID *pgroup) { extern DOM_SID global_sid_World; + connection_struct *conn = fsp->conn; mode_t acl_mask = (S_IRUSR|S_IWUSR|S_IXUSR); canon_ace *list_head = NULL; canon_ace *ace = NULL; @@ -1433,7 +1434,7 @@ static canon_ace *canonicalise_acl( files_struct *fsp, SMB_ACL_T posix_acl, SMB_ SMB_ACL_ENTRY_T entry; size_t ace_count; - while ( posix_acl && (sys_acl_get_entry(posix_acl, entry_id, &entry) == 1)) { + while ( posix_acl && (conn->vfs_ops.sys_acl_get_entry(conn, posix_acl, entry_id, &entry) == 1)) { SMB_ACL_TAG_T tagtype; SMB_ACL_PERMSET_T permset; DOM_SID sid; @@ -1445,10 +1446,10 @@ static canon_ace *canonicalise_acl( files_struct *fsp, SMB_ACL_T posix_acl, SMB_ entry_id = SMB_ACL_NEXT_ENTRY; /* Is this a MASK entry ? */ - if (sys_acl_get_tag_type(entry, &tagtype) == -1) + if (conn->vfs_ops.sys_acl_get_tag_type(conn, entry, &tagtype) == -1) continue; - if (sys_acl_get_permset(entry, &permset) == -1) + if (conn->vfs_ops.sys_acl_get_permset(conn, entry, &permset) == -1) continue; /* Decide which SID to use based on the ACL type. */ @@ -1461,7 +1462,7 @@ static canon_ace *canonicalise_acl( files_struct *fsp, SMB_ACL_T posix_acl, SMB_ break; case SMB_ACL_USER: { - uid_t *puid = (uid_t *)sys_acl_get_qualifier(entry); + uid_t *puid = (uid_t *)conn->vfs_ops.sys_acl_get_qualifier(conn, entry); if (puid == NULL) { DEBUG(0,("canonicalise_acl: Failed to get uid.\n")); continue; @@ -1469,7 +1470,7 @@ static canon_ace *canonicalise_acl( files_struct *fsp, SMB_ACL_T posix_acl, SMB_ uid_to_sid( &sid, *puid); unix_ug.uid = *puid; owner_type = UID_ACE; - sys_acl_free_qualifier((void *)puid,tagtype); + conn->vfs_ops.sys_acl_free_qualifier(conn, (void *)puid,tagtype); break; } case SMB_ACL_GROUP_OBJ: @@ -1480,7 +1481,7 @@ static canon_ace *canonicalise_acl( files_struct *fsp, SMB_ACL_T posix_acl, SMB_ break; case SMB_ACL_GROUP: { - gid_t *pgid = (gid_t *)sys_acl_get_qualifier(entry); + gid_t *pgid = (gid_t *)conn->vfs_ops.sys_acl_get_qualifier(conn, entry); if (pgid == NULL) { DEBUG(0,("canonicalise_acl: Failed to get gid.\n")); continue; @@ -1488,11 +1489,11 @@ static canon_ace *canonicalise_acl( files_struct *fsp, SMB_ACL_T posix_acl, SMB_ gid_to_sid( &sid, *pgid); unix_ug.gid = *pgid; owner_type = GID_ACE; - sys_acl_free_qualifier((void *)pgid,tagtype); + conn->vfs_ops.sys_acl_free_qualifier(conn, (void *)pgid,tagtype); break; } case SMB_ACL_MASK: - acl_mask = convert_permset_to_mode_t(permset); + acl_mask = convert_permset_to_mode_t(conn, permset); continue; /* Don't count the mask as an entry. */ case SMB_ACL_OTHER: /* Use the Everyone SID */ @@ -1514,7 +1515,7 @@ static canon_ace *canonicalise_acl( files_struct *fsp, SMB_ACL_T posix_acl, SMB_ ZERO_STRUCTP(ace); ace->type = tagtype; - ace->perms = convert_permset_to_mode_t(permset); + ace->perms = convert_permset_to_mode_t(conn, permset); ace->attr = ALLOW_ACE; ace->trustee = sid; ace->unix_ug = unix_ug; @@ -1571,8 +1572,9 @@ static canon_ace *canonicalise_acl( files_struct *fsp, SMB_ACL_T posix_acl, SMB_ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL default_ace, BOOL *pacl_set_support) { + connection_struct *conn = fsp->conn; BOOL ret = False; - SMB_ACL_T the_acl = sys_acl_init((int)count_canon_ace_list(the_ace) + 1); + SMB_ACL_T the_acl = conn->vfs_ops.sys_acl_init(conn, (int)count_canon_ace_list(the_ace) + 1); canon_ace *p_ace; int i; SMB_ACL_ENTRY_T mask_entry; @@ -1601,7 +1603,7 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau * Get the entry for this ACE. */ - if (sys_acl_create_entry( &the_acl, &the_entry) == -1) { + if (conn->vfs_ops.sys_acl_create_entry(conn, &the_acl, &the_entry) == -1) { DEBUG(0,("set_canon_ace_list: Failed to create entry %d. (%s)\n", i, strerror(errno) )); goto done; @@ -1622,7 +1624,7 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau * First tell the entry what type of ACE this is. */ - if (sys_acl_set_tag_type(the_entry, p_ace->type) == -1) { + if (conn->vfs_ops.sys_acl_set_tag_type(conn, the_entry, p_ace->type) == -1) { DEBUG(0,("set_canon_ace_list: Failed to set tag type on entry %d. (%s)\n", i, strerror(errno) )); goto done; @@ -1634,7 +1636,7 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau */ if ((p_ace->type == SMB_ACL_USER) || (p_ace->type == SMB_ACL_GROUP)) { - if (sys_acl_set_qualifier(the_entry,(void *)&p_ace->unix_ug.uid) == -1) { + if (conn->vfs_ops.sys_acl_set_qualifier(conn, the_entry,(void *)&p_ace->unix_ug.uid) == -1) { DEBUG(0,("set_canon_ace_list: Failed to set qualifier on entry %d. (%s)\n", i, strerror(errno) )); goto done; @@ -1645,13 +1647,13 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau * Convert the mode_t perms in the canon_ace to a POSIX permset. */ - if (sys_acl_get_permset(the_entry, &the_permset) == -1) { + if (conn->vfs_ops.sys_acl_get_permset(conn, the_entry, &the_permset) == -1) { DEBUG(0,("set_canon_ace_list: Failed to get permset on entry %d. (%s)\n", i, strerror(errno) )); goto done; } - if (map_acl_perms_to_permset(p_ace->perms, &the_permset) == -1) { + if (map_acl_perms_to_permset(conn, p_ace->perms, &the_permset) == -1) { DEBUG(0,("set_canon_ace_list: Failed to create permset for mode (%u) on entry %d. (%s)\n", (unsigned int)p_ace->perms, i, strerror(errno) )); goto done; @@ -1661,7 +1663,7 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau * ..and apply them to the entry. */ - if (sys_acl_set_permset(the_entry, the_permset) == -1) { + if (conn->vfs_ops.sys_acl_set_permset(conn, the_entry, the_permset) == -1) { DEBUG(0,("set_canon_ace_list: Failed to add permset on entry %d. (%s)\n", i, strerror(errno) )); goto done; @@ -1675,27 +1677,27 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau * Add in a mask of rwx. */ - if (sys_acl_create_entry( &the_acl, &mask_entry) == -1) { + if (conn->vfs_ops.sys_acl_create_entry( conn, &the_acl, &mask_entry) == -1) { DEBUG(0,("set_canon_ace_list: Failed to create mask entry. (%s)\n", strerror(errno) )); goto done; } - if (sys_acl_set_tag_type(mask_entry, SMB_ACL_MASK) == -1) { + if (conn->vfs_ops.sys_acl_set_tag_type(conn, mask_entry, SMB_ACL_MASK) == -1) { DEBUG(0,("set_canon_ace_list: Failed to set tag type on mask entry. (%s)\n",strerror(errno) )); goto done; } - if (sys_acl_get_permset(mask_entry, &mask_permset) == -1) { + if (conn->vfs_ops.sys_acl_get_permset(conn, mask_entry, &mask_permset) == -1) { DEBUG(0,("set_canon_ace_list: Failed to get mask permset. (%s)\n", strerror(errno) )); goto done; } - if (map_acl_perms_to_permset(S_IRUSR|S_IWUSR|S_IXUSR, &mask_permset) == -1) { + if (map_acl_perms_to_permset(conn, S_IRUSR|S_IWUSR|S_IXUSR, &mask_permset) == -1) { DEBUG(0,("set_canon_ace_list: Failed to create mask permset. (%s)\n", strerror(errno) )); goto done; } - if (sys_acl_set_permset(mask_entry, mask_permset) == -1) { + if (conn->vfs_ops.sys_acl_set_permset(conn, mask_entry, mask_permset) == -1) { DEBUG(0,("set_canon_ace_list: Failed to add mask permset. (%s)\n", strerror(errno) )); goto done; } @@ -1704,7 +1706,7 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau * Check if the ACL is valid. */ - if (sys_acl_valid(the_acl) == -1) { + if (conn->vfs_ops.sys_acl_valid(conn, the_acl) == -1) { DEBUG(0,("set_canon_ace_list: ACL type (%s) is invalid for set (%s).\n", the_acl_type == SMB_ACL_TYPE_DEFAULT ? "directory default" : "file", strerror(errno) )); @@ -1716,27 +1718,27 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau */ if(default_ace || fsp->is_directory || fsp->fd == -1) { - if (sys_acl_set_file(dos_to_unix(fsp->fsp_name,False), the_acl_type, the_acl) == -1) { + if (conn->vfs_ops.sys_acl_set_file(conn, dos_to_unix(fsp->fsp_name,False), the_acl_type, the_acl) == -1) { /* * Some systems allow all the above calls and only fail with no ACL support * when attempting to apply the acl. HPUX with HFS is an example of this. JRA. */ if (errno == ENOSYS) *pacl_set_support = False; - DEBUG(2,("set_canon_ace_list: sys_acl_set_file type %s failed for file %s (%s).\n", + DEBUG(2,("set_canon_ace_list: conn->vfs_ops.sys_acl_set_file type %s failed for file %s (%s).\n", the_acl_type == SMB_ACL_TYPE_DEFAULT ? "directory default" : "file", fsp->fsp_name, strerror(errno) )); goto done; } } else { - if (sys_acl_set_fd(fsp->fd, the_acl) == -1) { + if (conn->vfs_ops.sys_acl_set_fd(fsp, fsp->fd, the_acl) == -1) { /* * Some systems allow all the above calls and only fail with no ACL support * when attempting to apply the acl. HPUX with HFS is an example of this. JRA. */ if (errno == ENOSYS) *pacl_set_support = False; - DEBUG(2,("set_canon_ace_list: sys_acl_set_file failed for file %s (%s).\n", + DEBUG(2,("set_canon_ace_list: conn->vfs_ops.sys_acl_set_file failed for file %s (%s).\n", fsp->fsp_name, strerror(errno) )); goto done; } @@ -1747,7 +1749,7 @@ static BOOL set_canon_ace_list(files_struct *fsp, canon_ace *the_ace, BOOL defau done: if (the_acl != NULL) - sys_acl_free_acl(the_acl); + conn->vfs_ops.sys_acl_free_acl(conn, the_acl); return ret; } @@ -1846,6 +1848,7 @@ static int nt_ace_comp( SEC_ACE *a1, SEC_ACE *a2) size_t get_nt_acl(files_struct *fsp, SEC_DESC **ppdesc) { + connection_struct *conn = fsp->conn; SMB_STRUCT_STAT sbuf; SEC_ACE *nt_ace_list = NULL; DOM_SID owner_sid; @@ -1874,14 +1877,14 @@ size_t get_nt_acl(files_struct *fsp, SEC_DESC **ppdesc) * Get the ACL from the path. */ - posix_acl = sys_acl_get_file( dos_to_unix(fsp->fsp_name, False), SMB_ACL_TYPE_ACCESS); + posix_acl = conn->vfs_ops.sys_acl_get_file( conn, dos_to_unix(fsp->fsp_name, False), SMB_ACL_TYPE_ACCESS); /* * If it's a directory get the default POSIX ACL. */ if(fsp->is_directory) - dir_acl = sys_acl_get_file( dos_to_unix(fsp->fsp_name, False), SMB_ACL_TYPE_DEFAULT); + dir_acl = conn->vfs_ops.sys_acl_get_file( conn, dos_to_unix(fsp->fsp_name, False), SMB_ACL_TYPE_DEFAULT); } else { @@ -1892,7 +1895,7 @@ size_t get_nt_acl(files_struct *fsp, SEC_DESC **ppdesc) /* * Get the ACL from the fd. */ - posix_acl = sys_acl_get_fd(fsp->fd); + posix_acl = conn->vfs_ops.sys_acl_get_fd(fsp, fsp->fd); } DEBUG(5,("get_nt_acl : file ACL %s, directory ACL %s\n", @@ -1983,9 +1986,9 @@ size_t get_nt_acl(files_struct *fsp, SEC_DESC **ppdesc) done: if (posix_acl) - sys_acl_free_acl(posix_acl); + conn->vfs_ops.sys_acl_free_acl(conn, posix_acl); if (dir_acl) - sys_acl_free_acl(dir_acl); + conn->vfs_ops.sys_acl_free_acl(conn, dir_acl); free_canon_ace_list(file_ace); free_canon_ace_list(dir_ace); SAFE_FREE(nt_ace_list); @@ -2138,8 +2141,8 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) * No default ACL - delete one if it exists. */ - if (sys_acl_delete_def_file(dos_to_unix(fsp->fsp_name,False)) == -1) { - DEBUG(3,("set_nt_acl: sys_acl_delete_def_file failed (%s)\n", strerror(errno))); + if (conn->vfs_ops.sys_acl_delete_def_file(conn, dos_to_unix(fsp->fsp_name,False)) == -1) { + DEBUG(3,("set_nt_acl: conn->vfs_ops.sys_acl_delete_def_file failed (%s)\n", strerror(errno))); free_canon_ace_list(file_ace_list); return False; } @@ -2188,13 +2191,13 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) and set the mask to rwx. Needed to preserve complex ACLs set by NT. ****************************************************************************/ -static int chmod_acl_internals( SMB_ACL_T posix_acl, mode_t mode) +static int chmod_acl_internals( connection_struct *conn, SMB_ACL_T posix_acl, mode_t mode) { int entry_id = SMB_ACL_FIRST_ENTRY; SMB_ACL_ENTRY_T entry; int num_entries = 0; - while ( sys_acl_get_entry(posix_acl, entry_id, &entry) == 1) { + while ( conn->vfs_ops.sys_acl_get_entry(conn, posix_acl, entry_id, &entry) == 1) { SMB_ACL_TAG_T tagtype; SMB_ACL_PERMSET_T permset; mode_t perms; @@ -2203,10 +2206,10 @@ static int chmod_acl_internals( SMB_ACL_T posix_acl, mode_t mode) if (entry_id == SMB_ACL_FIRST_ENTRY) entry_id = SMB_ACL_NEXT_ENTRY; - if (sys_acl_get_tag_type(entry, &tagtype) == -1) + if (conn->vfs_ops.sys_acl_get_tag_type(conn, entry, &tagtype) == -1) return -1; - if (sys_acl_get_permset(entry, &permset) == -1) + if (conn->vfs_ops.sys_acl_get_permset(conn, entry, &permset) == -1) return -1; num_entries++; @@ -2228,10 +2231,10 @@ static int chmod_acl_internals( SMB_ACL_T posix_acl, mode_t mode) continue; } - if (map_acl_perms_to_permset(perms, &permset) == -1) + if (map_acl_perms_to_permset(conn, perms, &permset) == -1) return -1; - if (sys_acl_set_permset(entry, permset) == -1) + if (conn->vfs_ops.sys_acl_set_permset(conn, entry, permset) == -1) return -1; } @@ -2252,22 +2255,22 @@ static int chmod_acl_internals( SMB_ACL_T posix_acl, mode_t mode) Note that name is in UNIX character set. ****************************************************************************/ -int chmod_acl(const char *name, mode_t mode) +int chmod_acl(connection_struct *conn, const char *name, mode_t mode) { SMB_ACL_T posix_acl = NULL; int ret = -1; - if ((posix_acl = sys_acl_get_file(name, SMB_ACL_TYPE_ACCESS)) == NULL) + if ((posix_acl = conn->vfs_ops.sys_acl_get_file(conn, name, SMB_ACL_TYPE_ACCESS)) == NULL) return -1; - if ((ret = chmod_acl_internals(posix_acl, mode)) == -1) + if ((ret = chmod_acl_internals(conn, posix_acl, mode)) == -1) goto done; - ret = sys_acl_set_file(name, SMB_ACL_TYPE_ACCESS, posix_acl); + ret = conn->vfs_ops.sys_acl_set_file(conn, name, SMB_ACL_TYPE_ACCESS, posix_acl); done: - sys_acl_free_acl(posix_acl); + conn->vfs_ops.sys_acl_free_acl(conn, posix_acl); return ret; } @@ -2276,34 +2279,35 @@ int chmod_acl(const char *name, mode_t mode) and set the mask to rwx. Needed to preserve complex ACLs set by NT. ****************************************************************************/ -int fchmod_acl(int fd, mode_t mode) +int fchmod_acl(files_struct *fsp, int fd, mode_t mode) { + connection_struct *conn = fsp->conn; SMB_ACL_T posix_acl = NULL; int ret = -1; - if ((posix_acl = sys_acl_get_fd(fd)) == NULL) + if ((posix_acl = conn->vfs_ops.sys_acl_get_fd(fsp, fd)) == NULL) return -1; - if ((ret = chmod_acl_internals(posix_acl, mode)) == -1) + if ((ret = chmod_acl_internals(conn, posix_acl, mode)) == -1) goto done; - ret = sys_acl_set_fd(fd, posix_acl); + ret = conn->vfs_ops.sys_acl_set_fd(fsp, fd, posix_acl); done: - sys_acl_free_acl(posix_acl); + conn->vfs_ops.sys_acl_free_acl(conn, posix_acl); return ret; } -BOOL directory_has_default_acl(const char *fname) +BOOL directory_has_default_acl(connection_struct *conn, const char *fname) { - SMB_ACL_T dir_acl = sys_acl_get_file( fname, SMB_ACL_TYPE_DEFAULT); + SMB_ACL_T dir_acl = conn->vfs_ops.sys_acl_get_file( conn, fname, SMB_ACL_TYPE_DEFAULT); BOOL has_acl = False; SMB_ACL_ENTRY_T entry; - if (dir_acl != NULL && (sys_acl_get_entry(dir_acl, SMB_ACL_FIRST_ENTRY, &entry) == 1)) + if (dir_acl != NULL && (conn->vfs_ops.sys_acl_get_entry(conn, dir_acl, SMB_ACL_FIRST_ENTRY, &entry) == 1)) has_acl = True; - sys_acl_free_acl(dir_acl); + conn->vfs_ops.sys_acl_free_acl(conn, dir_acl); return has_acl; } diff --git a/source/smbd/vfs-wrap.c b/source/smbd/vfs-wrap.c index 9d1c5380fbf..c2345f4a503 100644 --- a/source/smbd/vfs-wrap.c +++ b/source/smbd/vfs-wrap.c @@ -106,7 +106,7 @@ int vfswrap_mkdir(connection_struct *conn, char *path, mode_t mode) } #endif - if (lp_inherit_acls(SNUM(conn)) && (has_dacl = directory_has_default_acl(parent_dirname(path)))) + if (lp_inherit_acls(SNUM(conn)) && (has_dacl = directory_has_default_acl(conn, parent_dirname(path)))) mode = 0777; result = mkdir(path, mode); @@ -841,7 +841,7 @@ int vfswrap_chmod_acl(connection_struct *conn, char *name, mode_t mode) int result; START_PROFILE(chmod_acl); - result = chmod_acl(name, mode); + result = chmod_acl(conn, name, mode); END_PROFILE(chmod_acl); return result; } @@ -851,7 +851,117 @@ int vfswrap_fchmod_acl(files_struct *fsp, int fd, mode_t mode) int result; START_PROFILE(fchmod_acl); - result = fchmod_acl(fd, mode); + result = fchmod_acl(fsp, fd, mode); END_PROFILE(fchmod_acl); return result; } + +int vfswrap_sys_acl_get_entry(struct connection_struct *conn, SMB_ACL_T theacl, int entry_id, SMB_ACL_ENTRY_T *entry_p) +{ + return sys_acl_get_entry(theacl, entry_id, entry_p); +} + +int vfswrap_sys_acl_get_tag_type(struct connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p) +{ + return sys_acl_get_tag_type(entry_d, tag_type_p); +} + +int vfswrap_sys_acl_get_permset(struct connection_struct *conn, SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p) +{ + return sys_acl_get_permset(entry_d, permset_p); +} + +void * vfswrap_sys_acl_get_qualifier(struct connection_struct *conn, SMB_ACL_ENTRY_T entry_d) +{ + return sys_acl_get_qualifier(entry_d); +} + +SMB_ACL_T vfswrap_sys_acl_get_file(struct connection_struct *conn, const char *path_p, SMB_ACL_TYPE_T type) +{ + return sys_acl_get_file(path_p, type); +} + +SMB_ACL_T vfswrap_sys_acl_get_fd(struct files_struct *fsp, int fd) +{ + return sys_acl_get_fd(fd); +} + +int vfswrap_sys_acl_clear_perms(struct connection_struct *conn, SMB_ACL_PERMSET_T permset) +{ + return sys_acl_clear_perms(permset); +} + +int vfswrap_sys_acl_add_perm(struct connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm) +{ + return sys_acl_add_perm(permset, perm); +} + +char * vfswrap_sys_acl_to_text(struct connection_struct *conn, SMB_ACL_T theacl, ssize_t *plen) +{ + return sys_acl_to_text(theacl, plen); +} + +SMB_ACL_T vfswrap_sys_acl_init(struct connection_struct *conn, int count) +{ + return sys_acl_init(count); +} + +int vfswrap_sys_acl_create_entry(struct connection_struct *conn, SMB_ACL_T *pacl, SMB_ACL_ENTRY_T *pentry) +{ + return sys_acl_create_entry(pacl, pentry); +} + +int vfswrap_sys_acl_set_tag_type(struct connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_TAG_T tagtype) +{ + return sys_acl_set_tag_type(entry, tagtype); +} + +int vfswrap_sys_acl_set_qualifier(struct connection_struct *conn, SMB_ACL_ENTRY_T entry, void *qual) +{ + return sys_acl_set_qualifier(entry, qual); +} + +int vfswrap_sys_acl_set_permset(struct connection_struct *conn, SMB_ACL_ENTRY_T entry, SMB_ACL_PERMSET_T permset) +{ + return sys_acl_set_permset(entry, permset); +} + +int vfswrap_sys_acl_valid(struct connection_struct *conn, SMB_ACL_T theacl ) +{ + return sys_acl_valid(theacl ); +} + +int vfswrap_sys_acl_set_file(struct connection_struct *conn, const char *name, SMB_ACL_TYPE_T acltype, SMB_ACL_T theacl) +{ + return sys_acl_set_file(name, acltype, theacl); +} + +int vfswrap_sys_acl_set_fd(struct files_struct *fsp, int fd, SMB_ACL_T theacl) +{ + return sys_acl_set_fd(fd, theacl); +} + +int vfswrap_sys_acl_delete_def_file(struct connection_struct *conn, const char *path) +{ + return sys_acl_delete_def_file(path); +} + +int vfswrap_sys_acl_get_perm(struct connection_struct *conn, SMB_ACL_PERMSET_T permset, SMB_ACL_PERM_T perm) +{ + return sys_acl_get_perm(permset, perm); +} + +int vfswrap_sys_acl_free_text(struct connection_struct *conn, char *text) +{ + return sys_acl_free_text(text); +} + +int vfswrap_sys_acl_free_acl(struct connection_struct *conn, SMB_ACL_T posix_acl) +{ + return sys_acl_free_acl(posix_acl); +} + +int vfswrap_sys_acl_free_qualifier(struct connection_struct *conn, void *qualifier, SMB_ACL_TAG_T tagtype) +{ + return sys_acl_free_qualifier(qualifier, tagtype); +} diff --git a/source/smbd/vfs.c b/source/smbd/vfs.c index 229880c9f15..9de8c12d69c 100644 --- a/source/smbd/vfs.c +++ b/source/smbd/vfs.c @@ -81,13 +81,36 @@ struct vfs_ops default_vfs_ops = { vfswrap_fset_nt_acl, vfswrap_set_nt_acl, + /* POSIX ACL operations. */ #if defined(HAVE_NO_ACLS) NULL, - NULL + NULL, #else vfswrap_chmod_acl, vfswrap_fchmod_acl #endif + vfswrap_sys_acl_get_entry, + vfswrap_sys_acl_get_tag_type, + vfswrap_sys_acl_get_permset, + vfswrap_sys_acl_get_qualifier, + vfswrap_sys_acl_get_file, + vfswrap_sys_acl_get_fd, + vfswrap_sys_acl_clear_perms, + vfswrap_sys_acl_add_perm, + vfswrap_sys_acl_to_text, + vfswrap_sys_acl_init, + vfswrap_sys_acl_create_entry, + vfswrap_sys_acl_set_tag_type, + vfswrap_sys_acl_set_qualifier, + vfswrap_sys_acl_set_permset, + vfswrap_sys_acl_valid, + vfswrap_sys_acl_set_file, + vfswrap_sys_acl_set_fd, + vfswrap_sys_acl_delete_def_file, + vfswrap_sys_acl_get_perm, + vfswrap_sys_acl_free_text, + vfswrap_sys_acl_free_acl, + vfswrap_sys_acl_free_qualifier }; /**************************************************************************** @@ -259,12 +282,79 @@ static BOOL vfs_init_custom(connection_struct *conn) if (conn->vfs_ops.set_nt_acl == NULL) conn->vfs_ops.set_nt_acl = default_vfs_ops.set_nt_acl; + /* POSIX ACL entries. */ if (conn->vfs_ops.chmod_acl == NULL) conn->vfs_ops.chmod_acl = default_vfs_ops.chmod_acl; if (conn->vfs_ops.fchmod_acl == NULL) conn->vfs_ops.fchmod_acl = default_vfs_ops.fchmod_acl; + if (conn->vfs_ops.sys_acl_get_entry == NULL) + conn->vfs_ops.sys_acl_get_entry = default_vfs_ops.sys_acl_get_entry; + + if (conn->vfs_ops.sys_acl_get_tag_type == NULL) + conn->vfs_ops.sys_acl_get_tag_type = default_vfs_ops.sys_acl_get_tag_type; + + if (conn->vfs_ops.sys_acl_get_permset == NULL) + conn->vfs_ops.sys_acl_get_permset = default_vfs_ops.sys_acl_get_permset; + + if (conn->vfs_ops.sys_acl_get_qualifier == NULL) + conn->vfs_ops.sys_acl_get_qualifier = default_vfs_ops.sys_acl_get_qualifier; + + if (conn->vfs_ops.sys_acl_get_file == NULL) + conn->vfs_ops.sys_acl_get_file = default_vfs_ops.sys_acl_get_file; + + if (conn->vfs_ops.sys_acl_get_fd == NULL) + conn->vfs_ops.sys_acl_get_fd = default_vfs_ops.sys_acl_get_fd; + + if (conn->vfs_ops.sys_acl_clear_perms == NULL) + conn->vfs_ops.sys_acl_clear_perms = default_vfs_ops.sys_acl_clear_perms; + + if (conn->vfs_ops.sys_acl_add_perm == NULL) + conn->vfs_ops.sys_acl_add_perm = default_vfs_ops.sys_acl_add_perm; + + if (conn->vfs_ops.sys_acl_to_text == NULL) + conn->vfs_ops.sys_acl_to_text = default_vfs_ops.sys_acl_to_text; + + if (conn->vfs_ops.sys_acl_init == NULL) + conn->vfs_ops.sys_acl_init = default_vfs_ops.sys_acl_init; + + if (conn->vfs_ops.sys_acl_create_entry == NULL) + conn->vfs_ops.sys_acl_create_entry = default_vfs_ops.sys_acl_create_entry; + + if (conn->vfs_ops.sys_acl_set_tag_type == NULL) + conn->vfs_ops.sys_acl_set_tag_type = default_vfs_ops.sys_acl_set_tag_type; + + if (conn->vfs_ops.sys_acl_set_qualifier == NULL) + conn->vfs_ops.sys_acl_set_qualifier = default_vfs_ops.sys_acl_set_qualifier; + + if (conn->vfs_ops.sys_acl_set_permset == NULL) + conn->vfs_ops.sys_acl_set_permset = default_vfs_ops.sys_acl_set_permset; + + if (conn->vfs_ops.sys_acl_valid == NULL) + conn->vfs_ops.sys_acl_valid = default_vfs_ops.sys_acl_valid; + + if (conn->vfs_ops.sys_acl_set_file == NULL) + conn->vfs_ops.sys_acl_set_file = default_vfs_ops.sys_acl_set_file; + + if (conn->vfs_ops.sys_acl_set_fd == NULL) + conn->vfs_ops.sys_acl_set_fd = default_vfs_ops.sys_acl_set_fd; + + if (conn->vfs_ops.sys_acl_delete_def_file == NULL) + conn->vfs_ops.sys_acl_delete_def_file = default_vfs_ops.sys_acl_delete_def_file; + + if (conn->vfs_ops.sys_acl_get_perm == NULL) + conn->vfs_ops.sys_acl_get_perm = default_vfs_ops.sys_acl_get_perm; + + if (conn->vfs_ops.sys_acl_free_text == NULL) + conn->vfs_ops.sys_acl_free_text = default_vfs_ops.sys_acl_free_text; + + if (conn->vfs_ops.sys_acl_free_acl == NULL) + conn->vfs_ops.sys_acl_free_acl = default_vfs_ops.sys_acl_free_acl; + + if (conn->vfs_ops.sys_acl_free_qualifier == NULL) + conn->vfs_ops.sys_acl_free_qualifier = default_vfs_ops.sys_acl_free_qualifier; + return True; } #endif |