From 4fe70bcee2ec8515f123d8c826631b54bbf793e7 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Thu, 9 Nov 2006 20:29:31 +0000 Subject: r19647: Add some GPFS support in a vfs mod. Also adds the kernel flock op to the vfs layer, since gpfs supports it. Thanks to Volker, Christian, Mathias, Chetan, and Peter. (This used to be commit 0620658890fa9c68a9848538728023192319c81a) --- source3/modules/vfs_gpfs.c | 68 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) create mode 100644 source3/modules/vfs_gpfs.c (limited to 'source3/modules/vfs_gpfs.c') diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c new file mode 100644 index 0000000000..c5658ceb51 --- /dev/null +++ b/source3/modules/vfs_gpfs.c @@ -0,0 +1,68 @@ +/* + Unix SMB/CIFS implementation. + Wrap gpfs calls in vfs functions. + + Copyright (C) Christian Ambach 2006 + + Major code contributions by Chetan Shringarpure + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + +*/ + +#include "includes.h" + + +static int vfs_gpfs_kernel_flock(vfs_handle_struct *handle, files_struct *fsp, + int fd, uint32 share_mode) +{ + + START_PROFILE(syscall_kernel_flock); + + kernel_flock(fsp->fh->fd, share_mode); + + if (!set_gpfs_sharemode(fsp, fsp->access_mask, fsp->share_access)) { + + return -1; + + } + + END_PROFILE(syscall_kernel_flock); + + return 0; +} + + +static vfs_op_tuple gpfs_op_tuples[] = { + + {SMB_VFS_OP(vfs_gpfs_kernel_flock), + SMB_VFS_OP_KERNEL_FLOCK, + SMB_VFS_LAYER_OPAQUE}, + + {SMB_VFS_OP(NULL), + SMB_VFS_OP_NOOP, + SMB_VFS_LAYER_NOOP} + +}; + + +NTSTATUS vfs_gpfs_init(void) +{ + init_gpfs(); + + return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "gpfs", + gpfs_op_tuples); +} -- cgit From 19ddef3dd9065b04896c626e7b4c691c7bbbec53 Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Fri, 8 Dec 2006 18:56:01 +0000 Subject: r20089: Put gpfs acl function into vfs_gpfs module. Thanks to Gomati Mohanan . Also fix fields for sec_desc differences between 3.0 and 3.0.24 in nfs4_acls.c. (This used to be commit 3d6f387783467bbd7ea88d6a853b41572badf1ef) --- source3/modules/vfs_gpfs.c | 576 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 576 insertions(+) (limited to 'source3/modules/vfs_gpfs.c') diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index c5658ceb51..9cc9f78381 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -5,6 +5,7 @@ Copyright (C) Christian Ambach 2006 Major code contributions by Chetan Shringarpure + and Gomati Mohanan This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -25,6 +26,12 @@ #include "includes.h" +#undef DBGC_CLASS +#define DBGC_CLASS DBGC_VFS + +#include +#include "nfs4_acls.h" + static int vfs_gpfs_kernel_flock(vfs_handle_struct *handle, files_struct *fsp, int fd, uint32 share_mode) @@ -45,6 +52,539 @@ static int vfs_gpfs_kernel_flock(vfs_handle_struct *handle, files_struct *fsp, return 0; } +static void gpfs_dumpacl(int level, struct gpfs_acl *gacl) +{ + int i; + if (gacl==NULL) + { + DEBUG(0, ("gpfs acl is NULL\n")); + return; + } + + DEBUG(level, ("gpfs acl: nace: %d, type:%d, version:%d, level:%d, len:%d\n", + gacl->acl_nace, gacl->acl_type, gacl->acl_version, gacl->acl_level, gacl->acl_len)); + for(i=0; iacl_nace; i++) + { + struct gpfs_ace_v4 *gace = gacl->ace_v4 + i; + DEBUG(level, ("\tace[%d]: type:%d, flags:0x%x, mask:0x%x, iflags:0x%x, who:%u\n", + i, gace->aceType, gace->aceFlags, gace->aceMask, + gace->aceIFlags, gace->aceWho)); + } +} + +static struct gpfs_acl *gpfs_getacl_alloc(const char *fname, gpfs_aclType_t type) +{ + struct gpfs_acl *acl; + size_t len = 200; + int ret; + TALLOC_CTX *mem_ctx = main_loop_talloc_get(); + + acl = (struct gpfs_acl *)talloc_size(mem_ctx, len); + if (acl == NULL) { + errno = ENOMEM; + return NULL; + } + + acl->acl_len = len; + acl->acl_level = 0; + acl->acl_version = 0; + acl->acl_type = type; + + ret = smbd_gpfs_getacl((char *)fname, GPFS_GETACL_STRUCT | GPFS_ACL_SAMBA, acl); + if ((ret != 0) && (errno == ENOSPC)) { + struct gpfs_acl *new_acl = (struct gpfs_acl *)talloc_size( + mem_ctx, acl->acl_len + sizeof(struct gpfs_acl)); + if (new_acl == NULL) { + errno = ENOMEM; + return NULL; + } + + new_acl->acl_len = acl->acl_len; + new_acl->acl_level = acl->acl_level; + new_acl->acl_version = acl->acl_version; + new_acl->acl_type = acl->acl_type; + acl = new_acl; + + ret = smbd_gpfs_getacl((char *)fname, GPFS_GETACL_STRUCT | GPFS_ACL_SAMBA, acl); + } + if (ret != 0) + { + DEBUG(8, ("smbd_gpfs_getacl failed with %s\n",strerror(errno))); + return NULL; + } + + return acl; +} + +static BOOL gpfs_get_nfs4_acl(struct files_struct *fsp, SMB4ACL_T **ppacl, BOOL *pretryPosix) +{ + TALLOC_CTX *mem_ctx; + int i; + struct gpfs_acl *gacl = NULL; + + mem_ctx = main_loop_talloc_get(); + + DEBUG(10, ("gpfs_get_nfs4_acl invoked for %s\n", fsp->fsp_name)); + + /* First get the real acl length */ + gacl = gpfs_getacl_alloc(fsp->fsp_name, GPFS_ACL_TYPE_NFS4); + if (gacl == NULL) { + DEBUG(9, ("gpfs_getacl failed for %s with %s\n", + fsp->fsp_name, strerror(errno))); + return False; + } + + if (gacl->acl_type != GPFS_ACL_TYPE_NFS4) { + DEBUG(10, ("Got non-nfsv4 acl\n")); + *pretryPosix = True; + return False; + } + + *ppacl = smb_create_smb4acl(); + + DEBUG(10, ("len: %d, level: %d, version: %d, nace: %d\n", + gacl->acl_len, gacl->acl_level, gacl->acl_version, + gacl->acl_nace)); + + for (i=0; iacl_nace; i++) { + struct gpfs_ace_v4 *gace = &gacl->ace_v4[i]; + SMB_ACE4PROP_T smbace; + memset(&smbace, 0, sizeof(SMB4ACE_T)); + + DEBUG(10, ("type: %d, iflags: %x, flags: %x, mask: %x, " + "who: %d\n", gace->aceType, gace->aceIFlags, + gace->aceFlags, gace->aceMask, gace->aceWho)); + + if (gace->aceIFlags & ACE4_IFLAG_SPECIAL_ID) { + smbace.flags |= SMB_ACE4_ID_SPECIAL; + switch (gace->aceWho) { + case ACE4_SPECIAL_OWNER: + smbace.who.special_id = SMB_ACE4_WHO_OWNER; + break; + case ACE4_SPECIAL_GROUP: + smbace.who.special_id = SMB_ACE4_WHO_GROUP; + break; + case ACE4_SPECIAL_EVERYONE: + smbace.who.special_id = SMB_ACE4_WHO_EVERYONE; + break; + default: + DEBUG(8, ("invalid special gpfs id %d " + "ignored\n", gace->aceWho)); + continue; /* don't add it */ + } + } else { + if (gace->aceFlags & ACE4_FLAG_GROUP_ID) + smbace.who.gid = gace->aceWho; + else + smbace.who.uid = gace->aceWho; + } + + smbace.aceType = gace->aceType; + smbace.aceFlags = gace->aceFlags; + smbace.aceMask = gace->aceMask; + smbace.flags = (gace->aceIFlags&ACE4_IFLAG_SPECIAL_ID) ? SMB_ACE4_ID_SPECIAL : 0; + + smb_add_ace4(*ppacl, &smbace); + } + + return True; +} + +static size_t gpfsacl_get_nt_acl_common(files_struct *fsp, + uint32 security_info, SEC_DESC **ppdesc) +{ + SMB4ACL_T *pacl = NULL; + BOOL result; + BOOL retryPosix = False; + + *ppdesc = NULL; + result = gpfs_get_nfs4_acl(fsp, &pacl, &retryPosix); + if (retryPosix) + { + DEBUG(10, ("retrying with posix acl...\n")); + return get_nt_acl(fsp, security_info, ppdesc); + } + if (result==False) + return 0; + + return smb_get_nt_acl_nfs4(fsp, security_info, ppdesc, pacl); +} + +size_t gpfsacl_fget_nt_acl(vfs_handle_struct *handle, + files_struct *fsp, int fd, uint32 security_info, + SEC_DESC **ppdesc) +{ + return gpfsacl_get_nt_acl_common(fsp, security_info, ppdesc); +} + +size_t gpfsacl_get_nt_acl(vfs_handle_struct *handle, + files_struct *fsp, const char *name, + uint32 security_info, SEC_DESC **ppdesc) +{ + return gpfsacl_get_nt_acl_common(fsp, security_info, ppdesc); +} + +static BOOL gpfsacl_process_smbacl(files_struct *fsp, SMB4ACL_T *smbacl) +{ + int ret; + gpfs_aclLen_t gacl_len; + SMB4ACE_T *smbace; + struct gpfs_acl *gacl; + TALLOC_CTX *mem_ctx = main_loop_talloc_get(); + + gacl_len = sizeof(struct gpfs_acl) + + (smb_get_naces(smbacl)-1)*sizeof(gpfs_ace_v4_t); + + gacl = talloc_size(mem_ctx, gacl_len); + if (gacl == NULL) { + DEBUG(0, ("talloc failed\n")); + errno = ENOMEM; + return False; + } + + gacl->acl_len = gacl_len; + gacl->acl_level = 0; + gacl->acl_version = GPFS_ACL_VERSION_NFS4; + gacl->acl_type = GPFS_ACL_TYPE_NFS4; + gacl->acl_nace = 0; /* change later... */ + + for (smbace=smb_first_ace4(smbacl); smbace!=NULL; smbace = smb_next_ace4(smbace)) { + struct gpfs_ace_v4 *gace = &gacl->ace_v4[gacl->acl_nace]; + SMB_ACE4PROP_T *aceprop = smb_get_ace4(smbace); + + gace->aceType = aceprop->aceType; + gace->aceFlags = aceprop->aceFlags; + gace->aceMask = aceprop->aceMask; + gace->aceIFlags = (aceprop->flags&SMB_ACE4_ID_SPECIAL) ? ACE4_IFLAG_SPECIAL_ID : 0; + + if (aceprop->flags&SMB_ACE4_ID_SPECIAL) + { + switch(aceprop->who.special_id) + { + case SMB_ACE4_WHO_EVERYONE: + gace->aceWho = ACE4_SPECIAL_EVERYONE; + break; + case SMB_ACE4_WHO_OWNER: + gace->aceWho = ACE4_SPECIAL_OWNER; + break; + case SMB_ACE4_WHO_GROUP: + gace->aceWho = ACE4_SPECIAL_GROUP; + break; + default: + DEBUG(8, ("unsupported special_id %d\n", aceprop->who.special_id)); + continue; /* don't add it !!! */ + } + } else { + /* just only for the type safety... */ + if (aceprop->aceFlags&SMB_ACE4_IDENTIFIER_GROUP) + gace->aceWho = aceprop->who.gid; + else + gace->aceWho = aceprop->who.uid; + } + + gacl->acl_nace++; + } + + ret = smbd_gpfs_putacl(fsp->fsp_name, GPFS_PUTACL_STRUCT | GPFS_ACL_SAMBA, gacl); + if (ret != 0) { + DEBUG(8, ("gpfs_putacl failed with %s\n", strerror(errno))); + gpfs_dumpacl(8, gacl); + return False; + } + + DEBUG(10, ("gpfs_putacl succeeded\n")); + return True; +} + +static BOOL gpfsacl_set_nt_acl_internal(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) +{ + struct gpfs_acl *acl; + BOOL result = False; + + acl = gpfs_getacl_alloc(fsp->fsp_name, GPFS_ACL_TYPE_ACCESS); + if (acl == NULL) + return False; + + if (acl->acl_version&GPFS_ACL_VERSION_NFS4) + { + result = smb_set_nt_acl_nfs4( + fsp, security_info_sent, psd, + gpfsacl_process_smbacl); + } else { /* assume POSIX ACL - by default... */ + result = set_nt_acl(fsp, security_info_sent, psd); + } + + return result; +} + +static BOOL gpfsacl_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, uint32 security_info_sent, SEC_DESC *psd) +{ + return gpfsacl_set_nt_acl_internal(fsp, security_info_sent, psd); +} + +static BOOL gpfsacl_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, char *name, uint32 security_info_sent, SEC_DESC *psd) +{ + return gpfsacl_set_nt_acl_internal(fsp, security_info_sent, psd); +} + +static SMB_ACL_T gpfs2smb_acl(const struct gpfs_acl *pacl) +{ + SMB_ACL_T result; + int i; + + result = sys_acl_init(pacl->acl_nace); + if (result == NULL) { + errno = ENOMEM; + return NULL; + } + + result->count = pacl->acl_nace; + + for (i=0; iacl_nace; i++) { + struct smb_acl_entry *ace = &result->acl[i]; + const struct gpfs_ace_v1 *g_ace = &pacl->ace_v1[i]; + + DEBUG(10, ("Converting type %d id %lu perm %x\n", + (int)g_ace->ace_type, (unsigned long)g_ace->ace_who, + (int)g_ace->ace_perm)); + + switch (g_ace->ace_type) { + case GPFS_ACL_USER: + ace->a_type = SMB_ACL_USER; + ace->uid = (uid_t)g_ace->ace_who; + break; + case GPFS_ACL_USER_OBJ: + ace->a_type = SMB_ACL_USER_OBJ; + break; + case GPFS_ACL_GROUP: + ace->a_type = SMB_ACL_GROUP; + ace->gid = (gid_t)g_ace->ace_who; + break; + case GPFS_ACL_GROUP_OBJ: + ace->a_type = SMB_ACL_GROUP_OBJ; + break; + case GPFS_ACL_OTHER: + ace->a_type = SMB_ACL_OTHER; + break; + case GPFS_ACL_MASK: + ace->a_type = SMB_ACL_MASK; + break; + default: + DEBUG(10, ("Got invalid ace_type: %d\n", + g_ace->ace_type)); + errno = EINVAL; + SAFE_FREE(result); + return NULL; + } + + ace->a_perm = 0; + ace->a_perm |= (g_ace->ace_perm & ACL_PERM_READ) ? + SMB_ACL_READ : 0; + ace->a_perm |= (g_ace->ace_perm & ACL_PERM_WRITE) ? + SMB_ACL_WRITE : 0; + ace->a_perm |= (g_ace->ace_perm & ACL_PERM_EXECUTE) ? + SMB_ACL_EXECUTE : 0; + + DEBUGADD(10, ("Converted to %d perm %x\n", + ace->a_type, ace->a_perm)); + } + + return result; +} + +static SMB_ACL_T gpfsacl_get_posix_acl(const char *path, gpfs_aclType_t type) +{ + struct gpfs_acl *pacl; + SMB_ACL_T result = NULL; + + pacl = gpfs_getacl_alloc(path, type); + + if (pacl == NULL) { + DEBUG(10, ("gpfs_getacl failed for %s with %s\n", + path, strerror(errno))); + if (errno == 0) { + errno = EINVAL; + } + goto done; + } + + if (pacl->acl_version != GPFS_ACL_VERSION_POSIX) { + DEBUG(10, ("Got acl version %d, expected %d\n", + pacl->acl_version, GPFS_ACL_VERSION_POSIX)); + errno = EINVAL; + goto done; + } + + DEBUG(10, ("len: %d, level: %d, version: %d, nace: %d\n", + pacl->acl_len, pacl->acl_level, pacl->acl_version, + pacl->acl_nace)); + + result = gpfs2smb_acl(pacl); + if (result == NULL) { + goto done; + } + + done: + + if (errno != 0) { + SAFE_FREE(result); + } + return result; +} + +SMB_ACL_T gpfsacl_sys_acl_get_file(vfs_handle_struct *handle, + + const char *path_p, + SMB_ACL_TYPE_T type) +{ + gpfs_aclType_t gpfs_type; + + switch(type) { + case SMB_ACL_TYPE_ACCESS: + gpfs_type = GPFS_ACL_TYPE_ACCESS; + break; + case SMB_ACL_TYPE_DEFAULT: + gpfs_type = GPFS_ACL_TYPE_DEFAULT; + break; + default: + DEBUG(0, ("Got invalid type: %d\n", type)); + smb_panic("exiting"); + } + + return gpfsacl_get_posix_acl(path_p, gpfs_type); +} + +SMB_ACL_T gpfsacl_sys_acl_get_fd(vfs_handle_struct *handle, + files_struct *fsp, + int fd) +{ + return gpfsacl_get_posix_acl(fsp->fsp_name, GPFS_ACL_TYPE_ACCESS); +} + +static struct gpfs_acl *smb2gpfs_acl(const SMB_ACL_T pacl, + SMB_ACL_TYPE_T type) +{ + gpfs_aclLen_t len; + struct gpfs_acl *result; + int i; + union gpfs_ace_union + { + gpfs_ace_v1_t ace_v1[1]; /* when GPFS_ACL_VERSION_POSIX */ + gpfs_ace_v4_t ace_v4[1]; /* when GPFS_ACL_VERSION_NFS4 */ + }; + + DEBUG(10, ("smb2gpfs_acl: Got ACL with %d entries\n", pacl->count)); + + len = sizeof(struct gpfs_acl) - sizeof(union gpfs_ace_union) + + (pacl->count)*sizeof(gpfs_ace_v1_t); + + result = SMB_MALLOC(len); + if (result == NULL) { + errno = ENOMEM; + return result; + } + + result->acl_len = len; + result->acl_level = 0; + result->acl_version = GPFS_ACL_VERSION_POSIX; + result->acl_type = (type == SMB_ACL_TYPE_DEFAULT) ? + GPFS_ACL_TYPE_DEFAULT : GPFS_ACL_TYPE_ACCESS; + result->acl_nace = pacl->count; + + for (i=0; icount; i++) { + const struct smb_acl_entry *ace = &pacl->acl[i]; + struct gpfs_ace_v1 *g_ace = &result->ace_v1[i]; + + DEBUG(10, ("Converting type %d perm %x\n", + (int)ace->a_type, (int)ace->a_perm)); + + g_ace->ace_perm = 0; + + switch(ace->a_type) { + case SMB_ACL_USER: + g_ace->ace_type = GPFS_ACL_USER; + g_ace->ace_who = (gpfs_uid_t)ace->uid; + break; + case SMB_ACL_USER_OBJ: + g_ace->ace_type = GPFS_ACL_USER_OBJ; + g_ace->ace_perm |= ACL_PERM_CONTROL; + g_ace->ace_who = 0; + break; + case SMB_ACL_GROUP: + g_ace->ace_type = GPFS_ACL_GROUP; + g_ace->ace_who = (gpfs_uid_t)ace->gid; + break; + case SMB_ACL_GROUP_OBJ: + g_ace->ace_type = GPFS_ACL_GROUP_OBJ; + g_ace->ace_who = 0; + break; + case SMB_ACL_MASK: + g_ace->ace_type = GPFS_ACL_MASK; + g_ace->ace_perm = 0x8f; + g_ace->ace_who = 0; + break; + case SMB_ACL_OTHER: + g_ace->ace_type = GPFS_ACL_OTHER; + g_ace->ace_who = 0; + break; + default: + DEBUG(10, ("Got invalid ace_type: %d\n", ace->a_type)); + errno = EINVAL; + SAFE_FREE(result); + return NULL; + } + + g_ace->ace_perm |= (ace->a_perm & SMB_ACL_READ) ? + ACL_PERM_READ : 0; + g_ace->ace_perm |= (ace->a_perm & SMB_ACL_WRITE) ? + ACL_PERM_WRITE : 0; + g_ace->ace_perm |= (ace->a_perm & SMB_ACL_EXECUTE) ? + ACL_PERM_EXECUTE : 0; + + DEBUGADD(10, ("Converted to %d id %d perm %x\n", + g_ace->ace_type, g_ace->ace_who, g_ace->ace_perm)); + } + + return result; +} + +int gpfsacl_sys_acl_set_file(vfs_handle_struct *handle, + + const char *name, + SMB_ACL_TYPE_T type, + SMB_ACL_T theacl) +{ + struct gpfs_acl *gpfs_acl; + int result; + + gpfs_acl = smb2gpfs_acl(theacl, type); + if (gpfs_acl == NULL) { + return -1; + } + + result = smbd_gpfs_putacl((char *)name, GPFS_PUTACL_STRUCT | GPFS_ACL_SAMBA, gpfs_acl); + + SAFE_FREE(gpfs_acl); + return result; +} + +int gpfsacl_sys_acl_set_fd(vfs_handle_struct *handle, + files_struct *fsp, + int fd, SMB_ACL_T theacl) +{ + errno = ENOTSUP; + return -1; +} + +int gpfsacl_sys_acl_delete_def_file(vfs_handle_struct *handle, + + const char *path) +{ + errno = ENOTSUP; + return -1; +} + +/* VFS operations structure */ static vfs_op_tuple gpfs_op_tuples[] = { @@ -52,6 +592,42 @@ static vfs_op_tuple gpfs_op_tuples[] = { SMB_VFS_OP_KERNEL_FLOCK, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(gpfsacl_fget_nt_acl), + SMB_VFS_OP_FGET_NT_ACL, + SMB_VFS_LAYER_TRANSPARENT}, + + {SMB_VFS_OP(gpfsacl_get_nt_acl), + SMB_VFS_OP_GET_NT_ACL, + SMB_VFS_LAYER_TRANSPARENT}, + + {SMB_VFS_OP(gpfsacl_fset_nt_acl), + SMB_VFS_OP_FSET_NT_ACL, + SMB_VFS_LAYER_TRANSPARENT}, + + {SMB_VFS_OP(gpfsacl_set_nt_acl), + SMB_VFS_OP_SET_NT_ACL, + SMB_VFS_LAYER_TRANSPARENT}, + + {SMB_VFS_OP(gpfsacl_sys_acl_get_file), + SMB_VFS_OP_SYS_ACL_GET_FILE, + SMB_VFS_LAYER_TRANSPARENT}, + + {SMB_VFS_OP(gpfsacl_sys_acl_get_fd), + SMB_VFS_OP_SYS_ACL_GET_FD, + SMB_VFS_LAYER_TRANSPARENT}, + + {SMB_VFS_OP(gpfsacl_sys_acl_set_file), + SMB_VFS_OP_SYS_ACL_SET_FILE, + SMB_VFS_LAYER_TRANSPARENT}, + + {SMB_VFS_OP(gpfsacl_sys_acl_set_fd), + SMB_VFS_OP_SYS_ACL_SET_FD, + SMB_VFS_LAYER_TRANSPARENT}, + + {SMB_VFS_OP(gpfsacl_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} -- cgit From 55ed1d59455566d90a03e7123fbf7a05a4bd4539 Mon Sep 17 00:00:00 2001 From: Herb Lewis Date: Tue, 19 Dec 2006 20:16:52 +0000 Subject: r20261: merge 20260 from samba_3_0_24 clean up a bunch of no previous prototype warnings (This used to be commit c60687db112405262adf26dbf267804b04074e67) --- source3/modules/vfs_gpfs.c | 1 + 1 file changed, 1 insertion(+) (limited to 'source3/modules/vfs_gpfs.c') diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index 9cc9f78381..c8bb848d0f 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -635,6 +635,7 @@ static vfs_op_tuple gpfs_op_tuples[] = { }; +NTSTATUS vfs_gpfs_init(void); NTSTATUS vfs_gpfs_init(void) { init_gpfs(); -- cgit From 5a052edf031d2c02b018743f0947a12b4df16c2d Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Wed, 14 Feb 2007 02:37:14 +0000 Subject: r21324: Add linux setlease to the vfs layer. Next round, as Volker points out, it should be abstracted a little higher up so other os'es can have an entry, but it will take a bit more work. Thanks to Chetan Shringarpure and Mathias Dietz. I didn't increment the vfs number again because the kernel change notify stuff hasn't been released yet anyway. (This used to be commit 9463211bf3b46ee408b88dfbf42d498e3839d4cc) --- source3/modules/vfs_gpfs.c | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (limited to 'source3/modules/vfs_gpfs.c') diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index c8bb848d0f..20c9f56a17 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -52,6 +52,31 @@ static int vfs_gpfs_kernel_flock(vfs_handle_struct *handle, files_struct *fsp, return 0; } +static int vfs_gpfs_setlease(vfs_handle_struct *handle, files_struct *fsp, + int fd, int leasetype) +{ + int ret; + + START_PROFILE(syscall_linux_setlease); + + if ( linux_set_lease_sighandler(fd) == -1) + return -1; + + ret = set_gpfs_lease(fd,leasetype); + + if ( ret < 0 ) { + /* This must have come from GPFS not being available */ + /* or some other error, hence call the default */ + ret = linux_setlease(fd, leasetype); + } + + END_PROFILE(syscall_linux_setlease); + + return ret; +} + + + static void gpfs_dumpacl(int level, struct gpfs_acl *gacl) { int i; @@ -592,6 +617,10 @@ static vfs_op_tuple gpfs_op_tuples[] = { SMB_VFS_OP_KERNEL_FLOCK, SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(vfs_gpfs_setlease), + SMB_VFS_OP_LINUX_SETLEASE, + SMB_VFS_LAYER_OPAQUE}, + {SMB_VFS_OP(gpfsacl_fget_nt_acl), SMB_VFS_OP_FGET_NT_ACL, SMB_VFS_LAYER_TRANSPARENT}, -- cgit From d6d35eab6e702c1a132eafb4c334ee4bad8e4f4f Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Tue, 10 Apr 2007 15:41:22 +0000 Subject: r22148: Fix gpfs module on posix-acl test. Adds gpfsacl_sys_set_fd (calls _file). Thanks to Gomati Mohanan. (This used to be commit 859269c9492e002f02415d610c83452538147972) --- source3/modules/vfs_gpfs.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/modules/vfs_gpfs.c') diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index 20c9f56a17..6841300d5b 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -597,8 +597,7 @@ int gpfsacl_sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp, int fd, SMB_ACL_T theacl) { - errno = ENOTSUP; - return -1; + return gpfsacl_sys_acl_set_file(handle, fsp->fsp_name, SMB_ACL_TYPE_ACCESS, theacl); } int gpfsacl_sys_acl_delete_def_file(vfs_handle_struct *handle, -- cgit From 12ba88574bf91bdcc4447bfc3d429b799064bfd9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 27 Apr 2007 23:18:41 +0000 Subject: r22542: Move over to using the _strict varients of the talloc calls. No functional changes. Looks bigger than it is :-). Jeremy. (This used to be commit f6fa3080fee1b20df9f1968500840a88cf0ee592) --- source3/modules/vfs_gpfs.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/modules/vfs_gpfs.c') diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index 6841300d5b..932b5000c8 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -104,7 +104,7 @@ static struct gpfs_acl *gpfs_getacl_alloc(const char *fname, gpfs_aclType_t type int ret; TALLOC_CTX *mem_ctx = main_loop_talloc_get(); - acl = (struct gpfs_acl *)talloc_size(mem_ctx, len); + acl = (struct gpfs_acl *)TALLOC_SIZE(mem_ctx, len); if (acl == NULL) { errno = ENOMEM; return NULL; @@ -117,7 +117,7 @@ static struct gpfs_acl *gpfs_getacl_alloc(const char *fname, gpfs_aclType_t type ret = smbd_gpfs_getacl((char *)fname, GPFS_GETACL_STRUCT | GPFS_ACL_SAMBA, acl); if ((ret != 0) && (errno == ENOSPC)) { - struct gpfs_acl *new_acl = (struct gpfs_acl *)talloc_size( + struct gpfs_acl *new_acl = (struct gpfs_acl *)TALLOC_SIZE( mem_ctx, acl->acl_len + sizeof(struct gpfs_acl)); if (new_acl == NULL) { errno = ENOMEM; @@ -260,7 +260,7 @@ static BOOL gpfsacl_process_smbacl(files_struct *fsp, SMB4ACL_T *smbacl) gacl_len = sizeof(struct gpfs_acl) + (smb_get_naces(smbacl)-1)*sizeof(gpfs_ace_v4_t); - gacl = talloc_size(mem_ctx, gacl_len); + gacl = TALLOC_SIZE(mem_ctx, gacl_len); if (gacl == NULL) { DEBUG(0, ("talloc failed\n")); errno = ENOMEM; -- cgit From ea7f6e7afafb2da4090d02cb5eb128e3bd0ec2cd Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Sat, 2 Jun 2007 06:28:38 +0000 Subject: r23302: Refactor vfs_gpfs module, fix problems with chmod Tridge has found during ctdb tests (This used to be commit e150e42ac59494a1da12bb5c9da8c9c935780924) --- source3/modules/vfs_gpfs.c | 155 +++++++++++++++++++++++++++------------------ 1 file changed, 94 insertions(+), 61 deletions(-) (limited to 'source3/modules/vfs_gpfs.c') diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index 932b5000c8..3795a5d4a6 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -141,28 +141,30 @@ static struct gpfs_acl *gpfs_getacl_alloc(const char *fname, gpfs_aclType_t type return acl; } -static BOOL gpfs_get_nfs4_acl(struct files_struct *fsp, SMB4ACL_T **ppacl, BOOL *pretryPosix) +/* Tries to get nfs4 acls and returns SMB ACL allocated. + * On failure returns 1 if it got non-NFSv4 ACL to prompt + * retry with POSIX ACL checks. + * On failure returns -1 if there is system (GPFS) error, check errno. + * Returns 0 on success + */ +static int gpfs_get_nfs4_acl(const char *fname, SMB4ACL_T **ppacl) { - TALLOC_CTX *mem_ctx; int i; struct gpfs_acl *gacl = NULL; - - mem_ctx = main_loop_talloc_get(); - - DEBUG(10, ("gpfs_get_nfs4_acl invoked for %s\n", fsp->fsp_name)); + DEBUG(10, ("gpfs_get_nfs4_acl invoked for %s\n", fname)); /* First get the real acl length */ - gacl = gpfs_getacl_alloc(fsp->fsp_name, GPFS_ACL_TYPE_NFS4); + gacl = gpfs_getacl_alloc(fname, GPFS_ACL_TYPE_NFS4); if (gacl == NULL) { DEBUG(9, ("gpfs_getacl failed for %s with %s\n", - fsp->fsp_name, strerror(errno))); - return False; + fname, strerror(errno))); + return -1; } if (gacl->acl_type != GPFS_ACL_TYPE_NFS4) { DEBUG(10, ("Got non-nfsv4 acl\n")); - *pretryPosix = True; - return False; + /* Retry with POSIX ACLs check */ + return 1; } *ppacl = smb_create_smb4acl(); @@ -174,12 +176,11 @@ static BOOL gpfs_get_nfs4_acl(struct files_struct *fsp, SMB4ACL_T **ppacl, BOOL for (i=0; iacl_nace; i++) { struct gpfs_ace_v4 *gace = &gacl->ace_v4[i]; SMB_ACE4PROP_T smbace; - memset(&smbace, 0, sizeof(SMB4ACE_T)); - DEBUG(10, ("type: %d, iflags: %x, flags: %x, mask: %x, " "who: %d\n", gace->aceType, gace->aceIFlags, gace->aceFlags, gace->aceMask, gace->aceWho)); + memset(&smbace, 0, sizeof(SMB4ACE_T)); if (gace->aceIFlags & ACE4_IFLAG_SPECIAL_ID) { smbace.flags |= SMB_ACE4_ID_SPECIAL; switch (gace->aceWho) { @@ -204,35 +205,47 @@ static BOOL gpfs_get_nfs4_acl(struct files_struct *fsp, SMB4ACL_T **ppacl, BOOL smbace.who.uid = gace->aceWho; } + /* remove redundent deny entries */ + if (i > 0 && gace->aceType == SMB_ACE4_ACCESS_DENIED_ACE_TYPE) { + struct gpfs_ace_v4 *prev = &gacl->ace_v4[i-1]; + if (prev->aceType == SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE && + prev->aceFlags == gace->aceFlags && + prev->aceIFlags == gace->aceIFlags && + (gace->aceMask & prev->aceMask) == 0 && + gace->aceWho == prev->aceWho) { + /* its redundent - skip it */ + continue; + } + } + smbace.aceType = gace->aceType; smbace.aceFlags = gace->aceFlags; smbace.aceMask = gace->aceMask; - smbace.flags = (gace->aceIFlags&ACE4_IFLAG_SPECIAL_ID) ? SMB_ACE4_ID_SPECIAL : 0; - smb_add_ace4(*ppacl, &smbace); } - return True; + return 0; } static size_t gpfsacl_get_nt_acl_common(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc) { SMB4ACL_T *pacl = NULL; - BOOL result; - BOOL retryPosix = False; + int result; *ppdesc = NULL; - result = gpfs_get_nfs4_acl(fsp, &pacl, &retryPosix); - if (retryPosix) - { + result = gpfs_get_nfs4_acl(fsp->fsp_name, &pacl); + + if (result == 0) + return smb_get_nt_acl_nfs4(fsp, security_info, ppdesc, pacl); + + if (result > 0) { DEBUG(10, ("retrying with posix acl...\n")); return get_nt_acl(fsp, security_info, ppdesc); } - if (result==False) - return 0; - - return smb_get_nt_acl_nfs4(fsp, security_info, ppdesc, pacl); + + /* GPFS ACL was not read, something wrong happened, error code is set in errno */ + return 0; } size_t gpfsacl_fget_nt_acl(vfs_handle_struct *handle, @@ -608,57 +621,77 @@ int gpfsacl_sys_acl_delete_def_file(vfs_handle_struct *handle, return -1; } +static int vfs_gpfs_chmod(vfs_handle_struct *handle, const char *path, mode_t mode) +{ + SMB_STRUCT_STAT st; + if (SMB_VFS_NEXT_STAT(handle, path, &st) != 0) { + return -1; + } + /* avoid chmod() if possible, to preserve acls */ + if ((st.st_mode & ~S_IFMT) == mode) { + return 0; + } + return SMB_VFS_NEXT_CHMOD(handle, path, mode); +} + +static int vfs_gpfs_fchmod(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode) +{ + SMB_STRUCT_STAT st; + if (SMB_VFS_NEXT_FSTAT(handle, fsp, fd, &st) != 0) { + return -1; + } + /* avoid chmod() if possible, to preserve acls */ + if ((st.st_mode & ~S_IFMT) == mode) { + return 0; + } + return SMB_VFS_NEXT_FCHMOD(handle, fsp, fd, mode); +} + /* VFS operations structure */ static vfs_op_tuple gpfs_op_tuples[] = { - {SMB_VFS_OP(vfs_gpfs_kernel_flock), - SMB_VFS_OP_KERNEL_FLOCK, - SMB_VFS_LAYER_OPAQUE}, + { SMB_VFS_OP(vfs_gpfs_kernel_flock), SMB_VFS_OP_KERNEL_FLOCK, + SMB_VFS_LAYER_OPAQUE }, + + { SMB_VFS_OP(vfs_gpfs_setlease), SMB_VFS_OP_LINUX_SETLEASE, + SMB_VFS_LAYER_OPAQUE }, + + { SMB_VFS_OP(gpfsacl_fget_nt_acl), SMB_VFS_OP_FGET_NT_ACL, + SMB_VFS_LAYER_TRANSPARENT }, - {SMB_VFS_OP(vfs_gpfs_setlease), - SMB_VFS_OP_LINUX_SETLEASE, - SMB_VFS_LAYER_OPAQUE}, + { SMB_VFS_OP(gpfsacl_get_nt_acl), SMB_VFS_OP_GET_NT_ACL, + SMB_VFS_LAYER_TRANSPARENT }, - {SMB_VFS_OP(gpfsacl_fget_nt_acl), - SMB_VFS_OP_FGET_NT_ACL, - SMB_VFS_LAYER_TRANSPARENT}, + { SMB_VFS_OP(gpfsacl_fset_nt_acl), SMB_VFS_OP_FSET_NT_ACL, + SMB_VFS_LAYER_TRANSPARENT }, - {SMB_VFS_OP(gpfsacl_get_nt_acl), - SMB_VFS_OP_GET_NT_ACL, - SMB_VFS_LAYER_TRANSPARENT}, + { SMB_VFS_OP(gpfsacl_set_nt_acl), SMB_VFS_OP_SET_NT_ACL, + SMB_VFS_LAYER_TRANSPARENT }, - {SMB_VFS_OP(gpfsacl_fset_nt_acl), - SMB_VFS_OP_FSET_NT_ACL, - SMB_VFS_LAYER_TRANSPARENT}, + { SMB_VFS_OP(gpfsacl_sys_acl_get_file), SMB_VFS_OP_SYS_ACL_GET_FILE, + SMB_VFS_LAYER_TRANSPARENT }, - {SMB_VFS_OP(gpfsacl_set_nt_acl), - SMB_VFS_OP_SET_NT_ACL, - SMB_VFS_LAYER_TRANSPARENT}, + { SMB_VFS_OP(gpfsacl_sys_acl_get_fd), SMB_VFS_OP_SYS_ACL_GET_FD, + SMB_VFS_LAYER_TRANSPARENT }, - {SMB_VFS_OP(gpfsacl_sys_acl_get_file), - SMB_VFS_OP_SYS_ACL_GET_FILE, - SMB_VFS_LAYER_TRANSPARENT}, + { SMB_VFS_OP(gpfsacl_sys_acl_set_file), SMB_VFS_OP_SYS_ACL_SET_FILE, + SMB_VFS_LAYER_TRANSPARENT }, - {SMB_VFS_OP(gpfsacl_sys_acl_get_fd), - SMB_VFS_OP_SYS_ACL_GET_FD, - SMB_VFS_LAYER_TRANSPARENT}, + { SMB_VFS_OP(gpfsacl_sys_acl_set_fd), SMB_VFS_OP_SYS_ACL_SET_FD, + SMB_VFS_LAYER_TRANSPARENT }, - {SMB_VFS_OP(gpfsacl_sys_acl_set_file), - SMB_VFS_OP_SYS_ACL_SET_FILE, - SMB_VFS_LAYER_TRANSPARENT}, + { SMB_VFS_OP(gpfsacl_sys_acl_delete_def_file), + SMB_VFS_OP_SYS_ACL_DELETE_DEF_FILE, + SMB_VFS_LAYER_TRANSPARENT }, - {SMB_VFS_OP(gpfsacl_sys_acl_set_fd), - SMB_VFS_OP_SYS_ACL_SET_FD, - SMB_VFS_LAYER_TRANSPARENT}, + { SMB_VFS_OP(vfs_gpfs_chmod), SMB_VFS_OP_CHMOD, + SMB_VFS_LAYER_TRANSPARENT }, - {SMB_VFS_OP(gpfsacl_sys_acl_delete_def_file), - SMB_VFS_OP_SYS_ACL_DELETE_DEF_FILE, - SMB_VFS_LAYER_TRANSPARENT}, + { SMB_VFS_OP(vfs_gpfs_fchmod), SMB_VFS_OP_FCHMOD, + SMB_VFS_LAYER_TRANSPARENT }, - {SMB_VFS_OP(NULL), - SMB_VFS_OP_NOOP, - SMB_VFS_LAYER_NOOP} + { SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP } }; -- cgit From a0ac7a7f4c0290787cdadb5866272cee2bd61b8a Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 26 Jun 2007 22:49:10 +0000 Subject: r23620: Convert set_nt_acl to return NTSTATUS. Also fix the chown return to correctly return NT_STATUS_INVALID_OWNER if it should be disallowed. Matches better what W2K3R3 does. NFSv4 ACL module owners, please examine these changes. Jeremy. (This used to be commit fc6899a5506b272f8cd5f5837ca13300b4e69a5f) --- source3/modules/vfs_gpfs.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'source3/modules/vfs_gpfs.c') diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index 3795a5d4a6..9c9503e772 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -334,14 +334,14 @@ static BOOL gpfsacl_process_smbacl(files_struct *fsp, SMB4ACL_T *smbacl) return True; } -static BOOL gpfsacl_set_nt_acl_internal(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) +static NTSTATUS gpfsacl_set_nt_acl_internal(files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) { struct gpfs_acl *acl; - BOOL result = False; + NTSTATUS result = NT_STATUS_ACCESS_DENIED; acl = gpfs_getacl_alloc(fsp->fsp_name, GPFS_ACL_TYPE_ACCESS); if (acl == NULL) - return False; + return result; if (acl->acl_version&GPFS_ACL_VERSION_NFS4) { @@ -355,12 +355,12 @@ static BOOL gpfsacl_set_nt_acl_internal(files_struct *fsp, uint32 security_info_ return result; } -static BOOL gpfsacl_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, uint32 security_info_sent, SEC_DESC *psd) +static NTSTATUS gpfsacl_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, uint32 security_info_sent, SEC_DESC *psd) { return gpfsacl_set_nt_acl_internal(fsp, security_info_sent, psd); } -static BOOL gpfsacl_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, char *name, uint32 security_info_sent, SEC_DESC *psd) +static NTSTATUS gpfsacl_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, char *name, uint32 security_info_sent, SEC_DESC *psd) { return gpfsacl_set_nt_acl_internal(fsp, security_info_sent, psd); } -- cgit From d824b98f80ba186030cbb70b3a1e5daf80469ecd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 9 Jul 2007 19:25:36 +0000 Subject: r23779: Change from v2 or later to v3 or later. Jeremy. (This used to be commit 407e6e695b8366369b7c76af1ff76869b45347b3) --- source3/modules/vfs_gpfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/modules/vfs_gpfs.c') diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index 9c9503e772..83f5d6ca3e 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -9,7 +9,7 @@ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, -- cgit From 5e54558c6dea67b56bbfaba5698f3a434d3dffb6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 00:52:41 +0000 Subject: r23784: use the GPLv3 boilerplate as recommended by the FSF and the license text (This used to be commit b0132e94fc5fef936aa766fb99a306b3628e9f07) --- source3/modules/vfs_gpfs.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/modules/vfs_gpfs.c') diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index 83f5d6ca3e..393efd2328 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -18,8 +18,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ -- cgit From 929e1d99209e20a9c2c95c8bdfc8eaa37b2c2291 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Thu, 30 Aug 2007 19:48:31 +0000 Subject: r24809: Consolidate the use of temporary talloc contexts. This adds the two functions talloc_stackframe() and talloc_tos(). * When a new talloc stackframe is allocated with talloc_stackframe(), then * the TALLOC_CTX returned with talloc_tos() is reset to that new * frame. Whenever that stack frame is TALLOC_FREE()'ed, then the reverse * happens: The previous talloc_tos() is restored. * * This API is designed to be robust in the sense that if someone forgets to * TALLOC_FREE() a stackframe, then the next outer one correctly cleans up and * resets the talloc_tos(). The original motivation for this patch was to get rid of the sid_string_static & friends buffers. Explicitly passing talloc context everywhere clutters code too much for my taste, so an implicit talloc_tos() is introduced here. Many of these static buffers are replaced by a single static pointer. The intended use would thus be that low-level functions can rather freely push stuff to talloc_tos, the upper layers clean up by freeing the stackframe. The more of these stackframes are used and correctly freed the more exact the memory cleanup happens. This patch removes the main_loop_talloc_ctx, tmp_talloc_ctx and lp_talloc_ctx (did I forget any?) So, never do a tmp_ctx = talloc_init("foo"); anymore, instead, use tmp_ctx = talloc_stackframe() :-) Volker (This used to be commit 6585ea2cb7f417e14540495b9c7380fe9c8c717b) --- source3/modules/vfs_gpfs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/modules/vfs_gpfs.c') diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index 393efd2328..b8e8209be0 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -101,7 +101,7 @@ static struct gpfs_acl *gpfs_getacl_alloc(const char *fname, gpfs_aclType_t type struct gpfs_acl *acl; size_t len = 200; int ret; - TALLOC_CTX *mem_ctx = main_loop_talloc_get(); + TALLOC_CTX *mem_ctx = talloc_tos(); acl = (struct gpfs_acl *)TALLOC_SIZE(mem_ctx, len); if (acl == NULL) { @@ -267,7 +267,7 @@ static BOOL gpfsacl_process_smbacl(files_struct *fsp, SMB4ACL_T *smbacl) gpfs_aclLen_t gacl_len; SMB4ACE_T *smbace; struct gpfs_acl *gacl; - TALLOC_CTX *mem_ctx = main_loop_talloc_get(); + TALLOC_CTX *mem_ctx = talloc_tos(); gacl_len = sizeof(struct gpfs_acl) + (smb_get_naces(smbacl)-1)*sizeof(gpfs_ace_v4_t); -- cgit From 30191d1a5704ad2b158386b511558972d539ce47 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 18 Oct 2007 17:40:25 -0700 Subject: RIP BOOL. Convert BOOL -> bool. I found a few interesting bugs in various places whilst doing this (places that assumed BOOL == int). I also need to fix the Samba4 pidl generation (next checkin). Jeremy. (This used to be commit f35a266b3cbb3e5fa6a86be60f34fe340a3ca71f) --- source3/modules/vfs_gpfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/modules/vfs_gpfs.c') diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index b8e8209be0..0188e380e9 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -261,7 +261,7 @@ size_t gpfsacl_get_nt_acl(vfs_handle_struct *handle, return gpfsacl_get_nt_acl_common(fsp, security_info, ppdesc); } -static BOOL gpfsacl_process_smbacl(files_struct *fsp, SMB4ACL_T *smbacl) +static bool gpfsacl_process_smbacl(files_struct *fsp, SMB4ACL_T *smbacl) { int ret; gpfs_aclLen_t gacl_len; -- cgit From 15953b82eb3b49d736b4b835b1d0d3cf0da0bff8 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sat, 13 Oct 2007 21:06:49 +0200 Subject: Make [f]get_nt_acl return NTSTATUS (This used to be commit dcbe1bf942d017a3cd5084c6ef605a13912f795b) --- source3/modules/vfs_gpfs.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/modules/vfs_gpfs.c') diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index 0188e380e9..c207bbfe2d 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -226,7 +226,7 @@ static int gpfs_get_nfs4_acl(const char *fname, SMB4ACL_T **ppacl) return 0; } -static size_t gpfsacl_get_nt_acl_common(files_struct *fsp, +static NTSTATUS gpfsacl_get_nt_acl_common(files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc) { SMB4ACL_T *pacl = NULL; @@ -244,17 +244,17 @@ static size_t gpfsacl_get_nt_acl_common(files_struct *fsp, } /* GPFS ACL was not read, something wrong happened, error code is set in errno */ - return 0; + return map_nt_error_from_unix(errno); } -size_t gpfsacl_fget_nt_acl(vfs_handle_struct *handle, +NTSTATUS gpfsacl_fget_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, uint32 security_info, SEC_DESC **ppdesc) { return gpfsacl_get_nt_acl_common(fsp, security_info, ppdesc); } -size_t gpfsacl_get_nt_acl(vfs_handle_struct *handle, +NTSTATUS gpfsacl_get_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info, SEC_DESC **ppdesc) { -- cgit From 8e2323e391e312e0f0284c918e2bb8567c035e20 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 6 Nov 2007 08:01:31 +0100 Subject: Split get_nt_acl() into two functions: fsp- and non-fsp variant. Replace smbd/posix_acls.c:get_nt_acl() by two funcions: posix_get_nt_acl() and posix_fget_nt_acl(). The first takes a connection struct and a file name instead of a files_struct pointer. This is in preparation of changing the vfs api for SMB_VFS_GET_NT_ACL. Michael (This used to be commit 50c82cc1456736fa634fb656e63555319742f725) --- source3/modules/vfs_gpfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/modules/vfs_gpfs.c') diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index c207bbfe2d..91d38874b9 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -240,7 +240,7 @@ static NTSTATUS gpfsacl_get_nt_acl_common(files_struct *fsp, if (result > 0) { DEBUG(10, ("retrying with posix acl...\n")); - return get_nt_acl(fsp, security_info, ppdesc); + return posix_fget_nt_acl(fsp, security_info, ppdesc); } /* GPFS ACL was not read, something wrong happened, error code is set in errno */ -- cgit From c650857fac826697cb1d9441b9ea869b85190d25 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Thu, 15 Nov 2007 00:46:20 +0100 Subject: Split smb_get_nt_acl_nfs4 into two (f- and non-f-variant). This is the next step in preparation of a get_nt_acl prototype change. Michael (This used to be commit 7afeb1c6cb1bdb58d1e61c54ae215d947d8dc3ea) --- source3/modules/vfs_gpfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/modules/vfs_gpfs.c') diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index 91d38874b9..418a81ffb4 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -236,7 +236,7 @@ static NTSTATUS gpfsacl_get_nt_acl_common(files_struct *fsp, result = gpfs_get_nfs4_acl(fsp->fsp_name, &pacl); if (result == 0) - return smb_get_nt_acl_nfs4(fsp, security_info, ppdesc, pacl); + return smb_fget_nt_acl_nfs4(fsp, security_info, ppdesc, pacl); if (result > 0) { DEBUG(10, ("retrying with posix acl...\n")); -- cgit From 010056a5e6c8b94d858575210b5544e5bbcd32b3 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Fri, 16 Nov 2007 18:33:39 +0100 Subject: Prepare the gpfs acl module for the api change in get_nt_acl(). This moves functionality from gpfsacl_get_nt_acl_common() back to gpfsacl_get_nt_acl() and gpfsacl_fget_nt_acl(), making both these functions more specific (calling the corresponding fsp- and non-fsp functions). gpfsacl_get_nt_acl_common(). is removed. Michael (This used to be commit d6043c1066322d2c567aedc5eae1a9d46c8fc396) --- source3/modules/vfs_gpfs.c | 33 +++++++++++++++++++++------------ 1 file changed, 21 insertions(+), 12 deletions(-) (limited to 'source3/modules/vfs_gpfs.c') diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index 418a81ffb4..e7331bef29 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -226,8 +226,9 @@ static int gpfs_get_nfs4_acl(const char *fname, SMB4ACL_T **ppacl) return 0; } -static NTSTATUS gpfsacl_get_nt_acl_common(files_struct *fsp, - uint32 security_info, SEC_DESC **ppdesc) +static NTSTATUS gpfsacl_fget_nt_acl(vfs_handle_struct *handle, + files_struct *fsp, int fd, uint32 security_info, + SEC_DESC **ppdesc) { SMB4ACL_T *pacl = NULL; int result; @@ -242,23 +243,31 @@ static NTSTATUS gpfsacl_get_nt_acl_common(files_struct *fsp, DEBUG(10, ("retrying with posix acl...\n")); return posix_fget_nt_acl(fsp, security_info, ppdesc); } - + /* GPFS ACL was not read, something wrong happened, error code is set in errno */ return map_nt_error_from_unix(errno); } -NTSTATUS gpfsacl_fget_nt_acl(vfs_handle_struct *handle, - files_struct *fsp, int fd, uint32 security_info, - SEC_DESC **ppdesc) -{ - return gpfsacl_get_nt_acl_common(fsp, security_info, ppdesc); -} - -NTSTATUS gpfsacl_get_nt_acl(vfs_handle_struct *handle, +static NTSTATUS gpfsacl_get_nt_acl(vfs_handle_struct *handle, files_struct *fsp, const char *name, uint32 security_info, SEC_DESC **ppdesc) { - return gpfsacl_get_nt_acl_common(fsp, security_info, ppdesc); + SMB4ACL_T *pacl = NULL; + int result; + + *ppdesc = NULL; + result = gpfs_get_nfs4_acl(fsp->fsp_name, &pacl); + + if (result == 0) + return smb_get_nt_acl_nfs4(handle->conn, name, security_info, ppdesc, pacl); + + if (result > 0) { + DEBUG(10, ("retrying with posix acl...\n")); + return posix_get_nt_acl(handle->conn, name, security_info, ppdesc); + } + + /* GPFS ACL was not read, something wrong happened, error code is set in errno */ + return map_nt_error_from_unix(errno); } static bool gpfsacl_process_smbacl(files_struct *fsp, SMB4ACL_T *smbacl) -- cgit From 233eb0e560acb26f8706fd3ab96d4c6379458414 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Wed, 5 Dec 2007 09:53:10 +0100 Subject: Change the prototype of the vfs function get_nt_acl(). Up to now, get_nt_acl() took a files_struct pointer (fsp) and a file name. All the underlying functions should need and now do need (after the previous preparatory work), is a connection_struct and a file name. The connection_struct is already there in the vfs_handle passed to the vfs functions. So the files_struct argument can be eliminated. This eliminates the need of calling open_file_stat in a couple of places to produce the fsp needed. Michael (This used to be commit b5f600fab53c9d159a958c59795db3ba4a8acc63) --- source3/modules/vfs_gpfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/modules/vfs_gpfs.c') diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index e7331bef29..24ca3d5e42 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -249,7 +249,7 @@ static NTSTATUS gpfsacl_fget_nt_acl(vfs_handle_struct *handle, } static NTSTATUS gpfsacl_get_nt_acl(vfs_handle_struct *handle, - files_struct *fsp, const char *name, + const char *name, uint32 security_info, SEC_DESC **ppdesc) { SMB4ACL_T *pacl = NULL; -- cgit From ee24c629a68e13764f78064121a6aea3d0e9240c Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sat, 5 Jan 2008 02:16:15 +0100 Subject: Remove superfluous fd parameter from SMB_VFS_FGET_NT_ACL(). Michael (This used to be commit c0c7c1223da29c68359dac64a340c1c710d5f3d2) --- source3/modules/vfs_gpfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/modules/vfs_gpfs.c') diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index 24ca3d5e42..21e5a6bcfa 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -227,7 +227,7 @@ static int gpfs_get_nfs4_acl(const char *fname, SMB4ACL_T **ppacl) } static NTSTATUS gpfsacl_fget_nt_acl(vfs_handle_struct *handle, - files_struct *fsp, int fd, uint32 security_info, + files_struct *fsp, uint32 security_info, SEC_DESC **ppdesc) { SMB4ACL_T *pacl = NULL; -- cgit From 05352cf2cb7f9710444d340f3f14ac6917fb0416 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Sun, 6 Jan 2008 18:48:02 +0100 Subject: Remove superfluous parameter fd from SMB_VFS_FSET_NT_ACL(). Michael (This used to be commit 4f2d139a186048f08180378a877b69d2f80ad51f) --- source3/modules/vfs_gpfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/modules/vfs_gpfs.c') diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index 21e5a6bcfa..0f7dc81ae6 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -363,7 +363,7 @@ static NTSTATUS gpfsacl_set_nt_acl_internal(files_struct *fsp, uint32 security_i return result; } -static NTSTATUS gpfsacl_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, int fd, uint32 security_info_sent, SEC_DESC *psd) +static NTSTATUS gpfsacl_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp, uint32 security_info_sent, SEC_DESC *psd) { return gpfsacl_set_nt_acl_internal(fsp, security_info_sent, psd); } -- cgit From 87a684f7fcfa8d9fabc42e33981299d0b33eeeb7 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Mon, 7 Jan 2008 13:21:26 +0100 Subject: Remove redundant parameter fd from SMB_VFS_FSTAT(). Michael (This used to be commit 0b86c420be94d295f6917a220b5d699f65b46711) --- source3/modules/vfs_gpfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/modules/vfs_gpfs.c') diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index 0f7dc81ae6..500a6ee772 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -645,7 +645,7 @@ static int vfs_gpfs_chmod(vfs_handle_struct *handle, const char *path, mode_t mo static int vfs_gpfs_fchmod(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode) { SMB_STRUCT_STAT st; - if (SMB_VFS_NEXT_FSTAT(handle, fsp, fd, &st) != 0) { + if (SMB_VFS_NEXT_FSTAT(handle, fsp, &st) != 0) { return -1; } /* avoid chmod() if possible, to preserve acls */ -- cgit From e614dec27f33c932c6c29c806d567fd6015cd5e6 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Mon, 7 Jan 2008 13:44:37 +0100 Subject: Remove redundant parameter fd from SMB_VFS_FCHMOD(). Michael (This used to be commit a54d5604da556d1250ca9948d4acc4a187a9fede) --- source3/modules/vfs_gpfs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/modules/vfs_gpfs.c') diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index 500a6ee772..832dcbfcad 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -642,7 +642,7 @@ static int vfs_gpfs_chmod(vfs_handle_struct *handle, const char *path, mode_t mo return SMB_VFS_NEXT_CHMOD(handle, path, mode); } -static int vfs_gpfs_fchmod(vfs_handle_struct *handle, files_struct *fsp, int fd, mode_t mode) +static int vfs_gpfs_fchmod(vfs_handle_struct *handle, files_struct *fsp, mode_t mode) { SMB_STRUCT_STAT st; if (SMB_VFS_NEXT_FSTAT(handle, fsp, &st) != 0) { @@ -652,7 +652,7 @@ static int vfs_gpfs_fchmod(vfs_handle_struct *handle, files_struct *fsp, int fd, if ((st.st_mode & ~S_IFMT) == mode) { return 0; } - return SMB_VFS_NEXT_FCHMOD(handle, fsp, fd, mode); + return SMB_VFS_NEXT_FCHMOD(handle, fsp, mode); } /* VFS operations structure */ -- cgit From 327cc04da587fa54f28dafb00267fde79b858349 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Mon, 7 Jan 2008 17:14:20 +0100 Subject: Remove redundant parameter fd from SMB_VFS_KERNEL_FLOCK(). Michael (This used to be commit 195c519377c2fdc655e25760b52bc0694b8dda81) --- source3/modules/vfs_gpfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/modules/vfs_gpfs.c') diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index 832dcbfcad..1dd2c5967e 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -33,7 +33,7 @@ static int vfs_gpfs_kernel_flock(vfs_handle_struct *handle, files_struct *fsp, - int fd, uint32 share_mode) + uint32 share_mode) { START_PROFILE(syscall_kernel_flock); -- cgit From 26169410cd3fa90be5740a913f027802488eca8d Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Mon, 7 Jan 2008 21:47:53 +0100 Subject: Remove redundant parameter fd from SMB_VFS_LINUX_SETLEASE(). Michael (This used to be commit 8880eb82f16d561a4023ec8426f8ea35c579a7a6) --- source3/modules/vfs_gpfs.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'source3/modules/vfs_gpfs.c') diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index 1dd2c5967e..f7605b20de 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -52,21 +52,21 @@ static int vfs_gpfs_kernel_flock(vfs_handle_struct *handle, files_struct *fsp, } static int vfs_gpfs_setlease(vfs_handle_struct *handle, files_struct *fsp, - int fd, int leasetype) + int leasetype) { int ret; START_PROFILE(syscall_linux_setlease); - if ( linux_set_lease_sighandler(fd) == -1) + if ( linux_set_lease_sighandler(fsp->fh->fd) == -1) return -1; - ret = set_gpfs_lease(fd,leasetype); + ret = set_gpfs_lease(fsp->fh->fd,leasetype); if ( ret < 0 ) { /* This must have come from GPFS not being available */ /* or some other error, hence call the default */ - ret = linux_setlease(fd, leasetype); + ret = linux_setlease(fsp->fh->fd, leasetype); } END_PROFILE(syscall_linux_setlease); -- cgit From 62e9d503d82d645cf29af643732ad97c0eb8b340 Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Mon, 7 Jan 2008 23:53:34 +0100 Subject: Remove redundant parameter fd from SMB_VFS_SYS_ACL_GET_FD(). Michael (This used to be commit 42663e8736e1a3dfb57e0aafdcbf5fec880da779) --- source3/modules/vfs_gpfs.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/modules/vfs_gpfs.c') diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index f7605b20de..714f6e2917 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -501,8 +501,7 @@ SMB_ACL_T gpfsacl_sys_acl_get_file(vfs_handle_struct *handle, } SMB_ACL_T gpfsacl_sys_acl_get_fd(vfs_handle_struct *handle, - files_struct *fsp, - int fd) + files_struct *fsp) { return gpfsacl_get_posix_acl(fsp->fsp_name, GPFS_ACL_TYPE_ACCESS); } -- cgit From 5921607f2647cec20a6bcebd17c5a0c53449c1ba Mon Sep 17 00:00:00 2001 From: Michael Adam Date: Tue, 8 Jan 2008 01:54:19 +0100 Subject: Remove redundant parameter fd from SMB_VFS_SYS_ACL_SET_FD(). Michael (This used to be commit 9296e93588c0e795cae770765050247ac1474a74) --- source3/modules/vfs_gpfs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/modules/vfs_gpfs.c') diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index 714f6e2917..bcf61f3bc7 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -615,7 +615,7 @@ int gpfsacl_sys_acl_set_file(vfs_handle_struct *handle, int gpfsacl_sys_acl_set_fd(vfs_handle_struct *handle, files_struct *fsp, - int fd, SMB_ACL_T theacl) + SMB_ACL_T theacl) { return gpfsacl_sys_acl_set_file(handle, fsp->fsp_name, SMB_ACL_TYPE_ACCESS, theacl); } -- cgit From 313f7d10b884d083ef9488db739465c54c3f6515 Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Wed, 16 Jan 2008 12:18:57 +0300 Subject: Merge latest fixes to vfs_gpfs and NFS4 ACLs from Samba 3.0 CTDB branch (from http://samba.org/~tridge/3_0-ctdb) Signed-off-by: Alexander Bokovoy (This used to be commit 1daad835cbfb4615a8fe7a241f4d578f7e69f214) --- source3/modules/vfs_gpfs.c | 281 ++++++++++++++++++++++++++++++++++++--------- 1 file changed, 227 insertions(+), 54 deletions(-) (limited to 'source3/modules/vfs_gpfs.c') diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index bcf61f3bc7..d10906dfb1 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -30,7 +30,7 @@ #include #include "nfs4_acls.h" - +#include "vfs_gpfs.h" static int vfs_gpfs_kernel_flock(vfs_handle_struct *handle, files_struct *fsp, uint32 share_mode) @@ -153,7 +153,7 @@ static int gpfs_get_nfs4_acl(const char *fname, SMB4ACL_T **ppacl) DEBUG(10, ("gpfs_get_nfs4_acl invoked for %s\n", fname)); /* First get the real acl length */ - gacl = gpfs_getacl_alloc(fname, GPFS_ACL_TYPE_NFS4); + gacl = gpfs_getacl_alloc(fname, 0); if (gacl == NULL) { DEBUG(9, ("gpfs_getacl failed for %s with %s\n", fname, strerror(errno))); @@ -208,10 +208,10 @@ static int gpfs_get_nfs4_acl(const char *fname, SMB4ACL_T **ppacl) if (i > 0 && gace->aceType == SMB_ACE4_ACCESS_DENIED_ACE_TYPE) { struct gpfs_ace_v4 *prev = &gacl->ace_v4[i-1]; if (prev->aceType == SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE && - prev->aceFlags == gace->aceFlags && - prev->aceIFlags == gace->aceIFlags && - (gace->aceMask & prev->aceMask) == 0 && - gace->aceWho == prev->aceWho) { + prev->aceFlags == gace->aceFlags && + prev->aceIFlags == gace->aceIFlags && + (gace->aceMask & prev->aceMask) == 0 && + gace->aceWho == prev->aceWho) { /* its redundent - skip it */ continue; } @@ -256,7 +256,7 @@ static NTSTATUS gpfsacl_get_nt_acl(vfs_handle_struct *handle, int result; *ppdesc = NULL; - result = gpfs_get_nfs4_acl(fsp->fsp_name, &pacl); + result = gpfs_get_nfs4_acl(name, &pacl); if (result == 0) return smb_get_nt_acl_nfs4(handle->conn, name, security_info, ppdesc, pacl); @@ -301,8 +301,31 @@ static bool gpfsacl_process_smbacl(files_struct *fsp, SMB4ACL_T *smbacl) gace->aceType = aceprop->aceType; gace->aceFlags = aceprop->aceFlags; gace->aceMask = aceprop->aceMask; + + /* + * GPFS can't distinguish between WRITE and APPEND on + * files, so one being set without the other is an + * error. Sorry for the many ()'s :-) + */ + + if (!fsp->is_directory + && + ((((gace->aceMask & ACE4_MASK_WRITE) == 0) + && ((gace->aceMask & ACE4_MASK_APPEND) != 0)) + || + (((gace->aceMask & ACE4_MASK_WRITE) != 0) + && ((gace->aceMask & ACE4_MASK_APPEND) == 0))) + && + lp_parm_bool(fsp->conn->params->service, "gpfs", + "merge_writeappend", True)) { + DEBUG(2, ("vfs_gpfs.c: file [%s]: ACE contains " + "WRITE^APPEND, setting WRITE|APPEND\n", + fsp->fsp_name)); + gace->aceMask |= ACE4_MASK_WRITE|ACE4_MASK_APPEND; + } + gace->aceIFlags = (aceprop->flags&SMB_ACE4_ID_SPECIAL) ? ACE4_IFLAG_SPECIAL_ID : 0; - + if (aceprop->flags&SMB_ACE4_ID_SPECIAL) { switch(aceprop->who.special_id) @@ -347,7 +370,7 @@ static NTSTATUS gpfsacl_set_nt_acl_internal(files_struct *fsp, uint32 security_i struct gpfs_acl *acl; NTSTATUS result = NT_STATUS_ACCESS_DENIED; - acl = gpfs_getacl_alloc(fsp->fsp_name, GPFS_ACL_TYPE_ACCESS); + acl = gpfs_getacl_alloc(fsp->fsp_name, 0); if (acl == NULL) return result; @@ -628,75 +651,225 @@ int gpfsacl_sys_acl_delete_def_file(vfs_handle_struct *handle, return -1; } +/* + * Assumed: mode bits are shiftable and standard + * Output: the new aceMask field for an smb nfs4 ace + */ +static uint32 gpfsacl_mask_filter(uint32 aceType, uint32 aceMask, uint32 rwx) +{ + const uint32 posix_nfs4map[3] = { + SMB_ACE4_EXECUTE, /* execute */ + SMB_ACE4_WRITE_DATA | SMB_ACE4_APPEND_DATA, /* write; GPFS specific */ + SMB_ACE4_READ_DATA /* read */ + }; + int i; + uint32_t posix_mask = 0x01; + uint32_t posix_bit; + uint32_t nfs4_bits; + + for(i=0; i<3; i++) { + nfs4_bits = posix_nfs4map[i]; + posix_bit = rwx & posix_mask; + + if (aceType==SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE) { + if (posix_bit) + aceMask |= nfs4_bits; + else + aceMask &= ~nfs4_bits; + } else { + /* add deny bits when suitable */ + if (!posix_bit) + aceMask |= nfs4_bits; + else + aceMask &= ~nfs4_bits; + } /* other ace types are unexpected */ + + posix_mask <<= 1; + } + + return aceMask; +} + +static int gpfsacl_emu_chmod(const char *path, mode_t mode) +{ + SMB4ACL_T *pacl = NULL; + int result; + bool haveAllowEntry[SMB_ACE4_WHO_EVERYONE + 1] = {False, False, False, False}; + int i; + files_struct fake_fsp; /* TODO: rationalize parametrization */ + SMB4ACE_T *smbace; + + DEBUG(10, ("gpfsacl_emu_chmod invoked for %s mode %o\n", path, mode)); + + result = gpfs_get_nfs4_acl(path, &pacl); + if (result) + return result; + + if (mode & ~(S_IRWXU | S_IRWXG | S_IRWXO)) { + DEBUG(2, ("WARNING: cutting extra mode bits %o on %s\n", mode, path)); + } + + for (smbace=smb_first_ace4(pacl); smbace!=NULL; smbace = smb_next_ace4(smbace)) { + SMB_ACE4PROP_T *ace = smb_get_ace4(smbace); + uint32_t specid = ace->who.special_id; + + if (ace->flags&SMB_ACE4_ID_SPECIAL && + ace->aceType<=SMB_ACE4_ACCESS_DENIED_ACE_TYPE && + specid <= SMB_ACE4_WHO_EVERYONE) { + + uint32_t newMask; + + if (ace->aceType==SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE) + haveAllowEntry[specid] = True; + + /* mode >> 6 for @owner, mode >> 3 for @group, + * mode >> 0 for @everyone */ + newMask = gpfsacl_mask_filter(ace->aceType, ace->aceMask, + mode >> ((SMB_ACE4_WHO_EVERYONE - specid) * 3)); + if (ace->aceMask!=newMask) { + DEBUG(10, ("ace changed for %s (%o -> %o) id=%d\n", + path, ace->aceMask, newMask, specid)); + } + ace->aceMask = newMask; + } + } + + /* make sure we have at least ALLOW entries + * for all the 3 special ids (@EVERYONE, @OWNER, @GROUP) + * - if necessary + */ + for(i = SMB_ACE4_WHO_OWNER; i<=SMB_ACE4_WHO_EVERYONE; i++) { + SMB_ACE4PROP_T ace; + + if (haveAllowEntry[i]==True) + continue; + + memset(&ace, 0, sizeof(SMB_ACE4PROP_T)); + ace.aceType = SMB_ACE4_ACCESS_ALLOWED_ACE_TYPE; + ace.flags |= SMB_ACE4_ID_SPECIAL; + ace.who.special_id = i; + + if (i==SMB_ACE4_WHO_GROUP) /* not sure it's necessary... */ + ace.aceFlags |= SMB_ACE4_IDENTIFIER_GROUP; + + ace.aceMask = gpfsacl_mask_filter(ace.aceType, ace.aceMask, + mode >> ((SMB_ACE4_WHO_EVERYONE - i) * 3)); + + /* don't add unnecessary aces */ + if (!ace.aceMask) + continue; + + /* we add it to the END - as windows expects allow aces */ + smb_add_ace4(pacl, &ace); + DEBUG(10, ("Added ALLOW ace for %s, mode=%o, id=%d, aceMask=%x\n", + path, mode, i, ace.aceMask)); + } + + /* don't add complementary DENY ACEs here */ + memset(&fake_fsp, 0, sizeof(struct files_struct)); + fake_fsp.fsp_name = (char *)path; /* no file_new is needed here */ + + /* put the acl */ + if (gpfsacl_process_smbacl(&fake_fsp, pacl) == False) + return -1; + return 0; /* ok for [f]chmod */ +} + static int vfs_gpfs_chmod(vfs_handle_struct *handle, const char *path, mode_t mode) { SMB_STRUCT_STAT st; + int rc; + if (SMB_VFS_NEXT_STAT(handle, path, &st) != 0) { - return -1; + return -1; } + /* avoid chmod() if possible, to preserve acls */ if ((st.st_mode & ~S_IFMT) == mode) { - return 0; + return 0; } - return SMB_VFS_NEXT_CHMOD(handle, path, mode); + + rc = gpfsacl_emu_chmod(path, mode); + if (rc == 1) + return SMB_VFS_NEXT_CHMOD(handle, path, mode); + return rc; } static int vfs_gpfs_fchmod(vfs_handle_struct *handle, files_struct *fsp, mode_t mode) { SMB_STRUCT_STAT st; + int rc; + if (SMB_VFS_NEXT_FSTAT(handle, fsp, &st) != 0) { - return -1; + return -1; } + /* avoid chmod() if possible, to preserve acls */ if ((st.st_mode & ~S_IFMT) == mode) { - return 0; + return 0; } - return SMB_VFS_NEXT_FCHMOD(handle, fsp, mode); + + rc = gpfsacl_emu_chmod(fsp->fsp_name, mode); + if (rc == 1) + return SMB_VFS_NEXT_FCHMOD(handle, fsp, mode); + return rc; } /* VFS operations structure */ static vfs_op_tuple gpfs_op_tuples[] = { - - { SMB_VFS_OP(vfs_gpfs_kernel_flock), SMB_VFS_OP_KERNEL_FLOCK, - SMB_VFS_LAYER_OPAQUE }, - - { SMB_VFS_OP(vfs_gpfs_setlease), SMB_VFS_OP_LINUX_SETLEASE, - SMB_VFS_LAYER_OPAQUE }, - - { SMB_VFS_OP(gpfsacl_fget_nt_acl), SMB_VFS_OP_FGET_NT_ACL, - SMB_VFS_LAYER_TRANSPARENT }, - - { SMB_VFS_OP(gpfsacl_get_nt_acl), SMB_VFS_OP_GET_NT_ACL, - SMB_VFS_LAYER_TRANSPARENT }, - - { SMB_VFS_OP(gpfsacl_fset_nt_acl), SMB_VFS_OP_FSET_NT_ACL, - SMB_VFS_LAYER_TRANSPARENT }, - - { SMB_VFS_OP(gpfsacl_set_nt_acl), SMB_VFS_OP_SET_NT_ACL, - SMB_VFS_LAYER_TRANSPARENT }, - - { SMB_VFS_OP(gpfsacl_sys_acl_get_file), SMB_VFS_OP_SYS_ACL_GET_FILE, - SMB_VFS_LAYER_TRANSPARENT }, - - { SMB_VFS_OP(gpfsacl_sys_acl_get_fd), SMB_VFS_OP_SYS_ACL_GET_FD, - SMB_VFS_LAYER_TRANSPARENT }, - - { SMB_VFS_OP(gpfsacl_sys_acl_set_file), SMB_VFS_OP_SYS_ACL_SET_FILE, - SMB_VFS_LAYER_TRANSPARENT }, - - { SMB_VFS_OP(gpfsacl_sys_acl_set_fd), SMB_VFS_OP_SYS_ACL_SET_FD, - SMB_VFS_LAYER_TRANSPARENT }, - + + { SMB_VFS_OP(vfs_gpfs_kernel_flock), + SMB_VFS_OP_KERNEL_FLOCK, + SMB_VFS_LAYER_OPAQUE }, + + { SMB_VFS_OP(vfs_gpfs_setlease), + SMB_VFS_OP_LINUX_SETLEASE, + SMB_VFS_LAYER_OPAQUE }, + + { SMB_VFS_OP(gpfsacl_fget_nt_acl), + SMB_VFS_OP_FGET_NT_ACL, + SMB_VFS_LAYER_TRANSPARENT }, + + { SMB_VFS_OP(gpfsacl_get_nt_acl), + SMB_VFS_OP_GET_NT_ACL, + SMB_VFS_LAYER_TRANSPARENT }, + + { SMB_VFS_OP(gpfsacl_fset_nt_acl), + SMB_VFS_OP_FSET_NT_ACL, + SMB_VFS_LAYER_TRANSPARENT }, + + { SMB_VFS_OP(gpfsacl_set_nt_acl), + SMB_VFS_OP_SET_NT_ACL, + SMB_VFS_LAYER_TRANSPARENT }, + + { SMB_VFS_OP(gpfsacl_sys_acl_get_file), + SMB_VFS_OP_SYS_ACL_GET_FILE, + SMB_VFS_LAYER_TRANSPARENT }, + + { SMB_VFS_OP(gpfsacl_sys_acl_get_fd), + SMB_VFS_OP_SYS_ACL_GET_FD, + SMB_VFS_LAYER_TRANSPARENT }, + + { SMB_VFS_OP(gpfsacl_sys_acl_set_file), + SMB_VFS_OP_SYS_ACL_SET_FILE, + SMB_VFS_LAYER_TRANSPARENT }, + + { SMB_VFS_OP(gpfsacl_sys_acl_set_fd), + SMB_VFS_OP_SYS_ACL_SET_FD, + SMB_VFS_LAYER_TRANSPARENT }, + { SMB_VFS_OP(gpfsacl_sys_acl_delete_def_file), - SMB_VFS_OP_SYS_ACL_DELETE_DEF_FILE, - SMB_VFS_LAYER_TRANSPARENT }, - - { SMB_VFS_OP(vfs_gpfs_chmod), SMB_VFS_OP_CHMOD, - SMB_VFS_LAYER_TRANSPARENT }, - - { SMB_VFS_OP(vfs_gpfs_fchmod), SMB_VFS_OP_FCHMOD, - SMB_VFS_LAYER_TRANSPARENT }, + SMB_VFS_OP_SYS_ACL_DELETE_DEF_FILE, + SMB_VFS_LAYER_TRANSPARENT }, + + { SMB_VFS_OP(vfs_gpfs_chmod), + SMB_VFS_OP_CHMOD, + SMB_VFS_LAYER_TRANSPARENT }, + + { SMB_VFS_OP(vfs_gpfs_fchmod), + SMB_VFS_OP_FCHMOD, + SMB_VFS_LAYER_TRANSPARENT }, { SMB_VFS_OP(NULL), SMB_VFS_OP_NOOP, SMB_VFS_LAYER_NOOP } -- cgit From 00b2cdf75e9bea25034440054b4acd91a179c86d Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 8 May 2008 18:09:07 -0700 Subject: Yay ! Remove a VFS entry. Removed the set_nt_acl() call, this can only be done via fset_nt_acl() using an open file/directory handle. I'd like to do the same with get_nt_acl() but am concerned about efficiency problems with "hide unreadable/hide unwritable" when doing a directory listing (this would mean opening every file in the dir on list). Moving closer to rationalizing the ACL model and maybe moving the POSIX calls into a posix_acl VFS module rather than having them as first class citizens of the VFS. Jeremy. (This used to be commit f487f742cb903a06fbf2be006ddc9ce9063339ed) --- source3/modules/vfs_gpfs.c | 9 --------- 1 file changed, 9 deletions(-) (limited to 'source3/modules/vfs_gpfs.c') diff --git a/source3/modules/vfs_gpfs.c b/source3/modules/vfs_gpfs.c index d10906dfb1..39d2bb6c38 100644 --- a/source3/modules/vfs_gpfs.c +++ b/source3/modules/vfs_gpfs.c @@ -391,11 +391,6 @@ static NTSTATUS gpfsacl_fset_nt_acl(vfs_handle_struct *handle, files_struct *fsp return gpfsacl_set_nt_acl_internal(fsp, security_info_sent, psd); } -static NTSTATUS gpfsacl_set_nt_acl(vfs_handle_struct *handle, files_struct *fsp, char *name, uint32 security_info_sent, SEC_DESC *psd) -{ - return gpfsacl_set_nt_acl_internal(fsp, security_info_sent, psd); -} - static SMB_ACL_T gpfs2smb_acl(const struct gpfs_acl *pacl) { SMB_ACL_T result; @@ -839,10 +834,6 @@ static vfs_op_tuple gpfs_op_tuples[] = { SMB_VFS_OP_FSET_NT_ACL, SMB_VFS_LAYER_TRANSPARENT }, - { SMB_VFS_OP(gpfsacl_set_nt_acl), - SMB_VFS_OP_SET_NT_ACL, - SMB_VFS_LAYER_TRANSPARENT }, - { SMB_VFS_OP(gpfsacl_sys_acl_get_file), SMB_VFS_OP_SYS_ACL_GET_FILE, SMB_VFS_LAYER_TRANSPARENT }, -- cgit