]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
smbd: Make read_symlink_reparse() return a reparse_data_buffer
authorVolker Lendecke <vl@samba.org>
Sun, 4 Feb 2024 15:07:22 +0000 (16:07 +0100)
committerAndreas Schneider <asn@cryptomilk.org>
Thu, 28 Mar 2024 08:05:35 +0000 (08:05 +0000)
Will make generalized handling of reparse point error returns easier
once we will also allow creating symlink reparse point files over smb.

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
source3/smbd/filename.c
source3/smbd/files.c
source3/smbd/proto.h

index f80f67c12910d70025f02679b68adc149771de41..b542d2fcf6f5f59e62a7b9f4658d88a726b97fdf 100644 (file)
@@ -1127,6 +1127,7 @@ NTSTATUS filename_convert_dirfsp(
        struct smb_filename **_smb_fname)
 {
        struct open_symlink_err *symlink_err = NULL;
+       struct symlink_reparse_struct *lnk = NULL;
        NTSTATUS status;
        char *target = NULL;
        char *safe_target = NULL;
@@ -1161,13 +1162,14 @@ next:
        if (!NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) {
                return status;
        }
+       lnk = &symlink_err->reparse->parsed.lnk;
 
        /*
         * If we're on an MSDFS share, see if this is
         * an MSDFS link.
         */
        if (lp_host_msdfs() && lp_msdfs_root(SNUM(conn)) &&
-           strnequal(symlink_err->reparse->substitute_name, "msdfs:", 6))
+           strnequal(lnk->substitute_name, "msdfs:", 6))
        {
                TALLOC_FREE(*_smb_fname);
                TALLOC_FREE(symlink_err);
@@ -1196,7 +1198,7 @@ next:
 
        target = symlink_target_path(mem_ctx,
                                     name_in,
-                                    symlink_err->reparse->substitute_name,
+                                    lnk->substitute_name,
                                     symlink_err->unparsed);
        if (target == NULL) {
                return NT_STATUS_NO_MEMORY;
index ca929cc94a12f71168c54f797fab804997ce4c8c..f4548e417251a40279ce7b35e6b93c5908ff8fcc 100644 (file)
@@ -733,28 +733,34 @@ NTSTATUS readlink_talloc(
        return NT_STATUS_OK;
 }
 
-NTSTATUS read_symlink_reparse(
-       TALLOC_CTX *mem_ctx,
-       struct files_struct *dirfsp,
-       struct smb_filename *smb_relname,
-       struct symlink_reparse_struct **_symlink)
+NTSTATUS read_symlink_reparse(TALLOC_CTX *mem_ctx,
+                             struct files_struct *dirfsp,
+                             struct smb_filename *smb_relname,
+                             struct reparse_data_buffer **_reparse)
 {
-       struct symlink_reparse_struct *symlink = NULL;
+       struct reparse_data_buffer *reparse = NULL;
+       struct symlink_reparse_struct *lnk = NULL;
        NTSTATUS status;
 
-       symlink = talloc_zero(mem_ctx, struct symlink_reparse_struct);
-       if (symlink == NULL) {
+       reparse = talloc_zero(mem_ctx, struct reparse_data_buffer);
+       if (reparse == NULL) {
                goto nomem;
        }
+       *reparse = (struct reparse_data_buffer){
+               .tag = IO_REPARSE_TAG_SYMLINK,
+       };
+       lnk = &reparse->parsed.lnk;
 
-       status = readlink_talloc(
-               symlink, dirfsp, smb_relname, &symlink->substitute_name);
+       status = readlink_talloc(reparse,
+                                dirfsp,
+                                smb_relname,
+                                &lnk->substitute_name);
        if (!NT_STATUS_IS_OK(status)) {
                DBG_DEBUG("readlink_talloc failed: %s\n", nt_errstr(status));
                goto fail;
        }
 
-       if (symlink->substitute_name[0] == '/') {
+       if (lnk->substitute_name[0] == '/') {
                char *subdir_path = NULL;
                char *abs_target_canon = NULL;
                const char *relative = NULL;
@@ -768,9 +774,8 @@ NTSTATUS read_symlink_reparse(
                        goto nomem;
                }
 
-               abs_target_canon =
-                       canonicalize_absolute_path(talloc_tos(),
-                                                  symlink->substitute_name);
+               abs_target_canon = canonicalize_absolute_path(
+                       talloc_tos(), lnk->substitute_name);
                if (abs_target_canon == NULL) {
                        goto nomem;
                }
@@ -780,25 +785,25 @@ NTSTATUS read_symlink_reparse(
                                     abs_target_canon,
                                     &relative);
                if (in_share) {
-                       TALLOC_FREE(symlink->substitute_name);
-                       symlink->substitute_name =
-                               talloc_strdup(symlink, relative);
-                       if (symlink->substitute_name == NULL) {
+                       TALLOC_FREE(lnk->substitute_name);
+                       lnk->substitute_name = talloc_strdup(reparse,
+                                                            relative);
+                       if (lnk->substitute_name == NULL) {
                                goto nomem;
                        }
                }
        }
 
-       if (!IS_DIRECTORY_SEP(symlink->substitute_name[0])) {
-               symlink->flags |= SYMLINK_FLAG_RELATIVE;
+       if (!IS_DIRECTORY_SEP(lnk->substitute_name[0])) {
+               lnk->flags |= SYMLINK_FLAG_RELATIVE;
        }
 
-       *_symlink = symlink;
+       *_reparse = reparse;
        return NT_STATUS_OK;
 nomem:
        status = NT_STATUS_NO_MEMORY;
 fail:
-       TALLOC_FREE(symlink);
+       TALLOC_FREE(reparse);
        return status;
 }
 
index e2b7ddc3e64e63196b8be8836868c8a2dbe27c30..364676347cdc4b971178b18f32e9b0883debc8da 100644 (file)
@@ -377,12 +377,10 @@ NTSTATUS open_stream_pathref_fsp(
        struct files_struct **_base_fsp,
        struct smb_filename *smb_fname);
 
-struct symlink_reparse_struct;
-
 struct open_symlink_err {
        struct stat_ex st;
        size_t unparsed;
-       struct symlink_reparse_struct *reparse;
+       struct reparse_data_buffer *reparse;
 };
 
 NTSTATUS create_open_symlink_err(TALLOC_CTX *mem_ctx,
@@ -407,13 +405,12 @@ NTSTATUS readlink_talloc(
        struct smb_filename *smb_relname,
        char **_substitute);
 
-struct symlink_reparse_struct;
+struct reparse_data_buffer;
 
-NTSTATUS read_symlink_reparse(
-       TALLOC_CTX *mem_ctx,
-       struct files_struct *dirfsp,
-       struct smb_filename *smb_relname,
-       struct symlink_reparse_struct **_symlink);
+NTSTATUS read_symlink_reparse(TALLOC_CTX *mem_ctx,
+                             struct files_struct *dirfsp,
+                             struct smb_filename *smb_relname,
+                             struct reparse_data_buffer **_reparse);
 
 void smb_fname_fsp_unlink(struct smb_filename *smb_fname);