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