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