X-Git-Url: http://git.samba.org/?a=blobdiff_plain;f=source3%2Fmodules%2Fvfs_solarisacl.c;h=4e0cd475a85b0ea2e2118d2b30e6ac9ae87f5882;hb=HEAD;hp=fbfe664c6ed504f62e789567131beb83ded86aa4;hpb=b4c9cfb2af8f4dd5e18f032c410694e491f1bd74;p=samba.git diff --git a/source3/modules/vfs_solarisacl.c b/source3/modules/vfs_solarisacl.c index fbfe664c6ed..d31bda50233 100644 --- a/source3/modules/vfs_solarisacl.c +++ b/source3/modules/vfs_solarisacl.c @@ -19,7 +19,9 @@ #include "includes.h" - +#include "system/filesys.h" +#include "smbd/smbd.h" +#include "modules/vfs_solarisacl.h" /* typedef struct acl SOLARIS_ACE_T; */ typedef aclent_t SOLARIS_ACE_T; @@ -43,7 +45,7 @@ static bool smb_acl_to_solaris_acl(SMB_ACL_T smb_acl, SOLARIS_ACL_T *solariacl, int *count, SMB_ACL_TYPE_T type); static SMB_ACL_T solaris_acl_to_smb_acl(SOLARIS_ACL_T solarisacl, int count, - SMB_ACL_TYPE_T type); + SMB_ACL_TYPE_T type, TALLOC_CTX *mem_ctx); static SOLARIS_ACL_TAG_T smb_tag_to_solaris_tag(SMB_ACL_TAG_T smb_tag); static SMB_ACL_TAG_T solaris_tag_to_smb_tag(SOLARIS_ACL_TAG_T solaris_tag); static bool solaris_add_to_acl(SOLARIS_ACL_T *solaris_acl, int *count, @@ -60,13 +62,15 @@ static bool solaris_acl_check(SOLARIS_ACL_T solaris_acl, int count); /* public functions - the api */ -SMB_ACL_T solarisacl_sys_acl_get_file(vfs_handle_struct *handle, - const char *path_p, - SMB_ACL_TYPE_T type) +static SMB_ACL_T solarisacl_sys_acl_get_file(vfs_handle_struct *handle, + const struct smb_filename *smb_fname, + SMB_ACL_TYPE_T type, + TALLOC_CTX *mem_ctx) { SMB_ACL_T result = NULL; int count; SOLARIS_ACL_T solaris_acl = NULL; + const char *path_p = smb_fname->base_name; DEBUG(10, ("solarisacl_sys_acl_get_file called for file '%s'.\n", path_p)); @@ -83,7 +87,7 @@ SMB_ACL_T solarisacl_sys_acl_get_file(vfs_handle_struct *handle, if (!solaris_acl_get_file(path_p, &solaris_acl, &count)) { goto done; } - result = solaris_acl_to_smb_acl(solaris_acl, count, type); + result = solaris_acl_to_smb_acl(solaris_acl, count, type, mem_ctx); if (result == NULL) { DEBUG(10, ("conversion solaris_acl -> smb_acl failed (%s).\n", strerror(errno))); @@ -101,7 +105,9 @@ SMB_ACL_T solarisacl_sys_acl_get_file(vfs_handle_struct *handle, * get the access ACL of a file referred to by a fd */ SMB_ACL_T solarisacl_sys_acl_get_fd(vfs_handle_struct *handle, - files_struct *fsp) + files_struct *fsp, + SMB_ACL_TYPE_T type, + TALLOC_CTX *mem_ctx) { SMB_ACL_T result = NULL; int count; @@ -109,7 +115,13 @@ SMB_ACL_T solarisacl_sys_acl_get_fd(vfs_handle_struct *handle, DEBUG(10, ("entering solarisacl_sys_acl_get_fd.\n")); - if (!solaris_acl_get_fd(fsp->fh->fd, &solaris_acl, &count)) { + if (!solaris_acl_get_fd(fsp_get_io_fd(fsp), &solaris_acl, &count)) { + goto done; + } + + if (type != SMB_ACL_TYPE_ACCESS && type != SMB_ACL_TYPE_DEFAULT) { + DEBUG(10, ("invalid SMB_ACL_TYPE given (%d)\n", type)); + errno = EINVAL; goto done; } /* @@ -118,7 +130,7 @@ SMB_ACL_T solarisacl_sys_acl_get_fd(vfs_handle_struct *handle, * access acl. So we need to filter this out here. */ result = solaris_acl_to_smb_acl(solaris_acl, count, - SMB_ACL_TYPE_ACCESS); + type, mem_ctx); if (result == NULL) { DEBUG(10, ("conversion solaris_acl -> smb_acl failed (%s).\n", strerror(errno))); @@ -131,99 +143,19 @@ 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 char *name, - SMB_ACL_TYPE_T type, - SMB_ACL_T theacl) -{ - int ret = -1; - struct stat s; - SOLARIS_ACL_T solaris_acl = NULL; - int count; - - DEBUG(10, ("solarisacl_sys_acl_set_file called for file '%s'\n", - 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. - */ - if (SMB_VFS_STAT(handle->conn, name, &s) != 0) { - DEBUG(10, ("Error in stat call: %s\n", strerror(errno))); - goto done; - } - if (S_ISDIR(s.st_mode)) { - SOLARIS_ACL_T other_acl; - 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(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(name, SETACL, count, solaris_acl); - - done: - DEBUG(10, ("solarisacl_sys_acl_set_file %s.\n", - ((ret != 0) ? "failed" : "succeeded"))); - SAFE_FREE(solaris_acl); - return ret; -} - /* * set the access ACL on the file referred to by a fd */ int solarisacl_sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp, + SMB_ACL_TYPE_T type, SMB_ACL_T theacl) { SOLARIS_ACL_T solaris_acl = NULL; - SOLARIS_ACL_T default_acl = NULL; - int count, default_count; + int count; + SOLARIS_ACL_T other_acl = NULL; + int other_count; + SMB_ACL_TYPE_T other_type; int ret = -1; DEBUG(10, ("entering solarisacl_sys_acl_set_fd\n")); @@ -236,19 +168,24 @@ int solarisacl_sys_acl_set_fd(vfs_handle_struct *handle, * concatenate it with the access acl provided. */ if (!smb_acl_to_solaris_acl(theacl, &solaris_acl, &count, - SMB_ACL_TYPE_ACCESS)) + type)) { DEBUG(10, ("conversion smb_acl -> solaris_acl failed (%s).\n", strerror(errno))); goto done; } - if (!solaris_acl_get_fd(fsp->fh->fd, &default_acl, &default_count)) { + if (!solaris_acl_get_fd(fsp_get_io_fd(fsp), &other_acl, &other_count)) { DEBUG(10, ("error getting (default) acl from fd\n")); goto done; } + + other_type = (type == SMB_ACL_TYPE_ACCESS) + ? SMB_ACL_TYPE_DEFAULT + : SMB_ACL_TYPE_ACCESS; + if (!solaris_add_to_acl(&solaris_acl, &count, - default_acl, default_count, - SMB_ACL_TYPE_DEFAULT)) + other_acl, other_count, + other_type)) { DEBUG(10, ("error adding default acl to solaris acl\n")); goto done; @@ -258,7 +195,7 @@ int solarisacl_sys_acl_set_fd(vfs_handle_struct *handle, goto done; } - ret = facl(fsp->fh->fd, SETACL, count, solaris_acl); + ret = facl(fsp_get_io_fd(fsp), SETACL, count, solaris_acl); if (ret != 0) { DEBUG(10, ("call of facl failed (%s).\n", strerror(errno))); } @@ -267,65 +204,64 @@ int solarisacl_sys_acl_set_fd(vfs_handle_struct *handle, DEBUG(10, ("solarisacl_sys_acl_set_fd %s.\n", ((ret == 0) ? "succeeded" : "failed" ))); SAFE_FREE(solaris_acl); - SAFE_FREE(default_acl); + SAFE_FREE(other_acl); return ret; } /* * delete the default ACL of a directory * - * This is achieved by fetching the access ACL and rewriting it - * directly, via the solaris system call: the SETACL call on + * This is achieved by fetching the access ACL and rewriting it + * directly, via the solaris system call: the SETACL call on * directories writes both the access and the default ACL as provided. * * XXX: posix acl_delete_def_file returns an error if * the file referred to by path is not a directory. - * this function does not complain but the actions + * this function does not complain but the actions * have no effect on a file other than a directory. * But sys_acl_delete_default_file is only called in * smbd/posixacls.c after having checked that the file * is a directory, anyways. So implementing the extra * check is considered unnecessary. --- Agreed? XXX */ -int solarisacl_sys_acl_delete_def_file(vfs_handle_struct *handle, - const char *path) +int solarisacl_sys_acl_delete_def_fd(vfs_handle_struct *handle, + files_struct *fsp) { SMB_ACL_T smb_acl; int ret = -1; SOLARIS_ACL_T solaris_acl = NULL; int count; - DEBUG(10, ("entering solarisacl_sys_acl_delete_def_file.\n")); - - smb_acl = solarisacl_sys_acl_get_file(handle, path, - SMB_ACL_TYPE_ACCESS); + DBG_DEBUG("entering solarisacl_sys_acl_delete_def_fd.\n"); + + smb_acl = solarisacl_sys_acl_get_file(handle, fsp->fsp_name->base_name, + SMB_ACL_TYPE_ACCESS, talloc_tos()); if (smb_acl == NULL) { - DEBUG(10, ("getting file acl failed!\n")); + DBG_DEBUG("getting file acl failed!\n"); goto done; } - if (!smb_acl_to_solaris_acl(smb_acl, &solaris_acl, &count, + if (!smb_acl_to_solaris_acl(smb_acl, &solaris_acl, &count, SMB_ACL_TYPE_ACCESS)) { - DEBUG(10, ("conversion smb_acl -> solaris_acl failed.\n")); + DBG_DEBUG("conversion smb_acl -> solaris_acl failed.\n"); goto done; } if (!solaris_acl_sort(solaris_acl, count)) { - DEBUG(10, ("resulting acl is not valid!\n")); + DBG_DEBUG("resulting acl is not valid!\n"); goto done; } - ret = acl(path, SETACL, count, solaris_acl); + ret = acl(fsp->fsp_name->base_name, SETACL, count, solaris_acl); if (ret != 0) { - DEBUG(10, ("settinge file acl failed!\n")); + DBG_DEBG("settinge file acl failed!\n"); } - + done: - DEBUG(10, ("solarisacl_sys_acl_delete_def_file %s.\n", - ((ret != 0) ? "failed" : "succeeded" ))); - SAFE_FREE(smb_acl); + DBG_DEBUG("solarisacl_sys_acl_delete_def_fd %s.\n", + ((ret != 0) ? "failed" : "succeeded" )); + TALLOC_FREE(smb_acl); return ret; } - /* private functions */ static SOLARIS_ACL_T solaris_acl_init(int count) @@ -368,13 +304,13 @@ static bool smb_acl_to_solaris_acl(SMB_ACL_T smb_acl, switch(solaris_entry.a_type) { case USER: DEBUG(10, ("got tag type USER with uid %u\n", - (unsigned int)smb_entry->uid)); - solaris_entry.a_id = (uid_t)smb_entry->uid; + (unsigned int)smb_entry->info.user.uid)); + solaris_entry.a_id = (uid_t)smb_entry->info.user.uid; break; case GROUP: DEBUG(10, ("got tag type GROUP with gid %u\n", - (unsigned int)smb_entry->gid)); - solaris_entry.a_id = (uid_t)smb_entry->gid; + (unsigned int)smb_entry->info.group.gid)); + solaris_entry.a_id = (uid_t)smb_entry->info.group.gid; break; default: break; @@ -422,12 +358,12 @@ static bool smb_acl_to_solaris_acl(SMB_ACL_T smb_acl, * soaris acl to the SMB_ACL format. */ static SMB_ACL_T solaris_acl_to_smb_acl(SOLARIS_ACL_T solaris_acl, int count, - SMB_ACL_TYPE_T type) + SMB_ACL_TYPE_T type, TALLOC_CTX *mem_ctx) { SMB_ACL_T result; int i; - if ((result = sys_acl_init(0)) == NULL) { + if ((result = sys_acl_init(mem_ctx)) == NULL) { DEBUG(10, ("error allocating memory for SMB_ACL\n")); goto fail; } @@ -438,11 +374,8 @@ static SMB_ACL_T solaris_acl_to_smb_acl(SOLARIS_ACL_T solaris_acl, int count, if (!_IS_OF_TYPE(solaris_acl[i], type)) { continue; } - result = SMB_REALLOC(result, - sizeof(struct smb_acl_t) + - (sizeof(struct smb_acl_entry) * - (result->count + 1))); - if (result == NULL) { + result->acl = talloc_realloc(result, result->acl, struct smb_acl_entry, result->count + 1); + if (result->acl == NULL) { DEBUG(10, ("error reallocating memory for SMB_ACL\n")); goto fail; } @@ -467,7 +400,7 @@ static SMB_ACL_T solaris_acl_to_smb_acl(SOLARIS_ACL_T solaris_acl, int count, goto done; fail: - SAFE_FREE(result); + TALLOC_FREE(result); done: DEBUG(10, ("solaris_acl_to_smb_acl %s\n", ((result == NULL) ? "failed" : "succeeded"))); @@ -749,40 +682,18 @@ static bool solaris_acl_check(SOLARIS_ACL_T solaris_acl, int count) } #endif -/* VFS operations structure */ - -static vfs_op_tuple solarisacl_op_tuples[] = { - /* Disk operations */ - {SMB_VFS_OP(solarisacl_sys_acl_get_file), - SMB_VFS_OP_SYS_ACL_GET_FILE, - SMB_VFS_LAYER_TRANSPARENT}, - - {SMB_VFS_OP(solarisacl_sys_acl_get_fd), - SMB_VFS_OP_SYS_ACL_GET_FD, - SMB_VFS_LAYER_TRANSPARENT}, - - {SMB_VFS_OP(solarisacl_sys_acl_set_file), - SMB_VFS_OP_SYS_ACL_SET_FILE, - SMB_VFS_LAYER_TRANSPARENT}, - - {SMB_VFS_OP(solarisacl_sys_acl_set_fd), - SMB_VFS_OP_SYS_ACL_SET_FD, - SMB_VFS_LAYER_TRANSPARENT}, - - {SMB_VFS_OP(solarisacl_sys_acl_delete_def_file), - SMB_VFS_OP_SYS_ACL_DELETE_DEF_FILE, - SMB_VFS_LAYER_TRANSPARENT}, - - {SMB_VFS_OP(NULL), - SMB_VFS_OP_NOOP, - SMB_VFS_LAYER_NOOP} +static struct vfs_fn_pointers solarisacl_fns = { + .sys_acl_get_fd_fn = solarisacl_sys_acl_get_fd, + .sys_acl_blob_get_fd_fn = posix_sys_acl_blob_get_fd, + .sys_acl_set_fd_fn = solarisacl_sys_acl_set_fd, + .sys_acl_delete_def_fd_fn = solarisacl_sys_acl_delete_def_fd, }; -NTSTATUS vfs_solarisacl_init(void); -NTSTATUS vfs_solarisacl_init(void) +static_decl_vfs; +NTSTATUS vfs_solarisacl_init(TALLOC_CTX *ctx) { return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "solarisacl", - solarisacl_op_tuples); + &solarisacl_fns); } /* ENTE */