2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Jeremy Allison 1992-2007.
6 Copyright (C) Volker Lendecke 2005
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "system/filesys.h"
24 #include "lib/util/server_id.h"
26 #include "locking/share_mode_lock.h"
27 #include "smbd/smbd.h"
28 #include "smbd/globals.h"
29 #include "smbd/smbXsrv_open.h"
30 #include "smbd/scavenger.h"
31 #include "fake_file.h"
32 #include "transfer_file.h"
35 #include "../librpc/gen_ndr/open_files.h"
36 #include "lib/util/tevent_ntstatus.h"
38 /****************************************************************************
39 Run a file if it is a magic script.
40 ****************************************************************************/
42 static NTSTATUS
check_magic(struct files_struct
*fsp
)
45 const struct loadparm_substitution
*lp_sub
=
46 loadparm_s3_global_substitution();
47 const char *magic_output
= NULL
;
50 TALLOC_CTX
*ctx
= NULL
;
52 struct connection_struct
*conn
= fsp
->conn
;
56 if (!*lp_magic_script(talloc_tos(), lp_sub
, SNUM(conn
))) {
60 DEBUG(5,("checking magic for %s\n", fsp_str_dbg(fsp
)));
62 ctx
= talloc_stackframe();
64 fname
= fsp
->fsp_name
->base_name
;
66 if (!(p
= strrchr_m(fname
,'/'))) {
72 if (!strequal(lp_magic_script(talloc_tos(), lp_sub
, SNUM(conn
)),p
)) {
73 status
= NT_STATUS_OK
;
77 if (*lp_magic_output(talloc_tos(), lp_sub
, SNUM(conn
))) {
78 magic_output
= lp_magic_output(talloc_tos(), lp_sub
, SNUM(conn
));
80 magic_output
= talloc_asprintf(ctx
,
85 status
= NT_STATUS_NO_MEMORY
;
89 /* Ensure we don't depend on user's PATH. */
90 p
= talloc_asprintf(ctx
, "./%s", fname
);
92 status
= NT_STATUS_NO_MEMORY
;
96 if (chmod(fname
, 0755) == -1) {
97 status
= map_nt_error_from_unix(errno
);
100 ret
= smbrun(p
, &tmp_fd
, NULL
);
101 DEBUG(3,("Invoking magic command %s gave %d\n",
105 if (ret
!= 0 || tmp_fd
== -1) {
109 status
= NT_STATUS_UNSUCCESSFUL
;
112 outfd
= open(magic_output
, O_CREAT
|O_EXCL
|O_RDWR
, 0600);
116 status
= map_nt_error_from_unix(err
);
120 if (sys_fstat(tmp_fd
, &st
, false) == -1) {
124 status
= map_nt_error_from_unix(err
);
128 if (transfer_file(tmp_fd
,outfd
,(off_t
)st
.st_ex_size
) == (off_t
)-1) {
132 status
= map_nt_error_from_unix(err
);
136 if (close(outfd
) == -1) {
137 status
= map_nt_error_from_unix(errno
);
141 status
= NT_STATUS_OK
;
148 /****************************************************************************
150 ****************************************************************************/
152 NTSTATUS
delete_all_streams(connection_struct
*conn
,
153 const struct smb_filename
*smb_fname
)
155 struct stream_struct
*stream_info
= NULL
;
157 unsigned int num_streams
= 0;
158 TALLOC_CTX
*frame
= talloc_stackframe();
161 status
= vfs_fstreaminfo(smb_fname
->fsp
, talloc_tos(),
162 &num_streams
, &stream_info
);
164 if (NT_STATUS_EQUAL(status
, NT_STATUS_NOT_IMPLEMENTED
)) {
165 DEBUG(10, ("no streams around\n"));
170 if (!NT_STATUS_IS_OK(status
)) {
171 DEBUG(10, ("vfs_fstreaminfo failed: %s\n",
176 DEBUG(10, ("delete_all_streams found %d streams\n",
179 if (num_streams
== 0) {
184 for (i
=0; i
<num_streams
; i
++) {
186 struct smb_filename
*smb_fname_stream
;
188 if (strequal(stream_info
[i
].name
, "::$DATA")) {
192 status
= synthetic_pathref(talloc_tos(),
194 smb_fname
->base_name
,
199 ~SMB_FILENAME_POSIX_PATH
),
201 if (!NT_STATUS_IS_OK(status
)) {
202 DEBUG(0, ("talloc_aprintf failed\n"));
203 status
= NT_STATUS_NO_MEMORY
;
207 res
= SMB_VFS_UNLINKAT(conn
,
213 status
= map_nt_error_from_unix(errno
);
214 DEBUG(10, ("Could not delete stream %s: %s\n",
215 smb_fname_str_dbg(smb_fname_stream
),
217 TALLOC_FREE(smb_fname_stream
);
220 TALLOC_FREE(smb_fname_stream
);
228 struct has_other_nonposix_opens_state
{
233 static bool has_other_nonposix_opens_fn(
234 struct share_mode_entry
*e
,
238 struct has_other_nonposix_opens_state
*state
= private_data
;
239 struct files_struct
*fsp
= state
->fsp
;
241 if (e
->name_hash
!= fsp
->name_hash
) {
244 if ((fsp
->posix_flags
& FSP_POSIX_FLAGS_OPEN
) &&
245 (e
->flags
& SHARE_MODE_FLAG_POSIX_OPEN
)) {
248 if (e
->share_file_id
== fh_get_gen_id(fsp
->fh
)) {
249 struct server_id self
= messaging_server_id(
250 fsp
->conn
->sconn
->msg_ctx
);
251 if (server_id_equal(&self
, &e
->pid
)) {
255 if (share_entry_stale_pid(e
)) {
259 state
->found_another
= true;
263 bool has_other_nonposix_opens(struct share_mode_lock
*lck
,
264 struct files_struct
*fsp
)
266 struct has_other_nonposix_opens_state state
= { .fsp
= fsp
};
269 ok
= share_mode_forall_entries(
270 lck
, has_other_nonposix_opens_fn
, &state
);
274 return state
.found_another
;
277 struct close_share_mode_lock_state
{
278 struct share_mode_entry_prepare_state prepare_state
;
279 const char *object_type
;
280 struct files_struct
*fsp
;
281 enum file_close_type close_type
;
284 const struct security_unix_token
*del_token
;
285 const struct security_token
*del_nt_token
;
286 bool reset_delete_on_close
;
287 share_mode_entry_prepare_unlock_fn_t cleanup_fn
;
290 static void close_share_mode_lock_prepare(struct share_mode_lock
*lck
,
294 struct close_share_mode_lock_state
*state
=
295 (struct close_share_mode_lock_state
*)private_data
;
296 struct files_struct
*fsp
= state
->fsp
;
301 * By default drop the g_lock again if we leave the
304 *keep_locked
= false;
306 if (fsp
->oplock_type
!= NO_OPLOCK
) {
307 ok
= remove_share_oplock(lck
, fsp
);
309 struct file_id_buf buf
;
311 DBG_ERR("failed to remove share oplock for "
314 fsp_str_dbg(fsp
), fsp_fnum_dbg(fsp
),
315 file_id_str_buf(fsp
->file_id
, &buf
));
319 if (fsp
->fsp_flags
.write_time_forced
) {
320 NTTIME mtime
= share_mode_changed_write_time(lck
);
321 struct timespec ts
= nt_time_to_full_timespec(mtime
);
323 DBG_DEBUG("write time forced for %s %s\n",
324 state
->object_type
, fsp_str_dbg(fsp
));
325 set_close_write_time(fsp
, ts
);
326 } else if (fsp
->fsp_flags
.update_write_time_on_close
) {
327 /* Someone had a pending write. */
328 if (is_omit_timespec(&fsp
->close_write_time
)) {
329 DBG_DEBUG("update to current time for %s %s\n",
330 state
->object_type
, fsp_str_dbg(fsp
));
331 /* Update to current time due to "normal" write. */
332 set_close_write_time(fsp
, timespec_current());
334 DBG_DEBUG("write time pending for %s %s\n",
335 state
->object_type
, fsp_str_dbg(fsp
));
336 /* Update to time set on close call. */
337 set_close_write_time(fsp
, fsp
->close_write_time
);
341 if (fsp
->fsp_flags
.initial_delete_on_close
&&
342 !is_delete_on_close_set(lck
, fsp
->name_hash
)) {
343 /* Initial delete on close was set and no one else
344 * wrote a real delete on close. */
346 fsp
->fsp_flags
.delete_on_close
= true;
347 set_delete_on_close_lck(fsp
, lck
,
348 fsp
->conn
->session_info
->security_token
,
349 fsp
->conn
->session_info
->unix_token
);
352 state
->delete_object
= is_delete_on_close_set(lck
, fsp
->name_hash
) &&
353 !has_other_nonposix_opens(lck
, fsp
);
356 * NT can set delete_on_close of the last open
357 * reference to a file.
360 normal_close
= (state
->close_type
== NORMAL_CLOSE
|| state
->close_type
== SHUTDOWN_CLOSE
);
363 * Never try to delete the file/directory for ERROR_CLOSE
365 state
->delete_object
= false;
368 if (!state
->delete_object
) {
369 ok
= del_share_mode(lck
, fsp
);
371 DBG_ERR("Could not delete share entry for %s %s\n",
372 state
->object_type
, fsp_str_dbg(fsp
));
378 * We're going to remove the file/directory
379 * so keep the g_lock after the tdb chainlock
380 * is left, so we hold the share_mode_lock
381 * also during the deletion
385 state
->got_tokens
= get_delete_on_close_token(lck
, fsp
->name_hash
,
386 &state
->del_nt_token
, &state
->del_token
);
387 if (state
->close_type
!= ERROR_CLOSE
) {
388 SMB_ASSERT(state
->got_tokens
);
392 static void close_share_mode_lock_cleanup(struct share_mode_lock
*lck
,
395 struct close_share_mode_lock_state
*state
=
396 (struct close_share_mode_lock_state
*)private_data
;
397 struct files_struct
*fsp
= state
->fsp
;
400 if (state
->reset_delete_on_close
) {
401 reset_delete_on_close_lck(fsp
, lck
);
404 ok
= del_share_mode(lck
, fsp
);
406 DBG_ERR("Could not delete share entry for %s %s\n",
407 state
->object_type
, fsp_str_dbg(fsp
));
411 /****************************************************************************
412 Deal with removing a share mode on last close.
413 ****************************************************************************/
415 static NTSTATUS
close_remove_share_mode(files_struct
*fsp
,
416 enum file_close_type close_type
)
418 connection_struct
*conn
= fsp
->conn
;
419 struct close_share_mode_lock_state lck_state
= {};
420 bool changed_user
= false;
421 NTSTATUS status
= NT_STATUS_OK
;
425 struct smb_filename
*parent_fname
= NULL
;
426 struct smb_filename
*base_fname
= NULL
;
429 /* Ensure any pending write time updates are done. */
430 if (fsp
->update_write_time_event
) {
431 fsp_flush_write_time_update(fsp
);
435 * Lock the share entries, and determine if we should delete
436 * on close. If so delete whilst the lock is still in effect.
437 * This prevents race conditions with the file being created. JRA.
440 lck_state
= (struct close_share_mode_lock_state
) {
442 .object_type
= "file",
443 .close_type
= close_type
,
446 status
= share_mode_entry_prepare_lock_del(&lck_state
.prepare_state
,
448 close_share_mode_lock_prepare
,
450 if (!NT_STATUS_IS_OK(status
)) {
451 DBG_ERR("share_mode_entry_prepare_lock_del() failed for %s - %s\n",
452 fsp_str_dbg(fsp
), nt_errstr(status
));
456 /* Remove the oplock before potentially deleting the file. */
457 if (fsp
->oplock_type
!= NO_OPLOCK
) {
458 release_file_oplock(fsp
);
462 * NT can set delete_on_close of the last open
463 * reference to a file.
466 if (!lck_state
.delete_object
) {
467 status
= NT_STATUS_OK
;
472 * Ok, we have to delete the file
474 lck_state
.cleanup_fn
= close_share_mode_lock_cleanup
;
476 DEBUG(5,("close_remove_share_mode: file %s. Delete on close was set "
477 "- deleting file.\n", fsp_str_dbg(fsp
)));
480 * Don't try to update the write time when we delete the file
482 fsp
->fsp_flags
.update_write_time_on_close
= false;
484 if (lck_state
.got_tokens
&&
485 !unix_token_equal(lck_state
.del_token
, get_current_utok(conn
)))
487 /* Become the user who requested the delete. */
489 DEBUG(5,("close_remove_share_mode: file %s. "
490 "Change user to uid %u\n",
492 (unsigned int)lck_state
.del_token
->uid
));
494 if (!push_sec_ctx()) {
495 smb_panic("close_remove_share_mode: file %s. failed to push "
499 set_sec_ctx(lck_state
.del_token
->uid
,
500 lck_state
.del_token
->gid
,
501 lck_state
.del_token
->ngroups
,
502 lck_state
.del_token
->groups
,
503 lck_state
.del_nt_token
);
508 /* We can only delete the file if the name we have is still valid and
509 hasn't been renamed. */
511 tmp_status
= vfs_stat_fsp(fsp
);
512 if (!NT_STATUS_IS_OK(tmp_status
)) {
513 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
514 "was set and stat failed with error %s\n",
515 fsp_str_dbg(fsp
), nt_errstr(tmp_status
)));
517 * Don't save the errno here, we ignore this error
522 id
= vfs_file_id_from_sbuf(conn
, &fsp
->fsp_name
->st
);
524 if (!file_id_equal(&fsp
->file_id
, &id
)) {
525 struct file_id_buf ftmp1
, ftmp2
;
526 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
527 "was set and dev and/or inode does not match\n",
529 DEBUG(5,("close_remove_share_mode: file %s. stored file_id %s, "
532 file_id_str_buf(fsp
->file_id
, &ftmp1
),
533 file_id_str_buf(id
, &ftmp2
)));
535 * Don't save the errno here, we ignore this error
540 if ((conn
->fs_capabilities
& FILE_NAMED_STREAMS
)
541 && !fsp_is_alternate_stream(fsp
)) {
543 status
= delete_all_streams(conn
, fsp
->fsp_name
);
545 if (!NT_STATUS_IS_OK(status
)) {
546 DEBUG(5, ("delete_all_streams failed: %s\n",
552 if (fsp
->fsp_flags
.kernel_share_modes_taken
) {
554 * A file system sharemode could block the unlink;
555 * remove filesystem sharemodes first.
557 ret
= SMB_VFS_FILESYSTEM_SHAREMODE(fsp
, 0, 0);
559 DBG_INFO("Removing file system sharemode for %s "
561 fsp_str_dbg(fsp
), strerror(errno
));
564 fsp
->fsp_flags
.kernel_share_modes_taken
= false;
567 status
= parent_pathref(talloc_tos(),
572 if (!NT_STATUS_IS_OK(status
)) {
576 ret
= SMB_VFS_UNLINKAT(conn
,
580 TALLOC_FREE(parent_fname
);
584 * This call can potentially fail as another smbd may
585 * have had the file open with delete on close set and
586 * deleted it when its last reference to this file
587 * went away. Hence we log this but not at debug level
591 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
592 "was set and unlink failed with error %s\n",
593 fsp_str_dbg(fsp
), strerror(errno
)));
595 status
= map_nt_error_from_unix(errno
);
598 /* As we now have POSIX opens which can unlink
599 * with other open files we may have taken
600 * this code path with more than one share mode
601 * entry - ensure we only delete once by resetting
602 * the delete on close flag. JRA.
605 fsp
->fsp_flags
.delete_on_close
= false;
606 lck_state
.reset_delete_on_close
= true;
615 if (fsp
->fsp_flags
.kernel_share_modes_taken
) {
616 /* remove filesystem sharemodes */
617 ret
= SMB_VFS_FILESYSTEM_SHAREMODE(fsp
, 0, 0);
619 DBG_INFO("Removing file system sharemode for "
621 fsp_str_dbg(fsp
), strerror(errno
));
625 ulstatus
= share_mode_entry_prepare_unlock(&lck_state
.prepare_state
,
626 lck_state
.cleanup_fn
,
628 if (!NT_STATUS_IS_OK(ulstatus
)) {
629 DBG_ERR("share_mode_entry_prepare_unlock() failed for %s - %s\n",
630 fsp_str_dbg(fsp
), nt_errstr(ulstatus
));
631 smb_panic("share_mode_entry_prepare_unlock() failed!");
634 if (lck_state
.delete_object
) {
636 * Do the notification after we released the share
637 * mode lock. Inside notify_fname we take out another
638 * tdb lock. With ctdb also accessing our databases,
639 * this can lead to deadlocks. Putting this notify
640 * after the TALLOC_FREE(lck) above we avoid locking
641 * two records simultaneously. Notifies are async and
642 * informational only, so calling the notify_fname
643 * without holding the share mode lock should not do
646 notify_fname(conn
, NOTIFY_ACTION_REMOVED
,
647 FILE_NOTIFY_CHANGE_FILE_NAME
,
648 fsp
->fsp_name
->base_name
);
654 void set_close_write_time(struct files_struct
*fsp
, struct timespec ts
)
656 DEBUG(6,("close_write_time: %s" , time_to_asc(convert_timespec_to_time_t(ts
))));
658 if (is_omit_timespec(&ts
)) {
661 fsp
->fsp_flags
.write_time_forced
= false;
662 fsp
->fsp_flags
.update_write_time_on_close
= true;
663 fsp
->close_write_time
= ts
;
666 static void update_write_time_on_close_share_mode_fn(struct share_mode_lock
*lck
,
669 struct files_struct
*fsp
=
670 talloc_get_type_abort(private_data
,
671 struct files_struct
);
672 NTTIME share_mtime
= share_mode_changed_write_time(lck
);
675 * On close if we're changing the real file time we
676 * must update it in the open file db too.
678 share_mode_set_old_write_time(lck
, fsp
->close_write_time
);
681 * Close write times overwrite sticky write times
682 * so we must replace any sticky write time here.
684 if (!null_nttime(share_mtime
)) {
685 share_mode_set_changed_write_time(lck
, fsp
->close_write_time
);
689 static NTSTATUS
update_write_time_on_close(struct files_struct
*fsp
)
691 struct smb_file_time ft
;
694 init_smb_file_time(&ft
);
696 if (!(fsp
->fsp_flags
.update_write_time_on_close
)) {
700 if (is_omit_timespec(&fsp
->close_write_time
)) {
701 fsp
->close_write_time
= timespec_current();
704 /* Ensure we have a valid stat struct for the source. */
705 status
= vfs_stat_fsp(fsp
);
706 if (!NT_STATUS_IS_OK(status
)) {
710 if (!VALID_STAT(fsp
->fsp_name
->st
)) {
711 /* if it doesn't seem to be a real file */
716 * We're being called after close_remove_share_mode() inside
717 * close_normal_file() so it's quite normal to not have an
718 * existing share. So just ignore the result of
719 * share_mode_do_locked_vfs_denied()...
721 share_mode_do_locked_vfs_denied(fsp
->file_id
,
722 update_write_time_on_close_share_mode_fn
,
725 ft
.mtime
= fsp
->close_write_time
;
726 /* As this is a close based update, we are not directly changing the
727 file attributes from a client call, but indirectly from a write. */
728 status
= smb_set_file_time(fsp
->conn
, fsp
, fsp
->fsp_name
, &ft
, false);
729 if (!NT_STATUS_IS_OK(status
)) {
730 DEBUG(10,("update_write_time_on_close: smb_set_file_time "
731 "on file %s returned %s\n",
740 static NTSTATUS
ntstatus_keeperror(NTSTATUS s1
, NTSTATUS s2
)
742 if (!NT_STATUS_IS_OK(s1
)) {
748 static void assert_no_pending_aio(struct files_struct
*fsp
,
749 enum file_close_type close_type
)
751 struct smbXsrv_client
*client
= global_smbXsrv_client
;
752 size_t num_connections_alive
;
753 unsigned num_requests
= fsp
->num_aio_requests
;
755 if (num_requests
== 0) {
759 num_connections_alive
= smbXsrv_client_valid_connections(client
);
761 if (close_type
== SHUTDOWN_CLOSE
&& num_connections_alive
== 0) {
763 * fsp->aio_requests and the contents (fsp->aio_requests[x])
764 * are both independently owned by fsp and are not in a
765 * talloc heirarchy. This allows the fsp->aio_requests array to
766 * be reallocated independently of the array contents so it can
769 * This means we must ensure order of deallocation
770 * on a SHUTDOWN_CLOSE by deallocating the fsp->aio_requests[x]
771 * contents first, as their destructors access the
772 * fsp->aio_request array. If we don't deallocate them
773 * first, when fsp is deallocated fsp->aio_requests
774 * could have been deallocated *before* its contents
775 * fsp->aio_requests[x], causing a crash.
777 while (fsp
->num_aio_requests
!= 0) {
780 * talloc_free(fsp->aio_requests[0]),
781 * and *NOT* TALLOC_FREE() here, as
782 * TALLOC_FREE(fsp->aio_requests[0])
783 * will overwrite any new contents of
784 * fsp->aio_requests[0] that were
785 * copied into it via the destructor
786 * aio_del_req_from_fsp().
788 * BUG: https://bugzilla.samba.org/show_bug.cgi?id=14515
790 talloc_free(fsp
->aio_requests
[0]);
795 DBG_ERR("fsp->num_aio_requests=%u\n", num_requests
);
796 smb_panic("can not close with outstanding aio requests");
800 /****************************************************************************
803 close_type can be NORMAL_CLOSE=0,SHUTDOWN_CLOSE,ERROR_CLOSE.
804 printing and magic scripts are only run on normal close.
805 delete on close is done on normal and shutdown close.
806 ****************************************************************************/
808 static NTSTATUS
close_normal_file(struct smb_request
*req
, files_struct
*fsp
,
809 enum file_close_type close_type
)
811 NTSTATUS status
= NT_STATUS_OK
;
813 connection_struct
*conn
= fsp
->conn
;
814 bool is_durable
= false;
816 SMB_ASSERT(fsp
->fsp_flags
.is_fsa
);
818 assert_no_pending_aio(fsp
, close_type
);
820 while (talloc_array_length(fsp
->blocked_smb1_lock_reqs
) != 0) {
821 smbd_smb1_brl_finish_by_req(
822 fsp
->blocked_smb1_lock_reqs
[0],
823 NT_STATUS_RANGE_NOT_LOCKED
);
827 * If we're flushing on a close we can get a write
828 * error here, we must remember this.
831 if (NT_STATUS_IS_OK(status
) && fsp
->op
!= NULL
) {
832 is_durable
= fsp
->op
->global
->durable
;
835 if (close_type
!= SHUTDOWN_CLOSE
) {
840 DATA_BLOB new_cookie
= data_blob_null
;
842 tmp
= SMB_VFS_DURABLE_DISCONNECT(fsp
,
843 fsp
->op
->global
->backend_cookie
,
846 if (NT_STATUS_IS_OK(tmp
)) {
851 tv
= req
->request_time
;
853 tv
= timeval_current();
855 now
= timeval_to_nttime(&tv
);
857 data_blob_free(&fsp
->op
->global
->backend_cookie
);
858 fsp
->op
->global
->backend_cookie
= new_cookie
;
860 fsp
->op
->compat
= NULL
;
861 tmp
= smbXsrv_open_close(fsp
->op
, now
);
862 if (!NT_STATUS_IS_OK(tmp
)) {
863 DEBUG(1, ("Failed to update smbXsrv_open "
864 "record when disconnecting durable "
865 "handle for file %s: %s - "
866 "proceeding with normal close\n",
867 fsp_str_dbg(fsp
), nt_errstr(tmp
)));
869 scavenger_schedule_disconnected(fsp
);
871 DEBUG(1, ("Failed to disconnect durable handle for "
872 "file %s: %s - proceeding with normal "
873 "close\n", fsp_str_dbg(fsp
), nt_errstr(tmp
)));
875 if (!NT_STATUS_IS_OK(tmp
)) {
882 * This is the case where we successfully disconnected
883 * a durable handle and closed the underlying file.
884 * In all other cases, we proceed with a genuine close.
886 DEBUG(10, ("%s disconnected durable handle for file %s\n",
887 conn
->session_info
->unix_info
->unix_name
,
892 if (fsp
->op
!= NULL
) {
894 * Make sure the handle is not marked as durable anymore
896 fsp
->op
->global
->durable
= false;
899 /* If this is an old DOS or FCB open and we have multiple opens on
900 the same handle we only have one share mode. Ensure we only remove
901 the share mode on the last close. */
903 if (fh_get_refcount(fsp
->fh
) == 1) {
904 /* Should we return on error here... ? */
905 tmp
= close_remove_share_mode(fsp
, close_type
);
906 status
= ntstatus_keeperror(status
, tmp
);
909 locking_close_file(fsp
, close_type
);
912 * Ensure pending modtime is set before closing underlying fd.
915 tmp
= update_write_time_on_close(fsp
);
916 if (NT_STATUS_EQUAL(tmp
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
918 * Someone renamed the file or a parent directory containing
919 * this file. We can't do anything about this, eat the error.
923 status
= ntstatus_keeperror(status
, tmp
);
926 status
= ntstatus_keeperror(status
, tmp
);
928 /* check for magic scripts */
929 if (close_type
== NORMAL_CLOSE
) {
930 tmp
= check_magic(fsp
);
931 status
= ntstatus_keeperror(status
, tmp
);
934 DEBUG(2,("%s closed file %s (numopen=%d) %s\n",
935 conn
->session_info
->unix_info
->unix_name
, fsp_str_dbg(fsp
),
936 conn
->num_files_open
- 1,
937 nt_errstr(status
) ));
941 /****************************************************************************
942 Function used by reply_rmdir to delete an entire directory
943 tree recursively. Return True on ok, False on fail.
944 ****************************************************************************/
946 NTSTATUS
recursive_rmdir(TALLOC_CTX
*ctx
,
947 connection_struct
*conn
,
948 struct smb_filename
*smb_dname
)
950 const char *dname
= NULL
;
951 char *talloced
= NULL
;
952 struct smb_Dir
*dir_hnd
= NULL
;
953 struct files_struct
*dirfsp
= NULL
;
955 NTSTATUS status
= NT_STATUS_OK
;
957 SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname
));
959 status
= OpenDir(talloc_tos(),
965 if (!NT_STATUS_IS_OK(status
)) {
969 dirfsp
= dir_hnd_fetch_fsp(dir_hnd
);
971 while ((dname
= ReadDirName(dir_hnd
, &talloced
))) {
972 struct smb_filename
*atname
= NULL
;
973 struct smb_filename
*smb_dname_full
= NULL
;
974 char *fullname
= NULL
;
975 bool do_break
= true;
976 int unlink_flags
= 0;
978 if (ISDOT(dname
) || ISDOTDOT(dname
)) {
979 TALLOC_FREE(talloced
);
983 /* Construct the full name. */
984 fullname
= talloc_asprintf(ctx
,
986 smb_dname
->base_name
,
989 status
= NT_STATUS_NO_MEMORY
;
993 smb_dname_full
= synthetic_smb_fname(talloc_tos(),
999 if (smb_dname_full
== NULL
) {
1000 status
= NT_STATUS_NO_MEMORY
;
1004 if (SMB_VFS_LSTAT(conn
, smb_dname_full
) != 0) {
1005 status
= map_nt_error_from_unix(errno
);
1009 if (smb_dname_full
->st
.st_ex_mode
& S_IFDIR
) {
1010 status
= recursive_rmdir(ctx
, conn
, smb_dname_full
);
1011 if (!NT_STATUS_IS_OK(status
)) {
1014 unlink_flags
= AT_REMOVEDIR
;
1017 status
= synthetic_pathref(talloc_tos(),
1021 &smb_dname_full
->st
,
1022 smb_dname_full
->twrp
,
1023 smb_dname_full
->flags
,
1025 if (!NT_STATUS_IS_OK(status
)) {
1029 if (!is_visible_fsp(atname
->fsp
)) {
1030 TALLOC_FREE(smb_dname_full
);
1031 TALLOC_FREE(fullname
);
1032 TALLOC_FREE(talloced
);
1033 TALLOC_FREE(atname
);
1037 retval
= SMB_VFS_UNLINKAT(conn
,
1042 status
= map_nt_error_from_unix(errno
);
1046 /* Successful iteration. */
1050 TALLOC_FREE(smb_dname_full
);
1051 TALLOC_FREE(fullname
);
1052 TALLOC_FREE(talloced
);
1053 TALLOC_FREE(atname
);
1058 TALLOC_FREE(dir_hnd
);
1062 /****************************************************************************
1063 The internals of the rmdir code - called elsewhere.
1064 ****************************************************************************/
1066 static NTSTATUS
rmdir_internals(TALLOC_CTX
*ctx
, struct files_struct
*fsp
)
1068 struct connection_struct
*conn
= fsp
->conn
;
1069 struct smb_filename
*smb_dname
= fsp
->fsp_name
;
1070 struct smb_filename
*parent_fname
= NULL
;
1071 struct smb_filename
*at_fname
= NULL
;
1072 const char *dname
= NULL
;
1073 char *talloced
= NULL
;
1074 struct smb_Dir
*dir_hnd
= NULL
;
1075 struct files_struct
*dirfsp
= NULL
;
1076 int unlink_flags
= 0;
1080 SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname
));
1082 status
= parent_pathref(talloc_tos(),
1087 if (!NT_STATUS_IS_OK(status
)) {
1092 * Todo: use SMB_VFS_STATX() once it's available.
1095 /* Might be a symlink. */
1096 ret
= SMB_VFS_LSTAT(conn
, smb_dname
);
1098 TALLOC_FREE(parent_fname
);
1099 return map_nt_error_from_unix(errno
);
1102 if (S_ISLNK(smb_dname
->st
.st_ex_mode
)) {
1103 /* Is what it points to a directory ? */
1104 ret
= SMB_VFS_STAT(conn
, smb_dname
);
1106 TALLOC_FREE(parent_fname
);
1107 return map_nt_error_from_unix(errno
);
1109 if (!(S_ISDIR(smb_dname
->st
.st_ex_mode
))) {
1110 TALLOC_FREE(parent_fname
);
1111 return NT_STATUS_NOT_A_DIRECTORY
;
1114 unlink_flags
= AT_REMOVEDIR
;
1117 ret
= SMB_VFS_UNLINKAT(conn
,
1122 TALLOC_FREE(parent_fname
);
1123 notify_fname(conn
, NOTIFY_ACTION_REMOVED
,
1124 FILE_NOTIFY_CHANGE_DIR_NAME
,
1125 smb_dname
->base_name
);
1126 return NT_STATUS_OK
;
1129 if (!((errno
== ENOTEMPTY
) || (errno
== EEXIST
))) {
1130 DEBUG(3,("rmdir_internals: couldn't remove directory %s : "
1131 "%s\n", smb_fname_str_dbg(smb_dname
),
1133 TALLOC_FREE(parent_fname
);
1134 return map_nt_error_from_unix(errno
);
1138 * Here we know the initial directory unlink failed with
1139 * ENOTEMPTY or EEXIST so we know there are objects within.
1140 * If we don't have permission to delete files non
1141 * visible to the client just fail the directory delete.
1144 if (!lp_delete_veto_files(SNUM(conn
))) {
1145 status
= NT_STATUS_DIRECTORY_NOT_EMPTY
;
1150 * Check to see if the only thing in this directory are
1151 * files non-visible to the client. If not, fail the delete.
1154 status
= OpenDir(talloc_tos(),
1160 if (!NT_STATUS_IS_OK(status
)) {
1162 * Note, we deliberately squash the error here
1163 * to avoid leaking information about what we
1166 status
= NT_STATUS_DIRECTORY_NOT_EMPTY
;
1170 dirfsp
= dir_hnd_fetch_fsp(dir_hnd
);
1172 while ((dname
= ReadDirName(dir_hnd
, &talloced
)) != NULL
) {
1173 struct smb_filename
*smb_dname_full
= NULL
;
1174 struct smb_filename
*direntry_fname
= NULL
;
1175 char *fullname
= NULL
;
1178 if (ISDOT(dname
) || ISDOTDOT(dname
)) {
1179 TALLOC_FREE(talloced
);
1182 if (IS_VETO_PATH(conn
, dname
)) {
1183 TALLOC_FREE(talloced
);
1187 fullname
= talloc_asprintf(talloc_tos(),
1189 smb_dname
->base_name
,
1192 if (fullname
== NULL
) {
1193 TALLOC_FREE(talloced
);
1194 status
= NT_STATUS_NO_MEMORY
;
1198 smb_dname_full
= synthetic_smb_fname(talloc_tos(),
1204 if (smb_dname_full
== NULL
) {
1205 TALLOC_FREE(talloced
);
1206 TALLOC_FREE(fullname
);
1207 status
= NT_STATUS_NO_MEMORY
;
1211 retval
= SMB_VFS_LSTAT(conn
, smb_dname_full
);
1213 status
= map_nt_error_from_unix(errno
);
1214 TALLOC_FREE(talloced
);
1215 TALLOC_FREE(fullname
);
1216 TALLOC_FREE(smb_dname_full
);
1220 if (S_ISLNK(smb_dname_full
->st
.st_ex_mode
)) {
1221 /* Could it be an msdfs link ? */
1222 if (lp_host_msdfs() &&
1223 lp_msdfs_root(SNUM(conn
))) {
1224 struct smb_filename
*smb_atname
;
1225 smb_atname
= synthetic_smb_fname(talloc_tos(),
1228 &smb_dname_full
->st
,
1229 fsp
->fsp_name
->twrp
,
1230 fsp
->fsp_name
->flags
);
1231 if (smb_atname
== NULL
) {
1232 TALLOC_FREE(talloced
);
1233 TALLOC_FREE(fullname
);
1234 TALLOC_FREE(smb_dname_full
);
1235 status
= NT_STATUS_NO_MEMORY
;
1238 if (is_msdfs_link(fsp
, smb_atname
)) {
1239 TALLOC_FREE(talloced
);
1240 TALLOC_FREE(fullname
);
1241 TALLOC_FREE(smb_dname_full
);
1242 TALLOC_FREE(smb_atname
);
1243 DBG_DEBUG("got msdfs link name %s "
1244 "- can't delete directory %s\n",
1247 status
= NT_STATUS_DIRECTORY_NOT_EMPTY
;
1250 TALLOC_FREE(smb_atname
);
1253 /* Not a DFS link - could it be a dangling symlink ? */
1254 retval
= SMB_VFS_STAT(conn
, smb_dname_full
);
1255 if (retval
== -1 && (errno
== ENOENT
|| errno
== ELOOP
)) {
1258 * Allow delete as "delete veto files = yes"
1260 TALLOC_FREE(talloced
);
1261 TALLOC_FREE(fullname
);
1262 TALLOC_FREE(smb_dname_full
);
1266 DBG_DEBUG("got symlink name %s - "
1267 "can't delete directory %s\n",
1270 TALLOC_FREE(talloced
);
1271 TALLOC_FREE(fullname
);
1272 TALLOC_FREE(smb_dname_full
);
1273 status
= NT_STATUS_DIRECTORY_NOT_EMPTY
;
1277 /* Not a symlink, get a pathref. */
1278 status
= synthetic_pathref(talloc_tos(),
1282 &smb_dname_full
->st
,
1286 if (!NT_STATUS_IS_OK(status
)) {
1287 TALLOC_FREE(talloced
);
1288 TALLOC_FREE(fullname
);
1289 TALLOC_FREE(smb_dname_full
);
1293 if (!is_visible_fsp(direntry_fname
->fsp
)) {
1294 TALLOC_FREE(talloced
);
1295 TALLOC_FREE(fullname
);
1296 TALLOC_FREE(smb_dname_full
);
1297 TALLOC_FREE(direntry_fname
);
1302 * We found a client visible name.
1303 * We cannot delete this directory.
1305 DBG_DEBUG("got name %s - "
1306 "can't delete directory %s\n",
1309 TALLOC_FREE(talloced
);
1310 TALLOC_FREE(fullname
);
1311 TALLOC_FREE(smb_dname_full
);
1312 TALLOC_FREE(direntry_fname
);
1313 status
= NT_STATUS_DIRECTORY_NOT_EMPTY
;
1317 /* Do a recursive delete. */
1320 while ((dname
= ReadDirName(dir_hnd
, &talloced
)) != NULL
) {
1321 struct smb_filename
*direntry_fname
= NULL
;
1322 struct smb_filename
*smb_dname_full
= NULL
;
1323 char *fullname
= NULL
;
1324 bool do_break
= true;
1327 if (ISDOT(dname
) || ISDOTDOT(dname
)) {
1328 TALLOC_FREE(talloced
);
1332 fullname
= talloc_asprintf(ctx
,
1334 smb_dname
->base_name
,
1337 if (fullname
== NULL
) {
1338 status
= NT_STATUS_NO_MEMORY
;
1342 smb_dname_full
= synthetic_smb_fname(talloc_tos(),
1348 if (smb_dname_full
== NULL
) {
1349 status
= NT_STATUS_NO_MEMORY
;
1354 * Todo: use SMB_VFS_STATX() once that's available.
1357 retval
= SMB_VFS_LSTAT(conn
, smb_dname_full
);
1359 status
= map_nt_error_from_unix(errno
);
1364 * We are only dealing with VETO'ed objects
1365 * here. If it's a symlink, just delete the
1366 * link without caring what it is pointing
1369 if (S_ISLNK(smb_dname_full
->st
.st_ex_mode
)) {
1370 direntry_fname
= synthetic_smb_fname(talloc_tos(),
1373 &smb_dname_full
->st
,
1376 if (direntry_fname
== NULL
) {
1377 status
= NT_STATUS_NO_MEMORY
;
1381 status
= synthetic_pathref(talloc_tos(),
1385 &smb_dname_full
->st
,
1389 if (!NT_STATUS_IS_OK(status
)) {
1393 if (!is_visible_fsp(direntry_fname
->fsp
)) {
1394 TALLOC_FREE(fullname
);
1395 TALLOC_FREE(smb_dname_full
);
1396 TALLOC_FREE(talloced
);
1397 TALLOC_FREE(direntry_fname
);
1404 if (smb_dname_full
->st
.st_ex_mode
& S_IFDIR
) {
1405 status
= recursive_rmdir(ctx
, conn
, smb_dname_full
);
1406 if (!NT_STATUS_IS_OK(status
)) {
1409 unlink_flags
= AT_REMOVEDIR
;
1412 retval
= SMB_VFS_UNLINKAT(conn
,
1417 status
= map_nt_error_from_unix(errno
);
1421 /* Successful iteration. */
1425 TALLOC_FREE(fullname
);
1426 TALLOC_FREE(smb_dname_full
);
1427 TALLOC_FREE(talloced
);
1428 TALLOC_FREE(direntry_fname
);
1434 /* If we get here, we know NT_STATUS_IS_OK(status) */
1435 SMB_ASSERT(NT_STATUS_IS_OK(status
));
1437 /* Retry the rmdir */
1438 ret
= SMB_VFS_UNLINKAT(conn
,
1443 status
= map_nt_error_from_unix(errno
);
1448 TALLOC_FREE(dir_hnd
);
1449 TALLOC_FREE(parent_fname
);
1451 if (!NT_STATUS_IS_OK(status
)) {
1452 DBG_NOTICE("couldn't remove directory %s : "
1453 "%s\n", smb_fname_str_dbg(smb_dname
),
1458 notify_fname(conn
, NOTIFY_ACTION_REMOVED
,
1459 FILE_NOTIFY_CHANGE_DIR_NAME
,
1460 smb_dname
->base_name
);
1465 /****************************************************************************
1466 Close a directory opened by an NT SMB call.
1467 ****************************************************************************/
1469 static NTSTATUS
close_directory(struct smb_request
*req
, files_struct
*fsp
,
1470 enum file_close_type close_type
)
1472 connection_struct
*conn
= fsp
->conn
;
1473 struct close_share_mode_lock_state lck_state
= {};
1474 bool changed_user
= false;
1475 NTSTATUS status
= NT_STATUS_OK
;
1476 NTSTATUS status1
= NT_STATUS_OK
;
1477 NTSTATUS notify_status
;
1480 SMB_ASSERT(fsp
->fsp_flags
.is_fsa
);
1482 if (fsp
->conn
->sconn
->using_smb2
) {
1483 notify_status
= NT_STATUS_NOTIFY_CLEANUP
;
1485 notify_status
= NT_STATUS_OK
;
1488 assert_no_pending_aio(fsp
, close_type
);
1491 * NT can set delete_on_close of the last open
1492 * reference to a directory also.
1495 lck_state
= (struct close_share_mode_lock_state
) {
1497 .object_type
= "directory",
1498 .close_type
= close_type
,
1501 status
= share_mode_entry_prepare_lock_del(&lck_state
.prepare_state
,
1503 close_share_mode_lock_prepare
,
1505 if (!NT_STATUS_IS_OK(status
)) {
1506 DBG_ERR("share_mode_entry_prepare_lock_del() failed for %s - %s\n",
1507 fsp_str_dbg(fsp
), nt_errstr(status
));
1512 * We don't have directory leases yet, so assert it in order
1513 * to skip release_file_oplock().
1515 SMB_ASSERT(fsp
->oplock_type
== NO_OPLOCK
);
1518 * NT can set delete_on_close of the last open
1519 * reference to a file.
1522 if (!lck_state
.delete_object
) {
1523 status
= NT_STATUS_OK
;
1528 * Ok, we have to delete the directory
1530 lck_state
.cleanup_fn
= close_share_mode_lock_cleanup
;
1532 if (lck_state
.got_tokens
&&
1533 !unix_token_equal(lck_state
.del_token
, get_current_utok(conn
)))
1535 /* Become the user who requested the delete. */
1537 DBG_INFO("dir %s. Change user to uid %u\n",
1539 (unsigned int)lck_state
.del_token
->uid
);
1541 if (!push_sec_ctx()) {
1542 smb_panic("close_directory: failed to push sec_ctx.\n");
1545 set_sec_ctx(lck_state
.del_token
->uid
,
1546 lck_state
.del_token
->gid
,
1547 lck_state
.del_token
->ngroups
,
1548 lck_state
.del_token
->groups
,
1549 lck_state
.del_nt_token
);
1551 changed_user
= true;
1554 if ((fsp
->conn
->fs_capabilities
& FILE_NAMED_STREAMS
)
1555 && !is_ntfs_stream_smb_fname(fsp
->fsp_name
)) {
1557 status
= delete_all_streams(fsp
->conn
, fsp
->fsp_name
);
1558 if (!NT_STATUS_IS_OK(status
)) {
1559 DEBUG(5, ("delete_all_streams failed: %s\n",
1560 nt_errstr(status
)));
1565 status
= rmdir_internals(talloc_tos(), fsp
);
1567 DEBUG(5,("close_directory: %s. Delete on close was set - "
1568 "deleting directory returned %s.\n",
1569 fsp_str_dbg(fsp
), nt_errstr(status
)));
1572 * Ensure we remove any change notify requests that would
1573 * now fail as the directory has been deleted.
1576 if (NT_STATUS_IS_OK(status
)) {
1577 notify_status
= NT_STATUS_DELETE_PENDING
;
1582 /* unbecome user. */
1586 ulstatus
= share_mode_entry_prepare_unlock(&lck_state
.prepare_state
,
1587 lck_state
.cleanup_fn
,
1589 if (!NT_STATUS_IS_OK(ulstatus
)) {
1590 DBG_ERR("share_mode_entry_prepare_unlock() failed for %s - %s\n",
1591 fsp_str_dbg(fsp
), nt_errstr(ulstatus
));
1592 smb_panic("share_mode_entry_prepare_unlock() failed!");
1595 remove_pending_change_notify_requests_by_fid(fsp
, notify_status
);
1597 status1
= fd_close(fsp
);
1599 if (!NT_STATUS_IS_OK(status1
)) {
1600 DEBUG(0, ("Could not close dir! fname=%s, fd=%d, err=%d=%s\n",
1601 fsp_str_dbg(fsp
), fsp_get_pathref_fd(fsp
), errno
,
1605 if (NT_STATUS_IS_OK(status
) && !NT_STATUS_IS_OK(status1
)) {
1611 /****************************************************************************
1612 Rundown all SMB-related dependencies of a files struct
1613 ****************************************************************************/
1615 NTSTATUS
close_file_smb(struct smb_request
*req
,
1616 struct files_struct
*fsp
,
1617 enum file_close_type close_type
)
1622 * This fsp can never be an internal dirfsp. They must
1623 * be explicitly closed by TALLOC_FREE of the dir handle.
1625 SMB_ASSERT(!fsp
->fsp_flags
.is_dirfsp
);
1628 * Never call directly on a base fsp
1630 SMB_ASSERT(fsp
->stream_fsp
== NULL
);
1632 if (fsp
->fake_file_handle
!= NULL
) {
1633 status
= close_fake_file(req
, fsp
);
1634 } else if (fsp
->print_file
!= NULL
) {
1635 /* FIXME: return spool errors */
1636 print_spool_end(fsp
, close_type
);
1638 status
= NT_STATUS_OK
;
1639 } else if (!fsp
->fsp_flags
.is_fsa
) {
1640 if (close_type
== NORMAL_CLOSE
) {
1641 DBG_ERR("unexpected NORMAL_CLOSE for [%s] "
1642 "is_fsa[%u] is_pathref[%u] is_directory[%u]\n",
1644 fsp
->fsp_flags
.is_fsa
,
1645 fsp
->fsp_flags
.is_pathref
,
1646 fsp
->fsp_flags
.is_directory
);
1648 SMB_ASSERT(close_type
!= NORMAL_CLOSE
);
1650 status
= NT_STATUS_OK
;
1651 } else if (fsp
->fsp_flags
.is_directory
) {
1652 status
= close_directory(req
, fsp
, close_type
);
1654 status
= close_normal_file(req
, fsp
, close_type
);
1657 if (fsp_is_alternate_stream(fsp
)) {
1659 * fsp was a stream, its base_fsp can't be a stream
1662 SMB_ASSERT(!fsp_is_alternate_stream(fsp
->base_fsp
));
1665 * There's a 1:1 relationship between fsp and a base_fsp
1667 SMB_ASSERT(fsp
->base_fsp
->stream_fsp
== fsp
);
1670 * Make base_fsp look standalone now
1672 fsp
->base_fsp
->stream_fsp
= NULL
;
1674 close_file_free(req
, &fsp
->base_fsp
, close_type
);
1677 fsp_unbind_smb(req
, fsp
);
1682 NTSTATUS
close_file_free(struct smb_request
*req
,
1683 struct files_struct
**_fsp
,
1684 enum file_close_type close_type
)
1686 struct files_struct
*fsp
= *_fsp
;
1689 status
= close_file_smb(req
, fsp
, close_type
);
1691 file_free(req
, fsp
);
1697 /****************************************************************************
1698 Deal with an (authorized) message to close a file given the share mode
1700 ****************************************************************************/
1702 void msg_close_file(struct messaging_context
*msg_ctx
,
1705 struct server_id server_id
,
1708 files_struct
*fsp
= NULL
;
1710 struct share_mode_entry e
;
1711 struct smbd_server_connection
*sconn
=
1712 talloc_get_type_abort(private_data
,
1713 struct smbd_server_connection
);
1715 message_to_share_mode_entry(&id
, &e
, (char *)data
->data
);
1718 char *sm_str
= share_mode_str(NULL
, 0, &id
, &e
);
1720 smb_panic("talloc failed");
1722 DEBUG(10,("msg_close_file: got request to close share mode "
1723 "entry %s\n", sm_str
));
1724 TALLOC_FREE(sm_str
);
1727 fsp
= file_find_dif(sconn
, id
, e
.share_file_id
);
1729 DEBUG(10,("msg_close_file: failed to find file.\n"));
1732 close_file_free(NULL
, &fsp
, NORMAL_CLOSE
);