1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-23 17:34:34 +03:00

vfs: restore platform specific POSIX sys_acl_set_file() functions

92b1499542 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 <slow@samba.org>
Reviewed-by: Björn Jacke <bjacke@samba.org>

Autobuild-User(master): Ralph Böhme <slow@samba.org>
Autobuild-Date(master): Thu Jan 28 15:21:02 UTC 2021 on sn-devel-184

(cherry picked from commit c8c2aef0ac)
This commit is contained in:
Ralph Boehme 2021-01-26 15:50:00 +01:00 committed by Karolin Seeger
parent 51577d22ef
commit 72dcae2f56
3 changed files with 164 additions and 0 deletions

View File

@ -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,

View File

@ -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
*/

View File

@ -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,