CVE-2020-25719 mit-samba: Add mit_samba_princ_needs_pac()
[Samba.git] / source3 / smbd / open.c
blobdf24f8d1b0e086b097da4ba2e5acdb17e368f878
1 /*
2 Unix SMB/CIFS implementation.
3 file opening and share modes
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Jeremy Allison 2001-2004
6 Copyright (C) Volker Lendecke 2005
7 Copyright (C) Ralph Boehme 2017
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "includes.h"
24 #include "smb1_utils.h"
25 #include "system/filesys.h"
26 #include "lib/util/server_id.h"
27 #include "printing.h"
28 #include "locking/share_mode_lock.h"
29 #include "smbd/smbd.h"
30 #include "smbd/globals.h"
31 #include "fake_file.h"
32 #include "../libcli/security/security.h"
33 #include "../librpc/gen_ndr/ndr_security.h"
34 #include "../librpc/gen_ndr/ndr_open_files.h"
35 #include "../librpc/gen_ndr/idmap.h"
36 #include "../librpc/gen_ndr/ioctl.h"
37 #include "passdb/lookup_sid.h"
38 #include "auth.h"
39 #include "serverid.h"
40 #include "messages.h"
41 #include "source3/lib/dbwrap/dbwrap_watch.h"
42 #include "locking/leases_db.h"
43 #include "librpc/gen_ndr/ndr_leases_db.h"
44 #include "lib/util/time_basic.h"
46 extern const struct generic_mapping file_generic_mapping;
48 struct deferred_open_record {
49 struct smbXsrv_connection *xconn;
50 uint64_t mid;
52 bool async_open;
55 * Timer for async opens, needed because they don't use a watch on
56 * a locking.tdb record. This is currently only used for real async
57 * opens and just terminates smbd if the async open times out.
59 struct tevent_timer *te;
62 * For the samba kernel oplock case we use both a timeout and
63 * a watch on locking.tdb. This way in case it's smbd holding
64 * the kernel oplock we get directly notified for the retry
65 * once the kernel oplock is properly broken. Store the req
66 * here so that it can be timely discarded once the timer
67 * above fires.
69 struct tevent_req *watch_req;
72 /****************************************************************************
73 If the requester wanted DELETE_ACCESS and was rejected because
74 the file ACL didn't include DELETE_ACCESS, see if the parent ACL
75 overrides this.
76 ****************************************************************************/
78 static bool parent_override_delete(connection_struct *conn,
79 struct files_struct *dirfsp,
80 const struct smb_filename *smb_fname,
81 uint32_t access_mask,
82 uint32_t rejected_mask)
84 if ((access_mask & DELETE_ACCESS) &&
85 (rejected_mask & DELETE_ACCESS) &&
86 can_delete_file_in_directory(conn,
87 dirfsp,
88 smb_fname))
90 return true;
92 return false;
95 /****************************************************************************
96 Check if we have open rights.
97 ****************************************************************************/
99 static NTSTATUS smbd_check_access_rights_sd(
100 struct connection_struct *conn,
101 struct files_struct *dirfsp,
102 const struct smb_filename *smb_fname,
103 struct security_descriptor *sd,
104 bool use_privs,
105 uint32_t access_mask)
107 uint32_t rejected_share_access;
108 uint32_t rejected_mask = access_mask;
109 uint32_t do_not_check_mask = 0;
110 NTSTATUS status;
112 rejected_share_access = access_mask & ~(conn->share_access);
114 if (rejected_share_access) {
115 DBG_DEBUG("rejected share access 0x%x on %s (0x%x)\n",
116 (unsigned int)access_mask,
117 smb_fname_str_dbg(smb_fname),
118 (unsigned int)rejected_share_access);
119 return NT_STATUS_ACCESS_DENIED;
122 if (!use_privs && get_current_uid(conn) == (uid_t)0) {
123 /* I'm sorry sir, I didn't know you were root... */
124 DBG_DEBUG("root override on %s. Granting 0x%x\n",
125 smb_fname_str_dbg(smb_fname),
126 (unsigned int)access_mask);
127 return NT_STATUS_OK;
130 if ((access_mask & DELETE_ACCESS) &&
131 !lp_acl_check_permissions(SNUM(conn)))
133 DBG_DEBUG("Not checking ACL on DELETE_ACCESS on file %s. "
134 "Granting 0x%x\n",
135 smb_fname_str_dbg(smb_fname),
136 (unsigned int)access_mask);
137 return NT_STATUS_OK;
140 if (access_mask == DELETE_ACCESS &&
141 VALID_STAT(smb_fname->st) &&
142 S_ISLNK(smb_fname->st.st_ex_mode))
144 /* We can always delete a symlink. */
145 DBG_DEBUG("Not checking ACL on DELETE_ACCESS on symlink %s.\n",
146 smb_fname_str_dbg(smb_fname));
147 return NT_STATUS_OK;
150 if (sd == NULL) {
151 goto access_denied;
155 * If we can access the path to this file, by
156 * default we have FILE_READ_ATTRIBUTES from the
157 * containing directory. See the section:
158 * "Algorithm to Check Access to an Existing File"
159 * in MS-FSA.pdf.
161 * se_file_access_check() also takes care of
162 * owner WRITE_DAC and READ_CONTROL.
164 do_not_check_mask = FILE_READ_ATTRIBUTES;
167 * Samba 3.6 and earlier granted execute access even
168 * if the ACL did not contain execute rights.
169 * Samba 4.0 is more correct and checks it.
170 * The compatibilty mode allows one to skip this check
171 * to smoothen upgrades.
173 if (lp_acl_allow_execute_always(SNUM(conn))) {
174 do_not_check_mask |= FILE_EXECUTE;
177 status = se_file_access_check(sd,
178 get_current_nttok(conn),
179 use_privs,
180 (access_mask & ~do_not_check_mask),
181 &rejected_mask);
183 DBG_DEBUG("File [%s] requesting [0x%x] returning [0x%x] (%s)\n",
184 smb_fname_str_dbg(smb_fname),
185 (unsigned int)access_mask,
186 (unsigned int)rejected_mask,
187 nt_errstr(status));
189 if (!NT_STATUS_IS_OK(status)) {
190 if (DEBUGLEVEL >= 10) {
191 DBG_DEBUG("acl for %s is:\n",
192 smb_fname_str_dbg(smb_fname));
193 NDR_PRINT_DEBUG(security_descriptor, sd);
197 TALLOC_FREE(sd);
199 if (NT_STATUS_IS_OK(status) ||
200 !NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED))
202 return status;
205 /* Here we know status == NT_STATUS_ACCESS_DENIED. */
207 access_denied:
209 if ((access_mask & FILE_WRITE_ATTRIBUTES) &&
210 (rejected_mask & FILE_WRITE_ATTRIBUTES) &&
211 !lp_store_dos_attributes(SNUM(conn)) &&
212 (lp_map_readonly(SNUM(conn)) ||
213 lp_map_archive(SNUM(conn)) ||
214 lp_map_hidden(SNUM(conn)) ||
215 lp_map_system(SNUM(conn))))
217 rejected_mask &= ~FILE_WRITE_ATTRIBUTES;
219 DBG_DEBUG("overrode FILE_WRITE_ATTRIBUTES on file %s\n",
220 smb_fname_str_dbg(smb_fname));
223 if (parent_override_delete(conn,
224 dirfsp,
225 smb_fname,
226 access_mask,
227 rejected_mask))
230 * Were we trying to do an open for delete and didn't get DELETE
231 * access. Check if the directory allows DELETE_CHILD.
232 * See here:
233 * http://blogs.msdn.com/oldnewthing/archive/2004/06/04/148426.aspx
234 * for details.
237 rejected_mask &= ~DELETE_ACCESS;
239 DBG_DEBUG("Overrode DELETE_ACCESS on file %s\n",
240 smb_fname_str_dbg(smb_fname));
243 if (rejected_mask != 0) {
244 return NT_STATUS_ACCESS_DENIED;
246 return NT_STATUS_OK;
249 NTSTATUS smbd_check_access_rights_fsp(struct files_struct *dirfsp,
250 struct files_struct *fsp,
251 bool use_privs,
252 uint32_t access_mask)
254 struct security_descriptor *sd = NULL;
255 NTSTATUS status;
257 /* Cope with fake/printer fsp's. */
258 if (fsp->fake_file_handle != NULL || fsp->print_file != NULL) {
259 if ((fsp->access_mask & access_mask) != access_mask) {
260 return NT_STATUS_ACCESS_DENIED;
262 return NT_STATUS_OK;
265 if (fsp_get_pathref_fd(fsp) == -1) {
267 * This is a POSIX open on a symlink. For the pathname
268 * verison of this function we used to return the st_mode
269 * bits turned into an NT ACL. For a symlink the mode bits
270 * are always rwxrwxrwx which means the pathname version always
271 * returned NT_STATUS_OK for a symlink. For the handle reference
272 * to a symlink use the handle access bits.
274 if ((fsp->access_mask & access_mask) != access_mask) {
275 return NT_STATUS_ACCESS_DENIED;
277 return NT_STATUS_OK;
280 status = SMB_VFS_FGET_NT_ACL(fsp,
281 (SECINFO_OWNER |
282 SECINFO_GROUP |
283 SECINFO_DACL),
284 talloc_tos(),
285 &sd);
286 if (!NT_STATUS_IS_OK(status)) {
287 DBG_DEBUG("Could not get acl on %s: %s\n",
288 fsp_str_dbg(fsp),
289 nt_errstr(status));
290 return status;
293 return smbd_check_access_rights_sd(fsp->conn,
294 dirfsp,
295 fsp->fsp_name,
297 use_privs,
298 access_mask);
302 * Given an fsp that represents a parent directory,
303 * check if the requested access can be granted.
305 NTSTATUS check_parent_access_fsp(struct files_struct *fsp,
306 uint32_t access_mask)
308 NTSTATUS status;
309 struct security_descriptor *parent_sd = NULL;
310 uint32_t access_granted = 0;
311 struct share_mode_lock *lck = NULL;
312 uint32_t name_hash;
313 bool delete_on_close_set;
314 TALLOC_CTX *frame = talloc_stackframe();
316 if (get_current_uid(fsp->conn) == (uid_t)0) {
317 /* I'm sorry sir, I didn't know you were root... */
318 DBG_DEBUG("root override on %s. Granting 0x%x\n",
319 fsp_str_dbg(fsp),
320 (unsigned int)access_mask);
321 status = NT_STATUS_OK;
322 goto out;
325 status = SMB_VFS_FGET_NT_ACL(fsp,
326 SECINFO_DACL,
327 frame,
328 &parent_sd);
330 if (!NT_STATUS_IS_OK(status)) {
331 DBG_INFO("SMB_VFS_FGET_NT_ACL failed for "
332 "%s with error %s\n",
333 fsp_str_dbg(fsp),
334 nt_errstr(status));
335 goto out;
339 * If we can access the path to this file, by
340 * default we have FILE_READ_ATTRIBUTES from the
341 * containing directory. See the section:
342 * "Algorithm to Check Access to an Existing File"
343 * in MS-FSA.pdf.
345 * se_file_access_check() also takes care of
346 * owner WRITE_DAC and READ_CONTROL.
348 status = se_file_access_check(parent_sd,
349 get_current_nttok(fsp->conn),
350 false,
351 (access_mask & ~FILE_READ_ATTRIBUTES),
352 &access_granted);
353 if(!NT_STATUS_IS_OK(status)) {
354 DBG_INFO("access check "
355 "on directory %s for mask 0x%x returned (0x%x) %s\n",
356 fsp_str_dbg(fsp),
357 access_mask,
358 access_granted,
359 nt_errstr(status));
360 goto out;
363 if (!(access_mask & (SEC_DIR_ADD_FILE | SEC_DIR_ADD_SUBDIR))) {
364 status = NT_STATUS_OK;
365 goto out;
367 if (!lp_check_parent_directory_delete_on_close(SNUM(fsp->conn))) {
368 status = NT_STATUS_OK;
369 goto out;
372 /* Check if the directory has delete-on-close set */
373 status = file_name_hash(fsp->conn,
374 fsp->fsp_name->base_name,
375 &name_hash);
376 if (!NT_STATUS_IS_OK(status)) {
377 goto out;
381 * Don't take a lock here. We just need a snapshot
382 * of the current state of delete on close and this is
383 * called in a codepath where we may already have a lock
384 * (and we explicitly can't hold 2 locks at the same time
385 * as that may deadlock).
387 lck = fetch_share_mode_unlocked(frame, fsp->file_id);
388 if (lck == NULL) {
389 status = NT_STATUS_OK;
390 goto out;
393 delete_on_close_set = is_delete_on_close_set(lck, name_hash);
394 if (delete_on_close_set) {
395 status = NT_STATUS_DELETE_PENDING;
396 goto out;
399 status = NT_STATUS_OK;
401 out:
402 TALLOC_FREE(frame);
403 return status;
406 /****************************************************************************
407 Ensure when opening a base file for a stream open that we have permissions
408 to do so given the access mask on the base file.
409 ****************************************************************************/
411 static NTSTATUS check_base_file_access(struct files_struct *fsp,
412 uint32_t access_mask)
414 NTSTATUS status;
416 status = smbd_calculate_access_mask_fsp(fsp->conn->cwd_fsp,
417 fsp,
418 false,
419 access_mask,
420 &access_mask);
421 if (!NT_STATUS_IS_OK(status)) {
422 DEBUG(10, ("smbd_calculate_access_mask "
423 "on file %s returned %s\n",
424 fsp_str_dbg(fsp),
425 nt_errstr(status)));
426 return status;
429 if (access_mask & (FILE_WRITE_DATA|FILE_APPEND_DATA)) {
430 uint32_t dosattrs;
431 if (!CAN_WRITE(fsp->conn)) {
432 return NT_STATUS_ACCESS_DENIED;
434 dosattrs = fdos_mode(fsp);
435 if (IS_DOS_READONLY(dosattrs)) {
436 return NT_STATUS_ACCESS_DENIED;
440 return smbd_check_access_rights_fsp(fsp->conn->cwd_fsp,
441 fsp,
442 false,
443 access_mask);
446 /****************************************************************************
447 Handle differing symlink errno's
448 ****************************************************************************/
450 static NTSTATUS link_errno_convert(int err)
452 #if defined(ENOTSUP) && defined(OSF1)
453 /* handle special Tru64 errno */
454 if (err == ENOTSUP) {
455 err = ELOOP;
457 #endif /* ENOTSUP */
458 #ifdef EFTYPE
459 /* fix broken NetBSD errno */
460 if (err == EFTYPE) {
461 err = ELOOP;
463 #endif /* EFTYPE */
464 /* fix broken FreeBSD errno */
465 if (err == EMLINK) {
466 err = ELOOP;
468 if (err == ELOOP) {
469 return NT_STATUS_STOPPED_ON_SYMLINK;
471 return map_nt_error_from_unix(err);
474 static NTSTATUS non_widelink_open(const struct files_struct *dirfsp,
475 files_struct *fsp,
476 struct smb_filename *smb_fname,
477 int flags,
478 mode_t mode,
479 unsigned int link_depth);
481 /****************************************************************************
482 Follow a symlink in userspace.
483 ****************************************************************************/
485 static NTSTATUS process_symlink_open(const struct files_struct *dirfsp,
486 files_struct *fsp,
487 struct smb_filename *smb_fname,
488 int flags,
489 mode_t mode,
490 unsigned int link_depth)
492 struct connection_struct *conn = dirfsp->conn;
493 const char *conn_rootdir = NULL;
494 struct smb_filename conn_rootdir_fname = { 0 };
495 char *link_target = NULL;
496 int link_len = -1;
497 struct smb_filename *oldwd_fname = NULL;
498 size_t rootdir_len = 0;
499 struct smb_filename *resolved_fname = NULL;
500 char *resolved_name = NULL;
501 bool matched = false;
502 struct smb_filename *full_fname = NULL;
503 NTSTATUS status;
505 conn_rootdir = SMB_VFS_CONNECTPATH(conn, smb_fname);
506 if (conn_rootdir == NULL) {
507 return NT_STATUS_NO_MEMORY;
510 * With shadow_copy2 conn_rootdir can be talloc_freed
511 * whilst we use it in this function. We must take a copy.
513 conn_rootdir_fname.base_name = talloc_strdup(talloc_tos(),
514 conn_rootdir);
515 if (conn_rootdir_fname.base_name == NULL) {
516 return NT_STATUS_NO_MEMORY;
520 * Ensure we don't get stuck in a symlink loop.
522 link_depth++;
523 if (link_depth >= 20) {
524 status = NT_STATUS_STOPPED_ON_SYMLINK;
525 goto out;
528 /* Allocate space for the link target. */
529 link_target = talloc_array(talloc_tos(), char, PATH_MAX);
530 if (link_target == NULL) {
531 status = NT_STATUS_NO_MEMORY;
532 goto out;
536 * Read the link target. We do this just to verify that smb_fname indeed
537 * points at a symbolic link and return NT_STATUS_NOT_A_DIRECTORY
538 * and failure in case smb_fname is NOT a symlink.
540 * The caller needs this piece of information to distinguish two cases
541 * where open() fails with errno=ENOTDIR, cf the comment in
542 * non_widelink_open().
544 * We rely on SMB_VFS_REALPATH() to resolve the path including the
545 * symlink. Once we have SMB_VFS_STATX() or something similar in our VFS
546 * we may want to use that instead of SMB_VFS_READLINKAT().
548 link_len = SMB_VFS_READLINKAT(conn,
549 dirfsp,
550 smb_fname,
551 link_target,
552 PATH_MAX - 1);
553 if (link_len == -1) {
554 status = NT_STATUS_INVALID_PARAMETER;
555 goto out;
558 full_fname = full_path_from_dirfsp_atname(
559 talloc_tos(), dirfsp, smb_fname);
560 if (full_fname == NULL) {
561 status = NT_STATUS_NO_MEMORY;
562 goto out;
565 /* Convert to an absolute path. */
566 resolved_fname = SMB_VFS_REALPATH(conn, talloc_tos(), full_fname);
567 if (resolved_fname == NULL) {
568 status = map_nt_error_from_unix(errno);
569 goto out;
571 resolved_name = resolved_fname->base_name;
574 * We know conn_rootdir starts with '/' and
575 * does not end in '/'. FIXME ! Should we
576 * smb_assert this ?
578 rootdir_len = strlen(conn_rootdir_fname.base_name);
580 matched = (strncmp(conn_rootdir_fname.base_name,
581 resolved_name,
582 rootdir_len) == 0);
583 if (!matched) {
584 status = NT_STATUS_STOPPED_ON_SYMLINK;
585 goto out;
589 * Turn into a path relative to the share root.
591 if (resolved_name[rootdir_len] == '\0') {
592 /* Link to the root of the share. */
593 TALLOC_FREE(smb_fname->base_name);
594 smb_fname->base_name = talloc_strdup(smb_fname, ".");
595 } else if (resolved_name[rootdir_len] == '/') {
596 TALLOC_FREE(smb_fname->base_name);
597 smb_fname->base_name = talloc_strdup(smb_fname,
598 &resolved_name[rootdir_len+1]);
599 } else {
600 status = NT_STATUS_STOPPED_ON_SYMLINK;
601 goto out;
604 if (smb_fname->base_name == NULL) {
605 status = NT_STATUS_NO_MEMORY;
606 goto out;
609 oldwd_fname = vfs_GetWd(talloc_tos(), dirfsp->conn);
610 if (oldwd_fname == NULL) {
611 status = map_nt_error_from_unix(errno);
612 goto out;
615 /* Ensure we operate from the root of the share. */
616 if (vfs_ChDir(conn, &conn_rootdir_fname) == -1) {
617 status = map_nt_error_from_unix(errno);
618 goto out;
622 * And do it all again... As smb_fname is not relative to the passed in
623 * dirfsp anymore, we pass conn->cwd_fsp as dirfsp to
624 * non_widelink_open() to trigger the chdir(parentdir) logic.
626 status = non_widelink_open(conn->cwd_fsp,
627 fsp,
628 smb_fname,
629 flags,
630 mode,
631 link_depth);
633 out:
635 TALLOC_FREE(resolved_fname);
636 TALLOC_FREE(link_target);
637 TALLOC_FREE(conn_rootdir_fname.base_name);
638 if (oldwd_fname != NULL) {
639 int ret = vfs_ChDir(conn, oldwd_fname);
640 if (ret == -1) {
641 smb_panic("unable to get back to old directory\n");
643 TALLOC_FREE(oldwd_fname);
646 return status;
649 /****************************************************************************
650 Non-widelink open.
651 ****************************************************************************/
653 static NTSTATUS non_widelink_open(const struct files_struct *dirfsp,
654 files_struct *fsp,
655 struct smb_filename *smb_fname,
656 int flags,
657 mode_t mode,
658 unsigned int link_depth)
660 struct connection_struct *conn = fsp->conn;
661 NTSTATUS saved_status;
662 NTSTATUS status = NT_STATUS_OK;
663 int fd = -1;
664 struct smb_filename *orig_fsp_name = fsp->fsp_name;
665 struct smb_filename *orig_base_fsp_name = NULL;
666 struct smb_filename *smb_fname_rel = NULL;
667 struct smb_filename *oldwd_fname = NULL;
668 struct smb_filename *parent_dir_fname = NULL;
669 bool have_opath = false;
670 int ret;
672 #ifdef O_PATH
673 have_opath = true;
674 #endif
676 if (dirfsp == conn->cwd_fsp) {
677 if (fsp->fsp_flags.is_directory) {
678 parent_dir_fname = cp_smb_filename(talloc_tos(), smb_fname);
679 if (parent_dir_fname == NULL) {
680 status = NT_STATUS_NO_MEMORY;
681 goto out;
684 smb_fname_rel = synthetic_smb_fname(parent_dir_fname,
685 ".",
686 smb_fname->stream_name,
687 &smb_fname->st,
688 smb_fname->twrp,
689 smb_fname->flags);
690 if (smb_fname_rel == NULL) {
691 status = NT_STATUS_NO_MEMORY;
692 goto out;
694 } else {
695 status = SMB_VFS_PARENT_PATHNAME(fsp->conn,
696 talloc_tos(),
697 smb_fname,
698 &parent_dir_fname,
699 &smb_fname_rel);
700 if (!NT_STATUS_IS_OK(status)) {
701 goto out;
705 if (!ISDOT(parent_dir_fname->base_name)) {
706 oldwd_fname = vfs_GetWd(talloc_tos(), conn);
707 if (oldwd_fname == NULL) {
708 status = map_nt_error_from_unix(errno);
709 goto out;
712 /* Pin parent directory in place. */
713 if (vfs_ChDir(conn, parent_dir_fname) == -1) {
714 status = map_nt_error_from_unix(errno);
715 goto out;
719 /* Ensure the relative path is below the share. */
720 status = check_reduced_name(conn, parent_dir_fname, smb_fname_rel);
721 if (!NT_STATUS_IS_OK(status)) {
722 goto out;
725 /* Setup fsp->fsp_name to be relative to cwd */
726 fsp->fsp_name = smb_fname_rel;
728 /* Also setup base_fsp to be relative to the new cwd */
729 if (fsp->base_fsp != NULL) {
730 struct smb_filename *base_smb_fname_rel = NULL;
732 /* Check the invarient is true. */
733 SMB_ASSERT(fsp->base_fsp->fsp_name->fsp ==
734 fsp->base_fsp);
736 base_smb_fname_rel = synthetic_smb_fname(
737 talloc_tos(),
738 smb_fname_rel->base_name,
739 NULL,
740 &smb_fname_rel->st,
741 smb_fname_rel->twrp,
742 smb_fname_rel->flags);
743 if (base_smb_fname_rel == NULL) {
744 status = NT_STATUS_NO_MEMORY;
745 goto out;
748 base_smb_fname_rel->fsp = fsp->base_fsp;
750 orig_base_fsp_name = fsp->base_fsp->fsp_name;
751 fsp->base_fsp->fsp_name = base_smb_fname_rel;
754 * We should have preserved the invarient
755 * fsp->base_fsp->fsp_name->fsp == fsp->base_fsp.
757 SMB_ASSERT(fsp->base_fsp->fsp_name->fsp ==
758 fsp->base_fsp);
760 } else {
762 * fsp->fsp_name is unchanged as it is already correctly
763 * relative to conn->cwd.
765 smb_fname_rel = smb_fname;
768 flags |= O_NOFOLLOW;
770 fd = SMB_VFS_OPENAT(conn,
771 dirfsp,
772 smb_fname_rel,
773 fsp,
774 flags,
775 mode);
776 if (fd == -1) {
777 status = link_errno_convert(errno);
779 fsp_set_fd(fsp, fd);
781 if (fd != -1) {
782 ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st);
783 if (ret != 0) {
784 status = map_nt_error_from_unix(errno);
785 goto out;
787 orig_fsp_name->st = fsp->fsp_name->st;
790 if (!is_ntfs_stream_smb_fname(fsp->fsp_name) &&
791 fsp->fsp_flags.is_pathref &&
792 have_opath)
795 * Opening with O_PATH and O_NOFOLLOW opens a handle on the
796 * symlink. In follow symlink=yes mode we must avoid this and
797 * instead should open a handle on the symlink target.
799 * Check for this case by doing an fstat, forcing
800 * process_symlink_open() codepath down below by setting fd=-1
801 * and errno=ELOOP.
803 if (S_ISLNK(fsp->fsp_name->st.st_ex_mode)) {
804 ret = SMB_VFS_CLOSE(fsp);
805 SMB_ASSERT(ret == 0);
807 fsp_set_fd(fsp, -1);
808 fd = -1;
809 status = NT_STATUS_STOPPED_ON_SYMLINK;
813 if ((fd == -1) &&
814 (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK) ||
815 NT_STATUS_EQUAL(status, NT_STATUS_NOT_A_DIRECTORY)))
818 * Trying to open a symlink to a directory with O_NOFOLLOW and
819 * O_DIRECTORY can return either of ELOOP and ENOTDIR. So
820 * ENOTDIR really means: might be a symlink, but we're not sure.
821 * In this case, we just assume there's a symlink. If we were
822 * wrong, process_symlink_open() will return EINVAL. We check
823 * this below, and fall back to returning the initial
824 * saved_errno.
826 * BUG: https://bugzilla.samba.org/show_bug.cgi?id=12860
828 saved_status = status;
830 if (fsp->fsp_name->flags & SMB_FILENAME_POSIX_PATH) {
831 /* Never follow symlinks on posix open. */
832 goto out;
834 if (!lp_follow_symlinks(SNUM(conn))) {
835 /* Explicitly no symlinks. */
836 goto out;
839 fsp->fsp_name = orig_fsp_name;
842 * We may have a symlink. Follow in userspace
843 * to ensure it's under the share definition.
845 status = process_symlink_open(dirfsp,
846 fsp,
847 smb_fname_rel,
848 flags,
849 mode,
850 link_depth);
851 if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER) &&
852 NT_STATUS_EQUAL(saved_status, NT_STATUS_NOT_A_DIRECTORY))
854 status = saved_status;
858 out:
859 fsp->fsp_name = orig_fsp_name;
860 if (fsp->base_fsp != NULL) {
861 /* Save off the temporary name. */
862 struct smb_filename *base_smb_fname_rel =
863 fsp->base_fsp->fsp_name;
864 /* It no longer has an associated fsp. */
865 base_smb_fname_rel->fsp = NULL;
867 /* Replace the original name. */
868 fsp->base_fsp->fsp_name = orig_base_fsp_name;
870 * We should have preserved the invarient
871 * fsp->base_fsp->fsp_name->fsp == fsp->base_fsp.
873 SMB_ASSERT(fsp->base_fsp->fsp_name->fsp == fsp->base_fsp);
874 TALLOC_FREE(base_smb_fname_rel);
876 TALLOC_FREE(parent_dir_fname);
878 if (oldwd_fname != NULL) {
879 ret = vfs_ChDir(conn, oldwd_fname);
880 if (ret == -1) {
881 smb_panic("unable to get back to old directory\n");
883 TALLOC_FREE(oldwd_fname);
885 return status;
888 /****************************************************************************
889 fd support routines - attempt to do a dos_open.
890 ****************************************************************************/
892 NTSTATUS fd_openat(const struct files_struct *dirfsp,
893 struct smb_filename *smb_fname,
894 files_struct *fsp,
895 int flags,
896 mode_t mode)
898 struct connection_struct *conn = fsp->conn;
899 NTSTATUS status = NT_STATUS_OK;
902 * Never follow symlinks on a POSIX client. The
903 * client should be doing this.
906 if ((fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) || !lp_follow_symlinks(SNUM(conn))) {
907 flags |= O_NOFOLLOW;
911 * Only follow symlinks within a share
912 * definition.
914 status = non_widelink_open(dirfsp, fsp, smb_fname, flags, mode, 0);
915 if (!NT_STATUS_IS_OK(status)) {
916 if (NT_STATUS_EQUAL(status, NT_STATUS_TOO_MANY_OPENED_FILES)) {
917 static time_t last_warned = 0L;
919 if (time((time_t *) NULL) > last_warned) {
920 DEBUG(0,("Too many open files, unable "
921 "to open more! smbd's max "
922 "open files = %d\n",
923 lp_max_open_files()));
924 last_warned = time((time_t *) NULL);
928 DBG_DEBUG("name %s, flags = 0%o mode = 0%o, fd = %d. %s\n",
929 smb_fname_str_dbg(smb_fname), flags, (int)mode,
930 fsp_get_pathref_fd(fsp), nt_errstr(status));
931 return status;
934 DBG_DEBUG("name %s, flags = 0%o mode = 0%o, fd = %d\n",
935 smb_fname_str_dbg(smb_fname), flags, (int)mode,
936 fsp_get_pathref_fd(fsp));
938 return status;
941 /****************************************************************************
942 Close the file associated with a fsp.
943 ****************************************************************************/
945 NTSTATUS fd_close(files_struct *fsp)
947 int ret;
949 if (fsp == fsp->conn->cwd_fsp) {
950 return NT_STATUS_OK;
953 if (fsp->dptr) {
954 dptr_CloseDir(fsp);
956 if (fsp_get_pathref_fd(fsp) == -1) {
958 * Either a directory where the dptr_CloseDir() already closed
959 * the fd or a stat open.
961 return NT_STATUS_OK;
963 if (fh_get_refcount(fsp->fh) > 1) {
964 return NT_STATUS_OK; /* Shared handle. Only close last reference. */
967 ret = SMB_VFS_CLOSE(fsp);
968 fsp_set_fd(fsp, -1);
969 if (ret == -1) {
970 return map_nt_error_from_unix(errno);
972 return NT_STATUS_OK;
975 /****************************************************************************
976 Change the ownership of a file to that of the parent directory.
977 Do this by fd if possible.
978 ****************************************************************************/
980 static void change_file_owner_to_parent_fsp(struct files_struct *parent_fsp,
981 struct files_struct *fsp)
983 int ret;
985 if (parent_fsp->fsp_name->st.st_ex_uid == fsp->fsp_name->st.st_ex_uid) {
986 /* Already this uid - no need to change. */
987 DBG_DEBUG("file %s is already owned by uid %u\n",
988 fsp_str_dbg(fsp),
989 (unsigned int)fsp->fsp_name->st.st_ex_uid);
990 return;
993 become_root();
994 ret = SMB_VFS_FCHOWN(fsp,
995 parent_fsp->fsp_name->st.st_ex_uid,
996 (gid_t)-1);
997 unbecome_root();
998 if (ret == -1) {
999 DBG_ERR("failed to fchown "
1000 "file %s to parent directory uid %u. Error "
1001 "was %s\n",
1002 fsp_str_dbg(fsp),
1003 (unsigned int)parent_fsp->fsp_name->st.st_ex_uid,
1004 strerror(errno));
1005 } else {
1006 DBG_DEBUG("changed new file %s to "
1007 "parent directory uid %u.\n",
1008 fsp_str_dbg(fsp),
1009 (unsigned int)parent_fsp->fsp_name->st.st_ex_uid);
1010 /* Ensure the uid entry is updated. */
1011 fsp->fsp_name->st.st_ex_uid =
1012 parent_fsp->fsp_name->st.st_ex_uid;
1016 static NTSTATUS change_dir_owner_to_parent_fsp(struct files_struct *parent_fsp,
1017 struct files_struct *fsp)
1019 NTSTATUS status;
1020 int ret;
1022 if (parent_fsp->fsp_name->st.st_ex_uid == fsp->fsp_name->st.st_ex_uid) {
1023 /* Already this uid - no need to change. */
1024 DBG_DEBUG("directory %s is already owned by uid %u\n",
1025 fsp_str_dbg(fsp),
1026 (unsigned int)fsp->fsp_name->st.st_ex_uid);
1027 return NT_STATUS_OK;
1030 become_root();
1031 ret = SMB_VFS_FCHOWN(fsp,
1032 parent_fsp->fsp_name->st.st_ex_uid,
1033 (gid_t)-1);
1034 unbecome_root();
1035 if (ret == -1) {
1036 status = map_nt_error_from_unix(errno);
1037 DBG_ERR("failed to chown "
1038 "directory %s to parent directory uid %u. "
1039 "Error was %s\n",
1040 fsp_str_dbg(fsp),
1041 (unsigned int)parent_fsp->fsp_name->st.st_ex_uid,
1042 nt_errstr(status));
1043 return status;
1046 DBG_DEBUG("changed ownership of new "
1047 "directory %s to parent directory uid %u.\n",
1048 fsp_str_dbg(fsp),
1049 (unsigned int)parent_fsp->fsp_name->st.st_ex_uid);
1051 /* Ensure the uid entry is updated. */
1052 fsp->fsp_name->st.st_ex_uid = parent_fsp->fsp_name->st.st_ex_uid;
1054 return NT_STATUS_OK;
1057 /****************************************************************************
1058 Open a file - returning a guaranteed ATOMIC indication of if the
1059 file was created or not.
1060 ****************************************************************************/
1062 static NTSTATUS fd_open_atomic(files_struct *fsp,
1063 int flags,
1064 mode_t mode,
1065 bool *file_created)
1067 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
1068 NTSTATUS retry_status;
1069 bool file_existed = VALID_STAT(fsp->fsp_name->st);
1070 int curr_flags;
1072 if (!(flags & O_CREAT)) {
1074 * We're not creating the file, just pass through.
1076 status = fd_openat(fsp->conn->cwd_fsp, fsp->fsp_name, fsp, flags, mode);
1077 *file_created = false;
1078 return status;
1081 if (flags & O_EXCL) {
1083 * Fail if already exists, just pass through.
1085 status = fd_openat(fsp->conn->cwd_fsp, fsp->fsp_name, fsp, flags, mode);
1088 * Here we've opened with O_CREAT|O_EXCL. If that went
1089 * NT_STATUS_OK, we *know* we created this file.
1091 *file_created = NT_STATUS_IS_OK(status);
1093 return status;
1097 * Now it gets tricky. We have O_CREAT, but not O_EXCL.
1098 * To know absolutely if we created the file or not,
1099 * we can never call O_CREAT without O_EXCL. So if
1100 * we think the file existed, try without O_CREAT|O_EXCL.
1101 * If we think the file didn't exist, try with
1102 * O_CREAT|O_EXCL.
1104 * The big problem here is dangling symlinks. Opening
1105 * without O_NOFOLLOW means both bad symlink
1106 * and missing path return -1, ENOENT from open(). As POSIX
1107 * is pathname based it's not possible to tell
1108 * the difference between these two cases in a
1109 * non-racy way, so change to try only two attempts before
1110 * giving up.
1112 * We don't have this problem for the O_NOFOLLOW
1113 * case as it just returns NT_STATUS_OBJECT_PATH_NOT_FOUND
1114 * mapped from the ELOOP POSIX error.
1117 if (file_existed) {
1118 curr_flags = flags & ~(O_CREAT);
1119 retry_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
1120 } else {
1121 curr_flags = flags | O_EXCL;
1122 retry_status = NT_STATUS_OBJECT_NAME_COLLISION;
1125 status = fd_openat(fsp->conn->cwd_fsp, fsp->fsp_name, fsp, curr_flags, mode);
1126 if (NT_STATUS_IS_OK(status)) {
1127 *file_created = !file_existed;
1128 return NT_STATUS_OK;
1130 if (NT_STATUS_EQUAL(status, retry_status)) {
1132 file_existed = !file_existed;
1134 DBG_DEBUG("File %s %s. Retry.\n",
1135 fsp_str_dbg(fsp),
1136 file_existed ? "existed" : "did not exist");
1138 if (file_existed) {
1139 curr_flags = flags & ~(O_CREAT);
1140 } else {
1141 curr_flags = flags | O_EXCL;
1144 status = fd_openat(fsp->conn->cwd_fsp, fsp->fsp_name, fsp, curr_flags, mode);
1147 *file_created = (NT_STATUS_IS_OK(status) && !file_existed);
1148 return status;
1151 static NTSTATUS reopen_from_procfd(struct files_struct *fsp,
1152 int flags,
1153 mode_t mode)
1155 struct smb_filename proc_fname;
1156 const char *p = NULL;
1157 char buf[PATH_MAX];
1158 int old_fd;
1159 int new_fd;
1160 NTSTATUS status;
1161 int ret;
1163 if (!fsp->fsp_flags.have_proc_fds) {
1164 return NT_STATUS_MORE_PROCESSING_REQUIRED;
1167 old_fd = fsp_get_pathref_fd(fsp);
1168 if (old_fd == -1) {
1169 return NT_STATUS_MORE_PROCESSING_REQUIRED;
1172 if (!fsp->fsp_flags.is_pathref) {
1173 DBG_ERR("[%s] is not a pathref\n",
1174 fsp_str_dbg(fsp));
1175 #ifdef DEVELOPER
1176 smb_panic("Not a pathref");
1177 #endif
1178 return NT_STATUS_INVALID_HANDLE;
1181 p = sys_proc_fd_path(old_fd, buf, sizeof(buf));
1182 if (p == NULL) {
1183 return NT_STATUS_NO_MEMORY;
1186 proc_fname = (struct smb_filename) {
1187 .base_name = discard_const_p(char, p),
1190 fsp->fsp_flags.is_pathref = false;
1192 new_fd = SMB_VFS_OPENAT(fsp->conn,
1193 fsp->conn->cwd_fsp,
1194 &proc_fname,
1195 fsp,
1196 flags,
1197 mode);
1198 if (new_fd == -1) {
1199 status = map_nt_error_from_unix(errno);
1200 SMB_VFS_CLOSE(fsp);
1201 fsp_set_fd(fsp, -1);
1202 return status;
1205 ret = SMB_VFS_CLOSE(fsp);
1206 fsp_set_fd(fsp, -1);
1207 if (ret != 0) {
1208 return map_nt_error_from_unix(errno);
1211 fsp_set_fd(fsp, new_fd);
1212 return NT_STATUS_OK;
1215 static NTSTATUS reopen_from_fsp(struct files_struct *fsp,
1216 int flags,
1217 mode_t mode,
1218 bool *p_file_created)
1220 bool __unused_file_created = false;
1221 NTSTATUS status;
1223 if (p_file_created == NULL) {
1224 p_file_created = &__unused_file_created;
1228 * TODO: should we move this to the VFS layer?
1229 * SMB_VFS_REOPEN_FSP()?
1232 status = reopen_from_procfd(fsp,
1233 flags,
1234 mode);
1235 if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1237 * Close the existing pathref fd and set the fsp flag
1238 * is_pathref to false so we get a "normal" fd this
1239 * time.
1241 status = fd_close(fsp);
1242 if (!NT_STATUS_IS_OK(status)) {
1243 return status;
1246 fsp->fsp_flags.is_pathref = false;
1248 status = fd_open_atomic(fsp,
1249 flags,
1250 mode,
1251 p_file_created);
1254 return status;
1257 /****************************************************************************
1258 Open a file.
1259 ****************************************************************************/
1261 static NTSTATUS open_file(files_struct *fsp,
1262 struct smb_request *req,
1263 struct smb_filename *parent_dir,
1264 int flags,
1265 mode_t unx_mode,
1266 uint32_t access_mask, /* client requested access mask. */
1267 uint32_t open_access_mask, /* what we're actually using in the open. */
1268 uint32_t private_flags,
1269 bool *p_file_created)
1271 connection_struct *conn = fsp->conn;
1272 struct smb_filename *smb_fname = fsp->fsp_name;
1273 NTSTATUS status = NT_STATUS_OK;
1274 int accmode = (flags & O_ACCMODE);
1275 int local_flags = flags;
1276 bool file_existed = VALID_STAT(fsp->fsp_name->st);
1277 uint32_t need_fd_mask =
1278 FILE_READ_DATA |
1279 FILE_WRITE_DATA |
1280 FILE_APPEND_DATA |
1281 FILE_EXECUTE |
1282 SEC_FLAG_SYSTEM_SECURITY;
1283 bool creating = !file_existed && (flags & O_CREAT);
1284 bool truncating = (flags & O_TRUNC);
1285 bool open_fd = false;
1288 * Catch early an attempt to open an existing
1289 * directory as a file.
1291 if (file_existed && S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
1292 return NT_STATUS_FILE_IS_A_DIRECTORY;
1295 /* Check permissions */
1298 * This code was changed after seeing a client open request
1299 * containing the open mode of (DENY_WRITE/read-only) with
1300 * the 'create if not exist' bit set. The previous code
1301 * would fail to open the file read only on a read-only share
1302 * as it was checking the flags parameter directly against O_RDONLY,
1303 * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
1304 * JRA.
1307 if (!CAN_WRITE(conn)) {
1308 /* It's a read-only share - fail if we wanted to write. */
1309 if(accmode != O_RDONLY || (flags & O_TRUNC) || (flags & O_APPEND)) {
1310 DEBUG(3,("Permission denied opening %s\n",
1311 smb_fname_str_dbg(smb_fname)));
1312 return NT_STATUS_ACCESS_DENIED;
1314 if (flags & O_CREAT) {
1315 /* We don't want to write - but we must make sure that
1316 O_CREAT doesn't create the file if we have write
1317 access into the directory.
1319 flags &= ~(O_CREAT|O_EXCL);
1320 local_flags &= ~(O_CREAT|O_EXCL);
1325 * This little piece of insanity is inspired by the
1326 * fact that an NT client can open a file for O_RDONLY,
1327 * but set the create disposition to FILE_EXISTS_TRUNCATE.
1328 * If the client *can* write to the file, then it expects to
1329 * truncate the file, even though it is opening for readonly.
1330 * Quicken uses this stupid trick in backup file creation...
1331 * Thanks *greatly* to "David W. Chapman Jr." <dwcjr@inethouston.net>
1332 * for helping track this one down. It didn't bite us in 2.0.x
1333 * as we always opened files read-write in that release. JRA.
1336 if ((accmode == O_RDONLY) && ((flags & O_TRUNC) == O_TRUNC)) {
1337 DEBUG(10,("open_file: truncate requested on read-only open "
1338 "for file %s\n", smb_fname_str_dbg(smb_fname)));
1339 local_flags = (flags & ~O_ACCMODE)|O_RDWR;
1342 if ((open_access_mask & need_fd_mask) || creating || truncating) {
1343 open_fd = true;
1346 if (open_fd) {
1347 const char *wild;
1348 int ret;
1350 #if defined(O_NONBLOCK) && defined(S_ISFIFO)
1352 * We would block on opening a FIFO with no one else on the
1353 * other end. Do what we used to do and add O_NONBLOCK to the
1354 * open flags. JRA.
1357 if (file_existed && S_ISFIFO(smb_fname->st.st_ex_mode)) {
1358 local_flags &= ~O_TRUNC; /* Can't truncate a FIFO. */
1359 local_flags |= O_NONBLOCK;
1360 truncating = false;
1362 #endif
1364 /* Don't create files with Microsoft wildcard characters. */
1365 if (fsp->base_fsp) {
1367 * wildcard characters are allowed in stream names
1368 * only test the basefilename
1370 wild = fsp->base_fsp->fsp_name->base_name;
1371 } else {
1372 wild = smb_fname->base_name;
1374 if ((local_flags & O_CREAT) && !file_existed &&
1375 !(fsp->posix_flags & FSP_POSIX_FLAGS_PATHNAMES) &&
1376 ms_has_wild(wild)) {
1377 return NT_STATUS_OBJECT_NAME_INVALID;
1380 /* Can we access this file ? */
1381 if (!fsp->base_fsp) {
1382 /* Only do this check on non-stream open. */
1383 if (file_existed) {
1384 status = smbd_check_access_rights_fsp(
1385 parent_dir->fsp,
1386 fsp,
1387 false,
1388 access_mask);
1390 if (!NT_STATUS_IS_OK(status)) {
1391 DBG_DEBUG("smbd_check_access_rights_fsp"
1392 " on file %s returned %s\n",
1393 fsp_str_dbg(fsp),
1394 nt_errstr(status));
1397 if (!NT_STATUS_IS_OK(status) &&
1398 !NT_STATUS_EQUAL(status,
1399 NT_STATUS_OBJECT_NAME_NOT_FOUND))
1401 return status;
1404 if (NT_STATUS_EQUAL(status,
1405 NT_STATUS_OBJECT_NAME_NOT_FOUND))
1407 DEBUG(10, ("open_file: "
1408 "file %s vanished since we "
1409 "checked for existence.\n",
1410 smb_fname_str_dbg(smb_fname)));
1411 file_existed = false;
1412 SET_STAT_INVALID(fsp->fsp_name->st);
1416 if (!file_existed) {
1417 if (!(local_flags & O_CREAT)) {
1418 /* File didn't exist and no O_CREAT. */
1419 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1422 status = check_parent_access_fsp(
1423 parent_dir->fsp,
1424 SEC_DIR_ADD_FILE);
1425 if (!NT_STATUS_IS_OK(status)) {
1426 DBG_DEBUG("check_parent_access_fsp on "
1427 "directory %s for file %s "
1428 "returned %s\n",
1429 smb_fname_str_dbg(parent_dir),
1430 smb_fname_str_dbg(smb_fname),
1431 nt_errstr(status));
1432 return status;
1438 * Actually do the open - if O_TRUNC is needed handle it
1439 * below under the share mode lock.
1441 status = reopen_from_fsp(fsp,
1442 local_flags & ~O_TRUNC,
1443 unx_mode,
1444 p_file_created);
1445 if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) {
1447 * POSIX client that hit a symlink. We don't want to
1448 * return NT_STATUS_STOPPED_ON_SYMLINK to avoid handling
1449 * this special error code in all callers, so we map
1450 * this to NT_STATUS_OBJECT_PATH_NOT_FOUND. Historically
1451 * the lower level functions returned status code mapped
1452 * from errno by map_nt_error_from_unix() where ELOOP is
1453 * mapped to NT_STATUS_OBJECT_PATH_NOT_FOUND.
1455 status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
1457 if (!NT_STATUS_IS_OK(status)) {
1458 DEBUG(3,("Error opening file %s (%s) (local_flags=%d) "
1459 "(flags=%d)\n", smb_fname_str_dbg(smb_fname),
1460 nt_errstr(status),local_flags,flags));
1461 return status;
1464 if (local_flags & O_NONBLOCK) {
1466 * GPFS can return ETIMEDOUT for pread on
1467 * nonblocking file descriptors when files
1468 * migrated to tape need to be recalled. I
1469 * could imagine this happens elsewhere
1470 * too. With blocking file descriptors this
1471 * does not happen.
1473 ret = vfs_set_blocking(fsp, true);
1474 if (ret == -1) {
1475 status = map_nt_error_from_unix(errno);
1476 DBG_WARNING("Could not set fd to blocking: "
1477 "%s\n", strerror(errno));
1478 fd_close(fsp);
1479 return status;
1483 if (*p_file_created) {
1484 /* We created this file. */
1486 bool need_re_stat = false;
1487 /* Do all inheritance work after we've
1488 done a successful fstat call and filled
1489 in the stat struct in fsp->fsp_name. */
1491 /* Inherit the ACL if required */
1492 if (lp_inherit_permissions(SNUM(conn))) {
1493 inherit_access_posix_acl(conn,
1494 parent_dir,
1495 smb_fname,
1496 unx_mode);
1497 need_re_stat = true;
1500 /* Change the owner if required. */
1501 if (lp_inherit_owner(SNUM(conn)) != INHERIT_OWNER_NO) {
1502 change_file_owner_to_parent_fsp(parent_dir->fsp,
1503 fsp);
1504 need_re_stat = true;
1507 if (need_re_stat) {
1508 ret = SMB_VFS_FSTAT(fsp, &smb_fname->st);
1510 * If we have an fd, this stat should succeed.
1512 if (ret == -1) {
1513 status = map_nt_error_from_unix(errno);
1514 DBG_ERR("Error doing fstat on open "
1515 "file %s (%s)\n",
1516 smb_fname_str_dbg(smb_fname),
1517 nt_errstr(status));
1518 fd_close(fsp);
1519 return status;
1523 notify_fname(conn, NOTIFY_ACTION_ADDED,
1524 FILE_NOTIFY_CHANGE_FILE_NAME,
1525 smb_fname->base_name);
1527 } else {
1528 if (!file_existed) {
1529 /* File must exist for a stat open. */
1530 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1533 if (S_ISLNK(smb_fname->st.st_ex_mode) &&
1534 !(fsp->posix_flags & FSP_POSIX_FLAGS_OPEN))
1537 * Don't allow stat opens on symlinks directly unless
1538 * it's a POSIX open.
1540 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
1543 if (!fsp->fsp_flags.is_pathref) {
1545 * There is only one legit case where end up here:
1546 * openat_pathref_fsp() failed to open a symlink, so the
1547 * fsp was created by fsp_new() which doesn't set
1548 * is_pathref. Other then that, we should always have a
1549 * pathref fsp at this point. The subsequent checks
1550 * assert this.
1552 if (!(smb_fname->flags & SMB_FILENAME_POSIX_PATH)) {
1553 DBG_ERR("[%s] is not a POSIX pathname\n",
1554 smb_fname_str_dbg(smb_fname));
1555 return NT_STATUS_INTERNAL_ERROR;
1557 if (!S_ISLNK(smb_fname->st.st_ex_mode)) {
1558 DBG_ERR("[%s] is not a symlink\n",
1559 smb_fname_str_dbg(smb_fname));
1560 return NT_STATUS_INTERNAL_ERROR;
1562 if (fsp_get_pathref_fd(fsp) != -1) {
1563 DBG_ERR("fd for [%s] is not -1: fd [%d]\n",
1564 smb_fname_str_dbg(smb_fname),
1565 fsp_get_pathref_fd(fsp));
1566 return NT_STATUS_INTERNAL_ERROR;
1570 status = smbd_check_access_rights_fsp(parent_dir->fsp,
1571 fsp,
1572 false,
1573 access_mask);
1575 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) &&
1576 (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) &&
1577 S_ISLNK(smb_fname->st.st_ex_mode)) {
1578 /* This is a POSIX stat open for delete
1579 * or rename on a symlink that points
1580 * nowhere. Allow. */
1581 DEBUG(10,("open_file: allowing POSIX "
1582 "open on bad symlink %s\n",
1583 smb_fname_str_dbg(smb_fname)));
1584 status = NT_STATUS_OK;
1587 if (!NT_STATUS_IS_OK(status)) {
1588 DBG_DEBUG("smbd_check_access_rights_fsp on file "
1589 "%s returned %s\n",
1590 fsp_str_dbg(fsp),
1591 nt_errstr(status));
1592 return status;
1596 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
1597 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
1598 fsp->file_pid = req ? req->smbpid : 0;
1599 fsp->fsp_flags.can_lock = true;
1600 fsp->fsp_flags.can_read = ((access_mask & FILE_READ_DATA) != 0);
1601 fsp->fsp_flags.can_write =
1602 CAN_WRITE(conn) &&
1603 ((access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) != 0);
1604 fsp->print_file = NULL;
1605 fsp->fsp_flags.modified = false;
1606 fsp->sent_oplock_break = NO_BREAK_SENT;
1607 fsp->fsp_flags.is_directory = false;
1608 if (conn->aio_write_behind_list &&
1609 is_in_path(smb_fname->base_name, conn->aio_write_behind_list,
1610 conn->case_sensitive)) {
1611 fsp->fsp_flags.aio_write_behind = true;
1614 DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
1615 conn->session_info->unix_info->unix_name,
1616 smb_fname_str_dbg(smb_fname),
1617 BOOLSTR(fsp->fsp_flags.can_read),
1618 BOOLSTR(fsp->fsp_flags.can_write),
1619 conn->num_files_open));
1621 return NT_STATUS_OK;
1624 static bool mask_conflict(
1625 uint32_t new_access,
1626 uint32_t existing_access,
1627 uint32_t access_mask,
1628 uint32_t new_sharemode,
1629 uint32_t existing_sharemode,
1630 uint32_t sharemode_mask)
1632 bool want_access = (new_access & access_mask);
1633 bool allow_existing = (existing_sharemode & sharemode_mask);
1634 bool have_access = (existing_access & access_mask);
1635 bool allow_new = (new_sharemode & sharemode_mask);
1637 if (want_access && !allow_existing) {
1638 DBG_DEBUG("Access request 0x%"PRIx32"/0x%"PRIx32" conflicts "
1639 "with existing sharemode 0x%"PRIx32"/0x%"PRIx32"\n",
1640 new_access,
1641 access_mask,
1642 existing_sharemode,
1643 sharemode_mask);
1644 return true;
1646 if (have_access && !allow_new) {
1647 DBG_DEBUG("Sharemode request 0x%"PRIx32"/0x%"PRIx32" conflicts "
1648 "with existing access 0x%"PRIx32"/0x%"PRIx32"\n",
1649 new_sharemode,
1650 sharemode_mask,
1651 existing_access,
1652 access_mask);
1653 return true;
1655 return false;
1658 /****************************************************************************
1659 Check if we can open a file with a share mode.
1660 Returns True if conflict, False if not.
1661 ****************************************************************************/
1663 static const uint32_t conflicting_access =
1664 FILE_WRITE_DATA|
1665 FILE_APPEND_DATA|
1666 FILE_READ_DATA|
1667 FILE_EXECUTE|
1668 DELETE_ACCESS;
1670 static bool share_conflict(uint32_t e_access_mask,
1671 uint32_t e_share_access,
1672 uint32_t access_mask,
1673 uint32_t share_access)
1675 bool conflict;
1677 DBG_DEBUG("existing access_mask = 0x%"PRIx32", "
1678 "existing share access = 0x%"PRIx32", "
1679 "access_mask = 0x%"PRIx32", "
1680 "share_access = 0x%"PRIx32"\n",
1681 e_access_mask,
1682 e_share_access,
1683 access_mask,
1684 share_access);
1686 if ((e_access_mask & conflicting_access) == 0) {
1687 DBG_DEBUG("No conflict due to "
1688 "existing access_mask = 0x%"PRIx32"\n",
1689 e_access_mask);
1690 return false;
1692 if ((access_mask & conflicting_access) == 0) {
1693 DBG_DEBUG("No conflict due to access_mask = 0x%"PRIx32"\n",
1694 access_mask);
1695 return false;
1698 conflict = mask_conflict(
1699 access_mask, e_access_mask, FILE_WRITE_DATA | FILE_APPEND_DATA,
1700 share_access, e_share_access, FILE_SHARE_WRITE);
1701 conflict |= mask_conflict(
1702 access_mask, e_access_mask, FILE_READ_DATA | FILE_EXECUTE,
1703 share_access, e_share_access, FILE_SHARE_READ);
1704 conflict |= mask_conflict(
1705 access_mask, e_access_mask, DELETE_ACCESS,
1706 share_access, e_share_access, FILE_SHARE_DELETE);
1708 DBG_DEBUG("conflict=%s\n", conflict ? "true" : "false");
1709 return conflict;
1712 #if defined(DEVELOPER)
1714 struct validate_my_share_entries_state {
1715 struct smbd_server_connection *sconn;
1716 struct file_id fid;
1717 struct server_id self;
1720 static bool validate_my_share_entries_fn(
1721 struct share_mode_entry *e,
1722 bool *modified,
1723 void *private_data)
1725 struct validate_my_share_entries_state *state = private_data;
1726 files_struct *fsp;
1728 if (!server_id_equal(&state->self, &e->pid)) {
1729 return false;
1732 if (e->op_mid == 0) {
1733 /* INTERNAL_OPEN_ONLY */
1734 return false;
1737 fsp = file_find_dif(state->sconn, state->fid, e->share_file_id);
1738 if (!fsp) {
1739 DBG_ERR("PANIC : %s\n",
1740 share_mode_str(talloc_tos(), 0, &state->fid, e));
1741 smb_panic("validate_my_share_entries: Cannot match a "
1742 "share entry with an open file\n");
1745 if (((uint16_t)fsp->oplock_type) != e->op_type) {
1746 goto panic;
1749 return false;
1751 panic:
1753 char *str;
1754 DBG_ERR("validate_my_share_entries: PANIC : %s\n",
1755 share_mode_str(talloc_tos(), 0, &state->fid, e));
1756 str = talloc_asprintf(talloc_tos(),
1757 "validate_my_share_entries: "
1758 "file %s, oplock_type = 0x%x, op_type = 0x%x\n",
1759 fsp->fsp_name->base_name,
1760 (unsigned int)fsp->oplock_type,
1761 (unsigned int)e->op_type);
1762 smb_panic(str);
1765 return false;
1767 #endif
1770 * Allowed access mask for stat opens relevant to oplocks
1772 bool is_oplock_stat_open(uint32_t access_mask)
1774 const uint32_t stat_open_bits =
1775 (SYNCHRONIZE_ACCESS|
1776 FILE_READ_ATTRIBUTES|
1777 FILE_WRITE_ATTRIBUTES);
1779 return (((access_mask & stat_open_bits) != 0) &&
1780 ((access_mask & ~stat_open_bits) == 0));
1784 * Allowed access mask for stat opens relevant to leases
1786 bool is_lease_stat_open(uint32_t access_mask)
1788 const uint32_t stat_open_bits =
1789 (SYNCHRONIZE_ACCESS|
1790 FILE_READ_ATTRIBUTES|
1791 FILE_WRITE_ATTRIBUTES|
1792 READ_CONTROL_ACCESS);
1794 return (((access_mask & stat_open_bits) != 0) &&
1795 ((access_mask & ~stat_open_bits) == 0));
1798 struct has_delete_on_close_state {
1799 bool ret;
1802 static bool has_delete_on_close_fn(
1803 struct share_mode_entry *e,
1804 bool *modified,
1805 void *private_data)
1807 struct has_delete_on_close_state *state = private_data;
1808 state->ret = !share_entry_stale_pid(e);
1809 return state->ret;
1812 static bool has_delete_on_close(struct share_mode_lock *lck,
1813 uint32_t name_hash)
1815 struct has_delete_on_close_state state = { .ret = false };
1816 bool ok;
1818 if (!is_delete_on_close_set(lck, name_hash)) {
1819 return false;
1822 ok= share_mode_forall_entries(lck, has_delete_on_close_fn, &state);
1823 if (!ok) {
1824 DBG_DEBUG("share_mode_forall_entries failed\n");
1825 return false;
1827 return state.ret;
1830 static void share_mode_flags_restrict(
1831 struct share_mode_lock *lck,
1832 uint32_t access_mask,
1833 uint32_t share_mode,
1834 uint32_t lease_type)
1836 uint32_t existing_access_mask, existing_share_mode;
1837 uint32_t existing_lease_type;
1839 share_mode_flags_get(
1840 lck,
1841 &existing_access_mask,
1842 &existing_share_mode,
1843 &existing_lease_type);
1845 existing_access_mask |= access_mask;
1846 if (access_mask & conflicting_access) {
1847 existing_share_mode &= share_mode;
1849 existing_lease_type |= lease_type;
1851 share_mode_flags_set(
1852 lck,
1853 existing_access_mask,
1854 existing_share_mode,
1855 existing_lease_type,
1856 NULL);
1859 /****************************************************************************
1860 Deal with share modes
1861 Invariant: Share mode must be locked on entry and exit.
1862 Returns -1 on error, or number of share modes on success (may be zero).
1863 ****************************************************************************/
1865 struct open_mode_check_state {
1866 struct file_id fid;
1867 uint32_t access_mask;
1868 uint32_t share_access;
1869 uint32_t lease_type;
1872 static bool open_mode_check_fn(
1873 struct share_mode_entry *e,
1874 bool *modified,
1875 void *private_data)
1877 struct open_mode_check_state *state = private_data;
1878 bool disconnected, stale;
1879 uint32_t access_mask, share_access, lease_type;
1881 disconnected = server_id_is_disconnected(&e->pid);
1882 if (disconnected) {
1883 return false;
1886 access_mask = state->access_mask | e->access_mask;
1887 share_access = state->share_access;
1888 if (e->access_mask & conflicting_access) {
1889 share_access &= e->share_access;
1891 lease_type = state->lease_type | get_lease_type(e, state->fid);
1893 if ((access_mask == state->access_mask) &&
1894 (share_access == state->share_access) &&
1895 (lease_type == state->lease_type)) {
1896 return false;
1899 stale = share_entry_stale_pid(e);
1900 if (stale) {
1901 return false;
1904 state->access_mask = access_mask;
1905 state->share_access = share_access;
1906 state->lease_type = lease_type;
1908 return false;
1911 static NTSTATUS open_mode_check(connection_struct *conn,
1912 struct file_id fid,
1913 struct share_mode_lock *lck,
1914 uint32_t access_mask,
1915 uint32_t share_access)
1917 struct open_mode_check_state state;
1918 bool ok, conflict;
1919 bool modified = false;
1921 if (is_oplock_stat_open(access_mask)) {
1922 /* Stat open that doesn't trigger oplock breaks or share mode
1923 * checks... ! JRA. */
1924 return NT_STATUS_OK;
1928 * Check if the share modes will give us access.
1931 #if defined(DEVELOPER)
1933 struct validate_my_share_entries_state validate_state = {
1934 .sconn = conn->sconn,
1935 .fid = fid,
1936 .self = messaging_server_id(conn->sconn->msg_ctx),
1938 ok = share_mode_forall_entries(
1939 lck, validate_my_share_entries_fn, &validate_state);
1940 SMB_ASSERT(ok);
1942 #endif
1944 share_mode_flags_get(
1945 lck, &state.access_mask, &state.share_access, NULL);
1947 conflict = share_conflict(
1948 state.access_mask,
1949 state.share_access,
1950 access_mask,
1951 share_access);
1952 if (!conflict) {
1953 DBG_DEBUG("No conflict due to share_mode_flags access\n");
1954 return NT_STATUS_OK;
1957 state = (struct open_mode_check_state) {
1958 .fid = fid,
1959 .share_access = (FILE_SHARE_READ|
1960 FILE_SHARE_WRITE|
1961 FILE_SHARE_DELETE),
1965 * Walk the share mode array to recalculate d->flags
1968 ok = share_mode_forall_entries(lck, open_mode_check_fn, &state);
1969 if (!ok) {
1970 DBG_DEBUG("share_mode_forall_entries failed\n");
1971 return NT_STATUS_INTERNAL_ERROR;
1974 share_mode_flags_set(
1975 lck,
1976 state.access_mask,
1977 state.share_access,
1978 state.lease_type,
1979 &modified);
1980 if (!modified) {
1982 * We only end up here if we had a sharing violation
1983 * from d->flags and have recalculated it.
1985 return NT_STATUS_SHARING_VIOLATION;
1988 conflict = share_conflict(
1989 state.access_mask,
1990 state.share_access,
1991 access_mask,
1992 share_access);
1993 if (!conflict) {
1994 DBG_DEBUG("No conflict due to share_mode_flags access\n");
1995 return NT_STATUS_OK;
1998 return NT_STATUS_SHARING_VIOLATION;
2002 * Send a break message to the oplock holder and delay the open for
2003 * our client.
2006 NTSTATUS send_break_message(struct messaging_context *msg_ctx,
2007 const struct file_id *id,
2008 const struct share_mode_entry *exclusive,
2009 uint16_t break_to)
2011 struct oplock_break_message msg = {
2012 .id = *id,
2013 .share_file_id = exclusive->share_file_id,
2014 .break_to = break_to,
2016 enum ndr_err_code ndr_err;
2017 DATA_BLOB blob;
2018 NTSTATUS status;
2020 if (DEBUGLVL(10)) {
2021 struct server_id_buf buf;
2022 DBG_DEBUG("Sending break message to %s\n",
2023 server_id_str_buf(exclusive->pid, &buf));
2024 NDR_PRINT_DEBUG(oplock_break_message, &msg);
2027 ndr_err = ndr_push_struct_blob(
2028 &blob,
2029 talloc_tos(),
2030 &msg,
2031 (ndr_push_flags_fn_t)ndr_push_oplock_break_message);
2032 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2033 DBG_WARNING("ndr_push_oplock_break_message failed: %s\n",
2034 ndr_errstr(ndr_err));
2035 return ndr_map_error2ntstatus(ndr_err);
2038 status = messaging_send(
2039 msg_ctx, exclusive->pid, MSG_SMB_BREAK_REQUEST, &blob);
2040 TALLOC_FREE(blob.data);
2041 if (!NT_STATUS_IS_OK(status)) {
2042 DEBUG(3, ("Could not send oplock break message: %s\n",
2043 nt_errstr(status)));
2046 return status;
2049 struct validate_oplock_types_state {
2050 bool valid;
2051 bool batch;
2052 bool ex_or_batch;
2053 bool level2;
2054 bool no_oplock;
2055 uint32_t num_non_stat_opens;
2058 static bool validate_oplock_types_fn(
2059 struct share_mode_entry *e,
2060 bool *modified,
2061 void *private_data)
2063 struct validate_oplock_types_state *state = private_data;
2065 if (e->op_mid == 0) {
2066 /* INTERNAL_OPEN_ONLY */
2067 return false;
2070 if (e->op_type == NO_OPLOCK && is_oplock_stat_open(e->access_mask)) {
2072 * We ignore stat opens in the table - they always
2073 * have NO_OPLOCK and never get or cause breaks. JRA.
2075 return false;
2078 state->num_non_stat_opens += 1;
2080 if (BATCH_OPLOCK_TYPE(e->op_type)) {
2081 /* batch - can only be one. */
2082 if (share_entry_stale_pid(e)) {
2083 DBG_DEBUG("Found stale batch oplock\n");
2084 return false;
2086 if (state->ex_or_batch ||
2087 state->batch ||
2088 state->level2 ||
2089 state->no_oplock) {
2090 DBG_ERR("Bad batch oplock entry\n");
2091 state->valid = false;
2092 return true;
2094 state->batch = true;
2097 if (EXCLUSIVE_OPLOCK_TYPE(e->op_type)) {
2098 if (share_entry_stale_pid(e)) {
2099 DBG_DEBUG("Found stale duplicate oplock\n");
2100 return false;
2102 /* Exclusive or batch - can only be one. */
2103 if (state->ex_or_batch ||
2104 state->level2 ||
2105 state->no_oplock) {
2106 DBG_ERR("Bad exclusive or batch oplock entry\n");
2107 state->valid = false;
2108 return true;
2110 state->ex_or_batch = true;
2113 if (LEVEL_II_OPLOCK_TYPE(e->op_type)) {
2114 if (state->batch || state->ex_or_batch) {
2115 if (share_entry_stale_pid(e)) {
2116 DBG_DEBUG("Found stale LevelII oplock\n");
2117 return false;
2119 DBG_DEBUG("Bad levelII oplock entry\n");
2120 state->valid = false;
2121 return true;
2123 state->level2 = true;
2126 if (e->op_type == NO_OPLOCK) {
2127 if (state->batch || state->ex_or_batch) {
2128 if (share_entry_stale_pid(e)) {
2129 DBG_DEBUG("Found stale NO_OPLOCK entry\n");
2130 return false;
2132 DBG_ERR("Bad no oplock entry\n");
2133 state->valid = false;
2134 return true;
2136 state->no_oplock = true;
2139 return false;
2143 * Do internal consistency checks on the share mode for a file.
2146 static bool validate_oplock_types(struct share_mode_lock *lck)
2148 struct validate_oplock_types_state state = { .valid = true };
2149 bool ok;
2151 ok = share_mode_forall_entries(lck, validate_oplock_types_fn, &state);
2152 if (!ok) {
2153 DBG_DEBUG("share_mode_forall_entries failed\n");
2154 return false;
2156 if (!state.valid) {
2157 DBG_DEBUG("Got invalid oplock configuration\n");
2158 return false;
2161 if ((state.batch || state.ex_or_batch) &&
2162 (state.num_non_stat_opens != 1)) {
2163 DBG_WARNING("got batch (%d) or ex (%d) non-exclusively "
2164 "(%"PRIu32")\n",
2165 (int)state.batch,
2166 (int)state.ex_or_batch,
2167 state.num_non_stat_opens);
2168 return false;
2171 return true;
2174 static bool is_same_lease(const files_struct *fsp,
2175 const struct share_mode_entry *e,
2176 const struct smb2_lease *lease)
2178 if (e->op_type != LEASE_OPLOCK) {
2179 return false;
2181 if (lease == NULL) {
2182 return false;
2185 return smb2_lease_equal(fsp_client_guid(fsp),
2186 &lease->lease_key,
2187 &e->client_guid,
2188 &e->lease_key);
2191 static bool file_has_brlocks(files_struct *fsp)
2193 struct byte_range_lock *br_lck;
2195 br_lck = brl_get_locks_readonly(fsp);
2196 if (!br_lck)
2197 return false;
2199 return (brl_num_locks(br_lck) > 0);
2202 struct fsp_lease *find_fsp_lease(struct files_struct *new_fsp,
2203 const struct smb2_lease_key *key,
2204 uint32_t current_state,
2205 uint16_t lease_version,
2206 uint16_t lease_epoch)
2208 struct files_struct *fsp;
2211 * TODO: Measure how expensive this loop is with thousands of open
2212 * handles...
2215 for (fsp = file_find_di_first(new_fsp->conn->sconn, new_fsp->file_id, true);
2216 fsp != NULL;
2217 fsp = file_find_di_next(fsp, true)) {
2219 if (fsp == new_fsp) {
2220 continue;
2222 if (fsp->oplock_type != LEASE_OPLOCK) {
2223 continue;
2225 if (smb2_lease_key_equal(&fsp->lease->lease.lease_key, key)) {
2226 fsp->lease->ref_count += 1;
2227 return fsp->lease;
2231 /* Not found - must be leased in another smbd. */
2232 new_fsp->lease = talloc_zero(new_fsp->conn->sconn, struct fsp_lease);
2233 if (new_fsp->lease == NULL) {
2234 return NULL;
2236 new_fsp->lease->ref_count = 1;
2237 new_fsp->lease->sconn = new_fsp->conn->sconn;
2238 new_fsp->lease->lease.lease_key = *key;
2239 new_fsp->lease->lease.lease_state = current_state;
2241 * We internally treat all leases as V2 and update
2242 * the epoch, but when sending breaks it matters if
2243 * the requesting lease was v1 or v2.
2245 new_fsp->lease->lease.lease_version = lease_version;
2246 new_fsp->lease->lease.lease_epoch = lease_epoch;
2247 return new_fsp->lease;
2250 static NTSTATUS try_lease_upgrade(struct files_struct *fsp,
2251 struct share_mode_lock *lck,
2252 const struct GUID *client_guid,
2253 const struct smb2_lease *lease,
2254 uint32_t granted)
2256 bool do_upgrade;
2257 uint32_t current_state, breaking_to_requested, breaking_to_required;
2258 bool breaking;
2259 uint16_t lease_version, epoch;
2260 uint32_t existing, requested;
2261 NTSTATUS status;
2263 status = leases_db_get(
2264 client_guid,
2265 &lease->lease_key,
2266 &fsp->file_id,
2267 &current_state,
2268 &breaking,
2269 &breaking_to_requested,
2270 &breaking_to_required,
2271 &lease_version,
2272 &epoch);
2273 if (!NT_STATUS_IS_OK(status)) {
2274 return status;
2277 fsp->lease = find_fsp_lease(
2278 fsp,
2279 &lease->lease_key,
2280 current_state,
2281 lease_version,
2282 epoch);
2283 if (fsp->lease == NULL) {
2284 DEBUG(1, ("Did not find existing lease for file %s\n",
2285 fsp_str_dbg(fsp)));
2286 return NT_STATUS_NO_MEMORY;
2290 * Upgrade only if the requested lease is a strict upgrade.
2292 existing = current_state;
2293 requested = lease->lease_state;
2296 * Tricky: This test makes sure that "requested" is a
2297 * strict bitwise superset of "existing".
2299 do_upgrade = ((existing & requested) == existing);
2302 * Upgrade only if there's a change.
2304 do_upgrade &= (granted != existing);
2307 * Upgrade only if other leases don't prevent what was asked
2308 * for.
2310 do_upgrade &= (granted == requested);
2313 * only upgrade if we are not in breaking state
2315 do_upgrade &= !breaking;
2317 DEBUG(10, ("existing=%"PRIu32", requested=%"PRIu32", "
2318 "granted=%"PRIu32", do_upgrade=%d\n",
2319 existing, requested, granted, (int)do_upgrade));
2321 if (do_upgrade) {
2322 NTSTATUS set_status;
2324 current_state = granted;
2325 epoch += 1;
2327 set_status = leases_db_set(
2328 client_guid,
2329 &lease->lease_key,
2330 current_state,
2331 breaking,
2332 breaking_to_requested,
2333 breaking_to_required,
2334 lease_version,
2335 epoch);
2337 if (!NT_STATUS_IS_OK(set_status)) {
2338 DBG_DEBUG("leases_db_set failed: %s\n",
2339 nt_errstr(set_status));
2340 return set_status;
2344 fsp_lease_update(fsp);
2346 return NT_STATUS_OK;
2349 static NTSTATUS grant_new_fsp_lease(struct files_struct *fsp,
2350 struct share_mode_lock *lck,
2351 const struct GUID *client_guid,
2352 const struct smb2_lease *lease,
2353 uint32_t granted)
2355 NTSTATUS status;
2357 fsp->lease = talloc_zero(fsp->conn->sconn, struct fsp_lease);
2358 if (fsp->lease == NULL) {
2359 return NT_STATUS_INSUFFICIENT_RESOURCES;
2361 fsp->lease->ref_count = 1;
2362 fsp->lease->sconn = fsp->conn->sconn;
2363 fsp->lease->lease.lease_version = lease->lease_version;
2364 fsp->lease->lease.lease_key = lease->lease_key;
2365 fsp->lease->lease.lease_state = granted;
2366 fsp->lease->lease.lease_epoch = lease->lease_epoch + 1;
2368 status = leases_db_add(client_guid,
2369 &lease->lease_key,
2370 &fsp->file_id,
2371 fsp->lease->lease.lease_state,
2372 fsp->lease->lease.lease_version,
2373 fsp->lease->lease.lease_epoch,
2374 fsp->conn->connectpath,
2375 fsp->fsp_name->base_name,
2376 fsp->fsp_name->stream_name);
2377 if (!NT_STATUS_IS_OK(status)) {
2378 DEBUG(10, ("%s: leases_db_add failed: %s\n", __func__,
2379 nt_errstr(status)));
2380 TALLOC_FREE(fsp->lease);
2381 return NT_STATUS_INSUFFICIENT_RESOURCES;
2385 * We used to set lck->data->modified=true here without
2386 * actually modifying lck->data, triggering a needless
2387 * writeback of lck->data.
2389 * Apart from that writeback, setting modified=true has the
2390 * effect of triggering all waiters for this file to
2391 * retry. This only makes sense if any blocking condition
2392 * (i.e. waiting for a lease to be downgraded or removed) is
2393 * gone. This routine here only adds a lease, so it will never
2394 * free up resources that blocked waiters can now claim. So
2395 * that second effect also does not matter in this
2396 * routine. Thus setting lck->data->modified=true does not
2397 * need to be done here.
2400 return NT_STATUS_OK;
2403 static NTSTATUS grant_fsp_lease(struct files_struct *fsp,
2404 struct share_mode_lock *lck,
2405 const struct smb2_lease *lease,
2406 uint32_t granted)
2408 const struct GUID *client_guid = fsp_client_guid(fsp);
2409 NTSTATUS status;
2411 status = try_lease_upgrade(fsp, lck, client_guid, lease, granted);
2413 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
2414 status = grant_new_fsp_lease(
2415 fsp, lck, client_guid, lease, granted);
2418 return status;
2421 static int map_lease_type_to_oplock(uint32_t lease_type)
2423 int result = NO_OPLOCK;
2425 switch (lease_type) {
2426 case SMB2_LEASE_READ|SMB2_LEASE_WRITE|SMB2_LEASE_HANDLE:
2427 result = BATCH_OPLOCK|EXCLUSIVE_OPLOCK;
2428 break;
2429 case SMB2_LEASE_READ|SMB2_LEASE_WRITE:
2430 result = EXCLUSIVE_OPLOCK;
2431 break;
2432 case SMB2_LEASE_READ|SMB2_LEASE_HANDLE:
2433 case SMB2_LEASE_READ:
2434 result = LEVEL_II_OPLOCK;
2435 break;
2438 return result;
2441 struct delay_for_oplock_state {
2442 struct files_struct *fsp;
2443 const struct smb2_lease *lease;
2444 bool will_overwrite;
2445 uint32_t delay_mask;
2446 bool first_open_attempt;
2447 bool got_handle_lease;
2448 bool got_oplock;
2449 bool have_other_lease;
2450 bool delay;
2453 static bool delay_for_oplock_fn(
2454 struct share_mode_entry *e,
2455 bool *modified,
2456 void *private_data)
2458 struct delay_for_oplock_state *state = private_data;
2459 struct files_struct *fsp = state->fsp;
2460 const struct smb2_lease *lease = state->lease;
2461 bool e_is_lease = (e->op_type == LEASE_OPLOCK);
2462 uint32_t e_lease_type = get_lease_type(e, fsp->file_id);
2463 uint32_t break_to;
2464 bool lease_is_breaking = false;
2466 if (e_is_lease) {
2467 NTSTATUS status;
2469 if (lease != NULL) {
2470 bool our_lease = is_same_lease(fsp, e, lease);
2471 if (our_lease) {
2472 DBG_DEBUG("Ignoring our own lease\n");
2473 return false;
2477 status = leases_db_get(
2478 &e->client_guid,
2479 &e->lease_key,
2480 &fsp->file_id,
2481 NULL, /* current_state */
2482 &lease_is_breaking,
2483 NULL, /* breaking_to_requested */
2484 NULL, /* breaking_to_required */
2485 NULL, /* lease_version */
2486 NULL); /* epoch */
2489 * leases_db_get() can return NT_STATUS_NOT_FOUND
2490 * if the share_mode_entry e is stale and the
2491 * lease record was already removed. In this case return
2492 * false so the traverse continues.
2495 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND) &&
2496 share_entry_stale_pid(e))
2498 struct GUID_txt_buf guid_strbuf;
2499 struct file_id_buf file_id_strbuf;
2500 DBG_DEBUG("leases_db_get for client_guid [%s] "
2501 "lease_key [%"PRIu64"/%"PRIu64"] "
2502 "file_id [%s] failed for stale "
2503 "share_mode_entry\n",
2504 GUID_buf_string(&e->client_guid, &guid_strbuf),
2505 e->lease_key.data[0],
2506 e->lease_key.data[1],
2507 file_id_str_buf(fsp->file_id, &file_id_strbuf));
2508 return false;
2510 if (!NT_STATUS_IS_OK(status)) {
2511 struct GUID_txt_buf guid_strbuf;
2512 struct file_id_buf file_id_strbuf;
2513 DBG_ERR("leases_db_get for client_guid [%s] "
2514 "lease_key [%"PRIu64"/%"PRIu64"] "
2515 "file_id [%s] failed: %s\n",
2516 GUID_buf_string(&e->client_guid, &guid_strbuf),
2517 e->lease_key.data[0],
2518 e->lease_key.data[1],
2519 file_id_str_buf(fsp->file_id, &file_id_strbuf),
2520 nt_errstr(status));
2521 smb_panic("leases_db_get() failed");
2525 if (!state->got_handle_lease &&
2526 ((e_lease_type & SMB2_LEASE_HANDLE) != 0) &&
2527 !share_entry_stale_pid(e)) {
2528 state->got_handle_lease = true;
2531 if (!state->got_oplock &&
2532 (e->op_type != LEASE_OPLOCK) &&
2533 !share_entry_stale_pid(e)) {
2534 state->got_oplock = true;
2537 if (!state->have_other_lease &&
2538 !is_same_lease(fsp, e, lease) &&
2539 !share_entry_stale_pid(e)) {
2540 state->have_other_lease = true;
2543 if (e_is_lease && is_lease_stat_open(fsp->access_mask)) {
2544 return false;
2547 break_to = e_lease_type & ~state->delay_mask;
2549 if (state->will_overwrite) {
2550 break_to &= ~(SMB2_LEASE_HANDLE|SMB2_LEASE_READ);
2553 DBG_DEBUG("e_lease_type %u, will_overwrite: %u\n",
2554 (unsigned)e_lease_type,
2555 (unsigned)state->will_overwrite);
2557 if ((e_lease_type & ~break_to) == 0) {
2558 if (lease_is_breaking) {
2559 state->delay = true;
2561 return false;
2564 if (share_entry_stale_pid(e)) {
2565 return false;
2568 if (state->will_overwrite) {
2570 * If we break anyway break to NONE directly.
2571 * Otherwise vfs_set_filelen() will trigger the
2572 * break.
2574 break_to &= ~(SMB2_LEASE_READ|SMB2_LEASE_WRITE);
2577 if (!e_is_lease) {
2579 * Oplocks only support breaking to R or NONE.
2581 break_to &= ~(SMB2_LEASE_HANDLE|SMB2_LEASE_WRITE);
2584 DBG_DEBUG("breaking from %d to %d\n",
2585 (int)e_lease_type,
2586 (int)break_to);
2587 send_break_message(
2588 fsp->conn->sconn->msg_ctx, &fsp->file_id, e, break_to);
2589 if (e_lease_type & state->delay_mask) {
2590 state->delay = true;
2592 if (lease_is_breaking && !state->first_open_attempt) {
2593 state->delay = true;
2596 return false;
2599 static NTSTATUS delay_for_oplock(files_struct *fsp,
2600 int oplock_request,
2601 const struct smb2_lease *lease,
2602 struct share_mode_lock *lck,
2603 bool have_sharing_violation,
2604 uint32_t create_disposition,
2605 bool first_open_attempt)
2607 struct delay_for_oplock_state state = {
2608 .fsp = fsp,
2609 .lease = lease,
2610 .first_open_attempt = first_open_attempt,
2612 uint32_t granted;
2613 NTSTATUS status;
2614 bool ok;
2616 if (is_oplock_stat_open(fsp->access_mask)) {
2617 goto grant;
2620 state.delay_mask = have_sharing_violation ?
2621 SMB2_LEASE_HANDLE : SMB2_LEASE_WRITE;
2623 switch (create_disposition) {
2624 case FILE_SUPERSEDE:
2625 case FILE_OVERWRITE:
2626 case FILE_OVERWRITE_IF:
2627 state.will_overwrite = true;
2628 break;
2629 default:
2630 state.will_overwrite = false;
2631 break;
2634 ok = share_mode_forall_entries(lck, delay_for_oplock_fn, &state);
2635 if (!ok) {
2636 return NT_STATUS_INTERNAL_ERROR;
2639 if (state.delay) {
2640 return NT_STATUS_RETRY;
2643 grant:
2644 if (have_sharing_violation) {
2645 return NT_STATUS_SHARING_VIOLATION;
2648 if (oplock_request == LEASE_OPLOCK) {
2649 if (lease == NULL) {
2651 * The SMB2 layer should have checked this
2653 return NT_STATUS_INTERNAL_ERROR;
2656 granted = lease->lease_state;
2658 if (lp_kernel_oplocks(SNUM(fsp->conn))) {
2659 DEBUG(10, ("No lease granted because kernel oplocks are enabled\n"));
2660 granted = SMB2_LEASE_NONE;
2662 if ((granted & (SMB2_LEASE_READ|SMB2_LEASE_WRITE)) == 0) {
2663 DEBUG(10, ("No read or write lease requested\n"));
2664 granted = SMB2_LEASE_NONE;
2666 if (granted == SMB2_LEASE_WRITE) {
2667 DEBUG(10, ("pure write lease requested\n"));
2668 granted = SMB2_LEASE_NONE;
2670 if (granted == (SMB2_LEASE_WRITE|SMB2_LEASE_HANDLE)) {
2671 DEBUG(10, ("write and handle lease requested\n"));
2672 granted = SMB2_LEASE_NONE;
2674 } else {
2675 granted = map_oplock_to_lease_type(
2676 oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK);
2679 if (lp_locking(fsp->conn->params) && file_has_brlocks(fsp)) {
2680 DBG_DEBUG("file %s has byte range locks\n",
2681 fsp_str_dbg(fsp));
2682 granted &= ~SMB2_LEASE_READ;
2685 if (state.have_other_lease) {
2687 * Can grant only one writer
2689 granted &= ~SMB2_LEASE_WRITE;
2692 if ((granted & SMB2_LEASE_READ) && !(granted & SMB2_LEASE_WRITE)) {
2693 bool allow_level2 =
2694 (global_client_caps & CAP_LEVEL_II_OPLOCKS) &&
2695 lp_level2_oplocks(SNUM(fsp->conn));
2697 if (!allow_level2) {
2698 granted = SMB2_LEASE_NONE;
2702 if (oplock_request == LEASE_OPLOCK) {
2703 if (state.got_oplock) {
2704 granted &= ~SMB2_LEASE_HANDLE;
2707 fsp->oplock_type = LEASE_OPLOCK;
2709 status = grant_fsp_lease(fsp, lck, lease, granted);
2710 if (!NT_STATUS_IS_OK(status)) {
2711 return status;
2715 DBG_DEBUG("lease_state=%d\n", fsp->lease->lease.lease_state);
2716 } else {
2717 if (state.got_handle_lease) {
2718 granted = SMB2_LEASE_NONE;
2721 fsp->oplock_type = map_lease_type_to_oplock(granted);
2723 status = set_file_oplock(fsp);
2724 if (!NT_STATUS_IS_OK(status)) {
2726 * Could not get the kernel oplock
2728 fsp->oplock_type = NO_OPLOCK;
2732 if (granted & SMB2_LEASE_READ) {
2733 uint32_t acc, sh, ls;
2734 share_mode_flags_get(lck, &acc, &sh, &ls);
2735 ls |= SHARE_MODE_LEASE_READ;
2736 share_mode_flags_set(lck, acc, sh, ls, NULL);
2739 DBG_DEBUG("oplock type 0x%x on file %s\n",
2740 fsp->oplock_type, fsp_str_dbg(fsp));
2742 return NT_STATUS_OK;
2745 static NTSTATUS handle_share_mode_lease(
2746 files_struct *fsp,
2747 struct share_mode_lock *lck,
2748 uint32_t create_disposition,
2749 uint32_t access_mask,
2750 uint32_t share_access,
2751 int oplock_request,
2752 const struct smb2_lease *lease,
2753 bool first_open_attempt)
2755 bool sharing_violation = false;
2756 NTSTATUS status;
2758 status = open_mode_check(
2759 fsp->conn, fsp->file_id, lck, access_mask, share_access);
2760 if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
2761 sharing_violation = true;
2762 status = NT_STATUS_OK; /* handled later */
2765 if (!NT_STATUS_IS_OK(status)) {
2766 return status;
2769 if (oplock_request == INTERNAL_OPEN_ONLY) {
2770 if (sharing_violation) {
2771 DBG_DEBUG("Sharing violation for internal open\n");
2772 return NT_STATUS_SHARING_VIOLATION;
2776 * Internal opens never do oplocks or leases. We don't
2777 * need to go through delay_for_oplock().
2779 fsp->oplock_type = NO_OPLOCK;
2781 return NT_STATUS_OK;
2784 status = delay_for_oplock(
2785 fsp,
2786 oplock_request,
2787 lease,
2788 lck,
2789 sharing_violation,
2790 create_disposition,
2791 first_open_attempt);
2792 if (!NT_STATUS_IS_OK(status)) {
2793 return status;
2796 return NT_STATUS_OK;
2799 static bool request_timed_out(struct smb_request *req, struct timeval timeout)
2801 struct timeval now, end_time;
2802 GetTimeOfDay(&now);
2803 end_time = timeval_sum(&req->request_time, &timeout);
2804 return (timeval_compare(&end_time, &now) < 0);
2807 struct defer_open_state {
2808 struct smbXsrv_connection *xconn;
2809 uint64_t mid;
2812 static void defer_open_done(struct tevent_req *req);
2815 * Defer an open and watch a locking.tdb record
2817 * This defers an open that gets rescheduled once the locking.tdb record watch
2818 * is triggered by a change to the record.
2820 * It is used to defer opens that triggered an oplock break and for the SMB1
2821 * sharing violation delay.
2823 static void defer_open(struct share_mode_lock *lck,
2824 struct timeval timeout,
2825 struct smb_request *req,
2826 struct file_id id)
2828 struct deferred_open_record *open_rec = NULL;
2829 struct timeval abs_timeout;
2830 struct defer_open_state *watch_state;
2831 struct tevent_req *watch_req;
2832 struct timeval_buf tvbuf1, tvbuf2;
2833 struct file_id_buf fbuf;
2834 bool ok;
2836 abs_timeout = timeval_sum(&req->request_time, &timeout);
2838 DBG_DEBUG("request time [%s] timeout [%s] mid [%" PRIu64 "] "
2839 "file_id [%s]\n",
2840 timeval_str_buf(&req->request_time, false, true, &tvbuf1),
2841 timeval_str_buf(&abs_timeout, false, true, &tvbuf2),
2842 req->mid,
2843 file_id_str_buf(id, &fbuf));
2845 open_rec = talloc_zero(NULL, struct deferred_open_record);
2846 if (open_rec == NULL) {
2847 TALLOC_FREE(lck);
2848 exit_server("talloc failed");
2851 watch_state = talloc(open_rec, struct defer_open_state);
2852 if (watch_state == NULL) {
2853 exit_server("talloc failed");
2855 watch_state->xconn = req->xconn;
2856 watch_state->mid = req->mid;
2858 DBG_DEBUG("defering mid %" PRIu64 "\n", req->mid);
2860 watch_req = share_mode_watch_send(
2861 watch_state,
2862 req->sconn->ev_ctx,
2863 lck,
2864 (struct server_id){0});
2865 if (watch_req == NULL) {
2866 exit_server("Could not watch share mode record");
2868 tevent_req_set_callback(watch_req, defer_open_done, watch_state);
2870 ok = tevent_req_set_endtime(watch_req, req->sconn->ev_ctx, abs_timeout);
2871 if (!ok) {
2872 exit_server("tevent_req_set_endtime failed");
2875 ok = push_deferred_open_message_smb(req, timeout, id, open_rec);
2876 if (!ok) {
2877 TALLOC_FREE(lck);
2878 exit_server("push_deferred_open_message_smb failed");
2882 static void defer_open_done(struct tevent_req *req)
2884 struct defer_open_state *state = tevent_req_callback_data(
2885 req, struct defer_open_state);
2886 NTSTATUS status;
2887 bool ret;
2889 status = share_mode_watch_recv(req, NULL, NULL);
2890 TALLOC_FREE(req);
2891 if (!NT_STATUS_IS_OK(status)) {
2892 DEBUG(5, ("dbwrap_watched_watch_recv returned %s\n",
2893 nt_errstr(status)));
2895 * Even if it failed, retry anyway. TODO: We need a way to
2896 * tell a re-scheduled open about that error.
2900 DEBUG(10, ("scheduling mid %llu\n", (unsigned long long)state->mid));
2902 ret = schedule_deferred_open_message_smb(state->xconn, state->mid);
2903 SMB_ASSERT(ret);
2904 TALLOC_FREE(state);
2908 * Actually attempt the kernel oplock polling open.
2911 static void poll_open_fn(struct tevent_context *ev,
2912 struct tevent_timer *te,
2913 struct timeval current_time,
2914 void *private_data)
2916 struct deferred_open_record *open_rec = talloc_get_type_abort(
2917 private_data, struct deferred_open_record);
2918 bool ok;
2920 TALLOC_FREE(open_rec->watch_req);
2922 ok = schedule_deferred_open_message_smb(
2923 open_rec->xconn, open_rec->mid);
2924 if (!ok) {
2925 exit_server("schedule_deferred_open_message_smb failed");
2927 DBG_DEBUG("timer fired. Retrying open !\n");
2930 static void poll_open_done(struct tevent_req *subreq);
2933 * Reschedule an open for 1 second from now, if not timed out.
2935 static bool setup_poll_open(
2936 struct smb_request *req,
2937 struct share_mode_lock *lck,
2938 struct file_id id,
2939 struct timeval max_timeout,
2940 struct timeval interval)
2942 bool ok;
2943 struct deferred_open_record *open_rec = NULL;
2944 struct timeval endtime, next_interval;
2945 struct file_id_buf ftmp;
2947 if (request_timed_out(req, max_timeout)) {
2948 return false;
2951 open_rec = talloc_zero(NULL, struct deferred_open_record);
2952 if (open_rec == NULL) {
2953 DBG_WARNING("talloc failed\n");
2954 return false;
2956 open_rec->xconn = req->xconn;
2957 open_rec->mid = req->mid;
2960 * Make sure open_rec->te does not come later than the
2961 * request's maximum endtime.
2964 endtime = timeval_sum(&req->request_time, &max_timeout);
2965 next_interval = timeval_current_ofs(interval.tv_sec, interval.tv_usec);
2966 next_interval = timeval_min(&endtime, &next_interval);
2968 open_rec->te = tevent_add_timer(
2969 req->sconn->ev_ctx,
2970 open_rec,
2971 next_interval,
2972 poll_open_fn,
2973 open_rec);
2974 if (open_rec->te == NULL) {
2975 DBG_WARNING("tevent_add_timer failed\n");
2976 TALLOC_FREE(open_rec);
2977 return false;
2980 if (lck != NULL) {
2981 open_rec->watch_req = share_mode_watch_send(
2982 open_rec,
2983 req->sconn->ev_ctx,
2984 lck,
2985 (struct server_id) {0});
2986 if (open_rec->watch_req == NULL) {
2987 DBG_WARNING("share_mode_watch_send failed\n");
2988 TALLOC_FREE(open_rec);
2989 return false;
2991 tevent_req_set_callback(
2992 open_rec->watch_req, poll_open_done, open_rec);
2995 ok = push_deferred_open_message_smb(req, max_timeout, id, open_rec);
2996 if (!ok) {
2997 DBG_WARNING("push_deferred_open_message_smb failed\n");
2998 TALLOC_FREE(open_rec);
2999 return false;
3002 DBG_DEBUG("poll request time [%s] mid [%" PRIu64 "] file_id [%s]\n",
3003 timeval_string(talloc_tos(), &req->request_time, false),
3004 req->mid,
3005 file_id_str_buf(id, &ftmp));
3007 return true;
3010 static void poll_open_done(struct tevent_req *subreq)
3012 struct deferred_open_record *open_rec = tevent_req_callback_data(
3013 subreq, struct deferred_open_record);
3014 NTSTATUS status;
3015 bool ok;
3017 status = share_mode_watch_recv(subreq, NULL, NULL);
3018 TALLOC_FREE(subreq);
3019 open_rec->watch_req = NULL;
3020 TALLOC_FREE(open_rec->te);
3022 DBG_DEBUG("dbwrap_watched_watch_recv returned %s\n",
3023 nt_errstr(status));
3025 ok = schedule_deferred_open_message_smb(
3026 open_rec->xconn, open_rec->mid);
3027 if (!ok) {
3028 exit_server("schedule_deferred_open_message_smb failed");
3032 bool defer_smb1_sharing_violation(struct smb_request *req)
3034 bool ok;
3035 int timeout_usecs;
3037 if (!lp_defer_sharing_violations()) {
3038 return false;
3042 * Try every 200msec up to (by default) one second. To be
3043 * precise, according to behaviour note <247> in [MS-CIFS],
3044 * the server tries 5 times. But up to one second should be
3045 * close enough.
3048 timeout_usecs = lp_parm_int(
3049 SNUM(req->conn),
3050 "smbd",
3051 "sharedelay",
3052 SHARING_VIOLATION_USEC_WAIT);
3054 ok = setup_poll_open(
3055 req,
3056 NULL,
3057 (struct file_id) {0},
3058 (struct timeval) { .tv_usec = timeout_usecs },
3059 (struct timeval) { .tv_usec = 200000 });
3060 return ok;
3063 /****************************************************************************
3064 On overwrite open ensure that the attributes match.
3065 ****************************************************************************/
3067 static bool open_match_attributes(connection_struct *conn,
3068 uint32_t old_dos_attr,
3069 uint32_t new_dos_attr,
3070 mode_t new_unx_mode,
3071 mode_t *returned_unx_mode)
3073 uint32_t noarch_old_dos_attr, noarch_new_dos_attr;
3075 noarch_old_dos_attr = (old_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
3076 noarch_new_dos_attr = (new_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
3078 if((noarch_old_dos_attr == 0 && noarch_new_dos_attr != 0) ||
3079 (noarch_old_dos_attr != 0 && ((noarch_old_dos_attr & noarch_new_dos_attr) == noarch_old_dos_attr))) {
3080 *returned_unx_mode = new_unx_mode;
3081 } else {
3082 *returned_unx_mode = (mode_t)0;
3085 DEBUG(10,("open_match_attributes: old_dos_attr = 0x%x, "
3086 "new_dos_attr = 0x%x "
3087 "returned_unx_mode = 0%o\n",
3088 (unsigned int)old_dos_attr,
3089 (unsigned int)new_dos_attr,
3090 (unsigned int)*returned_unx_mode ));
3092 /* If we're mapping SYSTEM and HIDDEN ensure they match. */
3093 if (lp_map_system(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
3094 if ((old_dos_attr & FILE_ATTRIBUTE_SYSTEM) &&
3095 !(new_dos_attr & FILE_ATTRIBUTE_SYSTEM)) {
3096 return False;
3099 if (lp_map_hidden(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
3100 if ((old_dos_attr & FILE_ATTRIBUTE_HIDDEN) &&
3101 !(new_dos_attr & FILE_ATTRIBUTE_HIDDEN)) {
3102 return False;
3105 return True;
3108 static void schedule_defer_open(struct share_mode_lock *lck,
3109 struct file_id id,
3110 struct smb_request *req)
3112 /* This is a relative time, added to the absolute
3113 request_time value to get the absolute timeout time.
3114 Note that if this is the second or greater time we enter
3115 this codepath for this particular request mid then
3116 request_time is left as the absolute time of the *first*
3117 time this request mid was processed. This is what allows
3118 the request to eventually time out. */
3120 struct timeval timeout;
3122 /* Normally the smbd we asked should respond within
3123 * OPLOCK_BREAK_TIMEOUT seconds regardless of whether
3124 * the client did, give twice the timeout as a safety
3125 * measure here in case the other smbd is stuck
3126 * somewhere else. */
3128 timeout = timeval_set(OPLOCK_BREAK_TIMEOUT*2, 0);
3130 if (request_timed_out(req, timeout)) {
3131 return;
3134 defer_open(lck, timeout, req, id);
3137 /****************************************************************************
3138 Reschedule an open call that went asynchronous.
3139 ****************************************************************************/
3141 static void schedule_async_open_timer(struct tevent_context *ev,
3142 struct tevent_timer *te,
3143 struct timeval current_time,
3144 void *private_data)
3146 exit_server("async open timeout");
3149 static void schedule_async_open(struct smb_request *req)
3151 struct deferred_open_record *open_rec = NULL;
3152 struct timeval timeout = timeval_set(20, 0);
3153 bool ok;
3155 if (request_timed_out(req, timeout)) {
3156 return;
3159 open_rec = talloc_zero(NULL, struct deferred_open_record);
3160 if (open_rec == NULL) {
3161 exit_server("deferred_open_record_create failed");
3163 open_rec->async_open = true;
3165 ok = push_deferred_open_message_smb(
3166 req, timeout, (struct file_id){0}, open_rec);
3167 if (!ok) {
3168 exit_server("push_deferred_open_message_smb failed");
3171 open_rec->te = tevent_add_timer(req->sconn->ev_ctx,
3172 req,
3173 timeval_current_ofs(20, 0),
3174 schedule_async_open_timer,
3175 open_rec);
3176 if (open_rec->te == NULL) {
3177 exit_server("tevent_add_timer failed");
3181 /****************************************************************************
3182 Work out what access_mask to use from what the client sent us.
3183 ****************************************************************************/
3185 static NTSTATUS smbd_calculate_maximum_allowed_access_fsp(
3186 struct files_struct *dirfsp,
3187 struct files_struct *fsp,
3188 bool use_privs,
3189 uint32_t *p_access_mask)
3191 struct security_descriptor *sd = NULL;
3192 uint32_t access_granted = 0;
3193 NTSTATUS status;
3195 /* Cope with symlinks */
3196 if (fsp == NULL || fsp_get_pathref_fd(fsp) == -1) {
3197 *p_access_mask = FILE_GENERIC_ALL;
3198 return NT_STATUS_OK;
3201 /* Cope with fake/printer fsp's. */
3202 if (fsp->fake_file_handle != NULL || fsp->print_file != NULL) {
3203 *p_access_mask = FILE_GENERIC_ALL;
3204 return NT_STATUS_OK;
3207 if (!use_privs && (get_current_uid(fsp->conn) == (uid_t)0)) {
3208 *p_access_mask |= FILE_GENERIC_ALL;
3209 return NT_STATUS_OK;
3212 status = SMB_VFS_FGET_NT_ACL(fsp,
3213 (SECINFO_OWNER |
3214 SECINFO_GROUP |
3215 SECINFO_DACL),
3216 talloc_tos(),
3217 &sd);
3219 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
3221 * File did not exist
3223 *p_access_mask = FILE_GENERIC_ALL;
3224 return NT_STATUS_OK;
3226 if (!NT_STATUS_IS_OK(status)) {
3227 DBG_ERR("Could not get acl on file %s: %s\n",
3228 fsp_str_dbg(fsp),
3229 nt_errstr(status));
3230 return status;
3234 * If we can access the path to this file, by
3235 * default we have FILE_READ_ATTRIBUTES from the
3236 * containing directory. See the section:
3237 * "Algorithm to Check Access to an Existing File"
3238 * in MS-FSA.pdf.
3240 * se_file_access_check()
3241 * also takes care of owner WRITE_DAC and READ_CONTROL.
3243 status = se_file_access_check(sd,
3244 get_current_nttok(fsp->conn),
3245 use_privs,
3246 (*p_access_mask & ~FILE_READ_ATTRIBUTES),
3247 &access_granted);
3249 TALLOC_FREE(sd);
3251 if (!NT_STATUS_IS_OK(status)) {
3252 DBG_ERR("Status %s on file %s: "
3253 "when calculating maximum access\n",
3254 nt_errstr(status),
3255 fsp_str_dbg(fsp));
3256 return status;
3259 *p_access_mask = (access_granted | FILE_READ_ATTRIBUTES);
3261 if (!(access_granted & DELETE_ACCESS)) {
3262 if (can_delete_file_in_directory(fsp->conn,
3263 dirfsp,
3264 fsp->fsp_name)) {
3265 *p_access_mask |= DELETE_ACCESS;
3269 return NT_STATUS_OK;
3272 NTSTATUS smbd_calculate_access_mask_fsp(struct files_struct *dirfsp,
3273 struct files_struct *fsp,
3274 bool use_privs,
3275 uint32_t access_mask,
3276 uint32_t *access_mask_out)
3278 NTSTATUS status;
3279 uint32_t orig_access_mask = access_mask;
3280 uint32_t rejected_share_access;
3282 if (access_mask & SEC_MASK_INVALID) {
3283 DBG_DEBUG("access_mask [%8x] contains invalid bits\n",
3284 access_mask);
3285 return NT_STATUS_ACCESS_DENIED;
3289 * Convert GENERIC bits to specific bits.
3292 se_map_generic(&access_mask, &file_generic_mapping);
3294 /* Calculate MAXIMUM_ALLOWED_ACCESS if requested. */
3295 if (access_mask & MAXIMUM_ALLOWED_ACCESS) {
3297 status = smbd_calculate_maximum_allowed_access_fsp(
3298 dirfsp,
3299 fsp,
3300 use_privs,
3301 &access_mask);
3303 if (!NT_STATUS_IS_OK(status)) {
3304 return status;
3307 access_mask &= fsp->conn->share_access;
3310 rejected_share_access = access_mask & ~(fsp->conn->share_access);
3312 if (rejected_share_access) {
3313 DBG_ERR("Access denied on file %s: "
3314 "rejected by share access mask[0x%08X] "
3315 "orig[0x%08X] mapped[0x%08X] reject[0x%08X]\n",
3316 fsp_str_dbg(fsp),
3317 fsp->conn->share_access,
3318 orig_access_mask, access_mask,
3319 rejected_share_access);
3320 return NT_STATUS_ACCESS_DENIED;
3323 *access_mask_out = access_mask;
3324 return NT_STATUS_OK;
3327 /****************************************************************************
3328 Remove the deferred open entry under lock.
3329 ****************************************************************************/
3331 /****************************************************************************
3332 Return true if this is a state pointer to an asynchronous create.
3333 ****************************************************************************/
3335 bool is_deferred_open_async(const struct deferred_open_record *rec)
3337 return rec->async_open;
3340 static bool clear_ads(uint32_t create_disposition)
3342 bool ret = false;
3344 switch (create_disposition) {
3345 case FILE_SUPERSEDE:
3346 case FILE_OVERWRITE_IF:
3347 case FILE_OVERWRITE:
3348 ret = true;
3349 break;
3350 default:
3351 break;
3353 return ret;
3356 static int disposition_to_open_flags(uint32_t create_disposition)
3358 int ret = 0;
3361 * Currently we're using FILE_SUPERSEDE as the same as
3362 * FILE_OVERWRITE_IF but they really are
3363 * different. FILE_SUPERSEDE deletes an existing file
3364 * (requiring delete access) then recreates it.
3367 switch (create_disposition) {
3368 case FILE_SUPERSEDE:
3369 case FILE_OVERWRITE_IF:
3371 * If file exists replace/overwrite. If file doesn't
3372 * exist create.
3374 ret = O_CREAT|O_TRUNC;
3375 break;
3377 case FILE_OPEN:
3379 * If file exists open. If file doesn't exist error.
3381 ret = 0;
3382 break;
3384 case FILE_OVERWRITE:
3386 * If file exists overwrite. If file doesn't exist
3387 * error.
3389 ret = O_TRUNC;
3390 break;
3392 case FILE_CREATE:
3394 * If file exists error. If file doesn't exist create.
3396 ret = O_CREAT|O_EXCL;
3397 break;
3399 case FILE_OPEN_IF:
3401 * If file exists open. If file doesn't exist create.
3403 ret = O_CREAT;
3404 break;
3406 return ret;
3409 static int calculate_open_access_flags(uint32_t access_mask,
3410 uint32_t private_flags)
3412 bool need_write, need_read;
3415 * Note that we ignore the append flag as append does not
3416 * mean the same thing under DOS and Unix.
3419 need_write = (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA));
3420 if (!need_write) {
3421 return O_RDONLY;
3424 /* DENY_DOS opens are always underlying read-write on the
3425 file handle, no matter what the requested access mask
3426 says. */
3428 need_read =
3429 ((private_flags & NTCREATEX_FLAG_DENY_DOS) ||
3430 access_mask & (FILE_READ_ATTRIBUTES|FILE_READ_DATA|
3431 FILE_READ_EA|FILE_EXECUTE));
3433 if (!need_read) {
3434 return O_WRONLY;
3436 return O_RDWR;
3439 /****************************************************************************
3440 Open a file with a share mode. Passed in an already created files_struct *.
3441 ****************************************************************************/
3443 static NTSTATUS open_file_ntcreate(connection_struct *conn,
3444 struct smb_request *req,
3445 uint32_t access_mask, /* access bits (FILE_READ_DATA etc.) */
3446 uint32_t share_access, /* share constants (FILE_SHARE_READ etc) */
3447 uint32_t create_disposition, /* FILE_OPEN_IF etc. */
3448 uint32_t create_options, /* options such as delete on close. */
3449 uint32_t new_dos_attributes, /* attributes used for new file. */
3450 int oplock_request, /* internal Samba oplock codes. */
3451 const struct smb2_lease *lease,
3452 /* Information (FILE_EXISTS etc.) */
3453 uint32_t private_flags, /* Samba specific flags. */
3454 struct smb_filename *parent_dir_fname, /* parent. */
3455 struct smb_filename *smb_fname_atname, /* atname relative to parent. */
3456 int *pinfo,
3457 files_struct *fsp)
3459 struct smb_filename *smb_fname = fsp->fsp_name;
3460 int flags=0;
3461 int flags2=0;
3462 bool file_existed = VALID_STAT(smb_fname->st);
3463 bool def_acl = False;
3464 bool posix_open = False;
3465 bool new_file_created = False;
3466 bool first_open_attempt = true;
3467 NTSTATUS fsp_open = NT_STATUS_ACCESS_DENIED;
3468 mode_t new_unx_mode = (mode_t)0;
3469 mode_t unx_mode = (mode_t)0;
3470 int info;
3471 uint32_t existing_dos_attributes = 0;
3472 struct share_mode_lock *lck = NULL;
3473 uint32_t open_access_mask = access_mask;
3474 NTSTATUS status;
3475 SMB_STRUCT_STAT saved_stat = smb_fname->st;
3476 struct timespec old_write_time;
3477 bool setup_poll = false;
3478 bool ok;
3480 if (conn->printer) {
3482 * Printers are handled completely differently.
3483 * Most of the passed parameters are ignored.
3486 if (pinfo) {
3487 *pinfo = FILE_WAS_CREATED;
3490 DEBUG(10, ("open_file_ntcreate: printer open fname=%s\n",
3491 smb_fname_str_dbg(smb_fname)));
3493 if (!req) {
3494 DEBUG(0,("open_file_ntcreate: printer open without "
3495 "an SMB request!\n"));
3496 return NT_STATUS_INTERNAL_ERROR;
3499 return print_spool_open(fsp, smb_fname->base_name,
3500 req->vuid);
3503 if (new_dos_attributes & FILE_FLAG_POSIX_SEMANTICS) {
3504 posix_open = True;
3505 unx_mode = (mode_t)(new_dos_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
3506 new_dos_attributes = 0;
3507 } else {
3508 /* Windows allows a new file to be created and
3509 silently removes a FILE_ATTRIBUTE_DIRECTORY
3510 sent by the client. Do the same. */
3512 new_dos_attributes &= ~FILE_ATTRIBUTE_DIRECTORY;
3514 /* We add FILE_ATTRIBUTE_ARCHIVE to this as this mode is only used if the file is
3515 * created new. */
3516 unx_mode = unix_mode(conn, new_dos_attributes | FILE_ATTRIBUTE_ARCHIVE,
3517 smb_fname, parent_dir_fname);
3520 DEBUG(10, ("open_file_ntcreate: fname=%s, dos_attrs=0x%x "
3521 "access_mask=0x%x share_access=0x%x "
3522 "create_disposition = 0x%x create_options=0x%x "
3523 "unix mode=0%o oplock_request=%d private_flags = 0x%x\n",
3524 smb_fname_str_dbg(smb_fname), new_dos_attributes,
3525 access_mask, share_access, create_disposition,
3526 create_options, (unsigned int)unx_mode, oplock_request,
3527 (unsigned int)private_flags));
3529 if (req == NULL) {
3530 /* Ensure req == NULL means INTERNAL_OPEN_ONLY */
3531 SMB_ASSERT(oplock_request == INTERNAL_OPEN_ONLY);
3532 } else {
3533 /* And req != NULL means no INTERNAL_OPEN_ONLY */
3534 SMB_ASSERT(((oplock_request & INTERNAL_OPEN_ONLY) == 0));
3538 * Only non-internal opens can be deferred at all
3541 if (req) {
3542 struct deferred_open_record *open_rec;
3543 if (get_deferred_open_message_state(req, NULL, &open_rec)) {
3545 /* If it was an async create retry, the file
3546 didn't exist. */
3548 if (is_deferred_open_async(open_rec)) {
3549 SET_STAT_INVALID(smb_fname->st);
3550 file_existed = false;
3553 /* Ensure we don't reprocess this message. */
3554 remove_deferred_open_message_smb(req->xconn, req->mid);
3556 first_open_attempt = false;
3560 if (!posix_open) {
3561 new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
3562 if (file_existed) {
3564 * Only use stored DOS attributes for checks
3565 * against requested attributes (below via
3566 * open_match_attributes()), cf bug #11992
3567 * for details. -slow
3569 uint32_t attr = 0;
3571 status = SMB_VFS_FGET_DOS_ATTRIBUTES(conn, smb_fname->fsp, &attr);
3572 if (NT_STATUS_IS_OK(status)) {
3573 existing_dos_attributes = attr;
3578 /* ignore any oplock requests if oplocks are disabled */
3579 if (!lp_oplocks(SNUM(conn)) ||
3580 IS_VETO_OPLOCK_PATH(conn, smb_fname->base_name)) {
3581 /* Mask off everything except the private Samba bits. */
3582 oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
3585 /* this is for OS/2 long file names - say we don't support them */
3586 if (req != NULL && !req->posix_pathnames &&
3587 strstr(smb_fname->base_name,".+,;=[].")) {
3588 /* OS/2 Workplace shell fix may be main code stream in a later
3589 * release. */
3590 DEBUG(5,("open_file_ntcreate: OS/2 long filenames are not "
3591 "supported.\n"));
3592 if (use_nt_status()) {
3593 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3595 return NT_STATUS_DOS(ERRDOS, ERRcannotopen);
3598 switch( create_disposition ) {
3599 case FILE_OPEN:
3600 /* If file exists open. If file doesn't exist error. */
3601 if (!file_existed) {
3602 DEBUG(5,("open_file_ntcreate: FILE_OPEN "
3603 "requested for file %s and file "
3604 "doesn't exist.\n",
3605 smb_fname_str_dbg(smb_fname)));
3606 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3608 break;
3610 case FILE_OVERWRITE:
3611 /* If file exists overwrite. If file doesn't exist
3612 * error. */
3613 if (!file_existed) {
3614 DEBUG(5,("open_file_ntcreate: FILE_OVERWRITE "
3615 "requested for file %s and file "
3616 "doesn't exist.\n",
3617 smb_fname_str_dbg(smb_fname) ));
3618 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3620 break;
3622 case FILE_CREATE:
3623 /* If file exists error. If file doesn't exist
3624 * create. */
3625 if (file_existed) {
3626 DEBUG(5,("open_file_ntcreate: FILE_CREATE "
3627 "requested for file %s and file "
3628 "already exists.\n",
3629 smb_fname_str_dbg(smb_fname)));
3630 if (S_ISDIR(smb_fname->st.st_ex_mode)) {
3631 return NT_STATUS_FILE_IS_A_DIRECTORY;
3633 return NT_STATUS_OBJECT_NAME_COLLISION;
3635 break;
3637 case FILE_SUPERSEDE:
3638 case FILE_OVERWRITE_IF:
3639 case FILE_OPEN_IF:
3640 break;
3641 default:
3642 return NT_STATUS_INVALID_PARAMETER;
3645 flags2 = disposition_to_open_flags(create_disposition);
3647 /* We only care about matching attributes on file exists and
3648 * overwrite. */
3650 if (!posix_open && file_existed &&
3651 ((create_disposition == FILE_OVERWRITE) ||
3652 (create_disposition == FILE_OVERWRITE_IF))) {
3653 if (!open_match_attributes(conn, existing_dos_attributes,
3654 new_dos_attributes,
3655 unx_mode, &new_unx_mode)) {
3656 DEBUG(5,("open_file_ntcreate: attributes mismatch "
3657 "for file %s (%x %x) (0%o, 0%o)\n",
3658 smb_fname_str_dbg(smb_fname),
3659 existing_dos_attributes,
3660 new_dos_attributes,
3661 (unsigned int)smb_fname->st.st_ex_mode,
3662 (unsigned int)unx_mode ));
3663 return NT_STATUS_ACCESS_DENIED;
3667 status = smbd_calculate_access_mask_fsp(parent_dir_fname->fsp,
3668 smb_fname->fsp,
3669 false,
3670 access_mask,
3671 &access_mask);
3672 if (!NT_STATUS_IS_OK(status)) {
3673 DBG_DEBUG("smbd_calculate_access_mask_fsp "
3674 "on file %s returned %s\n",
3675 smb_fname_str_dbg(smb_fname),
3676 nt_errstr(status));
3677 return status;
3680 open_access_mask = access_mask;
3682 if (flags2 & O_TRUNC) {
3683 open_access_mask |= FILE_WRITE_DATA; /* This will cause oplock breaks. */
3686 if (file_existed) {
3688 * stat opens on existing files don't get oplocks.
3689 * They can get leases.
3691 * Note that we check for stat open on the *open_access_mask*,
3692 * i.e. the access mask we actually used to do the open,
3693 * not the one the client asked for (which is in
3694 * fsp->access_mask). This is due to the fact that
3695 * FILE_OVERWRITE and FILE_OVERWRITE_IF add in O_TRUNC,
3696 * which adds FILE_WRITE_DATA to open_access_mask.
3698 if (is_oplock_stat_open(open_access_mask) && lease == NULL) {
3699 oplock_request = NO_OPLOCK;
3703 DEBUG(10, ("open_file_ntcreate: fname=%s, after mapping "
3704 "access_mask=0x%x\n", smb_fname_str_dbg(smb_fname),
3705 access_mask));
3708 * Note that we ignore the append flag as append does not
3709 * mean the same thing under DOS and Unix.
3712 flags = calculate_open_access_flags(access_mask, private_flags);
3715 * Currently we only look at FILE_WRITE_THROUGH for create options.
3718 #if defined(O_SYNC)
3719 if ((create_options & FILE_WRITE_THROUGH) && lp_strict_sync(SNUM(conn))) {
3720 flags2 |= O_SYNC;
3722 #endif /* O_SYNC */
3724 if (posix_open && (access_mask & FILE_APPEND_DATA)) {
3725 flags2 |= O_APPEND;
3728 if (!posix_open && !CAN_WRITE(conn)) {
3730 * We should really return a permission denied error if either
3731 * O_CREAT or O_TRUNC are set, but for compatibility with
3732 * older versions of Samba we just AND them out.
3734 flags2 &= ~(O_CREAT|O_TRUNC);
3738 * With kernel oplocks the open breaking an oplock
3739 * blocks until the oplock holder has given up the
3740 * oplock or closed the file. We prevent this by always
3741 * trying to open the file with O_NONBLOCK (see "man
3742 * fcntl" on Linux).
3744 * If a process that doesn't use the smbd open files
3745 * database or communication methods holds a kernel
3746 * oplock we must periodically poll for available open
3747 * using O_NONBLOCK.
3749 flags2 |= O_NONBLOCK;
3752 * Ensure we can't write on a read-only share or file.
3755 if (flags != O_RDONLY && file_existed &&
3756 (!CAN_WRITE(conn) || IS_DOS_READONLY(existing_dos_attributes))) {
3757 DEBUG(5,("open_file_ntcreate: write access requested for "
3758 "file %s on read only %s\n",
3759 smb_fname_str_dbg(smb_fname),
3760 !CAN_WRITE(conn) ? "share" : "file" ));
3761 return NT_STATUS_ACCESS_DENIED;
3764 if (VALID_STAT(smb_fname->st)) {
3766 * Only try and create a file id before open
3767 * for an existing file. For a file being created
3768 * this won't do anything useful until the file
3769 * exists and has a valid stat struct.
3771 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
3773 fh_set_private_options(fsp->fh, private_flags);
3774 fsp->access_mask = open_access_mask; /* We change this to the
3775 * requested access_mask after
3776 * the open is done. */
3777 if (posix_open) {
3778 fsp->posix_flags |= FSP_POSIX_FLAGS_ALL;
3781 if ((create_options & FILE_DELETE_ON_CLOSE) &&
3782 (flags2 & O_CREAT) &&
3783 !file_existed) {
3784 /* Delete on close semantics for new files. */
3785 status = can_set_delete_on_close(fsp,
3786 new_dos_attributes);
3787 if (!NT_STATUS_IS_OK(status)) {
3788 fd_close(fsp);
3789 return status;
3794 * Ensure we pay attention to default ACLs on directories if required.
3797 if ((flags2 & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
3798 (def_acl = directory_has_default_acl_fsp(parent_dir_fname->fsp)))
3800 unx_mode = (0777 & lp_create_mask(SNUM(conn)));
3803 DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o, "
3804 "access_mask = 0x%x, open_access_mask = 0x%x\n",
3805 (unsigned int)flags, (unsigned int)flags2,
3806 (unsigned int)unx_mode, (unsigned int)access_mask,
3807 (unsigned int)open_access_mask));
3809 fsp_open = open_file(fsp,
3810 req,
3811 parent_dir_fname,
3812 flags|flags2,
3813 unx_mode,
3814 access_mask,
3815 open_access_mask,
3816 private_flags,
3817 &new_file_created);
3818 if (NT_STATUS_EQUAL(fsp_open, NT_STATUS_NETWORK_BUSY)) {
3819 if (file_existed && S_ISFIFO(fsp->fsp_name->st.st_ex_mode)) {
3820 DEBUG(10, ("FIFO busy\n"));
3821 return NT_STATUS_NETWORK_BUSY;
3823 if (req == NULL) {
3824 DEBUG(10, ("Internal open busy\n"));
3825 return NT_STATUS_NETWORK_BUSY;
3828 * This handles the kernel oplock case:
3830 * the file has an active kernel oplock and the open() returned
3831 * EWOULDBLOCK/EAGAIN which maps to NETWORK_BUSY.
3833 * "Samba locking.tdb oplocks" are handled below after acquiring
3834 * the sharemode lock with get_share_mode_lock().
3836 setup_poll = true;
3839 if (NT_STATUS_EQUAL(fsp_open, NT_STATUS_RETRY)) {
3841 * EINTR from the open(2) syscall. Just setup a retry
3842 * in a bit. We can't use the sys_write() tight retry
3843 * loop here, as we might have to actually deal with
3844 * lease-break signals to avoid a deadlock.
3846 setup_poll = true;
3849 if (setup_poll) {
3851 * From here on we assume this is an oplock break triggered
3854 lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
3856 if ((lck != NULL) && !validate_oplock_types(lck)) {
3857 smb_panic("validate_oplock_types failed");
3861 * Retry once a second. If there's a share_mode_lock
3862 * around, also wait for it in case it was smbd
3863 * holding that kernel oplock that can quickly tell us
3864 * the oplock got removed.
3867 setup_poll_open(
3868 req,
3869 lck,
3870 fsp->file_id,
3871 timeval_set(OPLOCK_BREAK_TIMEOUT*2, 0),
3872 timeval_set(1, 0));
3874 TALLOC_FREE(lck);
3876 return NT_STATUS_SHARING_VIOLATION;
3879 if (!NT_STATUS_IS_OK(fsp_open)) {
3880 bool wait_for_aio = NT_STATUS_EQUAL(
3881 fsp_open, NT_STATUS_MORE_PROCESSING_REQUIRED);
3882 if (wait_for_aio) {
3883 schedule_async_open(req);
3885 return fsp_open;
3888 if (new_file_created) {
3890 * As we atomically create using O_CREAT|O_EXCL,
3891 * then if new_file_created is true, then
3892 * file_existed *MUST* have been false (even
3893 * if the file was previously detected as being
3894 * there).
3896 file_existed = false;
3899 if (file_existed && !check_same_dev_ino(&saved_stat, &smb_fname->st)) {
3901 * The file did exist, but some other (local or NFS)
3902 * process either renamed/unlinked and re-created the
3903 * file with different dev/ino after we walked the path,
3904 * but before we did the open. We could retry the
3905 * open but it's a rare enough case it's easier to
3906 * just fail the open to prevent creating any problems
3907 * in the open file db having the wrong dev/ino key.
3909 fd_close(fsp);
3910 DBG_WARNING("file %s - dev/ino mismatch. "
3911 "Old (dev=%ju, ino=%ju). "
3912 "New (dev=%ju, ino=%ju). Failing open "
3913 "with NT_STATUS_ACCESS_DENIED.\n",
3914 smb_fname_str_dbg(smb_fname),
3915 (uintmax_t)saved_stat.st_ex_dev,
3916 (uintmax_t)saved_stat.st_ex_ino,
3917 (uintmax_t)smb_fname->st.st_ex_dev,
3918 (uintmax_t)smb_fname->st.st_ex_ino);
3919 return NT_STATUS_ACCESS_DENIED;
3922 old_write_time = smb_fname->st.st_ex_mtime;
3925 * Deal with the race condition where two smbd's detect the
3926 * file doesn't exist and do the create at the same time. One
3927 * of them will win and set a share mode, the other (ie. this
3928 * one) should check if the requested share mode for this
3929 * create is allowed.
3933 * Now the file exists and fsp is successfully opened,
3934 * fsp->dev and fsp->inode are valid and should replace the
3935 * dev=0,inode=0 from a non existent file. Spotted by
3936 * Nadav Danieli <nadavd@exanet.com>. JRA.
3939 lck = get_share_mode_lock(talloc_tos(), fsp->file_id,
3940 conn->connectpath,
3941 smb_fname, &old_write_time);
3943 if (lck == NULL) {
3944 DEBUG(0, ("open_file_ntcreate: Could not get share "
3945 "mode lock for %s\n",
3946 smb_fname_str_dbg(smb_fname)));
3947 fd_close(fsp);
3948 return NT_STATUS_SHARING_VIOLATION;
3951 /* Get the types we need to examine. */
3952 if (!validate_oplock_types(lck)) {
3953 smb_panic("validate_oplock_types failed");
3956 if (has_delete_on_close(lck, fsp->name_hash)) {
3957 TALLOC_FREE(lck);
3958 fd_close(fsp);
3959 return NT_STATUS_DELETE_PENDING;
3962 status = handle_share_mode_lease(
3963 fsp,
3964 lck,
3965 create_disposition,
3966 access_mask,
3967 share_access,
3968 oplock_request,
3969 lease,
3970 first_open_attempt);
3972 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
3973 schedule_defer_open(lck, fsp->file_id, req);
3974 TALLOC_FREE(lck);
3975 fd_close(fsp);
3976 return NT_STATUS_SHARING_VIOLATION;
3979 if (!NT_STATUS_IS_OK(status)) {
3980 TALLOC_FREE(lck);
3981 fd_close(fsp);
3982 return status;
3985 share_mode_flags_restrict(lck, access_mask, share_access, 0);
3987 ok = set_share_mode(
3988 lck,
3989 fsp,
3990 get_current_uid(fsp->conn),
3991 req ? req->mid : 0,
3992 fsp->oplock_type,
3993 share_access,
3994 access_mask);
3995 if (!ok) {
3996 if (fsp->oplock_type == LEASE_OPLOCK) {
3997 status = remove_lease_if_stale(
3998 lck,
3999 fsp_client_guid(fsp),
4000 &fsp->lease->lease.lease_key);
4001 if (!NT_STATUS_IS_OK(status)) {
4002 DBG_WARNING("remove_lease_if_stale "
4003 "failed: %s\n",
4004 nt_errstr(status));
4007 TALLOC_FREE(lck);
4008 fd_close(fsp);
4009 return NT_STATUS_NO_MEMORY;
4012 /* Should we atomically (to the client at least) truncate ? */
4013 if ((!new_file_created) &&
4014 (flags2 & O_TRUNC) &&
4015 (S_ISREG(fsp->fsp_name->st.st_ex_mode))) {
4016 int ret;
4018 ret = SMB_VFS_FTRUNCATE(fsp, 0);
4019 if (ret != 0) {
4020 status = map_nt_error_from_unix(errno);
4021 del_share_mode(lck, fsp);
4022 TALLOC_FREE(lck);
4023 fd_close(fsp);
4024 return status;
4026 notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
4027 FILE_NOTIFY_CHANGE_SIZE
4028 | FILE_NOTIFY_CHANGE_ATTRIBUTES,
4029 fsp->fsp_name->base_name);
4033 * We have the share entry *locked*.....
4036 /* Delete streams if create_disposition requires it */
4037 if (!new_file_created && clear_ads(create_disposition) &&
4038 !is_ntfs_stream_smb_fname(smb_fname)) {
4039 status = delete_all_streams(conn, smb_fname);
4040 if (!NT_STATUS_IS_OK(status)) {
4041 del_share_mode(lck, fsp);
4042 TALLOC_FREE(lck);
4043 fd_close(fsp);
4044 return status;
4048 if (!fsp->fsp_flags.is_pathref &&
4049 fsp_get_io_fd(fsp) != -1 &&
4050 lp_kernel_share_modes(SNUM(conn)))
4052 int ret;
4054 * Beware: streams implementing VFS modules may
4055 * implement streams in a way that fsp will have the
4056 * basefile open in the fsp fd, so lacking a distinct
4057 * fd for the stream the file-system sharemode will
4058 * apply on the basefile which is wrong. The actual
4059 * check is deferred to the VFS module implementing
4060 * the file-system sharemode call.
4062 ret = SMB_VFS_FILESYSTEM_SHAREMODE(fsp,
4063 share_access,
4064 access_mask);
4065 if (ret == -1){
4066 del_share_mode(lck, fsp);
4067 TALLOC_FREE(lck);
4068 fd_close(fsp);
4070 return NT_STATUS_SHARING_VIOLATION;
4073 fsp->fsp_flags.kernel_share_modes_taken = true;
4077 * At this point onwards, we can guarantee that the share entry
4078 * is locked, whether we created the file or not, and that the
4079 * deny mode is compatible with all current opens.
4083 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
4084 * but we don't have to store this - just ignore it on access check.
4086 if (conn->sconn->using_smb2) {
4088 * SMB2 doesn't return it (according to Microsoft tests).
4089 * Test Case: TestSuite_ScenarioNo009GrantedAccessTestS0
4090 * File created with access = 0x7 (Read, Write, Delete)
4091 * Query Info on file returns 0x87 (Read, Write, Delete, Read Attributes)
4093 fsp->access_mask = access_mask;
4094 } else {
4095 /* But SMB1 does. */
4096 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
4099 if (new_file_created) {
4100 info = FILE_WAS_CREATED;
4101 } else {
4102 if (flags2 & O_TRUNC) {
4103 info = FILE_WAS_OVERWRITTEN;
4104 } else {
4105 info = FILE_WAS_OPENED;
4109 if (pinfo) {
4110 *pinfo = info;
4113 /* Handle strange delete on close create semantics. */
4114 if (create_options & FILE_DELETE_ON_CLOSE) {
4115 if (!new_file_created) {
4116 status = can_set_delete_on_close(fsp,
4117 existing_dos_attributes);
4119 if (!NT_STATUS_IS_OK(status)) {
4120 /* Remember to delete the mode we just added. */
4121 del_share_mode(lck, fsp);
4122 TALLOC_FREE(lck);
4123 fd_close(fsp);
4124 return status;
4127 /* Note that here we set the *initial* delete on close flag,
4128 not the regular one. The magic gets handled in close. */
4129 fsp->fsp_flags.initial_delete_on_close = true;
4133 * If we created a file and it's not a stream, this is the point where
4134 * we set the itime (aka invented time) that get's stored in the DOS
4135 * attribute xattr. The value is going to be either what the filesystem
4136 * provided or a copy of the creation date.
4138 * Either way, we turn the itime into a File-ID, unless the filesystem
4139 * provided one (unlikely).
4141 if (info == FILE_WAS_CREATED && !is_named_stream(smb_fname)) {
4142 smb_fname->st.st_ex_iflags &= ~ST_EX_IFLAG_CALCULATED_ITIME;
4144 if (lp_store_dos_attributes(SNUM(conn)) &&
4145 smb_fname->st.st_ex_iflags & ST_EX_IFLAG_CALCULATED_FILE_ID)
4147 uint64_t file_id;
4149 file_id = make_file_id_from_itime(&smb_fname->st);
4150 update_stat_ex_file_id(&smb_fname->st, file_id);
4154 if (info != FILE_WAS_OPENED) {
4155 /* Overwritten files should be initially set as archive */
4156 if ((info == FILE_WAS_OVERWRITTEN && lp_map_archive(SNUM(conn))) ||
4157 lp_store_dos_attributes(SNUM(conn))) {
4158 (void)fdos_mode(fsp);
4159 if (!posix_open) {
4160 if (file_set_dosmode(conn, smb_fname,
4161 new_dos_attributes | FILE_ATTRIBUTE_ARCHIVE,
4162 parent_dir_fname, true) == 0) {
4163 unx_mode = smb_fname->st.st_ex_mode;
4169 /* Determine sparse flag. */
4170 if (posix_open) {
4171 /* POSIX opens are sparse by default. */
4172 fsp->fsp_flags.is_sparse = true;
4173 } else {
4174 fsp->fsp_flags.is_sparse =
4175 (existing_dos_attributes & FILE_ATTRIBUTE_SPARSE);
4179 * Take care of inherited ACLs on created files - if default ACL not
4180 * selected.
4183 if (!posix_open && new_file_created && !def_acl) {
4184 if (unx_mode != smb_fname->st.st_ex_mode) {
4185 int ret = SMB_VFS_FCHMOD(fsp, unx_mode);
4186 if (ret == -1) {
4187 DBG_INFO("failed to reset "
4188 "attributes of file %s to 0%o\n",
4189 smb_fname_str_dbg(smb_fname),
4190 (unsigned int)unx_mode);
4194 } else if (new_unx_mode) {
4196 * We only get here in the case of:
4198 * a). Not a POSIX open.
4199 * b). File already existed.
4200 * c). File was overwritten.
4201 * d). Requested DOS attributes didn't match
4202 * the DOS attributes on the existing file.
4204 * In that case new_unx_mode has been set
4205 * equal to the calculated mode (including
4206 * possible inheritance of the mode from the
4207 * containing directory).
4209 * Note this mode was calculated with the
4210 * DOS attribute FILE_ATTRIBUTE_ARCHIVE added,
4211 * so the mode change here is suitable for
4212 * an overwritten file.
4215 if (new_unx_mode != smb_fname->st.st_ex_mode) {
4216 int ret = SMB_VFS_FCHMOD(fsp, new_unx_mode);
4217 if (ret == -1) {
4218 DBG_INFO("failed to reset "
4219 "attributes of file %s to 0%o\n",
4220 smb_fname_str_dbg(smb_fname),
4221 (unsigned int)new_unx_mode);
4228 * Deal with other opens having a modified write time.
4230 struct timespec write_time = get_share_mode_write_time(lck);
4232 if (!is_omit_timespec(&write_time)) {
4233 update_stat_ex_mtime(&fsp->fsp_name->st, write_time);
4237 TALLOC_FREE(lck);
4239 return NT_STATUS_OK;
4242 static NTSTATUS mkdir_internal(connection_struct *conn,
4243 struct smb_filename *parent_dir_fname, /* parent. */
4244 struct smb_filename *smb_fname_atname, /* atname relative to parent. */
4245 struct smb_filename *smb_dname, /* full pathname from root of share. */
4246 uint32_t file_attributes,
4247 struct files_struct *fsp)
4249 const struct loadparm_substitution *lp_sub =
4250 loadparm_s3_global_substitution();
4251 mode_t mode;
4252 NTSTATUS status;
4253 bool posix_open = false;
4254 bool need_re_stat = false;
4255 uint32_t access_mask = SEC_DIR_ADD_SUBDIR;
4256 int ret;
4258 if (!CAN_WRITE(conn) || (access_mask & ~(conn->share_access))) {
4259 DEBUG(5,("mkdir_internal: failing share access "
4260 "%s\n", lp_servicename(talloc_tos(), lp_sub, SNUM(conn))));
4261 return NT_STATUS_ACCESS_DENIED;
4264 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
4265 posix_open = true;
4266 mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
4267 } else {
4268 mode = unix_mode(conn,
4269 FILE_ATTRIBUTE_DIRECTORY,
4270 smb_dname,
4271 parent_dir_fname);
4274 status = check_parent_access_fsp(parent_dir_fname->fsp, access_mask);
4275 if(!NT_STATUS_IS_OK(status)) {
4276 DBG_INFO("check_parent_access_fsp "
4277 "on directory %s for path %s returned %s\n",
4278 smb_fname_str_dbg(parent_dir_fname),
4279 smb_dname->base_name,
4280 nt_errstr(status));
4281 return status;
4284 if (lp_inherit_acls(SNUM(conn))) {
4285 if (directory_has_default_acl_fsp(parent_dir_fname->fsp)) {
4286 mode = (0777 & lp_directory_mask(SNUM(conn)));
4290 ret = SMB_VFS_MKDIRAT(conn,
4291 parent_dir_fname->fsp,
4292 smb_fname_atname,
4293 mode);
4294 if (ret != 0) {
4295 return map_nt_error_from_unix(errno);
4299 * Make this a pathref fsp for now. open_directory() will reopen as a
4300 * full fsp.
4302 fsp->fsp_flags.is_pathref = true;
4304 status = fd_openat(conn->cwd_fsp, smb_dname, fsp, O_RDONLY | O_DIRECTORY, 0);
4305 if (!NT_STATUS_IS_OK(status)) {
4306 return status;
4309 /* Ensure we're checking for a symlink here.... */
4310 /* We don't want to get caught by a symlink racer. */
4312 if (SMB_VFS_FSTAT(fsp, &smb_dname->st) == -1) {
4313 DEBUG(2, ("Could not stat directory '%s' just created: %s\n",
4314 smb_fname_str_dbg(smb_dname), strerror(errno)));
4315 return map_nt_error_from_unix(errno);
4318 if (!S_ISDIR(smb_dname->st.st_ex_mode)) {
4319 DEBUG(0, ("Directory '%s' just created is not a directory !\n",
4320 smb_fname_str_dbg(smb_dname)));
4321 return NT_STATUS_NOT_A_DIRECTORY;
4324 smb_dname->st.st_ex_iflags &= ~ST_EX_IFLAG_CALCULATED_ITIME;
4326 if (lp_store_dos_attributes(SNUM(conn))) {
4327 if (smb_dname->st.st_ex_iflags & ST_EX_IFLAG_CALCULATED_FILE_ID)
4329 uint64_t file_id;
4331 file_id = make_file_id_from_itime(&smb_dname->st);
4332 update_stat_ex_file_id(&smb_dname->st, file_id);
4335 if (!posix_open) {
4336 file_set_dosmode(conn, smb_dname,
4337 file_attributes | FILE_ATTRIBUTE_DIRECTORY,
4338 parent_dir_fname, true);
4342 if (lp_inherit_permissions(SNUM(conn))) {
4343 inherit_access_posix_acl(conn, parent_dir_fname,
4344 smb_dname, mode);
4345 need_re_stat = true;
4348 if (!posix_open) {
4350 * Check if high bits should have been set,
4351 * then (if bits are missing): add them.
4352 * Consider bits automagically set by UNIX, i.e. SGID bit from parent
4353 * dir.
4355 if ((mode & ~(S_IRWXU|S_IRWXG|S_IRWXO)) &&
4356 (mode & ~smb_dname->st.st_ex_mode)) {
4357 SMB_VFS_FCHMOD(fsp,
4358 (smb_dname->st.st_ex_mode |
4359 (mode & ~smb_dname->st.st_ex_mode)));
4360 need_re_stat = true;
4364 /* Change the owner if required. */
4365 if (lp_inherit_owner(SNUM(conn)) != INHERIT_OWNER_NO) {
4366 change_dir_owner_to_parent_fsp(parent_dir_fname->fsp,
4367 fsp);
4368 need_re_stat = true;
4371 if (need_re_stat) {
4372 if (SMB_VFS_FSTAT(fsp, &smb_dname->st) == -1) {
4373 DEBUG(2, ("Could not stat directory '%s' just created: %s\n",
4374 smb_fname_str_dbg(smb_dname), strerror(errno)));
4375 return map_nt_error_from_unix(errno);
4379 notify_fname(conn, NOTIFY_ACTION_ADDED, FILE_NOTIFY_CHANGE_DIR_NAME,
4380 smb_dname->base_name);
4382 return NT_STATUS_OK;
4385 /****************************************************************************
4386 Open a directory from an NT SMB call.
4387 ****************************************************************************/
4389 static NTSTATUS open_directory(connection_struct *conn,
4390 struct smb_request *req,
4391 uint32_t access_mask,
4392 uint32_t share_access,
4393 uint32_t create_disposition,
4394 uint32_t create_options,
4395 uint32_t file_attributes,
4396 struct smb_filename *parent_dir_fname,
4397 struct smb_filename *smb_fname_atname,
4398 int *pinfo,
4399 struct files_struct *fsp)
4401 struct smb_filename *smb_dname = fsp->fsp_name;
4402 bool dir_existed = VALID_STAT(smb_dname->st);
4403 struct share_mode_lock *lck = NULL;
4404 NTSTATUS status;
4405 struct timespec mtimespec;
4406 int info = 0;
4407 bool ok;
4408 uint32_t need_fd_access;
4410 if (is_ntfs_stream_smb_fname(smb_dname)) {
4411 DEBUG(2, ("open_directory: %s is a stream name!\n",
4412 smb_fname_str_dbg(smb_dname)));
4413 return NT_STATUS_NOT_A_DIRECTORY;
4416 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS)) {
4417 /* Ensure we have a directory attribute. */
4418 file_attributes |= FILE_ATTRIBUTE_DIRECTORY;
4421 DBG_INFO("opening directory %s, access_mask = 0x%"PRIx32", "
4422 "share_access = 0x%"PRIx32" create_options = 0x%"PRIx32", "
4423 "create_disposition = 0x%"PRIx32", "
4424 "file_attributes = 0x%"PRIx32"\n",
4425 smb_fname_str_dbg(smb_dname),
4426 access_mask,
4427 share_access,
4428 create_options,
4429 create_disposition,
4430 file_attributes);
4432 status = smbd_calculate_access_mask_fsp(parent_dir_fname->fsp,
4433 smb_dname->fsp,
4434 false,
4435 access_mask,
4436 &access_mask);
4437 if (!NT_STATUS_IS_OK(status)) {
4438 DBG_DEBUG("smbd_calculate_access_mask_fsp "
4439 "on file %s returned %s\n",
4440 smb_fname_str_dbg(smb_dname),
4441 nt_errstr(status));
4442 return status;
4445 if ((access_mask & SEC_FLAG_SYSTEM_SECURITY) &&
4446 !security_token_has_privilege(get_current_nttok(conn),
4447 SEC_PRIV_SECURITY)) {
4448 DEBUG(10, ("open_directory: open on %s "
4449 "failed - SEC_FLAG_SYSTEM_SECURITY denied.\n",
4450 smb_fname_str_dbg(smb_dname)));
4451 return NT_STATUS_PRIVILEGE_NOT_HELD;
4454 switch( create_disposition ) {
4455 case FILE_OPEN:
4457 if (!dir_existed) {
4458 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4461 info = FILE_WAS_OPENED;
4462 break;
4464 case FILE_CREATE:
4466 /* If directory exists error. If directory doesn't
4467 * exist create. */
4469 if (dir_existed) {
4470 status = NT_STATUS_OBJECT_NAME_COLLISION;
4471 DEBUG(2, ("open_directory: unable to create "
4472 "%s. Error was %s\n",
4473 smb_fname_str_dbg(smb_dname),
4474 nt_errstr(status)));
4475 return status;
4478 status = mkdir_internal(conn,
4479 parent_dir_fname,
4480 smb_fname_atname,
4481 smb_dname,
4482 file_attributes,
4483 fsp);
4485 if (!NT_STATUS_IS_OK(status)) {
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 info = FILE_WAS_CREATED;
4494 break;
4496 case FILE_OPEN_IF:
4498 * If directory exists open. If directory doesn't
4499 * exist create.
4502 if (dir_existed) {
4503 status = NT_STATUS_OK;
4504 info = FILE_WAS_OPENED;
4505 } else {
4506 status = mkdir_internal(conn,
4507 parent_dir_fname,
4508 smb_fname_atname,
4509 smb_dname,
4510 file_attributes,
4511 fsp);
4513 if (NT_STATUS_IS_OK(status)) {
4514 info = FILE_WAS_CREATED;
4515 } else {
4516 /* Cope with create race. */
4517 if (!NT_STATUS_EQUAL(status,
4518 NT_STATUS_OBJECT_NAME_COLLISION)) {
4519 DEBUG(2, ("open_directory: unable to create "
4520 "%s. Error was %s\n",
4521 smb_fname_str_dbg(smb_dname),
4522 nt_errstr(status)));
4523 return status;
4527 * If mkdir_internal() returned
4528 * NT_STATUS_OBJECT_NAME_COLLISION
4529 * we still must lstat the path.
4532 if (SMB_VFS_LSTAT(conn, smb_dname)
4533 == -1) {
4534 DEBUG(2, ("Could not stat "
4535 "directory '%s' just "
4536 "opened: %s\n",
4537 smb_fname_str_dbg(
4538 smb_dname),
4539 strerror(errno)));
4540 return map_nt_error_from_unix(
4541 errno);
4544 info = FILE_WAS_OPENED;
4548 break;
4550 case FILE_SUPERSEDE:
4551 case FILE_OVERWRITE:
4552 case FILE_OVERWRITE_IF:
4553 default:
4554 DEBUG(5,("open_directory: invalid create_disposition "
4555 "0x%x for directory %s\n",
4556 (unsigned int)create_disposition,
4557 smb_fname_str_dbg(smb_dname)));
4558 return NT_STATUS_INVALID_PARAMETER;
4561 if(!S_ISDIR(smb_dname->st.st_ex_mode)) {
4562 DEBUG(5,("open_directory: %s is not a directory !\n",
4563 smb_fname_str_dbg(smb_dname)));
4564 return NT_STATUS_NOT_A_DIRECTORY;
4568 * Setup the files_struct for it.
4571 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_dname->st);
4572 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
4573 fsp->file_pid = req ? req->smbpid : 0;
4574 fsp->fsp_flags.can_lock = false;
4575 fsp->fsp_flags.can_read = false;
4576 fsp->fsp_flags.can_write = false;
4578 fh_set_private_options(fsp->fh, 0);
4580 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
4582 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
4583 fsp->print_file = NULL;
4584 fsp->fsp_flags.modified = false;
4585 fsp->oplock_type = NO_OPLOCK;
4586 fsp->sent_oplock_break = NO_BREAK_SENT;
4587 fsp->fsp_flags.is_directory = true;
4588 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
4589 fsp->posix_flags |= FSP_POSIX_FLAGS_ALL;
4592 /* Don't store old timestamps for directory
4593 handles in the internal database. We don't
4594 update them in there if new objects
4595 are created in the directory. Currently
4596 we only update timestamps on file writes.
4597 See bug #9870.
4599 mtimespec = make_omit_timespec();
4602 * Obviously for FILE_LIST_DIRECTORY we need to reopen to get an fd
4603 * usable for reading a directory. SMB2_FLUSH may be called on
4604 * directories opened with FILE_ADD_FILE and FILE_ADD_SUBDIRECTORY so
4605 * for those we need to reopen as well.
4607 need_fd_access =
4608 FILE_LIST_DIRECTORY |
4609 FILE_ADD_FILE |
4610 FILE_ADD_SUBDIRECTORY;
4612 if (access_mask & need_fd_access) {
4613 status = reopen_from_fsp(fsp, O_RDONLY | O_DIRECTORY, 0, NULL);
4614 if (!NT_STATUS_IS_OK(status)) {
4615 DBG_INFO("Could not open fd for [%s]: %s\n",
4616 smb_fname_str_dbg(smb_dname),
4617 nt_errstr(status));
4618 return status;
4622 status = vfs_stat_fsp(fsp);
4623 if (!NT_STATUS_IS_OK(status)) {
4624 fd_close(fsp);
4625 return status;
4628 if(!S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
4629 DEBUG(5,("open_directory: %s is not a directory !\n",
4630 smb_fname_str_dbg(smb_dname)));
4631 fd_close(fsp);
4632 return NT_STATUS_NOT_A_DIRECTORY;
4635 /* Ensure there was no race condition. We need to check
4636 * dev/inode but not permissions, as these can change
4637 * legitimately */
4638 if (!check_same_dev_ino(&smb_dname->st, &fsp->fsp_name->st)) {
4639 DEBUG(5,("open_directory: stat struct differs for "
4640 "directory %s.\n",
4641 smb_fname_str_dbg(smb_dname)));
4642 fd_close(fsp);
4643 return NT_STATUS_ACCESS_DENIED;
4646 if (info == FILE_WAS_OPENED) {
4647 status = smbd_check_access_rights_fsp(parent_dir_fname->fsp,
4648 fsp,
4649 false,
4650 access_mask);
4651 if (!NT_STATUS_IS_OK(status)) {
4652 DBG_DEBUG("smbd_check_access_rights_fsp on "
4653 "file %s failed with %s\n",
4654 fsp_str_dbg(fsp),
4655 nt_errstr(status));
4656 fd_close(fsp);
4657 return status;
4661 lck = get_share_mode_lock(talloc_tos(), fsp->file_id,
4662 conn->connectpath, smb_dname,
4663 &mtimespec);
4665 if (lck == NULL) {
4666 DEBUG(0, ("open_directory: Could not get share mode lock for "
4667 "%s\n", smb_fname_str_dbg(smb_dname)));
4668 fd_close(fsp);
4669 return NT_STATUS_SHARING_VIOLATION;
4672 if (has_delete_on_close(lck, fsp->name_hash)) {
4673 TALLOC_FREE(lck);
4674 fd_close(fsp);
4675 return NT_STATUS_DELETE_PENDING;
4678 status = open_mode_check(conn, fsp->file_id, lck,
4679 access_mask, share_access);
4681 if (!NT_STATUS_IS_OK(status)) {
4682 TALLOC_FREE(lck);
4683 fd_close(fsp);
4684 return status;
4687 share_mode_flags_restrict(lck, access_mask, share_access, 0);
4689 ok = set_share_mode(
4690 lck,
4691 fsp,
4692 get_current_uid(conn),
4693 req ? req->mid : 0,
4694 NO_OPLOCK,
4695 share_access,
4696 fsp->access_mask);
4697 if (!ok) {
4698 TALLOC_FREE(lck);
4699 fd_close(fsp);
4700 return NT_STATUS_NO_MEMORY;
4703 /* For directories the delete on close bit at open time seems
4704 always to be honored on close... See test 19 in Samba4 BASE-DELETE. */
4705 if (create_options & FILE_DELETE_ON_CLOSE) {
4706 status = can_set_delete_on_close(fsp, 0);
4707 if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
4708 del_share_mode(lck, fsp);
4709 TALLOC_FREE(lck);
4710 fd_close(fsp);
4711 return status;
4714 if (NT_STATUS_IS_OK(status)) {
4715 /* Note that here we set the *initial* delete on close flag,
4716 not the regular one. The magic gets handled in close. */
4717 fsp->fsp_flags.initial_delete_on_close = true;
4723 * Deal with other opens having a modified write time. Is this
4724 * possible for directories?
4726 struct timespec write_time = get_share_mode_write_time(lck);
4728 if (!is_omit_timespec(&write_time)) {
4729 update_stat_ex_mtime(&fsp->fsp_name->st, write_time);
4733 TALLOC_FREE(lck);
4735 if (pinfo) {
4736 *pinfo = info;
4739 return NT_STATUS_OK;
4742 NTSTATUS create_directory(connection_struct *conn, struct smb_request *req,
4743 struct smb_filename *smb_dname)
4745 NTSTATUS status;
4746 files_struct *fsp;
4748 status = SMB_VFS_CREATE_FILE(
4749 conn, /* conn */
4750 req, /* req */
4751 smb_dname, /* fname */
4752 FILE_READ_ATTRIBUTES, /* access_mask */
4753 FILE_SHARE_NONE, /* share_access */
4754 FILE_CREATE, /* create_disposition*/
4755 FILE_DIRECTORY_FILE, /* create_options */
4756 FILE_ATTRIBUTE_DIRECTORY, /* file_attributes */
4757 0, /* oplock_request */
4758 NULL, /* lease */
4759 0, /* allocation_size */
4760 0, /* private_flags */
4761 NULL, /* sd */
4762 NULL, /* ea_list */
4763 &fsp, /* result */
4764 NULL, /* pinfo */
4765 NULL, NULL); /* create context */
4767 if (NT_STATUS_IS_OK(status)) {
4768 close_file(req, fsp, NORMAL_CLOSE);
4771 return status;
4774 /****************************************************************************
4775 Receive notification that one of our open files has been renamed by another
4776 smbd process.
4777 ****************************************************************************/
4779 void msg_file_was_renamed(struct messaging_context *msg_ctx,
4780 void *private_data,
4781 uint32_t msg_type,
4782 struct server_id src,
4783 DATA_BLOB *data)
4785 struct file_rename_message *msg = NULL;
4786 enum ndr_err_code ndr_err;
4787 files_struct *fsp;
4788 struct smb_filename *smb_fname = NULL;
4789 struct smbd_server_connection *sconn =
4790 talloc_get_type_abort(private_data,
4791 struct smbd_server_connection);
4793 msg = talloc(talloc_tos(), struct file_rename_message);
4794 if (msg == NULL) {
4795 DBG_WARNING("talloc failed\n");
4796 return;
4799 ndr_err = ndr_pull_struct_blob_all(
4800 data,
4801 msg,
4802 msg,
4803 (ndr_pull_flags_fn_t)ndr_pull_file_rename_message);
4804 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
4805 DBG_DEBUG("ndr_pull_oplock_break_message failed: %s\n",
4806 ndr_errstr(ndr_err));
4807 goto out;
4809 if (DEBUGLEVEL >= 10) {
4810 struct server_id_buf buf;
4811 DBG_DEBUG("Got rename message from %s\n",
4812 server_id_str_buf(src, &buf));
4813 NDR_PRINT_DEBUG(file_rename_message, msg);
4816 /* stream_name must always be NULL if there is no stream. */
4817 if ((msg->stream_name != NULL) && (msg->stream_name[0] == '\0')) {
4818 msg->stream_name = NULL;
4821 smb_fname = synthetic_smb_fname(msg,
4822 msg->base_name,
4823 msg->stream_name,
4824 NULL,
4827 if (smb_fname == NULL) {
4828 DBG_DEBUG("synthetic_smb_fname failed\n");
4829 goto out;
4832 fsp = file_find_dif(sconn, msg->id, msg->share_file_id);
4833 if (fsp == NULL) {
4834 DBG_DEBUG("fsp not found\n");
4835 goto out;
4838 if (strcmp(fsp->conn->connectpath, msg->servicepath) == 0) {
4839 NTSTATUS status;
4840 DBG_DEBUG("renaming file %s from %s -> %s\n",
4841 fsp_fnum_dbg(fsp),
4842 fsp_str_dbg(fsp),
4843 smb_fname_str_dbg(smb_fname));
4844 status = fsp_set_smb_fname(fsp, smb_fname);
4845 if (!NT_STATUS_IS_OK(status)) {
4846 DBG_DEBUG("fsp_set_smb_fname failed: %s\n",
4847 nt_errstr(status));
4849 } else {
4850 /* TODO. JRA. */
4852 * Now we have the complete path we can work out if
4853 * this is actually within this share and adjust
4854 * newname accordingly.
4856 DBG_DEBUG("share mismatch (sharepath %s not sharepath %s) "
4857 "%s from %s -> %s\n",
4858 fsp->conn->connectpath,
4859 msg->servicepath,
4860 fsp_fnum_dbg(fsp),
4861 fsp_str_dbg(fsp),
4862 smb_fname_str_dbg(smb_fname));
4864 out:
4865 TALLOC_FREE(msg);
4869 * If a main file is opened for delete, all streams need to be checked for
4870 * !FILE_SHARE_DELETE. Do this by opening with DELETE_ACCESS.
4871 * If that works, delete them all by setting the delete on close and close.
4874 static NTSTATUS open_streams_for_delete(connection_struct *conn,
4875 const struct smb_filename *smb_fname)
4877 struct stream_struct *stream_info = NULL;
4878 files_struct **streams = NULL;
4879 int j;
4880 unsigned int i, num_streams = 0;
4881 TALLOC_CTX *frame = talloc_stackframe();
4882 const struct smb_filename *pathref = NULL;
4883 NTSTATUS status;
4885 if (smb_fname->fsp == NULL) {
4886 struct smb_filename *tmp = NULL;
4887 status = synthetic_pathref(frame,
4888 conn->cwd_fsp,
4889 smb_fname->base_name,
4890 NULL,
4891 NULL,
4892 smb_fname->twrp,
4893 smb_fname->flags,
4894 &tmp);
4895 if (!NT_STATUS_IS_OK(status)) {
4896 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
4897 || NT_STATUS_EQUAL(status,
4898 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4899 DBG_DEBUG("no streams around\n");
4900 TALLOC_FREE(frame);
4901 return NT_STATUS_OK;
4903 DBG_DEBUG("synthetic_pathref failed: %s\n",
4904 nt_errstr(status));
4905 goto fail;
4907 pathref = tmp;
4908 } else {
4909 pathref = smb_fname;
4911 status = vfs_fstreaminfo(pathref->fsp, talloc_tos(),
4912 &num_streams, &stream_info);
4914 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
4915 || NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4916 DEBUG(10, ("no streams around\n"));
4917 TALLOC_FREE(frame);
4918 return NT_STATUS_OK;
4921 if (!NT_STATUS_IS_OK(status)) {
4922 DEBUG(10, ("vfs_fstreaminfo failed: %s\n",
4923 nt_errstr(status)));
4924 goto fail;
4927 DEBUG(10, ("open_streams_for_delete found %d streams\n",
4928 num_streams));
4930 if (num_streams == 0) {
4931 TALLOC_FREE(frame);
4932 return NT_STATUS_OK;
4935 streams = talloc_array(talloc_tos(), files_struct *, num_streams);
4936 if (streams == NULL) {
4937 DEBUG(0, ("talloc failed\n"));
4938 status = NT_STATUS_NO_MEMORY;
4939 goto fail;
4942 for (i=0; i<num_streams; i++) {
4943 struct smb_filename *smb_fname_cp;
4945 if (strequal(stream_info[i].name, "::$DATA")) {
4946 streams[i] = NULL;
4947 continue;
4950 smb_fname_cp = synthetic_smb_fname(talloc_tos(),
4951 smb_fname->base_name,
4952 stream_info[i].name,
4953 NULL,
4954 smb_fname->twrp,
4955 (smb_fname->flags &
4956 ~SMB_FILENAME_POSIX_PATH));
4957 if (smb_fname_cp == NULL) {
4958 status = NT_STATUS_NO_MEMORY;
4959 goto fail;
4962 if (SMB_VFS_STAT(conn, smb_fname_cp) == -1) {
4963 DEBUG(10, ("Unable to stat stream: %s\n",
4964 smb_fname_str_dbg(smb_fname_cp)));
4967 status = openat_pathref_fsp(conn->cwd_fsp, smb_fname_cp);
4968 if (!NT_STATUS_IS_OK(status)) {
4969 DBG_DEBUG("Unable to open stream [%s]: %s\n",
4970 smb_fname_str_dbg(smb_fname_cp),
4971 nt_errstr(status));
4972 TALLOC_FREE(smb_fname_cp);
4973 break;
4976 status = SMB_VFS_CREATE_FILE(
4977 conn, /* conn */
4978 NULL, /* req */
4979 smb_fname_cp, /* fname */
4980 DELETE_ACCESS, /* access_mask */
4981 (FILE_SHARE_READ | /* share_access */
4982 FILE_SHARE_WRITE | FILE_SHARE_DELETE),
4983 FILE_OPEN, /* create_disposition*/
4984 0, /* create_options */
4985 FILE_ATTRIBUTE_NORMAL, /* file_attributes */
4986 0, /* oplock_request */
4987 NULL, /* lease */
4988 0, /* allocation_size */
4989 0, /* private_flags */
4990 NULL, /* sd */
4991 NULL, /* ea_list */
4992 &streams[i], /* result */
4993 NULL, /* pinfo */
4994 NULL, NULL); /* create context */
4996 if (!NT_STATUS_IS_OK(status)) {
4997 DEBUG(10, ("Could not open stream %s: %s\n",
4998 smb_fname_str_dbg(smb_fname_cp),
4999 nt_errstr(status)));
5001 TALLOC_FREE(smb_fname_cp);
5002 break;
5004 TALLOC_FREE(smb_fname_cp);
5008 * don't touch the variable "status" beyond this point :-)
5011 for (j = i-1 ; j >= 0; j--) {
5012 if (streams[j] == NULL) {
5013 continue;
5016 DEBUG(10, ("Closing stream # %d, %s\n", j,
5017 fsp_str_dbg(streams[j])));
5018 close_file(NULL, streams[j], NORMAL_CLOSE);
5021 fail:
5022 TALLOC_FREE(frame);
5023 return status;
5026 /*********************************************************************
5027 Create a default ACL by inheriting from the parent. If no inheritance
5028 from the parent available, don't set anything. This will leave the actual
5029 permissions the new file or directory already got from the filesystem
5030 as the NT ACL when read.
5031 *********************************************************************/
5033 static NTSTATUS inherit_new_acl(struct smb_filename *parent_dir_fname,
5034 files_struct *fsp)
5036 TALLOC_CTX *frame = talloc_stackframe();
5037 struct security_descriptor *parent_desc = NULL;
5038 NTSTATUS status = NT_STATUS_OK;
5039 struct security_descriptor *psd = NULL;
5040 const struct dom_sid *owner_sid = NULL;
5041 const struct dom_sid *group_sid = NULL;
5042 uint32_t security_info_sent = (SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL);
5043 struct security_token *token = fsp->conn->session_info->security_token;
5044 bool inherit_owner =
5045 (lp_inherit_owner(SNUM(fsp->conn)) == INHERIT_OWNER_WINDOWS_AND_UNIX);
5046 bool inheritable_components = false;
5047 bool try_builtin_administrators = false;
5048 const struct dom_sid *BA_U_sid = NULL;
5049 const struct dom_sid *BA_G_sid = NULL;
5050 bool try_system = false;
5051 const struct dom_sid *SY_U_sid = NULL;
5052 const struct dom_sid *SY_G_sid = NULL;
5053 size_t size = 0;
5054 bool ok;
5056 status = SMB_VFS_FGET_NT_ACL(parent_dir_fname->fsp,
5057 (SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL),
5058 frame,
5059 &parent_desc);
5060 if (!NT_STATUS_IS_OK(status)) {
5061 TALLOC_FREE(frame);
5062 return status;
5065 inheritable_components = sd_has_inheritable_components(parent_desc,
5066 fsp->fsp_flags.is_directory);
5068 if (!inheritable_components && !inherit_owner) {
5069 TALLOC_FREE(frame);
5070 /* Nothing to inherit and not setting owner. */
5071 return NT_STATUS_OK;
5074 /* Create an inherited descriptor from the parent. */
5076 if (DEBUGLEVEL >= 10) {
5077 DEBUG(10,("inherit_new_acl: parent acl for %s is:\n",
5078 fsp_str_dbg(fsp) ));
5079 NDR_PRINT_DEBUG(security_descriptor, parent_desc);
5082 /* Inherit from parent descriptor if "inherit owner" set. */
5083 if (inherit_owner) {
5084 owner_sid = parent_desc->owner_sid;
5085 group_sid = parent_desc->group_sid;
5088 if (owner_sid == NULL) {
5089 if (security_token_has_builtin_administrators(token)) {
5090 try_builtin_administrators = true;
5091 } else if (security_token_is_system(token)) {
5092 try_builtin_administrators = true;
5093 try_system = true;
5097 if (group_sid == NULL &&
5098 token->num_sids == PRIMARY_GROUP_SID_INDEX)
5100 if (security_token_is_system(token)) {
5101 try_builtin_administrators = true;
5102 try_system = true;
5106 if (try_builtin_administrators) {
5107 struct unixid ids = { .id = 0 };
5109 ok = sids_to_unixids(&global_sid_Builtin_Administrators, 1, &ids);
5110 if (ok) {
5111 switch (ids.type) {
5112 case ID_TYPE_BOTH:
5113 BA_U_sid = &global_sid_Builtin_Administrators;
5114 BA_G_sid = &global_sid_Builtin_Administrators;
5115 break;
5116 case ID_TYPE_UID:
5117 BA_U_sid = &global_sid_Builtin_Administrators;
5118 break;
5119 case ID_TYPE_GID:
5120 BA_G_sid = &global_sid_Builtin_Administrators;
5121 break;
5122 default:
5123 break;
5128 if (try_system) {
5129 struct unixid ids = { .id = 0 };
5131 ok = sids_to_unixids(&global_sid_System, 1, &ids);
5132 if (ok) {
5133 switch (ids.type) {
5134 case ID_TYPE_BOTH:
5135 SY_U_sid = &global_sid_System;
5136 SY_G_sid = &global_sid_System;
5137 break;
5138 case ID_TYPE_UID:
5139 SY_U_sid = &global_sid_System;
5140 break;
5141 case ID_TYPE_GID:
5142 SY_G_sid = &global_sid_System;
5143 break;
5144 default:
5145 break;
5150 if (owner_sid == NULL) {
5151 owner_sid = BA_U_sid;
5154 if (owner_sid == NULL) {
5155 owner_sid = SY_U_sid;
5158 if (group_sid == NULL) {
5159 group_sid = SY_G_sid;
5162 if (try_system && group_sid == NULL) {
5163 group_sid = BA_G_sid;
5166 if (owner_sid == NULL) {
5167 owner_sid = &token->sids[PRIMARY_USER_SID_INDEX];
5169 if (group_sid == NULL) {
5170 if (token->num_sids == PRIMARY_GROUP_SID_INDEX) {
5171 group_sid = &token->sids[PRIMARY_USER_SID_INDEX];
5172 } else {
5173 group_sid = &token->sids[PRIMARY_GROUP_SID_INDEX];
5177 status = se_create_child_secdesc(frame,
5178 &psd,
5179 &size,
5180 parent_desc,
5181 owner_sid,
5182 group_sid,
5183 fsp->fsp_flags.is_directory);
5184 if (!NT_STATUS_IS_OK(status)) {
5185 TALLOC_FREE(frame);
5186 return status;
5189 /* If inheritable_components == false,
5190 se_create_child_secdesc()
5191 creates a security descriptor with a NULL dacl
5192 entry, but with SEC_DESC_DACL_PRESENT. We need
5193 to remove that flag. */
5195 if (!inheritable_components) {
5196 security_info_sent &= ~SECINFO_DACL;
5197 psd->type &= ~SEC_DESC_DACL_PRESENT;
5200 if (DEBUGLEVEL >= 10) {
5201 DEBUG(10,("inherit_new_acl: child acl for %s is:\n",
5202 fsp_str_dbg(fsp) ));
5203 NDR_PRINT_DEBUG(security_descriptor, psd);
5206 if (inherit_owner) {
5207 /* We need to be root to force this. */
5208 become_root();
5210 status = SMB_VFS_FSET_NT_ACL(fsp,
5211 security_info_sent,
5212 psd);
5213 if (inherit_owner) {
5214 unbecome_root();
5216 TALLOC_FREE(frame);
5217 return status;
5221 * If we already have a lease, it must match the new file id. [MS-SMB2]
5222 * 3.3.5.9.8 speaks about INVALID_PARAMETER if an already used lease key is
5223 * used for a different file name.
5226 struct lease_match_state {
5227 /* Input parameters. */
5228 TALLOC_CTX *mem_ctx;
5229 const char *servicepath;
5230 const struct smb_filename *fname;
5231 bool file_existed;
5232 struct file_id id;
5233 /* Return parameters. */
5234 uint32_t num_file_ids;
5235 struct file_id *ids;
5236 NTSTATUS match_status;
5239 /*************************************************************
5240 File doesn't exist but this lease key+guid is already in use.
5242 This is only allowable in the dynamic share case where the
5243 service path must be different.
5245 There is a small race condition here in the multi-connection
5246 case where a client sends two create calls on different connections,
5247 where the file doesn't exist and one smbd creates the leases_db
5248 entry first, but this will get fixed by the multichannel cleanup
5249 when all identical client_guids get handled by a single smbd.
5250 **************************************************************/
5252 static void lease_match_parser_new_file(
5253 uint32_t num_files,
5254 const struct leases_db_file *files,
5255 struct lease_match_state *state)
5257 uint32_t i;
5259 for (i = 0; i < num_files; i++) {
5260 const struct leases_db_file *f = &files[i];
5261 if (strequal(state->servicepath, f->servicepath)) {
5262 state->match_status = NT_STATUS_INVALID_PARAMETER;
5263 return;
5267 /* Dynamic share case. Break leases on all other files. */
5268 state->match_status = leases_db_copy_file_ids(state->mem_ctx,
5269 num_files,
5270 files,
5271 &state->ids);
5272 if (!NT_STATUS_IS_OK(state->match_status)) {
5273 return;
5276 state->num_file_ids = num_files;
5277 state->match_status = NT_STATUS_OPLOCK_NOT_GRANTED;
5278 return;
5281 static void lease_match_parser(
5282 uint32_t num_files,
5283 const struct leases_db_file *files,
5284 void *private_data)
5286 struct lease_match_state *state =
5287 (struct lease_match_state *)private_data;
5288 uint32_t i;
5290 if (!state->file_existed) {
5292 * Deal with name mismatch or
5293 * possible dynamic share case separately
5294 * to make code clearer.
5296 lease_match_parser_new_file(num_files,
5297 files,
5298 state);
5299 return;
5302 /* File existed. */
5303 state->match_status = NT_STATUS_OK;
5305 for (i = 0; i < num_files; i++) {
5306 const struct leases_db_file *f = &files[i];
5308 /* Everything should be the same. */
5309 if (!file_id_equal(&state->id, &f->id)) {
5310 /* This should catch all dynamic share cases. */
5311 state->match_status = NT_STATUS_OPLOCK_NOT_GRANTED;
5312 break;
5314 if (!strequal(f->servicepath, state->servicepath)) {
5315 state->match_status = NT_STATUS_INVALID_PARAMETER;
5316 break;
5318 if (!strequal(f->base_name, state->fname->base_name)) {
5319 state->match_status = NT_STATUS_INVALID_PARAMETER;
5320 break;
5322 if (!strequal(f->stream_name, state->fname->stream_name)) {
5323 state->match_status = NT_STATUS_INVALID_PARAMETER;
5324 break;
5328 if (NT_STATUS_IS_OK(state->match_status)) {
5330 * Common case - just opening another handle on a
5331 * file on a non-dynamic share.
5333 return;
5336 if (NT_STATUS_EQUAL(state->match_status, NT_STATUS_INVALID_PARAMETER)) {
5337 /* Mismatched path. Error back to client. */
5338 return;
5342 * File id mismatch. Dynamic share case NT_STATUS_OPLOCK_NOT_GRANTED.
5343 * Don't allow leases.
5346 state->match_status = leases_db_copy_file_ids(state->mem_ctx,
5347 num_files,
5348 files,
5349 &state->ids);
5350 if (!NT_STATUS_IS_OK(state->match_status)) {
5351 return;
5354 state->num_file_ids = num_files;
5355 state->match_status = NT_STATUS_OPLOCK_NOT_GRANTED;
5356 return;
5359 struct lease_match_break_state {
5360 struct messaging_context *msg_ctx;
5361 const struct smb2_lease_key *lease_key;
5362 struct file_id id;
5364 bool found_lease;
5365 uint16_t version;
5366 uint16_t epoch;
5369 static bool lease_match_break_fn(
5370 struct share_mode_entry *e,
5371 void *private_data)
5373 struct lease_match_break_state *state = private_data;
5374 bool stale, equal;
5375 uint32_t e_lease_type;
5376 NTSTATUS status;
5378 stale = share_entry_stale_pid(e);
5379 if (stale) {
5380 return false;
5383 equal = smb2_lease_key_equal(&e->lease_key, state->lease_key);
5384 if (!equal) {
5385 return false;
5388 status = leases_db_get(
5389 &e->client_guid,
5390 &e->lease_key,
5391 &state->id,
5392 NULL, /* current_state */
5393 NULL, /* breaking */
5394 NULL, /* breaking_to_requested */
5395 NULL, /* breaking_to_required */
5396 &state->version, /* lease_version */
5397 &state->epoch); /* epoch */
5398 if (NT_STATUS_IS_OK(status)) {
5399 state->found_lease = true;
5400 } else {
5401 DBG_WARNING("Could not find version/epoch: %s\n",
5402 nt_errstr(status));
5405 e_lease_type = get_lease_type(e, state->id);
5406 if (e_lease_type == SMB2_LEASE_NONE) {
5407 return false;
5409 send_break_message(state->msg_ctx, &state->id, e, SMB2_LEASE_NONE);
5412 * Windows 7 and 8 lease clients are broken in that they will
5413 * not respond to lease break requests whilst waiting for an
5414 * outstanding open request on that lease handle on the same
5415 * TCP connection, due to holding an internal inode lock.
5417 * This means we can't reschedule ourselves here, but must
5418 * return from the create.
5420 * Work around:
5422 * Send the breaks and then return SMB2_LEASE_NONE in the
5423 * lease handle to cause them to acknowledge the lease
5424 * break. Consultation with Microsoft engineering confirmed
5425 * this approach is safe.
5428 return false;
5431 static NTSTATUS lease_match(connection_struct *conn,
5432 struct smb_request *req,
5433 const struct smb2_lease_key *lease_key,
5434 const char *servicepath,
5435 const struct smb_filename *fname,
5436 uint16_t *p_version,
5437 uint16_t *p_epoch)
5439 struct smbd_server_connection *sconn = req->sconn;
5440 TALLOC_CTX *tos = talloc_tos();
5441 struct lease_match_state state = {
5442 .mem_ctx = tos,
5443 .servicepath = servicepath,
5444 .fname = fname,
5445 .match_status = NT_STATUS_OK
5447 uint32_t i;
5448 NTSTATUS status;
5450 state.file_existed = VALID_STAT(fname->st);
5451 if (state.file_existed) {
5452 state.id = vfs_file_id_from_sbuf(conn, &fname->st);
5455 status = leases_db_parse(&sconn->client->global->client_guid,
5456 lease_key, lease_match_parser, &state);
5457 if (!NT_STATUS_IS_OK(status)) {
5459 * Not found or error means okay: We can make the lease pass
5461 return NT_STATUS_OK;
5463 if (!NT_STATUS_EQUAL(state.match_status, NT_STATUS_OPLOCK_NOT_GRANTED)) {
5465 * Anything but NT_STATUS_OPLOCK_NOT_GRANTED, let the caller
5466 * deal with it.
5468 return state.match_status;
5471 /* We have to break all existing leases. */
5472 for (i = 0; i < state.num_file_ids; i++) {
5473 struct lease_match_break_state break_state = {
5474 .msg_ctx = conn->sconn->msg_ctx,
5475 .lease_key = lease_key,
5477 struct share_mode_lock *lck;
5478 bool ok;
5480 if (file_id_equal(&state.ids[i], &state.id)) {
5481 /* Don't need to break our own file. */
5482 continue;
5485 break_state.id = state.ids[i];
5487 lck = get_existing_share_mode_lock(
5488 talloc_tos(), break_state.id);
5489 if (lck == NULL) {
5490 /* Race condition - file already closed. */
5491 continue;
5494 ok = share_mode_forall_leases(
5495 lck, lease_match_break_fn, &break_state);
5496 if (!ok) {
5497 DBG_DEBUG("share_mode_forall_leases failed\n");
5498 continue;
5501 TALLOC_FREE(lck);
5503 if (break_state.found_lease) {
5504 *p_version = break_state.version;
5505 *p_epoch = break_state.epoch;
5509 * Ensure we don't grant anything more so we
5510 * never upgrade.
5512 return NT_STATUS_OPLOCK_NOT_GRANTED;
5516 * Wrapper around open_file_ntcreate and open_directory
5519 static NTSTATUS create_file_unixpath(connection_struct *conn,
5520 struct smb_request *req,
5521 struct smb_filename *smb_fname,
5522 uint32_t access_mask,
5523 uint32_t share_access,
5524 uint32_t create_disposition,
5525 uint32_t create_options,
5526 uint32_t file_attributes,
5527 uint32_t oplock_request,
5528 const struct smb2_lease *lease,
5529 uint64_t allocation_size,
5530 uint32_t private_flags,
5531 struct security_descriptor *sd,
5532 struct ea_list *ea_list,
5534 files_struct **result,
5535 int *pinfo)
5537 struct smb2_lease none_lease;
5538 int info = FILE_WAS_OPENED;
5539 files_struct *base_fsp = NULL;
5540 files_struct *fsp = NULL;
5541 NTSTATUS status;
5542 int ret;
5543 struct smb_filename *parent_dir_fname = NULL;
5544 struct smb_filename *smb_fname_atname = NULL;
5546 DBG_DEBUG("create_file_unixpath: access_mask = 0x%x "
5547 "file_attributes = 0x%x, share_access = 0x%x, "
5548 "create_disposition = 0x%x create_options = 0x%x "
5549 "oplock_request = 0x%x private_flags = 0x%x "
5550 "ea_list = %p, sd = %p, "
5551 "fname = %s\n",
5552 (unsigned int)access_mask,
5553 (unsigned int)file_attributes,
5554 (unsigned int)share_access,
5555 (unsigned int)create_disposition,
5556 (unsigned int)create_options,
5557 (unsigned int)oplock_request,
5558 (unsigned int)private_flags,
5559 ea_list, sd, smb_fname_str_dbg(smb_fname));
5561 if (create_options & FILE_OPEN_BY_FILE_ID) {
5562 status = NT_STATUS_NOT_SUPPORTED;
5563 goto fail;
5566 if (create_options & NTCREATEX_OPTIONS_INVALID_PARAM_MASK) {
5567 status = NT_STATUS_INVALID_PARAMETER;
5568 goto fail;
5571 if (req == NULL) {
5572 oplock_request |= INTERNAL_OPEN_ONLY;
5575 if (lease != NULL) {
5576 uint16_t epoch = lease->lease_epoch;
5577 uint16_t version = lease->lease_version;
5579 if (req == NULL) {
5580 DBG_WARNING("Got lease on internal open\n");
5581 status = NT_STATUS_INTERNAL_ERROR;
5582 goto fail;
5585 status = lease_match(conn,
5586 req,
5587 &lease->lease_key,
5588 conn->connectpath,
5589 smb_fname,
5590 &version,
5591 &epoch);
5592 if (NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) {
5593 /* Dynamic share file. No leases and update epoch... */
5594 none_lease = *lease;
5595 none_lease.lease_state = SMB2_LEASE_NONE;
5596 none_lease.lease_epoch = epoch;
5597 none_lease.lease_version = version;
5598 lease = &none_lease;
5599 } else if (!NT_STATUS_IS_OK(status)) {
5600 goto fail;
5604 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
5605 && (access_mask & DELETE_ACCESS)
5606 && !is_ntfs_stream_smb_fname(smb_fname)) {
5608 * We can't open a file with DELETE access if any of the
5609 * streams is open without FILE_SHARE_DELETE
5611 status = open_streams_for_delete(conn, smb_fname);
5613 if (!NT_STATUS_IS_OK(status)) {
5614 goto fail;
5618 if (access_mask & SEC_FLAG_SYSTEM_SECURITY) {
5619 bool ok;
5621 ok = security_token_has_privilege(get_current_nttok(conn),
5622 SEC_PRIV_SECURITY);
5623 if (!ok) {
5624 DBG_DEBUG("open on %s failed - "
5625 "SEC_FLAG_SYSTEM_SECURITY denied.\n",
5626 smb_fname_str_dbg(smb_fname));
5627 status = NT_STATUS_PRIVILEGE_NOT_HELD;
5628 goto fail;
5631 if (conn->sconn->using_smb2 &&
5632 (access_mask == SEC_FLAG_SYSTEM_SECURITY))
5635 * No other bits set. Windows SMB2 refuses this.
5636 * See smbtorture3 SMB2-SACL test.
5638 * Note this is an SMB2-only behavior,
5639 * smbtorture3 SMB1-SYSTEM-SECURITY already tests
5640 * that SMB1 allows this.
5642 status = NT_STATUS_ACCESS_DENIED;
5643 goto fail;
5648 * Files or directories can't be opened DELETE_ON_CLOSE without
5649 * delete access.
5650 * BUG: https://bugzilla.samba.org/show_bug.cgi?id=13358
5652 if (create_options & FILE_DELETE_ON_CLOSE) {
5653 if ((access_mask & DELETE_ACCESS) == 0) {
5654 status = NT_STATUS_INVALID_PARAMETER;
5655 goto fail;
5659 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
5660 && is_ntfs_stream_smb_fname(smb_fname))
5662 uint32_t base_create_disposition;
5663 struct smb_filename *smb_fname_base = NULL;
5664 uint32_t base_privflags;
5666 if (create_options & FILE_DIRECTORY_FILE) {
5667 status = NT_STATUS_NOT_A_DIRECTORY;
5668 goto fail;
5671 switch (create_disposition) {
5672 case FILE_OPEN:
5673 base_create_disposition = FILE_OPEN;
5674 break;
5675 default:
5676 base_create_disposition = FILE_OPEN_IF;
5677 break;
5680 /* Create an smb_filename with stream_name == NULL. */
5681 smb_fname_base = synthetic_smb_fname(talloc_tos(),
5682 smb_fname->base_name,
5683 NULL,
5684 &smb_fname->st,
5685 smb_fname->twrp,
5686 smb_fname->flags);
5687 if (smb_fname_base == NULL) {
5688 status = NT_STATUS_NO_MEMORY;
5689 goto fail;
5693 * We may be creating the basefile as part of creating the
5694 * stream, so it's legal if the basefile doesn't exist at this
5695 * point, the create_file_unixpath() below will create it. But
5696 * if the basefile exists we want a handle so we can fstat() it.
5699 ret = vfs_stat(conn, smb_fname_base);
5700 if (ret == -1 && errno != ENOENT) {
5701 status = map_nt_error_from_unix(errno);
5702 TALLOC_FREE(smb_fname_base);
5703 goto fail;
5705 if (ret == 0) {
5706 status = openat_pathref_fsp(conn->cwd_fsp,
5707 smb_fname_base);
5708 if (!NT_STATUS_IS_OK(status)) {
5709 DBG_ERR("open_smb_fname_fsp [%s] failed: %s\n",
5710 smb_fname_str_dbg(smb_fname_base),
5711 nt_errstr(status));
5712 TALLOC_FREE(smb_fname_base);
5713 goto fail;
5717 * https://bugzilla.samba.org/show_bug.cgi?id=10229
5718 * We need to check if the requested access mask
5719 * could be used to open the underlying file (if
5720 * it existed), as we're passing in zero for the
5721 * access mask to the base filename.
5723 status = check_base_file_access(smb_fname_base->fsp,
5724 access_mask);
5726 if (!NT_STATUS_IS_OK(status)) {
5727 DEBUG(10, ("Permission check "
5728 "for base %s failed: "
5729 "%s\n", smb_fname->base_name,
5730 nt_errstr(status)));
5731 TALLOC_FREE(smb_fname_base);
5732 goto fail;
5736 base_privflags = NTCREATEX_FLAG_STREAM_BASEOPEN;
5738 /* Open the base file. */
5739 status = create_file_unixpath(conn,
5740 NULL,
5741 smb_fname_base,
5743 FILE_SHARE_READ
5744 | FILE_SHARE_WRITE
5745 | FILE_SHARE_DELETE,
5746 base_create_disposition,
5750 NULL,
5752 base_privflags,
5753 NULL,
5754 NULL,
5755 &base_fsp,
5756 NULL);
5757 TALLOC_FREE(smb_fname_base);
5759 if (!NT_STATUS_IS_OK(status)) {
5760 DEBUG(10, ("create_file_unixpath for base %s failed: "
5761 "%s\n", smb_fname->base_name,
5762 nt_errstr(status)));
5763 goto fail;
5768 * Now either reuse smb_fname->fsp or allocate a new fsp if
5769 * smb_fname->fsp is NULL. The latter will be the case when processing a
5770 * request to create a file that doesn't exist.
5772 if (smb_fname->fsp != NULL) {
5773 bool need_fsp_unlink = true;
5776 * This is really subtle. If someone passes in an smb_fname
5777 * where smb_fname actually is taken from fsp->fsp_name, then
5778 * the lifetime of these objects is meant to be the same.
5780 * This is commonly the case from an SMB1 path-based call,
5781 * (call_trans2qfilepathinfo) where we use the pathref fsp
5782 * (smb_fname->fsp) as the handle. In this case we must not
5783 * unlink smb_fname->fsp from it's owner.
5785 * The asserts below:
5787 * SMB_ASSERT(fsp->fsp_name->fsp != NULL);
5788 * SMB_ASSERT(fsp->fsp_name->fsp == fsp);
5790 * ensure the required invarients are met.
5792 if (smb_fname->fsp->fsp_name == smb_fname) {
5793 need_fsp_unlink = false;
5796 fsp = smb_fname->fsp;
5798 if (need_fsp_unlink) {
5800 * Unlink the fsp from the smb_fname so the fsp is not
5801 * autoclosed by the smb_fname pathref fsp talloc
5802 * destructor.
5804 smb_fname_fsp_unlink(smb_fname);
5807 status = fsp_bind_smb(fsp, req);
5808 if (!NT_STATUS_IS_OK(status)) {
5809 goto fail;
5812 if (fsp->base_fsp != NULL) {
5813 struct files_struct *tmp_base_fsp = fsp->base_fsp;
5815 fsp_set_base_fsp(fsp, NULL);
5817 fd_close(tmp_base_fsp);
5818 file_free(NULL, tmp_base_fsp);
5822 if (fsp == NULL) {
5823 /* Creating file */
5824 status = file_new(req, conn, &fsp);
5825 if(!NT_STATUS_IS_OK(status)) {
5826 goto fail;
5829 status = fsp_set_smb_fname(fsp, smb_fname);
5830 if (!NT_STATUS_IS_OK(status)) {
5831 goto fail;
5835 SMB_ASSERT(fsp->fsp_name->fsp != NULL);
5836 SMB_ASSERT(fsp->fsp_name->fsp == fsp);
5838 if (base_fsp) {
5840 * We're opening the stream element of a
5841 * base_fsp we already opened. Set up the
5842 * base_fsp pointer.
5844 fsp_set_base_fsp(fsp, base_fsp);
5848 * Get a pathref on the parent. We can re-use this
5849 * for multiple calls to check parent ACLs etc. to
5850 * avoid pathname calls.
5852 status = parent_pathref(talloc_tos(),
5853 conn->cwd_fsp,
5854 smb_fname,
5855 &parent_dir_fname,
5856 &smb_fname_atname);
5857 if (!NT_STATUS_IS_OK(status)) {
5858 goto fail;
5862 * If it's a request for a directory open, deal with it separately.
5865 if (create_options & FILE_DIRECTORY_FILE) {
5867 if (create_options & FILE_NON_DIRECTORY_FILE) {
5868 status = NT_STATUS_INVALID_PARAMETER;
5869 goto fail;
5872 /* Can't open a temp directory. IFS kit test. */
5873 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
5874 (file_attributes & FILE_ATTRIBUTE_TEMPORARY)) {
5875 status = NT_STATUS_INVALID_PARAMETER;
5876 goto fail;
5880 * We will get a create directory here if the Win32
5881 * app specified a security descriptor in the
5882 * CreateDirectory() call.
5885 oplock_request = 0;
5886 status = open_directory(conn,
5887 req,
5888 access_mask,
5889 share_access,
5890 create_disposition,
5891 create_options,
5892 file_attributes,
5893 parent_dir_fname,
5894 smb_fname_atname,
5895 &info,
5896 fsp);
5897 } else {
5900 * Ordinary file case.
5903 if (allocation_size) {
5904 fsp->initial_allocation_size = smb_roundup(fsp->conn,
5905 allocation_size);
5908 status = open_file_ntcreate(conn,
5909 req,
5910 access_mask,
5911 share_access,
5912 create_disposition,
5913 create_options,
5914 file_attributes,
5915 oplock_request,
5916 lease,
5917 private_flags,
5918 parent_dir_fname,
5919 smb_fname_atname,
5920 &info,
5921 fsp);
5922 if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
5924 /* A stream open never opens a directory */
5926 if (base_fsp) {
5927 status = NT_STATUS_FILE_IS_A_DIRECTORY;
5928 goto fail;
5932 * Fail the open if it was explicitly a non-directory
5933 * file.
5936 if (create_options & FILE_NON_DIRECTORY_FILE) {
5937 status = NT_STATUS_FILE_IS_A_DIRECTORY;
5938 goto fail;
5941 oplock_request = 0;
5942 status = open_directory(conn,
5943 req,
5944 access_mask,
5945 share_access,
5946 create_disposition,
5947 create_options,
5948 file_attributes,
5949 parent_dir_fname,
5950 smb_fname_atname,
5951 &info,
5952 fsp);
5956 if (!NT_STATUS_IS_OK(status)) {
5957 goto fail;
5960 fsp->fsp_flags.is_fsa = true;
5962 if ((ea_list != NULL) &&
5963 ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN))) {
5964 status = set_ea(conn, fsp, ea_list);
5965 if (!NT_STATUS_IS_OK(status)) {
5966 goto fail;
5970 if (!fsp->fsp_flags.is_directory &&
5971 S_ISDIR(fsp->fsp_name->st.st_ex_mode))
5973 status = NT_STATUS_ACCESS_DENIED;
5974 goto fail;
5977 /* Save the requested allocation size. */
5978 if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
5979 if ((allocation_size > (uint64_t)fsp->fsp_name->st.st_ex_size)
5980 && !(fsp->fsp_flags.is_directory))
5982 fsp->initial_allocation_size = smb_roundup(
5983 fsp->conn, allocation_size);
5984 if (vfs_allocate_file_space(
5985 fsp, fsp->initial_allocation_size) == -1) {
5986 status = NT_STATUS_DISK_FULL;
5987 goto fail;
5989 } else {
5990 fsp->initial_allocation_size = smb_roundup(
5991 fsp->conn, (uint64_t)fsp->fsp_name->st.st_ex_size);
5993 } else {
5994 fsp->initial_allocation_size = 0;
5997 if ((info == FILE_WAS_CREATED) && lp_nt_acl_support(SNUM(conn)) &&
5998 fsp->base_fsp == NULL) {
5999 if (sd != NULL) {
6001 * According to the MS documentation, the only time the security
6002 * descriptor is applied to the opened file is iff we *created* the
6003 * file; an existing file stays the same.
6005 * Also, it seems (from observation) that you can open the file with
6006 * any access mask but you can still write the sd. We need to override
6007 * the granted access before we call set_sd
6008 * Patch for bug #2242 from Tom Lackemann <cessnatomny@yahoo.com>.
6011 uint32_t sec_info_sent;
6012 uint32_t saved_access_mask = fsp->access_mask;
6014 sec_info_sent = get_sec_info(sd);
6016 fsp->access_mask = FILE_GENERIC_ALL;
6018 if (sec_info_sent & (SECINFO_OWNER|
6019 SECINFO_GROUP|
6020 SECINFO_DACL|
6021 SECINFO_SACL)) {
6022 status = set_sd(fsp, sd, sec_info_sent);
6025 fsp->access_mask = saved_access_mask;
6027 if (!NT_STATUS_IS_OK(status)) {
6028 goto fail;
6030 } else if (lp_inherit_acls(SNUM(conn))) {
6031 /* Inherit from parent. Errors here are not fatal. */
6032 status = inherit_new_acl(parent_dir_fname, fsp);
6033 if (!NT_STATUS_IS_OK(status)) {
6034 DEBUG(10,("inherit_new_acl: failed for %s with %s\n",
6035 fsp_str_dbg(fsp),
6036 nt_errstr(status) ));
6041 if ((conn->fs_capabilities & FILE_FILE_COMPRESSION)
6042 && (create_options & FILE_NO_COMPRESSION)
6043 && (info == FILE_WAS_CREATED)) {
6044 status = SMB_VFS_SET_COMPRESSION(conn, fsp, fsp,
6045 COMPRESSION_FORMAT_NONE);
6046 if (!NT_STATUS_IS_OK(status)) {
6047 DEBUG(1, ("failed to disable compression: %s\n",
6048 nt_errstr(status)));
6052 DEBUG(10, ("create_file_unixpath: info=%d\n", info));
6054 *result = fsp;
6055 if (pinfo != NULL) {
6056 *pinfo = info;
6059 smb_fname->st = fsp->fsp_name->st;
6061 TALLOC_FREE(parent_dir_fname);
6063 return NT_STATUS_OK;
6065 fail:
6066 DEBUG(10, ("create_file_unixpath: %s\n", nt_errstr(status)));
6068 if (fsp != NULL) {
6070 * The close_file below will close
6071 * fsp->base_fsp.
6073 base_fsp = NULL;
6074 close_file(req, fsp, ERROR_CLOSE);
6075 fsp = NULL;
6077 if (base_fsp != NULL) {
6078 close_file(req, base_fsp, ERROR_CLOSE);
6079 base_fsp = NULL;
6082 TALLOC_FREE(parent_dir_fname);
6084 return status;
6087 NTSTATUS create_file_default(connection_struct *conn,
6088 struct smb_request *req,
6089 struct smb_filename *smb_fname,
6090 uint32_t access_mask,
6091 uint32_t share_access,
6092 uint32_t create_disposition,
6093 uint32_t create_options,
6094 uint32_t file_attributes,
6095 uint32_t oplock_request,
6096 const struct smb2_lease *lease,
6097 uint64_t allocation_size,
6098 uint32_t private_flags,
6099 struct security_descriptor *sd,
6100 struct ea_list *ea_list,
6101 files_struct **result,
6102 int *pinfo,
6103 const struct smb2_create_blobs *in_context_blobs,
6104 struct smb2_create_blobs *out_context_blobs)
6106 int info = FILE_WAS_OPENED;
6107 files_struct *fsp = NULL;
6108 NTSTATUS status;
6109 bool stream_name = false;
6110 struct smb2_create_blob *posx = NULL;
6112 DBG_DEBUG("create_file: access_mask = 0x%x "
6113 "file_attributes = 0x%x, share_access = 0x%x, "
6114 "create_disposition = 0x%x create_options = 0x%x "
6115 "oplock_request = 0x%x "
6116 "private_flags = 0x%x "
6117 "ea_list = %p, sd = %p, "
6118 "fname = %s\n",
6119 (unsigned int)access_mask,
6120 (unsigned int)file_attributes,
6121 (unsigned int)share_access,
6122 (unsigned int)create_disposition,
6123 (unsigned int)create_options,
6124 (unsigned int)oplock_request,
6125 (unsigned int)private_flags,
6126 ea_list,
6128 smb_fname_str_dbg(smb_fname));
6130 if (req != NULL) {
6132 * Remember the absolute time of the original request
6133 * with this mid. We'll use it later to see if this
6134 * has timed out.
6136 get_deferred_open_message_state(req, &req->request_time, NULL);
6140 * Check to see if this is a mac fork of some kind.
6143 stream_name = is_ntfs_stream_smb_fname(smb_fname);
6144 if (stream_name) {
6145 enum FAKE_FILE_TYPE fake_file_type;
6147 fake_file_type = is_fake_file(smb_fname);
6149 if (req != NULL && fake_file_type != FAKE_FILE_TYPE_NONE) {
6152 * Here we go! support for changing the disk quotas
6153 * --metze
6155 * We need to fake up to open this MAGIC QUOTA file
6156 * and return a valid FID.
6158 * w2k close this file directly after openening xp
6159 * also tries a QUERY_FILE_INFO on the file and then
6160 * close it
6162 status = open_fake_file(req, conn, req->vuid,
6163 fake_file_type, smb_fname,
6164 access_mask, &fsp);
6165 if (!NT_STATUS_IS_OK(status)) {
6166 goto fail;
6169 ZERO_STRUCT(smb_fname->st);
6170 goto done;
6173 if (!(conn->fs_capabilities & FILE_NAMED_STREAMS)) {
6174 status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
6175 goto fail;
6179 if (is_ntfs_default_stream_smb_fname(smb_fname)) {
6180 int ret;
6181 smb_fname->stream_name = NULL;
6182 /* We have to handle this error here. */
6183 if (create_options & FILE_DIRECTORY_FILE) {
6184 status = NT_STATUS_NOT_A_DIRECTORY;
6185 goto fail;
6187 ret = vfs_stat(conn, smb_fname);
6188 if (ret == 0 && VALID_STAT_OF_DIR(smb_fname->st)) {
6189 status = NT_STATUS_FILE_IS_A_DIRECTORY;
6190 goto fail;
6194 posx = smb2_create_blob_find(
6195 in_context_blobs, SMB2_CREATE_TAG_POSIX);
6196 if (posx != NULL) {
6197 uint32_t wire_mode_bits = 0;
6198 mode_t mode_bits = 0;
6199 SMB_STRUCT_STAT sbuf = { 0 };
6200 enum perm_type ptype =
6201 (create_options & FILE_DIRECTORY_FILE) ?
6202 PERM_NEW_DIR : PERM_NEW_FILE;
6204 if (posx->data.length != 4) {
6205 status = NT_STATUS_INVALID_PARAMETER;
6206 goto fail;
6209 wire_mode_bits = IVAL(posx->data.data, 0);
6210 status = unix_perms_from_wire(
6211 conn, &sbuf, wire_mode_bits, ptype, &mode_bits);
6212 if (!NT_STATUS_IS_OK(status)) {
6213 goto fail;
6216 * Remove type info from mode, leaving only the
6217 * permissions and setuid/gid bits.
6219 mode_bits &= ~S_IFMT;
6221 file_attributes = (FILE_FLAG_POSIX_SEMANTICS | mode_bits);
6224 status = create_file_unixpath(conn,
6225 req,
6226 smb_fname,
6227 access_mask,
6228 share_access,
6229 create_disposition,
6230 create_options,
6231 file_attributes,
6232 oplock_request,
6233 lease,
6234 allocation_size,
6235 private_flags,
6237 ea_list,
6238 &fsp,
6239 &info);
6240 if (!NT_STATUS_IS_OK(status)) {
6241 goto fail;
6244 done:
6245 DEBUG(10, ("create_file: info=%d\n", info));
6247 *result = fsp;
6248 if (pinfo != NULL) {
6249 *pinfo = info;
6251 return NT_STATUS_OK;
6253 fail:
6254 DEBUG(10, ("create_file: %s\n", nt_errstr(status)));
6256 if (fsp != NULL) {
6257 close_file(req, fsp, ERROR_CLOSE);
6258 fsp = NULL;
6260 return status;