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