From 5c55cd93e5bd1481e88edd4fa0c76f4679bdfcc6 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 3 Dec 2021 16:14:08 -0800 Subject: 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 --- source3/smbd/filename.c | 11 +++++++++-- source3/smbd/msdfs.c | 3 ++- source3/smbd/proto.h | 1 + 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; -- cgit v1.2.1