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 /****************************************************************************
278 Deal with removing a share mode on last close.
279 ****************************************************************************/
281 static NTSTATUS close_remove_share_mode(files_struct *fsp,
282 enum file_close_type close_type)
284 connection_struct *conn = fsp->conn;
285 bool delete_file = false;
286 bool changed_user = false;
287 struct share_mode_lock *lck = NULL;
288 NTSTATUS status = NT_STATUS_OK;
291 const struct security_unix_token *del_token = NULL;
292 const struct security_token *del_nt_token = NULL;
293 struct smb_filename *parent_fname = NULL;
294 struct smb_filename *base_fname = NULL;
295 bool got_tokens = false;
299 /* Ensure any pending write time updates are done. */
300 if (fsp->update_write_time_event) {
301 fsp_flush_write_time_update(fsp);
305 * Lock the share entries, and determine if we should delete
306 * on close. If so delete whilst the lock is still in effect.
307 * This prevents race conditions with the file being created. JRA.
310 lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
312 DEBUG(0, ("close_remove_share_mode: Could not get share mode "
313 "lock for file %s\n", fsp_str_dbg(fsp)));
314 return NT_STATUS_INVALID_PARAMETER;
317 /* Remove the oplock before potentially deleting the file. */
318 if(fsp->oplock_type) {
322 if (fsp->fsp_flags.write_time_forced) {
323 NTTIME mtime = share_mode_changed_write_time(lck);
324 struct timespec ts = nt_time_to_full_timespec(mtime);
326 DEBUG(10,("close_remove_share_mode: write time forced "
329 set_close_write_time(fsp, ts);
330 } else if (fsp->fsp_flags.update_write_time_on_close) {
331 /* Someone had a pending write. */
332 if (is_omit_timespec(&fsp->close_write_time)) {
333 DEBUG(10,("close_remove_share_mode: update to current time "
336 /* Update to current time due to "normal" write. */
337 set_close_write_time(fsp, timespec_current());
339 DEBUG(10,("close_remove_share_mode: write time pending "
342 /* Update to time set on close call. */
343 set_close_write_time(fsp, fsp->close_write_time);
347 if (fsp->fsp_flags.initial_delete_on_close &&
348 !is_delete_on_close_set(lck, fsp->name_hash)) {
349 /* Initial delete on close was set and no one else
350 * wrote a real delete on close. */
352 fsp->fsp_flags.delete_on_close = true;
353 set_delete_on_close_lck(fsp, lck,
354 fsp->conn->session_info->security_token,
355 fsp->conn->session_info->unix_token);
358 delete_file = is_delete_on_close_set(lck, fsp->name_hash) &&
359 !has_other_nonposix_opens(lck, fsp);
362 * NT can set delete_on_close of the last open
363 * reference to a file.
366 normal_close = (close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE);
368 if (!normal_close || !delete_file) {
369 status = NT_STATUS_OK;
374 * Ok, we have to delete the file
377 DEBUG(5,("close_remove_share_mode: file %s. Delete on close was set "
378 "- deleting file.\n", fsp_str_dbg(fsp)));
381 * Don't try to update the write time when we delete the file
383 fsp->fsp_flags.update_write_time_on_close = false;
385 got_tokens = get_delete_on_close_token(lck, fsp->name_hash,
386 &del_nt_token, &del_token);
387 SMB_ASSERT(got_tokens);
389 if (!unix_token_equal(del_token, get_current_utok(conn))) {
390 /* Become the user who requested the delete. */
392 DEBUG(5,("close_remove_share_mode: file %s. "
393 "Change user to uid %u\n",
395 (unsigned int)del_token->uid));
397 if (!push_sec_ctx()) {
398 smb_panic("close_remove_share_mode: file %s. failed to push "
402 set_sec_ctx(del_token->uid,
411 /* We can only delete the file if the name we have is still valid and
412 hasn't been renamed. */
414 tmp_status = vfs_stat_fsp(fsp);
415 if (!NT_STATUS_IS_OK(tmp_status)) {
416 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
417 "was set and stat failed with error %s\n",
418 fsp_str_dbg(fsp), nt_errstr(tmp_status)));
420 * Don't save the errno here, we ignore this error
425 id = vfs_file_id_from_sbuf(conn, &fsp->fsp_name->st);
427 if (!file_id_equal(&fsp->file_id, &id)) {
428 struct file_id_buf ftmp1, ftmp2;
429 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
430 "was set and dev and/or inode does not match\n",
432 DEBUG(5,("close_remove_share_mode: file %s. stored file_id %s, "
435 file_id_str_buf(fsp->file_id, &ftmp1),
436 file_id_str_buf(id, &ftmp2)));
438 * Don't save the errno here, we ignore this error
443 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
444 && !is_ntfs_stream_smb_fname(fsp->fsp_name)) {
446 status = delete_all_streams(conn, fsp->fsp_name);
448 if (!NT_STATUS_IS_OK(status)) {
449 DEBUG(5, ("delete_all_streams failed: %s\n",
455 if (fsp->fsp_flags.kernel_share_modes_taken) {
457 * A file system sharemode could block the unlink;
458 * remove filesystem sharemodes first.
460 ret = SMB_VFS_FILESYSTEM_SHAREMODE(fsp, 0, 0);
462 DBG_INFO("Removing file system sharemode for %s "
464 fsp_str_dbg(fsp), strerror(errno));
467 fsp->fsp_flags.kernel_share_modes_taken = false;
470 status = parent_pathref(talloc_tos(),
475 if (!NT_STATUS_IS_OK(status)) {
479 ret = SMB_VFS_UNLINKAT(conn,
483 TALLOC_FREE(parent_fname);
487 * This call can potentially fail as another smbd may
488 * have had the file open with delete on close set and
489 * deleted it when its last reference to this file
490 * went away. Hence we log this but not at debug level
494 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
495 "was set and unlink failed with error %s\n",
496 fsp_str_dbg(fsp), strerror(errno)));
498 status = map_nt_error_from_unix(errno);
501 /* As we now have POSIX opens which can unlink
502 * with other open files we may have taken
503 * this code path with more than one share mode
504 * entry - ensure we only delete once by resetting
505 * the delete on close flag. JRA.
508 fsp->fsp_flags.delete_on_close = false;
509 reset_delete_on_close_lck(fsp, lck);
518 if (fsp->fsp_flags.kernel_share_modes_taken) {
519 /* remove filesystem sharemodes */
520 ret = SMB_VFS_FILESYSTEM_SHAREMODE(fsp, 0, 0);
522 DBG_INFO("Removing file system sharemode for "
524 fsp_str_dbg(fsp), strerror(errno));
528 if (!del_share_mode(lck, fsp)) {
529 DEBUG(0, ("close_remove_share_mode: Could not delete share "
530 "entry for file %s\n", fsp_str_dbg(fsp)));
537 * Do the notification after we released the share
538 * mode lock. Inside notify_fname we take out another
539 * tdb lock. With ctdb also accessing our databases,
540 * this can lead to deadlocks. Putting this notify
541 * after the TALLOC_FREE(lck) above we avoid locking
542 * two records simultaneously. Notifies are async and
543 * informational only, so calling the notify_fname
544 * without holding the share mode lock should not do
547 notify_fname(conn, NOTIFY_ACTION_REMOVED,
548 FILE_NOTIFY_CHANGE_FILE_NAME,
549 fsp->fsp_name->base_name);
555 void set_close_write_time(struct files_struct *fsp, struct timespec ts)
557 DEBUG(6,("close_write_time: %s" , time_to_asc(convert_timespec_to_time_t(ts))));
559 if (is_omit_timespec(&ts)) {
562 fsp->fsp_flags.write_time_forced = false;
563 fsp->fsp_flags.update_write_time_on_close = true;
564 fsp->close_write_time = ts;
567 static NTSTATUS update_write_time_on_close(struct files_struct *fsp)
569 struct smb_file_time ft;
571 struct share_mode_lock *lck = NULL;
573 init_smb_file_time(&ft);
575 if (!(fsp->fsp_flags.update_write_time_on_close)) {
579 if (is_omit_timespec(&fsp->close_write_time)) {
580 fsp->close_write_time = timespec_current();
583 /* Ensure we have a valid stat struct for the source. */
584 status = vfs_stat_fsp(fsp);
585 if (!NT_STATUS_IS_OK(status)) {
589 if (!VALID_STAT(fsp->fsp_name->st)) {
590 /* if it doesn't seem to be a real file */
595 * get_existing_share_mode_lock() isn't really the right
596 * call here, as we're being called after
597 * close_remove_share_mode() inside close_normal_file()
598 * so it's quite normal to not have an existing share
599 * mode here. However, get_share_mode_lock() doesn't
600 * work because that will create a new share mode if
601 * one doesn't exist - so stick with this call (just
602 * ignore any error we get if the share mode doesn't
606 lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
608 NTTIME share_mtime = share_mode_changed_write_time(lck);
609 /* On close if we're changing the real file time we
610 * must update it in the open file db too. */
611 (void)set_write_time(fsp->file_id, fsp->close_write_time);
613 /* Close write times overwrite sticky write times
614 so we must replace any sticky write time here. */
615 if (!null_nttime(share_mtime)) {
616 (void)set_sticky_write_time(fsp->file_id, fsp->close_write_time);
621 ft.mtime = fsp->close_write_time;
622 /* As this is a close based update, we are not directly changing the
623 file attributes from a client call, but indirectly from a write. */
624 status = smb_set_file_time(fsp->conn, fsp, fsp->fsp_name, &ft, false);
625 if (!NT_STATUS_IS_OK(status)) {
626 DEBUG(10,("update_write_time_on_close: smb_set_file_time "
627 "on file %s returned %s\n",
636 static NTSTATUS ntstatus_keeperror(NTSTATUS s1, NTSTATUS s2)
638 if (!NT_STATUS_IS_OK(s1)) {
644 static void assert_no_pending_aio(struct files_struct *fsp,
645 enum file_close_type close_type)
647 struct smbXsrv_client *client = global_smbXsrv_client;
648 size_t num_connections_alive;
649 unsigned num_requests = fsp->num_aio_requests;
651 if (num_requests == 0) {
655 num_connections_alive = smbXsrv_client_valid_connections(client);
657 if (close_type == SHUTDOWN_CLOSE && num_connections_alive == 0) {
659 * fsp->aio_requests and the contents (fsp->aio_requests[x])
660 * are both independently owned by fsp and are not in a
661 * talloc heirarchy. This allows the fsp->aio_requests array to
662 * be reallocated independently of the array contents so it can
665 * This means we must ensure order of deallocation
666 * on a SHUTDOWN_CLOSE by deallocating the fsp->aio_requests[x]
667 * contents first, as their destructors access the
668 * fsp->aio_request array. If we don't deallocate them
669 * first, when fsp is deallocated fsp->aio_requests
670 * could have been deallocated *before* its contents
671 * fsp->aio_requests[x], causing a crash.
673 while (fsp->num_aio_requests != 0) {
676 * talloc_free(fsp->aio_requests[0]),
677 * and *NOT* TALLOC_FREE() here, as
678 * TALLOC_FREE(fsp->aio_requests[0])
679 * will overwrite any new contents of
680 * fsp->aio_requests[0] that were
681 * copied into it via the destructor
682 * aio_del_req_from_fsp().
684 * BUG: https://bugzilla.samba.org/show_bug.cgi?id=14515
686 talloc_free(fsp->aio_requests[0]);
691 DBG_ERR("fsp->num_aio_requests=%u\n", num_requests);
692 smb_panic("can not close with outstanding aio requests");
696 /****************************************************************************
699 close_type can be NORMAL_CLOSE=0,SHUTDOWN_CLOSE,ERROR_CLOSE.
700 printing and magic scripts are only run on normal close.
701 delete on close is done on normal and shutdown close.
702 ****************************************************************************/
704 static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp,
705 enum file_close_type close_type)
707 NTSTATUS status = NT_STATUS_OK;
709 connection_struct *conn = fsp->conn;
710 bool is_durable = false;
712 SMB_ASSERT(fsp->fsp_flags.is_fsa);
714 assert_no_pending_aio(fsp, close_type);
716 while (talloc_array_length(fsp->blocked_smb1_lock_reqs) != 0) {
717 smbd_smb1_brl_finish_by_req(
718 fsp->blocked_smb1_lock_reqs[0],
719 NT_STATUS_RANGE_NOT_LOCKED);
723 * If we're flushing on a close we can get a write
724 * error here, we must remember this.
727 if (NT_STATUS_IS_OK(status) && fsp->op != NULL) {
728 is_durable = fsp->op->global->durable;
731 if (close_type != SHUTDOWN_CLOSE) {
736 DATA_BLOB new_cookie = data_blob_null;
738 tmp = SMB_VFS_DURABLE_DISCONNECT(fsp,
739 fsp->op->global->backend_cookie,
742 if (NT_STATUS_IS_OK(tmp)) {
747 tv = req->request_time;
749 tv = timeval_current();
751 now = timeval_to_nttime(&tv);
753 data_blob_free(&fsp->op->global->backend_cookie);
754 fsp->op->global->backend_cookie = new_cookie;
756 fsp->op->compat = NULL;
757 tmp = smbXsrv_open_close(fsp->op, now);
758 if (!NT_STATUS_IS_OK(tmp)) {
759 DEBUG(1, ("Failed to update smbXsrv_open "
760 "record when disconnecting durable "
761 "handle for file %s: %s - "
762 "proceeding with normal close\n",
763 fsp_str_dbg(fsp), nt_errstr(tmp)));
765 scavenger_schedule_disconnected(fsp);
767 DEBUG(1, ("Failed to disconnect durable handle for "
768 "file %s: %s - proceeding with normal "
769 "close\n", fsp_str_dbg(fsp), nt_errstr(tmp)));
771 if (!NT_STATUS_IS_OK(tmp)) {
778 * This is the case where we successfully disconnected
779 * a durable handle and closed the underlying file.
780 * In all other cases, we proceed with a genuine close.
782 DEBUG(10, ("%s disconnected durable handle for file %s\n",
783 conn->session_info->unix_info->unix_name,
788 if (fsp->op != NULL) {
790 * Make sure the handle is not marked as durable anymore
792 fsp->op->global->durable = false;
795 /* If this is an old DOS or FCB open and we have multiple opens on
796 the same handle we only have one share mode. Ensure we only remove
797 the share mode on the last close. */
799 if (fh_get_refcount(fsp->fh) == 1) {
800 /* Should we return on error here... ? */
801 tmp = close_remove_share_mode(fsp, close_type);
802 status = ntstatus_keeperror(status, tmp);
805 locking_close_file(fsp, close_type);
808 * Ensure pending modtime is set before closing underlying fd.
811 tmp = update_write_time_on_close(fsp);
812 if (NT_STATUS_EQUAL(tmp, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
814 * Someone renamed the file or a parent directory containing
815 * this file. We can't do anything about this, eat the error.
819 status = ntstatus_keeperror(status, tmp);
822 status = ntstatus_keeperror(status, tmp);
824 /* check for magic scripts */
825 if (close_type == NORMAL_CLOSE) {
826 tmp = check_magic(fsp);
827 status = ntstatus_keeperror(status, tmp);
830 DEBUG(2,("%s closed file %s (numopen=%d) %s\n",
831 conn->session_info->unix_info->unix_name, fsp_str_dbg(fsp),
832 conn->num_files_open - 1,
833 nt_errstr(status) ));
837 /****************************************************************************
838 Function used by reply_rmdir to delete an entire directory
839 tree recursively. Return True on ok, False on fail.
840 ****************************************************************************/
842 bool recursive_rmdir(TALLOC_CTX *ctx,
843 connection_struct *conn,
844 struct smb_filename *smb_dname)
846 const char *dname = NULL;
847 char *talloced = NULL;
851 struct smb_Dir *dir_hnd;
852 struct files_struct *dirfsp = NULL;
856 SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
858 dir_hnd = OpenDir(talloc_tos(), conn, smb_dname, NULL, 0);
862 dirfsp = dir_hnd_fetch_fsp(dir_hnd);
864 while ((dname = ReadDirName(dir_hnd, &offset, &st, &talloced))) {
865 struct smb_filename *atname = NULL;
866 struct smb_filename *smb_dname_full = NULL;
867 char *fullname = NULL;
868 bool do_break = true;
869 int unlink_flags = 0;
871 if (ISDOT(dname) || ISDOTDOT(dname)) {
872 TALLOC_FREE(talloced);
876 /* Construct the full name. */
877 fullname = talloc_asprintf(ctx,
879 smb_dname->base_name,
886 smb_dname_full = synthetic_smb_fname(talloc_tos(),
892 if (smb_dname_full == NULL) {
897 if (SMB_VFS_LSTAT(conn, smb_dname_full) != 0) {
901 if (smb_dname_full->st.st_ex_mode & S_IFDIR) {
902 if (!recursive_rmdir(ctx, conn, smb_dname_full)) {
905 unlink_flags = AT_REMOVEDIR;
908 status = synthetic_pathref(talloc_tos(),
913 smb_dname_full->twrp,
914 smb_dname_full->flags,
916 if (!NT_STATUS_IS_OK(status)) {
917 errno = map_errno_from_nt_status(status);
921 if (!is_visible_fsp(atname->fsp)) {
922 TALLOC_FREE(smb_dname_full);
923 TALLOC_FREE(fullname);
924 TALLOC_FREE(talloced);
929 retval = SMB_VFS_UNLINKAT(conn,
937 /* Successful iteration. */
941 TALLOC_FREE(smb_dname_full);
942 TALLOC_FREE(fullname);
943 TALLOC_FREE(talloced);
950 TALLOC_FREE(dir_hnd);
954 /****************************************************************************
955 The internals of the rmdir code - called elsewhere.
956 ****************************************************************************/
958 static NTSTATUS rmdir_internals(TALLOC_CTX *ctx, struct files_struct *fsp)
960 struct connection_struct *conn = fsp->conn;
961 struct smb_filename *smb_dname = fsp->fsp_name;
962 struct smb_filename *parent_fname = NULL;
963 struct smb_filename *at_fname = NULL;
965 const char *dname = NULL;
966 char *talloced = NULL;
968 struct smb_Dir *dir_hnd = NULL;
969 struct files_struct *dirfsp = NULL;
970 int unlink_flags = 0;
974 SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
976 status = parent_pathref(talloc_tos(),
981 if (!NT_STATUS_IS_OK(status)) {
986 * Todo: use SMB_VFS_STATX() once it's available.
989 /* Might be a symlink. */
990 ret = SMB_VFS_LSTAT(conn, smb_dname);
992 TALLOC_FREE(parent_fname);
993 return map_nt_error_from_unix(errno);
996 if (S_ISLNK(smb_dname->st.st_ex_mode)) {
997 /* Is what it points to a directory ? */
998 ret = SMB_VFS_STAT(conn, smb_dname);
1000 TALLOC_FREE(parent_fname);
1001 return map_nt_error_from_unix(errno);
1003 if (!(S_ISDIR(smb_dname->st.st_ex_mode))) {
1004 TALLOC_FREE(parent_fname);
1005 return NT_STATUS_NOT_A_DIRECTORY;
1008 unlink_flags = AT_REMOVEDIR;
1011 ret = SMB_VFS_UNLINKAT(conn,
1016 TALLOC_FREE(parent_fname);
1017 notify_fname(conn, NOTIFY_ACTION_REMOVED,
1018 FILE_NOTIFY_CHANGE_DIR_NAME,
1019 smb_dname->base_name);
1020 return NT_STATUS_OK;
1023 if (!((errno == ENOTEMPTY) || (errno == EEXIST))) {
1024 DEBUG(3,("rmdir_internals: couldn't remove directory %s : "
1025 "%s\n", smb_fname_str_dbg(smb_dname),
1027 TALLOC_FREE(parent_fname);
1028 return map_nt_error_from_unix(errno);
1032 * Here we know the initial directory unlink failed with
1033 * ENOTEMPTY or EEXIST so we know there are objects within.
1034 * If we don't have permission to delete files non
1035 * visible to the client just fail the directory delete.
1038 if (!lp_delete_veto_files(SNUM(conn))) {
1044 * Check to see if the only thing in this directory are
1045 * files non-visible to the client. If not, fail the delete.
1048 dir_hnd = OpenDir(talloc_tos(), conn, smb_dname, NULL, 0);
1049 if (dir_hnd == NULL) {
1054 dirfsp = dir_hnd_fetch_fsp(dir_hnd);
1056 while ((dname = ReadDirName(dir_hnd, &dirpos, &st, &talloced)) != NULL) {
1057 struct smb_filename *smb_dname_full = NULL;
1058 struct smb_filename *direntry_fname = NULL;
1059 char *fullname = NULL;
1062 if (ISDOT(dname) || ISDOTDOT(dname)) {
1063 TALLOC_FREE(talloced);
1066 if (IS_VETO_PATH(conn, dname)) {
1067 TALLOC_FREE(talloced);
1071 fullname = talloc_asprintf(talloc_tos(),
1073 smb_dname->base_name,
1076 if (fullname == NULL) {
1077 TALLOC_FREE(talloced);
1082 smb_dname_full = synthetic_smb_fname(talloc_tos(),
1088 if (smb_dname_full == NULL) {
1089 TALLOC_FREE(talloced);
1090 TALLOC_FREE(fullname);
1095 retval = SMB_VFS_LSTAT(conn, smb_dname_full);
1097 int saved_errno = errno;
1098 TALLOC_FREE(talloced);
1099 TALLOC_FREE(fullname);
1100 TALLOC_FREE(smb_dname_full);
1101 errno = saved_errno;
1105 if (S_ISLNK(smb_dname_full->st.st_ex_mode)) {
1106 /* Could it be an msdfs link ? */
1107 if (lp_host_msdfs() &&
1108 lp_msdfs_root(SNUM(conn))) {
1109 struct smb_filename *smb_atname;
1110 smb_atname = synthetic_smb_fname(talloc_tos(),
1113 &smb_dname_full->st,
1114 fsp->fsp_name->twrp,
1115 fsp->fsp_name->flags);
1116 if (smb_atname == NULL) {
1117 TALLOC_FREE(talloced);
1118 TALLOC_FREE(fullname);
1119 TALLOC_FREE(smb_dname_full);
1123 if (is_msdfs_link(fsp, smb_atname)) {
1124 TALLOC_FREE(talloced);
1125 TALLOC_FREE(fullname);
1126 TALLOC_FREE(smb_dname_full);
1127 TALLOC_FREE(smb_atname);
1128 DBG_DEBUG("got msdfs link name %s "
1129 "- can't delete directory %s\n",
1135 TALLOC_FREE(smb_atname);
1138 /* Not a DFS link - could it be a dangling symlink ? */
1139 retval = SMB_VFS_STAT(conn, smb_dname_full);
1140 if (retval == -1 && (errno == ENOENT || errno == ELOOP)) {
1143 * Allow delete as "delete veto files = yes"
1145 TALLOC_FREE(talloced);
1146 TALLOC_FREE(fullname);
1147 TALLOC_FREE(smb_dname_full);
1151 DBG_DEBUG("got symlink name %s - "
1152 "can't delete directory %s\n",
1155 TALLOC_FREE(talloced);
1156 TALLOC_FREE(fullname);
1157 TALLOC_FREE(smb_dname_full);
1162 /* Not a symlink, get a pathref. */
1163 status = synthetic_pathref(talloc_tos(),
1167 &smb_dname_full->st,
1171 if (!NT_STATUS_IS_OK(status)) {
1172 TALLOC_FREE(talloced);
1173 TALLOC_FREE(fullname);
1174 TALLOC_FREE(smb_dname_full);
1175 errno = map_errno_from_nt_status(status);
1179 if (!is_visible_fsp(direntry_fname->fsp)) {
1180 TALLOC_FREE(talloced);
1181 TALLOC_FREE(fullname);
1182 TALLOC_FREE(smb_dname_full);
1183 TALLOC_FREE(direntry_fname);
1188 * We found a client visible name.
1189 * We cannot delete this directory.
1191 DBG_DEBUG("got name %s - "
1192 "can't delete directory %s\n",
1195 TALLOC_FREE(talloced);
1196 TALLOC_FREE(fullname);
1197 TALLOC_FREE(smb_dname_full);
1198 TALLOC_FREE(direntry_fname);
1203 /* Do a recursive delete. */
1204 RewindDir(dir_hnd,&dirpos);
1206 while ((dname = ReadDirName(dir_hnd, &dirpos, &st, &talloced)) != NULL) {
1207 struct smb_filename *direntry_fname = NULL;
1208 struct smb_filename *smb_dname_full = NULL;
1209 char *fullname = NULL;
1210 bool do_break = true;
1213 if (ISDOT(dname) || ISDOTDOT(dname)) {
1214 TALLOC_FREE(talloced);
1218 fullname = talloc_asprintf(ctx,
1220 smb_dname->base_name,
1223 if (fullname == NULL) {
1228 smb_dname_full = synthetic_smb_fname(talloc_tos(),
1234 if (smb_dname_full == NULL) {
1240 * Todo: use SMB_VFS_STATX() once that's available.
1243 retval = SMB_VFS_LSTAT(conn, smb_dname_full);
1249 * We are only dealing with VETO'ed objects
1250 * here. If it's a symlink, just delete the
1251 * link without caring what it is pointing
1254 if (S_ISLNK(smb_dname_full->st.st_ex_mode)) {
1255 direntry_fname = synthetic_smb_fname(talloc_tos(),
1258 &smb_dname_full->st,
1261 if (direntry_fname == NULL) {
1266 status = synthetic_pathref(talloc_tos(),
1270 &smb_dname_full->st,
1274 if (!NT_STATUS_IS_OK(status)) {
1275 errno = map_errno_from_nt_status(status);
1279 if (!is_visible_fsp(direntry_fname->fsp)) {
1280 TALLOC_FREE(fullname);
1281 TALLOC_FREE(smb_dname_full);
1282 TALLOC_FREE(talloced);
1283 TALLOC_FREE(direntry_fname);
1290 if (smb_dname_full->st.st_ex_mode & S_IFDIR) {
1291 if (!recursive_rmdir(ctx, conn,
1296 unlink_flags = AT_REMOVEDIR;
1299 retval = SMB_VFS_UNLINKAT(conn,
1307 /* Successful iteration. */
1311 TALLOC_FREE(fullname);
1312 TALLOC_FREE(smb_dname_full);
1313 TALLOC_FREE(talloced);
1314 TALLOC_FREE(direntry_fname);
1320 /* Retry the rmdir */
1321 ret = SMB_VFS_UNLINKAT(conn,
1329 TALLOC_FREE(dir_hnd);
1330 TALLOC_FREE(parent_fname);
1333 DEBUG(3,("rmdir_internals: couldn't remove directory %s : "
1334 "%s\n", smb_fname_str_dbg(smb_dname),
1336 return map_nt_error_from_unix(errno);
1339 notify_fname(conn, NOTIFY_ACTION_REMOVED,
1340 FILE_NOTIFY_CHANGE_DIR_NAME,
1341 smb_dname->base_name);
1343 return NT_STATUS_OK;
1346 /****************************************************************************
1347 Close a directory opened by an NT SMB call.
1348 ****************************************************************************/
1350 static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
1351 enum file_close_type close_type)
1353 struct share_mode_lock *lck = NULL;
1354 bool delete_dir = False;
1355 NTSTATUS status = NT_STATUS_OK;
1356 NTSTATUS status1 = NT_STATUS_OK;
1357 const struct security_token *del_nt_token = NULL;
1358 const struct security_unix_token *del_token = NULL;
1359 NTSTATUS notify_status;
1361 SMB_ASSERT(fsp->fsp_flags.is_fsa);
1363 if (fsp->conn->sconn->using_smb2) {
1364 notify_status = NT_STATUS_NOTIFY_CLEANUP;
1366 notify_status = NT_STATUS_OK;
1369 assert_no_pending_aio(fsp, close_type);
1372 * NT can set delete_on_close of the last open
1373 * reference to a directory also.
1376 lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
1378 DEBUG(0, ("close_directory: Could not get share mode lock for "
1379 "%s\n", fsp_str_dbg(fsp)));
1380 return NT_STATUS_INVALID_PARAMETER;
1383 if (fsp->fsp_flags.initial_delete_on_close) {
1384 /* Initial delete on close was set - for
1385 * directories we don't care if anyone else
1386 * wrote a real delete on close. */
1388 send_stat_cache_delete_message(fsp->conn->sconn->msg_ctx,
1389 fsp->fsp_name->base_name);
1390 set_delete_on_close_lck(fsp, lck,
1391 fsp->conn->session_info->security_token,
1392 fsp->conn->session_info->unix_token);
1393 fsp->fsp_flags.delete_on_close = true;
1396 delete_dir = get_delete_on_close_token(
1397 lck, fsp->name_hash, &del_nt_token, &del_token) &&
1398 !has_other_nonposix_opens(lck, fsp);
1400 if ((close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) &&
1403 /* Become the user who requested the delete. */
1405 if (!push_sec_ctx()) {
1406 smb_panic("close_directory: failed to push sec_ctx.\n");
1409 set_sec_ctx(del_token->uid,
1415 if (!del_share_mode(lck, fsp)) {
1416 DEBUG(0, ("close_directory: Could not delete share entry for "
1417 "%s\n", fsp_str_dbg(fsp)));
1422 if ((fsp->conn->fs_capabilities & FILE_NAMED_STREAMS)
1423 && !is_ntfs_stream_smb_fname(fsp->fsp_name)) {
1425 status = delete_all_streams(fsp->conn, fsp->fsp_name);
1426 if (!NT_STATUS_IS_OK(status)) {
1427 DEBUG(5, ("delete_all_streams failed: %s\n",
1428 nt_errstr(status)));
1429 /* unbecome user. */
1435 status = rmdir_internals(talloc_tos(), fsp);
1437 DEBUG(5,("close_directory: %s. Delete on close was set - "
1438 "deleting directory returned %s.\n",
1439 fsp_str_dbg(fsp), nt_errstr(status)));
1441 /* unbecome user. */
1445 * Ensure we remove any change notify requests that would
1446 * now fail as the directory has been deleted.
1449 if (NT_STATUS_IS_OK(status)) {
1450 notify_status = NT_STATUS_DELETE_PENDING;
1453 if (!del_share_mode(lck, fsp)) {
1454 DEBUG(0, ("close_directory: Could not delete share entry for "
1455 "%s\n", fsp_str_dbg(fsp)));
1461 remove_pending_change_notify_requests_by_fid(fsp, notify_status);
1463 status1 = fd_close(fsp);
1465 if (!NT_STATUS_IS_OK(status1)) {
1466 DEBUG(0, ("Could not close dir! fname=%s, fd=%d, err=%d=%s\n",
1467 fsp_str_dbg(fsp), fsp_get_pathref_fd(fsp), errno,
1471 if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(status1)) {
1477 /****************************************************************************
1478 Close a files_struct.
1479 ****************************************************************************/
1481 NTSTATUS close_file_free(struct smb_request *req,
1482 struct files_struct **_fsp,
1483 enum file_close_type close_type)
1486 struct files_struct *fsp = *_fsp;
1487 struct files_struct *base_fsp = fsp->base_fsp;
1488 bool close_base_fsp = false;
1491 * This fsp can never be an internal dirfsp. They must
1492 * be explicitly closed by TALLOC_FREE of the dir handle.
1494 SMB_ASSERT(!fsp->fsp_flags.is_dirfsp);
1496 if (fsp->stream_fsp != NULL) {
1498 * fsp is the base for a stream.
1500 * We're called with SHUTDOWN_CLOSE from files.c which walks the
1501 * complete list of files.
1503 * We need to wait until the stream is closed.
1505 SMB_ASSERT(close_type == SHUTDOWN_CLOSE);
1506 return NT_STATUS_OK;
1509 if (base_fsp != NULL) {
1511 * We need to remove the link in order to
1512 * recurse for the base fsp below.
1514 SMB_ASSERT(base_fsp->base_fsp == NULL);
1515 SMB_ASSERT(base_fsp->stream_fsp == fsp);
1516 base_fsp->stream_fsp = NULL;
1518 if (close_type == SHUTDOWN_CLOSE) {
1520 * We're called with SHUTDOWN_CLOSE from files.c
1521 * which walks the complete list of files.
1523 * We may need to defer the SHUTDOWN_CLOSE
1524 * if it's the next in the linked list.
1526 * So we only close if the base is *not* the
1529 close_base_fsp = (fsp->next != base_fsp);
1531 close_base_fsp = true;
1535 if (fsp->fake_file_handle != NULL) {
1536 status = close_fake_file(req, fsp);
1537 } else if (fsp->print_file != NULL) {
1538 /* FIXME: return spool errors */
1539 print_spool_end(fsp, close_type);
1541 status = NT_STATUS_OK;
1542 } else if (!fsp->fsp_flags.is_fsa) {
1543 if (close_type == NORMAL_CLOSE) {
1544 DBG_ERR("unexpected NORMAL_CLOSE for [%s] "
1545 "is_fsa[%u] is_pathref[%u] is_directory[%u]\n",
1547 fsp->fsp_flags.is_fsa,
1548 fsp->fsp_flags.is_pathref,
1549 fsp->fsp_flags.is_directory);
1551 SMB_ASSERT(close_type != NORMAL_CLOSE);
1553 status = NT_STATUS_OK;
1554 } else if (fsp->fsp_flags.is_directory) {
1555 status = close_directory(req, fsp, close_type);
1557 status = close_normal_file(req, fsp, close_type);
1560 file_free(req, fsp);
1562 if (close_base_fsp) {
1565 * fsp was a stream, the base fsp can't be a stream as well
1567 * For SHUTDOWN_CLOSE this is not possible here
1568 * (if the base_fsp was the next in the linked list), because
1569 * SHUTDOWN_CLOSE only happens from files.c which walks the
1570 * complete list of files. If we mess with more than one fsp
1571 * those loops will become confused.
1574 close_file_free(req, &base_fsp, close_type);
1582 /****************************************************************************
1583 Deal with an (authorized) message to close a file given the share mode
1585 ****************************************************************************/
1587 void msg_close_file(struct messaging_context *msg_ctx,
1590 struct server_id server_id,
1593 files_struct *fsp = NULL;
1595 struct share_mode_entry e;
1596 struct smbd_server_connection *sconn =
1597 talloc_get_type_abort(private_data,
1598 struct smbd_server_connection);
1600 message_to_share_mode_entry(&id, &e, (char *)data->data);
1603 char *sm_str = share_mode_str(NULL, 0, &id, &e);
1605 smb_panic("talloc failed");
1607 DEBUG(10,("msg_close_file: got request to close share mode "
1608 "entry %s\n", sm_str));
1609 TALLOC_FREE(sm_str);
1612 fsp = file_find_dif(sconn, id, e.share_file_id);
1614 DEBUG(10,("msg_close_file: failed to find file.\n"));
1617 close_file_free(NULL, &fsp, NORMAL_CLOSE);