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"
45 extern const struct generic_mapping file_generic_mapping;
47 struct deferred_open_record {
48 struct smbXsrv_connection *xconn;
54 * Timer for async opens, needed because they don't use a watch on
55 * a locking.tdb record. This is currently only used for real async
56 * opens and just terminates smbd if the async open times out.
58 struct tevent_timer *te;
61 * For the samba kernel oplock case we use both a timeout and
62 * a watch on locking.tdb. This way in case it's smbd holding
63 * the kernel oplock we get directly notified for the retry
64 * once the kernel oplock is properly broken. Store the req
65 * here so that it can be timely discarded once the timer
68 struct tevent_req *watch_req;
71 /****************************************************************************
72 If the requester wanted DELETE_ACCESS and was rejected because
73 the file ACL didn't include DELETE_ACCESS, see if the parent ACL
75 ****************************************************************************/
77 static bool parent_override_delete(connection_struct *conn,
78 struct files_struct *dirfsp,
79 const struct smb_filename *smb_fname,
81 uint32_t rejected_mask)
83 if ((access_mask & DELETE_ACCESS) &&
84 (rejected_mask & DELETE_ACCESS) &&
85 can_delete_file_in_directory(conn,
94 /****************************************************************************
95 Check if we have open rights.
96 ****************************************************************************/
98 static NTSTATUS smbd_check_access_rights_fname(
99 struct connection_struct *conn,
100 const struct smb_filename *smb_fname,
102 uint32_t access_mask,
103 uint32_t do_not_check_mask)
105 uint32_t rejected_share_access;
106 uint32_t effective_access;
108 rejected_share_access = access_mask & ~(conn->share_access);
110 if (rejected_share_access) {
111 DBG_DEBUG("rejected share access 0x%"PRIx32" on "
112 "%s (0x%"PRIx32")\n",
114 smb_fname_str_dbg(smb_fname),
115 rejected_share_access);
116 return NT_STATUS_ACCESS_DENIED;
119 effective_access = access_mask & ~do_not_check_mask;
120 if (effective_access == 0) {
121 DBG_DEBUG("do_not_check_mask override on %s. Granting 0x%x for free.\n",
122 smb_fname_str_dbg(smb_fname),
123 (unsigned int)access_mask);
127 if (!use_privs && get_current_uid(conn) == (uid_t)0) {
128 /* I'm sorry sir, I didn't know you were root... */
129 DBG_DEBUG("root override on %s. Granting 0x%x\n",
130 smb_fname_str_dbg(smb_fname),
131 (unsigned int)access_mask);
135 if ((access_mask & DELETE_ACCESS) &&
136 !lp_acl_check_permissions(SNUM(conn)))
138 DBG_DEBUG("Not checking ACL on DELETE_ACCESS on file %s. "
139 "Granting 0x%"PRIx32"\n",
140 smb_fname_str_dbg(smb_fname),
145 if (access_mask == DELETE_ACCESS &&
146 VALID_STAT(smb_fname->st) &&
147 S_ISLNK(smb_fname->st.st_ex_mode))
149 /* We can always delete a symlink. */
150 DBG_DEBUG("Not checking ACL on DELETE_ACCESS on symlink %s.\n",
151 smb_fname_str_dbg(smb_fname));
155 return NT_STATUS_MORE_PROCESSING_REQUIRED;
158 static NTSTATUS smbd_check_access_rights_sd(
159 struct connection_struct *conn,
160 struct files_struct *dirfsp,
161 const struct smb_filename *smb_fname,
162 struct security_descriptor *sd,
164 uint32_t access_mask,
165 uint32_t do_not_check_mask)
167 uint32_t rejected_mask = access_mask;
174 status = se_file_access_check(sd,
175 get_current_nttok(conn),
177 (access_mask & ~do_not_check_mask),
180 DBG_DEBUG("File [%s] requesting [0x%"PRIx32"] "
181 "returning [0x%"PRIx32"] (%s)\n",
182 smb_fname_str_dbg(smb_fname),
187 if (!NT_STATUS_IS_OK(status)) {
188 if (DEBUGLEVEL >= 10) {
189 DBG_DEBUG("acl for %s is:\n",
190 smb_fname_str_dbg(smb_fname));
191 NDR_PRINT_DEBUG(security_descriptor, sd);
197 if (NT_STATUS_IS_OK(status) ||
198 !NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED))
203 /* Here we know status == NT_STATUS_ACCESS_DENIED. */
207 if ((access_mask & FILE_WRITE_ATTRIBUTES) &&
208 (rejected_mask & FILE_WRITE_ATTRIBUTES) &&
209 !lp_store_dos_attributes(SNUM(conn)) &&
210 (lp_map_readonly(SNUM(conn)) ||
211 lp_map_archive(SNUM(conn)) ||
212 lp_map_hidden(SNUM(conn)) ||
213 lp_map_system(SNUM(conn))))
215 rejected_mask &= ~FILE_WRITE_ATTRIBUTES;
217 DBG_DEBUG("overrode FILE_WRITE_ATTRIBUTES on file %s\n",
218 smb_fname_str_dbg(smb_fname));
221 if (parent_override_delete(conn,
228 * Were we trying to do an open for delete and didn't get DELETE
229 * access. Check if the directory allows DELETE_CHILD.
231 * http://blogs.msdn.com/oldnewthing/archive/2004/06/04/148426.aspx
235 rejected_mask &= ~DELETE_ACCESS;
237 DBG_DEBUG("Overrode DELETE_ACCESS on file %s\n",
238 smb_fname_str_dbg(smb_fname));
241 if (rejected_mask != 0) {
242 return NT_STATUS_ACCESS_DENIED;
247 NTSTATUS smbd_check_access_rights_fsp(struct files_struct *dirfsp,
248 struct files_struct *fsp,
250 uint32_t access_mask)
252 struct security_descriptor *sd = NULL;
253 uint32_t do_not_check_mask = 0;
256 /* Cope with fake/printer fsp's. */
257 if (fsp->fake_file_handle != NULL || fsp->print_file != NULL) {
258 if ((fsp->access_mask & access_mask) != access_mask) {
259 return NT_STATUS_ACCESS_DENIED;
264 if (fsp_get_pathref_fd(fsp) == -1) {
266 * This is a POSIX open on a symlink. For the pathname
267 * version of this function we used to return the st_mode
268 * bits turned into an NT ACL. For a symlink the mode bits
269 * are always rwxrwxrwx which means the pathname version always
270 * returned NT_STATUS_OK for a symlink. For the handle reference
271 * to a symlink use the handle access bits.
273 if ((fsp->access_mask & access_mask) != access_mask) {
274 return NT_STATUS_ACCESS_DENIED;
280 * If we can access the path to this file, by
281 * default we have FILE_READ_ATTRIBUTES from the
282 * containing directory. See the section:
283 * "Algorithm to Check Access to an Existing File"
286 * se_file_access_check() also takes care of
287 * owner WRITE_DAC and READ_CONTROL.
289 do_not_check_mask = FILE_READ_ATTRIBUTES;
292 * Samba 3.6 and earlier granted execute access even
293 * if the ACL did not contain execute rights.
294 * Samba 4.0 is more correct and checks it.
295 * The compatibilty mode allows one to skip this check
296 * to smoothen upgrades.
298 if (lp_acl_allow_execute_always(SNUM(fsp->conn))) {
299 do_not_check_mask |= FILE_EXECUTE;
302 status = smbd_check_access_rights_fname(fsp->conn,
307 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
311 status = SMB_VFS_FGET_NT_ACL(metadata_fsp(fsp),
317 if (!NT_STATUS_IS_OK(status)) {
318 DBG_DEBUG("Could not get acl on %s: %s\n",
324 return smbd_check_access_rights_sd(fsp->conn,
334 * Given an fsp that represents a parent directory,
335 * check if the requested access can be granted.
337 NTSTATUS check_parent_access_fsp(struct files_struct *fsp,
338 uint32_t access_mask)
341 struct security_descriptor *parent_sd = NULL;
342 uint32_t access_granted = 0;
343 struct share_mode_lock *lck = NULL;
345 bool delete_on_close_set;
346 TALLOC_CTX *frame = talloc_stackframe();
348 if (get_current_uid(fsp->conn) == (uid_t)0) {
349 /* I'm sorry sir, I didn't know you were root... */
350 DBG_DEBUG("root override on %s. Granting 0x%x\n",
352 (unsigned int)access_mask);
353 status = NT_STATUS_OK;
357 status = SMB_VFS_FGET_NT_ACL(fsp,
362 if (!NT_STATUS_IS_OK(status)) {
363 DBG_INFO("SMB_VFS_FGET_NT_ACL failed for "
364 "%s with error %s\n",
371 * If we can access the path to this file, by
372 * default we have FILE_READ_ATTRIBUTES from the
373 * containing directory. See the section:
374 * "Algorithm to Check Access to an Existing File"
377 * se_file_access_check() also takes care of
378 * owner WRITE_DAC and READ_CONTROL.
380 status = se_file_access_check(parent_sd,
381 get_current_nttok(fsp->conn),
383 (access_mask & ~FILE_READ_ATTRIBUTES),
385 if(!NT_STATUS_IS_OK(status)) {
386 DBG_INFO("access check "
387 "on directory %s for mask 0x%x returned (0x%x) %s\n",
395 if (!(access_mask & (SEC_DIR_ADD_FILE | SEC_DIR_ADD_SUBDIR))) {
396 status = NT_STATUS_OK;
399 if (!lp_check_parent_directory_delete_on_close(SNUM(fsp->conn))) {
400 status = NT_STATUS_OK;
404 /* Check if the directory has delete-on-close set */
405 status = file_name_hash(fsp->conn,
406 fsp->fsp_name->base_name,
408 if (!NT_STATUS_IS_OK(status)) {
413 * Don't take a lock here. We just need a snapshot
414 * of the current state of delete on close and this is
415 * called in a codepath where we may already have a lock
416 * (and we explicitly can't hold 2 locks at the same time
417 * as that may deadlock).
419 lck = fetch_share_mode_unlocked(frame, fsp->file_id);
421 status = NT_STATUS_OK;
425 delete_on_close_set = is_delete_on_close_set(lck, name_hash);
426 if (delete_on_close_set) {
427 status = NT_STATUS_DELETE_PENDING;
431 status = NT_STATUS_OK;
438 /****************************************************************************
439 Ensure when opening a base file for a stream open that we have permissions
440 to do so given the access mask on the base file.
441 ****************************************************************************/
443 static NTSTATUS check_base_file_access(struct files_struct *fsp,
444 uint32_t access_mask)
448 status = smbd_calculate_access_mask_fsp(fsp->conn->cwd_fsp,
453 if (!NT_STATUS_IS_OK(status)) {
454 DEBUG(10, ("smbd_calculate_access_mask "
455 "on file %s returned %s\n",
461 if (access_mask & (FILE_WRITE_DATA|FILE_APPEND_DATA)) {
463 if (!CAN_WRITE(fsp->conn)) {
464 return NT_STATUS_ACCESS_DENIED;
466 dosattrs = fdos_mode(fsp);
467 if (IS_DOS_READONLY(dosattrs)) {
468 return NT_STATUS_ACCESS_DENIED;
472 return smbd_check_access_rights_fsp(fsp->conn->cwd_fsp,
478 static NTSTATUS chdir_below_conn(
480 connection_struct *conn,
481 const char *connectpath,
482 size_t connectpath_len,
483 struct smb_filename *dir_fname,
484 struct smb_filename **_oldwd_fname)
486 struct smb_filename *oldwd_fname = NULL;
487 struct smb_filename *smb_fname_dot = NULL;
488 struct smb_filename *real_fname = NULL;
489 const char *relative = NULL;
494 if (!ISDOT(dir_fname->base_name)) {
496 oldwd_fname = vfs_GetWd(talloc_tos(), conn);
497 if (oldwd_fname == NULL) {
498 status = map_nt_error_from_unix(errno);
502 /* Pin parent directory in place. */
503 ret = vfs_ChDir(conn, dir_fname);
505 status = map_nt_error_from_unix(errno);
506 DBG_DEBUG("chdir to %s failed: %s\n",
507 dir_fname->base_name,
513 smb_fname_dot = synthetic_smb_fname(
520 if (smb_fname_dot == NULL) {
521 status = NT_STATUS_NO_MEMORY;
525 real_fname = SMB_VFS_REALPATH(conn, talloc_tos(), smb_fname_dot);
526 if (real_fname == NULL) {
527 status = map_nt_error_from_unix(errno);
528 DBG_DEBUG("realpath in %s failed: %s\n",
529 dir_fname->base_name,
533 TALLOC_FREE(smb_fname_dot);
535 ok = subdir_of(connectpath,
537 real_fname->base_name,
540 TALLOC_FREE(real_fname);
541 *_oldwd_fname = oldwd_fname;
545 DBG_NOTICE("Bad access attempt: %s is a symlink "
546 "outside the share path\n"
548 "resolved_name=%s\n",
549 dir_fname->base_name,
551 real_fname->base_name);
552 TALLOC_FREE(real_fname);
554 status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
557 if (oldwd_fname != NULL) {
558 ret = vfs_ChDir(conn, oldwd_fname);
559 SMB_ASSERT(ret == 0);
560 TALLOC_FREE(oldwd_fname);
567 * Get the symlink target of dirfsp/symlink_name, making sure the
568 * target is below connection_path.
571 static NTSTATUS symlink_target_below_conn(
573 const char *connection_path,
574 struct files_struct *fsp,
575 struct files_struct *dirfsp,
576 struct smb_filename *symlink_name,
580 char *absolute = NULL;
583 if (fsp_get_pathref_fd(fsp) != -1) {
585 * fsp is an O_PATH open, Linux does a "freadlink"
586 * with an empty name argument to readlinkat
588 status = readlink_talloc(talloc_tos(), fsp, NULL, &target);
590 status = readlink_talloc(
591 talloc_tos(), dirfsp, symlink_name, &target);
594 status = safe_symlink_target_path(talloc_tos(),
596 dirfsp->fsp_name->base_name,
600 if (!NT_STATUS_IS_OK(status)) {
601 DBG_DEBUG("safe_symlink_target_path() failed: %s\n",
606 if (absolute[0] == '\0') {
608 * special case symlink to share root: "." is our
609 * share root filename
611 TALLOC_FREE(absolute);
612 absolute = talloc_strdup(talloc_tos(), ".");
613 if (absolute == NULL) {
614 return NT_STATUS_NO_MEMORY;
622 /****************************************************************************
624 ****************************************************************************/
626 static NTSTATUS non_widelink_open(const struct files_struct *dirfsp,
628 struct smb_filename *smb_fname,
629 const struct vfs_open_how *_how)
631 struct connection_struct *conn = fsp->conn;
632 const char *connpath = SMB_VFS_CONNECTPATH(conn, dirfsp, smb_fname);
634 NTSTATUS status = NT_STATUS_OK;
636 char *orig_smb_fname_base = smb_fname->base_name;
637 struct smb_filename *orig_fsp_name = fsp->fsp_name;
638 struct smb_filename *smb_fname_rel = NULL;
639 struct smb_filename *oldwd_fname = NULL;
640 struct smb_filename *parent_dir_fname = NULL;
641 struct vfs_open_how how = *_how;
643 size_t link_depth = 0;
646 SMB_ASSERT(!fsp_is_alternate_stream(fsp));
648 if (connpath == NULL) {
650 * This can happen with shadow_copy2 if the snapshot
653 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
655 connpath_len = strlen(connpath);
658 if (smb_fname->base_name[0] == '/') {
659 int cmp = strcmp(connpath, smb_fname->base_name);
661 smb_fname->base_name = talloc_strdup(smb_fname, "");
662 if (smb_fname->base_name == NULL) {
663 status = NT_STATUS_NO_MEMORY;
669 if (dirfsp == conn->cwd_fsp) {
671 status = SMB_VFS_PARENT_PATHNAME(fsp->conn,
676 if (!NT_STATUS_IS_OK(status)) {
680 status = chdir_below_conn(
687 if (!NT_STATUS_IS_OK(status)) {
691 /* Setup fsp->fsp_name to be relative to cwd */
692 fsp->fsp_name = smb_fname_rel;
695 * fsp->fsp_name is unchanged as it is already correctly
696 * relative to conn->cwd.
698 smb_fname_rel = smb_fname;
703 * Assert nobody can step in with a symlink on the
704 * path, there is no path anymore and we'll use
705 * O_NOFOLLOW to open.
707 char *slash = strchr_m(smb_fname_rel->base_name, '/');
708 SMB_ASSERT(slash == NULL);
711 how.flags |= O_NOFOLLOW;
713 fd = SMB_VFS_OPENAT(conn,
718 fsp_set_fd(fsp, fd); /* This preserves errno */
721 status = map_nt_error_from_unix(errno);
723 if (errno == ENOENT) {
728 * ENOENT makes it worthless retrying with a
729 * stat, we know for sure the file does not
730 * exist. For everything else we want to know
733 ret = SMB_VFS_FSTATAT(
738 AT_SYMLINK_NOFOLLOW);
742 * Keep the original error. Otherwise we would
743 * mask for example EROFS for open(O_CREAT),
744 * turning it into ENOENT.
749 ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st);
753 status = map_nt_error_from_unix(errno);
754 DBG_DEBUG("fstat[at](%s) failed: %s\n",
755 smb_fname_str_dbg(smb_fname),
760 fsp->fsp_flags.is_directory = S_ISDIR(fsp->fsp_name->st.st_ex_mode);
761 orig_fsp_name->st = fsp->fsp_name->st;
763 if (!S_ISLNK(fsp->fsp_name->st.st_ex_mode)) {
768 * Found a symlink to follow in user space
771 if (fsp->fsp_name->flags & SMB_FILENAME_POSIX_PATH) {
772 /* Never follow symlinks on posix open. */
773 status = NT_STATUS_STOPPED_ON_SYMLINK;
776 if (!lp_follow_symlinks(SNUM(conn))) {
777 /* Explicitly no symlinks. */
778 status = NT_STATUS_STOPPED_ON_SYMLINK;
783 if (link_depth >= 40) {
784 status = NT_STATUS_STOPPED_ON_SYMLINK;
788 fsp->fsp_name = orig_fsp_name;
790 status = symlink_target_below_conn(
794 discard_const_p(files_struct, dirfsp),
798 if (!NT_STATUS_IS_OK(status)) {
799 DBG_DEBUG("symlink_target_below_conn() failed: %s\n",
805 * Close what openat(O_PATH) potentially left behind
809 if (smb_fname->base_name != orig_smb_fname_base) {
810 TALLOC_FREE(smb_fname->base_name);
812 smb_fname->base_name = target;
814 if (oldwd_fname != NULL) {
815 ret = vfs_ChDir(conn, oldwd_fname);
817 smb_panic("unable to get back to old directory\n");
819 TALLOC_FREE(oldwd_fname);
823 * And do it all again... As smb_fname is not relative to the passed in
824 * dirfsp anymore, we pass conn->cwd_fsp as dirfsp to
825 * non_widelink_open() to trigger the chdir(parentdir) logic.
827 dirfsp = conn->cwd_fsp;
832 fsp->fsp_name = orig_fsp_name;
833 smb_fname->base_name = orig_smb_fname_base;
835 TALLOC_FREE(parent_dir_fname);
837 if (!NT_STATUS_IS_OK(status)) {
841 if (oldwd_fname != NULL) {
842 ret = vfs_ChDir(conn, oldwd_fname);
844 smb_panic("unable to get back to old directory\n");
846 TALLOC_FREE(oldwd_fname);
851 /****************************************************************************
852 fd support routines - attempt to do a dos_open.
853 ****************************************************************************/
855 NTSTATUS fd_openat(const struct files_struct *dirfsp,
856 struct smb_filename *smb_fname,
858 const struct vfs_open_how *_how)
860 struct vfs_open_how how = *_how;
861 struct connection_struct *conn = fsp->conn;
862 NTSTATUS status = NT_STATUS_OK;
863 bool fsp_is_stream = fsp_is_alternate_stream(fsp);
864 bool smb_fname_is_stream = is_named_stream(smb_fname);
866 SMB_ASSERT(fsp_is_stream == smb_fname_is_stream);
869 * Never follow symlinks on a POSIX client. The
870 * client should be doing this.
873 if ((fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) || !lp_follow_symlinks(SNUM(conn))) {
874 how.flags |= O_NOFOLLOW;
882 NULL, /* stream open is relative to fsp->base_fsp */
887 status = map_nt_error_from_unix(errno);
892 status = vfs_stat_fsp(fsp);
893 if (!NT_STATUS_IS_OK(status)) {
894 DBG_DEBUG("vfs_stat_fsp failed: %s\n",
904 * Only follow symlinks within a share
907 status = non_widelink_open(dirfsp, fsp, smb_fname, &how);
908 if (!NT_STATUS_IS_OK(status)) {
909 if (NT_STATUS_EQUAL(status, NT_STATUS_TOO_MANY_OPENED_FILES)) {
910 static time_t last_warned = 0L;
912 if (time((time_t *) NULL) > last_warned) {
913 DEBUG(0,("Too many open files, unable "
914 "to open more! smbd's max "
916 lp_max_open_files()));
917 last_warned = time((time_t *) NULL);
921 DBG_DEBUG("name %s, flags = 0%o mode = 0%o, fd = %d. %s\n",
922 smb_fname_str_dbg(smb_fname),
925 fsp_get_pathref_fd(fsp),
930 DBG_DEBUG("name %s, flags = 0%o mode = 0%o, fd = %d\n",
931 smb_fname_str_dbg(smb_fname),
934 fsp_get_pathref_fd(fsp));
939 /****************************************************************************
940 Close the file associated with a fsp.
941 ****************************************************************************/
943 NTSTATUS fd_close(files_struct *fsp)
948 if (fsp == fsp->conn->cwd_fsp) {
952 if (fsp->fsp_flags.fstat_before_close) {
953 status = vfs_stat_fsp(fsp);
954 if (!NT_STATUS_IS_OK(status)) {
956 * If this is a stream and delete-on-close was set, the
957 * backing object (an xattr from streams_xattr) might
958 * already be deleted so fstat() fails with
959 * NT_STATUS_NOT_FOUND. So if fsp refers to a stream we
960 * ignore the error and only bail for normal files where
961 * an fstat() should still work. NB. We cannot use
962 * fsp_is_alternate_stream(fsp) for this as the base_fsp
963 * has already been closed at this point and so the value
964 * fsp_is_alternate_stream() checks for is already NULL.
966 if (fsp->fsp_name->stream_name == NULL) {
975 if (fsp_get_pathref_fd(fsp) == -1) {
977 * Either a directory where the dptr_CloseDir() already closed
978 * the fd or a stat open.
982 if (fh_get_refcount(fsp->fh) > 1) {
983 return NT_STATUS_OK; /* Shared handle. Only close last reference. */
986 ret = SMB_VFS_CLOSE(fsp);
989 return map_nt_error_from_unix(errno);
994 /****************************************************************************
995 Change the ownership of a file to that of the parent directory.
996 Do this by fd if possible.
997 ****************************************************************************/
999 static void change_file_owner_to_parent_fsp(struct files_struct *parent_fsp,
1000 struct files_struct *fsp)
1004 if (parent_fsp->fsp_name->st.st_ex_uid == fsp->fsp_name->st.st_ex_uid) {
1005 /* Already this uid - no need to change. */
1006 DBG_DEBUG("file %s is already owned by uid %u\n",
1008 (unsigned int)fsp->fsp_name->st.st_ex_uid);
1013 ret = SMB_VFS_FCHOWN(fsp,
1014 parent_fsp->fsp_name->st.st_ex_uid,
1018 DBG_ERR("failed to fchown "
1019 "file %s to parent directory uid %u. Error "
1022 (unsigned int)parent_fsp->fsp_name->st.st_ex_uid,
1025 DBG_DEBUG("changed new file %s to "
1026 "parent directory uid %u.\n",
1028 (unsigned int)parent_fsp->fsp_name->st.st_ex_uid);
1029 /* Ensure the uid entry is updated. */
1030 fsp->fsp_name->st.st_ex_uid =
1031 parent_fsp->fsp_name->st.st_ex_uid;
1035 static NTSTATUS change_dir_owner_to_parent_fsp(struct files_struct *parent_fsp,
1036 struct files_struct *fsp)
1041 if (parent_fsp->fsp_name->st.st_ex_uid == fsp->fsp_name->st.st_ex_uid) {
1042 /* Already this uid - no need to change. */
1043 DBG_DEBUG("directory %s is already owned by uid %u\n",
1045 (unsigned int)fsp->fsp_name->st.st_ex_uid);
1046 return NT_STATUS_OK;
1050 ret = SMB_VFS_FCHOWN(fsp,
1051 parent_fsp->fsp_name->st.st_ex_uid,
1055 status = map_nt_error_from_unix(errno);
1056 DBG_ERR("failed to chown "
1057 "directory %s to parent directory uid %u. "
1060 (unsigned int)parent_fsp->fsp_name->st.st_ex_uid,
1065 DBG_DEBUG("changed ownership of new "
1066 "directory %s to parent directory uid %u.\n",
1068 (unsigned int)parent_fsp->fsp_name->st.st_ex_uid);
1070 /* Ensure the uid entry is updated. */
1071 fsp->fsp_name->st.st_ex_uid = parent_fsp->fsp_name->st.st_ex_uid;
1073 return NT_STATUS_OK;
1076 /****************************************************************************
1077 Open a file - returning a guaranteed ATOMIC indication of if the
1078 file was created or not.
1079 ****************************************************************************/
1081 static NTSTATUS fd_open_atomic(struct files_struct *dirfsp,
1082 struct smb_filename *smb_fname,
1088 struct vfs_open_how how = { .flags = flags, .mode = mode, };
1089 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
1090 NTSTATUS retry_status;
1091 bool file_existed = VALID_STAT(smb_fname->st);
1093 if (!(how.flags & O_CREAT)) {
1095 * We're not creating the file, just pass through.
1097 status = fd_openat(dirfsp, smb_fname, fsp, &how);
1098 *file_created = false;
1102 if (how.flags & O_EXCL) {
1104 * Fail if already exists, just pass through.
1106 status = fd_openat(dirfsp, smb_fname, fsp, &how);
1109 * Here we've opened with O_CREAT|O_EXCL. If that went
1110 * NT_STATUS_OK, we *know* we created this file.
1112 *file_created = NT_STATUS_IS_OK(status);
1118 * Now it gets tricky. We have O_CREAT, but not O_EXCL.
1119 * To know absolutely if we created the file or not,
1120 * we can never call O_CREAT without O_EXCL. So if
1121 * we think the file existed, try without O_CREAT|O_EXCL.
1122 * If we think the file didn't exist, try with
1125 * The big problem here is dangling symlinks. Opening
1126 * without O_NOFOLLOW means both bad symlink
1127 * and missing path return -1, ENOENT from open(). As POSIX
1128 * is pathname based it's not possible to tell
1129 * the difference between these two cases in a
1130 * non-racy way, so change to try only two attempts before
1133 * We don't have this problem for the O_NOFOLLOW
1134 * case as it just returns NT_STATUS_OBJECT_PATH_NOT_FOUND
1135 * mapped from the ELOOP POSIX error.
1139 how.flags = flags & ~(O_CREAT);
1140 retry_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
1142 how.flags = flags | O_EXCL;
1143 retry_status = NT_STATUS_OBJECT_NAME_COLLISION;
1146 status = fd_openat(dirfsp, smb_fname, fsp, &how);
1147 if (NT_STATUS_IS_OK(status)) {
1148 *file_created = !file_existed;
1149 return NT_STATUS_OK;
1151 if (NT_STATUS_EQUAL(status, retry_status)) {
1153 file_existed = !file_existed;
1155 DBG_DEBUG("File %s %s. Retry.\n",
1157 file_existed ? "existed" : "did not exist");
1160 how.flags = flags & ~(O_CREAT);
1162 how.flags = flags | O_EXCL;
1165 status = fd_openat(dirfsp, smb_fname, fsp, &how);
1168 *file_created = (NT_STATUS_IS_OK(status) && !file_existed);
1172 static NTSTATUS reopen_from_procfd(struct files_struct *fsp,
1176 struct vfs_open_how how = { .flags = flags, .mode = mode };
1177 struct smb_filename proc_fname;
1178 const char *p = NULL;
1184 if (!fsp->fsp_flags.have_proc_fds) {
1185 return NT_STATUS_MORE_PROCESSING_REQUIRED;
1188 old_fd = fsp_get_pathref_fd(fsp);
1190 return NT_STATUS_MORE_PROCESSING_REQUIRED;
1193 if (!fsp->fsp_flags.is_pathref) {
1194 DBG_ERR("[%s] is not a pathref\n",
1197 smb_panic("Not a pathref");
1199 return NT_STATUS_INVALID_HANDLE;
1202 p = sys_proc_fd_path(old_fd, buf, sizeof(buf));
1204 return NT_STATUS_NO_MEMORY;
1207 proc_fname = (struct smb_filename) {
1208 .base_name = discard_const_p(char, p),
1211 fsp->fsp_flags.is_pathref = false;
1213 new_fd = SMB_VFS_OPENAT(fsp->conn,
1219 status = map_nt_error_from_unix(errno);
1224 status = fd_close(fsp);
1225 if (!NT_STATUS_IS_OK(status)) {
1229 fsp_set_fd(fsp, new_fd);
1230 return NT_STATUS_OK;
1233 static NTSTATUS reopen_from_fsp(struct files_struct *dirfsp,
1234 struct smb_filename *smb_fname,
1235 struct files_struct *fsp,
1238 bool *p_file_created)
1240 bool __unused_file_created = false;
1243 if (p_file_created == NULL) {
1244 p_file_created = &__unused_file_created;
1248 * TODO: should we move this to the VFS layer?
1249 * SMB_VFS_REOPEN_FSP()?
1252 status = reopen_from_procfd(fsp,
1255 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1260 * Close the existing pathref fd and set the fsp flag
1261 * is_pathref to false so we get a "normal" fd this time.
1263 status = fd_close(fsp);
1264 if (!NT_STATUS_IS_OK(status)) {
1268 fsp->fsp_flags.is_pathref = false;
1270 status = fd_open_atomic(
1280 /****************************************************************************
1282 ****************************************************************************/
1284 static NTSTATUS open_file(struct smb_request *req,
1285 struct files_struct *dirfsp,
1286 struct smb_filename *smb_fname_atname,
1290 uint32_t access_mask, /* client requested access mask. */
1291 uint32_t open_access_mask, /* what we're actually using in the open. */
1292 uint32_t private_flags,
1293 bool *p_file_created)
1295 connection_struct *conn = fsp->conn;
1296 struct smb_filename *smb_fname = fsp->fsp_name;
1297 NTSTATUS status = NT_STATUS_OK;
1298 int accmode = (flags & O_ACCMODE);
1299 int local_flags = flags;
1300 bool file_existed = VALID_STAT(fsp->fsp_name->st);
1301 const uint32_t need_fd_mask =
1306 SEC_FLAG_SYSTEM_SECURITY;
1307 bool creating = !file_existed && (flags & O_CREAT);
1308 bool truncating = (flags & O_TRUNC);
1309 bool open_fd = false;
1310 bool posix_open = (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN);
1313 * Catch early an attempt to open an existing
1314 * directory as a file.
1316 if (file_existed && S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
1317 return NT_STATUS_FILE_IS_A_DIRECTORY;
1320 /* Check permissions */
1323 * This code was changed after seeing a client open request
1324 * containing the open mode of (DENY_WRITE/read-only) with
1325 * the 'create if not exist' bit set. The previous code
1326 * would fail to open the file read only on a read-only share
1327 * as it was checking the flags parameter directly against O_RDONLY,
1328 * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
1332 if (!CAN_WRITE(conn)) {
1333 /* It's a read-only share - fail if we wanted to write. */
1334 if(accmode != O_RDONLY || (flags & O_TRUNC) || (flags & O_APPEND)) {
1335 DEBUG(3,("Permission denied opening %s\n",
1336 smb_fname_str_dbg(smb_fname)));
1337 return NT_STATUS_ACCESS_DENIED;
1339 if (flags & O_CREAT) {
1340 /* We don't want to write - but we must make sure that
1341 O_CREAT doesn't create the file if we have write
1342 access into the directory.
1344 flags &= ~(O_CREAT|O_EXCL);
1345 local_flags &= ~(O_CREAT|O_EXCL);
1350 * This little piece of insanity is inspired by the
1351 * fact that an NT client can open a file for O_RDONLY,
1352 * but set the create disposition to FILE_EXISTS_TRUNCATE.
1353 * If the client *can* write to the file, then it expects to
1354 * truncate the file, even though it is opening for readonly.
1355 * Quicken uses this stupid trick in backup file creation...
1356 * Thanks *greatly* to "David W. Chapman Jr." <dwcjr@inethouston.net>
1357 * for helping track this one down. It didn't bite us in 2.0.x
1358 * as we always opened files read-write in that release. JRA.
1361 if ((accmode == O_RDONLY) && ((flags & O_TRUNC) == O_TRUNC)) {
1362 DEBUG(10,("open_file: truncate requested on read-only open "
1363 "for file %s\n", smb_fname_str_dbg(smb_fname)));
1364 local_flags = (flags & ~O_ACCMODE)|O_RDWR;
1367 if ((open_access_mask & need_fd_mask) || creating || truncating) {
1375 #if defined(O_NONBLOCK) && defined(S_ISFIFO)
1377 * We would block on opening a FIFO with no one else on the
1378 * other end. Do what we used to do and add O_NONBLOCK to the
1382 if (file_existed && S_ISFIFO(smb_fname->st.st_ex_mode)) {
1383 local_flags &= ~O_TRUNC; /* Can't truncate a FIFO. */
1384 local_flags |= O_NONBLOCK;
1389 /* Don't create files with Microsoft wildcard characters. */
1390 if (fsp_is_alternate_stream(fsp)) {
1392 * wildcard characters are allowed in stream names
1393 * only test the basefilename
1395 wild = fsp->base_fsp->fsp_name->base_name;
1397 wild = smb_fname->base_name;
1399 if ((local_flags & O_CREAT) && !file_existed &&
1400 !(fsp->posix_flags & FSP_POSIX_FLAGS_PATHNAMES) &&
1401 ms_has_wild(wild)) {
1402 return NT_STATUS_OBJECT_NAME_INVALID;
1405 /* Can we access this file ? */
1406 if (!fsp_is_alternate_stream(fsp)) {
1407 /* Only do this check on non-stream open. */
1409 status = smbd_check_access_rights_fsp(
1415 if (!NT_STATUS_IS_OK(status)) {
1416 DBG_DEBUG("smbd_check_access_rights_fsp"
1417 " on file %s returned %s\n",
1422 if (!NT_STATUS_IS_OK(status) &&
1423 !NT_STATUS_EQUAL(status,
1424 NT_STATUS_OBJECT_NAME_NOT_FOUND))
1429 if (NT_STATUS_EQUAL(status,
1430 NT_STATUS_OBJECT_NAME_NOT_FOUND))
1432 DEBUG(10, ("open_file: "
1433 "file %s vanished since we "
1434 "checked for existence.\n",
1435 smb_fname_str_dbg(smb_fname)));
1436 file_existed = false;
1437 SET_STAT_INVALID(fsp->fsp_name->st);
1441 if (!file_existed) {
1442 if (!(local_flags & O_CREAT)) {
1443 /* File didn't exist and no O_CREAT. */
1444 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1447 status = check_parent_access_fsp(
1450 if (!NT_STATUS_IS_OK(status)) {
1451 DBG_DEBUG("check_parent_access_fsp on "
1452 "directory %s for file %s "
1456 smb_fname_str_dbg(smb_fname),
1464 * Actually do the open - if O_TRUNC is needed handle it
1465 * below under the share mode lock.
1467 status = reopen_from_fsp(dirfsp,
1470 local_flags & ~O_TRUNC,
1473 if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) {
1475 * Non-O_PATH reopen that hit a race
1476 * condition: Someone has put a symlink where
1477 * we used to have a file. Can't happen with
1478 * O_PATH and reopening from /proc/self/fd/ or
1481 status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
1483 if (!NT_STATUS_IS_OK(status)) {
1484 DEBUG(3,("Error opening file %s (%s) (local_flags=%d) "
1485 "(flags=%d)\n", smb_fname_str_dbg(smb_fname),
1486 nt_errstr(status),local_flags,flags));
1490 if (local_flags & O_NONBLOCK) {
1492 * GPFS can return ETIMEDOUT for pread on
1493 * nonblocking file descriptors when files
1494 * migrated to tape need to be recalled. I
1495 * could imagine this happens elsewhere
1496 * too. With blocking file descriptors this
1499 ret = vfs_set_blocking(fsp, true);
1501 status = map_nt_error_from_unix(errno);
1502 DBG_WARNING("Could not set fd to blocking: "
1503 "%s\n", strerror(errno));
1509 if (*p_file_created) {
1510 /* We created this file. */
1512 bool need_re_stat = false;
1513 /* Do all inheritance work after we've
1514 done a successful fstat call and filled
1515 in the stat struct in fsp->fsp_name. */
1517 /* Inherit the ACL if required */
1518 if (lp_inherit_permissions(SNUM(conn))) {
1519 inherit_access_posix_acl(conn,
1523 need_re_stat = true;
1526 /* Change the owner if required. */
1527 if (lp_inherit_owner(SNUM(conn)) != INHERIT_OWNER_NO) {
1528 change_file_owner_to_parent_fsp(dirfsp, fsp);
1529 need_re_stat = true;
1533 status = vfs_stat_fsp(fsp);
1535 * If we have an fd, this stat should succeed.
1537 if (!NT_STATUS_IS_OK(status)) {
1538 DBG_ERR("Error doing fstat on open "
1540 smb_fname_str_dbg(smb_fname),
1547 notify_fname(conn, NOTIFY_ACTION_ADDED,
1548 FILE_NOTIFY_CHANGE_FILE_NAME,
1549 smb_fname->base_name);
1552 if (!file_existed) {
1553 /* File must exist for a stat open. */
1554 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1557 if (S_ISLNK(smb_fname->st.st_ex_mode) &&
1561 * Don't allow stat opens on symlinks directly unless
1562 * it's a POSIX open. Match the return code from
1563 * openat_pathref_fsp().
1565 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1568 if (!fsp->fsp_flags.is_pathref) {
1570 * There is only one legit case where end up here:
1571 * openat_pathref_fsp() failed to open a symlink, so the
1572 * fsp was created by fsp_new() which doesn't set
1573 * is_pathref. Other then that, we should always have a
1574 * pathref fsp at this point. The subsequent checks
1577 if (!(smb_fname->flags & SMB_FILENAME_POSIX_PATH)) {
1578 DBG_ERR("[%s] is not a POSIX pathname\n",
1579 smb_fname_str_dbg(smb_fname));
1580 return NT_STATUS_INTERNAL_ERROR;
1582 if (!S_ISLNK(smb_fname->st.st_ex_mode)) {
1583 DBG_ERR("[%s] is not a symlink\n",
1584 smb_fname_str_dbg(smb_fname));
1585 return NT_STATUS_INTERNAL_ERROR;
1587 if (fsp_get_pathref_fd(fsp) != -1) {
1588 DBG_ERR("fd for [%s] is not -1: fd [%d]\n",
1589 smb_fname_str_dbg(smb_fname),
1590 fsp_get_pathref_fd(fsp));
1591 return NT_STATUS_INTERNAL_ERROR;
1596 * Access to streams is checked by checking the basefile and
1597 * that has alreay been checked by check_base_file_access()
1598 * in create_file_unixpath().
1600 if (!fsp_is_alternate_stream(fsp)) {
1601 status = smbd_check_access_rights_fsp(dirfsp,
1606 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) &&
1608 S_ISLNK(smb_fname->st.st_ex_mode)) {
1609 /* This is a POSIX stat open for delete
1610 * or rename on a symlink that points
1611 * nowhere. Allow. */
1612 DEBUG(10,("open_file: allowing POSIX "
1613 "open on bad symlink %s\n",
1614 smb_fname_str_dbg(smb_fname)));
1615 status = NT_STATUS_OK;
1618 if (!NT_STATUS_IS_OK(status)) {
1619 DBG_DEBUG("smbd_check_access_rights_fsp on file "
1628 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
1629 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
1630 fsp->file_pid = req ? req->smbpid : 0;
1631 fsp->fsp_flags.can_lock = true;
1632 fsp->fsp_flags.can_read = ((access_mask & FILE_READ_DATA) != 0);
1633 fsp->fsp_flags.can_write =
1635 ((access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) != 0);
1636 if (fsp->fsp_name->twrp != 0) {
1637 fsp->fsp_flags.can_write = false;
1639 fsp->print_file = NULL;
1640 fsp->fsp_flags.modified = false;
1641 fsp->sent_oplock_break = NO_BREAK_SENT;
1642 fsp->fsp_flags.is_directory = false;
1643 if (conn->aio_write_behind_list &&
1644 is_in_path(smb_fname->base_name, conn->aio_write_behind_list,
1645 posix_open ? true: conn->case_sensitive)) {
1646 fsp->fsp_flags.aio_write_behind = true;
1649 DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
1650 conn->session_info->unix_info->unix_name,
1651 smb_fname_str_dbg(smb_fname),
1652 BOOLSTR(fsp->fsp_flags.can_read),
1653 BOOLSTR(fsp->fsp_flags.can_write),
1654 conn->num_files_open));
1656 return NT_STATUS_OK;
1659 static bool mask_conflict(
1660 uint32_t new_access,
1661 uint32_t existing_access,
1662 uint32_t access_mask,
1663 uint32_t new_sharemode,
1664 uint32_t existing_sharemode,
1665 uint32_t sharemode_mask)
1667 bool want_access = (new_access & access_mask);
1668 bool allow_existing = (existing_sharemode & sharemode_mask);
1669 bool have_access = (existing_access & access_mask);
1670 bool allow_new = (new_sharemode & sharemode_mask);
1672 if (want_access && !allow_existing) {
1673 DBG_DEBUG("Access request 0x%"PRIx32"/0x%"PRIx32" conflicts "
1674 "with existing sharemode 0x%"PRIx32"/0x%"PRIx32"\n",
1681 if (have_access && !allow_new) {
1682 DBG_DEBUG("Sharemode request 0x%"PRIx32"/0x%"PRIx32" conflicts "
1683 "with existing access 0x%"PRIx32"/0x%"PRIx32"\n",
1693 /****************************************************************************
1694 Check if we can open a file with a share mode.
1695 Returns True if conflict, False if not.
1696 ****************************************************************************/
1698 static const uint32_t conflicting_access =
1705 static bool share_conflict(uint32_t e_access_mask,
1706 uint32_t e_share_access,
1707 uint32_t access_mask,
1708 uint32_t share_access)
1712 DBG_DEBUG("existing access_mask = 0x%"PRIx32", "
1713 "existing share access = 0x%"PRIx32", "
1714 "access_mask = 0x%"PRIx32", "
1715 "share_access = 0x%"PRIx32"\n",
1721 if ((e_access_mask & conflicting_access) == 0) {
1722 DBG_DEBUG("No conflict due to "
1723 "existing access_mask = 0x%"PRIx32"\n",
1727 if ((access_mask & conflicting_access) == 0) {
1728 DBG_DEBUG("No conflict due to access_mask = 0x%"PRIx32"\n",
1733 conflict = mask_conflict(
1734 access_mask, e_access_mask, FILE_WRITE_DATA | FILE_APPEND_DATA,
1735 share_access, e_share_access, FILE_SHARE_WRITE);
1736 conflict |= mask_conflict(
1737 access_mask, e_access_mask, FILE_READ_DATA | FILE_EXECUTE,
1738 share_access, e_share_access, FILE_SHARE_READ);
1739 conflict |= mask_conflict(
1740 access_mask, e_access_mask, DELETE_ACCESS,
1741 share_access, e_share_access, FILE_SHARE_DELETE);
1743 DBG_DEBUG("conflict=%s\n", conflict ? "true" : "false");
1747 #if defined(DEVELOPER)
1749 struct validate_my_share_entries_state {
1750 struct smbd_server_connection *sconn;
1752 struct server_id self;
1755 static bool validate_my_share_entries_fn(
1756 struct share_mode_entry *e,
1760 struct validate_my_share_entries_state *state = private_data;
1763 if (!server_id_equal(&state->self, &e->pid)) {
1767 if (e->op_mid == 0) {
1768 /* INTERNAL_OPEN_ONLY */
1772 fsp = file_find_dif(state->sconn, state->fid, e->share_file_id);
1774 DBG_ERR("PANIC : %s\n",
1775 share_mode_str(talloc_tos(), 0, &state->fid, e));
1776 smb_panic("validate_my_share_entries: Cannot match a "
1777 "share entry with an open file\n");
1780 if (((uint16_t)fsp->oplock_type) != e->op_type) {
1789 DBG_ERR("validate_my_share_entries: PANIC : %s\n",
1790 share_mode_str(talloc_tos(), 0, &state->fid, e));
1791 str = talloc_asprintf(talloc_tos(),
1792 "validate_my_share_entries: "
1793 "file %s, oplock_type = 0x%x, op_type = 0x%x\n",
1794 fsp->fsp_name->base_name,
1795 (unsigned int)fsp->oplock_type,
1796 (unsigned int)e->op_type);
1805 * Allowed access mask for stat opens relevant to oplocks
1807 bool is_oplock_stat_open(uint32_t access_mask)
1809 const uint32_t stat_open_bits =
1810 (SYNCHRONIZE_ACCESS|
1811 FILE_READ_ATTRIBUTES|
1812 FILE_WRITE_ATTRIBUTES);
1814 return (((access_mask & stat_open_bits) != 0) &&
1815 ((access_mask & ~stat_open_bits) == 0));
1819 * Allowed access mask for stat opens relevant to leases
1821 bool is_lease_stat_open(uint32_t access_mask)
1823 const uint32_t stat_open_bits =
1824 (SYNCHRONIZE_ACCESS|
1825 FILE_READ_ATTRIBUTES|
1826 FILE_WRITE_ATTRIBUTES|
1827 READ_CONTROL_ACCESS);
1829 return (((access_mask & stat_open_bits) != 0) &&
1830 ((access_mask & ~stat_open_bits) == 0));
1833 struct has_delete_on_close_state {
1837 static bool has_delete_on_close_fn(
1838 struct share_mode_entry *e,
1842 struct has_delete_on_close_state *state = private_data;
1843 state->ret = !share_entry_stale_pid(e);
1847 static bool has_delete_on_close(struct share_mode_lock *lck,
1850 struct has_delete_on_close_state state = { .ret = false };
1853 if (!is_delete_on_close_set(lck, name_hash)) {
1857 ok= share_mode_forall_entries(lck, has_delete_on_close_fn, &state);
1859 DBG_DEBUG("share_mode_forall_entries failed\n");
1865 static void share_mode_flags_restrict(
1866 struct share_mode_lock *lck,
1867 uint32_t access_mask,
1868 uint32_t share_mode,
1869 uint32_t lease_type)
1871 uint32_t existing_access_mask, existing_share_mode;
1872 uint32_t existing_lease_type;
1874 share_mode_flags_get(
1876 &existing_access_mask,
1877 &existing_share_mode,
1878 &existing_lease_type);
1880 existing_access_mask |= access_mask;
1881 if (access_mask & conflicting_access) {
1882 existing_share_mode &= share_mode;
1884 existing_lease_type |= lease_type;
1886 share_mode_flags_set(
1888 existing_access_mask,
1889 existing_share_mode,
1890 existing_lease_type,
1894 /****************************************************************************
1895 Deal with share modes
1896 Invariant: Share mode must be locked on entry and exit.
1897 Returns -1 on error, or number of share modes on success (may be zero).
1898 ****************************************************************************/
1900 struct open_mode_check_state {
1902 uint32_t access_mask;
1903 uint32_t share_access;
1904 uint32_t lease_type;
1907 static bool open_mode_check_fn(
1908 struct share_mode_entry *e,
1912 struct open_mode_check_state *state = private_data;
1913 bool disconnected, stale;
1914 uint32_t access_mask, share_access, lease_type;
1916 disconnected = server_id_is_disconnected(&e->pid);
1921 access_mask = state->access_mask | e->access_mask;
1922 share_access = state->share_access;
1923 if (e->access_mask & conflicting_access) {
1924 share_access &= e->share_access;
1926 lease_type = state->lease_type | get_lease_type(e, state->fid);
1928 if ((access_mask == state->access_mask) &&
1929 (share_access == state->share_access) &&
1930 (lease_type == state->lease_type)) {
1934 stale = share_entry_stale_pid(e);
1939 state->access_mask = access_mask;
1940 state->share_access = share_access;
1941 state->lease_type = lease_type;
1946 static NTSTATUS open_mode_check(connection_struct *conn,
1948 struct share_mode_lock *lck,
1949 uint32_t access_mask,
1950 uint32_t share_access)
1952 struct open_mode_check_state state;
1954 bool modified = false;
1956 if (is_oplock_stat_open(access_mask)) {
1957 /* Stat open that doesn't trigger oplock breaks or share mode
1958 * checks... ! JRA. */
1959 return NT_STATUS_OK;
1963 * Check if the share modes will give us access.
1966 #if defined(DEVELOPER)
1968 struct validate_my_share_entries_state validate_state = {
1969 .sconn = conn->sconn,
1971 .self = messaging_server_id(conn->sconn->msg_ctx),
1973 ok = share_mode_forall_entries(
1974 lck, validate_my_share_entries_fn, &validate_state);
1979 share_mode_flags_get(
1980 lck, &state.access_mask, &state.share_access, NULL);
1982 conflict = share_conflict(
1988 DBG_DEBUG("No conflict due to share_mode_flags access\n");
1989 return NT_STATUS_OK;
1992 state = (struct open_mode_check_state) {
1994 .share_access = (FILE_SHARE_READ|
2000 * Walk the share mode array to recalculate d->flags
2003 ok = share_mode_forall_entries(lck, open_mode_check_fn, &state);
2005 DBG_DEBUG("share_mode_forall_entries failed\n");
2006 return NT_STATUS_INTERNAL_ERROR;
2009 share_mode_flags_set(
2017 * We only end up here if we had a sharing violation
2018 * from d->flags and have recalculated it.
2020 return NT_STATUS_SHARING_VIOLATION;
2023 conflict = share_conflict(
2029 DBG_DEBUG("No conflict due to share_mode_flags access\n");
2030 return NT_STATUS_OK;
2033 return NT_STATUS_SHARING_VIOLATION;
2037 * Send a break message to the oplock holder and delay the open for
2041 NTSTATUS send_break_message(struct messaging_context *msg_ctx,
2042 const struct file_id *id,
2043 const struct share_mode_entry *exclusive,
2046 struct oplock_break_message msg = {
2048 .share_file_id = exclusive->share_file_id,
2049 .break_to = break_to,
2051 enum ndr_err_code ndr_err;
2056 struct server_id_buf buf;
2057 DBG_DEBUG("Sending break message to %s\n",
2058 server_id_str_buf(exclusive->pid, &buf));
2059 NDR_PRINT_DEBUG(oplock_break_message, &msg);
2062 ndr_err = ndr_push_struct_blob(
2066 (ndr_push_flags_fn_t)ndr_push_oplock_break_message);
2067 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2068 DBG_WARNING("ndr_push_oplock_break_message failed: %s\n",
2069 ndr_errstr(ndr_err));
2070 return ndr_map_error2ntstatus(ndr_err);
2073 status = messaging_send(
2074 msg_ctx, exclusive->pid, MSG_SMB_BREAK_REQUEST, &blob);
2075 TALLOC_FREE(blob.data);
2076 if (!NT_STATUS_IS_OK(status)) {
2077 DEBUG(3, ("Could not send oplock break message: %s\n",
2078 nt_errstr(status)));
2084 struct validate_oplock_types_state {
2090 uint32_t num_non_stat_opens;
2093 static bool validate_oplock_types_fn(
2094 struct share_mode_entry *e,
2098 struct validate_oplock_types_state *state = private_data;
2100 if (e->op_mid == 0) {
2101 /* INTERNAL_OPEN_ONLY */
2105 if (e->op_type == NO_OPLOCK && is_oplock_stat_open(e->access_mask)) {
2107 * We ignore stat opens in the table - they always
2108 * have NO_OPLOCK and never get or cause breaks. JRA.
2113 state->num_non_stat_opens += 1;
2115 if (BATCH_OPLOCK_TYPE(e->op_type)) {
2116 /* batch - can only be one. */
2117 if (share_entry_stale_pid(e)) {
2118 DBG_DEBUG("Found stale batch oplock\n");
2121 if (state->ex_or_batch ||
2125 DBG_ERR("Bad batch oplock entry\n");
2126 state->valid = false;
2129 state->batch = true;
2132 if (EXCLUSIVE_OPLOCK_TYPE(e->op_type)) {
2133 if (share_entry_stale_pid(e)) {
2134 DBG_DEBUG("Found stale duplicate oplock\n");
2137 /* Exclusive or batch - can only be one. */
2138 if (state->ex_or_batch ||
2141 DBG_ERR("Bad exclusive or batch oplock entry\n");
2142 state->valid = false;
2145 state->ex_or_batch = true;
2148 if (LEVEL_II_OPLOCK_TYPE(e->op_type)) {
2149 if (state->batch || state->ex_or_batch) {
2150 if (share_entry_stale_pid(e)) {
2151 DBG_DEBUG("Found stale LevelII oplock\n");
2154 DBG_DEBUG("Bad levelII oplock entry\n");
2155 state->valid = false;
2158 state->level2 = true;
2161 if (e->op_type == NO_OPLOCK) {
2162 if (state->batch || state->ex_or_batch) {
2163 if (share_entry_stale_pid(e)) {
2164 DBG_DEBUG("Found stale NO_OPLOCK entry\n");
2167 DBG_ERR("Bad no oplock entry\n");
2168 state->valid = false;
2171 state->no_oplock = true;
2178 * Do internal consistency checks on the share mode for a file.
2181 static bool validate_oplock_types(struct share_mode_lock *lck)
2183 struct validate_oplock_types_state state = { .valid = true };
2184 static bool skip_validation;
2188 if (skip_validation) {
2192 validate = lp_parm_bool(-1, "smbd", "validate_oplock_types", false);
2194 DBG_DEBUG("smbd:validate_oplock_types not set to yes\n");
2195 skip_validation = true;
2199 ok = share_mode_forall_entries(lck, validate_oplock_types_fn, &state);
2201 DBG_DEBUG("share_mode_forall_entries failed\n");
2205 DBG_DEBUG("Got invalid oplock configuration\n");
2209 if ((state.batch || state.ex_or_batch) &&
2210 (state.num_non_stat_opens != 1)) {
2211 DBG_WARNING("got batch (%d) or ex (%d) non-exclusively "
2214 (int)state.ex_or_batch,
2215 state.num_non_stat_opens);
2222 static bool is_same_lease(const files_struct *fsp,
2223 const struct share_mode_entry *e,
2224 const struct smb2_lease *lease)
2226 if (e->op_type != LEASE_OPLOCK) {
2229 if (lease == NULL) {
2233 return smb2_lease_equal(fsp_client_guid(fsp),
2239 static bool file_has_brlocks(files_struct *fsp)
2241 struct byte_range_lock *br_lck;
2243 br_lck = brl_get_locks_readonly(fsp);
2247 return (brl_num_locks(br_lck) > 0);
2250 struct fsp_lease *find_fsp_lease(struct files_struct *new_fsp,
2251 const struct smb2_lease_key *key,
2252 uint32_t current_state,
2253 uint16_t lease_version,
2254 uint16_t lease_epoch)
2256 struct files_struct *fsp;
2259 * TODO: Measure how expensive this loop is with thousands of open
2263 for (fsp = file_find_di_first(new_fsp->conn->sconn, new_fsp->file_id, true);
2265 fsp = file_find_di_next(fsp, true)) {
2267 if (fsp == new_fsp) {
2270 if (fsp->oplock_type != LEASE_OPLOCK) {
2273 if (smb2_lease_key_equal(&fsp->lease->lease.lease_key, key)) {
2274 fsp->lease->ref_count += 1;
2279 /* Not found - must be leased in another smbd. */
2280 new_fsp->lease = talloc_zero(new_fsp->conn->sconn, struct fsp_lease);
2281 if (new_fsp->lease == NULL) {
2284 new_fsp->lease->ref_count = 1;
2285 new_fsp->lease->sconn = new_fsp->conn->sconn;
2286 new_fsp->lease->lease.lease_key = *key;
2287 new_fsp->lease->lease.lease_state = current_state;
2289 * We internally treat all leases as V2 and update
2290 * the epoch, but when sending breaks it matters if
2291 * the requesting lease was v1 or v2.
2293 new_fsp->lease->lease.lease_version = lease_version;
2294 new_fsp->lease->lease.lease_epoch = lease_epoch;
2295 return new_fsp->lease;
2298 static NTSTATUS try_lease_upgrade(struct files_struct *fsp,
2299 struct share_mode_lock *lck,
2300 const struct GUID *client_guid,
2301 const struct smb2_lease *lease,
2305 uint32_t current_state, breaking_to_requested, breaking_to_required;
2307 uint16_t lease_version, epoch;
2308 uint32_t existing, requested;
2311 status = leases_db_get(
2317 &breaking_to_requested,
2318 &breaking_to_required,
2321 if (!NT_STATUS_IS_OK(status)) {
2325 fsp->lease = find_fsp_lease(
2331 if (fsp->lease == NULL) {
2332 DEBUG(1, ("Did not find existing lease for file %s\n",
2334 return NT_STATUS_NO_MEMORY;
2338 * Upgrade only if the requested lease is a strict upgrade.
2340 existing = current_state;
2341 requested = lease->lease_state;
2344 * Tricky: This test makes sure that "requested" is a
2345 * strict bitwise superset of "existing".
2347 do_upgrade = ((existing & requested) == existing);
2350 * Upgrade only if there's a change.
2352 do_upgrade &= (granted != existing);
2355 * Upgrade only if other leases don't prevent what was asked
2358 do_upgrade &= (granted == requested);
2361 * only upgrade if we are not in breaking state
2363 do_upgrade &= !breaking;
2365 DEBUG(10, ("existing=%"PRIu32", requested=%"PRIu32", "
2366 "granted=%"PRIu32", do_upgrade=%d\n",
2367 existing, requested, granted, (int)do_upgrade));
2370 NTSTATUS set_status;
2372 current_state = granted;
2375 set_status = leases_db_set(
2380 breaking_to_requested,
2381 breaking_to_required,
2385 if (!NT_STATUS_IS_OK(set_status)) {
2386 DBG_DEBUG("leases_db_set failed: %s\n",
2387 nt_errstr(set_status));
2392 fsp_lease_update(fsp);
2394 return NT_STATUS_OK;
2397 static NTSTATUS grant_new_fsp_lease(struct files_struct *fsp,
2398 struct share_mode_lock *lck,
2399 const struct GUID *client_guid,
2400 const struct smb2_lease *lease,
2405 fsp->lease = talloc_zero(fsp->conn->sconn, struct fsp_lease);
2406 if (fsp->lease == NULL) {
2407 return NT_STATUS_INSUFFICIENT_RESOURCES;
2409 fsp->lease->ref_count = 1;
2410 fsp->lease->sconn = fsp->conn->sconn;
2411 fsp->lease->lease.lease_version = lease->lease_version;
2412 fsp->lease->lease.lease_key = lease->lease_key;
2413 fsp->lease->lease.lease_state = granted;
2414 fsp->lease->lease.lease_epoch = lease->lease_epoch + 1;
2416 status = leases_db_add(client_guid,
2419 fsp->lease->lease.lease_state,
2420 fsp->lease->lease.lease_version,
2421 fsp->lease->lease.lease_epoch,
2422 fsp->conn->connectpath,
2423 fsp->fsp_name->base_name,
2424 fsp->fsp_name->stream_name);
2425 if (!NT_STATUS_IS_OK(status)) {
2426 DEBUG(10, ("%s: leases_db_add failed: %s\n", __func__,
2427 nt_errstr(status)));
2428 TALLOC_FREE(fsp->lease);
2429 return NT_STATUS_INSUFFICIENT_RESOURCES;
2433 * We used to set lck->data->modified=true here without
2434 * actually modifying lck->data, triggering a needless
2435 * writeback of lck->data.
2437 * Apart from that writeback, setting modified=true has the
2438 * effect of triggering all waiters for this file to
2439 * retry. This only makes sense if any blocking condition
2440 * (i.e. waiting for a lease to be downgraded or removed) is
2441 * gone. This routine here only adds a lease, so it will never
2442 * free up resources that blocked waiters can now claim. So
2443 * that second effect also does not matter in this
2444 * routine. Thus setting lck->data->modified=true does not
2445 * need to be done here.
2448 return NT_STATUS_OK;
2451 static NTSTATUS grant_fsp_lease(struct files_struct *fsp,
2452 struct share_mode_lock *lck,
2453 const struct smb2_lease *lease,
2456 const struct GUID *client_guid = fsp_client_guid(fsp);
2459 status = try_lease_upgrade(fsp, lck, client_guid, lease, granted);
2461 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
2462 status = grant_new_fsp_lease(
2463 fsp, lck, client_guid, lease, granted);
2469 static int map_lease_type_to_oplock(uint32_t lease_type)
2471 int result = NO_OPLOCK;
2473 switch (lease_type) {
2474 case SMB2_LEASE_READ|SMB2_LEASE_WRITE|SMB2_LEASE_HANDLE:
2475 result = BATCH_OPLOCK|EXCLUSIVE_OPLOCK;
2477 case SMB2_LEASE_READ|SMB2_LEASE_WRITE:
2478 result = EXCLUSIVE_OPLOCK;
2480 case SMB2_LEASE_READ|SMB2_LEASE_HANDLE:
2481 case SMB2_LEASE_READ:
2482 result = LEVEL_II_OPLOCK;
2489 struct delay_for_oplock_state {
2490 struct files_struct *fsp;
2491 const struct smb2_lease *lease;
2492 bool will_overwrite;
2493 uint32_t delay_mask;
2494 bool first_open_attempt;
2495 bool got_handle_lease;
2497 bool have_other_lease;
2498 uint32_t total_lease_types;
2502 static bool delay_for_oplock_fn(
2503 struct share_mode_entry *e,
2507 struct delay_for_oplock_state *state = private_data;
2508 struct files_struct *fsp = state->fsp;
2509 const struct smb2_lease *lease = state->lease;
2510 bool e_is_lease = (e->op_type == LEASE_OPLOCK);
2511 uint32_t e_lease_type = SMB2_LEASE_NONE;
2513 bool lease_is_breaking = false;
2518 if (lease != NULL) {
2519 bool our_lease = is_same_lease(fsp, e, lease);
2521 DBG_DEBUG("Ignoring our own lease\n");
2526 status = leases_db_get(
2530 &e_lease_type, /* current_state */
2532 NULL, /* breaking_to_requested */
2533 NULL, /* breaking_to_required */
2534 NULL, /* lease_version */
2538 * leases_db_get() can return NT_STATUS_NOT_FOUND
2539 * if the share_mode_entry e is stale and the
2540 * lease record was already removed. In this case return
2541 * false so the traverse continues.
2544 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND) &&
2545 share_entry_stale_pid(e))
2547 struct GUID_txt_buf guid_strbuf;
2548 struct file_id_buf file_id_strbuf;
2549 DBG_DEBUG("leases_db_get for client_guid [%s] "
2550 "lease_key [%"PRIu64"/%"PRIu64"] "
2551 "file_id [%s] failed for stale "
2552 "share_mode_entry\n",
2553 GUID_buf_string(&e->client_guid, &guid_strbuf),
2554 e->lease_key.data[0],
2555 e->lease_key.data[1],
2556 file_id_str_buf(fsp->file_id, &file_id_strbuf));
2559 if (!NT_STATUS_IS_OK(status)) {
2560 struct GUID_txt_buf guid_strbuf;
2561 struct file_id_buf file_id_strbuf;
2562 DBG_ERR("leases_db_get for client_guid [%s] "
2563 "lease_key [%"PRIu64"/%"PRIu64"] "
2564 "file_id [%s] failed: %s\n",
2565 GUID_buf_string(&e->client_guid, &guid_strbuf),
2566 e->lease_key.data[0],
2567 e->lease_key.data[1],
2568 file_id_str_buf(fsp->file_id, &file_id_strbuf),
2570 smb_panic("leases_db_get() failed");
2573 e_lease_type = get_lease_type(e, fsp->file_id);
2576 if (((e_lease_type & ~state->total_lease_types) != 0) &&
2577 !share_entry_stale_pid(e))
2579 state->total_lease_types |= e_lease_type;
2582 if (!state->got_handle_lease &&
2583 ((e_lease_type & SMB2_LEASE_HANDLE) != 0) &&
2584 !share_entry_stale_pid(e)) {
2585 state->got_handle_lease = true;
2588 if (!state->got_oplock &&
2589 (e->op_type != LEASE_OPLOCK) &&
2590 !share_entry_stale_pid(e)) {
2591 state->got_oplock = true;
2594 if (!state->have_other_lease &&
2595 !is_same_lease(fsp, e, lease) &&
2596 !share_entry_stale_pid(e)) {
2597 state->have_other_lease = true;
2600 if (e_is_lease && is_lease_stat_open(fsp->access_mask)) {
2604 break_to = e_lease_type & ~state->delay_mask;
2606 if (state->will_overwrite) {
2607 break_to &= ~(SMB2_LEASE_HANDLE|SMB2_LEASE_READ);
2610 DBG_DEBUG("e_lease_type %u, will_overwrite: %u\n",
2611 (unsigned)e_lease_type,
2612 (unsigned)state->will_overwrite);
2614 if ((e_lease_type & ~break_to) == 0) {
2615 if (lease_is_breaking) {
2616 state->delay = true;
2621 if (share_entry_stale_pid(e)) {
2625 if (state->will_overwrite) {
2627 * If we break anyway break to NONE directly.
2628 * Otherwise vfs_set_filelen() will trigger the
2631 break_to &= ~(SMB2_LEASE_READ|SMB2_LEASE_WRITE);
2636 * Oplocks only support breaking to R or NONE.
2638 break_to &= ~(SMB2_LEASE_HANDLE|SMB2_LEASE_WRITE);
2641 DBG_DEBUG("breaking from %d to %d\n",
2645 fsp->conn->sconn->msg_ctx, &fsp->file_id, e, break_to);
2646 if (e_lease_type & state->delay_mask) {
2647 state->delay = true;
2649 if (lease_is_breaking && !state->first_open_attempt) {
2650 state->delay = true;
2656 static NTSTATUS delay_for_oplock(files_struct *fsp,
2658 const struct smb2_lease *lease,
2659 struct share_mode_lock *lck,
2660 bool have_sharing_violation,
2661 uint32_t create_disposition,
2662 bool first_open_attempt,
2666 struct delay_for_oplock_state state = {
2669 .first_open_attempt = first_open_attempt,
2676 *poplock_type = NO_OPLOCK;
2679 if (fsp->fsp_flags.is_directory) {
2681 * No directory leases yet
2683 SMB_ASSERT(oplock_request == NO_OPLOCK);
2684 if (have_sharing_violation) {
2685 return NT_STATUS_SHARING_VIOLATION;
2687 return NT_STATUS_OK;
2690 if (oplock_request == LEASE_OPLOCK) {
2691 if (lease == NULL) {
2693 * The SMB2 layer should have checked this
2695 return NT_STATUS_INTERNAL_ERROR;
2698 requested = lease->lease_state;
2700 requested = map_oplock_to_lease_type(
2701 oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK);
2704 share_mode_flags_get(lck, NULL, NULL, &state.total_lease_types);
2706 if (is_oplock_stat_open(fsp->access_mask)) {
2710 state.delay_mask = have_sharing_violation ?
2711 SMB2_LEASE_HANDLE : SMB2_LEASE_WRITE;
2713 switch (create_disposition) {
2714 case FILE_SUPERSEDE:
2715 case FILE_OVERWRITE:
2716 case FILE_OVERWRITE_IF:
2717 state.will_overwrite = true;
2720 state.will_overwrite = false;
2724 state.total_lease_types = SMB2_LEASE_NONE;
2725 ok = share_mode_forall_entries(lck, delay_for_oplock_fn, &state);
2727 return NT_STATUS_INTERNAL_ERROR;
2731 return NT_STATUS_RETRY;
2735 if (have_sharing_violation) {
2736 return NT_STATUS_SHARING_VIOLATION;
2739 granted = requested;
2741 if (oplock_request == LEASE_OPLOCK) {
2742 if (lp_kernel_oplocks(SNUM(fsp->conn))) {
2743 DEBUG(10, ("No lease granted because kernel oplocks are enabled\n"));
2744 granted = SMB2_LEASE_NONE;
2746 if ((granted & (SMB2_LEASE_READ|SMB2_LEASE_WRITE)) == 0) {
2747 DEBUG(10, ("No read or write lease requested\n"));
2748 granted = SMB2_LEASE_NONE;
2750 if (granted == SMB2_LEASE_WRITE) {
2751 DEBUG(10, ("pure write lease requested\n"));
2752 granted = SMB2_LEASE_NONE;
2754 if (granted == (SMB2_LEASE_WRITE|SMB2_LEASE_HANDLE)) {
2755 DEBUG(10, ("write and handle lease requested\n"));
2756 granted = SMB2_LEASE_NONE;
2760 if (lp_locking(fsp->conn->params) && file_has_brlocks(fsp)) {
2761 DBG_DEBUG("file %s has byte range locks\n",
2763 granted &= ~SMB2_LEASE_READ;
2766 if (state.have_other_lease) {
2768 * Can grant only one writer
2770 granted &= ~SMB2_LEASE_WRITE;
2773 if ((granted & SMB2_LEASE_READ) && !(granted & SMB2_LEASE_WRITE)) {
2775 (global_client_caps & CAP_LEVEL_II_OPLOCKS) &&
2776 lp_level2_oplocks(SNUM(fsp->conn));
2778 if (!allow_level2) {
2779 granted = SMB2_LEASE_NONE;
2783 if (oplock_request == LEASE_OPLOCK) {
2784 if (state.got_oplock) {
2785 granted &= ~SMB2_LEASE_HANDLE;
2788 oplock_type = LEASE_OPLOCK;
2790 if (state.got_handle_lease) {
2791 granted = SMB2_LEASE_NONE;
2795 * Reflect possible downgrades from:
2796 * - map_lease_type_to_oplock() => "RH" to just LEVEL_II
2798 oplock_type = map_lease_type_to_oplock(granted);
2799 granted = map_oplock_to_lease_type(oplock_type);
2802 state.total_lease_types |= granted;
2805 uint32_t acc, sh, ls;
2806 share_mode_flags_get(lck, &acc, &sh, &ls);
2807 ls = state.total_lease_types;
2808 share_mode_flags_set(lck, acc, sh, ls, NULL);
2811 DBG_DEBUG("oplock type 0x%x granted (%s%s%s)(0x%x), on file %s, "
2812 "requested 0x%x (%s%s%s)(0x%x) => total (%s%s%s)(0x%x)\n",
2814 granted & SMB2_LEASE_READ ? "R":"",
2815 granted & SMB2_LEASE_WRITE ? "W":"",
2816 granted & SMB2_LEASE_HANDLE ? "H":"",
2820 requested & SMB2_LEASE_READ ? "R":"",
2821 requested & SMB2_LEASE_WRITE ? "W":"",
2822 requested & SMB2_LEASE_HANDLE ? "H":"",
2824 state.total_lease_types & SMB2_LEASE_READ ? "R":"",
2825 state.total_lease_types & SMB2_LEASE_WRITE ? "W":"",
2826 state.total_lease_types & SMB2_LEASE_HANDLE ? "H":"",
2827 state.total_lease_types);
2829 *poplock_type = oplock_type;
2830 *pgranted = granted;
2831 return NT_STATUS_OK;
2834 static NTSTATUS handle_share_mode_lease(
2836 struct share_mode_lock *lck,
2837 uint32_t create_disposition,
2838 uint32_t access_mask,
2839 uint32_t share_access,
2841 const struct smb2_lease *lease,
2842 bool first_open_attempt,
2846 bool sharing_violation = false;
2849 *poplock_type = NO_OPLOCK;
2852 status = open_mode_check(
2853 fsp->conn, fsp->file_id, lck, access_mask, share_access);
2854 if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
2855 sharing_violation = true;
2856 status = NT_STATUS_OK; /* handled later */
2859 if (!NT_STATUS_IS_OK(status)) {
2863 if (oplock_request == INTERNAL_OPEN_ONLY) {
2864 if (sharing_violation) {
2865 DBG_DEBUG("Sharing violation for internal open\n");
2866 return NT_STATUS_SHARING_VIOLATION;
2870 * Internal opens never do oplocks or leases. We don't
2871 * need to go through delay_for_oplock().
2873 return NT_STATUS_OK;
2876 status = delay_for_oplock(
2886 if (!NT_STATUS_IS_OK(status)) {
2890 return NT_STATUS_OK;
2893 static bool request_timed_out(struct smb_request *req, struct timeval timeout)
2895 struct timeval now, end_time;
2897 end_time = timeval_sum(&req->request_time, &timeout);
2898 return (timeval_compare(&end_time, &now) < 0);
2901 struct defer_open_state {
2902 struct smbXsrv_connection *xconn;
2906 static void defer_open_done(struct tevent_req *req);
2909 * Defer an open and watch a locking.tdb record
2911 * This defers an open that gets rescheduled once the locking.tdb record watch
2912 * is triggered by a change to the record.
2914 * It is used to defer opens that triggered an oplock break and for the SMB1
2915 * sharing violation delay.
2917 static void defer_open(struct share_mode_lock *lck,
2918 struct timeval timeout,
2919 struct smb_request *req,
2922 struct deferred_open_record *open_rec = NULL;
2923 struct timeval abs_timeout;
2924 struct defer_open_state *watch_state;
2925 struct tevent_req *watch_req;
2926 struct timeval_buf tvbuf1, tvbuf2;
2927 struct file_id_buf fbuf;
2930 abs_timeout = timeval_sum(&req->request_time, &timeout);
2932 DBG_DEBUG("request time [%s] timeout [%s] mid [%" PRIu64 "] "
2934 timeval_str_buf(&req->request_time, false, true, &tvbuf1),
2935 timeval_str_buf(&abs_timeout, false, true, &tvbuf2),
2937 file_id_str_buf(id, &fbuf));
2939 open_rec = talloc_zero(NULL, struct deferred_open_record);
2940 if (open_rec == NULL) {
2942 exit_server("talloc failed");
2945 watch_state = talloc(open_rec, struct defer_open_state);
2946 if (watch_state == NULL) {
2947 exit_server("talloc failed");
2949 watch_state->xconn = req->xconn;
2950 watch_state->mid = req->mid;
2952 DBG_DEBUG("defering mid %" PRIu64 "\n", req->mid);
2954 watch_req = share_mode_watch_send(
2958 (struct server_id){0});
2959 if (watch_req == NULL) {
2960 exit_server("Could not watch share mode record");
2962 tevent_req_set_callback(watch_req, defer_open_done, watch_state);
2964 ok = tevent_req_set_endtime(watch_req, req->sconn->ev_ctx, abs_timeout);
2966 exit_server("tevent_req_set_endtime failed");
2969 ok = push_deferred_open_message_smb(req, timeout, id, open_rec);
2972 exit_server("push_deferred_open_message_smb failed");
2976 static void defer_open_done(struct tevent_req *req)
2978 struct defer_open_state *state = tevent_req_callback_data(
2979 req, struct defer_open_state);
2983 status = share_mode_watch_recv(req, NULL, NULL);
2985 if (!NT_STATUS_IS_OK(status)) {
2986 DEBUG(5, ("dbwrap_watched_watch_recv returned %s\n",
2987 nt_errstr(status)));
2989 * Even if it failed, retry anyway. TODO: We need a way to
2990 * tell a re-scheduled open about that error.
2994 DEBUG(10, ("scheduling mid %llu\n", (unsigned long long)state->mid));
2996 ret = schedule_deferred_open_message_smb(state->xconn, state->mid);
3002 * Actually attempt the kernel oplock polling open.
3005 static void poll_open_fn(struct tevent_context *ev,
3006 struct tevent_timer *te,
3007 struct timeval current_time,
3010 struct deferred_open_record *open_rec = talloc_get_type_abort(
3011 private_data, struct deferred_open_record);
3014 TALLOC_FREE(open_rec->watch_req);
3016 ok = schedule_deferred_open_message_smb(
3017 open_rec->xconn, open_rec->mid);
3019 exit_server("schedule_deferred_open_message_smb failed");
3021 DBG_DEBUG("timer fired. Retrying open !\n");
3024 static void poll_open_done(struct tevent_req *subreq);
3026 struct poll_open_setup_watcher_state {
3027 TALLOC_CTX *mem_ctx;
3028 struct tevent_context *ev_ctx;
3029 struct tevent_req *watch_req;
3032 static void poll_open_setup_watcher_fn(struct share_mode_lock *lck,
3035 struct poll_open_setup_watcher_state *state =
3036 (struct poll_open_setup_watcher_state *)private_data;
3038 if (!validate_oplock_types(lck)) {
3039 smb_panic("validate_oplock_types failed");
3042 state->watch_req = share_mode_watch_send(
3046 (struct server_id) {0});
3047 if (state->watch_req == NULL) {
3048 DBG_WARNING("share_mode_watch_send failed\n");
3054 * Reschedule an open for 1 second from now, if not timed out.
3056 static bool setup_poll_open(
3057 struct smb_request *req,
3058 const struct file_id *id,
3059 struct timeval max_timeout,
3060 struct timeval interval)
3062 static struct file_id zero_id = {};
3064 struct deferred_open_record *open_rec = NULL;
3065 struct timeval endtime, next_interval;
3066 struct file_id_buf ftmp;
3068 if (request_timed_out(req, max_timeout)) {
3072 open_rec = talloc_zero(NULL, struct deferred_open_record);
3073 if (open_rec == NULL) {
3074 DBG_WARNING("talloc failed\n");
3077 open_rec->xconn = req->xconn;
3078 open_rec->mid = req->mid;
3081 * Make sure open_rec->te does not come later than the
3082 * request's maximum endtime.
3085 endtime = timeval_sum(&req->request_time, &max_timeout);
3086 next_interval = timeval_current_ofs(interval.tv_sec, interval.tv_usec);
3087 next_interval = timeval_min(&endtime, &next_interval);
3089 open_rec->te = tevent_add_timer(
3095 if (open_rec->te == NULL) {
3096 DBG_WARNING("tevent_add_timer failed\n");
3097 TALLOC_FREE(open_rec);
3102 struct poll_open_setup_watcher_state wstate = {
3103 .mem_ctx = open_rec,
3104 .ev_ctx = req->sconn->ev_ctx,
3108 status = share_mode_do_locked_vfs_denied(*id,
3109 poll_open_setup_watcher_fn,
3111 if (NT_STATUS_IS_OK(status)) {
3112 if (wstate.watch_req == NULL) {
3113 DBG_WARNING("share_mode_watch_send failed\n");
3114 TALLOC_FREE(open_rec);
3117 open_rec->watch_req = wstate.watch_req;
3118 tevent_req_set_callback(open_rec->watch_req,
3121 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
3122 DBG_WARNING("share_mode_do_locked_vfs_denied failed - %s\n",
3124 TALLOC_FREE(open_rec);
3131 ok = push_deferred_open_message_smb(req, max_timeout, *id, open_rec);
3133 DBG_WARNING("push_deferred_open_message_smb failed\n");
3134 TALLOC_FREE(open_rec);
3138 DBG_DEBUG("poll request time [%s] mid [%" PRIu64 "] file_id [%s]\n",
3139 timeval_string(talloc_tos(), &req->request_time, false),
3141 file_id_str_buf(*id, &ftmp));
3146 static void poll_open_done(struct tevent_req *subreq)
3148 struct deferred_open_record *open_rec = tevent_req_callback_data(
3149 subreq, struct deferred_open_record);
3153 status = share_mode_watch_recv(subreq, NULL, NULL);
3154 TALLOC_FREE(subreq);
3155 open_rec->watch_req = NULL;
3156 TALLOC_FREE(open_rec->te);
3158 DBG_DEBUG("dbwrap_watched_watch_recv returned %s\n",
3161 ok = schedule_deferred_open_message_smb(
3162 open_rec->xconn, open_rec->mid);
3164 exit_server("schedule_deferred_open_message_smb failed");
3168 bool defer_smb1_sharing_violation(struct smb_request *req)
3173 if (!lp_defer_sharing_violations()) {
3178 * Try every 200msec up to (by default) one second. To be
3179 * precise, according to behaviour note <247> in [MS-CIFS],
3180 * the server tries 5 times. But up to one second should be
3184 timeout_usecs = lp_parm_int(
3188 SHARING_VIOLATION_USEC_WAIT);
3190 ok = setup_poll_open(
3193 (struct timeval) { .tv_usec = timeout_usecs },
3194 (struct timeval) { .tv_usec = 200000 });
3198 /****************************************************************************
3199 On overwrite open ensure that the attributes match.
3200 ****************************************************************************/
3202 static bool open_match_attributes(connection_struct *conn,
3203 uint32_t old_dos_attr,
3204 uint32_t new_dos_attr,
3205 mode_t new_unx_mode,
3206 mode_t *returned_unx_mode)
3208 uint32_t noarch_old_dos_attr, noarch_new_dos_attr;
3210 noarch_old_dos_attr = (old_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
3211 noarch_new_dos_attr = (new_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
3213 if((noarch_old_dos_attr == 0 && noarch_new_dos_attr != 0) ||
3214 (noarch_old_dos_attr != 0 && ((noarch_old_dos_attr & noarch_new_dos_attr) == noarch_old_dos_attr))) {
3215 *returned_unx_mode = new_unx_mode;
3217 *returned_unx_mode = (mode_t)0;
3220 DEBUG(10,("open_match_attributes: old_dos_attr = 0x%x, "
3221 "new_dos_attr = 0x%x "
3222 "returned_unx_mode = 0%o\n",
3223 (unsigned int)old_dos_attr,
3224 (unsigned int)new_dos_attr,
3225 (unsigned int)*returned_unx_mode ));
3227 /* If we're mapping SYSTEM and HIDDEN ensure they match. */
3228 if (lp_map_system(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
3229 if ((old_dos_attr & FILE_ATTRIBUTE_SYSTEM) &&
3230 !(new_dos_attr & FILE_ATTRIBUTE_SYSTEM)) {
3234 if (lp_map_hidden(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
3235 if ((old_dos_attr & FILE_ATTRIBUTE_HIDDEN) &&
3236 !(new_dos_attr & FILE_ATTRIBUTE_HIDDEN)) {
3243 static void schedule_defer_open(struct share_mode_lock *lck,
3245 struct smb_request *req)
3247 /* This is a relative time, added to the absolute
3248 request_time value to get the absolute timeout time.
3249 Note that if this is the second or greater time we enter
3250 this codepath for this particular request mid then
3251 request_time is left as the absolute time of the *first*
3252 time this request mid was processed. This is what allows
3253 the request to eventually time out. */
3255 struct timeval timeout;
3257 /* Normally the smbd we asked should respond within
3258 * OPLOCK_BREAK_TIMEOUT seconds regardless of whether
3259 * the client did, give twice the timeout as a safety
3260 * measure here in case the other smbd is stuck
3261 * somewhere else. */
3263 timeout = timeval_set(OPLOCK_BREAK_TIMEOUT*2, 0);
3265 if (request_timed_out(req, timeout)) {
3269 defer_open(lck, timeout, req, id);
3272 /****************************************************************************
3273 Reschedule an open call that went asynchronous.
3274 ****************************************************************************/
3276 static void schedule_async_open_timer(struct tevent_context *ev,
3277 struct tevent_timer *te,
3278 struct timeval current_time,
3281 exit_server("async open timeout");
3284 static void schedule_async_open(struct smb_request *req)
3286 struct deferred_open_record *open_rec = NULL;
3287 struct timeval timeout = timeval_set(20, 0);
3290 if (request_timed_out(req, timeout)) {
3294 open_rec = talloc_zero(NULL, struct deferred_open_record);
3295 if (open_rec == NULL) {
3296 exit_server("deferred_open_record_create failed");
3298 open_rec->async_open = true;
3300 ok = push_deferred_open_message_smb(
3301 req, timeout, (struct file_id){0}, open_rec);
3303 exit_server("push_deferred_open_message_smb failed");
3306 open_rec->te = tevent_add_timer(req->sconn->ev_ctx,
3308 timeval_current_ofs(20, 0),
3309 schedule_async_open_timer,
3311 if (open_rec->te == NULL) {
3312 exit_server("tevent_add_timer failed");
3316 static NTSTATUS check_and_store_share_mode(
3317 struct files_struct *fsp,
3318 struct smb_request *req,
3319 struct share_mode_lock *lck,
3320 uint32_t create_disposition,
3321 uint32_t access_mask,
3322 uint32_t share_access,
3324 const struct smb2_lease *lease,
3325 bool first_open_attempt)
3328 int oplock_type = NO_OPLOCK;
3329 uint32_t granted_lease = 0;
3330 const struct smb2_lease_key *lease_key = NULL;
3331 bool delete_on_close;
3334 /* Get the types we need to examine. */
3335 if (!validate_oplock_types(lck)) {
3336 smb_panic("validate_oplock_types failed");
3339 delete_on_close = has_delete_on_close(lck, fsp->name_hash);
3340 if (delete_on_close) {
3341 return NT_STATUS_DELETE_PENDING;
3344 status = handle_share_mode_lease(fsp,
3354 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
3355 schedule_defer_open(lck, fsp->file_id, req);
3356 return NT_STATUS_SHARING_VIOLATION;
3358 if (!NT_STATUS_IS_OK(status)) {
3362 if (oplock_type == LEASE_OPLOCK) {
3363 lease_key = &lease->lease_key;
3366 share_mode_flags_restrict(lck, access_mask, share_access, 0);
3368 ok = set_share_mode(lck,
3370 get_current_uid(fsp->conn),
3377 return NT_STATUS_NO_MEMORY;
3380 if (oplock_type == LEASE_OPLOCK) {
3381 status = grant_fsp_lease(fsp, lck, lease, granted_lease);
3382 if (!NT_STATUS_IS_OK(status)) {
3383 del_share_mode(lck, fsp);
3387 DBG_DEBUG("lease_state=%d\n", fsp->lease->lease.lease_state);
3390 fsp->oplock_type = oplock_type;
3392 return NT_STATUS_OK;
3395 /****************************************************************************
3396 Work out what access_mask to use from what the client sent us.
3397 ****************************************************************************/
3399 static NTSTATUS smbd_calculate_maximum_allowed_access_fsp(
3400 struct files_struct *dirfsp,
3401 struct files_struct *fsp,
3403 uint32_t *p_access_mask)
3405 struct security_descriptor *sd = NULL;
3406 uint32_t access_granted = 0;
3410 /* Cope with symlinks */
3411 if (fsp == NULL || fsp_get_pathref_fd(fsp) == -1) {
3412 *p_access_mask = FILE_GENERIC_ALL;
3413 return NT_STATUS_OK;
3416 /* Cope with fake/printer fsp's. */
3417 if (fsp->fake_file_handle != NULL || fsp->print_file != NULL) {
3418 *p_access_mask = FILE_GENERIC_ALL;
3419 return NT_STATUS_OK;
3422 if (!use_privs && (get_current_uid(fsp->conn) == (uid_t)0)) {
3423 *p_access_mask |= FILE_GENERIC_ALL;
3424 return NT_STATUS_OK;
3427 status = SMB_VFS_FGET_NT_ACL(metadata_fsp(fsp),
3434 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
3436 * File did not exist
3438 *p_access_mask = FILE_GENERIC_ALL;
3439 return NT_STATUS_OK;
3441 if (!NT_STATUS_IS_OK(status)) {
3442 DBG_ERR("Could not get acl on file %s: %s\n",
3449 * If we can access the path to this file, by
3450 * default we have FILE_READ_ATTRIBUTES from the
3451 * containing directory. See the section:
3452 * "Algorithm to Check Access to an Existing File"
3455 * se_file_access_check()
3456 * also takes care of owner WRITE_DAC and READ_CONTROL.
3458 status = se_file_access_check(sd,
3459 get_current_nttok(fsp->conn),
3461 (*p_access_mask & ~FILE_READ_ATTRIBUTES),
3466 if (!NT_STATUS_IS_OK(status)) {
3467 DBG_ERR("Status %s on file %s: "
3468 "when calculating maximum access\n",
3474 *p_access_mask = (access_granted | FILE_READ_ATTRIBUTES);
3476 if (!(access_granted & DELETE_ACCESS)) {
3477 if (can_delete_file_in_directory(fsp->conn,
3480 *p_access_mask |= DELETE_ACCESS;
3484 dosattrs = fdos_mode(fsp);
3485 if (IS_DOS_READONLY(dosattrs) || !CAN_WRITE(fsp->conn)) {
3486 *p_access_mask &= ~(FILE_GENERIC_WRITE | DELETE_ACCESS);
3489 return NT_STATUS_OK;
3492 NTSTATUS smbd_calculate_access_mask_fsp(struct files_struct *dirfsp,
3493 struct files_struct *fsp,
3495 uint32_t access_mask,
3496 uint32_t *access_mask_out)
3499 uint32_t orig_access_mask = access_mask;
3500 uint32_t rejected_share_access;
3502 if (access_mask & SEC_MASK_INVALID) {
3503 DBG_DEBUG("access_mask [%8x] contains invalid bits\n",
3505 return NT_STATUS_ACCESS_DENIED;
3509 * Convert GENERIC bits to specific bits.
3512 se_map_generic(&access_mask, &file_generic_mapping);
3514 /* Calculate MAXIMUM_ALLOWED_ACCESS if requested. */
3515 if (access_mask & MAXIMUM_ALLOWED_ACCESS) {
3517 status = smbd_calculate_maximum_allowed_access_fsp(
3523 if (!NT_STATUS_IS_OK(status)) {
3527 access_mask &= fsp->conn->share_access;
3530 rejected_share_access = access_mask & ~(fsp->conn->share_access);
3532 if (rejected_share_access) {
3533 DBG_INFO("Access denied on file %s: "
3534 "rejected by share access mask[0x%08X] "
3535 "orig[0x%08X] mapped[0x%08X] reject[0x%08X]\n",
3537 fsp->conn->share_access,
3538 orig_access_mask, access_mask,
3539 rejected_share_access);
3540 return NT_STATUS_ACCESS_DENIED;
3543 *access_mask_out = access_mask;
3544 return NT_STATUS_OK;
3547 /****************************************************************************
3548 Remove the deferred open entry under lock.
3549 ****************************************************************************/
3551 /****************************************************************************
3552 Return true if this is a state pointer to an asynchronous create.
3553 ****************************************************************************/
3555 bool is_deferred_open_async(const struct deferred_open_record *rec)
3557 return rec->async_open;
3560 static bool clear_ads(uint32_t create_disposition)
3564 switch (create_disposition) {
3565 case FILE_SUPERSEDE:
3566 case FILE_OVERWRITE_IF:
3567 case FILE_OVERWRITE:
3576 static int disposition_to_open_flags(uint32_t create_disposition)
3581 * Currently we're using FILE_SUPERSEDE as the same as
3582 * FILE_OVERWRITE_IF but they really are
3583 * different. FILE_SUPERSEDE deletes an existing file
3584 * (requiring delete access) then recreates it.
3587 switch (create_disposition) {
3588 case FILE_SUPERSEDE:
3589 case FILE_OVERWRITE_IF:
3591 * If file exists replace/overwrite. If file doesn't
3594 ret = O_CREAT|O_TRUNC;
3599 * If file exists open. If file doesn't exist error.
3604 case FILE_OVERWRITE:
3606 * If file exists overwrite. If file doesn't exist
3614 * If file exists error. If file doesn't exist create.
3616 ret = O_CREAT|O_EXCL;
3621 * If file exists open. If file doesn't exist create.
3629 static int calculate_open_access_flags(uint32_t access_mask,
3630 uint32_t private_flags,
3633 bool need_write, need_read;
3636 * Note that we ignore the append flag as append does not
3637 * mean the same thing under DOS and Unix.
3642 * Pave over the user requested mode and force O_RDONLY for the
3643 * file handle. Windows allows opening a VSS file with O_RDWR,
3644 * even though actual writes on the handle will fail.
3649 need_write = (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA));
3654 /* DENY_DOS opens are always underlying read-write on the
3655 file handle, no matter what the requested access mask
3659 ((private_flags & NTCREATEX_FLAG_DENY_DOS) ||
3660 access_mask & (FILE_READ_ATTRIBUTES|FILE_READ_DATA|
3661 FILE_READ_EA|FILE_EXECUTE));
3669 struct open_ntcreate_lock_state {
3670 struct share_mode_entry_prepare_state prepare_state;
3671 struct files_struct *fsp;
3672 const char *object_type;
3673 struct smb_request *req;
3674 uint32_t create_disposition;
3675 uint32_t access_mask;
3676 uint32_t share_access;
3678 const struct smb2_lease *lease;
3679 bool first_open_attempt;
3682 struct timespec write_time;
3683 share_mode_entry_prepare_unlock_fn_t cleanup_fn;
3686 static void open_ntcreate_lock_add_entry(struct share_mode_lock *lck,
3690 struct open_ntcreate_lock_state *state =
3691 (struct open_ntcreate_lock_state *)private_data;
3694 * By default drop the g_lock again if we leave the
3697 *keep_locked = false;
3699 state->status = check_and_store_share_mode(state->fsp,
3702 state->create_disposition,
3704 state->share_access,
3705 state->oplock_request,
3707 state->first_open_attempt);
3708 if (!NT_STATUS_IS_OK(state->status)) {
3712 state->write_time = get_share_mode_write_time(lck);
3715 * keep the g_lock while existing the tdb chainlock,
3716 * we we're asked to, which mean we'll keep
3717 * the share_mode_lock during object creation,
3718 * or setting delete on close.
3720 *keep_locked = state->keep_locked;
3723 static void open_ntcreate_lock_cleanup_oplock(struct share_mode_lock *lck,
3726 struct open_ntcreate_lock_state *state =
3727 (struct open_ntcreate_lock_state *)private_data;
3730 ok = remove_share_oplock(lck, state->fsp);
3732 DBG_ERR("Could not remove oplock for %s %s\n",
3733 state->object_type, fsp_str_dbg(state->fsp));
3737 static void open_ntcreate_lock_cleanup_entry(struct share_mode_lock *lck,
3740 struct open_ntcreate_lock_state *state =
3741 (struct open_ntcreate_lock_state *)private_data;
3744 ok = del_share_mode(lck, state->fsp);
3746 DBG_ERR("Could not delete share entry for %s %s\n",
3747 state->object_type, fsp_str_dbg(state->fsp));
3751 /****************************************************************************
3752 Open a file with a share mode. Passed in an already created files_struct *.
3753 ****************************************************************************/
3755 static NTSTATUS open_file_ntcreate(connection_struct *conn,
3756 struct smb_request *req,
3757 uint32_t access_mask, /* access bits (FILE_READ_DATA etc.) */
3758 uint32_t share_access, /* share constants (FILE_SHARE_READ etc) */
3759 uint32_t create_disposition, /* FILE_OPEN_IF etc. */
3760 uint32_t create_options, /* options such as delete on close. */
3761 uint32_t new_dos_attributes, /* attributes used for new file. */
3762 int oplock_request, /* internal Samba oplock codes. */
3763 const struct smb2_lease *lease,
3764 /* Information (FILE_EXISTS etc.) */
3765 uint32_t private_flags, /* Samba specific flags. */
3766 struct smb_filename *parent_dir_fname, /* parent. */
3767 struct smb_filename *smb_fname_atname, /* atname relative to parent. */
3771 struct smb_filename *smb_fname = fsp->fsp_name;
3774 bool file_existed = VALID_STAT(smb_fname->st);
3775 bool def_acl = False;
3776 bool posix_open = False;
3777 bool new_file_created = False;
3778 bool first_open_attempt = true;
3779 bool is_twrp = (smb_fname_atname->twrp != 0);
3780 NTSTATUS fsp_open = NT_STATUS_ACCESS_DENIED;
3781 mode_t new_unx_mode = (mode_t)0;
3782 mode_t unx_mode = (mode_t)0;
3784 uint32_t existing_dos_attributes = 0;
3785 struct open_ntcreate_lock_state lck_state = {};
3786 bool keep_locked = false;
3787 uint32_t open_access_mask = access_mask;
3789 SMB_STRUCT_STAT saved_stat = smb_fname->st;
3790 struct timespec old_write_time;
3791 bool setup_poll = false;
3794 if (conn->printer) {
3796 * Printers are handled completely differently.
3797 * Most of the passed parameters are ignored.
3801 *pinfo = FILE_WAS_CREATED;
3804 DEBUG(10, ("open_file_ntcreate: printer open fname=%s\n",
3805 smb_fname_str_dbg(smb_fname)));
3808 DEBUG(0,("open_file_ntcreate: printer open without "
3809 "an SMB request!\n"));
3810 return NT_STATUS_INTERNAL_ERROR;
3813 return print_spool_open(fsp, smb_fname->base_name,
3817 if (new_dos_attributes & FILE_FLAG_POSIX_SEMANTICS) {
3819 unx_mode = (mode_t)(new_dos_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
3820 new_dos_attributes = 0;
3822 /* Windows allows a new file to be created and
3823 silently removes a FILE_ATTRIBUTE_DIRECTORY
3824 sent by the client. Do the same. */
3826 new_dos_attributes &= ~FILE_ATTRIBUTE_DIRECTORY;
3828 /* We add FILE_ATTRIBUTE_ARCHIVE to this as this mode is only used if the file is
3830 unx_mode = unix_mode(
3832 new_dos_attributes | FILE_ATTRIBUTE_ARCHIVE,
3834 parent_dir_fname->fsp);
3837 DEBUG(10, ("open_file_ntcreate: fname=%s, dos_attrs=0x%x "
3838 "access_mask=0x%x share_access=0x%x "
3839 "create_disposition = 0x%x create_options=0x%x "
3840 "unix mode=0%o oplock_request=%d private_flags = 0x%x\n",
3841 smb_fname_str_dbg(smb_fname), new_dos_attributes,
3842 access_mask, share_access, create_disposition,
3843 create_options, (unsigned int)unx_mode, oplock_request,
3844 (unsigned int)private_flags));
3847 /* Ensure req == NULL means INTERNAL_OPEN_ONLY */
3848 SMB_ASSERT(oplock_request == INTERNAL_OPEN_ONLY);
3850 /* And req != NULL means no INTERNAL_OPEN_ONLY */
3851 SMB_ASSERT(((oplock_request & INTERNAL_OPEN_ONLY) == 0));
3855 * Only non-internal opens can be deferred at all
3859 struct deferred_open_record *open_rec;
3860 if (get_deferred_open_message_state(req, NULL, &open_rec)) {
3862 /* If it was an async create retry, the file
3865 if (is_deferred_open_async(open_rec)) {
3866 SET_STAT_INVALID(smb_fname->st);
3867 file_existed = false;
3870 /* Ensure we don't reprocess this message. */
3871 remove_deferred_open_message_smb(req->xconn, req->mid);
3873 first_open_attempt = false;
3878 new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
3881 * Only use stored DOS attributes for checks
3882 * against requested attributes (below via
3883 * open_match_attributes()), cf bug #11992
3884 * for details. -slow
3888 status = vfs_fget_dos_attributes(smb_fname->fsp, &attr);
3889 if (NT_STATUS_IS_OK(status)) {
3890 existing_dos_attributes = attr;
3895 /* ignore any oplock requests if oplocks are disabled */
3896 if (!lp_oplocks(SNUM(conn)) ||
3897 IS_VETO_OPLOCK_PATH(conn, smb_fname->base_name)) {
3898 /* Mask off everything except the private Samba bits. */
3899 oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
3902 /* this is for OS/2 long file names - say we don't support them */
3903 if (req != NULL && !req->posix_pathnames &&
3904 strstr(smb_fname->base_name,".+,;=[].")) {
3905 /* OS/2 Workplace shell fix may be main code stream in a later
3907 DEBUG(5,("open_file_ntcreate: OS/2 long filenames are not "
3909 if (use_nt_status()) {
3910 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3912 return NT_STATUS_DOS(ERRDOS, ERRcannotopen);
3915 switch( create_disposition ) {
3917 /* If file exists open. If file doesn't exist error. */
3918 if (!file_existed) {
3919 DEBUG(5,("open_file_ntcreate: FILE_OPEN "
3920 "requested for file %s and file "
3922 smb_fname_str_dbg(smb_fname)));
3923 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3927 case FILE_OVERWRITE:
3928 /* If file exists overwrite. If file doesn't exist
3930 if (!file_existed) {
3931 DEBUG(5,("open_file_ntcreate: FILE_OVERWRITE "
3932 "requested for file %s and file "
3934 smb_fname_str_dbg(smb_fname) ));
3935 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3938 return NT_STATUS_MEDIA_WRITE_PROTECTED;
3943 /* If file exists error. If file doesn't exist
3946 DEBUG(5,("open_file_ntcreate: FILE_CREATE "
3947 "requested for file %s and file "
3948 "already exists.\n",
3949 smb_fname_str_dbg(smb_fname)));
3950 if (S_ISDIR(smb_fname->st.st_ex_mode)) {
3951 return NT_STATUS_FILE_IS_A_DIRECTORY;
3953 return NT_STATUS_OBJECT_NAME_COLLISION;
3956 return NT_STATUS_MEDIA_WRITE_PROTECTED;
3960 case FILE_SUPERSEDE:
3961 case FILE_OVERWRITE_IF:
3963 return NT_STATUS_MEDIA_WRITE_PROTECTED;
3968 if (!file_existed) {
3969 return NT_STATUS_MEDIA_WRITE_PROTECTED;
3971 create_disposition = FILE_OPEN;
3975 return NT_STATUS_INVALID_PARAMETER;
3978 flags2 = disposition_to_open_flags(create_disposition);
3980 /* We only care about matching attributes on file exists and
3983 if (!posix_open && file_existed &&
3984 ((create_disposition == FILE_OVERWRITE) ||
3985 (create_disposition == FILE_OVERWRITE_IF))) {
3986 if (!open_match_attributes(conn, existing_dos_attributes,
3988 unx_mode, &new_unx_mode)) {
3989 DEBUG(5,("open_file_ntcreate: attributes mismatch "
3990 "for file %s (%x %x) (0%o, 0%o)\n",
3991 smb_fname_str_dbg(smb_fname),
3992 existing_dos_attributes,
3994 (unsigned int)smb_fname->st.st_ex_mode,
3995 (unsigned int)unx_mode ));
3996 return NT_STATUS_ACCESS_DENIED;
4000 status = smbd_calculate_access_mask_fsp(parent_dir_fname->fsp,
4005 if (!NT_STATUS_IS_OK(status)) {
4006 DBG_DEBUG("smbd_calculate_access_mask_fsp "
4007 "on file %s returned %s\n",
4008 smb_fname_str_dbg(smb_fname),
4013 open_access_mask = access_mask;
4015 if (flags2 & O_TRUNC) {
4016 open_access_mask |= FILE_WRITE_DATA; /* This will cause oplock breaks. */
4021 * stat opens on existing files don't get oplocks.
4022 * They can get leases.
4024 * Note that we check for stat open on the *open_access_mask*,
4025 * i.e. the access mask we actually used to do the open,
4026 * not the one the client asked for (which is in
4027 * fsp->access_mask). This is due to the fact that
4028 * FILE_OVERWRITE and FILE_OVERWRITE_IF add in O_TRUNC,
4029 * which adds FILE_WRITE_DATA to open_access_mask.
4031 if (is_oplock_stat_open(open_access_mask) && lease == NULL) {
4032 oplock_request = NO_OPLOCK;
4036 DEBUG(10, ("open_file_ntcreate: fname=%s, after mapping "
4037 "access_mask=0x%x\n", smb_fname_str_dbg(smb_fname),
4041 * Note that we ignore the append flag as append does not
4042 * mean the same thing under DOS and Unix.
4045 flags = calculate_open_access_flags(access_mask,
4050 * Currently we only look at FILE_WRITE_THROUGH for create options.
4054 if ((create_options & FILE_WRITE_THROUGH) && lp_strict_sync(SNUM(conn))) {
4059 if (posix_open && (access_mask & FILE_APPEND_DATA)) {
4063 if (!posix_open && !CAN_WRITE(conn)) {
4065 * We should really return a permission denied error if either
4066 * O_CREAT or O_TRUNC are set, but for compatibility with
4067 * older versions of Samba we just AND them out.
4069 flags2 &= ~(O_CREAT|O_TRUNC);
4073 * With kernel oplocks the open breaking an oplock
4074 * blocks until the oplock holder has given up the
4075 * oplock or closed the file. We prevent this by always
4076 * trying to open the file with O_NONBLOCK (see "man
4079 * If a process that doesn't use the smbd open files
4080 * database or communication methods holds a kernel
4081 * oplock we must periodically poll for available open
4084 flags2 |= O_NONBLOCK;
4087 * Ensure we can't write on a read-only share or file.
4090 if (flags != O_RDONLY && file_existed &&
4091 (!CAN_WRITE(conn) || IS_DOS_READONLY(existing_dos_attributes))) {
4092 DEBUG(5,("open_file_ntcreate: write access requested for "
4093 "file %s on read only %s\n",
4094 smb_fname_str_dbg(smb_fname),
4095 !CAN_WRITE(conn) ? "share" : "file" ));
4096 return NT_STATUS_ACCESS_DENIED;
4099 if (VALID_STAT(smb_fname->st)) {
4101 * Only try and create a file id before open
4102 * for an existing file. For a file being created
4103 * this won't do anything useful until the file
4104 * exists and has a valid stat struct.
4106 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
4108 fh_set_private_options(fsp->fh, private_flags);
4109 fsp->access_mask = open_access_mask; /* We change this to the
4110 * requested access_mask after
4111 * the open is done. */
4113 fsp->posix_flags |= FSP_POSIX_FLAGS_ALL;
4116 if ((create_options & FILE_DELETE_ON_CLOSE) &&
4117 (flags2 & O_CREAT) &&
4119 /* Delete on close semantics for new files. */
4120 status = can_set_delete_on_close(fsp,
4121 new_dos_attributes);
4122 if (!NT_STATUS_IS_OK(status)) {
4129 * Ensure we pay attention to default ACLs on directories if required.
4132 if ((flags2 & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
4133 (def_acl = directory_has_default_acl_fsp(parent_dir_fname->fsp)))
4135 unx_mode = (0777 & lp_create_mask(SNUM(conn)));
4138 DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o, "
4139 "access_mask = 0x%x, open_access_mask = 0x%x\n",
4140 (unsigned int)flags, (unsigned int)flags2,
4141 (unsigned int)unx_mode, (unsigned int)access_mask,
4142 (unsigned int)open_access_mask));
4144 fsp_open = open_file(req,
4145 parent_dir_fname->fsp,
4154 if (NT_STATUS_EQUAL(fsp_open, NT_STATUS_NETWORK_BUSY)) {
4155 if (file_existed && S_ISFIFO(fsp->fsp_name->st.st_ex_mode)) {
4156 DEBUG(10, ("FIFO busy\n"));
4157 return NT_STATUS_NETWORK_BUSY;
4160 DEBUG(10, ("Internal open busy\n"));
4161 return NT_STATUS_NETWORK_BUSY;
4164 * This handles the kernel oplock case:
4166 * the file has an active kernel oplock and the open() returned
4167 * EWOULDBLOCK/EAGAIN which maps to NETWORK_BUSY.
4169 * "Samba locking.tdb oplocks" are handled below after acquiring
4170 * the sharemode lock with get_share_mode_lock().
4175 if (NT_STATUS_EQUAL(fsp_open, NT_STATUS_RETRY)) {
4177 * EINTR from the open(2) syscall. Just setup a retry
4178 * in a bit. We can't use the sys_write() tight retry
4179 * loop here, as we might have to actually deal with
4180 * lease-break signals to avoid a deadlock.
4187 * Retry once a second. If there's a share_mode_lock
4188 * around, also wait for it in case it was smbd
4189 * holding that kernel oplock that can quickly tell us
4190 * the oplock got removed.
4196 timeval_set(OPLOCK_BREAK_TIMEOUT*2, 0),
4199 return NT_STATUS_SHARING_VIOLATION;
4202 if (!NT_STATUS_IS_OK(fsp_open)) {
4203 bool wait_for_aio = NT_STATUS_EQUAL(
4204 fsp_open, NT_STATUS_MORE_PROCESSING_REQUIRED);
4206 schedule_async_open(req);
4211 if (new_file_created) {
4213 * As we atomically create using O_CREAT|O_EXCL,
4214 * then if new_file_created is true, then
4215 * file_existed *MUST* have been false (even
4216 * if the file was previously detected as being
4219 file_existed = false;
4222 if (file_existed && !check_same_dev_ino(&saved_stat, &smb_fname->st)) {
4224 * The file did exist, but some other (local or NFS)
4225 * process either renamed/unlinked and re-created the
4226 * file with different dev/ino after we walked the path,
4227 * but before we did the open. We could retry the
4228 * open but it's a rare enough case it's easier to
4229 * just fail the open to prevent creating any problems
4230 * in the open file db having the wrong dev/ino key.
4233 DBG_WARNING("file %s - dev/ino mismatch. "
4234 "Old (dev=%ju, ino=%ju). "
4235 "New (dev=%ju, ino=%ju). Failing open "
4236 "with NT_STATUS_ACCESS_DENIED.\n",
4237 smb_fname_str_dbg(smb_fname),
4238 (uintmax_t)saved_stat.st_ex_dev,
4239 (uintmax_t)saved_stat.st_ex_ino,
4240 (uintmax_t)smb_fname->st.st_ex_dev,
4241 (uintmax_t)smb_fname->st.st_ex_ino);
4242 return NT_STATUS_ACCESS_DENIED;
4245 old_write_time = smb_fname->st.st_ex_mtime;
4248 * Deal with the race condition where two smbd's detect the
4249 * file doesn't exist and do the create at the same time. One
4250 * of them will win and set a share mode, the other (ie. this
4251 * one) should check if the requested share mode for this
4252 * create is allowed.
4256 * Now the file exists and fsp is successfully opened,
4257 * fsp->dev and fsp->inode are valid and should replace the
4258 * dev=0,inode=0 from a non existent file. Spotted by
4259 * Nadav Danieli <nadavd@exanet.com>. JRA.
4262 if (new_file_created) {
4263 info = FILE_WAS_CREATED;
4265 if (flags2 & O_TRUNC) {
4266 info = FILE_WAS_OVERWRITTEN;
4268 info = FILE_WAS_OPENED;
4273 * If we created a new file, overwrite an existing one
4274 * or going to delete it later, we should keep
4275 * the share_mode_lock (g_lock) until we call
4276 * share_mode_entry_prepare_unlock()
4278 if (info != FILE_WAS_OPENED) {
4280 } else if (create_options & FILE_DELETE_ON_CLOSE) {
4284 lck_state = (struct open_ntcreate_lock_state) {
4286 .object_type = "file",
4288 .create_disposition = create_disposition,
4289 .access_mask = access_mask,
4290 .share_access = share_access,
4291 .oplock_request = oplock_request,
4293 .first_open_attempt = first_open_attempt,
4294 .keep_locked = keep_locked,
4297 status = share_mode_entry_prepare_lock_add(&lck_state.prepare_state,
4302 open_ntcreate_lock_add_entry,
4304 if (!NT_STATUS_IS_OK(status)) {
4305 DBG_ERR("share_mode_entry_prepare_lock_add() failed for %s - %s\n",
4306 smb_fname_str_dbg(smb_fname), nt_errstr(status));
4311 status = lck_state.status;
4312 if (!NT_STATUS_IS_OK(status)) {
4318 * From here we need to use 'goto unlock;' instead of return !!!
4321 if (fsp->oplock_type != NO_OPLOCK && fsp->oplock_type != LEASE_OPLOCK) {
4323 * Now ask for kernel oplocks
4324 * and cleanup on failure.
4326 status = set_file_oplock(fsp);
4327 if (!NT_STATUS_IS_OK(status)) {
4329 * Could not get the kernel oplock
4331 lck_state.cleanup_fn =
4332 open_ntcreate_lock_cleanup_oplock;
4333 fsp->oplock_type = NO_OPLOCK;
4337 /* Should we atomically (to the client at least) truncate ? */
4338 if ((!new_file_created) &&
4339 (flags2 & O_TRUNC) &&
4340 (S_ISREG(fsp->fsp_name->st.st_ex_mode))) {
4343 ret = SMB_VFS_FTRUNCATE(fsp, 0);
4345 status = map_nt_error_from_unix(errno);
4346 lck_state.cleanup_fn =
4347 open_ntcreate_lock_cleanup_entry;
4350 notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
4351 FILE_NOTIFY_CHANGE_SIZE
4352 | FILE_NOTIFY_CHANGE_ATTRIBUTES,
4353 fsp->fsp_name->base_name);
4357 * We have the share entry *locked*.....
4360 /* Delete streams if create_disposition requires it */
4361 if (!new_file_created &&
4362 clear_ads(create_disposition) &&
4363 !fsp_is_alternate_stream(fsp)) {
4364 status = delete_all_streams(conn, smb_fname);
4365 if (!NT_STATUS_IS_OK(status)) {
4366 lck_state.cleanup_fn =
4367 open_ntcreate_lock_cleanup_entry;
4372 if (!fsp->fsp_flags.is_pathref &&
4373 fsp_get_io_fd(fsp) != -1 &&
4374 lp_kernel_share_modes(SNUM(conn)))
4378 * Beware: streams implementing VFS modules may
4379 * implement streams in a way that fsp will have the
4380 * basefile open in the fsp fd, so lacking a distinct
4381 * fd for the stream the file-system sharemode will
4382 * apply on the basefile which is wrong. The actual
4383 * check is deferred to the VFS module implementing
4384 * the file-system sharemode call.
4386 ret = SMB_VFS_FILESYSTEM_SHAREMODE(fsp,
4390 status = NT_STATUS_SHARING_VIOLATION;
4391 lck_state.cleanup_fn =
4392 open_ntcreate_lock_cleanup_entry;
4396 fsp->fsp_flags.kernel_share_modes_taken = true;
4400 * At this point onwards, we can guarantee that the share entry
4401 * is locked, whether we created the file or not, and that the
4402 * deny mode is compatible with all current opens.
4406 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
4407 * but we don't have to store this - just ignore it on access check.
4409 if (conn->sconn->using_smb2) {
4411 * SMB2 doesn't return it (according to Microsoft tests).
4412 * Test Case: TestSuite_ScenarioNo009GrantedAccessTestS0
4413 * File created with access = 0x7 (Read, Write, Delete)
4414 * Query Info on file returns 0x87 (Read, Write, Delete, Read Attributes)
4416 fsp->access_mask = access_mask;
4418 /* But SMB1 does. */
4419 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
4426 /* Handle strange delete on close create semantics. */
4427 if (create_options & FILE_DELETE_ON_CLOSE) {
4428 if (!new_file_created) {
4429 status = can_set_delete_on_close(fsp,
4430 existing_dos_attributes);
4432 if (!NT_STATUS_IS_OK(status)) {
4433 /* Remember to delete the mode we just added. */
4434 lck_state.cleanup_fn =
4435 open_ntcreate_lock_cleanup_entry;
4439 /* Note that here we set the *initial* delete on close flag,
4440 not the regular one. The magic gets handled in close. */
4441 fsp->fsp_flags.initial_delete_on_close = true;
4444 if (info != FILE_WAS_OPENED) {
4445 /* Overwritten files should be initially set as archive */
4446 if ((info == FILE_WAS_OVERWRITTEN && lp_map_archive(SNUM(conn))) ||
4447 lp_store_dos_attributes(SNUM(conn))) {
4448 (void)fdos_mode(fsp);
4450 if (file_set_dosmode(conn, smb_fname,
4451 new_dos_attributes | FILE_ATTRIBUTE_ARCHIVE,
4452 parent_dir_fname, true) == 0) {
4453 unx_mode = smb_fname->st.st_ex_mode;
4459 /* Determine sparse flag. */
4461 /* POSIX opens are sparse by default. */
4462 fsp->fsp_flags.is_sparse = true;
4464 fsp->fsp_flags.is_sparse =
4465 (existing_dos_attributes & FILE_ATTRIBUTE_SPARSE);
4469 * Take care of inherited ACLs on created files - if default ACL not
4473 if (!posix_open && new_file_created && !def_acl) {
4474 if (unx_mode != smb_fname->st.st_ex_mode) {
4475 int ret = SMB_VFS_FCHMOD(fsp, unx_mode);
4477 DBG_INFO("failed to reset "
4478 "attributes of file %s to 0%o\n",
4479 smb_fname_str_dbg(smb_fname),
4480 (unsigned int)unx_mode);
4484 } else if (new_unx_mode) {
4486 * We only get here in the case of:
4488 * a). Not a POSIX open.
4489 * b). File already existed.
4490 * c). File was overwritten.
4491 * d). Requested DOS attributes didn't match
4492 * the DOS attributes on the existing file.
4494 * In that case new_unx_mode has been set
4495 * equal to the calculated mode (including
4496 * possible inheritance of the mode from the
4497 * containing directory).
4499 * Note this mode was calculated with the
4500 * DOS attribute FILE_ATTRIBUTE_ARCHIVE added,
4501 * so the mode change here is suitable for
4502 * an overwritten file.
4505 if (new_unx_mode != smb_fname->st.st_ex_mode) {
4506 int ret = SMB_VFS_FCHMOD(fsp, new_unx_mode);
4508 DBG_INFO("failed to reset "
4509 "attributes of file %s to 0%o\n",
4510 smb_fname_str_dbg(smb_fname),
4511 (unsigned int)new_unx_mode);
4517 * Deal with other opens having a modified write time.
4519 if (fsp_getinfo_ask_sharemode(fsp) &&
4520 !is_omit_timespec(&lck_state.write_time))
4522 update_stat_ex_mtime(&fsp->fsp_name->st, lck_state.write_time);
4525 status = NT_STATUS_OK;
4528 ulstatus = share_mode_entry_prepare_unlock(&lck_state.prepare_state,
4529 lck_state.cleanup_fn,
4531 if (!NT_STATUS_IS_OK(ulstatus)) {
4532 DBG_ERR("share_mode_entry_prepare_unlock() failed for %s - %s\n",
4533 smb_fname_str_dbg(smb_fname), nt_errstr(ulstatus));
4534 smb_panic("share_mode_entry_prepare_unlock() failed!");
4537 if (!NT_STATUS_IS_OK(status)) {
4542 return NT_STATUS_OK;
4545 static NTSTATUS mkdir_internal(connection_struct *conn,
4546 struct smb_filename *parent_dir_fname, /* parent. */
4547 struct smb_filename *smb_fname_atname, /* atname relative to parent. */
4548 struct smb_filename *smb_dname, /* full pathname from root of share. */
4549 uint32_t file_attributes,
4550 struct files_struct *fsp)
4552 const struct loadparm_substitution *lp_sub =
4553 loadparm_s3_global_substitution();
4556 bool posix_open = false;
4557 bool need_re_stat = false;
4558 uint32_t access_mask = SEC_DIR_ADD_SUBDIR;
4559 struct vfs_open_how how = { .flags = O_RDONLY|O_DIRECTORY, };
4562 if (!CAN_WRITE(conn) || (access_mask & ~(conn->share_access))) {
4563 DEBUG(5,("mkdir_internal: failing share access "
4564 "%s\n", lp_servicename(talloc_tos(), lp_sub, SNUM(conn))));
4565 return NT_STATUS_ACCESS_DENIED;
4568 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
4570 mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
4572 mode = unix_mode(conn,
4573 FILE_ATTRIBUTE_DIRECTORY,
4575 parent_dir_fname->fsp);
4578 status = check_parent_access_fsp(parent_dir_fname->fsp, access_mask);
4579 if(!NT_STATUS_IS_OK(status)) {
4580 DBG_INFO("check_parent_access_fsp "
4581 "on directory %s for path %s returned %s\n",
4582 smb_fname_str_dbg(parent_dir_fname),
4583 smb_dname->base_name,
4588 if (lp_inherit_acls(SNUM(conn))) {
4589 if (directory_has_default_acl_fsp(parent_dir_fname->fsp)) {
4590 mode = (0777 & lp_directory_mask(SNUM(conn)));
4594 ret = SMB_VFS_MKDIRAT(conn,
4595 parent_dir_fname->fsp,
4599 return map_nt_error_from_unix(errno);
4603 * Make this a pathref fsp for now. open_directory() will reopen as a
4606 fsp->fsp_flags.is_pathref = true;
4608 status = fd_openat(parent_dir_fname->fsp, smb_fname_atname, fsp, &how);
4609 if (!NT_STATUS_IS_OK(status)) {
4613 /* Ensure we're checking for a symlink here.... */
4614 /* We don't want to get caught by a symlink racer. */
4616 status = vfs_stat_fsp(fsp);
4617 if (!NT_STATUS_IS_OK(status)) {
4618 DEBUG(2, ("Could not stat directory '%s' just created: %s\n",
4619 smb_fname_str_dbg(smb_dname), nt_errstr(status)));
4623 if (!S_ISDIR(smb_dname->st.st_ex_mode)) {
4624 DEBUG(0, ("Directory '%s' just created is not a directory !\n",
4625 smb_fname_str_dbg(smb_dname)));
4626 return NT_STATUS_NOT_A_DIRECTORY;
4629 if (lp_store_dos_attributes(SNUM(conn)) && !posix_open) {
4630 file_set_dosmode(conn,
4632 file_attributes | FILE_ATTRIBUTE_DIRECTORY,
4637 if (lp_inherit_permissions(SNUM(conn))) {
4638 inherit_access_posix_acl(conn, parent_dir_fname->fsp,
4640 need_re_stat = true;
4645 * Check if high bits should have been set,
4646 * then (if bits are missing): add them.
4647 * Consider bits automagically set by UNIX, i.e. SGID bit from parent
4650 if ((mode & ~(S_IRWXU|S_IRWXG|S_IRWXO)) &&
4651 (mode & ~smb_dname->st.st_ex_mode)) {
4653 (smb_dname->st.st_ex_mode |
4654 (mode & ~smb_dname->st.st_ex_mode)));
4655 need_re_stat = true;
4659 /* Change the owner if required. */
4660 if (lp_inherit_owner(SNUM(conn)) != INHERIT_OWNER_NO) {
4661 change_dir_owner_to_parent_fsp(parent_dir_fname->fsp,
4663 need_re_stat = true;
4667 status = vfs_stat_fsp(fsp);
4668 if (!NT_STATUS_IS_OK(status)) {
4669 DEBUG(2, ("Could not stat directory '%s' just created: %s\n",
4670 smb_fname_str_dbg(smb_dname), nt_errstr(status)));
4675 notify_fname(conn, NOTIFY_ACTION_ADDED, FILE_NOTIFY_CHANGE_DIR_NAME,
4676 smb_dname->base_name);
4678 return NT_STATUS_OK;
4681 /****************************************************************************
4682 Open a directory from an NT SMB call.
4683 ****************************************************************************/
4685 static NTSTATUS open_directory(connection_struct *conn,
4686 struct smb_request *req,
4687 uint32_t access_mask,
4688 uint32_t share_access,
4689 uint32_t create_disposition,
4690 uint32_t create_options,
4691 uint32_t file_attributes,
4692 struct smb_filename *parent_dir_fname,
4693 struct smb_filename *smb_fname_atname,
4695 struct files_struct *fsp)
4697 struct smb_filename *smb_dname = fsp->fsp_name;
4698 bool dir_existed = VALID_STAT(smb_dname->st);
4699 struct open_ntcreate_lock_state lck_state = {};
4700 bool keep_locked = false;
4702 struct timespec mtimespec;
4704 uint32_t need_fd_access;
4707 if (is_ntfs_stream_smb_fname(smb_dname)) {
4708 DEBUG(2, ("open_directory: %s is a stream name!\n",
4709 smb_fname_str_dbg(smb_dname)));
4710 return NT_STATUS_NOT_A_DIRECTORY;
4713 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS)) {
4714 /* Ensure we have a directory attribute. */
4715 file_attributes |= FILE_ATTRIBUTE_DIRECTORY;
4718 DBG_INFO("opening directory %s, access_mask = 0x%"PRIx32", "
4719 "share_access = 0x%"PRIx32" create_options = 0x%"PRIx32", "
4720 "create_disposition = 0x%"PRIx32", "
4721 "file_attributes = 0x%"PRIx32"\n",
4722 smb_fname_str_dbg(smb_dname),
4729 status = smbd_calculate_access_mask_fsp(parent_dir_fname->fsp,
4734 if (!NT_STATUS_IS_OK(status)) {
4735 DBG_DEBUG("smbd_calculate_access_mask_fsp "
4736 "on file %s returned %s\n",
4737 smb_fname_str_dbg(smb_dname),
4742 if ((access_mask & SEC_FLAG_SYSTEM_SECURITY) &&
4743 !security_token_has_privilege(get_current_nttok(conn),
4744 SEC_PRIV_SECURITY)) {
4745 DEBUG(10, ("open_directory: open on %s "
4746 "failed - SEC_FLAG_SYSTEM_SECURITY denied.\n",
4747 smb_fname_str_dbg(smb_dname)));
4748 return NT_STATUS_PRIVILEGE_NOT_HELD;
4751 switch( create_disposition ) {
4755 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4758 info = FILE_WAS_OPENED;
4763 /* If directory exists error. If directory doesn't
4767 status = NT_STATUS_OBJECT_NAME_COLLISION;
4768 DEBUG(2, ("open_directory: unable to create "
4769 "%s. Error was %s\n",
4770 smb_fname_str_dbg(smb_dname),
4771 nt_errstr(status)));
4775 if (smb_fname_atname->twrp != 0) {
4776 return NT_STATUS_MEDIA_WRITE_PROTECTED;
4779 status = mkdir_internal(conn,
4786 if (!NT_STATUS_IS_OK(status)) {
4787 DEBUG(2, ("open_directory: unable to create "
4788 "%s. Error was %s\n",
4789 smb_fname_str_dbg(smb_dname),
4790 nt_errstr(status)));
4794 info = FILE_WAS_CREATED;
4799 * If directory exists open. If directory doesn't
4804 status = NT_STATUS_OK;
4805 info = FILE_WAS_OPENED;
4807 if (smb_fname_atname->twrp != 0) {
4808 return NT_STATUS_MEDIA_WRITE_PROTECTED;
4810 status = mkdir_internal(conn,
4817 if (NT_STATUS_IS_OK(status)) {
4818 info = FILE_WAS_CREATED;
4820 /* Cope with create race. */
4821 if (!NT_STATUS_EQUAL(status,
4822 NT_STATUS_OBJECT_NAME_COLLISION)) {
4823 DEBUG(2, ("open_directory: unable to create "
4824 "%s. Error was %s\n",
4825 smb_fname_str_dbg(smb_dname),
4826 nt_errstr(status)));
4831 * If mkdir_internal() returned
4832 * NT_STATUS_OBJECT_NAME_COLLISION
4833 * we still must lstat the path.
4836 if (SMB_VFS_LSTAT(conn, smb_dname)
4838 DEBUG(2, ("Could not stat "
4839 "directory '%s' just "
4844 return map_nt_error_from_unix(
4848 info = FILE_WAS_OPENED;
4854 case FILE_SUPERSEDE:
4855 case FILE_OVERWRITE:
4856 case FILE_OVERWRITE_IF:
4858 DEBUG(5,("open_directory: invalid create_disposition "
4859 "0x%x for directory %s\n",
4860 (unsigned int)create_disposition,
4861 smb_fname_str_dbg(smb_dname)));
4862 return NT_STATUS_INVALID_PARAMETER;
4865 if(!S_ISDIR(smb_dname->st.st_ex_mode)) {
4866 DEBUG(5,("open_directory: %s is not a directory !\n",
4867 smb_fname_str_dbg(smb_dname)));
4868 return NT_STATUS_NOT_A_DIRECTORY;
4872 * Setup the files_struct for it.
4875 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_dname->st);
4876 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
4877 fsp->file_pid = req ? req->smbpid : 0;
4878 fsp->fsp_flags.can_lock = false;
4879 fsp->fsp_flags.can_read = false;
4880 fsp->fsp_flags.can_write = false;
4882 fh_set_private_options(fsp->fh, 0);
4884 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
4886 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
4887 fsp->print_file = NULL;
4888 fsp->fsp_flags.modified = false;
4889 fsp->oplock_type = NO_OPLOCK;
4890 fsp->sent_oplock_break = NO_BREAK_SENT;
4891 fsp->fsp_flags.is_directory = true;
4892 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
4893 fsp->posix_flags |= FSP_POSIX_FLAGS_ALL;
4896 /* Don't store old timestamps for directory
4897 handles in the internal database. We don't
4898 update them in there if new objects
4899 are created in the directory. Currently
4900 we only update timestamps on file writes.
4903 mtimespec = make_omit_timespec();
4906 * Obviously for FILE_LIST_DIRECTORY we need to reopen to get an fd
4907 * usable for reading a directory. SMB2_FLUSH may be called on
4908 * directories opened with FILE_ADD_FILE and FILE_ADD_SUBDIRECTORY so
4909 * for those we need to reopen as well.
4912 FILE_LIST_DIRECTORY |
4914 FILE_ADD_SUBDIRECTORY;
4916 if (access_mask & need_fd_access) {
4917 status = reopen_from_fsp(
4921 O_RDONLY | O_DIRECTORY,
4924 if (!NT_STATUS_IS_OK(status)) {
4925 DBG_INFO("Could not open fd for [%s]: %s\n",
4926 smb_fname_str_dbg(smb_dname),
4932 status = vfs_stat_fsp(fsp);
4933 if (!NT_STATUS_IS_OK(status)) {
4938 if(!S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
4939 DEBUG(5,("open_directory: %s is not a directory !\n",
4940 smb_fname_str_dbg(smb_dname)));
4942 return NT_STATUS_NOT_A_DIRECTORY;
4945 /* Ensure there was no race condition. We need to check
4946 * dev/inode but not permissions, as these can change
4948 if (!check_same_dev_ino(&smb_dname->st, &fsp->fsp_name->st)) {
4949 DEBUG(5,("open_directory: stat struct differs for "
4951 smb_fname_str_dbg(smb_dname)));
4953 return NT_STATUS_ACCESS_DENIED;
4956 if (info == FILE_WAS_OPENED) {
4957 status = smbd_check_access_rights_fsp(parent_dir_fname->fsp,
4961 if (!NT_STATUS_IS_OK(status)) {
4962 DBG_DEBUG("smbd_check_access_rights_fsp on "
4963 "file %s failed with %s\n",
4972 * If we created a new directory or going to delete it later,
4973 * we should keep * the share_mode_lock (g_lock) until we call
4974 * share_mode_entry_prepare_unlock()
4976 if (info != FILE_WAS_OPENED) {
4978 } else if (create_options & FILE_DELETE_ON_CLOSE) {
4982 lck_state = (struct open_ntcreate_lock_state) {
4984 .object_type = "directory",
4986 .create_disposition = create_disposition,
4987 .access_mask = access_mask,
4988 .share_access = share_access,
4989 .oplock_request = NO_OPLOCK,
4991 .first_open_attempt = true,
4992 .keep_locked = keep_locked,
4995 status = share_mode_entry_prepare_lock_add(&lck_state.prepare_state,
5000 open_ntcreate_lock_add_entry,
5002 if (!NT_STATUS_IS_OK(status)) {
5003 DBG_ERR("share_mode_entry_prepare_lock_add() failed for %s - %s\n",
5004 smb_fname_str_dbg(smb_dname), nt_errstr(status));
5009 status = lck_state.status;
5010 if (!NT_STATUS_IS_OK(status)) {
5016 * From here we need to use 'goto unlock;' instead of return !!!
5019 /* For directories the delete on close bit at open time seems
5020 always to be honored on close... See test 19 in Samba4 BASE-DELETE. */
5021 if (create_options & FILE_DELETE_ON_CLOSE) {
5022 status = can_set_delete_on_close(fsp, 0);
5023 if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
5024 lck_state.cleanup_fn =
5025 open_ntcreate_lock_cleanup_entry;
5029 if (NT_STATUS_IS_OK(status)) {
5030 /* Note that here we set the *initial* delete on close flag,
5031 not the regular one. The magic gets handled in close. */
5032 fsp->fsp_flags.initial_delete_on_close = true;
5037 * Deal with other opens having a modified write time.
5039 if (!is_omit_timespec(&lck_state.write_time)) {
5040 update_stat_ex_mtime(&fsp->fsp_name->st, lck_state.write_time);
5047 status = NT_STATUS_OK;
5050 ulstatus = share_mode_entry_prepare_unlock(&lck_state.prepare_state,
5051 lck_state.cleanup_fn,
5053 if (!NT_STATUS_IS_OK(ulstatus)) {
5054 DBG_ERR("share_mode_entry_prepare_unlock() failed for %s - %s\n",
5055 smb_fname_str_dbg(smb_dname), nt_errstr(ulstatus));
5056 smb_panic("share_mode_entry_prepare_unlock() failed!");
5059 if (!NT_STATUS_IS_OK(status)) {
5064 return NT_STATUS_OK;
5067 NTSTATUS create_directory(connection_struct *conn,
5068 struct smb_request *req,
5069 struct files_struct *dirfsp,
5070 struct smb_filename *smb_dname)
5075 status = SMB_VFS_CREATE_FILE(
5078 dirfsp, /* dirfsp */
5079 smb_dname, /* fname */
5080 FILE_READ_ATTRIBUTES, /* access_mask */
5081 FILE_SHARE_NONE, /* share_access */
5082 FILE_CREATE, /* create_disposition*/
5083 FILE_DIRECTORY_FILE, /* create_options */
5084 FILE_ATTRIBUTE_DIRECTORY, /* file_attributes */
5085 0, /* oplock_request */
5087 0, /* allocation_size */
5088 0, /* private_flags */
5093 NULL, NULL); /* create context */
5095 if (NT_STATUS_IS_OK(status)) {
5096 close_file_free(req, &fsp, NORMAL_CLOSE);
5102 /****************************************************************************
5103 Receive notification that one of our open files has been renamed by another
5105 ****************************************************************************/
5107 void msg_file_was_renamed(struct messaging_context *msg_ctx,
5110 struct server_id src,
5113 struct file_rename_message *msg = NULL;
5114 enum ndr_err_code ndr_err;
5116 struct smb_filename *smb_fname = NULL;
5117 struct smbd_server_connection *sconn =
5118 talloc_get_type_abort(private_data,
5119 struct smbd_server_connection);
5121 msg = talloc(talloc_tos(), struct file_rename_message);
5123 DBG_WARNING("talloc failed\n");
5127 ndr_err = ndr_pull_struct_blob_all(
5131 (ndr_pull_flags_fn_t)ndr_pull_file_rename_message);
5132 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
5133 DBG_DEBUG("ndr_pull_oplock_break_message failed: %s\n",
5134 ndr_errstr(ndr_err));
5137 if (DEBUGLEVEL >= 10) {
5138 struct server_id_buf buf;
5139 DBG_DEBUG("Got rename message from %s\n",
5140 server_id_str_buf(src, &buf));
5141 NDR_PRINT_DEBUG(file_rename_message, msg);
5144 /* stream_name must always be NULL if there is no stream. */
5145 if ((msg->stream_name != NULL) && (msg->stream_name[0] == '\0')) {
5146 msg->stream_name = NULL;
5149 smb_fname = synthetic_smb_fname(msg,
5155 if (smb_fname == NULL) {
5156 DBG_DEBUG("synthetic_smb_fname failed\n");
5160 fsp = file_find_dif(sconn, msg->id, msg->share_file_id);
5162 DBG_DEBUG("fsp not found\n");
5166 if (strcmp(fsp->conn->connectpath, msg->servicepath) == 0) {
5167 SMB_STRUCT_STAT fsp_orig_sbuf;
5169 DBG_DEBUG("renaming file %s from %s -> %s\n",
5172 smb_fname_str_dbg(smb_fname));
5175 * The incoming smb_fname here has an
5176 * invalid stat struct from synthetic_smb_fname()
5178 * Preserve the existing stat from the
5179 * open fsp after fsp_set_smb_fname()
5180 * overwrites with the invalid stat.
5182 * (We could just copy this into
5183 * smb_fname->st, but keep this code
5184 * identical to the fix in rename_open_files()
5187 * We will do an fstat before returning
5188 * any of this metadata to the client anyway.
5190 fsp_orig_sbuf = fsp->fsp_name->st;
5191 status = fsp_set_smb_fname(fsp, smb_fname);
5192 if (!NT_STATUS_IS_OK(status)) {
5193 DBG_DEBUG("fsp_set_smb_fname failed: %s\n",
5196 fsp->fsp_name->st = fsp_orig_sbuf;
5200 * Now we have the complete path we can work out if
5201 * this is actually within this share and adjust
5202 * newname accordingly.
5204 DBG_DEBUG("share mismatch (sharepath %s not sharepath %s) "
5205 "%s from %s -> %s\n",
5206 fsp->conn->connectpath,
5210 smb_fname_str_dbg(smb_fname));
5217 * If a main file is opened for delete, all streams need to be checked for
5218 * !FILE_SHARE_DELETE. Do this by opening with DELETE_ACCESS.
5219 * If that works, delete them all by setting the delete on close and close.
5222 static NTSTATUS open_streams_for_delete(connection_struct *conn,
5223 const struct smb_filename *smb_fname)
5225 struct stream_struct *stream_info = NULL;
5226 files_struct **streams = NULL;
5228 unsigned int i, num_streams = 0;
5229 TALLOC_CTX *frame = talloc_stackframe();
5230 const struct smb_filename *pathref = NULL;
5233 if (smb_fname->fsp == NULL) {
5234 struct smb_filename *tmp = NULL;
5235 status = synthetic_pathref(frame,
5237 smb_fname->base_name,
5243 if (!NT_STATUS_IS_OK(status)) {
5244 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
5245 || NT_STATUS_EQUAL(status,
5246 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
5247 DBG_DEBUG("no streams around\n");
5249 return NT_STATUS_OK;
5251 DBG_DEBUG("synthetic_pathref failed: %s\n",
5257 pathref = smb_fname;
5259 status = vfs_fstreaminfo(pathref->fsp, talloc_tos(),
5260 &num_streams, &stream_info);
5262 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
5263 || NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
5264 DEBUG(10, ("no streams around\n"));
5266 return NT_STATUS_OK;
5269 if (!NT_STATUS_IS_OK(status)) {
5270 DEBUG(10, ("vfs_fstreaminfo failed: %s\n",
5271 nt_errstr(status)));
5275 DEBUG(10, ("open_streams_for_delete found %d streams\n",
5278 if (num_streams == 0) {
5280 return NT_STATUS_OK;
5283 streams = talloc_array(talloc_tos(), files_struct *, num_streams);
5284 if (streams == NULL) {
5285 DEBUG(0, ("talloc failed\n"));
5286 status = NT_STATUS_NO_MEMORY;
5290 for (i=0; i<num_streams; i++) {
5291 struct smb_filename *smb_fname_cp;
5293 if (strequal(stream_info[i].name, "::$DATA")) {
5298 smb_fname_cp = synthetic_smb_fname(talloc_tos(),
5299 smb_fname->base_name,
5300 stream_info[i].name,
5304 ~SMB_FILENAME_POSIX_PATH));
5305 if (smb_fname_cp == NULL) {
5306 status = NT_STATUS_NO_MEMORY;
5310 status = openat_pathref_fsp(conn->cwd_fsp, smb_fname_cp);
5311 if (!NT_STATUS_IS_OK(status)) {
5312 DBG_DEBUG("Unable to open stream [%s]: %s\n",
5313 smb_fname_str_dbg(smb_fname_cp),
5315 TALLOC_FREE(smb_fname_cp);
5319 status = SMB_VFS_CREATE_FILE(
5323 smb_fname_cp, /* fname */
5324 DELETE_ACCESS, /* access_mask */
5325 (FILE_SHARE_READ | /* share_access */
5326 FILE_SHARE_WRITE | FILE_SHARE_DELETE),
5327 FILE_OPEN, /* create_disposition*/
5328 0, /* create_options */
5329 FILE_ATTRIBUTE_NORMAL, /* file_attributes */
5330 0, /* oplock_request */
5332 0, /* allocation_size */
5333 0, /* private_flags */
5336 &streams[i], /* result */
5338 NULL, NULL); /* create context */
5340 if (!NT_STATUS_IS_OK(status)) {
5341 DEBUG(10, ("Could not open stream %s: %s\n",
5342 smb_fname_str_dbg(smb_fname_cp),
5343 nt_errstr(status)));
5345 TALLOC_FREE(smb_fname_cp);
5348 TALLOC_FREE(smb_fname_cp);
5352 * don't touch the variable "status" beyond this point :-)
5355 for (j = i-1 ; j >= 0; j--) {
5356 if (streams[j] == NULL) {
5360 DEBUG(10, ("Closing stream # %d, %s\n", j,
5361 fsp_str_dbg(streams[j])));
5362 close_file_free(NULL, &streams[j], NORMAL_CLOSE);
5370 /*********************************************************************
5371 Create a default ACL by inheriting from the parent. If no inheritance
5372 from the parent available, don't set anything. This will leave the actual
5373 permissions the new file or directory already got from the filesystem
5374 as the NT ACL when read.
5375 *********************************************************************/
5377 static NTSTATUS inherit_new_acl(files_struct *dirfsp, files_struct *fsp)
5379 TALLOC_CTX *frame = talloc_stackframe();
5380 struct security_descriptor *parent_desc = NULL;
5381 NTSTATUS status = NT_STATUS_OK;
5382 struct security_descriptor *psd = NULL;
5383 const struct dom_sid *owner_sid = NULL;
5384 const struct dom_sid *group_sid = NULL;
5385 uint32_t security_info_sent = (SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL);
5386 struct security_token *token = fsp->conn->session_info->security_token;
5387 bool inherit_owner =
5388 (lp_inherit_owner(SNUM(fsp->conn)) == INHERIT_OWNER_WINDOWS_AND_UNIX);
5389 bool inheritable_components = false;
5390 bool try_builtin_administrators = false;
5391 const struct dom_sid *BA_U_sid = NULL;
5392 const struct dom_sid *BA_G_sid = NULL;
5393 bool try_system = false;
5394 const struct dom_sid *SY_U_sid = NULL;
5395 const struct dom_sid *SY_G_sid = NULL;
5399 status = SMB_VFS_FGET_NT_ACL(dirfsp,
5400 (SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL),
5403 if (!NT_STATUS_IS_OK(status)) {
5408 inheritable_components = sd_has_inheritable_components(parent_desc,
5409 fsp->fsp_flags.is_directory);
5411 if (!inheritable_components && !inherit_owner) {
5413 /* Nothing to inherit and not setting owner. */
5414 return NT_STATUS_OK;
5417 /* Create an inherited descriptor from the parent. */
5419 if (DEBUGLEVEL >= 10) {
5420 DEBUG(10,("inherit_new_acl: parent acl for %s is:\n",
5421 fsp_str_dbg(fsp) ));
5422 NDR_PRINT_DEBUG(security_descriptor, parent_desc);
5425 /* Inherit from parent descriptor if "inherit owner" set. */
5426 if (inherit_owner) {
5427 owner_sid = parent_desc->owner_sid;
5428 group_sid = parent_desc->group_sid;
5431 if (owner_sid == NULL) {
5432 if (security_token_has_builtin_administrators(token)) {
5433 try_builtin_administrators = true;
5434 } else if (security_token_is_system(token)) {
5435 try_builtin_administrators = true;
5440 if (group_sid == NULL &&
5441 token->num_sids == PRIMARY_GROUP_SID_INDEX)
5443 if (security_token_is_system(token)) {
5444 try_builtin_administrators = true;
5449 if (try_builtin_administrators) {
5450 struct unixid ids = { .id = 0 };
5452 ok = sids_to_unixids(&global_sid_Builtin_Administrators, 1, &ids);
5456 BA_U_sid = &global_sid_Builtin_Administrators;
5457 BA_G_sid = &global_sid_Builtin_Administrators;
5460 BA_U_sid = &global_sid_Builtin_Administrators;
5463 BA_G_sid = &global_sid_Builtin_Administrators;
5472 struct unixid ids = { .id = 0 };
5474 ok = sids_to_unixids(&global_sid_System, 1, &ids);
5478 SY_U_sid = &global_sid_System;
5479 SY_G_sid = &global_sid_System;
5482 SY_U_sid = &global_sid_System;
5485 SY_G_sid = &global_sid_System;
5493 if (owner_sid == NULL) {
5494 owner_sid = BA_U_sid;
5497 if (owner_sid == NULL) {
5498 owner_sid = SY_U_sid;
5501 if (group_sid == NULL) {
5502 group_sid = SY_G_sid;
5505 if (try_system && group_sid == NULL) {
5506 group_sid = BA_G_sid;
5509 if (owner_sid == NULL) {
5510 owner_sid = &token->sids[PRIMARY_USER_SID_INDEX];
5512 if (group_sid == NULL) {
5513 if (token->num_sids == PRIMARY_GROUP_SID_INDEX) {
5514 group_sid = &token->sids[PRIMARY_USER_SID_INDEX];
5516 group_sid = &token->sids[PRIMARY_GROUP_SID_INDEX];
5520 status = se_create_child_secdesc(frame,
5526 fsp->fsp_flags.is_directory);
5527 if (!NT_STATUS_IS_OK(status)) {
5532 /* If inheritable_components == false,
5533 se_create_child_secdesc()
5534 creates a security descriptor with a NULL dacl
5535 entry, but with SEC_DESC_DACL_PRESENT. We need
5536 to remove that flag. */
5538 if (!inheritable_components) {
5539 security_info_sent &= ~SECINFO_DACL;
5540 psd->type &= ~SEC_DESC_DACL_PRESENT;
5543 if (DEBUGLEVEL >= 10) {
5544 DEBUG(10,("inherit_new_acl: child acl for %s is:\n",
5545 fsp_str_dbg(fsp) ));
5546 NDR_PRINT_DEBUG(security_descriptor, psd);
5549 if (inherit_owner) {
5550 /* We need to be root to force this. */
5553 status = SMB_VFS_FSET_NT_ACL(metadata_fsp(fsp),
5556 if (inherit_owner) {
5564 * If we already have a lease, it must match the new file id. [MS-SMB2]
5565 * 3.3.5.9.8 speaks about INVALID_PARAMETER if an already used lease key is
5566 * used for a different file name.
5569 struct lease_match_state {
5570 /* Input parameters. */
5571 TALLOC_CTX *mem_ctx;
5572 const char *servicepath;
5573 const struct smb_filename *fname;
5576 /* Return parameters. */
5577 uint32_t num_file_ids;
5578 struct file_id *ids;
5579 NTSTATUS match_status;
5582 /*************************************************************
5583 File doesn't exist but this lease key+guid is already in use.
5585 This is only allowable in the dynamic share case where the
5586 service path must be different.
5588 There is a small race condition here in the multi-connection
5589 case where a client sends two create calls on different connections,
5590 where the file doesn't exist and one smbd creates the leases_db
5591 entry first, but this will get fixed by the multichannel cleanup
5592 when all identical client_guids get handled by a single smbd.
5593 **************************************************************/
5595 static void lease_match_parser_new_file(
5597 const struct leases_db_file *files,
5598 struct lease_match_state *state)
5602 for (i = 0; i < num_files; i++) {
5603 const struct leases_db_file *f = &files[i];
5604 if (strequal(state->servicepath, f->servicepath)) {
5605 state->match_status = NT_STATUS_INVALID_PARAMETER;
5610 /* Dynamic share case. Break leases on all other files. */
5611 state->match_status = leases_db_copy_file_ids(state->mem_ctx,
5615 if (!NT_STATUS_IS_OK(state->match_status)) {
5619 state->num_file_ids = num_files;
5620 state->match_status = NT_STATUS_OPLOCK_NOT_GRANTED;
5624 static void lease_match_parser(
5626 const struct leases_db_file *files,
5629 struct lease_match_state *state =
5630 (struct lease_match_state *)private_data;
5633 if (!state->file_existed) {
5635 * Deal with name mismatch or
5636 * possible dynamic share case separately
5637 * to make code clearer.
5639 lease_match_parser_new_file(num_files,
5646 state->match_status = NT_STATUS_OK;
5648 for (i = 0; i < num_files; i++) {
5649 const struct leases_db_file *f = &files[i];
5651 /* Everything should be the same. */
5652 if (!file_id_equal(&state->id, &f->id)) {
5654 * The client asked for a lease on a
5655 * file that doesn't match the file_id
5658 * Maybe this is a dynamic share, i.e.
5659 * a share where the servicepath is
5660 * different for different users (e.g.
5661 * the [HOMES] share.
5663 * If the servicepath is different, but the requested
5664 * file name + stream name is the same then this is
5665 * a dynamic share, the client is using the same share
5666 * name and doesn't know that the underlying servicepath
5667 * is different. It was expecting a lease on the
5668 * same file. Return NT_STATUS_OPLOCK_NOT_GRANTED
5671 * Otherwise the client has messed up, or is
5672 * testing our error codes, so return
5673 * NT_STATUS_INVALID_PARAMETER.
5675 if (!strequal(f->servicepath, state->servicepath) &&
5676 strequal(f->base_name, state->fname->base_name) &&
5677 strequal(f->stream_name, state->fname->stream_name))
5680 * Name is the same but servicepath is
5681 * different, dynamic share. Break leases.
5683 state->match_status =
5684 NT_STATUS_OPLOCK_NOT_GRANTED;
5686 state->match_status =
5687 NT_STATUS_INVALID_PARAMETER;
5691 if (!strequal(f->servicepath, state->servicepath)) {
5692 state->match_status = NT_STATUS_INVALID_PARAMETER;
5695 if (!strequal(f->base_name, state->fname->base_name)) {
5696 state->match_status = NT_STATUS_INVALID_PARAMETER;
5699 if (!strequal(f->stream_name, state->fname->stream_name)) {
5700 state->match_status = NT_STATUS_INVALID_PARAMETER;
5705 if (NT_STATUS_IS_OK(state->match_status)) {
5707 * Common case - just opening another handle on a
5708 * file on a non-dynamic share.
5713 if (NT_STATUS_EQUAL(state->match_status, NT_STATUS_INVALID_PARAMETER)) {
5714 /* Mismatched path. Error back to client. */
5719 * File id mismatch. Dynamic share case NT_STATUS_OPLOCK_NOT_GRANTED.
5720 * Don't allow leases.
5723 state->match_status = leases_db_copy_file_ids(state->mem_ctx,
5727 if (!NT_STATUS_IS_OK(state->match_status)) {
5731 state->num_file_ids = num_files;
5732 state->match_status = NT_STATUS_OPLOCK_NOT_GRANTED;
5736 struct lease_match_break_state {
5737 struct messaging_context *msg_ctx;
5738 const struct smb2_lease_key *lease_key;
5746 static bool lease_match_break_fn(
5747 struct share_mode_entry *e,
5750 struct lease_match_break_state *state = private_data;
5752 uint32_t e_lease_type = SMB2_LEASE_NONE;
5755 stale = share_entry_stale_pid(e);
5760 equal = smb2_lease_key_equal(&e->lease_key, state->lease_key);
5765 status = leases_db_get(
5769 &e_lease_type, /* current_state */
5770 NULL, /* breaking */
5771 NULL, /* breaking_to_requested */
5772 NULL, /* breaking_to_required */
5773 &state->version, /* lease_version */
5774 &state->epoch); /* epoch */
5775 if (NT_STATUS_IS_OK(status)) {
5776 state->found_lease = true;
5778 DBG_WARNING("Could not find version/epoch: %s\n",
5783 if (e_lease_type == SMB2_LEASE_NONE) {
5786 send_break_message(state->msg_ctx, &state->id, e, SMB2_LEASE_NONE);
5789 * Windows 7 and 8 lease clients are broken in that they will
5790 * not respond to lease break requests whilst waiting for an
5791 * outstanding open request on that lease handle on the same
5792 * TCP connection, due to holding an internal inode lock.
5794 * This means we can't reschedule ourselves here, but must
5795 * return from the create.
5799 * Send the breaks and then return SMB2_LEASE_NONE in the
5800 * lease handle to cause them to acknowledge the lease
5801 * break. Consultation with Microsoft engineering confirmed
5802 * this approach is safe.
5808 static void lease_match_fid_fn(struct share_mode_lock *lck,
5813 ok = share_mode_forall_leases(lck, lease_match_break_fn, private_data);
5815 DBG_DEBUG("share_mode_forall_leases failed\n");
5819 static NTSTATUS lease_match(connection_struct *conn,
5820 struct smb_request *req,
5821 const struct smb2_lease_key *lease_key,
5822 const char *servicepath,
5823 const struct smb_filename *fname,
5824 uint16_t *p_version,
5827 struct smbd_server_connection *sconn = req->sconn;
5828 TALLOC_CTX *tos = talloc_tos();
5829 struct lease_match_state state = {
5831 .servicepath = servicepath,
5833 .match_status = NT_STATUS_OK
5838 state.file_existed = VALID_STAT(fname->st);
5839 if (state.file_existed) {
5840 state.id = vfs_file_id_from_sbuf(conn, &fname->st);
5843 status = leases_db_parse(&sconn->client->global->client_guid,
5844 lease_key, lease_match_parser, &state);
5845 if (!NT_STATUS_IS_OK(status)) {
5847 * Not found or error means okay: We can make the lease pass
5849 return NT_STATUS_OK;
5851 if (!NT_STATUS_EQUAL(state.match_status, NT_STATUS_OPLOCK_NOT_GRANTED)) {
5853 * Anything but NT_STATUS_OPLOCK_NOT_GRANTED, let the caller
5856 return state.match_status;
5859 /* We have to break all existing leases. */
5860 for (i = 0; i < state.num_file_ids; i++) {
5861 struct lease_match_break_state break_state = {
5862 .msg_ctx = conn->sconn->msg_ctx,
5863 .lease_key = lease_key,
5866 if (file_id_equal(&state.ids[i], &state.id)) {
5867 /* Don't need to break our own file. */
5871 break_state.id = state.ids[i];
5873 status = share_mode_do_locked_vfs_denied(break_state.id,
5876 if (!NT_STATUS_IS_OK(status)) {
5877 /* Race condition - file already closed. */
5881 if (break_state.found_lease) {
5882 *p_version = break_state.version;
5883 *p_epoch = break_state.epoch;
5887 * Ensure we don't grant anything more so we
5890 return NT_STATUS_OPLOCK_NOT_GRANTED;
5894 * Wrapper around open_file_ntcreate and open_directory
5897 static NTSTATUS create_file_unixpath(connection_struct *conn,
5898 struct smb_request *req,
5899 struct files_struct *dirfsp,
5900 struct smb_filename *smb_fname,
5901 uint32_t access_mask,
5902 uint32_t share_access,
5903 uint32_t create_disposition,
5904 uint32_t create_options,
5905 uint32_t file_attributes,
5906 uint32_t oplock_request,
5907 const struct smb2_lease *lease,
5908 uint64_t allocation_size,
5909 uint32_t private_flags,
5910 struct security_descriptor *sd,
5911 struct ea_list *ea_list,
5913 files_struct **result,
5916 struct smb2_lease none_lease;
5917 int info = FILE_WAS_OPENED;
5918 files_struct *base_fsp = NULL;
5919 files_struct *fsp = NULL;
5920 bool free_fsp_on_error = false;
5923 struct smb_filename *parent_dir_fname = NULL;
5924 struct smb_filename *smb_fname_atname = NULL;
5926 DBG_DEBUG("access_mask = 0x%"PRIx32" "
5927 "file_attributes = 0x%"PRIx32" "
5928 "share_access = 0x%"PRIx32" "
5929 "create_disposition = 0x%"PRIx32" "
5930 "create_options = 0x%"PRIx32" "
5931 "oplock_request = 0x%"PRIx32" "
5932 "private_flags = 0x%"PRIx32" "
5945 smb_fname_str_dbg(smb_fname));
5947 if (create_options & FILE_OPEN_BY_FILE_ID) {
5948 status = NT_STATUS_NOT_SUPPORTED;
5952 if (create_options & NTCREATEX_OPTIONS_INVALID_PARAM_MASK) {
5953 status = NT_STATUS_INVALID_PARAMETER;
5958 oplock_request |= INTERNAL_OPEN_ONLY;
5961 if (lease != NULL) {
5962 uint16_t epoch = lease->lease_epoch;
5963 uint16_t version = lease->lease_version;
5966 DBG_WARNING("Got lease on internal open\n");
5967 status = NT_STATUS_INTERNAL_ERROR;
5971 status = lease_match(conn,
5978 if (NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) {
5979 /* Dynamic share file. No leases and update epoch... */
5980 none_lease = *lease;
5981 none_lease.lease_state = SMB2_LEASE_NONE;
5982 none_lease.lease_epoch = epoch;
5983 none_lease.lease_version = version;
5984 lease = &none_lease;
5985 } else if (!NT_STATUS_IS_OK(status)) {
5990 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
5991 && (access_mask & DELETE_ACCESS)
5992 && !is_named_stream(smb_fname)) {
5994 * We can't open a file with DELETE access if any of the
5995 * streams is open without FILE_SHARE_DELETE
5997 status = open_streams_for_delete(conn, smb_fname);
5999 if (!NT_STATUS_IS_OK(status)) {
6004 if (access_mask & SEC_FLAG_SYSTEM_SECURITY) {
6007 ok = security_token_has_privilege(get_current_nttok(conn),
6010 DBG_DEBUG("open on %s failed - "
6011 "SEC_FLAG_SYSTEM_SECURITY denied.\n",
6012 smb_fname_str_dbg(smb_fname));
6013 status = NT_STATUS_PRIVILEGE_NOT_HELD;
6017 if (conn->sconn->using_smb2 &&
6018 (access_mask == SEC_FLAG_SYSTEM_SECURITY))
6021 * No other bits set. Windows SMB2 refuses this.
6022 * See smbtorture3 SMB2-SACL test.
6024 * Note this is an SMB2-only behavior,
6025 * smbtorture3 SMB1-SYSTEM-SECURITY already tests
6026 * that SMB1 allows this.
6028 status = NT_STATUS_ACCESS_DENIED;
6034 * Files or directories can't be opened DELETE_ON_CLOSE without
6036 * BUG: https://bugzilla.samba.org/show_bug.cgi?id=13358
6038 if (create_options & FILE_DELETE_ON_CLOSE) {
6039 if ((access_mask & DELETE_ACCESS) == 0) {
6040 status = NT_STATUS_INVALID_PARAMETER;
6045 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
6046 && is_named_stream(smb_fname))
6048 uint32_t base_create_disposition;
6049 struct smb_filename *smb_fname_base = NULL;
6050 uint32_t base_privflags;
6052 if (create_options & FILE_DIRECTORY_FILE) {
6053 DBG_DEBUG("Can't open a stream as directory\n");
6054 status = NT_STATUS_NOT_A_DIRECTORY;
6058 switch (create_disposition) {
6060 base_create_disposition = FILE_OPEN;
6063 base_create_disposition = FILE_OPEN_IF;
6067 smb_fname_base = cp_smb_filename_nostream(
6068 talloc_tos(), smb_fname);
6070 if (smb_fname_base == NULL) {
6071 status = NT_STATUS_NO_MEMORY;
6076 * We may be creating the basefile as part of creating the
6077 * stream, so it's legal if the basefile doesn't exist at this
6078 * point, the create_file_unixpath() below will create it. But
6079 * if the basefile exists we want a handle so we can fstat() it.
6082 ret = vfs_stat(conn, smb_fname_base);
6083 if (ret == -1 && errno != ENOENT) {
6084 status = map_nt_error_from_unix(errno);
6085 TALLOC_FREE(smb_fname_base);
6089 status = openat_pathref_fsp(conn->cwd_fsp,
6091 if (!NT_STATUS_IS_OK(status)) {
6092 DBG_ERR("open_smb_fname_fsp [%s] failed: %s\n",
6093 smb_fname_str_dbg(smb_fname_base),
6095 TALLOC_FREE(smb_fname_base);
6100 * https://bugzilla.samba.org/show_bug.cgi?id=10229
6101 * We need to check if the requested access mask
6102 * could be used to open the underlying file (if
6103 * it existed), as we're passing in zero for the
6104 * access mask to the base filename.
6106 status = check_base_file_access(smb_fname_base->fsp,
6109 if (!NT_STATUS_IS_OK(status)) {
6110 DEBUG(10, ("Permission check "
6111 "for base %s failed: "
6112 "%s\n", smb_fname->base_name,
6113 nt_errstr(status)));
6114 TALLOC_FREE(smb_fname_base);
6119 base_privflags = NTCREATEX_FLAG_STREAM_BASEOPEN;
6121 /* Open the base file. */
6122 status = create_file_unixpath(conn,
6129 | FILE_SHARE_DELETE,
6130 base_create_disposition,
6141 TALLOC_FREE(smb_fname_base);
6143 if (!NT_STATUS_IS_OK(status)) {
6144 DEBUG(10, ("create_file_unixpath for base %s failed: "
6145 "%s\n", smb_fname->base_name,
6146 nt_errstr(status)));
6151 if (smb_fname->fsp != NULL) {
6153 fsp = smb_fname->fsp;
6156 * We're about to use smb_fname->fsp for the fresh open.
6158 * Every fsp passed in via smb_fname->fsp already
6159 * holds a fsp->fsp_name. If it is already this
6160 * fsp->fsp_name that we got passed in as our input
6161 * argument smb_fname, these two are assumed to have
6162 * the same lifetime: Every fsp hangs of "conn", and
6163 * fsp->fsp_name is its talloc child.
6166 if (smb_fname != smb_fname->fsp->fsp_name) {
6168 * "smb_fname" is temporary in this case, but
6169 * the destructor of smb_fname would also tear
6170 * down the fsp we're about to use. Unlink
6171 * them from each other.
6173 smb_fname_fsp_unlink(smb_fname);
6178 free_fsp_on_error = true;
6181 status = fsp_bind_smb(fsp, req);
6182 if (!NT_STATUS_IS_OK(status)) {
6186 if (fsp_is_alternate_stream(fsp)) {
6187 struct files_struct *tmp_base_fsp = fsp->base_fsp;
6189 fsp_set_base_fsp(fsp, NULL);
6191 fd_close(tmp_base_fsp);
6192 file_free(NULL, tmp_base_fsp);
6196 * No fsp passed in that we can use, create one
6198 status = file_new(req, conn, &fsp);
6199 if(!NT_STATUS_IS_OK(status)) {
6202 free_fsp_on_error = true;
6204 status = fsp_set_smb_fname(fsp, smb_fname);
6205 if (!NT_STATUS_IS_OK(status)) {
6210 SMB_ASSERT(fsp->fsp_name->fsp != NULL);
6211 SMB_ASSERT(fsp->fsp_name->fsp == fsp);
6215 * We're opening the stream element of a
6216 * base_fsp we already opened. Set up the
6219 fsp_set_base_fsp(fsp, base_fsp);
6222 if (dirfsp != NULL) {
6223 status = SMB_VFS_PARENT_PATHNAME(
6229 if (!NT_STATUS_IS_OK(status)) {
6234 * Get a pathref on the parent. We can re-use this for
6235 * multiple calls to check parent ACLs etc. to avoid
6238 status = parent_pathref(talloc_tos(),
6243 if (!NT_STATUS_IS_OK(status)) {
6247 dirfsp = parent_dir_fname->fsp;
6248 status = fsp_set_smb_fname(dirfsp, parent_dir_fname);
6249 if (!NT_STATUS_IS_OK(status)) {
6255 * If it's a request for a directory open, deal with it separately.
6258 if (create_options & FILE_DIRECTORY_FILE) {
6260 if (create_options & FILE_NON_DIRECTORY_FILE) {
6261 status = NT_STATUS_INVALID_PARAMETER;
6265 /* Can't open a temp directory. IFS kit test. */
6266 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
6267 (file_attributes & FILE_ATTRIBUTE_TEMPORARY)) {
6268 status = NT_STATUS_INVALID_PARAMETER;
6273 * We will get a create directory here if the Win32
6274 * app specified a security descriptor in the
6275 * CreateDirectory() call.
6279 status = open_directory(conn,
6293 * Ordinary file case.
6296 if (allocation_size) {
6297 fsp->initial_allocation_size = smb_roundup(fsp->conn,
6301 status = open_file_ntcreate(conn,
6315 if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
6317 /* A stream open never opens a directory */
6320 status = NT_STATUS_FILE_IS_A_DIRECTORY;
6325 * Fail the open if it was explicitly a non-directory
6329 if (create_options & FILE_NON_DIRECTORY_FILE) {
6330 status = NT_STATUS_FILE_IS_A_DIRECTORY;
6335 status = open_directory(conn,
6349 if (!NT_STATUS_IS_OK(status)) {
6353 fsp->fsp_flags.is_fsa = true;
6355 if ((ea_list != NULL) &&
6356 ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN))) {
6357 status = set_ea(conn, fsp, ea_list);
6358 if (!NT_STATUS_IS_OK(status)) {
6363 if (!fsp->fsp_flags.is_directory &&
6364 S_ISDIR(fsp->fsp_name->st.st_ex_mode))
6366 status = NT_STATUS_ACCESS_DENIED;
6370 /* Save the requested allocation size. */
6371 if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
6372 if ((allocation_size > (uint64_t)fsp->fsp_name->st.st_ex_size)
6373 && !(fsp->fsp_flags.is_directory))
6375 fsp->initial_allocation_size = smb_roundup(
6376 fsp->conn, allocation_size);
6377 if (vfs_allocate_file_space(
6378 fsp, fsp->initial_allocation_size) == -1) {
6379 status = NT_STATUS_DISK_FULL;
6383 fsp->initial_allocation_size = smb_roundup(
6384 fsp->conn, (uint64_t)fsp->fsp_name->st.st_ex_size);
6387 fsp->initial_allocation_size = 0;
6390 if ((info == FILE_WAS_CREATED) &&
6391 lp_nt_acl_support(SNUM(conn)) &&
6392 !fsp_is_alternate_stream(fsp)) {
6395 * According to the MS documentation, the only time the security
6396 * descriptor is applied to the opened file is iff we *created* the
6397 * file; an existing file stays the same.
6399 * Also, it seems (from observation) that you can open the file with
6400 * any access mask but you can still write the sd. We need to override
6401 * the granted access before we call set_sd
6402 * Patch for bug #2242 from Tom Lackemann <cessnatomny@yahoo.com>.
6405 uint32_t sec_info_sent;
6406 uint32_t saved_access_mask = fsp->access_mask;
6408 sec_info_sent = get_sec_info(sd);
6410 fsp->access_mask = FILE_GENERIC_ALL;
6412 if (sec_info_sent & (SECINFO_OWNER|
6416 status = set_sd(fsp, sd, sec_info_sent);
6419 fsp->access_mask = saved_access_mask;
6421 if (!NT_STATUS_IS_OK(status)) {
6424 } else if (lp_inherit_acls(SNUM(conn))) {
6425 /* Inherit from parent. Errors here are not fatal. */
6426 status = inherit_new_acl(dirfsp, fsp);
6427 if (!NT_STATUS_IS_OK(status)) {
6428 DEBUG(10,("inherit_new_acl: failed for %s with %s\n",
6430 nt_errstr(status) ));
6435 if ((conn->fs_capabilities & FILE_FILE_COMPRESSION)
6436 && (create_options & FILE_NO_COMPRESSION)
6437 && (info == FILE_WAS_CREATED)) {
6438 status = SMB_VFS_SET_COMPRESSION(conn, fsp, fsp,
6439 COMPRESSION_FORMAT_NONE);
6440 if (!NT_STATUS_IS_OK(status)) {
6441 DEBUG(1, ("failed to disable compression: %s\n",
6442 nt_errstr(status)));
6446 DEBUG(10, ("create_file_unixpath: info=%d\n", info));
6449 if (pinfo != NULL) {
6453 smb_fname->st = fsp->fsp_name->st;
6455 TALLOC_FREE(parent_dir_fname);
6457 return NT_STATUS_OK;
6460 DEBUG(10, ("create_file_unixpath: %s\n", nt_errstr(status)));
6464 * The close_file below will close
6468 close_file_smb(req, fsp, ERROR_CLOSE);
6469 if (free_fsp_on_error) {
6470 file_free(req, fsp);
6474 if (base_fsp != NULL) {
6475 close_file_free(req, &base_fsp, ERROR_CLOSE);
6478 TALLOC_FREE(parent_dir_fname);
6483 NTSTATUS create_file_default(connection_struct *conn,
6484 struct smb_request *req,
6485 struct files_struct *dirfsp,
6486 struct smb_filename *smb_fname,
6487 uint32_t access_mask,
6488 uint32_t share_access,
6489 uint32_t create_disposition,
6490 uint32_t create_options,
6491 uint32_t file_attributes,
6492 uint32_t oplock_request,
6493 const struct smb2_lease *lease,
6494 uint64_t allocation_size,
6495 uint32_t private_flags,
6496 struct security_descriptor *sd,
6497 struct ea_list *ea_list,
6498 files_struct **result,
6500 const struct smb2_create_blobs *in_context_blobs,
6501 struct smb2_create_blobs *out_context_blobs)
6503 int info = FILE_WAS_OPENED;
6504 files_struct *fsp = NULL;
6506 bool stream_name = false;
6507 struct smb2_create_blob *posx = NULL;
6509 DBG_DEBUG("create_file: access_mask = 0x%x "
6510 "file_attributes = 0x%x, share_access = 0x%x, "
6511 "create_disposition = 0x%x create_options = 0x%x "
6512 "oplock_request = 0x%x "
6513 "private_flags = 0x%x "
6514 "ea_list = %p, sd = %p, "
6516 (unsigned int)access_mask,
6517 (unsigned int)file_attributes,
6518 (unsigned int)share_access,
6519 (unsigned int)create_disposition,
6520 (unsigned int)create_options,
6521 (unsigned int)oplock_request,
6522 (unsigned int)private_flags,
6525 smb_fname_str_dbg(smb_fname));
6529 * Remember the absolute time of the original request
6530 * with this mid. We'll use it later to see if this
6533 get_deferred_open_message_state(req, &req->request_time, NULL);
6537 * Check to see if this is a mac fork of some kind.
6540 stream_name = is_ntfs_stream_smb_fname(smb_fname);
6542 enum FAKE_FILE_TYPE fake_file_type;
6544 fake_file_type = is_fake_file(smb_fname);
6546 if (req != NULL && fake_file_type != FAKE_FILE_TYPE_NONE) {
6549 * Here we go! support for changing the disk quotas
6552 * We need to fake up to open this MAGIC QUOTA file
6553 * and return a valid FID.
6555 * w2k close this file directly after openening xp
6556 * also tries a QUERY_FILE_INFO on the file and then
6559 status = open_fake_file(req, conn, req->vuid,
6560 fake_file_type, smb_fname,
6562 if (!NT_STATUS_IS_OK(status)) {
6566 ZERO_STRUCT(smb_fname->st);
6570 if (!(conn->fs_capabilities & FILE_NAMED_STREAMS)) {
6571 status = NT_STATUS_OBJECT_NAME_INVALID;
6576 if (is_ntfs_default_stream_smb_fname(smb_fname)) {
6578 /* We have to handle this error here. */
6579 if (create_options & FILE_DIRECTORY_FILE) {
6580 status = NT_STATUS_NOT_A_DIRECTORY;
6583 ret = vfs_stat(conn, smb_fname);
6584 if (ret == 0 && VALID_STAT_OF_DIR(smb_fname->st)) {
6585 status = NT_STATUS_FILE_IS_A_DIRECTORY;
6590 posx = smb2_create_blob_find(
6591 in_context_blobs, SMB2_CREATE_TAG_POSIX);
6593 uint32_t wire_mode_bits = 0;
6594 mode_t mode_bits = 0;
6595 SMB_STRUCT_STAT sbuf = { 0 };
6596 enum perm_type ptype =
6597 (create_options & FILE_DIRECTORY_FILE) ?
6598 PERM_NEW_DIR : PERM_NEW_FILE;
6600 if (posx->data.length != 4) {
6601 status = NT_STATUS_INVALID_PARAMETER;
6605 wire_mode_bits = IVAL(posx->data.data, 0);
6606 status = unix_perms_from_wire(
6607 conn, &sbuf, wire_mode_bits, ptype, &mode_bits);
6608 if (!NT_STATUS_IS_OK(status)) {
6612 * Remove type info from mode, leaving only the
6613 * permissions and setuid/gid bits.
6615 mode_bits &= ~S_IFMT;
6617 file_attributes = (FILE_FLAG_POSIX_SEMANTICS | mode_bits);
6620 status = create_file_unixpath(conn,
6637 if (!NT_STATUS_IS_OK(status)) {
6642 DEBUG(10, ("create_file: info=%d\n", info));
6645 if (pinfo != NULL) {
6648 return NT_STATUS_OK;
6651 DEBUG(10, ("create_file: %s\n", nt_errstr(status)));
6654 close_file_free(req, &fsp, ERROR_CLOSE);