tests/krb5: Add more encryption type constants
[Samba.git] / source3 / smbd / open.c
blobd01b5ae65f4ca552fdef53bdb7c72475b7746797
1 /*
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/>.
23 #include "includes.h"
24 #include "smb1_utils.h"
25 #include "system/filesys.h"
26 #include "lib/util/server_id.h"
27 #include "printing.h"
28 #include "locking/share_mode_lock.h"
29 #include "smbd/smbd.h"
30 #include "smbd/globals.h"
31 #include "fake_file.h"
32 #include "../libcli/security/security.h"
33 #include "../librpc/gen_ndr/ndr_security.h"
34 #include "../librpc/gen_ndr/ndr_open_files.h"
35 #include "../librpc/gen_ndr/idmap.h"
36 #include "../librpc/gen_ndr/ioctl.h"
37 #include "passdb/lookup_sid.h"
38 #include "auth.h"
39 #include "serverid.h"
40 #include "messages.h"
41 #include "source3/lib/dbwrap/dbwrap_watch.h"
42 #include "locking/leases_db.h"
43 #include "librpc/gen_ndr/ndr_leases_db.h"
44 #include "lib/util/time_basic.h"
46 extern const struct generic_mapping file_generic_mapping;
48 struct deferred_open_record {
49 struct smbXsrv_connection *xconn;
50 uint64_t mid;
52 bool async_open;
55 * Timer for async opens, needed because they don't use a watch on
56 * a locking.tdb record. This is currently only used for real async
57 * opens and just terminates smbd if the async open times out.
59 struct tevent_timer *te;
62 * For the samba kernel oplock case we use both a timeout and
63 * a watch on locking.tdb. This way in case it's smbd holding
64 * the kernel oplock we get directly notified for the retry
65 * once the kernel oplock is properly broken. Store the req
66 * here so that it can be timely discarded once the timer
67 * above fires.
69 struct tevent_req *watch_req;
72 /****************************************************************************
73 If the requester wanted DELETE_ACCESS and was rejected because
74 the file ACL didn't include DELETE_ACCESS, see if the parent ACL
75 overrides this.
76 ****************************************************************************/
78 static bool parent_override_delete(connection_struct *conn,
79 struct files_struct *dirfsp,
80 const struct smb_filename *smb_fname,
81 uint32_t access_mask,
82 uint32_t rejected_mask)
84 if ((access_mask & DELETE_ACCESS) &&
85 (rejected_mask & DELETE_ACCESS) &&
86 can_delete_file_in_directory(conn,
87 dirfsp,
88 smb_fname))
90 return true;
92 return false;
95 /****************************************************************************
96 Check if we have open rights.
97 ****************************************************************************/
99 static NTSTATUS smbd_check_access_rights_sd(
100 struct connection_struct *conn,
101 struct files_struct *dirfsp,
102 const struct smb_filename *smb_fname,
103 struct security_descriptor *sd,
104 bool use_privs,
105 uint32_t access_mask)
107 uint32_t rejected_share_access;
108 uint32_t rejected_mask = access_mask;
109 uint32_t do_not_check_mask = 0;
110 NTSTATUS status;
112 rejected_share_access = access_mask & ~(conn->share_access);
114 if (rejected_share_access) {
115 DBG_DEBUG("rejected share access 0x%"PRIx32" on "
116 "%s (0x%"PRIx32")\n",
117 access_mask,
118 smb_fname_str_dbg(smb_fname),
119 rejected_share_access);
120 return NT_STATUS_ACCESS_DENIED;
123 if (!use_privs && get_current_uid(conn) == (uid_t)0) {
124 /* I'm sorry sir, I didn't know you were root... */
125 DBG_DEBUG("root override on %s. Granting 0x%x\n",
126 smb_fname_str_dbg(smb_fname),
127 (unsigned int)access_mask);
128 return NT_STATUS_OK;
131 if ((access_mask & DELETE_ACCESS) &&
132 !lp_acl_check_permissions(SNUM(conn)))
134 DBG_DEBUG("Not checking ACL on DELETE_ACCESS on file %s. "
135 "Granting 0x%"PRIx32"\n",
136 smb_fname_str_dbg(smb_fname),
137 access_mask);
138 return NT_STATUS_OK;
141 if (access_mask == DELETE_ACCESS &&
142 VALID_STAT(smb_fname->st) &&
143 S_ISLNK(smb_fname->st.st_ex_mode))
145 /* We can always delete a symlink. */
146 DBG_DEBUG("Not checking ACL on DELETE_ACCESS on symlink %s.\n",
147 smb_fname_str_dbg(smb_fname));
148 return NT_STATUS_OK;
151 if (sd == NULL) {
152 goto access_denied;
156 * If we can access the path to this file, by
157 * default we have FILE_READ_ATTRIBUTES from the
158 * containing directory. See the section:
159 * "Algorithm to Check Access to an Existing File"
160 * in MS-FSA.pdf.
162 * se_file_access_check() also takes care of
163 * owner WRITE_DAC and READ_CONTROL.
165 do_not_check_mask = FILE_READ_ATTRIBUTES;
168 * Samba 3.6 and earlier granted execute access even
169 * if the ACL did not contain execute rights.
170 * Samba 4.0 is more correct and checks it.
171 * The compatibilty mode allows one to skip this check
172 * to smoothen upgrades.
174 if (lp_acl_allow_execute_always(SNUM(conn))) {
175 do_not_check_mask |= FILE_EXECUTE;
178 status = se_file_access_check(sd,
179 get_current_nttok(conn),
180 use_privs,
181 (access_mask & ~do_not_check_mask),
182 &rejected_mask);
184 DBG_DEBUG("File [%s] requesting [0x%"PRIx32"] "
185 "returning [0x%"PRIx32"] (%s)\n",
186 smb_fname_str_dbg(smb_fname),
187 access_mask,
188 rejected_mask,
189 nt_errstr(status));
191 if (!NT_STATUS_IS_OK(status)) {
192 if (DEBUGLEVEL >= 10) {
193 DBG_DEBUG("acl for %s is:\n",
194 smb_fname_str_dbg(smb_fname));
195 NDR_PRINT_DEBUG(security_descriptor, sd);
199 TALLOC_FREE(sd);
201 if (NT_STATUS_IS_OK(status) ||
202 !NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED))
204 return status;
207 /* Here we know status == NT_STATUS_ACCESS_DENIED. */
209 access_denied:
211 if ((access_mask & FILE_WRITE_ATTRIBUTES) &&
212 (rejected_mask & FILE_WRITE_ATTRIBUTES) &&
213 !lp_store_dos_attributes(SNUM(conn)) &&
214 (lp_map_readonly(SNUM(conn)) ||
215 lp_map_archive(SNUM(conn)) ||
216 lp_map_hidden(SNUM(conn)) ||
217 lp_map_system(SNUM(conn))))
219 rejected_mask &= ~FILE_WRITE_ATTRIBUTES;
221 DBG_DEBUG("overrode FILE_WRITE_ATTRIBUTES on file %s\n",
222 smb_fname_str_dbg(smb_fname));
225 if (parent_override_delete(conn,
226 dirfsp,
227 smb_fname,
228 access_mask,
229 rejected_mask))
232 * Were we trying to do an open for delete and didn't get DELETE
233 * access. Check if the directory allows DELETE_CHILD.
234 * See here:
235 * http://blogs.msdn.com/oldnewthing/archive/2004/06/04/148426.aspx
236 * for details.
239 rejected_mask &= ~DELETE_ACCESS;
241 DBG_DEBUG("Overrode DELETE_ACCESS on file %s\n",
242 smb_fname_str_dbg(smb_fname));
245 if (rejected_mask != 0) {
246 return NT_STATUS_ACCESS_DENIED;
248 return NT_STATUS_OK;
251 NTSTATUS smbd_check_access_rights_fsp(struct files_struct *dirfsp,
252 struct files_struct *fsp,
253 bool use_privs,
254 uint32_t access_mask)
256 struct security_descriptor *sd = NULL;
257 NTSTATUS status;
259 /* Cope with fake/printer fsp's. */
260 if (fsp->fake_file_handle != NULL || fsp->print_file != NULL) {
261 if ((fsp->access_mask & access_mask) != access_mask) {
262 return NT_STATUS_ACCESS_DENIED;
264 return NT_STATUS_OK;
267 if (fsp_get_pathref_fd(fsp) == -1) {
269 * This is a POSIX open on a symlink. For the pathname
270 * version of this function we used to return the st_mode
271 * bits turned into an NT ACL. For a symlink the mode bits
272 * are always rwxrwxrwx which means the pathname version always
273 * returned NT_STATUS_OK for a symlink. For the handle reference
274 * to a symlink use the handle access bits.
276 if ((fsp->access_mask & access_mask) != access_mask) {
277 return NT_STATUS_ACCESS_DENIED;
279 return NT_STATUS_OK;
282 status = SMB_VFS_FGET_NT_ACL(fsp,
283 (SECINFO_OWNER |
284 SECINFO_GROUP |
285 SECINFO_DACL),
286 talloc_tos(),
287 &sd);
288 if (!NT_STATUS_IS_OK(status)) {
289 DBG_DEBUG("Could not get acl on %s: %s\n",
290 fsp_str_dbg(fsp),
291 nt_errstr(status));
292 return status;
295 return smbd_check_access_rights_sd(fsp->conn,
296 dirfsp,
297 fsp->fsp_name,
299 use_privs,
300 access_mask);
304 * Given an fsp that represents a parent directory,
305 * check if the requested access can be granted.
307 NTSTATUS check_parent_access_fsp(struct files_struct *fsp,
308 uint32_t access_mask)
310 NTSTATUS status;
311 struct security_descriptor *parent_sd = NULL;
312 uint32_t access_granted = 0;
313 struct share_mode_lock *lck = NULL;
314 uint32_t name_hash;
315 bool delete_on_close_set;
316 TALLOC_CTX *frame = talloc_stackframe();
318 if (get_current_uid(fsp->conn) == (uid_t)0) {
319 /* I'm sorry sir, I didn't know you were root... */
320 DBG_DEBUG("root override on %s. Granting 0x%x\n",
321 fsp_str_dbg(fsp),
322 (unsigned int)access_mask);
323 status = NT_STATUS_OK;
324 goto out;
327 status = SMB_VFS_FGET_NT_ACL(fsp,
328 SECINFO_DACL,
329 frame,
330 &parent_sd);
332 if (!NT_STATUS_IS_OK(status)) {
333 DBG_INFO("SMB_VFS_FGET_NT_ACL failed for "
334 "%s with error %s\n",
335 fsp_str_dbg(fsp),
336 nt_errstr(status));
337 goto out;
341 * If we can access the path to this file, by
342 * default we have FILE_READ_ATTRIBUTES from the
343 * containing directory. See the section:
344 * "Algorithm to Check Access to an Existing File"
345 * in MS-FSA.pdf.
347 * se_file_access_check() also takes care of
348 * owner WRITE_DAC and READ_CONTROL.
350 status = se_file_access_check(parent_sd,
351 get_current_nttok(fsp->conn),
352 false,
353 (access_mask & ~FILE_READ_ATTRIBUTES),
354 &access_granted);
355 if(!NT_STATUS_IS_OK(status)) {
356 DBG_INFO("access check "
357 "on directory %s for mask 0x%x returned (0x%x) %s\n",
358 fsp_str_dbg(fsp),
359 access_mask,
360 access_granted,
361 nt_errstr(status));
362 goto out;
365 if (!(access_mask & (SEC_DIR_ADD_FILE | SEC_DIR_ADD_SUBDIR))) {
366 status = NT_STATUS_OK;
367 goto out;
369 if (!lp_check_parent_directory_delete_on_close(SNUM(fsp->conn))) {
370 status = NT_STATUS_OK;
371 goto out;
374 /* Check if the directory has delete-on-close set */
375 status = file_name_hash(fsp->conn,
376 fsp->fsp_name->base_name,
377 &name_hash);
378 if (!NT_STATUS_IS_OK(status)) {
379 goto out;
383 * Don't take a lock here. We just need a snapshot
384 * of the current state of delete on close and this is
385 * called in a codepath where we may already have a lock
386 * (and we explicitly can't hold 2 locks at the same time
387 * as that may deadlock).
389 lck = fetch_share_mode_unlocked(frame, fsp->file_id);
390 if (lck == NULL) {
391 status = NT_STATUS_OK;
392 goto out;
395 delete_on_close_set = is_delete_on_close_set(lck, name_hash);
396 if (delete_on_close_set) {
397 status = NT_STATUS_DELETE_PENDING;
398 goto out;
401 status = NT_STATUS_OK;
403 out:
404 TALLOC_FREE(frame);
405 return status;
408 /****************************************************************************
409 Ensure when opening a base file for a stream open that we have permissions
410 to do so given the access mask on the base file.
411 ****************************************************************************/
413 static NTSTATUS check_base_file_access(struct files_struct *fsp,
414 uint32_t access_mask)
416 NTSTATUS status;
418 status = smbd_calculate_access_mask_fsp(fsp->conn->cwd_fsp,
419 fsp,
420 false,
421 access_mask,
422 &access_mask);
423 if (!NT_STATUS_IS_OK(status)) {
424 DEBUG(10, ("smbd_calculate_access_mask "
425 "on file %s returned %s\n",
426 fsp_str_dbg(fsp),
427 nt_errstr(status)));
428 return status;
431 if (access_mask & (FILE_WRITE_DATA|FILE_APPEND_DATA)) {
432 uint32_t dosattrs;
433 if (!CAN_WRITE(fsp->conn)) {
434 return NT_STATUS_ACCESS_DENIED;
436 dosattrs = fdos_mode(fsp);
437 if (IS_DOS_READONLY(dosattrs)) {
438 return NT_STATUS_ACCESS_DENIED;
442 return smbd_check_access_rights_fsp(fsp->conn->cwd_fsp,
443 fsp,
444 false,
445 access_mask);
448 /****************************************************************************
449 Handle differing symlink errno's
450 ****************************************************************************/
452 static NTSTATUS link_errno_convert(int err)
454 #if defined(ENOTSUP) && defined(OSF1)
455 /* handle special Tru64 errno */
456 if (err == ENOTSUP) {
457 err = ELOOP;
459 #endif /* ENOTSUP */
460 #ifdef EFTYPE
461 /* fix broken NetBSD errno */
462 if (err == EFTYPE) {
463 err = ELOOP;
465 #endif /* EFTYPE */
466 /* fix broken FreeBSD errno */
467 if (err == EMLINK) {
468 err = ELOOP;
470 if (err == ELOOP) {
471 return NT_STATUS_STOPPED_ON_SYMLINK;
473 return map_nt_error_from_unix(err);
476 static NTSTATUS non_widelink_open(const struct files_struct *dirfsp,
477 files_struct *fsp,
478 struct smb_filename *smb_fname,
479 int flags,
480 mode_t mode,
481 unsigned int link_depth);
483 /****************************************************************************
484 Follow a symlink in userspace.
485 ****************************************************************************/
487 static NTSTATUS process_symlink_open(const struct files_struct *dirfsp,
488 files_struct *fsp,
489 struct smb_filename *smb_fname,
490 int flags,
491 mode_t mode,
492 unsigned int link_depth)
494 struct connection_struct *conn = dirfsp->conn;
495 const char *conn_rootdir = NULL;
496 struct smb_filename conn_rootdir_fname = { 0 };
497 char *link_target = NULL;
498 int link_len = -1;
499 struct smb_filename *oldwd_fname = NULL;
500 size_t rootdir_len = 0;
501 struct smb_filename *resolved_fname = NULL;
502 char *resolved_name = NULL;
503 bool matched = false;
504 struct smb_filename *full_fname = NULL;
505 NTSTATUS status;
507 conn_rootdir = SMB_VFS_CONNECTPATH(conn, smb_fname);
508 if (conn_rootdir == NULL) {
509 return NT_STATUS_NO_MEMORY;
512 * With shadow_copy2 conn_rootdir can be talloc_freed
513 * whilst we use it in this function. We must take a copy.
515 conn_rootdir_fname.base_name = talloc_strdup(talloc_tos(),
516 conn_rootdir);
517 if (conn_rootdir_fname.base_name == NULL) {
518 return NT_STATUS_NO_MEMORY;
522 * Ensure we don't get stuck in a symlink loop.
524 link_depth++;
525 if (link_depth >= 20) {
526 status = NT_STATUS_STOPPED_ON_SYMLINK;
527 goto out;
530 /* Allocate space for the link target. */
531 link_target = talloc_array(talloc_tos(), char, PATH_MAX);
532 if (link_target == NULL) {
533 status = NT_STATUS_NO_MEMORY;
534 goto out;
538 * Read the link target. We do this just to verify that smb_fname indeed
539 * points at a symbolic link and return NT_STATUS_NOT_A_DIRECTORY
540 * and failure in case smb_fname is NOT a symlink.
542 * The caller needs this piece of information to distinguish two cases
543 * where open() fails with errno=ENOTDIR, cf the comment in
544 * non_widelink_open().
546 * We rely on SMB_VFS_REALPATH() to resolve the path including the
547 * symlink. Once we have SMB_VFS_STATX() or something similar in our VFS
548 * we may want to use that instead of SMB_VFS_READLINKAT().
550 link_len = SMB_VFS_READLINKAT(conn,
551 dirfsp,
552 smb_fname,
553 link_target,
554 PATH_MAX - 1);
555 if (link_len == -1) {
556 status = NT_STATUS_INVALID_PARAMETER;
557 goto out;
560 full_fname = full_path_from_dirfsp_atname(
561 talloc_tos(), dirfsp, smb_fname);
562 if (full_fname == NULL) {
563 status = NT_STATUS_NO_MEMORY;
564 goto out;
567 /* Convert to an absolute path. */
568 resolved_fname = SMB_VFS_REALPATH(conn, talloc_tos(), full_fname);
569 if (resolved_fname == NULL) {
570 status = map_nt_error_from_unix(errno);
571 goto out;
573 resolved_name = resolved_fname->base_name;
576 * We know conn_rootdir starts with '/' and
577 * does not end in '/'. FIXME ! Should we
578 * smb_assert this ?
580 rootdir_len = strlen(conn_rootdir_fname.base_name);
582 matched = (strncmp(conn_rootdir_fname.base_name,
583 resolved_name,
584 rootdir_len) == 0);
585 if (!matched) {
586 status = NT_STATUS_STOPPED_ON_SYMLINK;
587 goto out;
591 * Turn into a path relative to the share root.
593 if (resolved_name[rootdir_len] == '\0') {
594 /* Link to the root of the share. */
595 TALLOC_FREE(smb_fname->base_name);
596 smb_fname->base_name = talloc_strdup(smb_fname, ".");
597 } else if (resolved_name[rootdir_len] == '/') {
598 TALLOC_FREE(smb_fname->base_name);
599 smb_fname->base_name = talloc_strdup(smb_fname,
600 &resolved_name[rootdir_len+1]);
601 } else {
602 status = NT_STATUS_STOPPED_ON_SYMLINK;
603 goto out;
606 if (smb_fname->base_name == NULL) {
607 status = NT_STATUS_NO_MEMORY;
608 goto out;
611 oldwd_fname = vfs_GetWd(talloc_tos(), dirfsp->conn);
612 if (oldwd_fname == NULL) {
613 status = map_nt_error_from_unix(errno);
614 goto out;
617 /* Ensure we operate from the root of the share. */
618 if (vfs_ChDir(conn, &conn_rootdir_fname) == -1) {
619 status = map_nt_error_from_unix(errno);
620 goto out;
624 * And do it all again... As smb_fname is not relative to the passed in
625 * dirfsp anymore, we pass conn->cwd_fsp as dirfsp to
626 * non_widelink_open() to trigger the chdir(parentdir) logic.
628 status = non_widelink_open(conn->cwd_fsp,
629 fsp,
630 smb_fname,
631 flags,
632 mode,
633 link_depth);
635 out:
637 TALLOC_FREE(resolved_fname);
638 TALLOC_FREE(link_target);
639 TALLOC_FREE(conn_rootdir_fname.base_name);
640 if (oldwd_fname != NULL) {
641 int ret = vfs_ChDir(conn, oldwd_fname);
642 if (ret == -1) {
643 smb_panic("unable to get back to old directory\n");
645 TALLOC_FREE(oldwd_fname);
648 return status;
651 /****************************************************************************
652 Non-widelink open.
653 ****************************************************************************/
655 static NTSTATUS non_widelink_open(const struct files_struct *dirfsp,
656 files_struct *fsp,
657 struct smb_filename *smb_fname,
658 int flags,
659 mode_t mode,
660 unsigned int link_depth)
662 struct connection_struct *conn = fsp->conn;
663 NTSTATUS saved_status;
664 NTSTATUS status = NT_STATUS_OK;
665 int fd = -1;
666 struct smb_filename *orig_fsp_name = fsp->fsp_name;
667 struct smb_filename *orig_base_fsp_name = NULL;
668 struct smb_filename *smb_fname_rel = NULL;
669 struct smb_filename *oldwd_fname = NULL;
670 struct smb_filename *parent_dir_fname = NULL;
671 bool have_opath = false;
672 bool is_share_root = false;
673 int ret;
675 #ifdef O_PATH
676 have_opath = true;
677 #endif
679 if (smb_fname->base_name[0] == '/') {
680 const char *connpath = SMB_VFS_CONNECTPATH(conn, smb_fname);
681 int cmp = strcmp(connpath, smb_fname->base_name);
683 if (cmp == 0) {
684 is_share_root = true;
688 if (!is_share_root && (dirfsp == conn->cwd_fsp)) {
689 struct smb_filename *smb_fname_dot = NULL;
691 status = SMB_VFS_PARENT_PATHNAME(fsp->conn,
692 talloc_tos(),
693 smb_fname,
694 &parent_dir_fname,
695 &smb_fname_rel);
696 if (!NT_STATUS_IS_OK(status)) {
697 goto out;
700 if (!ISDOT(parent_dir_fname->base_name)) {
701 oldwd_fname = vfs_GetWd(talloc_tos(), conn);
702 if (oldwd_fname == NULL) {
703 status = map_nt_error_from_unix(errno);
704 goto out;
707 /* Pin parent directory in place. */
708 if (vfs_ChDir(conn, parent_dir_fname) == -1) {
709 status = map_nt_error_from_unix(errno);
710 goto out;
714 smb_fname_dot = synthetic_smb_fname(
715 parent_dir_fname,
716 ".",
717 NULL,
718 NULL,
720 smb_fname->flags);
721 if (smb_fname_dot == NULL) {
722 status = NT_STATUS_NO_MEMORY;
723 goto out;
726 /* Ensure the relative path is below the share. */
727 status = check_reduced_name(conn, parent_dir_fname, smb_fname_dot);
728 TALLOC_FREE(smb_fname_dot);
729 if (!NT_STATUS_IS_OK(status)) {
730 goto out;
733 /* Setup fsp->fsp_name to be relative to cwd */
734 fsp->fsp_name = smb_fname_rel;
736 /* Also setup base_fsp to be relative to the new cwd */
737 if (fsp->base_fsp != NULL) {
738 struct smb_filename *base_smb_fname_rel = NULL;
740 /* Check the invarient is true. */
741 SMB_ASSERT(fsp->base_fsp->fsp_name->fsp ==
742 fsp->base_fsp);
744 base_smb_fname_rel = synthetic_smb_fname(
745 talloc_tos(),
746 smb_fname_rel->base_name,
747 NULL,
748 &smb_fname_rel->st,
749 smb_fname_rel->twrp,
750 smb_fname_rel->flags);
751 if (base_smb_fname_rel == NULL) {
752 status = NT_STATUS_NO_MEMORY;
753 goto out;
756 base_smb_fname_rel->fsp = fsp->base_fsp;
758 orig_base_fsp_name = fsp->base_fsp->fsp_name;
759 fsp->base_fsp->fsp_name = base_smb_fname_rel;
762 * We should have preserved the invarient
763 * fsp->base_fsp->fsp_name->fsp == fsp->base_fsp.
765 SMB_ASSERT(fsp->base_fsp->fsp_name->fsp ==
766 fsp->base_fsp);
768 } else {
770 * fsp->fsp_name is unchanged as it is already correctly
771 * relative to conn->cwd.
773 smb_fname_rel = smb_fname;
776 if (!is_share_root) {
777 char *slash = strchr_m(smb_fname_rel->base_name, '/');
778 SMB_ASSERT(slash == NULL);
781 flags |= O_NOFOLLOW;
783 fd = SMB_VFS_OPENAT(conn,
784 dirfsp,
785 smb_fname_rel,
786 fsp,
787 flags,
788 mode);
789 if (fd == -1) {
790 status = link_errno_convert(errno);
792 fsp_set_fd(fsp, fd);
794 if ((fd == -1) &&
795 NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK) &&
796 fsp->fsp_flags.is_pathref &&
797 !have_opath) {
798 ret = SMB_VFS_FSTATAT(
799 fsp->conn,
800 dirfsp,
801 smb_fname_rel,
802 &fsp->fsp_name->st,
803 AT_SYMLINK_NOFOLLOW);
804 if (ret == -1) {
805 status = map_nt_error_from_unix(errno);
806 DBG_DEBUG("fstatat(%s) failed: %s\n",
807 smb_fname_str_dbg(smb_fname),
808 strerror(errno));
809 goto out;
813 if (fd != -1) {
814 ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st);
815 if (ret != 0) {
816 status = map_nt_error_from_unix(errno);
817 goto out;
819 orig_fsp_name->st = fsp->fsp_name->st;
822 if (!is_ntfs_stream_smb_fname(fsp->fsp_name) &&
823 fsp->fsp_flags.is_pathref &&
824 have_opath)
827 * Opening with O_PATH and O_NOFOLLOW opens a handle on the
828 * symlink. In follow symlink=yes mode we must avoid this and
829 * instead should open a handle on the symlink target.
831 * Check for this case by doing an fstat, forcing
832 * process_symlink_open() codepath down below by setting fd=-1
833 * and errno=ELOOP.
835 if (S_ISLNK(fsp->fsp_name->st.st_ex_mode)) {
836 status = fd_close(fsp);
837 SMB_ASSERT(NT_STATUS_IS_OK(status));
838 fd = -1;
839 status = NT_STATUS_STOPPED_ON_SYMLINK;
843 if ((fd == -1) &&
844 (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK) ||
845 NT_STATUS_EQUAL(status, NT_STATUS_NOT_A_DIRECTORY)))
848 * Trying to open a symlink to a directory with O_NOFOLLOW and
849 * O_DIRECTORY can return either of ELOOP and ENOTDIR. So
850 * ENOTDIR really means: might be a symlink, but we're not sure.
851 * In this case, we just assume there's a symlink. If we were
852 * wrong, process_symlink_open() will return EINVAL. We check
853 * this below, and fall back to returning the initial
854 * saved_errno.
856 * BUG: https://bugzilla.samba.org/show_bug.cgi?id=12860
858 saved_status = status;
860 if (fsp->fsp_name->flags & SMB_FILENAME_POSIX_PATH) {
861 /* Never follow symlinks on posix open, .. but
862 * pass the fact it's a symlink in
863 * smb_fname->st
865 smb_fname->st = fsp->fsp_name->st;
866 goto out;
868 if (!lp_follow_symlinks(SNUM(conn))) {
869 /* Explicitly no symlinks. */
870 goto out;
873 fsp->fsp_name = orig_fsp_name;
876 * We may have a symlink. Follow in userspace
877 * to ensure it's under the share definition.
879 status = process_symlink_open(dirfsp,
880 fsp,
881 smb_fname_rel,
882 flags,
883 mode,
884 link_depth);
885 if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER) &&
886 NT_STATUS_EQUAL(saved_status, NT_STATUS_NOT_A_DIRECTORY))
888 status = saved_status;
892 out:
893 fsp->fsp_name = orig_fsp_name;
894 if (fsp->base_fsp != NULL) {
895 /* Save off the temporary name. */
896 struct smb_filename *base_smb_fname_rel =
897 fsp->base_fsp->fsp_name;
898 /* It no longer has an associated fsp. */
899 base_smb_fname_rel->fsp = NULL;
901 /* Replace the original name. */
902 fsp->base_fsp->fsp_name = orig_base_fsp_name;
904 * We should have preserved the invarient
905 * fsp->base_fsp->fsp_name->fsp == fsp->base_fsp.
907 SMB_ASSERT(fsp->base_fsp->fsp_name->fsp == fsp->base_fsp);
908 TALLOC_FREE(base_smb_fname_rel);
910 TALLOC_FREE(parent_dir_fname);
912 if (oldwd_fname != NULL) {
913 ret = vfs_ChDir(conn, oldwd_fname);
914 if (ret == -1) {
915 smb_panic("unable to get back to old directory\n");
917 TALLOC_FREE(oldwd_fname);
919 return status;
922 /****************************************************************************
923 fd support routines - attempt to do a dos_open.
924 ****************************************************************************/
926 NTSTATUS fd_openat(const struct files_struct *dirfsp,
927 struct smb_filename *smb_fname,
928 files_struct *fsp,
929 int flags,
930 mode_t mode)
932 struct connection_struct *conn = fsp->conn;
933 NTSTATUS status = NT_STATUS_OK;
936 * Never follow symlinks on a POSIX client. The
937 * client should be doing this.
940 if ((fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) || !lp_follow_symlinks(SNUM(conn))) {
941 flags |= O_NOFOLLOW;
945 * Only follow symlinks within a share
946 * definition.
948 status = non_widelink_open(dirfsp, fsp, smb_fname, flags, mode, 0);
949 if (!NT_STATUS_IS_OK(status)) {
950 if (NT_STATUS_EQUAL(status, NT_STATUS_TOO_MANY_OPENED_FILES)) {
951 static time_t last_warned = 0L;
953 if (time((time_t *) NULL) > last_warned) {
954 DEBUG(0,("Too many open files, unable "
955 "to open more! smbd's max "
956 "open files = %d\n",
957 lp_max_open_files()));
958 last_warned = time((time_t *) NULL);
962 DBG_DEBUG("name %s, flags = 0%o mode = 0%o, fd = %d. %s\n",
963 smb_fname_str_dbg(smb_fname), flags, (int)mode,
964 fsp_get_pathref_fd(fsp), nt_errstr(status));
965 return status;
968 DBG_DEBUG("name %s, flags = 0%o mode = 0%o, fd = %d\n",
969 smb_fname_str_dbg(smb_fname), flags, (int)mode,
970 fsp_get_pathref_fd(fsp));
972 return status;
975 /****************************************************************************
976 Close the file associated with a fsp.
977 ****************************************************************************/
979 NTSTATUS fd_close(files_struct *fsp)
981 int ret;
983 if (fsp == fsp->conn->cwd_fsp) {
984 return NT_STATUS_OK;
987 if (fsp->dptr) {
988 dptr_CloseDir(fsp);
990 if (fsp_get_pathref_fd(fsp) == -1) {
992 * Either a directory where the dptr_CloseDir() already closed
993 * the fd or a stat open.
995 return NT_STATUS_OK;
997 if (fh_get_refcount(fsp->fh) > 1) {
998 return NT_STATUS_OK; /* Shared handle. Only close last reference. */
1001 ret = SMB_VFS_CLOSE(fsp);
1002 fsp_set_fd(fsp, -1);
1003 if (ret == -1) {
1004 return map_nt_error_from_unix(errno);
1006 return NT_STATUS_OK;
1009 /****************************************************************************
1010 Change the ownership of a file to that of the parent directory.
1011 Do this by fd if possible.
1012 ****************************************************************************/
1014 static void change_file_owner_to_parent_fsp(struct files_struct *parent_fsp,
1015 struct files_struct *fsp)
1017 int ret;
1019 if (parent_fsp->fsp_name->st.st_ex_uid == fsp->fsp_name->st.st_ex_uid) {
1020 /* Already this uid - no need to change. */
1021 DBG_DEBUG("file %s is already owned by uid %u\n",
1022 fsp_str_dbg(fsp),
1023 (unsigned int)fsp->fsp_name->st.st_ex_uid);
1024 return;
1027 become_root();
1028 ret = SMB_VFS_FCHOWN(fsp,
1029 parent_fsp->fsp_name->st.st_ex_uid,
1030 (gid_t)-1);
1031 unbecome_root();
1032 if (ret == -1) {
1033 DBG_ERR("failed to fchown "
1034 "file %s to parent directory uid %u. Error "
1035 "was %s\n",
1036 fsp_str_dbg(fsp),
1037 (unsigned int)parent_fsp->fsp_name->st.st_ex_uid,
1038 strerror(errno));
1039 } else {
1040 DBG_DEBUG("changed new file %s to "
1041 "parent directory uid %u.\n",
1042 fsp_str_dbg(fsp),
1043 (unsigned int)parent_fsp->fsp_name->st.st_ex_uid);
1044 /* Ensure the uid entry is updated. */
1045 fsp->fsp_name->st.st_ex_uid =
1046 parent_fsp->fsp_name->st.st_ex_uid;
1050 static NTSTATUS change_dir_owner_to_parent_fsp(struct files_struct *parent_fsp,
1051 struct files_struct *fsp)
1053 NTSTATUS status;
1054 int ret;
1056 if (parent_fsp->fsp_name->st.st_ex_uid == fsp->fsp_name->st.st_ex_uid) {
1057 /* Already this uid - no need to change. */
1058 DBG_DEBUG("directory %s is already owned by uid %u\n",
1059 fsp_str_dbg(fsp),
1060 (unsigned int)fsp->fsp_name->st.st_ex_uid);
1061 return NT_STATUS_OK;
1064 become_root();
1065 ret = SMB_VFS_FCHOWN(fsp,
1066 parent_fsp->fsp_name->st.st_ex_uid,
1067 (gid_t)-1);
1068 unbecome_root();
1069 if (ret == -1) {
1070 status = map_nt_error_from_unix(errno);
1071 DBG_ERR("failed to chown "
1072 "directory %s to parent directory uid %u. "
1073 "Error was %s\n",
1074 fsp_str_dbg(fsp),
1075 (unsigned int)parent_fsp->fsp_name->st.st_ex_uid,
1076 nt_errstr(status));
1077 return status;
1080 DBG_DEBUG("changed ownership of new "
1081 "directory %s to parent directory uid %u.\n",
1082 fsp_str_dbg(fsp),
1083 (unsigned int)parent_fsp->fsp_name->st.st_ex_uid);
1085 /* Ensure the uid entry is updated. */
1086 fsp->fsp_name->st.st_ex_uid = parent_fsp->fsp_name->st.st_ex_uid;
1088 return NT_STATUS_OK;
1091 /****************************************************************************
1092 Open a file - returning a guaranteed ATOMIC indication of if the
1093 file was created or not.
1094 ****************************************************************************/
1096 static NTSTATUS fd_open_atomic(struct files_struct *dirfsp,
1097 struct smb_filename *smb_fname,
1098 files_struct *fsp,
1099 int flags,
1100 mode_t mode,
1101 bool *file_created)
1103 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
1104 NTSTATUS retry_status;
1105 bool file_existed = VALID_STAT(smb_fname->st);
1106 int curr_flags;
1108 if (!(flags & O_CREAT)) {
1110 * We're not creating the file, just pass through.
1112 status = fd_openat(dirfsp, smb_fname, fsp, flags, mode);
1113 *file_created = false;
1114 return status;
1117 if (flags & O_EXCL) {
1119 * Fail if already exists, just pass through.
1121 status = fd_openat(dirfsp, smb_fname, fsp, flags, mode);
1124 * Here we've opened with O_CREAT|O_EXCL. If that went
1125 * NT_STATUS_OK, we *know* we created this file.
1127 *file_created = NT_STATUS_IS_OK(status);
1129 return status;
1133 * Now it gets tricky. We have O_CREAT, but not O_EXCL.
1134 * To know absolutely if we created the file or not,
1135 * we can never call O_CREAT without O_EXCL. So if
1136 * we think the file existed, try without O_CREAT|O_EXCL.
1137 * If we think the file didn't exist, try with
1138 * O_CREAT|O_EXCL.
1140 * The big problem here is dangling symlinks. Opening
1141 * without O_NOFOLLOW means both bad symlink
1142 * and missing path return -1, ENOENT from open(). As POSIX
1143 * is pathname based it's not possible to tell
1144 * the difference between these two cases in a
1145 * non-racy way, so change to try only two attempts before
1146 * giving up.
1148 * We don't have this problem for the O_NOFOLLOW
1149 * case as it just returns NT_STATUS_OBJECT_PATH_NOT_FOUND
1150 * mapped from the ELOOP POSIX error.
1153 if (file_existed) {
1154 curr_flags = flags & ~(O_CREAT);
1155 retry_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
1156 } else {
1157 curr_flags = flags | O_EXCL;
1158 retry_status = NT_STATUS_OBJECT_NAME_COLLISION;
1161 status = fd_openat(dirfsp, smb_fname, fsp, curr_flags, mode);
1162 if (NT_STATUS_IS_OK(status)) {
1163 *file_created = !file_existed;
1164 return NT_STATUS_OK;
1166 if (NT_STATUS_EQUAL(status, retry_status)) {
1168 file_existed = !file_existed;
1170 DBG_DEBUG("File %s %s. Retry.\n",
1171 fsp_str_dbg(fsp),
1172 file_existed ? "existed" : "did not exist");
1174 if (file_existed) {
1175 curr_flags = flags & ~(O_CREAT);
1176 } else {
1177 curr_flags = flags | O_EXCL;
1180 status = fd_openat(dirfsp, smb_fname, fsp, curr_flags, mode);
1183 *file_created = (NT_STATUS_IS_OK(status) && !file_existed);
1184 return status;
1187 static NTSTATUS reopen_from_procfd(struct files_struct *fsp,
1188 int flags,
1189 mode_t mode)
1191 struct smb_filename proc_fname;
1192 const char *p = NULL;
1193 char buf[PATH_MAX];
1194 int old_fd;
1195 int new_fd;
1196 NTSTATUS status;
1198 if (!fsp->fsp_flags.have_proc_fds) {
1199 return NT_STATUS_MORE_PROCESSING_REQUIRED;
1202 old_fd = fsp_get_pathref_fd(fsp);
1203 if (old_fd == -1) {
1204 return NT_STATUS_MORE_PROCESSING_REQUIRED;
1207 if (!fsp->fsp_flags.is_pathref) {
1208 DBG_ERR("[%s] is not a pathref\n",
1209 fsp_str_dbg(fsp));
1210 #ifdef DEVELOPER
1211 smb_panic("Not a pathref");
1212 #endif
1213 return NT_STATUS_INVALID_HANDLE;
1216 p = sys_proc_fd_path(old_fd, buf, sizeof(buf));
1217 if (p == NULL) {
1218 return NT_STATUS_NO_MEMORY;
1221 proc_fname = (struct smb_filename) {
1222 .base_name = discard_const_p(char, p),
1225 fsp->fsp_flags.is_pathref = false;
1227 new_fd = SMB_VFS_OPENAT(fsp->conn,
1228 fsp->conn->cwd_fsp,
1229 &proc_fname,
1230 fsp,
1231 flags,
1232 mode);
1233 if (new_fd == -1) {
1234 status = map_nt_error_from_unix(errno);
1235 fd_close(fsp);
1236 return status;
1239 status = fd_close(fsp);
1240 if (!NT_STATUS_IS_OK(status)) {
1241 return status;
1244 fsp_set_fd(fsp, new_fd);
1245 return NT_STATUS_OK;
1248 static NTSTATUS reopen_from_fsp(struct files_struct *dirfsp,
1249 struct smb_filename *smb_fname,
1250 struct files_struct *fsp,
1251 int flags,
1252 mode_t mode,
1253 bool *p_file_created)
1255 bool __unused_file_created = false;
1256 NTSTATUS status;
1258 if (p_file_created == NULL) {
1259 p_file_created = &__unused_file_created;
1263 * TODO: should we move this to the VFS layer?
1264 * SMB_VFS_REOPEN_FSP()?
1267 status = reopen_from_procfd(fsp,
1268 flags,
1269 mode);
1270 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1271 return status;
1275 * Close the existing pathref fd and set the fsp flag
1276 * is_pathref to false so we get a "normal" fd this time.
1278 status = fd_close(fsp);
1279 if (!NT_STATUS_IS_OK(status)) {
1280 return status;
1283 fsp->fsp_flags.is_pathref = false;
1285 status = fd_open_atomic(
1286 dirfsp,
1287 smb_fname,
1288 fsp,
1289 flags,
1290 mode,
1291 p_file_created);
1292 return status;
1295 /****************************************************************************
1296 Open a file.
1297 ****************************************************************************/
1299 static NTSTATUS open_file(files_struct *fsp,
1300 struct smb_request *req,
1301 struct files_struct *dirfsp,
1302 int flags,
1303 mode_t unx_mode,
1304 uint32_t access_mask, /* client requested access mask. */
1305 uint32_t open_access_mask, /* what we're actually using in the open. */
1306 uint32_t private_flags,
1307 bool *p_file_created)
1309 connection_struct *conn = fsp->conn;
1310 struct smb_filename *smb_fname = fsp->fsp_name;
1311 NTSTATUS status = NT_STATUS_OK;
1312 int accmode = (flags & O_ACCMODE);
1313 int local_flags = flags;
1314 bool file_existed = VALID_STAT(fsp->fsp_name->st);
1315 uint32_t need_fd_mask =
1316 FILE_READ_DATA |
1317 FILE_WRITE_DATA |
1318 FILE_APPEND_DATA |
1319 FILE_EXECUTE |
1320 SEC_FLAG_SYSTEM_SECURITY;
1321 bool creating = !file_existed && (flags & O_CREAT);
1322 bool truncating = (flags & O_TRUNC);
1323 bool open_fd = false;
1324 bool posix_open = (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN);
1327 * Catch early an attempt to open an existing
1328 * directory as a file.
1330 if (file_existed && S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
1331 return NT_STATUS_FILE_IS_A_DIRECTORY;
1334 /* Check permissions */
1337 * This code was changed after seeing a client open request
1338 * containing the open mode of (DENY_WRITE/read-only) with
1339 * the 'create if not exist' bit set. The previous code
1340 * would fail to open the file read only on a read-only share
1341 * as it was checking the flags parameter directly against O_RDONLY,
1342 * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
1343 * JRA.
1346 if (!CAN_WRITE(conn)) {
1347 /* It's a read-only share - fail if we wanted to write. */
1348 if(accmode != O_RDONLY || (flags & O_TRUNC) || (flags & O_APPEND)) {
1349 DEBUG(3,("Permission denied opening %s\n",
1350 smb_fname_str_dbg(smb_fname)));
1351 return NT_STATUS_ACCESS_DENIED;
1353 if (flags & O_CREAT) {
1354 /* We don't want to write - but we must make sure that
1355 O_CREAT doesn't create the file if we have write
1356 access into the directory.
1358 flags &= ~(O_CREAT|O_EXCL);
1359 local_flags &= ~(O_CREAT|O_EXCL);
1364 * This little piece of insanity is inspired by the
1365 * fact that an NT client can open a file for O_RDONLY,
1366 * but set the create disposition to FILE_EXISTS_TRUNCATE.
1367 * If the client *can* write to the file, then it expects to
1368 * truncate the file, even though it is opening for readonly.
1369 * Quicken uses this stupid trick in backup file creation...
1370 * Thanks *greatly* to "David W. Chapman Jr." <dwcjr@inethouston.net>
1371 * for helping track this one down. It didn't bite us in 2.0.x
1372 * as we always opened files read-write in that release. JRA.
1375 if ((accmode == O_RDONLY) && ((flags & O_TRUNC) == O_TRUNC)) {
1376 DEBUG(10,("open_file: truncate requested on read-only open "
1377 "for file %s\n", smb_fname_str_dbg(smb_fname)));
1378 local_flags = (flags & ~O_ACCMODE)|O_RDWR;
1381 if ((open_access_mask & need_fd_mask) || creating || truncating) {
1382 open_fd = true;
1385 if (open_fd) {
1386 const char *wild;
1387 int ret;
1389 #if defined(O_NONBLOCK) && defined(S_ISFIFO)
1391 * We would block on opening a FIFO with no one else on the
1392 * other end. Do what we used to do and add O_NONBLOCK to the
1393 * open flags. JRA.
1396 if (file_existed && S_ISFIFO(smb_fname->st.st_ex_mode)) {
1397 local_flags &= ~O_TRUNC; /* Can't truncate a FIFO. */
1398 local_flags |= O_NONBLOCK;
1399 truncating = false;
1401 #endif
1403 /* Don't create files with Microsoft wildcard characters. */
1404 if (fsp->base_fsp) {
1406 * wildcard characters are allowed in stream names
1407 * only test the basefilename
1409 wild = fsp->base_fsp->fsp_name->base_name;
1410 } else {
1411 wild = smb_fname->base_name;
1413 if ((local_flags & O_CREAT) && !file_existed &&
1414 !(fsp->posix_flags & FSP_POSIX_FLAGS_PATHNAMES) &&
1415 ms_has_wild(wild)) {
1416 return NT_STATUS_OBJECT_NAME_INVALID;
1419 /* Can we access this file ? */
1420 if (!fsp->base_fsp) {
1421 /* Only do this check on non-stream open. */
1422 if (file_existed) {
1423 status = smbd_check_access_rights_fsp(
1424 dirfsp,
1425 fsp,
1426 false,
1427 access_mask);
1429 if (!NT_STATUS_IS_OK(status)) {
1430 DBG_DEBUG("smbd_check_access_rights_fsp"
1431 " on file %s returned %s\n",
1432 fsp_str_dbg(fsp),
1433 nt_errstr(status));
1436 if (!NT_STATUS_IS_OK(status) &&
1437 !NT_STATUS_EQUAL(status,
1438 NT_STATUS_OBJECT_NAME_NOT_FOUND))
1440 return status;
1443 if (NT_STATUS_EQUAL(status,
1444 NT_STATUS_OBJECT_NAME_NOT_FOUND))
1446 DEBUG(10, ("open_file: "
1447 "file %s vanished since we "
1448 "checked for existence.\n",
1449 smb_fname_str_dbg(smb_fname)));
1450 file_existed = false;
1451 SET_STAT_INVALID(fsp->fsp_name->st);
1455 if (!file_existed) {
1456 if (!(local_flags & O_CREAT)) {
1457 /* File didn't exist and no O_CREAT. */
1458 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1461 status = check_parent_access_fsp(
1462 dirfsp,
1463 SEC_DIR_ADD_FILE);
1464 if (!NT_STATUS_IS_OK(status)) {
1465 DBG_DEBUG("check_parent_access_fsp on "
1466 "directory %s for file %s "
1467 "returned %s\n",
1468 smb_fname_str_dbg(
1469 dirfsp->fsp_name),
1470 smb_fname_str_dbg(smb_fname),
1471 nt_errstr(status));
1472 return status;
1478 * Actually do the open - if O_TRUNC is needed handle it
1479 * below under the share mode lock.
1481 status = reopen_from_fsp(fsp->conn->cwd_fsp,
1482 fsp->fsp_name,
1483 fsp,
1484 local_flags & ~O_TRUNC,
1485 unx_mode,
1486 p_file_created);
1487 if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) {
1489 * POSIX client that hit a symlink. We don't want to
1490 * return NT_STATUS_STOPPED_ON_SYMLINK to avoid handling
1491 * this special error code in all callers, so we map
1492 * this to NT_STATUS_OBJECT_NAME_NOT_FOUND to match
1493 * openat_pathref_fsp().
1495 status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
1497 if (!NT_STATUS_IS_OK(status)) {
1498 DEBUG(3,("Error opening file %s (%s) (local_flags=%d) "
1499 "(flags=%d)\n", smb_fname_str_dbg(smb_fname),
1500 nt_errstr(status),local_flags,flags));
1501 return status;
1504 if (local_flags & O_NONBLOCK) {
1506 * GPFS can return ETIMEDOUT for pread on
1507 * nonblocking file descriptors when files
1508 * migrated to tape need to be recalled. I
1509 * could imagine this happens elsewhere
1510 * too. With blocking file descriptors this
1511 * does not happen.
1513 ret = vfs_set_blocking(fsp, true);
1514 if (ret == -1) {
1515 status = map_nt_error_from_unix(errno);
1516 DBG_WARNING("Could not set fd to blocking: "
1517 "%s\n", strerror(errno));
1518 fd_close(fsp);
1519 return status;
1523 if (*p_file_created) {
1524 /* We created this file. */
1526 bool need_re_stat = false;
1527 /* Do all inheritance work after we've
1528 done a successful fstat call and filled
1529 in the stat struct in fsp->fsp_name. */
1531 /* Inherit the ACL if required */
1532 if (lp_inherit_permissions(SNUM(conn))) {
1533 inherit_access_posix_acl(conn,
1534 dirfsp,
1535 smb_fname,
1536 unx_mode);
1537 need_re_stat = true;
1540 /* Change the owner if required. */
1541 if (lp_inherit_owner(SNUM(conn)) != INHERIT_OWNER_NO) {
1542 change_file_owner_to_parent_fsp(dirfsp, fsp);
1543 need_re_stat = true;
1546 if (need_re_stat) {
1547 ret = SMB_VFS_FSTAT(fsp, &smb_fname->st);
1549 * If we have an fd, this stat should succeed.
1551 if (ret == -1) {
1552 status = map_nt_error_from_unix(errno);
1553 DBG_ERR("Error doing fstat on open "
1554 "file %s (%s)\n",
1555 smb_fname_str_dbg(smb_fname),
1556 nt_errstr(status));
1557 fd_close(fsp);
1558 return status;
1562 notify_fname(conn, NOTIFY_ACTION_ADDED,
1563 FILE_NOTIFY_CHANGE_FILE_NAME,
1564 smb_fname->base_name);
1566 } else {
1567 if (!file_existed) {
1568 /* File must exist for a stat open. */
1569 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1572 if (S_ISLNK(smb_fname->st.st_ex_mode) &&
1573 !posix_open)
1576 * Don't allow stat opens on symlinks directly unless
1577 * it's a POSIX open. Match the return code from
1578 * openat_pathref_fsp().
1580 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1583 if (!fsp->fsp_flags.is_pathref) {
1585 * There is only one legit case where end up here:
1586 * openat_pathref_fsp() failed to open a symlink, so the
1587 * fsp was created by fsp_new() which doesn't set
1588 * is_pathref. Other then that, we should always have a
1589 * pathref fsp at this point. The subsequent checks
1590 * assert this.
1592 if (!(smb_fname->flags & SMB_FILENAME_POSIX_PATH)) {
1593 DBG_ERR("[%s] is not a POSIX pathname\n",
1594 smb_fname_str_dbg(smb_fname));
1595 return NT_STATUS_INTERNAL_ERROR;
1597 if (!S_ISLNK(smb_fname->st.st_ex_mode)) {
1598 DBG_ERR("[%s] is not a symlink\n",
1599 smb_fname_str_dbg(smb_fname));
1600 return NT_STATUS_INTERNAL_ERROR;
1602 if (fsp_get_pathref_fd(fsp) != -1) {
1603 DBG_ERR("fd for [%s] is not -1: fd [%d]\n",
1604 smb_fname_str_dbg(smb_fname),
1605 fsp_get_pathref_fd(fsp));
1606 return NT_STATUS_INTERNAL_ERROR;
1610 status = smbd_check_access_rights_fsp(dirfsp,
1611 fsp,
1612 false,
1613 access_mask);
1615 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) &&
1616 posix_open &&
1617 S_ISLNK(smb_fname->st.st_ex_mode)) {
1618 /* This is a POSIX stat open for delete
1619 * or rename on a symlink that points
1620 * nowhere. Allow. */
1621 DEBUG(10,("open_file: allowing POSIX "
1622 "open on bad symlink %s\n",
1623 smb_fname_str_dbg(smb_fname)));
1624 status = NT_STATUS_OK;
1627 if (!NT_STATUS_IS_OK(status)) {
1628 DBG_DEBUG("smbd_check_access_rights_fsp on file "
1629 "%s returned %s\n",
1630 fsp_str_dbg(fsp),
1631 nt_errstr(status));
1632 return status;
1636 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
1637 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
1638 fsp->file_pid = req ? req->smbpid : 0;
1639 fsp->fsp_flags.can_lock = true;
1640 fsp->fsp_flags.can_read = ((access_mask & FILE_READ_DATA) != 0);
1641 fsp->fsp_flags.can_write =
1642 CAN_WRITE(conn) &&
1643 ((access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) != 0);
1644 fsp->print_file = NULL;
1645 fsp->fsp_flags.modified = false;
1646 fsp->sent_oplock_break = NO_BREAK_SENT;
1647 fsp->fsp_flags.is_directory = false;
1648 if (conn->aio_write_behind_list &&
1649 is_in_path(smb_fname->base_name, conn->aio_write_behind_list,
1650 posix_open ? true: conn->case_sensitive)) {
1651 fsp->fsp_flags.aio_write_behind = true;
1654 DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
1655 conn->session_info->unix_info->unix_name,
1656 smb_fname_str_dbg(smb_fname),
1657 BOOLSTR(fsp->fsp_flags.can_read),
1658 BOOLSTR(fsp->fsp_flags.can_write),
1659 conn->num_files_open));
1661 return NT_STATUS_OK;
1664 static bool mask_conflict(
1665 uint32_t new_access,
1666 uint32_t existing_access,
1667 uint32_t access_mask,
1668 uint32_t new_sharemode,
1669 uint32_t existing_sharemode,
1670 uint32_t sharemode_mask)
1672 bool want_access = (new_access & access_mask);
1673 bool allow_existing = (existing_sharemode & sharemode_mask);
1674 bool have_access = (existing_access & access_mask);
1675 bool allow_new = (new_sharemode & sharemode_mask);
1677 if (want_access && !allow_existing) {
1678 DBG_DEBUG("Access request 0x%"PRIx32"/0x%"PRIx32" conflicts "
1679 "with existing sharemode 0x%"PRIx32"/0x%"PRIx32"\n",
1680 new_access,
1681 access_mask,
1682 existing_sharemode,
1683 sharemode_mask);
1684 return true;
1686 if (have_access && !allow_new) {
1687 DBG_DEBUG("Sharemode request 0x%"PRIx32"/0x%"PRIx32" conflicts "
1688 "with existing access 0x%"PRIx32"/0x%"PRIx32"\n",
1689 new_sharemode,
1690 sharemode_mask,
1691 existing_access,
1692 access_mask);
1693 return true;
1695 return false;
1698 /****************************************************************************
1699 Check if we can open a file with a share mode.
1700 Returns True if conflict, False if not.
1701 ****************************************************************************/
1703 static const uint32_t conflicting_access =
1704 FILE_WRITE_DATA|
1705 FILE_APPEND_DATA|
1706 FILE_READ_DATA|
1707 FILE_EXECUTE|
1708 DELETE_ACCESS;
1710 static bool share_conflict(uint32_t e_access_mask,
1711 uint32_t e_share_access,
1712 uint32_t access_mask,
1713 uint32_t share_access)
1715 bool conflict;
1717 DBG_DEBUG("existing access_mask = 0x%"PRIx32", "
1718 "existing share access = 0x%"PRIx32", "
1719 "access_mask = 0x%"PRIx32", "
1720 "share_access = 0x%"PRIx32"\n",
1721 e_access_mask,
1722 e_share_access,
1723 access_mask,
1724 share_access);
1726 if ((e_access_mask & conflicting_access) == 0) {
1727 DBG_DEBUG("No conflict due to "
1728 "existing access_mask = 0x%"PRIx32"\n",
1729 e_access_mask);
1730 return false;
1732 if ((access_mask & conflicting_access) == 0) {
1733 DBG_DEBUG("No conflict due to access_mask = 0x%"PRIx32"\n",
1734 access_mask);
1735 return false;
1738 conflict = mask_conflict(
1739 access_mask, e_access_mask, FILE_WRITE_DATA | FILE_APPEND_DATA,
1740 share_access, e_share_access, FILE_SHARE_WRITE);
1741 conflict |= mask_conflict(
1742 access_mask, e_access_mask, FILE_READ_DATA | FILE_EXECUTE,
1743 share_access, e_share_access, FILE_SHARE_READ);
1744 conflict |= mask_conflict(
1745 access_mask, e_access_mask, DELETE_ACCESS,
1746 share_access, e_share_access, FILE_SHARE_DELETE);
1748 DBG_DEBUG("conflict=%s\n", conflict ? "true" : "false");
1749 return conflict;
1752 #if defined(DEVELOPER)
1754 struct validate_my_share_entries_state {
1755 struct smbd_server_connection *sconn;
1756 struct file_id fid;
1757 struct server_id self;
1760 static bool validate_my_share_entries_fn(
1761 struct share_mode_entry *e,
1762 bool *modified,
1763 void *private_data)
1765 struct validate_my_share_entries_state *state = private_data;
1766 files_struct *fsp;
1768 if (!server_id_equal(&state->self, &e->pid)) {
1769 return false;
1772 if (e->op_mid == 0) {
1773 /* INTERNAL_OPEN_ONLY */
1774 return false;
1777 fsp = file_find_dif(state->sconn, state->fid, e->share_file_id);
1778 if (!fsp) {
1779 DBG_ERR("PANIC : %s\n",
1780 share_mode_str(talloc_tos(), 0, &state->fid, e));
1781 smb_panic("validate_my_share_entries: Cannot match a "
1782 "share entry with an open file\n");
1785 if (((uint16_t)fsp->oplock_type) != e->op_type) {
1786 goto panic;
1789 return false;
1791 panic:
1793 char *str;
1794 DBG_ERR("validate_my_share_entries: PANIC : %s\n",
1795 share_mode_str(talloc_tos(), 0, &state->fid, e));
1796 str = talloc_asprintf(talloc_tos(),
1797 "validate_my_share_entries: "
1798 "file %s, oplock_type = 0x%x, op_type = 0x%x\n",
1799 fsp->fsp_name->base_name,
1800 (unsigned int)fsp->oplock_type,
1801 (unsigned int)e->op_type);
1802 smb_panic(str);
1805 return false;
1807 #endif
1810 * Allowed access mask for stat opens relevant to oplocks
1812 bool is_oplock_stat_open(uint32_t access_mask)
1814 const uint32_t stat_open_bits =
1815 (SYNCHRONIZE_ACCESS|
1816 FILE_READ_ATTRIBUTES|
1817 FILE_WRITE_ATTRIBUTES);
1819 return (((access_mask & stat_open_bits) != 0) &&
1820 ((access_mask & ~stat_open_bits) == 0));
1824 * Allowed access mask for stat opens relevant to leases
1826 bool is_lease_stat_open(uint32_t access_mask)
1828 const uint32_t stat_open_bits =
1829 (SYNCHRONIZE_ACCESS|
1830 FILE_READ_ATTRIBUTES|
1831 FILE_WRITE_ATTRIBUTES|
1832 READ_CONTROL_ACCESS);
1834 return (((access_mask & stat_open_bits) != 0) &&
1835 ((access_mask & ~stat_open_bits) == 0));
1838 struct has_delete_on_close_state {
1839 bool ret;
1842 static bool has_delete_on_close_fn(
1843 struct share_mode_entry *e,
1844 bool *modified,
1845 void *private_data)
1847 struct has_delete_on_close_state *state = private_data;
1848 state->ret = !share_entry_stale_pid(e);
1849 return state->ret;
1852 static bool has_delete_on_close(struct share_mode_lock *lck,
1853 uint32_t name_hash)
1855 struct has_delete_on_close_state state = { .ret = false };
1856 bool ok;
1858 if (!is_delete_on_close_set(lck, name_hash)) {
1859 return false;
1862 ok= share_mode_forall_entries(lck, has_delete_on_close_fn, &state);
1863 if (!ok) {
1864 DBG_DEBUG("share_mode_forall_entries failed\n");
1865 return false;
1867 return state.ret;
1870 static void share_mode_flags_restrict(
1871 struct share_mode_lock *lck,
1872 uint32_t access_mask,
1873 uint32_t share_mode,
1874 uint32_t lease_type)
1876 uint32_t existing_access_mask, existing_share_mode;
1877 uint32_t existing_lease_type;
1879 share_mode_flags_get(
1880 lck,
1881 &existing_access_mask,
1882 &existing_share_mode,
1883 &existing_lease_type);
1885 existing_access_mask |= access_mask;
1886 if (access_mask & conflicting_access) {
1887 existing_share_mode &= share_mode;
1889 existing_lease_type |= lease_type;
1891 share_mode_flags_set(
1892 lck,
1893 existing_access_mask,
1894 existing_share_mode,
1895 existing_lease_type,
1896 NULL);
1899 /****************************************************************************
1900 Deal with share modes
1901 Invariant: Share mode must be locked on entry and exit.
1902 Returns -1 on error, or number of share modes on success (may be zero).
1903 ****************************************************************************/
1905 struct open_mode_check_state {
1906 struct file_id fid;
1907 uint32_t access_mask;
1908 uint32_t share_access;
1909 uint32_t lease_type;
1912 static bool open_mode_check_fn(
1913 struct share_mode_entry *e,
1914 bool *modified,
1915 void *private_data)
1917 struct open_mode_check_state *state = private_data;
1918 bool disconnected, stale;
1919 uint32_t access_mask, share_access, lease_type;
1921 disconnected = server_id_is_disconnected(&e->pid);
1922 if (disconnected) {
1923 return false;
1926 access_mask = state->access_mask | e->access_mask;
1927 share_access = state->share_access;
1928 if (e->access_mask & conflicting_access) {
1929 share_access &= e->share_access;
1931 lease_type = state->lease_type | get_lease_type(e, state->fid);
1933 if ((access_mask == state->access_mask) &&
1934 (share_access == state->share_access) &&
1935 (lease_type == state->lease_type)) {
1936 return false;
1939 stale = share_entry_stale_pid(e);
1940 if (stale) {
1941 return false;
1944 state->access_mask = access_mask;
1945 state->share_access = share_access;
1946 state->lease_type = lease_type;
1948 return false;
1951 static NTSTATUS open_mode_check(connection_struct *conn,
1952 struct file_id fid,
1953 struct share_mode_lock *lck,
1954 uint32_t access_mask,
1955 uint32_t share_access)
1957 struct open_mode_check_state state;
1958 bool ok, conflict;
1959 bool modified = false;
1961 if (is_oplock_stat_open(access_mask)) {
1962 /* Stat open that doesn't trigger oplock breaks or share mode
1963 * checks... ! JRA. */
1964 return NT_STATUS_OK;
1968 * Check if the share modes will give us access.
1971 #if defined(DEVELOPER)
1973 struct validate_my_share_entries_state validate_state = {
1974 .sconn = conn->sconn,
1975 .fid = fid,
1976 .self = messaging_server_id(conn->sconn->msg_ctx),
1978 ok = share_mode_forall_entries(
1979 lck, validate_my_share_entries_fn, &validate_state);
1980 SMB_ASSERT(ok);
1982 #endif
1984 share_mode_flags_get(
1985 lck, &state.access_mask, &state.share_access, NULL);
1987 conflict = share_conflict(
1988 state.access_mask,
1989 state.share_access,
1990 access_mask,
1991 share_access);
1992 if (!conflict) {
1993 DBG_DEBUG("No conflict due to share_mode_flags access\n");
1994 return NT_STATUS_OK;
1997 state = (struct open_mode_check_state) {
1998 .fid = fid,
1999 .share_access = (FILE_SHARE_READ|
2000 FILE_SHARE_WRITE|
2001 FILE_SHARE_DELETE),
2005 * Walk the share mode array to recalculate d->flags
2008 ok = share_mode_forall_entries(lck, open_mode_check_fn, &state);
2009 if (!ok) {
2010 DBG_DEBUG("share_mode_forall_entries failed\n");
2011 return NT_STATUS_INTERNAL_ERROR;
2014 share_mode_flags_set(
2015 lck,
2016 state.access_mask,
2017 state.share_access,
2018 state.lease_type,
2019 &modified);
2020 if (!modified) {
2022 * We only end up here if we had a sharing violation
2023 * from d->flags and have recalculated it.
2025 return NT_STATUS_SHARING_VIOLATION;
2028 conflict = share_conflict(
2029 state.access_mask,
2030 state.share_access,
2031 access_mask,
2032 share_access);
2033 if (!conflict) {
2034 DBG_DEBUG("No conflict due to share_mode_flags access\n");
2035 return NT_STATUS_OK;
2038 return NT_STATUS_SHARING_VIOLATION;
2042 * Send a break message to the oplock holder and delay the open for
2043 * our client.
2046 NTSTATUS send_break_message(struct messaging_context *msg_ctx,
2047 const struct file_id *id,
2048 const struct share_mode_entry *exclusive,
2049 uint16_t break_to)
2051 struct oplock_break_message msg = {
2052 .id = *id,
2053 .share_file_id = exclusive->share_file_id,
2054 .break_to = break_to,
2056 enum ndr_err_code ndr_err;
2057 DATA_BLOB blob;
2058 NTSTATUS status;
2060 if (DEBUGLVL(10)) {
2061 struct server_id_buf buf;
2062 DBG_DEBUG("Sending break message to %s\n",
2063 server_id_str_buf(exclusive->pid, &buf));
2064 NDR_PRINT_DEBUG(oplock_break_message, &msg);
2067 ndr_err = ndr_push_struct_blob(
2068 &blob,
2069 talloc_tos(),
2070 &msg,
2071 (ndr_push_flags_fn_t)ndr_push_oplock_break_message);
2072 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2073 DBG_WARNING("ndr_push_oplock_break_message failed: %s\n",
2074 ndr_errstr(ndr_err));
2075 return ndr_map_error2ntstatus(ndr_err);
2078 status = messaging_send(
2079 msg_ctx, exclusive->pid, MSG_SMB_BREAK_REQUEST, &blob);
2080 TALLOC_FREE(blob.data);
2081 if (!NT_STATUS_IS_OK(status)) {
2082 DEBUG(3, ("Could not send oplock break message: %s\n",
2083 nt_errstr(status)));
2086 return status;
2089 struct validate_oplock_types_state {
2090 bool valid;
2091 bool batch;
2092 bool ex_or_batch;
2093 bool level2;
2094 bool no_oplock;
2095 uint32_t num_non_stat_opens;
2098 static bool validate_oplock_types_fn(
2099 struct share_mode_entry *e,
2100 bool *modified,
2101 void *private_data)
2103 struct validate_oplock_types_state *state = private_data;
2105 if (e->op_mid == 0) {
2106 /* INTERNAL_OPEN_ONLY */
2107 return false;
2110 if (e->op_type == NO_OPLOCK && is_oplock_stat_open(e->access_mask)) {
2112 * We ignore stat opens in the table - they always
2113 * have NO_OPLOCK and never get or cause breaks. JRA.
2115 return false;
2118 state->num_non_stat_opens += 1;
2120 if (BATCH_OPLOCK_TYPE(e->op_type)) {
2121 /* batch - can only be one. */
2122 if (share_entry_stale_pid(e)) {
2123 DBG_DEBUG("Found stale batch oplock\n");
2124 return false;
2126 if (state->ex_or_batch ||
2127 state->batch ||
2128 state->level2 ||
2129 state->no_oplock) {
2130 DBG_ERR("Bad batch oplock entry\n");
2131 state->valid = false;
2132 return true;
2134 state->batch = true;
2137 if (EXCLUSIVE_OPLOCK_TYPE(e->op_type)) {
2138 if (share_entry_stale_pid(e)) {
2139 DBG_DEBUG("Found stale duplicate oplock\n");
2140 return false;
2142 /* Exclusive or batch - can only be one. */
2143 if (state->ex_or_batch ||
2144 state->level2 ||
2145 state->no_oplock) {
2146 DBG_ERR("Bad exclusive or batch oplock entry\n");
2147 state->valid = false;
2148 return true;
2150 state->ex_or_batch = true;
2153 if (LEVEL_II_OPLOCK_TYPE(e->op_type)) {
2154 if (state->batch || state->ex_or_batch) {
2155 if (share_entry_stale_pid(e)) {
2156 DBG_DEBUG("Found stale LevelII oplock\n");
2157 return false;
2159 DBG_DEBUG("Bad levelII oplock entry\n");
2160 state->valid = false;
2161 return true;
2163 state->level2 = true;
2166 if (e->op_type == NO_OPLOCK) {
2167 if (state->batch || state->ex_or_batch) {
2168 if (share_entry_stale_pid(e)) {
2169 DBG_DEBUG("Found stale NO_OPLOCK entry\n");
2170 return false;
2172 DBG_ERR("Bad no oplock entry\n");
2173 state->valid = false;
2174 return true;
2176 state->no_oplock = true;
2179 return false;
2183 * Do internal consistency checks on the share mode for a file.
2186 static bool validate_oplock_types(struct share_mode_lock *lck)
2188 struct validate_oplock_types_state state = { .valid = true };
2189 bool ok;
2191 ok = share_mode_forall_entries(lck, validate_oplock_types_fn, &state);
2192 if (!ok) {
2193 DBG_DEBUG("share_mode_forall_entries failed\n");
2194 return false;
2196 if (!state.valid) {
2197 DBG_DEBUG("Got invalid oplock configuration\n");
2198 return false;
2201 if ((state.batch || state.ex_or_batch) &&
2202 (state.num_non_stat_opens != 1)) {
2203 DBG_WARNING("got batch (%d) or ex (%d) non-exclusively "
2204 "(%"PRIu32")\n",
2205 (int)state.batch,
2206 (int)state.ex_or_batch,
2207 state.num_non_stat_opens);
2208 return false;
2211 return true;
2214 static bool is_same_lease(const files_struct *fsp,
2215 const struct share_mode_entry *e,
2216 const struct smb2_lease *lease)
2218 if (e->op_type != LEASE_OPLOCK) {
2219 return false;
2221 if (lease == NULL) {
2222 return false;
2225 return smb2_lease_equal(fsp_client_guid(fsp),
2226 &lease->lease_key,
2227 &e->client_guid,
2228 &e->lease_key);
2231 static bool file_has_brlocks(files_struct *fsp)
2233 struct byte_range_lock *br_lck;
2235 br_lck = brl_get_locks_readonly(fsp);
2236 if (!br_lck)
2237 return false;
2239 return (brl_num_locks(br_lck) > 0);
2242 struct fsp_lease *find_fsp_lease(struct files_struct *new_fsp,
2243 const struct smb2_lease_key *key,
2244 uint32_t current_state,
2245 uint16_t lease_version,
2246 uint16_t lease_epoch)
2248 struct files_struct *fsp;
2251 * TODO: Measure how expensive this loop is with thousands of open
2252 * handles...
2255 for (fsp = file_find_di_first(new_fsp->conn->sconn, new_fsp->file_id, true);
2256 fsp != NULL;
2257 fsp = file_find_di_next(fsp, true)) {
2259 if (fsp == new_fsp) {
2260 continue;
2262 if (fsp->oplock_type != LEASE_OPLOCK) {
2263 continue;
2265 if (smb2_lease_key_equal(&fsp->lease->lease.lease_key, key)) {
2266 fsp->lease->ref_count += 1;
2267 return fsp->lease;
2271 /* Not found - must be leased in another smbd. */
2272 new_fsp->lease = talloc_zero(new_fsp->conn->sconn, struct fsp_lease);
2273 if (new_fsp->lease == NULL) {
2274 return NULL;
2276 new_fsp->lease->ref_count = 1;
2277 new_fsp->lease->sconn = new_fsp->conn->sconn;
2278 new_fsp->lease->lease.lease_key = *key;
2279 new_fsp->lease->lease.lease_state = current_state;
2281 * We internally treat all leases as V2 and update
2282 * the epoch, but when sending breaks it matters if
2283 * the requesting lease was v1 or v2.
2285 new_fsp->lease->lease.lease_version = lease_version;
2286 new_fsp->lease->lease.lease_epoch = lease_epoch;
2287 return new_fsp->lease;
2290 static NTSTATUS try_lease_upgrade(struct files_struct *fsp,
2291 struct share_mode_lock *lck,
2292 const struct GUID *client_guid,
2293 const struct smb2_lease *lease,
2294 uint32_t granted)
2296 bool do_upgrade;
2297 uint32_t current_state, breaking_to_requested, breaking_to_required;
2298 bool breaking;
2299 uint16_t lease_version, epoch;
2300 uint32_t existing, requested;
2301 NTSTATUS status;
2303 status = leases_db_get(
2304 client_guid,
2305 &lease->lease_key,
2306 &fsp->file_id,
2307 &current_state,
2308 &breaking,
2309 &breaking_to_requested,
2310 &breaking_to_required,
2311 &lease_version,
2312 &epoch);
2313 if (!NT_STATUS_IS_OK(status)) {
2314 return status;
2317 fsp->lease = find_fsp_lease(
2318 fsp,
2319 &lease->lease_key,
2320 current_state,
2321 lease_version,
2322 epoch);
2323 if (fsp->lease == NULL) {
2324 DEBUG(1, ("Did not find existing lease for file %s\n",
2325 fsp_str_dbg(fsp)));
2326 return NT_STATUS_NO_MEMORY;
2330 * Upgrade only if the requested lease is a strict upgrade.
2332 existing = current_state;
2333 requested = lease->lease_state;
2336 * Tricky: This test makes sure that "requested" is a
2337 * strict bitwise superset of "existing".
2339 do_upgrade = ((existing & requested) == existing);
2342 * Upgrade only if there's a change.
2344 do_upgrade &= (granted != existing);
2347 * Upgrade only if other leases don't prevent what was asked
2348 * for.
2350 do_upgrade &= (granted == requested);
2353 * only upgrade if we are not in breaking state
2355 do_upgrade &= !breaking;
2357 DEBUG(10, ("existing=%"PRIu32", requested=%"PRIu32", "
2358 "granted=%"PRIu32", do_upgrade=%d\n",
2359 existing, requested, granted, (int)do_upgrade));
2361 if (do_upgrade) {
2362 NTSTATUS set_status;
2364 current_state = granted;
2365 epoch += 1;
2367 set_status = leases_db_set(
2368 client_guid,
2369 &lease->lease_key,
2370 current_state,
2371 breaking,
2372 breaking_to_requested,
2373 breaking_to_required,
2374 lease_version,
2375 epoch);
2377 if (!NT_STATUS_IS_OK(set_status)) {
2378 DBG_DEBUG("leases_db_set failed: %s\n",
2379 nt_errstr(set_status));
2380 return set_status;
2384 fsp_lease_update(fsp);
2386 return NT_STATUS_OK;
2389 static NTSTATUS grant_new_fsp_lease(struct files_struct *fsp,
2390 struct share_mode_lock *lck,
2391 const struct GUID *client_guid,
2392 const struct smb2_lease *lease,
2393 uint32_t granted)
2395 NTSTATUS status;
2397 fsp->lease = talloc_zero(fsp->conn->sconn, struct fsp_lease);
2398 if (fsp->lease == NULL) {
2399 return NT_STATUS_INSUFFICIENT_RESOURCES;
2401 fsp->lease->ref_count = 1;
2402 fsp->lease->sconn = fsp->conn->sconn;
2403 fsp->lease->lease.lease_version = lease->lease_version;
2404 fsp->lease->lease.lease_key = lease->lease_key;
2405 fsp->lease->lease.lease_state = granted;
2406 fsp->lease->lease.lease_epoch = lease->lease_epoch + 1;
2408 status = leases_db_add(client_guid,
2409 &lease->lease_key,
2410 &fsp->file_id,
2411 fsp->lease->lease.lease_state,
2412 fsp->lease->lease.lease_version,
2413 fsp->lease->lease.lease_epoch,
2414 fsp->conn->connectpath,
2415 fsp->fsp_name->base_name,
2416 fsp->fsp_name->stream_name);
2417 if (!NT_STATUS_IS_OK(status)) {
2418 DEBUG(10, ("%s: leases_db_add failed: %s\n", __func__,
2419 nt_errstr(status)));
2420 TALLOC_FREE(fsp->lease);
2421 return NT_STATUS_INSUFFICIENT_RESOURCES;
2425 * We used to set lck->data->modified=true here without
2426 * actually modifying lck->data, triggering a needless
2427 * writeback of lck->data.
2429 * Apart from that writeback, setting modified=true has the
2430 * effect of triggering all waiters for this file to
2431 * retry. This only makes sense if any blocking condition
2432 * (i.e. waiting for a lease to be downgraded or removed) is
2433 * gone. This routine here only adds a lease, so it will never
2434 * free up resources that blocked waiters can now claim. So
2435 * that second effect also does not matter in this
2436 * routine. Thus setting lck->data->modified=true does not
2437 * need to be done here.
2440 return NT_STATUS_OK;
2443 static NTSTATUS grant_fsp_lease(struct files_struct *fsp,
2444 struct share_mode_lock *lck,
2445 const struct smb2_lease *lease,
2446 uint32_t granted)
2448 const struct GUID *client_guid = fsp_client_guid(fsp);
2449 NTSTATUS status;
2451 status = try_lease_upgrade(fsp, lck, client_guid, lease, granted);
2453 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
2454 status = grant_new_fsp_lease(
2455 fsp, lck, client_guid, lease, granted);
2458 return status;
2461 static int map_lease_type_to_oplock(uint32_t lease_type)
2463 int result = NO_OPLOCK;
2465 switch (lease_type) {
2466 case SMB2_LEASE_READ|SMB2_LEASE_WRITE|SMB2_LEASE_HANDLE:
2467 result = BATCH_OPLOCK|EXCLUSIVE_OPLOCK;
2468 break;
2469 case SMB2_LEASE_READ|SMB2_LEASE_WRITE:
2470 result = EXCLUSIVE_OPLOCK;
2471 break;
2472 case SMB2_LEASE_READ|SMB2_LEASE_HANDLE:
2473 case SMB2_LEASE_READ:
2474 result = LEVEL_II_OPLOCK;
2475 break;
2478 return result;
2481 struct delay_for_oplock_state {
2482 struct files_struct *fsp;
2483 const struct smb2_lease *lease;
2484 bool will_overwrite;
2485 uint32_t delay_mask;
2486 bool first_open_attempt;
2487 bool got_handle_lease;
2488 bool got_oplock;
2489 bool have_other_lease;
2490 bool delay;
2493 static bool delay_for_oplock_fn(
2494 struct share_mode_entry *e,
2495 bool *modified,
2496 void *private_data)
2498 struct delay_for_oplock_state *state = private_data;
2499 struct files_struct *fsp = state->fsp;
2500 const struct smb2_lease *lease = state->lease;
2501 bool e_is_lease = (e->op_type == LEASE_OPLOCK);
2502 uint32_t e_lease_type = get_lease_type(e, fsp->file_id);
2503 uint32_t break_to;
2504 bool lease_is_breaking = false;
2506 if (e_is_lease) {
2507 NTSTATUS status;
2509 if (lease != NULL) {
2510 bool our_lease = is_same_lease(fsp, e, lease);
2511 if (our_lease) {
2512 DBG_DEBUG("Ignoring our own lease\n");
2513 return false;
2517 status = leases_db_get(
2518 &e->client_guid,
2519 &e->lease_key,
2520 &fsp->file_id,
2521 NULL, /* current_state */
2522 &lease_is_breaking,
2523 NULL, /* breaking_to_requested */
2524 NULL, /* breaking_to_required */
2525 NULL, /* lease_version */
2526 NULL); /* epoch */
2529 * leases_db_get() can return NT_STATUS_NOT_FOUND
2530 * if the share_mode_entry e is stale and the
2531 * lease record was already removed. In this case return
2532 * false so the traverse continues.
2535 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND) &&
2536 share_entry_stale_pid(e))
2538 struct GUID_txt_buf guid_strbuf;
2539 struct file_id_buf file_id_strbuf;
2540 DBG_DEBUG("leases_db_get for client_guid [%s] "
2541 "lease_key [%"PRIu64"/%"PRIu64"] "
2542 "file_id [%s] failed for stale "
2543 "share_mode_entry\n",
2544 GUID_buf_string(&e->client_guid, &guid_strbuf),
2545 e->lease_key.data[0],
2546 e->lease_key.data[1],
2547 file_id_str_buf(fsp->file_id, &file_id_strbuf));
2548 return false;
2550 if (!NT_STATUS_IS_OK(status)) {
2551 struct GUID_txt_buf guid_strbuf;
2552 struct file_id_buf file_id_strbuf;
2553 DBG_ERR("leases_db_get for client_guid [%s] "
2554 "lease_key [%"PRIu64"/%"PRIu64"] "
2555 "file_id [%s] failed: %s\n",
2556 GUID_buf_string(&e->client_guid, &guid_strbuf),
2557 e->lease_key.data[0],
2558 e->lease_key.data[1],
2559 file_id_str_buf(fsp->file_id, &file_id_strbuf),
2560 nt_errstr(status));
2561 smb_panic("leases_db_get() failed");
2565 if (!state->got_handle_lease &&
2566 ((e_lease_type & SMB2_LEASE_HANDLE) != 0) &&
2567 !share_entry_stale_pid(e)) {
2568 state->got_handle_lease = true;
2571 if (!state->got_oplock &&
2572 (e->op_type != LEASE_OPLOCK) &&
2573 !share_entry_stale_pid(e)) {
2574 state->got_oplock = true;
2577 if (!state->have_other_lease &&
2578 !is_same_lease(fsp, e, lease) &&
2579 !share_entry_stale_pid(e)) {
2580 state->have_other_lease = true;
2583 if (e_is_lease && is_lease_stat_open(fsp->access_mask)) {
2584 return false;
2587 break_to = e_lease_type & ~state->delay_mask;
2589 if (state->will_overwrite) {
2590 break_to &= ~(SMB2_LEASE_HANDLE|SMB2_LEASE_READ);
2593 DBG_DEBUG("e_lease_type %u, will_overwrite: %u\n",
2594 (unsigned)e_lease_type,
2595 (unsigned)state->will_overwrite);
2597 if ((e_lease_type & ~break_to) == 0) {
2598 if (lease_is_breaking) {
2599 state->delay = true;
2601 return false;
2604 if (share_entry_stale_pid(e)) {
2605 return false;
2608 if (state->will_overwrite) {
2610 * If we break anyway break to NONE directly.
2611 * Otherwise vfs_set_filelen() will trigger the
2612 * break.
2614 break_to &= ~(SMB2_LEASE_READ|SMB2_LEASE_WRITE);
2617 if (!e_is_lease) {
2619 * Oplocks only support breaking to R or NONE.
2621 break_to &= ~(SMB2_LEASE_HANDLE|SMB2_LEASE_WRITE);
2624 DBG_DEBUG("breaking from %d to %d\n",
2625 (int)e_lease_type,
2626 (int)break_to);
2627 send_break_message(
2628 fsp->conn->sconn->msg_ctx, &fsp->file_id, e, break_to);
2629 if (e_lease_type & state->delay_mask) {
2630 state->delay = true;
2632 if (lease_is_breaking && !state->first_open_attempt) {
2633 state->delay = true;
2636 return false;
2639 static NTSTATUS delay_for_oplock(files_struct *fsp,
2640 int oplock_request,
2641 const struct smb2_lease *lease,
2642 struct share_mode_lock *lck,
2643 bool have_sharing_violation,
2644 uint32_t create_disposition,
2645 bool first_open_attempt)
2647 struct delay_for_oplock_state state = {
2648 .fsp = fsp,
2649 .lease = lease,
2650 .first_open_attempt = first_open_attempt,
2652 uint32_t granted;
2653 NTSTATUS status;
2654 bool ok;
2656 if (is_oplock_stat_open(fsp->access_mask)) {
2657 goto grant;
2660 state.delay_mask = have_sharing_violation ?
2661 SMB2_LEASE_HANDLE : SMB2_LEASE_WRITE;
2663 switch (create_disposition) {
2664 case FILE_SUPERSEDE:
2665 case FILE_OVERWRITE:
2666 case FILE_OVERWRITE_IF:
2667 state.will_overwrite = true;
2668 break;
2669 default:
2670 state.will_overwrite = false;
2671 break;
2674 ok = share_mode_forall_entries(lck, delay_for_oplock_fn, &state);
2675 if (!ok) {
2676 return NT_STATUS_INTERNAL_ERROR;
2679 if (state.delay) {
2680 return NT_STATUS_RETRY;
2683 grant:
2684 if (have_sharing_violation) {
2685 return NT_STATUS_SHARING_VIOLATION;
2688 if (oplock_request == LEASE_OPLOCK) {
2689 if (lease == NULL) {
2691 * The SMB2 layer should have checked this
2693 return NT_STATUS_INTERNAL_ERROR;
2696 granted = lease->lease_state;
2698 if (lp_kernel_oplocks(SNUM(fsp->conn))) {
2699 DEBUG(10, ("No lease granted because kernel oplocks are enabled\n"));
2700 granted = SMB2_LEASE_NONE;
2702 if ((granted & (SMB2_LEASE_READ|SMB2_LEASE_WRITE)) == 0) {
2703 DEBUG(10, ("No read or write lease requested\n"));
2704 granted = SMB2_LEASE_NONE;
2706 if (granted == SMB2_LEASE_WRITE) {
2707 DEBUG(10, ("pure write lease requested\n"));
2708 granted = SMB2_LEASE_NONE;
2710 if (granted == (SMB2_LEASE_WRITE|SMB2_LEASE_HANDLE)) {
2711 DEBUG(10, ("write and handle lease requested\n"));
2712 granted = SMB2_LEASE_NONE;
2714 } else {
2715 granted = map_oplock_to_lease_type(
2716 oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK);
2719 if (lp_locking(fsp->conn->params) && file_has_brlocks(fsp)) {
2720 DBG_DEBUG("file %s has byte range locks\n",
2721 fsp_str_dbg(fsp));
2722 granted &= ~SMB2_LEASE_READ;
2725 if (state.have_other_lease) {
2727 * Can grant only one writer
2729 granted &= ~SMB2_LEASE_WRITE;
2732 if ((granted & SMB2_LEASE_READ) && !(granted & SMB2_LEASE_WRITE)) {
2733 bool allow_level2 =
2734 (global_client_caps & CAP_LEVEL_II_OPLOCKS) &&
2735 lp_level2_oplocks(SNUM(fsp->conn));
2737 if (!allow_level2) {
2738 granted = SMB2_LEASE_NONE;
2742 if (oplock_request == LEASE_OPLOCK) {
2743 if (state.got_oplock) {
2744 granted &= ~SMB2_LEASE_HANDLE;
2747 fsp->oplock_type = LEASE_OPLOCK;
2749 status = grant_fsp_lease(fsp, lck, lease, granted);
2750 if (!NT_STATUS_IS_OK(status)) {
2751 return status;
2755 DBG_DEBUG("lease_state=%d\n", fsp->lease->lease.lease_state);
2756 } else {
2757 if (state.got_handle_lease) {
2758 granted = SMB2_LEASE_NONE;
2761 fsp->oplock_type = map_lease_type_to_oplock(granted);
2763 status = set_file_oplock(fsp);
2764 if (!NT_STATUS_IS_OK(status)) {
2766 * Could not get the kernel oplock
2768 fsp->oplock_type = NO_OPLOCK;
2772 if (granted & SMB2_LEASE_READ) {
2773 uint32_t acc, sh, ls;
2774 share_mode_flags_get(lck, &acc, &sh, &ls);
2775 ls |= SHARE_MODE_LEASE_READ;
2776 share_mode_flags_set(lck, acc, sh, ls, NULL);
2779 DBG_DEBUG("oplock type 0x%x on file %s\n",
2780 fsp->oplock_type, fsp_str_dbg(fsp));
2782 return NT_STATUS_OK;
2785 static NTSTATUS handle_share_mode_lease(
2786 files_struct *fsp,
2787 struct share_mode_lock *lck,
2788 uint32_t create_disposition,
2789 uint32_t access_mask,
2790 uint32_t share_access,
2791 int oplock_request,
2792 const struct smb2_lease *lease,
2793 bool first_open_attempt)
2795 bool sharing_violation = false;
2796 NTSTATUS status;
2798 status = open_mode_check(
2799 fsp->conn, fsp->file_id, lck, access_mask, share_access);
2800 if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
2801 sharing_violation = true;
2802 status = NT_STATUS_OK; /* handled later */
2805 if (!NT_STATUS_IS_OK(status)) {
2806 return status;
2809 if (oplock_request == INTERNAL_OPEN_ONLY) {
2810 if (sharing_violation) {
2811 DBG_DEBUG("Sharing violation for internal open\n");
2812 return NT_STATUS_SHARING_VIOLATION;
2816 * Internal opens never do oplocks or leases. We don't
2817 * need to go through delay_for_oplock().
2819 fsp->oplock_type = NO_OPLOCK;
2821 return NT_STATUS_OK;
2824 status = delay_for_oplock(
2825 fsp,
2826 oplock_request,
2827 lease,
2828 lck,
2829 sharing_violation,
2830 create_disposition,
2831 first_open_attempt);
2832 if (!NT_STATUS_IS_OK(status)) {
2833 return status;
2836 return NT_STATUS_OK;
2839 static bool request_timed_out(struct smb_request *req, struct timeval timeout)
2841 struct timeval now, end_time;
2842 GetTimeOfDay(&now);
2843 end_time = timeval_sum(&req->request_time, &timeout);
2844 return (timeval_compare(&end_time, &now) < 0);
2847 struct defer_open_state {
2848 struct smbXsrv_connection *xconn;
2849 uint64_t mid;
2852 static void defer_open_done(struct tevent_req *req);
2855 * Defer an open and watch a locking.tdb record
2857 * This defers an open that gets rescheduled once the locking.tdb record watch
2858 * is triggered by a change to the record.
2860 * It is used to defer opens that triggered an oplock break and for the SMB1
2861 * sharing violation delay.
2863 static void defer_open(struct share_mode_lock *lck,
2864 struct timeval timeout,
2865 struct smb_request *req,
2866 struct file_id id)
2868 struct deferred_open_record *open_rec = NULL;
2869 struct timeval abs_timeout;
2870 struct defer_open_state *watch_state;
2871 struct tevent_req *watch_req;
2872 struct timeval_buf tvbuf1, tvbuf2;
2873 struct file_id_buf fbuf;
2874 bool ok;
2876 abs_timeout = timeval_sum(&req->request_time, &timeout);
2878 DBG_DEBUG("request time [%s] timeout [%s] mid [%" PRIu64 "] "
2879 "file_id [%s]\n",
2880 timeval_str_buf(&req->request_time, false, true, &tvbuf1),
2881 timeval_str_buf(&abs_timeout, false, true, &tvbuf2),
2882 req->mid,
2883 file_id_str_buf(id, &fbuf));
2885 open_rec = talloc_zero(NULL, struct deferred_open_record);
2886 if (open_rec == NULL) {
2887 TALLOC_FREE(lck);
2888 exit_server("talloc failed");
2891 watch_state = talloc(open_rec, struct defer_open_state);
2892 if (watch_state == NULL) {
2893 exit_server("talloc failed");
2895 watch_state->xconn = req->xconn;
2896 watch_state->mid = req->mid;
2898 DBG_DEBUG("defering mid %" PRIu64 "\n", req->mid);
2900 watch_req = share_mode_watch_send(
2901 watch_state,
2902 req->sconn->ev_ctx,
2903 lck,
2904 (struct server_id){0});
2905 if (watch_req == NULL) {
2906 exit_server("Could not watch share mode record");
2908 tevent_req_set_callback(watch_req, defer_open_done, watch_state);
2910 ok = tevent_req_set_endtime(watch_req, req->sconn->ev_ctx, abs_timeout);
2911 if (!ok) {
2912 exit_server("tevent_req_set_endtime failed");
2915 ok = push_deferred_open_message_smb(req, timeout, id, open_rec);
2916 if (!ok) {
2917 TALLOC_FREE(lck);
2918 exit_server("push_deferred_open_message_smb failed");
2922 static void defer_open_done(struct tevent_req *req)
2924 struct defer_open_state *state = tevent_req_callback_data(
2925 req, struct defer_open_state);
2926 NTSTATUS status;
2927 bool ret;
2929 status = share_mode_watch_recv(req, NULL, NULL);
2930 TALLOC_FREE(req);
2931 if (!NT_STATUS_IS_OK(status)) {
2932 DEBUG(5, ("dbwrap_watched_watch_recv returned %s\n",
2933 nt_errstr(status)));
2935 * Even if it failed, retry anyway. TODO: We need a way to
2936 * tell a re-scheduled open about that error.
2940 DEBUG(10, ("scheduling mid %llu\n", (unsigned long long)state->mid));
2942 ret = schedule_deferred_open_message_smb(state->xconn, state->mid);
2943 SMB_ASSERT(ret);
2944 TALLOC_FREE(state);
2948 * Actually attempt the kernel oplock polling open.
2951 static void poll_open_fn(struct tevent_context *ev,
2952 struct tevent_timer *te,
2953 struct timeval current_time,
2954 void *private_data)
2956 struct deferred_open_record *open_rec = talloc_get_type_abort(
2957 private_data, struct deferred_open_record);
2958 bool ok;
2960 TALLOC_FREE(open_rec->watch_req);
2962 ok = schedule_deferred_open_message_smb(
2963 open_rec->xconn, open_rec->mid);
2964 if (!ok) {
2965 exit_server("schedule_deferred_open_message_smb failed");
2967 DBG_DEBUG("timer fired. Retrying open !\n");
2970 static void poll_open_done(struct tevent_req *subreq);
2973 * Reschedule an open for 1 second from now, if not timed out.
2975 static bool setup_poll_open(
2976 struct smb_request *req,
2977 struct share_mode_lock *lck,
2978 struct file_id id,
2979 struct timeval max_timeout,
2980 struct timeval interval)
2982 bool ok;
2983 struct deferred_open_record *open_rec = NULL;
2984 struct timeval endtime, next_interval;
2985 struct file_id_buf ftmp;
2987 if (request_timed_out(req, max_timeout)) {
2988 return false;
2991 open_rec = talloc_zero(NULL, struct deferred_open_record);
2992 if (open_rec == NULL) {
2993 DBG_WARNING("talloc failed\n");
2994 return false;
2996 open_rec->xconn = req->xconn;
2997 open_rec->mid = req->mid;
3000 * Make sure open_rec->te does not come later than the
3001 * request's maximum endtime.
3004 endtime = timeval_sum(&req->request_time, &max_timeout);
3005 next_interval = timeval_current_ofs(interval.tv_sec, interval.tv_usec);
3006 next_interval = timeval_min(&endtime, &next_interval);
3008 open_rec->te = tevent_add_timer(
3009 req->sconn->ev_ctx,
3010 open_rec,
3011 next_interval,
3012 poll_open_fn,
3013 open_rec);
3014 if (open_rec->te == NULL) {
3015 DBG_WARNING("tevent_add_timer failed\n");
3016 TALLOC_FREE(open_rec);
3017 return false;
3020 if (lck != NULL) {
3021 open_rec->watch_req = share_mode_watch_send(
3022 open_rec,
3023 req->sconn->ev_ctx,
3024 lck,
3025 (struct server_id) {0});
3026 if (open_rec->watch_req == NULL) {
3027 DBG_WARNING("share_mode_watch_send failed\n");
3028 TALLOC_FREE(open_rec);
3029 return false;
3031 tevent_req_set_callback(
3032 open_rec->watch_req, poll_open_done, open_rec);
3035 ok = push_deferred_open_message_smb(req, max_timeout, id, open_rec);
3036 if (!ok) {
3037 DBG_WARNING("push_deferred_open_message_smb failed\n");
3038 TALLOC_FREE(open_rec);
3039 return false;
3042 DBG_DEBUG("poll request time [%s] mid [%" PRIu64 "] file_id [%s]\n",
3043 timeval_string(talloc_tos(), &req->request_time, false),
3044 req->mid,
3045 file_id_str_buf(id, &ftmp));
3047 return true;
3050 static void poll_open_done(struct tevent_req *subreq)
3052 struct deferred_open_record *open_rec = tevent_req_callback_data(
3053 subreq, struct deferred_open_record);
3054 NTSTATUS status;
3055 bool ok;
3057 status = share_mode_watch_recv(subreq, NULL, NULL);
3058 TALLOC_FREE(subreq);
3059 open_rec->watch_req = NULL;
3060 TALLOC_FREE(open_rec->te);
3062 DBG_DEBUG("dbwrap_watched_watch_recv returned %s\n",
3063 nt_errstr(status));
3065 ok = schedule_deferred_open_message_smb(
3066 open_rec->xconn, open_rec->mid);
3067 if (!ok) {
3068 exit_server("schedule_deferred_open_message_smb failed");
3072 bool defer_smb1_sharing_violation(struct smb_request *req)
3074 bool ok;
3075 int timeout_usecs;
3077 if (!lp_defer_sharing_violations()) {
3078 return false;
3082 * Try every 200msec up to (by default) one second. To be
3083 * precise, according to behaviour note <247> in [MS-CIFS],
3084 * the server tries 5 times. But up to one second should be
3085 * close enough.
3088 timeout_usecs = lp_parm_int(
3089 SNUM(req->conn),
3090 "smbd",
3091 "sharedelay",
3092 SHARING_VIOLATION_USEC_WAIT);
3094 ok = setup_poll_open(
3095 req,
3096 NULL,
3097 (struct file_id) {0},
3098 (struct timeval) { .tv_usec = timeout_usecs },
3099 (struct timeval) { .tv_usec = 200000 });
3100 return ok;
3103 /****************************************************************************
3104 On overwrite open ensure that the attributes match.
3105 ****************************************************************************/
3107 static bool open_match_attributes(connection_struct *conn,
3108 uint32_t old_dos_attr,
3109 uint32_t new_dos_attr,
3110 mode_t new_unx_mode,
3111 mode_t *returned_unx_mode)
3113 uint32_t noarch_old_dos_attr, noarch_new_dos_attr;
3115 noarch_old_dos_attr = (old_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
3116 noarch_new_dos_attr = (new_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
3118 if((noarch_old_dos_attr == 0 && noarch_new_dos_attr != 0) ||
3119 (noarch_old_dos_attr != 0 && ((noarch_old_dos_attr & noarch_new_dos_attr) == noarch_old_dos_attr))) {
3120 *returned_unx_mode = new_unx_mode;
3121 } else {
3122 *returned_unx_mode = (mode_t)0;
3125 DEBUG(10,("open_match_attributes: old_dos_attr = 0x%x, "
3126 "new_dos_attr = 0x%x "
3127 "returned_unx_mode = 0%o\n",
3128 (unsigned int)old_dos_attr,
3129 (unsigned int)new_dos_attr,
3130 (unsigned int)*returned_unx_mode ));
3132 /* If we're mapping SYSTEM and HIDDEN ensure they match. */
3133 if (lp_map_system(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
3134 if ((old_dos_attr & FILE_ATTRIBUTE_SYSTEM) &&
3135 !(new_dos_attr & FILE_ATTRIBUTE_SYSTEM)) {
3136 return False;
3139 if (lp_map_hidden(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
3140 if ((old_dos_attr & FILE_ATTRIBUTE_HIDDEN) &&
3141 !(new_dos_attr & FILE_ATTRIBUTE_HIDDEN)) {
3142 return False;
3145 return True;
3148 static void schedule_defer_open(struct share_mode_lock *lck,
3149 struct file_id id,
3150 struct smb_request *req)
3152 /* This is a relative time, added to the absolute
3153 request_time value to get the absolute timeout time.
3154 Note that if this is the second or greater time we enter
3155 this codepath for this particular request mid then
3156 request_time is left as the absolute time of the *first*
3157 time this request mid was processed. This is what allows
3158 the request to eventually time out. */
3160 struct timeval timeout;
3162 /* Normally the smbd we asked should respond within
3163 * OPLOCK_BREAK_TIMEOUT seconds regardless of whether
3164 * the client did, give twice the timeout as a safety
3165 * measure here in case the other smbd is stuck
3166 * somewhere else. */
3168 timeout = timeval_set(OPLOCK_BREAK_TIMEOUT*2, 0);
3170 if (request_timed_out(req, timeout)) {
3171 return;
3174 defer_open(lck, timeout, req, id);
3177 /****************************************************************************
3178 Reschedule an open call that went asynchronous.
3179 ****************************************************************************/
3181 static void schedule_async_open_timer(struct tevent_context *ev,
3182 struct tevent_timer *te,
3183 struct timeval current_time,
3184 void *private_data)
3186 exit_server("async open timeout");
3189 static void schedule_async_open(struct smb_request *req)
3191 struct deferred_open_record *open_rec = NULL;
3192 struct timeval timeout = timeval_set(20, 0);
3193 bool ok;
3195 if (request_timed_out(req, timeout)) {
3196 return;
3199 open_rec = talloc_zero(NULL, struct deferred_open_record);
3200 if (open_rec == NULL) {
3201 exit_server("deferred_open_record_create failed");
3203 open_rec->async_open = true;
3205 ok = push_deferred_open_message_smb(
3206 req, timeout, (struct file_id){0}, open_rec);
3207 if (!ok) {
3208 exit_server("push_deferred_open_message_smb failed");
3211 open_rec->te = tevent_add_timer(req->sconn->ev_ctx,
3212 req,
3213 timeval_current_ofs(20, 0),
3214 schedule_async_open_timer,
3215 open_rec);
3216 if (open_rec->te == NULL) {
3217 exit_server("tevent_add_timer failed");
3221 /****************************************************************************
3222 Work out what access_mask to use from what the client sent us.
3223 ****************************************************************************/
3225 static NTSTATUS smbd_calculate_maximum_allowed_access_fsp(
3226 struct files_struct *dirfsp,
3227 struct files_struct *fsp,
3228 bool use_privs,
3229 uint32_t *p_access_mask)
3231 struct security_descriptor *sd = NULL;
3232 uint32_t access_granted = 0;
3233 NTSTATUS status;
3235 /* Cope with symlinks */
3236 if (fsp == NULL || fsp_get_pathref_fd(fsp) == -1) {
3237 *p_access_mask = FILE_GENERIC_ALL;
3238 return NT_STATUS_OK;
3241 /* Cope with fake/printer fsp's. */
3242 if (fsp->fake_file_handle != NULL || fsp->print_file != NULL) {
3243 *p_access_mask = FILE_GENERIC_ALL;
3244 return NT_STATUS_OK;
3247 if (!use_privs && (get_current_uid(fsp->conn) == (uid_t)0)) {
3248 *p_access_mask |= FILE_GENERIC_ALL;
3249 return NT_STATUS_OK;
3252 status = SMB_VFS_FGET_NT_ACL(fsp,
3253 (SECINFO_OWNER |
3254 SECINFO_GROUP |
3255 SECINFO_DACL),
3256 talloc_tos(),
3257 &sd);
3259 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
3261 * File did not exist
3263 *p_access_mask = FILE_GENERIC_ALL;
3264 return NT_STATUS_OK;
3266 if (!NT_STATUS_IS_OK(status)) {
3267 DBG_ERR("Could not get acl on file %s: %s\n",
3268 fsp_str_dbg(fsp),
3269 nt_errstr(status));
3270 return status;
3274 * If we can access the path to this file, by
3275 * default we have FILE_READ_ATTRIBUTES from the
3276 * containing directory. See the section:
3277 * "Algorithm to Check Access to an Existing File"
3278 * in MS-FSA.pdf.
3280 * se_file_access_check()
3281 * also takes care of owner WRITE_DAC and READ_CONTROL.
3283 status = se_file_access_check(sd,
3284 get_current_nttok(fsp->conn),
3285 use_privs,
3286 (*p_access_mask & ~FILE_READ_ATTRIBUTES),
3287 &access_granted);
3289 TALLOC_FREE(sd);
3291 if (!NT_STATUS_IS_OK(status)) {
3292 DBG_ERR("Status %s on file %s: "
3293 "when calculating maximum access\n",
3294 nt_errstr(status),
3295 fsp_str_dbg(fsp));
3296 return status;
3299 *p_access_mask = (access_granted | FILE_READ_ATTRIBUTES);
3301 if (!(access_granted & DELETE_ACCESS)) {
3302 if (can_delete_file_in_directory(fsp->conn,
3303 dirfsp,
3304 fsp->fsp_name)) {
3305 *p_access_mask |= DELETE_ACCESS;
3309 return NT_STATUS_OK;
3312 NTSTATUS smbd_calculate_access_mask_fsp(struct files_struct *dirfsp,
3313 struct files_struct *fsp,
3314 bool use_privs,
3315 uint32_t access_mask,
3316 uint32_t *access_mask_out)
3318 NTSTATUS status;
3319 uint32_t orig_access_mask = access_mask;
3320 uint32_t rejected_share_access;
3322 if (access_mask & SEC_MASK_INVALID) {
3323 DBG_DEBUG("access_mask [%8x] contains invalid bits\n",
3324 access_mask);
3325 return NT_STATUS_ACCESS_DENIED;
3329 * Convert GENERIC bits to specific bits.
3332 se_map_generic(&access_mask, &file_generic_mapping);
3334 /* Calculate MAXIMUM_ALLOWED_ACCESS if requested. */
3335 if (access_mask & MAXIMUM_ALLOWED_ACCESS) {
3337 status = smbd_calculate_maximum_allowed_access_fsp(
3338 dirfsp,
3339 fsp,
3340 use_privs,
3341 &access_mask);
3343 if (!NT_STATUS_IS_OK(status)) {
3344 return status;
3347 access_mask &= fsp->conn->share_access;
3350 rejected_share_access = access_mask & ~(fsp->conn->share_access);
3352 if (rejected_share_access) {
3353 DBG_ERR("Access denied on file %s: "
3354 "rejected by share access mask[0x%08X] "
3355 "orig[0x%08X] mapped[0x%08X] reject[0x%08X]\n",
3356 fsp_str_dbg(fsp),
3357 fsp->conn->share_access,
3358 orig_access_mask, access_mask,
3359 rejected_share_access);
3360 return NT_STATUS_ACCESS_DENIED;
3363 *access_mask_out = access_mask;
3364 return NT_STATUS_OK;
3367 /****************************************************************************
3368 Remove the deferred open entry under lock.
3369 ****************************************************************************/
3371 /****************************************************************************
3372 Return true if this is a state pointer to an asynchronous create.
3373 ****************************************************************************/
3375 bool is_deferred_open_async(const struct deferred_open_record *rec)
3377 return rec->async_open;
3380 static bool clear_ads(uint32_t create_disposition)
3382 bool ret = false;
3384 switch (create_disposition) {
3385 case FILE_SUPERSEDE:
3386 case FILE_OVERWRITE_IF:
3387 case FILE_OVERWRITE:
3388 ret = true;
3389 break;
3390 default:
3391 break;
3393 return ret;
3396 static int disposition_to_open_flags(uint32_t create_disposition)
3398 int ret = 0;
3401 * Currently we're using FILE_SUPERSEDE as the same as
3402 * FILE_OVERWRITE_IF but they really are
3403 * different. FILE_SUPERSEDE deletes an existing file
3404 * (requiring delete access) then recreates it.
3407 switch (create_disposition) {
3408 case FILE_SUPERSEDE:
3409 case FILE_OVERWRITE_IF:
3411 * If file exists replace/overwrite. If file doesn't
3412 * exist create.
3414 ret = O_CREAT|O_TRUNC;
3415 break;
3417 case FILE_OPEN:
3419 * If file exists open. If file doesn't exist error.
3421 ret = 0;
3422 break;
3424 case FILE_OVERWRITE:
3426 * If file exists overwrite. If file doesn't exist
3427 * error.
3429 ret = O_TRUNC;
3430 break;
3432 case FILE_CREATE:
3434 * If file exists error. If file doesn't exist create.
3436 ret = O_CREAT|O_EXCL;
3437 break;
3439 case FILE_OPEN_IF:
3441 * If file exists open. If file doesn't exist create.
3443 ret = O_CREAT;
3444 break;
3446 return ret;
3449 static int calculate_open_access_flags(uint32_t access_mask,
3450 uint32_t private_flags)
3452 bool need_write, need_read;
3455 * Note that we ignore the append flag as append does not
3456 * mean the same thing under DOS and Unix.
3459 need_write = (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA));
3460 if (!need_write) {
3461 return O_RDONLY;
3464 /* DENY_DOS opens are always underlying read-write on the
3465 file handle, no matter what the requested access mask
3466 says. */
3468 need_read =
3469 ((private_flags & NTCREATEX_FLAG_DENY_DOS) ||
3470 access_mask & (FILE_READ_ATTRIBUTES|FILE_READ_DATA|
3471 FILE_READ_EA|FILE_EXECUTE));
3473 if (!need_read) {
3474 return O_WRONLY;
3476 return O_RDWR;
3479 /****************************************************************************
3480 Open a file with a share mode. Passed in an already created files_struct *.
3481 ****************************************************************************/
3483 static NTSTATUS open_file_ntcreate(connection_struct *conn,
3484 struct smb_request *req,
3485 uint32_t access_mask, /* access bits (FILE_READ_DATA etc.) */
3486 uint32_t share_access, /* share constants (FILE_SHARE_READ etc) */
3487 uint32_t create_disposition, /* FILE_OPEN_IF etc. */
3488 uint32_t create_options, /* options such as delete on close. */
3489 uint32_t new_dos_attributes, /* attributes used for new file. */
3490 int oplock_request, /* internal Samba oplock codes. */
3491 const struct smb2_lease *lease,
3492 /* Information (FILE_EXISTS etc.) */
3493 uint32_t private_flags, /* Samba specific flags. */
3494 struct smb_filename *parent_dir_fname, /* parent. */
3495 struct smb_filename *smb_fname_atname, /* atname relative to parent. */
3496 int *pinfo,
3497 files_struct *fsp)
3499 struct smb_filename *smb_fname = fsp->fsp_name;
3500 int flags=0;
3501 int flags2=0;
3502 bool file_existed = VALID_STAT(smb_fname->st);
3503 bool def_acl = False;
3504 bool posix_open = False;
3505 bool new_file_created = False;
3506 bool first_open_attempt = true;
3507 NTSTATUS fsp_open = NT_STATUS_ACCESS_DENIED;
3508 mode_t new_unx_mode = (mode_t)0;
3509 mode_t unx_mode = (mode_t)0;
3510 int info;
3511 uint32_t existing_dos_attributes = 0;
3512 struct share_mode_lock *lck = NULL;
3513 uint32_t open_access_mask = access_mask;
3514 NTSTATUS status;
3515 SMB_STRUCT_STAT saved_stat = smb_fname->st;
3516 struct timespec old_write_time;
3517 bool setup_poll = false;
3518 bool ok;
3520 if (conn->printer) {
3522 * Printers are handled completely differently.
3523 * Most of the passed parameters are ignored.
3526 if (pinfo) {
3527 *pinfo = FILE_WAS_CREATED;
3530 DEBUG(10, ("open_file_ntcreate: printer open fname=%s\n",
3531 smb_fname_str_dbg(smb_fname)));
3533 if (!req) {
3534 DEBUG(0,("open_file_ntcreate: printer open without "
3535 "an SMB request!\n"));
3536 return NT_STATUS_INTERNAL_ERROR;
3539 return print_spool_open(fsp, smb_fname->base_name,
3540 req->vuid);
3543 if (new_dos_attributes & FILE_FLAG_POSIX_SEMANTICS) {
3544 posix_open = True;
3545 unx_mode = (mode_t)(new_dos_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
3546 new_dos_attributes = 0;
3547 } else {
3548 /* Windows allows a new file to be created and
3549 silently removes a FILE_ATTRIBUTE_DIRECTORY
3550 sent by the client. Do the same. */
3552 new_dos_attributes &= ~FILE_ATTRIBUTE_DIRECTORY;
3554 /* We add FILE_ATTRIBUTE_ARCHIVE to this as this mode is only used if the file is
3555 * created new. */
3556 unx_mode = unix_mode(
3557 conn,
3558 new_dos_attributes | FILE_ATTRIBUTE_ARCHIVE,
3559 smb_fname,
3560 parent_dir_fname->fsp);
3563 DEBUG(10, ("open_file_ntcreate: fname=%s, dos_attrs=0x%x "
3564 "access_mask=0x%x share_access=0x%x "
3565 "create_disposition = 0x%x create_options=0x%x "
3566 "unix mode=0%o oplock_request=%d private_flags = 0x%x\n",
3567 smb_fname_str_dbg(smb_fname), new_dos_attributes,
3568 access_mask, share_access, create_disposition,
3569 create_options, (unsigned int)unx_mode, oplock_request,
3570 (unsigned int)private_flags));
3572 if (req == NULL) {
3573 /* Ensure req == NULL means INTERNAL_OPEN_ONLY */
3574 SMB_ASSERT(oplock_request == INTERNAL_OPEN_ONLY);
3575 } else {
3576 /* And req != NULL means no INTERNAL_OPEN_ONLY */
3577 SMB_ASSERT(((oplock_request & INTERNAL_OPEN_ONLY) == 0));
3581 * Only non-internal opens can be deferred at all
3584 if (req) {
3585 struct deferred_open_record *open_rec;
3586 if (get_deferred_open_message_state(req, NULL, &open_rec)) {
3588 /* If it was an async create retry, the file
3589 didn't exist. */
3591 if (is_deferred_open_async(open_rec)) {
3592 SET_STAT_INVALID(smb_fname->st);
3593 file_existed = false;
3596 /* Ensure we don't reprocess this message. */
3597 remove_deferred_open_message_smb(req->xconn, req->mid);
3599 first_open_attempt = false;
3603 if (!posix_open) {
3604 new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
3605 if (file_existed) {
3607 * Only use stored DOS attributes for checks
3608 * against requested attributes (below via
3609 * open_match_attributes()), cf bug #11992
3610 * for details. -slow
3612 uint32_t attr = 0;
3614 status = SMB_VFS_FGET_DOS_ATTRIBUTES(conn, smb_fname->fsp, &attr);
3615 if (NT_STATUS_IS_OK(status)) {
3616 existing_dos_attributes = attr;
3621 /* ignore any oplock requests if oplocks are disabled */
3622 if (!lp_oplocks(SNUM(conn)) ||
3623 IS_VETO_OPLOCK_PATH(conn, smb_fname->base_name)) {
3624 /* Mask off everything except the private Samba bits. */
3625 oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
3628 /* this is for OS/2 long file names - say we don't support them */
3629 if (req != NULL && !req->posix_pathnames &&
3630 strstr(smb_fname->base_name,".+,;=[].")) {
3631 /* OS/2 Workplace shell fix may be main code stream in a later
3632 * release. */
3633 DEBUG(5,("open_file_ntcreate: OS/2 long filenames are not "
3634 "supported.\n"));
3635 if (use_nt_status()) {
3636 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3638 return NT_STATUS_DOS(ERRDOS, ERRcannotopen);
3641 switch( create_disposition ) {
3642 case FILE_OPEN:
3643 /* If file exists open. If file doesn't exist error. */
3644 if (!file_existed) {
3645 DEBUG(5,("open_file_ntcreate: FILE_OPEN "
3646 "requested for file %s and file "
3647 "doesn't exist.\n",
3648 smb_fname_str_dbg(smb_fname)));
3649 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3651 break;
3653 case FILE_OVERWRITE:
3654 /* If file exists overwrite. If file doesn't exist
3655 * error. */
3656 if (!file_existed) {
3657 DEBUG(5,("open_file_ntcreate: FILE_OVERWRITE "
3658 "requested for file %s and file "
3659 "doesn't exist.\n",
3660 smb_fname_str_dbg(smb_fname) ));
3661 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3663 break;
3665 case FILE_CREATE:
3666 /* If file exists error. If file doesn't exist
3667 * create. */
3668 if (file_existed) {
3669 DEBUG(5,("open_file_ntcreate: FILE_CREATE "
3670 "requested for file %s and file "
3671 "already exists.\n",
3672 smb_fname_str_dbg(smb_fname)));
3673 if (S_ISDIR(smb_fname->st.st_ex_mode)) {
3674 return NT_STATUS_FILE_IS_A_DIRECTORY;
3676 return NT_STATUS_OBJECT_NAME_COLLISION;
3678 break;
3680 case FILE_SUPERSEDE:
3681 case FILE_OVERWRITE_IF:
3682 case FILE_OPEN_IF:
3683 break;
3684 default:
3685 return NT_STATUS_INVALID_PARAMETER;
3688 flags2 = disposition_to_open_flags(create_disposition);
3690 /* We only care about matching attributes on file exists and
3691 * overwrite. */
3693 if (!posix_open && file_existed &&
3694 ((create_disposition == FILE_OVERWRITE) ||
3695 (create_disposition == FILE_OVERWRITE_IF))) {
3696 if (!open_match_attributes(conn, existing_dos_attributes,
3697 new_dos_attributes,
3698 unx_mode, &new_unx_mode)) {
3699 DEBUG(5,("open_file_ntcreate: attributes mismatch "
3700 "for file %s (%x %x) (0%o, 0%o)\n",
3701 smb_fname_str_dbg(smb_fname),
3702 existing_dos_attributes,
3703 new_dos_attributes,
3704 (unsigned int)smb_fname->st.st_ex_mode,
3705 (unsigned int)unx_mode ));
3706 return NT_STATUS_ACCESS_DENIED;
3710 status = smbd_calculate_access_mask_fsp(parent_dir_fname->fsp,
3711 smb_fname->fsp,
3712 false,
3713 access_mask,
3714 &access_mask);
3715 if (!NT_STATUS_IS_OK(status)) {
3716 DBG_DEBUG("smbd_calculate_access_mask_fsp "
3717 "on file %s returned %s\n",
3718 smb_fname_str_dbg(smb_fname),
3719 nt_errstr(status));
3720 return status;
3723 open_access_mask = access_mask;
3725 if (flags2 & O_TRUNC) {
3726 open_access_mask |= FILE_WRITE_DATA; /* This will cause oplock breaks. */
3729 if (file_existed) {
3731 * stat opens on existing files don't get oplocks.
3732 * They can get leases.
3734 * Note that we check for stat open on the *open_access_mask*,
3735 * i.e. the access mask we actually used to do the open,
3736 * not the one the client asked for (which is in
3737 * fsp->access_mask). This is due to the fact that
3738 * FILE_OVERWRITE and FILE_OVERWRITE_IF add in O_TRUNC,
3739 * which adds FILE_WRITE_DATA to open_access_mask.
3741 if (is_oplock_stat_open(open_access_mask) && lease == NULL) {
3742 oplock_request = NO_OPLOCK;
3746 DEBUG(10, ("open_file_ntcreate: fname=%s, after mapping "
3747 "access_mask=0x%x\n", smb_fname_str_dbg(smb_fname),
3748 access_mask));
3751 * Note that we ignore the append flag as append does not
3752 * mean the same thing under DOS and Unix.
3755 flags = calculate_open_access_flags(access_mask, private_flags);
3758 * Currently we only look at FILE_WRITE_THROUGH for create options.
3761 #if defined(O_SYNC)
3762 if ((create_options & FILE_WRITE_THROUGH) && lp_strict_sync(SNUM(conn))) {
3763 flags2 |= O_SYNC;
3765 #endif /* O_SYNC */
3767 if (posix_open && (access_mask & FILE_APPEND_DATA)) {
3768 flags2 |= O_APPEND;
3771 if (!posix_open && !CAN_WRITE(conn)) {
3773 * We should really return a permission denied error if either
3774 * O_CREAT or O_TRUNC are set, but for compatibility with
3775 * older versions of Samba we just AND them out.
3777 flags2 &= ~(O_CREAT|O_TRUNC);
3781 * With kernel oplocks the open breaking an oplock
3782 * blocks until the oplock holder has given up the
3783 * oplock or closed the file. We prevent this by always
3784 * trying to open the file with O_NONBLOCK (see "man
3785 * fcntl" on Linux).
3787 * If a process that doesn't use the smbd open files
3788 * database or communication methods holds a kernel
3789 * oplock we must periodically poll for available open
3790 * using O_NONBLOCK.
3792 flags2 |= O_NONBLOCK;
3795 * Ensure we can't write on a read-only share or file.
3798 if (flags != O_RDONLY && file_existed &&
3799 (!CAN_WRITE(conn) || IS_DOS_READONLY(existing_dos_attributes))) {
3800 DEBUG(5,("open_file_ntcreate: write access requested for "
3801 "file %s on read only %s\n",
3802 smb_fname_str_dbg(smb_fname),
3803 !CAN_WRITE(conn) ? "share" : "file" ));
3804 return NT_STATUS_ACCESS_DENIED;
3807 if (VALID_STAT(smb_fname->st)) {
3809 * Only try and create a file id before open
3810 * for an existing file. For a file being created
3811 * this won't do anything useful until the file
3812 * exists and has a valid stat struct.
3814 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
3816 fh_set_private_options(fsp->fh, private_flags);
3817 fsp->access_mask = open_access_mask; /* We change this to the
3818 * requested access_mask after
3819 * the open is done. */
3820 if (posix_open) {
3821 fsp->posix_flags |= FSP_POSIX_FLAGS_ALL;
3824 if ((create_options & FILE_DELETE_ON_CLOSE) &&
3825 (flags2 & O_CREAT) &&
3826 !file_existed) {
3827 /* Delete on close semantics for new files. */
3828 status = can_set_delete_on_close(fsp,
3829 new_dos_attributes);
3830 if (!NT_STATUS_IS_OK(status)) {
3831 fd_close(fsp);
3832 return status;
3837 * Ensure we pay attention to default ACLs on directories if required.
3840 if ((flags2 & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
3841 (def_acl = directory_has_default_acl_fsp(parent_dir_fname->fsp)))
3843 unx_mode = (0777 & lp_create_mask(SNUM(conn)));
3846 DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o, "
3847 "access_mask = 0x%x, open_access_mask = 0x%x\n",
3848 (unsigned int)flags, (unsigned int)flags2,
3849 (unsigned int)unx_mode, (unsigned int)access_mask,
3850 (unsigned int)open_access_mask));
3852 fsp_open = open_file(fsp,
3853 req,
3854 parent_dir_fname->fsp,
3855 flags|flags2,
3856 unx_mode,
3857 access_mask,
3858 open_access_mask,
3859 private_flags,
3860 &new_file_created);
3861 if (NT_STATUS_EQUAL(fsp_open, NT_STATUS_NETWORK_BUSY)) {
3862 if (file_existed && S_ISFIFO(fsp->fsp_name->st.st_ex_mode)) {
3863 DEBUG(10, ("FIFO busy\n"));
3864 return NT_STATUS_NETWORK_BUSY;
3866 if (req == NULL) {
3867 DEBUG(10, ("Internal open busy\n"));
3868 return NT_STATUS_NETWORK_BUSY;
3871 * This handles the kernel oplock case:
3873 * the file has an active kernel oplock and the open() returned
3874 * EWOULDBLOCK/EAGAIN which maps to NETWORK_BUSY.
3876 * "Samba locking.tdb oplocks" are handled below after acquiring
3877 * the sharemode lock with get_share_mode_lock().
3879 setup_poll = true;
3882 if (NT_STATUS_EQUAL(fsp_open, NT_STATUS_RETRY)) {
3884 * EINTR from the open(2) syscall. Just setup a retry
3885 * in a bit. We can't use the sys_write() tight retry
3886 * loop here, as we might have to actually deal with
3887 * lease-break signals to avoid a deadlock.
3889 setup_poll = true;
3892 if (setup_poll) {
3894 * From here on we assume this is an oplock break triggered
3897 lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
3899 if ((lck != NULL) && !validate_oplock_types(lck)) {
3900 smb_panic("validate_oplock_types failed");
3904 * Retry once a second. If there's a share_mode_lock
3905 * around, also wait for it in case it was smbd
3906 * holding that kernel oplock that can quickly tell us
3907 * the oplock got removed.
3910 setup_poll_open(
3911 req,
3912 lck,
3913 fsp->file_id,
3914 timeval_set(OPLOCK_BREAK_TIMEOUT*2, 0),
3915 timeval_set(1, 0));
3917 TALLOC_FREE(lck);
3919 return NT_STATUS_SHARING_VIOLATION;
3922 if (!NT_STATUS_IS_OK(fsp_open)) {
3923 bool wait_for_aio = NT_STATUS_EQUAL(
3924 fsp_open, NT_STATUS_MORE_PROCESSING_REQUIRED);
3925 if (wait_for_aio) {
3926 schedule_async_open(req);
3928 return fsp_open;
3931 if (new_file_created) {
3933 * As we atomically create using O_CREAT|O_EXCL,
3934 * then if new_file_created is true, then
3935 * file_existed *MUST* have been false (even
3936 * if the file was previously detected as being
3937 * there).
3939 file_existed = false;
3942 if (file_existed && !check_same_dev_ino(&saved_stat, &smb_fname->st)) {
3944 * The file did exist, but some other (local or NFS)
3945 * process either renamed/unlinked and re-created the
3946 * file with different dev/ino after we walked the path,
3947 * but before we did the open. We could retry the
3948 * open but it's a rare enough case it's easier to
3949 * just fail the open to prevent creating any problems
3950 * in the open file db having the wrong dev/ino key.
3952 fd_close(fsp);
3953 DBG_WARNING("file %s - dev/ino mismatch. "
3954 "Old (dev=%ju, ino=%ju). "
3955 "New (dev=%ju, ino=%ju). Failing open "
3956 "with NT_STATUS_ACCESS_DENIED.\n",
3957 smb_fname_str_dbg(smb_fname),
3958 (uintmax_t)saved_stat.st_ex_dev,
3959 (uintmax_t)saved_stat.st_ex_ino,
3960 (uintmax_t)smb_fname->st.st_ex_dev,
3961 (uintmax_t)smb_fname->st.st_ex_ino);
3962 return NT_STATUS_ACCESS_DENIED;
3965 old_write_time = smb_fname->st.st_ex_mtime;
3968 * Deal with the race condition where two smbd's detect the
3969 * file doesn't exist and do the create at the same time. One
3970 * of them will win and set a share mode, the other (ie. this
3971 * one) should check if the requested share mode for this
3972 * create is allowed.
3976 * Now the file exists and fsp is successfully opened,
3977 * fsp->dev and fsp->inode are valid and should replace the
3978 * dev=0,inode=0 from a non existent file. Spotted by
3979 * Nadav Danieli <nadavd@exanet.com>. JRA.
3982 lck = get_share_mode_lock(talloc_tos(), fsp->file_id,
3983 conn->connectpath,
3984 smb_fname, &old_write_time);
3986 if (lck == NULL) {
3987 DEBUG(0, ("open_file_ntcreate: Could not get share "
3988 "mode lock for %s\n",
3989 smb_fname_str_dbg(smb_fname)));
3990 fd_close(fsp);
3991 return NT_STATUS_SHARING_VIOLATION;
3994 /* Get the types we need to examine. */
3995 if (!validate_oplock_types(lck)) {
3996 smb_panic("validate_oplock_types failed");
3999 if (has_delete_on_close(lck, fsp->name_hash)) {
4000 TALLOC_FREE(lck);
4001 fd_close(fsp);
4002 return NT_STATUS_DELETE_PENDING;
4005 status = handle_share_mode_lease(
4006 fsp,
4007 lck,
4008 create_disposition,
4009 access_mask,
4010 share_access,
4011 oplock_request,
4012 lease,
4013 first_open_attempt);
4015 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
4016 schedule_defer_open(lck, fsp->file_id, req);
4017 TALLOC_FREE(lck);
4018 fd_close(fsp);
4019 return NT_STATUS_SHARING_VIOLATION;
4022 if (!NT_STATUS_IS_OK(status)) {
4023 TALLOC_FREE(lck);
4024 fd_close(fsp);
4025 return status;
4028 share_mode_flags_restrict(lck, access_mask, share_access, 0);
4030 ok = set_share_mode(
4031 lck,
4032 fsp,
4033 get_current_uid(fsp->conn),
4034 req ? req->mid : 0,
4035 fsp->oplock_type,
4036 share_access,
4037 access_mask);
4038 if (!ok) {
4039 if (fsp->oplock_type == LEASE_OPLOCK) {
4040 status = remove_lease_if_stale(
4041 lck,
4042 fsp_client_guid(fsp),
4043 &fsp->lease->lease.lease_key);
4044 if (!NT_STATUS_IS_OK(status)) {
4045 DBG_WARNING("remove_lease_if_stale "
4046 "failed: %s\n",
4047 nt_errstr(status));
4050 TALLOC_FREE(lck);
4051 fd_close(fsp);
4052 return NT_STATUS_NO_MEMORY;
4055 /* Should we atomically (to the client at least) truncate ? */
4056 if ((!new_file_created) &&
4057 (flags2 & O_TRUNC) &&
4058 (S_ISREG(fsp->fsp_name->st.st_ex_mode))) {
4059 int ret;
4061 ret = SMB_VFS_FTRUNCATE(fsp, 0);
4062 if (ret != 0) {
4063 status = map_nt_error_from_unix(errno);
4064 del_share_mode(lck, fsp);
4065 TALLOC_FREE(lck);
4066 fd_close(fsp);
4067 return status;
4069 notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
4070 FILE_NOTIFY_CHANGE_SIZE
4071 | FILE_NOTIFY_CHANGE_ATTRIBUTES,
4072 fsp->fsp_name->base_name);
4076 * We have the share entry *locked*.....
4079 /* Delete streams if create_disposition requires it */
4080 if (!new_file_created &&
4081 clear_ads(create_disposition) &&
4082 !fsp_is_alternate_stream(fsp)) {
4083 status = delete_all_streams(conn, smb_fname);
4084 if (!NT_STATUS_IS_OK(status)) {
4085 del_share_mode(lck, fsp);
4086 TALLOC_FREE(lck);
4087 fd_close(fsp);
4088 return status;
4092 if (!fsp->fsp_flags.is_pathref &&
4093 fsp_get_io_fd(fsp) != -1 &&
4094 lp_kernel_share_modes(SNUM(conn)))
4096 int ret;
4098 * Beware: streams implementing VFS modules may
4099 * implement streams in a way that fsp will have the
4100 * basefile open in the fsp fd, so lacking a distinct
4101 * fd for the stream the file-system sharemode will
4102 * apply on the basefile which is wrong. The actual
4103 * check is deferred to the VFS module implementing
4104 * the file-system sharemode call.
4106 ret = SMB_VFS_FILESYSTEM_SHAREMODE(fsp,
4107 share_access,
4108 access_mask);
4109 if (ret == -1){
4110 del_share_mode(lck, fsp);
4111 TALLOC_FREE(lck);
4112 fd_close(fsp);
4114 return NT_STATUS_SHARING_VIOLATION;
4117 fsp->fsp_flags.kernel_share_modes_taken = true;
4121 * At this point onwards, we can guarantee that the share entry
4122 * is locked, whether we created the file or not, and that the
4123 * deny mode is compatible with all current opens.
4127 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
4128 * but we don't have to store this - just ignore it on access check.
4130 if (conn->sconn->using_smb2) {
4132 * SMB2 doesn't return it (according to Microsoft tests).
4133 * Test Case: TestSuite_ScenarioNo009GrantedAccessTestS0
4134 * File created with access = 0x7 (Read, Write, Delete)
4135 * Query Info on file returns 0x87 (Read, Write, Delete, Read Attributes)
4137 fsp->access_mask = access_mask;
4138 } else {
4139 /* But SMB1 does. */
4140 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
4143 if (new_file_created) {
4144 info = FILE_WAS_CREATED;
4145 } else {
4146 if (flags2 & O_TRUNC) {
4147 info = FILE_WAS_OVERWRITTEN;
4148 } else {
4149 info = FILE_WAS_OPENED;
4153 if (pinfo) {
4154 *pinfo = info;
4157 /* Handle strange delete on close create semantics. */
4158 if (create_options & FILE_DELETE_ON_CLOSE) {
4159 if (!new_file_created) {
4160 status = can_set_delete_on_close(fsp,
4161 existing_dos_attributes);
4163 if (!NT_STATUS_IS_OK(status)) {
4164 /* Remember to delete the mode we just added. */
4165 del_share_mode(lck, fsp);
4166 TALLOC_FREE(lck);
4167 fd_close(fsp);
4168 return status;
4171 /* Note that here we set the *initial* delete on close flag,
4172 not the regular one. The magic gets handled in close. */
4173 fsp->fsp_flags.initial_delete_on_close = true;
4177 * If we created a file and it's not a stream, this is the point where
4178 * we set the itime (aka invented time) that get's stored in the DOS
4179 * attribute xattr. The value is going to be either what the filesystem
4180 * provided or a generated itime value.
4182 * Either way, we turn the itime into a File-ID, unless the filesystem
4183 * provided one (unlikely).
4185 if (info == FILE_WAS_CREATED && !is_named_stream(smb_fname)) {
4186 create_clock_itime(&smb_fname->st);
4188 if (lp_store_dos_attributes(SNUM(conn)) &&
4189 smb_fname->st.st_ex_iflags & ST_EX_IFLAG_CALCULATED_FILE_ID)
4191 uint64_t file_id;
4193 file_id = make_file_id_from_itime(&smb_fname->st);
4194 update_stat_ex_file_id(&smb_fname->st, file_id);
4198 if (info != FILE_WAS_OPENED) {
4199 /* Overwritten files should be initially set as archive */
4200 if ((info == FILE_WAS_OVERWRITTEN && lp_map_archive(SNUM(conn))) ||
4201 lp_store_dos_attributes(SNUM(conn))) {
4202 (void)fdos_mode(fsp);
4203 if (!posix_open) {
4204 if (file_set_dosmode(conn, smb_fname,
4205 new_dos_attributes | FILE_ATTRIBUTE_ARCHIVE,
4206 parent_dir_fname, true) == 0) {
4207 unx_mode = smb_fname->st.st_ex_mode;
4213 /* Determine sparse flag. */
4214 if (posix_open) {
4215 /* POSIX opens are sparse by default. */
4216 fsp->fsp_flags.is_sparse = true;
4217 } else {
4218 fsp->fsp_flags.is_sparse =
4219 (existing_dos_attributes & FILE_ATTRIBUTE_SPARSE);
4223 * Take care of inherited ACLs on created files - if default ACL not
4224 * selected.
4227 if (!posix_open && new_file_created && !def_acl) {
4228 if (unx_mode != smb_fname->st.st_ex_mode) {
4229 int ret = SMB_VFS_FCHMOD(fsp, unx_mode);
4230 if (ret == -1) {
4231 DBG_INFO("failed to reset "
4232 "attributes of file %s to 0%o\n",
4233 smb_fname_str_dbg(smb_fname),
4234 (unsigned int)unx_mode);
4238 } else if (new_unx_mode) {
4240 * We only get here in the case of:
4242 * a). Not a POSIX open.
4243 * b). File already existed.
4244 * c). File was overwritten.
4245 * d). Requested DOS attributes didn't match
4246 * the DOS attributes on the existing file.
4248 * In that case new_unx_mode has been set
4249 * equal to the calculated mode (including
4250 * possible inheritance of the mode from the
4251 * containing directory).
4253 * Note this mode was calculated with the
4254 * DOS attribute FILE_ATTRIBUTE_ARCHIVE added,
4255 * so the mode change here is suitable for
4256 * an overwritten file.
4259 if (new_unx_mode != smb_fname->st.st_ex_mode) {
4260 int ret = SMB_VFS_FCHMOD(fsp, new_unx_mode);
4261 if (ret == -1) {
4262 DBG_INFO("failed to reset "
4263 "attributes of file %s to 0%o\n",
4264 smb_fname_str_dbg(smb_fname),
4265 (unsigned int)new_unx_mode);
4272 * Deal with other opens having a modified write time.
4274 struct timespec write_time = get_share_mode_write_time(lck);
4276 if (!is_omit_timespec(&write_time)) {
4277 update_stat_ex_mtime(&fsp->fsp_name->st, write_time);
4281 TALLOC_FREE(lck);
4283 return NT_STATUS_OK;
4286 static NTSTATUS mkdir_internal(connection_struct *conn,
4287 struct smb_filename *parent_dir_fname, /* parent. */
4288 struct smb_filename *smb_fname_atname, /* atname relative to parent. */
4289 struct smb_filename *smb_dname, /* full pathname from root of share. */
4290 uint32_t file_attributes,
4291 struct files_struct *fsp)
4293 const struct loadparm_substitution *lp_sub =
4294 loadparm_s3_global_substitution();
4295 mode_t mode;
4296 NTSTATUS status;
4297 bool posix_open = false;
4298 bool need_re_stat = false;
4299 uint32_t access_mask = SEC_DIR_ADD_SUBDIR;
4300 int ret;
4302 if (!CAN_WRITE(conn) || (access_mask & ~(conn->share_access))) {
4303 DEBUG(5,("mkdir_internal: failing share access "
4304 "%s\n", lp_servicename(talloc_tos(), lp_sub, SNUM(conn))));
4305 return NT_STATUS_ACCESS_DENIED;
4308 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
4309 posix_open = true;
4310 mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
4311 } else {
4312 mode = unix_mode(conn,
4313 FILE_ATTRIBUTE_DIRECTORY,
4314 smb_dname,
4315 parent_dir_fname->fsp);
4318 status = check_parent_access_fsp(parent_dir_fname->fsp, access_mask);
4319 if(!NT_STATUS_IS_OK(status)) {
4320 DBG_INFO("check_parent_access_fsp "
4321 "on directory %s for path %s returned %s\n",
4322 smb_fname_str_dbg(parent_dir_fname),
4323 smb_dname->base_name,
4324 nt_errstr(status));
4325 return status;
4328 if (lp_inherit_acls(SNUM(conn))) {
4329 if (directory_has_default_acl_fsp(parent_dir_fname->fsp)) {
4330 mode = (0777 & lp_directory_mask(SNUM(conn)));
4334 ret = SMB_VFS_MKDIRAT(conn,
4335 parent_dir_fname->fsp,
4336 smb_fname_atname,
4337 mode);
4338 if (ret != 0) {
4339 return map_nt_error_from_unix(errno);
4343 * Make this a pathref fsp for now. open_directory() will reopen as a
4344 * full fsp.
4346 fsp->fsp_flags.is_pathref = true;
4348 status = fd_openat(conn->cwd_fsp, smb_dname, fsp, O_RDONLY | O_DIRECTORY, 0);
4349 if (!NT_STATUS_IS_OK(status)) {
4350 return status;
4353 /* Ensure we're checking for a symlink here.... */
4354 /* We don't want to get caught by a symlink racer. */
4356 if (SMB_VFS_FSTAT(fsp, &smb_dname->st) == -1) {
4357 DEBUG(2, ("Could not stat directory '%s' just created: %s\n",
4358 smb_fname_str_dbg(smb_dname), strerror(errno)));
4359 return map_nt_error_from_unix(errno);
4362 if (!S_ISDIR(smb_dname->st.st_ex_mode)) {
4363 DEBUG(0, ("Directory '%s' just created is not a directory !\n",
4364 smb_fname_str_dbg(smb_dname)));
4365 return NT_STATUS_NOT_A_DIRECTORY;
4368 create_clock_itime(&smb_dname->st);
4370 if (lp_store_dos_attributes(SNUM(conn))) {
4371 if (smb_dname->st.st_ex_iflags & ST_EX_IFLAG_CALCULATED_FILE_ID)
4373 uint64_t file_id;
4375 file_id = make_file_id_from_itime(&smb_dname->st);
4376 update_stat_ex_file_id(&smb_dname->st, file_id);
4379 if (!posix_open) {
4380 file_set_dosmode(conn, smb_dname,
4381 file_attributes | FILE_ATTRIBUTE_DIRECTORY,
4382 parent_dir_fname, true);
4386 if (lp_inherit_permissions(SNUM(conn))) {
4387 inherit_access_posix_acl(conn, parent_dir_fname->fsp,
4388 smb_dname, mode);
4389 need_re_stat = true;
4392 if (!posix_open) {
4394 * Check if high bits should have been set,
4395 * then (if bits are missing): add them.
4396 * Consider bits automagically set by UNIX, i.e. SGID bit from parent
4397 * dir.
4399 if ((mode & ~(S_IRWXU|S_IRWXG|S_IRWXO)) &&
4400 (mode & ~smb_dname->st.st_ex_mode)) {
4401 SMB_VFS_FCHMOD(fsp,
4402 (smb_dname->st.st_ex_mode |
4403 (mode & ~smb_dname->st.st_ex_mode)));
4404 need_re_stat = true;
4408 /* Change the owner if required. */
4409 if (lp_inherit_owner(SNUM(conn)) != INHERIT_OWNER_NO) {
4410 change_dir_owner_to_parent_fsp(parent_dir_fname->fsp,
4411 fsp);
4412 need_re_stat = true;
4415 if (need_re_stat) {
4416 if (SMB_VFS_FSTAT(fsp, &smb_dname->st) == -1) {
4417 DEBUG(2, ("Could not stat directory '%s' just created: %s\n",
4418 smb_fname_str_dbg(smb_dname), strerror(errno)));
4419 return map_nt_error_from_unix(errno);
4423 notify_fname(conn, NOTIFY_ACTION_ADDED, FILE_NOTIFY_CHANGE_DIR_NAME,
4424 smb_dname->base_name);
4426 return NT_STATUS_OK;
4429 /****************************************************************************
4430 Open a directory from an NT SMB call.
4431 ****************************************************************************/
4433 static NTSTATUS open_directory(connection_struct *conn,
4434 struct smb_request *req,
4435 uint32_t access_mask,
4436 uint32_t share_access,
4437 uint32_t create_disposition,
4438 uint32_t create_options,
4439 uint32_t file_attributes,
4440 struct smb_filename *parent_dir_fname,
4441 struct smb_filename *smb_fname_atname,
4442 int *pinfo,
4443 struct files_struct *fsp)
4445 struct smb_filename *smb_dname = fsp->fsp_name;
4446 bool dir_existed = VALID_STAT(smb_dname->st);
4447 struct share_mode_lock *lck = NULL;
4448 NTSTATUS status;
4449 struct timespec mtimespec;
4450 int info = 0;
4451 bool ok;
4452 uint32_t need_fd_access;
4454 if (is_ntfs_stream_smb_fname(smb_dname)) {
4455 DEBUG(2, ("open_directory: %s is a stream name!\n",
4456 smb_fname_str_dbg(smb_dname)));
4457 return NT_STATUS_NOT_A_DIRECTORY;
4460 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS)) {
4461 /* Ensure we have a directory attribute. */
4462 file_attributes |= FILE_ATTRIBUTE_DIRECTORY;
4465 DBG_INFO("opening directory %s, access_mask = 0x%"PRIx32", "
4466 "share_access = 0x%"PRIx32" create_options = 0x%"PRIx32", "
4467 "create_disposition = 0x%"PRIx32", "
4468 "file_attributes = 0x%"PRIx32"\n",
4469 smb_fname_str_dbg(smb_dname),
4470 access_mask,
4471 share_access,
4472 create_options,
4473 create_disposition,
4474 file_attributes);
4476 status = smbd_calculate_access_mask_fsp(parent_dir_fname->fsp,
4477 smb_dname->fsp,
4478 false,
4479 access_mask,
4480 &access_mask);
4481 if (!NT_STATUS_IS_OK(status)) {
4482 DBG_DEBUG("smbd_calculate_access_mask_fsp "
4483 "on file %s returned %s\n",
4484 smb_fname_str_dbg(smb_dname),
4485 nt_errstr(status));
4486 return status;
4489 if ((access_mask & SEC_FLAG_SYSTEM_SECURITY) &&
4490 !security_token_has_privilege(get_current_nttok(conn),
4491 SEC_PRIV_SECURITY)) {
4492 DEBUG(10, ("open_directory: open on %s "
4493 "failed - SEC_FLAG_SYSTEM_SECURITY denied.\n",
4494 smb_fname_str_dbg(smb_dname)));
4495 return NT_STATUS_PRIVILEGE_NOT_HELD;
4498 switch( create_disposition ) {
4499 case FILE_OPEN:
4501 if (!dir_existed) {
4502 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4505 info = FILE_WAS_OPENED;
4506 break;
4508 case FILE_CREATE:
4510 /* If directory exists error. If directory doesn't
4511 * exist create. */
4513 if (dir_existed) {
4514 status = NT_STATUS_OBJECT_NAME_COLLISION;
4515 DEBUG(2, ("open_directory: unable to create "
4516 "%s. Error was %s\n",
4517 smb_fname_str_dbg(smb_dname),
4518 nt_errstr(status)));
4519 return status;
4522 status = mkdir_internal(conn,
4523 parent_dir_fname,
4524 smb_fname_atname,
4525 smb_dname,
4526 file_attributes,
4527 fsp);
4529 if (!NT_STATUS_IS_OK(status)) {
4530 DEBUG(2, ("open_directory: unable to create "
4531 "%s. Error was %s\n",
4532 smb_fname_str_dbg(smb_dname),
4533 nt_errstr(status)));
4534 return status;
4537 info = FILE_WAS_CREATED;
4538 break;
4540 case FILE_OPEN_IF:
4542 * If directory exists open. If directory doesn't
4543 * exist create.
4546 if (dir_existed) {
4547 status = NT_STATUS_OK;
4548 info = FILE_WAS_OPENED;
4549 } else {
4550 status = mkdir_internal(conn,
4551 parent_dir_fname,
4552 smb_fname_atname,
4553 smb_dname,
4554 file_attributes,
4555 fsp);
4557 if (NT_STATUS_IS_OK(status)) {
4558 info = FILE_WAS_CREATED;
4559 } else {
4560 /* Cope with create race. */
4561 if (!NT_STATUS_EQUAL(status,
4562 NT_STATUS_OBJECT_NAME_COLLISION)) {
4563 DEBUG(2, ("open_directory: unable to create "
4564 "%s. Error was %s\n",
4565 smb_fname_str_dbg(smb_dname),
4566 nt_errstr(status)));
4567 return status;
4571 * If mkdir_internal() returned
4572 * NT_STATUS_OBJECT_NAME_COLLISION
4573 * we still must lstat the path.
4576 if (SMB_VFS_LSTAT(conn, smb_dname)
4577 == -1) {
4578 DEBUG(2, ("Could not stat "
4579 "directory '%s' just "
4580 "opened: %s\n",
4581 smb_fname_str_dbg(
4582 smb_dname),
4583 strerror(errno)));
4584 return map_nt_error_from_unix(
4585 errno);
4588 info = FILE_WAS_OPENED;
4592 break;
4594 case FILE_SUPERSEDE:
4595 case FILE_OVERWRITE:
4596 case FILE_OVERWRITE_IF:
4597 default:
4598 DEBUG(5,("open_directory: invalid create_disposition "
4599 "0x%x for directory %s\n",
4600 (unsigned int)create_disposition,
4601 smb_fname_str_dbg(smb_dname)));
4602 return NT_STATUS_INVALID_PARAMETER;
4605 if(!S_ISDIR(smb_dname->st.st_ex_mode)) {
4606 DEBUG(5,("open_directory: %s is not a directory !\n",
4607 smb_fname_str_dbg(smb_dname)));
4608 return NT_STATUS_NOT_A_DIRECTORY;
4612 * Setup the files_struct for it.
4615 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_dname->st);
4616 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
4617 fsp->file_pid = req ? req->smbpid : 0;
4618 fsp->fsp_flags.can_lock = false;
4619 fsp->fsp_flags.can_read = false;
4620 fsp->fsp_flags.can_write = false;
4622 fh_set_private_options(fsp->fh, 0);
4624 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
4626 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
4627 fsp->print_file = NULL;
4628 fsp->fsp_flags.modified = false;
4629 fsp->oplock_type = NO_OPLOCK;
4630 fsp->sent_oplock_break = NO_BREAK_SENT;
4631 fsp->fsp_flags.is_directory = true;
4632 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
4633 fsp->posix_flags |= FSP_POSIX_FLAGS_ALL;
4636 /* Don't store old timestamps for directory
4637 handles in the internal database. We don't
4638 update them in there if new objects
4639 are created in the directory. Currently
4640 we only update timestamps on file writes.
4641 See bug #9870.
4643 mtimespec = make_omit_timespec();
4646 * Obviously for FILE_LIST_DIRECTORY we need to reopen to get an fd
4647 * usable for reading a directory. SMB2_FLUSH may be called on
4648 * directories opened with FILE_ADD_FILE and FILE_ADD_SUBDIRECTORY so
4649 * for those we need to reopen as well.
4651 need_fd_access =
4652 FILE_LIST_DIRECTORY |
4653 FILE_ADD_FILE |
4654 FILE_ADD_SUBDIRECTORY;
4656 if (access_mask & need_fd_access) {
4657 status = reopen_from_fsp(
4658 fsp->conn->cwd_fsp,
4659 fsp->fsp_name,
4660 fsp,
4661 O_RDONLY | O_DIRECTORY,
4663 NULL);
4664 if (!NT_STATUS_IS_OK(status)) {
4665 DBG_INFO("Could not open fd for [%s]: %s\n",
4666 smb_fname_str_dbg(smb_dname),
4667 nt_errstr(status));
4668 return status;
4672 status = vfs_stat_fsp(fsp);
4673 if (!NT_STATUS_IS_OK(status)) {
4674 fd_close(fsp);
4675 return status;
4678 if(!S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
4679 DEBUG(5,("open_directory: %s is not a directory !\n",
4680 smb_fname_str_dbg(smb_dname)));
4681 fd_close(fsp);
4682 return NT_STATUS_NOT_A_DIRECTORY;
4685 /* Ensure there was no race condition. We need to check
4686 * dev/inode but not permissions, as these can change
4687 * legitimately */
4688 if (!check_same_dev_ino(&smb_dname->st, &fsp->fsp_name->st)) {
4689 DEBUG(5,("open_directory: stat struct differs for "
4690 "directory %s.\n",
4691 smb_fname_str_dbg(smb_dname)));
4692 fd_close(fsp);
4693 return NT_STATUS_ACCESS_DENIED;
4696 if (info == FILE_WAS_OPENED) {
4697 status = smbd_check_access_rights_fsp(parent_dir_fname->fsp,
4698 fsp,
4699 false,
4700 access_mask);
4701 if (!NT_STATUS_IS_OK(status)) {
4702 DBG_DEBUG("smbd_check_access_rights_fsp on "
4703 "file %s failed with %s\n",
4704 fsp_str_dbg(fsp),
4705 nt_errstr(status));
4706 fd_close(fsp);
4707 return status;
4711 lck = get_share_mode_lock(talloc_tos(), fsp->file_id,
4712 conn->connectpath, smb_dname,
4713 &mtimespec);
4715 if (lck == NULL) {
4716 DEBUG(0, ("open_directory: Could not get share mode lock for "
4717 "%s\n", smb_fname_str_dbg(smb_dname)));
4718 fd_close(fsp);
4719 return NT_STATUS_SHARING_VIOLATION;
4722 if (has_delete_on_close(lck, fsp->name_hash)) {
4723 TALLOC_FREE(lck);
4724 fd_close(fsp);
4725 return NT_STATUS_DELETE_PENDING;
4728 status = open_mode_check(conn, fsp->file_id, lck,
4729 access_mask, share_access);
4731 if (!NT_STATUS_IS_OK(status)) {
4732 TALLOC_FREE(lck);
4733 fd_close(fsp);
4734 return status;
4737 share_mode_flags_restrict(lck, access_mask, share_access, 0);
4739 ok = set_share_mode(
4740 lck,
4741 fsp,
4742 get_current_uid(conn),
4743 req ? req->mid : 0,
4744 NO_OPLOCK,
4745 share_access,
4746 fsp->access_mask);
4747 if (!ok) {
4748 TALLOC_FREE(lck);
4749 fd_close(fsp);
4750 return NT_STATUS_NO_MEMORY;
4753 /* For directories the delete on close bit at open time seems
4754 always to be honored on close... See test 19 in Samba4 BASE-DELETE. */
4755 if (create_options & FILE_DELETE_ON_CLOSE) {
4756 status = can_set_delete_on_close(fsp, 0);
4757 if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
4758 del_share_mode(lck, fsp);
4759 TALLOC_FREE(lck);
4760 fd_close(fsp);
4761 return status;
4764 if (NT_STATUS_IS_OK(status)) {
4765 /* Note that here we set the *initial* delete on close flag,
4766 not the regular one. The magic gets handled in close. */
4767 fsp->fsp_flags.initial_delete_on_close = true;
4773 * Deal with other opens having a modified write time. Is this
4774 * possible for directories?
4776 struct timespec write_time = get_share_mode_write_time(lck);
4778 if (!is_omit_timespec(&write_time)) {
4779 update_stat_ex_mtime(&fsp->fsp_name->st, write_time);
4783 TALLOC_FREE(lck);
4785 if (pinfo) {
4786 *pinfo = info;
4789 return NT_STATUS_OK;
4792 NTSTATUS create_directory(connection_struct *conn, struct smb_request *req,
4793 struct smb_filename *smb_dname)
4795 NTSTATUS status;
4796 files_struct *fsp;
4798 status = SMB_VFS_CREATE_FILE(
4799 conn, /* conn */
4800 req, /* req */
4801 smb_dname, /* fname */
4802 FILE_READ_ATTRIBUTES, /* access_mask */
4803 FILE_SHARE_NONE, /* share_access */
4804 FILE_CREATE, /* create_disposition*/
4805 FILE_DIRECTORY_FILE, /* create_options */
4806 FILE_ATTRIBUTE_DIRECTORY, /* file_attributes */
4807 0, /* oplock_request */
4808 NULL, /* lease */
4809 0, /* allocation_size */
4810 0, /* private_flags */
4811 NULL, /* sd */
4812 NULL, /* ea_list */
4813 &fsp, /* result */
4814 NULL, /* pinfo */
4815 NULL, NULL); /* create context */
4817 if (NT_STATUS_IS_OK(status)) {
4818 close_file_free(req, &fsp, NORMAL_CLOSE);
4821 return status;
4824 /****************************************************************************
4825 Receive notification that one of our open files has been renamed by another
4826 smbd process.
4827 ****************************************************************************/
4829 void msg_file_was_renamed(struct messaging_context *msg_ctx,
4830 void *private_data,
4831 uint32_t msg_type,
4832 struct server_id src,
4833 DATA_BLOB *data)
4835 struct file_rename_message *msg = NULL;
4836 enum ndr_err_code ndr_err;
4837 files_struct *fsp;
4838 struct smb_filename *smb_fname = NULL;
4839 struct smbd_server_connection *sconn =
4840 talloc_get_type_abort(private_data,
4841 struct smbd_server_connection);
4843 msg = talloc(talloc_tos(), struct file_rename_message);
4844 if (msg == NULL) {
4845 DBG_WARNING("talloc failed\n");
4846 return;
4849 ndr_err = ndr_pull_struct_blob_all(
4850 data,
4851 msg,
4852 msg,
4853 (ndr_pull_flags_fn_t)ndr_pull_file_rename_message);
4854 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
4855 DBG_DEBUG("ndr_pull_oplock_break_message failed: %s\n",
4856 ndr_errstr(ndr_err));
4857 goto out;
4859 if (DEBUGLEVEL >= 10) {
4860 struct server_id_buf buf;
4861 DBG_DEBUG("Got rename message from %s\n",
4862 server_id_str_buf(src, &buf));
4863 NDR_PRINT_DEBUG(file_rename_message, msg);
4866 /* stream_name must always be NULL if there is no stream. */
4867 if ((msg->stream_name != NULL) && (msg->stream_name[0] == '\0')) {
4868 msg->stream_name = NULL;
4871 smb_fname = synthetic_smb_fname(msg,
4872 msg->base_name,
4873 msg->stream_name,
4874 NULL,
4877 if (smb_fname == NULL) {
4878 DBG_DEBUG("synthetic_smb_fname failed\n");
4879 goto out;
4882 fsp = file_find_dif(sconn, msg->id, msg->share_file_id);
4883 if (fsp == NULL) {
4884 DBG_DEBUG("fsp not found\n");
4885 goto out;
4888 if (strcmp(fsp->conn->connectpath, msg->servicepath) == 0) {
4889 NTSTATUS status;
4890 DBG_DEBUG("renaming file %s from %s -> %s\n",
4891 fsp_fnum_dbg(fsp),
4892 fsp_str_dbg(fsp),
4893 smb_fname_str_dbg(smb_fname));
4894 status = fsp_set_smb_fname(fsp, smb_fname);
4895 if (!NT_STATUS_IS_OK(status)) {
4896 DBG_DEBUG("fsp_set_smb_fname failed: %s\n",
4897 nt_errstr(status));
4899 } else {
4900 /* TODO. JRA. */
4902 * Now we have the complete path we can work out if
4903 * this is actually within this share and adjust
4904 * newname accordingly.
4906 DBG_DEBUG("share mismatch (sharepath %s not sharepath %s) "
4907 "%s from %s -> %s\n",
4908 fsp->conn->connectpath,
4909 msg->servicepath,
4910 fsp_fnum_dbg(fsp),
4911 fsp_str_dbg(fsp),
4912 smb_fname_str_dbg(smb_fname));
4914 out:
4915 TALLOC_FREE(msg);
4919 * If a main file is opened for delete, all streams need to be checked for
4920 * !FILE_SHARE_DELETE. Do this by opening with DELETE_ACCESS.
4921 * If that works, delete them all by setting the delete on close and close.
4924 static NTSTATUS open_streams_for_delete(connection_struct *conn,
4925 const struct smb_filename *smb_fname)
4927 struct stream_struct *stream_info = NULL;
4928 files_struct **streams = NULL;
4929 int j;
4930 unsigned int i, num_streams = 0;
4931 TALLOC_CTX *frame = talloc_stackframe();
4932 const struct smb_filename *pathref = NULL;
4933 NTSTATUS status;
4935 if (smb_fname->fsp == NULL) {
4936 struct smb_filename *tmp = NULL;
4937 status = synthetic_pathref(frame,
4938 conn->cwd_fsp,
4939 smb_fname->base_name,
4940 NULL,
4941 NULL,
4942 smb_fname->twrp,
4943 smb_fname->flags,
4944 &tmp);
4945 if (!NT_STATUS_IS_OK(status)) {
4946 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
4947 || NT_STATUS_EQUAL(status,
4948 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4949 DBG_DEBUG("no streams around\n");
4950 TALLOC_FREE(frame);
4951 return NT_STATUS_OK;
4953 DBG_DEBUG("synthetic_pathref failed: %s\n",
4954 nt_errstr(status));
4955 goto fail;
4957 pathref = tmp;
4958 } else {
4959 pathref = smb_fname;
4961 status = vfs_fstreaminfo(pathref->fsp, talloc_tos(),
4962 &num_streams, &stream_info);
4964 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
4965 || NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4966 DEBUG(10, ("no streams around\n"));
4967 TALLOC_FREE(frame);
4968 return NT_STATUS_OK;
4971 if (!NT_STATUS_IS_OK(status)) {
4972 DEBUG(10, ("vfs_fstreaminfo failed: %s\n",
4973 nt_errstr(status)));
4974 goto fail;
4977 DEBUG(10, ("open_streams_for_delete found %d streams\n",
4978 num_streams));
4980 if (num_streams == 0) {
4981 TALLOC_FREE(frame);
4982 return NT_STATUS_OK;
4985 streams = talloc_array(talloc_tos(), files_struct *, num_streams);
4986 if (streams == NULL) {
4987 DEBUG(0, ("talloc failed\n"));
4988 status = NT_STATUS_NO_MEMORY;
4989 goto fail;
4992 for (i=0; i<num_streams; i++) {
4993 struct smb_filename *smb_fname_cp;
4995 if (strequal(stream_info[i].name, "::$DATA")) {
4996 streams[i] = NULL;
4997 continue;
5000 smb_fname_cp = synthetic_smb_fname(talloc_tos(),
5001 smb_fname->base_name,
5002 stream_info[i].name,
5003 NULL,
5004 smb_fname->twrp,
5005 (smb_fname->flags &
5006 ~SMB_FILENAME_POSIX_PATH));
5007 if (smb_fname_cp == NULL) {
5008 status = NT_STATUS_NO_MEMORY;
5009 goto fail;
5012 status = openat_pathref_fsp(conn->cwd_fsp, smb_fname_cp);
5013 if (!NT_STATUS_IS_OK(status)) {
5014 DBG_DEBUG("Unable to open stream [%s]: %s\n",
5015 smb_fname_str_dbg(smb_fname_cp),
5016 nt_errstr(status));
5017 TALLOC_FREE(smb_fname_cp);
5018 break;
5021 status = SMB_VFS_CREATE_FILE(
5022 conn, /* conn */
5023 NULL, /* req */
5024 smb_fname_cp, /* fname */
5025 DELETE_ACCESS, /* access_mask */
5026 (FILE_SHARE_READ | /* share_access */
5027 FILE_SHARE_WRITE | FILE_SHARE_DELETE),
5028 FILE_OPEN, /* create_disposition*/
5029 0, /* create_options */
5030 FILE_ATTRIBUTE_NORMAL, /* file_attributes */
5031 0, /* oplock_request */
5032 NULL, /* lease */
5033 0, /* allocation_size */
5034 0, /* private_flags */
5035 NULL, /* sd */
5036 NULL, /* ea_list */
5037 &streams[i], /* result */
5038 NULL, /* pinfo */
5039 NULL, NULL); /* create context */
5041 if (!NT_STATUS_IS_OK(status)) {
5042 DEBUG(10, ("Could not open stream %s: %s\n",
5043 smb_fname_str_dbg(smb_fname_cp),
5044 nt_errstr(status)));
5046 TALLOC_FREE(smb_fname_cp);
5047 break;
5049 TALLOC_FREE(smb_fname_cp);
5053 * don't touch the variable "status" beyond this point :-)
5056 for (j = i-1 ; j >= 0; j--) {
5057 if (streams[j] == NULL) {
5058 continue;
5061 DEBUG(10, ("Closing stream # %d, %s\n", j,
5062 fsp_str_dbg(streams[j])));
5063 close_file_free(NULL, &streams[j], NORMAL_CLOSE);
5066 fail:
5067 TALLOC_FREE(frame);
5068 return status;
5071 /*********************************************************************
5072 Create a default ACL by inheriting from the parent. If no inheritance
5073 from the parent available, don't set anything. This will leave the actual
5074 permissions the new file or directory already got from the filesystem
5075 as the NT ACL when read.
5076 *********************************************************************/
5078 static NTSTATUS inherit_new_acl(files_struct *dirfsp, files_struct *fsp)
5080 TALLOC_CTX *frame = talloc_stackframe();
5081 struct security_descriptor *parent_desc = NULL;
5082 NTSTATUS status = NT_STATUS_OK;
5083 struct security_descriptor *psd = NULL;
5084 const struct dom_sid *owner_sid = NULL;
5085 const struct dom_sid *group_sid = NULL;
5086 uint32_t security_info_sent = (SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL);
5087 struct security_token *token = fsp->conn->session_info->security_token;
5088 bool inherit_owner =
5089 (lp_inherit_owner(SNUM(fsp->conn)) == INHERIT_OWNER_WINDOWS_AND_UNIX);
5090 bool inheritable_components = false;
5091 bool try_builtin_administrators = false;
5092 const struct dom_sid *BA_U_sid = NULL;
5093 const struct dom_sid *BA_G_sid = NULL;
5094 bool try_system = false;
5095 const struct dom_sid *SY_U_sid = NULL;
5096 const struct dom_sid *SY_G_sid = NULL;
5097 size_t size = 0;
5098 bool ok;
5100 status = SMB_VFS_FGET_NT_ACL(dirfsp,
5101 (SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL),
5102 frame,
5103 &parent_desc);
5104 if (!NT_STATUS_IS_OK(status)) {
5105 TALLOC_FREE(frame);
5106 return status;
5109 inheritable_components = sd_has_inheritable_components(parent_desc,
5110 fsp->fsp_flags.is_directory);
5112 if (!inheritable_components && !inherit_owner) {
5113 TALLOC_FREE(frame);
5114 /* Nothing to inherit and not setting owner. */
5115 return NT_STATUS_OK;
5118 /* Create an inherited descriptor from the parent. */
5120 if (DEBUGLEVEL >= 10) {
5121 DEBUG(10,("inherit_new_acl: parent acl for %s is:\n",
5122 fsp_str_dbg(fsp) ));
5123 NDR_PRINT_DEBUG(security_descriptor, parent_desc);
5126 /* Inherit from parent descriptor if "inherit owner" set. */
5127 if (inherit_owner) {
5128 owner_sid = parent_desc->owner_sid;
5129 group_sid = parent_desc->group_sid;
5132 if (owner_sid == NULL) {
5133 if (security_token_has_builtin_administrators(token)) {
5134 try_builtin_administrators = true;
5135 } else if (security_token_is_system(token)) {
5136 try_builtin_administrators = true;
5137 try_system = true;
5141 if (group_sid == NULL &&
5142 token->num_sids == PRIMARY_GROUP_SID_INDEX)
5144 if (security_token_is_system(token)) {
5145 try_builtin_administrators = true;
5146 try_system = true;
5150 if (try_builtin_administrators) {
5151 struct unixid ids = { .id = 0 };
5153 ok = sids_to_unixids(&global_sid_Builtin_Administrators, 1, &ids);
5154 if (ok) {
5155 switch (ids.type) {
5156 case ID_TYPE_BOTH:
5157 BA_U_sid = &global_sid_Builtin_Administrators;
5158 BA_G_sid = &global_sid_Builtin_Administrators;
5159 break;
5160 case ID_TYPE_UID:
5161 BA_U_sid = &global_sid_Builtin_Administrators;
5162 break;
5163 case ID_TYPE_GID:
5164 BA_G_sid = &global_sid_Builtin_Administrators;
5165 break;
5166 default:
5167 break;
5172 if (try_system) {
5173 struct unixid ids = { .id = 0 };
5175 ok = sids_to_unixids(&global_sid_System, 1, &ids);
5176 if (ok) {
5177 switch (ids.type) {
5178 case ID_TYPE_BOTH:
5179 SY_U_sid = &global_sid_System;
5180 SY_G_sid = &global_sid_System;
5181 break;
5182 case ID_TYPE_UID:
5183 SY_U_sid = &global_sid_System;
5184 break;
5185 case ID_TYPE_GID:
5186 SY_G_sid = &global_sid_System;
5187 break;
5188 default:
5189 break;
5194 if (owner_sid == NULL) {
5195 owner_sid = BA_U_sid;
5198 if (owner_sid == NULL) {
5199 owner_sid = SY_U_sid;
5202 if (group_sid == NULL) {
5203 group_sid = SY_G_sid;
5206 if (try_system && group_sid == NULL) {
5207 group_sid = BA_G_sid;
5210 if (owner_sid == NULL) {
5211 owner_sid = &token->sids[PRIMARY_USER_SID_INDEX];
5213 if (group_sid == NULL) {
5214 if (token->num_sids == PRIMARY_GROUP_SID_INDEX) {
5215 group_sid = &token->sids[PRIMARY_USER_SID_INDEX];
5216 } else {
5217 group_sid = &token->sids[PRIMARY_GROUP_SID_INDEX];
5221 status = se_create_child_secdesc(frame,
5222 &psd,
5223 &size,
5224 parent_desc,
5225 owner_sid,
5226 group_sid,
5227 fsp->fsp_flags.is_directory);
5228 if (!NT_STATUS_IS_OK(status)) {
5229 TALLOC_FREE(frame);
5230 return status;
5233 /* If inheritable_components == false,
5234 se_create_child_secdesc()
5235 creates a security descriptor with a NULL dacl
5236 entry, but with SEC_DESC_DACL_PRESENT. We need
5237 to remove that flag. */
5239 if (!inheritable_components) {
5240 security_info_sent &= ~SECINFO_DACL;
5241 psd->type &= ~SEC_DESC_DACL_PRESENT;
5244 if (DEBUGLEVEL >= 10) {
5245 DEBUG(10,("inherit_new_acl: child acl for %s is:\n",
5246 fsp_str_dbg(fsp) ));
5247 NDR_PRINT_DEBUG(security_descriptor, psd);
5250 if (inherit_owner) {
5251 /* We need to be root to force this. */
5252 become_root();
5254 status = SMB_VFS_FSET_NT_ACL(fsp,
5255 security_info_sent,
5256 psd);
5257 if (inherit_owner) {
5258 unbecome_root();
5260 TALLOC_FREE(frame);
5261 return status;
5265 * If we already have a lease, it must match the new file id. [MS-SMB2]
5266 * 3.3.5.9.8 speaks about INVALID_PARAMETER if an already used lease key is
5267 * used for a different file name.
5270 struct lease_match_state {
5271 /* Input parameters. */
5272 TALLOC_CTX *mem_ctx;
5273 const char *servicepath;
5274 const struct smb_filename *fname;
5275 bool file_existed;
5276 struct file_id id;
5277 /* Return parameters. */
5278 uint32_t num_file_ids;
5279 struct file_id *ids;
5280 NTSTATUS match_status;
5283 /*************************************************************
5284 File doesn't exist but this lease key+guid is already in use.
5286 This is only allowable in the dynamic share case where the
5287 service path must be different.
5289 There is a small race condition here in the multi-connection
5290 case where a client sends two create calls on different connections,
5291 where the file doesn't exist and one smbd creates the leases_db
5292 entry first, but this will get fixed by the multichannel cleanup
5293 when all identical client_guids get handled by a single smbd.
5294 **************************************************************/
5296 static void lease_match_parser_new_file(
5297 uint32_t num_files,
5298 const struct leases_db_file *files,
5299 struct lease_match_state *state)
5301 uint32_t i;
5303 for (i = 0; i < num_files; i++) {
5304 const struct leases_db_file *f = &files[i];
5305 if (strequal(state->servicepath, f->servicepath)) {
5306 state->match_status = NT_STATUS_INVALID_PARAMETER;
5307 return;
5311 /* Dynamic share case. Break leases on all other files. */
5312 state->match_status = leases_db_copy_file_ids(state->mem_ctx,
5313 num_files,
5314 files,
5315 &state->ids);
5316 if (!NT_STATUS_IS_OK(state->match_status)) {
5317 return;
5320 state->num_file_ids = num_files;
5321 state->match_status = NT_STATUS_OPLOCK_NOT_GRANTED;
5322 return;
5325 static void lease_match_parser(
5326 uint32_t num_files,
5327 const struct leases_db_file *files,
5328 void *private_data)
5330 struct lease_match_state *state =
5331 (struct lease_match_state *)private_data;
5332 uint32_t i;
5334 if (!state->file_existed) {
5336 * Deal with name mismatch or
5337 * possible dynamic share case separately
5338 * to make code clearer.
5340 lease_match_parser_new_file(num_files,
5341 files,
5342 state);
5343 return;
5346 /* File existed. */
5347 state->match_status = NT_STATUS_OK;
5349 for (i = 0; i < num_files; i++) {
5350 const struct leases_db_file *f = &files[i];
5352 /* Everything should be the same. */
5353 if (!file_id_equal(&state->id, &f->id)) {
5355 * The client asked for a lease on a
5356 * file that doesn't match the file_id
5357 * in the database.
5359 * Maybe this is a dynamic share, i.e.
5360 * a share where the servicepath is
5361 * different for different users (e.g.
5362 * the [HOMES] share.
5364 * If the servicepath is different, but the requested
5365 * file name + stream name is the same then this is
5366 * a dynamic share, the client is using the same share
5367 * name and doesn't know that the underlying servicepath
5368 * is different. It was expecting a lease on the
5369 * same file. Return NT_STATUS_OPLOCK_NOT_GRANTED
5370 * to break leases
5372 * Otherwise the client has messed up, or is
5373 * testing our error codes, so return
5374 * NT_STATUS_INVALID_PARAMETER.
5376 if (!strequal(f->servicepath, state->servicepath) &&
5377 strequal(f->base_name, state->fname->base_name) &&
5378 strequal(f->stream_name, state->fname->stream_name))
5381 * Name is the same but servicepath is
5382 * different, dynamic share. Break leases.
5384 state->match_status =
5385 NT_STATUS_OPLOCK_NOT_GRANTED;
5386 } else {
5387 state->match_status =
5388 NT_STATUS_INVALID_PARAMETER;
5390 break;
5392 if (!strequal(f->servicepath, state->servicepath)) {
5393 state->match_status = NT_STATUS_INVALID_PARAMETER;
5394 break;
5396 if (!strequal(f->base_name, state->fname->base_name)) {
5397 state->match_status = NT_STATUS_INVALID_PARAMETER;
5398 break;
5400 if (!strequal(f->stream_name, state->fname->stream_name)) {
5401 state->match_status = NT_STATUS_INVALID_PARAMETER;
5402 break;
5406 if (NT_STATUS_IS_OK(state->match_status)) {
5408 * Common case - just opening another handle on a
5409 * file on a non-dynamic share.
5411 return;
5414 if (NT_STATUS_EQUAL(state->match_status, NT_STATUS_INVALID_PARAMETER)) {
5415 /* Mismatched path. Error back to client. */
5416 return;
5420 * File id mismatch. Dynamic share case NT_STATUS_OPLOCK_NOT_GRANTED.
5421 * Don't allow leases.
5424 state->match_status = leases_db_copy_file_ids(state->mem_ctx,
5425 num_files,
5426 files,
5427 &state->ids);
5428 if (!NT_STATUS_IS_OK(state->match_status)) {
5429 return;
5432 state->num_file_ids = num_files;
5433 state->match_status = NT_STATUS_OPLOCK_NOT_GRANTED;
5434 return;
5437 struct lease_match_break_state {
5438 struct messaging_context *msg_ctx;
5439 const struct smb2_lease_key *lease_key;
5440 struct file_id id;
5442 bool found_lease;
5443 uint16_t version;
5444 uint16_t epoch;
5447 static bool lease_match_break_fn(
5448 struct share_mode_entry *e,
5449 void *private_data)
5451 struct lease_match_break_state *state = private_data;
5452 bool stale, equal;
5453 uint32_t e_lease_type;
5454 NTSTATUS status;
5456 stale = share_entry_stale_pid(e);
5457 if (stale) {
5458 return false;
5461 equal = smb2_lease_key_equal(&e->lease_key, state->lease_key);
5462 if (!equal) {
5463 return false;
5466 status = leases_db_get(
5467 &e->client_guid,
5468 &e->lease_key,
5469 &state->id,
5470 NULL, /* current_state */
5471 NULL, /* breaking */
5472 NULL, /* breaking_to_requested */
5473 NULL, /* breaking_to_required */
5474 &state->version, /* lease_version */
5475 &state->epoch); /* epoch */
5476 if (NT_STATUS_IS_OK(status)) {
5477 state->found_lease = true;
5478 } else {
5479 DBG_WARNING("Could not find version/epoch: %s\n",
5480 nt_errstr(status));
5483 e_lease_type = get_lease_type(e, state->id);
5484 if (e_lease_type == SMB2_LEASE_NONE) {
5485 return false;
5487 send_break_message(state->msg_ctx, &state->id, e, SMB2_LEASE_NONE);
5490 * Windows 7 and 8 lease clients are broken in that they will
5491 * not respond to lease break requests whilst waiting for an
5492 * outstanding open request on that lease handle on the same
5493 * TCP connection, due to holding an internal inode lock.
5495 * This means we can't reschedule ourselves here, but must
5496 * return from the create.
5498 * Work around:
5500 * Send the breaks and then return SMB2_LEASE_NONE in the
5501 * lease handle to cause them to acknowledge the lease
5502 * break. Consultation with Microsoft engineering confirmed
5503 * this approach is safe.
5506 return false;
5509 static NTSTATUS lease_match(connection_struct *conn,
5510 struct smb_request *req,
5511 const struct smb2_lease_key *lease_key,
5512 const char *servicepath,
5513 const struct smb_filename *fname,
5514 uint16_t *p_version,
5515 uint16_t *p_epoch)
5517 struct smbd_server_connection *sconn = req->sconn;
5518 TALLOC_CTX *tos = talloc_tos();
5519 struct lease_match_state state = {
5520 .mem_ctx = tos,
5521 .servicepath = servicepath,
5522 .fname = fname,
5523 .match_status = NT_STATUS_OK
5525 uint32_t i;
5526 NTSTATUS status;
5528 state.file_existed = VALID_STAT(fname->st);
5529 if (state.file_existed) {
5530 state.id = vfs_file_id_from_sbuf(conn, &fname->st);
5533 status = leases_db_parse(&sconn->client->global->client_guid,
5534 lease_key, lease_match_parser, &state);
5535 if (!NT_STATUS_IS_OK(status)) {
5537 * Not found or error means okay: We can make the lease pass
5539 return NT_STATUS_OK;
5541 if (!NT_STATUS_EQUAL(state.match_status, NT_STATUS_OPLOCK_NOT_GRANTED)) {
5543 * Anything but NT_STATUS_OPLOCK_NOT_GRANTED, let the caller
5544 * deal with it.
5546 return state.match_status;
5549 /* We have to break all existing leases. */
5550 for (i = 0; i < state.num_file_ids; i++) {
5551 struct lease_match_break_state break_state = {
5552 .msg_ctx = conn->sconn->msg_ctx,
5553 .lease_key = lease_key,
5555 struct share_mode_lock *lck;
5556 bool ok;
5558 if (file_id_equal(&state.ids[i], &state.id)) {
5559 /* Don't need to break our own file. */
5560 continue;
5563 break_state.id = state.ids[i];
5565 lck = get_existing_share_mode_lock(
5566 talloc_tos(), break_state.id);
5567 if (lck == NULL) {
5568 /* Race condition - file already closed. */
5569 continue;
5572 ok = share_mode_forall_leases(
5573 lck, lease_match_break_fn, &break_state);
5574 if (!ok) {
5575 DBG_DEBUG("share_mode_forall_leases failed\n");
5576 continue;
5579 TALLOC_FREE(lck);
5581 if (break_state.found_lease) {
5582 *p_version = break_state.version;
5583 *p_epoch = break_state.epoch;
5587 * Ensure we don't grant anything more so we
5588 * never upgrade.
5590 return NT_STATUS_OPLOCK_NOT_GRANTED;
5594 * Wrapper around open_file_ntcreate and open_directory
5597 static NTSTATUS create_file_unixpath(connection_struct *conn,
5598 struct smb_request *req,
5599 struct smb_filename *smb_fname,
5600 uint32_t access_mask,
5601 uint32_t share_access,
5602 uint32_t create_disposition,
5603 uint32_t create_options,
5604 uint32_t file_attributes,
5605 uint32_t oplock_request,
5606 const struct smb2_lease *lease,
5607 uint64_t allocation_size,
5608 uint32_t private_flags,
5609 struct security_descriptor *sd,
5610 struct ea_list *ea_list,
5612 files_struct **result,
5613 int *pinfo)
5615 struct smb2_lease none_lease;
5616 int info = FILE_WAS_OPENED;
5617 files_struct *base_fsp = NULL;
5618 files_struct *fsp = NULL;
5619 bool free_fsp_on_error = false;
5620 NTSTATUS status;
5621 int ret;
5622 struct smb_filename *parent_dir_fname = NULL;
5623 struct smb_filename *smb_fname_atname = NULL;
5625 DBG_DEBUG("access_mask = 0x%"PRIx32" "
5626 "file_attributes = 0x%"PRIx32" "
5627 "share_access = 0x%"PRIx32" "
5628 "create_disposition = 0x%"PRIx32" "
5629 "create_options = 0x%"PRIx32" "
5630 "oplock_request = 0x%"PRIx32" "
5631 "private_flags = 0x%"PRIx32" "
5632 "ea_list = %p, "
5633 "sd = %p, "
5634 "fname = %s\n",
5635 access_mask,
5636 file_attributes,
5637 share_access,
5638 create_disposition,
5639 create_options,
5640 oplock_request,
5641 private_flags,
5642 ea_list,
5644 smb_fname_str_dbg(smb_fname));
5646 if (create_options & FILE_OPEN_BY_FILE_ID) {
5647 status = NT_STATUS_NOT_SUPPORTED;
5648 goto fail;
5651 if (create_options & NTCREATEX_OPTIONS_INVALID_PARAM_MASK) {
5652 status = NT_STATUS_INVALID_PARAMETER;
5653 goto fail;
5656 if (req == NULL) {
5657 oplock_request |= INTERNAL_OPEN_ONLY;
5660 if (lease != NULL) {
5661 uint16_t epoch = lease->lease_epoch;
5662 uint16_t version = lease->lease_version;
5664 if (req == NULL) {
5665 DBG_WARNING("Got lease on internal open\n");
5666 status = NT_STATUS_INTERNAL_ERROR;
5667 goto fail;
5670 status = lease_match(conn,
5671 req,
5672 &lease->lease_key,
5673 conn->connectpath,
5674 smb_fname,
5675 &version,
5676 &epoch);
5677 if (NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) {
5678 /* Dynamic share file. No leases and update epoch... */
5679 none_lease = *lease;
5680 none_lease.lease_state = SMB2_LEASE_NONE;
5681 none_lease.lease_epoch = epoch;
5682 none_lease.lease_version = version;
5683 lease = &none_lease;
5684 } else if (!NT_STATUS_IS_OK(status)) {
5685 goto fail;
5689 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
5690 && (access_mask & DELETE_ACCESS)
5691 && !is_ntfs_stream_smb_fname(smb_fname)) {
5693 * We can't open a file with DELETE access if any of the
5694 * streams is open without FILE_SHARE_DELETE
5696 status = open_streams_for_delete(conn, smb_fname);
5698 if (!NT_STATUS_IS_OK(status)) {
5699 goto fail;
5703 if (access_mask & SEC_FLAG_SYSTEM_SECURITY) {
5704 bool ok;
5706 ok = security_token_has_privilege(get_current_nttok(conn),
5707 SEC_PRIV_SECURITY);
5708 if (!ok) {
5709 DBG_DEBUG("open on %s failed - "
5710 "SEC_FLAG_SYSTEM_SECURITY denied.\n",
5711 smb_fname_str_dbg(smb_fname));
5712 status = NT_STATUS_PRIVILEGE_NOT_HELD;
5713 goto fail;
5716 if (conn->sconn->using_smb2 &&
5717 (access_mask == SEC_FLAG_SYSTEM_SECURITY))
5720 * No other bits set. Windows SMB2 refuses this.
5721 * See smbtorture3 SMB2-SACL test.
5723 * Note this is an SMB2-only behavior,
5724 * smbtorture3 SMB1-SYSTEM-SECURITY already tests
5725 * that SMB1 allows this.
5727 status = NT_STATUS_ACCESS_DENIED;
5728 goto fail;
5733 * Files or directories can't be opened DELETE_ON_CLOSE without
5734 * delete access.
5735 * BUG: https://bugzilla.samba.org/show_bug.cgi?id=13358
5737 if (create_options & FILE_DELETE_ON_CLOSE) {
5738 if ((access_mask & DELETE_ACCESS) == 0) {
5739 status = NT_STATUS_INVALID_PARAMETER;
5740 goto fail;
5744 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
5745 && is_named_stream(smb_fname))
5747 uint32_t base_create_disposition;
5748 struct smb_filename *smb_fname_base = NULL;
5749 uint32_t base_privflags;
5751 if (create_options & FILE_DIRECTORY_FILE) {
5752 status = NT_STATUS_NOT_A_DIRECTORY;
5753 goto fail;
5756 switch (create_disposition) {
5757 case FILE_OPEN:
5758 base_create_disposition = FILE_OPEN;
5759 break;
5760 default:
5761 base_create_disposition = FILE_OPEN_IF;
5762 break;
5765 smb_fname_base = cp_smb_filename_nostream(
5766 talloc_tos(), smb_fname);
5768 if (smb_fname_base == NULL) {
5769 status = NT_STATUS_NO_MEMORY;
5770 goto fail;
5774 * We may be creating the basefile as part of creating the
5775 * stream, so it's legal if the basefile doesn't exist at this
5776 * point, the create_file_unixpath() below will create it. But
5777 * if the basefile exists we want a handle so we can fstat() it.
5780 ret = vfs_stat(conn, smb_fname_base);
5781 if (ret == -1 && errno != ENOENT) {
5782 status = map_nt_error_from_unix(errno);
5783 TALLOC_FREE(smb_fname_base);
5784 goto fail;
5786 if (ret == 0) {
5787 status = openat_pathref_fsp(conn->cwd_fsp,
5788 smb_fname_base);
5789 if (!NT_STATUS_IS_OK(status)) {
5790 DBG_ERR("open_smb_fname_fsp [%s] failed: %s\n",
5791 smb_fname_str_dbg(smb_fname_base),
5792 nt_errstr(status));
5793 TALLOC_FREE(smb_fname_base);
5794 goto fail;
5798 * https://bugzilla.samba.org/show_bug.cgi?id=10229
5799 * We need to check if the requested access mask
5800 * could be used to open the underlying file (if
5801 * it existed), as we're passing in zero for the
5802 * access mask to the base filename.
5804 status = check_base_file_access(smb_fname_base->fsp,
5805 access_mask);
5807 if (!NT_STATUS_IS_OK(status)) {
5808 DEBUG(10, ("Permission check "
5809 "for base %s failed: "
5810 "%s\n", smb_fname->base_name,
5811 nt_errstr(status)));
5812 TALLOC_FREE(smb_fname_base);
5813 goto fail;
5817 base_privflags = NTCREATEX_FLAG_STREAM_BASEOPEN;
5819 /* Open the base file. */
5820 status = create_file_unixpath(conn,
5821 NULL,
5822 smb_fname_base,
5824 FILE_SHARE_READ
5825 | FILE_SHARE_WRITE
5826 | FILE_SHARE_DELETE,
5827 base_create_disposition,
5831 NULL,
5833 base_privflags,
5834 NULL,
5835 NULL,
5836 &base_fsp,
5837 NULL);
5838 TALLOC_FREE(smb_fname_base);
5840 if (!NT_STATUS_IS_OK(status)) {
5841 DEBUG(10, ("create_file_unixpath for base %s failed: "
5842 "%s\n", smb_fname->base_name,
5843 nt_errstr(status)));
5844 goto fail;
5848 if (smb_fname->fsp != NULL) {
5850 fsp = smb_fname->fsp;
5853 * We're about to use smb_fname->fsp for the fresh open.
5855 * Every fsp passed in via smb_fname->fsp already
5856 * holds a fsp->fsp_name. If it is already this
5857 * fsp->fsp_name that we got passed in as our input
5858 * argument smb_fname, these two are assumed to have
5859 * the same lifetime: Every fsp hangs of "conn", and
5860 * fsp->fsp_name is its talloc child.
5863 if (smb_fname != smb_fname->fsp->fsp_name) {
5865 * "smb_fname" is temporary in this case, but
5866 * the destructor of smb_fname would also tear
5867 * down the fsp we're about to use. Unlink
5868 * them from each other.
5870 smb_fname_fsp_unlink(smb_fname);
5873 * "fsp" is ours now
5875 free_fsp_on_error = true;
5878 status = fsp_bind_smb(fsp, req);
5879 if (!NT_STATUS_IS_OK(status)) {
5880 goto fail;
5883 if (fsp_is_alternate_stream(fsp)) {
5884 struct files_struct *tmp_base_fsp = fsp->base_fsp;
5886 fsp_set_base_fsp(fsp, NULL);
5888 fd_close(tmp_base_fsp);
5889 file_free(NULL, tmp_base_fsp);
5891 } else {
5893 * No fsp passed in that we can use, create one
5895 status = file_new(req, conn, &fsp);
5896 if(!NT_STATUS_IS_OK(status)) {
5897 goto fail;
5899 free_fsp_on_error = true;
5901 status = fsp_set_smb_fname(fsp, smb_fname);
5902 if (!NT_STATUS_IS_OK(status)) {
5903 goto fail;
5907 SMB_ASSERT(fsp->fsp_name->fsp != NULL);
5908 SMB_ASSERT(fsp->fsp_name->fsp == fsp);
5910 if (base_fsp) {
5912 * We're opening the stream element of a
5913 * base_fsp we already opened. Set up the
5914 * base_fsp pointer.
5916 fsp_set_base_fsp(fsp, base_fsp);
5920 * Get a pathref on the parent. We can re-use this
5921 * for multiple calls to check parent ACLs etc. to
5922 * avoid pathname calls.
5924 status = parent_pathref(talloc_tos(),
5925 conn->cwd_fsp,
5926 smb_fname,
5927 &parent_dir_fname,
5928 &smb_fname_atname);
5929 if (!NT_STATUS_IS_OK(status)) {
5930 goto fail;
5934 * If it's a request for a directory open, deal with it separately.
5937 if (create_options & FILE_DIRECTORY_FILE) {
5939 if (create_options & FILE_NON_DIRECTORY_FILE) {
5940 status = NT_STATUS_INVALID_PARAMETER;
5941 goto fail;
5944 /* Can't open a temp directory. IFS kit test. */
5945 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
5946 (file_attributes & FILE_ATTRIBUTE_TEMPORARY)) {
5947 status = NT_STATUS_INVALID_PARAMETER;
5948 goto fail;
5952 * We will get a create directory here if the Win32
5953 * app specified a security descriptor in the
5954 * CreateDirectory() call.
5957 oplock_request = 0;
5958 status = open_directory(conn,
5959 req,
5960 access_mask,
5961 share_access,
5962 create_disposition,
5963 create_options,
5964 file_attributes,
5965 parent_dir_fname,
5966 smb_fname_atname,
5967 &info,
5968 fsp);
5969 } else {
5972 * Ordinary file case.
5975 if (allocation_size) {
5976 fsp->initial_allocation_size = smb_roundup(fsp->conn,
5977 allocation_size);
5980 status = open_file_ntcreate(conn,
5981 req,
5982 access_mask,
5983 share_access,
5984 create_disposition,
5985 create_options,
5986 file_attributes,
5987 oplock_request,
5988 lease,
5989 private_flags,
5990 parent_dir_fname,
5991 smb_fname_atname,
5992 &info,
5993 fsp);
5994 if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
5996 /* A stream open never opens a directory */
5998 if (base_fsp) {
5999 status = NT_STATUS_FILE_IS_A_DIRECTORY;
6000 goto fail;
6004 * Fail the open if it was explicitly a non-directory
6005 * file.
6008 if (create_options & FILE_NON_DIRECTORY_FILE) {
6009 status = NT_STATUS_FILE_IS_A_DIRECTORY;
6010 goto fail;
6013 oplock_request = 0;
6014 status = open_directory(conn,
6015 req,
6016 access_mask,
6017 share_access,
6018 create_disposition,
6019 create_options,
6020 file_attributes,
6021 parent_dir_fname,
6022 smb_fname_atname,
6023 &info,
6024 fsp);
6028 if (!NT_STATUS_IS_OK(status)) {
6029 goto fail;
6032 fsp->fsp_flags.is_fsa = true;
6034 if ((ea_list != NULL) &&
6035 ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN))) {
6036 status = set_ea(conn, fsp, ea_list);
6037 if (!NT_STATUS_IS_OK(status)) {
6038 goto fail;
6042 if (!fsp->fsp_flags.is_directory &&
6043 S_ISDIR(fsp->fsp_name->st.st_ex_mode))
6045 status = NT_STATUS_ACCESS_DENIED;
6046 goto fail;
6049 /* Save the requested allocation size. */
6050 if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
6051 if ((allocation_size > (uint64_t)fsp->fsp_name->st.st_ex_size)
6052 && !(fsp->fsp_flags.is_directory))
6054 fsp->initial_allocation_size = smb_roundup(
6055 fsp->conn, allocation_size);
6056 if (vfs_allocate_file_space(
6057 fsp, fsp->initial_allocation_size) == -1) {
6058 status = NT_STATUS_DISK_FULL;
6059 goto fail;
6061 } else {
6062 fsp->initial_allocation_size = smb_roundup(
6063 fsp->conn, (uint64_t)fsp->fsp_name->st.st_ex_size);
6065 } else {
6066 fsp->initial_allocation_size = 0;
6069 if ((info == FILE_WAS_CREATED) &&
6070 lp_nt_acl_support(SNUM(conn)) &&
6071 !fsp_is_alternate_stream(fsp)) {
6072 if (sd != NULL) {
6074 * According to the MS documentation, the only time the security
6075 * descriptor is applied to the opened file is iff we *created* the
6076 * file; an existing file stays the same.
6078 * Also, it seems (from observation) that you can open the file with
6079 * any access mask but you can still write the sd. We need to override
6080 * the granted access before we call set_sd
6081 * Patch for bug #2242 from Tom Lackemann <cessnatomny@yahoo.com>.
6084 uint32_t sec_info_sent;
6085 uint32_t saved_access_mask = fsp->access_mask;
6087 sec_info_sent = get_sec_info(sd);
6089 fsp->access_mask = FILE_GENERIC_ALL;
6091 if (sec_info_sent & (SECINFO_OWNER|
6092 SECINFO_GROUP|
6093 SECINFO_DACL|
6094 SECINFO_SACL)) {
6095 status = set_sd(fsp, sd, sec_info_sent);
6098 fsp->access_mask = saved_access_mask;
6100 if (!NT_STATUS_IS_OK(status)) {
6101 goto fail;
6103 } else if (lp_inherit_acls(SNUM(conn))) {
6104 /* Inherit from parent. Errors here are not fatal. */
6105 status = inherit_new_acl(
6106 parent_dir_fname->fsp, fsp);
6107 if (!NT_STATUS_IS_OK(status)) {
6108 DEBUG(10,("inherit_new_acl: failed for %s with %s\n",
6109 fsp_str_dbg(fsp),
6110 nt_errstr(status) ));
6115 if ((conn->fs_capabilities & FILE_FILE_COMPRESSION)
6116 && (create_options & FILE_NO_COMPRESSION)
6117 && (info == FILE_WAS_CREATED)) {
6118 status = SMB_VFS_SET_COMPRESSION(conn, fsp, fsp,
6119 COMPRESSION_FORMAT_NONE);
6120 if (!NT_STATUS_IS_OK(status)) {
6121 DEBUG(1, ("failed to disable compression: %s\n",
6122 nt_errstr(status)));
6126 DEBUG(10, ("create_file_unixpath: info=%d\n", info));
6128 *result = fsp;
6129 if (pinfo != NULL) {
6130 *pinfo = info;
6133 smb_fname->st = fsp->fsp_name->st;
6135 TALLOC_FREE(parent_dir_fname);
6137 return NT_STATUS_OK;
6139 fail:
6140 DEBUG(10, ("create_file_unixpath: %s\n", nt_errstr(status)));
6142 if (fsp != NULL) {
6144 * The close_file below will close
6145 * fsp->base_fsp.
6147 base_fsp = NULL;
6148 close_file_smb(req, fsp, ERROR_CLOSE);
6149 if (free_fsp_on_error) {
6150 file_free(req, fsp);
6151 fsp = NULL;
6154 if (base_fsp != NULL) {
6155 close_file_free(req, &base_fsp, ERROR_CLOSE);
6158 TALLOC_FREE(parent_dir_fname);
6160 return status;
6163 NTSTATUS create_file_default(connection_struct *conn,
6164 struct smb_request *req,
6165 struct smb_filename *smb_fname,
6166 uint32_t access_mask,
6167 uint32_t share_access,
6168 uint32_t create_disposition,
6169 uint32_t create_options,
6170 uint32_t file_attributes,
6171 uint32_t oplock_request,
6172 const struct smb2_lease *lease,
6173 uint64_t allocation_size,
6174 uint32_t private_flags,
6175 struct security_descriptor *sd,
6176 struct ea_list *ea_list,
6177 files_struct **result,
6178 int *pinfo,
6179 const struct smb2_create_blobs *in_context_blobs,
6180 struct smb2_create_blobs *out_context_blobs)
6182 int info = FILE_WAS_OPENED;
6183 files_struct *fsp = NULL;
6184 NTSTATUS status;
6185 bool stream_name = false;
6186 struct smb2_create_blob *posx = NULL;
6188 DBG_DEBUG("create_file: access_mask = 0x%x "
6189 "file_attributes = 0x%x, share_access = 0x%x, "
6190 "create_disposition = 0x%x create_options = 0x%x "
6191 "oplock_request = 0x%x "
6192 "private_flags = 0x%x "
6193 "ea_list = %p, sd = %p, "
6194 "fname = %s\n",
6195 (unsigned int)access_mask,
6196 (unsigned int)file_attributes,
6197 (unsigned int)share_access,
6198 (unsigned int)create_disposition,
6199 (unsigned int)create_options,
6200 (unsigned int)oplock_request,
6201 (unsigned int)private_flags,
6202 ea_list,
6204 smb_fname_str_dbg(smb_fname));
6206 if (req != NULL) {
6208 * Remember the absolute time of the original request
6209 * with this mid. We'll use it later to see if this
6210 * has timed out.
6212 get_deferred_open_message_state(req, &req->request_time, NULL);
6216 * Check to see if this is a mac fork of some kind.
6219 stream_name = is_ntfs_stream_smb_fname(smb_fname);
6220 if (stream_name) {
6221 enum FAKE_FILE_TYPE fake_file_type;
6223 fake_file_type = is_fake_file(smb_fname);
6225 if (req != NULL && fake_file_type != FAKE_FILE_TYPE_NONE) {
6228 * Here we go! support for changing the disk quotas
6229 * --metze
6231 * We need to fake up to open this MAGIC QUOTA file
6232 * and return a valid FID.
6234 * w2k close this file directly after openening xp
6235 * also tries a QUERY_FILE_INFO on the file and then
6236 * close it
6238 status = open_fake_file(req, conn, req->vuid,
6239 fake_file_type, smb_fname,
6240 access_mask, &fsp);
6241 if (!NT_STATUS_IS_OK(status)) {
6242 goto fail;
6245 ZERO_STRUCT(smb_fname->st);
6246 goto done;
6249 if (!(conn->fs_capabilities & FILE_NAMED_STREAMS)) {
6250 status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
6251 goto fail;
6255 if (is_ntfs_default_stream_smb_fname(smb_fname)) {
6256 int ret;
6257 smb_fname->stream_name = NULL;
6258 /* We have to handle this error here. */
6259 if (create_options & FILE_DIRECTORY_FILE) {
6260 status = NT_STATUS_NOT_A_DIRECTORY;
6261 goto fail;
6263 ret = vfs_stat(conn, smb_fname);
6264 if (ret == 0 && VALID_STAT_OF_DIR(smb_fname->st)) {
6265 status = NT_STATUS_FILE_IS_A_DIRECTORY;
6266 goto fail;
6270 posx = smb2_create_blob_find(
6271 in_context_blobs, SMB2_CREATE_TAG_POSIX);
6272 if (posx != NULL) {
6273 uint32_t wire_mode_bits = 0;
6274 mode_t mode_bits = 0;
6275 SMB_STRUCT_STAT sbuf = { 0 };
6276 enum perm_type ptype =
6277 (create_options & FILE_DIRECTORY_FILE) ?
6278 PERM_NEW_DIR : PERM_NEW_FILE;
6280 if (posx->data.length != 4) {
6281 status = NT_STATUS_INVALID_PARAMETER;
6282 goto fail;
6285 wire_mode_bits = IVAL(posx->data.data, 0);
6286 status = unix_perms_from_wire(
6287 conn, &sbuf, wire_mode_bits, ptype, &mode_bits);
6288 if (!NT_STATUS_IS_OK(status)) {
6289 goto fail;
6292 * Remove type info from mode, leaving only the
6293 * permissions and setuid/gid bits.
6295 mode_bits &= ~S_IFMT;
6297 file_attributes = (FILE_FLAG_POSIX_SEMANTICS | mode_bits);
6300 status = create_file_unixpath(conn,
6301 req,
6302 smb_fname,
6303 access_mask,
6304 share_access,
6305 create_disposition,
6306 create_options,
6307 file_attributes,
6308 oplock_request,
6309 lease,
6310 allocation_size,
6311 private_flags,
6313 ea_list,
6314 &fsp,
6315 &info);
6316 if (!NT_STATUS_IS_OK(status)) {
6317 goto fail;
6320 done:
6321 DEBUG(10, ("create_file: info=%d\n", info));
6323 *result = fsp;
6324 if (pinfo != NULL) {
6325 *pinfo = info;
6327 return NT_STATUS_OK;
6329 fail:
6330 DEBUG(10, ("create_file: %s\n", nt_errstr(status)));
6332 if (fsp != NULL) {
6333 close_file_free(req, &fsp, ERROR_CLOSE);
6335 return status;