}
}
-static int gpfs_getacl_with_capability(const char *fname, int flags, void *buf)
+static int gpfs_getacl_with_capability(struct files_struct *fsp,
+ int flags,
+ void *buf)
{
int ret, saved_errno;
set_effective_capability(DAC_OVERRIDE_CAPABILITY);
- ret = gpfswrap_getacl(fname, flags, buf);
+ ret = gpfswrap_fgetacl(fsp_get_pathref_fd(fsp), flags, buf);
saved_errno = errno;
drop_effective_capability(DAC_OVERRIDE_CAPABILITY);
*
*/
static void *vfs_gpfs_getacl(TALLOC_CTX *mem_ctx,
- const char *fname,
+ struct files_struct *fsp,
const bool raw,
const gpfs_aclType_t type)
{
-
+ const char *fname = fsp->fsp_name->base_name;
void *aclbuf;
size_t size = 512;
int ret, flags;
*len = size;
if (use_capability) {
- ret = gpfs_getacl_with_capability(fname, flags, aclbuf);
+ ret = gpfs_getacl_with_capability(fsp, flags, aclbuf);
} else {
- ret = gpfswrap_getacl(fname, flags, aclbuf);
+ ret = gpfswrap_fgetacl(fsp_get_pathref_fd(fsp), 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);
+ ret = gpfs_getacl_with_capability(fsp, flags, aclbuf);
}
}
DEBUG(10, ("gpfs_get_nfs4_acl invoked for %s\n", fname));
/* Get the ACL */
- gacl = (struct gpfs_acl*) vfs_gpfs_getacl(talloc_tos(), fname,
+ gacl = (struct gpfs_acl*) vfs_gpfs_getacl(talloc_tos(), fsp,
false, 0);
if (gacl == NULL) {
DEBUG(9, ("gpfs_getacl failed for %s with %s\n",
NTSTATUS result = NT_STATUS_ACCESS_DENIED;
acl = (struct gpfs_acl*) vfs_gpfs_getacl(talloc_tos(),
- fsp->fsp_name->base_name,
+ fsp,
false, 0);
if (acl == NULL) {
return map_nt_error_from_unix(errno);
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)) {
- DEBUG(2, ("Rejecting unsupported ACL with DACL_PROTECTED bit set\n"));
- talloc_free(acl);
- return NT_STATUS_NOT_SUPPORTED;
- }
-
SMB_VFS_HANDLE_GET_DATA(handle, config,
struct gpfs_config_data,
return NT_STATUS_INTERNAL_ERROR);
gpfs_aclType_t type,
TALLOC_CTX *mem_ctx)
{
- const char *path = fsp->fsp_name->base_name;
struct gpfs_acl *pacl;
SMB_ACL_T result = NULL;
- pacl = vfs_gpfs_getacl(talloc_tos(), path, false, type);
+ pacl = vfs_gpfs_getacl(talloc_tos(), fsp, false, type);
if (pacl == NULL) {
- DEBUG(10, ("vfs_gpfs_getacl failed for %s with %s\n",
- path, strerror(errno)));
+ DBG_DEBUG("vfs_gpfs_getacl failed for %s with %s\n",
+ fsp_str_dbg(fsp), strerror(errno));
if (errno == 0) {
errno = EINVAL;
}
errno = 0;
acl = (struct gpfs_opaque_acl *) vfs_gpfs_getacl(mem_ctx,
- fsp->fsp_name->base_name,
+ fsp,
true,
GPFS_ACL_TYPE_NFS4);
{
struct gpfs_config_data *config;
int fd = fsp_get_pathref_fd(fsp);
- char buf[PATH_MAX];
+ struct sys_proc_fd_path_buf buf;
const char *p = NULL;
struct gpfs_iattr64 iattr = { };
unsigned int litemask = 0;
if (fsp->fsp_flags.is_pathref && !config->pathref_ok.gpfs_fstat_x) {
if (fsp->fsp_flags.have_proc_fds) {
- p = sys_proc_fd_path(fd, buf, sizeof(buf));
- if (p == NULL) {
- return NT_STATUS_NO_MEMORY;
- }
+ p = sys_proc_fd_path(fd, &buf);
} else {
p = fsp->fsp_name->base_name;
}
if (fsp->fsp_flags.have_proc_fds) {
int fd = fsp_get_pathref_fd(fsp);
- const char *p = NULL;
- char buf[PATH_MAX];
-
- p = sys_proc_fd_path(fd, buf, sizeof(buf));
- if (p == NULL) {
- return NT_STATUS_NO_MEMORY;
- }
+ struct sys_proc_fd_path_buf buf;
- ret = gpfswrap_set_winattrs_path(p,
+ ret = gpfswrap_set_winattrs_path(sys_proc_fd_path(fd, &buf),
GPFS_WINATTR_SET_ATTRS,
&attrs);
if (ret == -1) {
- DBG_WARNING("Setting winattrs failed for [%s][%s]: %s\n",
- p, fsp_str_dbg(fsp), strerror(errno));
+ DBG_WARNING("Setting winattrs failed for "
+ "[%s][%s]: %s\n",
+ buf.buf,
+ fsp_str_dbg(fsp),
+ strerror(errno));
return map_nt_error_from_unix(errno);
}
return NT_STATUS_OK;
return NT_STATUS_OK;
}
-static int stat_with_capability(struct vfs_handle_struct *handle,
- struct smb_filename *smb_fname, int flag)
+static int timespec_to_gpfs_time(
+ struct timespec ts, gpfs_timestruc_t *gt, int idx, int *flags)
{
- int fd = -1;
- NTSTATUS status;
- struct smb_filename *dir_name = NULL;
- struct smb_filename *rel_name = NULL;
- struct stat st;
- int ret = -1;
-
- status = SMB_VFS_PARENT_PATHNAME(handle->conn,
- talloc_tos(),
- smb_fname,
- &dir_name,
- &rel_name);
- if (!NT_STATUS_IS_OK(status)) {
- errno = map_errno_from_nt_status(status);
- return -1;
+ if (is_omit_timespec(&ts)) {
+ return 0;
}
- fd = open(dir_name->base_name, O_RDONLY, 0);
- if (fd == -1) {
- TALLOC_FREE(dir_name);
+ if (ts.tv_sec < 0 || ts.tv_sec > UINT32_MAX) {
+ DBG_NOTICE("GPFS uses 32-bit unsigned timestamps "
+ "and cannot handle %jd.\n",
+ (intmax_t)ts.tv_sec);
+ errno = ERANGE;
return -1;
}
- set_effective_capability(DAC_OVERRIDE_CAPABILITY);
- ret = fstatat(fd, rel_name->base_name, &st, flag);
- drop_effective_capability(DAC_OVERRIDE_CAPABILITY);
-
- TALLOC_FREE(dir_name);
- close(fd);
-
- if (ret == 0) {
- init_stat_ex_from_stat(
- &smb_fname->st, &st,
- lp_fake_directory_create_times(SNUM(handle->conn)));
- }
-
- return ret;
-}
-
-static int vfs_gpfs_stat(struct vfs_handle_struct *handle,
- struct smb_filename *smb_fname)
-{
- int ret;
-
- ret = SMB_VFS_NEXT_STAT(handle, smb_fname);
- 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);
- }
- return ret;
-}
+ *flags |= 1 << idx;
+ gt[idx].tv_sec = ts.tv_sec;
+ gt[idx].tv_nsec = ts.tv_nsec;
+ DBG_DEBUG("Setting GPFS time %d, flags 0x%x\n", idx, *flags);
-static int vfs_gpfs_lstat(struct vfs_handle_struct *handle,
- struct smb_filename *smb_fname)
-{
- int ret;
-
- ret = SMB_VFS_NEXT_LSTAT(handle, smb_fname);
- 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);
- }
- return ret;
-}
-
-static void timespec_to_gpfs_time(struct timespec ts, gpfs_timestruc_t *gt,
- int idx, int *flags)
-{
- if (!is_omit_timespec(&ts)) {
- *flags |= 1 << idx;
- gt[idx].tv_sec = ts.tv_sec;
- gt[idx].tv_nsec = ts.tv_nsec;
- DEBUG(10, ("Setting GPFS time %d, flags 0x%x\n", idx, *flags));
- }
+ return 0;
}
static int smbd_gpfs_set_times(struct files_struct *fsp,
int rc;
ZERO_ARRAY(gpfs_times);
- timespec_to_gpfs_time(ft->atime, gpfs_times, 0, &flags);
- timespec_to_gpfs_time(ft->mtime, gpfs_times, 1, &flags);
+ rc = timespec_to_gpfs_time(ft->atime, gpfs_times, 0, &flags);
+ if (rc != 0) {
+ return rc;
+ }
+
+ rc = timespec_to_gpfs_time(ft->mtime, gpfs_times, 1, &flags);
+ if (rc != 0) {
+ return rc;
+ }
+
/* No good mapping from LastChangeTime to ctime, not storing */
- timespec_to_gpfs_time(ft->create_time, gpfs_times, 3, &flags);
+ rc = timespec_to_gpfs_time(ft->create_time, gpfs_times, 3, &flags);
+ if (rc != 0) {
+ return rc;
+ }
if (!flags) {
DBG_DEBUG("nothing to do, return to avoid EINVAL\n");
if (fsp->fsp_flags.have_proc_fds) {
int fd = fsp_get_pathref_fd(fsp);
- const char *p = NULL;
- char buf[PATH_MAX];
-
- p = sys_proc_fd_path(fd, buf, sizeof(buf));
- if (p == NULL) {
- return -1;
- }
+ struct sys_proc_fd_path_buf buf;
- rc = gpfswrap_set_times_path(buf, flags, gpfs_times);
+ rc = gpfswrap_set_times_path(sys_proc_fd_path(fd, &buf),
+ flags,
+ gpfs_times);
if (rc != 0) {
DBG_WARNING("gpfs_set_times_path(%s,%s) failed: %s\n",
- fsp_str_dbg(fsp), p, strerror(errno));
+ fsp_str_dbg(fsp),
+ buf.buf,
+ strerror(errno));
}
return rc;
}
if (ret == -1) {
/* don't complain if access was denied */
if (errno != EPERM && errno != EACCES) {
- DBG_WARNING("SMB_VFS_NEXT_FNTIMES failed: %s",
+ DBG_WARNING("SMB_VFS_NEXT_FNTIMES failed: %s\n",
strerror(errno));
}
return -1;
if (fsp->fsp_flags.have_proc_fds) {
int fd = fsp_get_pathref_fd(fsp);
- const char *p = NULL;
- char buf[PATH_MAX];
+ struct sys_proc_fd_path_buf buf;
- p = sys_proc_fd_path(fd, buf, sizeof(buf));
- if (p == NULL) {
- return -1;
- }
-
- ret = gpfswrap_set_winattrs_path(p,
- GPFS_WINATTR_SET_CREATION_TIME,
- &attrs);
+ ret = gpfswrap_set_winattrs_path(
+ sys_proc_fd_path(fd, &buf),
+ GPFS_WINATTR_SET_CREATION_TIME,
+ &attrs);
if (ret == -1 && errno != ENOSYS) {
DBG_WARNING("Set GPFS ntimes failed %d\n", ret);
return -1;
}
static bool vfs_gpfs_is_offline(struct vfs_handle_struct *handle,
- const struct smb_filename *fname,
+ struct files_struct *fsp,
SMB_STRUCT_STAT *sbuf)
{
struct gpfs_winattr attrs;
return false;
}
- ret = gpfswrap_get_winattrs_path(fname->base_name, &attrs);
+ ret = gpfswrap_get_winattrs(fsp_get_pathref_fd(fsp), &attrs);
if (ret == -1) {
return false;
}
if ((attrs.winAttrs & GPFS_WINATTR_OFFLINE) != 0) {
- DBG_DEBUG("%s is offline\n", fname->base_name);
+ DBG_DEBUG("%s is offline\n", fsp_str_dbg(fsp));
return true;
}
- DBG_DEBUG("%s is online\n", fname->base_name);
+ DBG_DEBUG("%s is online\n", fsp_str_dbg(fsp));
return false;
}
/*
* Something bad happened, always ask.
*/
- return vfs_gpfs_is_offline(handle, fsp->fsp_name,
+ return vfs_gpfs_is_offline(handle, fsp,
&fsp->fsp_name->st);
}
/*
* As long as it's offline, ask.
*/
- ext->offline = vfs_gpfs_is_offline(handle, fsp->fsp_name,
+ ext->offline = vfs_gpfs_is_offline(handle, fsp,
&fsp->fsp_name->st);
}
return 0;
}
- gpfswrap_lib_init(0);
+ ret = gpfswrap_init();
+ if (ret < 0) {
+ DBG_ERR("Could not load GPFS library.\n");
+ return ret;
+ }
+
+ ret = gpfswrap_lib_init(0);
+ if (ret < 0) {
+ DBG_ERR("Could not open GPFS device file: %s\n",
+ strerror(errno));
+ return ret;
+ }
+
+ ret = gpfswrap_register_cifs_export();
+ if (ret < 0) {
+ DBG_ERR("Failed to register with GPFS: %s\n", strerror(errno));
+ return ret;
+ }
config = talloc_zero(handle->conn, struct gpfs_config_data);
if (!config) {
const struct files_struct *dirfsp,
const struct smb_filename *smb_fname,
files_struct *fsp,
- int flags,
- mode_t mode)
+ const struct vfs_open_how *_how)
{
+ struct vfs_open_how how = *_how;
struct gpfs_config_data *config = NULL;
struct gpfs_fsp_extension *ext = NULL;
int ret;
}
if (config->syncio) {
- flags |= O_SYNC;
+ how.flags |= O_SYNC;
}
ext = VFS_ADD_FSP_EXTENSION(handle, fsp, struct gpfs_fsp_extension,
*/
*ext = (struct gpfs_fsp_extension) { .offline = true };
- ret = SMB_VFS_NEXT_OPENAT(handle, dirfsp, smb_fname, fsp, flags, mode);
+ ret = SMB_VFS_NEXT_OPENAT(handle, dirfsp, smb_fname, fsp, &how);
if (ret == -1) {
VFS_REMOVE_FSP_EXTENSION(handle, fsp);
}
.sys_acl_delete_def_fd_fn = gpfsacl_sys_acl_delete_def_fd,
.fchmod_fn = vfs_gpfs_fchmod,
.close_fn = vfs_gpfs_close,
- .stat_fn = vfs_gpfs_stat,
- .lstat_fn = vfs_gpfs_lstat,
+ .stat_fn = nfs4_acl_stat,
+ .fstat_fn = nfs4_acl_fstat,
+ .lstat_fn = nfs4_acl_lstat,
+ .fstatat_fn = nfs4_acl_fstatat,
.fntimes_fn = vfs_gpfs_fntimes,
.aio_force_fn = vfs_gpfs_aio_force,
.sendfile_fn = vfs_gpfs_sendfile,
static_decl_vfs;
NTSTATUS vfs_gpfs_init(TALLOC_CTX *ctx)
{
- int ret;
-
- ret = gpfswrap_init();
- if (ret != 0) {
- DEBUG(1, ("Could not initialize GPFS library wrapper\n"));
- }
-
return smb_register_vfs(SMB_VFS_INTERFACE_VERSION, "gpfs",
&vfs_gpfs_fns);
}