vfs: Convert get_real_filename() to NTSTATUS
authorVolker Lendecke <vl@samba.org>
Mon, 7 Mar 2022 17:00:20 +0000 (18:00 +0100)
committerJeremy Allison <jra@samba.org>
Thu, 10 Mar 2022 18:23:36 +0000 (18:23 +0000)
This makes it possible to more easily handle STOPPED_ON_SYMLINK vs
OBJECT_PATH_NOT_FOUND vs OBJECT_NAME_NOT_FOUND and so on. The next
patch needs this to properly handle symlinks.

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Jeremy Allison <jra@samba.org>
18 files changed:
examples/VFS/skel_opaque.c
examples/VFS/skel_transparent.c
source3/include/vfs.h
source3/modules/vfs_ceph.c
source3/modules/vfs_ceph_snapshots.c
source3/modules/vfs_default.c
source3/modules/vfs_full_audit.c
source3/modules/vfs_glusterfs.c
source3/modules/vfs_glusterfs_fuse.c
source3/modules/vfs_gpfs.c
source3/modules/vfs_not_implemented.c
source3/modules/vfs_shadow_copy2.c
source3/modules/vfs_snapper.c
source3/modules/vfs_time_audit.c
source3/smbd/dir.c
source3/smbd/filename.c
source3/smbd/proto.h
source3/smbd/vfs.c

index e39668ed2a8aa73227bb5d8ab79095106930216d..4719a45e7bbc0eee54b517f743e3f6ab726ee1b2 100644 (file)
@@ -651,13 +651,13 @@ static NTSTATUS skel_fstreaminfo(struct vfs_handle_struct *handle,
        return NT_STATUS_NOT_IMPLEMENTED;
 }
 
-static int skel_get_real_filename(struct vfs_handle_struct *handle,
-                                 const struct smb_filename *path,
-                                 const char *name,
-                                 TALLOC_CTX *mem_ctx, char **found_name)
+static NTSTATUS skel_get_real_filename(struct vfs_handle_struct *handle,
+                                      const struct smb_filename *path,
+                                      const char *name,
+                                      TALLOC_CTX *mem_ctx,
+                                      char **found_name)
 {
-       errno = ENOSYS;
-       return -1;
+       return NT_STATUS_NOT_IMPLEMENTED;
 }
 
 static const char *skel_connectpath(struct vfs_handle_struct *handle,
index 5508e084abd53c3fe740dde4bead750802a15acf..ecd3c282240a62adf705ce2ee54c7021fcfec8b5 100644 (file)
@@ -875,10 +875,11 @@ static NTSTATUS skel_fstreaminfo(struct vfs_handle_struct *handle,
                                streams);
 }
 
