#include "includes.h"
#include "smbd/smbd.h"
-#include "librpc/gen_ndr/ndr_xattr.h"
#include "include/smbprofile.h"
#include "modules/non_posix_acls.h"
#include "libcli/security/security.h"
#endif
struct gpfs_config_data {
+ struct smbacl4_vfs_params nfs4_params;
bool sharemodes;
bool leases;
bool hsm;
}
}
+static int gpfs_getacl_with_capability(const char *fname, int flags, void *buf)
+{
+ int ret, saved_errno;
+
+ set_effective_capability(DAC_OVERRIDE_CAPABILITY);
+
+ ret = gpfswrap_getacl(discard_const_p(char, fname), flags, buf);
+ saved_errno = errno;
+
+ drop_effective_capability(DAC_OVERRIDE_CAPABILITY);
+
+ errno = saved_errno;
+ return ret;
+}
+
/*
* get the ACL from GPFS, allocated on the specified mem_ctx
* internally retries when initial buffer was too small
int ret, flags;
unsigned int *len;
size_t struct_size;
+ bool use_capability = false;
again:
/* set the length of the buffer as input value */
*len = size;
- errno = 0;
- ret = gpfswrap_getacl(discard_const_p(char, fname), flags, aclbuf);
+ if (use_capability) {
+ ret = gpfs_getacl_with_capability(fname, flags, aclbuf);
+ } else {
+ ret = gpfswrap_getacl(discard_const_p(char, fname),
+ flags, aclbuf);
+ if ((ret != 0) && (errno == EACCES)) {
+ DBG_DEBUG("Retry with DAC capability for %s\n", fname);
+ use_capability = true;
+ ret = gpfs_getacl_with_capability(fname, flags, aclbuf);
+ }
+ }
+
if ((ret != 0) && (errno == ENOSPC)) {
/*
* get the size needed to accommodate the complete buffer
result = gpfs_get_nfs4_acl(frame, fsp->fsp_name->base_name, &pacl);
if (result == 0) {
- status = smb_fget_nt_acl_nfs4(fsp, security_info, mem_ctx,
- ppdesc, pacl);
+ status = smb_fget_nt_acl_nfs4(fsp, &config->nfs4_params,
+ security_info,
+ mem_ctx, ppdesc, pacl);
TALLOC_FREE(frame);
return status;
}
}
static NTSTATUS gpfsacl_get_nt_acl(vfs_handle_struct *handle,
- const char *name,
- uint32_t security_info,
- TALLOC_CTX *mem_ctx, struct security_descriptor **ppdesc)
+ const struct smb_filename *smb_fname,
+ uint32_t security_info,
+ TALLOC_CTX *mem_ctx,
+ struct security_descriptor **ppdesc)
{
struct SMB4ACL_T *pacl = NULL;
int result;
return NT_STATUS_INTERNAL_ERROR);
if (!config->acl) {
- status = SMB_VFS_NEXT_GET_NT_ACL(handle, name, security_info,
+ status = SMB_VFS_NEXT_GET_NT_ACL(handle, smb_fname,
+ security_info,
mem_ctx, ppdesc);
TALLOC_FREE(frame);
return status;
}
- result = gpfs_get_nfs4_acl(frame, name, &pacl);
+ result = gpfs_get_nfs4_acl(frame, smb_fname->base_name, &pacl);
if (result == 0) {
- status = smb_get_nt_acl_nfs4(handle->conn, name, security_info,
- mem_ctx, ppdesc, pacl);
+ status = smb_get_nt_acl_nfs4(handle->conn, smb_fname,
+ &config->nfs4_params,
+ security_info, mem_ctx, ppdesc,
+ pacl);
TALLOC_FREE(frame);
return status;
}
if (result > 0) {
DEBUG(10, ("retrying with posix acl...\n"));
- status = posix_get_nt_acl(handle->conn, name, security_info,
- mem_ctx, ppdesc);
+ status = posix_get_nt_acl(handle->conn, smb_fname,
+ security_info, mem_ctx, ppdesc);
TALLOC_FREE(frame);
return status;
}
}
if (acl->acl_version == GPFS_ACL_VERSION_NFS4) {
+ struct gpfs_config_data *config;
+
if (lp_parm_bool(fsp->conn->params->service, "gpfs",
"refuse_dacl_protected", false)
&& (psd->type&SEC_DESC_DACL_PROTECTED)) {
return NT_STATUS_NOT_SUPPORTED;
}
+ SMB_VFS_HANDLE_GET_DATA(handle, config,
+ struct gpfs_config_data,
+ return NT_STATUS_INTERNAL_ERROR);
+
result = smb_set_nt_acl_nfs4(handle,
- fsp, security_info_sent, psd,
+ fsp, &config->nfs4_params, security_info_sent, psd,
gpfsacl_process_smbacl);
} else { /* assume POSIX ACL - by default... */
result = set_nt_acl(fsp, security_info_sent, psd);
}
static SMB_ACL_T gpfsacl_sys_acl_get_file(vfs_handle_struct *handle,
- const char *path_p,
+ const struct smb_filename *smb_fname,
SMB_ACL_TYPE_T type,
TALLOC_CTX *mem_ctx)
{
return NULL);
if (!config->acl) {
- return SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, path_p,
+ return SMB_VFS_NEXT_SYS_ACL_GET_FILE(handle, smb_fname,
type, mem_ctx);
}
smb_panic("exiting");
}
- return gpfsacl_get_posix_acl(path_p, gpfs_type, mem_ctx);
+ return gpfsacl_get_posix_acl(smb_fname->base_name, gpfs_type, mem_ctx);
}
static SMB_ACL_T gpfsacl_sys_acl_get_fd(vfs_handle_struct *handle,
}
static int gpfsacl_sys_acl_blob_get_file(vfs_handle_struct *handle,
- const char *path_p,
+ const struct smb_filename *smb_fname,
TALLOC_CTX *mem_ctx,
char **blob_description,
DATA_BLOB *blob)
struct gpfs_opaque_acl *acl = NULL;
DATA_BLOB aclblob;
int result;
+ const char *path_p = smb_fname->base_name;
SMB_VFS_HANDLE_GET_DATA(handle, config,
struct gpfs_config_data,
return -1);
if (!config->acl) {
- return SMB_VFS_NEXT_SYS_ACL_BLOB_GET_FILE(handle, path_p,
+ return SMB_VFS_NEXT_SYS_ACL_BLOB_GET_FILE(handle, smb_fname,
mem_ctx,
blob_description,
blob);
return -1;
}
- result = non_posix_sys_acl_blob_get_file_helper(handle, path_p,
+ result = non_posix_sys_acl_blob_get_file_helper(handle, smb_fname,
aclblob,
mem_ctx, blob);
}
/* fall back to POSIX ACL */
- return posix_sys_acl_blob_get_file(handle, path_p, mem_ctx,
+ return posix_sys_acl_blob_get_file(handle, smb_fname, mem_ctx,
blob_description, blob);
}
}
static int gpfsacl_sys_acl_delete_def_file(vfs_handle_struct *handle,
- const char *path)
+ const struct smb_filename *smb_fname)
{
struct gpfs_config_data *config;
return -1);
if (!config->acl) {
- return SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, path);
+ return SMB_VFS_NEXT_SYS_ACL_DELETE_DEF_FILE(handle, smb_fname);
}
errno = ENOTSUP;
/* don't add complementary DENY ACEs here */
fake_fsp.fsp_name = synthetic_smb_fname(
- frame, path, NULL, NULL);
+ frame, path, NULL, NULL, 0);
if (fake_fsp.fsp_name == NULL) {
errno = ENOMEM;
TALLOC_FREE(frame);
return 0; /* ok for [f]chmod */
}
-static int vfs_gpfs_chmod(vfs_handle_struct *handle, const char *path, mode_t mode)
+static int vfs_gpfs_chmod(vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname,
+ mode_t mode)
{
struct smb_filename *smb_fname_cpath;
int rc;
- smb_fname_cpath = synthetic_smb_fname(talloc_tos(), path, NULL, NULL);
+ smb_fname_cpath = cp_smb_filename(talloc_tos(), smb_fname);
if (smb_fname_cpath == NULL) {
errno = ENOMEM;
return -1;
}
if (SMB_VFS_NEXT_STAT(handle, smb_fname_cpath) != 0) {
+ TALLOC_FREE(smb_fname_cpath);
return -1;
}
/* avoid chmod() if possible, to preserve acls */
if ((smb_fname_cpath->st.st_ex_mode & ~S_IFMT) == mode) {
+ TALLOC_FREE(smb_fname_cpath);
return 0;
}
- rc = gpfsacl_emu_chmod(handle, path, mode);
+ rc = gpfsacl_emu_chmod(handle, smb_fname->base_name, mode);
if (rc == 1)
- return SMB_VFS_NEXT_CHMOD(handle, path, mode);
+ return SMB_VFS_NEXT_CHMOD(handle, smb_fname, mode);
+
+ TALLOC_FREE(smb_fname_cpath);
return rc;
}
return rc;
}
-static int gpfs_set_xattr(struct vfs_handle_struct *handle, const char *path,
- const char *name, const void *value, size_t size, int flags){
- struct xattr_DOSATTRIB dosattrib;
- enum ndr_err_code ndr_err;
- DATA_BLOB blob;
- unsigned int dosmode=0;
- struct gpfs_winattr attrs;
- int ret = 0;
+static uint32_t vfs_gpfs_winattrs_to_dosmode(unsigned int winattrs)
+{
+ uint32_t dosmode = 0;
+
+ if (winattrs & GPFS_WINATTR_ARCHIVE){
+ dosmode |= FILE_ATTRIBUTE_ARCHIVE;
+ }
+ if (winattrs & GPFS_WINATTR_HIDDEN){
+ dosmode |= FILE_ATTRIBUTE_HIDDEN;
+ }
+ if (winattrs & GPFS_WINATTR_SYSTEM){
+ dosmode |= FILE_ATTRIBUTE_SYSTEM;
+ }
+ if (winattrs & GPFS_WINATTR_READONLY){
+ dosmode |= FILE_ATTRIBUTE_READONLY;
+ }
+ if (winattrs & GPFS_WINATTR_SPARSE_FILE) {
+ dosmode |= FILE_ATTRIBUTE_SPARSE;
+ }
+ if (winattrs & GPFS_WINATTR_OFFLINE) {
+ dosmode |= FILE_ATTRIBUTE_OFFLINE;
+ }
+
+ return dosmode;
+}
+
+static unsigned int vfs_gpfs_dosmode_to_winattrs(uint32_t dosmode)
+{
+ unsigned int winattrs = 0;
+
+ if (dosmode & FILE_ATTRIBUTE_ARCHIVE){
+ winattrs |= GPFS_WINATTR_ARCHIVE;
+ }
+ if (dosmode & FILE_ATTRIBUTE_HIDDEN){
+ winattrs |= GPFS_WINATTR_HIDDEN;
+ }
+ if (dosmode & FILE_ATTRIBUTE_SYSTEM){
+ winattrs |= GPFS_WINATTR_SYSTEM;
+ }
+ if (dosmode & FILE_ATTRIBUTE_READONLY){
+ winattrs |= GPFS_WINATTR_READONLY;
+ }
+ if (dosmode & FILE_ATTRIBUTE_SPARSE) {
+ winattrs |= GPFS_WINATTR_SPARSE_FILE;
+ }
+ if (dosmode & FILE_ATTRIBUTE_OFFLINE) {
+ winattrs |= GPFS_WINATTR_OFFLINE;
+ }
+
+ return winattrs;
+}
+
+static NTSTATUS vfs_gpfs_get_dos_attributes(struct vfs_handle_struct *handle,
+ struct smb_filename *smb_fname,
+ uint32_t *dosmode)
+{
struct gpfs_config_data *config;
+ struct gpfs_winattr attrs = { };
+ int ret;
SMB_VFS_HANDLE_GET_DATA(handle, config,
struct gpfs_config_data,
- return -1);
+ return NT_STATUS_INTERNAL_ERROR);
if (!config->winattr) {
- DEBUG(10, ("gpfs_set_xattr:name is %s -> next\n",name));
- return SMB_VFS_NEXT_SETXATTR(handle,path,name,value,size,flags);
+ return SMB_VFS_NEXT_GET_DOS_ATTRIBUTES(handle,
+ smb_fname, dosmode);
}
- DEBUG(10, ("gpfs_set_xattr: %s \n",path));
-
- /* Only handle DOS Attributes */
- if (strcmp(name,SAMBA_XATTR_DOS_ATTRIB) != 0){
- DEBUG(5, ("gpfs_set_xattr:name is %s\n",name));
- return SMB_VFS_NEXT_SETXATTR(handle,path,name,value,size,flags);
- }
+ ret = gpfswrap_get_winattrs_path(smb_fname->base_name, &attrs);
+ if (ret == -1 && errno == ENOSYS) {
+ return SMB_VFS_NEXT_GET_DOS_ATTRIBUTES(handle, smb_fname,
+ dosmode);
+ }
- blob.data = discard_const_p(uint8_t, value);
- blob.length = size;
+ if (ret == -1) {
+ DBG_WARNING("Getting winattrs failed for %s: %s\n",
+ smb_fname->base_name, strerror(errno));
+ return map_nt_error_from_unix(errno);
+ }
- ndr_err = ndr_pull_struct_blob(&blob, talloc_tos(), &dosattrib,
- (ndr_pull_flags_fn_t)ndr_pull_xattr_DOSATTRIB);
+ *dosmode |= vfs_gpfs_winattrs_to_dosmode(attrs.winAttrs);
+ smb_fname->st.st_ex_calculated_birthtime = false;
+ smb_fname->st.st_ex_btime.tv_sec = attrs.creationTime.tv_sec;
+ smb_fname->st.st_ex_btime.tv_nsec = attrs.creationTime.tv_nsec;
- if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
- DEBUG(1, ("gpfs_set_xattr: bad ndr decode "
- "from EA on file %s: Error = %s\n",
- path, ndr_errstr(ndr_err)));
- return false;
- }
+ return NT_STATUS_OK;
+}
- if (dosattrib.version != 3) {
- DEBUG(1, ("gpfs_set_xattr: expected dosattrib version 3, got "
- "%d\n", (int)dosattrib.version));
- return false;
- }
- if (!(dosattrib.info.info3.valid_flags & XATTR_DOSINFO_ATTRIB)) {
- DEBUG(10, ("gpfs_set_xattr: XATTR_DOSINFO_ATTRIB not "
- "valid, ignoring\n"));
- return true;
- }
+static NTSTATUS vfs_gpfs_fget_dos_attributes(struct vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ uint32_t *dosmode)
+{
+ struct gpfs_config_data *config;
+ struct gpfs_winattr attrs = { };
+ int ret;
- dosmode = dosattrib.info.info3.attrib;
+ SMB_VFS_HANDLE_GET_DATA(handle, config,
+ struct gpfs_config_data,
+ return NT_STATUS_INTERNAL_ERROR);
- attrs.winAttrs = 0;
- /*Just map RD_ONLY, ARCHIVE, SYSTEM HIDDEN and SPARSE. Ignore the others*/
- if (dosmode & FILE_ATTRIBUTE_ARCHIVE){
- attrs.winAttrs |= GPFS_WINATTR_ARCHIVE;
- }
- if (dosmode & FILE_ATTRIBUTE_HIDDEN){
- attrs.winAttrs |= GPFS_WINATTR_HIDDEN;
- }
- if (dosmode & FILE_ATTRIBUTE_SYSTEM){
- attrs.winAttrs |= GPFS_WINATTR_SYSTEM;
- }
- if (dosmode & FILE_ATTRIBUTE_READONLY){
- attrs.winAttrs |= GPFS_WINATTR_READONLY;
- }
- if (dosmode & FILE_ATTRIBUTE_SPARSE) {
- attrs.winAttrs |= GPFS_WINATTR_SPARSE_FILE;
+ if (!config->winattr) {
+ return SMB_VFS_NEXT_FGET_DOS_ATTRIBUTES(handle, fsp, dosmode);
}
+ ret = gpfswrap_get_winattrs(fsp->fh->fd, &attrs);
+ if (ret == -1 && errno == ENOSYS) {
+ return SMB_VFS_NEXT_FGET_DOS_ATTRIBUTES(handle, fsp, dosmode);
+ }
- ret = gpfswrap_set_winattrs_path(discard_const_p(char, path),
- GPFS_WINATTR_SET_ATTRS, &attrs);
- if ( ret == -1){
- if (errno == ENOSYS) {
- return SMB_VFS_NEXT_SETXATTR(handle, path, name, value,
- size, flags);
- }
+ if (ret == -1) {
+ DBG_WARNING("Getting winattrs failed for %s: %s\n",
+ fsp->fsp_name->base_name, strerror(errno));
+ return map_nt_error_from_unix(errno);
+ }
- DEBUG(1, ("gpfs_set_xattr:Set GPFS attributes failed %d\n",ret));
- return -1;
- }
+ *dosmode |= vfs_gpfs_winattrs_to_dosmode(attrs.winAttrs);
+ fsp->fsp_name->st.st_ex_calculated_birthtime = false;
+ fsp->fsp_name->st.st_ex_btime.tv_sec = attrs.creationTime.tv_sec;
+ fsp->fsp_name->st.st_ex_btime.tv_nsec = attrs.creationTime.tv_nsec;
- DEBUG(10, ("gpfs_set_xattr:Set attributes: 0x%x\n",attrs.winAttrs));
- return 0;
+ return NT_STATUS_OK;
}
-static ssize_t gpfs_get_xattr(struct vfs_handle_struct *handle, const char *path,
- const char *name, void *value, size_t size){
- char *attrstr = value;
- unsigned int dosmode = 0;
- struct gpfs_winattr attrs;
- int ret = 0;
+static NTSTATUS vfs_gpfs_set_dos_attributes(struct vfs_handle_struct *handle,
+ const struct smb_filename *smb_fname,
+ uint32_t dosmode)
+{
struct gpfs_config_data *config;
+ struct gpfs_winattr attrs = { };
+ int ret;
SMB_VFS_HANDLE_GET_DATA(handle, config,
struct gpfs_config_data,
- return -1);
+ return NT_STATUS_INTERNAL_ERROR);
if (!config->winattr) {
- DEBUG(10, ("gpfs_get_xattr:name is %s -> next\n",name));
- return SMB_VFS_NEXT_GETXATTR(handle,path,name,value,size);
+ return SMB_VFS_NEXT_SET_DOS_ATTRIBUTES(handle,
+ smb_fname, dosmode);
}
- DEBUG(10, ("gpfs_get_xattr: %s \n",path));
+ attrs.winAttrs = vfs_gpfs_dosmode_to_winattrs(dosmode);
+ ret = gpfswrap_set_winattrs_path(smb_fname->base_name,
+ GPFS_WINATTR_SET_ATTRS, &attrs);
- /* Only handle DOS Attributes */
- if (strcmp(name,SAMBA_XATTR_DOS_ATTRIB) != 0){
- DEBUG(5, ("gpfs_get_xattr:name is %s\n",name));
- return SMB_VFS_NEXT_GETXATTR(handle,path,name,value,size);
- }
+ if (ret == -1 && errno == ENOSYS) {
+ return SMB_VFS_NEXT_SET_DOS_ATTRIBUTES(handle,
+ smb_fname, dosmode);
+ }
- ret = gpfswrap_get_winattrs_path(discard_const_p(char, path), &attrs);
- if ( ret == -1){
- int dbg_lvl;
+ if (ret == -1) {
+ DBG_WARNING("Setting winattrs failed for %s: %s\n",
+ smb_fname->base_name, strerror(errno));
+ return map_nt_error_from_unix(errno);
+ }
- if (errno == ENOSYS) {
- return SMB_VFS_NEXT_GETXATTR(handle, path, name, value,
- size);
- }
+ return NT_STATUS_OK;
+}
- if (errno != EPERM && errno != EACCES) {
- dbg_lvl = 1;
- } else {
- dbg_lvl = 5;
- }
- DEBUG(dbg_lvl, ("gpfs_get_xattr: Get GPFS attributes failed: "
- "%d (%s)\n", ret, strerror(errno)));
- return -1;
- }
+static NTSTATUS vfs_gpfs_fset_dos_attributes(struct vfs_handle_struct *handle,
+ struct files_struct *fsp,
+ uint32_t dosmode)
+{
+ struct gpfs_config_data *config;
+ struct gpfs_winattr attrs = { };
+ int ret;
- DEBUG(10, ("gpfs_get_xattr:Got attributes: 0x%x\n",attrs.winAttrs));
+ SMB_VFS_HANDLE_GET_DATA(handle, config,
+ struct gpfs_config_data,
+ return NT_STATUS_INTERNAL_ERROR);
- /*Just map RD_ONLY, ARCHIVE, SYSTEM, HIDDEN and SPARSE. Ignore the others*/
- if (attrs.winAttrs & GPFS_WINATTR_ARCHIVE){
- dosmode |= FILE_ATTRIBUTE_ARCHIVE;
- }
- if (attrs.winAttrs & GPFS_WINATTR_HIDDEN){
- dosmode |= FILE_ATTRIBUTE_HIDDEN;
- }
- if (attrs.winAttrs & GPFS_WINATTR_SYSTEM){
- dosmode |= FILE_ATTRIBUTE_SYSTEM;
- }
- if (attrs.winAttrs & GPFS_WINATTR_READONLY){
- dosmode |= FILE_ATTRIBUTE_READONLY;
- }
- if (attrs.winAttrs & GPFS_WINATTR_SPARSE_FILE) {
- dosmode |= FILE_ATTRIBUTE_SPARSE;
+ if (!config->winattr) {
+ return SMB_VFS_NEXT_FSET_DOS_ATTRIBUTES(handle, fsp, dosmode);
+ }
+
+ attrs.winAttrs = vfs_gpfs_dosmode_to_winattrs(dosmode);
+ ret = gpfswrap_set_winattrs(fsp->fh->fd,
+ GPFS_WINATTR_SET_ATTRS, &attrs);
+
+ if (ret == -1 && errno == ENOSYS) {
+ return SMB_VFS_NEXT_FSET_DOS_ATTRIBUTES(handle, fsp, dosmode);
}
- snprintf(attrstr, size, "0x%2.2x",
- (unsigned int)(dosmode & SAMBA_ATTRIBUTES_MASK));
- DEBUG(10, ("gpfs_get_xattr: returning %s\n",attrstr));
- return 4;
+ if (ret == -1) {
+ DBG_WARNING("Setting winattrs failed for %s: %s\n",
+ fsp->fsp_name->base_name, strerror(errno));
+ return map_nt_error_from_unix(errno);
+ }
+
+ return NT_STATUS_OK;
}
-#if defined(HAVE_FSTATAT)
static int stat_with_capability(struct vfs_handle_struct *handle,
struct smb_filename *smb_fname, int flag)
{
+#if defined(HAVE_FSTATAT)
int fd = -1;
bool b;
char *dir_name;
}
return ret;
-}
+#else
+ return -1;
#endif
+}
static int vfs_gpfs_stat(struct vfs_handle_struct *handle,
struct smb_filename *smb_fname)
{
- struct gpfs_winattr attrs;
- char *fname = NULL;
- NTSTATUS status;
int ret;
struct gpfs_config_data *config;
return -1);
ret = SMB_VFS_NEXT_STAT(handle, smb_fname);
-#if defined(HAVE_FSTATAT)
if (ret == -1 && errno == EACCES) {
DEBUG(10, ("Trying stat with capability for %s\n",
smb_fname->base_name));
ret = stat_with_capability(handle, smb_fname, 0);
}
-#endif
- if (ret == -1) {
- return -1;
- }
-
- if (!config->winattr) {
- return 0;
- }
-
- status = get_full_smb_filename(talloc_tos(), smb_fname, &fname);
- if (!NT_STATUS_IS_OK(status)) {
- errno = map_errno_from_nt_status(status);
- return -1;
- }
- ret = gpfswrap_get_winattrs_path(discard_const_p(char, fname), &attrs);
- TALLOC_FREE(fname);
- if (ret == 0) {
- smb_fname->st.st_ex_calculated_birthtime = false;
- smb_fname->st.st_ex_btime.tv_sec = attrs.creationTime.tv_sec;
- smb_fname->st.st_ex_btime.tv_nsec = attrs.creationTime.tv_nsec;
- }
- return 0;
-}
-
-static int vfs_gpfs_fstat(struct vfs_handle_struct *handle,
- struct files_struct *fsp, SMB_STRUCT_STAT *sbuf)
-{
- struct gpfs_winattr attrs;
- int ret;
- struct gpfs_config_data *config;
-
- SMB_VFS_HANDLE_GET_DATA(handle, config,
- struct gpfs_config_data,
- return -1);
-
- ret = SMB_VFS_NEXT_FSTAT(handle, fsp, sbuf);
- if (ret == -1) {
- return -1;
- }
- if ((fsp->fh == NULL) || (fsp->fh->fd == -1)) {
- return 0;
- }
- if (!config->winattr) {
- return 0;
- }
-
- ret = gpfswrap_get_winattrs(fsp->fh->fd, &attrs);
- if (ret == 0) {
- sbuf->st_ex_calculated_birthtime = false;
- sbuf->st_ex_btime.tv_sec = attrs.creationTime.tv_sec;
- sbuf->st_ex_btime.tv_nsec = attrs.creationTime.tv_nsec;
- }
- return 0;
+ return ret;
}
static int vfs_gpfs_lstat(struct vfs_handle_struct *handle,
struct smb_filename *smb_fname)
{
- struct gpfs_winattr attrs;
- char *path = NULL;
- NTSTATUS status;
int ret;
struct gpfs_config_data *config;
return -1);
ret = SMB_VFS_NEXT_LSTAT(handle, smb_fname);
-#if defined(HAVE_FSTATAT)
if (ret == -1 && errno == EACCES) {
DEBUG(10, ("Trying lstat with capability for %s\n",
smb_fname->base_name));
ret = stat_with_capability(handle, smb_fname,
AT_SYMLINK_NOFOLLOW);
}
-#endif
-
- if (ret == -1) {
- return -1;
- }
- if (!config->winattr) {
- return 0;
- }
-
- status = get_full_smb_filename(talloc_tos(), smb_fname, &path);
- if (!NT_STATUS_IS_OK(status)) {
- errno = map_errno_from_nt_status(status);
- return -1;
- }
- ret = gpfswrap_get_winattrs_path(discard_const_p(char, path), &attrs);
- TALLOC_FREE(path);
- if (ret == 0) {
- smb_fname->st.st_ex_calculated_birthtime = false;
- smb_fname->st.st_ex_btime.tv_sec = attrs.creationTime.tv_sec;
- smb_fname->st.st_ex_btime.tv_nsec = attrs.creationTime.tv_nsec;
- }
- return 0;
+ return ret;
}
static void timespec_to_gpfs_time(struct timespec ts, gpfs_timestruc_t *gt,
return -1);
if (!config->winattr) {
- return SMB_VFS_NEXT_IS_OFFLINE(handle, fname, sbuf);
+ return false;
}
status = get_full_smb_filename(talloc_tos(), fname, &path);
if (!NT_STATUS_IS_OK(status)) {
- errno = map_errno_from_nt_status(status);
- return -1;
+ return false;
}
ret = gpfswrap_get_winattrs_path(path, &attrs);
}
DEBUG(10, ("%s is online\n", path));
TALLOC_FREE(path);
- return SMB_VFS_NEXT_IS_OFFLINE(handle, fname, sbuf);
+ return false;
}
static bool vfs_gpfs_fsp_is_offline(struct vfs_handle_struct *handle,
return ret;
}
+ ret = smbacl4_get_vfs_params(handle->conn, &config->nfs4_params);
+ if (ret < 0) {
+ TALLOC_FREE(config);
+ return ret;
+ }
+
config->sharemodes = lp_parm_bool(SNUM(handle->conn), "gpfs",
"sharemodes", true);
struct vfs_gpfs_pread_state {
struct files_struct *fsp;
ssize_t ret;
- int err;
bool was_offline;
+ struct vfs_aio_state vfs_aio_state;
};
static void vfs_gpfs_pread_done(struct tevent_req *subreq);
struct vfs_gpfs_pread_state *state = tevent_req_data(
req, struct vfs_gpfs_pread_state);
- state->ret = SMB_VFS_PREAD_RECV(subreq, &state->err);
+ state->ret = SMB_VFS_PREAD_RECV(subreq, &state->vfs_aio_state);
TALLOC_FREE(subreq);
tevent_req_done(req);
}
-static ssize_t vfs_gpfs_pread_recv(struct tevent_req *req, int *err)
+static ssize_t vfs_gpfs_pread_recv(struct tevent_req *req,
+ struct vfs_aio_state *vfs_aio_state)
{
struct vfs_gpfs_pread_state *state = tevent_req_data(
req, struct vfs_gpfs_pread_state);
struct files_struct *fsp = state->fsp;
- if (tevent_req_is_unix_error(req, err)) {
+ if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
return -1;
}
- *err = state->err;
+ *vfs_aio_state = state->vfs_aio_state;
if ((state->ret != -1) && state->was_offline) {
DEBUG(10, ("sending notify\n"));
struct vfs_gpfs_pwrite_state {
struct files_struct *fsp;
ssize_t ret;
- int err;
bool was_offline;
+ struct vfs_aio_state vfs_aio_state;
};
static void vfs_gpfs_pwrite_done(struct tevent_req *subreq);
struct vfs_gpfs_pwrite_state *state = tevent_req_data(
req, struct vfs_gpfs_pwrite_state);
- state->ret = SMB_VFS_PWRITE_RECV(subreq, &state->err);
+ state->ret = SMB_VFS_PWRITE_RECV(subreq, &state->vfs_aio_state);
TALLOC_FREE(subreq);
tevent_req_done(req);
}
-static ssize_t vfs_gpfs_pwrite_recv(struct tevent_req *req, int *err)
+static ssize_t vfs_gpfs_pwrite_recv(struct tevent_req *req,
+ struct vfs_aio_state *vfs_aio_state)
{
struct vfs_gpfs_pwrite_state *state = tevent_req_data(
req, struct vfs_gpfs_pwrite_state);
struct files_struct *fsp = state->fsp;
- if (tevent_req_is_unix_error(req, err)) {
+ if (tevent_req_is_unix_error(req, &vfs_aio_state->error)) {
return -1;
}
- *err = state->err;
+ *vfs_aio_state = state->vfs_aio_state;
if ((state->ret != -1) && state->was_offline) {
DEBUG(10, ("sending notify\n"));
.kernel_flock_fn = vfs_gpfs_kernel_flock,
.linux_setlease_fn = vfs_gpfs_setlease,
.get_real_filename_fn = vfs_gpfs_get_real_filename,
+ .get_dos_attributes_fn = vfs_gpfs_get_dos_attributes,
+ .fget_dos_attributes_fn = vfs_gpfs_fget_dos_attributes,
+ .set_dos_attributes_fn = vfs_gpfs_set_dos_attributes,
+ .fset_dos_attributes_fn = vfs_gpfs_fset_dos_attributes,
.fget_nt_acl_fn = gpfsacl_fget_nt_acl,
.get_nt_acl_fn = gpfsacl_get_nt_acl,
.fset_nt_acl_fn = gpfsacl_fset_nt_acl,
.chmod_fn = vfs_gpfs_chmod,
.fchmod_fn = vfs_gpfs_fchmod,
.close_fn = vfs_gpfs_close,
- .setxattr_fn = gpfs_set_xattr,
- .getxattr_fn = gpfs_get_xattr,
.stat_fn = vfs_gpfs_stat,
- .fstat_fn = vfs_gpfs_fstat,
.lstat_fn = vfs_gpfs_lstat,
.ntimes_fn = vfs_gpfs_ntimes,
- .is_offline_fn = vfs_gpfs_is_offline,
.aio_force_fn = vfs_gpfs_aio_force,
.sendfile_fn = vfs_gpfs_sendfile,
.fallocate_fn = vfs_gpfs_fallocate,
.ftruncate_fn = vfs_gpfs_ftruncate
};
-NTSTATUS vfs_gpfs_init(void);
-NTSTATUS vfs_gpfs_init(void)
+NTSTATUS vfs_gpfs_init(TALLOC_CTX *);
+NTSTATUS vfs_gpfs_init(TALLOC_CTX *ctx)
{
int ret;