s3: smbd: Reformat calls to is_visible_file() to one arg per line.
[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->fsp_flags.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->fsp_flags.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,
836                                         smb_dname,
837                                         dname,
838                                         &st,
839                                         false)) {
840                         TALLOC_FREE(talloced);
841                         continue;
842                 }
843
844                 /* Construct the full name. */
845                 fullname = talloc_asprintf(ctx,
846                                 "%s/%s",
847                                 smb_dname->base_name,
848                                 dname);
849                 if (!fullname) {
850                         errno = ENOMEM;
851                         goto err_break;
852                 }
853
854                 smb_dname_full = synthetic_smb_fname(talloc_tos(),
855                                                 fullname,
856                                                 NULL,
857                                                 NULL,
858                                                 smb_dname->flags);
859                 if (smb_dname_full == NULL) {
860                         errno = ENOMEM;
861                         goto err_break;
862                 }
863
864                 if(SMB_VFS_LSTAT(conn, smb_dname_full) != 0) {
865                         goto err_break;
866                 }
867
868                 if(smb_dname_full->st.st_ex_mode & S_IFDIR) {
869                         if(!recursive_rmdir(ctx, conn, smb_dname_full)) {
870                                 goto err_break;
871                         }
872                         retval = SMB_VFS_UNLINKAT(conn,
873                                         conn->cwd_fsp,
874                                         smb_dname_full,
875                                         AT_REMOVEDIR);
876                         if (retval != 0) {
877                                 goto err_break;
878                         }
879                 } else {
880                         retval = SMB_VFS_UNLINKAT(conn,
881                                         conn->cwd_fsp,
882                                         smb_dname_full,
883                                         0);
884                         if (retval != 0) {
885                                 goto err_break;
886                         }
887                 }
888
889                 /* Successful iteration. */
890                 do_break = false;
891
892          err_break:
893                 TALLOC_FREE(smb_dname_full);
894                 TALLOC_FREE(fullname);
895                 TALLOC_FREE(talloced);
896                 if (do_break) {
897                         ret = false;
898                         break;
899                 }
900         }
901         TALLOC_FREE(dir_hnd);
902         return ret;
903 }
904
905 /****************************************************************************
906  The internals of the rmdir code - called elsewhere.
907 ****************************************************************************/
908
909 static NTSTATUS rmdir_internals(TALLOC_CTX *ctx, files_struct *fsp)
910 {
911         connection_struct *conn = fsp->conn;
912         struct smb_filename *smb_dname = fsp->fsp_name;
913         const struct loadparm_substitution *lp_sub =
914                 loadparm_s3_global_substitution();
915         int ret;
916
917         SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
918
919         /* Might be a symlink. */
920         if(SMB_VFS_LSTAT(conn, smb_dname) != 0) {
921                 return map_nt_error_from_unix(errno);
922         }
923
924         if (S_ISLNK(smb_dname->st.st_ex_mode)) {
925                 /* Is what it points to a directory ? */
926                 if(SMB_VFS_STAT(conn, smb_dname) != 0) {
927                         return map_nt_error_from_unix(errno);
928                 }
929                 if (!(S_ISDIR(smb_dname->st.st_ex_mode))) {
930                         return NT_STATUS_NOT_A_DIRECTORY;
931                 }
932                 ret = SMB_VFS_UNLINKAT(conn,
933                                 conn->cwd_fsp,
934                                 smb_dname,
935                                 0);
936         } else {
937                 ret = SMB_VFS_UNLINKAT(conn,
938                                 conn->cwd_fsp,
939                                 smb_dname,
940                                 AT_REMOVEDIR);
941         }
942         if (ret == 0) {
943                 notify_fname(conn, NOTIFY_ACTION_REMOVED,
944                              FILE_NOTIFY_CHANGE_DIR_NAME,
945                              smb_dname->base_name);
946                 return NT_STATUS_OK;
947         }
948
949         if(((errno == ENOTEMPTY)||(errno == EEXIST)) && *lp_veto_files(talloc_tos(), lp_sub, SNUM(conn))) {
950                 /*
951                  * Check to see if the only thing in this directory are
952                  * vetoed files/directories. If so then delete them and
953                  * retry. If we fail to delete any of them (and we *don't*
954                  * do a recursive delete) then fail the rmdir.
955                  */
956                 SMB_STRUCT_STAT st;
957                 const char *dname = NULL;
958                 char *talloced = NULL;
959                 long dirpos = 0;
960                 struct smb_Dir *dir_hnd = OpenDir(talloc_tos(), conn,
961                                                   smb_dname, NULL,
962                                                   0);
963
964                 if(dir_hnd == NULL) {
965                         errno = ENOTEMPTY;
966                         goto err;
967                 }
968
969                 while ((dname = ReadDirName(dir_hnd, &dirpos, &st,
970                                             &talloced)) != NULL) {
971                         if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0)) {
972                                 TALLOC_FREE(talloced);
973                                 continue;
974                         }
975                         if (!is_visible_file(conn,
976                                                 smb_dname,
977                                                 dname,
978                                                 &st,
979                                                 false)) {
980                                 TALLOC_FREE(talloced);
981                                 continue;
982                         }
983                         if(!IS_VETO_PATH(conn, dname)) {
984                                 TALLOC_FREE(dir_hnd);
985                                 TALLOC_FREE(talloced);
986                                 errno = ENOTEMPTY;
987                                 goto err;
988                         }
989                         TALLOC_FREE(talloced);
990                 }
991
992                 /* We only have veto files/directories.
993                  * Are we allowed to delete them ? */
994
995                 if(!lp_delete_veto_files(SNUM(conn))) {
996                         TALLOC_FREE(dir_hnd);
997                         errno = ENOTEMPTY;
998                         goto err;
999                 }
1000
1001                 /* Do a recursive delete. */
1002                 RewindDir(dir_hnd,&dirpos);
1003                 while ((dname = ReadDirName(dir_hnd, &dirpos, &st,
1004                                             &talloced)) != NULL) {
1005                         struct smb_filename *smb_dname_full = NULL;
1006                         char *fullname = NULL;
1007                         bool do_break = true;
1008
1009                         if (ISDOT(dname) || ISDOTDOT(dname)) {
1010                                 TALLOC_FREE(talloced);
1011                                 continue;
1012                         }
1013                         if (!is_visible_file(conn,
1014                                                 smb_dname,
1015                                                 dname,
1016                                                 &st,
1017                                                 false)) {
1018                                 TALLOC_FREE(talloced);
1019                                 continue;
1020                         }
1021
1022                         fullname = talloc_asprintf(ctx,
1023                                         "%s/%s",
1024                                         smb_dname->base_name,
1025                                         dname);
1026
1027                         if(!fullname) {
1028                                 errno = ENOMEM;
1029                                 goto err_break;
1030                         }
1031
1032                         smb_dname_full = synthetic_smb_fname(talloc_tos(),
1033                                                         fullname,
1034                                                         NULL,
1035                                                         NULL,
1036                                                         smb_dname->flags);
1037                         if (smb_dname_full == NULL) {
1038                                 errno = ENOMEM;
1039                                 goto err_break;
1040                         }
1041
1042                         if(SMB_VFS_LSTAT(conn, smb_dname_full) != 0) {
1043                                 goto err_break;
1044                         }
1045                         if(smb_dname_full->st.st_ex_mode & S_IFDIR) {
1046                                 int retval;
1047                                 if(!recursive_rmdir(ctx, conn,
1048                                                     smb_dname_full)) {
1049                                         goto err_break;
1050                                 }
1051                                 retval = SMB_VFS_UNLINKAT(conn,
1052                                                 conn->cwd_fsp,
1053                                                 smb_dname_full,
1054                                                 AT_REMOVEDIR);
1055                                 if(retval != 0) {
1056                                         goto err_break;
1057                                 }
1058                         } else {
1059                                 int retval = SMB_VFS_UNLINKAT(conn,
1060                                                 conn->cwd_fsp,
1061                                                 smb_dname_full,
1062                                                 0);
1063                                 if(retval != 0) {
1064                                         goto err_break;
1065                                 }
1066                         }
1067
1068                         /* Successful iteration. */
1069                         do_break = false;
1070
1071                  err_break:
1072                         TALLOC_FREE(fullname);
1073                         TALLOC_FREE(smb_dname_full);
1074                         TALLOC_FREE(talloced);
1075                         if (do_break)
1076                                 break;
1077                 }
1078                 TALLOC_FREE(dir_hnd);
1079                 /* Retry the rmdir */
1080                 ret = SMB_VFS_UNLINKAT(conn,
1081                                 conn->cwd_fsp,
1082                                 smb_dname,
1083                                 AT_REMOVEDIR);
1084         }
1085
1086   err:
1087
1088         if (ret != 0) {
1089                 DEBUG(3,("rmdir_internals: couldn't remove directory %s : "
1090                          "%s\n", smb_fname_str_dbg(smb_dname),
1091                          strerror(errno)));
1092                 return map_nt_error_from_unix(errno);
1093         }
1094
1095         notify_fname(conn, NOTIFY_ACTION_REMOVED,
1096                      FILE_NOTIFY_CHANGE_DIR_NAME,
1097                      smb_dname->base_name);
1098
1099         return NT_STATUS_OK;
1100 }
1101
1102 /****************************************************************************
1103  Close a directory opened by an NT SMB call. 
1104 ****************************************************************************/
1105   
1106 static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
1107                                 enum file_close_type close_type)
1108 {
1109         struct share_mode_lock *lck = NULL;
1110         bool delete_dir = False;
1111         NTSTATUS status = NT_STATUS_OK;
1112         NTSTATUS status1 = NT_STATUS_OK;
1113         const struct security_token *del_nt_token = NULL;
1114         const struct security_unix_token *del_token = NULL;
1115         NTSTATUS notify_status;
1116
1117         if (fsp->conn->sconn->using_smb2) {
1118                 notify_status = STATUS_NOTIFY_CLEANUP;
1119         } else {
1120                 notify_status = NT_STATUS_OK;
1121         }
1122
1123         assert_no_pending_aio(fsp, close_type);
1124
1125         /*
1126          * NT can set delete_on_close of the last open
1127          * reference to a directory also.
1128          */
1129
1130         lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
1131         if (lck == NULL) {
1132                 DEBUG(0, ("close_directory: Could not get share mode lock for "
1133                           "%s\n", fsp_str_dbg(fsp)));
1134                 file_free(req, fsp);
1135                 return NT_STATUS_INVALID_PARAMETER;
1136         }
1137
1138         if (fsp->fsp_flags.initial_delete_on_close) {
1139                 bool became_user = False;
1140
1141                 /* Initial delete on close was set - for
1142                  * directories we don't care if anyone else
1143                  * wrote a real delete on close. */
1144
1145                 if (get_current_vuid(fsp->conn) != fsp->vuid) {
1146                         become_user_without_service(fsp->conn, fsp->vuid);
1147                         became_user = True;
1148                 }
1149                 send_stat_cache_delete_message(fsp->conn->sconn->msg_ctx,
1150                                                fsp->fsp_name->base_name);
1151                 set_delete_on_close_lck(fsp, lck,
1152                                 get_current_nttok(fsp->conn),
1153                                 get_current_utok(fsp->conn));
1154                 fsp->fsp_flags.delete_on_close = true;
1155                 if (became_user) {
1156                         unbecome_user_without_service();
1157                 }
1158         }
1159
1160         delete_dir = get_delete_on_close_token(
1161                 lck, fsp->name_hash, &del_nt_token, &del_token) &&
1162                 !has_other_nonposix_opens(lck, fsp);
1163
1164         if ((close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) &&
1165                                 delete_dir) {
1166         
1167                 /* Become the user who requested the delete. */
1168
1169                 if (!push_sec_ctx()) {
1170                         smb_panic("close_directory: failed to push sec_ctx.\n");
1171                 }
1172
1173                 set_sec_ctx(del_token->uid,
1174                                 del_token->gid,
1175                                 del_token->ngroups,
1176                                 del_token->groups,
1177                                 del_nt_token);
1178
1179                 if (!del_share_mode(lck, fsp)) {
1180                         DEBUG(0, ("close_directory: Could not delete share entry for "
1181                                   "%s\n", fsp_str_dbg(fsp)));
1182                 }
1183
1184                 TALLOC_FREE(lck);
1185
1186                 if ((fsp->conn->fs_capabilities & FILE_NAMED_STREAMS)
1187                     && !is_ntfs_stream_smb_fname(fsp->fsp_name)) {
1188
1189                         status = delete_all_streams(fsp->conn, fsp->fsp_name);
1190                         if (!NT_STATUS_IS_OK(status)) {
1191                                 DEBUG(5, ("delete_all_streams failed: %s\n",
1192                                           nt_errstr(status)));
1193                                 file_free(req, fsp);
1194                                 return status;
1195                         }
1196                 }
1197
1198                 status = rmdir_internals(talloc_tos(), fsp);
1199
1200                 DEBUG(5,("close_directory: %s. Delete on close was set - "
1201                          "deleting directory returned %s.\n",
1202                          fsp_str_dbg(fsp), nt_errstr(status)));
1203
1204                 /* unbecome user. */
1205                 pop_sec_ctx();
1206
1207                 /*
1208                  * Ensure we remove any change notify requests that would
1209                  * now fail as the directory has been deleted.
1210                  */
1211
1212                 if (NT_STATUS_IS_OK(status)) {
1213                         notify_status = NT_STATUS_DELETE_PENDING;
1214                 }
1215         } else {
1216                 if (!del_share_mode(lck, fsp)) {
1217                         DEBUG(0, ("close_directory: Could not delete share entry for "
1218                                   "%s\n", fsp_str_dbg(fsp)));
1219                 }
1220
1221                 TALLOC_FREE(lck);
1222         }
1223
1224         remove_pending_change_notify_requests_by_fid(fsp, notify_status);
1225
1226         status1 = fd_close(fsp);
1227
1228         if (!NT_STATUS_IS_OK(status1)) {
1229                 DEBUG(0, ("Could not close dir! fname=%s, fd=%d, err=%d=%s\n",
1230                           fsp_str_dbg(fsp), fsp->fh->fd, errno,
1231                           strerror(errno)));
1232         }
1233
1234         /*
1235          * Do the code common to files and directories.
1236          */
1237         file_free(req, fsp);
1238
1239         if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(status1)) {
1240                 status = status1;
1241         }
1242         return status;
1243 }
1244
1245 /****************************************************************************
1246  Close a files_struct.
1247 ****************************************************************************/
1248   
1249 NTSTATUS close_file(struct smb_request *req, files_struct *fsp,
1250                     enum file_close_type close_type)
1251 {
1252         NTSTATUS status;
1253         struct files_struct *base_fsp = fsp->base_fsp;
1254
1255         if (fsp->fsp_flags.is_directory) {
1256                 status = close_directory(req, fsp, close_type);
1257         } else if (fsp->fake_file_handle != NULL) {
1258                 status = close_fake_file(req, fsp);
1259         } else {
1260                 status = close_normal_file(req, fsp, close_type);
1261         }
1262
1263         if ((base_fsp != NULL) && (close_type != SHUTDOWN_CLOSE)) {
1264
1265                 /*
1266                  * fsp was a stream, the base fsp can't be a stream as well
1267                  *
1268                  * For SHUTDOWN_CLOSE this is not possible here, because
1269                  * SHUTDOWN_CLOSE only happens from files.c which walks the
1270                  * complete list of files. If we mess with more than one fsp
1271                  * those loops will become confused.
1272                  */
1273
1274                 SMB_ASSERT(base_fsp->base_fsp == NULL);
1275                 close_file(req, base_fsp, close_type);
1276         }
1277
1278         return status;
1279 }
1280
1281 /****************************************************************************
1282  Deal with an (authorized) message to close a file given the share mode
1283  entry.
1284 ****************************************************************************/
1285
1286 void msg_close_file(struct messaging_context *msg_ctx,
1287                         void *private_data,
1288                         uint32_t msg_type,
1289                         struct server_id server_id,
1290                         DATA_BLOB *data)
1291 {
1292         files_struct *fsp = NULL;
1293         struct file_id id;
1294         struct share_mode_entry e;
1295         struct smbd_server_connection *sconn =
1296                 talloc_get_type_abort(private_data,
1297                 struct smbd_server_connection);
1298
1299         message_to_share_mode_entry(&id, &e, (char *)data->data);
1300
1301         if(DEBUGLVL(10)) {
1302                 char *sm_str = share_mode_str(NULL, 0, &id, &e);
1303                 if (!sm_str) {
1304                         smb_panic("talloc failed");
1305                 }
1306                 DEBUG(10,("msg_close_file: got request to close share mode "
1307                         "entry %s\n", sm_str));
1308                 TALLOC_FREE(sm_str);
1309         }
1310
1311         fsp = file_find_dif(sconn, id, e.share_file_id);
1312         if (!fsp) {
1313                 DEBUG(10,("msg_close_file: failed to find file.\n"));
1314                 return;
1315         }
1316         close_file(NULL, fsp, NORMAL_CLOSE);
1317 }