From 759cd10ca5b2b43fbd204d3efdc4da96e6c2c3a0 Mon Sep 17 00:00:00 2001 From: Ralph Boehme Date: Tue, 26 Jan 2021 15:50:00 +0100 Subject: [PATCH] vfs: restore platform specific POSIX sys_acl_set_file() functions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 92b149954237a445594c993b79a860c63113d54b removed SMB_VFS_SYS_ACL_SET_FILE() and all the VFS module implementations. But sys_acl_set_file() in vfs_default calls into sys_acl_set_file() in sysacls.c which calls back into platform specific modules. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14619 Signed-off-by: Ralph Boehme Reviewed-by: Björn Jacke Autobuild-User(master): Ralph Böhme Autobuild-Date(master): Thu Jan 28 15:21:02 UTC 2021 on sn-devel-184 (cherry picked from commit c8c2aef0ac613849d641e39193448f3e512caccf) --- source3/modules/vfs_aixacl.c | 21 +++++++ source3/modules/vfs_solarisacl.c | 97 ++++++++++++++++++++++++++++++++ source3/modules/vfs_tru64acl.c | 46 +++++++++++++++ 3 files changed, 164 insertions(+) diff --git a/source3/modules/vfs_aixacl.c b/source3/modules/vfs_aixacl.c index 181d4560cc2..3deea81889f 100644 --- a/source3/modules/vfs_aixacl.c +++ b/source3/modules/vfs_aixacl.c @@ -133,6 +133,27 @@ SMB_ACL_T aixacl_sys_acl_get_fd(vfs_handle_struct *handle, return NULL;*/ } +int aixacl_sys_acl_set_file(vfs_handle_struct *handle, + const struct smb_filename *smb_fname, + SMB_ACL_TYPE_T type, + SMB_ACL_T theacl) +{ + struct acl *file_acl = NULL; + unsigned int rc; + + file_acl = aixacl_smb_to_aixacl(type, theacl); + if (!file_acl) + return -1; + + rc = chacl((char *)smb_fname->base_name,file_acl,file_acl->acl_len); + DEBUG(10,("errno is %d\n",errno)); + DEBUG(10,("return code is %d\n",rc)); + SAFE_FREE(file_acl); + DEBUG(10,("Exiting the aixacl_sys_acl_set_file\n")); + + return rc; +} + int aixacl_sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp, SMB_ACL_TYPE_T type, diff --git a/source3/modules/vfs_solarisacl.c b/source3/modules/vfs_solarisacl.c index b43a57c9c9f..1b3b4ba0706 100644 --- a/source3/modules/vfs_solarisacl.c +++ b/source3/modules/vfs_solarisacl.c @@ -135,6 +135,103 @@ SMB_ACL_T solarisacl_sys_acl_get_fd(vfs_handle_struct *handle, return result; } +int solarisacl_sys_acl_set_file(vfs_handle_struct *handle, + const struct smb_filename *smb_fname_in, + SMB_ACL_TYPE_T type, + SMB_ACL_T theacl) +{ + int ret = -1; + SOLARIS_ACL_T solaris_acl = NULL; + int count; + struct smb_filename *smb_fname = NULL; + + smb_fname = cp_smb_filename_nostream(talloc_tos(), smb_fname_in); + if (smb_fname == NULL) { + errno = ENOMEM; + goto done; + } + + DEBUG(10, ("solarisacl_sys_acl_set_file called for file '%s'\n", + smb_fname->base_name)); + + if ((type != SMB_ACL_TYPE_ACCESS) && (type != SMB_ACL_TYPE_DEFAULT)) { + errno = EINVAL; + DEBUG(10, ("invalid smb acl type given (%d).\n", type)); + goto done; + } + DEBUGADD(10, ("setting %s acl\n", + ((type == SMB_ACL_TYPE_ACCESS) ? "access" : "default"))); + + if(!smb_acl_to_solaris_acl(theacl, &solaris_acl, &count, type)) { + DEBUG(10, ("conversion smb_acl -> solaris_acl failed (%s).\n", + strerror(errno))); + goto done; + } + + /* + * if the file is a directory, there is extra work to do: + * since the solaris acl call stores both the access acl and + * the default acl as provided, we have to get the acl part + * that has not been specified in "type" from the file first + * and concatenate it with the acl provided. + * + * We can directly use SMB_VFS_STAT here, as if this was a + * POSIX call on a symlink, we've already refused it. + * For a Windows acl mapped call on a symlink, we want to follow + * it. + */ + ret = SMB_VFS_STAT(handle->conn, smb_fname); + if (ret != 0) { + DEBUG(10, ("Error in stat call: %s\n", strerror(errno))); + goto done; + } + if (S_ISDIR(smb_fname->st.st_ex_mode)) { + SOLARIS_ACL_T other_acl = NULL; + int other_count; + SMB_ACL_TYPE_T other_type; + + other_type = (type == SMB_ACL_TYPE_ACCESS) + ? SMB_ACL_TYPE_DEFAULT + : SMB_ACL_TYPE_ACCESS; + DEBUGADD(10, ("getting acl from filesystem\n")); + if (!solaris_acl_get_file(smb_fname->base_name, + &other_acl, &other_count)) { + DEBUG(10, ("error getting acl from directory\n")); + goto done; + } + DEBUG(10, ("adding %s part of fs acl to given acl\n", + ((other_type == SMB_ACL_TYPE_ACCESS) + ? "access" + : "default"))); + if (!solaris_add_to_acl(&solaris_acl, &count, other_acl, + other_count, other_type)) + { + DEBUG(10, ("error adding other acl.\n")); + SAFE_FREE(other_acl); + goto done; + } + SAFE_FREE(other_acl); + } + else if (type != SMB_ACL_TYPE_ACCESS) { + errno = EINVAL; + goto done; + } + + if (!solaris_acl_sort(solaris_acl, count)) { + DEBUG(10, ("resulting acl is not valid!\n")); + goto done; + } + + ret = acl(smb_fname->base_name, SETACL, count, solaris_acl); + + done: + DEBUG(10, ("solarisacl_sys_acl_set_file %s.\n", + ((ret != 0) ? "failed" : "succeeded"))); + SAFE_FREE(solaris_acl); + TALLOC_FREE(smb_fname); + return ret; +} + /* * set the access ACL on the file referred to by a fd */ diff --git a/source3/modules/vfs_tru64acl.c b/source3/modules/vfs_tru64acl.c index 12b50ea042c..24e9a69bf89 100644 --- a/source3/modules/vfs_tru64acl.c +++ b/source3/modules/vfs_tru64acl.c @@ -87,6 +87,52 @@ SMB_ACL_T tru64acl_sys_acl_get_fd(vfs_handle_struct *handle, return result; } +int tru64acl_sys_acl_set_file(vfs_handle_struct *handle, + const struct smb_filename *smb_fname, + SMB_ACL_TYPE_T type, + SMB_ACL_T theacl) +{ + int res; + acl_type_t the_acl_type; + acl_t tru64_acl; + + DEBUG(10, ("tru64acl_sys_acl_set_file called with name %s, type %d\n", + smb_fname->base_name, type)); + + switch(type) { + case SMB_ACL_TYPE_ACCESS: + DEBUGADD(10, ("got acl type ACL_TYPE_ACCESS\n")); + the_acl_type = ACL_TYPE_ACCESS; + break; + case SMB_ACL_TYPE_DEFAULT: + DEBUGADD(10, ("got acl type ACL_TYPE_DEFAULT\n")); + the_acl_type = ACL_TYPE_DEFAULT; + break; + default: + DEBUGADD(10, ("invalid acl type\n")); + errno = EINVAL; + goto fail; + } + + tru64_acl = smb_acl_to_tru64_acl(theacl); + if (tru64_acl == NULL) { + DEBUG(10, ("smb_acl_to_tru64_acl failed!\n")); + goto fail; + } + DEBUG(10, ("got tru64 acl...\n")); + res = acl_set_file((char *)smb_fname->base_name, + the_acl_type, tru64_acl); + acl_free(tru64_acl); + if (res != 0) { + DEBUG(10, ("acl_set_file failed: %s\n", strerror(errno))); + goto fail; + } + return res; +fail: + DEBUG(1, ("tru64acl_sys_acl_set_file failed!\n")); + return -1; +} + int tru64acl_sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp, SMB_ACL_TYPE_T type, -- 2.20.2