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