VFS: Rename kernel_flock to filesystem_sharemode
[Samba.git] / source3 / smbd / close.c
blob87c6a44d295478dc152231936b11cd47c1dc7316
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/scavenger.h"
30 #include "fake_file.h"
31 #include "transfer_file.h"
32 #include "auth.h"
33 #include "messages.h"
34 #include "../librpc/gen_ndr/open_files.h"
35 #include "lib/util/tevent_ntstatus.h"
37 /****************************************************************************
38 Run a file if it is a magic script.
39 ****************************************************************************/
41 static NTSTATUS check_magic(struct files_struct *fsp)
43 int ret;
44 const struct loadparm_substitution *lp_sub =
45 loadparm_s3_global_substitution();
46 const char *magic_output = NULL;
47 SMB_STRUCT_STAT st;
48 int tmp_fd, outfd;
49 TALLOC_CTX *ctx = NULL;
50 const char *p;
51 struct connection_struct *conn = fsp->conn;
52 char *fname = NULL;
53 NTSTATUS status;
55 if (!*lp_magic_script(talloc_tos(), lp_sub, SNUM(conn))) {
56 return NT_STATUS_OK;
59 DEBUG(5,("checking magic for %s\n", fsp_str_dbg(fsp)));
61 ctx = talloc_stackframe();
63 fname = fsp->fsp_name->base_name;
65 if (!(p = strrchr_m(fname,'/'))) {
66 p = fname;
67 } else {
68 p++;
71 if (!strequal(lp_magic_script(talloc_tos(), lp_sub, SNUM(conn)),p)) {
72 status = NT_STATUS_OK;
73 goto out;
76 if (*lp_magic_output(talloc_tos(), lp_sub, SNUM(conn))) {
77 magic_output = lp_magic_output(talloc_tos(), lp_sub, SNUM(conn));
78 } else {
79 magic_output = talloc_asprintf(ctx,
80 "%s.out",
81 fname);
83 if (!magic_output) {
84 status = NT_STATUS_NO_MEMORY;
85 goto out;
88 /* Ensure we don't depend on user's PATH. */
89 p = talloc_asprintf(ctx, "./%s", fname);
90 if (!p) {
91 status = NT_STATUS_NO_MEMORY;
92 goto out;
95 if (chmod(fname, 0755) == -1) {
96 status = map_nt_error_from_unix(errno);
97 goto out;
99 ret = smbrun(p, &tmp_fd, NULL);
100 DEBUG(3,("Invoking magic command %s gave %d\n",
101 p,ret));
103 unlink(fname);
104 if (ret != 0 || tmp_fd == -1) {
105 if (tmp_fd != -1) {
106 close(tmp_fd);
108 status = NT_STATUS_UNSUCCESSFUL;
109 goto out;
111 outfd = open(magic_output, O_CREAT|O_EXCL|O_RDWR, 0600);
112 if (outfd == -1) {
113 int err = errno;
114 close(tmp_fd);
115 status = map_nt_error_from_unix(err);
116 goto out;
119 if (sys_fstat(tmp_fd, &st, false) == -1) {
120 int err = errno;
121 close(tmp_fd);
122 close(outfd);
123 status = map_nt_error_from_unix(err);
124 goto out;
127 if (transfer_file(tmp_fd,outfd,(off_t)st.st_ex_size) == (off_t)-1) {
128 int err = errno;
129 close(tmp_fd);
130 close(outfd);
131 status = map_nt_error_from_unix(err);
132 goto out;
134 close(tmp_fd);
135 if (close(outfd) == -1) {
136 status = map_nt_error_from_unix(errno);
137 goto out;
140 status = NT_STATUS_OK;
142 out:
143 TALLOC_FREE(ctx);
144 return status;
147 /****************************************************************************
148 Delete all streams
149 ****************************************************************************/
151 NTSTATUS delete_all_streams(connection_struct *conn,
152 const struct smb_filename *smb_fname)
154 struct stream_struct *stream_info = NULL;
155 unsigned int i;
156 unsigned int num_streams = 0;
157 TALLOC_CTX *frame = talloc_stackframe();
158 NTSTATUS status;
160 status = vfs_fstreaminfo(smb_fname->fsp, talloc_tos(),
161 &num_streams, &stream_info);
163 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
164 DEBUG(10, ("no streams around\n"));
165 TALLOC_FREE(frame);
166 return NT_STATUS_OK;
169 if (!NT_STATUS_IS_OK(status)) {
170 DEBUG(10, ("vfs_fstreaminfo failed: %s\n",
171 nt_errstr(status)));
172 goto fail;
175 DEBUG(10, ("delete_all_streams found %d streams\n",
176 num_streams));
178 if (num_streams == 0) {
179 TALLOC_FREE(frame);
180 return NT_STATUS_OK;
183 for (i=0; i<num_streams; i++) {
184 int res;
185 struct smb_filename *smb_fname_stream;
187 if (strequal(stream_info[i].name, "::$DATA")) {
188 continue;
191 status = synthetic_pathref(talloc_tos(),
192 conn->cwd_fsp,
193 smb_fname->base_name,
194 stream_info[i].name,
195 NULL,
196 smb_fname->twrp,
197 (smb_fname->flags &
198 ~SMB_FILENAME_POSIX_PATH),
199 &smb_fname_stream);
200 if (!NT_STATUS_IS_OK(status)) {
201 DEBUG(0, ("talloc_aprintf failed\n"));
202 status = NT_STATUS_NO_MEMORY;
203 goto fail;
206 res = SMB_VFS_UNLINKAT(conn,
207 conn->cwd_fsp,
208 smb_fname_stream,
211 if (res == -1) {
212 status = map_nt_error_from_unix(errno);
213 DEBUG(10, ("Could not delete stream %s: %s\n",
214 smb_fname_str_dbg(smb_fname_stream),
215 strerror(errno)));
216 TALLOC_FREE(smb_fname_stream);
217 break;
219 TALLOC_FREE(smb_fname_stream);
222 fail:
223 TALLOC_FREE(frame);
224 return status;
227 struct has_other_nonposix_opens_state {
228 files_struct *fsp;
229 bool found_another;
232 static bool has_other_nonposix_opens_fn(
233 struct share_mode_entry *e,
234 bool *modified,
235 void *private_data)
237 struct has_other_nonposix_opens_state *state = private_data;
238 struct files_struct *fsp = state->fsp;
240 if (e->name_hash != fsp->name_hash) {
241 return false;
243 if ((fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) &&
244 (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) {
245 return false;
247 if (e->share_file_id == fh_get_gen_id(fsp->fh)) {
248 struct server_id self = messaging_server_id(
249 fsp->conn->sconn->msg_ctx);
250 if (server_id_equal(&self, &e->pid)) {
251 return false;
254 if (share_entry_stale_pid(e)) {
255 return false;
258 state->found_another = true;
259 return true;
262 bool has_other_nonposix_opens(struct share_mode_lock *lck,
263 struct files_struct *fsp)
265 struct has_other_nonposix_opens_state state = { .fsp = fsp };
266 bool ok;
268 ok = share_mode_forall_entries(
269 lck, has_other_nonposix_opens_fn, &state);
270 if (!ok) {
271 return false;
273 return state.found_another;
276 /****************************************************************************
277 Deal with removing a share mode on last close.
278 ****************************************************************************/
280 static NTSTATUS close_remove_share_mode(files_struct *fsp,
281 enum file_close_type close_type)
283 connection_struct *conn = fsp->conn;
284 bool delete_file = false;
285 bool changed_user = false;
286 struct share_mode_lock *lck = NULL;
287 NTSTATUS status = NT_STATUS_OK;
288 NTSTATUS tmp_status;
289 struct file_id id;
290 const struct security_unix_token *del_token = NULL;
291 const struct security_token *del_nt_token = NULL;
292 struct smb_filename *parent_fname = NULL;
293 struct smb_filename *base_fname = NULL;
294 bool got_tokens = false;
295 bool normal_close;
296 int ret;
298 /* Ensure any pending write time updates are done. */
299 if (fsp->update_write_time_event) {
300 fsp_flush_write_time_update(fsp);
304 * Lock the share entries, and determine if we should delete
305 * on close. If so delete whilst the lock is still in effect.
306 * This prevents race conditions with the file being created. JRA.
309 lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
310 if (lck == NULL) {
311 DEBUG(0, ("close_remove_share_mode: Could not get share mode "
312 "lock for file %s\n", fsp_str_dbg(fsp)));
313 return NT_STATUS_INVALID_PARAMETER;
316 /* Remove the oplock before potentially deleting the file. */
317 if(fsp->oplock_type) {
318 remove_oplock(fsp);
321 if (fsp->fsp_flags.write_time_forced) {
322 NTTIME mtime = share_mode_changed_write_time(lck);
323 struct timespec ts = nt_time_to_full_timespec(mtime);
325 DEBUG(10,("close_remove_share_mode: write time forced "
326 "for file %s\n",
327 fsp_str_dbg(fsp)));
328 set_close_write_time(fsp, ts);
329 } else if (fsp->fsp_flags.update_write_time_on_close) {
330 /* Someone had a pending write. */
331 if (is_omit_timespec(&fsp->close_write_time)) {
332 DEBUG(10,("close_remove_share_mode: update to current time "
333 "for file %s\n",
334 fsp_str_dbg(fsp)));
335 /* Update to current time due to "normal" write. */
336 set_close_write_time(fsp, timespec_current());
337 } else {
338 DEBUG(10,("close_remove_share_mode: write time pending "
339 "for file %s\n",
340 fsp_str_dbg(fsp)));
341 /* Update to time set on close call. */
342 set_close_write_time(fsp, fsp->close_write_time);
346 if (fsp->fsp_flags.initial_delete_on_close &&
347 !is_delete_on_close_set(lck, fsp->name_hash)) {
348 /* Initial delete on close was set and no one else
349 * wrote a real delete on close. */
351 fsp->fsp_flags.delete_on_close = true;
352 set_delete_on_close_lck(fsp, lck,
353 fsp->conn->session_info->security_token,
354 fsp->conn->session_info->unix_token);
357 delete_file = is_delete_on_close_set(lck, fsp->name_hash) &&
358 !has_other_nonposix_opens(lck, fsp);
361 * NT can set delete_on_close of the last open
362 * reference to a file.
365 normal_close = (close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE);
367 if (!normal_close || !delete_file) {
368 status = NT_STATUS_OK;
369 goto done;
373 * Ok, we have to delete the file
376 DEBUG(5,("close_remove_share_mode: file %s. Delete on close was set "
377 "- deleting file.\n", fsp_str_dbg(fsp)));
380 * Don't try to update the write time when we delete the file
382 fsp->fsp_flags.update_write_time_on_close = false;
384 got_tokens = get_delete_on_close_token(lck, fsp->name_hash,
385 &del_nt_token, &del_token);
386 SMB_ASSERT(got_tokens);
388 if (!unix_token_equal(del_token, get_current_utok(conn))) {
389 /* Become the user who requested the delete. */
391 DEBUG(5,("close_remove_share_mode: file %s. "
392 "Change user to uid %u\n",
393 fsp_str_dbg(fsp),
394 (unsigned int)del_token->uid));
396 if (!push_sec_ctx()) {
397 smb_panic("close_remove_share_mode: file %s. failed to push "
398 "sec_ctx.\n");
401 set_sec_ctx(del_token->uid,
402 del_token->gid,
403 del_token->ngroups,
404 del_token->groups,
405 del_nt_token);
407 changed_user = true;
410 /* We can only delete the file if the name we have is still valid and
411 hasn't been renamed. */
413 tmp_status = vfs_stat_fsp(fsp);
414 if (!NT_STATUS_IS_OK(tmp_status)) {
415 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
416 "was set and stat failed with error %s\n",
417 fsp_str_dbg(fsp), nt_errstr(tmp_status)));
419 * Don't save the errno here, we ignore this error
421 goto done;
424 id = vfs_file_id_from_sbuf(conn, &fsp->fsp_name->st);
426 if (!file_id_equal(&fsp->file_id, &id)) {
427 struct file_id_buf ftmp1, ftmp2;
428 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
429 "was set and dev and/or inode does not match\n",
430 fsp_str_dbg(fsp)));
431 DEBUG(5,("close_remove_share_mode: file %s. stored file_id %s, "
432 "stat file_id %s\n",
433 fsp_str_dbg(fsp),
434 file_id_str_buf(fsp->file_id, &ftmp1),
435 file_id_str_buf(id, &ftmp2)));
437 * Don't save the errno here, we ignore this error
439 goto done;
442 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
443 && !is_ntfs_stream_smb_fname(fsp->fsp_name)) {
445 status = delete_all_streams(conn, fsp->fsp_name);
447 if (!NT_STATUS_IS_OK(status)) {
448 DEBUG(5, ("delete_all_streams failed: %s\n",
449 nt_errstr(status)));
450 goto done;
454 if (fsp->fsp_flags.kernel_share_modes_taken) {
455 int ret_flock;
458 * A file system sharemode could block the unlink;
459 * remove filesystem sharemodes first.
461 ret_flock = SMB_VFS_FILESYSTEM_SHAREMODE(fsp, 0, 0);
462 if (ret_flock == -1) {
463 DBG_INFO("removing kernel flock for %s failed: %s\n",
464 fsp_str_dbg(fsp), strerror(errno));
467 fsp->fsp_flags.kernel_share_modes_taken = false;
470 status = parent_pathref(talloc_tos(),
471 conn->cwd_fsp,
472 fsp->fsp_name,
473 &parent_fname,
474 &base_fname);
475 if (!NT_STATUS_IS_OK(status)) {
476 goto done;
479 ret = SMB_VFS_UNLINKAT(conn,
480 parent_fname->fsp,
481 base_fname,
483 TALLOC_FREE(parent_fname);
484 base_fname = NULL;
485 if (ret != 0) {
487 * This call can potentially fail as another smbd may
488 * have had the file open with delete on close set and
489 * deleted it when its last reference to this file
490 * went away. Hence we log this but not at debug level
491 * zero.
494 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
495 "was set and unlink failed with error %s\n",
496 fsp_str_dbg(fsp), strerror(errno)));
498 status = map_nt_error_from_unix(errno);
501 /* As we now have POSIX opens which can unlink
502 * with other open files we may have taken
503 * this code path with more than one share mode
504 * entry - ensure we only delete once by resetting
505 * the delete on close flag. JRA.
508 fsp->fsp_flags.delete_on_close = false;
509 reset_delete_on_close_lck(fsp, lck);
511 done:
513 if (changed_user) {
514 /* unbecome user. */
515 pop_sec_ctx();
518 if (fsp->fsp_flags.kernel_share_modes_taken) {
519 int ret_flock;
521 /* remove filesystem sharemodes */
522 ret_flock = SMB_VFS_FILESYSTEM_SHAREMODE(fsp, 0, 0);
523 if (ret_flock == -1) {
524 DEBUG(2, ("close_remove_share_mode: removing kernel "
525 "flock for %s failed: %s\n",
526 fsp_str_dbg(fsp), strerror(errno)));
530 if (!del_share_mode(lck, fsp)) {
531 DEBUG(0, ("close_remove_share_mode: Could not delete share "
532 "entry for file %s\n", fsp_str_dbg(fsp)));
535 TALLOC_FREE(lck);
537 if (delete_file) {
539 * Do the notification after we released the share
540 * mode lock. Inside notify_fname we take out another
541 * tdb lock. With ctdb also accessing our databases,
542 * this can lead to deadlocks. Putting this notify
543 * after the TALLOC_FREE(lck) above we avoid locking
544 * two records simultaneously. Notifies are async and
545 * informational only, so calling the notify_fname
546 * without holding the share mode lock should not do
547 * any harm.
549 notify_fname(conn, NOTIFY_ACTION_REMOVED,
550 FILE_NOTIFY_CHANGE_FILE_NAME,
551 fsp->fsp_name->base_name);
554 return status;
557 void set_close_write_time(struct files_struct *fsp, struct timespec ts)
559 DEBUG(6,("close_write_time: %s" , time_to_asc(convert_timespec_to_time_t(ts))));
561 if (is_omit_timespec(&ts)) {
562 return;
564 fsp->fsp_flags.write_time_forced = false;
565 fsp->fsp_flags.update_write_time_on_close = true;
566 fsp->close_write_time = ts;
569 static NTSTATUS update_write_time_on_close(struct files_struct *fsp)
571 struct smb_file_time ft;
572 NTSTATUS status;
573 struct share_mode_lock *lck = NULL;
575 init_smb_file_time(&ft);
577 if (!(fsp->fsp_flags.update_write_time_on_close)) {
578 return NT_STATUS_OK;
581 if (is_omit_timespec(&fsp->close_write_time)) {
582 fsp->close_write_time = timespec_current();
585 /* Ensure we have a valid stat struct for the source. */
586 status = vfs_stat_fsp(fsp);
587 if (!NT_STATUS_IS_OK(status)) {
588 return status;
591 if (!VALID_STAT(fsp->fsp_name->st)) {
592 /* if it doesn't seem to be a real file */
593 return NT_STATUS_OK;
597 * get_existing_share_mode_lock() isn't really the right
598 * call here, as we're being called after
599 * close_remove_share_mode() inside close_normal_file()
600 * so it's quite normal to not have an existing share
601 * mode here. However, get_share_mode_lock() doesn't
602 * work because that will create a new share mode if
603 * one doesn't exist - so stick with this call (just
604 * ignore any error we get if the share mode doesn't
605 * exist.
608 lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
609 if (lck) {
610 NTTIME share_mtime = share_mode_changed_write_time(lck);
611 /* On close if we're changing the real file time we
612 * must update it in the open file db too. */
613 (void)set_write_time(fsp->file_id, fsp->close_write_time);
615 /* Close write times overwrite sticky write times
616 so we must replace any sticky write time here. */
617 if (!null_nttime(share_mtime)) {
618 (void)set_sticky_write_time(fsp->file_id, fsp->close_write_time);
620 TALLOC_FREE(lck);
623 ft.mtime = fsp->close_write_time;
624 /* As this is a close based update, we are not directly changing the
625 file attributes from a client call, but indirectly from a write. */
626 status = smb_set_file_time(fsp->conn, fsp, fsp->fsp_name, &ft, false);
627 if (!NT_STATUS_IS_OK(status)) {
628 DEBUG(10,("update_write_time_on_close: smb_set_file_time "
629 "on file %s returned %s\n",
630 fsp_str_dbg(fsp),
631 nt_errstr(status)));
632 return status;
635 return status;
638 static NTSTATUS ntstatus_keeperror(NTSTATUS s1, NTSTATUS s2)
640 if (!NT_STATUS_IS_OK(s1)) {
641 return s1;
643 return s2;
646 static void assert_no_pending_aio(struct files_struct *fsp,
647 enum file_close_type close_type)
649 struct smbXsrv_client *client = global_smbXsrv_client;
650 size_t num_connections_alive;
651 unsigned num_requests = fsp->num_aio_requests;
653 if (num_requests == 0) {
654 return;
657 num_connections_alive = smbXsrv_client_valid_connections(client);
659 if (close_type == SHUTDOWN_CLOSE && num_connections_alive == 0) {
661 * fsp->aio_requests and the contents (fsp->aio_requests[x])
662 * are both independently owned by fsp and are not in a
663 * talloc heirarchy. This allows the fsp->aio_requests array to
664 * be reallocated independently of the array contents so it can
665 * grow on demand.
667 * This means we must ensure order of deallocation
668 * on a SHUTDOWN_CLOSE by deallocating the fsp->aio_requests[x]
669 * contents first, as their destructors access the
670 * fsp->aio_request array. If we don't deallocate them
671 * first, when fsp is deallocated fsp->aio_requests
672 * could have been deallocated *before* its contents
673 * fsp->aio_requests[x], causing a crash.
675 while (fsp->num_aio_requests != 0) {
677 * NB. We *MUST* use
678 * talloc_free(fsp->aio_requests[0]),
679 * and *NOT* TALLOC_FREE() here, as
680 * TALLOC_FREE(fsp->aio_requests[0])
681 * will overwrite any new contents of
682 * fsp->aio_requests[0] that were
683 * copied into it via the destructor
684 * aio_del_req_from_fsp().
686 * BUG: https://bugzilla.samba.org/show_bug.cgi?id=14515
688 talloc_free(fsp->aio_requests[0]);
690 return;
693 DBG_ERR("fsp->num_aio_requests=%u\n", num_requests);
694 smb_panic("can not close with outstanding aio requests");
695 return;
698 /****************************************************************************
699 Close a file.
701 close_type can be NORMAL_CLOSE=0,SHUTDOWN_CLOSE,ERROR_CLOSE.
702 printing and magic scripts are only run on normal close.
703 delete on close is done on normal and shutdown close.
704 ****************************************************************************/
706 static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp,
707 enum file_close_type close_type)
709 NTSTATUS status = NT_STATUS_OK;
710 NTSTATUS tmp;
711 connection_struct *conn = fsp->conn;
712 bool is_durable = false;
714 SMB_ASSERT(fsp->fsp_flags.is_fsa);
716 assert_no_pending_aio(fsp, close_type);
718 while (talloc_array_length(fsp->blocked_smb1_lock_reqs) != 0) {
719 smbd_smb1_brl_finish_by_req(
720 fsp->blocked_smb1_lock_reqs[0],
721 NT_STATUS_RANGE_NOT_LOCKED);
725 * If we're flushing on a close we can get a write
726 * error here, we must remember this.
729 if (NT_STATUS_IS_OK(status) && fsp->op != NULL) {
730 is_durable = fsp->op->global->durable;
733 if (close_type != SHUTDOWN_CLOSE) {
734 is_durable = false;
737 if (is_durable) {
738 DATA_BLOB new_cookie = data_blob_null;
740 tmp = SMB_VFS_DURABLE_DISCONNECT(fsp,
741 fsp->op->global->backend_cookie,
742 fsp->op,
743 &new_cookie);
744 if (NT_STATUS_IS_OK(tmp)) {
745 struct timeval tv;
746 NTTIME now;
748 if (req != NULL) {
749 tv = req->request_time;
750 } else {
751 tv = timeval_current();
753 now = timeval_to_nttime(&tv);
755 data_blob_free(&fsp->op->global->backend_cookie);
756 fsp->op->global->backend_cookie = new_cookie;
758 fsp->op->compat = NULL;
759 tmp = smbXsrv_open_close(fsp->op, now);
760 if (!NT_STATUS_IS_OK(tmp)) {
761 DEBUG(1, ("Failed to update smbXsrv_open "
762 "record when disconnecting durable "
763 "handle for file %s: %s - "
764 "proceeding with normal close\n",
765 fsp_str_dbg(fsp), nt_errstr(tmp)));
767 scavenger_schedule_disconnected(fsp);
768 } else {
769 DEBUG(1, ("Failed to disconnect durable handle for "
770 "file %s: %s - proceeding with normal "
771 "close\n", fsp_str_dbg(fsp), nt_errstr(tmp)));
773 if (!NT_STATUS_IS_OK(tmp)) {
774 is_durable = false;
778 if (is_durable) {
780 * This is the case where we successfully disconnected
781 * a durable handle and closed the underlying file.
782 * In all other cases, we proceed with a genuine close.
784 DEBUG(10, ("%s disconnected durable handle for file %s\n",
785 conn->session_info->unix_info->unix_name,
786 fsp_str_dbg(fsp)));
787 file_free(req, fsp);
788 return NT_STATUS_OK;
791 if (fsp->op != NULL) {
793 * Make sure the handle is not marked as durable anymore
795 fsp->op->global->durable = false;
798 /* If this is an old DOS or FCB open and we have multiple opens on
799 the same handle we only have one share mode. Ensure we only remove
800 the share mode on the last close. */
802 if (fh_get_refcount(fsp->fh) == 1) {
803 /* Should we return on error here... ? */
804 tmp = close_remove_share_mode(fsp, close_type);
805 status = ntstatus_keeperror(status, tmp);
808 locking_close_file(fsp, close_type);
811 * Ensure pending modtime is set before closing underlying fd.
814 tmp = update_write_time_on_close(fsp);
815 if (NT_STATUS_EQUAL(tmp, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
817 * Someone renamed the file or a parent directory containing
818 * this file. We can't do anything about this, eat the error.
820 tmp = NT_STATUS_OK;
822 status = ntstatus_keeperror(status, tmp);
824 tmp = fd_close(fsp);
825 status = ntstatus_keeperror(status, tmp);
827 /* check for magic scripts */
828 if (close_type == NORMAL_CLOSE) {
829 tmp = check_magic(fsp);
830 status = ntstatus_keeperror(status, tmp);
833 DEBUG(2,("%s closed file %s (numopen=%d) %s\n",
834 conn->session_info->unix_info->unix_name, fsp_str_dbg(fsp),
835 conn->num_files_open - 1,
836 nt_errstr(status) ));
838 file_free(req, fsp);
839 return status;
841 /****************************************************************************
842 Function used by reply_rmdir to delete an entire directory
843 tree recursively. Return True on ok, False on fail.
844 ****************************************************************************/
846 bool recursive_rmdir(TALLOC_CTX *ctx,
847 connection_struct *conn,
848 struct smb_filename *smb_dname)
850 const char *dname = NULL;
851 char *talloced = NULL;
852 bool ret = True;
853 long offset = 0;
854 SMB_STRUCT_STAT st;
855 struct smb_Dir *dir_hnd;
856 struct files_struct *dirfsp = NULL;
857 int retval;
858 NTSTATUS status;
860 SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
862 dir_hnd = OpenDir(talloc_tos(), conn, smb_dname, NULL, 0);
863 if (dir_hnd == NULL)
864 return False;
866 dirfsp = dir_hnd_fetch_fsp(dir_hnd);
868 while ((dname = ReadDirName(dir_hnd, &offset, &st, &talloced))) {
869 struct smb_filename *atname = NULL;
870 struct smb_filename *smb_dname_full = NULL;
871 char *fullname = NULL;
872 bool do_break = true;
873 int unlink_flags = 0;
875 if (ISDOT(dname) || ISDOTDOT(dname)) {
876 TALLOC_FREE(talloced);
877 continue;
880 /* Construct the full name. */
881 fullname = talloc_asprintf(ctx,
882 "%s/%s",
883 smb_dname->base_name,
884 dname);
885 if (!fullname) {
886 errno = ENOMEM;
887 goto err_break;
890 smb_dname_full = synthetic_smb_fname(talloc_tos(),
891 fullname,
892 NULL,
893 NULL,
894 smb_dname->twrp,
895 smb_dname->flags);
896 if (smb_dname_full == NULL) {
897 errno = ENOMEM;
898 goto err_break;
901 if (SMB_VFS_LSTAT(conn, smb_dname_full) != 0) {
902 goto err_break;
905 if (smb_dname_full->st.st_ex_mode & S_IFDIR) {
906 if (!recursive_rmdir(ctx, conn, smb_dname_full)) {
907 goto err_break;
909 unlink_flags = AT_REMOVEDIR;
912 status = synthetic_pathref(talloc_tos(),
913 dirfsp,
914 dname,
915 NULL,
916 &smb_dname_full->st,
917 smb_dname_full->twrp,
918 smb_dname_full->flags,
919 &atname);
920 if (!NT_STATUS_IS_OK(status)) {
921 errno = map_errno_from_nt_status(status);
922 goto err_break;
925 if (!is_visible_fsp(atname->fsp)) {
926 TALLOC_FREE(smb_dname_full);
927 TALLOC_FREE(fullname);
928 TALLOC_FREE(talloced);
929 TALLOC_FREE(atname);
930 continue;
933 retval = SMB_VFS_UNLINKAT(conn,
934 dirfsp,
935 atname,
936 unlink_flags);
937 if (retval != 0) {
938 goto err_break;
941 /* Successful iteration. */
942 do_break = false;
944 err_break:
945 TALLOC_FREE(smb_dname_full);
946 TALLOC_FREE(fullname);
947 TALLOC_FREE(talloced);
948 TALLOC_FREE(atname);
949 if (do_break) {
950 ret = false;
951 break;
954 TALLOC_FREE(dir_hnd);
955 return ret;
958 /****************************************************************************
959 The internals of the rmdir code - called elsewhere.
960 ****************************************************************************/
962 static NTSTATUS rmdir_internals(TALLOC_CTX *ctx, struct files_struct *fsp)
964 struct connection_struct *conn = fsp->conn;
965 struct smb_filename *smb_dname = fsp->fsp_name;
966 struct smb_filename *parent_fname = NULL;
967 struct smb_filename *at_fname = NULL;
968 const struct loadparm_substitution *lp_sub =
969 loadparm_s3_global_substitution();
970 SMB_STRUCT_STAT st;
971 const char *dname = NULL;
972 char *talloced = NULL;
973 long dirpos = 0;
974 struct smb_Dir *dir_hnd = NULL;
975 struct files_struct *dirfsp = NULL;
976 int unlink_flags = 0;
977 NTSTATUS status;
978 int ret;
980 SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
982 status = parent_pathref(talloc_tos(),
983 conn->cwd_fsp,
984 fsp->fsp_name,
985 &parent_fname,
986 &at_fname);
987 if (!NT_STATUS_IS_OK(status)) {
988 return status;
992 * Todo: use SMB_VFS_STATX() once it's available.
995 /* Might be a symlink. */
996 ret = SMB_VFS_LSTAT(conn, smb_dname);
997 if (ret != 0) {
998 TALLOC_FREE(parent_fname);
999 return map_nt_error_from_unix(errno);
1002 if (S_ISLNK(smb_dname->st.st_ex_mode)) {
1003 /* Is what it points to a directory ? */
1004 ret = SMB_VFS_STAT(conn, smb_dname);
1005 if (ret != 0) {
1006 TALLOC_FREE(parent_fname);
1007 return map_nt_error_from_unix(errno);
1009 if (!(S_ISDIR(smb_dname->st.st_ex_mode))) {
1010 TALLOC_FREE(parent_fname);
1011 return NT_STATUS_NOT_A_DIRECTORY;
1013 } else {
1014 unlink_flags = AT_REMOVEDIR;
1017 ret = SMB_VFS_UNLINKAT(conn,
1018 parent_fname->fsp,
1019 at_fname,
1020 unlink_flags);
1021 if (ret == 0) {
1022 TALLOC_FREE(parent_fname);
1023 notify_fname(conn, NOTIFY_ACTION_REMOVED,
1024 FILE_NOTIFY_CHANGE_DIR_NAME,
1025 smb_dname->base_name);
1026 return NT_STATUS_OK;
1029 if (!((errno == ENOTEMPTY) || (errno == EEXIST)) ||
1030 !*lp_veto_files(talloc_tos(), lp_sub, SNUM(conn)))
1032 DEBUG(3,("rmdir_internals: couldn't remove directory %s : "
1033 "%s\n", smb_fname_str_dbg(smb_dname),
1034 strerror(errno)));
1035 TALLOC_FREE(parent_fname);
1036 return map_nt_error_from_unix(errno);
1040 * Check to see if the only thing in this directory are
1041 * vetoed files/directories. If so then delete them and
1042 * retry. If we fail to delete any of them (and we *don't*
1043 * do a recursive delete) then fail the rmdir.
1046 dir_hnd = OpenDir(talloc_tos(), conn, smb_dname, NULL, 0);
1047 if (dir_hnd == NULL) {
1048 errno = ENOTEMPTY;
1049 goto err;
1052 while ((dname = ReadDirName(dir_hnd, &dirpos, &st, &talloced)) != NULL) {
1053 struct smb_filename *smb_dname_full = NULL;
1054 struct smb_filename *direntry_fname = NULL;
1055 char *fullname = NULL;
1057 if (ISDOT(dname) || ISDOTDOT(dname)) {
1058 TALLOC_FREE(talloced);
1059 continue;
1061 if (IS_VETO_PATH(conn, dname)) {
1062 TALLOC_FREE(talloced);
1063 continue;
1066 fullname = talloc_asprintf(talloc_tos(),
1067 "%s/%s",
1068 smb_dname->base_name,
1069 dname);
1071 if (fullname == NULL) {
1072 TALLOC_FREE(talloced);
1073 errno = ENOMEM;
1074 goto err;
1077 smb_dname_full = synthetic_smb_fname(talloc_tos(),
1078 fullname,
1079 NULL,
1080 NULL,
1081 smb_dname->twrp,
1082 smb_dname->flags);
1083 if (smb_dname_full == NULL) {
1084 TALLOC_FREE(talloced);
1085 TALLOC_FREE(fullname);
1086 errno = ENOMEM;
1087 goto err;
1090 ret = SMB_VFS_LSTAT(conn, smb_dname_full);
1091 if (ret != 0) {
1092 int saved_errno = errno;
1093 TALLOC_FREE(talloced);
1094 TALLOC_FREE(fullname);
1095 TALLOC_FREE(smb_dname_full);
1096 errno = saved_errno;
1097 goto err;
1101 * is_visible_fsp() always returns true
1102 * for the symlink/MSDFS case.
1104 if (S_ISLNK(smb_dname_full->st.st_ex_mode)) {
1105 TALLOC_FREE(talloced);
1106 TALLOC_FREE(fullname);
1107 TALLOC_FREE(smb_dname_full);
1108 continue;
1111 /* Not a symlink, get a pathref. */
1112 status = synthetic_pathref(talloc_tos(),
1113 dirfsp,
1114 dname,
1115 NULL,
1116 &smb_dname_full->st,
1117 smb_dname->twrp,
1118 smb_dname->flags,
1119 &direntry_fname);
1120 if (!NT_STATUS_IS_OK(status)) {
1121 TALLOC_FREE(talloced);
1122 TALLOC_FREE(fullname);
1123 TALLOC_FREE(smb_dname_full);
1124 errno = map_errno_from_nt_status(status);
1125 goto err;
1128 if (!is_visible_fsp(direntry_fname->fsp)) {
1129 TALLOC_FREE(talloced);
1130 TALLOC_FREE(fullname);
1131 TALLOC_FREE(smb_dname_full);
1132 TALLOC_FREE(direntry_fname);
1133 continue;
1136 TALLOC_FREE(talloced);
1137 TALLOC_FREE(fullname);
1138 TALLOC_FREE(smb_dname_full);
1139 TALLOC_FREE(direntry_fname);
1142 /* We only have veto files/directories.
1143 * Are we allowed to delete them ? */
1145 if (!lp_delete_veto_files(SNUM(conn))) {
1146 errno = ENOTEMPTY;
1147 goto err;
1150 /* Do a recursive delete. */
1151 RewindDir(dir_hnd,&dirpos);
1152 dirfsp = dir_hnd_fetch_fsp(dir_hnd);
1154 while ((dname = ReadDirName(dir_hnd, &dirpos, &st, &talloced)) != NULL) {
1155 struct smb_filename *direntry_fname = NULL;
1156 struct smb_filename *smb_dname_full = NULL;
1157 char *fullname = NULL;
1158 bool do_break = true;
1159 int retval;
1161 if (ISDOT(dname) || ISDOTDOT(dname)) {
1162 TALLOC_FREE(talloced);
1163 continue;
1166 fullname = talloc_asprintf(ctx,
1167 "%s/%s",
1168 smb_dname->base_name,
1169 dname);
1171 if (fullname == NULL) {
1172 errno = ENOMEM;
1173 goto err_break;
1176 smb_dname_full = synthetic_smb_fname(talloc_tos(),
1177 fullname,
1178 NULL,
1179 NULL,
1180 smb_dname->twrp,
1181 smb_dname->flags);
1182 if (smb_dname_full == NULL) {
1183 errno = ENOMEM;
1184 goto err_break;
1188 * Todo: use SMB_VFS_STATX() once that's available.
1191 ret = SMB_VFS_LSTAT(conn, smb_dname_full);
1192 if (ret != 0) {
1193 goto err_break;
1197 * We are only dealing with VETO'ed objects
1198 * here. If it's a symlink, just delete the
1199 * link without caring what it is pointing
1200 * to.
1202 if (S_ISLNK(smb_dname_full->st.st_ex_mode)) {
1203 direntry_fname = synthetic_smb_fname(talloc_tos(),
1204 dname,
1205 NULL,
1206 &smb_dname_full->st,
1207 smb_dname->twrp,
1208 smb_dname->flags);
1209 if (direntry_fname == NULL) {
1210 errno = ENOMEM;
1211 goto err_break;
1213 } else {
1214 status = synthetic_pathref(talloc_tos(),
1215 dirfsp,
1216 dname,
1217 NULL,
1218 &smb_dname_full->st,
1219 smb_dname->twrp,
1220 smb_dname->flags,
1221 &direntry_fname);
1222 if (!NT_STATUS_IS_OK(status)) {
1223 errno = map_errno_from_nt_status(status);
1224 goto err_break;
1227 if (!is_visible_fsp(direntry_fname->fsp)) {
1228 TALLOC_FREE(fullname);
1229 TALLOC_FREE(smb_dname_full);
1230 TALLOC_FREE(talloced);
1231 TALLOC_FREE(direntry_fname);
1232 continue;
1236 unlink_flags = 0;
1238 if (smb_dname_full->st.st_ex_mode & S_IFDIR) {
1239 if (!recursive_rmdir(ctx, conn,
1240 smb_dname_full))
1242 goto err_break;
1244 unlink_flags = AT_REMOVEDIR;
1247 retval = SMB_VFS_UNLINKAT(conn,
1248 dirfsp,
1249 direntry_fname,
1250 unlink_flags);
1251 if (retval != 0) {
1252 goto err_break;
1255 /* Successful iteration. */
1256 do_break = false;
1258 err_break:
1259 TALLOC_FREE(fullname);
1260 TALLOC_FREE(smb_dname_full);
1261 TALLOC_FREE(talloced);
1262 TALLOC_FREE(direntry_fname);
1263 if (do_break) {
1264 break;
1268 /* Retry the rmdir */
1269 ret = SMB_VFS_UNLINKAT(conn,
1270 dirfsp,
1271 at_fname,
1272 AT_REMOVEDIR);
1275 err:
1277 TALLOC_FREE(dir_hnd);
1278 TALLOC_FREE(parent_fname);
1280 if (ret != 0) {
1281 DEBUG(3,("rmdir_internals: couldn't remove directory %s : "
1282 "%s\n", smb_fname_str_dbg(smb_dname),
1283 strerror(errno)));
1284 return map_nt_error_from_unix(errno);
1287 notify_fname(conn, NOTIFY_ACTION_REMOVED,
1288 FILE_NOTIFY_CHANGE_DIR_NAME,
1289 smb_dname->base_name);
1291 return NT_STATUS_OK;
1294 /****************************************************************************
1295 Close a directory opened by an NT SMB call.
1296 ****************************************************************************/
1298 static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
1299 enum file_close_type close_type)
1301 struct share_mode_lock *lck = NULL;
1302 bool delete_dir = False;
1303 NTSTATUS status = NT_STATUS_OK;
1304 NTSTATUS status1 = NT_STATUS_OK;
1305 const struct security_token *del_nt_token = NULL;
1306 const struct security_unix_token *del_token = NULL;
1307 NTSTATUS notify_status;
1309 SMB_ASSERT(fsp->fsp_flags.is_fsa);
1311 if (fsp->conn->sconn->using_smb2) {
1312 notify_status = NT_STATUS_NOTIFY_CLEANUP;
1313 } else {
1314 notify_status = NT_STATUS_OK;
1317 assert_no_pending_aio(fsp, close_type);
1320 * NT can set delete_on_close of the last open
1321 * reference to a directory also.
1324 lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
1325 if (lck == NULL) {
1326 DEBUG(0, ("close_directory: Could not get share mode lock for "
1327 "%s\n", fsp_str_dbg(fsp)));
1328 file_free(req, fsp);
1329 return NT_STATUS_INVALID_PARAMETER;
1332 if (fsp->fsp_flags.initial_delete_on_close) {
1333 /* Initial delete on close was set - for
1334 * directories we don't care if anyone else
1335 * wrote a real delete on close. */
1337 send_stat_cache_delete_message(fsp->conn->sconn->msg_ctx,
1338 fsp->fsp_name->base_name);
1339 set_delete_on_close_lck(fsp, lck,
1340 fsp->conn->session_info->security_token,
1341 fsp->conn->session_info->unix_token);
1342 fsp->fsp_flags.delete_on_close = true;
1345 delete_dir = get_delete_on_close_token(
1346 lck, fsp->name_hash, &del_nt_token, &del_token) &&
1347 !has_other_nonposix_opens(lck, fsp);
1349 if ((close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) &&
1350 delete_dir) {
1352 /* Become the user who requested the delete. */
1354 if (!push_sec_ctx()) {
1355 smb_panic("close_directory: failed to push sec_ctx.\n");
1358 set_sec_ctx(del_token->uid,
1359 del_token->gid,
1360 del_token->ngroups,
1361 del_token->groups,
1362 del_nt_token);
1364 if (!del_share_mode(lck, fsp)) {
1365 DEBUG(0, ("close_directory: Could not delete share entry for "
1366 "%s\n", fsp_str_dbg(fsp)));
1369 TALLOC_FREE(lck);
1371 if ((fsp->conn->fs_capabilities & FILE_NAMED_STREAMS)
1372 && !is_ntfs_stream_smb_fname(fsp->fsp_name)) {
1374 status = delete_all_streams(fsp->conn, fsp->fsp_name);
1375 if (!NT_STATUS_IS_OK(status)) {
1376 DEBUG(5, ("delete_all_streams failed: %s\n",
1377 nt_errstr(status)));
1378 file_free(req, fsp);
1379 return status;
1383 status = rmdir_internals(talloc_tos(), fsp);
1385 DEBUG(5,("close_directory: %s. Delete on close was set - "
1386 "deleting directory returned %s.\n",
1387 fsp_str_dbg(fsp), nt_errstr(status)));
1389 /* unbecome user. */
1390 pop_sec_ctx();
1393 * Ensure we remove any change notify requests that would
1394 * now fail as the directory has been deleted.
1397 if (NT_STATUS_IS_OK(status)) {
1398 notify_status = NT_STATUS_DELETE_PENDING;
1400 } else {
1401 if (!del_share_mode(lck, fsp)) {
1402 DEBUG(0, ("close_directory: Could not delete share entry for "
1403 "%s\n", fsp_str_dbg(fsp)));
1406 TALLOC_FREE(lck);
1409 remove_pending_change_notify_requests_by_fid(fsp, notify_status);
1411 status1 = fd_close(fsp);
1413 if (!NT_STATUS_IS_OK(status1)) {
1414 DEBUG(0, ("Could not close dir! fname=%s, fd=%d, err=%d=%s\n",
1415 fsp_str_dbg(fsp), fsp_get_pathref_fd(fsp), errno,
1416 strerror(errno)));
1420 * Do the code common to files and directories.
1422 file_free(req, fsp);
1424 if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(status1)) {
1425 status = status1;
1427 return status;
1430 /****************************************************************************
1431 Close a files_struct.
1432 ****************************************************************************/
1434 NTSTATUS close_file(struct smb_request *req, files_struct *fsp,
1435 enum file_close_type close_type)
1437 NTSTATUS status;
1438 struct files_struct *base_fsp = fsp->base_fsp;
1439 bool close_base_fsp = false;
1442 * This fsp can never be an internal dirfsp. They must
1443 * be explicitly closed by TALLOC_FREE of the dir handle.
1445 SMB_ASSERT(!fsp->fsp_flags.is_dirfsp);
1447 if (fsp->stream_fsp != NULL) {
1449 * fsp is the base for a stream.
1451 * We're called with SHUTDOWN_CLOSE from files.c which walks the
1452 * complete list of files.
1454 * We need to wait until the stream is closed.
1456 SMB_ASSERT(close_type == SHUTDOWN_CLOSE);
1457 return NT_STATUS_OK;
1460 if (base_fsp != NULL) {
1462 * We need to remove the link in order to
1463 * recurse for the base fsp below.
1465 SMB_ASSERT(base_fsp->base_fsp == NULL);
1466 SMB_ASSERT(base_fsp->stream_fsp == fsp);
1467 base_fsp->stream_fsp = NULL;
1469 if (close_type == SHUTDOWN_CLOSE) {
1471 * We're called with SHUTDOWN_CLOSE from files.c
1472 * which walks the complete list of files.
1474 * We may need to defer the SHUTDOWN_CLOSE
1475 * if it's the next in the linked list.
1477 * So we only close if the base is *not* the
1478 * next in the list.
1480 close_base_fsp = (fsp->next != base_fsp);
1481 } else {
1482 close_base_fsp = true;
1486 if (fsp->fake_file_handle != NULL) {
1487 status = close_fake_file(req, fsp);
1488 } else if (fsp->print_file != NULL) {
1489 /* FIXME: return spool errors */
1490 print_spool_end(fsp, close_type);
1491 file_free(req, fsp);
1492 status = NT_STATUS_OK;
1493 } else if (!fsp->fsp_flags.is_fsa) {
1494 if (close_type == NORMAL_CLOSE) {
1495 DBG_ERR("unexpected NORMAL_CLOSE for [%s] "
1496 "is_fsa[%u] is_pathref[%u] is_directory[%u]\n",
1497 fsp_str_dbg(fsp),
1498 fsp->fsp_flags.is_fsa,
1499 fsp->fsp_flags.is_pathref,
1500 fsp->fsp_flags.is_directory);
1502 SMB_ASSERT(close_type != NORMAL_CLOSE);
1503 fd_close(fsp);
1504 file_free(req, fsp);
1505 status = NT_STATUS_OK;
1506 } else if (fsp->fsp_flags.is_directory) {
1507 status = close_directory(req, fsp, close_type);
1508 } else {
1509 status = close_normal_file(req, fsp, close_type);
1512 if (close_base_fsp) {
1515 * fsp was a stream, the base fsp can't be a stream as well
1517 * For SHUTDOWN_CLOSE this is not possible here
1518 * (if the base_fsp was the next in the linked list), because
1519 * SHUTDOWN_CLOSE only happens from files.c which walks the
1520 * complete list of files. If we mess with more than one fsp
1521 * those loops will become confused.
1524 close_file(req, base_fsp, close_type);
1527 return status;
1530 /****************************************************************************
1531 Deal with an (authorized) message to close a file given the share mode
1532 entry.
1533 ****************************************************************************/
1535 void msg_close_file(struct messaging_context *msg_ctx,
1536 void *private_data,
1537 uint32_t msg_type,
1538 struct server_id server_id,
1539 DATA_BLOB *data)
1541 files_struct *fsp = NULL;
1542 struct file_id id;
1543 struct share_mode_entry e;
1544 struct smbd_server_connection *sconn =
1545 talloc_get_type_abort(private_data,
1546 struct smbd_server_connection);
1548 message_to_share_mode_entry(&id, &e, (char *)data->data);
1550 if(DEBUGLVL(10)) {
1551 char *sm_str = share_mode_str(NULL, 0, &id, &e);
1552 if (!sm_str) {
1553 smb_panic("talloc failed");
1555 DEBUG(10,("msg_close_file: got request to close share mode "
1556 "entry %s\n", sm_str));
1557 TALLOC_FREE(sm_str);
1560 fsp = file_find_dif(sconn, id, e.share_file_id);
1561 if (!fsp) {
1562 DEBUG(10,("msg_close_file: failed to find file.\n"));
1563 return;
1565 close_file(NULL, fsp, NORMAL_CLOSE);