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 "fake_file.h"
28 #include "transfer_file.h"
32 /****************************************************************************
33 Run a file if it is a magic script.
34 ****************************************************************************/
36 static NTSTATUS check_magic(struct files_struct *fsp)
39 const char *magic_output = NULL;
42 TALLOC_CTX *ctx = NULL;
44 struct connection_struct *conn = fsp->conn;
48 if (!*lp_magicscript(SNUM(conn))) {
52 DEBUG(5,("checking magic for %s\n", fsp_str_dbg(fsp)));
54 ctx = talloc_stackframe();
56 fname = fsp->fsp_name->base_name;
58 if (!(p = strrchr_m(fname,'/'))) {
64 if (!strequal(lp_magicscript(SNUM(conn)),p)) {
65 status = NT_STATUS_OK;
69 if (*lp_magicoutput(SNUM(conn))) {
70 magic_output = lp_magicoutput(SNUM(conn));
72 magic_output = talloc_asprintf(ctx,
77 status = NT_STATUS_NO_MEMORY;
81 /* Ensure we don't depend on user's PATH. */
82 p = talloc_asprintf(ctx, "./%s", fname);
84 status = NT_STATUS_NO_MEMORY;
88 if (chmod(fname, 0755) == -1) {
89 status = map_nt_error_from_unix(errno);
92 ret = smbrun(p,&tmp_fd);
93 DEBUG(3,("Invoking magic command %s gave %d\n",
97 if (ret != 0 || tmp_fd == -1) {
101 status = NT_STATUS_UNSUCCESSFUL;
104 outfd = open(magic_output, O_CREAT|O_EXCL|O_RDWR, 0600);
108 status = map_nt_error_from_unix(err);
112 if (sys_fstat(tmp_fd, &st, false) == -1) {
116 status = map_nt_error_from_unix(err);
120 if (transfer_file(tmp_fd,outfd,(SMB_OFF_T)st.st_ex_size) == (SMB_OFF_T)-1) {
124 status = map_nt_error_from_unix(err);
128 if (close(outfd) == -1) {
129 status = map_nt_error_from_unix(errno);
133 status = NT_STATUS_OK;
140 /****************************************************************************
141 Common code to close a file or a directory.
142 ****************************************************************************/
144 static NTSTATUS close_filestruct(files_struct *fsp)
146 NTSTATUS status = NT_STATUS_OK;
148 if (fsp->fh->fd != -1) {
149 if(flush_write_cache(fsp, CLOSE_FLUSH) == -1) {
150 status = map_nt_error_from_unix(errno);
152 delete_write_cache(fsp);
158 /****************************************************************************
159 If any deferred opens are waiting on this close, notify them.
160 ****************************************************************************/
162 static void notify_deferred_opens(struct messaging_context *msg_ctx,
163 struct share_mode_lock *lck)
167 if (!should_notify_deferred_opens()) {
171 for (i=0; i<lck->num_share_modes; i++) {
172 struct share_mode_entry *e = &lck->share_modes[i];
174 if (!is_deferred_open_entry(e)) {
178 if (procid_is_me(&e->pid)) {
179 struct smbd_server_connection *sconn;
181 * We need to notify ourself to retry the open. Do
182 * this by finding the queued SMB record, moving it to
183 * the head of the queue and changing the wait time to
186 sconn = msg_ctx_to_sconn(msg_ctx);
188 schedule_deferred_open_message_smb(
192 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
194 share_mode_entry_to_message(msg, e);
196 messaging_send_buf(msg_ctx, e->pid, MSG_SMB_OPEN_RETRY,
198 MSG_SMB_SHARE_MODE_ENTRY_SIZE);
203 /****************************************************************************
205 ****************************************************************************/
207 NTSTATUS delete_all_streams(connection_struct *conn, const char *fname)
209 struct stream_struct *stream_info = NULL;
211 unsigned int num_streams = 0;
212 TALLOC_CTX *frame = talloc_stackframe();
215 status = vfs_streaminfo(conn, NULL, fname, talloc_tos(),
216 &num_streams, &stream_info);
218 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
219 DEBUG(10, ("no streams around\n"));
224 if (!NT_STATUS_IS_OK(status)) {
225 DEBUG(10, ("vfs_streaminfo failed: %s\n",
230 DEBUG(10, ("delete_all_streams found %d streams\n",
233 if (num_streams == 0) {
238 for (i=0; i<num_streams; i++) {
240 struct smb_filename *smb_fname_stream = NULL;
242 if (strequal(stream_info[i].name, "::$DATA")) {
246 status = create_synthetic_smb_fname(talloc_tos(), fname,
247 stream_info[i].name, NULL,
250 if (!NT_STATUS_IS_OK(status)) {
251 DEBUG(0, ("talloc_aprintf failed\n"));
255 res = SMB_VFS_UNLINK(conn, smb_fname_stream);
258 status = map_nt_error_from_unix(errno);
259 DEBUG(10, ("Could not delete stream %s: %s\n",
260 smb_fname_str_dbg(smb_fname_stream),
262 TALLOC_FREE(smb_fname_stream);
265 TALLOC_FREE(smb_fname_stream);
273 /****************************************************************************
274 Deal with removing a share mode on last close.
275 ****************************************************************************/
277 static NTSTATUS close_remove_share_mode(files_struct *fsp,
278 enum file_close_type close_type)
280 connection_struct *conn = fsp->conn;
281 bool delete_file = false;
282 bool changed_user = false;
283 struct share_mode_lock *lck = NULL;
284 NTSTATUS status = NT_STATUS_OK;
287 const struct security_unix_token *del_token = NULL;
289 /* Ensure any pending write time updates are done. */
290 if (fsp->update_write_time_event) {
291 update_write_time_handler(server_event_context(),
292 fsp->update_write_time_event,
298 * Lock the share entries, and determine if we should delete
299 * on close. If so delete whilst the lock is still in effect.
300 * This prevents race conditions with the file being created. JRA.
303 lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL,
307 DEBUG(0, ("close_remove_share_mode: Could not get share mode "
308 "lock for file %s\n", fsp_str_dbg(fsp)));
309 status = NT_STATUS_INVALID_PARAMETER;
313 if (fsp->write_time_forced) {
314 DEBUG(10,("close_remove_share_mode: write time forced "
317 set_close_write_time(fsp, lck->changed_write_time);
318 } else if (fsp->update_write_time_on_close) {
319 /* Someone had a pending write. */
320 if (null_timespec(fsp->close_write_time)) {
321 DEBUG(10,("close_remove_share_mode: update to current time "
324 /* Update to current time due to "normal" write. */
325 set_close_write_time(fsp, timespec_current());
327 DEBUG(10,("close_remove_share_mode: write time pending "
330 /* Update to time set on close call. */
331 set_close_write_time(fsp, fsp->close_write_time);
335 if (!del_share_mode(lck, fsp)) {
336 DEBUG(0, ("close_remove_share_mode: Could not delete share "
337 "entry for file %s\n",
341 if (fsp->initial_delete_on_close &&
342 !is_delete_on_close_set(lck, fsp->name_hash)) {
343 bool became_user = False;
345 /* Initial delete on close was set and no one else
346 * wrote a real delete on close. */
348 if (get_current_vuid(conn) != fsp->vuid) {
349 become_user(conn, fsp->vuid);
352 fsp->delete_on_close = true;
353 set_delete_on_close_lck(fsp, lck, True, get_current_utok(conn));
359 delete_file = is_delete_on_close_set(lck, fsp->name_hash);
363 /* See if others still have the file open via this pathname.
364 If this is the case, then don't delete. If all opens are
366 for (i=0; i<lck->num_share_modes; i++) {
367 struct share_mode_entry *e = &lck->share_modes[i];
368 if (is_valid_share_mode_entry(e) &&
369 e->name_hash == fsp->name_hash) {
370 if (fsp->posix_open && (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) {
379 /* Notify any deferred opens waiting on this close. */
380 notify_deferred_opens(conn->sconn->msg_ctx, lck);
381 reply_to_oplock_break_requests(fsp);
384 * NT can set delete_on_close of the last open
385 * reference to a file.
388 if (!(close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) ||
395 * Ok, we have to delete the file
398 DEBUG(5,("close_remove_share_mode: file %s. Delete on close was set "
399 "- deleting file.\n", fsp_str_dbg(fsp)));
402 * Don't try to update the write time when we delete the file
404 fsp->update_write_time_on_close = false;
406 del_token = get_delete_on_close_token(lck, fsp->name_hash);
407 SMB_ASSERT(del_token != NULL);
409 if (!unix_token_equal(del_token, get_current_utok(conn))) {
410 /* Become the user who requested the delete. */
412 DEBUG(5,("close_remove_share_mode: file %s. "
413 "Change user to uid %u\n",
415 (unsigned int)del_token->uid));
417 if (!push_sec_ctx()) {
418 smb_panic("close_remove_share_mode: file %s. failed to push "
422 set_sec_ctx(del_token->uid,
431 /* We can only delete the file if the name we have is still valid and
432 hasn't been renamed. */
434 tmp_status = vfs_stat_fsp(fsp);
435 if (!NT_STATUS_IS_OK(tmp_status)) {
436 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
437 "was set and stat failed with error %s\n",
438 fsp_str_dbg(fsp), nt_errstr(tmp_status)));
440 * Don't save the errno here, we ignore this error
445 id = vfs_file_id_from_sbuf(conn, &fsp->fsp_name->st);
447 if (!file_id_equal(&fsp->file_id, &id)) {
448 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
449 "was set and dev and/or inode does not match\n",
451 DEBUG(5,("close_remove_share_mode: file %s. stored file_id %s, "
454 file_id_string_tos(&fsp->file_id),
455 file_id_string_tos(&id)));
457 * Don't save the errno here, we ignore this error
462 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
463 && !is_ntfs_stream_smb_fname(fsp->fsp_name)) {
465 status = delete_all_streams(conn, fsp->fsp_name->base_name);
467 if (!NT_STATUS_IS_OK(status)) {
468 DEBUG(5, ("delete_all_streams failed: %s\n",
475 if (SMB_VFS_UNLINK(conn, fsp->fsp_name) != 0) {
477 * This call can potentially fail as another smbd may
478 * have had the file open with delete on close set and
479 * deleted it when its last reference to this file
480 * went away. Hence we log this but not at debug level
484 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
485 "was set and unlink failed with error %s\n",
486 fsp_str_dbg(fsp), strerror(errno)));
488 status = map_nt_error_from_unix(errno);
491 /* As we now have POSIX opens which can unlink
492 * with other open files we may have taken
493 * this code path with more than one share mode
494 * entry - ensure we only delete once by resetting
495 * the delete on close flag. JRA.
498 fsp->delete_on_close = false;
499 set_delete_on_close_lck(fsp, lck, false, NULL);
512 * Do the notification after we released the share
513 * mode lock. Inside notify_fname we take out another
514 * tdb lock. With ctdb also accessing our databases,
515 * this can lead to deadlocks. Putting this notify
516 * after the TALLOC_FREE(lck) above we avoid locking
517 * two records simultaneously. Notifies are async and
518 * informational only, so calling the notify_fname
519 * without holding the share mode lock should not do
522 notify_fname(conn, NOTIFY_ACTION_REMOVED,
523 FILE_NOTIFY_CHANGE_FILE_NAME,
524 fsp->fsp_name->base_name);
530 void set_close_write_time(struct files_struct *fsp, struct timespec ts)
532 DEBUG(6,("close_write_time: %s" , time_to_asc(convert_timespec_to_time_t(ts))));
534 if (null_timespec(ts)) {
537 fsp->write_time_forced = false;
538 fsp->update_write_time_on_close = true;
539 fsp->close_write_time = ts;
542 static NTSTATUS update_write_time_on_close(struct files_struct *fsp)
544 struct smb_file_time ft;
546 struct share_mode_lock *lck = NULL;
550 if (!fsp->update_write_time_on_close) {
554 if (null_timespec(fsp->close_write_time)) {
555 fsp->close_write_time = timespec_current();
558 /* Ensure we have a valid stat struct for the source. */
559 status = vfs_stat_fsp(fsp);
560 if (!NT_STATUS_IS_OK(status)) {
564 if (!VALID_STAT(fsp->fsp_name->st)) {
565 /* if it doesn't seem to be a real file */
569 /* On close if we're changing the real file time we
570 * must update it in the open file db too. */
571 (void)set_write_time(fsp->file_id, fsp->close_write_time);
573 lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL, NULL);
575 /* Close write times overwrite sticky write times
576 so we must replace any sticky write time here. */
577 if (!null_timespec(lck->changed_write_time)) {
578 (void)set_sticky_write_time(fsp->file_id, fsp->close_write_time);
583 ft.mtime = fsp->close_write_time;
584 /* We must use NULL for the fsp handle here, as smb_set_file_time()
585 checks the fsp access_mask, which may not include FILE_WRITE_ATTRIBUTES.
586 As this is a close based update, we are not directly changing the
587 file attributes from a client call, but indirectly from a write. */
588 status = smb_set_file_time(fsp->conn, NULL, fsp->fsp_name, &ft, false);
589 if (!NT_STATUS_IS_OK(status)) {
590 DEBUG(10,("update_write_time_on_close: smb_set_file_time "
591 "on file %s returned %s\n",
600 static NTSTATUS ntstatus_keeperror(NTSTATUS s1, NTSTATUS s2)
602 if (!NT_STATUS_IS_OK(s1)) {
608 /****************************************************************************
611 close_type can be NORMAL_CLOSE=0,SHUTDOWN_CLOSE,ERROR_CLOSE.
612 printing and magic scripts are only run on normal close.
613 delete on close is done on normal and shutdown close.
614 ****************************************************************************/
616 static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp,
617 enum file_close_type close_type)
619 NTSTATUS status = NT_STATUS_OK;
621 connection_struct *conn = fsp->conn;
623 if (close_type == ERROR_CLOSE) {
624 cancel_aio_by_fsp(fsp);
627 * If we're finishing async io on a close we can get a write
628 * error here, we must remember this.
630 int ret = wait_for_aio_completion(fsp);
632 status = ntstatus_keeperror(
633 status, map_nt_error_from_unix(ret));
638 * If we're flushing on a close we can get a write
639 * error here, we must remember this.
642 tmp = close_filestruct(fsp);
643 status = ntstatus_keeperror(status, tmp);
645 if (fsp->print_file) {
646 /* FIXME: return spool errors */
647 print_spool_end(fsp, close_type);
652 /* Remove the oplock before potentially deleting the file. */
653 if(fsp->oplock_type) {
654 release_file_oplock(fsp);
657 /* If this is an old DOS or FCB open and we have multiple opens on
658 the same handle we only have one share mode. Ensure we only remove
659 the share mode on the last close. */
661 if (fsp->fh->ref_count == 1) {
662 /* Should we return on error here... ? */
663 tmp = close_remove_share_mode(fsp, close_type);
664 status = ntstatus_keeperror(status, tmp);
667 locking_close_file(conn->sconn->msg_ctx, fsp, close_type);
670 status = ntstatus_keeperror(status, tmp);
672 /* check for magic scripts */
673 if (close_type == NORMAL_CLOSE) {
674 tmp = check_magic(fsp);
675 status = ntstatus_keeperror(status, tmp);
679 * Ensure pending modtime is set after close.
682 tmp = update_write_time_on_close(fsp);
683 if (NT_STATUS_EQUAL(tmp, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
684 /* Someone renamed the file or a parent directory containing
685 * this file. We can't do anything about this, we don't have
686 * an "update timestamp by fd" call in POSIX. Eat the error. */
691 status = ntstatus_keeperror(status, tmp);
693 DEBUG(2,("%s closed file %s (numopen=%d) %s\n",
694 conn->session_info->unix_info->unix_name, fsp_str_dbg(fsp),
695 conn->num_files_open - 1,
696 nt_errstr(status) ));
701 /****************************************************************************
702 Static function used by reply_rmdir to delete an entire directory
703 tree recursively. Return True on ok, False on fail.
704 ****************************************************************************/
706 static bool recursive_rmdir(TALLOC_CTX *ctx,
707 connection_struct *conn,
708 struct smb_filename *smb_dname)
710 const char *dname = NULL;
711 char *talloced = NULL;
715 struct smb_Dir *dir_hnd;
717 SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
719 dir_hnd = OpenDir(talloc_tos(), conn, smb_dname->base_name, NULL, 0);
723 while((dname = ReadDirName(dir_hnd, &offset, &st, &talloced))) {
724 struct smb_filename *smb_dname_full = NULL;
725 char *fullname = NULL;
726 bool do_break = true;
729 if (ISDOT(dname) || ISDOTDOT(dname)) {
730 TALLOC_FREE(talloced);
734 if (!is_visible_file(conn, smb_dname->base_name, dname, &st,
736 TALLOC_FREE(talloced);
740 /* Construct the full name. */
741 fullname = talloc_asprintf(ctx,
743 smb_dname->base_name,
750 status = create_synthetic_smb_fname(talloc_tos(), fullname,
753 if (!NT_STATUS_IS_OK(status)) {
757 if(SMB_VFS_LSTAT(conn, smb_dname_full) != 0) {
761 if(smb_dname_full->st.st_ex_mode & S_IFDIR) {
762 if(!recursive_rmdir(ctx, conn, smb_dname_full)) {
765 if(SMB_VFS_RMDIR(conn,
766 smb_dname_full->base_name) != 0) {
769 } else if(SMB_VFS_UNLINK(conn, smb_dname_full) != 0) {
773 /* Successful iteration. */
777 TALLOC_FREE(smb_dname_full);
778 TALLOC_FREE(fullname);
779 TALLOC_FREE(talloced);
785 TALLOC_FREE(dir_hnd);
789 /****************************************************************************
790 The internals of the rmdir code - called elsewhere.
791 ****************************************************************************/
793 static NTSTATUS rmdir_internals(TALLOC_CTX *ctx, files_struct *fsp)
795 connection_struct *conn = fsp->conn;
796 struct smb_filename *smb_dname = fsp->fsp_name;
799 SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
801 /* Might be a symlink. */
802 if(SMB_VFS_LSTAT(conn, smb_dname) != 0) {
803 return map_nt_error_from_unix(errno);
806 if (S_ISLNK(smb_dname->st.st_ex_mode)) {
807 /* Is what it points to a directory ? */
808 if(SMB_VFS_STAT(conn, smb_dname) != 0) {
809 return map_nt_error_from_unix(errno);
811 if (!(S_ISDIR(smb_dname->st.st_ex_mode))) {
812 return NT_STATUS_NOT_A_DIRECTORY;
814 ret = SMB_VFS_UNLINK(conn, smb_dname);
816 ret = SMB_VFS_RMDIR(conn, smb_dname->base_name);
819 notify_fname(conn, NOTIFY_ACTION_REMOVED,
820 FILE_NOTIFY_CHANGE_DIR_NAME,
821 smb_dname->base_name);
825 if(((errno == ENOTEMPTY)||(errno == EEXIST)) && lp_veto_files(SNUM(conn))) {
827 * Check to see if the only thing in this directory are
828 * vetoed files/directories. If so then delete them and
829 * retry. If we fail to delete any of them (and we *don't*
830 * do a recursive delete) then fail the rmdir.
833 const char *dname = NULL;
834 char *talloced = NULL;
836 struct smb_Dir *dir_hnd = OpenDir(talloc_tos(), conn,
837 smb_dname->base_name, NULL,
840 if(dir_hnd == NULL) {
845 while ((dname = ReadDirName(dir_hnd, &dirpos, &st,
846 &talloced)) != NULL) {
847 if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0)) {
848 TALLOC_FREE(talloced);
851 if (!is_visible_file(conn, smb_dname->base_name, dname,
853 TALLOC_FREE(talloced);
856 if(!IS_VETO_PATH(conn, dname)) {
857 TALLOC_FREE(dir_hnd);
858 TALLOC_FREE(talloced);
862 TALLOC_FREE(talloced);
865 /* We only have veto files/directories.
866 * Are we allowed to delete them ? */
868 if(!lp_recursive_veto_delete(SNUM(conn))) {
869 TALLOC_FREE(dir_hnd);
874 /* Do a recursive delete. */
875 RewindDir(dir_hnd,&dirpos);
876 while ((dname = ReadDirName(dir_hnd, &dirpos, &st,
877 &talloced)) != NULL) {
878 struct smb_filename *smb_dname_full = NULL;
879 char *fullname = NULL;
880 bool do_break = true;
883 if (ISDOT(dname) || ISDOTDOT(dname)) {
884 TALLOC_FREE(talloced);
887 if (!is_visible_file(conn, smb_dname->base_name, dname,
889 TALLOC_FREE(talloced);
893 fullname = talloc_asprintf(ctx,
895 smb_dname->base_name,
903 status = create_synthetic_smb_fname(talloc_tos(),
907 if (!NT_STATUS_IS_OK(status)) {
908 errno = map_errno_from_nt_status(status);
912 if(SMB_VFS_LSTAT(conn, smb_dname_full) != 0) {
915 if(smb_dname_full->st.st_ex_mode & S_IFDIR) {
916 if(!recursive_rmdir(ctx, conn,
920 if(SMB_VFS_RMDIR(conn,
921 smb_dname_full->base_name) != 0) {
924 } else if(SMB_VFS_UNLINK(conn, smb_dname_full) != 0) {
928 /* Successful iteration. */
932 TALLOC_FREE(fullname);
933 TALLOC_FREE(smb_dname_full);
934 TALLOC_FREE(talloced);
938 TALLOC_FREE(dir_hnd);
939 /* Retry the rmdir */
940 ret = SMB_VFS_RMDIR(conn, smb_dname->base_name);
946 DEBUG(3,("rmdir_internals: couldn't remove directory %s : "
947 "%s\n", smb_fname_str_dbg(smb_dname),
949 return map_nt_error_from_unix(errno);
952 notify_fname(conn, NOTIFY_ACTION_REMOVED,
953 FILE_NOTIFY_CHANGE_DIR_NAME,
954 smb_dname->base_name);
959 /****************************************************************************
960 Close a directory opened by an NT SMB call.
961 ****************************************************************************/
963 static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
964 enum file_close_type close_type)
966 struct share_mode_lock *lck = NULL;
967 bool delete_dir = False;
968 NTSTATUS status = NT_STATUS_OK;
969 NTSTATUS status1 = NT_STATUS_OK;
970 const struct security_unix_token *del_token = NULL;
973 * NT can set delete_on_close of the last open
974 * reference to a directory also.
977 lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL,
981 DEBUG(0, ("close_directory: Could not get share mode lock for "
982 "%s\n", fsp_str_dbg(fsp)));
983 status = NT_STATUS_INVALID_PARAMETER;
987 if (!del_share_mode(lck, fsp)) {
988 DEBUG(0, ("close_directory: Could not delete share entry for "
989 "%s\n", fsp_str_dbg(fsp)));
992 if (fsp->initial_delete_on_close) {
993 bool became_user = False;
995 /* Initial delete on close was set - for
996 * directories we don't care if anyone else
997 * wrote a real delete on close. */
999 if (get_current_vuid(fsp->conn) != fsp->vuid) {
1000 become_user(fsp->conn, fsp->vuid);
1003 send_stat_cache_delete_message(fsp->conn->sconn->msg_ctx,
1004 fsp->fsp_name->base_name);
1005 set_delete_on_close_lck(fsp, lck, true,
1006 get_current_utok(fsp->conn));
1007 fsp->delete_on_close = true;
1013 del_token = get_delete_on_close_token(lck, fsp->name_hash);
1014 delete_dir = (del_token != NULL);
1018 /* See if others still have the dir open. If this is the
1019 * case, then don't delete. If all opens are POSIX delete now. */
1020 for (i=0; i<lck->num_share_modes; i++) {
1021 struct share_mode_entry *e = &lck->share_modes[i];
1022 if (is_valid_share_mode_entry(e) &&
1023 e->name_hash == fsp->name_hash) {
1024 if (fsp->posix_open && (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) {
1033 if ((close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) &&
1036 /* Become the user who requested the delete. */
1038 if (!push_sec_ctx()) {
1039 smb_panic("close_directory: failed to push sec_ctx.\n");
1042 set_sec_ctx(del_token->uid,
1050 status = rmdir_internals(talloc_tos(), fsp);
1052 DEBUG(5,("close_directory: %s. Delete on close was set - "
1053 "deleting directory returned %s.\n",
1054 fsp_str_dbg(fsp), nt_errstr(status)));
1056 /* unbecome user. */
1060 * Ensure we remove any change notify requests that would
1061 * now fail as the directory has been deleted.
1064 if(NT_STATUS_IS_OK(status)) {
1065 remove_pending_change_notify_requests_by_fid(fsp, NT_STATUS_DELETE_PENDING);
1069 remove_pending_change_notify_requests_by_fid(
1073 status1 = fd_close(fsp);
1075 if (!NT_STATUS_IS_OK(status1)) {
1076 DEBUG(0, ("Could not close dir! fname=%s, fd=%d, err=%d=%s\n",
1077 fsp_str_dbg(fsp), fsp->fh->fd, errno,
1082 * Do the code common to files and directories.
1084 close_filestruct(fsp);
1085 file_free(req, fsp);
1089 if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(status1)) {
1095 /****************************************************************************
1096 Close a files_struct.
1097 ****************************************************************************/
1099 NTSTATUS close_file(struct smb_request *req, files_struct *fsp,
1100 enum file_close_type close_type)
1103 struct files_struct *base_fsp = fsp->base_fsp;
1105 if(fsp->is_directory) {
1106 status = close_directory(req, fsp, close_type);
1107 } else if (fsp->fake_file_handle != NULL) {
1108 status = close_fake_file(req, fsp);
1110 status = close_normal_file(req, fsp, close_type);
1113 if ((base_fsp != NULL) && (close_type != SHUTDOWN_CLOSE)) {
1116 * fsp was a stream, the base fsp can't be a stream as well
1118 * For SHUTDOWN_CLOSE this is not possible here, because
1119 * SHUTDOWN_CLOSE only happens from files.c which walks the
1120 * complete list of files. If we mess with more than one fsp
1121 * those loops will become confused.
1124 SMB_ASSERT(base_fsp->base_fsp == NULL);
1125 close_file(req, base_fsp, close_type);
1131 /****************************************************************************
1132 Deal with an (authorized) message to close a file given the share mode
1134 ****************************************************************************/
1136 void msg_close_file(struct messaging_context *msg_ctx,
1139 struct server_id server_id,
1142 struct smbd_server_connection *sconn;
1143 files_struct *fsp = NULL;
1144 struct share_mode_entry e;
1146 sconn = msg_ctx_to_sconn(msg_ctx);
1147 if (sconn == NULL) {
1148 DEBUG(1, ("could not find sconn\n"));
1152 message_to_share_mode_entry(&e, (char *)data->data);
1155 char *sm_str = share_mode_str(NULL, 0, &e);
1157 smb_panic("talloc failed");
1159 DEBUG(10,("msg_close_file: got request to close share mode "
1160 "entry %s\n", sm_str));
1161 TALLOC_FREE(sm_str);
1164 fsp = file_find_dif(sconn, e.id, e.share_file_id);
1166 DEBUG(10,("msg_close_file: failed to find file.\n"));
1169 close_file(NULL, fsp, NORMAL_CLOSE);