From 5a62dfe8e9304f7ae99a3b74e33372f67fc1d6c2 Mon Sep 17 00:00:00 2001 From: Boris Lechner Date: Wed, 11 Feb 2015 18:05:44 +0100 Subject: [PATCH] vfs_acl_xattr: propagate gid when container has sgid bit set Bug 8938 - When storing ACL blob, check if container has sgid bit set, and set the contents gid to the container's gid, instead of setting it to user's main gid. To keep ACL display clean, option acl_xattr:ignore should be enabled. Boris Lechner --- source3/modules/vfs_acl_xattr.c | 57 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/source3/modules/vfs_acl_xattr.c b/source3/modules/vfs_acl_xattr.c index c1b0a60..fefd9d9 100644 --- a/source3/modules/vfs_acl_xattr.c +++ b/source3/modules/vfs_acl_xattr.c @@ -92,6 +92,56 @@ static NTSTATUS get_acl_blob(TALLOC_CTX *ctx, } /******************************************************************* + Honor container sgid if any +*******************************************************************/ + +static int store_acl_blob_honor_sgid_fsp(vfs_handle_struct *handle, + files_struct *fsp) +{ + struct smb_filename parent = { 0, }; + int res; + + + // Retrieve parent dir name + if (!parent_dirname(talloc_tos(), fsp->fsp_name->base_name, + &parent.base_name, NULL)) + { + DEBUG(5, ("unable to get parent_dirname\n")); + return -1; + } + + // Parent has sgid ? + res = SMB_VFS_NEXT_STAT(handle, &parent); + if (res == -1) { + DEBUG(5, ("SMB_VFS_NEXT_STAT(%s) failed: %s\n", + parent.base_name, strerror(errno))); + TALLOC_FREE(parent.base_name); + return -2; + } + TALLOC_FREE(parent.base_name); + + if ((parent.st.st_ex_mode & S_ISGID) == 0) { + DEBUG(10, ("Parent has no SGID\n")); + return 0; + } + + // Doing chown for gid + become_root(); + res = SMB_VFS_NEXT_CHOWN(handle, fsp->fsp_name->base_name, + -1, parent.st.st_ex_gid); + unbecome_root(); + + if (res == -1) { + DEBUG(5, ("CHOWN(%s, -1; %u) failed: %s\n", + fsp->fsp_name->base_name, parent.st.st_ex_gid, + strerror(errno))); + return -3; + } + + return 0; +} + +/******************************************************************* Store a DATA_BLOB into an xattr given an fsp pointer. *******************************************************************/ @@ -104,6 +154,13 @@ static NTSTATUS store_acl_blob_fsp(vfs_handle_struct *handle, DEBUG(10,("store_acl_blob_fsp: storing blob length %u on file %s\n", (unsigned int)pblob->length, fsp_str_dbg(fsp))); + + // Check if container has sgid bit, and set its gid if necessary + ret = store_acl_blob_honor_sgid_fsp(handle, fsp); + if (ret < 0) { + DEBUG(5, ("store_acl_blob_sgid_check failed(%d)\n", + ret)); + } become_root(); if (fsp->fh->fd != -1) { -- 1.9.1