-static int skel_get_real_filename(struct vfs_handle_struct *handle,
-                                 const struct smb_filename *path,
-                                 const char *name,
-                                 TALLOC_CTX *mem_ctx, char **found_name)
+static NTSTATUS skel_get_real_filename(struct vfs_handle_struct *handle,
+                                      const struct smb_filename *path,
+                                      const char *name,
+                                      TALLOC_CTX *mem_ctx,
+                                      char **found_name)
 {
        return SMB_VFS_NEXT_GET_REAL_FILENAME(handle,
                                              path, name, mem_ctx, found_name);
index 39cb38bcc91c709e2e61c9f3453e1f394f2fcf0d..333fdba15489a3981e7aa62417c0382910201c4f 100644 (file)
  * Version 46 - Rename SMB_VFS_KERNEL_FLOCK to SMB_VFS_FILESYSTEM_SHAREMODE
  * Version 46 - Add flags and xferlen args to SMB_VFS_OFFLOAD_READ_RECV
  * Version 46 - Add SMB_VFS_FSTATAT
+ * Version 46 - Change SMB_VFS_GET_REAL_FILENAME to return NTSTATUS
  */
 
 #define SMB_VFS_INTERFACE_VERSION 46
@@ -1142,11 +1143,11 @@ struct vfs_fn_pointers {
                                   unsigned int *num_streams,
                                   struct stream_struct **streams);
 
-       int (*get_real_filename_fn)(struct vfs_handle_struct *handle,
-                                   const struct smb_filename *path,
-                                   const char *name,
-                                   TALLOC_CTX *mem_ctx,
-                                   char **found_name);
+       NTSTATUS (*get_real_filename_fn)(struct vfs_handle_struct *handle,
+                                        const struct smb_filename *path,
+                                        const char *name,
+                                        TALLOC_CTX *mem_ctx,
+                                        char **found_name);
 
        const char *(*connectpath_fn)(struct vfs_handle_struct *handle,
                                      const struct smb_filename *smb_fname);
@@ -1611,11 +1612,11 @@ NTSTATUS smb_vfs_call_fstreaminfo(struct vfs_handle_struct *handle,
                                  TALLOC_CTX *mem_ctx,
                                  unsigned int *num_streams,
                                  struct stream_struct **streams);
-int smb_vfs_call_get_real_filename(struct vfs_handle_struct *handle,
-                                  const struct smb_filename *path,
-                                  const char *name,
-                                  TALLOC_CTX *mem_ctx,
-                                  char **found_name);
+NTSTATUS smb_vfs_call_get_real_filename(struct vfs_handle_struct *handle,
+                                       const struct smb_filename *path,
+                                       const char *name,
+                                       TALLOC_CTX *mem_ctx,
+                                       char **found_name);
 const char *smb_vfs_call_connectpath(struct vfs_handle_struct *handle,
                                     const struct smb_filename *smb_fname);
 NTSTATUS smb_vfs_call_brl_lock_windows(struct vfs_handle_struct *handle,
@@ -2077,11 +2078,12 @@ NTSTATUS vfs_not_implemented_fstreaminfo(struct vfs_handle_struct *handle,
                                         TALLOC_CTX *mem_ctx,
                                         unsigned int *num_streams,
                                         struct stream_struct **streams);
-int vfs_not_implemented_get_real_filename(struct vfs_handle_struct *handle,
-                                         const struct smb_filename *path,
-                                         const char *name,
-                                         TALLOC_CTX *mem_ctx,
-                                         char **found_name);
+NTSTATUS vfs_not_implemented_get_real_filename(
+       struct vfs_handle_struct *handle,
+       const struct smb_filename *path,
+       const char *name,
+       TALLOC_CTX *mem_ctx,
+       char **found_name);
 const char *vfs_not_implemented_connectpath(struct vfs_handle_struct *handle,
                                            const struct smb_filename *smb_fname);
 NTSTATUS vfs_not_implemented_brl_lock_windows(struct vfs_handle_struct *handle,
index 4e1fa6a2df440881a0576dd71a01b938148cd32e..9188b7991d4064b60cf5139e0b7a68d0deaed6fe 100644 (file)
@@ -1276,18 +1276,18 @@ static int cephwrap_fchflags(struct vfs_handle_struct *handle,
        return -1;
 }
 
-static int cephwrap_get_real_filename(struct vfs_handle_struct *handle,
-                                    const struct smb_filename *path,
-                                    const char *name,
-                                    TALLOC_CTX *mem_ctx,
-                                    char **found_name)
+static NTSTATUS cephwrap_get_real_filename(
+       struct vfs_handle_struct *handle,
+       const struct smb_filename *path,
+       const char *name,
+       TALLOC_CTX *mem_ctx,
+       char **found_name)
 {
        /*
         * Don't fall back to get_real_filename so callers can differentiate
         * between a full directory scan and an actual case-insensitive stat.
         */
-       errno = EOPNOTSUPP;
-       return -1;
+       return NT_STATUS_NOT_SUPPORTED;
 }
 
 static const char *cephwrap_connectpath(struct vfs_handle_struct *handle,
index d533b9479a3d59eb94f6c156bf705affbc362730..ad4c8f1dd94ce5a4e3843c1cae74245b70e68e35 100644 (file)
@@ -1313,23 +1313,24 @@ static int ceph_snap_gmt_fsetxattr(struct vfs_handle_struct *handle,
                                aname, value, size, flags);
 }
 
-static int ceph_snap_gmt_get_real_filename(struct vfs_handle_struct *handle,
-                                        const struct smb_filename *path,
-                                        const char *name,
-                                        TALLOC_CTX *mem_ctx,
-                                        char **found_name)
+static NTSTATUS ceph_snap_gmt_get_real_filename(
+       struct vfs_handle_struct *handle,
+       const struct smb_filename *path,
+       const char *name,
+       TALLOC_CTX *mem_ctx,
+       char **found_name)
 {
        time_t timestamp = 0;
        char stripped[PATH_MAX + 1];
        char conv[PATH_MAX + 1];
        struct smb_filename conv_fname;
        int ret;
+       NTSTATUS status;
 
        ret = ceph_snap_gmt_strip_snapshot(handle, path,
                                        &timestamp, stripped, sizeof(stripped));
        if (ret < 0) {
-               errno = -ret;
-               return -1;
+               return map_nt_error_from_unix(-ret);
        }
        if (timestamp == 0) {
                return SMB_VFS_NEXT_GET_REAL_FILENAME(handle, path, name,
@@ -1338,17 +1339,16 @@ static int ceph_snap_gmt_get_real_filename(struct vfs_handle_struct *handle,
        ret = ceph_snap_gmt_convert_dir(handle, stripped,
                                        timestamp, conv, sizeof(conv));
        if (ret < 0) {
-               errno = -ret;
-               return -1;
+               return map_nt_error_from_unix(-ret);
        }
 
        conv_fname = (struct smb_filename) {
                .base_name = conv,
        };
 
-       ret = SMB_VFS_NEXT_GET_REAL_FILENAME(handle, &conv_fname, name,
-                                            mem_ctx, found_name);
-       return ret;
+       status = SMB_VFS_NEXT_GET_REAL_FILENAME(
+               handle, &conv_fname, name, mem_ctx, found_name);
+       return status;
 }
 
 static uint64_t ceph_snap_gmt_disk_free(vfs_handle_struct *handle,
index d6c244e561323fac2b77ae682325211b2700067f..6c4f15ba39fb617a3860067f982c54f81a57e8ca 100644 (file)
@@ -3362,18 +3362,17 @@ static NTSTATUS vfswrap_fstreaminfo(vfs_handle_struct *handle,
        return NT_STATUS_OK;
 }
 
-static int vfswrap_get_real_filename(struct vfs_handle_struct *handle,
-                                    const struct smb_filename *path,
-                                    const char *name,
-                                    TALLOC_CTX *mem_ctx,
-                                    char **found_name)
+static NTSTATUS vfswrap_get_real_filename(struct vfs_handle_struct *handle,
+                                         const struct smb_filename *path,
+                                         const char *name,
+                                         TALLOC_CTX *mem_ctx,
+                                         char **found_name)
 {
        /*
         * Don't fall back to get_real_filename so callers can differentiate
         * between a full directory scan and an actual case-insensitive stat.
         */
-       errno = EOPNOTSUPP;
-       return -1;
+       return NT_STATUS_NOT_SUPPORTED;
 }
 
 static const char *vfswrap_connectpath(struct vfs_handle_struct *handle,
index 9fd712399c981a1b3a00b1b97001b739c77ee9b6..a905971c1b953772bd696b85e3e0beb648163bb9 100644 (file)
@@ -2080,20 +2080,25 @@ static NTSTATUS smb_full_audit_fstreaminfo(vfs_handle_struct *handle,
         return result;
 }
 
-static int smb_full_audit_get_real_filename(struct vfs_handle_struct *handle,
-                                           const struct smb_filename *path,
-                                           const char *name,
-                                           TALLOC_CTX *mem_ctx,
-                                           char **found_name)
+static NTSTATUS smb_full_audit_get_real_filename(
+       struct vfs_handle_struct *handle,
+       const struct smb_filename *path,
+       const char *name,
+       TALLOC_CTX *mem_ctx,
+       char **found_name)
 {
-       int result;
+       NTSTATUS result;
 
        result = SMB_VFS_NEXT_GET_REAL_FILENAME(handle, path, name, mem_ctx,
                                                found_name);
 
-       do_log(SMB_VFS_OP_GET_REAL_FILENAME, (result == 0), handle,
+       do_log(SMB_VFS_OP_GET_REAL_FILENAME,
+              NT_STATUS_IS_OK(result),
+              handle,
               "%s/%s->%s",
-              path->base_name, name, (result == 0) ? *found_name : "");
+              path->base_name,
+              name,
+              NT_STATUS_IS_OK(result) ? *found_name : "");
 
        return result;
 }
index 25b82bdd4719c7b02a4513d94ca0230dec353540..bce73094c54a577d5ee39d26dbc43de8b5690d6a 100644 (file)
@@ -2003,19 +2003,19 @@ static int vfs_gluster_fchflags(struct vfs_handle_struct *handle,
        return -1;
 }
 
-static int vfs_gluster_get_real_filename(struct vfs_handle_struct *handle,
-                                        const struct smb_filename *path,
-                                        const char *name,
-                                        TALLOC_CTX *mem_ctx,
-                                        char **found_name)
+static NTSTATUS vfs_gluster_get_real_filename(
+       struct vfs_handle_struct *handle,
+       const struct smb_filename *path,
+       const char *name,
+       TALLOC_CTX *mem_ctx,
+       char **found_name)
 {
        int ret;
        char key_buf[GLUSTER_NAME_MAX + 64];
        char val_buf[GLUSTER_NAME_MAX + 1];
 
        if (strlen(name) >= GLUSTER_NAME_MAX) {
-               errno = ENAMETOOLONG;
-               return -1;
+               return NT_STATUS_OBJECT_NAME_INVALID;
        }
 
        snprintf(key_buf, GLUSTER_NAME_MAX + 64,
@@ -2027,15 +2027,14 @@ static int vfs_gluster_get_real_filename(struct vfs_handle_struct *handle,
                if (errno == ENOATTR) {
                        errno = ENOENT;
                }
-               return -1;
+               return map_nt_error_from_unix(errno);
        }
 
        *found_name = talloc_strdup(mem_ctx, val_buf);
        if (found_name[0] == NULL) {
-               errno = ENOMEM;
-               return -1;
+               return NT_STATUS_NO_MEMORY;
        }
-       return 0;
+       return NT_STATUS_OK;
 }
 
 static const char *vfs_gluster_connectpath(struct vfs_handle_struct *handle,
index 1e07308e980513c8a73045e6811a2e0a46f13928..d4bef3fe834fed50e408f00f012b12ff71258cca 100644 (file)
 
 #define GLUSTER_NAME_MAX 255
 
-static int vfs_gluster_fuse_get_real_filename(struct vfs_handle_struct *handle,
-                                             const struct smb_filename *path,
-                                             const char *name,
-                                             TALLOC_CTX *mem_ctx,
-                                             char **_found_name)
+static NTSTATUS vfs_gluster_fuse_get_real_filename(
+       struct vfs_handle_struct *handle,
+       const struct smb_filename *path,
+       const char *name,
+       TALLOC_CTX *mem_ctx,
+       char **_found_name)
 {
        int ret;
        char key_buf[GLUSTER_NAME_MAX + 64];
@@ -35,8 +36,7 @@ static int vfs_gluster_fuse_get_real_filename(struct vfs_handle_struct *handle,
        char *found_name = NULL;
 
        if (strlen(name) >= GLUSTER_NAME_MAX) {
-               errno = ENAMETOOLONG;
-               return -1;
+               return NT_STATUS_OBJECT_NAME_INVALID;
        }
 
        snprintf(key_buf, GLUSTER_NAME_MAX + 64,
@@ -47,16 +47,15 @@ static int vfs_gluster_fuse_get_real_filename(struct vfs_handle_struct *handle,
                if (errno == ENOATTR) {
                        errno = ENOENT;
                }
-               return -1;
+               return map_nt_error_from_unix(errno);
        }
 
        found_name = talloc_strdup(mem_ctx, val_buf);
        if (found_name == NULL) {
-               errno = ENOMEM;
-               return -1;
+               return NT_STATUS_NO_MEMORY;
        }
        *_found_name = found_name;
-       return 0;
+       return NT_STATUS_OK;
 }
 
 struct device_mapping_entry {
index e336f8aec5d8afda2cb798e190382f2afd7c4408..1444d44bbb9441603429f806ead59a175ed155db 100644 (file)
@@ -288,11 +288,11 @@ static int vfs_gpfs_setlease(vfs_handle_struct *handle,
 }
 #endif /* HAVE_KERNEL_OPLOCKS_LINUX */
 
-static int vfs_gpfs_get_real_filename(struct vfs_handle_struct *handle,
-                                     const struct smb_filename *path,
-                                     const char *name,
-                                     TALLOC_CTX *mem_ctx,
-                                     char **found_name)
+static NTSTATUS vfs_gpfs_get_real_filename(struct vfs_handle_struct *handle,
+                                          const struct smb_filename *path,
+                                          const char *name,
+                                          TALLOC_CTX *mem_ctx,
+                                          char **found_name)
 {
        int result;
        char *full_path = NULL;
@@ -305,7 +305,7 @@ static int vfs_gpfs_get_real_filename(struct vfs_handle_struct *handle,
 
        SMB_VFS_HANDLE_GET_DATA(handle, config,
                                struct gpfs_config_data,
-                               return -1);
+                               return NT_STATUS_INTERNAL_ERROR);
 
        if (!config->getrealfilename) {
                return SMB_VFS_NEXT_GET_REAL_FILENAME(handle, path, name,
@@ -322,8 +322,7 @@ static int vfs_gpfs_get_real_filename(struct vfs_handle_struct *handle,
                                      tmpbuf, sizeof(tmpbuf),
                                      &full_path, &to_free);
        if (full_path_len == -1) {
-               errno = ENOMEM;
-               return -1;
+               return NT_STATUS_NO_MEMORY;
        }
 
        buflen = sizeof(real_pathname) - 1;
@@ -341,7 +340,7 @@ static int vfs_gpfs_get_real_filename(struct vfs_handle_struct *handle,
        if (result == -1) {
                DEBUG(10, ("smbd_gpfs_get_realfilename_path returned %s\n",
                           strerror(errno)));
-               return -1;
+               return map_nt_error_from_unix(errno);
        }
 
        /*
@@ -360,17 +359,15 @@ static int vfs_gpfs_get_real_filename(struct vfs_handle_struct *handle,
 
        name = strrchr_m(real_pathname, '/');
        if (name == NULL) {
-               errno = ENOENT;
-               return -1;
+               return NT_STATUS_OBJECT_NAME_NOT_FOUND;
        }
 
        *found_name = talloc_strdup(mem_ctx, name+1);
        if (*found_name == NULL) {
-               errno = ENOMEM;
-               return -1;
+               return NT_STATUS_NO_MEMORY;
        }
 
-       return 0;
+       return NT_STATUS_OK;
 }
 
 static void sd2gpfs_control(uint16_t control, struct gpfs_acl *gacl)
index 303f0a7c5cf6919fec46859232642ee1dc07ec1c..3b6b84cffd05891356a22e680392016fd136fd6f 100644 (file)
@@ -724,14 +724,14 @@ NTSTATUS vfs_not_implemented_fstreaminfo(struct vfs_handle_struct *handle,
 }
 
 _PUBLIC_
-int vfs_not_implemented_get_real_filename(struct vfs_handle_struct *handle,
-                                         const struct smb_filename *path,
-                                         const char *name,
-                                         TALLOC_CTX *mem_ctx,
-                                         char **found_name)
+NTSTATUS vfs_not_implemented_get_real_filename(
+       struct vfs_handle_struct *handle,
+       const struct smb_filename *path,
+       const char *name,
+       TALLOC_CTX *mem_ctx,
+       char **found_name)
 {
-       errno = ENOSYS;
-       return -1;
+       return NT_STATUS_NOT_IMPLEMENTED;
 }
 
 _PUBLIC_
index f08a813dac7c7ce1a2e0506877f8c652ca85656a..8f77b395d534817a346c3eecb8b4609513184fce 100644 (file)
@@ -2500,31 +2500,32 @@ static NTSTATUS shadow_copy2_read_dfs_pathat(struct vfs_handle_struct *handle,
        return status;
 }
 
-static int shadow_copy2_get_real_filename(struct vfs_handle_struct *handle,
-                                         const struct smb_filename *fname,
-                                         const char *name,
-                                         TALLOC_CTX *mem_ctx,
-                                         char **found_name)
+static NTSTATUS shadow_copy2_get_real_filename(
+       struct vfs_handle_struct *handle,
+       const struct smb_filename *fname,
+       const char *name,
+       TALLOC_CTX *mem_ctx,
+       char **found_name)
 {
        struct shadow_copy2_private *priv = NULL;
        struct shadow_copy2_config *config = NULL;
        time_t timestamp = 0;
        char *stripped = NULL;
-       ssize_t ret;
-       int saved_errno = 0;
        char *conv;
        struct smb_filename conv_fname;
+       NTSTATUS status;
 
        SMB_VFS_HANDLE_GET_DATA(handle, priv, struct shadow_copy2_private,
-                               return -1);
+                               return NT_STATUS_INTERNAL_ERROR);
        config = priv->config;
 
        DBG_DEBUG("Path=[%s] name=[%s]\n", smb_fname_str_dbg(fname), name);
 
        if (!shadow_copy2_strip_snapshot(talloc_tos(), handle, fname,
                                         &timestamp, &stripped)) {
+               status = map_nt_error_from_unix(errno);
                DEBUG(10, ("shadow_copy2_strip_snapshot failed\n"));
-               return -1;
+               return status;
        }
        if (timestamp == 0) {
                DEBUG(10, ("timestamp == 0\n"));
@@ -2542,9 +2543,11 @@ static int shadow_copy2_get_real_filename(struct vfs_handle_struct *handle,
 
        conv = shadow_copy2_convert(talloc_tos(), handle, stripped, timestamp);
        if (conv == NULL) {
+               status = map_nt_error_from_unix(errno);
+
                if (!config->snapdirseverywhere) {
                        DBG_DEBUG("shadow_copy2_convert [%s] failed\n", stripped);
-                       return -1;
+                       return status;
                }
 
                /*
@@ -2559,8 +2562,7 @@ static int shadow_copy2_get_real_filename(struct vfs_handle_struct *handle,
                DBG_DEBUG("Use stripped [%s] as conv\n", stripped);
                conv = talloc_strdup(talloc_tos(), stripped);
                if (conv == NULL) {
-                       TALLOC_FREE(stripped);
-                       return -1;
+                       return NT_STATUS_NO_MEMORY;
                }
        }
 
@@ -2570,37 +2572,34 @@ static int shadow_copy2_get_real_filename(struct vfs_handle_struct *handle,
 
        DEBUG(10, ("Calling NEXT_GET_REAL_FILE_NAME for conv=[%s], "
                   "name=[%s]\n", conv, name));
-       ret = SMB_VFS_NEXT_GET_REAL_FILENAME(handle, &conv_fname, name,
-                                            mem_ctx, found_name);
-       DEBUG(10, ("NEXT_REAL_FILE_NAME returned %d\n", (int)ret));
-       if (ret == 0) {
-               return 0;
+       status = SMB_VFS_NEXT_GET_REAL_FILENAME(
+               handle, &conv_fname, name, mem_ctx, found_name);
+       DEBUG(10, ("NEXT_REAL_FILE_NAME returned %s\n", nt_errstr(status)));
+       if (NT_STATUS_IS_OK(status)) {
+               return NT_STATUS_OK;
        }
-       if (errno != EOPNOTSUPP) {
+       if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
                TALLOC_FREE(conv);
-               errno = EOPNOTSUPP;
-               return -1;
+               return NT_STATUS_NOT_SUPPORTED;
        }
 
-       ret = get_real_filename_full_scan(handle->conn,
-                                         conv,
-                                         name,
-                                         false,
-                                         mem_ctx,
-                                         found_name);
-       if (ret != 0) {
-               saved_errno = errno;
+       status = get_real_filename_full_scan(handle->conn,
+                                            conv,
+                                            name,
+                                            false,
+                                            mem_ctx,
+                                            found_name);
+       if (!NT_STATUS_IS_OK(status)) {
                DBG_DEBUG("Scan [%s] for [%s] failed\n",
                          conv, name);
-               errno = saved_errno;
-               return -1;
+               return status;
        }
 
        DBG_DEBUG("Scan [%s] for [%s] returned [%s]\n",
                  conv, name, *found_name);
 
        TALLOC_FREE(conv);
-       return 0;
+       return NT_STATUS_OK;
 }
 
 static const char *shadow_copy2_connectpath(struct vfs_handle_struct *handle,
index 2c85f0c2c3a4d3c1d1c8ba1ea26bee1bedda5a3c..a0e3852681d0482155b1df40fd2fd01a42952c9e 100644 (file)
@@ -2433,22 +2433,22 @@ static int snapper_gmt_fsetxattr(struct vfs_handle_struct *handle,
                                aname, value, size, flags);
 }
 
-static int snapper_gmt_get_real_filename(struct vfs_handle_struct *handle,
-                                        const struct smb_filename *fpath,
-                                        const char *name,
-                                        TALLOC_CTX *mem_ctx,
-                                        char **found_name)
+static NTSTATUS snapper_gmt_get_real_filename(
+       struct vfs_handle_struct *handle,
+       const struct smb_filename *fpath,
+       const char *name,
+       TALLOC_CTX *mem_ctx,
+       char **found_name)
 {
        time_t timestamp;
        char *stripped;
-       ssize_t ret;
-       int saved_errno;
        char *conv;
        struct smb_filename conv_fname;
+       NTSTATUS status;
 
        if (!snapper_gmt_strip_snapshot(talloc_tos(), handle, fpath,
                                        &timestamp, &stripped)) {
-               return -1;
+               return NT_STATUS_NO_MEMORY;
        }
        if (timestamp == 0) {
                return SMB_VFS_NEXT_GET_REAL_FILENAME(handle, fpath, name,
@@ -2457,27 +2457,24 @@ static int snapper_gmt_get_real_filename(struct vfs_handle_struct *handle,
        if (stripped[0] == '\0') {
                *found_name = talloc_strdup(mem_ctx, name);
                if (*found_name == NULL) {
-                       errno = ENOMEM;
-                       return -1;
+                       return NT_STATUS_NO_MEMORY;
                }
-               return 0;
+               return NT_STATUS_OK;
        }
        conv = snapper_gmt_convert(talloc_tos(), handle, stripped, timestamp);
        TALLOC_FREE(stripped);
        if (conv == NULL) {
-               return -1;
+               return map_nt_error_from_unix(errno);
        }
 
        conv_fname = (struct smb_filename) {
                .base_name = conv,
        };
 
-       ret = SMB_VFS_NEXT_GET_REAL_FILENAME(handle, &conv_fname, name,
-                                            mem_ctx, found_name);
-       saved_errno = errno;
+       status = SMB_VFS_NEXT_GET_REAL_FILENAME(
+               handle, &conv_fname, name, mem_ctx, found_name);
        TALLOC_FREE(conv);
-       errno = saved_errno;
-       return ret;
+       return status;
 }
 
 static uint64_t snapper_gmt_disk_free(vfs_handle_struct *handle,
index 858900e4fbcd8b32e45ddf06f1c5120bddab1f94..6f133d29b547372319c881ac90089c910399addd 100644 (file)
@@ -1717,13 +1717,14 @@ static NTSTATUS smb_time_audit_fstreaminfo(vfs_handle_struct *handle,
        return result;
 }
 
-static int smb_time_audit_get_real_filename(struct vfs_handle_struct *handle,
-                                           const struct smb_filename *path,
-                                           const char *name,
-                                           TALLOC_CTX *mem_ctx,
-                                           char **found_name)
+static NTSTATUS smb_time_audit_get_real_filename(
+       struct vfs_handle_struct *handle,
+       const struct smb_filename *path,
+       const char *name,
+       TALLOC_CTX *mem_ctx,
+       char **found_name)
 {
-       int result;
+       NTSTATUS result;
        struct timespec ts1,ts2;
        double timediff;
 
index 431d4d72b5d80ae5da3194ca45a8bb5ebafdb9c0..d0d0ec2a43f9d3e3ad1d9dc2302f31f578faa072 100644 (file)
@@ -424,7 +424,7 @@ static char *dptr_ReadDirName(TALLOC_CTX *ctx,
        char *talloced = NULL;
        char *pathreal = NULL;
        char *found_name = NULL;
-       int ret;
+       NTSTATUS status;
 
        SET_STAT_INVALID(*pst);
 
@@ -499,15 +499,15 @@ static char *dptr_ReadDirName(TALLOC_CTX *ctx,
         * Try case-insensitive stat if the fs has the ability. This avoids
         * scanning the whole directory.
         */
-       ret = SMB_VFS_GET_REAL_FILENAME(dptr->conn,
-                                       dptr->smb_dname,
-                                       dptr->wcard,
-                                       ctx,
-                                       &found_name);
-       if (ret == 0) {
+       status = SMB_VFS_GET_REAL_FILENAME(dptr->conn,
+                                          dptr->smb_dname,
+                                          dptr->wcard,
+                                          ctx,
+                                          &found_name);
+       if (NT_STATUS_IS_OK(status)) {
                name = found_name;
                goto clean;
-       } else if (errno == ENOENT) {
+       } else if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
                /* The case-insensitive lookup was authoritative. */
                goto clean;
        }
index 84548dce21d13424670b77c7a4f7ed1a9248468f..fb86e84683ee8fadcc1772b2af79d69482b04d42 100644 (file)
 #include "smbd/smbd.h"
 #include "smbd/globals.h"
 
-static int get_real_filename(connection_struct *conn,
-                            struct smb_filename *path,
-                            const char *name,
-                            TALLOC_CTX *mem_ctx,
-                            char **found_name);
+static NTSTATUS get_real_filename(connection_struct *conn,
+                                 struct smb_filename *path,
+                                 const char *name,
+                                 TALLOC_CTX *mem_ctx,
+                                 char **found_name);
 
 static NTSTATUS check_name(connection_struct *conn,
                           const struct smb_filename *smb_fname);
@@ -508,7 +508,8 @@ struct uc_state {
        bool short_case_preserve;
 };
 
-static NTSTATUS unix_convert_step_search_fail(struct uc_state *state)
+static NTSTATUS unix_convert_step_search_fail(
+       struct uc_state *state, NTSTATUS status)
 {
        char *unmangled;
 
@@ -536,14 +537,12 @@ static NTSTATUS unix_convert_step_search_fail(struct uc_state *state)
                 * to NT_STATUS_OBJECT_PATH_NOT_FOUND
                 * in the filename walk.
                 */
-
-               if (errno == ENOENT ||
-                   errno == ENOTDIR ||
-                   errno == ELOOP)
-               {
-                       return NT_STATUS_OBJECT_PATH_NOT_FOUND;
+               if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) ||
+                   NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK) ||
+                   NT_STATUS_EQUAL(status, NT_STATUS_NOT_A_DIRECTORY)) {
+                       status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
                }
-               return map_nt_error_from_unix(errno);
+               return status;
        }
 
        /*
@@ -551,7 +550,7 @@ static NTSTATUS unix_convert_step_search_fail(struct uc_state *state)
         * here.
         */
 
-       if (errno == EACCES) {
+       if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
                if ((state->ucf_flags & UCF_PREP_CREATEFILE) == 0) {
                        /*
                         * Could be a symlink pointing to
@@ -563,7 +562,6 @@ static NTSTATUS unix_convert_step_search_fail(struct uc_state *state)
                         * error out of filename_convert().
                         */
                        int ret;
-                       NTSTATUS status;
                        struct smb_filename dname = (struct smb_filename) {
                                        .base_name = state->dirpath,
                                        .twrp = state->smb_fname->twrp,
@@ -599,20 +597,22 @@ static NTSTATUS unix_convert_step_search_fail(struct uc_state *state)
                         * nevertheless want to allow
                         * users creating a file.
                         */
-                       errno = 0;
+                       status = NT_STATUS_OK;
                }
        }
 
-       if ((errno != 0) && (errno != ENOENT)) {
+       if (!NT_STATUS_IS_OK(status) &&
+           !NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
                /*
                 * ENOTDIR and ELOOP both map to
                 * NT_STATUS_OBJECT_PATH_NOT_FOUND
                 * in the filename walk.
                 */
-               if (errno == ENOTDIR || errno == ELOOP) {
-                       return NT_STATUS_OBJECT_PATH_NOT_FOUND;
+               if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_A_DIRECTORY) ||
+                   NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) {
+                       status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
                }
-               return map_nt_error_from_unix(errno);
+               return status;
        }
 
        /*
@@ -688,6 +688,7 @@ static NTSTATUS unix_convert_step_stat(struct uc_state *state)
        char dot[2] = ".";
        char *found_name = NULL;
        int ret;
+       NTSTATUS status;
 
        /*
         * Check if the name exists up to this point.
@@ -787,13 +788,13 @@ static NTSTATUS unix_convert_step_stat(struct uc_state *state)
                dname.base_name = dot;
        }
 
-       ret = get_real_filename(state->conn,
-                               &dname,
-                               state->name,
-                               talloc_tos(),
-                               &found_name);
-       if (ret != 0) {
-               return unix_convert_step_search_fail(state);
+       status = get_real_filename(state->conn,
+                                  &dname,
+                                  state->name,
+                                  talloc_tos(),
+                                  &found_name);
+       if (!NT_STATUS_IS_OK(status)) {
+               return unix_convert_step_search_fail(state, status);
        }
 
        /*
@@ -1540,12 +1541,12 @@ static bool sname_equal(const char *name1, const char *name2,
  If the name looks like a mangled name then try via the mangling functions
 ****************************************************************************/
 
-int get_real_filename_full_scan(connection_struct *conn,
-                               const char *path,
-                               const char *name,
-                               bool mangled,
-                               TALLOC_CTX *mem_ctx,
-                               char **found_name)
+NTSTATUS get_real_filename_full_scan(connection_struct *conn,
+                                    const char *path,
+                                    const char *name,
+                                    bool mangled,
+                                    TALLOC_CTX *mem_ctx,
+                                    char **found_name)
 {
        struct smb_Dir *cur_dir = NULL;
        const char *dname = NULL;
@@ -1565,8 +1566,7 @@ int get_real_filename_full_scan(connection_struct *conn,
         * there, then the original stat(2) would have found it.
         */
        if (!mangled && !(conn->fs_capabilities & FILE_CASE_SENSITIVE_SEARCH)) {
-               errno = ENOENT;
-               return -1;
+               return NT_STATUS_OBJECT_NAME_NOT_FOUND;
        }
 
        /*
@@ -1602,7 +1602,7 @@ int get_real_filename_full_scan(connection_struct *conn,
                                        0);
        if (smb_fname == NULL) {
                TALLOC_FREE(unmangled_name);
-               return -1;
+               return NT_STATUS_NO_MEMORY;
        }
 
        /* open the directory */
@@ -1614,8 +1614,7 @@ int get_real_filename_full_scan(connection_struct *conn,
                           nt_errstr(status));
                TALLOC_FREE(unmangled_name);
                TALLOC_FREE(smb_fname);
-               errno = map_errno_from_nt_status(status);
-               return -1;
+               return status;
        }
 
        TALLOC_FREE(smb_fname);
@@ -1648,20 +1647,18 @@ int get_real_filename_full_scan(connection_struct *conn,
                        TALLOC_FREE(unmangled_name);
                        TALLOC_FREE(cur_dir);
                        if (!*found_name) {
-                               errno = ENOMEM;
                                TALLOC_FREE(talloced);
-                               return -1;
+                               return NT_STATUS_NO_MEMORY;
                        }
                        TALLOC_FREE(talloced);
-                       return 0;
+                       return NT_STATUS_OK;
                }
                TALLOC_FREE(talloced);
        }
 
        TALLOC_FREE(unmangled_name);
        TALLOC_FREE(cur_dir);
-       errno = ENOENT;
-       return -1;
+       return NT_STATUS_OBJECT_NAME_NOT_FOUND;
 }
 
 /****************************************************************************
@@ -1669,13 +1666,13 @@ int get_real_filename_full_scan(connection_struct *conn,
  fallback.
 ****************************************************************************/
 
-static int get_real_filename(connection_struct *conn,
-                            struct smb_filename *path,
-                            const char *name,
-                            TALLOC_CTX *mem_ctx,
-                            char **found_name)
+static NTSTATUS get_real_filename(connection_struct *conn,
+                                 struct smb_filename *path,
+                                 const char *name,
+                                 TALLOC_CTX *mem_ctx,
+                                 char **found_name)
 {
-       int ret;
+       NTSTATUS status;
        bool mangled;
 
        mangled = mangle_is_mangled(name, conn->params);
@@ -1690,19 +1687,20 @@ static int get_real_filename(connection_struct *conn,
        }
 
        /* Try the vfs first to take advantage of case-insensitive stat. */
-       ret = SMB_VFS_GET_REAL_FILENAME(conn,
-                                       path,
-                                       name,
-                                       mem_ctx,
-                                       found_name);
+       status = SMB_VFS_GET_REAL_FILENAME(conn,
+                                          path,
+                                          name,
+                                          mem_ctx,
+                                          found_name);
 
        /*
         * If the case-insensitive stat was successful, or returned an error
         * other than EOPNOTSUPP then there is no need to fall back on the
         * full directory scan.
         */
-       if (ret == 0 || (ret == -1 && errno != EOPNOTSUPP)) {
-               return ret;
+       if (NT_STATUS_IS_OK(status) ||
+           !NT_STATUS_EQUAL(status, NT_STATUS_NOT_SUPPORTED)) {
+               return status;
        }
 
        return get_real_filename_full_scan(conn,
index 5661fdfbf26bb34314369b942743bad15429f734..1b7e2015cac1875dffd5110a383bf840726c581d 100644 (file)
@@ -364,12 +364,12 @@ NTSTATUS unix_convert(TALLOC_CTX *ctx,
 NTSTATUS canonicalize_snapshot_path(struct smb_filename *smb_fname,
                                    uint32_t ucf_flags,
                                    NTTIME twrp);
-int get_real_filename_full_scan(connection_struct *conn,
-                               const char *path,
-                               const char *name,
-                               bool mangled,
-                               TALLOC_CTX *mem_ctx,
-                               char **found_name);
+NTSTATUS get_real_filename_full_scan(connection_struct *conn,
+                                    const char *path,
+                                    const char *name,
+                                    bool mangled,
+                                    TALLOC_CTX *mem_ctx,
+                                    char **found_name);
 char *get_original_lcomp(TALLOC_CTX *ctx,
                        connection_struct *conn,
                        const char *filename_in,
index 208beaff80730d9c337755139f36c7e705eb780d..5e8c5505905cfa5936a2035b42e7a4c0b28cc402 100644 (file)
@@ -2261,11 +2261,11 @@ NTSTATUS smb_vfs_call_fstreaminfo(struct vfs_handle_struct *handle,
                                          num_streams, streams);
 }
 
-int smb_vfs_call_get_real_filename(struct vfs_handle_struct *handle,
-                                  const struct smb_filename *path,
-                                  const char *name,
-                                  TALLOC_CTX *mem_ctx,
-                                  char **found_name)
+NTSTATUS smb_vfs_call_get_real_filename(struct vfs_handle_struct *handle,
+                                       const struct smb_filename *path,
+                                       const char *name,
+                                       TALLOC_CTX *mem_ctx,
+                                       char **found_name)
 {
        VFS_FIND(get_real_filename);
        return handle->fns->get_real_filename_fn(handle, path, name, mem_ctx,