]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
smbd: pass symlink target path to safe_symlink_target_path()
authorRalph Boehme <slow@samba.org>
Tue, 2 Jan 2024 11:49:14 +0000 (12:49 +0100)
committerJule Anger <janger@samba.org>
Mon, 29 Jan 2024 10:46:17 +0000 (10:46 +0000)
Moves processing the symlink error response to the caller
filename_convert_dirfsp(). Prepares for using this in
non_widelink_open(), where it will replace symlink_target_below_conn()
with the same functionality.

BUG: https://bugzilla.samba.org/show_bug.cgi?id=15549

Signed-off-by: Ralph Boehme <slow@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
(back-ported from commit 0515dded4ddb49e5570ae7df51126af1a2d643de)

source3/include/proto.h
source3/smbd/filename.c

index 8eed81d8f2e9ef7481e05a33b0dafe8b8da31b93..13240033bf16c1503ae7d917448653cd8ae14389 100644 (file)
@@ -719,6 +719,11 @@ struct smb_filename *synthetic_smb_fname(TALLOC_CTX *mem_ctx,
                                         const SMB_STRUCT_STAT *psbuf,
                                         NTTIME twrp,
                                         uint32_t flags);
+NTSTATUS safe_symlink_target_path(TALLOC_CTX *mem_ctx,
+                                 const char *connectpath,
+                                 const char *target,
+                                 size_t unparsed,
+                                 char **_relative);
 NTSTATUS filename_convert_dirfsp(
        TALLOC_CTX *ctx,
        connection_struct *conn,
index 8693dcf1153caab1be58a0982d9498004c414e04..45fb90381e262d1e621d84d974979c3aef5d271e 100644 (file)
@@ -942,44 +942,34 @@ static char *symlink_target_path(
        return ret;
 }
 
-static NTSTATUS safe_symlink_target_path(
-       TALLOC_CTX *mem_ctx,
-       const char *connectpath,
-       const char *name_in,
-       const char *substitute,
-       size_t unparsed,
-       char **_name_out)
+NTSTATUS safe_symlink_target_path(TALLOC_CTX *mem_ctx,
+                                 const char *connectpath,
+                                 const char *target,
+                                 size_t unparsed,
+                                 char **_relative)
 {
-       char *target = NULL;
        char *abs_target = NULL;
        char *abs_target_canon = NULL;
        const char *relative = NULL;
-       char *name_out = NULL;
-       NTSTATUS status = NT_STATUS_NO_MEMORY;
        bool in_share;
+       NTSTATUS status = NT_STATUS_NO_MEMORY;
 
-       target = symlink_target_path(mem_ctx, name_in, substitute, unparsed);
-       if (target == NULL) {
-               goto fail;
-       }
-
-       DBG_DEBUG("name_in: %s, substitute: %s, unparsed: %zu, target=%s\n",
-                 name_in,
-                 substitute,
-                 unparsed,
-                 target);
+       DBG_DEBUG("connectpath [%s] target [%s] unparsed [%zu]\n",
+                 connectpath, target, unparsed);
 
        if (target[0] == '/') {
-               abs_target = target;
+               abs_target = talloc_strdup(mem_ctx, target);
        } else {
-               abs_target = talloc_asprintf(
-                       target, "%s/%s", connectpath, target);
-               if (abs_target == NULL) {
-                       goto fail;
-               }
+               abs_target = talloc_asprintf(mem_ctx,
+                                            "%s/%s",
+                                            connectpath,
+                                            target);
+       }
+       if (abs_target == NULL) {
+               goto fail;
        }
 
-       abs_target_canon = canonicalize_absolute_path(target, abs_target);
+       abs_target_canon = canonicalize_absolute_path(abs_target, abs_target);
        if (abs_target_canon == NULL) {
                goto fail;
        }
@@ -994,15 +984,14 @@ static NTSTATUS safe_symlink_target_path(
                goto fail;
        }
 
-       name_out = talloc_strdup(mem_ctx, relative);
-       if (name_out == NULL) {
+       *_relative = talloc_strdup(mem_ctx, relative);
+       if (*_relative == NULL) {
                goto fail;
        }
 
        status = NT_STATUS_OK;
-       *_name_out = name_out;
 fail:
-       TALLOC_FREE(target);
+       TALLOC_FREE(abs_target);
        return status;
 }
 
@@ -1438,6 +1427,7 @@ NTSTATUS filename_convert_dirfsp(
        size_t unparsed = 0;
        NTSTATUS status;
        char *target = NULL;
+       char *safe_target = NULL;
        size_t symlink_redirects = 0;
 
 next:
@@ -1476,17 +1466,21 @@ next:
         * resolve all symlinks locally.
         */
 
-       status = safe_symlink_target_path(
-               mem_ctx,
-               conn->connectpath,
-               name_in,
-               substitute,
-               unparsed,
-               &target);
+       target = symlink_target_path(mem_ctx, name_in, substitute, unparsed);
+       if (target == NULL) {
+               return NT_STATUS_NO_MEMORY;
+       }
+
+       status = safe_symlink_target_path(mem_ctx,
+                                         conn->connectpath,
+                                         target,
+                                         unparsed,
+                                         &safe_target);
+       TALLOC_FREE(target);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
-       name_in = target;
+       name_in = safe_target;
 
        symlink_redirects += 1;