smbd: Remove source3/smbd/statcache.c
[samba.git] / source3 / smbd / close.c
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
7
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.
12
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.
17
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/>.
20 */
21
22 #include "includes.h"
23 #include "system/filesys.h"
24 #include "lib/util/server_id.h"
25 #include "printing.h"
26 #include "locking/share_mode_lock.h"
27 #include "smbd/smbd.h"
28 #include "smbd/globals.h"
29 #include "smbd/smbXsrv_open.h"
30 #include "smbd/scavenger.h"
31 #include "fake_file.h"
32 #include "transfer_file.h"
33 #include "auth.h"
34 #include "messages.h"
35 #include "../librpc/gen_ndr/open_files.h"
36 #include "lib/util/tevent_ntstatus.h"
37
38 /****************************************************************************
39  Run a file if it is a magic script.
40 ****************************************************************************/
41
42 static NTSTATUS check_magic(struct files_struct *fsp)
43 {
44         int ret;
45         const struct loadparm_substitution *lp_sub =
46                 loadparm_s3_global_substitution();
47         const char *magic_output = NULL;
48         SMB_STRUCT_STAT st;
49         int tmp_fd, outfd;
50         TALLOC_CTX *ctx = NULL;
51         const char *p;
52         struct connection_struct *conn = fsp->conn;
53         char *fname = NULL;
54         NTSTATUS status;
55
56         if (!*lp_magic_script(talloc_tos(), lp_sub, SNUM(conn))) {
57                 return NT_STATUS_OK;
58         }
59
60         DEBUG(5,("checking magic for %s\n", fsp_str_dbg(fsp)));
61
62         ctx = talloc_stackframe();
63
64         fname = fsp->fsp_name->base_name;
65
66         if (!(p = strrchr_m(fname,'/'))) {
67                 p = fname;
68         } else {
69                 p++;
70         }
71
72         if (!strequal(lp_magic_script(talloc_tos(), lp_sub, SNUM(conn)),p)) {
73                 status = NT_STATUS_OK;
74                 goto out;
75         }
76
77         if (*lp_magic_output(talloc_tos(), lp_sub, SNUM(conn))) {
78                 magic_output = lp_magic_output(talloc_tos(), lp_sub, SNUM(conn));
79         } else {
80                 magic_output = talloc_asprintf(ctx,
81                                 "%s.out",
82                                 fname);
83         }
84         if (!magic_output) {
85                 status = NT_STATUS_NO_MEMORY;
86                 goto out;
87         }
88
89         /* Ensure we don't depend on user's PATH. */
90         p = talloc_asprintf(ctx, "./%s", fname);
91         if (!p) {
92                 status = NT_STATUS_NO_MEMORY;
93                 goto out;
94         }
95
96         if (chmod(fname, 0755) == -1) {
97                 status = map_nt_error_from_unix(errno);
98                 goto out;
99         }
100         ret = smbrun(p, &tmp_fd, NULL);
101         DEBUG(3,("Invoking magic command %s gave %d\n",
102                 p,ret));
103
104         unlink(fname);
105         if (ret != 0 || tmp_fd == -1) {
106                 if (tmp_fd != -1) {
107                         close(tmp_fd);
108                 }
109                 status = NT_STATUS_UNSUCCESSFUL;
110                 goto out;
111         }
112         outfd = open(magic_output, O_CREAT|O_EXCL|O_RDWR, 0600);
113         if (outfd == -1) {
114                 int err = errno;
115                 close(tmp_fd);
116                 status = map_nt_error_from_unix(err);
117                 goto out;
118         }
119
120         if (sys_fstat(tmp_fd, &st, false) == -1) {
121                 int err = errno;
122                 close(tmp_fd);
123                 close(outfd);
124                 status = map_nt_error_from_unix(err);
125                 goto out;
126         }
127
128         if (transfer_file(tmp_fd,outfd,(off_t)st.st_ex_size) == (off_t)-1) {
129                 int err = errno;
130                 close(tmp_fd);
131                 close(outfd);
132                 status = map_nt_error_from_unix(err);
133                 goto out;
134         }
135         close(tmp_fd);
136         if (close(outfd) == -1) {
137                 status = map_nt_error_from_unix(errno);
138                 goto out;
139         }
140
141         status = NT_STATUS_OK;
142
143  out:
144         TALLOC_FREE(ctx);
145         return status;
146 }
147
148 /****************************************************************************
149  Delete all streams
150 ****************************************************************************/
151
152 NTSTATUS delete_all_streams(connection_struct *conn,
153                         const struct smb_filename *smb_fname)
154 {
155         struct stream_struct *stream_info = NULL;
156         unsigned int i;
157         unsigned int num_streams = 0;
158         TALLOC_CTX *frame = talloc_stackframe();
159         NTSTATUS status;
160
161         status = vfs_fstreaminfo(smb_fname->fsp, talloc_tos(),
162                                 &num_streams, &stream_info);
163
164         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
165                 DEBUG(10, ("no streams around\n"));
166                 TALLOC_FREE(frame);
167                 return NT_STATUS_OK;
168         }
169
170         if (!NT_STATUS_IS_OK(status)) {
171                 DEBUG(10, ("vfs_fstreaminfo failed: %s\n",
172                            nt_errstr(status)));
173                 goto fail;
174         }
175
176         DEBUG(10, ("delete_all_streams found %d streams\n",
177                    num_streams));
178
179         if (num_streams == 0) {
180                 TALLOC_FREE(frame);
181                 return NT_STATUS_OK;
182         }
183
184         for (i=0; i<num_streams; i++) {
185                 int res;
186                 struct smb_filename *smb_fname_stream;
187
188                 if (strequal(stream_info[i].name, "::$DATA")) {
189                         continue;
190                 }
191
192                 status = synthetic_pathref(talloc_tos(),
193                                            conn->cwd_fsp,
194                                            smb_fname->base_name,
195                                            stream_info[i].name,
196                                            NULL,
197                                            smb_fname->twrp,
198                                            (smb_fname->flags &
199                                             ~SMB_FILENAME_POSIX_PATH),
200                                            &smb_fname_stream);
201                 if (!NT_STATUS_IS_OK(status)) {
202                         DEBUG(0, ("talloc_aprintf failed\n"));
203                         status = NT_STATUS_NO_MEMORY;
204                         goto fail;
205                 }
206
207                 res = SMB_VFS_UNLINKAT(conn,
208                                 conn->cwd_fsp,
209                                 smb_fname_stream,
210                                 0);
211
212                 if (res == -1) {
213                         status = map_nt_error_from_unix(errno);
214                         DEBUG(10, ("Could not delete stream %s: %s\n",
215                                    smb_fname_str_dbg(smb_fname_stream),
216                                    strerror(errno)));
217                         TALLOC_FREE(smb_fname_stream);
218                         break;
219                 }
220                 TALLOC_FREE(smb_fname_stream);
221         }
222
223  fail:
224         TALLOC_FREE(frame);
225         return status;
226 }
227
228 struct has_other_nonposix_opens_state {
229         files_struct *fsp;
230         bool found_another;
231 };
232
233 static bool has_other_nonposix_opens_fn(
234         struct share_mode_entry *e,
235         bool *modified,
236         void *private_data)
237 {
238         struct has_other_nonposix_opens_state *state = private_data;
239         struct files_struct *fsp = state->fsp;
240
241         if (e->name_hash != fsp->name_hash) {
242                 return false;
243         }
244         if ((fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) &&
245             (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) {
246                 return false;
247         }
248         if (e->share_file_id == fh_get_gen_id(fsp->fh)) {
249                 struct server_id self = messaging_server_id(
250                         fsp->conn->sconn->msg_ctx);
251                 if (server_id_equal(&self, &e->pid)) {
252                         return false;
253                 }
254         }
255         if (share_entry_stale_pid(e)) {
256                 return false;
257         }
258
259         state->found_another = true;
260         return true;
261 }
262
263 bool has_other_nonposix_opens(struct share_mode_lock *lck,
264                               struct files_struct *fsp)
265 {
266         struct has_other_nonposix_opens_state state = { .fsp = fsp };
267         bool ok;
268
269         ok = share_mode_forall_entries(
270                 lck, has_other_nonposix_opens_fn, &state);
271         if (!ok) {
272                 return false;
273         }
274         return state.found_another;
275 }
276
277 struct close_share_mode_lock_state {
278         struct share_mode_entry_prepare_state prepare_state;
279         const char *object_type;
280         struct files_struct *fsp;
281         enum file_close_type close_type;
282         bool delete_object;
283         bool got_tokens;
284         const struct security_unix_token *del_token;
285         const struct security_token *del_nt_token;
286         bool reset_delete_on_close;
287         share_mode_entry_prepare_unlock_fn_t cleanup_fn;
288 };
289
290 static void close_share_mode_lock_prepare(struct share_mode_lock *lck,
291                                           bool *keep_locked,
292                                           void *private_data)
293 {
294         struct close_share_mode_lock_state *state =
295                 (struct close_share_mode_lock_state *)private_data;
296         struct files_struct *fsp = state->fsp;
297         bool normal_close;
298         bool ok;
299
300         /*
301          * By default drop the g_lock again if we leave the
302          * tdb chainlock.
303          */
304         *keep_locked = false;
305
306         if (fsp->oplock_type != NO_OPLOCK) {
307                 ok = remove_share_oplock(lck, fsp);
308                 if (!ok) {
309                         struct file_id_buf buf;
310
311                         DBG_ERR("failed to remove share oplock for "
312                                 "%s %s, %s, %s\n",
313                                 state->object_type,
314                                 fsp_str_dbg(fsp), fsp_fnum_dbg(fsp),
315                                 file_id_str_buf(fsp->file_id, &buf));
316                 }
317         }
318
319         if (fsp->fsp_flags.write_time_forced) {
320                 NTTIME mtime = share_mode_changed_write_time(lck);
321                 struct timespec ts = nt_time_to_full_timespec(mtime);
322
323                 DBG_DEBUG("write time forced for %s %s\n",
324                           state->object_type, fsp_str_dbg(fsp));
325                 set_close_write_time(fsp, ts);
326         } else if (fsp->fsp_flags.update_write_time_on_close) {
327                 /* Someone had a pending write. */
328                 if (is_omit_timespec(&fsp->close_write_time)) {
329                         DBG_DEBUG("update to current time for %s %s\n",
330                                   state->object_type, fsp_str_dbg(fsp));
331                         /* Update to current time due to "normal" write. */
332                         set_close_write_time(fsp, timespec_current());
333                 } else {
334                         DBG_DEBUG("write time pending for %s %s\n",
335                                   state->object_type, fsp_str_dbg(fsp));
336                         /* Update to time set on close call. */
337                         set_close_write_time(fsp, fsp->close_write_time);
338                 }
339         }
340
341         if (fsp->fsp_flags.initial_delete_on_close &&
342                         !is_delete_on_close_set(lck, fsp->name_hash)) {
343                 /* Initial delete on close was set and no one else
344                  * wrote a real delete on close. */
345
346                 fsp->fsp_flags.delete_on_close = true;
347                 set_delete_on_close_lck(fsp, lck,
348                                         fsp->conn->session_info->security_token,
349                                         fsp->conn->session_info->unix_token);
350         }
351
352         state->delete_object = is_delete_on_close_set(lck, fsp->name_hash) &&
353                 !has_other_nonposix_opens(lck, fsp);
354
355         /*
356          * NT can set delete_on_close of the last open
357          * reference to a file.
358          */
359
360         normal_close = (state->close_type == NORMAL_CLOSE || state->close_type == SHUTDOWN_CLOSE);
361         if (!normal_close) {
362                 /*
363                  * Never try to delete the file/directory for ERROR_CLOSE
364                  */
365                 state->delete_object = false;
366         }
367
368         if (!state->delete_object) {
369                 ok = del_share_mode(lck, fsp);
370                 if (!ok) {
371                         DBG_ERR("Could not delete share entry for %s %s\n",
372                                 state->object_type, fsp_str_dbg(fsp));
373                 }
374                 return;
375         }
376
377         /*
378          * We're going to remove the file/directory
379          * so keep the g_lock after the tdb chainlock
380          * is left, so we hold the share_mode_lock
381          * also during the deletion
382          */
383         *keep_locked = true;
384
385         state->got_tokens = get_delete_on_close_token(lck, fsp->name_hash,
386                                         &state->del_nt_token, &state->del_token);
387         if (state->close_type != ERROR_CLOSE) {
388                 SMB_ASSERT(state->got_tokens);
389         }
390 }
391
392 static void close_share_mode_lock_cleanup(struct share_mode_lock *lck,
393                                           void *private_data)
394 {
395         struct close_share_mode_lock_state *state =
396                 (struct close_share_mode_lock_state *)private_data;
397         struct files_struct *fsp = state->fsp;
398         bool ok;
399
400         if (state->reset_delete_on_close) {
401                 reset_delete_on_close_lck(fsp, lck);
402         }
403
404         ok = del_share_mode(lck, fsp);
405         if (!ok) {
406                 DBG_ERR("Could not delete share entry for %s %s\n",
407                         state->object_type, fsp_str_dbg(fsp));
408         }
409 }
410
411 /****************************************************************************
412  Deal with removing a share mode on last close.
413 ****************************************************************************/
414
415 static NTSTATUS close_remove_share_mode(files_struct *fsp,
416                                         enum file_close_type close_type)
417 {
418         connection_struct *conn = fsp->conn;
419         struct close_share_mode_lock_state lck_state = {};
420         bool changed_user = false;
421         NTSTATUS status = NT_STATUS_OK;
422         NTSTATUS tmp_status;
423         NTSTATUS ulstatus;
424         struct file_id id;
425         struct smb_filename *parent_fname = NULL;
426         struct smb_filename *base_fname = NULL;
427         int ret;
428
429         /* Ensure any pending write time updates are done. */
430         if (fsp->update_write_time_event) {
431                 fsp_flush_write_time_update(fsp);
432         }
433
434         /*
435          * Lock the share entries, and determine if we should delete
436          * on close. If so delete whilst the lock is still in effect.
437          * This prevents race conditions with the file being created. JRA.
438          */
439
440         lck_state = (struct close_share_mode_lock_state) {
441                 .fsp                    = fsp,
442                 .object_type            = "file",
443                 .close_type             = close_type,
444         };
445
446         status = share_mode_entry_prepare_lock_del(&lck_state.prepare_state,
447                                                    fsp->file_id,
448                                                    close_share_mode_lock_prepare,
449                                                    &lck_state);
450         if (!NT_STATUS_IS_OK(status)) {
451                 DBG_ERR("share_mode_entry_prepare_lock_del() failed for %s - %s\n",
452                         fsp_str_dbg(fsp), nt_errstr(status));
453                 return status;
454         }
455
456         /* Remove the oplock before potentially deleting the file. */
457         if (fsp->oplock_type != NO_OPLOCK) {
458                 release_file_oplock(fsp);
459         }
460
461         /*
462          * NT can set delete_on_close of the last open
463          * reference to a file.
464          */
465
466         if (!lck_state.delete_object) {
467                 status = NT_STATUS_OK;
468                 goto done;
469         }
470
471         /*
472          * Ok, we have to delete the file
473          */
474         lck_state.cleanup_fn = close_share_mode_lock_cleanup;
475
476         DEBUG(5,("close_remove_share_mode: file %s. Delete on close was set "
477                  "- deleting file.\n", fsp_str_dbg(fsp)));
478
479         /*
480          * Don't try to update the write time when we delete the file
481          */
482         fsp->fsp_flags.update_write_time_on_close = false;
483
484         if (lck_state.got_tokens &&
485             !unix_token_equal(lck_state.del_token, get_current_utok(conn)))
486         {
487                 /* Become the user who requested the delete. */
488
489                 DEBUG(5,("close_remove_share_mode: file %s. "
490                         "Change user to uid %u\n",
491                         fsp_str_dbg(fsp),
492                         (unsigned int)lck_state.del_token->uid));
493
494                 if (!push_sec_ctx()) {
495                         smb_panic("close_remove_share_mode: file %s. failed to push "
496                                   "sec_ctx.\n");
497                 }
498
499                 set_sec_ctx(lck_state.del_token->uid,
500                             lck_state.del_token->gid,
501                             lck_state.del_token->ngroups,
502                             lck_state.del_token->groups,
503                             lck_state.del_nt_token);
504
505                 changed_user = true;
506         }
507
508         /* We can only delete the file if the name we have is still valid and
509            hasn't been renamed. */
510
511         tmp_status = vfs_stat_fsp(fsp);
512         if (!NT_STATUS_IS_OK(tmp_status)) {
513                 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
514                          "was set and stat failed with error %s\n",
515                          fsp_str_dbg(fsp), nt_errstr(tmp_status)));
516                 /*
517                  * Don't save the errno here, we ignore this error
518                  */
519                 goto done;
520         }
521
522         id = vfs_file_id_from_sbuf(conn, &fsp->fsp_name->st);
523
524         if (!file_id_equal(&fsp->file_id, &id)) {
525                 struct file_id_buf ftmp1, ftmp2;
526                 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
527                          "was set and dev and/or inode does not match\n",
528                          fsp_str_dbg(fsp)));
529                 DEBUG(5,("close_remove_share_mode: file %s. stored file_id %s, "
530                          "stat file_id %s\n",
531                          fsp_str_dbg(fsp),
532                          file_id_str_buf(fsp->file_id, &ftmp1),
533                          file_id_str_buf(id, &ftmp2)));
534                 /*
535                  * Don't save the errno here, we ignore this error
536                  */
537                 goto done;
538         }
539
540         if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
541             && !fsp_is_alternate_stream(fsp)) {
542
543                 status = delete_all_streams(conn, fsp->fsp_name);
544
545                 if (!NT_STATUS_IS_OK(status)) {
546                         DEBUG(5, ("delete_all_streams failed: %s\n",
547                                   nt_errstr(status)));
548                         goto done;
549                 }
550         }
551
552         if (fsp->fsp_flags.kernel_share_modes_taken) {
553                 /*
554                  * A file system sharemode could block the unlink;
555                  * remove filesystem sharemodes first.
556                  */
557                 ret = SMB_VFS_FILESYSTEM_SHAREMODE(fsp, 0, 0);
558                 if (ret == -1) {
559                         DBG_INFO("Removing file system sharemode for %s "
560                                  "failed: %s\n",
561                                  fsp_str_dbg(fsp), strerror(errno));
562                 }
563
564                 fsp->fsp_flags.kernel_share_modes_taken = false;
565         }
566
567         status = parent_pathref(talloc_tos(),
568                                 conn->cwd_fsp,
569                                 fsp->fsp_name,
570                                 &parent_fname,
571                                 &base_fname);
572         if (!NT_STATUS_IS_OK(status)) {
573                 goto done;
574         }
575
576         ret = SMB_VFS_UNLINKAT(conn,
577                                parent_fname->fsp,
578                                base_fname,
579                                0);
580         TALLOC_FREE(parent_fname);
581         base_fname = NULL;
582         if (ret != 0) {
583                 /*
584                  * This call can potentially fail as another smbd may
585                  * have had the file open with delete on close set and
586                  * deleted it when its last reference to this file
587                  * went away. Hence we log this but not at debug level
588                  * zero.
589                  */
590
591                 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
592                          "was set and unlink failed with error %s\n",
593                          fsp_str_dbg(fsp), strerror(errno)));
594
595                 status = map_nt_error_from_unix(errno);
596         }
597
598         /* As we now have POSIX opens which can unlink
599          * with other open files we may have taken
600          * this code path with more than one share mode
601          * entry - ensure we only delete once by resetting
602          * the delete on close flag. JRA.
603          */
604
605         fsp->fsp_flags.delete_on_close = false;
606         lck_state.reset_delete_on_close = true;
607
608  done:
609
610         if (changed_user) {
611                 /* unbecome user. */
612                 pop_sec_ctx();
613         }
614
615         if (fsp->fsp_flags.kernel_share_modes_taken) {
616                 /* remove filesystem sharemodes */
617                 ret = SMB_VFS_FILESYSTEM_SHAREMODE(fsp, 0, 0);
618                 if (ret == -1) {
619                         DBG_INFO("Removing file system sharemode for "
620                                  "%s failed: %s\n",
621                                  fsp_str_dbg(fsp), strerror(errno));
622                 }
623         }
624
625         ulstatus = share_mode_entry_prepare_unlock(&lck_state.prepare_state,
626                                                    lck_state.cleanup_fn,
627                                                    &lck_state);
628         if (!NT_STATUS_IS_OK(ulstatus)) {
629                 DBG_ERR("share_mode_entry_prepare_unlock() failed for %s - %s\n",
630                         fsp_str_dbg(fsp), nt_errstr(ulstatus));
631                 smb_panic("share_mode_entry_prepare_unlock() failed!");
632         }
633
634         if (lck_state.delete_object) {
635                 /*
636                  * Do the notification after we released the share
637                  * mode lock. Inside notify_fname we take out another
638                  * tdb lock. With ctdb also accessing our databases,
639                  * this can lead to deadlocks. Putting this notify
640                  * after the TALLOC_FREE(lck) above we avoid locking
641                  * two records simultaneously. Notifies are async and
642                  * informational only, so calling the notify_fname
643                  * without holding the share mode lock should not do
644                  * any harm.
645                  */
646                 notify_fname(conn, NOTIFY_ACTION_REMOVED,
647                              FILE_NOTIFY_CHANGE_FILE_NAME,
648                              fsp->fsp_name->base_name);
649         }
650
651         return status;
652 }
653
654 void set_close_write_time(struct files_struct *fsp, struct timespec ts)
655 {
656         DEBUG(6,("close_write_time: %s" , time_to_asc(convert_timespec_to_time_t(ts))));
657
658         if (is_omit_timespec(&ts)) {
659                 return;
660         }
661         fsp->fsp_flags.write_time_forced = false;
662         fsp->fsp_flags.update_write_time_on_close = true;
663         fsp->close_write_time = ts;
664 }
665
666 static void update_write_time_on_close_share_mode_fn(struct share_mode_lock *lck,
667                                                      void *private_data)
668 {
669         struct files_struct *fsp =
670                 talloc_get_type_abort(private_data,
671                 struct files_struct);
672         NTTIME share_mtime = share_mode_changed_write_time(lck);
673
674         /*
675          * On close if we're changing the real file time we
676          * must update it in the open file db too.
677          */
678         share_mode_set_old_write_time(lck, fsp->close_write_time);
679
680         /*
681          * Close write times overwrite sticky write times
682          * so we must replace any sticky write time here.
683          */
684         if (!null_nttime(share_mtime)) {
685                 share_mode_set_changed_write_time(lck, fsp->close_write_time);
686         }
687 }
688
689 static NTSTATUS update_write_time_on_close(struct files_struct *fsp)
690 {
691         struct smb_file_time ft;
692         NTSTATUS status;
693
694         init_smb_file_time(&ft);
695
696         if (!(fsp->fsp_flags.update_write_time_on_close)) {
697                 return NT_STATUS_OK;
698         }
699
700         if (is_omit_timespec(&fsp->close_write_time)) {
701                 fsp->close_write_time = timespec_current();
702         }
703
704         /* Ensure we have a valid stat struct for the source. */
705         status = vfs_stat_fsp(fsp);
706         if (!NT_STATUS_IS_OK(status)) {
707                 return status;
708         }
709
710         if (!VALID_STAT(fsp->fsp_name->st)) {
711                 /* if it doesn't seem to be a real file */
712                 return NT_STATUS_OK;
713         }
714
715         /*
716          * We're being called after close_remove_share_mode() inside
717          * close_normal_file() so it's quite normal to not have an
718          * existing share. So just ignore the result of
719          * share_mode_do_locked_vfs_denied()...
720          */
721         share_mode_do_locked_vfs_denied(fsp->file_id,
722                                         update_write_time_on_close_share_mode_fn,
723                                         fsp);
724
725         ft.mtime = fsp->close_write_time;
726         /* As this is a close based update, we are not directly changing the
727            file attributes from a client call, but indirectly from a write. */
728         status = smb_set_file_time(fsp->conn, fsp, fsp->fsp_name, &ft, false);
729         if (!NT_STATUS_IS_OK(status)) {
730                 DEBUG(10,("update_write_time_on_close: smb_set_file_time "
731                         "on file %s returned %s\n",
732                         fsp_str_dbg(fsp),
733                         nt_errstr(status)));
734                 return status;
735         }
736
737         return status;
738 }
739
740 static NTSTATUS ntstatus_keeperror(NTSTATUS s1, NTSTATUS s2)
741 {
742         if (!NT_STATUS_IS_OK(s1)) {
743                 return s1;
744         }
745         return s2;
746 }
747
748 static void assert_no_pending_aio(struct files_struct *fsp,
749                                   enum file_close_type close_type)
750 {
751         struct smbXsrv_client *client = global_smbXsrv_client;
752         size_t num_connections_alive;
753         unsigned num_requests = fsp->num_aio_requests;
754
755         if (num_requests == 0) {
756                 return;
757         }
758
759         num_connections_alive = smbXsrv_client_valid_connections(client);
760
761         if (close_type == SHUTDOWN_CLOSE && num_connections_alive == 0) {
762                 /*
763                  * fsp->aio_requests and the contents (fsp->aio_requests[x])
764                  * are both independently owned by fsp and are not in a
765                  * talloc heirarchy. This allows the fsp->aio_requests array to
766                  * be reallocated independently of the array contents so it can
767                  * grow on demand.
768                  *
769                  * This means we must ensure order of deallocation
770                  * on a SHUTDOWN_CLOSE by deallocating the fsp->aio_requests[x]
771                  * contents first, as their destructors access the
772                  * fsp->aio_request array. If we don't deallocate them
773                  * first, when fsp is deallocated fsp->aio_requests
774                  * could have been deallocated *before* its contents
775                  * fsp->aio_requests[x], causing a crash.
776                  */
777                 while (fsp->num_aio_requests != 0) {
778                         /*
779                          * NB. We *MUST* use
780                          * talloc_free(fsp->aio_requests[0]),
781                          * and *NOT* TALLOC_FREE() here, as
782                          * TALLOC_FREE(fsp->aio_requests[0])
783                          * will overwrite any new contents of
784                          * fsp->aio_requests[0] that were
785                          * copied into it via the destructor
786                          * aio_del_req_from_fsp().
787                          *
788                          * BUG: https://bugzilla.samba.org/show_bug.cgi?id=14515
789                          */
790                         talloc_free(fsp->aio_requests[0]);
791                 }
792                 return;
793         }
794
795         DBG_ERR("fsp->num_aio_requests=%u\n", num_requests);
796         smb_panic("can not close with outstanding aio requests");
797         return;
798 }
799
800 /****************************************************************************
801  Close a file.
802
803  close_type can be NORMAL_CLOSE=0,SHUTDOWN_CLOSE,ERROR_CLOSE.
804  printing and magic scripts are only run on normal close.
805  delete on close is done on normal and shutdown close.
806 ****************************************************************************/
807
808 static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp,
809                                   enum file_close_type close_type)
810 {
811         NTSTATUS status = NT_STATUS_OK;
812         NTSTATUS tmp;
813         connection_struct *conn = fsp->conn;
814         bool is_durable = false;
815
816         SMB_ASSERT(fsp->fsp_flags.is_fsa);
817
818         assert_no_pending_aio(fsp, close_type);
819
820         while (talloc_array_length(fsp->blocked_smb1_lock_reqs) != 0) {
821                 smbd_smb1_brl_finish_by_req(
822                         fsp->blocked_smb1_lock_reqs[0],
823                         NT_STATUS_RANGE_NOT_LOCKED);
824         }
825
826         /*
827          * If we're flushing on a close we can get a write
828          * error here, we must remember this.
829          */
830
831         if (NT_STATUS_IS_OK(status) && fsp->op != NULL) {
832                 is_durable = fsp->op->global->durable;
833         }
834
835         if (close_type != SHUTDOWN_CLOSE) {
836                 is_durable = false;
837         }
838
839         if (is_durable) {
840                 DATA_BLOB new_cookie = data_blob_null;
841
842                 tmp = SMB_VFS_DURABLE_DISCONNECT(fsp,
843                                         fsp->op->global->backend_cookie,
844                                         fsp->op,
845                                         &new_cookie);
846                 if (NT_STATUS_IS_OK(tmp)) {
847                         struct timeval tv;
848                         NTTIME now;
849
850                         if (req != NULL) {
851                                 tv = req->request_time;
852                         } else {
853                                 tv = timeval_current();
854                         }
855                         now = timeval_to_nttime(&tv);
856
857                         data_blob_free(&fsp->op->global->backend_cookie);
858                         fsp->op->global->backend_cookie = new_cookie;
859
860                         fsp->op->compat = NULL;
861                         tmp = smbXsrv_open_close(fsp->op, now);
862                         if (!NT_STATUS_IS_OK(tmp)) {
863                                 DEBUG(1, ("Failed to update smbXsrv_open "
864                                           "record when disconnecting durable "
865                                           "handle for file %s: %s - "
866                                           "proceeding with normal close\n",
867                                           fsp_str_dbg(fsp), nt_errstr(tmp)));
868                         }
869                         scavenger_schedule_disconnected(fsp);
870                 } else {
871                         DEBUG(1, ("Failed to disconnect durable handle for "
872                                   "file %s: %s - proceeding with normal "
873                                   "close\n", fsp_str_dbg(fsp), nt_errstr(tmp)));
874                 }
875                 if (!NT_STATUS_IS_OK(tmp)) {
876                         is_durable = false;
877                 }
878         }
879
880         if (is_durable) {
881                 /*
882                  * This is the case where we successfully disconnected
883                  * a durable handle and closed the underlying file.
884                  * In all other cases, we proceed with a genuine close.
885                  */
886                 DEBUG(10, ("%s disconnected durable handle for file %s\n",
887                            conn->session_info->unix_info->unix_name,
888                            fsp_str_dbg(fsp)));
889                 return NT_STATUS_OK;
890         }
891
892         if (fsp->op != NULL) {
893                 /*
894                  * Make sure the handle is not marked as durable anymore
895                  */
896                 fsp->op->global->durable = false;
897         }
898
899         /* If this is an old DOS or FCB open and we have multiple opens on
900            the same handle we only have one share mode. Ensure we only remove
901            the share mode on the last close. */
902
903         if (fh_get_refcount(fsp->fh) == 1) {
904                 /* Should we return on error here... ? */
905                 tmp = close_remove_share_mode(fsp, close_type);
906                 status = ntstatus_keeperror(status, tmp);
907         }
908
909         locking_close_file(fsp, close_type);
910
911         /*
912          * Ensure pending modtime is set before closing underlying fd.
913          */
914
915         tmp = update_write_time_on_close(fsp);
916         if (NT_STATUS_EQUAL(tmp, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
917                 /*
918                  * Someone renamed the file or a parent directory containing
919                  * this file. We can't do anything about this, eat the error.
920                  */
921                 tmp = NT_STATUS_OK;
922         }
923         status = ntstatus_keeperror(status, tmp);
924
925         tmp = fd_close(fsp);
926         status = ntstatus_keeperror(status, tmp);
927
928         /* check for magic scripts */
929         if (close_type == NORMAL_CLOSE) {
930                 tmp = check_magic(fsp);
931                 status = ntstatus_keeperror(status, tmp);
932         }
933
934         DEBUG(2,("%s closed file %s (numopen=%d) %s\n",
935                 conn->session_info->unix_info->unix_name, fsp_str_dbg(fsp),
936                 conn->num_files_open - 1,
937                 nt_errstr(status) ));
938
939         return status;
940 }
941 /****************************************************************************
942  Function used by reply_rmdir to delete an entire directory
943  tree recursively. Return True on ok, False on fail.
944 ****************************************************************************/
945
946 NTSTATUS recursive_rmdir(TALLOC_CTX *ctx,
947                      connection_struct *conn,
948                      struct smb_filename *smb_dname)
949 {
950         const char *dname = NULL;
951         char *talloced = NULL;
952         long offset = 0;
953         struct smb_Dir *dir_hnd = NULL;
954         struct files_struct *dirfsp = NULL;
955         int retval;
956         NTSTATUS status = NT_STATUS_OK;
957
958         SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
959
960         status = OpenDir(talloc_tos(),
961                          conn,
962                          smb_dname,
963                          NULL,
964                          0,
965                          &dir_hnd);
966         if (!NT_STATUS_IS_OK(status)) {
967                 return status;
968         }
969
970         dirfsp = dir_hnd_fetch_fsp(dir_hnd);
971
972         while ((dname = ReadDirName(dir_hnd, &offset, NULL, &talloced))) {
973                 struct smb_filename *atname = NULL;
974                 struct smb_filename *smb_dname_full = NULL;
975                 char *fullname = NULL;
976                 bool do_break = true;
977                 int unlink_flags = 0;
978
979                 if (ISDOT(dname) || ISDOTDOT(dname)) {
980                         TALLOC_FREE(talloced);
981                         continue;
982                 }
983
984                 /* Construct the full name. */
985                 fullname = talloc_asprintf(ctx,
986                                 "%s/%s",
987                                 smb_dname->base_name,
988                                 dname);
989                 if (!fullname) {
990                         status = NT_STATUS_NO_MEMORY;
991                         goto err_break;
992                 }
993
994                 smb_dname_full = synthetic_smb_fname(talloc_tos(),
995                                                 fullname,
996                                                 NULL,
997                                                 NULL,
998                                                 smb_dname->twrp,
999                                                 smb_dname->flags);
1000                 if (smb_dname_full == NULL) {
1001                         status = NT_STATUS_NO_MEMORY;
1002                         goto err_break;
1003                 }
1004
1005                 if (SMB_VFS_LSTAT(conn, smb_dname_full) != 0) {
1006                         status = map_nt_error_from_unix(errno);
1007                         goto err_break;
1008                 }
1009
1010                 if (smb_dname_full->st.st_ex_mode & S_IFDIR) {
1011                         status = recursive_rmdir(ctx, conn, smb_dname_full);
1012                         if (!NT_STATUS_IS_OK(status)) {
1013                                 goto err_break;
1014                         }
1015                         unlink_flags = AT_REMOVEDIR;
1016                 }
1017
1018                 status = synthetic_pathref(talloc_tos(),
1019                                            dirfsp,
1020                                            dname,
1021                                            NULL,
1022                                            &smb_dname_full->st,
1023                                            smb_dname_full->twrp,
1024                                            smb_dname_full->flags,
1025                                            &atname);
1026                 if (!NT_STATUS_IS_OK(status)) {
1027                         goto err_break;
1028                 }
1029
1030                 if (!is_visible_fsp(atname->fsp)) {
1031                         TALLOC_FREE(smb_dname_full);
1032                         TALLOC_FREE(fullname);
1033                         TALLOC_FREE(talloced);
1034                         TALLOC_FREE(atname);
1035                         continue;
1036                 }
1037
1038                 retval = SMB_VFS_UNLINKAT(conn,
1039                                           dirfsp,
1040                                           atname,
1041                                           unlink_flags);
1042                 if (retval != 0) {
1043                         status = map_nt_error_from_unix(errno);
1044                         goto err_break;
1045                 }
1046
1047                 /* Successful iteration. */
1048                 do_break = false;
1049
1050          err_break:
1051                 TALLOC_FREE(smb_dname_full);
1052                 TALLOC_FREE(fullname);
1053                 TALLOC_FREE(talloced);
1054                 TALLOC_FREE(atname);
1055                 if (do_break) {
1056                         break;
1057                 }
1058         }
1059         TALLOC_FREE(dir_hnd);
1060         return status;
1061 }
1062
1063 /****************************************************************************
1064  The internals of the rmdir code - called elsewhere.
1065 ****************************************************************************/
1066
1067 static NTSTATUS rmdir_internals(TALLOC_CTX *ctx, struct files_struct *fsp)
1068 {
1069         struct connection_struct *conn = fsp->conn;
1070         struct smb_filename *smb_dname = fsp->fsp_name;
1071         struct smb_filename *parent_fname = NULL;
1072         struct smb_filename *at_fname = NULL;
1073         const char *dname = NULL;
1074         char *talloced = NULL;
1075         long dirpos = 0;
1076         struct smb_Dir *dir_hnd = NULL;
1077         struct files_struct *dirfsp = NULL;
1078         int unlink_flags = 0;
1079         NTSTATUS status;
1080         int ret;
1081
1082         SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
1083
1084         status = parent_pathref(talloc_tos(),
1085                                 conn->cwd_fsp,
1086                                 fsp->fsp_name,
1087                                 &parent_fname,
1088                                 &at_fname);
1089         if (!NT_STATUS_IS_OK(status)) {
1090                 return status;
1091         }
1092
1093         /*
1094          * Todo: use SMB_VFS_STATX() once it's available.
1095          */
1096
1097         /* Might be a symlink. */
1098         ret = SMB_VFS_LSTAT(conn, smb_dname);
1099         if (ret != 0) {
1100                 TALLOC_FREE(parent_fname);
1101                 return map_nt_error_from_unix(errno);
1102         }
1103
1104         if (S_ISLNK(smb_dname->st.st_ex_mode)) {
1105                 /* Is what it points to a directory ? */
1106                 ret = SMB_VFS_STAT(conn, smb_dname);
1107                 if (ret != 0) {
1108                         TALLOC_FREE(parent_fname);
1109                         return map_nt_error_from_unix(errno);
1110                 }
1111                 if (!(S_ISDIR(smb_dname->st.st_ex_mode))) {
1112                         TALLOC_FREE(parent_fname);
1113                         return NT_STATUS_NOT_A_DIRECTORY;
1114                 }
1115         } else {
1116                 unlink_flags = AT_REMOVEDIR;
1117         }
1118
1119         ret = SMB_VFS_UNLINKAT(conn,
1120                                parent_fname->fsp,
1121                                at_fname,
1122                                unlink_flags);
1123         if (ret == 0) {
1124                 TALLOC_FREE(parent_fname);
1125                 notify_fname(conn, NOTIFY_ACTION_REMOVED,
1126                              FILE_NOTIFY_CHANGE_DIR_NAME,
1127                              smb_dname->base_name);
1128                 return NT_STATUS_OK;
1129         }
1130
1131         if (!((errno == ENOTEMPTY) || (errno == EEXIST))) {
1132                 DEBUG(3,("rmdir_internals: couldn't remove directory %s : "
1133                          "%s\n", smb_fname_str_dbg(smb_dname),
1134                          strerror(errno)));
1135                 TALLOC_FREE(parent_fname);
1136                 return map_nt_error_from_unix(errno);
1137         }
1138
1139         /*
1140          * Here we know the initial directory unlink failed with
1141          * ENOTEMPTY or EEXIST so we know there are objects within.
1142          * If we don't have permission to delete files non
1143          * visible to the client just fail the directory delete.
1144          */
1145
1146         if (!lp_delete_veto_files(SNUM(conn))) {
1147                 status = NT_STATUS_DIRECTORY_NOT_EMPTY;
1148                 goto err;
1149         }
1150
1151         /*
1152          * Check to see if the only thing in this directory are
1153          * files non-visible to the client. If not, fail the delete.
1154          */
1155
1156         status = OpenDir(talloc_tos(),
1157                          conn,
1158                          smb_dname,
1159                          NULL,
1160                          0,
1161                          &dir_hnd);
1162         if (!NT_STATUS_IS_OK(status)) {
1163                 /*
1164                  * Note, we deliberately squash the error here
1165                  * to avoid leaking information about what we
1166                  * can't delete.
1167                  */
1168                 status = NT_STATUS_DIRECTORY_NOT_EMPTY;
1169                 goto err;
1170         }
1171
1172         dirfsp = dir_hnd_fetch_fsp(dir_hnd);
1173
1174         while ((dname = ReadDirName(
1175                         dir_hnd, &dirpos, NULL, &talloced)) != NULL) {
1176                 struct smb_filename *smb_dname_full = NULL;
1177                 struct smb_filename *direntry_fname = NULL;
1178                 char *fullname = NULL;
1179                 int retval;
1180
1181                 if (ISDOT(dname) || ISDOTDOT(dname)) {
1182                         TALLOC_FREE(talloced);
1183                         continue;
1184                 }
1185                 if (IS_VETO_PATH(conn, dname)) {
1186                         TALLOC_FREE(talloced);
1187                         continue;
1188                 }
1189
1190                 fullname = talloc_asprintf(talloc_tos(),
1191                                            "%s/%s",
1192                                            smb_dname->base_name,
1193                                            dname);
1194
1195                 if (fullname == NULL) {
1196                         TALLOC_FREE(talloced);
1197                         status = NT_STATUS_NO_MEMORY;
1198                         goto err;
1199                 }
1200
1201                 smb_dname_full = synthetic_smb_fname(talloc_tos(),
1202                                                      fullname,
1203                                                      NULL,
1204                                                      NULL,
1205                                                      smb_dname->twrp,
1206                                                      smb_dname->flags);
1207                 if (smb_dname_full == NULL) {
1208                         TALLOC_FREE(talloced);
1209                         TALLOC_FREE(fullname);
1210                         status = NT_STATUS_NO_MEMORY;
1211                         goto err;
1212                 }
1213
1214                 retval = SMB_VFS_LSTAT(conn, smb_dname_full);
1215                 if (retval != 0) {
1216                         status = map_nt_error_from_unix(errno);
1217                         TALLOC_FREE(talloced);
1218                         TALLOC_FREE(fullname);
1219                         TALLOC_FREE(smb_dname_full);
1220                         goto err;
1221                 }
1222
1223                 if (S_ISLNK(smb_dname_full->st.st_ex_mode)) {
1224                         /* Could it be an msdfs link ? */
1225                         if (lp_host_msdfs() &&
1226                             lp_msdfs_root(SNUM(conn))) {
1227                                 struct smb_filename *smb_atname;
1228                                 smb_atname = synthetic_smb_fname(talloc_tos(),
1229                                                         dname,
1230                                                         NULL,
1231                                                         &smb_dname_full->st,
1232                                                         fsp->fsp_name->twrp,
1233                                                         fsp->fsp_name->flags);
1234                                 if (smb_atname == NULL) {
1235                                         TALLOC_FREE(talloced);
1236                                         TALLOC_FREE(fullname);
1237                                         TALLOC_FREE(smb_dname_full);
1238                                         status = NT_STATUS_NO_MEMORY;
1239                                         goto err;
1240                                 }
1241                                 if (is_msdfs_link(fsp, smb_atname)) {
1242                                         TALLOC_FREE(talloced);
1243                                         TALLOC_FREE(fullname);
1244                                         TALLOC_FREE(smb_dname_full);
1245                                         TALLOC_FREE(smb_atname);
1246                                         DBG_DEBUG("got msdfs link name %s "
1247                                                 "- can't delete directory %s\n",
1248                                                 dname,
1249                                                 fsp_str_dbg(fsp));
1250                                         status = NT_STATUS_DIRECTORY_NOT_EMPTY;
1251                                         goto err;
1252                                 }
1253                                 TALLOC_FREE(smb_atname);
1254                         }
1255
1256                         /* Not a DFS link - could it be a dangling symlink ? */
1257                         retval = SMB_VFS_STAT(conn, smb_dname_full);
1258                         if (retval == -1 && (errno == ENOENT || errno == ELOOP)) {
1259                                 /*
1260                                  * Dangling symlink.
1261                                  * Allow delete as "delete veto files = yes"
1262                                  */
1263                                 TALLOC_FREE(talloced);
1264                                 TALLOC_FREE(fullname);
1265                                 TALLOC_FREE(smb_dname_full);
1266                                 continue;
1267                         }
1268
1269                         DBG_DEBUG("got symlink name %s - "
1270                                 "can't delete directory %s\n",
1271                                 dname,
1272                                 fsp_str_dbg(fsp));
1273                         TALLOC_FREE(talloced);
1274                         TALLOC_FREE(fullname);
1275                         TALLOC_FREE(smb_dname_full);
1276                         status = NT_STATUS_DIRECTORY_NOT_EMPTY;
1277                         goto err;
1278                 }
1279
1280                 /* Not a symlink, get a pathref. */
1281                 status = synthetic_pathref(talloc_tos(),
1282                                            dirfsp,
1283                                            dname,
1284                                            NULL,
1285                                            &smb_dname_full->st,
1286                                            smb_dname->twrp,
1287                                            smb_dname->flags,
1288                                            &direntry_fname);
1289                 if (!NT_STATUS_IS_OK(status)) {
1290                         TALLOC_FREE(talloced);
1291                         TALLOC_FREE(fullname);
1292                         TALLOC_FREE(smb_dname_full);
1293                         goto err;
1294                 }
1295
1296                 if (!is_visible_fsp(direntry_fname->fsp)) {
1297                         TALLOC_FREE(talloced);
1298                         TALLOC_FREE(fullname);
1299                         TALLOC_FREE(smb_dname_full);
1300                         TALLOC_FREE(direntry_fname);
1301                         continue;
1302                 }
1303
1304                 /*
1305                  * We found a client visible name.
1306                  * We cannot delete this directory.
1307                  */
1308                 DBG_DEBUG("got name %s - "
1309                         "can't delete directory %s\n",
1310                         dname,
1311                         fsp_str_dbg(fsp));
1312                 TALLOC_FREE(talloced);
1313                 TALLOC_FREE(fullname);
1314                 TALLOC_FREE(smb_dname_full);
1315                 TALLOC_FREE(direntry_fname);
1316                 status = NT_STATUS_DIRECTORY_NOT_EMPTY;
1317                 goto err;
1318         }
1319
1320         /* Do a recursive delete. */
1321         RewindDir(dir_hnd,&dirpos);
1322
1323         while ((dname = ReadDirName(
1324                         dir_hnd, &dirpos, NULL, &talloced)) != NULL) {
1325                 struct smb_filename *direntry_fname = NULL;
1326                 struct smb_filename *smb_dname_full = NULL;
1327                 char *fullname = NULL;
1328                 bool do_break = true;
1329                 int retval;
1330
1331                 if (ISDOT(dname) || ISDOTDOT(dname)) {
1332                         TALLOC_FREE(talloced);
1333                         continue;
1334                 }
1335
1336                 fullname = talloc_asprintf(ctx,
1337                                            "%s/%s",
1338                                            smb_dname->base_name,
1339                                            dname);
1340
1341                 if (fullname == NULL) {
1342                         status = NT_STATUS_NO_MEMORY;
1343                         goto err_break;
1344                 }
1345
1346                 smb_dname_full = synthetic_smb_fname(talloc_tos(),
1347                                                      fullname,
1348                                                      NULL,
1349                                                      NULL,
1350                                                      smb_dname->twrp,
1351                                                      smb_dname->flags);
1352                 if (smb_dname_full == NULL) {
1353                         status = NT_STATUS_NO_MEMORY;
1354                         goto err_break;
1355                 }
1356
1357                 /*
1358                  * Todo: use SMB_VFS_STATX() once that's available.
1359                  */
1360
1361                 retval = SMB_VFS_LSTAT(conn, smb_dname_full);
1362                 if (retval != 0) {
1363                         status = map_nt_error_from_unix(errno);
1364                         goto err_break;
1365                 }
1366
1367                 /*
1368                  * We are only dealing with VETO'ed objects
1369                  * here. If it's a symlink, just delete the
1370                  * link without caring what it is pointing
1371                  * to.
1372                  */
1373                 if (S_ISLNK(smb_dname_full->st.st_ex_mode)) {
1374                         direntry_fname = synthetic_smb_fname(talloc_tos(),
1375                                                         dname,
1376                                                         NULL,
1377                                                         &smb_dname_full->st,
1378                                                         smb_dname->twrp,
1379                                                         smb_dname->flags);
1380                         if (direntry_fname == NULL) {
1381                                 status = NT_STATUS_NO_MEMORY;
1382                                 goto err_break;
1383                         }
1384                 } else {
1385                         status = synthetic_pathref(talloc_tos(),
1386                                                    dirfsp,
1387                                                    dname,
1388                                                    NULL,
1389                                                    &smb_dname_full->st,
1390                                                    smb_dname->twrp,
1391                                                    smb_dname->flags,
1392                                                    &direntry_fname);
1393                         if (!NT_STATUS_IS_OK(status)) {
1394                                 goto err_break;
1395                         }
1396
1397                         if (!is_visible_fsp(direntry_fname->fsp)) {
1398                                 TALLOC_FREE(fullname);
1399                                 TALLOC_FREE(smb_dname_full);
1400                                 TALLOC_FREE(talloced);
1401                                 TALLOC_FREE(direntry_fname);
1402                                 continue;
1403                         }
1404                 }
1405
1406                 unlink_flags = 0;
1407
1408                 if (smb_dname_full->st.st_ex_mode & S_IFDIR) {
1409                         status = recursive_rmdir(ctx, conn, smb_dname_full);
1410                         if (!NT_STATUS_IS_OK(status)) {
1411                                 goto err_break;
1412                         }
1413                         unlink_flags = AT_REMOVEDIR;
1414                 }
1415
1416                 retval = SMB_VFS_UNLINKAT(conn,
1417                                           dirfsp,
1418                                           direntry_fname,
1419                                           unlink_flags);
1420                 if (retval != 0) {
1421                         status = map_nt_error_from_unix(errno);
1422                         goto err_break;
1423                 }
1424
1425                 /* Successful iteration. */
1426                 do_break = false;
1427
1428         err_break:
1429                 TALLOC_FREE(fullname);
1430                 TALLOC_FREE(smb_dname_full);
1431                 TALLOC_FREE(talloced);
1432                 TALLOC_FREE(direntry_fname);
1433                 if (do_break) {
1434                         break;
1435                 }
1436         }
1437
1438         /* If we get here, we know NT_STATUS_IS_OK(status) */
1439         SMB_ASSERT(NT_STATUS_IS_OK(status));
1440
1441         /* Retry the rmdir */
1442         ret = SMB_VFS_UNLINKAT(conn,
1443                                parent_fname->fsp,
1444                                at_fname,
1445                                AT_REMOVEDIR);
1446         if (ret != 0) {
1447                 status = map_nt_error_from_unix(errno);
1448         }
1449
1450   err:
1451
1452         TALLOC_FREE(dir_hnd);
1453         TALLOC_FREE(parent_fname);
1454
1455         if (!NT_STATUS_IS_OK(status)) {
1456                 DBG_NOTICE("couldn't remove directory %s : "
1457                          "%s\n", smb_fname_str_dbg(smb_dname),
1458                          nt_errstr(status));
1459                 return status;
1460         }
1461
1462         notify_fname(conn, NOTIFY_ACTION_REMOVED,
1463                      FILE_NOTIFY_CHANGE_DIR_NAME,
1464                      smb_dname->base_name);
1465
1466         return status;
1467 }
1468
1469 /****************************************************************************
1470  Close a directory opened by an NT SMB call. 
1471 ****************************************************************************/
1472   
1473 static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
1474                                 enum file_close_type close_type)
1475 {
1476         connection_struct *conn = fsp->conn;
1477         struct close_share_mode_lock_state lck_state = {};
1478         bool changed_user = false;
1479         NTSTATUS status = NT_STATUS_OK;
1480         NTSTATUS status1 = NT_STATUS_OK;
1481         NTSTATUS notify_status;
1482         NTSTATUS ulstatus;
1483
1484         SMB_ASSERT(fsp->fsp_flags.is_fsa);
1485
1486         if (fsp->conn->sconn->using_smb2) {
1487                 notify_status = NT_STATUS_NOTIFY_CLEANUP;
1488         } else {
1489                 notify_status = NT_STATUS_OK;
1490         }
1491
1492         assert_no_pending_aio(fsp, close_type);
1493
1494         /*
1495          * NT can set delete_on_close of the last open
1496          * reference to a directory also.
1497          */
1498
1499         lck_state = (struct close_share_mode_lock_state) {
1500                 .fsp                    = fsp,
1501                 .object_type            = "directory",
1502                 .close_type             = close_type,
1503         };
1504
1505         status = share_mode_entry_prepare_lock_del(&lck_state.prepare_state,
1506                                                    fsp->file_id,
1507                                                    close_share_mode_lock_prepare,
1508                                                    &lck_state);
1509         if (!NT_STATUS_IS_OK(status)) {
1510                 DBG_ERR("share_mode_entry_prepare_lock_del() failed for %s - %s\n",
1511                         fsp_str_dbg(fsp), nt_errstr(status));
1512                 return status;
1513         }
1514
1515         /*
1516          * We don't have directory leases yet, so assert it in order
1517          * to skip release_file_oplock().
1518          */
1519         SMB_ASSERT(fsp->oplock_type == NO_OPLOCK);
1520
1521         /*
1522          * NT can set delete_on_close of the last open
1523          * reference to a file.
1524          */
1525
1526         if (!lck_state.delete_object) {
1527                 status = NT_STATUS_OK;
1528                 goto done;
1529         }
1530
1531         /*
1532          * Ok, we have to delete the directory
1533          */
1534         lck_state.cleanup_fn = close_share_mode_lock_cleanup;
1535
1536         if (lck_state.got_tokens &&
1537             !unix_token_equal(lck_state.del_token, get_current_utok(conn)))
1538         {
1539                 /* Become the user who requested the delete. */
1540
1541                 DBG_INFO("dir %s. Change user to uid %u\n",
1542                          fsp_str_dbg(fsp),
1543                          (unsigned int)lck_state.del_token->uid);
1544
1545                 if (!push_sec_ctx()) {
1546                         smb_panic("close_directory: failed to push sec_ctx.\n");
1547                 }
1548
1549                 set_sec_ctx(lck_state.del_token->uid,
1550                             lck_state.del_token->gid,
1551                             lck_state.del_token->ngroups,
1552                             lck_state.del_token->groups,
1553                             lck_state.del_nt_token);
1554
1555                 changed_user = true;
1556         }
1557
1558         if ((fsp->conn->fs_capabilities & FILE_NAMED_STREAMS)
1559             && !is_ntfs_stream_smb_fname(fsp->fsp_name)) {
1560
1561                 status = delete_all_streams(fsp->conn, fsp->fsp_name);
1562                 if (!NT_STATUS_IS_OK(status)) {
1563                         DEBUG(5, ("delete_all_streams failed: %s\n",
1564                                   nt_errstr(status)));
1565                         goto done;
1566                 }
1567         }
1568
1569         status = rmdir_internals(talloc_tos(), fsp);
1570
1571         DEBUG(5,("close_directory: %s. Delete on close was set - "
1572                  "deleting directory returned %s.\n",
1573                  fsp_str_dbg(fsp), nt_errstr(status)));
1574
1575         /*
1576          * Ensure we remove any change notify requests that would
1577          * now fail as the directory has been deleted.
1578          */
1579
1580         if (NT_STATUS_IS_OK(status)) {
1581                 notify_status = NT_STATUS_DELETE_PENDING;
1582         }
1583
1584 done:
1585         if (changed_user) {
1586                 /* unbecome user. */
1587                 pop_sec_ctx();
1588         }
1589
1590         ulstatus = share_mode_entry_prepare_unlock(&lck_state.prepare_state,
1591                                                    lck_state.cleanup_fn,
1592                                                    &lck_state);
1593         if (!NT_STATUS_IS_OK(ulstatus)) {
1594                 DBG_ERR("share_mode_entry_prepare_unlock() failed for %s - %s\n",
1595                         fsp_str_dbg(fsp), nt_errstr(ulstatus));
1596                 smb_panic("share_mode_entry_prepare_unlock() failed!");
1597         }
1598
1599         remove_pending_change_notify_requests_by_fid(fsp, notify_status);
1600
1601         status1 = fd_close(fsp);
1602
1603         if (!NT_STATUS_IS_OK(status1)) {
1604                 DEBUG(0, ("Could not close dir! fname=%s, fd=%d, err=%d=%s\n",
1605                           fsp_str_dbg(fsp), fsp_get_pathref_fd(fsp), errno,
1606                           strerror(errno)));
1607         }
1608
1609         if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(status1)) {
1610                 status = status1;
1611         }
1612         return status;
1613 }
1614
1615 /****************************************************************************
1616  Rundown all SMB-related dependencies of a files struct
1617 ****************************************************************************/
1618   
1619 NTSTATUS close_file_smb(struct smb_request *req,
1620                         struct files_struct *fsp,
1621                         enum file_close_type close_type)
1622 {
1623         NTSTATUS status;
1624
1625         /*
1626          * This fsp can never be an internal dirfsp. They must
1627          * be explicitly closed by TALLOC_FREE of the dir handle.
1628          */
1629         SMB_ASSERT(!fsp->fsp_flags.is_dirfsp);
1630
1631         /*
1632          * Never call directly on a base fsp
1633          */
1634         SMB_ASSERT(fsp->stream_fsp == NULL);
1635
1636         if (fsp->fake_file_handle != NULL) {
1637                 status = close_fake_file(req, fsp);
1638         } else if (fsp->print_file != NULL) {
1639                 /* FIXME: return spool errors */
1640                 print_spool_end(fsp, close_type);
1641                 fd_close(fsp);
1642                 status = NT_STATUS_OK;
1643         } else if (!fsp->fsp_flags.is_fsa) {
1644                 if (close_type == NORMAL_CLOSE) {
1645                         DBG_ERR("unexpected NORMAL_CLOSE for [%s] "
1646                                 "is_fsa[%u] is_pathref[%u] is_directory[%u]\n",
1647                                 fsp_str_dbg(fsp),
1648                                 fsp->fsp_flags.is_fsa,
1649                                 fsp->fsp_flags.is_pathref,
1650                                 fsp->fsp_flags.is_directory);
1651                 }
1652                 SMB_ASSERT(close_type != NORMAL_CLOSE);
1653                 fd_close(fsp);
1654                 status = NT_STATUS_OK;
1655         } else if (fsp->fsp_flags.is_directory) {
1656                 status = close_directory(req, fsp, close_type);
1657         } else {
1658                 status = close_normal_file(req, fsp, close_type);
1659         }
1660
1661         if (fsp_is_alternate_stream(fsp)) {
1662                 /*
1663                  * fsp was a stream, its base_fsp can't be a stream
1664                  * as well
1665                  */
1666                 SMB_ASSERT(!fsp_is_alternate_stream(fsp->base_fsp));
1667
1668                 /*
1669                  * There's a 1:1 relationship between fsp and a base_fsp
1670                  */
1671                 SMB_ASSERT(fsp->base_fsp->stream_fsp == fsp);
1672
1673                 /*
1674                  * Make base_fsp look standalone now
1675                  */
1676                 fsp->base_fsp->stream_fsp = NULL;
1677
1678                 close_file_free(req, &fsp->base_fsp, close_type);
1679         }
1680
1681         fsp_unbind_smb(req, fsp);
1682
1683         return status;
1684 }
1685
1686 NTSTATUS close_file_free(struct smb_request *req,
1687                          struct files_struct **_fsp,
1688                          enum file_close_type close_type)
1689 {
1690         struct files_struct *fsp = *_fsp;
1691         NTSTATUS status;
1692
1693         status = close_file_smb(req, fsp, close_type);
1694
1695         file_free(req, fsp);
1696         *_fsp = NULL;
1697
1698         return status;
1699 }
1700
1701 /****************************************************************************
1702  Deal with an (authorized) message to close a file given the share mode
1703  entry.
1704 ****************************************************************************/
1705
1706 void msg_close_file(struct messaging_context *msg_ctx,
1707                         void *private_data,
1708                         uint32_t msg_type,
1709                         struct server_id server_id,
1710                         DATA_BLOB *data)
1711 {
1712         files_struct *fsp = NULL;
1713         struct file_id id;
1714         struct share_mode_entry e;
1715         struct smbd_server_connection *sconn =
1716                 talloc_get_type_abort(private_data,
1717                 struct smbd_server_connection);
1718
1719         message_to_share_mode_entry(&id, &e, (char *)data->data);
1720
1721         if(DEBUGLVL(10)) {
1722                 char *sm_str = share_mode_str(NULL, 0, &id, &e);
1723                 if (!sm_str) {
1724                         smb_panic("talloc failed");
1725                 }
1726                 DEBUG(10,("msg_close_file: got request to close share mode "
1727                         "entry %s\n", sm_str));
1728                 TALLOC_FREE(sm_str);
1729         }
1730
1731         fsp = file_find_dif(sconn, id, e.share_file_id);
1732         if (!fsp) {
1733                 DEBUG(10,("msg_close_file: failed to find file.\n"));
1734                 return;
1735         }
1736         close_file_free(NULL, &fsp, NORMAL_CLOSE);
1737 }