From: Jeremy Allison Date: Tue, 13 Jul 2021 00:56:13 +0000 (-0700) Subject: s3: smbd: In dfs_path_lookup(), use relative dirfsp, atname lookups in SMB_VFS_READ_D... X-Git-Tag: talloc-2.3.3~54 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=1538b44d942091d14f6b8f554d249bf98fd06b5e;p=thirdparty%2Fsamba.git s3: smbd: In dfs_path_lookup(), use relative dirfsp, atname lookups in SMB_VFS_READ_DFS_PATHAT() for the pathname walk fallback. 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 Reviewed-by: Ralph Boehme --- diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c index cb40e0ce55f..45b6478985d 100644 --- a/source3/smbd/msdfs.c +++ b/source3/smbd/msdfs.c @@ -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; }