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/smbd.h"
27 #include "smbd/globals.h"
28 #include "fake_file.h"
29 #include "transfer_file.h"
31 /****************************************************************************
32 Run a file if it is a magic script.
33 ****************************************************************************/
35 static NTSTATUS check_magic(struct files_struct *fsp)
38 const char *magic_output = NULL;
41 TALLOC_CTX *ctx = NULL;
43 struct connection_struct *conn = fsp->conn;
47 if (!*lp_magicscript(SNUM(conn))) {
51 DEBUG(5,("checking magic for %s\n", fsp_str_dbg(fsp)));
53 ctx = talloc_stackframe();
55 fname = fsp->fsp_name->base_name;
57 if (!(p = strrchr_m(fname,'/'))) {
63 if (!strequal(lp_magicscript(SNUM(conn)),p)) {
64 status = NT_STATUS_OK;
68 if (*lp_magicoutput(SNUM(conn))) {
69 magic_output = lp_magicoutput(SNUM(conn));
71 magic_output = talloc_asprintf(ctx,
76 status = NT_STATUS_NO_MEMORY;
80 /* Ensure we don't depend on user's PATH. */
81 p = talloc_asprintf(ctx, "./%s", fname);
83 status = NT_STATUS_NO_MEMORY;
87 if (chmod(fname, 0755) == -1) {
88 status = map_nt_error_from_unix(errno);
91 ret = smbrun(p,&tmp_fd);
92 DEBUG(3,("Invoking magic command %s gave %d\n",
96 if (ret != 0 || tmp_fd == -1) {
100 status = NT_STATUS_UNSUCCESSFUL;
103 outfd = open(magic_output, O_CREAT|O_EXCL|O_RDWR, 0600);
107 status = map_nt_error_from_unix(err);
111 if (sys_fstat(tmp_fd, &st, false) == -1) {
115 status = map_nt_error_from_unix(err);
119 if (transfer_file(tmp_fd,outfd,(SMB_OFF_T)st.st_ex_size) == (SMB_OFF_T)-1) {
123 status = map_nt_error_from_unix(err);
127 if (close(outfd) == -1) {
128 status = map_nt_error_from_unix(errno);
132 status = NT_STATUS_OK;
139 /****************************************************************************
140 Common code to close a file or a directory.
141 ****************************************************************************/
143 static NTSTATUS close_filestruct(files_struct *fsp)
145 NTSTATUS status = NT_STATUS_OK;
147 if (fsp->fh->fd != -1) {
148 if(flush_write_cache(fsp, CLOSE_FLUSH) == -1) {
149 status = map_nt_error_from_unix(errno);
151 delete_write_cache(fsp);
157 /****************************************************************************
158 If any deferred opens are waiting on this close, notify them.
159 ****************************************************************************/
161 static void notify_deferred_opens(struct messaging_context *msg_ctx,
162 struct share_mode_lock *lck)
166 if (!should_notify_deferred_opens()) {
170 for (i=0; i<lck->num_share_modes; i++) {
171 struct share_mode_entry *e = &lck->share_modes[i];
173 if (!is_deferred_open_entry(e)) {
177 if (procid_is_me(&e->pid)) {
179 * We need to notify ourself to retry the open. Do
180 * this by finding the queued SMB record, moving it to
181 * the head of the queue and changing the wait time to
184 schedule_deferred_open_message_smb(e->op_mid);
186 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
188 share_mode_entry_to_message(msg, e);
190 messaging_send_buf(msg_ctx, e->pid, MSG_SMB_OPEN_RETRY,
192 MSG_SMB_SHARE_MODE_ENTRY_SIZE);
197 /****************************************************************************
199 ****************************************************************************/
201 NTSTATUS delete_all_streams(connection_struct *conn, const char *fname)
203 struct stream_struct *stream_info;
205 unsigned int num_streams;
206 TALLOC_CTX *frame = talloc_stackframe();
209 status = SMB_VFS_STREAMINFO(conn, NULL, fname, talloc_tos(),
210 &num_streams, &stream_info);
212 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
213 DEBUG(10, ("no streams around\n"));
218 if (!NT_STATUS_IS_OK(status)) {
219 DEBUG(10, ("SMB_VFS_STREAMINFO failed: %s\n",
224 DEBUG(10, ("delete_all_streams found %d streams\n",
227 if (num_streams == 0) {
232 for (i=0; i<num_streams; i++) {
234 struct smb_filename *smb_fname_stream = NULL;
236 if (strequal(stream_info[i].name, "::$DATA")) {
240 status = create_synthetic_smb_fname(talloc_tos(), fname,
241 stream_info[i].name, NULL,
244 if (!NT_STATUS_IS_OK(status)) {
245 DEBUG(0, ("talloc_aprintf failed\n"));
249 res = SMB_VFS_UNLINK(conn, smb_fname_stream);
252 status = map_nt_error_from_unix(errno);
253 DEBUG(10, ("Could not delete stream %s: %s\n",
254 smb_fname_str_dbg(smb_fname_stream),
256 TALLOC_FREE(smb_fname_stream);
259 TALLOC_FREE(smb_fname_stream);
267 /****************************************************************************
268 Deal with removing a share mode on last close.
269 ****************************************************************************/
271 static NTSTATUS close_remove_share_mode(files_struct *fsp,
272 enum file_close_type close_type)
274 connection_struct *conn = fsp->conn;
275 bool delete_file = false;
276 bool changed_user = false;
277 struct share_mode_lock *lck = NULL;
278 NTSTATUS status = NT_STATUS_OK;
281 const struct security_unix_token *del_token = NULL;
283 /* Ensure any pending write time updates are done. */
284 if (fsp->update_write_time_event) {
285 update_write_time_handler(smbd_event_context(),
286 fsp->update_write_time_event,
292 * Lock the share entries, and determine if we should delete
293 * on close. If so delete whilst the lock is still in effect.
294 * This prevents race conditions with the file being created. JRA.
297 lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL,
301 DEBUG(0, ("close_remove_share_mode: Could not get share mode "
302 "lock for file %s\n", fsp_str_dbg(fsp)));
303 status = NT_STATUS_INVALID_PARAMETER;
307 if (fsp->write_time_forced) {
308 DEBUG(10,("close_remove_share_mode: write time forced "
311 set_close_write_time(fsp, lck->changed_write_time);
312 } else if (fsp->update_write_time_on_close) {
313 /* Someone had a pending write. */
314 if (null_timespec(fsp->close_write_time)) {
315 DEBUG(10,("close_remove_share_mode: update to current time "
318 /* Update to current time due to "normal" write. */
319 set_close_write_time(fsp, timespec_current());
321 DEBUG(10,("close_remove_share_mode: write time pending "
324 /* Update to time set on close call. */
325 set_close_write_time(fsp, fsp->close_write_time);
329 if (!del_share_mode(lck, fsp)) {
330 DEBUG(0, ("close_remove_share_mode: Could not delete share "
331 "entry for file %s\n",
335 if (fsp->initial_delete_on_close &&
336 !is_delete_on_close_set(lck, fsp->name_hash)) {
337 bool became_user = False;
339 /* Initial delete on close was set and no one else
340 * wrote a real delete on close. */
342 if (get_current_vuid(conn) != fsp->vuid) {
343 become_user(conn, fsp->vuid);
346 fsp->delete_on_close = true;
347 set_delete_on_close_lck(fsp, lck, True, get_current_utok(conn));
353 delete_file = is_delete_on_close_set(lck, fsp->name_hash);
357 /* See if others still have the file open via this pathname.
358 If this is the case, then don't delete. If all opens are
360 for (i=0; i<lck->num_share_modes; i++) {
361 struct share_mode_entry *e = &lck->share_modes[i];
362 if (is_valid_share_mode_entry(e) &&
363 e->name_hash == fsp->name_hash) {
364 if (fsp->posix_open && (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) {
373 /* Notify any deferred opens waiting on this close. */
374 notify_deferred_opens(conn->sconn->msg_ctx, lck);
375 reply_to_oplock_break_requests(fsp);
378 * NT can set delete_on_close of the last open
379 * reference to a file.
382 if (!(close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) ||
389 * Ok, we have to delete the file
392 DEBUG(5,("close_remove_share_mode: file %s. Delete on close was set "
393 "- deleting file.\n", fsp_str_dbg(fsp)));
396 * Don't try to update the write time when we delete the file
398 fsp->update_write_time_on_close = false;
400 del_token = get_delete_on_close_token(lck, fsp->name_hash);
401 SMB_ASSERT(del_token != NULL);
403 if (!unix_token_equal(del_token, get_current_utok(conn))) {
404 /* Become the user who requested the delete. */
406 DEBUG(5,("close_remove_share_mode: file %s. "
407 "Change user to uid %u\n",
409 (unsigned int)del_token->uid));
411 if (!push_sec_ctx()) {
412 smb_panic("close_remove_share_mode: file %s. failed to push "
416 set_sec_ctx(del_token->uid,
425 /* We can only delete the file if the name we have is still valid and
426 hasn't been renamed. */
428 tmp_status = vfs_stat_fsp(fsp);
429 if (!NT_STATUS_IS_OK(tmp_status)) {
430 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
431 "was set and stat failed with error %s\n",
432 fsp_str_dbg(fsp), nt_errstr(tmp_status)));
434 * Don't save the errno here, we ignore this error
439 id = vfs_file_id_from_sbuf(conn, &fsp->fsp_name->st);
441 if (!file_id_equal(&fsp->file_id, &id)) {
442 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
443 "was set and dev and/or inode does not match\n",
445 DEBUG(5,("close_remove_share_mode: file %s. stored file_id %s, "
448 file_id_string_tos(&fsp->file_id),
449 file_id_string_tos(&id)));
451 * Don't save the errno here, we ignore this error
456 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
457 && !is_ntfs_stream_smb_fname(fsp->fsp_name)) {
459 status = delete_all_streams(conn, fsp->fsp_name->base_name);
461 if (!NT_STATUS_IS_OK(status)) {
462 DEBUG(5, ("delete_all_streams failed: %s\n",
469 if (SMB_VFS_UNLINK(conn, fsp->fsp_name) != 0) {
471 * This call can potentially fail as another smbd may
472 * have had the file open with delete on close set and
473 * deleted it when its last reference to this file
474 * went away. Hence we log this but not at debug level
478 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
479 "was set and unlink failed with error %s\n",
480 fsp_str_dbg(fsp), strerror(errno)));
482 status = map_nt_error_from_unix(errno);
485 /* As we now have POSIX opens which can unlink
486 * with other open files we may have taken
487 * this code path with more than one share mode
488 * entry - ensure we only delete once by resetting
489 * the delete on close flag. JRA.
492 fsp->delete_on_close = false;
493 set_delete_on_close_lck(fsp, lck, false, NULL);
506 * Do the notification after we released the share
507 * mode lock. Inside notify_fname we take out another
508 * tdb lock. With ctdb also accessing our databases,
509 * this can lead to deadlocks. Putting this notify
510 * after the TALLOC_FREE(lck) above we avoid locking
511 * two records simultaneously. Notifies are async and
512 * informational only, so calling the notify_fname
513 * without holding the share mode lock should not do
516 notify_fname(conn, NOTIFY_ACTION_REMOVED,
517 FILE_NOTIFY_CHANGE_FILE_NAME,
518 fsp->fsp_name->base_name);
524 void set_close_write_time(struct files_struct *fsp, struct timespec ts)
526 DEBUG(6,("close_write_time: %s" , time_to_asc(convert_timespec_to_time_t(ts))));
528 if (null_timespec(ts)) {
531 fsp->write_time_forced = false;
532 fsp->update_write_time_on_close = true;
533 fsp->close_write_time = ts;
536 static NTSTATUS update_write_time_on_close(struct files_struct *fsp)
538 struct smb_file_time ft;
540 struct share_mode_lock *lck = NULL;
544 if (!fsp->update_write_time_on_close) {
548 if (null_timespec(fsp->close_write_time)) {
549 fsp->close_write_time = timespec_current();
552 /* Ensure we have a valid stat struct for the source. */
553 status = vfs_stat_fsp(fsp);
554 if (!NT_STATUS_IS_OK(status)) {
558 if (!VALID_STAT(fsp->fsp_name->st)) {
559 /* if it doesn't seem to be a real file */
563 /* On close if we're changing the real file time we
564 * must update it in the open file db too. */
565 (void)set_write_time(fsp->file_id, fsp->close_write_time);
567 lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL, NULL);
569 /* Close write times overwrite sticky write times
570 so we must replace any sticky write time here. */
571 if (!null_timespec(lck->changed_write_time)) {
572 (void)set_sticky_write_time(fsp->file_id, fsp->close_write_time);
577 ft.mtime = fsp->close_write_time;
578 /* We must use NULL for the fsp handle here, as smb_set_file_time()
579 checks the fsp access_mask, which may not include FILE_WRITE_ATTRIBUTES.
580 As this is a close based update, we are not directly changing the
581 file attributes from a client call, but indirectly from a write. */
582 status = smb_set_file_time(fsp->conn, NULL, fsp->fsp_name, &ft, false);
583 if (!NT_STATUS_IS_OK(status)) {
584 DEBUG(10,("update_write_time_on_close: smb_set_file_time "
585 "on file %s returned %s\n",
594 static NTSTATUS ntstatus_keeperror(NTSTATUS s1, NTSTATUS s2)
596 if (!NT_STATUS_IS_OK(s1)) {
602 /****************************************************************************
605 close_type can be NORMAL_CLOSE=0,SHUTDOWN_CLOSE,ERROR_CLOSE.
606 printing and magic scripts are only run on normal close.
607 delete on close is done on normal and shutdown close.
608 ****************************************************************************/
610 static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp,
611 enum file_close_type close_type)
613 NTSTATUS status = NT_STATUS_OK;
615 connection_struct *conn = fsp->conn;
617 if (close_type == ERROR_CLOSE) {
618 cancel_aio_by_fsp(fsp);
621 * If we're finishing async io on a close we can get a write
622 * error here, we must remember this.
624 int ret = wait_for_aio_completion(fsp);
626 status = ntstatus_keeperror(
627 status, map_nt_error_from_unix(ret));
632 * If we're flushing on a close we can get a write
633 * error here, we must remember this.
636 tmp = close_filestruct(fsp);
637 status = ntstatus_keeperror(status, tmp);
639 if (fsp->print_file) {
640 /* FIXME: return spool errors */
641 print_spool_end(fsp, close_type);
646 /* Remove the oplock before potentially deleting the file. */
647 if(fsp->oplock_type) {
648 release_file_oplock(fsp);
651 /* If this is an old DOS or FCB open and we have multiple opens on
652 the same handle we only have one share mode. Ensure we only remove
653 the share mode on the last close. */
655 if (fsp->fh->ref_count == 1) {
656 /* Should we return on error here... ? */
657 tmp = close_remove_share_mode(fsp, close_type);
658 status = ntstatus_keeperror(status, tmp);
661 locking_close_file(conn->sconn->msg_ctx, fsp, close_type);
664 status = ntstatus_keeperror(status, tmp);
666 /* check for magic scripts */
667 if (close_type == NORMAL_CLOSE) {
668 tmp = check_magic(fsp);
669 status = ntstatus_keeperror(status, tmp);
673 * Ensure pending modtime is set after close.
676 tmp = update_write_time_on_close(fsp);
677 if (NT_STATUS_EQUAL(tmp, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
678 /* Someone renamed the file or a parent directory containing
679 * this file. We can't do anything about this, we don't have
680 * an "update timestamp by fd" call in POSIX. Eat the error. */
685 status = ntstatus_keeperror(status, tmp);
687 DEBUG(2,("%s closed file %s (numopen=%d) %s\n",
688 conn->session_info->unix_name, fsp_str_dbg(fsp),
689 conn->num_files_open - 1,
690 nt_errstr(status) ));
695 /****************************************************************************
696 Static function used by reply_rmdir to delete an entire directory
697 tree recursively. Return True on ok, False on fail.
698 ****************************************************************************/
700 static bool recursive_rmdir(TALLOC_CTX *ctx,
701 connection_struct *conn,
702 struct smb_filename *smb_dname)
704 const char *dname = NULL;
705 char *talloced = NULL;
709 struct smb_Dir *dir_hnd;
711 SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
713 dir_hnd = OpenDir(talloc_tos(), conn, smb_dname->base_name, NULL, 0);
717 while((dname = ReadDirName(dir_hnd, &offset, &st, &talloced))) {
718 struct smb_filename *smb_dname_full = NULL;
719 char *fullname = NULL;
720 bool do_break = true;
723 if (ISDOT(dname) || ISDOTDOT(dname)) {
724 TALLOC_FREE(talloced);
728 if (!is_visible_file(conn, smb_dname->base_name, dname, &st,
730 TALLOC_FREE(talloced);
734 /* Construct the full name. */
735 fullname = talloc_asprintf(ctx,
737 smb_dname->base_name,
744 status = create_synthetic_smb_fname(talloc_tos(), fullname,
747 if (!NT_STATUS_IS_OK(status)) {
751 if(SMB_VFS_LSTAT(conn, smb_dname_full) != 0) {
755 if(smb_dname_full->st.st_ex_mode & S_IFDIR) {
756 if(!recursive_rmdir(ctx, conn, smb_dname_full)) {
759 if(SMB_VFS_RMDIR(conn,
760 smb_dname_full->base_name) != 0) {
763 } else if(SMB_VFS_UNLINK(conn, smb_dname_full) != 0) {
767 /* Successful iteration. */
771 TALLOC_FREE(smb_dname_full);
772 TALLOC_FREE(fullname);
773 TALLOC_FREE(talloced);
779 TALLOC_FREE(dir_hnd);
783 /****************************************************************************
784 The internals of the rmdir code - called elsewhere.
785 ****************************************************************************/
787 static NTSTATUS rmdir_internals(TALLOC_CTX *ctx, files_struct *fsp)
789 connection_struct *conn = fsp->conn;
790 struct smb_filename *smb_dname = fsp->fsp_name;
793 SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
795 /* Might be a symlink. */
796 if(SMB_VFS_LSTAT(conn, smb_dname) != 0) {
797 return map_nt_error_from_unix(errno);
800 if (S_ISLNK(smb_dname->st.st_ex_mode)) {
801 /* Is what it points to a directory ? */
802 if(SMB_VFS_STAT(conn, smb_dname) != 0) {
803 return map_nt_error_from_unix(errno);
805 if (!(S_ISDIR(smb_dname->st.st_ex_mode))) {
806 return NT_STATUS_NOT_A_DIRECTORY;
808 ret = SMB_VFS_UNLINK(conn, smb_dname);
810 ret = SMB_VFS_RMDIR(conn, smb_dname->base_name);
813 notify_fname(conn, NOTIFY_ACTION_REMOVED,
814 FILE_NOTIFY_CHANGE_DIR_NAME,
815 smb_dname->base_name);
819 if(((errno == ENOTEMPTY)||(errno == EEXIST)) && lp_veto_files(SNUM(conn))) {
821 * Check to see if the only thing in this directory are
822 * vetoed files/directories. If so then delete them and
823 * retry. If we fail to delete any of them (and we *don't*
824 * do a recursive delete) then fail the rmdir.
827 const char *dname = NULL;
828 char *talloced = NULL;
830 struct smb_Dir *dir_hnd = OpenDir(talloc_tos(), conn,
831 smb_dname->base_name, NULL,
834 if(dir_hnd == NULL) {
839 while ((dname = ReadDirName(dir_hnd, &dirpos, &st,
840 &talloced)) != NULL) {
841 if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0)) {
842 TALLOC_FREE(talloced);
845 if (!is_visible_file(conn, smb_dname->base_name, dname,
847 TALLOC_FREE(talloced);
850 if(!IS_VETO_PATH(conn, dname)) {
851 TALLOC_FREE(dir_hnd);
852 TALLOC_FREE(talloced);
856 TALLOC_FREE(talloced);
859 /* We only have veto files/directories.
860 * Are we allowed to delete them ? */
862 if(!lp_recursive_veto_delete(SNUM(conn))) {
863 TALLOC_FREE(dir_hnd);
868 /* Do a recursive delete. */
869 RewindDir(dir_hnd,&dirpos);
870 while ((dname = ReadDirName(dir_hnd, &dirpos, &st,
871 &talloced)) != NULL) {
872 struct smb_filename *smb_dname_full = NULL;
873 char *fullname = NULL;
874 bool do_break = true;
877 if (ISDOT(dname) || ISDOTDOT(dname)) {
878 TALLOC_FREE(talloced);
881 if (!is_visible_file(conn, smb_dname->base_name, dname,
883 TALLOC_FREE(talloced);
887 fullname = talloc_asprintf(ctx,
889 smb_dname->base_name,
897 status = create_synthetic_smb_fname(talloc_tos(),
901 if (!NT_STATUS_IS_OK(status)) {
902 errno = map_errno_from_nt_status(status);
906 if(SMB_VFS_LSTAT(conn, smb_dname_full) != 0) {
909 if(smb_dname_full->st.st_ex_mode & S_IFDIR) {
910 if(!recursive_rmdir(ctx, conn,
914 if(SMB_VFS_RMDIR(conn,
915 smb_dname_full->base_name) != 0) {
918 } else if(SMB_VFS_UNLINK(conn, smb_dname_full) != 0) {
922 /* Successful iteration. */
926 TALLOC_FREE(fullname);
927 TALLOC_FREE(smb_dname_full);
928 TALLOC_FREE(talloced);
932 TALLOC_FREE(dir_hnd);
933 /* Retry the rmdir */
934 ret = SMB_VFS_RMDIR(conn, smb_dname->base_name);
940 DEBUG(3,("rmdir_internals: couldn't remove directory %s : "
941 "%s\n", smb_fname_str_dbg(smb_dname),
943 return map_nt_error_from_unix(errno);
946 notify_fname(conn, NOTIFY_ACTION_REMOVED,
947 FILE_NOTIFY_CHANGE_DIR_NAME,
948 smb_dname->base_name);
953 /****************************************************************************
954 Close a directory opened by an NT SMB call.
955 ****************************************************************************/
957 static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
958 enum file_close_type close_type)
960 struct share_mode_lock *lck = NULL;
961 bool delete_dir = False;
962 NTSTATUS status = NT_STATUS_OK;
963 NTSTATUS status1 = NT_STATUS_OK;
964 const struct security_unix_token *del_token = NULL;
967 * NT can set delete_on_close of the last open
968 * reference to a directory also.
971 lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL,
975 DEBUG(0, ("close_directory: Could not get share mode lock for "
976 "%s\n", fsp_str_dbg(fsp)));
977 status = NT_STATUS_INVALID_PARAMETER;
981 if (!del_share_mode(lck, fsp)) {
982 DEBUG(0, ("close_directory: Could not delete share entry for "
983 "%s\n", fsp_str_dbg(fsp)));
986 if (fsp->initial_delete_on_close) {
987 bool became_user = False;
989 /* Initial delete on close was set - for
990 * directories we don't care if anyone else
991 * wrote a real delete on close. */
993 if (get_current_vuid(fsp->conn) != fsp->vuid) {
994 become_user(fsp->conn, fsp->vuid);
997 send_stat_cache_delete_message(fsp->conn->sconn->msg_ctx,
998 fsp->fsp_name->base_name);
999 set_delete_on_close_lck(fsp, lck, true,
1000 get_current_utok(fsp->conn));
1001 fsp->delete_on_close = true;
1007 del_token = get_delete_on_close_token(lck, fsp->name_hash);
1008 delete_dir = (del_token != NULL);
1012 /* See if others still have the dir open. If this is the
1013 * case, then don't delete. If all opens are POSIX delete now. */
1014 for (i=0; i<lck->num_share_modes; i++) {
1015 struct share_mode_entry *e = &lck->share_modes[i];
1016 if (is_valid_share_mode_entry(e) &&
1017 e->name_hash == fsp->name_hash) {
1018 if (fsp->posix_open && (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) {
1027 if ((close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) &&
1030 /* Become the user who requested the delete. */
1032 if (!push_sec_ctx()) {
1033 smb_panic("close_directory: failed to push sec_ctx.\n");
1036 set_sec_ctx(del_token->uid,
1044 status = rmdir_internals(talloc_tos(), fsp);
1046 DEBUG(5,("close_directory: %s. Delete on close was set - "
1047 "deleting directory returned %s.\n",
1048 fsp_str_dbg(fsp), nt_errstr(status)));
1050 /* unbecome user. */
1054 * Ensure we remove any change notify requests that would
1055 * now fail as the directory has been deleted.
1058 if(NT_STATUS_IS_OK(status)) {
1059 remove_pending_change_notify_requests_by_fid(fsp, NT_STATUS_DELETE_PENDING);
1063 remove_pending_change_notify_requests_by_fid(
1067 status1 = fd_close(fsp);
1069 if (!NT_STATUS_IS_OK(status1)) {
1070 DEBUG(0, ("Could not close dir! fname=%s, fd=%d, err=%d=%s\n",
1071 fsp_str_dbg(fsp), fsp->fh->fd, errno,
1076 * Do the code common to files and directories.
1078 close_filestruct(fsp);
1079 file_free(req, fsp);
1083 if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(status1)) {
1089 /****************************************************************************
1090 Close a files_struct.
1091 ****************************************************************************/
1093 NTSTATUS close_file(struct smb_request *req, files_struct *fsp,
1094 enum file_close_type close_type)
1097 struct files_struct *base_fsp = fsp->base_fsp;
1099 if(fsp->is_directory) {
1100 status = close_directory(req, fsp, close_type);
1101 } else if (fsp->fake_file_handle != NULL) {
1102 status = close_fake_file(req, fsp);
1104 status = close_normal_file(req, fsp, close_type);
1107 if ((base_fsp != NULL) && (close_type != SHUTDOWN_CLOSE)) {
1110 * fsp was a stream, the base fsp can't be a stream as well
1112 * For SHUTDOWN_CLOSE this is not possible here, because
1113 * SHUTDOWN_CLOSE only happens from files.c which walks the
1114 * complete list of files. If we mess with more than one fsp
1115 * those loops will become confused.
1118 SMB_ASSERT(base_fsp->base_fsp == NULL);
1119 close_file(req, base_fsp, close_type);
1125 /****************************************************************************
1126 Deal with an (authorized) message to close a file given the share mode
1128 ****************************************************************************/
1130 void msg_close_file(struct messaging_context *msg_ctx,
1133 struct server_id server_id,
1136 struct smbd_server_connection *sconn;
1137 files_struct *fsp = NULL;
1138 struct share_mode_entry e;
1140 sconn = msg_ctx_to_sconn(msg_ctx);
1141 if (sconn == NULL) {
1142 DEBUG(1, ("could not find sconn\n"));
1146 message_to_share_mode_entry(&e, (char *)data->data);
1149 char *sm_str = share_mode_str(NULL, 0, &e);
1151 smb_panic("talloc failed");
1153 DEBUG(10,("msg_close_file: got request to close share mode "
1154 "entry %s\n", sm_str));
1155 TALLOC_FREE(sm_str);
1158 fsp = file_find_dif(sconn, e.id, e.share_file_id);
1160 DEBUG(10,("msg_close_file: failed to find file.\n"));
1163 close_file(NULL, fsp, NORMAL_CLOSE);