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