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 "librpc/gen_ndr/messaging.h"
26 #include "smbd/globals.h"
27 #include "fake_file.h"
28 #include "transfer_file.h"
30 /****************************************************************************
31 Run a file if it is a magic script.
32 ****************************************************************************/
34 static NTSTATUS check_magic(struct files_struct *fsp)
37 const char *magic_output = NULL;
40 TALLOC_CTX *ctx = NULL;
42 struct connection_struct *conn = fsp->conn;
46 if (!*lp_magicscript(SNUM(conn))) {
50 DEBUG(5,("checking magic for %s\n", fsp_str_dbg(fsp)));
52 ctx = talloc_stackframe();
54 fname = fsp->fsp_name->base_name;
56 if (!(p = strrchr_m(fname,'/'))) {
62 if (!strequal(lp_magicscript(SNUM(conn)),p)) {
63 status = NT_STATUS_OK;
67 if (*lp_magicoutput(SNUM(conn))) {
68 magic_output = lp_magicoutput(SNUM(conn));
70 magic_output = talloc_asprintf(ctx,
75 status = NT_STATUS_NO_MEMORY;
79 /* Ensure we don't depend on user's PATH. */
80 p = talloc_asprintf(ctx, "./%s", fname);
82 status = NT_STATUS_NO_MEMORY;
86 if (chmod(fname, 0755) == -1) {
87 status = map_nt_error_from_unix(errno);
90 ret = smbrun(p,&tmp_fd);
91 DEBUG(3,("Invoking magic command %s gave %d\n",
95 if (ret != 0 || tmp_fd == -1) {
99 status = NT_STATUS_UNSUCCESSFUL;
102 outfd = open(magic_output, O_CREAT|O_EXCL|O_RDWR, 0600);
106 status = map_nt_error_from_unix(err);
110 if (sys_fstat(tmp_fd, &st, false) == -1) {
114 status = map_nt_error_from_unix(err);
118 if (transfer_file(tmp_fd,outfd,(SMB_OFF_T)st.st_ex_size) == (SMB_OFF_T)-1) {
122 status = map_nt_error_from_unix(err);
126 if (close(outfd) == -1) {
127 status = map_nt_error_from_unix(errno);
131 status = NT_STATUS_OK;
138 /****************************************************************************
139 Common code to close a file or a directory.
140 ****************************************************************************/
142 static NTSTATUS close_filestruct(files_struct *fsp)
144 NTSTATUS status = NT_STATUS_OK;
146 if (fsp->fh->fd != -1) {
147 if(flush_write_cache(fsp, CLOSE_FLUSH) == -1) {
148 status = map_nt_error_from_unix(errno);
150 delete_write_cache(fsp);
156 /****************************************************************************
157 If any deferred opens are waiting on this close, notify them.
158 ****************************************************************************/
160 static void notify_deferred_opens(struct messaging_context *msg_ctx,
161 struct share_mode_lock *lck)
165 if (!should_notify_deferred_opens()) {
169 for (i=0; i<lck->num_share_modes; i++) {
170 struct share_mode_entry *e = &lck->share_modes[i];
172 if (!is_deferred_open_entry(e)) {
176 if (procid_is_me(&e->pid)) {
178 * We need to notify ourself to retry the open. Do
179 * this by finding the queued SMB record, moving it to
180 * the head of the queue and changing the wait time to
183 schedule_deferred_open_message_smb(e->op_mid);
185 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
187 share_mode_entry_to_message(msg, e);
189 messaging_send_buf(msg_ctx, e->pid, MSG_SMB_OPEN_RETRY,
191 MSG_SMB_SHARE_MODE_ENTRY_SIZE);
196 /****************************************************************************
198 ****************************************************************************/
200 NTSTATUS delete_all_streams(connection_struct *conn, const char *fname)
202 struct stream_struct *stream_info;
204 unsigned int num_streams;
205 TALLOC_CTX *frame = talloc_stackframe();
208 status = SMB_VFS_STREAMINFO(conn, NULL, fname, talloc_tos(),
209 &num_streams, &stream_info);
211 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
212 DEBUG(10, ("no streams around\n"));
217 if (!NT_STATUS_IS_OK(status)) {
218 DEBUG(10, ("SMB_VFS_STREAMINFO failed: %s\n",
223 DEBUG(10, ("delete_all_streams found %d streams\n",
226 if (num_streams == 0) {
231 for (i=0; i<num_streams; i++) {
233 struct smb_filename *smb_fname_stream = NULL;
235 if (strequal(stream_info[i].name, "::$DATA")) {
239 status = create_synthetic_smb_fname(talloc_tos(), fname,
240 stream_info[i].name, NULL,
243 if (!NT_STATUS_IS_OK(status)) {
244 DEBUG(0, ("talloc_aprintf failed\n"));
248 res = SMB_VFS_UNLINK(conn, smb_fname_stream);
251 status = map_nt_error_from_unix(errno);
252 DEBUG(10, ("Could not delete stream %s: %s\n",
253 smb_fname_str_dbg(smb_fname_stream),
255 TALLOC_FREE(smb_fname_stream);
258 TALLOC_FREE(smb_fname_stream);
266 /****************************************************************************
267 Deal with removing a share mode on last close.
268 ****************************************************************************/
270 static NTSTATUS close_remove_share_mode(files_struct *fsp,
271 enum file_close_type close_type)
273 connection_struct *conn = fsp->conn;
274 bool delete_file = false;
275 bool changed_user = false;
276 struct share_mode_lock *lck = NULL;
277 NTSTATUS status = NT_STATUS_OK;
280 const struct security_unix_token *del_token = NULL;
282 /* Ensure any pending write time updates are done. */
283 if (fsp->update_write_time_event) {
284 update_write_time_handler(smbd_event_context(),
285 fsp->update_write_time_event,
291 * Lock the share entries, and determine if we should delete
292 * on close. If so delete whilst the lock is still in effect.
293 * This prevents race conditions with the file being created. JRA.
296 lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL,
300 DEBUG(0, ("close_remove_share_mode: Could not get share mode "
301 "lock for file %s\n", fsp_str_dbg(fsp)));
302 status = NT_STATUS_INVALID_PARAMETER;
306 if (fsp->write_time_forced) {
307 DEBUG(10,("close_remove_share_mode: write time forced "
310 set_close_write_time(fsp, lck->changed_write_time);
311 } else if (fsp->update_write_time_on_close) {
312 /* Someone had a pending write. */
313 if (null_timespec(fsp->close_write_time)) {
314 DEBUG(10,("close_remove_share_mode: update to current time "
317 /* Update to current time due to "normal" write. */
318 set_close_write_time(fsp, timespec_current());
320 DEBUG(10,("close_remove_share_mode: write time pending "
323 /* Update to time set on close call. */
324 set_close_write_time(fsp, fsp->close_write_time);
328 if (!del_share_mode(lck, fsp)) {
329 DEBUG(0, ("close_remove_share_mode: Could not delete share "
330 "entry for file %s\n",
334 if (fsp->initial_delete_on_close &&
335 !is_delete_on_close_set(lck, fsp->name_hash)) {
336 bool became_user = False;
338 /* Initial delete on close was set and no one else
339 * wrote a real delete on close. */
341 if (get_current_vuid(conn) != fsp->vuid) {
342 become_user(conn, fsp->vuid);
345 fsp->delete_on_close = true;
346 set_delete_on_close_lck(fsp, lck, True, get_current_utok(conn));
352 delete_file = is_delete_on_close_set(lck, fsp->name_hash);
356 /* See if others still have the file open via this pathname.
357 If this is the case, then don't delete. If all opens are
359 for (i=0; i<lck->num_share_modes; i++) {
360 struct share_mode_entry *e = &lck->share_modes[i];
361 if (is_valid_share_mode_entry(e) &&
362 e->name_hash == fsp->name_hash) {
363 if (fsp->posix_open && (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) {
372 /* Notify any deferred opens waiting on this close. */
373 notify_deferred_opens(conn->sconn->msg_ctx, lck);
374 reply_to_oplock_break_requests(fsp);
377 * NT can set delete_on_close of the last open
378 * reference to a file.
381 if (!(close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) ||
388 * Ok, we have to delete the file
391 DEBUG(5,("close_remove_share_mode: file %s. Delete on close was set "
392 "- deleting file.\n", fsp_str_dbg(fsp)));
395 * Don't try to update the write time when we delete the file
397 fsp->update_write_time_on_close = false;
399 del_token = get_delete_on_close_token(lck, fsp->name_hash);
400 SMB_ASSERT(del_token != NULL);
402 if (!unix_token_equal(del_token, get_current_utok(conn))) {
403 /* Become the user who requested the delete. */
405 DEBUG(5,("close_remove_share_mode: file %s. "
406 "Change user to uid %u\n",
408 (unsigned int)del_token->uid));
410 if (!push_sec_ctx()) {
411 smb_panic("close_remove_share_mode: file %s. failed to push "
415 set_sec_ctx(del_token->uid,
424 /* We can only delete the file if the name we have is still valid and
425 hasn't been renamed. */
427 tmp_status = vfs_stat_fsp(fsp);
428 if (!NT_STATUS_IS_OK(tmp_status)) {
429 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
430 "was set and stat failed with error %s\n",
431 fsp_str_dbg(fsp), nt_errstr(tmp_status)));
433 * Don't save the errno here, we ignore this error
438 id = vfs_file_id_from_sbuf(conn, &fsp->fsp_name->st);
440 if (!file_id_equal(&fsp->file_id, &id)) {
441 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
442 "was set and dev and/or inode does not match\n",
444 DEBUG(5,("close_remove_share_mode: file %s. stored file_id %s, "
447 file_id_string_tos(&fsp->file_id),
448 file_id_string_tos(&id)));
450 * Don't save the errno here, we ignore this error
455 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
456 && !is_ntfs_stream_smb_fname(fsp->fsp_name)) {
458 status = delete_all_streams(conn, fsp->fsp_name->base_name);
460 if (!NT_STATUS_IS_OK(status)) {
461 DEBUG(5, ("delete_all_streams failed: %s\n",
468 if (SMB_VFS_UNLINK(conn, fsp->fsp_name) != 0) {
470 * This call can potentially fail as another smbd may
471 * have had the file open with delete on close set and
472 * deleted it when its last reference to this file
473 * went away. Hence we log this but not at debug level
477 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
478 "was set and unlink failed with error %s\n",
479 fsp_str_dbg(fsp), strerror(errno)));
481 status = map_nt_error_from_unix(errno);
484 /* As we now have POSIX opens which can unlink
485 * with other open files we may have taken
486 * this code path with more than one share mode
487 * entry - ensure we only delete once by resetting
488 * the delete on close flag. JRA.
491 fsp->delete_on_close = false;
492 set_delete_on_close_lck(fsp, lck, false, NULL);
505 * Do the notification after we released the share
506 * mode lock. Inside notify_fname we take out another
507 * tdb lock. With ctdb also accessing our databases,
508 * this can lead to deadlocks. Putting this notify
509 * after the TALLOC_FREE(lck) above we avoid locking
510 * two records simultaneously. Notifies are async and
511 * informational only, so calling the notify_fname
512 * without holding the share mode lock should not do
515 notify_fname(conn, NOTIFY_ACTION_REMOVED,
516 FILE_NOTIFY_CHANGE_FILE_NAME,
517 fsp->fsp_name->base_name);
523 void set_close_write_time(struct files_struct *fsp, struct timespec ts)
525 DEBUG(6,("close_write_time: %s" , time_to_asc(convert_timespec_to_time_t(ts))));
527 if (null_timespec(ts)) {
530 fsp->write_time_forced = false;
531 fsp->update_write_time_on_close = true;
532 fsp->close_write_time = ts;
535 static NTSTATUS update_write_time_on_close(struct files_struct *fsp)
537 struct smb_file_time ft;
539 struct share_mode_lock *lck = NULL;
543 if (!fsp->update_write_time_on_close) {
547 if (null_timespec(fsp->close_write_time)) {
548 fsp->close_write_time = timespec_current();
551 /* Ensure we have a valid stat struct for the source. */
552 status = vfs_stat_fsp(fsp);
553 if (!NT_STATUS_IS_OK(status)) {
557 if (!VALID_STAT(fsp->fsp_name->st)) {
558 /* if it doesn't seem to be a real file */
562 /* On close if we're changing the real file time we
563 * must update it in the open file db too. */
564 (void)set_write_time(fsp->file_id, fsp->close_write_time);
566 lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL, NULL);
568 /* Close write times overwrite sticky write times
569 so we must replace any sticky write time here. */
570 if (!null_timespec(lck->changed_write_time)) {
571 (void)set_sticky_write_time(fsp->file_id, fsp->close_write_time);
576 ft.mtime = fsp->close_write_time;
577 /* We must use NULL for the fsp handle here, as smb_set_file_time()
578 checks the fsp access_mask, which may not include FILE_WRITE_ATTRIBUTES.
579 As this is a close based update, we are not directly changing the
580 file attributes from a client call, but indirectly from a write. */
581 status = smb_set_file_time(fsp->conn, NULL, fsp->fsp_name, &ft, false);
582 if (!NT_STATUS_IS_OK(status)) {
583 DEBUG(10,("update_write_time_on_close: smb_set_file_time "
584 "on file %s returned %s\n",
593 static NTSTATUS ntstatus_keeperror(NTSTATUS s1, NTSTATUS s2)
595 if (!NT_STATUS_IS_OK(s1)) {
601 /****************************************************************************
604 close_type can be NORMAL_CLOSE=0,SHUTDOWN_CLOSE,ERROR_CLOSE.
605 printing and magic scripts are only run on normal close.
606 delete on close is done on normal and shutdown close.
607 ****************************************************************************/
609 static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp,
610 enum file_close_type close_type)
612 NTSTATUS status = NT_STATUS_OK;
614 connection_struct *conn = fsp->conn;
616 if (close_type == ERROR_CLOSE) {
617 cancel_aio_by_fsp(fsp);
620 * If we're finishing async io on a close we can get a write
621 * error here, we must remember this.
623 int ret = wait_for_aio_completion(fsp);
625 status = ntstatus_keeperror(
626 status, map_nt_error_from_unix(ret));
631 * If we're flushing on a close we can get a write
632 * error here, we must remember this.
635 tmp = close_filestruct(fsp);
636 status = ntstatus_keeperror(status, tmp);
638 if (fsp->print_file) {
639 /* FIXME: return spool errors */
640 print_spool_end(fsp, close_type);
645 /* Remove the oplock before potentially deleting the file. */
646 if(fsp->oplock_type) {
647 release_file_oplock(fsp);
650 /* If this is an old DOS or FCB open and we have multiple opens on
651 the same handle we only have one share mode. Ensure we only remove
652 the share mode on the last close. */
654 if (fsp->fh->ref_count == 1) {
655 /* Should we return on error here... ? */
656 tmp = close_remove_share_mode(fsp, close_type);
657 status = ntstatus_keeperror(status, tmp);
660 locking_close_file(conn->sconn->msg_ctx, fsp, close_type);
663 status = ntstatus_keeperror(status, tmp);
665 /* check for magic scripts */
666 if (close_type == NORMAL_CLOSE) {
667 tmp = check_magic(fsp);
668 status = ntstatus_keeperror(status, tmp);
672 * Ensure pending modtime is set after close.
675 tmp = update_write_time_on_close(fsp);
676 if (NT_STATUS_EQUAL(tmp, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
677 /* Someone renamed the file or a parent directory containing
678 * this file. We can't do anything about this, we don't have
679 * an "update timestamp by fd" call in POSIX. Eat the error. */
684 status = ntstatus_keeperror(status, tmp);
686 DEBUG(2,("%s closed file %s (numopen=%d) %s\n",
687 conn->session_info->unix_name, fsp_str_dbg(fsp),
688 conn->num_files_open - 1,
689 nt_errstr(status) ));
694 /****************************************************************************
695 Static function used by reply_rmdir to delete an entire directory
696 tree recursively. Return True on ok, False on fail.
697 ****************************************************************************/
699 static bool recursive_rmdir(TALLOC_CTX *ctx,
700 connection_struct *conn,
701 struct smb_filename *smb_dname)
703 const char *dname = NULL;
704 char *talloced = NULL;
708 struct smb_Dir *dir_hnd;
710 SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
712 dir_hnd = OpenDir(talloc_tos(), conn, smb_dname->base_name, NULL, 0);
716 while((dname = ReadDirName(dir_hnd, &offset, &st, &talloced))) {
717 struct smb_filename *smb_dname_full = NULL;
718 char *fullname = NULL;
719 bool do_break = true;
722 if (ISDOT(dname) || ISDOTDOT(dname)) {
723 TALLOC_FREE(talloced);
727 if (!is_visible_file(conn, smb_dname->base_name, dname, &st,
729 TALLOC_FREE(talloced);
733 /* Construct the full name. */
734 fullname = talloc_asprintf(ctx,
736 smb_dname->base_name,
743 status = create_synthetic_smb_fname(talloc_tos(), fullname,
746 if (!NT_STATUS_IS_OK(status)) {
750 if(SMB_VFS_LSTAT(conn, smb_dname_full) != 0) {
754 if(smb_dname_full->st.st_ex_mode & S_IFDIR) {
755 if(!recursive_rmdir(ctx, conn, smb_dname_full)) {
758 if(SMB_VFS_RMDIR(conn,
759 smb_dname_full->base_name) != 0) {
762 } else if(SMB_VFS_UNLINK(conn, smb_dname_full) != 0) {
766 /* Successful iteration. */
770 TALLOC_FREE(smb_dname_full);
771 TALLOC_FREE(fullname);
772 TALLOC_FREE(talloced);
778 TALLOC_FREE(dir_hnd);
782 /****************************************************************************
783 The internals of the rmdir code - called elsewhere.
784 ****************************************************************************/
786 static NTSTATUS rmdir_internals(TALLOC_CTX *ctx, files_struct *fsp)
788 connection_struct *conn = fsp->conn;
789 struct smb_filename *smb_dname = fsp->fsp_name;
792 SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
794 /* Might be a symlink. */
795 if(SMB_VFS_LSTAT(conn, smb_dname) != 0) {
796 return map_nt_error_from_unix(errno);
799 if (S_ISLNK(smb_dname->st.st_ex_mode)) {
800 /* Is what it points to a directory ? */
801 if(SMB_VFS_STAT(conn, smb_dname) != 0) {
802 return map_nt_error_from_unix(errno);
804 if (!(S_ISDIR(smb_dname->st.st_ex_mode))) {
805 return NT_STATUS_NOT_A_DIRECTORY;
807 ret = SMB_VFS_UNLINK(conn, smb_dname);
809 ret = SMB_VFS_RMDIR(conn, smb_dname->base_name);
812 notify_fname(conn, NOTIFY_ACTION_REMOVED,
813 FILE_NOTIFY_CHANGE_DIR_NAME,
814 smb_dname->base_name);
818 if(((errno == ENOTEMPTY)||(errno == EEXIST)) && lp_veto_files(SNUM(conn))) {
820 * Check to see if the only thing in this directory are
821 * vetoed files/directories. If so then delete them and
822 * retry. If we fail to delete any of them (and we *don't*
823 * do a recursive delete) then fail the rmdir.
826 const char *dname = NULL;
827 char *talloced = NULL;
829 struct smb_Dir *dir_hnd = OpenDir(talloc_tos(), conn,
830 smb_dname->base_name, NULL,
833 if(dir_hnd == NULL) {
838 while ((dname = ReadDirName(dir_hnd, &dirpos, &st,
839 &talloced)) != NULL) {
840 if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0)) {
841 TALLOC_FREE(talloced);
844 if (!is_visible_file(conn, smb_dname->base_name, dname,
846 TALLOC_FREE(talloced);
849 if(!IS_VETO_PATH(conn, dname)) {
850 TALLOC_FREE(dir_hnd);
851 TALLOC_FREE(talloced);
855 TALLOC_FREE(talloced);
858 /* We only have veto files/directories.
859 * Are we allowed to delete them ? */
861 if(!lp_recursive_veto_delete(SNUM(conn))) {
862 TALLOC_FREE(dir_hnd);
867 /* Do a recursive delete. */
868 RewindDir(dir_hnd,&dirpos);
869 while ((dname = ReadDirName(dir_hnd, &dirpos, &st,
870 &talloced)) != NULL) {
871 struct smb_filename *smb_dname_full = NULL;
872 char *fullname = NULL;
873 bool do_break = true;
876 if (ISDOT(dname) || ISDOTDOT(dname)) {
877 TALLOC_FREE(talloced);
880 if (!is_visible_file(conn, smb_dname->base_name, dname,
882 TALLOC_FREE(talloced);
886 fullname = talloc_asprintf(ctx,
888 smb_dname->base_name,
896 status = create_synthetic_smb_fname(talloc_tos(),
900 if (!NT_STATUS_IS_OK(status)) {
901 errno = map_errno_from_nt_status(status);
905 if(SMB_VFS_LSTAT(conn, smb_dname_full) != 0) {
908 if(smb_dname_full->st.st_ex_mode & S_IFDIR) {
909 if(!recursive_rmdir(ctx, conn,
913 if(SMB_VFS_RMDIR(conn,
914 smb_dname_full->base_name) != 0) {
917 } else if(SMB_VFS_UNLINK(conn, smb_dname_full) != 0) {
921 /* Successful iteration. */
925 TALLOC_FREE(fullname);
926 TALLOC_FREE(smb_dname_full);
927 TALLOC_FREE(talloced);
931 TALLOC_FREE(dir_hnd);
932 /* Retry the rmdir */
933 ret = SMB_VFS_RMDIR(conn, smb_dname->base_name);
939 DEBUG(3,("rmdir_internals: couldn't remove directory %s : "
940 "%s\n", smb_fname_str_dbg(smb_dname),
942 return map_nt_error_from_unix(errno);
945 notify_fname(conn, NOTIFY_ACTION_REMOVED,
946 FILE_NOTIFY_CHANGE_DIR_NAME,
947 smb_dname->base_name);
952 /****************************************************************************
953 Close a directory opened by an NT SMB call.
954 ****************************************************************************/
956 static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
957 enum file_close_type close_type)
959 struct share_mode_lock *lck = NULL;
960 bool delete_dir = False;
961 NTSTATUS status = NT_STATUS_OK;
962 NTSTATUS status1 = NT_STATUS_OK;
963 const struct security_unix_token *del_token = NULL;
966 * NT can set delete_on_close of the last open
967 * reference to a directory also.
970 lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL,
974 DEBUG(0, ("close_directory: Could not get share mode lock for "
975 "%s\n", fsp_str_dbg(fsp)));
976 status = NT_STATUS_INVALID_PARAMETER;
980 if (!del_share_mode(lck, fsp)) {
981 DEBUG(0, ("close_directory: Could not delete share entry for "
982 "%s\n", fsp_str_dbg(fsp)));
985 if (fsp->initial_delete_on_close) {
986 bool became_user = False;
988 /* Initial delete on close was set - for
989 * directories we don't care if anyone else
990 * wrote a real delete on close. */
992 if (get_current_vuid(fsp->conn) != fsp->vuid) {
993 become_user(fsp->conn, fsp->vuid);
996 send_stat_cache_delete_message(fsp->conn->sconn->msg_ctx,
997 fsp->fsp_name->base_name);
998 set_delete_on_close_lck(fsp, lck, true,
999 get_current_utok(fsp->conn));
1000 fsp->delete_on_close = true;
1006 del_token = get_delete_on_close_token(lck, fsp->name_hash);
1007 delete_dir = (del_token != NULL);
1011 /* See if others still have the dir open. If this is the
1012 * case, then don't delete. If all opens are POSIX delete now. */
1013 for (i=0; i<lck->num_share_modes; i++) {
1014 struct share_mode_entry *e = &lck->share_modes[i];
1015 if (is_valid_share_mode_entry(e) &&
1016 e->name_hash == fsp->name_hash) {
1017 if (fsp->posix_open && (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) {
1026 if ((close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) &&
1029 /* Become the user who requested the delete. */
1031 if (!push_sec_ctx()) {
1032 smb_panic("close_directory: failed to push sec_ctx.\n");
1035 set_sec_ctx(del_token->uid,
1043 status = rmdir_internals(talloc_tos(), fsp);
1045 DEBUG(5,("close_directory: %s. Delete on close was set - "
1046 "deleting directory returned %s.\n",
1047 fsp_str_dbg(fsp), nt_errstr(status)));
1049 /* unbecome user. */
1053 * Ensure we remove any change notify requests that would
1054 * now fail as the directory has been deleted.
1057 if(NT_STATUS_IS_OK(status)) {
1058 remove_pending_change_notify_requests_by_fid(fsp, NT_STATUS_DELETE_PENDING);
1062 remove_pending_change_notify_requests_by_fid(
1066 status1 = fd_close(fsp);
1068 if (!NT_STATUS_IS_OK(status1)) {
1069 DEBUG(0, ("Could not close dir! fname=%s, fd=%d, err=%d=%s\n",
1070 fsp_str_dbg(fsp), fsp->fh->fd, errno,
1075 * Do the code common to files and directories.
1077 close_filestruct(fsp);
1078 file_free(req, fsp);
1082 if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(status1)) {
1088 /****************************************************************************
1089 Close a files_struct.
1090 ****************************************************************************/
1092 NTSTATUS close_file(struct smb_request *req, files_struct *fsp,
1093 enum file_close_type close_type)
1096 struct files_struct *base_fsp = fsp->base_fsp;
1098 if(fsp->is_directory) {
1099 status = close_directory(req, fsp, close_type);
1100 } else if (fsp->fake_file_handle != NULL) {
1101 status = close_fake_file(req, fsp);
1103 status = close_normal_file(req, fsp, close_type);
1106 if ((base_fsp != NULL) && (close_type != SHUTDOWN_CLOSE)) {
1109 * fsp was a stream, the base fsp can't be a stream as well
1111 * For SHUTDOWN_CLOSE this is not possible here, because
1112 * SHUTDOWN_CLOSE only happens from files.c which walks the
1113 * complete list of files. If we mess with more than one fsp
1114 * those loops will become confused.
1117 SMB_ASSERT(base_fsp->base_fsp == NULL);
1118 close_file(req, base_fsp, close_type);
1124 /****************************************************************************
1125 Deal with an (authorized) message to close a file given the share mode
1127 ****************************************************************************/
1129 void msg_close_file(struct messaging_context *msg_ctx,
1132 struct server_id server_id,
1135 struct smbd_server_connection *sconn;
1136 files_struct *fsp = NULL;
1137 struct share_mode_entry e;
1139 sconn = msg_ctx_to_sconn(msg_ctx);
1140 if (sconn == NULL) {
1141 DEBUG(1, ("could not find sconn\n"));
1145 message_to_share_mode_entry(&e, (char *)data->data);
1148 char *sm_str = share_mode_str(NULL, 0, &e);
1150 smb_panic("talloc failed");
1152 DEBUG(10,("msg_close_file: got request to close share mode "
1153 "entry %s\n", sm_str));
1154 TALLOC_FREE(sm_str);
1157 fsp = file_find_dif(sconn, e.id, e.share_file_id);
1159 DEBUG(10,("msg_close_file: failed to find file.\n"));
1162 close_file(NULL, fsp, NORMAL_CLOSE);