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