s3: smbd: open_directory(), smbd_check_access_rights() -> smbd_check_access_rights_fsp().
[Samba.git] / source3 / smbd / open.c
blob8978e316fd934c2b72e85bd604dae47ddbe1c13e
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 const struct smb_filename *smb_fname,
80 uint32_t access_mask,
81 uint32_t rejected_mask)
83 if ((access_mask & DELETE_ACCESS) &&
84 (rejected_mask & DELETE_ACCESS) &&
85 can_delete_file_in_directory(conn,
86 conn->cwd_fsp,
87 smb_fname))
89 return true;
91 return false;
94 /****************************************************************************
95 Check if we have open rights.
96 ****************************************************************************/
98 static NTSTATUS smbd_check_access_rights_sd(
99 struct connection_struct *conn,
100 const struct smb_filename *smb_fname,
101 struct security_descriptor *sd,
102 bool use_privs,
103 uint32_t access_mask)
105 uint32_t rejected_share_access;
106 uint32_t rejected_mask = access_mask;
107 uint32_t do_not_check_mask = 0;
108 NTSTATUS status;
110 rejected_share_access = access_mask & ~(conn->share_access);
112 if (rejected_share_access) {
113 DBG_DEBUG("rejected share access 0x%x on %s (0x%x)\n",
114 (unsigned int)access_mask,
115 smb_fname_str_dbg(smb_fname),
116 (unsigned int)rejected_share_access);
117 return NT_STATUS_ACCESS_DENIED;
120 if (!use_privs && get_current_uid(conn) == (uid_t)0) {
121 /* I'm sorry sir, I didn't know you were root... */
122 DBG_DEBUG("root override on %s. Granting 0x%x\n",
123 smb_fname_str_dbg(smb_fname),
124 (unsigned int)access_mask);
125 return NT_STATUS_OK;
128 if ((access_mask & DELETE_ACCESS) &&
129 !lp_acl_check_permissions(SNUM(conn)))
131 DBG_DEBUG("Not checking ACL on DELETE_ACCESS on file %s. "
132 "Granting 0x%x\n",
133 smb_fname_str_dbg(smb_fname),
134 (unsigned int)access_mask);
135 return NT_STATUS_OK;
138 if (access_mask == DELETE_ACCESS &&
139 VALID_STAT(smb_fname->st) &&
140 S_ISLNK(smb_fname->st.st_ex_mode))
142 /* We can always delete a symlink. */
143 DBG_DEBUG("Not checking ACL on DELETE_ACCESS on symlink %s.\n",
144 smb_fname_str_dbg(smb_fname));
145 return NT_STATUS_OK;
148 if (sd == NULL) {
149 goto access_denied;
153 * If we can access the path to this file, by
154 * default we have FILE_READ_ATTRIBUTES from the
155 * containing directory. See the section:
156 * "Algorithm to Check Access to an Existing File"
157 * in MS-FSA.pdf.
159 * se_file_access_check() also takes care of
160 * owner WRITE_DAC and READ_CONTROL.
162 do_not_check_mask = FILE_READ_ATTRIBUTES;
165 * Samba 3.6 and earlier granted execute access even
166 * if the ACL did not contain execute rights.
167 * Samba 4.0 is more correct and checks it.
168 * The compatibilty mode allows one to skip this check
169 * to smoothen upgrades.
171 if (lp_acl_allow_execute_always(SNUM(conn))) {
172 do_not_check_mask |= FILE_EXECUTE;
175 status = se_file_access_check(sd,
176 get_current_nttok(conn),
177 use_privs,
178 (access_mask & ~do_not_check_mask),
179 &rejected_mask);
181 DBG_DEBUG("File [%s] requesting [0x%x] returning [0x%x] (%s)\n",
182 smb_fname_str_dbg(smb_fname),
183 (unsigned int)access_mask,
184 (unsigned int)rejected_mask,
185 nt_errstr(status));
187 if (!NT_STATUS_IS_OK(status)) {
188 if (DEBUGLEVEL >= 10) {
189 DBG_DEBUG("acl for %s is:\n",
190 smb_fname_str_dbg(smb_fname));
191 NDR_PRINT_DEBUG(security_descriptor, sd);
195 TALLOC_FREE(sd);
197 if (NT_STATUS_IS_OK(status) ||
198 !NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED))
200 return status;
203 /* Here we know status == NT_STATUS_ACCESS_DENIED. */
205 access_denied:
207 if ((access_mask & FILE_WRITE_ATTRIBUTES) &&
208 (rejected_mask & FILE_WRITE_ATTRIBUTES) &&
209 !lp_store_dos_attributes(SNUM(conn)) &&
210 (lp_map_readonly(SNUM(conn)) ||
211 lp_map_archive(SNUM(conn)) ||
212 lp_map_hidden(SNUM(conn)) ||
213 lp_map_system(SNUM(conn))))
215 rejected_mask &= ~FILE_WRITE_ATTRIBUTES;
217 DBG_DEBUG("overrode FILE_WRITE_ATTRIBUTES on file %s\n",
218 smb_fname_str_dbg(smb_fname));
221 if (parent_override_delete(conn,
222 smb_fname,
223 access_mask,
224 rejected_mask))
227 * Were we trying to do an open for delete and didn't get DELETE
228 * access. Check if the directory allows DELETE_CHILD.
229 * See here:
230 * http://blogs.msdn.com/oldnewthing/archive/2004/06/04/148426.aspx
231 * for details.
234 rejected_mask &= ~DELETE_ACCESS;
236 DBG_DEBUG("Overrode DELETE_ACCESS on file %s\n",
237 smb_fname_str_dbg(smb_fname));
240 if (rejected_mask != 0) {
241 return NT_STATUS_ACCESS_DENIED;
243 return NT_STATUS_OK;
246 NTSTATUS smbd_check_access_rights(struct connection_struct *conn,
247 struct files_struct *dirfsp,
248 const struct smb_filename *smb_fname,
249 bool use_privs,
250 uint32_t access_mask)
252 /* Check if we have rights to open. */
253 NTSTATUS status;
254 struct security_descriptor *sd = NULL;
256 status = SMB_VFS_GET_NT_ACL_AT(conn,
257 dirfsp,
258 smb_fname,
259 (SECINFO_OWNER |
260 SECINFO_GROUP |
261 SECINFO_DACL),
262 talloc_tos(),
263 &sd);
265 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
266 status = NT_STATUS_OK;
268 if (!NT_STATUS_IS_OK(status)) {
269 DEBUG(10, ("smbd_check_access_rights: Could not get acl "
270 "on %s: %s\n",
271 smb_fname_str_dbg(smb_fname),
272 nt_errstr(status)));
273 return status;
276 return smbd_check_access_rights_sd(conn,
277 smb_fname,
279 use_privs,
280 access_mask);
283 NTSTATUS smbd_check_access_rights_fsp(struct files_struct *fsp,
284 bool use_privs,
285 uint32_t access_mask)
287 struct security_descriptor *sd = NULL;
288 NTSTATUS status;
290 /* Cope with fake/printer fsp's. */
291 if (fsp->fake_file_handle != NULL || fsp->print_file != NULL) {
292 if ((fsp->access_mask & access_mask) != access_mask) {
293 return NT_STATUS_ACCESS_DENIED;
295 return NT_STATUS_OK;
298 if (fsp_get_pathref_fd(fsp) == -1) {
300 * This is a POSIX open on a symlink. For the pathname
301 * verison of this function we used to return the st_mode
302 * bits turned into an NT ACL. For a symlink the mode bits
303 * are always rwxrwxrwx which means the pathname version always
304 * returned NT_STATUS_OK for a symlink. For the handle reference
305 * to a symlink use the handle access bits.
307 if ((fsp->access_mask & access_mask) != access_mask) {
308 return NT_STATUS_ACCESS_DENIED;
310 return NT_STATUS_OK;
313 status = SMB_VFS_FGET_NT_ACL(fsp,
314 (SECINFO_OWNER |
315 SECINFO_GROUP |
316 SECINFO_DACL),
317 talloc_tos(),
318 &sd);
319 if (!NT_STATUS_IS_OK(status)) {
320 DBG_DEBUG("Could not get acl on %s: %s\n",
321 fsp_str_dbg(fsp),
322 nt_errstr(status));
323 return status;
326 return smbd_check_access_rights_sd(fsp->conn,
327 fsp->fsp_name,
329 use_privs,
330 access_mask);
334 * Given an fsp that represents a parent directory,
335 * check if the requested access can be granted.
337 NTSTATUS check_parent_access_fsp(struct files_struct *fsp,
338 uint32_t access_mask)
340 NTSTATUS status;
341 struct security_descriptor *parent_sd = NULL;
342 uint32_t access_granted = 0;
343 struct share_mode_lock *lck = NULL;
344 uint32_t name_hash;
345 bool delete_on_close_set;
346 TALLOC_CTX *frame = talloc_stackframe();
348 if (get_current_uid(fsp->conn) == (uid_t)0) {
349 /* I'm sorry sir, I didn't know you were root... */
350 DBG_DEBUG("root override on %s. Granting 0x%x\n",
351 fsp_str_dbg(fsp),
352 (unsigned int)access_mask);
353 status = NT_STATUS_OK;
354 goto out;
357 status = SMB_VFS_FGET_NT_ACL(fsp,
358 SECINFO_DACL,
359 frame,
360 &parent_sd);
362 if (!NT_STATUS_IS_OK(status)) {
363 DBG_INFO("SMB_VFS_FGET_NT_ACL failed for "
364 "%s with error %s\n",
365 fsp_str_dbg(fsp),
366 nt_errstr(status));
367 goto out;
371 * If we can access the path to this file, by
372 * default we have FILE_READ_ATTRIBUTES from the
373 * containing directory. See the section:
374 * "Algorithm to Check Access to an Existing File"
375 * in MS-FSA.pdf.
377 * se_file_access_check() also takes care of
378 * owner WRITE_DAC and READ_CONTROL.
380 status = se_file_access_check(parent_sd,
381 get_current_nttok(fsp->conn),
382 false,
383 (access_mask & ~FILE_READ_ATTRIBUTES),
384 &access_granted);
385 if(!NT_STATUS_IS_OK(status)) {
386 DBG_INFO("access check "
387 "on directory %s for mask 0x%x returned (0x%x) %s\n",
388 fsp_str_dbg(fsp),
389 access_mask,
390 access_granted,
391 nt_errstr(status));
392 goto out;
395 if (!(access_mask & (SEC_DIR_ADD_FILE | SEC_DIR_ADD_SUBDIR))) {
396 status = NT_STATUS_OK;
397 goto out;
399 if (!lp_check_parent_directory_delete_on_close(SNUM(fsp->conn))) {
400 status = NT_STATUS_OK;
401 goto out;
404 /* Check if the directory has delete-on-close set */
405 status = file_name_hash(fsp->conn,
406 fsp->fsp_name->base_name,
407 &name_hash);
408 if (!NT_STATUS_IS_OK(status)) {
409 goto out;
413 * Don't take a lock here. We just need a snapshot
414 * of the current state of delete on close and this is
415 * called in a codepath where we may already have a lock
416 * (and we explicitly can't hold 2 locks at the same time
417 * as that may deadlock).
419 lck = fetch_share_mode_unlocked(frame, fsp->file_id);
420 if (lck == NULL) {
421 status = NT_STATUS_OK;
422 goto out;
425 delete_on_close_set = is_delete_on_close_set(lck, name_hash);
426 if (delete_on_close_set) {
427 status = NT_STATUS_DELETE_PENDING;
428 goto out;
431 status = NT_STATUS_OK;
433 out:
434 TALLOC_FREE(frame);
435 return status;
438 /****************************************************************************
439 Ensure when opening a base file for a stream open that we have permissions
440 to do so given the access mask on the base file.
441 ****************************************************************************/
443 static NTSTATUS check_base_file_access(struct connection_struct *conn,
444 struct smb_filename *smb_fname,
445 uint32_t access_mask)
447 NTSTATUS status;
449 status = smbd_calculate_access_mask(conn,
450 conn->cwd_fsp,
451 smb_fname,
452 false,
453 access_mask,
454 &access_mask);
455 if (!NT_STATUS_IS_OK(status)) {
456 DEBUG(10, ("smbd_calculate_access_mask "
457 "on file %s returned %s\n",
458 smb_fname_str_dbg(smb_fname),
459 nt_errstr(status)));
460 return status;
463 if (access_mask & (FILE_WRITE_DATA|FILE_APPEND_DATA)) {
464 uint32_t dosattrs;
465 if (!CAN_WRITE(conn)) {
466 return NT_STATUS_ACCESS_DENIED;
468 dosattrs = fdos_mode(smb_fname->fsp);
469 if (IS_DOS_READONLY(dosattrs)) {
470 return NT_STATUS_ACCESS_DENIED;
474 return smbd_check_access_rights_fsp(smb_fname->fsp,
475 false,
476 access_mask);
479 /****************************************************************************
480 Handle differing symlink errno's
481 ****************************************************************************/
483 static NTSTATUS link_errno_convert(int err)
485 #if defined(ENOTSUP) && defined(OSF1)
486 /* handle special Tru64 errno */
487 if (err == ENOTSUP) {
488 err = ELOOP;
490 #endif /* ENOTSUP */
491 #ifdef EFTYPE
492 /* fix broken NetBSD errno */
493 if (err == EFTYPE) {
494 err = ELOOP;
496 #endif /* EFTYPE */
497 /* fix broken FreeBSD errno */
498 if (err == EMLINK) {
499 err = ELOOP;
501 if (err == ELOOP) {
502 return NT_STATUS_STOPPED_ON_SYMLINK;
504 return map_nt_error_from_unix(err);
507 static NTSTATUS non_widelink_open(const struct files_struct *dirfsp,
508 files_struct *fsp,
509 struct smb_filename *smb_fname,
510 int flags,
511 mode_t mode,
512 unsigned int link_depth);
514 /****************************************************************************
515 Follow a symlink in userspace.
516 ****************************************************************************/
518 static NTSTATUS process_symlink_open(const struct files_struct *dirfsp,
519 files_struct *fsp,
520 struct smb_filename *smb_fname,
521 int flags,
522 mode_t mode,
523 unsigned int link_depth)
525 struct connection_struct *conn = dirfsp->conn;
526 const char *conn_rootdir = NULL;
527 struct smb_filename conn_rootdir_fname = { 0 };
528 char *link_target = NULL;
529 int link_len = -1;
530 struct smb_filename *oldwd_fname = NULL;
531 size_t rootdir_len = 0;
532 struct smb_filename *resolved_fname = NULL;
533 char *resolved_name = NULL;
534 bool matched = false;
535 struct smb_filename *full_fname = NULL;
536 NTSTATUS status;
538 conn_rootdir = SMB_VFS_CONNECTPATH(conn, smb_fname);
539 if (conn_rootdir == NULL) {
540 return NT_STATUS_NO_MEMORY;
543 * With shadow_copy2 conn_rootdir can be talloc_freed
544 * whilst we use it in this function. We must take a copy.
546 conn_rootdir_fname.base_name = talloc_strdup(talloc_tos(),
547 conn_rootdir);
548 if (conn_rootdir_fname.base_name == NULL) {
549 return NT_STATUS_NO_MEMORY;
553 * Ensure we don't get stuck in a symlink loop.
555 link_depth++;
556 if (link_depth >= 20) {
557 status = NT_STATUS_STOPPED_ON_SYMLINK;
558 goto out;
561 /* Allocate space for the link target. */
562 link_target = talloc_array(talloc_tos(), char, PATH_MAX);
563 if (link_target == NULL) {
564 status = NT_STATUS_NO_MEMORY;
565 goto out;
569 * Read the link target. We do this just to verify that smb_fname indeed
570 * points at a symbolic link and return NT_STATUS_NOT_A_DIRECTORY
571 * and failure in case smb_fname is NOT a symlink.
573 * The caller needs this piece of information to distinguish two cases
574 * where open() fails with errno=ENOTDIR, cf the comment in
575 * non_widelink_open().
577 * We rely on SMB_VFS_REALPATH() to resolve the path including the
578 * symlink. Once we have SMB_VFS_STATX() or something similar in our VFS
579 * we may want to use that instead of SMB_VFS_READLINKAT().
581 link_len = SMB_VFS_READLINKAT(conn,
582 dirfsp,
583 smb_fname,
584 link_target,
585 PATH_MAX - 1);
586 if (link_len == -1) {
587 status = NT_STATUS_INVALID_PARAMETER;
588 goto out;
591 full_fname = full_path_from_dirfsp_atname(
592 talloc_tos(), dirfsp, smb_fname);
593 if (full_fname == NULL) {
594 status = NT_STATUS_NO_MEMORY;
595 goto out;
598 /* Convert to an absolute path. */
599 resolved_fname = SMB_VFS_REALPATH(conn, talloc_tos(), full_fname);
600 if (resolved_fname == NULL) {
601 status = map_nt_error_from_unix(errno);
602 goto out;
604 resolved_name = resolved_fname->base_name;
607 * We know conn_rootdir starts with '/' and
608 * does not end in '/'. FIXME ! Should we
609 * smb_assert this ?
611 rootdir_len = strlen(conn_rootdir_fname.base_name);
613 matched = (strncmp(conn_rootdir_fname.base_name,
614 resolved_name,
615 rootdir_len) == 0);
616 if (!matched) {
617 status = NT_STATUS_STOPPED_ON_SYMLINK;
618 goto out;
622 * Turn into a path relative to the share root.
624 if (resolved_name[rootdir_len] == '\0') {
625 /* Link to the root of the share. */
626 TALLOC_FREE(smb_fname->base_name);
627 smb_fname->base_name = talloc_strdup(smb_fname, ".");
628 } else if (resolved_name[rootdir_len] == '/') {
629 TALLOC_FREE(smb_fname->base_name);
630 smb_fname->base_name = talloc_strdup(smb_fname,
631 &resolved_name[rootdir_len+1]);
632 } else {
633 status = NT_STATUS_STOPPED_ON_SYMLINK;
634 goto out;
637 if (smb_fname->base_name == NULL) {
638 status = NT_STATUS_NO_MEMORY;
639 goto out;
642 oldwd_fname = vfs_GetWd(talloc_tos(), dirfsp->conn);
643 if (oldwd_fname == NULL) {
644 status = map_nt_error_from_unix(errno);
645 goto out;
648 /* Ensure we operate from the root of the share. */
649 if (vfs_ChDir(conn, &conn_rootdir_fname) == -1) {
650 status = map_nt_error_from_unix(errno);
651 goto out;
655 * And do it all again... As smb_fname is not relative to the passed in
656 * dirfsp anymore, we pass conn->cwd_fsp as dirfsp to
657 * non_widelink_open() to trigger the chdir(parentdir) logic.
659 status = non_widelink_open(conn->cwd_fsp,
660 fsp,
661 smb_fname,
662 flags,
663 mode,
664 link_depth);
666 out:
668 TALLOC_FREE(resolved_fname);
669 TALLOC_FREE(link_target);
670 TALLOC_FREE(conn_rootdir_fname.base_name);
671 if (oldwd_fname != NULL) {
672 int ret = vfs_ChDir(conn, oldwd_fname);
673 if (ret == -1) {
674 smb_panic("unable to get back to old directory\n");
676 TALLOC_FREE(oldwd_fname);
679 return status;
682 /****************************************************************************
683 Non-widelink open.
684 ****************************************************************************/
686 static NTSTATUS non_widelink_open(const struct files_struct *dirfsp,
687 files_struct *fsp,
688 struct smb_filename *smb_fname,
689 int flags,
690 mode_t mode,
691 unsigned int link_depth)
693 struct connection_struct *conn = fsp->conn;
694 NTSTATUS saved_status;
695 NTSTATUS status = NT_STATUS_OK;
696 int fd = -1;
697 struct smb_filename *orig_fsp_name = fsp->fsp_name;
698 struct smb_filename *orig_base_fsp_name = NULL;
699 struct smb_filename *smb_fname_rel = NULL;
700 struct smb_filename base_smb_fname_rel;
701 struct smb_filename *oldwd_fname = NULL;
702 struct smb_filename *parent_dir_fname = NULL;
703 bool have_opath = false;
704 int ret;
706 #ifdef O_PATH
707 have_opath = true;
708 #endif
710 if (dirfsp == conn->cwd_fsp) {
711 if (fsp->fsp_flags.is_directory) {
712 parent_dir_fname = cp_smb_filename(talloc_tos(), smb_fname);
713 if (parent_dir_fname == NULL) {
714 status = NT_STATUS_NO_MEMORY;
715 goto out;
718 smb_fname_rel = synthetic_smb_fname(parent_dir_fname,
719 ".",
720 smb_fname->stream_name,
721 &smb_fname->st,
722 smb_fname->twrp,
723 smb_fname->flags);
724 if (smb_fname_rel == NULL) {
725 status = NT_STATUS_NO_MEMORY;
726 goto out;
728 } else {
729 status = SMB_VFS_PARENT_PATHNAME(fsp->conn,
730 talloc_tos(),
731 smb_fname,
732 &parent_dir_fname,
733 &smb_fname_rel);
734 if (!NT_STATUS_IS_OK(status)) {
735 goto out;
739 oldwd_fname = vfs_GetWd(talloc_tos(), conn);
740 if (oldwd_fname == NULL) {
741 status = map_nt_error_from_unix(errno);
742 goto out;
745 /* Pin parent directory in place. */
746 if (vfs_ChDir(conn, parent_dir_fname) == -1) {
747 status = map_nt_error_from_unix(errno);
748 goto out;
751 /* Ensure the relative path is below the share. */
752 status = check_reduced_name(conn, parent_dir_fname, smb_fname_rel);
753 if (!NT_STATUS_IS_OK(status)) {
754 goto out;
757 /* Setup fsp->fsp_name to be relative to cwd */
758 fsp->fsp_name = smb_fname_rel;
760 /* Also setup base_fsp to be relative to the new cwd */
761 if (fsp->base_fsp != NULL) {
762 base_smb_fname_rel = (struct smb_filename) {
763 .base_name = smb_fname_rel->base_name,
765 orig_base_fsp_name = fsp->base_fsp->fsp_name;
766 fsp->base_fsp->fsp_name = &base_smb_fname_rel;
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 flags |= O_NOFOLLOW;
778 fd = SMB_VFS_OPENAT(conn,
779 dirfsp,
780 smb_fname_rel,
781 fsp,
782 flags,
783 mode);
784 if (fd == -1) {
785 status = link_errno_convert(errno);
787 fsp_set_fd(fsp, fd);
789 if (fd != -1) {
790 ret = SMB_VFS_FSTAT(fsp, &orig_fsp_name->st);
791 if (ret != 0) {
792 status = map_nt_error_from_unix(errno);
793 goto out;
795 fsp->fsp_name->st = orig_fsp_name->st;
798 if (!is_ntfs_stream_smb_fname(fsp->fsp_name) &&
799 fsp->fsp_flags.is_pathref &&
800 have_opath)
803 * Opening with O_PATH and O_NOFOLLOW opens a handle on the
804 * symlink. In follow symlink=yes mode we must avoid this and
805 * instead should open a handle on the symlink target.
807 * Check for this case by doing an fstat, forcing
808 * process_symlink_open() codepath down below by setting fd=-1
809 * and errno=ELOOP.
811 if (S_ISLNK(fsp->fsp_name->st.st_ex_mode)) {
812 ret = SMB_VFS_CLOSE(fsp);
813 SMB_ASSERT(ret == 0);
815 fsp_set_fd(fsp, -1);
816 fd = -1;
817 status = NT_STATUS_STOPPED_ON_SYMLINK;
821 if ((fd == -1) &&
822 (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK) ||
823 NT_STATUS_EQUAL(status, NT_STATUS_NOT_A_DIRECTORY)))
826 * Trying to open a symlink to a directory with O_NOFOLLOW and
827 * O_DIRECTORY can return either of ELOOP and ENOTDIR. So
828 * ENOTDIR really means: might be a symlink, but we're not sure.
829 * In this case, we just assume there's a symlink. If we were
830 * wrong, process_symlink_open() will return EINVAL. We check
831 * this below, and fall back to returning the initial
832 * saved_errno.
834 * BUG: https://bugzilla.samba.org/show_bug.cgi?id=12860
836 saved_status = status;
838 if (fsp->fsp_name->flags & SMB_FILENAME_POSIX_PATH) {
839 /* Never follow symlinks on posix open. */
840 goto out;
842 if (!lp_follow_symlinks(SNUM(conn))) {
843 /* Explicitly no symlinks. */
844 goto out;
847 fsp->fsp_name = orig_fsp_name;
850 * We may have a symlink. Follow in userspace
851 * to ensure it's under the share definition.
853 status = process_symlink_open(dirfsp,
854 fsp,
855 smb_fname_rel,
856 flags,
857 mode,
858 link_depth);
859 if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER) &&
860 NT_STATUS_EQUAL(saved_status, NT_STATUS_NOT_A_DIRECTORY))
862 status = saved_status;
866 out:
867 fsp->fsp_name = orig_fsp_name;
868 if (fsp->base_fsp != NULL) {
869 fsp->base_fsp->fsp_name = orig_base_fsp_name;
871 TALLOC_FREE(parent_dir_fname);
873 if (oldwd_fname != NULL) {
874 ret = vfs_ChDir(conn, oldwd_fname);
875 if (ret == -1) {
876 smb_panic("unable to get back to old directory\n");
878 TALLOC_FREE(oldwd_fname);
880 return status;
883 /****************************************************************************
884 fd support routines - attempt to do a dos_open.
885 ****************************************************************************/
887 NTSTATUS fd_openat(const struct files_struct *dirfsp,
888 struct smb_filename *smb_fname,
889 files_struct *fsp,
890 int flags,
891 mode_t mode)
893 struct connection_struct *conn = fsp->conn;
894 NTSTATUS status = NT_STATUS_OK;
897 * Never follow symlinks on a POSIX client. The
898 * client should be doing this.
901 if ((fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) || !lp_follow_symlinks(SNUM(conn))) {
902 flags |= O_NOFOLLOW;
906 * Only follow symlinks within a share
907 * definition.
909 status = non_widelink_open(dirfsp, fsp, smb_fname, flags, mode, 0);
910 if (!NT_STATUS_IS_OK(status)) {
911 if (NT_STATUS_EQUAL(status, NT_STATUS_TOO_MANY_OPENED_FILES)) {
912 static time_t last_warned = 0L;
914 if (time((time_t *) NULL) > last_warned) {
915 DEBUG(0,("Too many open files, unable "
916 "to open more! smbd's max "
917 "open files = %d\n",
918 lp_max_open_files()));
919 last_warned = time((time_t *) NULL);
923 DBG_DEBUG("name %s, flags = 0%o mode = 0%o, fd = %d. %s\n",
924 smb_fname_str_dbg(smb_fname), flags, (int)mode,
925 fsp_get_pathref_fd(fsp), nt_errstr(status));
926 return status;
929 DBG_DEBUG("name %s, flags = 0%o mode = 0%o, fd = %d\n",
930 smb_fname_str_dbg(smb_fname), flags, (int)mode,
931 fsp_get_pathref_fd(fsp));
933 return status;
936 /****************************************************************************
937 Close the file associated with a fsp.
938 ****************************************************************************/
940 NTSTATUS fd_close(files_struct *fsp)
942 int ret;
944 if (fsp == fsp->conn->cwd_fsp) {
945 return NT_STATUS_OK;
948 if (fsp->dptr) {
949 dptr_CloseDir(fsp);
951 if (fsp_get_pathref_fd(fsp) == -1) {
953 * Either a directory where the dptr_CloseDir() already closed
954 * the fd or a stat open.
956 return NT_STATUS_OK;
958 if (fh_get_refcount(fsp->fh) > 1) {
959 return NT_STATUS_OK; /* Shared handle. Only close last reference. */
962 ret = SMB_VFS_CLOSE(fsp);
963 fsp_set_fd(fsp, -1);
964 if (ret == -1) {
965 return map_nt_error_from_unix(errno);
967 return NT_STATUS_OK;
970 /****************************************************************************
971 Change the ownership of a file to that of the parent directory.
972 Do this by fd if possible.
973 ****************************************************************************/
975 void change_file_owner_to_parent(connection_struct *conn,
976 struct smb_filename *smb_fname_parent,
977 files_struct *fsp)
979 int ret;
981 ret = SMB_VFS_STAT(conn, smb_fname_parent);
982 if (ret == -1) {
983 DEBUG(0,("change_file_owner_to_parent: failed to stat parent "
984 "directory %s. Error was %s\n",
985 smb_fname_str_dbg(smb_fname_parent),
986 strerror(errno)));
987 TALLOC_FREE(smb_fname_parent);
988 return;
991 if (smb_fname_parent->st.st_ex_uid == fsp->fsp_name->st.st_ex_uid) {
992 /* Already this uid - no need to change. */
993 DEBUG(10,("change_file_owner_to_parent: file %s "
994 "is already owned by uid %d\n",
995 fsp_str_dbg(fsp),
996 (int)fsp->fsp_name->st.st_ex_uid ));
997 TALLOC_FREE(smb_fname_parent);
998 return;
1001 become_root();
1002 ret = SMB_VFS_FCHOWN(fsp, smb_fname_parent->st.st_ex_uid, (gid_t)-1);
1003 unbecome_root();
1004 if (ret == -1) {
1005 DEBUG(0,("change_file_owner_to_parent: failed to fchown "
1006 "file %s to parent directory uid %u. Error "
1007 "was %s\n", fsp_str_dbg(fsp),
1008 (unsigned int)smb_fname_parent->st.st_ex_uid,
1009 strerror(errno) ));
1010 } else {
1011 DEBUG(10,("change_file_owner_to_parent: changed new file %s to "
1012 "parent directory uid %u.\n", fsp_str_dbg(fsp),
1013 (unsigned int)smb_fname_parent->st.st_ex_uid));
1014 /* Ensure the uid entry is updated. */
1015 fsp->fsp_name->st.st_ex_uid = smb_fname_parent->st.st_ex_uid;
1019 static NTSTATUS change_dir_owner_to_parent(connection_struct *conn,
1020 struct smb_filename *smb_fname_parent,
1021 struct smb_filename *smb_dname,
1022 SMB_STRUCT_STAT *psbuf)
1024 int ret;
1026 ret = SMB_VFS_STAT(conn, smb_fname_parent);
1027 if (ret == -1) {
1028 DEBUG(0,("change_dir_owner_to_parent: failed to stat parent "
1029 "directory %s. Error was %s\n",
1030 smb_fname_str_dbg(smb_fname_parent),
1031 strerror(errno)));
1032 return map_nt_error_from_unix(errno);
1035 if (smb_fname_parent->st.st_ex_uid == smb_dname->st.st_ex_uid) {
1036 /* Already this uid - no need to change. */
1037 DEBUG(10,("change_dir_owner_to_parent: directory %s "
1038 "is already owned by uid %d\n",
1039 smb_dname->base_name,
1040 (int)smb_dname->st.st_ex_uid ));
1041 return NT_STATUS_OK;
1044 become_root();
1045 ret = SMB_VFS_FCHOWN(smb_dname->fsp,
1046 smb_fname_parent->st.st_ex_uid,
1047 (gid_t)-1);
1048 unbecome_root();
1049 if (ret == -1) {
1050 DEBUG(10,("change_dir_owner_to_parent: failed to chown "
1051 "directory %s to parent directory uid %u. "
1052 "Error was %s\n",
1053 smb_dname->base_name,
1054 (unsigned int)smb_fname_parent->st.st_ex_uid,
1055 strerror(errno) ));
1056 return map_nt_error_from_unix(errno);
1059 DBG_DEBUG("changed ownership of new "
1060 "directory %s to parent directory uid %u.\n",
1061 smb_dname->base_name,
1062 (unsigned int)smb_fname_parent->st.st_ex_uid);
1064 /* Ensure the uid entry is updated. */
1065 psbuf->st_ex_uid = smb_fname_parent->st.st_ex_uid;
1067 return NT_STATUS_OK;
1070 /****************************************************************************
1071 Open a file - returning a guaranteed ATOMIC indication of if the
1072 file was created or not.
1073 ****************************************************************************/
1075 static NTSTATUS fd_open_atomic(files_struct *fsp,
1076 int flags,
1077 mode_t mode,
1078 bool *file_created)
1080 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
1081 NTSTATUS retry_status;
1082 bool file_existed = VALID_STAT(fsp->fsp_name->st);
1083 int curr_flags;
1085 if (!(flags & O_CREAT)) {
1087 * We're not creating the file, just pass through.
1089 status = fd_openat(fsp->conn->cwd_fsp, fsp->fsp_name, fsp, flags, mode);
1090 *file_created = false;
1091 return status;
1094 if (flags & O_EXCL) {
1096 * Fail if already exists, just pass through.
1098 status = fd_openat(fsp->conn->cwd_fsp, fsp->fsp_name, fsp, flags, mode);
1101 * Here we've opened with O_CREAT|O_EXCL. If that went
1102 * NT_STATUS_OK, we *know* we created this file.
1104 *file_created = NT_STATUS_IS_OK(status);
1106 return status;
1110 * Now it gets tricky. We have O_CREAT, but not O_EXCL.
1111 * To know absolutely if we created the file or not,
1112 * we can never call O_CREAT without O_EXCL. So if
1113 * we think the file existed, try without O_CREAT|O_EXCL.
1114 * If we think the file didn't exist, try with
1115 * O_CREAT|O_EXCL.
1117 * The big problem here is dangling symlinks. Opening
1118 * without O_NOFOLLOW means both bad symlink
1119 * and missing path return -1, ENOENT from open(). As POSIX
1120 * is pathname based it's not possible to tell
1121 * the difference between these two cases in a
1122 * non-racy way, so change to try only two attempts before
1123 * giving up.
1125 * We don't have this problem for the O_NOFOLLOW
1126 * case as it just returns NT_STATUS_OBJECT_PATH_NOT_FOUND
1127 * mapped from the ELOOP POSIX error.
1130 if (file_existed) {
1131 curr_flags = flags & ~(O_CREAT);
1132 retry_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
1133 } else {
1134 curr_flags = flags | O_EXCL;
1135 retry_status = NT_STATUS_OBJECT_NAME_COLLISION;
1138 status = fd_openat(fsp->conn->cwd_fsp, fsp->fsp_name, fsp, curr_flags, mode);
1139 if (NT_STATUS_IS_OK(status)) {
1140 *file_created = !file_existed;
1141 return NT_STATUS_OK;
1143 if (NT_STATUS_EQUAL(status, retry_status)) {
1145 file_existed = !file_existed;
1147 DBG_DEBUG("File %s %s. Retry.\n",
1148 fsp_str_dbg(fsp),
1149 file_existed ? "existed" : "did not exist");
1151 if (file_existed) {
1152 curr_flags = flags & ~(O_CREAT);
1153 } else {
1154 curr_flags = flags | O_EXCL;
1157 status = fd_openat(fsp->conn->cwd_fsp, fsp->fsp_name, fsp, curr_flags, mode);
1160 *file_created = (NT_STATUS_IS_OK(status) && !file_existed);
1161 return status;
1164 static NTSTATUS reopen_from_procfd(struct files_struct *fsp,
1165 int flags,
1166 mode_t mode)
1168 struct smb_filename proc_fname;
1169 const char *p = NULL;
1170 char buf[PATH_MAX];
1171 int old_fd;
1172 int new_fd;
1173 NTSTATUS status;
1174 int ret;
1176 if (!fsp->fsp_flags.have_proc_fds) {
1177 return NT_STATUS_MORE_PROCESSING_REQUIRED;
1180 old_fd = fsp_get_pathref_fd(fsp);
1181 if (old_fd == -1) {
1182 return NT_STATUS_MORE_PROCESSING_REQUIRED;
1185 if (!fsp->fsp_flags.is_pathref) {
1186 DBG_ERR("[%s] is not a pathref\n",
1187 fsp_str_dbg(fsp));
1188 #ifdef DEVELOPER
1189 smb_panic("Not a pathref");
1190 #endif
1191 return NT_STATUS_INVALID_HANDLE;
1194 p = sys_proc_fd_path(old_fd, buf, sizeof(buf));
1195 if (p == NULL) {
1196 return NT_STATUS_NO_MEMORY;
1199 proc_fname = (struct smb_filename) {
1200 .base_name = discard_const_p(char, p),
1203 fsp->fsp_flags.is_pathref = false;
1205 new_fd = SMB_VFS_OPENAT(fsp->conn,
1206 fsp->conn->cwd_fsp,
1207 &proc_fname,
1208 fsp,
1209 flags,
1210 mode);
1211 if (new_fd == -1) {
1212 status = map_nt_error_from_unix(errno);
1213 SMB_VFS_CLOSE(fsp);
1214 fsp_set_fd(fsp, -1);
1215 return status;
1218 ret = SMB_VFS_CLOSE(fsp);
1219 fsp_set_fd(fsp, -1);
1220 if (ret != 0) {
1221 return map_nt_error_from_unix(errno);
1224 fsp_set_fd(fsp, new_fd);
1225 return NT_STATUS_OK;
1228 static NTSTATUS reopen_from_fsp(struct files_struct *fsp,
1229 int flags,
1230 mode_t mode,
1231 bool *p_file_created)
1233 bool __unused_file_created = false;
1234 NTSTATUS status;
1236 if (p_file_created == NULL) {
1237 p_file_created = &__unused_file_created;
1241 * TODO: should we move this to the VFS layer?
1242 * SMB_VFS_REOPEN_FSP()?
1245 status = reopen_from_procfd(fsp,
1246 flags,
1247 mode);
1248 if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1250 * Close the existing pathref fd and set the fsp flag
1251 * is_pathref to false so we get a "normal" fd this
1252 * time.
1254 status = fd_close(fsp);
1255 if (!NT_STATUS_IS_OK(status)) {
1256 return status;
1259 fsp->fsp_flags.is_pathref = false;
1261 status = fd_open_atomic(fsp,
1262 flags,
1263 mode,
1264 p_file_created);
1267 return status;
1270 /****************************************************************************
1271 Open a file.
1272 ****************************************************************************/
1274 static NTSTATUS open_file(files_struct *fsp,
1275 struct smb_request *req,
1276 struct smb_filename *parent_dir,
1277 int flags,
1278 mode_t unx_mode,
1279 uint32_t access_mask, /* client requested access mask. */
1280 uint32_t open_access_mask, /* what we're actually using in the open. */
1281 uint32_t private_flags,
1282 bool *p_file_created)
1284 connection_struct *conn = fsp->conn;
1285 struct smb_filename *smb_fname = fsp->fsp_name;
1286 NTSTATUS status = NT_STATUS_OK;
1287 int accmode = (flags & O_ACCMODE);
1288 int local_flags = flags;
1289 bool file_existed = VALID_STAT(fsp->fsp_name->st);
1290 uint32_t need_fd_mask =
1291 FILE_READ_DATA |
1292 FILE_WRITE_DATA |
1293 FILE_APPEND_DATA |
1294 FILE_EXECUTE |
1295 WRITE_DAC_ACCESS |
1296 WRITE_OWNER_ACCESS |
1297 SEC_FLAG_SYSTEM_SECURITY |
1298 READ_CONTROL_ACCESS;
1299 bool creating = !file_existed && (flags & O_CREAT);
1300 bool truncating = (flags & O_TRUNC);
1301 bool open_fd = false;
1304 * Catch early an attempt to open an existing
1305 * directory as a file.
1307 if (file_existed && S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
1308 return NT_STATUS_FILE_IS_A_DIRECTORY;
1311 /* Check permissions */
1314 * This code was changed after seeing a client open request
1315 * containing the open mode of (DENY_WRITE/read-only) with
1316 * the 'create if not exist' bit set. The previous code
1317 * would fail to open the file read only on a read-only share
1318 * as it was checking the flags parameter directly against O_RDONLY,
1319 * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
1320 * JRA.
1323 if (!CAN_WRITE(conn)) {
1324 /* It's a read-only share - fail if we wanted to write. */
1325 if(accmode != O_RDONLY || (flags & O_TRUNC) || (flags & O_APPEND)) {
1326 DEBUG(3,("Permission denied opening %s\n",
1327 smb_fname_str_dbg(smb_fname)));
1328 return NT_STATUS_ACCESS_DENIED;
1330 if (flags & O_CREAT) {
1331 /* We don't want to write - but we must make sure that
1332 O_CREAT doesn't create the file if we have write
1333 access into the directory.
1335 flags &= ~(O_CREAT|O_EXCL);
1336 local_flags &= ~(O_CREAT|O_EXCL);
1341 * This little piece of insanity is inspired by the
1342 * fact that an NT client can open a file for O_RDONLY,
1343 * but set the create disposition to FILE_EXISTS_TRUNCATE.
1344 * If the client *can* write to the file, then it expects to
1345 * truncate the file, even though it is opening for readonly.
1346 * Quicken uses this stupid trick in backup file creation...
1347 * Thanks *greatly* to "David W. Chapman Jr." <dwcjr@inethouston.net>
1348 * for helping track this one down. It didn't bite us in 2.0.x
1349 * as we always opened files read-write in that release. JRA.
1352 if ((accmode == O_RDONLY) && ((flags & O_TRUNC) == O_TRUNC)) {
1353 DEBUG(10,("open_file: truncate requested on read-only open "
1354 "for file %s\n", smb_fname_str_dbg(smb_fname)));
1355 local_flags = (flags & ~O_ACCMODE)|O_RDWR;
1358 if ((open_access_mask & need_fd_mask) || creating || truncating) {
1359 open_fd = true;
1362 if (open_fd) {
1363 const char *wild;
1364 int ret;
1366 #if defined(O_NONBLOCK) && defined(S_ISFIFO)
1368 * We would block on opening a FIFO with no one else on the
1369 * other end. Do what we used to do and add O_NONBLOCK to the
1370 * open flags. JRA.
1373 if (file_existed && S_ISFIFO(smb_fname->st.st_ex_mode)) {
1374 local_flags &= ~O_TRUNC; /* Can't truncate a FIFO. */
1375 local_flags |= O_NONBLOCK;
1376 truncating = false;
1378 #endif
1380 /* Don't create files with Microsoft wildcard characters. */
1381 if (fsp->base_fsp) {
1383 * wildcard characters are allowed in stream names
1384 * only test the basefilename
1386 wild = fsp->base_fsp->fsp_name->base_name;
1387 } else {
1388 wild = smb_fname->base_name;
1390 if ((local_flags & O_CREAT) && !file_existed &&
1391 !(fsp->posix_flags & FSP_POSIX_FLAGS_PATHNAMES) &&
1392 ms_has_wild(wild)) {
1393 return NT_STATUS_OBJECT_NAME_INVALID;
1396 /* Can we access this file ? */
1397 if (!fsp->base_fsp) {
1398 /* Only do this check on non-stream open. */
1399 if (file_existed) {
1400 status = smbd_check_access_rights(conn,
1401 conn->cwd_fsp,
1402 smb_fname,
1403 false,
1404 access_mask);
1406 if (!NT_STATUS_IS_OK(status)) {
1407 DEBUG(10, ("open_file: "
1408 "smbd_check_access_rights "
1409 "on file %s returned %s\n",
1410 smb_fname_str_dbg(smb_fname),
1411 nt_errstr(status)));
1414 if (!NT_STATUS_IS_OK(status) &&
1415 !NT_STATUS_EQUAL(status,
1416 NT_STATUS_OBJECT_NAME_NOT_FOUND))
1418 return status;
1421 if (NT_STATUS_EQUAL(status,
1422 NT_STATUS_OBJECT_NAME_NOT_FOUND))
1424 DEBUG(10, ("open_file: "
1425 "file %s vanished since we "
1426 "checked for existence.\n",
1427 smb_fname_str_dbg(smb_fname)));
1428 file_existed = false;
1429 SET_STAT_INVALID(fsp->fsp_name->st);
1433 if (!file_existed) {
1434 if (!(local_flags & O_CREAT)) {
1435 /* File didn't exist and no O_CREAT. */
1436 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1439 status = check_parent_access_fsp(
1440 parent_dir->fsp,
1441 SEC_DIR_ADD_FILE);
1442 if (!NT_STATUS_IS_OK(status)) {
1443 DBG_DEBUG("check_parent_access_fsp on "
1444 "directory %s for file %s "
1445 "returned %s\n",
1446 smb_fname_str_dbg(parent_dir),
1447 smb_fname_str_dbg(smb_fname),
1448 nt_errstr(status));
1449 return status;
1455 * Actually do the open - if O_TRUNC is needed handle it
1456 * below under the share mode lock.
1458 status = reopen_from_fsp(fsp,
1459 local_flags & ~O_TRUNC,
1460 unx_mode,
1461 p_file_created);
1462 if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) {
1464 * POSIX client that hit a symlink. We don't want to
1465 * return NT_STATUS_STOPPED_ON_SYMLINK to avoid handling
1466 * this special error code in all callers, so we map
1467 * this to NT_STATUS_OBJECT_PATH_NOT_FOUND. Historically
1468 * the lower level functions returned status code mapped
1469 * from errno by map_nt_error_from_unix() where ELOOP is
1470 * mapped to NT_STATUS_OBJECT_PATH_NOT_FOUND.
1472 status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
1474 if (!NT_STATUS_IS_OK(status)) {
1475 DEBUG(3,("Error opening file %s (%s) (local_flags=%d) "
1476 "(flags=%d)\n", smb_fname_str_dbg(smb_fname),
1477 nt_errstr(status),local_flags,flags));
1478 return status;
1481 if (local_flags & O_NONBLOCK) {
1483 * GPFS can return ETIMEDOUT for pread on
1484 * nonblocking file descriptors when files
1485 * migrated to tape need to be recalled. I
1486 * could imagine this happens elsewhere
1487 * too. With blocking file descriptors this
1488 * does not happen.
1490 ret = vfs_set_blocking(fsp, true);
1491 if (ret == -1) {
1492 status = map_nt_error_from_unix(errno);
1493 DBG_WARNING("Could not set fd to blocking: "
1494 "%s\n", strerror(errno));
1495 fd_close(fsp);
1496 return status;
1500 if (*p_file_created) {
1501 /* We created this file. */
1503 bool need_re_stat = false;
1504 /* Do all inheritance work after we've
1505 done a successful fstat call and filled
1506 in the stat struct in fsp->fsp_name. */
1508 /* Inherit the ACL if required */
1509 if (lp_inherit_permissions(SNUM(conn))) {
1510 inherit_access_posix_acl(conn,
1511 parent_dir,
1512 smb_fname,
1513 unx_mode);
1514 need_re_stat = true;
1517 /* Change the owner if required. */
1518 if (lp_inherit_owner(SNUM(conn)) != INHERIT_OWNER_NO) {
1519 change_file_owner_to_parent(conn,
1520 parent_dir,
1521 fsp);
1522 need_re_stat = true;
1525 if (need_re_stat) {
1526 ret = SMB_VFS_FSTAT(fsp, &smb_fname->st);
1528 * If we have an fd, this stat should succeed.
1530 if (ret == -1) {
1531 status = map_nt_error_from_unix(errno);
1532 DBG_ERR("Error doing fstat on open "
1533 "file %s (%s)\n",
1534 smb_fname_str_dbg(smb_fname),
1535 nt_errstr(status));
1536 fd_close(fsp);
1537 return status;
1541 notify_fname(conn, NOTIFY_ACTION_ADDED,
1542 FILE_NOTIFY_CHANGE_FILE_NAME,
1543 smb_fname->base_name);
1545 } else {
1546 if (!file_existed) {
1547 /* File must exist for a stat open. */
1548 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1551 if (S_ISLNK(smb_fname->st.st_ex_mode) &&
1552 !(fsp->posix_flags & FSP_POSIX_FLAGS_OPEN))
1555 * Don't allow stat opens on symlinks directly unless
1556 * it's a POSIX open.
1558 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
1561 if (!fsp->fsp_flags.is_pathref) {
1563 * There is only one legit case where end up here:
1564 * openat_pathref_fsp() failed to open a symlink, so the
1565 * fsp was created by fsp_new() which doesn't set
1566 * is_pathref. Other then that, we should always have a
1567 * pathref fsp at this point. The subsequent checks
1568 * assert this.
1570 if (!(smb_fname->flags & SMB_FILENAME_POSIX_PATH)) {
1571 DBG_ERR("[%s] is not a POSIX pathname\n",
1572 smb_fname_str_dbg(smb_fname));
1573 return NT_STATUS_INTERNAL_ERROR;
1575 if (!S_ISLNK(smb_fname->st.st_ex_mode)) {
1576 DBG_ERR("[%s] is not a symlink\n",
1577 smb_fname_str_dbg(smb_fname));
1578 return NT_STATUS_INTERNAL_ERROR;
1580 if (fsp_get_pathref_fd(fsp) != -1) {
1581 DBG_ERR("fd for [%s] is not -1: fd [%d]\n",
1582 smb_fname_str_dbg(smb_fname),
1583 fsp_get_pathref_fd(fsp));
1584 return NT_STATUS_INTERNAL_ERROR;
1588 status = smbd_check_access_rights_fsp(fsp,
1589 false,
1590 access_mask);
1592 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) &&
1593 (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) &&
1594 S_ISLNK(smb_fname->st.st_ex_mode)) {
1595 /* This is a POSIX stat open for delete
1596 * or rename on a symlink that points
1597 * nowhere. Allow. */
1598 DEBUG(10,("open_file: allowing POSIX "
1599 "open on bad symlink %s\n",
1600 smb_fname_str_dbg(smb_fname)));
1601 status = NT_STATUS_OK;
1604 if (!NT_STATUS_IS_OK(status)) {
1605 DEBUG(10,("open_file: "
1606 "smbd_check_access_rights on file "
1607 "%s returned %s\n",
1608 smb_fname_str_dbg(smb_fname),
1609 nt_errstr(status) ));
1610 return status;
1614 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
1615 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
1616 fsp->file_pid = req ? req->smbpid : 0;
1617 fsp->fsp_flags.can_lock = true;
1618 fsp->fsp_flags.can_read = ((access_mask & FILE_READ_DATA) != 0);
1619 fsp->fsp_flags.can_write =
1620 CAN_WRITE(conn) &&
1621 ((access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) != 0);
1622 fsp->print_file = NULL;
1623 fsp->fsp_flags.modified = false;
1624 fsp->sent_oplock_break = NO_BREAK_SENT;
1625 fsp->fsp_flags.is_directory = false;
1626 if (conn->aio_write_behind_list &&
1627 is_in_path(smb_fname->base_name, conn->aio_write_behind_list,
1628 conn->case_sensitive)) {
1629 fsp->fsp_flags.aio_write_behind = true;
1632 DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
1633 conn->session_info->unix_info->unix_name,
1634 smb_fname_str_dbg(smb_fname),
1635 BOOLSTR(fsp->fsp_flags.can_read),
1636 BOOLSTR(fsp->fsp_flags.can_write),
1637 conn->num_files_open));
1639 return NT_STATUS_OK;
1642 static bool mask_conflict(
1643 uint32_t new_access,
1644 uint32_t existing_access,
1645 uint32_t access_mask,
1646 uint32_t new_sharemode,
1647 uint32_t existing_sharemode,
1648 uint32_t sharemode_mask)
1650 bool want_access = (new_access & access_mask);
1651 bool allow_existing = (existing_sharemode & sharemode_mask);
1652 bool have_access = (existing_access & access_mask);
1653 bool allow_new = (new_sharemode & sharemode_mask);
1655 if (want_access && !allow_existing) {
1656 DBG_DEBUG("Access request 0x%"PRIx32"/0x%"PRIx32" conflicts "
1657 "with existing sharemode 0x%"PRIx32"/0x%"PRIx32"\n",
1658 new_access,
1659 access_mask,
1660 existing_sharemode,
1661 sharemode_mask);
1662 return true;
1664 if (have_access && !allow_new) {
1665 DBG_DEBUG("Sharemode request 0x%"PRIx32"/0x%"PRIx32" conflicts "
1666 "with existing access 0x%"PRIx32"/0x%"PRIx32"\n",
1667 new_sharemode,
1668 sharemode_mask,
1669 existing_access,
1670 access_mask);
1671 return true;
1673 return false;
1676 /****************************************************************************
1677 Check if we can open a file with a share mode.
1678 Returns True if conflict, False if not.
1679 ****************************************************************************/
1681 static const uint32_t conflicting_access =
1682 FILE_WRITE_DATA|
1683 FILE_APPEND_DATA|
1684 FILE_READ_DATA|
1685 FILE_EXECUTE|
1686 DELETE_ACCESS;
1688 static bool share_conflict(uint32_t e_access_mask,
1689 uint32_t e_share_access,
1690 uint32_t access_mask,
1691 uint32_t share_access)
1693 bool conflict;
1695 DBG_DEBUG("existing access_mask = 0x%"PRIx32", "
1696 "existing share access = 0x%"PRIx32", "
1697 "access_mask = 0x%"PRIx32", "
1698 "share_access = 0x%"PRIx32"\n",
1699 e_access_mask,
1700 e_share_access,
1701 access_mask,
1702 share_access);
1704 if ((e_access_mask & conflicting_access) == 0) {
1705 DBG_DEBUG("No conflict due to "
1706 "existing access_mask = 0x%"PRIx32"\n",
1707 e_access_mask);
1708 return false;
1710 if ((access_mask & conflicting_access) == 0) {
1711 DBG_DEBUG("No conflict due to access_mask = 0x%"PRIx32"\n",
1712 access_mask);
1713 return false;
1716 conflict = mask_conflict(
1717 access_mask, e_access_mask, FILE_WRITE_DATA | FILE_APPEND_DATA,
1718 share_access, e_share_access, FILE_SHARE_WRITE);
1719 conflict |= mask_conflict(
1720 access_mask, e_access_mask, FILE_READ_DATA | FILE_EXECUTE,
1721 share_access, e_share_access, FILE_SHARE_READ);
1722 conflict |= mask_conflict(
1723 access_mask, e_access_mask, DELETE_ACCESS,
1724 share_access, e_share_access, FILE_SHARE_DELETE);
1726 DBG_DEBUG("conflict=%s\n", conflict ? "true" : "false");
1727 return conflict;
1730 #if defined(DEVELOPER)
1732 struct validate_my_share_entries_state {
1733 struct smbd_server_connection *sconn;
1734 struct file_id fid;
1735 struct server_id self;
1738 static bool validate_my_share_entries_fn(
1739 struct share_mode_entry *e,
1740 bool *modified,
1741 void *private_data)
1743 struct validate_my_share_entries_state *state = private_data;
1744 files_struct *fsp;
1746 if (!server_id_equal(&state->self, &e->pid)) {
1747 return false;
1750 if (e->op_mid == 0) {
1751 /* INTERNAL_OPEN_ONLY */
1752 return false;
1755 fsp = file_find_dif(state->sconn, state->fid, e->share_file_id);
1756 if (!fsp) {
1757 DBG_ERR("PANIC : %s\n",
1758 share_mode_str(talloc_tos(), 0, &state->fid, e));
1759 smb_panic("validate_my_share_entries: Cannot match a "
1760 "share entry with an open file\n");
1763 if (((uint16_t)fsp->oplock_type) != e->op_type) {
1764 goto panic;
1767 return false;
1769 panic:
1771 char *str;
1772 DBG_ERR("validate_my_share_entries: PANIC : %s\n",
1773 share_mode_str(talloc_tos(), 0, &state->fid, e));
1774 str = talloc_asprintf(talloc_tos(),
1775 "validate_my_share_entries: "
1776 "file %s, oplock_type = 0x%x, op_type = 0x%x\n",
1777 fsp->fsp_name->base_name,
1778 (unsigned int)fsp->oplock_type,
1779 (unsigned int)e->op_type);
1780 smb_panic(str);
1783 return false;
1785 #endif
1788 * Allowed access mask for stat opens relevant to oplocks
1790 bool is_oplock_stat_open(uint32_t access_mask)
1792 const uint32_t stat_open_bits =
1793 (SYNCHRONIZE_ACCESS|
1794 FILE_READ_ATTRIBUTES|
1795 FILE_WRITE_ATTRIBUTES);
1797 return (((access_mask & stat_open_bits) != 0) &&
1798 ((access_mask & ~stat_open_bits) == 0));
1802 * Allowed access mask for stat opens relevant to leases
1804 bool is_lease_stat_open(uint32_t access_mask)
1806 const uint32_t stat_open_bits =
1807 (SYNCHRONIZE_ACCESS|
1808 FILE_READ_ATTRIBUTES|
1809 FILE_WRITE_ATTRIBUTES|
1810 READ_CONTROL_ACCESS);
1812 return (((access_mask & stat_open_bits) != 0) &&
1813 ((access_mask & ~stat_open_bits) == 0));
1816 struct has_delete_on_close_state {
1817 bool ret;
1820 static bool has_delete_on_close_fn(
1821 struct share_mode_entry *e,
1822 bool *modified,
1823 void *private_data)
1825 struct has_delete_on_close_state *state = private_data;
1826 state->ret = !share_entry_stale_pid(e);
1827 return state->ret;
1830 static bool has_delete_on_close(struct share_mode_lock *lck,
1831 uint32_t name_hash)
1833 struct has_delete_on_close_state state = { .ret = false };
1834 bool ok;
1836 if (!is_delete_on_close_set(lck, name_hash)) {
1837 return false;
1840 ok= share_mode_forall_entries(lck, has_delete_on_close_fn, &state);
1841 if (!ok) {
1842 DBG_DEBUG("share_mode_forall_entries failed\n");
1843 return false;
1845 return state.ret;
1848 static void share_mode_flags_restrict(
1849 struct share_mode_lock *lck,
1850 uint32_t access_mask,
1851 uint32_t share_mode,
1852 uint32_t lease_type)
1854 uint32_t existing_access_mask, existing_share_mode;
1855 uint32_t existing_lease_type;
1857 share_mode_flags_get(
1858 lck,
1859 &existing_access_mask,
1860 &existing_share_mode,
1861 &existing_lease_type);
1863 existing_access_mask |= access_mask;
1864 if (access_mask & conflicting_access) {
1865 existing_share_mode &= share_mode;
1867 existing_lease_type |= lease_type;
1869 share_mode_flags_set(
1870 lck,
1871 existing_access_mask,
1872 existing_share_mode,
1873 existing_lease_type,
1874 NULL);
1877 /****************************************************************************
1878 Deal with share modes
1879 Invariant: Share mode must be locked on entry and exit.
1880 Returns -1 on error, or number of share modes on success (may be zero).
1881 ****************************************************************************/
1883 struct open_mode_check_state {
1884 struct file_id fid;
1885 uint32_t access_mask;
1886 uint32_t share_access;
1887 uint32_t lease_type;
1890 static bool open_mode_check_fn(
1891 struct share_mode_entry *e,
1892 bool *modified,
1893 void *private_data)
1895 struct open_mode_check_state *state = private_data;
1896 bool disconnected, stale;
1897 uint32_t access_mask, share_access, lease_type;
1899 disconnected = server_id_is_disconnected(&e->pid);
1900 if (disconnected) {
1901 return false;
1904 access_mask = state->access_mask | e->access_mask;
1905 share_access = state->share_access;
1906 if (e->access_mask & conflicting_access) {
1907 share_access &= e->share_access;
1909 lease_type = state->lease_type | get_lease_type(e, state->fid);
1911 if ((access_mask == state->access_mask) &&
1912 (share_access == state->share_access) &&
1913 (lease_type == state->lease_type)) {
1914 return false;
1917 stale = share_entry_stale_pid(e);
1918 if (stale) {
1919 return false;
1922 state->access_mask = access_mask;
1923 state->share_access = share_access;
1924 state->lease_type = lease_type;
1926 return false;
1929 static NTSTATUS open_mode_check(connection_struct *conn,
1930 struct file_id fid,
1931 struct share_mode_lock *lck,
1932 uint32_t access_mask,
1933 uint32_t share_access)
1935 struct open_mode_check_state state;
1936 bool ok, conflict;
1937 bool modified = false;
1939 if (is_oplock_stat_open(access_mask)) {
1940 /* Stat open that doesn't trigger oplock breaks or share mode
1941 * checks... ! JRA. */
1942 return NT_STATUS_OK;
1946 * Check if the share modes will give us access.
1949 #if defined(DEVELOPER)
1951 struct validate_my_share_entries_state validate_state = {
1952 .sconn = conn->sconn,
1953 .fid = fid,
1954 .self = messaging_server_id(conn->sconn->msg_ctx),
1956 ok = share_mode_forall_entries(
1957 lck, validate_my_share_entries_fn, &validate_state);
1958 SMB_ASSERT(ok);
1960 #endif
1962 share_mode_flags_get(
1963 lck, &state.access_mask, &state.share_access, NULL);
1965 conflict = share_conflict(
1966 state.access_mask,
1967 state.share_access,
1968 access_mask,
1969 share_access);
1970 if (!conflict) {
1971 DBG_DEBUG("No conflict due to share_mode_flags access\n");
1972 return NT_STATUS_OK;
1975 state = (struct open_mode_check_state) {
1976 .fid = fid,
1977 .share_access = (FILE_SHARE_READ|
1978 FILE_SHARE_WRITE|
1979 FILE_SHARE_DELETE),
1983 * Walk the share mode array to recalculate d->flags
1986 ok = share_mode_forall_entries(lck, open_mode_check_fn, &state);
1987 if (!ok) {
1988 DBG_DEBUG("share_mode_forall_entries failed\n");
1989 return NT_STATUS_INTERNAL_ERROR;
1992 share_mode_flags_set(
1993 lck,
1994 state.access_mask,
1995 state.share_access,
1996 state.lease_type,
1997 &modified);
1998 if (!modified) {
2000 * We only end up here if we had a sharing violation
2001 * from d->flags and have recalculated it.
2003 return NT_STATUS_SHARING_VIOLATION;
2006 conflict = share_conflict(
2007 state.access_mask,
2008 state.share_access,
2009 access_mask,
2010 share_access);
2011 if (!conflict) {
2012 DBG_DEBUG("No conflict due to share_mode_flags access\n");
2013 return NT_STATUS_OK;
2016 return NT_STATUS_SHARING_VIOLATION;
2020 * Send a break message to the oplock holder and delay the open for
2021 * our client.
2024 NTSTATUS send_break_message(struct messaging_context *msg_ctx,
2025 const struct file_id *id,
2026 const struct share_mode_entry *exclusive,
2027 uint16_t break_to)
2029 struct oplock_break_message msg = {
2030 .id = *id,
2031 .share_file_id = exclusive->share_file_id,
2032 .break_to = break_to,
2034 enum ndr_err_code ndr_err;
2035 DATA_BLOB blob;
2036 NTSTATUS status;
2038 if (DEBUGLVL(10)) {
2039 struct server_id_buf buf;
2040 DBG_DEBUG("Sending break message to %s\n",
2041 server_id_str_buf(exclusive->pid, &buf));
2042 NDR_PRINT_DEBUG(oplock_break_message, &msg);
2045 ndr_err = ndr_push_struct_blob(
2046 &blob,
2047 talloc_tos(),
2048 &msg,
2049 (ndr_push_flags_fn_t)ndr_push_oplock_break_message);
2050 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2051 DBG_WARNING("ndr_push_oplock_break_message failed: %s\n",
2052 ndr_errstr(ndr_err));
2053 return ndr_map_error2ntstatus(ndr_err);
2056 status = messaging_send(
2057 msg_ctx, exclusive->pid, MSG_SMB_BREAK_REQUEST, &blob);
2058 TALLOC_FREE(blob.data);
2059 if (!NT_STATUS_IS_OK(status)) {
2060 DEBUG(3, ("Could not send oplock break message: %s\n",
2061 nt_errstr(status)));
2064 return status;
2067 struct validate_oplock_types_state {
2068 bool valid;
2069 bool batch;
2070 bool ex_or_batch;
2071 bool level2;
2072 bool no_oplock;
2073 uint32_t num_non_stat_opens;
2076 static bool validate_oplock_types_fn(
2077 struct share_mode_entry *e,
2078 bool *modified,
2079 void *private_data)
2081 struct validate_oplock_types_state *state = private_data;
2083 if (e->op_mid == 0) {
2084 /* INTERNAL_OPEN_ONLY */
2085 return false;
2088 if (e->op_type == NO_OPLOCK && is_oplock_stat_open(e->access_mask)) {
2090 * We ignore stat opens in the table - they always
2091 * have NO_OPLOCK and never get or cause breaks. JRA.
2093 return false;
2096 state->num_non_stat_opens += 1;
2098 if (BATCH_OPLOCK_TYPE(e->op_type)) {
2099 /* batch - can only be one. */
2100 if (share_entry_stale_pid(e)) {
2101 DBG_DEBUG("Found stale batch oplock\n");
2102 return false;
2104 if (state->ex_or_batch ||
2105 state->batch ||
2106 state->level2 ||
2107 state->no_oplock) {
2108 DBG_ERR("Bad batch oplock entry\n");
2109 state->valid = false;
2110 return true;
2112 state->batch = true;
2115 if (EXCLUSIVE_OPLOCK_TYPE(e->op_type)) {
2116 if (share_entry_stale_pid(e)) {
2117 DBG_DEBUG("Found stale duplicate oplock\n");
2118 return false;
2120 /* Exclusive or batch - can only be one. */
2121 if (state->ex_or_batch ||
2122 state->level2 ||
2123 state->no_oplock) {
2124 DBG_ERR("Bad exclusive or batch oplock entry\n");
2125 state->valid = false;
2126 return true;
2128 state->ex_or_batch = true;
2131 if (LEVEL_II_OPLOCK_TYPE(e->op_type)) {
2132 if (state->batch || state->ex_or_batch) {
2133 if (share_entry_stale_pid(e)) {
2134 DBG_DEBUG("Found stale LevelII oplock\n");
2135 return false;
2137 DBG_DEBUG("Bad levelII oplock entry\n");
2138 state->valid = false;
2139 return true;
2141 state->level2 = true;
2144 if (e->op_type == NO_OPLOCK) {
2145 if (state->batch || state->ex_or_batch) {
2146 if (share_entry_stale_pid(e)) {
2147 DBG_DEBUG("Found stale NO_OPLOCK entry\n");
2148 return false;
2150 DBG_ERR("Bad no oplock entry\n");
2151 state->valid = false;
2152 return true;
2154 state->no_oplock = true;
2157 return false;
2161 * Do internal consistency checks on the share mode for a file.
2164 static bool validate_oplock_types(struct share_mode_lock *lck)
2166 struct validate_oplock_types_state state = { .valid = true };
2167 bool ok;
2169 ok = share_mode_forall_entries(lck, validate_oplock_types_fn, &state);
2170 if (!ok) {
2171 DBG_DEBUG("share_mode_forall_entries failed\n");
2172 return false;
2174 if (!state.valid) {
2175 DBG_DEBUG("Got invalid oplock configuration\n");
2176 return false;
2179 if ((state.batch || state.ex_or_batch) &&
2180 (state.num_non_stat_opens != 1)) {
2181 DBG_WARNING("got batch (%d) or ex (%d) non-exclusively "
2182 "(%"PRIu32")\n",
2183 (int)state.batch,
2184 (int)state.ex_or_batch,
2185 state.num_non_stat_opens);
2186 return false;
2189 return true;
2192 static bool is_same_lease(const files_struct *fsp,
2193 const struct share_mode_entry *e,
2194 const struct smb2_lease *lease)
2196 if (e->op_type != LEASE_OPLOCK) {
2197 return false;
2199 if (lease == NULL) {
2200 return false;
2203 return smb2_lease_equal(fsp_client_guid(fsp),
2204 &lease->lease_key,
2205 &e->client_guid,
2206 &e->lease_key);
2209 static bool file_has_brlocks(files_struct *fsp)
2211 struct byte_range_lock *br_lck;
2213 br_lck = brl_get_locks_readonly(fsp);
2214 if (!br_lck)
2215 return false;
2217 return (brl_num_locks(br_lck) > 0);
2220 struct fsp_lease *find_fsp_lease(struct files_struct *new_fsp,
2221 const struct smb2_lease_key *key,
2222 uint32_t current_state,
2223 uint16_t lease_version,
2224 uint16_t lease_epoch)
2226 struct files_struct *fsp;
2229 * TODO: Measure how expensive this loop is with thousands of open
2230 * handles...
2233 for (fsp = file_find_di_first(new_fsp->conn->sconn, new_fsp->file_id, true);
2234 fsp != NULL;
2235 fsp = file_find_di_next(fsp, true)) {
2237 if (fsp == new_fsp) {
2238 continue;
2240 if (fsp->oplock_type != LEASE_OPLOCK) {
2241 continue;
2243 if (smb2_lease_key_equal(&fsp->lease->lease.lease_key, key)) {
2244 fsp->lease->ref_count += 1;
2245 return fsp->lease;
2249 /* Not found - must be leased in another smbd. */
2250 new_fsp->lease = talloc_zero(new_fsp->conn->sconn, struct fsp_lease);
2251 if (new_fsp->lease == NULL) {
2252 return NULL;
2254 new_fsp->lease->ref_count = 1;
2255 new_fsp->lease->sconn = new_fsp->conn->sconn;
2256 new_fsp->lease->lease.lease_key = *key;
2257 new_fsp->lease->lease.lease_state = current_state;
2259 * We internally treat all leases as V2 and update
2260 * the epoch, but when sending breaks it matters if
2261 * the requesting lease was v1 or v2.
2263 new_fsp->lease->lease.lease_version = lease_version;
2264 new_fsp->lease->lease.lease_epoch = lease_epoch;
2265 return new_fsp->lease;
2268 static NTSTATUS try_lease_upgrade(struct files_struct *fsp,
2269 struct share_mode_lock *lck,
2270 const struct GUID *client_guid,
2271 const struct smb2_lease *lease,
2272 uint32_t granted)
2274 bool do_upgrade;
2275 uint32_t current_state, breaking_to_requested, breaking_to_required;
2276 bool breaking;
2277 uint16_t lease_version, epoch;
2278 uint32_t existing, requested;
2279 NTSTATUS status;
2281 status = leases_db_get(
2282 client_guid,
2283 &lease->lease_key,
2284 &fsp->file_id,
2285 &current_state,
2286 &breaking,
2287 &breaking_to_requested,
2288 &breaking_to_required,
2289 &lease_version,
2290 &epoch);
2291 if (!NT_STATUS_IS_OK(status)) {
2292 return status;
2295 fsp->lease = find_fsp_lease(
2296 fsp,
2297 &lease->lease_key,
2298 current_state,
2299 lease_version,
2300 epoch);
2301 if (fsp->lease == NULL) {
2302 DEBUG(1, ("Did not find existing lease for file %s\n",
2303 fsp_str_dbg(fsp)));
2304 return NT_STATUS_NO_MEMORY;
2308 * Upgrade only if the requested lease is a strict upgrade.
2310 existing = current_state;
2311 requested = lease->lease_state;
2314 * Tricky: This test makes sure that "requested" is a
2315 * strict bitwise superset of "existing".
2317 do_upgrade = ((existing & requested) == existing);
2320 * Upgrade only if there's a change.
2322 do_upgrade &= (granted != existing);
2325 * Upgrade only if other leases don't prevent what was asked
2326 * for.
2328 do_upgrade &= (granted == requested);
2331 * only upgrade if we are not in breaking state
2333 do_upgrade &= !breaking;
2335 DEBUG(10, ("existing=%"PRIu32", requested=%"PRIu32", "
2336 "granted=%"PRIu32", do_upgrade=%d\n",
2337 existing, requested, granted, (int)do_upgrade));
2339 if (do_upgrade) {
2340 NTSTATUS set_status;
2342 current_state = granted;
2343 epoch += 1;
2345 set_status = leases_db_set(
2346 client_guid,
2347 &lease->lease_key,
2348 current_state,
2349 breaking,
2350 breaking_to_requested,
2351 breaking_to_required,
2352 lease_version,
2353 epoch);
2355 if (!NT_STATUS_IS_OK(set_status)) {
2356 DBG_DEBUG("leases_db_set failed: %s\n",
2357 nt_errstr(set_status));
2358 return set_status;
2362 fsp_lease_update(fsp);
2364 return NT_STATUS_OK;
2367 static NTSTATUS grant_new_fsp_lease(struct files_struct *fsp,
2368 struct share_mode_lock *lck,
2369 const struct GUID *client_guid,
2370 const struct smb2_lease *lease,
2371 uint32_t granted)
2373 NTSTATUS status;
2375 fsp->lease = talloc_zero(fsp->conn->sconn, struct fsp_lease);
2376 if (fsp->lease == NULL) {
2377 return NT_STATUS_INSUFFICIENT_RESOURCES;
2379 fsp->lease->ref_count = 1;
2380 fsp->lease->sconn = fsp->conn->sconn;
2381 fsp->lease->lease.lease_version = lease->lease_version;
2382 fsp->lease->lease.lease_key = lease->lease_key;
2383 fsp->lease->lease.lease_state = granted;
2384 fsp->lease->lease.lease_epoch = lease->lease_epoch + 1;
2386 status = leases_db_add(client_guid,
2387 &lease->lease_key,
2388 &fsp->file_id,
2389 fsp->lease->lease.lease_state,
2390 fsp->lease->lease.lease_version,
2391 fsp->lease->lease.lease_epoch,
2392 fsp->conn->connectpath,
2393 fsp->fsp_name->base_name,
2394 fsp->fsp_name->stream_name);
2395 if (!NT_STATUS_IS_OK(status)) {
2396 DEBUG(10, ("%s: leases_db_add failed: %s\n", __func__,
2397 nt_errstr(status)));
2398 TALLOC_FREE(fsp->lease);
2399 return NT_STATUS_INSUFFICIENT_RESOURCES;
2403 * We used to set lck->data->modified=true here without
2404 * actually modifying lck->data, triggering a needless
2405 * writeback of lck->data.
2407 * Apart from that writeback, setting modified=true has the
2408 * effect of triggering all waiters for this file to
2409 * retry. This only makes sense if any blocking condition
2410 * (i.e. waiting for a lease to be downgraded or removed) is
2411 * gone. This routine here only adds a lease, so it will never
2412 * free up resources that blocked waiters can now claim. So
2413 * that second effect also does not matter in this
2414 * routine. Thus setting lck->data->modified=true does not
2415 * need to be done here.
2418 return NT_STATUS_OK;
2421 static NTSTATUS grant_fsp_lease(struct files_struct *fsp,
2422 struct share_mode_lock *lck,
2423 const struct smb2_lease *lease,
2424 uint32_t granted)
2426 const struct GUID *client_guid = fsp_client_guid(fsp);
2427 NTSTATUS status;
2429 status = try_lease_upgrade(fsp, lck, client_guid, lease, granted);
2431 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
2432 status = grant_new_fsp_lease(
2433 fsp, lck, client_guid, lease, granted);
2436 return status;
2439 static int map_lease_type_to_oplock(uint32_t lease_type)
2441 int result = NO_OPLOCK;
2443 switch (lease_type) {
2444 case SMB2_LEASE_READ|SMB2_LEASE_WRITE|SMB2_LEASE_HANDLE:
2445 result = BATCH_OPLOCK|EXCLUSIVE_OPLOCK;
2446 break;
2447 case SMB2_LEASE_READ|SMB2_LEASE_WRITE:
2448 result = EXCLUSIVE_OPLOCK;
2449 break;
2450 case SMB2_LEASE_READ|SMB2_LEASE_HANDLE:
2451 case SMB2_LEASE_READ:
2452 result = LEVEL_II_OPLOCK;
2453 break;
2456 return result;
2459 struct delay_for_oplock_state {
2460 struct files_struct *fsp;
2461 const struct smb2_lease *lease;
2462 bool will_overwrite;
2463 uint32_t delay_mask;
2464 bool first_open_attempt;
2465 bool got_handle_lease;
2466 bool got_oplock;
2467 bool have_other_lease;
2468 bool delay;
2471 static bool delay_for_oplock_fn(
2472 struct share_mode_entry *e,
2473 bool *modified,
2474 void *private_data)
2476 struct delay_for_oplock_state *state = private_data;
2477 struct files_struct *fsp = state->fsp;
2478 const struct smb2_lease *lease = state->lease;
2479 bool e_is_lease = (e->op_type == LEASE_OPLOCK);
2480 uint32_t e_lease_type = get_lease_type(e, fsp->file_id);
2481 uint32_t break_to;
2482 bool lease_is_breaking = false;
2484 if (e_is_lease) {
2485 NTSTATUS status;
2487 if (lease != NULL) {
2488 bool our_lease = is_same_lease(fsp, e, lease);
2489 if (our_lease) {
2490 DBG_DEBUG("Ignoring our own lease\n");
2491 return false;
2495 status = leases_db_get(
2496 &e->client_guid,
2497 &e->lease_key,
2498 &fsp->file_id,
2499 NULL, /* current_state */
2500 &lease_is_breaking,
2501 NULL, /* breaking_to_requested */
2502 NULL, /* breaking_to_required */
2503 NULL, /* lease_version */
2504 NULL); /* epoch */
2507 * leases_db_get() can return NT_STATUS_NOT_FOUND
2508 * if the share_mode_entry e is stale and the
2509 * lease record was already removed. In this case return
2510 * false so the traverse continues.
2513 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND) &&
2514 share_entry_stale_pid(e))
2516 struct GUID_txt_buf guid_strbuf;
2517 struct file_id_buf file_id_strbuf;
2518 DBG_DEBUG("leases_db_get for client_guid [%s] "
2519 "lease_key [%"PRIu64"/%"PRIu64"] "
2520 "file_id [%s] failed for stale "
2521 "share_mode_entry\n",
2522 GUID_buf_string(&e->client_guid, &guid_strbuf),
2523 e->lease_key.data[0],
2524 e->lease_key.data[1],
2525 file_id_str_buf(fsp->file_id, &file_id_strbuf));
2526 return false;
2528 if (!NT_STATUS_IS_OK(status)) {
2529 struct GUID_txt_buf guid_strbuf;
2530 struct file_id_buf file_id_strbuf;
2531 DBG_ERR("leases_db_get for client_guid [%s] "
2532 "lease_key [%"PRIu64"/%"PRIu64"] "
2533 "file_id [%s] failed: %s\n",
2534 GUID_buf_string(&e->client_guid, &guid_strbuf),
2535 e->lease_key.data[0],
2536 e->lease_key.data[1],
2537 file_id_str_buf(fsp->file_id, &file_id_strbuf),
2538 nt_errstr(status));
2539 smb_panic("leases_db_get() failed");
2543 if (!state->got_handle_lease &&
2544 ((e_lease_type & SMB2_LEASE_HANDLE) != 0) &&
2545 !share_entry_stale_pid(e)) {
2546 state->got_handle_lease = true;
2549 if (!state->got_oplock &&
2550 (e->op_type != LEASE_OPLOCK) &&
2551 !share_entry_stale_pid(e)) {
2552 state->got_oplock = true;
2555 if (!state->have_other_lease &&
2556 !is_same_lease(fsp, e, lease) &&
2557 !share_entry_stale_pid(e)) {
2558 state->have_other_lease = true;
2561 if (e_is_lease && is_lease_stat_open(fsp->access_mask)) {
2562 return false;
2565 break_to = e_lease_type & ~state->delay_mask;
2567 if (state->will_overwrite) {
2568 break_to &= ~(SMB2_LEASE_HANDLE|SMB2_LEASE_READ);
2571 DBG_DEBUG("e_lease_type %u, will_overwrite: %u\n",
2572 (unsigned)e_lease_type,
2573 (unsigned)state->will_overwrite);
2575 if ((e_lease_type & ~break_to) == 0) {
2576 if (lease_is_breaking) {
2577 state->delay = true;
2579 return false;
2582 if (share_entry_stale_pid(e)) {
2583 return false;
2586 if (state->will_overwrite) {
2588 * If we break anyway break to NONE directly.
2589 * Otherwise vfs_set_filelen() will trigger the
2590 * break.
2592 break_to &= ~(SMB2_LEASE_READ|SMB2_LEASE_WRITE);
2595 if (!e_is_lease) {
2597 * Oplocks only support breaking to R or NONE.
2599 break_to &= ~(SMB2_LEASE_HANDLE|SMB2_LEASE_WRITE);
2602 DBG_DEBUG("breaking from %d to %d\n",
2603 (int)e_lease_type,
2604 (int)break_to);
2605 send_break_message(
2606 fsp->conn->sconn->msg_ctx, &fsp->file_id, e, break_to);
2607 if (e_lease_type & state->delay_mask) {
2608 state->delay = true;
2610 if (lease_is_breaking && !state->first_open_attempt) {
2611 state->delay = true;
2614 return false;
2617 static NTSTATUS delay_for_oplock(files_struct *fsp,
2618 int oplock_request,
2619 const struct smb2_lease *lease,
2620 struct share_mode_lock *lck,
2621 bool have_sharing_violation,
2622 uint32_t create_disposition,
2623 bool first_open_attempt)
2625 struct delay_for_oplock_state state = {
2626 .fsp = fsp,
2627 .lease = lease,
2628 .first_open_attempt = first_open_attempt,
2630 uint32_t granted;
2631 NTSTATUS status;
2632 bool ok;
2634 if (is_oplock_stat_open(fsp->access_mask)) {
2635 goto grant;
2638 state.delay_mask = have_sharing_violation ?
2639 SMB2_LEASE_HANDLE : SMB2_LEASE_WRITE;
2641 switch (create_disposition) {
2642 case FILE_SUPERSEDE:
2643 case FILE_OVERWRITE:
2644 case FILE_OVERWRITE_IF:
2645 state.will_overwrite = true;
2646 break;
2647 default:
2648 state.will_overwrite = false;
2649 break;
2652 ok = share_mode_forall_entries(lck, delay_for_oplock_fn, &state);
2653 if (!ok) {
2654 return NT_STATUS_INTERNAL_ERROR;
2657 if (state.delay) {
2658 return NT_STATUS_RETRY;
2661 grant:
2662 if (have_sharing_violation) {
2663 return NT_STATUS_SHARING_VIOLATION;
2666 if (oplock_request == LEASE_OPLOCK) {
2667 if (lease == NULL) {
2669 * The SMB2 layer should have checked this
2671 return NT_STATUS_INTERNAL_ERROR;
2674 granted = lease->lease_state;
2676 if (lp_kernel_oplocks(SNUM(fsp->conn))) {
2677 DEBUG(10, ("No lease granted because kernel oplocks are enabled\n"));
2678 granted = SMB2_LEASE_NONE;
2680 if ((granted & (SMB2_LEASE_READ|SMB2_LEASE_WRITE)) == 0) {
2681 DEBUG(10, ("No read or write lease requested\n"));
2682 granted = SMB2_LEASE_NONE;
2684 if (granted == SMB2_LEASE_WRITE) {
2685 DEBUG(10, ("pure write lease requested\n"));
2686 granted = SMB2_LEASE_NONE;
2688 if (granted == (SMB2_LEASE_WRITE|SMB2_LEASE_HANDLE)) {
2689 DEBUG(10, ("write and handle lease requested\n"));
2690 granted = SMB2_LEASE_NONE;
2692 } else {
2693 granted = map_oplock_to_lease_type(
2694 oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK);
2697 if (lp_locking(fsp->conn->params) && file_has_brlocks(fsp)) {
2698 DBG_DEBUG("file %s has byte range locks\n",
2699 fsp_str_dbg(fsp));
2700 granted &= ~SMB2_LEASE_READ;
2703 if (state.have_other_lease) {
2705 * Can grant only one writer
2707 granted &= ~SMB2_LEASE_WRITE;
2710 if ((granted & SMB2_LEASE_READ) && !(granted & SMB2_LEASE_WRITE)) {
2711 bool allow_level2 =
2712 (global_client_caps & CAP_LEVEL_II_OPLOCKS) &&
2713 lp_level2_oplocks(SNUM(fsp->conn));
2715 if (!allow_level2) {
2716 granted = SMB2_LEASE_NONE;
2720 if (oplock_request == LEASE_OPLOCK) {
2721 if (state.got_oplock) {
2722 granted &= ~SMB2_LEASE_HANDLE;
2725 fsp->oplock_type = LEASE_OPLOCK;
2727 status = grant_fsp_lease(fsp, lck, lease, granted);
2728 if (!NT_STATUS_IS_OK(status)) {
2729 return status;
2733 DBG_DEBUG("lease_state=%d\n", fsp->lease->lease.lease_state);
2734 } else {
2735 if (state.got_handle_lease) {
2736 granted = SMB2_LEASE_NONE;
2739 fsp->oplock_type = map_lease_type_to_oplock(granted);
2741 status = set_file_oplock(fsp);
2742 if (!NT_STATUS_IS_OK(status)) {
2744 * Could not get the kernel oplock
2746 fsp->oplock_type = NO_OPLOCK;
2750 if (granted & SMB2_LEASE_READ) {
2751 uint32_t acc, sh, ls;
2752 share_mode_flags_get(lck, &acc, &sh, &ls);
2753 ls |= SHARE_MODE_LEASE_READ;
2754 share_mode_flags_set(lck, acc, sh, ls, NULL);
2757 DBG_DEBUG("oplock type 0x%x on file %s\n",
2758 fsp->oplock_type, fsp_str_dbg(fsp));
2760 return NT_STATUS_OK;
2763 static NTSTATUS handle_share_mode_lease(
2764 files_struct *fsp,
2765 struct share_mode_lock *lck,
2766 uint32_t create_disposition,
2767 uint32_t access_mask,
2768 uint32_t share_access,
2769 int oplock_request,
2770 const struct smb2_lease *lease,
2771 bool first_open_attempt)
2773 bool sharing_violation = false;
2774 NTSTATUS status;
2776 status = open_mode_check(
2777 fsp->conn, fsp->file_id, lck, access_mask, share_access);
2778 if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
2779 sharing_violation = true;
2780 status = NT_STATUS_OK; /* handled later */
2783 if (!NT_STATUS_IS_OK(status)) {
2784 return status;
2787 if (oplock_request == INTERNAL_OPEN_ONLY) {
2788 if (sharing_violation) {
2789 DBG_DEBUG("Sharing violation for internal open\n");
2790 return NT_STATUS_SHARING_VIOLATION;
2794 * Internal opens never do oplocks or leases. We don't
2795 * need to go through delay_for_oplock().
2797 fsp->oplock_type = NO_OPLOCK;
2799 return NT_STATUS_OK;
2802 status = delay_for_oplock(
2803 fsp,
2804 oplock_request,
2805 lease,
2806 lck,
2807 sharing_violation,
2808 create_disposition,
2809 first_open_attempt);
2810 if (!NT_STATUS_IS_OK(status)) {
2811 return status;
2814 return NT_STATUS_OK;
2817 static bool request_timed_out(struct smb_request *req, struct timeval timeout)
2819 struct timeval now, end_time;
2820 GetTimeOfDay(&now);
2821 end_time = timeval_sum(&req->request_time, &timeout);
2822 return (timeval_compare(&end_time, &now) < 0);
2825 struct defer_open_state {
2826 struct smbXsrv_connection *xconn;
2827 uint64_t mid;
2830 static void defer_open_done(struct tevent_req *req);
2833 * Defer an open and watch a locking.tdb record
2835 * This defers an open that gets rescheduled once the locking.tdb record watch
2836 * is triggered by a change to the record.
2838 * It is used to defer opens that triggered an oplock break and for the SMB1
2839 * sharing violation delay.
2841 static void defer_open(struct share_mode_lock *lck,
2842 struct timeval timeout,
2843 struct smb_request *req,
2844 struct file_id id)
2846 struct deferred_open_record *open_rec = NULL;
2847 struct timeval abs_timeout;
2848 struct defer_open_state *watch_state;
2849 struct tevent_req *watch_req;
2850 struct timeval_buf tvbuf1, tvbuf2;
2851 struct file_id_buf fbuf;
2852 bool ok;
2854 abs_timeout = timeval_sum(&req->request_time, &timeout);
2856 DBG_DEBUG("request time [%s] timeout [%s] mid [%" PRIu64 "] "
2857 "file_id [%s]\n",
2858 timeval_str_buf(&req->request_time, false, true, &tvbuf1),
2859 timeval_str_buf(&abs_timeout, false, true, &tvbuf2),
2860 req->mid,
2861 file_id_str_buf(id, &fbuf));
2863 open_rec = talloc_zero(NULL, struct deferred_open_record);
2864 if (open_rec == NULL) {
2865 TALLOC_FREE(lck);
2866 exit_server("talloc failed");
2869 watch_state = talloc(open_rec, struct defer_open_state);
2870 if (watch_state == NULL) {
2871 exit_server("talloc failed");
2873 watch_state->xconn = req->xconn;
2874 watch_state->mid = req->mid;
2876 DBG_DEBUG("defering mid %" PRIu64 "\n", req->mid);
2878 watch_req = share_mode_watch_send(
2879 watch_state,
2880 req->sconn->ev_ctx,
2881 lck,
2882 (struct server_id){0});
2883 if (watch_req == NULL) {
2884 exit_server("Could not watch share mode record");
2886 tevent_req_set_callback(watch_req, defer_open_done, watch_state);
2888 ok = tevent_req_set_endtime(watch_req, req->sconn->ev_ctx, abs_timeout);
2889 if (!ok) {
2890 exit_server("tevent_req_set_endtime failed");
2893 ok = push_deferred_open_message_smb(req, timeout, id, open_rec);
2894 if (!ok) {
2895 TALLOC_FREE(lck);
2896 exit_server("push_deferred_open_message_smb failed");
2900 static void defer_open_done(struct tevent_req *req)
2902 struct defer_open_state *state = tevent_req_callback_data(
2903 req, struct defer_open_state);
2904 NTSTATUS status;
2905 bool ret;
2907 status = share_mode_watch_recv(req, NULL, NULL);
2908 TALLOC_FREE(req);
2909 if (!NT_STATUS_IS_OK(status)) {
2910 DEBUG(5, ("dbwrap_watched_watch_recv returned %s\n",
2911 nt_errstr(status)));
2913 * Even if it failed, retry anyway. TODO: We need a way to
2914 * tell a re-scheduled open about that error.
2918 DEBUG(10, ("scheduling mid %llu\n", (unsigned long long)state->mid));
2920 ret = schedule_deferred_open_message_smb(state->xconn, state->mid);
2921 SMB_ASSERT(ret);
2922 TALLOC_FREE(state);
2926 * Actually attempt the kernel oplock polling open.
2929 static void poll_open_fn(struct tevent_context *ev,
2930 struct tevent_timer *te,
2931 struct timeval current_time,
2932 void *private_data)
2934 struct deferred_open_record *open_rec = talloc_get_type_abort(
2935 private_data, struct deferred_open_record);
2936 bool ok;
2938 TALLOC_FREE(open_rec->watch_req);
2940 ok = schedule_deferred_open_message_smb(
2941 open_rec->xconn, open_rec->mid);
2942 if (!ok) {
2943 exit_server("schedule_deferred_open_message_smb failed");
2945 DBG_DEBUG("timer fired. Retrying open !\n");
2948 static void poll_open_done(struct tevent_req *subreq);
2951 * Reschedule an open for 1 second from now, if not timed out.
2953 static bool setup_poll_open(
2954 struct smb_request *req,
2955 struct share_mode_lock *lck,
2956 struct file_id id,
2957 struct timeval max_timeout,
2958 struct timeval interval)
2960 bool ok;
2961 struct deferred_open_record *open_rec = NULL;
2962 struct timeval endtime, next_interval;
2963 struct file_id_buf ftmp;
2965 if (request_timed_out(req, max_timeout)) {
2966 return false;
2969 open_rec = talloc_zero(NULL, struct deferred_open_record);
2970 if (open_rec == NULL) {
2971 DBG_WARNING("talloc failed\n");
2972 return false;
2974 open_rec->xconn = req->xconn;
2975 open_rec->mid = req->mid;
2978 * Make sure open_rec->te does not come later than the
2979 * request's maximum endtime.
2982 endtime = timeval_sum(&req->request_time, &max_timeout);
2983 next_interval = timeval_current_ofs(interval.tv_sec, interval.tv_usec);
2984 next_interval = timeval_min(&endtime, &next_interval);
2986 open_rec->te = tevent_add_timer(
2987 req->sconn->ev_ctx,
2988 open_rec,
2989 next_interval,
2990 poll_open_fn,
2991 open_rec);
2992 if (open_rec->te == NULL) {
2993 DBG_WARNING("tevent_add_timer failed\n");
2994 TALLOC_FREE(open_rec);
2995 return false;
2998 if (lck != NULL) {
2999 open_rec->watch_req = share_mode_watch_send(
3000 open_rec,
3001 req->sconn->ev_ctx,
3002 lck,
3003 (struct server_id) {0});
3004 if (open_rec->watch_req == NULL) {
3005 DBG_WARNING("share_mode_watch_send failed\n");
3006 TALLOC_FREE(open_rec);
3007 return false;
3009 tevent_req_set_callback(
3010 open_rec->watch_req, poll_open_done, open_rec);
3013 ok = push_deferred_open_message_smb(req, max_timeout, id, open_rec);
3014 if (!ok) {
3015 DBG_WARNING("push_deferred_open_message_smb failed\n");
3016 TALLOC_FREE(open_rec);
3017 return false;
3020 DBG_DEBUG("poll request time [%s] mid [%" PRIu64 "] file_id [%s]\n",
3021 timeval_string(talloc_tos(), &req->request_time, false),
3022 req->mid,
3023 file_id_str_buf(id, &ftmp));
3025 return true;
3028 static void poll_open_done(struct tevent_req *subreq)
3030 struct deferred_open_record *open_rec = tevent_req_callback_data(
3031 subreq, struct deferred_open_record);
3032 NTSTATUS status;
3033 bool ok;
3035 status = share_mode_watch_recv(subreq, NULL, NULL);
3036 TALLOC_FREE(subreq);
3037 open_rec->watch_req = NULL;
3038 TALLOC_FREE(open_rec->te);
3040 DBG_DEBUG("dbwrap_watched_watch_recv returned %s\n",
3041 nt_errstr(status));
3043 ok = schedule_deferred_open_message_smb(
3044 open_rec->xconn, open_rec->mid);
3045 if (!ok) {
3046 exit_server("schedule_deferred_open_message_smb failed");
3050 bool defer_smb1_sharing_violation(struct smb_request *req)
3052 bool ok;
3053 int timeout_usecs;
3055 if (!lp_defer_sharing_violations()) {
3056 return false;
3060 * Try every 200msec up to (by default) one second. To be
3061 * precise, according to behaviour note <247> in [MS-CIFS],
3062 * the server tries 5 times. But up to one second should be
3063 * close enough.
3066 timeout_usecs = lp_parm_int(
3067 SNUM(req->conn),
3068 "smbd",
3069 "sharedelay",
3070 SHARING_VIOLATION_USEC_WAIT);
3072 ok = setup_poll_open(
3073 req,
3074 NULL,
3075 (struct file_id) {0},
3076 (struct timeval) { .tv_usec = timeout_usecs },
3077 (struct timeval) { .tv_usec = 200000 });
3078 return ok;
3081 /****************************************************************************
3082 On overwrite open ensure that the attributes match.
3083 ****************************************************************************/
3085 static bool open_match_attributes(connection_struct *conn,
3086 uint32_t old_dos_attr,
3087 uint32_t new_dos_attr,
3088 mode_t new_unx_mode,
3089 mode_t *returned_unx_mode)
3091 uint32_t noarch_old_dos_attr, noarch_new_dos_attr;
3093 noarch_old_dos_attr = (old_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
3094 noarch_new_dos_attr = (new_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
3096 if((noarch_old_dos_attr == 0 && noarch_new_dos_attr != 0) ||
3097 (noarch_old_dos_attr != 0 && ((noarch_old_dos_attr & noarch_new_dos_attr) == noarch_old_dos_attr))) {
3098 *returned_unx_mode = new_unx_mode;
3099 } else {
3100 *returned_unx_mode = (mode_t)0;
3103 DEBUG(10,("open_match_attributes: old_dos_attr = 0x%x, "
3104 "new_dos_attr = 0x%x "
3105 "returned_unx_mode = 0%o\n",
3106 (unsigned int)old_dos_attr,
3107 (unsigned int)new_dos_attr,
3108 (unsigned int)*returned_unx_mode ));
3110 /* If we're mapping SYSTEM and HIDDEN ensure they match. */
3111 if (lp_map_system(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
3112 if ((old_dos_attr & FILE_ATTRIBUTE_SYSTEM) &&
3113 !(new_dos_attr & FILE_ATTRIBUTE_SYSTEM)) {
3114 return False;
3117 if (lp_map_hidden(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
3118 if ((old_dos_attr & FILE_ATTRIBUTE_HIDDEN) &&
3119 !(new_dos_attr & FILE_ATTRIBUTE_HIDDEN)) {
3120 return False;
3123 return True;
3126 static void schedule_defer_open(struct share_mode_lock *lck,
3127 struct file_id id,
3128 struct smb_request *req)
3130 /* This is a relative time, added to the absolute
3131 request_time value to get the absolute timeout time.
3132 Note that if this is the second or greater time we enter
3133 this codepath for this particular request mid then
3134 request_time is left as the absolute time of the *first*
3135 time this request mid was processed. This is what allows
3136 the request to eventually time out. */
3138 struct timeval timeout;
3140 /* Normally the smbd we asked should respond within
3141 * OPLOCK_BREAK_TIMEOUT seconds regardless of whether
3142 * the client did, give twice the timeout as a safety
3143 * measure here in case the other smbd is stuck
3144 * somewhere else. */
3146 timeout = timeval_set(OPLOCK_BREAK_TIMEOUT*2, 0);
3148 if (request_timed_out(req, timeout)) {
3149 return;
3152 defer_open(lck, timeout, req, id);
3155 /****************************************************************************
3156 Reschedule an open call that went asynchronous.
3157 ****************************************************************************/
3159 static void schedule_async_open_timer(struct tevent_context *ev,
3160 struct tevent_timer *te,
3161 struct timeval current_time,
3162 void *private_data)
3164 exit_server("async open timeout");
3167 static void schedule_async_open(struct smb_request *req)
3169 struct deferred_open_record *open_rec = NULL;
3170 struct timeval timeout = timeval_set(20, 0);
3171 bool ok;
3173 if (request_timed_out(req, timeout)) {
3174 return;
3177 open_rec = talloc_zero(NULL, struct deferred_open_record);
3178 if (open_rec == NULL) {
3179 exit_server("deferred_open_record_create failed");
3181 open_rec->async_open = true;
3183 ok = push_deferred_open_message_smb(
3184 req, timeout, (struct file_id){0}, open_rec);
3185 if (!ok) {
3186 exit_server("push_deferred_open_message_smb failed");
3189 open_rec->te = tevent_add_timer(req->sconn->ev_ctx,
3190 req,
3191 timeval_current_ofs(20, 0),
3192 schedule_async_open_timer,
3193 open_rec);
3194 if (open_rec->te == NULL) {
3195 exit_server("tevent_add_timer failed");
3199 /****************************************************************************
3200 Work out what access_mask to use from what the client sent us.
3201 ****************************************************************************/
3203 static NTSTATUS smbd_calculate_maximum_allowed_access(
3204 connection_struct *conn,
3205 struct files_struct *dirfsp,
3206 const struct smb_filename *smb_fname,
3207 bool use_privs,
3208 uint32_t *p_access_mask)
3210 struct security_descriptor *sd;
3211 uint32_t access_granted;
3212 NTSTATUS status;
3214 SMB_ASSERT(dirfsp == conn->cwd_fsp);
3216 if (!use_privs && (get_current_uid(conn) == (uid_t)0)) {
3217 *p_access_mask |= FILE_GENERIC_ALL;
3218 return NT_STATUS_OK;
3221 status = SMB_VFS_GET_NT_ACL_AT(conn,
3222 dirfsp,
3223 smb_fname,
3224 (SECINFO_OWNER |
3225 SECINFO_GROUP |
3226 SECINFO_DACL),
3227 talloc_tos(),
3228 &sd);
3230 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
3232 * File did not exist
3234 *p_access_mask = FILE_GENERIC_ALL;
3235 return NT_STATUS_OK;
3237 if (!NT_STATUS_IS_OK(status)) {
3238 DEBUG(10,("Could not get acl on file %s: %s\n",
3239 smb_fname_str_dbg(smb_fname),
3240 nt_errstr(status)));
3241 return NT_STATUS_ACCESS_DENIED;
3245 * If we can access the path to this file, by
3246 * default we have FILE_READ_ATTRIBUTES from the
3247 * containing directory. See the section:
3248 * "Algorithm to Check Access to an Existing File"
3249 * in MS-FSA.pdf.
3251 * se_file_access_check()
3252 * also takes care of owner WRITE_DAC and READ_CONTROL.
3254 status = se_file_access_check(sd,
3255 get_current_nttok(conn),
3256 use_privs,
3257 (*p_access_mask & ~FILE_READ_ATTRIBUTES),
3258 &access_granted);
3260 TALLOC_FREE(sd);
3262 if (!NT_STATUS_IS_OK(status)) {
3263 DEBUG(10, ("Access denied on file %s: "
3264 "when calculating maximum access\n",
3265 smb_fname_str_dbg(smb_fname)));
3266 return NT_STATUS_ACCESS_DENIED;
3268 *p_access_mask = (access_granted | FILE_READ_ATTRIBUTES);
3270 if (!(access_granted & DELETE_ACCESS)) {
3271 if (can_delete_file_in_directory(conn,
3272 conn->cwd_fsp,
3273 smb_fname))
3275 *p_access_mask |= DELETE_ACCESS;
3279 return NT_STATUS_OK;
3282 NTSTATUS smbd_calculate_access_mask(connection_struct *conn,
3283 struct files_struct *dirfsp,
3284 const struct smb_filename *smb_fname,
3285 bool use_privs,
3286 uint32_t access_mask,
3287 uint32_t *access_mask_out)
3289 NTSTATUS status;
3290 uint32_t orig_access_mask = access_mask;
3291 uint32_t rejected_share_access;
3293 SMB_ASSERT(dirfsp == conn->cwd_fsp);
3295 if (access_mask & SEC_MASK_INVALID) {
3296 DBG_DEBUG("access_mask [%8x] contains invalid bits\n",
3297 access_mask);
3298 return NT_STATUS_ACCESS_DENIED;
3302 * Convert GENERIC bits to specific bits.
3305 se_map_generic(&access_mask, &file_generic_mapping);
3307 /* Calculate MAXIMUM_ALLOWED_ACCESS if requested. */
3308 if (access_mask & MAXIMUM_ALLOWED_ACCESS) {
3310 status = smbd_calculate_maximum_allowed_access(conn,
3311 dirfsp,
3312 smb_fname,
3313 use_privs,
3314 &access_mask);
3316 if (!NT_STATUS_IS_OK(status)) {
3317 return status;
3320 access_mask &= conn->share_access;
3323 rejected_share_access = access_mask & ~(conn->share_access);
3325 if (rejected_share_access) {
3326 DEBUG(10, ("smbd_calculate_access_mask: Access denied on "
3327 "file %s: rejected by share access mask[0x%08X] "
3328 "orig[0x%08X] mapped[0x%08X] reject[0x%08X]\n",
3329 smb_fname_str_dbg(smb_fname),
3330 conn->share_access,
3331 orig_access_mask, access_mask,
3332 rejected_share_access));
3333 return NT_STATUS_ACCESS_DENIED;
3336 *access_mask_out = access_mask;
3337 return NT_STATUS_OK;
3340 /****************************************************************************
3341 Remove the deferred open entry under lock.
3342 ****************************************************************************/
3344 /****************************************************************************
3345 Return true if this is a state pointer to an asynchronous create.
3346 ****************************************************************************/
3348 bool is_deferred_open_async(const struct deferred_open_record *rec)
3350 return rec->async_open;
3353 static bool clear_ads(uint32_t create_disposition)
3355 bool ret = false;
3357 switch (create_disposition) {
3358 case FILE_SUPERSEDE:
3359 case FILE_OVERWRITE_IF:
3360 case FILE_OVERWRITE:
3361 ret = true;
3362 break;
3363 default:
3364 break;
3366 return ret;
3369 static int disposition_to_open_flags(uint32_t create_disposition)
3371 int ret = 0;
3374 * Currently we're using FILE_SUPERSEDE as the same as
3375 * FILE_OVERWRITE_IF but they really are
3376 * different. FILE_SUPERSEDE deletes an existing file
3377 * (requiring delete access) then recreates it.
3380 switch (create_disposition) {
3381 case FILE_SUPERSEDE:
3382 case FILE_OVERWRITE_IF:
3384 * If file exists replace/overwrite. If file doesn't
3385 * exist create.
3387 ret = O_CREAT|O_TRUNC;
3388 break;
3390 case FILE_OPEN:
3392 * If file exists open. If file doesn't exist error.
3394 ret = 0;
3395 break;
3397 case FILE_OVERWRITE:
3399 * If file exists overwrite. If file doesn't exist
3400 * error.
3402 ret = O_TRUNC;
3403 break;
3405 case FILE_CREATE:
3407 * If file exists error. If file doesn't exist create.
3409 ret = O_CREAT|O_EXCL;
3410 break;
3412 case FILE_OPEN_IF:
3414 * If file exists open. If file doesn't exist create.
3416 ret = O_CREAT;
3417 break;
3419 return ret;
3422 static int calculate_open_access_flags(uint32_t access_mask,
3423 uint32_t private_flags)
3425 bool need_write, need_read;
3428 * Note that we ignore the append flag as append does not
3429 * mean the same thing under DOS and Unix.
3432 need_write = (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA));
3433 if (!need_write) {
3434 return O_RDONLY;
3437 /* DENY_DOS opens are always underlying read-write on the
3438 file handle, no matter what the requested access mask
3439 says. */
3441 need_read =
3442 ((private_flags & NTCREATEX_FLAG_DENY_DOS) ||
3443 access_mask & (FILE_READ_ATTRIBUTES|FILE_READ_DATA|
3444 FILE_READ_EA|FILE_EXECUTE));
3446 if (!need_read) {
3447 return O_WRONLY;
3449 return O_RDWR;
3452 /****************************************************************************
3453 Open a file with a share mode. Passed in an already created files_struct *.
3454 ****************************************************************************/
3456 static NTSTATUS open_file_ntcreate(connection_struct *conn,
3457 struct smb_request *req,
3458 uint32_t access_mask, /* access bits (FILE_READ_DATA etc.) */
3459 uint32_t share_access, /* share constants (FILE_SHARE_READ etc) */
3460 uint32_t create_disposition, /* FILE_OPEN_IF etc. */
3461 uint32_t create_options, /* options such as delete on close. */
3462 uint32_t new_dos_attributes, /* attributes used for new file. */
3463 int oplock_request, /* internal Samba oplock codes. */
3464 const struct smb2_lease *lease,
3465 /* Information (FILE_EXISTS etc.) */
3466 uint32_t private_flags, /* Samba specific flags. */
3467 struct smb_filename *parent_dir_fname, /* parent. */
3468 struct smb_filename *smb_fname_atname, /* atname relative to parent. */
3469 int *pinfo,
3470 files_struct *fsp)
3472 struct smb_filename *smb_fname = fsp->fsp_name;
3473 int flags=0;
3474 int flags2=0;
3475 bool file_existed = VALID_STAT(smb_fname->st);
3476 bool def_acl = False;
3477 bool posix_open = False;
3478 bool new_file_created = False;
3479 bool first_open_attempt = true;
3480 NTSTATUS fsp_open = NT_STATUS_ACCESS_DENIED;
3481 mode_t new_unx_mode = (mode_t)0;
3482 mode_t unx_mode = (mode_t)0;
3483 int info;
3484 uint32_t existing_dos_attributes = 0;
3485 struct share_mode_lock *lck = NULL;
3486 uint32_t open_access_mask = access_mask;
3487 NTSTATUS status;
3488 SMB_STRUCT_STAT saved_stat = smb_fname->st;
3489 struct timespec old_write_time;
3490 bool setup_poll = false;
3491 bool ok;
3493 if (conn->printer) {
3495 * Printers are handled completely differently.
3496 * Most of the passed parameters are ignored.
3499 if (pinfo) {
3500 *pinfo = FILE_WAS_CREATED;
3503 DEBUG(10, ("open_file_ntcreate: printer open fname=%s\n",
3504 smb_fname_str_dbg(smb_fname)));
3506 if (!req) {
3507 DEBUG(0,("open_file_ntcreate: printer open without "
3508 "an SMB request!\n"));
3509 return NT_STATUS_INTERNAL_ERROR;
3512 return print_spool_open(fsp, smb_fname->base_name,
3513 req->vuid);
3516 if (new_dos_attributes & FILE_FLAG_POSIX_SEMANTICS) {
3517 posix_open = True;
3518 unx_mode = (mode_t)(new_dos_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
3519 new_dos_attributes = 0;
3520 } else {
3521 /* Windows allows a new file to be created and
3522 silently removes a FILE_ATTRIBUTE_DIRECTORY
3523 sent by the client. Do the same. */
3525 new_dos_attributes &= ~FILE_ATTRIBUTE_DIRECTORY;
3527 /* We add FILE_ATTRIBUTE_ARCHIVE to this as this mode is only used if the file is
3528 * created new. */
3529 unx_mode = unix_mode(conn, new_dos_attributes | FILE_ATTRIBUTE_ARCHIVE,
3530 smb_fname, parent_dir_fname);
3533 DEBUG(10, ("open_file_ntcreate: fname=%s, dos_attrs=0x%x "
3534 "access_mask=0x%x share_access=0x%x "
3535 "create_disposition = 0x%x create_options=0x%x "
3536 "unix mode=0%o oplock_request=%d private_flags = 0x%x\n",
3537 smb_fname_str_dbg(smb_fname), new_dos_attributes,
3538 access_mask, share_access, create_disposition,
3539 create_options, (unsigned int)unx_mode, oplock_request,
3540 (unsigned int)private_flags));
3542 if (req == NULL) {
3543 /* Ensure req == NULL means INTERNAL_OPEN_ONLY */
3544 SMB_ASSERT(oplock_request == INTERNAL_OPEN_ONLY);
3545 } else {
3546 /* And req != NULL means no INTERNAL_OPEN_ONLY */
3547 SMB_ASSERT(((oplock_request & INTERNAL_OPEN_ONLY) == 0));
3551 * Only non-internal opens can be deferred at all
3554 if (req) {
3555 struct deferred_open_record *open_rec;
3556 if (get_deferred_open_message_state(req, NULL, &open_rec)) {
3558 /* If it was an async create retry, the file
3559 didn't exist. */
3561 if (is_deferred_open_async(open_rec)) {
3562 SET_STAT_INVALID(smb_fname->st);
3563 file_existed = false;
3566 /* Ensure we don't reprocess this message. */
3567 remove_deferred_open_message_smb(req->xconn, req->mid);
3569 first_open_attempt = false;
3573 if (!posix_open) {
3574 new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
3575 if (file_existed) {
3577 * Only use stored DOS attributes for checks
3578 * against requested attributes (below via
3579 * open_match_attributes()), cf bug #11992
3580 * for details. -slow
3582 uint32_t attr = 0;
3584 status = SMB_VFS_FGET_DOS_ATTRIBUTES(conn, smb_fname->fsp, &attr);
3585 if (NT_STATUS_IS_OK(status)) {
3586 existing_dos_attributes = attr;
3591 /* ignore any oplock requests if oplocks are disabled */
3592 if (!lp_oplocks(SNUM(conn)) ||
3593 IS_VETO_OPLOCK_PATH(conn, smb_fname->base_name)) {
3594 /* Mask off everything except the private Samba bits. */
3595 oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
3598 /* this is for OS/2 long file names - say we don't support them */
3599 if (req != NULL && !req->posix_pathnames &&
3600 strstr(smb_fname->base_name,".+,;=[].")) {
3601 /* OS/2 Workplace shell fix may be main code stream in a later
3602 * release. */
3603 DEBUG(5,("open_file_ntcreate: OS/2 long filenames are not "
3604 "supported.\n"));
3605 if (use_nt_status()) {
3606 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3608 return NT_STATUS_DOS(ERRDOS, ERRcannotopen);
3611 switch( create_disposition ) {
3612 case FILE_OPEN:
3613 /* If file exists open. If file doesn't exist error. */
3614 if (!file_existed) {
3615 DEBUG(5,("open_file_ntcreate: FILE_OPEN "
3616 "requested for file %s and file "
3617 "doesn't exist.\n",
3618 smb_fname_str_dbg(smb_fname)));
3619 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3621 break;
3623 case FILE_OVERWRITE:
3624 /* If file exists overwrite. If file doesn't exist
3625 * error. */
3626 if (!file_existed) {
3627 DEBUG(5,("open_file_ntcreate: FILE_OVERWRITE "
3628 "requested for file %s and file "
3629 "doesn't exist.\n",
3630 smb_fname_str_dbg(smb_fname) ));
3631 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3633 break;
3635 case FILE_CREATE:
3636 /* If file exists error. If file doesn't exist
3637 * create. */
3638 if (file_existed) {
3639 DEBUG(5,("open_file_ntcreate: FILE_CREATE "
3640 "requested for file %s and file "
3641 "already exists.\n",
3642 smb_fname_str_dbg(smb_fname)));
3643 if (S_ISDIR(smb_fname->st.st_ex_mode)) {
3644 return NT_STATUS_FILE_IS_A_DIRECTORY;
3645 } else {
3646 return NT_STATUS_OBJECT_NAME_COLLISION;
3649 break;
3651 case FILE_SUPERSEDE:
3652 case FILE_OVERWRITE_IF:
3653 case FILE_OPEN_IF:
3654 break;
3655 default:
3656 return NT_STATUS_INVALID_PARAMETER;
3659 flags2 = disposition_to_open_flags(create_disposition);
3661 /* We only care about matching attributes on file exists and
3662 * overwrite. */
3664 if (!posix_open && file_existed &&
3665 ((create_disposition == FILE_OVERWRITE) ||
3666 (create_disposition == FILE_OVERWRITE_IF))) {
3667 if (!open_match_attributes(conn, existing_dos_attributes,
3668 new_dos_attributes,
3669 unx_mode, &new_unx_mode)) {
3670 DEBUG(5,("open_file_ntcreate: attributes mismatch "
3671 "for file %s (%x %x) (0%o, 0%o)\n",
3672 smb_fname_str_dbg(smb_fname),
3673 existing_dos_attributes,
3674 new_dos_attributes,
3675 (unsigned int)smb_fname->st.st_ex_mode,
3676 (unsigned int)unx_mode ));
3677 return NT_STATUS_ACCESS_DENIED;
3681 status = smbd_calculate_access_mask(conn,
3682 conn->cwd_fsp,
3683 smb_fname,
3684 false,
3685 access_mask,
3686 &access_mask);
3687 if (!NT_STATUS_IS_OK(status)) {
3688 DEBUG(10, ("open_file_ntcreate: smbd_calculate_access_mask "
3689 "on file %s returned %s\n",
3690 smb_fname_str_dbg(smb_fname), nt_errstr(status)));
3691 return status;
3694 open_access_mask = access_mask;
3696 if (flags2 & O_TRUNC) {
3697 open_access_mask |= FILE_WRITE_DATA; /* This will cause oplock breaks. */
3700 if (file_existed) {
3702 * stat opens on existing files don't get oplocks.
3703 * They can get leases.
3705 * Note that we check for stat open on the *open_access_mask*,
3706 * i.e. the access mask we actually used to do the open,
3707 * not the one the client asked for (which is in
3708 * fsp->access_mask). This is due to the fact that
3709 * FILE_OVERWRITE and FILE_OVERWRITE_IF add in O_TRUNC,
3710 * which adds FILE_WRITE_DATA to open_access_mask.
3712 if (is_oplock_stat_open(open_access_mask) && lease == NULL) {
3713 oplock_request = NO_OPLOCK;
3717 DEBUG(10, ("open_file_ntcreate: fname=%s, after mapping "
3718 "access_mask=0x%x\n", smb_fname_str_dbg(smb_fname),
3719 access_mask));
3722 * Note that we ignore the append flag as append does not
3723 * mean the same thing under DOS and Unix.
3726 flags = calculate_open_access_flags(access_mask, private_flags);
3729 * Currently we only look at FILE_WRITE_THROUGH for create options.
3732 #if defined(O_SYNC)
3733 if ((create_options & FILE_WRITE_THROUGH) && lp_strict_sync(SNUM(conn))) {
3734 flags2 |= O_SYNC;
3736 #endif /* O_SYNC */
3738 if (posix_open && (access_mask & FILE_APPEND_DATA)) {
3739 flags2 |= O_APPEND;
3742 if (!posix_open && !CAN_WRITE(conn)) {
3744 * We should really return a permission denied error if either
3745 * O_CREAT or O_TRUNC are set, but for compatibility with
3746 * older versions of Samba we just AND them out.
3748 flags2 &= ~(O_CREAT|O_TRUNC);
3752 * With kernel oplocks the open breaking an oplock
3753 * blocks until the oplock holder has given up the
3754 * oplock or closed the file. We prevent this by always
3755 * trying to open the file with O_NONBLOCK (see "man
3756 * fcntl" on Linux).
3758 * If a process that doesn't use the smbd open files
3759 * database or communication methods holds a kernel
3760 * oplock we must periodically poll for available open
3761 * using O_NONBLOCK.
3763 flags2 |= O_NONBLOCK;
3766 * Ensure we can't write on a read-only share or file.
3769 if (flags != O_RDONLY && file_existed &&
3770 (!CAN_WRITE(conn) || IS_DOS_READONLY(existing_dos_attributes))) {
3771 DEBUG(5,("open_file_ntcreate: write access requested for "
3772 "file %s on read only %s\n",
3773 smb_fname_str_dbg(smb_fname),
3774 !CAN_WRITE(conn) ? "share" : "file" ));
3775 return NT_STATUS_ACCESS_DENIED;
3778 if (VALID_STAT(smb_fname->st)) {
3780 * Only try and create a file id before open
3781 * for an existing file. For a file being created
3782 * this won't do anything useful until the file
3783 * exists and has a valid stat struct.
3785 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
3787 fh_set_private_options(fsp->fh, private_flags);
3788 fsp->access_mask = open_access_mask; /* We change this to the
3789 * requested access_mask after
3790 * the open is done. */
3791 if (posix_open) {
3792 fsp->posix_flags |= FSP_POSIX_FLAGS_ALL;
3795 if ((create_options & FILE_DELETE_ON_CLOSE) &&
3796 (flags2 & O_CREAT) &&
3797 !file_existed) {
3798 /* Delete on close semantics for new files. */
3799 status = can_set_delete_on_close(fsp,
3800 new_dos_attributes);
3801 if (!NT_STATUS_IS_OK(status)) {
3802 fd_close(fsp);
3803 return status;
3808 * Ensure we pay attention to default ACLs on directories if required.
3811 if ((flags2 & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
3812 (def_acl = directory_has_default_acl_fsp(parent_dir_fname->fsp)))
3814 unx_mode = (0777 & lp_create_mask(SNUM(conn)));
3817 DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o, "
3818 "access_mask = 0x%x, open_access_mask = 0x%x\n",
3819 (unsigned int)flags, (unsigned int)flags2,
3820 (unsigned int)unx_mode, (unsigned int)access_mask,
3821 (unsigned int)open_access_mask));
3823 fsp_open = open_file(fsp,
3824 req,
3825 parent_dir_fname,
3826 flags|flags2,
3827 unx_mode,
3828 access_mask,
3829 open_access_mask,
3830 private_flags,
3831 &new_file_created);
3832 if (NT_STATUS_EQUAL(fsp_open, NT_STATUS_NETWORK_BUSY)) {
3833 if (file_existed && S_ISFIFO(fsp->fsp_name->st.st_ex_mode)) {
3834 DEBUG(10, ("FIFO busy\n"));
3835 return NT_STATUS_NETWORK_BUSY;
3837 if (req == NULL) {
3838 DEBUG(10, ("Internal open busy\n"));
3839 return NT_STATUS_NETWORK_BUSY;
3842 * This handles the kernel oplock case:
3844 * the file has an active kernel oplock and the open() returned
3845 * EWOULDBLOCK/EAGAIN which maps to NETWORK_BUSY.
3847 * "Samba locking.tdb oplocks" are handled below after acquiring
3848 * the sharemode lock with get_share_mode_lock().
3850 setup_poll = true;
3853 if (NT_STATUS_EQUAL(fsp_open, NT_STATUS_RETRY)) {
3855 * EINTR from the open(2) syscall. Just setup a retry
3856 * in a bit. We can't use the sys_write() tight retry
3857 * loop here, as we might have to actually deal with
3858 * lease-break signals to avoid a deadlock.
3860 setup_poll = true;
3863 if (setup_poll) {
3865 * From here on we assume this is an oplock break triggered
3868 lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
3870 if ((lck != NULL) && !validate_oplock_types(lck)) {
3871 smb_panic("validate_oplock_types failed");
3875 * Retry once a second. If there's a share_mode_lock
3876 * around, also wait for it in case it was smbd
3877 * holding that kernel oplock that can quickly tell us
3878 * the oplock got removed.
3881 setup_poll_open(
3882 req,
3883 lck,
3884 fsp->file_id,
3885 timeval_set(OPLOCK_BREAK_TIMEOUT*2, 0),
3886 timeval_set(1, 0));
3888 TALLOC_FREE(lck);
3890 return NT_STATUS_SHARING_VIOLATION;
3893 if (!NT_STATUS_IS_OK(fsp_open)) {
3894 bool wait_for_aio = NT_STATUS_EQUAL(
3895 fsp_open, NT_STATUS_MORE_PROCESSING_REQUIRED);
3896 if (wait_for_aio) {
3897 schedule_async_open(req);
3899 return fsp_open;
3902 if (new_file_created) {
3904 * As we atomically create using O_CREAT|O_EXCL,
3905 * then if new_file_created is true, then
3906 * file_existed *MUST* have been false (even
3907 * if the file was previously detected as being
3908 * there).
3910 file_existed = false;
3913 if (file_existed && !check_same_dev_ino(&saved_stat, &smb_fname->st)) {
3915 * The file did exist, but some other (local or NFS)
3916 * process either renamed/unlinked and re-created the
3917 * file with different dev/ino after we walked the path,
3918 * but before we did the open. We could retry the
3919 * open but it's a rare enough case it's easier to
3920 * just fail the open to prevent creating any problems
3921 * in the open file db having the wrong dev/ino key.
3923 fd_close(fsp);
3924 DBG_WARNING("file %s - dev/ino mismatch. "
3925 "Old (dev=%ju, ino=%ju). "
3926 "New (dev=%ju, ino=%ju). Failing open "
3927 "with NT_STATUS_ACCESS_DENIED.\n",
3928 smb_fname_str_dbg(smb_fname),
3929 (uintmax_t)saved_stat.st_ex_dev,
3930 (uintmax_t)saved_stat.st_ex_ino,
3931 (uintmax_t)smb_fname->st.st_ex_dev,
3932 (uintmax_t)smb_fname->st.st_ex_ino);
3933 return NT_STATUS_ACCESS_DENIED;
3936 old_write_time = smb_fname->st.st_ex_mtime;
3939 * Deal with the race condition where two smbd's detect the
3940 * file doesn't exist and do the create at the same time. One
3941 * of them will win and set a share mode, the other (ie. this
3942 * one) should check if the requested share mode for this
3943 * create is allowed.
3947 * Now the file exists and fsp is successfully opened,
3948 * fsp->dev and fsp->inode are valid and should replace the
3949 * dev=0,inode=0 from a non existent file. Spotted by
3950 * Nadav Danieli <nadavd@exanet.com>. JRA.
3953 lck = get_share_mode_lock(talloc_tos(), fsp->file_id,
3954 conn->connectpath,
3955 smb_fname, &old_write_time);
3957 if (lck == NULL) {
3958 DEBUG(0, ("open_file_ntcreate: Could not get share "
3959 "mode lock for %s\n",
3960 smb_fname_str_dbg(smb_fname)));
3961 fd_close(fsp);
3962 return NT_STATUS_SHARING_VIOLATION;
3965 /* Get the types we need to examine. */
3966 if (!validate_oplock_types(lck)) {
3967 smb_panic("validate_oplock_types failed");
3970 if (has_delete_on_close(lck, fsp->name_hash)) {
3971 TALLOC_FREE(lck);
3972 fd_close(fsp);
3973 return NT_STATUS_DELETE_PENDING;
3976 status = handle_share_mode_lease(
3977 fsp,
3978 lck,
3979 create_disposition,
3980 access_mask,
3981 share_access,
3982 oplock_request,
3983 lease,
3984 first_open_attempt);
3986 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
3987 schedule_defer_open(lck, fsp->file_id, req);
3988 TALLOC_FREE(lck);
3989 fd_close(fsp);
3990 return NT_STATUS_SHARING_VIOLATION;
3993 if (!NT_STATUS_IS_OK(status)) {
3994 TALLOC_FREE(lck);
3995 fd_close(fsp);
3996 return status;
3999 share_mode_flags_restrict(lck, access_mask, share_access, 0);
4001 ok = set_share_mode(
4002 lck,
4003 fsp,
4004 get_current_uid(fsp->conn),
4005 req ? req->mid : 0,
4006 fsp->oplock_type,
4007 share_access,
4008 access_mask);
4009 if (!ok) {
4010 if (fsp->oplock_type == LEASE_OPLOCK) {
4011 status = remove_lease_if_stale(
4012 lck,
4013 fsp_client_guid(fsp),
4014 &fsp->lease->lease.lease_key);
4015 if (!NT_STATUS_IS_OK(status)) {
4016 DBG_WARNING("remove_lease_if_stale "
4017 "failed: %s\n",
4018 nt_errstr(status));
4021 TALLOC_FREE(lck);
4022 fd_close(fsp);
4023 return NT_STATUS_NO_MEMORY;
4026 /* Should we atomically (to the client at least) truncate ? */
4027 if ((!new_file_created) &&
4028 (flags2 & O_TRUNC) &&
4029 (S_ISREG(fsp->fsp_name->st.st_ex_mode))) {
4030 int ret;
4032 ret = SMB_VFS_FTRUNCATE(fsp, 0);
4033 if (ret != 0) {
4034 status = map_nt_error_from_unix(errno);
4035 del_share_mode(lck, fsp);
4036 TALLOC_FREE(lck);
4037 fd_close(fsp);
4038 return status;
4040 notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
4041 FILE_NOTIFY_CHANGE_SIZE
4042 | FILE_NOTIFY_CHANGE_ATTRIBUTES,
4043 fsp->fsp_name->base_name);
4047 * We have the share entry *locked*.....
4050 /* Delete streams if create_disposition requires it */
4051 if (!new_file_created && clear_ads(create_disposition) &&
4052 !is_ntfs_stream_smb_fname(smb_fname)) {
4053 status = delete_all_streams(conn, smb_fname);
4054 if (!NT_STATUS_IS_OK(status)) {
4055 del_share_mode(lck, fsp);
4056 TALLOC_FREE(lck);
4057 fd_close(fsp);
4058 return status;
4062 if (!fsp->fsp_flags.is_pathref &&
4063 fsp_get_io_fd(fsp) != -1 &&
4064 lp_kernel_share_modes(SNUM(conn)))
4066 int ret_flock;
4068 * Beware: streams implementing VFS modules may
4069 * implement streams in a way that fsp will have the
4070 * basefile open in the fsp fd, so lacking a distinct
4071 * fd for the stream kernel_flock will apply on the
4072 * basefile which is wrong. The actual check is
4073 * deferred to the VFS module implementing the
4074 * kernel_flock call.
4076 ret_flock = SMB_VFS_KERNEL_FLOCK(fsp, share_access, access_mask);
4077 if(ret_flock == -1 ){
4079 del_share_mode(lck, fsp);
4080 TALLOC_FREE(lck);
4081 fd_close(fsp);
4083 return NT_STATUS_SHARING_VIOLATION;
4086 fsp->fsp_flags.kernel_share_modes_taken = true;
4090 * At this point onwards, we can guarantee that the share entry
4091 * is locked, whether we created the file or not, and that the
4092 * deny mode is compatible with all current opens.
4096 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
4097 * but we don't have to store this - just ignore it on access check.
4099 if (conn->sconn->using_smb2) {
4101 * SMB2 doesn't return it (according to Microsoft tests).
4102 * Test Case: TestSuite_ScenarioNo009GrantedAccessTestS0
4103 * File created with access = 0x7 (Read, Write, Delete)
4104 * Query Info on file returns 0x87 (Read, Write, Delete, Read Attributes)
4106 fsp->access_mask = access_mask;
4107 } else {
4108 /* But SMB1 does. */
4109 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
4112 if (new_file_created) {
4113 info = FILE_WAS_CREATED;
4114 } else {
4115 if (flags2 & O_TRUNC) {
4116 info = FILE_WAS_OVERWRITTEN;
4117 } else {
4118 info = FILE_WAS_OPENED;
4122 if (pinfo) {
4123 *pinfo = info;
4126 /* Handle strange delete on close create semantics. */
4127 if (create_options & FILE_DELETE_ON_CLOSE) {
4128 if (!new_file_created) {
4129 status = can_set_delete_on_close(fsp,
4130 existing_dos_attributes);
4132 if (!NT_STATUS_IS_OK(status)) {
4133 /* Remember to delete the mode we just added. */
4134 del_share_mode(lck, fsp);
4135 TALLOC_FREE(lck);
4136 fd_close(fsp);
4137 return status;
4140 /* Note that here we set the *initial* delete on close flag,
4141 not the regular one. The magic gets handled in close. */
4142 fsp->fsp_flags.initial_delete_on_close = true;
4146 * If we created a file and it's not a stream, this is the point where
4147 * we set the itime (aka invented time) that get's stored in the DOS
4148 * attribute xattr. The value is going to be either what the filesystem
4149 * provided or a copy of the creation date.
4151 * Either way, we turn the itime into a File-ID, unless the filesystem
4152 * provided one (unlikely).
4154 if (info == FILE_WAS_CREATED && !is_named_stream(smb_fname)) {
4155 smb_fname->st.st_ex_iflags &= ~ST_EX_IFLAG_CALCULATED_ITIME;
4157 if (lp_store_dos_attributes(SNUM(conn)) &&
4158 smb_fname->st.st_ex_iflags & ST_EX_IFLAG_CALCULATED_FILE_ID)
4160 uint64_t file_id;
4162 file_id = make_file_id_from_itime(&smb_fname->st);
4163 update_stat_ex_file_id(&smb_fname->st, file_id);
4167 if (info != FILE_WAS_OPENED) {
4168 /* Overwritten files should be initially set as archive */
4169 if ((info == FILE_WAS_OVERWRITTEN && lp_map_archive(SNUM(conn))) ||
4170 lp_store_dos_attributes(SNUM(conn))) {
4171 (void)fdos_mode(fsp);
4172 if (!posix_open) {
4173 if (file_set_dosmode(conn, smb_fname,
4174 new_dos_attributes | FILE_ATTRIBUTE_ARCHIVE,
4175 parent_dir_fname, true) == 0) {
4176 unx_mode = smb_fname->st.st_ex_mode;
4182 /* Determine sparse flag. */
4183 if (posix_open) {
4184 /* POSIX opens are sparse by default. */
4185 fsp->fsp_flags.is_sparse = true;
4186 } else {
4187 fsp->fsp_flags.is_sparse =
4188 (existing_dos_attributes & FILE_ATTRIBUTE_SPARSE);
4192 * Take care of inherited ACLs on created files - if default ACL not
4193 * selected.
4196 if (!posix_open && new_file_created && !def_acl) {
4197 if (unx_mode != smb_fname->st.st_ex_mode) {
4198 int ret = SMB_VFS_FCHMOD(fsp, unx_mode);
4199 if (ret == -1) {
4200 DBG_INFO("failed to reset "
4201 "attributes of file %s to 0%o\n",
4202 smb_fname_str_dbg(smb_fname),
4203 (unsigned int)unx_mode);
4207 } else if (new_unx_mode) {
4209 * We only get here in the case of:
4211 * a). Not a POSIX open.
4212 * b). File already existed.
4213 * c). File was overwritten.
4214 * d). Requested DOS attributes didn't match
4215 * the DOS attributes on the existing file.
4217 * In that case new_unx_mode has been set
4218 * equal to the calculated mode (including
4219 * possible inheritance of the mode from the
4220 * containing directory).
4222 * Note this mode was calculated with the
4223 * DOS attribute FILE_ATTRIBUTE_ARCHIVE added,
4224 * so the mode change here is suitable for
4225 * an overwritten file.
4228 if (new_unx_mode != smb_fname->st.st_ex_mode) {
4229 int ret = SMB_VFS_FCHMOD(fsp, new_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)new_unx_mode);
4241 * Deal with other opens having a modified write time.
4243 struct timespec write_time = get_share_mode_write_time(lck);
4245 if (!is_omit_timespec(&write_time)) {
4246 update_stat_ex_mtime(&fsp->fsp_name->st, write_time);
4250 TALLOC_FREE(lck);
4252 return NT_STATUS_OK;
4255 static NTSTATUS mkdir_internal(connection_struct *conn,
4256 struct smb_filename *parent_dir_fname, /* parent. */
4257 struct smb_filename *smb_fname_atname, /* atname relative to parent. */
4258 struct smb_filename *smb_dname, /* full pathname from root of share. */
4259 uint32_t file_attributes,
4260 struct files_struct *fsp)
4262 const struct loadparm_substitution *lp_sub =
4263 loadparm_s3_global_substitution();
4264 mode_t mode;
4265 NTSTATUS status;
4266 bool posix_open = false;
4267 bool need_re_stat = false;
4268 uint32_t access_mask = SEC_DIR_ADD_SUBDIR;
4269 int ret;
4271 if (!CAN_WRITE(conn) || (access_mask & ~(conn->share_access))) {
4272 DEBUG(5,("mkdir_internal: failing share access "
4273 "%s\n", lp_servicename(talloc_tos(), lp_sub, SNUM(conn))));
4274 return NT_STATUS_ACCESS_DENIED;
4277 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
4278 posix_open = true;
4279 mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
4280 } else {
4281 mode = unix_mode(conn,
4282 FILE_ATTRIBUTE_DIRECTORY,
4283 smb_dname,
4284 parent_dir_fname);
4287 status = check_parent_access_fsp(parent_dir_fname->fsp, access_mask);
4288 if(!NT_STATUS_IS_OK(status)) {
4289 DBG_INFO("check_parent_access_fsp "
4290 "on directory %s for path %s returned %s\n",
4291 smb_fname_str_dbg(parent_dir_fname),
4292 smb_dname->base_name,
4293 nt_errstr(status));
4294 return status;
4297 if (lp_inherit_acls(SNUM(conn))) {
4298 if (directory_has_default_acl_fsp(parent_dir_fname->fsp)) {
4299 mode = (0777 & lp_directory_mask(SNUM(conn)));
4303 ret = SMB_VFS_MKDIRAT(conn,
4304 parent_dir_fname->fsp,
4305 smb_fname_atname,
4306 mode);
4307 if (ret != 0) {
4308 return map_nt_error_from_unix(errno);
4312 * Make this a pathref fsp for now. open_directory() will reopen as a
4313 * full fsp.
4315 fsp->fsp_flags.is_pathref = true;
4317 status = fd_openat(conn->cwd_fsp, smb_dname, fsp, O_RDONLY | O_DIRECTORY, 0);
4318 if (!NT_STATUS_IS_OK(status)) {
4319 return status;
4322 /* Ensure we're checking for a symlink here.... */
4323 /* We don't want to get caught by a symlink racer. */
4325 if (SMB_VFS_FSTAT(fsp, &smb_dname->st) == -1) {
4326 DEBUG(2, ("Could not stat directory '%s' just created: %s\n",
4327 smb_fname_str_dbg(smb_dname), strerror(errno)));
4328 return map_nt_error_from_unix(errno);
4331 if (!S_ISDIR(smb_dname->st.st_ex_mode)) {
4332 DEBUG(0, ("Directory '%s' just created is not a directory !\n",
4333 smb_fname_str_dbg(smb_dname)));
4334 return NT_STATUS_NOT_A_DIRECTORY;
4337 smb_dname->st.st_ex_iflags &= ~ST_EX_IFLAG_CALCULATED_ITIME;
4339 if (lp_store_dos_attributes(SNUM(conn))) {
4340 if (smb_dname->st.st_ex_iflags & ST_EX_IFLAG_CALCULATED_FILE_ID)
4342 uint64_t file_id;
4344 file_id = make_file_id_from_itime(&smb_dname->st);
4345 update_stat_ex_file_id(&smb_dname->st, file_id);
4348 if (!posix_open) {
4349 file_set_dosmode(conn, smb_dname,
4350 file_attributes | FILE_ATTRIBUTE_DIRECTORY,
4351 parent_dir_fname, true);
4355 if (lp_inherit_permissions(SNUM(conn))) {
4356 inherit_access_posix_acl(conn, parent_dir_fname,
4357 smb_dname, mode);
4358 need_re_stat = true;
4361 if (!posix_open) {
4363 * Check if high bits should have been set,
4364 * then (if bits are missing): add them.
4365 * Consider bits automagically set by UNIX, i.e. SGID bit from parent
4366 * dir.
4368 if ((mode & ~(S_IRWXU|S_IRWXG|S_IRWXO)) &&
4369 (mode & ~smb_dname->st.st_ex_mode)) {
4370 SMB_VFS_FCHMOD(fsp,
4371 (smb_dname->st.st_ex_mode |
4372 (mode & ~smb_dname->st.st_ex_mode)));
4373 need_re_stat = true;
4377 /* Change the owner if required. */
4378 if (lp_inherit_owner(SNUM(conn)) != INHERIT_OWNER_NO) {
4379 change_dir_owner_to_parent(conn, parent_dir_fname,
4380 smb_dname,
4381 &smb_dname->st);
4382 need_re_stat = true;
4385 if (need_re_stat) {
4386 if (SMB_VFS_FSTAT(fsp, &smb_dname->st) == -1) {
4387 DEBUG(2, ("Could not stat directory '%s' just created: %s\n",
4388 smb_fname_str_dbg(smb_dname), strerror(errno)));
4389 return map_nt_error_from_unix(errno);
4393 notify_fname(conn, NOTIFY_ACTION_ADDED, FILE_NOTIFY_CHANGE_DIR_NAME,
4394 smb_dname->base_name);
4396 return NT_STATUS_OK;
4399 /****************************************************************************
4400 Open a directory from an NT SMB call.
4401 ****************************************************************************/
4403 static NTSTATUS open_directory(connection_struct *conn,
4404 struct smb_request *req,
4405 uint32_t access_mask,
4406 uint32_t share_access,
4407 uint32_t create_disposition,
4408 uint32_t create_options,
4409 uint32_t file_attributes,
4410 struct smb_filename *parent_dir_fname,
4411 struct smb_filename *smb_fname_atname,
4412 int *pinfo,
4413 struct files_struct *fsp)
4415 struct smb_filename *smb_dname = fsp->fsp_name;
4416 bool dir_existed = VALID_STAT(smb_dname->st);
4417 struct share_mode_lock *lck = NULL;
4418 NTSTATUS status;
4419 struct timespec mtimespec;
4420 int info = 0;
4421 int flags;
4422 bool ok;
4424 if (is_ntfs_stream_smb_fname(smb_dname)) {
4425 DEBUG(2, ("open_directory: %s is a stream name!\n",
4426 smb_fname_str_dbg(smb_dname)));
4427 return NT_STATUS_NOT_A_DIRECTORY;
4430 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS)) {
4431 /* Ensure we have a directory attribute. */
4432 file_attributes |= FILE_ATTRIBUTE_DIRECTORY;
4435 DBG_INFO("opening directory %s, access_mask = 0x%"PRIx32", "
4436 "share_access = 0x%"PRIx32" create_options = 0x%"PRIx32", "
4437 "create_disposition = 0x%"PRIx32", "
4438 "file_attributes = 0x%"PRIx32"\n",
4439 smb_fname_str_dbg(smb_dname),
4440 access_mask,
4441 share_access,
4442 create_options,
4443 create_disposition,
4444 file_attributes);
4446 status = smbd_calculate_access_mask(conn,
4447 conn->cwd_fsp,
4448 smb_dname,
4449 false,
4450 access_mask,
4451 &access_mask);
4452 if (!NT_STATUS_IS_OK(status)) {
4453 DEBUG(10, ("open_directory: smbd_calculate_access_mask "
4454 "on file %s returned %s\n",
4455 smb_fname_str_dbg(smb_dname),
4456 nt_errstr(status)));
4457 return status;
4460 if ((access_mask & SEC_FLAG_SYSTEM_SECURITY) &&
4461 !security_token_has_privilege(get_current_nttok(conn),
4462 SEC_PRIV_SECURITY)) {
4463 DEBUG(10, ("open_directory: open on %s "
4464 "failed - SEC_FLAG_SYSTEM_SECURITY denied.\n",
4465 smb_fname_str_dbg(smb_dname)));
4466 return NT_STATUS_PRIVILEGE_NOT_HELD;
4469 switch( create_disposition ) {
4470 case FILE_OPEN:
4472 if (!dir_existed) {
4473 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4476 info = FILE_WAS_OPENED;
4477 break;
4479 case FILE_CREATE:
4481 /* If directory exists error. If directory doesn't
4482 * exist create. */
4484 if (dir_existed) {
4485 status = NT_STATUS_OBJECT_NAME_COLLISION;
4486 DEBUG(2, ("open_directory: unable to create "
4487 "%s. Error was %s\n",
4488 smb_fname_str_dbg(smb_dname),
4489 nt_errstr(status)));
4490 return status;
4493 status = mkdir_internal(conn,
4494 parent_dir_fname,
4495 smb_fname_atname,
4496 smb_dname,
4497 file_attributes,
4498 fsp);
4500 if (!NT_STATUS_IS_OK(status)) {
4501 DEBUG(2, ("open_directory: unable to create "
4502 "%s. Error was %s\n",
4503 smb_fname_str_dbg(smb_dname),
4504 nt_errstr(status)));
4505 return status;
4508 info = FILE_WAS_CREATED;
4509 break;
4511 case FILE_OPEN_IF:
4513 * If directory exists open. If directory doesn't
4514 * exist create.
4517 if (dir_existed) {
4518 status = NT_STATUS_OK;
4519 info = FILE_WAS_OPENED;
4520 } else {
4521 status = mkdir_internal(conn,
4522 parent_dir_fname,
4523 smb_fname_atname,
4524 smb_dname,
4525 file_attributes,
4526 fsp);
4528 if (NT_STATUS_IS_OK(status)) {
4529 info = FILE_WAS_CREATED;
4530 } else {
4531 /* Cope with create race. */
4532 if (!NT_STATUS_EQUAL(status,
4533 NT_STATUS_OBJECT_NAME_COLLISION)) {
4534 DEBUG(2, ("open_directory: unable to create "
4535 "%s. Error was %s\n",
4536 smb_fname_str_dbg(smb_dname),
4537 nt_errstr(status)));
4538 return status;
4542 * If mkdir_internal() returned
4543 * NT_STATUS_OBJECT_NAME_COLLISION
4544 * we still must lstat the path.
4547 if (SMB_VFS_LSTAT(conn, smb_dname)
4548 == -1) {
4549 DEBUG(2, ("Could not stat "
4550 "directory '%s' just "
4551 "opened: %s\n",
4552 smb_fname_str_dbg(
4553 smb_dname),
4554 strerror(errno)));
4555 return map_nt_error_from_unix(
4556 errno);
4559 info = FILE_WAS_OPENED;
4563 break;
4565 case FILE_SUPERSEDE:
4566 case FILE_OVERWRITE:
4567 case FILE_OVERWRITE_IF:
4568 default:
4569 DEBUG(5,("open_directory: invalid create_disposition "
4570 "0x%x for directory %s\n",
4571 (unsigned int)create_disposition,
4572 smb_fname_str_dbg(smb_dname)));
4573 return NT_STATUS_INVALID_PARAMETER;
4576 if(!S_ISDIR(smb_dname->st.st_ex_mode)) {
4577 DEBUG(5,("open_directory: %s is not a directory !\n",
4578 smb_fname_str_dbg(smb_dname)));
4579 return NT_STATUS_NOT_A_DIRECTORY;
4583 * Setup the files_struct for it.
4586 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_dname->st);
4587 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
4588 fsp->file_pid = req ? req->smbpid : 0;
4589 fsp->fsp_flags.can_lock = false;
4590 fsp->fsp_flags.can_read = false;
4591 fsp->fsp_flags.can_write = false;
4593 fh_set_private_options(fsp->fh, 0);
4595 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
4597 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
4598 fsp->print_file = NULL;
4599 fsp->fsp_flags.modified = false;
4600 fsp->oplock_type = NO_OPLOCK;
4601 fsp->sent_oplock_break = NO_BREAK_SENT;
4602 fsp->fsp_flags.is_directory = true;
4603 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
4604 fsp->posix_flags |= FSP_POSIX_FLAGS_ALL;
4607 /* Don't store old timestamps for directory
4608 handles in the internal database. We don't
4609 update them in there if new objects
4610 are created in the directory. Currently
4611 we only update timestamps on file writes.
4612 See bug #9870.
4614 mtimespec = make_omit_timespec();
4616 /* POSIX allows us to open a directory with O_RDONLY. */
4617 flags = O_RDONLY;
4618 #ifdef O_DIRECTORY
4619 flags |= O_DIRECTORY;
4620 #endif
4622 status = reopen_from_fsp(fsp, flags, 0, NULL);
4623 if (!NT_STATUS_IS_OK(status)) {
4624 DBG_INFO("Could not open fd for%s (%s)\n",
4625 smb_fname_str_dbg(smb_dname),
4626 nt_errstr(status));
4627 return status;
4630 status = vfs_stat_fsp(fsp);
4631 if (!NT_STATUS_IS_OK(status)) {
4632 fd_close(fsp);
4633 return status;
4636 if(!S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
4637 DEBUG(5,("open_directory: %s is not a directory !\n",
4638 smb_fname_str_dbg(smb_dname)));
4639 fd_close(fsp);
4640 return NT_STATUS_NOT_A_DIRECTORY;
4643 /* Ensure there was no race condition. We need to check
4644 * dev/inode but not permissions, as these can change
4645 * legitimately */
4646 if (!check_same_dev_ino(&smb_dname->st, &fsp->fsp_name->st)) {
4647 DEBUG(5,("open_directory: stat struct differs for "
4648 "directory %s.\n",
4649 smb_fname_str_dbg(smb_dname)));
4650 fd_close(fsp);
4651 return NT_STATUS_ACCESS_DENIED;
4654 if (info == FILE_WAS_OPENED) {
4655 status = smbd_check_access_rights_fsp(fsp,
4656 false,
4657 access_mask);
4658 if (!NT_STATUS_IS_OK(status)) {
4659 DEBUG(10, ("open_directory: smbd_check_access_rights on "
4660 "file %s failed with %s\n",
4661 smb_fname_str_dbg(smb_dname),
4662 nt_errstr(status)));
4663 fd_close(fsp);
4664 return status;
4668 lck = get_share_mode_lock(talloc_tos(), fsp->file_id,
4669 conn->connectpath, smb_dname,
4670 &mtimespec);
4672 if (lck == NULL) {
4673 DEBUG(0, ("open_directory: Could not get share mode lock for "
4674 "%s\n", smb_fname_str_dbg(smb_dname)));
4675 fd_close(fsp);
4676 return NT_STATUS_SHARING_VIOLATION;
4679 if (has_delete_on_close(lck, fsp->name_hash)) {
4680 TALLOC_FREE(lck);
4681 fd_close(fsp);
4682 return NT_STATUS_DELETE_PENDING;
4685 status = open_mode_check(conn, fsp->file_id, lck,
4686 access_mask, share_access);
4688 if (!NT_STATUS_IS_OK(status)) {
4689 TALLOC_FREE(lck);
4690 fd_close(fsp);
4691 return status;
4694 share_mode_flags_restrict(lck, access_mask, share_access, 0);
4696 ok = set_share_mode(
4697 lck,
4698 fsp,
4699 get_current_uid(conn),
4700 req ? req->mid : 0,
4701 NO_OPLOCK,
4702 share_access,
4703 fsp->access_mask);
4704 if (!ok) {
4705 TALLOC_FREE(lck);
4706 fd_close(fsp);
4707 return NT_STATUS_NO_MEMORY;
4710 /* For directories the delete on close bit at open time seems
4711 always to be honored on close... See test 19 in Samba4 BASE-DELETE. */
4712 if (create_options & FILE_DELETE_ON_CLOSE) {
4713 status = can_set_delete_on_close(fsp, 0);
4714 if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
4715 del_share_mode(lck, fsp);
4716 TALLOC_FREE(lck);
4717 fd_close(fsp);
4718 return status;
4721 if (NT_STATUS_IS_OK(status)) {
4722 /* Note that here we set the *initial* delete on close flag,
4723 not the regular one. The magic gets handled in close. */
4724 fsp->fsp_flags.initial_delete_on_close = true;
4730 * Deal with other opens having a modified write time. Is this
4731 * possible for directories?
4733 struct timespec write_time = get_share_mode_write_time(lck);
4735 if (!is_omit_timespec(&write_time)) {
4736 update_stat_ex_mtime(&fsp->fsp_name->st, write_time);
4740 TALLOC_FREE(lck);
4742 if (pinfo) {
4743 *pinfo = info;
4746 return NT_STATUS_OK;
4749 NTSTATUS create_directory(connection_struct *conn, struct smb_request *req,
4750 struct smb_filename *smb_dname)
4752 NTSTATUS status;
4753 files_struct *fsp;
4755 status = SMB_VFS_CREATE_FILE(
4756 conn, /* conn */
4757 req, /* req */
4758 smb_dname, /* fname */
4759 FILE_READ_ATTRIBUTES, /* access_mask */
4760 FILE_SHARE_NONE, /* share_access */
4761 FILE_CREATE, /* create_disposition*/
4762 FILE_DIRECTORY_FILE, /* create_options */
4763 FILE_ATTRIBUTE_DIRECTORY, /* file_attributes */
4764 0, /* oplock_request */
4765 NULL, /* lease */
4766 0, /* allocation_size */
4767 0, /* private_flags */
4768 NULL, /* sd */
4769 NULL, /* ea_list */
4770 &fsp, /* result */
4771 NULL, /* pinfo */
4772 NULL, NULL); /* create context */
4774 if (NT_STATUS_IS_OK(status)) {
4775 close_file(req, fsp, NORMAL_CLOSE);
4778 return status;
4781 /****************************************************************************
4782 Receive notification that one of our open files has been renamed by another
4783 smbd process.
4784 ****************************************************************************/
4786 void msg_file_was_renamed(struct messaging_context *msg_ctx,
4787 void *private_data,
4788 uint32_t msg_type,
4789 struct server_id src,
4790 DATA_BLOB *data)
4792 struct file_rename_message *msg = NULL;
4793 enum ndr_err_code ndr_err;
4794 files_struct *fsp;
4795 struct smb_filename *smb_fname = NULL;
4796 struct smbd_server_connection *sconn =
4797 talloc_get_type_abort(private_data,
4798 struct smbd_server_connection);
4800 msg = talloc(talloc_tos(), struct file_rename_message);
4801 if (msg == NULL) {
4802 DBG_WARNING("talloc failed\n");
4803 return;
4806 ndr_err = ndr_pull_struct_blob_all(
4807 data,
4808 msg,
4809 msg,
4810 (ndr_pull_flags_fn_t)ndr_pull_file_rename_message);
4811 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
4812 DBG_DEBUG("ndr_pull_oplock_break_message failed: %s\n",
4813 ndr_errstr(ndr_err));
4814 goto out;
4816 if (DEBUGLEVEL >= 10) {
4817 struct server_id_buf buf;
4818 DBG_DEBUG("Got rename message from %s\n",
4819 server_id_str_buf(src, &buf));
4820 NDR_PRINT_DEBUG(file_rename_message, msg);
4823 /* stream_name must always be NULL if there is no stream. */
4824 if ((msg->stream_name != NULL) && (msg->stream_name[0] == '\0')) {
4825 msg->stream_name = NULL;
4828 smb_fname = synthetic_smb_fname(msg,
4829 msg->base_name,
4830 msg->stream_name,
4831 NULL,
4834 if (smb_fname == NULL) {
4835 DBG_DEBUG("synthetic_smb_fname failed\n");
4836 goto out;
4839 fsp = file_find_dif(sconn, msg->id, msg->share_file_id);
4840 if (fsp == NULL) {
4841 DBG_DEBUG("fsp not found\n");
4842 goto out;
4845 if (strcmp(fsp->conn->connectpath, msg->servicepath) == 0) {
4846 NTSTATUS status;
4847 DBG_DEBUG("renaming file %s from %s -> %s\n",
4848 fsp_fnum_dbg(fsp),
4849 fsp_str_dbg(fsp),
4850 smb_fname_str_dbg(smb_fname));
4851 status = fsp_set_smb_fname(fsp, smb_fname);
4852 if (!NT_STATUS_IS_OK(status)) {
4853 DBG_DEBUG("fsp_set_smb_fname failed: %s\n",
4854 nt_errstr(status));
4856 } else {
4857 /* TODO. JRA. */
4859 * Now we have the complete path we can work out if
4860 * this is actually within this share and adjust
4861 * newname accordingly.
4863 DBG_DEBUG("share mismatch (sharepath %s not sharepath %s) "
4864 "%s from %s -> %s\n",
4865 fsp->conn->connectpath,
4866 msg->servicepath,
4867 fsp_fnum_dbg(fsp),
4868 fsp_str_dbg(fsp),
4869 smb_fname_str_dbg(smb_fname));
4871 out:
4872 TALLOC_FREE(msg);
4876 * If a main file is opened for delete, all streams need to be checked for
4877 * !FILE_SHARE_DELETE. Do this by opening with DELETE_ACCESS.
4878 * If that works, delete them all by setting the delete on close and close.
4881 static NTSTATUS open_streams_for_delete(connection_struct *conn,
4882 const struct smb_filename *smb_fname)
4884 struct stream_struct *stream_info = NULL;
4885 files_struct **streams = NULL;
4886 int j;
4887 unsigned int i, num_streams = 0;
4888 TALLOC_CTX *frame = talloc_stackframe();
4889 const struct smb_filename *pathref = NULL;
4890 NTSTATUS status;
4892 if (smb_fname->fsp == NULL) {
4893 struct smb_filename *tmp = NULL;
4894 status = synthetic_pathref(frame,
4895 conn->cwd_fsp,
4896 smb_fname->base_name,
4897 NULL,
4898 NULL,
4899 smb_fname->twrp,
4900 smb_fname->flags,
4901 &tmp);
4902 if (!NT_STATUS_IS_OK(status)) {
4903 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
4904 || NT_STATUS_EQUAL(status,
4905 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4906 DBG_DEBUG("no streams around\n");
4907 TALLOC_FREE(frame);
4908 return NT_STATUS_OK;
4910 DBG_DEBUG("synthetic_pathref failed: %s\n",
4911 nt_errstr(status));
4912 goto fail;
4914 pathref = tmp;
4915 } else {
4916 pathref = smb_fname;
4918 status = vfs_fstreaminfo(pathref->fsp, talloc_tos(),
4919 &num_streams, &stream_info);
4921 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
4922 || NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4923 DEBUG(10, ("no streams around\n"));
4924 TALLOC_FREE(frame);
4925 return NT_STATUS_OK;
4928 if (!NT_STATUS_IS_OK(status)) {
4929 DEBUG(10, ("vfs_fstreaminfo failed: %s\n",
4930 nt_errstr(status)));
4931 goto fail;
4934 DEBUG(10, ("open_streams_for_delete found %d streams\n",
4935 num_streams));
4937 if (num_streams == 0) {
4938 TALLOC_FREE(frame);
4939 return NT_STATUS_OK;
4942 streams = talloc_array(talloc_tos(), files_struct *, num_streams);
4943 if (streams == NULL) {
4944 DEBUG(0, ("talloc failed\n"));
4945 status = NT_STATUS_NO_MEMORY;
4946 goto fail;
4949 for (i=0; i<num_streams; i++) {
4950 struct smb_filename *smb_fname_cp;
4952 if (strequal(stream_info[i].name, "::$DATA")) {
4953 streams[i] = NULL;
4954 continue;
4957 smb_fname_cp = synthetic_smb_fname(talloc_tos(),
4958 smb_fname->base_name,
4959 stream_info[i].name,
4960 NULL,
4961 smb_fname->twrp,
4962 (smb_fname->flags &
4963 ~SMB_FILENAME_POSIX_PATH));
4964 if (smb_fname_cp == NULL) {
4965 status = NT_STATUS_NO_MEMORY;
4966 goto fail;
4969 if (SMB_VFS_STAT(conn, smb_fname_cp) == -1) {
4970 DEBUG(10, ("Unable to stat stream: %s\n",
4971 smb_fname_str_dbg(smb_fname_cp)));
4974 status = openat_pathref_fsp(conn->cwd_fsp, smb_fname_cp);
4975 if (!NT_STATUS_IS_OK(status)) {
4976 DBG_DEBUG("Unable to open stream [%s]: %s\n",
4977 smb_fname_str_dbg(smb_fname_cp),
4978 nt_errstr(status));
4979 TALLOC_FREE(smb_fname_cp);
4980 break;
4983 status = SMB_VFS_CREATE_FILE(
4984 conn, /* conn */
4985 NULL, /* req */
4986 smb_fname_cp, /* fname */
4987 DELETE_ACCESS, /* access_mask */
4988 (FILE_SHARE_READ | /* share_access */
4989 FILE_SHARE_WRITE | FILE_SHARE_DELETE),
4990 FILE_OPEN, /* create_disposition*/
4991 0, /* create_options */
4992 FILE_ATTRIBUTE_NORMAL, /* file_attributes */
4993 0, /* oplock_request */
4994 NULL, /* lease */
4995 0, /* allocation_size */
4996 0, /* private_flags */
4997 NULL, /* sd */
4998 NULL, /* ea_list */
4999 &streams[i], /* result */
5000 NULL, /* pinfo */
5001 NULL, NULL); /* create context */
5003 if (!NT_STATUS_IS_OK(status)) {
5004 DEBUG(10, ("Could not open stream %s: %s\n",
5005 smb_fname_str_dbg(smb_fname_cp),
5006 nt_errstr(status)));
5008 TALLOC_FREE(smb_fname_cp);
5009 break;
5011 TALLOC_FREE(smb_fname_cp);
5015 * don't touch the variable "status" beyond this point :-)
5018 for (j = i-1 ; j >= 0; j--) {
5019 if (streams[j] == NULL) {
5020 continue;
5023 DEBUG(10, ("Closing stream # %d, %s\n", j,
5024 fsp_str_dbg(streams[j])));
5025 close_file(NULL, streams[j], NORMAL_CLOSE);
5028 fail:
5029 TALLOC_FREE(frame);
5030 return status;
5033 /*********************************************************************
5034 Create a default ACL by inheriting from the parent. If no inheritance
5035 from the parent available, don't set anything. This will leave the actual
5036 permissions the new file or directory already got from the filesystem
5037 as the NT ACL when read.
5038 *********************************************************************/
5040 static NTSTATUS inherit_new_acl(struct smb_filename *parent_dir_fname,
5041 files_struct *fsp)
5043 TALLOC_CTX *frame = talloc_stackframe();
5044 struct security_descriptor *parent_desc = NULL;
5045 NTSTATUS status = NT_STATUS_OK;
5046 struct security_descriptor *psd = NULL;
5047 const struct dom_sid *owner_sid = NULL;
5048 const struct dom_sid *group_sid = NULL;
5049 uint32_t security_info_sent = (SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL);
5050 struct security_token *token = fsp->conn->session_info->security_token;
5051 bool inherit_owner =
5052 (lp_inherit_owner(SNUM(fsp->conn)) == INHERIT_OWNER_WINDOWS_AND_UNIX);
5053 bool inheritable_components = false;
5054 bool try_builtin_administrators = false;
5055 const struct dom_sid *BA_U_sid = NULL;
5056 const struct dom_sid *BA_G_sid = NULL;
5057 bool try_system = false;
5058 const struct dom_sid *SY_U_sid = NULL;
5059 const struct dom_sid *SY_G_sid = NULL;
5060 size_t size = 0;
5061 bool ok;
5063 status = SMB_VFS_FGET_NT_ACL(parent_dir_fname->fsp,
5064 (SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL),
5065 frame,
5066 &parent_desc);
5067 if (!NT_STATUS_IS_OK(status)) {
5068 TALLOC_FREE(frame);
5069 return status;
5072 inheritable_components = sd_has_inheritable_components(parent_desc,
5073 fsp->fsp_flags.is_directory);
5075 if (!inheritable_components && !inherit_owner) {
5076 TALLOC_FREE(frame);
5077 /* Nothing to inherit and not setting owner. */
5078 return NT_STATUS_OK;
5081 /* Create an inherited descriptor from the parent. */
5083 if (DEBUGLEVEL >= 10) {
5084 DEBUG(10,("inherit_new_acl: parent acl for %s is:\n",
5085 fsp_str_dbg(fsp) ));
5086 NDR_PRINT_DEBUG(security_descriptor, parent_desc);
5089 /* Inherit from parent descriptor if "inherit owner" set. */
5090 if (inherit_owner) {
5091 owner_sid = parent_desc->owner_sid;
5092 group_sid = parent_desc->group_sid;
5095 if (owner_sid == NULL) {
5096 if (security_token_has_builtin_administrators(token)) {
5097 try_builtin_administrators = true;
5098 } else if (security_token_is_system(token)) {
5099 try_builtin_administrators = true;
5100 try_system = true;
5104 if (group_sid == NULL &&
5105 token->num_sids == PRIMARY_GROUP_SID_INDEX)
5107 if (security_token_is_system(token)) {
5108 try_builtin_administrators = true;
5109 try_system = true;
5113 if (try_builtin_administrators) {
5114 struct unixid ids;
5116 ZERO_STRUCT(ids);
5117 ok = sids_to_unixids(&global_sid_Builtin_Administrators, 1, &ids);
5118 if (ok) {
5119 switch (ids.type) {
5120 case ID_TYPE_BOTH:
5121 BA_U_sid = &global_sid_Builtin_Administrators;
5122 BA_G_sid = &global_sid_Builtin_Administrators;
5123 break;
5124 case ID_TYPE_UID:
5125 BA_U_sid = &global_sid_Builtin_Administrators;
5126 break;
5127 case ID_TYPE_GID:
5128 BA_G_sid = &global_sid_Builtin_Administrators;
5129 break;
5130 default:
5131 break;
5136 if (try_system) {
5137 struct unixid ids;
5139 ZERO_STRUCT(ids);
5140 ok = sids_to_unixids(&global_sid_System, 1, &ids);
5141 if (ok) {
5142 switch (ids.type) {
5143 case ID_TYPE_BOTH:
5144 SY_U_sid = &global_sid_System;
5145 SY_G_sid = &global_sid_System;
5146 break;
5147 case ID_TYPE_UID:
5148 SY_U_sid = &global_sid_System;
5149 break;
5150 case ID_TYPE_GID:
5151 SY_G_sid = &global_sid_System;
5152 break;
5153 default:
5154 break;
5159 if (owner_sid == NULL) {
5160 owner_sid = BA_U_sid;
5163 if (owner_sid == NULL) {
5164 owner_sid = SY_U_sid;
5167 if (group_sid == NULL) {
5168 group_sid = SY_G_sid;
5171 if (try_system && group_sid == NULL) {
5172 group_sid = BA_G_sid;
5175 if (owner_sid == NULL) {
5176 owner_sid = &token->sids[PRIMARY_USER_SID_INDEX];
5178 if (group_sid == NULL) {
5179 if (token->num_sids == PRIMARY_GROUP_SID_INDEX) {
5180 group_sid = &token->sids[PRIMARY_USER_SID_INDEX];
5181 } else {
5182 group_sid = &token->sids[PRIMARY_GROUP_SID_INDEX];
5186 status = se_create_child_secdesc(frame,
5187 &psd,
5188 &size,
5189 parent_desc,
5190 owner_sid,
5191 group_sid,
5192 fsp->fsp_flags.is_directory);
5193 if (!NT_STATUS_IS_OK(status)) {
5194 TALLOC_FREE(frame);
5195 return status;
5198 /* If inheritable_components == false,
5199 se_create_child_secdesc()
5200 creates a security descriptor with a NULL dacl
5201 entry, but with SEC_DESC_DACL_PRESENT. We need
5202 to remove that flag. */
5204 if (!inheritable_components) {
5205 security_info_sent &= ~SECINFO_DACL;
5206 psd->type &= ~SEC_DESC_DACL_PRESENT;
5209 if (DEBUGLEVEL >= 10) {
5210 DEBUG(10,("inherit_new_acl: child acl for %s is:\n",
5211 fsp_str_dbg(fsp) ));
5212 NDR_PRINT_DEBUG(security_descriptor, psd);
5215 if (inherit_owner) {
5216 /* We need to be root to force this. */
5217 become_root();
5219 status = SMB_VFS_FSET_NT_ACL(fsp,
5220 security_info_sent,
5221 psd);
5222 if (inherit_owner) {
5223 unbecome_root();
5225 TALLOC_FREE(frame);
5226 return status;
5230 * If we already have a lease, it must match the new file id. [MS-SMB2]
5231 * 3.3.5.9.8 speaks about INVALID_PARAMETER if an already used lease key is
5232 * used for a different file name.
5235 struct lease_match_state {
5236 /* Input parameters. */
5237 TALLOC_CTX *mem_ctx;
5238 const char *servicepath;
5239 const struct smb_filename *fname;
5240 bool file_existed;
5241 struct file_id id;
5242 /* Return parameters. */
5243 uint32_t num_file_ids;
5244 struct file_id *ids;
5245 NTSTATUS match_status;
5248 /*************************************************************
5249 File doesn't exist but this lease key+guid is already in use.
5251 This is only allowable in the dynamic share case where the
5252 service path must be different.
5254 There is a small race condition here in the multi-connection
5255 case where a client sends two create calls on different connections,
5256 where the file doesn't exist and one smbd creates the leases_db
5257 entry first, but this will get fixed by the multichannel cleanup
5258 when all identical client_guids get handled by a single smbd.
5259 **************************************************************/
5261 static void lease_match_parser_new_file(
5262 uint32_t num_files,
5263 const struct leases_db_file *files,
5264 struct lease_match_state *state)
5266 uint32_t i;
5268 for (i = 0; i < num_files; i++) {
5269 const struct leases_db_file *f = &files[i];
5270 if (strequal(state->servicepath, f->servicepath)) {
5271 state->match_status = NT_STATUS_INVALID_PARAMETER;
5272 return;
5276 /* Dynamic share case. Break leases on all other files. */
5277 state->match_status = leases_db_copy_file_ids(state->mem_ctx,
5278 num_files,
5279 files,
5280 &state->ids);
5281 if (!NT_STATUS_IS_OK(state->match_status)) {
5282 return;
5285 state->num_file_ids = num_files;
5286 state->match_status = NT_STATUS_OPLOCK_NOT_GRANTED;
5287 return;
5290 static void lease_match_parser(
5291 uint32_t num_files,
5292 const struct leases_db_file *files,
5293 void *private_data)
5295 struct lease_match_state *state =
5296 (struct lease_match_state *)private_data;
5297 uint32_t i;
5299 if (!state->file_existed) {
5301 * Deal with name mismatch or
5302 * possible dynamic share case separately
5303 * to make code clearer.
5305 lease_match_parser_new_file(num_files,
5306 files,
5307 state);
5308 return;
5311 /* File existed. */
5312 state->match_status = NT_STATUS_OK;
5314 for (i = 0; i < num_files; i++) {
5315 const struct leases_db_file *f = &files[i];
5317 /* Everything should be the same. */
5318 if (!file_id_equal(&state->id, &f->id)) {
5319 /* This should catch all dynamic share cases. */
5320 state->match_status = NT_STATUS_OPLOCK_NOT_GRANTED;
5321 break;
5323 if (!strequal(f->servicepath, state->servicepath)) {
5324 state->match_status = NT_STATUS_INVALID_PARAMETER;
5325 break;
5327 if (!strequal(f->base_name, state->fname->base_name)) {
5328 state->match_status = NT_STATUS_INVALID_PARAMETER;
5329 break;
5331 if (!strequal(f->stream_name, state->fname->stream_name)) {
5332 state->match_status = NT_STATUS_INVALID_PARAMETER;
5333 break;
5337 if (NT_STATUS_IS_OK(state->match_status)) {
5339 * Common case - just opening another handle on a
5340 * file on a non-dynamic share.
5342 return;
5345 if (NT_STATUS_EQUAL(state->match_status, NT_STATUS_INVALID_PARAMETER)) {
5346 /* Mismatched path. Error back to client. */
5347 return;
5351 * File id mismatch. Dynamic share case NT_STATUS_OPLOCK_NOT_GRANTED.
5352 * Don't allow leases.
5355 state->match_status = leases_db_copy_file_ids(state->mem_ctx,
5356 num_files,
5357 files,
5358 &state->ids);
5359 if (!NT_STATUS_IS_OK(state->match_status)) {
5360 return;
5363 state->num_file_ids = num_files;
5364 state->match_status = NT_STATUS_OPLOCK_NOT_GRANTED;
5365 return;
5368 struct lease_match_break_state {
5369 struct messaging_context *msg_ctx;
5370 const struct smb2_lease_key *lease_key;
5371 struct file_id id;
5373 bool found_lease;
5374 uint16_t version;
5375 uint16_t epoch;
5378 static bool lease_match_break_fn(
5379 struct share_mode_entry *e,
5380 void *private_data)
5382 struct lease_match_break_state *state = private_data;
5383 bool stale, equal;
5384 uint32_t e_lease_type;
5385 NTSTATUS status;
5387 stale = share_entry_stale_pid(e);
5388 if (stale) {
5389 return false;
5392 equal = smb2_lease_key_equal(&e->lease_key, state->lease_key);
5393 if (!equal) {
5394 return false;
5397 status = leases_db_get(
5398 &e->client_guid,
5399 &e->lease_key,
5400 &state->id,
5401 NULL, /* current_state */
5402 NULL, /* breaking */
5403 NULL, /* breaking_to_requested */
5404 NULL, /* breaking_to_required */
5405 &state->version, /* lease_version */
5406 &state->epoch); /* epoch */
5407 if (NT_STATUS_IS_OK(status)) {
5408 state->found_lease = true;
5409 } else {
5410 DBG_WARNING("Could not find version/epoch: %s\n",
5411 nt_errstr(status));
5414 e_lease_type = get_lease_type(e, state->id);
5415 if (e_lease_type == SMB2_LEASE_NONE) {
5416 return false;
5418 send_break_message(state->msg_ctx, &state->id, e, SMB2_LEASE_NONE);
5421 * Windows 7 and 8 lease clients are broken in that they will
5422 * not respond to lease break requests whilst waiting for an
5423 * outstanding open request on that lease handle on the same
5424 * TCP connection, due to holding an internal inode lock.
5426 * This means we can't reschedule ourselves here, but must
5427 * return from the create.
5429 * Work around:
5431 * Send the breaks and then return SMB2_LEASE_NONE in the
5432 * lease handle to cause them to acknowledge the lease
5433 * break. Consultation with Microsoft engineering confirmed
5434 * this approach is safe.
5437 return false;
5440 static NTSTATUS lease_match(connection_struct *conn,
5441 struct smb_request *req,
5442 const struct smb2_lease_key *lease_key,
5443 const char *servicepath,
5444 const struct smb_filename *fname,
5445 uint16_t *p_version,
5446 uint16_t *p_epoch)
5448 struct smbd_server_connection *sconn = req->sconn;
5449 TALLOC_CTX *tos = talloc_tos();
5450 struct lease_match_state state = {
5451 .mem_ctx = tos,
5452 .servicepath = servicepath,
5453 .fname = fname,
5454 .match_status = NT_STATUS_OK
5456 uint32_t i;
5457 NTSTATUS status;
5459 state.file_existed = VALID_STAT(fname->st);
5460 if (state.file_existed) {
5461 state.id = vfs_file_id_from_sbuf(conn, &fname->st);
5464 status = leases_db_parse(&sconn->client->global->client_guid,
5465 lease_key, lease_match_parser, &state);
5466 if (!NT_STATUS_IS_OK(status)) {
5468 * Not found or error means okay: We can make the lease pass
5470 return NT_STATUS_OK;
5472 if (!NT_STATUS_EQUAL(state.match_status, NT_STATUS_OPLOCK_NOT_GRANTED)) {
5474 * Anything but NT_STATUS_OPLOCK_NOT_GRANTED, let the caller
5475 * deal with it.
5477 return state.match_status;
5480 /* We have to break all existing leases. */
5481 for (i = 0; i < state.num_file_ids; i++) {
5482 struct lease_match_break_state break_state = {
5483 .msg_ctx = conn->sconn->msg_ctx,
5484 .lease_key = lease_key,
5486 struct share_mode_lock *lck;
5487 bool ok;
5489 if (file_id_equal(&state.ids[i], &state.id)) {
5490 /* Don't need to break our own file. */
5491 continue;
5494 break_state.id = state.ids[i];
5496 lck = get_existing_share_mode_lock(
5497 talloc_tos(), break_state.id);
5498 if (lck == NULL) {
5499 /* Race condition - file already closed. */
5500 continue;
5503 ok = share_mode_forall_leases(
5504 lck, lease_match_break_fn, &break_state);
5505 if (!ok) {
5506 DBG_DEBUG("share_mode_forall_leases failed\n");
5507 continue;
5510 TALLOC_FREE(lck);
5512 if (break_state.found_lease) {
5513 *p_version = break_state.version;
5514 *p_epoch = break_state.epoch;
5518 * Ensure we don't grant anything more so we
5519 * never upgrade.
5521 return NT_STATUS_OPLOCK_NOT_GRANTED;
5525 * Wrapper around open_file_ntcreate and open_directory
5528 static NTSTATUS create_file_unixpath(connection_struct *conn,
5529 struct smb_request *req,
5530 struct smb_filename *smb_fname,
5531 uint32_t access_mask,
5532 uint32_t share_access,
5533 uint32_t create_disposition,
5534 uint32_t create_options,
5535 uint32_t file_attributes,
5536 uint32_t oplock_request,
5537 const struct smb2_lease *lease,
5538 uint64_t allocation_size,
5539 uint32_t private_flags,
5540 struct security_descriptor *sd,
5541 struct ea_list *ea_list,
5543 files_struct **result,
5544 int *pinfo)
5546 struct smb2_lease none_lease;
5547 int info = FILE_WAS_OPENED;
5548 files_struct *base_fsp = NULL;
5549 files_struct *fsp = NULL;
5550 NTSTATUS status;
5551 int ret;
5552 struct smb_filename *parent_dir_fname = NULL;
5553 struct smb_filename *smb_fname_atname = NULL;
5555 DBG_DEBUG("create_file_unixpath: access_mask = 0x%x "
5556 "file_attributes = 0x%x, share_access = 0x%x, "
5557 "create_disposition = 0x%x create_options = 0x%x "
5558 "oplock_request = 0x%x private_flags = 0x%x "
5559 "ea_list = %p, sd = %p, "
5560 "fname = %s\n",
5561 (unsigned int)access_mask,
5562 (unsigned int)file_attributes,
5563 (unsigned int)share_access,
5564 (unsigned int)create_disposition,
5565 (unsigned int)create_options,
5566 (unsigned int)oplock_request,
5567 (unsigned int)private_flags,
5568 ea_list, sd, smb_fname_str_dbg(smb_fname));
5570 if (create_options & FILE_OPEN_BY_FILE_ID) {
5571 status = NT_STATUS_NOT_SUPPORTED;
5572 goto fail;
5575 if (create_options & NTCREATEX_OPTIONS_INVALID_PARAM_MASK) {
5576 status = NT_STATUS_INVALID_PARAMETER;
5577 goto fail;
5580 if (req == NULL) {
5581 oplock_request |= INTERNAL_OPEN_ONLY;
5584 if (lease != NULL) {
5585 uint16_t epoch = lease->lease_epoch;
5586 uint16_t version = lease->lease_version;
5588 if (req == NULL) {
5589 DBG_WARNING("Got lease on internal open\n");
5590 status = NT_STATUS_INTERNAL_ERROR;
5591 goto fail;
5594 status = lease_match(conn,
5595 req,
5596 &lease->lease_key,
5597 conn->connectpath,
5598 smb_fname,
5599 &version,
5600 &epoch);
5601 if (NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) {
5602 /* Dynamic share file. No leases and update epoch... */
5603 none_lease = *lease;
5604 none_lease.lease_state = SMB2_LEASE_NONE;
5605 none_lease.lease_epoch = epoch;
5606 none_lease.lease_version = version;
5607 lease = &none_lease;
5608 } else if (!NT_STATUS_IS_OK(status)) {
5609 goto fail;
5613 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
5614 && (access_mask & DELETE_ACCESS)
5615 && !is_ntfs_stream_smb_fname(smb_fname)) {
5617 * We can't open a file with DELETE access if any of the
5618 * streams is open without FILE_SHARE_DELETE
5620 status = open_streams_for_delete(conn, smb_fname);
5622 if (!NT_STATUS_IS_OK(status)) {
5623 goto fail;
5627 if (access_mask & SEC_FLAG_SYSTEM_SECURITY) {
5628 bool ok;
5630 ok = security_token_has_privilege(get_current_nttok(conn),
5631 SEC_PRIV_SECURITY);
5632 if (!ok) {
5633 DBG_DEBUG("open on %s failed - "
5634 "SEC_FLAG_SYSTEM_SECURITY denied.\n",
5635 smb_fname_str_dbg(smb_fname));
5636 status = NT_STATUS_PRIVILEGE_NOT_HELD;
5637 goto fail;
5640 if (conn->sconn->using_smb2 &&
5641 (access_mask == SEC_FLAG_SYSTEM_SECURITY))
5644 * No other bits set. Windows SMB2 refuses this.
5645 * See smbtorture3 SMB2-SACL test.
5647 * Note this is an SMB2-only behavior,
5648 * smbtorture3 SMB1-SYSTEM-SECURITY already tests
5649 * that SMB1 allows this.
5651 status = NT_STATUS_ACCESS_DENIED;
5652 goto fail;
5657 * Files or directories can't be opened DELETE_ON_CLOSE without
5658 * delete access.
5659 * BUG: https://bugzilla.samba.org/show_bug.cgi?id=13358
5661 if (create_options & FILE_DELETE_ON_CLOSE) {
5662 if ((access_mask & DELETE_ACCESS) == 0) {
5663 status = NT_STATUS_INVALID_PARAMETER;
5664 goto fail;
5668 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
5669 && is_ntfs_stream_smb_fname(smb_fname))
5671 uint32_t base_create_disposition;
5672 struct smb_filename *smb_fname_base = NULL;
5673 uint32_t base_privflags;
5675 if (create_options & FILE_DIRECTORY_FILE) {
5676 status = NT_STATUS_NOT_A_DIRECTORY;
5677 goto fail;
5680 switch (create_disposition) {
5681 case FILE_OPEN:
5682 base_create_disposition = FILE_OPEN;
5683 break;
5684 default:
5685 base_create_disposition = FILE_OPEN_IF;
5686 break;
5689 /* Create an smb_filename with stream_name == NULL. */
5690 smb_fname_base = synthetic_smb_fname(talloc_tos(),
5691 smb_fname->base_name,
5692 NULL,
5693 &smb_fname->st,
5694 smb_fname->twrp,
5695 smb_fname->flags);
5696 if (smb_fname_base == NULL) {
5697 status = NT_STATUS_NO_MEMORY;
5698 goto fail;
5702 * We may be creating the basefile as part of creating the
5703 * stream, so it's legal if the basefile doesn't exist at this
5704 * point, the create_file_unixpath() below will create it. But
5705 * if the basefile exists we want a handle so we can fstat() it.
5708 ret = vfs_stat(conn, smb_fname_base);
5709 if (ret == -1 && errno != ENOENT) {
5710 status = map_nt_error_from_unix(errno);
5711 TALLOC_FREE(smb_fname_base);
5712 goto fail;
5714 if (ret == 0) {
5715 status = openat_pathref_fsp(conn->cwd_fsp,
5716 smb_fname_base);
5717 if (!NT_STATUS_IS_OK(status)) {
5718 DBG_ERR("open_smb_fname_fsp [%s] failed: %s\n",
5719 smb_fname_str_dbg(smb_fname_base),
5720 nt_errstr(status));
5721 TALLOC_FREE(smb_fname_base);
5722 goto fail;
5726 * https://bugzilla.samba.org/show_bug.cgi?id=10229
5727 * We need to check if the requested access mask
5728 * could be used to open the underlying file (if
5729 * it existed), as we're passing in zero for the
5730 * access mask to the base filename.
5732 status = check_base_file_access(conn,
5733 smb_fname_base,
5734 access_mask);
5736 if (!NT_STATUS_IS_OK(status)) {
5737 DEBUG(10, ("Permission check "
5738 "for base %s failed: "
5739 "%s\n", smb_fname->base_name,
5740 nt_errstr(status)));
5741 TALLOC_FREE(smb_fname_base);
5742 goto fail;
5746 base_privflags = NTCREATEX_FLAG_STREAM_BASEOPEN;
5748 /* Open the base file. */
5749 status = create_file_unixpath(conn,
5750 NULL,
5751 smb_fname_base,
5753 FILE_SHARE_READ
5754 | FILE_SHARE_WRITE
5755 | FILE_SHARE_DELETE,
5756 base_create_disposition,
5760 NULL,
5762 base_privflags,
5763 NULL,
5764 NULL,
5765 &base_fsp,
5766 NULL);
5767 TALLOC_FREE(smb_fname_base);
5769 if (!NT_STATUS_IS_OK(status)) {
5770 DEBUG(10, ("create_file_unixpath for base %s failed: "
5771 "%s\n", smb_fname->base_name,
5772 nt_errstr(status)));
5773 goto fail;
5778 * Now either reuse smb_fname->fsp or allocate a new fsp if
5779 * smb_fname->fsp is NULL. The latter will be the case when processing a
5780 * request to create a file that doesn't exist.
5782 if (smb_fname->fsp != NULL) {
5783 bool need_fsp_unlink = true;
5786 * This is really subtle. If someone passes in an smb_fname
5787 * where smb_fname actually is taken from fsp->fsp_name, then
5788 * the lifetime of these objects is meant to be the same.
5790 * This is commonly the case from an SMB1 path-based call,
5791 * (call_trans2qfilepathinfo) where we use the pathref fsp
5792 * (smb_fname->fsp) as the handle. In this case we must not
5793 * unlink smb_fname->fsp from it's owner.
5795 * The asserts below:
5797 * SMB_ASSERT(fsp->fsp_name->fsp != NULL);
5798 * SMB_ASSERT(fsp->fsp_name->fsp == fsp);
5800 * ensure the required invarients are met.
5802 if (smb_fname->fsp->fsp_name == smb_fname) {
5803 need_fsp_unlink = false;
5806 fsp = smb_fname->fsp;
5808 if (need_fsp_unlink) {
5810 * Unlink the fsp from the smb_fname so the fsp is not
5811 * autoclosed by the smb_fname pathref fsp talloc
5812 * destructor.
5814 smb_fname_fsp_unlink(smb_fname);
5817 status = fsp_bind_smb(fsp, req);
5818 if (!NT_STATUS_IS_OK(status)) {
5819 goto fail;
5822 if (fsp->base_fsp != NULL) {
5823 struct files_struct *tmp_base_fsp = fsp->base_fsp;
5825 fsp_set_base_fsp(fsp, NULL);
5827 fd_close(tmp_base_fsp);
5828 file_free(NULL, tmp_base_fsp);
5832 if (fsp == NULL) {
5833 /* Creating file */
5834 status = file_new(req, conn, &fsp);
5835 if(!NT_STATUS_IS_OK(status)) {
5836 goto fail;
5839 status = fsp_set_smb_fname(fsp, smb_fname);
5840 if (!NT_STATUS_IS_OK(status)) {
5841 goto fail;
5845 SMB_ASSERT(fsp->fsp_name->fsp != NULL);
5846 SMB_ASSERT(fsp->fsp_name->fsp == fsp);
5848 if (base_fsp) {
5850 * We're opening the stream element of a
5851 * base_fsp we already opened. Set up the
5852 * base_fsp pointer.
5854 fsp_set_base_fsp(fsp, base_fsp);
5858 * Get a pathref on the parent. We can re-use this
5859 * for multiple calls to check parent ACLs etc. to
5860 * avoid pathname calls.
5862 status = parent_pathref(talloc_tos(),
5863 conn->cwd_fsp,
5864 smb_fname,
5865 &parent_dir_fname,
5866 &smb_fname_atname);
5867 if (!NT_STATUS_IS_OK(status)) {
5868 goto fail;
5872 * If it's a request for a directory open, deal with it separately.
5875 if (create_options & FILE_DIRECTORY_FILE) {
5877 if (create_options & FILE_NON_DIRECTORY_FILE) {
5878 status = NT_STATUS_INVALID_PARAMETER;
5879 goto fail;
5882 /* Can't open a temp directory. IFS kit test. */
5883 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
5884 (file_attributes & FILE_ATTRIBUTE_TEMPORARY)) {
5885 status = NT_STATUS_INVALID_PARAMETER;
5886 goto fail;
5890 * We will get a create directory here if the Win32
5891 * app specified a security descriptor in the
5892 * CreateDirectory() call.
5895 oplock_request = 0;
5896 status = open_directory(conn,
5897 req,
5898 access_mask,
5899 share_access,
5900 create_disposition,
5901 create_options,
5902 file_attributes,
5903 parent_dir_fname,
5904 smb_fname_atname,
5905 &info,
5906 fsp);
5907 } else {
5910 * Ordinary file case.
5913 if (allocation_size) {
5914 fsp->initial_allocation_size = smb_roundup(fsp->conn,
5915 allocation_size);
5918 status = open_file_ntcreate(conn,
5919 req,
5920 access_mask,
5921 share_access,
5922 create_disposition,
5923 create_options,
5924 file_attributes,
5925 oplock_request,
5926 lease,
5927 private_flags,
5928 parent_dir_fname,
5929 smb_fname_atname,
5930 &info,
5931 fsp);
5932 if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
5934 /* A stream open never opens a directory */
5936 if (base_fsp) {
5937 status = NT_STATUS_FILE_IS_A_DIRECTORY;
5938 goto fail;
5942 * Fail the open if it was explicitly a non-directory
5943 * file.
5946 if (create_options & FILE_NON_DIRECTORY_FILE) {
5947 status = NT_STATUS_FILE_IS_A_DIRECTORY;
5948 goto fail;
5951 oplock_request = 0;
5952 status = open_directory(conn,
5953 req,
5954 access_mask,
5955 share_access,
5956 create_disposition,
5957 create_options,
5958 file_attributes,
5959 parent_dir_fname,
5960 smb_fname_atname,
5961 &info,
5962 fsp);
5966 if (!NT_STATUS_IS_OK(status)) {
5967 goto fail;
5970 fsp->fsp_flags.is_fsa = true;
5972 if ((ea_list != NULL) &&
5973 ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN))) {
5974 status = set_ea(conn, fsp, ea_list);
5975 if (!NT_STATUS_IS_OK(status)) {
5976 goto fail;
5980 if (!fsp->fsp_flags.is_directory &&
5981 S_ISDIR(fsp->fsp_name->st.st_ex_mode))
5983 status = NT_STATUS_ACCESS_DENIED;
5984 goto fail;
5987 /* Save the requested allocation size. */
5988 if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
5989 if ((allocation_size > (uint64_t)fsp->fsp_name->st.st_ex_size)
5990 && !(fsp->fsp_flags.is_directory))
5992 fsp->initial_allocation_size = smb_roundup(
5993 fsp->conn, allocation_size);
5994 if (vfs_allocate_file_space(
5995 fsp, fsp->initial_allocation_size) == -1) {
5996 status = NT_STATUS_DISK_FULL;
5997 goto fail;
5999 } else {
6000 fsp->initial_allocation_size = smb_roundup(
6001 fsp->conn, (uint64_t)fsp->fsp_name->st.st_ex_size);
6003 } else {
6004 fsp->initial_allocation_size = 0;
6007 if ((info == FILE_WAS_CREATED) && lp_nt_acl_support(SNUM(conn)) &&
6008 fsp->base_fsp == NULL) {
6009 if (sd != NULL) {
6011 * According to the MS documentation, the only time the security
6012 * descriptor is applied to the opened file is iff we *created* the
6013 * file; an existing file stays the same.
6015 * Also, it seems (from observation) that you can open the file with
6016 * any access mask but you can still write the sd. We need to override
6017 * the granted access before we call set_sd
6018 * Patch for bug #2242 from Tom Lackemann <cessnatomny@yahoo.com>.
6021 uint32_t sec_info_sent;
6022 uint32_t saved_access_mask = fsp->access_mask;
6024 sec_info_sent = get_sec_info(sd);
6026 fsp->access_mask = FILE_GENERIC_ALL;
6028 if (sec_info_sent & (SECINFO_OWNER|
6029 SECINFO_GROUP|
6030 SECINFO_DACL|
6031 SECINFO_SACL)) {
6032 status = set_sd(fsp, sd, sec_info_sent);
6035 fsp->access_mask = saved_access_mask;
6037 if (!NT_STATUS_IS_OK(status)) {
6038 goto fail;
6040 } else if (lp_inherit_acls(SNUM(conn))) {
6041 /* Inherit from parent. Errors here are not fatal. */
6042 status = inherit_new_acl(parent_dir_fname, fsp);
6043 if (!NT_STATUS_IS_OK(status)) {
6044 DEBUG(10,("inherit_new_acl: failed for %s with %s\n",
6045 fsp_str_dbg(fsp),
6046 nt_errstr(status) ));
6051 if ((conn->fs_capabilities & FILE_FILE_COMPRESSION)
6052 && (create_options & FILE_NO_COMPRESSION)
6053 && (info == FILE_WAS_CREATED)) {
6054 status = SMB_VFS_SET_COMPRESSION(conn, fsp, fsp,
6055 COMPRESSION_FORMAT_NONE);
6056 if (!NT_STATUS_IS_OK(status)) {
6057 DEBUG(1, ("failed to disable compression: %s\n",
6058 nt_errstr(status)));
6062 DEBUG(10, ("create_file_unixpath: info=%d\n", info));
6064 *result = fsp;
6065 if (pinfo != NULL) {
6066 *pinfo = info;
6069 smb_fname->st = fsp->fsp_name->st;
6071 TALLOC_FREE(parent_dir_fname);
6073 return NT_STATUS_OK;
6075 fail:
6076 DEBUG(10, ("create_file_unixpath: %s\n", nt_errstr(status)));
6078 if (fsp != NULL) {
6080 * The close_file below will close
6081 * fsp->base_fsp.
6083 base_fsp = NULL;
6084 close_file(req, fsp, ERROR_CLOSE);
6085 fsp = NULL;
6087 if (base_fsp != NULL) {
6088 close_file(req, base_fsp, ERROR_CLOSE);
6089 base_fsp = NULL;
6092 TALLOC_FREE(parent_dir_fname);
6094 return status;
6097 NTSTATUS create_file_default(connection_struct *conn,
6098 struct smb_request *req,
6099 struct smb_filename *smb_fname,
6100 uint32_t access_mask,
6101 uint32_t share_access,
6102 uint32_t create_disposition,
6103 uint32_t create_options,
6104 uint32_t file_attributes,
6105 uint32_t oplock_request,
6106 const struct smb2_lease *lease,
6107 uint64_t allocation_size,
6108 uint32_t private_flags,
6109 struct security_descriptor *sd,
6110 struct ea_list *ea_list,
6111 files_struct **result,
6112 int *pinfo,
6113 const struct smb2_create_blobs *in_context_blobs,
6114 struct smb2_create_blobs *out_context_blobs)
6116 int info = FILE_WAS_OPENED;
6117 files_struct *fsp = NULL;
6118 NTSTATUS status;
6119 bool stream_name = false;
6120 struct smb2_create_blob *posx = NULL;
6122 DBG_DEBUG("create_file: access_mask = 0x%x "
6123 "file_attributes = 0x%x, share_access = 0x%x, "
6124 "create_disposition = 0x%x create_options = 0x%x "
6125 "oplock_request = 0x%x "
6126 "private_flags = 0x%x "
6127 "ea_list = %p, sd = %p, "
6128 "fname = %s\n",
6129 (unsigned int)access_mask,
6130 (unsigned int)file_attributes,
6131 (unsigned int)share_access,
6132 (unsigned int)create_disposition,
6133 (unsigned int)create_options,
6134 (unsigned int)oplock_request,
6135 (unsigned int)private_flags,
6136 ea_list,
6138 smb_fname_str_dbg(smb_fname));
6140 if (req != NULL) {
6142 * Remember the absolute time of the original request
6143 * with this mid. We'll use it later to see if this
6144 * has timed out.
6146 get_deferred_open_message_state(req, &req->request_time, NULL);
6150 * Check to see if this is a mac fork of some kind.
6153 stream_name = is_ntfs_stream_smb_fname(smb_fname);
6154 if (stream_name) {
6155 enum FAKE_FILE_TYPE fake_file_type;
6157 fake_file_type = is_fake_file(smb_fname);
6159 if (req != NULL && fake_file_type != FAKE_FILE_TYPE_NONE) {
6162 * Here we go! support for changing the disk quotas
6163 * --metze
6165 * We need to fake up to open this MAGIC QUOTA file
6166 * and return a valid FID.
6168 * w2k close this file directly after openening xp
6169 * also tries a QUERY_FILE_INFO on the file and then
6170 * close it
6172 status = open_fake_file(req, conn, req->vuid,
6173 fake_file_type, smb_fname,
6174 access_mask, &fsp);
6175 if (!NT_STATUS_IS_OK(status)) {
6176 goto fail;
6179 ZERO_STRUCT(smb_fname->st);
6180 goto done;
6183 if (!(conn->fs_capabilities & FILE_NAMED_STREAMS)) {
6184 status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
6185 goto fail;
6189 if (is_ntfs_default_stream_smb_fname(smb_fname)) {
6190 int ret;
6191 smb_fname->stream_name = NULL;
6192 /* We have to handle this error here. */
6193 if (create_options & FILE_DIRECTORY_FILE) {
6194 status = NT_STATUS_NOT_A_DIRECTORY;
6195 goto fail;
6197 ret = vfs_stat(conn, smb_fname);
6198 if (ret == 0 && VALID_STAT_OF_DIR(smb_fname->st)) {
6199 status = NT_STATUS_FILE_IS_A_DIRECTORY;
6200 goto fail;
6204 posx = smb2_create_blob_find(
6205 in_context_blobs, SMB2_CREATE_TAG_POSIX);
6206 if (posx != NULL) {
6207 uint32_t wire_mode_bits = 0;
6208 mode_t mode_bits = 0;
6209 SMB_STRUCT_STAT sbuf = { 0 };
6210 enum perm_type ptype =
6211 (create_options & FILE_DIRECTORY_FILE) ?
6212 PERM_NEW_DIR : PERM_NEW_FILE;
6214 if (posx->data.length != 4) {
6215 status = NT_STATUS_INVALID_PARAMETER;
6216 goto fail;
6219 wire_mode_bits = IVAL(posx->data.data, 0);
6220 status = unix_perms_from_wire(
6221 conn, &sbuf, wire_mode_bits, ptype, &mode_bits);
6222 if (!NT_STATUS_IS_OK(status)) {
6223 goto fail;
6226 * Remove type info from mode, leaving only the
6227 * permissions and setuid/gid bits.
6229 mode_bits &= ~S_IFMT;
6231 file_attributes = (FILE_FLAG_POSIX_SEMANTICS | mode_bits);
6234 status = create_file_unixpath(conn,
6235 req,
6236 smb_fname,
6237 access_mask,
6238 share_access,
6239 create_disposition,
6240 create_options,
6241 file_attributes,
6242 oplock_request,
6243 lease,
6244 allocation_size,
6245 private_flags,
6247 ea_list,
6248 &fsp,
6249 &info);
6250 if (!NT_STATUS_IS_OK(status)) {
6251 goto fail;
6254 done:
6255 DEBUG(10, ("create_file: info=%d\n", info));
6257 *result = fsp;
6258 if (pinfo != NULL) {
6259 *pinfo = info;
6261 return NT_STATUS_OK;
6263 fail:
6264 DEBUG(10, ("create_file: %s\n", nt_errstr(status)));
6266 if (fsp != NULL) {
6267 close_file(req, fsp, ERROR_CLOSE);
6268 fsp = NULL;
6270 return status;