2 Unix SMB/CIFS implementation.
3 file opening and share modes
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Jeremy Allison 2001-2004
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"
25 #include "smbd/smbd.h"
26 #include "smbd/globals.h"
27 #include "fake_file.h"
28 #include "../libcli/security/security.h"
29 #include "../librpc/gen_ndr/ndr_security.h"
30 #include "../librpc/gen_ndr/open_files.h"
31 #include "../librpc/gen_ndr/idmap.h"
32 #include "../librpc/gen_ndr/ioctl.h"
33 #include "passdb/lookup_sid.h"
37 #include "source3/lib/dbwrap/dbwrap_watch.h"
38 #include "locking/leases_db.h"
39 #include "librpc/gen_ndr/ndr_leases_db.h"
41 extern const struct generic_mapping file_generic_mapping
;
43 struct deferred_open_record
{
44 bool delayed_for_oplocks
;
49 * Timer for async opens, needed because they don't use a watch on
50 * a locking.tdb record. This is currently only used for real async
51 * opens and just terminates smbd if the async open times out.
53 struct tevent_timer
*te
;
56 /****************************************************************************
57 If the requester wanted DELETE_ACCESS and was rejected because
58 the file ACL didn't include DELETE_ACCESS, see if the parent ACL
60 ****************************************************************************/
62 static bool parent_override_delete(connection_struct
*conn
,
63 const struct smb_filename
*smb_fname
,
65 uint32_t rejected_mask
)
67 if ((access_mask
& DELETE_ACCESS
) &&
68 (rejected_mask
& DELETE_ACCESS
) &&
69 can_delete_file_in_directory(conn
, smb_fname
)) {
75 /****************************************************************************
76 Check if we have open rights.
77 ****************************************************************************/
79 NTSTATUS
smbd_check_access_rights(struct connection_struct
*conn
,
80 const struct smb_filename
*smb_fname
,
84 /* Check if we have rights to open. */
86 struct security_descriptor
*sd
= NULL
;
87 uint32_t rejected_share_access
;
88 uint32_t rejected_mask
= access_mask
;
89 uint32_t do_not_check_mask
= 0;
91 rejected_share_access
= access_mask
& ~(conn
->share_access
);
93 if (rejected_share_access
) {
94 DEBUG(10, ("smbd_check_access_rights: rejected share access 0x%x "
96 (unsigned int)access_mask
,
97 smb_fname_str_dbg(smb_fname
),
98 (unsigned int)rejected_share_access
));
99 return NT_STATUS_ACCESS_DENIED
;
102 if (!use_privs
&& get_current_uid(conn
) == (uid_t
)0) {
103 /* I'm sorry sir, I didn't know you were root... */
104 DEBUG(10,("smbd_check_access_rights: root override "
105 "on %s. Granting 0x%x\n",
106 smb_fname_str_dbg(smb_fname
),
107 (unsigned int)access_mask
));
111 if ((access_mask
& DELETE_ACCESS
) && !lp_acl_check_permissions(SNUM(conn
))) {
112 DEBUG(10,("smbd_check_access_rights: not checking ACL "
113 "on DELETE_ACCESS on file %s. Granting 0x%x\n",
114 smb_fname_str_dbg(smb_fname
),
115 (unsigned int)access_mask
));
119 if (access_mask
== DELETE_ACCESS
&&
120 VALID_STAT(smb_fname
->st
) &&
121 S_ISLNK(smb_fname
->st
.st_ex_mode
)) {
122 /* We can always delete a symlink. */
123 DEBUG(10,("smbd_check_access_rights: not checking ACL "
124 "on DELETE_ACCESS on symlink %s.\n",
125 smb_fname_str_dbg(smb_fname
) ));
129 status
= SMB_VFS_GET_NT_ACL(conn
, smb_fname
,
132 SECINFO_DACL
), talloc_tos(), &sd
);
134 if (!NT_STATUS_IS_OK(status
)) {
135 DEBUG(10, ("smbd_check_access_rights: Could not get acl "
137 smb_fname_str_dbg(smb_fname
),
140 if (NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
148 * If we can access the path to this file, by
149 * default we have FILE_READ_ATTRIBUTES from the
150 * containing directory. See the section:
151 * "Algorithm to Check Access to an Existing File"
154 * se_file_access_check() also takes care of
155 * owner WRITE_DAC and READ_CONTROL.
157 do_not_check_mask
= FILE_READ_ATTRIBUTES
;
160 * Samba 3.6 and earlier granted execute access even
161 * if the ACL did not contain execute rights.
162 * Samba 4.0 is more correct and checks it.
163 * The compatibilty mode allows one to skip this check
164 * to smoothen upgrades.
166 if (lp_acl_allow_execute_always(SNUM(conn
))) {
167 do_not_check_mask
|= FILE_EXECUTE
;
170 status
= se_file_access_check(sd
,
171 get_current_nttok(conn
),
173 (access_mask
& ~do_not_check_mask
),
176 DEBUG(10,("smbd_check_access_rights: file %s requesting "
177 "0x%x returning 0x%x (%s)\n",
178 smb_fname_str_dbg(smb_fname
),
179 (unsigned int)access_mask
,
180 (unsigned int)rejected_mask
,
181 nt_errstr(status
) ));
183 if (!NT_STATUS_IS_OK(status
)) {
184 if (DEBUGLEVEL
>= 10) {
185 DEBUG(10,("smbd_check_access_rights: acl for %s is:\n",
186 smb_fname_str_dbg(smb_fname
) ));
187 NDR_PRINT_DEBUG(security_descriptor
, sd
);
193 if (NT_STATUS_IS_OK(status
) ||
194 !NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
198 /* Here we know status == NT_STATUS_ACCESS_DENIED. */
202 if ((access_mask
& FILE_WRITE_ATTRIBUTES
) &&
203 (rejected_mask
& FILE_WRITE_ATTRIBUTES
) &&
204 !lp_store_dos_attributes(SNUM(conn
)) &&
205 (lp_map_readonly(SNUM(conn
)) ||
206 lp_map_archive(SNUM(conn
)) ||
207 lp_map_hidden(SNUM(conn
)) ||
208 lp_map_system(SNUM(conn
)))) {
209 rejected_mask
&= ~FILE_WRITE_ATTRIBUTES
;
211 DEBUG(10,("smbd_check_access_rights: "
213 "FILE_WRITE_ATTRIBUTES "
215 smb_fname_str_dbg(smb_fname
)));
218 if (parent_override_delete(conn
,
222 /* Were we trying to do an open
223 * for delete and didn't get DELETE
224 * access (only) ? Check if the
225 * directory allows DELETE_CHILD.
227 * http://blogs.msdn.com/oldnewthing/archive/2004/06/04/148426.aspx
230 rejected_mask
&= ~DELETE_ACCESS
;
232 DEBUG(10,("smbd_check_access_rights: "
236 smb_fname_str_dbg(smb_fname
)));
239 if (rejected_mask
!= 0) {
240 return NT_STATUS_ACCESS_DENIED
;
245 NTSTATUS
check_parent_access(struct connection_struct
*conn
,
246 struct smb_filename
*smb_fname
,
247 uint32_t access_mask
)
250 char *parent_dir
= NULL
;
251 struct security_descriptor
*parent_sd
= NULL
;
252 uint32_t access_granted
= 0;
253 struct smb_filename
*parent_smb_fname
= NULL
;
255 if (!parent_dirname(talloc_tos(),
256 smb_fname
->base_name
,
259 return NT_STATUS_NO_MEMORY
;
262 parent_smb_fname
= synthetic_smb_fname(talloc_tos(),
267 if (parent_smb_fname
== NULL
) {
268 return NT_STATUS_NO_MEMORY
;
271 if (get_current_uid(conn
) == (uid_t
)0) {
272 /* I'm sorry sir, I didn't know you were root... */
273 DEBUG(10,("check_parent_access: root override "
274 "on %s. Granting 0x%x\n",
275 smb_fname_str_dbg(smb_fname
),
276 (unsigned int)access_mask
));
280 status
= SMB_VFS_GET_NT_ACL(conn
,
286 if (!NT_STATUS_IS_OK(status
)) {
287 DEBUG(5,("check_parent_access: SMB_VFS_GET_NT_ACL failed for "
288 "%s with error %s\n",
295 * If we can access the path to this file, by
296 * default we have FILE_READ_ATTRIBUTES from the
297 * containing directory. See the section:
298 * "Algorithm to Check Access to an Existing File"
301 * se_file_access_check() also takes care of
302 * owner WRITE_DAC and READ_CONTROL.
304 status
= se_file_access_check(parent_sd
,
305 get_current_nttok(conn
),
307 (access_mask
& ~FILE_READ_ATTRIBUTES
),
309 if(!NT_STATUS_IS_OK(status
)) {
310 DEBUG(5,("check_parent_access: access check "
311 "on directory %s for "
312 "path %s for mask 0x%x returned (0x%x) %s\n",
314 smb_fname
->base_name
,
317 nt_errstr(status
) ));
324 /****************************************************************************
325 Ensure when opening a base file for a stream open that we have permissions
326 to do so given the access mask on the base file.
327 ****************************************************************************/
329 static NTSTATUS
check_base_file_access(struct connection_struct
*conn
,
330 struct smb_filename
*smb_fname
,
331 uint32_t access_mask
)
335 status
= smbd_calculate_access_mask(conn
, smb_fname
,
339 if (!NT_STATUS_IS_OK(status
)) {
340 DEBUG(10, ("smbd_calculate_access_mask "
341 "on file %s returned %s\n",
342 smb_fname_str_dbg(smb_fname
),
347 if (access_mask
& (FILE_WRITE_DATA
|FILE_APPEND_DATA
)) {
349 if (!CAN_WRITE(conn
)) {
350 return NT_STATUS_ACCESS_DENIED
;
352 dosattrs
= dos_mode(conn
, smb_fname
);
353 if (IS_DOS_READONLY(dosattrs
)) {
354 return NT_STATUS_ACCESS_DENIED
;
358 return smbd_check_access_rights(conn
,
364 /****************************************************************************
365 Handle differing symlink errno's
366 ****************************************************************************/
368 static int link_errno_convert(int err
)
370 #if defined(ENOTSUP) && defined(OSF1)
371 /* handle special Tru64 errno */
372 if (err
== ENOTSUP
) {
377 /* fix broken NetBSD errno */
382 /* fix broken FreeBSD errno */
389 static int non_widelink_open(struct connection_struct
*conn
,
390 const char *conn_rootdir
,
392 struct smb_filename
*smb_fname
,
395 unsigned int link_depth
);
397 /****************************************************************************
398 Follow a symlink in userspace.
399 ****************************************************************************/
401 static int process_symlink_open(struct connection_struct
*conn
,
402 const char *conn_rootdir
,
404 struct smb_filename
*smb_fname
,
407 unsigned int link_depth
)
410 char *link_target
= NULL
;
413 size_t rootdir_len
= 0;
414 char *resolved_name
= NULL
;
415 bool matched
= false;
419 * Ensure we don't get stuck in a symlink loop.
422 if (link_depth
>= 20) {
427 /* Allocate space for the link target. */
428 link_target
= talloc_array(talloc_tos(), char, PATH_MAX
);
429 if (link_target
== NULL
) {
434 /* Read the link target. */
435 link_len
= SMB_VFS_READLINK(conn
,
436 smb_fname
->base_name
,
439 if (link_len
== -1) {
443 /* Ensure it's at least null terminated. */
444 link_target
[link_len
] = '\0';
446 /* Convert to an absolute path. */
447 resolved_name
= SMB_VFS_REALPATH(conn
, link_target
);
448 if (resolved_name
== NULL
) {
453 * We know conn_rootdir starts with '/' and
454 * does not end in '/'. FIXME ! Should we
457 rootdir_len
= strlen(conn_rootdir
);
459 matched
= (strncmp(conn_rootdir
, resolved_name
, rootdir_len
) == 0);
466 * Turn into a path relative to the share root.
468 if (resolved_name
[rootdir_len
] == '\0') {
469 /* Link to the root of the share. */
470 smb_fname
->base_name
= talloc_strdup(talloc_tos(), ".");
471 if (smb_fname
->base_name
== NULL
) {
475 } else if (resolved_name
[rootdir_len
] == '/') {
476 smb_fname
->base_name
= &resolved_name
[rootdir_len
+1];
482 oldwd
= vfs_GetWd(talloc_tos(), conn
);
487 /* Ensure we operate from the root of the share. */
488 if (vfs_ChDir(conn
, conn_rootdir
) == -1) {
492 /* And do it all again.. */
493 fd
= non_widelink_open(conn
,
506 SAFE_FREE(resolved_name
);
507 TALLOC_FREE(link_target
);
509 int ret
= vfs_ChDir(conn
, oldwd
);
511 smb_panic("unable to get back to old directory\n");
515 if (saved_errno
!= 0) {
521 /****************************************************************************
523 ****************************************************************************/
525 static int non_widelink_open(struct connection_struct
*conn
,
526 const char *conn_rootdir
,
528 struct smb_filename
*smb_fname
,
531 unsigned int link_depth
)
535 struct smb_filename
*smb_fname_rel
= NULL
;
538 char *parent_dir
= NULL
;
539 const char *final_component
= NULL
;
540 bool is_directory
= false;
544 if (flags
& O_DIRECTORY
) {
550 parent_dir
= talloc_strdup(talloc_tos(), smb_fname
->base_name
);
551 if (parent_dir
== NULL
) {
556 final_component
= ".";
558 ok
= parent_dirname(talloc_tos(),
559 smb_fname
->base_name
,
568 oldwd
= vfs_GetWd(talloc_tos(), conn
);
573 /* Pin parent directory in place. */
574 if (vfs_ChDir(conn
, parent_dir
) == -1) {
578 /* Ensure the relative path is below the share. */
579 status
= check_reduced_name(conn
, parent_dir
, final_component
);
580 if (!NT_STATUS_IS_OK(status
)) {
581 saved_errno
= map_errno_from_nt_status(status
);
585 smb_fname_rel
= synthetic_smb_fname(talloc_tos(),
587 smb_fname
->stream_name
,
594 struct smb_filename
*tmp_name
= fsp
->fsp_name
;
595 fsp
->fsp_name
= smb_fname_rel
;
596 fd
= SMB_VFS_OPEN(conn
, smb_fname_rel
, fsp
, flags
, mode
);
597 fsp
->fsp_name
= tmp_name
;
601 saved_errno
= link_errno_convert(errno
);
603 * Trying to open a symlink to a directory with O_NOFOLLOW and
604 * O_DIRECTORY can return either of ELOOP and ENOTDIR. So
605 * ENOTDIR really means: might be a symlink, but we're not sure.
606 * In this case, we just assume there's a symlink. If we were
607 * wrong, process_symlink_open() will return EINVAL. We check
608 * this below, and fall back to returning the initial
611 * BUG: https://bugzilla.samba.org/show_bug.cgi?id=12860
613 if (saved_errno
== ELOOP
|| saved_errno
== ENOTDIR
) {
614 if (fsp
->posix_flags
& FSP_POSIX_FLAGS_OPEN
) {
615 /* Never follow symlinks on posix open. */
618 if (!lp_follow_symlinks(SNUM(conn
))) {
619 /* Explicitly no symlinks. */
623 * We may have a symlink. Follow in userspace
624 * to ensure it's under the share definition.
626 fd
= process_symlink_open(conn
,
634 if (saved_errno
== ENOTDIR
&&
637 * O_DIRECTORY on neither a directory,
638 * nor a symlink. Just return
639 * saved_errno from initial open()
644 link_errno_convert(errno
);
651 TALLOC_FREE(parent_dir
);
652 TALLOC_FREE(smb_fname_rel
);
655 int ret
= vfs_ChDir(conn
, oldwd
);
657 smb_panic("unable to get back to old directory\n");
661 if (saved_errno
!= 0) {
667 /****************************************************************************
668 fd support routines - attempt to do a dos_open.
669 ****************************************************************************/
671 NTSTATUS
fd_open(struct connection_struct
*conn
,
676 struct smb_filename
*smb_fname
= fsp
->fsp_name
;
677 NTSTATUS status
= NT_STATUS_OK
;
680 * Never follow symlinks on a POSIX client. The
681 * client should be doing this.
684 if ((fsp
->posix_flags
& FSP_POSIX_FLAGS_OPEN
) || !lp_follow_symlinks(SNUM(conn
))) {
688 /* Ensure path is below share definition. */
689 if (!lp_widelinks(SNUM(conn
))) {
690 const char *conn_rootdir
= SMB_VFS_CONNECTPATH(conn
,
691 smb_fname
->base_name
);
692 if (conn_rootdir
== NULL
) {
693 return NT_STATUS_NO_MEMORY
;
696 * Only follow symlinks within a share
699 fsp
->fh
->fd
= non_widelink_open(conn
,
707 fsp
->fh
->fd
= SMB_VFS_OPEN(conn
, smb_fname
, fsp
, flags
, mode
);
710 if (fsp
->fh
->fd
== -1) {
711 int posix_errno
= link_errno_convert(errno
);
712 status
= map_nt_error_from_unix(posix_errno
);
713 if (errno
== EMFILE
) {
714 static time_t last_warned
= 0L;
716 if (time((time_t *) NULL
) > last_warned
) {
717 DEBUG(0,("Too many open files, unable "
718 "to open more! smbd's max "
720 lp_max_open_files()));
721 last_warned
= time((time_t *) NULL
);
727 DEBUG(10,("fd_open: name %s, flags = 0%o mode = 0%o, fd = %d. %s\n",
728 smb_fname_str_dbg(smb_fname
), flags
, (int)mode
, fsp
->fh
->fd
,
729 (fsp
->fh
->fd
== -1) ? strerror(errno
) : "" ));
734 /****************************************************************************
735 Close the file associated with a fsp.
736 ****************************************************************************/
738 NTSTATUS
fd_close(files_struct
*fsp
)
745 if (fsp
->fh
->fd
== -1) {
746 return NT_STATUS_OK
; /* What we used to call a stat open. */
748 if (fsp
->fh
->ref_count
> 1) {
749 return NT_STATUS_OK
; /* Shared handle. Only close last reference. */
752 ret
= SMB_VFS_CLOSE(fsp
);
755 return map_nt_error_from_unix(errno
);
760 /****************************************************************************
761 Change the ownership of a file to that of the parent directory.
762 Do this by fd if possible.
763 ****************************************************************************/
765 void change_file_owner_to_parent(connection_struct
*conn
,
766 const char *inherit_from_dir
,
769 struct smb_filename
*smb_fname_parent
;
772 smb_fname_parent
= synthetic_smb_fname(talloc_tos(),
777 if (smb_fname_parent
== NULL
) {
781 ret
= SMB_VFS_STAT(conn
, smb_fname_parent
);
783 DEBUG(0,("change_file_owner_to_parent: failed to stat parent "
784 "directory %s. Error was %s\n",
785 smb_fname_str_dbg(smb_fname_parent
),
787 TALLOC_FREE(smb_fname_parent
);
791 if (smb_fname_parent
->st
.st_ex_uid
== fsp
->fsp_name
->st
.st_ex_uid
) {
792 /* Already this uid - no need to change. */
793 DEBUG(10,("change_file_owner_to_parent: file %s "
794 "is already owned by uid %d\n",
796 (int)fsp
->fsp_name
->st
.st_ex_uid
));
797 TALLOC_FREE(smb_fname_parent
);
802 ret
= SMB_VFS_FCHOWN(fsp
, smb_fname_parent
->st
.st_ex_uid
, (gid_t
)-1);
805 DEBUG(0,("change_file_owner_to_parent: failed to fchown "
806 "file %s to parent directory uid %u. Error "
807 "was %s\n", fsp_str_dbg(fsp
),
808 (unsigned int)smb_fname_parent
->st
.st_ex_uid
,
811 DEBUG(10,("change_file_owner_to_parent: changed new file %s to "
812 "parent directory uid %u.\n", fsp_str_dbg(fsp
),
813 (unsigned int)smb_fname_parent
->st
.st_ex_uid
));
814 /* Ensure the uid entry is updated. */
815 fsp
->fsp_name
->st
.st_ex_uid
= smb_fname_parent
->st
.st_ex_uid
;
818 TALLOC_FREE(smb_fname_parent
);
821 NTSTATUS
change_dir_owner_to_parent(connection_struct
*conn
,
822 const char *inherit_from_dir
,
824 SMB_STRUCT_STAT
*psbuf
)
826 struct smb_filename
*smb_fname_parent
;
827 struct smb_filename
*smb_fname_cwd
= NULL
;
828 char *saved_dir
= NULL
;
829 TALLOC_CTX
*ctx
= talloc_tos();
830 NTSTATUS status
= NT_STATUS_OK
;
833 smb_fname_parent
= synthetic_smb_fname(ctx
,
838 if (smb_fname_parent
== NULL
) {
839 return NT_STATUS_NO_MEMORY
;
842 ret
= SMB_VFS_STAT(conn
, smb_fname_parent
);
844 status
= map_nt_error_from_unix(errno
);
845 DEBUG(0,("change_dir_owner_to_parent: failed to stat parent "
846 "directory %s. Error was %s\n",
847 smb_fname_str_dbg(smb_fname_parent
),
852 /* We've already done an lstat into psbuf, and we know it's a
853 directory. If we can cd into the directory and the dev/ino
854 are the same then we can safely chown without races as
855 we're locking the directory in place by being in it. This
856 should work on any UNIX (thanks tridge :-). JRA.
859 saved_dir
= vfs_GetWd(ctx
,conn
);
861 status
= map_nt_error_from_unix(errno
);
862 DEBUG(0,("change_dir_owner_to_parent: failed to get "
863 "current working directory. Error was %s\n",
868 /* Chdir into the new path. */
869 if (vfs_ChDir(conn
, fname
) == -1) {
870 status
= map_nt_error_from_unix(errno
);
871 DEBUG(0,("change_dir_owner_to_parent: failed to change "
872 "current working directory to %s. Error "
873 "was %s\n", fname
, strerror(errno
) ));
877 smb_fname_cwd
= synthetic_smb_fname(ctx
, ".", NULL
, NULL
, 0);
878 if (smb_fname_cwd
== NULL
) {
879 status
= NT_STATUS_NO_MEMORY
;
883 ret
= SMB_VFS_STAT(conn
, smb_fname_cwd
);
885 status
= map_nt_error_from_unix(errno
);
886 DEBUG(0,("change_dir_owner_to_parent: failed to stat "
887 "directory '.' (%s) Error was %s\n",
888 fname
, strerror(errno
)));
892 /* Ensure we're pointing at the same place. */
893 if (smb_fname_cwd
->st
.st_ex_dev
!= psbuf
->st_ex_dev
||
894 smb_fname_cwd
->st
.st_ex_ino
!= psbuf
->st_ex_ino
) {
895 DEBUG(0,("change_dir_owner_to_parent: "
896 "device/inode on directory %s changed. "
897 "Refusing to chown !\n", fname
));
898 status
= NT_STATUS_ACCESS_DENIED
;
902 if (smb_fname_parent
->st
.st_ex_uid
== smb_fname_cwd
->st
.st_ex_uid
) {
903 /* Already this uid - no need to change. */
904 DEBUG(10,("change_dir_owner_to_parent: directory %s "
905 "is already owned by uid %d\n",
907 (int)smb_fname_cwd
->st
.st_ex_uid
));
908 status
= NT_STATUS_OK
;
913 ret
= SMB_VFS_LCHOWN(conn
,
915 smb_fname_parent
->st
.st_ex_uid
,
919 status
= map_nt_error_from_unix(errno
);
920 DEBUG(10,("change_dir_owner_to_parent: failed to chown "
921 "directory %s to parent directory uid %u. "
922 "Error was %s\n", fname
,
923 (unsigned int)smb_fname_parent
->st
.st_ex_uid
,
926 DEBUG(10,("change_dir_owner_to_parent: changed ownership of new "
927 "directory %s to parent directory uid %u.\n",
928 fname
, (unsigned int)smb_fname_parent
->st
.st_ex_uid
));
929 /* Ensure the uid entry is updated. */
930 psbuf
->st_ex_uid
= smb_fname_parent
->st
.st_ex_uid
;
934 vfs_ChDir(conn
,saved_dir
);
936 TALLOC_FREE(smb_fname_parent
);
937 TALLOC_FREE(smb_fname_cwd
);
941 /****************************************************************************
942 Open a file - returning a guaranteed ATOMIC indication of if the
943 file was created or not.
944 ****************************************************************************/
946 static NTSTATUS
fd_open_atomic(struct connection_struct
*conn
,
952 NTSTATUS status
= NT_STATUS_UNSUCCESSFUL
;
953 NTSTATUS retry_status
;
954 bool file_existed
= VALID_STAT(fsp
->fsp_name
->st
);
957 *file_created
= false;
959 if (!(flags
& O_CREAT
)) {
961 * We're not creating the file, just pass through.
963 return fd_open(conn
, fsp
, flags
, mode
);
966 if (flags
& O_EXCL
) {
968 * Fail if already exists, just pass through.
970 status
= fd_open(conn
, fsp
, flags
, mode
);
973 * Here we've opened with O_CREAT|O_EXCL. If that went
974 * NT_STATUS_OK, we *know* we created this file.
976 *file_created
= NT_STATUS_IS_OK(status
);
982 * Now it gets tricky. We have O_CREAT, but not O_EXCL.
983 * To know absolutely if we created the file or not,
984 * we can never call O_CREAT without O_EXCL. So if
985 * we think the file existed, try without O_CREAT|O_EXCL.
986 * If we think the file didn't exist, try with
989 * The big problem here is dangling symlinks. Opening
990 * without O_NOFOLLOW means both bad symlink
991 * and missing path return -1, ENOENT from open(). As POSIX
992 * is pathname based it's not possible to tell
993 * the difference between these two cases in a
994 * non-racy way, so change to try only two attempts before
997 * We don't have this problem for the O_NOFOLLOW
998 * case as it just returns NT_STATUS_OBJECT_PATH_NOT_FOUND
999 * mapped from the ELOOP POSIX error.
1005 curr_flags
&= ~(O_CREAT
);
1006 retry_status
= NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1008 curr_flags
|= O_EXCL
;
1009 retry_status
= NT_STATUS_OBJECT_NAME_COLLISION
;
1012 status
= fd_open(conn
, fsp
, curr_flags
, mode
);
1013 if (NT_STATUS_IS_OK(status
)) {
1014 if (!file_existed
) {
1015 *file_created
= true;
1017 return NT_STATUS_OK
;
1019 if (!NT_STATUS_EQUAL(status
, retry_status
)) {
1026 * Keep file_existed up to date for clarity.
1028 if (NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
1029 file_existed
= false;
1030 curr_flags
|= O_EXCL
;
1031 DBG_DEBUG("file %s did not exist. Retry.\n",
1032 smb_fname_str_dbg(fsp
->fsp_name
));
1034 file_existed
= true;
1035 curr_flags
&= ~(O_CREAT
);
1036 DBG_DEBUG("file %s existed. Retry.\n",
1037 smb_fname_str_dbg(fsp
->fsp_name
));
1040 status
= fd_open(conn
, fsp
, curr_flags
, mode
);
1042 if (NT_STATUS_IS_OK(status
) && (!file_existed
)) {
1043 *file_created
= true;
1049 /****************************************************************************
1051 ****************************************************************************/
1053 static NTSTATUS
open_file(files_struct
*fsp
,
1054 connection_struct
*conn
,
1055 struct smb_request
*req
,
1056 const char *parent_dir
,
1059 uint32_t access_mask
, /* client requested access mask. */
1060 uint32_t open_access_mask
, /* what we're actually using in the open. */
1061 bool *p_file_created
)
1063 struct smb_filename
*smb_fname
= fsp
->fsp_name
;
1064 NTSTATUS status
= NT_STATUS_OK
;
1065 int accmode
= (flags
& O_ACCMODE
);
1066 int local_flags
= flags
;
1067 bool file_existed
= VALID_STAT(fsp
->fsp_name
->st
);
1072 /* Check permissions */
1075 * This code was changed after seeing a client open request
1076 * containing the open mode of (DENY_WRITE/read-only) with
1077 * the 'create if not exist' bit set. The previous code
1078 * would fail to open the file read only on a read-only share
1079 * as it was checking the flags parameter directly against O_RDONLY,
1080 * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
1084 if (!CAN_WRITE(conn
)) {
1085 /* It's a read-only share - fail if we wanted to write. */
1086 if(accmode
!= O_RDONLY
|| (flags
& O_TRUNC
) || (flags
& O_APPEND
)) {
1087 DEBUG(3,("Permission denied opening %s\n",
1088 smb_fname_str_dbg(smb_fname
)));
1089 return NT_STATUS_ACCESS_DENIED
;
1091 if (flags
& O_CREAT
) {
1092 /* We don't want to write - but we must make sure that
1093 O_CREAT doesn't create the file if we have write
1094 access into the directory.
1096 flags
&= ~(O_CREAT
|O_EXCL
);
1097 local_flags
&= ~(O_CREAT
|O_EXCL
);
1102 * This little piece of insanity is inspired by the
1103 * fact that an NT client can open a file for O_RDONLY,
1104 * but set the create disposition to FILE_EXISTS_TRUNCATE.
1105 * If the client *can* write to the file, then it expects to
1106 * truncate the file, even though it is opening for readonly.
1107 * Quicken uses this stupid trick in backup file creation...
1108 * Thanks *greatly* to "David W. Chapman Jr." <dwcjr@inethouston.net>
1109 * for helping track this one down. It didn't bite us in 2.0.x
1110 * as we always opened files read-write in that release. JRA.
1113 if ((accmode
== O_RDONLY
) && ((flags
& O_TRUNC
) == O_TRUNC
)) {
1114 DEBUG(10,("open_file: truncate requested on read-only open "
1115 "for file %s\n", smb_fname_str_dbg(smb_fname
)));
1116 local_flags
= (flags
& ~O_ACCMODE
)|O_RDWR
;
1119 if ((open_access_mask
& (FILE_READ_DATA
|FILE_WRITE_DATA
|FILE_APPEND_DATA
|FILE_EXECUTE
)) ||
1120 (!file_existed
&& (local_flags
& O_CREAT
)) ||
1121 ((local_flags
& O_TRUNC
) == O_TRUNC
) ) {
1125 #if defined(O_NONBLOCK) && defined(S_ISFIFO)
1127 * We would block on opening a FIFO with no one else on the
1128 * other end. Do what we used to do and add O_NONBLOCK to the
1132 if (file_existed
&& S_ISFIFO(smb_fname
->st
.st_ex_mode
)) {
1133 local_flags
&= ~O_TRUNC
; /* Can't truncate a FIFO. */
1134 local_flags
|= O_NONBLOCK
;
1138 /* Don't create files with Microsoft wildcard characters. */
1139 if (fsp
->base_fsp
) {
1141 * wildcard characters are allowed in stream names
1142 * only test the basefilename
1144 wild
= fsp
->base_fsp
->fsp_name
->base_name
;
1146 wild
= smb_fname
->base_name
;
1148 if ((local_flags
& O_CREAT
) && !file_existed
&&
1149 !(fsp
->posix_flags
& FSP_POSIX_FLAGS_PATHNAMES
) &&
1150 ms_has_wild(wild
)) {
1151 return NT_STATUS_OBJECT_NAME_INVALID
;
1154 /* Can we access this file ? */
1155 if (!fsp
->base_fsp
) {
1156 /* Only do this check on non-stream open. */
1158 status
= smbd_check_access_rights(conn
,
1163 if (!NT_STATUS_IS_OK(status
)) {
1164 DEBUG(10, ("open_file: "
1165 "smbd_check_access_rights "
1166 "on file %s returned %s\n",
1167 smb_fname_str_dbg(smb_fname
),
1168 nt_errstr(status
)));
1171 if (!NT_STATUS_IS_OK(status
) &&
1172 !NT_STATUS_EQUAL(status
,
1173 NT_STATUS_OBJECT_NAME_NOT_FOUND
))
1178 if (NT_STATUS_EQUAL(status
,
1179 NT_STATUS_OBJECT_NAME_NOT_FOUND
))
1181 DEBUG(10, ("open_file: "
1182 "file %s vanished since we "
1183 "checked for existence.\n",
1184 smb_fname_str_dbg(smb_fname
)));
1185 file_existed
= false;
1186 SET_STAT_INVALID(fsp
->fsp_name
->st
);
1190 if (!file_existed
) {
1191 if (!(local_flags
& O_CREAT
)) {
1192 /* File didn't exist and no O_CREAT. */
1193 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1196 status
= check_parent_access(conn
,
1199 if (!NT_STATUS_IS_OK(status
)) {
1200 DEBUG(10, ("open_file: "
1201 "check_parent_access on "
1202 "file %s returned %s\n",
1203 smb_fname_str_dbg(smb_fname
),
1204 nt_errstr(status
) ));
1211 * Actually do the open - if O_TRUNC is needed handle it
1212 * below under the share mode lock.
1214 status
= fd_open_atomic(conn
, fsp
, local_flags
& ~O_TRUNC
,
1215 unx_mode
, p_file_created
);
1216 if (!NT_STATUS_IS_OK(status
)) {
1217 DEBUG(3,("Error opening file %s (%s) (local_flags=%d) "
1218 "(flags=%d)\n", smb_fname_str_dbg(smb_fname
),
1219 nt_errstr(status
),local_flags
,flags
));
1223 if (local_flags
& O_NONBLOCK
) {
1225 * GPFS can return ETIMEDOUT for pread on
1226 * nonblocking file descriptors when files
1227 * migrated to tape need to be recalled. I
1228 * could imagine this happens elsehwere
1229 * too. With blocking file descriptors this
1232 ret
= set_blocking(fsp
->fh
->fd
, true);
1234 status
= map_nt_error_from_unix(errno
);
1235 DBG_WARNING("Could not set fd to blocking: "
1236 "%s\n", strerror(errno
));
1242 ret
= SMB_VFS_FSTAT(fsp
, &smb_fname
->st
);
1244 /* If we have an fd, this stat should succeed. */
1245 DEBUG(0,("Error doing fstat on open file %s "
1247 smb_fname_str_dbg(smb_fname
),
1249 status
= map_nt_error_from_unix(errno
);
1254 if (*p_file_created
) {
1255 /* We created this file. */
1257 bool need_re_stat
= false;
1258 /* Do all inheritance work after we've
1259 done a successful fstat call and filled
1260 in the stat struct in fsp->fsp_name. */
1262 /* Inherit the ACL if required */
1263 if (lp_inherit_permissions(SNUM(conn
))) {
1264 inherit_access_posix_acl(conn
, parent_dir
,
1265 smb_fname
->base_name
,
1267 need_re_stat
= true;
1270 /* Change the owner if required. */
1271 if (lp_inherit_owner(SNUM(conn
)) != INHERIT_OWNER_NO
) {
1272 change_file_owner_to_parent(conn
, parent_dir
,
1274 need_re_stat
= true;
1278 ret
= SMB_VFS_FSTAT(fsp
, &smb_fname
->st
);
1279 /* If we have an fd, this stat should succeed. */
1281 DEBUG(0,("Error doing fstat on open file %s "
1283 smb_fname_str_dbg(smb_fname
),
1288 notify_fname(conn
, NOTIFY_ACTION_ADDED
,
1289 FILE_NOTIFY_CHANGE_FILE_NAME
,
1290 smb_fname
->base_name
);
1293 fsp
->fh
->fd
= -1; /* What we used to call a stat open. */
1294 if (!file_existed
) {
1295 /* File must exist for a stat open. */
1296 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1299 status
= smbd_check_access_rights(conn
,
1304 if (NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
) &&
1305 (fsp
->posix_flags
& FSP_POSIX_FLAGS_OPEN
) &&
1306 S_ISLNK(smb_fname
->st
.st_ex_mode
)) {
1307 /* This is a POSIX stat open for delete
1308 * or rename on a symlink that points
1309 * nowhere. Allow. */
1310 DEBUG(10,("open_file: allowing POSIX "
1311 "open on bad symlink %s\n",
1312 smb_fname_str_dbg(smb_fname
)));
1313 status
= NT_STATUS_OK
;
1316 if (!NT_STATUS_IS_OK(status
)) {
1317 DEBUG(10,("open_file: "
1318 "smbd_check_access_rights on file "
1320 smb_fname_str_dbg(smb_fname
),
1321 nt_errstr(status
) ));
1327 * POSIX allows read-only opens of directories. We don't
1328 * want to do this (we use a different code path for this)
1329 * so catch a directory open and return an EISDIR. JRA.
1332 if(S_ISDIR(smb_fname
->st
.st_ex_mode
)) {
1335 return NT_STATUS_FILE_IS_A_DIRECTORY
;
1338 fsp
->file_id
= vfs_file_id_from_sbuf(conn
, &smb_fname
->st
);
1339 fsp
->vuid
= req
? req
->vuid
: UID_FIELD_INVALID
;
1340 fsp
->file_pid
= req
? req
->smbpid
: 0;
1341 fsp
->can_lock
= True
;
1342 fsp
->can_read
= ((access_mask
& FILE_READ_DATA
) != 0);
1345 ((access_mask
& (FILE_WRITE_DATA
| FILE_APPEND_DATA
)) != 0);
1346 fsp
->print_file
= NULL
;
1347 fsp
->modified
= False
;
1348 fsp
->sent_oplock_break
= NO_BREAK_SENT
;
1349 fsp
->is_directory
= False
;
1350 if (conn
->aio_write_behind_list
&&
1351 is_in_path(smb_fname
->base_name
, conn
->aio_write_behind_list
,
1352 conn
->case_sensitive
)) {
1353 fsp
->aio_write_behind
= True
;
1356 fsp
->wcp
= NULL
; /* Write cache pointer. */
1358 DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
1359 conn
->session_info
->unix_info
->unix_name
,
1360 smb_fname_str_dbg(smb_fname
),
1361 BOOLSTR(fsp
->can_read
), BOOLSTR(fsp
->can_write
),
1362 conn
->num_files_open
));
1365 return NT_STATUS_OK
;
1368 /****************************************************************************
1369 Check if we can open a file with a share mode.
1370 Returns True if conflict, False if not.
1371 ****************************************************************************/
1373 static bool share_conflict(struct share_mode_entry
*entry
,
1374 uint32_t access_mask
,
1375 uint32_t share_access
)
1377 DEBUG(10,("share_conflict: entry->access_mask = 0x%x, "
1378 "entry->share_access = 0x%x, "
1379 "entry->private_options = 0x%x\n",
1380 (unsigned int)entry
->access_mask
,
1381 (unsigned int)entry
->share_access
,
1382 (unsigned int)entry
->private_options
));
1384 if (server_id_is_disconnected(&entry
->pid
)) {
1386 * note: cleanup should have been done by
1387 * delay_for_batch_oplocks()
1392 DEBUG(10,("share_conflict: access_mask = 0x%x, share_access = 0x%x\n",
1393 (unsigned int)access_mask
, (unsigned int)share_access
));
1395 if ((entry
->access_mask
& (FILE_WRITE_DATA
|
1399 DELETE_ACCESS
)) == 0) {
1400 DEBUG(10,("share_conflict: No conflict due to "
1401 "entry->access_mask = 0x%x\n",
1402 (unsigned int)entry
->access_mask
));
1406 if ((access_mask
& (FILE_WRITE_DATA
|
1410 DELETE_ACCESS
)) == 0) {
1411 DEBUG(10,("share_conflict: No conflict due to "
1412 "access_mask = 0x%x\n",
1413 (unsigned int)access_mask
));
1417 #if 1 /* JRA TEST - Superdebug. */
1418 #define CHECK_MASK(num, am, right, sa, share) \
1419 DEBUG(10,("share_conflict: [%d] am (0x%x) & right (0x%x) = 0x%x\n", \
1420 (unsigned int)(num), (unsigned int)(am), \
1421 (unsigned int)(right), (unsigned int)(am)&(right) )); \
1422 DEBUG(10,("share_conflict: [%d] sa (0x%x) & share (0x%x) = 0x%x\n", \
1423 (unsigned int)(num), (unsigned int)(sa), \
1424 (unsigned int)(share), (unsigned int)(sa)&(share) )); \
1425 if (((am) & (right)) && !((sa) & (share))) { \
1426 DEBUG(10,("share_conflict: check %d conflict am = 0x%x, right = 0x%x, \
1427 sa = 0x%x, share = 0x%x\n", (num), (unsigned int)(am), (unsigned int)(right), (unsigned int)(sa), \
1428 (unsigned int)(share) )); \
1432 #define CHECK_MASK(num, am, right, sa, share) \
1433 if (((am) & (right)) && !((sa) & (share))) { \
1434 DEBUG(10,("share_conflict: check %d conflict am = 0x%x, right = 0x%x, \
1435 sa = 0x%x, share = 0x%x\n", (num), (unsigned int)(am), (unsigned int)(right), (unsigned int)(sa), \
1436 (unsigned int)(share) )); \
1441 CHECK_MASK(1, entry
->access_mask
, FILE_WRITE_DATA
| FILE_APPEND_DATA
,
1442 share_access
, FILE_SHARE_WRITE
);
1443 CHECK_MASK(2, access_mask
, FILE_WRITE_DATA
| FILE_APPEND_DATA
,
1444 entry
->share_access
, FILE_SHARE_WRITE
);
1446 CHECK_MASK(3, entry
->access_mask
, FILE_READ_DATA
| FILE_EXECUTE
,
1447 share_access
, FILE_SHARE_READ
);
1448 CHECK_MASK(4, access_mask
, FILE_READ_DATA
| FILE_EXECUTE
,
1449 entry
->share_access
, FILE_SHARE_READ
);
1451 CHECK_MASK(5, entry
->access_mask
, DELETE_ACCESS
,
1452 share_access
, FILE_SHARE_DELETE
);
1453 CHECK_MASK(6, access_mask
, DELETE_ACCESS
,
1454 entry
->share_access
, FILE_SHARE_DELETE
);
1456 DEBUG(10,("share_conflict: No conflict.\n"));
1460 #if defined(DEVELOPER)
1461 static void validate_my_share_entries(struct smbd_server_connection
*sconn
,
1463 struct share_mode_entry
*share_entry
)
1465 struct server_id self
= messaging_server_id(sconn
->msg_ctx
);
1468 if (!serverid_equal(&self
, &share_entry
->pid
)) {
1472 if (share_entry
->op_mid
== 0) {
1473 /* INTERNAL_OPEN_ONLY */
1477 if (!is_valid_share_mode_entry(share_entry
)) {
1481 fsp
= file_find_dif(sconn
, share_entry
->id
,
1482 share_entry
->share_file_id
);
1484 DEBUG(0,("validate_my_share_entries: PANIC : %s\n",
1485 share_mode_str(talloc_tos(), num
, share_entry
) ));
1486 smb_panic("validate_my_share_entries: Cannot match a "
1487 "share entry with an open file\n");
1490 if (((uint16_t)fsp
->oplock_type
) != share_entry
->op_type
) {
1499 DEBUG(0,("validate_my_share_entries: PANIC : %s\n",
1500 share_mode_str(talloc_tos(), num
, share_entry
) ));
1501 str
= talloc_asprintf(talloc_tos(),
1502 "validate_my_share_entries: "
1503 "file %s, oplock_type = 0x%x, op_type = 0x%x\n",
1504 fsp
->fsp_name
->base_name
,
1505 (unsigned int)fsp
->oplock_type
,
1506 (unsigned int)share_entry
->op_type
);
1512 bool is_stat_open(uint32_t access_mask
)
1514 const uint32_t stat_open_bits
=
1515 (SYNCHRONIZE_ACCESS
|
1516 FILE_READ_ATTRIBUTES
|
1517 FILE_WRITE_ATTRIBUTES
);
1519 return (((access_mask
& stat_open_bits
) != 0) &&
1520 ((access_mask
& ~stat_open_bits
) == 0));
1523 static bool has_delete_on_close(struct share_mode_lock
*lck
,
1526 struct share_mode_data
*d
= lck
->data
;
1529 if (d
->num_share_modes
== 0) {
1532 if (!is_delete_on_close_set(lck
, name_hash
)) {
1535 for (i
=0; i
<d
->num_share_modes
; i
++) {
1536 if (!share_mode_stale_pid(d
, i
)) {
1543 /****************************************************************************
1544 Deal with share modes
1545 Invariant: Share mode must be locked on entry and exit.
1546 Returns -1 on error, or number of share modes on success (may be zero).
1547 ****************************************************************************/
1549 static NTSTATUS
open_mode_check(connection_struct
*conn
,
1550 struct share_mode_lock
*lck
,
1551 uint32_t access_mask
,
1552 uint32_t share_access
)
1556 if(lck
->data
->num_share_modes
== 0) {
1557 return NT_STATUS_OK
;
1560 if (is_stat_open(access_mask
)) {
1561 /* Stat open that doesn't trigger oplock breaks or share mode
1562 * checks... ! JRA. */
1563 return NT_STATUS_OK
;
1567 * Check if the share modes will give us access.
1570 #if defined(DEVELOPER)
1571 for(i
= 0; i
< lck
->data
->num_share_modes
; i
++) {
1572 validate_my_share_entries(conn
->sconn
, i
,
1573 &lck
->data
->share_modes
[i
]);
1577 /* Now we check the share modes, after any oplock breaks. */
1578 for(i
= 0; i
< lck
->data
->num_share_modes
; i
++) {
1580 if (!is_valid_share_mode_entry(&lck
->data
->share_modes
[i
])) {
1584 /* someone else has a share lock on it, check to see if we can
1586 if (share_conflict(&lck
->data
->share_modes
[i
],
1587 access_mask
, share_access
)) {
1589 if (share_mode_stale_pid(lck
->data
, i
)) {
1593 return NT_STATUS_SHARING_VIOLATION
;
1597 return NT_STATUS_OK
;
1601 * Send a break message to the oplock holder and delay the open for
1605 NTSTATUS
send_break_message(struct messaging_context
*msg_ctx
,
1606 const struct share_mode_entry
*exclusive
,
1610 char msg
[MSG_SMB_SHARE_MODE_ENTRY_SIZE
];
1611 struct server_id_buf tmp
;
1613 DEBUG(10, ("Sending break request to PID %s\n",
1614 server_id_str_buf(exclusive
->pid
, &tmp
)));
1616 /* Create the message. */
1617 share_mode_entry_to_message(msg
, exclusive
);
1619 /* Overload entry->op_type */
1621 * This is a cut from uint32_t to uint16_t, but so far only the lower 3
1622 * bits (LEASE_WRITE/HANDLE/READ are used anyway.
1624 SSVAL(msg
,OP_BREAK_MSG_OP_TYPE_OFFSET
, break_to
);
1626 status
= messaging_send_buf(msg_ctx
, exclusive
->pid
,
1627 MSG_SMB_BREAK_REQUEST
,
1628 (uint8_t *)msg
, sizeof(msg
));
1629 if (!NT_STATUS_IS_OK(status
)) {
1630 DEBUG(3, ("Could not send oplock break message: %s\n",
1631 nt_errstr(status
)));
1638 * Do internal consistency checks on the share mode for a file.
1641 static bool validate_oplock_types(struct share_mode_lock
*lck
)
1643 struct share_mode_data
*d
= lck
->data
;
1645 bool ex_or_batch
= false;
1646 bool level2
= false;
1647 bool no_oplock
= false;
1648 uint32_t num_non_stat_opens
= 0;
1651 for (i
=0; i
<d
->num_share_modes
; i
++) {
1652 struct share_mode_entry
*e
= &d
->share_modes
[i
];
1654 if (!is_valid_share_mode_entry(e
)) {
1658 if (e
->op_mid
== 0) {
1659 /* INTERNAL_OPEN_ONLY */
1663 if (e
->op_type
== NO_OPLOCK
&& is_stat_open(e
->access_mask
)) {
1664 /* We ignore stat opens in the table - they
1665 always have NO_OPLOCK and never get or
1666 cause breaks. JRA. */
1670 num_non_stat_opens
+= 1;
1672 if (BATCH_OPLOCK_TYPE(e
->op_type
)) {
1673 /* batch - can only be one. */
1674 if (share_mode_stale_pid(d
, i
)) {
1675 DEBUG(10, ("Found stale batch oplock\n"));
1678 if (ex_or_batch
|| batch
|| level2
|| no_oplock
) {
1679 DEBUG(0, ("Bad batch oplock entry %u.",
1686 if (EXCLUSIVE_OPLOCK_TYPE(e
->op_type
)) {
1687 if (share_mode_stale_pid(d
, i
)) {
1688 DEBUG(10, ("Found stale duplicate oplock\n"));
1691 /* Exclusive or batch - can only be one. */
1692 if (ex_or_batch
|| level2
|| no_oplock
) {
1693 DEBUG(0, ("Bad exclusive or batch oplock "
1694 "entry %u.", (unsigned)i
));
1700 if (LEVEL_II_OPLOCK_TYPE(e
->op_type
)) {
1701 if (batch
|| ex_or_batch
) {
1702 if (share_mode_stale_pid(d
, i
)) {
1703 DEBUG(10, ("Found stale LevelII "
1707 DEBUG(0, ("Bad levelII oplock entry %u.",
1714 if (e
->op_type
== NO_OPLOCK
) {
1715 if (batch
|| ex_or_batch
) {
1716 if (share_mode_stale_pid(d
, i
)) {
1717 DEBUG(10, ("Found stale NO_OPLOCK "
1721 DEBUG(0, ("Bad no oplock entry %u.",
1729 remove_stale_share_mode_entries(d
);
1731 if ((batch
|| ex_or_batch
) && (num_non_stat_opens
!= 1)) {
1732 DEBUG(1, ("got batch (%d) or ex (%d) non-exclusively (%d)\n",
1733 (int)batch
, (int)ex_or_batch
,
1734 (int)d
->num_share_modes
));
1741 static bool delay_for_oplock(files_struct
*fsp
,
1743 const struct smb2_lease
*lease
,
1744 struct share_mode_lock
*lck
,
1745 bool have_sharing_violation
,
1746 uint32_t create_disposition
,
1747 bool first_open_attempt
)
1749 struct share_mode_data
*d
= lck
->data
;
1752 bool will_overwrite
;
1754 if ((oplock_request
& INTERNAL_OPEN_ONLY
) ||
1755 is_stat_open(fsp
->access_mask
)) {
1759 switch (create_disposition
) {
1760 case FILE_SUPERSEDE
:
1761 case FILE_OVERWRITE
:
1762 case FILE_OVERWRITE_IF
:
1763 will_overwrite
= true;
1766 will_overwrite
= false;
1770 for (i
=0; i
<d
->num_share_modes
; i
++) {
1771 struct share_mode_entry
*e
= &d
->share_modes
[i
];
1772 struct share_mode_lease
*l
= NULL
;
1773 uint32_t e_lease_type
= get_lease_type(d
, e
);
1775 uint32_t delay_mask
= 0;
1777 if (e
->op_type
== LEASE_OPLOCK
) {
1778 l
= &d
->leases
[e
->lease_idx
];
1781 if (have_sharing_violation
) {
1782 delay_mask
= SMB2_LEASE_HANDLE
;
1784 delay_mask
= SMB2_LEASE_WRITE
;
1787 break_to
= e_lease_type
& ~delay_mask
;
1789 if (will_overwrite
) {
1791 * we'll decide about SMB2_LEASE_READ later.
1793 * Maybe the break will be defered
1795 break_to
&= ~SMB2_LEASE_HANDLE
;
1798 DEBUG(10, ("entry %u: e_lease_type %u, will_overwrite: %u\n",
1799 (unsigned)i
, (unsigned)e_lease_type
,
1800 (unsigned)will_overwrite
));
1802 if (lease
!= NULL
&& l
!= NULL
) {
1805 ign
= smb2_lease_equal(fsp_client_guid(fsp
),
1814 if ((e_lease_type
& ~break_to
) == 0) {
1815 if (l
!= NULL
&& l
->breaking
) {
1821 if (share_mode_stale_pid(d
, i
)) {
1825 if (will_overwrite
) {
1827 * If we break anyway break to NONE directly.
1828 * Otherwise vfs_set_filelen() will trigger the
1831 break_to
&= ~(SMB2_LEASE_READ
|SMB2_LEASE_WRITE
);
1834 if (e
->op_type
!= LEASE_OPLOCK
) {
1836 * Oplocks only support breaking to R or NONE.
1838 break_to
&= ~(SMB2_LEASE_HANDLE
|SMB2_LEASE_WRITE
);
1841 DEBUG(10, ("breaking from %d to %d\n",
1842 (int)e_lease_type
, (int)break_to
));
1843 send_break_message(fsp
->conn
->sconn
->msg_ctx
, e
,
1845 if (e_lease_type
& delay_mask
) {
1848 if (l
!= NULL
&& l
->breaking
&& !first_open_attempt
) {
1858 * Return lease or oplock state from a share mode
1860 static uint32_t get_lease_type_from_share_mode(const struct share_mode_data
*d
)
1862 uint32_t e_lease_type
= 0;
1865 for (i
=0; i
< d
->num_share_modes
; i
++) {
1866 struct share_mode_entry
*e
= &d
->share_modes
[i
];
1868 e_lease_type
|= get_lease_type(d
, e
);
1871 return e_lease_type
;
1874 static bool file_has_brlocks(files_struct
*fsp
)
1876 struct byte_range_lock
*br_lck
;
1878 br_lck
= brl_get_locks_readonly(fsp
);
1882 return (brl_num_locks(br_lck
) > 0);
1885 int find_share_mode_lease(struct share_mode_data
*d
,
1886 const struct GUID
*client_guid
,
1887 const struct smb2_lease_key
*key
)
1891 for (i
=0; i
<d
->num_leases
; i
++) {
1892 struct share_mode_lease
*l
= &d
->leases
[i
];
1894 if (smb2_lease_equal(client_guid
,
1905 struct fsp_lease
*find_fsp_lease(struct files_struct
*new_fsp
,
1906 const struct smb2_lease_key
*key
,
1907 const struct share_mode_lease
*l
)
1909 struct files_struct
*fsp
;
1912 * TODO: Measure how expensive this loop is with thousands of open
1916 for (fsp
= file_find_di_first(new_fsp
->conn
->sconn
, new_fsp
->file_id
);
1918 fsp
= file_find_di_next(fsp
)) {
1920 if (fsp
== new_fsp
) {
1923 if (fsp
->oplock_type
!= LEASE_OPLOCK
) {
1926 if (smb2_lease_key_equal(&fsp
->lease
->lease
.lease_key
, key
)) {
1927 fsp
->lease
->ref_count
+= 1;
1932 /* Not found - must be leased in another smbd. */
1933 new_fsp
->lease
= talloc_zero(new_fsp
->conn
->sconn
, struct fsp_lease
);
1934 if (new_fsp
->lease
== NULL
) {
1937 new_fsp
->lease
->ref_count
= 1;
1938 new_fsp
->lease
->sconn
= new_fsp
->conn
->sconn
;
1939 new_fsp
->lease
->lease
.lease_key
= *key
;
1940 new_fsp
->lease
->lease
.lease_state
= l
->current_state
;
1942 * We internally treat all leases as V2 and update
1943 * the epoch, but when sending breaks it matters if
1944 * the requesting lease was v1 or v2.
1946 new_fsp
->lease
->lease
.lease_version
= l
->lease_version
;
1947 new_fsp
->lease
->lease
.lease_epoch
= l
->epoch
;
1948 return new_fsp
->lease
;
1951 static NTSTATUS
grant_fsp_lease(struct files_struct
*fsp
,
1952 struct share_mode_lock
*lck
,
1953 const struct smb2_lease
*lease
,
1954 uint32_t *p_lease_idx
,
1957 struct share_mode_data
*d
= lck
->data
;
1958 const struct GUID
*client_guid
= fsp_client_guid(fsp
);
1959 struct share_mode_lease
*tmp
;
1963 idx
= find_share_mode_lease(d
, client_guid
, &lease
->lease_key
);
1966 struct share_mode_lease
*l
= &d
->leases
[idx
];
1968 uint32_t existing
, requested
;
1970 fsp
->lease
= find_fsp_lease(fsp
, &lease
->lease_key
, l
);
1971 if (fsp
->lease
== NULL
) {
1972 DEBUG(1, ("Did not find existing lease for file %s\n",
1974 return NT_STATUS_NO_MEMORY
;
1980 * Upgrade only if the requested lease is a strict upgrade.
1982 existing
= l
->current_state
;
1983 requested
= lease
->lease_state
;
1986 * Tricky: This test makes sure that "requested" is a
1987 * strict bitwise superset of "existing".
1989 do_upgrade
= ((existing
& requested
) == existing
);
1992 * Upgrade only if there's a change.
1994 do_upgrade
&= (granted
!= existing
);
1997 * Upgrade only if other leases don't prevent what was asked
2000 do_upgrade
&= (granted
== requested
);
2003 * only upgrade if we are not in breaking state
2005 do_upgrade
&= !l
->breaking
;
2007 DEBUG(10, ("existing=%"PRIu32
", requested=%"PRIu32
", "
2008 "granted=%"PRIu32
", do_upgrade=%d\n",
2009 existing
, requested
, granted
, (int)do_upgrade
));
2012 l
->current_state
= granted
;
2016 /* Ensure we're in sync with current lease state. */
2017 fsp_lease_update(lck
, fsp_client_guid(fsp
), fsp
->lease
);
2018 return NT_STATUS_OK
;
2025 tmp
= talloc_realloc(d
, d
->leases
, struct share_mode_lease
,
2031 return NT_STATUS_INSUFFICIENT_RESOURCES
;
2035 fsp
->lease
= talloc_zero(fsp
->conn
->sconn
, struct fsp_lease
);
2036 if (fsp
->lease
== NULL
) {
2037 return NT_STATUS_INSUFFICIENT_RESOURCES
;
2039 fsp
->lease
->ref_count
= 1;
2040 fsp
->lease
->sconn
= fsp
->conn
->sconn
;
2041 fsp
->lease
->lease
.lease_version
= lease
->lease_version
;
2042 fsp
->lease
->lease
.lease_key
= lease
->lease_key
;
2043 fsp
->lease
->lease
.lease_state
= granted
;
2044 fsp
->lease
->lease
.lease_epoch
= lease
->lease_epoch
+ 1;
2046 *p_lease_idx
= d
->num_leases
;
2048 d
->leases
[d
->num_leases
] = (struct share_mode_lease
) {
2049 .client_guid
= *client_guid
,
2050 .lease_key
= fsp
->lease
->lease
.lease_key
,
2051 .current_state
= fsp
->lease
->lease
.lease_state
,
2052 .lease_version
= fsp
->lease
->lease
.lease_version
,
2053 .epoch
= fsp
->lease
->lease
.lease_epoch
,
2056 status
= leases_db_add(client_guid
,
2059 fsp
->conn
->connectpath
,
2060 fsp
->fsp_name
->base_name
,
2061 fsp
->fsp_name
->stream_name
);
2062 if (!NT_STATUS_IS_OK(status
)) {
2063 DEBUG(10, ("%s: leases_db_add failed: %s\n", __func__
,
2064 nt_errstr(status
)));
2065 TALLOC_FREE(fsp
->lease
);
2066 return NT_STATUS_INSUFFICIENT_RESOURCES
;
2072 return NT_STATUS_OK
;
2075 static bool is_same_lease(const files_struct
*fsp
,
2076 const struct share_mode_data
*d
,
2077 const struct share_mode_entry
*e
,
2078 const struct smb2_lease
*lease
)
2080 if (e
->op_type
!= LEASE_OPLOCK
) {
2083 if (lease
== NULL
) {
2087 return smb2_lease_equal(fsp_client_guid(fsp
),
2089 &d
->leases
[e
->lease_idx
].client_guid
,
2090 &d
->leases
[e
->lease_idx
].lease_key
);
2093 static NTSTATUS
grant_fsp_oplock_type(struct smb_request
*req
,
2094 struct files_struct
*fsp
,
2095 struct share_mode_lock
*lck
,
2097 struct smb2_lease
*lease
)
2099 struct share_mode_data
*d
= lck
->data
;
2100 bool got_handle_lease
= false;
2101 bool got_oplock
= false;
2104 uint32_t lease_idx
= UINT32_MAX
;
2108 if (oplock_request
& INTERNAL_OPEN_ONLY
) {
2109 /* No oplocks on internal open. */
2110 oplock_request
= NO_OPLOCK
;
2111 DEBUG(10,("grant_fsp_oplock_type: oplock type 0x%x on file %s\n",
2112 fsp
->oplock_type
, fsp_str_dbg(fsp
)));
2115 if (oplock_request
== LEASE_OPLOCK
) {
2116 if (lease
== NULL
) {
2118 * The SMB2 layer should have checked this
2120 return NT_STATUS_INTERNAL_ERROR
;
2123 granted
= lease
->lease_state
;
2125 if (lp_kernel_oplocks(SNUM(fsp
->conn
))) {
2126 DEBUG(10, ("No lease granted because kernel oplocks are enabled\n"));
2127 granted
= SMB2_LEASE_NONE
;
2129 if ((granted
& (SMB2_LEASE_READ
|SMB2_LEASE_WRITE
)) == 0) {
2130 DEBUG(10, ("No read or write lease requested\n"));
2131 granted
= SMB2_LEASE_NONE
;
2133 if (granted
== SMB2_LEASE_WRITE
) {
2134 DEBUG(10, ("pure write lease requested\n"));
2135 granted
= SMB2_LEASE_NONE
;
2137 if (granted
== (SMB2_LEASE_WRITE
|SMB2_LEASE_HANDLE
)) {
2138 DEBUG(10, ("write and handle lease requested\n"));
2139 granted
= SMB2_LEASE_NONE
;
2142 granted
= map_oplock_to_lease_type(
2143 oplock_request
& ~SAMBA_PRIVATE_OPLOCK_MASK
);
2146 if (lp_locking(fsp
->conn
->params
) && file_has_brlocks(fsp
)) {
2147 DEBUG(10,("grant_fsp_oplock_type: file %s has byte range locks\n",
2149 granted
&= ~SMB2_LEASE_READ
;
2152 for (i
=0; i
<d
->num_share_modes
; i
++) {
2153 struct share_mode_entry
*e
= &d
->share_modes
[i
];
2154 uint32_t e_lease_type
;
2156 e_lease_type
= get_lease_type(d
, e
);
2158 if ((granted
& SMB2_LEASE_WRITE
) &&
2159 !is_same_lease(fsp
, d
, e
, lease
) &&
2160 !share_mode_stale_pid(d
, i
)) {
2162 * Can grant only one writer
2164 granted
&= ~SMB2_LEASE_WRITE
;
2167 if ((e_lease_type
& SMB2_LEASE_HANDLE
) && !got_handle_lease
&&
2168 !share_mode_stale_pid(d
, i
)) {
2169 got_handle_lease
= true;
2172 if ((e
->op_type
!= LEASE_OPLOCK
) && !got_oplock
&&
2173 !share_mode_stale_pid(d
, i
)) {
2178 if ((granted
& SMB2_LEASE_READ
) && !(granted
& SMB2_LEASE_WRITE
)) {
2180 (global_client_caps
& CAP_LEVEL_II_OPLOCKS
) &&
2181 lp_level2_oplocks(SNUM(fsp
->conn
));
2183 if (!allow_level2
) {
2184 granted
= SMB2_LEASE_NONE
;
2188 if (oplock_request
== LEASE_OPLOCK
) {
2190 granted
&= ~SMB2_LEASE_HANDLE
;
2193 fsp
->oplock_type
= LEASE_OPLOCK
;
2195 status
= grant_fsp_lease(fsp
, lck
, lease
, &lease_idx
,
2197 if (!NT_STATUS_IS_OK(status
)) {
2201 *lease
= fsp
->lease
->lease
;
2202 DEBUG(10, ("lease_state=%d\n", lease
->lease_state
));
2204 if (got_handle_lease
) {
2205 granted
= SMB2_LEASE_NONE
;
2209 case SMB2_LEASE_READ
|SMB2_LEASE_WRITE
|SMB2_LEASE_HANDLE
:
2210 fsp
->oplock_type
= BATCH_OPLOCK
|EXCLUSIVE_OPLOCK
;
2212 case SMB2_LEASE_READ
|SMB2_LEASE_WRITE
:
2213 fsp
->oplock_type
= EXCLUSIVE_OPLOCK
;
2215 case SMB2_LEASE_READ
|SMB2_LEASE_HANDLE
:
2216 case SMB2_LEASE_READ
:
2217 fsp
->oplock_type
= LEVEL_II_OPLOCK
;
2220 fsp
->oplock_type
= NO_OPLOCK
;
2224 status
= set_file_oplock(fsp
);
2225 if (!NT_STATUS_IS_OK(status
)) {
2227 * Could not get the kernel oplock
2229 fsp
->oplock_type
= NO_OPLOCK
;
2233 ok
= set_share_mode(lck
, fsp
, get_current_uid(fsp
->conn
),
2238 return NT_STATUS_NO_MEMORY
;
2241 ok
= update_num_read_oplocks(fsp
, lck
);
2243 del_share_mode(lck
, fsp
);
2244 return NT_STATUS_INTERNAL_ERROR
;
2247 DEBUG(10,("grant_fsp_oplock_type: oplock type 0x%x on file %s\n",
2248 fsp
->oplock_type
, fsp_str_dbg(fsp
)));
2250 return NT_STATUS_OK
;
2253 static bool request_timed_out(struct timeval request_time
,
2254 struct timeval timeout
)
2256 struct timeval now
, end_time
;
2258 end_time
= timeval_sum(&request_time
, &timeout
);
2259 return (timeval_compare(&end_time
, &now
) < 0);
2262 static struct deferred_open_record
*deferred_open_record_create(
2263 bool delayed_for_oplocks
,
2267 struct deferred_open_record
*record
= NULL
;
2269 record
= talloc(NULL
, struct deferred_open_record
);
2270 if (record
== NULL
) {
2274 *record
= (struct deferred_open_record
) {
2275 .delayed_for_oplocks
= delayed_for_oplocks
,
2276 .async_open
= async_open
,
2283 struct defer_open_state
{
2284 struct smbXsrv_connection
*xconn
;
2286 struct file_id file_id
;
2287 struct timeval request_time
;
2288 struct timeval timeout
;
2290 uint32_t lease_type
;
2293 static void defer_open_done(struct tevent_req
*req
);
2296 * Defer an open and watch a locking.tdb record
2298 * This defers an open that gets rescheduled once the locking.tdb record watch
2299 * is triggered by a change to the record.
2301 * It is used to defer opens that triggered an oplock break and for the SMB1
2302 * sharing violation delay.
2304 static void defer_open(struct share_mode_lock
*lck
,
2305 struct timeval request_time
,
2306 struct timeval timeout
,
2307 struct smb_request
*req
,
2308 bool delayed_for_oplocks
,
2312 struct deferred_open_record
*open_rec
= NULL
;
2313 struct timeval abs_timeout
;
2314 struct defer_open_state
*watch_state
;
2315 struct tevent_req
*watch_req
;
2318 abs_timeout
= timeval_sum(&request_time
, &timeout
);
2320 DBG_DEBUG("request time [%s] timeout [%s] mid [%" PRIu64
"] "
2321 "delayed_for_oplocks [%s] kernel_oplock [%s] file_id [%s]\n",
2322 timeval_string(talloc_tos(), &request_time
, false),
2323 timeval_string(talloc_tos(), &abs_timeout
, false),
2325 delayed_for_oplocks
? "yes" : "no",
2326 kernel_oplock
? "yes" : "no",
2327 file_id_string_tos(&id
));
2329 open_rec
= deferred_open_record_create(delayed_for_oplocks
,
2332 if (open_rec
== NULL
) {
2334 exit_server("talloc failed");
2337 watch_state
= talloc(open_rec
, struct defer_open_state
);
2338 if (watch_state
== NULL
) {
2339 exit_server("talloc failed");
2341 watch_state
->xconn
= req
->xconn
;
2342 watch_state
->mid
= req
->mid
;
2343 watch_state
->file_id
= lck
->data
->id
;
2344 watch_state
->request_time
= request_time
;
2345 watch_state
->timeout
= timeout
;
2346 watch_state
->kernel_oplock
= kernel_oplock
;
2347 watch_state
->lease_type
= get_lease_type_from_share_mode(lck
->data
);
2349 DBG_DEBUG("defering mid %" PRIu64
"\n", req
->mid
);
2351 watch_req
= dbwrap_watched_watch_send(watch_state
,
2354 (struct server_id
){0});
2355 if (watch_req
== NULL
) {
2356 exit_server("Could not watch share mode record");
2358 tevent_req_set_callback(watch_req
, defer_open_done
, watch_state
);
2360 ok
= tevent_req_set_endtime(watch_req
, req
->sconn
->ev_ctx
, abs_timeout
);
2362 exit_server("tevent_req_set_endtime failed");
2365 ok
= push_deferred_open_message_smb(req
, request_time
, timeout
,
2366 open_rec
->id
, open_rec
);
2369 exit_server("push_deferred_open_message_smb failed");
2373 static void defer_open_done(struct tevent_req
*req
)
2375 struct defer_open_state
*state
= tevent_req_callback_data(
2376 req
, struct defer_open_state
);
2377 struct tevent_req
*watch_req
= NULL
;
2378 struct share_mode_lock
*lck
= NULL
;
2379 bool schedule_req
= true;
2380 struct timeval timeout
;
2384 status
= dbwrap_watched_watch_recv(req
, talloc_tos(), NULL
, NULL
,
2387 if (!NT_STATUS_IS_OK(status
)) {
2388 DEBUG(5, ("dbwrap_watched_watch_recv returned %s\n",
2389 nt_errstr(status
)));
2391 * Even if it failed, retry anyway. TODO: We need a way to
2392 * tell a re-scheduled open about that error.
2394 if (NT_STATUS_EQUAL(status
, NT_STATUS_IO_TIMEOUT
) &&
2395 state
->kernel_oplock
)
2398 * If we reschedule but the kernel oplock is still hold
2399 * we would block in the second open as that will be a
2400 * blocking open attempt.
2402 exit_server("Kernel oplock holder didn't "
2403 "respond to break message");
2407 if (state
->kernel_oplock
) {
2408 lck
= get_existing_share_mode_lock(talloc_tos(), state
->file_id
);
2410 uint32_t lease_type
;
2412 lease_type
= get_lease_type_from_share_mode(lck
->data
);
2414 if ((lease_type
!= 0) &&
2415 (lease_type
== state
->lease_type
))
2417 DBG_DEBUG("Unchanged lease: %" PRIu32
"\n",
2419 schedule_req
= false;
2425 DBG_DEBUG("scheduling mid %" PRIu64
"\n", state
->mid
);
2427 ok
= schedule_deferred_open_message_smb(state
->xconn
,
2430 exit_server("schedule_deferred_open_message_smb failed");
2437 DBG_DEBUG("Keep waiting for oplock release for [%s/%s%s] "
2438 "mid: %" PRIu64
"\n",
2439 lck
->data
->servicepath
,
2440 lck
->data
->base_name
,
2441 lck
->data
->stream_name
? lck
->data
->stream_name
: "",
2444 watch_req
= dbwrap_watched_watch_send(state
,
2445 state
->xconn
->ev_ctx
,
2447 (struct server_id
){0});
2448 if (watch_req
== NULL
) {
2449 exit_server("Could not watch share mode record");
2451 tevent_req_set_callback(watch_req
, defer_open_done
, state
);
2453 timeout
= timeval_sum(&state
->request_time
, &state
->timeout
);
2454 ok
= tevent_req_set_endtime(watch_req
, state
->xconn
->ev_ctx
, timeout
);
2456 exit_server("tevent_req_set_endtime failed");
2463 * Reschedule an open for immediate execution
2465 static void retry_open(struct timeval request_time
,
2466 struct smb_request
*req
,
2469 struct deferred_open_record
*open_rec
= NULL
;
2472 DBG_DEBUG("request time [%s] mid [%" PRIu64
"] file_id [%s]\n",
2473 timeval_string(talloc_tos(), &request_time
, false),
2475 file_id_string_tos(&id
));
2477 open_rec
= deferred_open_record_create(false, false, id
);
2478 if (open_rec
== NULL
) {
2479 exit_server("talloc failed");
2482 ok
= push_deferred_open_message_smb(req
,
2488 exit_server("push_deferred_open_message_smb failed");
2491 ok
= schedule_deferred_open_message_smb(req
->xconn
, req
->mid
);
2493 exit_server("schedule_deferred_open_message_smb failed");
2497 /****************************************************************************
2498 On overwrite open ensure that the attributes match.
2499 ****************************************************************************/
2501 static bool open_match_attributes(connection_struct
*conn
,
2502 uint32_t old_dos_attr
,
2503 uint32_t new_dos_attr
,
2504 mode_t existing_unx_mode
,
2505 mode_t new_unx_mode
,
2506 mode_t
*returned_unx_mode
)
2508 uint32_t noarch_old_dos_attr
, noarch_new_dos_attr
;
2510 noarch_old_dos_attr
= (old_dos_attr
& ~FILE_ATTRIBUTE_ARCHIVE
);
2511 noarch_new_dos_attr
= (new_dos_attr
& ~FILE_ATTRIBUTE_ARCHIVE
);
2513 if((noarch_old_dos_attr
== 0 && noarch_new_dos_attr
!= 0) ||
2514 (noarch_old_dos_attr
!= 0 && ((noarch_old_dos_attr
& noarch_new_dos_attr
) == noarch_old_dos_attr
))) {
2515 *returned_unx_mode
= new_unx_mode
;
2517 *returned_unx_mode
= (mode_t
)0;
2520 DEBUG(10,("open_match_attributes: old_dos_attr = 0x%x, "
2521 "existing_unx_mode = 0%o, new_dos_attr = 0x%x "
2522 "returned_unx_mode = 0%o\n",
2523 (unsigned int)old_dos_attr
,
2524 (unsigned int)existing_unx_mode
,
2525 (unsigned int)new_dos_attr
,
2526 (unsigned int)*returned_unx_mode
));
2528 /* If we're mapping SYSTEM and HIDDEN ensure they match. */
2529 if (lp_map_system(SNUM(conn
)) || lp_store_dos_attributes(SNUM(conn
))) {
2530 if ((old_dos_attr
& FILE_ATTRIBUTE_SYSTEM
) &&
2531 !(new_dos_attr
& FILE_ATTRIBUTE_SYSTEM
)) {
2535 if (lp_map_hidden(SNUM(conn
)) || lp_store_dos_attributes(SNUM(conn
))) {
2536 if ((old_dos_attr
& FILE_ATTRIBUTE_HIDDEN
) &&
2537 !(new_dos_attr
& FILE_ATTRIBUTE_HIDDEN
)) {
2544 /****************************************************************************
2545 Special FCB or DOS processing in the case of a sharing violation.
2546 Try and find a duplicated file handle.
2547 ****************************************************************************/
2549 static NTSTATUS
fcb_or_dos_open(struct smb_request
*req
,
2550 connection_struct
*conn
,
2551 files_struct
*fsp_to_dup_into
,
2552 const struct smb_filename
*smb_fname
,
2556 uint32_t access_mask
,
2557 uint32_t share_access
,
2558 uint32_t create_options
)
2562 DEBUG(5,("fcb_or_dos_open: attempting old open semantics for "
2563 "file %s.\n", smb_fname_str_dbg(smb_fname
)));
2565 for(fsp
= file_find_di_first(conn
->sconn
, id
); fsp
;
2566 fsp
= file_find_di_next(fsp
)) {
2568 DEBUG(10,("fcb_or_dos_open: checking file %s, fd = %d, "
2569 "vuid = %llu, file_pid = %u, private_options = 0x%x "
2570 "access_mask = 0x%x\n", fsp_str_dbg(fsp
),
2571 fsp
->fh
->fd
, (unsigned long long)fsp
->vuid
,
2572 (unsigned int)fsp
->file_pid
,
2573 (unsigned int)fsp
->fh
->private_options
,
2574 (unsigned int)fsp
->access_mask
));
2576 if (fsp
!= fsp_to_dup_into
&&
2577 fsp
->fh
->fd
!= -1 &&
2578 fsp
->vuid
== vuid
&&
2579 fsp
->file_pid
== file_pid
&&
2580 (fsp
->fh
->private_options
& (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS
|
2581 NTCREATEX_OPTIONS_PRIVATE_DENY_FCB
)) &&
2582 (fsp
->access_mask
& FILE_WRITE_DATA
) &&
2583 strequal(fsp
->fsp_name
->base_name
, smb_fname
->base_name
) &&
2584 strequal(fsp
->fsp_name
->stream_name
,
2585 smb_fname
->stream_name
)) {
2586 DEBUG(10,("fcb_or_dos_open: file match\n"));
2592 return NT_STATUS_NOT_FOUND
;
2595 /* quite an insane set of semantics ... */
2596 if (is_executable(smb_fname
->base_name
) &&
2597 (fsp
->fh
->private_options
& NTCREATEX_OPTIONS_PRIVATE_DENY_DOS
)) {
2598 DEBUG(10,("fcb_or_dos_open: file fail due to is_executable.\n"));
2599 return NT_STATUS_INVALID_PARAMETER
;
2602 /* We need to duplicate this fsp. */
2603 return dup_file_fsp(req
, fsp
, access_mask
, share_access
,
2604 create_options
, fsp_to_dup_into
);
2607 static void schedule_defer_open(struct share_mode_lock
*lck
,
2609 struct timeval request_time
,
2610 struct smb_request
*req
,
2613 /* This is a relative time, added to the absolute
2614 request_time value to get the absolute timeout time.
2615 Note that if this is the second or greater time we enter
2616 this codepath for this particular request mid then
2617 request_time is left as the absolute time of the *first*
2618 time this request mid was processed. This is what allows
2619 the request to eventually time out. */
2621 struct timeval timeout
;
2623 /* Normally the smbd we asked should respond within
2624 * OPLOCK_BREAK_TIMEOUT seconds regardless of whether
2625 * the client did, give twice the timeout as a safety
2626 * measure here in case the other smbd is stuck
2627 * somewhere else. */
2629 timeout
= timeval_set(OPLOCK_BREAK_TIMEOUT
*2, 0);
2631 if (request_timed_out(request_time
, timeout
)) {
2635 defer_open(lck
, request_time
, timeout
, req
, true, kernel_oplock
, id
);
2638 /****************************************************************************
2639 Reschedule an open call that went asynchronous.
2640 ****************************************************************************/
2642 static void schedule_async_open_timer(struct tevent_context
*ev
,
2643 struct tevent_timer
*te
,
2644 struct timeval current_time
,
2647 exit_server("async open timeout");
2650 static void schedule_async_open(struct timeval request_time
,
2651 struct smb_request
*req
)
2653 struct deferred_open_record
*open_rec
= NULL
;
2654 struct timeval timeout
= timeval_set(20, 0);
2657 if (request_timed_out(request_time
, timeout
)) {
2661 open_rec
= deferred_open_record_create(false, true, (struct file_id
){0});
2662 if (open_rec
== NULL
) {
2663 exit_server("deferred_open_record_create failed");
2666 ok
= push_deferred_open_message_smb(req
, request_time
, timeout
,
2667 (struct file_id
){0}, open_rec
);
2669 exit_server("push_deferred_open_message_smb failed");
2672 open_rec
->te
= tevent_add_timer(req
->sconn
->ev_ctx
,
2674 timeval_current_ofs(20, 0),
2675 schedule_async_open_timer
,
2677 if (open_rec
->te
== NULL
) {
2678 exit_server("tevent_add_timer failed");
2682 /****************************************************************************
2683 Work out what access_mask to use from what the client sent us.
2684 ****************************************************************************/
2686 static NTSTATUS
smbd_calculate_maximum_allowed_access(
2687 connection_struct
*conn
,
2688 const struct smb_filename
*smb_fname
,
2690 uint32_t *p_access_mask
)
2692 struct security_descriptor
*sd
;
2693 uint32_t access_granted
;
2696 if (!use_privs
&& (get_current_uid(conn
) == (uid_t
)0)) {
2697 *p_access_mask
|= FILE_GENERIC_ALL
;
2698 return NT_STATUS_OK
;
2701 status
= SMB_VFS_GET_NT_ACL(conn
, smb_fname
,
2707 if (NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
2709 * File did not exist
2711 *p_access_mask
= FILE_GENERIC_ALL
;
2712 return NT_STATUS_OK
;
2714 if (!NT_STATUS_IS_OK(status
)) {
2715 DEBUG(10,("Could not get acl on file %s: %s\n",
2716 smb_fname_str_dbg(smb_fname
),
2717 nt_errstr(status
)));
2718 return NT_STATUS_ACCESS_DENIED
;
2722 * If we can access the path to this file, by
2723 * default we have FILE_READ_ATTRIBUTES from the
2724 * containing directory. See the section:
2725 * "Algorithm to Check Access to an Existing File"
2728 * se_file_access_check()
2729 * also takes care of owner WRITE_DAC and READ_CONTROL.
2731 status
= se_file_access_check(sd
,
2732 get_current_nttok(conn
),
2734 (*p_access_mask
& ~FILE_READ_ATTRIBUTES
),
2739 if (!NT_STATUS_IS_OK(status
)) {
2740 DEBUG(10, ("Access denied on file %s: "
2741 "when calculating maximum access\n",
2742 smb_fname_str_dbg(smb_fname
)));
2743 return NT_STATUS_ACCESS_DENIED
;
2745 *p_access_mask
= (access_granted
| FILE_READ_ATTRIBUTES
);
2747 if (!(access_granted
& DELETE_ACCESS
)) {
2748 if (can_delete_file_in_directory(conn
, smb_fname
)) {
2749 *p_access_mask
|= DELETE_ACCESS
;
2753 return NT_STATUS_OK
;
2756 NTSTATUS
smbd_calculate_access_mask(connection_struct
*conn
,
2757 const struct smb_filename
*smb_fname
,
2759 uint32_t access_mask
,
2760 uint32_t *access_mask_out
)
2763 uint32_t orig_access_mask
= access_mask
;
2764 uint32_t rejected_share_access
;
2766 if (access_mask
& SEC_MASK_INVALID
) {
2767 DBG_DEBUG("access_mask [%8x] contains invalid bits\n",
2769 return NT_STATUS_ACCESS_DENIED
;
2773 * Convert GENERIC bits to specific bits.
2776 se_map_generic(&access_mask
, &file_generic_mapping
);
2778 /* Calculate MAXIMUM_ALLOWED_ACCESS if requested. */
2779 if (access_mask
& MAXIMUM_ALLOWED_ACCESS
) {
2781 status
= smbd_calculate_maximum_allowed_access(
2782 conn
, smb_fname
, use_privs
, &access_mask
);
2784 if (!NT_STATUS_IS_OK(status
)) {
2788 access_mask
&= conn
->share_access
;
2791 rejected_share_access
= access_mask
& ~(conn
->share_access
);
2793 if (rejected_share_access
) {
2794 DEBUG(10, ("smbd_calculate_access_mask: Access denied on "
2795 "file %s: rejected by share access mask[0x%08X] "
2796 "orig[0x%08X] mapped[0x%08X] reject[0x%08X]\n",
2797 smb_fname_str_dbg(smb_fname
),
2799 orig_access_mask
, access_mask
,
2800 rejected_share_access
));
2801 return NT_STATUS_ACCESS_DENIED
;
2804 *access_mask_out
= access_mask
;
2805 return NT_STATUS_OK
;
2808 /****************************************************************************
2809 Remove the deferred open entry under lock.
2810 ****************************************************************************/
2812 /****************************************************************************
2813 Return true if this is a state pointer to an asynchronous create.
2814 ****************************************************************************/
2816 bool is_deferred_open_async(const struct deferred_open_record
*rec
)
2818 return rec
->async_open
;
2821 static bool clear_ads(uint32_t create_disposition
)
2825 switch (create_disposition
) {
2826 case FILE_SUPERSEDE
:
2827 case FILE_OVERWRITE_IF
:
2828 case FILE_OVERWRITE
:
2837 static int disposition_to_open_flags(uint32_t create_disposition
)
2842 * Currently we're using FILE_SUPERSEDE as the same as
2843 * FILE_OVERWRITE_IF but they really are
2844 * different. FILE_SUPERSEDE deletes an existing file
2845 * (requiring delete access) then recreates it.
2848 switch (create_disposition
) {
2849 case FILE_SUPERSEDE
:
2850 case FILE_OVERWRITE_IF
:
2852 * If file exists replace/overwrite. If file doesn't
2855 ret
= O_CREAT
|O_TRUNC
;
2860 * If file exists open. If file doesn't exist error.
2865 case FILE_OVERWRITE
:
2867 * If file exists overwrite. If file doesn't exist
2875 * If file exists error. If file doesn't exist create.
2877 ret
= O_CREAT
|O_EXCL
;
2882 * If file exists open. If file doesn't exist create.
2890 static int calculate_open_access_flags(uint32_t access_mask
,
2891 uint32_t private_flags
)
2893 bool need_write
, need_read
;
2896 * Note that we ignore the append flag as append does not
2897 * mean the same thing under DOS and Unix.
2900 need_write
= (access_mask
& (FILE_WRITE_DATA
| FILE_APPEND_DATA
));
2905 /* DENY_DOS opens are always underlying read-write on the
2906 file handle, no matter what the requested access mask
2910 ((private_flags
& NTCREATEX_OPTIONS_PRIVATE_DENY_DOS
) ||
2911 access_mask
& (FILE_READ_ATTRIBUTES
|FILE_READ_DATA
|
2912 FILE_READ_EA
|FILE_EXECUTE
));
2920 /****************************************************************************
2921 Open a file with a share mode. Passed in an already created files_struct *.
2922 ****************************************************************************/
2924 static NTSTATUS
open_file_ntcreate(connection_struct
*conn
,
2925 struct smb_request
*req
,
2926 uint32_t access_mask
, /* access bits (FILE_READ_DATA etc.) */
2927 uint32_t share_access
, /* share constants (FILE_SHARE_READ etc) */
2928 uint32_t create_disposition
, /* FILE_OPEN_IF etc. */
2929 uint32_t create_options
, /* options such as delete on close. */
2930 uint32_t new_dos_attributes
, /* attributes used for new file. */
2931 int oplock_request
, /* internal Samba oplock codes. */
2932 struct smb2_lease
*lease
,
2933 /* Information (FILE_EXISTS etc.) */
2934 uint32_t private_flags
, /* Samba specific flags. */
2938 struct smb_filename
*smb_fname
= fsp
->fsp_name
;
2941 bool file_existed
= VALID_STAT(smb_fname
->st
);
2942 bool def_acl
= False
;
2943 bool posix_open
= False
;
2944 bool new_file_created
= False
;
2945 bool first_open_attempt
= true;
2946 NTSTATUS fsp_open
= NT_STATUS_ACCESS_DENIED
;
2947 mode_t new_unx_mode
= (mode_t
)0;
2948 mode_t unx_mode
= (mode_t
)0;
2950 uint32_t existing_dos_attributes
= 0;
2951 struct timeval request_time
= timeval_zero();
2952 struct share_mode_lock
*lck
= NULL
;
2953 uint32_t open_access_mask
= access_mask
;
2956 SMB_STRUCT_STAT saved_stat
= smb_fname
->st
;
2957 struct timespec old_write_time
;
2960 if (conn
->printer
) {
2962 * Printers are handled completely differently.
2963 * Most of the passed parameters are ignored.
2967 *pinfo
= FILE_WAS_CREATED
;
2970 DEBUG(10, ("open_file_ntcreate: printer open fname=%s\n",
2971 smb_fname_str_dbg(smb_fname
)));
2974 DEBUG(0,("open_file_ntcreate: printer open without "
2975 "an SMB request!\n"));
2976 return NT_STATUS_INTERNAL_ERROR
;
2979 return print_spool_open(fsp
, smb_fname
->base_name
,
2983 if (!parent_dirname(talloc_tos(), smb_fname
->base_name
, &parent_dir
,
2985 return NT_STATUS_NO_MEMORY
;
2988 if (new_dos_attributes
& FILE_FLAG_POSIX_SEMANTICS
) {
2990 unx_mode
= (mode_t
)(new_dos_attributes
& ~FILE_FLAG_POSIX_SEMANTICS
);
2991 new_dos_attributes
= 0;
2993 /* Windows allows a new file to be created and
2994 silently removes a FILE_ATTRIBUTE_DIRECTORY
2995 sent by the client. Do the same. */
2997 new_dos_attributes
&= ~FILE_ATTRIBUTE_DIRECTORY
;
2999 /* We add FILE_ATTRIBUTE_ARCHIVE to this as this mode is only used if the file is
3001 unx_mode
= unix_mode(conn
, new_dos_attributes
| FILE_ATTRIBUTE_ARCHIVE
,
3002 smb_fname
, parent_dir
);
3005 DEBUG(10, ("open_file_ntcreate: fname=%s, dos_attrs=0x%x "
3006 "access_mask=0x%x share_access=0x%x "
3007 "create_disposition = 0x%x create_options=0x%x "
3008 "unix mode=0%o oplock_request=%d private_flags = 0x%x\n",
3009 smb_fname_str_dbg(smb_fname
), new_dos_attributes
,
3010 access_mask
, share_access
, create_disposition
,
3011 create_options
, (unsigned int)unx_mode
, oplock_request
,
3012 (unsigned int)private_flags
));
3015 /* Ensure req == NULL means INTERNAL_OPEN_ONLY */
3016 SMB_ASSERT(((oplock_request
& INTERNAL_OPEN_ONLY
) != 0));
3018 /* And req != NULL means no INTERNAL_OPEN_ONLY */
3019 SMB_ASSERT(((oplock_request
& INTERNAL_OPEN_ONLY
) == 0));
3023 * Only non-internal opens can be deferred at all
3027 struct deferred_open_record
*open_rec
;
3028 if (get_deferred_open_message_state(req
,
3031 /* Remember the absolute time of the original
3032 request with this mid. We'll use it later to
3033 see if this has timed out. */
3035 /* If it was an async create retry, the file
3038 if (is_deferred_open_async(open_rec
)) {
3039 SET_STAT_INVALID(smb_fname
->st
);
3040 file_existed
= false;
3043 /* Ensure we don't reprocess this message. */
3044 remove_deferred_open_message_smb(req
->xconn
, req
->mid
);
3046 first_open_attempt
= false;
3051 new_dos_attributes
&= SAMBA_ATTRIBUTES_MASK
;
3054 * Only use strored DOS attributes for checks
3055 * against requested attributes (below via
3056 * open_match_attributes()), cf bug #11992
3057 * for details. -slow
3061 status
= SMB_VFS_GET_DOS_ATTRIBUTES(conn
, smb_fname
, &attr
);
3062 if (NT_STATUS_IS_OK(status
)) {
3063 existing_dos_attributes
= attr
;
3068 /* ignore any oplock requests if oplocks are disabled */
3069 if (!lp_oplocks(SNUM(conn
)) ||
3070 IS_VETO_OPLOCK_PATH(conn
, smb_fname
->base_name
)) {
3071 /* Mask off everything except the private Samba bits. */
3072 oplock_request
&= SAMBA_PRIVATE_OPLOCK_MASK
;
3075 /* this is for OS/2 long file names - say we don't support them */
3076 if (req
!= NULL
&& !req
->posix_pathnames
&&
3077 strstr(smb_fname
->base_name
,".+,;=[].")) {
3078 /* OS/2 Workplace shell fix may be main code stream in a later
3080 DEBUG(5,("open_file_ntcreate: OS/2 long filenames are not "
3082 if (use_nt_status()) {
3083 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
3085 return NT_STATUS_DOS(ERRDOS
, ERRcannotopen
);
3088 switch( create_disposition
) {
3090 /* If file exists open. If file doesn't exist error. */
3091 if (!file_existed
) {
3092 DEBUG(5,("open_file_ntcreate: FILE_OPEN "
3093 "requested for file %s and file "
3095 smb_fname_str_dbg(smb_fname
)));
3097 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
3101 case FILE_OVERWRITE
:
3102 /* If file exists overwrite. If file doesn't exist
3104 if (!file_existed
) {
3105 DEBUG(5,("open_file_ntcreate: FILE_OVERWRITE "
3106 "requested for file %s and file "
3108 smb_fname_str_dbg(smb_fname
) ));
3110 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
3115 /* If file exists error. If file doesn't exist
3118 DEBUG(5,("open_file_ntcreate: FILE_CREATE "
3119 "requested for file %s and file "
3120 "already exists.\n",
3121 smb_fname_str_dbg(smb_fname
)));
3122 if (S_ISDIR(smb_fname
->st
.st_ex_mode
)) {
3127 return map_nt_error_from_unix(errno
);
3131 case FILE_SUPERSEDE
:
3132 case FILE_OVERWRITE_IF
:
3136 return NT_STATUS_INVALID_PARAMETER
;
3139 flags2
= disposition_to_open_flags(create_disposition
);
3141 /* We only care about matching attributes on file exists and
3144 if (!posix_open
&& file_existed
&&
3145 ((create_disposition
== FILE_OVERWRITE
) ||
3146 (create_disposition
== FILE_OVERWRITE_IF
))) {
3147 if (!open_match_attributes(conn
, existing_dos_attributes
,
3149 smb_fname
->st
.st_ex_mode
,
3150 unx_mode
, &new_unx_mode
)) {
3151 DEBUG(5,("open_file_ntcreate: attributes missmatch "
3152 "for file %s (%x %x) (0%o, 0%o)\n",
3153 smb_fname_str_dbg(smb_fname
),
3154 existing_dos_attributes
,
3156 (unsigned int)smb_fname
->st
.st_ex_mode
,
3157 (unsigned int)unx_mode
));
3159 return NT_STATUS_ACCESS_DENIED
;
3163 status
= smbd_calculate_access_mask(conn
, smb_fname
,
3167 if (!NT_STATUS_IS_OK(status
)) {
3168 DEBUG(10, ("open_file_ntcreate: smbd_calculate_access_mask "
3169 "on file %s returned %s\n",
3170 smb_fname_str_dbg(smb_fname
), nt_errstr(status
)));
3174 open_access_mask
= access_mask
;
3176 if (flags2
& O_TRUNC
) {
3177 open_access_mask
|= FILE_WRITE_DATA
; /* This will cause oplock breaks. */
3180 DEBUG(10, ("open_file_ntcreate: fname=%s, after mapping "
3181 "access_mask=0x%x\n", smb_fname_str_dbg(smb_fname
),
3185 * Note that we ignore the append flag as append does not
3186 * mean the same thing under DOS and Unix.
3189 flags
= calculate_open_access_flags(access_mask
, private_flags
);
3192 * Currently we only look at FILE_WRITE_THROUGH for create options.
3196 if ((create_options
& FILE_WRITE_THROUGH
) && lp_strict_sync(SNUM(conn
))) {
3201 if (posix_open
&& (access_mask
& FILE_APPEND_DATA
)) {
3205 if (!posix_open
&& !CAN_WRITE(conn
)) {
3207 * We should really return a permission denied error if either
3208 * O_CREAT or O_TRUNC are set, but for compatibility with
3209 * older versions of Samba we just AND them out.
3211 flags2
&= ~(O_CREAT
|O_TRUNC
);
3214 if (first_open_attempt
&& lp_kernel_oplocks(SNUM(conn
))) {
3216 * With kernel oplocks the open breaking an oplock
3217 * blocks until the oplock holder has given up the
3218 * oplock or closed the file. We prevent this by first
3219 * trying to open the file with O_NONBLOCK (see "man
3220 * fcntl" on Linux). For the second try, triggered by
3221 * an oplock break response, we do not need this
3224 * This is true under the assumption that only Samba
3225 * requests kernel oplocks. Once someone else like
3226 * NFSv4 starts to use that API, we will have to
3227 * modify this by communicating with the NFSv4 server.
3229 flags2
|= O_NONBLOCK
;
3233 * Ensure we can't write on a read-only share or file.
3236 if (flags
!= O_RDONLY
&& file_existed
&&
3237 (!CAN_WRITE(conn
) || IS_DOS_READONLY(existing_dos_attributes
))) {
3238 DEBUG(5,("open_file_ntcreate: write access requested for "
3239 "file %s on read only %s\n",
3240 smb_fname_str_dbg(smb_fname
),
3241 !CAN_WRITE(conn
) ? "share" : "file" ));
3243 return NT_STATUS_ACCESS_DENIED
;
3246 fsp
->file_id
= vfs_file_id_from_sbuf(conn
, &smb_fname
->st
);
3247 fsp
->share_access
= share_access
;
3248 fsp
->fh
->private_options
= private_flags
;
3249 fsp
->access_mask
= open_access_mask
; /* We change this to the
3250 * requested access_mask after
3251 * the open is done. */
3253 fsp
->posix_flags
|= FSP_POSIX_FLAGS_ALL
;
3256 if (timeval_is_zero(&request_time
)) {
3257 request_time
= fsp
->open_time
;
3261 * Ensure we pay attention to default ACLs on directories if required.
3264 if ((flags2
& O_CREAT
) && lp_inherit_acls(SNUM(conn
)) &&
3265 (def_acl
= directory_has_default_acl(conn
, parent_dir
))) {
3266 unx_mode
= (0777 & lp_create_mask(SNUM(conn
)));
3269 DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o, "
3270 "access_mask = 0x%x, open_access_mask = 0x%x\n",
3271 (unsigned int)flags
, (unsigned int)flags2
,
3272 (unsigned int)unx_mode
, (unsigned int)access_mask
,
3273 (unsigned int)open_access_mask
));
3275 fsp_open
= open_file(fsp
, conn
, req
, parent_dir
,
3276 flags
|flags2
, unx_mode
, access_mask
,
3277 open_access_mask
, &new_file_created
);
3279 if (NT_STATUS_EQUAL(fsp_open
, NT_STATUS_NETWORK_BUSY
)) {
3283 * This handles the kernel oplock case:
3285 * the file has an active kernel oplock and the open() returned
3286 * EWOULDBLOCK/EAGAIN which maps to NETWORK_BUSY.
3288 * "Samba locking.tdb oplocks" are handled below after acquiring
3289 * the sharemode lock with get_share_mode_lock().
3291 if (file_existed
&& S_ISFIFO(fsp
->fsp_name
->st
.st_ex_mode
)) {
3292 DEBUG(10, ("FIFO busy\n"));
3293 return NT_STATUS_NETWORK_BUSY
;
3296 DEBUG(10, ("Internal open busy\n"));
3297 return NT_STATUS_NETWORK_BUSY
;
3301 * From here on we assume this is an oplock break triggered
3304 lck
= get_existing_share_mode_lock(talloc_tos(), fsp
->file_id
);
3306 retry_open(request_time
, req
, fsp
->file_id
);
3307 DEBUG(10, ("No share mode lock found after "
3308 "EWOULDBLOCK, retrying sync\n"));
3309 return NT_STATUS_SHARING_VIOLATION
;
3312 if (!validate_oplock_types(lck
)) {
3313 smb_panic("validate_oplock_types failed");
3316 delay
= delay_for_oplock(fsp
, 0, lease
, lck
, false,
3318 first_open_attempt
);
3320 schedule_defer_open(lck
, fsp
->file_id
, request_time
,
3323 DEBUG(10, ("Sent oplock break request to kernel "
3324 "oplock holder\n"));
3325 return NT_STATUS_SHARING_VIOLATION
;
3329 * No oplock from Samba around. Immediately retry with
3332 retry_open(request_time
, req
, fsp
->file_id
);
3335 DEBUG(10, ("No Samba oplock around after EWOULDBLOCK. "
3336 "Retrying sync\n"));
3337 return NT_STATUS_SHARING_VIOLATION
;
3340 if (!NT_STATUS_IS_OK(fsp_open
)) {
3341 if (NT_STATUS_EQUAL(fsp_open
, NT_STATUS_RETRY
)) {
3342 schedule_async_open(request_time
, req
);
3347 if (new_file_created
) {
3349 * As we atomically create using O_CREAT|O_EXCL,
3350 * then if new_file_created is true, then
3351 * file_existed *MUST* have been false (even
3352 * if the file was previously detected as being
3355 file_existed
= false;
3358 if (file_existed
&& !check_same_dev_ino(&saved_stat
, &smb_fname
->st
)) {
3360 * The file did exist, but some other (local or NFS)
3361 * process either renamed/unlinked and re-created the
3362 * file with different dev/ino after we walked the path,
3363 * but before we did the open. We could retry the
3364 * open but it's a rare enough case it's easier to
3365 * just fail the open to prevent creating any problems
3366 * in the open file db having the wrong dev/ino key.
3369 DEBUG(1,("open_file_ntcreate: file %s - dev/ino mismatch. "
3370 "Old (dev=0x%llu, ino =0x%llu). "
3371 "New (dev=0x%llu, ino=0x%llu). Failing open "
3372 " with NT_STATUS_ACCESS_DENIED.\n",
3373 smb_fname_str_dbg(smb_fname
),
3374 (unsigned long long)saved_stat
.st_ex_dev
,
3375 (unsigned long long)saved_stat
.st_ex_ino
,
3376 (unsigned long long)smb_fname
->st
.st_ex_dev
,
3377 (unsigned long long)smb_fname
->st
.st_ex_ino
));
3378 return NT_STATUS_ACCESS_DENIED
;
3381 old_write_time
= smb_fname
->st
.st_ex_mtime
;
3384 * Deal with the race condition where two smbd's detect the
3385 * file doesn't exist and do the create at the same time. One
3386 * of them will win and set a share mode, the other (ie. this
3387 * one) should check if the requested share mode for this
3388 * create is allowed.
3392 * Now the file exists and fsp is successfully opened,
3393 * fsp->dev and fsp->inode are valid and should replace the
3394 * dev=0,inode=0 from a non existent file. Spotted by
3395 * Nadav Danieli <nadavd@exanet.com>. JRA.
3400 lck
= get_share_mode_lock(talloc_tos(), id
,
3402 smb_fname
, &old_write_time
);
3405 DEBUG(0, ("open_file_ntcreate: Could not get share "
3406 "mode lock for %s\n",
3407 smb_fname_str_dbg(smb_fname
)));
3409 return NT_STATUS_SHARING_VIOLATION
;
3412 /* Get the types we need to examine. */
3413 if (!validate_oplock_types(lck
)) {
3414 smb_panic("validate_oplock_types failed");
3417 if (has_delete_on_close(lck
, fsp
->name_hash
)) {
3420 return NT_STATUS_DELETE_PENDING
;
3423 status
= open_mode_check(conn
, lck
,
3424 access_mask
, share_access
);
3426 if (NT_STATUS_EQUAL(status
, NT_STATUS_SHARING_VIOLATION
) ||
3427 (lck
->data
->num_share_modes
> 0)) {
3429 * This comes from ancient times out of open_mode_check. I
3430 * have no clue whether this is still necessary. I can't think
3431 * of a case where this would actually matter further down in
3432 * this function. I leave it here for further investigation
3435 file_existed
= true;
3440 * Handle oplocks, deferring the request if delay_for_oplock()
3441 * triggered a break message and we have to wait for the break
3445 bool sharing_violation
= NT_STATUS_EQUAL(
3446 status
, NT_STATUS_SHARING_VIOLATION
);
3448 delay
= delay_for_oplock(fsp
, oplock_request
, lease
, lck
,
3451 first_open_attempt
);
3453 schedule_defer_open(lck
, fsp
->file_id
,
3454 request_time
, req
, false);
3457 return NT_STATUS_SHARING_VIOLATION
;
3461 if (!NT_STATUS_IS_OK(status
)) {
3462 uint32_t can_access_mask
;
3463 bool can_access
= True
;
3465 SMB_ASSERT(NT_STATUS_EQUAL(status
, NT_STATUS_SHARING_VIOLATION
));
3467 /* Check if this can be done with the deny_dos and fcb
3470 (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS
|
3471 NTCREATEX_OPTIONS_PRIVATE_DENY_FCB
)) {
3473 DEBUG(0, ("DOS open without an SMB "
3477 return NT_STATUS_INTERNAL_ERROR
;
3480 /* Use the client requested access mask here,
3481 * not the one we open with. */
3482 status
= fcb_or_dos_open(req
,
3493 if (NT_STATUS_IS_OK(status
)) {
3496 *pinfo
= FILE_WAS_OPENED
;
3498 return NT_STATUS_OK
;
3503 * This next line is a subtlety we need for
3504 * MS-Access. If a file open will fail due to share
3505 * permissions and also for security (access) reasons,
3506 * we need to return the access failed error, not the
3507 * share error. We can't open the file due to kernel
3508 * oplock deadlock (it's possible we failed above on
3509 * the open_mode_check()) so use a userspace check.
3512 if (flags
& O_RDWR
) {
3513 can_access_mask
= FILE_READ_DATA
|FILE_WRITE_DATA
;
3514 } else if (flags
& O_WRONLY
) {
3515 can_access_mask
= FILE_WRITE_DATA
;
3517 can_access_mask
= FILE_READ_DATA
;
3520 if (((can_access_mask
& FILE_WRITE_DATA
) &&
3521 !CAN_WRITE(conn
)) ||
3522 !NT_STATUS_IS_OK(smbd_check_access_rights(conn
,
3525 can_access_mask
))) {
3530 * If we're returning a share violation, ensure we
3531 * cope with the braindead 1 second delay (SMB1 only).
3534 if (!(oplock_request
& INTERNAL_OPEN_ONLY
) &&
3535 !conn
->sconn
->using_smb2
&&
3536 lp_defer_sharing_violations()) {
3537 struct timeval timeout
;
3540 /* this is a hack to speed up torture tests
3542 timeout_usecs
= lp_parm_int(SNUM(conn
),
3543 "smbd","sharedelay",
3544 SHARING_VIOLATION_USEC_WAIT
);
3546 /* This is a relative time, added to the absolute
3547 request_time value to get the absolute timeout time.
3548 Note that if this is the second or greater time we enter
3549 this codepath for this particular request mid then
3550 request_time is left as the absolute time of the *first*
3551 time this request mid was processed. This is what allows
3552 the request to eventually time out. */
3554 timeout
= timeval_set(0, timeout_usecs
);
3556 if (!request_timed_out(request_time
, timeout
)) {
3557 defer_open(lck
, request_time
, timeout
, req
,
3566 * We have detected a sharing violation here
3567 * so return the correct error code
3569 status
= NT_STATUS_SHARING_VIOLATION
;
3571 status
= NT_STATUS_ACCESS_DENIED
;
3576 /* Should we atomically (to the client at least) truncate ? */
3577 if ((!new_file_created
) &&
3578 (flags2
& O_TRUNC
) &&
3579 (!S_ISFIFO(fsp
->fsp_name
->st
.st_ex_mode
))) {
3582 ret
= vfs_set_filelen(fsp
, 0);
3584 status
= map_nt_error_from_unix(errno
);
3592 * We have the share entry *locked*.....
3595 /* Delete streams if create_disposition requires it */
3596 if (!new_file_created
&& clear_ads(create_disposition
) &&
3597 !is_ntfs_stream_smb_fname(smb_fname
)) {
3598 status
= delete_all_streams(conn
, smb_fname
);
3599 if (!NT_STATUS_IS_OK(status
)) {
3606 /* note that we ignore failure for the following. It is
3607 basically a hack for NFS, and NFS will never set one of
3608 these only read them. Nobody but Samba can ever set a deny
3609 mode and we have already checked our more authoritative
3610 locking database for permission to set this deny mode. If
3611 the kernel refuses the operations then the kernel is wrong.
3612 note that GPFS supports it as well - jmcd */
3614 if (fsp
->fh
->fd
!= -1 && lp_kernel_share_modes(SNUM(conn
))) {
3617 * Beware: streams implementing VFS modules may
3618 * implement streams in a way that fsp will have the
3619 * basefile open in the fsp fd, so lacking a distinct
3620 * fd for the stream kernel_flock will apply on the
3621 * basefile which is wrong. The actual check is
3622 * deffered to the VFS module implementing the
3623 * kernel_flock call.
3625 ret_flock
= SMB_VFS_KERNEL_FLOCK(fsp
, share_access
, access_mask
);
3626 if(ret_flock
== -1 ){
3631 return NT_STATUS_SHARING_VIOLATION
;
3634 fsp
->kernel_share_modes_taken
= true;
3638 * At this point onwards, we can guarantee that the share entry
3639 * is locked, whether we created the file or not, and that the
3640 * deny mode is compatible with all current opens.
3644 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
3645 * but we don't have to store this - just ignore it on access check.
3647 if (conn
->sconn
->using_smb2
) {
3649 * SMB2 doesn't return it (according to Microsoft tests).
3650 * Test Case: TestSuite_ScenarioNo009GrantedAccessTestS0
3651 * File created with access = 0x7 (Read, Write, Delete)
3652 * Query Info on file returns 0x87 (Read, Write, Delete, Read Attributes)
3654 fsp
->access_mask
= access_mask
;
3656 /* But SMB1 does. */
3657 fsp
->access_mask
= access_mask
| FILE_READ_ATTRIBUTES
;
3662 * stat opens on existing files don't get oplocks.
3663 * They can get leases.
3665 * Note that we check for stat open on the *open_access_mask*,
3666 * i.e. the access mask we actually used to do the open,
3667 * not the one the client asked for (which is in
3668 * fsp->access_mask). This is due to the fact that
3669 * FILE_OVERWRITE and FILE_OVERWRITE_IF add in O_TRUNC,
3670 * which adds FILE_WRITE_DATA to open_access_mask.
3672 if (is_stat_open(open_access_mask
) && lease
== NULL
) {
3673 oplock_request
= NO_OPLOCK
;
3677 if (new_file_created
) {
3678 info
= FILE_WAS_CREATED
;
3680 if (flags2
& O_TRUNC
) {
3681 info
= FILE_WAS_OVERWRITTEN
;
3683 info
= FILE_WAS_OPENED
;
3692 * Setup the oplock info in both the shared memory and
3695 status
= grant_fsp_oplock_type(req
, fsp
, lck
, oplock_request
, lease
);
3696 if (!NT_STATUS_IS_OK(status
)) {
3702 /* Handle strange delete on close create semantics. */
3703 if (create_options
& FILE_DELETE_ON_CLOSE
) {
3705 status
= can_set_delete_on_close(fsp
, new_dos_attributes
);
3707 if (!NT_STATUS_IS_OK(status
)) {
3708 /* Remember to delete the mode we just added. */
3709 del_share_mode(lck
, fsp
);
3714 /* Note that here we set the *inital* delete on close flag,
3715 not the regular one. The magic gets handled in close. */
3716 fsp
->initial_delete_on_close
= True
;
3719 if (info
!= FILE_WAS_OPENED
) {
3720 /* Overwritten files should be initially set as archive */
3721 if ((info
== FILE_WAS_OVERWRITTEN
&& lp_map_archive(SNUM(conn
))) ||
3722 lp_store_dos_attributes(SNUM(conn
))) {
3724 if (file_set_dosmode(conn
, smb_fname
,
3725 new_dos_attributes
| FILE_ATTRIBUTE_ARCHIVE
,
3726 parent_dir
, true) == 0) {
3727 unx_mode
= smb_fname
->st
.st_ex_mode
;
3733 /* Determine sparse flag. */
3735 /* POSIX opens are sparse by default. */
3736 fsp
->is_sparse
= true;
3738 fsp
->is_sparse
= (file_existed
&&
3739 (existing_dos_attributes
& FILE_ATTRIBUTE_SPARSE
));
3743 * Take care of inherited ACLs on created files - if default ACL not
3747 if (!posix_open
&& new_file_created
&& !def_acl
) {
3749 int saved_errno
= errno
; /* We might get ENOSYS in the next
3752 if (SMB_VFS_FCHMOD_ACL(fsp
, unx_mode
) == -1 &&
3754 errno
= saved_errno
; /* Ignore ENOSYS */
3757 } else if (new_unx_mode
) {
3761 /* Attributes need changing. File already existed. */
3764 int saved_errno
= errno
; /* We might get ENOSYS in the
3766 ret
= SMB_VFS_FCHMOD_ACL(fsp
, new_unx_mode
);
3768 if (ret
== -1 && errno
== ENOSYS
) {
3769 errno
= saved_errno
; /* Ignore ENOSYS */
3771 DEBUG(5, ("open_file_ntcreate: reset "
3772 "attributes of file %s to 0%o\n",
3773 smb_fname_str_dbg(smb_fname
),
3774 (unsigned int)new_unx_mode
));
3775 ret
= 0; /* Don't do the fchmod below. */
3780 (SMB_VFS_FCHMOD(fsp
, new_unx_mode
) == -1))
3781 DEBUG(5, ("open_file_ntcreate: failed to reset "
3782 "attributes of file %s to 0%o\n",
3783 smb_fname_str_dbg(smb_fname
),
3784 (unsigned int)new_unx_mode
));
3789 * Deal with other opens having a modified write time.
3791 struct timespec write_time
= get_share_mode_write_time(lck
);
3793 if (!null_timespec(write_time
)) {
3794 update_stat_ex_mtime(&fsp
->fsp_name
->st
, write_time
);
3800 return NT_STATUS_OK
;
3803 static NTSTATUS
mkdir_internal(connection_struct
*conn
,
3804 struct smb_filename
*smb_dname
,
3805 uint32_t file_attributes
)
3808 char *parent_dir
= NULL
;
3810 bool posix_open
= false;
3811 bool need_re_stat
= false;
3812 uint32_t access_mask
= SEC_DIR_ADD_SUBDIR
;
3814 if (!CAN_WRITE(conn
) || (access_mask
& ~(conn
->share_access
))) {
3815 DEBUG(5,("mkdir_internal: failing share access "
3816 "%s\n", lp_servicename(talloc_tos(), SNUM(conn
))));
3817 return NT_STATUS_ACCESS_DENIED
;
3820 if (!parent_dirname(talloc_tos(), smb_dname
->base_name
, &parent_dir
,
3822 return NT_STATUS_NO_MEMORY
;
3825 if (file_attributes
& FILE_FLAG_POSIX_SEMANTICS
) {
3827 mode
= (mode_t
)(file_attributes
& ~FILE_FLAG_POSIX_SEMANTICS
);
3829 mode
= unix_mode(conn
, FILE_ATTRIBUTE_DIRECTORY
, smb_dname
, parent_dir
);
3832 status
= check_parent_access(conn
,
3835 if(!NT_STATUS_IS_OK(status
)) {
3836 DEBUG(5,("mkdir_internal: check_parent_access "
3837 "on directory %s for path %s returned %s\n",
3839 smb_dname
->base_name
,
3840 nt_errstr(status
) ));
3844 if (SMB_VFS_MKDIR(conn
, smb_dname
, mode
) != 0) {
3845 return map_nt_error_from_unix(errno
);
3848 /* Ensure we're checking for a symlink here.... */
3849 /* We don't want to get caught by a symlink racer. */
3851 if (SMB_VFS_LSTAT(conn
, smb_dname
) == -1) {
3852 DEBUG(2, ("Could not stat directory '%s' just created: %s\n",
3853 smb_fname_str_dbg(smb_dname
), strerror(errno
)));
3854 return map_nt_error_from_unix(errno
);
3857 if (!S_ISDIR(smb_dname
->st
.st_ex_mode
)) {
3858 DEBUG(0, ("Directory '%s' just created is not a directory !\n",
3859 smb_fname_str_dbg(smb_dname
)));
3860 return NT_STATUS_NOT_A_DIRECTORY
;
3863 if (lp_store_dos_attributes(SNUM(conn
))) {
3865 file_set_dosmode(conn
, smb_dname
,
3866 file_attributes
| FILE_ATTRIBUTE_DIRECTORY
,
3871 if (lp_inherit_permissions(SNUM(conn
))) {
3872 inherit_access_posix_acl(conn
, parent_dir
,
3873 smb_dname
->base_name
, mode
);
3874 need_re_stat
= true;
3879 * Check if high bits should have been set,
3880 * then (if bits are missing): add them.
3881 * Consider bits automagically set by UNIX, i.e. SGID bit from parent
3884 if ((mode
& ~(S_IRWXU
|S_IRWXG
|S_IRWXO
)) &&
3885 (mode
& ~smb_dname
->st
.st_ex_mode
)) {
3886 SMB_VFS_CHMOD(conn
, smb_dname
,
3887 (smb_dname
->st
.st_ex_mode
|
3888 (mode
& ~smb_dname
->st
.st_ex_mode
)));
3889 need_re_stat
= true;
3893 /* Change the owner if required. */
3894 if (lp_inherit_owner(SNUM(conn
)) != INHERIT_OWNER_NO
) {
3895 change_dir_owner_to_parent(conn
, parent_dir
,
3896 smb_dname
->base_name
,
3898 need_re_stat
= true;
3902 if (SMB_VFS_LSTAT(conn
, smb_dname
) == -1) {
3903 DEBUG(2, ("Could not stat directory '%s' just created: %s\n",
3904 smb_fname_str_dbg(smb_dname
), strerror(errno
)));
3905 return map_nt_error_from_unix(errno
);
3909 notify_fname(conn
, NOTIFY_ACTION_ADDED
, FILE_NOTIFY_CHANGE_DIR_NAME
,
3910 smb_dname
->base_name
);
3912 return NT_STATUS_OK
;
3915 /****************************************************************************
3916 Open a directory from an NT SMB call.
3917 ****************************************************************************/
3919 static NTSTATUS
open_directory(connection_struct
*conn
,
3920 struct smb_request
*req
,
3921 struct smb_filename
*smb_dname
,
3922 uint32_t access_mask
,
3923 uint32_t share_access
,
3924 uint32_t create_disposition
,
3925 uint32_t create_options
,
3926 uint32_t file_attributes
,
3928 files_struct
**result
)
3930 files_struct
*fsp
= NULL
;
3931 bool dir_existed
= VALID_STAT(smb_dname
->st
) ? True
: False
;
3932 struct share_mode_lock
*lck
= NULL
;
3934 struct timespec mtimespec
;
3938 if (is_ntfs_stream_smb_fname(smb_dname
)) {
3939 DEBUG(2, ("open_directory: %s is a stream name!\n",
3940 smb_fname_str_dbg(smb_dname
)));
3941 return NT_STATUS_NOT_A_DIRECTORY
;
3944 if (!(file_attributes
& FILE_FLAG_POSIX_SEMANTICS
)) {
3945 /* Ensure we have a directory attribute. */
3946 file_attributes
|= FILE_ATTRIBUTE_DIRECTORY
;
3949 DEBUG(5,("open_directory: opening directory %s, access_mask = 0x%x, "
3950 "share_access = 0x%x create_options = 0x%x, "
3951 "create_disposition = 0x%x, file_attributes = 0x%x\n",
3952 smb_fname_str_dbg(smb_dname
),
3953 (unsigned int)access_mask
,
3954 (unsigned int)share_access
,
3955 (unsigned int)create_options
,
3956 (unsigned int)create_disposition
,
3957 (unsigned int)file_attributes
));
3959 status
= smbd_calculate_access_mask(conn
, smb_dname
, false,
3960 access_mask
, &access_mask
);
3961 if (!NT_STATUS_IS_OK(status
)) {
3962 DEBUG(10, ("open_directory: smbd_calculate_access_mask "
3963 "on file %s returned %s\n",
3964 smb_fname_str_dbg(smb_dname
),
3965 nt_errstr(status
)));
3969 if ((access_mask
& SEC_FLAG_SYSTEM_SECURITY
) &&
3970 !security_token_has_privilege(get_current_nttok(conn
),
3971 SEC_PRIV_SECURITY
)) {
3972 DEBUG(10, ("open_directory: open on %s "
3973 "failed - SEC_FLAG_SYSTEM_SECURITY denied.\n",
3974 smb_fname_str_dbg(smb_dname
)));
3975 return NT_STATUS_PRIVILEGE_NOT_HELD
;
3978 switch( create_disposition
) {
3982 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
3985 info
= FILE_WAS_OPENED
;
3990 /* If directory exists error. If directory doesn't
3994 status
= NT_STATUS_OBJECT_NAME_COLLISION
;
3995 DEBUG(2, ("open_directory: unable to create "
3996 "%s. Error was %s\n",
3997 smb_fname_str_dbg(smb_dname
),
3998 nt_errstr(status
)));
4002 status
= mkdir_internal(conn
, smb_dname
,
4005 if (!NT_STATUS_IS_OK(status
)) {
4006 DEBUG(2, ("open_directory: unable to create "
4007 "%s. Error was %s\n",
4008 smb_fname_str_dbg(smb_dname
),
4009 nt_errstr(status
)));
4013 info
= FILE_WAS_CREATED
;
4018 * If directory exists open. If directory doesn't
4023 status
= NT_STATUS_OK
;
4024 info
= FILE_WAS_OPENED
;
4026 status
= mkdir_internal(conn
, smb_dname
,
4029 if (NT_STATUS_IS_OK(status
)) {
4030 info
= FILE_WAS_CREATED
;
4032 /* Cope with create race. */
4033 if (!NT_STATUS_EQUAL(status
,
4034 NT_STATUS_OBJECT_NAME_COLLISION
)) {
4035 DEBUG(2, ("open_directory: unable to create "
4036 "%s. Error was %s\n",
4037 smb_fname_str_dbg(smb_dname
),
4038 nt_errstr(status
)));
4043 * If mkdir_internal() returned
4044 * NT_STATUS_OBJECT_NAME_COLLISION
4045 * we still must lstat the path.
4048 if (SMB_VFS_LSTAT(conn
, smb_dname
)
4050 DEBUG(2, ("Could not stat "
4051 "directory '%s' just "
4056 return map_nt_error_from_unix(
4060 info
= FILE_WAS_OPENED
;
4066 case FILE_SUPERSEDE
:
4067 case FILE_OVERWRITE
:
4068 case FILE_OVERWRITE_IF
:
4070 DEBUG(5,("open_directory: invalid create_disposition "
4071 "0x%x for directory %s\n",
4072 (unsigned int)create_disposition
,
4073 smb_fname_str_dbg(smb_dname
)));
4074 return NT_STATUS_INVALID_PARAMETER
;
4077 if(!S_ISDIR(smb_dname
->st
.st_ex_mode
)) {
4078 DEBUG(5,("open_directory: %s is not a directory !\n",
4079 smb_fname_str_dbg(smb_dname
)));
4080 return NT_STATUS_NOT_A_DIRECTORY
;
4083 if (info
== FILE_WAS_OPENED
) {
4084 status
= smbd_check_access_rights(conn
,
4088 if (!NT_STATUS_IS_OK(status
)) {
4089 DEBUG(10, ("open_directory: smbd_check_access_rights on "
4090 "file %s failed with %s\n",
4091 smb_fname_str_dbg(smb_dname
),
4092 nt_errstr(status
)));
4097 status
= file_new(req
, conn
, &fsp
);
4098 if(!NT_STATUS_IS_OK(status
)) {
4103 * Setup the files_struct for it.
4106 fsp
->file_id
= vfs_file_id_from_sbuf(conn
, &smb_dname
->st
);
4107 fsp
->vuid
= req
? req
->vuid
: UID_FIELD_INVALID
;
4108 fsp
->file_pid
= req
? req
->smbpid
: 0;
4109 fsp
->can_lock
= False
;
4110 fsp
->can_read
= False
;
4111 fsp
->can_write
= False
;
4113 fsp
->share_access
= share_access
;
4114 fsp
->fh
->private_options
= 0;
4116 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
4118 fsp
->access_mask
= access_mask
| FILE_READ_ATTRIBUTES
;
4119 fsp
->print_file
= NULL
;
4120 fsp
->modified
= False
;
4121 fsp
->oplock_type
= NO_OPLOCK
;
4122 fsp
->sent_oplock_break
= NO_BREAK_SENT
;
4123 fsp
->is_directory
= True
;
4124 if (file_attributes
& FILE_FLAG_POSIX_SEMANTICS
) {
4125 fsp
->posix_flags
|= FSP_POSIX_FLAGS_ALL
;
4127 status
= fsp_set_smb_fname(fsp
, smb_dname
);
4128 if (!NT_STATUS_IS_OK(status
)) {
4129 file_free(req
, fsp
);
4133 /* Don't store old timestamps for directory
4134 handles in the internal database. We don't
4135 update them in there if new objects
4136 are creaded in the directory. Currently
4137 we only update timestamps on file writes.
4140 ZERO_STRUCT(mtimespec
);
4142 if (access_mask
& (FILE_LIST_DIRECTORY
|
4144 FILE_ADD_SUBDIRECTORY
|
4147 FILE_DELETE_CHILD
)) {
4149 status
= fd_open(conn
, fsp
, O_RDONLY
|O_DIRECTORY
, 0);
4151 /* POSIX allows us to open a directory with O_RDONLY. */
4152 status
= fd_open(conn
, fsp
, O_RDONLY
, 0);
4154 if (!NT_STATUS_IS_OK(status
)) {
4155 DEBUG(5, ("open_directory: Could not open fd for "
4157 smb_fname_str_dbg(smb_dname
),
4158 nt_errstr(status
)));
4159 file_free(req
, fsp
);
4164 DEBUG(10, ("Not opening Directory %s\n",
4165 smb_fname_str_dbg(smb_dname
)));
4168 status
= vfs_stat_fsp(fsp
);
4169 if (!NT_STATUS_IS_OK(status
)) {
4171 file_free(req
, fsp
);
4175 if(!S_ISDIR(fsp
->fsp_name
->st
.st_ex_mode
)) {
4176 DEBUG(5,("open_directory: %s is not a directory !\n",
4177 smb_fname_str_dbg(smb_dname
)));
4179 file_free(req
, fsp
);
4180 return NT_STATUS_NOT_A_DIRECTORY
;
4183 /* Ensure there was no race condition. We need to check
4184 * dev/inode but not permissions, as these can change
4186 if (!check_same_dev_ino(&smb_dname
->st
, &fsp
->fsp_name
->st
)) {
4187 DEBUG(5,("open_directory: stat struct differs for "
4189 smb_fname_str_dbg(smb_dname
)));
4191 file_free(req
, fsp
);
4192 return NT_STATUS_ACCESS_DENIED
;
4195 lck
= get_share_mode_lock(talloc_tos(), fsp
->file_id
,
4196 conn
->connectpath
, smb_dname
,
4200 DEBUG(0, ("open_directory: Could not get share mode lock for "
4201 "%s\n", smb_fname_str_dbg(smb_dname
)));
4203 file_free(req
, fsp
);
4204 return NT_STATUS_SHARING_VIOLATION
;
4207 if (has_delete_on_close(lck
, fsp
->name_hash
)) {
4210 file_free(req
, fsp
);
4211 return NT_STATUS_DELETE_PENDING
;
4214 status
= open_mode_check(conn
, lck
,
4215 access_mask
, share_access
);
4217 if (!NT_STATUS_IS_OK(status
)) {
4220 file_free(req
, fsp
);
4224 ok
= set_share_mode(lck
, fsp
, get_current_uid(conn
),
4225 req
? req
->mid
: 0, NO_OPLOCK
,
4230 file_free(req
, fsp
);
4231 return NT_STATUS_NO_MEMORY
;
4234 /* For directories the delete on close bit at open time seems
4235 always to be honored on close... See test 19 in Samba4 BASE-DELETE. */
4236 if (create_options
& FILE_DELETE_ON_CLOSE
) {
4237 status
= can_set_delete_on_close(fsp
, 0);
4238 if (!NT_STATUS_IS_OK(status
) && !NT_STATUS_EQUAL(status
, NT_STATUS_DIRECTORY_NOT_EMPTY
)) {
4239 del_share_mode(lck
, fsp
);
4242 file_free(req
, fsp
);
4246 if (NT_STATUS_IS_OK(status
)) {
4247 /* Note that here we set the *inital* delete on close flag,
4248 not the regular one. The magic gets handled in close. */
4249 fsp
->initial_delete_on_close
= True
;
4255 * Deal with other opens having a modified write time. Is this
4256 * possible for directories?
4258 struct timespec write_time
= get_share_mode_write_time(lck
);
4260 if (!null_timespec(write_time
)) {
4261 update_stat_ex_mtime(&fsp
->fsp_name
->st
, write_time
);
4272 return NT_STATUS_OK
;
4275 NTSTATUS
create_directory(connection_struct
*conn
, struct smb_request
*req
,
4276 struct smb_filename
*smb_dname
)
4281 status
= SMB_VFS_CREATE_FILE(
4284 0, /* root_dir_fid */
4285 smb_dname
, /* fname */
4286 FILE_READ_ATTRIBUTES
, /* access_mask */
4287 FILE_SHARE_NONE
, /* share_access */
4288 FILE_CREATE
, /* create_disposition*/
4289 FILE_DIRECTORY_FILE
, /* create_options */
4290 FILE_ATTRIBUTE_DIRECTORY
, /* file_attributes */
4291 0, /* oplock_request */
4293 0, /* allocation_size */
4294 0, /* private_flags */
4299 NULL
, NULL
); /* create context */
4301 if (NT_STATUS_IS_OK(status
)) {
4302 close_file(req
, fsp
, NORMAL_CLOSE
);
4308 /****************************************************************************
4309 Receive notification that one of our open files has been renamed by another
4311 ****************************************************************************/
4313 void msg_file_was_renamed(struct messaging_context
*msg
,
4316 struct server_id server_id
,
4320 char *frm
= (char *)data
->data
;
4322 const char *sharepath
;
4323 const char *base_name
;
4324 const char *stream_name
;
4325 struct smb_filename
*smb_fname
= NULL
;
4326 size_t sp_len
, bn_len
;
4328 struct smbd_server_connection
*sconn
=
4329 talloc_get_type_abort(private_data
,
4330 struct smbd_server_connection
);
4332 if (data
->data
== NULL
4333 || data
->length
< MSG_FILE_RENAMED_MIN_SIZE
+ 2) {
4334 DEBUG(0, ("msg_file_was_renamed: Got invalid msg len %d\n",
4335 (int)data
->length
));
4339 /* Unpack the message. */
4340 pull_file_id_24(frm
, &id
);
4341 sharepath
= &frm
[24];
4342 sp_len
= strlen(sharepath
);
4343 base_name
= sharepath
+ sp_len
+ 1;
4344 bn_len
= strlen(base_name
);
4345 stream_name
= sharepath
+ sp_len
+ 1 + bn_len
+ 1;
4347 /* stream_name must always be NULL if there is no stream. */
4348 if (stream_name
[0] == '\0') {
4352 smb_fname
= synthetic_smb_fname(talloc_tos(),
4357 if (smb_fname
== NULL
) {
4361 DEBUG(10,("msg_file_was_renamed: Got rename message for sharepath %s, new name %s, "
4363 sharepath
, smb_fname_str_dbg(smb_fname
),
4364 file_id_string_tos(&id
)));
4366 for(fsp
= file_find_di_first(sconn
, id
); fsp
;
4367 fsp
= file_find_di_next(fsp
)) {
4368 if (memcmp(fsp
->conn
->connectpath
, sharepath
, sp_len
) == 0) {
4370 DEBUG(10,("msg_file_was_renamed: renaming file %s from %s -> %s\n",
4371 fsp_fnum_dbg(fsp
), fsp_str_dbg(fsp
),
4372 smb_fname_str_dbg(smb_fname
)));
4373 status
= fsp_set_smb_fname(fsp
, smb_fname
);
4374 if (!NT_STATUS_IS_OK(status
)) {
4379 /* Now we have the complete path we can work out if this is
4380 actually within this share and adjust newname accordingly. */
4381 DEBUG(10,("msg_file_was_renamed: share mismatch (sharepath %s "
4382 "not sharepath %s) "
4383 "%s from %s -> %s\n",
4384 fsp
->conn
->connectpath
,
4388 smb_fname_str_dbg(smb_fname
)));
4392 TALLOC_FREE(smb_fname
);
4397 * If a main file is opened for delete, all streams need to be checked for
4398 * !FILE_SHARE_DELETE. Do this by opening with DELETE_ACCESS.
4399 * If that works, delete them all by setting the delete on close and close.
4402 static NTSTATUS
open_streams_for_delete(connection_struct
*conn
,
4403 const struct smb_filename
*smb_fname
)
4405 struct stream_struct
*stream_info
= NULL
;
4406 files_struct
**streams
= NULL
;
4408 unsigned int num_streams
= 0;
4409 TALLOC_CTX
*frame
= talloc_stackframe();
4412 status
= vfs_streaminfo(conn
, NULL
, smb_fname
, talloc_tos(),
4413 &num_streams
, &stream_info
);
4415 if (NT_STATUS_EQUAL(status
, NT_STATUS_NOT_IMPLEMENTED
)
4416 || NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
4417 DEBUG(10, ("no streams around\n"));
4419 return NT_STATUS_OK
;
4422 if (!NT_STATUS_IS_OK(status
)) {
4423 DEBUG(10, ("vfs_streaminfo failed: %s\n",
4424 nt_errstr(status
)));
4428 DEBUG(10, ("open_streams_for_delete found %d streams\n",
4431 if (num_streams
== 0) {
4433 return NT_STATUS_OK
;
4436 streams
= talloc_array(talloc_tos(), files_struct
*, num_streams
);
4437 if (streams
== NULL
) {
4438 DEBUG(0, ("talloc failed\n"));
4439 status
= NT_STATUS_NO_MEMORY
;
4443 for (i
=0; i
<num_streams
; i
++) {
4444 struct smb_filename
*smb_fname_cp
;
4446 if (strequal(stream_info
[i
].name
, "::$DATA")) {
4451 smb_fname_cp
= synthetic_smb_fname(talloc_tos(),
4452 smb_fname
->base_name
,
4453 stream_info
[i
].name
,
4456 ~SMB_FILENAME_POSIX_PATH
));
4457 if (smb_fname_cp
== NULL
) {
4458 status
= NT_STATUS_NO_MEMORY
;
4462 if (SMB_VFS_STAT(conn
, smb_fname_cp
) == -1) {
4463 DEBUG(10, ("Unable to stat stream: %s\n",
4464 smb_fname_str_dbg(smb_fname_cp
)));
4467 status
= SMB_VFS_CREATE_FILE(
4470 0, /* root_dir_fid */
4471 smb_fname_cp
, /* fname */
4472 DELETE_ACCESS
, /* access_mask */
4473 (FILE_SHARE_READ
| /* share_access */
4474 FILE_SHARE_WRITE
| FILE_SHARE_DELETE
),
4475 FILE_OPEN
, /* create_disposition*/
4476 0, /* create_options */
4477 FILE_ATTRIBUTE_NORMAL
, /* file_attributes */
4478 0, /* oplock_request */
4480 0, /* allocation_size */
4481 NTCREATEX_OPTIONS_PRIVATE_STREAM_DELETE
, /* private_flags */
4484 &streams
[i
], /* result */
4486 NULL
, NULL
); /* create context */
4488 if (!NT_STATUS_IS_OK(status
)) {
4489 DEBUG(10, ("Could not open stream %s: %s\n",
4490 smb_fname_str_dbg(smb_fname_cp
),
4491 nt_errstr(status
)));
4493 TALLOC_FREE(smb_fname_cp
);
4496 TALLOC_FREE(smb_fname_cp
);
4500 * don't touch the variable "status" beyond this point :-)
4503 for (i
-= 1 ; i
>= 0; i
--) {
4504 if (streams
[i
] == NULL
) {
4508 DEBUG(10, ("Closing stream # %d, %s\n", i
,
4509 fsp_str_dbg(streams
[i
])));
4510 close_file(NULL
, streams
[i
], NORMAL_CLOSE
);
4518 /*********************************************************************
4519 Create a default ACL by inheriting from the parent. If no inheritance
4520 from the parent available, don't set anything. This will leave the actual
4521 permissions the new file or directory already got from the filesystem
4522 as the NT ACL when read.
4523 *********************************************************************/
4525 static NTSTATUS
inherit_new_acl(files_struct
*fsp
)
4527 TALLOC_CTX
*frame
= talloc_stackframe();
4528 char *parent_name
= NULL
;
4529 struct security_descriptor
*parent_desc
= NULL
;
4530 NTSTATUS status
= NT_STATUS_OK
;
4531 struct security_descriptor
*psd
= NULL
;
4532 const struct dom_sid
*owner_sid
= NULL
;
4533 const struct dom_sid
*group_sid
= NULL
;
4534 uint32_t security_info_sent
= (SECINFO_OWNER
| SECINFO_GROUP
| SECINFO_DACL
);
4535 struct security_token
*token
= fsp
->conn
->session_info
->security_token
;
4536 bool inherit_owner
=
4537 (lp_inherit_owner(SNUM(fsp
->conn
)) == INHERIT_OWNER_WINDOWS_AND_UNIX
);
4538 bool inheritable_components
= false;
4539 bool try_builtin_administrators
= false;
4540 const struct dom_sid
*BA_U_sid
= NULL
;
4541 const struct dom_sid
*BA_G_sid
= NULL
;
4542 bool try_system
= false;
4543 const struct dom_sid
*SY_U_sid
= NULL
;
4544 const struct dom_sid
*SY_G_sid
= NULL
;
4546 struct smb_filename
*parent_smb_fname
= NULL
;
4548 if (!parent_dirname(frame
, fsp
->fsp_name
->base_name
, &parent_name
, NULL
)) {
4550 return NT_STATUS_NO_MEMORY
;
4552 parent_smb_fname
= synthetic_smb_fname(talloc_tos(),
4556 fsp
->fsp_name
->flags
);
4558 if (parent_smb_fname
== NULL
) {
4560 return NT_STATUS_NO_MEMORY
;
4563 status
= SMB_VFS_GET_NT_ACL(fsp
->conn
,
4565 (SECINFO_OWNER
| SECINFO_GROUP
| SECINFO_DACL
),
4568 if (!NT_STATUS_IS_OK(status
)) {
4573 inheritable_components
= sd_has_inheritable_components(parent_desc
,
4576 if (!inheritable_components
&& !inherit_owner
) {
4578 /* Nothing to inherit and not setting owner. */
4579 return NT_STATUS_OK
;
4582 /* Create an inherited descriptor from the parent. */
4584 if (DEBUGLEVEL
>= 10) {
4585 DEBUG(10,("inherit_new_acl: parent acl for %s is:\n",
4586 fsp_str_dbg(fsp
) ));
4587 NDR_PRINT_DEBUG(security_descriptor
, parent_desc
);
4590 /* Inherit from parent descriptor if "inherit owner" set. */
4591 if (inherit_owner
) {
4592 owner_sid
= parent_desc
->owner_sid
;
4593 group_sid
= parent_desc
->group_sid
;
4596 if (owner_sid
== NULL
) {
4597 if (security_token_has_builtin_administrators(token
)) {
4598 try_builtin_administrators
= true;
4599 } else if (security_token_is_system(token
)) {
4600 try_builtin_administrators
= true;
4605 if (group_sid
== NULL
&&
4606 token
->num_sids
== PRIMARY_GROUP_SID_INDEX
)
4608 if (security_token_is_system(token
)) {
4609 try_builtin_administrators
= true;
4614 if (try_builtin_administrators
) {
4619 ok
= sids_to_unixids(&global_sid_Builtin_Administrators
, 1, &ids
);
4623 BA_U_sid
= &global_sid_Builtin_Administrators
;
4624 BA_G_sid
= &global_sid_Builtin_Administrators
;
4627 BA_U_sid
= &global_sid_Builtin_Administrators
;
4630 BA_G_sid
= &global_sid_Builtin_Administrators
;
4643 ok
= sids_to_unixids(&global_sid_System
, 1, &ids
);
4647 SY_U_sid
= &global_sid_System
;
4648 SY_G_sid
= &global_sid_System
;
4651 SY_U_sid
= &global_sid_System
;
4654 SY_G_sid
= &global_sid_System
;
4662 if (owner_sid
== NULL
) {
4663 owner_sid
= BA_U_sid
;
4666 if (owner_sid
== NULL
) {
4667 owner_sid
= SY_U_sid
;
4670 if (group_sid
== NULL
) {
4671 group_sid
= SY_G_sid
;
4674 if (try_system
&& group_sid
== NULL
) {
4675 group_sid
= BA_G_sid
;
4678 if (owner_sid
== NULL
) {
4679 owner_sid
= &token
->sids
[PRIMARY_USER_SID_INDEX
];
4681 if (group_sid
== NULL
) {
4682 if (token
->num_sids
== PRIMARY_GROUP_SID_INDEX
) {
4683 group_sid
= &token
->sids
[PRIMARY_USER_SID_INDEX
];
4685 group_sid
= &token
->sids
[PRIMARY_GROUP_SID_INDEX
];
4689 status
= se_create_child_secdesc(frame
,
4696 if (!NT_STATUS_IS_OK(status
)) {
4701 /* If inheritable_components == false,
4702 se_create_child_secdesc()
4703 creates a security desriptor with a NULL dacl
4704 entry, but with SEC_DESC_DACL_PRESENT. We need
4705 to remove that flag. */
4707 if (!inheritable_components
) {
4708 security_info_sent
&= ~SECINFO_DACL
;
4709 psd
->type
&= ~SEC_DESC_DACL_PRESENT
;
4712 if (DEBUGLEVEL
>= 10) {
4713 DEBUG(10,("inherit_new_acl: child acl for %s is:\n",
4714 fsp_str_dbg(fsp
) ));
4715 NDR_PRINT_DEBUG(security_descriptor
, psd
);
4718 if (inherit_owner
) {
4719 /* We need to be root to force this. */
4722 status
= SMB_VFS_FSET_NT_ACL(fsp
,
4725 if (inherit_owner
) {
4733 * If we already have a lease, it must match the new file id. [MS-SMB2]
4734 * 3.3.5.9.8 speaks about INVALID_PARAMETER if an already used lease key is
4735 * used for a different file name.
4738 struct lease_match_state
{
4739 /* Input parameters. */
4740 TALLOC_CTX
*mem_ctx
;
4741 const char *servicepath
;
4742 const struct smb_filename
*fname
;
4745 /* Return parameters. */
4746 uint32_t num_file_ids
;
4747 struct file_id
*ids
;
4748 NTSTATUS match_status
;
4751 /*************************************************************
4752 File doesn't exist but this lease key+guid is already in use.
4754 This is only allowable in the dynamic share case where the
4755 service path must be different.
4757 There is a small race condition here in the multi-connection
4758 case where a client sends two create calls on different connections,
4759 where the file doesn't exist and one smbd creates the leases_db
4760 entry first, but this will get fixed by the multichannel cleanup
4761 when all identical client_guids get handled by a single smbd.
4762 **************************************************************/
4764 static void lease_match_parser_new_file(
4766 const struct leases_db_file
*files
,
4767 struct lease_match_state
*state
)
4771 for (i
= 0; i
< num_files
; i
++) {
4772 const struct leases_db_file
*f
= &files
[i
];
4773 if (strequal(state
->servicepath
, f
->servicepath
)) {
4774 state
->match_status
= NT_STATUS_INVALID_PARAMETER
;
4779 /* Dynamic share case. Break leases on all other files. */
4780 state
->match_status
= leases_db_copy_file_ids(state
->mem_ctx
,
4784 if (!NT_STATUS_IS_OK(state
->match_status
)) {
4788 state
->num_file_ids
= num_files
;
4789 state
->match_status
= NT_STATUS_OPLOCK_NOT_GRANTED
;
4793 static void lease_match_parser(
4795 const struct leases_db_file
*files
,
4798 struct lease_match_state
*state
=
4799 (struct lease_match_state
*)private_data
;
4802 if (!state
->file_existed
) {
4804 * Deal with name mismatch or
4805 * possible dynamic share case separately
4806 * to make code clearer.
4808 lease_match_parser_new_file(num_files
,
4815 state
->match_status
= NT_STATUS_OK
;
4817 for (i
= 0; i
< num_files
; i
++) {
4818 const struct leases_db_file
*f
= &files
[i
];
4820 /* Everything should be the same. */
4821 if (!file_id_equal(&state
->id
, &f
->id
)) {
4822 /* This should catch all dynamic share cases. */
4823 state
->match_status
= NT_STATUS_OPLOCK_NOT_GRANTED
;
4826 if (!strequal(f
->servicepath
, state
->servicepath
)) {
4827 state
->match_status
= NT_STATUS_INVALID_PARAMETER
;
4830 if (!strequal(f
->base_name
, state
->fname
->base_name
)) {
4831 state
->match_status
= NT_STATUS_INVALID_PARAMETER
;
4834 if (!strequal(f
->stream_name
, state
->fname
->stream_name
)) {
4835 state
->match_status
= NT_STATUS_INVALID_PARAMETER
;
4840 if (NT_STATUS_IS_OK(state
->match_status
)) {
4842 * Common case - just opening another handle on a
4843 * file on a non-dynamic share.
4848 if (NT_STATUS_EQUAL(state
->match_status
, NT_STATUS_INVALID_PARAMETER
)) {
4849 /* Mismatched path. Error back to client. */
4854 * File id mismatch. Dynamic share case NT_STATUS_OPLOCK_NOT_GRANTED.
4855 * Don't allow leases.
4858 state
->match_status
= leases_db_copy_file_ids(state
->mem_ctx
,
4862 if (!NT_STATUS_IS_OK(state
->match_status
)) {
4866 state
->num_file_ids
= num_files
;
4867 state
->match_status
= NT_STATUS_OPLOCK_NOT_GRANTED
;
4871 static NTSTATUS
lease_match(connection_struct
*conn
,
4872 struct smb_request
*req
,
4873 struct smb2_lease_key
*lease_key
,
4874 const char *servicepath
,
4875 const struct smb_filename
*fname
,
4876 uint16_t *p_version
,
4879 struct smbd_server_connection
*sconn
= req
->sconn
;
4880 TALLOC_CTX
*tos
= talloc_tos();
4881 struct lease_match_state state
= {
4883 .servicepath
= servicepath
,
4885 .match_status
= NT_STATUS_OK
4890 state
.file_existed
= VALID_STAT(fname
->st
);
4891 if (state
.file_existed
) {
4892 state
.id
= vfs_file_id_from_sbuf(conn
, &fname
->st
);
4894 memset(&state
.id
, '\0', sizeof(state
.id
));
4897 status
= leases_db_parse(&sconn
->client
->connections
->smb2
.client
.guid
,
4898 lease_key
, lease_match_parser
, &state
);
4899 if (!NT_STATUS_IS_OK(status
)) {
4901 * Not found or error means okay: We can make the lease pass
4903 return NT_STATUS_OK
;
4905 if (!NT_STATUS_EQUAL(state
.match_status
, NT_STATUS_OPLOCK_NOT_GRANTED
)) {
4907 * Anything but NT_STATUS_OPLOCK_NOT_GRANTED, let the caller
4910 return state
.match_status
;
4913 /* We have to break all existing leases. */
4914 for (i
= 0; i
< state
.num_file_ids
; i
++) {
4915 struct share_mode_lock
*lck
;
4916 struct share_mode_data
*d
;
4919 if (file_id_equal(&state
.ids
[i
], &state
.id
)) {
4920 /* Don't need to break our own file. */
4924 lck
= get_existing_share_mode_lock(talloc_tos(), state
.ids
[i
]);
4926 /* Race condition - file already closed. */
4930 for (j
=0; j
<d
->num_share_modes
; j
++) {
4931 struct share_mode_entry
*e
= &d
->share_modes
[j
];
4932 uint32_t e_lease_type
= get_lease_type(d
, e
);
4933 struct share_mode_lease
*l
= NULL
;
4935 if (share_mode_stale_pid(d
, j
)) {
4939 if (e
->op_type
== LEASE_OPLOCK
) {
4940 l
= &lck
->data
->leases
[e
->lease_idx
];
4941 if (!smb2_lease_key_equal(&l
->lease_key
,
4945 *p_epoch
= l
->epoch
;
4946 *p_version
= l
->lease_version
;
4949 if (e_lease_type
== SMB2_LEASE_NONE
) {
4953 send_break_message(conn
->sconn
->msg_ctx
, e
,
4957 * Windows 7 and 8 lease clients
4958 * are broken in that they will not
4959 * respond to lease break requests
4960 * whilst waiting for an outstanding
4961 * open request on that lease handle
4962 * on the same TCP connection, due
4963 * to holding an internal inode lock.
4965 * This means we can't reschedule
4966 * ourselves here, but must return
4971 * Send the breaks and then return
4972 * SMB2_LEASE_NONE in the lease handle
4973 * to cause them to acknowledge the
4974 * lease break. Consulatation with
4975 * Microsoft engineering confirmed
4976 * this approach is safe.
4983 * Ensure we don't grant anything more so we
4986 return NT_STATUS_OPLOCK_NOT_GRANTED
;
4990 * Wrapper around open_file_ntcreate and open_directory
4993 static NTSTATUS
create_file_unixpath(connection_struct
*conn
,
4994 struct smb_request
*req
,
4995 struct smb_filename
*smb_fname
,
4996 uint32_t access_mask
,
4997 uint32_t share_access
,
4998 uint32_t create_disposition
,
4999 uint32_t create_options
,
5000 uint32_t file_attributes
,
5001 uint32_t oplock_request
,
5002 struct smb2_lease
*lease
,
5003 uint64_t allocation_size
,
5004 uint32_t private_flags
,
5005 struct security_descriptor
*sd
,
5006 struct ea_list
*ea_list
,
5008 files_struct
**result
,
5011 int info
= FILE_WAS_OPENED
;
5012 files_struct
*base_fsp
= NULL
;
5013 files_struct
*fsp
= NULL
;
5016 DEBUG(10,("create_file_unixpath: access_mask = 0x%x "
5017 "file_attributes = 0x%x, share_access = 0x%x, "
5018 "create_disposition = 0x%x create_options = 0x%x "
5019 "oplock_request = 0x%x private_flags = 0x%x "
5020 "ea_list = 0x%p, sd = 0x%p, "
5022 (unsigned int)access_mask
,
5023 (unsigned int)file_attributes
,
5024 (unsigned int)share_access
,
5025 (unsigned int)create_disposition
,
5026 (unsigned int)create_options
,
5027 (unsigned int)oplock_request
,
5028 (unsigned int)private_flags
,
5029 ea_list
, sd
, smb_fname_str_dbg(smb_fname
)));
5031 if (create_options
& FILE_OPEN_BY_FILE_ID
) {
5032 status
= NT_STATUS_NOT_SUPPORTED
;
5036 if (create_options
& NTCREATEX_OPTIONS_INVALID_PARAM_MASK
) {
5037 status
= NT_STATUS_INVALID_PARAMETER
;
5042 oplock_request
|= INTERNAL_OPEN_ONLY
;
5045 if (lease
!= NULL
) {
5046 uint16_t epoch
= lease
->lease_epoch
;
5047 uint16_t version
= lease
->lease_version
;
5048 status
= lease_match(conn
,
5055 if (NT_STATUS_EQUAL(status
, NT_STATUS_OPLOCK_NOT_GRANTED
)) {
5056 /* Dynamic share file. No leases and update epoch... */
5057 lease
->lease_state
= SMB2_LEASE_NONE
;
5058 lease
->lease_epoch
= epoch
;
5059 lease
->lease_version
= version
;
5060 } else if (!NT_STATUS_IS_OK(status
)) {
5065 if ((conn
->fs_capabilities
& FILE_NAMED_STREAMS
)
5066 && (access_mask
& DELETE_ACCESS
)
5067 && !is_ntfs_stream_smb_fname(smb_fname
)) {
5069 * We can't open a file with DELETE access if any of the
5070 * streams is open without FILE_SHARE_DELETE
5072 status
= open_streams_for_delete(conn
, smb_fname
);
5074 if (!NT_STATUS_IS_OK(status
)) {
5079 if ((access_mask
& SEC_FLAG_SYSTEM_SECURITY
) &&
5080 !security_token_has_privilege(get_current_nttok(conn
),
5081 SEC_PRIV_SECURITY
)) {
5082 DEBUG(10, ("create_file_unixpath: open on %s "
5083 "failed - SEC_FLAG_SYSTEM_SECURITY denied.\n",
5084 smb_fname_str_dbg(smb_fname
)));
5085 status
= NT_STATUS_PRIVILEGE_NOT_HELD
;
5089 if ((conn
->fs_capabilities
& FILE_NAMED_STREAMS
)
5090 && is_ntfs_stream_smb_fname(smb_fname
)
5091 && (!(private_flags
& NTCREATEX_OPTIONS_PRIVATE_STREAM_DELETE
))) {
5092 uint32_t base_create_disposition
;
5093 struct smb_filename
*smb_fname_base
= NULL
;
5095 if (create_options
& FILE_DIRECTORY_FILE
) {
5096 status
= NT_STATUS_NOT_A_DIRECTORY
;
5100 switch (create_disposition
) {
5102 base_create_disposition
= FILE_OPEN
;
5105 base_create_disposition
= FILE_OPEN_IF
;
5109 /* Create an smb_filename with stream_name == NULL. */
5110 smb_fname_base
= synthetic_smb_fname(talloc_tos(),
5111 smb_fname
->base_name
,
5115 if (smb_fname_base
== NULL
) {
5116 status
= NT_STATUS_NO_MEMORY
;
5120 if (SMB_VFS_STAT(conn
, smb_fname_base
) == -1) {
5121 DEBUG(10, ("Unable to stat stream: %s\n",
5122 smb_fname_str_dbg(smb_fname_base
)));
5125 * https://bugzilla.samba.org/show_bug.cgi?id=10229
5126 * We need to check if the requested access mask
5127 * could be used to open the underlying file (if
5128 * it existed), as we're passing in zero for the
5129 * access mask to the base filename.
5131 status
= check_base_file_access(conn
,
5135 if (!NT_STATUS_IS_OK(status
)) {
5136 DEBUG(10, ("Permission check "
5137 "for base %s failed: "
5138 "%s\n", smb_fname
->base_name
,
5139 nt_errstr(status
)));
5144 /* Open the base file. */
5145 status
= create_file_unixpath(conn
, NULL
, smb_fname_base
, 0,
5148 | FILE_SHARE_DELETE
,
5149 base_create_disposition
,
5150 0, 0, 0, NULL
, 0, 0, NULL
, NULL
,
5152 TALLOC_FREE(smb_fname_base
);
5154 if (!NT_STATUS_IS_OK(status
)) {
5155 DEBUG(10, ("create_file_unixpath for base %s failed: "
5156 "%s\n", smb_fname
->base_name
,
5157 nt_errstr(status
)));
5160 /* we don't need the low level fd */
5165 * If it's a request for a directory open, deal with it separately.
5168 if (create_options
& FILE_DIRECTORY_FILE
) {
5170 if (create_options
& FILE_NON_DIRECTORY_FILE
) {
5171 status
= NT_STATUS_INVALID_PARAMETER
;
5175 /* Can't open a temp directory. IFS kit test. */
5176 if (!(file_attributes
& FILE_FLAG_POSIX_SEMANTICS
) &&
5177 (file_attributes
& FILE_ATTRIBUTE_TEMPORARY
)) {
5178 status
= NT_STATUS_INVALID_PARAMETER
;
5183 * We will get a create directory here if the Win32
5184 * app specified a security descriptor in the
5185 * CreateDirectory() call.
5189 status
= open_directory(
5190 conn
, req
, smb_fname
, access_mask
, share_access
,
5191 create_disposition
, create_options
, file_attributes
,
5196 * Ordinary file case.
5199 status
= file_new(req
, conn
, &fsp
);
5200 if(!NT_STATUS_IS_OK(status
)) {
5204 status
= fsp_set_smb_fname(fsp
, smb_fname
);
5205 if (!NT_STATUS_IS_OK(status
)) {
5211 * We're opening the stream element of a
5212 * base_fsp we already opened. Set up the
5215 fsp
->base_fsp
= base_fsp
;
5218 if (allocation_size
) {
5219 fsp
->initial_allocation_size
= smb_roundup(fsp
->conn
,
5223 status
= open_file_ntcreate(conn
,
5236 if(!NT_STATUS_IS_OK(status
)) {
5237 file_free(req
, fsp
);
5241 if (NT_STATUS_EQUAL(status
, NT_STATUS_FILE_IS_A_DIRECTORY
)) {
5243 /* A stream open never opens a directory */
5246 status
= NT_STATUS_FILE_IS_A_DIRECTORY
;
5251 * Fail the open if it was explicitly a non-directory
5255 if (create_options
& FILE_NON_DIRECTORY_FILE
) {
5256 status
= NT_STATUS_FILE_IS_A_DIRECTORY
;
5261 status
= open_directory(
5262 conn
, req
, smb_fname
, access_mask
,
5263 share_access
, create_disposition
,
5264 create_options
, file_attributes
,
5269 if (!NT_STATUS_IS_OK(status
)) {
5273 fsp
->base_fsp
= base_fsp
;
5275 if ((ea_list
!= NULL
) &&
5276 ((info
== FILE_WAS_CREATED
) || (info
== FILE_WAS_OVERWRITTEN
))) {
5277 status
= set_ea(conn
, fsp
, fsp
->fsp_name
, ea_list
);
5278 if (!NT_STATUS_IS_OK(status
)) {
5283 if (!fsp
->is_directory
&& S_ISDIR(fsp
->fsp_name
->st
.st_ex_mode
)) {
5284 status
= NT_STATUS_ACCESS_DENIED
;
5288 /* Save the requested allocation size. */
5289 if ((info
== FILE_WAS_CREATED
) || (info
== FILE_WAS_OVERWRITTEN
)) {
5290 if ((allocation_size
> fsp
->fsp_name
->st
.st_ex_size
)
5291 && !(fsp
->is_directory
))
5293 fsp
->initial_allocation_size
= smb_roundup(
5294 fsp
->conn
, allocation_size
);
5295 if (vfs_allocate_file_space(
5296 fsp
, fsp
->initial_allocation_size
) == -1) {
5297 status
= NT_STATUS_DISK_FULL
;
5301 fsp
->initial_allocation_size
= smb_roundup(
5302 fsp
->conn
, (uint64_t)fsp
->fsp_name
->st
.st_ex_size
);
5305 fsp
->initial_allocation_size
= 0;
5308 if ((info
== FILE_WAS_CREATED
) && lp_nt_acl_support(SNUM(conn
)) &&
5309 fsp
->base_fsp
== NULL
) {
5312 * According to the MS documentation, the only time the security
5313 * descriptor is applied to the opened file is iff we *created* the
5314 * file; an existing file stays the same.
5316 * Also, it seems (from observation) that you can open the file with
5317 * any access mask but you can still write the sd. We need to override
5318 * the granted access before we call set_sd
5319 * Patch for bug #2242 from Tom Lackemann <cessnatomny@yahoo.com>.
5322 uint32_t sec_info_sent
;
5323 uint32_t saved_access_mask
= fsp
->access_mask
;
5325 sec_info_sent
= get_sec_info(sd
);
5327 fsp
->access_mask
= FILE_GENERIC_ALL
;
5329 if (sec_info_sent
& (SECINFO_OWNER
|
5333 status
= set_sd(fsp
, sd
, sec_info_sent
);
5336 fsp
->access_mask
= saved_access_mask
;
5338 if (!NT_STATUS_IS_OK(status
)) {
5341 } else if (lp_inherit_acls(SNUM(conn
))) {
5342 /* Inherit from parent. Errors here are not fatal. */
5343 status
= inherit_new_acl(fsp
);
5344 if (!NT_STATUS_IS_OK(status
)) {
5345 DEBUG(10,("inherit_new_acl: failed for %s with %s\n",
5347 nt_errstr(status
) ));
5352 if ((conn
->fs_capabilities
& FILE_FILE_COMPRESSION
)
5353 && (create_options
& FILE_NO_COMPRESSION
)
5354 && (info
== FILE_WAS_CREATED
)) {
5355 status
= SMB_VFS_SET_COMPRESSION(conn
, fsp
, fsp
,
5356 COMPRESSION_FORMAT_NONE
);
5357 if (!NT_STATUS_IS_OK(status
)) {
5358 DEBUG(1, ("failed to disable compression: %s\n",
5359 nt_errstr(status
)));
5363 DEBUG(10, ("create_file_unixpath: info=%d\n", info
));
5366 if (pinfo
!= NULL
) {
5370 smb_fname
->st
= fsp
->fsp_name
->st
;
5372 return NT_STATUS_OK
;
5375 DEBUG(10, ("create_file_unixpath: %s\n", nt_errstr(status
)));
5378 if (base_fsp
&& fsp
->base_fsp
== base_fsp
) {
5380 * The close_file below will close
5385 close_file(req
, fsp
, ERROR_CLOSE
);
5388 if (base_fsp
!= NULL
) {
5389 close_file(req
, base_fsp
, ERROR_CLOSE
);
5396 * Calculate the full path name given a relative fid.
5398 NTSTATUS
get_relative_fid_filename(connection_struct
*conn
,
5399 struct smb_request
*req
,
5400 uint16_t root_dir_fid
,
5401 const struct smb_filename
*smb_fname
,
5402 struct smb_filename
**smb_fname_out
)
5404 files_struct
*dir_fsp
;
5405 char *parent_fname
= NULL
;
5406 char *new_base_name
= NULL
;
5407 uint32_t ucf_flags
= ((req
!= NULL
&& req
->posix_pathnames
) ?
5408 UCF_POSIX_PATHNAMES
: 0);
5411 if (root_dir_fid
== 0 || !smb_fname
) {
5412 status
= NT_STATUS_INTERNAL_ERROR
;
5416 dir_fsp
= file_fsp(req
, root_dir_fid
);
5418 if (dir_fsp
== NULL
) {
5419 status
= NT_STATUS_INVALID_HANDLE
;
5423 if (is_ntfs_stream_smb_fname(dir_fsp
->fsp_name
)) {
5424 status
= NT_STATUS_INVALID_HANDLE
;
5428 if (!dir_fsp
->is_directory
) {
5431 * Check to see if this is a mac fork of some kind.
5434 if ((conn
->fs_capabilities
& FILE_NAMED_STREAMS
) &&
5435 is_ntfs_stream_smb_fname(smb_fname
)) {
5436 status
= NT_STATUS_OBJECT_PATH_NOT_FOUND
;
5441 we need to handle the case when we get a
5442 relative open relative to a file and the
5443 pathname is blank - this is a reopen!
5444 (hint from demyn plantenberg)
5447 status
= NT_STATUS_INVALID_HANDLE
;
5451 if (ISDOT(dir_fsp
->fsp_name
->base_name
)) {
5453 * We're at the toplevel dir, the final file name
5454 * must not contain ./, as this is filtered out
5455 * normally by srvstr_get_path and unix_convert
5456 * explicitly rejects paths containing ./.
5458 parent_fname
= talloc_strdup(talloc_tos(), "");
5459 if (parent_fname
== NULL
) {
5460 status
= NT_STATUS_NO_MEMORY
;
5464 size_t dir_name_len
= strlen(dir_fsp
->fsp_name
->base_name
);
5467 * Copy in the base directory name.
5470 parent_fname
= talloc_array(talloc_tos(), char,
5472 if (parent_fname
== NULL
) {
5473 status
= NT_STATUS_NO_MEMORY
;
5476 memcpy(parent_fname
, dir_fsp
->fsp_name
->base_name
,
5480 * Ensure it ends in a '/'.
5481 * We used TALLOC_SIZE +2 to add space for the '/'.
5485 && (parent_fname
[dir_name_len
-1] != '\\')
5486 && (parent_fname
[dir_name_len
-1] != '/')) {
5487 parent_fname
[dir_name_len
] = '/';
5488 parent_fname
[dir_name_len
+1] = '\0';
5492 new_base_name
= talloc_asprintf(talloc_tos(), "%s%s", parent_fname
,
5493 smb_fname
->base_name
);
5494 if (new_base_name
== NULL
) {
5495 status
= NT_STATUS_NO_MEMORY
;
5499 status
= filename_convert(req
,
5501 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
5506 if (!NT_STATUS_IS_OK(status
)) {
5511 TALLOC_FREE(parent_fname
);
5512 TALLOC_FREE(new_base_name
);
5516 NTSTATUS
create_file_default(connection_struct
*conn
,
5517 struct smb_request
*req
,
5518 uint16_t root_dir_fid
,
5519 struct smb_filename
*smb_fname
,
5520 uint32_t access_mask
,
5521 uint32_t share_access
,
5522 uint32_t create_disposition
,
5523 uint32_t create_options
,
5524 uint32_t file_attributes
,
5525 uint32_t oplock_request
,
5526 struct smb2_lease
*lease
,
5527 uint64_t allocation_size
,
5528 uint32_t private_flags
,
5529 struct security_descriptor
*sd
,
5530 struct ea_list
*ea_list
,
5531 files_struct
**result
,
5533 const struct smb2_create_blobs
*in_context_blobs
,
5534 struct smb2_create_blobs
*out_context_blobs
)
5536 int info
= FILE_WAS_OPENED
;
5537 files_struct
*fsp
= NULL
;
5539 bool stream_name
= false;
5541 DEBUG(10,("create_file: access_mask = 0x%x "
5542 "file_attributes = 0x%x, share_access = 0x%x, "
5543 "create_disposition = 0x%x create_options = 0x%x "
5544 "oplock_request = 0x%x "
5545 "private_flags = 0x%x "
5546 "root_dir_fid = 0x%x, ea_list = 0x%p, sd = 0x%p, "
5548 (unsigned int)access_mask
,
5549 (unsigned int)file_attributes
,
5550 (unsigned int)share_access
,
5551 (unsigned int)create_disposition
,
5552 (unsigned int)create_options
,
5553 (unsigned int)oplock_request
,
5554 (unsigned int)private_flags
,
5555 (unsigned int)root_dir_fid
,
5556 ea_list
, sd
, smb_fname_str_dbg(smb_fname
)));
5559 * Calculate the filename from the root_dir_if if necessary.
5562 if (root_dir_fid
!= 0) {
5563 struct smb_filename
*smb_fname_out
= NULL
;
5564 status
= get_relative_fid_filename(conn
, req
, root_dir_fid
,
5565 smb_fname
, &smb_fname_out
);
5566 if (!NT_STATUS_IS_OK(status
)) {
5569 smb_fname
= smb_fname_out
;
5573 * Check to see if this is a mac fork of some kind.
5576 stream_name
= is_ntfs_stream_smb_fname(smb_fname
);
5578 enum FAKE_FILE_TYPE fake_file_type
;
5580 fake_file_type
= is_fake_file(smb_fname
);
5582 if (fake_file_type
!= FAKE_FILE_TYPE_NONE
) {
5585 * Here we go! support for changing the disk quotas
5588 * We need to fake up to open this MAGIC QUOTA file
5589 * and return a valid FID.
5591 * w2k close this file directly after openening xp
5592 * also tries a QUERY_FILE_INFO on the file and then
5595 status
= open_fake_file(req
, conn
, req
->vuid
,
5596 fake_file_type
, smb_fname
,
5598 if (!NT_STATUS_IS_OK(status
)) {
5602 ZERO_STRUCT(smb_fname
->st
);
5606 if (!(conn
->fs_capabilities
& FILE_NAMED_STREAMS
)) {
5607 status
= NT_STATUS_OBJECT_NAME_NOT_FOUND
;
5612 if (is_ntfs_default_stream_smb_fname(smb_fname
)) {
5614 smb_fname
->stream_name
= NULL
;
5615 /* We have to handle this error here. */
5616 if (create_options
& FILE_DIRECTORY_FILE
) {
5617 status
= NT_STATUS_NOT_A_DIRECTORY
;
5620 if (req
!= NULL
&& req
->posix_pathnames
) {
5621 ret
= SMB_VFS_LSTAT(conn
, smb_fname
);
5623 ret
= SMB_VFS_STAT(conn
, smb_fname
);
5626 if (ret
== 0 && VALID_STAT_OF_DIR(smb_fname
->st
)) {
5627 status
= NT_STATUS_FILE_IS_A_DIRECTORY
;
5632 status
= create_file_unixpath(
5633 conn
, req
, smb_fname
, access_mask
, share_access
,
5634 create_disposition
, create_options
, file_attributes
,
5635 oplock_request
, lease
, allocation_size
, private_flags
,
5639 if (!NT_STATUS_IS_OK(status
)) {
5644 DEBUG(10, ("create_file: info=%d\n", info
));
5647 if (pinfo
!= NULL
) {
5650 return NT_STATUS_OK
;
5653 DEBUG(10, ("create_file: %s\n", nt_errstr(status
)));
5656 close_file(req
, fsp
, ERROR_CLOSE
);