Allow SMB2_FIND to actually use the open fd handle if we support fdopendir. Fallback...
[kai/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, NULL, 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                                                   NULL,
821                                                   smb_dname->base_name, NULL,
822                                                   0);
823
824                 if(dir_hnd == NULL) {
825                         errno = ENOTEMPTY;
826                         goto err;
827                 }
828
829                 while ((dname = ReadDirName(dir_hnd, &dirpos, &st,
830                                             &talloced)) != NULL) {
831                         if((strcmp(dname, ".") == 0) || (strcmp(dname, "..")==0)) {
832                                 TALLOC_FREE(talloced);
833                                 continue;
834                         }
835                         if (!is_visible_file(conn, smb_dname->base_name, dname,
836                                              &st, false)) {
837                                 TALLOC_FREE(talloced);
838                                 continue;
839                         }
840                         if(!IS_VETO_PATH(conn, dname)) {
841                                 TALLOC_FREE(dir_hnd);
842                                 TALLOC_FREE(talloced);
843                                 errno = ENOTEMPTY;
844                                 goto err;
845                         }
846                         TALLOC_FREE(talloced);
847                 }
848
849                 /* We only have veto files/directories.
850                  * Are we allowed to delete them ? */
851
852                 if(!lp_recursive_veto_delete(SNUM(conn))) {
853                         TALLOC_FREE(dir_hnd);
854                         errno = ENOTEMPTY;
855                         goto err;
856                 }
857
858                 /* Do a recursive delete. */
859                 RewindDir(dir_hnd,&dirpos);
860                 while ((dname = ReadDirName(dir_hnd, &dirpos, &st,
861                                             &talloced)) != NULL) {
862                         struct smb_filename *smb_dname_full = NULL;
863                         char *fullname = NULL;
864                         bool do_break = true;
865                         NTSTATUS status;
866
867                         if (ISDOT(dname) || ISDOTDOT(dname)) {
868                                 TALLOC_FREE(talloced);
869                                 continue;
870                         }
871                         if (!is_visible_file(conn, smb_dname->base_name, dname,
872                                              &st, false)) {
873                                 TALLOC_FREE(talloced);
874                                 continue;
875                         }
876
877                         fullname = talloc_asprintf(ctx,
878                                         "%s/%s",
879                                         smb_dname->base_name,
880                                         dname);
881
882                         if(!fullname) {
883                                 errno = ENOMEM;
884                                 goto err_break;
885                         }
886
887                         status = create_synthetic_smb_fname(talloc_tos(),
888                                                             fullname, NULL,
889                                                             NULL,
890                                                             &smb_dname_full);
891                         if (!NT_STATUS_IS_OK(status)) {
892                                 errno = map_errno_from_nt_status(status);
893                                 goto err_break;
894                         }
895
896                         if(SMB_VFS_LSTAT(conn, smb_dname_full) != 0) {
897                                 goto err_break;
898                         }
899                         if(smb_dname_full->st.st_ex_mode & S_IFDIR) {
900                                 if(!recursive_rmdir(ctx, conn,
901                                                     smb_dname_full)) {
902                                         goto err_break;
903                                 }
904                                 if(SMB_VFS_RMDIR(conn,
905                                         smb_dname_full->base_name) != 0) {
906                                         goto err_break;
907                                 }
908                         } else if(SMB_VFS_UNLINK(conn, smb_dname_full) != 0) {
909                                 goto err_break;
910                         }
911
912                         /* Successful iteration. */
913                         do_break = false;
914
915                  err_break:
916                         TALLOC_FREE(fullname);
917                         TALLOC_FREE(smb_dname_full);
918                         TALLOC_FREE(talloced);
919                         if (do_break)
920                                 break;
921                 }
922                 TALLOC_FREE(dir_hnd);
923                 /* Retry the rmdir */
924                 ret = SMB_VFS_RMDIR(conn, smb_dname->base_name);
925         }
926
927   err:
928
929         if (ret != 0) {
930                 DEBUG(3,("rmdir_internals: couldn't remove directory %s : "
931                          "%s\n", smb_fname_str_dbg(smb_dname),
932                          strerror(errno)));
933                 return map_nt_error_from_unix(errno);
934         }
935
936         notify_fname(conn, NOTIFY_ACTION_REMOVED,
937                      FILE_NOTIFY_CHANGE_DIR_NAME,
938                      smb_dname->base_name);
939
940         return NT_STATUS_OK;
941 }
942
943 /****************************************************************************
944  Close a directory opened by an NT SMB call. 
945 ****************************************************************************/
946   
947 static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
948                                 enum file_close_type close_type)
949 {
950         struct share_mode_lock *lck = NULL;
951         bool delete_dir = False;
952         NTSTATUS status = NT_STATUS_OK;
953         NTSTATUS status1 = NT_STATUS_OK;
954         const UNIX_USER_TOKEN *del_token = NULL;
955
956         /*
957          * NT can set delete_on_close of the last open
958          * reference to a directory also.
959          */
960
961         lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL,
962                                   NULL);
963
964         if (lck == NULL) {
965                 DEBUG(0, ("close_directory: Could not get share mode lock for "
966                           "%s\n", fsp_str_dbg(fsp)));
967                 status = NT_STATUS_INVALID_PARAMETER;
968                 goto out;
969         }
970
971         if (!del_share_mode(lck, fsp)) {
972                 DEBUG(0, ("close_directory: Could not delete share entry for "
973                           "%s\n", fsp_str_dbg(fsp)));
974         }
975
976         if (fsp->initial_delete_on_close) {
977                 bool became_user = False;
978
979                 /* Initial delete on close was set - for
980                  * directories we don't care if anyone else
981                  * wrote a real delete on close. */
982
983                 if (get_current_vuid(fsp->conn) != fsp->vuid) {
984                         become_user(fsp->conn, fsp->vuid);
985                         became_user = True;
986                 }
987                 send_stat_cache_delete_message(fsp->conn->sconn->msg_ctx,
988                                                fsp->fsp_name->base_name);
989                 set_delete_on_close_lck(fsp, lck, true,
990                                 get_current_utok(fsp->conn));
991                 fsp->delete_on_close = true;
992                 if (became_user) {
993                         unbecome_user();
994                 }
995         }
996
997         del_token = get_delete_on_close_token(lck, fsp->name_hash);
998         delete_dir = (del_token != NULL);
999
1000         if (delete_dir) {
1001                 int i;
1002                 /* See if others still have the dir open. If this is the
1003                  * case, then don't delete. If all opens are POSIX delete now. */
1004                 for (i=0; i<lck->num_share_modes; i++) {
1005                         struct share_mode_entry *e = &lck->share_modes[i];
1006                         if (is_valid_share_mode_entry(e) &&
1007                                         e->name_hash == fsp->name_hash) {
1008                                 if (fsp->posix_open && (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) {
1009                                         continue;
1010                                 }
1011                                 delete_dir = False;
1012                                 break;
1013                         }
1014                 }
1015         }
1016
1017         if ((close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) &&
1018                                 delete_dir) {
1019         
1020                 /* Become the user who requested the delete. */
1021
1022                 if (!push_sec_ctx()) {
1023                         smb_panic("close_directory: failed to push sec_ctx.\n");
1024                 }
1025
1026                 set_sec_ctx(del_token->uid,
1027                                 del_token->gid,
1028                                 del_token->ngroups,
1029                                 del_token->groups,
1030                                 NULL);
1031
1032                 TALLOC_FREE(lck);
1033
1034                 status = rmdir_internals(talloc_tos(), fsp);
1035
1036                 DEBUG(5,("close_directory: %s. Delete on close was set - "
1037                          "deleting directory returned %s.\n",
1038                          fsp_str_dbg(fsp), nt_errstr(status)));
1039
1040                 /* unbecome user. */
1041                 pop_sec_ctx();
1042
1043                 /*
1044                  * Ensure we remove any change notify requests that would
1045                  * now fail as the directory has been deleted.
1046                  */
1047
1048                 if(NT_STATUS_IS_OK(status)) {
1049                         remove_pending_change_notify_requests_by_fid(fsp, NT_STATUS_DELETE_PENDING);
1050                 }
1051         } else {
1052                 TALLOC_FREE(lck);
1053                 remove_pending_change_notify_requests_by_fid(
1054                         fsp, NT_STATUS_OK);
1055         }
1056
1057         status1 = fd_close(fsp);
1058
1059         if (!NT_STATUS_IS_OK(status1)) {
1060                 DEBUG(0, ("Could not close dir! fname=%s, fd=%d, err=%d=%s\n",
1061                           fsp_str_dbg(fsp), fsp->fh->fd, errno,
1062                           strerror(errno)));
1063         }
1064
1065         /*
1066          * Do the code common to files and directories.
1067          */
1068         close_filestruct(fsp);
1069         file_free(req, fsp);
1070
1071  out:
1072         TALLOC_FREE(lck);
1073         if (NT_STATUS_IS_OK(status) && !NT_STATUS_IS_OK(status1)) {
1074                 status = status1;
1075         }
1076         return status;
1077 }
1078
1079 /****************************************************************************
1080  Close a files_struct.
1081 ****************************************************************************/
1082   
1083 NTSTATUS close_file(struct smb_request *req, files_struct *fsp,
1084                     enum file_close_type close_type)
1085 {
1086         NTSTATUS status;
1087         struct files_struct *base_fsp = fsp->base_fsp;
1088
1089         if(fsp->is_directory) {
1090                 status = close_directory(req, fsp, close_type);
1091         } else if (fsp->fake_file_handle != NULL) {
1092                 status = close_fake_file(req, fsp);
1093         } else {
1094                 status = close_normal_file(req, fsp, close_type);
1095         }
1096
1097         if ((base_fsp != NULL) && (close_type != SHUTDOWN_CLOSE)) {
1098
1099                 /*
1100                  * fsp was a stream, the base fsp can't be a stream as well
1101                  *
1102                  * For SHUTDOWN_CLOSE this is not possible here, because
1103                  * SHUTDOWN_CLOSE only happens from files.c which walks the
1104                  * complete list of files. If we mess with more than one fsp
1105                  * those loops will become confused.
1106                  */
1107
1108                 SMB_ASSERT(base_fsp->base_fsp == NULL);
1109                 close_file(req, base_fsp, close_type);
1110         }
1111
1112         return status;
1113 }
1114
1115 /****************************************************************************
1116  Deal with an (authorized) message to close a file given the share mode
1117  entry.
1118 ****************************************************************************/
1119
1120 void msg_close_file(struct messaging_context *msg_ctx,
1121                         void *private_data,
1122                         uint32_t msg_type,
1123                         struct server_id server_id,
1124                         DATA_BLOB *data)
1125 {
1126         struct smbd_server_connection *sconn;
1127         files_struct *fsp = NULL;
1128         struct share_mode_entry e;
1129
1130         sconn = msg_ctx_to_sconn(msg_ctx);
1131         if (sconn == NULL) {
1132                 DEBUG(1, ("could not find sconn\n"));
1133                 return;
1134         }
1135
1136         message_to_share_mode_entry(&e, (char *)data->data);
1137
1138         if(DEBUGLVL(10)) {
1139                 char *sm_str = share_mode_str(NULL, 0, &e);
1140                 if (!sm_str) {
1141                         smb_panic("talloc failed");
1142                 }
1143                 DEBUG(10,("msg_close_file: got request to close share mode "
1144                         "entry %s\n", sm_str));
1145                 TALLOC_FREE(sm_str);
1146         }
1147
1148         fsp = file_find_dif(sconn, e.id, e.share_file_id);
1149         if (!fsp) {
1150                 DEBUG(10,("msg_close_file: failed to find file.\n"));
1151                 return;
1152         }
1153         close_file(NULL, fsp, NORMAL_CLOSE);
1154 }