libndr: Avoid assigning duplicate versions to symbols
[amitay/samba.git] / source3 / smbd / close.c
1 /*
2    Unix SMB/CIFS implementation.
3    file closing
4    Copyright (C) Andrew Tridgell 1992-1998
5    Copyright (C) Jeremy Allison 1992-2007.
6    Copyright (C) Volker Lendecke 2005
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "includes.h"
23 #include "system/filesys.h"
24 #include "lib/util/server_id.h"
25 #include "printing.h"
26 #include "smbd/smbd.h"
27 #include "smbd/globals.h"
28 #include "smbd/scavenger.h"
29 #include "fake_file.h"
30 #include "transfer_file.h"
31 #include "auth.h"
32 #include "messages.h"
33 #include "../librpc/gen_ndr/open_files.h"
34 #include "lib/util/tevent_ntstatus.h"
35
36 /****************************************************************************
37  Run a file if it is a magic script.
38 ****************************************************************************/
39
40 static NTSTATUS check_magic(struct files_struct *fsp)
41 {
42         int ret;
43         const struct loadparm_substitution *lp_sub =
44                 loadparm_s3_global_substitution();
45         const char *magic_output = NULL;
46         SMB_STRUCT_STAT st;
47         int tmp_fd, outfd;
48         TALLOC_CTX *ctx = NULL;
49         const char *p;
50         struct connection_struct *conn = fsp->conn;
51         char *fname = NULL;
52         NTSTATUS status;
53
54         if (!*lp_magic_script(talloc_tos(), lp_sub, SNUM(conn))) {
55                 return NT_STATUS_OK;
56         }
57
58         DEBUG(5,("checking magic for %s\n", fsp_str_dbg(fsp)));
59
60         ctx = talloc_stackframe();
61
62         fname = fsp->fsp_name->base_name;
63
64         if (!(p = strrchr_m(fname,'/'))) {
65                 p = fname;
66         } else {
67                 p++;
68         }
69
70         if (!strequal(lp_magic_script(talloc_tos(), lp_sub, SNUM(conn)),p)) {
71                 status = NT_STATUS_OK;
72                 goto out;
73         }
74
75         if (*lp_magic_output(talloc_tos(), lp_sub, SNUM(conn))) {
76                 magic_output = lp_magic_output(talloc_tos(), lp_sub, SNUM(conn));
77         } else {
78                 magic_output = talloc_asprintf(ctx,
79                                 "%s.out",
80                                 fname);
81         }
82         if (!magic_output) {
83                 status = NT_STATUS_NO_MEMORY;
84                 goto out;
85         }
86
87         /* Ensure we don't depend on user's PATH. */
88         p = talloc_asprintf(ctx, "./%s", fname);
89         if (!p) {
90                 status = NT_STATUS_NO_MEMORY;
91                 goto out;
92         }
93
94         if (chmod(fname, 0755) == -1) {
95                 status = map_nt_error_from_unix(errno);
96                 goto out;
97         }
98         ret = smbrun(p, &tmp_fd, NULL);
99         DEBUG(3,("Invoking magic command %s gave %d\n",
100                 p,ret));
101
102         unlink(fname);
103         if (ret != 0 || tmp_fd == -1) {
104                 if (tmp_fd != -1) {
105                         close(tmp_fd);
106                 }
107                 status = NT_STATUS_UNSUCCESSFUL;
108                 goto out;
109         }
110         outfd = open(magic_output, O_CREAT|O_EXCL|O_RDWR, 0600);
111         if (outfd == -1) {
112                 int err = errno;
113                 close(tmp_fd);
114                 status = map_nt_error_from_unix(err);
115                 goto out;
116         }
117
118         if (sys_fstat(tmp_fd, &st, false) == -1) {
119                 int err = errno;
120                 close(tmp_fd);
121                 close(outfd);
122                 status = map_nt_error_from_unix(err);
123                 goto out;
124         }
125
126         if (transfer_file(tmp_fd,outfd,(off_t)st.st_ex_size) == (off_t)-1) {
127                 int err = errno;
128                 close(tmp_fd);
129                 close(outfd);
130                 status = map_nt_error_from_unix(err);
131                 goto out;
132         }
133         close(tmp_fd);
134         if (close(outfd) == -1) {
135                 status = map_nt_error_from_unix(errno);
136                 goto out;
137         }
138
139         status = NT_STATUS_OK;
140
141  out:
142         TALLOC_FREE(ctx);
143         return status;
144 }
145
146 /****************************************************************************
147  Delete all streams
148 ****************************************************************************/
149
150 NTSTATUS delete_all_streams(connection_struct *conn,
151                         const struct smb_filename *smb_fname)
152 {
153         struct stream_struct *stream_info = NULL;
154         unsigned int i;
155         unsigned int num_streams = 0;
156         TALLOC_CTX *frame = talloc_stackframe();
157         NTSTATUS status;
158
159         status = vfs_streaminfo(conn, NULL, smb_fname, talloc_tos(),
160                                 &num_streams, &stream_info);
161
162         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
163                 DEBUG(10, ("no streams around\n"));
164                 TALLOC_FREE(frame);
165                 return NT_STATUS_OK;
166         }
167
168         if (!NT_STATUS_IS_OK(status)) {
169                 DEBUG(10, ("vfs_streaminfo failed: %s\n",
170                            nt_errstr(status)));
171                 goto fail;
172         }
173
174         DEBUG(10, ("delete_all_streams found %d streams\n",
175                    num_streams));
176
177         if (num_streams == 0) {
178                 TALLOC_FREE(frame);
179                 return NT_STATUS_OK;
180         }
181
182         for (i=0; i<num_streams; i++) {
183                 int res;
184                 struct smb_filename *smb_fname_stream;
185
186                 if (strequal(stream_info[i].name, "::$DATA")) {
187                         continue;
188                 }
189
190                 smb_fname_stream = synthetic_smb_fname(talloc_tos(),
191                                         smb_fname->base_name,
192                                         stream_info[i].name,
193                                         NULL,
194                                         smb_fname->twrp,
195                                         (smb_fname->flags &
196                                                 ~SMB_FILENAME_POSIX_PATH));
197
198                 if (smb_fname_stream == NULL) {
199                         DEBUG(0, ("talloc_aprintf failed\n"));
200                         status = NT_STATUS_NO_MEMORY;
201                         goto fail;
202                 }
203
204                 res = SMB_VFS_UNLINKAT(conn,
205                                 conn->cwd_fsp,
206                                 smb_fname_stream,
207                                 0);
208
209                 if (res == -1) {
210                         status = map_nt_error_from_unix(errno);
211                         DEBUG(10, ("Could not delete stream %s: %s\n",
212                                    smb_fname_str_dbg(smb_fname_stream),
213                                    strerror(errno)));
214                         TALLOC_FREE(smb_fname_stream);
215                         break;
216                 }
217                 TALLOC_FREE(smb_fname_stream);
218         }
219
220  fail:
221         TALLOC_FREE(frame);
222         return status;
223 }
224
225 struct has_other_nonposix_opens_state {
226         files_struct *fsp;
227         bool found_another;
228 };
229
230 static bool has_other_nonposix_opens_fn(
231         struct share_mode_entry *e,
232         bool *modified,
233         void *private_data)
234 {
235         struct has_other_nonposix_opens_state *state = private_data;
236         struct files_struct *fsp = state->fsp;
237
238         if (e->name_hash != fsp->name_hash) {
239                 return false;
240         }
241         if ((fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) &&
242             (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) {
243                 return false;
244         }
245         if (e->share_file_id == fsp->fh->gen_id) {
246                 struct server_id self = messaging_server_id(
247                         fsp->conn->sconn->msg_ctx);
248                 if (server_id_equal(&self, &e->pid)) {
249                         return false;
250                 }
251         }
252         if (share_entry_stale_pid(e)) {
253                 return false;
254         }
255
256         state->found_another = true;
257         return true;
258 }
259
260 bool has_other_nonposix_opens(struct share_mode_lock *lck,
261                               struct files_struct *fsp)
262 {
263         struct has_other_nonposix_opens_state state = { .fsp = fsp };
264         bool ok;
265
266         ok = share_mode_forall_entries(
267                 lck, has_other_nonposix_opens_fn, &state);
268         if (!ok) {
269                 return false;
270         }
271         return state.found_another;
272 }
273
274 /****************************************************************************
275  Deal with removing a share mode on last close.
276 ****************************************************************************/
277
278 static NTSTATUS close_remove_share_mode(files_struct *fsp,
279                                         enum file_close_type close_type)
280 {
281         connection_struct *conn = fsp->conn;
282         bool delete_file = false;
283         bool changed_user = false;
284         struct share_mode_lock *lck = NULL;
285         NTSTATUS status = NT_STATUS_OK;
286         NTSTATUS tmp_status;
287         struct file_id id;
288         const struct security_unix_token *del_token = NULL;
289         const struct security_token *del_nt_token = NULL;
290         bool got_tokens = false;
291         bool normal_close;
292         int ret;
293
294         /* Ensure any pending write time updates are done. */
295         if (fsp->update_write_time_event) {
296                 fsp_flush_write_time_update(fsp);
297         }
298
299         /*
300          * Lock the share entries, and determine if we should delete
301          * on close. If so delete whilst the lock is still in effect.
302          * This prevents race conditions with the file being created. JRA.
303          */
304
305         lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
306         if (lck == NULL) {
307                 DEBUG(0, ("close_remove_share_mode: Could not get share mode "
308                           "lock for file %s\n", fsp_str_dbg(fsp)));
309                 return NT_STATUS_INVALID_PARAMETER;
310         }
311
312         /* Remove the oplock before potentially deleting the file. */
313         if(fsp->oplock_type) {
314                 remove_oplock(fsp);
315         }
316
317         if (fsp->fsp_flags.write_time_forced) {
318                 struct timespec ts;
319
320                 DEBUG(10,("close_remove_share_mode: write time forced "
321                         "for file %s\n",
322                         fsp_str_dbg(fsp)));
323                 ts = nt_time_to_full_timespec(lck->data->changed_write_time);
324                 set_close_write_time(fsp, ts);
325         } else if (fsp->fsp_flags.update_write_time_on_close) {
326                 /* Someone had a pending write. */
327                 if (is_omit_timespec(&fsp->close_write_time)) {
328                         DEBUG(10,("close_remove_share_mode: update to current time "
329                                 "for file %s\n",
330                                 fsp_str_dbg(fsp)));
331                         /* Update to current time due to "normal" write. */
332                         set_close_write_time(fsp, timespec_current());
333                 } else {
334                         DEBUG(10,("close_remove_share_mode: write time pending "
335                                 "for file %s\n",
336                                 fsp_str_dbg(fsp)));
337                         /* Update to time set on close call. */
338                         set_close_write_time(fsp, fsp->close_write_time);
339                 }
340         }
341
342         if (fsp->fsp_flags.initial_delete_on_close &&
343                         !is_delete_on_close_set(lck, fsp->name_hash)) {
344                 struct auth_session_info *session_info = NULL;
345
346                 /* Initial delete on close was set and no one else
347                  * wrote a real delete on close. */
348
349                 status = smbXsrv_session_info_lookup(conn->sconn->client,
350                                                      fsp->vuid,
351                                                      &session_info);
352                 if (!NT_STATUS_IS_OK(status)) {
353                         return NT_STATUS_INTERNAL_ERROR;
354                 }
355                 fsp->fsp_flags.delete_on_close = true;
356                 set_delete_on_close_lck(fsp, lck,
357                                         session_info->security_token,
358                                         session_info->unix_token);
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         struct smbXsrv_client *client = global_smbXsrv_client;
643         size_t num_connections_alive;
644         unsigned num_requests = fsp->num_aio_requests;
645
646         if (num_requests == 0) {
647                 return;
648         }
649
650         num_connections_alive = smbXsrv_client_valid_connections(client);
651
652         if (close_type == SHUTDOWN_CLOSE && num_connections_alive == 0) {
653                 /*
654                  * fsp->aio_requests and the contents (fsp->aio_requests[x])
655                  * are both independently owned by fsp and are not in a
656                  * talloc heirarchy. This allows the fsp->aio_requests array to
657                  * be reallocated independently of the array contents so it can
658                  * grow on demand.
659                  *
660                  * This means we must ensure order of deallocation
661                  * on a SHUTDOWN_CLOSE by deallocating the fsp->aio_requests[x]
662                  * contents first, as their destructors access the
663                  * fsp->aio_request array. If we don't deallocate them
664                  * first, when fsp is deallocated fsp->aio_requests
665                  * could have been deallocated *before* its contents
666                  * fsp->aio_requests[x], causing a crash.
667                  */
668                 while (fsp->num_aio_requests != 0) {
669                         /*
670                          * NB. We *MUST* use
671                          * talloc_free(fsp->aio_requests[0]),
672                          * and *NOT* TALLOC_FREE() here, as
673                          * TALLOC_FREE(fsp->aio_requests[0])
674                          * will overwrite any new contents of
675                          * fsp->aio_requests[0] that were
676                          * copied into it via the destructor
677                          * aio_del_req_from_fsp().
678                          *
679                          * BUG: https://bugzilla.samba.org/show_bug.cgi?id=14515
680                          */
681                         talloc_free(fsp->aio_requests[0]);
682                 }
683                 return;
684         }
685
686         DBG_ERR("fsp->num_aio_requests=%u\n", num_requests);
687         smb_panic("can not close with outstanding aio requests");
688         return;
689 }
690
691 /****************************************************************************
692  Close a file.
693
694  close_type can be NORMAL_CLOSE=0,SHUTDOWN_CLOSE,ERROR_CLOSE.
695  printing and magic scripts are only run on normal close.
696  delete on close is done on normal and shutdown close.
697 ****************************************************************************/
698
699 static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp,
700                                   enum file_close_type close_type)
701 {
702         NTSTATUS status = NT_STATUS_OK;
703         NTSTATUS tmp;
704         connection_struct *conn = fsp->conn;
705         bool is_durable = false;
706
707         assert_no_pending_aio(fsp, close_type);
708
709         while (talloc_array_length(fsp->blocked_smb1_lock_reqs) != 0) {
710                 smbd_smb1_brl_finish_by_req(
711                         fsp->blocked_smb1_lock_reqs[0],
712                         NT_STATUS_RANGE_NOT_LOCKED);
713         }
714
715         /*
716          * If we're flushing on a close we can get a write
717          * error here, we must remember this.
718          */
719
720         if (NT_STATUS_IS_OK(status) && fsp->op != NULL) {
721                 is_durable = fsp->op->global->durable;
722         }
723
724         if (close_type != SHUTDOWN_CLOSE) {
725                 is_durable = false;
726         }
727
728         if (is_durable) {
729                 DATA_BLOB new_cookie = data_blob_null;
730
731                 tmp = SMB_VFS_DURABLE_DISCONNECT(fsp,
732                                         fsp->op->global->backend_cookie,
733                                         fsp->op,
734                                         &new_cookie);
735                 if (NT_STATUS_IS_OK(tmp)) {
736                         struct timeval tv;
737                         NTTIME now;
738
739                         if (req != NULL) {
740                                 tv = req->request_time;
741                         } else {
742                                 tv = timeval_current();
743                         }
744                         now = timeval_to_nttime(&tv);
745
746                         data_blob_free(&fsp->op->global->backend_cookie);
747                         fsp->op->global->backend_cookie = new_cookie;
748
749                         fsp->op->compat = NULL;
750                         tmp = smbXsrv_open_close(fsp->op, now);
751                         if (!NT_STATUS_IS_OK(tmp)) {
752                                 DEBUG(1, ("Failed to update smbXsrv_open "
753                                           "record when disconnecting durable "
754                                           "handle for file %s: %s - "
755                                           "proceeding with normal close\n",
756                                           fsp_str_dbg(fsp), nt_errstr(tmp)));
757                         }
758                         scavenger_schedule_disconnected(fsp);
759                 } else {
760                         DEBUG(1, ("Failed to disconnect durable handle for "
761                                   "file %s: %s - proceeding with normal "
762                                   "close\n", fsp_str_dbg(fsp), nt_errstr(tmp)));
763                 }
764                 if (!NT_STATUS_IS_OK(tmp)) {
765                         is_durable = false;
766                 }
767         }
768
769         if (is_durable) {
770                 /*
771                  * This is the case where we successfully disconnected
772                  * a durable handle and closed the underlying file.
773                  * In all other cases, we proceed with a genuine close.
774                  */
775                 DEBUG(10, ("%s disconnected durable handle for file %s\n",
776                            conn->session_info->unix_info->unix_name,
777                            fsp_str_dbg(fsp)));
778                 file_free(req, fsp);
779                 return NT_STATUS_OK;
780         }
781
782         if (fsp->op != NULL) {
783                 /*
784                  * Make sure the handle is not marked as durable anymore
785                  */
786                 fsp->op->global->durable = false;
787         }
788
789         if (fsp->print_file) {
790                 /* FIXME: return spool errors */
791                 print_spool_end(fsp, close_type);
792                 file_free(req, fsp);
793                 return NT_STATUS_OK;
794         }
795
796         /* If this is an old DOS or FCB open and we have multiple opens on
797            the same handle we only have one share mode. Ensure we only remove
798            the share mode on the last close. */
799
800         if (fsp->fh->ref_count == 1) {
801                 /* Should we return on error here... ? */
802                 tmp = close_remove_share_mode(fsp, close_type);
803                 status = ntstatus_keeperror(status, tmp);
804         }
805
806         locking_close_file(fsp, close_type);
807
808         tmp = fd_close(fsp);
809         status = ntstatus_keeperror(status, tmp);
810
811         /* check for magic scripts */
812         if (close_type == NORMAL_CLOSE) {
813                 tmp = check_magic(fsp);
814                 status = ntstatus_keeperror(status, tmp);
815         }
816
817         /*
818          * Ensure pending modtime is set after close.
819          */
820
821         tmp = update_write_time_on_close(fsp);
822         if (NT_STATUS_EQUAL(tmp, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
823                 /* Someone renamed the file or a parent directory containing
824                  * this file. We can't do anything about this, we don't have
825                  * an "update timestamp by fd" call in POSIX. Eat the error. */
826
827                 tmp = NT_STATUS_OK;
828         }
829
830         status = ntstatus_keeperror(status, tmp);
831
832         DEBUG(2,("%s closed file %s (numopen=%d) %s\n",
833                 conn->session_info->unix_info->unix_name, fsp_str_dbg(fsp),
834                 conn->num_files_open - 1,
835                 nt_errstr(status) ));
836
837         file_free(req, fsp);
838         return status;
839 }
840 /****************************************************************************
841  Function used by reply_rmdir to delete an entire directory
842  tree recursively. Return True on ok, False on fail.
843 ****************************************************************************/
844
845 bool recursive_rmdir(TALLOC_CTX *ctx,
846                      connection_struct *conn,
847                      struct smb_filename *smb_dname)
848 {
849         const char *dname = NULL;
850         char *talloced = NULL;
851         bool ret = True;
852         long offset = 0;
853         SMB_STRUCT_STAT st;
854         struct smb_Dir *dir_hnd;
855         int retval;
856
857         SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
858
859         dir_hnd = OpenDir(talloc_tos(), conn, smb_dname, NULL, 0);
860         if(dir_hnd == NULL)
861                 return False;
862
863         while((dname = ReadDirName(dir_hnd, &offset, &st, &talloced))) {
864                 struct smb_filename *smb_dname_full = NULL;
865                 char *fullname = NULL;
866                 bool do_break = true;
867
868                 if (ISDOT(dname) || ISDOTDOT(dname)) {
869                         TALLOC_FREE(talloced);
870                         continue;
871                 }
872
873                 if (!is_visible_file(conn,
874                                         dir_hnd,
875                                         dname,
876                                         &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->twrp,
897                                                 smb_dname->flags);
898                 if (smb_dname_full == NULL) {
899                         errno = ENOMEM;
900                         goto err_break;
901                 }
902
903                 if(SMB_VFS_LSTAT(conn, smb_dname_full) != 0) {
904                         goto err_break;
905                 }
906
907                 if(smb_dname_full->st.st_ex_mode & S_IFDIR) {
908                         if(!recursive_rmdir(ctx, conn, smb_dname_full)) {
909                                 goto err_break;
910                         }
911                         retval = SMB_VFS_UNLINKAT(conn,
912                                         conn->cwd_fsp,
913                                         smb_dname_full,
914                                         AT_REMOVEDIR);
915                         if (retval != 0) {
916                                 goto err_break;
917                         }
918                 } else {
919                         retval = SMB_VFS_UNLINKAT(conn,
920                                         conn->cwd_fsp,
921                                         smb_dname_full,
922                                         0);
923                         if (retval != 0) {
924                                 goto err_break;
925                         }
926                 }
927
928                 /* Successful iteration. */
929                 do_break = false;
930
931          err_break:
932                 TALLOC_FREE(smb_dname_full);
933                 TALLOC_FREE(fullname);
934                 TALLOC_FREE(talloced);
935                 if (do_break) {
936                         ret = false;
937                         break;
938                 }
939         }
940         TALLOC_FREE(dir_hnd);
941         return ret;
942 }
943
944 /****************************************************************************
945  The internals of the rmdir code - called elsewhere.
946 ****************************************************************************/
947
948 static NTSTATUS rmdir_internals(TALLOC_CTX *ctx, files_struct *fsp)
949 {
950         connection_struct *conn = fsp->conn;
951         struct smb_filename *smb_dname = fsp->fsp_name;
952         const struct loadparm_substitution *lp_sub =
953                 loadparm_s3_global_substitution();
954         int ret;
955
956         SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname));
957
958         /* Might be a symlink. */
959         if(SMB_VFS_LSTAT(conn, smb_dname) != 0) {
960                 return map_nt_error_from_unix(errno);
961         }
962
963         if (S_ISLNK(smb_dname->st.st_ex_mode)) {
964                 /* Is what it points to a directory ? */
965                 if(SMB_VFS_STAT(conn, smb_dname) != 0) {
966                         return map_nt_error_from_unix(errno);
967                 }
968                 if (!(S_ISDIR(smb_dname->st.st_ex_mode))) {
969                         return NT_STATUS_NOT_A_DIRECTORY;
970                 }
971                 ret = SMB_VFS_UNLINKAT(conn,
972                                 conn->cwd_fsp,
973                                 smb_dname,
974                                 0);
975         } else {
976                 ret = SMB_VFS_UNLINKAT(conn,
977                                 conn->cwd_fsp,
978                                 smb_dname,
979                                 AT_REMOVEDIR);
980         }
981         if (ret == 0) {
982                 notify_fname(conn, NOTIFY_ACTION_REMOVED,
983                              FILE_NOTIFY_CHANGE_DIR_NAME,
984                              smb_dname->base_name);
985                 return NT_STATUS_OK;
986         }
987
988         if(((errno == ENOTEMPTY)||(errno == EEXIST)) && *lp_veto_files(talloc_tos(), lp_sub, SNUM(conn))) {
989                 /*
990                  * Check to see if the only thing in this directory are
991                  * vetoed files/directories. If so then delete them and
992                  * retry. If we fail to delete any of them (and we *don't*
993                  * do a recursive delete) then fail the rmdir.
994                  */
995                 SMB_STRUCT_STAT st;
996                 const char *dname = NULL;
997                 char *talloced = NULL;
998                 long dirpos = 0;
999                 struct smb_Dir *dir_hnd = OpenDir(talloc_tos(), conn,
1000                                                   smb_dname, NULL,
1001                                                   0);
1002
1003                 if(dir_hnd == NULL) {
1004                         errno = ENOTEMPTY;
1005                         goto err;
1006                 }
1007
1008                 while ((dname = ReadDirName(dir_hnd, &dirpos, &st,
1009                                             &talloced)) != NULL) {
1010                         if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0)) {
1011                                 TALLOC_FREE(talloced);
1012                                 continue;
1013                         }
1014                         if (!is_visible_file(conn,
1015                                                 dir_hnd,
1016                                                 dname,
1017                                                 &st,
1018                                                 false)) {
1019                                 TALLOC_FREE(talloced);
1020                                 continue;
1021                         }
1022                         if(!IS_VETO_PATH(conn, dname)) {
1023                                 TALLOC_FREE(dir_hnd);
1024                                 TALLOC_FREE(talloced);
1025                                 errno = ENOTEMPTY;
1026                                 goto err;
1027                         }
1028                         TALLOC_FREE(talloced);
1029                 }
1030
1031                 /* We only have veto files/directories.
1032                  * Are we allowed to delete them ? */
1033
1034                 if(!lp_delete_veto_files(SNUM(conn))) {
1035                         TALLOC_FREE(dir_hnd);
1036                         errno = ENOTEMPTY;
1037                         goto err;
1038                 }
1039
1040                 /* Do a recursive delete. */
1041                 RewindDir(dir_hnd,&dirpos);
1042                 while ((dname = ReadDirName(dir_hnd, &dirpos, &st,
1043                                             &talloced)) != NULL) {
1044                         struct smb_filename *smb_dname_full = NULL;
1045                         char *fullname = NULL;
1046                         bool do_break = true;
1047
1048                         if (ISDOT(dname) || ISDOTDOT(dname)) {
1049                                 TALLOC_FREE(talloced);
1050                                 continue;
1051                         }
1052                         if (!is_visible_file(conn,
1053                                                 dir_hnd,
1054                                                 dname,
1055                                                 &st,
1056                                                 false)) {
1057                                 TALLOC_FREE(talloced);
1058                                 continue;
1059                         }
1060
1061                         fullname = talloc_asprintf(ctx,
1062                                         "%s/%s",
1063                                         smb_dname->base_name,
1064                                         dname);
1065
1066                         if(!fullname) {
1067                                 errno = ENOMEM;
1068                                 goto err_break;
1069                         }
1070
1071                         smb_dname_full = synthetic_smb_fname(talloc_tos(),
1072                                                         fullname,
1073                                                         NULL,
1074                                                         NULL,
1075                                                         smb_dname->twrp,
1076                                                         smb_dname->flags);
1077                         if (smb_dname_full == NULL) {
1078                                 errno = ENOMEM;
1079                                 goto err_break;
1080                         }
1081
1082                         if(SMB_VFS_LSTAT(conn, smb_dname_full) != 0) {
1083                                 goto err_break;
1084                         }
1085                         if(smb_dname_full->st.st_ex_mode & S_IFDIR) {
1086                                 int retval;
1087                                 if(!recursive_rmdir(ctx, conn,
1088                                                     smb_dname_full)) {
1089                                         goto err_break;
1090                                 }
1091                                 retval = SMB_VFS_UNLINKAT(conn,
1092                                                 conn->cwd_fsp,
1093                                                 smb_dname_full,
1094                                                 AT_REMOVEDIR);
1095                                 if(retval != 0) {
1096                                         goto err_break;
1097                                 }
1098                         } else {
1099                                 int retval = SMB_VFS_UNLINKAT(conn,
1100                                                 conn->cwd_fsp,
1101                                                 smb_dname_full,
1102                                                 0);
1103                                 if(retval != 0) {
1104                                         goto err_break;
1105                                 }
1106                         }
1107
1108                         /* Successful iteration. */
1109                         do_break = false;
1110
1111                  err_break:
1112                         TALLOC_FREE(fullname);
1113                         TALLOC_FREE(smb_dname_full);
1114                         TALLOC_FREE(talloced);
1115                         if (do_break)
1116                                 break;
1117                 }
1118                 TALLOC_FREE(dir_hnd);
1119                 /* Retry the rmdir */
1120                 ret = SMB_VFS_UNLINKAT(conn,
1121                                 conn->cwd_fsp,
1122                                 smb_dname,
1123                                 AT_REMOVEDIR);
1124         }
1125
1126   err:
1127
1128         if (ret != 0) {
1129                 DEBUG(3,("rmdir_internals: couldn't remove directory %s : "
1130                          "%s\n", smb_fname_str_dbg(smb_dname),
1131                          strerror(errno)));
1132                 return map_nt_error_from_unix(errno);
1133         }
1134
1135         notify_fname(conn, NOTIFY_ACTION_REMOVED,
1136                      FILE_NOTIFY_CHANGE_DIR_NAME,
1137                      smb_dname->base_name);
1138
1139         return NT_STATUS_OK;
1140 }
1141
1142 /****************************************************************************
1143  Close a directory opened by an NT SMB call. 
1144 ****************************************************************************/
1145   
1146 static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
1147                                 enum file_close_type close_type)
1148 {
1149         struct share_mode_lock *lck = NULL;
1150         bool delete_dir = False;
1151         NTSTATUS status = NT_STATUS_OK;
1152         NTSTATUS status1 = NT_STATUS_OK;
1153         const struct security_token *del_nt_token = NULL;
1154         const struct security_unix_token *del_token = NULL;
1155         NTSTATUS notify_status;
1156
1157         if (fsp->conn->sconn->using_smb2) {
1158                 notify_status = NT_STATUS_NOTIFY_CLEANUP;
1159         } else {
1160                 notify_status = NT_STATUS_OK;
1161         }
1162
1163         assert_no_pending_aio(fsp, close_type);
1164
1165         /*
1166          * NT can set delete_on_close of the last open
1167          * reference to a directory also.
1168          */
1169
1170         lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
1171         if (lck == NULL) {
1172                 DEBUG(0, ("close_directory: Could not get share mode lock for "
1173                           "%s\n", fsp_str_dbg(fsp)));
1174                 file_free(req, fsp);
1175                 return NT_STATUS_INVALID_PARAMETER;
1176         }
1177
1178         if (fsp->fsp_flags.initial_delete_on_close) {
1179                 struct auth_session_info *session_info = NULL;
1180
1181                 /* Initial delete on close was set - for
1182                  * directories we don't care if anyone else
1183                  * wrote a real delete on close. */
1184
1185                 status = smbXsrv_session_info_lookup(fsp->conn->sconn->client,
1186                                                      fsp->vuid,
1187                                                      &session_info);
1188                 if (!NT_STATUS_IS_OK(status)) {
1189                         return NT_STATUS_INTERNAL_ERROR;
1190                 }
1191
1192                 send_stat_cache_delete_message(fsp->conn->sconn->msg_ctx,
1193                                                fsp->fsp_name->base_name);
1194                 set_delete_on_close_lck(fsp, lck,
1195                                         session_info->security_token,
1196                                         session_info->unix_token);
1197                 fsp->fsp_flags.delete_on_close = true;
1198         }
1199
1200         delete_dir = get_delete_on_close_token(
1201                 lck, fsp->name_hash, &del_nt_token, &del_token) &&
1202                 !has_other_nonposix_opens(lck, fsp);
1203
1204         if ((close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) &&
1205                                 delete_dir) {
1206         
1207                 /* Become the user who requested the delete. */
1208
1209                 if (!push_sec_ctx()) {
1210                         smb_panic("close_directory: failed to push sec_ctx.\n");
1211                 }
1212
1213                 set_sec_ctx(del_token->uid,
1214                                 del_token->gid,
1215                                 del_token->ngroups,
1216                                 del_token->groups,
1217                                 del_nt_token);
1218
1219                 if (!del_share_mode(lck, fsp)) {
1220                         DEBUG(0, ("close_directory: Could not delete share entry for "
1221                                   "%s\n", fsp_str_dbg(fsp)));
1222                 }
1223
1224                 TALLOC_FREE(lck);
1225
1226                 if ((fsp->conn->fs_capabilities & FILE_NAMED_STREAMS)
1227                     && !is_ntfs_stream_smb_fname(fsp->fsp_name)) {
1228
1229                         status = delete_all_streams(fsp->conn, fsp->fsp_name);
1230                         if (!NT_STATUS_IS_OK(status)) {
1231                                 DEBUG(5, ("delete_all_streams failed: %s\n",
1232                                           nt_errstr(status)));
1233                                 file_free(req, fsp);
1234                                 return status;
1235                         }
1236                 }
1237
1238                 status = rmdir_internals(talloc_tos(), fsp);
1239
1240                 DEBUG(5,("close_directory: %s. Delete on close was set - "
1241                          "deleting directory returned %s.\n",
1242                          fsp_str_dbg(fsp), nt_errstr(status)));
1243
1244                 /* unbecome user. */
1245                 pop_sec_ctx();
1246
1247                 /*
1248                  * Ensure we remove any change notify requests that would
1249                  * now fail as the directory has been deleted.
1250                  */
1251
1252                 if (NT_STATUS_IS_OK(status)) {
1253                         notify_status = NT_STATUS_DELETE_PENDING;
1254                 }
1255         } else {
1256                 if (!del_share_mode(lck, fsp)) {
1257                         DEBUG(0, ("close_directory: Could not delete share entry for "
1258                                   "%s\n", fsp_str_dbg(fsp)));
1259                 }
1260
1261                 TALLOC_FREE(lck);
1262         }
1263
1264         remove_pending_change_notify_requests_by_fid(fsp, notify_status);
1265
1266         status1 = fd_close(fsp);
1267
1268         if (!NT_STATUS_IS_OK(status1)) {
1269                 DEBUG(0, ("Could not close dir! fname=%s, fd=%d, err=%d=%s\n",
1270                           fsp_str_dbg(fsp), fsp->fh->fd, errno,
1271                           strerror(errno)));
1272         }
1273
1274         /*
1275          * Do the code common to files and directories.
1276          */
1277         file_free(req, fsp);
1278
1279         if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(status1)) {
1280                 status = status1;
1281         }
1282         return status;
1283 }
1284
1285 /****************************************************************************
1286  Close a files_struct.
1287 ****************************************************************************/
1288   
1289 NTSTATUS close_file(struct smb_request *req, files_struct *fsp,
1290                     enum file_close_type close_type)
1291 {
1292         NTSTATUS status;
1293         struct files_struct *base_fsp = fsp->base_fsp;
1294
1295         if (fsp->fsp_flags.is_dirfsp) {
1296                 /*
1297                  * The typical way to get here is via file_close_[conn|user]()
1298                  * and this is taken care of below.
1299                  */
1300                 return NT_STATUS_OK;
1301         }
1302
1303         if (fsp->fsp_flags.is_directory) {
1304                 status = close_directory(req, fsp, close_type);
1305         } else if (fsp->fake_file_handle != NULL) {
1306                 status = close_fake_file(req, fsp);
1307         } else {
1308                 status = close_normal_file(req, fsp, close_type);
1309         }
1310
1311         if ((base_fsp != NULL) && (close_type != SHUTDOWN_CLOSE)) {
1312
1313                 /*
1314                  * fsp was a stream, the base fsp can't be a stream as well
1315                  *
1316                  * For SHUTDOWN_CLOSE this is not possible here, because
1317                  * SHUTDOWN_CLOSE only happens from files.c which walks the
1318                  * complete list of files. If we mess with more than one fsp
1319                  * those loops will become confused.
1320                  */
1321
1322                 SMB_ASSERT(base_fsp->base_fsp == NULL);
1323                 close_file(req, base_fsp, close_type);
1324         }
1325
1326         return status;
1327 }
1328
1329 /****************************************************************************
1330  Deal with an (authorized) message to close a file given the share mode
1331  entry.
1332 ****************************************************************************/
1333
1334 void msg_close_file(struct messaging_context *msg_ctx,
1335                         void *private_data,
1336                         uint32_t msg_type,
1337                         struct server_id server_id,
1338                         DATA_BLOB *data)
1339 {
1340         files_struct *fsp = NULL;
1341         struct file_id id;
1342         struct share_mode_entry e;
1343         struct smbd_server_connection *sconn =
1344                 talloc_get_type_abort(private_data,
1345                 struct smbd_server_connection);
1346
1347         message_to_share_mode_entry(&id, &e, (char *)data->data);
1348
1349         if(DEBUGLVL(10)) {
1350                 char *sm_str = share_mode_str(NULL, 0, &id, &e);
1351                 if (!sm_str) {
1352                         smb_panic("talloc failed");
1353                 }
1354                 DEBUG(10,("msg_close_file: got request to close share mode "
1355                         "entry %s\n", sm_str));
1356                 TALLOC_FREE(sm_str);
1357         }
1358
1359         fsp = file_find_dif(sconn, id, e.share_file_id);
1360         if (!fsp) {
1361                 DEBUG(10,("msg_close_file: failed to find file.\n"));
1362                 return;
1363         }
1364         close_file(NULL, fsp, NORMAL_CLOSE);
1365 }