]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
smbd: Move smb_posix_unlink() to smb1_trans2.c
authorVolker Lendecke <vl@samba.org>
Wed, 28 Dec 2022 23:07:21 +0000 (00:07 +0100)
committerRalph Boehme <slow@samba.org>
Wed, 4 Jan 2023 08:54:32 +0000 (08:54 +0000)
Most of this is direct cut&paste without reformatting.

Don't pass SMB_POSIX_PATH_UNLINK through smbd_do_setfilepathinfo(),
directly handle it in call_trans2setpathinfo() where we know we have a
path.

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

index 35743f7cfd0128eb0106767dc77737b470481d1d..2cd855c0455cf6cf038c25bd28b84b662c453b7d 100644 (file)
@@ -2907,6 +2907,144 @@ static NTSTATUS smb_posix_open(connection_struct *conn,
        return NT_STATUS_OK;
 }
 
+/****************************************************************************
+ Delete a file with POSIX semantics.
+****************************************************************************/
+
+struct smb_posix_unlink_state {
+       struct smb_filename *smb_fname;
+       struct files_struct *fsp;
+       NTSTATUS status;
+};
+
+static void smb_posix_unlink_locked(struct share_mode_lock *lck,
+                                   void *private_data)
+{
+       struct smb_posix_unlink_state *state = private_data;
+       char del = 1;
+       bool other_nonposix_opens;
+
+       other_nonposix_opens = has_other_nonposix_opens(lck, state->fsp);
+       if (other_nonposix_opens) {
+               /* Fail with sharing violation. */
+               state->status = NT_STATUS_SHARING_VIOLATION;
+               return;
+       }
+
+       /*
+        * Set the delete on close.
+        */
+       state->status = smb_set_file_disposition_info(state->fsp->conn,
+                                                     &del,
+                                                     1,
+                                                     state->fsp,
+                                                     state->smb_fname);
+}
+
+static NTSTATUS smb_posix_unlink(connection_struct *conn,
+                                struct smb_request *req,
+                               const char *pdata,
+                               int total_data,
+                               struct smb_filename *smb_fname)
+{
+       struct smb_posix_unlink_state state = {};
+       NTSTATUS status = NT_STATUS_OK;
+       files_struct *fsp = NULL;
+       uint16_t flags = 0;
+       int info = 0;
+       int create_options = 0;
+       struct smb2_create_blobs *posx = NULL;
+
+       if (!CAN_WRITE(conn)) {
+               return NT_STATUS_DOS(ERRSRV, ERRaccess);
+       }
+
+       if (total_data < 2) {
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       flags = SVAL(pdata,0);
+
+       if (!VALID_STAT(smb_fname->st)) {
+               return NT_STATUS_OBJECT_NAME_NOT_FOUND;
+       }
+
+       if ((flags == SMB_POSIX_UNLINK_DIRECTORY_TARGET) &&
+                       !VALID_STAT_OF_DIR(smb_fname->st)) {
+               return NT_STATUS_NOT_A_DIRECTORY;
+       }
+
+       DEBUG(10,("smb_posix_unlink: %s %s\n",
+               (flags == SMB_POSIX_UNLINK_DIRECTORY_TARGET) ? "directory" : "file",
+               smb_fname_str_dbg(smb_fname)));
+
+       if (S_ISDIR(smb_fname->st.st_ex_mode)) {
+               create_options |= FILE_DIRECTORY_FILE;
+       }
+
+       status = make_smb2_posix_create_ctx(talloc_tos(), &posx, 0777);
+       if (!NT_STATUS_IS_OK(status)) {
+               DBG_WARNING("make_smb2_posix_create_ctx failed: %s\n",
+                           nt_errstr(status));
+               return status;
+       }
+
+        status = SMB_VFS_CREATE_FILE(
+               conn,                                   /* conn */
+               req,                                    /* req */
+               NULL,                                   /* dirfsp */
+               smb_fname,                              /* fname */
+               DELETE_ACCESS,                          /* access_mask */
+               (FILE_SHARE_READ | FILE_SHARE_WRITE |   /* share_access */
+                   FILE_SHARE_DELETE),
+               FILE_OPEN,                              /* create_disposition*/
+               create_options,                         /* create_options */
+               0,                                      /* file_attributes */
+               0,                                      /* oplock_request */
+               NULL,                                   /* lease */
+               0,                                      /* allocation_size */
+               0,                                      /* private_flags */
+               NULL,                                   /* sd */
+               NULL,                                   /* ea_list */
+               &fsp,                                   /* result */
+               &info,                                  /* pinfo */
+               posx,                                   /* in_context_blobs */
+               NULL);                                  /* out_context_blobs */
+
+       TALLOC_FREE(posx);
+
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       /*
+        * Don't lie to client. If we can't really delete due to
+        * non-POSIX opens return SHARING_VIOLATION.
+        */
+
+       state = (struct smb_posix_unlink_state) {
+               .smb_fname = smb_fname,
+               .fsp = fsp,
+       };
+
+       status = share_mode_do_locked_vfs_allowed(fsp->file_id,
+                                                 smb_posix_unlink_locked,
+                                                 &state);
+       if (!NT_STATUS_IS_OK(status)) {
+               DBG_ERR("share_mode_do_locked_vfs_allowed(%s) failed - %s\n",
+                       fsp_str_dbg(fsp), nt_errstr(status));
+               close_file_free(req, &fsp, NORMAL_CLOSE);
+               return NT_STATUS_INVALID_PARAMETER;
+       }
+
+       status = state.status;
+       if (!NT_STATUS_IS_OK(status)) {
+               close_file_free(req, &fsp, NORMAL_CLOSE);
+               return status;
+       }
+       return close_file_free(req, &fsp, NORMAL_CLOSE);
+}
+
 static void call_trans2setpathinfo(
        connection_struct *conn,
        struct smb_request *req,
@@ -3020,6 +3158,11 @@ static void call_trans2setpathinfo(
                        smb_fname,
                        &data_return_size);
                break;
+
+       case SMB_POSIX_PATH_UNLINK:
+               status = smb_posix_unlink(
+                       conn, req, *ppdata, total_data, smb_fname);
+               break;
        }
 
        if (info_level_handled) {
index ff95b24017efe9e6939e9d195ec7b82be0b08c16..e057da1885a2b4258f35bebc15029546b9b69af3 100644 (file)
@@ -6310,140 +6310,6 @@ static NTSTATUS smb_set_file_unix_info2(connection_struct *conn,
        return NT_STATUS_OK;
 }
 
-/****************************************************************************
- Delete a file with POSIX semantics.
-****************************************************************************/
-
-struct smb_posix_unlink_state {
-       struct smb_filename *smb_fname;
-       struct files_struct *fsp;
-       NTSTATUS status;
-};
-
-static void smb_posix_unlink_locked(struct share_mode_lock *lck,
-                                   void *private_data)
-{
-       struct smb_posix_unlink_state *state = private_data;
-       char del = 1;
-       bool other_nonposix_opens;
-
-       other_nonposix_opens = has_other_nonposix_opens(lck, state->fsp);
-       if (other_nonposix_opens) {
-               /* Fail with sharing violation. */
-               state->status = NT_STATUS_SHARING_VIOLATION;
-               return;
-       }
-
-       /*
-        * Set the delete on close.
-        */
-       state->status = smb_set_file_disposition_info(state->fsp->conn,
-                                                     &del,
-                                                     1,
-                                                     state->fsp,
-                                                     state->smb_fname);
-}
-
-static NTSTATUS smb_posix_unlink(connection_struct *conn,
-                                struct smb_request *req,
-                               const char *pdata,
-                               int total_data,
-                               struct smb_filename *smb_fname)
-{
-       struct smb_posix_unlink_state state = {};
-       NTSTATUS status = NT_STATUS_OK;
-       files_struct *fsp = NULL;
-       uint16_t flags = 0;
-       int info = 0;
-       int create_options = 0;
-       struct smb2_create_blobs *posx = NULL;
-
-       if (total_data < 2) {
-               return NT_STATUS_INVALID_PARAMETER;
-       }
-
-       flags = SVAL(pdata,0);
-
-       if (!VALID_STAT(smb_fname->st)) {
-               return NT_STATUS_OBJECT_NAME_NOT_FOUND;
-       }
-
-       if ((flags == SMB_POSIX_UNLINK_DIRECTORY_TARGET) &&
-                       !VALID_STAT_OF_DIR(smb_fname->st)) {
-               return NT_STATUS_NOT_A_DIRECTORY;
-       }
-
-       DEBUG(10,("smb_posix_unlink: %s %s\n",
-               (flags == SMB_POSIX_UNLINK_DIRECTORY_TARGET) ? "directory" : "file",
-               smb_fname_str_dbg(smb_fname)));
-
-       if (S_ISDIR(smb_fname->st.st_ex_mode)) {
-               create_options |= FILE_DIRECTORY_FILE;
-       }
-
-       status = make_smb2_posix_create_ctx(talloc_tos(), &posx, 0777);
-       if (!NT_STATUS_IS_OK(status)) {
-               DBG_WARNING("make_smb2_posix_create_ctx failed: %s\n",
-                           nt_errstr(status));
-               return status;
-       }
-
-        status = SMB_VFS_CREATE_FILE(
-               conn,                                   /* conn */
-               req,                                    /* req */
-               NULL,                                   /* dirfsp */
-               smb_fname,                              /* fname */
-               DELETE_ACCESS,                          /* access_mask */
-               (FILE_SHARE_READ | FILE_SHARE_WRITE |   /* share_access */
-                   FILE_SHARE_DELETE),
-               FILE_OPEN,                              /* create_disposition*/
-               create_options,                         /* create_options */
-               0,                                      /* file_attributes */
-               0,                                      /* oplock_request */
-               NULL,                                   /* lease */
-               0,                                      /* allocation_size */
-               0,                                      /* private_flags */
-               NULL,                                   /* sd */
-               NULL,                                   /* ea_list */
-               &fsp,                                   /* result */
-               &info,                                  /* pinfo */
-               posx,                                   /* in_context_blobs */
-               NULL);                                  /* out_context_blobs */
-
-       TALLOC_FREE(posx);
-
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-
-       /*
-        * Don't lie to client. If we can't really delete due to
-        * non-POSIX opens return SHARING_VIOLATION.
-        */
-
-       state = (struct smb_posix_unlink_state) {
-               .smb_fname = smb_fname,
-               .fsp = fsp,
-       };
-
-       status = share_mode_do_locked_vfs_allowed(fsp->file_id,
-                                                 smb_posix_unlink_locked,
-                                                 &state);
-       if (!NT_STATUS_IS_OK(status)) {
-               DBG_ERR("share_mode_do_locked_vfs_allowed(%s) failed - %s\n",
-                       fsp_str_dbg(fsp), nt_errstr(status));
-               close_file_free(req, &fsp, NORMAL_CLOSE);
-               return NT_STATUS_INVALID_PARAMETER;
-       }
-
-       status = state.status;
-       if (!NT_STATUS_IS_OK(status)) {
-               close_file_free(req, &fsp, NORMAL_CLOSE);
-               return status;
-       }
-       return close_file_free(req, &fsp, NORMAL_CLOSE);
-}
-
 static NTSTATUS smbd_do_posix_setfilepathinfo(struct connection_struct *conn,
                                              struct smb_request *req,
                                              TALLOC_CTX *mem_ctx,
@@ -6543,20 +6409,6 @@ static NTSTATUS smbd_do_posix_setfilepathinfo(struct connection_struct *conn,
                }
 #endif
 
-               case SMB_POSIX_PATH_UNLINK:
-               {
-                       if (smb_fname == NULL) {
-                               /* We must have a pathname for this. */
-                               return NT_STATUS_INVALID_LEVEL;
-                       }
-
-                       status = smb_posix_unlink(conn, req,
-                                               pdata,
-                                               total_data,
-                                               smb_fname);
-                       break;
-               }
-
                default:
                        return NT_STATUS_INVALID_LEVEL;
        }