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"
25 #include "smbd/smbd.h"
26 #include "smbd/globals.h"
27 #include "smbd/scavenger.h"
28 #include "fake_file.h"
29 #include "transfer_file.h"
32 #include "../librpc/gen_ndr/open_files.h"
34 /****************************************************************************
35 Run a file if it is a magic script.
36 ****************************************************************************/
38 static NTSTATUS check_magic(struct files_struct *fsp)
41 const char *magic_output = NULL;
44 TALLOC_CTX *ctx = NULL;
46 struct connection_struct *conn = fsp->conn;
50 if (!*lp_magic_script(talloc_tos(), SNUM(conn))) {
54 DEBUG(5,("checking magic for %s\n", fsp_str_dbg(fsp)));
56 ctx = talloc_stackframe();
58 fname = fsp->fsp_name->base_name;
60 if (!(p = strrchr_m(fname,'/'))) {
66 if (!strequal(lp_magic_script(talloc_tos(), SNUM(conn)),p)) {
67 status = NT_STATUS_OK;
71 if (*lp_magic_output(talloc_tos(), SNUM(conn))) {
72 magic_output = lp_magic_output(talloc_tos(), SNUM(conn));
74 magic_output = talloc_asprintf(ctx,
79 status = NT_STATUS_NO_MEMORY;
83 /* Ensure we don't depend on user's PATH. */
84 p = talloc_asprintf(ctx, "./%s", fname);
86 status = NT_STATUS_NO_MEMORY;
90 if (chmod(fname, 0755) == -1) {
91 status = map_nt_error_from_unix(errno);
94 ret = smbrun(p,&tmp_fd);
95 DEBUG(3,("Invoking magic command %s gave %d\n",
99 if (ret != 0 || tmp_fd == -1) {
103 status = NT_STATUS_UNSUCCESSFUL;
106 outfd = open(magic_output, O_CREAT|O_EXCL|O_RDWR, 0600);
110 status = map_nt_error_from_unix(err);
114 if (sys_fstat(tmp_fd, &st, false) == -1) {
118 status = map_nt_error_from_unix(err);
122 if (transfer_file(tmp_fd,outfd,(off_t)st.st_ex_size) == (off_t)-1) {
126 status = map_nt_error_from_unix(err);
130 if (close(outfd) == -1) {
131 status = map_nt_error_from_unix(errno);
135 status = NT_STATUS_OK;
142 /****************************************************************************
143 Common code to close a file or a directory.
144 ****************************************************************************/
146 static NTSTATUS close_filestruct(files_struct *fsp)
148 NTSTATUS status = NT_STATUS_OK;
150 if (fsp->fh->fd != -1) {
151 if(flush_write_cache(fsp, SAMBA_CLOSE_FLUSH) == -1) {
152 status = map_nt_error_from_unix(errno);
154 delete_write_cache(fsp);
160 /****************************************************************************
162 ****************************************************************************/
164 NTSTATUS delete_all_streams(connection_struct *conn,
165 const struct smb_filename *smb_fname)
167 struct stream_struct *stream_info = NULL;
169 unsigned int num_streams = 0;
170 TALLOC_CTX *frame = talloc_stackframe();
173 status = vfs_streaminfo(conn, NULL, smb_fname, talloc_tos(),
174 &num_streams, &stream_info);
176 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
177 DEBUG(10, ("no streams around\n"));
182 if (!NT_STATUS_IS_OK(status)) {
183 DEBUG(10, ("vfs_streaminfo failed: %s\n",
188 DEBUG(10, ("delete_all_streams found %d streams\n",
191 if (num_streams == 0) {
196 for (i=0; i<num_streams; i++) {
198 struct smb_filename *smb_fname_stream;
200 if (strequal(stream_info[i].name, "::$DATA")) {
204 smb_fname_stream = synthetic_smb_fname(talloc_tos(),
205 smb_fname->base_name,
209 ~SMB_FILENAME_POSIX_PATH));
211 if (smb_fname_stream == NULL) {
212 DEBUG(0, ("talloc_aprintf failed\n"));
213 status = NT_STATUS_NO_MEMORY;
217 res = SMB_VFS_UNLINK(conn, smb_fname_stream);
220 status = map_nt_error_from_unix(errno);
221 DEBUG(10, ("Could not delete stream %s: %s\n",
222 smb_fname_str_dbg(smb_fname_stream),
224 TALLOC_FREE(smb_fname_stream);
227 TALLOC_FREE(smb_fname_stream);
235 /****************************************************************************
236 Deal with removing a share mode on last close.
237 ****************************************************************************/
239 static NTSTATUS close_remove_share_mode(files_struct *fsp,
240 enum file_close_type close_type)
242 connection_struct *conn = fsp->conn;
243 struct server_id self = messaging_server_id(conn->sconn->msg_ctx);
244 bool delete_file = false;
245 bool changed_user = false;
246 struct share_mode_lock *lck = NULL;
247 NTSTATUS status = NT_STATUS_OK;
250 const struct security_unix_token *del_token = NULL;
251 const struct security_token *del_nt_token = NULL;
252 bool got_tokens = false;
255 /* Ensure any pending write time updates are done. */
256 if (fsp->update_write_time_event) {
257 update_write_time_handler(fsp->conn->sconn->ev_ctx,
258 fsp->update_write_time_event,
264 * Lock the share entries, and determine if we should delete
265 * on close. If so delete whilst the lock is still in effect.
266 * This prevents race conditions with the file being created. JRA.
269 lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
271 DEBUG(0, ("close_remove_share_mode: Could not get share mode "
272 "lock for file %s\n", fsp_str_dbg(fsp)));
273 return NT_STATUS_INVALID_PARAMETER;
276 /* Remove the oplock before potentially deleting the file. */
277 if(fsp->oplock_type) {
278 remove_oplock_under_lock(fsp, lck);
281 if (fsp->write_time_forced) {
282 DEBUG(10,("close_remove_share_mode: write time forced "
285 set_close_write_time(fsp, lck->data->changed_write_time);
286 } else if (fsp->update_write_time_on_close) {
287 /* Someone had a pending write. */
288 if (null_timespec(fsp->close_write_time)) {
289 DEBUG(10,("close_remove_share_mode: update to current time "
292 /* Update to current time due to "normal" write. */
293 set_close_write_time(fsp, timespec_current());
295 DEBUG(10,("close_remove_share_mode: write time pending "
298 /* Update to time set on close call. */
299 set_close_write_time(fsp, fsp->close_write_time);
303 if (fsp->initial_delete_on_close &&
304 !is_delete_on_close_set(lck, fsp->name_hash)) {
305 bool became_user = False;
307 /* Initial delete on close was set and no one else
308 * wrote a real delete on close. */
310 if (get_current_vuid(conn) != fsp->vuid) {
311 become_user(conn, fsp->vuid);
314 fsp->delete_on_close = true;
315 set_delete_on_close_lck(fsp, lck,
316 get_current_nttok(conn),
317 get_current_utok(conn));
323 delete_file = is_delete_on_close_set(lck, fsp->name_hash);
327 /* See if others still have the file open via this pathname.
328 If this is the case, then don't delete. If all opens are
330 for (i=0; i<lck->data->num_share_modes; i++) {
331 struct share_mode_entry *e = &lck->data->share_modes[i];
333 if (!is_valid_share_mode_entry(e)) {
336 if (e->name_hash != fsp->name_hash) {
339 if ((fsp->posix_flags & FSP_POSIX_FLAGS_OPEN)
340 && (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) {
343 if (serverid_equal(&self, &e->pid) &&
344 (e->share_file_id == fsp->fh->gen_id)) {
347 if (share_mode_stale_pid(lck->data, i)) {
356 * NT can set delete_on_close of the last open
357 * reference to a file.
360 normal_close = (close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE);
362 if (!normal_close || !delete_file) {
363 status = NT_STATUS_OK;
368 * Ok, we have to delete the file
371 DEBUG(5,("close_remove_share_mode: file %s. Delete on close was set "
372 "- deleting file.\n", fsp_str_dbg(fsp)));
375 * Don't try to update the write time when we delete the file
377 fsp->update_write_time_on_close = false;
379 got_tokens = get_delete_on_close_token(lck, fsp->name_hash,
380 &del_nt_token, &del_token);
381 SMB_ASSERT(got_tokens);
383 if (!unix_token_equal(del_token, get_current_utok(conn))) {
384 /* Become the user who requested the delete. */
386 DEBUG(5,("close_remove_share_mode: file %s. "
387 "Change user to uid %u\n",
389 (unsigned int)del_token->uid));
391 if (!push_sec_ctx()) {
392 smb_panic("close_remove_share_mode: file %s. failed to push "
396 set_sec_ctx(del_token->uid,
405 /* We can only delete the file if the name we have is still valid and
406 hasn't been renamed. */
408 tmp_status = vfs_stat_fsp(fsp);
409 if (!NT_STATUS_IS_OK(tmp_status)) {
410 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
411 "was set and stat failed with error %s\n",
412 fsp_str_dbg(fsp), nt_errstr(tmp_status)));
414 * Don't save the errno here, we ignore this error
419 id = vfs_file_id_from_sbuf(conn, &fsp->fsp_name->st);
421 if (!file_id_equal(&fsp->file_id, &id)) {
422 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
423 "was set and dev and/or inode does not match\n",
425 DEBUG(5,("close_remove_share_mode: file %s. stored file_id %s, "
428 file_id_string_tos(&fsp->file_id),
429 file_id_string_tos(&id)));
431 * Don't save the errno here, we ignore this error
436 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
437 && !is_ntfs_stream_smb_fname(fsp->fsp_name)) {
439 status = delete_all_streams(conn, fsp->fsp_name);
441 if (!NT_STATUS_IS_OK(status)) {
442 DEBUG(5, ("delete_all_streams failed: %s\n",
449 if (SMB_VFS_UNLINK(conn, fsp->fsp_name) != 0) {
451 * This call can potentially fail as another smbd may
452 * have had the file open with delete on close set and
453 * deleted it when its last reference to this file
454 * went away. Hence we log this but not at debug level
458 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
459 "was set and unlink failed with error %s\n",
460 fsp_str_dbg(fsp), strerror(errno)));
462 status = map_nt_error_from_unix(errno);
465 /* As we now have POSIX opens which can unlink
466 * with other open files we may have taken
467 * this code path with more than one share mode
468 * entry - ensure we only delete once by resetting
469 * the delete on close flag. JRA.
472 fsp->delete_on_close = false;
473 reset_delete_on_close_lck(fsp, lck);
482 if (fsp->kernel_share_modes_taken) {
485 /* remove filesystem sharemodes */
486 ret_flock = SMB_VFS_KERNEL_FLOCK(fsp, 0, 0);
487 if (ret_flock == -1) {
488 DEBUG(2, ("close_remove_share_mode: removing kernel "
489 "flock for %s failed: %s\n",
490 fsp_str_dbg(fsp), strerror(errno)));
494 if (!del_share_mode(lck, fsp)) {
495 DEBUG(0, ("close_remove_share_mode: Could not delete share "
496 "entry for file %s\n", fsp_str_dbg(fsp)));
503 * Do the notification after we released the share
504 * mode lock. Inside notify_fname we take out another
505 * tdb lock. With ctdb also accessing our databases,
506 * this can lead to deadlocks. Putting this notify
507 * after the TALLOC_FREE(lck) above we avoid locking
508 * two records simultaneously. Notifies are async and
509 * informational only, so calling the notify_fname
510 * without holding the share mode lock should not do
513 notify_fname(conn, NOTIFY_ACTION_REMOVED,
514 FILE_NOTIFY_CHANGE_FILE_NAME,
515 fsp->fsp_name->base_name);
521 void set_close_write_time(struct files_struct *fsp, struct timespec ts)
523 DEBUG(6,("close_write_time: %s" , time_to_asc(convert_timespec_to_time_t(ts))));
525 if (null_timespec(ts)) {
528 fsp->write_time_forced = false;
529 fsp->update_write_time_on_close = true;
530 fsp->close_write_time = ts;
533 static NTSTATUS update_write_time_on_close(struct files_struct *fsp)
535 struct smb_file_time ft;
537 struct share_mode_lock *lck = NULL;
541 if (!fsp->update_write_time_on_close) {
545 if (null_timespec(fsp->close_write_time)) {
546 fsp->close_write_time = timespec_current();
549 /* Ensure we have a valid stat struct for the source. */
550 status = vfs_stat_fsp(fsp);
551 if (!NT_STATUS_IS_OK(status)) {
555 if (!VALID_STAT(fsp->fsp_name->st)) {
556 /* if it doesn't seem to be a real file */
561 * get_existing_share_mode_lock() isn't really the right
562 * call here, as we're being called after
563 * close_remove_share_mode() inside close_normal_file()
564 * so it's quite normal to not have an existing share
565 * mode here. However, get_share_mode_lock() doesn't
566 * work because that will create a new share mode if
567 * one doesn't exist - so stick with this call (just
568 * ignore any error we get if the share mode doesn't
572 lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
574 /* On close if we're changing the real file time we
575 * must update it in the open file db too. */
576 (void)set_write_time(fsp->file_id, fsp->close_write_time);
578 /* Close write times overwrite sticky write times
579 so we must replace any sticky write time here. */
580 if (!null_timespec(lck->data->changed_write_time)) {
581 (void)set_sticky_write_time(fsp->file_id, fsp->close_write_time);
586 ft.mtime = fsp->close_write_time;
587 /* As this is a close based update, we are not directly changing the
588 file attributes from a client call, but indirectly from a write. */
589 status = smb_set_file_time(fsp->conn, fsp, fsp->fsp_name, &ft, false);
590 if (!NT_STATUS_IS_OK(status)) {
591 DEBUG(10,("update_write_time_on_close: smb_set_file_time "
592 "on file %s returned %s\n",
601 static NTSTATUS ntstatus_keeperror(NTSTATUS s1, NTSTATUS s2)
603 if (!NT_STATUS_IS_OK(s1)) {
609 /****************************************************************************
612 close_type can be NORMAL_CLOSE=0,SHUTDOWN_CLOSE,ERROR_CLOSE.
613 printing and magic scripts are only run on normal close.
614 delete on close is done on normal and shutdown close.
615 ****************************************************************************/
617 static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp,
618 enum file_close_type close_type)
620 NTSTATUS status = NT_STATUS_OK;
622 connection_struct *conn = fsp->conn;
623 bool is_durable = false;
625 if (fsp->num_aio_requests != 0) {
627 if (close_type != SHUTDOWN_CLOSE) {
629 * reply_close and the smb2 close must have
630 * taken care of this. No other callers of
631 * close_file should ever have created async
634 * We need to panic here because if we close()
635 * the fd while we have outstanding async I/O
636 * requests, in the worst case we could end up
637 * writing to the wrong file.
639 DEBUG(0, ("fsp->num_aio_requests=%u\n",
640 fsp->num_aio_requests));
641 smb_panic("can not close with outstanding aio "
646 * For shutdown close, just drop the async requests
647 * including a potential close request pending for
648 * this fsp. Drop the close request first, the
649 * destructor for the aio_requests would execute it.
651 TALLOC_FREE(fsp->deferred_close);
653 while (fsp->num_aio_requests != 0) {
655 * The destructor of the req will remove
656 * itself from the fsp.
657 * Don't use TALLOC_FREE here, this will overwrite
658 * what the destructor just wrote into
661 talloc_free(fsp->aio_requests[0]);
666 * If we're flushing on a close we can get a write
667 * error here, we must remember this.
670 tmp = close_filestruct(fsp);
671 status = ntstatus_keeperror(status, tmp);
673 if (NT_STATUS_IS_OK(status) && fsp->op != NULL) {
674 is_durable = fsp->op->global->durable;
677 if (close_type != SHUTDOWN_CLOSE) {
682 DATA_BLOB new_cookie = data_blob_null;
684 tmp = SMB_VFS_DURABLE_DISCONNECT(fsp,
685 fsp->op->global->backend_cookie,
688 if (NT_STATUS_IS_OK(tmp)) {
693 tv = req->request_time;
695 tv = timeval_current();
697 now = timeval_to_nttime(&tv);
699 data_blob_free(&fsp->op->global->backend_cookie);
700 fsp->op->global->backend_cookie = new_cookie;
702 fsp->op->compat = NULL;
703 tmp = smbXsrv_open_close(fsp->op, now);
704 if (!NT_STATUS_IS_OK(tmp)) {
705 DEBUG(1, ("Failed to update smbXsrv_open "
706 "record when disconnecting durable "
707 "handle for file %s: %s - "
708 "proceeding with normal close\n",
709 fsp_str_dbg(fsp), nt_errstr(tmp)));
711 scavenger_schedule_disconnected(fsp);
713 DEBUG(1, ("Failed to disconnect durable handle for "
714 "file %s: %s - proceeding with normal "
715 "close\n", fsp_str_dbg(fsp), nt_errstr(tmp)));
717 if (!NT_STATUS_IS_OK(tmp)) {
724 * This is the case where we successfully disconnected
725 * a durable handle and closed the underlying file.
726 * In all other cases, we proceed with a genuine close.
728 DEBUG(10, ("%s disconnected durable handle for file %s\n",
729 conn->session_info->unix_info->unix_name,
735 if (fsp->op != NULL) {
737 * Make sure the handle is not marked as durable anymore
739 fsp->op->global->durable = false;
742 if (fsp->print_file) {
743 /* FIXME: return spool errors */
744 print_spool_end(fsp, close_type);
749 /* If this is an old DOS or FCB open and we have multiple opens on
750 the same handle we only have one share mode. Ensure we only remove
751 the share mode on the last close. */
753 if (fsp->fh->ref_count == 1) {
754 /* Should we return on error here... ? */
755 tmp = close_remove_share_mode(fsp, close_type);
756 status = ntstatus_keeperror(status, tmp);
759 locking_close_file(conn->sconn->msg_ctx, fsp, close_type);
762 status = ntstatus_keeperror(status, tmp);
764 /* check for magic scripts */
765 if (close_type == NORMAL_CLOSE) {
766 tmp = check_magic(fsp);
767 status = ntstatus_keeperror(status, tmp);
771 * Ensure pending modtime is set after close.
774 tmp = update_write_time_on_close(fsp);
775 if (NT_STATUS_EQUAL(tmp, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
776 /* Someone renamed the file or a parent directory containing
777 * this file. We can't do anything about this, we don't have
778 * an "update timestamp by fd" call in POSIX. Eat the error. */
783 status = ntstatus_keeperror(status, tmp);
785 DEBUG(2,("%s closed file %s (numopen=%d) %s\n",
786 conn->session_info->unix_info->unix_name, fsp_str_dbg(fsp),
787 conn->num_files_open - 1,
788 nt_errstr(status) ));
793 /****************************************************************************
794 Function used by reply_rmdir to delete an entire directory
795 tree recursively. Return True on ok, False on fail.
796 ****************************************************************************/
798 bool recursive_rmdir(TALLOC_CTX *ctx,
799 connection_struct *conn,
800 struct smb_filename *smb_dname)
802 const char *dname = NULL;
803 char *talloced = NULL;
807 struct smb_Dir *dir_hnd;
809 SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
811 dir_hnd = OpenDir(talloc_tos(), conn, smb_dname, NULL, 0);
815 while((dname = ReadDirName(dir_hnd, &offset, &st, &talloced))) {
816 struct smb_filename *smb_dname_full = NULL;
817 char *fullname = NULL;
818 bool do_break = true;
820 if (ISDOT(dname) || ISDOTDOT(dname)) {
821 TALLOC_FREE(talloced);
825 if (!is_visible_file(conn, smb_dname->base_name, dname, &st,
827 TALLOC_FREE(talloced);
831 /* Construct the full name. */
832 fullname = talloc_asprintf(ctx,
834 smb_dname->base_name,
841 smb_dname_full = synthetic_smb_fname(talloc_tos(),
846 if (smb_dname_full == NULL) {
851 if(SMB_VFS_LSTAT(conn, smb_dname_full) != 0) {
855 if(smb_dname_full->st.st_ex_mode & S_IFDIR) {
856 if(!recursive_rmdir(ctx, conn, smb_dname_full)) {
859 if(SMB_VFS_RMDIR(conn, smb_dname_full) != 0) {
862 } else if(SMB_VFS_UNLINK(conn, smb_dname_full) != 0) {
866 /* Successful iteration. */
870 TALLOC_FREE(smb_dname_full);
871 TALLOC_FREE(fullname);
872 TALLOC_FREE(talloced);
878 TALLOC_FREE(dir_hnd);
882 /****************************************************************************
883 The internals of the rmdir code - called elsewhere.
884 ****************************************************************************/
886 static NTSTATUS rmdir_internals(TALLOC_CTX *ctx, files_struct *fsp)
888 connection_struct *conn = fsp->conn;
889 struct smb_filename *smb_dname = fsp->fsp_name;
892 SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
894 /* Might be a symlink. */
895 if(SMB_VFS_LSTAT(conn, smb_dname) != 0) {
896 return map_nt_error_from_unix(errno);
899 if (S_ISLNK(smb_dname->st.st_ex_mode)) {
900 /* Is what it points to a directory ? */
901 if(SMB_VFS_STAT(conn, smb_dname) != 0) {
902 return map_nt_error_from_unix(errno);
904 if (!(S_ISDIR(smb_dname->st.st_ex_mode))) {
905 return NT_STATUS_NOT_A_DIRECTORY;
907 ret = SMB_VFS_UNLINK(conn, smb_dname);
909 ret = SMB_VFS_RMDIR(conn, smb_dname);
912 notify_fname(conn, NOTIFY_ACTION_REMOVED,
913 FILE_NOTIFY_CHANGE_DIR_NAME,
914 smb_dname->base_name);
918 if(((errno == ENOTEMPTY)||(errno == EEXIST)) && *lp_veto_files(talloc_tos(), SNUM(conn))) {
920 * Check to see if the only thing in this directory are
921 * vetoed files/directories. If so then delete them and
922 * retry. If we fail to delete any of them (and we *don't*
923 * do a recursive delete) then fail the rmdir.
926 const char *dname = NULL;
927 char *talloced = NULL;
929 struct smb_Dir *dir_hnd = OpenDir(talloc_tos(), conn,
933 if(dir_hnd == NULL) {
938 while ((dname = ReadDirName(dir_hnd, &dirpos, &st,
939 &talloced)) != NULL) {
940 if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0)) {
941 TALLOC_FREE(talloced);
944 if (!is_visible_file(conn, smb_dname->base_name, dname,
946 TALLOC_FREE(talloced);
949 if(!IS_VETO_PATH(conn, dname)) {
950 TALLOC_FREE(dir_hnd);
951 TALLOC_FREE(talloced);
955 TALLOC_FREE(talloced);
958 /* We only have veto files/directories.
959 * Are we allowed to delete them ? */
961 if(!lp_delete_veto_files(SNUM(conn))) {
962 TALLOC_FREE(dir_hnd);
967 /* Do a recursive delete. */
968 RewindDir(dir_hnd,&dirpos);
969 while ((dname = ReadDirName(dir_hnd, &dirpos, &st,
970 &talloced)) != NULL) {
971 struct smb_filename *smb_dname_full = NULL;
972 char *fullname = NULL;
973 bool do_break = true;
975 if (ISDOT(dname) || ISDOTDOT(dname)) {
976 TALLOC_FREE(talloced);
979 if (!is_visible_file(conn, smb_dname->base_name, dname,
981 TALLOC_FREE(talloced);
985 fullname = talloc_asprintf(ctx,
987 smb_dname->base_name,
995 smb_dname_full = synthetic_smb_fname(talloc_tos(),
1000 if (smb_dname_full == NULL) {
1005 if(SMB_VFS_LSTAT(conn, smb_dname_full) != 0) {
1008 if(smb_dname_full->st.st_ex_mode & S_IFDIR) {
1009 if(!recursive_rmdir(ctx, conn,
1013 if(SMB_VFS_RMDIR(conn,
1014 smb_dname_full) != 0) {
1017 } else if(SMB_VFS_UNLINK(conn, smb_dname_full) != 0) {
1021 /* Successful iteration. */
1025 TALLOC_FREE(fullname);
1026 TALLOC_FREE(smb_dname_full);
1027 TALLOC_FREE(talloced);
1031 TALLOC_FREE(dir_hnd);
1032 /* Retry the rmdir */
1033 ret = SMB_VFS_RMDIR(conn, smb_dname);
1039 DEBUG(3,("rmdir_internals: couldn't remove directory %s : "
1040 "%s\n", smb_fname_str_dbg(smb_dname),
1042 return map_nt_error_from_unix(errno);
1045 notify_fname(conn, NOTIFY_ACTION_REMOVED,
1046 FILE_NOTIFY_CHANGE_DIR_NAME,
1047 smb_dname->base_name);
1049 return NT_STATUS_OK;
1052 /****************************************************************************
1053 Close a directory opened by an NT SMB call.
1054 ****************************************************************************/
1056 static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
1057 enum file_close_type close_type)
1059 struct server_id self = messaging_server_id(fsp->conn->sconn->msg_ctx);
1060 struct share_mode_lock *lck = NULL;
1061 bool delete_dir = False;
1062 NTSTATUS status = NT_STATUS_OK;
1063 NTSTATUS status1 = NT_STATUS_OK;
1064 const struct security_token *del_nt_token = NULL;
1065 const struct security_unix_token *del_token = NULL;
1066 NTSTATUS notify_status;
1068 if (fsp->conn->sconn->using_smb2) {
1069 notify_status = STATUS_NOTIFY_CLEANUP;
1071 notify_status = NT_STATUS_OK;
1075 * NT can set delete_on_close of the last open
1076 * reference to a directory also.
1079 lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
1081 DEBUG(0, ("close_directory: Could not get share mode lock for "
1082 "%s\n", fsp_str_dbg(fsp)));
1083 return NT_STATUS_INVALID_PARAMETER;
1086 if (fsp->initial_delete_on_close) {
1087 bool became_user = False;
1089 /* Initial delete on close was set - for
1090 * directories we don't care if anyone else
1091 * wrote a real delete on close. */
1093 if (get_current_vuid(fsp->conn) != fsp->vuid) {
1094 become_user(fsp->conn, fsp->vuid);
1097 send_stat_cache_delete_message(fsp->conn->sconn->msg_ctx,
1098 fsp->fsp_name->base_name);
1099 set_delete_on_close_lck(fsp, lck,
1100 get_current_nttok(fsp->conn),
1101 get_current_utok(fsp->conn));
1102 fsp->delete_on_close = true;
1108 delete_dir = get_delete_on_close_token(lck, fsp->name_hash,
1109 &del_nt_token, &del_token);
1113 /* See if others still have the dir open. If this is the
1114 * case, then don't delete. If all opens are POSIX delete now. */
1115 for (i=0; i<lck->data->num_share_modes; i++) {
1116 struct share_mode_entry *e = &lck->data->share_modes[i];
1117 if (is_valid_share_mode_entry(e) &&
1118 e->name_hash == fsp->name_hash) {
1119 if ((fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) &&
1120 (e->flags & SHARE_MODE_FLAG_POSIX_OPEN))
1124 if (serverid_equal(&self, &e->pid) &&
1125 (e->share_file_id == fsp->fh->gen_id)) {
1128 if (share_mode_stale_pid(lck->data, i)) {
1137 if ((close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) &&
1140 /* Become the user who requested the delete. */
1142 if (!push_sec_ctx()) {
1143 smb_panic("close_directory: failed to push sec_ctx.\n");
1146 set_sec_ctx(del_token->uid,
1152 if (!del_share_mode(lck, fsp)) {
1153 DEBUG(0, ("close_directory: Could not delete share entry for "
1154 "%s\n", fsp_str_dbg(fsp)));
1159 if ((fsp->conn->fs_capabilities & FILE_NAMED_STREAMS)
1160 && !is_ntfs_stream_smb_fname(fsp->fsp_name)) {
1162 status = delete_all_streams(fsp->conn, fsp->fsp_name);
1163 if (!NT_STATUS_IS_OK(status)) {
1164 DEBUG(5, ("delete_all_streams failed: %s\n",
1165 nt_errstr(status)));
1170 status = rmdir_internals(talloc_tos(), fsp);
1172 DEBUG(5,("close_directory: %s. Delete on close was set - "
1173 "deleting directory returned %s.\n",
1174 fsp_str_dbg(fsp), nt_errstr(status)));
1176 /* unbecome user. */
1180 * Ensure we remove any change notify requests that would
1181 * now fail as the directory has been deleted.
1184 if (NT_STATUS_IS_OK(status)) {
1185 notify_status = NT_STATUS_DELETE_PENDING;
1188 if (!del_share_mode(lck, fsp)) {
1189 DEBUG(0, ("close_directory: Could not delete share entry for "
1190 "%s\n", fsp_str_dbg(fsp)));
1196 remove_pending_change_notify_requests_by_fid(fsp, notify_status);
1198 status1 = fd_close(fsp);
1200 if (!NT_STATUS_IS_OK(status1)) {
1201 DEBUG(0, ("Could not close dir! fname=%s, fd=%d, err=%d=%s\n",
1202 fsp_str_dbg(fsp), fsp->fh->fd, errno,
1207 * Do the code common to files and directories.
1209 close_filestruct(fsp);
1210 file_free(req, fsp);
1212 if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(status1)) {
1218 /****************************************************************************
1219 Close a files_struct.
1220 ****************************************************************************/
1222 NTSTATUS close_file(struct smb_request *req, files_struct *fsp,
1223 enum file_close_type close_type)
1226 struct files_struct *base_fsp = fsp->base_fsp;
1228 if(fsp->is_directory) {
1229 status = close_directory(req, fsp, close_type);
1230 } else if (fsp->fake_file_handle != NULL) {
1231 status = close_fake_file(req, fsp);
1233 status = close_normal_file(req, fsp, close_type);
1236 if ((base_fsp != NULL) && (close_type != SHUTDOWN_CLOSE)) {
1239 * fsp was a stream, the base fsp can't be a stream as well
1241 * For SHUTDOWN_CLOSE this is not possible here, because
1242 * SHUTDOWN_CLOSE only happens from files.c which walks the
1243 * complete list of files. If we mess with more than one fsp
1244 * those loops will become confused.
1247 SMB_ASSERT(base_fsp->base_fsp == NULL);
1248 close_file(req, base_fsp, close_type);
1254 /****************************************************************************
1255 Deal with an (authorized) message to close a file given the share mode
1257 ****************************************************************************/
1259 void msg_close_file(struct messaging_context *msg_ctx,
1262 struct server_id server_id,
1265 files_struct *fsp = NULL;
1266 struct share_mode_entry e;
1267 struct smbd_server_connection *sconn =
1268 talloc_get_type_abort(private_data,
1269 struct smbd_server_connection);
1271 message_to_share_mode_entry(&e, (char *)data->data);
1274 char *sm_str = share_mode_str(NULL, 0, &e);
1276 smb_panic("talloc failed");
1278 DEBUG(10,("msg_close_file: got request to close share mode "
1279 "entry %s\n", sm_str));
1280 TALLOC_FREE(sm_str);
1283 fsp = file_find_dif(sconn, e.id, e.share_file_id);
1285 DEBUG(10,("msg_close_file: failed to find file.\n"));
1288 close_file(NULL, fsp, NORMAL_CLOSE);