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