struct security_descriptor *parent_sd = NULL;
uint32_t access_granted = 0;
struct smb_filename *parent_smb_fname = NULL;
+ struct share_mode_lock *lck = NULL;
+ struct file_id id = {0};
+ uint32_t name_hash;
+ bool delete_on_close_set;
+ int ret;
if (!parent_dirname(talloc_tos(),
smb_fname->base_name,
return status;
}
- return NT_STATUS_OK;
+ if (!(access_mask & (SEC_DIR_ADD_FILE | SEC_DIR_ADD_SUBDIR))) {
+ return NT_STATUS_OK;
+ }
+ if (!lp_check_parent_directory_delete_on_close(SNUM(conn))) {
+ return NT_STATUS_OK;
+ }
+
+ /* Check if the directory has delete-on-close set */
+ ret = SMB_VFS_STAT(conn, parent_smb_fname);
+ if (ret != 0) {
+ status = map_nt_error_from_unix(errno);
+ goto out;
+ }
+
+ id = SMB_VFS_FILE_ID_CREATE(conn, &parent_smb_fname->st);
+
+ status = file_name_hash(conn, parent_smb_fname->base_name, &name_hash);
+ if (!NT_STATUS_IS_OK(status)) {
+ goto out;
+ }
+
+ lck = get_existing_share_mode_lock(talloc_tos(), id);
+ if (lck == NULL) {
+ status = NT_STATUS_OK;
+ goto out;
+ }
+
+ delete_on_close_set = is_delete_on_close_set(lck, name_hash);
+ if (delete_on_close_set) {
+ status = NT_STATUS_DELETE_PENDING;
+ goto out;
+ }
+
+ status = NT_STATUS_OK;
+
+out:
+ TALLOC_FREE(lck);
+ TALLOC_FREE(parent_smb_fname);
+ return status;
}
/****************************************************************************
#if defined(DEVELOPER)
static void validate_my_share_entries(struct smbd_server_connection *sconn,
+ const struct file_id id,
int num,
struct share_mode_entry *share_entry)
{
return;
}
- fsp = file_find_dif(sconn, share_entry->id,
- share_entry->share_file_id);
+ fsp = file_find_dif(sconn, id, share_entry->share_file_id);
if (!fsp) {
- DEBUG(0,("validate_my_share_entries: PANIC : %s\n",
- share_mode_str(talloc_tos(), num, share_entry) ));
+ DBG_ERR("PANIC : %s\n",
+ share_mode_str(talloc_tos(), num, &id,
+ share_entry));
smb_panic("validate_my_share_entries: Cannot match a "
"share entry with an open file\n");
}
panic:
{
char *str;
- DEBUG(0,("validate_my_share_entries: PANIC : %s\n",
- share_mode_str(talloc_tos(), num, share_entry) ));
+ DBG_ERR("validate_my_share_entries: PANIC : %s\n",
+ share_mode_str(talloc_tos(), num, &id,
+ share_entry));
str = talloc_asprintf(talloc_tos(),
"validate_my_share_entries: "
"file %s, oplock_type = 0x%x, op_type = 0x%x\n",
#if defined(DEVELOPER)
for(i = 0; i < lck->data->num_share_modes; i++) {
- validate_my_share_entries(conn->sconn, i,
+ validate_my_share_entries(conn->sconn, lck->data->id, i,
&lck->data->share_modes[i]);
}
#endif
*/
NTSTATUS send_break_message(struct messaging_context *msg_ctx,
- const struct share_mode_entry *exclusive,
- uint16_t break_to)
+ const struct file_id *id,
+ const struct share_mode_entry *exclusive,
+ uint16_t break_to)
{
NTSTATUS status;
char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
server_id_str_buf(exclusive->pid, &tmp)));
/* Create the message. */
- share_mode_entry_to_message(msg, exclusive);
+ share_mode_entry_to_message(msg, id, exclusive);
/* Overload entry->op_type */
/*
DEBUG(10, ("breaking from %d to %d\n",
(int)e_lease_type, (int)break_to));
- send_break_message(fsp->conn->sconn->msg_ctx, e,
- break_to);
+ send_break_message(fsp->conn->sconn->msg_ctx, &fsp->file_id,
+ e, break_to);
if (e_lease_type & delay_mask) {
delay = true;
}
continue;
}
- send_break_message(conn->sconn->msg_ctx, e,
+ send_break_message(conn->sconn->msg_ctx, &d->id, e,
SMB2_LEASE_NONE);
/*