Fix typos in LDAP schema files
[Samba.git] / source3 / smbd / close.c
blobaeed4e3c9d7b01cc93e3a033841a0f3abd3cd520
1 /*
2 Unix SMB/CIFS implementation.
3 file closing
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Jeremy Allison 1992-2007.
6 Copyright (C) Volker Lendecke 2005
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "includes.h"
23 #include "system/filesys.h"
24 #include "printing.h"
25 #include "smbd/smbd.h"
26 #include "smbd/globals.h"
27 #include "fake_file.h"
28 #include "transfer_file.h"
29 #include "auth.h"
30 #include "messages.h"
32 /****************************************************************************
33 Run a file if it is a magic script.
34 ****************************************************************************/
36 static NTSTATUS check_magic(struct files_struct *fsp)
38 int ret;
39 const char *magic_output = NULL;
40 SMB_STRUCT_STAT st;
41 int tmp_fd, outfd;
42 TALLOC_CTX *ctx = NULL;
43 const char *p;
44 struct connection_struct *conn = fsp->conn;
45 char *fname = NULL;
46 NTSTATUS status;
48 if (!*lp_magicscript(SNUM(conn))) {
49 return NT_STATUS_OK;
52 DEBUG(5,("checking magic for %s\n", fsp_str_dbg(fsp)));
54 ctx = talloc_stackframe();
56 fname = fsp->fsp_name->base_name;
58 if (!(p = strrchr_m(fname,'/'))) {
59 p = fname;
60 } else {
61 p++;
64 if (!strequal(lp_magicscript(SNUM(conn)),p)) {
65 status = NT_STATUS_OK;
66 goto out;
69 if (*lp_magicoutput(SNUM(conn))) {
70 magic_output = lp_magicoutput(SNUM(conn));
71 } else {
72 magic_output = talloc_asprintf(ctx,
73 "%s.out",
74 fname);
76 if (!magic_output) {
77 status = NT_STATUS_NO_MEMORY;
78 goto out;
81 /* Ensure we don't depend on user's PATH. */
82 p = talloc_asprintf(ctx, "./%s", fname);
83 if (!p) {
84 status = NT_STATUS_NO_MEMORY;
85 goto out;
88 if (chmod(fname, 0755) == -1) {
89 status = map_nt_error_from_unix(errno);
90 goto out;
92 ret = smbrun(p,&tmp_fd);
93 DEBUG(3,("Invoking magic command %s gave %d\n",
94 p,ret));
96 unlink(fname);
97 if (ret != 0 || tmp_fd == -1) {
98 if (tmp_fd != -1) {
99 close(tmp_fd);
101 status = NT_STATUS_UNSUCCESSFUL;
102 goto out;
104 outfd = open(magic_output, O_CREAT|O_EXCL|O_RDWR, 0600);
105 if (outfd == -1) {
106 int err = errno;
107 close(tmp_fd);
108 status = map_nt_error_from_unix(err);
109 goto out;
112 if (sys_fstat(tmp_fd, &st, false) == -1) {
113 int err = errno;
114 close(tmp_fd);
115 close(outfd);
116 status = map_nt_error_from_unix(err);
117 goto out;
120 if (transfer_file(tmp_fd,outfd,(SMB_OFF_T)st.st_ex_size) == (SMB_OFF_T)-1) {
121 int err = errno;
122 close(tmp_fd);
123 close(outfd);
124 status = map_nt_error_from_unix(err);
125 goto out;
127 close(tmp_fd);
128 if (close(outfd) == -1) {
129 status = map_nt_error_from_unix(errno);
130 goto out;
133 status = NT_STATUS_OK;
135 out:
136 TALLOC_FREE(ctx);
137 return status;
140 /****************************************************************************
141 Common code to close a file or a directory.
142 ****************************************************************************/
144 static NTSTATUS close_filestruct(files_struct *fsp)
146 NTSTATUS status = NT_STATUS_OK;
148 if (fsp->fh->fd != -1) {
149 if(flush_write_cache(fsp, CLOSE_FLUSH) == -1) {
150 status = map_nt_error_from_unix(errno);
152 delete_write_cache(fsp);
155 return status;
158 /****************************************************************************
159 If any deferred opens are waiting on this close, notify them.
160 ****************************************************************************/
162 static void notify_deferred_opens(struct messaging_context *msg_ctx,
163 struct share_mode_lock *lck)
165 int i;
167 if (!should_notify_deferred_opens()) {
168 return;
171 for (i=0; i<lck->num_share_modes; i++) {
172 struct share_mode_entry *e = &lck->share_modes[i];
174 if (!is_deferred_open_entry(e)) {
175 continue;
178 if (procid_is_me(&e->pid)) {
180 * We need to notify ourself to retry the open. Do
181 * this by finding the queued SMB record, moving it to
182 * the head of the queue and changing the wait time to
183 * zero.
185 schedule_deferred_open_message_smb(e->op_mid);
186 } else {
187 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
189 share_mode_entry_to_message(msg, e);
191 messaging_send_buf(msg_ctx, e->pid, MSG_SMB_OPEN_RETRY,
192 (uint8 *)msg,
193 MSG_SMB_SHARE_MODE_ENTRY_SIZE);
198 /****************************************************************************
199 Delete all streams
200 ****************************************************************************/
202 NTSTATUS delete_all_streams(connection_struct *conn, const char *fname)
204 struct stream_struct *stream_info;
205 int i;
206 unsigned int num_streams;
207 TALLOC_CTX *frame = talloc_stackframe();
208 NTSTATUS status;
210 status = SMB_VFS_STREAMINFO(conn, NULL, fname, talloc_tos(),
211 &num_streams, &stream_info);
213 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
214 DEBUG(10, ("no streams around\n"));
215 TALLOC_FREE(frame);
216 return NT_STATUS_OK;
219 if (!NT_STATUS_IS_OK(status)) {
220 DEBUG(10, ("SMB_VFS_STREAMINFO failed: %s\n",
221 nt_errstr(status)));
222 goto fail;
225 DEBUG(10, ("delete_all_streams found %d streams\n",
226 num_streams));
228 if (num_streams == 0) {
229 TALLOC_FREE(frame);
230 return NT_STATUS_OK;
233 for (i=0; i<num_streams; i++) {
234 int res;
235 struct smb_filename *smb_fname_stream = NULL;
237 if (strequal(stream_info[i].name, "::$DATA")) {
238 continue;
241 status = create_synthetic_smb_fname(talloc_tos(), fname,
242 stream_info[i].name, NULL,
243 &smb_fname_stream);
245 if (!NT_STATUS_IS_OK(status)) {
246 DEBUG(0, ("talloc_aprintf failed\n"));
247 goto fail;
250 res = SMB_VFS_UNLINK(conn, smb_fname_stream);
252 if (res == -1) {
253 status = map_nt_error_from_unix(errno);
254 DEBUG(10, ("Could not delete stream %s: %s\n",
255 smb_fname_str_dbg(smb_fname_stream),
256 strerror(errno)));
257 TALLOC_FREE(smb_fname_stream);
258 break;
260 TALLOC_FREE(smb_fname_stream);
263 fail:
264 TALLOC_FREE(frame);
265 return status;
268 /****************************************************************************
269 Deal with removing a share mode on last close.
270 ****************************************************************************/
272 static NTSTATUS close_remove_share_mode(files_struct *fsp,
273 enum file_close_type close_type)
275 connection_struct *conn = fsp->conn;
276 bool delete_file = false;
277 bool changed_user = false;
278 struct share_mode_lock *lck = NULL;
279 NTSTATUS status = NT_STATUS_OK;
280 NTSTATUS tmp_status;
281 struct file_id id;
282 const struct security_unix_token *del_token = NULL;
284 /* Ensure any pending write time updates are done. */
285 if (fsp->update_write_time_event) {
286 update_write_time_handler(smbd_event_context(),
287 fsp->update_write_time_event,
288 timeval_current(),
289 (void *)fsp);
293 * Lock the share entries, and determine if we should delete
294 * on close. If so delete whilst the lock is still in effect.
295 * This prevents race conditions with the file being created. JRA.
298 lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL,
299 NULL);
301 if (lck == NULL) {
302 DEBUG(0, ("close_remove_share_mode: Could not get share mode "
303 "lock for file %s\n", fsp_str_dbg(fsp)));
304 status = NT_STATUS_INVALID_PARAMETER;
305 goto done;
308 if (fsp->write_time_forced) {
309 DEBUG(10,("close_remove_share_mode: write time forced "
310 "for file %s\n",
311 fsp_str_dbg(fsp)));
312 set_close_write_time(fsp, lck->changed_write_time);
313 } else if (fsp->update_write_time_on_close) {
314 /* Someone had a pending write. */
315 if (null_timespec(fsp->close_write_time)) {
316 DEBUG(10,("close_remove_share_mode: update to current time "
317 "for file %s\n",
318 fsp_str_dbg(fsp)));
319 /* Update to current time due to "normal" write. */
320 set_close_write_time(fsp, timespec_current());
321 } else {
322 DEBUG(10,("close_remove_share_mode: write time pending "
323 "for file %s\n",
324 fsp_str_dbg(fsp)));
325 /* Update to time set on close call. */
326 set_close_write_time(fsp, fsp->close_write_time);
330 if (!del_share_mode(lck, fsp)) {
331 DEBUG(0, ("close_remove_share_mode: Could not delete share "
332 "entry for file %s\n",
333 fsp_str_dbg(fsp)));
336 if (fsp->initial_delete_on_close &&
337 !is_delete_on_close_set(lck, fsp->name_hash)) {
338 bool became_user = False;
340 /* Initial delete on close was set and no one else
341 * wrote a real delete on close. */
343 if (get_current_vuid(conn) != fsp->vuid) {
344 become_user(conn, fsp->vuid);
345 became_user = True;
347 fsp->delete_on_close = true;
348 set_delete_on_close_lck(fsp, lck, True, get_current_utok(conn));
349 if (became_user) {
350 unbecome_user();
354 delete_file = is_delete_on_close_set(lck, fsp->name_hash);
356 if (delete_file) {
357 int i;
358 /* See if others still have the file open via this pathname.
359 If this is the case, then don't delete. If all opens are
360 POSIX delete now. */
361 for (i=0; i<lck->num_share_modes; i++) {
362 struct share_mode_entry *e = &lck->share_modes[i];
363 if (is_valid_share_mode_entry(e) &&
364 e->name_hash == fsp->name_hash) {
365 if (fsp->posix_open && (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) {
366 continue;
368 delete_file = False;
369 break;
374 /* Notify any deferred opens waiting on this close. */
375 notify_deferred_opens(conn->sconn->msg_ctx, lck);
376 reply_to_oplock_break_requests(fsp);
379 * NT can set delete_on_close of the last open
380 * reference to a file.
383 if (!(close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) ||
384 !delete_file) {
385 TALLOC_FREE(lck);
386 return NT_STATUS_OK;
390 * Ok, we have to delete the file
393 DEBUG(5,("close_remove_share_mode: file %s. Delete on close was set "
394 "- deleting file.\n", fsp_str_dbg(fsp)));
397 * Don't try to update the write time when we delete the file
399 fsp->update_write_time_on_close = false;
401 del_token = get_delete_on_close_token(lck, fsp->name_hash);
402 SMB_ASSERT(del_token != NULL);
404 if (!unix_token_equal(del_token, get_current_utok(conn))) {
405 /* Become the user who requested the delete. */
407 DEBUG(5,("close_remove_share_mode: file %s. "
408 "Change user to uid %u\n",
409 fsp_str_dbg(fsp),
410 (unsigned int)del_token->uid));
412 if (!push_sec_ctx()) {
413 smb_panic("close_remove_share_mode: file %s. failed to push "
414 "sec_ctx.\n");
417 set_sec_ctx(del_token->uid,
418 del_token->gid,
419 del_token->ngroups,
420 del_token->groups,
421 NULL);
423 changed_user = true;
426 /* We can only delete the file if the name we have is still valid and
427 hasn't been renamed. */
429 tmp_status = vfs_stat_fsp(fsp);
430 if (!NT_STATUS_IS_OK(tmp_status)) {
431 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
432 "was set and stat failed with error %s\n",
433 fsp_str_dbg(fsp), nt_errstr(tmp_status)));
435 * Don't save the errno here, we ignore this error
437 goto done;
440 id = vfs_file_id_from_sbuf(conn, &fsp->fsp_name->st);
442 if (!file_id_equal(&fsp->file_id, &id)) {
443 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
444 "was set and dev and/or inode does not match\n",
445 fsp_str_dbg(fsp)));
446 DEBUG(5,("close_remove_share_mode: file %s. stored file_id %s, "
447 "stat file_id %s\n",
448 fsp_str_dbg(fsp),
449 file_id_string_tos(&fsp->file_id),
450 file_id_string_tos(&id)));
452 * Don't save the errno here, we ignore this error
454 goto done;
457 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
458 && !is_ntfs_stream_smb_fname(fsp->fsp_name)) {
460 status = delete_all_streams(conn, fsp->fsp_name->base_name);
462 if (!NT_STATUS_IS_OK(status)) {
463 DEBUG(5, ("delete_all_streams failed: %s\n",
464 nt_errstr(status)));
465 goto done;
470 if (SMB_VFS_UNLINK(conn, fsp->fsp_name) != 0) {
472 * This call can potentially fail as another smbd may
473 * have had the file open with delete on close set and
474 * deleted it when its last reference to this file
475 * went away. Hence we log this but not at debug level
476 * zero.
479 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
480 "was set and unlink failed with error %s\n",
481 fsp_str_dbg(fsp), strerror(errno)));
483 status = map_nt_error_from_unix(errno);
486 /* As we now have POSIX opens which can unlink
487 * with other open files we may have taken
488 * this code path with more than one share mode
489 * entry - ensure we only delete once by resetting
490 * the delete on close flag. JRA.
493 fsp->delete_on_close = false;
494 set_delete_on_close_lck(fsp, lck, false, NULL);
496 done:
498 if (changed_user) {
499 /* unbecome user. */
500 pop_sec_ctx();
503 TALLOC_FREE(lck);
505 if (delete_file) {
507 * Do the notification after we released the share
508 * mode lock. Inside notify_fname we take out another
509 * tdb lock. With ctdb also accessing our databases,
510 * this can lead to deadlocks. Putting this notify
511 * after the TALLOC_FREE(lck) above we avoid locking
512 * two records simultaneously. Notifies are async and
513 * informational only, so calling the notify_fname
514 * without holding the share mode lock should not do
515 * any harm.
517 notify_fname(conn, NOTIFY_ACTION_REMOVED,
518 FILE_NOTIFY_CHANGE_FILE_NAME,
519 fsp->fsp_name->base_name);
522 return status;
525 void set_close_write_time(struct files_struct *fsp, struct timespec ts)
527 DEBUG(6,("close_write_time: %s" , time_to_asc(convert_timespec_to_time_t(ts))));
529 if (null_timespec(ts)) {
530 return;
532 fsp->write_time_forced = false;
533 fsp->update_write_time_on_close = true;
534 fsp->close_write_time = ts;
537 static NTSTATUS update_write_time_on_close(struct files_struct *fsp)
539 struct smb_file_time ft;
540 NTSTATUS status;
541 struct share_mode_lock *lck = NULL;
543 ZERO_STRUCT(ft);
545 if (!fsp->update_write_time_on_close) {
546 return NT_STATUS_OK;
549 if (null_timespec(fsp->close_write_time)) {
550 fsp->close_write_time = timespec_current();
553 /* Ensure we have a valid stat struct for the source. */
554 status = vfs_stat_fsp(fsp);
555 if (!NT_STATUS_IS_OK(status)) {
556 return status;
559 if (!VALID_STAT(fsp->fsp_name->st)) {
560 /* if it doesn't seem to be a real file */
561 return NT_STATUS_OK;
564 /* On close if we're changing the real file time we
565 * must update it in the open file db too. */
566 (void)set_write_time(fsp->file_id, fsp->close_write_time);
568 lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL, NULL);
569 if (lck) {
570 /* Close write times overwrite sticky write times
571 so we must replace any sticky write time here. */
572 if (!null_timespec(lck->changed_write_time)) {
573 (void)set_sticky_write_time(fsp->file_id, fsp->close_write_time);
575 TALLOC_FREE(lck);
578 ft.mtime = fsp->close_write_time;
579 /* We must use NULL for the fsp handle here, as smb_set_file_time()
580 checks the fsp access_mask, which may not include FILE_WRITE_ATTRIBUTES.
581 As this is a close based update, we are not directly changing the
582 file attributes from a client call, but indirectly from a write. */
583 status = smb_set_file_time(fsp->conn, NULL, fsp->fsp_name, &ft, false);
584 if (!NT_STATUS_IS_OK(status)) {
585 DEBUG(10,("update_write_time_on_close: smb_set_file_time "
586 "on file %s returned %s\n",
587 fsp_str_dbg(fsp),
588 nt_errstr(status)));
589 return status;
592 return status;
595 static NTSTATUS ntstatus_keeperror(NTSTATUS s1, NTSTATUS s2)
597 if (!NT_STATUS_IS_OK(s1)) {
598 return s1;
600 return s2;
603 /****************************************************************************
604 Close a file.
606 close_type can be NORMAL_CLOSE=0,SHUTDOWN_CLOSE,ERROR_CLOSE.
607 printing and magic scripts are only run on normal close.
608 delete on close is done on normal and shutdown close.
609 ****************************************************************************/
611 static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp,
612 enum file_close_type close_type)
614 NTSTATUS status = NT_STATUS_OK;
615 NTSTATUS tmp;
616 connection_struct *conn = fsp->conn;
618 if (close_type == ERROR_CLOSE) {
619 cancel_aio_by_fsp(fsp);
620 } else {
622 * If we're finishing async io on a close we can get a write
623 * error here, we must remember this.
625 int ret = wait_for_aio_completion(fsp);
626 if (ret) {
627 status = ntstatus_keeperror(
628 status, map_nt_error_from_unix(ret));
633 * If we're flushing on a close we can get a write
634 * error here, we must remember this.
637 tmp = close_filestruct(fsp);
638 status = ntstatus_keeperror(status, tmp);
640 if (fsp->print_file) {
641 /* FIXME: return spool errors */
642 print_spool_end(fsp, close_type);
643 file_free(req, fsp);
644 return NT_STATUS_OK;
647 /* Remove the oplock before potentially deleting the file. */
648 if(fsp->oplock_type) {
649 release_file_oplock(fsp);
652 /* If this is an old DOS or FCB open and we have multiple opens on
653 the same handle we only have one share mode. Ensure we only remove
654 the share mode on the last close. */
656 if (fsp->fh->ref_count == 1) {
657 /* Should we return on error here... ? */
658 tmp = close_remove_share_mode(fsp, close_type);
659 status = ntstatus_keeperror(status, tmp);
662 locking_close_file(conn->sconn->msg_ctx, fsp, close_type);
664 tmp = fd_close(fsp);
665 status = ntstatus_keeperror(status, tmp);
667 /* check for magic scripts */
668 if (close_type == NORMAL_CLOSE) {
669 tmp = check_magic(fsp);
670 status = ntstatus_keeperror(status, tmp);
674 * Ensure pending modtime is set after close.
677 tmp = update_write_time_on_close(fsp);
678 if (NT_STATUS_EQUAL(tmp, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
679 /* Someone renamed the file or a parent directory containing
680 * this file. We can't do anything about this, we don't have
681 * an "update timestamp by fd" call in POSIX. Eat the error. */
683 tmp = NT_STATUS_OK;
686 status = ntstatus_keeperror(status, tmp);
688 DEBUG(2,("%s closed file %s (numopen=%d) %s\n",
689 conn->session_info->unix_name, fsp_str_dbg(fsp),
690 conn->num_files_open - 1,
691 nt_errstr(status) ));
693 file_free(req, fsp);
694 return status;
696 /****************************************************************************
697 Static function used by reply_rmdir to delete an entire directory
698 tree recursively. Return True on ok, False on fail.
699 ****************************************************************************/
701 static bool recursive_rmdir(TALLOC_CTX *ctx,
702 connection_struct *conn,
703 struct smb_filename *smb_dname)
705 const char *dname = NULL;
706 char *talloced = NULL;
707 bool ret = True;
708 long offset = 0;
709 SMB_STRUCT_STAT st;
710 struct smb_Dir *dir_hnd;
712 SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
714 dir_hnd = OpenDir(talloc_tos(), conn, smb_dname->base_name, NULL, 0);
715 if(dir_hnd == NULL)
716 return False;
718 while((dname = ReadDirName(dir_hnd, &offset, &st, &talloced))) {
719 struct smb_filename *smb_dname_full = NULL;
720 char *fullname = NULL;
721 bool do_break = true;
722 NTSTATUS status;
724 if (ISDOT(dname) || ISDOTDOT(dname)) {
725 TALLOC_FREE(talloced);
726 continue;
729 if (!is_visible_file(conn, smb_dname->base_name, dname, &st,
730 false)) {
731 TALLOC_FREE(talloced);
732 continue;
735 /* Construct the full name. */
736 fullname = talloc_asprintf(ctx,
737 "%s/%s",
738 smb_dname->base_name,
739 dname);
740 if (!fullname) {
741 errno = ENOMEM;
742 goto err_break;
745 status = create_synthetic_smb_fname(talloc_tos(), fullname,
746 NULL, NULL,
747 &smb_dname_full);
748 if (!NT_STATUS_IS_OK(status)) {
749 goto err_break;
752 if(SMB_VFS_LSTAT(conn, smb_dname_full) != 0) {
753 goto err_break;
756 if(smb_dname_full->st.st_ex_mode & S_IFDIR) {
757 if(!recursive_rmdir(ctx, conn, smb_dname_full)) {
758 goto err_break;
760 if(SMB_VFS_RMDIR(conn,
761 smb_dname_full->base_name) != 0) {
762 goto err_break;
764 } else if(SMB_VFS_UNLINK(conn, smb_dname_full) != 0) {
765 goto err_break;
768 /* Successful iteration. */
769 do_break = false;
771 err_break:
772 TALLOC_FREE(smb_dname_full);
773 TALLOC_FREE(fullname);
774 TALLOC_FREE(talloced);
775 if (do_break) {
776 ret = false;
777 break;
780 TALLOC_FREE(dir_hnd);
781 return ret;
784 /****************************************************************************
785 The internals of the rmdir code - called elsewhere.
786 ****************************************************************************/
788 static NTSTATUS rmdir_internals(TALLOC_CTX *ctx, files_struct *fsp)
790 connection_struct *conn = fsp->conn;
791 struct smb_filename *smb_dname = fsp->fsp_name;
792 int ret;
794 SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
796 /* Might be a symlink. */
797 if(SMB_VFS_LSTAT(conn, smb_dname) != 0) {
798 return map_nt_error_from_unix(errno);
801 if (S_ISLNK(smb_dname->st.st_ex_mode)) {
802 /* Is what it points to a directory ? */
803 if(SMB_VFS_STAT(conn, smb_dname) != 0) {
804 return map_nt_error_from_unix(errno);
806 if (!(S_ISDIR(smb_dname->st.st_ex_mode))) {
807 return NT_STATUS_NOT_A_DIRECTORY;
809 ret = SMB_VFS_UNLINK(conn, smb_dname);
810 } else {
811 ret = SMB_VFS_RMDIR(conn, smb_dname->base_name);
813 if (ret == 0) {
814 notify_fname(conn, NOTIFY_ACTION_REMOVED,
815 FILE_NOTIFY_CHANGE_DIR_NAME,
816 smb_dname->base_name);
817 return NT_STATUS_OK;
820 if(((errno == ENOTEMPTY)||(errno == EEXIST)) && lp_veto_files(SNUM(conn))) {
822 * Check to see if the only thing in this directory are
823 * vetoed files/directories. If so then delete them and
824 * retry. If we fail to delete any of them (and we *don't*
825 * do a recursive delete) then fail the rmdir.
827 SMB_STRUCT_STAT st;
828 const char *dname = NULL;
829 char *talloced = NULL;
830 long dirpos = 0;
831 struct smb_Dir *dir_hnd = OpenDir(talloc_tos(), conn,
832 smb_dname->base_name, NULL,
835 if(dir_hnd == NULL) {
836 errno = ENOTEMPTY;
837 goto err;
840 while ((dname = ReadDirName(dir_hnd, &dirpos, &st,
841 &talloced)) != NULL) {
842 if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0)) {
843 TALLOC_FREE(talloced);
844 continue;
846 if (!is_visible_file(conn, smb_dname->base_name, dname,
847 &st, false)) {
848 TALLOC_FREE(talloced);
849 continue;
851 if(!IS_VETO_PATH(conn, dname)) {
852 TALLOC_FREE(dir_hnd);
853 TALLOC_FREE(talloced);
854 errno = ENOTEMPTY;
855 goto err;
857 TALLOC_FREE(talloced);
860 /* We only have veto files/directories.
861 * Are we allowed to delete them ? */
863 if(!lp_recursive_veto_delete(SNUM(conn))) {
864 TALLOC_FREE(dir_hnd);
865 errno = ENOTEMPTY;
866 goto err;
869 /* Do a recursive delete. */
870 RewindDir(dir_hnd,&dirpos);
871 while ((dname = ReadDirName(dir_hnd, &dirpos, &st,
872 &talloced)) != NULL) {
873 struct smb_filename *smb_dname_full = NULL;
874 char *fullname = NULL;
875 bool do_break = true;
876 NTSTATUS status;
878 if (ISDOT(dname) || ISDOTDOT(dname)) {
879 TALLOC_FREE(talloced);
880 continue;
882 if (!is_visible_file(conn, smb_dname->base_name, dname,
883 &st, false)) {
884 TALLOC_FREE(talloced);
885 continue;
888 fullname = talloc_asprintf(ctx,
889 "%s/%s",
890 smb_dname->base_name,
891 dname);
893 if(!fullname) {
894 errno = ENOMEM;
895 goto err_break;
898 status = create_synthetic_smb_fname(talloc_tos(),
899 fullname, NULL,
900 NULL,
901 &smb_dname_full);
902 if (!NT_STATUS_IS_OK(status)) {
903 errno = map_errno_from_nt_status(status);
904 goto err_break;
907 if(SMB_VFS_LSTAT(conn, smb_dname_full) != 0) {
908 goto err_break;
910 if(smb_dname_full->st.st_ex_mode & S_IFDIR) {
911 if(!recursive_rmdir(ctx, conn,
912 smb_dname_full)) {
913 goto err_break;
915 if(SMB_VFS_RMDIR(conn,
916 smb_dname_full->base_name) != 0) {
917 goto err_break;
919 } else if(SMB_VFS_UNLINK(conn, smb_dname_full) != 0) {
920 goto err_break;
923 /* Successful iteration. */
924 do_break = false;
926 err_break:
927 TALLOC_FREE(fullname);
928 TALLOC_FREE(smb_dname_full);
929 TALLOC_FREE(talloced);
930 if (do_break)
931 break;
933 TALLOC_FREE(dir_hnd);
934 /* Retry the rmdir */
935 ret = SMB_VFS_RMDIR(conn, smb_dname->base_name);
938 err:
940 if (ret != 0) {
941 DEBUG(3,("rmdir_internals: couldn't remove directory %s : "
942 "%s\n", smb_fname_str_dbg(smb_dname),
943 strerror(errno)));
944 return map_nt_error_from_unix(errno);
947 notify_fname(conn, NOTIFY_ACTION_REMOVED,
948 FILE_NOTIFY_CHANGE_DIR_NAME,
949 smb_dname->base_name);
951 return NT_STATUS_OK;
954 /****************************************************************************
955 Close a directory opened by an NT SMB call.
956 ****************************************************************************/
958 static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
959 enum file_close_type close_type)
961 struct share_mode_lock *lck = NULL;
962 bool delete_dir = False;
963 NTSTATUS status = NT_STATUS_OK;
964 NTSTATUS status1 = NT_STATUS_OK;
965 const struct security_unix_token *del_token = NULL;
968 * NT can set delete_on_close of the last open
969 * reference to a directory also.
972 lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL,
973 NULL);
975 if (lck == NULL) {
976 DEBUG(0, ("close_directory: Could not get share mode lock for "
977 "%s\n", fsp_str_dbg(fsp)));
978 status = NT_STATUS_INVALID_PARAMETER;
979 goto out;
982 if (!del_share_mode(lck, fsp)) {
983 DEBUG(0, ("close_directory: Could not delete share entry for "
984 "%s\n", fsp_str_dbg(fsp)));
987 if (fsp->initial_delete_on_close) {
988 bool became_user = False;
990 /* Initial delete on close was set - for
991 * directories we don't care if anyone else
992 * wrote a real delete on close. */
994 if (get_current_vuid(fsp->conn) != fsp->vuid) {
995 become_user(fsp->conn, fsp->vuid);
996 became_user = True;
998 send_stat_cache_delete_message(fsp->conn->sconn->msg_ctx,
999 fsp->fsp_name->base_name);
1000 set_delete_on_close_lck(fsp, lck, true,
1001 get_current_utok(fsp->conn));
1002 fsp->delete_on_close = true;
1003 if (became_user) {
1004 unbecome_user();
1008 del_token = get_delete_on_close_token(lck, fsp->name_hash);
1009 delete_dir = (del_token != NULL);
1011 if (delete_dir) {
1012 int i;
1013 /* See if others still have the dir open. If this is the
1014 * case, then don't delete. If all opens are POSIX delete now. */
1015 for (i=0; i<lck->num_share_modes; i++) {
1016 struct share_mode_entry *e = &lck->share_modes[i];
1017 if (is_valid_share_mode_entry(e) &&
1018 e->name_hash == fsp->name_hash) {
1019 if (fsp->posix_open && (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) {
1020 continue;
1022 delete_dir = False;
1023 break;
1028 if ((close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) &&
1029 delete_dir) {
1031 /* Become the user who requested the delete. */
1033 if (!push_sec_ctx()) {
1034 smb_panic("close_directory: failed to push sec_ctx.\n");
1037 set_sec_ctx(del_token->uid,
1038 del_token->gid,
1039 del_token->ngroups,
1040 del_token->groups,
1041 NULL);
1043 TALLOC_FREE(lck);
1045 status = rmdir_internals(talloc_tos(), fsp);
1047 DEBUG(5,("close_directory: %s. Delete on close was set - "
1048 "deleting directory returned %s.\n",
1049 fsp_str_dbg(fsp), nt_errstr(status)));
1051 /* unbecome user. */
1052 pop_sec_ctx();
1055 * Ensure we remove any change notify requests that would
1056 * now fail as the directory has been deleted.
1059 if(NT_STATUS_IS_OK(status)) {
1060 remove_pending_change_notify_requests_by_fid(fsp, NT_STATUS_DELETE_PENDING);
1062 } else {
1063 TALLOC_FREE(lck);
1064 remove_pending_change_notify_requests_by_fid(
1065 fsp, NT_STATUS_OK);
1068 status1 = fd_close(fsp);
1070 if (!NT_STATUS_IS_OK(status1)) {
1071 DEBUG(0, ("Could not close dir! fname=%s, fd=%d, err=%d=%s\n",
1072 fsp_str_dbg(fsp), fsp->fh->fd, errno,
1073 strerror(errno)));
1077 * Do the code common to files and directories.
1079 close_filestruct(fsp);
1080 file_free(req, fsp);
1082 out:
1083 TALLOC_FREE(lck);
1084 if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(status1)) {
1085 status = status1;
1087 return status;
1090 /****************************************************************************
1091 Close a files_struct.
1092 ****************************************************************************/
1094 NTSTATUS close_file(struct smb_request *req, files_struct *fsp,
1095 enum file_close_type close_type)
1097 NTSTATUS status;
1098 struct files_struct *base_fsp = fsp->base_fsp;
1100 if(fsp->is_directory) {
1101 status = close_directory(req, fsp, close_type);
1102 } else if (fsp->fake_file_handle != NULL) {
1103 status = close_fake_file(req, fsp);
1104 } else {
1105 status = close_normal_file(req, fsp, close_type);
1108 if ((base_fsp != NULL) && (close_type != SHUTDOWN_CLOSE)) {
1111 * fsp was a stream, the base fsp can't be a stream as well
1113 * For SHUTDOWN_CLOSE this is not possible here, because
1114 * SHUTDOWN_CLOSE only happens from files.c which walks the
1115 * complete list of files. If we mess with more than one fsp
1116 * those loops will become confused.
1119 SMB_ASSERT(base_fsp->base_fsp == NULL);
1120 close_file(req, base_fsp, close_type);
1123 return status;
1126 /****************************************************************************
1127 Deal with an (authorized) message to close a file given the share mode
1128 entry.
1129 ****************************************************************************/
1131 void msg_close_file(struct messaging_context *msg_ctx,
1132 void *private_data,
1133 uint32_t msg_type,
1134 struct server_id server_id,
1135 DATA_BLOB *data)
1137 struct smbd_server_connection *sconn;
1138 files_struct *fsp = NULL;
1139 struct share_mode_entry e;
1141 sconn = msg_ctx_to_sconn(msg_ctx);
1142 if (sconn == NULL) {
1143 DEBUG(1, ("could not find sconn\n"));
1144 return;
1147 message_to_share_mode_entry(&e, (char *)data->data);
1149 if(DEBUGLVL(10)) {
1150 char *sm_str = share_mode_str(NULL, 0, &e);
1151 if (!sm_str) {
1152 smb_panic("talloc failed");
1154 DEBUG(10,("msg_close_file: got request to close share mode "
1155 "entry %s\n", sm_str));
1156 TALLOC_FREE(sm_str);
1159 fsp = file_find_dif(sconn, e.id, e.share_file_id);
1160 if (!fsp) {
1161 DEBUG(10,("msg_close_file: failed to find file.\n"));
1162 return;
1164 close_file(NULL, fsp, NORMAL_CLOSE);