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