From 70922b9bbe412dc43397ecfd3feeb01169ed0b96 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Wed, 6 Dec 2000 23:24:31 +0000 Subject: Cause smbd to use the new posix_acls code, not the old unix_acls code. Currently does exactly the same thing (returns ACLs the same way). This code is written to try and get a POSIX ACL via the abstract sys_XX interface, then fall back to providing a UNIX based ACL if the calls fail. Seems to work. Next step is to add a --with-posix-acls to configure.in and then check on a POSIX ACL system that a complex ACL is returned correctly as an NT ACL. Note that the ACL set (a more complex problem) is not addressed yet. Jeremy. (This used to be commit 4339e20202a876dbadc07980b731f711463b7299) --- source3/Makefile.in | 4 +- source3/include/proto.h | 35 +++++++++---- source3/include/smb.h | 1 + source3/include/smb_acls.h | 6 ++- source3/lib/sysacls.c | 12 +++++ source3/passdb/pdb_smbpasswd.c | 5 ++ source3/script/mkproto.awk | 2 +- source3/smbd/posix_acls.c | 108 ++++++++++++++++++----------------------- 8 files changed, 98 insertions(+), 75 deletions(-) (limited to 'source3') diff --git a/source3/Makefile.in b/source3/Makefile.in index b56ea8c173..7dc23e2eae 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -104,7 +104,7 @@ LIB_OBJ = lib/charcnv.o lib/charset.o lib/debug.o lib/fault.o \ lib/ufc.o lib/genrand.o lib/username.o lib/access.o lib/smbrun.o \ lib/bitmap.o lib/crc32.o lib/snprintf.o lib/wins_srv.o \ lib/util_array.o lib/util_str.o lib/util_sid.o \ - lib/util_unistr.o lib/util_file.o \ + lib/util_unistr.o lib/util_file.o lib/sysacls.o \ lib/util.o lib/util_sock.o lib/util_sec.o smbd/ssl.o \ lib/talloc.o lib/hash.o lib/substitute.o lib/fsusage.o \ lib/ms_fnmatch.o lib/select.o lib/error.o lib/messages.o \ @@ -179,7 +179,7 @@ SMBD_OBJ1 = smbd/server.o smbd/files.o smbd/chgpasswd.o smbd/connection.o \ smbd/dosmode.o smbd/filename.o smbd/open.o smbd/close.o \ smbd/blocking.o smbd/sec_ctx.o \ smbd/vfs.o smbd/vfs-wrap.o smbd/statcache.o \ - smbd/unix_acls.o lib/msrpc-client.o lib/msrpc_use.o \ + smbd/posix_acls.o lib/msrpc-client.o lib/msrpc_use.o \ smbd/process.o smbd/service.o smbd/error.o \ printing/printfsp.o lib/util_seaccess.o diff --git a/source3/include/proto.h b/source3/include/proto.h index c4898fc2ba..fe04dcb5e3 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -240,6 +240,23 @@ void standard_sub_snum(int snum, char *str); void standard_sub_vuser(char *str, user_struct *vuser); void standard_sub_vsnum(char *str, user_struct *vuser, int snum); +/*The following definitions come from lib/sysacls.c */ + +int sys_acl_get_entry( SMB_ACL_T acl, int entry_id, SMB_ACL_ENTRY_T *entry_p); +int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p); +int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p); +void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d); +SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type); +SMB_ACL_T sys_acl_get_fd(int fd); +int sys_acl_free( void *obj_p); +int sys_acl_get_entry( SMB_ACL_T acl, int entry_id, SMB_ACL_ENTRY_T *entry_p); +int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p); +int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p); +void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d); +SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type); +SMB_ACL_T sys_acl_get_fd(int fd); +int sys_acl_free( void *obj_p); + /*The following definitions come from lib/system.c */ int sys_usleep(long usecs); @@ -1731,10 +1748,10 @@ BOOL pdb_delete_sam_account (char* username); BOOL pdb_setsampwent(BOOL update); void pdb_endsampwent(void); SAM_ACCOUNT* pdb_getsampwent(void); -SAM_ACCOUNT* pdb_getsampwnam (char *name); +SAM_ACCOUNT* pdb_getsampwnam (char *sname); SAM_ACCOUNT* pdb_getsampwuid (uid_t uid); SAM_ACCOUNT* pdb_getsampwrid (uint32 rid); -BOOL pdb_delete_sam_account(char *name); +BOOL pdb_delete_sam_account(char *sname); BOOL pdb_update_sam_account (SAM_ACCOUNT *newpwd, BOOL override); BOOL pdb_add_sam_account (SAM_ACCOUNT *newpwd); @@ -3699,6 +3716,13 @@ int reply_pipe_read_and_X(char *inbuf,char *outbuf,int length,int bufsize); int reply_pipe_close(connection_struct *conn, char *inbuf,char *outbuf); #endif +/*The following definitions come from smbd/posix_acls.c */ + +#if OLD_NTDOMAIN +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); +#endif + /*The following definitions come from smbd/process.c */ #if OLD_NTDOMAIN @@ -3866,13 +3890,6 @@ BOOL sid_to_uid(DOM_SID *psid, uid_t *puid, enum SID_NAME_USE *sidtype); BOOL sid_to_gid(DOM_SID *psid, gid_t *pgid, enum SID_NAME_USE *sidtype); #endif -/*The following definitions come from smbd/unix_acls.c */ - -#if OLD_NTDOMAIN -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); -#endif - /*The following definitions come from smbd/vfs-wrap.c */ int vfswrap_dummy_connect(connection_struct *conn, char *service, char *user); diff --git a/source3/include/smb.h b/source3/include/smb.h index 1e5d312997..f97e7cd9f5 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -1670,5 +1670,6 @@ typedef struct user_struct #define MAP_TO_GUEST_ON_BAD_PASSWORD 2 #include "nsswitch/winbindd_nss.h" +#include "smb_acls.h" #endif /* _SMB_H */ diff --git a/source3/include/smb_acls.h b/source3/include/smb_acls.h index 6acd17c321..bc07a1b271 100644 --- a/source3/include/smb_acls.h +++ b/source3/include/smb_acls.h @@ -29,6 +29,7 @@ /* This is an identity mapping (just remove the SMB_). */ #define SMB_ACL_TAG_T acl_tag_t +#define SMB_ACL_TYPE_T acl_type_t #define SMB_ACL_PERMSET_T acl_permset_t #define SMB_ACL_READ ACL_READ #define SMB_ACL_WRITE ACL_WRITE @@ -60,6 +61,7 @@ /* No ACLS - fake it. */ #define SMB_ACL_TAG_T int +#define SMB_ACL_TYPE_T int #define SMB_ACL_PERMSET_T mode_t #define SMB_ACL_READ S_IRUSR #define SMB_ACL_WRITE S_IWUSR @@ -73,11 +75,11 @@ #define SMB_ACL_OTHER_OBJ 4 #define SMB_ACL_MASK 5 -typdef struct SMB_ACL_T { +typedef struct SMB_ACL_T { int dummy; } *SMB_ACL_T; -typdef struct SMB_ACL_ENTRY_T { +typedef struct SMB_ACL_ENTRY_T { int dummy; } *SMB_ACL_ENTRY_T; diff --git a/source3/lib/sysacls.c b/source3/lib/sysacls.c index 50d9757acd..da62479cd8 100644 --- a/source3/lib/sysacls.c +++ b/source3/lib/sysacls.c @@ -84,27 +84,39 @@ int sys_acl_free( void *obj_p) #elif defined(HAVE_IRIX_ACLS) #else /* No ACLs. */ + int sys_acl_get_entry( SMB_ACL_T acl, int entry_id, SMB_ACL_ENTRY_T *entry_p) { + return -1; } int sys_acl_get_tag_type( SMB_ACL_ENTRY_T entry_d, SMB_ACL_TAG_T *tag_type_p) { + return -1; } int sys_acl_get_permset( SMB_ACL_ENTRY_T entry_d, SMB_ACL_PERMSET_T *permset_p) { + return -1; } void *sys_acl_get_qualifier( SMB_ACL_ENTRY_T entry_d) { + return NULL; } SMB_ACL_T sys_acl_get_file( const char *path_p, SMB_ACL_TYPE_T type) { + return (SMB_ACL_T)NULL; +} + +SMB_ACL_T sys_acl_get_fd(int fd) +{ + return (SMB_ACL_T)NULL; } int sys_acl_free( void *obj_p) { + return -1; } #endif /* No ACLs. */ diff --git a/source3/passdb/pdb_smbpasswd.c b/source3/passdb/pdb_smbpasswd.c index 38059d5ef3..ad07b8a11e 100644 --- a/source3/passdb/pdb_smbpasswd.c +++ b/source3/passdb/pdb_smbpasswd.c @@ -569,6 +569,11 @@ static BOOL add_smbfilepwd_entry(struct smb_passwd *newpwd) /* Open the smbpassword file - for update. */ fp = startsmbfilepwent(pfile, PWF_UPDATE, &pw_file_lock_depth); + if (fp == NULL && errno == ENOENT) { + /* Try again - create. */ + fp = startsmbfilepwent(pfile, PWF_CREATE, &pw_file_lock_depth); + } + if (fp == NULL) { DEBUG(0, ("add_smbfilepwd_entry: unable to open file.\n")); return False; diff --git a/source3/script/mkproto.awk b/source3/script/mkproto.awk index 9a85e89ced..c66fe07972 100644 --- a/source3/script/mkproto.awk +++ b/source3/script/mkproto.awk @@ -120,7 +120,7 @@ END { gotstart = 1; } - if( $0 ~ /^SAM_ACCT_INFO_NODE/ ) { + if( $0 ~ /^SAM_ACCT_INFO_NODE|^SMB_ACL_T/ ) { gotstart = 1; } diff --git a/source3/smbd/posix_acls.c b/source3/smbd/posix_acls.c index b106975a86..4f483c8f53 100644 --- a/source3/smbd/posix_acls.c +++ b/source3/smbd/posix_acls.c @@ -1,4 +1,3 @@ -#ifdef HAVE_POSIX_ACLS #define OLD_NTDOMAIN 1 /* Unix SMB/Netbios implementation. @@ -57,17 +56,16 @@ static SEC_ACCESS map_canon_ace_perms(int *pacl_type, DOM_SID *powner_sid, canon /* * Here we differentiate between the owner and any other user. */ - if (sid_equal(powner_sid, &ace->sid) + if (sid_equal(powner_sid, &ace->sid)) { nt_mask = UNIX_ACCESS_NONE; } else { - /* Not owner, this is an access denied ACE. */ - nt_mask = UNIX_ACCESS_RWX; - *pacl_type = SEC_ACE_TYPE_ACCESS_DENIED; + /* Not owner, no access. */ + nt_mask = 0; } } else { - nt_mask |= (perm & SMB_ACL_READ) ? UNIX_ACCESS_R : 0; - nt_mask |= (perm & SMB_ACL_WRITE) ? UNIX_ACCESS_W : 0; - nt_mask |= (perm & SMB_ACL_EXECUTE) ? UNIX_ACCESS_X : 0; + nt_mask |= (ace->perms & SMB_ACL_READ) ? UNIX_ACCESS_R : 0; + nt_mask |= (ace->perms & SMB_ACL_WRITE) ? UNIX_ACCESS_W : 0; + nt_mask |= (ace->perms & SMB_ACL_EXECUTE) ? UNIX_ACCESS_X : 0; } init_sec_access(&sa,nt_mask); return sa; @@ -130,8 +128,6 @@ static BOOL unpack_nt_permissions(SMB_STRUCT_STAT *psbuf, uid_t *puser, gid_t *p DOM_SID grp_sid; DOM_SID file_owner_sid; DOM_SID file_grp_sid; - uint32 owner_rid; - uint32 grp_rid; SEC_ACL *dacl = psd->dacl; BOOL all_aces_are_inherit_only = (is_directory ? True : False); int i; @@ -360,9 +356,6 @@ static canon_ace *unix_canonicalise_acl(files_struct *fsp, SMB_STRUCT_STAT *psbu canon_ace *owner_ace = NULL; canon_ace *group_ace = NULL; canon_ace *other_ace = NULL; - SMB_ACL_TAG_T type; - SMB_ACL_PERMSET_T perms; - DOM_SID sid; /* * Create 3 linked list entries. @@ -371,7 +364,7 @@ static canon_ace *unix_canonicalise_acl(files_struct *fsp, SMB_STRUCT_STAT *psbu if ((owner_ace = (canon_ace *)malloc(sizeof(canon_ace))) == NULL) goto fail; - if ((gtoup_ace = (canon_ace *)malloc(sizeof(canon_ace))) == NULL) + if ((group_ace = (canon_ace *)malloc(sizeof(canon_ace))) == NULL) goto fail; if ((other_ace = (canon_ace *)malloc(sizeof(canon_ace))) == NULL) @@ -391,9 +384,9 @@ static canon_ace *unix_canonicalise_acl(files_struct *fsp, SMB_STRUCT_STAT *psbu other_ace->sid = global_sid_World; if (!fsp->is_directory) { - owner_ace->perms = unix_perms_to_acl_perms(sbuf.st_mode, S_IRUSR, S_IWUSR, S_IXUSR); - group_ace->perms = unix_perms_to_acl_perms(sbuf.st_mode, S_IRGRP, S_IWGRP, S_IXGRP); - other_ace->perms = unix_perms_to_acl_perms(sbuf.st_mode, S_IROTH, S_IWOTH, S_IXOTH); + owner_ace->perms = unix_perms_to_acl_perms(psbuf->st_mode, S_IRUSR, S_IWUSR, S_IXUSR); + group_ace->perms = unix_perms_to_acl_perms(psbuf->st_mode, S_IRGRP, S_IWGRP, S_IXGRP); + other_ace->perms = unix_perms_to_acl_perms(psbuf->st_mode, S_IROTH, S_IWOTH, S_IXOTH); } else { mode_t mode = unix_mode( fsp->conn, FILE_ATTRIBUTE_ARCHIVE, fsp->fsp_name); @@ -450,11 +443,11 @@ static canon_ace *canonicalise_acl( SMB_ACL_T posix_acl, SMB_STRUCT_STAT *psbuf) /* Decide which SID to use based on the ACL type. */ switch(tagtype) { - SMB_ACL_USER_OBJ: + case SMB_ACL_USER_OBJ: /* Get the SID from the owner. */ uid_to_sid( &sid, psbuf->st_uid ); break; - SMB_ACL_USER: + case SMB_ACL_USER: { uid_t *puid = (uid_t *)sys_acl_get_qualifier(entry); if (puid == NULL) { @@ -464,11 +457,11 @@ static canon_ace *canonicalise_acl( SMB_ACL_T posix_acl, SMB_STRUCT_STAT *psbuf) uid_to_sid( &sid, *puid); break; } - SMB_ACL_GROUP_OBJ: + case SMB_ACL_GROUP_OBJ: /* Get the SID from the owning group. */ gid_to_sid( &sid, psbuf->st_gid ); break; - SMB_ACL_GROUP: + case SMB_ACL_GROUP: { gid_t *pgid = (gid_t *)sys_acl_get_qualifier(entry); if (pgid == NULL) { @@ -478,10 +471,10 @@ static canon_ace *canonicalise_acl( SMB_ACL_T posix_acl, SMB_STRUCT_STAT *psbuf) gid_to_sid( &sid, *pgid); break; } - SMB_ACL_MASK: + case SMB_ACL_MASK: acl_mask = permset; continue; /* Don't count the mask as an entry. */ - SMB_ACL_OTHER_OBJ: + case SMB_ACL_OTHER_OBJ: /* Use the Everyone SID */ sid = global_sid_World; break; @@ -515,18 +508,18 @@ static canon_ace *canonicalise_acl( SMB_ACL_T posix_acl, SMB_STRUCT_STAT *psbuf) */ for ( ace = list_head; ace; ace = next_ace) { - next_ace = ace_next; + next_ace = ace->next; ace->perms &= acl_mask; if (ace->perms == 0) { switch (ace->type) { - SMB_ACL_USER_OBJ: - SMB_ACL_GROUP_OBJ: - SMB_ACL_OTHER_OBJ: + case SMB_ACL_USER_OBJ: + case SMB_ACL_GROUP_OBJ: + case SMB_ACL_OTHER_OBJ: DLIST_REMOVE(list_head, ace); break; - SMB_ACL_USER: - SMB_ACL_GROUP: + case SMB_ACL_USER: + case SMB_ACL_GROUP: DLIST_PROMOTE(list_head, ace); break; } @@ -534,6 +527,11 @@ static canon_ace *canonicalise_acl( SMB_ACL_T posix_acl, SMB_STRUCT_STAT *psbuf) } return list_head; + + fail: + + free_canon_ace_list(list_head); + return NULL; } /**************************************************************************** @@ -545,19 +543,12 @@ static canon_ace *canonicalise_acl( SMB_ACL_T posix_acl, SMB_STRUCT_STAT *psbuf) size_t get_nt_acl(files_struct *fsp, SEC_DESC **ppdesc) { - extern DOM_SID global_sid_World; SMB_STRUCT_STAT sbuf; SEC_ACE *nt_ace_list; DOM_SID owner_sid; DOM_SID group_sid; size_t sd_size = 0; SEC_ACL *psa = NULL; - SEC_ACCESS owner_access; - int owner_acl_type; - SEC_ACCESS group_access; - int grp_acl_type; - SEC_ACCESS other_access; - int other_acl_type; size_t num_acls = 0; size_t num_dir_acls = 0; size_t num_aces = 0; @@ -571,7 +562,7 @@ size_t get_nt_acl(files_struct *fsp, SEC_DESC **ppdesc) if(fsp->is_directory || fsp->fd == -1) { /* Get the stat struct for the owner info. */ - if(vfs_stat(fsp,fsp->fsp_name, &sbuf) != 0) { + if(vfs_stat(fsp->conn,fsp->fsp_name, &sbuf) != 0) { return 0; } /* @@ -590,7 +581,7 @@ size_t get_nt_acl(files_struct *fsp, SEC_DESC **ppdesc) } else { /* Get the stat struct for the owner info. */ - if(fsp->conn->vfs_ops.fstat(fsp->fd,&sbuf) != 0) { + if(vfs_fstat(fsp,fsp->fd,&sbuf) != 0) { return 0; } /* @@ -625,7 +616,7 @@ size_t get_nt_acl(files_struct *fsp, SEC_DESC **ppdesc) /* Allocate the ace list. */ if ((nt_ace_list = (SEC_ACE *)malloc((num_acls + num_dir_acls)* sizeof(SEC_ACE))) == NULL) { DEBUG(0,("get_nt_acl: Unable to malloc space for nt_ace_list.\n")); - goto done: + goto done; } memset(nt_ace_list, '\0', (num_acls + num_dir_acls) * sizeof(SEC_ACE) ); @@ -637,6 +628,7 @@ size_t get_nt_acl(files_struct *fsp, SEC_DESC **ppdesc) { canon_ace *ace; int nt_acl_type; + int i; ace = file_ace; @@ -655,7 +647,7 @@ size_t get_nt_acl(files_struct *fsp, SEC_DESC **ppdesc) } if (num_acls) { - if((psa = make_sec_acl( ACL_REVISION, num_aces, ace_list)) == NULL) { + if((psa = make_sec_acl( ACL_REVISION, num_aces, nt_ace_list)) == NULL) { DEBUG(0,("get_nt_acl: Unable to malloc space for acl.\n")); goto done; } @@ -672,8 +664,8 @@ size_t get_nt_acl(files_struct *fsp, SEC_DESC **ppdesc) if (posix_acl) sys_acl_free(posix_acl); - if (directory_acl) - sys_acl_free(directory_acl); + if (dir_acl) + sys_acl_free(dir_acl); if (file_ace) free_canon_ace_list(file_ace); if (dir_ace) @@ -705,19 +697,11 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) * Get the current state of the file. */ - if(fsp->is_directory) { - if(dos_stat(fsp->fsp_name, &sbuf) != 0) + if(fsp->is_directory || fsp->fd == -1) { + if(vfs_stat(fsp->conn,fsp->fsp_name, &sbuf) != 0) return False; } else { - - int ret; - - if(fsp->fd == -1) - ret = conn->vfs_ops.stat(dos_to_unix(fsp->fsp_name,False), &sbuf); - else - ret = conn->vfs_ops.fstat(fsp->fd,&sbuf); - - if(ret != 0) + if(conn->vfs_ops.fstat(fsp,fsp->fd,&sbuf) != 0) return False; } @@ -740,7 +724,7 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) DEBUG(3,("call_nt_transact_set_security_desc: chown %s. uid = %u, gid = %u.\n", fsp->fsp_name, (unsigned int)user, (unsigned int)grp )); - if(dos_chown( fsp->fsp_name, user, grp) == -1) { + if(vfs_chown( fsp->conn, fsp->fsp_name, user, grp) == -1) { DEBUG(3,("call_nt_transact_set_security_desc: chown %s, %u, %u failed. Error = %s.\n", fsp->fsp_name, (unsigned int)user, (unsigned int)grp, strerror(errno) )); return False; @@ -752,7 +736,7 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) */ if(fsp->is_directory) { - if(dos_stat(fsp->fsp_name, &sbuf) != 0) { + if(vfs_stat(fsp->conn, fsp->fsp_name, &sbuf) != 0) { return False; } } else { @@ -760,9 +744,9 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) int ret; if(fsp->fd == -1) - ret = conn->vfs_ops.stat(dos_to_unix(fsp->fsp_name,False), &sbuf); + ret = vfs_stat(fsp->conn, fsp->fsp_name, &sbuf); else - ret = conn->vfs_ops.fstat(fsp->fd,&sbuf); + ret = conn->vfs_ops.fstat(fsp,fsp->fd,&sbuf); if(ret != 0) return False; @@ -808,7 +792,7 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) DEBUG(3,("call_nt_transact_set_security_desc: chmod %s. perms = 0%o.\n", fsp->fsp_name, (unsigned int)perms )); - if(conn->vfs_ops.chmod(dos_to_unix(fsp->fsp_name, False), perms) == -1) { + if(conn->vfs_ops.chmod(conn,dos_to_unix(fsp->fsp_name, False), perms) == -1) { DEBUG(3,("call_nt_transact_set_security_desc: chmod %s, 0%o failed. Error = %s.\n", fsp->fsp_name, (unsigned int)perms, strerror(errno) )); return False; @@ -819,6 +803,8 @@ BOOL set_nt_acl(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) return True; } #undef OLD_NTDOMAIN -#else /* HAVE_POSIX_ACLS */ - void dummy_posix_acls(void) {;} /* So some compilers don't complain. */ -#endif /* HAVE_POSIX_ACLS */ + + + + + -- cgit