2 Unix SMB/CIFS implementation.
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Jeremy Allison 1992-2007.
6 Copyright (C) Volker Lendecke 2005
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.
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.
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/>.
23 #include "system/filesys.h"
24 #include "lib/util/server_id.h"
26 #include "locking/share_mode_lock.h"
27 #include "smbd/smbd.h"
28 #include "smbd/globals.h"
29 #include "smbd/smbXsrv_open.h"
30 #include "smbd/scavenger.h"
31 #include "fake_file.h"
32 #include "transfer_file.h"
35 #include "librpc/gen_ndr/ndr_open_files.h"
36 #include "lib/util/tevent_ntstatus.h"
37 #include "source3/smbd/dir.h"
39 /****************************************************************************
40 Run a file if it is a magic script.
41 ****************************************************************************/
43 static NTSTATUS
check_magic(struct files_struct
*fsp
)
46 const struct loadparm_substitution
*lp_sub
=
47 loadparm_s3_global_substitution();
48 const char *magic_output
= NULL
;
51 TALLOC_CTX
*ctx
= NULL
;
53 struct connection_struct
*conn
= fsp
->conn
;
57 if (!*lp_magic_script(talloc_tos(), lp_sub
, SNUM(conn
))) {
61 DEBUG(5,("checking magic for %s\n", fsp_str_dbg(fsp
)));
63 ctx
= talloc_stackframe();
65 fname
= fsp
->fsp_name
->base_name
;
67 if (!(p
= strrchr_m(fname
,'/'))) {
73 if (!strequal(lp_magic_script(talloc_tos(), lp_sub
, SNUM(conn
)),p
)) {
74 status
= NT_STATUS_OK
;
78 if (*lp_magic_output(talloc_tos(), lp_sub
, SNUM(conn
))) {
79 magic_output
= lp_magic_output(talloc_tos(), lp_sub
, SNUM(conn
));
81 magic_output
= talloc_asprintf(ctx
,
86 status
= NT_STATUS_NO_MEMORY
;
90 /* Ensure we don't depend on user's PATH. */
91 p
= talloc_asprintf(ctx
, "./%s", fname
);
93 status
= NT_STATUS_NO_MEMORY
;
97 if (chmod(fname
, 0755) == -1) {
98 status
= map_nt_error_from_unix(errno
);
101 ret
= smbrun(p
, &tmp_fd
, NULL
);
102 DEBUG(3,("Invoking magic command %s gave %d\n",
106 if (ret
!= 0 || tmp_fd
== -1) {
110 status
= NT_STATUS_UNSUCCESSFUL
;
113 outfd
= open(magic_output
, O_CREAT
|O_EXCL
|O_RDWR
, 0600);
117 status
= map_nt_error_from_unix(err
);
121 if (sys_fstat(tmp_fd
, &st
, false) == -1) {
125 status
= map_nt_error_from_unix(err
);
129 if (transfer_file(tmp_fd
,outfd
,(off_t
)st
.st_ex_size
) == (off_t
)-1) {
133 status
= map_nt_error_from_unix(err
);
137 if (close(outfd
) == -1) {
138 status
= map_nt_error_from_unix(errno
);
142 status
= NT_STATUS_OK
;
149 /****************************************************************************
151 ****************************************************************************/
153 NTSTATUS
delete_all_streams(connection_struct
*conn
,
154 const struct smb_filename
*smb_fname
)
156 struct stream_struct
*stream_info
= NULL
;
158 unsigned int num_streams
= 0;
159 TALLOC_CTX
*frame
= talloc_stackframe();
162 status
= vfs_fstreaminfo(smb_fname
->fsp
, talloc_tos(),
163 &num_streams
, &stream_info
);
165 if (NT_STATUS_EQUAL(status
, NT_STATUS_NOT_IMPLEMENTED
)) {
166 DEBUG(10, ("no streams around\n"));
171 if (!NT_STATUS_IS_OK(status
)) {
172 DEBUG(10, ("vfs_fstreaminfo failed: %s\n",
177 DEBUG(10, ("delete_all_streams found %d streams\n",
180 if (num_streams
== 0) {
185 for (i
=0; i
<num_streams
; i
++) {
187 struct smb_filename
*smb_fname_stream
;
189 if (strequal(stream_info
[i
].name
, "::$DATA")) {
193 status
= synthetic_pathref(talloc_tos(),
195 smb_fname
->base_name
,
200 ~SMB_FILENAME_POSIX_PATH
),
202 if (!NT_STATUS_IS_OK(status
)) {
203 DEBUG(0, ("talloc_aprintf failed\n"));
204 status
= NT_STATUS_NO_MEMORY
;
208 res
= SMB_VFS_UNLINKAT(conn
,
214 status
= map_nt_error_from_unix(errno
);
215 DEBUG(10, ("Could not delete stream %s: %s\n",
216 smb_fname_str_dbg(smb_fname_stream
),
218 TALLOC_FREE(smb_fname_stream
);
221 TALLOC_FREE(smb_fname_stream
);
229 struct has_other_nonposix_opens_state
{
234 static bool has_other_nonposix_opens_fn(
235 struct share_mode_entry
*e
,
239 struct has_other_nonposix_opens_state
*state
= private_data
;
240 struct files_struct
*fsp
= state
->fsp
;
242 if (e
->flags
& SHARE_MODE_FLAG_POSIX_OPEN
) {
246 if (e
->name_hash
!= fsp
->name_hash
) {
249 if (e
->share_file_id
== fh_get_gen_id(fsp
->fh
)) {
250 struct server_id self
= messaging_server_id(
251 fsp
->conn
->sconn
->msg_ctx
);
252 if (server_id_equal(&self
, &e
->pid
)) {
257 if (share_entry_stale_pid(e
)) {
261 state
->found_another
= true;
265 bool has_other_nonposix_opens(struct share_mode_lock
*lck
,
266 struct files_struct
*fsp
)
268 struct has_other_nonposix_opens_state state
= { .fsp
= fsp
};
271 ok
= share_mode_forall_entries(
272 lck
, has_other_nonposix_opens_fn
, &state
);
276 return state
.found_another
;
279 bool has_nonposix_opens(struct share_mode_lock
*lck
)
281 struct has_other_nonposix_opens_state state
= {};
284 ok
= share_mode_forall_entries(
285 lck
, has_other_nonposix_opens_fn
, &state
);
289 return state
.found_another
;
292 struct close_share_mode_lock_state
{
293 struct share_mode_entry_prepare_state prepare_state
;
294 const char *object_type
;
295 struct files_struct
*fsp
;
296 enum file_close_type close_type
;
299 struct smb2_lease_key parent_lease_key
;
300 const struct security_unix_token
*del_token
;
301 const struct security_token
*del_nt_token
;
302 bool reset_delete_on_close
;
303 share_mode_entry_prepare_unlock_fn_t cleanup_fn
;
306 static void close_share_mode_lock_prepare(struct share_mode_lock
*lck
,
310 struct close_share_mode_lock_state
*state
=
311 (struct close_share_mode_lock_state
*)private_data
;
312 struct files_struct
*fsp
= state
->fsp
;
317 * By default drop the g_lock again if we leave the
320 *keep_locked
= false;
322 if (fsp
->oplock_type
!= NO_OPLOCK
) {
323 ok
= remove_share_oplock(lck
, fsp
);
325 struct file_id_buf buf
;
327 DBG_ERR("failed to remove share oplock for "
330 fsp_str_dbg(fsp
), fsp_fnum_dbg(fsp
),
331 file_id_str_buf(fsp
->file_id
, &buf
));
335 if (fsp
->fsp_flags
.write_time_forced
) {
336 NTTIME mtime
= share_mode_changed_write_time(lck
);
337 struct timespec ts
= nt_time_to_full_timespec(mtime
);
339 DBG_DEBUG("write time forced for %s %s\n",
340 state
->object_type
, fsp_str_dbg(fsp
));
341 set_close_write_time(fsp
, ts
);
342 } else if (fsp
->fsp_flags
.update_write_time_on_close
) {
343 /* Someone had a pending write. */
344 if (is_omit_timespec(&fsp
->close_write_time
)) {
345 DBG_DEBUG("update to current time for %s %s\n",
346 state
->object_type
, fsp_str_dbg(fsp
));
347 /* Update to current time due to "normal" write. */
348 set_close_write_time(fsp
, timespec_current());
350 DBG_DEBUG("write time pending for %s %s\n",
351 state
->object_type
, fsp_str_dbg(fsp
));
352 /* Update to time set on close call. */
353 set_close_write_time(fsp
, fsp
->close_write_time
);
357 if (fsp
->fsp_flags
.initial_delete_on_close
&&
358 !is_delete_on_close_set(lck
, fsp
->name_hash
)) {
359 /* Initial delete on close was set and no one else
360 * wrote a real delete on close. */
362 fsp
->fsp_flags
.delete_on_close
= true;
363 set_delete_on_close_lck(fsp
, lck
,
364 fsp
->conn
->session_info
->security_token
,
365 fsp
->conn
->session_info
->unix_token
);
368 state
->delete_object
= is_delete_on_close_set(lck
, fsp
->name_hash
) &&
369 !has_other_nonposix_opens(lck
, fsp
);
372 * NT can set delete_on_close of the last open
373 * reference to a file.
376 normal_close
= (state
->close_type
== NORMAL_CLOSE
|| state
->close_type
== SHUTDOWN_CLOSE
);
379 * Never try to delete the file/directory for ERROR_CLOSE
381 state
->delete_object
= false;
384 if (!state
->delete_object
) {
385 ok
= del_share_mode(lck
, fsp
);
387 DBG_ERR("Could not delete share entry for %s %s\n",
388 state
->object_type
, fsp_str_dbg(fsp
));
394 * We're going to remove the file/directory
395 * so keep the g_lock after the tdb chainlock
396 * is left, so we hold the share_mode_lock
397 * also during the deletion
401 state
->got_tokens
= get_delete_on_close_token(lck
,
403 &state
->del_nt_token
,
405 &state
->parent_lease_key
);
406 if (state
->close_type
!= ERROR_CLOSE
) {
407 SMB_ASSERT(state
->got_tokens
);
411 static void close_share_mode_lock_cleanup(struct share_mode_lock
*lck
,
414 struct close_share_mode_lock_state
*state
=
415 (struct close_share_mode_lock_state
*)private_data
;
416 struct files_struct
*fsp
= state
->fsp
;
419 if (state
->reset_delete_on_close
) {
420 reset_delete_on_close_lck(fsp
, lck
);
423 ok
= del_share_mode(lck
, fsp
);
425 DBG_ERR("Could not delete share entry for %s %s\n",
426 state
->object_type
, fsp_str_dbg(fsp
));
430 /****************************************************************************
431 Deal with removing a share mode on last close.
432 ****************************************************************************/
434 static NTSTATUS
close_remove_share_mode(files_struct
*fsp
,
435 enum file_close_type close_type
)
437 connection_struct
*conn
= fsp
->conn
;
438 struct close_share_mode_lock_state lck_state
= {};
439 bool changed_user
= false;
440 NTSTATUS status
= NT_STATUS_OK
;
444 struct smb_filename
*parent_fname
= NULL
;
445 struct smb_filename
*base_fname
= NULL
;
448 /* Ensure any pending write time updates are done. */
449 if (fsp
->update_write_time_event
) {
450 fsp_flush_write_time_update(fsp
);
454 * Lock the share entries, and determine if we should delete
455 * on close. If so delete whilst the lock is still in effect.
456 * This prevents race conditions with the file being created. JRA.
459 lck_state
= (struct close_share_mode_lock_state
) {
461 .object_type
= "file",
462 .close_type
= close_type
,
465 status
= share_mode_entry_prepare_lock_del(&lck_state
.prepare_state
,
467 close_share_mode_lock_prepare
,
469 if (!NT_STATUS_IS_OK(status
)) {
470 DBG_ERR("share_mode_entry_prepare_lock_del() failed for %s - %s\n",
471 fsp_str_dbg(fsp
), nt_errstr(status
));
475 /* Remove the oplock before potentially deleting the file. */
476 if (fsp
->oplock_type
!= NO_OPLOCK
) {
477 release_file_oplock(fsp
);
481 * NT can set delete_on_close of the last open
482 * reference to a file.
485 if (!lck_state
.delete_object
) {
486 status
= NT_STATUS_OK
;
491 * Ok, we have to delete the file
493 lck_state
.cleanup_fn
= close_share_mode_lock_cleanup
;
495 DBG_INFO("%s. Delete on close was set - deleting file.\n",
499 * Don't try to update the write time when we delete the file
501 fsp
->fsp_flags
.update_write_time_on_close
= false;
503 if (lck_state
.got_tokens
&&
504 !unix_token_equal(lck_state
.del_token
, get_current_utok(conn
)))
506 /* Become the user who requested the delete. */
508 DBG_INFO("file %s. Change user to uid %u\n",
510 (unsigned int)lck_state
.del_token
->uid
);
512 if (!push_sec_ctx()) {
513 smb_panic("close_remove_share_mode: file %s. failed to push "
517 set_sec_ctx(lck_state
.del_token
->uid
,
518 lck_state
.del_token
->gid
,
519 lck_state
.del_token
->ngroups
,
520 lck_state
.del_token
->groups
,
521 lck_state
.del_nt_token
);
526 /* We can only delete the file if the name we have is still valid and
527 hasn't been renamed. */
529 tmp_status
= vfs_stat_fsp(fsp
);
530 if (!NT_STATUS_IS_OK(tmp_status
)) {
531 DBG_INFO("file %s. Delete on close "
532 "was set and stat failed with error %s\n",
534 nt_errstr(tmp_status
));
536 * Don't save the errno here, we ignore this error
541 id
= vfs_file_id_from_sbuf(conn
, &fsp
->fsp_name
->st
);
543 if (!file_id_equal(&fsp
->file_id
, &id
)) {
544 struct file_id_buf ftmp1
, ftmp2
;
545 DBG_INFO("file %s. Delete on close "
546 "was set and dev and/or inode does not match\n",
548 DBG_INFO("file %s. stored file_id %s, stat file_id %s\n",
550 file_id_str_buf(fsp
->file_id
, &ftmp1
),
551 file_id_str_buf(id
, &ftmp2
));
553 * Don't save the errno here, we ignore this error
558 if ((conn
->fs_capabilities
& FILE_NAMED_STREAMS
)
559 && !fsp_is_alternate_stream(fsp
)) {
561 status
= delete_all_streams(conn
, fsp
->fsp_name
);
563 if (!NT_STATUS_IS_OK(status
)) {
564 DEBUG(5, ("delete_all_streams failed: %s\n",
570 if (fsp
->fsp_flags
.kernel_share_modes_taken
) {
572 * A file system sharemode could block the unlink;
573 * remove filesystem sharemodes first.
575 ret
= SMB_VFS_FILESYSTEM_SHAREMODE(fsp
, 0, 0);
577 DBG_INFO("Removing file system sharemode for %s "
579 fsp_str_dbg(fsp
), strerror(errno
));
582 fsp
->fsp_flags
.kernel_share_modes_taken
= false;
585 status
= parent_pathref(talloc_tos(),
590 if (!NT_STATUS_IS_OK(status
)) {
594 ret
= SMB_VFS_UNLINKAT(conn
,
598 TALLOC_FREE(parent_fname
);
602 * This call can potentially fail as another smbd may
603 * have had the file open with delete on close set and
604 * deleted it when its last reference to this file
605 * went away. Hence we log this but not at debug level
609 DBG_INFO("file %s. Delete on close "
610 "was set and unlink failed with error %s\n",
614 status
= map_nt_error_from_unix(errno
);
617 /* As we now have POSIX opens which can unlink
618 * with other open files we may have taken
619 * this code path with more than one share mode
620 * entry - ensure we only delete once by resetting
621 * the delete on close flag. JRA.
624 fsp
->fsp_flags
.delete_on_close
= false;
625 fsp
->fsp_flags
.fstat_before_close
= false;
626 lck_state
.reset_delete_on_close
= true;
635 if (fsp
->fsp_flags
.kernel_share_modes_taken
) {
636 /* remove filesystem sharemodes */
637 ret
= SMB_VFS_FILESYSTEM_SHAREMODE(fsp
, 0, 0);
639 DBG_INFO("Removing file system sharemode for "
641 fsp_str_dbg(fsp
), strerror(errno
));
645 ulstatus
= share_mode_entry_prepare_unlock(&lck_state
.prepare_state
,
646 lck_state
.cleanup_fn
,
648 if (!NT_STATUS_IS_OK(ulstatus
)) {
649 DBG_ERR("share_mode_entry_prepare_unlock() failed for %s - %s\n",
650 fsp_str_dbg(fsp
), nt_errstr(ulstatus
));
651 smb_panic("share_mode_entry_prepare_unlock() failed!");
654 if (lck_state
.delete_object
&& NT_STATUS_IS_OK(status
)) {
655 const struct smb2_lease
*lease
= fsp_get_smb2_lease(fsp
);
659 * If parent lease key of handle on which delete
660 * disposition was set does not match the parent key of
661 * last closed handle, break all leases on the parent
664 if (!smb2_lease_key_equal(&lease
->parent_lease_key
,
665 &lck_state
.parent_lease_key
))
671 NOTIFY_ACTION_REMOVED
|
672 NOTIFY_ACTION_DIRLEASE_BREAK
,
673 FILE_NOTIFY_CHANGE_FILE_NAME
,
681 void set_close_write_time(struct files_struct
*fsp
, struct timespec ts
)
683 DEBUG(6,("close_write_time: %s" , time_to_asc(convert_timespec_to_time_t(ts
))));
685 if (is_omit_timespec(&ts
)) {
688 fsp
->fsp_flags
.write_time_forced
= false;
689 fsp
->fsp_flags
.update_write_time_on_close
= true;
690 fsp
->close_write_time
= ts
;
693 static void update_write_time_on_close_share_mode_fn(struct share_mode_lock
*lck
,
696 struct files_struct
*fsp
=
697 talloc_get_type_abort(private_data
,
698 struct files_struct
);
699 NTTIME share_mtime
= share_mode_changed_write_time(lck
);
702 * On close if we're changing the real file time we
703 * must update it in the open file db too.
705 share_mode_set_old_write_time(lck
, fsp
->close_write_time
);
708 * Close write times overwrite sticky write times
709 * so we must replace any sticky write time here.
711 if (!null_nttime(share_mtime
)) {
712 share_mode_set_changed_write_time(lck
, fsp
->close_write_time
);
716 static NTSTATUS
update_write_time_on_close(struct files_struct
*fsp
)
718 struct smb_file_time ft
;
721 init_smb_file_time(&ft
);
723 if (!(fsp
->fsp_flags
.update_write_time_on_close
)) {
727 if (is_omit_timespec(&fsp
->close_write_time
)) {
728 fsp
->close_write_time
= timespec_current();
731 /* Ensure we have a valid stat struct for the source. */
732 status
= vfs_stat_fsp(fsp
);
733 if (!NT_STATUS_IS_OK(status
)) {
737 if (!VALID_STAT(fsp
->fsp_name
->st
)) {
738 /* if it doesn't seem to be a real file */
743 * We're being called after close_remove_share_mode() inside
744 * close_normal_file() so it's quite normal to not have an
745 * existing share. So just ignore the result of
746 * share_mode_do_locked_vfs_denied()...
748 share_mode_do_locked_vfs_denied(fsp
->file_id
,
749 update_write_time_on_close_share_mode_fn
,
752 ft
.mtime
= fsp
->close_write_time
;
753 /* As this is a close based update, we are not directly changing the
754 file attributes from a client call, but indirectly from a write. */
755 status
= smb_set_file_time(fsp
->conn
, fsp
, fsp
->fsp_name
, &ft
, false);
756 if (!NT_STATUS_IS_OK(status
)) {
757 DEBUG(10,("update_write_time_on_close: smb_set_file_time "
758 "on file %s returned %s\n",
767 static NTSTATUS
ntstatus_keeperror(NTSTATUS s1
, NTSTATUS s2
)
769 if (!NT_STATUS_IS_OK(s1
)) {
775 static void assert_no_pending_aio(struct files_struct
*fsp
,
776 enum file_close_type close_type
)
778 struct smbXsrv_client
*client
= global_smbXsrv_client
;
779 size_t num_connections_alive
;
780 unsigned num_requests
= fsp
->num_aio_requests
;
782 if (num_requests
== 0) {
786 num_connections_alive
= smbXsrv_client_valid_connections(client
);
788 if (close_type
== SHUTDOWN_CLOSE
&& num_connections_alive
== 0) {
790 * fsp->aio_requests and the contents (fsp->aio_requests[x])
791 * are both independently owned by fsp and are not in a
792 * talloc hierarchy. This allows the fsp->aio_requests array to
793 * be reallocated independently of the array contents so it can
796 * This means we must ensure order of deallocation
797 * on a SHUTDOWN_CLOSE by deallocating the fsp->aio_requests[x]
798 * contents first, as their destructors access the
799 * fsp->aio_request array. If we don't deallocate them
800 * first, when fsp is deallocated fsp->aio_requests
801 * could have been deallocated *before* its contents
802 * fsp->aio_requests[x], causing a crash.
804 while (fsp
->num_aio_requests
!= 0) {
807 * talloc_free(fsp->aio_requests[0]),
808 * and *NOT* TALLOC_FREE() here, as
809 * TALLOC_FREE(fsp->aio_requests[0])
810 * will overwrite any new contents of
811 * fsp->aio_requests[0] that were
812 * copied into it via the destructor
813 * aio_del_req_from_fsp().
815 * BUG: https://bugzilla.samba.org/show_bug.cgi?id=14515
817 talloc_free(fsp
->aio_requests
[0]);
822 DBG_ERR("fsp->num_aio_requests=%u\n", num_requests
);
823 smb_panic("can not close with outstanding aio requests");
827 /****************************************************************************
830 close_type can be NORMAL_CLOSE=0,SHUTDOWN_CLOSE,ERROR_CLOSE.
831 printing and magic scripts are only run on normal close.
832 delete on close is done on normal and shutdown close.
833 ****************************************************************************/
835 static NTSTATUS
close_normal_file(struct smb_request
*req
, files_struct
*fsp
,
836 enum file_close_type close_type
)
838 NTSTATUS status
= NT_STATUS_OK
;
840 connection_struct
*conn
= fsp
->conn
;
841 bool is_durable
= false;
843 SMB_ASSERT(fsp
->fsp_flags
.is_fsa
);
845 assert_no_pending_aio(fsp
, close_type
);
847 while (talloc_array_length(fsp
->blocked_smb1_lock_reqs
) != 0) {
848 smbd_smb1_brl_finish_by_req(
849 fsp
->blocked_smb1_lock_reqs
[0],
850 NT_STATUS_RANGE_NOT_LOCKED
);
854 * If we're flushing on a close we can get a write
855 * error here, we must remember this.
858 if (NT_STATUS_IS_OK(status
) && fsp
->op
!= NULL
) {
859 is_durable
= fsp
->op
->global
->durable
;
862 if (close_type
!= SHUTDOWN_CLOSE
) {
867 DATA_BLOB new_cookie
= data_blob_null
;
869 tmp
= SMB_VFS_DURABLE_DISCONNECT(fsp
,
870 fsp
->op
->global
->backend_cookie
,
873 if (NT_STATUS_IS_OK(tmp
)) {
878 tv
= req
->request_time
;
880 tv
= timeval_current();
882 now
= timeval_to_nttime(&tv
);
884 data_blob_free(&fsp
->op
->global
->backend_cookie
);
885 fsp
->op
->global
->backend_cookie
= new_cookie
;
887 fsp
->op
->compat
= NULL
;
888 tmp
= smbXsrv_open_close(fsp
->op
, now
);
889 if (!NT_STATUS_IS_OK(tmp
)) {
890 DEBUG(1, ("Failed to update smbXsrv_open "
891 "record when disconnecting durable "
892 "handle for file %s: %s - "
893 "proceeding with normal close\n",
894 fsp_str_dbg(fsp
), nt_errstr(tmp
)));
896 scavenger_schedule_disconnected(fsp
);
898 DEBUG(1, ("Failed to disconnect durable handle for "
899 "file %s: %s - proceeding with normal "
900 "close\n", fsp_str_dbg(fsp
), nt_errstr(tmp
)));
902 if (!NT_STATUS_IS_OK(tmp
)) {
909 * This is the case where we successfully disconnected
910 * a durable handle and closed the underlying file.
911 * In all other cases, we proceed with a genuine close.
913 DEBUG(10, ("%s disconnected durable handle for file %s\n",
914 conn
->session_info
->unix_info
->unix_name
,
919 if (fsp
->op
!= NULL
) {
921 * Make sure the handle is not marked as durable anymore
923 fsp
->op
->global
->durable
= false;
926 if (fsp
->fsp_flags
.modified
) {
928 NOTIFY_ACTION_DIRLEASE_BREAK
,
931 fsp_get_smb2_lease(fsp
));
934 /* If this is an old DOS or FCB open and we have multiple opens on
935 the same handle we only have one share mode. Ensure we only remove
936 the share mode on the last close. */
938 if (fh_get_refcount(fsp
->fh
) == 1) {
939 /* Should we return on error here... ? */
940 tmp
= close_remove_share_mode(fsp
, close_type
);
941 status
= ntstatus_keeperror(status
, tmp
);
944 locking_close_file(fsp
, close_type
);
947 * Ensure pending modtime is set before closing underlying fd.
950 tmp
= update_write_time_on_close(fsp
);
951 if (NT_STATUS_EQUAL(tmp
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
953 * Someone renamed the file or a parent directory containing
954 * this file. We can't do anything about this, eat the error.
958 status
= ntstatus_keeperror(status
, tmp
);
961 status
= ntstatus_keeperror(status
, tmp
);
963 /* check for magic scripts */
964 if (close_type
== NORMAL_CLOSE
) {
965 tmp
= check_magic(fsp
);
966 status
= ntstatus_keeperror(status
, tmp
);
969 DEBUG(2,("%s closed file %s (numopen=%d) %s\n",
970 conn
->session_info
->unix_info
->unix_name
, fsp_str_dbg(fsp
),
971 conn
->num_files_open
- 1,
972 nt_errstr(status
) ));
976 /****************************************************************************
977 Function used by reply_rmdir to delete an entire directory
978 tree recursively. Return True on ok, False on fail.
979 ****************************************************************************/
981 NTSTATUS
recursive_rmdir(TALLOC_CTX
*ctx
,
982 connection_struct
*conn
,
983 struct smb_filename
*smb_dname
)
985 const char *dname
= NULL
;
986 char *talloced
= NULL
;
987 struct smb_Dir
*dir_hnd
= NULL
;
988 struct files_struct
*dirfsp
= NULL
;
990 NTSTATUS status
= NT_STATUS_OK
;
992 SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname
));
994 status
= OpenDir(talloc_tos(),
1000 if (!NT_STATUS_IS_OK(status
)) {
1004 dirfsp
= dir_hnd_fetch_fsp(dir_hnd
);
1006 while ((dname
= ReadDirName(dir_hnd
, &talloced
))) {
1007 struct smb_filename
*atname
= NULL
;
1008 struct smb_filename
*smb_dname_full
= NULL
;
1009 char *fullname
= NULL
;
1010 bool do_break
= true;
1011 int unlink_flags
= 0;
1013 if (ISDOT(dname
) || ISDOTDOT(dname
)) {
1014 TALLOC_FREE(talloced
);
1018 /* Construct the full name. */
1019 fullname
= talloc_asprintf(ctx
,
1021 smb_dname
->base_name
,
1024 status
= NT_STATUS_NO_MEMORY
;
1028 smb_dname_full
= synthetic_smb_fname(talloc_tos(),
1034 if (smb_dname_full
== NULL
) {
1035 status
= NT_STATUS_NO_MEMORY
;
1039 if (SMB_VFS_LSTAT(conn
, smb_dname_full
) != 0) {
1040 status
= map_nt_error_from_unix(errno
);
1044 if (smb_dname_full
->st
.st_ex_mode
& S_IFDIR
) {
1045 status
= recursive_rmdir(ctx
, conn
, smb_dname_full
);
1046 if (!NT_STATUS_IS_OK(status
)) {
1049 unlink_flags
= AT_REMOVEDIR
;
1052 status
= synthetic_pathref(talloc_tos(),
1056 &smb_dname_full
->st
,
1057 smb_dname_full
->twrp
,
1058 smb_dname_full
->flags
,
1060 if (!NT_STATUS_IS_OK(status
)) {
1064 if (!is_visible_fsp(atname
->fsp
)) {
1065 TALLOC_FREE(smb_dname_full
);
1066 TALLOC_FREE(fullname
);
1067 TALLOC_FREE(talloced
);
1068 TALLOC_FREE(atname
);
1072 retval
= SMB_VFS_UNLINKAT(conn
,
1077 status
= map_nt_error_from_unix(errno
);
1081 /* Successful iteration. */
1085 TALLOC_FREE(smb_dname_full
);
1086 TALLOC_FREE(fullname
);
1087 TALLOC_FREE(talloced
);
1088 TALLOC_FREE(atname
);
1093 TALLOC_FREE(dir_hnd
);
1097 /****************************************************************************
1098 The internals of the rmdir code - called elsewhere.
1099 ****************************************************************************/
1101 static NTSTATUS
rmdir_internals(TALLOC_CTX
*ctx
, struct files_struct
*fsp
)
1103 struct connection_struct
*conn
= fsp
->conn
;
1104 struct smb_filename
*smb_dname
= fsp
->fsp_name
;
1105 struct smb_filename
*parent_fname
= NULL
;
1106 struct smb_filename
*at_fname
= NULL
;
1107 const char *dname
= NULL
;
1108 char *talloced
= NULL
;
1109 struct smb_Dir
*dir_hnd
= NULL
;
1110 struct files_struct
*dirfsp
= NULL
;
1111 int unlink_flags
= 0;
1115 SMB_ASSERT(!is_ntfs_stream_smb_fname(smb_dname
));
1117 status
= parent_pathref(talloc_tos(),
1122 if (!NT_STATUS_IS_OK(status
)) {
1127 * Todo: use SMB_VFS_STATX() once it's available.
1130 /* Might be a symlink. */
1131 ret
= SMB_VFS_LSTAT(conn
, smb_dname
);
1133 TALLOC_FREE(parent_fname
);
1134 return map_nt_error_from_unix(errno
);
1137 if (S_ISLNK(smb_dname
->st
.st_ex_mode
)) {
1138 /* Is what it points to a directory ? */
1139 ret
= SMB_VFS_STAT(conn
, smb_dname
);
1141 TALLOC_FREE(parent_fname
);
1142 return map_nt_error_from_unix(errno
);
1144 if (!(S_ISDIR(smb_dname
->st
.st_ex_mode
))) {
1145 TALLOC_FREE(parent_fname
);
1146 return NT_STATUS_NOT_A_DIRECTORY
;
1149 unlink_flags
= AT_REMOVEDIR
;
1152 ret
= SMB_VFS_UNLINKAT(conn
,
1157 TALLOC_FREE(parent_fname
);
1158 return NT_STATUS_OK
;
1161 if (!((errno
== ENOTEMPTY
) || (errno
== EEXIST
))) {
1162 DEBUG(3,("rmdir_internals: couldn't remove directory %s : "
1163 "%s\n", smb_fname_str_dbg(smb_dname
),
1165 TALLOC_FREE(parent_fname
);
1166 return map_nt_error_from_unix(errno
);
1170 * Here we know the initial directory unlink failed with
1171 * ENOTEMPTY or EEXIST so we know there are objects within.
1172 * If we don't have permission to delete files non
1173 * visible to the client just fail the directory delete.
1176 if (!lp_delete_veto_files(SNUM(conn
))) {
1177 status
= NT_STATUS_DIRECTORY_NOT_EMPTY
;
1182 * Check to see if the only thing in this directory are
1183 * files non-visible to the client. If not, fail the delete.
1186 status
= OpenDir_from_pathref(talloc_tos(), fsp
, NULL
, 0, &dir_hnd
);
1187 if (!NT_STATUS_IS_OK(status
)) {
1189 * Note, we deliberately squash the error here
1190 * to avoid leaking information about what we
1193 status
= NT_STATUS_DIRECTORY_NOT_EMPTY
;
1197 dirfsp
= dir_hnd_fetch_fsp(dir_hnd
);
1199 while ((dname
= ReadDirName(dir_hnd
, &talloced
)) != NULL
) {
1200 struct smb_filename
*smb_dname_full
= NULL
;
1201 struct smb_filename
*direntry_fname
= NULL
;
1202 char *fullname
= NULL
;
1205 if (ISDOT(dname
) || ISDOTDOT(dname
)) {
1206 TALLOC_FREE(talloced
);
1209 if (IS_VETO_PATH(conn
, dname
)) {
1210 TALLOC_FREE(talloced
);
1214 fullname
= talloc_asprintf(talloc_tos(),
1216 smb_dname
->base_name
,
1219 if (fullname
== NULL
) {
1220 TALLOC_FREE(talloced
);
1221 status
= NT_STATUS_NO_MEMORY
;
1225 smb_dname_full
= synthetic_smb_fname(talloc_tos(),
1231 if (smb_dname_full
== NULL
) {
1232 TALLOC_FREE(talloced
);
1233 TALLOC_FREE(fullname
);
1234 status
= NT_STATUS_NO_MEMORY
;
1238 retval
= SMB_VFS_LSTAT(conn
, smb_dname_full
);
1240 status
= map_nt_error_from_unix(errno
);
1241 TALLOC_FREE(talloced
);
1242 TALLOC_FREE(fullname
);
1243 TALLOC_FREE(smb_dname_full
);
1247 if (S_ISLNK(smb_dname_full
->st
.st_ex_mode
)) {
1248 /* Could it be an msdfs link ? */
1249 if (lp_host_msdfs() &&
1250 lp_msdfs_root(SNUM(conn
))) {
1251 struct smb_filename
*smb_atname
;
1252 smb_atname
= synthetic_smb_fname(talloc_tos(),
1255 &smb_dname_full
->st
,
1256 fsp
->fsp_name
->twrp
,
1257 fsp
->fsp_name
->flags
);
1258 if (smb_atname
== NULL
) {
1259 TALLOC_FREE(talloced
);
1260 TALLOC_FREE(fullname
);
1261 TALLOC_FREE(smb_dname_full
);
1262 status
= NT_STATUS_NO_MEMORY
;
1265 if (is_msdfs_link(fsp
, smb_atname
)) {
1266 TALLOC_FREE(talloced
);
1267 TALLOC_FREE(fullname
);
1268 TALLOC_FREE(smb_dname_full
);
1269 TALLOC_FREE(smb_atname
);
1270 DBG_DEBUG("got msdfs link name %s "
1271 "- can't delete directory %s\n",
1274 status
= NT_STATUS_DIRECTORY_NOT_EMPTY
;
1277 TALLOC_FREE(smb_atname
);
1280 /* Not a DFS link - could it be a dangling symlink ? */
1281 retval
= SMB_VFS_STAT(conn
, smb_dname_full
);
1282 if (retval
== -1 && (errno
== ENOENT
|| errno
== ELOOP
)) {
1285 * Allow delete as "delete veto files = yes"
1287 TALLOC_FREE(talloced
);
1288 TALLOC_FREE(fullname
);
1289 TALLOC_FREE(smb_dname_full
);
1293 DBG_DEBUG("got symlink name %s - "
1294 "can't delete directory %s\n",
1297 TALLOC_FREE(talloced
);
1298 TALLOC_FREE(fullname
);
1299 TALLOC_FREE(smb_dname_full
);
1300 status
= NT_STATUS_DIRECTORY_NOT_EMPTY
;
1304 /* Not a symlink, get a pathref. */
1305 status
= synthetic_pathref(talloc_tos(),
1309 &smb_dname_full
->st
,
1313 if (!NT_STATUS_IS_OK(status
)) {
1314 TALLOC_FREE(talloced
);
1315 TALLOC_FREE(fullname
);
1316 TALLOC_FREE(smb_dname_full
);
1320 if (!is_visible_fsp(direntry_fname
->fsp
)) {
1321 TALLOC_FREE(talloced
);
1322 TALLOC_FREE(fullname
);
1323 TALLOC_FREE(smb_dname_full
);
1324 TALLOC_FREE(direntry_fname
);
1329 * We found a client visible name.
1330 * We cannot delete this directory.
1332 DBG_DEBUG("got name %s - "
1333 "can't delete directory %s\n",
1336 TALLOC_FREE(talloced
);
1337 TALLOC_FREE(fullname
);
1338 TALLOC_FREE(smb_dname_full
);
1339 TALLOC_FREE(direntry_fname
);
1340 status
= NT_STATUS_DIRECTORY_NOT_EMPTY
;
1344 /* Do a recursive delete. */
1347 while ((dname
= ReadDirName(dir_hnd
, &talloced
)) != NULL
) {
1348 struct smb_filename
*direntry_fname
= NULL
;
1349 struct smb_filename
*smb_dname_full
= NULL
;
1350 char *fullname
= NULL
;
1351 bool do_break
= true;
1354 if (ISDOT(dname
) || ISDOTDOT(dname
)) {
1355 TALLOC_FREE(talloced
);
1359 fullname
= talloc_asprintf(ctx
,
1361 smb_dname
->base_name
,
1364 if (fullname
== NULL
) {
1365 status
= NT_STATUS_NO_MEMORY
;
1369 smb_dname_full
= synthetic_smb_fname(talloc_tos(),
1375 if (smb_dname_full
== NULL
) {
1376 status
= NT_STATUS_NO_MEMORY
;
1381 * Todo: use SMB_VFS_STATX() once that's available.
1384 retval
= SMB_VFS_LSTAT(conn
, smb_dname_full
);
1386 status
= map_nt_error_from_unix(errno
);
1391 * We are only dealing with VETO'ed objects
1392 * here. If it's a symlink, just delete the
1393 * link without caring what it is pointing
1396 if (S_ISLNK(smb_dname_full
->st
.st_ex_mode
)) {
1397 direntry_fname
= synthetic_smb_fname(talloc_tos(),
1400 &smb_dname_full
->st
,
1403 if (direntry_fname
== NULL
) {
1404 status
= NT_STATUS_NO_MEMORY
;
1408 status
= synthetic_pathref(talloc_tos(),
1412 &smb_dname_full
->st
,
1416 if (!NT_STATUS_IS_OK(status
)) {
1420 if (!is_visible_fsp(direntry_fname
->fsp
)) {
1421 TALLOC_FREE(fullname
);
1422 TALLOC_FREE(smb_dname_full
);
1423 TALLOC_FREE(talloced
);
1424 TALLOC_FREE(direntry_fname
);
1431 if (smb_dname_full
->st
.st_ex_mode
& S_IFDIR
) {
1432 status
= recursive_rmdir(ctx
, conn
, smb_dname_full
);
1433 if (!NT_STATUS_IS_OK(status
)) {
1436 unlink_flags
= AT_REMOVEDIR
;
1439 retval
= SMB_VFS_UNLINKAT(conn
,
1444 status
= map_nt_error_from_unix(errno
);
1448 /* Successful iteration. */
1452 TALLOC_FREE(fullname
);
1453 TALLOC_FREE(smb_dname_full
);
1454 TALLOC_FREE(talloced
);
1455 TALLOC_FREE(direntry_fname
);
1461 /* If we get here, we know NT_STATUS_IS_OK(status) */
1462 SMB_ASSERT(NT_STATUS_IS_OK(status
));
1464 /* Retry the rmdir */
1465 ret
= SMB_VFS_UNLINKAT(conn
,
1470 status
= map_nt_error_from_unix(errno
);
1475 TALLOC_FREE(dir_hnd
);
1476 TALLOC_FREE(parent_fname
);
1478 if (!NT_STATUS_IS_OK(status
)) {
1479 DBG_NOTICE("couldn't remove directory %s : "
1480 "%s\n", smb_fname_str_dbg(smb_dname
),
1488 /****************************************************************************
1489 Close a directory opened by an NT SMB call.
1490 ****************************************************************************/
1492 static NTSTATUS
close_directory(struct smb_request
*req
, files_struct
*fsp
,
1493 enum file_close_type close_type
)
1495 connection_struct
*conn
= fsp
->conn
;
1496 struct close_share_mode_lock_state lck_state
= {};
1497 bool changed_user
= false;
1498 NTSTATUS status
= NT_STATUS_OK
;
1499 NTSTATUS status1
= NT_STATUS_OK
;
1500 NTSTATUS notify_status
;
1503 SMB_ASSERT(fsp
->fsp_flags
.is_fsa
);
1505 if (conn_using_smb2(fsp
->conn
->sconn
)) {
1506 notify_status
= NT_STATUS_NOTIFY_CLEANUP
;
1508 notify_status
= NT_STATUS_OK
;
1511 assert_no_pending_aio(fsp
, close_type
);
1514 * NT can set delete_on_close of the last open
1515 * reference to a directory also.
1518 lck_state
= (struct close_share_mode_lock_state
) {
1520 .object_type
= "directory",
1521 .close_type
= close_type
,
1524 status
= share_mode_entry_prepare_lock_del(&lck_state
.prepare_state
,
1526 close_share_mode_lock_prepare
,
1528 if (!NT_STATUS_IS_OK(status
)) {
1529 DBG_ERR("share_mode_entry_prepare_lock_del() failed for %s - %s\n",
1530 fsp_str_dbg(fsp
), nt_errstr(status
));
1535 /* Remove the oplock before potentially deleting the file. */
1536 if (fsp
->oplock_type
!= NO_OPLOCK
) {
1537 release_file_oplock(fsp
);
1541 * NT can set delete_on_close of the last open
1542 * reference to a file.
1545 if (!lck_state
.delete_object
) {
1546 status
= NT_STATUS_OK
;
1551 * Ok, we have to delete the directory
1553 lck_state
.cleanup_fn
= close_share_mode_lock_cleanup
;
1555 if (lck_state
.got_tokens
&&
1556 !unix_token_equal(lck_state
.del_token
, get_current_utok(conn
)))
1558 /* Become the user who requested the delete. */
1560 DBG_INFO("dir %s. Change user to uid %u\n",
1562 (unsigned int)lck_state
.del_token
->uid
);
1564 if (!push_sec_ctx()) {
1565 smb_panic("close_directory: failed to push sec_ctx.\n");
1568 set_sec_ctx(lck_state
.del_token
->uid
,
1569 lck_state
.del_token
->gid
,
1570 lck_state
.del_token
->ngroups
,
1571 lck_state
.del_token
->groups
,
1572 lck_state
.del_nt_token
);
1574 changed_user
= true;
1577 if ((fsp
->conn
->fs_capabilities
& FILE_NAMED_STREAMS
)
1578 && !is_ntfs_stream_smb_fname(fsp
->fsp_name
)) {
1580 status
= delete_all_streams(fsp
->conn
, fsp
->fsp_name
);
1581 if (!NT_STATUS_IS_OK(status
)) {
1582 DEBUG(5, ("delete_all_streams failed: %s\n",
1583 nt_errstr(status
)));
1588 status
= rmdir_internals(talloc_tos(), fsp
);
1590 DEBUG(5,("close_directory: %s. Delete on close was set - "
1591 "deleting directory returned %s.\n",
1592 fsp_str_dbg(fsp
), nt_errstr(status
)));
1595 * Ensure we remove any change notify requests that would
1596 * now fail as the directory has been deleted.
1599 if (NT_STATUS_IS_OK(status
)) {
1600 notify_status
= NT_STATUS_DELETE_PENDING
;
1605 /* unbecome user. */
1609 ulstatus
= share_mode_entry_prepare_unlock(&lck_state
.prepare_state
,
1610 lck_state
.cleanup_fn
,
1612 if (!NT_STATUS_IS_OK(ulstatus
)) {
1613 DBG_ERR("share_mode_entry_prepare_unlock() failed for %s - %s\n",
1614 fsp_str_dbg(fsp
), nt_errstr(ulstatus
));
1615 smb_panic("share_mode_entry_prepare_unlock() failed!");
1618 remove_pending_change_notify_requests_by_fid(fsp
, notify_status
);
1620 if (lck_state
.delete_object
&& NT_STATUS_IS_OK(status
)) {
1621 const struct smb2_lease
*lease
= fsp_get_smb2_lease(fsp
);
1623 if (lease
!= NULL
) {
1625 * If parent lease key of handle on which delete
1626 * disposition was set does not match the parent lease
1627 * key of last closed handle, break all leases on the
1630 if (!smb2_lease_key_equal(&lease
->parent_lease_key
,
1631 &lck_state
.parent_lease_key
))
1637 NOTIFY_ACTION_REMOVED
|
1638 NOTIFY_ACTION_DIRLEASE_BREAK
,
1639 FILE_NOTIFY_CHANGE_DIR_NAME
,
1645 status1
= fd_close(fsp
);
1647 if (!NT_STATUS_IS_OK(status1
)) {
1648 DEBUG(0, ("Could not close dir! fname=%s, fd=%d, err=%d=%s\n",
1649 fsp_str_dbg(fsp
), fsp_get_pathref_fd(fsp
), errno
,
1653 if (NT_STATUS_IS_OK(status
) && !NT_STATUS_IS_OK(status1
)) {
1659 /****************************************************************************
1660 Rundown all SMB-related dependencies of a files struct
1661 ****************************************************************************/
1663 NTSTATUS
close_file_smb(struct smb_request
*req
,
1664 struct files_struct
*fsp
,
1665 enum file_close_type close_type
)
1670 * This fsp can never be an internal dirfsp. They must
1671 * be explicitly closed by TALLOC_FREE of the dir handle.
1673 SMB_ASSERT(!fsp
->fsp_flags
.is_dirfsp
);
1676 * Never call directly on a base fsp
1678 SMB_ASSERT(fsp
->stream_fsp
== NULL
);
1680 if (fsp
->fake_file_handle
!= NULL
) {
1682 * Named pipes are opened as fake files and
1683 * can have pending aio requests. Ensure
1684 * we clear out all pending aio on force
1685 * shutdown of named pipes also.
1686 * BUG: https://bugzilla.samba.org/show_bug.cgi?id=15423
1688 assert_no_pending_aio(fsp
, close_type
);
1689 status
= close_fake_file(req
, fsp
);
1690 } else if (fsp
->print_file
!= NULL
) {
1691 /* FIXME: return spool errors */
1692 print_spool_end(fsp
, close_type
);
1694 status
= NT_STATUS_OK
;
1695 } else if (!fsp
->fsp_flags
.is_fsa
) {
1696 if (close_type
== NORMAL_CLOSE
) {
1697 DBG_ERR("unexpected NORMAL_CLOSE for [%s] "
1698 "is_fsa[%u] is_pathref[%u] is_directory[%u]\n",
1700 fsp
->fsp_flags
.is_fsa
,
1701 fsp
->fsp_flags
.is_pathref
,
1702 fsp
->fsp_flags
.is_directory
);
1704 SMB_ASSERT(close_type
!= NORMAL_CLOSE
);
1706 status
= NT_STATUS_OK
;
1707 } else if (fsp
->fsp_flags
.is_directory
) {
1708 status
= close_directory(req
, fsp
, close_type
);
1710 status
= close_normal_file(req
, fsp
, close_type
);
1713 if (fsp_is_alternate_stream(fsp
)) {
1715 * fsp was a stream, its base_fsp can't be a stream
1718 SMB_ASSERT(!fsp_is_alternate_stream(fsp
->base_fsp
));
1721 * There's a 1:1 relationship between fsp and a base_fsp
1723 SMB_ASSERT(fsp
->base_fsp
->stream_fsp
== fsp
);
1726 * Make base_fsp look standalone now
1728 fsp
->base_fsp
->stream_fsp
= NULL
;
1730 close_file_free(req
, &fsp
->base_fsp
, close_type
);
1733 fsp_unbind_smb(req
, fsp
);
1738 NTSTATUS
close_file_free(struct smb_request
*req
,
1739 struct files_struct
**_fsp
,
1740 enum file_close_type close_type
)
1742 struct files_struct
*fsp
= *_fsp
;
1745 status
= close_file_smb(req
, fsp
, close_type
);
1747 file_free(req
, fsp
);
1753 /****************************************************************************
1754 Deal with an (authorized) message to close a file given the share mode
1756 ****************************************************************************/
1758 void msg_close_file(struct messaging_context
*msg_ctx
,
1761 struct server_id server_id
,
1764 struct oplock_break_message msg
;
1765 enum ndr_err_code ndr_err
;
1766 files_struct
*fsp
= NULL
;
1767 struct smbd_server_connection
*sconn
=
1768 talloc_get_type_abort(private_data
,
1769 struct smbd_server_connection
);
1771 ndr_err
= ndr_pull_struct_blob_all_noalloc(
1774 (ndr_pull_flags_fn_t
)ndr_pull_oplock_break_message
);
1775 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1776 DBG_DEBUG("ndr_pull_oplock_break_message failed: %s\n",
1777 ndr_errstr(ndr_err
));
1781 fsp
= file_find_dif(sconn
, msg
.id
, msg
.share_file_id
);
1783 DEBUG(10,("msg_close_file: failed to find file.\n"));
1786 close_file_free(NULL
, &fsp
, NORMAL_CLOSE
);