From beb10e8bbe4909b6bcc70da89c11560e04e483e9 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 29 Jul 2022 14:07:50 -0700 Subject: [PATCH] s3: smbd: In reply_ntrename(), don't call filename_convert() if we know it's a stream rename. There is no point in calling filename_convert() on a raw stream name. It can never find the file anyway (and never returns a valid smb_fname->fsp). Use the same logic as SMB2_FILE_RENAME_INFORMATION_INTERNAL now does and generate smb_fname_new directly. Signed-off-by: Jeremy Allison Reviewed-by: Volker Lendecke --- source3/smbd/smb1_nttrans.c | 53 ++++++++++++++++++++++--------------- 1 file changed, 31 insertions(+), 22 deletions(-) diff --git a/source3/smbd/smb1_nttrans.c b/source3/smbd/smb1_nttrans.c index acb09fb7650..4de7cd45d4e 100644 --- a/source3/smbd/smb1_nttrans.c +++ b/source3/smbd/smb1_nttrans.c @@ -1491,30 +1491,39 @@ void reply_ntrename(struct smb_request *req) goto out; } - status = filename_convert(ctx, conn, - newname, - ucf_flags_dst, - 0, - &smb_fname_new); - if (!NT_STATUS_IS_OK(status)) { - if (NT_STATUS_EQUAL(status, - NT_STATUS_PATH_NOT_COVERED)) { - reply_botherror(req, - NT_STATUS_PATH_NOT_COVERED, - ERRSRV, ERRbadpath); + if (stream_rename) { + /* + * No point in calling filename_convert() + * on a raw stream name. It can never find + * the file anyway. Use the same logic as + * SMB2_FILE_RENAME_INFORMATION_INTERNAL + * and generate smb_fname_new directly. + */ + smb_fname_new = synthetic_smb_fname(talloc_tos(), + smb_fname_old->base_name, + newname, + NULL, + smb_fname_old->twrp, + smb_fname_old->flags); + if (smb_fname_new == NULL) { + reply_nterror(req, NT_STATUS_NO_MEMORY); goto out; } - reply_nterror(req, status); - goto out; - } - - if (stream_rename) { - /* smb_fname_new must be the same as smb_fname_old. */ - TALLOC_FREE(smb_fname_new->base_name); - smb_fname_new->base_name = talloc_strdup(smb_fname_new, - smb_fname_old->base_name); - if (!smb_fname_new->base_name) { - reply_nterror(req, NT_STATUS_NO_MEMORY); + } else { + status = filename_convert(ctx, conn, + newname, + ucf_flags_dst, + 0, + &smb_fname_new); + if (!NT_STATUS_IS_OK(status)) { + if (NT_STATUS_EQUAL(status, + NT_STATUS_PATH_NOT_COVERED)) { + reply_botherror(req, + NT_STATUS_PATH_NOT_COVERED, + ERRSRV, ERRbadpath); + goto out; + } + reply_nterror(req, status); goto out; } }