22
22
#include "includes.h"
24
extern struct current_user current_user;
23
#include "system/filesys.h"
25
#include "smbd/smbd.h"
26
#include "smbd/globals.h"
27
#include "fake_file.h"
28
#include "transfer_file.h"
26
32
/****************************************************************************
27
33
Run a file if it is a magic script.
153
159
If any deferred opens are waiting on this close, notify them.
154
160
****************************************************************************/
156
static void notify_deferred_opens(struct share_mode_lock *lck)
162
static void notify_deferred_opens(struct messaging_context *msg_ctx,
163
struct share_mode_lock *lck)
175
182
* the head of the queue and changing the wait time to
178
schedule_deferred_open_smb_message(e->op_mid);
185
schedule_deferred_open_message_smb(e->op_mid);
180
187
char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
182
189
share_mode_entry_to_message(msg, e);
184
messaging_send_buf(smbd_messaging_context(),
185
e->pid, MSG_SMB_OPEN_RETRY,
191
messaging_send_buf(msg_ctx, e->pid, MSG_SMB_OPEN_RETRY,
187
193
MSG_SMB_SHARE_MODE_ENTRY_SIZE);
326
333
fsp_str_dbg(fsp)));
329
if (fsp->initial_delete_on_close && (lck->delete_token == NULL)) {
336
if (fsp->initial_delete_on_close &&
337
!is_delete_on_close_set(lck, fsp->name_hash)) {
330
338
bool became_user = False;
332
340
/* Initial delete on close was set and no one else
333
341
* wrote a real delete on close. */
335
if (current_user.vuid != fsp->vuid) {
343
if (get_current_vuid(conn) != fsp->vuid) {
336
344
become_user(conn, fsp->vuid);
337
345
became_user = True;
339
347
fsp->delete_on_close = true;
340
set_delete_on_close_lck(lck, True, ¤t_user.ut);
348
set_delete_on_close_lck(fsp, lck, True, get_current_utok(conn));
341
349
if (became_user) {
346
delete_file = lck->delete_on_close;
354
delete_file = is_delete_on_close_set(lck, fsp->name_hash);
348
356
if (delete_file) {
350
/* See if others still have the file open. If this is the
351
* case, then don't delete. If all opens are POSIX delete now. */
358
/* See if others still have the file open via this pathname.
359
If this is the case, then don't delete. If all opens are
352
361
for (i=0; i<lck->num_share_modes; i++) {
353
362
struct share_mode_entry *e = &lck->share_modes[i];
354
if (is_valid_share_mode_entry(e)) {
363
if (is_valid_share_mode_entry(e) &&
364
e->name_hash == fsp->name_hash) {
355
365
if (fsp->posix_open && (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) {
364
374
/* Notify any deferred opens waiting on this close. */
365
notify_deferred_opens(lck);
375
notify_deferred_opens(conn->sconn->msg_ctx, lck);
366
376
reply_to_oplock_break_requests(fsp);
390
399
fsp->update_write_time_on_close = false;
392
if (!unix_token_equal(lck->delete_token, ¤t_user.ut)) {
401
del_token = get_delete_on_close_token(lck, fsp->name_hash);
402
SMB_ASSERT(del_token != NULL);
404
if (!unix_token_equal(del_token, get_current_utok(conn))) {
393
405
/* Become the user who requested the delete. */
395
407
DEBUG(5,("close_remove_share_mode: file %s. "
396
408
"Change user to uid %u\n",
397
409
fsp_str_dbg(fsp),
398
(unsigned int)lck->delete_token->uid));
410
(unsigned int)del_token->uid));
400
412
if (!push_sec_ctx()) {
401
413
smb_panic("close_remove_share_mode: file %s. failed to push "
405
set_sec_ctx(lck->delete_token->uid,
406
lck->delete_token->gid,
407
lck->delete_token->ngroups,
408
lck->delete_token->groups,
417
set_sec_ctx(del_token->uid,
411
423
changed_user = true;
471
483
status = map_nt_error_from_unix(errno);
474
notify_fname(conn, NOTIFY_ACTION_REMOVED,
475
FILE_NOTIFY_CHANGE_FILE_NAME,
476
fsp->fsp_name->base_name);
478
486
/* As we now have POSIX opens which can unlink
479
487
* with other open files we may have taken
480
488
* this code path with more than one share mode
485
493
fsp->delete_on_close = false;
486
set_delete_on_close_lck(lck, False, NULL);
494
set_delete_on_close_lck(fsp, lck, false, NULL);
495
503
TALLOC_FREE(lck);
507
* Do the notification after we released the share
508
* mode lock. Inside notify_fname we take out another
509
* tdb lock. With ctdb also accessing our databases,
510
* this can lead to deadlocks. Putting this notify
511
* after the TALLOC_FREE(lck) above we avoid locking
512
* two records simultaneously. Notifies are async and
513
* informational only, so calling the notify_fname
514
* without holding the share mode lock should not do
517
notify_fname(conn, NOTIFY_ACTION_REMOVED,
518
FILE_NOTIFY_CHANGE_FILE_NAME,
519
fsp->fsp_name->base_name);
552
578
ft.mtime = fsp->close_write_time;
553
status = smb_set_file_time(fsp->conn, fsp, fsp->fsp_name, &ft, false);
579
/* We must use NULL for the fsp handle here, as smb_set_file_time()
580
checks the fsp access_mask, which may not include FILE_WRITE_ATTRIBUTES.
581
As this is a close based update, we are not directly changing the
582
file attributes from a client call, but indirectly from a write. */
583
status = smb_set_file_time(fsp->conn, NULL, fsp->fsp_name, &ft, false);
554
584
if (!NT_STATUS_IS_OK(status)) {
585
DEBUG(10,("update_write_time_on_close: smb_set_file_time "
586
"on file %s returned %s\n",
582
616
connection_struct *conn = fsp->conn;
584
if (fsp->aio_write_behind) {
618
if (close_type == ERROR_CLOSE) {
619
cancel_aio_by_fsp(fsp);
586
* If we're finishing write behind on a close we can get a write
622
* If we're finishing async io on a close we can get a write
587
623
* error here, we must remember this.
589
625
int ret = wait_for_aio_completion(fsp);
591
627
status = ntstatus_keeperror(
592
628
status, map_nt_error_from_unix(ret));
595
cancel_aio_by_fsp(fsp);
599
633
* If we're flushing on a close we can get a write
600
634
* error here, we must remember this.
604
638
status = ntstatus_keeperror(status, tmp);
606
640
if (fsp->print_file) {
607
print_fsp_end(fsp, close_type);
641
/* FIXME: return spool errors */
642
print_spool_end(fsp, close_type);
608
643
file_free(req, fsp);
609
644
return NT_STATUS_OK;
624
659
status = ntstatus_keeperror(status, tmp);
627
locking_close_file(smbd_messaging_context(), fsp);
662
locking_close_file(conn->sconn->msg_ctx, fsp, close_type);
629
664
tmp = fd_close(fsp);
630
665
status = ntstatus_keeperror(status, tmp);
651
686
status = ntstatus_keeperror(status, tmp);
653
688
DEBUG(2,("%s closed file %s (numopen=%d) %s\n",
654
conn->server_info->unix_name, fsp_str_dbg(fsp),
689
conn->session_info->unix_name, fsp_str_dbg(fsp),
655
690
conn->num_files_open - 1,
656
691
nt_errstr(status) ));
955
991
* directories we don't care if anyone else
956
992
* wrote a real delete on close. */
958
if (current_user.vuid != fsp->vuid) {
994
if (get_current_vuid(fsp->conn) != fsp->vuid) {
959
995
become_user(fsp->conn, fsp->vuid);
960
996
became_user = True;
962
send_stat_cache_delete_message(fsp->fsp_name->base_name);
963
set_delete_on_close_lck(lck, True, ¤t_user.ut);
998
send_stat_cache_delete_message(fsp->conn->sconn->msg_ctx,
999
fsp->fsp_name->base_name);
1000
set_delete_on_close_lck(fsp, lck, true,
1001
get_current_utok(fsp->conn));
964
1002
fsp->delete_on_close = true;
965
1003
if (became_user) {
966
1004
unbecome_user();
970
delete_dir = lck->delete_on_close;
1008
del_token = get_delete_on_close_token(lck, fsp->name_hash);
1009
delete_dir = (del_token != NULL);
972
1011
if (delete_dir) {
975
1014
* case, then don't delete. If all opens are POSIX delete now. */
976
1015
for (i=0; i<lck->num_share_modes; i++) {
977
1016
struct share_mode_entry *e = &lck->share_modes[i];
978
if (is_valid_share_mode_entry(e)) {
1017
if (is_valid_share_mode_entry(e) &&
1018
e->name_hash == fsp->name_hash) {
979
1019
if (fsp->posix_open && (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) {
995
1034
smb_panic("close_directory: failed to push sec_ctx.\n");
998
set_sec_ctx(lck->delete_token->uid,
999
lck->delete_token->gid,
1000
lck->delete_token->ngroups,
1001
lck->delete_token->groups,
1037
set_sec_ctx(del_token->uid,
1004
1043
TALLOC_FREE(lck);
1099
1134
struct server_id server_id,
1100
1135
DATA_BLOB *data)
1137
struct smbd_server_connection *sconn;
1102
1138
files_struct *fsp = NULL;
1103
1139
struct share_mode_entry e;
1141
sconn = msg_ctx_to_sconn(msg_ctx);
1142
if (sconn == NULL) {
1143
DEBUG(1, ("could not find sconn\n"));
1105
1147
message_to_share_mode_entry(&e, (char *)data->data);
1107
1149
if(DEBUGLVL(10)) {
1114
1156
TALLOC_FREE(sm_str);
1117
fsp = file_find_dif(e.id, e.share_file_id);
1159
fsp = file_find_dif(sconn, e.id, e.share_file_id);
1119
1161
DEBUG(10,("msg_close_file: failed to find file.\n"));