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,
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) {
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,
}
#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;
}