diff options
author | Jeremy Allison <jra@samba.org> | 2012-02-03 14:55:34 -0800 |
---|---|---|
committer | Jeremy Allison <jra@samba.org> | 2012-02-03 14:55:34 -0800 |
commit | 45a3b14beab20445ecffea5f66d278d1bd102c74 (patch) | |
tree | 4877dadaf73d8c9c312d8a4c534bac664be20e26 /source3/modules | |
parent | d9b9ad2af27d4d4ace21838cb90a1714e9168887 (diff) | |
download | samba-45a3b14beab20445ecffea5f66d278d1bd102c74.tar.gz samba-45a3b14beab20445ecffea5f66d278d1bd102c74.tar.xz samba-45a3b14beab20445ecffea5f66d278d1bd102c74.zip |
Fix bug #7933 - samba fails to honor SEC_STD_WRITE_OWNER bit with the acl_xattr module.
Diffstat (limited to 'source3/modules')
-rw-r--r-- | source3/modules/vfs_acl_common.c | 37 |
1 files changed, 36 insertions, 1 deletions
diff --git a/source3/modules/vfs_acl_common.c b/source3/modules/vfs_acl_common.c index e162bb9823..ca303d376e 100644 --- a/source3/modules/vfs_acl_common.c +++ b/source3/modules/vfs_acl_common.c @@ -480,6 +480,7 @@ static NTSTATUS fset_nt_acl_common(vfs_handle_struct *handle, files_struct *fsp, struct security_descriptor *pdesc_next = NULL; struct security_descriptor *psd = NULL; uint8_t hash[XATTR_SD_HASH_SIZE]; + bool chown_needed = false; if (DEBUGLEVEL >= 10) { DEBUG(10,("fset_nt_acl_xattr: incoming sd for file %s\n", @@ -502,9 +503,17 @@ static NTSTATUS fset_nt_acl_common(vfs_handle_struct *handle, files_struct *fsp, psd->type = orig_psd->type | SEC_DESC_SELF_RELATIVE; if ((security_info_sent & SECINFO_OWNER) && (orig_psd->owner_sid != NULL)) { + if (!dom_sid_equal(orig_psd->owner_sid, psd->owner_sid)) { + /* We're changing the owner. */ + chown_needed = true; + } psd->owner_sid = orig_psd->owner_sid; } if ((security_info_sent & SECINFO_GROUP) && (orig_psd->group_sid != NULL)) { + if (!dom_sid_equal(orig_psd->group_sid, psd->group_sid)) { + /* We're changing the group. */ + chown_needed = true; + } psd->group_sid = orig_psd->group_sid; } if (security_info_sent & SECINFO_DACL) { @@ -518,7 +527,33 @@ static NTSTATUS fset_nt_acl_common(vfs_handle_struct *handle, files_struct *fsp, status = SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, security_info_sent, psd); if (!NT_STATUS_IS_OK(status)) { - return status; + if (!NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) { + return status; + } + /* We got access denied here. If we're already root, + or we didn't need to do a chown, or the fsp isn't + open with WRITE_OWNER access, just return. */ + if (get_current_uid(handle->conn) == 0 || + chown_needed == false || + !(fsp->access_mask & SEC_STD_WRITE_OWNER)) { + return NT_STATUS_ACCESS_DENIED; + } + + DEBUG(10,("fset_nt_acl_common: overriding chown on file %s " + "for sid %s\n", + fsp_str_dbg(fsp), + sid_string_tos(psd->owner_sid) + )); + + /* Ok, we failed to chown and we have + SEC_STD_WRITE_OWNER access - override. */ + become_root(); + status = SMB_VFS_NEXT_FSET_NT_ACL(handle, fsp, + security_info_sent, psd); + unbecome_root(); + if (!NT_STATUS_IS_OK(status)) { + return status; + } } /* Get the full underlying sd, then hash. */ |