smbd: Make reopen_from_fsp() public
[samba4-gss.git] / source3 / smbd / close.c
blob603a4c01e7e38a93a7a85efcbc83f8b60ab2b945
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(talloc_tos(),
1187 conn,
1188 smb_dname,
1189 NULL,
1191 &dir_hnd);
1192 if (!NT_STATUS_IS_OK(status)) {
1194 * Note, we deliberately squash the error here
1195 * to avoid leaking information about what we
1196 * can't delete.
1198 status = NT_STATUS_DIRECTORY_NOT_EMPTY;
1199 goto err;
1202 dirfsp = dir_hnd_fetch_fsp(dir_hnd);
1204 while ((dname = ReadDirName(dir_hnd, &talloced)) != NULL) {
1205 struct smb_filename *smb_dname_full = NULL;
1206 struct smb_filename *direntry_fname = NULL;
1207 char *fullname = NULL;
1208 int retval;
1210 if (ISDOT(dname) || ISDOTDOT(dname)) {
1211 TALLOC_FREE(talloced);
1212 continue;
1214 if (IS_VETO_PATH(conn, dname)) {
1215 TALLOC_FREE(talloced);
1216 continue;
1219 fullname = talloc_asprintf(talloc_tos(),
1220 "%s/%s",
1221 smb_dname->base_name,
1222 dname);
1224 if (fullname == NULL) {
1225 TALLOC_FREE(talloced);
1226 status = NT_STATUS_NO_MEMORY;
1227 goto err;
1230 smb_dname_full = synthetic_smb_fname(talloc_tos(),
1231 fullname,
1232 NULL,
1233 NULL,
1234 smb_dname->twrp,
1235 smb_dname->flags);
1236 if (smb_dname_full == NULL) {
1237 TALLOC_FREE(talloced);
1238 TALLOC_FREE(fullname);
1239 status = NT_STATUS_NO_MEMORY;
1240 goto err;
1243 retval = SMB_VFS_LSTAT(conn, smb_dname_full);
1244 if (retval != 0) {
1245 status = map_nt_error_from_unix(errno);
1246 TALLOC_FREE(talloced);
1247 TALLOC_FREE(fullname);
1248 TALLOC_FREE(smb_dname_full);
1249 goto err;
1252 if (S_ISLNK(smb_dname_full->st.st_ex_mode)) {
1253 /* Could it be an msdfs link ? */
1254 if (lp_host_msdfs() &&
1255 lp_msdfs_root(SNUM(conn))) {
1256 struct smb_filename *smb_atname;
1257 smb_atname = synthetic_smb_fname(talloc_tos(),
1258 dname,
1259 NULL,
1260 &smb_dname_full->st,
1261 fsp->fsp_name->twrp,
1262 fsp->fsp_name->flags);
1263 if (smb_atname == NULL) {
1264 TALLOC_FREE(talloced);
1265 TALLOC_FREE(fullname);
1266 TALLOC_FREE(smb_dname_full);
1267 status = NT_STATUS_NO_MEMORY;
1268 goto err;
1270 if (is_msdfs_link(fsp, smb_atname)) {
1271 TALLOC_FREE(talloced);
1272 TALLOC_FREE(fullname);
1273 TALLOC_FREE(smb_dname_full);
1274 TALLOC_FREE(smb_atname);
1275 DBG_DEBUG("got msdfs link name %s "
1276 "- can't delete directory %s\n",
1277 dname,
1278 fsp_str_dbg(fsp));
1279 status = NT_STATUS_DIRECTORY_NOT_EMPTY;
1280 goto err;
1282 TALLOC_FREE(smb_atname);
1285 /* Not a DFS link - could it be a dangling symlink ? */
1286 retval = SMB_VFS_STAT(conn, smb_dname_full);
1287 if (retval == -1 && (errno == ENOENT || errno == ELOOP)) {
1289 * Dangling symlink.
1290 * Allow delete as "delete veto files = yes"
1292 TALLOC_FREE(talloced);
1293 TALLOC_FREE(fullname);
1294 TALLOC_FREE(smb_dname_full);
1295 continue;
1298 DBG_DEBUG("got symlink name %s - "
1299 "can't delete directory %s\n",
1300 dname,
1301 fsp_str_dbg(fsp));
1302 TALLOC_FREE(talloced);
1303 TALLOC_FREE(fullname);
1304 TALLOC_FREE(smb_dname_full);
1305 status = NT_STATUS_DIRECTORY_NOT_EMPTY;
1306 goto err;
1309 /* Not a symlink, get a pathref. */
1310 status = synthetic_pathref(talloc_tos(),
1311 dirfsp,
1312 dname,
1313 NULL,
1314 &smb_dname_full->st,
1315 smb_dname->twrp,
1316 smb_dname->flags,
1317 &direntry_fname);
1318 if (!NT_STATUS_IS_OK(status)) {
1319 TALLOC_FREE(talloced);
1320 TALLOC_FREE(fullname);
1321 TALLOC_FREE(smb_dname_full);
1322 goto err;
1325 if (!is_visible_fsp(direntry_fname->fsp)) {
1326 TALLOC_FREE(talloced);
1327 TALLOC_FREE(fullname);
1328 TALLOC_FREE(smb_dname_full);
1329 TALLOC_FREE(direntry_fname);
1330 continue;
1334 * We found a client visible name.
1335 * We cannot delete this directory.
1337 DBG_DEBUG("got name %s - "
1338 "can't delete directory %s\n",
1339 dname,
1340 fsp_str_dbg(fsp));
1341 TALLOC_FREE(talloced);
1342 TALLOC_FREE(fullname);
1343 TALLOC_FREE(smb_dname_full);
1344 TALLOC_FREE(direntry_fname);
1345 status = NT_STATUS_DIRECTORY_NOT_EMPTY;
1346 goto err;
1349 /* Do a recursive delete. */
1350 RewindDir(dir_hnd);
1352 while ((dname = ReadDirName(dir_hnd, &talloced)) != NULL) {
1353 struct smb_filename *direntry_fname = NULL;
1354 struct smb_filename *smb_dname_full = NULL;
1355 char *fullname = NULL;
1356 bool do_break = true;
1357 int retval;
1359 if (ISDOT(dname) || ISDOTDOT(dname)) {
1360 TALLOC_FREE(talloced);
1361 continue;
1364 fullname = talloc_asprintf(ctx,
1365 "%s/%s",
1366 smb_dname->base_name,
1367 dname);
1369 if (fullname == NULL) {
1370 status = NT_STATUS_NO_MEMORY;
1371 goto err_break;
1374 smb_dname_full = synthetic_smb_fname(talloc_tos(),
1375 fullname,
1376 NULL,
1377 NULL,
1378 smb_dname->twrp,
1379 smb_dname->flags);
1380 if (smb_dname_full == NULL) {
1381 status = NT_STATUS_NO_MEMORY;
1382 goto err_break;
1386 * Todo: use SMB_VFS_STATX() once that's available.
1389 retval = SMB_VFS_LSTAT(conn, smb_dname_full);
1390 if (retval != 0) {
1391 status = map_nt_error_from_unix(errno);
1392 goto err_break;
1396 * We are only dealing with VETO'ed objects
1397 * here. If it's a symlink, just delete the
1398 * link without caring what it is pointing
1399 * to.
1401 if (S_ISLNK(smb_dname_full->st.st_ex_mode)) {
1402 direntry_fname = synthetic_smb_fname(talloc_tos(),
1403 dname,
1404 NULL,
1405 &smb_dname_full->st,
1406 smb_dname->twrp,
1407 smb_dname->flags);
1408 if (direntry_fname == NULL) {
1409 status = NT_STATUS_NO_MEMORY;
1410 goto err_break;
1412 } else {
1413 status = synthetic_pathref(talloc_tos(),
1414 dirfsp,
1415 dname,
1416 NULL,
1417 &smb_dname_full->st,
1418 smb_dname->twrp,
1419 smb_dname->flags,
1420 &direntry_fname);
1421 if (!NT_STATUS_IS_OK(status)) {
1422 goto err_break;
1425 if (!is_visible_fsp(direntry_fname->fsp)) {
1426 TALLOC_FREE(fullname);
1427 TALLOC_FREE(smb_dname_full);
1428 TALLOC_FREE(talloced);
1429 TALLOC_FREE(direntry_fname);
1430 continue;
1434 unlink_flags = 0;
1436 if (smb_dname_full->st.st_ex_mode & S_IFDIR) {
1437 status = recursive_rmdir(ctx, conn, smb_dname_full);
1438 if (!NT_STATUS_IS_OK(status)) {
1439 goto err_break;
1441 unlink_flags = AT_REMOVEDIR;
1444 retval = SMB_VFS_UNLINKAT(conn,
1445 dirfsp,
1446 direntry_fname,
1447 unlink_flags);
1448 if (retval != 0) {
1449 status = map_nt_error_from_unix(errno);
1450 goto err_break;
1453 /* Successful iteration. */
1454 do_break = false;
1456 err_break:
1457 TALLOC_FREE(fullname);
1458 TALLOC_FREE(smb_dname_full);
1459 TALLOC_FREE(talloced);
1460 TALLOC_FREE(direntry_fname);
1461 if (do_break) {
1462 break;
1466 /* If we get here, we know NT_STATUS_IS_OK(status) */
1467 SMB_ASSERT(NT_STATUS_IS_OK(status));
1469 /* Retry the rmdir */
1470 ret = SMB_VFS_UNLINKAT(conn,
1471 parent_fname->fsp,
1472 at_fname,
1473 AT_REMOVEDIR);
1474 if (ret != 0) {
1475 status = map_nt_error_from_unix(errno);
1478 err:
1480 TALLOC_FREE(dir_hnd);
1481 TALLOC_FREE(parent_fname);
1483 if (!NT_STATUS_IS_OK(status)) {
1484 DBG_NOTICE("couldn't remove directory %s : "
1485 "%s\n", smb_fname_str_dbg(smb_dname),
1486 nt_errstr(status));
1487 return status;
1490 return status;
1493 /****************************************************************************
1494 Close a directory opened by an NT SMB call.
1495 ****************************************************************************/
1497 static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
1498 enum file_close_type close_type)
1500 connection_struct *conn = fsp->conn;
1501 struct close_share_mode_lock_state lck_state = {};
1502 bool changed_user = false;
1503 NTSTATUS status = NT_STATUS_OK;
1504 NTSTATUS status1 = NT_STATUS_OK;
1505 NTSTATUS notify_status;
1506 NTSTATUS ulstatus;
1508 SMB_ASSERT(fsp->fsp_flags.is_fsa);
1510 if (conn_using_smb2(fsp->conn->sconn)) {
1511 notify_status = NT_STATUS_NOTIFY_CLEANUP;
1512 } else {
1513 notify_status = NT_STATUS_OK;
1516 assert_no_pending_aio(fsp, close_type);
1519 * NT can set delete_on_close of the last open
1520 * reference to a directory also.
1523 lck_state = (struct close_share_mode_lock_state) {
1524 .fsp = fsp,
1525 .object_type = "directory",
1526 .close_type = close_type,
1529 status = share_mode_entry_prepare_lock_del(&lck_state.prepare_state,
1530 fsp->file_id,
1531 close_share_mode_lock_prepare,
1532 &lck_state);
1533 if (!NT_STATUS_IS_OK(status)) {
1534 DBG_ERR("share_mode_entry_prepare_lock_del() failed for %s - %s\n",
1535 fsp_str_dbg(fsp), nt_errstr(status));
1536 return status;
1539 /* Remove the oplock before potentially deleting the file. */
1540 if (fsp->oplock_type != NO_OPLOCK) {
1541 release_file_oplock(fsp);
1545 * NT can set delete_on_close of the last open
1546 * reference to a file.
1549 if (!lck_state.delete_object) {
1550 status = NT_STATUS_OK;
1551 goto done;
1555 * Ok, we have to delete the directory
1557 lck_state.cleanup_fn = close_share_mode_lock_cleanup;
1559 if (lck_state.got_tokens &&
1560 !unix_token_equal(lck_state.del_token, get_current_utok(conn)))
1562 /* Become the user who requested the delete. */
1564 DBG_INFO("dir %s. Change user to uid %u\n",
1565 fsp_str_dbg(fsp),
1566 (unsigned int)lck_state.del_token->uid);
1568 if (!push_sec_ctx()) {
1569 smb_panic("close_directory: failed to push sec_ctx.\n");
1572 set_sec_ctx(lck_state.del_token->uid,
1573 lck_state.del_token->gid,
1574 lck_state.del_token->ngroups,
1575 lck_state.del_token->groups,
1576 lck_state.del_nt_token);
1578 changed_user = true;
1581 if ((fsp->conn->fs_capabilities & FILE_NAMED_STREAMS)
1582 && !is_ntfs_stream_smb_fname(fsp->fsp_name)) {
1584 status = delete_all_streams(fsp->conn, fsp->fsp_name);
1585 if (!NT_STATUS_IS_OK(status)) {
1586 DEBUG(5, ("delete_all_streams failed: %s\n",
1587 nt_errstr(status)));
1588 goto done;
1592 status = rmdir_internals(talloc_tos(), fsp);
1594 DEBUG(5,("close_directory: %s. Delete on close was set - "
1595 "deleting directory returned %s.\n",
1596 fsp_str_dbg(fsp), nt_errstr(status)));
1599 * Ensure we remove any change notify requests that would
1600 * now fail as the directory has been deleted.
1603 if (NT_STATUS_IS_OK(status)) {
1604 notify_status = NT_STATUS_DELETE_PENDING;
1607 done:
1608 if (changed_user) {
1609 /* unbecome user. */
1610 pop_sec_ctx();
1613 ulstatus = share_mode_entry_prepare_unlock(&lck_state.prepare_state,
1614 lck_state.cleanup_fn,
1615 &lck_state);
1616 if (!NT_STATUS_IS_OK(ulstatus)) {
1617 DBG_ERR("share_mode_entry_prepare_unlock() failed for %s - %s\n",
1618 fsp_str_dbg(fsp), nt_errstr(ulstatus));
1619 smb_panic("share_mode_entry_prepare_unlock() failed!");
1622 remove_pending_change_notify_requests_by_fid(fsp, notify_status);
1624 if (lck_state.delete_object && NT_STATUS_IS_OK(status)) {
1625 const struct smb2_lease *lease = fsp_get_smb2_lease(fsp);
1627 if (lease != NULL) {
1629 * If parent lease key of handle on which delete
1630 * disposition was set does not match the parent lease
1631 * key of last closed handle, break all leases on the
1632 * parent directory.
1634 if (!smb2_lease_key_equal(&lease->parent_lease_key,
1635 &lck_state.parent_lease_key))
1637 lease = NULL;
1640 notify_fname(conn,
1641 NOTIFY_ACTION_REMOVED |
1642 NOTIFY_ACTION_DIRLEASE_BREAK,
1643 FILE_NOTIFY_CHANGE_DIR_NAME,
1644 fsp->fsp_name,
1645 lease);
1648 status1 = fd_close(fsp);
1650 if (!NT_STATUS_IS_OK(status1)) {
1651 DEBUG(0, ("Could not close dir! fname=%s, fd=%d, err=%d=%s\n",
1652 fsp_str_dbg(fsp), fsp_get_pathref_fd(fsp), errno,
1653 strerror(errno)));
1656 if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(status1)) {
1657 status = status1;
1659 return status;
1662 /****************************************************************************
1663 Rundown all SMB-related dependencies of a files struct
1664 ****************************************************************************/
1666 NTSTATUS close_file_smb(struct smb_request *req,
1667 struct files_struct *fsp,
1668 enum file_close_type close_type)
1670 NTSTATUS status;
1673 * This fsp can never be an internal dirfsp. They must
1674 * be explicitly closed by TALLOC_FREE of the dir handle.
1676 SMB_ASSERT(!fsp->fsp_flags.is_dirfsp);
1679 * Never call directly on a base fsp
1681 SMB_ASSERT(fsp->stream_fsp == NULL);
1683 if (fsp->fake_file_handle != NULL) {
1685 * Named pipes are opened as fake files and
1686 * can have pending aio requests. Ensure
1687 * we clear out all pending aio on force
1688 * shutdown of named pipes also.
1689 * BUG: https://bugzilla.samba.org/show_bug.cgi?id=15423
1691 assert_no_pending_aio(fsp, close_type);
1692 status = close_fake_file(req, fsp);
1693 } else if (fsp->print_file != NULL) {
1694 /* FIXME: return spool errors */
1695 print_spool_end(fsp, close_type);
1696 fd_close(fsp);
1697 status = NT_STATUS_OK;
1698 } else if (!fsp->fsp_flags.is_fsa) {
1699 if (close_type == NORMAL_CLOSE) {
1700 DBG_ERR("unexpected NORMAL_CLOSE for [%s] "
1701 "is_fsa[%u] is_pathref[%u] is_directory[%u]\n",
1702 fsp_str_dbg(fsp),
1703 fsp->fsp_flags.is_fsa,
1704 fsp->fsp_flags.is_pathref,
1705 fsp->fsp_flags.is_directory);
1707 SMB_ASSERT(close_type != NORMAL_CLOSE);
1708 fd_close(fsp);
1709 status = NT_STATUS_OK;
1710 } else if (fsp->fsp_flags.is_directory) {
1711 status = close_directory(req, fsp, close_type);
1712 } else {
1713 status = close_normal_file(req, fsp, close_type);
1716 if (fsp_is_alternate_stream(fsp)) {
1718 * fsp was a stream, its base_fsp can't be a stream
1719 * as well
1721 SMB_ASSERT(!fsp_is_alternate_stream(fsp->base_fsp));
1724 * There's a 1:1 relationship between fsp and a base_fsp
1726 SMB_ASSERT(fsp->base_fsp->stream_fsp == fsp);
1729 * Make base_fsp look standalone now
1731 fsp->base_fsp->stream_fsp = NULL;
1733 close_file_free(req, &fsp->base_fsp, close_type);
1736 fsp_unbind_smb(req, fsp);
1738 return status;
1741 NTSTATUS close_file_free(struct smb_request *req,
1742 struct files_struct **_fsp,
1743 enum file_close_type close_type)
1745 struct files_struct *fsp = *_fsp;
1746 NTSTATUS status;
1748 status = close_file_smb(req, fsp, close_type);
1750 file_free(req, fsp);
1751 *_fsp = NULL;
1753 return status;
1756 /****************************************************************************
1757 Deal with an (authorized) message to close a file given the share mode
1758 entry.
1759 ****************************************************************************/
1761 void msg_close_file(struct messaging_context *msg_ctx,
1762 void *private_data,
1763 uint32_t msg_type,
1764 struct server_id server_id,
1765 DATA_BLOB *data)
1767 struct oplock_break_message msg;
1768 enum ndr_err_code ndr_err;
1769 files_struct *fsp = NULL;
1770 struct smbd_server_connection *sconn =
1771 talloc_get_type_abort(private_data,
1772 struct smbd_server_connection);
1774 ndr_err = ndr_pull_struct_blob_all_noalloc(
1775 data,
1776 &msg,
1777 (ndr_pull_flags_fn_t)ndr_pull_oplock_break_message);
1778 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1779 DBG_DEBUG("ndr_pull_oplock_break_message failed: %s\n",
1780 ndr_errstr(ndr_err));
1781 return;
1784 fsp = file_find_dif(sconn, msg.id, msg.share_file_id);
1785 if (!fsp) {
1786 DEBUG(10,("msg_close_file: failed to find file.\n"));
1787 return;
1789 close_file_free(NULL, &fsp, NORMAL_CLOSE);