s4:kdc: Implement KDC plugin hardware authentication policy
[samba.git] / source3 / modules / vfs_gpfs.c
index 9a85ee0c6a94711dc89006962ff4daf42ba2239e..a8b4e38ff88c00c61285258f92c4f4a67de152a2 100644 (file)
@@ -431,7 +431,7 @@ static int gpfs_getacl_with_capability(struct files_struct *fsp,
 
        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);
@@ -492,7 +492,7 @@ again:
        if (use_capability) {
                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;
@@ -842,14 +842,6 @@ static NTSTATUS gpfsacl_set_nt_acl_internal(vfs_handle_struct *handle, files_str
        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);
@@ -1454,7 +1446,7 @@ static NTSTATUS vfs_gpfs_fget_dos_attributes(struct vfs_handle_struct *handle,
 {
        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;
@@ -1471,10 +1463,7 @@ static NTSTATUS vfs_gpfs_fget_dos_attributes(struct vfs_handle_struct *handle,
 
        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;
                }
@@ -1568,20 +1557,17 @@ static NTSTATUS vfs_gpfs_fset_dos_attributes(struct vfs_handle_struct *handle,
 
        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;
@@ -1602,86 +1588,27 @@ static NTSTATUS vfs_gpfs_fset_dos_attributes(struct vfs_handle_struct *handle,
        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;
-}
+       *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_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;
-}
-
-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,
@@ -1692,10 +1619,21 @@ 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");
@@ -1714,18 +1652,16 @@ static int smbd_gpfs_set_times(struct files_struct *fsp,
 
        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;
-               }
-
-               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;
        }
@@ -1770,7 +1706,7 @@ static int vfs_gpfs_fntimes(struct vfs_handle_struct *handle,
        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;
@@ -1802,17 +1738,12 @@ static int vfs_gpfs_fntimes(struct vfs_handle_struct *handle,
 
        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;
@@ -1878,7 +1809,7 @@ static int vfs_gpfs_ftruncate(vfs_handle_struct *handle, files_struct *fsp,
 }
 
 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;
@@ -1893,17 +1824,17 @@ static bool vfs_gpfs_is_offline(struct vfs_handle_struct *handle,
                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;
 }
 
@@ -1917,7 +1848,7 @@ static bool vfs_gpfs_fsp_is_offline(struct vfs_handle_struct *handle,
                /*
                 * 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);
        }
 
@@ -1925,7 +1856,7 @@ static bool vfs_gpfs_fsp_is_offline(struct vfs_handle_struct *handle,
                /*
                 * 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);
        }
 
@@ -2027,7 +1958,24 @@ static int vfs_gpfs_connect(struct vfs_handle_struct *handle,
                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) {
@@ -2332,9 +2280,9 @@ static int vfs_gpfs_openat(struct vfs_handle_struct *handle,
                           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;
@@ -2354,7 +2302,7 @@ static int vfs_gpfs_openat(struct vfs_handle_struct *handle,
        }
 
        if (config->syncio) {
-               flags |= O_SYNC;
+               how.flags |= O_SYNC;
        }
 
        ext = VFS_ADD_FSP_EXTENSION(handle, fsp, struct gpfs_fsp_extension,
@@ -2369,7 +2317,7 @@ static int vfs_gpfs_openat(struct vfs_handle_struct *handle,
         */
        *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);
        }
@@ -2572,8 +2520,10 @@ static struct vfs_fn_pointers vfs_gpfs_fns = {
        .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,
@@ -2591,13 +2541,6 @@ static struct vfs_fn_pointers vfs_gpfs_fns = {
 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);
 }