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 extern const struct generic_mapping file_generic_mapping;
48 struct deferred_open_record {
49 struct smbXsrv_connection *xconn;
55 * Timer for async opens, needed because they don't use a watch on
56 * a locking.tdb record. This is currently only used for real async
57 * opens and just terminates smbd if the async open times out.
59 struct tevent_timer *te;
62 * For the samba kernel oplock case we use both a timeout and
63 * a watch on locking.tdb. This way in case it's smbd holding
64 * the kernel oplock we get directly notified for the retry
65 * once the kernel oplock is properly broken. Store the req
66 * here so that it can be timely discarded once the timer
69 struct tevent_req *watch_req;
72 /****************************************************************************
73 If the requester wanted DELETE_ACCESS and was rejected because
74 the file ACL didn't include DELETE_ACCESS, see if the parent ACL
76 ****************************************************************************/
78 static bool parent_override_delete(connection_struct *conn,
79 struct files_struct *dirfsp,
80 const struct smb_filename *smb_fname,
82 uint32_t rejected_mask)
84 if ((access_mask & DELETE_ACCESS) &&
85 (rejected_mask & DELETE_ACCESS) &&
86 can_delete_file_in_directory(conn,
95 /****************************************************************************
96 Check if we have open rights.
97 ****************************************************************************/
99 static NTSTATUS smbd_check_access_rights_fname(
100 struct connection_struct *conn,
101 const struct smb_filename *smb_fname,
103 uint32_t access_mask,
104 uint32_t do_not_check_mask)
106 uint32_t rejected_share_access;
107 uint32_t effective_access;
109 rejected_share_access = access_mask & ~(conn->share_access);
111 if (rejected_share_access) {
112 DBG_DEBUG("rejected share access 0x%"PRIx32" on "
113 "%s (0x%"PRIx32")\n",
115 smb_fname_str_dbg(smb_fname),
116 rejected_share_access);
117 return NT_STATUS_ACCESS_DENIED;
120 effective_access = access_mask & ~do_not_check_mask;
121 if (effective_access == 0) {
122 DBG_DEBUG("do_not_check_mask override on %s. Granting 0x%x for free.\n",
123 smb_fname_str_dbg(smb_fname),
124 (unsigned int)access_mask);
128 if (!use_privs && get_current_uid(conn) == (uid_t)0) {
129 /* I'm sorry sir, I didn't know you were root... */
130 DBG_DEBUG("root override on %s. Granting 0x%x\n",
131 smb_fname_str_dbg(smb_fname),
132 (unsigned int)access_mask);
136 if ((access_mask & DELETE_ACCESS) &&
137 !lp_acl_check_permissions(SNUM(conn)))
139 DBG_DEBUG("Not checking ACL on DELETE_ACCESS on file %s. "
140 "Granting 0x%"PRIx32"\n",
141 smb_fname_str_dbg(smb_fname),
146 if (access_mask == DELETE_ACCESS &&
147 VALID_STAT(smb_fname->st) &&
148 S_ISLNK(smb_fname->st.st_ex_mode))
150 /* We can always delete a symlink. */
151 DBG_DEBUG("Not checking ACL on DELETE_ACCESS on symlink %s.\n",
152 smb_fname_str_dbg(smb_fname));
156 return NT_STATUS_MORE_PROCESSING_REQUIRED;
159 static NTSTATUS smbd_check_access_rights_sd(
160 struct connection_struct *conn,
161 struct files_struct *dirfsp,
162 const struct smb_filename *smb_fname,
163 struct security_descriptor *sd,
165 uint32_t access_mask,
166 uint32_t do_not_check_mask)
168 uint32_t rejected_mask = access_mask;
175 status = se_file_access_check(sd,
176 get_current_nttok(conn),
178 (access_mask & ~do_not_check_mask),
181 DBG_DEBUG("File [%s] requesting [0x%"PRIx32"] "
182 "returning [0x%"PRIx32"] (%s)\n",
183 smb_fname_str_dbg(smb_fname),
188 if (!NT_STATUS_IS_OK(status)) {
189 if (DEBUGLEVEL >= 10) {
190 DBG_DEBUG("acl for %s is:\n",
191 smb_fname_str_dbg(smb_fname));
192 NDR_PRINT_DEBUG(security_descriptor, sd);
198 if (NT_STATUS_IS_OK(status) ||
199 !NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED))
204 /* Here we know status == NT_STATUS_ACCESS_DENIED. */
208 if ((access_mask & FILE_WRITE_ATTRIBUTES) &&
209 (rejected_mask & FILE_WRITE_ATTRIBUTES) &&
210 !lp_store_dos_attributes(SNUM(conn)) &&
211 (lp_map_readonly(SNUM(conn)) ||
212 lp_map_archive(SNUM(conn)) ||
213 lp_map_hidden(SNUM(conn)) ||
214 lp_map_system(SNUM(conn))))
216 rejected_mask &= ~FILE_WRITE_ATTRIBUTES;
218 DBG_DEBUG("overrode FILE_WRITE_ATTRIBUTES on file %s\n",
219 smb_fname_str_dbg(smb_fname));
222 if (parent_override_delete(conn,
229 * Were we trying to do an open for delete and didn't get DELETE
230 * access. Check if the directory allows DELETE_CHILD.
232 * http://blogs.msdn.com/oldnewthing/archive/2004/06/04/148426.aspx
236 rejected_mask &= ~DELETE_ACCESS;
238 DBG_DEBUG("Overrode DELETE_ACCESS on file %s\n",
239 smb_fname_str_dbg(smb_fname));
242 if (rejected_mask != 0) {
243 return NT_STATUS_ACCESS_DENIED;
248 NTSTATUS smbd_check_access_rights_fsp(struct files_struct *dirfsp,
249 struct files_struct *fsp,
251 uint32_t access_mask)
253 struct security_descriptor *sd = NULL;
254 uint32_t do_not_check_mask = 0;
257 /* Cope with fake/printer fsp's. */
258 if (fsp->fake_file_handle != NULL || fsp->print_file != NULL) {
259 if ((fsp->access_mask & access_mask) != access_mask) {
260 return NT_STATUS_ACCESS_DENIED;
265 if (fsp_get_pathref_fd(fsp) == -1) {
267 * This is a POSIX open on a symlink. For the pathname
268 * version of this function we used to return the st_mode
269 * bits turned into an NT ACL. For a symlink the mode bits
270 * are always rwxrwxrwx which means the pathname version always
271 * returned NT_STATUS_OK for a symlink. For the handle reference
272 * to a symlink use the handle access bits.
274 if ((fsp->access_mask & access_mask) != access_mask) {
275 return NT_STATUS_ACCESS_DENIED;
281 * If we can access the path to this file, by
282 * default we have FILE_READ_ATTRIBUTES from the
283 * containing directory. See the section:
284 * "Algorithm to Check Access to an Existing File"
287 * se_file_access_check() also takes care of
288 * owner WRITE_DAC and READ_CONTROL.
290 do_not_check_mask = FILE_READ_ATTRIBUTES;
293 * Samba 3.6 and earlier granted execute access even
294 * if the ACL did not contain execute rights.
295 * Samba 4.0 is more correct and checks it.
296 * The compatibility mode allows one to skip this check
297 * to smoothen upgrades.
299 if (lp_acl_allow_execute_always(SNUM(fsp->conn))) {
300 do_not_check_mask |= FILE_EXECUTE;
303 status = smbd_check_access_rights_fname(fsp->conn,
308 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
312 status = SMB_VFS_FGET_NT_ACL(metadata_fsp(fsp),
318 if (!NT_STATUS_IS_OK(status)) {
319 DBG_DEBUG("Could not get acl on %s: %s\n",
325 return smbd_check_access_rights_sd(fsp->conn,
335 * Given an fsp that represents a parent directory,
336 * check if the requested access can be granted.
338 NTSTATUS check_parent_access_fsp(struct files_struct *fsp,
339 uint32_t access_mask)
342 struct security_descriptor *parent_sd = NULL;
343 uint32_t access_granted = 0;
344 struct share_mode_lock *lck = NULL;
346 bool delete_on_close_set;
347 TALLOC_CTX *frame = talloc_stackframe();
349 if (get_current_uid(fsp->conn) == (uid_t)0) {
350 /* I'm sorry sir, I didn't know you were root... */
351 DBG_DEBUG("root override on %s. Granting 0x%x\n",
353 (unsigned int)access_mask);
354 status = NT_STATUS_OK;
358 status = SMB_VFS_FGET_NT_ACL(fsp,
363 if (!NT_STATUS_IS_OK(status)) {
364 DBG_INFO("SMB_VFS_FGET_NT_ACL failed for "
365 "%s with error %s\n",
372 * If we can access the path to this file, by
373 * default we have FILE_READ_ATTRIBUTES from the
374 * containing directory. See the section:
375 * "Algorithm to Check Access to an Existing File"
378 * se_file_access_check() also takes care of
379 * owner WRITE_DAC and READ_CONTROL.
381 status = se_file_access_check(parent_sd,
382 get_current_nttok(fsp->conn),
384 (access_mask & ~FILE_READ_ATTRIBUTES),
386 if(!NT_STATUS_IS_OK(status)) {
387 DBG_INFO("access check "
388 "on directory %s for mask 0x%x returned (0x%x) %s\n",
396 if (!(access_mask & (SEC_DIR_ADD_FILE | SEC_DIR_ADD_SUBDIR))) {
397 status = NT_STATUS_OK;
400 if (!lp_check_parent_directory_delete_on_close(SNUM(fsp->conn))) {
401 status = NT_STATUS_OK;
405 /* Check if the directory has delete-on-close set */
406 status = file_name_hash(fsp->conn,
407 fsp->fsp_name->base_name,
409 if (!NT_STATUS_IS_OK(status)) {
414 * Don't take a lock here. We just need a snapshot
415 * of the current state of delete on close and this is
416 * called in a codepath where we may already have a lock
417 * (and we explicitly can't hold 2 locks at the same time
418 * as that may deadlock).
420 lck = fetch_share_mode_unlocked(frame, fsp->file_id);
422 status = NT_STATUS_OK;
426 delete_on_close_set = is_delete_on_close_set(lck, name_hash);
427 if (delete_on_close_set) {
428 status = NT_STATUS_DELETE_PENDING;
432 status = NT_STATUS_OK;
439 /****************************************************************************
440 Ensure when opening a base file for a stream open that we have permissions
441 to do so given the access mask on the base file.
442 ****************************************************************************/
444 static NTSTATUS check_base_file_access(struct files_struct *fsp,
445 uint32_t access_mask)
449 status = smbd_calculate_access_mask_fsp(fsp->conn->cwd_fsp,
454 if (!NT_STATUS_IS_OK(status)) {
455 DEBUG(10, ("smbd_calculate_access_mask "
456 "on file %s returned %s\n",
462 if (access_mask & (FILE_WRITE_DATA|FILE_APPEND_DATA)) {
464 if (!CAN_WRITE(fsp->conn)) {
465 return NT_STATUS_ACCESS_DENIED;
467 dosattrs = fdos_mode(fsp);
468 if (dosattrs & FILE_ATTRIBUTE_READONLY) {
469 return NT_STATUS_ACCESS_DENIED;
473 return smbd_check_access_rights_fsp(fsp->conn->cwd_fsp,
479 static NTSTATUS chdir_below_conn(
481 connection_struct *conn,
482 const char *connectpath,
483 size_t connectpath_len,
484 struct smb_filename *dir_fname,
485 struct smb_filename **_oldwd_fname)
487 struct smb_filename *oldwd_fname = NULL;
488 struct smb_filename *smb_fname_dot = NULL;
489 struct smb_filename *real_fname = NULL;
490 const char *relative = NULL;
495 if (!ISDOT(dir_fname->base_name)) {
497 oldwd_fname = vfs_GetWd(talloc_tos(), conn);
498 if (oldwd_fname == NULL) {
499 status = map_nt_error_from_unix(errno);
503 /* Pin parent directory in place. */
504 ret = vfs_ChDir(conn, dir_fname);
506 status = map_nt_error_from_unix(errno);
507 DBG_DEBUG("chdir to %s failed: %s\n",
508 dir_fname->base_name,
514 smb_fname_dot = synthetic_smb_fname(
521 if (smb_fname_dot == NULL) {
522 status = NT_STATUS_NO_MEMORY;
526 real_fname = SMB_VFS_REALPATH(conn, talloc_tos(), smb_fname_dot);
527 if (real_fname == NULL) {
528 status = map_nt_error_from_unix(errno);
529 DBG_DEBUG("realpath in %s failed: %s\n",
530 dir_fname->base_name,
534 TALLOC_FREE(smb_fname_dot);
536 ok = subdir_of(connectpath,
538 real_fname->base_name,
541 TALLOC_FREE(real_fname);
542 *_oldwd_fname = oldwd_fname;
546 DBG_NOTICE("Bad access attempt: %s is a symlink "
547 "outside the share path\n"
549 "resolved_name=%s\n",
550 dir_fname->base_name,
552 real_fname->base_name);
553 TALLOC_FREE(real_fname);
555 status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
558 if (oldwd_fname != NULL) {
559 ret = vfs_ChDir(conn, oldwd_fname);
560 SMB_ASSERT(ret == 0);
561 TALLOC_FREE(oldwd_fname);
568 * Get the symlink target of dirfsp/symlink_name, making sure the
569 * target is below connection_path.
572 static NTSTATUS symlink_target_below_conn(
574 const char *connection_path,
575 struct files_struct *fsp,
576 struct files_struct *dirfsp,
577 struct smb_filename *symlink_name,
581 char *absolute = NULL;
584 if (fsp_get_pathref_fd(fsp) != -1) {
586 * fsp is an O_PATH open, Linux does a "freadlink"
587 * with an empty name argument to readlinkat
589 status = readlink_talloc(talloc_tos(), fsp, NULL, &target);
591 status = readlink_talloc(
592 talloc_tos(), dirfsp, symlink_name, &target);
595 status = safe_symlink_target_path(talloc_tos(),
597 dirfsp->fsp_name->base_name,
601 if (!NT_STATUS_IS_OK(status)) {
602 DBG_DEBUG("safe_symlink_target_path() failed: %s\n",
607 if (absolute[0] == '\0') {
609 * special case symlink to share root: "." is our
610 * share root filename
612 TALLOC_FREE(absolute);
613 absolute = talloc_strdup(talloc_tos(), ".");
614 if (absolute == NULL) {
615 return NT_STATUS_NO_MEMORY;
623 /****************************************************************************
625 ****************************************************************************/
627 static NTSTATUS non_widelink_open(const struct files_struct *dirfsp,
629 struct smb_filename *smb_fname,
630 const struct vfs_open_how *_how)
632 struct connection_struct *conn = fsp->conn;
633 const char *connpath = SMB_VFS_CONNECTPATH(conn, dirfsp, smb_fname);
635 NTSTATUS status = NT_STATUS_OK;
637 char *orig_smb_fname_base = smb_fname->base_name;
638 struct smb_filename *orig_fsp_name = fsp->fsp_name;
639 struct smb_filename *smb_fname_rel = NULL;
640 struct smb_filename *oldwd_fname = NULL;
641 struct smb_filename *parent_dir_fname = NULL;
642 struct vfs_open_how how = *_how;
644 size_t link_depth = 0;
647 SMB_ASSERT(!fsp_is_alternate_stream(fsp));
649 if (connpath == NULL) {
651 * This can happen with shadow_copy2 if the snapshot
654 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
656 connpath_len = strlen(connpath);
659 if (smb_fname->base_name[0] == '/') {
660 int cmp = strcmp(connpath, smb_fname->base_name);
662 smb_fname->base_name = talloc_strdup(smb_fname, "");
663 if (smb_fname->base_name == NULL) {
664 status = NT_STATUS_NO_MEMORY;
670 if (dirfsp == conn->cwd_fsp) {
672 status = SMB_VFS_PARENT_PATHNAME(fsp->conn,
677 if (!NT_STATUS_IS_OK(status)) {
681 status = chdir_below_conn(
688 if (!NT_STATUS_IS_OK(status)) {
692 /* Setup fsp->fsp_name to be relative to cwd */
693 fsp->fsp_name = smb_fname_rel;
696 * fsp->fsp_name is unchanged as it is already correctly
697 * relative to dirfsp.
699 smb_fname_rel = smb_fname;
704 * Assert nobody can step in with a symlink on the
705 * path, there is no path anymore and we'll use
706 * O_NOFOLLOW to open.
708 char *slash = strchr_m(smb_fname_rel->base_name, '/');
709 SMB_ASSERT(slash == NULL);
712 how.flags |= O_NOFOLLOW;
714 fd = SMB_VFS_OPENAT(conn,
719 fsp_set_fd(fsp, fd); /* This preserves errno */
722 status = map_nt_error_from_unix(errno);
724 if (errno == ENOENT) {
729 * ENOENT makes it worthless retrying with a
730 * stat, we know for sure the file does not
731 * exist. For everything else we want to know
734 ret = SMB_VFS_FSTATAT(
739 AT_SYMLINK_NOFOLLOW);
743 * Keep the original error. Otherwise we would
744 * mask for example EROFS for open(O_CREAT),
745 * turning it into ENOENT.
750 ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st);
754 status = map_nt_error_from_unix(errno);
755 DBG_DEBUG("fstat[at](%s) failed: %s\n",
756 smb_fname_str_dbg(smb_fname),
761 fsp->fsp_flags.is_directory = S_ISDIR(fsp->fsp_name->st.st_ex_mode);
762 orig_fsp_name->st = fsp->fsp_name->st;
764 if (!S_ISLNK(fsp->fsp_name->st.st_ex_mode)) {
769 * Found a symlink to follow in user space
772 if (fsp->fsp_name->flags & SMB_FILENAME_POSIX_PATH) {
773 /* Never follow symlinks on posix open. */
774 status = NT_STATUS_STOPPED_ON_SYMLINK;
777 if (!lp_follow_symlinks(SNUM(conn))) {
778 /* Explicitly no symlinks. */
779 status = NT_STATUS_STOPPED_ON_SYMLINK;
784 if (link_depth >= 40) {
785 status = NT_STATUS_STOPPED_ON_SYMLINK;
789 fsp->fsp_name = orig_fsp_name;
791 status = symlink_target_below_conn(
795 discard_const_p(files_struct, dirfsp),
799 if (!NT_STATUS_IS_OK(status)) {
800 DBG_DEBUG("symlink_target_below_conn() failed: %s\n",
806 * Close what openat(O_PATH) potentially left behind
810 if (smb_fname->base_name != orig_smb_fname_base) {
811 TALLOC_FREE(smb_fname->base_name);
813 smb_fname->base_name = target;
815 if (oldwd_fname != NULL) {
816 ret = vfs_ChDir(conn, oldwd_fname);
818 smb_panic("unable to get back to old directory\n");
820 TALLOC_FREE(oldwd_fname);
824 * And do it all again... As smb_fname is not relative to the passed in
825 * dirfsp anymore, we pass conn->cwd_fsp as dirfsp to
826 * non_widelink_open() to trigger the chdir(parentdir) logic.
828 dirfsp = conn->cwd_fsp;
833 fsp->fsp_name = orig_fsp_name;
834 smb_fname->base_name = orig_smb_fname_base;
836 TALLOC_FREE(parent_dir_fname);
838 if (!NT_STATUS_IS_OK(status)) {
842 if (oldwd_fname != NULL) {
843 ret = vfs_ChDir(conn, oldwd_fname);
845 smb_panic("unable to get back to old directory\n");
847 TALLOC_FREE(oldwd_fname);
852 /****************************************************************************
853 fd support routines - attempt to do a dos_open.
854 ****************************************************************************/
856 NTSTATUS fd_openat(const struct files_struct *dirfsp,
857 struct smb_filename *smb_fname,
859 const struct vfs_open_how *_how)
861 struct vfs_open_how how = *_how;
862 struct connection_struct *conn = fsp->conn;
863 NTSTATUS status = NT_STATUS_OK;
864 bool fsp_is_stream = fsp_is_alternate_stream(fsp);
865 bool smb_fname_is_stream = is_named_stream(smb_fname);
867 SMB_ASSERT(fsp_is_stream == smb_fname_is_stream);
870 * Never follow symlinks on a POSIX client. The
871 * client should be doing this.
874 if ((fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) || !lp_follow_symlinks(SNUM(conn))) {
875 how.flags |= O_NOFOLLOW;
883 NULL, /* stream open is relative to fsp->base_fsp */
888 status = map_nt_error_from_unix(errno);
893 status = vfs_stat_fsp(fsp);
894 if (!NT_STATUS_IS_OK(status)) {
895 DBG_DEBUG("vfs_stat_fsp failed: %s\n",
905 * Only follow symlinks within a share
908 status = non_widelink_open(dirfsp, fsp, smb_fname, &how);
909 if (!NT_STATUS_IS_OK(status)) {
910 if (NT_STATUS_EQUAL(status, NT_STATUS_TOO_MANY_OPENED_FILES)) {
911 static time_t last_warned = 0L;
913 if (time((time_t *) NULL) > last_warned) {
914 DEBUG(0,("Too many open files, unable "
915 "to open more! smbd's max "
917 lp_max_open_files()));
918 last_warned = time((time_t *) NULL);
922 DBG_DEBUG("name %s, flags = 0%o mode = 0%o, fd = %d. %s\n",
923 smb_fname_str_dbg(smb_fname),
926 fsp_get_pathref_fd(fsp),
931 DBG_DEBUG("name %s, flags = 0%o mode = 0%o, fd = %d\n",
932 smb_fname_str_dbg(smb_fname),
935 fsp_get_pathref_fd(fsp));
940 /****************************************************************************
941 Close the file associated with a fsp.
942 ****************************************************************************/
944 NTSTATUS fd_close(files_struct *fsp)
946 NTSTATUS stat_status = NT_STATUS_OK;
949 if (fsp == fsp->conn->cwd_fsp) {
953 if (fsp->fsp_flags.fstat_before_close) {
955 * capture status, if failure
956 * continue close processing
959 stat_status = vfs_stat_fsp(fsp);
965 if (fsp_get_pathref_fd(fsp) == -1) {
967 * Either a directory where the dptr_CloseDir() already closed
968 * the fd or a stat open.
972 if (fh_get_refcount(fsp->fh) > 1) {
973 return NT_STATUS_OK; /* Shared handle. Only close last reference. */
976 ret = SMB_VFS_CLOSE(fsp);
979 return map_nt_error_from_unix(errno);
984 /****************************************************************************
985 Change the ownership of a file to that of the parent directory.
986 Do this by fd if possible.
987 ****************************************************************************/
989 static void change_file_owner_to_parent_fsp(struct files_struct *parent_fsp,
990 struct files_struct *fsp)
994 if (parent_fsp->fsp_name->st.st_ex_uid == fsp->fsp_name->st.st_ex_uid) {
995 /* Already this uid - no need to change. */
996 DBG_DEBUG("file %s is already owned by uid %u\n",
998 (unsigned int)fsp->fsp_name->st.st_ex_uid);
1003 ret = SMB_VFS_FCHOWN(fsp,
1004 parent_fsp->fsp_name->st.st_ex_uid,
1008 DBG_ERR("failed to fchown "
1009 "file %s to parent directory uid %u. Error "
1012 (unsigned int)parent_fsp->fsp_name->st.st_ex_uid,
1015 DBG_DEBUG("changed new file %s to "
1016 "parent directory uid %u.\n",
1018 (unsigned int)parent_fsp->fsp_name->st.st_ex_uid);
1019 /* Ensure the uid entry is updated. */
1020 fsp->fsp_name->st.st_ex_uid =
1021 parent_fsp->fsp_name->st.st_ex_uid;
1025 static NTSTATUS change_dir_owner_to_parent_fsp(struct files_struct *parent_fsp,
1026 struct files_struct *fsp)
1031 if (parent_fsp->fsp_name->st.st_ex_uid == fsp->fsp_name->st.st_ex_uid) {
1032 /* Already this uid - no need to change. */
1033 DBG_DEBUG("directory %s is already owned by uid %u\n",
1035 (unsigned int)fsp->fsp_name->st.st_ex_uid);
1036 return NT_STATUS_OK;
1040 ret = SMB_VFS_FCHOWN(fsp,
1041 parent_fsp->fsp_name->st.st_ex_uid,
1045 status = map_nt_error_from_unix(errno);
1046 DBG_ERR("failed to chown "
1047 "directory %s to parent directory uid %u. "
1050 (unsigned int)parent_fsp->fsp_name->st.st_ex_uid,
1055 DBG_DEBUG("changed ownership of new "
1056 "directory %s to parent directory uid %u.\n",
1058 (unsigned int)parent_fsp->fsp_name->st.st_ex_uid);
1060 /* Ensure the uid entry is updated. */
1061 fsp->fsp_name->st.st_ex_uid = parent_fsp->fsp_name->st.st_ex_uid;
1063 return NT_STATUS_OK;
1066 /****************************************************************************
1067 Open a file - returning a guaranteed ATOMIC indication of if the
1068 file was created or not.
1069 ****************************************************************************/
1071 static NTSTATUS fd_open_atomic(struct files_struct *dirfsp,
1072 struct smb_filename *smb_fname,
1074 const struct vfs_open_how *_how,
1077 struct vfs_open_how how = *_how;
1078 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
1079 NTSTATUS retry_status;
1080 bool file_existed = VALID_STAT(smb_fname->st);
1082 if (!(how.flags & O_CREAT)) {
1084 * We're not creating the file, just pass through.
1086 status = fd_openat(dirfsp, smb_fname, fsp, &how);
1087 *file_created = false;
1091 if (how.flags & O_EXCL) {
1093 * Fail if already exists, just pass through.
1095 status = fd_openat(dirfsp, smb_fname, fsp, &how);
1098 * Here we've opened with O_CREAT|O_EXCL. If that went
1099 * NT_STATUS_OK, we *know* we created this file.
1101 *file_created = NT_STATUS_IS_OK(status);
1107 * Now it gets tricky. We have O_CREAT, but not O_EXCL.
1108 * To know absolutely if we created the file or not,
1109 * we can never call O_CREAT without O_EXCL. So if
1110 * we think the file existed, try without O_CREAT|O_EXCL.
1111 * If we think the file didn't exist, try with
1114 * The big problem here is dangling symlinks. Opening
1115 * without O_NOFOLLOW means both bad symlink
1116 * and missing path return -1, ENOENT from open(). As POSIX
1117 * is pathname based it's not possible to tell
1118 * the difference between these two cases in a
1119 * non-racy way, so change to try only two attempts before
1122 * We don't have this problem for the O_NOFOLLOW
1123 * case as it just returns NT_STATUS_OBJECT_PATH_NOT_FOUND
1124 * mapped from the ELOOP POSIX error.
1128 how.flags = _how->flags & ~(O_CREAT);
1129 retry_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
1131 how.flags = _how->flags | O_EXCL;
1132 retry_status = NT_STATUS_OBJECT_NAME_COLLISION;
1135 status = fd_openat(dirfsp, smb_fname, fsp, &how);
1136 if (NT_STATUS_IS_OK(status)) {
1137 *file_created = !file_existed;
1138 return NT_STATUS_OK;
1140 if (NT_STATUS_EQUAL(status, retry_status)) {
1142 file_existed = !file_existed;
1144 DBG_DEBUG("File %s %s. Retry.\n",
1146 file_existed ? "existed" : "did not exist");
1149 how.flags = _how->flags & ~(O_CREAT);
1151 how.flags = _how->flags | O_EXCL;
1154 status = fd_openat(dirfsp, smb_fname, fsp, &how);
1157 *file_created = (NT_STATUS_IS_OK(status) && !file_existed);
1161 static NTSTATUS reopen_from_fsp(struct files_struct *dirfsp,
1162 struct smb_filename *smb_fname,
1163 struct files_struct *fsp,
1164 const struct vfs_open_how *how,
1165 bool *p_file_created)
1170 if (fsp->fsp_flags.have_proc_fds &&
1171 ((old_fd = fsp_get_pathref_fd(fsp)) != -1)) {
1173 struct sys_proc_fd_path_buf buf;
1174 struct smb_filename proc_fname = (struct smb_filename){
1175 .base_name = sys_proc_fd_path(old_fd, &buf),
1177 mode_t mode = fsp->fsp_name->st.st_ex_mode;
1180 SMB_ASSERT(fsp->fsp_flags.is_pathref);
1182 if (S_ISLNK(mode)) {
1183 return NT_STATUS_STOPPED_ON_SYMLINK;
1185 if (!(S_ISREG(mode) || S_ISDIR(mode))) {
1186 return NT_STATUS_IO_REPARSE_TAG_NOT_HANDLED;
1189 fsp->fsp_flags.is_pathref = false;
1191 new_fd = SMB_VFS_OPENAT(fsp->conn,
1197 status = map_nt_error_from_unix(errno);
1202 status = fd_close(fsp);
1203 if (!NT_STATUS_IS_OK(status)) {
1207 fsp_set_fd(fsp, new_fd);
1208 return NT_STATUS_OK;
1212 * Close the existing pathref fd and set the fsp flag
1213 * is_pathref to false so we get a "normal" fd this time.
1215 status = fd_close(fsp);
1216 if (!NT_STATUS_IS_OK(status)) {
1220 fsp->fsp_flags.is_pathref = false;
1222 status = fd_open_atomic(dirfsp, smb_fname, fsp, how, p_file_created);
1226 /****************************************************************************
1228 ****************************************************************************/
1230 static NTSTATUS open_file(
1231 struct smb_request *req,
1232 struct files_struct *dirfsp,
1233 struct smb_filename *smb_fname_atname,
1235 const struct vfs_open_how *_how,
1236 uint32_t access_mask, /* client requested access mask. */
1237 uint32_t open_access_mask, /* what we're actually using in the open. */
1238 uint32_t private_flags,
1239 bool *p_file_created)
1241 connection_struct *conn = fsp->conn;
1242 struct smb_filename *smb_fname = fsp->fsp_name;
1243 struct vfs_open_how how = *_how;
1244 NTSTATUS status = NT_STATUS_OK;
1245 bool file_existed = VALID_STAT(fsp->fsp_name->st);
1246 const uint32_t need_fd_mask =
1251 SEC_FLAG_SYSTEM_SECURITY;
1252 bool creating = !file_existed && (how.flags & O_CREAT);
1253 bool open_fd = false;
1254 bool posix_open = (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN);
1257 * Catch early an attempt to open an existing
1258 * directory as a file.
1260 if (file_existed && S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
1261 return NT_STATUS_FILE_IS_A_DIRECTORY;
1265 * This little piece of insanity is inspired by the
1266 * fact that an NT client can open a file for O_RDONLY,
1267 * but set the create disposition to FILE_EXISTS_TRUNCATE.
1268 * If the client *can* write to the file, then it expects to
1269 * truncate the file, even though it is opening for readonly.
1270 * Quicken uses this stupid trick in backup file creation...
1271 * Thanks *greatly* to "David W. Chapman Jr." <dwcjr@inethouston.net>
1272 * for helping track this one down. It didn't bite us in 2.0.x
1273 * as we always opened files read-write in that release. JRA.
1276 if (((how.flags & O_ACCMODE) == O_RDONLY) && (how.flags & O_TRUNC)) {
1277 DBG_DEBUG("truncate requested on read-only open for file %s\n",
1278 smb_fname_str_dbg(smb_fname));
1279 how.flags = (how.flags & ~O_ACCMODE) | O_RDWR;
1282 /* Check permissions */
1285 * This code was changed after seeing a client open request
1286 * containing the open mode of (DENY_WRITE/read-only) with
1287 * the 'create if not exist' bit set. The previous code
1288 * would fail to open the file read only on a read-only share
1289 * as it was checking the flags parameter directly against O_RDONLY,
1290 * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
1294 if (!CAN_WRITE(conn)) {
1295 /* It's a read-only share - fail if we wanted to write. */
1296 if ((how.flags & O_ACCMODE) != O_RDONLY ||
1297 (how.flags & O_TRUNC) || (how.flags & O_APPEND)) {
1298 DEBUG(3,("Permission denied opening %s\n",
1299 smb_fname_str_dbg(smb_fname)));
1300 return NT_STATUS_ACCESS_DENIED;
1303 * We don't want to write - but we must make sure that
1304 * O_CREAT doesn't create the file if we have write
1305 * access into the directory.
1307 how.flags &= ~(O_CREAT | O_EXCL);
1310 if ((open_access_mask & need_fd_mask) || creating ||
1311 (how.flags & O_TRUNC)) {
1318 #if defined(O_NONBLOCK) && defined(S_ISFIFO)
1320 * We would block on opening a FIFO with no one else on the
1321 * other end. Do what we used to do and add O_NONBLOCK to the
1325 if (file_existed && S_ISFIFO(smb_fname->st.st_ex_mode)) {
1326 how.flags |= O_NONBLOCK;
1331 const char *wild = smb_fname->base_name;
1333 * Don't open files with Microsoft wildcard characters.
1335 if (fsp_is_alternate_stream(fsp)) {
1337 * wildcard characters are allowed in stream
1338 * names only test the basefilename
1340 wild = fsp->base_fsp->fsp_name->base_name;
1343 if (ms_has_wild(wild)) {
1344 return NT_STATUS_OBJECT_NAME_INVALID;
1348 /* Can we access this file ? */
1349 if (!fsp_is_alternate_stream(fsp)) {
1350 /* Only do this check on non-stream open. */
1352 status = smbd_check_access_rights_fsp(
1358 if (!NT_STATUS_IS_OK(status)) {
1359 DBG_DEBUG("smbd_check_access_rights_fsp"
1360 " on file %s returned %s\n",
1365 if (!NT_STATUS_IS_OK(status) &&
1366 !NT_STATUS_EQUAL(status,
1367 NT_STATUS_OBJECT_NAME_NOT_FOUND))
1372 if (NT_STATUS_EQUAL(status,
1373 NT_STATUS_OBJECT_NAME_NOT_FOUND))
1375 DEBUG(10, ("open_file: "
1376 "file %s vanished since we "
1377 "checked for existence.\n",
1378 smb_fname_str_dbg(smb_fname)));
1379 file_existed = false;
1380 SET_STAT_INVALID(fsp->fsp_name->st);
1384 if (!file_existed) {
1385 if (!(how.flags & O_CREAT)) {
1386 /* File didn't exist and no O_CREAT. */
1387 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1390 status = check_parent_access_fsp(
1393 if (!NT_STATUS_IS_OK(status)) {
1394 DBG_DEBUG("check_parent_access_fsp on "
1395 "directory %s for file %s "
1399 smb_fname_str_dbg(smb_fname),
1407 * Actually do the open - if O_TRUNC is needed handle it
1408 * below under the share mode lock.
1410 how.flags &= ~O_TRUNC;
1411 status = reopen_from_fsp(dirfsp,
1416 if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) {
1418 * Non-O_PATH reopen that hit a race
1419 * condition: Someone has put a symlink where
1420 * we used to have a file. Can't happen with
1421 * O_PATH and reopening from /proc/self/fd/ or
1424 status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
1426 if (!NT_STATUS_IS_OK(status)) {
1427 DBG_NOTICE("Error opening file %s (%s) (in_flags=%d) "
1429 smb_fname_str_dbg(smb_fname),
1436 if (how.flags & O_NONBLOCK) {
1438 * GPFS can return ETIMEDOUT for pread on
1439 * nonblocking file descriptors when files
1440 * migrated to tape need to be recalled. I
1441 * could imagine this happens elsewhere
1442 * too. With blocking file descriptors this
1445 ret = vfs_set_blocking(fsp, true);
1447 status = map_nt_error_from_unix(errno);
1448 DBG_WARNING("Could not set fd to blocking: "
1449 "%s\n", strerror(errno));
1455 if (*p_file_created) {
1456 /* We created this file. */
1458 bool need_re_stat = false;
1459 /* Do all inheritance work after we've
1460 done a successful fstat call and filled
1461 in the stat struct in fsp->fsp_name. */
1463 /* Inherit the ACL if required */
1464 if (lp_inherit_permissions(SNUM(conn))) {
1465 inherit_access_posix_acl(conn,
1469 need_re_stat = true;
1472 /* Change the owner if required. */
1473 if (lp_inherit_owner(SNUM(conn)) != INHERIT_OWNER_NO) {
1474 change_file_owner_to_parent_fsp(dirfsp, fsp);
1475 need_re_stat = true;
1479 status = vfs_stat_fsp(fsp);
1481 * If we have an fd, this stat should succeed.
1483 if (!NT_STATUS_IS_OK(status)) {
1484 DBG_ERR("Error doing fstat on open "
1486 smb_fname_str_dbg(smb_fname),
1493 notify_fname(conn, NOTIFY_ACTION_ADDED,
1494 FILE_NOTIFY_CHANGE_FILE_NAME,
1495 smb_fname->base_name);
1498 if (!file_existed) {
1499 /* File must exist for a stat open. */
1500 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1503 if (S_ISLNK(smb_fname->st.st_ex_mode) &&
1507 * Don't allow stat opens on symlinks directly unless
1508 * it's a POSIX open. Match the return code from
1509 * openat_pathref_fsp().
1511 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1514 if (!fsp->fsp_flags.is_pathref) {
1516 * There is only one legit case where end up here:
1517 * openat_pathref_fsp() failed to open a symlink, so the
1518 * fsp was created by fsp_new() which doesn't set
1519 * is_pathref. Other than that, we should always have a
1520 * pathref fsp at this point. The subsequent checks
1523 if (!(smb_fname->flags & SMB_FILENAME_POSIX_PATH)) {
1524 DBG_ERR("[%s] is not a POSIX pathname\n",
1525 smb_fname_str_dbg(smb_fname));
1526 return NT_STATUS_INTERNAL_ERROR;
1528 if (!S_ISLNK(smb_fname->st.st_ex_mode)) {
1529 DBG_ERR("[%s] is not a symlink\n",
1530 smb_fname_str_dbg(smb_fname));
1531 return NT_STATUS_INTERNAL_ERROR;
1533 if (fsp_get_pathref_fd(fsp) != -1) {
1534 DBG_ERR("fd for [%s] is not -1: fd [%d]\n",
1535 smb_fname_str_dbg(smb_fname),
1536 fsp_get_pathref_fd(fsp));
1537 return NT_STATUS_INTERNAL_ERROR;
1542 * Access to streams is checked by checking the basefile and
1543 * that has already been checked by check_base_file_access()
1544 * in create_file_unixpath().
1546 if (!fsp_is_alternate_stream(fsp)) {
1547 status = smbd_check_access_rights_fsp(dirfsp,
1552 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) &&
1554 S_ISLNK(smb_fname->st.st_ex_mode)) {
1555 /* This is a POSIX stat open for delete
1556 * or rename on a symlink that points
1557 * nowhere. Allow. */
1558 DEBUG(10,("open_file: allowing POSIX "
1559 "open on bad symlink %s\n",
1560 smb_fname_str_dbg(smb_fname)));
1561 status = NT_STATUS_OK;
1564 if (!NT_STATUS_IS_OK(status)) {
1565 DBG_DEBUG("smbd_check_access_rights_fsp on file "
1574 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
1575 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
1576 fsp->file_pid = req ? req->smbpid : 0;
1577 fsp->fsp_flags.can_lock = true;
1578 fsp->fsp_flags.can_read = ((access_mask & FILE_READ_DATA) != 0);
1579 fsp->fsp_flags.can_write =
1581 ((access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) != 0);
1582 if (fsp->fsp_name->twrp != 0) {
1583 fsp->fsp_flags.can_write = false;
1585 fsp->print_file = NULL;
1586 fsp->fsp_flags.modified = false;
1587 fsp->sent_oplock_break = NO_BREAK_SENT;
1588 fsp->fsp_flags.is_directory = false;
1589 if (is_in_path(smb_fname->base_name,
1590 conn->aio_write_behind_list,
1591 posix_open ? true : conn->case_sensitive)) {
1592 fsp->fsp_flags.aio_write_behind = true;
1595 DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
1596 conn->session_info->unix_info->unix_name,
1597 smb_fname_str_dbg(smb_fname),
1598 BOOLSTR(fsp->fsp_flags.can_read),
1599 BOOLSTR(fsp->fsp_flags.can_write),
1600 conn->num_files_open));
1602 return NT_STATUS_OK;
1605 static bool mask_conflict(
1606 uint32_t new_access,
1607 uint32_t existing_access,
1608 uint32_t access_mask,
1609 uint32_t new_sharemode,
1610 uint32_t existing_sharemode,
1611 uint32_t sharemode_mask)
1613 bool want_access = (new_access & access_mask);
1614 bool allow_existing = (existing_sharemode & sharemode_mask);
1615 bool have_access = (existing_access & access_mask);
1616 bool allow_new = (new_sharemode & sharemode_mask);
1618 if (want_access && !allow_existing) {
1619 DBG_DEBUG("Access request 0x%"PRIx32"/0x%"PRIx32" conflicts "
1620 "with existing sharemode 0x%"PRIx32"/0x%"PRIx32"\n",
1627 if (have_access && !allow_new) {
1628 DBG_DEBUG("Sharemode request 0x%"PRIx32"/0x%"PRIx32" conflicts "
1629 "with existing access 0x%"PRIx32"/0x%"PRIx32"\n",
1639 /****************************************************************************
1640 Check if we can open a file with a share mode.
1641 Returns True if conflict, False if not.
1642 ****************************************************************************/
1644 static const uint32_t conflicting_access =
1651 static bool share_conflict(uint32_t e_access_mask,
1652 uint32_t e_share_access,
1653 uint32_t access_mask,
1654 uint32_t share_access)
1658 DBG_DEBUG("existing access_mask = 0x%"PRIx32", "
1659 "existing share access = 0x%"PRIx32", "
1660 "access_mask = 0x%"PRIx32", "
1661 "share_access = 0x%"PRIx32"\n",
1667 if ((e_access_mask & conflicting_access) == 0) {
1668 DBG_DEBUG("No conflict due to "
1669 "existing access_mask = 0x%"PRIx32"\n",
1673 if ((access_mask & conflicting_access) == 0) {
1674 DBG_DEBUG("No conflict due to access_mask = 0x%"PRIx32"\n",
1679 conflict = mask_conflict(
1680 access_mask, e_access_mask, FILE_WRITE_DATA | FILE_APPEND_DATA,
1681 share_access, e_share_access, FILE_SHARE_WRITE);
1682 conflict |= mask_conflict(
1683 access_mask, e_access_mask, FILE_READ_DATA | FILE_EXECUTE,
1684 share_access, e_share_access, FILE_SHARE_READ);
1685 conflict |= mask_conflict(
1686 access_mask, e_access_mask, DELETE_ACCESS,
1687 share_access, e_share_access, FILE_SHARE_DELETE);
1689 DBG_DEBUG("conflict=%s\n", conflict ? "true" : "false");
1693 #if defined(DEVELOPER)
1695 struct validate_my_share_entries_state {
1696 struct smbd_server_connection *sconn;
1698 struct server_id self;
1701 static bool validate_my_share_entries_fn(
1702 struct share_mode_entry *e,
1706 struct validate_my_share_entries_state *state = private_data;
1709 if (!server_id_equal(&state->self, &e->pid)) {
1713 if (e->op_mid == 0) {
1714 /* INTERNAL_OPEN_ONLY */
1718 fsp = file_find_dif(state->sconn, state->fid, e->share_file_id);
1720 DBG_ERR("PANIC : %s\n",
1721 share_mode_str(talloc_tos(), 0, &state->fid, e));
1722 smb_panic("validate_my_share_entries: Cannot match a "
1723 "share entry with an open file\n");
1726 if (((uint16_t)fsp->oplock_type) != e->op_type) {
1735 DBG_ERR("validate_my_share_entries: PANIC : %s\n",
1736 share_mode_str(talloc_tos(), 0, &state->fid, e));
1737 str = talloc_asprintf(talloc_tos(),
1738 "validate_my_share_entries: "
1739 "file %s, oplock_type = 0x%x, op_type = 0x%x\n",
1740 fsp->fsp_name->base_name,
1741 (unsigned int)fsp->oplock_type,
1742 (unsigned int)e->op_type);
1751 * Allowed access mask for stat opens relevant to oplocks
1753 bool is_oplock_stat_open(uint32_t access_mask)
1755 const uint32_t stat_open_bits =
1756 (SYNCHRONIZE_ACCESS|
1757 FILE_READ_ATTRIBUTES|
1758 FILE_WRITE_ATTRIBUTES);
1760 return (((access_mask & stat_open_bits) != 0) &&
1761 ((access_mask & ~stat_open_bits) == 0));
1765 * Allowed access mask for stat opens relevant to leases
1767 bool is_lease_stat_open(uint32_t access_mask)
1769 const uint32_t stat_open_bits =
1770 (SYNCHRONIZE_ACCESS|
1771 FILE_READ_ATTRIBUTES|
1772 FILE_WRITE_ATTRIBUTES|
1773 READ_CONTROL_ACCESS);
1775 return (((access_mask & stat_open_bits) != 0) &&
1776 ((access_mask & ~stat_open_bits) == 0));
1779 struct has_delete_on_close_state {
1783 static bool has_delete_on_close_fn(
1784 struct share_mode_entry *e,
1788 struct has_delete_on_close_state *state = private_data;
1789 state->ret = !share_entry_stale_pid(e);
1793 static bool has_delete_on_close(struct share_mode_lock *lck,
1796 struct has_delete_on_close_state state = { .ret = false };
1799 if (!is_delete_on_close_set(lck, name_hash)) {
1803 ok= share_mode_forall_entries(lck, has_delete_on_close_fn, &state);
1805 DBG_DEBUG("share_mode_forall_entries failed\n");
1811 static void share_mode_flags_restrict(
1812 struct share_mode_lock *lck,
1813 uint32_t access_mask,
1814 uint32_t share_mode,
1815 uint32_t lease_type)
1817 uint32_t existing_access_mask, existing_share_mode;
1818 uint32_t existing_lease_type;
1820 share_mode_flags_get(
1822 &existing_access_mask,
1823 &existing_share_mode,
1824 &existing_lease_type);
1826 existing_access_mask |= access_mask;
1827 if (access_mask & conflicting_access) {
1828 existing_share_mode &= share_mode;
1830 existing_lease_type |= lease_type;
1832 share_mode_flags_set(
1834 existing_access_mask,
1835 existing_share_mode,
1836 existing_lease_type,
1840 /****************************************************************************
1841 Deal with share modes
1842 Invariant: Share mode must be locked on entry and exit.
1843 Returns -1 on error, or number of share modes on success (may be zero).
1844 ****************************************************************************/
1846 struct open_mode_check_state {
1848 uint32_t access_mask;
1849 uint32_t share_access;
1850 uint32_t lease_type;
1853 static bool open_mode_check_fn(
1854 struct share_mode_entry *e,
1858 struct open_mode_check_state *state = private_data;
1859 bool disconnected, stale;
1860 uint32_t access_mask, share_access, lease_type;
1862 disconnected = server_id_is_disconnected(&e->pid);
1867 access_mask = state->access_mask | e->access_mask;
1868 share_access = state->share_access;
1869 if (e->access_mask & conflicting_access) {
1870 share_access &= e->share_access;
1872 lease_type = state->lease_type | get_lease_type(e, state->fid);
1874 if ((access_mask == state->access_mask) &&
1875 (share_access == state->share_access) &&
1876 (lease_type == state->lease_type)) {
1880 stale = share_entry_stale_pid(e);
1885 state->access_mask = access_mask;
1886 state->share_access = share_access;
1887 state->lease_type = lease_type;
1892 static NTSTATUS open_mode_check(connection_struct *conn,
1894 struct share_mode_lock *lck,
1895 uint32_t access_mask,
1896 uint32_t share_access)
1898 struct open_mode_check_state state;
1900 bool modified = false;
1902 if (is_oplock_stat_open(access_mask)) {
1903 /* Stat open that doesn't trigger oplock breaks or share mode
1904 * checks... ! JRA. */
1905 return NT_STATUS_OK;
1909 * Check if the share modes will give us access.
1912 #if defined(DEVELOPER)
1914 struct validate_my_share_entries_state validate_state = {
1915 .sconn = conn->sconn,
1917 .self = messaging_server_id(conn->sconn->msg_ctx),
1919 ok = share_mode_forall_entries(
1920 lck, validate_my_share_entries_fn, &validate_state);
1925 share_mode_flags_get(
1926 lck, &state.access_mask, &state.share_access, NULL);
1928 conflict = share_conflict(
1934 DBG_DEBUG("No conflict due to share_mode_flags access\n");
1935 return NT_STATUS_OK;
1938 state = (struct open_mode_check_state) {
1940 .share_access = (FILE_SHARE_READ|
1946 * Walk the share mode array to recalculate d->flags
1949 ok = share_mode_forall_entries(lck, open_mode_check_fn, &state);
1951 DBG_DEBUG("share_mode_forall_entries failed\n");
1952 return NT_STATUS_INTERNAL_ERROR;
1955 share_mode_flags_set(
1963 * We only end up here if we had a sharing violation
1964 * from d->flags and have recalculated it.
1966 return NT_STATUS_SHARING_VIOLATION;
1969 conflict = share_conflict(
1975 DBG_DEBUG("No conflict due to share_mode_flags access\n");
1976 return NT_STATUS_OK;
1979 return NT_STATUS_SHARING_VIOLATION;
1983 * Send a break message to the oplock holder and delay the open for
1987 NTSTATUS send_break_message(struct messaging_context *msg_ctx,
1988 const struct file_id *id,
1989 const struct share_mode_entry *exclusive,
1992 struct oplock_break_message msg = {
1994 .share_file_id = exclusive->share_file_id,
1995 .break_to = break_to,
1997 enum ndr_err_code ndr_err;
2002 struct server_id_buf buf;
2003 DBG_DEBUG("Sending break message to %s\n",
2004 server_id_str_buf(exclusive->pid, &buf));
2005 NDR_PRINT_DEBUG(oplock_break_message, &msg);
2008 ndr_err = ndr_push_struct_blob(
2012 (ndr_push_flags_fn_t)ndr_push_oplock_break_message);
2013 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2014 DBG_WARNING("ndr_push_oplock_break_message failed: %s\n",
2015 ndr_errstr(ndr_err));
2016 return ndr_map_error2ntstatus(ndr_err);
2019 status = messaging_send(
2020 msg_ctx, exclusive->pid, MSG_SMB_BREAK_REQUEST, &blob);
2021 TALLOC_FREE(blob.data);
2022 if (!NT_STATUS_IS_OK(status)) {
2023 DEBUG(3, ("Could not send oplock break message: %s\n",
2024 nt_errstr(status)));
2030 struct validate_oplock_types_state {
2036 uint32_t num_non_stat_opens;
2039 static bool validate_oplock_types_fn(
2040 struct share_mode_entry *e,
2044 struct validate_oplock_types_state *state = private_data;
2046 if (e->op_mid == 0) {
2047 /* INTERNAL_OPEN_ONLY */
2051 if (e->op_type == NO_OPLOCK && is_oplock_stat_open(e->access_mask)) {
2053 * We ignore stat opens in the table - they always
2054 * have NO_OPLOCK and never get or cause breaks. JRA.
2059 state->num_non_stat_opens += 1;
2061 if (BATCH_OPLOCK_TYPE(e->op_type)) {
2062 /* batch - can only be one. */
2063 if (share_entry_stale_pid(e)) {
2064 DBG_DEBUG("Found stale batch oplock\n");
2067 if (state->ex_or_batch ||
2071 DBG_ERR("Bad batch oplock entry\n");
2072 state->valid = false;
2075 state->batch = true;
2078 if (EXCLUSIVE_OPLOCK_TYPE(e->op_type)) {
2079 if (share_entry_stale_pid(e)) {
2080 DBG_DEBUG("Found stale duplicate oplock\n");
2083 /* Exclusive or batch - can only be one. */
2084 if (state->ex_or_batch ||
2087 DBG_ERR("Bad exclusive or batch oplock entry\n");
2088 state->valid = false;
2091 state->ex_or_batch = true;
2094 if (LEVEL_II_OPLOCK_TYPE(e->op_type)) {
2095 if (state->batch || state->ex_or_batch) {
2096 if (share_entry_stale_pid(e)) {
2097 DBG_DEBUG("Found stale LevelII oplock\n");
2100 DBG_DEBUG("Bad levelII oplock entry\n");
2101 state->valid = false;
2104 state->level2 = true;
2107 if (e->op_type == NO_OPLOCK) {
2108 if (state->batch || state->ex_or_batch) {
2109 if (share_entry_stale_pid(e)) {
2110 DBG_DEBUG("Found stale NO_OPLOCK entry\n");
2113 DBG_ERR("Bad no oplock entry\n");
2114 state->valid = false;
2117 state->no_oplock = true;
2124 * Do internal consistency checks on the share mode for a file.
2127 static bool validate_oplock_types(struct share_mode_lock *lck)
2129 struct validate_oplock_types_state state = { .valid = true };
2130 static bool skip_validation;
2134 if (skip_validation) {
2138 validate = lp_parm_bool(-1, "smbd", "validate_oplock_types", false);
2140 DBG_DEBUG("smbd:validate_oplock_types not set to yes\n");
2141 skip_validation = true;
2145 ok = share_mode_forall_entries(lck, validate_oplock_types_fn, &state);
2147 DBG_DEBUG("share_mode_forall_entries failed\n");
2151 DBG_DEBUG("Got invalid oplock configuration\n");
2155 if ((state.batch || state.ex_or_batch) &&
2156 (state.num_non_stat_opens != 1)) {
2157 DBG_WARNING("got batch (%d) or ex (%d) non-exclusively "
2160 (int)state.ex_or_batch,
2161 state.num_non_stat_opens);
2168 static bool is_same_lease(const files_struct *fsp,
2169 const struct share_mode_entry *e,
2170 const struct smb2_lease *lease)
2172 if (e->op_type != LEASE_OPLOCK) {
2175 if (lease == NULL) {
2179 return smb2_lease_equal(fsp_client_guid(fsp),
2185 static bool file_has_brlocks(files_struct *fsp)
2187 struct byte_range_lock *br_lck;
2189 br_lck = brl_get_locks_readonly(fsp);
2193 return (brl_num_locks(br_lck) > 0);
2196 struct fsp_lease *find_fsp_lease(struct files_struct *new_fsp,
2197 const struct smb2_lease_key *key,
2198 uint32_t current_state,
2199 uint16_t lease_version,
2200 uint16_t lease_epoch)
2202 struct files_struct *fsp;
2205 * TODO: Measure how expensive this loop is with thousands of open
2209 for (fsp = file_find_di_first(new_fsp->conn->sconn, new_fsp->file_id, true);
2211 fsp = file_find_di_next(fsp, true)) {
2213 if (fsp == new_fsp) {
2216 if (fsp->oplock_type != LEASE_OPLOCK) {
2219 if (smb2_lease_key_equal(&fsp->lease->lease.lease_key, key)) {
2220 fsp->lease->ref_count += 1;
2225 /* Not found - must be leased in another smbd. */
2226 new_fsp->lease = talloc_zero(new_fsp->conn->sconn, struct fsp_lease);
2227 if (new_fsp->lease == NULL) {
2230 new_fsp->lease->ref_count = 1;
2231 new_fsp->lease->sconn = new_fsp->conn->sconn;
2232 new_fsp->lease->lease.lease_key = *key;
2233 new_fsp->lease->lease.lease_state = current_state;
2235 * We internally treat all leases as V2 and update
2236 * the epoch, but when sending breaks it matters if
2237 * the requesting lease was v1 or v2.
2239 new_fsp->lease->lease.lease_version = lease_version;
2240 new_fsp->lease->lease.lease_epoch = lease_epoch;
2241 return new_fsp->lease;
2244 static NTSTATUS try_lease_upgrade(struct files_struct *fsp,
2245 struct share_mode_lock *lck,
2246 const struct GUID *client_guid,
2247 const struct smb2_lease *lease,
2251 uint32_t current_state, breaking_to_requested, breaking_to_required;
2253 uint16_t lease_version, epoch;
2254 uint32_t existing, requested;
2257 status = leases_db_get(
2263 &breaking_to_requested,
2264 &breaking_to_required,
2267 if (!NT_STATUS_IS_OK(status)) {
2271 fsp->lease = find_fsp_lease(
2277 if (fsp->lease == NULL) {
2278 DEBUG(1, ("Did not find existing lease for file %s\n",
2280 return NT_STATUS_NO_MEMORY;
2284 * Upgrade only if the requested lease is a strict upgrade.
2286 existing = current_state;
2287 requested = lease->lease_state;
2290 * Tricky: This test makes sure that "requested" is a
2291 * strict bitwise superset of "existing".
2293 do_upgrade = ((existing & requested) == existing);
2296 * Upgrade only if there's a change.
2298 do_upgrade &= (granted != existing);
2301 * Upgrade only if other leases don't prevent what was asked
2304 do_upgrade &= (granted == requested);
2307 * only upgrade if we are not in breaking state
2309 do_upgrade &= !breaking;
2311 DEBUG(10, ("existing=%"PRIu32", requested=%"PRIu32", "
2312 "granted=%"PRIu32", do_upgrade=%d\n",
2313 existing, requested, granted, (int)do_upgrade));
2316 NTSTATUS set_status;
2318 current_state = granted;
2321 set_status = leases_db_set(
2326 breaking_to_requested,
2327 breaking_to_required,
2331 if (!NT_STATUS_IS_OK(set_status)) {
2332 DBG_DEBUG("leases_db_set failed: %s\n",
2333 nt_errstr(set_status));
2338 fsp_lease_update(fsp);
2340 return NT_STATUS_OK;
2343 static NTSTATUS grant_new_fsp_lease(struct files_struct *fsp,
2344 struct share_mode_lock *lck,
2345 const struct GUID *client_guid,
2346 const struct smb2_lease *lease,
2351 fsp->lease = talloc_zero(fsp->conn->sconn, struct fsp_lease);
2352 if (fsp->lease == NULL) {
2353 return NT_STATUS_INSUFFICIENT_RESOURCES;
2355 fsp->lease->ref_count = 1;
2356 fsp->lease->sconn = fsp->conn->sconn;
2357 fsp->lease->lease.lease_version = lease->lease_version;
2358 fsp->lease->lease.lease_key = lease->lease_key;
2359 fsp->lease->lease.lease_state = granted;
2360 fsp->lease->lease.lease_epoch = lease->lease_epoch + 1;
2362 status = leases_db_add(client_guid,
2365 fsp->lease->lease.lease_state,
2366 fsp->lease->lease.lease_version,
2367 fsp->lease->lease.lease_epoch,
2368 fsp->conn->connectpath,
2369 fsp->fsp_name->base_name,
2370 fsp->fsp_name->stream_name);
2371 if (!NT_STATUS_IS_OK(status)) {
2372 DEBUG(10, ("%s: leases_db_add failed: %s\n", __func__,
2373 nt_errstr(status)));
2374 TALLOC_FREE(fsp->lease);
2375 return NT_STATUS_INSUFFICIENT_RESOURCES;
2379 * We used to set lck->data->modified=true here without
2380 * actually modifying lck->data, triggering a needless
2381 * writeback of lck->data.
2383 * Apart from that writeback, setting modified=true has the
2384 * effect of triggering all waiters for this file to
2385 * retry. This only makes sense if any blocking condition
2386 * (i.e. waiting for a lease to be downgraded or removed) is
2387 * gone. This routine here only adds a lease, so it will never
2388 * free up resources that blocked waiters can now claim. So
2389 * that second effect also does not matter in this
2390 * routine. Thus setting lck->data->modified=true does not
2391 * need to be done here.
2394 return NT_STATUS_OK;
2397 static NTSTATUS grant_fsp_lease(struct files_struct *fsp,
2398 struct share_mode_lock *lck,
2399 const struct smb2_lease *lease,
2402 const struct GUID *client_guid = fsp_client_guid(fsp);
2405 status = try_lease_upgrade(fsp, lck, client_guid, lease, granted);
2407 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
2408 status = grant_new_fsp_lease(
2409 fsp, lck, client_guid, lease, granted);
2415 static int map_lease_type_to_oplock(uint32_t lease_type)
2417 int result = NO_OPLOCK;
2419 switch (lease_type) {
2420 case SMB2_LEASE_READ|SMB2_LEASE_WRITE|SMB2_LEASE_HANDLE:
2421 result = BATCH_OPLOCK|EXCLUSIVE_OPLOCK;
2423 case SMB2_LEASE_READ|SMB2_LEASE_WRITE:
2424 result = EXCLUSIVE_OPLOCK;
2426 case SMB2_LEASE_READ|SMB2_LEASE_HANDLE:
2427 case SMB2_LEASE_READ:
2428 result = LEVEL_II_OPLOCK;
2435 struct delay_for_oplock_state {
2436 struct files_struct *fsp;
2437 const struct smb2_lease *lease;
2438 bool will_overwrite;
2439 uint32_t delay_mask;
2440 bool first_open_attempt;
2441 bool got_handle_lease;
2443 bool have_other_lease;
2444 uint32_t total_lease_types;
2448 static bool delay_for_oplock_fn(
2449 struct share_mode_entry *e,
2453 struct delay_for_oplock_state *state = private_data;
2454 struct files_struct *fsp = state->fsp;
2455 const struct smb2_lease *lease = state->lease;
2456 bool e_is_lease = (e->op_type == LEASE_OPLOCK);
2457 uint32_t e_lease_type = SMB2_LEASE_NONE;
2459 bool lease_is_breaking = false;
2464 if (lease != NULL) {
2465 bool our_lease = is_same_lease(fsp, e, lease);
2467 DBG_DEBUG("Ignoring our own lease\n");
2472 status = leases_db_get(
2476 &e_lease_type, /* current_state */
2478 NULL, /* breaking_to_requested */
2479 NULL, /* breaking_to_required */
2480 NULL, /* lease_version */
2484 * leases_db_get() can return NT_STATUS_NOT_FOUND
2485 * if the share_mode_entry e is stale and the
2486 * lease record was already removed. In this case return
2487 * false so the traverse continues.
2490 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND) &&
2491 share_entry_stale_pid(e))
2493 struct GUID_txt_buf guid_strbuf;
2494 struct file_id_buf file_id_strbuf;
2495 DBG_DEBUG("leases_db_get for client_guid [%s] "
2496 "lease_key [%"PRIu64"/%"PRIu64"] "
2497 "file_id [%s] failed for stale "
2498 "share_mode_entry\n",
2499 GUID_buf_string(&e->client_guid, &guid_strbuf),
2500 e->lease_key.data[0],
2501 e->lease_key.data[1],
2502 file_id_str_buf(fsp->file_id, &file_id_strbuf));
2505 if (!NT_STATUS_IS_OK(status)) {
2506 struct GUID_txt_buf guid_strbuf;
2507 struct file_id_buf file_id_strbuf;
2508 DBG_ERR("leases_db_get for client_guid [%s] "
2509 "lease_key [%"PRIu64"/%"PRIu64"] "
2510 "file_id [%s] failed: %s\n",
2511 GUID_buf_string(&e->client_guid, &guid_strbuf),
2512 e->lease_key.data[0],
2513 e->lease_key.data[1],
2514 file_id_str_buf(fsp->file_id, &file_id_strbuf),
2516 smb_panic("leases_db_get() failed");
2519 e_lease_type = get_lease_type(e, fsp->file_id);
2522 if (((e_lease_type & ~state->total_lease_types) != 0) &&
2523 !share_entry_stale_pid(e))
2525 state->total_lease_types |= e_lease_type;
2528 if (!state->got_handle_lease &&
2529 ((e_lease_type & SMB2_LEASE_HANDLE) != 0) &&
2530 !share_entry_stale_pid(e)) {
2531 state->got_handle_lease = true;
2534 if (!state->got_oplock &&
2535 (e->op_type != LEASE_OPLOCK) &&
2536 !share_entry_stale_pid(e)) {
2537 state->got_oplock = true;
2540 if (!state->have_other_lease &&
2541 !is_same_lease(fsp, e, lease) &&
2542 !share_entry_stale_pid(e)) {
2543 state->have_other_lease = true;
2546 if (e_is_lease && is_lease_stat_open(fsp->access_mask)) {
2550 break_to = e_lease_type & ~state->delay_mask;
2552 if (state->will_overwrite) {
2553 break_to &= ~(SMB2_LEASE_HANDLE|SMB2_LEASE_READ);
2556 DBG_DEBUG("e_lease_type %u, will_overwrite: %u\n",
2557 (unsigned)e_lease_type,
2558 (unsigned)state->will_overwrite);
2560 if ((e_lease_type & ~break_to) == 0) {
2561 if (lease_is_breaking) {
2562 state->delay = true;
2567 if (share_entry_stale_pid(e)) {
2571 if (state->will_overwrite) {
2573 * If we break anyway break to NONE directly.
2574 * Otherwise vfs_set_filelen() will trigger the
2577 break_to &= ~(SMB2_LEASE_READ|SMB2_LEASE_WRITE);
2582 * Oplocks only support breaking to R or NONE.
2584 break_to &= ~(SMB2_LEASE_HANDLE|SMB2_LEASE_WRITE);
2587 DBG_DEBUG("breaking from %d to %d\n",
2591 fsp->conn->sconn->msg_ctx, &fsp->file_id, e, break_to);
2592 if (e_lease_type & state->delay_mask) {
2593 state->delay = true;
2595 if (lease_is_breaking && !state->first_open_attempt) {
2596 state->delay = true;
2602 static NTSTATUS delay_for_oplock(files_struct *fsp,
2604 const struct smb2_lease *lease,
2605 struct share_mode_lock *lck,
2606 bool have_sharing_violation,
2607 uint32_t create_disposition,
2608 bool first_open_attempt,
2612 struct delay_for_oplock_state state = {
2615 .first_open_attempt = first_open_attempt,
2622 *poplock_type = NO_OPLOCK;
2625 if (fsp->fsp_flags.is_directory) {
2627 * No directory leases yet
2629 SMB_ASSERT(oplock_request == NO_OPLOCK);
2630 if (have_sharing_violation) {
2631 return NT_STATUS_SHARING_VIOLATION;
2633 return NT_STATUS_OK;
2636 if (oplock_request == LEASE_OPLOCK) {
2637 if (lease == NULL) {
2639 * The SMB2 layer should have checked this
2641 return NT_STATUS_INTERNAL_ERROR;
2644 requested = lease->lease_state;
2646 requested = map_oplock_to_lease_type(
2647 oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK);
2650 share_mode_flags_get(lck, NULL, NULL, &state.total_lease_types);
2652 if (is_oplock_stat_open(fsp->access_mask)) {
2656 state.delay_mask = have_sharing_violation ?
2657 SMB2_LEASE_HANDLE : SMB2_LEASE_WRITE;
2659 switch (create_disposition) {
2660 case FILE_SUPERSEDE:
2661 case FILE_OVERWRITE:
2662 case FILE_OVERWRITE_IF:
2663 state.will_overwrite = true;
2666 state.will_overwrite = false;
2670 state.total_lease_types = SMB2_LEASE_NONE;
2671 ok = share_mode_forall_entries(lck, delay_for_oplock_fn, &state);
2673 return NT_STATUS_INTERNAL_ERROR;
2677 return NT_STATUS_RETRY;
2681 if (have_sharing_violation) {
2682 return NT_STATUS_SHARING_VIOLATION;
2685 granted = requested;
2687 if (oplock_request == LEASE_OPLOCK) {
2688 if (lp_kernel_oplocks(SNUM(fsp->conn))) {
2689 DEBUG(10, ("No lease granted because kernel oplocks are enabled\n"));
2690 granted = SMB2_LEASE_NONE;
2692 if ((granted & (SMB2_LEASE_READ|SMB2_LEASE_WRITE)) == 0) {
2693 DEBUG(10, ("No read or write lease requested\n"));
2694 granted = SMB2_LEASE_NONE;
2696 if (granted == SMB2_LEASE_WRITE) {
2697 DEBUG(10, ("pure write lease requested\n"));
2698 granted = SMB2_LEASE_NONE;
2700 if (granted == (SMB2_LEASE_WRITE|SMB2_LEASE_HANDLE)) {
2701 DEBUG(10, ("write and handle lease requested\n"));
2702 granted = SMB2_LEASE_NONE;
2706 if (lp_locking(fsp->conn->params) && file_has_brlocks(fsp)) {
2707 DBG_DEBUG("file %s has byte range locks\n",
2709 granted &= ~SMB2_LEASE_READ;
2712 if (state.have_other_lease) {
2714 * Can grant only one writer
2716 granted &= ~SMB2_LEASE_WRITE;
2719 if ((granted & SMB2_LEASE_READ) && !(granted & SMB2_LEASE_WRITE)) {
2721 (global_client_caps & CAP_LEVEL_II_OPLOCKS) &&
2722 lp_level2_oplocks(SNUM(fsp->conn));
2724 if (!allow_level2) {
2725 granted = SMB2_LEASE_NONE;
2729 if (oplock_request == LEASE_OPLOCK) {
2730 if (state.got_oplock) {
2731 granted &= ~SMB2_LEASE_HANDLE;
2734 oplock_type = LEASE_OPLOCK;
2736 if (state.got_handle_lease) {
2737 granted = SMB2_LEASE_NONE;
2741 * Reflect possible downgrades from:
2742 * - map_lease_type_to_oplock() => "RH" to just LEVEL_II
2744 oplock_type = map_lease_type_to_oplock(granted);
2745 granted = map_oplock_to_lease_type(oplock_type);
2748 state.total_lease_types |= granted;
2751 uint32_t acc, sh, ls;
2752 share_mode_flags_get(lck, &acc, &sh, &ls);
2753 ls = state.total_lease_types;
2754 share_mode_flags_set(lck, acc, sh, ls, NULL);
2757 DBG_DEBUG("oplock type 0x%x granted (%s%s%s)(0x%x), on file %s, "
2758 "requested 0x%x (%s%s%s)(0x%x) => total (%s%s%s)(0x%x)\n",
2760 granted & SMB2_LEASE_READ ? "R":"",
2761 granted & SMB2_LEASE_WRITE ? "W":"",
2762 granted & SMB2_LEASE_HANDLE ? "H":"",
2766 requested & SMB2_LEASE_READ ? "R":"",
2767 requested & SMB2_LEASE_WRITE ? "W":"",
2768 requested & SMB2_LEASE_HANDLE ? "H":"",
2770 state.total_lease_types & SMB2_LEASE_READ ? "R":"",
2771 state.total_lease_types & SMB2_LEASE_WRITE ? "W":"",
2772 state.total_lease_types & SMB2_LEASE_HANDLE ? "H":"",
2773 state.total_lease_types);
2775 *poplock_type = oplock_type;
2776 *pgranted = granted;
2777 return NT_STATUS_OK;
2780 static NTSTATUS handle_share_mode_lease(
2782 struct share_mode_lock *lck,
2783 uint32_t create_disposition,
2784 uint32_t access_mask,
2785 uint32_t share_access,
2787 const struct smb2_lease *lease,
2788 bool first_open_attempt,
2792 bool sharing_violation = false;
2795 *poplock_type = NO_OPLOCK;
2798 status = open_mode_check(
2799 fsp->conn, fsp->file_id, lck, access_mask, share_access);
2800 if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
2801 sharing_violation = true;
2802 status = NT_STATUS_OK; /* handled later */
2805 if (!NT_STATUS_IS_OK(status)) {
2809 if (oplock_request == INTERNAL_OPEN_ONLY) {
2810 if (sharing_violation) {
2811 DBG_DEBUG("Sharing violation for internal open\n");
2812 return NT_STATUS_SHARING_VIOLATION;
2816 * Internal opens never do oplocks or leases. We don't
2817 * need to go through delay_for_oplock().
2819 return NT_STATUS_OK;
2822 status = delay_for_oplock(
2832 if (!NT_STATUS_IS_OK(status)) {
2836 return NT_STATUS_OK;
2839 static bool request_timed_out(struct smb_request *req, struct timeval timeout)
2841 struct timeval now, end_time;
2843 end_time = timeval_sum(&req->request_time, &timeout);
2844 return (timeval_compare(&end_time, &now) < 0);
2847 struct defer_open_state {
2848 struct smbXsrv_connection *xconn;
2852 static void defer_open_done(struct tevent_req *req);
2855 * Defer an open and watch a locking.tdb record
2857 * This defers an open that gets rescheduled once the locking.tdb record watch
2858 * is triggered by a change to the record.
2860 * It is used to defer opens that triggered an oplock break and for the SMB1
2861 * sharing violation delay.
2863 static void defer_open(struct share_mode_lock *lck,
2864 struct timeval timeout,
2865 struct smb_request *req,
2868 struct deferred_open_record *open_rec = NULL;
2869 struct timeval abs_timeout;
2870 struct defer_open_state *watch_state;
2871 struct tevent_req *watch_req;
2872 struct timeval_buf tvbuf1, tvbuf2;
2873 struct file_id_buf fbuf;
2876 abs_timeout = timeval_sum(&req->request_time, &timeout);
2878 DBG_DEBUG("request time [%s] timeout [%s] mid [%" PRIu64 "] "
2880 timeval_str_buf(&req->request_time, false, true, &tvbuf1),
2881 timeval_str_buf(&abs_timeout, false, true, &tvbuf2),
2883 file_id_str_buf(id, &fbuf));
2885 open_rec = talloc_zero(NULL, struct deferred_open_record);
2886 if (open_rec == NULL) {
2888 exit_server("talloc failed");
2891 watch_state = talloc(open_rec, struct defer_open_state);
2892 if (watch_state == NULL) {
2893 exit_server("talloc failed");
2895 watch_state->xconn = req->xconn;
2896 watch_state->mid = req->mid;
2898 DBG_DEBUG("deferring mid %" PRIu64 "\n", req->mid);
2900 watch_req = share_mode_watch_send(
2904 (struct server_id){0});
2905 if (watch_req == NULL) {
2906 exit_server("Could not watch share mode record");
2908 tevent_req_set_callback(watch_req, defer_open_done, watch_state);
2910 ok = tevent_req_set_endtime(watch_req, req->sconn->ev_ctx, abs_timeout);
2912 exit_server("tevent_req_set_endtime failed");
2915 ok = push_deferred_open_message_smb(req, timeout, id, open_rec);
2918 exit_server("push_deferred_open_message_smb failed");
2922 static void defer_open_done(struct tevent_req *req)
2924 struct defer_open_state *state = tevent_req_callback_data(
2925 req, struct defer_open_state);
2929 status = share_mode_watch_recv(req, NULL, NULL);
2931 if (!NT_STATUS_IS_OK(status)) {
2932 DEBUG(5, ("dbwrap_watched_watch_recv returned %s\n",
2933 nt_errstr(status)));
2935 * Even if it failed, retry anyway. TODO: We need a way to
2936 * tell a re-scheduled open about that error.
2940 DEBUG(10, ("scheduling mid %llu\n", (unsigned long long)state->mid));
2942 ret = schedule_deferred_open_message_smb(state->xconn, state->mid);
2948 * Actually attempt the kernel oplock polling open.
2951 static void poll_open_fn(struct tevent_context *ev,
2952 struct tevent_timer *te,
2953 struct timeval current_time,
2956 struct deferred_open_record *open_rec = talloc_get_type_abort(
2957 private_data, struct deferred_open_record);
2960 TALLOC_FREE(open_rec->watch_req);
2962 ok = schedule_deferred_open_message_smb(
2963 open_rec->xconn, open_rec->mid);
2965 exit_server("schedule_deferred_open_message_smb failed");
2967 DBG_DEBUG("timer fired. Retrying open !\n");
2970 static void poll_open_done(struct tevent_req *subreq);
2972 struct poll_open_setup_watcher_state {
2973 TALLOC_CTX *mem_ctx;
2974 struct tevent_context *ev_ctx;
2975 struct tevent_req *watch_req;
2978 static void poll_open_setup_watcher_fn(struct share_mode_lock *lck,
2981 struct poll_open_setup_watcher_state *state =
2982 (struct poll_open_setup_watcher_state *)private_data;
2984 if (!validate_oplock_types(lck)) {
2985 smb_panic("validate_oplock_types failed");
2988 state->watch_req = share_mode_watch_send(
2992 (struct server_id) {0});
2993 if (state->watch_req == NULL) {
2994 DBG_WARNING("share_mode_watch_send failed\n");
3000 * Reschedule an open for 1 second from now, if not timed out.
3002 static bool setup_poll_open(
3003 struct smb_request *req,
3004 const struct file_id *id,
3005 struct timeval max_timeout,
3006 struct timeval interval)
3008 static struct file_id zero_id = {};
3010 struct deferred_open_record *open_rec = NULL;
3011 struct timeval endtime, next_interval;
3012 struct file_id_buf ftmp;
3014 if (request_timed_out(req, max_timeout)) {
3018 open_rec = talloc_zero(NULL, struct deferred_open_record);
3019 if (open_rec == NULL) {
3020 DBG_WARNING("talloc failed\n");
3023 open_rec->xconn = req->xconn;
3024 open_rec->mid = req->mid;
3027 * Make sure open_rec->te does not come later than the
3028 * request's maximum endtime.
3031 endtime = timeval_sum(&req->request_time, &max_timeout);
3032 next_interval = timeval_current_ofs(interval.tv_sec, interval.tv_usec);
3033 next_interval = timeval_min(&endtime, &next_interval);
3035 open_rec->te = tevent_add_timer(
3041 if (open_rec->te == NULL) {
3042 DBG_WARNING("tevent_add_timer failed\n");
3043 TALLOC_FREE(open_rec);
3048 struct poll_open_setup_watcher_state wstate = {
3049 .mem_ctx = open_rec,
3050 .ev_ctx = req->sconn->ev_ctx,
3054 status = share_mode_do_locked_vfs_denied(*id,
3055 poll_open_setup_watcher_fn,
3057 if (NT_STATUS_IS_OK(status)) {
3058 if (wstate.watch_req == NULL) {
3059 DBG_WARNING("share_mode_watch_send failed\n");
3060 TALLOC_FREE(open_rec);
3063 open_rec->watch_req = wstate.watch_req;
3064 tevent_req_set_callback(open_rec->watch_req,
3067 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
3068 DBG_WARNING("share_mode_do_locked_vfs_denied failed - %s\n",
3070 TALLOC_FREE(open_rec);
3077 ok = push_deferred_open_message_smb(req, max_timeout, *id, open_rec);
3079 DBG_WARNING("push_deferred_open_message_smb failed\n");
3080 TALLOC_FREE(open_rec);
3084 DBG_DEBUG("poll request time [%s] mid [%" PRIu64 "] file_id [%s]\n",
3085 timeval_string(talloc_tos(), &req->request_time, false),
3087 file_id_str_buf(*id, &ftmp));
3092 static void poll_open_done(struct tevent_req *subreq)
3094 struct deferred_open_record *open_rec = tevent_req_callback_data(
3095 subreq, struct deferred_open_record);
3099 status = share_mode_watch_recv(subreq, NULL, NULL);
3100 TALLOC_FREE(subreq);
3101 open_rec->watch_req = NULL;
3102 TALLOC_FREE(open_rec->te);
3104 DBG_DEBUG("dbwrap_watched_watch_recv returned %s\n",
3107 ok = schedule_deferred_open_message_smb(
3108 open_rec->xconn, open_rec->mid);
3110 exit_server("schedule_deferred_open_message_smb failed");
3114 bool defer_smb1_sharing_violation(struct smb_request *req)
3119 if (!lp_defer_sharing_violations()) {
3124 * Try every 200msec up to (by default) one second. To be
3125 * precise, according to behaviour note <247> in [MS-CIFS],
3126 * the server tries 5 times. But up to one second should be
3130 timeout_usecs = lp_parm_int(
3134 SHARING_VIOLATION_USEC_WAIT);
3136 ok = setup_poll_open(
3139 (struct timeval) { .tv_usec = timeout_usecs },
3140 (struct timeval) { .tv_usec = 200000 });
3144 /****************************************************************************
3145 On overwrite open ensure that the attributes match.
3146 ****************************************************************************/
3148 static bool open_match_attributes(connection_struct *conn,
3149 uint32_t old_dos_attr,
3150 uint32_t new_dos_attr,
3151 mode_t new_unx_mode,
3152 mode_t *returned_unx_mode)
3154 uint32_t noarch_old_dos_attr, noarch_new_dos_attr;
3156 noarch_old_dos_attr = (old_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
3157 noarch_new_dos_attr = (new_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
3159 if((noarch_old_dos_attr == 0 && noarch_new_dos_attr != 0) ||
3160 (noarch_old_dos_attr != 0 && ((noarch_old_dos_attr & noarch_new_dos_attr) == noarch_old_dos_attr))) {
3161 *returned_unx_mode = new_unx_mode;
3163 *returned_unx_mode = (mode_t)0;
3166 DEBUG(10,("open_match_attributes: old_dos_attr = 0x%x, "
3167 "new_dos_attr = 0x%x "
3168 "returned_unx_mode = 0%o\n",
3169 (unsigned int)old_dos_attr,
3170 (unsigned int)new_dos_attr,
3171 (unsigned int)*returned_unx_mode ));
3173 /* If we're mapping SYSTEM and HIDDEN ensure they match. */
3174 if (lp_map_system(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
3175 if ((old_dos_attr & FILE_ATTRIBUTE_SYSTEM) &&
3176 !(new_dos_attr & FILE_ATTRIBUTE_SYSTEM)) {
3180 if (lp_map_hidden(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
3181 if ((old_dos_attr & FILE_ATTRIBUTE_HIDDEN) &&
3182 !(new_dos_attr & FILE_ATTRIBUTE_HIDDEN)) {
3189 static void schedule_defer_open(struct share_mode_lock *lck,
3191 struct smb_request *req)
3193 /* This is a relative time, added to the absolute
3194 request_time value to get the absolute timeout time.
3195 Note that if this is the second or greater time we enter
3196 this codepath for this particular request mid then
3197 request_time is left as the absolute time of the *first*
3198 time this request mid was processed. This is what allows
3199 the request to eventually time out. */
3201 struct timeval timeout;
3203 /* Normally the smbd we asked should respond within
3204 * OPLOCK_BREAK_TIMEOUT seconds regardless of whether
3205 * the client did, give twice the timeout as a safety
3206 * measure here in case the other smbd is stuck
3207 * somewhere else. */
3209 timeout = tevent_timeval_set(OPLOCK_BREAK_TIMEOUT * 2, 0);
3211 if (request_timed_out(req, timeout)) {
3215 defer_open(lck, timeout, req, id);
3218 /****************************************************************************
3219 Reschedule an open call that went asynchronous.
3220 ****************************************************************************/
3222 static void schedule_async_open_timer(struct tevent_context *ev,
3223 struct tevent_timer *te,
3224 struct timeval current_time,
3227 exit_server("async open timeout");
3230 static void schedule_async_open(struct smb_request *req)
3232 struct deferred_open_record *open_rec = NULL;
3233 struct timeval timeout = tevent_timeval_set(20, 0);
3236 if (request_timed_out(req, timeout)) {
3240 open_rec = talloc_zero(NULL, struct deferred_open_record);
3241 if (open_rec == NULL) {
3242 exit_server("deferred_open_record_create failed");
3244 open_rec->async_open = true;
3246 ok = push_deferred_open_message_smb(
3247 req, timeout, (struct file_id){0}, open_rec);
3249 exit_server("push_deferred_open_message_smb failed");
3252 open_rec->te = tevent_add_timer(req->sconn->ev_ctx,
3254 timeval_current_ofs(20, 0),
3255 schedule_async_open_timer,
3257 if (open_rec->te == NULL) {
3258 exit_server("tevent_add_timer failed");
3262 static NTSTATUS check_and_store_share_mode(
3263 struct files_struct *fsp,
3264 struct smb_request *req,
3265 struct share_mode_lock *lck,
3266 uint32_t create_disposition,
3267 uint32_t access_mask,
3268 uint32_t share_access,
3270 const struct smb2_lease *lease,
3271 bool first_open_attempt)
3274 int oplock_type = NO_OPLOCK;
3275 uint32_t granted_lease = 0;
3276 const struct smb2_lease_key *lease_key = NULL;
3277 bool delete_on_close;
3280 /* Get the types we need to examine. */
3281 if (!validate_oplock_types(lck)) {
3282 smb_panic("validate_oplock_types failed");
3285 delete_on_close = has_delete_on_close(lck, fsp->name_hash);
3286 if (delete_on_close) {
3287 return NT_STATUS_DELETE_PENDING;
3290 status = handle_share_mode_lease(fsp,
3300 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
3301 schedule_defer_open(lck, fsp->file_id, req);
3302 return NT_STATUS_SHARING_VIOLATION;
3304 if (!NT_STATUS_IS_OK(status)) {
3308 if (oplock_type == LEASE_OPLOCK) {
3309 lease_key = &lease->lease_key;
3312 share_mode_flags_restrict(lck, access_mask, share_access, 0);
3314 ok = set_share_mode(lck,
3316 get_current_uid(fsp->conn),
3323 return NT_STATUS_NO_MEMORY;
3326 if (oplock_type == LEASE_OPLOCK) {
3327 status = grant_fsp_lease(fsp, lck, lease, granted_lease);
3328 if (!NT_STATUS_IS_OK(status)) {
3329 del_share_mode(lck, fsp);
3333 DBG_DEBUG("lease_state=%d\n", fsp->lease->lease.lease_state);
3336 fsp->oplock_type = oplock_type;
3338 return NT_STATUS_OK;
3341 /****************************************************************************
3342 Work out what access_mask to use from what the client sent us.
3343 ****************************************************************************/
3345 static NTSTATUS smbd_calculate_maximum_allowed_access_fsp(
3346 struct files_struct *dirfsp,
3347 struct files_struct *fsp,
3349 uint32_t *p_access_mask)
3351 struct security_descriptor *sd = NULL;
3352 uint32_t access_granted = 0;
3356 /* Cope with symlinks */
3357 if (fsp == NULL || fsp_get_pathref_fd(fsp) == -1) {
3358 *p_access_mask = FILE_GENERIC_ALL;
3359 return NT_STATUS_OK;
3362 /* Cope with fake/printer fsp's. */
3363 if (fsp->fake_file_handle != NULL || fsp->print_file != NULL) {
3364 *p_access_mask = FILE_GENERIC_ALL;
3365 return NT_STATUS_OK;
3368 if (!use_privs && (get_current_uid(fsp->conn) == (uid_t)0)) {
3369 *p_access_mask |= FILE_GENERIC_ALL;
3370 return NT_STATUS_OK;
3373 status = SMB_VFS_FGET_NT_ACL(metadata_fsp(fsp),
3380 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
3382 * File did not exist
3384 *p_access_mask = FILE_GENERIC_ALL;
3385 return NT_STATUS_OK;
3387 if (!NT_STATUS_IS_OK(status)) {
3388 DBG_ERR("Could not get acl on file %s: %s\n",
3395 * If we can access the path to this file, by
3396 * default we have FILE_READ_ATTRIBUTES from the
3397 * containing directory. See the section:
3398 * "Algorithm to Check Access to an Existing File"
3401 * se_file_access_check()
3402 * also takes care of owner WRITE_DAC and READ_CONTROL.
3404 status = se_file_access_check(sd,
3405 get_current_nttok(fsp->conn),
3407 (*p_access_mask & ~FILE_READ_ATTRIBUTES),
3412 if (!NT_STATUS_IS_OK(status)) {
3413 DBG_ERR("Status %s on file %s: "
3414 "when calculating maximum access\n",
3420 *p_access_mask = (access_granted | FILE_READ_ATTRIBUTES);
3422 if (!(access_granted & DELETE_ACCESS)) {
3423 if (can_delete_file_in_directory(fsp->conn,
3426 *p_access_mask |= DELETE_ACCESS;
3430 dosattrs = fdos_mode(fsp);
3431 if ((dosattrs & FILE_ATTRIBUTE_READONLY) || !CAN_WRITE(fsp->conn)) {
3432 *p_access_mask &= ~(FILE_GENERIC_WRITE | DELETE_ACCESS);
3435 return NT_STATUS_OK;
3438 NTSTATUS smbd_calculate_access_mask_fsp(struct files_struct *dirfsp,
3439 struct files_struct *fsp,
3441 uint32_t access_mask,
3442 uint32_t *access_mask_out)
3445 uint32_t orig_access_mask = access_mask;
3446 uint32_t rejected_share_access;
3448 if (access_mask & SEC_MASK_INVALID) {
3449 DBG_DEBUG("access_mask [%8x] contains invalid bits\n",
3451 return NT_STATUS_ACCESS_DENIED;
3455 * Convert GENERIC bits to specific bits.
3458 se_map_generic(&access_mask, &file_generic_mapping);
3460 /* Calculate MAXIMUM_ALLOWED_ACCESS if requested. */
3461 if (access_mask & MAXIMUM_ALLOWED_ACCESS) {
3463 status = smbd_calculate_maximum_allowed_access_fsp(
3469 if (!NT_STATUS_IS_OK(status)) {
3473 access_mask &= fsp->conn->share_access;
3476 rejected_share_access = access_mask & ~(fsp->conn->share_access);
3478 if (rejected_share_access) {
3479 DBG_INFO("Access denied on file %s: "
3480 "rejected by share access mask[0x%08X] "
3481 "orig[0x%08X] mapped[0x%08X] reject[0x%08X]\n",
3483 fsp->conn->share_access,
3484 orig_access_mask, access_mask,
3485 rejected_share_access);
3486 return NT_STATUS_ACCESS_DENIED;
3489 *access_mask_out = access_mask;
3490 return NT_STATUS_OK;
3493 /****************************************************************************
3494 Remove the deferred open entry under lock.
3495 ****************************************************************************/
3497 /****************************************************************************
3498 Return true if this is a state pointer to an asynchronous create.
3499 ****************************************************************************/
3501 bool is_deferred_open_async(const struct deferred_open_record *rec)
3503 return rec->async_open;
3506 static bool clear_ads(uint32_t create_disposition)
3510 switch (create_disposition) {
3511 case FILE_SUPERSEDE:
3512 case FILE_OVERWRITE_IF:
3513 case FILE_OVERWRITE:
3522 static int disposition_to_open_flags(uint32_t create_disposition)
3527 * Currently we're using FILE_SUPERSEDE as the same as
3528 * FILE_OVERWRITE_IF but they really are
3529 * different. FILE_SUPERSEDE deletes an existing file
3530 * (requiring delete access) then recreates it.
3533 switch (create_disposition) {
3534 case FILE_SUPERSEDE:
3535 case FILE_OVERWRITE_IF:
3537 * If file exists replace/overwrite. If file doesn't
3540 ret = O_CREAT|O_TRUNC;
3545 * If file exists open. If file doesn't exist error.
3550 case FILE_OVERWRITE:
3552 * If file exists overwrite. If file doesn't exist
3560 * If file exists error. If file doesn't exist create.
3562 ret = O_CREAT|O_EXCL;
3567 * If file exists open. If file doesn't exist create.
3575 static int calculate_open_access_flags(uint32_t access_mask,
3576 uint32_t private_flags,
3579 bool need_write, need_read;
3582 * Note that we ignore the append flag as append does not
3583 * mean the same thing under DOS and Unix.
3588 * Pave over the user requested mode and force O_RDONLY for the
3589 * file handle. Windows allows opening a VSS file with O_RDWR,
3590 * even though actual writes on the handle will fail.
3595 need_write = (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA));
3600 /* DENY_DOS opens are always underlying read-write on the
3601 file handle, no matter what the requested access mask
3605 ((private_flags & NTCREATEX_FLAG_DENY_DOS) ||
3606 access_mask & (FILE_READ_ATTRIBUTES|FILE_READ_DATA|
3607 FILE_READ_EA|FILE_EXECUTE));
3615 struct open_ntcreate_lock_state {
3616 struct share_mode_entry_prepare_state prepare_state;
3617 struct files_struct *fsp;
3618 const char *object_type;
3619 struct smb_request *req;
3620 uint32_t create_disposition;
3621 uint32_t access_mask;
3622 uint32_t share_access;
3624 const struct smb2_lease *lease;
3625 bool first_open_attempt;
3628 struct timespec write_time;
3629 share_mode_entry_prepare_unlock_fn_t cleanup_fn;
3632 static void open_ntcreate_lock_add_entry(struct share_mode_lock *lck,
3636 struct open_ntcreate_lock_state *state =
3637 (struct open_ntcreate_lock_state *)private_data;
3640 * By default drop the g_lock again if we leave the
3643 *keep_locked = false;
3645 state->status = check_and_store_share_mode(state->fsp,
3648 state->create_disposition,
3650 state->share_access,
3651 state->oplock_request,
3653 state->first_open_attempt);
3654 if (!NT_STATUS_IS_OK(state->status)) {
3658 state->write_time = get_share_mode_write_time(lck);
3661 * keep the g_lock while existing the tdb chainlock,
3662 * we we're asked to, which mean we'll keep
3663 * the share_mode_lock during object creation,
3664 * or setting delete on close.
3666 *keep_locked = state->keep_locked;
3669 static void open_ntcreate_lock_cleanup_oplock(struct share_mode_lock *lck,
3672 struct open_ntcreate_lock_state *state =
3673 (struct open_ntcreate_lock_state *)private_data;
3676 ok = remove_share_oplock(lck, state->fsp);
3678 DBG_ERR("Could not remove oplock for %s %s\n",
3679 state->object_type, fsp_str_dbg(state->fsp));
3683 static void open_ntcreate_lock_cleanup_entry(struct share_mode_lock *lck,
3686 struct open_ntcreate_lock_state *state =
3687 (struct open_ntcreate_lock_state *)private_data;
3690 ok = del_share_mode(lck, state->fsp);
3692 DBG_ERR("Could not delete share entry for %s %s\n",
3693 state->object_type, fsp_str_dbg(state->fsp));
3697 static void possibly_set_archive(struct connection_struct *conn,
3698 struct files_struct *fsp,
3699 struct smb_filename *smb_fname,
3700 struct smb_filename *parent_dir_fname,
3705 bool set_archive = false;
3708 if (info == FILE_WAS_OPENED) {
3712 /* Overwritten files should be initially set as archive */
3713 if ((info == FILE_WAS_OVERWRITTEN && lp_map_archive(SNUM(conn)))) {
3715 } else if (lp_store_dos_attributes(SNUM(conn))) {
3722 ret = file_set_dosmode(conn,
3724 dosattrs | FILE_ATTRIBUTE_ARCHIVE,
3730 *unx_mode = smb_fname->st.st_ex_mode;
3733 /****************************************************************************
3734 Open a file with a share mode. Passed in an already created files_struct *.
3735 ****************************************************************************/
3737 static NTSTATUS open_file_ntcreate(connection_struct *conn,
3738 struct smb_request *req,
3739 uint32_t access_mask, /* access bits (FILE_READ_DATA etc.) */
3740 uint32_t share_access, /* share constants (FILE_SHARE_READ etc) */
3741 uint32_t create_disposition, /* FILE_OPEN_IF etc. */
3742 uint32_t create_options, /* options such as delete on close. */
3743 uint32_t new_dos_attributes, /* attributes used for new file. */
3744 int oplock_request, /* internal Samba oplock codes. */
3745 const struct smb2_lease *lease,
3746 /* Information (FILE_EXISTS etc.) */
3747 uint32_t private_flags, /* Samba specific flags. */
3748 struct smb_filename *parent_dir_fname, /* parent. */
3749 struct smb_filename *smb_fname_atname, /* atname relative to parent. */
3753 struct smb_filename *smb_fname = fsp->fsp_name;
3755 bool file_existed = VALID_STAT(smb_fname->st);
3756 bool def_acl = False;
3757 bool posix_open = False;
3758 bool new_file_created = False;
3759 bool first_open_attempt = true;
3760 bool is_twrp = (smb_fname_atname->twrp != 0);
3761 NTSTATUS fsp_open = NT_STATUS_ACCESS_DENIED;
3762 mode_t new_unx_mode = (mode_t)0;
3763 mode_t unx_mode = (mode_t)0;
3765 uint32_t existing_dos_attributes = 0;
3766 struct open_ntcreate_lock_state lck_state = {};
3767 bool keep_locked = false;
3768 uint32_t open_access_mask = access_mask;
3770 SMB_STRUCT_STAT saved_stat = smb_fname->st;
3771 struct timespec old_write_time;
3772 bool setup_poll = false;
3775 if (conn->printer) {
3777 * Printers are handled completely differently.
3778 * Most of the passed parameters are ignored.
3782 *pinfo = FILE_WAS_CREATED;
3785 DBG_DEBUG("printer open fname=%s\n",
3786 smb_fname_str_dbg(smb_fname));
3789 DBG_ERR("printer open without an SMB request!\n");
3790 return NT_STATUS_INTERNAL_ERROR;
3793 return print_spool_open(fsp, smb_fname->base_name,
3797 if (new_dos_attributes & FILE_FLAG_POSIX_SEMANTICS) {
3799 unx_mode = (mode_t)(new_dos_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
3800 new_dos_attributes = 0;
3802 /* Windows allows a new file to be created and
3803 silently removes a FILE_ATTRIBUTE_DIRECTORY
3804 sent by the client. Do the same. */
3806 new_dos_attributes &= ~FILE_ATTRIBUTE_DIRECTORY;
3808 /* We add FILE_ATTRIBUTE_ARCHIVE to this as this mode is only used if the file is
3810 unx_mode = unix_mode(
3812 new_dos_attributes | FILE_ATTRIBUTE_ARCHIVE,
3814 parent_dir_fname->fsp);
3817 DEBUG(10, ("open_file_ntcreate: fname=%s, dos_attrs=0x%x "
3818 "access_mask=0x%x share_access=0x%x "
3819 "create_disposition = 0x%x create_options=0x%x "
3820 "unix mode=0%o oplock_request=%d private_flags = 0x%x\n",
3821 smb_fname_str_dbg(smb_fname), new_dos_attributes,
3822 access_mask, share_access, create_disposition,
3823 create_options, (unsigned int)unx_mode, oplock_request,
3824 (unsigned int)private_flags));
3827 /* Ensure req == NULL means INTERNAL_OPEN_ONLY */
3828 SMB_ASSERT(oplock_request == INTERNAL_OPEN_ONLY);
3830 /* And req != NULL means no INTERNAL_OPEN_ONLY */
3831 SMB_ASSERT(((oplock_request & INTERNAL_OPEN_ONLY) == 0));
3835 * Only non-internal opens can be deferred at all
3839 struct deferred_open_record *open_rec;
3840 if (get_deferred_open_message_state(req, NULL, &open_rec)) {
3842 /* If it was an async create retry, the file
3845 if (is_deferred_open_async(open_rec)) {
3846 SET_STAT_INVALID(smb_fname->st);
3847 file_existed = false;
3850 /* Ensure we don't reprocess this message. */
3851 remove_deferred_open_message_smb(req->xconn, req->mid);
3853 first_open_attempt = false;
3858 new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
3861 * Only use stored DOS attributes for checks
3862 * against requested attributes (below via
3863 * open_match_attributes()), cf bug #11992
3864 * for details. -slow
3868 status = SMB_VFS_FGET_DOS_ATTRIBUTES(
3870 metadata_fsp(smb_fname->fsp),
3872 if (NT_STATUS_IS_OK(status)) {
3873 existing_dos_attributes = attr;
3878 /* ignore any oplock requests if oplocks are disabled */
3879 if (!lp_oplocks(SNUM(conn)) ||
3880 IS_VETO_OPLOCK_PATH(conn, smb_fname->base_name)) {
3881 /* Mask off everything except the private Samba bits. */
3882 oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
3885 /* this is for OS/2 long file names - say we don't support them */
3886 if (req != NULL && !req->posix_pathnames &&
3887 strstr(smb_fname->base_name,".+,;=[].")) {
3888 /* OS/2 Workplace shell fix may be main code stream in a later
3890 DEBUG(5,("open_file_ntcreate: OS/2 long filenames are not "
3892 if (use_nt_status()) {
3893 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3895 return NT_STATUS_DOS(ERRDOS, ERRcannotopen);
3898 switch( create_disposition ) {
3900 /* If file exists open. If file doesn't exist error. */
3901 if (!file_existed) {
3902 DEBUG(5,("open_file_ntcreate: FILE_OPEN "
3903 "requested for file %s and file "
3905 smb_fname_str_dbg(smb_fname)));
3906 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3910 case FILE_OVERWRITE:
3911 /* If file exists overwrite. If file doesn't exist
3913 if (!file_existed) {
3914 DEBUG(5,("open_file_ntcreate: FILE_OVERWRITE "
3915 "requested for file %s and file "
3917 smb_fname_str_dbg(smb_fname) ));
3918 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3921 return NT_STATUS_MEDIA_WRITE_PROTECTED;
3926 /* If file exists error. If file doesn't exist
3929 DEBUG(5,("open_file_ntcreate: FILE_CREATE "
3930 "requested for file %s and file "
3931 "already exists.\n",
3932 smb_fname_str_dbg(smb_fname)));
3933 if (S_ISDIR(smb_fname->st.st_ex_mode)) {
3934 return NT_STATUS_FILE_IS_A_DIRECTORY;
3936 return NT_STATUS_OBJECT_NAME_COLLISION;
3939 return NT_STATUS_MEDIA_WRITE_PROTECTED;
3943 case FILE_SUPERSEDE:
3944 case FILE_OVERWRITE_IF:
3946 return NT_STATUS_MEDIA_WRITE_PROTECTED;
3951 if (!file_existed) {
3952 return NT_STATUS_MEDIA_WRITE_PROTECTED;
3954 create_disposition = FILE_OPEN;
3958 return NT_STATUS_INVALID_PARAMETER;
3961 flags = disposition_to_open_flags(create_disposition);
3963 /* We only care about matching attributes on file exists and
3966 if (!posix_open && file_existed &&
3967 ((create_disposition == FILE_OVERWRITE) ||
3968 (create_disposition == FILE_OVERWRITE_IF))) {
3969 if (!open_match_attributes(conn, existing_dos_attributes,
3971 unx_mode, &new_unx_mode)) {
3972 DEBUG(5,("open_file_ntcreate: attributes mismatch "
3973 "for file %s (%x %x) (0%o, 0%o)\n",
3974 smb_fname_str_dbg(smb_fname),
3975 existing_dos_attributes,
3977 (unsigned int)smb_fname->st.st_ex_mode,
3978 (unsigned int)unx_mode ));
3979 return NT_STATUS_ACCESS_DENIED;
3983 status = smbd_calculate_access_mask_fsp(parent_dir_fname->fsp,
3988 if (!NT_STATUS_IS_OK(status)) {
3989 DBG_DEBUG("smbd_calculate_access_mask_fsp "
3990 "on file %s returned %s\n",
3991 smb_fname_str_dbg(smb_fname),
3996 open_access_mask = access_mask;
3998 if (flags & O_TRUNC) {
3999 open_access_mask |= FILE_WRITE_DATA; /* This will cause oplock breaks. */
4004 * stat opens on existing files don't get oplocks.
4005 * They can get leases.
4007 * Note that we check for stat open on the *open_access_mask*,
4008 * i.e. the access mask we actually used to do the open,
4009 * not the one the client asked for (which is in
4010 * fsp->access_mask). This is due to the fact that
4011 * FILE_OVERWRITE and FILE_OVERWRITE_IF add in O_TRUNC,
4012 * which adds FILE_WRITE_DATA to open_access_mask.
4014 if (is_oplock_stat_open(open_access_mask) && lease == NULL) {
4015 oplock_request = NO_OPLOCK;
4019 DEBUG(10, ("open_file_ntcreate: fname=%s, after mapping "
4020 "access_mask=0x%x\n", smb_fname_str_dbg(smb_fname),
4024 * Note that we ignore the append flag as append does not
4025 * mean the same thing under DOS and Unix.
4028 flags |= calculate_open_access_flags(access_mask,
4033 * Currently we only look at FILE_WRITE_THROUGH for create options.
4037 if ((create_options & FILE_WRITE_THROUGH) && lp_strict_sync(SNUM(conn))) {
4042 if (posix_open && (access_mask & FILE_APPEND_DATA)) {
4046 if (!posix_open && !CAN_WRITE(conn)) {
4048 * We should really return a permission denied error if either
4049 * O_CREAT or O_TRUNC are set, but for compatibility with
4050 * older versions of Samba we just AND them out.
4052 flags &= ~(O_CREAT | O_TRUNC);
4056 * With kernel oplocks the open breaking an oplock
4057 * blocks until the oplock holder has given up the
4058 * oplock or closed the file. We prevent this by always
4059 * trying to open the file with O_NONBLOCK (see "man
4062 * If a process that doesn't use the smbd open files
4063 * database or communication methods holds a kernel
4064 * oplock we must periodically poll for available open
4067 flags |= O_NONBLOCK;
4070 * Ensure we can't write on a read-only share or file.
4073 if (((flags & O_ACCMODE) != O_RDONLY) && file_existed &&
4074 (!CAN_WRITE(conn) ||
4075 (existing_dos_attributes & FILE_ATTRIBUTE_READONLY))) {
4076 DEBUG(5,("open_file_ntcreate: write access requested for "
4077 "file %s on read only %s\n",
4078 smb_fname_str_dbg(smb_fname),
4079 !CAN_WRITE(conn) ? "share" : "file" ));
4080 return NT_STATUS_ACCESS_DENIED;
4083 if (VALID_STAT(smb_fname->st)) {
4085 * Only try and create a file id before open
4086 * for an existing file. For a file being created
4087 * this won't do anything useful until the file
4088 * exists and has a valid stat struct.
4090 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
4092 fh_set_private_options(fsp->fh, private_flags);
4093 fsp->access_mask = open_access_mask; /* We change this to the
4094 * requested access_mask after
4095 * the open is done. */
4097 fsp->posix_flags |= FSP_POSIX_FLAGS_ALL;
4100 if ((create_options & FILE_DELETE_ON_CLOSE) && (flags & O_CREAT) &&
4102 /* Delete on close semantics for new files. */
4103 status = can_set_delete_on_close(fsp,
4104 new_dos_attributes);
4105 if (!NT_STATUS_IS_OK(status)) {
4112 * Ensure we pay attention to default ACLs on directories if required.
4115 if ((flags & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
4116 (def_acl = directory_has_default_acl_fsp(parent_dir_fname->fsp))) {
4117 unx_mode = (0777 & lp_create_mask(SNUM(conn)));
4121 ("calling open_file with flags=0x%X mode=0%o, "
4122 "access_mask = 0x%x, open_access_mask = 0x%x\n",
4123 (unsigned int)flags,
4124 (unsigned int)unx_mode,
4125 (unsigned int)access_mask,
4126 (unsigned int)open_access_mask));
4129 struct vfs_open_how how = {
4134 if (create_options & FILE_OPEN_FOR_BACKUP_INTENT) {
4135 how.resolve |= VFS_OPEN_HOW_WITH_BACKUP_INTENT;
4138 fsp_open = open_file(req,
4139 parent_dir_fname->fsp,
4148 if (NT_STATUS_EQUAL(fsp_open, NT_STATUS_NETWORK_BUSY)) {
4149 if (file_existed && S_ISFIFO(fsp->fsp_name->st.st_ex_mode)) {
4150 DEBUG(10, ("FIFO busy\n"));
4151 return NT_STATUS_NETWORK_BUSY;
4154 DEBUG(10, ("Internal open busy\n"));
4155 return NT_STATUS_NETWORK_BUSY;
4158 * This handles the kernel oplock case:
4160 * the file has an active kernel oplock and the open() returned
4161 * EWOULDBLOCK/EAGAIN which maps to NETWORK_BUSY.
4163 * "Samba locking.tdb oplocks" are handled below after acquiring
4164 * the sharemode lock with get_share_mode_lock().
4169 if (NT_STATUS_EQUAL(fsp_open, NT_STATUS_RETRY)) {
4171 * EINTR from the open(2) syscall. Just setup a retry
4172 * in a bit. We can't use the sys_write() tight retry
4173 * loop here, as we might have to actually deal with
4174 * lease-break signals to avoid a deadlock.
4181 * Retry once a second. If there's a share_mode_lock
4182 * around, also wait for it in case it was smbd
4183 * holding that kernel oplock that can quickly tell us
4184 * the oplock got removed.
4187 setup_poll_open(req,
4189 tevent_timeval_set(OPLOCK_BREAK_TIMEOUT * 2,
4191 tevent_timeval_set(1, 0));
4193 return NT_STATUS_SHARING_VIOLATION;
4196 if (!NT_STATUS_IS_OK(fsp_open)) {
4197 bool wait_for_aio = NT_STATUS_EQUAL(
4198 fsp_open, NT_STATUS_MORE_PROCESSING_REQUIRED);
4200 schedule_async_open(req);
4205 if (new_file_created) {
4207 * As we atomically create using O_CREAT|O_EXCL,
4208 * then if new_file_created is true, then
4209 * file_existed *MUST* have been false (even
4210 * if the file was previously detected as being
4213 file_existed = false;
4216 if (file_existed && !check_same_dev_ino(&saved_stat, &smb_fname->st)) {
4218 * The file did exist, but some other (local or NFS)
4219 * process either renamed/unlinked and re-created the
4220 * file with different dev/ino after we walked the path,
4221 * but before we did the open. We could retry the
4222 * open but it's a rare enough case it's easier to
4223 * just fail the open to prevent creating any problems
4224 * in the open file db having the wrong dev/ino key.
4227 DBG_WARNING("file %s - dev/ino mismatch. "
4228 "Old (dev=%ju, ino=%ju). "
4229 "New (dev=%ju, ino=%ju). Failing open "
4230 "with NT_STATUS_ACCESS_DENIED.\n",
4231 smb_fname_str_dbg(smb_fname),
4232 (uintmax_t)saved_stat.st_ex_dev,
4233 (uintmax_t)saved_stat.st_ex_ino,
4234 (uintmax_t)smb_fname->st.st_ex_dev,
4235 (uintmax_t)smb_fname->st.st_ex_ino);
4236 return NT_STATUS_ACCESS_DENIED;
4239 old_write_time = smb_fname->st.st_ex_mtime;
4242 * Deal with the race condition where two smbd's detect the
4243 * file doesn't exist and do the create at the same time. One
4244 * of them will win and set a share mode, the other (ie. this
4245 * one) should check if the requested share mode for this
4246 * create is allowed.
4250 * Now the file exists and fsp is successfully opened,
4251 * fsp->dev and fsp->inode are valid and should replace the
4252 * dev=0,inode=0 from a non existent file. Spotted by
4253 * Nadav Danieli <nadavd@exanet.com>. JRA.
4256 if (new_file_created) {
4257 info = FILE_WAS_CREATED;
4259 if (flags & O_TRUNC) {
4260 info = FILE_WAS_OVERWRITTEN;
4262 info = FILE_WAS_OPENED;
4267 * If we created a new file, overwrite an existing one
4268 * or going to delete it later, we should keep
4269 * the share_mode_lock (g_lock) until we call
4270 * share_mode_entry_prepare_unlock()
4272 if (info != FILE_WAS_OPENED) {
4274 } else if (create_options & FILE_DELETE_ON_CLOSE) {
4278 lck_state = (struct open_ntcreate_lock_state) {
4280 .object_type = "file",
4282 .create_disposition = create_disposition,
4283 .access_mask = access_mask,
4284 .share_access = share_access,
4285 .oplock_request = oplock_request,
4287 .first_open_attempt = first_open_attempt,
4288 .keep_locked = keep_locked,
4291 status = share_mode_entry_prepare_lock_add(&lck_state.prepare_state,
4296 open_ntcreate_lock_add_entry,
4298 if (!NT_STATUS_IS_OK(status)) {
4299 DBG_ERR("share_mode_entry_prepare_lock_add() failed for %s - %s\n",
4300 smb_fname_str_dbg(smb_fname), nt_errstr(status));
4305 status = lck_state.status;
4306 if (!NT_STATUS_IS_OK(status)) {
4312 * From here we need to use 'goto unlock;' instead of return !!!
4315 if (fsp->oplock_type != NO_OPLOCK && fsp->oplock_type != LEASE_OPLOCK) {
4317 * Now ask for kernel oplocks
4318 * and cleanup on failure.
4320 status = set_file_oplock(fsp);
4321 if (!NT_STATUS_IS_OK(status)) {
4323 * Could not get the kernel oplock
4325 lck_state.cleanup_fn =
4326 open_ntcreate_lock_cleanup_oplock;
4327 fsp->oplock_type = NO_OPLOCK;
4331 /* Should we atomically (to the client at least) truncate ? */
4332 if ((!new_file_created) && (flags & O_TRUNC) &&
4333 (S_ISREG(fsp->fsp_name->st.st_ex_mode))) {
4336 ret = SMB_VFS_FTRUNCATE(fsp, 0);
4338 status = map_nt_error_from_unix(errno);
4339 lck_state.cleanup_fn =
4340 open_ntcreate_lock_cleanup_entry;
4343 notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
4344 FILE_NOTIFY_CHANGE_SIZE
4345 | FILE_NOTIFY_CHANGE_ATTRIBUTES,
4346 fsp->fsp_name->base_name);
4350 * We have the share entry *locked*.....
4353 /* Delete streams if create_disposition requires it */
4354 if (!new_file_created &&
4355 clear_ads(create_disposition) &&
4356 !fsp_is_alternate_stream(fsp)) {
4357 status = delete_all_streams(conn, smb_fname);
4358 if (!NT_STATUS_IS_OK(status)) {
4359 lck_state.cleanup_fn =
4360 open_ntcreate_lock_cleanup_entry;
4365 if (!fsp->fsp_flags.is_pathref &&
4366 fsp_get_io_fd(fsp) != -1 &&
4367 lp_kernel_share_modes(SNUM(conn)))
4371 * Beware: streams implementing VFS modules may
4372 * implement streams in a way that fsp will have the
4373 * basefile open in the fsp fd, so lacking a distinct
4374 * fd for the stream the file-system sharemode will
4375 * apply on the basefile which is wrong. The actual
4376 * check is deferred to the VFS module implementing
4377 * the file-system sharemode call.
4379 ret = SMB_VFS_FILESYSTEM_SHAREMODE(fsp,
4383 status = NT_STATUS_SHARING_VIOLATION;
4384 lck_state.cleanup_fn =
4385 open_ntcreate_lock_cleanup_entry;
4389 fsp->fsp_flags.kernel_share_modes_taken = true;
4393 * At this point onwards, we can guarantee that the share entry
4394 * is locked, whether we created the file or not, and that the
4395 * deny mode is compatible with all current opens.
4399 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
4400 * but we don't have to store this - just ignore it on access check.
4402 if (conn_using_smb2(conn->sconn)) {
4404 * SMB2 doesn't return it (according to Microsoft tests).
4405 * Test Case: TestSuite_ScenarioNo009GrantedAccessTestS0
4406 * File created with access = 0x7 (Read, Write, Delete)
4407 * Query Info on file returns 0x87 (Read, Write, Delete, Read Attributes)
4409 fsp->access_mask = access_mask;
4411 /* But SMB1 does. */
4412 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
4419 /* Handle strange delete on close create semantics. */
4420 if (create_options & FILE_DELETE_ON_CLOSE) {
4421 if (!new_file_created) {
4422 status = can_set_delete_on_close(fsp,
4423 existing_dos_attributes);
4425 if (!NT_STATUS_IS_OK(status)) {
4426 /* Remember to delete the mode we just added. */
4427 lck_state.cleanup_fn =
4428 open_ntcreate_lock_cleanup_entry;
4432 /* Note that here we set the *initial* delete on close flag,
4433 not the regular one. The magic gets handled in close. */
4434 fsp->fsp_flags.initial_delete_on_close = true;
4437 possibly_set_archive(conn,
4443 &smb_fname->st.st_ex_mode);
4445 /* Determine sparse flag. */
4447 /* POSIX opens are sparse by default. */
4448 fsp->fsp_flags.is_sparse = true;
4450 fsp->fsp_flags.is_sparse =
4451 (existing_dos_attributes & FILE_ATTRIBUTE_SPARSE);
4455 * Take care of inherited ACLs on created files - if default ACL not
4459 if (!posix_open && new_file_created && !def_acl) {
4460 if (unx_mode != smb_fname->st.st_ex_mode) {
4461 int ret = SMB_VFS_FCHMOD(fsp, unx_mode);
4463 DBG_INFO("failed to reset "
4464 "attributes of file %s to 0%o\n",
4465 smb_fname_str_dbg(smb_fname),
4466 (unsigned int)unx_mode);
4470 } else if (new_unx_mode) {
4472 * We only get here in the case of:
4474 * a). Not a POSIX open.
4475 * b). File already existed.
4476 * c). File was overwritten.
4477 * d). Requested DOS attributes didn't match
4478 * the DOS attributes on the existing file.
4480 * In that case new_unx_mode has been set
4481 * equal to the calculated mode (including
4482 * possible inheritance of the mode from the
4483 * containing directory).
4485 * Note this mode was calculated with the
4486 * DOS attribute FILE_ATTRIBUTE_ARCHIVE added,
4487 * so the mode change here is suitable for
4488 * an overwritten file.
4491 if (new_unx_mode != smb_fname->st.st_ex_mode) {
4492 int ret = SMB_VFS_FCHMOD(fsp, new_unx_mode);
4494 DBG_INFO("failed to reset "
4495 "attributes of file %s to 0%o\n",
4496 smb_fname_str_dbg(smb_fname),
4497 (unsigned int)new_unx_mode);
4503 * Deal with other opens having a modified write time.
4505 if (fsp_getinfo_ask_sharemode(fsp) &&
4506 !is_omit_timespec(&lck_state.write_time))
4508 update_stat_ex_mtime(&fsp->fsp_name->st, lck_state.write_time);
4511 status = NT_STATUS_OK;
4514 ulstatus = share_mode_entry_prepare_unlock(&lck_state.prepare_state,
4515 lck_state.cleanup_fn,
4517 if (!NT_STATUS_IS_OK(ulstatus)) {
4518 DBG_ERR("share_mode_entry_prepare_unlock() failed for %s - %s\n",
4519 smb_fname_str_dbg(smb_fname), nt_errstr(ulstatus));
4520 smb_panic("share_mode_entry_prepare_unlock() failed!");
4523 if (!NT_STATUS_IS_OK(status)) {
4528 return NT_STATUS_OK;
4531 static NTSTATUS mkdir_internal(connection_struct *conn,
4532 struct smb_filename *parent_dir_fname, /* parent. */
4533 struct smb_filename *smb_fname_atname, /* atname relative to parent. */
4534 struct smb_filename *smb_dname, /* full pathname from root of share. */
4535 uint32_t file_attributes,
4536 struct files_struct *fsp)
4538 const struct loadparm_substitution *lp_sub =
4539 loadparm_s3_global_substitution();
4542 bool posix_open = false;
4543 bool need_re_stat = false;
4544 uint32_t access_mask = SEC_DIR_ADD_SUBDIR;
4545 struct vfs_open_how how = { .flags = O_RDONLY|O_DIRECTORY, };
4548 if (!CAN_WRITE(conn) || (access_mask & ~(conn->share_access))) {
4549 DEBUG(5,("mkdir_internal: failing share access "
4550 "%s\n", lp_servicename(talloc_tos(), lp_sub, SNUM(conn))));
4551 return NT_STATUS_ACCESS_DENIED;
4554 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
4556 mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
4558 mode = unix_mode(conn,
4559 FILE_ATTRIBUTE_DIRECTORY,
4561 parent_dir_fname->fsp);
4564 status = check_parent_access_fsp(parent_dir_fname->fsp, access_mask);
4565 if(!NT_STATUS_IS_OK(status)) {
4566 DBG_INFO("check_parent_access_fsp "
4567 "on directory %s for path %s returned %s\n",
4568 smb_fname_str_dbg(parent_dir_fname),
4569 smb_dname->base_name,
4574 if (lp_inherit_acls(SNUM(conn))) {
4575 if (directory_has_default_acl_fsp(parent_dir_fname->fsp)) {
4576 mode = (0777 & lp_directory_mask(SNUM(conn)));
4580 ret = SMB_VFS_MKDIRAT(conn,
4581 parent_dir_fname->fsp,
4585 return map_nt_error_from_unix(errno);
4589 * Make this a pathref fsp for now. open_directory() will reopen as a
4592 fsp->fsp_flags.is_pathref = true;
4594 status = fd_openat(parent_dir_fname->fsp, smb_fname_atname, fsp, &how);
4595 if (!NT_STATUS_IS_OK(status)) {
4599 /* Ensure we're checking for a symlink here.... */
4600 /* We don't want to get caught by a symlink racer. */
4602 status = vfs_stat_fsp(fsp);
4603 if (!NT_STATUS_IS_OK(status)) {
4604 DEBUG(2, ("Could not stat directory '%s' just created: %s\n",
4605 smb_fname_str_dbg(smb_dname), nt_errstr(status)));
4609 if (!S_ISDIR(smb_dname->st.st_ex_mode)) {
4610 DEBUG(0, ("Directory '%s' just created is not a directory !\n",
4611 smb_fname_str_dbg(smb_dname)));
4612 return NT_STATUS_NOT_A_DIRECTORY;
4615 if (lp_store_dos_attributes(SNUM(conn))) {
4616 file_set_dosmode(conn,
4618 file_attributes | FILE_ATTRIBUTE_DIRECTORY,
4623 if (lp_inherit_permissions(SNUM(conn))) {
4624 inherit_access_posix_acl(conn, parent_dir_fname->fsp,
4626 need_re_stat = true;
4631 * Check if high bits should have been set,
4632 * then (if bits are missing): add them.
4633 * Consider bits automagically set by UNIX, i.e. SGID bit from parent
4636 if ((mode & ~(S_IRWXU|S_IRWXG|S_IRWXO)) &&
4637 (mode & ~smb_dname->st.st_ex_mode)) {
4639 (smb_dname->st.st_ex_mode |
4640 (mode & ~smb_dname->st.st_ex_mode)));
4641 need_re_stat = true;
4645 /* Change the owner if required. */
4646 if (lp_inherit_owner(SNUM(conn)) != INHERIT_OWNER_NO) {
4647 change_dir_owner_to_parent_fsp(parent_dir_fname->fsp,
4649 need_re_stat = true;
4653 status = vfs_stat_fsp(fsp);
4654 if (!NT_STATUS_IS_OK(status)) {
4655 DEBUG(2, ("Could not stat directory '%s' just created: %s\n",
4656 smb_fname_str_dbg(smb_dname), nt_errstr(status)));
4661 notify_fname(conn, NOTIFY_ACTION_ADDED, FILE_NOTIFY_CHANGE_DIR_NAME,
4662 smb_dname->base_name);
4664 return NT_STATUS_OK;
4667 /****************************************************************************
4668 Open a directory from an NT SMB call.
4669 ****************************************************************************/
4671 static NTSTATUS open_directory(connection_struct *conn,
4672 struct smb_request *req,
4673 uint32_t access_mask,
4674 uint32_t share_access,
4675 uint32_t create_disposition,
4676 uint32_t create_options,
4677 uint32_t file_attributes,
4678 struct smb_filename *parent_dir_fname,
4679 struct smb_filename *smb_fname_atname,
4681 struct files_struct *fsp)
4683 struct smb_filename *smb_dname = fsp->fsp_name;
4684 bool dir_existed = VALID_STAT(smb_dname->st);
4685 struct open_ntcreate_lock_state lck_state = {};
4686 bool keep_locked = false;
4688 struct timespec mtimespec;
4690 uint32_t need_fd_access;
4693 if (is_ntfs_stream_smb_fname(smb_dname)) {
4694 DEBUG(2, ("open_directory: %s is a stream name!\n",
4695 smb_fname_str_dbg(smb_dname)));
4696 return NT_STATUS_NOT_A_DIRECTORY;
4699 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS)) {
4700 /* Ensure we have a directory attribute. */
4701 file_attributes |= FILE_ATTRIBUTE_DIRECTORY;
4704 DBG_INFO("opening directory %s, access_mask = 0x%"PRIx32", "
4705 "share_access = 0x%"PRIx32" create_options = 0x%"PRIx32", "
4706 "create_disposition = 0x%"PRIx32", "
4707 "file_attributes = 0x%"PRIx32"\n",
4708 smb_fname_str_dbg(smb_dname),
4715 status = smbd_calculate_access_mask_fsp(parent_dir_fname->fsp,
4720 if (!NT_STATUS_IS_OK(status)) {
4721 DBG_DEBUG("smbd_calculate_access_mask_fsp "
4722 "on file %s returned %s\n",
4723 smb_fname_str_dbg(smb_dname),
4728 if ((access_mask & SEC_FLAG_SYSTEM_SECURITY) &&
4729 !security_token_has_privilege(get_current_nttok(conn),
4730 SEC_PRIV_SECURITY)) {
4731 DEBUG(10, ("open_directory: open on %s "
4732 "failed - SEC_FLAG_SYSTEM_SECURITY denied.\n",
4733 smb_fname_str_dbg(smb_dname)));
4734 return NT_STATUS_PRIVILEGE_NOT_HELD;
4737 switch( create_disposition ) {
4741 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4744 info = FILE_WAS_OPENED;
4749 /* If directory exists error. If directory doesn't
4753 status = NT_STATUS_OBJECT_NAME_COLLISION;
4754 DEBUG(2, ("open_directory: unable to create "
4755 "%s. Error was %s\n",
4756 smb_fname_str_dbg(smb_dname),
4757 nt_errstr(status)));
4761 if (smb_fname_atname->twrp != 0) {
4762 return NT_STATUS_MEDIA_WRITE_PROTECTED;
4765 status = mkdir_internal(conn,
4772 if (!NT_STATUS_IS_OK(status)) {
4773 DEBUG(2, ("open_directory: unable to create "
4774 "%s. Error was %s\n",
4775 smb_fname_str_dbg(smb_dname),
4776 nt_errstr(status)));
4780 info = FILE_WAS_CREATED;
4785 * If directory exists open. If directory doesn't
4790 status = NT_STATUS_OK;
4791 info = FILE_WAS_OPENED;
4793 if (smb_fname_atname->twrp != 0) {
4794 return NT_STATUS_MEDIA_WRITE_PROTECTED;
4796 status = mkdir_internal(conn,
4803 if (NT_STATUS_IS_OK(status)) {
4804 info = FILE_WAS_CREATED;
4807 /* Cope with create race. */
4808 if (!NT_STATUS_EQUAL(status,
4809 NT_STATUS_OBJECT_NAME_COLLISION)) {
4810 DEBUG(2, ("open_directory: unable to create "
4811 "%s. Error was %s\n",
4812 smb_fname_str_dbg(smb_dname),
4813 nt_errstr(status)));
4818 * If mkdir_internal() returned
4819 * NT_STATUS_OBJECT_NAME_COLLISION
4820 * we still must lstat the path.
4822 ret = SMB_VFS_FSTATAT(
4824 parent_dir_fname->fsp,
4827 AT_SYMLINK_NOFOLLOW);
4829 DEBUG(2, ("Could not stat "
4830 "directory '%s' just "
4835 return map_nt_error_from_unix(
4839 info = FILE_WAS_OPENED;
4845 case FILE_SUPERSEDE:
4846 case FILE_OVERWRITE:
4847 case FILE_OVERWRITE_IF:
4849 DEBUG(5,("open_directory: invalid create_disposition "
4850 "0x%x for directory %s\n",
4851 (unsigned int)create_disposition,
4852 smb_fname_str_dbg(smb_dname)));
4853 return NT_STATUS_INVALID_PARAMETER;
4856 if(!S_ISDIR(smb_dname->st.st_ex_mode)) {
4857 DEBUG(5,("open_directory: %s is not a directory !\n",
4858 smb_fname_str_dbg(smb_dname)));
4859 return NT_STATUS_NOT_A_DIRECTORY;
4863 * Setup the files_struct for it.
4866 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_dname->st);
4867 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
4868 fsp->file_pid = req ? req->smbpid : 0;
4869 fsp->fsp_flags.can_lock = false;
4870 fsp->fsp_flags.can_read = false;
4871 fsp->fsp_flags.can_write = false;
4873 fh_set_private_options(fsp->fh, 0);
4875 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
4877 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
4878 fsp->print_file = NULL;
4879 fsp->fsp_flags.modified = false;
4880 fsp->oplock_type = NO_OPLOCK;
4881 fsp->sent_oplock_break = NO_BREAK_SENT;
4882 fsp->fsp_flags.is_directory = true;
4883 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
4884 fsp->posix_flags |= FSP_POSIX_FLAGS_ALL;
4887 /* Don't store old timestamps for directory
4888 handles in the internal database. We don't
4889 update them in there if new objects
4890 are created in the directory. Currently
4891 we only update timestamps on file writes.
4894 mtimespec = make_omit_timespec();
4897 * Obviously for FILE_LIST_DIRECTORY we need to reopen to get an fd
4898 * usable for reading a directory. SMB2_FLUSH may be called on
4899 * directories opened with FILE_ADD_FILE and FILE_ADD_SUBDIRECTORY so
4900 * for those we need to reopen as well.
4903 FILE_LIST_DIRECTORY |
4905 FILE_ADD_SUBDIRECTORY;
4907 if (access_mask & need_fd_access) {
4908 struct vfs_open_how how = {
4909 .flags = O_RDONLY | O_DIRECTORY,
4913 status = reopen_from_fsp(parent_dir_fname->fsp,
4918 if (!NT_STATUS_IS_OK(status)) {
4919 DBG_INFO("Could not open fd for [%s]: %s\n",
4920 smb_fname_str_dbg(smb_dname),
4926 status = vfs_stat_fsp(fsp);
4927 if (!NT_STATUS_IS_OK(status)) {
4932 if(!S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
4933 DEBUG(5,("open_directory: %s is not a directory !\n",
4934 smb_fname_str_dbg(smb_dname)));
4936 return NT_STATUS_NOT_A_DIRECTORY;
4939 /* Ensure there was no race condition. We need to check
4940 * dev/inode but not permissions, as these can change
4942 if (!check_same_dev_ino(&smb_dname->st, &fsp->fsp_name->st)) {
4943 DEBUG(5,("open_directory: stat struct differs for "
4945 smb_fname_str_dbg(smb_dname)));
4947 return NT_STATUS_ACCESS_DENIED;
4950 if (info == FILE_WAS_OPENED) {
4951 status = smbd_check_access_rights_fsp(parent_dir_fname->fsp,
4955 if (!NT_STATUS_IS_OK(status)) {
4956 DBG_DEBUG("smbd_check_access_rights_fsp on "
4957 "file %s failed with %s\n",
4966 * If we created a new directory or going to delete it later,
4967 * we should keep * the share_mode_lock (g_lock) until we call
4968 * share_mode_entry_prepare_unlock()
4970 if (info != FILE_WAS_OPENED) {
4972 } else if (create_options & FILE_DELETE_ON_CLOSE) {
4976 lck_state = (struct open_ntcreate_lock_state) {
4978 .object_type = "directory",
4980 .create_disposition = create_disposition,
4981 .access_mask = access_mask,
4982 .share_access = share_access,
4983 .oplock_request = NO_OPLOCK,
4985 .first_open_attempt = true,
4986 .keep_locked = keep_locked,
4989 status = share_mode_entry_prepare_lock_add(&lck_state.prepare_state,
4994 open_ntcreate_lock_add_entry,
4996 if (!NT_STATUS_IS_OK(status)) {
4997 DBG_ERR("share_mode_entry_prepare_lock_add() failed for %s - %s\n",
4998 smb_fname_str_dbg(smb_dname), nt_errstr(status));
5003 status = lck_state.status;
5004 if (!NT_STATUS_IS_OK(status)) {
5010 * From here we need to use 'goto unlock;' instead of return !!!
5013 /* For directories the delete on close bit at open time seems
5014 always to be honored on close... See test 19 in Samba4 BASE-DELETE. */
5015 if (create_options & FILE_DELETE_ON_CLOSE) {
5016 status = can_set_delete_on_close(fsp, 0);
5017 if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
5018 lck_state.cleanup_fn =
5019 open_ntcreate_lock_cleanup_entry;
5023 if (NT_STATUS_IS_OK(status)) {
5024 /* Note that here we set the *initial* delete on close flag,
5025 not the regular one. The magic gets handled in close. */
5026 fsp->fsp_flags.initial_delete_on_close = true;
5031 * Deal with other opens having a modified write time.
5033 if (!is_omit_timespec(&lck_state.write_time)) {
5034 update_stat_ex_mtime(&fsp->fsp_name->st, lck_state.write_time);
5041 status = NT_STATUS_OK;
5044 ulstatus = share_mode_entry_prepare_unlock(&lck_state.prepare_state,
5045 lck_state.cleanup_fn,
5047 if (!NT_STATUS_IS_OK(ulstatus)) {
5048 DBG_ERR("share_mode_entry_prepare_unlock() failed for %s - %s\n",
5049 smb_fname_str_dbg(smb_dname), nt_errstr(ulstatus));
5050 smb_panic("share_mode_entry_prepare_unlock() failed!");
5053 if (!NT_STATUS_IS_OK(status)) {
5058 return NT_STATUS_OK;
5061 NTSTATUS create_directory(connection_struct *conn,
5062 struct smb_request *req,
5063 struct files_struct *dirfsp,
5064 struct smb_filename *smb_dname)
5069 status = SMB_VFS_CREATE_FILE(
5072 dirfsp, /* dirfsp */
5073 smb_dname, /* fname */
5074 FILE_READ_ATTRIBUTES, /* access_mask */
5075 FILE_SHARE_NONE, /* share_access */
5076 FILE_CREATE, /* create_disposition*/
5077 FILE_DIRECTORY_FILE, /* create_options */
5078 FILE_ATTRIBUTE_DIRECTORY, /* file_attributes */
5079 0, /* oplock_request */
5081 0, /* allocation_size */
5082 0, /* private_flags */
5087 NULL, NULL); /* create context */
5089 if (NT_STATUS_IS_OK(status)) {
5090 close_file_free(req, &fsp, NORMAL_CLOSE);
5096 /****************************************************************************
5097 Receive notification that one of our open files has been renamed by another
5099 ****************************************************************************/
5101 void msg_file_was_renamed(struct messaging_context *msg_ctx,
5104 struct server_id src,
5107 struct file_rename_message *msg = NULL;
5108 enum ndr_err_code ndr_err;
5110 struct smb_filename *smb_fname = NULL;
5111 struct smbd_server_connection *sconn =
5112 talloc_get_type_abort(private_data,
5113 struct smbd_server_connection);
5115 msg = talloc(talloc_tos(), struct file_rename_message);
5117 DBG_WARNING("talloc failed\n");
5121 ndr_err = ndr_pull_struct_blob_all(
5125 (ndr_pull_flags_fn_t)ndr_pull_file_rename_message);
5126 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
5127 DBG_DEBUG("ndr_pull_oplock_break_message failed: %s\n",
5128 ndr_errstr(ndr_err));
5131 if (DEBUGLEVEL >= 10) {
5132 struct server_id_buf buf;
5133 DBG_DEBUG("Got rename message from %s\n",
5134 server_id_str_buf(src, &buf));
5135 NDR_PRINT_DEBUG(file_rename_message, msg);
5138 /* stream_name must always be NULL if there is no stream. */
5139 if ((msg->stream_name != NULL) && (msg->stream_name[0] == '\0')) {
5140 msg->stream_name = NULL;
5143 smb_fname = synthetic_smb_fname(msg,
5149 if (smb_fname == NULL) {
5150 DBG_DEBUG("synthetic_smb_fname failed\n");
5154 fsp = file_find_dif(sconn, msg->id, msg->share_file_id);
5156 DBG_DEBUG("fsp not found\n");
5160 if (strcmp(fsp->conn->connectpath, msg->servicepath) == 0) {
5161 SMB_STRUCT_STAT fsp_orig_sbuf;
5163 DBG_DEBUG("renaming file %s from %s -> %s\n",
5166 smb_fname_str_dbg(smb_fname));
5169 * The incoming smb_fname here has an
5170 * invalid stat struct from synthetic_smb_fname()
5172 * Preserve the existing stat from the
5173 * open fsp after fsp_set_smb_fname()
5174 * overwrites with the invalid stat.
5176 * (We could just copy this into
5177 * smb_fname->st, but keep this code
5178 * identical to the fix in rename_open_files()
5181 * We will do an fstat before returning
5182 * any of this metadata to the client anyway.
5184 fsp_orig_sbuf = fsp->fsp_name->st;
5185 status = fsp_set_smb_fname(fsp, smb_fname);
5186 if (!NT_STATUS_IS_OK(status)) {
5187 DBG_DEBUG("fsp_set_smb_fname failed: %s\n",
5190 fsp->fsp_name->st = fsp_orig_sbuf;
5194 * Now we have the complete path we can work out if
5195 * this is actually within this share and adjust
5196 * newname accordingly.
5198 DBG_DEBUG("share mismatch (sharepath %s not sharepath %s) "
5199 "%s from %s -> %s\n",
5200 fsp->conn->connectpath,
5204 smb_fname_str_dbg(smb_fname));
5211 * If a main file is opened for delete, all streams need to be checked for
5212 * !FILE_SHARE_DELETE. Do this by opening with DELETE_ACCESS.
5213 * If that works, delete them all by setting the delete on close and close.
5216 static NTSTATUS open_streams_for_delete(connection_struct *conn,
5217 const struct smb_filename *smb_fname)
5219 struct stream_struct *stream_info = NULL;
5220 files_struct **streams = NULL;
5222 unsigned int i, num_streams = 0;
5223 TALLOC_CTX *frame = talloc_stackframe();
5224 const struct smb_filename *pathref = NULL;
5227 if (smb_fname->fsp == NULL) {
5228 struct smb_filename *tmp = NULL;
5229 status = synthetic_pathref(frame,
5231 smb_fname->base_name,
5237 if (!NT_STATUS_IS_OK(status)) {
5238 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
5239 || NT_STATUS_EQUAL(status,
5240 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
5241 DBG_DEBUG("no streams around\n");
5243 return NT_STATUS_OK;
5245 DBG_DEBUG("synthetic_pathref failed: %s\n",
5251 pathref = smb_fname;
5253 status = vfs_fstreaminfo(pathref->fsp, talloc_tos(),
5254 &num_streams, &stream_info);
5256 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
5257 || NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
5258 DEBUG(10, ("no streams around\n"));
5260 return NT_STATUS_OK;
5263 if (!NT_STATUS_IS_OK(status)) {
5264 DEBUG(10, ("vfs_fstreaminfo failed: %s\n",
5265 nt_errstr(status)));
5269 DEBUG(10, ("open_streams_for_delete found %d streams\n",
5272 if (num_streams == 0) {
5274 return NT_STATUS_OK;
5277 streams = talloc_array(talloc_tos(), files_struct *, num_streams);
5278 if (streams == NULL) {
5279 DEBUG(0, ("talloc failed\n"));
5280 status = NT_STATUS_NO_MEMORY;
5284 for (i=0; i<num_streams; i++) {
5285 struct smb_filename *smb_fname_cp;
5287 if (strequal(stream_info[i].name, "::$DATA")) {
5292 smb_fname_cp = synthetic_smb_fname(talloc_tos(),
5293 smb_fname->base_name,
5294 stream_info[i].name,
5298 ~SMB_FILENAME_POSIX_PATH));
5299 if (smb_fname_cp == NULL) {
5300 status = NT_STATUS_NO_MEMORY;
5304 status = openat_pathref_fsp(conn->cwd_fsp, smb_fname_cp);
5305 if (!NT_STATUS_IS_OK(status)) {
5306 DBG_DEBUG("Unable to open stream [%s]: %s\n",
5307 smb_fname_str_dbg(smb_fname_cp),
5309 TALLOC_FREE(smb_fname_cp);
5313 status = SMB_VFS_CREATE_FILE(
5317 smb_fname_cp, /* fname */
5318 DELETE_ACCESS, /* access_mask */
5319 (FILE_SHARE_READ | /* share_access */
5320 FILE_SHARE_WRITE | FILE_SHARE_DELETE),
5321 FILE_OPEN, /* create_disposition*/
5322 0, /* create_options */
5323 FILE_ATTRIBUTE_NORMAL, /* file_attributes */
5324 0, /* oplock_request */
5326 0, /* allocation_size */
5327 0, /* private_flags */
5330 &streams[i], /* result */
5332 NULL, NULL); /* create context */
5334 if (!NT_STATUS_IS_OK(status)) {
5335 DEBUG(10, ("Could not open stream %s: %s\n",
5336 smb_fname_str_dbg(smb_fname_cp),
5337 nt_errstr(status)));
5339 TALLOC_FREE(smb_fname_cp);
5342 TALLOC_FREE(smb_fname_cp);
5346 * don't touch the variable "status" beyond this point :-)
5349 for (j = i-1 ; j >= 0; j--) {
5350 if (streams[j] == NULL) {
5354 DEBUG(10, ("Closing stream # %d, %s\n", j,
5355 fsp_str_dbg(streams[j])));
5356 close_file_free(NULL, &streams[j], NORMAL_CLOSE);
5364 /*********************************************************************
5365 Create a default ACL by inheriting from the parent. If no inheritance
5366 from the parent available, don't set anything. This will leave the actual
5367 permissions the new file or directory already got from the filesystem
5368 as the NT ACL when read.
5369 *********************************************************************/
5371 static NTSTATUS inherit_new_acl(files_struct *dirfsp, files_struct *fsp)
5373 TALLOC_CTX *frame = talloc_stackframe();
5374 struct security_descriptor *parent_desc = NULL;
5375 NTSTATUS status = NT_STATUS_OK;
5376 struct security_descriptor *psd = NULL;
5377 const struct dom_sid *owner_sid = NULL;
5378 const struct dom_sid *group_sid = NULL;
5379 uint32_t security_info_sent = (SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL);
5380 struct security_token *token = fsp->conn->session_info->security_token;
5381 bool inherit_owner =
5382 (lp_inherit_owner(SNUM(fsp->conn)) == INHERIT_OWNER_WINDOWS_AND_UNIX);
5383 bool inheritable_components = false;
5384 bool try_builtin_administrators = false;
5385 const struct dom_sid *BA_U_sid = NULL;
5386 const struct dom_sid *BA_G_sid = NULL;
5387 bool try_system = false;
5388 const struct dom_sid *SY_U_sid = NULL;
5389 const struct dom_sid *SY_G_sid = NULL;
5393 status = SMB_VFS_FGET_NT_ACL(dirfsp,
5394 (SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL),
5397 if (!NT_STATUS_IS_OK(status)) {
5402 inheritable_components = sd_has_inheritable_components(parent_desc,
5403 fsp->fsp_flags.is_directory);
5405 if (!inheritable_components && !inherit_owner) {
5407 /* Nothing to inherit and not setting owner. */
5408 return NT_STATUS_OK;
5411 /* Create an inherited descriptor from the parent. */
5413 if (DEBUGLEVEL >= 10) {
5414 DEBUG(10,("inherit_new_acl: parent acl for %s is:\n",
5415 fsp_str_dbg(fsp) ));
5416 NDR_PRINT_DEBUG(security_descriptor, parent_desc);
5419 /* Inherit from parent descriptor if "inherit owner" set. */
5420 if (inherit_owner) {
5421 owner_sid = parent_desc->owner_sid;
5422 group_sid = parent_desc->group_sid;
5425 if (owner_sid == NULL) {
5426 if (security_token_has_builtin_administrators(token)) {
5427 try_builtin_administrators = true;
5428 } else if (security_token_is_system(token)) {
5429 try_builtin_administrators = true;
5434 if (group_sid == NULL &&
5435 token->num_sids == PRIMARY_GROUP_SID_INDEX)
5437 if (security_token_is_system(token)) {
5438 try_builtin_administrators = true;
5443 if (try_builtin_administrators) {
5444 struct unixid ids = { .id = 0 };
5446 ok = sids_to_unixids(&global_sid_Builtin_Administrators, 1, &ids);
5450 BA_U_sid = &global_sid_Builtin_Administrators;
5451 BA_G_sid = &global_sid_Builtin_Administrators;
5454 BA_U_sid = &global_sid_Builtin_Administrators;
5457 BA_G_sid = &global_sid_Builtin_Administrators;
5466 struct unixid ids = { .id = 0 };
5468 ok = sids_to_unixids(&global_sid_System, 1, &ids);
5472 SY_U_sid = &global_sid_System;
5473 SY_G_sid = &global_sid_System;
5476 SY_U_sid = &global_sid_System;
5479 SY_G_sid = &global_sid_System;
5487 if (owner_sid == NULL) {
5488 owner_sid = BA_U_sid;
5491 if (owner_sid == NULL) {
5492 owner_sid = SY_U_sid;
5495 if (group_sid == NULL) {
5496 group_sid = SY_G_sid;
5499 if (try_system && group_sid == NULL) {
5500 group_sid = BA_G_sid;
5503 if (owner_sid == NULL) {
5504 owner_sid = &token->sids[PRIMARY_USER_SID_INDEX];
5506 if (group_sid == NULL) {
5507 if (token->num_sids == PRIMARY_GROUP_SID_INDEX) {
5508 group_sid = &token->sids[PRIMARY_USER_SID_INDEX];
5510 group_sid = &token->sids[PRIMARY_GROUP_SID_INDEX];
5514 status = se_create_child_secdesc(frame,
5520 fsp->fsp_flags.is_directory);
5521 if (!NT_STATUS_IS_OK(status)) {
5526 /* If inheritable_components == false,
5527 se_create_child_secdesc()
5528 creates a security descriptor with a NULL dacl
5529 entry, but with SEC_DESC_DACL_PRESENT. We need
5530 to remove that flag. */
5532 if (!inheritable_components) {
5533 security_info_sent &= ~SECINFO_DACL;
5534 psd->type &= ~SEC_DESC_DACL_PRESENT;
5537 if (DEBUGLEVEL >= 10) {
5538 DEBUG(10,("inherit_new_acl: child acl for %s is:\n",
5539 fsp_str_dbg(fsp) ));
5540 NDR_PRINT_DEBUG(security_descriptor, psd);
5543 if (inherit_owner) {
5544 /* We need to be root to force this. */
5547 status = SMB_VFS_FSET_NT_ACL(metadata_fsp(fsp),
5550 if (inherit_owner) {
5558 * If we already have a lease, it must match the new file id. [MS-SMB2]
5559 * 3.3.5.9.8 speaks about INVALID_PARAMETER if an already used lease key is
5560 * used for a different file name.
5563 struct lease_match_state {
5564 /* Input parameters. */
5565 TALLOC_CTX *mem_ctx;
5566 const char *servicepath;
5567 const struct smb_filename *fname;
5570 /* Return parameters. */
5571 uint32_t num_file_ids;
5572 struct file_id *ids;
5573 NTSTATUS match_status;
5576 /*************************************************************
5577 File doesn't exist but this lease key+guid is already in use.
5579 This is only allowable in the dynamic share case where the
5580 service path must be different.
5582 There is a small race condition here in the multi-connection
5583 case where a client sends two create calls on different connections,
5584 where the file doesn't exist and one smbd creates the leases_db
5585 entry first, but this will get fixed by the multichannel cleanup
5586 when all identical client_guids get handled by a single smbd.
5587 **************************************************************/
5589 static void lease_match_parser_new_file(
5591 const struct leases_db_file *files,
5592 struct lease_match_state *state)
5596 for (i = 0; i < num_files; i++) {
5597 const struct leases_db_file *f = &files[i];
5598 if (strequal(state->servicepath, f->servicepath)) {
5599 state->match_status = NT_STATUS_INVALID_PARAMETER;
5604 /* Dynamic share case. Break leases on all other files. */
5605 state->match_status = leases_db_copy_file_ids(state->mem_ctx,
5609 if (!NT_STATUS_IS_OK(state->match_status)) {
5613 state->num_file_ids = num_files;
5614 state->match_status = NT_STATUS_OPLOCK_NOT_GRANTED;
5618 static void lease_match_parser(
5620 const struct leases_db_file *files,
5623 struct lease_match_state *state =
5624 (struct lease_match_state *)private_data;
5627 if (!state->file_existed) {
5629 * Deal with name mismatch or
5630 * possible dynamic share case separately
5631 * to make code clearer.
5633 lease_match_parser_new_file(num_files,
5640 state->match_status = NT_STATUS_OK;
5642 for (i = 0; i < num_files; i++) {
5643 const struct leases_db_file *f = &files[i];
5645 /* Everything should be the same. */
5646 if (!file_id_equal(&state->id, &f->id)) {
5648 * The client asked for a lease on a
5649 * file that doesn't match the file_id
5652 * Maybe this is a dynamic share, i.e.
5653 * a share where the servicepath is
5654 * different for different users (e.g.
5655 * the [HOMES] share.
5657 * If the servicepath is different, but the requested
5658 * file name + stream name is the same then this is
5659 * a dynamic share, the client is using the same share
5660 * name and doesn't know that the underlying servicepath
5661 * is different. It was expecting a lease on the
5662 * same file. Return NT_STATUS_OPLOCK_NOT_GRANTED
5665 * Otherwise the client has messed up, or is
5666 * testing our error codes, so return
5667 * NT_STATUS_INVALID_PARAMETER.
5669 if (!strequal(f->servicepath, state->servicepath) &&
5670 strequal(f->base_name, state->fname->base_name) &&
5671 strequal(f->stream_name, state->fname->stream_name))
5674 * Name is the same but servicepath is
5675 * different, dynamic share. Break leases.
5677 state->match_status =
5678 NT_STATUS_OPLOCK_NOT_GRANTED;
5680 state->match_status =
5681 NT_STATUS_INVALID_PARAMETER;
5685 if (!strequal(f->servicepath, state->servicepath)) {
5686 state->match_status = NT_STATUS_INVALID_PARAMETER;
5689 if (!strequal(f->base_name, state->fname->base_name)) {
5690 state->match_status = NT_STATUS_INVALID_PARAMETER;
5693 if (!strequal(f->stream_name, state->fname->stream_name)) {
5694 state->match_status = NT_STATUS_INVALID_PARAMETER;
5699 if (NT_STATUS_IS_OK(state->match_status)) {
5701 * Common case - just opening another handle on a
5702 * file on a non-dynamic share.
5707 if (NT_STATUS_EQUAL(state->match_status, NT_STATUS_INVALID_PARAMETER)) {
5708 /* Mismatched path. Error back to client. */
5713 * File id mismatch. Dynamic share case NT_STATUS_OPLOCK_NOT_GRANTED.
5714 * Don't allow leases.
5717 state->match_status = leases_db_copy_file_ids(state->mem_ctx,
5721 if (!NT_STATUS_IS_OK(state->match_status)) {
5725 state->num_file_ids = num_files;
5726 state->match_status = NT_STATUS_OPLOCK_NOT_GRANTED;
5730 struct lease_match_break_state {
5731 struct messaging_context *msg_ctx;
5732 const struct smb2_lease_key *lease_key;
5740 static bool lease_match_break_fn(
5741 struct share_mode_entry *e,
5744 struct lease_match_break_state *state = private_data;
5746 uint32_t e_lease_type = SMB2_LEASE_NONE;
5749 stale = share_entry_stale_pid(e);
5754 equal = smb2_lease_key_equal(&e->lease_key, state->lease_key);
5759 status = leases_db_get(
5763 &e_lease_type, /* current_state */
5764 NULL, /* breaking */
5765 NULL, /* breaking_to_requested */
5766 NULL, /* breaking_to_required */
5767 &state->version, /* lease_version */
5768 &state->epoch); /* epoch */
5769 if (NT_STATUS_IS_OK(status)) {
5770 state->found_lease = true;
5772 DBG_WARNING("Could not find version/epoch: %s\n",
5777 if (e_lease_type == SMB2_LEASE_NONE) {
5780 send_break_message(state->msg_ctx, &state->id, e, SMB2_LEASE_NONE);
5783 * Windows 7 and 8 lease clients are broken in that they will
5784 * not respond to lease break requests whilst waiting for an
5785 * outstanding open request on that lease handle on the same
5786 * TCP connection, due to holding an internal inode lock.
5788 * This means we can't reschedule ourselves here, but must
5789 * return from the create.
5793 * Send the breaks and then return SMB2_LEASE_NONE in the
5794 * lease handle to cause them to acknowledge the lease
5795 * break. Consultation with Microsoft engineering confirmed
5796 * this approach is safe.
5802 static void lease_match_fid_fn(struct share_mode_lock *lck,
5807 ok = share_mode_forall_leases(lck, lease_match_break_fn, private_data);
5809 DBG_DEBUG("share_mode_forall_leases failed\n");
5813 static NTSTATUS lease_match(connection_struct *conn,
5814 struct smb_request *req,
5815 const struct smb2_lease_key *lease_key,
5816 const char *servicepath,
5817 const struct smb_filename *fname,
5818 uint16_t *p_version,
5821 struct smbd_server_connection *sconn = req->sconn;
5822 TALLOC_CTX *tos = talloc_tos();
5823 struct lease_match_state state = {
5825 .servicepath = servicepath,
5827 .match_status = NT_STATUS_OK
5832 state.file_existed = VALID_STAT(fname->st);
5833 if (state.file_existed) {
5834 state.id = vfs_file_id_from_sbuf(conn, &fname->st);
5837 status = leases_db_parse(&sconn->client->global->client_guid,
5838 lease_key, lease_match_parser, &state);
5839 if (!NT_STATUS_IS_OK(status)) {
5841 * Not found or error means okay: We can make the lease pass
5843 return NT_STATUS_OK;
5845 if (!NT_STATUS_EQUAL(state.match_status, NT_STATUS_OPLOCK_NOT_GRANTED)) {
5847 * Anything but NT_STATUS_OPLOCK_NOT_GRANTED, let the caller
5850 return state.match_status;
5853 /* We have to break all existing leases. */
5854 for (i = 0; i < state.num_file_ids; i++) {
5855 struct lease_match_break_state break_state = {
5856 .msg_ctx = conn->sconn->msg_ctx,
5857 .lease_key = lease_key,
5860 if (file_id_equal(&state.ids[i], &state.id)) {
5861 /* Don't need to break our own file. */
5865 break_state.id = state.ids[i];
5867 status = share_mode_do_locked_vfs_denied(break_state.id,
5870 if (!NT_STATUS_IS_OK(status)) {
5871 /* Race condition - file already closed. */
5875 if (break_state.found_lease) {
5876 *p_version = break_state.version;
5877 *p_epoch = break_state.epoch;
5881 * Ensure we don't grant anything more so we
5884 return NT_STATUS_OPLOCK_NOT_GRANTED;
5888 * Wrapper around open_file_ntcreate and open_directory
5891 static NTSTATUS create_file_unixpath(connection_struct *conn,
5892 struct smb_request *req,
5893 struct files_struct *dirfsp,
5894 struct smb_filename *smb_fname,
5895 uint32_t access_mask,
5896 uint32_t share_access,
5897 uint32_t create_disposition,
5898 uint32_t create_options,
5899 uint32_t file_attributes,
5900 uint32_t oplock_request,
5901 const struct smb2_lease *lease,
5902 uint64_t allocation_size,
5903 uint32_t private_flags,
5904 struct security_descriptor *sd,
5905 struct ea_list *ea_list,
5907 files_struct **result,
5910 struct smb2_lease none_lease;
5911 int info = FILE_WAS_OPENED;
5912 files_struct *base_fsp = NULL;
5913 files_struct *fsp = NULL;
5914 bool free_fsp_on_error = false;
5917 struct smb_filename *parent_dir_fname = NULL;
5918 struct smb_filename *smb_fname_atname = NULL;
5920 DBG_DEBUG("access_mask = 0x%"PRIx32" "
5921 "file_attributes = 0x%"PRIx32" "
5922 "share_access = 0x%"PRIx32" "
5923 "create_disposition = 0x%"PRIx32" "
5924 "create_options = 0x%"PRIx32" "
5925 "oplock_request = 0x%"PRIx32" "
5926 "private_flags = 0x%"PRIx32" "
5939 smb_fname_str_dbg(smb_fname));
5941 if (create_options & FILE_OPEN_BY_FILE_ID) {
5942 status = NT_STATUS_NOT_SUPPORTED;
5946 if (create_options & NTCREATEX_OPTIONS_INVALID_PARAM_MASK) {
5947 status = NT_STATUS_INVALID_PARAMETER;
5951 if (!(create_options & FILE_OPEN_REPARSE_POINT) &&
5952 (smb_fname->fsp != NULL) && /* new files don't have an fsp */
5953 VALID_STAT(smb_fname->fsp->fsp_name->st))
5955 mode_t type = (smb_fname->fsp->fsp_name->st.st_ex_mode &
5965 * We should never get this far with a symlink
5966 * "as such". Report as not existing.
5968 status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
5971 status = NT_STATUS_IO_REPARSE_TAG_NOT_HANDLED;
5977 oplock_request |= INTERNAL_OPEN_ONLY;
5980 if (lease != NULL) {
5981 uint16_t epoch = lease->lease_epoch;
5982 uint16_t version = lease->lease_version;
5985 DBG_WARNING("Got lease on internal open\n");
5986 status = NT_STATUS_INTERNAL_ERROR;
5990 status = lease_match(conn,
5997 if (NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) {
5998 /* Dynamic share file. No leases and update epoch... */
5999 none_lease = *lease;
6000 none_lease.lease_state = SMB2_LEASE_NONE;
6001 none_lease.lease_epoch = epoch;
6002 none_lease.lease_version = version;
6003 lease = &none_lease;
6004 } else if (!NT_STATUS_IS_OK(status)) {
6009 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
6010 && (access_mask & DELETE_ACCESS)
6011 && !is_named_stream(smb_fname)) {
6013 * We can't open a file with DELETE access if any of the
6014 * streams is open without FILE_SHARE_DELETE
6016 status = open_streams_for_delete(conn, smb_fname);
6018 if (!NT_STATUS_IS_OK(status)) {
6023 if (access_mask & SEC_FLAG_SYSTEM_SECURITY) {
6026 ok = security_token_has_privilege(get_current_nttok(conn),
6029 DBG_DEBUG("open on %s failed - "
6030 "SEC_FLAG_SYSTEM_SECURITY denied.\n",
6031 smb_fname_str_dbg(smb_fname));
6032 status = NT_STATUS_PRIVILEGE_NOT_HELD;
6036 if (conn_using_smb2(conn->sconn) &&
6037 (access_mask == SEC_FLAG_SYSTEM_SECURITY))
6040 * No other bits set. Windows SMB2 refuses this.
6041 * See smbtorture3 SMB2-SACL test.
6043 * Note this is an SMB2-only behavior,
6044 * smbtorture3 SMB1-SYSTEM-SECURITY already tests
6045 * that SMB1 allows this.
6047 status = NT_STATUS_ACCESS_DENIED;
6053 * Files or directories can't be opened DELETE_ON_CLOSE without
6055 * BUG: https://bugzilla.samba.org/show_bug.cgi?id=13358
6057 if ((create_options & FILE_DELETE_ON_CLOSE) &&
6058 ((access_mask & DELETE_ACCESS) == 0)) {
6059 status = NT_STATUS_INVALID_PARAMETER;
6063 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
6064 && is_named_stream(smb_fname))
6066 uint32_t base_create_disposition;
6067 struct smb_filename *smb_fname_base = NULL;
6068 uint32_t base_privflags;
6070 if (create_options & FILE_DIRECTORY_FILE) {
6071 DBG_DEBUG("Can't open a stream as directory\n");
6072 status = NT_STATUS_NOT_A_DIRECTORY;
6076 switch (create_disposition) {
6078 base_create_disposition = FILE_OPEN;
6081 base_create_disposition = FILE_OPEN_IF;
6085 smb_fname_base = cp_smb_filename_nostream(
6086 talloc_tos(), smb_fname);
6088 if (smb_fname_base == NULL) {
6089 status = NT_STATUS_NO_MEMORY;
6094 * We may be creating the basefile as part of creating the
6095 * stream, so it's legal if the basefile doesn't exist at this
6096 * point, the create_file_unixpath() below will create it. But
6097 * if the basefile exists we want a handle so we can fstat() it.
6100 ret = vfs_stat(conn, smb_fname_base);
6101 if (ret == -1 && errno != ENOENT) {
6102 status = map_nt_error_from_unix(errno);
6103 TALLOC_FREE(smb_fname_base);
6107 status = openat_pathref_fsp(conn->cwd_fsp,
6109 if (!NT_STATUS_IS_OK(status)) {
6110 DBG_ERR("open_smb_fname_fsp [%s] failed: %s\n",
6111 smb_fname_str_dbg(smb_fname_base),
6113 TALLOC_FREE(smb_fname_base);
6118 * https://bugzilla.samba.org/show_bug.cgi?id=10229
6119 * We need to check if the requested access mask
6120 * could be used to open the underlying file (if
6121 * it existed), as we're passing in zero for the
6122 * access mask to the base filename.
6124 status = check_base_file_access(smb_fname_base->fsp,
6127 if (!NT_STATUS_IS_OK(status)) {
6128 DEBUG(10, ("Permission check "
6129 "for base %s failed: "
6130 "%s\n", smb_fname->base_name,
6131 nt_errstr(status)));
6132 TALLOC_FREE(smb_fname_base);
6137 base_privflags = NTCREATEX_FLAG_STREAM_BASEOPEN;
6139 /* Open the base file. */
6140 status = create_file_unixpath(conn,
6147 | FILE_SHARE_DELETE,
6148 base_create_disposition,
6159 TALLOC_FREE(smb_fname_base);
6161 if (!NT_STATUS_IS_OK(status)) {
6162 DEBUG(10, ("create_file_unixpath for base %s failed: "
6163 "%s\n", smb_fname->base_name,
6164 nt_errstr(status)));
6169 if (smb_fname->fsp != NULL) {
6171 fsp = smb_fname->fsp;
6174 * We're about to use smb_fname->fsp for the fresh open.
6176 * Every fsp passed in via smb_fname->fsp already
6177 * holds a fsp->fsp_name. If it is already this
6178 * fsp->fsp_name that we got passed in as our input
6179 * argument smb_fname, these two are assumed to have
6180 * the same lifetime: Every fsp hangs of "conn", and
6181 * fsp->fsp_name is its talloc child.
6184 if (smb_fname != smb_fname->fsp->fsp_name) {
6186 * "smb_fname" is temporary in this case, but
6187 * the destructor of smb_fname would also tear
6188 * down the fsp we're about to use. Unlink
6189 * them from each other.
6191 smb_fname_fsp_unlink(smb_fname);
6196 free_fsp_on_error = true;
6199 status = fsp_bind_smb(fsp, req);
6200 if (!NT_STATUS_IS_OK(status)) {
6204 if (fsp_is_alternate_stream(fsp)) {
6205 struct files_struct *tmp_base_fsp = fsp->base_fsp;
6207 fsp_set_base_fsp(fsp, NULL);
6209 fd_close(tmp_base_fsp);
6210 file_free(NULL, tmp_base_fsp);
6214 * No fsp passed in that we can use, create one
6216 status = file_new(req, conn, &fsp);
6217 if(!NT_STATUS_IS_OK(status)) {
6220 free_fsp_on_error = true;
6222 status = fsp_set_smb_fname(fsp, smb_fname);
6223 if (!NT_STATUS_IS_OK(status)) {
6228 SMB_ASSERT(fsp->fsp_name->fsp != NULL);
6229 SMB_ASSERT(fsp->fsp_name->fsp == fsp);
6233 * We're opening the stream element of a
6234 * base_fsp we already opened. Set up the
6237 fsp_set_base_fsp(fsp, base_fsp);
6240 if (dirfsp != NULL) {
6241 status = SMB_VFS_PARENT_PATHNAME(
6247 if (!NT_STATUS_IS_OK(status)) {
6252 * Get a pathref on the parent. We can re-use this for
6253 * multiple calls to check parent ACLs etc. to avoid
6256 status = parent_pathref(talloc_tos(),
6261 if (!NT_STATUS_IS_OK(status)) {
6265 dirfsp = parent_dir_fname->fsp;
6266 status = fsp_set_smb_fname(dirfsp, parent_dir_fname);
6267 if (!NT_STATUS_IS_OK(status)) {
6273 * If it's a request for a directory open, deal with it separately.
6276 if (create_options & FILE_DIRECTORY_FILE) {
6278 if (create_options & FILE_NON_DIRECTORY_FILE) {
6279 status = NT_STATUS_INVALID_PARAMETER;
6283 /* Can't open a temp directory. IFS kit test. */
6284 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
6285 (file_attributes & FILE_ATTRIBUTE_TEMPORARY)) {
6286 status = NT_STATUS_INVALID_PARAMETER;
6291 * We will get a create directory here if the Win32
6292 * app specified a security descriptor in the
6293 * CreateDirectory() call.
6297 status = open_directory(conn,
6311 * Ordinary file case.
6314 if (allocation_size) {
6315 fsp->initial_allocation_size = smb_roundup(fsp->conn,
6319 status = open_file_ntcreate(conn,
6333 if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
6335 /* A stream open never opens a directory */
6338 status = NT_STATUS_FILE_IS_A_DIRECTORY;
6343 * Fail the open if it was explicitly a non-directory
6347 if (create_options & FILE_NON_DIRECTORY_FILE) {
6348 status = NT_STATUS_FILE_IS_A_DIRECTORY;
6353 status = open_directory(conn,
6367 if (!NT_STATUS_IS_OK(status)) {
6371 fsp->fsp_flags.is_fsa = true;
6373 if ((ea_list != NULL) &&
6374 ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN))) {
6375 status = set_ea(conn, fsp, ea_list);
6376 if (!NT_STATUS_IS_OK(status)) {
6381 if (!fsp->fsp_flags.is_directory &&
6382 S_ISDIR(fsp->fsp_name->st.st_ex_mode))
6384 status = NT_STATUS_ACCESS_DENIED;
6388 /* Save the requested allocation size. */
6389 if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
6390 if ((allocation_size > (uint64_t)fsp->fsp_name->st.st_ex_size)
6391 && !(fsp->fsp_flags.is_directory))
6393 fsp->initial_allocation_size = smb_roundup(
6394 fsp->conn, allocation_size);
6395 if (vfs_allocate_file_space(
6396 fsp, fsp->initial_allocation_size) == -1) {
6397 status = NT_STATUS_DISK_FULL;
6401 fsp->initial_allocation_size = smb_roundup(
6402 fsp->conn, (uint64_t)fsp->fsp_name->st.st_ex_size);
6405 fsp->initial_allocation_size = 0;
6408 if ((info == FILE_WAS_CREATED) &&
6409 lp_nt_acl_support(SNUM(conn)) &&
6410 !fsp_is_alternate_stream(fsp)) {
6413 * According to the MS documentation, the only time the security
6414 * descriptor is applied to the opened file is iff we *created* the
6415 * file; an existing file stays the same.
6417 * Also, it seems (from observation) that you can open the file with
6418 * any access mask but you can still write the sd. We need to override
6419 * the granted access before we call set_sd
6420 * Patch for bug #2242 from Tom Lackemann <cessnatomny@yahoo.com>.
6423 uint32_t sec_info_sent;
6424 uint32_t saved_access_mask = fsp->access_mask;
6426 sec_info_sent = get_sec_info(sd);
6428 fsp->access_mask = FILE_GENERIC_ALL;
6430 if (sec_info_sent & (SECINFO_OWNER|
6434 status = set_sd(fsp, sd, sec_info_sent);
6437 fsp->access_mask = saved_access_mask;
6439 if (!NT_STATUS_IS_OK(status)) {
6442 } else if (lp_inherit_acls(SNUM(conn))) {
6443 /* Inherit from parent. Errors here are not fatal. */
6444 status = inherit_new_acl(dirfsp, fsp);
6445 if (!NT_STATUS_IS_OK(status)) {
6446 DEBUG(10,("inherit_new_acl: failed for %s with %s\n",
6448 nt_errstr(status) ));
6453 if ((conn->fs_capabilities & FILE_FILE_COMPRESSION)
6454 && (create_options & FILE_NO_COMPRESSION)
6455 && (info == FILE_WAS_CREATED)) {
6456 status = SMB_VFS_SET_COMPRESSION(conn, fsp, fsp,
6457 COMPRESSION_FORMAT_NONE);
6458 if (!NT_STATUS_IS_OK(status)) {
6459 DEBUG(1, ("failed to disable compression: %s\n",
6460 nt_errstr(status)));
6464 DEBUG(10, ("create_file_unixpath: info=%d\n", info));
6467 if (pinfo != NULL) {
6471 smb_fname->st = fsp->fsp_name->st;
6473 TALLOC_FREE(parent_dir_fname);
6475 return NT_STATUS_OK;
6478 DEBUG(10, ("create_file_unixpath: %s\n", nt_errstr(status)));
6482 * The close_file below will close
6486 close_file_smb(req, fsp, ERROR_CLOSE);
6487 if (free_fsp_on_error) {
6488 file_free(req, fsp);
6492 if (base_fsp != NULL) {
6493 close_file_free(req, &base_fsp, ERROR_CLOSE);
6496 TALLOC_FREE(parent_dir_fname);
6501 NTSTATUS create_file_default(connection_struct *conn,
6502 struct smb_request *req,
6503 struct files_struct *dirfsp,
6504 struct smb_filename *smb_fname,
6505 uint32_t access_mask,
6506 uint32_t share_access,
6507 uint32_t create_disposition,
6508 uint32_t create_options,
6509 uint32_t file_attributes,
6510 uint32_t oplock_request,
6511 const struct smb2_lease *lease,
6512 uint64_t allocation_size,
6513 uint32_t private_flags,
6514 struct security_descriptor *sd,
6515 struct ea_list *ea_list,
6516 files_struct **result,
6518 const struct smb2_create_blobs *in_context_blobs,
6519 struct smb2_create_blobs *out_context_blobs)
6521 int info = FILE_WAS_OPENED;
6522 files_struct *fsp = NULL;
6524 bool stream_name = false;
6525 struct smb2_create_blob *posx = NULL;
6527 DBG_DEBUG("access_mask = 0x%" PRIu32
6528 " file_attributes = 0x%" PRIu32
6529 " share_access = 0x%" PRIu32
6530 " create_disposition = 0x%" PRIu32
6531 " create_options = 0x%" PRIu32
6532 " oplock_request = 0x%" PRIu32
6533 " private_flags = 0x%" PRIu32
6534 " ea_list = %p, sd = %p, fname = %s\n",
6544 smb_fname_str_dbg(smb_fname));
6548 * Remember the absolute time of the original request
6549 * with this mid. We'll use it later to see if this
6552 get_deferred_open_message_state(req, &req->request_time, NULL);
6556 * Check to see if this is a mac fork of some kind.
6559 stream_name = is_ntfs_stream_smb_fname(smb_fname);
6561 enum FAKE_FILE_TYPE fake_file_type;
6563 fake_file_type = is_fake_file(smb_fname);
6565 if (req != NULL && fake_file_type != FAKE_FILE_TYPE_NONE) {
6568 * Here we go! support for changing the disk quotas
6571 * We need to fake up to open this MAGIC QUOTA file
6572 * and return a valid FID.
6574 * w2k close this file directly after opening xp
6575 * also tries a QUERY_FILE_INFO on the file and then
6578 status = open_fake_file(req, conn, req->vuid,
6579 fake_file_type, smb_fname,
6581 if (!NT_STATUS_IS_OK(status)) {
6585 ZERO_STRUCT(smb_fname->st);
6589 if (!(conn->fs_capabilities & FILE_NAMED_STREAMS)) {
6590 status = NT_STATUS_OBJECT_NAME_INVALID;
6595 if (is_ntfs_default_stream_smb_fname(smb_fname)) {
6597 /* We have to handle this error here. */
6598 if (create_options & FILE_DIRECTORY_FILE) {
6599 status = NT_STATUS_NOT_A_DIRECTORY;
6602 ret = vfs_stat(conn, smb_fname);
6603 if (ret == 0 && VALID_STAT_OF_DIR(smb_fname->st)) {
6604 status = NT_STATUS_FILE_IS_A_DIRECTORY;
6609 posx = smb2_create_blob_find(
6610 in_context_blobs, SMB2_CREATE_TAG_POSIX);
6612 uint32_t wire_mode_bits = 0;
6613 mode_t mode_bits = 0;
6614 SMB_STRUCT_STAT sbuf = { 0 };
6615 enum perm_type ptype =
6616 (create_options & FILE_DIRECTORY_FILE) ?
6617 PERM_NEW_DIR : PERM_NEW_FILE;
6619 if (posx->data.length != 4) {
6620 status = NT_STATUS_INVALID_PARAMETER;
6624 wire_mode_bits = IVAL(posx->data.data, 0);
6625 status = unix_perms_from_wire(
6626 conn, &sbuf, wire_mode_bits, ptype, &mode_bits);
6627 if (!NT_STATUS_IS_OK(status)) {
6631 * Remove type info from mode, leaving only the
6632 * permissions and setuid/gid bits.
6634 mode_bits &= ~S_IFMT;
6636 file_attributes = (FILE_FLAG_POSIX_SEMANTICS | mode_bits);
6639 status = create_file_unixpath(conn,
6656 if (!NT_STATUS_IS_OK(status)) {
6661 DEBUG(10, ("create_file: info=%d\n", info));
6664 if (pinfo != NULL) {
6667 return NT_STATUS_OK;
6670 DEBUG(10, ("create_file: %s\n", nt_errstr(status)));
6673 close_file_free(req, &fsp, ERROR_CLOSE);