s3:selftest: introduce a variable for binpath('smbtorture3') in tests.py
[Samba/gebeck_regimport.git] / source3 / smbd / close.c
blob4b7f6945107cd28d4cf50194b623c3e68067cd42
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 if (share_mode_stale_pid(lck->data, i)) {
429 continue;
431 delete_file = False;
432 break;
437 /* Notify any deferred opens waiting on this close. */
438 notify_deferred_opens(conn->sconn, lck);
439 reply_to_oplock_break_requests(fsp);
442 * NT can set delete_on_close of the last open
443 * reference to a file.
446 if (!(close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) ||
447 !delete_file) {
448 TALLOC_FREE(lck);
449 return NT_STATUS_OK;
453 * Ok, we have to delete the file
456 DEBUG(5,("close_remove_share_mode: file %s. Delete on close was set "
457 "- deleting file.\n", fsp_str_dbg(fsp)));
460 * Don't try to update the write time when we delete the file
462 fsp->update_write_time_on_close = false;
464 got_tokens = get_delete_on_close_token(lck, fsp->name_hash,
465 &del_nt_token, &del_token);
466 SMB_ASSERT(got_tokens);
468 if (!unix_token_equal(del_token, get_current_utok(conn))) {
469 /* Become the user who requested the delete. */
471 DEBUG(5,("close_remove_share_mode: file %s. "
472 "Change user to uid %u\n",
473 fsp_str_dbg(fsp),
474 (unsigned int)del_token->uid));
476 if (!push_sec_ctx()) {
477 smb_panic("close_remove_share_mode: file %s. failed to push "
478 "sec_ctx.\n");
481 set_sec_ctx(del_token->uid,
482 del_token->gid,
483 del_token->ngroups,
484 del_token->groups,
485 del_nt_token);
487 changed_user = true;
490 /* We can only delete the file if the name we have is still valid and
491 hasn't been renamed. */
493 tmp_status = vfs_stat_fsp(fsp);
494 if (!NT_STATUS_IS_OK(tmp_status)) {
495 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
496 "was set and stat failed with error %s\n",
497 fsp_str_dbg(fsp), nt_errstr(tmp_status)));
499 * Don't save the errno here, we ignore this error
501 goto done;
504 id = vfs_file_id_from_sbuf(conn, &fsp->fsp_name->st);
506 if (!file_id_equal(&fsp->file_id, &id)) {
507 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
508 "was set and dev and/or inode does not match\n",
509 fsp_str_dbg(fsp)));
510 DEBUG(5,("close_remove_share_mode: file %s. stored file_id %s, "
511 "stat file_id %s\n",
512 fsp_str_dbg(fsp),
513 file_id_string_tos(&fsp->file_id),
514 file_id_string_tos(&id)));
516 * Don't save the errno here, we ignore this error
518 goto done;
521 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
522 && !is_ntfs_stream_smb_fname(fsp->fsp_name)) {
524 status = delete_all_streams(conn, fsp->fsp_name->base_name);
526 if (!NT_STATUS_IS_OK(status)) {
527 DEBUG(5, ("delete_all_streams failed: %s\n",
528 nt_errstr(status)));
529 goto done;
534 if (SMB_VFS_UNLINK(conn, fsp->fsp_name) != 0) {
536 * This call can potentially fail as another smbd may
537 * have had the file open with delete on close set and
538 * deleted it when its last reference to this file
539 * went away. Hence we log this but not at debug level
540 * zero.
543 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
544 "was set and unlink failed with error %s\n",
545 fsp_str_dbg(fsp), strerror(errno)));
547 status = map_nt_error_from_unix(errno);
550 /* As we now have POSIX opens which can unlink
551 * with other open files we may have taken
552 * this code path with more than one share mode
553 * entry - ensure we only delete once by resetting
554 * the delete on close flag. JRA.
557 fsp->delete_on_close = false;
558 set_delete_on_close_lck(fsp, lck, false, NULL, NULL);
560 done:
562 if (changed_user) {
563 /* unbecome user. */
564 pop_sec_ctx();
567 TALLOC_FREE(lck);
569 if (delete_file) {
571 * Do the notification after we released the share
572 * mode lock. Inside notify_fname we take out another
573 * tdb lock. With ctdb also accessing our databases,
574 * this can lead to deadlocks. Putting this notify
575 * after the TALLOC_FREE(lck) above we avoid locking
576 * two records simultaneously. Notifies are async and
577 * informational only, so calling the notify_fname
578 * without holding the share mode lock should not do
579 * any harm.
581 notify_fname(conn, NOTIFY_ACTION_REMOVED,
582 FILE_NOTIFY_CHANGE_FILE_NAME,
583 fsp->fsp_name->base_name);
586 return status;
589 void set_close_write_time(struct files_struct *fsp, struct timespec ts)
591 DEBUG(6,("close_write_time: %s" , time_to_asc(convert_timespec_to_time_t(ts))));
593 if (null_timespec(ts)) {
594 return;
596 fsp->write_time_forced = false;
597 fsp->update_write_time_on_close = true;
598 fsp->close_write_time = ts;
601 static NTSTATUS update_write_time_on_close(struct files_struct *fsp)
603 struct smb_file_time ft;
604 NTSTATUS status;
605 struct share_mode_lock *lck = NULL;
607 ZERO_STRUCT(ft);
609 if (!fsp->update_write_time_on_close) {
610 return NT_STATUS_OK;
613 if (null_timespec(fsp->close_write_time)) {
614 fsp->close_write_time = timespec_current();
617 /* Ensure we have a valid stat struct for the source. */
618 status = vfs_stat_fsp(fsp);
619 if (!NT_STATUS_IS_OK(status)) {
620 return status;
623 if (!VALID_STAT(fsp->fsp_name->st)) {
624 /* if it doesn't seem to be a real file */
625 return NT_STATUS_OK;
629 * get_existing_share_mode_lock() isn't really the right
630 * call here, as we're being called after
631 * close_remove_share_mode() inside close_normal_file()
632 * so it's quite normal to not have an existing share
633 * mode here. However, get_share_mode_lock() doesn't
634 * work because that will create a new share mode if
635 * one doesn't exist - so stick with this call (just
636 * ignore any error we get if the share mode doesn't
637 * exist.
640 lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
641 if (lck) {
642 /* On close if we're changing the real file time we
643 * must update it in the open file db too. */
644 (void)set_write_time(fsp->file_id, fsp->close_write_time);
646 /* Close write times overwrite sticky write times
647 so we must replace any sticky write time here. */
648 if (!null_timespec(lck->data->changed_write_time)) {
649 (void)set_sticky_write_time(fsp->file_id, fsp->close_write_time);
651 TALLOC_FREE(lck);
654 ft.mtime = fsp->close_write_time;
655 /* As this is a close based update, we are not directly changing the
656 file attributes from a client call, but indirectly from a write. */
657 status = smb_set_file_time(fsp->conn, fsp, fsp->fsp_name, &ft, false);
658 if (!NT_STATUS_IS_OK(status)) {
659 DEBUG(10,("update_write_time_on_close: smb_set_file_time "
660 "on file %s returned %s\n",
661 fsp_str_dbg(fsp),
662 nt_errstr(status)));
663 return status;
666 return status;
669 static NTSTATUS ntstatus_keeperror(NTSTATUS s1, NTSTATUS s2)
671 if (!NT_STATUS_IS_OK(s1)) {
672 return s1;
674 return s2;
677 /****************************************************************************
678 Close a file.
680 close_type can be NORMAL_CLOSE=0,SHUTDOWN_CLOSE,ERROR_CLOSE.
681 printing and magic scripts are only run on normal close.
682 delete on close is done on normal and shutdown close.
683 ****************************************************************************/
685 static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp,
686 enum file_close_type close_type)
688 NTSTATUS status = NT_STATUS_OK;
689 NTSTATUS tmp;
690 connection_struct *conn = fsp->conn;
691 int ret;
694 * If we're finishing async io on a close we can get a write
695 * error here, we must remember this.
697 ret = wait_for_aio_completion(fsp);
698 if (ret) {
699 status = ntstatus_keeperror(
700 status, map_nt_error_from_unix(ret));
704 * If we're flushing on a close we can get a write
705 * error here, we must remember this.
708 tmp = close_filestruct(fsp);
709 status = ntstatus_keeperror(status, tmp);
711 if (fsp->print_file) {
712 /* FIXME: return spool errors */
713 print_spool_end(fsp, close_type);
714 file_free(req, fsp);
715 return NT_STATUS_OK;
718 /* Remove the oplock before potentially deleting the file. */
719 if(fsp->oplock_type) {
720 release_file_oplock(fsp);
723 /* If this is an old DOS or FCB open and we have multiple opens on
724 the same handle we only have one share mode. Ensure we only remove
725 the share mode on the last close. */
727 if (fsp->fh->ref_count == 1) {
728 /* Should we return on error here... ? */
729 tmp = close_remove_share_mode(fsp, close_type);
730 status = ntstatus_keeperror(status, tmp);
733 locking_close_file(conn->sconn->msg_ctx, fsp, close_type);
735 tmp = fd_close(fsp);
736 status = ntstatus_keeperror(status, tmp);
738 /* check for magic scripts */
739 if (close_type == NORMAL_CLOSE) {
740 tmp = check_magic(fsp);
741 status = ntstatus_keeperror(status, tmp);
745 * Ensure pending modtime is set after close.
748 tmp = update_write_time_on_close(fsp);
749 if (NT_STATUS_EQUAL(tmp, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
750 /* Someone renamed the file or a parent directory containing
751 * this file. We can't do anything about this, we don't have
752 * an "update timestamp by fd" call in POSIX. Eat the error. */
754 tmp = NT_STATUS_OK;
757 status = ntstatus_keeperror(status, tmp);
759 DEBUG(2,("%s closed file %s (numopen=%d) %s\n",
760 conn->session_info->unix_info->unix_name, fsp_str_dbg(fsp),
761 conn->num_files_open - 1,
762 nt_errstr(status) ));
764 file_free(req, fsp);
765 return status;
767 /****************************************************************************
768 Static function used by reply_rmdir to delete an entire directory
769 tree recursively. Return True on ok, False on fail.
770 ****************************************************************************/
772 static bool recursive_rmdir(TALLOC_CTX *ctx,
773 connection_struct *conn,
774 struct smb_filename *smb_dname)
776 const char *dname = NULL;
777 char *talloced = NULL;
778 bool ret = True;
779 long offset = 0;
780 SMB_STRUCT_STAT st;
781 struct smb_Dir *dir_hnd;
783 SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
785 dir_hnd = OpenDir(talloc_tos(), conn, smb_dname->base_name, NULL, 0);
786 if(dir_hnd == NULL)
787 return False;
789 while((dname = ReadDirName(dir_hnd, &offset, &st, &talloced))) {
790 struct smb_filename *smb_dname_full = NULL;
791 char *fullname = NULL;
792 bool do_break = true;
793 NTSTATUS status;
795 if (ISDOT(dname) || ISDOTDOT(dname)) {
796 TALLOC_FREE(talloced);
797 continue;
800 if (!is_visible_file(conn, smb_dname->base_name, dname, &st,
801 false)) {
802 TALLOC_FREE(talloced);
803 continue;
806 /* Construct the full name. */
807 fullname = talloc_asprintf(ctx,
808 "%s/%s",
809 smb_dname->base_name,
810 dname);
811 if (!fullname) {
812 errno = ENOMEM;
813 goto err_break;
816 status = create_synthetic_smb_fname(talloc_tos(), fullname,
817 NULL, NULL,
818 &smb_dname_full);
819 if (!NT_STATUS_IS_OK(status)) {
820 goto err_break;
823 if(SMB_VFS_LSTAT(conn, smb_dname_full) != 0) {
824 goto err_break;
827 if(smb_dname_full->st.st_ex_mode & S_IFDIR) {
828 if(!recursive_rmdir(ctx, conn, smb_dname_full)) {
829 goto err_break;
831 if(SMB_VFS_RMDIR(conn,
832 smb_dname_full->base_name) != 0) {
833 goto err_break;
835 } else if(SMB_VFS_UNLINK(conn, smb_dname_full) != 0) {
836 goto err_break;
839 /* Successful iteration. */
840 do_break = false;
842 err_break:
843 TALLOC_FREE(smb_dname_full);
844 TALLOC_FREE(fullname);
845 TALLOC_FREE(talloced);
846 if (do_break) {
847 ret = false;
848 break;
851 TALLOC_FREE(dir_hnd);
852 return ret;
855 /****************************************************************************
856 The internals of the rmdir code - called elsewhere.
857 ****************************************************************************/
859 static NTSTATUS rmdir_internals(TALLOC_CTX *ctx, files_struct *fsp)
861 connection_struct *conn = fsp->conn;
862 struct smb_filename *smb_dname = fsp->fsp_name;
863 int ret;
865 SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
867 /* Might be a symlink. */
868 if(SMB_VFS_LSTAT(conn, smb_dname) != 0) {
869 return map_nt_error_from_unix(errno);
872 if (S_ISLNK(smb_dname->st.st_ex_mode)) {
873 /* Is what it points to a directory ? */
874 if(SMB_VFS_STAT(conn, smb_dname) != 0) {
875 return map_nt_error_from_unix(errno);
877 if (!(S_ISDIR(smb_dname->st.st_ex_mode))) {
878 return NT_STATUS_NOT_A_DIRECTORY;
880 ret = SMB_VFS_UNLINK(conn, smb_dname);
881 } else {
882 ret = SMB_VFS_RMDIR(conn, smb_dname->base_name);
884 if (ret == 0) {
885 notify_fname(conn, NOTIFY_ACTION_REMOVED,
886 FILE_NOTIFY_CHANGE_DIR_NAME,
887 smb_dname->base_name);
888 return NT_STATUS_OK;
891 if(((errno == ENOTEMPTY)||(errno == EEXIST)) && *lp_veto_files(SNUM(conn))) {
893 * Check to see if the only thing in this directory are
894 * vetoed files/directories. If so then delete them and
895 * retry. If we fail to delete any of them (and we *don't*
896 * do a recursive delete) then fail the rmdir.
898 SMB_STRUCT_STAT st;
899 const char *dname = NULL;
900 char *talloced = NULL;
901 long dirpos = 0;
902 struct smb_Dir *dir_hnd = OpenDir(talloc_tos(), conn,
903 smb_dname->base_name, NULL,
906 if(dir_hnd == NULL) {
907 errno = ENOTEMPTY;
908 goto err;
911 while ((dname = ReadDirName(dir_hnd, &dirpos, &st,
912 &talloced)) != NULL) {
913 if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0)) {
914 TALLOC_FREE(talloced);
915 continue;
917 if (!is_visible_file(conn, smb_dname->base_name, dname,
918 &st, false)) {
919 TALLOC_FREE(talloced);
920 continue;
922 if(!IS_VETO_PATH(conn, dname)) {
923 TALLOC_FREE(dir_hnd);
924 TALLOC_FREE(talloced);
925 errno = ENOTEMPTY;
926 goto err;
928 TALLOC_FREE(talloced);
931 /* We only have veto files/directories.
932 * Are we allowed to delete them ? */
934 if(!lp_recursive_veto_delete(SNUM(conn))) {
935 TALLOC_FREE(dir_hnd);
936 errno = ENOTEMPTY;
937 goto err;
940 /* Do a recursive delete. */
941 RewindDir(dir_hnd,&dirpos);
942 while ((dname = ReadDirName(dir_hnd, &dirpos, &st,
943 &talloced)) != NULL) {
944 struct smb_filename *smb_dname_full = NULL;
945 char *fullname = NULL;
946 bool do_break = true;
947 NTSTATUS status;
949 if (ISDOT(dname) || ISDOTDOT(dname)) {
950 TALLOC_FREE(talloced);
951 continue;
953 if (!is_visible_file(conn, smb_dname->base_name, dname,
954 &st, false)) {
955 TALLOC_FREE(talloced);
956 continue;
959 fullname = talloc_asprintf(ctx,
960 "%s/%s",
961 smb_dname->base_name,
962 dname);
964 if(!fullname) {
965 errno = ENOMEM;
966 goto err_break;
969 status = create_synthetic_smb_fname(talloc_tos(),
970 fullname, NULL,
971 NULL,
972 &smb_dname_full);
973 if (!NT_STATUS_IS_OK(status)) {
974 errno = map_errno_from_nt_status(status);
975 goto err_break;
978 if(SMB_VFS_LSTAT(conn, smb_dname_full) != 0) {
979 goto err_break;
981 if(smb_dname_full->st.st_ex_mode & S_IFDIR) {
982 if(!recursive_rmdir(ctx, conn,
983 smb_dname_full)) {
984 goto err_break;
986 if(SMB_VFS_RMDIR(conn,
987 smb_dname_full->base_name) != 0) {
988 goto err_break;
990 } else if(SMB_VFS_UNLINK(conn, smb_dname_full) != 0) {
991 goto err_break;
994 /* Successful iteration. */
995 do_break = false;
997 err_break:
998 TALLOC_FREE(fullname);
999 TALLOC_FREE(smb_dname_full);
1000 TALLOC_FREE(talloced);
1001 if (do_break)
1002 break;
1004 TALLOC_FREE(dir_hnd);
1005 /* Retry the rmdir */
1006 ret = SMB_VFS_RMDIR(conn, smb_dname->base_name);
1009 err:
1011 if (ret != 0) {
1012 DEBUG(3,("rmdir_internals: couldn't remove directory %s : "
1013 "%s\n", smb_fname_str_dbg(smb_dname),
1014 strerror(errno)));
1015 return map_nt_error_from_unix(errno);
1018 notify_fname(conn, NOTIFY_ACTION_REMOVED,
1019 FILE_NOTIFY_CHANGE_DIR_NAME,
1020 smb_dname->base_name);
1022 return NT_STATUS_OK;
1025 /****************************************************************************
1026 Close a directory opened by an NT SMB call.
1027 ****************************************************************************/
1029 static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
1030 enum file_close_type close_type)
1032 struct share_mode_lock *lck = NULL;
1033 bool delete_dir = False;
1034 NTSTATUS status = NT_STATUS_OK;
1035 NTSTATUS status1 = NT_STATUS_OK;
1036 const struct security_token *del_nt_token = NULL;
1037 const struct security_unix_token *del_token = NULL;
1040 * NT can set delete_on_close of the last open
1041 * reference to a directory also.
1044 lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
1045 if (lck == NULL) {
1046 DEBUG(0, ("close_directory: Could not get share mode lock for "
1047 "%s\n", fsp_str_dbg(fsp)));
1048 status = NT_STATUS_INVALID_PARAMETER;
1049 goto out;
1052 if (!del_share_mode(lck, fsp)) {
1053 DEBUG(0, ("close_directory: Could not delete share entry for "
1054 "%s\n", fsp_str_dbg(fsp)));
1057 if (fsp->initial_delete_on_close) {
1058 bool became_user = False;
1060 /* Initial delete on close was set - for
1061 * directories we don't care if anyone else
1062 * wrote a real delete on close. */
1064 if (get_current_vuid(fsp->conn) != fsp->vuid) {
1065 become_user(fsp->conn, fsp->vuid);
1066 became_user = True;
1068 send_stat_cache_delete_message(fsp->conn->sconn->msg_ctx,
1069 fsp->fsp_name->base_name);
1070 set_delete_on_close_lck(fsp, lck, true,
1071 get_current_nttok(fsp->conn),
1072 get_current_utok(fsp->conn));
1073 fsp->delete_on_close = true;
1074 if (became_user) {
1075 unbecome_user();
1079 delete_dir = get_delete_on_close_token(lck, fsp->name_hash,
1080 &del_nt_token, &del_token);
1082 if (delete_dir) {
1083 int i;
1084 /* See if others still have the dir open. If this is the
1085 * case, then don't delete. If all opens are POSIX delete now. */
1086 for (i=0; i<lck->data->num_share_modes; i++) {
1087 struct share_mode_entry *e = &lck->data->share_modes[i];
1088 if (is_valid_share_mode_entry(e) &&
1089 e->name_hash == fsp->name_hash) {
1090 if (fsp->posix_open && (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) {
1091 continue;
1093 if (share_mode_stale_pid(lck->data, i)) {
1094 continue;
1096 delete_dir = False;
1097 break;
1102 if ((close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) &&
1103 delete_dir) {
1105 /* Become the user who requested the delete. */
1107 if (!push_sec_ctx()) {
1108 smb_panic("close_directory: failed to push sec_ctx.\n");
1111 set_sec_ctx(del_token->uid,
1112 del_token->gid,
1113 del_token->ngroups,
1114 del_token->groups,
1115 del_nt_token);
1117 TALLOC_FREE(lck);
1119 if ((fsp->conn->fs_capabilities & FILE_NAMED_STREAMS)
1120 && !is_ntfs_stream_smb_fname(fsp->fsp_name)) {
1122 status = delete_all_streams(fsp->conn, fsp->fsp_name->base_name);
1123 if (!NT_STATUS_IS_OK(status)) {
1124 DEBUG(5, ("delete_all_streams failed: %s\n",
1125 nt_errstr(status)));
1126 goto out;
1130 status = rmdir_internals(talloc_tos(), fsp);
1132 DEBUG(5,("close_directory: %s. Delete on close was set - "
1133 "deleting directory returned %s.\n",
1134 fsp_str_dbg(fsp), nt_errstr(status)));
1136 /* unbecome user. */
1137 pop_sec_ctx();
1140 * Ensure we remove any change notify requests that would
1141 * now fail as the directory has been deleted.
1144 if(NT_STATUS_IS_OK(status)) {
1145 remove_pending_change_notify_requests_by_fid(fsp, NT_STATUS_DELETE_PENDING);
1147 } else {
1148 TALLOC_FREE(lck);
1149 remove_pending_change_notify_requests_by_fid(
1150 fsp, NT_STATUS_OK);
1153 status1 = fd_close(fsp);
1155 if (!NT_STATUS_IS_OK(status1)) {
1156 DEBUG(0, ("Could not close dir! fname=%s, fd=%d, err=%d=%s\n",
1157 fsp_str_dbg(fsp), fsp->fh->fd, errno,
1158 strerror(errno)));
1162 * Do the code common to files and directories.
1164 close_filestruct(fsp);
1165 file_free(req, fsp);
1167 out:
1168 TALLOC_FREE(lck);
1169 if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(status1)) {
1170 status = status1;
1172 return status;
1175 /****************************************************************************
1176 Close a files_struct.
1177 ****************************************************************************/
1179 NTSTATUS close_file(struct smb_request *req, files_struct *fsp,
1180 enum file_close_type close_type)
1182 NTSTATUS status;
1183 struct files_struct *base_fsp = fsp->base_fsp;
1185 if(fsp->is_directory) {
1186 status = close_directory(req, fsp, close_type);
1187 } else if (fsp->fake_file_handle != NULL) {
1188 status = close_fake_file(req, fsp);
1189 } else {
1190 status = close_normal_file(req, fsp, close_type);
1193 if ((base_fsp != NULL) && (close_type != SHUTDOWN_CLOSE)) {
1196 * fsp was a stream, the base fsp can't be a stream as well
1198 * For SHUTDOWN_CLOSE this is not possible here, because
1199 * SHUTDOWN_CLOSE only happens from files.c which walks the
1200 * complete list of files. If we mess with more than one fsp
1201 * those loops will become confused.
1204 SMB_ASSERT(base_fsp->base_fsp == NULL);
1205 close_file(req, base_fsp, close_type);
1208 return status;
1211 /****************************************************************************
1212 Deal with an (authorized) message to close a file given the share mode
1213 entry.
1214 ****************************************************************************/
1216 void msg_close_file(struct messaging_context *msg_ctx,
1217 void *private_data,
1218 uint32_t msg_type,
1219 struct server_id server_id,
1220 DATA_BLOB *data)
1222 files_struct *fsp = NULL;
1223 struct share_mode_entry e;
1224 struct smbd_server_connection *sconn =
1225 talloc_get_type_abort(private_data,
1226 struct smbd_server_connection);
1228 message_to_share_mode_entry(&e, (char *)data->data);
1230 if(DEBUGLVL(10)) {
1231 char *sm_str = share_mode_str(NULL, 0, &e);
1232 if (!sm_str) {
1233 smb_panic("talloc failed");
1235 DEBUG(10,("msg_close_file: got request to close share mode "
1236 "entry %s\n", sm_str));
1237 TALLOC_FREE(sm_str);
1240 fsp = file_find_dif(sconn, e.id, e.share_file_id);
1241 if (!fsp) {
1242 DEBUG(10,("msg_close_file: failed to find file.\n"));
1243 return;
1245 close_file(NULL, fsp, NORMAL_CLOSE);