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