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 size_t connection_path_len,
575 struct files_struct *fsp,
576 struct files_struct *dirfsp,
577 struct smb_filename *symlink_name,
581 char *absolute = NULL;
582 const char *relative = NULL;
586 if (fsp_get_pathref_fd(fsp) != -1) {
588 * fsp is an O_PATH open, Linux does a "freadlink"
589 * with an empty name argument to readlinkat
591 status = readlink_talloc(talloc_tos(), fsp, NULL, &target);
593 status = readlink_talloc(
594 talloc_tos(), dirfsp, symlink_name, &target);
597 if (!NT_STATUS_IS_OK(status)) {
598 DBG_DEBUG("readlink_talloc failed: %s\n", nt_errstr(status));
602 if (target[0] != '/') {
603 char *tmp = talloc_asprintf(
607 dirfsp->fsp_name->base_name,
613 return NT_STATUS_NO_MEMORY;
618 DBG_DEBUG("redirecting to %s\n", target);
620 absolute = canonicalize_absolute_path(talloc_tos(), target);
623 if (absolute == NULL) {
624 return NT_STATUS_NO_MEMORY;
628 * We're doing the "below connection_path" here because it's
629 * cheap. It might be that we get a symlink out of the share,
630 * pointing to yet another symlink getting us back into the
631 * share. If we need that, we would have to remove the check
640 DBG_NOTICE("Bad access attempt: %s is a symlink "
641 "outside the share path\n"
643 "resolved_name=%s\n",
644 symlink_name->base_name,
647 TALLOC_FREE(absolute);
648 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
651 if (relative[0] == '\0') {
653 * special case symlink to share root: "." is our
654 * share root filename
659 memmove(absolute, relative, strlen(relative)+1);
666 /****************************************************************************
668 ****************************************************************************/
670 static NTSTATUS non_widelink_open(const struct files_struct *dirfsp,
672 struct smb_filename *smb_fname,
673 const struct vfs_open_how *_how)
675 struct connection_struct *conn = fsp->conn;
676 const char *connpath = SMB_VFS_CONNECTPATH(conn, dirfsp, smb_fname);
678 NTSTATUS status = NT_STATUS_OK;
680 char *orig_smb_fname_base = smb_fname->base_name;
681 struct smb_filename *orig_fsp_name = fsp->fsp_name;
682 struct smb_filename *smb_fname_rel = NULL;
683 struct smb_filename *oldwd_fname = NULL;
684 struct smb_filename *parent_dir_fname = NULL;
685 struct vfs_open_how how = *_how;
687 size_t link_depth = 0;
690 SMB_ASSERT(!fsp_is_alternate_stream(fsp));
692 if (connpath == NULL) {
694 * This can happen with shadow_copy2 if the snapshot
697 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
699 connpath_len = strlen(connpath);
702 if (smb_fname->base_name[0] == '/') {
703 int cmp = strcmp(connpath, smb_fname->base_name);
705 smb_fname->base_name = talloc_strdup(smb_fname, "");
706 if (smb_fname->base_name == NULL) {
707 status = NT_STATUS_NO_MEMORY;
713 if (dirfsp == conn->cwd_fsp) {
715 status = SMB_VFS_PARENT_PATHNAME(fsp->conn,
720 if (!NT_STATUS_IS_OK(status)) {
724 status = chdir_below_conn(
731 if (!NT_STATUS_IS_OK(status)) {
735 /* Setup fsp->fsp_name to be relative to cwd */
736 fsp->fsp_name = smb_fname_rel;
739 * fsp->fsp_name is unchanged as it is already correctly
740 * relative to conn->cwd.
742 smb_fname_rel = smb_fname;
747 * Assert nobody can step in with a symlink on the
748 * path, there is no path anymore and we'll use
749 * O_NOFOLLOW to open.
751 char *slash = strchr_m(smb_fname_rel->base_name, '/');
752 SMB_ASSERT(slash == NULL);
755 how.flags |= O_NOFOLLOW;
757 fd = SMB_VFS_OPENAT(conn,
762 fsp_set_fd(fsp, fd); /* This preserves errno */
765 status = map_nt_error_from_unix(errno);
767 if (errno == ENOENT) {
772 * ENOENT makes it worthless retrying with a
773 * stat, we know for sure the file does not
774 * exist. For everything else we want to know
777 ret = SMB_VFS_FSTATAT(
782 AT_SYMLINK_NOFOLLOW);
786 * Keep the original error. Otherwise we would
787 * mask for example EROFS for open(O_CREAT),
788 * turning it into ENOENT.
793 ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st);
797 status = map_nt_error_from_unix(errno);
798 DBG_DEBUG("fstat[at](%s) failed: %s\n",
799 smb_fname_str_dbg(smb_fname),
804 fsp->fsp_flags.is_directory = S_ISDIR(fsp->fsp_name->st.st_ex_mode);
805 orig_fsp_name->st = fsp->fsp_name->st;
807 if (!S_ISLNK(fsp->fsp_name->st.st_ex_mode)) {
812 * Found a symlink to follow in user space
815 if (fsp->fsp_name->flags & SMB_FILENAME_POSIX_PATH) {
816 /* Never follow symlinks on posix open. */
817 status = NT_STATUS_STOPPED_ON_SYMLINK;
820 if (!lp_follow_symlinks(SNUM(conn))) {
821 /* Explicitly no symlinks. */
822 status = NT_STATUS_STOPPED_ON_SYMLINK;
827 if (link_depth >= 40) {
828 status = NT_STATUS_STOPPED_ON_SYMLINK;
832 fsp->fsp_name = orig_fsp_name;
834 status = symlink_target_below_conn(
839 discard_const_p(files_struct, dirfsp),
843 if (!NT_STATUS_IS_OK(status)) {
844 DBG_DEBUG("symlink_target_below_conn() failed: %s\n",
850 * Close what openat(O_PATH) potentially left behind
854 if (smb_fname->base_name != orig_smb_fname_base) {
855 TALLOC_FREE(smb_fname->base_name);
857 smb_fname->base_name = target;
859 if (oldwd_fname != NULL) {
860 ret = vfs_ChDir(conn, oldwd_fname);
862 smb_panic("unable to get back to old directory\n");
864 TALLOC_FREE(oldwd_fname);
868 * And do it all again... As smb_fname is not relative to the passed in
869 * dirfsp anymore, we pass conn->cwd_fsp as dirfsp to
870 * non_widelink_open() to trigger the chdir(parentdir) logic.
872 dirfsp = conn->cwd_fsp;
877 fsp->fsp_name = orig_fsp_name;
878 smb_fname->base_name = orig_smb_fname_base;
880 TALLOC_FREE(parent_dir_fname);
882 if (!NT_STATUS_IS_OK(status)) {
886 if (oldwd_fname != NULL) {
887 ret = vfs_ChDir(conn, oldwd_fname);
889 smb_panic("unable to get back to old directory\n");
891 TALLOC_FREE(oldwd_fname);
896 /****************************************************************************
897 fd support routines - attempt to do a dos_open.
898 ****************************************************************************/
900 NTSTATUS fd_openat(const struct files_struct *dirfsp,
901 struct smb_filename *smb_fname,
903 const struct vfs_open_how *_how)
905 struct vfs_open_how how = *_how;
906 struct connection_struct *conn = fsp->conn;
907 NTSTATUS status = NT_STATUS_OK;
908 bool fsp_is_stream = fsp_is_alternate_stream(fsp);
909 bool smb_fname_is_stream = is_named_stream(smb_fname);
911 SMB_ASSERT(fsp_is_stream == smb_fname_is_stream);
914 * Never follow symlinks on a POSIX client. The
915 * client should be doing this.
918 if ((fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) || !lp_follow_symlinks(SNUM(conn))) {
919 how.flags |= O_NOFOLLOW;
927 NULL, /* stream open is relative to fsp->base_fsp */
932 status = map_nt_error_from_unix(errno);
937 status = vfs_stat_fsp(fsp);
938 if (!NT_STATUS_IS_OK(status)) {
939 DBG_DEBUG("vfs_stat_fsp failed: %s\n",
949 * Only follow symlinks within a share
952 status = non_widelink_open(dirfsp, fsp, smb_fname, &how);
953 if (!NT_STATUS_IS_OK(status)) {
954 if (NT_STATUS_EQUAL(status, NT_STATUS_TOO_MANY_OPENED_FILES)) {
955 static time_t last_warned = 0L;
957 if (time((time_t *) NULL) > last_warned) {
958 DEBUG(0,("Too many open files, unable "
959 "to open more! smbd's max "
961 lp_max_open_files()));
962 last_warned = time((time_t *) NULL);
966 DBG_DEBUG("name %s, flags = 0%o mode = 0%o, fd = %d. %s\n",
967 smb_fname_str_dbg(smb_fname),
970 fsp_get_pathref_fd(fsp),
975 DBG_DEBUG("name %s, flags = 0%o mode = 0%o, fd = %d\n",
976 smb_fname_str_dbg(smb_fname),
979 fsp_get_pathref_fd(fsp));
984 /****************************************************************************
985 Close the file associated with a fsp.
986 ****************************************************************************/
988 NTSTATUS fd_close(files_struct *fsp)
993 if (fsp == fsp->conn->cwd_fsp) {
997 if (fsp->fsp_flags.fstat_before_close) {
998 status = vfs_stat_fsp(fsp);
999 if (!NT_STATUS_IS_OK(status)) {
1007 if (fsp_get_pathref_fd(fsp) == -1) {
1009 * Either a directory where the dptr_CloseDir() already closed
1010 * the fd or a stat open.
1012 return NT_STATUS_OK;
1014 if (fh_get_refcount(fsp->fh) > 1) {
1015 return NT_STATUS_OK; /* Shared handle. Only close last reference. */
1018 ret = SMB_VFS_CLOSE(fsp);
1019 fsp_set_fd(fsp, -1);
1021 return map_nt_error_from_unix(errno);
1023 return NT_STATUS_OK;
1026 /****************************************************************************
1027 Change the ownership of a file to that of the parent directory.
1028 Do this by fd if possible.
1029 ****************************************************************************/
1031 static void change_file_owner_to_parent_fsp(struct files_struct *parent_fsp,
1032 struct files_struct *fsp)
1036 if (parent_fsp->fsp_name->st.st_ex_uid == fsp->fsp_name->st.st_ex_uid) {
1037 /* Already this uid - no need to change. */
1038 DBG_DEBUG("file %s is already owned by uid %u\n",
1040 (unsigned int)fsp->fsp_name->st.st_ex_uid);
1045 ret = SMB_VFS_FCHOWN(fsp,
1046 parent_fsp->fsp_name->st.st_ex_uid,
1050 DBG_ERR("failed to fchown "
1051 "file %s to parent directory uid %u. Error "
1054 (unsigned int)parent_fsp->fsp_name->st.st_ex_uid,
1057 DBG_DEBUG("changed new file %s to "
1058 "parent directory uid %u.\n",
1060 (unsigned int)parent_fsp->fsp_name->st.st_ex_uid);
1061 /* Ensure the uid entry is updated. */
1062 fsp->fsp_name->st.st_ex_uid =
1063 parent_fsp->fsp_name->st.st_ex_uid;
1067 static NTSTATUS change_dir_owner_to_parent_fsp(struct files_struct *parent_fsp,
1068 struct files_struct *fsp)
1073 if (parent_fsp->fsp_name->st.st_ex_uid == fsp->fsp_name->st.st_ex_uid) {
1074 /* Already this uid - no need to change. */
1075 DBG_DEBUG("directory %s is already owned by uid %u\n",
1077 (unsigned int)fsp->fsp_name->st.st_ex_uid);
1078 return NT_STATUS_OK;
1082 ret = SMB_VFS_FCHOWN(fsp,
1083 parent_fsp->fsp_name->st.st_ex_uid,
1087 status = map_nt_error_from_unix(errno);
1088 DBG_ERR("failed to chown "
1089 "directory %s to parent directory uid %u. "
1092 (unsigned int)parent_fsp->fsp_name->st.st_ex_uid,
1097 DBG_DEBUG("changed ownership of new "
1098 "directory %s to parent directory uid %u.\n",
1100 (unsigned int)parent_fsp->fsp_name->st.st_ex_uid);
1102 /* Ensure the uid entry is updated. */
1103 fsp->fsp_name->st.st_ex_uid = parent_fsp->fsp_name->st.st_ex_uid;
1105 return NT_STATUS_OK;
1108 /****************************************************************************
1109 Open a file - returning a guaranteed ATOMIC indication of if the
1110 file was created or not.
1111 ****************************************************************************/
1113 static NTSTATUS fd_open_atomic(struct files_struct *dirfsp,
1114 struct smb_filename *smb_fname,
1120 struct vfs_open_how how = { .flags = flags, .mode = mode, };
1121 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
1122 NTSTATUS retry_status;
1123 bool file_existed = VALID_STAT(smb_fname->st);
1125 if (!(how.flags & O_CREAT)) {
1127 * We're not creating the file, just pass through.
1129 status = fd_openat(dirfsp, smb_fname, fsp, &how);
1130 *file_created = false;
1134 if (how.flags & O_EXCL) {
1136 * Fail if already exists, just pass through.
1138 status = fd_openat(dirfsp, smb_fname, fsp, &how);
1141 * Here we've opened with O_CREAT|O_EXCL. If that went
1142 * NT_STATUS_OK, we *know* we created this file.
1144 *file_created = NT_STATUS_IS_OK(status);
1150 * Now it gets tricky. We have O_CREAT, but not O_EXCL.
1151 * To know absolutely if we created the file or not,
1152 * we can never call O_CREAT without O_EXCL. So if
1153 * we think the file existed, try without O_CREAT|O_EXCL.
1154 * If we think the file didn't exist, try with
1157 * The big problem here is dangling symlinks. Opening
1158 * without O_NOFOLLOW means both bad symlink
1159 * and missing path return -1, ENOENT from open(). As POSIX
1160 * is pathname based it's not possible to tell
1161 * the difference between these two cases in a
1162 * non-racy way, so change to try only two attempts before
1165 * We don't have this problem for the O_NOFOLLOW
1166 * case as it just returns NT_STATUS_OBJECT_PATH_NOT_FOUND
1167 * mapped from the ELOOP POSIX error.
1171 how.flags = flags & ~(O_CREAT);
1172 retry_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
1174 how.flags = flags | O_EXCL;
1175 retry_status = NT_STATUS_OBJECT_NAME_COLLISION;
1178 status = fd_openat(dirfsp, smb_fname, fsp, &how);
1179 if (NT_STATUS_IS_OK(status)) {
1180 *file_created = !file_existed;
1181 return NT_STATUS_OK;
1183 if (NT_STATUS_EQUAL(status, retry_status)) {
1185 file_existed = !file_existed;
1187 DBG_DEBUG("File %s %s. Retry.\n",
1189 file_existed ? "existed" : "did not exist");
1192 how.flags = flags & ~(O_CREAT);
1194 how.flags = flags | O_EXCL;
1197 status = fd_openat(dirfsp, smb_fname, fsp, &how);
1200 *file_created = (NT_STATUS_IS_OK(status) && !file_existed);
1204 static NTSTATUS reopen_from_procfd(struct files_struct *fsp,
1208 struct vfs_open_how how = { .flags = flags, .mode = mode };
1209 struct smb_filename proc_fname;
1210 const char *p = NULL;
1216 if (!fsp->fsp_flags.have_proc_fds) {
1217 return NT_STATUS_MORE_PROCESSING_REQUIRED;
1220 old_fd = fsp_get_pathref_fd(fsp);
1222 return NT_STATUS_MORE_PROCESSING_REQUIRED;
1225 if (!fsp->fsp_flags.is_pathref) {
1226 DBG_ERR("[%s] is not a pathref\n",
1229 smb_panic("Not a pathref");
1231 return NT_STATUS_INVALID_HANDLE;
1234 p = sys_proc_fd_path(old_fd, buf, sizeof(buf));
1236 return NT_STATUS_NO_MEMORY;
1239 proc_fname = (struct smb_filename) {
1240 .base_name = discard_const_p(char, p),
1243 fsp->fsp_flags.is_pathref = false;
1245 new_fd = SMB_VFS_OPENAT(fsp->conn,
1251 status = map_nt_error_from_unix(errno);
1256 status = fd_close(fsp);
1257 if (!NT_STATUS_IS_OK(status)) {
1261 fsp_set_fd(fsp, new_fd);
1262 return NT_STATUS_OK;
1265 static NTSTATUS reopen_from_fsp(struct files_struct *dirfsp,
1266 struct smb_filename *smb_fname,
1267 struct files_struct *fsp,
1270 bool *p_file_created)
1272 bool __unused_file_created = false;
1275 if (p_file_created == NULL) {
1276 p_file_created = &__unused_file_created;
1280 * TODO: should we move this to the VFS layer?
1281 * SMB_VFS_REOPEN_FSP()?
1284 status = reopen_from_procfd(fsp,
1287 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1292 * Close the existing pathref fd and set the fsp flag
1293 * is_pathref to false so we get a "normal" fd this time.
1295 status = fd_close(fsp);
1296 if (!NT_STATUS_IS_OK(status)) {
1300 fsp->fsp_flags.is_pathref = false;
1302 status = fd_open_atomic(
1312 /****************************************************************************
1314 ****************************************************************************/
1316 static NTSTATUS open_file(struct smb_request *req,
1317 struct files_struct *dirfsp,
1318 struct smb_filename *smb_fname_atname,
1322 uint32_t access_mask, /* client requested access mask. */
1323 uint32_t open_access_mask, /* what we're actually using in the open. */
1324 uint32_t private_flags,
1325 bool *p_file_created)
1327 connection_struct *conn = fsp->conn;
1328 struct smb_filename *smb_fname = fsp->fsp_name;
1329 NTSTATUS status = NT_STATUS_OK;
1330 int accmode = (flags & O_ACCMODE);
1331 int local_flags = flags;
1332 bool file_existed = VALID_STAT(fsp->fsp_name->st);
1333 const uint32_t need_fd_mask =
1338 SEC_FLAG_SYSTEM_SECURITY;
1339 bool creating = !file_existed && (flags & O_CREAT);
1340 bool truncating = (flags & O_TRUNC);
1341 bool open_fd = false;
1342 bool posix_open = (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN);
1345 * Catch early an attempt to open an existing
1346 * directory as a file.
1348 if (file_existed && S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
1349 return NT_STATUS_FILE_IS_A_DIRECTORY;
1352 /* Check permissions */
1355 * This code was changed after seeing a client open request
1356 * containing the open mode of (DENY_WRITE/read-only) with
1357 * the 'create if not exist' bit set. The previous code
1358 * would fail to open the file read only on a read-only share
1359 * as it was checking the flags parameter directly against O_RDONLY,
1360 * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
1364 if (!CAN_WRITE(conn)) {
1365 /* It's a read-only share - fail if we wanted to write. */
1366 if(accmode != O_RDONLY || (flags & O_TRUNC) || (flags & O_APPEND)) {
1367 DEBUG(3,("Permission denied opening %s\n",
1368 smb_fname_str_dbg(smb_fname)));
1369 return NT_STATUS_ACCESS_DENIED;
1371 if (flags & O_CREAT) {
1372 /* We don't want to write - but we must make sure that
1373 O_CREAT doesn't create the file if we have write
1374 access into the directory.
1376 flags &= ~(O_CREAT|O_EXCL);
1377 local_flags &= ~(O_CREAT|O_EXCL);
1382 * This little piece of insanity is inspired by the
1383 * fact that an NT client can open a file for O_RDONLY,
1384 * but set the create disposition to FILE_EXISTS_TRUNCATE.
1385 * If the client *can* write to the file, then it expects to
1386 * truncate the file, even though it is opening for readonly.
1387 * Quicken uses this stupid trick in backup file creation...
1388 * Thanks *greatly* to "David W. Chapman Jr." <dwcjr@inethouston.net>
1389 * for helping track this one down. It didn't bite us in 2.0.x
1390 * as we always opened files read-write in that release. JRA.
1393 if ((accmode == O_RDONLY) && ((flags & O_TRUNC) == O_TRUNC)) {
1394 DEBUG(10,("open_file: truncate requested on read-only open "
1395 "for file %s\n", smb_fname_str_dbg(smb_fname)));
1396 local_flags = (flags & ~O_ACCMODE)|O_RDWR;
1399 if ((open_access_mask & need_fd_mask) || creating || truncating) {
1407 #if defined(O_NONBLOCK) && defined(S_ISFIFO)
1409 * We would block on opening a FIFO with no one else on the
1410 * other end. Do what we used to do and add O_NONBLOCK to the
1414 if (file_existed && S_ISFIFO(smb_fname->st.st_ex_mode)) {
1415 local_flags &= ~O_TRUNC; /* Can't truncate a FIFO. */
1416 local_flags |= O_NONBLOCK;
1421 /* Don't create files with Microsoft wildcard characters. */
1422 if (fsp_is_alternate_stream(fsp)) {
1424 * wildcard characters are allowed in stream names
1425 * only test the basefilename
1427 wild = fsp->base_fsp->fsp_name->base_name;
1429 wild = smb_fname->base_name;
1431 if ((local_flags & O_CREAT) && !file_existed &&
1432 !(fsp->posix_flags & FSP_POSIX_FLAGS_PATHNAMES) &&
1433 ms_has_wild(wild)) {
1434 return NT_STATUS_OBJECT_NAME_INVALID;
1437 /* Can we access this file ? */
1438 if (!fsp_is_alternate_stream(fsp)) {
1439 /* Only do this check on non-stream open. */
1441 status = smbd_check_access_rights_fsp(
1447 if (!NT_STATUS_IS_OK(status)) {
1448 DBG_DEBUG("smbd_check_access_rights_fsp"
1449 " on file %s returned %s\n",
1454 if (!NT_STATUS_IS_OK(status) &&
1455 !NT_STATUS_EQUAL(status,
1456 NT_STATUS_OBJECT_NAME_NOT_FOUND))
1461 if (NT_STATUS_EQUAL(status,
1462 NT_STATUS_OBJECT_NAME_NOT_FOUND))
1464 DEBUG(10, ("open_file: "
1465 "file %s vanished since we "
1466 "checked for existence.\n",
1467 smb_fname_str_dbg(smb_fname)));
1468 file_existed = false;
1469 SET_STAT_INVALID(fsp->fsp_name->st);
1473 if (!file_existed) {
1474 if (!(local_flags & O_CREAT)) {
1475 /* File didn't exist and no O_CREAT. */
1476 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1479 status = check_parent_access_fsp(
1482 if (!NT_STATUS_IS_OK(status)) {
1483 DBG_DEBUG("check_parent_access_fsp on "
1484 "directory %s for file %s "
1488 smb_fname_str_dbg(smb_fname),
1496 * Actually do the open - if O_TRUNC is needed handle it
1497 * below under the share mode lock.
1499 status = reopen_from_fsp(dirfsp,
1502 local_flags & ~O_TRUNC,
1505 if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) {
1507 * Non-O_PATH reopen that hit a race
1508 * condition: Someone has put a symlink where
1509 * we used to have a file. Can't happen with
1510 * O_PATH and reopening from /proc/self/fd/ or
1513 status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
1515 if (!NT_STATUS_IS_OK(status)) {
1516 DEBUG(3,("Error opening file %s (%s) (local_flags=%d) "
1517 "(flags=%d)\n", smb_fname_str_dbg(smb_fname),
1518 nt_errstr(status),local_flags,flags));
1522 if (local_flags & O_NONBLOCK) {
1524 * GPFS can return ETIMEDOUT for pread on
1525 * nonblocking file descriptors when files
1526 * migrated to tape need to be recalled. I
1527 * could imagine this happens elsewhere
1528 * too. With blocking file descriptors this
1531 ret = vfs_set_blocking(fsp, true);
1533 status = map_nt_error_from_unix(errno);
1534 DBG_WARNING("Could not set fd to blocking: "
1535 "%s\n", strerror(errno));
1541 if (*p_file_created) {
1542 /* We created this file. */
1544 bool need_re_stat = false;
1545 /* Do all inheritance work after we've
1546 done a successful fstat call and filled
1547 in the stat struct in fsp->fsp_name. */
1549 /* Inherit the ACL if required */
1550 if (lp_inherit_permissions(SNUM(conn))) {
1551 inherit_access_posix_acl(conn,
1555 need_re_stat = true;
1558 /* Change the owner if required. */
1559 if (lp_inherit_owner(SNUM(conn)) != INHERIT_OWNER_NO) {
1560 change_file_owner_to_parent_fsp(dirfsp, fsp);
1561 need_re_stat = true;
1565 status = vfs_stat_fsp(fsp);
1567 * If we have an fd, this stat should succeed.
1569 if (!NT_STATUS_IS_OK(status)) {
1570 DBG_ERR("Error doing fstat on open "
1572 smb_fname_str_dbg(smb_fname),
1579 notify_fname(conn, NOTIFY_ACTION_ADDED,
1580 FILE_NOTIFY_CHANGE_FILE_NAME,
1581 smb_fname->base_name);
1584 if (!file_existed) {
1585 /* File must exist for a stat open. */
1586 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1589 if (S_ISLNK(smb_fname->st.st_ex_mode) &&
1593 * Don't allow stat opens on symlinks directly unless
1594 * it's a POSIX open. Match the return code from
1595 * openat_pathref_fsp().
1597 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1600 if (!fsp->fsp_flags.is_pathref) {
1602 * There is only one legit case where end up here:
1603 * openat_pathref_fsp() failed to open a symlink, so the
1604 * fsp was created by fsp_new() which doesn't set
1605 * is_pathref. Other then that, we should always have a
1606 * pathref fsp at this point. The subsequent checks
1609 if (!(smb_fname->flags & SMB_FILENAME_POSIX_PATH)) {
1610 DBG_ERR("[%s] is not a POSIX pathname\n",
1611 smb_fname_str_dbg(smb_fname));
1612 return NT_STATUS_INTERNAL_ERROR;
1614 if (!S_ISLNK(smb_fname->st.st_ex_mode)) {
1615 DBG_ERR("[%s] is not a symlink\n",
1616 smb_fname_str_dbg(smb_fname));
1617 return NT_STATUS_INTERNAL_ERROR;
1619 if (fsp_get_pathref_fd(fsp) != -1) {
1620 DBG_ERR("fd for [%s] is not -1: fd [%d]\n",
1621 smb_fname_str_dbg(smb_fname),
1622 fsp_get_pathref_fd(fsp));
1623 return NT_STATUS_INTERNAL_ERROR;
1628 * Access to streams is checked by checking the basefile and
1629 * that has alreay been checked by check_base_file_access()
1630 * in create_file_unixpath().
1632 if (!fsp_is_alternate_stream(fsp)) {
1633 status = smbd_check_access_rights_fsp(dirfsp,
1638 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) &&
1640 S_ISLNK(smb_fname->st.st_ex_mode)) {
1641 /* This is a POSIX stat open for delete
1642 * or rename on a symlink that points
1643 * nowhere. Allow. */
1644 DEBUG(10,("open_file: allowing POSIX "
1645 "open on bad symlink %s\n",
1646 smb_fname_str_dbg(smb_fname)));
1647 status = NT_STATUS_OK;
1650 if (!NT_STATUS_IS_OK(status)) {
1651 DBG_DEBUG("smbd_check_access_rights_fsp on file "
1660 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
1661 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
1662 fsp->file_pid = req ? req->smbpid : 0;
1663 fsp->fsp_flags.can_lock = true;
1664 fsp->fsp_flags.can_read = ((access_mask & FILE_READ_DATA) != 0);
1665 fsp->fsp_flags.can_write =
1667 ((access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) != 0);
1668 fsp->print_file = NULL;
1669 fsp->fsp_flags.modified = false;
1670 fsp->sent_oplock_break = NO_BREAK_SENT;
1671 fsp->fsp_flags.is_directory = false;
1672 if (conn->aio_write_behind_list &&
1673 is_in_path(smb_fname->base_name, conn->aio_write_behind_list,
1674 posix_open ? true: conn->case_sensitive)) {
1675 fsp->fsp_flags.aio_write_behind = true;
1678 DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
1679 conn->session_info->unix_info->unix_name,
1680 smb_fname_str_dbg(smb_fname),
1681 BOOLSTR(fsp->fsp_flags.can_read),
1682 BOOLSTR(fsp->fsp_flags.can_write),
1683 conn->num_files_open));
1685 return NT_STATUS_OK;
1688 static bool mask_conflict(
1689 uint32_t new_access,
1690 uint32_t existing_access,
1691 uint32_t access_mask,
1692 uint32_t new_sharemode,
1693 uint32_t existing_sharemode,
1694 uint32_t sharemode_mask)
1696 bool want_access = (new_access & access_mask);
1697 bool allow_existing = (existing_sharemode & sharemode_mask);
1698 bool have_access = (existing_access & access_mask);
1699 bool allow_new = (new_sharemode & sharemode_mask);
1701 if (want_access && !allow_existing) {
1702 DBG_DEBUG("Access request 0x%"PRIx32"/0x%"PRIx32" conflicts "
1703 "with existing sharemode 0x%"PRIx32"/0x%"PRIx32"\n",
1710 if (have_access && !allow_new) {
1711 DBG_DEBUG("Sharemode request 0x%"PRIx32"/0x%"PRIx32" conflicts "
1712 "with existing access 0x%"PRIx32"/0x%"PRIx32"\n",
1722 /****************************************************************************
1723 Check if we can open a file with a share mode.
1724 Returns True if conflict, False if not.
1725 ****************************************************************************/
1727 static const uint32_t conflicting_access =
1734 static bool share_conflict(uint32_t e_access_mask,
1735 uint32_t e_share_access,
1736 uint32_t access_mask,
1737 uint32_t share_access)
1741 DBG_DEBUG("existing access_mask = 0x%"PRIx32", "
1742 "existing share access = 0x%"PRIx32", "
1743 "access_mask = 0x%"PRIx32", "
1744 "share_access = 0x%"PRIx32"\n",
1750 if ((e_access_mask & conflicting_access) == 0) {
1751 DBG_DEBUG("No conflict due to "
1752 "existing access_mask = 0x%"PRIx32"\n",
1756 if ((access_mask & conflicting_access) == 0) {
1757 DBG_DEBUG("No conflict due to access_mask = 0x%"PRIx32"\n",
1762 conflict = mask_conflict(
1763 access_mask, e_access_mask, FILE_WRITE_DATA | FILE_APPEND_DATA,
1764 share_access, e_share_access, FILE_SHARE_WRITE);
1765 conflict |= mask_conflict(
1766 access_mask, e_access_mask, FILE_READ_DATA | FILE_EXECUTE,
1767 share_access, e_share_access, FILE_SHARE_READ);
1768 conflict |= mask_conflict(
1769 access_mask, e_access_mask, DELETE_ACCESS,
1770 share_access, e_share_access, FILE_SHARE_DELETE);
1772 DBG_DEBUG("conflict=%s\n", conflict ? "true" : "false");
1776 #if defined(DEVELOPER)
1778 struct validate_my_share_entries_state {
1779 struct smbd_server_connection *sconn;
1781 struct server_id self;
1784 static bool validate_my_share_entries_fn(
1785 struct share_mode_entry *e,
1789 struct validate_my_share_entries_state *state = private_data;
1792 if (!server_id_equal(&state->self, &e->pid)) {
1796 if (e->op_mid == 0) {
1797 /* INTERNAL_OPEN_ONLY */
1801 fsp = file_find_dif(state->sconn, state->fid, e->share_file_id);
1803 DBG_ERR("PANIC : %s\n",
1804 share_mode_str(talloc_tos(), 0, &state->fid, e));
1805 smb_panic("validate_my_share_entries: Cannot match a "
1806 "share entry with an open file\n");
1809 if (((uint16_t)fsp->oplock_type) != e->op_type) {
1818 DBG_ERR("validate_my_share_entries: PANIC : %s\n",
1819 share_mode_str(talloc_tos(), 0, &state->fid, e));
1820 str = talloc_asprintf(talloc_tos(),
1821 "validate_my_share_entries: "
1822 "file %s, oplock_type = 0x%x, op_type = 0x%x\n",
1823 fsp->fsp_name->base_name,
1824 (unsigned int)fsp->oplock_type,
1825 (unsigned int)e->op_type);
1834 * Allowed access mask for stat opens relevant to oplocks
1836 bool is_oplock_stat_open(uint32_t access_mask)
1838 const uint32_t stat_open_bits =
1839 (SYNCHRONIZE_ACCESS|
1840 FILE_READ_ATTRIBUTES|
1841 FILE_WRITE_ATTRIBUTES);
1843 return (((access_mask & stat_open_bits) != 0) &&
1844 ((access_mask & ~stat_open_bits) == 0));
1848 * Allowed access mask for stat opens relevant to leases
1850 bool is_lease_stat_open(uint32_t access_mask)
1852 const uint32_t stat_open_bits =
1853 (SYNCHRONIZE_ACCESS|
1854 FILE_READ_ATTRIBUTES|
1855 FILE_WRITE_ATTRIBUTES|
1856 READ_CONTROL_ACCESS);
1858 return (((access_mask & stat_open_bits) != 0) &&
1859 ((access_mask & ~stat_open_bits) == 0));
1862 struct has_delete_on_close_state {
1866 static bool has_delete_on_close_fn(
1867 struct share_mode_entry *e,
1871 struct has_delete_on_close_state *state = private_data;
1872 state->ret = !share_entry_stale_pid(e);
1876 static bool has_delete_on_close(struct share_mode_lock *lck,
1879 struct has_delete_on_close_state state = { .ret = false };
1882 if (!is_delete_on_close_set(lck, name_hash)) {
1886 ok= share_mode_forall_entries(lck, has_delete_on_close_fn, &state);
1888 DBG_DEBUG("share_mode_forall_entries failed\n");
1894 static void share_mode_flags_restrict(
1895 struct share_mode_lock *lck,
1896 uint32_t access_mask,
1897 uint32_t share_mode,
1898 uint32_t lease_type)
1900 uint32_t existing_access_mask, existing_share_mode;
1901 uint32_t existing_lease_type;
1903 share_mode_flags_get(
1905 &existing_access_mask,
1906 &existing_share_mode,
1907 &existing_lease_type);
1909 existing_access_mask |= access_mask;
1910 if (access_mask & conflicting_access) {
1911 existing_share_mode &= share_mode;
1913 existing_lease_type |= lease_type;
1915 share_mode_flags_set(
1917 existing_access_mask,
1918 existing_share_mode,
1919 existing_lease_type,
1923 /****************************************************************************
1924 Deal with share modes
1925 Invariant: Share mode must be locked on entry and exit.
1926 Returns -1 on error, or number of share modes on success (may be zero).
1927 ****************************************************************************/
1929 struct open_mode_check_state {
1931 uint32_t access_mask;
1932 uint32_t share_access;
1933 uint32_t lease_type;
1936 static bool open_mode_check_fn(
1937 struct share_mode_entry *e,
1941 struct open_mode_check_state *state = private_data;
1942 bool disconnected, stale;
1943 uint32_t access_mask, share_access, lease_type;
1945 disconnected = server_id_is_disconnected(&e->pid);
1950 access_mask = state->access_mask | e->access_mask;
1951 share_access = state->share_access;
1952 if (e->access_mask & conflicting_access) {
1953 share_access &= e->share_access;
1955 lease_type = state->lease_type | get_lease_type(e, state->fid);
1957 if ((access_mask == state->access_mask) &&
1958 (share_access == state->share_access) &&
1959 (lease_type == state->lease_type)) {
1963 stale = share_entry_stale_pid(e);
1968 state->access_mask = access_mask;
1969 state->share_access = share_access;
1970 state->lease_type = lease_type;
1975 static NTSTATUS open_mode_check(connection_struct *conn,
1977 struct share_mode_lock *lck,
1978 uint32_t access_mask,
1979 uint32_t share_access)
1981 struct open_mode_check_state state;
1983 bool modified = false;
1985 if (is_oplock_stat_open(access_mask)) {
1986 /* Stat open that doesn't trigger oplock breaks or share mode
1987 * checks... ! JRA. */
1988 return NT_STATUS_OK;
1992 * Check if the share modes will give us access.
1995 #if defined(DEVELOPER)
1997 struct validate_my_share_entries_state validate_state = {
1998 .sconn = conn->sconn,
2000 .self = messaging_server_id(conn->sconn->msg_ctx),
2002 ok = share_mode_forall_entries(
2003 lck, validate_my_share_entries_fn, &validate_state);
2008 share_mode_flags_get(
2009 lck, &state.access_mask, &state.share_access, NULL);
2011 conflict = share_conflict(
2017 DBG_DEBUG("No conflict due to share_mode_flags access\n");
2018 return NT_STATUS_OK;
2021 state = (struct open_mode_check_state) {
2023 .share_access = (FILE_SHARE_READ|
2029 * Walk the share mode array to recalculate d->flags
2032 ok = share_mode_forall_entries(lck, open_mode_check_fn, &state);
2034 DBG_DEBUG("share_mode_forall_entries failed\n");
2035 return NT_STATUS_INTERNAL_ERROR;
2038 share_mode_flags_set(
2046 * We only end up here if we had a sharing violation
2047 * from d->flags and have recalculated it.
2049 return NT_STATUS_SHARING_VIOLATION;
2052 conflict = share_conflict(
2058 DBG_DEBUG("No conflict due to share_mode_flags access\n");
2059 return NT_STATUS_OK;
2062 return NT_STATUS_SHARING_VIOLATION;
2066 * Send a break message to the oplock holder and delay the open for
2070 NTSTATUS send_break_message(struct messaging_context *msg_ctx,
2071 const struct file_id *id,
2072 const struct share_mode_entry *exclusive,
2075 struct oplock_break_message msg = {
2077 .share_file_id = exclusive->share_file_id,
2078 .break_to = break_to,
2080 enum ndr_err_code ndr_err;
2085 struct server_id_buf buf;
2086 DBG_DEBUG("Sending break message to %s\n",
2087 server_id_str_buf(exclusive->pid, &buf));
2088 NDR_PRINT_DEBUG(oplock_break_message, &msg);
2091 ndr_err = ndr_push_struct_blob(
2095 (ndr_push_flags_fn_t)ndr_push_oplock_break_message);
2096 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2097 DBG_WARNING("ndr_push_oplock_break_message failed: %s\n",
2098 ndr_errstr(ndr_err));
2099 return ndr_map_error2ntstatus(ndr_err);
2102 status = messaging_send(
2103 msg_ctx, exclusive->pid, MSG_SMB_BREAK_REQUEST, &blob);
2104 TALLOC_FREE(blob.data);
2105 if (!NT_STATUS_IS_OK(status)) {
2106 DEBUG(3, ("Could not send oplock break message: %s\n",
2107 nt_errstr(status)));
2113 struct validate_oplock_types_state {
2119 uint32_t num_non_stat_opens;
2122 static bool validate_oplock_types_fn(
2123 struct share_mode_entry *e,
2127 struct validate_oplock_types_state *state = private_data;
2129 if (e->op_mid == 0) {
2130 /* INTERNAL_OPEN_ONLY */
2134 if (e->op_type == NO_OPLOCK && is_oplock_stat_open(e->access_mask)) {
2136 * We ignore stat opens in the table - they always
2137 * have NO_OPLOCK and never get or cause breaks. JRA.
2142 state->num_non_stat_opens += 1;
2144 if (BATCH_OPLOCK_TYPE(e->op_type)) {
2145 /* batch - can only be one. */
2146 if (share_entry_stale_pid(e)) {
2147 DBG_DEBUG("Found stale batch oplock\n");
2150 if (state->ex_or_batch ||
2154 DBG_ERR("Bad batch oplock entry\n");
2155 state->valid = false;
2158 state->batch = true;
2161 if (EXCLUSIVE_OPLOCK_TYPE(e->op_type)) {
2162 if (share_entry_stale_pid(e)) {
2163 DBG_DEBUG("Found stale duplicate oplock\n");
2166 /* Exclusive or batch - can only be one. */
2167 if (state->ex_or_batch ||
2170 DBG_ERR("Bad exclusive or batch oplock entry\n");
2171 state->valid = false;
2174 state->ex_or_batch = true;
2177 if (LEVEL_II_OPLOCK_TYPE(e->op_type)) {
2178 if (state->batch || state->ex_or_batch) {
2179 if (share_entry_stale_pid(e)) {
2180 DBG_DEBUG("Found stale LevelII oplock\n");
2183 DBG_DEBUG("Bad levelII oplock entry\n");
2184 state->valid = false;
2187 state->level2 = true;
2190 if (e->op_type == NO_OPLOCK) {
2191 if (state->batch || state->ex_or_batch) {
2192 if (share_entry_stale_pid(e)) {
2193 DBG_DEBUG("Found stale NO_OPLOCK entry\n");
2196 DBG_ERR("Bad no oplock entry\n");
2197 state->valid = false;
2200 state->no_oplock = true;
2207 * Do internal consistency checks on the share mode for a file.
2210 static bool validate_oplock_types(struct share_mode_lock *lck)
2212 struct validate_oplock_types_state state = { .valid = true };
2213 static bool skip_validation;
2217 if (skip_validation) {
2221 validate = lp_parm_bool(-1, "smbd", "validate_oplock_types", false);
2223 DBG_DEBUG("smbd:validate_oplock_types not set to yes\n");
2224 skip_validation = true;
2228 ok = share_mode_forall_entries(lck, validate_oplock_types_fn, &state);
2230 DBG_DEBUG("share_mode_forall_entries failed\n");
2234 DBG_DEBUG("Got invalid oplock configuration\n");
2238 if ((state.batch || state.ex_or_batch) &&
2239 (state.num_non_stat_opens != 1)) {
2240 DBG_WARNING("got batch (%d) or ex (%d) non-exclusively "
2243 (int)state.ex_or_batch,
2244 state.num_non_stat_opens);
2251 static bool is_same_lease(const files_struct *fsp,
2252 const struct share_mode_entry *e,
2253 const struct smb2_lease *lease)
2255 if (e->op_type != LEASE_OPLOCK) {
2258 if (lease == NULL) {
2262 return smb2_lease_equal(fsp_client_guid(fsp),
2268 static bool file_has_brlocks(files_struct *fsp)
2270 struct byte_range_lock *br_lck;
2272 br_lck = brl_get_locks_readonly(fsp);
2276 return (brl_num_locks(br_lck) > 0);
2279 struct fsp_lease *find_fsp_lease(struct files_struct *new_fsp,
2280 const struct smb2_lease_key *key,
2281 uint32_t current_state,
2282 uint16_t lease_version,
2283 uint16_t lease_epoch)
2285 struct files_struct *fsp;
2288 * TODO: Measure how expensive this loop is with thousands of open
2292 for (fsp = file_find_di_first(new_fsp->conn->sconn, new_fsp->file_id, true);
2294 fsp = file_find_di_next(fsp, true)) {
2296 if (fsp == new_fsp) {
2299 if (fsp->oplock_type != LEASE_OPLOCK) {
2302 if (smb2_lease_key_equal(&fsp->lease->lease.lease_key, key)) {
2303 fsp->lease->ref_count += 1;
2308 /* Not found - must be leased in another smbd. */
2309 new_fsp->lease = talloc_zero(new_fsp->conn->sconn, struct fsp_lease);
2310 if (new_fsp->lease == NULL) {
2313 new_fsp->lease->ref_count = 1;
2314 new_fsp->lease->sconn = new_fsp->conn->sconn;
2315 new_fsp->lease->lease.lease_key = *key;
2316 new_fsp->lease->lease.lease_state = current_state;
2318 * We internally treat all leases as V2 and update
2319 * the epoch, but when sending breaks it matters if
2320 * the requesting lease was v1 or v2.
2322 new_fsp->lease->lease.lease_version = lease_version;
2323 new_fsp->lease->lease.lease_epoch = lease_epoch;
2324 return new_fsp->lease;
2327 static NTSTATUS try_lease_upgrade(struct files_struct *fsp,
2328 struct share_mode_lock *lck,
2329 const struct GUID *client_guid,
2330 const struct smb2_lease *lease,
2334 uint32_t current_state, breaking_to_requested, breaking_to_required;
2336 uint16_t lease_version, epoch;
2337 uint32_t existing, requested;
2340 status = leases_db_get(
2346 &breaking_to_requested,
2347 &breaking_to_required,
2350 if (!NT_STATUS_IS_OK(status)) {
2354 fsp->lease = find_fsp_lease(
2360 if (fsp->lease == NULL) {
2361 DEBUG(1, ("Did not find existing lease for file %s\n",
2363 return NT_STATUS_NO_MEMORY;
2367 * Upgrade only if the requested lease is a strict upgrade.
2369 existing = current_state;
2370 requested = lease->lease_state;
2373 * Tricky: This test makes sure that "requested" is a
2374 * strict bitwise superset of "existing".
2376 do_upgrade = ((existing & requested) == existing);
2379 * Upgrade only if there's a change.
2381 do_upgrade &= (granted != existing);
2384 * Upgrade only if other leases don't prevent what was asked
2387 do_upgrade &= (granted == requested);
2390 * only upgrade if we are not in breaking state
2392 do_upgrade &= !breaking;
2394 DEBUG(10, ("existing=%"PRIu32", requested=%"PRIu32", "
2395 "granted=%"PRIu32", do_upgrade=%d\n",
2396 existing, requested, granted, (int)do_upgrade));
2399 NTSTATUS set_status;
2401 current_state = granted;
2404 set_status = leases_db_set(
2409 breaking_to_requested,
2410 breaking_to_required,
2414 if (!NT_STATUS_IS_OK(set_status)) {
2415 DBG_DEBUG("leases_db_set failed: %s\n",
2416 nt_errstr(set_status));
2421 fsp_lease_update(fsp);
2423 return NT_STATUS_OK;
2426 static NTSTATUS grant_new_fsp_lease(struct files_struct *fsp,
2427 struct share_mode_lock *lck,
2428 const struct GUID *client_guid,
2429 const struct smb2_lease *lease,
2434 fsp->lease = talloc_zero(fsp->conn->sconn, struct fsp_lease);
2435 if (fsp->lease == NULL) {
2436 return NT_STATUS_INSUFFICIENT_RESOURCES;
2438 fsp->lease->ref_count = 1;
2439 fsp->lease->sconn = fsp->conn->sconn;
2440 fsp->lease->lease.lease_version = lease->lease_version;
2441 fsp->lease->lease.lease_key = lease->lease_key;
2442 fsp->lease->lease.lease_state = granted;
2443 fsp->lease->lease.lease_epoch = lease->lease_epoch + 1;
2445 status = leases_db_add(client_guid,
2448 fsp->lease->lease.lease_state,
2449 fsp->lease->lease.lease_version,
2450 fsp->lease->lease.lease_epoch,
2451 fsp->conn->connectpath,
2452 fsp->fsp_name->base_name,
2453 fsp->fsp_name->stream_name);
2454 if (!NT_STATUS_IS_OK(status)) {
2455 DEBUG(10, ("%s: leases_db_add failed: %s\n", __func__,
2456 nt_errstr(status)));
2457 TALLOC_FREE(fsp->lease);
2458 return NT_STATUS_INSUFFICIENT_RESOURCES;
2462 * We used to set lck->data->modified=true here without
2463 * actually modifying lck->data, triggering a needless
2464 * writeback of lck->data.
2466 * Apart from that writeback, setting modified=true has the
2467 * effect of triggering all waiters for this file to
2468 * retry. This only makes sense if any blocking condition
2469 * (i.e. waiting for a lease to be downgraded or removed) is
2470 * gone. This routine here only adds a lease, so it will never
2471 * free up resources that blocked waiters can now claim. So
2472 * that second effect also does not matter in this
2473 * routine. Thus setting lck->data->modified=true does not
2474 * need to be done here.
2477 return NT_STATUS_OK;
2480 static NTSTATUS grant_fsp_lease(struct files_struct *fsp,
2481 struct share_mode_lock *lck,
2482 const struct smb2_lease *lease,
2485 const struct GUID *client_guid = fsp_client_guid(fsp);
2488 status = try_lease_upgrade(fsp, lck, client_guid, lease, granted);
2490 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
2491 status = grant_new_fsp_lease(
2492 fsp, lck, client_guid, lease, granted);
2498 static int map_lease_type_to_oplock(uint32_t lease_type)
2500 int result = NO_OPLOCK;
2502 switch (lease_type) {
2503 case SMB2_LEASE_READ|SMB2_LEASE_WRITE|SMB2_LEASE_HANDLE:
2504 result = BATCH_OPLOCK|EXCLUSIVE_OPLOCK;
2506 case SMB2_LEASE_READ|SMB2_LEASE_WRITE:
2507 result = EXCLUSIVE_OPLOCK;
2509 case SMB2_LEASE_READ|SMB2_LEASE_HANDLE:
2510 case SMB2_LEASE_READ:
2511 result = LEVEL_II_OPLOCK;
2518 struct delay_for_oplock_state {
2519 struct files_struct *fsp;
2520 const struct smb2_lease *lease;
2521 bool will_overwrite;
2522 uint32_t delay_mask;
2523 bool first_open_attempt;
2524 bool got_handle_lease;
2526 bool have_other_lease;
2527 uint32_t total_lease_types;
2531 static bool delay_for_oplock_fn(
2532 struct share_mode_entry *e,
2536 struct delay_for_oplock_state *state = private_data;
2537 struct files_struct *fsp = state->fsp;
2538 const struct smb2_lease *lease = state->lease;
2539 bool e_is_lease = (e->op_type == LEASE_OPLOCK);
2540 uint32_t e_lease_type = SMB2_LEASE_NONE;
2542 bool lease_is_breaking = false;
2547 if (lease != NULL) {
2548 bool our_lease = is_same_lease(fsp, e, lease);
2550 DBG_DEBUG("Ignoring our own lease\n");
2555 status = leases_db_get(
2559 &e_lease_type, /* current_state */
2561 NULL, /* breaking_to_requested */
2562 NULL, /* breaking_to_required */
2563 NULL, /* lease_version */
2567 * leases_db_get() can return NT_STATUS_NOT_FOUND
2568 * if the share_mode_entry e is stale and the
2569 * lease record was already removed. In this case return
2570 * false so the traverse continues.
2573 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND) &&
2574 share_entry_stale_pid(e))
2576 struct GUID_txt_buf guid_strbuf;
2577 struct file_id_buf file_id_strbuf;
2578 DBG_DEBUG("leases_db_get for client_guid [%s] "
2579 "lease_key [%"PRIu64"/%"PRIu64"] "
2580 "file_id [%s] failed for stale "
2581 "share_mode_entry\n",
2582 GUID_buf_string(&e->client_guid, &guid_strbuf),
2583 e->lease_key.data[0],
2584 e->lease_key.data[1],
2585 file_id_str_buf(fsp->file_id, &file_id_strbuf));
2588 if (!NT_STATUS_IS_OK(status)) {
2589 struct GUID_txt_buf guid_strbuf;
2590 struct file_id_buf file_id_strbuf;
2591 DBG_ERR("leases_db_get for client_guid [%s] "
2592 "lease_key [%"PRIu64"/%"PRIu64"] "
2593 "file_id [%s] failed: %s\n",
2594 GUID_buf_string(&e->client_guid, &guid_strbuf),
2595 e->lease_key.data[0],
2596 e->lease_key.data[1],
2597 file_id_str_buf(fsp->file_id, &file_id_strbuf),
2599 smb_panic("leases_db_get() failed");
2602 e_lease_type = get_lease_type(e, fsp->file_id);
2605 if (((e_lease_type & ~state->total_lease_types) != 0) &&
2606 !share_entry_stale_pid(e))
2608 state->total_lease_types |= e_lease_type;
2611 if (!state->got_handle_lease &&
2612 ((e_lease_type & SMB2_LEASE_HANDLE) != 0) &&
2613 !share_entry_stale_pid(e)) {
2614 state->got_handle_lease = true;
2617 if (!state->got_oplock &&
2618 (e->op_type != LEASE_OPLOCK) &&
2619 !share_entry_stale_pid(e)) {
2620 state->got_oplock = true;
2623 if (!state->have_other_lease &&
2624 !is_same_lease(fsp, e, lease) &&
2625 !share_entry_stale_pid(e)) {
2626 state->have_other_lease = true;
2629 if (e_is_lease && is_lease_stat_open(fsp->access_mask)) {
2633 break_to = e_lease_type & ~state->delay_mask;
2635 if (state->will_overwrite) {
2636 break_to &= ~(SMB2_LEASE_HANDLE|SMB2_LEASE_READ);
2639 DBG_DEBUG("e_lease_type %u, will_overwrite: %u\n",
2640 (unsigned)e_lease_type,
2641 (unsigned)state->will_overwrite);
2643 if ((e_lease_type & ~break_to) == 0) {
2644 if (lease_is_breaking) {
2645 state->delay = true;
2650 if (share_entry_stale_pid(e)) {
2654 if (state->will_overwrite) {
2656 * If we break anyway break to NONE directly.
2657 * Otherwise vfs_set_filelen() will trigger the
2660 break_to &= ~(SMB2_LEASE_READ|SMB2_LEASE_WRITE);
2665 * Oplocks only support breaking to R or NONE.
2667 break_to &= ~(SMB2_LEASE_HANDLE|SMB2_LEASE_WRITE);
2670 DBG_DEBUG("breaking from %d to %d\n",
2674 fsp->conn->sconn->msg_ctx, &fsp->file_id, e, break_to);
2675 if (e_lease_type & state->delay_mask) {
2676 state->delay = true;
2678 if (lease_is_breaking && !state->first_open_attempt) {
2679 state->delay = true;
2685 static NTSTATUS delay_for_oplock(files_struct *fsp,
2687 const struct smb2_lease *lease,
2688 struct share_mode_lock *lck,
2689 bool have_sharing_violation,
2690 uint32_t create_disposition,
2691 bool first_open_attempt,
2695 struct delay_for_oplock_state state = {
2698 .first_open_attempt = first_open_attempt,
2705 *poplock_type = NO_OPLOCK;
2708 if (fsp->fsp_flags.is_directory) {
2710 * No directory leases yet
2712 SMB_ASSERT(oplock_request == NO_OPLOCK);
2713 if (have_sharing_violation) {
2714 return NT_STATUS_SHARING_VIOLATION;
2716 return NT_STATUS_OK;
2719 if (oplock_request == LEASE_OPLOCK) {
2720 if (lease == NULL) {
2722 * The SMB2 layer should have checked this
2724 return NT_STATUS_INTERNAL_ERROR;
2727 requested = lease->lease_state;
2729 requested = map_oplock_to_lease_type(
2730 oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK);
2733 share_mode_flags_get(lck, NULL, NULL, &state.total_lease_types);
2735 if (is_oplock_stat_open(fsp->access_mask)) {
2739 state.delay_mask = have_sharing_violation ?
2740 SMB2_LEASE_HANDLE : SMB2_LEASE_WRITE;
2742 switch (create_disposition) {
2743 case FILE_SUPERSEDE:
2744 case FILE_OVERWRITE:
2745 case FILE_OVERWRITE_IF:
2746 state.will_overwrite = true;
2749 state.will_overwrite = false;
2753 state.total_lease_types = SMB2_LEASE_NONE;
2754 ok = share_mode_forall_entries(lck, delay_for_oplock_fn, &state);
2756 return NT_STATUS_INTERNAL_ERROR;
2760 return NT_STATUS_RETRY;
2764 if (have_sharing_violation) {
2765 return NT_STATUS_SHARING_VIOLATION;
2768 granted = requested;
2770 if (oplock_request == LEASE_OPLOCK) {
2771 if (lp_kernel_oplocks(SNUM(fsp->conn))) {
2772 DEBUG(10, ("No lease granted because kernel oplocks are enabled\n"));
2773 granted = SMB2_LEASE_NONE;
2775 if ((granted & (SMB2_LEASE_READ|SMB2_LEASE_WRITE)) == 0) {
2776 DEBUG(10, ("No read or write lease requested\n"));
2777 granted = SMB2_LEASE_NONE;
2779 if (granted == SMB2_LEASE_WRITE) {
2780 DEBUG(10, ("pure write lease requested\n"));
2781 granted = SMB2_LEASE_NONE;
2783 if (granted == (SMB2_LEASE_WRITE|SMB2_LEASE_HANDLE)) {
2784 DEBUG(10, ("write and handle lease requested\n"));
2785 granted = SMB2_LEASE_NONE;
2789 if (lp_locking(fsp->conn->params) && file_has_brlocks(fsp)) {
2790 DBG_DEBUG("file %s has byte range locks\n",
2792 granted &= ~SMB2_LEASE_READ;
2795 if (state.have_other_lease) {
2797 * Can grant only one writer
2799 granted &= ~SMB2_LEASE_WRITE;
2802 if ((granted & SMB2_LEASE_READ) && !(granted & SMB2_LEASE_WRITE)) {
2804 (global_client_caps & CAP_LEVEL_II_OPLOCKS) &&
2805 lp_level2_oplocks(SNUM(fsp->conn));
2807 if (!allow_level2) {
2808 granted = SMB2_LEASE_NONE;
2812 if (oplock_request == LEASE_OPLOCK) {
2813 if (state.got_oplock) {
2814 granted &= ~SMB2_LEASE_HANDLE;
2817 oplock_type = LEASE_OPLOCK;
2819 if (state.got_handle_lease) {
2820 granted = SMB2_LEASE_NONE;
2824 * Reflect possible downgrades from:
2825 * - map_lease_type_to_oplock() => "RH" to just LEVEL_II
2827 oplock_type = map_lease_type_to_oplock(granted);
2828 granted = map_oplock_to_lease_type(oplock_type);
2831 state.total_lease_types |= granted;
2834 uint32_t acc, sh, ls;
2835 share_mode_flags_get(lck, &acc, &sh, &ls);
2836 ls = state.total_lease_types;
2837 share_mode_flags_set(lck, acc, sh, ls, NULL);
2840 DBG_DEBUG("oplock type 0x%x granted (%s%s%s)(0x%x), on file %s, "
2841 "requested 0x%x (%s%s%s)(0x%x) => total (%s%s%s)(0x%x)\n",
2843 granted & SMB2_LEASE_READ ? "R":"",
2844 granted & SMB2_LEASE_WRITE ? "W":"",
2845 granted & SMB2_LEASE_HANDLE ? "H":"",
2849 requested & SMB2_LEASE_READ ? "R":"",
2850 requested & SMB2_LEASE_WRITE ? "W":"",
2851 requested & SMB2_LEASE_HANDLE ? "H":"",
2853 state.total_lease_types & SMB2_LEASE_READ ? "R":"",
2854 state.total_lease_types & SMB2_LEASE_WRITE ? "W":"",
2855 state.total_lease_types & SMB2_LEASE_HANDLE ? "H":"",
2856 state.total_lease_types);
2858 *poplock_type = oplock_type;
2859 *pgranted = granted;
2860 return NT_STATUS_OK;
2863 static NTSTATUS handle_share_mode_lease(
2865 struct share_mode_lock *lck,
2866 uint32_t create_disposition,
2867 uint32_t access_mask,
2868 uint32_t share_access,
2870 const struct smb2_lease *lease,
2871 bool first_open_attempt,
2875 bool sharing_violation = false;
2878 *poplock_type = NO_OPLOCK;
2881 status = open_mode_check(
2882 fsp->conn, fsp->file_id, lck, access_mask, share_access);
2883 if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
2884 sharing_violation = true;
2885 status = NT_STATUS_OK; /* handled later */
2888 if (!NT_STATUS_IS_OK(status)) {
2892 if (oplock_request == INTERNAL_OPEN_ONLY) {
2893 if (sharing_violation) {
2894 DBG_DEBUG("Sharing violation for internal open\n");
2895 return NT_STATUS_SHARING_VIOLATION;
2899 * Internal opens never do oplocks or leases. We don't
2900 * need to go through delay_for_oplock().
2902 return NT_STATUS_OK;
2905 status = delay_for_oplock(
2915 if (!NT_STATUS_IS_OK(status)) {
2919 return NT_STATUS_OK;
2922 static bool request_timed_out(struct smb_request *req, struct timeval timeout)
2924 struct timeval now, end_time;
2926 end_time = timeval_sum(&req->request_time, &timeout);
2927 return (timeval_compare(&end_time, &now) < 0);
2930 struct defer_open_state {
2931 struct smbXsrv_connection *xconn;
2935 static void defer_open_done(struct tevent_req *req);
2938 * Defer an open and watch a locking.tdb record
2940 * This defers an open that gets rescheduled once the locking.tdb record watch
2941 * is triggered by a change to the record.
2943 * It is used to defer opens that triggered an oplock break and for the SMB1
2944 * sharing violation delay.
2946 static void defer_open(struct share_mode_lock *lck,
2947 struct timeval timeout,
2948 struct smb_request *req,
2951 struct deferred_open_record *open_rec = NULL;
2952 struct timeval abs_timeout;
2953 struct defer_open_state *watch_state;
2954 struct tevent_req *watch_req;
2955 struct timeval_buf tvbuf1, tvbuf2;
2956 struct file_id_buf fbuf;
2959 abs_timeout = timeval_sum(&req->request_time, &timeout);
2961 DBG_DEBUG("request time [%s] timeout [%s] mid [%" PRIu64 "] "
2963 timeval_str_buf(&req->request_time, false, true, &tvbuf1),
2964 timeval_str_buf(&abs_timeout, false, true, &tvbuf2),
2966 file_id_str_buf(id, &fbuf));
2968 open_rec = talloc_zero(NULL, struct deferred_open_record);
2969 if (open_rec == NULL) {
2971 exit_server("talloc failed");
2974 watch_state = talloc(open_rec, struct defer_open_state);
2975 if (watch_state == NULL) {
2976 exit_server("talloc failed");
2978 watch_state->xconn = req->xconn;
2979 watch_state->mid = req->mid;
2981 DBG_DEBUG("defering mid %" PRIu64 "\n", req->mid);
2983 watch_req = share_mode_watch_send(
2987 (struct server_id){0});
2988 if (watch_req == NULL) {
2989 exit_server("Could not watch share mode record");
2991 tevent_req_set_callback(watch_req, defer_open_done, watch_state);
2993 ok = tevent_req_set_endtime(watch_req, req->sconn->ev_ctx, abs_timeout);
2995 exit_server("tevent_req_set_endtime failed");
2998 ok = push_deferred_open_message_smb(req, timeout, id, open_rec);
3001 exit_server("push_deferred_open_message_smb failed");
3005 static void defer_open_done(struct tevent_req *req)
3007 struct defer_open_state *state = tevent_req_callback_data(
3008 req, struct defer_open_state);
3012 status = share_mode_watch_recv(req, NULL, NULL);
3014 if (!NT_STATUS_IS_OK(status)) {
3015 DEBUG(5, ("dbwrap_watched_watch_recv returned %s\n",
3016 nt_errstr(status)));
3018 * Even if it failed, retry anyway. TODO: We need a way to
3019 * tell a re-scheduled open about that error.
3023 DEBUG(10, ("scheduling mid %llu\n", (unsigned long long)state->mid));
3025 ret = schedule_deferred_open_message_smb(state->xconn, state->mid);
3031 * Actually attempt the kernel oplock polling open.
3034 static void poll_open_fn(struct tevent_context *ev,
3035 struct tevent_timer *te,
3036 struct timeval current_time,
3039 struct deferred_open_record *open_rec = talloc_get_type_abort(
3040 private_data, struct deferred_open_record);
3043 TALLOC_FREE(open_rec->watch_req);
3045 ok = schedule_deferred_open_message_smb(
3046 open_rec->xconn, open_rec->mid);
3048 exit_server("schedule_deferred_open_message_smb failed");
3050 DBG_DEBUG("timer fired. Retrying open !\n");
3053 static void poll_open_done(struct tevent_req *subreq);
3055 struct poll_open_setup_watcher_state {
3056 TALLOC_CTX *mem_ctx;
3057 struct tevent_context *ev_ctx;
3058 struct tevent_req *watch_req;
3061 static void poll_open_setup_watcher_fn(struct share_mode_lock *lck,
3064 struct poll_open_setup_watcher_state *state =
3065 (struct poll_open_setup_watcher_state *)private_data;
3067 if (!validate_oplock_types(lck)) {
3068 smb_panic("validate_oplock_types failed");
3071 state->watch_req = share_mode_watch_send(
3075 (struct server_id) {0});
3076 if (state->watch_req == NULL) {
3077 DBG_WARNING("share_mode_watch_send failed\n");
3083 * Reschedule an open for 1 second from now, if not timed out.
3085 static bool setup_poll_open(
3086 struct smb_request *req,
3087 const struct file_id *id,
3088 struct timeval max_timeout,
3089 struct timeval interval)
3091 static struct file_id zero_id = {};
3093 struct deferred_open_record *open_rec = NULL;
3094 struct timeval endtime, next_interval;
3095 struct file_id_buf ftmp;
3097 if (request_timed_out(req, max_timeout)) {
3101 open_rec = talloc_zero(NULL, struct deferred_open_record);
3102 if (open_rec == NULL) {
3103 DBG_WARNING("talloc failed\n");
3106 open_rec->xconn = req->xconn;
3107 open_rec->mid = req->mid;
3110 * Make sure open_rec->te does not come later than the
3111 * request's maximum endtime.
3114 endtime = timeval_sum(&req->request_time, &max_timeout);
3115 next_interval = timeval_current_ofs(interval.tv_sec, interval.tv_usec);
3116 next_interval = timeval_min(&endtime, &next_interval);
3118 open_rec->te = tevent_add_timer(
3124 if (open_rec->te == NULL) {
3125 DBG_WARNING("tevent_add_timer failed\n");
3126 TALLOC_FREE(open_rec);
3131 struct poll_open_setup_watcher_state wstate = {
3132 .mem_ctx = open_rec,
3133 .ev_ctx = req->sconn->ev_ctx,
3137 status = share_mode_do_locked_vfs_denied(*id,
3138 poll_open_setup_watcher_fn,
3140 if (NT_STATUS_IS_OK(status)) {
3141 if (wstate.watch_req == NULL) {
3142 DBG_WARNING("share_mode_watch_send failed\n");
3143 TALLOC_FREE(open_rec);
3146 open_rec->watch_req = wstate.watch_req;
3147 tevent_req_set_callback(open_rec->watch_req,
3150 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
3151 DBG_WARNING("share_mode_do_locked_vfs_denied failed - %s\n",
3153 TALLOC_FREE(open_rec);
3160 ok = push_deferred_open_message_smb(req, max_timeout, *id, open_rec);
3162 DBG_WARNING("push_deferred_open_message_smb failed\n");
3163 TALLOC_FREE(open_rec);
3167 DBG_DEBUG("poll request time [%s] mid [%" PRIu64 "] file_id [%s]\n",
3168 timeval_string(talloc_tos(), &req->request_time, false),
3170 file_id_str_buf(*id, &ftmp));
3175 static void poll_open_done(struct tevent_req *subreq)
3177 struct deferred_open_record *open_rec = tevent_req_callback_data(
3178 subreq, struct deferred_open_record);
3182 status = share_mode_watch_recv(subreq, NULL, NULL);
3183 TALLOC_FREE(subreq);
3184 open_rec->watch_req = NULL;
3185 TALLOC_FREE(open_rec->te);
3187 DBG_DEBUG("dbwrap_watched_watch_recv returned %s\n",
3190 ok = schedule_deferred_open_message_smb(
3191 open_rec->xconn, open_rec->mid);
3193 exit_server("schedule_deferred_open_message_smb failed");
3197 bool defer_smb1_sharing_violation(struct smb_request *req)
3202 if (!lp_defer_sharing_violations()) {
3207 * Try every 200msec up to (by default) one second. To be
3208 * precise, according to behaviour note <247> in [MS-CIFS],
3209 * the server tries 5 times. But up to one second should be
3213 timeout_usecs = lp_parm_int(
3217 SHARING_VIOLATION_USEC_WAIT);
3219 ok = setup_poll_open(
3222 (struct timeval) { .tv_usec = timeout_usecs },
3223 (struct timeval) { .tv_usec = 200000 });
3227 /****************************************************************************
3228 On overwrite open ensure that the attributes match.
3229 ****************************************************************************/
3231 static bool open_match_attributes(connection_struct *conn,
3232 uint32_t old_dos_attr,
3233 uint32_t new_dos_attr,
3234 mode_t new_unx_mode,
3235 mode_t *returned_unx_mode)
3237 uint32_t noarch_old_dos_attr, noarch_new_dos_attr;
3239 noarch_old_dos_attr = (old_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
3240 noarch_new_dos_attr = (new_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
3242 if((noarch_old_dos_attr == 0 && noarch_new_dos_attr != 0) ||
3243 (noarch_old_dos_attr != 0 && ((noarch_old_dos_attr & noarch_new_dos_attr) == noarch_old_dos_attr))) {
3244 *returned_unx_mode = new_unx_mode;
3246 *returned_unx_mode = (mode_t)0;
3249 DEBUG(10,("open_match_attributes: old_dos_attr = 0x%x, "
3250 "new_dos_attr = 0x%x "
3251 "returned_unx_mode = 0%o\n",
3252 (unsigned int)old_dos_attr,
3253 (unsigned int)new_dos_attr,
3254 (unsigned int)*returned_unx_mode ));
3256 /* If we're mapping SYSTEM and HIDDEN ensure they match. */
3257 if (lp_map_system(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
3258 if ((old_dos_attr & FILE_ATTRIBUTE_SYSTEM) &&
3259 !(new_dos_attr & FILE_ATTRIBUTE_SYSTEM)) {
3263 if (lp_map_hidden(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
3264 if ((old_dos_attr & FILE_ATTRIBUTE_HIDDEN) &&
3265 !(new_dos_attr & FILE_ATTRIBUTE_HIDDEN)) {
3272 static void schedule_defer_open(struct share_mode_lock *lck,
3274 struct smb_request *req)
3276 /* This is a relative time, added to the absolute
3277 request_time value to get the absolute timeout time.
3278 Note that if this is the second or greater time we enter
3279 this codepath for this particular request mid then
3280 request_time is left as the absolute time of the *first*
3281 time this request mid was processed. This is what allows
3282 the request to eventually time out. */
3284 struct timeval timeout;
3286 /* Normally the smbd we asked should respond within
3287 * OPLOCK_BREAK_TIMEOUT seconds regardless of whether
3288 * the client did, give twice the timeout as a safety
3289 * measure here in case the other smbd is stuck
3290 * somewhere else. */
3292 timeout = timeval_set(OPLOCK_BREAK_TIMEOUT*2, 0);
3294 if (request_timed_out(req, timeout)) {
3298 defer_open(lck, timeout, req, id);
3301 /****************************************************************************
3302 Reschedule an open call that went asynchronous.
3303 ****************************************************************************/
3305 static void schedule_async_open_timer(struct tevent_context *ev,
3306 struct tevent_timer *te,
3307 struct timeval current_time,
3310 exit_server("async open timeout");
3313 static void schedule_async_open(struct smb_request *req)
3315 struct deferred_open_record *open_rec = NULL;
3316 struct timeval timeout = timeval_set(20, 0);
3319 if (request_timed_out(req, timeout)) {
3323 open_rec = talloc_zero(NULL, struct deferred_open_record);
3324 if (open_rec == NULL) {
3325 exit_server("deferred_open_record_create failed");
3327 open_rec->async_open = true;
3329 ok = push_deferred_open_message_smb(
3330 req, timeout, (struct file_id){0}, open_rec);
3332 exit_server("push_deferred_open_message_smb failed");
3335 open_rec->te = tevent_add_timer(req->sconn->ev_ctx,
3337 timeval_current_ofs(20, 0),
3338 schedule_async_open_timer,
3340 if (open_rec->te == NULL) {
3341 exit_server("tevent_add_timer failed");
3345 static NTSTATUS check_and_store_share_mode(
3346 struct files_struct *fsp,
3347 struct smb_request *req,
3348 struct share_mode_lock *lck,
3349 uint32_t create_disposition,
3350 uint32_t access_mask,
3351 uint32_t share_access,
3353 const struct smb2_lease *lease,
3354 bool first_open_attempt)
3357 int oplock_type = NO_OPLOCK;
3358 uint32_t granted_lease = 0;
3359 const struct smb2_lease_key *lease_key = NULL;
3360 bool delete_on_close;
3363 /* Get the types we need to examine. */
3364 if (!validate_oplock_types(lck)) {
3365 smb_panic("validate_oplock_types failed");
3368 delete_on_close = has_delete_on_close(lck, fsp->name_hash);
3369 if (delete_on_close) {
3370 return NT_STATUS_DELETE_PENDING;
3373 status = handle_share_mode_lease(fsp,
3383 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
3384 schedule_defer_open(lck, fsp->file_id, req);
3385 return NT_STATUS_SHARING_VIOLATION;
3387 if (!NT_STATUS_IS_OK(status)) {
3391 if (oplock_type == LEASE_OPLOCK) {
3392 lease_key = &lease->lease_key;
3395 share_mode_flags_restrict(lck, access_mask, share_access, 0);
3397 ok = set_share_mode(lck,
3399 get_current_uid(fsp->conn),
3406 return NT_STATUS_NO_MEMORY;
3409 if (oplock_type == LEASE_OPLOCK) {
3410 status = grant_fsp_lease(fsp, lck, lease, granted_lease);
3411 if (!NT_STATUS_IS_OK(status)) {
3412 del_share_mode(lck, fsp);
3416 DBG_DEBUG("lease_state=%d\n", fsp->lease->lease.lease_state);
3419 fsp->oplock_type = oplock_type;
3421 return NT_STATUS_OK;
3424 /****************************************************************************
3425 Work out what access_mask to use from what the client sent us.
3426 ****************************************************************************/
3428 static NTSTATUS smbd_calculate_maximum_allowed_access_fsp(
3429 struct files_struct *dirfsp,
3430 struct files_struct *fsp,
3432 uint32_t *p_access_mask)
3434 struct security_descriptor *sd = NULL;
3435 uint32_t access_granted = 0;
3439 /* Cope with symlinks */
3440 if (fsp == NULL || fsp_get_pathref_fd(fsp) == -1) {
3441 *p_access_mask = FILE_GENERIC_ALL;
3442 return NT_STATUS_OK;
3445 /* Cope with fake/printer fsp's. */
3446 if (fsp->fake_file_handle != NULL || fsp->print_file != NULL) {
3447 *p_access_mask = FILE_GENERIC_ALL;
3448 return NT_STATUS_OK;
3451 if (!use_privs && (get_current_uid(fsp->conn) == (uid_t)0)) {
3452 *p_access_mask |= FILE_GENERIC_ALL;
3453 return NT_STATUS_OK;
3456 status = SMB_VFS_FGET_NT_ACL(metadata_fsp(fsp),
3463 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
3465 * File did not exist
3467 *p_access_mask = FILE_GENERIC_ALL;
3468 return NT_STATUS_OK;
3470 if (!NT_STATUS_IS_OK(status)) {
3471 DBG_ERR("Could not get acl on file %s: %s\n",
3478 * If we can access the path to this file, by
3479 * default we have FILE_READ_ATTRIBUTES from the
3480 * containing directory. See the section:
3481 * "Algorithm to Check Access to an Existing File"
3484 * se_file_access_check()
3485 * also takes care of owner WRITE_DAC and READ_CONTROL.
3487 status = se_file_access_check(sd,
3488 get_current_nttok(fsp->conn),
3490 (*p_access_mask & ~FILE_READ_ATTRIBUTES),
3495 if (!NT_STATUS_IS_OK(status)) {
3496 DBG_ERR("Status %s on file %s: "
3497 "when calculating maximum access\n",
3503 *p_access_mask = (access_granted | FILE_READ_ATTRIBUTES);
3505 if (!(access_granted & DELETE_ACCESS)) {
3506 if (can_delete_file_in_directory(fsp->conn,
3509 *p_access_mask |= DELETE_ACCESS;
3513 dosattrs = fdos_mode(fsp);
3514 if (IS_DOS_READONLY(dosattrs) || !CAN_WRITE(fsp->conn)) {
3515 *p_access_mask &= ~(FILE_GENERIC_WRITE | DELETE_ACCESS);
3518 return NT_STATUS_OK;
3521 NTSTATUS smbd_calculate_access_mask_fsp(struct files_struct *dirfsp,
3522 struct files_struct *fsp,
3524 uint32_t access_mask,
3525 uint32_t *access_mask_out)
3528 uint32_t orig_access_mask = access_mask;
3529 uint32_t rejected_share_access;
3531 if (access_mask & SEC_MASK_INVALID) {
3532 DBG_DEBUG("access_mask [%8x] contains invalid bits\n",
3534 return NT_STATUS_ACCESS_DENIED;
3538 * Convert GENERIC bits to specific bits.
3541 se_map_generic(&access_mask, &file_generic_mapping);
3543 /* Calculate MAXIMUM_ALLOWED_ACCESS if requested. */
3544 if (access_mask & MAXIMUM_ALLOWED_ACCESS) {
3546 status = smbd_calculate_maximum_allowed_access_fsp(
3552 if (!NT_STATUS_IS_OK(status)) {
3556 access_mask &= fsp->conn->share_access;
3559 rejected_share_access = access_mask & ~(fsp->conn->share_access);
3561 if (rejected_share_access) {
3562 DBG_INFO("Access denied on file %s: "
3563 "rejected by share access mask[0x%08X] "
3564 "orig[0x%08X] mapped[0x%08X] reject[0x%08X]\n",
3566 fsp->conn->share_access,
3567 orig_access_mask, access_mask,
3568 rejected_share_access);
3569 return NT_STATUS_ACCESS_DENIED;
3572 *access_mask_out = access_mask;
3573 return NT_STATUS_OK;
3576 /****************************************************************************
3577 Remove the deferred open entry under lock.
3578 ****************************************************************************/
3580 /****************************************************************************
3581 Return true if this is a state pointer to an asynchronous create.
3582 ****************************************************************************/
3584 bool is_deferred_open_async(const struct deferred_open_record *rec)
3586 return rec->async_open;
3589 static bool clear_ads(uint32_t create_disposition)
3593 switch (create_disposition) {
3594 case FILE_SUPERSEDE:
3595 case FILE_OVERWRITE_IF:
3596 case FILE_OVERWRITE:
3605 static int disposition_to_open_flags(uint32_t create_disposition)
3610 * Currently we're using FILE_SUPERSEDE as the same as
3611 * FILE_OVERWRITE_IF but they really are
3612 * different. FILE_SUPERSEDE deletes an existing file
3613 * (requiring delete access) then recreates it.
3616 switch (create_disposition) {
3617 case FILE_SUPERSEDE:
3618 case FILE_OVERWRITE_IF:
3620 * If file exists replace/overwrite. If file doesn't
3623 ret = O_CREAT|O_TRUNC;
3628 * If file exists open. If file doesn't exist error.
3633 case FILE_OVERWRITE:
3635 * If file exists overwrite. If file doesn't exist
3643 * If file exists error. If file doesn't exist create.
3645 ret = O_CREAT|O_EXCL;
3650 * If file exists open. If file doesn't exist create.
3658 static int calculate_open_access_flags(uint32_t access_mask,
3659 uint32_t private_flags)
3661 bool need_write, need_read;
3664 * Note that we ignore the append flag as append does not
3665 * mean the same thing under DOS and Unix.
3668 need_write = (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA));
3673 /* DENY_DOS opens are always underlying read-write on the
3674 file handle, no matter what the requested access mask
3678 ((private_flags & NTCREATEX_FLAG_DENY_DOS) ||
3679 access_mask & (FILE_READ_ATTRIBUTES|FILE_READ_DATA|
3680 FILE_READ_EA|FILE_EXECUTE));
3688 struct open_ntcreate_lock_state {
3689 struct share_mode_entry_prepare_state prepare_state;
3690 struct files_struct *fsp;
3691 const char *object_type;
3692 struct smb_request *req;
3693 uint32_t create_disposition;
3694 uint32_t access_mask;
3695 uint32_t share_access;
3697 const struct smb2_lease *lease;
3698 bool first_open_attempt;
3701 struct timespec write_time;
3702 share_mode_entry_prepare_unlock_fn_t cleanup_fn;
3705 static void open_ntcreate_lock_add_entry(struct share_mode_lock *lck,
3709 struct open_ntcreate_lock_state *state =
3710 (struct open_ntcreate_lock_state *)private_data;
3713 * By default drop the g_lock again if we leave the
3716 *keep_locked = false;
3718 state->status = check_and_store_share_mode(state->fsp,
3721 state->create_disposition,
3723 state->share_access,
3724 state->oplock_request,
3726 state->first_open_attempt);
3727 if (!NT_STATUS_IS_OK(state->status)) {
3731 state->write_time = get_share_mode_write_time(lck);
3734 * keep the g_lock while existing the tdb chainlock,
3735 * we we're asked to, which mean we'll keep
3736 * the share_mode_lock during object creation,
3737 * or setting delete on close.
3739 *keep_locked = state->keep_locked;
3742 static void open_ntcreate_lock_cleanup_oplock(struct share_mode_lock *lck,
3745 struct open_ntcreate_lock_state *state =
3746 (struct open_ntcreate_lock_state *)private_data;
3749 ok = remove_share_oplock(lck, state->fsp);
3751 DBG_ERR("Could not remove oplock for %s %s\n",
3752 state->object_type, fsp_str_dbg(state->fsp));
3756 static void open_ntcreate_lock_cleanup_entry(struct share_mode_lock *lck,
3759 struct open_ntcreate_lock_state *state =
3760 (struct open_ntcreate_lock_state *)private_data;
3763 ok = del_share_mode(lck, state->fsp);
3765 DBG_ERR("Could not delete share entry for %s %s\n",
3766 state->object_type, fsp_str_dbg(state->fsp));
3770 /****************************************************************************
3771 Open a file with a share mode. Passed in an already created files_struct *.
3772 ****************************************************************************/
3774 static NTSTATUS open_file_ntcreate(connection_struct *conn,
3775 struct smb_request *req,
3776 uint32_t access_mask, /* access bits (FILE_READ_DATA etc.) */
3777 uint32_t share_access, /* share constants (FILE_SHARE_READ etc) */
3778 uint32_t create_disposition, /* FILE_OPEN_IF etc. */
3779 uint32_t create_options, /* options such as delete on close. */
3780 uint32_t new_dos_attributes, /* attributes used for new file. */
3781 int oplock_request, /* internal Samba oplock codes. */
3782 const struct smb2_lease *lease,
3783 /* Information (FILE_EXISTS etc.) */
3784 uint32_t private_flags, /* Samba specific flags. */
3785 struct smb_filename *parent_dir_fname, /* parent. */
3786 struct smb_filename *smb_fname_atname, /* atname relative to parent. */
3790 struct smb_filename *smb_fname = fsp->fsp_name;
3793 bool file_existed = VALID_STAT(smb_fname->st);
3794 bool def_acl = False;
3795 bool posix_open = False;
3796 bool new_file_created = False;
3797 bool first_open_attempt = true;
3798 NTSTATUS fsp_open = NT_STATUS_ACCESS_DENIED;
3799 mode_t new_unx_mode = (mode_t)0;
3800 mode_t unx_mode = (mode_t)0;
3802 uint32_t existing_dos_attributes = 0;
3803 struct open_ntcreate_lock_state lck_state = {};
3804 bool keep_locked = false;
3805 uint32_t open_access_mask = access_mask;
3807 SMB_STRUCT_STAT saved_stat = smb_fname->st;
3808 struct timespec old_write_time;
3809 bool setup_poll = false;
3812 if (conn->printer) {
3814 * Printers are handled completely differently.
3815 * Most of the passed parameters are ignored.
3819 *pinfo = FILE_WAS_CREATED;
3822 DEBUG(10, ("open_file_ntcreate: printer open fname=%s\n",
3823 smb_fname_str_dbg(smb_fname)));
3826 DEBUG(0,("open_file_ntcreate: printer open without "
3827 "an SMB request!\n"));
3828 return NT_STATUS_INTERNAL_ERROR;
3831 return print_spool_open(fsp, smb_fname->base_name,
3835 if (new_dos_attributes & FILE_FLAG_POSIX_SEMANTICS) {
3837 unx_mode = (mode_t)(new_dos_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
3838 new_dos_attributes = 0;
3840 /* Windows allows a new file to be created and
3841 silently removes a FILE_ATTRIBUTE_DIRECTORY
3842 sent by the client. Do the same. */
3844 new_dos_attributes &= ~FILE_ATTRIBUTE_DIRECTORY;
3846 /* We add FILE_ATTRIBUTE_ARCHIVE to this as this mode is only used if the file is
3848 unx_mode = unix_mode(
3850 new_dos_attributes | FILE_ATTRIBUTE_ARCHIVE,
3852 parent_dir_fname->fsp);
3855 DEBUG(10, ("open_file_ntcreate: fname=%s, dos_attrs=0x%x "
3856 "access_mask=0x%x share_access=0x%x "
3857 "create_disposition = 0x%x create_options=0x%x "
3858 "unix mode=0%o oplock_request=%d private_flags = 0x%x\n",
3859 smb_fname_str_dbg(smb_fname), new_dos_attributes,
3860 access_mask, share_access, create_disposition,
3861 create_options, (unsigned int)unx_mode, oplock_request,
3862 (unsigned int)private_flags));
3865 /* Ensure req == NULL means INTERNAL_OPEN_ONLY */
3866 SMB_ASSERT(oplock_request == INTERNAL_OPEN_ONLY);
3868 /* And req != NULL means no INTERNAL_OPEN_ONLY */
3869 SMB_ASSERT(((oplock_request & INTERNAL_OPEN_ONLY) == 0));
3873 * Only non-internal opens can be deferred at all
3877 struct deferred_open_record *open_rec;
3878 if (get_deferred_open_message_state(req, NULL, &open_rec)) {
3880 /* If it was an async create retry, the file
3883 if (is_deferred_open_async(open_rec)) {
3884 SET_STAT_INVALID(smb_fname->st);
3885 file_existed = false;
3888 /* Ensure we don't reprocess this message. */
3889 remove_deferred_open_message_smb(req->xconn, req->mid);
3891 first_open_attempt = false;
3896 new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
3899 * Only use stored DOS attributes for checks
3900 * against requested attributes (below via
3901 * open_match_attributes()), cf bug #11992
3902 * for details. -slow
3906 status = vfs_fget_dos_attributes(smb_fname->fsp, &attr);
3907 if (NT_STATUS_IS_OK(status)) {
3908 existing_dos_attributes = attr;
3913 /* ignore any oplock requests if oplocks are disabled */
3914 if (!lp_oplocks(SNUM(conn)) ||
3915 IS_VETO_OPLOCK_PATH(conn, smb_fname->base_name)) {
3916 /* Mask off everything except the private Samba bits. */
3917 oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
3920 /* this is for OS/2 long file names - say we don't support them */
3921 if (req != NULL && !req->posix_pathnames &&
3922 strstr(smb_fname->base_name,".+,;=[].")) {
3923 /* OS/2 Workplace shell fix may be main code stream in a later
3925 DEBUG(5,("open_file_ntcreate: OS/2 long filenames are not "
3927 if (use_nt_status()) {
3928 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3930 return NT_STATUS_DOS(ERRDOS, ERRcannotopen);
3933 switch( create_disposition ) {
3935 /* If file exists open. If file doesn't exist error. */
3936 if (!file_existed) {
3937 DEBUG(5,("open_file_ntcreate: FILE_OPEN "
3938 "requested for file %s and file "
3940 smb_fname_str_dbg(smb_fname)));
3941 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3945 case FILE_OVERWRITE:
3946 /* If file exists overwrite. If file doesn't exist
3948 if (!file_existed) {
3949 DEBUG(5,("open_file_ntcreate: FILE_OVERWRITE "
3950 "requested for file %s and file "
3952 smb_fname_str_dbg(smb_fname) ));
3953 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3958 /* If file exists error. If file doesn't exist
3961 DEBUG(5,("open_file_ntcreate: FILE_CREATE "
3962 "requested for file %s and file "
3963 "already exists.\n",
3964 smb_fname_str_dbg(smb_fname)));
3965 if (S_ISDIR(smb_fname->st.st_ex_mode)) {
3966 return NT_STATUS_FILE_IS_A_DIRECTORY;
3968 return NT_STATUS_OBJECT_NAME_COLLISION;
3972 case FILE_SUPERSEDE:
3973 case FILE_OVERWRITE_IF:
3977 return NT_STATUS_INVALID_PARAMETER;
3980 flags2 = disposition_to_open_flags(create_disposition);
3982 /* We only care about matching attributes on file exists and
3985 if (!posix_open && file_existed &&
3986 ((create_disposition == FILE_OVERWRITE) ||
3987 (create_disposition == FILE_OVERWRITE_IF))) {
3988 if (!open_match_attributes(conn, existing_dos_attributes,
3990 unx_mode, &new_unx_mode)) {
3991 DEBUG(5,("open_file_ntcreate: attributes mismatch "
3992 "for file %s (%x %x) (0%o, 0%o)\n",
3993 smb_fname_str_dbg(smb_fname),
3994 existing_dos_attributes,
3996 (unsigned int)smb_fname->st.st_ex_mode,
3997 (unsigned int)unx_mode ));
3998 return NT_STATUS_ACCESS_DENIED;
4002 status = smbd_calculate_access_mask_fsp(parent_dir_fname->fsp,
4007 if (!NT_STATUS_IS_OK(status)) {
4008 DBG_DEBUG("smbd_calculate_access_mask_fsp "
4009 "on file %s returned %s\n",
4010 smb_fname_str_dbg(smb_fname),
4015 open_access_mask = access_mask;
4017 if (flags2 & O_TRUNC) {
4018 open_access_mask |= FILE_WRITE_DATA; /* This will cause oplock breaks. */
4023 * stat opens on existing files don't get oplocks.
4024 * They can get leases.
4026 * Note that we check for stat open on the *open_access_mask*,
4027 * i.e. the access mask we actually used to do the open,
4028 * not the one the client asked for (which is in
4029 * fsp->access_mask). This is due to the fact that
4030 * FILE_OVERWRITE and FILE_OVERWRITE_IF add in O_TRUNC,
4031 * which adds FILE_WRITE_DATA to open_access_mask.
4033 if (is_oplock_stat_open(open_access_mask) && lease == NULL) {
4034 oplock_request = NO_OPLOCK;
4038 DEBUG(10, ("open_file_ntcreate: fname=%s, after mapping "
4039 "access_mask=0x%x\n", smb_fname_str_dbg(smb_fname),
4043 * Note that we ignore the append flag as append does not
4044 * mean the same thing under DOS and Unix.
4047 flags = calculate_open_access_flags(access_mask, private_flags);
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 status = mkdir_internal(conn,
4782 if (!NT_STATUS_IS_OK(status)) {
4783 DEBUG(2, ("open_directory: unable to create "
4784 "%s. Error was %s\n",
4785 smb_fname_str_dbg(smb_dname),
4786 nt_errstr(status)));
4790 info = FILE_WAS_CREATED;
4795 * If directory exists open. If directory doesn't
4800 status = NT_STATUS_OK;
4801 info = FILE_WAS_OPENED;
4803 status = mkdir_internal(conn,
4810 if (NT_STATUS_IS_OK(status)) {
4811 info = FILE_WAS_CREATED;
4813 /* Cope with create race. */
4814 if (!NT_STATUS_EQUAL(status,
4815 NT_STATUS_OBJECT_NAME_COLLISION)) {
4816 DEBUG(2, ("open_directory: unable to create "
4817 "%s. Error was %s\n",
4818 smb_fname_str_dbg(smb_dname),
4819 nt_errstr(status)));
4824 * If mkdir_internal() returned
4825 * NT_STATUS_OBJECT_NAME_COLLISION
4826 * we still must lstat the path.
4829 if (SMB_VFS_LSTAT(conn, smb_dname)
4831 DEBUG(2, ("Could not stat "
4832 "directory '%s' just "
4837 return map_nt_error_from_unix(
4841 info = FILE_WAS_OPENED;
4847 case FILE_SUPERSEDE:
4848 case FILE_OVERWRITE:
4849 case FILE_OVERWRITE_IF:
4851 DEBUG(5,("open_directory: invalid create_disposition "
4852 "0x%x for directory %s\n",
4853 (unsigned int)create_disposition,
4854 smb_fname_str_dbg(smb_dname)));
4855 return NT_STATUS_INVALID_PARAMETER;
4858 if(!S_ISDIR(smb_dname->st.st_ex_mode)) {
4859 DEBUG(5,("open_directory: %s is not a directory !\n",
4860 smb_fname_str_dbg(smb_dname)));
4861 return NT_STATUS_NOT_A_DIRECTORY;
4865 * Setup the files_struct for it.
4868 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_dname->st);
4869 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
4870 fsp->file_pid = req ? req->smbpid : 0;
4871 fsp->fsp_flags.can_lock = false;
4872 fsp->fsp_flags.can_read = false;
4873 fsp->fsp_flags.can_write = false;
4875 fh_set_private_options(fsp->fh, 0);
4877 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
4879 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
4880 fsp->print_file = NULL;
4881 fsp->fsp_flags.modified = false;
4882 fsp->oplock_type = NO_OPLOCK;
4883 fsp->sent_oplock_break = NO_BREAK_SENT;
4884 fsp->fsp_flags.is_directory = true;
4885 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
4886 fsp->posix_flags |= FSP_POSIX_FLAGS_ALL;
4889 /* Don't store old timestamps for directory
4890 handles in the internal database. We don't
4891 update them in there if new objects
4892 are created in the directory. Currently
4893 we only update timestamps on file writes.
4896 mtimespec = make_omit_timespec();
4899 * Obviously for FILE_LIST_DIRECTORY we need to reopen to get an fd
4900 * usable for reading a directory. SMB2_FLUSH may be called on
4901 * directories opened with FILE_ADD_FILE and FILE_ADD_SUBDIRECTORY so
4902 * for those we need to reopen as well.
4905 FILE_LIST_DIRECTORY |
4907 FILE_ADD_SUBDIRECTORY;
4909 if (access_mask & need_fd_access) {
4910 status = reopen_from_fsp(
4914 O_RDONLY | O_DIRECTORY,
4917 if (!NT_STATUS_IS_OK(status)) {
4918 DBG_INFO("Could not open fd for [%s]: %s\n",
4919 smb_fname_str_dbg(smb_dname),
4925 status = vfs_stat_fsp(fsp);
4926 if (!NT_STATUS_IS_OK(status)) {
4931 if(!S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
4932 DEBUG(5,("open_directory: %s is not a directory !\n",
4933 smb_fname_str_dbg(smb_dname)));
4935 return NT_STATUS_NOT_A_DIRECTORY;
4938 /* Ensure there was no race condition. We need to check
4939 * dev/inode but not permissions, as these can change
4941 if (!check_same_dev_ino(&smb_dname->st, &fsp->fsp_name->st)) {
4942 DEBUG(5,("open_directory: stat struct differs for "
4944 smb_fname_str_dbg(smb_dname)));
4946 return NT_STATUS_ACCESS_DENIED;
4949 if (info == FILE_WAS_OPENED) {
4950 status = smbd_check_access_rights_fsp(parent_dir_fname->fsp,
4954 if (!NT_STATUS_IS_OK(status)) {
4955 DBG_DEBUG("smbd_check_access_rights_fsp on "
4956 "file %s failed with %s\n",
4965 * If we created a new directory or going to delete it later,
4966 * we should keep * the share_mode_lock (g_lock) until we call
4967 * share_mode_entry_prepare_unlock()
4969 if (info != FILE_WAS_OPENED) {
4971 } else if (create_options & FILE_DELETE_ON_CLOSE) {
4975 lck_state = (struct open_ntcreate_lock_state) {
4977 .object_type = "directory",
4979 .create_disposition = create_disposition,
4980 .access_mask = access_mask,
4981 .share_access = share_access,
4982 .oplock_request = NO_OPLOCK,
4984 .first_open_attempt = true,
4985 .keep_locked = keep_locked,
4988 status = share_mode_entry_prepare_lock_add(&lck_state.prepare_state,
4993 open_ntcreate_lock_add_entry,
4995 if (!NT_STATUS_IS_OK(status)) {
4996 DBG_ERR("share_mode_entry_prepare_lock_add() failed for %s - %s\n",
4997 smb_fname_str_dbg(smb_dname), nt_errstr(status));
5002 status = lck_state.status;
5003 if (!NT_STATUS_IS_OK(status)) {
5009 * From here we need to use 'goto unlock;' instead of return !!!
5012 /* For directories the delete on close bit at open time seems
5013 always to be honored on close... See test 19 in Samba4 BASE-DELETE. */
5014 if (create_options & FILE_DELETE_ON_CLOSE) {
5015 status = can_set_delete_on_close(fsp, 0);
5016 if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
5017 lck_state.cleanup_fn =
5018 open_ntcreate_lock_cleanup_entry;
5022 if (NT_STATUS_IS_OK(status)) {
5023 /* Note that here we set the *initial* delete on close flag,
5024 not the regular one. The magic gets handled in close. */
5025 fsp->fsp_flags.initial_delete_on_close = true;
5030 * Deal with other opens having a modified write time.
5032 if (!is_omit_timespec(&lck_state.write_time)) {
5033 update_stat_ex_mtime(&fsp->fsp_name->st, lck_state.write_time);
5040 status = NT_STATUS_OK;
5043 ulstatus = share_mode_entry_prepare_unlock(&lck_state.prepare_state,
5044 lck_state.cleanup_fn,
5046 if (!NT_STATUS_IS_OK(ulstatus)) {
5047 DBG_ERR("share_mode_entry_prepare_unlock() failed for %s - %s\n",
5048 smb_fname_str_dbg(smb_dname), nt_errstr(ulstatus));
5049 smb_panic("share_mode_entry_prepare_unlock() failed!");
5052 if (!NT_STATUS_IS_OK(status)) {
5057 return NT_STATUS_OK;
5060 NTSTATUS create_directory(connection_struct *conn,
5061 struct smb_request *req,
5062 struct files_struct *dirfsp,
5063 struct smb_filename *smb_dname)
5068 status = SMB_VFS_CREATE_FILE(
5071 dirfsp, /* dirfsp */
5072 smb_dname, /* fname */
5073 FILE_READ_ATTRIBUTES, /* access_mask */
5074 FILE_SHARE_NONE, /* share_access */
5075 FILE_CREATE, /* create_disposition*/
5076 FILE_DIRECTORY_FILE, /* create_options */
5077 FILE_ATTRIBUTE_DIRECTORY, /* file_attributes */
5078 0, /* oplock_request */
5080 0, /* allocation_size */
5081 0, /* private_flags */
5086 NULL, NULL); /* create context */
5088 if (NT_STATUS_IS_OK(status)) {
5089 close_file_free(req, &fsp, NORMAL_CLOSE);
5095 /****************************************************************************
5096 Receive notification that one of our open files has been renamed by another
5098 ****************************************************************************/
5100 void msg_file_was_renamed(struct messaging_context *msg_ctx,
5103 struct server_id src,
5106 struct file_rename_message *msg = NULL;
5107 enum ndr_err_code ndr_err;
5109 struct smb_filename *smb_fname = NULL;
5110 struct smbd_server_connection *sconn =
5111 talloc_get_type_abort(private_data,
5112 struct smbd_server_connection);
5114 msg = talloc(talloc_tos(), struct file_rename_message);
5116 DBG_WARNING("talloc failed\n");
5120 ndr_err = ndr_pull_struct_blob_all(
5124 (ndr_pull_flags_fn_t)ndr_pull_file_rename_message);
5125 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
5126 DBG_DEBUG("ndr_pull_oplock_break_message failed: %s\n",
5127 ndr_errstr(ndr_err));
5130 if (DEBUGLEVEL >= 10) {
5131 struct server_id_buf buf;
5132 DBG_DEBUG("Got rename message from %s\n",
5133 server_id_str_buf(src, &buf));
5134 NDR_PRINT_DEBUG(file_rename_message, msg);
5137 /* stream_name must always be NULL if there is no stream. */
5138 if ((msg->stream_name != NULL) && (msg->stream_name[0] == '\0')) {
5139 msg->stream_name = NULL;
5142 smb_fname = synthetic_smb_fname(msg,
5148 if (smb_fname == NULL) {
5149 DBG_DEBUG("synthetic_smb_fname failed\n");
5153 fsp = file_find_dif(sconn, msg->id, msg->share_file_id);
5155 DBG_DEBUG("fsp not found\n");
5159 if (strcmp(fsp->conn->connectpath, msg->servicepath) == 0) {
5160 SMB_STRUCT_STAT fsp_orig_sbuf;
5162 DBG_DEBUG("renaming file %s from %s -> %s\n",
5165 smb_fname_str_dbg(smb_fname));
5168 * The incoming smb_fname here has an
5169 * invalid stat struct from synthetic_smb_fname()
5171 * Preserve the existing stat from the
5172 * open fsp after fsp_set_smb_fname()
5173 * overwrites with the invalid stat.
5175 * (We could just copy this into
5176 * smb_fname->st, but keep this code
5177 * identical to the fix in rename_open_files()
5180 * We will do an fstat before returning
5181 * any of this metadata to the client anyway.
5183 fsp_orig_sbuf = fsp->fsp_name->st;
5184 status = fsp_set_smb_fname(fsp, smb_fname);
5185 if (!NT_STATUS_IS_OK(status)) {
5186 DBG_DEBUG("fsp_set_smb_fname failed: %s\n",
5189 fsp->fsp_name->st = fsp_orig_sbuf;
5193 * Now we have the complete path we can work out if
5194 * this is actually within this share and adjust
5195 * newname accordingly.
5197 DBG_DEBUG("share mismatch (sharepath %s not sharepath %s) "
5198 "%s from %s -> %s\n",
5199 fsp->conn->connectpath,
5203 smb_fname_str_dbg(smb_fname));
5210 * If a main file is opened for delete, all streams need to be checked for
5211 * !FILE_SHARE_DELETE. Do this by opening with DELETE_ACCESS.
5212 * If that works, delete them all by setting the delete on close and close.
5215 static NTSTATUS open_streams_for_delete(connection_struct *conn,
5216 const struct smb_filename *smb_fname)
5218 struct stream_struct *stream_info = NULL;
5219 files_struct **streams = NULL;
5221 unsigned int i, num_streams = 0;
5222 TALLOC_CTX *frame = talloc_stackframe();
5223 const struct smb_filename *pathref = NULL;
5226 if (smb_fname->fsp == NULL) {
5227 struct smb_filename *tmp = NULL;
5228 status = synthetic_pathref(frame,
5230 smb_fname->base_name,
5236 if (!NT_STATUS_IS_OK(status)) {
5237 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
5238 || NT_STATUS_EQUAL(status,
5239 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
5240 DBG_DEBUG("no streams around\n");
5242 return NT_STATUS_OK;
5244 DBG_DEBUG("synthetic_pathref failed: %s\n",
5250 pathref = smb_fname;
5252 status = vfs_fstreaminfo(pathref->fsp, talloc_tos(),
5253 &num_streams, &stream_info);
5255 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
5256 || NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
5257 DEBUG(10, ("no streams around\n"));
5259 return NT_STATUS_OK;
5262 if (!NT_STATUS_IS_OK(status)) {
5263 DEBUG(10, ("vfs_fstreaminfo failed: %s\n",
5264 nt_errstr(status)));
5268 DEBUG(10, ("open_streams_for_delete found %d streams\n",
5271 if (num_streams == 0) {
5273 return NT_STATUS_OK;
5276 streams = talloc_array(talloc_tos(), files_struct *, num_streams);
5277 if (streams == NULL) {
5278 DEBUG(0, ("talloc failed\n"));
5279 status = NT_STATUS_NO_MEMORY;
5283 for (i=0; i<num_streams; i++) {
5284 struct smb_filename *smb_fname_cp;
5286 if (strequal(stream_info[i].name, "::$DATA")) {
5291 smb_fname_cp = synthetic_smb_fname(talloc_tos(),
5292 smb_fname->base_name,
5293 stream_info[i].name,
5297 ~SMB_FILENAME_POSIX_PATH));
5298 if (smb_fname_cp == NULL) {
5299 status = NT_STATUS_NO_MEMORY;
5303 status = openat_pathref_fsp(conn->cwd_fsp, smb_fname_cp);
5304 if (!NT_STATUS_IS_OK(status)) {
5305 DBG_DEBUG("Unable to open stream [%s]: %s\n",
5306 smb_fname_str_dbg(smb_fname_cp),
5308 TALLOC_FREE(smb_fname_cp);
5312 status = SMB_VFS_CREATE_FILE(
5316 smb_fname_cp, /* fname */
5317 DELETE_ACCESS, /* access_mask */
5318 (FILE_SHARE_READ | /* share_access */
5319 FILE_SHARE_WRITE | FILE_SHARE_DELETE),
5320 FILE_OPEN, /* create_disposition*/
5321 0, /* create_options */
5322 FILE_ATTRIBUTE_NORMAL, /* file_attributes */
5323 0, /* oplock_request */
5325 0, /* allocation_size */
5326 0, /* private_flags */
5329 &streams[i], /* result */
5331 NULL, NULL); /* create context */
5333 if (!NT_STATUS_IS_OK(status)) {
5334 DEBUG(10, ("Could not open stream %s: %s\n",
5335 smb_fname_str_dbg(smb_fname_cp),
5336 nt_errstr(status)));
5338 TALLOC_FREE(smb_fname_cp);
5341 TALLOC_FREE(smb_fname_cp);
5345 * don't touch the variable "status" beyond this point :-)
5348 for (j = i-1 ; j >= 0; j--) {
5349 if (streams[j] == NULL) {
5353 DEBUG(10, ("Closing stream # %d, %s\n", j,
5354 fsp_str_dbg(streams[j])));
5355 close_file_free(NULL, &streams[j], NORMAL_CLOSE);
5363 /*********************************************************************
5364 Create a default ACL by inheriting from the parent. If no inheritance
5365 from the parent available, don't set anything. This will leave the actual
5366 permissions the new file or directory already got from the filesystem
5367 as the NT ACL when read.
5368 *********************************************************************/
5370 static NTSTATUS inherit_new_acl(files_struct *dirfsp, files_struct *fsp)
5372 TALLOC_CTX *frame = talloc_stackframe();
5373 struct security_descriptor *parent_desc = NULL;
5374 NTSTATUS status = NT_STATUS_OK;
5375 struct security_descriptor *psd = NULL;
5376 const struct dom_sid *owner_sid = NULL;
5377 const struct dom_sid *group_sid = NULL;
5378 uint32_t security_info_sent = (SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL);
5379 struct security_token *token = fsp->conn->session_info->security_token;
5380 bool inherit_owner =
5381 (lp_inherit_owner(SNUM(fsp->conn)) == INHERIT_OWNER_WINDOWS_AND_UNIX);
5382 bool inheritable_components = false;
5383 bool try_builtin_administrators = false;
5384 const struct dom_sid *BA_U_sid = NULL;
5385 const struct dom_sid *BA_G_sid = NULL;
5386 bool try_system = false;
5387 const struct dom_sid *SY_U_sid = NULL;
5388 const struct dom_sid *SY_G_sid = NULL;
5392 status = SMB_VFS_FGET_NT_ACL(dirfsp,
5393 (SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL),
5396 if (!NT_STATUS_IS_OK(status)) {
5401 inheritable_components = sd_has_inheritable_components(parent_desc,
5402 fsp->fsp_flags.is_directory);
5404 if (!inheritable_components && !inherit_owner) {
5406 /* Nothing to inherit and not setting owner. */
5407 return NT_STATUS_OK;
5410 /* Create an inherited descriptor from the parent. */
5412 if (DEBUGLEVEL >= 10) {
5413 DEBUG(10,("inherit_new_acl: parent acl for %s is:\n",
5414 fsp_str_dbg(fsp) ));
5415 NDR_PRINT_DEBUG(security_descriptor, parent_desc);
5418 /* Inherit from parent descriptor if "inherit owner" set. */
5419 if (inherit_owner) {
5420 owner_sid = parent_desc->owner_sid;
5421 group_sid = parent_desc->group_sid;
5424 if (owner_sid == NULL) {
5425 if (security_token_has_builtin_administrators(token)) {
5426 try_builtin_administrators = true;
5427 } else if (security_token_is_system(token)) {
5428 try_builtin_administrators = true;
5433 if (group_sid == NULL &&
5434 token->num_sids == PRIMARY_GROUP_SID_INDEX)
5436 if (security_token_is_system(token)) {
5437 try_builtin_administrators = true;
5442 if (try_builtin_administrators) {
5443 struct unixid ids = { .id = 0 };
5445 ok = sids_to_unixids(&global_sid_Builtin_Administrators, 1, &ids);
5449 BA_U_sid = &global_sid_Builtin_Administrators;
5450 BA_G_sid = &global_sid_Builtin_Administrators;
5453 BA_U_sid = &global_sid_Builtin_Administrators;
5456 BA_G_sid = &global_sid_Builtin_Administrators;
5465 struct unixid ids = { .id = 0 };
5467 ok = sids_to_unixids(&global_sid_System, 1, &ids);
5471 SY_U_sid = &global_sid_System;
5472 SY_G_sid = &global_sid_System;
5475 SY_U_sid = &global_sid_System;
5478 SY_G_sid = &global_sid_System;
5486 if (owner_sid == NULL) {
5487 owner_sid = BA_U_sid;
5490 if (owner_sid == NULL) {
5491 owner_sid = SY_U_sid;
5494 if (group_sid == NULL) {
5495 group_sid = SY_G_sid;
5498 if (try_system && group_sid == NULL) {
5499 group_sid = BA_G_sid;
5502 if (owner_sid == NULL) {
5503 owner_sid = &token->sids[PRIMARY_USER_SID_INDEX];
5505 if (group_sid == NULL) {
5506 if (token->num_sids == PRIMARY_GROUP_SID_INDEX) {
5507 group_sid = &token->sids[PRIMARY_USER_SID_INDEX];
5509 group_sid = &token->sids[PRIMARY_GROUP_SID_INDEX];
5513 status = se_create_child_secdesc(frame,
5519 fsp->fsp_flags.is_directory);
5520 if (!NT_STATUS_IS_OK(status)) {
5525 /* If inheritable_components == false,
5526 se_create_child_secdesc()
5527 creates a security descriptor with a NULL dacl
5528 entry, but with SEC_DESC_DACL_PRESENT. We need
5529 to remove that flag. */
5531 if (!inheritable_components) {
5532 security_info_sent &= ~SECINFO_DACL;
5533 psd->type &= ~SEC_DESC_DACL_PRESENT;
5536 if (DEBUGLEVEL >= 10) {
5537 DEBUG(10,("inherit_new_acl: child acl for %s is:\n",
5538 fsp_str_dbg(fsp) ));
5539 NDR_PRINT_DEBUG(security_descriptor, psd);
5542 if (inherit_owner) {
5543 /* We need to be root to force this. */
5546 status = SMB_VFS_FSET_NT_ACL(metadata_fsp(fsp),
5549 if (inherit_owner) {
5557 * If we already have a lease, it must match the new file id. [MS-SMB2]
5558 * 3.3.5.9.8 speaks about INVALID_PARAMETER if an already used lease key is
5559 * used for a different file name.
5562 struct lease_match_state {
5563 /* Input parameters. */
5564 TALLOC_CTX *mem_ctx;
5565 const char *servicepath;
5566 const struct smb_filename *fname;
5569 /* Return parameters. */
5570 uint32_t num_file_ids;
5571 struct file_id *ids;
5572 NTSTATUS match_status;
5575 /*************************************************************
5576 File doesn't exist but this lease key+guid is already in use.
5578 This is only allowable in the dynamic share case where the
5579 service path must be different.
5581 There is a small race condition here in the multi-connection
5582 case where a client sends two create calls on different connections,
5583 where the file doesn't exist and one smbd creates the leases_db
5584 entry first, but this will get fixed by the multichannel cleanup
5585 when all identical client_guids get handled by a single smbd.
5586 **************************************************************/
5588 static void lease_match_parser_new_file(
5590 const struct leases_db_file *files,
5591 struct lease_match_state *state)
5595 for (i = 0; i < num_files; i++) {
5596 const struct leases_db_file *f = &files[i];
5597 if (strequal(state->servicepath, f->servicepath)) {
5598 state->match_status = NT_STATUS_INVALID_PARAMETER;
5603 /* Dynamic share case. Break leases on all other files. */
5604 state->match_status = leases_db_copy_file_ids(state->mem_ctx,
5608 if (!NT_STATUS_IS_OK(state->match_status)) {
5612 state->num_file_ids = num_files;
5613 state->match_status = NT_STATUS_OPLOCK_NOT_GRANTED;
5617 static void lease_match_parser(
5619 const struct leases_db_file *files,
5622 struct lease_match_state *state =
5623 (struct lease_match_state *)private_data;
5626 if (!state->file_existed) {
5628 * Deal with name mismatch or
5629 * possible dynamic share case separately
5630 * to make code clearer.
5632 lease_match_parser_new_file(num_files,
5639 state->match_status = NT_STATUS_OK;
5641 for (i = 0; i < num_files; i++) {
5642 const struct leases_db_file *f = &files[i];
5644 /* Everything should be the same. */
5645 if (!file_id_equal(&state->id, &f->id)) {
5647 * The client asked for a lease on a
5648 * file that doesn't match the file_id
5651 * Maybe this is a dynamic share, i.e.
5652 * a share where the servicepath is
5653 * different for different users (e.g.
5654 * the [HOMES] share.
5656 * If the servicepath is different, but the requested
5657 * file name + stream name is the same then this is
5658 * a dynamic share, the client is using the same share
5659 * name and doesn't know that the underlying servicepath
5660 * is different. It was expecting a lease on the
5661 * same file. Return NT_STATUS_OPLOCK_NOT_GRANTED
5664 * Otherwise the client has messed up, or is
5665 * testing our error codes, so return
5666 * NT_STATUS_INVALID_PARAMETER.
5668 if (!strequal(f->servicepath, state->servicepath) &&
5669 strequal(f->base_name, state->fname->base_name) &&
5670 strequal(f->stream_name, state->fname->stream_name))
5673 * Name is the same but servicepath is
5674 * different, dynamic share. Break leases.
5676 state->match_status =
5677 NT_STATUS_OPLOCK_NOT_GRANTED;
5679 state->match_status =
5680 NT_STATUS_INVALID_PARAMETER;
5684 if (!strequal(f->servicepath, state->servicepath)) {
5685 state->match_status = NT_STATUS_INVALID_PARAMETER;
5688 if (!strequal(f->base_name, state->fname->base_name)) {
5689 state->match_status = NT_STATUS_INVALID_PARAMETER;
5692 if (!strequal(f->stream_name, state->fname->stream_name)) {
5693 state->match_status = NT_STATUS_INVALID_PARAMETER;
5698 if (NT_STATUS_IS_OK(state->match_status)) {
5700 * Common case - just opening another handle on a
5701 * file on a non-dynamic share.
5706 if (NT_STATUS_EQUAL(state->match_status, NT_STATUS_INVALID_PARAMETER)) {
5707 /* Mismatched path. Error back to client. */
5712 * File id mismatch. Dynamic share case NT_STATUS_OPLOCK_NOT_GRANTED.
5713 * Don't allow leases.
5716 state->match_status = leases_db_copy_file_ids(state->mem_ctx,
5720 if (!NT_STATUS_IS_OK(state->match_status)) {
5724 state->num_file_ids = num_files;
5725 state->match_status = NT_STATUS_OPLOCK_NOT_GRANTED;
5729 struct lease_match_break_state {
5730 struct messaging_context *msg_ctx;
5731 const struct smb2_lease_key *lease_key;
5739 static bool lease_match_break_fn(
5740 struct share_mode_entry *e,
5743 struct lease_match_break_state *state = private_data;
5745 uint32_t e_lease_type = SMB2_LEASE_NONE;
5748 stale = share_entry_stale_pid(e);
5753 equal = smb2_lease_key_equal(&e->lease_key, state->lease_key);
5758 status = leases_db_get(
5762 &e_lease_type, /* current_state */
5763 NULL, /* breaking */
5764 NULL, /* breaking_to_requested */
5765 NULL, /* breaking_to_required */
5766 &state->version, /* lease_version */
5767 &state->epoch); /* epoch */
5768 if (NT_STATUS_IS_OK(status)) {
5769 state->found_lease = true;
5771 DBG_WARNING("Could not find version/epoch: %s\n",
5776 if (e_lease_type == SMB2_LEASE_NONE) {
5779 send_break_message(state->msg_ctx, &state->id, e, SMB2_LEASE_NONE);
5782 * Windows 7 and 8 lease clients are broken in that they will
5783 * not respond to lease break requests whilst waiting for an
5784 * outstanding open request on that lease handle on the same
5785 * TCP connection, due to holding an internal inode lock.
5787 * This means we can't reschedule ourselves here, but must
5788 * return from the create.
5792 * Send the breaks and then return SMB2_LEASE_NONE in the
5793 * lease handle to cause them to acknowledge the lease
5794 * break. Consultation with Microsoft engineering confirmed
5795 * this approach is safe.
5801 static void lease_match_fid_fn(struct share_mode_lock *lck,
5806 ok = share_mode_forall_leases(lck, lease_match_break_fn, private_data);
5808 DBG_DEBUG("share_mode_forall_leases failed\n");
5812 static NTSTATUS lease_match(connection_struct *conn,
5813 struct smb_request *req,
5814 const struct smb2_lease_key *lease_key,
5815 const char *servicepath,
5816 const struct smb_filename *fname,
5817 uint16_t *p_version,
5820 struct smbd_server_connection *sconn = req->sconn;
5821 TALLOC_CTX *tos = talloc_tos();
5822 struct lease_match_state state = {
5824 .servicepath = servicepath,
5826 .match_status = NT_STATUS_OK
5831 state.file_existed = VALID_STAT(fname->st);
5832 if (state.file_existed) {
5833 state.id = vfs_file_id_from_sbuf(conn, &fname->st);
5836 status = leases_db_parse(&sconn->client->global->client_guid,
5837 lease_key, lease_match_parser, &state);
5838 if (!NT_STATUS_IS_OK(status)) {
5840 * Not found or error means okay: We can make the lease pass
5842 return NT_STATUS_OK;
5844 if (!NT_STATUS_EQUAL(state.match_status, NT_STATUS_OPLOCK_NOT_GRANTED)) {
5846 * Anything but NT_STATUS_OPLOCK_NOT_GRANTED, let the caller
5849 return state.match_status;
5852 /* We have to break all existing leases. */
5853 for (i = 0; i < state.num_file_ids; i++) {
5854 struct lease_match_break_state break_state = {
5855 .msg_ctx = conn->sconn->msg_ctx,
5856 .lease_key = lease_key,
5859 if (file_id_equal(&state.ids[i], &state.id)) {
5860 /* Don't need to break our own file. */
5864 break_state.id = state.ids[i];
5866 status = share_mode_do_locked_vfs_denied(break_state.id,
5869 if (!NT_STATUS_IS_OK(status)) {
5870 /* Race condition - file already closed. */
5874 if (break_state.found_lease) {
5875 *p_version = break_state.version;
5876 *p_epoch = break_state.epoch;
5880 * Ensure we don't grant anything more so we
5883 return NT_STATUS_OPLOCK_NOT_GRANTED;
5887 * Wrapper around open_file_ntcreate and open_directory
5890 static NTSTATUS create_file_unixpath(connection_struct *conn,
5891 struct smb_request *req,
5892 struct files_struct *dirfsp,
5893 struct smb_filename *smb_fname,
5894 uint32_t access_mask,
5895 uint32_t share_access,
5896 uint32_t create_disposition,
5897 uint32_t create_options,
5898 uint32_t file_attributes,
5899 uint32_t oplock_request,
5900 const struct smb2_lease *lease,
5901 uint64_t allocation_size,
5902 uint32_t private_flags,
5903 struct security_descriptor *sd,
5904 struct ea_list *ea_list,
5906 files_struct **result,
5909 struct smb2_lease none_lease;
5910 int info = FILE_WAS_OPENED;
5911 files_struct *base_fsp = NULL;
5912 files_struct *fsp = NULL;
5913 bool free_fsp_on_error = false;
5916 struct smb_filename *parent_dir_fname = NULL;
5917 struct smb_filename *smb_fname_atname = NULL;
5919 DBG_DEBUG("access_mask = 0x%"PRIx32" "
5920 "file_attributes = 0x%"PRIx32" "
5921 "share_access = 0x%"PRIx32" "
5922 "create_disposition = 0x%"PRIx32" "
5923 "create_options = 0x%"PRIx32" "
5924 "oplock_request = 0x%"PRIx32" "
5925 "private_flags = 0x%"PRIx32" "
5938 smb_fname_str_dbg(smb_fname));
5940 if (create_options & FILE_OPEN_BY_FILE_ID) {
5941 status = NT_STATUS_NOT_SUPPORTED;
5945 if (create_options & NTCREATEX_OPTIONS_INVALID_PARAM_MASK) {
5946 status = NT_STATUS_INVALID_PARAMETER;
5951 oplock_request |= INTERNAL_OPEN_ONLY;
5954 if (lease != NULL) {
5955 uint16_t epoch = lease->lease_epoch;
5956 uint16_t version = lease->lease_version;
5959 DBG_WARNING("Got lease on internal open\n");
5960 status = NT_STATUS_INTERNAL_ERROR;
5964 status = lease_match(conn,
5971 if (NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) {
5972 /* Dynamic share file. No leases and update epoch... */
5973 none_lease = *lease;
5974 none_lease.lease_state = SMB2_LEASE_NONE;
5975 none_lease.lease_epoch = epoch;
5976 none_lease.lease_version = version;
5977 lease = &none_lease;
5978 } else if (!NT_STATUS_IS_OK(status)) {
5983 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
5984 && (access_mask & DELETE_ACCESS)
5985 && !is_named_stream(smb_fname)) {
5987 * We can't open a file with DELETE access if any of the
5988 * streams is open without FILE_SHARE_DELETE
5990 status = open_streams_for_delete(conn, smb_fname);
5992 if (!NT_STATUS_IS_OK(status)) {
5997 if (access_mask & SEC_FLAG_SYSTEM_SECURITY) {
6000 ok = security_token_has_privilege(get_current_nttok(conn),
6003 DBG_DEBUG("open on %s failed - "
6004 "SEC_FLAG_SYSTEM_SECURITY denied.\n",
6005 smb_fname_str_dbg(smb_fname));
6006 status = NT_STATUS_PRIVILEGE_NOT_HELD;
6010 if (conn->sconn->using_smb2 &&
6011 (access_mask == SEC_FLAG_SYSTEM_SECURITY))
6014 * No other bits set. Windows SMB2 refuses this.
6015 * See smbtorture3 SMB2-SACL test.
6017 * Note this is an SMB2-only behavior,
6018 * smbtorture3 SMB1-SYSTEM-SECURITY already tests
6019 * that SMB1 allows this.
6021 status = NT_STATUS_ACCESS_DENIED;
6027 * Files or directories can't be opened DELETE_ON_CLOSE without
6029 * BUG: https://bugzilla.samba.org/show_bug.cgi?id=13358
6031 if (create_options & FILE_DELETE_ON_CLOSE) {
6032 if ((access_mask & DELETE_ACCESS) == 0) {
6033 status = NT_STATUS_INVALID_PARAMETER;
6038 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
6039 && is_named_stream(smb_fname))
6041 uint32_t base_create_disposition;
6042 struct smb_filename *smb_fname_base = NULL;
6043 uint32_t base_privflags;
6045 if (create_options & FILE_DIRECTORY_FILE) {
6046 DBG_DEBUG("Can't open a stream as directory\n");
6047 status = NT_STATUS_NOT_A_DIRECTORY;
6051 switch (create_disposition) {
6053 base_create_disposition = FILE_OPEN;
6056 base_create_disposition = FILE_OPEN_IF;
6060 smb_fname_base = cp_smb_filename_nostream(
6061 talloc_tos(), smb_fname);
6063 if (smb_fname_base == NULL) {
6064 status = NT_STATUS_NO_MEMORY;
6069 * We may be creating the basefile as part of creating the
6070 * stream, so it's legal if the basefile doesn't exist at this
6071 * point, the create_file_unixpath() below will create it. But
6072 * if the basefile exists we want a handle so we can fstat() it.
6075 ret = vfs_stat(conn, smb_fname_base);
6076 if (ret == -1 && errno != ENOENT) {
6077 status = map_nt_error_from_unix(errno);
6078 TALLOC_FREE(smb_fname_base);
6082 status = openat_pathref_fsp(conn->cwd_fsp,
6084 if (!NT_STATUS_IS_OK(status)) {
6085 DBG_ERR("open_smb_fname_fsp [%s] failed: %s\n",
6086 smb_fname_str_dbg(smb_fname_base),
6088 TALLOC_FREE(smb_fname_base);
6093 * https://bugzilla.samba.org/show_bug.cgi?id=10229
6094 * We need to check if the requested access mask
6095 * could be used to open the underlying file (if
6096 * it existed), as we're passing in zero for the
6097 * access mask to the base filename.
6099 status = check_base_file_access(smb_fname_base->fsp,
6102 if (!NT_STATUS_IS_OK(status)) {
6103 DEBUG(10, ("Permission check "
6104 "for base %s failed: "
6105 "%s\n", smb_fname->base_name,
6106 nt_errstr(status)));
6107 TALLOC_FREE(smb_fname_base);
6112 base_privflags = NTCREATEX_FLAG_STREAM_BASEOPEN;
6114 /* Open the base file. */
6115 status = create_file_unixpath(conn,
6122 | FILE_SHARE_DELETE,
6123 base_create_disposition,
6134 TALLOC_FREE(smb_fname_base);
6136 if (!NT_STATUS_IS_OK(status)) {
6137 DEBUG(10, ("create_file_unixpath for base %s failed: "
6138 "%s\n", smb_fname->base_name,
6139 nt_errstr(status)));
6144 if (smb_fname->fsp != NULL) {
6146 fsp = smb_fname->fsp;
6149 * We're about to use smb_fname->fsp for the fresh open.
6151 * Every fsp passed in via smb_fname->fsp already
6152 * holds a fsp->fsp_name. If it is already this
6153 * fsp->fsp_name that we got passed in as our input
6154 * argument smb_fname, these two are assumed to have
6155 * the same lifetime: Every fsp hangs of "conn", and
6156 * fsp->fsp_name is its talloc child.
6159 if (smb_fname != smb_fname->fsp->fsp_name) {
6161 * "smb_fname" is temporary in this case, but
6162 * the destructor of smb_fname would also tear
6163 * down the fsp we're about to use. Unlink
6164 * them from each other.
6166 smb_fname_fsp_unlink(smb_fname);
6171 free_fsp_on_error = true;
6174 status = fsp_bind_smb(fsp, req);
6175 if (!NT_STATUS_IS_OK(status)) {
6179 if (fsp_is_alternate_stream(fsp)) {
6180 struct files_struct *tmp_base_fsp = fsp->base_fsp;
6182 fsp_set_base_fsp(fsp, NULL);
6184 fd_close(tmp_base_fsp);
6185 file_free(NULL, tmp_base_fsp);
6189 * No fsp passed in that we can use, create one
6191 status = file_new(req, conn, &fsp);
6192 if(!NT_STATUS_IS_OK(status)) {
6195 free_fsp_on_error = true;
6197 status = fsp_set_smb_fname(fsp, smb_fname);
6198 if (!NT_STATUS_IS_OK(status)) {
6203 SMB_ASSERT(fsp->fsp_name->fsp != NULL);
6204 SMB_ASSERT(fsp->fsp_name->fsp == fsp);
6208 * We're opening the stream element of a
6209 * base_fsp we already opened. Set up the
6212 fsp_set_base_fsp(fsp, base_fsp);
6215 if (dirfsp != NULL) {
6216 status = SMB_VFS_PARENT_PATHNAME(
6222 if (!NT_STATUS_IS_OK(status)) {
6227 * Get a pathref on the parent. We can re-use this for
6228 * multiple calls to check parent ACLs etc. to avoid
6231 status = parent_pathref(talloc_tos(),
6236 if (!NT_STATUS_IS_OK(status)) {
6240 dirfsp = parent_dir_fname->fsp;
6241 status = fsp_set_smb_fname(dirfsp, parent_dir_fname);
6242 if (!NT_STATUS_IS_OK(status)) {
6248 * If it's a request for a directory open, deal with it separately.
6251 if (create_options & FILE_DIRECTORY_FILE) {
6253 if (create_options & FILE_NON_DIRECTORY_FILE) {
6254 status = NT_STATUS_INVALID_PARAMETER;
6258 /* Can't open a temp directory. IFS kit test. */
6259 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
6260 (file_attributes & FILE_ATTRIBUTE_TEMPORARY)) {
6261 status = NT_STATUS_INVALID_PARAMETER;
6266 * We will get a create directory here if the Win32
6267 * app specified a security descriptor in the
6268 * CreateDirectory() call.
6272 status = open_directory(conn,
6286 * Ordinary file case.
6289 if (allocation_size) {
6290 fsp->initial_allocation_size = smb_roundup(fsp->conn,
6294 status = open_file_ntcreate(conn,
6308 if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
6310 /* A stream open never opens a directory */
6313 status = NT_STATUS_FILE_IS_A_DIRECTORY;
6318 * Fail the open if it was explicitly a non-directory
6322 if (create_options & FILE_NON_DIRECTORY_FILE) {
6323 status = NT_STATUS_FILE_IS_A_DIRECTORY;
6328 status = open_directory(conn,
6342 if (!NT_STATUS_IS_OK(status)) {
6346 fsp->fsp_flags.is_fsa = true;
6348 if ((ea_list != NULL) &&
6349 ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN))) {
6350 status = set_ea(conn, fsp, ea_list);
6351 if (!NT_STATUS_IS_OK(status)) {
6356 if (!fsp->fsp_flags.is_directory &&
6357 S_ISDIR(fsp->fsp_name->st.st_ex_mode))
6359 status = NT_STATUS_ACCESS_DENIED;
6363 /* Save the requested allocation size. */
6364 if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
6365 if ((allocation_size > (uint64_t)fsp->fsp_name->st.st_ex_size)
6366 && !(fsp->fsp_flags.is_directory))
6368 fsp->initial_allocation_size = smb_roundup(
6369 fsp->conn, allocation_size);
6370 if (vfs_allocate_file_space(
6371 fsp, fsp->initial_allocation_size) == -1) {
6372 status = NT_STATUS_DISK_FULL;
6376 fsp->initial_allocation_size = smb_roundup(
6377 fsp->conn, (uint64_t)fsp->fsp_name->st.st_ex_size);
6380 fsp->initial_allocation_size = 0;
6383 if ((info == FILE_WAS_CREATED) &&
6384 lp_nt_acl_support(SNUM(conn)) &&
6385 !fsp_is_alternate_stream(fsp)) {
6388 * According to the MS documentation, the only time the security
6389 * descriptor is applied to the opened file is iff we *created* the
6390 * file; an existing file stays the same.
6392 * Also, it seems (from observation) that you can open the file with
6393 * any access mask but you can still write the sd. We need to override
6394 * the granted access before we call set_sd
6395 * Patch for bug #2242 from Tom Lackemann <cessnatomny@yahoo.com>.
6398 uint32_t sec_info_sent;
6399 uint32_t saved_access_mask = fsp->access_mask;
6401 sec_info_sent = get_sec_info(sd);
6403 fsp->access_mask = FILE_GENERIC_ALL;
6405 if (sec_info_sent & (SECINFO_OWNER|
6409 status = set_sd(fsp, sd, sec_info_sent);
6412 fsp->access_mask = saved_access_mask;
6414 if (!NT_STATUS_IS_OK(status)) {
6417 } else if (lp_inherit_acls(SNUM(conn))) {
6418 /* Inherit from parent. Errors here are not fatal. */
6419 status = inherit_new_acl(dirfsp, fsp);
6420 if (!NT_STATUS_IS_OK(status)) {
6421 DEBUG(10,("inherit_new_acl: failed for %s with %s\n",
6423 nt_errstr(status) ));
6428 if ((conn->fs_capabilities & FILE_FILE_COMPRESSION)
6429 && (create_options & FILE_NO_COMPRESSION)
6430 && (info == FILE_WAS_CREATED)) {
6431 status = SMB_VFS_SET_COMPRESSION(conn, fsp, fsp,
6432 COMPRESSION_FORMAT_NONE);
6433 if (!NT_STATUS_IS_OK(status)) {
6434 DEBUG(1, ("failed to disable compression: %s\n",
6435 nt_errstr(status)));
6439 DEBUG(10, ("create_file_unixpath: info=%d\n", info));
6442 if (pinfo != NULL) {
6446 smb_fname->st = fsp->fsp_name->st;
6448 TALLOC_FREE(parent_dir_fname);
6450 return NT_STATUS_OK;
6453 DEBUG(10, ("create_file_unixpath: %s\n", nt_errstr(status)));
6457 * The close_file below will close
6461 close_file_smb(req, fsp, ERROR_CLOSE);
6462 if (free_fsp_on_error) {
6463 file_free(req, fsp);
6467 if (base_fsp != NULL) {
6468 close_file_free(req, &base_fsp, ERROR_CLOSE);
6471 TALLOC_FREE(parent_dir_fname);
6476 NTSTATUS create_file_default(connection_struct *conn,
6477 struct smb_request *req,
6478 struct files_struct *dirfsp,
6479 struct smb_filename *smb_fname,
6480 uint32_t access_mask,
6481 uint32_t share_access,
6482 uint32_t create_disposition,
6483 uint32_t create_options,
6484 uint32_t file_attributes,
6485 uint32_t oplock_request,
6486 const struct smb2_lease *lease,
6487 uint64_t allocation_size,
6488 uint32_t private_flags,
6489 struct security_descriptor *sd,
6490 struct ea_list *ea_list,
6491 files_struct **result,
6493 const struct smb2_create_blobs *in_context_blobs,
6494 struct smb2_create_blobs *out_context_blobs)
6496 int info = FILE_WAS_OPENED;
6497 files_struct *fsp = NULL;
6499 bool stream_name = false;
6500 struct smb2_create_blob *posx = NULL;
6502 DBG_DEBUG("create_file: access_mask = 0x%x "
6503 "file_attributes = 0x%x, share_access = 0x%x, "
6504 "create_disposition = 0x%x create_options = 0x%x "
6505 "oplock_request = 0x%x "
6506 "private_flags = 0x%x "
6507 "ea_list = %p, sd = %p, "
6509 (unsigned int)access_mask,
6510 (unsigned int)file_attributes,
6511 (unsigned int)share_access,
6512 (unsigned int)create_disposition,
6513 (unsigned int)create_options,
6514 (unsigned int)oplock_request,
6515 (unsigned int)private_flags,
6518 smb_fname_str_dbg(smb_fname));
6522 * Remember the absolute time of the original request
6523 * with this mid. We'll use it later to see if this
6526 get_deferred_open_message_state(req, &req->request_time, NULL);
6530 * Check to see if this is a mac fork of some kind.
6533 stream_name = is_ntfs_stream_smb_fname(smb_fname);
6535 enum FAKE_FILE_TYPE fake_file_type;
6537 fake_file_type = is_fake_file(smb_fname);
6539 if (req != NULL && fake_file_type != FAKE_FILE_TYPE_NONE) {
6542 * Here we go! support for changing the disk quotas
6545 * We need to fake up to open this MAGIC QUOTA file
6546 * and return a valid FID.
6548 * w2k close this file directly after openening xp
6549 * also tries a QUERY_FILE_INFO on the file and then
6552 status = open_fake_file(req, conn, req->vuid,
6553 fake_file_type, smb_fname,
6555 if (!NT_STATUS_IS_OK(status)) {
6559 ZERO_STRUCT(smb_fname->st);
6563 if (!(conn->fs_capabilities & FILE_NAMED_STREAMS)) {
6564 status = NT_STATUS_OBJECT_NAME_INVALID;
6569 if (is_ntfs_default_stream_smb_fname(smb_fname)) {
6571 /* We have to handle this error here. */
6572 if (create_options & FILE_DIRECTORY_FILE) {
6573 status = NT_STATUS_NOT_A_DIRECTORY;
6576 ret = vfs_stat(conn, smb_fname);
6577 if (ret == 0 && VALID_STAT_OF_DIR(smb_fname->st)) {
6578 status = NT_STATUS_FILE_IS_A_DIRECTORY;
6583 posx = smb2_create_blob_find(
6584 in_context_blobs, SMB2_CREATE_TAG_POSIX);
6586 uint32_t wire_mode_bits = 0;
6587 mode_t mode_bits = 0;
6588 SMB_STRUCT_STAT sbuf = { 0 };
6589 enum perm_type ptype =
6590 (create_options & FILE_DIRECTORY_FILE) ?
6591 PERM_NEW_DIR : PERM_NEW_FILE;
6593 if (posx->data.length != 4) {
6594 status = NT_STATUS_INVALID_PARAMETER;
6598 wire_mode_bits = IVAL(posx->data.data, 0);
6599 status = unix_perms_from_wire(
6600 conn, &sbuf, wire_mode_bits, ptype, &mode_bits);
6601 if (!NT_STATUS_IS_OK(status)) {
6605 * Remove type info from mode, leaving only the
6606 * permissions and setuid/gid bits.
6608 mode_bits &= ~S_IFMT;
6610 file_attributes = (FILE_FLAG_POSIX_SEMANTICS | mode_bits);
6613 status = create_file_unixpath(conn,
6630 if (!NT_STATUS_IS_OK(status)) {
6635 DEBUG(10, ("create_file: info=%d\n", info));
6638 if (pinfo != NULL) {
6641 return NT_STATUS_OK;
6644 DEBUG(10, ("create_file: %s\n", nt_errstr(status)));
6647 close_file_free(req, &fsp, ERROR_CLOSE);