tests: Check symlinks are readable as reparse points
[samba.git] / source3 / smbd / close.c
blob16356a07cc31c792b51b467804ac19ebe3257f6e
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 "lib/util/server_id.h"
25 #include "printing.h"
26 #include "locking/share_mode_lock.h"
27 #include "smbd/smbd.h"
28 #include "smbd/globals.h"
29 #include "smbd/smbXsrv_open.h"
30 #include "smbd/scavenger.h"
31 #include "fake_file.h"
32 #include "transfer_file.h"
33 #include "auth.h"
34 #include "messages.h"
35 #include "librpc/gen_ndr/ndr_open_files.h"
36 #include "lib/util/tevent_ntstatus.h"
37 #include "source3/smbd/dir.h"
39 /****************************************************************************
40 Run a file if it is a magic script.
41 ****************************************************************************/
43 static NTSTATUS check_magic(struct files_struct *fsp)
45 int ret;
46 const struct loadparm_substitution *lp_sub =
47 loadparm_s3_global_substitution();
48 const char *magic_output = NULL;
49 SMB_STRUCT_STAT st;
50 int tmp_fd, outfd;
51 TALLOC_CTX *ctx = NULL;
52 const char *p;
53 struct connection_struct *conn = fsp->conn;
54 char *fname = NULL;
55 NTSTATUS status;
57 if (!*lp_magic_script(talloc_tos(), lp_sub, SNUM(conn))) {
58 return NT_STATUS_OK;
61 DEBUG(5,("checking magic for %s\n", fsp_str_dbg(fsp)));
63 ctx = talloc_stackframe();
65 fname = fsp->fsp_name->base_name;
67 if (!(p = strrchr_m(fname,'/'))) {
68 p = fname;
69 } else {
70 p++;
73 if (!strequal(lp_magic_script(talloc_tos(), lp_sub, SNUM(conn)),p)) {
74 status = NT_STATUS_OK;
75 goto out;
78 if (*lp_magic_output(talloc_tos(), lp_sub, SNUM(conn))) {
79 magic_output = lp_magic_output(talloc_tos(), lp_sub, SNUM(conn));
80 } else {
81 magic_output = talloc_asprintf(ctx,
82 "%s.out",
83 fname);
85 if (!magic_output) {
86 status = NT_STATUS_NO_MEMORY;
87 goto out;
90 /* Ensure we don't depend on user's PATH. */
91 p = talloc_asprintf(ctx, "./%s", fname);
92 if (!p) {
93 status = NT_STATUS_NO_MEMORY;
94 goto out;
97 if (chmod(fname, 0755) == -1) {
98 status = map_nt_error_from_unix(errno);
99 goto out;
101 ret = smbrun(p, &tmp_fd, NULL);
102 DEBUG(3,("Invoking magic command %s gave %d\n",
103 p,ret));
105 unlink(fname);
106 if (ret != 0 || tmp_fd == -1) {
107 if (tmp_fd != -1) {
108 close(tmp_fd);
110 status = NT_STATUS_UNSUCCESSFUL;
111 goto out;
113 outfd = open(magic_output, O_CREAT|O_EXCL|O_RDWR, 0600);
114 if (outfd == -1) {
115 int err = errno;
116 close(tmp_fd);
117 status = map_nt_error_from_unix(err);
118 goto out;
121 if (sys_fstat(tmp_fd, &st, false) == -1) {
122 int err = errno;
123 close(tmp_fd);
124 close(outfd);
125 status = map_nt_error_from_unix(err);
126 goto out;
129 if (transfer_file(tmp_fd,outfd,(off_t)st.st_ex_size) == (off_t)-1) {
130 int err = errno;
131 close(tmp_fd);
132 close(outfd);
133 status = map_nt_error_from_unix(err);
134 goto out;
136 close(tmp_fd);
137 if (close(outfd) == -1) {
138 status = map_nt_error_from_unix(errno);
139 goto out;
142 status = NT_STATUS_OK;
144 out:
145 TALLOC_FREE(ctx);
146 return status;
149 /****************************************************************************
150 Delete all streams
151 ****************************************************************************/
153 NTSTATUS delete_all_streams(connection_struct *conn,
154 const struct smb_filename *smb_fname)
156 struct stream_struct *stream_info = NULL;
157 unsigned int i;
158 unsigned int num_streams = 0;
159 TALLOC_CTX *frame = talloc_stackframe();
160 NTSTATUS status;
162 status = vfs_fstreaminfo(smb_fname->fsp, talloc_tos(),
163 &num_streams, &stream_info);
165 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
166 DEBUG(10, ("no streams around\n"));
167 TALLOC_FREE(frame);
168 return NT_STATUS_OK;
171 if (!NT_STATUS_IS_OK(status)) {
172 DEBUG(10, ("vfs_fstreaminfo failed: %s\n",
173 nt_errstr(status)));
174 goto fail;
177 DEBUG(10, ("delete_all_streams found %d streams\n",
178 num_streams));
180 if (num_streams == 0) {
181 TALLOC_FREE(frame);
182 return NT_STATUS_OK;
185 for (i=0; i<num_streams; i++) {
186 int res;
187 struct smb_filename *smb_fname_stream;
189 if (strequal(stream_info[i].name, "::$DATA")) {
190 continue;
193 status = synthetic_pathref(talloc_tos(),
194 conn->cwd_fsp,
195 smb_fname->base_name,
196 stream_info[i].name,
197 NULL,
198 smb_fname->twrp,
199 (smb_fname->flags &
200 ~SMB_FILENAME_POSIX_PATH),
201 &smb_fname_stream);
202 if (!NT_STATUS_IS_OK(status)) {
203 DEBUG(0, ("talloc_aprintf failed\n"));
204 status = NT_STATUS_NO_MEMORY;
205 goto fail;
208 res = SMB_VFS_UNLINKAT(conn,
209 conn->cwd_fsp,
210 smb_fname_stream,
213 if (res == -1) {
214 status = map_nt_error_from_unix(errno);
215 DEBUG(10, ("Could not delete stream %s: %s\n",
216 smb_fname_str_dbg(smb_fname_stream),
217 strerror(errno)));
218 TALLOC_FREE(smb_fname_stream);
219 break;
221 TALLOC_FREE(smb_fname_stream);
224 fail:
225 TALLOC_FREE(frame);
226 return status;
229 struct has_other_nonposix_opens_state {
230 files_struct *fsp;
231 bool found_another;
234 static bool has_other_nonposix_opens_fn(
235 struct share_mode_entry *e,
236 bool *modified,
237 void *private_data)
239 struct has_other_nonposix_opens_state *state = private_data;
240 struct files_struct *fsp = state->fsp;
242 if (e->flags & SHARE_MODE_FLAG_POSIX_OPEN) {
243 return false;
245 if (fsp != NULL) {
246 if (e->name_hash != fsp->name_hash) {
247 return false;
249 if (e->share_file_id == fh_get_gen_id(fsp->fh)) {
250 struct server_id self = messaging_server_id(
251 fsp->conn->sconn->msg_ctx);
252 if (server_id_equal(&self, &e->pid)) {
253 return false;
257 if (share_entry_stale_pid(e)) {
258 return false;
261 state->found_another = true;
262 return true;
265 bool has_other_nonposix_opens(struct share_mode_lock *lck,
266 struct files_struct *fsp)
268 struct has_other_nonposix_opens_state state = { .fsp = fsp };
269 bool ok;
271 ok = share_mode_forall_entries(
272 lck, has_other_nonposix_opens_fn, &state);
273 if (!ok) {
274 return false;
276 return state.found_another;
279 bool has_nonposix_opens(struct share_mode_lock *lck)
281 struct has_other_nonposix_opens_state state = {};
282 bool ok;
284 ok = share_mode_forall_entries(
285 lck, has_other_nonposix_opens_fn, &state);
286 if (!ok) {
287 return false;
289 return state.found_another;
292 struct close_share_mode_lock_state {
293 struct share_mode_entry_prepare_state prepare_state;
294 const char *object_type;
295 struct files_struct *fsp;
296 enum file_close_type close_type;
297 bool delete_object;
298 bool got_tokens;
299 struct smb2_lease_key parent_lease_key;
300 const struct security_unix_token *del_token;
301 const struct security_token *del_nt_token;
302 bool reset_delete_on_close;
303 share_mode_entry_prepare_unlock_fn_t cleanup_fn;
306 static void close_share_mode_lock_prepare(struct share_mode_lock *lck,
307 bool *keep_locked,
308 void *private_data)
310 struct close_share_mode_lock_state *state =
311 (struct close_share_mode_lock_state *)private_data;
312 struct files_struct *fsp = state->fsp;
313 bool normal_close;
314 bool ok;
317 * By default drop the g_lock again if we leave the
318 * tdb chainlock.
320 *keep_locked = false;
322 if (fsp->oplock_type != NO_OPLOCK) {
323 ok = remove_share_oplock(lck, fsp);
324 if (!ok) {
325 struct file_id_buf buf;
327 DBG_ERR("failed to remove share oplock for "
328 "%s %s, %s, %s\n",
329 state->object_type,
330 fsp_str_dbg(fsp), fsp_fnum_dbg(fsp),
331 file_id_str_buf(fsp->file_id, &buf));
335 if (fsp->fsp_flags.write_time_forced) {
336 NTTIME mtime = share_mode_changed_write_time(lck);
337 struct timespec ts = nt_time_to_full_timespec(mtime);
339 DBG_DEBUG("write time forced for %s %s\n",
340 state->object_type, fsp_str_dbg(fsp));
341 set_close_write_time(fsp, ts);
342 } else if (fsp->fsp_flags.update_write_time_on_close) {
343 /* Someone had a pending write. */
344 if (is_omit_timespec(&fsp->close_write_time)) {
345 DBG_DEBUG("update to current time for %s %s\n",
346 state->object_type, fsp_str_dbg(fsp));
347 /* Update to current time due to "normal" write. */
348 set_close_write_time(fsp, timespec_current());
349 } else {
350 DBG_DEBUG("write time pending for %s %s\n",
351 state->object_type, fsp_str_dbg(fsp));
352 /* Update to time set on close call. */
353 set_close_write_time(fsp, fsp->close_write_time);
357 if (fsp->fsp_flags.initial_delete_on_close &&
358 !is_delete_on_close_set(lck, fsp->name_hash)) {
359 /* Initial delete on close was set and no one else
360 * wrote a real delete on close. */
362 fsp->fsp_flags.delete_on_close = true;
363 set_delete_on_close_lck(fsp, lck,
364 fsp->conn->session_info->security_token,
365 fsp->conn->session_info->unix_token);
368 state->delete_object = is_delete_on_close_set(lck, fsp->name_hash) &&
369 !has_other_nonposix_opens(lck, fsp);
372 * NT can set delete_on_close of the last open
373 * reference to a file.
376 normal_close = (state->close_type == NORMAL_CLOSE || state->close_type == SHUTDOWN_CLOSE);
377 if (!normal_close) {
379 * Never try to delete the file/directory for ERROR_CLOSE
381 state->delete_object = false;
384 if (!state->delete_object) {
385 ok = del_share_mode(lck, fsp);
386 if (!ok) {
387 DBG_ERR("Could not delete share entry for %s %s\n",
388 state->object_type, fsp_str_dbg(fsp));
390 return;
394 * We're going to remove the file/directory
395 * so keep the g_lock after the tdb chainlock
396 * is left, so we hold the share_mode_lock
397 * also during the deletion
399 *keep_locked = true;
401 state->got_tokens = get_delete_on_close_token(lck,
402 fsp->name_hash,
403 &state->del_nt_token,
404 &state->del_token,
405 &state->parent_lease_key);
406 if (state->close_type != ERROR_CLOSE) {
407 SMB_ASSERT(state->got_tokens);
411 static void close_share_mode_lock_cleanup(struct share_mode_lock *lck,
412 void *private_data)
414 struct close_share_mode_lock_state *state =
415 (struct close_share_mode_lock_state *)private_data;
416 struct files_struct *fsp = state->fsp;
417 bool ok;
419 if (state->reset_delete_on_close) {
420 reset_delete_on_close_lck(fsp, lck);
423 ok = del_share_mode(lck, fsp);
424 if (!ok) {
425 DBG_ERR("Could not delete share entry for %s %s\n",
426 state->object_type, fsp_str_dbg(fsp));
430 /****************************************************************************
431 Deal with removing a share mode on last close.
432 ****************************************************************************/
434 static NTSTATUS close_remove_share_mode(files_struct *fsp,
435 enum file_close_type close_type)
437 connection_struct *conn = fsp->conn;
438 struct close_share_mode_lock_state lck_state = {};
439 bool changed_user = false;
440 NTSTATUS status = NT_STATUS_OK;
441 NTSTATUS tmp_status;
442 NTSTATUS ulstatus;
443 struct file_id id;
444 struct smb_filename *parent_fname = NULL;
445 struct smb_filename *base_fname = NULL;
446 int ret;
448 /* Ensure any pending write time updates are done. */
449 if (fsp->update_write_time_event) {
450 fsp_flush_write_time_update(fsp);
454 * Lock the share entries, and determine if we should delete
455 * on close. If so delete whilst the lock is still in effect.
456 * This prevents race conditions with the file being created. JRA.
459 lck_state = (struct close_share_mode_lock_state) {
460 .fsp = fsp,
461 .object_type = "file",
462 .close_type = close_type,
465 status = share_mode_entry_prepare_lock_del(&lck_state.prepare_state,
466 fsp->file_id,
467 close_share_mode_lock_prepare,
468 &lck_state);
469 if (!NT_STATUS_IS_OK(status)) {
470 DBG_ERR("share_mode_entry_prepare_lock_del() failed for %s - %s\n",
471 fsp_str_dbg(fsp), nt_errstr(status));
472 return status;
475 /* Remove the oplock before potentially deleting the file. */
476 if (fsp->oplock_type != NO_OPLOCK) {
477 release_file_oplock(fsp);
481 * NT can set delete_on_close of the last open
482 * reference to a file.
485 if (!lck_state.delete_object) {
486 status = NT_STATUS_OK;
487 goto done;
491 * Ok, we have to delete the file
493 lck_state.cleanup_fn = close_share_mode_lock_cleanup;
495 DBG_INFO("%s. Delete on close was set - deleting file.\n",
496 fsp_str_dbg(fsp));
499 * Don't try to update the write time when we delete the file
501 fsp->fsp_flags.update_write_time_on_close = false;
503 if (lck_state.got_tokens &&
504 !unix_token_equal(lck_state.del_token, get_current_utok(conn)))
506 /* Become the user who requested the delete. */
508 DBG_INFO("file %s. Change user to uid %u\n",
509 fsp_str_dbg(fsp),
510 (unsigned int)lck_state.del_token->uid);
512 if (!push_sec_ctx()) {
513 smb_panic("close_remove_share_mode: file %s. failed to push "
514 "sec_ctx.\n");
517 set_sec_ctx(lck_state.del_token->uid,
518 lck_state.del_token->gid,
519 lck_state.del_token->ngroups,
520 lck_state.del_token->groups,
521 lck_state.del_nt_token);
523 changed_user = true;
526 /* We can only delete the file if the name we have is still valid and
527 hasn't been renamed. */
529 tmp_status = vfs_stat_fsp(fsp);
530 if (!NT_STATUS_IS_OK(tmp_status)) {
531 DBG_INFO("file %s. Delete on close "
532 "was set and stat failed with error %s\n",
533 fsp_str_dbg(fsp),
534 nt_errstr(tmp_status));
536 * Don't save the errno here, we ignore this error
538 goto done;
541 id = vfs_file_id_from_sbuf(conn, &fsp->fsp_name->st);
543 if (!file_id_equal(&fsp->file_id, &id)) {
544 struct file_id_buf ftmp1, ftmp2;
545 DBG_INFO("file %s. Delete on close "
546 "was set and dev and/or inode does not match\n",
547 fsp_str_dbg(fsp));
548 DBG_INFO("file %s. stored file_id %s, stat file_id %s\n",
549 fsp_str_dbg(fsp),
550 file_id_str_buf(fsp->file_id, &ftmp1),
551 file_id_str_buf(id, &ftmp2));
553 * Don't save the errno here, we ignore this error
555 goto done;
558 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
559 && !fsp_is_alternate_stream(fsp)) {
561 status = delete_all_streams(conn, fsp->fsp_name);
563 if (!NT_STATUS_IS_OK(status)) {
564 DEBUG(5, ("delete_all_streams failed: %s\n",
565 nt_errstr(status)));
566 goto done;
570 if (fsp->fsp_flags.kernel_share_modes_taken) {
572 * A file system sharemode could block the unlink;
573 * remove filesystem sharemodes first.
575 ret = SMB_VFS_FILESYSTEM_SHAREMODE(fsp, 0, 0);
576 if (ret == -1) {
577 DBG_INFO("Removing file system sharemode for %s "
578 "failed: %s\n",
579 fsp_str_dbg(fsp), strerror(errno));
582 fsp->fsp_flags.kernel_share_modes_taken = false;
585 status = parent_pathref(talloc_tos(),
586 conn->cwd_fsp,
587 fsp->fsp_name,
588 &parent_fname,
589 &base_fname);
590 if (!NT_STATUS_IS_OK(status)) {
591 goto done;
594 ret = SMB_VFS_UNLINKAT(conn,
595 parent_fname->fsp,
596 base_fname,
598 TALLOC_FREE(parent_fname);
599 base_fname = NULL;
600 if (ret != 0) {
602 * This call can potentially fail as another smbd may
603 * have had the file open with delete on close set and
604 * deleted it when its last reference to this file
605 * went away. Hence we log this but not at debug level
606 * zero.
609 DBG_INFO("file %s. Delete on close "
610 "was set and unlink failed with error %s\n",
611 fsp_str_dbg(fsp),
612 strerror(errno));
614 status = map_nt_error_from_unix(errno);
617 /* As we now have POSIX opens which can unlink
618 * with other open files we may have taken
619 * this code path with more than one share mode
620 * entry - ensure we only delete once by resetting
621 * the delete on close flag. JRA.
624 fsp->fsp_flags.delete_on_close = false;
625 fsp->fsp_flags.fstat_before_close = false;
626 lck_state.reset_delete_on_close = true;
628 done:
630 if (changed_user) {
631 /* unbecome user. */
632 pop_sec_ctx();
635 if (fsp->fsp_flags.kernel_share_modes_taken) {
636 /* remove filesystem sharemodes */
637 ret = SMB_VFS_FILESYSTEM_SHAREMODE(fsp, 0, 0);
638 if (ret == -1) {
639 DBG_INFO("Removing file system sharemode for "
640 "%s failed: %s\n",
641 fsp_str_dbg(fsp), strerror(errno));
645 ulstatus = share_mode_entry_prepare_unlock(&lck_state.prepare_state,
646 lck_state.cleanup_fn,
647 &lck_state);
648 if (!NT_STATUS_IS_OK(ulstatus)) {
649 DBG_ERR("share_mode_entry_prepare_unlock() failed for %s - %s\n",
650 fsp_str_dbg(fsp), nt_errstr(ulstatus));
651 smb_panic("share_mode_entry_prepare_unlock() failed!");
654 if (lck_state.delete_object && NT_STATUS_IS_OK(status)) {
655 const struct smb2_lease *lease = fsp_get_smb2_lease(fsp);
657 if (lease != NULL) {
659 * If parent lease key of handle on which delete
660 * disposition was set does not match the parent key of
661 * last closed handle, break all leases on the parent
662 * directory.
664 if (!smb2_lease_key_equal(&lease->parent_lease_key,
665 &lck_state.parent_lease_key))
667 lease = NULL;
670 notify_fname(conn,
671 NOTIFY_ACTION_REMOVED |
672 NOTIFY_ACTION_DIRLEASE_BREAK,
673 FILE_NOTIFY_CHANGE_FILE_NAME,
674 fsp->fsp_name,
675 lease);
678 return status;
681 void set_close_write_time(struct files_struct *fsp, struct timespec ts)
683 DEBUG(6,("close_write_time: %s" , time_to_asc(convert_timespec_to_time_t(ts))));
685 if (is_omit_timespec(&ts)) {
686 return;
688 fsp->fsp_flags.write_time_forced = false;
689 fsp->fsp_flags.update_write_time_on_close = true;
690 fsp->close_write_time = ts;
693 static void update_write_time_on_close_share_mode_fn(struct share_mode_lock *lck,
694 void *private_data)
696 struct files_struct *fsp =
697 talloc_get_type_abort(private_data,
698 struct files_struct);
699 NTTIME share_mtime = share_mode_changed_write_time(lck);
702 * On close if we're changing the real file time we
703 * must update it in the open file db too.
705 share_mode_set_old_write_time(lck, fsp->close_write_time);
708 * Close write times overwrite sticky write times
709 * so we must replace any sticky write time here.
711 if (!null_nttime(share_mtime)) {
712 share_mode_set_changed_write_time(lck, fsp->close_write_time);
716 static NTSTATUS update_write_time_on_close(struct files_struct *fsp)
718 struct smb_file_time ft;
719 NTSTATUS status;
721 init_smb_file_time(&ft);
723 if (!(fsp->fsp_flags.update_write_time_on_close)) {
724 return NT_STATUS_OK;
727 if (is_omit_timespec(&fsp->close_write_time)) {
728 fsp->close_write_time = timespec_current();
731 /* Ensure we have a valid stat struct for the source. */
732 status = vfs_stat_fsp(fsp);
733 if (!NT_STATUS_IS_OK(status)) {
734 return status;
737 if (!VALID_STAT(fsp->fsp_name->st)) {
738 /* if it doesn't seem to be a real file */
739 return NT_STATUS_OK;
743 * We're being called after close_remove_share_mode() inside
744 * close_normal_file() so it's quite normal to not have an
745 * existing share. So just ignore the result of
746 * share_mode_do_locked_vfs_denied()...
748 share_mode_do_locked_vfs_denied(fsp->file_id,
749 update_write_time_on_close_share_mode_fn,
750 fsp);
752 ft.mtime = fsp->close_write_time;
753 /* As this is a close based update, we are not directly changing the
754 file attributes from a client call, but indirectly from a write. */
755 status = smb_set_file_time(fsp->conn, fsp, fsp->fsp_name, &ft, false);
756 if (!NT_STATUS_IS_OK(status)) {
757 DEBUG(10,("update_write_time_on_close: smb_set_file_time "
758 "on file %s returned %s\n",
759 fsp_str_dbg(fsp),
760 nt_errstr(status)));
761 return status;
764 return status;
767 static NTSTATUS ntstatus_keeperror(NTSTATUS s1, NTSTATUS s2)
769 if (!NT_STATUS_IS_OK(s1)) {
770 return s1;
772 return s2;
775 static void assert_no_pending_aio(struct files_struct *fsp,
776 enum file_close_type close_type)
778 struct smbXsrv_client *client = global_smbXsrv_client;
779 size_t num_connections_alive;
780 unsigned num_requests = fsp->num_aio_requests;
782 if (num_requests == 0) {
783 return;
786 num_connections_alive = smbXsrv_client_valid_connections(client);
788 if (close_type == SHUTDOWN_CLOSE && num_connections_alive == 0) {
790 * fsp->aio_requests and the contents (fsp->aio_requests[x])
791 * are both independently owned by fsp and are not in a
792 * talloc hierarchy. This allows the fsp->aio_requests array to
793 * be reallocated independently of the array contents so it can
794 * grow on demand.
796 * This means we must ensure order of deallocation
797 * on a SHUTDOWN_CLOSE by deallocating the fsp->aio_requests[x]
798 * contents first, as their destructors access the
799 * fsp->aio_request array. If we don't deallocate them
800 * first, when fsp is deallocated fsp->aio_requests
801 * could have been deallocated *before* its contents
802 * fsp->aio_requests[x], causing a crash.
804 while (fsp->num_aio_requests != 0) {
806 * NB. We *MUST* use
807 * talloc_free(fsp->aio_requests[0]),
808 * and *NOT* TALLOC_FREE() here, as
809 * TALLOC_FREE(fsp->aio_requests[0])
810 * will overwrite any new contents of
811 * fsp->aio_requests[0] that were
812 * copied into it via the destructor
813 * aio_del_req_from_fsp().
815 * BUG: https://bugzilla.samba.org/show_bug.cgi?id=14515
817 talloc_free(fsp->aio_requests[0]);
819 return;
822 DBG_ERR("fsp->num_aio_requests=%u\n", num_requests);
823 smb_panic("can not close with outstanding aio requests");
824 return;
827 /****************************************************************************
828 Close a file.
830 close_type can be NORMAL_CLOSE=0,SHUTDOWN_CLOSE,ERROR_CLOSE.
831 printing and magic scripts are only run on normal close.
832 delete on close is done on normal and shutdown close.
833 ****************************************************************************/
835 static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp,
836 enum file_close_type close_type)
838 NTSTATUS status = NT_STATUS_OK;
839 NTSTATUS tmp;
840 connection_struct *conn = fsp->conn;
841 bool is_durable = false;
843 SMB_ASSERT(fsp->fsp_flags.is_fsa);
845 assert_no_pending_aio(fsp, close_type);
847 while (talloc_array_length(fsp->blocked_smb1_lock_reqs) != 0) {
848 smbd_smb1_brl_finish_by_req(
849 fsp->blocked_smb1_lock_reqs[0],
850 NT_STATUS_RANGE_NOT_LOCKED);
854 * If we're flushing on a close we can get a write
855 * error here, we must remember this.
858 if (NT_STATUS_IS_OK(status) && fsp->op != NULL) {
859 is_durable = fsp->op->global->durable;
862 if (close_type != SHUTDOWN_CLOSE) {
863 is_durable = false;
866 if (is_durable) {
867 DATA_BLOB new_cookie = data_blob_null;
869 tmp = SMB_VFS_DURABLE_DISCONNECT(fsp,
870 fsp->op->global->backend_cookie,
871 fsp->op,
872 &new_cookie);
873 if (NT_STATUS_IS_OK(tmp)) {
874 struct timeval tv;
875 NTTIME now;
877 if (req != NULL) {
878 tv = req->request_time;
879 } else {
880 tv = timeval_current();
882 now = timeval_to_nttime(&tv);
884 data_blob_free(&fsp->op->global->backend_cookie);
885 fsp->op->global->backend_cookie = new_cookie;
887 fsp->op->compat = NULL;
888 tmp = smbXsrv_open_close(fsp->op, now);
889 if (!NT_STATUS_IS_OK(tmp)) {
890 DEBUG(1, ("Failed to update smbXsrv_open "
891 "record when disconnecting durable "
892 "handle for file %s: %s - "
893 "proceeding with normal close\n",
894 fsp_str_dbg(fsp), nt_errstr(tmp)));
896 scavenger_schedule_disconnected(fsp);
897 } else {
898 DEBUG(1, ("Failed to disconnect durable handle for "
899 "file %s: %s - proceeding with normal "
900 "close\n", fsp_str_dbg(fsp), nt_errstr(tmp)));
902 if (!NT_STATUS_IS_OK(tmp)) {
903 is_durable = false;
907 if (is_durable) {
909 * This is the case where we successfully disconnected
910 * a durable handle and closed the underlying file.
911 * In all other cases, we proceed with a genuine close.
913 DEBUG(10, ("%s disconnected durable handle for file %s\n",
914 conn->session_info->unix_info->unix_name,
915 fsp_str_dbg(fsp)));
916 return NT_STATUS_OK;
919 if (fsp->op != NULL) {
921 * Make sure the handle is not marked as durable anymore
923 fsp->op->global->durable = false;
926 if (fsp->fsp_flags.modified) {
927 notify_fname(conn,
928 NOTIFY_ACTION_DIRLEASE_BREAK,
930 fsp->fsp_name,
931 fsp_get_smb2_lease(fsp));
934 /* If this is an old DOS or FCB open and we have multiple opens on
935 the same handle we only have one share mode. Ensure we only remove
936 the share mode on the last close. */
938 if (fh_get_refcount(fsp->fh) == 1) {
939 /* Should we return on error here... ? */
940 tmp = close_remove_share_mode(fsp, close_type);
941 status = ntstatus_keeperror(status, tmp);
944 locking_close_file(fsp, close_type);
947 * Ensure pending modtime is set before closing underlying fd.
950 tmp = update_write_time_on_close(fsp);
951 if (NT_STATUS_EQUAL(tmp, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
953 * Someone renamed the file or a parent directory containing
954 * this file. We can't do anything about this, eat the error.
956 tmp = NT_STATUS_OK;
958 status = ntstatus_keeperror(status, tmp);
960 tmp = fd_close(fsp);
961 status = ntstatus_keeperror(status, tmp);
963 /* check for magic scripts */
964 if (close_type == NORMAL_CLOSE) {
965 tmp = check_magic(fsp);
966 status = ntstatus_keeperror(status, tmp);
969 DEBUG(2,("%s closed file %s (numopen=%d) %s\n",
970 conn->session_info->unix_info->unix_name, fsp_str_dbg(fsp),
971 conn->num_files_open - 1,
972 nt_errstr(status) ));
974 return status;
976 /****************************************************************************
977 Function used by reply_rmdir to delete an entire directory
978 tree recursively. Return True on ok, False on fail.
979 ****************************************************************************/
981 NTSTATUS recursive_rmdir(TALLOC_CTX *ctx,
982 connection_struct *conn,
983 struct smb_filename *smb_dname)
985 const char *dname = NULL;
986 char *talloced = NULL;
987 struct smb_Dir *dir_hnd = NULL;
988 struct files_struct *dirfsp = NULL;
989 int retval;
990 NTSTATUS status = NT_STATUS_OK;
992 SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
994 status = OpenDir(talloc_tos(),
995 conn,
996 smb_dname,
997 NULL,
999 &dir_hnd);
1000 if (!NT_STATUS_IS_OK(status)) {
1001 return status;
1004 dirfsp = dir_hnd_fetch_fsp(dir_hnd);
1006 while ((dname = ReadDirName(dir_hnd, &talloced))) {
1007 struct smb_filename *atname = NULL;
1008 struct smb_filename *smb_dname_full = NULL;
1009 char *fullname = NULL;
1010 bool do_break = true;
1011 int unlink_flags = 0;
1013 if (ISDOT(dname) || ISDOTDOT(dname)) {
1014 TALLOC_FREE(talloced);
1015 continue;
1018 /* Construct the full name. */
1019 fullname = talloc_asprintf(ctx,
1020 "%s/%s",
1021 smb_dname->base_name,
1022 dname);
1023 if (!fullname) {
1024 status = NT_STATUS_NO_MEMORY;
1025 goto err_break;
1028 smb_dname_full = synthetic_smb_fname(talloc_tos(),
1029 fullname,
1030 NULL,
1031 NULL,
1032 smb_dname->twrp,
1033 smb_dname->flags);
1034 if (smb_dname_full == NULL) {
1035 status = NT_STATUS_NO_MEMORY;
1036 goto err_break;
1039 if (SMB_VFS_LSTAT(conn, smb_dname_full) != 0) {
1040 status = map_nt_error_from_unix(errno);
1041 goto err_break;
1044 if (smb_dname_full->st.st_ex_mode & S_IFDIR) {
1045 status = recursive_rmdir(ctx, conn, smb_dname_full);
1046 if (!NT_STATUS_IS_OK(status)) {
1047 goto err_break;
1049 unlink_flags = AT_REMOVEDIR;
1052 status = synthetic_pathref(talloc_tos(),
1053 dirfsp,
1054 dname,
1055 NULL,
1056 &smb_dname_full->st,
1057 smb_dname_full->twrp,
1058 smb_dname_full->flags,
1059 &atname);
1060 if (!NT_STATUS_IS_OK(status)) {
1061 goto err_break;
1064 if (!is_visible_fsp(atname->fsp)) {
1065 TALLOC_FREE(smb_dname_full);
1066 TALLOC_FREE(fullname);
1067 TALLOC_FREE(talloced);
1068 TALLOC_FREE(atname);
1069 continue;
1072 retval = SMB_VFS_UNLINKAT(conn,
1073 dirfsp,
1074 atname,
1075 unlink_flags);
1076 if (retval != 0) {
1077 status = map_nt_error_from_unix(errno);
1078 goto err_break;
1081 /* Successful iteration. */
1082 do_break = false;
1084 err_break:
1085 TALLOC_FREE(smb_dname_full);
1086 TALLOC_FREE(fullname);
1087 TALLOC_FREE(talloced);
1088 TALLOC_FREE(atname);
1089 if (do_break) {
1090 break;
1093 TALLOC_FREE(dir_hnd);
1094 return status;
1097 /****************************************************************************
1098 The internals of the rmdir code - called elsewhere.
1099 ****************************************************************************/
1101 static NTSTATUS rmdir_internals(TALLOC_CTX *ctx, struct files_struct *fsp)
1103 struct connection_struct *conn = fsp->conn;
1104 struct smb_filename *smb_dname = fsp->fsp_name;
1105 struct smb_filename *parent_fname = NULL;
1106 struct smb_filename *at_fname = NULL;
1107 const char *dname = NULL;
1108 char *talloced = NULL;
1109 struct smb_Dir *dir_hnd = NULL;
1110 struct files_struct *dirfsp = NULL;
1111 int unlink_flags = 0;
1112 NTSTATUS status;
1113 int ret;
1115 SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
1117 status = parent_pathref(talloc_tos(),
1118 conn->cwd_fsp,
1119 fsp->fsp_name,
1120 &parent_fname,
1121 &at_fname);
1122 if (!NT_STATUS_IS_OK(status)) {
1123 return status;
1127 * Todo: use SMB_VFS_STATX() once it's available.
1130 /* Might be a symlink. */
1131 ret = SMB_VFS_LSTAT(conn, smb_dname);
1132 if (ret != 0) {
1133 TALLOC_FREE(parent_fname);
1134 return map_nt_error_from_unix(errno);
1137 if (S_ISLNK(smb_dname->st.st_ex_mode)) {
1138 /* Is what it points to a directory ? */
1139 ret = SMB_VFS_STAT(conn, smb_dname);
1140 if (ret != 0) {
1141 TALLOC_FREE(parent_fname);
1142 return map_nt_error_from_unix(errno);
1144 if (!(S_ISDIR(smb_dname->st.st_ex_mode))) {
1145 TALLOC_FREE(parent_fname);
1146 return NT_STATUS_NOT_A_DIRECTORY;
1148 } else {
1149 unlink_flags = AT_REMOVEDIR;
1152 ret = SMB_VFS_UNLINKAT(conn,
1153 parent_fname->fsp,
1154 at_fname,
1155 unlink_flags);
1156 if (ret == 0) {
1157 TALLOC_FREE(parent_fname);
1158 return NT_STATUS_OK;
1161 if (!((errno == ENOTEMPTY) || (errno == EEXIST))) {
1162 DEBUG(3,("rmdir_internals: couldn't remove directory %s : "
1163 "%s\n", smb_fname_str_dbg(smb_dname),
1164 strerror(errno)));
1165 TALLOC_FREE(parent_fname);
1166 return map_nt_error_from_unix(errno);
1170 * Here we know the initial directory unlink failed with
1171 * ENOTEMPTY or EEXIST so we know there are objects within.
1172 * If we don't have permission to delete files non
1173 * visible to the client just fail the directory delete.
1176 if (!lp_delete_veto_files(SNUM(conn))) {
1177 status = NT_STATUS_DIRECTORY_NOT_EMPTY;
1178 goto err;
1182 * Check to see if the only thing in this directory are
1183 * files non-visible to the client. If not, fail the delete.
1186 status = OpenDir_from_pathref(talloc_tos(), fsp, NULL, 0, &dir_hnd);
1187 if (!NT_STATUS_IS_OK(status)) {
1189 * Note, we deliberately squash the error here
1190 * to avoid leaking information about what we
1191 * can't delete.
1193 status = NT_STATUS_DIRECTORY_NOT_EMPTY;
1194 goto err;
1197 dirfsp = dir_hnd_fetch_fsp(dir_hnd);
1199 while ((dname = ReadDirName(dir_hnd, &talloced)) != NULL) {
1200 struct smb_filename *smb_dname_full = NULL;
1201 struct smb_filename *direntry_fname = NULL;
1202 char *fullname = NULL;
1203 int retval;
1205 if (ISDOT(dname) || ISDOTDOT(dname)) {
1206 TALLOC_FREE(talloced);
1207 continue;
1209 if (IS_VETO_PATH(conn, dname)) {
1210 TALLOC_FREE(talloced);
1211 continue;
1214 fullname = talloc_asprintf(talloc_tos(),
1215 "%s/%s",
1216 smb_dname->base_name,
1217 dname);
1219 if (fullname == NULL) {
1220 TALLOC_FREE(talloced);
1221 status = NT_STATUS_NO_MEMORY;
1222 goto err;
1225 smb_dname_full = synthetic_smb_fname(talloc_tos(),
1226 fullname,
1227 NULL,
1228 NULL,
1229 smb_dname->twrp,
1230 smb_dname->flags);
1231 if (smb_dname_full == NULL) {
1232 TALLOC_FREE(talloced);
1233 TALLOC_FREE(fullname);
1234 status = NT_STATUS_NO_MEMORY;
1235 goto err;
1238 retval = SMB_VFS_LSTAT(conn, smb_dname_full);
1239 if (retval != 0) {
1240 status = map_nt_error_from_unix(errno);
1241 TALLOC_FREE(talloced);
1242 TALLOC_FREE(fullname);
1243 TALLOC_FREE(smb_dname_full);
1244 goto err;
1247 if (S_ISLNK(smb_dname_full->st.st_ex_mode)) {
1248 /* Could it be an msdfs link ? */
1249 if (lp_host_msdfs() &&
1250 lp_msdfs_root(SNUM(conn))) {
1251 struct smb_filename *smb_atname;
1252 smb_atname = synthetic_smb_fname(talloc_tos(),
1253 dname,
1254 NULL,
1255 &smb_dname_full->st,
1256 fsp->fsp_name->twrp,
1257 fsp->fsp_name->flags);
1258 if (smb_atname == NULL) {
1259 TALLOC_FREE(talloced);
1260 TALLOC_FREE(fullname);
1261 TALLOC_FREE(smb_dname_full);
1262 status = NT_STATUS_NO_MEMORY;
1263 goto err;
1265 if (is_msdfs_link(fsp, smb_atname)) {
1266 TALLOC_FREE(talloced);
1267 TALLOC_FREE(fullname);
1268 TALLOC_FREE(smb_dname_full);
1269 TALLOC_FREE(smb_atname);
1270 DBG_DEBUG("got msdfs link name %s "
1271 "- can't delete directory %s\n",
1272 dname,
1273 fsp_str_dbg(fsp));
1274 status = NT_STATUS_DIRECTORY_NOT_EMPTY;
1275 goto err;
1277 TALLOC_FREE(smb_atname);
1280 /* Not a DFS link - could it be a dangling symlink ? */
1281 retval = SMB_VFS_STAT(conn, smb_dname_full);
1282 if (retval == -1 && (errno == ENOENT || errno == ELOOP)) {
1284 * Dangling symlink.
1285 * Allow delete as "delete veto files = yes"
1287 TALLOC_FREE(talloced);
1288 TALLOC_FREE(fullname);
1289 TALLOC_FREE(smb_dname_full);
1290 continue;
1293 DBG_DEBUG("got symlink name %s - "
1294 "can't delete directory %s\n",
1295 dname,
1296 fsp_str_dbg(fsp));
1297 TALLOC_FREE(talloced);
1298 TALLOC_FREE(fullname);
1299 TALLOC_FREE(smb_dname_full);
1300 status = NT_STATUS_DIRECTORY_NOT_EMPTY;
1301 goto err;
1304 /* Not a symlink, get a pathref. */
1305 status = synthetic_pathref(talloc_tos(),
1306 dirfsp,
1307 dname,
1308 NULL,
1309 &smb_dname_full->st,
1310 smb_dname->twrp,
1311 smb_dname->flags,
1312 &direntry_fname);
1313 if (!NT_STATUS_IS_OK(status)) {
1314 TALLOC_FREE(talloced);
1315 TALLOC_FREE(fullname);
1316 TALLOC_FREE(smb_dname_full);
1317 goto err;
1320 if (!is_visible_fsp(direntry_fname->fsp)) {
1321 TALLOC_FREE(talloced);
1322 TALLOC_FREE(fullname);
1323 TALLOC_FREE(smb_dname_full);
1324 TALLOC_FREE(direntry_fname);
1325 continue;
1329 * We found a client visible name.
1330 * We cannot delete this directory.
1332 DBG_DEBUG("got name %s - "
1333 "can't delete directory %s\n",
1334 dname,
1335 fsp_str_dbg(fsp));
1336 TALLOC_FREE(talloced);
1337 TALLOC_FREE(fullname);
1338 TALLOC_FREE(smb_dname_full);
1339 TALLOC_FREE(direntry_fname);
1340 status = NT_STATUS_DIRECTORY_NOT_EMPTY;
1341 goto err;
1344 /* Do a recursive delete. */
1345 RewindDir(dir_hnd);
1347 while ((dname = ReadDirName(dir_hnd, &talloced)) != NULL) {
1348 struct smb_filename *direntry_fname = NULL;
1349 struct smb_filename *smb_dname_full = NULL;
1350 char *fullname = NULL;
1351 bool do_break = true;
1352 int retval;
1354 if (ISDOT(dname) || ISDOTDOT(dname)) {
1355 TALLOC_FREE(talloced);
1356 continue;
1359 fullname = talloc_asprintf(ctx,
1360 "%s/%s",
1361 smb_dname->base_name,
1362 dname);
1364 if (fullname == NULL) {
1365 status = NT_STATUS_NO_MEMORY;
1366 goto err_break;
1369 smb_dname_full = synthetic_smb_fname(talloc_tos(),
1370 fullname,
1371 NULL,
1372 NULL,
1373 smb_dname->twrp,
1374 smb_dname->flags);
1375 if (smb_dname_full == NULL) {
1376 status = NT_STATUS_NO_MEMORY;
1377 goto err_break;
1381 * Todo: use SMB_VFS_STATX() once that's available.
1384 retval = SMB_VFS_LSTAT(conn, smb_dname_full);
1385 if (retval != 0) {
1386 status = map_nt_error_from_unix(errno);
1387 goto err_break;
1391 * We are only dealing with VETO'ed objects
1392 * here. If it's a symlink, just delete the
1393 * link without caring what it is pointing
1394 * to.
1396 if (S_ISLNK(smb_dname_full->st.st_ex_mode)) {
1397 direntry_fname = synthetic_smb_fname(talloc_tos(),
1398 dname,
1399 NULL,
1400 &smb_dname_full->st,
1401 smb_dname->twrp,
1402 smb_dname->flags);
1403 if (direntry_fname == NULL) {
1404 status = NT_STATUS_NO_MEMORY;
1405 goto err_break;
1407 } else {
1408 status = synthetic_pathref(talloc_tos(),
1409 dirfsp,
1410 dname,
1411 NULL,
1412 &smb_dname_full->st,
1413 smb_dname->twrp,
1414 smb_dname->flags,
1415 &direntry_fname);
1416 if (!NT_STATUS_IS_OK(status)) {
1417 goto err_break;
1420 if (!is_visible_fsp(direntry_fname->fsp)) {
1421 TALLOC_FREE(fullname);
1422 TALLOC_FREE(smb_dname_full);
1423 TALLOC_FREE(talloced);
1424 TALLOC_FREE(direntry_fname);
1425 continue;
1429 unlink_flags = 0;
1431 if (smb_dname_full->st.st_ex_mode & S_IFDIR) {
1432 status = recursive_rmdir(ctx, conn, smb_dname_full);
1433 if (!NT_STATUS_IS_OK(status)) {
1434 goto err_break;
1436 unlink_flags = AT_REMOVEDIR;
1439 retval = SMB_VFS_UNLINKAT(conn,
1440 dirfsp,
1441 direntry_fname,
1442 unlink_flags);
1443 if (retval != 0) {
1444 status = map_nt_error_from_unix(errno);
1445 goto err_break;
1448 /* Successful iteration. */
1449 do_break = false;
1451 err_break:
1452 TALLOC_FREE(fullname);
1453 TALLOC_FREE(smb_dname_full);
1454 TALLOC_FREE(talloced);
1455 TALLOC_FREE(direntry_fname);
1456 if (do_break) {
1457 break;
1461 /* If we get here, we know NT_STATUS_IS_OK(status) */
1462 SMB_ASSERT(NT_STATUS_IS_OK(status));
1464 /* Retry the rmdir */
1465 ret = SMB_VFS_UNLINKAT(conn,
1466 parent_fname->fsp,
1467 at_fname,
1468 AT_REMOVEDIR);
1469 if (ret != 0) {
1470 status = map_nt_error_from_unix(errno);
1473 err:
1475 TALLOC_FREE(dir_hnd);
1476 TALLOC_FREE(parent_fname);
1478 if (!NT_STATUS_IS_OK(status)) {
1479 DBG_NOTICE("couldn't remove directory %s : "
1480 "%s\n", smb_fname_str_dbg(smb_dname),
1481 nt_errstr(status));
1482 return status;
1485 return status;
1488 /****************************************************************************
1489 Close a directory opened by an NT SMB call.
1490 ****************************************************************************/
1492 static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
1493 enum file_close_type close_type)
1495 connection_struct *conn = fsp->conn;
1496 struct close_share_mode_lock_state lck_state = {};
1497 bool changed_user = false;
1498 NTSTATUS status = NT_STATUS_OK;
1499 NTSTATUS status1 = NT_STATUS_OK;
1500 NTSTATUS notify_status;
1501 NTSTATUS ulstatus;
1503 SMB_ASSERT(fsp->fsp_flags.is_fsa);
1505 if (conn_using_smb2(fsp->conn->sconn)) {
1506 notify_status = NT_STATUS_NOTIFY_CLEANUP;
1507 } else {
1508 notify_status = NT_STATUS_OK;
1511 assert_no_pending_aio(fsp, close_type);
1514 * NT can set delete_on_close of the last open
1515 * reference to a directory also.
1518 lck_state = (struct close_share_mode_lock_state) {
1519 .fsp = fsp,
1520 .object_type = "directory",
1521 .close_type = close_type,
1524 status = share_mode_entry_prepare_lock_del(&lck_state.prepare_state,
1525 fsp->file_id,
1526 close_share_mode_lock_prepare,
1527 &lck_state);
1528 if (!NT_STATUS_IS_OK(status)) {
1529 DBG_ERR("share_mode_entry_prepare_lock_del() failed for %s - %s\n",
1530 fsp_str_dbg(fsp), nt_errstr(status));
1531 log_stack_trace();
1532 goto close_fd;
1535 /* Remove the oplock before potentially deleting the file. */
1536 if (fsp->oplock_type != NO_OPLOCK) {
1537 release_file_oplock(fsp);
1541 * NT can set delete_on_close of the last open
1542 * reference to a file.
1545 if (!lck_state.delete_object) {
1546 status = NT_STATUS_OK;
1547 goto done;
1551 * Ok, we have to delete the directory
1553 lck_state.cleanup_fn = close_share_mode_lock_cleanup;
1555 if (lck_state.got_tokens &&
1556 !unix_token_equal(lck_state.del_token, get_current_utok(conn)))
1558 /* Become the user who requested the delete. */
1560 DBG_INFO("dir %s. Change user to uid %u\n",
1561 fsp_str_dbg(fsp),
1562 (unsigned int)lck_state.del_token->uid);
1564 if (!push_sec_ctx()) {
1565 smb_panic("close_directory: failed to push sec_ctx.\n");
1568 set_sec_ctx(lck_state.del_token->uid,
1569 lck_state.del_token->gid,
1570 lck_state.del_token->ngroups,
1571 lck_state.del_token->groups,
1572 lck_state.del_nt_token);
1574 changed_user = true;
1577 if ((fsp->conn->fs_capabilities & FILE_NAMED_STREAMS)
1578 && !is_ntfs_stream_smb_fname(fsp->fsp_name)) {
1580 status = delete_all_streams(fsp->conn, fsp->fsp_name);
1581 if (!NT_STATUS_IS_OK(status)) {
1582 DEBUG(5, ("delete_all_streams failed: %s\n",
1583 nt_errstr(status)));
1584 goto done;
1588 status = rmdir_internals(talloc_tos(), fsp);
1590 DEBUG(5,("close_directory: %s. Delete on close was set - "
1591 "deleting directory returned %s.\n",
1592 fsp_str_dbg(fsp), nt_errstr(status)));
1595 * Ensure we remove any change notify requests that would
1596 * now fail as the directory has been deleted.
1599 if (NT_STATUS_IS_OK(status)) {
1600 notify_status = NT_STATUS_DELETE_PENDING;
1603 done:
1604 if (changed_user) {
1605 /* unbecome user. */
1606 pop_sec_ctx();
1609 ulstatus = share_mode_entry_prepare_unlock(&lck_state.prepare_state,
1610 lck_state.cleanup_fn,
1611 &lck_state);
1612 if (!NT_STATUS_IS_OK(ulstatus)) {
1613 DBG_ERR("share_mode_entry_prepare_unlock() failed for %s - %s\n",
1614 fsp_str_dbg(fsp), nt_errstr(ulstatus));
1615 smb_panic("share_mode_entry_prepare_unlock() failed!");
1618 remove_pending_change_notify_requests_by_fid(fsp, notify_status);
1620 if (lck_state.delete_object && NT_STATUS_IS_OK(status)) {
1621 const struct smb2_lease *lease = fsp_get_smb2_lease(fsp);
1623 if (lease != NULL) {
1625 * If parent lease key of handle on which delete
1626 * disposition was set does not match the parent lease
1627 * key of last closed handle, break all leases on the
1628 * parent directory.
1630 if (!smb2_lease_key_equal(&lease->parent_lease_key,
1631 &lck_state.parent_lease_key))
1633 lease = NULL;
1636 notify_fname(conn,
1637 NOTIFY_ACTION_REMOVED |
1638 NOTIFY_ACTION_DIRLEASE_BREAK,
1639 FILE_NOTIFY_CHANGE_DIR_NAME,
1640 fsp->fsp_name,
1641 lease);
1644 close_fd:
1645 status1 = fd_close(fsp);
1647 if (!NT_STATUS_IS_OK(status1)) {
1648 DEBUG(0, ("Could not close dir! fname=%s, fd=%d, err=%d=%s\n",
1649 fsp_str_dbg(fsp), fsp_get_pathref_fd(fsp), errno,
1650 strerror(errno)));
1653 if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(status1)) {
1654 status = status1;
1656 return status;
1659 /****************************************************************************
1660 Rundown all SMB-related dependencies of a files struct
1661 ****************************************************************************/
1663 NTSTATUS close_file_smb(struct smb_request *req,
1664 struct files_struct *fsp,
1665 enum file_close_type close_type)
1667 NTSTATUS status;
1670 * This fsp can never be an internal dirfsp. They must
1671 * be explicitly closed by TALLOC_FREE of the dir handle.
1673 SMB_ASSERT(!fsp->fsp_flags.is_dirfsp);
1676 * Never call directly on a base fsp
1678 SMB_ASSERT(fsp->stream_fsp == NULL);
1680 if (fsp->fake_file_handle != NULL) {
1682 * Named pipes are opened as fake files and
1683 * can have pending aio requests. Ensure
1684 * we clear out all pending aio on force
1685 * shutdown of named pipes also.
1686 * BUG: https://bugzilla.samba.org/show_bug.cgi?id=15423
1688 assert_no_pending_aio(fsp, close_type);
1689 status = close_fake_file(req, fsp);
1690 } else if (fsp->print_file != NULL) {
1691 /* FIXME: return spool errors */
1692 print_spool_end(fsp, close_type);
1693 fd_close(fsp);
1694 status = NT_STATUS_OK;
1695 } else if (!fsp->fsp_flags.is_fsa) {
1696 if (close_type == NORMAL_CLOSE) {
1697 DBG_ERR("unexpected NORMAL_CLOSE for [%s] "
1698 "is_fsa[%u] is_pathref[%u] is_directory[%u]\n",
1699 fsp_str_dbg(fsp),
1700 fsp->fsp_flags.is_fsa,
1701 fsp->fsp_flags.is_pathref,
1702 fsp->fsp_flags.is_directory);
1704 SMB_ASSERT(close_type != NORMAL_CLOSE);
1705 fd_close(fsp);
1706 status = NT_STATUS_OK;
1707 } else if (fsp->fsp_flags.is_directory) {
1708 status = close_directory(req, fsp, close_type);
1709 } else {
1710 status = close_normal_file(req, fsp, close_type);
1713 if (fsp_is_alternate_stream(fsp)) {
1715 * fsp was a stream, its base_fsp can't be a stream
1716 * as well
1718 SMB_ASSERT(!fsp_is_alternate_stream(fsp->base_fsp));
1721 * There's a 1:1 relationship between fsp and a base_fsp
1723 SMB_ASSERT(fsp->base_fsp->stream_fsp == fsp);
1726 * Make base_fsp look standalone now
1728 fsp->base_fsp->stream_fsp = NULL;
1730 close_file_free(req, &fsp->base_fsp, close_type);
1733 fsp_unbind_smb(req, fsp);
1735 return status;
1738 NTSTATUS close_file_free(struct smb_request *req,
1739 struct files_struct **_fsp,
1740 enum file_close_type close_type)
1742 struct files_struct *fsp = *_fsp;
1743 NTSTATUS status;
1745 status = close_file_smb(req, fsp, close_type);
1747 file_free(req, fsp);
1748 *_fsp = NULL;
1750 return status;
1753 /****************************************************************************
1754 Deal with an (authorized) message to close a file given the share mode
1755 entry.
1756 ****************************************************************************/
1758 void msg_close_file(struct messaging_context *msg_ctx,
1759 void *private_data,
1760 uint32_t msg_type,
1761 struct server_id server_id,
1762 DATA_BLOB *data)
1764 struct oplock_break_message msg;
1765 enum ndr_err_code ndr_err;
1766 files_struct *fsp = NULL;
1767 struct smbd_server_connection *sconn =
1768 talloc_get_type_abort(private_data,
1769 struct smbd_server_connection);
1771 ndr_err = ndr_pull_struct_blob_all_noalloc(
1772 data,
1773 &msg,
1774 (ndr_pull_flags_fn_t)ndr_pull_oplock_break_message);
1775 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1776 DBG_DEBUG("ndr_pull_oplock_break_message failed: %s\n",
1777 ndr_errstr(ndr_err));
1778 return;
1781 fsp = file_find_dif(sconn, msg.id, msg.share_file_id);
1782 if (!fsp) {
1783 DEBUG(10,("msg_close_file: failed to find file.\n"));
1784 return;
1786 close_file_free(NULL, &fsp, NORMAL_CLOSE);