s3: Check for serverid_exists in notify_deferred_opens
[Samba.git] / source3 / smbd / close.c
blob354a68c546c6a006fc549fde0db691b741343b27
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"
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)
39 int ret;
40 const char *magic_output = NULL;
41 SMB_STRUCT_STAT st;
42 int tmp_fd, outfd;
43 TALLOC_CTX *ctx = NULL;
44 const char *p;
45 struct connection_struct *conn = fsp->conn;
46 char *fname = NULL;
47 NTSTATUS status;
49 if (!*lp_magicscript(SNUM(conn))) {
50 return NT_STATUS_OK;
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,'/'))) {
60 p = fname;
61 } else {
62 p++;
65 if (!strequal(lp_magicscript(SNUM(conn)),p)) {
66 status = NT_STATUS_OK;
67 goto out;
70 if (*lp_magicoutput(SNUM(conn))) {
71 magic_output = lp_magicoutput(SNUM(conn));
72 } else {
73 magic_output = talloc_asprintf(ctx,
74 "%s.out",
75 fname);
77 if (!magic_output) {
78 status = NT_STATUS_NO_MEMORY;
79 goto out;
82 /* Ensure we don't depend on user's PATH. */
83 p = talloc_asprintf(ctx, "./%s", fname);
84 if (!p) {
85 status = NT_STATUS_NO_MEMORY;
86 goto out;
89 if (chmod(fname, 0755) == -1) {
90 status = map_nt_error_from_unix(errno);
91 goto out;
93 ret = smbrun(p,&tmp_fd);
94 DEBUG(3,("Invoking magic command %s gave %d\n",
95 p,ret));
97 unlink(fname);
98 if (ret != 0 || tmp_fd == -1) {
99 if (tmp_fd != -1) {
100 close(tmp_fd);
102 status = NT_STATUS_UNSUCCESSFUL;
103 goto out;
105 outfd = open(magic_output, O_CREAT|O_EXCL|O_RDWR, 0600);
106 if (outfd == -1) {
107 int err = errno;
108 close(tmp_fd);
109 status = map_nt_error_from_unix(err);
110 goto out;
113 if (sys_fstat(tmp_fd, &st, false) == -1) {
114 int err = errno;
115 close(tmp_fd);
116 close(outfd);
117 status = map_nt_error_from_unix(err);
118 goto out;
121 if (transfer_file(tmp_fd,outfd,(off_t)st.st_ex_size) == (off_t)-1) {
122 int err = errno;
123 close(tmp_fd);
124 close(outfd);
125 status = map_nt_error_from_unix(err);
126 goto out;
128 close(tmp_fd);
129 if (close(outfd) == -1) {
130 status = map_nt_error_from_unix(errno);
131 goto out;
134 status = NT_STATUS_OK;
136 out:
137 TALLOC_FREE(ctx);
138 return status;
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);
156 return status;
159 static int compare_share_mode_times(const void *p1, const void *p2)
161 const struct share_mode_entry *s1 = (const struct share_mode_entry *)p1;
162 const struct share_mode_entry *s2 = (const struct share_mode_entry *)p2;
163 return timeval_compare(&s1->time, &s2->time);
166 /****************************************************************************
167 If any deferred opens are waiting on this close, notify them.
168 ****************************************************************************/
170 static void notify_deferred_opens(struct smbd_server_connection *sconn,
171 struct share_mode_lock *lck)
173 uint32_t i, num_deferred;
174 struct share_mode_entry *deferred;
176 if (!should_notify_deferred_opens(sconn)) {
177 return;
180 num_deferred = 0;
181 for (i=0; i<lck->data->num_share_modes; i++) {
182 struct share_mode_entry *e = &lck->data->share_modes[i];
184 if (!is_deferred_open_entry(e)) {
185 continue;
187 if (share_mode_stale_pid(lck->data, i)) {
188 continue;
190 num_deferred += 1;
192 if (num_deferred == 0) {
193 return;
196 deferred = talloc_array(talloc_tos(), struct share_mode_entry,
197 num_deferred);
198 if (deferred == NULL) {
199 return;
202 num_deferred = 0;
203 for (i=0; i<lck->data->num_share_modes; i++) {
204 struct share_mode_entry *e = &lck->data->share_modes[i];
205 if (is_deferred_open_entry(e)) {
206 deferred[num_deferred] = *e;
207 num_deferred += 1;
212 * We need to sort the notifications by initial request time. Imagine
213 * two opens come in asyncronously, both conflicting with the open we
214 * just close here. If we don't sort the notifications, the one that
215 * came in last might get the response before the one that came in
216 * first. This is demonstrated with the smbtorture4 raw.mux test.
218 * As long as we had the UNUSED_SHARE_MODE_ENTRY, we happened to
219 * survive this particular test. Without UNUSED_SHARE_MODE_ENTRY, we
220 * shuffle the share mode entries around a bit, so that we do not
221 * survive raw.mux anymore.
223 * We could have kept the ordering in del_share_mode, but as the
224 * ordering was never formalized I think it is better to do it here
225 * where it is necessary.
228 qsort(deferred, num_deferred, sizeof(struct share_mode_entry),
229 compare_share_mode_times);
231 for (i=0; i<num_deferred; i++) {
232 struct share_mode_entry *e = &deferred[i];
234 if (procid_is_me(&e->pid)) {
236 * We need to notify ourself to retry the open. Do
237 * this by finding the queued SMB record, moving it to
238 * the head of the queue and changing the wait time to
239 * zero.
241 schedule_deferred_open_message_smb(sconn, e->op_mid);
242 } else {
243 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
245 share_mode_entry_to_message(msg, e);
247 messaging_send_buf(sconn->msg_ctx, e->pid,
248 MSG_SMB_OPEN_RETRY,
249 (uint8 *)msg,
250 MSG_SMB_SHARE_MODE_ENTRY_SIZE);
253 TALLOC_FREE(deferred);
256 /****************************************************************************
257 Delete all streams
258 ****************************************************************************/
260 NTSTATUS delete_all_streams(connection_struct *conn, const char *fname)
262 struct stream_struct *stream_info = NULL;
263 int i;
264 unsigned int num_streams = 0;
265 TALLOC_CTX *frame = talloc_stackframe();
266 NTSTATUS status;
268 status = vfs_streaminfo(conn, NULL, fname, talloc_tos(),
269 &num_streams, &stream_info);
271 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
272 DEBUG(10, ("no streams around\n"));
273 TALLOC_FREE(frame);
274 return NT_STATUS_OK;
277 if (!NT_STATUS_IS_OK(status)) {
278 DEBUG(10, ("vfs_streaminfo failed: %s\n",
279 nt_errstr(status)));
280 goto fail;
283 DEBUG(10, ("delete_all_streams found %d streams\n",
284 num_streams));
286 if (num_streams == 0) {
287 TALLOC_FREE(frame);
288 return NT_STATUS_OK;
291 for (i=0; i<num_streams; i++) {
292 int res;
293 struct smb_filename *smb_fname_stream = NULL;
295 if (strequal(stream_info[i].name, "::$DATA")) {
296 continue;
299 status = create_synthetic_smb_fname(talloc_tos(), fname,
300 stream_info[i].name, NULL,
301 &smb_fname_stream);
303 if (!NT_STATUS_IS_OK(status)) {
304 DEBUG(0, ("talloc_aprintf failed\n"));
305 goto fail;
308 res = SMB_VFS_UNLINK(conn, smb_fname_stream);
310 if (res == -1) {
311 status = map_nt_error_from_unix(errno);
312 DEBUG(10, ("Could not delete stream %s: %s\n",
313 smb_fname_str_dbg(smb_fname_stream),
314 strerror(errno)));
315 TALLOC_FREE(smb_fname_stream);
316 break;
318 TALLOC_FREE(smb_fname_stream);
321 fail:
322 TALLOC_FREE(frame);
323 return status;
326 /****************************************************************************
327 Deal with removing a share mode on last close.
328 ****************************************************************************/
330 static NTSTATUS close_remove_share_mode(files_struct *fsp,
331 enum file_close_type close_type)
333 connection_struct *conn = fsp->conn;
334 bool delete_file = false;
335 bool changed_user = false;
336 struct share_mode_lock *lck = NULL;
337 NTSTATUS status = NT_STATUS_OK;
338 NTSTATUS tmp_status;
339 struct file_id id;
340 const struct security_unix_token *del_token = NULL;
341 const struct security_token *del_nt_token = NULL;
342 bool got_tokens = false;
344 /* Ensure any pending write time updates are done. */
345 if (fsp->update_write_time_event) {
346 update_write_time_handler(fsp->conn->sconn->ev_ctx,
347 fsp->update_write_time_event,
348 timeval_current(),
349 (void *)fsp);
353 * Lock the share entries, and determine if we should delete
354 * on close. If so delete whilst the lock is still in effect.
355 * This prevents race conditions with the file being created. JRA.
358 lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
359 if (lck == NULL) {
360 DEBUG(0, ("close_remove_share_mode: Could not get share mode "
361 "lock for file %s\n", fsp_str_dbg(fsp)));
362 status = NT_STATUS_INVALID_PARAMETER;
363 goto done;
366 if (fsp->write_time_forced) {
367 DEBUG(10,("close_remove_share_mode: write time forced "
368 "for file %s\n",
369 fsp_str_dbg(fsp)));
370 set_close_write_time(fsp, lck->data->changed_write_time);
371 } else if (fsp->update_write_time_on_close) {
372 /* Someone had a pending write. */
373 if (null_timespec(fsp->close_write_time)) {
374 DEBUG(10,("close_remove_share_mode: update to current time "
375 "for file %s\n",
376 fsp_str_dbg(fsp)));
377 /* Update to current time due to "normal" write. */
378 set_close_write_time(fsp, timespec_current());
379 } else {
380 DEBUG(10,("close_remove_share_mode: write time pending "
381 "for file %s\n",
382 fsp_str_dbg(fsp)));
383 /* Update to time set on close call. */
384 set_close_write_time(fsp, fsp->close_write_time);
388 if (!del_share_mode(lck, fsp)) {
389 DEBUG(0, ("close_remove_share_mode: Could not delete share "
390 "entry for file %s\n",
391 fsp_str_dbg(fsp)));
394 if (fsp->initial_delete_on_close &&
395 !is_delete_on_close_set(lck, fsp->name_hash)) {
396 bool became_user = False;
398 /* Initial delete on close was set and no one else
399 * wrote a real delete on close. */
401 if (get_current_vuid(conn) != fsp->vuid) {
402 become_user(conn, fsp->vuid);
403 became_user = True;
405 fsp->delete_on_close = true;
406 set_delete_on_close_lck(fsp, lck, True,
407 get_current_nttok(conn),
408 get_current_utok(conn));
409 if (became_user) {
410 unbecome_user();
414 delete_file = is_delete_on_close_set(lck, fsp->name_hash);
416 if (delete_file) {
417 int i;
418 /* See if others still have the file open via this pathname.
419 If this is the case, then don't delete. If all opens are
420 POSIX delete now. */
421 for (i=0; i<lck->data->num_share_modes; i++) {
422 struct share_mode_entry *e = &lck->data->share_modes[i];
423 if (is_valid_share_mode_entry(e) &&
424 e->name_hash == fsp->name_hash) {
425 if (fsp->posix_open && (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) {
426 continue;
428 delete_file = False;
429 break;
434 /* Notify any deferred opens waiting on this close. */
435 notify_deferred_opens(conn->sconn, lck);
436 reply_to_oplock_break_requests(fsp);
439 * NT can set delete_on_close of the last open
440 * reference to a file.
443 if (!(close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) ||
444 !delete_file) {
445 TALLOC_FREE(lck);
446 return NT_STATUS_OK;
450 * Ok, we have to delete the file
453 DEBUG(5,("close_remove_share_mode: file %s. Delete on close was set "
454 "- deleting file.\n", fsp_str_dbg(fsp)));
457 * Don't try to update the write time when we delete the file
459 fsp->update_write_time_on_close = false;
461 got_tokens = get_delete_on_close_token(lck, fsp->name_hash,
462 &del_nt_token, &del_token);
463 SMB_ASSERT(got_tokens);
465 if (!unix_token_equal(del_token, get_current_utok(conn))) {
466 /* Become the user who requested the delete. */
468 DEBUG(5,("close_remove_share_mode: file %s. "
469 "Change user to uid %u\n",
470 fsp_str_dbg(fsp),
471 (unsigned int)del_token->uid));
473 if (!push_sec_ctx()) {
474 smb_panic("close_remove_share_mode: file %s. failed to push "
475 "sec_ctx.\n");
478 set_sec_ctx(del_token->uid,
479 del_token->gid,
480 del_token->ngroups,
481 del_token->groups,
482 del_nt_token);
484 changed_user = true;
487 /* We can only delete the file if the name we have is still valid and
488 hasn't been renamed. */
490 tmp_status = vfs_stat_fsp(fsp);
491 if (!NT_STATUS_IS_OK(tmp_status)) {
492 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
493 "was set and stat failed with error %s\n",
494 fsp_str_dbg(fsp), nt_errstr(tmp_status)));
496 * Don't save the errno here, we ignore this error
498 goto done;
501 id = vfs_file_id_from_sbuf(conn, &fsp->fsp_name->st);
503 if (!file_id_equal(&fsp->file_id, &id)) {
504 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
505 "was set and dev and/or inode does not match\n",
506 fsp_str_dbg(fsp)));
507 DEBUG(5,("close_remove_share_mode: file %s. stored file_id %s, "
508 "stat file_id %s\n",
509 fsp_str_dbg(fsp),
510 file_id_string_tos(&fsp->file_id),
511 file_id_string_tos(&id)));
513 * Don't save the errno here, we ignore this error
515 goto done;
518 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
519 && !is_ntfs_stream_smb_fname(fsp->fsp_name)) {
521 status = delete_all_streams(conn, fsp->fsp_name->base_name);
523 if (!NT_STATUS_IS_OK(status)) {
524 DEBUG(5, ("delete_all_streams failed: %s\n",
525 nt_errstr(status)));
526 goto done;
531 if (SMB_VFS_UNLINK(conn, fsp->fsp_name) != 0) {
533 * This call can potentially fail as another smbd may
534 * have had the file open with delete on close set and
535 * deleted it when its last reference to this file
536 * went away. Hence we log this but not at debug level
537 * zero.
540 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
541 "was set and unlink failed with error %s\n",
542 fsp_str_dbg(fsp), strerror(errno)));
544 status = map_nt_error_from_unix(errno);
547 /* As we now have POSIX opens which can unlink
548 * with other open files we may have taken
549 * this code path with more than one share mode
550 * entry - ensure we only delete once by resetting
551 * the delete on close flag. JRA.
554 fsp->delete_on_close = false;
555 set_delete_on_close_lck(fsp, lck, false, NULL, NULL);
557 done:
559 if (changed_user) {
560 /* unbecome user. */
561 pop_sec_ctx();
564 TALLOC_FREE(lck);
566 if (delete_file) {
568 * Do the notification after we released the share
569 * mode lock. Inside notify_fname we take out another
570 * tdb lock. With ctdb also accessing our databases,
571 * this can lead to deadlocks. Putting this notify
572 * after the TALLOC_FREE(lck) above we avoid locking
573 * two records simultaneously. Notifies are async and
574 * informational only, so calling the notify_fname
575 * without holding the share mode lock should not do
576 * any harm.
578 notify_fname(conn, NOTIFY_ACTION_REMOVED,
579 FILE_NOTIFY_CHANGE_FILE_NAME,
580 fsp->fsp_name->base_name);
583 return status;
586 void set_close_write_time(struct files_struct *fsp, struct timespec ts)
588 DEBUG(6,("close_write_time: %s" , time_to_asc(convert_timespec_to_time_t(ts))));
590 if (null_timespec(ts)) {
591 return;
593 fsp->write_time_forced = false;
594 fsp->update_write_time_on_close = true;
595 fsp->close_write_time = ts;
598 static NTSTATUS update_write_time_on_close(struct files_struct *fsp)
600 struct smb_file_time ft;
601 NTSTATUS status;
602 struct share_mode_lock *lck = NULL;
604 ZERO_STRUCT(ft);
606 if (!fsp->update_write_time_on_close) {
607 return NT_STATUS_OK;
610 if (null_timespec(fsp->close_write_time)) {
611 fsp->close_write_time = timespec_current();
614 /* Ensure we have a valid stat struct for the source. */
615 status = vfs_stat_fsp(fsp);
616 if (!NT_STATUS_IS_OK(status)) {
617 return status;
620 if (!VALID_STAT(fsp->fsp_name->st)) {
621 /* if it doesn't seem to be a real file */
622 return NT_STATUS_OK;
626 * get_existing_share_mode_lock() isn't really the right
627 * call here, as we're being called after
628 * close_remove_share_mode() inside close_normal_file()
629 * so it's quite normal to not have an existing share
630 * mode here. However, get_share_mode_lock() doesn't
631 * work because that will create a new share mode if
632 * one doesn't exist - so stick with this call (just
633 * ignore any error we get if the share mode doesn't
634 * exist.
637 lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
638 if (lck) {
639 /* On close if we're changing the real file time we
640 * must update it in the open file db too. */
641 (void)set_write_time(fsp->file_id, fsp->close_write_time);
643 /* Close write times overwrite sticky write times
644 so we must replace any sticky write time here. */
645 if (!null_timespec(lck->data->changed_write_time)) {
646 (void)set_sticky_write_time(fsp->file_id, fsp->close_write_time);
648 TALLOC_FREE(lck);
651 ft.mtime = fsp->close_write_time;
652 /* As this is a close based update, we are not directly changing the
653 file attributes from a client call, but indirectly from a write. */
654 status = smb_set_file_time(fsp->conn, fsp, fsp->fsp_name, &ft, false);
655 if (!NT_STATUS_IS_OK(status)) {
656 DEBUG(10,("update_write_time_on_close: smb_set_file_time "
657 "on file %s returned %s\n",
658 fsp_str_dbg(fsp),
659 nt_errstr(status)));
660 return status;
663 return status;
666 static NTSTATUS ntstatus_keeperror(NTSTATUS s1, NTSTATUS s2)
668 if (!NT_STATUS_IS_OK(s1)) {
669 return s1;
671 return s2;
674 /****************************************************************************
675 Close a file.
677 close_type can be NORMAL_CLOSE=0,SHUTDOWN_CLOSE,ERROR_CLOSE.
678 printing and magic scripts are only run on normal close.
679 delete on close is done on normal and shutdown close.
680 ****************************************************************************/
682 static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp,
683 enum file_close_type close_type)
685 NTSTATUS status = NT_STATUS_OK;
686 NTSTATUS tmp;
687 connection_struct *conn = fsp->conn;
688 int ret;
691 * If we're finishing async io on a close we can get a write
692 * error here, we must remember this.
694 ret = wait_for_aio_completion(fsp);
695 if (ret) {
696 status = ntstatus_keeperror(
697 status, map_nt_error_from_unix(ret));
701 * If we're flushing on a close we can get a write
702 * error here, we must remember this.
705 tmp = close_filestruct(fsp);
706 status = ntstatus_keeperror(status, tmp);
708 if (fsp->print_file) {
709 /* FIXME: return spool errors */
710 print_spool_end(fsp, close_type);
711 file_free(req, fsp);
712 return NT_STATUS_OK;
715 /* Remove the oplock before potentially deleting the file. */
716 if(fsp->oplock_type) {
717 release_file_oplock(fsp);
720 /* If this is an old DOS or FCB open and we have multiple opens on
721 the same handle we only have one share mode. Ensure we only remove
722 the share mode on the last close. */
724 if (fsp->fh->ref_count == 1) {
725 /* Should we return on error here... ? */
726 tmp = close_remove_share_mode(fsp, close_type);
727 status = ntstatus_keeperror(status, tmp);
730 locking_close_file(conn->sconn->msg_ctx, fsp, close_type);
732 tmp = fd_close(fsp);
733 status = ntstatus_keeperror(status, tmp);
735 /* check for magic scripts */
736 if (close_type == NORMAL_CLOSE) {
737 tmp = check_magic(fsp);
738 status = ntstatus_keeperror(status, tmp);
742 * Ensure pending modtime is set after close.
745 tmp = update_write_time_on_close(fsp);
746 if (NT_STATUS_EQUAL(tmp, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
747 /* Someone renamed the file or a parent directory containing
748 * this file. We can't do anything about this, we don't have
749 * an "update timestamp by fd" call in POSIX. Eat the error. */
751 tmp = NT_STATUS_OK;
754 status = ntstatus_keeperror(status, tmp);
756 DEBUG(2,("%s closed file %s (numopen=%d) %s\n",
757 conn->session_info->unix_info->unix_name, fsp_str_dbg(fsp),
758 conn->num_files_open - 1,
759 nt_errstr(status) ));
761 file_free(req, fsp);
762 return status;
764 /****************************************************************************
765 Static function used by reply_rmdir to delete an entire directory
766 tree recursively. Return True on ok, False on fail.
767 ****************************************************************************/
769 static bool recursive_rmdir(TALLOC_CTX *ctx,
770 connection_struct *conn,
771 struct smb_filename *smb_dname)
773 const char *dname = NULL;
774 char *talloced = NULL;
775 bool ret = True;
776 long offset = 0;
777 SMB_STRUCT_STAT st;
778 struct smb_Dir *dir_hnd;
780 SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
782 dir_hnd = OpenDir(talloc_tos(), conn, smb_dname->base_name, NULL, 0);
783 if(dir_hnd == NULL)
784 return False;
786 while((dname = ReadDirName(dir_hnd, &offset, &st, &talloced))) {
787 struct smb_filename *smb_dname_full = NULL;
788 char *fullname = NULL;
789 bool do_break = true;
790 NTSTATUS status;
792 if (ISDOT(dname) || ISDOTDOT(dname)) {
793 TALLOC_FREE(talloced);
794 continue;
797 if (!is_visible_file(conn, smb_dname->base_name, dname, &st,
798 false)) {
799 TALLOC_FREE(talloced);
800 continue;
803 /* Construct the full name. */
804 fullname = talloc_asprintf(ctx,
805 "%s/%s",
806 smb_dname->base_name,
807 dname);
808 if (!fullname) {
809 errno = ENOMEM;
810 goto err_break;
813 status = create_synthetic_smb_fname(talloc_tos(), fullname,
814 NULL, NULL,
815 &smb_dname_full);
816 if (!NT_STATUS_IS_OK(status)) {
817 goto err_break;
820 if(SMB_VFS_LSTAT(conn, smb_dname_full) != 0) {
821 goto err_break;
824 if(smb_dname_full->st.st_ex_mode & S_IFDIR) {
825 if(!recursive_rmdir(ctx, conn, smb_dname_full)) {
826 goto err_break;
828 if(SMB_VFS_RMDIR(conn,
829 smb_dname_full->base_name) != 0) {
830 goto err_break;
832 } else if(SMB_VFS_UNLINK(conn, smb_dname_full) != 0) {
833 goto err_break;
836 /* Successful iteration. */
837 do_break = false;
839 err_break:
840 TALLOC_FREE(smb_dname_full);
841 TALLOC_FREE(fullname);
842 TALLOC_FREE(talloced);
843 if (do_break) {
844 ret = false;
845 break;
848 TALLOC_FREE(dir_hnd);
849 return ret;
852 /****************************************************************************
853 The internals of the rmdir code - called elsewhere.
854 ****************************************************************************/
856 static NTSTATUS rmdir_internals(TALLOC_CTX *ctx, files_struct *fsp)
858 connection_struct *conn = fsp->conn;
859 struct smb_filename *smb_dname = fsp->fsp_name;
860 int ret;
862 SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
864 /* Might be a symlink. */
865 if(SMB_VFS_LSTAT(conn, smb_dname) != 0) {
866 return map_nt_error_from_unix(errno);
869 if (S_ISLNK(smb_dname->st.st_ex_mode)) {
870 /* Is what it points to a directory ? */
871 if(SMB_VFS_STAT(conn, smb_dname) != 0) {
872 return map_nt_error_from_unix(errno);
874 if (!(S_ISDIR(smb_dname->st.st_ex_mode))) {
875 return NT_STATUS_NOT_A_DIRECTORY;
877 ret = SMB_VFS_UNLINK(conn, smb_dname);
878 } else {
879 ret = SMB_VFS_RMDIR(conn, smb_dname->base_name);
881 if (ret == 0) {
882 notify_fname(conn, NOTIFY_ACTION_REMOVED,
883 FILE_NOTIFY_CHANGE_DIR_NAME,
884 smb_dname->base_name);
885 return NT_STATUS_OK;
888 if(((errno == ENOTEMPTY)||(errno == EEXIST)) && *lp_veto_files(SNUM(conn))) {
890 * Check to see if the only thing in this directory are
891 * vetoed files/directories. If so then delete them and
892 * retry. If we fail to delete any of them (and we *don't*
893 * do a recursive delete) then fail the rmdir.
895 SMB_STRUCT_STAT st;
896 const char *dname = NULL;
897 char *talloced = NULL;
898 long dirpos = 0;
899 struct smb_Dir *dir_hnd = OpenDir(talloc_tos(), conn,
900 smb_dname->base_name, NULL,
903 if(dir_hnd == NULL) {
904 errno = ENOTEMPTY;
905 goto err;
908 while ((dname = ReadDirName(dir_hnd, &dirpos, &st,
909 &talloced)) != NULL) {
910 if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0)) {
911 TALLOC_FREE(talloced);
912 continue;
914 if (!is_visible_file(conn, smb_dname->base_name, dname,
915 &st, false)) {
916 TALLOC_FREE(talloced);
917 continue;
919 if(!IS_VETO_PATH(conn, dname)) {
920 TALLOC_FREE(dir_hnd);
921 TALLOC_FREE(talloced);
922 errno = ENOTEMPTY;
923 goto err;
925 TALLOC_FREE(talloced);
928 /* We only have veto files/directories.
929 * Are we allowed to delete them ? */
931 if(!lp_recursive_veto_delete(SNUM(conn))) {
932 TALLOC_FREE(dir_hnd);
933 errno = ENOTEMPTY;
934 goto err;
937 /* Do a recursive delete. */
938 RewindDir(dir_hnd,&dirpos);
939 while ((dname = ReadDirName(dir_hnd, &dirpos, &st,
940 &talloced)) != NULL) {
941 struct smb_filename *smb_dname_full = NULL;
942 char *fullname = NULL;
943 bool do_break = true;
944 NTSTATUS status;
946 if (ISDOT(dname) || ISDOTDOT(dname)) {
947 TALLOC_FREE(talloced);
948 continue;
950 if (!is_visible_file(conn, smb_dname->base_name, dname,
951 &st, false)) {
952 TALLOC_FREE(talloced);
953 continue;
956 fullname = talloc_asprintf(ctx,
957 "%s/%s",
958 smb_dname->base_name,
959 dname);
961 if(!fullname) {
962 errno = ENOMEM;
963 goto err_break;
966 status = create_synthetic_smb_fname(talloc_tos(),
967 fullname, NULL,
968 NULL,
969 &smb_dname_full);
970 if (!NT_STATUS_IS_OK(status)) {
971 errno = map_errno_from_nt_status(status);
972 goto err_break;
975 if(SMB_VFS_LSTAT(conn, smb_dname_full) != 0) {
976 goto err_break;
978 if(smb_dname_full->st.st_ex_mode & S_IFDIR) {
979 if(!recursive_rmdir(ctx, conn,
980 smb_dname_full)) {
981 goto err_break;
983 if(SMB_VFS_RMDIR(conn,
984 smb_dname_full->base_name) != 0) {
985 goto err_break;
987 } else if(SMB_VFS_UNLINK(conn, smb_dname_full) != 0) {
988 goto err_break;
991 /* Successful iteration. */
992 do_break = false;
994 err_break:
995 TALLOC_FREE(fullname);
996 TALLOC_FREE(smb_dname_full);
997 TALLOC_FREE(talloced);
998 if (do_break)
999 break;
1001 TALLOC_FREE(dir_hnd);
1002 /* Retry the rmdir */
1003 ret = SMB_VFS_RMDIR(conn, smb_dname->base_name);
1006 err:
1008 if (ret != 0) {
1009 DEBUG(3,("rmdir_internals: couldn't remove directory %s : "
1010 "%s\n", smb_fname_str_dbg(smb_dname),
1011 strerror(errno)));
1012 return map_nt_error_from_unix(errno);
1015 notify_fname(conn, NOTIFY_ACTION_REMOVED,
1016 FILE_NOTIFY_CHANGE_DIR_NAME,
1017 smb_dname->base_name);
1019 return NT_STATUS_OK;
1022 /****************************************************************************
1023 Close a directory opened by an NT SMB call.
1024 ****************************************************************************/
1026 static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
1027 enum file_close_type close_type)
1029 struct share_mode_lock *lck = NULL;
1030 bool delete_dir = False;
1031 NTSTATUS status = NT_STATUS_OK;
1032 NTSTATUS status1 = NT_STATUS_OK;
1033 const struct security_token *del_nt_token = NULL;
1034 const struct security_unix_token *del_token = NULL;
1037 * NT can set delete_on_close of the last open
1038 * reference to a directory also.
1041 lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
1042 if (lck == NULL) {
1043 DEBUG(0, ("close_directory: Could not get share mode lock for "
1044 "%s\n", fsp_str_dbg(fsp)));
1045 status = NT_STATUS_INVALID_PARAMETER;
1046 goto out;
1049 if (!del_share_mode(lck, fsp)) {
1050 DEBUG(0, ("close_directory: Could not delete share entry for "
1051 "%s\n", fsp_str_dbg(fsp)));
1054 if (fsp->initial_delete_on_close) {
1055 bool became_user = False;
1057 /* Initial delete on close was set - for
1058 * directories we don't care if anyone else
1059 * wrote a real delete on close. */
1061 if (get_current_vuid(fsp->conn) != fsp->vuid) {
1062 become_user(fsp->conn, fsp->vuid);
1063 became_user = True;
1065 send_stat_cache_delete_message(fsp->conn->sconn->msg_ctx,
1066 fsp->fsp_name->base_name);
1067 set_delete_on_close_lck(fsp, lck, true,
1068 get_current_nttok(fsp->conn),
1069 get_current_utok(fsp->conn));
1070 fsp->delete_on_close = true;
1071 if (became_user) {
1072 unbecome_user();
1076 delete_dir = get_delete_on_close_token(lck, fsp->name_hash,
1077 &del_nt_token, &del_token);
1079 if (delete_dir) {
1080 int i;
1081 /* See if others still have the dir open. If this is the
1082 * case, then don't delete. If all opens are POSIX delete now. */
1083 for (i=0; i<lck->data->num_share_modes; i++) {
1084 struct share_mode_entry *e = &lck->data->share_modes[i];
1085 if (is_valid_share_mode_entry(e) &&
1086 e->name_hash == fsp->name_hash) {
1087 if (fsp->posix_open && (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) {
1088 continue;
1090 delete_dir = False;
1091 break;
1096 if ((close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) &&
1097 delete_dir) {
1099 /* Become the user who requested the delete. */
1101 if (!push_sec_ctx()) {
1102 smb_panic("close_directory: failed to push sec_ctx.\n");
1105 set_sec_ctx(del_token->uid,
1106 del_token->gid,
1107 del_token->ngroups,
1108 del_token->groups,
1109 del_nt_token);
1111 TALLOC_FREE(lck);
1113 if ((fsp->conn->fs_capabilities & FILE_NAMED_STREAMS)
1114 && !is_ntfs_stream_smb_fname(fsp->fsp_name)) {
1116 status = delete_all_streams(fsp->conn, fsp->fsp_name->base_name);
1117 if (!NT_STATUS_IS_OK(status)) {
1118 DEBUG(5, ("delete_all_streams failed: %s\n",
1119 nt_errstr(status)));
1120 goto out;
1124 status = rmdir_internals(talloc_tos(), fsp);
1126 DEBUG(5,("close_directory: %s. Delete on close was set - "
1127 "deleting directory returned %s.\n",
1128 fsp_str_dbg(fsp), nt_errstr(status)));
1130 /* unbecome user. */
1131 pop_sec_ctx();
1134 * Ensure we remove any change notify requests that would
1135 * now fail as the directory has been deleted.
1138 if(NT_STATUS_IS_OK(status)) {
1139 remove_pending_change_notify_requests_by_fid(fsp, NT_STATUS_DELETE_PENDING);
1141 } else {
1142 TALLOC_FREE(lck);
1143 remove_pending_change_notify_requests_by_fid(
1144 fsp, NT_STATUS_OK);
1147 status1 = fd_close(fsp);
1149 if (!NT_STATUS_IS_OK(status1)) {
1150 DEBUG(0, ("Could not close dir! fname=%s, fd=%d, err=%d=%s\n",
1151 fsp_str_dbg(fsp), fsp->fh->fd, errno,
1152 strerror(errno)));
1156 * Do the code common to files and directories.
1158 close_filestruct(fsp);
1159 file_free(req, fsp);
1161 out:
1162 TALLOC_FREE(lck);
1163 if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(status1)) {
1164 status = status1;
1166 return status;
1169 /****************************************************************************
1170 Close a files_struct.
1171 ****************************************************************************/
1173 NTSTATUS close_file(struct smb_request *req, files_struct *fsp,
1174 enum file_close_type close_type)
1176 NTSTATUS status;
1177 struct files_struct *base_fsp = fsp->base_fsp;
1179 if(fsp->is_directory) {
1180 status = close_directory(req, fsp, close_type);
1181 } else if (fsp->fake_file_handle != NULL) {
1182 status = close_fake_file(req, fsp);
1183 } else {
1184 status = close_normal_file(req, fsp, close_type);
1187 if ((base_fsp != NULL) && (close_type != SHUTDOWN_CLOSE)) {
1190 * fsp was a stream, the base fsp can't be a stream as well
1192 * For SHUTDOWN_CLOSE this is not possible here, because
1193 * SHUTDOWN_CLOSE only happens from files.c which walks the
1194 * complete list of files. If we mess with more than one fsp
1195 * those loops will become confused.
1198 SMB_ASSERT(base_fsp->base_fsp == NULL);
1199 close_file(req, base_fsp, close_type);
1202 return status;
1205 /****************************************************************************
1206 Deal with an (authorized) message to close a file given the share mode
1207 entry.
1208 ****************************************************************************/
1210 void msg_close_file(struct messaging_context *msg_ctx,
1211 void *private_data,
1212 uint32_t msg_type,
1213 struct server_id server_id,
1214 DATA_BLOB *data)
1216 files_struct *fsp = NULL;
1217 struct share_mode_entry e;
1218 struct smbd_server_connection *sconn =
1219 talloc_get_type_abort(private_data,
1220 struct smbd_server_connection);
1222 message_to_share_mode_entry(&e, (char *)data->data);
1224 if(DEBUGLVL(10)) {
1225 char *sm_str = share_mode_str(NULL, 0, &e);
1226 if (!sm_str) {
1227 smb_panic("talloc failed");
1229 DEBUG(10,("msg_close_file: got request to close share mode "
1230 "entry %s\n", sm_str));
1231 TALLOC_FREE(sm_str);
1234 fsp = file_find_dif(sconn, e.id, e.share_file_id);
1235 if (!fsp) {
1236 DEBUG(10,("msg_close_file: failed to find file.\n"));
1237 return;
1239 close_file(NULL, fsp, NORMAL_CLOSE);