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 "smbd/smbd.h"
27 #include "smbd/globals.h"
28 #include "smbd/scavenger.h"
29 #include "fake_file.h"
30 #include "transfer_file.h"
33 #include "../librpc/gen_ndr/open_files.h"
34 #include "lib/util/tevent_ntstatus.h"
36 /****************************************************************************
37 Run a file if it is a magic script.
38 ****************************************************************************/
40 static NTSTATUS check_magic(struct files_struct *fsp)
43 const struct loadparm_substitution *lp_sub =
44 loadparm_s3_global_substitution();
45 const char *magic_output = NULL;
48 TALLOC_CTX *ctx = NULL;
50 struct connection_struct *conn = fsp->conn;
54 if (!*lp_magic_script(talloc_tos(), lp_sub, SNUM(conn))) {
58 DEBUG(5,("checking magic for %s\n", fsp_str_dbg(fsp)));
60 ctx = talloc_stackframe();
62 fname = fsp->fsp_name->base_name;
64 if (!(p = strrchr_m(fname,'/'))) {
70 if (!strequal(lp_magic_script(talloc_tos(), lp_sub, SNUM(conn)),p)) {
71 status = NT_STATUS_OK;
75 if (*lp_magic_output(talloc_tos(), lp_sub, SNUM(conn))) {
76 magic_output = lp_magic_output(talloc_tos(), lp_sub, SNUM(conn));
78 magic_output = talloc_asprintf(ctx,
83 status = NT_STATUS_NO_MEMORY;
87 /* Ensure we don't depend on user's PATH. */
88 p = talloc_asprintf(ctx, "./%s", fname);
90 status = NT_STATUS_NO_MEMORY;
94 if (chmod(fname, 0755) == -1) {
95 status = map_nt_error_from_unix(errno);
98 ret = smbrun(p, &tmp_fd, NULL);
99 DEBUG(3,("Invoking magic command %s gave %d\n",
103 if (ret != 0 || tmp_fd == -1) {
107 status = NT_STATUS_UNSUCCESSFUL;
110 outfd = open(magic_output, O_CREAT|O_EXCL|O_RDWR, 0600);
114 status = map_nt_error_from_unix(err);
118 if (sys_fstat(tmp_fd, &st, false) == -1) {
122 status = map_nt_error_from_unix(err);
126 if (transfer_file(tmp_fd,outfd,(off_t)st.st_ex_size) == (off_t)-1) {
130 status = map_nt_error_from_unix(err);
134 if (close(outfd) == -1) {
135 status = map_nt_error_from_unix(errno);
139 status = NT_STATUS_OK;
146 /****************************************************************************
148 ****************************************************************************/
150 NTSTATUS delete_all_streams(connection_struct *conn,
151 const struct smb_filename *smb_fname)
153 struct stream_struct *stream_info = NULL;
155 unsigned int num_streams = 0;
156 TALLOC_CTX *frame = talloc_stackframe();
159 status = vfs_streaminfo(conn, NULL, smb_fname, talloc_tos(),
160 &num_streams, &stream_info);
162 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
163 DEBUG(10, ("no streams around\n"));
168 if (!NT_STATUS_IS_OK(status)) {
169 DEBUG(10, ("vfs_streaminfo failed: %s\n",
174 DEBUG(10, ("delete_all_streams found %d streams\n",
177 if (num_streams == 0) {
182 for (i=0; i<num_streams; i++) {
184 struct smb_filename *smb_fname_stream;
186 if (strequal(stream_info[i].name, "::$DATA")) {
190 smb_fname_stream = synthetic_smb_fname(talloc_tos(),
191 smb_fname->base_name,
196 ~SMB_FILENAME_POSIX_PATH));
198 if (smb_fname_stream == NULL) {
199 DEBUG(0, ("talloc_aprintf failed\n"));
200 status = NT_STATUS_NO_MEMORY;
204 res = SMB_VFS_UNLINKAT(conn,
210 status = map_nt_error_from_unix(errno);
211 DEBUG(10, ("Could not delete stream %s: %s\n",
212 smb_fname_str_dbg(smb_fname_stream),
214 TALLOC_FREE(smb_fname_stream);
217 TALLOC_FREE(smb_fname_stream);
225 struct has_other_nonposix_opens_state {
230 static bool has_other_nonposix_opens_fn(
231 struct share_mode_entry *e,
235 struct has_other_nonposix_opens_state *state = private_data;
236 struct files_struct *fsp = state->fsp;
238 if (e->name_hash != fsp->name_hash) {
241 if ((fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) &&
242 (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) {
245 if (e->share_file_id == fsp->fh->gen_id) {
246 struct server_id self = messaging_server_id(
247 fsp->conn->sconn->msg_ctx);
248 if (server_id_equal(&self, &e->pid)) {
252 if (share_entry_stale_pid(e)) {
256 state->found_another = true;
260 bool has_other_nonposix_opens(struct share_mode_lock *lck,
261 struct files_struct *fsp)
263 struct has_other_nonposix_opens_state state = { .fsp = fsp };
266 ok = share_mode_forall_entries(
267 lck, has_other_nonposix_opens_fn, &state);
271 return state.found_another;
274 /****************************************************************************
275 Deal with removing a share mode on last close.
276 ****************************************************************************/
278 static NTSTATUS close_remove_share_mode(files_struct *fsp,
279 enum file_close_type close_type)
281 connection_struct *conn = fsp->conn;
282 bool delete_file = false;
283 bool changed_user = false;
284 struct share_mode_lock *lck = NULL;
285 NTSTATUS status = NT_STATUS_OK;
288 const struct security_unix_token *del_token = NULL;
289 const struct security_token *del_nt_token = NULL;
290 bool got_tokens = false;
294 /* Ensure any pending write time updates are done. */
295 if (fsp->update_write_time_event) {
296 fsp_flush_write_time_update(fsp);
300 * Lock the share entries, and determine if we should delete
301 * on close. If so delete whilst the lock is still in effect.
302 * This prevents race conditions with the file being created. JRA.
305 lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
307 DEBUG(0, ("close_remove_share_mode: Could not get share mode "
308 "lock for file %s\n", fsp_str_dbg(fsp)));
309 return NT_STATUS_INVALID_PARAMETER;
312 /* Remove the oplock before potentially deleting the file. */
313 if(fsp->oplock_type) {
317 if (fsp->fsp_flags.write_time_forced) {
320 DEBUG(10,("close_remove_share_mode: write time forced "
323 ts = nt_time_to_full_timespec(lck->data->changed_write_time);
324 set_close_write_time(fsp, ts);
325 } else if (fsp->fsp_flags.update_write_time_on_close) {
326 /* Someone had a pending write. */
327 if (is_omit_timespec(&fsp->close_write_time)) {
328 DEBUG(10,("close_remove_share_mode: update to current time "
331 /* Update to current time due to "normal" write. */
332 set_close_write_time(fsp, timespec_current());
334 DEBUG(10,("close_remove_share_mode: write time pending "
337 /* Update to time set on close call. */
338 set_close_write_time(fsp, fsp->close_write_time);
342 if (fsp->fsp_flags.initial_delete_on_close &&
343 !is_delete_on_close_set(lck, fsp->name_hash)) {
344 bool became_user = False;
346 /* Initial delete on close was set and no one else
347 * wrote a real delete on close. */
349 if (get_current_vuid(conn) != fsp->vuid) {
350 become_user_without_service(conn, fsp->vuid);
353 fsp->fsp_flags.delete_on_close = true;
354 set_delete_on_close_lck(fsp, lck,
355 get_current_nttok(conn),
356 get_current_utok(conn));
358 unbecome_user_without_service();
362 delete_file = is_delete_on_close_set(lck, fsp->name_hash) &&
363 !has_other_nonposix_opens(lck, fsp);
366 * NT can set delete_on_close of the last open
367 * reference to a file.
370 normal_close = (close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE);
372 if (!normal_close || !delete_file) {
373 status = NT_STATUS_OK;
378 * Ok, we have to delete the file
381 DEBUG(5,("close_remove_share_mode: file %s. Delete on close was set "
382 "- deleting file.\n", fsp_str_dbg(fsp)));
385 * Don't try to update the write time when we delete the file
387 fsp->fsp_flags.update_write_time_on_close = false;
389 got_tokens = get_delete_on_close_token(lck, fsp->name_hash,
390 &del_nt_token, &del_token);
391 SMB_ASSERT(got_tokens);
393 if (!unix_token_equal(del_token, get_current_utok(conn))) {
394 /* Become the user who requested the delete. */
396 DEBUG(5,("close_remove_share_mode: file %s. "
397 "Change user to uid %u\n",
399 (unsigned int)del_token->uid));
401 if (!push_sec_ctx()) {
402 smb_panic("close_remove_share_mode: file %s. failed to push "
406 set_sec_ctx(del_token->uid,
415 /* We can only delete the file if the name we have is still valid and
416 hasn't been renamed. */
418 tmp_status = vfs_stat_fsp(fsp);
419 if (!NT_STATUS_IS_OK(tmp_status)) {
420 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
421 "was set and stat failed with error %s\n",
422 fsp_str_dbg(fsp), nt_errstr(tmp_status)));
424 * Don't save the errno here, we ignore this error
429 id = vfs_file_id_from_sbuf(conn, &fsp->fsp_name->st);
431 if (!file_id_equal(&fsp->file_id, &id)) {
432 struct file_id_buf ftmp1, ftmp2;
433 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
434 "was set and dev and/or inode does not match\n",
436 DEBUG(5,("close_remove_share_mode: file %s. stored file_id %s, "
439 file_id_str_buf(fsp->file_id, &ftmp1),
440 file_id_str_buf(id, &ftmp2)));
442 * Don't save the errno here, we ignore this error
447 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
448 && !is_ntfs_stream_smb_fname(fsp->fsp_name)) {
450 status = delete_all_streams(conn, fsp->fsp_name);
452 if (!NT_STATUS_IS_OK(status)) {
453 DEBUG(5, ("delete_all_streams failed: %s\n",
459 if (fsp->fsp_flags.kernel_share_modes_taken) {
463 * A file system sharemode could block the unlink;
464 * remove filesystem sharemodes first.
466 ret_flock = SMB_VFS_KERNEL_FLOCK(fsp, 0, 0);
467 if (ret_flock == -1) {
468 DBG_INFO("removing kernel flock for %s failed: %s\n",
469 fsp_str_dbg(fsp), strerror(errno));
472 fsp->fsp_flags.kernel_share_modes_taken = false;
476 ret = SMB_VFS_UNLINKAT(conn,
482 * This call can potentially fail as another smbd may
483 * have had the file open with delete on close set and
484 * deleted it when its last reference to this file
485 * went away. Hence we log this but not at debug level
489 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
490 "was set and unlink failed with error %s\n",
491 fsp_str_dbg(fsp), strerror(errno)));
493 status = map_nt_error_from_unix(errno);
496 /* As we now have POSIX opens which can unlink
497 * with other open files we may have taken
498 * this code path with more than one share mode
499 * entry - ensure we only delete once by resetting
500 * the delete on close flag. JRA.
503 fsp->fsp_flags.delete_on_close = false;
504 reset_delete_on_close_lck(fsp, lck);
513 if (fsp->fsp_flags.kernel_share_modes_taken) {
516 /* remove filesystem sharemodes */
517 ret_flock = SMB_VFS_KERNEL_FLOCK(fsp, 0, 0);
518 if (ret_flock == -1) {
519 DEBUG(2, ("close_remove_share_mode: removing kernel "
520 "flock for %s failed: %s\n",
521 fsp_str_dbg(fsp), strerror(errno)));
525 if (!del_share_mode(lck, fsp)) {
526 DEBUG(0, ("close_remove_share_mode: Could not delete share "
527 "entry for file %s\n", fsp_str_dbg(fsp)));
534 * Do the notification after we released the share
535 * mode lock. Inside notify_fname we take out another
536 * tdb lock. With ctdb also accessing our databases,
537 * this can lead to deadlocks. Putting this notify
538 * after the TALLOC_FREE(lck) above we avoid locking
539 * two records simultaneously. Notifies are async and
540 * informational only, so calling the notify_fname
541 * without holding the share mode lock should not do
544 notify_fname(conn, NOTIFY_ACTION_REMOVED,
545 FILE_NOTIFY_CHANGE_FILE_NAME,
546 fsp->fsp_name->base_name);
552 void set_close_write_time(struct files_struct *fsp, struct timespec ts)
554 DEBUG(6,("close_write_time: %s" , time_to_asc(convert_timespec_to_time_t(ts))));
556 if (is_omit_timespec(&ts)) {
559 fsp->fsp_flags.write_time_forced = false;
560 fsp->fsp_flags.update_write_time_on_close = true;
561 fsp->close_write_time = ts;
564 static NTSTATUS update_write_time_on_close(struct files_struct *fsp)
566 struct smb_file_time ft;
568 struct share_mode_lock *lck = NULL;
570 init_smb_file_time(&ft);
572 if (!(fsp->fsp_flags.update_write_time_on_close)) {
576 if (is_omit_timespec(&fsp->close_write_time)) {
577 fsp->close_write_time = timespec_current();
580 /* Ensure we have a valid stat struct for the source. */
581 status = vfs_stat_fsp(fsp);
582 if (!NT_STATUS_IS_OK(status)) {
586 if (!VALID_STAT(fsp->fsp_name->st)) {
587 /* if it doesn't seem to be a real file */
592 * get_existing_share_mode_lock() isn't really the right
593 * call here, as we're being called after
594 * close_remove_share_mode() inside close_normal_file()
595 * so it's quite normal to not have an existing share
596 * mode here. However, get_share_mode_lock() doesn't
597 * work because that will create a new share mode if
598 * one doesn't exist - so stick with this call (just
599 * ignore any error we get if the share mode doesn't
603 lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
605 /* On close if we're changing the real file time we
606 * must update it in the open file db too. */
607 (void)set_write_time(fsp->file_id, fsp->close_write_time);
609 /* Close write times overwrite sticky write times
610 so we must replace any sticky write time here. */
611 if (!null_nttime(lck->data->changed_write_time)) {
612 (void)set_sticky_write_time(fsp->file_id, fsp->close_write_time);
617 ft.mtime = fsp->close_write_time;
618 /* As this is a close based update, we are not directly changing the
619 file attributes from a client call, but indirectly from a write. */
620 status = smb_set_file_time(fsp->conn, fsp, fsp->fsp_name, &ft, false);
621 if (!NT_STATUS_IS_OK(status)) {
622 DEBUG(10,("update_write_time_on_close: smb_set_file_time "
623 "on file %s returned %s\n",
632 static NTSTATUS ntstatus_keeperror(NTSTATUS s1, NTSTATUS s2)
634 if (!NT_STATUS_IS_OK(s1)) {
640 static void assert_no_pending_aio(struct files_struct *fsp,
641 enum file_close_type close_type)
643 unsigned num_requests = fsp->num_aio_requests;
645 if (num_requests == 0) {
649 DBG_ERR("fsp->num_aio_requests=%u\n", num_requests);
650 smb_panic("can not close with outstanding aio requests");
654 /****************************************************************************
657 close_type can be NORMAL_CLOSE=0,SHUTDOWN_CLOSE,ERROR_CLOSE.
658 printing and magic scripts are only run on normal close.
659 delete on close is done on normal and shutdown close.
660 ****************************************************************************/
662 static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp,
663 enum file_close_type close_type)
665 NTSTATUS status = NT_STATUS_OK;
667 connection_struct *conn = fsp->conn;
668 bool is_durable = false;
670 assert_no_pending_aio(fsp, close_type);
672 while (talloc_array_length(fsp->blocked_smb1_lock_reqs) != 0) {
673 smbd_smb1_brl_finish_by_req(
674 fsp->blocked_smb1_lock_reqs[0],
675 NT_STATUS_RANGE_NOT_LOCKED);
679 * If we're flushing on a close we can get a write
680 * error here, we must remember this.
683 if (NT_STATUS_IS_OK(status) && fsp->op != NULL) {
684 is_durable = fsp->op->global->durable;
687 if (close_type != SHUTDOWN_CLOSE) {
692 DATA_BLOB new_cookie = data_blob_null;
694 tmp = SMB_VFS_DURABLE_DISCONNECT(fsp,
695 fsp->op->global->backend_cookie,
698 if (NT_STATUS_IS_OK(tmp)) {
703 tv = req->request_time;
705 tv = timeval_current();
707 now = timeval_to_nttime(&tv);
709 data_blob_free(&fsp->op->global->backend_cookie);
710 fsp->op->global->backend_cookie = new_cookie;
712 fsp->op->compat = NULL;
713 tmp = smbXsrv_open_close(fsp->op, now);
714 if (!NT_STATUS_IS_OK(tmp)) {
715 DEBUG(1, ("Failed to update smbXsrv_open "
716 "record when disconnecting durable "
717 "handle for file %s: %s - "
718 "proceeding with normal close\n",
719 fsp_str_dbg(fsp), nt_errstr(tmp)));
721 scavenger_schedule_disconnected(fsp);
723 DEBUG(1, ("Failed to disconnect durable handle for "
724 "file %s: %s - proceeding with normal "
725 "close\n", fsp_str_dbg(fsp), nt_errstr(tmp)));
727 if (!NT_STATUS_IS_OK(tmp)) {
734 * This is the case where we successfully disconnected
735 * a durable handle and closed the underlying file.
736 * In all other cases, we proceed with a genuine close.
738 DEBUG(10, ("%s disconnected durable handle for file %s\n",
739 conn->session_info->unix_info->unix_name,
745 if (fsp->op != NULL) {
747 * Make sure the handle is not marked as durable anymore
749 fsp->op->global->durable = false;
752 if (fsp->print_file) {
753 /* FIXME: return spool errors */
754 print_spool_end(fsp, close_type);
759 /* If this is an old DOS or FCB open and we have multiple opens on
760 the same handle we only have one share mode. Ensure we only remove
761 the share mode on the last close. */
763 if (fsp->fh->ref_count == 1) {
764 /* Should we return on error here... ? */
765 tmp = close_remove_share_mode(fsp, close_type);
766 status = ntstatus_keeperror(status, tmp);
769 locking_close_file(fsp, close_type);
772 status = ntstatus_keeperror(status, tmp);
774 /* check for magic scripts */
775 if (close_type == NORMAL_CLOSE) {
776 tmp = check_magic(fsp);
777 status = ntstatus_keeperror(status, tmp);
781 * Ensure pending modtime is set after close.
784 tmp = update_write_time_on_close(fsp);
785 if (NT_STATUS_EQUAL(tmp, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
786 /* Someone renamed the file or a parent directory containing
787 * this file. We can't do anything about this, we don't have
788 * an "update timestamp by fd" call in POSIX. Eat the error. */
793 status = ntstatus_keeperror(status, tmp);
795 DEBUG(2,("%s closed file %s (numopen=%d) %s\n",
796 conn->session_info->unix_info->unix_name, fsp_str_dbg(fsp),
797 conn->num_files_open - 1,
798 nt_errstr(status) ));
803 /****************************************************************************
804 Function used by reply_rmdir to delete an entire directory
805 tree recursively. Return True on ok, False on fail.
806 ****************************************************************************/
808 bool recursive_rmdir(TALLOC_CTX *ctx,
809 connection_struct *conn,
810 struct smb_filename *smb_dname)
812 const char *dname = NULL;
813 char *talloced = NULL;
817 struct smb_Dir *dir_hnd;
820 SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
822 dir_hnd = OpenDir(talloc_tos(), conn, smb_dname, NULL, 0);
826 while((dname = ReadDirName(dir_hnd, &offset, &st, &talloced))) {
827 struct smb_filename *smb_dname_full = NULL;
828 char *fullname = NULL;
829 bool do_break = true;
831 if (ISDOT(dname) || ISDOTDOT(dname)) {
832 TALLOC_FREE(talloced);
836 if (!is_visible_file(conn,
841 TALLOC_FREE(talloced);
845 /* Construct the full name. */
846 fullname = talloc_asprintf(ctx,
848 smb_dname->base_name,
855 smb_dname_full = synthetic_smb_fname(talloc_tos(),
861 if (smb_dname_full == NULL) {
866 if(SMB_VFS_LSTAT(conn, smb_dname_full) != 0) {
870 if(smb_dname_full->st.st_ex_mode & S_IFDIR) {
871 if(!recursive_rmdir(ctx, conn, smb_dname_full)) {
874 retval = SMB_VFS_UNLINKAT(conn,
882 retval = SMB_VFS_UNLINKAT(conn,
891 /* Successful iteration. */
895 TALLOC_FREE(smb_dname_full);
896 TALLOC_FREE(fullname);
897 TALLOC_FREE(talloced);
903 TALLOC_FREE(dir_hnd);
907 /****************************************************************************
908 The internals of the rmdir code - called elsewhere.
909 ****************************************************************************/
911 static NTSTATUS rmdir_internals(TALLOC_CTX *ctx, files_struct *fsp)
913 connection_struct *conn = fsp->conn;
914 struct smb_filename *smb_dname = fsp->fsp_name;
915 const struct loadparm_substitution *lp_sub =
916 loadparm_s3_global_substitution();
919 SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
921 /* Might be a symlink. */
922 if(SMB_VFS_LSTAT(conn, smb_dname) != 0) {
923 return map_nt_error_from_unix(errno);
926 if (S_ISLNK(smb_dname->st.st_ex_mode)) {
927 /* Is what it points to a directory ? */
928 if(SMB_VFS_STAT(conn, smb_dname) != 0) {
929 return map_nt_error_from_unix(errno);
931 if (!(S_ISDIR(smb_dname->st.st_ex_mode))) {
932 return NT_STATUS_NOT_A_DIRECTORY;
934 ret = SMB_VFS_UNLINKAT(conn,
939 ret = SMB_VFS_UNLINKAT(conn,
945 notify_fname(conn, NOTIFY_ACTION_REMOVED,
946 FILE_NOTIFY_CHANGE_DIR_NAME,
947 smb_dname->base_name);
951 if(((errno == ENOTEMPTY)||(errno == EEXIST)) && *lp_veto_files(talloc_tos(), lp_sub, SNUM(conn))) {
953 * Check to see if the only thing in this directory are
954 * vetoed files/directories. If so then delete them and
955 * retry. If we fail to delete any of them (and we *don't*
956 * do a recursive delete) then fail the rmdir.
959 const char *dname = NULL;
960 char *talloced = NULL;
962 struct smb_Dir *dir_hnd = OpenDir(talloc_tos(), conn,
966 if(dir_hnd == NULL) {
971 while ((dname = ReadDirName(dir_hnd, &dirpos, &st,
972 &talloced)) != NULL) {
973 if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0)) {
974 TALLOC_FREE(talloced);
977 if (!is_visible_file(conn,
982 TALLOC_FREE(talloced);
985 if(!IS_VETO_PATH(conn, dname)) {
986 TALLOC_FREE(dir_hnd);
987 TALLOC_FREE(talloced);
991 TALLOC_FREE(talloced);
994 /* We only have veto files/directories.
995 * Are we allowed to delete them ? */
997 if(!lp_delete_veto_files(SNUM(conn))) {
998 TALLOC_FREE(dir_hnd);
1003 /* Do a recursive delete. */
1004 RewindDir(dir_hnd,&dirpos);
1005 while ((dname = ReadDirName(dir_hnd, &dirpos, &st,
1006 &talloced)) != NULL) {
1007 struct smb_filename *smb_dname_full = NULL;
1008 char *fullname = NULL;
1009 bool do_break = true;
1011 if (ISDOT(dname) || ISDOTDOT(dname)) {
1012 TALLOC_FREE(talloced);
1015 if (!is_visible_file(conn,
1020 TALLOC_FREE(talloced);
1024 fullname = talloc_asprintf(ctx,
1026 smb_dname->base_name,
1034 smb_dname_full = synthetic_smb_fname(talloc_tos(),
1040 if (smb_dname_full == NULL) {
1045 if(SMB_VFS_LSTAT(conn, smb_dname_full) != 0) {
1048 if(smb_dname_full->st.st_ex_mode & S_IFDIR) {
1050 if(!recursive_rmdir(ctx, conn,
1054 retval = SMB_VFS_UNLINKAT(conn,
1062 int retval = SMB_VFS_UNLINKAT(conn,
1071 /* Successful iteration. */
1075 TALLOC_FREE(fullname);
1076 TALLOC_FREE(smb_dname_full);
1077 TALLOC_FREE(talloced);
1081 TALLOC_FREE(dir_hnd);
1082 /* Retry the rmdir */
1083 ret = SMB_VFS_UNLINKAT(conn,
1092 DEBUG(3,("rmdir_internals: couldn't remove directory %s : "
1093 "%s\n", smb_fname_str_dbg(smb_dname),
1095 return map_nt_error_from_unix(errno);
1098 notify_fname(conn, NOTIFY_ACTION_REMOVED,
1099 FILE_NOTIFY_CHANGE_DIR_NAME,
1100 smb_dname->base_name);
1102 return NT_STATUS_OK;
1105 /****************************************************************************
1106 Close a directory opened by an NT SMB call.
1107 ****************************************************************************/
1109 static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
1110 enum file_close_type close_type)
1112 struct share_mode_lock *lck = NULL;
1113 bool delete_dir = False;
1114 NTSTATUS status = NT_STATUS_OK;
1115 NTSTATUS status1 = NT_STATUS_OK;
1116 const struct security_token *del_nt_token = NULL;
1117 const struct security_unix_token *del_token = NULL;
1118 NTSTATUS notify_status;
1120 if (fsp->conn->sconn->using_smb2) {
1121 notify_status = STATUS_NOTIFY_CLEANUP;
1123 notify_status = NT_STATUS_OK;
1126 assert_no_pending_aio(fsp, close_type);
1129 * NT can set delete_on_close of the last open
1130 * reference to a directory also.
1133 lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
1135 DEBUG(0, ("close_directory: Could not get share mode lock for "
1136 "%s\n", fsp_str_dbg(fsp)));
1137 file_free(req, fsp);
1138 return NT_STATUS_INVALID_PARAMETER;
1141 if (fsp->fsp_flags.initial_delete_on_close) {
1142 bool became_user = False;
1144 /* Initial delete on close was set - for
1145 * directories we don't care if anyone else
1146 * wrote a real delete on close. */
1148 if (get_current_vuid(fsp->conn) != fsp->vuid) {
1149 become_user_without_service(fsp->conn, fsp->vuid);
1152 send_stat_cache_delete_message(fsp->conn->sconn->msg_ctx,
1153 fsp->fsp_name->base_name);
1154 set_delete_on_close_lck(fsp, lck,
1155 get_current_nttok(fsp->conn),
1156 get_current_utok(fsp->conn));
1157 fsp->fsp_flags.delete_on_close = true;
1159 unbecome_user_without_service();
1163 delete_dir = get_delete_on_close_token(
1164 lck, fsp->name_hash, &del_nt_token, &del_token) &&
1165 !has_other_nonposix_opens(lck, fsp);
1167 if ((close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) &&
1170 /* Become the user who requested the delete. */
1172 if (!push_sec_ctx()) {
1173 smb_panic("close_directory: failed to push sec_ctx.\n");
1176 set_sec_ctx(del_token->uid,
1182 if (!del_share_mode(lck, fsp)) {
1183 DEBUG(0, ("close_directory: Could not delete share entry for "
1184 "%s\n", fsp_str_dbg(fsp)));
1189 if ((fsp->conn->fs_capabilities & FILE_NAMED_STREAMS)
1190 && !is_ntfs_stream_smb_fname(fsp->fsp_name)) {
1192 status = delete_all_streams(fsp->conn, fsp->fsp_name);
1193 if (!NT_STATUS_IS_OK(status)) {
1194 DEBUG(5, ("delete_all_streams failed: %s\n",
1195 nt_errstr(status)));
1196 file_free(req, fsp);
1201 status = rmdir_internals(talloc_tos(), fsp);
1203 DEBUG(5,("close_directory: %s. Delete on close was set - "
1204 "deleting directory returned %s.\n",
1205 fsp_str_dbg(fsp), nt_errstr(status)));
1207 /* unbecome user. */
1211 * Ensure we remove any change notify requests that would
1212 * now fail as the directory has been deleted.
1215 if (NT_STATUS_IS_OK(status)) {
1216 notify_status = NT_STATUS_DELETE_PENDING;
1219 if (!del_share_mode(lck, fsp)) {
1220 DEBUG(0, ("close_directory: Could not delete share entry for "
1221 "%s\n", fsp_str_dbg(fsp)));
1227 remove_pending_change_notify_requests_by_fid(fsp, notify_status);
1229 status1 = fd_close(fsp);
1231 if (!NT_STATUS_IS_OK(status1)) {
1232 DEBUG(0, ("Could not close dir! fname=%s, fd=%d, err=%d=%s\n",
1233 fsp_str_dbg(fsp), fsp->fh->fd, errno,
1238 * Do the code common to files and directories.
1240 file_free(req, fsp);
1242 if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(status1)) {
1248 /****************************************************************************
1249 Close a files_struct.
1250 ****************************************************************************/
1252 NTSTATUS close_file(struct smb_request *req, files_struct *fsp,
1253 enum file_close_type close_type)
1256 struct files_struct *base_fsp = fsp->base_fsp;
1258 if (fsp->fsp_flags.is_directory) {
1259 status = close_directory(req, fsp, close_type);
1260 } else if (fsp->fake_file_handle != NULL) {
1261 status = close_fake_file(req, fsp);
1263 status = close_normal_file(req, fsp, close_type);
1266 if ((base_fsp != NULL) && (close_type != SHUTDOWN_CLOSE)) {
1269 * fsp was a stream, the base fsp can't be a stream as well
1271 * For SHUTDOWN_CLOSE this is not possible here, because
1272 * SHUTDOWN_CLOSE only happens from files.c which walks the
1273 * complete list of files. If we mess with more than one fsp
1274 * those loops will become confused.
1277 SMB_ASSERT(base_fsp->base_fsp == NULL);
1278 close_file(req, base_fsp, close_type);
1284 /****************************************************************************
1285 Deal with an (authorized) message to close a file given the share mode
1287 ****************************************************************************/
1289 void msg_close_file(struct messaging_context *msg_ctx,
1292 struct server_id server_id,
1295 files_struct *fsp = NULL;
1297 struct share_mode_entry e;
1298 struct smbd_server_connection *sconn =
1299 talloc_get_type_abort(private_data,
1300 struct smbd_server_connection);
1302 message_to_share_mode_entry(&id, &e, (char *)data->data);
1305 char *sm_str = share_mode_str(NULL, 0, &id, &e);
1307 smb_panic("talloc failed");
1309 DEBUG(10,("msg_close_file: got request to close share mode "
1310 "entry %s\n", sm_str));
1311 TALLOC_FREE(sm_str);
1314 fsp = file_find_dif(sconn, id, e.share_file_id);
1316 DEBUG(10,("msg_close_file: failed to find file.\n"));
1319 close_file(NULL, fsp, NORMAL_CLOSE);