s3: Change fsp->fsp_name to be an smb_filename struct!
[metze/samba/wip.git] / source3 / smbd / close.c
1 /*
2    Unix SMB/CIFS implementation.
3    file closing
4    Copyright (C) Andrew Tridgell 1992-1998
5    Copyright (C) Jeremy Allison 1992-2007.
6    Copyright (C) Volker Lendecke 2005
7
8    This program is free software; you can redistribute it and/or modify
9    it under the terms of the GNU General Public License as published by
10    the Free Software Foundation; either version 3 of the License, or
11    (at your option) any later version.
12
13    This program is distributed in the hope that it will be useful,
14    but WITHOUT ANY WARRANTY; without even the implied warranty of
15    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16    GNU General Public License for more details.
17
18    You should have received a copy of the GNU General Public License
19    along with this program.  If not, see <http://www.gnu.org/licenses/>.
20 */
21
22 #include "includes.h"
23
24 extern struct current_user current_user;
25
26 /****************************************************************************
27  Run a file if it is a magic script.
28 ****************************************************************************/
29
30 static NTSTATUS check_magic(struct files_struct *fsp)
31 {
32         int ret;
33         const char *magic_output = NULL;
34         SMB_STRUCT_STAT st;
35         int tmp_fd, outfd;
36         TALLOC_CTX *ctx = NULL;
37         const char *p;
38         struct connection_struct *conn = fsp->conn;
39         char *fname = NULL;
40         NTSTATUS status;
41
42         if (!*lp_magicscript(SNUM(conn))) {
43                 return NT_STATUS_OK;
44         }
45
46         DEBUG(5,("checking magic for %s\n", fsp_str_dbg(fsp)));
47
48         ctx = talloc_stackframe();
49
50         status = get_full_smb_filename(ctx, fsp->fsp_name, &fname);
51         if (!NT_STATUS_IS_OK(status)) {
52                 goto out;
53         }
54
55         if (!(p = strrchr_m(fname,'/'))) {
56                 p = fname;
57         } else {
58                 p++;
59         }
60
61         if (!strequal(lp_magicscript(SNUM(conn)),p)) {
62                 status = NT_STATUS_OK;
63                 goto out;
64         }
65
66         if (*lp_magicoutput(SNUM(conn))) {
67                 magic_output = lp_magicoutput(SNUM(conn));
68         } else {
69                 magic_output = talloc_asprintf(ctx,
70                                 "%s.out",
71                                 fname);
72         }
73         if (!magic_output) {
74                 status = NT_STATUS_NO_MEMORY;
75                 goto out;
76         }
77
78         /* Ensure we don't depend on user's PATH. */
79         p = talloc_asprintf(ctx, "./%s", fname);
80         if (!p) {
81                 status = NT_STATUS_NO_MEMORY;
82                 goto out;
83         }
84
85         if (chmod(fname, 0755) == -1) {
86                 status = map_nt_error_from_unix(errno);
87                 goto out;
88         }
89         ret = smbrun(p,&tmp_fd);
90         DEBUG(3,("Invoking magic command %s gave %d\n",
91                 p,ret));
92
93         unlink(fname);
94         if (ret != 0 || tmp_fd == -1) {
95                 if (tmp_fd != -1) {
96                         close(tmp_fd);
97                 }
98                 status = NT_STATUS_UNSUCCESSFUL;
99                 goto out;
100         }
101         outfd = open(magic_output, O_CREAT|O_EXCL|O_RDWR, 0600);
102         if (outfd == -1) {
103                 int err = errno;
104                 close(tmp_fd);
105                 status = map_nt_error_from_unix(err);
106                 goto out;
107         }
108
109         if (sys_fstat(tmp_fd,&st) == -1) {
110                 int err = errno;
111                 close(tmp_fd);
112                 close(outfd);
113                 status = map_nt_error_from_unix(err);
114                 goto out;
115         }
116
117         if (transfer_file(tmp_fd,outfd,(SMB_OFF_T)st.st_ex_size) == (SMB_OFF_T)-1) {
118                 int err = errno;
119                 close(tmp_fd);
120                 close(outfd);
121                 status = map_nt_error_from_unix(err);
122                 goto out;
123         }
124         close(tmp_fd);
125         if (close(outfd) == -1) {
126                 status = map_nt_error_from_unix(errno);
127                 goto out;
128         }
129
130         status = NT_STATUS_OK;
131
132  out:
133         TALLOC_FREE(ctx);
134         return status;
135 }
136
137 /****************************************************************************
138   Common code to close a file or a directory.
139 ****************************************************************************/
140
141 static NTSTATUS close_filestruct(files_struct *fsp)
142 {
143         NTSTATUS status = NT_STATUS_OK;
144
145         if (fsp->fh->fd != -1) {
146                 if(flush_write_cache(fsp, CLOSE_FLUSH) == -1) {
147                         status = map_nt_error_from_unix(errno);
148                 }
149                 delete_write_cache(fsp);
150         }
151
152         return status;
153 }
154
155 /****************************************************************************
156  If any deferred opens are waiting on this close, notify them.
157 ****************************************************************************/
158
159 static void notify_deferred_opens(struct share_mode_lock *lck)
160 {
161         int i;
162
163         if (!should_notify_deferred_opens()) {
164                 return;
165         }
166  
167         for (i=0; i<lck->num_share_modes; i++) {
168                 struct share_mode_entry *e = &lck->share_modes[i];
169  
170                 if (!is_deferred_open_entry(e)) {
171                         continue;
172                 }
173  
174                 if (procid_is_me(&e->pid)) {
175                         /*
176                          * We need to notify ourself to retry the open.  Do
177                          * this by finding the queued SMB record, moving it to
178                          * the head of the queue and changing the wait time to
179                          * zero.
180                          */
181                         schedule_deferred_open_smb_message(e->op_mid);
182                 } else {
183                         char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
184
185                         share_mode_entry_to_message(msg, e);
186
187                         messaging_send_buf(smbd_messaging_context(),
188                                            e->pid, MSG_SMB_OPEN_RETRY,
189                                            (uint8 *)msg,
190                                            MSG_SMB_SHARE_MODE_ENTRY_SIZE);
191                 }
192         }
193 }
194
195 /****************************************************************************
196  Delete all streams
197 ****************************************************************************/
198
199 NTSTATUS delete_all_streams(connection_struct *conn, const char *fname)
200 {
201         struct stream_struct *stream_info;
202         int i;
203         unsigned int num_streams;
204         TALLOC_CTX *frame = talloc_stackframe();
205         NTSTATUS status;
206
207         status = SMB_VFS_STREAMINFO(conn, NULL, fname, talloc_tos(),
208                                     &num_streams, &stream_info);
209
210         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)) {
211                 DEBUG(10, ("no streams around\n"));
212                 TALLOC_FREE(frame);
213                 return NT_STATUS_OK;
214         }
215
216         if (!NT_STATUS_IS_OK(status)) {
217                 DEBUG(10, ("SMB_VFS_STREAMINFO failed: %s\n",
218                            nt_errstr(status)));
219                 goto fail;
220         }
221
222         DEBUG(10, ("delete_all_streams found %d streams\n",
223                    num_streams));
224
225         if (num_streams == 0) {
226                 TALLOC_FREE(frame);
227                 return NT_STATUS_OK;
228         }
229
230         for (i=0; i<num_streams; i++) {
231                 int res;
232                 struct smb_filename *smb_fname_stream = NULL;
233
234                 if (strequal(stream_info[i].name, "::$DATA")) {
235                         continue;
236                 }
237
238                 status = create_synthetic_smb_fname(talloc_tos(), fname,
239                                                     stream_info[i].name, NULL,
240                                                     &smb_fname_stream);
241
242                 if (!NT_STATUS_IS_OK(status)) {
243                         DEBUG(0, ("talloc_aprintf failed\n"));
244                         goto fail;
245                 }
246
247                 res = SMB_VFS_UNLINK(conn, smb_fname_stream);
248
249                 if (res == -1) {
250                         status = map_nt_error_from_unix(errno);
251                         DEBUG(10, ("Could not delete stream %s: %s\n",
252                                    smb_fname_str_dbg(smb_fname_stream),
253                                    strerror(errno)));
254                         TALLOC_FREE(smb_fname_stream);
255                         break;
256                 }
257                 TALLOC_FREE(smb_fname_stream);
258         }
259
260  fail:
261         TALLOC_FREE(frame);
262         return status;
263 }
264
265 /****************************************************************************
266  Deal with removing a share mode on last close.
267 ****************************************************************************/
268
269 static NTSTATUS close_remove_share_mode(files_struct *fsp,
270                                         enum file_close_type close_type)
271 {
272         connection_struct *conn = fsp->conn;
273         bool delete_file = false;
274         bool changed_user = false;
275         struct share_mode_lock *lck = NULL;
276         NTSTATUS status = NT_STATUS_OK;
277         int ret;
278         struct file_id id;
279
280         /*
281          * Lock the share entries, and determine if we should delete
282          * on close. If so delete whilst the lock is still in effect.
283          * This prevents race conditions with the file being created. JRA.
284          */
285
286         lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL,
287                                   NULL);
288
289         if (lck == NULL) {
290                 DEBUG(0, ("close_remove_share_mode: Could not get share mode "
291                           "lock for file %s\n", fsp_str_dbg(fsp)));
292                 status = NT_STATUS_INVALID_PARAMETER;
293                 goto done;
294         }
295
296         if (fsp->write_time_forced) {
297                 set_close_write_time(fsp, lck->changed_write_time);
298         }
299
300         if (!del_share_mode(lck, fsp)) {
301                 DEBUG(0, ("close_remove_share_mode: Could not delete share "
302                           "entry for file %s\n",
303                           fsp_str_dbg(fsp)));
304         }
305
306         if (fsp->initial_delete_on_close && (lck->delete_token == NULL)) {
307                 bool became_user = False;
308
309                 /* Initial delete on close was set and no one else
310                  * wrote a real delete on close. */
311
312                 if (current_user.vuid != fsp->vuid) {
313                         become_user(conn, fsp->vuid);
314                         became_user = True;
315                 }
316                 set_delete_on_close_lck(lck, True, &current_user.ut);
317                 if (became_user) {
318                         unbecome_user();
319                 }
320         }
321
322         delete_file = lck->delete_on_close;
323
324         if (delete_file) {
325                 int i;
326                 /* See if others still have the file open. If this is the
327                  * case, then don't delete. If all opens are POSIX delete now. */
328                 for (i=0; i<lck->num_share_modes; i++) {
329                         struct share_mode_entry *e = &lck->share_modes[i];
330                         if (is_valid_share_mode_entry(e)) {
331                                 if (fsp->posix_open && (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) {
332                                         continue;
333                                 }
334                                 delete_file = False;
335                                 break;
336                         }
337                 }
338         }
339
340         /* Notify any deferred opens waiting on this close. */
341         notify_deferred_opens(lck);
342         reply_to_oplock_break_requests(fsp);
343
344         /*
345          * NT can set delete_on_close of the last open
346          * reference to a file.
347          */
348
349         if (!(close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE)
350             || !delete_file
351             || (lck->delete_token == NULL)) {
352                 TALLOC_FREE(lck);
353                 return NT_STATUS_OK;
354         }
355
356         /*
357          * Ok, we have to delete the file
358          */
359
360         DEBUG(5,("close_remove_share_mode: file %s. Delete on close was set "
361                  "- deleting file.\n", fsp_str_dbg(fsp)));
362
363         /*
364          * Don't try to update the write time when we delete the file
365          */
366         fsp->update_write_time_on_close = false;
367
368         if (!unix_token_equal(lck->delete_token, &current_user.ut)) {
369                 /* Become the user who requested the delete. */
370
371                 DEBUG(5,("close_remove_share_mode: file %s. "
372                         "Change user to uid %u\n",
373                         fsp_str_dbg(fsp),
374                         (unsigned int)lck->delete_token->uid));
375
376                 if (!push_sec_ctx()) {
377                         smb_panic("close_remove_share_mode: file %s. failed to push "
378                                   "sec_ctx.\n");
379                 }
380
381                 set_sec_ctx(lck->delete_token->uid,
382                             lck->delete_token->gid,
383                             lck->delete_token->ngroups,
384                             lck->delete_token->groups,
385                             NULL);
386
387                 changed_user = true;
388         }
389
390         /* We can only delete the file if the name we have is still valid and
391            hasn't been renamed. */
392
393         if (fsp->posix_open) {
394                 ret = SMB_VFS_LSTAT(conn, fsp->fsp_name);
395         } else {
396                 ret = SMB_VFS_STAT(conn, fsp->fsp_name);
397         }
398
399         if (ret != 0) {
400                 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
401                          "was set and stat failed with error %s\n",
402                          fsp_str_dbg(fsp), strerror(errno)));
403                 /*
404                  * Don't save the errno here, we ignore this error
405                  */
406                 goto done;
407         }
408
409         id = vfs_file_id_from_sbuf(conn, &fsp->fsp_name->st);
410
411         if (!file_id_equal(&fsp->file_id, &id)) {
412                 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
413                          "was set and dev and/or inode does not match\n",
414                          fsp_str_dbg(fsp)));
415                 DEBUG(5,("close_remove_share_mode: file %s. stored file_id %s, "
416                          "stat file_id %s\n",
417                          fsp_str_dbg(fsp),
418                          file_id_string_tos(&fsp->file_id),
419                          file_id_string_tos(&id)));
420                 /*
421                  * Don't save the errno here, we ignore this error
422                  */
423                 goto done;
424         }
425
426         if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
427             && !is_ntfs_stream_smb_fname(fsp->fsp_name)) {
428
429                 status = delete_all_streams(conn, fsp->fsp_name->base_name);
430
431                 if (!NT_STATUS_IS_OK(status)) {
432                         DEBUG(5, ("delete_all_streams failed: %s\n",
433                                   nt_errstr(status)));
434                         goto done;
435                 }
436         }
437
438
439         if (SMB_VFS_UNLINK(conn, fsp->fsp_name) != 0) {
440                 /*
441                  * This call can potentially fail as another smbd may
442                  * have had the file open with delete on close set and
443                  * deleted it when its last reference to this file
444                  * went away. Hence we log this but not at debug level
445                  * zero.
446                  */
447
448                 DEBUG(5,("close_remove_share_mode: file %s. Delete on close "
449                          "was set and unlink failed with error %s\n",
450                          fsp_str_dbg(fsp), strerror(errno)));
451
452                 status = map_nt_error_from_unix(errno);
453         }
454
455         notify_fname(conn, NOTIFY_ACTION_REMOVED,
456                      FILE_NOTIFY_CHANGE_FILE_NAME,
457                      fsp->fsp_name->base_name);
458
459         /* As we now have POSIX opens which can unlink
460          * with other open files we may have taken
461          * this code path with more than one share mode
462          * entry - ensure we only delete once by resetting
463          * the delete on close flag. JRA.
464          */
465
466         set_delete_on_close_lck(lck, False, NULL);
467
468  done:
469
470         if (changed_user) {
471                 /* unbecome user. */
472                 pop_sec_ctx();
473         }
474
475         TALLOC_FREE(lck);
476         return status;
477 }
478
479 void set_close_write_time(struct files_struct *fsp, struct timespec ts)
480 {
481         DEBUG(6,("close_write_time: %s" , time_to_asc(convert_timespec_to_time_t(ts))));
482
483         if (null_timespec(ts)) {
484                 return;
485         }
486         /*
487          * if the write time on close is explict set, then don't
488          * need to fix it up to the value in the locking db
489          */
490         fsp->write_time_forced = false;
491
492         fsp->update_write_time_on_close = true;
493         fsp->close_write_time = ts;
494 }
495
496 static NTSTATUS update_write_time_on_close(struct files_struct *fsp)
497 {
498         struct smb_file_time ft;
499         NTSTATUS status;
500         int ret = -1;
501
502         ZERO_STRUCT(ft);
503
504         if (!fsp->update_write_time_on_close) {
505                 return NT_STATUS_OK;
506         }
507
508         if (null_timespec(fsp->close_write_time)) {
509                 fsp->close_write_time = timespec_current();
510         }
511
512         /* Ensure we have a valid stat struct for the source. */
513         if (fsp->fh->fd != -1) {
514                 ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st);
515         } else {
516                 if (fsp->posix_open) {
517                         ret = SMB_VFS_LSTAT(fsp->conn, fsp->fsp_name);
518                 } else {
519                         ret = SMB_VFS_STAT(fsp->conn, fsp->fsp_name);
520                 }
521         }
522
523         if (ret == -1) {
524                 return map_nt_error_from_unix(errno);
525         }
526
527         if (!VALID_STAT(fsp->fsp_name->st)) {
528                 /* if it doesn't seem to be a real file */
529                 return NT_STATUS_OK;
530         }
531
532         ft.mtime = fsp->close_write_time;
533         status = smb_set_file_time(fsp->conn, fsp, fsp->fsp_name, &ft, true);
534         if (!NT_STATUS_IS_OK(status)) {
535                 return status;
536         }
537
538         return status;
539 }
540
541 static NTSTATUS ntstatus_keeperror(NTSTATUS s1, NTSTATUS s2)
542 {
543         if (!NT_STATUS_IS_OK(s1)) {
544                 return s1;
545         }
546         return s2;
547 }
548
549 /****************************************************************************
550  Close a file.
551
552  close_type can be NORMAL_CLOSE=0,SHUTDOWN_CLOSE,ERROR_CLOSE.
553  printing and magic scripts are only run on normal close.
554  delete on close is done on normal and shutdown close.
555 ****************************************************************************/
556
557 static NTSTATUS close_normal_file(struct smb_request *req, files_struct *fsp,
558                                   enum file_close_type close_type)
559 {
560         NTSTATUS status = NT_STATUS_OK;
561         NTSTATUS tmp;
562         connection_struct *conn = fsp->conn;
563
564         if (fsp->aio_write_behind) {
565                 /*
566                  * If we're finishing write behind on a close we can get a write
567                  * error here, we must remember this.
568                  */
569                 int ret = wait_for_aio_completion(fsp);
570                 if (ret) {
571                         status = ntstatus_keeperror(
572                                 status, map_nt_error_from_unix(ret));
573                 }
574         } else {
575                 cancel_aio_by_fsp(fsp);
576         }
577  
578         /*
579          * If we're flushing on a close we can get a write
580          * error here, we must remember this.
581          */
582
583         tmp = close_filestruct(fsp);
584         status = ntstatus_keeperror(status, tmp);
585
586         if (fsp->print_file) {
587                 print_fsp_end(fsp, close_type);
588                 file_free(req, fsp);
589                 return NT_STATUS_OK;
590         }
591
592         /* Remove the oplock before potentially deleting the file. */
593         if(fsp->oplock_type) {
594                 release_file_oplock(fsp);
595         }
596
597         /* If this is an old DOS or FCB open and we have multiple opens on
598            the same handle we only have one share mode. Ensure we only remove
599            the share mode on the last close. */
600
601         if (fsp->fh->ref_count == 1) {
602                 /* Should we return on error here... ? */
603                 tmp = close_remove_share_mode(fsp, close_type);
604                 status = ntstatus_keeperror(status, tmp);
605         }
606
607         locking_close_file(smbd_messaging_context(), fsp);
608
609         tmp = fd_close(fsp);
610         status = ntstatus_keeperror(status, tmp);
611
612         /* check for magic scripts */
613         if (close_type == NORMAL_CLOSE) {
614                 tmp = check_magic(fsp);
615                 status = ntstatus_keeperror(status, tmp);
616         }
617
618         /*
619          * Ensure pending modtime is set after close.
620          */
621
622         tmp = update_write_time_on_close(fsp);
623         if (NT_STATUS_EQUAL(tmp, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
624                 /* Someone renamed the file or a parent directory containing
625                  * this file. We can't do anything about this, we don't have
626                  * an "update timestamp by fd" call in POSIX. Eat the error. */
627
628                 tmp = NT_STATUS_OK;
629         }
630
631         status = ntstatus_keeperror(status, tmp);
632
633         DEBUG(2,("%s closed file %s (numopen=%d) %s\n",
634                 conn->server_info->unix_name, fsp_str_dbg(fsp),
635                 conn->num_files_open - 1,
636                 nt_errstr(status) ));
637
638         file_free(req, fsp);
639         return status;
640 }
641
642 /****************************************************************************
643  Close a directory opened by an NT SMB call. 
644 ****************************************************************************/
645   
646 static NTSTATUS close_directory(struct smb_request *req, files_struct *fsp,
647                                 enum file_close_type close_type)
648 {
649         struct share_mode_lock *lck = NULL;
650         bool delete_dir = False;
651         NTSTATUS status = NT_STATUS_OK;
652
653         /*
654          * NT can set delete_on_close of the last open
655          * reference to a directory also.
656          */
657
658         lck = get_share_mode_lock(talloc_tos(), fsp->file_id, NULL, NULL,
659                                   NULL);
660
661         if (lck == NULL) {
662                 DEBUG(0, ("close_directory: Could not get share mode lock for "
663                           "%s\n", fsp_str_dbg(fsp)));
664                 status = NT_STATUS_INVALID_PARAMETER;
665                 goto out;
666         }
667
668         if (!del_share_mode(lck, fsp)) {
669                 DEBUG(0, ("close_directory: Could not delete share entry for "
670                           "%s\n", fsp_str_dbg(fsp)));
671         }
672
673         if (fsp->initial_delete_on_close) {
674                 bool became_user = False;
675
676                 /* Initial delete on close was set - for
677                  * directories we don't care if anyone else
678                  * wrote a real delete on close. */
679
680                 if (current_user.vuid != fsp->vuid) {
681                         become_user(fsp->conn, fsp->vuid);
682                         became_user = True;
683                 }
684                 send_stat_cache_delete_message(fsp->fsp_name->base_name);
685                 set_delete_on_close_lck(lck, True, &current_user.ut);
686                 if (became_user) {
687                         unbecome_user();
688                 }
689         }
690
691         delete_dir = lck->delete_on_close;
692
693         if (delete_dir) {
694                 int i;
695                 /* See if others still have the dir open. If this is the
696                  * case, then don't delete. If all opens are POSIX delete now. */
697                 for (i=0; i<lck->num_share_modes; i++) {
698                         struct share_mode_entry *e = &lck->share_modes[i];
699                         if (is_valid_share_mode_entry(e)) {
700                                 if (fsp->posix_open && (e->flags & SHARE_MODE_FLAG_POSIX_OPEN)) {
701                                         continue;
702                                 }
703                                 delete_dir = False;
704                                 break;
705                         }
706                 }
707         }
708
709         if ((close_type == NORMAL_CLOSE || close_type == SHUTDOWN_CLOSE) &&
710                                 delete_dir &&
711                                 lck->delete_token) {
712         
713                 /* Become the user who requested the delete. */
714
715                 if (!push_sec_ctx()) {
716                         smb_panic("close_directory: failed to push sec_ctx.\n");
717                 }
718
719                 set_sec_ctx(lck->delete_token->uid,
720                                 lck->delete_token->gid,
721                                 lck->delete_token->ngroups,
722                                 lck->delete_token->groups,
723                                 NULL);
724
725                 TALLOC_FREE(lck);
726
727                 status = rmdir_internals(talloc_tos(), fsp->conn,
728                                          fsp->fsp_name);
729
730                 DEBUG(5,("close_directory: %s. Delete on close was set - "
731                          "deleting directory returned %s.\n",
732                          fsp_str_dbg(fsp), nt_errstr(status)));
733
734                 /* unbecome user. */
735                 pop_sec_ctx();
736
737                 /*
738                  * Ensure we remove any change notify requests that would
739                  * now fail as the directory has been deleted.
740                  */
741
742                 if(NT_STATUS_IS_OK(status)) {
743                         remove_pending_change_notify_requests_by_fid(fsp, NT_STATUS_DELETE_PENDING);
744                 }
745         } else {
746                 TALLOC_FREE(lck);
747                 remove_pending_change_notify_requests_by_fid(
748                         fsp, NT_STATUS_OK);
749         }
750
751         status = fd_close(fsp);
752
753         if (!NT_STATUS_IS_OK(status)) {
754                 DEBUG(0, ("Could not close dir! fname=%s, fd=%d, err=%d=%s\n",
755                           fsp_str_dbg(fsp), fsp->fh->fd, errno,
756                           strerror(errno)));
757         }
758
759         /*
760          * Do the code common to files and directories.
761          */
762         close_filestruct(fsp);
763         file_free(req, fsp);
764
765  out:
766         TALLOC_FREE(lck);
767         return status;
768 }
769
770 /****************************************************************************
771  Close a files_struct.
772 ****************************************************************************/
773   
774 NTSTATUS close_file(struct smb_request *req, files_struct *fsp,
775                     enum file_close_type close_type)
776 {
777         NTSTATUS status;
778         struct files_struct *base_fsp = fsp->base_fsp;
779
780         if(fsp->is_directory) {
781                 status = close_directory(req, fsp, close_type);
782         } else if (fsp->fake_file_handle != NULL) {
783                 status = close_fake_file(req, fsp);
784         } else {
785                 status = close_normal_file(req, fsp, close_type);
786         }
787
788         if ((base_fsp != NULL) && (close_type != SHUTDOWN_CLOSE)) {
789
790                 /*
791                  * fsp was a stream, the base fsp can't be a stream as well
792                  *
793                  * For SHUTDOWN_CLOSE this is not possible here, because
794                  * SHUTDOWN_CLOSE only happens from files.c which walks the
795                  * complete list of files. If we mess with more than one fsp
796                  * those loops will become confused.
797                  */
798
799                 SMB_ASSERT(base_fsp->base_fsp == NULL);
800                 close_file(req, base_fsp, close_type);
801         }
802
803         return status;
804 }
805
806 /****************************************************************************
807  Deal with an (authorized) message to close a file given the share mode
808  entry.
809 ****************************************************************************/
810
811 void msg_close_file(struct messaging_context *msg_ctx,
812                         void *private_data,
813                         uint32_t msg_type,
814                         struct server_id server_id,
815                         DATA_BLOB *data)
816 {
817         files_struct *fsp = NULL;
818         struct share_mode_entry e;
819
820         message_to_share_mode_entry(&e, (char *)data->data);
821
822         if(DEBUGLVL(10)) {
823                 char *sm_str = share_mode_str(NULL, 0, &e);
824                 if (!sm_str) {
825                         smb_panic("talloc failed");
826                 }
827                 DEBUG(10,("msg_close_file: got request to close share mode "
828                         "entry %s\n", sm_str));
829                 TALLOC_FREE(sm_str);
830         }
831
832         fsp = file_find_dif(e.id, e.share_file_id);
833         if (!fsp) {
834                 DEBUG(10,("msg_close_file: failed to find file.\n"));
835                 return;
836         }
837         close_file(NULL, fsp, NORMAL_CLOSE);
838 }