]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3: smbd: Inside call_trans2setfilepathinfo(), for the TRANSACT2_SETPATHINFO case...
authorJeremy Allison <jra@samba.org>
Tue, 14 Dec 2021 00:48:14 +0000 (16:48 -0800)
committerJeremy Allison <jra@samba.org>
Wed, 15 Dec 2021 18:36:31 +0000 (18:36 +0000)
Remember, filename_convert() can return NT_STATUS_OK
with !VALID_STAT() if the last component doesn't exist,
as this may be an object create.

For call_trans2setfilepathinfo(), there are only 4 info levels
for the TRANSACT2_SETPATHINFO (pathname) case that don't require
an existing filesystem object (i.e. a VALID_STAT()) in the return
from filename_convert() as they can create an object in the
filesystem.

If we don't get a VALID_STAT() and the info level isn't one of
those 4, error out.

Signed-off-by: Jeremy Allison <jra@samba.org>
Reviewed-by: Noel Power <npower@samba.org>
source3/smbd/trans2.c

index 8b97aa64d282ea1bbf04a304e0c6bb171f825723..73a3bbae7cd715166f61e3d9e8ffd129e283493f 100644 (file)
@@ -9339,6 +9339,7 @@ static void call_trans2setfilepathinfo(connection_struct *conn,
        } else {
                char *fname = NULL;
                uint32_t ucf_flags = ucf_flags_from_smb_request(req);
+               bool require_existing_object = true;
 
                /* set path info */
                if (total_params < 7) {
@@ -9406,6 +9407,32 @@ static void call_trans2setfilepathinfo(connection_struct *conn,
                 */
                fsp = smb_fname->fsp;
 
+               /*
+                * There are 4 info levels which can
+                * create a new object in the filesystem.
+                * They are:
+                * SMB_SET_FILE_UNIX_LINK -> creates POSIX symlink.
+                * SMB_POSIX_PATH_OPEN -> creates POSIX file or directory.
+                * SMB_SET_FILE_UNIX_BASIC:
+                * SMB_SET_FILE_UNIX_INFO2: can create a POSIX special file.
+                *
+                * These info levels do not require an existing object.
+                */
+               switch (info_level) {
+               case SMB_SET_FILE_UNIX_LINK:
+               case SMB_POSIX_PATH_OPEN:
+               case SMB_SET_FILE_UNIX_BASIC:
+               case SMB_SET_FILE_UNIX_INFO2:
+                       require_existing_object = false;
+                       break;
+               default:
+                       break;
+               }
+
+               if (!VALID_STAT(smb_fname->st) && require_existing_object) {
+                       reply_nterror(req, NT_STATUS_OBJECT_NAME_NOT_FOUND);
+               }
+
                if (INFO_LEVEL_IS_UNIX(info_level)) {
                        /*
                         * For CIFS UNIX extensions the target name may not exist.