s3: smbd: In reply_ntrename(), don't call filename_convert() if we know it's a stream...
authorJeremy Allison <jra@samba.org>
Fri, 29 Jul 2022 21:07:50 +0000 (14:07 -0700)
committerJeremy Allison <jra@samba.org>
Tue, 2 Aug 2022 19:49:32 +0000 (19:49 +0000)
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 <jra@samba.org>
Reviewed-by: Volker Lendecke <vl@samba.org>
source3/smbd/smb1_nttrans.c

index acb09fb76503a62619b386ca67a8ae28e0c98075..4de7cd45d4e7a874528bf0e23c4f86b40acca445 100644 (file)
@@ -1491,32 +1491,41 @@ 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);
-                       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) {
+               /*
+                * 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;
                }
+       } 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;
+               }
        }
 
        DEBUG(3,("reply_ntrename: %s -> %s\n",