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"
31 #include "../librpc/gen_ndr/open_files.h"
33 /****************************************************************************
34 Run a file if it is a magic script.
35 ****************************************************************************/
37 static NTSTATUS check_magic(struct files_struct *fsp)
40 const char *magic_output = NULL;
43 TALLOC_CTX *ctx = NULL;
45 struct connection_struct *conn = fsp->conn;
49 if (!*lp_magicscript(SNUM(conn))) {
53 DEBUG(5,("checking magic for %s\n", fsp_str_dbg(fsp)));
55 ctx = talloc_stackframe();
57 fname = fsp->fsp_name->base_name;
59 if (!(p = strrchr_m(fname,'/'))) {
65 if (!strequal(lp_magicscript(SNUM(conn)),p)) {
66 status = NT_STATUS_OK;
70 if (*lp_magicoutput(SNUM(conn))) {
71 magic_output = lp_magicoutput(SNUM(conn));
73 magic_output = talloc_asprintf(ctx,
78 status = NT_STATUS_NO_MEMORY;
82 /* Ensure we don't depend on user's PATH. */
83 p = talloc_asprintf(ctx, "./%s", fname);
85 status = NT_STATUS_NO_MEMORY;
89 if (chmod(fname, 0755) == -1) {
90 status = map_nt_error_from_unix(errno);
93 ret = smbrun(p,&tmp_fd);
94 DEBUG(3,("Invoking magic command %s gave %d\n",
98 if (ret != 0 || tmp_fd == -1) {
102 status = NT_STATUS_UNSUCCESSFUL;
105 outfd = open(magic_output, O_CREAT|O_EXCL|O_RDWR, 0600);
109 status = map_nt_error_from_unix(err);
113 if (sys_fstat(tmp_fd, &st, false) == -1) {
117 status = map_nt_error_from_unix(err);
121 if (transfer_file(tmp_fd,outfd,(SMB_OFF_T)st.st_ex_size) == (SMB_OFF_T)-1) {
125 status = map_nt_error_from_unix(err);
129 if (close(outfd) == -1) {
130 status = map_nt_error_from_unix(errno);
134 status = NT_STATUS_OK;
141 /****************************************************************************
142 Common code to close a file or a directory.
143 ****************************************************************************/
145 static NTSTATUS close_filestruct(files_struct *fsp)
147 NTSTATUS status = NT_STATUS_OK;
149 if (fsp->fh->fd != -1) {
150 if(flush_write_cache(fsp, CLOSE_FLUSH) == -1) {
151 status = map_nt_error_from_unix(errno);
153 delete_write_cache(fsp);
159 /****************************************************************************
160 If any deferred opens are waiting on this close, notify them.
161 ****************************************************************************/
163 static void notify_deferred_opens(struct messaging_context *msg_ctx,
164 struct share_mode_lock *lck)
168 if (!should_notify_deferred_opens()) {
172 for (i=0; i<lck->num_share_modes; i++) {
173 struct share_mode_entry *e = &lck->share_modes[i];
175 if (!is_deferred_open_entry(e)) {
179 if (procid_is_me(&e->pid)) {
180 struct smbd_server_connection *sconn;
182 * We need to notify ourself to retry the open. Do
183 * this by finding the queued SMB record, moving it to
184 * the head of the queue and changing the wait time to
187 sconn = msg_ctx_to_sconn(msg_ctx);
189 schedule_deferred_open_message_smb(
193 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
195 share_mode_entry_to_message(msg, e);
197 messaging_send_buf(msg_ctx, e->pid, MSG_SMB_OPEN_RETRY,
199 MSG_SMB_SHARE_MODE_ENTRY_SIZE);
204 /****************************************************************************
206 ****************************************************************************/
208 NTSTATUS delete_all_streams(connection_struct *conn, const char *fname)
210 struct stream_struct *stream_info = NULL;
212 unsigned int num_streams = 0;
213 TALLOC_CTX *frame = talloc_stackframe();
216 status = vfs_streaminfo(conn, NULL, fname, talloc_tos(),
217 &num_streams, &stream_info);
219 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
220 DEBUG(10, ("no streams around\n"));
225 if (!NT_STATUS_IS_OK(status)) {
226 DEBUG(10, ("vfs_streaminfo failed: %s\n",
231 DEBUG(10, ("delete_all_streams found %d streams\n",
234 if (num_streams == 0) {
239 for (i=0; i<num_streams; i++) {
241 struct smb_filename *smb_fname_stream = NULL;
243 if (strequal(stream_info[i].name, "::$DATA")) {
247 status = create_synthetic_smb_fname(talloc_tos(), fname,
248 stream_info[i].name, NULL,
251 if (!NT_STATUS_IS_OK(status)) {
252 DEBUG(0, ("talloc_aprintf failed\n"));
256 res = SMB_VFS_UNLINK(conn, smb_fname_stream);
259 status = map_nt_error_from_unix(errno);
260 DEBUG(10, ("Could not delete stream %s: %s\n",
261 smb_fname_str_dbg(smb_fname_stream),
263 TALLOC_FREE(smb_fname_stream);
266 TALLOC_FREE(smb_fname_stream);
274 /****************************************************************************
275 Deal with removing a share mode on last close.
276 ****************************************************************************/
278 static NTSTATUS close_remove_share_mode(files_struct *fsp,
279 enum file_close_type close_type)
281 connection_struct *conn = fsp->conn;
282 bool delete_file = false;
283 bool changed_user = false;
284 struct share_mode_lock *lck = NULL;
285 NTSTATUS status = NT_STATUS_OK;
288 const struct security_unix_token *del_token = NULL;
290 /* Ensure any pending write time updates are done. */
291 if (fsp->update_write_time_event) {
292 update_write_time_handler(fsp->conn->sconn->ev_ctx,
293 fsp->update_write_time_event,
299 * Lock the share entries, and determine if we should delete
300 * on close. If so delete whilst the lock is still in effect.
301 * This prevents race conditions with the file being created. JRA.
304 lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL,
308 DEBUG(0, ("close_remove_share_mode: Could not get share mode "
309 "lock for file %s\n", fsp_str_dbg(fsp)));
310 status = NT_STATUS_INVALID_PARAMETER;
314 if (fsp->write_time_forced) {
315 DEBUG(10,("close_remove_share_mode: write time forced "
318 set_close_write_time(fsp, lck->changed_write_time);
319 } else if (fsp->update_write_time_on_close) {
320 /* Someone had a pending write. */
321 if (null_timespec(fsp->close_write_time)) {
322 DEBUG(10,("close_remove_share_mode: update to current time "
325 /* Update to current time due to "normal" write. */
326 set_close_write_time(fsp, timespec_current());
328 DEBUG(10,("close_remove_share_mode: write time pending "
331 /* Update to time set on close call. */
332 set_close_write_time(fsp, fsp->close_write_time);
336 if (!del_share_mode(lck, fsp)) {
337 DEBUG(0, ("close_remove_share_mode: Could not delete share "
338 "entry for file %s\n",
342 if (fsp->initial_delete_on_close &&
343 !is_delete_on_close_set(lck, fsp->name_hash)) {
344 bool became_user = False;
346 /* Initial delete on close was set and no one else
347 * wrote a real delete on close. */
349 if (get_current_vuid(conn) != fsp->vuid) {
350 become_user(conn, fsp->vuid);
353 fsp->delete_on_close = true;
354 set_delete_on_close_lck(fsp, lck, True, get_current_utok(conn));
360 delete_file = is_delete_on_close_set(lck, fsp->name_hash);
364 /* See if others still have the file open via this pathname.
365 If this is the case, then don't delete. If all opens are
367 for (i=0; i<lck->num_share_modes; i++) {
368 struct share_mode_entry *e = &lck->share_modes[i];
369 if (is_valid_share_mode_entry(e) &&
370 e->name_hash == fsp->name_hash) {
371 if (fsp->posix_open && (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) {
380 /* Notify any deferred opens waiting on this close. */
381 notify_deferred_opens(conn->sconn->msg_ctx, lck);
382 reply_to_oplock_break_requests(fsp);
385 * NT can set delete_on_close of the last open
386 * reference to a file.
389 if (!(close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) ||
396 * Ok, we have to delete the file
399 DEBUG(5,("close_remove_share_mode: file %s. Delete on close was set "
400 "- deleting file.\n", fsp_str_dbg(fsp)));
403 * Don't try to update the write time when we delete the file
405 fsp->update_write_time_on_close = false;
407 del_token = get_delete_on_close_token(lck, fsp->name_hash);
408 SMB_ASSERT(del_token != NULL);
410 if (!unix_token_equal(del_token, get_current_utok(conn))) {
411 /* Become the user who requested the delete. */
413 DEBUG(5,("close_remove_share_mode: file %s. "
414 "Change user to uid %u\n",
416 (unsigned int)del_token->uid));
418 if (!push_sec_ctx()) {
419 smb_panic("close_remove_share_mode: file %s. failed to push "
423 set_sec_ctx(del_token->uid,
432 /* We can only delete the file if the name we have is still valid and
433 hasn't been renamed. */
435 tmp_status = vfs_stat_fsp(fsp);
436 if (!NT_STATUS_IS_OK(tmp_status)) {
437 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
438 "was set and stat failed with error %s\n",
439 fsp_str_dbg(fsp), nt_errstr(tmp_status)));
441 * Don't save the errno here, we ignore this error
446 id = vfs_file_id_from_sbuf(conn, &fsp->fsp_name->st);
448 if (!file_id_equal(&fsp->file_id, &id)) {
449 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
450 "was set and dev and/or inode does not match\n",
452 DEBUG(5,("close_remove_share_mode: file %s. stored file_id %s, "
455 file_id_string_tos(&fsp->file_id),
456 file_id_string_tos(&id)));
458 * Don't save the errno here, we ignore this error
463 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
464 && !is_ntfs_stream_smb_fname(fsp->fsp_name)) {
466 status = delete_all_streams(conn, fsp->fsp_name->base_name);
468 if (!NT_STATUS_IS_OK(status)) {
469 DEBUG(5, ("delete_all_streams failed: %s\n",
476 if (SMB_VFS_UNLINK(conn, fsp->fsp_name) != 0) {
478 * This call can potentially fail as another smbd may
479 * have had the file open with delete on close set and
480 * deleted it when its last reference to this file
481 * went away. Hence we log this but not at debug level
485 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
486 "was set and unlink failed with error %s\n",
487 fsp_str_dbg(fsp), strerror(errno)));
489 status = map_nt_error_from_unix(errno);
492 /* As we now have POSIX opens which can unlink
493 * with other open files we may have taken
494 * this code path with more than one share mode
495 * entry - ensure we only delete once by resetting
496 * the delete on close flag. JRA.
499 fsp->delete_on_close = false;
500 set_delete_on_close_lck(fsp, lck, false, NULL);
513 * Do the notification after we released the share
514 * mode lock. Inside notify_fname we take out another
515 * tdb lock. With ctdb also accessing our databases,
516 * this can lead to deadlocks. Putting this notify
517 * after the TALLOC_FREE(lck) above we avoid locking
518 * two records simultaneously. Notifies are async and
519 * informational only, so calling the notify_fname
520 * without holding the share mode lock should not do
523 notify_fname(conn, NOTIFY_ACTION_REMOVED,
524 FILE_NOTIFY_CHANGE_FILE_NAME,
525 fsp->fsp_name->base_name);
531 void set_close_write_time(struct files_struct *fsp, struct timespec ts)
533 DEBUG(6,("close_write_time: %s" , time_to_asc(convert_timespec_to_time_t(ts))));
535 if (null_timespec(ts)) {
538 fsp->write_time_forced = false;
539 fsp->update_write_time_on_close = true;
540 fsp->close_write_time = ts;
543 static NTSTATUS update_write_time_on_close(struct files_struct *fsp)
545 struct smb_file_time ft;
547 struct share_mode_lock *lck = NULL;
551 if (!fsp->update_write_time_on_close) {
555 if (null_timespec(fsp->close_write_time)) {
556 fsp->close_write_time = timespec_current();
559 /* Ensure we have a valid stat struct for the source. */
560 status = vfs_stat_fsp(fsp);
561 if (!NT_STATUS_IS_OK(status)) {
565 if (!VALID_STAT(fsp->fsp_name->st)) {
566 /* if it doesn't seem to be a real file */
570 /* On close if we're changing the real file time we
571 * must update it in the open file db too. */
572 (void)set_write_time(fsp->file_id, fsp->close_write_time);
574 lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL, NULL);
576 /* Close write times overwrite sticky write times
577 so we must replace any sticky write time here. */
578 if (!null_timespec(lck->changed_write_time)) {
579 (void)set_sticky_write_time(fsp->file_id, fsp->close_write_time);
584 ft.mtime = fsp->close_write_time;
585 /* As this is a close based update, we are not directly changing the
586 file attributes from a client call, but indirectly from a write. */
587 status = smb_set_file_time(fsp->conn, fsp, fsp->fsp_name, &ft, false);
588 if (!NT_STATUS_IS_OK(status)) {
589 DEBUG(10,("update_write_time_on_close: smb_set_file_time "
590 "on file %s returned %s\n",
599 static NTSTATUS ntstatus_keeperror(NTSTATUS s1, NTSTATUS s2)
601 if (!NT_STATUS_IS_OK(s1)) {
607 /****************************************************************************
610 close_type can be NORMAL_CLOSE=0,SHUTDOWN_CLOSE,ERROR_CLOSE.
611 printing and magic scripts are only run on normal close.
612 delete on close is done on normal and shutdown close.
613 ****************************************************************************/
615 static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp,
616 enum file_close_type close_type)
618 NTSTATUS status = NT_STATUS_OK;
620 connection_struct *conn = fsp->conn;
622 if (close_type == ERROR_CLOSE) {
623 cancel_aio_by_fsp(fsp);
626 * If we're finishing async io on a close we can get a write
627 * error here, we must remember this.
629 int ret = wait_for_aio_completion(fsp);
631 status = ntstatus_keeperror(
632 status, map_nt_error_from_unix(ret));
637 * If we're flushing on a close we can get a write
638 * error here, we must remember this.
641 tmp = close_filestruct(fsp);
642 status = ntstatus_keeperror(status, tmp);
644 if (fsp->print_file) {
645 /* FIXME: return spool errors */
646 print_spool_end(fsp, close_type);
651 /* Remove the oplock before potentially deleting the file. */
652 if(fsp->oplock_type) {
653 release_file_oplock(fsp);
656 /* If this is an old DOS or FCB open and we have multiple opens on
657 the same handle we only have one share mode. Ensure we only remove
658 the share mode on the last close. */
660 if (fsp->fh->ref_count == 1) {
661 /* Should we return on error here... ? */
662 tmp = close_remove_share_mode(fsp, close_type);
663 status = ntstatus_keeperror(status, tmp);
666 locking_close_file(conn->sconn->msg_ctx, fsp, close_type);
669 status = ntstatus_keeperror(status, tmp);
671 /* check for magic scripts */
672 if (close_type == NORMAL_CLOSE) {
673 tmp = check_magic(fsp);
674 status = ntstatus_keeperror(status, tmp);
678 * Ensure pending modtime is set after close.
681 tmp = update_write_time_on_close(fsp);
682 if (NT_STATUS_EQUAL(tmp, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
683 /* Someone renamed the file or a parent directory containing
684 * this file. We can't do anything about this, we don't have
685 * an "update timestamp by fd" call in POSIX. Eat the error. */
690 status = ntstatus_keeperror(status, tmp);
692 DEBUG(2,("%s closed file %s (numopen=%d) %s\n",
693 conn->session_info->unix_info->unix_name, fsp_str_dbg(fsp),
694 conn->num_files_open - 1,
695 nt_errstr(status) ));
700 /****************************************************************************
701 Static function used by reply_rmdir to delete an entire directory
702 tree recursively. Return True on ok, False on fail.
703 ****************************************************************************/
705 static bool recursive_rmdir(TALLOC_CTX *ctx,
706 connection_struct *conn,
707 struct smb_filename *smb_dname)
709 const char *dname = NULL;
710 char *talloced = NULL;
714 struct smb_Dir *dir_hnd;
716 SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
718 dir_hnd = OpenDir(talloc_tos(), conn, smb_dname->base_name, NULL, 0);
722 while((dname = ReadDirName(dir_hnd, &offset, &st, &talloced))) {
723 struct smb_filename *smb_dname_full = NULL;
724 char *fullname = NULL;
725 bool do_break = true;
728 if (ISDOT(dname) || ISDOTDOT(dname)) {
729 TALLOC_FREE(talloced);
733 if (!is_visible_file(conn, smb_dname->base_name, dname, &st,
735 TALLOC_FREE(talloced);
739 /* Construct the full name. */
740 fullname = talloc_asprintf(ctx,
742 smb_dname->base_name,
749 status = create_synthetic_smb_fname(talloc_tos(), fullname,
752 if (!NT_STATUS_IS_OK(status)) {
756 if(SMB_VFS_LSTAT(conn, smb_dname_full) != 0) {
760 if(smb_dname_full->st.st_ex_mode & S_IFDIR) {
761 if(!recursive_rmdir(ctx, conn, smb_dname_full)) {
764 if(SMB_VFS_RMDIR(conn,
765 smb_dname_full->base_name) != 0) {
768 } else if(SMB_VFS_UNLINK(conn, smb_dname_full) != 0) {
772 /* Successful iteration. */
776 TALLOC_FREE(smb_dname_full);
777 TALLOC_FREE(fullname);
778 TALLOC_FREE(talloced);
784 TALLOC_FREE(dir_hnd);
788 /****************************************************************************
789 The internals of the rmdir code - called elsewhere.
790 ****************************************************************************/
792 static NTSTATUS rmdir_internals(TALLOC_CTX *ctx, files_struct *fsp)
794 connection_struct *conn = fsp->conn;
795 struct smb_filename *smb_dname = fsp->fsp_name;
798 SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
800 /* Might be a symlink. */
801 if(SMB_VFS_LSTAT(conn, smb_dname) != 0) {
802 return map_nt_error_from_unix(errno);
805 if (S_ISLNK(smb_dname->st.st_ex_mode)) {
806 /* Is what it points to a directory ? */
807 if(SMB_VFS_STAT(conn, smb_dname) != 0) {
808 return map_nt_error_from_unix(errno);
810 if (!(S_ISDIR(smb_dname->st.st_ex_mode))) {
811 return NT_STATUS_NOT_A_DIRECTORY;
813 ret = SMB_VFS_UNLINK(conn, smb_dname);
815 ret = SMB_VFS_RMDIR(conn, smb_dname->base_name);
818 notify_fname(conn, NOTIFY_ACTION_REMOVED,
819 FILE_NOTIFY_CHANGE_DIR_NAME,
820 smb_dname->base_name);
824 if(((errno == ENOTEMPTY)||(errno == EEXIST)) && lp_veto_files(SNUM(conn))) {
826 * Check to see if the only thing in this directory are
827 * vetoed files/directories. If so then delete them and
828 * retry. If we fail to delete any of them (and we *don't*
829 * do a recursive delete) then fail the rmdir.
832 const char *dname = NULL;
833 char *talloced = NULL;
835 struct smb_Dir *dir_hnd = OpenDir(talloc_tos(), conn,
836 smb_dname->base_name, NULL,
839 if(dir_hnd == NULL) {
844 while ((dname = ReadDirName(dir_hnd, &dirpos, &st,
845 &talloced)) != NULL) {
846 if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0)) {
847 TALLOC_FREE(talloced);
850 if (!is_visible_file(conn, smb_dname->base_name, dname,
852 TALLOC_FREE(talloced);
855 if(!IS_VETO_PATH(conn, dname)) {
856 TALLOC_FREE(dir_hnd);
857 TALLOC_FREE(talloced);
861 TALLOC_FREE(talloced);
864 /* We only have veto files/directories.
865 * Are we allowed to delete them ? */
867 if(!lp_recursive_veto_delete(SNUM(conn))) {
868 TALLOC_FREE(dir_hnd);
873 /* Do a recursive delete. */
874 RewindDir(dir_hnd,&dirpos);
875 while ((dname = ReadDirName(dir_hnd, &dirpos, &st,
876 &talloced)) != NULL) {
877 struct smb_filename *smb_dname_full = NULL;
878 char *fullname = NULL;
879 bool do_break = true;
882 if (ISDOT(dname) || ISDOTDOT(dname)) {
883 TALLOC_FREE(talloced);
886 if (!is_visible_file(conn, smb_dname->base_name, dname,
888 TALLOC_FREE(talloced);
892 fullname = talloc_asprintf(ctx,
894 smb_dname->base_name,
902 status = create_synthetic_smb_fname(talloc_tos(),
906 if (!NT_STATUS_IS_OK(status)) {
907 errno = map_errno_from_nt_status(status);
911 if(SMB_VFS_LSTAT(conn, smb_dname_full) != 0) {
914 if(smb_dname_full->st.st_ex_mode & S_IFDIR) {
915 if(!recursive_rmdir(ctx, conn,
919 if(SMB_VFS_RMDIR(conn,
920 smb_dname_full->base_name) != 0) {
923 } else if(SMB_VFS_UNLINK(conn, smb_dname_full) != 0) {
927 /* Successful iteration. */
931 TALLOC_FREE(fullname);
932 TALLOC_FREE(smb_dname_full);
933 TALLOC_FREE(talloced);
937 TALLOC_FREE(dir_hnd);
938 /* Retry the rmdir */
939 ret = SMB_VFS_RMDIR(conn, smb_dname->base_name);
945 DEBUG(3,("rmdir_internals: couldn't remove directory %s : "
946 "%s\n", smb_fname_str_dbg(smb_dname),
948 return map_nt_error_from_unix(errno);
951 notify_fname(conn, NOTIFY_ACTION_REMOVED,
952 FILE_NOTIFY_CHANGE_DIR_NAME,
953 smb_dname->base_name);
958 /****************************************************************************
959 Close a directory opened by an NT SMB call.
960 ****************************************************************************/
962 static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
963 enum file_close_type close_type)
965 struct share_mode_lock *lck = NULL;
966 bool delete_dir = False;
967 NTSTATUS status = NT_STATUS_OK;
968 NTSTATUS status1 = NT_STATUS_OK;
969 const struct security_unix_token *del_token = NULL;
972 * NT can set delete_on_close of the last open
973 * reference to a directory also.
976 lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL,
980 DEBUG(0, ("close_directory: Could not get share mode lock for "
981 "%s\n", fsp_str_dbg(fsp)));
982 status = NT_STATUS_INVALID_PARAMETER;
986 if (!del_share_mode(lck, fsp)) {
987 DEBUG(0, ("close_directory: Could not delete share entry for "
988 "%s\n", fsp_str_dbg(fsp)));
991 if (fsp->initial_delete_on_close) {
992 bool became_user = False;
994 /* Initial delete on close was set - for
995 * directories we don't care if anyone else
996 * wrote a real delete on close. */
998 if (get_current_vuid(fsp->conn) != fsp->vuid) {
999 become_user(fsp->conn, fsp->vuid);
1002 send_stat_cache_delete_message(fsp->conn->sconn->msg_ctx,
1003 fsp->fsp_name->base_name);
1004 set_delete_on_close_lck(fsp, lck, true,
1005 get_current_utok(fsp->conn));
1006 fsp->delete_on_close = true;
1012 del_token = get_delete_on_close_token(lck, fsp->name_hash);
1013 delete_dir = (del_token != NULL);
1017 /* See if others still have the dir open. If this is the
1018 * case, then don't delete. If all opens are POSIX delete now. */
1019 for (i=0; i<lck->num_share_modes; i++) {
1020 struct share_mode_entry *e = &lck->share_modes[i];
1021 if (is_valid_share_mode_entry(e) &&
1022 e->name_hash == fsp->name_hash) {
1023 if (fsp->posix_open && (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) {
1032 if ((close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) &&
1035 /* Become the user who requested the delete. */
1037 if (!push_sec_ctx()) {
1038 smb_panic("close_directory: failed to push sec_ctx.\n");
1041 set_sec_ctx(del_token->uid,
1049 status = rmdir_internals(talloc_tos(), fsp);
1051 DEBUG(5,("close_directory: %s. Delete on close was set - "
1052 "deleting directory returned %s.\n",
1053 fsp_str_dbg(fsp), nt_errstr(status)));
1055 /* unbecome user. */
1059 * Ensure we remove any change notify requests that would
1060 * now fail as the directory has been deleted.
1063 if(NT_STATUS_IS_OK(status)) {
1064 remove_pending_change_notify_requests_by_fid(fsp, NT_STATUS_DELETE_PENDING);
1068 remove_pending_change_notify_requests_by_fid(
1072 status1 = fd_close(fsp);
1074 if (!NT_STATUS_IS_OK(status1)) {
1075 DEBUG(0, ("Could not close dir! fname=%s, fd=%d, err=%d=%s\n",
1076 fsp_str_dbg(fsp), fsp->fh->fd, errno,
1081 * Do the code common to files and directories.
1083 close_filestruct(fsp);
1084 file_free(req, fsp);
1088 if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(status1)) {
1094 /****************************************************************************
1095 Close a files_struct.
1096 ****************************************************************************/
1098 NTSTATUS close_file(struct smb_request *req, files_struct *fsp,
1099 enum file_close_type close_type)
1102 struct files_struct *base_fsp = fsp->base_fsp;
1104 if(fsp->is_directory) {
1105 status = close_directory(req, fsp, close_type);
1106 } else if (fsp->fake_file_handle != NULL) {
1107 status = close_fake_file(req, fsp);
1109 status = close_normal_file(req, fsp, close_type);
1112 if ((base_fsp != NULL) && (close_type != SHUTDOWN_CLOSE)) {
1115 * fsp was a stream, the base fsp can't be a stream as well
1117 * For SHUTDOWN_CLOSE this is not possible here, because
1118 * SHUTDOWN_CLOSE only happens from files.c which walks the
1119 * complete list of files. If we mess with more than one fsp
1120 * those loops will become confused.
1123 SMB_ASSERT(base_fsp->base_fsp == NULL);
1124 close_file(req, base_fsp, close_type);
1130 /****************************************************************************
1131 Deal with an (authorized) message to close a file given the share mode
1133 ****************************************************************************/
1135 void msg_close_file(struct messaging_context *msg_ctx,
1138 struct server_id server_id,
1141 struct smbd_server_connection *sconn;
1142 files_struct *fsp = NULL;
1143 struct share_mode_entry e;
1145 sconn = msg_ctx_to_sconn(msg_ctx);
1146 if (sconn == NULL) {
1147 DEBUG(1, ("could not find sconn\n"));
1151 message_to_share_mode_entry(&e, (char *)data->data);
1154 char *sm_str = share_mode_str(NULL, 0, &e);
1156 smb_panic("talloc failed");
1158 DEBUG(10,("msg_close_file: got request to close share mode "
1159 "entry %s\n", sm_str));
1160 TALLOC_FREE(sm_str);
1163 fsp = file_find_dif(sconn, e.id, e.share_file_id);
1165 DEBUG(10,("msg_close_file: failed to find file.\n"));
1168 close_file(NULL, fsp, NORMAL_CLOSE);