librpc: Shorten dcerpc_binding_handle_call a bit
[Samba/bjacke.git] / source3 / smbd / close.c
blob64faf989ffdb71de0c910878576f767c1d3922e4
1 /*
2 Unix SMB/CIFS implementation.
3 file closing
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Jeremy Allison 1992-2007.
6 Copyright (C) Volker Lendecke 2005
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "includes.h"
23 #include "system/filesys.h"
24 #include "printing.h"
25 #include "smbd/smbd.h"
26 #include "smbd/globals.h"
27 #include "smbd/scavenger.h"
28 #include "fake_file.h"
29 #include "transfer_file.h"
30 #include "auth.h"
31 #include "messages.h"
32 #include "../librpc/gen_ndr/open_files.h"
34 /****************************************************************************
35 Run a file if it is a magic script.
36 ****************************************************************************/
38 static NTSTATUS check_magic(struct files_struct *fsp)
40 int ret;
41 const char *magic_output = NULL;
42 SMB_STRUCT_STAT st;
43 int tmp_fd, outfd;
44 TALLOC_CTX *ctx = NULL;
45 const char *p;
46 struct connection_struct *conn = fsp->conn;
47 char *fname = NULL;
48 NTSTATUS status;
50 if (!*lp_magicscript(talloc_tos(), SNUM(conn))) {
51 return NT_STATUS_OK;
54 DEBUG(5,("checking magic for %s\n", fsp_str_dbg(fsp)));
56 ctx = talloc_stackframe();
58 fname = fsp->fsp_name->base_name;
60 if (!(p = strrchr_m(fname,'/'))) {
61 p = fname;
62 } else {
63 p++;
66 if (!strequal(lp_magicscript(talloc_tos(), SNUM(conn)),p)) {
67 status = NT_STATUS_OK;
68 goto out;
71 if (*lp_magicoutput(talloc_tos(), SNUM(conn))) {
72 magic_output = lp_magicoutput(talloc_tos(), SNUM(conn));
73 } else {
74 magic_output = talloc_asprintf(ctx,
75 "%s.out",
76 fname);
78 if (!magic_output) {
79 status = NT_STATUS_NO_MEMORY;
80 goto out;
83 /* Ensure we don't depend on user's PATH. */
84 p = talloc_asprintf(ctx, "./%s", fname);
85 if (!p) {
86 status = NT_STATUS_NO_MEMORY;
87 goto out;
90 if (chmod(fname, 0755) == -1) {
91 status = map_nt_error_from_unix(errno);
92 goto out;
94 ret = smbrun(p,&tmp_fd);
95 DEBUG(3,("Invoking magic command %s gave %d\n",
96 p,ret));
98 unlink(fname);
99 if (ret != 0 || tmp_fd == -1) {
100 if (tmp_fd != -1) {
101 close(tmp_fd);
103 status = NT_STATUS_UNSUCCESSFUL;
104 goto out;
106 outfd = open(magic_output, O_CREAT|O_EXCL|O_RDWR, 0600);
107 if (outfd == -1) {
108 int err = errno;
109 close(tmp_fd);
110 status = map_nt_error_from_unix(err);
111 goto out;
114 if (sys_fstat(tmp_fd, &st, false) == -1) {
115 int err = errno;
116 close(tmp_fd);
117 close(outfd);
118 status = map_nt_error_from_unix(err);
119 goto out;
122 if (transfer_file(tmp_fd,outfd,(off_t)st.st_ex_size) == (off_t)-1) {
123 int err = errno;
124 close(tmp_fd);
125 close(outfd);
126 status = map_nt_error_from_unix(err);
127 goto out;
129 close(tmp_fd);
130 if (close(outfd) == -1) {
131 status = map_nt_error_from_unix(errno);
132 goto out;
135 status = NT_STATUS_OK;
137 out:
138 TALLOC_FREE(ctx);
139 return status;
142 /****************************************************************************
143 Common code to close a file or a directory.
144 ****************************************************************************/
146 static NTSTATUS close_filestruct(files_struct *fsp)
148 NTSTATUS status = NT_STATUS_OK;
150 if (fsp->fh->fd != -1) {
151 if(flush_write_cache(fsp, CLOSE_FLUSH) == -1) {
152 status = map_nt_error_from_unix(errno);
154 delete_write_cache(fsp);
157 return status;
160 /****************************************************************************
161 Delete all streams
162 ****************************************************************************/
164 NTSTATUS delete_all_streams(connection_struct *conn, const char *fname)
166 struct stream_struct *stream_info = NULL;
167 int i;
168 unsigned int num_streams = 0;
169 TALLOC_CTX *frame = talloc_stackframe();
170 NTSTATUS status;
172 status = vfs_streaminfo(conn, NULL, fname, talloc_tos(),
173 &num_streams, &stream_info);
175 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
176 DEBUG(10, ("no streams around\n"));
177 TALLOC_FREE(frame);
178 return NT_STATUS_OK;
181 if (!NT_STATUS_IS_OK(status)) {
182 DEBUG(10, ("vfs_streaminfo failed: %s\n",
183 nt_errstr(status)));
184 goto fail;
187 DEBUG(10, ("delete_all_streams found %d streams\n",
188 num_streams));
190 if (num_streams == 0) {
191 TALLOC_FREE(frame);
192 return NT_STATUS_OK;
195 for (i=0; i<num_streams; i++) {
196 int res;
197 struct smb_filename *smb_fname_stream;
199 if (strequal(stream_info[i].name, "::$DATA")) {
200 continue;
203 smb_fname_stream = synthetic_smb_fname(
204 talloc_tos(), fname, stream_info[i].name, NULL);
206 if (smb_fname_stream == NULL) {
207 DEBUG(0, ("talloc_aprintf failed\n"));
208 status = NT_STATUS_NO_MEMORY;
209 goto fail;
212 res = SMB_VFS_UNLINK(conn, smb_fname_stream);
214 if (res == -1) {
215 status = map_nt_error_from_unix(errno);
216 DEBUG(10, ("Could not delete stream %s: %s\n",
217 smb_fname_str_dbg(smb_fname_stream),
218 strerror(errno)));
219 TALLOC_FREE(smb_fname_stream);
220 break;
222 TALLOC_FREE(smb_fname_stream);
225 fail:
226 TALLOC_FREE(frame);
227 return status;
230 /****************************************************************************
231 Deal with removing a share mode on last close.
232 ****************************************************************************/
234 static NTSTATUS close_remove_share_mode(files_struct *fsp,
235 enum file_close_type close_type)
237 connection_struct *conn = fsp->conn;
238 struct server_id self = messaging_server_id(conn->sconn->msg_ctx);
239 bool delete_file = false;
240 bool changed_user = false;
241 struct share_mode_lock *lck = NULL;
242 NTSTATUS status = NT_STATUS_OK;
243 NTSTATUS tmp_status;
244 struct file_id id;
245 const struct security_unix_token *del_token = NULL;
246 const struct security_token *del_nt_token = NULL;
247 bool got_tokens = false;
248 bool normal_close;
250 /* Ensure any pending write time updates are done. */
251 if (fsp->update_write_time_event) {
252 update_write_time_handler(fsp->conn->sconn->ev_ctx,
253 fsp->update_write_time_event,
254 timeval_current(),
255 (void *)fsp);
259 * Lock the share entries, and determine if we should delete
260 * on close. If so delete whilst the lock is still in effect.
261 * This prevents race conditions with the file being created. JRA.
264 lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
265 if (lck == NULL) {
266 DEBUG(0, ("close_remove_share_mode: Could not get share mode "
267 "lock for file %s\n", fsp_str_dbg(fsp)));
268 return NT_STATUS_INVALID_PARAMETER;
271 if (fsp->write_time_forced) {
272 DEBUG(10,("close_remove_share_mode: write time forced "
273 "for file %s\n",
274 fsp_str_dbg(fsp)));
275 set_close_write_time(fsp, lck->data->changed_write_time);
276 } else if (fsp->update_write_time_on_close) {
277 /* Someone had a pending write. */
278 if (null_timespec(fsp->close_write_time)) {
279 DEBUG(10,("close_remove_share_mode: update to current time "
280 "for file %s\n",
281 fsp_str_dbg(fsp)));
282 /* Update to current time due to "normal" write. */
283 set_close_write_time(fsp, timespec_current());
284 } else {
285 DEBUG(10,("close_remove_share_mode: write time pending "
286 "for file %s\n",
287 fsp_str_dbg(fsp)));
288 /* Update to time set on close call. */
289 set_close_write_time(fsp, fsp->close_write_time);
293 if (fsp->initial_delete_on_close &&
294 !is_delete_on_close_set(lck, fsp->name_hash)) {
295 bool became_user = False;
297 /* Initial delete on close was set and no one else
298 * wrote a real delete on close. */
300 if (get_current_vuid(conn) != fsp->vuid) {
301 become_user(conn, fsp->vuid);
302 became_user = True;
304 fsp->delete_on_close = true;
305 set_delete_on_close_lck(fsp, lck, True,
306 get_current_nttok(conn),
307 get_current_utok(conn));
308 if (became_user) {
309 unbecome_user();
313 delete_file = is_delete_on_close_set(lck, fsp->name_hash);
315 if (delete_file) {
316 int i;
317 /* See if others still have the file open via this pathname.
318 If this is the case, then don't delete. If all opens are
319 POSIX delete now. */
320 for (i=0; i<lck->data->num_share_modes; i++) {
321 struct share_mode_entry *e = &lck->data->share_modes[i];
323 if (!is_valid_share_mode_entry(e)) {
324 continue;
326 if (e->name_hash != fsp->name_hash) {
327 continue;
329 if (fsp->posix_open
330 && (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) {
331 continue;
333 if (serverid_equal(&self, &e->pid) &&
334 (e->share_file_id == fsp->fh->gen_id)) {
335 continue;
337 if (share_mode_stale_pid(lck->data, i)) {
338 continue;
340 delete_file = False;
341 break;
346 * NT can set delete_on_close of the last open
347 * reference to a file.
350 normal_close = (close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE);
352 if (!normal_close || !delete_file) {
354 if (!del_share_mode(lck, fsp)) {
355 DEBUG(0, ("close_remove_share_mode: Could not delete "
356 "share entry for file %s\n",
357 fsp_str_dbg(fsp)));
360 TALLOC_FREE(lck);
361 return NT_STATUS_OK;
365 * Ok, we have to delete the file
368 DEBUG(5,("close_remove_share_mode: file %s. Delete on close was set "
369 "- deleting file.\n", fsp_str_dbg(fsp)));
372 * Don't try to update the write time when we delete the file
374 fsp->update_write_time_on_close = false;
376 got_tokens = get_delete_on_close_token(lck, fsp->name_hash,
377 &del_nt_token, &del_token);
378 SMB_ASSERT(got_tokens);
380 if (!unix_token_equal(del_token, get_current_utok(conn))) {
381 /* Become the user who requested the delete. */
383 DEBUG(5,("close_remove_share_mode: file %s. "
384 "Change user to uid %u\n",
385 fsp_str_dbg(fsp),
386 (unsigned int)del_token->uid));
388 if (!push_sec_ctx()) {
389 smb_panic("close_remove_share_mode: file %s. failed to push "
390 "sec_ctx.\n");
393 set_sec_ctx(del_token->uid,
394 del_token->gid,
395 del_token->ngroups,
396 del_token->groups,
397 del_nt_token);
399 changed_user = true;
402 /* We can only delete the file if the name we have is still valid and
403 hasn't been renamed. */
405 tmp_status = vfs_stat_fsp(fsp);
406 if (!NT_STATUS_IS_OK(tmp_status)) {
407 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
408 "was set and stat failed with error %s\n",
409 fsp_str_dbg(fsp), nt_errstr(tmp_status)));
411 * Don't save the errno here, we ignore this error
413 goto done;
416 id = vfs_file_id_from_sbuf(conn, &fsp->fsp_name->st);
418 if (!file_id_equal(&fsp->file_id, &id)) {
419 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
420 "was set and dev and/or inode does not match\n",
421 fsp_str_dbg(fsp)));
422 DEBUG(5,("close_remove_share_mode: file %s. stored file_id %s, "
423 "stat file_id %s\n",
424 fsp_str_dbg(fsp),
425 file_id_string_tos(&fsp->file_id),
426 file_id_string_tos(&id)));
428 * Don't save the errno here, we ignore this error
430 goto done;
433 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
434 && !is_ntfs_stream_smb_fname(fsp->fsp_name)) {
436 status = delete_all_streams(conn, fsp->fsp_name->base_name);
438 if (!NT_STATUS_IS_OK(status)) {
439 DEBUG(5, ("delete_all_streams failed: %s\n",
440 nt_errstr(status)));
441 goto done;
446 if (SMB_VFS_UNLINK(conn, fsp->fsp_name) != 0) {
448 * This call can potentially fail as another smbd may
449 * have had the file open with delete on close set and
450 * deleted it when its last reference to this file
451 * went away. Hence we log this but not at debug level
452 * zero.
455 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
456 "was set and unlink failed with error %s\n",
457 fsp_str_dbg(fsp), strerror(errno)));
459 status = map_nt_error_from_unix(errno);
462 /* As we now have POSIX opens which can unlink
463 * with other open files we may have taken
464 * this code path with more than one share mode
465 * entry - ensure we only delete once by resetting
466 * the delete on close flag. JRA.
469 fsp->delete_on_close = false;
470 set_delete_on_close_lck(fsp, lck, false, NULL, NULL);
472 done:
474 if (changed_user) {
475 /* unbecome user. */
476 pop_sec_ctx();
479 if (!del_share_mode(lck, fsp)) {
480 DEBUG(0, ("close_remove_share_mode: Could not delete share "
481 "entry for file %s\n", fsp_str_dbg(fsp)));
484 TALLOC_FREE(lck);
486 if (delete_file) {
488 * Do the notification after we released the share
489 * mode lock. Inside notify_fname we take out another
490 * tdb lock. With ctdb also accessing our databases,
491 * this can lead to deadlocks. Putting this notify
492 * after the TALLOC_FREE(lck) above we avoid locking
493 * two records simultaneously. Notifies are async and
494 * informational only, so calling the notify_fname
495 * without holding the share mode lock should not do
496 * any harm.
498 notify_fname(conn, NOTIFY_ACTION_REMOVED,
499 FILE_NOTIFY_CHANGE_FILE_NAME,
500 fsp->fsp_name->base_name);
503 return status;
506 void set_close_write_time(struct files_struct *fsp, struct timespec ts)
508 DEBUG(6,("close_write_time: %s" , time_to_asc(convert_timespec_to_time_t(ts))));
510 if (null_timespec(ts)) {
511 return;
513 fsp->write_time_forced = false;
514 fsp->update_write_time_on_close = true;
515 fsp->close_write_time = ts;
518 static NTSTATUS update_write_time_on_close(struct files_struct *fsp)
520 struct smb_file_time ft;
521 NTSTATUS status;
522 struct share_mode_lock *lck = NULL;
524 ZERO_STRUCT(ft);
526 if (!fsp->update_write_time_on_close) {
527 return NT_STATUS_OK;
530 if (null_timespec(fsp->close_write_time)) {
531 fsp->close_write_time = timespec_current();
534 /* Ensure we have a valid stat struct for the source. */
535 status = vfs_stat_fsp(fsp);
536 if (!NT_STATUS_IS_OK(status)) {
537 return status;
540 if (!VALID_STAT(fsp->fsp_name->st)) {
541 /* if it doesn't seem to be a real file */
542 return NT_STATUS_OK;
546 * get_existing_share_mode_lock() isn't really the right
547 * call here, as we're being called after
548 * close_remove_share_mode() inside close_normal_file()
549 * so it's quite normal to not have an existing share
550 * mode here. However, get_share_mode_lock() doesn't
551 * work because that will create a new share mode if
552 * one doesn't exist - so stick with this call (just
553 * ignore any error we get if the share mode doesn't
554 * exist.
557 lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
558 if (lck) {
559 /* On close if we're changing the real file time we
560 * must update it in the open file db too. */
561 (void)set_write_time(fsp->file_id, fsp->close_write_time);
563 /* Close write times overwrite sticky write times
564 so we must replace any sticky write time here. */
565 if (!null_timespec(lck->data->changed_write_time)) {
566 (void)set_sticky_write_time(fsp->file_id, fsp->close_write_time);
568 TALLOC_FREE(lck);
571 ft.mtime = fsp->close_write_time;
572 /* As this is a close based update, we are not directly changing the
573 file attributes from a client call, but indirectly from a write. */
574 status = smb_set_file_time(fsp->conn, fsp, fsp->fsp_name, &ft, false);
575 if (!NT_STATUS_IS_OK(status)) {
576 DEBUG(10,("update_write_time_on_close: smb_set_file_time "
577 "on file %s returned %s\n",
578 fsp_str_dbg(fsp),
579 nt_errstr(status)));
580 return status;
583 return status;
586 static NTSTATUS ntstatus_keeperror(NTSTATUS s1, NTSTATUS s2)
588 if (!NT_STATUS_IS_OK(s1)) {
589 return s1;
591 return s2;
594 /****************************************************************************
595 Close a file.
597 close_type can be NORMAL_CLOSE=0,SHUTDOWN_CLOSE,ERROR_CLOSE.
598 printing and magic scripts are only run on normal close.
599 delete on close is done on normal and shutdown close.
600 ****************************************************************************/
602 static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp,
603 enum file_close_type close_type)
605 NTSTATUS status = NT_STATUS_OK;
606 NTSTATUS tmp;
607 connection_struct *conn = fsp->conn;
608 bool is_durable = false;
610 if (fsp->num_aio_requests != 0) {
612 if (close_type != SHUTDOWN_CLOSE) {
614 * reply_close and the smb2 close must have
615 * taken care of this. No other callers of
616 * close_file should ever have created async
617 * I/O.
619 * We need to panic here because if we close()
620 * the fd while we have outstanding async I/O
621 * requests, in the worst case we could end up
622 * writing to the wrong file.
624 DEBUG(0, ("fsp->num_aio_requests=%u\n",
625 fsp->num_aio_requests));
626 smb_panic("can not close with outstanding aio "
627 "requests");
631 * For shutdown close, just drop the async requests
632 * including a potential close request pending for
633 * this fsp. Drop the close request first, the
634 * destructor for the aio_requests would execute it.
636 TALLOC_FREE(fsp->deferred_close);
638 while (fsp->num_aio_requests != 0) {
640 * The destructor of the req will remove
641 * itself from the fsp
643 TALLOC_FREE(fsp->aio_requests[0]);
648 * If we're flushing on a close we can get a write
649 * error here, we must remember this.
652 tmp = close_filestruct(fsp);
653 status = ntstatus_keeperror(status, tmp);
655 if (NT_STATUS_IS_OK(status) && fsp->op != NULL) {
656 is_durable = fsp->op->global->durable;
659 if (close_type != SHUTDOWN_CLOSE) {
660 is_durable = false;
663 if (is_durable) {
664 DATA_BLOB new_cookie = data_blob_null;
666 tmp = SMB_VFS_DURABLE_DISCONNECT(fsp,
667 fsp->op->global->backend_cookie,
668 fsp->op,
669 &new_cookie);
670 if (NT_STATUS_IS_OK(tmp)) {
671 struct timeval tv;
672 NTTIME now;
674 if (req != NULL) {
675 tv = req->request_time;
676 } else {
677 tv = timeval_current();
679 now = timeval_to_nttime(&tv);
681 data_blob_free(&fsp->op->global->backend_cookie);
682 fsp->op->global->backend_cookie = new_cookie;
684 fsp->op->compat = NULL;
685 tmp = smbXsrv_open_close(fsp->op, now);
686 if (!NT_STATUS_IS_OK(tmp)) {
687 DEBUG(1, ("Failed to update smbXsrv_open "
688 "record when disconnecting durable "
689 "handle for file %s: %s - "
690 "proceeding with normal close\n",
691 fsp_str_dbg(fsp), nt_errstr(tmp)));
693 scavenger_schedule_disconnected(fsp);
694 } else {
695 DEBUG(1, ("Failed to disconnect durable handle for "
696 "file %s: %s - proceeding with normal "
697 "close\n", fsp_str_dbg(fsp), nt_errstr(tmp)));
699 if (!NT_STATUS_IS_OK(tmp)) {
700 is_durable = false;
704 if (is_durable) {
706 * This is the case where we successfully disconnected
707 * a durable handle and closed the underlying file.
708 * In all other cases, we proceed with a genuine close.
710 DEBUG(10, ("%s disconnected durable handle for file %s\n",
711 conn->session_info->unix_info->unix_name,
712 fsp_str_dbg(fsp)));
713 file_free(req, fsp);
714 return NT_STATUS_OK;
717 if (fsp->op != NULL) {
719 * Make sure the handle is not marked as durable anymore
721 fsp->op->global->durable = false;
724 if (fsp->print_file) {
725 /* FIXME: return spool errors */
726 print_spool_end(fsp, close_type);
727 file_free(req, fsp);
728 return NT_STATUS_OK;
731 /* Remove the oplock before potentially deleting the file. */
732 if(fsp->oplock_type) {
733 release_file_oplock(fsp);
736 /* If this is an old DOS or FCB open and we have multiple opens on
737 the same handle we only have one share mode. Ensure we only remove
738 the share mode on the last close. */
740 if (fsp->fh->ref_count == 1) {
741 /* Should we return on error here... ? */
742 tmp = close_remove_share_mode(fsp, close_type);
743 status = ntstatus_keeperror(status, tmp);
746 locking_close_file(conn->sconn->msg_ctx, fsp, close_type);
748 tmp = fd_close(fsp);
749 status = ntstatus_keeperror(status, tmp);
751 /* check for magic scripts */
752 if (close_type == NORMAL_CLOSE) {
753 tmp = check_magic(fsp);
754 status = ntstatus_keeperror(status, tmp);
758 * Ensure pending modtime is set after close.
761 tmp = update_write_time_on_close(fsp);
762 if (NT_STATUS_EQUAL(tmp, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
763 /* Someone renamed the file or a parent directory containing
764 * this file. We can't do anything about this, we don't have
765 * an "update timestamp by fd" call in POSIX. Eat the error. */
767 tmp = NT_STATUS_OK;
770 status = ntstatus_keeperror(status, tmp);
772 DEBUG(2,("%s closed file %s (numopen=%d) %s\n",
773 conn->session_info->unix_info->unix_name, fsp_str_dbg(fsp),
774 conn->num_files_open - 1,
775 nt_errstr(status) ));
777 file_free(req, fsp);
778 return status;
780 /****************************************************************************
781 Function used by reply_rmdir to delete an entire directory
782 tree recursively. Return True on ok, False on fail.
783 ****************************************************************************/
785 bool recursive_rmdir(TALLOC_CTX *ctx,
786 connection_struct *conn,
787 struct smb_filename *smb_dname)
789 const char *dname = NULL;
790 char *talloced = NULL;
791 bool ret = True;
792 long offset = 0;
793 SMB_STRUCT_STAT st;
794 struct smb_Dir *dir_hnd;
796 SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
798 dir_hnd = OpenDir(talloc_tos(), conn, smb_dname->base_name, NULL, 0);
799 if(dir_hnd == NULL)
800 return False;
802 while((dname = ReadDirName(dir_hnd, &offset, &st, &talloced))) {
803 struct smb_filename *smb_dname_full = NULL;
804 char *fullname = NULL;
805 bool do_break = true;
807 if (ISDOT(dname) || ISDOTDOT(dname)) {
808 TALLOC_FREE(talloced);
809 continue;
812 if (!is_visible_file(conn, smb_dname->base_name, dname, &st,
813 false)) {
814 TALLOC_FREE(talloced);
815 continue;
818 /* Construct the full name. */
819 fullname = talloc_asprintf(ctx,
820 "%s/%s",
821 smb_dname->base_name,
822 dname);
823 if (!fullname) {
824 errno = ENOMEM;
825 goto err_break;
828 smb_dname_full = synthetic_smb_fname(talloc_tos(), fullname,
829 NULL, NULL);
830 if (smb_dname_full == NULL) {
831 errno = ENOMEM;
832 goto err_break;
835 if(SMB_VFS_LSTAT(conn, smb_dname_full) != 0) {
836 goto err_break;
839 if(smb_dname_full->st.st_ex_mode & S_IFDIR) {
840 if(!recursive_rmdir(ctx, conn, smb_dname_full)) {
841 goto err_break;
843 if(SMB_VFS_RMDIR(conn,
844 smb_dname_full->base_name) != 0) {
845 goto err_break;
847 } else if(SMB_VFS_UNLINK(conn, smb_dname_full) != 0) {
848 goto err_break;
851 /* Successful iteration. */
852 do_break = false;
854 err_break:
855 TALLOC_FREE(smb_dname_full);
856 TALLOC_FREE(fullname);
857 TALLOC_FREE(talloced);
858 if (do_break) {
859 ret = false;
860 break;
863 TALLOC_FREE(dir_hnd);
864 return ret;
867 /****************************************************************************
868 The internals of the rmdir code - called elsewhere.
869 ****************************************************************************/
871 static NTSTATUS rmdir_internals(TALLOC_CTX *ctx, files_struct *fsp)
873 connection_struct *conn = fsp->conn;
874 struct smb_filename *smb_dname = fsp->fsp_name;
875 int ret;
877 SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
879 /* Might be a symlink. */
880 if(SMB_VFS_LSTAT(conn, smb_dname) != 0) {
881 return map_nt_error_from_unix(errno);
884 if (S_ISLNK(smb_dname->st.st_ex_mode)) {
885 /* Is what it points to a directory ? */
886 if(SMB_VFS_STAT(conn, smb_dname) != 0) {
887 return map_nt_error_from_unix(errno);
889 if (!(S_ISDIR(smb_dname->st.st_ex_mode))) {
890 return NT_STATUS_NOT_A_DIRECTORY;
892 ret = SMB_VFS_UNLINK(conn, smb_dname);
893 } else {
894 ret = SMB_VFS_RMDIR(conn, smb_dname->base_name);
896 if (ret == 0) {
897 notify_fname(conn, NOTIFY_ACTION_REMOVED,
898 FILE_NOTIFY_CHANGE_DIR_NAME,
899 smb_dname->base_name);
900 return NT_STATUS_OK;
903 if(((errno == ENOTEMPTY)||(errno == EEXIST)) && *lp_veto_files(talloc_tos(), SNUM(conn))) {
905 * Check to see if the only thing in this directory are
906 * vetoed files/directories. If so then delete them and
907 * retry. If we fail to delete any of them (and we *don't*
908 * do a recursive delete) then fail the rmdir.
910 SMB_STRUCT_STAT st;
911 const char *dname = NULL;
912 char *talloced = NULL;
913 long dirpos = 0;
914 struct smb_Dir *dir_hnd = OpenDir(talloc_tos(), conn,
915 smb_dname->base_name, NULL,
918 if(dir_hnd == NULL) {
919 errno = ENOTEMPTY;
920 goto err;
923 while ((dname = ReadDirName(dir_hnd, &dirpos, &st,
924 &talloced)) != NULL) {
925 if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0)) {
926 TALLOC_FREE(talloced);
927 continue;
929 if (!is_visible_file(conn, smb_dname->base_name, dname,
930 &st, false)) {
931 TALLOC_FREE(talloced);
932 continue;
934 if(!IS_VETO_PATH(conn, dname)) {
935 TALLOC_FREE(dir_hnd);
936 TALLOC_FREE(talloced);
937 errno = ENOTEMPTY;
938 goto err;
940 TALLOC_FREE(talloced);
943 /* We only have veto files/directories.
944 * Are we allowed to delete them ? */
946 if(!lp_recursive_veto_delete(SNUM(conn))) {
947 TALLOC_FREE(dir_hnd);
948 errno = ENOTEMPTY;
949 goto err;
952 /* Do a recursive delete. */
953 RewindDir(dir_hnd,&dirpos);
954 while ((dname = ReadDirName(dir_hnd, &dirpos, &st,
955 &talloced)) != NULL) {
956 struct smb_filename *smb_dname_full = NULL;
957 char *fullname = NULL;
958 bool do_break = true;
960 if (ISDOT(dname) || ISDOTDOT(dname)) {
961 TALLOC_FREE(talloced);
962 continue;
964 if (!is_visible_file(conn, smb_dname->base_name, dname,
965 &st, false)) {
966 TALLOC_FREE(talloced);
967 continue;
970 fullname = talloc_asprintf(ctx,
971 "%s/%s",
972 smb_dname->base_name,
973 dname);
975 if(!fullname) {
976 errno = ENOMEM;
977 goto err_break;
980 smb_dname_full = synthetic_smb_fname(
981 talloc_tos(), fullname, NULL, NULL);
982 if (smb_dname_full == NULL) {
983 errno = ENOMEM;
984 goto err_break;
987 if(SMB_VFS_LSTAT(conn, smb_dname_full) != 0) {
988 goto err_break;
990 if(smb_dname_full->st.st_ex_mode & S_IFDIR) {
991 if(!recursive_rmdir(ctx, conn,
992 smb_dname_full)) {
993 goto err_break;
995 if(SMB_VFS_RMDIR(conn,
996 smb_dname_full->base_name) != 0) {
997 goto err_break;
999 } else if(SMB_VFS_UNLINK(conn, smb_dname_full) != 0) {
1000 goto err_break;
1003 /* Successful iteration. */
1004 do_break = false;
1006 err_break:
1007 TALLOC_FREE(fullname);
1008 TALLOC_FREE(smb_dname_full);
1009 TALLOC_FREE(talloced);
1010 if (do_break)
1011 break;
1013 TALLOC_FREE(dir_hnd);
1014 /* Retry the rmdir */
1015 ret = SMB_VFS_RMDIR(conn, smb_dname->base_name);
1018 err:
1020 if (ret != 0) {
1021 DEBUG(3,("rmdir_internals: couldn't remove directory %s : "
1022 "%s\n", smb_fname_str_dbg(smb_dname),
1023 strerror(errno)));
1024 return map_nt_error_from_unix(errno);
1027 notify_fname(conn, NOTIFY_ACTION_REMOVED,
1028 FILE_NOTIFY_CHANGE_DIR_NAME,
1029 smb_dname->base_name);
1031 return NT_STATUS_OK;
1034 /****************************************************************************
1035 Close a directory opened by an NT SMB call.
1036 ****************************************************************************/
1038 static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
1039 enum file_close_type close_type)
1041 struct server_id self = messaging_server_id(fsp->conn->sconn->msg_ctx);
1042 struct share_mode_lock *lck = NULL;
1043 bool delete_dir = False;
1044 NTSTATUS status = NT_STATUS_OK;
1045 NTSTATUS status1 = NT_STATUS_OK;
1046 const struct security_token *del_nt_token = NULL;
1047 const struct security_unix_token *del_token = NULL;
1050 * NT can set delete_on_close of the last open
1051 * reference to a directory also.
1054 lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
1055 if (lck == NULL) {
1056 DEBUG(0, ("close_directory: Could not get share mode lock for "
1057 "%s\n", fsp_str_dbg(fsp)));
1058 return NT_STATUS_INVALID_PARAMETER;
1061 if (fsp->initial_delete_on_close) {
1062 bool became_user = False;
1064 /* Initial delete on close was set - for
1065 * directories we don't care if anyone else
1066 * wrote a real delete on close. */
1068 if (get_current_vuid(fsp->conn) != fsp->vuid) {
1069 become_user(fsp->conn, fsp->vuid);
1070 became_user = True;
1072 send_stat_cache_delete_message(fsp->conn->sconn->msg_ctx,
1073 fsp->fsp_name->base_name);
1074 set_delete_on_close_lck(fsp, lck, true,
1075 get_current_nttok(fsp->conn),
1076 get_current_utok(fsp->conn));
1077 fsp->delete_on_close = true;
1078 if (became_user) {
1079 unbecome_user();
1083 delete_dir = get_delete_on_close_token(lck, fsp->name_hash,
1084 &del_nt_token, &del_token);
1086 if (delete_dir) {
1087 int i;
1088 /* See if others still have the dir open. If this is the
1089 * case, then don't delete. If all opens are POSIX delete now. */
1090 for (i=0; i<lck->data->num_share_modes; i++) {
1091 struct share_mode_entry *e = &lck->data->share_modes[i];
1092 if (is_valid_share_mode_entry(e) &&
1093 e->name_hash == fsp->name_hash) {
1094 if (fsp->posix_open && (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) {
1095 continue;
1097 if (serverid_equal(&self, &e->pid) &&
1098 (e->share_file_id == fsp->fh->gen_id)) {
1099 continue;
1101 if (share_mode_stale_pid(lck->data, i)) {
1102 continue;
1104 delete_dir = False;
1105 break;
1110 if ((close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) &&
1111 delete_dir) {
1113 /* Become the user who requested the delete. */
1115 if (!push_sec_ctx()) {
1116 smb_panic("close_directory: failed to push sec_ctx.\n");
1119 set_sec_ctx(del_token->uid,
1120 del_token->gid,
1121 del_token->ngroups,
1122 del_token->groups,
1123 del_nt_token);
1125 if (!del_share_mode(lck, fsp)) {
1126 DEBUG(0, ("close_directory: Could not delete share entry for "
1127 "%s\n", fsp_str_dbg(fsp)));
1130 TALLOC_FREE(lck);
1132 if ((fsp->conn->fs_capabilities & FILE_NAMED_STREAMS)
1133 && !is_ntfs_stream_smb_fname(fsp->fsp_name)) {
1135 status = delete_all_streams(fsp->conn, fsp->fsp_name->base_name);
1136 if (!NT_STATUS_IS_OK(status)) {
1137 DEBUG(5, ("delete_all_streams failed: %s\n",
1138 nt_errstr(status)));
1139 return status;
1143 status = rmdir_internals(talloc_tos(), fsp);
1145 DEBUG(5,("close_directory: %s. Delete on close was set - "
1146 "deleting directory returned %s.\n",
1147 fsp_str_dbg(fsp), nt_errstr(status)));
1149 /* unbecome user. */
1150 pop_sec_ctx();
1153 * Ensure we remove any change notify requests that would
1154 * now fail as the directory has been deleted.
1157 if(NT_STATUS_IS_OK(status)) {
1158 remove_pending_change_notify_requests_by_fid(fsp, NT_STATUS_DELETE_PENDING);
1160 } else {
1161 if (!del_share_mode(lck, fsp)) {
1162 DEBUG(0, ("close_directory: Could not delete share entry for "
1163 "%s\n", fsp_str_dbg(fsp)));
1166 TALLOC_FREE(lck);
1167 remove_pending_change_notify_requests_by_fid(
1168 fsp, NT_STATUS_OK);
1171 status1 = fd_close(fsp);
1173 if (!NT_STATUS_IS_OK(status1)) {
1174 DEBUG(0, ("Could not close dir! fname=%s, fd=%d, err=%d=%s\n",
1175 fsp_str_dbg(fsp), fsp->fh->fd, errno,
1176 strerror(errno)));
1180 * Do the code common to files and directories.
1182 close_filestruct(fsp);
1183 file_free(req, fsp);
1185 if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(status1)) {
1186 status = status1;
1188 return status;
1191 /****************************************************************************
1192 Close a files_struct.
1193 ****************************************************************************/
1195 NTSTATUS close_file(struct smb_request *req, files_struct *fsp,
1196 enum file_close_type close_type)
1198 NTSTATUS status;
1199 struct files_struct *base_fsp = fsp->base_fsp;
1201 if(fsp->is_directory) {
1202 status = close_directory(req, fsp, close_type);
1203 } else if (fsp->fake_file_handle != NULL) {
1204 status = close_fake_file(req, fsp);
1205 } else {
1206 status = close_normal_file(req, fsp, close_type);
1209 if ((base_fsp != NULL) && (close_type != SHUTDOWN_CLOSE)) {
1212 * fsp was a stream, the base fsp can't be a stream as well
1214 * For SHUTDOWN_CLOSE this is not possible here, because
1215 * SHUTDOWN_CLOSE only happens from files.c which walks the
1216 * complete list of files. If we mess with more than one fsp
1217 * those loops will become confused.
1220 SMB_ASSERT(base_fsp->base_fsp == NULL);
1221 close_file(req, base_fsp, close_type);
1224 return status;
1227 /****************************************************************************
1228 Deal with an (authorized) message to close a file given the share mode
1229 entry.
1230 ****************************************************************************/
1232 void msg_close_file(struct messaging_context *msg_ctx,
1233 void *private_data,
1234 uint32_t msg_type,
1235 struct server_id server_id,
1236 DATA_BLOB *data)
1238 files_struct *fsp = NULL;
1239 struct share_mode_entry e;
1240 struct smbd_server_connection *sconn =
1241 talloc_get_type_abort(private_data,
1242 struct smbd_server_connection);
1244 message_to_share_mode_entry(&e, (char *)data->data);
1246 if(DEBUGLVL(10)) {
1247 char *sm_str = share_mode_str(NULL, 0, &e);
1248 if (!sm_str) {
1249 smb_panic("talloc failed");
1251 DEBUG(10,("msg_close_file: got request to close share mode "
1252 "entry %s\n", sm_str));
1253 TALLOC_FREE(sm_str);
1256 fsp = file_find_dif(sconn, e.id, e.share_file_id);
1257 if (!fsp) {
1258 DEBUG(10,("msg_close_file: failed to find file.\n"));
1259 return;
1261 close_file(NULL, fsp, NORMAL_CLOSE);