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