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