From c443e3c9b2d459a969ac897d608882c4afa8ac68 Mon Sep 17 00:00:00 2001 From: Alexander Werth Date: Thu, 26 Jul 2012 16:51:20 +0200 Subject: [PATCH 1/8] s3: Add new nfs4:mode specialcreator on reading parameters. --- source3/modules/nfs4_acls.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/source3/modules/nfs4_acls.c b/source3/modules/nfs4_acls.c index e112728..9151c66 100644 --- a/source3/modules/nfs4_acls.c +++ b/source3/modules/nfs4_acls.c @@ -54,11 +54,12 @@ typedef struct _SMB_ACL4_INT_T SMB_ACE4_INT_T *last; } SMB_ACL4_INT_T; -enum smbacl4_mode_enum {e_simple=0, e_special=1}; +enum smbacl4_mode_enum {e_simple=0, e_special=1, e_specialcreator=2}; enum smbacl4_acedup_enum {e_dontcare=0, e_reject=1, e_ignore=2, e_merge=3}; typedef struct _smbacl4_vfs_params { enum smbacl4_mode_enum mode; + enum smbacl4_mode_enum readmode; bool do_chown; enum smbacl4_acedup_enum acedup; } smbacl4_vfs_params; @@ -75,6 +76,7 @@ static int smbacl4_get_vfs_params( static const struct enum_list enum_smbacl4_modes[] = { { e_simple, "simple" }, { e_special, "special" }, + { e_specialcreator, "specialcreator" }, { -1 , NULL } }; static const struct enum_list enum_smbacl4_acedups[] = { @@ -95,8 +97,9 @@ static int smbacl4_get_vfs_params( SNUM(conn), type_name, "acedup", enum_smbacl4_acedups, e_dontcare); - DEBUG(10, ("mode:%s, do_chown:%s, acedup: %s\n", + DEBUG(10, ("mode:%s, readmode:%s, do_chown:%s, acedup: %s\n", enum_smbacl4_modes[params->mode].name, + enum_smbacl4_modes[params->readmode].name, params->do_chown ? "true" : "false", enum_smbacl4_acedups[params->acedup].name)); -- 1.7.9.5 From fe37635d17a4811fc791932afc7954ecb9ff963a Mon Sep 17 00:00:00 2001 From: Alexander Werth Date: Tue, 24 Jul 2012 18:54:00 +0200 Subject: [PATCH 2/8] s3: Add specialcreator to nfs4acls.txt readme --- source3/modules/README.nfs4acls.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source3/modules/README.nfs4acls.txt b/source3/modules/README.nfs4acls.txt index 1cb0887..58b58fc 100644 --- a/source3/modules/README.nfs4acls.txt +++ b/source3/modules/README.nfs4acls.txt @@ -12,9 +12,12 @@ Parameters in smb.conf: Each parameter must have a prefix "nfs4:". Each one affects the behaviour only when _setting_ an acl on a file/dir: -mode = [simple|special] +mode = [simple|special|specialcreator] - simple: don't use OWNER@ and GROUP@ special IDs in ACEs. - default - special: use OWNER@ and GROUP@ special IDs in ACEs instead of simple user&group ids. +- specialcreator: use non inheriting OWNER@ and GROUP@ special IDs for +mode bits and inheriting OWNER@ and GROUP@ special IDs for creator +owner and creator owner group. Note: EVERYONE@ is always processed (if found such an ACE). Note2: special mode will have side effect when _only_ chown is performed. Later this may be worked out. -- 1.7.9.5 From 69c96f6241f11841f27e986f3c167a326b57b8f2 Mon Sep 17 00:00:00 2001 From: Alexander Werth Date: Thu, 26 Jul 2012 14:45:53 +0200 Subject: [PATCH 3/8] s3: Add smbacl4_expand_special function for mode specialcreate This function replaces inherited user acl entries with a non inheriting special entry and an inherit only user entry. It also replaces non inheriting user entries with special entries. As a result the posix mode bits are set for user acl entries. The same applies to groups and their posix mode bits. --- source3/modules/nfs4_acls.c | 74 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 74 insertions(+) diff --git a/source3/modules/nfs4_acls.c b/source3/modules/nfs4_acls.c index 9151c66..cf85b9a 100644 --- a/source3/modules/nfs4_acls.c +++ b/source3/modules/nfs4_acls.c @@ -761,6 +761,76 @@ static int smbacl4_MergeIgnoreReject( return result; } +static int smbacl4_expand_special( + SMB4ACL_T *theacl, + uid_t ownerUID, + gid_t ownerGID +) +{ + SMB_ACL4_INT_T *aclint = get_validated_aclint(theacl); + SMB_ACE4_INT_T *aceint; + + for(aceint = aclint->first; aceint!=NULL; aceint=(SMB_ACE4_INT_T *)aceint->next) { + SMB_ACE4PROP_T *ace = &aceint->prop; + + DEBUG(10,("ace type:0x%x flags:0x%x aceFlags:0x%x\n", + ace->aceType, ace->flags, ace->aceFlags)); + + if (!(ace->flags & SMB_ACE4_ID_SPECIAL) && + !(ace->aceFlags & SMB_ACE4_IDENTIFIER_GROUP) && + ace->who.uid == ownerUID && + !(ace->aceFlags & SMB_ACE4_INHERIT_ONLY_ACE) && + !(ace->aceFlags & SMB_ACE4_FILE_INHERIT_ACE) && + !(ace->aceFlags & SMB_ACE4_DIRECTORY_INHERIT_ACE)) { + ace->flags |= SMB_ACE4_ID_SPECIAL; + ace->who.special_id = SMB_ACE4_WHO_OWNER; + DEBUG(10,("replaced with special owner ace\n")); + } + else if (!(ace->flags & SMB_ACE4_ID_SPECIAL) && + !(ace->aceFlags & SMB_ACE4_IDENTIFIER_GROUP) && + ace->who.uid == ownerUID && + !(ace->aceFlags & SMB_ACE4_INHERIT_ONLY_ACE)) { + SMB_ACE4PROP_T ace_special; + ace_special = *ace; + ace_special.aceFlags &= ~SMB_ACE4_FILE_INHERIT_ACE; + ace_special.aceFlags &= ~SMB_ACE4_DIRECTORY_INHERIT_ACE; + ace_special.flags |= SMB_ACE4_ID_SPECIAL; + ace_special.who.special_id = SMB_ACE4_WHO_OWNER; + smb_add_ace4(theacl, &ace_special); + ace->aceFlags |= SMB_ACE4_INHERIT_ONLY_ACE; + DEBUG(10,("ace special flags:0x%x aceFlags:0x%x\n", + ace_special.flags, ace_special.aceFlags)); + } + + if (!(ace->flags & SMB_ACE4_ID_SPECIAL) && + ace->aceFlags & SMB_ACE4_IDENTIFIER_GROUP && + ace->who.uid == ownerGID && + !(ace->aceFlags & SMB_ACE4_INHERIT_ONLY_ACE) && + !(ace->aceFlags & SMB_ACE4_FILE_INHERIT_ACE) && + !(ace->aceFlags & SMB_ACE4_DIRECTORY_INHERIT_ACE)) { + ace->flags |= SMB_ACE4_ID_SPECIAL; + ace->who.special_id = SMB_ACE4_WHO_GROUP; + DEBUG(10,("replaced with special group ace\n")); + } + else if (!(ace->flags & SMB_ACE4_ID_SPECIAL) && + ace->aceFlags & SMB_ACE4_IDENTIFIER_GROUP && + ace->who.uid == ownerGID && + !(ace->aceFlags & SMB_ACE4_INHERIT_ONLY_ACE)) { + SMB_ACE4PROP_T ace_special; + ace_special = *ace; + ace_special.aceFlags &= ~SMB_ACE4_FILE_INHERIT_ACE; + ace_special.aceFlags &= ~SMB_ACE4_DIRECTORY_INHERIT_ACE; + ace_special.flags |= SMB_ACE4_ID_SPECIAL; + ace_special.who.special_id = SMB_ACE4_WHO_GROUP; + smb_add_ace4(theacl, &ace_special); + ace->aceFlags |= SMB_ACE4_INHERIT_ONLY_ACE; + DEBUG(10,("ace special flags:0x%x aceFlags:0x%x\n", + ace_special.flags, ace_special.aceFlags)); + } + } + return True; /* OK */ +} + static SMB4ACL_T *smbacl4_win2nfs4( const files_struct *fsp, const struct security_acl *dacl, @@ -802,6 +872,10 @@ static SMB4ACL_T *smbacl4_win2nfs4( smb_add_ace4(theacl, &ace_v4); } + if (pparams->mode==e_specialcreator) { + smbacl4_expand_special(theacl, ownerUID, ownerGID); + } + return theacl; } -- 1.7.9.5 From bf188da3e50852038d89f89d85e2011b11f593c3 Mon Sep 17 00:00:00 2001 From: Alexander Werth Date: Thu, 26 Jul 2012 15:11:48 +0200 Subject: [PATCH 4/8] s3: Add function smbacl4_substitute_special. --- source3/modules/nfs4_acls.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/source3/modules/nfs4_acls.c b/source3/modules/nfs4_acls.c index cf85b9a..81a0471 100644 --- a/source3/modules/nfs4_acls.c +++ b/source3/modules/nfs4_acls.c @@ -761,6 +761,40 @@ static int smbacl4_MergeIgnoreReject( return result; } +static int smbacl4_substitute_special( + SMB4ACL_T *theacl, + uid_t ownerUID, + gid_t ownerGID +) +{ + SMB_ACL4_INT_T *aclint = get_validated_aclint(theacl); + SMB_ACE4_INT_T *aceint; + + for(aceint = aclint->first; aceint!=NULL; aceint=(SMB_ACE4_INT_T *)aceint->next) { + SMB_ACE4PROP_T *ace = &aceint->prop; + + DEBUG(10,("ace type:0x%x flags:0x%x aceFlags:0x%x\n", + ace->aceType, ace->flags, ace->aceFlags)); + + if (!(ace->flags & SMB_ACE4_ID_SPECIAL) && + !(ace->aceFlags & SMB_ACE4_IDENTIFIER_GROUP) && + ace->who.uid == ownerUID) { + ace->flags |= SMB_ACE4_ID_SPECIAL; + ace->who.special_id = SMB_ACE4_WHO_OWNER; + DEBUG(10,("replaced with special owner ace\n")); + } + + if (!(ace->flags & SMB_ACE4_ID_SPECIAL) && + ace->aceFlags & SMB_ACE4_IDENTIFIER_GROUP && + ace->who.uid == ownerGID) { + ace->flags |= SMB_ACE4_ID_SPECIAL; + ace->who.special_id = SMB_ACE4_WHO_GROUP; + DEBUG(10,("replaced with special group ace\n")); + } + } + return True; /* OK */ +} + static int smbacl4_expand_special( SMB4ACL_T *theacl, uid_t ownerUID, -- 1.7.9.5 From 40ec659f0a996373d3a94e339fd48c822c15da82 Mon Sep 17 00:00:00 2001 From: Alexander Werth Date: Fri, 13 Jul 2012 17:48:34 +0200 Subject: [PATCH 5/8] s3: Remove inlined special substitution of mode special. Remove inlined special substitution of mode special. Instead call the function smbacl4_substitute_special. --- source3/modules/nfs4_acls.c | 78 ++++++++++++++++++++++++++++++------------- 1 file changed, 55 insertions(+), 23 deletions(-) diff --git a/source3/modules/nfs4_acls.c b/source3/modules/nfs4_acls.c index 81a0471..0bed5a1 100644 --- a/source3/modules/nfs4_acls.c +++ b/source3/modules/nfs4_acls.c @@ -594,7 +594,7 @@ static void smbacl4_dump_nfs4acl(int level, SMB4ACL_T *theacl) } } -/* +/* * Find 2 NFS4 who-special ACE property (non-copy!!!) * match nonzero if "special" and who is equal * return ace if found matching; otherwise NULL @@ -645,8 +645,6 @@ static SMB_ACE4PROP_T *smbacl4_find_equal_special( static bool smbacl4_fill_ace4( const struct smb_filename *filename, smbacl4_vfs_params *params, - uid_t ownerUID, - gid_t ownerGID, const struct security_ace *ace_nt, /* input */ SMB_ACE4PROP_T *ace_v4 /* output */ ) @@ -696,31 +694,62 @@ static bool smbacl4_fill_ace4( ace_v4->who.special_id = SMB_ACE4_WHO_GROUP; ace_v4->flags |= SMB_ACE4_ID_SPECIAL; } else { + TALLOC_CTX *mem_ctx = talloc_tos(); + const char *dom, *name; + enum lsa_SidType type; uid_t uid; gid_t gid; + struct dom_sid sid; - if (sid_to_gid(&ace_nt->trustee, &gid)) { - ace_v4->aceFlags |= SMB_ACE4_IDENTIFIER_GROUP; + sid_copy(&sid, &ace_nt->trustee); - if (params->mode==e_special && gid==ownerGID) { - ace_v4->flags |= SMB_ACE4_ID_SPECIAL; - ace_v4->who.special_id = SMB_ACE4_WHO_GROUP; - } else { - ace_v4->who.gid = gid; + if (!lookup_sid(mem_ctx, &sid, &dom, &name, &type)) { + + struct dom_sid mapped; + + if (!nfs4_map_sid(params, &sid, &mapped)) { + DEBUG(1, ("nfs4_acls.c: file [%s]: SID %s " + "unknown\n", filename, + sid_string_dbg(&sid))); + errno = EINVAL; + return False; } - } else if (sid_to_uid(&ace_nt->trustee, &uid)) { - if (params->mode==e_special && uid==ownerUID) { - ace_v4->flags |= SMB_ACE4_ID_SPECIAL; - ace_v4->who.special_id = SMB_ACE4_WHO_OWNER; - } else { - ace_v4->who.uid = uid; + + DEBUG(3, ("nfs4_acls.c: file [%s]: mapped SID %s " + "to %s\n", filename, sid_string_dbg(&sid), + sid_string_dbg(&mapped))); + + if (!lookup_sid(mem_ctx, &mapped, &dom, + &name, &type)) { + DEBUG(1, ("nfs4_acls.c: file [%s]: SID %s " + "mapped from %s is unknown\n", + filename, sid_string_dbg(&mapped), + sid_string_dbg(&sid))); + errno = EINVAL; + return False; } - } else { - DEBUG(1, ("nfs4_acls.c: file [%s]: could not " - "convert %s to uid or gid\n", - filename->base_name, - sid_string_dbg(&ace_nt->trustee))); - return False; + + sid_copy(&sid, &mapped); + } + + if (type == SID_NAME_USER) { + if (!sid_to_uid(&sid, &uid)) { + DEBUG(1, ("nfs4_acls.c: file [%s]: could not " + "convert %s to uid\n", filename, + sid_string_dbg(&sid))); + return False; + } + ace_v4->who.uid = uid; + + } else { /* else group? - TODO check it... */ + if (!sid_to_gid(&sid, &gid)) { + DEBUG(1, ("nfs4_acls.c: file [%s]: could not " + "convert %s to gid\n", filename, + sid_string_dbg(&sid))); + return False; + } + ace_v4->aceFlags |= SMB_ACE4_IDENTIFIER_GROUP; + ace_v4->who.gid = gid; } } @@ -888,7 +917,6 @@ static SMB4ACL_T *smbacl4_win2nfs4( bool addNewACE = True; if (!smbacl4_fill_ace4(fsp->fsp_name, pparams, - ownerUID, ownerGID, dacl->aces + i, &ace_v4)) { DEBUG(3, ("Could not fill ace for file %s, SID %s\n", filename, @@ -906,6 +934,10 @@ static SMB4ACL_T *smbacl4_win2nfs4( smb_add_ace4(theacl, &ace_v4); } + if (pparams->mode==e_special) { + smbacl4_substitute_special(theacl, ownerUID, ownerGID); + } + if (pparams->mode==e_specialcreator) { smbacl4_expand_special(theacl, ownerUID, ownerGID); } -- 1.7.9.5 From bbe20bec50cb3bafb87a265553761d89794c6894 Mon Sep 17 00:00:00 2001 From: Alexander Werth Date: Wed, 18 Jul 2012 17:18:02 +0200 Subject: [PATCH 6/8] s3: Rewrite ACL with special entries for the owner and group. --- source3/modules/nfs4_acls.c | 90 +++++++++++++++++++++++++++++++++++++++++++ source3/modules/nfs4_acls.h | 17 ++++++++ 2 files changed, 107 insertions(+) diff --git a/source3/modules/nfs4_acls.c b/source3/modules/nfs4_acls.c index 0bed5a1..b87656c 100644 --- a/source3/modules/nfs4_acls.c +++ b/source3/modules/nfs4_acls.c @@ -1046,3 +1046,93 @@ NTSTATUS smb_set_nt_acl_nfs4(files_struct *fsp, DEBUG(10, ("smb_set_nt_acl_nfs4 succeeded\n")); return NT_STATUS_OK; } + +NTSTATUS smb_create_file_nfs4(struct vfs_handle_struct *handle, + struct smb_request *req, + uint16_t root_dir_fid, + struct smb_filename *smb_fname, + uint32_t access_mask, + uint32_t share_access, + uint32_t create_disposition, + uint32_t create_options, + uint32_t file_attributes, + uint32_t oplock_request, + uint64_t allocation_size, + uint32_t private_flags, + struct security_descriptor *sd, + struct ea_list *ea_list, + files_struct **result, + int *pinfo) +{ + NTSTATUS status, status1; + files_struct *fsp = NULL; + uint32 security_info; + int info; + struct security_descriptor *psd = NULL; + + status = SMB_VFS_NEXT_CREATE_FILE(handle, + req, + root_dir_fid, + smb_fname, + access_mask, + share_access, + create_disposition, + create_options, + file_attributes, + oplock_request, + allocation_size, + private_flags, + sd, + ea_list, + result, + &info); + + if (!NT_STATUS_IS_OK(status)) { + goto out; + } + + if (info != FILE_WAS_CREATED) { + /* File/directory was opened, not created. */ + goto out; + } + + fsp = *result; + + if (fsp == NULL) { + /* Only handle success. */ + goto out; + } + + if (sd) { + /* Security descriptor already set. */ + goto out; + } + + if (fsp->base_fsp) { + /* Stream open. */ + goto out; + } + + security_info = (SECINFO_OWNER | SECINFO_GROUP | + SECINFO_DACL | SECINFO_SACL); + + /* Rewrite ACL with special entries for the owner and group */ + status1 = SMB_VFS_FGET_NT_ACL(fsp, security_info, &psd); + + if (!NT_STATUS_IS_OK(status1)) { + goto out; + } + + status1 = SMB_VFS_FSET_NT_ACL(fsp, security_info, psd); + + out: + + if (fsp) { + VFS_REMOVE_FSP_EXTENSION(handle, fsp); + } + + if (NT_STATUS_IS_OK(status) && pinfo) { + *pinfo = info; + } + return status; +} diff --git a/source3/modules/nfs4_acls.h b/source3/modules/nfs4_acls.h index c461229..67a321b 100644 --- a/source3/modules/nfs4_acls.h +++ b/source3/modules/nfs4_acls.h @@ -150,4 +150,21 @@ NTSTATUS smb_set_nt_acl_nfs4(files_struct *fsp, const struct security_descriptor *psd, set_nfs4acl_native_fn_t set_nfs4_native); +NTSTATUS smb_create_file_nfs4(struct vfs_handle_struct *handle, + struct smb_request *req, + uint16_t root_dir_fid, + struct smb_filename *smb_fname, + uint32_t access_mask, + uint32_t share_access, + uint32_t create_disposition, + uint32_t create_options, + uint32_t file_attributes, + uint32_t oplock_request, + uint64_t allocation_size, + uint32_t private_flags, + struct security_descriptor *sd, + struct ea_list *ea_list, + files_struct **result, + int *pinfo); + #endif /* __NFS4_ACLS_H__ */ -- 1.7.9.5 From 40fd7622e0047553315c99eaa667c5175cae06d0 Mon Sep 17 00:00:00 2001 From: Alexander Werth Date: Tue, 24 Jul 2012 13:47:52 +0200 Subject: [PATCH 7/8] s3: Only rewrite acl on mode specialcreator. --- source3/modules/nfs4_acls.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/source3/modules/nfs4_acls.c b/source3/modules/nfs4_acls.c index b87656c..bac8fae 100644 --- a/source3/modules/nfs4_acls.c +++ b/source3/modules/nfs4_acls.c @@ -1069,6 +1069,7 @@ NTSTATUS smb_create_file_nfs4(struct vfs_handle_struct *handle, uint32 security_info; int info; struct security_descriptor *psd = NULL; + smbacl4_vfs_params params; status = SMB_VFS_NEXT_CREATE_FILE(handle, req, @@ -1113,6 +1114,14 @@ NTSTATUS smb_create_file_nfs4(struct vfs_handle_struct *handle, goto out; } + /* Special behaviours */ + if (smbacl4_get_vfs_params(SMBACL4_PARAM_TYPE_NAME, fsp->conn, ¶ms)) + return NT_STATUS_NO_MEMORY; + if (params.mode != e_specialcreator) { + /* We don't need to adjust the ACLs */ + goto out; + } + security_info = (SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL | SECINFO_SACL); -- 1.7.9.5 From c968b8b20646404e4daad84d6edefabcc0a37fc0 Mon Sep 17 00:00:00 2001 From: Alexander Werth Date: Wed, 18 Jul 2012 15:41:25 +0200 Subject: [PATCH 8/8] s3: Add smb_create_file_nfs4 to vfs_fn_pointers. --- source3/modules/vfs_gpfs.c | 1 + 1 file changed, 1 insertion(+) diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index e2058e1..1082a52 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -2019,6 +2019,7 @@ static struct vfs_fn_pointers vfs_gpfs_fns = { .sendfile_fn = vfs_gpfs_sendfile, .fallocate_fn = vfs_gpfs_fallocate, .open_fn = vfs_gpfs_open, + .create_file_nf = smb_create_file_nfs4, .pread_fn = vfs_gpfs_pread, .pread_send_fn = vfs_gpfs_pread_send, .pread_recv_fn = vfs_gpfs_pread_recv, -- 1.7.9.5