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
7 Copyright (C) Ralph Boehme 2017
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "system/filesys.h"
25 #include "lib/util/server_id.h"
27 #include "locking/share_mode_lock.h"
28 #include "smbd/smbd.h"
29 #include "smbd/globals.h"
30 #include "fake_file.h"
31 #include "../libcli/security/security.h"
32 #include "../librpc/gen_ndr/ndr_security.h"
33 #include "../librpc/gen_ndr/ndr_open_files.h"
34 #include "../librpc/gen_ndr/idmap.h"
35 #include "../librpc/gen_ndr/ioctl.h"
36 #include "passdb/lookup_sid.h"
40 #include "source3/lib/dbwrap/dbwrap_watch.h"
41 #include "locking/leases_db.h"
42 #include "librpc/gen_ndr/ndr_leases_db.h"
43 #include "lib/util/time_basic.h"
44 #include "source3/smbd/dir.h"
46 #if defined(HAVE_LINUX_MAGIC_H)
47 #include <linux/magic.h>
50 static NTSTATUS
inherit_new_acl(files_struct
*dirfsp
, files_struct
*fsp
);
52 extern const struct generic_mapping file_generic_mapping
;
54 struct deferred_open_record
{
55 struct smbXsrv_connection
*xconn
;
61 * Timer for async opens, needed because they don't use a watch on
62 * a locking.tdb record. This is currently only used for real async
63 * opens and just terminates smbd if the async open times out.
65 struct tevent_timer
*te
;
68 * For the samba kernel oplock case we use both a timeout and
69 * a watch on locking.tdb. This way in case it's smbd holding
70 * the kernel oplock we get directly notified for the retry
71 * once the kernel oplock is properly broken. Store the req
72 * here so that it can be timely discarded once the timer
75 struct tevent_req
*watch_req
;
78 /****************************************************************************
79 If the requester wanted DELETE_ACCESS and was rejected because
80 the file ACL didn't include DELETE_ACCESS, see if the parent ACL
82 ****************************************************************************/
84 static bool parent_override_delete(connection_struct
*conn
,
85 struct files_struct
*dirfsp
,
86 const struct smb_filename
*smb_fname
,
88 uint32_t rejected_mask
)
90 if ((access_mask
& DELETE_ACCESS
) && (rejected_mask
& DELETE_ACCESS
)) {
92 ok
= can_delete_file_in_directory(conn
, dirfsp
, smb_fname
);
99 /****************************************************************************
100 Check if we have open rights.
101 ****************************************************************************/
103 static NTSTATUS
smbd_check_access_rights_fname(
104 struct connection_struct
*conn
,
105 const struct smb_filename
*smb_fname
,
107 uint32_t access_mask
,
108 uint32_t do_not_check_mask
)
110 uint32_t rejected_share_access
;
111 uint32_t effective_access
;
113 rejected_share_access
= access_mask
& ~(conn
->share_access
);
115 if (rejected_share_access
) {
116 DBG_DEBUG("rejected share access 0x%"PRIx32
" on "
117 "%s (0x%"PRIx32
")\n",
119 smb_fname_str_dbg(smb_fname
),
120 rejected_share_access
);
121 return NT_STATUS_ACCESS_DENIED
;
124 effective_access
= access_mask
& ~do_not_check_mask
;
125 if (effective_access
== 0) {
126 DBG_DEBUG("do_not_check_mask override on %s. Granting 0x%x for free.\n",
127 smb_fname_str_dbg(smb_fname
),
128 (unsigned int)access_mask
);
132 if (!use_privs
&& get_current_uid(conn
) == (uid_t
)0) {
133 /* I'm sorry sir, I didn't know you were root... */
134 DBG_DEBUG("root override on %s. Granting 0x%x\n",
135 smb_fname_str_dbg(smb_fname
),
136 (unsigned int)access_mask
);
140 if ((access_mask
& DELETE_ACCESS
) &&
141 !lp_acl_check_permissions(SNUM(conn
)))
143 DBG_DEBUG("Not checking ACL on DELETE_ACCESS on file %s. "
144 "Granting 0x%"PRIx32
"\n",
145 smb_fname_str_dbg(smb_fname
),
150 if (access_mask
== DELETE_ACCESS
&&
151 VALID_STAT(smb_fname
->st
) &&
152 S_ISLNK(smb_fname
->st
.st_ex_mode
))
154 /* We can always delete a symlink. */
155 DBG_DEBUG("Not checking ACL on DELETE_ACCESS on symlink %s.\n",
156 smb_fname_str_dbg(smb_fname
));
160 return NT_STATUS_MORE_PROCESSING_REQUIRED
;
163 static NTSTATUS
smbd_check_access_rights_sd(
164 struct connection_struct
*conn
,
165 struct files_struct
*dirfsp
,
166 const struct smb_filename
*smb_fname
,
167 struct security_descriptor
*sd
,
169 uint32_t access_mask
,
170 uint32_t do_not_check_mask
)
172 uint32_t rejected_mask
= access_mask
;
179 status
= se_file_access_check(sd
,
180 get_current_nttok(conn
),
182 (access_mask
& ~do_not_check_mask
),
185 DBG_DEBUG("File [%s] requesting [0x%"PRIx32
"] "
186 "returning [0x%"PRIx32
"] (%s)\n",
187 smb_fname_str_dbg(smb_fname
),
192 if (!NT_STATUS_IS_OK(status
)) {
193 if (DEBUGLEVEL
>= 10) {
194 DBG_DEBUG("acl for %s is:\n",
195 smb_fname_str_dbg(smb_fname
));
196 NDR_PRINT_DEBUG(security_descriptor
, sd
);
202 if (NT_STATUS_IS_OK(status
) ||
203 !NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
))
208 /* Here we know status == NT_STATUS_ACCESS_DENIED. */
212 if ((access_mask
& FILE_WRITE_ATTRIBUTES
) &&
213 (rejected_mask
& FILE_WRITE_ATTRIBUTES
) &&
214 !lp_store_dos_attributes(SNUM(conn
)) &&
215 (lp_map_readonly(SNUM(conn
)) ||
216 lp_map_archive(SNUM(conn
)) ||
217 lp_map_hidden(SNUM(conn
)) ||
218 lp_map_system(SNUM(conn
))))
220 rejected_mask
&= ~FILE_WRITE_ATTRIBUTES
;
222 DBG_DEBUG("overrode FILE_WRITE_ATTRIBUTES on file %s\n",
223 smb_fname_str_dbg(smb_fname
));
226 if (parent_override_delete(conn
,
233 * Were we trying to do an open for delete and didn't get DELETE
234 * access. Check if the directory allows DELETE_CHILD.
236 * http://blogs.msdn.com/oldnewthing/archive/2004/06/04/148426.aspx
240 rejected_mask
&= ~DELETE_ACCESS
;
242 DBG_DEBUG("Overrode DELETE_ACCESS on file %s\n",
243 smb_fname_str_dbg(smb_fname
));
246 if (rejected_mask
!= 0) {
247 return NT_STATUS_ACCESS_DENIED
;
252 NTSTATUS
smbd_check_access_rights_fsp(struct files_struct
*dirfsp
,
253 struct files_struct
*fsp
,
255 uint32_t access_mask
)
257 struct security_descriptor
*sd
= NULL
;
258 uint32_t do_not_check_mask
= 0;
261 /* Cope with fake/printer fsp's. */
262 if (fsp
->fake_file_handle
!= NULL
|| fsp
->print_file
!= NULL
) {
263 if ((fsp
->access_mask
& access_mask
) != access_mask
) {
264 return NT_STATUS_ACCESS_DENIED
;
269 if (fsp_get_pathref_fd(fsp
) == -1) {
271 * This is a POSIX open on a symlink. For the pathname
272 * version of this function we used to return the st_mode
273 * bits turned into an NT ACL. For a symlink the mode bits
274 * are always rwxrwxrwx which means the pathname version always
275 * returned NT_STATUS_OK for a symlink. For the handle reference
276 * to a symlink use the handle access bits.
278 if ((fsp
->access_mask
& access_mask
) != access_mask
) {
279 return NT_STATUS_ACCESS_DENIED
;
285 * If we can access the path to this file, by
286 * default we have FILE_READ_ATTRIBUTES from the
287 * containing directory. See the section:
288 * "Algorithm to Check Access to an Existing File"
291 * se_file_access_check() also takes care of
292 * owner WRITE_DAC and READ_CONTROL.
294 do_not_check_mask
= FILE_READ_ATTRIBUTES
;
297 * Samba 3.6 and earlier granted execute access even
298 * if the ACL did not contain execute rights.
299 * Samba 4.0 is more correct and checks it.
300 * The compatibility mode allows one to skip this check
301 * to smoothen upgrades.
303 if (lp_acl_allow_execute_always(SNUM(fsp
->conn
))) {
304 do_not_check_mask
|= FILE_EXECUTE
;
307 status
= smbd_check_access_rights_fname(fsp
->conn
,
312 if (!NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
316 status
= SMB_VFS_FGET_NT_ACL(metadata_fsp(fsp
),
322 if (!NT_STATUS_IS_OK(status
)) {
323 DBG_DEBUG("Could not get acl on %s: %s\n",
329 return smbd_check_access_rights_sd(fsp
->conn
,
339 * Given an fsp that represents a parent directory,
340 * check if the requested access can be granted.
342 NTSTATUS
check_parent_access_fsp(struct files_struct
*fsp
,
343 uint32_t access_mask
)
346 struct security_descriptor
*parent_sd
= NULL
;
347 uint32_t access_granted
= 0;
349 bool delete_on_close_set
;
350 TALLOC_CTX
*frame
= talloc_stackframe();
352 if (get_current_uid(fsp
->conn
) == (uid_t
)0) {
353 /* I'm sorry sir, I didn't know you were root... */
354 DBG_DEBUG("root override on %s. Granting 0x%x\n",
356 (unsigned int)access_mask
);
357 status
= NT_STATUS_OK
;
361 status
= SMB_VFS_FGET_NT_ACL(fsp
,
362 (SECINFO_OWNER
| SECINFO_GROUP
| SECINFO_DACL
),
366 if (!NT_STATUS_IS_OK(status
)) {
367 DBG_INFO("SMB_VFS_FGET_NT_ACL failed for "
368 "%s with error %s\n",
375 * If we can access the path to this file, by
376 * default we have FILE_READ_ATTRIBUTES from the
377 * containing directory. See the section:
378 * "Algorithm to Check Access to an Existing File"
381 * se_file_access_check() also takes care of
382 * owner WRITE_DAC and READ_CONTROL.
384 status
= se_file_access_check(parent_sd
,
385 get_current_nttok(fsp
->conn
),
387 (access_mask
& ~FILE_READ_ATTRIBUTES
),
389 if(!NT_STATUS_IS_OK(status
)) {
390 DBG_INFO("access check "
391 "on directory %s for mask 0x%x returned (0x%x) %s\n",
399 if (!(access_mask
& (SEC_DIR_ADD_FILE
| SEC_DIR_ADD_SUBDIR
))) {
400 status
= NT_STATUS_OK
;
403 if (!lp_check_parent_directory_delete_on_close(SNUM(fsp
->conn
))) {
404 status
= NT_STATUS_OK
;
408 /* Check if the directory has delete-on-close set */
409 status
= file_name_hash(fsp
->conn
,
410 fsp
->fsp_name
->base_name
,
412 if (!NT_STATUS_IS_OK(status
)) {
416 get_file_infos(fsp
->file_id
, name_hash
, &delete_on_close_set
, NULL
);
417 if (delete_on_close_set
) {
418 status
= NT_STATUS_DELETE_PENDING
;
422 status
= NT_STATUS_OK
;
429 /****************************************************************************
430 Ensure when opening a base file for a stream open that we have permissions
431 to do so given the access mask on the base file.
432 ****************************************************************************/
434 static NTSTATUS
check_base_file_access(struct files_struct
*fsp
,
435 uint32_t access_mask
)
439 status
= smbd_calculate_access_mask_fsp(fsp
->conn
->cwd_fsp
,
444 if (!NT_STATUS_IS_OK(status
)) {
445 DEBUG(10, ("smbd_calculate_access_mask "
446 "on file %s returned %s\n",
452 if (access_mask
& (FILE_WRITE_DATA
|FILE_APPEND_DATA
)) {
454 if (!CAN_WRITE(fsp
->conn
)) {
455 return NT_STATUS_ACCESS_DENIED
;
457 dosattrs
= fdos_mode(fsp
);
458 if (dosattrs
& FILE_ATTRIBUTE_READONLY
) {
459 return NT_STATUS_ACCESS_DENIED
;
463 return smbd_check_access_rights_fsp(fsp
->conn
->cwd_fsp
,
469 static NTSTATUS
chdir_below_conn(
471 connection_struct
*conn
,
472 const char *connectpath
,
473 size_t connectpath_len
,
474 struct smb_filename
*dir_fname
,
475 struct smb_filename
**_oldwd_fname
)
477 struct smb_filename
*oldwd_fname
= NULL
;
478 struct smb_filename
*smb_fname_dot
= NULL
;
479 struct smb_filename
*real_fname
= NULL
;
480 const char *relative
= NULL
;
485 if (!ISDOT(dir_fname
->base_name
)) {
487 oldwd_fname
= vfs_GetWd(talloc_tos(), conn
);
488 if (oldwd_fname
== NULL
) {
489 status
= map_nt_error_from_unix(errno
);
493 /* Pin parent directory in place. */
494 ret
= vfs_ChDir(conn
, dir_fname
);
496 status
= map_nt_error_from_unix(errno
);
497 DBG_DEBUG("chdir to %s failed: %s\n",
498 dir_fname
->base_name
,
504 smb_fname_dot
= synthetic_smb_fname(
511 if (smb_fname_dot
== NULL
) {
512 status
= NT_STATUS_NO_MEMORY
;
516 real_fname
= SMB_VFS_REALPATH(conn
, talloc_tos(), smb_fname_dot
);
517 if (real_fname
== NULL
) {
518 status
= map_nt_error_from_unix(errno
);
519 DBG_DEBUG("realpath in %s failed: %s\n",
520 dir_fname
->base_name
,
524 TALLOC_FREE(smb_fname_dot
);
526 ok
= subdir_of(connectpath
,
528 real_fname
->base_name
,
531 TALLOC_FREE(real_fname
);
532 *_oldwd_fname
= oldwd_fname
;
536 DBG_NOTICE("Bad access attempt: %s is a symlink "
537 "outside the share path\n"
539 "resolved_name=%s\n",
540 dir_fname
->base_name
,
542 real_fname
->base_name
);
543 TALLOC_FREE(real_fname
);
545 status
= NT_STATUS_OBJECT_NAME_NOT_FOUND
;
548 if (oldwd_fname
!= NULL
) {
549 ret
= vfs_ChDir(conn
, oldwd_fname
);
550 SMB_ASSERT(ret
== 0);
551 TALLOC_FREE(oldwd_fname
);
558 * Get the symlink target of dirfsp/symlink_name, making sure the
559 * target is below connection_path.
562 static NTSTATUS
symlink_target_below_conn(
564 const char *connection_path
,
565 struct files_struct
*fsp
,
566 struct files_struct
*dirfsp
,
567 struct smb_filename
*symlink_name
,
571 char *absolute
= NULL
;
574 if (fsp_get_pathref_fd(fsp
) != -1) {
576 * fsp is an O_PATH open, Linux does a "freadlink"
577 * with an empty name argument to readlinkat
579 status
= readlink_talloc(talloc_tos(), fsp
, NULL
, &target
);
581 status
= readlink_talloc(
582 talloc_tos(), dirfsp
, symlink_name
, &target
);
585 status
= safe_symlink_target_path(talloc_tos(),
587 dirfsp
->fsp_name
->base_name
,
591 if (!NT_STATUS_IS_OK(status
)) {
592 DBG_DEBUG("safe_symlink_target_path() failed: %s\n",
597 if (absolute
[0] == '\0') {
599 * special case symlink to share root: "." is our
600 * share root filename
602 TALLOC_FREE(absolute
);
603 absolute
= talloc_strdup(talloc_tos(), ".");
604 if (absolute
== NULL
) {
605 return NT_STATUS_NO_MEMORY
;
613 /****************************************************************************
615 ****************************************************************************/
617 static NTSTATUS
non_widelink_open(const struct files_struct
*dirfsp
,
619 struct smb_filename
*smb_fname
,
620 const struct vfs_open_how
*_how
)
622 struct connection_struct
*conn
= fsp
->conn
;
623 const char *connpath
= SMB_VFS_CONNECTPATH(conn
, dirfsp
, smb_fname
);
625 NTSTATUS status
= NT_STATUS_OK
;
627 char *orig_smb_fname_base
= smb_fname
->base_name
;
628 struct smb_filename
*orig_fsp_name
= fsp
->fsp_name
;
629 struct smb_filename
*smb_fname_rel
= NULL
;
630 struct smb_filename
*oldwd_fname
= NULL
;
631 struct smb_filename
*parent_dir_fname
= NULL
;
632 struct vfs_open_how how
= *_how
;
634 size_t link_depth
= 0;
637 SMB_ASSERT(!fsp_is_alternate_stream(fsp
));
639 if (connpath
== NULL
) {
641 * This can happen with shadow_copy2 if the snapshot
644 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
646 connpath_len
= strlen(connpath
);
649 if (smb_fname
->base_name
[0] == '/') {
650 int cmp
= strcmp(connpath
, smb_fname
->base_name
);
652 smb_fname
->base_name
= talloc_strdup(smb_fname
, "");
653 if (smb_fname
->base_name
== NULL
) {
654 status
= NT_STATUS_NO_MEMORY
;
660 if (dirfsp
== conn
->cwd_fsp
) {
662 status
= SMB_VFS_PARENT_PATHNAME(fsp
->conn
,
667 if (!NT_STATUS_IS_OK(status
)) {
671 status
= chdir_below_conn(
678 if (!NT_STATUS_IS_OK(status
)) {
682 /* Setup fsp->fsp_name to be relative to cwd */
683 fsp
->fsp_name
= smb_fname_rel
;
686 * fsp->fsp_name is unchanged as it is already correctly
687 * relative to dirfsp.
689 smb_fname_rel
= smb_fname
;
694 * Assert nobody can step in with a symlink on the
695 * path, there is no path anymore and we'll use
696 * O_NOFOLLOW to open.
698 char *slash
= strchr_m(smb_fname_rel
->base_name
, '/');
699 SMB_ASSERT(slash
== NULL
);
702 how
.flags
|= O_NOFOLLOW
;
704 fd
= SMB_VFS_OPENAT(conn
,
709 fsp_set_fd(fsp
, fd
); /* This preserves errno */
712 status
= map_nt_error_from_unix(errno
);
714 if (errno
== ENOENT
) {
719 * ENOENT makes it worthless retrying with a
720 * stat, we know for sure the file does not
721 * exist. For everything else we want to know
724 ret
= SMB_VFS_FSTATAT(
729 AT_SYMLINK_NOFOLLOW
);
733 * Keep the original error. Otherwise we would
734 * mask for example EROFS for open(O_CREAT),
735 * turning it into ENOENT.
740 ret
= SMB_VFS_FSTAT(fsp
, &fsp
->fsp_name
->st
);
744 status
= map_nt_error_from_unix(errno
);
745 DBG_DEBUG("fstat[at](%s) failed: %s\n",
746 smb_fname_str_dbg(smb_fname
),
751 fsp
->fsp_flags
.is_directory
= S_ISDIR(fsp
->fsp_name
->st
.st_ex_mode
);
752 orig_fsp_name
->st
= fsp
->fsp_name
->st
;
754 if (!S_ISLNK(fsp
->fsp_name
->st
.st_ex_mode
)) {
759 * Found a symlink to follow in user space
762 if (fsp
->fsp_name
->flags
& SMB_FILENAME_POSIX_PATH
) {
763 /* Never follow symlinks on posix open. */
764 status
= NT_STATUS_STOPPED_ON_SYMLINK
;
767 if (!lp_follow_symlinks(SNUM(conn
))) {
768 /* Explicitly no symlinks. */
769 status
= NT_STATUS_STOPPED_ON_SYMLINK
;
774 if (link_depth
>= 40) {
775 status
= NT_STATUS_STOPPED_ON_SYMLINK
;
779 fsp
->fsp_name
= orig_fsp_name
;
781 status
= symlink_target_below_conn(
785 discard_const_p(files_struct
, dirfsp
),
789 if (!NT_STATUS_IS_OK(status
)) {
790 DBG_DEBUG("symlink_target_below_conn() failed: %s\n",
796 * Close what openat(O_PATH) potentially left behind
800 if (smb_fname
->base_name
!= orig_smb_fname_base
) {
801 TALLOC_FREE(smb_fname
->base_name
);
803 smb_fname
->base_name
= target
;
805 if (oldwd_fname
!= NULL
) {
806 ret
= vfs_ChDir(conn
, oldwd_fname
);
808 smb_panic("unable to get back to old directory\n");
810 TALLOC_FREE(oldwd_fname
);
814 * And do it all again... As smb_fname is not relative to the passed in
815 * dirfsp anymore, we pass conn->cwd_fsp as dirfsp to
816 * non_widelink_open() to trigger the chdir(parentdir) logic.
818 dirfsp
= conn
->cwd_fsp
;
823 fsp
->fsp_name
= orig_fsp_name
;
824 smb_fname
->base_name
= orig_smb_fname_base
;
826 TALLOC_FREE(parent_dir_fname
);
828 if (!NT_STATUS_IS_OK(status
)) {
832 if (oldwd_fname
!= NULL
) {
833 ret
= vfs_ChDir(conn
, oldwd_fname
);
835 smb_panic("unable to get back to old directory\n");
837 TALLOC_FREE(oldwd_fname
);
842 /****************************************************************************
843 fd support routines - attempt to do a dos_open.
844 ****************************************************************************/
846 NTSTATUS
fd_openat(const struct files_struct
*dirfsp
,
847 struct smb_filename
*smb_fname
,
849 const struct vfs_open_how
*_how
)
851 struct vfs_open_how how
= *_how
;
852 struct connection_struct
*conn
= fsp
->conn
;
853 NTSTATUS status
= NT_STATUS_OK
;
854 bool fsp_is_stream
= fsp_is_alternate_stream(fsp
);
855 bool smb_fname_is_stream
= is_named_stream(smb_fname
);
857 SMB_ASSERT(fsp_is_stream
== smb_fname_is_stream
);
860 * Never follow symlinks on a POSIX client. The
861 * client should be doing this.
864 if ((fsp
->posix_flags
& FSP_POSIX_FLAGS_OPEN
) || !lp_follow_symlinks(SNUM(conn
))) {
865 how
.flags
|= O_NOFOLLOW
;
873 NULL
, /* stream open is relative to fsp->base_fsp */
878 status
= map_nt_error_from_unix(errno
);
883 status
= vfs_stat_fsp(fsp
);
884 if (!NT_STATUS_IS_OK(status
)) {
885 DBG_DEBUG("vfs_stat_fsp failed: %s\n",
895 * Only follow symlinks within a share
898 status
= non_widelink_open(dirfsp
, fsp
, smb_fname
, &how
);
899 if (!NT_STATUS_IS_OK(status
)) {
900 if (NT_STATUS_EQUAL(status
, NT_STATUS_TOO_MANY_OPENED_FILES
)) {
901 static time_t last_warned
= 0L;
903 if (time((time_t *) NULL
) > last_warned
) {
904 DEBUG(0,("Too many open files, unable "
905 "to open more! smbd's max "
907 lp_max_open_files()));
908 last_warned
= time((time_t *) NULL
);
912 DBG_DEBUG("name %s, flags = 0%o mode = 0%o, fd = %d. %s\n",
913 smb_fname_str_dbg(smb_fname
),
916 fsp_get_pathref_fd(fsp
),
921 DBG_DEBUG("name %s, flags = 0%o mode = 0%o, fd = %d\n",
922 smb_fname_str_dbg(smb_fname
),
925 fsp_get_pathref_fd(fsp
));
930 /****************************************************************************
931 Close the file associated with a fsp.
932 ****************************************************************************/
934 NTSTATUS
fd_close(files_struct
*fsp
)
936 NTSTATUS stat_status
= NT_STATUS_OK
;
939 if (fsp
== fsp
->conn
->cwd_fsp
) {
943 if (fsp
->fsp_flags
.fstat_before_close
) {
945 * capture status, if failure
946 * continue close processing
949 stat_status
= vfs_stat_fsp(fsp
);
955 if (fsp_get_pathref_fd(fsp
) == -1) {
957 * Either a directory where the dptr_CloseDir() already closed
958 * the fd or a stat open.
962 if (fh_get_refcount(fsp
->fh
) > 1) {
963 return NT_STATUS_OK
; /* Shared handle. Only close last reference. */
966 ret
= SMB_VFS_CLOSE(fsp
);
969 return map_nt_error_from_unix(errno
);
974 /****************************************************************************
975 Change the ownership of a file to that of the parent directory.
976 Do this by fd if possible.
977 ****************************************************************************/
979 static void change_file_owner_to_parent_fsp(struct files_struct
*parent_fsp
,
980 struct files_struct
*fsp
)
984 if (parent_fsp
->fsp_name
->st
.st_ex_uid
== fsp
->fsp_name
->st
.st_ex_uid
) {
985 /* Already this uid - no need to change. */
986 DBG_DEBUG("file %s is already owned by uid %u\n",
988 (unsigned int)fsp
->fsp_name
->st
.st_ex_uid
);
993 ret
= SMB_VFS_FCHOWN(fsp
,
994 parent_fsp
->fsp_name
->st
.st_ex_uid
,
998 DBG_ERR("failed to fchown "
999 "file %s to parent directory uid %u. Error "
1002 (unsigned int)parent_fsp
->fsp_name
->st
.st_ex_uid
,
1005 DBG_DEBUG("changed new file %s to "
1006 "parent directory uid %u.\n",
1008 (unsigned int)parent_fsp
->fsp_name
->st
.st_ex_uid
);
1009 /* Ensure the uid entry is updated. */
1010 fsp
->fsp_name
->st
.st_ex_uid
=
1011 parent_fsp
->fsp_name
->st
.st_ex_uid
;
1015 static NTSTATUS
change_dir_owner_to_parent_fsp(struct files_struct
*parent_fsp
,
1016 struct files_struct
*fsp
)
1021 if (parent_fsp
->fsp_name
->st
.st_ex_uid
== fsp
->fsp_name
->st
.st_ex_uid
) {
1022 /* Already this uid - no need to change. */
1023 DBG_DEBUG("directory %s is already owned by uid %u\n",
1025 (unsigned int)fsp
->fsp_name
->st
.st_ex_uid
);
1026 return NT_STATUS_OK
;
1030 ret
= SMB_VFS_FCHOWN(fsp
,
1031 parent_fsp
->fsp_name
->st
.st_ex_uid
,
1035 status
= map_nt_error_from_unix(errno
);
1036 DBG_ERR("failed to chown "
1037 "directory %s to parent directory uid %u. "
1040 (unsigned int)parent_fsp
->fsp_name
->st
.st_ex_uid
,
1045 DBG_DEBUG("changed ownership of new "
1046 "directory %s to parent directory uid %u.\n",
1048 (unsigned int)parent_fsp
->fsp_name
->st
.st_ex_uid
);
1050 /* Ensure the uid entry is updated. */
1051 fsp
->fsp_name
->st
.st_ex_uid
= parent_fsp
->fsp_name
->st
.st_ex_uid
;
1053 return NT_STATUS_OK
;
1056 /****************************************************************************
1057 Open a file - returning a guaranteed ATOMIC indication of if the
1058 file was created or not.
1059 ****************************************************************************/
1061 static NTSTATUS
fd_open_atomic(struct files_struct
*dirfsp
,
1062 struct smb_filename
*smb_fname
,
1064 const struct vfs_open_how
*_how
,
1067 struct vfs_open_how how
= *_how
;
1068 NTSTATUS status
= NT_STATUS_UNSUCCESSFUL
;
1069 NTSTATUS retry_status
;
1070 bool file_existed
= VALID_STAT(smb_fname
->st
);
1072 if (!(how
.flags
& O_CREAT
)) {
1074 * We're not creating the file, just pass through.
1076 status
= fd_openat(dirfsp
, smb_fname
, fsp
, &how
);
1077 *file_created
= false;
1081 if (how
.flags
& O_EXCL
) {
1083 * Fail if already exists, just pass through.
1085 status
= fd_openat(dirfsp
, smb_fname
, fsp
, &how
);
1088 * Here we've opened with O_CREAT|O_EXCL. If that went
1089 * NT_STATUS_OK, we *know* we created this file.
1091 *file_created
= NT_STATUS_IS_OK(status
);
1097 * Now it gets tricky. We have O_CREAT, but not O_EXCL.
1098 * To know absolutely if we created the file or not,
1099 * we can never call O_CREAT without O_EXCL. So if
1100 * we think the file existed, try without O_CREAT|O_EXCL.
1101 * If we think the file didn't exist, try with
1104 * The big problem here is dangling symlinks. Opening
1105 * without O_NOFOLLOW means both bad symlink
1106 * and missing path return -1, ENOENT from open(). As POSIX
1107 * is pathname based it's not possible to tell
1108 * the difference between these two cases in a
1109 * non-racy way, so change to try only two attempts before
1112 * We don't have this problem for the O_NOFOLLOW
1113 * case as it just returns NT_STATUS_OBJECT_PATH_NOT_FOUND
1114 * mapped from the ELOOP POSIX error.
1118 how
.flags
= _how
->flags
& ~(O_CREAT
);
1119 retry_status
= NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1121 how
.flags
= _how
->flags
| O_EXCL
;
1122 retry_status
= NT_STATUS_OBJECT_NAME_COLLISION
;
1125 status
= fd_openat(dirfsp
, smb_fname
, fsp
, &how
);
1126 if (NT_STATUS_IS_OK(status
)) {
1127 *file_created
= !file_existed
;
1128 return NT_STATUS_OK
;
1130 if (NT_STATUS_EQUAL(status
, retry_status
)) {
1132 file_existed
= !file_existed
;
1134 DBG_DEBUG("File %s %s. Retry.\n",
1136 file_existed
? "existed" : "did not exist");
1139 how
.flags
= _how
->flags
& ~(O_CREAT
);
1141 how
.flags
= _how
->flags
| O_EXCL
;
1144 status
= fd_openat(dirfsp
, smb_fname
, fsp
, &how
);
1147 *file_created
= (NT_STATUS_IS_OK(status
) && !file_existed
);
1151 static NTSTATUS
reopen_from_fsp(struct files_struct
*dirfsp
,
1152 struct smb_filename
*smb_fname
,
1153 struct files_struct
*fsp
,
1154 const struct vfs_open_how
*how
,
1155 bool *p_file_created
)
1160 if (fsp
->fsp_flags
.have_proc_fds
&&
1161 ((old_fd
= fsp_get_pathref_fd(fsp
)) != -1)) {
1163 struct sys_proc_fd_path_buf buf
;
1164 struct smb_filename proc_fname
= {
1165 .base_name
= sys_proc_fd_path(old_fd
, &buf
),
1167 mode_t mode
= fsp
->fsp_name
->st
.st_ex_mode
;
1170 SMB_ASSERT(fsp
->fsp_flags
.is_pathref
);
1172 if (S_ISLNK(mode
)) {
1173 return NT_STATUS_STOPPED_ON_SYMLINK
;
1175 if (!(S_ISREG(mode
) || S_ISDIR(mode
))) {
1176 return NT_STATUS_IO_REPARSE_TAG_NOT_HANDLED
;
1179 fsp
->fsp_flags
.is_pathref
= false;
1181 new_fd
= SMB_VFS_OPENAT(fsp
->conn
,
1187 #if defined(HAVE_FSTATFS) && defined(HAVE_LINUX_MAGIC_H)
1188 if (S_ISDIR(fsp
->fsp_name
->st
.st_ex_mode
) &&
1189 (errno
== ENOENT
)) {
1190 struct statfs sbuf
= {};
1191 int ret
= fstatfs(old_fd
, &sbuf
);
1193 DBG_ERR("fstatfs failed: %s\n",
1195 } else if (sbuf
.f_type
== AUTOFS_SUPER_MAGIC
) {
1197 * When reopening an as-yet
1198 * unmounted autofs mount
1199 * point we get ENOENT. We
1200 * have to retry pathbased.
1202 goto namebased_open
;
1204 /* restore ENOENT if changed in the meantime */
1208 status
= map_nt_error_from_unix(errno
);
1213 status
= fd_close(fsp
);
1214 if (!NT_STATUS_IS_OK(status
)) {
1218 fsp_set_fd(fsp
, new_fd
);
1219 return NT_STATUS_OK
;
1222 #if defined(HAVE_FSTATFS) && defined(HAVE_LINUX_MAGIC_H)
1226 * Close the existing pathref fd and set the fsp flag
1227 * is_pathref to false so we get a "normal" fd this time.
1229 status
= fd_close(fsp
);
1230 if (!NT_STATUS_IS_OK(status
)) {
1234 fsp
->fsp_flags
.is_pathref
= false;
1236 status
= fd_open_atomic(dirfsp
, smb_fname
, fsp
, how
, p_file_created
);
1240 /****************************************************************************
1242 ****************************************************************************/
1244 static NTSTATUS
open_file(
1245 struct smb_request
*req
,
1246 struct files_struct
*dirfsp
,
1247 struct smb_filename
*smb_fname_atname
,
1249 const struct vfs_open_how
*_how
,
1250 uint32_t access_mask
, /* client requested access mask. */
1251 uint32_t open_access_mask
, /* what we're actually using in the open. */
1252 uint32_t private_flags
,
1253 bool *p_file_created
)
1255 connection_struct
*conn
= fsp
->conn
;
1256 struct smb_filename
*smb_fname
= fsp
->fsp_name
;
1257 struct vfs_open_how how
= *_how
;
1258 NTSTATUS status
= NT_STATUS_OK
;
1259 bool file_existed
= VALID_STAT(fsp
->fsp_name
->st
);
1260 const uint32_t need_fd_mask
=
1265 SEC_FLAG_SYSTEM_SECURITY
;
1266 bool creating
= !file_existed
&& (how
.flags
& O_CREAT
);
1267 bool open_fd
= false;
1268 bool posix_open
= (fsp
->posix_flags
& FSP_POSIX_FLAGS_OPEN
);
1271 * Catch early an attempt to open an existing
1272 * directory as a file.
1274 if (file_existed
&& S_ISDIR(fsp
->fsp_name
->st
.st_ex_mode
)) {
1275 return NT_STATUS_FILE_IS_A_DIRECTORY
;
1279 * This little piece of insanity is inspired by the
1280 * fact that an NT client can open a file for O_RDONLY,
1281 * but set the create disposition to FILE_EXISTS_TRUNCATE.
1282 * If the client *can* write to the file, then it expects to
1283 * truncate the file, even though it is opening for readonly.
1284 * Quicken uses this stupid trick in backup file creation...
1285 * Thanks *greatly* to "David W. Chapman Jr." <dwcjr@inethouston.net>
1286 * for helping track this one down. It didn't bite us in 2.0.x
1287 * as we always opened files read-write in that release. JRA.
1290 if (((how
.flags
& O_ACCMODE
) == O_RDONLY
) && (how
.flags
& O_TRUNC
)) {
1291 DBG_DEBUG("truncate requested on read-only open for file %s\n",
1292 smb_fname_str_dbg(smb_fname
));
1293 how
.flags
= (how
.flags
& ~O_ACCMODE
) | O_RDWR
;
1296 /* Check permissions */
1299 * This code was changed after seeing a client open request
1300 * containing the open mode of (DENY_WRITE/read-only) with
1301 * the 'create if not exist' bit set. The previous code
1302 * would fail to open the file read only on a read-only share
1303 * as it was checking the flags parameter directly against O_RDONLY,
1304 * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
1308 if (!CAN_WRITE(conn
)) {
1309 /* It's a read-only share - fail if we wanted to write. */
1310 if ((how
.flags
& O_ACCMODE
) != O_RDONLY
||
1311 (how
.flags
& O_TRUNC
) || (how
.flags
& O_APPEND
)) {
1312 DEBUG(3,("Permission denied opening %s\n",
1313 smb_fname_str_dbg(smb_fname
)));
1314 return NT_STATUS_ACCESS_DENIED
;
1317 * We don't want to write - but we must make sure that
1318 * O_CREAT doesn't create the file if we have write
1319 * access into the directory.
1321 how
.flags
&= ~(O_CREAT
| O_EXCL
);
1324 if ((open_access_mask
& need_fd_mask
) || creating
||
1325 (how
.flags
& O_TRUNC
)) {
1332 #if defined(O_NONBLOCK) && defined(S_ISFIFO)
1334 * We would block on opening a FIFO with no one else on the
1335 * other end. Do what we used to do and add O_NONBLOCK to the
1339 if (file_existed
&& S_ISFIFO(smb_fname
->st
.st_ex_mode
)) {
1340 how
.flags
|= O_NONBLOCK
;
1345 const char *wild
= smb_fname
->base_name
;
1347 * Don't open files with Microsoft wildcard characters.
1349 if (fsp_is_alternate_stream(fsp
)) {
1351 * wildcard characters are allowed in stream
1352 * names only test the basefilename
1354 wild
= fsp
->base_fsp
->fsp_name
->base_name
;
1357 if (ms_has_wild(wild
)) {
1358 return NT_STATUS_OBJECT_NAME_INVALID
;
1362 /* Can we access this file ? */
1363 if (!fsp_is_alternate_stream(fsp
)) {
1364 /* Only do this check on non-stream open. */
1366 status
= smbd_check_access_rights_fsp(
1372 if (!NT_STATUS_IS_OK(status
)) {
1373 DBG_DEBUG("smbd_check_access_rights_fsp"
1374 " on file %s returned %s\n",
1379 if (!NT_STATUS_IS_OK(status
) &&
1380 !NT_STATUS_EQUAL(status
,
1381 NT_STATUS_OBJECT_NAME_NOT_FOUND
))
1386 if (NT_STATUS_EQUAL(status
,
1387 NT_STATUS_OBJECT_NAME_NOT_FOUND
))
1389 DEBUG(10, ("open_file: "
1390 "file %s vanished since we "
1391 "checked for existence.\n",
1392 smb_fname_str_dbg(smb_fname
)));
1393 file_existed
= false;
1394 SET_STAT_INVALID(fsp
->fsp_name
->st
);
1398 if (!file_existed
) {
1399 if (!(how
.flags
& O_CREAT
)) {
1400 /* File didn't exist and no O_CREAT. */
1401 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1404 status
= check_parent_access_fsp(
1407 if (!NT_STATUS_IS_OK(status
)) {
1408 DBG_DEBUG("check_parent_access_fsp on "
1409 "directory %s for file %s "
1413 smb_fname_str_dbg(smb_fname
),
1421 * Actually do the open - if O_TRUNC is needed handle it
1422 * below under the share mode lock.
1424 how
.flags
&= ~O_TRUNC
;
1425 status
= reopen_from_fsp(dirfsp
,
1430 if (NT_STATUS_EQUAL(status
, NT_STATUS_STOPPED_ON_SYMLINK
)) {
1432 * Non-O_PATH reopen that hit a race
1433 * condition: Someone has put a symlink where
1434 * we used to have a file. Can't happen with
1435 * O_PATH and reopening from /proc/self/fd/ or
1438 status
= NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1440 if (!NT_STATUS_IS_OK(status
)) {
1441 DBG_NOTICE("Error opening file %s (%s) (in_flags=%d) "
1443 smb_fname_str_dbg(smb_fname
),
1450 if (how
.flags
& O_NONBLOCK
) {
1452 * GPFS can return ETIMEDOUT for pread on
1453 * nonblocking file descriptors when files
1454 * migrated to tape need to be recalled. I
1455 * could imagine this happens elsewhere
1456 * too. With blocking file descriptors this
1459 ret
= vfs_set_blocking(fsp
, true);
1461 status
= map_nt_error_from_unix(errno
);
1462 DBG_WARNING("Could not set fd to blocking: "
1463 "%s\n", strerror(errno
));
1469 if (*p_file_created
) {
1470 /* We created this file. */
1472 bool need_re_stat
= false;
1473 /* Do all inheritance work after we've
1474 done a successful fstat call and filled
1475 in the stat struct in fsp->fsp_name. */
1477 /* Inherit the ACL if required */
1478 if (lp_inherit_permissions(SNUM(conn
))) {
1479 inherit_access_posix_acl(conn
,
1483 need_re_stat
= true;
1486 /* Change the owner if required. */
1487 if (lp_inherit_owner(SNUM(conn
)) != INHERIT_OWNER_NO
) {
1488 change_file_owner_to_parent_fsp(dirfsp
, fsp
);
1489 need_re_stat
= true;
1493 status
= vfs_stat_fsp(fsp
);
1495 * If we have an fd, this stat should succeed.
1497 if (!NT_STATUS_IS_OK(status
)) {
1498 DBG_ERR("Error doing fstat on open "
1500 smb_fname_str_dbg(smb_fname
),
1507 notify_fname(conn
, NOTIFY_ACTION_ADDED
,
1508 FILE_NOTIFY_CHANGE_FILE_NAME
,
1509 smb_fname
->base_name
);
1512 if (!file_existed
) {
1513 /* File must exist for a stat open. */
1514 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1517 if (S_ISLNK(smb_fname
->st
.st_ex_mode
) &&
1521 * Don't allow stat opens on symlinks directly unless
1522 * it's a POSIX open. Match the return code from
1523 * openat_pathref_fsp().
1525 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1528 if (!fsp
->fsp_flags
.is_pathref
) {
1530 * There is only one legit case where end up here:
1531 * openat_pathref_fsp() failed to open a symlink, so the
1532 * fsp was created by fsp_new() which doesn't set
1533 * is_pathref. Other than that, we should always have a
1534 * pathref fsp at this point. The subsequent checks
1537 if (!(smb_fname
->flags
& SMB_FILENAME_POSIX_PATH
)) {
1538 DBG_ERR("[%s] is not a POSIX pathname\n",
1539 smb_fname_str_dbg(smb_fname
));
1540 return NT_STATUS_INTERNAL_ERROR
;
1542 if (!S_ISLNK(smb_fname
->st
.st_ex_mode
)) {
1543 DBG_ERR("[%s] is not a symlink\n",
1544 smb_fname_str_dbg(smb_fname
));
1545 return NT_STATUS_INTERNAL_ERROR
;
1547 if (fsp_get_pathref_fd(fsp
) != -1) {
1548 DBG_ERR("fd for [%s] is not -1: fd [%d]\n",
1549 smb_fname_str_dbg(smb_fname
),
1550 fsp_get_pathref_fd(fsp
));
1551 return NT_STATUS_INTERNAL_ERROR
;
1556 * Access to streams is checked by checking the basefile and
1557 * that has already been checked by check_base_file_access()
1558 * in create_file_unixpath().
1560 if (!fsp_is_alternate_stream(fsp
)) {
1561 status
= smbd_check_access_rights_fsp(dirfsp
,
1566 if (NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
) &&
1568 S_ISLNK(smb_fname
->st
.st_ex_mode
)) {
1569 /* This is a POSIX stat open for delete
1570 * or rename on a symlink that points
1571 * nowhere. Allow. */
1572 DEBUG(10,("open_file: allowing POSIX "
1573 "open on bad symlink %s\n",
1574 smb_fname_str_dbg(smb_fname
)));
1575 status
= NT_STATUS_OK
;
1578 if (!NT_STATUS_IS_OK(status
)) {
1579 DBG_DEBUG("smbd_check_access_rights_fsp on file "
1588 fsp
->file_id
= vfs_file_id_from_sbuf(conn
, &smb_fname
->st
);
1589 fsp
->vuid
= req
? req
->vuid
: UID_FIELD_INVALID
;
1590 fsp
->file_pid
= req
? req
->smbpid
: 0;
1591 fsp
->fsp_flags
.can_lock
= true;
1592 fsp
->fsp_flags
.can_read
= ((access_mask
& FILE_READ_DATA
) != 0);
1593 fsp
->fsp_flags
.can_write
=
1595 ((access_mask
& (FILE_WRITE_DATA
| FILE_APPEND_DATA
)) != 0);
1596 if (fsp
->fsp_name
->twrp
!= 0) {
1597 fsp
->fsp_flags
.can_write
= false;
1599 fsp
->print_file
= NULL
;
1600 fsp
->fsp_flags
.modified
= false;
1601 fsp
->sent_oplock_break
= NO_BREAK_SENT
;
1602 fsp
->fsp_flags
.is_directory
= false;
1603 if (is_in_path(smb_fname
->base_name
,
1604 conn
->aio_write_behind_list
,
1605 posix_open
? true : conn
->case_sensitive
)) {
1606 fsp
->fsp_flags
.aio_write_behind
= true;
1609 DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
1610 conn
->session_info
->unix_info
->unix_name
,
1611 smb_fname_str_dbg(smb_fname
),
1612 BOOLSTR(fsp
->fsp_flags
.can_read
),
1613 BOOLSTR(fsp
->fsp_flags
.can_write
),
1614 conn
->num_files_open
));
1616 return NT_STATUS_OK
;
1619 static bool mask_conflict(
1620 uint32_t new_access
,
1621 uint32_t existing_access
,
1622 uint32_t access_mask
,
1623 uint32_t new_sharemode
,
1624 uint32_t existing_sharemode
,
1625 uint32_t sharemode_mask
)
1627 bool want_access
= (new_access
& access_mask
);
1628 bool allow_existing
= (existing_sharemode
& sharemode_mask
);
1629 bool have_access
= (existing_access
& access_mask
);
1630 bool allow_new
= (new_sharemode
& sharemode_mask
);
1632 if (want_access
&& !allow_existing
) {
1633 DBG_DEBUG("Access request 0x%"PRIx32
"/0x%"PRIx32
" conflicts "
1634 "with existing sharemode 0x%"PRIx32
"/0x%"PRIx32
"\n",
1641 if (have_access
&& !allow_new
) {
1642 DBG_DEBUG("Sharemode request 0x%"PRIx32
"/0x%"PRIx32
" conflicts "
1643 "with existing access 0x%"PRIx32
"/0x%"PRIx32
"\n",
1653 /****************************************************************************
1654 Check if we can open a file with a share mode.
1655 Returns True if conflict, False if not.
1656 ****************************************************************************/
1658 static const uint32_t conflicting_access
=
1665 static bool share_conflict(uint32_t e_access_mask
,
1666 uint32_t e_share_access
,
1667 uint32_t access_mask
,
1668 uint32_t share_access
)
1672 DBG_DEBUG("existing access_mask = 0x%"PRIx32
", "
1673 "existing share access = 0x%"PRIx32
", "
1674 "access_mask = 0x%"PRIx32
", "
1675 "share_access = 0x%"PRIx32
"\n",
1681 if ((e_access_mask
& conflicting_access
) == 0) {
1682 DBG_DEBUG("No conflict due to "
1683 "existing access_mask = 0x%"PRIx32
"\n",
1687 if ((access_mask
& conflicting_access
) == 0) {
1688 DBG_DEBUG("No conflict due to access_mask = 0x%"PRIx32
"\n",
1693 conflict
= mask_conflict(
1694 access_mask
, e_access_mask
, FILE_WRITE_DATA
| FILE_APPEND_DATA
,
1695 share_access
, e_share_access
, FILE_SHARE_WRITE
);
1696 conflict
|= mask_conflict(
1697 access_mask
, e_access_mask
, FILE_READ_DATA
| FILE_EXECUTE
,
1698 share_access
, e_share_access
, FILE_SHARE_READ
);
1699 conflict
|= mask_conflict(
1700 access_mask
, e_access_mask
, DELETE_ACCESS
,
1701 share_access
, e_share_access
, FILE_SHARE_DELETE
);
1703 DBG_DEBUG("conflict=%s\n", conflict
? "true" : "false");
1707 #if defined(DEVELOPER)
1709 struct validate_my_share_entries_state
{
1710 struct smbd_server_connection
*sconn
;
1712 struct server_id self
;
1715 static bool validate_my_share_entries_fn(
1716 struct share_mode_entry
*e
,
1720 struct validate_my_share_entries_state
*state
= private_data
;
1723 if (!server_id_equal(&state
->self
, &e
->pid
)) {
1727 if (e
->op_mid
== 0) {
1728 /* INTERNAL_OPEN_ONLY */
1732 fsp
= file_find_dif(state
->sconn
, state
->fid
, e
->share_file_id
);
1734 DBG_ERR("PANIC : %s\n",
1735 share_mode_str(talloc_tos(), 0, &state
->fid
, e
));
1736 smb_panic("validate_my_share_entries: Cannot match a "
1737 "share entry with an open file\n");
1740 if (((uint16_t)fsp
->oplock_type
) != e
->op_type
) {
1749 DBG_ERR("validate_my_share_entries: PANIC : %s\n",
1750 share_mode_str(talloc_tos(), 0, &state
->fid
, e
));
1751 str
= talloc_asprintf(talloc_tos(),
1752 "validate_my_share_entries: "
1753 "file %s, oplock_type = 0x%x, op_type = 0x%x\n",
1754 fsp
->fsp_name
->base_name
,
1755 (unsigned int)fsp
->oplock_type
,
1756 (unsigned int)e
->op_type
);
1765 * Allowed access mask for stat opens relevant to oplocks
1767 bool is_oplock_stat_open(uint32_t access_mask
)
1769 const uint32_t stat_open_bits
=
1770 (SYNCHRONIZE_ACCESS
|
1771 FILE_READ_ATTRIBUTES
|
1772 FILE_WRITE_ATTRIBUTES
);
1774 return (((access_mask
& stat_open_bits
) != 0) &&
1775 ((access_mask
& ~stat_open_bits
) == 0));
1779 * Allowed access mask for stat opens relevant to leases
1781 bool is_lease_stat_open(uint32_t access_mask
)
1783 const uint32_t stat_open_bits
=
1784 (SYNCHRONIZE_ACCESS
|
1785 FILE_READ_ATTRIBUTES
|
1786 FILE_WRITE_ATTRIBUTES
|
1787 READ_CONTROL_ACCESS
);
1789 return (((access_mask
& stat_open_bits
) != 0) &&
1790 ((access_mask
& ~stat_open_bits
) == 0));
1793 struct has_delete_on_close_state
{
1797 static bool has_delete_on_close_fn(
1798 struct share_mode_entry
*e
,
1802 struct has_delete_on_close_state
*state
= private_data
;
1803 state
->ret
= !share_entry_stale_pid(e
);
1807 static bool has_delete_on_close(struct share_mode_lock
*lck
,
1810 struct has_delete_on_close_state state
= { .ret
= false };
1813 if (!is_delete_on_close_set(lck
, name_hash
)) {
1817 ok
= share_mode_forall_entries(lck
, has_delete_on_close_fn
, &state
);
1819 DBG_DEBUG("share_mode_forall_entries failed\n");
1825 static void share_mode_flags_restrict(
1826 struct share_mode_lock
*lck
,
1827 uint32_t access_mask
,
1828 uint32_t share_mode
,
1829 uint32_t lease_type
)
1831 uint32_t existing_access_mask
, existing_share_mode
;
1832 uint32_t existing_lease_type
;
1834 share_mode_flags_get(
1836 &existing_access_mask
,
1837 &existing_share_mode
,
1838 &existing_lease_type
);
1840 existing_access_mask
|= access_mask
;
1841 if (access_mask
& conflicting_access
) {
1842 existing_share_mode
&= share_mode
;
1844 existing_lease_type
|= lease_type
;
1846 share_mode_flags_set(
1848 existing_access_mask
,
1849 existing_share_mode
,
1850 existing_lease_type
,
1854 /****************************************************************************
1855 Deal with share modes
1856 Invariant: Share mode must be locked on entry and exit.
1857 Returns -1 on error, or number of share modes on success (may be zero).
1858 ****************************************************************************/
1860 struct open_mode_check_state
{
1862 uint32_t access_mask
;
1863 uint32_t share_access
;
1864 uint32_t lease_type
;
1867 static bool open_mode_check_fn(
1868 struct share_mode_entry
*e
,
1872 struct open_mode_check_state
*state
= private_data
;
1873 bool disconnected
, stale
;
1874 uint32_t access_mask
, share_access
, lease_type
;
1876 disconnected
= server_id_is_disconnected(&e
->pid
);
1881 access_mask
= state
->access_mask
| e
->access_mask
;
1882 share_access
= state
->share_access
;
1883 if (e
->access_mask
& conflicting_access
) {
1884 share_access
&= e
->share_access
;
1886 lease_type
= state
->lease_type
| get_lease_type(e
, state
->fid
);
1888 if ((access_mask
== state
->access_mask
) &&
1889 (share_access
== state
->share_access
) &&
1890 (lease_type
== state
->lease_type
)) {
1894 stale
= share_entry_stale_pid(e
);
1899 state
->access_mask
= access_mask
;
1900 state
->share_access
= share_access
;
1901 state
->lease_type
= lease_type
;
1906 static NTSTATUS
open_mode_check(connection_struct
*conn
,
1908 struct share_mode_lock
*lck
,
1909 uint32_t access_mask
,
1910 uint32_t share_access
)
1912 struct open_mode_check_state state
;
1914 bool modified
= false;
1916 if (is_oplock_stat_open(access_mask
)) {
1917 /* Stat open that doesn't trigger oplock breaks or share mode
1918 * checks... ! JRA. */
1919 return NT_STATUS_OK
;
1923 * Check if the share modes will give us access.
1926 #if defined(DEVELOPER)
1928 struct validate_my_share_entries_state validate_state
= {
1929 .sconn
= conn
->sconn
,
1931 .self
= messaging_server_id(conn
->sconn
->msg_ctx
),
1933 ok
= share_mode_forall_entries(
1934 lck
, validate_my_share_entries_fn
, &validate_state
);
1939 share_mode_flags_get(
1940 lck
, &state
.access_mask
, &state
.share_access
, NULL
);
1942 conflict
= share_conflict(
1948 DBG_DEBUG("No conflict due to share_mode_flags access\n");
1949 return NT_STATUS_OK
;
1952 state
= (struct open_mode_check_state
) {
1954 .share_access
= (FILE_SHARE_READ
|
1960 * Walk the share mode array to recalculate d->flags
1963 ok
= share_mode_forall_entries(lck
, open_mode_check_fn
, &state
);
1965 DBG_DEBUG("share_mode_forall_entries failed\n");
1966 return NT_STATUS_INTERNAL_ERROR
;
1969 share_mode_flags_set(
1977 * We only end up here if we had a sharing violation
1978 * from d->flags and have recalculated it.
1980 return NT_STATUS_SHARING_VIOLATION
;
1983 conflict
= share_conflict(
1989 DBG_DEBUG("No conflict due to share_mode_flags access\n");
1990 return NT_STATUS_OK
;
1993 return NT_STATUS_SHARING_VIOLATION
;
1997 * Send a break message to the oplock holder and delay the open for
2001 NTSTATUS
send_break_message(struct messaging_context
*msg_ctx
,
2002 const struct file_id
*id
,
2003 const struct share_mode_entry
*exclusive
,
2006 struct oplock_break_message msg
= {
2008 .share_file_id
= exclusive
->share_file_id
,
2009 .break_to
= break_to
,
2011 enum ndr_err_code ndr_err
;
2013 DATA_BLOB blob
= {.data
= msgbuf
, .length
= sizeof(msgbuf
)};
2017 struct server_id_buf buf
;
2018 DBG_DEBUG("Sending break message to %s\n",
2019 server_id_str_buf(exclusive
->pid
, &buf
));
2020 NDR_PRINT_DEBUG(oplock_break_message
, &msg
);
2023 ndr_err
= ndr_push_struct_into_fixed_blob(
2026 (ndr_push_flags_fn_t
)ndr_push_oplock_break_message
);
2027 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
2028 DBG_WARNING("ndr_push_oplock_break_message failed: %s\n",
2029 ndr_errstr(ndr_err
));
2030 return ndr_map_error2ntstatus(ndr_err
);
2033 status
= messaging_send(msg_ctx
,
2035 MSG_SMB_BREAK_REQUEST
,
2037 if (!NT_STATUS_IS_OK(status
)) {
2038 DEBUG(3, ("Could not send oplock break message: %s\n",
2039 nt_errstr(status
)));
2045 struct validate_oplock_types_state
{
2051 uint32_t num_non_stat_opens
;
2054 static bool validate_oplock_types_fn(
2055 struct share_mode_entry
*e
,
2059 struct validate_oplock_types_state
*state
= private_data
;
2061 if (e
->op_mid
== 0) {
2062 /* INTERNAL_OPEN_ONLY */
2066 if (e
->op_type
== NO_OPLOCK
&& is_oplock_stat_open(e
->access_mask
)) {
2068 * We ignore stat opens in the table - they always
2069 * have NO_OPLOCK and never get or cause breaks. JRA.
2074 state
->num_non_stat_opens
+= 1;
2076 if (BATCH_OPLOCK_TYPE(e
->op_type
)) {
2077 /* batch - can only be one. */
2078 if (share_entry_stale_pid(e
)) {
2079 DBG_DEBUG("Found stale batch oplock\n");
2082 if (state
->ex_or_batch
||
2086 DBG_ERR("Bad batch oplock entry\n");
2087 state
->valid
= false;
2090 state
->batch
= true;
2093 if (EXCLUSIVE_OPLOCK_TYPE(e
->op_type
)) {
2094 if (share_entry_stale_pid(e
)) {
2095 DBG_DEBUG("Found stale duplicate oplock\n");
2098 /* Exclusive or batch - can only be one. */
2099 if (state
->ex_or_batch
||
2102 DBG_ERR("Bad exclusive or batch oplock entry\n");
2103 state
->valid
= false;
2106 state
->ex_or_batch
= true;
2109 if (LEVEL_II_OPLOCK_TYPE(e
->op_type
)) {
2110 if (state
->batch
|| state
->ex_or_batch
) {
2111 if (share_entry_stale_pid(e
)) {
2112 DBG_DEBUG("Found stale LevelII oplock\n");
2115 DBG_DEBUG("Bad levelII oplock entry\n");
2116 state
->valid
= false;
2119 state
->level2
= true;
2122 if (e
->op_type
== NO_OPLOCK
) {
2123 if (state
->batch
|| state
->ex_or_batch
) {
2124 if (share_entry_stale_pid(e
)) {
2125 DBG_DEBUG("Found stale NO_OPLOCK entry\n");
2128 DBG_ERR("Bad no oplock entry\n");
2129 state
->valid
= false;
2132 state
->no_oplock
= true;
2139 * Do internal consistency checks on the share mode for a file.
2142 static bool validate_oplock_types(struct share_mode_lock
*lck
)
2144 struct validate_oplock_types_state state
= { .valid
= true };
2145 static bool skip_validation
;
2149 if (skip_validation
) {
2153 validate
= lp_parm_bool(-1, "smbd", "validate_oplock_types", false);
2155 DBG_DEBUG("smbd:validate_oplock_types not set to yes\n");
2156 skip_validation
= true;
2160 ok
= share_mode_forall_entries(lck
, validate_oplock_types_fn
, &state
);
2162 DBG_DEBUG("share_mode_forall_entries failed\n");
2166 DBG_DEBUG("Got invalid oplock configuration\n");
2170 if ((state
.batch
|| state
.ex_or_batch
) &&
2171 (state
.num_non_stat_opens
!= 1)) {
2172 DBG_WARNING("got batch (%d) or ex (%d) non-exclusively "
2175 (int)state
.ex_or_batch
,
2176 state
.num_non_stat_opens
);
2183 static bool is_same_lease(const files_struct
*fsp
,
2184 const struct share_mode_entry
*e
,
2185 const struct smb2_lease
*lease
)
2187 if (e
->op_type
!= LEASE_OPLOCK
) {
2190 if (lease
== NULL
) {
2194 return smb2_lease_equal(fsp_client_guid(fsp
),
2200 static bool file_has_brlocks(files_struct
*fsp
)
2202 struct byte_range_lock
*br_lck
;
2204 br_lck
= brl_get_locks_readonly(fsp
);
2208 return (brl_num_locks(br_lck
) > 0);
2211 struct fsp_lease
*find_fsp_lease(struct files_struct
*new_fsp
,
2212 const struct smb2_lease_key
*key
,
2213 uint32_t current_state
,
2214 uint16_t lease_version
,
2215 uint16_t lease_epoch
)
2217 struct files_struct
*fsp
;
2220 * TODO: Measure how expensive this loop is with thousands of open
2224 for (fsp
= file_find_di_first(new_fsp
->conn
->sconn
, new_fsp
->file_id
, true);
2226 fsp
= file_find_di_next(fsp
, true)) {
2228 if (fsp
== new_fsp
) {
2231 if (fsp
->oplock_type
!= LEASE_OPLOCK
) {
2234 if (smb2_lease_key_equal(&fsp
->lease
->lease
.lease_key
, key
)) {
2235 fsp
->lease
->ref_count
+= 1;
2240 /* Not found - must be leased in another smbd. */
2241 new_fsp
->lease
= talloc_zero(new_fsp
->conn
->sconn
, struct fsp_lease
);
2242 if (new_fsp
->lease
== NULL
) {
2245 new_fsp
->lease
->ref_count
= 1;
2246 new_fsp
->lease
->sconn
= new_fsp
->conn
->sconn
;
2247 new_fsp
->lease
->lease
.lease_key
= *key
;
2248 new_fsp
->lease
->lease
.lease_state
= current_state
;
2250 * We internally treat all leases as V2 and update
2251 * the epoch, but when sending breaks it matters if
2252 * the requesting lease was v1 or v2.
2254 new_fsp
->lease
->lease
.lease_version
= lease_version
;
2255 new_fsp
->lease
->lease
.lease_epoch
= lease_epoch
;
2256 return new_fsp
->lease
;
2259 static NTSTATUS
try_lease_upgrade(struct files_struct
*fsp
,
2260 struct share_mode_lock
*lck
,
2261 const struct GUID
*client_guid
,
2262 const struct smb2_lease
*lease
,
2266 uint32_t current_state
, breaking_to_requested
, breaking_to_required
;
2268 uint16_t lease_version
, epoch
;
2269 uint32_t existing
, requested
;
2272 status
= leases_db_get(
2278 &breaking_to_requested
,
2279 &breaking_to_required
,
2282 if (!NT_STATUS_IS_OK(status
)) {
2286 fsp
->lease
= find_fsp_lease(
2292 if (fsp
->lease
== NULL
) {
2293 DEBUG(1, ("Did not find existing lease for file %s\n",
2295 return NT_STATUS_NO_MEMORY
;
2299 * Upgrade only if the requested lease is a strict upgrade.
2301 existing
= current_state
;
2302 requested
= lease
->lease_state
;
2305 * Tricky: This test makes sure that "requested" is a
2306 * strict bitwise superset of "existing".
2308 do_upgrade
= ((existing
& requested
) == existing
);
2311 * Upgrade only if there's a change.
2313 do_upgrade
&= (granted
!= existing
);
2316 * Upgrade only if other leases don't prevent what was asked
2319 do_upgrade
&= (granted
== requested
);
2322 * only upgrade if we are not in breaking state
2324 do_upgrade
&= !breaking
;
2326 DEBUG(10, ("existing=%"PRIu32
", requested=%"PRIu32
", "
2327 "granted=%"PRIu32
", do_upgrade=%d\n",
2328 existing
, requested
, granted
, (int)do_upgrade
));
2331 NTSTATUS set_status
;
2333 current_state
= granted
;
2336 set_status
= leases_db_set(
2341 breaking_to_requested
,
2342 breaking_to_required
,
2346 if (!NT_STATUS_IS_OK(set_status
)) {
2347 DBG_DEBUG("leases_db_set failed: %s\n",
2348 nt_errstr(set_status
));
2353 fsp_lease_update(fsp
);
2355 return NT_STATUS_OK
;
2358 static NTSTATUS
grant_new_fsp_lease(struct files_struct
*fsp
,
2359 struct share_mode_lock
*lck
,
2360 const struct GUID
*client_guid
,
2361 const struct smb2_lease
*lease
,
2366 fsp
->lease
= talloc_zero(fsp
->conn
->sconn
, struct fsp_lease
);
2367 if (fsp
->lease
== NULL
) {
2368 return NT_STATUS_INSUFFICIENT_RESOURCES
;
2370 fsp
->lease
->ref_count
= 1;
2371 fsp
->lease
->sconn
= fsp
->conn
->sconn
;
2372 fsp
->lease
->lease
.lease_version
= lease
->lease_version
;
2373 fsp
->lease
->lease
.lease_key
= lease
->lease_key
;
2374 fsp
->lease
->lease
.lease_state
= granted
;
2375 fsp
->lease
->lease
.lease_epoch
= lease
->lease_epoch
+ 1;
2377 status
= leases_db_add(client_guid
,
2380 fsp
->lease
->lease
.lease_state
,
2381 fsp
->lease
->lease
.lease_version
,
2382 fsp
->lease
->lease
.lease_epoch
,
2383 fsp
->conn
->connectpath
,
2384 fsp
->fsp_name
->base_name
,
2385 fsp
->fsp_name
->stream_name
);
2386 if (!NT_STATUS_IS_OK(status
)) {
2387 DEBUG(10, ("%s: leases_db_add failed: %s\n", __func__
,
2388 nt_errstr(status
)));
2389 TALLOC_FREE(fsp
->lease
);
2390 return NT_STATUS_INSUFFICIENT_RESOURCES
;
2394 * We used to set lck->data->modified=true here without
2395 * actually modifying lck->data, triggering a needless
2396 * writeback of lck->data.
2398 * Apart from that writeback, setting modified=true has the
2399 * effect of triggering all waiters for this file to
2400 * retry. This only makes sense if any blocking condition
2401 * (i.e. waiting for a lease to be downgraded or removed) is
2402 * gone. This routine here only adds a lease, so it will never
2403 * free up resources that blocked waiters can now claim. So
2404 * that second effect also does not matter in this
2405 * routine. Thus setting lck->data->modified=true does not
2406 * need to be done here.
2409 return NT_STATUS_OK
;
2412 static NTSTATUS
grant_fsp_lease(struct files_struct
*fsp
,
2413 struct share_mode_lock
*lck
,
2414 const struct smb2_lease
*lease
,
2417 const struct GUID
*client_guid
= fsp_client_guid(fsp
);
2420 status
= try_lease_upgrade(fsp
, lck
, client_guid
, lease
, granted
);
2422 if (NT_STATUS_EQUAL(status
, NT_STATUS_NOT_FOUND
)) {
2423 status
= grant_new_fsp_lease(
2424 fsp
, lck
, client_guid
, lease
, granted
);
2430 static int map_lease_type_to_oplock(uint32_t lease_type
)
2432 int result
= NO_OPLOCK
;
2434 switch (lease_type
) {
2435 case SMB2_LEASE_READ
|SMB2_LEASE_WRITE
|SMB2_LEASE_HANDLE
:
2436 result
= BATCH_OPLOCK
|EXCLUSIVE_OPLOCK
;
2438 case SMB2_LEASE_READ
|SMB2_LEASE_WRITE
:
2439 result
= EXCLUSIVE_OPLOCK
;
2441 case SMB2_LEASE_READ
|SMB2_LEASE_HANDLE
:
2442 case SMB2_LEASE_READ
:
2443 result
= LEVEL_II_OPLOCK
;
2450 struct delay_for_oplock_state
{
2451 struct files_struct
*fsp
;
2452 const struct smb2_lease
*lease
;
2453 bool will_overwrite
;
2454 uint32_t delay_mask
;
2455 bool first_open_attempt
;
2456 bool got_handle_lease
;
2458 bool have_other_lease
;
2459 uint32_t total_lease_types
;
2463 static bool delay_for_oplock_fn(
2464 struct share_mode_entry
*e
,
2468 struct delay_for_oplock_state
*state
= private_data
;
2469 struct files_struct
*fsp
= state
->fsp
;
2470 const struct smb2_lease
*lease
= state
->lease
;
2471 bool e_is_lease
= (e
->op_type
== LEASE_OPLOCK
);
2472 uint32_t e_lease_type
= SMB2_LEASE_NONE
;
2474 bool lease_is_breaking
= false;
2479 if (lease
!= NULL
) {
2480 bool our_lease
= is_same_lease(fsp
, e
, lease
);
2482 DBG_DEBUG("Ignoring our own lease\n");
2487 status
= leases_db_get(
2491 &e_lease_type
, /* current_state */
2493 NULL
, /* breaking_to_requested */
2494 NULL
, /* breaking_to_required */
2495 NULL
, /* lease_version */
2499 * leases_db_get() can return NT_STATUS_NOT_FOUND
2500 * if the share_mode_entry e is stale and the
2501 * lease record was already removed. In this case return
2502 * false so the traverse continues.
2505 if (NT_STATUS_EQUAL(status
, NT_STATUS_NOT_FOUND
) &&
2506 share_entry_stale_pid(e
))
2508 struct GUID_txt_buf guid_strbuf
;
2509 struct file_id_buf file_id_strbuf
;
2510 DBG_DEBUG("leases_db_get for client_guid [%s] "
2511 "lease_key [%"PRIu64
"/%"PRIu64
"] "
2512 "file_id [%s] failed for stale "
2513 "share_mode_entry\n",
2514 GUID_buf_string(&e
->client_guid
, &guid_strbuf
),
2515 e
->lease_key
.data
[0],
2516 e
->lease_key
.data
[1],
2517 file_id_str_buf(fsp
->file_id
, &file_id_strbuf
));
2520 if (!NT_STATUS_IS_OK(status
)) {
2521 struct GUID_txt_buf guid_strbuf
;
2522 struct file_id_buf file_id_strbuf
;
2523 DBG_ERR("leases_db_get for client_guid [%s] "
2524 "lease_key [%"PRIu64
"/%"PRIu64
"] "
2525 "file_id [%s] failed: %s\n",
2526 GUID_buf_string(&e
->client_guid
, &guid_strbuf
),
2527 e
->lease_key
.data
[0],
2528 e
->lease_key
.data
[1],
2529 file_id_str_buf(fsp
->file_id
, &file_id_strbuf
),
2531 smb_panic("leases_db_get() failed");
2534 e_lease_type
= get_lease_type(e
, fsp
->file_id
);
2537 if (((e_lease_type
& ~state
->total_lease_types
) != 0) &&
2538 !share_entry_stale_pid(e
))
2540 state
->total_lease_types
|= e_lease_type
;
2543 if (!state
->got_handle_lease
&&
2544 ((e_lease_type
& SMB2_LEASE_HANDLE
) != 0) &&
2545 !share_entry_stale_pid(e
)) {
2546 state
->got_handle_lease
= true;
2549 if (!state
->got_oplock
&&
2550 (e
->op_type
!= LEASE_OPLOCK
) &&
2551 !share_entry_stale_pid(e
)) {
2552 state
->got_oplock
= true;
2555 if (!state
->have_other_lease
&&
2556 !is_same_lease(fsp
, e
, lease
) &&
2557 !share_entry_stale_pid(e
)) {
2558 state
->have_other_lease
= true;
2561 if (e_is_lease
&& is_lease_stat_open(fsp
->access_mask
)) {
2565 break_to
= e_lease_type
& ~state
->delay_mask
;
2567 if (state
->will_overwrite
) {
2568 break_to
&= ~(SMB2_LEASE_HANDLE
|SMB2_LEASE_READ
);
2571 DBG_DEBUG("e_lease_type %u, will_overwrite: %u\n",
2572 (unsigned)e_lease_type
,
2573 (unsigned)state
->will_overwrite
);
2575 if ((e_lease_type
& ~break_to
) == 0) {
2576 if (lease_is_breaking
) {
2577 state
->delay
= true;
2582 if (share_entry_stale_pid(e
)) {
2586 if (state
->will_overwrite
) {
2588 * If we break anyway break to NONE directly.
2589 * Otherwise vfs_set_filelen() will trigger the
2592 break_to
&= ~(SMB2_LEASE_READ
|SMB2_LEASE_WRITE
);
2597 * Oplocks only support breaking to R or NONE.
2599 break_to
&= ~(SMB2_LEASE_HANDLE
|SMB2_LEASE_WRITE
);
2602 DBG_DEBUG("breaking from %d to %d\n",
2606 fsp
->conn
->sconn
->msg_ctx
, &fsp
->file_id
, e
, break_to
);
2607 if (e_lease_type
& state
->delay_mask
) {
2608 state
->delay
= true;
2610 if (lease_is_breaking
&& !state
->first_open_attempt
) {
2611 state
->delay
= true;
2617 static NTSTATUS
delay_for_oplock(files_struct
*fsp
,
2619 const struct smb2_lease
*lease
,
2620 struct share_mode_lock
*lck
,
2621 bool have_sharing_violation
,
2622 uint32_t create_disposition
,
2623 bool first_open_attempt
,
2627 struct delay_for_oplock_state state
= {
2630 .first_open_attempt
= first_open_attempt
,
2637 *poplock_type
= NO_OPLOCK
;
2640 if (fsp
->fsp_flags
.is_directory
) {
2642 * No directory leases yet
2644 SMB_ASSERT(oplock_request
== NO_OPLOCK
);
2645 if (have_sharing_violation
) {
2646 return NT_STATUS_SHARING_VIOLATION
;
2648 return NT_STATUS_OK
;
2651 if (oplock_request
== LEASE_OPLOCK
) {
2652 if (lease
== NULL
) {
2654 * The SMB2 layer should have checked this
2656 return NT_STATUS_INTERNAL_ERROR
;
2659 requested
= lease
->lease_state
;
2661 requested
= map_oplock_to_lease_type(
2662 oplock_request
& ~SAMBA_PRIVATE_OPLOCK_MASK
);
2665 share_mode_flags_get(lck
, NULL
, NULL
, &state
.total_lease_types
);
2667 if (is_oplock_stat_open(fsp
->access_mask
)) {
2671 state
.delay_mask
= have_sharing_violation
?
2672 SMB2_LEASE_HANDLE
: SMB2_LEASE_WRITE
;
2674 switch (create_disposition
) {
2675 case FILE_SUPERSEDE
:
2676 case FILE_OVERWRITE
:
2677 case FILE_OVERWRITE_IF
:
2678 state
.will_overwrite
= true;
2681 state
.will_overwrite
= false;
2685 state
.total_lease_types
= SMB2_LEASE_NONE
;
2686 ok
= share_mode_forall_entries(lck
, delay_for_oplock_fn
, &state
);
2688 return NT_STATUS_INTERNAL_ERROR
;
2692 return NT_STATUS_RETRY
;
2696 if (have_sharing_violation
) {
2697 return NT_STATUS_SHARING_VIOLATION
;
2700 granted
= requested
;
2702 if (oplock_request
== LEASE_OPLOCK
) {
2703 if (lp_kernel_oplocks(SNUM(fsp
->conn
))) {
2704 DEBUG(10, ("No lease granted because kernel oplocks are enabled\n"));
2705 granted
= SMB2_LEASE_NONE
;
2707 if ((granted
& (SMB2_LEASE_READ
|SMB2_LEASE_WRITE
)) == 0) {
2708 DEBUG(10, ("No read or write lease requested\n"));
2709 granted
= SMB2_LEASE_NONE
;
2711 if (granted
== SMB2_LEASE_WRITE
) {
2712 DEBUG(10, ("pure write lease requested\n"));
2713 granted
= SMB2_LEASE_NONE
;
2715 if (granted
== (SMB2_LEASE_WRITE
|SMB2_LEASE_HANDLE
)) {
2716 DEBUG(10, ("write and handle lease requested\n"));
2717 granted
= SMB2_LEASE_NONE
;
2721 if (lp_locking(fsp
->conn
->params
) && file_has_brlocks(fsp
)) {
2722 DBG_DEBUG("file %s has byte range locks\n",
2724 granted
&= ~SMB2_LEASE_READ
;
2727 if (state
.have_other_lease
) {
2729 * Can grant only one writer
2731 granted
&= ~SMB2_LEASE_WRITE
;
2734 if ((granted
& SMB2_LEASE_READ
) && !(granted
& SMB2_LEASE_WRITE
)) {
2736 (global_client_caps
& CAP_LEVEL_II_OPLOCKS
) &&
2737 lp_level2_oplocks(SNUM(fsp
->conn
));
2739 if (!allow_level2
) {
2740 granted
= SMB2_LEASE_NONE
;
2744 if (oplock_request
== LEASE_OPLOCK
) {
2745 if (state
.got_oplock
) {
2746 granted
&= ~SMB2_LEASE_HANDLE
;
2749 oplock_type
= LEASE_OPLOCK
;
2751 if (state
.got_handle_lease
) {
2752 granted
= SMB2_LEASE_NONE
;
2756 * Reflect possible downgrades from:
2757 * - map_lease_type_to_oplock() => "RH" to just LEVEL_II
2759 oplock_type
= map_lease_type_to_oplock(granted
);
2760 granted
= map_oplock_to_lease_type(oplock_type
);
2763 state
.total_lease_types
|= granted
;
2766 uint32_t acc
, sh
, ls
;
2767 share_mode_flags_get(lck
, &acc
, &sh
, &ls
);
2768 ls
= state
.total_lease_types
;
2769 share_mode_flags_set(lck
, acc
, sh
, ls
, NULL
);
2772 DBG_DEBUG("oplock type 0x%x granted (%s%s%s)(0x%x), on file %s, "
2773 "requested 0x%x (%s%s%s)(0x%x) => total (%s%s%s)(0x%x)\n",
2775 granted
& SMB2_LEASE_READ
? "R":"",
2776 granted
& SMB2_LEASE_WRITE
? "W":"",
2777 granted
& SMB2_LEASE_HANDLE
? "H":"",
2781 requested
& SMB2_LEASE_READ
? "R":"",
2782 requested
& SMB2_LEASE_WRITE
? "W":"",
2783 requested
& SMB2_LEASE_HANDLE
? "H":"",
2785 state
.total_lease_types
& SMB2_LEASE_READ
? "R":"",
2786 state
.total_lease_types
& SMB2_LEASE_WRITE
? "W":"",
2787 state
.total_lease_types
& SMB2_LEASE_HANDLE
? "H":"",
2788 state
.total_lease_types
);
2790 *poplock_type
= oplock_type
;
2791 *pgranted
= granted
;
2792 return NT_STATUS_OK
;
2795 static NTSTATUS
handle_share_mode_lease(
2797 struct share_mode_lock
*lck
,
2798 uint32_t create_disposition
,
2799 uint32_t access_mask
,
2800 uint32_t share_access
,
2802 const struct smb2_lease
*lease
,
2803 bool first_open_attempt
,
2807 bool sharing_violation
= false;
2810 *poplock_type
= NO_OPLOCK
;
2813 status
= open_mode_check(
2814 fsp
->conn
, fsp
->file_id
, lck
, access_mask
, share_access
);
2815 if (NT_STATUS_EQUAL(status
, NT_STATUS_SHARING_VIOLATION
)) {
2816 sharing_violation
= true;
2817 status
= NT_STATUS_OK
; /* handled later */
2820 if (!NT_STATUS_IS_OK(status
)) {
2824 if (oplock_request
== INTERNAL_OPEN_ONLY
) {
2825 if (sharing_violation
) {
2826 DBG_DEBUG("Sharing violation for internal open\n");
2827 return NT_STATUS_SHARING_VIOLATION
;
2831 * Internal opens never do oplocks or leases. We don't
2832 * need to go through delay_for_oplock().
2834 return NT_STATUS_OK
;
2837 status
= delay_for_oplock(
2847 if (!NT_STATUS_IS_OK(status
)) {
2851 return NT_STATUS_OK
;
2854 static bool request_timed_out(struct smb_request
*req
, struct timeval timeout
)
2856 struct timeval end_time
= timeval_sum(&req
->request_time
, &timeout
);
2857 return timeval_expired(&end_time
);
2860 struct defer_open_state
{
2861 struct smbXsrv_connection
*xconn
;
2865 static void defer_open_done(struct tevent_req
*req
);
2868 * Defer an open and watch a locking.tdb record
2870 * This defers an open that gets rescheduled once the locking.tdb record watch
2871 * is triggered by a change to the record.
2873 * It is used to defer opens that triggered an oplock break and for the SMB1
2874 * sharing violation delay.
2876 static void defer_open(struct share_mode_lock
*lck
,
2877 struct timeval timeout
,
2878 struct smb_request
*req
,
2881 struct deferred_open_record
*open_rec
= NULL
;
2882 struct timeval abs_timeout
;
2883 struct defer_open_state
*watch_state
;
2884 struct tevent_req
*watch_req
;
2885 struct timeval_buf tvbuf1
, tvbuf2
;
2886 struct file_id_buf fbuf
;
2889 abs_timeout
= timeval_sum(&req
->request_time
, &timeout
);
2891 DBG_DEBUG("request time [%s] timeout [%s] mid [%" PRIu64
"] "
2893 timeval_str_buf(&req
->request_time
, false, true, &tvbuf1
),
2894 timeval_str_buf(&abs_timeout
, false, true, &tvbuf2
),
2896 file_id_str_buf(id
, &fbuf
));
2898 open_rec
= talloc_zero(NULL
, struct deferred_open_record
);
2899 if (open_rec
== NULL
) {
2901 exit_server("talloc failed");
2904 watch_state
= talloc(open_rec
, struct defer_open_state
);
2905 if (watch_state
== NULL
) {
2906 exit_server("talloc failed");
2908 watch_state
->xconn
= req
->xconn
;
2909 watch_state
->mid
= req
->mid
;
2911 DBG_DEBUG("deferring mid %" PRIu64
"\n", req
->mid
);
2913 watch_req
= share_mode_watch_send(
2917 (struct server_id
){0});
2918 if (watch_req
== NULL
) {
2919 exit_server("Could not watch share mode record");
2921 tevent_req_set_callback(watch_req
, defer_open_done
, watch_state
);
2923 ok
= tevent_req_set_endtime(watch_req
, req
->sconn
->ev_ctx
, abs_timeout
);
2925 exit_server("tevent_req_set_endtime failed");
2928 ok
= push_deferred_open_message_smb(req
, timeout
, id
, open_rec
);
2931 exit_server("push_deferred_open_message_smb failed");
2935 static void defer_open_done(struct tevent_req
*req
)
2937 struct defer_open_state
*state
= tevent_req_callback_data(
2938 req
, struct defer_open_state
);
2942 status
= share_mode_watch_recv(req
, NULL
, NULL
);
2944 if (!NT_STATUS_IS_OK(status
)) {
2945 DEBUG(5, ("dbwrap_watched_watch_recv returned %s\n",
2946 nt_errstr(status
)));
2948 * Even if it failed, retry anyway. TODO: We need a way to
2949 * tell a re-scheduled open about that error.
2953 DEBUG(10, ("scheduling mid %llu\n", (unsigned long long)state
->mid
));
2955 ret
= schedule_deferred_open_message_smb(state
->xconn
, state
->mid
);
2961 * Actually attempt the kernel oplock polling open.
2964 static void poll_open_fn(struct tevent_context
*ev
,
2965 struct tevent_timer
*te
,
2966 struct timeval current_time
,
2969 struct deferred_open_record
*open_rec
= talloc_get_type_abort(
2970 private_data
, struct deferred_open_record
);
2973 TALLOC_FREE(open_rec
->watch_req
);
2975 ok
= schedule_deferred_open_message_smb(
2976 open_rec
->xconn
, open_rec
->mid
);
2978 exit_server("schedule_deferred_open_message_smb failed");
2980 DBG_DEBUG("timer fired. Retrying open !\n");
2983 static void poll_open_done(struct tevent_req
*subreq
);
2985 struct poll_open_setup_watcher_state
{
2986 TALLOC_CTX
*mem_ctx
;
2987 struct tevent_context
*ev_ctx
;
2988 struct tevent_req
*watch_req
;
2991 static void poll_open_setup_watcher_fn(struct share_mode_lock
*lck
,
2994 struct poll_open_setup_watcher_state
*state
=
2995 (struct poll_open_setup_watcher_state
*)private_data
;
2997 if (!validate_oplock_types(lck
)) {
2998 smb_panic("validate_oplock_types failed");
3001 state
->watch_req
= share_mode_watch_send(
3005 (struct server_id
) {0});
3006 if (state
->watch_req
== NULL
) {
3007 DBG_WARNING("share_mode_watch_send failed\n");
3013 * Reschedule an open for 1 second from now, if not timed out.
3015 static bool setup_poll_open(
3016 struct smb_request
*req
,
3017 const struct file_id
*id
,
3018 struct timeval max_timeout
,
3019 struct timeval interval
)
3021 static struct file_id zero_id
= {};
3023 struct deferred_open_record
*open_rec
= NULL
;
3024 struct timeval endtime
, next_interval
;
3025 struct file_id_buf ftmp
;
3027 if (request_timed_out(req
, max_timeout
)) {
3031 open_rec
= talloc_zero(NULL
, struct deferred_open_record
);
3032 if (open_rec
== NULL
) {
3033 DBG_WARNING("talloc failed\n");
3036 open_rec
->xconn
= req
->xconn
;
3037 open_rec
->mid
= req
->mid
;
3040 * Make sure open_rec->te does not come later than the
3041 * request's maximum endtime.
3044 endtime
= timeval_sum(&req
->request_time
, &max_timeout
);
3045 next_interval
= timeval_current_ofs(interval
.tv_sec
, interval
.tv_usec
);
3046 next_interval
= timeval_min(&endtime
, &next_interval
);
3048 open_rec
->te
= tevent_add_timer(
3054 if (open_rec
->te
== NULL
) {
3055 DBG_WARNING("tevent_add_timer failed\n");
3056 TALLOC_FREE(open_rec
);
3061 struct poll_open_setup_watcher_state wstate
= {
3062 .mem_ctx
= open_rec
,
3063 .ev_ctx
= req
->sconn
->ev_ctx
,
3067 status
= share_mode_do_locked_vfs_denied(*id
,
3068 poll_open_setup_watcher_fn
,
3070 if (NT_STATUS_IS_OK(status
)) {
3071 if (wstate
.watch_req
== NULL
) {
3072 DBG_WARNING("share_mode_watch_send failed\n");
3073 TALLOC_FREE(open_rec
);
3076 open_rec
->watch_req
= wstate
.watch_req
;
3077 tevent_req_set_callback(open_rec
->watch_req
,
3080 } else if (!NT_STATUS_EQUAL(status
, NT_STATUS_NOT_FOUND
)) {
3081 DBG_WARNING("share_mode_do_locked_vfs_denied failed - %s\n",
3083 TALLOC_FREE(open_rec
);
3090 ok
= push_deferred_open_message_smb(req
, max_timeout
, *id
, open_rec
);
3092 DBG_WARNING("push_deferred_open_message_smb failed\n");
3093 TALLOC_FREE(open_rec
);
3097 DBG_DEBUG("poll request time [%s] mid [%" PRIu64
"] file_id [%s]\n",
3098 timeval_string(talloc_tos(), &req
->request_time
, false),
3100 file_id_str_buf(*id
, &ftmp
));
3105 static void poll_open_done(struct tevent_req
*subreq
)
3107 struct deferred_open_record
*open_rec
= tevent_req_callback_data(
3108 subreq
, struct deferred_open_record
);
3112 status
= share_mode_watch_recv(subreq
, NULL
, NULL
);
3113 TALLOC_FREE(subreq
);
3114 open_rec
->watch_req
= NULL
;
3115 TALLOC_FREE(open_rec
->te
);
3117 DBG_DEBUG("dbwrap_watched_watch_recv returned %s\n",
3120 ok
= schedule_deferred_open_message_smb(
3121 open_rec
->xconn
, open_rec
->mid
);
3123 exit_server("schedule_deferred_open_message_smb failed");
3127 bool defer_smb1_sharing_violation(struct smb_request
*req
)
3132 if (!lp_defer_sharing_violations()) {
3137 * Try every 200msec up to (by default) one second. To be
3138 * precise, according to behaviour note <247> in [MS-CIFS],
3139 * the server tries 5 times. But up to one second should be
3143 timeout_usecs
= lp_parm_int(
3147 SHARING_VIOLATION_USEC_WAIT
);
3149 ok
= setup_poll_open(
3152 (struct timeval
) { .tv_usec
= timeout_usecs
},
3153 (struct timeval
) { .tv_usec
= 200000 });
3157 /****************************************************************************
3158 On overwrite open ensure that the attributes match.
3159 ****************************************************************************/
3161 static bool open_match_attributes(connection_struct
*conn
,
3162 uint32_t old_dos_attr
,
3163 uint32_t new_dos_attr
,
3164 mode_t new_unx_mode
,
3165 mode_t
*returned_unx_mode
)
3167 uint32_t noarch_old_dos_attr
, noarch_new_dos_attr
;
3169 noarch_old_dos_attr
= (old_dos_attr
& ~FILE_ATTRIBUTE_ARCHIVE
);
3170 noarch_new_dos_attr
= (new_dos_attr
& ~FILE_ATTRIBUTE_ARCHIVE
);
3172 if((noarch_old_dos_attr
== 0 && noarch_new_dos_attr
!= 0) ||
3173 (noarch_old_dos_attr
!= 0 && ((noarch_old_dos_attr
& noarch_new_dos_attr
) == noarch_old_dos_attr
))) {
3174 *returned_unx_mode
= new_unx_mode
;
3176 *returned_unx_mode
= (mode_t
)0;
3179 DEBUG(10,("open_match_attributes: old_dos_attr = 0x%x, "
3180 "new_dos_attr = 0x%x "
3181 "returned_unx_mode = 0%o\n",
3182 (unsigned int)old_dos_attr
,
3183 (unsigned int)new_dos_attr
,
3184 (unsigned int)*returned_unx_mode
));
3186 /* If we're mapping SYSTEM and HIDDEN ensure they match. */
3187 if (lp_map_system(SNUM(conn
)) || lp_store_dos_attributes(SNUM(conn
))) {
3188 if ((old_dos_attr
& FILE_ATTRIBUTE_SYSTEM
) &&
3189 !(new_dos_attr
& FILE_ATTRIBUTE_SYSTEM
)) {
3193 if (lp_map_hidden(SNUM(conn
)) || lp_store_dos_attributes(SNUM(conn
))) {
3194 if ((old_dos_attr
& FILE_ATTRIBUTE_HIDDEN
) &&
3195 !(new_dos_attr
& FILE_ATTRIBUTE_HIDDEN
)) {
3202 static void schedule_defer_open(struct share_mode_lock
*lck
,
3204 struct smb_request
*req
)
3206 /* This is a relative time, added to the absolute
3207 request_time value to get the absolute timeout time.
3208 Note that if this is the second or greater time we enter
3209 this codepath for this particular request mid then
3210 request_time is left as the absolute time of the *first*
3211 time this request mid was processed. This is what allows
3212 the request to eventually time out. */
3214 struct timeval timeout
;
3216 /* Normally the smbd we asked should respond within
3217 * OPLOCK_BREAK_TIMEOUT seconds regardless of whether
3218 * the client did, give twice the timeout as a safety
3219 * measure here in case the other smbd is stuck
3220 * somewhere else. */
3222 timeout
= tevent_timeval_set(OPLOCK_BREAK_TIMEOUT
* 2, 0);
3224 if (request_timed_out(req
, timeout
)) {
3228 defer_open(lck
, timeout
, req
, id
);
3231 /****************************************************************************
3232 Reschedule an open call that went asynchronous.
3233 ****************************************************************************/
3235 static void schedule_async_open_timer(struct tevent_context
*ev
,
3236 struct tevent_timer
*te
,
3237 struct timeval current_time
,
3240 exit_server("async open timeout");
3243 static void schedule_async_open(struct smb_request
*req
)
3245 struct deferred_open_record
*open_rec
= NULL
;
3246 struct timeval timeout
= tevent_timeval_set(20, 0);
3249 if (request_timed_out(req
, timeout
)) {
3253 open_rec
= talloc_zero(NULL
, struct deferred_open_record
);
3254 if (open_rec
== NULL
) {
3255 exit_server("deferred_open_record_create failed");
3257 open_rec
->async_open
= true;
3259 ok
= push_deferred_open_message_smb(
3260 req
, timeout
, (struct file_id
){0}, open_rec
);
3262 exit_server("push_deferred_open_message_smb failed");
3265 open_rec
->te
= tevent_add_timer(req
->sconn
->ev_ctx
,
3267 timeval_current_ofs(20, 0),
3268 schedule_async_open_timer
,
3270 if (open_rec
->te
== NULL
) {
3271 exit_server("tevent_add_timer failed");
3275 static NTSTATUS
check_and_store_share_mode(
3276 struct files_struct
*fsp
,
3277 struct smb_request
*req
,
3278 struct share_mode_lock
*lck
,
3279 uint32_t create_disposition
,
3280 uint32_t access_mask
,
3281 uint32_t share_access
,
3283 const struct smb2_lease
*lease
,
3284 bool first_open_attempt
)
3287 int oplock_type
= NO_OPLOCK
;
3288 uint32_t granted_lease
= 0;
3289 const struct smb2_lease_key
*lease_key
= NULL
;
3290 bool delete_on_close
;
3293 /* Get the types we need to examine. */
3294 if (!validate_oplock_types(lck
)) {
3295 smb_panic("validate_oplock_types failed");
3298 delete_on_close
= has_delete_on_close(lck
, fsp
->name_hash
);
3299 if (delete_on_close
) {
3300 return NT_STATUS_DELETE_PENDING
;
3303 status
= handle_share_mode_lease(fsp
,
3313 if (NT_STATUS_EQUAL(status
, NT_STATUS_RETRY
)) {
3314 schedule_defer_open(lck
, fsp
->file_id
, req
);
3315 return NT_STATUS_SHARING_VIOLATION
;
3317 if (!NT_STATUS_IS_OK(status
)) {
3321 if (oplock_type
== LEASE_OPLOCK
) {
3322 lease_key
= &lease
->lease_key
;
3325 share_mode_flags_restrict(lck
, access_mask
, share_access
, 0);
3327 ok
= set_share_mode(lck
,
3329 get_current_uid(fsp
->conn
),
3336 return NT_STATUS_NO_MEMORY
;
3339 if (oplock_type
== LEASE_OPLOCK
) {
3340 status
= grant_fsp_lease(fsp
, lck
, lease
, granted_lease
);
3341 if (!NT_STATUS_IS_OK(status
)) {
3342 del_share_mode(lck
, fsp
);
3346 DBG_DEBUG("lease_state=%d\n", fsp
->lease
->lease
.lease_state
);
3349 fsp
->oplock_type
= oplock_type
;
3351 return NT_STATUS_OK
;
3354 /****************************************************************************
3355 Work out what access_mask to use from what the client sent us.
3356 ****************************************************************************/
3358 static NTSTATUS
smbd_calculate_maximum_allowed_access_fsp(
3359 struct files_struct
*dirfsp
,
3360 struct files_struct
*fsp
,
3362 uint32_t *p_access_mask
)
3364 struct security_descriptor
*sd
= NULL
;
3365 uint32_t access_granted
= 0;
3369 /* Cope with symlinks */
3370 if (fsp
== NULL
|| fsp_get_pathref_fd(fsp
) == -1) {
3371 *p_access_mask
= FILE_GENERIC_ALL
;
3372 return NT_STATUS_OK
;
3375 /* Cope with fake/printer fsp's. */
3376 if (fsp
->fake_file_handle
!= NULL
|| fsp
->print_file
!= NULL
) {
3377 *p_access_mask
= FILE_GENERIC_ALL
;
3378 return NT_STATUS_OK
;
3381 if (!use_privs
&& (get_current_uid(fsp
->conn
) == (uid_t
)0)) {
3382 *p_access_mask
|= FILE_GENERIC_ALL
;
3383 return NT_STATUS_OK
;
3386 status
= SMB_VFS_FGET_NT_ACL(metadata_fsp(fsp
),
3393 if (NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
3395 * File did not exist
3397 *p_access_mask
= FILE_GENERIC_ALL
;
3398 return NT_STATUS_OK
;
3400 if (!NT_STATUS_IS_OK(status
)) {
3401 DBG_ERR("Could not get acl on file %s: %s\n",
3408 * If we can access the path to this file, by
3409 * default we have FILE_READ_ATTRIBUTES from the
3410 * containing directory. See the section:
3411 * "Algorithm to Check Access to an Existing File"
3414 * se_file_access_check()
3415 * also takes care of owner WRITE_DAC and READ_CONTROL.
3417 status
= se_file_access_check(sd
,
3418 get_current_nttok(fsp
->conn
),
3420 (*p_access_mask
& ~FILE_READ_ATTRIBUTES
),
3425 if (!NT_STATUS_IS_OK(status
)) {
3426 DBG_ERR("Status %s on file %s: "
3427 "when calculating maximum access\n",
3433 *p_access_mask
= (access_granted
| FILE_READ_ATTRIBUTES
);
3435 if (!(access_granted
& DELETE_ACCESS
)) {
3436 if (can_delete_file_in_directory(fsp
->conn
,
3439 *p_access_mask
|= DELETE_ACCESS
;
3443 dosattrs
= fdos_mode(fsp
);
3444 if ((dosattrs
& FILE_ATTRIBUTE_READONLY
) || !CAN_WRITE(fsp
->conn
)) {
3445 *p_access_mask
&= ~(FILE_GENERIC_WRITE
| DELETE_ACCESS
);
3448 return NT_STATUS_OK
;
3451 NTSTATUS
smbd_calculate_access_mask_fsp(struct files_struct
*dirfsp
,
3452 struct files_struct
*fsp
,
3454 uint32_t access_mask
,
3455 uint32_t *access_mask_out
)
3458 uint32_t orig_access_mask
= access_mask
;
3459 uint32_t rejected_share_access
;
3461 if (access_mask
& SEC_MASK_INVALID
) {
3462 DBG_DEBUG("access_mask [%8x] contains invalid bits\n",
3464 return NT_STATUS_ACCESS_DENIED
;
3468 * Convert GENERIC bits to specific bits.
3471 se_map_generic(&access_mask
, &file_generic_mapping
);
3473 /* Calculate MAXIMUM_ALLOWED_ACCESS if requested. */
3474 if (access_mask
& MAXIMUM_ALLOWED_ACCESS
) {
3476 status
= smbd_calculate_maximum_allowed_access_fsp(
3482 if (!NT_STATUS_IS_OK(status
)) {
3486 access_mask
&= fsp
->conn
->share_access
;
3489 rejected_share_access
= access_mask
& ~(fsp
->conn
->share_access
);
3491 if (rejected_share_access
) {
3492 DBG_INFO("Access denied on file %s: "
3493 "rejected by share access mask[0x%08X] "
3494 "orig[0x%08X] mapped[0x%08X] reject[0x%08X]\n",
3496 fsp
->conn
->share_access
,
3497 orig_access_mask
, access_mask
,
3498 rejected_share_access
);
3499 return NT_STATUS_ACCESS_DENIED
;
3502 *access_mask_out
= access_mask
;
3503 return NT_STATUS_OK
;
3506 /****************************************************************************
3507 Remove the deferred open entry under lock.
3508 ****************************************************************************/
3510 /****************************************************************************
3511 Return true if this is a state pointer to an asynchronous create.
3512 ****************************************************************************/
3514 bool is_deferred_open_async(const struct deferred_open_record
*rec
)
3516 return rec
->async_open
;
3519 static bool clear_ads(uint32_t create_disposition
)
3523 switch (create_disposition
) {
3524 case FILE_SUPERSEDE
:
3525 case FILE_OVERWRITE_IF
:
3526 case FILE_OVERWRITE
:
3535 static int disposition_to_open_flags(uint32_t create_disposition
)
3540 * Currently we're using FILE_SUPERSEDE as the same as
3541 * FILE_OVERWRITE_IF but they really are
3542 * different. FILE_SUPERSEDE deletes an existing file
3543 * (requiring delete access) then recreates it.
3546 switch (create_disposition
) {
3547 case FILE_SUPERSEDE
:
3548 case FILE_OVERWRITE_IF
:
3550 * If file exists replace/overwrite. If file doesn't
3553 ret
= O_CREAT
|O_TRUNC
;
3558 * If file exists open. If file doesn't exist error.
3563 case FILE_OVERWRITE
:
3565 * If file exists overwrite. If file doesn't exist
3573 * If file exists error. If file doesn't exist create.
3575 ret
= O_CREAT
|O_EXCL
;
3580 * If file exists open. If file doesn't exist create.
3588 static int calculate_open_access_flags(uint32_t access_mask
,
3589 uint32_t private_flags
,
3592 bool need_write
, need_read
;
3595 * Note that we ignore the append flag as append does not
3596 * mean the same thing under DOS and Unix.
3601 * Pave over the user requested mode and force O_RDONLY for the
3602 * file handle. Windows allows opening a VSS file with O_RDWR,
3603 * even though actual writes on the handle will fail.
3608 need_write
= (access_mask
& (FILE_WRITE_DATA
| FILE_APPEND_DATA
));
3613 /* DENY_DOS opens are always underlying read-write on the
3614 file handle, no matter what the requested access mask
3618 ((private_flags
& NTCREATEX_FLAG_DENY_DOS
) ||
3619 access_mask
& (FILE_READ_ATTRIBUTES
|FILE_READ_DATA
|
3620 FILE_READ_EA
|FILE_EXECUTE
));
3628 struct open_ntcreate_lock_state
{
3629 struct share_mode_entry_prepare_state prepare_state
;
3630 struct files_struct
*fsp
;
3631 const char *object_type
;
3632 struct smb_request
*req
;
3633 uint32_t create_disposition
;
3634 uint32_t access_mask
;
3635 uint32_t share_access
;
3637 const struct smb2_lease
*lease
;
3638 bool first_open_attempt
;
3641 struct timespec write_time
;
3642 share_mode_entry_prepare_unlock_fn_t cleanup_fn
;
3645 static void open_ntcreate_lock_add_entry(struct share_mode_lock
*lck
,
3649 struct open_ntcreate_lock_state
*state
=
3650 (struct open_ntcreate_lock_state
*)private_data
;
3653 * By default drop the g_lock again if we leave the
3656 *keep_locked
= false;
3658 state
->status
= check_and_store_share_mode(state
->fsp
,
3661 state
->create_disposition
,
3663 state
->share_access
,
3664 state
->oplock_request
,
3666 state
->first_open_attempt
);
3667 if (!NT_STATUS_IS_OK(state
->status
)) {
3671 state
->write_time
= get_share_mode_write_time(lck
);
3674 * keep the g_lock while existing the tdb chainlock,
3675 * we we're asked to, which mean we'll keep
3676 * the share_mode_lock during object creation,
3677 * or setting delete on close.
3679 *keep_locked
= state
->keep_locked
;
3682 static void open_ntcreate_lock_cleanup_oplock(struct share_mode_lock
*lck
,
3685 struct open_ntcreate_lock_state
*state
=
3686 (struct open_ntcreate_lock_state
*)private_data
;
3689 ok
= remove_share_oplock(lck
, state
->fsp
);
3691 DBG_ERR("Could not remove oplock for %s %s\n",
3692 state
->object_type
, fsp_str_dbg(state
->fsp
));
3696 static void open_ntcreate_lock_cleanup_entry(struct share_mode_lock
*lck
,
3699 struct open_ntcreate_lock_state
*state
=
3700 (struct open_ntcreate_lock_state
*)private_data
;
3703 ok
= del_share_mode(lck
, state
->fsp
);
3705 DBG_ERR("Could not delete share entry for %s %s\n",
3706 state
->object_type
, fsp_str_dbg(state
->fsp
));
3710 static void possibly_set_archive(struct connection_struct
*conn
,
3711 struct files_struct
*fsp
,
3712 struct smb_filename
*smb_fname
,
3713 struct smb_filename
*parent_dir_fname
,
3718 bool set_archive
= false;
3721 if (info
== FILE_WAS_OPENED
) {
3725 /* Overwritten files should be initially set as archive */
3726 if ((info
== FILE_WAS_OVERWRITTEN
&& lp_map_archive(SNUM(conn
)))) {
3728 } else if (lp_store_dos_attributes(SNUM(conn
))) {
3735 ret
= file_set_dosmode(conn
,
3737 dosattrs
| FILE_ATTRIBUTE_ARCHIVE
,
3743 *unx_mode
= smb_fname
->st
.st_ex_mode
;
3746 /****************************************************************************
3747 Open a file with a share mode. Passed in an already created files_struct *.
3748 ****************************************************************************/
3750 static NTSTATUS
open_file_ntcreate(connection_struct
*conn
,
3751 struct smb_request
*req
,
3752 uint32_t access_mask
, /* access bits (FILE_READ_DATA etc.) */
3753 uint32_t share_access
, /* share constants (FILE_SHARE_READ etc) */
3754 uint32_t create_disposition
, /* FILE_OPEN_IF etc. */
3755 uint32_t create_options
, /* options such as delete on close. */
3756 uint32_t new_dos_attributes
, /* attributes used for new file. */
3757 int oplock_request
, /* internal Samba oplock codes. */
3758 const struct smb2_lease
*lease
,
3759 /* Information (FILE_EXISTS etc.) */
3760 uint32_t private_flags
, /* Samba specific flags. */
3761 struct smb_filename
*parent_dir_fname
, /* parent. */
3762 struct smb_filename
*smb_fname_atname
, /* atname relative to parent. */
3766 struct smb_filename
*smb_fname
= fsp
->fsp_name
;
3768 bool file_existed
= VALID_STAT(smb_fname
->st
);
3769 bool def_acl
= False
;
3770 bool posix_open
= False
;
3771 bool new_file_created
= False
;
3772 bool first_open_attempt
= true;
3773 bool is_twrp
= (smb_fname_atname
->twrp
!= 0);
3774 NTSTATUS fsp_open
= NT_STATUS_ACCESS_DENIED
;
3775 mode_t new_unx_mode
= (mode_t
)0;
3776 mode_t unx_mode
= (mode_t
)0;
3778 uint32_t existing_dos_attributes
= 0;
3779 struct open_ntcreate_lock_state lck_state
= {};
3780 bool keep_locked
= false;
3781 uint32_t open_access_mask
= access_mask
;
3783 SMB_STRUCT_STAT saved_stat
= smb_fname
->st
;
3784 struct timespec old_write_time
;
3785 bool setup_poll
= false;
3788 if (conn
->printer
) {
3790 * Printers are handled completely differently.
3791 * Most of the passed parameters are ignored.
3795 *pinfo
= FILE_WAS_CREATED
;
3798 DBG_DEBUG("printer open fname=%s\n",
3799 smb_fname_str_dbg(smb_fname
));
3802 DBG_ERR("printer open without an SMB request!\n");
3803 return NT_STATUS_INTERNAL_ERROR
;
3806 return print_spool_open(fsp
, smb_fname
->base_name
,
3810 if (new_dos_attributes
& FILE_FLAG_POSIX_SEMANTICS
) {
3812 unx_mode
= (mode_t
)(new_dos_attributes
& ~FILE_FLAG_POSIX_SEMANTICS
);
3813 new_dos_attributes
= 0;
3815 /* Windows allows a new file to be created and
3816 silently removes a FILE_ATTRIBUTE_DIRECTORY
3817 sent by the client. Do the same. */
3819 new_dos_attributes
&= ~FILE_ATTRIBUTE_DIRECTORY
;
3821 /* We add FILE_ATTRIBUTE_ARCHIVE to this as this mode is only used if the file is
3823 unx_mode
= unix_mode(
3825 new_dos_attributes
| FILE_ATTRIBUTE_ARCHIVE
,
3827 parent_dir_fname
->fsp
);
3830 DEBUG(10, ("open_file_ntcreate: fname=%s, dos_attrs=0x%x "
3831 "access_mask=0x%x share_access=0x%x "
3832 "create_disposition = 0x%x create_options=0x%x "
3833 "unix mode=0%o oplock_request=%d private_flags = 0x%x\n",
3834 smb_fname_str_dbg(smb_fname
), new_dos_attributes
,
3835 access_mask
, share_access
, create_disposition
,
3836 create_options
, (unsigned int)unx_mode
, oplock_request
,
3837 (unsigned int)private_flags
));
3840 /* Ensure req == NULL means INTERNAL_OPEN_ONLY */
3841 SMB_ASSERT(oplock_request
== INTERNAL_OPEN_ONLY
);
3843 /* And req != NULL means no INTERNAL_OPEN_ONLY */
3844 SMB_ASSERT(((oplock_request
& INTERNAL_OPEN_ONLY
) == 0));
3848 * Only non-internal opens can be deferred at all
3852 struct deferred_open_record
*open_rec
;
3853 if (get_deferred_open_message_state(req
, NULL
, &open_rec
)) {
3855 /* If it was an async create retry, the file
3858 if (is_deferred_open_async(open_rec
)) {
3859 SET_STAT_INVALID(smb_fname
->st
);
3860 file_existed
= false;
3863 /* Ensure we don't reprocess this message. */
3864 remove_deferred_open_message_smb(req
->xconn
, req
->mid
);
3866 first_open_attempt
= false;
3871 new_dos_attributes
&= SAMBA_ATTRIBUTES_MASK
;
3874 * Only use stored DOS attributes for checks
3875 * against requested attributes (below via
3876 * open_match_attributes()), cf bug #11992
3877 * for details. -slow
3881 status
= SMB_VFS_FGET_DOS_ATTRIBUTES(
3883 metadata_fsp(smb_fname
->fsp
),
3885 if (NT_STATUS_IS_OK(status
)) {
3886 existing_dos_attributes
= attr
;
3891 /* ignore any oplock requests if oplocks are disabled */
3892 if (!lp_oplocks(SNUM(conn
)) ||
3893 IS_VETO_OPLOCK_PATH(conn
, smb_fname
->base_name
)) {
3894 /* Mask off everything except the private Samba bits. */
3895 oplock_request
&= SAMBA_PRIVATE_OPLOCK_MASK
;
3898 /* this is for OS/2 long file names - say we don't support them */
3899 if (req
!= NULL
&& !req
->posix_pathnames
&&
3900 strstr(smb_fname
->base_name
,".+,;=[].")) {
3901 /* OS/2 Workplace shell fix may be main code stream in a later
3903 DEBUG(5,("open_file_ntcreate: OS/2 long filenames are not "
3905 if (use_nt_status()) {
3906 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
3908 return NT_STATUS_DOS(ERRDOS
, ERRcannotopen
);
3911 switch( create_disposition
) {
3913 /* If file exists open. If file doesn't exist error. */
3914 if (!file_existed
) {
3915 DEBUG(5,("open_file_ntcreate: FILE_OPEN "
3916 "requested for file %s and file "
3918 smb_fname_str_dbg(smb_fname
)));
3919 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
3923 case FILE_OVERWRITE
:
3924 /* If file exists overwrite. If file doesn't exist
3926 if (!file_existed
) {
3927 DEBUG(5,("open_file_ntcreate: FILE_OVERWRITE "
3928 "requested for file %s and file "
3930 smb_fname_str_dbg(smb_fname
) ));
3931 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
3934 return NT_STATUS_MEDIA_WRITE_PROTECTED
;
3939 /* If file exists error. If file doesn't exist
3942 DEBUG(5,("open_file_ntcreate: FILE_CREATE "
3943 "requested for file %s and file "
3944 "already exists.\n",
3945 smb_fname_str_dbg(smb_fname
)));
3946 if (S_ISDIR(smb_fname
->st
.st_ex_mode
)) {
3947 return NT_STATUS_FILE_IS_A_DIRECTORY
;
3949 return NT_STATUS_OBJECT_NAME_COLLISION
;
3952 return NT_STATUS_MEDIA_WRITE_PROTECTED
;
3956 case FILE_SUPERSEDE
:
3957 case FILE_OVERWRITE_IF
:
3959 return NT_STATUS_MEDIA_WRITE_PROTECTED
;
3964 if (!file_existed
) {
3965 return NT_STATUS_MEDIA_WRITE_PROTECTED
;
3967 create_disposition
= FILE_OPEN
;
3971 return NT_STATUS_INVALID_PARAMETER
;
3974 flags
= disposition_to_open_flags(create_disposition
);
3976 /* We only care about matching attributes on file exists and
3979 if (!posix_open
&& file_existed
&&
3980 ((create_disposition
== FILE_OVERWRITE
) ||
3981 (create_disposition
== FILE_OVERWRITE_IF
))) {
3982 if (!open_match_attributes(conn
, existing_dos_attributes
,
3984 unx_mode
, &new_unx_mode
)) {
3985 DEBUG(5,("open_file_ntcreate: attributes mismatch "
3986 "for file %s (%x %x) (0%o, 0%o)\n",
3987 smb_fname_str_dbg(smb_fname
),
3988 existing_dos_attributes
,
3990 (unsigned int)smb_fname
->st
.st_ex_mode
,
3991 (unsigned int)unx_mode
));
3992 return NT_STATUS_ACCESS_DENIED
;
3996 status
= smbd_calculate_access_mask_fsp(parent_dir_fname
->fsp
,
4001 if (!NT_STATUS_IS_OK(status
)) {
4002 DBG_DEBUG("smbd_calculate_access_mask_fsp "
4003 "on file %s returned %s\n",
4004 smb_fname_str_dbg(smb_fname
),
4009 open_access_mask
= access_mask
;
4011 if (flags
& O_TRUNC
) {
4012 open_access_mask
|= FILE_WRITE_DATA
; /* This will cause oplock breaks. */
4017 * stat opens on existing files don't get oplocks.
4018 * They can get leases.
4020 * Note that we check for stat open on the *open_access_mask*,
4021 * i.e. the access mask we actually used to do the open,
4022 * not the one the client asked for (which is in
4023 * fsp->access_mask). This is due to the fact that
4024 * FILE_OVERWRITE and FILE_OVERWRITE_IF add in O_TRUNC,
4025 * which adds FILE_WRITE_DATA to open_access_mask.
4027 if (is_oplock_stat_open(open_access_mask
) && lease
== NULL
) {
4028 oplock_request
= NO_OPLOCK
;
4032 DEBUG(10, ("open_file_ntcreate: fname=%s, after mapping "
4033 "access_mask=0x%x\n", smb_fname_str_dbg(smb_fname
),
4037 * Note that we ignore the append flag as append does not
4038 * mean the same thing under DOS and Unix.
4041 flags
|= calculate_open_access_flags(access_mask
,
4046 * Currently we only look at FILE_WRITE_THROUGH for create options.
4050 if ((create_options
& FILE_WRITE_THROUGH
) && lp_strict_sync(SNUM(conn
))) {
4055 if (posix_open
&& (access_mask
& FILE_APPEND_DATA
)) {
4059 if (!posix_open
&& !CAN_WRITE(conn
)) {
4061 * We should really return a permission denied error if either
4062 * O_CREAT or O_TRUNC are set, but for compatibility with
4063 * older versions of Samba we just AND them out.
4065 flags
&= ~(O_CREAT
| O_TRUNC
);
4069 * With kernel oplocks the open breaking an oplock
4070 * blocks until the oplock holder has given up the
4071 * oplock or closed the file. We prevent this by always
4072 * trying to open the file with O_NONBLOCK (see "man
4075 * If a process that doesn't use the smbd open files
4076 * database or communication methods holds a kernel
4077 * oplock we must periodically poll for available open
4080 flags
|= O_NONBLOCK
;
4083 * Ensure we can't write on a read-only share or file.
4086 if (((flags
& O_ACCMODE
) != O_RDONLY
) && file_existed
&&
4087 (!CAN_WRITE(conn
) ||
4088 (existing_dos_attributes
& FILE_ATTRIBUTE_READONLY
))) {
4089 DEBUG(5,("open_file_ntcreate: write access requested for "
4090 "file %s on read only %s\n",
4091 smb_fname_str_dbg(smb_fname
),
4092 !CAN_WRITE(conn
) ? "share" : "file" ));
4093 return NT_STATUS_ACCESS_DENIED
;
4096 if (VALID_STAT(smb_fname
->st
)) {
4098 * Only try and create a file id before open
4099 * for an existing file. For a file being created
4100 * this won't do anything useful until the file
4101 * exists and has a valid stat struct.
4103 fsp
->file_id
= vfs_file_id_from_sbuf(conn
, &smb_fname
->st
);
4105 fh_set_private_options(fsp
->fh
, private_flags
);
4106 fsp
->access_mask
= open_access_mask
; /* We change this to the
4107 * requested access_mask after
4108 * the open is done. */
4110 fsp
->posix_flags
|= FSP_POSIX_FLAGS_ALL
;
4113 if ((create_options
& FILE_DELETE_ON_CLOSE
) && (flags
& O_CREAT
) &&
4115 /* Delete on close semantics for new files. */
4116 status
= can_set_delete_on_close(fsp
,
4117 new_dos_attributes
);
4118 if (!NT_STATUS_IS_OK(status
)) {
4125 * Ensure we pay attention to default ACLs on directories if required.
4128 if ((flags
& O_CREAT
) && lp_inherit_acls(SNUM(conn
)) &&
4129 (def_acl
= directory_has_default_acl_fsp(parent_dir_fname
->fsp
))) {
4130 unx_mode
= (0777 & lp_create_mask(SNUM(conn
)));
4134 ("calling open_file with flags=0x%X mode=0%o, "
4135 "access_mask = 0x%x, open_access_mask = 0x%x\n",
4136 (unsigned int)flags
,
4137 (unsigned int)unx_mode
,
4138 (unsigned int)access_mask
,
4139 (unsigned int)open_access_mask
));
4142 struct vfs_open_how how
= {
4147 if (create_options
& FILE_OPEN_FOR_BACKUP_INTENT
) {
4148 how
.resolve
|= VFS_OPEN_HOW_WITH_BACKUP_INTENT
;
4151 fsp_open
= open_file(req
,
4152 parent_dir_fname
->fsp
,
4161 if (NT_STATUS_EQUAL(fsp_open
, NT_STATUS_NETWORK_BUSY
)) {
4162 if (file_existed
&& S_ISFIFO(fsp
->fsp_name
->st
.st_ex_mode
)) {
4163 DEBUG(10, ("FIFO busy\n"));
4164 return NT_STATUS_NETWORK_BUSY
;
4167 DEBUG(10, ("Internal open busy\n"));
4168 return NT_STATUS_NETWORK_BUSY
;
4171 * This handles the kernel oplock case:
4173 * the file has an active kernel oplock and the open() returned
4174 * EWOULDBLOCK/EAGAIN which maps to NETWORK_BUSY.
4176 * "Samba locking.tdb oplocks" are handled below after acquiring
4177 * the sharemode lock with get_share_mode_lock().
4182 if (NT_STATUS_EQUAL(fsp_open
, NT_STATUS_RETRY
)) {
4184 * EINTR from the open(2) syscall. Just setup a retry
4185 * in a bit. We can't use the sys_write() tight retry
4186 * loop here, as we might have to actually deal with
4187 * lease-break signals to avoid a deadlock.
4194 * Retry once a second. If there's a share_mode_lock
4195 * around, also wait for it in case it was smbd
4196 * holding that kernel oplock that can quickly tell us
4197 * the oplock got removed.
4200 setup_poll_open(req
,
4202 tevent_timeval_set(OPLOCK_BREAK_TIMEOUT
* 2,
4204 tevent_timeval_set(1, 0));
4206 return NT_STATUS_SHARING_VIOLATION
;
4209 if (!NT_STATUS_IS_OK(fsp_open
)) {
4210 bool wait_for_aio
= NT_STATUS_EQUAL(
4211 fsp_open
, NT_STATUS_MORE_PROCESSING_REQUIRED
);
4213 schedule_async_open(req
);
4218 if (new_file_created
) {
4220 * As we atomically create using O_CREAT|O_EXCL,
4221 * then if new_file_created is true, then
4222 * file_existed *MUST* have been false (even
4223 * if the file was previously detected as being
4226 file_existed
= false;
4229 if (file_existed
&& !check_same_dev_ino(&saved_stat
, &smb_fname
->st
)) {
4231 * The file did exist, but some other (local or NFS)
4232 * process either renamed/unlinked and re-created the
4233 * file with different dev/ino after we walked the path,
4234 * but before we did the open. We could retry the
4235 * open but it's a rare enough case it's easier to
4236 * just fail the open to prevent creating any problems
4237 * in the open file db having the wrong dev/ino key.
4240 DBG_WARNING("file %s - dev/ino mismatch. "
4241 "Old (dev=%ju, ino=%ju). "
4242 "New (dev=%ju, ino=%ju). Failing open "
4243 "with NT_STATUS_ACCESS_DENIED.\n",
4244 smb_fname_str_dbg(smb_fname
),
4245 (uintmax_t)saved_stat
.st_ex_dev
,
4246 (uintmax_t)saved_stat
.st_ex_ino
,
4247 (uintmax_t)smb_fname
->st
.st_ex_dev
,
4248 (uintmax_t)smb_fname
->st
.st_ex_ino
);
4249 return NT_STATUS_ACCESS_DENIED
;
4252 old_write_time
= smb_fname
->st
.st_ex_mtime
;
4255 * Deal with the race condition where two smbd's detect the
4256 * file doesn't exist and do the create at the same time. One
4257 * of them will win and set a share mode, the other (ie. this
4258 * one) should check if the requested share mode for this
4259 * create is allowed.
4263 * Now the file exists and fsp is successfully opened,
4264 * fsp->dev and fsp->inode are valid and should replace the
4265 * dev=0,inode=0 from a non existent file. Spotted by
4266 * Nadav Danieli <nadavd@exanet.com>. JRA.
4269 if (new_file_created
) {
4270 info
= FILE_WAS_CREATED
;
4272 if (flags
& O_TRUNC
) {
4273 info
= FILE_WAS_OVERWRITTEN
;
4275 info
= FILE_WAS_OPENED
;
4280 * If we created a new file, overwrite an existing one
4281 * or going to delete it later, we should keep
4282 * the share_mode_lock (g_lock) until we call
4283 * share_mode_entry_prepare_unlock()
4285 if (info
!= FILE_WAS_OPENED
) {
4287 } else if (create_options
& FILE_DELETE_ON_CLOSE
) {
4291 lck_state
= (struct open_ntcreate_lock_state
) {
4293 .object_type
= "file",
4295 .create_disposition
= create_disposition
,
4296 .access_mask
= access_mask
,
4297 .share_access
= share_access
,
4298 .oplock_request
= oplock_request
,
4300 .first_open_attempt
= first_open_attempt
,
4301 .keep_locked
= keep_locked
,
4304 status
= share_mode_entry_prepare_lock_add(&lck_state
.prepare_state
,
4309 open_ntcreate_lock_add_entry
,
4311 if (!NT_STATUS_IS_OK(status
)) {
4312 DBG_ERR("share_mode_entry_prepare_lock_add() failed for %s - %s\n",
4313 smb_fname_str_dbg(smb_fname
), nt_errstr(status
));
4318 status
= lck_state
.status
;
4319 if (!NT_STATUS_IS_OK(status
)) {
4325 * From here we need to use 'goto unlock;' instead of return !!!
4328 if (fsp
->oplock_type
!= NO_OPLOCK
&& fsp
->oplock_type
!= LEASE_OPLOCK
) {
4330 * Now ask for kernel oplocks
4331 * and cleanup on failure.
4333 status
= set_file_oplock(fsp
);
4334 if (!NT_STATUS_IS_OK(status
)) {
4336 * Could not get the kernel oplock
4338 lck_state
.cleanup_fn
=
4339 open_ntcreate_lock_cleanup_oplock
;
4340 fsp
->oplock_type
= NO_OPLOCK
;
4344 /* Should we atomically (to the client at least) truncate ? */
4345 if ((!new_file_created
) && (flags
& O_TRUNC
) &&
4346 (S_ISREG(fsp
->fsp_name
->st
.st_ex_mode
))) {
4349 ret
= SMB_VFS_FTRUNCATE(fsp
, 0);
4351 status
= map_nt_error_from_unix(errno
);
4352 lck_state
.cleanup_fn
=
4353 open_ntcreate_lock_cleanup_entry
;
4356 notify_fname(fsp
->conn
, NOTIFY_ACTION_MODIFIED
,
4357 FILE_NOTIFY_CHANGE_SIZE
4358 | FILE_NOTIFY_CHANGE_ATTRIBUTES
,
4359 fsp
->fsp_name
->base_name
);
4363 * We have the share entry *locked*.....
4366 /* Delete streams if create_disposition requires it */
4367 if (!new_file_created
&&
4368 clear_ads(create_disposition
) &&
4369 !fsp_is_alternate_stream(fsp
)) {
4370 status
= delete_all_streams(conn
, smb_fname
);
4371 if (!NT_STATUS_IS_OK(status
)) {
4372 lck_state
.cleanup_fn
=
4373 open_ntcreate_lock_cleanup_entry
;
4378 if (!fsp
->fsp_flags
.is_pathref
&&
4379 fsp_get_io_fd(fsp
) != -1 &&
4380 lp_kernel_share_modes(SNUM(conn
)))
4384 * Beware: streams implementing VFS modules may
4385 * implement streams in a way that fsp will have the
4386 * basefile open in the fsp fd, so lacking a distinct
4387 * fd for the stream the file-system sharemode will
4388 * apply on the basefile which is wrong. The actual
4389 * check is deferred to the VFS module implementing
4390 * the file-system sharemode call.
4392 ret
= SMB_VFS_FILESYSTEM_SHAREMODE(fsp
,
4396 status
= NT_STATUS_SHARING_VIOLATION
;
4397 lck_state
.cleanup_fn
=
4398 open_ntcreate_lock_cleanup_entry
;
4402 fsp
->fsp_flags
.kernel_share_modes_taken
= true;
4406 * At this point onwards, we can guarantee that the share entry
4407 * is locked, whether we created the file or not, and that the
4408 * deny mode is compatible with all current opens.
4412 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
4413 * but we don't have to store this - just ignore it on access check.
4415 if (conn_using_smb2(conn
->sconn
)) {
4417 * SMB2 doesn't return it (according to Microsoft tests).
4418 * Test Case: TestSuite_ScenarioNo009GrantedAccessTestS0
4419 * File created with access = 0x7 (Read, Write, Delete)
4420 * Query Info on file returns 0x87 (Read, Write, Delete, Read Attributes)
4422 fsp
->access_mask
= access_mask
;
4424 /* But SMB1 does. */
4425 fsp
->access_mask
= access_mask
| FILE_READ_ATTRIBUTES
;
4432 /* Handle strange delete on close create semantics. */
4433 if (create_options
& FILE_DELETE_ON_CLOSE
) {
4434 if (!new_file_created
) {
4435 status
= can_set_delete_on_close(fsp
,
4436 existing_dos_attributes
);
4438 if (!NT_STATUS_IS_OK(status
)) {
4439 /* Remember to delete the mode we just added. */
4440 lck_state
.cleanup_fn
=
4441 open_ntcreate_lock_cleanup_entry
;
4445 /* Note that here we set the *initial* delete on close flag,
4446 not the regular one. The magic gets handled in close. */
4447 fsp
->fsp_flags
.initial_delete_on_close
= true;
4450 possibly_set_archive(conn
,
4456 &smb_fname
->st
.st_ex_mode
);
4458 /* Determine sparse flag. */
4460 /* POSIX opens are sparse by default. */
4461 fsp
->fsp_flags
.is_sparse
= true;
4463 fsp
->fsp_flags
.is_sparse
=
4464 (existing_dos_attributes
& FILE_ATTRIBUTE_SPARSE
);
4468 * Take care of inherited ACLs on created files - if default ACL not
4472 if (!posix_open
&& new_file_created
&& !def_acl
) {
4473 if (unx_mode
!= smb_fname
->st
.st_ex_mode
) {
4474 int ret
= SMB_VFS_FCHMOD(fsp
, unx_mode
);
4476 DBG_INFO("failed to reset "
4477 "attributes of file %s to 0%o\n",
4478 smb_fname_str_dbg(smb_fname
),
4479 (unsigned int)unx_mode
);
4483 } else if (new_unx_mode
) {
4485 * We only get here in the case of:
4487 * a). Not a POSIX open.
4488 * b). File already existed.
4489 * c). File was overwritten.
4490 * d). Requested DOS attributes didn't match
4491 * the DOS attributes on the existing file.
4493 * In that case new_unx_mode has been set
4494 * equal to the calculated mode (including
4495 * possible inheritance of the mode from the
4496 * containing directory).
4498 * Note this mode was calculated with the
4499 * DOS attribute FILE_ATTRIBUTE_ARCHIVE added,
4500 * so the mode change here is suitable for
4501 * an overwritten file.
4504 if (new_unx_mode
!= smb_fname
->st
.st_ex_mode
) {
4505 int ret
= SMB_VFS_FCHMOD(fsp
, new_unx_mode
);
4507 DBG_INFO("failed to reset "
4508 "attributes of file %s to 0%o\n",
4509 smb_fname_str_dbg(smb_fname
),
4510 (unsigned int)new_unx_mode
);
4516 * Deal with other opens having a modified write time.
4518 if (fsp_getinfo_ask_sharemode(fsp
) &&
4519 !is_omit_timespec(&lck_state
.write_time
))
4521 update_stat_ex_mtime(&fsp
->fsp_name
->st
, lck_state
.write_time
);
4524 status
= NT_STATUS_OK
;
4527 ulstatus
= share_mode_entry_prepare_unlock(&lck_state
.prepare_state
,
4528 lck_state
.cleanup_fn
,
4530 if (!NT_STATUS_IS_OK(ulstatus
)) {
4531 DBG_ERR("share_mode_entry_prepare_unlock() failed for %s - %s\n",
4532 smb_fname_str_dbg(smb_fname
), nt_errstr(ulstatus
));
4533 smb_panic("share_mode_entry_prepare_unlock() failed!");
4536 if (!NT_STATUS_IS_OK(status
)) {
4541 return NT_STATUS_OK
;
4544 static NTSTATUS
apply_new_nt_acl(struct files_struct
*dirfsp
,
4545 struct files_struct
*fsp
,
4546 struct security_descriptor
*sd
)
4552 * According to the MS documentation, the only time the security
4553 * descriptor is applied to the opened file is iff we *created* the
4554 * file; an existing file stays the same.
4556 * Also, it seems (from observation) that you can open the file with
4557 * any access mask but you can still write the sd. We need to override
4558 * the granted access before we call set_sd
4559 * Patch for bug #2242 from Tom Lackemann <cessnatomny@yahoo.com>.
4562 uint32_t sec_info_sent
;
4563 uint32_t saved_access_mask
= fsp
->access_mask
;
4565 sec_info_sent
= get_sec_info(sd
);
4567 fsp
->access_mask
= FILE_GENERIC_ALL
;
4569 if (sec_info_sent
& (SECINFO_OWNER
|
4573 status
= set_sd(fsp
, sd
, sec_info_sent
);
4575 status
= NT_STATUS_OK
;
4578 fsp
->access_mask
= saved_access_mask
;
4580 if (!NT_STATUS_IS_OK(status
)) {
4581 DBG_WARNING("set_sd() failed for '%s': %s\n",
4582 fsp_str_dbg(fsp
), nt_errstr(status
));
4586 return NT_STATUS_OK
;
4589 if (!lp_inherit_acls(SNUM(fsp
->conn
))) {
4590 return NT_STATUS_OK
;
4593 /* Inherit from parent. Errors here are not fatal. */
4594 status
= inherit_new_acl(dirfsp
, fsp
);
4595 if (!NT_STATUS_IS_OK(status
)) {
4596 DBG_WARNING("inherit_new_acl failed for %s with %s\n",
4597 fsp_str_dbg(fsp
), nt_errstr(status
));
4600 return NT_STATUS_OK
;
4603 bool smbd_is_tmpname(const char *n
, int *_unlink_flags
)
4606 int unlink_flags
= INT_MAX
;
4607 struct server_id id
;
4610 if (_unlink_flags
!= NULL
) {
4611 *_unlink_flags
= INT_MAX
;
4614 if (!IS_SMBD_TMPNAME_PREFIX(n
)) {
4617 p
+= sizeof(SMBD_TMPNAME_PREFIX
) - 1;
4620 unlink_flags
= AT_REMOVEDIR
;
4631 id
= server_id_from_string_ex(get_my_vnn(), '%', p
);
4632 if (id
.pid
== UINT64_MAX
) {
4635 if (id
.unique_id
== 0) {
4638 if (id
.unique_id
== SERVERID_UNIQUE_ID_NOT_TO_VERIFY
) {
4642 if (_unlink_flags
== NULL
) {
4646 exists
= serverid_exists(&id
);
4649 * let the caller know it's stale
4650 * and should be removed
4652 *_unlink_flags
= unlink_flags
;
4658 static NTSTATUS
mkdir_internal(connection_struct
*conn
,
4659 struct smb_filename
*parent_dir_fname
, /* parent. */
4660 struct smb_filename
*smb_fname_atname
, /* atname relative to parent. */
4661 struct smb_filename
*smb_dname
, /* full pathname from root of share. */
4662 struct security_descriptor
*sd
,
4663 uint32_t file_attributes
,
4664 struct files_struct
*fsp
)
4666 TALLOC_CTX
*frame
= talloc_stackframe();
4667 const struct loadparm_substitution
*lp_sub
=
4668 loadparm_s3_global_substitution();
4671 bool posix_open
= false;
4672 bool need_re_stat
= false;
4673 uint32_t access_mask
= SEC_DIR_ADD_SUBDIR
;
4674 struct smb_filename
*first_atname
= NULL
;
4675 struct smb_filename
*tmp_atname
= NULL
;
4676 char *orig_dname
= NULL
;
4677 char *tmp_dname
= NULL
;
4678 int vfs_use_tmp
= lp_vfs_mkdir_use_tmp_name(SNUM(conn
));
4679 bool need_tmpname
= false;
4680 struct server_id id
= messaging_server_id(conn
->sconn
->msg_ctx
);
4681 struct server_id_buf idbuf
;
4682 char *idstr
= server_id_str_buf_unique_ex(id
, '%', &idbuf
);
4683 struct vfs_open_how how
= { .flags
= O_RDONLY
|O_DIRECTORY
, };
4684 struct vfs_rename_how rhow
= { .flags
= VFS_RENAME_HOW_NO_REPLACE
, };
4687 if (!CAN_WRITE(conn
) || (access_mask
& ~(conn
->share_access
))) {
4688 DBG_INFO("failing share access %s\n",
4689 lp_servicename(talloc_tos(), lp_sub
, SNUM(conn
)));
4691 return NT_STATUS_ACCESS_DENIED
;
4694 if (file_attributes
& FILE_FLAG_POSIX_SEMANTICS
) {
4696 mode
= (mode_t
)(file_attributes
& ~FILE_FLAG_POSIX_SEMANTICS
);
4698 mode
= unix_mode(conn
,
4699 FILE_ATTRIBUTE_DIRECTORY
,
4701 parent_dir_fname
->fsp
);
4704 status
= check_parent_access_fsp(parent_dir_fname
->fsp
, access_mask
);
4705 if(!NT_STATUS_IS_OK(status
)) {
4706 DBG_INFO("check_parent_access_fsp "
4707 "on directory %s for path %s returned %s\n",
4708 smb_fname_str_dbg(parent_dir_fname
),
4709 smb_dname
->base_name
,
4715 if (lp_inherit_acls(SNUM(conn
))) {
4716 if (directory_has_default_acl_fsp(parent_dir_fname
->fsp
)) {
4717 mode
= (0777 & lp_directory_mask(SNUM(conn
)));
4719 need_tmpname
= true;
4720 } else if (lp_store_dos_attributes(SNUM(conn
))) {
4721 need_tmpname
= true;
4722 } else if (lp_inherit_permissions(SNUM(conn
))) {
4723 need_tmpname
= true;
4724 } else if (lp_inherit_owner(SNUM(conn
)) != INHERIT_OWNER_NO
) {
4725 need_tmpname
= true;
4726 } else if (lp_nt_acl_support(SNUM(conn
)) && sd
!= NULL
) {
4727 need_tmpname
= true;
4730 if (vfs_use_tmp
!= Auto
) {
4731 need_tmpname
= vfs_use_tmp
;
4734 if (!need_tmpname
) {
4735 first_atname
= smb_fname_atname
;
4740 * In order to avoid races where other clients could
4741 * see the directory before it is setup completely
4742 * we use a temporary name and rename it
4743 * when everything is ready.
4746 orig_dname
= smb_dname
->base_name
;
4748 tmp_atname
= cp_smb_filename(frame
,
4750 if (tmp_atname
== NULL
) {
4752 return NT_STATUS_NO_MEMORY
;
4754 TALLOC_FREE(tmp_atname
->base_name
);
4755 tmp_atname
->base_name
= talloc_asprintf(tmp_atname
,
4759 smb_fname_atname
->base_name
);
4760 if (tmp_atname
== NULL
) {
4762 return NT_STATUS_NO_MEMORY
;
4764 SMB_ASSERT(smbd_is_tmpname(tmp_atname
->base_name
, NULL
));
4765 if (!ISDOT(parent_dir_fname
->base_name
)) {
4766 tmp_dname
= talloc_asprintf(frame
,
4768 parent_dir_fname
->base_name
,
4769 tmp_atname
->base_name
);
4770 if (tmp_dname
== NULL
) {
4772 return NT_STATUS_NO_MEMORY
;
4775 tmp_dname
= talloc_strdup(frame
, tmp_atname
->base_name
);
4776 if (tmp_dname
== NULL
) {
4778 return NT_STATUS_NO_MEMORY
;
4782 smb_dname
->base_name
= tmp_dname
;
4784 DBG_DEBUG("temporary replace '%s' by '%s'\n",
4785 orig_dname
, tmp_dname
);
4787 first_atname
= tmp_atname
;
4790 ret
= SMB_VFS_MKDIRAT(conn
,
4791 parent_dir_fname
->fsp
,
4795 status
= map_nt_error_from_unix(errno
);
4796 DBG_NOTICE("MKDIRAT failed for '%s': %s\n",
4797 smb_fname_str_dbg(smb_dname
), nt_errstr(status
));
4802 * Make this a pathref fsp for now. open_directory() will reopen as a
4805 fsp
->fsp_flags
.is_pathref
= true;
4807 status
= fd_openat(parent_dir_fname
->fsp
, first_atname
, fsp
, &how
);
4808 if (!NT_STATUS_IS_OK(status
)) {
4809 DBG_ERR("fd_openat() failed for '%s': %s\n",
4810 smb_fname_str_dbg(smb_dname
), nt_errstr(status
));
4814 /* Ensure we're checking for a symlink here.... */
4815 /* We don't want to get caught by a symlink racer. */
4817 status
= vfs_stat_fsp(fsp
);
4818 if (!NT_STATUS_IS_OK(status
)) {
4819 DBG_ERR("Could not stat directory '%s' just created: %s\n",
4820 smb_fname_str_dbg(smb_dname
), nt_errstr(status
));
4824 if (!S_ISDIR(smb_dname
->st
.st_ex_mode
)) {
4825 DBG_ERR("Directory '%s' just created is not a directory !\n",
4826 smb_fname_str_dbg(smb_dname
));
4827 status
= NT_STATUS_NOT_A_DIRECTORY
;
4831 if (lp_store_dos_attributes(SNUM(conn
))) {
4832 file_set_dosmode(conn
,
4834 file_attributes
| FILE_ATTRIBUTE_DIRECTORY
,
4839 if (lp_inherit_permissions(SNUM(conn
))) {
4840 inherit_access_posix_acl(conn
, parent_dir_fname
->fsp
,
4842 need_re_stat
= true;
4847 * Check if high bits should have been set,
4848 * then (if bits are missing): add them.
4849 * Consider bits automagically set by UNIX, i.e. SGID bit from parent
4852 if ((mode
& ~(S_IRWXU
|S_IRWXG
|S_IRWXO
)) &&
4853 (mode
& ~smb_dname
->st
.st_ex_mode
)) {
4855 (smb_dname
->st
.st_ex_mode
|
4856 (mode
& ~smb_dname
->st
.st_ex_mode
)));
4857 need_re_stat
= true;
4861 /* Change the owner if required. */
4862 if (lp_inherit_owner(SNUM(conn
)) != INHERIT_OWNER_NO
) {
4863 change_dir_owner_to_parent_fsp(parent_dir_fname
->fsp
,
4865 need_re_stat
= true;
4869 status
= vfs_stat_fsp(fsp
);
4870 if (!NT_STATUS_IS_OK(status
)) {
4871 DBG_ERR("Could not stat directory '%s' just created: %s\n",
4872 smb_fname_str_dbg(smb_dname
), nt_errstr(status
));
4877 if (lp_nt_acl_support(SNUM(conn
))) {
4878 status
= apply_new_nt_acl(parent_dir_fname
->fsp
,
4881 if (!NT_STATUS_IS_OK(status
)) {
4882 DBG_WARNING("apply_new_nt_acl() failed for %s with %s\n",
4889 if (!need_tmpname
) {
4894 * A rename needs a valid stat for the source,
4895 * see vfs_fruit.c ...
4897 tmp_atname
->st
= smb_dname
->st
;
4900 * We first try VFS_RENAME_HOW_NO_REPLACE,
4901 * if it's implemented in the kernel,
4902 * we'll always get EEXIST if the target
4903 * exist, as it's handled at the linux vfs
4904 * layer. But if it doesn't exist we
4905 * can still get EINVAL if the actual
4906 * filesystem doesn't support RENAME_NOREPLACE.
4908 * If the kernel doesn't support rename2()
4909 * we get EINVAL instead of ENOSYS (this
4910 * is mapped in the libreplace replacement
4911 * (as well as the glibc replacement).
4913 ret
= SMB_VFS_RENAMEAT(conn
,
4914 parent_dir_fname
->fsp
,
4916 parent_dir_fname
->fsp
,
4919 if (ret
== -1 && errno
== EINVAL
) {
4921 * This is the strategie we use without having
4922 * renameat2(RENAME_NOREPLACE):
4924 * renameat() is able to replace a directory if the source is
4927 * So in order to avoid races as much as possible we do a
4928 * mkdirat() with mode 0 in order to catch EEXIST almost
4929 * atomically, when this code runs by two processes at the same
4932 * Then a renameat() makes the temporary directory available for
4935 * This a much smaller window where the other clients may see
4936 * the incomplete directory, which has a mode of 0.
4939 rhow
.flags
&= ~VFS_RENAME_HOW_NO_REPLACE
;
4941 DBG_DEBUG("MKDIRAT/RENAMEAT '%s' -> '%s'\n",
4942 tmp_dname
, orig_dname
);
4944 ret
= SMB_VFS_MKDIRAT(conn
,
4945 parent_dir_fname
->fsp
,
4949 status
= map_nt_error_from_unix(errno
);
4950 DBG_NOTICE("MKDIRAT failed for '%s': %s\n",
4951 orig_dname
, nt_errstr(status
));
4955 ret
= SMB_VFS_RENAMEAT(conn
,
4956 parent_dir_fname
->fsp
,
4958 parent_dir_fname
->fsp
,
4964 status
= map_nt_error_from_unix(errno
);
4965 DBG_NOTICE("RENAMEAT failed for '%s' -> '%s': %s\n",
4966 tmp_dname
, orig_dname
, nt_errstr(status
));
4969 smb_fname_atname
->st
= tmp_atname
->st
;
4970 smb_dname
->base_name
= orig_dname
;
4973 DBG_DEBUG("Created directory '%s'\n",
4974 smb_fname_str_dbg(smb_dname
));
4976 notify_fname(conn
, NOTIFY_ACTION_ADDED
, FILE_NOTIFY_CHANGE_DIR_NAME
,
4977 smb_dname
->base_name
);
4980 return NT_STATUS_OK
;
4983 DBG_NOTICE("%s: rollback and unlink '%s'\n",
4986 ret
= SMB_VFS_UNLINKAT(conn
,
4987 parent_dir_fname
->fsp
,
4991 DBG_NOTICE("SMB_VFS_UNLINKAT(%s): OK\n",
4994 NTSTATUS status2
= map_nt_error_from_unix(errno
);
4995 DBG_WARNING("SMB_VFS_UNLINKAT(%s) ignoring %s\n",
4996 tmp_dname
, nt_errstr(status2
));
5000 if (!need_tmpname
) {
5004 DBG_NOTICE("%s: restoring '%s' -> '%s'\n",
5008 SET_STAT_INVALID(smb_fname_atname
->st
);
5009 smb_dname
->base_name
= orig_dname
;
5010 SET_STAT_INVALID(smb_dname
->st
);
5015 /****************************************************************************
5016 Open a directory from an NT SMB call.
5017 ****************************************************************************/
5019 static NTSTATUS
open_directory(connection_struct
*conn
,
5020 struct smb_request
*req
,
5021 uint32_t access_mask
,
5022 uint32_t share_access
,
5023 uint32_t create_disposition
,
5024 uint32_t create_options
,
5025 uint32_t file_attributes
,
5026 struct smb_filename
*parent_dir_fname
,
5027 struct smb_filename
*smb_fname_atname
,
5028 struct security_descriptor
*sd
,
5030 struct files_struct
*fsp
)
5032 struct smb_filename
*smb_dname
= fsp
->fsp_name
;
5033 bool dir_existed
= VALID_STAT(smb_dname
->st
);
5034 struct open_ntcreate_lock_state lck_state
= {};
5035 bool keep_locked
= false;
5037 struct timespec mtimespec
;
5039 uint32_t need_fd_access
;
5042 if (is_ntfs_stream_smb_fname(smb_dname
)) {
5043 DEBUG(2, ("open_directory: %s is a stream name!\n",
5044 smb_fname_str_dbg(smb_dname
)));
5045 return NT_STATUS_NOT_A_DIRECTORY
;
5048 if (!(file_attributes
& FILE_FLAG_POSIX_SEMANTICS
)) {
5049 /* Ensure we have a directory attribute. */
5050 file_attributes
|= FILE_ATTRIBUTE_DIRECTORY
;
5053 DBG_INFO("opening directory %s, access_mask = 0x%"PRIx32
", "
5054 "share_access = 0x%"PRIx32
" create_options = 0x%"PRIx32
", "
5055 "create_disposition = 0x%"PRIx32
", "
5056 "file_attributes = 0x%"PRIx32
"\n",
5057 smb_fname_str_dbg(smb_dname
),
5064 status
= smbd_calculate_access_mask_fsp(parent_dir_fname
->fsp
,
5069 if (!NT_STATUS_IS_OK(status
)) {
5070 DBG_DEBUG("smbd_calculate_access_mask_fsp "
5071 "on file %s returned %s\n",
5072 smb_fname_str_dbg(smb_dname
),
5077 if ((access_mask
& SEC_FLAG_SYSTEM_SECURITY
) &&
5078 !security_token_has_privilege(get_current_nttok(conn
),
5079 SEC_PRIV_SECURITY
)) {
5080 DEBUG(10, ("open_directory: open on %s "
5081 "failed - SEC_FLAG_SYSTEM_SECURITY denied.\n",
5082 smb_fname_str_dbg(smb_dname
)));
5083 return NT_STATUS_PRIVILEGE_NOT_HELD
;
5086 switch( create_disposition
) {
5090 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
5093 info
= FILE_WAS_OPENED
;
5098 /* If directory exists error. If directory doesn't
5102 status
= NT_STATUS_OBJECT_NAME_COLLISION
;
5103 DEBUG(2, ("open_directory: unable to create "
5104 "%s. Error was %s\n",
5105 smb_fname_str_dbg(smb_dname
),
5106 nt_errstr(status
)));
5110 if (smb_fname_atname
->twrp
!= 0) {
5111 return NT_STATUS_MEDIA_WRITE_PROTECTED
;
5114 status
= mkdir_internal(conn
,
5122 if (!NT_STATUS_IS_OK(status
)) {
5123 DEBUG(2, ("open_directory: unable to create "
5124 "%s. Error was %s\n",
5125 smb_fname_str_dbg(smb_dname
),
5126 nt_errstr(status
)));
5130 info
= FILE_WAS_CREATED
;
5135 * If directory exists open. If directory doesn't
5140 status
= NT_STATUS_OK
;
5141 info
= FILE_WAS_OPENED
;
5143 if (smb_fname_atname
->twrp
!= 0) {
5144 return NT_STATUS_MEDIA_WRITE_PROTECTED
;
5146 status
= mkdir_internal(conn
,
5154 if (NT_STATUS_IS_OK(status
)) {
5155 info
= FILE_WAS_CREATED
;
5158 /* Cope with create race. */
5159 if (!NT_STATUS_EQUAL(status
,
5160 NT_STATUS_OBJECT_NAME_COLLISION
)) {
5161 DEBUG(2, ("open_directory: unable to create "
5162 "%s. Error was %s\n",
5163 smb_fname_str_dbg(smb_dname
),
5164 nt_errstr(status
)));
5169 * If mkdir_internal() returned
5170 * NT_STATUS_OBJECT_NAME_COLLISION
5171 * we still must lstat the path.
5173 ret
= SMB_VFS_FSTATAT(
5175 parent_dir_fname
->fsp
,
5178 AT_SYMLINK_NOFOLLOW
);
5180 DEBUG(2, ("Could not stat "
5181 "directory '%s' just "
5186 return map_nt_error_from_unix(
5190 info
= FILE_WAS_OPENED
;
5196 case FILE_SUPERSEDE
:
5197 case FILE_OVERWRITE
:
5198 case FILE_OVERWRITE_IF
:
5200 DEBUG(5,("open_directory: invalid create_disposition "
5201 "0x%x for directory %s\n",
5202 (unsigned int)create_disposition
,
5203 smb_fname_str_dbg(smb_dname
)));
5204 return NT_STATUS_INVALID_PARAMETER
;
5207 if(!S_ISDIR(smb_dname
->st
.st_ex_mode
)) {
5208 DEBUG(5,("open_directory: %s is not a directory !\n",
5209 smb_fname_str_dbg(smb_dname
)));
5210 return NT_STATUS_NOT_A_DIRECTORY
;
5214 * Setup the files_struct for it.
5217 fsp
->file_id
= vfs_file_id_from_sbuf(conn
, &smb_dname
->st
);
5218 fsp
->vuid
= req
? req
->vuid
: UID_FIELD_INVALID
;
5219 fsp
->file_pid
= req
? req
->smbpid
: 0;
5220 fsp
->fsp_flags
.can_lock
= false;
5221 fsp
->fsp_flags
.can_read
= false;
5222 fsp
->fsp_flags
.can_write
= false;
5224 fh_set_private_options(fsp
->fh
, 0);
5226 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
5228 fsp
->access_mask
= access_mask
| FILE_READ_ATTRIBUTES
;
5229 fsp
->print_file
= NULL
;
5230 fsp
->fsp_flags
.modified
= false;
5231 fsp
->oplock_type
= NO_OPLOCK
;
5232 fsp
->sent_oplock_break
= NO_BREAK_SENT
;
5233 fsp
->fsp_flags
.is_directory
= true;
5234 if (file_attributes
& FILE_FLAG_POSIX_SEMANTICS
) {
5235 fsp
->posix_flags
|= FSP_POSIX_FLAGS_ALL
;
5238 /* Don't store old timestamps for directory
5239 handles in the internal database. We don't
5240 update them in there if new objects
5241 are created in the directory. Currently
5242 we only update timestamps on file writes.
5245 mtimespec
= make_omit_timespec();
5248 * Obviously for FILE_LIST_DIRECTORY we need to reopen to get an fd
5249 * usable for reading a directory. SMB2_FLUSH may be called on
5250 * directories opened with FILE_ADD_FILE and FILE_ADD_SUBDIRECTORY so
5251 * for those we need to reopen as well.
5254 FILE_LIST_DIRECTORY
|
5256 FILE_ADD_SUBDIRECTORY
;
5258 if (access_mask
& need_fd_access
) {
5259 struct vfs_open_how how
= {
5260 .flags
= O_RDONLY
| O_DIRECTORY
,
5264 status
= reopen_from_fsp(parent_dir_fname
->fsp
,
5269 if (!NT_STATUS_IS_OK(status
)) {
5270 DBG_INFO("Could not open fd for [%s]: %s\n",
5271 smb_fname_str_dbg(smb_dname
),
5277 status
= vfs_stat_fsp(fsp
);
5278 if (!NT_STATUS_IS_OK(status
)) {
5283 if(!S_ISDIR(fsp
->fsp_name
->st
.st_ex_mode
)) {
5284 DEBUG(5,("open_directory: %s is not a directory !\n",
5285 smb_fname_str_dbg(smb_dname
)));
5287 return NT_STATUS_NOT_A_DIRECTORY
;
5290 /* Ensure there was no race condition. We need to check
5291 * dev/inode but not permissions, as these can change
5293 if (!check_same_dev_ino(&smb_dname
->st
, &fsp
->fsp_name
->st
)) {
5294 DEBUG(5,("open_directory: stat struct differs for "
5296 smb_fname_str_dbg(smb_dname
)));
5298 return NT_STATUS_ACCESS_DENIED
;
5301 if (info
== FILE_WAS_OPENED
) {
5302 status
= smbd_check_access_rights_fsp(parent_dir_fname
->fsp
,
5306 if (!NT_STATUS_IS_OK(status
)) {
5307 DBG_DEBUG("smbd_check_access_rights_fsp on "
5308 "file %s failed with %s\n",
5317 * If we created a new directory or going to delete it later,
5318 * we should keep * the share_mode_lock (g_lock) until we call
5319 * share_mode_entry_prepare_unlock()
5321 if (info
!= FILE_WAS_OPENED
) {
5323 } else if (create_options
& FILE_DELETE_ON_CLOSE
) {
5327 lck_state
= (struct open_ntcreate_lock_state
) {
5329 .object_type
= "directory",
5331 .create_disposition
= create_disposition
,
5332 .access_mask
= access_mask
,
5333 .share_access
= share_access
,
5334 .oplock_request
= NO_OPLOCK
,
5336 .first_open_attempt
= true,
5337 .keep_locked
= keep_locked
,
5340 status
= share_mode_entry_prepare_lock_add(&lck_state
.prepare_state
,
5345 open_ntcreate_lock_add_entry
,
5347 if (!NT_STATUS_IS_OK(status
)) {
5348 DBG_ERR("share_mode_entry_prepare_lock_add() failed for %s - %s\n",
5349 smb_fname_str_dbg(smb_dname
), nt_errstr(status
));
5354 status
= lck_state
.status
;
5355 if (!NT_STATUS_IS_OK(status
)) {
5361 * From here we need to use 'goto unlock;' instead of return !!!
5364 /* For directories the delete on close bit at open time seems
5365 always to be honored on close... See test 19 in Samba4 BASE-DELETE. */
5366 if (create_options
& FILE_DELETE_ON_CLOSE
) {
5367 status
= can_set_delete_on_close(fsp
, 0);
5368 if (!NT_STATUS_IS_OK(status
) && !NT_STATUS_EQUAL(status
, NT_STATUS_DIRECTORY_NOT_EMPTY
)) {
5369 lck_state
.cleanup_fn
=
5370 open_ntcreate_lock_cleanup_entry
;
5374 if (NT_STATUS_IS_OK(status
)) {
5375 /* Note that here we set the *initial* delete on close flag,
5376 not the regular one. The magic gets handled in close. */
5377 fsp
->fsp_flags
.initial_delete_on_close
= true;
5382 * Deal with other opens having a modified write time.
5384 if (!is_omit_timespec(&lck_state
.write_time
)) {
5385 update_stat_ex_mtime(&fsp
->fsp_name
->st
, lck_state
.write_time
);
5392 status
= NT_STATUS_OK
;
5395 ulstatus
= share_mode_entry_prepare_unlock(&lck_state
.prepare_state
,
5396 lck_state
.cleanup_fn
,
5398 if (!NT_STATUS_IS_OK(ulstatus
)) {
5399 DBG_ERR("share_mode_entry_prepare_unlock() failed for %s - %s\n",
5400 smb_fname_str_dbg(smb_dname
), nt_errstr(ulstatus
));
5401 smb_panic("share_mode_entry_prepare_unlock() failed!");
5404 if (!NT_STATUS_IS_OK(status
)) {
5409 return NT_STATUS_OK
;
5412 NTSTATUS
create_directory(connection_struct
*conn
,
5413 struct smb_request
*req
,
5414 struct files_struct
*dirfsp
,
5415 struct smb_filename
*smb_dname
)
5420 status
= SMB_VFS_CREATE_FILE(
5423 dirfsp
, /* dirfsp */
5424 smb_dname
, /* fname */
5425 FILE_READ_ATTRIBUTES
, /* access_mask */
5426 FILE_SHARE_NONE
, /* share_access */
5427 FILE_CREATE
, /* create_disposition*/
5428 FILE_DIRECTORY_FILE
, /* create_options */
5429 FILE_ATTRIBUTE_DIRECTORY
, /* file_attributes */
5430 0, /* oplock_request */
5432 0, /* allocation_size */
5433 0, /* private_flags */
5438 NULL
, NULL
); /* create context */
5440 if (NT_STATUS_IS_OK(status
)) {
5441 close_file_free(req
, &fsp
, NORMAL_CLOSE
);
5447 /****************************************************************************
5448 Receive notification that one of our open files has been renamed by another
5450 ****************************************************************************/
5452 void msg_file_was_renamed(struct messaging_context
*msg_ctx
,
5455 struct server_id src
,
5458 struct file_rename_message
*msg
= NULL
;
5459 enum ndr_err_code ndr_err
;
5461 struct smb_filename
*smb_fname
= NULL
;
5462 struct smbd_server_connection
*sconn
=
5463 talloc_get_type_abort(private_data
,
5464 struct smbd_server_connection
);
5466 msg
= talloc(talloc_tos(), struct file_rename_message
);
5468 DBG_WARNING("talloc failed\n");
5472 ndr_err
= ndr_pull_struct_blob_all(
5476 (ndr_pull_flags_fn_t
)ndr_pull_file_rename_message
);
5477 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
5478 DBG_DEBUG("ndr_pull_file_rename_message failed: %s\n",
5479 ndr_errstr(ndr_err
));
5482 if (DEBUGLEVEL
>= 10) {
5483 struct server_id_buf buf
;
5484 DBG_DEBUG("Got rename message from %s\n",
5485 server_id_str_buf(src
, &buf
));
5486 NDR_PRINT_DEBUG(file_rename_message
, msg
);
5489 /* stream_name must always be NULL if there is no stream. */
5490 if ((msg
->stream_name
!= NULL
) && (msg
->stream_name
[0] == '\0')) {
5491 msg
->stream_name
= NULL
;
5494 smb_fname
= synthetic_smb_fname(msg
,
5500 if (smb_fname
== NULL
) {
5501 DBG_DEBUG("synthetic_smb_fname failed\n");
5505 fsp
= file_find_dif(sconn
, msg
->id
, msg
->share_file_id
);
5507 DBG_DEBUG("fsp not found\n");
5511 if (strcmp(fsp
->conn
->connectpath
, msg
->servicepath
) == 0) {
5512 SMB_STRUCT_STAT fsp_orig_sbuf
;
5514 DBG_DEBUG("renaming file %s from %s -> %s\n",
5517 smb_fname_str_dbg(smb_fname
));
5520 * The incoming smb_fname here has an
5521 * invalid stat struct from synthetic_smb_fname()
5523 * Preserve the existing stat from the
5524 * open fsp after fsp_set_smb_fname()
5525 * overwrites with the invalid stat.
5527 * (We could just copy this into
5528 * smb_fname->st, but keep this code
5529 * identical to the fix in rename_open_files()
5532 * We will do an fstat before returning
5533 * any of this metadata to the client anyway.
5535 fsp_orig_sbuf
= fsp
->fsp_name
->st
;
5536 status
= fsp_set_smb_fname(fsp
, smb_fname
);
5537 if (!NT_STATUS_IS_OK(status
)) {
5538 DBG_DEBUG("fsp_set_smb_fname failed: %s\n",
5541 fsp
->fsp_name
->st
= fsp_orig_sbuf
;
5545 * Now we have the complete path we can work out if
5546 * this is actually within this share and adjust
5547 * newname accordingly.
5549 DBG_DEBUG("share mismatch (sharepath %s not sharepath %s) "
5550 "%s from %s -> %s\n",
5551 fsp
->conn
->connectpath
,
5555 smb_fname_str_dbg(smb_fname
));
5562 * If a main file is opened for delete, all streams need to be checked for
5563 * !FILE_SHARE_DELETE. Do this by opening with DELETE_ACCESS.
5564 * If that works, delete them all by setting the delete on close and close.
5567 static NTSTATUS
open_streams_for_delete(connection_struct
*conn
,
5568 const struct smb_filename
*smb_fname
)
5570 struct stream_struct
*stream_info
= NULL
;
5571 files_struct
**streams
= NULL
;
5573 unsigned int i
, num_streams
= 0;
5574 TALLOC_CTX
*frame
= talloc_stackframe();
5575 const struct smb_filename
*pathref
= NULL
;
5578 if (smb_fname
->fsp
== NULL
) {
5579 struct smb_filename
*tmp
= NULL
;
5580 status
= synthetic_pathref(frame
,
5582 smb_fname
->base_name
,
5588 if (!NT_STATUS_IS_OK(status
)) {
5589 if (NT_STATUS_EQUAL(status
, NT_STATUS_NOT_IMPLEMENTED
)
5590 || NT_STATUS_EQUAL(status
,
5591 NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
5592 DBG_DEBUG("no streams around\n");
5594 return NT_STATUS_OK
;
5596 DBG_DEBUG("synthetic_pathref failed: %s\n",
5602 pathref
= smb_fname
;
5604 status
= vfs_fstreaminfo(pathref
->fsp
, talloc_tos(),
5605 &num_streams
, &stream_info
);
5607 if (NT_STATUS_EQUAL(status
, NT_STATUS_NOT_IMPLEMENTED
)
5608 || NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
5609 DEBUG(10, ("no streams around\n"));
5611 return NT_STATUS_OK
;
5614 if (!NT_STATUS_IS_OK(status
)) {
5615 DEBUG(10, ("vfs_fstreaminfo failed: %s\n",
5616 nt_errstr(status
)));
5620 DEBUG(10, ("open_streams_for_delete found %d streams\n",
5623 if (num_streams
== 0) {
5625 return NT_STATUS_OK
;
5628 streams
= talloc_array(talloc_tos(), files_struct
*, num_streams
);
5629 if (streams
== NULL
) {
5630 DEBUG(0, ("talloc failed\n"));
5631 status
= NT_STATUS_NO_MEMORY
;
5635 for (i
=0; i
<num_streams
; i
++) {
5636 struct smb_filename
*smb_fname_cp
;
5638 if (strequal(stream_info
[i
].name
, "::$DATA")) {
5643 smb_fname_cp
= synthetic_smb_fname(talloc_tos(),
5644 smb_fname
->base_name
,
5645 stream_info
[i
].name
,
5649 ~SMB_FILENAME_POSIX_PATH
));
5650 if (smb_fname_cp
== NULL
) {
5651 status
= NT_STATUS_NO_MEMORY
;
5655 status
= openat_pathref_fsp(conn
->cwd_fsp
, smb_fname_cp
);
5656 if (!NT_STATUS_IS_OK(status
)) {
5657 DBG_DEBUG("Unable to open stream [%s]: %s\n",
5658 smb_fname_str_dbg(smb_fname_cp
),
5660 TALLOC_FREE(smb_fname_cp
);
5664 status
= SMB_VFS_CREATE_FILE(
5668 smb_fname_cp
, /* fname */
5669 DELETE_ACCESS
, /* access_mask */
5670 (FILE_SHARE_READ
| /* share_access */
5671 FILE_SHARE_WRITE
| FILE_SHARE_DELETE
),
5672 FILE_OPEN
, /* create_disposition*/
5673 0, /* create_options */
5674 FILE_ATTRIBUTE_NORMAL
, /* file_attributes */
5675 0, /* oplock_request */
5677 0, /* allocation_size */
5678 0, /* private_flags */
5681 &streams
[i
], /* result */
5683 NULL
, NULL
); /* create context */
5685 if (!NT_STATUS_IS_OK(status
)) {
5686 DEBUG(10, ("Could not open stream %s: %s\n",
5687 smb_fname_str_dbg(smb_fname_cp
),
5688 nt_errstr(status
)));
5690 TALLOC_FREE(smb_fname_cp
);
5693 TALLOC_FREE(smb_fname_cp
);
5697 * don't touch the variable "status" beyond this point :-)
5700 for (j
= i
-1 ; j
>= 0; j
--) {
5701 if (streams
[j
] == NULL
) {
5705 DEBUG(10, ("Closing stream # %d, %s\n", j
,
5706 fsp_str_dbg(streams
[j
])));
5707 close_file_free(NULL
, &streams
[j
], NORMAL_CLOSE
);
5715 /*********************************************************************
5716 Create a default ACL by inheriting from the parent. If no inheritance
5717 from the parent available, don't set anything. This will leave the actual
5718 permissions the new file or directory already got from the filesystem
5719 as the NT ACL when read.
5720 *********************************************************************/
5722 static NTSTATUS
inherit_new_acl(files_struct
*dirfsp
, files_struct
*fsp
)
5724 TALLOC_CTX
*frame
= talloc_stackframe();
5725 struct security_descriptor
*parent_desc
= NULL
;
5726 NTSTATUS status
= NT_STATUS_OK
;
5727 struct security_descriptor
*psd
= NULL
;
5728 const struct dom_sid
*owner_sid
= NULL
;
5729 const struct dom_sid
*group_sid
= NULL
;
5730 uint32_t security_info_sent
= (SECINFO_OWNER
| SECINFO_GROUP
| SECINFO_DACL
);
5731 struct security_token
*token
= fsp
->conn
->session_info
->security_token
;
5732 bool inherit_owner
=
5733 (lp_inherit_owner(SNUM(fsp
->conn
)) == INHERIT_OWNER_WINDOWS_AND_UNIX
);
5734 bool inheritable_components
= false;
5735 bool try_builtin_administrators
= false;
5736 const struct dom_sid
*BA_U_sid
= NULL
;
5737 const struct dom_sid
*BA_G_sid
= NULL
;
5738 bool try_system
= false;
5739 const struct dom_sid
*SY_U_sid
= NULL
;
5740 const struct dom_sid
*SY_G_sid
= NULL
;
5744 status
= SMB_VFS_FGET_NT_ACL(dirfsp
,
5745 (SECINFO_OWNER
| SECINFO_GROUP
| SECINFO_DACL
),
5748 if (!NT_STATUS_IS_OK(status
)) {
5753 inheritable_components
= sd_has_inheritable_components(parent_desc
,
5754 fsp
->fsp_flags
.is_directory
);
5756 if (!inheritable_components
&& !inherit_owner
) {
5758 /* Nothing to inherit and not setting owner. */
5759 return NT_STATUS_OK
;
5762 /* Create an inherited descriptor from the parent. */
5764 if (DEBUGLEVEL
>= 10) {
5765 DEBUG(10,("inherit_new_acl: parent acl for %s is:\n",
5766 fsp_str_dbg(fsp
) ));
5767 NDR_PRINT_DEBUG(security_descriptor
, parent_desc
);
5770 /* Inherit from parent descriptor if "inherit owner" set. */
5771 if (inherit_owner
) {
5772 owner_sid
= parent_desc
->owner_sid
;
5773 group_sid
= parent_desc
->group_sid
;
5776 if (owner_sid
== NULL
) {
5777 if (security_token_has_builtin_administrators(token
)) {
5778 try_builtin_administrators
= true;
5779 } else if (security_token_is_system(token
)) {
5780 try_builtin_administrators
= true;
5785 if (group_sid
== NULL
&&
5786 token
->num_sids
== PRIMARY_GROUP_SID_INDEX
)
5788 if (security_token_is_system(token
)) {
5789 try_builtin_administrators
= true;
5794 if (try_builtin_administrators
) {
5795 struct unixid ids
= { .id
= 0 };
5797 ok
= sids_to_unixids(&global_sid_Builtin_Administrators
, 1, &ids
);
5801 BA_U_sid
= &global_sid_Builtin_Administrators
;
5802 BA_G_sid
= &global_sid_Builtin_Administrators
;
5805 BA_U_sid
= &global_sid_Builtin_Administrators
;
5808 BA_G_sid
= &global_sid_Builtin_Administrators
;
5817 struct unixid ids
= { .id
= 0 };
5819 ok
= sids_to_unixids(&global_sid_System
, 1, &ids
);
5823 SY_U_sid
= &global_sid_System
;
5824 SY_G_sid
= &global_sid_System
;
5827 SY_U_sid
= &global_sid_System
;
5830 SY_G_sid
= &global_sid_System
;
5838 if (owner_sid
== NULL
) {
5839 owner_sid
= BA_U_sid
;
5842 if (owner_sid
== NULL
) {
5843 owner_sid
= SY_U_sid
;
5846 if (group_sid
== NULL
) {
5847 group_sid
= SY_G_sid
;
5850 if (try_system
&& group_sid
== NULL
) {
5851 group_sid
= BA_G_sid
;
5854 if (owner_sid
== NULL
) {
5855 owner_sid
= &token
->sids
[PRIMARY_USER_SID_INDEX
];
5857 if (group_sid
== NULL
) {
5858 if (token
->num_sids
== PRIMARY_GROUP_SID_INDEX
) {
5859 group_sid
= &token
->sids
[PRIMARY_USER_SID_INDEX
];
5861 group_sid
= &token
->sids
[PRIMARY_GROUP_SID_INDEX
];
5865 status
= se_create_child_secdesc(frame
,
5871 fsp
->fsp_flags
.is_directory
);
5872 if (!NT_STATUS_IS_OK(status
)) {
5877 /* If inheritable_components == false,
5878 se_create_child_secdesc()
5879 creates a security descriptor with a NULL dacl
5880 entry, but with SEC_DESC_DACL_PRESENT. We need
5881 to remove that flag. */
5883 if (!inheritable_components
) {
5884 security_info_sent
&= ~SECINFO_DACL
;
5885 psd
->type
&= ~SEC_DESC_DACL_PRESENT
;
5888 if (DEBUGLEVEL
>= 10) {
5889 DEBUG(10,("inherit_new_acl: child acl for %s is:\n",
5890 fsp_str_dbg(fsp
) ));
5891 NDR_PRINT_DEBUG(security_descriptor
, psd
);
5894 if (inherit_owner
) {
5895 /* We need to be root to force this. */
5898 status
= SMB_VFS_FSET_NT_ACL(metadata_fsp(fsp
),
5901 if (inherit_owner
) {
5909 * If we already have a lease, it must match the new file id. [MS-SMB2]
5910 * 3.3.5.9.8 speaks about INVALID_PARAMETER if an already used lease key is
5911 * used for a different file name.
5914 struct lease_match_state
{
5915 /* Input parameters. */
5916 TALLOC_CTX
*mem_ctx
;
5917 const char *servicepath
;
5918 const struct smb_filename
*fname
;
5921 /* Return parameters. */
5922 uint32_t num_file_ids
;
5923 struct file_id
*ids
;
5924 NTSTATUS match_status
;
5927 /*************************************************************
5928 File doesn't exist but this lease key+guid is already in use.
5930 This is only allowable in the dynamic share case where the
5931 service path must be different.
5933 There is a small race condition here in the multi-connection
5934 case where a client sends two create calls on different connections,
5935 where the file doesn't exist and one smbd creates the leases_db
5936 entry first, but this will get fixed by the multichannel cleanup
5937 when all identical client_guids get handled by a single smbd.
5938 **************************************************************/
5940 static void lease_match_parser_new_file(
5942 const struct leases_db_file
*files
,
5943 struct lease_match_state
*state
)
5947 for (i
= 0; i
< num_files
; i
++) {
5948 const struct leases_db_file
*f
= &files
[i
];
5949 if (strequal(state
->servicepath
, f
->servicepath
)) {
5950 state
->match_status
= NT_STATUS_INVALID_PARAMETER
;
5955 /* Dynamic share case. Break leases on all other files. */
5956 state
->match_status
= leases_db_copy_file_ids(state
->mem_ctx
,
5960 if (!NT_STATUS_IS_OK(state
->match_status
)) {
5964 state
->num_file_ids
= num_files
;
5965 state
->match_status
= NT_STATUS_OPLOCK_NOT_GRANTED
;
5969 static void lease_match_parser(
5971 const struct leases_db_file
*files
,
5974 struct lease_match_state
*state
=
5975 (struct lease_match_state
*)private_data
;
5978 if (!state
->file_existed
) {
5980 * Deal with name mismatch or
5981 * possible dynamic share case separately
5982 * to make code clearer.
5984 lease_match_parser_new_file(num_files
,
5991 state
->match_status
= NT_STATUS_OK
;
5993 for (i
= 0; i
< num_files
; i
++) {
5994 const struct leases_db_file
*f
= &files
[i
];
5996 /* Everything should be the same. */
5997 if (!file_id_equal(&state
->id
, &f
->id
)) {
5999 * The client asked for a lease on a
6000 * file that doesn't match the file_id
6003 * Maybe this is a dynamic share, i.e.
6004 * a share where the servicepath is
6005 * different for different users (e.g.
6006 * the [HOMES] share.
6008 * If the servicepath is different, but the requested
6009 * file name + stream name is the same then this is
6010 * a dynamic share, the client is using the same share
6011 * name and doesn't know that the underlying servicepath
6012 * is different. It was expecting a lease on the
6013 * same file. Return NT_STATUS_OPLOCK_NOT_GRANTED
6016 * Otherwise the client has messed up, or is
6017 * testing our error codes, so return
6018 * NT_STATUS_INVALID_PARAMETER.
6020 if (!strequal(f
->servicepath
, state
->servicepath
) &&
6021 strequal(f
->base_name
, state
->fname
->base_name
) &&
6022 strequal(f
->stream_name
, state
->fname
->stream_name
))
6025 * Name is the same but servicepath is
6026 * different, dynamic share. Break leases.
6028 state
->match_status
=
6029 NT_STATUS_OPLOCK_NOT_GRANTED
;
6031 state
->match_status
=
6032 NT_STATUS_INVALID_PARAMETER
;
6036 if (!strequal(f
->servicepath
, state
->servicepath
)) {
6037 state
->match_status
= NT_STATUS_INVALID_PARAMETER
;
6040 if (!strequal(f
->base_name
, state
->fname
->base_name
)) {
6041 state
->match_status
= NT_STATUS_INVALID_PARAMETER
;
6044 if (!strequal(f
->stream_name
, state
->fname
->stream_name
)) {
6045 state
->match_status
= NT_STATUS_INVALID_PARAMETER
;
6050 if (NT_STATUS_IS_OK(state
->match_status
)) {
6052 * Common case - just opening another handle on a
6053 * file on a non-dynamic share.
6058 if (NT_STATUS_EQUAL(state
->match_status
, NT_STATUS_INVALID_PARAMETER
)) {
6059 /* Mismatched path. Error back to client. */
6064 * File id mismatch. Dynamic share case NT_STATUS_OPLOCK_NOT_GRANTED.
6065 * Don't allow leases.
6068 state
->match_status
= leases_db_copy_file_ids(state
->mem_ctx
,
6072 if (!NT_STATUS_IS_OK(state
->match_status
)) {
6076 state
->num_file_ids
= num_files
;
6077 state
->match_status
= NT_STATUS_OPLOCK_NOT_GRANTED
;
6081 struct lease_match_break_state
{
6082 struct messaging_context
*msg_ctx
;
6083 const struct smb2_lease_key
*lease_key
;
6091 static bool lease_match_break_fn(
6092 struct share_mode_entry
*e
,
6095 struct lease_match_break_state
*state
= private_data
;
6097 uint32_t e_lease_type
= SMB2_LEASE_NONE
;
6100 stale
= share_entry_stale_pid(e
);
6105 equal
= smb2_lease_key_equal(&e
->lease_key
, state
->lease_key
);
6110 status
= leases_db_get(
6114 &e_lease_type
, /* current_state */
6115 NULL
, /* breaking */
6116 NULL
, /* breaking_to_requested */
6117 NULL
, /* breaking_to_required */
6118 &state
->version
, /* lease_version */
6119 &state
->epoch
); /* epoch */
6120 if (NT_STATUS_IS_OK(status
)) {
6121 state
->found_lease
= true;
6123 DBG_WARNING("Could not find version/epoch: %s\n",
6128 if (e_lease_type
== SMB2_LEASE_NONE
) {
6131 send_break_message(state
->msg_ctx
, &state
->id
, e
, SMB2_LEASE_NONE
);
6134 * Windows 7 and 8 lease clients are broken in that they will
6135 * not respond to lease break requests whilst waiting for an
6136 * outstanding open request on that lease handle on the same
6137 * TCP connection, due to holding an internal inode lock.
6139 * This means we can't reschedule ourselves here, but must
6140 * return from the create.
6144 * Send the breaks and then return SMB2_LEASE_NONE in the
6145 * lease handle to cause them to acknowledge the lease
6146 * break. Consultation with Microsoft engineering confirmed
6147 * this approach is safe.
6153 static void lease_match_fid_fn(struct share_mode_lock
*lck
,
6158 ok
= share_mode_forall_leases(lck
, lease_match_break_fn
, private_data
);
6160 DBG_DEBUG("share_mode_forall_leases failed\n");
6164 static NTSTATUS
lease_match(connection_struct
*conn
,
6165 struct smb_request
*req
,
6166 const struct smb2_lease_key
*lease_key
,
6167 const char *servicepath
,
6168 const struct smb_filename
*fname
,
6169 uint16_t *p_version
,
6172 struct smbd_server_connection
*sconn
= req
->sconn
;
6173 TALLOC_CTX
*tos
= talloc_tos();
6174 struct lease_match_state state
= {
6176 .servicepath
= servicepath
,
6178 .match_status
= NT_STATUS_OK
6183 state
.file_existed
= VALID_STAT(fname
->st
);
6184 if (state
.file_existed
) {
6185 state
.id
= vfs_file_id_from_sbuf(conn
, &fname
->st
);
6188 status
= leases_db_parse(&sconn
->client
->global
->client_guid
,
6189 lease_key
, lease_match_parser
, &state
);
6190 if (!NT_STATUS_IS_OK(status
)) {
6192 * Not found or error means okay: We can make the lease pass
6194 return NT_STATUS_OK
;
6196 if (!NT_STATUS_EQUAL(state
.match_status
, NT_STATUS_OPLOCK_NOT_GRANTED
)) {
6198 * Anything but NT_STATUS_OPLOCK_NOT_GRANTED, let the caller
6201 return state
.match_status
;
6204 /* We have to break all existing leases. */
6205 for (i
= 0; i
< state
.num_file_ids
; i
++) {
6206 struct lease_match_break_state break_state
= {
6207 .msg_ctx
= conn
->sconn
->msg_ctx
,
6208 .lease_key
= lease_key
,
6211 if (file_id_equal(&state
.ids
[i
], &state
.id
)) {
6212 /* Don't need to break our own file. */
6216 break_state
.id
= state
.ids
[i
];
6218 status
= share_mode_do_locked_vfs_denied(break_state
.id
,
6221 if (!NT_STATUS_IS_OK(status
)) {
6222 /* Race condition - file already closed. */
6226 if (break_state
.found_lease
) {
6227 *p_version
= break_state
.version
;
6228 *p_epoch
= break_state
.epoch
;
6232 * Ensure we don't grant anything more so we
6235 return NT_STATUS_OPLOCK_NOT_GRANTED
;
6239 * Wrapper around open_file_ntcreate and open_directory
6242 static NTSTATUS
create_file_unixpath(connection_struct
*conn
,
6243 struct smb_request
*req
,
6244 struct files_struct
*dirfsp
,
6245 struct smb_filename
*smb_fname
,
6246 uint32_t access_mask
,
6247 uint32_t share_access
,
6248 uint32_t create_disposition
,
6249 uint32_t create_options
,
6250 uint32_t file_attributes
,
6251 uint32_t oplock_request
,
6252 const struct smb2_lease
*lease
,
6253 uint64_t allocation_size
,
6254 uint32_t private_flags
,
6255 struct security_descriptor
*sd
,
6256 struct ea_list
*ea_list
,
6258 files_struct
**result
,
6261 struct smb2_lease none_lease
;
6262 int info
= FILE_WAS_OPENED
;
6263 files_struct
*base_fsp
= NULL
;
6264 files_struct
*fsp
= NULL
;
6265 bool free_fsp_on_error
= false;
6268 struct smb_filename
*parent_dir_fname
= NULL
;
6269 struct smb_filename
*smb_fname_atname
= NULL
;
6271 DBG_DEBUG("access_mask = 0x%"PRIx32
" "
6272 "file_attributes = 0x%"PRIx32
" "
6273 "share_access = 0x%"PRIx32
" "
6274 "create_disposition = 0x%"PRIx32
" "
6275 "create_options = 0x%"PRIx32
" "
6276 "oplock_request = 0x%"PRIx32
" "
6277 "private_flags = 0x%"PRIx32
" "
6290 smb_fname_str_dbg(smb_fname
));
6292 if (create_options
& FILE_OPEN_BY_FILE_ID
) {
6293 status
= NT_STATUS_NOT_SUPPORTED
;
6297 if (create_options
& NTCREATEX_OPTIONS_INVALID_PARAM_MASK
) {
6298 status
= NT_STATUS_INVALID_PARAMETER
;
6302 if (!(create_options
& FILE_OPEN_REPARSE_POINT
) &&
6303 (smb_fname
->fsp
!= NULL
) && /* new files don't have an fsp */
6304 VALID_STAT(smb_fname
->fsp
->fsp_name
->st
))
6306 mode_t type
= (smb_fname
->fsp
->fsp_name
->st
.st_ex_mode
&
6316 * We should never get this far with a symlink
6317 * "as such". Report as not existing.
6319 status
= NT_STATUS_OBJECT_NAME_NOT_FOUND
;
6322 status
= NT_STATUS_IO_REPARSE_TAG_NOT_HANDLED
;
6328 oplock_request
|= INTERNAL_OPEN_ONLY
;
6331 if (lease
!= NULL
) {
6332 uint16_t epoch
= lease
->lease_epoch
;
6333 uint16_t version
= lease
->lease_version
;
6336 DBG_WARNING("Got lease on internal open\n");
6337 status
= NT_STATUS_INTERNAL_ERROR
;
6341 status
= lease_match(conn
,
6348 if (NT_STATUS_EQUAL(status
, NT_STATUS_OPLOCK_NOT_GRANTED
)) {
6349 /* Dynamic share file. No leases and update epoch... */
6350 none_lease
= *lease
;
6351 none_lease
.lease_state
= SMB2_LEASE_NONE
;
6352 none_lease
.lease_epoch
= epoch
;
6353 none_lease
.lease_version
= version
;
6354 lease
= &none_lease
;
6355 } else if (!NT_STATUS_IS_OK(status
)) {
6360 if ((conn
->fs_capabilities
& FILE_NAMED_STREAMS
)
6361 && (access_mask
& DELETE_ACCESS
)
6362 && !is_named_stream(smb_fname
)) {
6364 * We can't open a file with DELETE access if any of the
6365 * streams is open without FILE_SHARE_DELETE
6367 status
= open_streams_for_delete(conn
, smb_fname
);
6369 if (!NT_STATUS_IS_OK(status
)) {
6374 if (access_mask
& SEC_FLAG_SYSTEM_SECURITY
) {
6377 ok
= security_token_has_privilege(get_current_nttok(conn
),
6380 DBG_DEBUG("open on %s failed - "
6381 "SEC_FLAG_SYSTEM_SECURITY denied.\n",
6382 smb_fname_str_dbg(smb_fname
));
6383 status
= NT_STATUS_PRIVILEGE_NOT_HELD
;
6387 if (conn_using_smb2(conn
->sconn
) &&
6388 (access_mask
== SEC_FLAG_SYSTEM_SECURITY
))
6391 * No other bits set. Windows SMB2 refuses this.
6392 * See smbtorture3 SMB2-SACL test.
6394 * Note this is an SMB2-only behavior,
6395 * smbtorture3 SMB1-SYSTEM-SECURITY already tests
6396 * that SMB1 allows this.
6398 status
= NT_STATUS_ACCESS_DENIED
;
6404 * Files or directories can't be opened DELETE_ON_CLOSE without
6406 * BUG: https://bugzilla.samba.org/show_bug.cgi?id=13358
6408 if ((create_options
& FILE_DELETE_ON_CLOSE
) &&
6409 ((access_mask
& DELETE_ACCESS
) == 0)) {
6410 status
= NT_STATUS_INVALID_PARAMETER
;
6414 if ((conn
->fs_capabilities
& FILE_NAMED_STREAMS
)
6415 && is_named_stream(smb_fname
))
6417 uint32_t base_create_disposition
;
6418 struct smb_filename
*smb_fname_base
= NULL
;
6419 uint32_t base_privflags
;
6421 if (create_options
& FILE_DIRECTORY_FILE
) {
6422 DBG_DEBUG("Can't open a stream as directory\n");
6423 status
= NT_STATUS_NOT_A_DIRECTORY
;
6427 switch (create_disposition
) {
6429 base_create_disposition
= FILE_OPEN
;
6432 base_create_disposition
= FILE_OPEN_IF
;
6436 smb_fname_base
= cp_smb_filename_nostream(
6437 talloc_tos(), smb_fname
);
6439 if (smb_fname_base
== NULL
) {
6440 status
= NT_STATUS_NO_MEMORY
;
6445 * We may be creating the basefile as part of creating the
6446 * stream, so it's legal if the basefile doesn't exist at this
6447 * point, the create_file_unixpath() below will create it. But
6448 * if the basefile exists we want a handle so we can fstat() it.
6451 ret
= vfs_stat(conn
, smb_fname_base
);
6452 if (ret
== -1 && errno
!= ENOENT
) {
6453 status
= map_nt_error_from_unix(errno
);
6454 TALLOC_FREE(smb_fname_base
);
6458 status
= openat_pathref_fsp(conn
->cwd_fsp
,
6460 if (!NT_STATUS_IS_OK(status
)) {
6461 DBG_ERR("open_smb_fname_fsp [%s] failed: %s\n",
6462 smb_fname_str_dbg(smb_fname_base
),
6464 TALLOC_FREE(smb_fname_base
);
6469 * https://bugzilla.samba.org/show_bug.cgi?id=10229
6470 * We need to check if the requested access mask
6471 * could be used to open the underlying file (if
6472 * it existed), as we're passing in zero for the
6473 * access mask to the base filename.
6475 status
= check_base_file_access(smb_fname_base
->fsp
,
6478 if (!NT_STATUS_IS_OK(status
)) {
6479 DEBUG(10, ("Permission check "
6480 "for base %s failed: "
6481 "%s\n", smb_fname
->base_name
,
6482 nt_errstr(status
)));
6483 TALLOC_FREE(smb_fname_base
);
6488 base_privflags
= NTCREATEX_FLAG_STREAM_BASEOPEN
;
6490 /* Open the base file. */
6491 status
= create_file_unixpath(conn
,
6498 | FILE_SHARE_DELETE
,
6499 base_create_disposition
,
6510 TALLOC_FREE(smb_fname_base
);
6512 if (!NT_STATUS_IS_OK(status
)) {
6513 DEBUG(10, ("create_file_unixpath for base %s failed: "
6514 "%s\n", smb_fname
->base_name
,
6515 nt_errstr(status
)));
6520 if (smb_fname
->fsp
!= NULL
) {
6522 fsp
= smb_fname
->fsp
;
6525 * We're about to use smb_fname->fsp for the fresh open.
6527 * Every fsp passed in via smb_fname->fsp already
6528 * holds a fsp->fsp_name. If it is already this
6529 * fsp->fsp_name that we got passed in as our input
6530 * argument smb_fname, these two are assumed to have
6531 * the same lifetime: Every fsp hangs of "conn", and
6532 * fsp->fsp_name is its talloc child.
6535 if (smb_fname
!= smb_fname
->fsp
->fsp_name
) {
6537 * "smb_fname" is temporary in this case, but
6538 * the destructor of smb_fname would also tear
6539 * down the fsp we're about to use. Unlink
6540 * them from each other.
6542 smb_fname_fsp_unlink(smb_fname
);
6547 free_fsp_on_error
= true;
6550 status
= fsp_bind_smb(fsp
, req
);
6551 if (!NT_STATUS_IS_OK(status
)) {
6555 if (fsp_is_alternate_stream(fsp
)) {
6556 struct files_struct
*tmp_base_fsp
= fsp
->base_fsp
;
6558 fsp_set_base_fsp(fsp
, NULL
);
6560 fd_close(tmp_base_fsp
);
6561 file_free(NULL
, tmp_base_fsp
);
6565 * No fsp passed in that we can use, create one
6567 status
= file_new(req
, conn
, &fsp
);
6568 if(!NT_STATUS_IS_OK(status
)) {
6571 free_fsp_on_error
= true;
6573 status
= fsp_set_smb_fname(fsp
, smb_fname
);
6574 if (!NT_STATUS_IS_OK(status
)) {
6579 SMB_ASSERT(fsp
->fsp_name
->fsp
!= NULL
);
6580 SMB_ASSERT(fsp
->fsp_name
->fsp
== fsp
);
6584 * We're opening the stream element of a
6585 * base_fsp we already opened. Set up the
6588 fsp_set_base_fsp(fsp
, base_fsp
);
6591 if (dirfsp
!= NULL
) {
6592 status
= SMB_VFS_PARENT_PATHNAME(
6598 if (!NT_STATUS_IS_OK(status
)) {
6603 * Get a pathref on the parent. We can re-use this for
6604 * multiple calls to check parent ACLs etc. to avoid
6607 status
= parent_pathref(talloc_tos(),
6612 if (!NT_STATUS_IS_OK(status
)) {
6616 dirfsp
= parent_dir_fname
->fsp
;
6617 status
= fsp_set_smb_fname(dirfsp
, parent_dir_fname
);
6618 if (!NT_STATUS_IS_OK(status
)) {
6624 * If it's a request for a directory open, deal with it separately.
6627 if (create_options
& FILE_DIRECTORY_FILE
) {
6629 if (create_options
& FILE_NON_DIRECTORY_FILE
) {
6630 status
= NT_STATUS_INVALID_PARAMETER
;
6634 /* Can't open a temp directory. IFS kit test. */
6635 if (!(file_attributes
& FILE_FLAG_POSIX_SEMANTICS
) &&
6636 (file_attributes
& FILE_ATTRIBUTE_TEMPORARY
)) {
6637 status
= NT_STATUS_INVALID_PARAMETER
;
6642 * We will get a create directory here if the Win32
6643 * app specified a security descriptor in the
6644 * CreateDirectory() call.
6648 status
= open_directory(conn
,
6663 * Ordinary file case.
6666 if (allocation_size
) {
6667 fsp
->initial_allocation_size
= smb_roundup(fsp
->conn
,
6671 status
= open_file_ntcreate(conn
,
6685 if (NT_STATUS_EQUAL(status
, NT_STATUS_FILE_IS_A_DIRECTORY
)) {
6687 /* A stream open never opens a directory */
6690 status
= NT_STATUS_FILE_IS_A_DIRECTORY
;
6695 * Fail the open if it was explicitly a non-directory
6699 if (create_options
& FILE_NON_DIRECTORY_FILE
) {
6700 status
= NT_STATUS_FILE_IS_A_DIRECTORY
;
6705 status
= open_directory(conn
,
6720 if (!NT_STATUS_IS_OK(status
)) {
6724 fsp
->fsp_flags
.is_fsa
= true;
6726 if ((ea_list
!= NULL
) &&
6727 ((info
== FILE_WAS_CREATED
) || (info
== FILE_WAS_OVERWRITTEN
))) {
6728 status
= set_ea(conn
, fsp
, ea_list
);
6729 if (!NT_STATUS_IS_OK(status
)) {
6734 if (!fsp
->fsp_flags
.is_directory
&&
6735 S_ISDIR(fsp
->fsp_name
->st
.st_ex_mode
))
6737 status
= NT_STATUS_ACCESS_DENIED
;
6741 /* Save the requested allocation size. */
6742 if ((info
== FILE_WAS_CREATED
) || (info
== FILE_WAS_OVERWRITTEN
)) {
6743 if ((allocation_size
> (uint64_t)fsp
->fsp_name
->st
.st_ex_size
)
6744 && !(fsp
->fsp_flags
.is_directory
))
6746 fsp
->initial_allocation_size
= smb_roundup(
6747 fsp
->conn
, allocation_size
);
6748 if (vfs_allocate_file_space(
6749 fsp
, fsp
->initial_allocation_size
) == -1) {
6750 status
= NT_STATUS_DISK_FULL
;
6754 fsp
->initial_allocation_size
= smb_roundup(
6755 fsp
->conn
, (uint64_t)fsp
->fsp_name
->st
.st_ex_size
);
6758 fsp
->initial_allocation_size
= 0;
6761 if ((info
== FILE_WAS_CREATED
) &&
6762 !S_ISDIR(fsp
->fsp_name
->st
.st_ex_mode
) &&
6763 lp_nt_acl_support(SNUM(conn
)) &&
6764 !fsp_is_alternate_stream(fsp
)) {
6765 status
= apply_new_nt_acl(dirfsp
, fsp
, sd
);
6766 if (!NT_STATUS_IS_OK(status
)) {
6767 DBG_WARNING("apply_new_nt_acl(): failed for %s with %s\n",
6768 fsp_str_dbg(fsp
), nt_errstr(status
));
6773 if ((conn
->fs_capabilities
& FILE_FILE_COMPRESSION
)
6774 && (create_options
& FILE_NO_COMPRESSION
)
6775 && (info
== FILE_WAS_CREATED
)) {
6776 status
= SMB_VFS_SET_COMPRESSION(conn
, fsp
, fsp
,
6777 COMPRESSION_FORMAT_NONE
);
6778 if (!NT_STATUS_IS_OK(status
)) {
6779 DEBUG(1, ("failed to disable compression: %s\n",
6780 nt_errstr(status
)));
6784 DEBUG(10, ("create_file_unixpath: info=%d\n", info
));
6787 if (pinfo
!= NULL
) {
6791 smb_fname
->st
= fsp
->fsp_name
->st
;
6793 TALLOC_FREE(parent_dir_fname
);
6795 return NT_STATUS_OK
;
6798 DEBUG(10, ("create_file_unixpath: %s\n", nt_errstr(status
)));
6802 * The close_file below will close
6806 close_file_smb(req
, fsp
, ERROR_CLOSE
);
6807 if (free_fsp_on_error
) {
6808 file_free(req
, fsp
);
6812 if (base_fsp
!= NULL
) {
6813 close_file_free(req
, &base_fsp
, ERROR_CLOSE
);
6816 TALLOC_FREE(parent_dir_fname
);
6821 NTSTATUS
create_file_default(connection_struct
*conn
,
6822 struct smb_request
*req
,
6823 struct files_struct
*dirfsp
,
6824 struct smb_filename
*smb_fname
,
6825 uint32_t access_mask
,
6826 uint32_t share_access
,
6827 uint32_t create_disposition
,
6828 uint32_t create_options
,
6829 uint32_t file_attributes
,
6830 uint32_t oplock_request
,
6831 const struct smb2_lease
*lease
,
6832 uint64_t allocation_size
,
6833 uint32_t private_flags
,
6834 struct security_descriptor
*sd
,
6835 struct ea_list
*ea_list
,
6836 files_struct
**result
,
6838 const struct smb2_create_blobs
*in_context_blobs
,
6839 struct smb2_create_blobs
*out_context_blobs
)
6841 int info
= FILE_WAS_OPENED
;
6842 files_struct
*fsp
= NULL
;
6844 bool stream_name
= false;
6845 struct smb2_create_blob
*posx
= NULL
;
6847 DBG_DEBUG("access_mask = 0x%" PRIu32
6848 " file_attributes = 0x%" PRIu32
6849 " share_access = 0x%" PRIu32
6850 " create_disposition = 0x%" PRIu32
6851 " create_options = 0x%" PRIu32
6852 " oplock_request = 0x%" PRIu32
6853 " private_flags = 0x%" PRIu32
6854 " ea_list = %p, sd = %p, fname = %s\n",
6864 smb_fname_str_dbg(smb_fname
));
6868 * Remember the absolute time of the original request
6869 * with this mid. We'll use it later to see if this
6872 get_deferred_open_message_state(req
, &req
->request_time
, NULL
);
6876 * Check to see if this is a mac fork of some kind.
6879 stream_name
= is_ntfs_stream_smb_fname(smb_fname
);
6881 enum FAKE_FILE_TYPE fake_file_type
;
6883 fake_file_type
= is_fake_file(smb_fname
);
6885 if (req
!= NULL
&& fake_file_type
!= FAKE_FILE_TYPE_NONE
) {
6888 * Here we go! support for changing the disk quotas
6891 * We need to fake up to open this MAGIC QUOTA file
6892 * and return a valid FID.
6894 * w2k close this file directly after opening xp
6895 * also tries a QUERY_FILE_INFO on the file and then
6898 status
= open_fake_file(req
, conn
, req
->vuid
,
6899 fake_file_type
, smb_fname
,
6901 if (!NT_STATUS_IS_OK(status
)) {
6905 ZERO_STRUCT(smb_fname
->st
);
6909 if (!(conn
->fs_capabilities
& FILE_NAMED_STREAMS
)) {
6910 status
= NT_STATUS_OBJECT_NAME_INVALID
;
6915 if (is_ntfs_default_stream_smb_fname(smb_fname
)) {
6917 /* We have to handle this error here. */
6918 if (create_options
& FILE_DIRECTORY_FILE
) {
6919 status
= NT_STATUS_NOT_A_DIRECTORY
;
6922 ret
= vfs_stat(conn
, smb_fname
);
6923 if (ret
== 0 && VALID_STAT_OF_DIR(smb_fname
->st
)) {
6924 status
= NT_STATUS_FILE_IS_A_DIRECTORY
;
6929 posx
= smb2_create_blob_find(
6930 in_context_blobs
, SMB2_CREATE_TAG_POSIX
);
6932 uint32_t wire_mode_bits
= 0;
6933 mode_t mode_bits
= 0;
6934 SMB_STRUCT_STAT sbuf
= { 0 };
6935 enum perm_type ptype
=
6936 (create_options
& FILE_DIRECTORY_FILE
) ?
6937 PERM_NEW_DIR
: PERM_NEW_FILE
;
6939 if (posx
->data
.length
!= 4) {
6940 status
= NT_STATUS_INVALID_PARAMETER
;
6944 wire_mode_bits
= IVAL(posx
->data
.data
, 0);
6945 status
= unix_perms_from_wire(
6946 conn
, &sbuf
, wire_mode_bits
, ptype
, &mode_bits
);
6947 if (!NT_STATUS_IS_OK(status
)) {
6951 * Remove type info from mode, leaving only the
6952 * permissions and setuid/gid bits.
6954 mode_bits
&= ~S_IFMT
;
6956 file_attributes
= (FILE_FLAG_POSIX_SEMANTICS
| mode_bits
);
6959 status
= create_file_unixpath(conn
,
6976 if (!NT_STATUS_IS_OK(status
)) {
6981 DEBUG(10, ("create_file: info=%d\n", info
));
6984 if (pinfo
!= NULL
) {
6987 return NT_STATUS_OK
;
6990 DEBUG(10, ("create_file: %s\n", nt_errstr(status
)));
6993 close_file_free(req
, &fsp
, ERROR_CLOSE
);