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