]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3: smbd: In dfs_path_lookup(), use relative dirfsp, atname lookups in SMB_VFS_READ_D...
authorJeremy Allison <jra@samba.org>
Tue, 13 Jul 2021 00:56:13 +0000 (17:56 -0700)
committerRalph Boehme <slow@samba.org>
Wed, 14 Jul 2021 08:09:31 +0000 (08:09 +0000)
Note that parent_pathref() must succeed before we call SMB_VFS_READ_DFS_PATHAT().
If parent_pathref() fails, just step back a component without calling
SMB_VFS_READ_DFS_PATHAT().

There are no longer any non-relative uses of SMB_VFS_READ_DFS_PATHAT().

Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
source3/smbd/msdfs.c

index cb40e0ce55f34d8205fe2c100e74b2aa1dd44a3d..45b6478985d4781a6d28e99ebb091815d96cae2c 100644 (file)
@@ -818,29 +818,48 @@ static NTSTATUS dfs_path_lookup(TALLOC_CTX *ctx,
                        *q = '\0';
                }
 
-               status = SMB_VFS_READ_DFS_PATHAT(conn,
-                                       ctx,
+               /*
+                * Ensure parent_pathref() calls vfs_stat() on
+                * the newly truncated path.
+                */
+               SET_STAT_INVALID(smb_fname->st);
+               status = parent_pathref(ctx,
                                        conn->cwd_fsp,
                                        smb_fname,
-                                       ppreflist,
-                                       preferral_count);
-
+                                       &parent_fname,
+                                       &atname);
                if (NT_STATUS_IS_OK(status)) {
-                       DBG_INFO("Redirecting %s because "
-                               "parent %s is a dfs link\n",
-                               dfspath,
-                               smb_fname_str_dbg(smb_fname));
-
-                       if (consumedcntp) {
-                               *consumedcntp = strlen(canon_dfspath);
-                               DEBUG(10, ("dfs_path_lookup: Path consumed: %s "
-                                       "(%d)\n",
-                                       canon_dfspath,
-                                       *consumedcntp));
+                       /*
+                        * We must have a parent_fname->fsp before
+                        * we can call SMB_VFS_READ_DFS_PATHAT().
+                        */
+                       status = SMB_VFS_READ_DFS_PATHAT(conn,
+                                                        ctx,
+                                                        parent_fname->fsp,
+                                                        atname,
+                                                        ppreflist,
+                                                        preferral_count);
+
+                       /* We're now done with parent_fname and atname. */
+                       TALLOC_FREE(parent_fname);
+
+                       if (NT_STATUS_IS_OK(status)) {
+                               DBG_INFO("Redirecting %s because "
+                                        "parent %s is a dfs link\n",
+                                        dfspath,
+                                        smb_fname_str_dbg(smb_fname));
+
+                               if (consumedcntp) {
+                                       *consumedcntp = strlen(canon_dfspath);
+                                       DBG_DEBUG("Path consumed: %s "
+                                                 "(%d)\n",
+                                                 canon_dfspath,
+                                                 *consumedcntp);
+                               }
+
+                               status = NT_STATUS_PATH_NOT_COVERED;
+                               goto out;
                        }
-
-                       status = NT_STATUS_PATH_NOT_COVERED;
-                       goto out;
                }
 
                /* Step back on the filesystem. */
@@ -855,6 +874,8 @@ static NTSTATUS dfs_path_lookup(TALLOC_CTX *ctx,
        status = NT_STATUS_OK;
  out:
 
+       /* This should already be free, but make sure. */
+       TALLOC_FREE(parent_fname);
        TALLOC_FREE(smb_fname);
        return status;
 }