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