summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2021-12-03 16:14:08 -0800
committerJule Anger <janger@samba.org>2022-01-31 12:23:52 +0100
commit5c55cd93e5bd1481e88edd4fa0c76f4679bdfcc6 (patch)
tree021ae2c54bf262fc83f16cf438d08d90e87b280e
parent3490db2a38981b10ad165d9815ff026ad1b8513d (diff)
downloadsamba-5c55cd93e5bd1481e88edd4fa0c76f4679bdfcc6.tar.gz
CVE-2021-44141: s3: smbd: Allow dfs_redirect() to return a TWRP token it got from a parsed pathname.
This one is subtle. If an SMB1 request has both a DFS path and a @GMT token, the unix_convert() inside the DFS path processing will remove the @GMT token, not allowing the subsequent unix_convert() inside filename_convert() to see it. By returning it from dfs_redirect() we can ensure it's correctly added to the smb_filename returned from filename_convert(). BUG: https://bugzilla.samba.org/show_bug.cgi?id=14911 Signed-off-by: Jeremy Allison <jra@samba.org>
-rw-r--r--source3/smbd/filename.c11
-rw-r--r--source3/smbd/msdfs.c3
-rw-r--r--source3/smbd/proto.h1
3 files changed, 12 insertions, 3 deletions
diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c
index 2c4fa5506ff..bcbe9f70015 100644
--- a/source3/smbd/filename.c
+++ b/source3/smbd/filename.c
@@ -1824,6 +1824,7 @@ char *get_original_lcomp(TALLOC_CTX *ctx,
char *last_slash = NULL;
char *orig_lcomp;
char *fname = NULL;
+ NTTIME twrp = 0;
NTSTATUS status;
if (ucf_flags & UCF_DFS_PATHNAME) {
@@ -1832,6 +1833,7 @@ char *get_original_lcomp(TALLOC_CTX *ctx,
filename_in,
ucf_flags,
!conn->sconn->using_smb2,
+ &twrp,
&fname);
if (!NT_STATUS_IS_OK(status)) {
DBG_DEBUG("dfs_redirect "
@@ -1860,7 +1862,7 @@ char *get_original_lcomp(TALLOC_CTX *ctx,
filename_in,
NULL,
NULL,
- 0,
+ twrp,
0);
if (smb_fname == NULL) {
TALLOC_FREE(fname);
@@ -1868,7 +1870,7 @@ char *get_original_lcomp(TALLOC_CTX *ctx,
}
status = canonicalize_snapshot_path(smb_fname,
ucf_flags,
- 0);
+ twrp);
if (!NT_STATUS_IS_OK(status)) {
TALLOC_FREE(fname);
TALLOC_FREE(smb_fname);
@@ -1928,10 +1930,12 @@ NTSTATUS filename_convert(TALLOC_CTX *ctx,
if (ucf_flags & UCF_DFS_PATHNAME) {
char *fname = NULL;
+ NTTIME dfs_twrp = 0;
status = dfs_redirect(ctx, conn,
name_in,
ucf_flags,
!conn->sconn->using_smb2,
+ &dfs_twrp,
&fname);
if (!NT_STATUS_IS_OK(status)) {
DBG_DEBUG("dfs_redirect "
@@ -1942,6 +1946,9 @@ NTSTATUS filename_convert(TALLOC_CTX *ctx,
}
name_in = fname;
ucf_flags &= ~UCF_DFS_PATHNAME;
+ if (twrp == 0 && dfs_twrp != 0) {
+ twrp = dfs_twrp;
+ }
}
if (is_fake_file_path(name_in)) {
diff --git a/source3/smbd/msdfs.c b/source3/smbd/msdfs.c
index 86ca79a994b..07636592016 100644
--- a/source3/smbd/msdfs.c
+++ b/source3/smbd/msdfs.c
@@ -901,6 +901,7 @@ NTSTATUS dfs_redirect(TALLOC_CTX *ctx,
const char *path_in,
uint32_t ucf_flags,
bool allow_broken_path,
+ NTTIME *_twrp,
char **pp_path_out)
{
const struct loadparm_substitution *lp_sub =
@@ -970,7 +971,7 @@ NTSTATUS dfs_redirect(TALLOC_CTX *ctx,
path_in,
pdp,
ucf_flags,
- NULL, /* twrp. */
+ _twrp, /* twrp. */
NULL, /* int *consumedcntp */
NULL, /* struct referral **ppreflist */
NULL); /* size_t *preferral_count */
diff --git a/source3/smbd/proto.h b/source3/smbd/proto.h
index 5e7bc392b87..c1db119633e 100644
--- a/source3/smbd/proto.h
+++ b/source3/smbd/proto.h
@@ -567,6 +567,7 @@ NTSTATUS dfs_redirect(TALLOC_CTX *ctx,
const char *name_in,
uint32_t ucf_flags,
bool allow_broken_path,
+ NTTIME *twrp,
char **pp_name_out);
struct connection_struct;
struct smb_filename;