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