s3:vfs_gpfs skip local flock when gpfs sharemodes are disabled
[kai/samba.git] / source3 / modules / vfs_gpfs.c
index a39187e487446d269580dc4d16714a2465e9e04c..fdd8e93cf603717bdc1e9f5179692358c6275a1d 100644 (file)
@@ -61,12 +61,15 @@ static int vfs_gpfs_kernel_flock(vfs_handle_struct *handle, files_struct *fsp,
                                struct gpfs_config_data,
                                return -1);
 
+       if(!config->sharemodes) {
+               return 0;
+       }
+
        START_PROFILE(syscall_kernel_flock);
 
        kernel_flock(fsp->fh->fd, share_mode, access_mask);
 
-       if (config->sharemodes
-               && !set_gpfs_sharemode(fsp, access_mask, fsp->share_access)) {
+       if (!set_gpfs_sharemode(fsp, access_mask, fsp->share_access)) {
                ret = -1;
        }
 
@@ -348,6 +351,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, uint32 security_info,
+       TALLOC_CTX *mem_ctx,
        struct security_descriptor **ppdesc)
 {
        SMB4ACL_T *pacl = NULL;
@@ -367,11 +371,11 @@ static NTSTATUS gpfsacl_fget_nt_acl(vfs_handle_struct *handle,
        result = gpfs_get_nfs4_acl(fsp->fsp_name->base_name, &pacl);
 
        if (result == 0)
-               return smb_fget_nt_acl_nfs4(fsp, security_info, ppdesc, pacl);
+               return smb_fget_nt_acl_nfs4(fsp, security_info, mem_ctx, ppdesc, pacl);
 
        if (result > 0) {
                DEBUG(10, ("retrying with posix acl...\n"));
-               return posix_fget_nt_acl(fsp, security_info, ppdesc);
+               return posix_fget_nt_acl(fsp, security_info, mem_ctx, ppdesc);
        }
 
        /* GPFS ACL was not read, something wrong happened, error code is set in errno */
@@ -380,7 +384,8 @@ static NTSTATUS gpfsacl_fget_nt_acl(vfs_handle_struct *handle,
 
 static NTSTATUS gpfsacl_get_nt_acl(vfs_handle_struct *handle,
        const char *name,
-       uint32 security_info, struct security_descriptor **ppdesc)
+       uint32 security_info,
+       TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc)
 {
        SMB4ACL_T *pacl = NULL;
        int     result;
@@ -399,11 +404,13 @@ static NTSTATUS gpfsacl_get_nt_acl(vfs_handle_struct *handle,
        result = gpfs_get_nfs4_acl(name, &pacl);
 
        if (result == 0)
-               return smb_get_nt_acl_nfs4(handle->conn, name, security_info, ppdesc, pacl);
+               return smb_get_nt_acl_nfs4(handle->conn, name, security_info,
+                                          mem_ctx, ppdesc, pacl);
 
        if (result > 0) {
                DEBUG(10, ("retrying with posix acl...\n"));
-               return posix_get_nt_acl(handle->conn, name, security_info, ppdesc);
+               return posix_get_nt_acl(handle->conn, name, security_info,
+                                       mem_ctx, ppdesc);
        }
 
        /* GPFS ACL was not read, something wrong happened, error code is set in errno */
@@ -549,12 +556,12 @@ 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 SMB_ACL_T gpfs2smb_acl(const struct gpfs_acl *pacl)
+static SMB_ACL_T gpfs2smb_acl(const struct gpfs_acl *pacl, TALLOC_CTX *mem_ctx)
 {
        SMB_ACL_T result;
        gpfs_aclCount_t i;
 
-       result = sys_acl_init(pacl->acl_nace);
+       result = sys_acl_init(mem_ctx);
        if (result == NULL) {
                errno = ENOMEM;
                return NULL;
@@ -573,14 +580,14 @@ static SMB_ACL_T gpfs2smb_acl(const struct gpfs_acl *pacl)
                switch (g_ace->ace_type) {
                case GPFS_ACL_USER:
                        ace->a_type = SMB_ACL_USER;
-                       ace->uid = (uid_t)g_ace->ace_who;
+                       ace->info.user.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;
+                       ace->info.group.gid = (gid_t)g_ace->ace_who;
                        break;
                case GPFS_ACL_GROUP_OBJ:
                        ace->a_type = SMB_ACL_GROUP_OBJ;
@@ -614,7 +621,8 @@ static SMB_ACL_T gpfs2smb_acl(const struct gpfs_acl *pacl)
        return result;
 }
 
-static SMB_ACL_T gpfsacl_get_posix_acl(const char *path, gpfs_aclType_t type)
+static SMB_ACL_T gpfsacl_get_posix_acl(const char *path, gpfs_aclType_t type,
+                                      TALLOC_CTX *mem_ctx)
 {
        struct gpfs_acl *pacl;
        SMB_ACL_T result = NULL;
@@ -641,7 +649,7 @@ static SMB_ACL_T gpfsacl_get_posix_acl(const char *path, gpfs_aclType_t type)
                   pacl->acl_len, pacl->acl_level, pacl->acl_version,
                   pacl->acl_nace));
 
-       result = gpfs2smb_acl(pacl);
+       result = gpfs2smb_acl(pacl, mem_ctx);
        if (result != NULL) {
                errno = 0;
        }
@@ -656,7 +664,8 @@ static SMB_ACL_T gpfsacl_get_posix_acl(const char *path, gpfs_aclType_t type)
 
 static SMB_ACL_T gpfsacl_sys_acl_get_file(vfs_handle_struct *handle,
                                          const char *path_p,
-                                         SMB_ACL_TYPE_T type)
+                                         SMB_ACL_TYPE_T type,
+                                         TALLOC_CTX *mem_ctx)
 {
        gpfs_aclType_t gpfs_type;
        struct gpfs_config_data *config;
@@ -666,7 +675,8 @@ static SMB_ACL_T gpfsacl_sys_acl_get_file(vfs_handle_struct *handle,
                                return NULL);
 
        if (!config->acl) {
-               return SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, path_p, type);
+               return SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, path_p,
+                                                    type, mem_ctx);
        }
 
        switch(type) {
@@ -681,11 +691,12 @@ static SMB_ACL_T gpfsacl_sys_acl_get_file(vfs_handle_struct *handle,
                smb_panic("exiting");
        }
 
-       return gpfsacl_get_posix_acl(path_p, gpfs_type);
+       return gpfsacl_get_posix_acl(path_p, gpfs_type, mem_ctx);
 }
 
 static SMB_ACL_T gpfsacl_sys_acl_get_fd(vfs_handle_struct *handle,
-                                       files_struct *fsp)
+                                       files_struct *fsp,
+                                       TALLOC_CTX *mem_ctx)
 {
        struct gpfs_config_data *config;
 
@@ -694,11 +705,67 @@ static SMB_ACL_T gpfsacl_sys_acl_get_fd(vfs_handle_struct *handle,
                                return NULL);
 
        if (!config->acl) {
-               return SMB_VFS_NEXT_SYS_ACL_GET_FD(handle, fsp);
+               return SMB_VFS_NEXT_SYS_ACL_GET_FD(handle, fsp, mem_ctx);
        }
 
        return gpfsacl_get_posix_acl(fsp->fsp_name->base_name,
-                                    GPFS_ACL_TYPE_ACCESS);
+                                    GPFS_ACL_TYPE_ACCESS, mem_ctx);
+}
+
+static int gpfsacl_sys_acl_blob_get_file(vfs_handle_struct *handle, const char *path_p,
+                                     TALLOC_CTX *mem_ctx,
+                                     char **blob_description,
+                                     DATA_BLOB *blob)
+{
+       struct gpfs_config_data *config;
+
+       SMB_VFS_HANDLE_GET_DATA(handle, config,
+                               struct gpfs_config_data,
+                               return NULL);
+
+       if (!config->acl) {
+               return SMB_VFS_NEXT_SYS_ACL_BLOB_GET_FILE(handle, path_p, mem_ctx, blob_description, blob);
+       }
+
+       result = gpfs_get_nfs4_acl(name, &pacl);
+       if (result == 0) {
+               /* We don't have a way to linearlise the NFS4 ACL
+                * right now, and it is much closer to the NT ACL
+                * anyway */
+               errno = EINVAL;
+               return -1;
+       }
+
+       return posix_sys_acl_blob_get_file(handle, path_p, mem_ctx,
+                                          blob_description, blob);
+}
+
+static int gpfsacl_sys_acl_blob_get_fd(vfs_handle_struct *handle, files_struct *fsp,
+                                     TALLOC_CTX *mem_ctx,
+                                     char **blob_description,
+                                     DATA_BLOB *blob)
+{
+       struct gpfs_config_data *config;
+
+       SMB_VFS_HANDLE_GET_DATA(handle, config,
+                               struct gpfs_config_data,
+                               return NULL);
+
+       if (!config->acl) {
+               return SMB_VFS_NEXT_SYS_ACL_BLOB_GET_FD(handle, fsp, mem_ctx, blob_description, blob);
+       }
+
+       result = gpfs_get_nfs4_acl(fsp->fsp_name->base_name, &pacl);
+       if (result == 0) {
+               /* We don't have a way to linearlise the NFS4 ACL
+                * right now, and it is much closer to the NT ACL
+                * anyway */
+               errno = EINVAL;
+               return -1;
+       }
+
+       return posix_sys_acl_blob_get_fd(handle, fsp, mem_ctx,
+                                        blob_description, blob);
 }
 
 static struct gpfs_acl *smb2gpfs_acl(const SMB_ACL_T pacl,
@@ -738,7 +805,7 @@ static struct gpfs_acl *smb2gpfs_acl(const SMB_ACL_T pacl,
                switch(ace->a_type) {
                case SMB_ACL_USER:
                        g_ace->ace_type = GPFS_ACL_USER;
-                       g_ace->ace_who = (gpfs_uid_t)ace->uid;
+                       g_ace->ace_who = (gpfs_uid_t)ace->info.user.uid;
                        break;
                case SMB_ACL_USER_OBJ:
                        g_ace->ace_type = GPFS_ACL_USER_OBJ;
@@ -747,7 +814,7 @@ static struct gpfs_acl *smb2gpfs_acl(const SMB_ACL_T pacl,
                        break;
                case SMB_ACL_GROUP:
                        g_ace->ace_type = GPFS_ACL_GROUP;
-                       g_ace->ace_who = (gpfs_uid_t)ace->gid;
+                       g_ace->ace_who = (gpfs_uid_t)ace->info.group.gid;
                        break;
                case SMB_ACL_GROUP_OBJ:
                        g_ace->ace_type = GPFS_ACL_GROUP_OBJ;
@@ -1908,6 +1975,8 @@ static struct vfs_fn_pointers vfs_gpfs_fns = {
        .fset_nt_acl_fn = gpfsacl_fset_nt_acl,
        .sys_acl_get_file_fn = gpfsacl_sys_acl_get_file,
        .sys_acl_get_fd_fn = gpfsacl_sys_acl_get_fd,
+       .sys_acl_blob_get_file_fn = gpfsacl_sys_acl_blob_get_file,
+       .sys_acl_blob_get_fd_fn = gpfsacl_sys_acl_blob_get_fd,
        .sys_acl_set_file_fn = gpfsacl_sys_acl_set_file,
        .sys_acl_set_fd_fn = gpfsacl_sys_acl_set_fd,
        .sys_acl_delete_def_file_fn = gpfsacl_sys_acl_delete_def_file,