Fix bug 9811 - Old DOS SMB CTEMP request uses a non-VFS function to access the filesy...
[Samba.git] / source3 / smbd / close.c
blob36cec1ae9cc8878aba3d6772097b42d5e29fa4be
1 /*
2 Unix SMB/CIFS implementation.
3 file closing
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/>.
22 #include "includes.h"
23 #include "system/filesys.h"
24 #include "printing.h"
25 #include "smbd/smbd.h"
26 #include "smbd/globals.h"
27 #include "fake_file.h"
28 #include "transfer_file.h"
29 #include "auth.h"
30 #include "messages.h"
32 /****************************************************************************
33 Run a file if it is a magic script.
34 ****************************************************************************/
36 static NTSTATUS check_magic(struct files_struct *fsp)
38 int ret;
39 const char *magic_output = NULL;
40 SMB_STRUCT_STAT st;
41 int tmp_fd, outfd;
42 TALLOC_CTX *ctx = NULL;
43 const char *p;
44 struct connection_struct *conn = fsp->conn;
45 char *fname = NULL;
46 NTSTATUS status;
48 if (!*lp_magicscript(SNUM(conn))) {
49 return NT_STATUS_OK;
52 DEBUG(5,("checking magic for %s\n", fsp_str_dbg(fsp)));
54 ctx = talloc_stackframe();
56 fname = fsp->fsp_name->base_name;
58 if (!(p = strrchr_m(fname,'/'))) {
59 p = fname;
60 } else {
61 p++;
64 if (!strequal(lp_magicscript(SNUM(conn)),p)) {
65 status = NT_STATUS_OK;
66 goto out;
69 if (*lp_magicoutput(SNUM(conn))) {
70 magic_output = lp_magicoutput(SNUM(conn));
71 } else {
72 magic_output = talloc_asprintf(ctx,
73 "%s.out",
74 fname);
76 if (!magic_output) {
77 status = NT_STATUS_NO_MEMORY;
78 goto out;
81 /* Ensure we don't depend on user's PATH. */
82 p = talloc_asprintf(ctx, "./%s", fname);
83 if (!p) {
84 status = NT_STATUS_NO_MEMORY;
85 goto out;
88 if (chmod(fname, 0755) == -1) {
89 status = map_nt_error_from_unix(errno);
90 goto out;
92 ret = smbrun(p,&tmp_fd);
93 DEBUG(3,("Invoking magic command %s gave %d\n",
94 p,ret));
96 unlink(fname);
97 if (ret != 0 || tmp_fd == -1) {
98 if (tmp_fd != -1) {
99 close(tmp_fd);
101 status = NT_STATUS_UNSUCCESSFUL;
102 goto out;
104 outfd = open(magic_output, O_CREAT|O_EXCL|O_RDWR, 0600);
105 if (outfd == -1) {
106 int err = errno;
107 close(tmp_fd);
108 status = map_nt_error_from_unix(err);
109 goto out;
112 if (sys_fstat(tmp_fd, &st, false) == -1) {
113 int err = errno;
114 close(tmp_fd);
115 close(outfd);
116 status = map_nt_error_from_unix(err);
117 goto out;
120 if (transfer_file(tmp_fd,outfd,(SMB_OFF_T)st.st_ex_size) == (SMB_OFF_T)-1) {
121 int err = errno;
122 close(tmp_fd);
123 close(outfd);
124 status = map_nt_error_from_unix(err);
125 goto out;
127 close(tmp_fd);
128 if (close(outfd) == -1) {
129 status = map_nt_error_from_unix(errno);
130 goto out;
133 status = NT_STATUS_OK;
135 out:
136 TALLOC_FREE(ctx);
137 return status;
140 /****************************************************************************
141 Common code to close a file or a directory.
142 ****************************************************************************/
144 static NTSTATUS close_filestruct(files_struct *fsp)
146 NTSTATUS status = NT_STATUS_OK;
148 if (fsp->fh->fd != -1) {
149 if(flush_write_cache(fsp, CLOSE_FLUSH) == -1) {
150 status = map_nt_error_from_unix(errno);
152 delete_write_cache(fsp);
155 return status;
158 /****************************************************************************
159 If any deferred opens are waiting on this close, notify them.
160 ****************************************************************************/
162 static void notify_deferred_opens(struct messaging_context *msg_ctx,
163 struct share_mode_lock *lck)
165 int i;
167 if (!should_notify_deferred_opens()) {
168 return;
171 for (i=0; i<lck->num_share_modes; i++) {
172 struct share_mode_entry *e = &lck->share_modes[i];
174 if (!is_deferred_open_entry(e)) {
175 continue;
178 if (procid_is_me(&e->pid)) {
180 * We need to notify ourself to retry the open. Do
181 * this by finding the queued SMB record, moving it to
182 * the head of the queue and changing the wait time to
183 * zero.
185 schedule_deferred_open_message_smb(e->op_mid);
186 } else {
187 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
189 share_mode_entry_to_message(msg, e);
191 messaging_send_buf(msg_ctx, e->pid, MSG_SMB_OPEN_RETRY,
192 (uint8 *)msg,
193 MSG_SMB_SHARE_MODE_ENTRY_SIZE);
198 /****************************************************************************
199 Delete all streams
200 ****************************************************************************/
202 NTSTATUS delete_all_streams(connection_struct *conn, const char *fname)
204 struct stream_struct *stream_info = NULL;
205 int i;
206 unsigned int num_streams = 0;
207 TALLOC_CTX *frame = talloc_stackframe();
208 NTSTATUS status;
210 status = vfs_streaminfo(conn, NULL, fname, talloc_tos(),
211 &num_streams, &stream_info);
213 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
214 DEBUG(10, ("no streams around\n"));
215 TALLOC_FREE(frame);
216 return NT_STATUS_OK;
219 if (!NT_STATUS_IS_OK(status)) {
220 DEBUG(10, ("vfs_streaminfo failed: %s\n",
221 nt_errstr(status)));
222 goto fail;
225 DEBUG(10, ("delete_all_streams found %d streams\n",
226 num_streams));
228 if (num_streams == 0) {
229 TALLOC_FREE(frame);
230 return NT_STATUS_OK;
233 for (i=0; i<num_streams; i++) {
234 int res;
235 struct smb_filename *smb_fname_stream = NULL;
237 if (strequal(stream_info[i].name, "::$DATA")) {
238 continue;
241 status = create_synthetic_smb_fname(talloc_tos(), fname,
242 stream_info[i].name, NULL,
243 &smb_fname_stream);
245 if (!NT_STATUS_IS_OK(status)) {
246 DEBUG(0, ("talloc_aprintf failed\n"));
247 goto fail;
250 res = SMB_VFS_UNLINK(conn, smb_fname_stream);
252 if (res == -1) {
253 status = map_nt_error_from_unix(errno);
254 DEBUG(10, ("Could not delete stream %s: %s\n",
255 smb_fname_str_dbg(smb_fname_stream),
256 strerror(errno)));
257 TALLOC_FREE(smb_fname_stream);
258 break;
260 TALLOC_FREE(smb_fname_stream);
263 fail:
264 TALLOC_FREE(frame);
265 return status;
268 /****************************************************************************
269 Deal with removing a share mode on last close.
270 ****************************************************************************/
272 static NTSTATUS close_remove_share_mode(files_struct *fsp,
273 enum file_close_type close_type)
275 connection_struct *conn = fsp->conn;
276 bool delete_file = false;
277 bool changed_user = false;
278 struct share_mode_lock *lck = NULL;
279 NTSTATUS status = NT_STATUS_OK;
280 NTSTATUS tmp_status;
281 struct file_id id;
282 const struct security_unix_token *del_token = NULL;
283 const struct security_token *del_nt_token = NULL;
284 bool got_tokens = false;
286 /* Ensure any pending write time updates are done. */
287 if (fsp->update_write_time_event) {
288 update_write_time_handler(smbd_event_context(),
289 fsp->update_write_time_event,
290 timeval_current(),
291 (void *)fsp);
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,
301 NULL);
303 if (lck == 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;
307 goto done;
310 if (fsp->write_time_forced) {
311 DEBUG(10,("close_remove_share_mode: write time forced "
312 "for file %s\n",
313 fsp_str_dbg(fsp)));
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 "
319 "for file %s\n",
320 fsp_str_dbg(fsp)));
321 /* Update to current time due to "normal" write. */
322 set_close_write_time(fsp, timespec_current());
323 } else {
324 DEBUG(10,("close_remove_share_mode: write time pending "
325 "for file %s\n",
326 fsp_str_dbg(fsp)));
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",
335 fsp_str_dbg(fsp)));
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);
347 became_user = True;
349 fsp->delete_on_close = true;
350 set_delete_on_close_lck(fsp, lck, True,
351 get_current_nttok(conn),
352 get_current_utok(conn));
353 if (became_user) {
354 unbecome_user();
358 delete_file = is_delete_on_close_set(lck, fsp->name_hash);
360 if (delete_file) {
361 int i;
362 /* See if others still have the file open via this pathname.
363 If this is the case, then don't delete. If all opens are
364 POSIX delete now. */
365 for (i=0; i<lck->num_share_modes; i++) {
366 struct share_mode_entry *e = &lck->share_modes[i];
367 if (is_valid_share_mode_entry(e) &&
368 e->name_hash == fsp->name_hash) {
369 if (fsp->posix_open && (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) {
370 continue;
372 delete_file = False;
373 break;
378 /* Notify any deferred opens waiting on this close. */
379 notify_deferred_opens(conn->sconn->msg_ctx, lck);
380 reply_to_oplock_break_requests(fsp);
383 * NT can set delete_on_close of the last open
384 * reference to a file.
387 if (!(close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) ||
388 !delete_file) {
389 TALLOC_FREE(lck);
390 return NT_STATUS_OK;
394 * Ok, we have to delete the file
397 DEBUG(5,("close_remove_share_mode: file %s. Delete on close was set "
398 "- deleting file.\n", fsp_str_dbg(fsp)));
401 * Don't try to update the write time when we delete the file
403 fsp->update_write_time_on_close = false;
405 got_tokens = get_delete_on_close_token(lck, fsp->name_hash,
406 &del_nt_token, &del_token);
407 SMB_ASSERT(got_tokens);
409 if (!unix_token_equal(del_token, get_current_utok(conn))) {
410 /* Become the user who requested the delete. */
412 DEBUG(5,("close_remove_share_mode: file %s. "
413 "Change user to uid %u\n",
414 fsp_str_dbg(fsp),
415 (unsigned int)del_token->uid));
417 if (!push_sec_ctx()) {
418 smb_panic("close_remove_share_mode: file %s. failed to push "
419 "sec_ctx.\n");
422 set_sec_ctx(del_token->uid,
423 del_token->gid,
424 del_token->ngroups,
425 del_token->groups,
426 del_nt_token);
428 changed_user = true;
431 /* We can only delete the file if the name we have is still valid and
432 hasn't been renamed. */
434 tmp_status = vfs_stat_fsp(fsp);
435 if (!NT_STATUS_IS_OK(tmp_status)) {
436 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
437 "was set and stat failed with error %s\n",
438 fsp_str_dbg(fsp), nt_errstr(tmp_status)));
440 * Don't save the errno here, we ignore this error
442 goto done;
445 id = vfs_file_id_from_sbuf(conn, &fsp->fsp_name->st);
447 if (!file_id_equal(&fsp->file_id, &id)) {
448 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
449 "was set and dev and/or inode does not match\n",
450 fsp_str_dbg(fsp)));
451 DEBUG(5,("close_remove_share_mode: file %s. stored file_id %s, "
452 "stat file_id %s\n",
453 fsp_str_dbg(fsp),
454 file_id_string_tos(&fsp->file_id),
455 file_id_string_tos(&id)));
457 * Don't save the errno here, we ignore this error
459 goto done;
462 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
463 && !is_ntfs_stream_smb_fname(fsp->fsp_name)) {
465 status = delete_all_streams(conn, fsp->fsp_name->base_name);
467 if (!NT_STATUS_IS_OK(status)) {
468 DEBUG(5, ("delete_all_streams failed: %s\n",
469 nt_errstr(status)));
470 goto done;
475 if (SMB_VFS_UNLINK(conn, fsp->fsp_name) != 0) {
477 * This call can potentially fail as another smbd may
478 * have had the file open with delete on close set and
479 * deleted it when its last reference to this file
480 * went away. Hence we log this but not at debug level
481 * zero.
484 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
485 "was set and unlink failed with error %s\n",
486 fsp_str_dbg(fsp), strerror(errno)));
488 status = map_nt_error_from_unix(errno);
491 /* As we now have POSIX opens which can unlink
492 * with other open files we may have taken
493 * this code path with more than one share mode
494 * entry - ensure we only delete once by resetting
495 * the delete on close flag. JRA.
498 fsp->delete_on_close = false;
499 set_delete_on_close_lck(fsp, lck, false, NULL, NULL);
501 done:
503 if (changed_user) {
504 /* unbecome user. */
505 pop_sec_ctx();
508 TALLOC_FREE(lck);
510 if (delete_file) {
512 * Do the notification after we released the share
513 * mode lock. Inside notify_fname we take out another
514 * tdb lock. With ctdb also accessing our databases,
515 * this can lead to deadlocks. Putting this notify
516 * after the TALLOC_FREE(lck) above we avoid locking
517 * two records simultaneously. Notifies are async and
518 * informational only, so calling the notify_fname
519 * without holding the share mode lock should not do
520 * any harm.
522 notify_fname(conn, NOTIFY_ACTION_REMOVED,
523 FILE_NOTIFY_CHANGE_FILE_NAME,
524 fsp->fsp_name->base_name);
527 return status;
530 void set_close_write_time(struct files_struct *fsp, struct timespec ts)
532 DEBUG(6,("close_write_time: %s" , time_to_asc(convert_timespec_to_time_t(ts))));
534 if (null_timespec(ts)) {
535 return;
537 fsp->write_time_forced = false;
538 fsp->update_write_time_on_close = true;
539 fsp->close_write_time = ts;
542 static NTSTATUS update_write_time_on_close(struct files_struct *fsp)
544 struct smb_file_time ft;
545 NTSTATUS status;
546 struct share_mode_lock *lck = NULL;
548 ZERO_STRUCT(ft);
550 if (!fsp->update_write_time_on_close) {
551 return NT_STATUS_OK;
554 if (null_timespec(fsp->close_write_time)) {
555 fsp->close_write_time = timespec_current();
558 /* Ensure we have a valid stat struct for the source. */
559 status = vfs_stat_fsp(fsp);
560 if (!NT_STATUS_IS_OK(status)) {
561 return status;
564 if (!VALID_STAT(fsp->fsp_name->st)) {
565 /* if it doesn't seem to be a real file */
566 return NT_STATUS_OK;
569 /* On close if we're changing the real file time we
570 * must update it in the open file db too. */
571 (void)set_write_time(fsp->file_id, fsp->close_write_time);
573 lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL, NULL);
574 if (lck) {
575 /* Close write times overwrite sticky write times
576 so we must replace any sticky write time here. */
577 if (!null_timespec(lck->changed_write_time)) {
578 (void)set_sticky_write_time(fsp->file_id, fsp->close_write_time);
580 TALLOC_FREE(lck);
583 ft.mtime = fsp->close_write_time;
584 /* We must use NULL for the fsp handle here, as smb_set_file_time()
585 checks the fsp access_mask, which may not include FILE_WRITE_ATTRIBUTES.
586 As this is a close based update, we are not directly changing the
587 file attributes from a client call, but indirectly from a write. */
588 status = smb_set_file_time(fsp->conn, NULL, fsp->fsp_name, &ft, false);
589 if (!NT_STATUS_IS_OK(status)) {
590 DEBUG(10,("update_write_time_on_close: smb_set_file_time "
591 "on file %s returned %s\n",
592 fsp_str_dbg(fsp),
593 nt_errstr(status)));
594 return status;
597 return status;
600 static NTSTATUS ntstatus_keeperror(NTSTATUS s1, NTSTATUS s2)
602 if (!NT_STATUS_IS_OK(s1)) {
603 return s1;
605 return s2;
608 /****************************************************************************
609 Close a file.
611 close_type can be NORMAL_CLOSE=0,SHUTDOWN_CLOSE,ERROR_CLOSE.
612 printing and magic scripts are only run on normal close.
613 delete on close is done on normal and shutdown close.
614 ****************************************************************************/
616 static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp,
617 enum file_close_type close_type)
619 NTSTATUS status = NT_STATUS_OK;
620 NTSTATUS tmp;
621 connection_struct *conn = fsp->conn;
623 if (close_type == ERROR_CLOSE) {
624 cancel_aio_by_fsp(fsp);
625 } else {
627 * If we're finishing async io on a close we can get a write
628 * error here, we must remember this.
630 int ret = wait_for_aio_completion(fsp);
631 if (ret) {
632 status = ntstatus_keeperror(
633 status, map_nt_error_from_unix(ret));
638 * If we're flushing on a close we can get a write
639 * error here, we must remember this.
642 tmp = close_filestruct(fsp);
643 status = ntstatus_keeperror(status, tmp);
645 if (fsp->print_file) {
646 /* FIXME: return spool errors */
647 print_spool_end(fsp, close_type);
648 file_free(req, fsp);
649 return NT_STATUS_OK;
652 /* Remove the oplock before potentially deleting the file. */
653 if(fsp->oplock_type) {
654 release_file_oplock(fsp);
657 /* If this is an old DOS or FCB open and we have multiple opens on
658 the same handle we only have one share mode. Ensure we only remove
659 the share mode on the last close. */
661 if (fsp->fh->ref_count == 1) {
662 /* Should we return on error here... ? */
663 tmp = close_remove_share_mode(fsp, close_type);
664 status = ntstatus_keeperror(status, tmp);
667 locking_close_file(conn->sconn->msg_ctx, fsp, close_type);
669 tmp = fd_close(fsp);
670 status = ntstatus_keeperror(status, tmp);
672 /* check for magic scripts */
673 if (close_type == NORMAL_CLOSE) {
674 tmp = check_magic(fsp);
675 status = ntstatus_keeperror(status, tmp);
679 * Ensure pending modtime is set after close.
682 tmp = update_write_time_on_close(fsp);
683 if (NT_STATUS_EQUAL(tmp, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
684 /* Someone renamed the file or a parent directory containing
685 * this file. We can't do anything about this, we don't have
686 * an "update timestamp by fd" call in POSIX. Eat the error. */
688 tmp = NT_STATUS_OK;
691 status = ntstatus_keeperror(status, tmp);
693 DEBUG(2,("%s closed file %s (numopen=%d) %s\n",
694 conn->session_info->unix_name, fsp_str_dbg(fsp),
695 conn->num_files_open - 1,
696 nt_errstr(status) ));
698 file_free(req, fsp);
699 return status;
701 /****************************************************************************
702 Static function used by reply_rmdir to delete an entire directory
703 tree recursively. Return True on ok, False on fail.
704 ****************************************************************************/
706 static bool recursive_rmdir(TALLOC_CTX *ctx,
707 connection_struct *conn,
708 struct smb_filename *smb_dname)
710 const char *dname = NULL;
711 char *talloced = NULL;
712 bool ret = True;
713 long offset = 0;
714 SMB_STRUCT_STAT st;
715 struct smb_Dir *dir_hnd;
717 SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
719 dir_hnd = OpenDir(talloc_tos(), conn, smb_dname->base_name, NULL, 0);
720 if(dir_hnd == NULL)
721 return False;
723 while((dname = ReadDirName(dir_hnd, &offset, &st, &talloced))) {
724 struct smb_filename *smb_dname_full = NULL;
725 char *fullname = NULL;
726 bool do_break = true;
727 NTSTATUS status;
729 if (ISDOT(dname) || ISDOTDOT(dname)) {
730 TALLOC_FREE(talloced);
731 continue;
734 if (!is_visible_file(conn, smb_dname->base_name, dname, &st,
735 false)) {
736 TALLOC_FREE(talloced);
737 continue;
740 /* Construct the full name. */
741 fullname = talloc_asprintf(ctx,
742 "%s/%s",
743 smb_dname->base_name,
744 dname);
745 if (!fullname) {
746 errno = ENOMEM;
747 goto err_break;
750 status = create_synthetic_smb_fname(talloc_tos(), fullname,
751 NULL, NULL,
752 &smb_dname_full);
753 if (!NT_STATUS_IS_OK(status)) {
754 goto err_break;
757 if(SMB_VFS_LSTAT(conn, smb_dname_full) != 0) {
758 goto err_break;
761 if(smb_dname_full->st.st_ex_mode & S_IFDIR) {
762 if(!recursive_rmdir(ctx, conn, smb_dname_full)) {
763 goto err_break;
765 if(SMB_VFS_RMDIR(conn,
766 smb_dname_full->base_name) != 0) {
767 goto err_break;
769 } else if(SMB_VFS_UNLINK(conn, smb_dname_full) != 0) {
770 goto err_break;
773 /* Successful iteration. */
774 do_break = false;
776 err_break:
777 TALLOC_FREE(smb_dname_full);
778 TALLOC_FREE(fullname);
779 TALLOC_FREE(talloced);
780 if (do_break) {
781 ret = false;
782 break;
785 TALLOC_FREE(dir_hnd);
786 return ret;
789 /****************************************************************************
790 The internals of the rmdir code - called elsewhere.
791 ****************************************************************************/
793 static NTSTATUS rmdir_internals(TALLOC_CTX *ctx, files_struct *fsp)
795 connection_struct *conn = fsp->conn;
796 struct smb_filename *smb_dname = fsp->fsp_name;
797 int ret;
799 SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
801 /* Might be a symlink. */
802 if(SMB_VFS_LSTAT(conn, smb_dname) != 0) {
803 return map_nt_error_from_unix(errno);
806 if (S_ISLNK(smb_dname->st.st_ex_mode)) {
807 /* Is what it points to a directory ? */
808 if(SMB_VFS_STAT(conn, smb_dname) != 0) {
809 return map_nt_error_from_unix(errno);
811 if (!(S_ISDIR(smb_dname->st.st_ex_mode))) {
812 return NT_STATUS_NOT_A_DIRECTORY;
814 ret = SMB_VFS_UNLINK(conn, smb_dname);
815 } else {
816 ret = SMB_VFS_RMDIR(conn, smb_dname->base_name);
818 if (ret == 0) {
819 notify_fname(conn, NOTIFY_ACTION_REMOVED,
820 FILE_NOTIFY_CHANGE_DIR_NAME,
821 smb_dname->base_name);
822 return NT_STATUS_OK;
825 if(((errno == ENOTEMPTY)||(errno == EEXIST)) && *lp_veto_files(SNUM(conn))) {
827 * Check to see if the only thing in this directory are
828 * vetoed files/directories. If so then delete them and
829 * retry. If we fail to delete any of them (and we *don't*
830 * do a recursive delete) then fail the rmdir.
832 SMB_STRUCT_STAT st;
833 const char *dname = NULL;
834 char *talloced = NULL;
835 long dirpos = 0;
836 struct smb_Dir *dir_hnd = OpenDir(talloc_tos(), conn,
837 smb_dname->base_name, NULL,
840 if(dir_hnd == NULL) {
841 errno = ENOTEMPTY;
842 goto err;
845 while ((dname = ReadDirName(dir_hnd, &dirpos, &st,
846 &talloced)) != NULL) {
847 if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0)) {
848 TALLOC_FREE(talloced);
849 continue;
851 if (!is_visible_file(conn, smb_dname->base_name, dname,
852 &st, false)) {
853 TALLOC_FREE(talloced);
854 continue;
856 if(!IS_VETO_PATH(conn, dname)) {
857 TALLOC_FREE(dir_hnd);
858 TALLOC_FREE(talloced);
859 errno = ENOTEMPTY;
860 goto err;
862 TALLOC_FREE(talloced);
865 /* We only have veto files/directories.
866 * Are we allowed to delete them ? */
868 if(!lp_recursive_veto_delete(SNUM(conn))) {
869 TALLOC_FREE(dir_hnd);
870 errno = ENOTEMPTY;
871 goto err;
874 /* Do a recursive delete. */
875 RewindDir(dir_hnd,&dirpos);
876 while ((dname = ReadDirName(dir_hnd, &dirpos, &st,
877 &talloced)) != NULL) {
878 struct smb_filename *smb_dname_full = NULL;
879 char *fullname = NULL;
880 bool do_break = true;
881 NTSTATUS status;
883 if (ISDOT(dname) || ISDOTDOT(dname)) {
884 TALLOC_FREE(talloced);
885 continue;
887 if (!is_visible_file(conn, smb_dname->base_name, dname,
888 &st, false)) {
889 TALLOC_FREE(talloced);
890 continue;
893 fullname = talloc_asprintf(ctx,
894 "%s/%s",
895 smb_dname->base_name,
896 dname);
898 if(!fullname) {
899 errno = ENOMEM;
900 goto err_break;
903 status = create_synthetic_smb_fname(talloc_tos(),
904 fullname, NULL,
905 NULL,
906 &smb_dname_full);
907 if (!NT_STATUS_IS_OK(status)) {
908 errno = map_errno_from_nt_status(status);
909 goto err_break;
912 if(SMB_VFS_LSTAT(conn, smb_dname_full) != 0) {
913 goto err_break;
915 if(smb_dname_full->st.st_ex_mode & S_IFDIR) {
916 if(!recursive_rmdir(ctx, conn,
917 smb_dname_full)) {
918 goto err_break;
920 if(SMB_VFS_RMDIR(conn,
921 smb_dname_full->base_name) != 0) {
922 goto err_break;
924 } else if(SMB_VFS_UNLINK(conn, smb_dname_full) != 0) {
925 goto err_break;
928 /* Successful iteration. */
929 do_break = false;
931 err_break:
932 TALLOC_FREE(fullname);
933 TALLOC_FREE(smb_dname_full);
934 TALLOC_FREE(talloced);
935 if (do_break)
936 break;
938 TALLOC_FREE(dir_hnd);
939 /* Retry the rmdir */
940 ret = SMB_VFS_RMDIR(conn, smb_dname->base_name);
943 err:
945 if (ret != 0) {
946 DEBUG(3,("rmdir_internals: couldn't remove directory %s : "
947 "%s\n", smb_fname_str_dbg(smb_dname),
948 strerror(errno)));
949 return map_nt_error_from_unix(errno);
952 notify_fname(conn, NOTIFY_ACTION_REMOVED,
953 FILE_NOTIFY_CHANGE_DIR_NAME,
954 smb_dname->base_name);
956 return NT_STATUS_OK;
959 /****************************************************************************
960 Close a directory opened by an NT SMB call.
961 ****************************************************************************/
963 static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
964 enum file_close_type close_type)
966 struct share_mode_lock *lck = NULL;
967 bool delete_dir = False;
968 NTSTATUS status = NT_STATUS_OK;
969 NTSTATUS status1 = NT_STATUS_OK;
970 const struct security_token *del_nt_token = NULL;
971 const struct security_unix_token *del_token = NULL;
974 * NT can set delete_on_close of the last open
975 * reference to a directory also.
978 lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL,
979 NULL);
981 if (lck == NULL) {
982 DEBUG(0, ("close_directory: Could not get share mode lock for "
983 "%s\n", fsp_str_dbg(fsp)));
984 status = NT_STATUS_INVALID_PARAMETER;
985 goto out;
988 if (!del_share_mode(lck, fsp)) {
989 DEBUG(0, ("close_directory: Could not delete share entry for "
990 "%s\n", fsp_str_dbg(fsp)));
993 if (fsp->initial_delete_on_close) {
994 bool became_user = False;
996 /* Initial delete on close was set - for
997 * directories we don't care if anyone else
998 * wrote a real delete on close. */
1000 if (get_current_vuid(fsp->conn) != fsp->vuid) {
1001 become_user(fsp->conn, fsp->vuid);
1002 became_user = True;
1004 send_stat_cache_delete_message(fsp->conn->sconn->msg_ctx,
1005 fsp->fsp_name->base_name);
1006 set_delete_on_close_lck(fsp, lck, true,
1007 get_current_nttok(fsp->conn),
1008 get_current_utok(fsp->conn));
1009 fsp->delete_on_close = true;
1010 if (became_user) {
1011 unbecome_user();
1015 delete_dir = get_delete_on_close_token(lck, fsp->name_hash,
1016 &del_nt_token, &del_token);
1018 if (delete_dir) {
1019 int i;
1020 /* See if others still have the dir open. If this is the
1021 * case, then don't delete. If all opens are POSIX delete now. */
1022 for (i=0; i<lck->num_share_modes; i++) {
1023 struct share_mode_entry *e = &lck->share_modes[i];
1024 if (is_valid_share_mode_entry(e) &&
1025 e->name_hash == fsp->name_hash) {
1026 if (fsp->posix_open && (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) {
1027 continue;
1029 delete_dir = False;
1030 break;
1035 if ((close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) &&
1036 delete_dir) {
1038 /* Become the user who requested the delete. */
1040 if (!push_sec_ctx()) {
1041 smb_panic("close_directory: failed to push sec_ctx.\n");
1044 set_sec_ctx(del_token->uid,
1045 del_token->gid,
1046 del_token->ngroups,
1047 del_token->groups,
1048 del_nt_token);
1050 TALLOC_FREE(lck);
1052 if ((fsp->conn->fs_capabilities & FILE_NAMED_STREAMS)
1053 && !is_ntfs_stream_smb_fname(fsp->fsp_name)) {
1055 status = delete_all_streams(fsp->conn, fsp->fsp_name->base_name);
1056 if (!NT_STATUS_IS_OK(status)) {
1057 DEBUG(5, ("delete_all_streams failed: %s\n",
1058 nt_errstr(status)));
1059 goto out;
1063 status = rmdir_internals(talloc_tos(), fsp);
1065 DEBUG(5,("close_directory: %s. Delete on close was set - "
1066 "deleting directory returned %s.\n",
1067 fsp_str_dbg(fsp), nt_errstr(status)));
1069 /* unbecome user. */
1070 pop_sec_ctx();
1073 * Ensure we remove any change notify requests that would
1074 * now fail as the directory has been deleted.
1077 if(NT_STATUS_IS_OK(status)) {
1078 remove_pending_change_notify_requests_by_fid(fsp, NT_STATUS_DELETE_PENDING);
1080 } else {
1081 TALLOC_FREE(lck);
1082 remove_pending_change_notify_requests_by_fid(
1083 fsp, NT_STATUS_OK);
1086 status1 = fd_close(fsp);
1088 if (!NT_STATUS_IS_OK(status1)) {
1089 DEBUG(0, ("Could not close dir! fname=%s, fd=%d, err=%d=%s\n",
1090 fsp_str_dbg(fsp), fsp->fh->fd, errno,
1091 strerror(errno)));
1095 * Do the code common to files and directories.
1097 close_filestruct(fsp);
1098 file_free(req, fsp);
1100 out:
1101 TALLOC_FREE(lck);
1102 if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(status1)) {
1103 status = status1;
1105 return status;
1108 /****************************************************************************
1109 Close a files_struct.
1110 ****************************************************************************/
1112 NTSTATUS close_file(struct smb_request *req, files_struct *fsp,
1113 enum file_close_type close_type)
1115 NTSTATUS status;
1116 struct files_struct *base_fsp = fsp->base_fsp;
1118 if(fsp->is_directory) {
1119 status = close_directory(req, fsp, close_type);
1120 } else if (fsp->fake_file_handle != NULL) {
1121 status = close_fake_file(req, fsp);
1122 } else {
1123 status = close_normal_file(req, fsp, close_type);
1126 if ((base_fsp != NULL) && (close_type != SHUTDOWN_CLOSE)) {
1129 * fsp was a stream, the base fsp can't be a stream as well
1131 * For SHUTDOWN_CLOSE this is not possible here, because
1132 * SHUTDOWN_CLOSE only happens from files.c which walks the
1133 * complete list of files. If we mess with more than one fsp
1134 * those loops will become confused.
1137 SMB_ASSERT(base_fsp->base_fsp == NULL);
1138 close_file(req, base_fsp, close_type);
1141 return status;
1144 /****************************************************************************
1145 Deal with an (authorized) message to close a file given the share mode
1146 entry.
1147 ****************************************************************************/
1149 void msg_close_file(struct messaging_context *msg_ctx,
1150 void *private_data,
1151 uint32_t msg_type,
1152 struct server_id server_id,
1153 DATA_BLOB *data)
1155 struct smbd_server_connection *sconn;
1156 files_struct *fsp = NULL;
1157 struct share_mode_entry e;
1159 sconn = msg_ctx_to_sconn(msg_ctx);
1160 if (sconn == NULL) {
1161 DEBUG(1, ("could not find sconn\n"));
1162 return;
1165 message_to_share_mode_entry(&e, (char *)data->data);
1167 if(DEBUGLVL(10)) {
1168 char *sm_str = share_mode_str(NULL, 0, &e);
1169 if (!sm_str) {
1170 smb_panic("talloc failed");
1172 DEBUG(10,("msg_close_file: got request to close share mode "
1173 "entry %s\n", sm_str));
1174 TALLOC_FREE(sm_str);
1177 fsp = file_find_dif(sconn, e.id, e.share_file_id);
1178 if (!fsp) {
1179 DEBUG(10,("msg_close_file: failed to find file.\n"));
1180 return;
1182 close_file(NULL, fsp, NORMAL_CLOSE);