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);
369 * Never try to delete the file for ERROR_CLOSE
375 status = NT_STATUS_OK;
380 * Ok, we have to delete the file
383 DEBUG(5,("close_remove_share_mode: file %s. Delete on close was set "
384 "- deleting file.\n", fsp_str_dbg(fsp)));
387 * Don't try to update the write time when we delete the file
389 fsp->fsp_flags.update_write_time_on_close = false;
391 got_tokens = get_delete_on_close_token(lck, fsp->name_hash,
392 &del_nt_token, &del_token);
393 SMB_ASSERT(got_tokens);
395 if (!unix_token_equal(del_token, get_current_utok(conn))) {
396 /* Become the user who requested the delete. */
398 DEBUG(5,("close_remove_share_mode: file %s. "
399 "Change user to uid %u\n",
401 (unsigned int)del_token->uid));
403 if (!push_sec_ctx()) {
404 smb_panic("close_remove_share_mode: file %s. failed to push "
408 set_sec_ctx(del_token->uid,
417 /* We can only delete the file if the name we have is still valid and
418 hasn't been renamed. */
420 tmp_status = vfs_stat_fsp(fsp);
421 if (!NT_STATUS_IS_OK(tmp_status)) {
422 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
423 "was set and stat failed with error %s\n",
424 fsp_str_dbg(fsp), nt_errstr(tmp_status)));
426 * Don't save the errno here, we ignore this error
431 id = vfs_file_id_from_sbuf(conn, &fsp->fsp_name->st);
433 if (!file_id_equal(&fsp->file_id, &id)) {
434 struct file_id_buf ftmp1, ftmp2;
435 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
436 "was set and dev and/or inode does not match\n",
438 DEBUG(5,("close_remove_share_mode: file %s. stored file_id %s, "
441 file_id_str_buf(fsp->file_id, &ftmp1),
442 file_id_str_buf(id, &ftmp2)));
444 * Don't save the errno here, we ignore this error
449 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
450 && !fsp_is_alternate_stream(fsp)) {
452 status = delete_all_streams(conn, fsp->fsp_name);
454 if (!NT_STATUS_IS_OK(status)) {
455 DEBUG(5, ("delete_all_streams failed: %s\n",
461 if (fsp->fsp_flags.kernel_share_modes_taken) {
463 * A file system sharemode could block the unlink;
464 * remove filesystem sharemodes first.
466 ret = SMB_VFS_FILESYSTEM_SHAREMODE(fsp, 0, 0);
468 DBG_INFO("Removing file system sharemode for %s "
470 fsp_str_dbg(fsp), strerror(errno));
473 fsp->fsp_flags.kernel_share_modes_taken = false;
476 status = parent_pathref(talloc_tos(),
481 if (!NT_STATUS_IS_OK(status)) {
485 ret = SMB_VFS_UNLINKAT(conn,
489 TALLOC_FREE(parent_fname);
493 * This call can potentially fail as another smbd may
494 * have had the file open with delete on close set and
495 * deleted it when its last reference to this file
496 * went away. Hence we log this but not at debug level
500 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
501 "was set and unlink failed with error %s\n",
502 fsp_str_dbg(fsp), strerror(errno)));
504 status = map_nt_error_from_unix(errno);
507 /* As we now have POSIX opens which can unlink
508 * with other open files we may have taken
509 * this code path with more than one share mode
510 * entry - ensure we only delete once by resetting
511 * the delete on close flag. JRA.
514 fsp->fsp_flags.delete_on_close = false;
515 reset_delete_on_close_lck(fsp, lck);
524 if (fsp->fsp_flags.kernel_share_modes_taken) {
525 /* remove filesystem sharemodes */
526 ret = SMB_VFS_FILESYSTEM_SHAREMODE(fsp, 0, 0);
528 DBG_INFO("Removing file system sharemode for "
530 fsp_str_dbg(fsp), strerror(errno));
534 if (!del_share_mode(lck, fsp)) {
535 DEBUG(0, ("close_remove_share_mode: Could not delete share "
536 "entry for file %s\n", fsp_str_dbg(fsp)));
543 * Do the notification after we released the share
544 * mode lock. Inside notify_fname we take out another
545 * tdb lock. With ctdb also accessing our databases,
546 * this can lead to deadlocks. Putting this notify
547 * after the TALLOC_FREE(lck) above we avoid locking
548 * two records simultaneously. Notifies are async and
549 * informational only, so calling the notify_fname
550 * without holding the share mode lock should not do
553 notify_fname(conn, NOTIFY_ACTION_REMOVED,
554 FILE_NOTIFY_CHANGE_FILE_NAME,
555 fsp->fsp_name->base_name);
561 void set_close_write_time(struct files_struct *fsp, struct timespec ts)
563 DEBUG(6,("close_write_time: %s" , time_to_asc(convert_timespec_to_time_t(ts))));
565 if (is_omit_timespec(&ts)) {
568 fsp->fsp_flags.write_time_forced = false;
569 fsp->fsp_flags.update_write_time_on_close = true;
570 fsp->close_write_time = ts;
573 static void update_write_time_on_close_share_mode_fn(struct share_mode_lock *lck,
576 struct files_struct *fsp =
577 talloc_get_type_abort(private_data,
578 struct files_struct);
579 NTTIME share_mtime = share_mode_changed_write_time(lck);
582 * On close if we're changing the real file time we
583 * must update it in the open file db too.
585 share_mode_set_old_write_time(lck, fsp->close_write_time);
588 * Close write times overwrite sticky write times
589 * so we must replace any sticky write time here.
591 if (!null_nttime(share_mtime)) {
592 share_mode_set_changed_write_time(lck, fsp->close_write_time);
596 static NTSTATUS update_write_time_on_close(struct files_struct *fsp)
598 struct smb_file_time ft;
601 init_smb_file_time(&ft);
603 if (!(fsp->fsp_flags.update_write_time_on_close)) {
607 if (is_omit_timespec(&fsp->close_write_time)) {
608 fsp->close_write_time = timespec_current();
611 /* Ensure we have a valid stat struct for the source. */
612 status = vfs_stat_fsp(fsp);
613 if (!NT_STATUS_IS_OK(status)) {
617 if (!VALID_STAT(fsp->fsp_name->st)) {
618 /* if it doesn't seem to be a real file */
623 * We're being called after close_remove_share_mode() inside
624 * close_normal_file() so it's quite normal to not have an
625 * existing share. So just ignore the result of
626 * share_mode_do_locked_vfs_denied()...
628 share_mode_do_locked_vfs_denied(fsp->file_id,
629 update_write_time_on_close_share_mode_fn,
632 ft.mtime = fsp->close_write_time;
633 /* As this is a close based update, we are not directly changing the
634 file attributes from a client call, but indirectly from a write. */
635 status = smb_set_file_time(fsp->conn, fsp, fsp->fsp_name, &ft, false);
636 if (!NT_STATUS_IS_OK(status)) {
637 DEBUG(10,("update_write_time_on_close: smb_set_file_time "
638 "on file %s returned %s\n",
647 static NTSTATUS ntstatus_keeperror(NTSTATUS s1, NTSTATUS s2)
649 if (!NT_STATUS_IS_OK(s1)) {
655 static void assert_no_pending_aio(struct files_struct *fsp,
656 enum file_close_type close_type)
658 struct smbXsrv_client *client = global_smbXsrv_client;
659 size_t num_connections_alive;
660 unsigned num_requests = fsp->num_aio_requests;
662 if (num_requests == 0) {
666 num_connections_alive = smbXsrv_client_valid_connections(client);
668 if (close_type == SHUTDOWN_CLOSE && num_connections_alive == 0) {
670 * fsp->aio_requests and the contents (fsp->aio_requests[x])
671 * are both independently owned by fsp and are not in a
672 * talloc heirarchy. This allows the fsp->aio_requests array to
673 * be reallocated independently of the array contents so it can
676 * This means we must ensure order of deallocation
677 * on a SHUTDOWN_CLOSE by deallocating the fsp->aio_requests[x]
678 * contents first, as their destructors access the
679 * fsp->aio_request array. If we don't deallocate them
680 * first, when fsp is deallocated fsp->aio_requests
681 * could have been deallocated *before* its contents
682 * fsp->aio_requests[x], causing a crash.
684 while (fsp->num_aio_requests != 0) {
687 * talloc_free(fsp->aio_requests[0]),
688 * and *NOT* TALLOC_FREE() here, as
689 * TALLOC_FREE(fsp->aio_requests[0])
690 * will overwrite any new contents of
691 * fsp->aio_requests[0] that were
692 * copied into it via the destructor
693 * aio_del_req_from_fsp().
695 * BUG: https://bugzilla.samba.org/show_bug.cgi?id=14515
697 talloc_free(fsp->aio_requests[0]);
702 DBG_ERR("fsp->num_aio_requests=%u\n", num_requests);
703 smb_panic("can not close with outstanding aio requests");
707 /****************************************************************************
710 close_type can be NORMAL_CLOSE=0,SHUTDOWN_CLOSE,ERROR_CLOSE.
711 printing and magic scripts are only run on normal close.
712 delete on close is done on normal and shutdown close.
713 ****************************************************************************/
715 static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp,
716 enum file_close_type close_type)
718 NTSTATUS status = NT_STATUS_OK;
720 connection_struct *conn = fsp->conn;
721 bool is_durable = false;
723 SMB_ASSERT(fsp->fsp_flags.is_fsa);
725 assert_no_pending_aio(fsp, close_type);
727 while (talloc_array_length(fsp->blocked_smb1_lock_reqs) != 0) {
728 smbd_smb1_brl_finish_by_req(
729 fsp->blocked_smb1_lock_reqs[0],
730 NT_STATUS_RANGE_NOT_LOCKED);
734 * If we're flushing on a close we can get a write
735 * error here, we must remember this.
738 if (NT_STATUS_IS_OK(status) && fsp->op != NULL) {
739 is_durable = fsp->op->global->durable;
742 if (close_type != SHUTDOWN_CLOSE) {
747 DATA_BLOB new_cookie = data_blob_null;
749 tmp = SMB_VFS_DURABLE_DISCONNECT(fsp,
750 fsp->op->global->backend_cookie,
753 if (NT_STATUS_IS_OK(tmp)) {
758 tv = req->request_time;
760 tv = timeval_current();
762 now = timeval_to_nttime(&tv);
764 data_blob_free(&fsp->op->global->backend_cookie);
765 fsp->op->global->backend_cookie = new_cookie;
767 fsp->op->compat = NULL;
768 tmp = smbXsrv_open_close(fsp->op, now);
769 if (!NT_STATUS_IS_OK(tmp)) {
770 DEBUG(1, ("Failed to update smbXsrv_open "
771 "record when disconnecting durable "
772 "handle for file %s: %s - "
773 "proceeding with normal close\n",
774 fsp_str_dbg(fsp), nt_errstr(tmp)));
776 scavenger_schedule_disconnected(fsp);
778 DEBUG(1, ("Failed to disconnect durable handle for "
779 "file %s: %s - proceeding with normal "
780 "close\n", fsp_str_dbg(fsp), nt_errstr(tmp)));
782 if (!NT_STATUS_IS_OK(tmp)) {
789 * This is the case where we successfully disconnected
790 * a durable handle and closed the underlying file.
791 * In all other cases, we proceed with a genuine close.
793 DEBUG(10, ("%s disconnected durable handle for file %s\n",
794 conn->session_info->unix_info->unix_name,
799 if (fsp->op != NULL) {
801 * Make sure the handle is not marked as durable anymore
803 fsp->op->global->durable = false;
806 /* If this is an old DOS or FCB open and we have multiple opens on
807 the same handle we only have one share mode. Ensure we only remove
808 the share mode on the last close. */
810 if (fh_get_refcount(fsp->fh) == 1) {
811 /* Should we return on error here... ? */
812 tmp = close_remove_share_mode(fsp, close_type);
813 status = ntstatus_keeperror(status, tmp);
816 locking_close_file(fsp, close_type);
819 * Ensure pending modtime is set before closing underlying fd.
822 tmp = update_write_time_on_close(fsp);
823 if (NT_STATUS_EQUAL(tmp, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
825 * Someone renamed the file or a parent directory containing
826 * this file. We can't do anything about this, eat the error.
830 status = ntstatus_keeperror(status, tmp);
833 status = ntstatus_keeperror(status, tmp);
835 /* check for magic scripts */
836 if (close_type == NORMAL_CLOSE) {
837 tmp = check_magic(fsp);
838 status = ntstatus_keeperror(status, tmp);
841 DEBUG(2,("%s closed file %s (numopen=%d) %s\n",
842 conn->session_info->unix_info->unix_name, fsp_str_dbg(fsp),
843 conn->num_files_open - 1,
844 nt_errstr(status) ));
848 /****************************************************************************
849 Function used by reply_rmdir to delete an entire directory
850 tree recursively. Return True on ok, False on fail.
851 ****************************************************************************/
853 NTSTATUS recursive_rmdir(TALLOC_CTX *ctx,
854 connection_struct *conn,
855 struct smb_filename *smb_dname)
857 const char *dname = NULL;
858 char *talloced = NULL;
860 struct smb_Dir *dir_hnd = NULL;
861 struct files_struct *dirfsp = NULL;
863 NTSTATUS status = NT_STATUS_OK;
865 SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
867 status = OpenDir(talloc_tos(),
873 if (!NT_STATUS_IS_OK(status)) {
877 dirfsp = dir_hnd_fetch_fsp(dir_hnd);
879 while ((dname = ReadDirName(dir_hnd, &offset, NULL, &talloced))) {
880 struct smb_filename *atname = NULL;
881 struct smb_filename *smb_dname_full = NULL;
882 char *fullname = NULL;
883 bool do_break = true;
884 int unlink_flags = 0;
886 if (ISDOT(dname) || ISDOTDOT(dname)) {
887 TALLOC_FREE(talloced);
891 /* Construct the full name. */
892 fullname = talloc_asprintf(ctx,
894 smb_dname->base_name,
897 status = NT_STATUS_NO_MEMORY;
901 smb_dname_full = synthetic_smb_fname(talloc_tos(),
907 if (smb_dname_full == NULL) {
908 status = NT_STATUS_NO_MEMORY;
912 if (SMB_VFS_LSTAT(conn, smb_dname_full) != 0) {
913 status = map_nt_error_from_unix(errno);
917 if (smb_dname_full->st.st_ex_mode & S_IFDIR) {
918 status = recursive_rmdir(ctx, conn, smb_dname_full);
919 if (!NT_STATUS_IS_OK(status)) {
922 unlink_flags = AT_REMOVEDIR;
925 status = synthetic_pathref(talloc_tos(),
930 smb_dname_full->twrp,
931 smb_dname_full->flags,
933 if (!NT_STATUS_IS_OK(status)) {
937 if (!is_visible_fsp(atname->fsp)) {
938 TALLOC_FREE(smb_dname_full);
939 TALLOC_FREE(fullname);
940 TALLOC_FREE(talloced);
945 retval = SMB_VFS_UNLINKAT(conn,
950 status = map_nt_error_from_unix(errno);
954 /* Successful iteration. */
958 TALLOC_FREE(smb_dname_full);
959 TALLOC_FREE(fullname);
960 TALLOC_FREE(talloced);
966 TALLOC_FREE(dir_hnd);
970 /****************************************************************************
971 The internals of the rmdir code - called elsewhere.
972 ****************************************************************************/
974 static NTSTATUS rmdir_internals(TALLOC_CTX *ctx, struct files_struct *fsp)
976 struct connection_struct *conn = fsp->conn;
977 struct smb_filename *smb_dname = fsp->fsp_name;
978 struct smb_filename *parent_fname = NULL;
979 struct smb_filename *at_fname = NULL;
980 const char *dname = NULL;
981 char *talloced = NULL;
983 struct smb_Dir *dir_hnd = NULL;
984 struct files_struct *dirfsp = NULL;
985 int unlink_flags = 0;
989 SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
991 status = parent_pathref(talloc_tos(),
996 if (!NT_STATUS_IS_OK(status)) {
1001 * Todo: use SMB_VFS_STATX() once it's available.
1004 /* Might be a symlink. */
1005 ret = SMB_VFS_LSTAT(conn, smb_dname);
1007 TALLOC_FREE(parent_fname);
1008 return map_nt_error_from_unix(errno);
1011 if (S_ISLNK(smb_dname->st.st_ex_mode)) {
1012 /* Is what it points to a directory ? */
1013 ret = SMB_VFS_STAT(conn, smb_dname);
1015 TALLOC_FREE(parent_fname);
1016 return map_nt_error_from_unix(errno);
1018 if (!(S_ISDIR(smb_dname->st.st_ex_mode))) {
1019 TALLOC_FREE(parent_fname);
1020 return NT_STATUS_NOT_A_DIRECTORY;
1023 unlink_flags = AT_REMOVEDIR;
1026 ret = SMB_VFS_UNLINKAT(conn,
1031 TALLOC_FREE(parent_fname);
1032 notify_fname(conn, NOTIFY_ACTION_REMOVED,
1033 FILE_NOTIFY_CHANGE_DIR_NAME,
1034 smb_dname->base_name);
1035 return NT_STATUS_OK;
1038 if (!((errno == ENOTEMPTY) || (errno == EEXIST))) {
1039 DEBUG(3,("rmdir_internals: couldn't remove directory %s : "
1040 "%s\n", smb_fname_str_dbg(smb_dname),
1042 TALLOC_FREE(parent_fname);
1043 return map_nt_error_from_unix(errno);
1047 * Here we know the initial directory unlink failed with
1048 * ENOTEMPTY or EEXIST so we know there are objects within.
1049 * If we don't have permission to delete files non
1050 * visible to the client just fail the directory delete.
1053 if (!lp_delete_veto_files(SNUM(conn))) {
1054 status = NT_STATUS_DIRECTORY_NOT_EMPTY;
1059 * Check to see if the only thing in this directory are
1060 * files non-visible to the client. If not, fail the delete.
1063 status = OpenDir(talloc_tos(),
1069 if (!NT_STATUS_IS_OK(status)) {
1071 * Note, we deliberately squash the error here
1072 * to avoid leaking information about what we
1075 status = NT_STATUS_DIRECTORY_NOT_EMPTY;
1079 dirfsp = dir_hnd_fetch_fsp(dir_hnd);
1081 while ((dname = ReadDirName(
1082 dir_hnd, &dirpos, NULL, &talloced)) != NULL) {
1083 struct smb_filename *smb_dname_full = NULL;
1084 struct smb_filename *direntry_fname = NULL;
1085 char *fullname = NULL;
1088 if (ISDOT(dname) || ISDOTDOT(dname)) {
1089 TALLOC_FREE(talloced);
1092 if (IS_VETO_PATH(conn, dname)) {
1093 TALLOC_FREE(talloced);
1097 fullname = talloc_asprintf(talloc_tos(),
1099 smb_dname->base_name,
1102 if (fullname == NULL) {
1103 TALLOC_FREE(talloced);
1104 status = NT_STATUS_NO_MEMORY;
1108 smb_dname_full = synthetic_smb_fname(talloc_tos(),
1114 if (smb_dname_full == NULL) {
1115 TALLOC_FREE(talloced);
1116 TALLOC_FREE(fullname);
1117 status = NT_STATUS_NO_MEMORY;
1121 retval = SMB_VFS_LSTAT(conn, smb_dname_full);
1123 status = map_nt_error_from_unix(errno);
1124 TALLOC_FREE(talloced);
1125 TALLOC_FREE(fullname);
1126 TALLOC_FREE(smb_dname_full);
1130 if (S_ISLNK(smb_dname_full->st.st_ex_mode)) {
1131 /* Could it be an msdfs link ? */
1132 if (lp_host_msdfs() &&
1133 lp_msdfs_root(SNUM(conn))) {
1134 struct smb_filename *smb_atname;
1135 smb_atname = synthetic_smb_fname(talloc_tos(),
1138 &smb_dname_full->st,
1139 fsp->fsp_name->twrp,
1140 fsp->fsp_name->flags);
1141 if (smb_atname == NULL) {
1142 TALLOC_FREE(talloced);
1143 TALLOC_FREE(fullname);
1144 TALLOC_FREE(smb_dname_full);
1145 status = NT_STATUS_NO_MEMORY;
1148 if (is_msdfs_link(fsp, smb_atname)) {
1149 TALLOC_FREE(talloced);
1150 TALLOC_FREE(fullname);
1151 TALLOC_FREE(smb_dname_full);
1152 TALLOC_FREE(smb_atname);
1153 DBG_DEBUG("got msdfs link name %s "
1154 "- can't delete directory %s\n",
1157 status = NT_STATUS_DIRECTORY_NOT_EMPTY;
1160 TALLOC_FREE(smb_atname);
1163 /* Not a DFS link - could it be a dangling symlink ? */
1164 retval = SMB_VFS_STAT(conn, smb_dname_full);
1165 if (retval == -1 && (errno == ENOENT || errno == ELOOP)) {
1168 * Allow delete as "delete veto files = yes"
1170 TALLOC_FREE(talloced);
1171 TALLOC_FREE(fullname);
1172 TALLOC_FREE(smb_dname_full);
1176 DBG_DEBUG("got symlink name %s - "
1177 "can't delete directory %s\n",
1180 TALLOC_FREE(talloced);
1181 TALLOC_FREE(fullname);
1182 TALLOC_FREE(smb_dname_full);
1183 status = NT_STATUS_DIRECTORY_NOT_EMPTY;
1187 /* Not a symlink, get a pathref. */
1188 status = synthetic_pathref(talloc_tos(),
1192 &smb_dname_full->st,
1196 if (!NT_STATUS_IS_OK(status)) {
1197 TALLOC_FREE(talloced);
1198 TALLOC_FREE(fullname);
1199 TALLOC_FREE(smb_dname_full);
1203 if (!is_visible_fsp(direntry_fname->fsp)) {
1204 TALLOC_FREE(talloced);
1205 TALLOC_FREE(fullname);
1206 TALLOC_FREE(smb_dname_full);
1207 TALLOC_FREE(direntry_fname);
1212 * We found a client visible name.
1213 * We cannot delete this directory.
1215 DBG_DEBUG("got name %s - "
1216 "can't delete directory %s\n",
1219 TALLOC_FREE(talloced);
1220 TALLOC_FREE(fullname);
1221 TALLOC_FREE(smb_dname_full);
1222 TALLOC_FREE(direntry_fname);
1223 status = NT_STATUS_DIRECTORY_NOT_EMPTY;
1227 /* Do a recursive delete. */
1228 RewindDir(dir_hnd,&dirpos);
1230 while ((dname = ReadDirName(
1231 dir_hnd, &dirpos, NULL, &talloced)) != NULL) {
1232 struct smb_filename *direntry_fname = NULL;
1233 struct smb_filename *smb_dname_full = NULL;
1234 char *fullname = NULL;
1235 bool do_break = true;
1238 if (ISDOT(dname) || ISDOTDOT(dname)) {
1239 TALLOC_FREE(talloced);
1243 fullname = talloc_asprintf(ctx,
1245 smb_dname->base_name,
1248 if (fullname == NULL) {
1249 status = NT_STATUS_NO_MEMORY;
1253 smb_dname_full = synthetic_smb_fname(talloc_tos(),
1259 if (smb_dname_full == NULL) {
1260 status = NT_STATUS_NO_MEMORY;
1265 * Todo: use SMB_VFS_STATX() once that's available.
1268 retval = SMB_VFS_LSTAT(conn, smb_dname_full);
1270 status = map_nt_error_from_unix(errno);
1275 * We are only dealing with VETO'ed objects
1276 * here. If it's a symlink, just delete the
1277 * link without caring what it is pointing
1280 if (S_ISLNK(smb_dname_full->st.st_ex_mode)) {
1281 direntry_fname = synthetic_smb_fname(talloc_tos(),
1284 &smb_dname_full->st,
1287 if (direntry_fname == NULL) {
1288 status = NT_STATUS_NO_MEMORY;
1292 status = synthetic_pathref(talloc_tos(),
1296 &smb_dname_full->st,
1300 if (!NT_STATUS_IS_OK(status)) {
1304 if (!is_visible_fsp(direntry_fname->fsp)) {
1305 TALLOC_FREE(fullname);
1306 TALLOC_FREE(smb_dname_full);
1307 TALLOC_FREE(talloced);
1308 TALLOC_FREE(direntry_fname);
1315 if (smb_dname_full->st.st_ex_mode & S_IFDIR) {
1316 status = recursive_rmdir(ctx, conn, smb_dname_full);
1317 if (!NT_STATUS_IS_OK(status)) {
1320 unlink_flags = AT_REMOVEDIR;
1323 retval = SMB_VFS_UNLINKAT(conn,
1328 status = map_nt_error_from_unix(errno);
1332 /* Successful iteration. */
1336 TALLOC_FREE(fullname);
1337 TALLOC_FREE(smb_dname_full);
1338 TALLOC_FREE(talloced);
1339 TALLOC_FREE(direntry_fname);
1345 /* If we get here, we know NT_STATUS_IS_OK(status) */
1346 SMB_ASSERT(NT_STATUS_IS_OK(status));
1348 /* Retry the rmdir */
1349 ret = SMB_VFS_UNLINKAT(conn,
1354 status = map_nt_error_from_unix(errno);
1359 TALLOC_FREE(dir_hnd);
1360 TALLOC_FREE(parent_fname);
1362 if (!NT_STATUS_IS_OK(status)) {
1363 DBG_NOTICE("couldn't remove directory %s : "
1364 "%s\n", smb_fname_str_dbg(smb_dname),
1369 notify_fname(conn, NOTIFY_ACTION_REMOVED,
1370 FILE_NOTIFY_CHANGE_DIR_NAME,
1371 smb_dname->base_name);
1376 /****************************************************************************
1377 Close a directory opened by an NT SMB call.
1378 ****************************************************************************/
1380 static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
1381 enum file_close_type close_type)
1383 connection_struct *conn = fsp->conn;
1384 struct share_mode_lock *lck = NULL;
1385 bool delete_dir = False;
1386 bool changed_user = false;
1387 NTSTATUS status = NT_STATUS_OK;
1388 NTSTATUS status1 = NT_STATUS_OK;
1389 const struct security_token *del_nt_token = NULL;
1390 const struct security_unix_token *del_token = NULL;
1393 NTSTATUS notify_status;
1395 SMB_ASSERT(fsp->fsp_flags.is_fsa);
1397 if (fsp->conn->sconn->using_smb2) {
1398 notify_status = NT_STATUS_NOTIFY_CLEANUP;
1400 notify_status = NT_STATUS_OK;
1403 assert_no_pending_aio(fsp, close_type);
1406 * NT can set delete_on_close of the last open
1407 * reference to a directory also.
1410 lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
1412 DEBUG(0, ("close_directory: Could not get share mode lock for "
1413 "%s\n", fsp_str_dbg(fsp)));
1414 return NT_STATUS_INVALID_PARAMETER;
1417 if (fsp->fsp_flags.initial_delete_on_close &&
1418 !is_delete_on_close_set(lck, fsp->name_hash)) {
1419 /* Initial delete on close was set - for
1420 * directories we don't care if anyone else
1421 * wrote a real delete on close. */
1423 send_stat_cache_delete_message(fsp->conn->sconn->msg_ctx,
1424 fsp->fsp_name->base_name);
1425 set_delete_on_close_lck(fsp, lck,
1426 fsp->conn->session_info->security_token,
1427 fsp->conn->session_info->unix_token);
1428 fsp->fsp_flags.delete_on_close = true;
1431 delete_dir = is_delete_on_close_set(lck, fsp->name_hash) &&
1432 !has_other_nonposix_opens(lck, fsp);
1435 * NT can set delete_on_close of the last open
1436 * reference to a file.
1439 normal_close = (close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE);
1440 if (!normal_close) {
1442 * Never try to delete the directory for ERROR_CLOSE
1448 status = NT_STATUS_OK;
1453 * Ok, we have to delete the directory
1456 DBG_INFO("dir %s. Delete on close was set - deleting directory.\n",
1459 got_tokens = get_delete_on_close_token(lck, fsp->name_hash,
1460 &del_nt_token, &del_token);
1461 SMB_ASSERT(got_tokens);
1463 /* Become the user who requested the delete. */
1465 if (!unix_token_equal(del_token, get_current_utok(conn))) {
1466 /* Become the user who requested the delete. */
1468 DBG_INFO("dir %s. Change user to uid %u\n",
1470 (unsigned int)del_token->uid);
1472 if (!push_sec_ctx()) {
1473 smb_panic("close_directory: failed to push sec_ctx.\n");
1476 set_sec_ctx(del_token->uid,
1482 changed_user = true;
1485 if ((fsp->conn->fs_capabilities & FILE_NAMED_STREAMS)
1486 && !is_ntfs_stream_smb_fname(fsp->fsp_name)) {
1488 status = delete_all_streams(fsp->conn, fsp->fsp_name);
1489 if (!NT_STATUS_IS_OK(status)) {
1490 DEBUG(5, ("delete_all_streams failed: %s\n",
1491 nt_errstr(status)));
1496 status = rmdir_internals(talloc_tos(), fsp);
1498 DEBUG(5,("close_directory: %s. Delete on close was set - "
1499 "deleting directory returned %s.\n",
1500 fsp_str_dbg(fsp), nt_errstr(status)));
1503 * Ensure we remove any change notify requests that would
1504 * now fail as the directory has been deleted.
1507 if (NT_STATUS_IS_OK(status)) {
1508 notify_status = NT_STATUS_DELETE_PENDING;
1513 /* unbecome user. */
1517 if (!del_share_mode(lck, fsp)) {
1518 DEBUG(0, ("close_directory: Could not delete share entry for "
1519 "%s\n", fsp_str_dbg(fsp)));
1524 remove_pending_change_notify_requests_by_fid(fsp, notify_status);
1526 status1 = fd_close(fsp);
1528 if (!NT_STATUS_IS_OK(status1)) {
1529 DEBUG(0, ("Could not close dir! fname=%s, fd=%d, err=%d=%s\n",
1530 fsp_str_dbg(fsp), fsp_get_pathref_fd(fsp), errno,
1534 if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(status1)) {
1540 /****************************************************************************
1541 Rundown all SMB-related dependencies of a files struct
1542 ****************************************************************************/
1544 NTSTATUS close_file_smb(struct smb_request *req,
1545 struct files_struct *fsp,
1546 enum file_close_type close_type)
1551 * This fsp can never be an internal dirfsp. They must
1552 * be explicitly closed by TALLOC_FREE of the dir handle.
1554 SMB_ASSERT(!fsp->fsp_flags.is_dirfsp);
1557 * Never call directly on a base fsp
1559 SMB_ASSERT(fsp->stream_fsp == NULL);
1561 if (fsp->fake_file_handle != NULL) {
1562 status = close_fake_file(req, fsp);
1563 } else if (fsp->print_file != NULL) {
1564 /* FIXME: return spool errors */
1565 print_spool_end(fsp, close_type);
1567 status = NT_STATUS_OK;
1568 } else if (!fsp->fsp_flags.is_fsa) {
1569 if (close_type == NORMAL_CLOSE) {
1570 DBG_ERR("unexpected NORMAL_CLOSE for [%s] "
1571 "is_fsa[%u] is_pathref[%u] is_directory[%u]\n",
1573 fsp->fsp_flags.is_fsa,
1574 fsp->fsp_flags.is_pathref,
1575 fsp->fsp_flags.is_directory);
1577 SMB_ASSERT(close_type != NORMAL_CLOSE);
1579 status = NT_STATUS_OK;
1580 } else if (fsp->fsp_flags.is_directory) {
1581 status = close_directory(req, fsp, close_type);
1583 status = close_normal_file(req, fsp, close_type);
1586 if (fsp_is_alternate_stream(fsp)) {
1588 * fsp was a stream, its base_fsp can't be a stream
1591 SMB_ASSERT(!fsp_is_alternate_stream(fsp->base_fsp));
1594 * There's a 1:1 relationship between fsp and a base_fsp
1596 SMB_ASSERT(fsp->base_fsp->stream_fsp == fsp);
1599 * Make base_fsp look standalone now
1601 fsp->base_fsp->stream_fsp = NULL;
1603 close_file_free(req, &fsp->base_fsp, close_type);
1606 fsp_unbind_smb(req, fsp);
1611 NTSTATUS close_file_free(struct smb_request *req,
1612 struct files_struct **_fsp,
1613 enum file_close_type close_type)
1615 struct files_struct *fsp = *_fsp;
1618 status = close_file_smb(req, fsp, close_type);
1620 file_free(req, fsp);
1626 /****************************************************************************
1627 Deal with an (authorized) message to close a file given the share mode
1629 ****************************************************************************/
1631 void msg_close_file(struct messaging_context *msg_ctx,
1634 struct server_id server_id,
1637 files_struct *fsp = NULL;
1639 struct share_mode_entry e;
1640 struct smbd_server_connection *sconn =
1641 talloc_get_type_abort(private_data,
1642 struct smbd_server_connection);
1644 message_to_share_mode_entry(&id, &e, (char *)data->data);
1647 char *sm_str = share_mode_str(NULL, 0, &id, &e);
1649 smb_panic("talloc failed");
1651 DEBUG(10,("msg_close_file: got request to close share mode "
1652 "entry %s\n", sm_str));
1653 TALLOC_FREE(sm_str);
1656 fsp = file_find_dif(sconn, id, e.share_file_id);
1658 DEBUG(10,("msg_close_file: failed to find file.\n"));
1661 close_file_free(NULL, &fsp, NORMAL_CLOSE);