vfs_gpfs: add path based fallback for gpfswrap_fstat_x() on pathref handles
authorRalph Boehme <slow@samba.org>
Thu, 29 Jul 2021 17:28:14 +0000 (19:28 +0200)
committerRalph Boehme <slow@samba.org>
Thu, 26 Aug 2021 19:18:31 +0000 (19:18 +0000)
BUG: https://bugzilla.samba.org/show_bug.cgi?id=14771

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Christof Schmitt <cs@samba.org>
source3/modules/vfs_gpfs.c

index 88d814cb8db0584174b93867a16a85014a03d5e6..a8e50b82a17f6319a55a520972161514679da9b3 100644 (file)
@@ -1474,6 +1474,9 @@ static NTSTATUS vfs_gpfs_fget_dos_attributes(struct vfs_handle_struct *handle,
                                             uint32_t *dosmode)
 {
        struct gpfs_config_data *config;
+       int fd = fsp_get_pathref_fd(fsp);
+       char buf[PATH_MAX];
+       const char *p = NULL;
        struct gpfs_iattr64 iattr = { };
        unsigned int litemask;
        struct timespec ts;
@@ -1489,7 +1492,22 @@ static NTSTATUS vfs_gpfs_fget_dos_attributes(struct vfs_handle_struct *handle,
                return SMB_VFS_NEXT_FGET_DOS_ATTRIBUTES(handle, fsp, dosmode);
        }
 
-       ret = gpfswrap_fstat_x(fsp_get_pathref_fd(fsp), &litemask, &iattr, sizeof(iattr));
+       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;
+                       }
+               } else {
+                       p = fsp->fsp_name->base_name;
+               }
+       }
+
+       if (p != NULL) {
+               ret = gpfswrap_stat_x(p, &litemask, &iattr, sizeof(iattr));
+       } else {
+               ret = gpfswrap_fstat_x(fd, &litemask, &iattr, sizeof(iattr));
+       }
        if (ret == -1 && errno == ENOSYS) {
                return SMB_VFS_NEXT_FGET_DOS_ATTRIBUTES(handle, fsp, dosmode);
        }
@@ -1506,8 +1524,17 @@ static NTSTATUS vfs_gpfs_fget_dos_attributes(struct vfs_handle_struct *handle,
 
                set_effective_capability(DAC_OVERRIDE_CAPABILITY);
 
-               ret = gpfswrap_fstat_x(fsp_get_pathref_fd(fsp), &litemask,
-                                      &iattr, sizeof(iattr));
+               if (p != NULL) {
+                       ret = gpfswrap_stat_x(p,
+                                             &litemask,
+                                             &iattr,
+                                             sizeof(iattr));
+               } else {
+                       ret = gpfswrap_fstat_x(fd,
+                                              &litemask,
+                                              &iattr,
+                                              sizeof(iattr));
+               }
                if (ret == -1) {
                        saved_errno = errno;
                }