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 smbd_server_connection *sconn,
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)) {
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 schedule_deferred_open_message_smb(sconn, e->op_mid);
188 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
190 share_mode_entry_to_message(msg, e);
192 messaging_send_buf(sconn->msg_ctx, e->pid,
195 MSG_SMB_SHARE_MODE_ENTRY_SIZE);
200 /****************************************************************************
202 ****************************************************************************/
204 NTSTATUS delete_all_streams(connection_struct *conn, const char *fname)
206 struct stream_struct *stream_info = NULL;
208 unsigned int num_streams = 0;
209 TALLOC_CTX *frame = talloc_stackframe();
212 status = vfs_streaminfo(conn, NULL, fname, talloc_tos(),
213 &num_streams, &stream_info);
215 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
216 DEBUG(10, ("no streams around\n"));
221 if (!NT_STATUS_IS_OK(status)) {
222 DEBUG(10, ("vfs_streaminfo failed: %s\n",
227 DEBUG(10, ("delete_all_streams found %d streams\n",
230 if (num_streams == 0) {
235 for (i=0; i<num_streams; i++) {
237 struct smb_filename *smb_fname_stream = NULL;
239 if (strequal(stream_info[i].name, "::$DATA")) {
243 status = create_synthetic_smb_fname(talloc_tos(), fname,
244 stream_info[i].name, NULL,
247 if (!NT_STATUS_IS_OK(status)) {
248 DEBUG(0, ("talloc_aprintf failed\n"));
252 res = SMB_VFS_UNLINK(conn, smb_fname_stream);
255 status = map_nt_error_from_unix(errno);
256 DEBUG(10, ("Could not delete stream %s: %s\n",
257 smb_fname_str_dbg(smb_fname_stream),
259 TALLOC_FREE(smb_fname_stream);
262 TALLOC_FREE(smb_fname_stream);
270 /****************************************************************************
271 Deal with removing a share mode on last close.
272 ****************************************************************************/
274 static NTSTATUS close_remove_share_mode(files_struct *fsp,
275 enum file_close_type close_type)
277 connection_struct *conn = fsp->conn;
278 bool delete_file = false;
279 bool changed_user = false;
280 struct share_mode_lock *lck = NULL;
281 NTSTATUS status = NT_STATUS_OK;
284 const struct security_unix_token *del_token = NULL;
286 /* Ensure any pending write time updates are done. */
287 if (fsp->update_write_time_event) {
288 update_write_time_handler(fsp->conn->sconn->ev_ctx,
289 fsp->update_write_time_event,
295 * Lock the share entries, and determine if we should delete
296 * on close. If so delete whilst the lock is still in effect.
297 * This prevents race conditions with the file being created. JRA.
300 lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL,
304 DEBUG(0, ("close_remove_share_mode: Could not get share mode "
305 "lock for file %s\n", fsp_str_dbg(fsp)));
306 status = NT_STATUS_INVALID_PARAMETER;
310 if (fsp->write_time_forced) {
311 DEBUG(10,("close_remove_share_mode: write time forced "
314 set_close_write_time(fsp, lck->changed_write_time);
315 } else if (fsp->update_write_time_on_close) {
316 /* Someone had a pending write. */
317 if (null_timespec(fsp->close_write_time)) {
318 DEBUG(10,("close_remove_share_mode: update to current time "
321 /* Update to current time due to "normal" write. */
322 set_close_write_time(fsp, timespec_current());
324 DEBUG(10,("close_remove_share_mode: write time pending "
327 /* Update to time set on close call. */
328 set_close_write_time(fsp, fsp->close_write_time);
332 if (!del_share_mode(lck, fsp)) {
333 DEBUG(0, ("close_remove_share_mode: Could not delete share "
334 "entry for file %s\n",
338 if (fsp->initial_delete_on_close &&
339 !is_delete_on_close_set(lck, fsp->name_hash)) {
340 bool became_user = False;
342 /* Initial delete on close was set and no one else
343 * wrote a real delete on close. */
345 if (get_current_vuid(conn) != fsp->vuid) {
346 become_user(conn, fsp->vuid);
349 fsp->delete_on_close = true;
350 set_delete_on_close_lck(fsp, lck, True, get_current_utok(conn));
356 delete_file = is_delete_on_close_set(lck, fsp->name_hash);
360 /* See if others still have the file open via this pathname.
361 If this is the case, then don't delete. If all opens are
363 for (i=0; i<lck->num_share_modes; i++) {
364 struct share_mode_entry *e = &lck->share_modes[i];
365 if (is_valid_share_mode_entry(e) &&
366 e->name_hash == fsp->name_hash) {
367 if (fsp->posix_open && (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) {
376 /* Notify any deferred opens waiting on this close. */
377 notify_deferred_opens(conn->sconn, lck);
378 reply_to_oplock_break_requests(fsp);
381 * NT can set delete_on_close of the last open
382 * reference to a file.
385 if (!(close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) ||
392 * Ok, we have to delete the file
395 DEBUG(5,("close_remove_share_mode: file %s. Delete on close was set "
396 "- deleting file.\n", fsp_str_dbg(fsp)));
399 * Don't try to update the write time when we delete the file
401 fsp->update_write_time_on_close = false;
403 del_token = get_delete_on_close_token(lck, fsp->name_hash);
404 SMB_ASSERT(del_token != NULL);
406 if (!unix_token_equal(del_token, get_current_utok(conn))) {
407 /* Become the user who requested the delete. */
409 DEBUG(5,("close_remove_share_mode: file %s. "
410 "Change user to uid %u\n",
412 (unsigned int)del_token->uid));
414 if (!push_sec_ctx()) {
415 smb_panic("close_remove_share_mode: file %s. failed to push "
419 set_sec_ctx(del_token->uid,
428 /* We can only delete the file if the name we have is still valid and
429 hasn't been renamed. */
431 tmp_status = vfs_stat_fsp(fsp);
432 if (!NT_STATUS_IS_OK(tmp_status)) {
433 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
434 "was set and stat failed with error %s\n",
435 fsp_str_dbg(fsp), nt_errstr(tmp_status)));
437 * Don't save the errno here, we ignore this error
442 id = vfs_file_id_from_sbuf(conn, &fsp->fsp_name->st);
444 if (!file_id_equal(&fsp->file_id, &id)) {
445 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
446 "was set and dev and/or inode does not match\n",
448 DEBUG(5,("close_remove_share_mode: file %s. stored file_id %s, "
451 file_id_string_tos(&fsp->file_id),
452 file_id_string_tos(&id)));
454 * Don't save the errno here, we ignore this error
459 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
460 && !is_ntfs_stream_smb_fname(fsp->fsp_name)) {
462 status = delete_all_streams(conn, fsp->fsp_name->base_name);
464 if (!NT_STATUS_IS_OK(status)) {
465 DEBUG(5, ("delete_all_streams failed: %s\n",
472 if (SMB_VFS_UNLINK(conn, fsp->fsp_name) != 0) {
474 * This call can potentially fail as another smbd may
475 * have had the file open with delete on close set and
476 * deleted it when its last reference to this file
477 * went away. Hence we log this but not at debug level
481 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
482 "was set and unlink failed with error %s\n",
483 fsp_str_dbg(fsp), strerror(errno)));
485 status = map_nt_error_from_unix(errno);
488 /* As we now have POSIX opens which can unlink
489 * with other open files we may have taken
490 * this code path with more than one share mode
491 * entry - ensure we only delete once by resetting
492 * the delete on close flag. JRA.
495 fsp->delete_on_close = false;
496 set_delete_on_close_lck(fsp, lck, false, NULL);
509 * Do the notification after we released the share
510 * mode lock. Inside notify_fname we take out another
511 * tdb lock. With ctdb also accessing our databases,
512 * this can lead to deadlocks. Putting this notify
513 * after the TALLOC_FREE(lck) above we avoid locking
514 * two records simultaneously. Notifies are async and
515 * informational only, so calling the notify_fname
516 * without holding the share mode lock should not do
519 notify_fname(conn, NOTIFY_ACTION_REMOVED,
520 FILE_NOTIFY_CHANGE_FILE_NAME,
521 fsp->fsp_name->base_name);
527 void set_close_write_time(struct files_struct *fsp, struct timespec ts)
529 DEBUG(6,("close_write_time: %s" , time_to_asc(convert_timespec_to_time_t(ts))));
531 if (null_timespec(ts)) {
534 fsp->write_time_forced = false;
535 fsp->update_write_time_on_close = true;
536 fsp->close_write_time = ts;
539 static NTSTATUS update_write_time_on_close(struct files_struct *fsp)
541 struct smb_file_time ft;
543 struct share_mode_lock *lck = NULL;
547 if (!fsp->update_write_time_on_close) {
551 if (null_timespec(fsp->close_write_time)) {
552 fsp->close_write_time = timespec_current();
555 /* Ensure we have a valid stat struct for the source. */
556 status = vfs_stat_fsp(fsp);
557 if (!NT_STATUS_IS_OK(status)) {
561 if (!VALID_STAT(fsp->fsp_name->st)) {
562 /* if it doesn't seem to be a real file */
566 /* On close if we're changing the real file time we
567 * must update it in the open file db too. */
568 (void)set_write_time(fsp->file_id, fsp->close_write_time);
570 lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL, NULL);
572 /* Close write times overwrite sticky write times
573 so we must replace any sticky write time here. */
574 if (!null_timespec(lck->changed_write_time)) {
575 (void)set_sticky_write_time(fsp->file_id, fsp->close_write_time);
580 ft.mtime = fsp->close_write_time;
581 /* As this is a close based update, we are not directly changing the
582 file attributes from a client call, but indirectly from a write. */
583 status = smb_set_file_time(fsp->conn, fsp, fsp->fsp_name, &ft, false);
584 if (!NT_STATUS_IS_OK(status)) {
585 DEBUG(10,("update_write_time_on_close: smb_set_file_time "
586 "on file %s returned %s\n",
595 static NTSTATUS ntstatus_keeperror(NTSTATUS s1, NTSTATUS s2)
597 if (!NT_STATUS_IS_OK(s1)) {
603 /****************************************************************************
606 close_type can be NORMAL_CLOSE=0,SHUTDOWN_CLOSE,ERROR_CLOSE.
607 printing and magic scripts are only run on normal close.
608 delete on close is done on normal and shutdown close.
609 ****************************************************************************/
611 static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp,
612 enum file_close_type close_type)
614 NTSTATUS status = NT_STATUS_OK;
616 connection_struct *conn = fsp->conn;
618 if (close_type == ERROR_CLOSE) {
619 cancel_aio_by_fsp(fsp);
622 * If we're finishing async io on a close we can get a write
623 * error here, we must remember this.
625 int ret = wait_for_aio_completion(fsp);
627 status = ntstatus_keeperror(
628 status, map_nt_error_from_unix(ret));
633 * If we're flushing on a close we can get a write
634 * error here, we must remember this.
637 tmp = close_filestruct(fsp);
638 status = ntstatus_keeperror(status, tmp);
640 if (fsp->print_file) {
641 /* FIXME: return spool errors */
642 print_spool_end(fsp, close_type);
647 /* Remove the oplock before potentially deleting the file. */
648 if(fsp->oplock_type) {
649 release_file_oplock(fsp);
652 /* If this is an old DOS or FCB open and we have multiple opens on
653 the same handle we only have one share mode. Ensure we only remove
654 the share mode on the last close. */
656 if (fsp->fh->ref_count == 1) {
657 /* Should we return on error here... ? */
658 tmp = close_remove_share_mode(fsp, close_type);
659 status = ntstatus_keeperror(status, tmp);
662 locking_close_file(conn->sconn->msg_ctx, fsp, close_type);
665 status = ntstatus_keeperror(status, tmp);
667 /* check for magic scripts */
668 if (close_type == NORMAL_CLOSE) {
669 tmp = check_magic(fsp);
670 status = ntstatus_keeperror(status, tmp);
674 * Ensure pending modtime is set after close.
677 tmp = update_write_time_on_close(fsp);
678 if (NT_STATUS_EQUAL(tmp, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
679 /* Someone renamed the file or a parent directory containing
680 * this file. We can't do anything about this, we don't have
681 * an "update timestamp by fd" call in POSIX. Eat the error. */
686 status = ntstatus_keeperror(status, tmp);
688 DEBUG(2,("%s closed file %s (numopen=%d) %s\n",
689 conn->session_info->unix_info->unix_name, fsp_str_dbg(fsp),
690 conn->num_files_open - 1,
691 nt_errstr(status) ));
696 /****************************************************************************
697 Static function used by reply_rmdir to delete an entire directory
698 tree recursively. Return True on ok, False on fail.
699 ****************************************************************************/
701 static bool recursive_rmdir(TALLOC_CTX *ctx,
702 connection_struct *conn,
703 struct smb_filename *smb_dname)
705 const char *dname = NULL;
706 char *talloced = NULL;
710 struct smb_Dir *dir_hnd;
712 SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
714 dir_hnd = OpenDir(talloc_tos(), conn, smb_dname->base_name, NULL, 0);
718 while((dname = ReadDirName(dir_hnd, &offset, &st, &talloced))) {
719 struct smb_filename *smb_dname_full = NULL;
720 char *fullname = NULL;
721 bool do_break = true;
724 if (ISDOT(dname) || ISDOTDOT(dname)) {
725 TALLOC_FREE(talloced);
729 if (!is_visible_file(conn, smb_dname->base_name, dname, &st,
731 TALLOC_FREE(talloced);
735 /* Construct the full name. */
736 fullname = talloc_asprintf(ctx,
738 smb_dname->base_name,
745 status = create_synthetic_smb_fname(talloc_tos(), fullname,
748 if (!NT_STATUS_IS_OK(status)) {
752 if(SMB_VFS_LSTAT(conn, smb_dname_full) != 0) {
756 if(smb_dname_full->st.st_ex_mode & S_IFDIR) {
757 if(!recursive_rmdir(ctx, conn, smb_dname_full)) {
760 if(SMB_VFS_RMDIR(conn,
761 smb_dname_full->base_name) != 0) {
764 } else if(SMB_VFS_UNLINK(conn, smb_dname_full) != 0) {
768 /* Successful iteration. */
772 TALLOC_FREE(smb_dname_full);
773 TALLOC_FREE(fullname);
774 TALLOC_FREE(talloced);
780 TALLOC_FREE(dir_hnd);
784 /****************************************************************************
785 The internals of the rmdir code - called elsewhere.
786 ****************************************************************************/
788 static NTSTATUS rmdir_internals(TALLOC_CTX *ctx, files_struct *fsp)
790 connection_struct *conn = fsp->conn;
791 struct smb_filename *smb_dname = fsp->fsp_name;
794 SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
796 /* Might be a symlink. */
797 if(SMB_VFS_LSTAT(conn, smb_dname) != 0) {
798 return map_nt_error_from_unix(errno);
801 if (S_ISLNK(smb_dname->st.st_ex_mode)) {
802 /* Is what it points to a directory ? */
803 if(SMB_VFS_STAT(conn, smb_dname) != 0) {
804 return map_nt_error_from_unix(errno);
806 if (!(S_ISDIR(smb_dname->st.st_ex_mode))) {
807 return NT_STATUS_NOT_A_DIRECTORY;
809 ret = SMB_VFS_UNLINK(conn, smb_dname);
811 ret = SMB_VFS_RMDIR(conn, smb_dname->base_name);
814 notify_fname(conn, NOTIFY_ACTION_REMOVED,
815 FILE_NOTIFY_CHANGE_DIR_NAME,
816 smb_dname->base_name);
820 if(((errno == ENOTEMPTY)||(errno == EEXIST)) && lp_veto_files(SNUM(conn))) {
822 * Check to see if the only thing in this directory are
823 * vetoed files/directories. If so then delete them and
824 * retry. If we fail to delete any of them (and we *don't*
825 * do a recursive delete) then fail the rmdir.
828 const char *dname = NULL;
829 char *talloced = NULL;
831 struct smb_Dir *dir_hnd = OpenDir(talloc_tos(), conn,
832 smb_dname->base_name, NULL,
835 if(dir_hnd == NULL) {
840 while ((dname = ReadDirName(dir_hnd, &dirpos, &st,
841 &talloced)) != NULL) {
842 if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0)) {
843 TALLOC_FREE(talloced);
846 if (!is_visible_file(conn, smb_dname->base_name, dname,
848 TALLOC_FREE(talloced);
851 if(!IS_VETO_PATH(conn, dname)) {
852 TALLOC_FREE(dir_hnd);
853 TALLOC_FREE(talloced);
857 TALLOC_FREE(talloced);
860 /* We only have veto files/directories.
861 * Are we allowed to delete them ? */
863 if(!lp_recursive_veto_delete(SNUM(conn))) {
864 TALLOC_FREE(dir_hnd);
869 /* Do a recursive delete. */
870 RewindDir(dir_hnd,&dirpos);
871 while ((dname = ReadDirName(dir_hnd, &dirpos, &st,
872 &talloced)) != NULL) {
873 struct smb_filename *smb_dname_full = NULL;
874 char *fullname = NULL;
875 bool do_break = true;
878 if (ISDOT(dname) || ISDOTDOT(dname)) {
879 TALLOC_FREE(talloced);
882 if (!is_visible_file(conn, smb_dname->base_name, dname,
884 TALLOC_FREE(talloced);
888 fullname = talloc_asprintf(ctx,
890 smb_dname->base_name,
898 status = create_synthetic_smb_fname(talloc_tos(),
902 if (!NT_STATUS_IS_OK(status)) {
903 errno = map_errno_from_nt_status(status);
907 if(SMB_VFS_LSTAT(conn, smb_dname_full) != 0) {
910 if(smb_dname_full->st.st_ex_mode & S_IFDIR) {
911 if(!recursive_rmdir(ctx, conn,
915 if(SMB_VFS_RMDIR(conn,
916 smb_dname_full->base_name) != 0) {
919 } else if(SMB_VFS_UNLINK(conn, smb_dname_full) != 0) {
923 /* Successful iteration. */
927 TALLOC_FREE(fullname);
928 TALLOC_FREE(smb_dname_full);
929 TALLOC_FREE(talloced);
933 TALLOC_FREE(dir_hnd);
934 /* Retry the rmdir */
935 ret = SMB_VFS_RMDIR(conn, smb_dname->base_name);
941 DEBUG(3,("rmdir_internals: couldn't remove directory %s : "
942 "%s\n", smb_fname_str_dbg(smb_dname),
944 return map_nt_error_from_unix(errno);
947 notify_fname(conn, NOTIFY_ACTION_REMOVED,
948 FILE_NOTIFY_CHANGE_DIR_NAME,
949 smb_dname->base_name);
954 /****************************************************************************
955 Close a directory opened by an NT SMB call.
956 ****************************************************************************/
958 static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
959 enum file_close_type close_type)
961 struct share_mode_lock *lck = NULL;
962 bool delete_dir = False;
963 NTSTATUS status = NT_STATUS_OK;
964 NTSTATUS status1 = NT_STATUS_OK;
965 const struct security_unix_token *del_token = NULL;
968 * NT can set delete_on_close of the last open
969 * reference to a directory also.
972 lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL,
976 DEBUG(0, ("close_directory: Could not get share mode lock for "
977 "%s\n", fsp_str_dbg(fsp)));
978 status = NT_STATUS_INVALID_PARAMETER;
982 if (!del_share_mode(lck, fsp)) {
983 DEBUG(0, ("close_directory: Could not delete share entry for "
984 "%s\n", fsp_str_dbg(fsp)));
987 if (fsp->initial_delete_on_close) {
988 bool became_user = False;
990 /* Initial delete on close was set - for
991 * directories we don't care if anyone else
992 * wrote a real delete on close. */
994 if (get_current_vuid(fsp->conn) != fsp->vuid) {
995 become_user(fsp->conn, fsp->vuid);
998 send_stat_cache_delete_message(fsp->conn->sconn->msg_ctx,
999 fsp->fsp_name->base_name);
1000 set_delete_on_close_lck(fsp, lck, true,
1001 get_current_utok(fsp->conn));
1002 fsp->delete_on_close = true;
1008 del_token = get_delete_on_close_token(lck, fsp->name_hash);
1009 delete_dir = (del_token != NULL);
1013 /* See if others still have the dir open. If this is the
1014 * case, then don't delete. If all opens are POSIX delete now. */
1015 for (i=0; i<lck->num_share_modes; i++) {
1016 struct share_mode_entry *e = &lck->share_modes[i];
1017 if (is_valid_share_mode_entry(e) &&
1018 e->name_hash == fsp->name_hash) {
1019 if (fsp->posix_open && (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) {
1028 if ((close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) &&
1031 /* Become the user who requested the delete. */
1033 if (!push_sec_ctx()) {
1034 smb_panic("close_directory: failed to push sec_ctx.\n");
1037 set_sec_ctx(del_token->uid,
1045 status = rmdir_internals(talloc_tos(), fsp);
1047 DEBUG(5,("close_directory: %s. Delete on close was set - "
1048 "deleting directory returned %s.\n",
1049 fsp_str_dbg(fsp), nt_errstr(status)));
1051 /* unbecome user. */
1055 * Ensure we remove any change notify requests that would
1056 * now fail as the directory has been deleted.
1059 if(NT_STATUS_IS_OK(status)) {
1060 remove_pending_change_notify_requests_by_fid(fsp, NT_STATUS_DELETE_PENDING);
1064 remove_pending_change_notify_requests_by_fid(
1068 status1 = fd_close(fsp);
1070 if (!NT_STATUS_IS_OK(status1)) {
1071 DEBUG(0, ("Could not close dir! fname=%s, fd=%d, err=%d=%s\n",
1072 fsp_str_dbg(fsp), fsp->fh->fd, errno,
1077 * Do the code common to files and directories.
1079 close_filestruct(fsp);
1080 file_free(req, fsp);
1084 if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(status1)) {
1090 /****************************************************************************
1091 Close a files_struct.
1092 ****************************************************************************/
1094 NTSTATUS close_file(struct smb_request *req, files_struct *fsp,
1095 enum file_close_type close_type)
1098 struct files_struct *base_fsp = fsp->base_fsp;
1100 if(fsp->is_directory) {
1101 status = close_directory(req, fsp, close_type);
1102 } else if (fsp->fake_file_handle != NULL) {
1103 status = close_fake_file(req, fsp);
1105 status = close_normal_file(req, fsp, close_type);
1108 if ((base_fsp != NULL) && (close_type != SHUTDOWN_CLOSE)) {
1111 * fsp was a stream, the base fsp can't be a stream as well
1113 * For SHUTDOWN_CLOSE this is not possible here, because
1114 * SHUTDOWN_CLOSE only happens from files.c which walks the
1115 * complete list of files. If we mess with more than one fsp
1116 * those loops will become confused.
1119 SMB_ASSERT(base_fsp->base_fsp == NULL);
1120 close_file(req, base_fsp, close_type);
1126 /****************************************************************************
1127 Deal with an (authorized) message to close a file given the share mode
1129 ****************************************************************************/
1131 void msg_close_file(struct messaging_context *msg_ctx,
1134 struct server_id server_id,
1137 files_struct *fsp = NULL;
1138 struct share_mode_entry e;
1139 struct smbd_server_connection *sconn =
1140 talloc_get_type(private_data,
1141 struct smbd_server_connection);
1143 if (sconn == NULL) {
1147 message_to_share_mode_entry(&e, (char *)data->data);
1150 char *sm_str = share_mode_str(NULL, 0, &e);
1152 smb_panic("talloc failed");
1154 DEBUG(10,("msg_close_file: got request to close share mode "
1155 "entry %s\n", sm_str));
1156 TALLOC_FREE(sm_str);
1159 fsp = file_find_dif(sconn, e.id, e.share_file_id);
1161 DEBUG(10,("msg_close_file: failed to find file.\n"));
1164 close_file(NULL, fsp, NORMAL_CLOSE);