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