smbd: add twrp arg to synthetic_smb_fname()
[amitay/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 "smbd/smbd.h"
27 #include "smbd/globals.h"
28 #include "smbd/scavenger.h"
29 #include "fake_file.h"
30 #include "transfer_file.h"
31 #include "auth.h"
32 #include "messages.h"
33 #include "../librpc/gen_ndr/open_files.h"
34 #include "lib/util/tevent_ntstatus.h"
35
36 /****************************************************************************
37  Run a file if it is a magic script.
38 ****************************************************************************/
39
40 static NTSTATUS check_magic(struct files_struct *fsp)
41 {
42         int ret;
43         const struct loadparm_substitution *lp_sub =
44                 loadparm_s3_global_substitution();
45         const char *magic_output = NULL;
46         SMB_STRUCT_STAT st;
47         int tmp_fd, outfd;
48         TALLOC_CTX *ctx = NULL;
49         const char *p;
50         struct connection_struct *conn = fsp->conn;
51         char *fname = NULL;
52         NTSTATUS status;
53
54         if (!*lp_magic_script(talloc_tos(), lp_sub, SNUM(conn))) {
55                 return NT_STATUS_OK;
56         }
57
58         DEBUG(5,("checking magic for %s\n", fsp_str_dbg(fsp)));
59
60         ctx = talloc_stackframe();
61
62         fname = fsp->fsp_name->base_name;
63
64         if (!(p = strrchr_m(fname,'/'))) {
65                 p = fname;
66         } else {
67                 p++;
68         }
69
70         if (!strequal(lp_magic_script(talloc_tos(), lp_sub, SNUM(conn)),p)) {
71                 status = NT_STATUS_OK;
72                 goto out;
73         }
74
75         if (*lp_magic_output(talloc_tos(), lp_sub, SNUM(conn))) {
76                 magic_output = lp_magic_output(talloc_tos(), lp_sub, SNUM(conn));
77         } else {
78                 magic_output = talloc_asprintf(ctx,
79                                 "%s.out",
80                                 fname);
81         }
82         if (!magic_output) {
83                 status = NT_STATUS_NO_MEMORY;
84                 goto out;
85         }
86
87         /* Ensure we don't depend on user's PATH. */
88         p = talloc_asprintf(ctx, "./%s", fname);
89         if (!p) {
90                 status = NT_STATUS_NO_MEMORY;
91                 goto out;
92         }
93
94         if (chmod(fname, 0755) == -1) {
95                 status = map_nt_error_from_unix(errno);
96                 goto out;
97         }
98         ret = smbrun(p, &tmp_fd, NULL);
99         DEBUG(3,("Invoking magic command %s gave %d\n",
100                 p,ret));
101
102         unlink(fname);
103         if (ret != 0 || tmp_fd == -1) {
104                 if (tmp_fd != -1) {
105                         close(tmp_fd);
106                 }
107                 status = NT_STATUS_UNSUCCESSFUL;
108                 goto out;
109         }
110         outfd = open(magic_output, O_CREAT|O_EXCL|O_RDWR, 0600);
111         if (outfd == -1) {
112                 int err = errno;
113                 close(tmp_fd);
114                 status = map_nt_error_from_unix(err);
115                 goto out;
116         }
117
118         if (sys_fstat(tmp_fd, &st, false) == -1) {
119                 int err = errno;
120                 close(tmp_fd);
121                 close(outfd);
122                 status = map_nt_error_from_unix(err);
123                 goto out;
124         }
125
126         if (transfer_file(tmp_fd,outfd,(off_t)st.st_ex_size) == (off_t)-1) {
127                 int err = errno;
128                 close(tmp_fd);
129                 close(outfd);
130                 status = map_nt_error_from_unix(err);
131                 goto out;
132         }
133         close(tmp_fd);
134         if (close(outfd) == -1) {
135                 status = map_nt_error_from_unix(errno);
136                 goto out;
137         }
138
139         status = NT_STATUS_OK;
140
141  out:
142         TALLOC_FREE(ctx);
143         return status;
144 }
145
146 /****************************************************************************
147  Delete all streams
148 ****************************************************************************/
149
150 NTSTATUS delete_all_streams(connection_struct *conn,
151                         const struct smb_filename *smb_fname)
152 {
153         struct stream_struct *stream_info = NULL;
154         unsigned int i;
155         unsigned int num_streams = 0;
156         TALLOC_CTX *frame = talloc_stackframe();
157         NTSTATUS status;
158
159         status = vfs_streaminfo(conn, NULL, smb_fname, talloc_tos(),
160                                 &num_streams, &stream_info);
161
162         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
163                 DEBUG(10, ("no streams around\n"));
164                 TALLOC_FREE(frame);
165                 return NT_STATUS_OK;
166         }
167
168         if (!NT_STATUS_IS_OK(status)) {
169                 DEBUG(10, ("vfs_streaminfo failed: %s\n",
170                            nt_errstr(status)));
171                 goto fail;
172         }
173
174         DEBUG(10, ("delete_all_streams found %d streams\n",
175                    num_streams));
176
177         if (num_streams == 0) {
178                 TALLOC_FREE(frame);
179                 return NT_STATUS_OK;
180         }
181
182         for (i=0; i<num_streams; i++) {
183                 int res;
184                 struct smb_filename *smb_fname_stream;
185
186                 if (strequal(stream_info[i].name, "::$DATA")) {
187                         continue;
188                 }
189
190                 smb_fname_stream = synthetic_smb_fname(talloc_tos(),
191                                         smb_fname->base_name,
192                                         stream_info[i].name,
193                                         NULL,
194                                         smb_fname->twrp,
195                                         (smb_fname->flags &
196                                                 ~SMB_FILENAME_POSIX_PATH));
197
198                 if (smb_fname_stream == NULL) {
199                         DEBUG(0, ("talloc_aprintf failed\n"));
200                         status = NT_STATUS_NO_MEMORY;
201                         goto fail;
202                 }
203
204                 res = SMB_VFS_UNLINKAT(conn,
205                                 conn->cwd_fsp,
206                                 smb_fname_stream,
207                                 0);
208
209                 if (res == -1) {
210                         status = map_nt_error_from_unix(errno);
211                         DEBUG(10, ("Could not delete stream %s: %s\n",
212                                    smb_fname_str_dbg(smb_fname_stream),
213                                    strerror(errno)));
214                         TALLOC_FREE(smb_fname_stream);
215                         break;
216                 }
217                 TALLOC_FREE(smb_fname_stream);
218         }
219
220  fail:
221         TALLOC_FREE(frame);
222         return status;
223 }
224
225 struct has_other_nonposix_opens_state {
226         files_struct *fsp;
227         bool found_another;
228 };
229
230 static bool has_other_nonposix_opens_fn(
231         struct share_mode_entry *e,
232         bool *modified,
233         void *private_data)
234 {
235         struct has_other_nonposix_opens_state *state = private_data;
236         struct files_struct *fsp = state->fsp;
237
238         if (e->name_hash != fsp->name_hash) {
239                 return false;
240         }
241         if ((fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) &&
242             (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) {
243                 return false;
244         }
245         if (e->share_file_id == fsp->fh->gen_id) {
246                 struct server_id self = messaging_server_id(
247                         fsp->conn->sconn->msg_ctx);
248                 if (server_id_equal(&self, &e->pid)) {
249                         return false;
250                 }
251         }
252         if (share_entry_stale_pid(e)) {
253                 return false;
254         }
255
256         state->found_another = true;
257         return true;
258 }
259
260 bool has_other_nonposix_opens(struct share_mode_lock *lck,
261                               struct files_struct *fsp)
262 {
263         struct has_other_nonposix_opens_state state = { .fsp = fsp };
264         bool ok;
265
266         ok = share_mode_forall_entries(
267                 lck, has_other_nonposix_opens_fn, &state);
268         if (!ok) {
269                 return false;
270         }
271         return state.found_another;
272 }
273
274 /****************************************************************************
275  Deal with removing a share mode on last close.
276 ****************************************************************************/
277
278 static NTSTATUS close_remove_share_mode(files_struct *fsp,
279                                         enum file_close_type close_type)
280 {
281         connection_struct *conn = fsp->conn;
282         bool delete_file = false;
283         bool changed_user = false;
284         struct share_mode_lock *lck = NULL;
285         NTSTATUS status = NT_STATUS_OK;
286         NTSTATUS tmp_status;
287         struct file_id id;
288         const struct security_unix_token *del_token = NULL;
289         const struct security_token *del_nt_token = NULL;
290         bool got_tokens = false;
291         bool normal_close;
292         int ret;
293
294         /* Ensure any pending write time updates are done. */
295         if (fsp->update_write_time_event) {
296                 fsp_flush_write_time_update(fsp);
297         }
298
299         /*
300          * Lock the share entries, and determine if we should delete
301          * on close. If so delete whilst the lock is still in effect.
302          * This prevents race conditions with the file being created. JRA.
303          */
304
305         lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
306         if (lck == NULL) {
307                 DEBUG(0, ("close_remove_share_mode: Could not get share mode "
308                           "lock for file %s\n", fsp_str_dbg(fsp)));
309                 return NT_STATUS_INVALID_PARAMETER;
310         }
311
312         /* Remove the oplock before potentially deleting the file. */
313         if(fsp->oplock_type) {
314                 remove_oplock(fsp);
315         }
316
317         if (fsp->fsp_flags.write_time_forced) {
318                 struct timespec ts;
319
320                 DEBUG(10,("close_remove_share_mode: write time forced "
321                         "for file %s\n",
322                         fsp_str_dbg(fsp)));
323                 ts = nt_time_to_full_timespec(lck->data->changed_write_time);
324                 set_close_write_time(fsp, ts);
325         } else if (fsp->fsp_flags.update_write_time_on_close) {
326                 /* Someone had a pending write. */
327                 if (is_omit_timespec(&fsp->close_write_time)) {
328                         DEBUG(10,("close_remove_share_mode: update to current time "
329                                 "for file %s\n",
330                                 fsp_str_dbg(fsp)));
331                         /* Update to current time due to "normal" write. */
332                         set_close_write_time(fsp, timespec_current());
333                 } else {
334                         DEBUG(10,("close_remove_share_mode: write time pending "
335                                 "for file %s\n",
336                                 fsp_str_dbg(fsp)));
337                         /* Update to time set on close call. */
338                         set_close_write_time(fsp, fsp->close_write_time);
339                 }
340         }
341
342         if (fsp->fsp_flags.initial_delete_on_close &&
343                         !is_delete_on_close_set(lck, fsp->name_hash)) {
344                 bool became_user = False;
345
346                 /* Initial delete on close was set and no one else
347                  * wrote a real delete on close. */
348
349                 if (get_current_vuid(conn) != fsp->vuid) {
350                         become_user_without_service(conn, fsp->vuid);
351                         became_user = True;
352                 }
353                 fsp->fsp_flags.delete_on_close = true;
354                 set_delete_on_close_lck(fsp, lck,
355                                 get_current_nttok(conn),
356                                 get_current_utok(conn));
357                 if (became_user) {
358                         unbecome_user_without_service();
359                 }
360         }
361
362         delete_file = is_delete_on_close_set(lck, fsp->name_hash) &&
363                 !has_other_nonposix_opens(lck, fsp);
364
365         /*
366          * NT can set delete_on_close of the last open
367          * reference to a file.
368          */
369
370         normal_close = (close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE);
371
372         if (!normal_close || !delete_file) {
373                 status = NT_STATUS_OK;
374                 goto done;
375         }
376
377         /*
378          * Ok, we have to delete the file
379          */
380
381         DEBUG(5,("close_remove_share_mode: file %s. Delete on close was set "
382                  "- deleting file.\n", fsp_str_dbg(fsp)));
383
384         /*
385          * Don't try to update the write time when we delete the file
386          */
387         fsp->fsp_flags.update_write_time_on_close = false;
388
389         got_tokens = get_delete_on_close_token(lck, fsp->name_hash,
390                                         &del_nt_token, &del_token);
391         SMB_ASSERT(got_tokens);
392
393         if (!unix_token_equal(del_token, get_current_utok(conn))) {
394                 /* Become the user who requested the delete. */
395
396                 DEBUG(5,("close_remove_share_mode: file %s. "
397                         "Change user to uid %u\n",
398                         fsp_str_dbg(fsp),
399                         (unsigned int)del_token->uid));
400
401                 if (!push_sec_ctx()) {
402                         smb_panic("close_remove_share_mode: file %s. failed to push "
403                                   "sec_ctx.\n");
404                 }
405
406                 set_sec_ctx(del_token->uid,
407                             del_token->gid,
408                             del_token->ngroups,
409                             del_token->groups,
410                             del_nt_token);
411
412                 changed_user = true;
413         }
414
415         /* We can only delete the file if the name we have is still valid and
416            hasn't been renamed. */
417
418         tmp_status = vfs_stat_fsp(fsp);
419         if (!NT_STATUS_IS_OK(tmp_status)) {
420                 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
421                          "was set and stat failed with error %s\n",
422                          fsp_str_dbg(fsp), nt_errstr(tmp_status)));
423                 /*
424                  * Don't save the errno here, we ignore this error
425                  */
426                 goto done;
427         }
428
429         id = vfs_file_id_from_sbuf(conn, &fsp->fsp_name->st);
430
431         if (!file_id_equal(&fsp->file_id, &id)) {
432                 struct file_id_buf ftmp1, ftmp2;
433                 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
434                          "was set and dev and/or inode does not match\n",
435                          fsp_str_dbg(fsp)));
436                 DEBUG(5,("close_remove_share_mode: file %s. stored file_id %s, "
437                          "stat file_id %s\n",
438                          fsp_str_dbg(fsp),
439                          file_id_str_buf(fsp->file_id, &ftmp1),
440                          file_id_str_buf(id, &ftmp2)));
441                 /*
442                  * Don't save the errno here, we ignore this error
443                  */
444                 goto done;
445         }
446
447         if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
448             && !is_ntfs_stream_smb_fname(fsp->fsp_name)) {
449
450                 status = delete_all_streams(conn, fsp->fsp_name);
451
452                 if (!NT_STATUS_IS_OK(status)) {
453                         DEBUG(5, ("delete_all_streams failed: %s\n",
454                                   nt_errstr(status)));
455                         goto done;
456                 }
457         }
458
459         if (fsp->fsp_flags.kernel_share_modes_taken) {
460                 int ret_flock;
461
462                 /*
463                  * A file system sharemode could block the unlink;
464                  * remove filesystem sharemodes first.
465                  */
466                 ret_flock = SMB_VFS_KERNEL_FLOCK(fsp, 0, 0);
467                 if (ret_flock == -1) {
468                         DBG_INFO("removing kernel flock for %s failed: %s\n",
469                                   fsp_str_dbg(fsp), strerror(errno));
470                 }
471
472                 fsp->fsp_flags.kernel_share_modes_taken = false;
473         }
474
475
476         ret = SMB_VFS_UNLINKAT(conn,
477                         conn->cwd_fsp,
478                         fsp->fsp_name,
479                         0);
480         if (ret != 0) {
481                 /*
482                  * This call can potentially fail as another smbd may
483                  * have had the file open with delete on close set and
484                  * deleted it when its last reference to this file
485                  * went away. Hence we log this but not at debug level
486                  * zero.
487                  */
488
489                 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
490                          "was set and unlink failed with error %s\n",
491                          fsp_str_dbg(fsp), strerror(errno)));
492
493                 status = map_nt_error_from_unix(errno);
494         }
495
496         /* As we now have POSIX opens which can unlink
497          * with other open files we may have taken
498          * this code path with more than one share mode
499          * entry - ensure we only delete once by resetting
500          * the delete on close flag. JRA.
501          */
502
503         fsp->fsp_flags.delete_on_close = false;
504         reset_delete_on_close_lck(fsp, lck);
505
506  done:
507
508         if (changed_user) {
509                 /* unbecome user. */
510                 pop_sec_ctx();
511         }
512
513         if (fsp->fsp_flags.kernel_share_modes_taken) {
514                 int ret_flock;
515
516                 /* remove filesystem sharemodes */
517                 ret_flock = SMB_VFS_KERNEL_FLOCK(fsp, 0, 0);
518                 if (ret_flock == -1) {
519                         DEBUG(2, ("close_remove_share_mode: removing kernel "
520                                   "flock for %s failed: %s\n",
521                                   fsp_str_dbg(fsp), strerror(errno)));
522                 }
523         }
524
525         if (!del_share_mode(lck, fsp)) {
526                 DEBUG(0, ("close_remove_share_mode: Could not delete share "
527                           "entry for file %s\n", fsp_str_dbg(fsp)));
528         }
529
530         TALLOC_FREE(lck);
531
532         if (delete_file) {
533                 /*
534                  * Do the notification after we released the share
535                  * mode lock. Inside notify_fname we take out another
536                  * tdb lock. With ctdb also accessing our databases,
537                  * this can lead to deadlocks. Putting this notify
538                  * after the TALLOC_FREE(lck) above we avoid locking
539                  * two records simultaneously. Notifies are async and
540                  * informational only, so calling the notify_fname
541                  * without holding the share mode lock should not do
542                  * any harm.
543                  */
544                 notify_fname(conn, NOTIFY_ACTION_REMOVED,
545                              FILE_NOTIFY_CHANGE_FILE_NAME,
546                              fsp->fsp_name->base_name);
547         }
548
549         return status;
550 }
551
552 void set_close_write_time(struct files_struct *fsp, struct timespec ts)
553 {
554         DEBUG(6,("close_write_time: %s" , time_to_asc(convert_timespec_to_time_t(ts))));
555
556         if (is_omit_timespec(&ts)) {
557                 return;
558         }
559         fsp->fsp_flags.write_time_forced = false;
560         fsp->fsp_flags.update_write_time_on_close = true;
561         fsp->close_write_time = ts;
562 }
563
564 static NTSTATUS update_write_time_on_close(struct files_struct *fsp)
565 {
566         struct smb_file_time ft;
567         NTSTATUS status;
568         struct share_mode_lock *lck = NULL;
569
570         init_smb_file_time(&ft);
571
572         if (!(fsp->fsp_flags.update_write_time_on_close)) {
573                 return NT_STATUS_OK;
574         }
575
576         if (is_omit_timespec(&fsp->close_write_time)) {
577                 fsp->close_write_time = timespec_current();
578         }
579
580         /* Ensure we have a valid stat struct for the source. */
581         status = vfs_stat_fsp(fsp);
582         if (!NT_STATUS_IS_OK(status)) {
583                 return status;
584         }
585
586         if (!VALID_STAT(fsp->fsp_name->st)) {
587                 /* if it doesn't seem to be a real file */
588                 return NT_STATUS_OK;
589         }
590
591         /*
592          * get_existing_share_mode_lock() isn't really the right
593          * call here, as we're being called after
594          * close_remove_share_mode() inside close_normal_file()
595          * so it's quite normal to not have an existing share
596          * mode here. However, get_share_mode_lock() doesn't
597          * work because that will create a new share mode if
598          * one doesn't exist - so stick with this call (just
599          * ignore any error we get if the share mode doesn't
600          * exist.
601          */
602
603         lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
604         if (lck) {
605                 /* On close if we're changing the real file time we
606                  * must update it in the open file db too. */
607                 (void)set_write_time(fsp->file_id, fsp->close_write_time);
608
609                 /* Close write times overwrite sticky write times
610                    so we must replace any sticky write time here. */
611                 if (!null_nttime(lck->data->changed_write_time)) {
612                         (void)set_sticky_write_time(fsp->file_id, fsp->close_write_time);
613                 }
614                 TALLOC_FREE(lck);
615         }
616
617         ft.mtime = fsp->close_write_time;
618         /* As this is a close based update, we are not directly changing the
619            file attributes from a client call, but indirectly from a write. */
620         status = smb_set_file_time(fsp->conn, fsp, fsp->fsp_name, &ft, false);
621         if (!NT_STATUS_IS_OK(status)) {
622                 DEBUG(10,("update_write_time_on_close: smb_set_file_time "
623                         "on file %s returned %s\n",
624                         fsp_str_dbg(fsp),
625                         nt_errstr(status)));
626                 return status;
627         }
628
629         return status;
630 }
631
632 static NTSTATUS ntstatus_keeperror(NTSTATUS s1, NTSTATUS s2)
633 {
634         if (!NT_STATUS_IS_OK(s1)) {
635                 return s1;
636         }
637         return s2;
638 }
639
640 static void assert_no_pending_aio(struct files_struct *fsp,
641                                   enum file_close_type close_type)
642 {
643         unsigned num_requests = fsp->num_aio_requests;
644
645         if (num_requests == 0) {
646                 return;
647         }
648
649         DBG_ERR("fsp->num_aio_requests=%u\n", num_requests);
650         smb_panic("can not close with outstanding aio requests");
651         return;
652 }
653
654 /****************************************************************************
655  Close a file.
656
657  close_type can be NORMAL_CLOSE=0,SHUTDOWN_CLOSE,ERROR_CLOSE.
658  printing and magic scripts are only run on normal close.
659  delete on close is done on normal and shutdown close.
660 ****************************************************************************/
661
662 static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp,
663                                   enum file_close_type close_type)
664 {
665         NTSTATUS status = NT_STATUS_OK;
666         NTSTATUS tmp;
667         connection_struct *conn = fsp->conn;
668         bool is_durable = false;
669
670         assert_no_pending_aio(fsp, close_type);
671
672         while (talloc_array_length(fsp->blocked_smb1_lock_reqs) != 0) {
673                 smbd_smb1_brl_finish_by_req(
674                         fsp->blocked_smb1_lock_reqs[0],
675                         NT_STATUS_RANGE_NOT_LOCKED);
676         }
677
678         /*
679          * If we're flushing on a close we can get a write
680          * error here, we must remember this.
681          */
682
683         if (NT_STATUS_IS_OK(status) && fsp->op != NULL) {
684                 is_durable = fsp->op->global->durable;
685         }
686
687         if (close_type != SHUTDOWN_CLOSE) {
688                 is_durable = false;
689         }
690
691         if (is_durable) {
692                 DATA_BLOB new_cookie = data_blob_null;
693
694                 tmp = SMB_VFS_DURABLE_DISCONNECT(fsp,
695                                         fsp->op->global->backend_cookie,
696                                         fsp->op,
697                                         &new_cookie);
698                 if (NT_STATUS_IS_OK(tmp)) {
699                         struct timeval tv;
700                         NTTIME now;
701
702                         if (req != NULL) {
703                                 tv = req->request_time;
704                         } else {
705                                 tv = timeval_current();
706                         }
707                         now = timeval_to_nttime(&tv);
708
709                         data_blob_free(&fsp->op->global->backend_cookie);
710                         fsp->op->global->backend_cookie = new_cookie;
711
712                         fsp->op->compat = NULL;
713                         tmp = smbXsrv_open_close(fsp->op, now);
714                         if (!NT_STATUS_IS_OK(tmp)) {
715                                 DEBUG(1, ("Failed to update smbXsrv_open "
716                                           "record when disconnecting durable "
717                                           "handle for file %s: %s - "
718                                           "proceeding with normal close\n",
719                                           fsp_str_dbg(fsp), nt_errstr(tmp)));
720                         }
721                         scavenger_schedule_disconnected(fsp);
722                 } else {
723                         DEBUG(1, ("Failed to disconnect durable handle for "
724                                   "file %s: %s - proceeding with normal "
725                                   "close\n", fsp_str_dbg(fsp), nt_errstr(tmp)));
726                 }
727                 if (!NT_STATUS_IS_OK(tmp)) {
728                         is_durable = false;
729                 }
730         }
731
732         if (is_durable) {
733                 /*
734                  * This is the case where we successfully disconnected
735                  * a durable handle and closed the underlying file.
736                  * In all other cases, we proceed with a genuine close.
737                  */
738                 DEBUG(10, ("%s disconnected durable handle for file %s\n",
739                            conn->session_info->unix_info->unix_name,
740                            fsp_str_dbg(fsp)));
741                 file_free(req, fsp);
742                 return NT_STATUS_OK;
743         }
744
745         if (fsp->op != NULL) {
746                 /*
747                  * Make sure the handle is not marked as durable anymore
748                  */
749                 fsp->op->global->durable = false;
750         }
751
752         if (fsp->print_file) {
753                 /* FIXME: return spool errors */
754                 print_spool_end(fsp, close_type);
755                 file_free(req, fsp);
756                 return NT_STATUS_OK;
757         }
758
759         /* If this is an old DOS or FCB open and we have multiple opens on
760            the same handle we only have one share mode. Ensure we only remove
761            the share mode on the last close. */
762
763         if (fsp->fh->ref_count == 1) {
764                 /* Should we return on error here... ? */
765                 tmp = close_remove_share_mode(fsp, close_type);
766                 status = ntstatus_keeperror(status, tmp);
767         }
768
769         locking_close_file(fsp, close_type);
770
771         tmp = fd_close(fsp);
772         status = ntstatus_keeperror(status, tmp);
773
774         /* check for magic scripts */
775         if (close_type == NORMAL_CLOSE) {
776                 tmp = check_magic(fsp);
777                 status = ntstatus_keeperror(status, tmp);
778         }
779
780         /*
781          * Ensure pending modtime is set after close.
782          */
783
784         tmp = update_write_time_on_close(fsp);
785         if (NT_STATUS_EQUAL(tmp, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
786                 /* Someone renamed the file or a parent directory containing
787                  * this file. We can't do anything about this, we don't have
788                  * an "update timestamp by fd" call in POSIX. Eat the error. */
789
790                 tmp = NT_STATUS_OK;
791         }
792
793         status = ntstatus_keeperror(status, tmp);
794
795         DEBUG(2,("%s closed file %s (numopen=%d) %s\n",
796                 conn->session_info->unix_info->unix_name, fsp_str_dbg(fsp),
797                 conn->num_files_open - 1,
798                 nt_errstr(status) ));
799
800         file_free(req, fsp);
801         return status;
802 }
803 /****************************************************************************
804  Function used by reply_rmdir to delete an entire directory
805  tree recursively. Return True on ok, False on fail.
806 ****************************************************************************/
807
808 bool recursive_rmdir(TALLOC_CTX *ctx,
809                      connection_struct *conn,
810                      struct smb_filename *smb_dname)
811 {
812         const char *dname = NULL;
813         char *talloced = NULL;
814         bool ret = True;
815         long offset = 0;
816         SMB_STRUCT_STAT st;
817         struct smb_Dir *dir_hnd;
818         int retval;
819
820         SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
821
822         dir_hnd = OpenDir(talloc_tos(), conn, smb_dname, NULL, 0);
823         if(dir_hnd == NULL)
824                 return False;
825
826         while((dname = ReadDirName(dir_hnd, &offset, &st, &talloced))) {
827                 struct smb_filename *smb_dname_full = NULL;
828                 char *fullname = NULL;
829                 bool do_break = true;
830
831                 if (ISDOT(dname) || ISDOTDOT(dname)) {
832                         TALLOC_FREE(talloced);
833                         continue;
834                 }
835
836                 if (!is_visible_file(conn,
837                                         dir_hnd,
838                                         dname,
839                                         &st,
840                                         false)) {
841                         TALLOC_FREE(talloced);
842                         continue;
843                 }
844
845                 /* Construct the full name. */
846                 fullname = talloc_asprintf(ctx,
847                                 "%s/%s",
848                                 smb_dname->base_name,
849                                 dname);
850                 if (!fullname) {
851                         errno = ENOMEM;
852                         goto err_break;
853                 }
854
855                 smb_dname_full = synthetic_smb_fname(talloc_tos(),
856                                                 fullname,
857                                                 NULL,
858                                                 NULL,
859                                                 smb_dname->twrp,
860                                                 smb_dname->flags);
861                 if (smb_dname_full == NULL) {
862                         errno = ENOMEM;
863                         goto err_break;
864                 }
865
866                 if(SMB_VFS_LSTAT(conn, smb_dname_full) != 0) {
867                         goto err_break;
868                 }
869
870                 if(smb_dname_full->st.st_ex_mode & S_IFDIR) {
871                         if(!recursive_rmdir(ctx, conn, smb_dname_full)) {
872                                 goto err_break;
873                         }
874                         retval = SMB_VFS_UNLINKAT(conn,
875                                         conn->cwd_fsp,
876                                         smb_dname_full,
877                                         AT_REMOVEDIR);
878                         if (retval != 0) {
879                                 goto err_break;
880                         }
881                 } else {
882                         retval = SMB_VFS_UNLINKAT(conn,
883                                         conn->cwd_fsp,
884                                         smb_dname_full,
885                                         0);
886                         if (retval != 0) {
887                                 goto err_break;
888                         }
889                 }
890
891                 /* Successful iteration. */
892                 do_break = false;
893
894          err_break:
895                 TALLOC_FREE(smb_dname_full);
896                 TALLOC_FREE(fullname);
897                 TALLOC_FREE(talloced);
898                 if (do_break) {
899                         ret = false;
900                         break;
901                 }
902         }
903         TALLOC_FREE(dir_hnd);
904         return ret;
905 }
906
907 /****************************************************************************
908  The internals of the rmdir code - called elsewhere.
909 ****************************************************************************/
910
911 static NTSTATUS rmdir_internals(TALLOC_CTX *ctx, files_struct *fsp)
912 {
913         connection_struct *conn = fsp->conn;
914         struct smb_filename *smb_dname = fsp->fsp_name;
915         const struct loadparm_substitution *lp_sub =
916                 loadparm_s3_global_substitution();
917         int ret;
918
919         SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
920
921         /* Might be a symlink. */
922         if(SMB_VFS_LSTAT(conn, smb_dname) != 0) {
923                 return map_nt_error_from_unix(errno);
924         }
925
926         if (S_ISLNK(smb_dname->st.st_ex_mode)) {
927                 /* Is what it points to a directory ? */
928                 if(SMB_VFS_STAT(conn, smb_dname) != 0) {
929                         return map_nt_error_from_unix(errno);
930                 }
931                 if (!(S_ISDIR(smb_dname->st.st_ex_mode))) {
932                         return NT_STATUS_NOT_A_DIRECTORY;
933                 }
934                 ret = SMB_VFS_UNLINKAT(conn,
935                                 conn->cwd_fsp,
936                                 smb_dname,
937                                 0);
938         } else {
939                 ret = SMB_VFS_UNLINKAT(conn,
940                                 conn->cwd_fsp,
941                                 smb_dname,
942                                 AT_REMOVEDIR);
943         }
944         if (ret == 0) {
945                 notify_fname(conn, NOTIFY_ACTION_REMOVED,
946                              FILE_NOTIFY_CHANGE_DIR_NAME,
947                              smb_dname->base_name);
948                 return NT_STATUS_OK;
949         }
950
951         if(((errno == ENOTEMPTY)||(errno == EEXIST)) && *lp_veto_files(talloc_tos(), lp_sub, SNUM(conn))) {
952                 /*
953                  * Check to see if the only thing in this directory are
954                  * vetoed files/directories. If so then delete them and
955                  * retry. If we fail to delete any of them (and we *don't*
956                  * do a recursive delete) then fail the rmdir.
957                  */
958                 SMB_STRUCT_STAT st;
959                 const char *dname = NULL;
960                 char *talloced = NULL;
961                 long dirpos = 0;
962                 struct smb_Dir *dir_hnd = OpenDir(talloc_tos(), conn,
963                                                   smb_dname, NULL,
964                                                   0);
965
966                 if(dir_hnd == NULL) {
967                         errno = ENOTEMPTY;
968                         goto err;
969                 }
970
971                 while ((dname = ReadDirName(dir_hnd, &dirpos, &st,
972                                             &talloced)) != NULL) {
973                         if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0)) {
974                                 TALLOC_FREE(talloced);
975                                 continue;
976                         }
977                         if (!is_visible_file(conn,
978                                                 dir_hnd,
979                                                 dname,
980                                                 &st,
981                                                 false)) {
982                                 TALLOC_FREE(talloced);
983                                 continue;
984                         }
985                         if(!IS_VETO_PATH(conn, dname)) {
986                                 TALLOC_FREE(dir_hnd);
987                                 TALLOC_FREE(talloced);
988                                 errno = ENOTEMPTY;
989                                 goto err;
990                         }
991                         TALLOC_FREE(talloced);
992                 }
993
994                 /* We only have veto files/directories.
995                  * Are we allowed to delete them ? */
996
997                 if(!lp_delete_veto_files(SNUM(conn))) {
998                         TALLOC_FREE(dir_hnd);
999                         errno = ENOTEMPTY;
1000                         goto err;
1001                 }
1002
1003                 /* Do a recursive delete. */
1004                 RewindDir(dir_hnd,&dirpos);
1005                 while ((dname = ReadDirName(dir_hnd, &dirpos, &st,
1006                                             &talloced)) != NULL) {
1007                         struct smb_filename *smb_dname_full = NULL;
1008                         char *fullname = NULL;
1009                         bool do_break = true;
1010
1011                         if (ISDOT(dname) || ISDOTDOT(dname)) {
1012                                 TALLOC_FREE(talloced);
1013                                 continue;
1014                         }
1015                         if (!is_visible_file(conn,
1016                                                 dir_hnd,
1017                                                 dname,
1018                                                 &st,
1019                                                 false)) {
1020                                 TALLOC_FREE(talloced);
1021                                 continue;
1022                         }
1023
1024                         fullname = talloc_asprintf(ctx,
1025                                         "%s/%s",
1026                                         smb_dname->base_name,
1027                                         dname);
1028
1029                         if(!fullname) {
1030                                 errno = ENOMEM;
1031                                 goto err_break;
1032                         }
1033
1034                         smb_dname_full = synthetic_smb_fname(talloc_tos(),
1035                                                         fullname,
1036                                                         NULL,
1037                                                         NULL,
1038                                                         smb_dname->twrp,
1039                                                         smb_dname->flags);
1040                         if (smb_dname_full == NULL) {
1041                                 errno = ENOMEM;
1042                                 goto err_break;
1043                         }
1044
1045                         if(SMB_VFS_LSTAT(conn, smb_dname_full) != 0) {
1046                                 goto err_break;
1047                         }
1048                         if(smb_dname_full->st.st_ex_mode & S_IFDIR) {
1049                                 int retval;
1050                                 if(!recursive_rmdir(ctx, conn,
1051                                                     smb_dname_full)) {
1052                                         goto err_break;
1053                                 }
1054                                 retval = SMB_VFS_UNLINKAT(conn,
1055                                                 conn->cwd_fsp,
1056                                                 smb_dname_full,
1057                                                 AT_REMOVEDIR);
1058                                 if(retval != 0) {
1059                                         goto err_break;
1060                                 }
1061                         } else {
1062                                 int retval = SMB_VFS_UNLINKAT(conn,
1063                                                 conn->cwd_fsp,
1064                                                 smb_dname_full,
1065                                                 0);
1066                                 if(retval != 0) {
1067                                         goto err_break;
1068                                 }
1069                         }
1070
1071                         /* Successful iteration. */
1072                         do_break = false;
1073
1074                  err_break:
1075                         TALLOC_FREE(fullname);
1076                         TALLOC_FREE(smb_dname_full);
1077                         TALLOC_FREE(talloced);
1078                         if (do_break)
1079                                 break;
1080                 }
1081                 TALLOC_FREE(dir_hnd);
1082                 /* Retry the rmdir */
1083                 ret = SMB_VFS_UNLINKAT(conn,
1084                                 conn->cwd_fsp,
1085                                 smb_dname,
1086                                 AT_REMOVEDIR);
1087         }
1088
1089   err:
1090
1091         if (ret != 0) {
1092                 DEBUG(3,("rmdir_internals: couldn't remove directory %s : "
1093                          "%s\n", smb_fname_str_dbg(smb_dname),
1094                          strerror(errno)));
1095                 return map_nt_error_from_unix(errno);
1096         }
1097
1098         notify_fname(conn, NOTIFY_ACTION_REMOVED,
1099                      FILE_NOTIFY_CHANGE_DIR_NAME,
1100                      smb_dname->base_name);
1101
1102         return NT_STATUS_OK;
1103 }
1104
1105 /****************************************************************************
1106  Close a directory opened by an NT SMB call. 
1107 ****************************************************************************/
1108   
1109 static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
1110                                 enum file_close_type close_type)
1111 {
1112         struct share_mode_lock *lck = NULL;
1113         bool delete_dir = False;
1114         NTSTATUS status = NT_STATUS_OK;
1115         NTSTATUS status1 = NT_STATUS_OK;
1116         const struct security_token *del_nt_token = NULL;
1117         const struct security_unix_token *del_token = NULL;
1118         NTSTATUS notify_status;
1119
1120         if (fsp->conn->sconn->using_smb2) {
1121                 notify_status = STATUS_NOTIFY_CLEANUP;
1122         } else {
1123                 notify_status = NT_STATUS_OK;
1124         }
1125
1126         assert_no_pending_aio(fsp, close_type);
1127
1128         /*
1129          * NT can set delete_on_close of the last open
1130          * reference to a directory also.
1131          */
1132
1133         lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
1134         if (lck == NULL) {
1135                 DEBUG(0, ("close_directory: Could not get share mode lock for "
1136                           "%s\n", fsp_str_dbg(fsp)));
1137                 file_free(req, fsp);
1138                 return NT_STATUS_INVALID_PARAMETER;
1139         }
1140
1141         if (fsp->fsp_flags.initial_delete_on_close) {
1142                 bool became_user = False;
1143
1144                 /* Initial delete on close was set - for
1145                  * directories we don't care if anyone else
1146                  * wrote a real delete on close. */
1147
1148                 if (get_current_vuid(fsp->conn) != fsp->vuid) {
1149                         become_user_without_service(fsp->conn, fsp->vuid);
1150                         became_user = True;
1151                 }
1152                 send_stat_cache_delete_message(fsp->conn->sconn->msg_ctx,
1153                                                fsp->fsp_name->base_name);
1154                 set_delete_on_close_lck(fsp, lck,
1155                                 get_current_nttok(fsp->conn),
1156                                 get_current_utok(fsp->conn));
1157                 fsp->fsp_flags.delete_on_close = true;
1158                 if (became_user) {
1159                         unbecome_user_without_service();
1160                 }
1161         }
1162
1163         delete_dir = get_delete_on_close_token(
1164                 lck, fsp->name_hash, &del_nt_token, &del_token) &&
1165                 !has_other_nonposix_opens(lck, fsp);
1166
1167         if ((close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) &&
1168                                 delete_dir) {
1169         
1170                 /* Become the user who requested the delete. */
1171
1172                 if (!push_sec_ctx()) {
1173                         smb_panic("close_directory: failed to push sec_ctx.\n");
1174                 }
1175
1176                 set_sec_ctx(del_token->uid,
1177                                 del_token->gid,
1178                                 del_token->ngroups,
1179                                 del_token->groups,
1180                                 del_nt_token);
1181
1182                 if (!del_share_mode(lck, fsp)) {
1183                         DEBUG(0, ("close_directory: Could not delete share entry for "
1184                                   "%s\n", fsp_str_dbg(fsp)));
1185                 }
1186
1187                 TALLOC_FREE(lck);
1188
1189                 if ((fsp->conn->fs_capabilities & FILE_NAMED_STREAMS)
1190                     && !is_ntfs_stream_smb_fname(fsp->fsp_name)) {
1191
1192                         status = delete_all_streams(fsp->conn, fsp->fsp_name);
1193                         if (!NT_STATUS_IS_OK(status)) {
1194                                 DEBUG(5, ("delete_all_streams failed: %s\n",
1195                                           nt_errstr(status)));
1196                                 file_free(req, fsp);
1197                                 return status;
1198                         }
1199                 }
1200
1201                 status = rmdir_internals(talloc_tos(), fsp);
1202
1203                 DEBUG(5,("close_directory: %s. Delete on close was set - "
1204                          "deleting directory returned %s.\n",
1205                          fsp_str_dbg(fsp), nt_errstr(status)));
1206
1207                 /* unbecome user. */
1208                 pop_sec_ctx();
1209
1210                 /*
1211                  * Ensure we remove any change notify requests that would
1212                  * now fail as the directory has been deleted.
1213                  */
1214
1215                 if (NT_STATUS_IS_OK(status)) {
1216                         notify_status = NT_STATUS_DELETE_PENDING;
1217                 }
1218         } else {
1219                 if (!del_share_mode(lck, fsp)) {
1220                         DEBUG(0, ("close_directory: Could not delete share entry for "
1221                                   "%s\n", fsp_str_dbg(fsp)));
1222                 }
1223
1224                 TALLOC_FREE(lck);
1225         }
1226
1227         remove_pending_change_notify_requests_by_fid(fsp, notify_status);
1228
1229         status1 = fd_close(fsp);
1230
1231         if (!NT_STATUS_IS_OK(status1)) {
1232                 DEBUG(0, ("Could not close dir! fname=%s, fd=%d, err=%d=%s\n",
1233                           fsp_str_dbg(fsp), fsp->fh->fd, errno,
1234                           strerror(errno)));
1235         }
1236
1237         /*
1238          * Do the code common to files and directories.
1239          */
1240         file_free(req, fsp);
1241
1242         if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(status1)) {
1243                 status = status1;
1244         }
1245         return status;
1246 }
1247
1248 /****************************************************************************
1249  Close a files_struct.
1250 ****************************************************************************/
1251   
1252 NTSTATUS close_file(struct smb_request *req, files_struct *fsp,
1253                     enum file_close_type close_type)
1254 {
1255         NTSTATUS status;
1256         struct files_struct *base_fsp = fsp->base_fsp;
1257
1258         if (fsp->fsp_flags.is_directory) {
1259                 status = close_directory(req, fsp, close_type);
1260         } else if (fsp->fake_file_handle != NULL) {
1261                 status = close_fake_file(req, fsp);
1262         } else {
1263                 status = close_normal_file(req, fsp, close_type);
1264         }
1265
1266         if ((base_fsp != NULL) && (close_type != SHUTDOWN_CLOSE)) {
1267
1268                 /*
1269                  * fsp was a stream, the base fsp can't be a stream as well
1270                  *
1271                  * For SHUTDOWN_CLOSE this is not possible here, because
1272                  * SHUTDOWN_CLOSE only happens from files.c which walks the
1273                  * complete list of files. If we mess with more than one fsp
1274                  * those loops will become confused.
1275                  */
1276
1277                 SMB_ASSERT(base_fsp->base_fsp == NULL);
1278                 close_file(req, base_fsp, close_type);
1279         }
1280
1281         return status;
1282 }
1283
1284 /****************************************************************************
1285  Deal with an (authorized) message to close a file given the share mode
1286  entry.
1287 ****************************************************************************/
1288
1289 void msg_close_file(struct messaging_context *msg_ctx,
1290                         void *private_data,
1291                         uint32_t msg_type,
1292                         struct server_id server_id,
1293                         DATA_BLOB *data)
1294 {
1295         files_struct *fsp = NULL;
1296         struct file_id id;
1297         struct share_mode_entry e;
1298         struct smbd_server_connection *sconn =
1299                 talloc_get_type_abort(private_data,
1300                 struct smbd_server_connection);
1301
1302         message_to_share_mode_entry(&id, &e, (char *)data->data);
1303
1304         if(DEBUGLVL(10)) {
1305                 char *sm_str = share_mode_str(NULL, 0, &id, &e);
1306                 if (!sm_str) {
1307                         smb_panic("talloc failed");
1308                 }
1309                 DEBUG(10,("msg_close_file: got request to close share mode "
1310                         "entry %s\n", sm_str));
1311                 TALLOC_FREE(sm_str);
1312         }
1313
1314         fsp = file_find_dif(sconn, id, e.share_file_id);
1315         if (!fsp) {
1316                 DEBUG(10,("msg_close_file: failed to find file.\n"));
1317                 return;
1318         }
1319         close_file(NULL, fsp, NORMAL_CLOSE);
1320 }