goto out;
}
- if (transfer_file(tmp_fd,outfd,(SMB_OFF_T)st.st_ex_size) == (SMB_OFF_T)-1) {
+ if (transfer_file(tmp_fd,outfd,(off_t)st.st_ex_size) == (off_t)-1) {
int err = errno;
close(tmp_fd);
close(outfd);
static int compare_share_mode_times(const void *p1, const void *p2)
{
- struct share_mode_entry *s1 = (struct share_mode_entry *)p1;
- struct share_mode_entry *s2 = (struct share_mode_entry *)p2;
+ const struct share_mode_entry *s1 = (const struct share_mode_entry *)p1;
+ const struct share_mode_entry *s2 = (const struct share_mode_entry *)p2;
return timeval_compare(&s1->time, &s2->time);
}
uint32_t i, num_deferred;
struct share_mode_entry *deferred;
- if (!should_notify_deferred_opens()) {
+ if (!should_notify_deferred_opens(sconn)) {
return;
}
num_deferred = 0;
for (i=0; i<lck->data->num_share_modes; i++) {
- if (is_deferred_open_entry(&lck->data->share_modes[i])) {
- num_deferred += 1;
+ struct share_mode_entry *e = &lck->data->share_modes[i];
+
+ if (!is_deferred_open_entry(e)) {
+ continue;
}
+ if (share_mode_stale_pid(lck->data, i)) {
+ continue;
+ }
+ num_deferred += 1;
}
if (num_deferred == 0) {
return;
NTSTATUS tmp_status;
struct file_id id;
const struct security_unix_token *del_token = NULL;
+ const struct security_token *del_nt_token = NULL;
+ bool got_tokens = false;
/* Ensure any pending write time updates are done. */
if (fsp->update_write_time_event) {
}
}
- if (!del_share_mode(lck, fsp)) {
- DEBUG(0, ("close_remove_share_mode: Could not delete share "
- "entry for file %s\n",
- fsp_str_dbg(fsp)));
- }
-
if (fsp->initial_delete_on_close &&
!is_delete_on_close_set(lck, fsp->name_hash)) {
bool became_user = False;
became_user = True;
}
fsp->delete_on_close = true;
- set_delete_on_close_lck(fsp, lck, True, get_current_utok(conn));
+ set_delete_on_close_lck(fsp, lck, True,
+ get_current_nttok(conn),
+ get_current_utok(conn));
if (became_user) {
unbecome_user();
}
POSIX delete now. */
for (i=0; i<lck->data->num_share_modes; i++) {
struct share_mode_entry *e = &lck->data->share_modes[i];
+
+ //TODO: continue if our own entry...
+
if (is_valid_share_mode_entry(e) &&
e->name_hash == fsp->name_hash) {
if (fsp->posix_open && (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) {
continue;
}
+ if (share_mode_stale_pid(lck->data, i)) {
+ continue;
+ }
delete_file = False;
break;
}
if (!(close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) ||
!delete_file) {
+ if (!del_share_mode(lck, fsp)) {
+ DEBUG(0, ("close_remove_share_mode: Could not delete share "
+ "entry for file %s\n",
+ fsp_str_dbg(fsp)));
+ }
+
TALLOC_FREE(lck);
return NT_STATUS_OK;
}
*/
fsp->update_write_time_on_close = false;
- del_token = get_delete_on_close_token(lck, fsp->name_hash);
- SMB_ASSERT(del_token != NULL);
+ got_tokens = get_delete_on_close_token(lck, fsp->name_hash,
+ &del_nt_token, &del_token);
+ SMB_ASSERT(got_tokens);
if (!unix_token_equal(del_token, get_current_utok(conn))) {
/* Become the user who requested the delete. */
del_token->gid,
del_token->ngroups,
del_token->groups,
- NULL);
+ del_nt_token);
changed_user = true;
}
*/
fsp->delete_on_close = false;
- set_delete_on_close_lck(fsp, lck, false, NULL);
+ set_delete_on_close_lck(fsp, lck, false, NULL, NULL);
done:
pop_sec_ctx();
}
+ if (delete_file) {
+ if (!del_share_mode(lck, fsp)) {
+ DEBUG(0, ("close_remove_share_mode: Could not delete share "
+ "entry for file %s\n",
+ fsp_str_dbg(fsp)));
+ }
+ }
+
TALLOC_FREE(lck);
if (delete_file) {
return NT_STATUS_OK;
}
- /* On close if we're changing the real file time we
- * must update it in the open file db too. */
- (void)set_write_time(fsp->file_id, fsp->close_write_time);
+ /*
+ * get_existing_share_mode_lock() isn't really the right
+ * call here, as we're being called after
+ * close_remove_share_mode() inside close_normal_file()
+ * so it's quite normal to not have an existing share
+ * mode here. However, get_share_mode_lock() doesn't
+ * work because that will create a new share mode if
+ * one doesn't exist - so stick with this call (just
+ * ignore any error we get if the share mode doesn't
+ * exist.
+ */
lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
if (lck) {
+ /* On close if we're changing the real file time we
+ * must update it in the open file db too. */
+ (void)set_write_time(fsp->file_id, fsp->close_write_time);
+
/* Close write times overwrite sticky write times
so we must replace any sticky write time here. */
if (!null_timespec(lck->data->changed_write_time)) {
NTSTATUS status = NT_STATUS_OK;
NTSTATUS tmp;
connection_struct *conn = fsp->conn;
+ int ret;
- if (close_type == ERROR_CLOSE) {
- cancel_aio_by_fsp(fsp);
- } else {
- /*
- * If we're finishing async io on a close we can get a write
- * error here, we must remember this.
- */
- int ret = wait_for_aio_completion(fsp);
- if (ret) {
- status = ntstatus_keeperror(
- status, map_nt_error_from_unix(ret));
- }
+ /*
+ * If we're finishing async io on a close we can get a write
+ * error here, we must remember this.
+ */
+ ret = wait_for_aio_completion(fsp);
+ if (ret) {
+ status = ntstatus_keeperror(
+ status, map_nt_error_from_unix(ret));
}
/*
return NT_STATUS_OK;
}
- if(((errno == ENOTEMPTY)||(errno == EEXIST)) && lp_veto_files(SNUM(conn))) {
+ if(((errno == ENOTEMPTY)||(errno == EEXIST)) && *lp_veto_files(SNUM(conn))) {
/*
* Check to see if the only thing in this directory are
* vetoed files/directories. If so then delete them and
bool delete_dir = False;
NTSTATUS status = NT_STATUS_OK;
NTSTATUS status1 = NT_STATUS_OK;
+ const struct security_token *del_nt_token = NULL;
const struct security_unix_token *del_token = NULL;
/*
send_stat_cache_delete_message(fsp->conn->sconn->msg_ctx,
fsp->fsp_name->base_name);
set_delete_on_close_lck(fsp, lck, true,
+ get_current_nttok(fsp->conn),
get_current_utok(fsp->conn));
fsp->delete_on_close = true;
if (became_user) {
}
}
- del_token = get_delete_on_close_token(lck, fsp->name_hash);
- delete_dir = (del_token != NULL);
+ delete_dir = get_delete_on_close_token(lck, fsp->name_hash,
+ &del_nt_token, &del_token);
if (delete_dir) {
int i;
if (fsp->posix_open && (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) {
continue;
}
+ if (share_mode_stale_pid(lck->data, i)) {
+ continue;
+ }
delete_dir = False;
break;
}
del_token->gid,
del_token->ngroups,
del_token->groups,
- NULL);
+ del_nt_token);
TALLOC_FREE(lck);