]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
smbd: Simplify call_trans2setfilepathinfo()
authorVolker Lendecke <vl@samba.org>
Fri, 23 Dec 2022 16:29:45 +0000 (17:29 +0100)
committerRalph Boehme <slow@samba.org>
Wed, 4 Jan 2023 08:54:32 +0000 (08:54 +0000)
Move the file/path specific preparations to the respective callers.

Signed-off-by: Volker Lendecke <vl@samba.org>
Reviewed-by: Ralph Boehme <slow@samba.org>
source3/smbd/smb1_trans2.c

index 78d1a1318686500976c97302f3c0c8f42d64d082..a399f1aafde32a003cb7fa7aebbe733fc035f53f 100644 (file)
@@ -2362,204 +2362,16 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
 static void call_trans2setfilepathinfo(connection_struct *conn,
                                       struct smb_request *req,
                                       unsigned int tran_call,
+                                      uint16_t info_level,
+                                      struct smb_filename *smb_fname,
+                                      struct files_struct *fsp,
                                       char **pparams, int total_params,
                                       char **ppdata, int total_data,
                                       unsigned int max_data_bytes)
 {
        char *params = *pparams;
-       char *pdata = *ppdata;
-       uint16_t info_level;
-       struct smb_filename *smb_fname = NULL;
-       struct files_struct *dirfsp = NULL;
-       files_struct *fsp = NULL;
        NTSTATUS status = NT_STATUS_OK;
        int data_return_size = 0;
-       int ret;
-
-       if (!params) {
-               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
-               return;
-       }
-
-       if (tran_call == TRANSACT2_SETFILEINFO) {
-               if (total_params < 4) {
-                       reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
-                       return;
-               }
-
-               fsp = file_fsp(req, SVAL(params,0));
-               /* Basic check for non-null fsp. */
-               if (!check_fsp_open(conn, req, fsp)) {
-                       return;
-               }
-               info_level = SVAL(params,2);
-
-               if (INFO_LEVEL_IS_UNIX(info_level)) {
-                       if (!lp_smb1_unix_extensions()) {
-                               reply_nterror(req, NT_STATUS_INVALID_LEVEL);
-                               return;
-                       }
-                       if (!req->posix_pathnames) {
-                               reply_nterror(req, NT_STATUS_INVALID_LEVEL);
-                               return;
-                       }
-               }
-
-               smb_fname = fsp->fsp_name;
-
-               if (fsp_get_pathref_fd(fsp) == -1) {
-                       /*
-                        * This is actually a SETFILEINFO on a directory
-                        * handle (returned from an NT SMB). NT5.0 seems
-                        * to do this call. JRA.
-                        */
-                       ret = vfs_stat(conn, smb_fname);
-                       if (ret != 0) {
-                               DBG_NOTICE("vfs_stat of %s failed (%s)\n",
-                                       smb_fname_str_dbg(smb_fname),
-                                       strerror(errno));
-                               reply_nterror(req,
-                                       map_nt_error_from_unix(errno));
-                               return;
-                       }
-               } else if (fsp->print_file) {
-                       /*
-                        * Doing a DELETE_ON_CLOSE should cancel a print job.
-                        */
-                       if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) && CVAL(pdata,0)) {
-
-                               fsp->fsp_flags.delete_on_close = true;
-
-                               DEBUG(3,("call_trans2setfilepathinfo: "
-                                        "Cancelling print job (%s)\n",
-                                        fsp_str_dbg(fsp)));
-
-                               SSVAL(params,0,0);
-                               send_trans2_replies(conn, req, NT_STATUS_OK, params, 2,
-                                                   *ppdata, 0,
-                                                   max_data_bytes);
-                               return;
-                       } else {
-                               reply_nterror(req,
-                                       NT_STATUS_OBJECT_PATH_NOT_FOUND);
-                               return;
-                       }
-               } else {
-                       /*
-                        * Original code - this is an open file.
-                        */
-                       status = vfs_stat_fsp(fsp);
-                       if (!NT_STATUS_IS_OK(status)) {
-                               DEBUG(3,("call_trans2setfilepathinfo: fstat "
-                                        "of %s failed (%s)\n", fsp_fnum_dbg(fsp),
-                                        nt_errstr(status)));
-                               reply_nterror(req, status);
-                               return;
-                       }
-               }
-       } else {
-               char *fname = NULL;
-               uint32_t ucf_flags = ucf_flags_from_smb_request(req);
-               bool require_existing_object = true;
-               NTTIME twrp = 0;
-
-               /* set path info */
-               if (total_params < 7) {
-                       reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
-                       return;
-               }
-
-               info_level = SVAL(params,0);
-
-               if (INFO_LEVEL_IS_UNIX(info_level)) {
-                       if (!lp_smb1_unix_extensions()) {
-                               reply_nterror(req, NT_STATUS_INVALID_LEVEL);
-                               return;
-                       }
-                       if (!req->posix_pathnames) {
-                               reply_nterror(req, NT_STATUS_INVALID_LEVEL);
-                               return;
-                       }
-               }
-
-               if (req->posix_pathnames) {
-                       srvstr_get_path_posix(req,
-                               params,
-                               req->flags2,
-                               &fname,
-                               &params[6],
-                               total_params - 6,
-                               STR_TERMINATE,
-                               &status);
-               } else {
-                       srvstr_get_path(req,
-                               params,
-                               req->flags2,
-                               &fname,
-                               &params[6],
-                               total_params - 6,
-                               STR_TERMINATE,
-                               &status);
-               }
-               if (!NT_STATUS_IS_OK(status)) {
-                       reply_nterror(req, status);
-                       return;
-               }
-
-               if (ucf_flags & UCF_GMT_PATHNAME) {
-                       extract_snapshot_token(fname, &twrp);
-               }
-               status = filename_convert_dirfsp(req,
-                                                conn,
-                                                fname,
-                                                ucf_flags,
-                                                twrp,
-                                                &dirfsp,
-                                                &smb_fname);
-               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);
-                               return;
-                       }
-                       reply_nterror(req, status);
-                       return;
-               }
-
-               /*
-                * smb_fname->fsp may be NULL if smb_fname points at a symlink
-                * and we're in POSIX context, so be careful when using fsp
-                * below, it can still be NULL.
-                */
-               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);
-               }
-       }
 
        DEBUG(3,("call_trans2setfilepathinfo(%d) %s (%s) info_level=%d "
                 "totdata=%d\n", tran_call, smb_fname_str_dbg(smb_fname),
@@ -2635,10 +2447,126 @@ static void call_trans2setpathinfo(
        int total_data,
        unsigned int max_data_bytes)
 {
+       uint16_t info_level;
+       struct smb_filename *smb_fname = NULL;
+       struct files_struct *dirfsp = NULL;
+       struct files_struct *fsp = NULL;
+       char *params = *pparams;
+       uint32_t ucf_flags = ucf_flags_from_smb_request(req);
+       bool require_existing_object = true;
+       NTTIME twrp = 0;
+       char *fname = NULL;
+       NTSTATUS status;
+
+       if (params == NULL) {
+               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+               return;
+       }
+
+       /* set path info */
+       if (total_params < 7) {
+               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+               return;
+       }
+
+       info_level = SVAL(params,0);
+
+       if (INFO_LEVEL_IS_UNIX(info_level)) {
+               if (!lp_smb1_unix_extensions()) {
+                       reply_nterror(req, NT_STATUS_INVALID_LEVEL);
+                       return;
+               }
+               if (!req->posix_pathnames) {
+                       reply_nterror(req, NT_STATUS_INVALID_LEVEL);
+                       return;
+               }
+       }
+
+       if (req->posix_pathnames) {
+               srvstr_get_path_posix(req,
+                                     params,
+                                     req->flags2,
+                                     &fname,
+                                     &params[6],
+                                     total_params - 6,
+                                     STR_TERMINATE,
+                                     &status);
+       } else {
+               srvstr_get_path(req,
+                               params,
+                               req->flags2,
+                               &fname,
+                               &params[6],
+                               total_params - 6,
+                               STR_TERMINATE,
+                               &status);
+       }
+       if (!NT_STATUS_IS_OK(status)) {
+               reply_nterror(req, status);
+               return;
+       }
+
+       if (ucf_flags & UCF_GMT_PATHNAME) {
+               extract_snapshot_token(fname, &twrp);
+       }
+       status = filename_convert_dirfsp(req,
+                                        conn,
+                                        fname,
+                                        ucf_flags,
+                                        twrp,
+                                        &dirfsp,
+                                        &smb_fname);
+       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);
+                       return;
+               }
+               reply_nterror(req, status);
+               return;
+       }
+
+       /*
+        * smb_fname->fsp may be NULL if smb_fname points at a symlink
+        * and we're in POSIX context, so be careful when using fsp
+        * below, it can still be NULL.
+        */
+       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);
+       }
+
        call_trans2setfilepathinfo(
                conn,
                req,
                TRANSACT2_SETPATHINFO,
+               info_level,
+               smb_fname,
+               fsp,
                pparams,
                total_params,
                ppdata,
@@ -2655,10 +2583,104 @@ static void call_trans2setfileinfo(
        int total_data,
        unsigned int max_data_bytes)
 {
+       char *pdata = *ppdata;
+       uint16_t info_level;
+       struct smb_filename *smb_fname = NULL;
+       struct files_struct *fsp = NULL;
+       char *params = *pparams;
+       NTSTATUS status;
+       int ret;
+
+       if (params == NULL) {
+               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+               return;
+       }
+       if (total_params < 4) {
+               reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
+               return;
+       }
+
+       fsp = file_fsp(req, SVAL(params,0));
+       /* Basic check for non-null fsp. */
+       if (!check_fsp_open(conn, req, fsp)) {
+               return;
+       }
+       info_level = SVAL(params,2);
+
+       if (INFO_LEVEL_IS_UNIX(info_level)) {
+               if (!lp_smb1_unix_extensions()) {
+                       reply_nterror(req, NT_STATUS_INVALID_LEVEL);
+                       return;
+               }
+               if (!req->posix_pathnames) {
+                       reply_nterror(req, NT_STATUS_INVALID_LEVEL);
+                       return;
+               }
+       }
+
+       smb_fname = fsp->fsp_name;
+
+       if (fsp_get_pathref_fd(fsp) == -1) {
+               /*
+                * This is actually a SETFILEINFO on a directory
+                * handle (returned from an NT SMB). NT5.0 seems
+                * to do this call. JRA.
+                */
+               ret = vfs_stat(conn, smb_fname);
+               if (ret != 0) {
+                       DBG_NOTICE("vfs_stat of %s failed (%s)\n",
+                                  smb_fname_str_dbg(smb_fname),
+                                  strerror(errno));
+                       reply_nterror(req, map_nt_error_from_unix(errno));
+                       return;
+               }
+       } else if (fsp->print_file) {
+               /*
+                * Doing a DELETE_ON_CLOSE should cancel a print job.
+                */
+               if ((info_level == SMB_SET_FILE_DISPOSITION_INFO) &&
+                   CVAL(pdata,0)) {
+
+                       fsp->fsp_flags.delete_on_close = true;
+
+                       DBG_NOTICE("Cancelling print job (%s)\n",
+                                  fsp_str_dbg(fsp));
+
+                       SSVAL(params,0,0);
+                       send_trans2_replies(
+                               conn,
+                               req,
+                               NT_STATUS_OK,
+                               params,
+                               2,
+                               *ppdata, 0,
+                               max_data_bytes);
+                       return;
+               } else {
+                       reply_nterror(req, NT_STATUS_OBJECT_PATH_NOT_FOUND);
+                       return;
+               }
+       } else {
+               /*
+                * Original code - this is an open file.
+                */
+               status = vfs_stat_fsp(fsp);
+               if (!NT_STATUS_IS_OK(status)) {
+                       DBG_NOTICE("fstat of %s failed (%s)\n",
+                                  fsp_fnum_dbg(fsp),
+                                  nt_errstr(status));
+                       reply_nterror(req, status);
+                       return;
+               }
+       }
+
        call_trans2setfilepathinfo(
                conn,
                req,
                TRANSACT2_SETFILEINFO,
+               info_level,
+               smb_fname,
+               fsp,
                pparams,
                total_params,
                ppdata,