/* Fetch the NFSv4 ACL from the xattr, and convert into Samba's internal NFSv4 format */ static NTSTATUS nfs4_fget_nfs4_acl(vfs_handle_struct *handle, TALLOC_CTX *mem_ctx, files_struct *fsp, struct SMB4ACL_T **ppacl) { NTSTATUS status; DATA_BLOB blob = data_blob_null; ssize_t length; TALLOC_CTX *frame = talloc_stackframe(); do { blob.length += 1000; blob.data = talloc_realloc(frame, blob.data, uint8_t, blob.length); if (!blob.data) { TALLOC_FREE(frame); errno = ENOMEM; return NT_STATUS_NO_MEMORY; } length = SMB_VFS_NEXT_FGETXATTR(handle, fsp, NFS4ACL_XATTR_NAME, blob.data, blob.length); blob.length = length; } while (length == -1 && errno == ERANGE); if (length == -1) { TALLOC_FREE(frame); return map_nt_error_from_unix(errno); } status = nfs4_get_nfs4_acl_common(mem_ctx, &blob, ppacl); TALLOC_FREE(frame); return status; }
static SMB_ACL_T fake_acls_sys_acl_get_fd(struct vfs_handle_struct *handle, files_struct *fsp, TALLOC_CTX *mem_ctx) { DATA_BLOB blob = data_blob_null; ssize_t length; const char *name = FAKE_ACL_ACCESS_XATTR; struct smb_acl_t *acl = NULL; TALLOC_CTX *frame = talloc_stackframe(); do { blob.length += 1000; blob.data = talloc_realloc(frame, blob.data, uint8_t, blob.length); if (!blob.data) { errno = ENOMEM; TALLOC_FREE(frame); return NULL; } length = SMB_VFS_NEXT_FGETXATTR(handle, fsp, name, blob.data, blob.length); blob.length = length; } while (length == -1 && errno == ERANGE); if (length == -1 && errno == ENOATTR) { TALLOC_FREE(frame); return NULL; } if (length != -1) { acl = fake_acls_blob2acl(&blob, mem_ctx); } TALLOC_FREE(frame); return acl; }
static ssize_t vxfs_fget_xattr(struct vfs_handle_struct *handle, struct files_struct *fsp, const char *name, void *value, size_t size){ DEBUG(10, ("In vxfs_fget_xattr\n")); if (strcmp(name, XATTR_NTACL_NAME) == 0) { return SMB_VFS_NEXT_FGETXATTR(handle, fsp, XATTR_USER_NTACL, value, size); } /* Clients can't see XATTR_USER_NTACL directly. */ if (strcasecmp(name, XATTR_USER_NTACL) == 0) { errno = ENOATTR; return -1; } return SMB_VFS_NEXT_FGETXATTR(handle, fsp, name, value, size); }
static int fake_acls_fgid(vfs_handle_struct *handle, files_struct *fsp, uid_t *gid) { ssize_t size; uint8_t gid_buf[4]; size = SMB_VFS_NEXT_FGETXATTR(handle, fsp, FAKE_GID, gid_buf, sizeof(gid_buf)); if (size == -1 && errno == ENOATTR) { return 0; } if (size != 4) { return -1; } *gid = IVAL(gid_buf, 0); return 0; }
static ssize_t skel_fgetxattr(vfs_handle_struct *handle, struct files_struct *fsp, const char *name, void *value, size_t size) { return SMB_VFS_NEXT_FGETXATTR(handle, fsp, name, value, size); }
static ssize_t cap_fgetxattr(vfs_handle_struct *handle, struct files_struct *fsp,int fd, const char *name, void *value, size_t size) { pstring capname; capencode(capname, name); return SMB_VFS_NEXT_FGETXATTR(handle, fsp, fd, capname, value, size); }
static NTSTATUS nfs4acl_get_blob(struct vfs_handle_struct *handle, files_struct *fsp, const struct smb_filename *smb_fname_in, TALLOC_CTX *mem_ctx, DATA_BLOB *blob) { struct nfs4acl_config *config = NULL; const struct smb_filename *smb_fname = NULL; size_t allocsize = 256; ssize_t length; bool ok; SMB_VFS_HANDLE_GET_DATA(handle, config, struct nfs4acl_config, return NT_STATUS_INTERNAL_ERROR); *blob = data_blob_null; if (fsp == NULL && smb_fname_in == NULL) { return NT_STATUS_INTERNAL_ERROR; } smb_fname = smb_fname_in; if (smb_fname == NULL) { smb_fname = fsp->fsp_name; } if (smb_fname == NULL) { return NT_STATUS_INTERNAL_ERROR; } ok = nfs4acl_validate_blob(handle, smb_fname); if (!ok) { return NT_STATUS_INTERNAL_ERROR; } do { int saved_errno = 0; allocsize *= 4; ok = data_blob_realloc(mem_ctx, blob, allocsize); if (!ok) { return NT_STATUS_NO_MEMORY; } become_root(); if (fsp != NULL && fsp->fh->fd != -1) { length = SMB_VFS_NEXT_FGETXATTR(handle, fsp, config->xattr_name, blob->data, blob->length); } else { length = SMB_VFS_NEXT_GETXATTR(handle, smb_fname, config->xattr_name, blob->data, blob->length); } if (length == -1) { saved_errno = errno; } unbecome_root(); if (saved_errno != 0) { errno = saved_errno; } } while (length == -1 && errno == ERANGE && allocsize <= 65536); if (length == -1) { return map_nt_error_from_unix(errno); } return NT_STATUS_OK; }