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/scavenger.h"
30 #include "fake_file.h"
31 #include "transfer_file.h"
34 #include "../librpc/gen_ndr/open_files.h"
35 #include "lib/util/tevent_ntstatus.h"
37 /****************************************************************************
38 Run a file if it is a magic script.
39 ****************************************************************************/
41 static NTSTATUS check_magic(struct files_struct *fsp)
44 const struct loadparm_substitution *lp_sub =
45 loadparm_s3_global_substitution();
46 const char *magic_output = NULL;
49 TALLOC_CTX *ctx = NULL;
51 struct connection_struct *conn = fsp->conn;
55 if (!*lp_magic_script(talloc_tos(), lp_sub, SNUM(conn))) {
59 DEBUG(5,("checking magic for %s\n", fsp_str_dbg(fsp)));
61 ctx = talloc_stackframe();
63 fname = fsp->fsp_name->base_name;
65 if (!(p = strrchr_m(fname,'/'))) {
71 if (!strequal(lp_magic_script(talloc_tos(), lp_sub, SNUM(conn)),p)) {
72 status = NT_STATUS_OK;
76 if (*lp_magic_output(talloc_tos(), lp_sub, SNUM(conn))) {
77 magic_output = lp_magic_output(talloc_tos(), lp_sub, SNUM(conn));
79 magic_output = talloc_asprintf(ctx,
84 status = NT_STATUS_NO_MEMORY;
88 /* Ensure we don't depend on user's PATH. */
89 p = talloc_asprintf(ctx, "./%s", fname);
91 status = NT_STATUS_NO_MEMORY;
95 if (chmod(fname, 0755) == -1) {
96 status = map_nt_error_from_unix(errno);
99 ret = smbrun(p, &tmp_fd, NULL);
100 DEBUG(3,("Invoking magic command %s gave %d\n",
104 if (ret != 0 || tmp_fd == -1) {
108 status = NT_STATUS_UNSUCCESSFUL;
111 outfd = open(magic_output, O_CREAT|O_EXCL|O_RDWR, 0600);
115 status = map_nt_error_from_unix(err);
119 if (sys_fstat(tmp_fd, &st, false) == -1) {
123 status = map_nt_error_from_unix(err);
127 if (transfer_file(tmp_fd,outfd,(off_t)st.st_ex_size) == (off_t)-1) {
131 status = map_nt_error_from_unix(err);
135 if (close(outfd) == -1) {
136 status = map_nt_error_from_unix(errno);
140 status = NT_STATUS_OK;
147 /****************************************************************************
149 ****************************************************************************/
151 NTSTATUS delete_all_streams(connection_struct *conn,
152 const struct smb_filename *smb_fname)
154 struct stream_struct *stream_info = NULL;
156 unsigned int num_streams = 0;
157 TALLOC_CTX *frame = talloc_stackframe();
160 status = vfs_fstreaminfo(smb_fname->fsp, talloc_tos(),
161 &num_streams, &stream_info);
163 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
164 DEBUG(10, ("no streams around\n"));
169 if (!NT_STATUS_IS_OK(status)) {
170 DEBUG(10, ("vfs_fstreaminfo failed: %s\n",
175 DEBUG(10, ("delete_all_streams found %d streams\n",
178 if (num_streams == 0) {
183 for (i=0; i<num_streams; i++) {
185 struct smb_filename *smb_fname_stream;
187 if (strequal(stream_info[i].name, "::$DATA")) {
191 status = synthetic_pathref(talloc_tos(),
193 smb_fname->base_name,
198 ~SMB_FILENAME_POSIX_PATH),
200 if (!NT_STATUS_IS_OK(status)) {
201 DEBUG(0, ("talloc_aprintf failed\n"));
202 status = NT_STATUS_NO_MEMORY;
206 res = SMB_VFS_UNLINKAT(conn,
212 status = map_nt_error_from_unix(errno);
213 DEBUG(10, ("Could not delete stream %s: %s\n",
214 smb_fname_str_dbg(smb_fname_stream),
216 TALLOC_FREE(smb_fname_stream);
219 TALLOC_FREE(smb_fname_stream);
227 struct has_other_nonposix_opens_state {
232 static bool has_other_nonposix_opens_fn(
233 struct share_mode_entry *e,
237 struct has_other_nonposix_opens_state *state = private_data;
238 struct files_struct *fsp = state->fsp;
240 if (e->name_hash != fsp->name_hash) {
243 if ((fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) &&
244 (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) {
247 if (e->share_file_id == fh_get_gen_id(fsp->fh)) {
248 struct server_id self = messaging_server_id(
249 fsp->conn->sconn->msg_ctx);
250 if (server_id_equal(&self, &e->pid)) {
254 if (share_entry_stale_pid(e)) {
258 state->found_another = true;
262 bool has_other_nonposix_opens(struct share_mode_lock *lck,
263 struct files_struct *fsp)
265 struct has_other_nonposix_opens_state state = { .fsp = fsp };
268 ok = share_mode_forall_entries(
269 lck, has_other_nonposix_opens_fn, &state);
273 return state.found_another;
276 /****************************************************************************
277 Deal with removing a share mode on last close.
278 ****************************************************************************/
280 static NTSTATUS close_remove_share_mode(files_struct *fsp,
281 enum file_close_type close_type)
283 connection_struct *conn = fsp->conn;
284 bool delete_file = false;
285 bool changed_user = false;
286 struct share_mode_lock *lck = NULL;
287 NTSTATUS status = NT_STATUS_OK;
290 const struct security_unix_token *del_token = NULL;
291 const struct security_token *del_nt_token = NULL;
292 struct smb_filename *parent_fname = NULL;
293 struct smb_filename *base_fname = NULL;
294 bool got_tokens = false;
298 /* Ensure any pending write time updates are done. */
299 if (fsp->update_write_time_event) {
300 fsp_flush_write_time_update(fsp);
304 * Lock the share entries, and determine if we should delete
305 * on close. If so delete whilst the lock is still in effect.
306 * This prevents race conditions with the file being created. JRA.
309 lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
311 DEBUG(0, ("close_remove_share_mode: Could not get share mode "
312 "lock for file %s\n", fsp_str_dbg(fsp)));
313 return NT_STATUS_INVALID_PARAMETER;
316 /* Remove the oplock before potentially deleting the file. */
317 if(fsp->oplock_type) {
321 if (fsp->fsp_flags.write_time_forced) {
322 NTTIME mtime = share_mode_changed_write_time(lck);
323 struct timespec ts = nt_time_to_full_timespec(mtime);
325 DEBUG(10,("close_remove_share_mode: write time forced "
328 set_close_write_time(fsp, ts);
329 } else if (fsp->fsp_flags.update_write_time_on_close) {
330 /* Someone had a pending write. */
331 if (is_omit_timespec(&fsp->close_write_time)) {
332 DEBUG(10,("close_remove_share_mode: update to current time "
335 /* Update to current time due to "normal" write. */
336 set_close_write_time(fsp, timespec_current());
338 DEBUG(10,("close_remove_share_mode: write time pending "
341 /* Update to time set on close call. */
342 set_close_write_time(fsp, fsp->close_write_time);
346 if (fsp->fsp_flags.initial_delete_on_close &&
347 !is_delete_on_close_set(lck, fsp->name_hash)) {
348 /* Initial delete on close was set and no one else
349 * wrote a real delete on close. */
351 fsp->fsp_flags.delete_on_close = true;
352 set_delete_on_close_lck(fsp, lck,
353 fsp->conn->session_info->security_token,
354 fsp->conn->session_info->unix_token);
357 delete_file = is_delete_on_close_set(lck, fsp->name_hash) &&
358 !has_other_nonposix_opens(lck, fsp);
361 * NT can set delete_on_close of the last open
362 * reference to a file.
365 normal_close = (close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE);
367 if (!normal_close || !delete_file) {
368 status = NT_STATUS_OK;
373 * Ok, we have to delete the file
376 DEBUG(5,("close_remove_share_mode: file %s. Delete on close was set "
377 "- deleting file.\n", fsp_str_dbg(fsp)));
380 * Don't try to update the write time when we delete the file
382 fsp->fsp_flags.update_write_time_on_close = false;
384 got_tokens = get_delete_on_close_token(lck, fsp->name_hash,
385 &del_nt_token, &del_token);
386 SMB_ASSERT(got_tokens);
388 if (!unix_token_equal(del_token, get_current_utok(conn))) {
389 /* Become the user who requested the delete. */
391 DEBUG(5,("close_remove_share_mode: file %s. "
392 "Change user to uid %u\n",
394 (unsigned int)del_token->uid));
396 if (!push_sec_ctx()) {
397 smb_panic("close_remove_share_mode: file %s. failed to push "
401 set_sec_ctx(del_token->uid,
410 /* We can only delete the file if the name we have is still valid and
411 hasn't been renamed. */
413 tmp_status = vfs_stat_fsp(fsp);
414 if (!NT_STATUS_IS_OK(tmp_status)) {
415 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
416 "was set and stat failed with error %s\n",
417 fsp_str_dbg(fsp), nt_errstr(tmp_status)));
419 * Don't save the errno here, we ignore this error
424 id = vfs_file_id_from_sbuf(conn, &fsp->fsp_name->st);
426 if (!file_id_equal(&fsp->file_id, &id)) {
427 struct file_id_buf ftmp1, ftmp2;
428 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
429 "was set and dev and/or inode does not match\n",
431 DEBUG(5,("close_remove_share_mode: file %s. stored file_id %s, "
434 file_id_str_buf(fsp->file_id, &ftmp1),
435 file_id_str_buf(id, &ftmp2)));
437 * Don't save the errno here, we ignore this error
442 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
443 && !is_ntfs_stream_smb_fname(fsp->fsp_name)) {
445 status = delete_all_streams(conn, fsp->fsp_name);
447 if (!NT_STATUS_IS_OK(status)) {
448 DEBUG(5, ("delete_all_streams failed: %s\n",
454 if (fsp->fsp_flags.kernel_share_modes_taken) {
456 * A file system sharemode could block the unlink;
457 * remove filesystem sharemodes first.
459 ret = SMB_VFS_FILESYSTEM_SHAREMODE(fsp, 0, 0);
461 DBG_INFO("Removing file system sharemode for %s "
463 fsp_str_dbg(fsp), strerror(errno));
466 fsp->fsp_flags.kernel_share_modes_taken = false;
469 status = parent_pathref(talloc_tos(),
474 if (!NT_STATUS_IS_OK(status)) {
478 ret = SMB_VFS_UNLINKAT(conn,
482 TALLOC_FREE(parent_fname);
486 * This call can potentially fail as another smbd may
487 * have had the file open with delete on close set and
488 * deleted it when its last reference to this file
489 * went away. Hence we log this but not at debug level
493 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
494 "was set and unlink failed with error %s\n",
495 fsp_str_dbg(fsp), strerror(errno)));
497 status = map_nt_error_from_unix(errno);
500 /* As we now have POSIX opens which can unlink
501 * with other open files we may have taken
502 * this code path with more than one share mode
503 * entry - ensure we only delete once by resetting
504 * the delete on close flag. JRA.
507 fsp->fsp_flags.delete_on_close = false;
508 reset_delete_on_close_lck(fsp, lck);
517 if (fsp->fsp_flags.kernel_share_modes_taken) {
518 /* remove filesystem sharemodes */
519 ret = SMB_VFS_FILESYSTEM_SHAREMODE(fsp, 0, 0);
521 DBG_INFO("Removing file system sharemode for "
523 fsp_str_dbg(fsp), strerror(errno));
527 if (!del_share_mode(lck, fsp)) {
528 DEBUG(0, ("close_remove_share_mode: Could not delete share "
529 "entry for file %s\n", fsp_str_dbg(fsp)));
536 * Do the notification after we released the share
537 * mode lock. Inside notify_fname we take out another
538 * tdb lock. With ctdb also accessing our databases,
539 * this can lead to deadlocks. Putting this notify
540 * after the TALLOC_FREE(lck) above we avoid locking
541 * two records simultaneously. Notifies are async and
542 * informational only, so calling the notify_fname
543 * without holding the share mode lock should not do
546 notify_fname(conn, NOTIFY_ACTION_REMOVED,
547 FILE_NOTIFY_CHANGE_FILE_NAME,
548 fsp->fsp_name->base_name);
554 void set_close_write_time(struct files_struct *fsp, struct timespec ts)
556 DEBUG(6,("close_write_time: %s" , time_to_asc(convert_timespec_to_time_t(ts))));
558 if (is_omit_timespec(&ts)) {
561 fsp->fsp_flags.write_time_forced = false;
562 fsp->fsp_flags.update_write_time_on_close = true;
563 fsp->close_write_time = ts;
566 static NTSTATUS update_write_time_on_close(struct files_struct *fsp)
568 struct smb_file_time ft;
570 struct share_mode_lock *lck = NULL;
572 init_smb_file_time(&ft);
574 if (!(fsp->fsp_flags.update_write_time_on_close)) {
578 if (is_omit_timespec(&fsp->close_write_time)) {
579 fsp->close_write_time = timespec_current();
582 /* Ensure we have a valid stat struct for the source. */
583 status = vfs_stat_fsp(fsp);
584 if (!NT_STATUS_IS_OK(status)) {
588 if (!VALID_STAT(fsp->fsp_name->st)) {
589 /* if it doesn't seem to be a real file */
594 * get_existing_share_mode_lock() isn't really the right
595 * call here, as we're being called after
596 * close_remove_share_mode() inside close_normal_file()
597 * so it's quite normal to not have an existing share
598 * mode here. However, get_share_mode_lock() doesn't
599 * work because that will create a new share mode if
600 * one doesn't exist - so stick with this call (just
601 * ignore any error we get if the share mode doesn't
605 lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
607 NTTIME share_mtime = share_mode_changed_write_time(lck);
608 /* On close if we're changing the real file time we
609 * must update it in the open file db too. */
610 (void)set_write_time(fsp->file_id, fsp->close_write_time);
612 /* Close write times overwrite sticky write times
613 so we must replace any sticky write time here. */
614 if (!null_nttime(share_mtime)) {
615 (void)set_sticky_write_time(fsp->file_id, fsp->close_write_time);
620 ft.mtime = fsp->close_write_time;
621 /* As this is a close based update, we are not directly changing the
622 file attributes from a client call, but indirectly from a write. */
623 status = smb_set_file_time(fsp->conn, fsp, fsp->fsp_name, &ft, false);
624 if (!NT_STATUS_IS_OK(status)) {
625 DEBUG(10,("update_write_time_on_close: smb_set_file_time "
626 "on file %s returned %s\n",
635 static NTSTATUS ntstatus_keeperror(NTSTATUS s1, NTSTATUS s2)
637 if (!NT_STATUS_IS_OK(s1)) {
643 static void assert_no_pending_aio(struct files_struct *fsp,
644 enum file_close_type close_type)
646 struct smbXsrv_client *client = global_smbXsrv_client;
647 size_t num_connections_alive;
648 unsigned num_requests = fsp->num_aio_requests;
650 if (num_requests == 0) {
654 num_connections_alive = smbXsrv_client_valid_connections(client);
656 if (close_type == SHUTDOWN_CLOSE && num_connections_alive == 0) {
658 * fsp->aio_requests and the contents (fsp->aio_requests[x])
659 * are both independently owned by fsp and are not in a
660 * talloc heirarchy. This allows the fsp->aio_requests array to
661 * be reallocated independently of the array contents so it can
664 * This means we must ensure order of deallocation
665 * on a SHUTDOWN_CLOSE by deallocating the fsp->aio_requests[x]
666 * contents first, as their destructors access the
667 * fsp->aio_request array. If we don't deallocate them
668 * first, when fsp is deallocated fsp->aio_requests
669 * could have been deallocated *before* its contents
670 * fsp->aio_requests[x], causing a crash.
672 while (fsp->num_aio_requests != 0) {
675 * talloc_free(fsp->aio_requests[0]),
676 * and *NOT* TALLOC_FREE() here, as
677 * TALLOC_FREE(fsp->aio_requests[0])
678 * will overwrite any new contents of
679 * fsp->aio_requests[0] that were
680 * copied into it via the destructor
681 * aio_del_req_from_fsp().
683 * BUG: https://bugzilla.samba.org/show_bug.cgi?id=14515
685 talloc_free(fsp->aio_requests[0]);
690 DBG_ERR("fsp->num_aio_requests=%u\n", num_requests);
691 smb_panic("can not close with outstanding aio requests");
695 /****************************************************************************
698 close_type can be NORMAL_CLOSE=0,SHUTDOWN_CLOSE,ERROR_CLOSE.
699 printing and magic scripts are only run on normal close.
700 delete on close is done on normal and shutdown close.
701 ****************************************************************************/
703 static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp,
704 enum file_close_type close_type)
706 NTSTATUS status = NT_STATUS_OK;
708 connection_struct *conn = fsp->conn;
709 bool is_durable = false;
711 SMB_ASSERT(fsp->fsp_flags.is_fsa);
713 assert_no_pending_aio(fsp, close_type);
715 while (talloc_array_length(fsp->blocked_smb1_lock_reqs) != 0) {
716 smbd_smb1_brl_finish_by_req(
717 fsp->blocked_smb1_lock_reqs[0],
718 NT_STATUS_RANGE_NOT_LOCKED);
722 * If we're flushing on a close we can get a write
723 * error here, we must remember this.
726 if (NT_STATUS_IS_OK(status) && fsp->op != NULL) {
727 is_durable = fsp->op->global->durable;
730 if (close_type != SHUTDOWN_CLOSE) {
735 DATA_BLOB new_cookie = data_blob_null;
737 tmp = SMB_VFS_DURABLE_DISCONNECT(fsp,
738 fsp->op->global->backend_cookie,
741 if (NT_STATUS_IS_OK(tmp)) {
746 tv = req->request_time;
748 tv = timeval_current();
750 now = timeval_to_nttime(&tv);
752 data_blob_free(&fsp->op->global->backend_cookie);
753 fsp->op->global->backend_cookie = new_cookie;
755 fsp->op->compat = NULL;
756 tmp = smbXsrv_open_close(fsp->op, now);
757 if (!NT_STATUS_IS_OK(tmp)) {
758 DEBUG(1, ("Failed to update smbXsrv_open "
759 "record when disconnecting durable "
760 "handle for file %s: %s - "
761 "proceeding with normal close\n",
762 fsp_str_dbg(fsp), nt_errstr(tmp)));
764 scavenger_schedule_disconnected(fsp);
766 DEBUG(1, ("Failed to disconnect durable handle for "
767 "file %s: %s - proceeding with normal "
768 "close\n", fsp_str_dbg(fsp), nt_errstr(tmp)));
770 if (!NT_STATUS_IS_OK(tmp)) {
777 * This is the case where we successfully disconnected
778 * a durable handle and closed the underlying file.
779 * In all other cases, we proceed with a genuine close.
781 DEBUG(10, ("%s disconnected durable handle for file %s\n",
782 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) ));
838 /****************************************************************************
839 Function used by reply_rmdir to delete an entire directory
840 tree recursively. Return True on ok, False on fail.
841 ****************************************************************************/
843 bool recursive_rmdir(TALLOC_CTX *ctx,
844 connection_struct *conn,
845 struct smb_filename *smb_dname)
847 const char *dname = NULL;
848 char *talloced = NULL;
852 struct smb_Dir *dir_hnd;
853 struct files_struct *dirfsp = NULL;
857 SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
859 dir_hnd = OpenDir(talloc_tos(), conn, smb_dname, NULL, 0);
863 dirfsp = dir_hnd_fetch_fsp(dir_hnd);
865 while ((dname = ReadDirName(dir_hnd, &offset, &st, &talloced))) {
866 struct smb_filename *atname = NULL;
867 struct smb_filename *smb_dname_full = NULL;
868 char *fullname = NULL;
869 bool do_break = true;
870 int unlink_flags = 0;
872 if (ISDOT(dname) || ISDOTDOT(dname)) {
873 TALLOC_FREE(talloced);
877 /* Construct the full name. */
878 fullname = talloc_asprintf(ctx,
880 smb_dname->base_name,
887 smb_dname_full = synthetic_smb_fname(talloc_tos(),
893 if (smb_dname_full == NULL) {
898 if (SMB_VFS_LSTAT(conn, smb_dname_full) != 0) {
902 if (smb_dname_full->st.st_ex_mode & S_IFDIR) {
903 if (!recursive_rmdir(ctx, conn, smb_dname_full)) {
906 unlink_flags = AT_REMOVEDIR;
909 status = synthetic_pathref(talloc_tos(),
914 smb_dname_full->twrp,
915 smb_dname_full->flags,
917 if (!NT_STATUS_IS_OK(status)) {
918 errno = map_errno_from_nt_status(status);
922 if (!is_visible_fsp(atname->fsp)) {
923 TALLOC_FREE(smb_dname_full);
924 TALLOC_FREE(fullname);
925 TALLOC_FREE(talloced);
930 retval = SMB_VFS_UNLINKAT(conn,
938 /* Successful iteration. */
942 TALLOC_FREE(smb_dname_full);
943 TALLOC_FREE(fullname);
944 TALLOC_FREE(talloced);
951 TALLOC_FREE(dir_hnd);
955 /****************************************************************************
956 The internals of the rmdir code - called elsewhere.
957 ****************************************************************************/
959 static NTSTATUS rmdir_internals(TALLOC_CTX *ctx, struct files_struct *fsp)
961 struct connection_struct *conn = fsp->conn;
962 struct smb_filename *smb_dname = fsp->fsp_name;
963 struct smb_filename *parent_fname = NULL;
964 struct smb_filename *at_fname = NULL;
966 const char *dname = NULL;
967 char *talloced = NULL;
969 struct smb_Dir *dir_hnd = NULL;
970 struct files_struct *dirfsp = NULL;
971 int unlink_flags = 0;
975 SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
977 status = parent_pathref(talloc_tos(),
982 if (!NT_STATUS_IS_OK(status)) {
987 * Todo: use SMB_VFS_STATX() once it's available.
990 /* Might be a symlink. */
991 ret = SMB_VFS_LSTAT(conn, smb_dname);
993 TALLOC_FREE(parent_fname);
994 return map_nt_error_from_unix(errno);
997 if (S_ISLNK(smb_dname->st.st_ex_mode)) {
998 /* Is what it points to a directory ? */
999 ret = SMB_VFS_STAT(conn, smb_dname);
1001 TALLOC_FREE(parent_fname);
1002 return map_nt_error_from_unix(errno);
1004 if (!(S_ISDIR(smb_dname->st.st_ex_mode))) {
1005 TALLOC_FREE(parent_fname);
1006 return NT_STATUS_NOT_A_DIRECTORY;
1009 unlink_flags = AT_REMOVEDIR;
1012 ret = SMB_VFS_UNLINKAT(conn,
1017 TALLOC_FREE(parent_fname);
1018 notify_fname(conn, NOTIFY_ACTION_REMOVED,
1019 FILE_NOTIFY_CHANGE_DIR_NAME,
1020 smb_dname->base_name);
1021 return NT_STATUS_OK;
1024 if (!((errno == ENOTEMPTY) || (errno == EEXIST))) {
1025 DEBUG(3,("rmdir_internals: couldn't remove directory %s : "
1026 "%s\n", smb_fname_str_dbg(smb_dname),
1028 TALLOC_FREE(parent_fname);
1029 return map_nt_error_from_unix(errno);
1033 * Here we know the initial directory unlink failed with
1034 * ENOTEMPTY or EEXIST so we know there are objects within.
1035 * If we don't have permission to delete files non
1036 * visible to the client just fail the directory delete.
1039 if (!lp_delete_veto_files(SNUM(conn))) {
1045 * Check to see if the only thing in this directory are
1046 * files non-visible to the client. If not, fail the delete.
1049 dir_hnd = OpenDir(talloc_tos(), conn, smb_dname, NULL, 0);
1050 if (dir_hnd == NULL) {
1055 while ((dname = ReadDirName(dir_hnd, &dirpos, &st, &talloced)) != NULL) {
1056 struct smb_filename *smb_dname_full = NULL;
1057 struct smb_filename *direntry_fname = NULL;
1058 char *fullname = NULL;
1060 if (ISDOT(dname) || ISDOTDOT(dname)) {
1061 TALLOC_FREE(talloced);
1064 if (IS_VETO_PATH(conn, dname)) {
1065 TALLOC_FREE(talloced);
1069 fullname = talloc_asprintf(talloc_tos(),
1071 smb_dname->base_name,
1074 if (fullname == NULL) {
1075 TALLOC_FREE(talloced);
1080 smb_dname_full = synthetic_smb_fname(talloc_tos(),
1086 if (smb_dname_full == NULL) {
1087 TALLOC_FREE(talloced);
1088 TALLOC_FREE(fullname);
1093 ret = SMB_VFS_LSTAT(conn, smb_dname_full);
1095 int saved_errno = errno;
1096 TALLOC_FREE(talloced);
1097 TALLOC_FREE(fullname);
1098 TALLOC_FREE(smb_dname_full);
1099 errno = saved_errno;
1103 if (S_ISLNK(smb_dname_full->st.st_ex_mode)) {
1104 /* Could it be an msdfs link ? */
1105 if (lp_host_msdfs() &&
1106 lp_msdfs_root(SNUM(conn))) {
1107 struct smb_filename *smb_atname;
1108 smb_atname = synthetic_smb_fname(talloc_tos(),
1111 &smb_dname_full->st,
1112 fsp->fsp_name->twrp,
1113 fsp->fsp_name->flags);
1114 if (smb_atname == NULL) {
1115 TALLOC_FREE(talloced);
1116 TALLOC_FREE(fullname);
1117 TALLOC_FREE(smb_dname_full);
1121 if (is_msdfs_link(fsp, smb_atname)) {
1122 TALLOC_FREE(talloced);
1123 TALLOC_FREE(fullname);
1124 TALLOC_FREE(smb_dname_full);
1125 TALLOC_FREE(smb_atname);
1126 DBG_DEBUG("got msdfs link name %s "
1127 "- can't delete directory %s\n",
1133 TALLOC_FREE(smb_atname);
1136 /* Not a DFS link - could it be a dangling symlink ? */
1137 ret = SMB_VFS_STAT(conn, smb_dname_full);
1138 if (ret == -1 && (errno == ENOENT || errno == ELOOP)) {
1141 * Allow delete as "delete veto files = yes"
1143 TALLOC_FREE(talloced);
1144 TALLOC_FREE(fullname);
1145 TALLOC_FREE(smb_dname_full);
1149 DBG_DEBUG("got symlink name %s - "
1150 "can't delete directory %s\n",
1153 TALLOC_FREE(talloced);
1154 TALLOC_FREE(fullname);
1155 TALLOC_FREE(smb_dname_full);
1160 /* Not a symlink, get a pathref. */
1161 status = synthetic_pathref(talloc_tos(),
1165 &smb_dname_full->st,
1169 if (!NT_STATUS_IS_OK(status)) {
1170 TALLOC_FREE(talloced);
1171 TALLOC_FREE(fullname);
1172 TALLOC_FREE(smb_dname_full);
1173 errno = map_errno_from_nt_status(status);
1177 if (!is_visible_fsp(direntry_fname->fsp)) {
1178 TALLOC_FREE(talloced);
1179 TALLOC_FREE(fullname);
1180 TALLOC_FREE(smb_dname_full);
1181 TALLOC_FREE(direntry_fname);
1186 * We found a client visible name.
1187 * We cannot delete this directory.
1189 DBG_DEBUG("got name %s - "
1190 "can't delete directory %s\n",
1193 TALLOC_FREE(talloced);
1194 TALLOC_FREE(fullname);
1195 TALLOC_FREE(smb_dname_full);
1196 TALLOC_FREE(direntry_fname);
1201 /* Do a recursive delete. */
1202 RewindDir(dir_hnd,&dirpos);
1203 dirfsp = dir_hnd_fetch_fsp(dir_hnd);
1205 while ((dname = ReadDirName(dir_hnd, &dirpos, &st, &talloced)) != NULL) {
1206 struct smb_filename *direntry_fname = NULL;
1207 struct smb_filename *smb_dname_full = NULL;
1208 char *fullname = NULL;
1209 bool do_break = true;
1212 if (ISDOT(dname) || ISDOTDOT(dname)) {
1213 TALLOC_FREE(talloced);
1217 fullname = talloc_asprintf(ctx,
1219 smb_dname->base_name,
1222 if (fullname == NULL) {
1227 smb_dname_full = synthetic_smb_fname(talloc_tos(),
1233 if (smb_dname_full == NULL) {
1239 * Todo: use SMB_VFS_STATX() once that's available.
1242 ret = SMB_VFS_LSTAT(conn, smb_dname_full);
1248 * We are only dealing with VETO'ed objects
1249 * here. If it's a symlink, just delete the
1250 * link without caring what it is pointing
1253 if (S_ISLNK(smb_dname_full->st.st_ex_mode)) {
1254 direntry_fname = synthetic_smb_fname(talloc_tos(),
1257 &smb_dname_full->st,
1260 if (direntry_fname == NULL) {
1265 status = synthetic_pathref(talloc_tos(),
1269 &smb_dname_full->st,
1273 if (!NT_STATUS_IS_OK(status)) {
1274 errno = map_errno_from_nt_status(status);
1278 if (!is_visible_fsp(direntry_fname->fsp)) {
1279 TALLOC_FREE(fullname);
1280 TALLOC_FREE(smb_dname_full);
1281 TALLOC_FREE(talloced);
1282 TALLOC_FREE(direntry_fname);
1289 if (smb_dname_full->st.st_ex_mode & S_IFDIR) {
1290 if (!recursive_rmdir(ctx, conn,
1295 unlink_flags = AT_REMOVEDIR;
1298 retval = SMB_VFS_UNLINKAT(conn,
1306 /* Successful iteration. */
1310 TALLOC_FREE(fullname);
1311 TALLOC_FREE(smb_dname_full);
1312 TALLOC_FREE(talloced);
1313 TALLOC_FREE(direntry_fname);
1319 /* Retry the rmdir */
1320 ret = SMB_VFS_UNLINKAT(conn,
1328 TALLOC_FREE(dir_hnd);
1329 TALLOC_FREE(parent_fname);
1332 DEBUG(3,("rmdir_internals: couldn't remove directory %s : "
1333 "%s\n", smb_fname_str_dbg(smb_dname),
1335 return map_nt_error_from_unix(errno);
1338 notify_fname(conn, NOTIFY_ACTION_REMOVED,
1339 FILE_NOTIFY_CHANGE_DIR_NAME,
1340 smb_dname->base_name);
1342 return NT_STATUS_OK;
1345 /****************************************************************************
1346 Close a directory opened by an NT SMB call.
1347 ****************************************************************************/
1349 static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
1350 enum file_close_type close_type)
1352 struct share_mode_lock *lck = NULL;
1353 bool delete_dir = False;
1354 NTSTATUS status = NT_STATUS_OK;
1355 NTSTATUS status1 = NT_STATUS_OK;
1356 const struct security_token *del_nt_token = NULL;
1357 const struct security_unix_token *del_token = NULL;
1358 NTSTATUS notify_status;
1360 SMB_ASSERT(fsp->fsp_flags.is_fsa);
1362 if (fsp->conn->sconn->using_smb2) {
1363 notify_status = NT_STATUS_NOTIFY_CLEANUP;
1365 notify_status = NT_STATUS_OK;
1368 assert_no_pending_aio(fsp, close_type);
1371 * NT can set delete_on_close of the last open
1372 * reference to a directory also.
1375 lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
1377 DEBUG(0, ("close_directory: Could not get share mode lock for "
1378 "%s\n", fsp_str_dbg(fsp)));
1379 file_free(req, 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 file_free(req, fsp);
1434 status = rmdir_internals(talloc_tos(), fsp);
1436 DEBUG(5,("close_directory: %s. Delete on close was set - "
1437 "deleting directory returned %s.\n",
1438 fsp_str_dbg(fsp), nt_errstr(status)));
1440 /* unbecome user. */
1444 * Ensure we remove any change notify requests that would
1445 * now fail as the directory has been deleted.
1448 if (NT_STATUS_IS_OK(status)) {
1449 notify_status = NT_STATUS_DELETE_PENDING;
1452 if (!del_share_mode(lck, fsp)) {
1453 DEBUG(0, ("close_directory: Could not delete share entry for "
1454 "%s\n", fsp_str_dbg(fsp)));
1460 remove_pending_change_notify_requests_by_fid(fsp, notify_status);
1462 status1 = fd_close(fsp);
1464 if (!NT_STATUS_IS_OK(status1)) {
1465 DEBUG(0, ("Could not close dir! fname=%s, fd=%d, err=%d=%s\n",
1466 fsp_str_dbg(fsp), fsp_get_pathref_fd(fsp), errno,
1471 * Do the code common to files and directories.
1473 file_free(req, fsp);
1475 if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(status1)) {
1481 /****************************************************************************
1482 Close a files_struct.
1483 ****************************************************************************/
1485 NTSTATUS close_file(struct smb_request *req, files_struct *fsp,
1486 enum file_close_type close_type)
1489 struct files_struct *base_fsp = fsp->base_fsp;
1490 bool close_base_fsp = false;
1493 * This fsp can never be an internal dirfsp. They must
1494 * be explicitly closed by TALLOC_FREE of the dir handle.
1496 SMB_ASSERT(!fsp->fsp_flags.is_dirfsp);
1498 if (fsp->stream_fsp != NULL) {
1500 * fsp is the base for a stream.
1502 * We're called with SHUTDOWN_CLOSE from files.c which walks the
1503 * complete list of files.
1505 * We need to wait until the stream is closed.
1507 SMB_ASSERT(close_type == SHUTDOWN_CLOSE);
1508 return NT_STATUS_OK;
1511 if (base_fsp != NULL) {
1513 * We need to remove the link in order to
1514 * recurse for the base fsp below.
1516 SMB_ASSERT(base_fsp->base_fsp == NULL);
1517 SMB_ASSERT(base_fsp->stream_fsp == fsp);
1518 base_fsp->stream_fsp = NULL;
1520 if (close_type == SHUTDOWN_CLOSE) {
1522 * We're called with SHUTDOWN_CLOSE from files.c
1523 * which walks the complete list of files.
1525 * We may need to defer the SHUTDOWN_CLOSE
1526 * if it's the next in the linked list.
1528 * So we only close if the base is *not* the
1531 close_base_fsp = (fsp->next != base_fsp);
1533 close_base_fsp = true;
1537 if (fsp->fake_file_handle != NULL) {
1538 status = close_fake_file(req, fsp);
1539 } else if (fsp->print_file != NULL) {
1540 /* FIXME: return spool errors */
1541 print_spool_end(fsp, close_type);
1542 file_free(req, fsp);
1543 status = NT_STATUS_OK;
1544 } else if (!fsp->fsp_flags.is_fsa) {
1545 if (close_type == NORMAL_CLOSE) {
1546 DBG_ERR("unexpected NORMAL_CLOSE for [%s] "
1547 "is_fsa[%u] is_pathref[%u] is_directory[%u]\n",
1549 fsp->fsp_flags.is_fsa,
1550 fsp->fsp_flags.is_pathref,
1551 fsp->fsp_flags.is_directory);
1553 SMB_ASSERT(close_type != NORMAL_CLOSE);
1555 file_free(req, fsp);
1556 status = NT_STATUS_OK;
1557 } else if (fsp->fsp_flags.is_directory) {
1558 status = close_directory(req, fsp, close_type);
1560 status = close_normal_file(req, fsp, close_type);
1563 if (close_base_fsp) {
1566 * fsp was a stream, the base fsp can't be a stream as well
1568 * For SHUTDOWN_CLOSE this is not possible here
1569 * (if the base_fsp was the next in the linked list), because
1570 * SHUTDOWN_CLOSE only happens from files.c which walks the
1571 * complete list of files. If we mess with more than one fsp
1572 * those loops will become confused.
1575 close_file(req, base_fsp, close_type);
1581 /****************************************************************************
1582 Deal with an (authorized) message to close a file given the share mode
1584 ****************************************************************************/
1586 void msg_close_file(struct messaging_context *msg_ctx,
1589 struct server_id server_id,
1592 files_struct *fsp = NULL;
1594 struct share_mode_entry e;
1595 struct smbd_server_connection *sconn =
1596 talloc_get_type_abort(private_data,
1597 struct smbd_server_connection);
1599 message_to_share_mode_entry(&id, &e, (char *)data->data);
1602 char *sm_str = share_mode_str(NULL, 0, &id, &e);
1604 smb_panic("talloc failed");
1606 DEBUG(10,("msg_close_file: got request to close share mode "
1607 "entry %s\n", sm_str));
1608 TALLOC_FREE(sm_str);
1611 fsp = file_find_dif(sconn, id, e.share_file_id);
1613 DEBUG(10,("msg_close_file: failed to find file.\n"));
1616 close_file(NULL, fsp, NORMAL_CLOSE);