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