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/>.
24 #include "librpc/gen_ndr/messaging.h"
25 #include "smbd/globals.h"
27 /****************************************************************************
28 Run a file if it is a magic script.
29 ****************************************************************************/
31 static NTSTATUS
check_magic(struct files_struct
*fsp
)
34 const char *magic_output
= NULL
;
37 TALLOC_CTX
*ctx
= NULL
;
39 struct connection_struct
*conn
= fsp
->conn
;
43 if (!*lp_magicscript(SNUM(conn
))) {
47 DEBUG(5,("checking magic for %s\n", fsp_str_dbg(fsp
)));
49 ctx
= talloc_stackframe();
51 fname
= fsp
->fsp_name
->base_name
;
53 if (!(p
= strrchr_m(fname
,'/'))) {
59 if (!strequal(lp_magicscript(SNUM(conn
)),p
)) {
60 status
= NT_STATUS_OK
;
64 if (*lp_magicoutput(SNUM(conn
))) {
65 magic_output
= lp_magicoutput(SNUM(conn
));
67 magic_output
= talloc_asprintf(ctx
,
72 status
= NT_STATUS_NO_MEMORY
;
76 /* Ensure we don't depend on user's PATH. */
77 p
= talloc_asprintf(ctx
, "./%s", fname
);
79 status
= NT_STATUS_NO_MEMORY
;
83 if (chmod(fname
, 0755) == -1) {
84 status
= map_nt_error_from_unix(errno
);
87 ret
= smbrun(p
,&tmp_fd
);
88 DEBUG(3,("Invoking magic command %s gave %d\n",
92 if (ret
!= 0 || tmp_fd
== -1) {
96 status
= NT_STATUS_UNSUCCESSFUL
;
99 outfd
= open(magic_output
, O_CREAT
|O_EXCL
|O_RDWR
, 0600);
103 status
= map_nt_error_from_unix(err
);
107 if (sys_fstat(tmp_fd
, &st
, false) == -1) {
111 status
= map_nt_error_from_unix(err
);
115 if (transfer_file(tmp_fd
,outfd
,(SMB_OFF_T
)st
.st_ex_size
) == (SMB_OFF_T
)-1) {
119 status
= map_nt_error_from_unix(err
);
123 if (close(outfd
) == -1) {
124 status
= map_nt_error_from_unix(errno
);
128 status
= NT_STATUS_OK
;
135 /****************************************************************************
136 Common code to close a file or a directory.
137 ****************************************************************************/
139 static NTSTATUS
close_filestruct(files_struct
*fsp
)
141 NTSTATUS status
= NT_STATUS_OK
;
143 if (fsp
->fh
->fd
!= -1) {
144 if(flush_write_cache(fsp
, CLOSE_FLUSH
) == -1) {
145 status
= map_nt_error_from_unix(errno
);
147 delete_write_cache(fsp
);
153 /****************************************************************************
154 If any deferred opens are waiting on this close, notify them.
155 ****************************************************************************/
157 static void notify_deferred_opens(struct messaging_context
*msg_ctx
,
158 struct share_mode_lock
*lck
)
162 if (!should_notify_deferred_opens()) {
166 for (i
=0; i
<lck
->num_share_modes
; i
++) {
167 struct share_mode_entry
*e
= &lck
->share_modes
[i
];
169 if (!is_deferred_open_entry(e
)) {
173 if (procid_is_me(&e
->pid
)) {
175 * We need to notify ourself to retry the open. Do
176 * this by finding the queued SMB record, moving it to
177 * the head of the queue and changing the wait time to
180 schedule_deferred_open_message_smb(e
->op_mid
);
182 char msg
[MSG_SMB_SHARE_MODE_ENTRY_SIZE
];
184 share_mode_entry_to_message(msg
, e
);
186 messaging_send_buf(msg_ctx
, e
->pid
, MSG_SMB_OPEN_RETRY
,
188 MSG_SMB_SHARE_MODE_ENTRY_SIZE
);
193 /****************************************************************************
195 ****************************************************************************/
197 NTSTATUS
delete_all_streams(connection_struct
*conn
, const char *fname
)
199 struct stream_struct
*stream_info
;
201 unsigned int num_streams
;
202 TALLOC_CTX
*frame
= talloc_stackframe();
205 status
= SMB_VFS_STREAMINFO(conn
, NULL
, fname
, talloc_tos(),
206 &num_streams
, &stream_info
);
208 if (NT_STATUS_EQUAL(status
, NT_STATUS_NOT_IMPLEMENTED
)) {
209 DEBUG(10, ("no streams around\n"));
214 if (!NT_STATUS_IS_OK(status
)) {
215 DEBUG(10, ("SMB_VFS_STREAMINFO failed: %s\n",
220 DEBUG(10, ("delete_all_streams found %d streams\n",
223 if (num_streams
== 0) {
228 for (i
=0; i
<num_streams
; i
++) {
230 struct smb_filename
*smb_fname_stream
= NULL
;
232 if (strequal(stream_info
[i
].name
, "::$DATA")) {
236 status
= create_synthetic_smb_fname(talloc_tos(), fname
,
237 stream_info
[i
].name
, NULL
,
240 if (!NT_STATUS_IS_OK(status
)) {
241 DEBUG(0, ("talloc_aprintf failed\n"));
245 res
= SMB_VFS_UNLINK(conn
, smb_fname_stream
);
248 status
= map_nt_error_from_unix(errno
);
249 DEBUG(10, ("Could not delete stream %s: %s\n",
250 smb_fname_str_dbg(smb_fname_stream
),
252 TALLOC_FREE(smb_fname_stream
);
255 TALLOC_FREE(smb_fname_stream
);
263 /****************************************************************************
264 Deal with removing a share mode on last close.
265 ****************************************************************************/
267 static NTSTATUS
close_remove_share_mode(files_struct
*fsp
,
268 enum file_close_type close_type
)
270 connection_struct
*conn
= fsp
->conn
;
271 bool delete_file
= false;
272 bool changed_user
= false;
273 struct share_mode_lock
*lck
= NULL
;
274 NTSTATUS status
= NT_STATUS_OK
;
278 /* Ensure any pending write time updates are done. */
279 if (fsp
->update_write_time_event
) {
280 update_write_time_handler(smbd_event_context(),
281 fsp
->update_write_time_event
,
287 * Lock the share entries, and determine if we should delete
288 * on close. If so delete whilst the lock is still in effect.
289 * This prevents race conditions with the file being created. JRA.
292 lck
= get_share_mode_lock(talloc_tos(), fsp
->file_id
, NULL
, NULL
,
296 DEBUG(0, ("close_remove_share_mode: Could not get share mode "
297 "lock for file %s\n", fsp_str_dbg(fsp
)));
298 status
= NT_STATUS_INVALID_PARAMETER
;
302 if (fsp
->write_time_forced
) {
303 DEBUG(10,("close_remove_share_mode: write time forced "
306 set_close_write_time(fsp
, lck
->changed_write_time
);
307 } else if (fsp
->update_write_time_on_close
) {
308 /* Someone had a pending write. */
309 if (null_timespec(fsp
->close_write_time
)) {
310 DEBUG(10,("close_remove_share_mode: update to current time "
313 /* Update to current time due to "normal" write. */
314 set_close_write_time(fsp
, timespec_current());
316 DEBUG(10,("close_remove_share_mode: write time pending "
319 /* Update to time set on close call. */
320 set_close_write_time(fsp
, fsp
->close_write_time
);
324 if (!del_share_mode(lck
, fsp
)) {
325 DEBUG(0, ("close_remove_share_mode: Could not delete share "
326 "entry for file %s\n",
330 if (fsp
->initial_delete_on_close
&& (lck
->delete_token
== NULL
)) {
331 bool became_user
= False
;
333 /* Initial delete on close was set and no one else
334 * wrote a real delete on close. */
336 if (get_current_vuid(conn
) != fsp
->vuid
) {
337 become_user(conn
, fsp
->vuid
);
340 fsp
->delete_on_close
= true;
341 set_delete_on_close_lck(lck
, True
, get_current_utok(conn
));
347 delete_file
= lck
->delete_on_close
;
351 /* See if others still have the file open. If this is the
352 * case, then don't delete. If all opens are POSIX delete now. */
353 for (i
=0; i
<lck
->num_share_modes
; i
++) {
354 struct share_mode_entry
*e
= &lck
->share_modes
[i
];
355 if (is_valid_share_mode_entry(e
)) {
356 if (fsp
->posix_open
&& (e
->flags
& SHARE_MODE_FLAG_POSIX_OPEN
)) {
365 /* Notify any deferred opens waiting on this close. */
366 notify_deferred_opens(conn
->sconn
->msg_ctx
, lck
);
367 reply_to_oplock_break_requests(fsp
);
370 * NT can set delete_on_close of the last open
371 * reference to a file.
374 if (!(close_type
== NORMAL_CLOSE
|| close_type
== SHUTDOWN_CLOSE
)
376 || (lck
->delete_token
== NULL
)) {
382 * Ok, we have to delete the file
385 DEBUG(5,("close_remove_share_mode: file %s. Delete on close was set "
386 "- deleting file.\n", fsp_str_dbg(fsp
)));
389 * Don't try to update the write time when we delete the file
391 fsp
->update_write_time_on_close
= false;
393 if (!unix_token_equal(lck
->delete_token
, get_current_utok(conn
))) {
394 /* Become the user who requested the delete. */
396 DEBUG(5,("close_remove_share_mode: file %s. "
397 "Change user to uid %u\n",
399 (unsigned int)lck
->delete_token
->uid
));
401 if (!push_sec_ctx()) {
402 smb_panic("close_remove_share_mode: file %s. failed to push "
406 set_sec_ctx(lck
->delete_token
->uid
,
407 lck
->delete_token
->gid
,
408 lck
->delete_token
->ngroups
,
409 lck
->delete_token
->groups
,
415 /* We can only delete the file if the name we have is still valid and
416 hasn't been renamed. */
418 tmp_status
= vfs_stat_fsp(fsp
);
419 if (!NT_STATUS_IS_OK(tmp_status
)) {
420 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
421 "was set and stat failed with error %s\n",
422 fsp_str_dbg(fsp
), nt_errstr(tmp_status
)));
424 * Don't save the errno here, we ignore this error
429 id
= vfs_file_id_from_sbuf(conn
, &fsp
->fsp_name
->st
);
431 if (!file_id_equal(&fsp
->file_id
, &id
)) {
432 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
433 "was set and dev and/or inode does not match\n",
435 DEBUG(5,("close_remove_share_mode: file %s. stored file_id %s, "
438 file_id_string_tos(&fsp
->file_id
),
439 file_id_string_tos(&id
)));
441 * Don't save the errno here, we ignore this error
446 if ((conn
->fs_capabilities
& FILE_NAMED_STREAMS
)
447 && !is_ntfs_stream_smb_fname(fsp
->fsp_name
)) {
449 status
= delete_all_streams(conn
, fsp
->fsp_name
->base_name
);
451 if (!NT_STATUS_IS_OK(status
)) {
452 DEBUG(5, ("delete_all_streams failed: %s\n",
459 if (SMB_VFS_UNLINK(conn
, fsp
->fsp_name
) != 0) {
461 * This call can potentially fail as another smbd may
462 * have had the file open with delete on close set and
463 * deleted it when its last reference to this file
464 * went away. Hence we log this but not at debug level
468 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
469 "was set and unlink failed with error %s\n",
470 fsp_str_dbg(fsp
), strerror(errno
)));
472 status
= map_nt_error_from_unix(errno
);
475 notify_fname(conn
, NOTIFY_ACTION_REMOVED
,
476 FILE_NOTIFY_CHANGE_FILE_NAME
,
477 fsp
->fsp_name
->base_name
);
479 /* As we now have POSIX opens which can unlink
480 * with other open files we may have taken
481 * this code path with more than one share mode
482 * entry - ensure we only delete once by resetting
483 * the delete on close flag. JRA.
486 fsp
->delete_on_close
= false;
487 set_delete_on_close_lck(lck
, False
, NULL
);
500 void set_close_write_time(struct files_struct
*fsp
, struct timespec ts
)
502 DEBUG(6,("close_write_time: %s" , time_to_asc(convert_timespec_to_time_t(ts
))));
504 if (null_timespec(ts
)) {
507 fsp
->write_time_forced
= false;
508 fsp
->update_write_time_on_close
= true;
509 fsp
->close_write_time
= ts
;
512 static NTSTATUS
update_write_time_on_close(struct files_struct
*fsp
)
514 struct smb_file_time ft
;
516 struct share_mode_lock
*lck
= NULL
;
520 if (!fsp
->update_write_time_on_close
) {
524 if (null_timespec(fsp
->close_write_time
)) {
525 fsp
->close_write_time
= timespec_current();
528 /* Ensure we have a valid stat struct for the source. */
529 status
= vfs_stat_fsp(fsp
);
530 if (!NT_STATUS_IS_OK(status
)) {
534 if (!VALID_STAT(fsp
->fsp_name
->st
)) {
535 /* if it doesn't seem to be a real file */
539 /* On close if we're changing the real file time we
540 * must update it in the open file db too. */
541 (void)set_write_time(fsp
->file_id
, fsp
->close_write_time
);
543 lck
= get_share_mode_lock(talloc_tos(), fsp
->file_id
, NULL
, NULL
, NULL
);
545 /* Close write times overwrite sticky write times
546 so we must replace any sticky write time here. */
547 if (!null_timespec(lck
->changed_write_time
)) {
548 (void)set_sticky_write_time(fsp
->file_id
, fsp
->close_write_time
);
553 ft
.mtime
= fsp
->close_write_time
;
554 status
= smb_set_file_time(fsp
->conn
, fsp
, fsp
->fsp_name
, &ft
, false);
555 if (!NT_STATUS_IS_OK(status
)) {
562 static NTSTATUS
ntstatus_keeperror(NTSTATUS s1
, NTSTATUS s2
)
564 if (!NT_STATUS_IS_OK(s1
)) {
570 /****************************************************************************
573 close_type can be NORMAL_CLOSE=0,SHUTDOWN_CLOSE,ERROR_CLOSE.
574 printing and magic scripts are only run on normal close.
575 delete on close is done on normal and shutdown close.
576 ****************************************************************************/
578 static NTSTATUS
close_normal_file(struct smb_request
*req
, files_struct
*fsp
,
579 enum file_close_type close_type
)
581 NTSTATUS status
= NT_STATUS_OK
;
583 connection_struct
*conn
= fsp
->conn
;
585 if (close_type
== ERROR_CLOSE
) {
586 cancel_aio_by_fsp(fsp
);
589 * If we're finishing async io on a close we can get a write
590 * error here, we must remember this.
592 int ret
= wait_for_aio_completion(fsp
);
594 status
= ntstatus_keeperror(
595 status
, map_nt_error_from_unix(ret
));
600 * If we're flushing on a close we can get a write
601 * error here, we must remember this.
604 tmp
= close_filestruct(fsp
);
605 status
= ntstatus_keeperror(status
, tmp
);
607 if (fsp
->print_file
) {
608 /* FIXME: return spool errors */
609 print_spool_end(fsp
, close_type
);
614 /* Remove the oplock before potentially deleting the file. */
615 if(fsp
->oplock_type
) {
616 release_file_oplock(fsp
);
619 /* If this is an old DOS or FCB open and we have multiple opens on
620 the same handle we only have one share mode. Ensure we only remove
621 the share mode on the last close. */
623 if (fsp
->fh
->ref_count
== 1) {
624 /* Should we return on error here... ? */
625 tmp
= close_remove_share_mode(fsp
, close_type
);
626 status
= ntstatus_keeperror(status
, tmp
);
629 locking_close_file(conn
->sconn
->msg_ctx
, fsp
, close_type
);
632 status
= ntstatus_keeperror(status
, tmp
);
634 /* check for magic scripts */
635 if (close_type
== NORMAL_CLOSE
) {
636 tmp
= check_magic(fsp
);
637 status
= ntstatus_keeperror(status
, tmp
);
641 * Ensure pending modtime is set after close.
644 tmp
= update_write_time_on_close(fsp
);
645 if (NT_STATUS_EQUAL(tmp
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
646 /* Someone renamed the file or a parent directory containing
647 * this file. We can't do anything about this, we don't have
648 * an "update timestamp by fd" call in POSIX. Eat the error. */
653 status
= ntstatus_keeperror(status
, tmp
);
655 DEBUG(2,("%s closed file %s (numopen=%d) %s\n",
656 conn
->server_info
->unix_name
, fsp_str_dbg(fsp
),
657 conn
->num_files_open
- 1,
658 nt_errstr(status
) ));
663 /****************************************************************************
664 Static function used by reply_rmdir to delete an entire directory
665 tree recursively. Return True on ok, False on fail.
666 ****************************************************************************/
668 static bool recursive_rmdir(TALLOC_CTX
*ctx
,
669 connection_struct
*conn
,
670 struct smb_filename
*smb_dname
)
672 const char *dname
= NULL
;
673 char *talloced
= NULL
;
677 struct smb_Dir
*dir_hnd
;
679 SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname
));
681 dir_hnd
= OpenDir(talloc_tos(), conn
, smb_dname
->base_name
, NULL
, 0);
685 while((dname
= ReadDirName(dir_hnd
, &offset
, &st
, &talloced
))) {
686 struct smb_filename
*smb_dname_full
= NULL
;
687 char *fullname
= NULL
;
688 bool do_break
= true;
691 if (ISDOT(dname
) || ISDOTDOT(dname
)) {
692 TALLOC_FREE(talloced
);
696 if (!is_visible_file(conn
, smb_dname
->base_name
, dname
, &st
,
698 TALLOC_FREE(talloced
);
702 /* Construct the full name. */
703 fullname
= talloc_asprintf(ctx
,
705 smb_dname
->base_name
,
712 status
= create_synthetic_smb_fname(talloc_tos(), fullname
,
715 if (!NT_STATUS_IS_OK(status
)) {
719 if(SMB_VFS_LSTAT(conn
, smb_dname_full
) != 0) {
723 if(smb_dname_full
->st
.st_ex_mode
& S_IFDIR
) {
724 if(!recursive_rmdir(ctx
, conn
, smb_dname_full
)) {
727 if(SMB_VFS_RMDIR(conn
,
728 smb_dname_full
->base_name
) != 0) {
731 } else if(SMB_VFS_UNLINK(conn
, smb_dname_full
) != 0) {
735 /* Successful iteration. */
739 TALLOC_FREE(smb_dname_full
);
740 TALLOC_FREE(fullname
);
741 TALLOC_FREE(talloced
);
747 TALLOC_FREE(dir_hnd
);
751 /****************************************************************************
752 The internals of the rmdir code - called elsewhere.
753 ****************************************************************************/
755 static NTSTATUS
rmdir_internals(TALLOC_CTX
*ctx
, files_struct
*fsp
)
757 connection_struct
*conn
= fsp
->conn
;
758 struct smb_filename
*smb_dname
= fsp
->fsp_name
;
761 SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname
));
763 /* Might be a symlink. */
764 if(SMB_VFS_LSTAT(conn
, smb_dname
) != 0) {
765 return map_nt_error_from_unix(errno
);
768 if (S_ISLNK(smb_dname
->st
.st_ex_mode
)) {
769 /* Is what it points to a directory ? */
770 if(SMB_VFS_STAT(conn
, smb_dname
) != 0) {
771 return map_nt_error_from_unix(errno
);
773 if (!(S_ISDIR(smb_dname
->st
.st_ex_mode
))) {
774 return NT_STATUS_NOT_A_DIRECTORY
;
776 ret
= SMB_VFS_UNLINK(conn
, smb_dname
);
778 ret
= SMB_VFS_RMDIR(conn
, smb_dname
->base_name
);
781 notify_fname(conn
, NOTIFY_ACTION_REMOVED
,
782 FILE_NOTIFY_CHANGE_DIR_NAME
,
783 smb_dname
->base_name
);
787 if(((errno
== ENOTEMPTY
)||(errno
== EEXIST
)) && lp_veto_files(SNUM(conn
))) {
789 * Check to see if the only thing in this directory are
790 * vetoed files/directories. If so then delete them and
791 * retry. If we fail to delete any of them (and we *don't*
792 * do a recursive delete) then fail the rmdir.
795 const char *dname
= NULL
;
796 char *talloced
= NULL
;
798 struct smb_Dir
*dir_hnd
= OpenDir(talloc_tos(), conn
,
799 smb_dname
->base_name
, NULL
,
802 if(dir_hnd
== NULL
) {
807 while ((dname
= ReadDirName(dir_hnd
, &dirpos
, &st
,
808 &talloced
)) != NULL
) {
809 if((strcmp(dname
, ".") == 0) || (strcmp(dname
, "..")==0)) {
810 TALLOC_FREE(talloced
);
813 if (!is_visible_file(conn
, smb_dname
->base_name
, dname
,
815 TALLOC_FREE(talloced
);
818 if(!IS_VETO_PATH(conn
, dname
)) {
819 TALLOC_FREE(dir_hnd
);
820 TALLOC_FREE(talloced
);
824 TALLOC_FREE(talloced
);
827 /* We only have veto files/directories.
828 * Are we allowed to delete them ? */
830 if(!lp_recursive_veto_delete(SNUM(conn
))) {
831 TALLOC_FREE(dir_hnd
);
836 /* Do a recursive delete. */
837 RewindDir(dir_hnd
,&dirpos
);
838 while ((dname
= ReadDirName(dir_hnd
, &dirpos
, &st
,
839 &talloced
)) != NULL
) {
840 struct smb_filename
*smb_dname_full
= NULL
;
841 char *fullname
= NULL
;
842 bool do_break
= true;
845 if (ISDOT(dname
) || ISDOTDOT(dname
)) {
846 TALLOC_FREE(talloced
);
849 if (!is_visible_file(conn
, smb_dname
->base_name
, dname
,
851 TALLOC_FREE(talloced
);
855 fullname
= talloc_asprintf(ctx
,
857 smb_dname
->base_name
,
865 status
= create_synthetic_smb_fname(talloc_tos(),
869 if (!NT_STATUS_IS_OK(status
)) {
870 errno
= map_errno_from_nt_status(status
);
874 if(SMB_VFS_LSTAT(conn
, smb_dname_full
) != 0) {
877 if(smb_dname_full
->st
.st_ex_mode
& S_IFDIR
) {
878 if(!recursive_rmdir(ctx
, conn
,
882 if(SMB_VFS_RMDIR(conn
,
883 smb_dname_full
->base_name
) != 0) {
886 } else if(SMB_VFS_UNLINK(conn
, smb_dname_full
) != 0) {
890 /* Successful iteration. */
894 TALLOC_FREE(fullname
);
895 TALLOC_FREE(smb_dname_full
);
896 TALLOC_FREE(talloced
);
900 TALLOC_FREE(dir_hnd
);
901 /* Retry the rmdir */
902 ret
= SMB_VFS_RMDIR(conn
, smb_dname
->base_name
);
908 DEBUG(3,("rmdir_internals: couldn't remove directory %s : "
909 "%s\n", smb_fname_str_dbg(smb_dname
),
911 return map_nt_error_from_unix(errno
);
914 notify_fname(conn
, NOTIFY_ACTION_REMOVED
,
915 FILE_NOTIFY_CHANGE_DIR_NAME
,
916 smb_dname
->base_name
);
921 /****************************************************************************
922 Close a directory opened by an NT SMB call.
923 ****************************************************************************/
925 static NTSTATUS
close_directory(struct smb_request
*req
, files_struct
*fsp
,
926 enum file_close_type close_type
)
928 struct share_mode_lock
*lck
= NULL
;
929 bool delete_dir
= False
;
930 NTSTATUS status
= NT_STATUS_OK
;
931 NTSTATUS status1
= NT_STATUS_OK
;
934 * NT can set delete_on_close of the last open
935 * reference to a directory also.
938 lck
= get_share_mode_lock(talloc_tos(), fsp
->file_id
, NULL
, NULL
,
942 DEBUG(0, ("close_directory: Could not get share mode lock for "
943 "%s\n", fsp_str_dbg(fsp
)));
944 status
= NT_STATUS_INVALID_PARAMETER
;
948 if (!del_share_mode(lck
, fsp
)) {
949 DEBUG(0, ("close_directory: Could not delete share entry for "
950 "%s\n", fsp_str_dbg(fsp
)));
953 if (fsp
->initial_delete_on_close
) {
954 bool became_user
= False
;
956 /* Initial delete on close was set - for
957 * directories we don't care if anyone else
958 * wrote a real delete on close. */
960 if (get_current_vuid(fsp
->conn
) != fsp
->vuid
) {
961 become_user(fsp
->conn
, fsp
->vuid
);
964 send_stat_cache_delete_message(fsp
->conn
->sconn
->msg_ctx
,
965 fsp
->fsp_name
->base_name
);
966 set_delete_on_close_lck(lck
, True
, get_current_utok(fsp
->conn
));
967 fsp
->delete_on_close
= true;
973 delete_dir
= lck
->delete_on_close
;
977 /* See if others still have the dir open. If this is the
978 * case, then don't delete. If all opens are POSIX delete now. */
979 for (i
=0; i
<lck
->num_share_modes
; i
++) {
980 struct share_mode_entry
*e
= &lck
->share_modes
[i
];
981 if (is_valid_share_mode_entry(e
)) {
982 if (fsp
->posix_open
&& (e
->flags
& SHARE_MODE_FLAG_POSIX_OPEN
)) {
991 if ((close_type
== NORMAL_CLOSE
|| close_type
== SHUTDOWN_CLOSE
) &&
995 /* Become the user who requested the delete. */
997 if (!push_sec_ctx()) {
998 smb_panic("close_directory: failed to push sec_ctx.\n");
1001 set_sec_ctx(lck
->delete_token
->uid
,
1002 lck
->delete_token
->gid
,
1003 lck
->delete_token
->ngroups
,
1004 lck
->delete_token
->groups
,
1009 status
= rmdir_internals(talloc_tos(), fsp
);
1011 DEBUG(5,("close_directory: %s. Delete on close was set - "
1012 "deleting directory returned %s.\n",
1013 fsp_str_dbg(fsp
), nt_errstr(status
)));
1015 /* unbecome user. */
1019 * Ensure we remove any change notify requests that would
1020 * now fail as the directory has been deleted.
1023 if(NT_STATUS_IS_OK(status
)) {
1024 remove_pending_change_notify_requests_by_fid(fsp
, NT_STATUS_DELETE_PENDING
);
1028 remove_pending_change_notify_requests_by_fid(
1032 status1
= fd_close(fsp
);
1034 if (!NT_STATUS_IS_OK(status1
)) {
1035 DEBUG(0, ("Could not close dir! fname=%s, fd=%d, err=%d=%s\n",
1036 fsp_str_dbg(fsp
), fsp
->fh
->fd
, errno
,
1041 dptr_CloseDir(fsp
->dptr
);
1045 * Do the code common to files and directories.
1047 close_filestruct(fsp
);
1048 file_free(req
, fsp
);
1052 if (NT_STATUS_IS_OK(status
) && !NT_STATUS_IS_OK(status1
)) {
1058 /****************************************************************************
1059 Close a files_struct.
1060 ****************************************************************************/
1062 NTSTATUS
close_file(struct smb_request
*req
, files_struct
*fsp
,
1063 enum file_close_type close_type
)
1066 struct files_struct
*base_fsp
= fsp
->base_fsp
;
1068 if(fsp
->is_directory
) {
1069 status
= close_directory(req
, fsp
, close_type
);
1070 } else if (fsp
->fake_file_handle
!= NULL
) {
1071 status
= close_fake_file(req
, fsp
);
1073 status
= close_normal_file(req
, fsp
, close_type
);
1076 if ((base_fsp
!= NULL
) && (close_type
!= SHUTDOWN_CLOSE
)) {
1079 * fsp was a stream, the base fsp can't be a stream as well
1081 * For SHUTDOWN_CLOSE this is not possible here, because
1082 * SHUTDOWN_CLOSE only happens from files.c which walks the
1083 * complete list of files. If we mess with more than one fsp
1084 * those loops will become confused.
1087 SMB_ASSERT(base_fsp
->base_fsp
== NULL
);
1088 close_file(req
, base_fsp
, close_type
);
1094 /****************************************************************************
1095 Deal with an (authorized) message to close a file given the share mode
1097 ****************************************************************************/
1099 void msg_close_file(struct messaging_context
*msg_ctx
,
1102 struct server_id server_id
,
1105 files_struct
*fsp
= NULL
;
1106 struct share_mode_entry e
;
1108 message_to_share_mode_entry(&e
, (char *)data
->data
);
1111 char *sm_str
= share_mode_str(NULL
, 0, &e
);
1113 smb_panic("talloc failed");
1115 DEBUG(10,("msg_close_file: got request to close share mode "
1116 "entry %s\n", sm_str
));
1117 TALLOC_FREE(sm_str
);
1120 fsp
= file_find_dif(e
.id
, e
.share_file_id
);
1122 DEBUG(10,("msg_close_file: failed to find file.\n"));
1125 close_file(NULL
, fsp
, NORMAL_CLOSE
);