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