smbd: Fix a typo
[Samba.git] / source3 / smbd / open.c
blob68e5eb957f2923ac87a30bb6fcc357a11ce7c512
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 "system/filesys.h"
25 #include "lib/util/server_id.h"
26 #include "printing.h"
27 #include "locking/share_mode_lock.h"
28 #include "smbd/smbd.h"
29 #include "smbd/globals.h"
30 #include "fake_file.h"
31 #include "../libcli/security/security.h"
32 #include "../librpc/gen_ndr/ndr_security.h"
33 #include "../librpc/gen_ndr/ndr_open_files.h"
34 #include "../librpc/gen_ndr/idmap.h"
35 #include "../librpc/gen_ndr/ioctl.h"
36 #include "passdb/lookup_sid.h"
37 #include "auth.h"
38 #include "serverid.h"
39 #include "messages.h"
40 #include "source3/lib/dbwrap/dbwrap_watch.h"
41 #include "locking/leases_db.h"
42 #include "librpc/gen_ndr/ndr_leases_db.h"
43 #include "lib/util/time_basic.h"
44 #include "source3/smbd/dir.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_fname(
100 struct connection_struct *conn,
101 const struct smb_filename *smb_fname,
102 bool use_privs,
103 uint32_t access_mask,
104 uint32_t do_not_check_mask)
106 uint32_t rejected_share_access;
107 uint32_t effective_access;
109 rejected_share_access = access_mask & ~(conn->share_access);
111 if (rejected_share_access) {
112 DBG_DEBUG("rejected share access 0x%"PRIx32" on "
113 "%s (0x%"PRIx32")\n",
114 access_mask,
115 smb_fname_str_dbg(smb_fname),
116 rejected_share_access);
117 return NT_STATUS_ACCESS_DENIED;
120 effective_access = access_mask & ~do_not_check_mask;
121 if (effective_access == 0) {
122 DBG_DEBUG("do_not_check_mask override on %s. Granting 0x%x for free.\n",
123 smb_fname_str_dbg(smb_fname),
124 (unsigned int)access_mask);
125 return NT_STATUS_OK;
128 if (!use_privs && get_current_uid(conn) == (uid_t)0) {
129 /* I'm sorry sir, I didn't know you were root... */
130 DBG_DEBUG("root override on %s. Granting 0x%x\n",
131 smb_fname_str_dbg(smb_fname),
132 (unsigned int)access_mask);
133 return NT_STATUS_OK;
136 if ((access_mask & DELETE_ACCESS) &&
137 !lp_acl_check_permissions(SNUM(conn)))
139 DBG_DEBUG("Not checking ACL on DELETE_ACCESS on file %s. "
140 "Granting 0x%"PRIx32"\n",
141 smb_fname_str_dbg(smb_fname),
142 access_mask);
143 return NT_STATUS_OK;
146 if (access_mask == DELETE_ACCESS &&
147 VALID_STAT(smb_fname->st) &&
148 S_ISLNK(smb_fname->st.st_ex_mode))
150 /* We can always delete a symlink. */
151 DBG_DEBUG("Not checking ACL on DELETE_ACCESS on symlink %s.\n",
152 smb_fname_str_dbg(smb_fname));
153 return NT_STATUS_OK;
156 return NT_STATUS_MORE_PROCESSING_REQUIRED;
159 static NTSTATUS smbd_check_access_rights_sd(
160 struct connection_struct *conn,
161 struct files_struct *dirfsp,
162 const struct smb_filename *smb_fname,
163 struct security_descriptor *sd,
164 bool use_privs,
165 uint32_t access_mask,
166 uint32_t do_not_check_mask)
168 uint32_t rejected_mask = access_mask;
169 NTSTATUS status;
171 if (sd == NULL) {
172 goto access_denied;
175 status = se_file_access_check(sd,
176 get_current_nttok(conn),
177 use_privs,
178 (access_mask & ~do_not_check_mask),
179 &rejected_mask);
181 DBG_DEBUG("File [%s] requesting [0x%"PRIx32"] "
182 "returning [0x%"PRIx32"] (%s)\n",
183 smb_fname_str_dbg(smb_fname),
184 access_mask,
185 rejected_mask,
186 nt_errstr(status));
188 if (!NT_STATUS_IS_OK(status)) {
189 if (DEBUGLEVEL >= 10) {
190 DBG_DEBUG("acl for %s is:\n",
191 smb_fname_str_dbg(smb_fname));
192 NDR_PRINT_DEBUG(security_descriptor, sd);
196 TALLOC_FREE(sd);
198 if (NT_STATUS_IS_OK(status) ||
199 !NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED))
201 return status;
204 /* Here we know status == NT_STATUS_ACCESS_DENIED. */
206 access_denied:
208 if ((access_mask & FILE_WRITE_ATTRIBUTES) &&
209 (rejected_mask & FILE_WRITE_ATTRIBUTES) &&
210 !lp_store_dos_attributes(SNUM(conn)) &&
211 (lp_map_readonly(SNUM(conn)) ||
212 lp_map_archive(SNUM(conn)) ||
213 lp_map_hidden(SNUM(conn)) ||
214 lp_map_system(SNUM(conn))))
216 rejected_mask &= ~FILE_WRITE_ATTRIBUTES;
218 DBG_DEBUG("overrode FILE_WRITE_ATTRIBUTES on file %s\n",
219 smb_fname_str_dbg(smb_fname));
222 if (parent_override_delete(conn,
223 dirfsp,
224 smb_fname,
225 access_mask,
226 rejected_mask))
229 * Were we trying to do an open for delete and didn't get DELETE
230 * access. Check if the directory allows DELETE_CHILD.
231 * See here:
232 * http://blogs.msdn.com/oldnewthing/archive/2004/06/04/148426.aspx
233 * for details.
236 rejected_mask &= ~DELETE_ACCESS;
238 DBG_DEBUG("Overrode DELETE_ACCESS on file %s\n",
239 smb_fname_str_dbg(smb_fname));
242 if (rejected_mask != 0) {
243 return NT_STATUS_ACCESS_DENIED;
245 return NT_STATUS_OK;
248 NTSTATUS smbd_check_access_rights_fsp(struct files_struct *dirfsp,
249 struct files_struct *fsp,
250 bool use_privs,
251 uint32_t access_mask)
253 struct security_descriptor *sd = NULL;
254 uint32_t do_not_check_mask = 0;
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 * version 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;
281 * If we can access the path to this file, by
282 * default we have FILE_READ_ATTRIBUTES from the
283 * containing directory. See the section:
284 * "Algorithm to Check Access to an Existing File"
285 * in MS-FSA.pdf.
287 * se_file_access_check() also takes care of
288 * owner WRITE_DAC and READ_CONTROL.
290 do_not_check_mask = FILE_READ_ATTRIBUTES;
293 * Samba 3.6 and earlier granted execute access even
294 * if the ACL did not contain execute rights.
295 * Samba 4.0 is more correct and checks it.
296 * The compatibility mode allows one to skip this check
297 * to smoothen upgrades.
299 if (lp_acl_allow_execute_always(SNUM(fsp->conn))) {
300 do_not_check_mask |= FILE_EXECUTE;
303 status = smbd_check_access_rights_fname(fsp->conn,
304 fsp->fsp_name,
305 use_privs,
306 access_mask,
307 do_not_check_mask);
308 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
309 return status;
312 status = SMB_VFS_FGET_NT_ACL(metadata_fsp(fsp),
313 (SECINFO_OWNER |
314 SECINFO_GROUP |
315 SECINFO_DACL),
316 talloc_tos(),
317 &sd);
318 if (!NT_STATUS_IS_OK(status)) {
319 DBG_DEBUG("Could not get acl on %s: %s\n",
320 fsp_str_dbg(fsp),
321 nt_errstr(status));
322 return status;
325 return smbd_check_access_rights_sd(fsp->conn,
326 dirfsp,
327 fsp->fsp_name,
329 use_privs,
330 access_mask,
331 do_not_check_mask);
335 * Given an fsp that represents a parent directory,
336 * check if the requested access can be granted.
338 NTSTATUS check_parent_access_fsp(struct files_struct *fsp,
339 uint32_t access_mask)
341 NTSTATUS status;
342 struct security_descriptor *parent_sd = NULL;
343 uint32_t access_granted = 0;
344 struct share_mode_lock *lck = NULL;
345 uint32_t name_hash;
346 bool delete_on_close_set;
347 TALLOC_CTX *frame = talloc_stackframe();
349 if (get_current_uid(fsp->conn) == (uid_t)0) {
350 /* I'm sorry sir, I didn't know you were root... */
351 DBG_DEBUG("root override on %s. Granting 0x%x\n",
352 fsp_str_dbg(fsp),
353 (unsigned int)access_mask);
354 status = NT_STATUS_OK;
355 goto out;
358 status = SMB_VFS_FGET_NT_ACL(fsp,
359 SECINFO_DACL,
360 frame,
361 &parent_sd);
363 if (!NT_STATUS_IS_OK(status)) {
364 DBG_INFO("SMB_VFS_FGET_NT_ACL failed for "
365 "%s with error %s\n",
366 fsp_str_dbg(fsp),
367 nt_errstr(status));
368 goto out;
372 * If we can access the path to this file, by
373 * default we have FILE_READ_ATTRIBUTES from the
374 * containing directory. See the section:
375 * "Algorithm to Check Access to an Existing File"
376 * in MS-FSA.pdf.
378 * se_file_access_check() also takes care of
379 * owner WRITE_DAC and READ_CONTROL.
381 status = se_file_access_check(parent_sd,
382 get_current_nttok(fsp->conn),
383 false,
384 (access_mask & ~FILE_READ_ATTRIBUTES),
385 &access_granted);
386 if(!NT_STATUS_IS_OK(status)) {
387 DBG_INFO("access check "
388 "on directory %s for mask 0x%x returned (0x%x) %s\n",
389 fsp_str_dbg(fsp),
390 access_mask,
391 access_granted,
392 nt_errstr(status));
393 goto out;
396 if (!(access_mask & (SEC_DIR_ADD_FILE | SEC_DIR_ADD_SUBDIR))) {
397 status = NT_STATUS_OK;
398 goto out;
400 if (!lp_check_parent_directory_delete_on_close(SNUM(fsp->conn))) {
401 status = NT_STATUS_OK;
402 goto out;
405 /* Check if the directory has delete-on-close set */
406 status = file_name_hash(fsp->conn,
407 fsp->fsp_name->base_name,
408 &name_hash);
409 if (!NT_STATUS_IS_OK(status)) {
410 goto out;
414 * Don't take a lock here. We just need a snapshot
415 * of the current state of delete on close and this is
416 * called in a codepath where we may already have a lock
417 * (and we explicitly can't hold 2 locks at the same time
418 * as that may deadlock).
420 lck = fetch_share_mode_unlocked(frame, fsp->file_id);
421 if (lck == NULL) {
422 status = NT_STATUS_OK;
423 goto out;
426 delete_on_close_set = is_delete_on_close_set(lck, name_hash);
427 if (delete_on_close_set) {
428 status = NT_STATUS_DELETE_PENDING;
429 goto out;
432 status = NT_STATUS_OK;
434 out:
435 TALLOC_FREE(frame);
436 return status;
439 /****************************************************************************
440 Ensure when opening a base file for a stream open that we have permissions
441 to do so given the access mask on the base file.
442 ****************************************************************************/
444 static NTSTATUS check_base_file_access(struct files_struct *fsp,
445 uint32_t access_mask)
447 NTSTATUS status;
449 status = smbd_calculate_access_mask_fsp(fsp->conn->cwd_fsp,
450 fsp,
451 false,
452 access_mask,
453 &access_mask);
454 if (!NT_STATUS_IS_OK(status)) {
455 DEBUG(10, ("smbd_calculate_access_mask "
456 "on file %s returned %s\n",
457 fsp_str_dbg(fsp),
458 nt_errstr(status)));
459 return status;
462 if (access_mask & (FILE_WRITE_DATA|FILE_APPEND_DATA)) {
463 uint32_t dosattrs;
464 if (!CAN_WRITE(fsp->conn)) {
465 return NT_STATUS_ACCESS_DENIED;
467 dosattrs = fdos_mode(fsp);
468 if (dosattrs & FILE_ATTRIBUTE_READONLY) {
469 return NT_STATUS_ACCESS_DENIED;
473 return smbd_check_access_rights_fsp(fsp->conn->cwd_fsp,
474 fsp,
475 false,
476 access_mask);
479 static NTSTATUS chdir_below_conn(
480 TALLOC_CTX *mem_ctx,
481 connection_struct *conn,
482 const char *connectpath,
483 size_t connectpath_len,
484 struct smb_filename *dir_fname,
485 struct smb_filename **_oldwd_fname)
487 struct smb_filename *oldwd_fname = NULL;
488 struct smb_filename *smb_fname_dot = NULL;
489 struct smb_filename *real_fname = NULL;
490 const char *relative = NULL;
491 NTSTATUS status;
492 int ret;
493 bool ok;
495 if (!ISDOT(dir_fname->base_name)) {
497 oldwd_fname = vfs_GetWd(talloc_tos(), conn);
498 if (oldwd_fname == NULL) {
499 status = map_nt_error_from_unix(errno);
500 goto out;
503 /* Pin parent directory in place. */
504 ret = vfs_ChDir(conn, dir_fname);
505 if (ret == -1) {
506 status = map_nt_error_from_unix(errno);
507 DBG_DEBUG("chdir to %s failed: %s\n",
508 dir_fname->base_name,
509 strerror(errno));
510 goto out;
514 smb_fname_dot = synthetic_smb_fname(
515 talloc_tos(),
516 ".",
517 NULL,
518 NULL,
519 dir_fname->twrp,
520 dir_fname->flags);
521 if (smb_fname_dot == NULL) {
522 status = NT_STATUS_NO_MEMORY;
523 goto out;
526 real_fname = SMB_VFS_REALPATH(conn, talloc_tos(), smb_fname_dot);
527 if (real_fname == NULL) {
528 status = map_nt_error_from_unix(errno);
529 DBG_DEBUG("realpath in %s failed: %s\n",
530 dir_fname->base_name,
531 strerror(errno));
532 goto out;
534 TALLOC_FREE(smb_fname_dot);
536 ok = subdir_of(connectpath,
537 connectpath_len,
538 real_fname->base_name,
539 &relative);
540 if (ok) {
541 TALLOC_FREE(real_fname);
542 *_oldwd_fname = oldwd_fname;
543 return NT_STATUS_OK;
546 DBG_NOTICE("Bad access attempt: %s is a symlink "
547 "outside the share path\n"
548 "conn_rootdir =%s\n"
549 "resolved_name=%s\n",
550 dir_fname->base_name,
551 connectpath,
552 real_fname->base_name);
553 TALLOC_FREE(real_fname);
555 status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
557 out:
558 if (oldwd_fname != NULL) {
559 ret = vfs_ChDir(conn, oldwd_fname);
560 SMB_ASSERT(ret == 0);
561 TALLOC_FREE(oldwd_fname);
564 return status;
568 * Get the symlink target of dirfsp/symlink_name, making sure the
569 * target is below connection_path.
572 static NTSTATUS symlink_target_below_conn(
573 TALLOC_CTX *mem_ctx,
574 const char *connection_path,
575 struct files_struct *fsp,
576 struct files_struct *dirfsp,
577 struct smb_filename *symlink_name,
578 char **_target)
580 char *target = NULL;
581 char *absolute = NULL;
582 NTSTATUS status;
584 if (fsp_get_pathref_fd(fsp) != -1) {
586 * fsp is an O_PATH open, Linux does a "freadlink"
587 * with an empty name argument to readlinkat
589 status = readlink_talloc(talloc_tos(), fsp, NULL, &target);
590 } else {
591 status = readlink_talloc(
592 talloc_tos(), dirfsp, symlink_name, &target);
595 status = safe_symlink_target_path(talloc_tos(),
596 connection_path,
597 dirfsp->fsp_name->base_name,
598 target,
600 &absolute);
601 if (!NT_STATUS_IS_OK(status)) {
602 DBG_DEBUG("safe_symlink_target_path() failed: %s\n",
603 nt_errstr(status));
604 return status;
607 if (absolute[0] == '\0') {
609 * special case symlink to share root: "." is our
610 * share root filename
612 TALLOC_FREE(absolute);
613 absolute = talloc_strdup(talloc_tos(), ".");
614 if (absolute == NULL) {
615 return NT_STATUS_NO_MEMORY;
619 *_target = absolute;
620 return NT_STATUS_OK;
623 /****************************************************************************
624 Non-widelink open.
625 ****************************************************************************/
627 static NTSTATUS non_widelink_open(const struct files_struct *dirfsp,
628 files_struct *fsp,
629 struct smb_filename *smb_fname,
630 const struct vfs_open_how *_how)
632 struct connection_struct *conn = fsp->conn;
633 const char *connpath = SMB_VFS_CONNECTPATH(conn, dirfsp, smb_fname);
634 size_t connpath_len;
635 NTSTATUS status = NT_STATUS_OK;
636 int fd = -1;
637 char *orig_smb_fname_base = smb_fname->base_name;
638 struct smb_filename *orig_fsp_name = fsp->fsp_name;
639 struct smb_filename *smb_fname_rel = NULL;
640 struct smb_filename *oldwd_fname = NULL;
641 struct smb_filename *parent_dir_fname = NULL;
642 struct vfs_open_how how = *_how;
643 char *target = NULL;
644 size_t link_depth = 0;
645 int ret;
647 SMB_ASSERT(!fsp_is_alternate_stream(fsp));
649 if (connpath == NULL) {
651 * This can happen with shadow_copy2 if the snapshot
652 * path is not found
654 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
656 connpath_len = strlen(connpath);
658 again:
659 if (smb_fname->base_name[0] == '/') {
660 int cmp = strcmp(connpath, smb_fname->base_name);
661 if (cmp == 0) {
662 smb_fname->base_name = talloc_strdup(smb_fname, "");
663 if (smb_fname->base_name == NULL) {
664 status = NT_STATUS_NO_MEMORY;
665 goto out;
670 if (dirfsp == conn->cwd_fsp) {
672 status = SMB_VFS_PARENT_PATHNAME(fsp->conn,
673 talloc_tos(),
674 smb_fname,
675 &parent_dir_fname,
676 &smb_fname_rel);
677 if (!NT_STATUS_IS_OK(status)) {
678 goto out;
681 status = chdir_below_conn(
682 talloc_tos(),
683 conn,
684 connpath,
685 connpath_len,
686 parent_dir_fname,
687 &oldwd_fname);
688 if (!NT_STATUS_IS_OK(status)) {
689 goto out;
692 /* Setup fsp->fsp_name to be relative to cwd */
693 fsp->fsp_name = smb_fname_rel;
694 } else {
696 * fsp->fsp_name is unchanged as it is already correctly
697 * relative to dirfsp.
699 smb_fname_rel = smb_fname;
704 * Assert nobody can step in with a symlink on the
705 * path, there is no path anymore and we'll use
706 * O_NOFOLLOW to open.
708 char *slash = strchr_m(smb_fname_rel->base_name, '/');
709 SMB_ASSERT(slash == NULL);
712 how.flags |= O_NOFOLLOW;
714 fd = SMB_VFS_OPENAT(conn,
715 dirfsp,
716 smb_fname_rel,
717 fsp,
718 &how);
719 fsp_set_fd(fsp, fd); /* This preserves errno */
721 if (fd == -1) {
722 status = map_nt_error_from_unix(errno);
724 if (errno == ENOENT) {
725 goto out;
729 * ENOENT makes it worthless retrying with a
730 * stat, we know for sure the file does not
731 * exist. For everything else we want to know
732 * what's there.
734 ret = SMB_VFS_FSTATAT(
735 fsp->conn,
736 dirfsp,
737 smb_fname_rel,
738 &fsp->fsp_name->st,
739 AT_SYMLINK_NOFOLLOW);
741 if (ret == -1) {
743 * Keep the original error. Otherwise we would
744 * mask for example EROFS for open(O_CREAT),
745 * turning it into ENOENT.
747 goto out;
749 } else {
750 ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st);
753 if (ret == -1) {
754 status = map_nt_error_from_unix(errno);
755 DBG_DEBUG("fstat[at](%s) failed: %s\n",
756 smb_fname_str_dbg(smb_fname),
757 strerror(errno));
758 goto out;
761 fsp->fsp_flags.is_directory = S_ISDIR(fsp->fsp_name->st.st_ex_mode);
762 orig_fsp_name->st = fsp->fsp_name->st;
764 if (!S_ISLNK(fsp->fsp_name->st.st_ex_mode)) {
765 goto out;
769 * Found a symlink to follow in user space
772 if (fsp->fsp_name->flags & SMB_FILENAME_POSIX_PATH) {
773 /* Never follow symlinks on posix open. */
774 status = NT_STATUS_STOPPED_ON_SYMLINK;
775 goto out;
777 if (!lp_follow_symlinks(SNUM(conn))) {
778 /* Explicitly no symlinks. */
779 status = NT_STATUS_STOPPED_ON_SYMLINK;
780 goto out;
783 link_depth += 1;
784 if (link_depth >= 40) {
785 status = NT_STATUS_STOPPED_ON_SYMLINK;
786 goto out;
789 fsp->fsp_name = orig_fsp_name;
791 status = symlink_target_below_conn(
792 talloc_tos(),
793 connpath,
794 fsp,
795 discard_const_p(files_struct, dirfsp),
796 smb_fname_rel,
797 &target);
799 if (!NT_STATUS_IS_OK(status)) {
800 DBG_DEBUG("symlink_target_below_conn() failed: %s\n",
801 nt_errstr(status));
802 goto out;
806 * Close what openat(O_PATH) potentially left behind
808 fd_close(fsp);
810 if (smb_fname->base_name != orig_smb_fname_base) {
811 TALLOC_FREE(smb_fname->base_name);
813 smb_fname->base_name = target;
815 if (oldwd_fname != NULL) {
816 ret = vfs_ChDir(conn, oldwd_fname);
817 if (ret == -1) {
818 smb_panic("unable to get back to old directory\n");
820 TALLOC_FREE(oldwd_fname);
824 * And do it all again... As smb_fname is not relative to the passed in
825 * dirfsp anymore, we pass conn->cwd_fsp as dirfsp to
826 * non_widelink_open() to trigger the chdir(parentdir) logic.
828 dirfsp = conn->cwd_fsp;
830 goto again;
832 out:
833 fsp->fsp_name = orig_fsp_name;
834 smb_fname->base_name = orig_smb_fname_base;
836 TALLOC_FREE(parent_dir_fname);
838 if (!NT_STATUS_IS_OK(status)) {
839 fd_close(fsp);
842 if (oldwd_fname != NULL) {
843 ret = vfs_ChDir(conn, oldwd_fname);
844 if (ret == -1) {
845 smb_panic("unable to get back to old directory\n");
847 TALLOC_FREE(oldwd_fname);
849 return status;
852 /****************************************************************************
853 fd support routines - attempt to do a dos_open.
854 ****************************************************************************/
856 NTSTATUS fd_openat(const struct files_struct *dirfsp,
857 struct smb_filename *smb_fname,
858 files_struct *fsp,
859 const struct vfs_open_how *_how)
861 struct vfs_open_how how = *_how;
862 struct connection_struct *conn = fsp->conn;
863 NTSTATUS status = NT_STATUS_OK;
864 bool fsp_is_stream = fsp_is_alternate_stream(fsp);
865 bool smb_fname_is_stream = is_named_stream(smb_fname);
867 SMB_ASSERT(fsp_is_stream == smb_fname_is_stream);
870 * Never follow symlinks on a POSIX client. The
871 * client should be doing this.
874 if ((fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) || !lp_follow_symlinks(SNUM(conn))) {
875 how.flags |= O_NOFOLLOW;
878 if (fsp_is_stream) {
879 int fd;
881 fd = SMB_VFS_OPENAT(
882 conn,
883 NULL, /* stream open is relative to fsp->base_fsp */
884 smb_fname,
885 fsp,
886 &how);
887 if (fd == -1) {
888 status = map_nt_error_from_unix(errno);
890 fsp_set_fd(fsp, fd);
892 if (fd != -1) {
893 status = vfs_stat_fsp(fsp);
894 if (!NT_STATUS_IS_OK(status)) {
895 DBG_DEBUG("vfs_stat_fsp failed: %s\n",
896 nt_errstr(status));
897 fd_close(fsp);
901 return status;
905 * Only follow symlinks within a share
906 * definition.
908 status = non_widelink_open(dirfsp, fsp, smb_fname, &how);
909 if (!NT_STATUS_IS_OK(status)) {
910 if (NT_STATUS_EQUAL(status, NT_STATUS_TOO_MANY_OPENED_FILES)) {
911 static time_t last_warned = 0L;
913 if (time((time_t *) NULL) > last_warned) {
914 DEBUG(0,("Too many open files, unable "
915 "to open more! smbd's max "
916 "open files = %d\n",
917 lp_max_open_files()));
918 last_warned = time((time_t *) NULL);
922 DBG_DEBUG("name %s, flags = 0%o mode = 0%o, fd = %d. %s\n",
923 smb_fname_str_dbg(smb_fname),
924 how.flags,
925 (int)how.mode,
926 fsp_get_pathref_fd(fsp),
927 nt_errstr(status));
928 return status;
931 DBG_DEBUG("name %s, flags = 0%o mode = 0%o, fd = %d\n",
932 smb_fname_str_dbg(smb_fname),
933 how.flags,
934 (int)how.mode,
935 fsp_get_pathref_fd(fsp));
937 return status;
940 /****************************************************************************
941 Close the file associated with a fsp.
942 ****************************************************************************/
944 NTSTATUS fd_close(files_struct *fsp)
946 NTSTATUS stat_status = NT_STATUS_OK;
947 int ret;
949 if (fsp == fsp->conn->cwd_fsp) {
950 return NT_STATUS_OK;
953 if (fsp->fsp_flags.fstat_before_close) {
955 * capture status, if failure
956 * continue close processing
957 * and return status
959 stat_status = vfs_stat_fsp(fsp);
962 if (fsp->dptr) {
963 dptr_CloseDir(fsp);
965 if (fsp_get_pathref_fd(fsp) == -1) {
967 * Either a directory where the dptr_CloseDir() already closed
968 * the fd or a stat open.
970 return NT_STATUS_OK;
972 if (fh_get_refcount(fsp->fh) > 1) {
973 return NT_STATUS_OK; /* Shared handle. Only close last reference. */
976 ret = SMB_VFS_CLOSE(fsp);
977 fsp_set_fd(fsp, -1);
978 if (ret == -1) {
979 return map_nt_error_from_unix(errno);
981 return stat_status;
984 /****************************************************************************
985 Change the ownership of a file to that of the parent directory.
986 Do this by fd if possible.
987 ****************************************************************************/
989 static void change_file_owner_to_parent_fsp(struct files_struct *parent_fsp,
990 struct files_struct *fsp)
992 int ret;
994 if (parent_fsp->fsp_name->st.st_ex_uid == fsp->fsp_name->st.st_ex_uid) {
995 /* Already this uid - no need to change. */
996 DBG_DEBUG("file %s is already owned by uid %u\n",
997 fsp_str_dbg(fsp),
998 (unsigned int)fsp->fsp_name->st.st_ex_uid);
999 return;
1002 become_root();
1003 ret = SMB_VFS_FCHOWN(fsp,
1004 parent_fsp->fsp_name->st.st_ex_uid,
1005 (gid_t)-1);
1006 unbecome_root();
1007 if (ret == -1) {
1008 DBG_ERR("failed to fchown "
1009 "file %s to parent directory uid %u. Error "
1010 "was %s\n",
1011 fsp_str_dbg(fsp),
1012 (unsigned int)parent_fsp->fsp_name->st.st_ex_uid,
1013 strerror(errno));
1014 } else {
1015 DBG_DEBUG("changed new file %s to "
1016 "parent directory uid %u.\n",
1017 fsp_str_dbg(fsp),
1018 (unsigned int)parent_fsp->fsp_name->st.st_ex_uid);
1019 /* Ensure the uid entry is updated. */
1020 fsp->fsp_name->st.st_ex_uid =
1021 parent_fsp->fsp_name->st.st_ex_uid;
1025 static NTSTATUS change_dir_owner_to_parent_fsp(struct files_struct *parent_fsp,
1026 struct files_struct *fsp)
1028 NTSTATUS status;
1029 int ret;
1031 if (parent_fsp->fsp_name->st.st_ex_uid == fsp->fsp_name->st.st_ex_uid) {
1032 /* Already this uid - no need to change. */
1033 DBG_DEBUG("directory %s is already owned by uid %u\n",
1034 fsp_str_dbg(fsp),
1035 (unsigned int)fsp->fsp_name->st.st_ex_uid);
1036 return NT_STATUS_OK;
1039 become_root();
1040 ret = SMB_VFS_FCHOWN(fsp,
1041 parent_fsp->fsp_name->st.st_ex_uid,
1042 (gid_t)-1);
1043 unbecome_root();
1044 if (ret == -1) {
1045 status = map_nt_error_from_unix(errno);
1046 DBG_ERR("failed to chown "
1047 "directory %s to parent directory uid %u. "
1048 "Error was %s\n",
1049 fsp_str_dbg(fsp),
1050 (unsigned int)parent_fsp->fsp_name->st.st_ex_uid,
1051 nt_errstr(status));
1052 return status;
1055 DBG_DEBUG("changed ownership of new "
1056 "directory %s to parent directory uid %u.\n",
1057 fsp_str_dbg(fsp),
1058 (unsigned int)parent_fsp->fsp_name->st.st_ex_uid);
1060 /* Ensure the uid entry is updated. */
1061 fsp->fsp_name->st.st_ex_uid = parent_fsp->fsp_name->st.st_ex_uid;
1063 return NT_STATUS_OK;
1066 /****************************************************************************
1067 Open a file - returning a guaranteed ATOMIC indication of if the
1068 file was created or not.
1069 ****************************************************************************/
1071 static NTSTATUS fd_open_atomic(struct files_struct *dirfsp,
1072 struct smb_filename *smb_fname,
1073 files_struct *fsp,
1074 const struct vfs_open_how *_how,
1075 bool *file_created)
1077 struct vfs_open_how how = *_how;
1078 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
1079 NTSTATUS retry_status;
1080 bool file_existed = VALID_STAT(smb_fname->st);
1082 if (!(how.flags & O_CREAT)) {
1084 * We're not creating the file, just pass through.
1086 status = fd_openat(dirfsp, smb_fname, fsp, &how);
1087 *file_created = false;
1088 return status;
1091 if (how.flags & O_EXCL) {
1093 * Fail if already exists, just pass through.
1095 status = fd_openat(dirfsp, smb_fname, fsp, &how);
1098 * Here we've opened with O_CREAT|O_EXCL. If that went
1099 * NT_STATUS_OK, we *know* we created this file.
1101 *file_created = NT_STATUS_IS_OK(status);
1103 return status;
1107 * Now it gets tricky. We have O_CREAT, but not O_EXCL.
1108 * To know absolutely if we created the file or not,
1109 * we can never call O_CREAT without O_EXCL. So if
1110 * we think the file existed, try without O_CREAT|O_EXCL.
1111 * If we think the file didn't exist, try with
1112 * O_CREAT|O_EXCL.
1114 * The big problem here is dangling symlinks. Opening
1115 * without O_NOFOLLOW means both bad symlink
1116 * and missing path return -1, ENOENT from open(). As POSIX
1117 * is pathname based it's not possible to tell
1118 * the difference between these two cases in a
1119 * non-racy way, so change to try only two attempts before
1120 * giving up.
1122 * We don't have this problem for the O_NOFOLLOW
1123 * case as it just returns NT_STATUS_OBJECT_PATH_NOT_FOUND
1124 * mapped from the ELOOP POSIX error.
1127 if (file_existed) {
1128 how.flags = _how->flags & ~(O_CREAT);
1129 retry_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
1130 } else {
1131 how.flags = _how->flags | O_EXCL;
1132 retry_status = NT_STATUS_OBJECT_NAME_COLLISION;
1135 status = fd_openat(dirfsp, smb_fname, fsp, &how);
1136 if (NT_STATUS_IS_OK(status)) {
1137 *file_created = !file_existed;
1138 return NT_STATUS_OK;
1140 if (NT_STATUS_EQUAL(status, retry_status)) {
1142 file_existed = !file_existed;
1144 DBG_DEBUG("File %s %s. Retry.\n",
1145 fsp_str_dbg(fsp),
1146 file_existed ? "existed" : "did not exist");
1148 if (file_existed) {
1149 how.flags = _how->flags & ~(O_CREAT);
1150 } else {
1151 how.flags = _how->flags | O_EXCL;
1154 status = fd_openat(dirfsp, smb_fname, fsp, &how);
1157 *file_created = (NT_STATUS_IS_OK(status) && !file_existed);
1158 return status;
1161 static NTSTATUS reopen_from_fsp(struct files_struct *dirfsp,
1162 struct smb_filename *smb_fname,
1163 struct files_struct *fsp,
1164 const struct vfs_open_how *how,
1165 bool *p_file_created)
1167 NTSTATUS status;
1168 int old_fd;
1170 if (fsp->fsp_flags.have_proc_fds &&
1171 ((old_fd = fsp_get_pathref_fd(fsp)) != -1)) {
1173 struct sys_proc_fd_path_buf buf;
1174 struct smb_filename proc_fname = (struct smb_filename){
1175 .base_name = sys_proc_fd_path(old_fd, &buf),
1177 mode_t mode = fsp->fsp_name->st.st_ex_mode;
1178 int new_fd;
1180 SMB_ASSERT(fsp->fsp_flags.is_pathref);
1182 if (S_ISLNK(mode)) {
1183 return NT_STATUS_STOPPED_ON_SYMLINK;
1185 if (!(S_ISREG(mode) || S_ISDIR(mode))) {
1186 return NT_STATUS_IO_REPARSE_TAG_NOT_HANDLED;
1189 fsp->fsp_flags.is_pathref = false;
1191 new_fd = SMB_VFS_OPENAT(fsp->conn,
1192 fsp->conn->cwd_fsp,
1193 &proc_fname,
1194 fsp,
1195 how);
1196 if (new_fd == -1) {
1197 status = map_nt_error_from_unix(errno);
1198 fd_close(fsp);
1199 return status;
1202 status = fd_close(fsp);
1203 if (!NT_STATUS_IS_OK(status)) {
1204 return status;
1207 fsp_set_fd(fsp, new_fd);
1208 return NT_STATUS_OK;
1212 * Close the existing pathref fd and set the fsp flag
1213 * is_pathref to false so we get a "normal" fd this time.
1215 status = fd_close(fsp);
1216 if (!NT_STATUS_IS_OK(status)) {
1217 return status;
1220 fsp->fsp_flags.is_pathref = false;
1222 status = fd_open_atomic(dirfsp, smb_fname, fsp, how, p_file_created);
1223 return status;
1226 /****************************************************************************
1227 Open a file.
1228 ****************************************************************************/
1230 static NTSTATUS open_file(
1231 struct smb_request *req,
1232 struct files_struct *dirfsp,
1233 struct smb_filename *smb_fname_atname,
1234 files_struct *fsp,
1235 const struct vfs_open_how *_how,
1236 uint32_t access_mask, /* client requested access mask. */
1237 uint32_t open_access_mask, /* what we're actually using in the open. */
1238 uint32_t private_flags,
1239 bool *p_file_created)
1241 connection_struct *conn = fsp->conn;
1242 struct smb_filename *smb_fname = fsp->fsp_name;
1243 struct vfs_open_how how = *_how;
1244 NTSTATUS status = NT_STATUS_OK;
1245 bool file_existed = VALID_STAT(fsp->fsp_name->st);
1246 const uint32_t need_fd_mask =
1247 FILE_READ_DATA |
1248 FILE_WRITE_DATA |
1249 FILE_APPEND_DATA |
1250 FILE_EXECUTE |
1251 SEC_FLAG_SYSTEM_SECURITY;
1252 bool creating = !file_existed && (how.flags & O_CREAT);
1253 bool open_fd = false;
1254 bool posix_open = (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN);
1257 * Catch early an attempt to open an existing
1258 * directory as a file.
1260 if (file_existed && S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
1261 return NT_STATUS_FILE_IS_A_DIRECTORY;
1265 * This little piece of insanity is inspired by the
1266 * fact that an NT client can open a file for O_RDONLY,
1267 * but set the create disposition to FILE_EXISTS_TRUNCATE.
1268 * If the client *can* write to the file, then it expects to
1269 * truncate the file, even though it is opening for readonly.
1270 * Quicken uses this stupid trick in backup file creation...
1271 * Thanks *greatly* to "David W. Chapman Jr." <dwcjr@inethouston.net>
1272 * for helping track this one down. It didn't bite us in 2.0.x
1273 * as we always opened files read-write in that release. JRA.
1276 if (((how.flags & O_ACCMODE) == O_RDONLY) && (how.flags & O_TRUNC)) {
1277 DBG_DEBUG("truncate requested on read-only open for file %s\n",
1278 smb_fname_str_dbg(smb_fname));
1279 how.flags = (how.flags & ~O_ACCMODE) | O_RDWR;
1282 /* Check permissions */
1285 * This code was changed after seeing a client open request
1286 * containing the open mode of (DENY_WRITE/read-only) with
1287 * the 'create if not exist' bit set. The previous code
1288 * would fail to open the file read only on a read-only share
1289 * as it was checking the flags parameter directly against O_RDONLY,
1290 * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
1291 * JRA.
1294 if (!CAN_WRITE(conn)) {
1295 /* It's a read-only share - fail if we wanted to write. */
1296 if ((how.flags & O_ACCMODE) != O_RDONLY ||
1297 (how.flags & O_TRUNC) || (how.flags & O_APPEND)) {
1298 DEBUG(3,("Permission denied opening %s\n",
1299 smb_fname_str_dbg(smb_fname)));
1300 return NT_STATUS_ACCESS_DENIED;
1303 * We don't want to write - but we must make sure that
1304 * O_CREAT doesn't create the file if we have write
1305 * access into the directory.
1307 how.flags &= ~(O_CREAT | O_EXCL);
1310 if ((open_access_mask & need_fd_mask) || creating ||
1311 (how.flags & O_TRUNC)) {
1312 open_fd = true;
1315 if (open_fd) {
1316 int ret;
1318 #if defined(O_NONBLOCK) && defined(S_ISFIFO)
1320 * We would block on opening a FIFO with no one else on the
1321 * other end. Do what we used to do and add O_NONBLOCK to the
1322 * open flags. JRA.
1325 if (file_existed && S_ISFIFO(smb_fname->st.st_ex_mode)) {
1326 how.flags |= O_NONBLOCK;
1328 #endif
1330 if (!posix_open) {
1331 const char *wild = smb_fname->base_name;
1333 * Don't open files with Microsoft wildcard characters.
1335 if (fsp_is_alternate_stream(fsp)) {
1337 * wildcard characters are allowed in stream
1338 * names only test the basefilename
1340 wild = fsp->base_fsp->fsp_name->base_name;
1343 if (ms_has_wild(wild)) {
1344 return NT_STATUS_OBJECT_NAME_INVALID;
1348 /* Can we access this file ? */
1349 if (!fsp_is_alternate_stream(fsp)) {
1350 /* Only do this check on non-stream open. */
1351 if (file_existed) {
1352 status = smbd_check_access_rights_fsp(
1353 dirfsp,
1354 fsp,
1355 false,
1356 open_access_mask);
1358 if (!NT_STATUS_IS_OK(status)) {
1359 DBG_DEBUG("smbd_check_access_rights_fsp"
1360 " on file %s returned %s\n",
1361 fsp_str_dbg(fsp),
1362 nt_errstr(status));
1365 if (!NT_STATUS_IS_OK(status) &&
1366 !NT_STATUS_EQUAL(status,
1367 NT_STATUS_OBJECT_NAME_NOT_FOUND))
1369 return status;
1372 if (NT_STATUS_EQUAL(status,
1373 NT_STATUS_OBJECT_NAME_NOT_FOUND))
1375 DEBUG(10, ("open_file: "
1376 "file %s vanished since we "
1377 "checked for existence.\n",
1378 smb_fname_str_dbg(smb_fname)));
1379 file_existed = false;
1380 SET_STAT_INVALID(fsp->fsp_name->st);
1384 if (!file_existed) {
1385 if (!(how.flags & O_CREAT)) {
1386 /* File didn't exist and no O_CREAT. */
1387 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1390 status = check_parent_access_fsp(
1391 dirfsp,
1392 SEC_DIR_ADD_FILE);
1393 if (!NT_STATUS_IS_OK(status)) {
1394 DBG_DEBUG("check_parent_access_fsp on "
1395 "directory %s for file %s "
1396 "returned %s\n",
1397 smb_fname_str_dbg(
1398 dirfsp->fsp_name),
1399 smb_fname_str_dbg(smb_fname),
1400 nt_errstr(status));
1401 return status;
1407 * Actually do the open - if O_TRUNC is needed handle it
1408 * below under the share mode lock.
1410 how.flags &= ~O_TRUNC;
1411 status = reopen_from_fsp(dirfsp,
1412 smb_fname_atname,
1413 fsp,
1414 &how,
1415 p_file_created);
1416 if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) {
1418 * Non-O_PATH reopen that hit a race
1419 * condition: Someone has put a symlink where
1420 * we used to have a file. Can't happen with
1421 * O_PATH and reopening from /proc/self/fd/ or
1422 * equivalent.
1424 status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
1426 if (!NT_STATUS_IS_OK(status)) {
1427 DBG_NOTICE("Error opening file %s (%s) (in_flags=%d) "
1428 "(flags=%d)\n",
1429 smb_fname_str_dbg(smb_fname),
1430 nt_errstr(status),
1431 _how->flags,
1432 how.flags);
1433 return status;
1436 if (how.flags & O_NONBLOCK) {
1438 * GPFS can return ETIMEDOUT for pread on
1439 * nonblocking file descriptors when files
1440 * migrated to tape need to be recalled. I
1441 * could imagine this happens elsewhere
1442 * too. With blocking file descriptors this
1443 * does not happen.
1445 ret = vfs_set_blocking(fsp, true);
1446 if (ret == -1) {
1447 status = map_nt_error_from_unix(errno);
1448 DBG_WARNING("Could not set fd to blocking: "
1449 "%s\n", strerror(errno));
1450 fd_close(fsp);
1451 return status;
1455 if (*p_file_created) {
1456 /* We created this file. */
1458 bool need_re_stat = false;
1459 /* Do all inheritance work after we've
1460 done a successful fstat call and filled
1461 in the stat struct in fsp->fsp_name. */
1463 /* Inherit the ACL if required */
1464 if (lp_inherit_permissions(SNUM(conn))) {
1465 inherit_access_posix_acl(conn,
1466 dirfsp,
1467 smb_fname,
1468 how.mode);
1469 need_re_stat = true;
1472 /* Change the owner if required. */
1473 if (lp_inherit_owner(SNUM(conn)) != INHERIT_OWNER_NO) {
1474 change_file_owner_to_parent_fsp(dirfsp, fsp);
1475 need_re_stat = true;
1478 if (need_re_stat) {
1479 status = vfs_stat_fsp(fsp);
1481 * If we have an fd, this stat should succeed.
1483 if (!NT_STATUS_IS_OK(status)) {
1484 DBG_ERR("Error doing fstat on open "
1485 "file %s (%s)\n",
1486 smb_fname_str_dbg(smb_fname),
1487 nt_errstr(status));
1488 fd_close(fsp);
1489 return status;
1493 notify_fname(conn, NOTIFY_ACTION_ADDED,
1494 FILE_NOTIFY_CHANGE_FILE_NAME,
1495 smb_fname->base_name);
1497 } else {
1498 if (!file_existed) {
1499 /* File must exist for a stat open. */
1500 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1503 if (S_ISLNK(smb_fname->st.st_ex_mode) &&
1504 !posix_open)
1507 * Don't allow stat opens on symlinks directly unless
1508 * it's a POSIX open. Match the return code from
1509 * openat_pathref_fsp().
1511 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1514 if (!fsp->fsp_flags.is_pathref) {
1516 * There is only one legit case where end up here:
1517 * openat_pathref_fsp() failed to open a symlink, so the
1518 * fsp was created by fsp_new() which doesn't set
1519 * is_pathref. Other than that, we should always have a
1520 * pathref fsp at this point. The subsequent checks
1521 * assert this.
1523 if (!(smb_fname->flags & SMB_FILENAME_POSIX_PATH)) {
1524 DBG_ERR("[%s] is not a POSIX pathname\n",
1525 smb_fname_str_dbg(smb_fname));
1526 return NT_STATUS_INTERNAL_ERROR;
1528 if (!S_ISLNK(smb_fname->st.st_ex_mode)) {
1529 DBG_ERR("[%s] is not a symlink\n",
1530 smb_fname_str_dbg(smb_fname));
1531 return NT_STATUS_INTERNAL_ERROR;
1533 if (fsp_get_pathref_fd(fsp) != -1) {
1534 DBG_ERR("fd for [%s] is not -1: fd [%d]\n",
1535 smb_fname_str_dbg(smb_fname),
1536 fsp_get_pathref_fd(fsp));
1537 return NT_STATUS_INTERNAL_ERROR;
1542 * Access to streams is checked by checking the basefile and
1543 * that has already been checked by check_base_file_access()
1544 * in create_file_unixpath().
1546 if (!fsp_is_alternate_stream(fsp)) {
1547 status = smbd_check_access_rights_fsp(dirfsp,
1548 fsp,
1549 false,
1550 open_access_mask);
1552 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) &&
1553 posix_open &&
1554 S_ISLNK(smb_fname->st.st_ex_mode)) {
1555 /* This is a POSIX stat open for delete
1556 * or rename on a symlink that points
1557 * nowhere. Allow. */
1558 DEBUG(10,("open_file: allowing POSIX "
1559 "open on bad symlink %s\n",
1560 smb_fname_str_dbg(smb_fname)));
1561 status = NT_STATUS_OK;
1564 if (!NT_STATUS_IS_OK(status)) {
1565 DBG_DEBUG("smbd_check_access_rights_fsp on file "
1566 "%s returned %s\n",
1567 fsp_str_dbg(fsp),
1568 nt_errstr(status));
1569 return status;
1574 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
1575 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
1576 fsp->file_pid = req ? req->smbpid : 0;
1577 fsp->fsp_flags.can_lock = true;
1578 fsp->fsp_flags.can_read = ((access_mask & FILE_READ_DATA) != 0);
1579 fsp->fsp_flags.can_write =
1580 CAN_WRITE(conn) &&
1581 ((access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) != 0);
1582 if (fsp->fsp_name->twrp != 0) {
1583 fsp->fsp_flags.can_write = false;
1585 fsp->print_file = NULL;
1586 fsp->fsp_flags.modified = false;
1587 fsp->sent_oplock_break = NO_BREAK_SENT;
1588 fsp->fsp_flags.is_directory = false;
1589 if (is_in_path(smb_fname->base_name,
1590 conn->aio_write_behind_list,
1591 posix_open ? true : conn->case_sensitive)) {
1592 fsp->fsp_flags.aio_write_behind = true;
1595 DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
1596 conn->session_info->unix_info->unix_name,
1597 smb_fname_str_dbg(smb_fname),
1598 BOOLSTR(fsp->fsp_flags.can_read),
1599 BOOLSTR(fsp->fsp_flags.can_write),
1600 conn->num_files_open));
1602 return NT_STATUS_OK;
1605 static bool mask_conflict(
1606 uint32_t new_access,
1607 uint32_t existing_access,
1608 uint32_t access_mask,
1609 uint32_t new_sharemode,
1610 uint32_t existing_sharemode,
1611 uint32_t sharemode_mask)
1613 bool want_access = (new_access & access_mask);
1614 bool allow_existing = (existing_sharemode & sharemode_mask);
1615 bool have_access = (existing_access & access_mask);
1616 bool allow_new = (new_sharemode & sharemode_mask);
1618 if (want_access && !allow_existing) {
1619 DBG_DEBUG("Access request 0x%"PRIx32"/0x%"PRIx32" conflicts "
1620 "with existing sharemode 0x%"PRIx32"/0x%"PRIx32"\n",
1621 new_access,
1622 access_mask,
1623 existing_sharemode,
1624 sharemode_mask);
1625 return true;
1627 if (have_access && !allow_new) {
1628 DBG_DEBUG("Sharemode request 0x%"PRIx32"/0x%"PRIx32" conflicts "
1629 "with existing access 0x%"PRIx32"/0x%"PRIx32"\n",
1630 new_sharemode,
1631 sharemode_mask,
1632 existing_access,
1633 access_mask);
1634 return true;
1636 return false;
1639 /****************************************************************************
1640 Check if we can open a file with a share mode.
1641 Returns True if conflict, False if not.
1642 ****************************************************************************/
1644 static const uint32_t conflicting_access =
1645 FILE_WRITE_DATA|
1646 FILE_APPEND_DATA|
1647 FILE_READ_DATA|
1648 FILE_EXECUTE|
1649 DELETE_ACCESS;
1651 static bool share_conflict(uint32_t e_access_mask,
1652 uint32_t e_share_access,
1653 uint32_t access_mask,
1654 uint32_t share_access)
1656 bool conflict;
1658 DBG_DEBUG("existing access_mask = 0x%"PRIx32", "
1659 "existing share access = 0x%"PRIx32", "
1660 "access_mask = 0x%"PRIx32", "
1661 "share_access = 0x%"PRIx32"\n",
1662 e_access_mask,
1663 e_share_access,
1664 access_mask,
1665 share_access);
1667 if ((e_access_mask & conflicting_access) == 0) {
1668 DBG_DEBUG("No conflict due to "
1669 "existing access_mask = 0x%"PRIx32"\n",
1670 e_access_mask);
1671 return false;
1673 if ((access_mask & conflicting_access) == 0) {
1674 DBG_DEBUG("No conflict due to access_mask = 0x%"PRIx32"\n",
1675 access_mask);
1676 return false;
1679 conflict = mask_conflict(
1680 access_mask, e_access_mask, FILE_WRITE_DATA | FILE_APPEND_DATA,
1681 share_access, e_share_access, FILE_SHARE_WRITE);
1682 conflict |= mask_conflict(
1683 access_mask, e_access_mask, FILE_READ_DATA | FILE_EXECUTE,
1684 share_access, e_share_access, FILE_SHARE_READ);
1685 conflict |= mask_conflict(
1686 access_mask, e_access_mask, DELETE_ACCESS,
1687 share_access, e_share_access, FILE_SHARE_DELETE);
1689 DBG_DEBUG("conflict=%s\n", conflict ? "true" : "false");
1690 return conflict;
1693 #if defined(DEVELOPER)
1695 struct validate_my_share_entries_state {
1696 struct smbd_server_connection *sconn;
1697 struct file_id fid;
1698 struct server_id self;
1701 static bool validate_my_share_entries_fn(
1702 struct share_mode_entry *e,
1703 bool *modified,
1704 void *private_data)
1706 struct validate_my_share_entries_state *state = private_data;
1707 files_struct *fsp;
1709 if (!server_id_equal(&state->self, &e->pid)) {
1710 return false;
1713 if (e->op_mid == 0) {
1714 /* INTERNAL_OPEN_ONLY */
1715 return false;
1718 fsp = file_find_dif(state->sconn, state->fid, e->share_file_id);
1719 if (!fsp) {
1720 DBG_ERR("PANIC : %s\n",
1721 share_mode_str(talloc_tos(), 0, &state->fid, e));
1722 smb_panic("validate_my_share_entries: Cannot match a "
1723 "share entry with an open file\n");
1726 if (((uint16_t)fsp->oplock_type) != e->op_type) {
1727 goto panic;
1730 return false;
1732 panic:
1734 char *str;
1735 DBG_ERR("validate_my_share_entries: PANIC : %s\n",
1736 share_mode_str(talloc_tos(), 0, &state->fid, e));
1737 str = talloc_asprintf(talloc_tos(),
1738 "validate_my_share_entries: "
1739 "file %s, oplock_type = 0x%x, op_type = 0x%x\n",
1740 fsp->fsp_name->base_name,
1741 (unsigned int)fsp->oplock_type,
1742 (unsigned int)e->op_type);
1743 smb_panic(str);
1746 return false;
1748 #endif
1751 * Allowed access mask for stat opens relevant to oplocks
1753 bool is_oplock_stat_open(uint32_t access_mask)
1755 const uint32_t stat_open_bits =
1756 (SYNCHRONIZE_ACCESS|
1757 FILE_READ_ATTRIBUTES|
1758 FILE_WRITE_ATTRIBUTES);
1760 return (((access_mask & stat_open_bits) != 0) &&
1761 ((access_mask & ~stat_open_bits) == 0));
1765 * Allowed access mask for stat opens relevant to leases
1767 bool is_lease_stat_open(uint32_t access_mask)
1769 const uint32_t stat_open_bits =
1770 (SYNCHRONIZE_ACCESS|
1771 FILE_READ_ATTRIBUTES|
1772 FILE_WRITE_ATTRIBUTES|
1773 READ_CONTROL_ACCESS);
1775 return (((access_mask & stat_open_bits) != 0) &&
1776 ((access_mask & ~stat_open_bits) == 0));
1779 struct has_delete_on_close_state {
1780 bool ret;
1783 static bool has_delete_on_close_fn(
1784 struct share_mode_entry *e,
1785 bool *modified,
1786 void *private_data)
1788 struct has_delete_on_close_state *state = private_data;
1789 state->ret = !share_entry_stale_pid(e);
1790 return state->ret;
1793 static bool has_delete_on_close(struct share_mode_lock *lck,
1794 uint32_t name_hash)
1796 struct has_delete_on_close_state state = { .ret = false };
1797 bool ok;
1799 if (!is_delete_on_close_set(lck, name_hash)) {
1800 return false;
1803 ok= share_mode_forall_entries(lck, has_delete_on_close_fn, &state);
1804 if (!ok) {
1805 DBG_DEBUG("share_mode_forall_entries failed\n");
1806 return false;
1808 return state.ret;
1811 static void share_mode_flags_restrict(
1812 struct share_mode_lock *lck,
1813 uint32_t access_mask,
1814 uint32_t share_mode,
1815 uint32_t lease_type)
1817 uint32_t existing_access_mask, existing_share_mode;
1818 uint32_t existing_lease_type;
1820 share_mode_flags_get(
1821 lck,
1822 &existing_access_mask,
1823 &existing_share_mode,
1824 &existing_lease_type);
1826 existing_access_mask |= access_mask;
1827 if (access_mask & conflicting_access) {
1828 existing_share_mode &= share_mode;
1830 existing_lease_type |= lease_type;
1832 share_mode_flags_set(
1833 lck,
1834 existing_access_mask,
1835 existing_share_mode,
1836 existing_lease_type,
1837 NULL);
1840 /****************************************************************************
1841 Deal with share modes
1842 Invariant: Share mode must be locked on entry and exit.
1843 Returns -1 on error, or number of share modes on success (may be zero).
1844 ****************************************************************************/
1846 struct open_mode_check_state {
1847 struct file_id fid;
1848 uint32_t access_mask;
1849 uint32_t share_access;
1850 uint32_t lease_type;
1853 static bool open_mode_check_fn(
1854 struct share_mode_entry *e,
1855 bool *modified,
1856 void *private_data)
1858 struct open_mode_check_state *state = private_data;
1859 bool disconnected, stale;
1860 uint32_t access_mask, share_access, lease_type;
1862 disconnected = server_id_is_disconnected(&e->pid);
1863 if (disconnected) {
1864 return false;
1867 access_mask = state->access_mask | e->access_mask;
1868 share_access = state->share_access;
1869 if (e->access_mask & conflicting_access) {
1870 share_access &= e->share_access;
1872 lease_type = state->lease_type | get_lease_type(e, state->fid);
1874 if ((access_mask == state->access_mask) &&
1875 (share_access == state->share_access) &&
1876 (lease_type == state->lease_type)) {
1877 return false;
1880 stale = share_entry_stale_pid(e);
1881 if (stale) {
1882 return false;
1885 state->access_mask = access_mask;
1886 state->share_access = share_access;
1887 state->lease_type = lease_type;
1889 return false;
1892 static NTSTATUS open_mode_check(connection_struct *conn,
1893 struct file_id fid,
1894 struct share_mode_lock *lck,
1895 uint32_t access_mask,
1896 uint32_t share_access)
1898 struct open_mode_check_state state;
1899 bool ok, conflict;
1900 bool modified = false;
1902 if (is_oplock_stat_open(access_mask)) {
1903 /* Stat open that doesn't trigger oplock breaks or share mode
1904 * checks... ! JRA. */
1905 return NT_STATUS_OK;
1909 * Check if the share modes will give us access.
1912 #if defined(DEVELOPER)
1914 struct validate_my_share_entries_state validate_state = {
1915 .sconn = conn->sconn,
1916 .fid = fid,
1917 .self = messaging_server_id(conn->sconn->msg_ctx),
1919 ok = share_mode_forall_entries(
1920 lck, validate_my_share_entries_fn, &validate_state);
1921 SMB_ASSERT(ok);
1923 #endif
1925 share_mode_flags_get(
1926 lck, &state.access_mask, &state.share_access, NULL);
1928 conflict = share_conflict(
1929 state.access_mask,
1930 state.share_access,
1931 access_mask,
1932 share_access);
1933 if (!conflict) {
1934 DBG_DEBUG("No conflict due to share_mode_flags access\n");
1935 return NT_STATUS_OK;
1938 state = (struct open_mode_check_state) {
1939 .fid = fid,
1940 .share_access = (FILE_SHARE_READ|
1941 FILE_SHARE_WRITE|
1942 FILE_SHARE_DELETE),
1946 * Walk the share mode array to recalculate d->flags
1949 ok = share_mode_forall_entries(lck, open_mode_check_fn, &state);
1950 if (!ok) {
1951 DBG_DEBUG("share_mode_forall_entries failed\n");
1952 return NT_STATUS_INTERNAL_ERROR;
1955 share_mode_flags_set(
1956 lck,
1957 state.access_mask,
1958 state.share_access,
1959 state.lease_type,
1960 &modified);
1961 if (!modified) {
1963 * We only end up here if we had a sharing violation
1964 * from d->flags and have recalculated it.
1966 return NT_STATUS_SHARING_VIOLATION;
1969 conflict = share_conflict(
1970 state.access_mask,
1971 state.share_access,
1972 access_mask,
1973 share_access);
1974 if (!conflict) {
1975 DBG_DEBUG("No conflict due to share_mode_flags access\n");
1976 return NT_STATUS_OK;
1979 return NT_STATUS_SHARING_VIOLATION;
1983 * Send a break message to the oplock holder and delay the open for
1984 * our client.
1987 NTSTATUS send_break_message(struct messaging_context *msg_ctx,
1988 const struct file_id *id,
1989 const struct share_mode_entry *exclusive,
1990 uint16_t break_to)
1992 struct oplock_break_message msg = {
1993 .id = *id,
1994 .share_file_id = exclusive->share_file_id,
1995 .break_to = break_to,
1997 enum ndr_err_code ndr_err;
1998 uint8_t msgbuf[33];
1999 DATA_BLOB blob = {.data = msgbuf, .length = sizeof(msgbuf)};
2000 NTSTATUS status;
2002 if (DEBUGLVL(10)) {
2003 struct server_id_buf buf;
2004 DBG_DEBUG("Sending break message to %s\n",
2005 server_id_str_buf(exclusive->pid, &buf));
2006 NDR_PRINT_DEBUG(oplock_break_message, &msg);
2009 ndr_err = ndr_push_struct_into_fixed_blob(
2010 &blob,
2011 &msg,
2012 (ndr_push_flags_fn_t)ndr_push_oplock_break_message);
2013 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2014 DBG_WARNING("ndr_push_oplock_break_message failed: %s\n",
2015 ndr_errstr(ndr_err));
2016 return ndr_map_error2ntstatus(ndr_err);
2019 status = messaging_send(msg_ctx,
2020 exclusive->pid,
2021 MSG_SMB_BREAK_REQUEST,
2022 &blob);
2023 if (!NT_STATUS_IS_OK(status)) {
2024 DEBUG(3, ("Could not send oplock break message: %s\n",
2025 nt_errstr(status)));
2028 return status;
2031 struct validate_oplock_types_state {
2032 bool valid;
2033 bool batch;
2034 bool ex_or_batch;
2035 bool level2;
2036 bool no_oplock;
2037 uint32_t num_non_stat_opens;
2040 static bool validate_oplock_types_fn(
2041 struct share_mode_entry *e,
2042 bool *modified,
2043 void *private_data)
2045 struct validate_oplock_types_state *state = private_data;
2047 if (e->op_mid == 0) {
2048 /* INTERNAL_OPEN_ONLY */
2049 return false;
2052 if (e->op_type == NO_OPLOCK && is_oplock_stat_open(e->access_mask)) {
2054 * We ignore stat opens in the table - they always
2055 * have NO_OPLOCK and never get or cause breaks. JRA.
2057 return false;
2060 state->num_non_stat_opens += 1;
2062 if (BATCH_OPLOCK_TYPE(e->op_type)) {
2063 /* batch - can only be one. */
2064 if (share_entry_stale_pid(e)) {
2065 DBG_DEBUG("Found stale batch oplock\n");
2066 return false;
2068 if (state->ex_or_batch ||
2069 state->batch ||
2070 state->level2 ||
2071 state->no_oplock) {
2072 DBG_ERR("Bad batch oplock entry\n");
2073 state->valid = false;
2074 return true;
2076 state->batch = true;
2079 if (EXCLUSIVE_OPLOCK_TYPE(e->op_type)) {
2080 if (share_entry_stale_pid(e)) {
2081 DBG_DEBUG("Found stale duplicate oplock\n");
2082 return false;
2084 /* Exclusive or batch - can only be one. */
2085 if (state->ex_or_batch ||
2086 state->level2 ||
2087 state->no_oplock) {
2088 DBG_ERR("Bad exclusive or batch oplock entry\n");
2089 state->valid = false;
2090 return true;
2092 state->ex_or_batch = true;
2095 if (LEVEL_II_OPLOCK_TYPE(e->op_type)) {
2096 if (state->batch || state->ex_or_batch) {
2097 if (share_entry_stale_pid(e)) {
2098 DBG_DEBUG("Found stale LevelII oplock\n");
2099 return false;
2101 DBG_DEBUG("Bad levelII oplock entry\n");
2102 state->valid = false;
2103 return true;
2105 state->level2 = true;
2108 if (e->op_type == NO_OPLOCK) {
2109 if (state->batch || state->ex_or_batch) {
2110 if (share_entry_stale_pid(e)) {
2111 DBG_DEBUG("Found stale NO_OPLOCK entry\n");
2112 return false;
2114 DBG_ERR("Bad no oplock entry\n");
2115 state->valid = false;
2116 return true;
2118 state->no_oplock = true;
2121 return false;
2125 * Do internal consistency checks on the share mode for a file.
2128 static bool validate_oplock_types(struct share_mode_lock *lck)
2130 struct validate_oplock_types_state state = { .valid = true };
2131 static bool skip_validation;
2132 bool validate;
2133 bool ok;
2135 if (skip_validation) {
2136 return true;
2139 validate = lp_parm_bool(-1, "smbd", "validate_oplock_types", false);
2140 if (!validate) {
2141 DBG_DEBUG("smbd:validate_oplock_types not set to yes\n");
2142 skip_validation = true;
2143 return true;
2146 ok = share_mode_forall_entries(lck, validate_oplock_types_fn, &state);
2147 if (!ok) {
2148 DBG_DEBUG("share_mode_forall_entries failed\n");
2149 return false;
2151 if (!state.valid) {
2152 DBG_DEBUG("Got invalid oplock configuration\n");
2153 return false;
2156 if ((state.batch || state.ex_or_batch) &&
2157 (state.num_non_stat_opens != 1)) {
2158 DBG_WARNING("got batch (%d) or ex (%d) non-exclusively "
2159 "(%"PRIu32")\n",
2160 (int)state.batch,
2161 (int)state.ex_or_batch,
2162 state.num_non_stat_opens);
2163 return false;
2166 return true;
2169 static bool is_same_lease(const files_struct *fsp,
2170 const struct share_mode_entry *e,
2171 const struct smb2_lease *lease)
2173 if (e->op_type != LEASE_OPLOCK) {
2174 return false;
2176 if (lease == NULL) {
2177 return false;
2180 return smb2_lease_equal(fsp_client_guid(fsp),
2181 &lease->lease_key,
2182 &e->client_guid,
2183 &e->lease_key);
2186 static bool file_has_brlocks(files_struct *fsp)
2188 struct byte_range_lock *br_lck;
2190 br_lck = brl_get_locks_readonly(fsp);
2191 if (!br_lck)
2192 return false;
2194 return (brl_num_locks(br_lck) > 0);
2197 struct fsp_lease *find_fsp_lease(struct files_struct *new_fsp,
2198 const struct smb2_lease_key *key,
2199 uint32_t current_state,
2200 uint16_t lease_version,
2201 uint16_t lease_epoch)
2203 struct files_struct *fsp;
2206 * TODO: Measure how expensive this loop is with thousands of open
2207 * handles...
2210 for (fsp = file_find_di_first(new_fsp->conn->sconn, new_fsp->file_id, true);
2211 fsp != NULL;
2212 fsp = file_find_di_next(fsp, true)) {
2214 if (fsp == new_fsp) {
2215 continue;
2217 if (fsp->oplock_type != LEASE_OPLOCK) {
2218 continue;
2220 if (smb2_lease_key_equal(&fsp->lease->lease.lease_key, key)) {
2221 fsp->lease->ref_count += 1;
2222 return fsp->lease;
2226 /* Not found - must be leased in another smbd. */
2227 new_fsp->lease = talloc_zero(new_fsp->conn->sconn, struct fsp_lease);
2228 if (new_fsp->lease == NULL) {
2229 return NULL;
2231 new_fsp->lease->ref_count = 1;
2232 new_fsp->lease->sconn = new_fsp->conn->sconn;
2233 new_fsp->lease->lease.lease_key = *key;
2234 new_fsp->lease->lease.lease_state = current_state;
2236 * We internally treat all leases as V2 and update
2237 * the epoch, but when sending breaks it matters if
2238 * the requesting lease was v1 or v2.
2240 new_fsp->lease->lease.lease_version = lease_version;
2241 new_fsp->lease->lease.lease_epoch = lease_epoch;
2242 return new_fsp->lease;
2245 static NTSTATUS try_lease_upgrade(struct files_struct *fsp,
2246 struct share_mode_lock *lck,
2247 const struct GUID *client_guid,
2248 const struct smb2_lease *lease,
2249 uint32_t granted)
2251 bool do_upgrade;
2252 uint32_t current_state, breaking_to_requested, breaking_to_required;
2253 bool breaking;
2254 uint16_t lease_version, epoch;
2255 uint32_t existing, requested;
2256 NTSTATUS status;
2258 status = leases_db_get(
2259 client_guid,
2260 &lease->lease_key,
2261 &fsp->file_id,
2262 &current_state,
2263 &breaking,
2264 &breaking_to_requested,
2265 &breaking_to_required,
2266 &lease_version,
2267 &epoch);
2268 if (!NT_STATUS_IS_OK(status)) {
2269 return status;
2272 fsp->lease = find_fsp_lease(
2273 fsp,
2274 &lease->lease_key,
2275 current_state,
2276 lease_version,
2277 epoch);
2278 if (fsp->lease == NULL) {
2279 DEBUG(1, ("Did not find existing lease for file %s\n",
2280 fsp_str_dbg(fsp)));
2281 return NT_STATUS_NO_MEMORY;
2285 * Upgrade only if the requested lease is a strict upgrade.
2287 existing = current_state;
2288 requested = lease->lease_state;
2291 * Tricky: This test makes sure that "requested" is a
2292 * strict bitwise superset of "existing".
2294 do_upgrade = ((existing & requested) == existing);
2297 * Upgrade only if there's a change.
2299 do_upgrade &= (granted != existing);
2302 * Upgrade only if other leases don't prevent what was asked
2303 * for.
2305 do_upgrade &= (granted == requested);
2308 * only upgrade if we are not in breaking state
2310 do_upgrade &= !breaking;
2312 DEBUG(10, ("existing=%"PRIu32", requested=%"PRIu32", "
2313 "granted=%"PRIu32", do_upgrade=%d\n",
2314 existing, requested, granted, (int)do_upgrade));
2316 if (do_upgrade) {
2317 NTSTATUS set_status;
2319 current_state = granted;
2320 epoch += 1;
2322 set_status = leases_db_set(
2323 client_guid,
2324 &lease->lease_key,
2325 current_state,
2326 breaking,
2327 breaking_to_requested,
2328 breaking_to_required,
2329 lease_version,
2330 epoch);
2332 if (!NT_STATUS_IS_OK(set_status)) {
2333 DBG_DEBUG("leases_db_set failed: %s\n",
2334 nt_errstr(set_status));
2335 return set_status;
2339 fsp_lease_update(fsp);
2341 return NT_STATUS_OK;
2344 static NTSTATUS grant_new_fsp_lease(struct files_struct *fsp,
2345 struct share_mode_lock *lck,
2346 const struct GUID *client_guid,
2347 const struct smb2_lease *lease,
2348 uint32_t granted)
2350 NTSTATUS status;
2352 fsp->lease = talloc_zero(fsp->conn->sconn, struct fsp_lease);
2353 if (fsp->lease == NULL) {
2354 return NT_STATUS_INSUFFICIENT_RESOURCES;
2356 fsp->lease->ref_count = 1;
2357 fsp->lease->sconn = fsp->conn->sconn;
2358 fsp->lease->lease.lease_version = lease->lease_version;
2359 fsp->lease->lease.lease_key = lease->lease_key;
2360 fsp->lease->lease.lease_state = granted;
2361 fsp->lease->lease.lease_epoch = lease->lease_epoch + 1;
2363 status = leases_db_add(client_guid,
2364 &lease->lease_key,
2365 &fsp->file_id,
2366 fsp->lease->lease.lease_state,
2367 fsp->lease->lease.lease_version,
2368 fsp->lease->lease.lease_epoch,
2369 fsp->conn->connectpath,
2370 fsp->fsp_name->base_name,
2371 fsp->fsp_name->stream_name);
2372 if (!NT_STATUS_IS_OK(status)) {
2373 DEBUG(10, ("%s: leases_db_add failed: %s\n", __func__,
2374 nt_errstr(status)));
2375 TALLOC_FREE(fsp->lease);
2376 return NT_STATUS_INSUFFICIENT_RESOURCES;
2380 * We used to set lck->data->modified=true here without
2381 * actually modifying lck->data, triggering a needless
2382 * writeback of lck->data.
2384 * Apart from that writeback, setting modified=true has the
2385 * effect of triggering all waiters for this file to
2386 * retry. This only makes sense if any blocking condition
2387 * (i.e. waiting for a lease to be downgraded or removed) is
2388 * gone. This routine here only adds a lease, so it will never
2389 * free up resources that blocked waiters can now claim. So
2390 * that second effect also does not matter in this
2391 * routine. Thus setting lck->data->modified=true does not
2392 * need to be done here.
2395 return NT_STATUS_OK;
2398 static NTSTATUS grant_fsp_lease(struct files_struct *fsp,
2399 struct share_mode_lock *lck,
2400 const struct smb2_lease *lease,
2401 uint32_t granted)
2403 const struct GUID *client_guid = fsp_client_guid(fsp);
2404 NTSTATUS status;
2406 status = try_lease_upgrade(fsp, lck, client_guid, lease, granted);
2408 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
2409 status = grant_new_fsp_lease(
2410 fsp, lck, client_guid, lease, granted);
2413 return status;
2416 static int map_lease_type_to_oplock(uint32_t lease_type)
2418 int result = NO_OPLOCK;
2420 switch (lease_type) {
2421 case SMB2_LEASE_READ|SMB2_LEASE_WRITE|SMB2_LEASE_HANDLE:
2422 result = BATCH_OPLOCK|EXCLUSIVE_OPLOCK;
2423 break;
2424 case SMB2_LEASE_READ|SMB2_LEASE_WRITE:
2425 result = EXCLUSIVE_OPLOCK;
2426 break;
2427 case SMB2_LEASE_READ|SMB2_LEASE_HANDLE:
2428 case SMB2_LEASE_READ:
2429 result = LEVEL_II_OPLOCK;
2430 break;
2433 return result;
2436 struct delay_for_oplock_state {
2437 struct files_struct *fsp;
2438 const struct smb2_lease *lease;
2439 bool will_overwrite;
2440 uint32_t delay_mask;
2441 bool first_open_attempt;
2442 bool got_handle_lease;
2443 bool got_oplock;
2444 bool have_other_lease;
2445 uint32_t total_lease_types;
2446 bool delay;
2449 static bool delay_for_oplock_fn(
2450 struct share_mode_entry *e,
2451 bool *modified,
2452 void *private_data)
2454 struct delay_for_oplock_state *state = private_data;
2455 struct files_struct *fsp = state->fsp;
2456 const struct smb2_lease *lease = state->lease;
2457 bool e_is_lease = (e->op_type == LEASE_OPLOCK);
2458 uint32_t e_lease_type = SMB2_LEASE_NONE;
2459 uint32_t break_to;
2460 bool lease_is_breaking = false;
2462 if (e_is_lease) {
2463 NTSTATUS status;
2465 if (lease != NULL) {
2466 bool our_lease = is_same_lease(fsp, e, lease);
2467 if (our_lease) {
2468 DBG_DEBUG("Ignoring our own lease\n");
2469 return false;
2473 status = leases_db_get(
2474 &e->client_guid,
2475 &e->lease_key,
2476 &fsp->file_id,
2477 &e_lease_type, /* current_state */
2478 &lease_is_breaking,
2479 NULL, /* breaking_to_requested */
2480 NULL, /* breaking_to_required */
2481 NULL, /* lease_version */
2482 NULL); /* epoch */
2485 * leases_db_get() can return NT_STATUS_NOT_FOUND
2486 * if the share_mode_entry e is stale and the
2487 * lease record was already removed. In this case return
2488 * false so the traverse continues.
2491 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND) &&
2492 share_entry_stale_pid(e))
2494 struct GUID_txt_buf guid_strbuf;
2495 struct file_id_buf file_id_strbuf;
2496 DBG_DEBUG("leases_db_get for client_guid [%s] "
2497 "lease_key [%"PRIu64"/%"PRIu64"] "
2498 "file_id [%s] failed for stale "
2499 "share_mode_entry\n",
2500 GUID_buf_string(&e->client_guid, &guid_strbuf),
2501 e->lease_key.data[0],
2502 e->lease_key.data[1],
2503 file_id_str_buf(fsp->file_id, &file_id_strbuf));
2504 return false;
2506 if (!NT_STATUS_IS_OK(status)) {
2507 struct GUID_txt_buf guid_strbuf;
2508 struct file_id_buf file_id_strbuf;
2509 DBG_ERR("leases_db_get for client_guid [%s] "
2510 "lease_key [%"PRIu64"/%"PRIu64"] "
2511 "file_id [%s] failed: %s\n",
2512 GUID_buf_string(&e->client_guid, &guid_strbuf),
2513 e->lease_key.data[0],
2514 e->lease_key.data[1],
2515 file_id_str_buf(fsp->file_id, &file_id_strbuf),
2516 nt_errstr(status));
2517 smb_panic("leases_db_get() failed");
2519 } else {
2520 e_lease_type = get_lease_type(e, fsp->file_id);
2523 if (((e_lease_type & ~state->total_lease_types) != 0) &&
2524 !share_entry_stale_pid(e))
2526 state->total_lease_types |= e_lease_type;
2529 if (!state->got_handle_lease &&
2530 ((e_lease_type & SMB2_LEASE_HANDLE) != 0) &&
2531 !share_entry_stale_pid(e)) {
2532 state->got_handle_lease = true;
2535 if (!state->got_oplock &&
2536 (e->op_type != LEASE_OPLOCK) &&
2537 !share_entry_stale_pid(e)) {
2538 state->got_oplock = true;
2541 if (!state->have_other_lease &&
2542 !is_same_lease(fsp, e, lease) &&
2543 !share_entry_stale_pid(e)) {
2544 state->have_other_lease = true;
2547 if (e_is_lease && is_lease_stat_open(fsp->access_mask)) {
2548 return false;
2551 break_to = e_lease_type & ~state->delay_mask;
2553 if (state->will_overwrite) {
2554 break_to &= ~(SMB2_LEASE_HANDLE|SMB2_LEASE_READ);
2557 DBG_DEBUG("e_lease_type %u, will_overwrite: %u\n",
2558 (unsigned)e_lease_type,
2559 (unsigned)state->will_overwrite);
2561 if ((e_lease_type & ~break_to) == 0) {
2562 if (lease_is_breaking) {
2563 state->delay = true;
2565 return false;
2568 if (share_entry_stale_pid(e)) {
2569 return false;
2572 if (state->will_overwrite) {
2574 * If we break anyway break to NONE directly.
2575 * Otherwise vfs_set_filelen() will trigger the
2576 * break.
2578 break_to &= ~(SMB2_LEASE_READ|SMB2_LEASE_WRITE);
2581 if (!e_is_lease) {
2583 * Oplocks only support breaking to R or NONE.
2585 break_to &= ~(SMB2_LEASE_HANDLE|SMB2_LEASE_WRITE);
2588 DBG_DEBUG("breaking from %d to %d\n",
2589 (int)e_lease_type,
2590 (int)break_to);
2591 send_break_message(
2592 fsp->conn->sconn->msg_ctx, &fsp->file_id, e, break_to);
2593 if (e_lease_type & state->delay_mask) {
2594 state->delay = true;
2596 if (lease_is_breaking && !state->first_open_attempt) {
2597 state->delay = true;
2600 return false;
2603 static NTSTATUS delay_for_oplock(files_struct *fsp,
2604 int oplock_request,
2605 const struct smb2_lease *lease,
2606 struct share_mode_lock *lck,
2607 bool have_sharing_violation,
2608 uint32_t create_disposition,
2609 bool first_open_attempt,
2610 int *poplock_type,
2611 uint32_t *pgranted)
2613 struct delay_for_oplock_state state = {
2614 .fsp = fsp,
2615 .lease = lease,
2616 .first_open_attempt = first_open_attempt,
2618 uint32_t requested;
2619 uint32_t granted;
2620 int oplock_type;
2621 bool ok;
2623 *poplock_type = NO_OPLOCK;
2624 *pgranted = 0;
2626 if (fsp->fsp_flags.is_directory) {
2628 * No directory leases yet
2630 SMB_ASSERT(oplock_request == NO_OPLOCK);
2631 if (have_sharing_violation) {
2632 return NT_STATUS_SHARING_VIOLATION;
2634 return NT_STATUS_OK;
2637 if (oplock_request == LEASE_OPLOCK) {
2638 if (lease == NULL) {
2640 * The SMB2 layer should have checked this
2642 return NT_STATUS_INTERNAL_ERROR;
2645 requested = lease->lease_state;
2646 } else {
2647 requested = map_oplock_to_lease_type(
2648 oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK);
2651 share_mode_flags_get(lck, NULL, NULL, &state.total_lease_types);
2653 if (is_oplock_stat_open(fsp->access_mask)) {
2654 goto grant;
2657 state.delay_mask = have_sharing_violation ?
2658 SMB2_LEASE_HANDLE : SMB2_LEASE_WRITE;
2660 switch (create_disposition) {
2661 case FILE_SUPERSEDE:
2662 case FILE_OVERWRITE:
2663 case FILE_OVERWRITE_IF:
2664 state.will_overwrite = true;
2665 break;
2666 default:
2667 state.will_overwrite = false;
2668 break;
2671 state.total_lease_types = SMB2_LEASE_NONE;
2672 ok = share_mode_forall_entries(lck, delay_for_oplock_fn, &state);
2673 if (!ok) {
2674 return NT_STATUS_INTERNAL_ERROR;
2677 if (state.delay) {
2678 return NT_STATUS_RETRY;
2681 grant:
2682 if (have_sharing_violation) {
2683 return NT_STATUS_SHARING_VIOLATION;
2686 granted = requested;
2688 if (oplock_request == LEASE_OPLOCK) {
2689 if (lp_kernel_oplocks(SNUM(fsp->conn))) {
2690 DEBUG(10, ("No lease granted because kernel oplocks are enabled\n"));
2691 granted = SMB2_LEASE_NONE;
2693 if ((granted & (SMB2_LEASE_READ|SMB2_LEASE_WRITE)) == 0) {
2694 DEBUG(10, ("No read or write lease requested\n"));
2695 granted = SMB2_LEASE_NONE;
2697 if (granted == SMB2_LEASE_WRITE) {
2698 DEBUG(10, ("pure write lease requested\n"));
2699 granted = SMB2_LEASE_NONE;
2701 if (granted == (SMB2_LEASE_WRITE|SMB2_LEASE_HANDLE)) {
2702 DEBUG(10, ("write and handle lease requested\n"));
2703 granted = SMB2_LEASE_NONE;
2707 if (lp_locking(fsp->conn->params) && file_has_brlocks(fsp)) {
2708 DBG_DEBUG("file %s has byte range locks\n",
2709 fsp_str_dbg(fsp));
2710 granted &= ~SMB2_LEASE_READ;
2713 if (state.have_other_lease) {
2715 * Can grant only one writer
2717 granted &= ~SMB2_LEASE_WRITE;
2720 if ((granted & SMB2_LEASE_READ) && !(granted & SMB2_LEASE_WRITE)) {
2721 bool allow_level2 =
2722 (global_client_caps & CAP_LEVEL_II_OPLOCKS) &&
2723 lp_level2_oplocks(SNUM(fsp->conn));
2725 if (!allow_level2) {
2726 granted = SMB2_LEASE_NONE;
2730 if (oplock_request == LEASE_OPLOCK) {
2731 if (state.got_oplock) {
2732 granted &= ~SMB2_LEASE_HANDLE;
2735 oplock_type = LEASE_OPLOCK;
2736 } else {
2737 if (state.got_handle_lease) {
2738 granted = SMB2_LEASE_NONE;
2742 * Reflect possible downgrades from:
2743 * - map_lease_type_to_oplock() => "RH" to just LEVEL_II
2745 oplock_type = map_lease_type_to_oplock(granted);
2746 granted = map_oplock_to_lease_type(oplock_type);
2749 state.total_lease_types |= granted;
2752 uint32_t acc, sh, ls;
2753 share_mode_flags_get(lck, &acc, &sh, &ls);
2754 ls = state.total_lease_types;
2755 share_mode_flags_set(lck, acc, sh, ls, NULL);
2758 DBG_DEBUG("oplock type 0x%x granted (%s%s%s)(0x%x), on file %s, "
2759 "requested 0x%x (%s%s%s)(0x%x) => total (%s%s%s)(0x%x)\n",
2760 fsp->oplock_type,
2761 granted & SMB2_LEASE_READ ? "R":"",
2762 granted & SMB2_LEASE_WRITE ? "W":"",
2763 granted & SMB2_LEASE_HANDLE ? "H":"",
2764 granted,
2765 fsp_str_dbg(fsp),
2766 oplock_request,
2767 requested & SMB2_LEASE_READ ? "R":"",
2768 requested & SMB2_LEASE_WRITE ? "W":"",
2769 requested & SMB2_LEASE_HANDLE ? "H":"",
2770 requested,
2771 state.total_lease_types & SMB2_LEASE_READ ? "R":"",
2772 state.total_lease_types & SMB2_LEASE_WRITE ? "W":"",
2773 state.total_lease_types & SMB2_LEASE_HANDLE ? "H":"",
2774 state.total_lease_types);
2776 *poplock_type = oplock_type;
2777 *pgranted = granted;
2778 return NT_STATUS_OK;
2781 static NTSTATUS handle_share_mode_lease(
2782 files_struct *fsp,
2783 struct share_mode_lock *lck,
2784 uint32_t create_disposition,
2785 uint32_t access_mask,
2786 uint32_t share_access,
2787 int oplock_request,
2788 const struct smb2_lease *lease,
2789 bool first_open_attempt,
2790 int *poplock_type,
2791 uint32_t *pgranted)
2793 bool sharing_violation = false;
2794 NTSTATUS status;
2796 *poplock_type = NO_OPLOCK;
2797 *pgranted = 0;
2799 status = open_mode_check(
2800 fsp->conn, fsp->file_id, lck, access_mask, share_access);
2801 if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
2802 sharing_violation = true;
2803 status = NT_STATUS_OK; /* handled later */
2806 if (!NT_STATUS_IS_OK(status)) {
2807 return status;
2810 if (oplock_request == INTERNAL_OPEN_ONLY) {
2811 if (sharing_violation) {
2812 DBG_DEBUG("Sharing violation for internal open\n");
2813 return NT_STATUS_SHARING_VIOLATION;
2817 * Internal opens never do oplocks or leases. We don't
2818 * need to go through delay_for_oplock().
2820 return NT_STATUS_OK;
2823 status = delay_for_oplock(
2824 fsp,
2825 oplock_request,
2826 lease,
2827 lck,
2828 sharing_violation,
2829 create_disposition,
2830 first_open_attempt,
2831 poplock_type,
2832 pgranted);
2833 if (!NT_STATUS_IS_OK(status)) {
2834 return status;
2837 return NT_STATUS_OK;
2840 static bool request_timed_out(struct smb_request *req, struct timeval timeout)
2842 struct timeval now, end_time;
2843 GetTimeOfDay(&now);
2844 end_time = timeval_sum(&req->request_time, &timeout);
2845 return (timeval_compare(&end_time, &now) < 0);
2848 struct defer_open_state {
2849 struct smbXsrv_connection *xconn;
2850 uint64_t mid;
2853 static void defer_open_done(struct tevent_req *req);
2856 * Defer an open and watch a locking.tdb record
2858 * This defers an open that gets rescheduled once the locking.tdb record watch
2859 * is triggered by a change to the record.
2861 * It is used to defer opens that triggered an oplock break and for the SMB1
2862 * sharing violation delay.
2864 static void defer_open(struct share_mode_lock *lck,
2865 struct timeval timeout,
2866 struct smb_request *req,
2867 struct file_id id)
2869 struct deferred_open_record *open_rec = NULL;
2870 struct timeval abs_timeout;
2871 struct defer_open_state *watch_state;
2872 struct tevent_req *watch_req;
2873 struct timeval_buf tvbuf1, tvbuf2;
2874 struct file_id_buf fbuf;
2875 bool ok;
2877 abs_timeout = timeval_sum(&req->request_time, &timeout);
2879 DBG_DEBUG("request time [%s] timeout [%s] mid [%" PRIu64 "] "
2880 "file_id [%s]\n",
2881 timeval_str_buf(&req->request_time, false, true, &tvbuf1),
2882 timeval_str_buf(&abs_timeout, false, true, &tvbuf2),
2883 req->mid,
2884 file_id_str_buf(id, &fbuf));
2886 open_rec = talloc_zero(NULL, struct deferred_open_record);
2887 if (open_rec == NULL) {
2888 TALLOC_FREE(lck);
2889 exit_server("talloc failed");
2892 watch_state = talloc(open_rec, struct defer_open_state);
2893 if (watch_state == NULL) {
2894 exit_server("talloc failed");
2896 watch_state->xconn = req->xconn;
2897 watch_state->mid = req->mid;
2899 DBG_DEBUG("deferring mid %" PRIu64 "\n", req->mid);
2901 watch_req = share_mode_watch_send(
2902 watch_state,
2903 req->sconn->ev_ctx,
2904 lck,
2905 (struct server_id){0});
2906 if (watch_req == NULL) {
2907 exit_server("Could not watch share mode record");
2909 tevent_req_set_callback(watch_req, defer_open_done, watch_state);
2911 ok = tevent_req_set_endtime(watch_req, req->sconn->ev_ctx, abs_timeout);
2912 if (!ok) {
2913 exit_server("tevent_req_set_endtime failed");
2916 ok = push_deferred_open_message_smb(req, timeout, id, open_rec);
2917 if (!ok) {
2918 TALLOC_FREE(lck);
2919 exit_server("push_deferred_open_message_smb failed");
2923 static void defer_open_done(struct tevent_req *req)
2925 struct defer_open_state *state = tevent_req_callback_data(
2926 req, struct defer_open_state);
2927 NTSTATUS status;
2928 bool ret;
2930 status = share_mode_watch_recv(req, NULL, NULL);
2931 TALLOC_FREE(req);
2932 if (!NT_STATUS_IS_OK(status)) {
2933 DEBUG(5, ("dbwrap_watched_watch_recv returned %s\n",
2934 nt_errstr(status)));
2936 * Even if it failed, retry anyway. TODO: We need a way to
2937 * tell a re-scheduled open about that error.
2941 DEBUG(10, ("scheduling mid %llu\n", (unsigned long long)state->mid));
2943 ret = schedule_deferred_open_message_smb(state->xconn, state->mid);
2944 SMB_ASSERT(ret);
2945 TALLOC_FREE(state);
2949 * Actually attempt the kernel oplock polling open.
2952 static void poll_open_fn(struct tevent_context *ev,
2953 struct tevent_timer *te,
2954 struct timeval current_time,
2955 void *private_data)
2957 struct deferred_open_record *open_rec = talloc_get_type_abort(
2958 private_data, struct deferred_open_record);
2959 bool ok;
2961 TALLOC_FREE(open_rec->watch_req);
2963 ok = schedule_deferred_open_message_smb(
2964 open_rec->xconn, open_rec->mid);
2965 if (!ok) {
2966 exit_server("schedule_deferred_open_message_smb failed");
2968 DBG_DEBUG("timer fired. Retrying open !\n");
2971 static void poll_open_done(struct tevent_req *subreq);
2973 struct poll_open_setup_watcher_state {
2974 TALLOC_CTX *mem_ctx;
2975 struct tevent_context *ev_ctx;
2976 struct tevent_req *watch_req;
2979 static void poll_open_setup_watcher_fn(struct share_mode_lock *lck,
2980 void *private_data)
2982 struct poll_open_setup_watcher_state *state =
2983 (struct poll_open_setup_watcher_state *)private_data;
2985 if (!validate_oplock_types(lck)) {
2986 smb_panic("validate_oplock_types failed");
2989 state->watch_req = share_mode_watch_send(
2990 state->mem_ctx,
2991 state->ev_ctx,
2992 lck,
2993 (struct server_id) {0});
2994 if (state->watch_req == NULL) {
2995 DBG_WARNING("share_mode_watch_send failed\n");
2996 return;
3001 * Reschedule an open for 1 second from now, if not timed out.
3003 static bool setup_poll_open(
3004 struct smb_request *req,
3005 const struct file_id *id,
3006 struct timeval max_timeout,
3007 struct timeval interval)
3009 static struct file_id zero_id = {};
3010 bool ok;
3011 struct deferred_open_record *open_rec = NULL;
3012 struct timeval endtime, next_interval;
3013 struct file_id_buf ftmp;
3015 if (request_timed_out(req, max_timeout)) {
3016 return false;
3019 open_rec = talloc_zero(NULL, struct deferred_open_record);
3020 if (open_rec == NULL) {
3021 DBG_WARNING("talloc failed\n");
3022 return false;
3024 open_rec->xconn = req->xconn;
3025 open_rec->mid = req->mid;
3028 * Make sure open_rec->te does not come later than the
3029 * request's maximum endtime.
3032 endtime = timeval_sum(&req->request_time, &max_timeout);
3033 next_interval = timeval_current_ofs(interval.tv_sec, interval.tv_usec);
3034 next_interval = timeval_min(&endtime, &next_interval);
3036 open_rec->te = tevent_add_timer(
3037 req->sconn->ev_ctx,
3038 open_rec,
3039 next_interval,
3040 poll_open_fn,
3041 open_rec);
3042 if (open_rec->te == NULL) {
3043 DBG_WARNING("tevent_add_timer failed\n");
3044 TALLOC_FREE(open_rec);
3045 return false;
3048 if (id != NULL) {
3049 struct poll_open_setup_watcher_state wstate = {
3050 .mem_ctx = open_rec,
3051 .ev_ctx = req->sconn->ev_ctx,
3053 NTSTATUS status;
3055 status = share_mode_do_locked_vfs_denied(*id,
3056 poll_open_setup_watcher_fn,
3057 &wstate);
3058 if (NT_STATUS_IS_OK(status)) {
3059 if (wstate.watch_req == NULL) {
3060 DBG_WARNING("share_mode_watch_send failed\n");
3061 TALLOC_FREE(open_rec);
3062 return false;
3064 open_rec->watch_req = wstate.watch_req;
3065 tevent_req_set_callback(open_rec->watch_req,
3066 poll_open_done,
3067 open_rec);
3068 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
3069 DBG_WARNING("share_mode_do_locked_vfs_denied failed - %s\n",
3070 nt_errstr(status));
3071 TALLOC_FREE(open_rec);
3072 return false;
3074 } else {
3075 id = &zero_id;
3078 ok = push_deferred_open_message_smb(req, max_timeout, *id, open_rec);
3079 if (!ok) {
3080 DBG_WARNING("push_deferred_open_message_smb failed\n");
3081 TALLOC_FREE(open_rec);
3082 return false;
3085 DBG_DEBUG("poll request time [%s] mid [%" PRIu64 "] file_id [%s]\n",
3086 timeval_string(talloc_tos(), &req->request_time, false),
3087 req->mid,
3088 file_id_str_buf(*id, &ftmp));
3090 return true;
3093 static void poll_open_done(struct tevent_req *subreq)
3095 struct deferred_open_record *open_rec = tevent_req_callback_data(
3096 subreq, struct deferred_open_record);
3097 NTSTATUS status;
3098 bool ok;
3100 status = share_mode_watch_recv(subreq, NULL, NULL);
3101 TALLOC_FREE(subreq);
3102 open_rec->watch_req = NULL;
3103 TALLOC_FREE(open_rec->te);
3105 DBG_DEBUG("dbwrap_watched_watch_recv returned %s\n",
3106 nt_errstr(status));
3108 ok = schedule_deferred_open_message_smb(
3109 open_rec->xconn, open_rec->mid);
3110 if (!ok) {
3111 exit_server("schedule_deferred_open_message_smb failed");
3115 bool defer_smb1_sharing_violation(struct smb_request *req)
3117 bool ok;
3118 int timeout_usecs;
3120 if (!lp_defer_sharing_violations()) {
3121 return false;
3125 * Try every 200msec up to (by default) one second. To be
3126 * precise, according to behaviour note <247> in [MS-CIFS],
3127 * the server tries 5 times. But up to one second should be
3128 * close enough.
3131 timeout_usecs = lp_parm_int(
3132 SNUM(req->conn),
3133 "smbd",
3134 "sharedelay",
3135 SHARING_VIOLATION_USEC_WAIT);
3137 ok = setup_poll_open(
3138 req,
3139 NULL,
3140 (struct timeval) { .tv_usec = timeout_usecs },
3141 (struct timeval) { .tv_usec = 200000 });
3142 return ok;
3145 /****************************************************************************
3146 On overwrite open ensure that the attributes match.
3147 ****************************************************************************/
3149 static bool open_match_attributes(connection_struct *conn,
3150 uint32_t old_dos_attr,
3151 uint32_t new_dos_attr,
3152 mode_t new_unx_mode,
3153 mode_t *returned_unx_mode)
3155 uint32_t noarch_old_dos_attr, noarch_new_dos_attr;
3157 noarch_old_dos_attr = (old_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
3158 noarch_new_dos_attr = (new_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
3160 if((noarch_old_dos_attr == 0 && noarch_new_dos_attr != 0) ||
3161 (noarch_old_dos_attr != 0 && ((noarch_old_dos_attr & noarch_new_dos_attr) == noarch_old_dos_attr))) {
3162 *returned_unx_mode = new_unx_mode;
3163 } else {
3164 *returned_unx_mode = (mode_t)0;
3167 DEBUG(10,("open_match_attributes: old_dos_attr = 0x%x, "
3168 "new_dos_attr = 0x%x "
3169 "returned_unx_mode = 0%o\n",
3170 (unsigned int)old_dos_attr,
3171 (unsigned int)new_dos_attr,
3172 (unsigned int)*returned_unx_mode ));
3174 /* If we're mapping SYSTEM and HIDDEN ensure they match. */
3175 if (lp_map_system(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
3176 if ((old_dos_attr & FILE_ATTRIBUTE_SYSTEM) &&
3177 !(new_dos_attr & FILE_ATTRIBUTE_SYSTEM)) {
3178 return False;
3181 if (lp_map_hidden(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
3182 if ((old_dos_attr & FILE_ATTRIBUTE_HIDDEN) &&
3183 !(new_dos_attr & FILE_ATTRIBUTE_HIDDEN)) {
3184 return False;
3187 return True;
3190 static void schedule_defer_open(struct share_mode_lock *lck,
3191 struct file_id id,
3192 struct smb_request *req)
3194 /* This is a relative time, added to the absolute
3195 request_time value to get the absolute timeout time.
3196 Note that if this is the second or greater time we enter
3197 this codepath for this particular request mid then
3198 request_time is left as the absolute time of the *first*
3199 time this request mid was processed. This is what allows
3200 the request to eventually time out. */
3202 struct timeval timeout;
3204 /* Normally the smbd we asked should respond within
3205 * OPLOCK_BREAK_TIMEOUT seconds regardless of whether
3206 * the client did, give twice the timeout as a safety
3207 * measure here in case the other smbd is stuck
3208 * somewhere else. */
3210 timeout = tevent_timeval_set(OPLOCK_BREAK_TIMEOUT * 2, 0);
3212 if (request_timed_out(req, timeout)) {
3213 return;
3216 defer_open(lck, timeout, req, id);
3219 /****************************************************************************
3220 Reschedule an open call that went asynchronous.
3221 ****************************************************************************/
3223 static void schedule_async_open_timer(struct tevent_context *ev,
3224 struct tevent_timer *te,
3225 struct timeval current_time,
3226 void *private_data)
3228 exit_server("async open timeout");
3231 static void schedule_async_open(struct smb_request *req)
3233 struct deferred_open_record *open_rec = NULL;
3234 struct timeval timeout = tevent_timeval_set(20, 0);
3235 bool ok;
3237 if (request_timed_out(req, timeout)) {
3238 return;
3241 open_rec = talloc_zero(NULL, struct deferred_open_record);
3242 if (open_rec == NULL) {
3243 exit_server("deferred_open_record_create failed");
3245 open_rec->async_open = true;
3247 ok = push_deferred_open_message_smb(
3248 req, timeout, (struct file_id){0}, open_rec);
3249 if (!ok) {
3250 exit_server("push_deferred_open_message_smb failed");
3253 open_rec->te = tevent_add_timer(req->sconn->ev_ctx,
3254 req,
3255 timeval_current_ofs(20, 0),
3256 schedule_async_open_timer,
3257 open_rec);
3258 if (open_rec->te == NULL) {
3259 exit_server("tevent_add_timer failed");
3263 static NTSTATUS check_and_store_share_mode(
3264 struct files_struct *fsp,
3265 struct smb_request *req,
3266 struct share_mode_lock *lck,
3267 uint32_t create_disposition,
3268 uint32_t access_mask,
3269 uint32_t share_access,
3270 int oplock_request,
3271 const struct smb2_lease *lease,
3272 bool first_open_attempt)
3274 NTSTATUS status;
3275 int oplock_type = NO_OPLOCK;
3276 uint32_t granted_lease = 0;
3277 const struct smb2_lease_key *lease_key = NULL;
3278 bool delete_on_close;
3279 bool ok;
3281 /* Get the types we need to examine. */
3282 if (!validate_oplock_types(lck)) {
3283 smb_panic("validate_oplock_types failed");
3286 delete_on_close = has_delete_on_close(lck, fsp->name_hash);
3287 if (delete_on_close) {
3288 return NT_STATUS_DELETE_PENDING;
3291 status = handle_share_mode_lease(fsp,
3292 lck,
3293 create_disposition,
3294 access_mask,
3295 share_access,
3296 oplock_request,
3297 lease,
3298 first_open_attempt,
3299 &oplock_type,
3300 &granted_lease);
3301 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
3302 schedule_defer_open(lck, fsp->file_id, req);
3303 return NT_STATUS_SHARING_VIOLATION;
3305 if (!NT_STATUS_IS_OK(status)) {
3306 return status;
3309 if (oplock_type == LEASE_OPLOCK) {
3310 lease_key = &lease->lease_key;
3313 share_mode_flags_restrict(lck, access_mask, share_access, 0);
3315 ok = set_share_mode(lck,
3316 fsp,
3317 get_current_uid(fsp->conn),
3318 req ? req->mid : 0,
3319 oplock_type,
3320 lease_key,
3321 share_access,
3322 access_mask);
3323 if (!ok) {
3324 return NT_STATUS_NO_MEMORY;
3327 if (oplock_type == LEASE_OPLOCK) {
3328 status = grant_fsp_lease(fsp, lck, lease, granted_lease);
3329 if (!NT_STATUS_IS_OK(status)) {
3330 del_share_mode(lck, fsp);
3331 return status;
3334 DBG_DEBUG("lease_state=%d\n", fsp->lease->lease.lease_state);
3337 fsp->oplock_type = oplock_type;
3339 return NT_STATUS_OK;
3342 /****************************************************************************
3343 Work out what access_mask to use from what the client sent us.
3344 ****************************************************************************/
3346 static NTSTATUS smbd_calculate_maximum_allowed_access_fsp(
3347 struct files_struct *dirfsp,
3348 struct files_struct *fsp,
3349 bool use_privs,
3350 uint32_t *p_access_mask)
3352 struct security_descriptor *sd = NULL;
3353 uint32_t access_granted = 0;
3354 uint32_t dosattrs;
3355 NTSTATUS status;
3357 /* Cope with symlinks */
3358 if (fsp == NULL || fsp_get_pathref_fd(fsp) == -1) {
3359 *p_access_mask = FILE_GENERIC_ALL;
3360 return NT_STATUS_OK;
3363 /* Cope with fake/printer fsp's. */
3364 if (fsp->fake_file_handle != NULL || fsp->print_file != NULL) {
3365 *p_access_mask = FILE_GENERIC_ALL;
3366 return NT_STATUS_OK;
3369 if (!use_privs && (get_current_uid(fsp->conn) == (uid_t)0)) {
3370 *p_access_mask |= FILE_GENERIC_ALL;
3371 return NT_STATUS_OK;
3374 status = SMB_VFS_FGET_NT_ACL(metadata_fsp(fsp),
3375 (SECINFO_OWNER |
3376 SECINFO_GROUP |
3377 SECINFO_DACL),
3378 talloc_tos(),
3379 &sd);
3381 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
3383 * File did not exist
3385 *p_access_mask = FILE_GENERIC_ALL;
3386 return NT_STATUS_OK;
3388 if (!NT_STATUS_IS_OK(status)) {
3389 DBG_ERR("Could not get acl on file %s: %s\n",
3390 fsp_str_dbg(fsp),
3391 nt_errstr(status));
3392 return status;
3396 * If we can access the path to this file, by
3397 * default we have FILE_READ_ATTRIBUTES from the
3398 * containing directory. See the section:
3399 * "Algorithm to Check Access to an Existing File"
3400 * in MS-FSA.pdf.
3402 * se_file_access_check()
3403 * also takes care of owner WRITE_DAC and READ_CONTROL.
3405 status = se_file_access_check(sd,
3406 get_current_nttok(fsp->conn),
3407 use_privs,
3408 (*p_access_mask & ~FILE_READ_ATTRIBUTES),
3409 &access_granted);
3411 TALLOC_FREE(sd);
3413 if (!NT_STATUS_IS_OK(status)) {
3414 DBG_ERR("Status %s on file %s: "
3415 "when calculating maximum access\n",
3416 nt_errstr(status),
3417 fsp_str_dbg(fsp));
3418 return status;
3421 *p_access_mask = (access_granted | FILE_READ_ATTRIBUTES);
3423 if (!(access_granted & DELETE_ACCESS)) {
3424 if (can_delete_file_in_directory(fsp->conn,
3425 dirfsp,
3426 fsp->fsp_name)) {
3427 *p_access_mask |= DELETE_ACCESS;
3431 dosattrs = fdos_mode(fsp);
3432 if ((dosattrs & FILE_ATTRIBUTE_READONLY) || !CAN_WRITE(fsp->conn)) {
3433 *p_access_mask &= ~(FILE_GENERIC_WRITE | DELETE_ACCESS);
3436 return NT_STATUS_OK;
3439 NTSTATUS smbd_calculate_access_mask_fsp(struct files_struct *dirfsp,
3440 struct files_struct *fsp,
3441 bool use_privs,
3442 uint32_t access_mask,
3443 uint32_t *access_mask_out)
3445 NTSTATUS status;
3446 uint32_t orig_access_mask = access_mask;
3447 uint32_t rejected_share_access;
3449 if (access_mask & SEC_MASK_INVALID) {
3450 DBG_DEBUG("access_mask [%8x] contains invalid bits\n",
3451 access_mask);
3452 return NT_STATUS_ACCESS_DENIED;
3456 * Convert GENERIC bits to specific bits.
3459 se_map_generic(&access_mask, &file_generic_mapping);
3461 /* Calculate MAXIMUM_ALLOWED_ACCESS if requested. */
3462 if (access_mask & MAXIMUM_ALLOWED_ACCESS) {
3464 status = smbd_calculate_maximum_allowed_access_fsp(
3465 dirfsp,
3466 fsp,
3467 use_privs,
3468 &access_mask);
3470 if (!NT_STATUS_IS_OK(status)) {
3471 return status;
3474 access_mask &= fsp->conn->share_access;
3477 rejected_share_access = access_mask & ~(fsp->conn->share_access);
3479 if (rejected_share_access) {
3480 DBG_INFO("Access denied on file %s: "
3481 "rejected by share access mask[0x%08X] "
3482 "orig[0x%08X] mapped[0x%08X] reject[0x%08X]\n",
3483 fsp_str_dbg(fsp),
3484 fsp->conn->share_access,
3485 orig_access_mask, access_mask,
3486 rejected_share_access);
3487 return NT_STATUS_ACCESS_DENIED;
3490 *access_mask_out = access_mask;
3491 return NT_STATUS_OK;
3494 /****************************************************************************
3495 Remove the deferred open entry under lock.
3496 ****************************************************************************/
3498 /****************************************************************************
3499 Return true if this is a state pointer to an asynchronous create.
3500 ****************************************************************************/
3502 bool is_deferred_open_async(const struct deferred_open_record *rec)
3504 return rec->async_open;
3507 static bool clear_ads(uint32_t create_disposition)
3509 bool ret = false;
3511 switch (create_disposition) {
3512 case FILE_SUPERSEDE:
3513 case FILE_OVERWRITE_IF:
3514 case FILE_OVERWRITE:
3515 ret = true;
3516 break;
3517 default:
3518 break;
3520 return ret;
3523 static int disposition_to_open_flags(uint32_t create_disposition)
3525 int ret = 0;
3528 * Currently we're using FILE_SUPERSEDE as the same as
3529 * FILE_OVERWRITE_IF but they really are
3530 * different. FILE_SUPERSEDE deletes an existing file
3531 * (requiring delete access) then recreates it.
3534 switch (create_disposition) {
3535 case FILE_SUPERSEDE:
3536 case FILE_OVERWRITE_IF:
3538 * If file exists replace/overwrite. If file doesn't
3539 * exist create.
3541 ret = O_CREAT|O_TRUNC;
3542 break;
3544 case FILE_OPEN:
3546 * If file exists open. If file doesn't exist error.
3548 ret = 0;
3549 break;
3551 case FILE_OVERWRITE:
3553 * If file exists overwrite. If file doesn't exist
3554 * error.
3556 ret = O_TRUNC;
3557 break;
3559 case FILE_CREATE:
3561 * If file exists error. If file doesn't exist create.
3563 ret = O_CREAT|O_EXCL;
3564 break;
3566 case FILE_OPEN_IF:
3568 * If file exists open. If file doesn't exist create.
3570 ret = O_CREAT;
3571 break;
3573 return ret;
3576 static int calculate_open_access_flags(uint32_t access_mask,
3577 uint32_t private_flags,
3578 NTTIME twrp)
3580 bool need_write, need_read;
3583 * Note that we ignore the append flag as append does not
3584 * mean the same thing under DOS and Unix.
3587 if (twrp != 0) {
3589 * Pave over the user requested mode and force O_RDONLY for the
3590 * file handle. Windows allows opening a VSS file with O_RDWR,
3591 * even though actual writes on the handle will fail.
3593 return O_RDONLY;
3596 need_write = (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA));
3597 if (!need_write) {
3598 return O_RDONLY;
3601 /* DENY_DOS opens are always underlying read-write on the
3602 file handle, no matter what the requested access mask
3603 says. */
3605 need_read =
3606 ((private_flags & NTCREATEX_FLAG_DENY_DOS) ||
3607 access_mask & (FILE_READ_ATTRIBUTES|FILE_READ_DATA|
3608 FILE_READ_EA|FILE_EXECUTE));
3610 if (!need_read) {
3611 return O_WRONLY;
3613 return O_RDWR;
3616 struct open_ntcreate_lock_state {
3617 struct share_mode_entry_prepare_state prepare_state;
3618 struct files_struct *fsp;
3619 const char *object_type;
3620 struct smb_request *req;
3621 uint32_t create_disposition;
3622 uint32_t access_mask;
3623 uint32_t share_access;
3624 int oplock_request;
3625 const struct smb2_lease *lease;
3626 bool first_open_attempt;
3627 bool keep_locked;
3628 NTSTATUS status;
3629 struct timespec write_time;
3630 share_mode_entry_prepare_unlock_fn_t cleanup_fn;
3633 static void open_ntcreate_lock_add_entry(struct share_mode_lock *lck,
3634 bool *keep_locked,
3635 void *private_data)
3637 struct open_ntcreate_lock_state *state =
3638 (struct open_ntcreate_lock_state *)private_data;
3641 * By default drop the g_lock again if we leave the
3642 * tdb chainlock.
3644 *keep_locked = false;
3646 state->status = check_and_store_share_mode(state->fsp,
3647 state->req,
3648 lck,
3649 state->create_disposition,
3650 state->access_mask,
3651 state->share_access,
3652 state->oplock_request,
3653 state->lease,
3654 state->first_open_attempt);
3655 if (!NT_STATUS_IS_OK(state->status)) {
3656 return;
3659 state->write_time = get_share_mode_write_time(lck);
3662 * keep the g_lock while existing the tdb chainlock,
3663 * we we're asked to, which mean we'll keep
3664 * the share_mode_lock during object creation,
3665 * or setting delete on close.
3667 *keep_locked = state->keep_locked;
3670 static void open_ntcreate_lock_cleanup_oplock(struct share_mode_lock *lck,
3671 void *private_data)
3673 struct open_ntcreate_lock_state *state =
3674 (struct open_ntcreate_lock_state *)private_data;
3675 bool ok;
3677 ok = remove_share_oplock(lck, state->fsp);
3678 if (!ok) {
3679 DBG_ERR("Could not remove oplock for %s %s\n",
3680 state->object_type, fsp_str_dbg(state->fsp));
3684 static void open_ntcreate_lock_cleanup_entry(struct share_mode_lock *lck,
3685 void *private_data)
3687 struct open_ntcreate_lock_state *state =
3688 (struct open_ntcreate_lock_state *)private_data;
3689 bool ok;
3691 ok = del_share_mode(lck, state->fsp);
3692 if (!ok) {
3693 DBG_ERR("Could not delete share entry for %s %s\n",
3694 state->object_type, fsp_str_dbg(state->fsp));
3698 static void possibly_set_archive(struct connection_struct *conn,
3699 struct files_struct *fsp,
3700 struct smb_filename *smb_fname,
3701 struct smb_filename *parent_dir_fname,
3702 int info,
3703 uint32_t dosattrs,
3704 mode_t *unx_mode)
3706 bool set_archive = false;
3707 int ret;
3709 if (info == FILE_WAS_OPENED) {
3710 return;
3713 /* Overwritten files should be initially set as archive */
3714 if ((info == FILE_WAS_OVERWRITTEN && lp_map_archive(SNUM(conn)))) {
3715 set_archive = true;
3716 } else if (lp_store_dos_attributes(SNUM(conn))) {
3717 set_archive = true;
3719 if (!set_archive) {
3720 return;
3723 ret = file_set_dosmode(conn,
3724 smb_fname,
3725 dosattrs | FILE_ATTRIBUTE_ARCHIVE,
3726 parent_dir_fname,
3727 true);
3728 if (ret != 0) {
3729 return;
3731 *unx_mode = smb_fname->st.st_ex_mode;
3734 /****************************************************************************
3735 Open a file with a share mode. Passed in an already created files_struct *.
3736 ****************************************************************************/
3738 static NTSTATUS open_file_ntcreate(connection_struct *conn,
3739 struct smb_request *req,
3740 uint32_t access_mask, /* access bits (FILE_READ_DATA etc.) */
3741 uint32_t share_access, /* share constants (FILE_SHARE_READ etc) */
3742 uint32_t create_disposition, /* FILE_OPEN_IF etc. */
3743 uint32_t create_options, /* options such as delete on close. */
3744 uint32_t new_dos_attributes, /* attributes used for new file. */
3745 int oplock_request, /* internal Samba oplock codes. */
3746 const struct smb2_lease *lease,
3747 /* Information (FILE_EXISTS etc.) */
3748 uint32_t private_flags, /* Samba specific flags. */
3749 struct smb_filename *parent_dir_fname, /* parent. */
3750 struct smb_filename *smb_fname_atname, /* atname relative to parent. */
3751 int *pinfo,
3752 files_struct *fsp)
3754 struct smb_filename *smb_fname = fsp->fsp_name;
3755 int flags=0;
3756 bool file_existed = VALID_STAT(smb_fname->st);
3757 bool def_acl = False;
3758 bool posix_open = False;
3759 bool new_file_created = False;
3760 bool first_open_attempt = true;
3761 bool is_twrp = (smb_fname_atname->twrp != 0);
3762 NTSTATUS fsp_open = NT_STATUS_ACCESS_DENIED;
3763 mode_t new_unx_mode = (mode_t)0;
3764 mode_t unx_mode = (mode_t)0;
3765 int info;
3766 uint32_t existing_dos_attributes = 0;
3767 struct open_ntcreate_lock_state lck_state = {};
3768 bool keep_locked = false;
3769 uint32_t open_access_mask = access_mask;
3770 NTSTATUS status;
3771 SMB_STRUCT_STAT saved_stat = smb_fname->st;
3772 struct timespec old_write_time;
3773 bool setup_poll = false;
3774 NTSTATUS ulstatus;
3776 if (conn->printer) {
3778 * Printers are handled completely differently.
3779 * Most of the passed parameters are ignored.
3782 if (pinfo) {
3783 *pinfo = FILE_WAS_CREATED;
3786 DBG_DEBUG("printer open fname=%s\n",
3787 smb_fname_str_dbg(smb_fname));
3789 if (!req) {
3790 DBG_ERR("printer open without an SMB request!\n");
3791 return NT_STATUS_INTERNAL_ERROR;
3794 return print_spool_open(fsp, smb_fname->base_name,
3795 req->vuid);
3798 if (new_dos_attributes & FILE_FLAG_POSIX_SEMANTICS) {
3799 posix_open = True;
3800 unx_mode = (mode_t)(new_dos_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
3801 new_dos_attributes = 0;
3802 } else {
3803 /* Windows allows a new file to be created and
3804 silently removes a FILE_ATTRIBUTE_DIRECTORY
3805 sent by the client. Do the same. */
3807 new_dos_attributes &= ~FILE_ATTRIBUTE_DIRECTORY;
3809 /* We add FILE_ATTRIBUTE_ARCHIVE to this as this mode is only used if the file is
3810 * created new. */
3811 unx_mode = unix_mode(
3812 conn,
3813 new_dos_attributes | FILE_ATTRIBUTE_ARCHIVE,
3814 smb_fname,
3815 parent_dir_fname->fsp);
3818 DEBUG(10, ("open_file_ntcreate: fname=%s, dos_attrs=0x%x "
3819 "access_mask=0x%x share_access=0x%x "
3820 "create_disposition = 0x%x create_options=0x%x "
3821 "unix mode=0%o oplock_request=%d private_flags = 0x%x\n",
3822 smb_fname_str_dbg(smb_fname), new_dos_attributes,
3823 access_mask, share_access, create_disposition,
3824 create_options, (unsigned int)unx_mode, oplock_request,
3825 (unsigned int)private_flags));
3827 if (req == NULL) {
3828 /* Ensure req == NULL means INTERNAL_OPEN_ONLY */
3829 SMB_ASSERT(oplock_request == INTERNAL_OPEN_ONLY);
3830 } else {
3831 /* And req != NULL means no INTERNAL_OPEN_ONLY */
3832 SMB_ASSERT(((oplock_request & INTERNAL_OPEN_ONLY) == 0));
3836 * Only non-internal opens can be deferred at all
3839 if (req) {
3840 struct deferred_open_record *open_rec;
3841 if (get_deferred_open_message_state(req, NULL, &open_rec)) {
3843 /* If it was an async create retry, the file
3844 didn't exist. */
3846 if (is_deferred_open_async(open_rec)) {
3847 SET_STAT_INVALID(smb_fname->st);
3848 file_existed = false;
3851 /* Ensure we don't reprocess this message. */
3852 remove_deferred_open_message_smb(req->xconn, req->mid);
3854 first_open_attempt = false;
3858 if (!posix_open) {
3859 new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
3860 if (file_existed) {
3862 * Only use stored DOS attributes for checks
3863 * against requested attributes (below via
3864 * open_match_attributes()), cf bug #11992
3865 * for details. -slow
3867 uint32_t attr = 0;
3869 status = SMB_VFS_FGET_DOS_ATTRIBUTES(
3870 conn,
3871 metadata_fsp(smb_fname->fsp),
3872 &attr);
3873 if (NT_STATUS_IS_OK(status)) {
3874 existing_dos_attributes = attr;
3879 /* ignore any oplock requests if oplocks are disabled */
3880 if (!lp_oplocks(SNUM(conn)) ||
3881 IS_VETO_OPLOCK_PATH(conn, smb_fname->base_name)) {
3882 /* Mask off everything except the private Samba bits. */
3883 oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
3886 /* this is for OS/2 long file names - say we don't support them */
3887 if (req != NULL && !req->posix_pathnames &&
3888 strstr(smb_fname->base_name,".+,;=[].")) {
3889 /* OS/2 Workplace shell fix may be main code stream in a later
3890 * release. */
3891 DEBUG(5,("open_file_ntcreate: OS/2 long filenames are not "
3892 "supported.\n"));
3893 if (use_nt_status()) {
3894 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3896 return NT_STATUS_DOS(ERRDOS, ERRcannotopen);
3899 switch( create_disposition ) {
3900 case FILE_OPEN:
3901 /* If file exists open. If file doesn't exist error. */
3902 if (!file_existed) {
3903 DEBUG(5,("open_file_ntcreate: FILE_OPEN "
3904 "requested for file %s and file "
3905 "doesn't exist.\n",
3906 smb_fname_str_dbg(smb_fname)));
3907 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3909 break;
3911 case FILE_OVERWRITE:
3912 /* If file exists overwrite. If file doesn't exist
3913 * error. */
3914 if (!file_existed) {
3915 DEBUG(5,("open_file_ntcreate: FILE_OVERWRITE "
3916 "requested for file %s and file "
3917 "doesn't exist.\n",
3918 smb_fname_str_dbg(smb_fname) ));
3919 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3921 if (is_twrp) {
3922 return NT_STATUS_MEDIA_WRITE_PROTECTED;
3924 break;
3926 case FILE_CREATE:
3927 /* If file exists error. If file doesn't exist
3928 * create. */
3929 if (file_existed) {
3930 DEBUG(5,("open_file_ntcreate: FILE_CREATE "
3931 "requested for file %s and file "
3932 "already exists.\n",
3933 smb_fname_str_dbg(smb_fname)));
3934 if (S_ISDIR(smb_fname->st.st_ex_mode)) {
3935 return NT_STATUS_FILE_IS_A_DIRECTORY;
3937 return NT_STATUS_OBJECT_NAME_COLLISION;
3939 if (is_twrp) {
3940 return NT_STATUS_MEDIA_WRITE_PROTECTED;
3942 break;
3944 case FILE_SUPERSEDE:
3945 case FILE_OVERWRITE_IF:
3946 if (is_twrp) {
3947 return NT_STATUS_MEDIA_WRITE_PROTECTED;
3949 break;
3950 case FILE_OPEN_IF:
3951 if (is_twrp) {
3952 if (!file_existed) {
3953 return NT_STATUS_MEDIA_WRITE_PROTECTED;
3955 create_disposition = FILE_OPEN;
3957 break;
3958 default:
3959 return NT_STATUS_INVALID_PARAMETER;
3962 flags = disposition_to_open_flags(create_disposition);
3964 /* We only care about matching attributes on file exists and
3965 * overwrite. */
3967 if (!posix_open && file_existed &&
3968 ((create_disposition == FILE_OVERWRITE) ||
3969 (create_disposition == FILE_OVERWRITE_IF))) {
3970 if (!open_match_attributes(conn, existing_dos_attributes,
3971 new_dos_attributes,
3972 unx_mode, &new_unx_mode)) {
3973 DEBUG(5,("open_file_ntcreate: attributes mismatch "
3974 "for file %s (%x %x) (0%o, 0%o)\n",
3975 smb_fname_str_dbg(smb_fname),
3976 existing_dos_attributes,
3977 new_dos_attributes,
3978 (unsigned int)smb_fname->st.st_ex_mode,
3979 (unsigned int)unx_mode ));
3980 return NT_STATUS_ACCESS_DENIED;
3984 status = smbd_calculate_access_mask_fsp(parent_dir_fname->fsp,
3985 smb_fname->fsp,
3986 false,
3987 access_mask,
3988 &access_mask);
3989 if (!NT_STATUS_IS_OK(status)) {
3990 DBG_DEBUG("smbd_calculate_access_mask_fsp "
3991 "on file %s returned %s\n",
3992 smb_fname_str_dbg(smb_fname),
3993 nt_errstr(status));
3994 return status;
3997 open_access_mask = access_mask;
3999 if (flags & O_TRUNC) {
4000 open_access_mask |= FILE_WRITE_DATA; /* This will cause oplock breaks. */
4003 if (file_existed) {
4005 * stat opens on existing files don't get oplocks.
4006 * They can get leases.
4008 * Note that we check for stat open on the *open_access_mask*,
4009 * i.e. the access mask we actually used to do the open,
4010 * not the one the client asked for (which is in
4011 * fsp->access_mask). This is due to the fact that
4012 * FILE_OVERWRITE and FILE_OVERWRITE_IF add in O_TRUNC,
4013 * which adds FILE_WRITE_DATA to open_access_mask.
4015 if (is_oplock_stat_open(open_access_mask) && lease == NULL) {
4016 oplock_request = NO_OPLOCK;
4020 DEBUG(10, ("open_file_ntcreate: fname=%s, after mapping "
4021 "access_mask=0x%x\n", smb_fname_str_dbg(smb_fname),
4022 access_mask));
4025 * Note that we ignore the append flag as append does not
4026 * mean the same thing under DOS and Unix.
4029 flags |= calculate_open_access_flags(access_mask,
4030 private_flags,
4031 smb_fname->twrp);
4034 * Currently we only look at FILE_WRITE_THROUGH for create options.
4037 #if defined(O_SYNC)
4038 if ((create_options & FILE_WRITE_THROUGH) && lp_strict_sync(SNUM(conn))) {
4039 flags |= O_SYNC;
4041 #endif /* O_SYNC */
4043 if (posix_open && (access_mask & FILE_APPEND_DATA)) {
4044 flags |= O_APPEND;
4047 if (!posix_open && !CAN_WRITE(conn)) {
4049 * We should really return a permission denied error if either
4050 * O_CREAT or O_TRUNC are set, but for compatibility with
4051 * older versions of Samba we just AND them out.
4053 flags &= ~(O_CREAT | O_TRUNC);
4057 * With kernel oplocks the open breaking an oplock
4058 * blocks until the oplock holder has given up the
4059 * oplock or closed the file. We prevent this by always
4060 * trying to open the file with O_NONBLOCK (see "man
4061 * fcntl" on Linux).
4063 * If a process that doesn't use the smbd open files
4064 * database or communication methods holds a kernel
4065 * oplock we must periodically poll for available open
4066 * using O_NONBLOCK.
4068 flags |= O_NONBLOCK;
4071 * Ensure we can't write on a read-only share or file.
4074 if (((flags & O_ACCMODE) != O_RDONLY) && file_existed &&
4075 (!CAN_WRITE(conn) ||
4076 (existing_dos_attributes & FILE_ATTRIBUTE_READONLY))) {
4077 DEBUG(5,("open_file_ntcreate: write access requested for "
4078 "file %s on read only %s\n",
4079 smb_fname_str_dbg(smb_fname),
4080 !CAN_WRITE(conn) ? "share" : "file" ));
4081 return NT_STATUS_ACCESS_DENIED;
4084 if (VALID_STAT(smb_fname->st)) {
4086 * Only try and create a file id before open
4087 * for an existing file. For a file being created
4088 * this won't do anything useful until the file
4089 * exists and has a valid stat struct.
4091 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
4093 fh_set_private_options(fsp->fh, private_flags);
4094 fsp->access_mask = open_access_mask; /* We change this to the
4095 * requested access_mask after
4096 * the open is done. */
4097 if (posix_open) {
4098 fsp->posix_flags |= FSP_POSIX_FLAGS_ALL;
4101 if ((create_options & FILE_DELETE_ON_CLOSE) && (flags & O_CREAT) &&
4102 !file_existed) {
4103 /* Delete on close semantics for new files. */
4104 status = can_set_delete_on_close(fsp,
4105 new_dos_attributes);
4106 if (!NT_STATUS_IS_OK(status)) {
4107 fd_close(fsp);
4108 return status;
4113 * Ensure we pay attention to default ACLs on directories if required.
4116 if ((flags & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
4117 (def_acl = directory_has_default_acl_fsp(parent_dir_fname->fsp))) {
4118 unx_mode = (0777 & lp_create_mask(SNUM(conn)));
4121 DEBUG(4,
4122 ("calling open_file with flags=0x%X mode=0%o, "
4123 "access_mask = 0x%x, open_access_mask = 0x%x\n",
4124 (unsigned int)flags,
4125 (unsigned int)unx_mode,
4126 (unsigned int)access_mask,
4127 (unsigned int)open_access_mask));
4130 struct vfs_open_how how = {
4131 .flags = flags,
4132 .mode = unx_mode,
4135 if (create_options & FILE_OPEN_FOR_BACKUP_INTENT) {
4136 how.resolve |= VFS_OPEN_HOW_WITH_BACKUP_INTENT;
4139 fsp_open = open_file(req,
4140 parent_dir_fname->fsp,
4141 smb_fname_atname,
4142 fsp,
4143 &how,
4144 access_mask,
4145 open_access_mask,
4146 private_flags,
4147 &new_file_created);
4149 if (NT_STATUS_EQUAL(fsp_open, NT_STATUS_NETWORK_BUSY)) {
4150 if (file_existed && S_ISFIFO(fsp->fsp_name->st.st_ex_mode)) {
4151 DEBUG(10, ("FIFO busy\n"));
4152 return NT_STATUS_NETWORK_BUSY;
4154 if (req == NULL) {
4155 DEBUG(10, ("Internal open busy\n"));
4156 return NT_STATUS_NETWORK_BUSY;
4159 * This handles the kernel oplock case:
4161 * the file has an active kernel oplock and the open() returned
4162 * EWOULDBLOCK/EAGAIN which maps to NETWORK_BUSY.
4164 * "Samba locking.tdb oplocks" are handled below after acquiring
4165 * the sharemode lock with get_share_mode_lock().
4167 setup_poll = true;
4170 if (NT_STATUS_EQUAL(fsp_open, NT_STATUS_RETRY)) {
4172 * EINTR from the open(2) syscall. Just setup a retry
4173 * in a bit. We can't use the sys_write() tight retry
4174 * loop here, as we might have to actually deal with
4175 * lease-break signals to avoid a deadlock.
4177 setup_poll = true;
4180 if (setup_poll) {
4182 * Retry once a second. If there's a share_mode_lock
4183 * around, also wait for it in case it was smbd
4184 * holding that kernel oplock that can quickly tell us
4185 * the oplock got removed.
4188 setup_poll_open(req,
4189 &fsp->file_id,
4190 tevent_timeval_set(OPLOCK_BREAK_TIMEOUT * 2,
4192 tevent_timeval_set(1, 0));
4194 return NT_STATUS_SHARING_VIOLATION;
4197 if (!NT_STATUS_IS_OK(fsp_open)) {
4198 bool wait_for_aio = NT_STATUS_EQUAL(
4199 fsp_open, NT_STATUS_MORE_PROCESSING_REQUIRED);
4200 if (wait_for_aio) {
4201 schedule_async_open(req);
4203 return fsp_open;
4206 if (new_file_created) {
4208 * As we atomically create using O_CREAT|O_EXCL,
4209 * then if new_file_created is true, then
4210 * file_existed *MUST* have been false (even
4211 * if the file was previously detected as being
4212 * there).
4214 file_existed = false;
4217 if (file_existed && !check_same_dev_ino(&saved_stat, &smb_fname->st)) {
4219 * The file did exist, but some other (local or NFS)
4220 * process either renamed/unlinked and re-created the
4221 * file with different dev/ino after we walked the path,
4222 * but before we did the open. We could retry the
4223 * open but it's a rare enough case it's easier to
4224 * just fail the open to prevent creating any problems
4225 * in the open file db having the wrong dev/ino key.
4227 fd_close(fsp);
4228 DBG_WARNING("file %s - dev/ino mismatch. "
4229 "Old (dev=%ju, ino=%ju). "
4230 "New (dev=%ju, ino=%ju). Failing open "
4231 "with NT_STATUS_ACCESS_DENIED.\n",
4232 smb_fname_str_dbg(smb_fname),
4233 (uintmax_t)saved_stat.st_ex_dev,
4234 (uintmax_t)saved_stat.st_ex_ino,
4235 (uintmax_t)smb_fname->st.st_ex_dev,
4236 (uintmax_t)smb_fname->st.st_ex_ino);
4237 return NT_STATUS_ACCESS_DENIED;
4240 old_write_time = smb_fname->st.st_ex_mtime;
4243 * Deal with the race condition where two smbd's detect the
4244 * file doesn't exist and do the create at the same time. One
4245 * of them will win and set a share mode, the other (ie. this
4246 * one) should check if the requested share mode for this
4247 * create is allowed.
4251 * Now the file exists and fsp is successfully opened,
4252 * fsp->dev and fsp->inode are valid and should replace the
4253 * dev=0,inode=0 from a non existent file. Spotted by
4254 * Nadav Danieli <nadavd@exanet.com>. JRA.
4257 if (new_file_created) {
4258 info = FILE_WAS_CREATED;
4259 } else {
4260 if (flags & O_TRUNC) {
4261 info = FILE_WAS_OVERWRITTEN;
4262 } else {
4263 info = FILE_WAS_OPENED;
4268 * If we created a new file, overwrite an existing one
4269 * or going to delete it later, we should keep
4270 * the share_mode_lock (g_lock) until we call
4271 * share_mode_entry_prepare_unlock()
4273 if (info != FILE_WAS_OPENED) {
4274 keep_locked = true;
4275 } else if (create_options & FILE_DELETE_ON_CLOSE) {
4276 keep_locked = true;
4279 lck_state = (struct open_ntcreate_lock_state) {
4280 .fsp = fsp,
4281 .object_type = "file",
4282 .req = req,
4283 .create_disposition = create_disposition,
4284 .access_mask = access_mask,
4285 .share_access = share_access,
4286 .oplock_request = oplock_request,
4287 .lease = lease,
4288 .first_open_attempt = first_open_attempt,
4289 .keep_locked = keep_locked,
4292 status = share_mode_entry_prepare_lock_add(&lck_state.prepare_state,
4293 fsp->file_id,
4294 conn->connectpath,
4295 smb_fname,
4296 &old_write_time,
4297 open_ntcreate_lock_add_entry,
4298 &lck_state);
4299 if (!NT_STATUS_IS_OK(status)) {
4300 DBG_ERR("share_mode_entry_prepare_lock_add() failed for %s - %s\n",
4301 smb_fname_str_dbg(smb_fname), nt_errstr(status));
4302 fd_close(fsp);
4303 return status;
4306 status = lck_state.status;
4307 if (!NT_STATUS_IS_OK(status)) {
4308 fd_close(fsp);
4309 return status;
4313 * From here we need to use 'goto unlock;' instead of return !!!
4316 if (fsp->oplock_type != NO_OPLOCK && fsp->oplock_type != LEASE_OPLOCK) {
4318 * Now ask for kernel oplocks
4319 * and cleanup on failure.
4321 status = set_file_oplock(fsp);
4322 if (!NT_STATUS_IS_OK(status)) {
4324 * Could not get the kernel oplock
4326 lck_state.cleanup_fn =
4327 open_ntcreate_lock_cleanup_oplock;
4328 fsp->oplock_type = NO_OPLOCK;
4332 /* Should we atomically (to the client at least) truncate ? */
4333 if ((!new_file_created) && (flags & O_TRUNC) &&
4334 (S_ISREG(fsp->fsp_name->st.st_ex_mode))) {
4335 int ret;
4337 ret = SMB_VFS_FTRUNCATE(fsp, 0);
4338 if (ret != 0) {
4339 status = map_nt_error_from_unix(errno);
4340 lck_state.cleanup_fn =
4341 open_ntcreate_lock_cleanup_entry;
4342 goto unlock;
4344 notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
4345 FILE_NOTIFY_CHANGE_SIZE
4346 | FILE_NOTIFY_CHANGE_ATTRIBUTES,
4347 fsp->fsp_name->base_name);
4351 * We have the share entry *locked*.....
4354 /* Delete streams if create_disposition requires it */
4355 if (!new_file_created &&
4356 clear_ads(create_disposition) &&
4357 !fsp_is_alternate_stream(fsp)) {
4358 status = delete_all_streams(conn, smb_fname);
4359 if (!NT_STATUS_IS_OK(status)) {
4360 lck_state.cleanup_fn =
4361 open_ntcreate_lock_cleanup_entry;
4362 goto unlock;
4366 if (!fsp->fsp_flags.is_pathref &&
4367 fsp_get_io_fd(fsp) != -1 &&
4368 lp_kernel_share_modes(SNUM(conn)))
4370 int ret;
4372 * Beware: streams implementing VFS modules may
4373 * implement streams in a way that fsp will have the
4374 * basefile open in the fsp fd, so lacking a distinct
4375 * fd for the stream the file-system sharemode will
4376 * apply on the basefile which is wrong. The actual
4377 * check is deferred to the VFS module implementing
4378 * the file-system sharemode call.
4380 ret = SMB_VFS_FILESYSTEM_SHAREMODE(fsp,
4381 share_access,
4382 access_mask);
4383 if (ret == -1){
4384 status = NT_STATUS_SHARING_VIOLATION;
4385 lck_state.cleanup_fn =
4386 open_ntcreate_lock_cleanup_entry;
4387 goto unlock;
4390 fsp->fsp_flags.kernel_share_modes_taken = true;
4394 * At this point onwards, we can guarantee that the share entry
4395 * is locked, whether we created the file or not, and that the
4396 * deny mode is compatible with all current opens.
4400 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
4401 * but we don't have to store this - just ignore it on access check.
4403 if (conn_using_smb2(conn->sconn)) {
4405 * SMB2 doesn't return it (according to Microsoft tests).
4406 * Test Case: TestSuite_ScenarioNo009GrantedAccessTestS0
4407 * File created with access = 0x7 (Read, Write, Delete)
4408 * Query Info on file returns 0x87 (Read, Write, Delete, Read Attributes)
4410 fsp->access_mask = access_mask;
4411 } else {
4412 /* But SMB1 does. */
4413 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
4416 if (pinfo) {
4417 *pinfo = info;
4420 /* Handle strange delete on close create semantics. */
4421 if (create_options & FILE_DELETE_ON_CLOSE) {
4422 if (!new_file_created) {
4423 status = can_set_delete_on_close(fsp,
4424 existing_dos_attributes);
4426 if (!NT_STATUS_IS_OK(status)) {
4427 /* Remember to delete the mode we just added. */
4428 lck_state.cleanup_fn =
4429 open_ntcreate_lock_cleanup_entry;
4430 goto unlock;
4433 /* Note that here we set the *initial* delete on close flag,
4434 not the regular one. The magic gets handled in close. */
4435 fsp->fsp_flags.initial_delete_on_close = true;
4438 possibly_set_archive(conn,
4439 fsp,
4440 smb_fname,
4441 parent_dir_fname,
4442 info,
4443 new_dos_attributes,
4444 &smb_fname->st.st_ex_mode);
4446 /* Determine sparse flag. */
4447 if (posix_open) {
4448 /* POSIX opens are sparse by default. */
4449 fsp->fsp_flags.is_sparse = true;
4450 } else {
4451 fsp->fsp_flags.is_sparse =
4452 (existing_dos_attributes & FILE_ATTRIBUTE_SPARSE);
4456 * Take care of inherited ACLs on created files - if default ACL not
4457 * selected.
4460 if (!posix_open && new_file_created && !def_acl) {
4461 if (unx_mode != smb_fname->st.st_ex_mode) {
4462 int ret = SMB_VFS_FCHMOD(fsp, unx_mode);
4463 if (ret == -1) {
4464 DBG_INFO("failed to reset "
4465 "attributes of file %s to 0%o\n",
4466 smb_fname_str_dbg(smb_fname),
4467 (unsigned int)unx_mode);
4471 } else if (new_unx_mode) {
4473 * We only get here in the case of:
4475 * a). Not a POSIX open.
4476 * b). File already existed.
4477 * c). File was overwritten.
4478 * d). Requested DOS attributes didn't match
4479 * the DOS attributes on the existing file.
4481 * In that case new_unx_mode has been set
4482 * equal to the calculated mode (including
4483 * possible inheritance of the mode from the
4484 * containing directory).
4486 * Note this mode was calculated with the
4487 * DOS attribute FILE_ATTRIBUTE_ARCHIVE added,
4488 * so the mode change here is suitable for
4489 * an overwritten file.
4492 if (new_unx_mode != smb_fname->st.st_ex_mode) {
4493 int ret = SMB_VFS_FCHMOD(fsp, new_unx_mode);
4494 if (ret == -1) {
4495 DBG_INFO("failed to reset "
4496 "attributes of file %s to 0%o\n",
4497 smb_fname_str_dbg(smb_fname),
4498 (unsigned int)new_unx_mode);
4504 * Deal with other opens having a modified write time.
4506 if (fsp_getinfo_ask_sharemode(fsp) &&
4507 !is_omit_timespec(&lck_state.write_time))
4509 update_stat_ex_mtime(&fsp->fsp_name->st, lck_state.write_time);
4512 status = NT_STATUS_OK;
4514 unlock:
4515 ulstatus = share_mode_entry_prepare_unlock(&lck_state.prepare_state,
4516 lck_state.cleanup_fn,
4517 &lck_state);
4518 if (!NT_STATUS_IS_OK(ulstatus)) {
4519 DBG_ERR("share_mode_entry_prepare_unlock() failed for %s - %s\n",
4520 smb_fname_str_dbg(smb_fname), nt_errstr(ulstatus));
4521 smb_panic("share_mode_entry_prepare_unlock() failed!");
4524 if (!NT_STATUS_IS_OK(status)) {
4525 fd_close(fsp);
4526 return status;
4529 return NT_STATUS_OK;
4532 static NTSTATUS mkdir_internal(connection_struct *conn,
4533 struct smb_filename *parent_dir_fname, /* parent. */
4534 struct smb_filename *smb_fname_atname, /* atname relative to parent. */
4535 struct smb_filename *smb_dname, /* full pathname from root of share. */
4536 uint32_t file_attributes,
4537 struct files_struct *fsp)
4539 const struct loadparm_substitution *lp_sub =
4540 loadparm_s3_global_substitution();
4541 mode_t mode;
4542 NTSTATUS status;
4543 bool posix_open = false;
4544 bool need_re_stat = false;
4545 uint32_t access_mask = SEC_DIR_ADD_SUBDIR;
4546 struct vfs_open_how how = { .flags = O_RDONLY|O_DIRECTORY, };
4547 int ret;
4549 if (!CAN_WRITE(conn) || (access_mask & ~(conn->share_access))) {
4550 DEBUG(5,("mkdir_internal: failing share access "
4551 "%s\n", lp_servicename(talloc_tos(), lp_sub, SNUM(conn))));
4552 return NT_STATUS_ACCESS_DENIED;
4555 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
4556 posix_open = true;
4557 mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
4558 } else {
4559 mode = unix_mode(conn,
4560 FILE_ATTRIBUTE_DIRECTORY,
4561 smb_dname,
4562 parent_dir_fname->fsp);
4565 status = check_parent_access_fsp(parent_dir_fname->fsp, access_mask);
4566 if(!NT_STATUS_IS_OK(status)) {
4567 DBG_INFO("check_parent_access_fsp "
4568 "on directory %s for path %s returned %s\n",
4569 smb_fname_str_dbg(parent_dir_fname),
4570 smb_dname->base_name,
4571 nt_errstr(status));
4572 return status;
4575 if (lp_inherit_acls(SNUM(conn))) {
4576 if (directory_has_default_acl_fsp(parent_dir_fname->fsp)) {
4577 mode = (0777 & lp_directory_mask(SNUM(conn)));
4581 ret = SMB_VFS_MKDIRAT(conn,
4582 parent_dir_fname->fsp,
4583 smb_fname_atname,
4584 mode);
4585 if (ret != 0) {
4586 return map_nt_error_from_unix(errno);
4590 * Make this a pathref fsp for now. open_directory() will reopen as a
4591 * full fsp.
4593 fsp->fsp_flags.is_pathref = true;
4595 status = fd_openat(parent_dir_fname->fsp, smb_fname_atname, fsp, &how);
4596 if (!NT_STATUS_IS_OK(status)) {
4597 return status;
4600 /* Ensure we're checking for a symlink here.... */
4601 /* We don't want to get caught by a symlink racer. */
4603 status = vfs_stat_fsp(fsp);
4604 if (!NT_STATUS_IS_OK(status)) {
4605 DEBUG(2, ("Could not stat directory '%s' just created: %s\n",
4606 smb_fname_str_dbg(smb_dname), nt_errstr(status)));
4607 return status;
4610 if (!S_ISDIR(smb_dname->st.st_ex_mode)) {
4611 DEBUG(0, ("Directory '%s' just created is not a directory !\n",
4612 smb_fname_str_dbg(smb_dname)));
4613 return NT_STATUS_NOT_A_DIRECTORY;
4616 if (lp_store_dos_attributes(SNUM(conn))) {
4617 file_set_dosmode(conn,
4618 smb_dname,
4619 file_attributes | FILE_ATTRIBUTE_DIRECTORY,
4620 parent_dir_fname,
4621 true);
4624 if (lp_inherit_permissions(SNUM(conn))) {
4625 inherit_access_posix_acl(conn, parent_dir_fname->fsp,
4626 smb_dname, mode);
4627 need_re_stat = true;
4630 if (!posix_open) {
4632 * Check if high bits should have been set,
4633 * then (if bits are missing): add them.
4634 * Consider bits automagically set by UNIX, i.e. SGID bit from parent
4635 * dir.
4637 if ((mode & ~(S_IRWXU|S_IRWXG|S_IRWXO)) &&
4638 (mode & ~smb_dname->st.st_ex_mode)) {
4639 SMB_VFS_FCHMOD(fsp,
4640 (smb_dname->st.st_ex_mode |
4641 (mode & ~smb_dname->st.st_ex_mode)));
4642 need_re_stat = true;
4646 /* Change the owner if required. */
4647 if (lp_inherit_owner(SNUM(conn)) != INHERIT_OWNER_NO) {
4648 change_dir_owner_to_parent_fsp(parent_dir_fname->fsp,
4649 fsp);
4650 need_re_stat = true;
4653 if (need_re_stat) {
4654 status = vfs_stat_fsp(fsp);
4655 if (!NT_STATUS_IS_OK(status)) {
4656 DEBUG(2, ("Could not stat directory '%s' just created: %s\n",
4657 smb_fname_str_dbg(smb_dname), nt_errstr(status)));
4658 return status;
4662 notify_fname(conn, NOTIFY_ACTION_ADDED, FILE_NOTIFY_CHANGE_DIR_NAME,
4663 smb_dname->base_name);
4665 return NT_STATUS_OK;
4668 /****************************************************************************
4669 Open a directory from an NT SMB call.
4670 ****************************************************************************/
4672 static NTSTATUS open_directory(connection_struct *conn,
4673 struct smb_request *req,
4674 uint32_t access_mask,
4675 uint32_t share_access,
4676 uint32_t create_disposition,
4677 uint32_t create_options,
4678 uint32_t file_attributes,
4679 struct smb_filename *parent_dir_fname,
4680 struct smb_filename *smb_fname_atname,
4681 int *pinfo,
4682 struct files_struct *fsp)
4684 struct smb_filename *smb_dname = fsp->fsp_name;
4685 bool dir_existed = VALID_STAT(smb_dname->st);
4686 struct open_ntcreate_lock_state lck_state = {};
4687 bool keep_locked = false;
4688 NTSTATUS status;
4689 struct timespec mtimespec;
4690 int info = 0;
4691 uint32_t need_fd_access;
4692 NTSTATUS ulstatus;
4694 if (is_ntfs_stream_smb_fname(smb_dname)) {
4695 DEBUG(2, ("open_directory: %s is a stream name!\n",
4696 smb_fname_str_dbg(smb_dname)));
4697 return NT_STATUS_NOT_A_DIRECTORY;
4700 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS)) {
4701 /* Ensure we have a directory attribute. */
4702 file_attributes |= FILE_ATTRIBUTE_DIRECTORY;
4705 DBG_INFO("opening directory %s, access_mask = 0x%"PRIx32", "
4706 "share_access = 0x%"PRIx32" create_options = 0x%"PRIx32", "
4707 "create_disposition = 0x%"PRIx32", "
4708 "file_attributes = 0x%"PRIx32"\n",
4709 smb_fname_str_dbg(smb_dname),
4710 access_mask,
4711 share_access,
4712 create_options,
4713 create_disposition,
4714 file_attributes);
4716 status = smbd_calculate_access_mask_fsp(parent_dir_fname->fsp,
4717 smb_dname->fsp,
4718 false,
4719 access_mask,
4720 &access_mask);
4721 if (!NT_STATUS_IS_OK(status)) {
4722 DBG_DEBUG("smbd_calculate_access_mask_fsp "
4723 "on file %s returned %s\n",
4724 smb_fname_str_dbg(smb_dname),
4725 nt_errstr(status));
4726 return status;
4729 if ((access_mask & SEC_FLAG_SYSTEM_SECURITY) &&
4730 !security_token_has_privilege(get_current_nttok(conn),
4731 SEC_PRIV_SECURITY)) {
4732 DEBUG(10, ("open_directory: open on %s "
4733 "failed - SEC_FLAG_SYSTEM_SECURITY denied.\n",
4734 smb_fname_str_dbg(smb_dname)));
4735 return NT_STATUS_PRIVILEGE_NOT_HELD;
4738 switch( create_disposition ) {
4739 case FILE_OPEN:
4741 if (!dir_existed) {
4742 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4745 info = FILE_WAS_OPENED;
4746 break;
4748 case FILE_CREATE:
4750 /* If directory exists error. If directory doesn't
4751 * exist create. */
4753 if (dir_existed) {
4754 status = NT_STATUS_OBJECT_NAME_COLLISION;
4755 DEBUG(2, ("open_directory: unable to create "
4756 "%s. Error was %s\n",
4757 smb_fname_str_dbg(smb_dname),
4758 nt_errstr(status)));
4759 return status;
4762 if (smb_fname_atname->twrp != 0) {
4763 return NT_STATUS_MEDIA_WRITE_PROTECTED;
4766 status = mkdir_internal(conn,
4767 parent_dir_fname,
4768 smb_fname_atname,
4769 smb_dname,
4770 file_attributes,
4771 fsp);
4773 if (!NT_STATUS_IS_OK(status)) {
4774 DEBUG(2, ("open_directory: unable to create "
4775 "%s. Error was %s\n",
4776 smb_fname_str_dbg(smb_dname),
4777 nt_errstr(status)));
4778 return status;
4781 info = FILE_WAS_CREATED;
4782 break;
4784 case FILE_OPEN_IF:
4786 * If directory exists open. If directory doesn't
4787 * exist create.
4790 if (dir_existed) {
4791 status = NT_STATUS_OK;
4792 info = FILE_WAS_OPENED;
4793 } else {
4794 if (smb_fname_atname->twrp != 0) {
4795 return NT_STATUS_MEDIA_WRITE_PROTECTED;
4797 status = mkdir_internal(conn,
4798 parent_dir_fname,
4799 smb_fname_atname,
4800 smb_dname,
4801 file_attributes,
4802 fsp);
4804 if (NT_STATUS_IS_OK(status)) {
4805 info = FILE_WAS_CREATED;
4806 } else {
4807 int ret;
4808 /* Cope with create race. */
4809 if (!NT_STATUS_EQUAL(status,
4810 NT_STATUS_OBJECT_NAME_COLLISION)) {
4811 DEBUG(2, ("open_directory: unable to create "
4812 "%s. Error was %s\n",
4813 smb_fname_str_dbg(smb_dname),
4814 nt_errstr(status)));
4815 return status;
4819 * If mkdir_internal() returned
4820 * NT_STATUS_OBJECT_NAME_COLLISION
4821 * we still must lstat the path.
4823 ret = SMB_VFS_FSTATAT(
4824 conn,
4825 parent_dir_fname->fsp,
4826 smb_fname_atname,
4827 &smb_dname->st,
4828 AT_SYMLINK_NOFOLLOW);
4829 if (ret == -1) {
4830 DEBUG(2, ("Could not stat "
4831 "directory '%s' just "
4832 "opened: %s\n",
4833 smb_fname_str_dbg(
4834 smb_dname),
4835 strerror(errno)));
4836 return map_nt_error_from_unix(
4837 errno);
4840 info = FILE_WAS_OPENED;
4844 break;
4846 case FILE_SUPERSEDE:
4847 case FILE_OVERWRITE:
4848 case FILE_OVERWRITE_IF:
4849 default:
4850 DEBUG(5,("open_directory: invalid create_disposition "
4851 "0x%x for directory %s\n",
4852 (unsigned int)create_disposition,
4853 smb_fname_str_dbg(smb_dname)));
4854 return NT_STATUS_INVALID_PARAMETER;
4857 if(!S_ISDIR(smb_dname->st.st_ex_mode)) {
4858 DEBUG(5,("open_directory: %s is not a directory !\n",
4859 smb_fname_str_dbg(smb_dname)));
4860 return NT_STATUS_NOT_A_DIRECTORY;
4864 * Setup the files_struct for it.
4867 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_dname->st);
4868 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
4869 fsp->file_pid = req ? req->smbpid : 0;
4870 fsp->fsp_flags.can_lock = false;
4871 fsp->fsp_flags.can_read = false;
4872 fsp->fsp_flags.can_write = false;
4874 fh_set_private_options(fsp->fh, 0);
4876 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
4878 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
4879 fsp->print_file = NULL;
4880 fsp->fsp_flags.modified = false;
4881 fsp->oplock_type = NO_OPLOCK;
4882 fsp->sent_oplock_break = NO_BREAK_SENT;
4883 fsp->fsp_flags.is_directory = true;
4884 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
4885 fsp->posix_flags |= FSP_POSIX_FLAGS_ALL;
4888 /* Don't store old timestamps for directory
4889 handles in the internal database. We don't
4890 update them in there if new objects
4891 are created in the directory. Currently
4892 we only update timestamps on file writes.
4893 See bug #9870.
4895 mtimespec = make_omit_timespec();
4898 * Obviously for FILE_LIST_DIRECTORY we need to reopen to get an fd
4899 * usable for reading a directory. SMB2_FLUSH may be called on
4900 * directories opened with FILE_ADD_FILE and FILE_ADD_SUBDIRECTORY so
4901 * for those we need to reopen as well.
4903 need_fd_access =
4904 FILE_LIST_DIRECTORY |
4905 FILE_ADD_FILE |
4906 FILE_ADD_SUBDIRECTORY;
4908 if (access_mask & need_fd_access) {
4909 struct vfs_open_how how = {
4910 .flags = O_RDONLY | O_DIRECTORY,
4912 bool file_created;
4914 status = reopen_from_fsp(parent_dir_fname->fsp,
4915 smb_fname_atname,
4916 fsp,
4917 &how,
4918 &file_created);
4919 if (!NT_STATUS_IS_OK(status)) {
4920 DBG_INFO("Could not open fd for [%s]: %s\n",
4921 smb_fname_str_dbg(smb_dname),
4922 nt_errstr(status));
4923 return status;
4927 status = vfs_stat_fsp(fsp);
4928 if (!NT_STATUS_IS_OK(status)) {
4929 fd_close(fsp);
4930 return status;
4933 if(!S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
4934 DEBUG(5,("open_directory: %s is not a directory !\n",
4935 smb_fname_str_dbg(smb_dname)));
4936 fd_close(fsp);
4937 return NT_STATUS_NOT_A_DIRECTORY;
4940 /* Ensure there was no race condition. We need to check
4941 * dev/inode but not permissions, as these can change
4942 * legitimately */
4943 if (!check_same_dev_ino(&smb_dname->st, &fsp->fsp_name->st)) {
4944 DEBUG(5,("open_directory: stat struct differs for "
4945 "directory %s.\n",
4946 smb_fname_str_dbg(smb_dname)));
4947 fd_close(fsp);
4948 return NT_STATUS_ACCESS_DENIED;
4951 if (info == FILE_WAS_OPENED) {
4952 status = smbd_check_access_rights_fsp(parent_dir_fname->fsp,
4953 fsp,
4954 false,
4955 access_mask);
4956 if (!NT_STATUS_IS_OK(status)) {
4957 DBG_DEBUG("smbd_check_access_rights_fsp on "
4958 "file %s failed with %s\n",
4959 fsp_str_dbg(fsp),
4960 nt_errstr(status));
4961 fd_close(fsp);
4962 return status;
4967 * If we created a new directory or going to delete it later,
4968 * we should keep * the share_mode_lock (g_lock) until we call
4969 * share_mode_entry_prepare_unlock()
4971 if (info != FILE_WAS_OPENED) {
4972 keep_locked = true;
4973 } else if (create_options & FILE_DELETE_ON_CLOSE) {
4974 keep_locked = true;
4977 lck_state = (struct open_ntcreate_lock_state) {
4978 .fsp = fsp,
4979 .object_type = "directory",
4980 .req = req,
4981 .create_disposition = create_disposition,
4982 .access_mask = access_mask,
4983 .share_access = share_access,
4984 .oplock_request = NO_OPLOCK,
4985 .lease = NULL,
4986 .first_open_attempt = true,
4987 .keep_locked = keep_locked,
4990 status = share_mode_entry_prepare_lock_add(&lck_state.prepare_state,
4991 fsp->file_id,
4992 conn->connectpath,
4993 smb_dname,
4994 &mtimespec,
4995 open_ntcreate_lock_add_entry,
4996 &lck_state);
4997 if (!NT_STATUS_IS_OK(status)) {
4998 DBG_ERR("share_mode_entry_prepare_lock_add() failed for %s - %s\n",
4999 smb_fname_str_dbg(smb_dname), nt_errstr(status));
5000 fd_close(fsp);
5001 return status;
5004 status = lck_state.status;
5005 if (!NT_STATUS_IS_OK(status)) {
5006 fd_close(fsp);
5007 return status;
5011 * From here we need to use 'goto unlock;' instead of return !!!
5014 /* For directories the delete on close bit at open time seems
5015 always to be honored on close... See test 19 in Samba4 BASE-DELETE. */
5016 if (create_options & FILE_DELETE_ON_CLOSE) {
5017 status = can_set_delete_on_close(fsp, 0);
5018 if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
5019 lck_state.cleanup_fn =
5020 open_ntcreate_lock_cleanup_entry;
5021 goto unlock;
5024 if (NT_STATUS_IS_OK(status)) {
5025 /* Note that here we set the *initial* delete on close flag,
5026 not the regular one. The magic gets handled in close. */
5027 fsp->fsp_flags.initial_delete_on_close = true;
5032 * Deal with other opens having a modified write time.
5034 if (!is_omit_timespec(&lck_state.write_time)) {
5035 update_stat_ex_mtime(&fsp->fsp_name->st, lck_state.write_time);
5038 if (pinfo) {
5039 *pinfo = info;
5042 status = NT_STATUS_OK;
5044 unlock:
5045 ulstatus = share_mode_entry_prepare_unlock(&lck_state.prepare_state,
5046 lck_state.cleanup_fn,
5047 &lck_state);
5048 if (!NT_STATUS_IS_OK(ulstatus)) {
5049 DBG_ERR("share_mode_entry_prepare_unlock() failed for %s - %s\n",
5050 smb_fname_str_dbg(smb_dname), nt_errstr(ulstatus));
5051 smb_panic("share_mode_entry_prepare_unlock() failed!");
5054 if (!NT_STATUS_IS_OK(status)) {
5055 fd_close(fsp);
5056 return status;
5059 return NT_STATUS_OK;
5062 NTSTATUS create_directory(connection_struct *conn,
5063 struct smb_request *req,
5064 struct files_struct *dirfsp,
5065 struct smb_filename *smb_dname)
5067 NTSTATUS status;
5068 files_struct *fsp;
5070 status = SMB_VFS_CREATE_FILE(
5071 conn, /* conn */
5072 req, /* req */
5073 dirfsp, /* dirfsp */
5074 smb_dname, /* fname */
5075 FILE_READ_ATTRIBUTES, /* access_mask */
5076 FILE_SHARE_NONE, /* share_access */
5077 FILE_CREATE, /* create_disposition*/
5078 FILE_DIRECTORY_FILE, /* create_options */
5079 FILE_ATTRIBUTE_DIRECTORY, /* file_attributes */
5080 0, /* oplock_request */
5081 NULL, /* lease */
5082 0, /* allocation_size */
5083 0, /* private_flags */
5084 NULL, /* sd */
5085 NULL, /* ea_list */
5086 &fsp, /* result */
5087 NULL, /* pinfo */
5088 NULL, NULL); /* create context */
5090 if (NT_STATUS_IS_OK(status)) {
5091 close_file_free(req, &fsp, NORMAL_CLOSE);
5094 return status;
5097 /****************************************************************************
5098 Receive notification that one of our open files has been renamed by another
5099 smbd process.
5100 ****************************************************************************/
5102 void msg_file_was_renamed(struct messaging_context *msg_ctx,
5103 void *private_data,
5104 uint32_t msg_type,
5105 struct server_id src,
5106 DATA_BLOB *data)
5108 struct file_rename_message *msg = NULL;
5109 enum ndr_err_code ndr_err;
5110 files_struct *fsp;
5111 struct smb_filename *smb_fname = NULL;
5112 struct smbd_server_connection *sconn =
5113 talloc_get_type_abort(private_data,
5114 struct smbd_server_connection);
5116 msg = talloc(talloc_tos(), struct file_rename_message);
5117 if (msg == NULL) {
5118 DBG_WARNING("talloc failed\n");
5119 return;
5122 ndr_err = ndr_pull_struct_blob_all(
5123 data,
5124 msg,
5125 msg,
5126 (ndr_pull_flags_fn_t)ndr_pull_file_rename_message);
5127 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
5128 DBG_DEBUG("ndr_pull_file_rename_message failed: %s\n",
5129 ndr_errstr(ndr_err));
5130 goto out;
5132 if (DEBUGLEVEL >= 10) {
5133 struct server_id_buf buf;
5134 DBG_DEBUG("Got rename message from %s\n",
5135 server_id_str_buf(src, &buf));
5136 NDR_PRINT_DEBUG(file_rename_message, msg);
5139 /* stream_name must always be NULL if there is no stream. */
5140 if ((msg->stream_name != NULL) && (msg->stream_name[0] == '\0')) {
5141 msg->stream_name = NULL;
5144 smb_fname = synthetic_smb_fname(msg,
5145 msg->base_name,
5146 msg->stream_name,
5147 NULL,
5150 if (smb_fname == NULL) {
5151 DBG_DEBUG("synthetic_smb_fname failed\n");
5152 goto out;
5155 fsp = file_find_dif(sconn, msg->id, msg->share_file_id);
5156 if (fsp == NULL) {
5157 DBG_DEBUG("fsp not found\n");
5158 goto out;
5161 if (strcmp(fsp->conn->connectpath, msg->servicepath) == 0) {
5162 SMB_STRUCT_STAT fsp_orig_sbuf;
5163 NTSTATUS status;
5164 DBG_DEBUG("renaming file %s from %s -> %s\n",
5165 fsp_fnum_dbg(fsp),
5166 fsp_str_dbg(fsp),
5167 smb_fname_str_dbg(smb_fname));
5170 * The incoming smb_fname here has an
5171 * invalid stat struct from synthetic_smb_fname()
5172 * above.
5173 * Preserve the existing stat from the
5174 * open fsp after fsp_set_smb_fname()
5175 * overwrites with the invalid stat.
5177 * (We could just copy this into
5178 * smb_fname->st, but keep this code
5179 * identical to the fix in rename_open_files()
5180 * for clarity.
5182 * We will do an fstat before returning
5183 * any of this metadata to the client anyway.
5185 fsp_orig_sbuf = fsp->fsp_name->st;
5186 status = fsp_set_smb_fname(fsp, smb_fname);
5187 if (!NT_STATUS_IS_OK(status)) {
5188 DBG_DEBUG("fsp_set_smb_fname failed: %s\n",
5189 nt_errstr(status));
5191 fsp->fsp_name->st = fsp_orig_sbuf;
5192 } else {
5193 /* TODO. JRA. */
5195 * Now we have the complete path we can work out if
5196 * this is actually within this share and adjust
5197 * newname accordingly.
5199 DBG_DEBUG("share mismatch (sharepath %s not sharepath %s) "
5200 "%s from %s -> %s\n",
5201 fsp->conn->connectpath,
5202 msg->servicepath,
5203 fsp_fnum_dbg(fsp),
5204 fsp_str_dbg(fsp),
5205 smb_fname_str_dbg(smb_fname));
5207 out:
5208 TALLOC_FREE(msg);
5212 * If a main file is opened for delete, all streams need to be checked for
5213 * !FILE_SHARE_DELETE. Do this by opening with DELETE_ACCESS.
5214 * If that works, delete them all by setting the delete on close and close.
5217 static NTSTATUS open_streams_for_delete(connection_struct *conn,
5218 const struct smb_filename *smb_fname)
5220 struct stream_struct *stream_info = NULL;
5221 files_struct **streams = NULL;
5222 int j;
5223 unsigned int i, num_streams = 0;
5224 TALLOC_CTX *frame = talloc_stackframe();
5225 const struct smb_filename *pathref = NULL;
5226 NTSTATUS status;
5228 if (smb_fname->fsp == NULL) {
5229 struct smb_filename *tmp = NULL;
5230 status = synthetic_pathref(frame,
5231 conn->cwd_fsp,
5232 smb_fname->base_name,
5233 NULL,
5234 NULL,
5235 smb_fname->twrp,
5236 smb_fname->flags,
5237 &tmp);
5238 if (!NT_STATUS_IS_OK(status)) {
5239 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
5240 || NT_STATUS_EQUAL(status,
5241 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
5242 DBG_DEBUG("no streams around\n");
5243 TALLOC_FREE(frame);
5244 return NT_STATUS_OK;
5246 DBG_DEBUG("synthetic_pathref failed: %s\n",
5247 nt_errstr(status));
5248 goto fail;
5250 pathref = tmp;
5251 } else {
5252 pathref = smb_fname;
5254 status = vfs_fstreaminfo(pathref->fsp, talloc_tos(),
5255 &num_streams, &stream_info);
5257 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
5258 || NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
5259 DEBUG(10, ("no streams around\n"));
5260 TALLOC_FREE(frame);
5261 return NT_STATUS_OK;
5264 if (!NT_STATUS_IS_OK(status)) {
5265 DEBUG(10, ("vfs_fstreaminfo failed: %s\n",
5266 nt_errstr(status)));
5267 goto fail;
5270 DEBUG(10, ("open_streams_for_delete found %d streams\n",
5271 num_streams));
5273 if (num_streams == 0) {
5274 TALLOC_FREE(frame);
5275 return NT_STATUS_OK;
5278 streams = talloc_array(talloc_tos(), files_struct *, num_streams);
5279 if (streams == NULL) {
5280 DEBUG(0, ("talloc failed\n"));
5281 status = NT_STATUS_NO_MEMORY;
5282 goto fail;
5285 for (i=0; i<num_streams; i++) {
5286 struct smb_filename *smb_fname_cp;
5288 if (strequal(stream_info[i].name, "::$DATA")) {
5289 streams[i] = NULL;
5290 continue;
5293 smb_fname_cp = synthetic_smb_fname(talloc_tos(),
5294 smb_fname->base_name,
5295 stream_info[i].name,
5296 NULL,
5297 smb_fname->twrp,
5298 (smb_fname->flags &
5299 ~SMB_FILENAME_POSIX_PATH));
5300 if (smb_fname_cp == NULL) {
5301 status = NT_STATUS_NO_MEMORY;
5302 goto fail;
5305 status = openat_pathref_fsp(conn->cwd_fsp, smb_fname_cp);
5306 if (!NT_STATUS_IS_OK(status)) {
5307 DBG_DEBUG("Unable to open stream [%s]: %s\n",
5308 smb_fname_str_dbg(smb_fname_cp),
5309 nt_errstr(status));
5310 TALLOC_FREE(smb_fname_cp);
5311 break;
5314 status = SMB_VFS_CREATE_FILE(
5315 conn, /* conn */
5316 NULL, /* req */
5317 NULL, /* dirfsp */
5318 smb_fname_cp, /* fname */
5319 DELETE_ACCESS, /* access_mask */
5320 (FILE_SHARE_READ | /* share_access */
5321 FILE_SHARE_WRITE | FILE_SHARE_DELETE),
5322 FILE_OPEN, /* create_disposition*/
5323 0, /* create_options */
5324 FILE_ATTRIBUTE_NORMAL, /* file_attributes */
5325 0, /* oplock_request */
5326 NULL, /* lease */
5327 0, /* allocation_size */
5328 0, /* private_flags */
5329 NULL, /* sd */
5330 NULL, /* ea_list */
5331 &streams[i], /* result */
5332 NULL, /* pinfo */
5333 NULL, NULL); /* create context */
5335 if (!NT_STATUS_IS_OK(status)) {
5336 DEBUG(10, ("Could not open stream %s: %s\n",
5337 smb_fname_str_dbg(smb_fname_cp),
5338 nt_errstr(status)));
5340 TALLOC_FREE(smb_fname_cp);
5341 break;
5343 TALLOC_FREE(smb_fname_cp);
5347 * don't touch the variable "status" beyond this point :-)
5350 for (j = i-1 ; j >= 0; j--) {
5351 if (streams[j] == NULL) {
5352 continue;
5355 DEBUG(10, ("Closing stream # %d, %s\n", j,
5356 fsp_str_dbg(streams[j])));
5357 close_file_free(NULL, &streams[j], NORMAL_CLOSE);
5360 fail:
5361 TALLOC_FREE(frame);
5362 return status;
5365 /*********************************************************************
5366 Create a default ACL by inheriting from the parent. If no inheritance
5367 from the parent available, don't set anything. This will leave the actual
5368 permissions the new file or directory already got from the filesystem
5369 as the NT ACL when read.
5370 *********************************************************************/
5372 static NTSTATUS inherit_new_acl(files_struct *dirfsp, files_struct *fsp)
5374 TALLOC_CTX *frame = talloc_stackframe();
5375 struct security_descriptor *parent_desc = NULL;
5376 NTSTATUS status = NT_STATUS_OK;
5377 struct security_descriptor *psd = NULL;
5378 const struct dom_sid *owner_sid = NULL;
5379 const struct dom_sid *group_sid = NULL;
5380 uint32_t security_info_sent = (SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL);
5381 struct security_token *token = fsp->conn->session_info->security_token;
5382 bool inherit_owner =
5383 (lp_inherit_owner(SNUM(fsp->conn)) == INHERIT_OWNER_WINDOWS_AND_UNIX);
5384 bool inheritable_components = false;
5385 bool try_builtin_administrators = false;
5386 const struct dom_sid *BA_U_sid = NULL;
5387 const struct dom_sid *BA_G_sid = NULL;
5388 bool try_system = false;
5389 const struct dom_sid *SY_U_sid = NULL;
5390 const struct dom_sid *SY_G_sid = NULL;
5391 size_t size = 0;
5392 bool ok;
5394 status = SMB_VFS_FGET_NT_ACL(dirfsp,
5395 (SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL),
5396 frame,
5397 &parent_desc);
5398 if (!NT_STATUS_IS_OK(status)) {
5399 TALLOC_FREE(frame);
5400 return status;
5403 inheritable_components = sd_has_inheritable_components(parent_desc,
5404 fsp->fsp_flags.is_directory);
5406 if (!inheritable_components && !inherit_owner) {
5407 TALLOC_FREE(frame);
5408 /* Nothing to inherit and not setting owner. */
5409 return NT_STATUS_OK;
5412 /* Create an inherited descriptor from the parent. */
5414 if (DEBUGLEVEL >= 10) {
5415 DEBUG(10,("inherit_new_acl: parent acl for %s is:\n",
5416 fsp_str_dbg(fsp) ));
5417 NDR_PRINT_DEBUG(security_descriptor, parent_desc);
5420 /* Inherit from parent descriptor if "inherit owner" set. */
5421 if (inherit_owner) {
5422 owner_sid = parent_desc->owner_sid;
5423 group_sid = parent_desc->group_sid;
5426 if (owner_sid == NULL) {
5427 if (security_token_has_builtin_administrators(token)) {
5428 try_builtin_administrators = true;
5429 } else if (security_token_is_system(token)) {
5430 try_builtin_administrators = true;
5431 try_system = true;
5435 if (group_sid == NULL &&
5436 token->num_sids == PRIMARY_GROUP_SID_INDEX)
5438 if (security_token_is_system(token)) {
5439 try_builtin_administrators = true;
5440 try_system = true;
5444 if (try_builtin_administrators) {
5445 struct unixid ids = { .id = 0 };
5447 ok = sids_to_unixids(&global_sid_Builtin_Administrators, 1, &ids);
5448 if (ok) {
5449 switch (ids.type) {
5450 case ID_TYPE_BOTH:
5451 BA_U_sid = &global_sid_Builtin_Administrators;
5452 BA_G_sid = &global_sid_Builtin_Administrators;
5453 break;
5454 case ID_TYPE_UID:
5455 BA_U_sid = &global_sid_Builtin_Administrators;
5456 break;
5457 case ID_TYPE_GID:
5458 BA_G_sid = &global_sid_Builtin_Administrators;
5459 break;
5460 default:
5461 break;
5466 if (try_system) {
5467 struct unixid ids = { .id = 0 };
5469 ok = sids_to_unixids(&global_sid_System, 1, &ids);
5470 if (ok) {
5471 switch (ids.type) {
5472 case ID_TYPE_BOTH:
5473 SY_U_sid = &global_sid_System;
5474 SY_G_sid = &global_sid_System;
5475 break;
5476 case ID_TYPE_UID:
5477 SY_U_sid = &global_sid_System;
5478 break;
5479 case ID_TYPE_GID:
5480 SY_G_sid = &global_sid_System;
5481 break;
5482 default:
5483 break;
5488 if (owner_sid == NULL) {
5489 owner_sid = BA_U_sid;
5492 if (owner_sid == NULL) {
5493 owner_sid = SY_U_sid;
5496 if (group_sid == NULL) {
5497 group_sid = SY_G_sid;
5500 if (try_system && group_sid == NULL) {
5501 group_sid = BA_G_sid;
5504 if (owner_sid == NULL) {
5505 owner_sid = &token->sids[PRIMARY_USER_SID_INDEX];
5507 if (group_sid == NULL) {
5508 if (token->num_sids == PRIMARY_GROUP_SID_INDEX) {
5509 group_sid = &token->sids[PRIMARY_USER_SID_INDEX];
5510 } else {
5511 group_sid = &token->sids[PRIMARY_GROUP_SID_INDEX];
5515 status = se_create_child_secdesc(frame,
5516 &psd,
5517 &size,
5518 parent_desc,
5519 owner_sid,
5520 group_sid,
5521 fsp->fsp_flags.is_directory);
5522 if (!NT_STATUS_IS_OK(status)) {
5523 TALLOC_FREE(frame);
5524 return status;
5527 /* If inheritable_components == false,
5528 se_create_child_secdesc()
5529 creates a security descriptor with a NULL dacl
5530 entry, but with SEC_DESC_DACL_PRESENT. We need
5531 to remove that flag. */
5533 if (!inheritable_components) {
5534 security_info_sent &= ~SECINFO_DACL;
5535 psd->type &= ~SEC_DESC_DACL_PRESENT;
5538 if (DEBUGLEVEL >= 10) {
5539 DEBUG(10,("inherit_new_acl: child acl for %s is:\n",
5540 fsp_str_dbg(fsp) ));
5541 NDR_PRINT_DEBUG(security_descriptor, psd);
5544 if (inherit_owner) {
5545 /* We need to be root to force this. */
5546 become_root();
5548 status = SMB_VFS_FSET_NT_ACL(metadata_fsp(fsp),
5549 security_info_sent,
5550 psd);
5551 if (inherit_owner) {
5552 unbecome_root();
5554 TALLOC_FREE(frame);
5555 return status;
5559 * If we already have a lease, it must match the new file id. [MS-SMB2]
5560 * 3.3.5.9.8 speaks about INVALID_PARAMETER if an already used lease key is
5561 * used for a different file name.
5564 struct lease_match_state {
5565 /* Input parameters. */
5566 TALLOC_CTX *mem_ctx;
5567 const char *servicepath;
5568 const struct smb_filename *fname;
5569 bool file_existed;
5570 struct file_id id;
5571 /* Return parameters. */
5572 uint32_t num_file_ids;
5573 struct file_id *ids;
5574 NTSTATUS match_status;
5577 /*************************************************************
5578 File doesn't exist but this lease key+guid is already in use.
5580 This is only allowable in the dynamic share case where the
5581 service path must be different.
5583 There is a small race condition here in the multi-connection
5584 case where a client sends two create calls on different connections,
5585 where the file doesn't exist and one smbd creates the leases_db
5586 entry first, but this will get fixed by the multichannel cleanup
5587 when all identical client_guids get handled by a single smbd.
5588 **************************************************************/
5590 static void lease_match_parser_new_file(
5591 uint32_t num_files,
5592 const struct leases_db_file *files,
5593 struct lease_match_state *state)
5595 uint32_t i;
5597 for (i = 0; i < num_files; i++) {
5598 const struct leases_db_file *f = &files[i];
5599 if (strequal(state->servicepath, f->servicepath)) {
5600 state->match_status = NT_STATUS_INVALID_PARAMETER;
5601 return;
5605 /* Dynamic share case. Break leases on all other files. */
5606 state->match_status = leases_db_copy_file_ids(state->mem_ctx,
5607 num_files,
5608 files,
5609 &state->ids);
5610 if (!NT_STATUS_IS_OK(state->match_status)) {
5611 return;
5614 state->num_file_ids = num_files;
5615 state->match_status = NT_STATUS_OPLOCK_NOT_GRANTED;
5616 return;
5619 static void lease_match_parser(
5620 uint32_t num_files,
5621 const struct leases_db_file *files,
5622 void *private_data)
5624 struct lease_match_state *state =
5625 (struct lease_match_state *)private_data;
5626 uint32_t i;
5628 if (!state->file_existed) {
5630 * Deal with name mismatch or
5631 * possible dynamic share case separately
5632 * to make code clearer.
5634 lease_match_parser_new_file(num_files,
5635 files,
5636 state);
5637 return;
5640 /* File existed. */
5641 state->match_status = NT_STATUS_OK;
5643 for (i = 0; i < num_files; i++) {
5644 const struct leases_db_file *f = &files[i];
5646 /* Everything should be the same. */
5647 if (!file_id_equal(&state->id, &f->id)) {
5649 * The client asked for a lease on a
5650 * file that doesn't match the file_id
5651 * in the database.
5653 * Maybe this is a dynamic share, i.e.
5654 * a share where the servicepath is
5655 * different for different users (e.g.
5656 * the [HOMES] share.
5658 * If the servicepath is different, but the requested
5659 * file name + stream name is the same then this is
5660 * a dynamic share, the client is using the same share
5661 * name and doesn't know that the underlying servicepath
5662 * is different. It was expecting a lease on the
5663 * same file. Return NT_STATUS_OPLOCK_NOT_GRANTED
5664 * to break leases
5666 * Otherwise the client has messed up, or is
5667 * testing our error codes, so return
5668 * NT_STATUS_INVALID_PARAMETER.
5670 if (!strequal(f->servicepath, state->servicepath) &&
5671 strequal(f->base_name, state->fname->base_name) &&
5672 strequal(f->stream_name, state->fname->stream_name))
5675 * Name is the same but servicepath is
5676 * different, dynamic share. Break leases.
5678 state->match_status =
5679 NT_STATUS_OPLOCK_NOT_GRANTED;
5680 } else {
5681 state->match_status =
5682 NT_STATUS_INVALID_PARAMETER;
5684 break;
5686 if (!strequal(f->servicepath, state->servicepath)) {
5687 state->match_status = NT_STATUS_INVALID_PARAMETER;
5688 break;
5690 if (!strequal(f->base_name, state->fname->base_name)) {
5691 state->match_status = NT_STATUS_INVALID_PARAMETER;
5692 break;
5694 if (!strequal(f->stream_name, state->fname->stream_name)) {
5695 state->match_status = NT_STATUS_INVALID_PARAMETER;
5696 break;
5700 if (NT_STATUS_IS_OK(state->match_status)) {
5702 * Common case - just opening another handle on a
5703 * file on a non-dynamic share.
5705 return;
5708 if (NT_STATUS_EQUAL(state->match_status, NT_STATUS_INVALID_PARAMETER)) {
5709 /* Mismatched path. Error back to client. */
5710 return;
5714 * File id mismatch. Dynamic share case NT_STATUS_OPLOCK_NOT_GRANTED.
5715 * Don't allow leases.
5718 state->match_status = leases_db_copy_file_ids(state->mem_ctx,
5719 num_files,
5720 files,
5721 &state->ids);
5722 if (!NT_STATUS_IS_OK(state->match_status)) {
5723 return;
5726 state->num_file_ids = num_files;
5727 state->match_status = NT_STATUS_OPLOCK_NOT_GRANTED;
5728 return;
5731 struct lease_match_break_state {
5732 struct messaging_context *msg_ctx;
5733 const struct smb2_lease_key *lease_key;
5734 struct file_id id;
5736 bool found_lease;
5737 uint16_t version;
5738 uint16_t epoch;
5741 static bool lease_match_break_fn(
5742 struct share_mode_entry *e,
5743 void *private_data)
5745 struct lease_match_break_state *state = private_data;
5746 bool stale, equal;
5747 uint32_t e_lease_type = SMB2_LEASE_NONE;
5748 NTSTATUS status;
5750 stale = share_entry_stale_pid(e);
5751 if (stale) {
5752 return false;
5755 equal = smb2_lease_key_equal(&e->lease_key, state->lease_key);
5756 if (!equal) {
5757 return false;
5760 status = leases_db_get(
5761 &e->client_guid,
5762 &e->lease_key,
5763 &state->id,
5764 &e_lease_type, /* current_state */
5765 NULL, /* breaking */
5766 NULL, /* breaking_to_requested */
5767 NULL, /* breaking_to_required */
5768 &state->version, /* lease_version */
5769 &state->epoch); /* epoch */
5770 if (NT_STATUS_IS_OK(status)) {
5771 state->found_lease = true;
5772 } else {
5773 DBG_WARNING("Could not find version/epoch: %s\n",
5774 nt_errstr(status));
5775 return false;
5778 if (e_lease_type == SMB2_LEASE_NONE) {
5779 return false;
5781 send_break_message(state->msg_ctx, &state->id, e, SMB2_LEASE_NONE);
5784 * Windows 7 and 8 lease clients are broken in that they will
5785 * not respond to lease break requests whilst waiting for an
5786 * outstanding open request on that lease handle on the same
5787 * TCP connection, due to holding an internal inode lock.
5789 * This means we can't reschedule ourselves here, but must
5790 * return from the create.
5792 * Work around:
5794 * Send the breaks and then return SMB2_LEASE_NONE in the
5795 * lease handle to cause them to acknowledge the lease
5796 * break. Consultation with Microsoft engineering confirmed
5797 * this approach is safe.
5800 return false;
5803 static void lease_match_fid_fn(struct share_mode_lock *lck,
5804 void *private_data)
5806 bool ok;
5808 ok = share_mode_forall_leases(lck, lease_match_break_fn, private_data);
5809 if (!ok) {
5810 DBG_DEBUG("share_mode_forall_leases failed\n");
5814 static NTSTATUS lease_match(connection_struct *conn,
5815 struct smb_request *req,
5816 const struct smb2_lease_key *lease_key,
5817 const char *servicepath,
5818 const struct smb_filename *fname,
5819 uint16_t *p_version,
5820 uint16_t *p_epoch)
5822 struct smbd_server_connection *sconn = req->sconn;
5823 TALLOC_CTX *tos = talloc_tos();
5824 struct lease_match_state state = {
5825 .mem_ctx = tos,
5826 .servicepath = servicepath,
5827 .fname = fname,
5828 .match_status = NT_STATUS_OK
5830 uint32_t i;
5831 NTSTATUS status;
5833 state.file_existed = VALID_STAT(fname->st);
5834 if (state.file_existed) {
5835 state.id = vfs_file_id_from_sbuf(conn, &fname->st);
5838 status = leases_db_parse(&sconn->client->global->client_guid,
5839 lease_key, lease_match_parser, &state);
5840 if (!NT_STATUS_IS_OK(status)) {
5842 * Not found or error means okay: We can make the lease pass
5844 return NT_STATUS_OK;
5846 if (!NT_STATUS_EQUAL(state.match_status, NT_STATUS_OPLOCK_NOT_GRANTED)) {
5848 * Anything but NT_STATUS_OPLOCK_NOT_GRANTED, let the caller
5849 * deal with it.
5851 return state.match_status;
5854 /* We have to break all existing leases. */
5855 for (i = 0; i < state.num_file_ids; i++) {
5856 struct lease_match_break_state break_state = {
5857 .msg_ctx = conn->sconn->msg_ctx,
5858 .lease_key = lease_key,
5861 if (file_id_equal(&state.ids[i], &state.id)) {
5862 /* Don't need to break our own file. */
5863 continue;
5866 break_state.id = state.ids[i];
5868 status = share_mode_do_locked_vfs_denied(break_state.id,
5869 lease_match_fid_fn,
5870 &break_state);
5871 if (!NT_STATUS_IS_OK(status)) {
5872 /* Race condition - file already closed. */
5873 continue;
5876 if (break_state.found_lease) {
5877 *p_version = break_state.version;
5878 *p_epoch = break_state.epoch;
5882 * Ensure we don't grant anything more so we
5883 * never upgrade.
5885 return NT_STATUS_OPLOCK_NOT_GRANTED;
5889 * Wrapper around open_file_ntcreate and open_directory
5892 static NTSTATUS create_file_unixpath(connection_struct *conn,
5893 struct smb_request *req,
5894 struct files_struct *dirfsp,
5895 struct smb_filename *smb_fname,
5896 uint32_t access_mask,
5897 uint32_t share_access,
5898 uint32_t create_disposition,
5899 uint32_t create_options,
5900 uint32_t file_attributes,
5901 uint32_t oplock_request,
5902 const struct smb2_lease *lease,
5903 uint64_t allocation_size,
5904 uint32_t private_flags,
5905 struct security_descriptor *sd,
5906 struct ea_list *ea_list,
5908 files_struct **result,
5909 int *pinfo)
5911 struct smb2_lease none_lease;
5912 int info = FILE_WAS_OPENED;
5913 files_struct *base_fsp = NULL;
5914 files_struct *fsp = NULL;
5915 bool free_fsp_on_error = false;
5916 NTSTATUS status;
5917 int ret;
5918 struct smb_filename *parent_dir_fname = NULL;
5919 struct smb_filename *smb_fname_atname = NULL;
5921 DBG_DEBUG("access_mask = 0x%"PRIx32" "
5922 "file_attributes = 0x%"PRIx32" "
5923 "share_access = 0x%"PRIx32" "
5924 "create_disposition = 0x%"PRIx32" "
5925 "create_options = 0x%"PRIx32" "
5926 "oplock_request = 0x%"PRIx32" "
5927 "private_flags = 0x%"PRIx32" "
5928 "ea_list = %p, "
5929 "sd = %p, "
5930 "fname = %s\n",
5931 access_mask,
5932 file_attributes,
5933 share_access,
5934 create_disposition,
5935 create_options,
5936 oplock_request,
5937 private_flags,
5938 ea_list,
5940 smb_fname_str_dbg(smb_fname));
5942 if (create_options & FILE_OPEN_BY_FILE_ID) {
5943 status = NT_STATUS_NOT_SUPPORTED;
5944 goto fail;
5947 if (create_options & NTCREATEX_OPTIONS_INVALID_PARAM_MASK) {
5948 status = NT_STATUS_INVALID_PARAMETER;
5949 goto fail;
5952 if (!(create_options & FILE_OPEN_REPARSE_POINT) &&
5953 (smb_fname->fsp != NULL) && /* new files don't have an fsp */
5954 VALID_STAT(smb_fname->fsp->fsp_name->st))
5956 mode_t type = (smb_fname->fsp->fsp_name->st.st_ex_mode &
5957 S_IFMT);
5959 switch (type) {
5960 case S_IFREG:
5961 FALL_THROUGH;
5962 case S_IFDIR:
5963 break;
5964 case S_IFLNK:
5966 * We should never get this far with a symlink
5967 * "as such". Report as not existing.
5969 status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
5970 goto fail;
5971 default:
5972 status = NT_STATUS_IO_REPARSE_TAG_NOT_HANDLED;
5973 goto fail;
5977 if (req == NULL) {
5978 oplock_request |= INTERNAL_OPEN_ONLY;
5981 if (lease != NULL) {
5982 uint16_t epoch = lease->lease_epoch;
5983 uint16_t version = lease->lease_version;
5985 if (req == NULL) {
5986 DBG_WARNING("Got lease on internal open\n");
5987 status = NT_STATUS_INTERNAL_ERROR;
5988 goto fail;
5991 status = lease_match(conn,
5992 req,
5993 &lease->lease_key,
5994 conn->connectpath,
5995 smb_fname,
5996 &version,
5997 &epoch);
5998 if (NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) {
5999 /* Dynamic share file. No leases and update epoch... */
6000 none_lease = *lease;
6001 none_lease.lease_state = SMB2_LEASE_NONE;
6002 none_lease.lease_epoch = epoch;
6003 none_lease.lease_version = version;
6004 lease = &none_lease;
6005 } else if (!NT_STATUS_IS_OK(status)) {
6006 goto fail;
6010 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
6011 && (access_mask & DELETE_ACCESS)
6012 && !is_named_stream(smb_fname)) {
6014 * We can't open a file with DELETE access if any of the
6015 * streams is open without FILE_SHARE_DELETE
6017 status = open_streams_for_delete(conn, smb_fname);
6019 if (!NT_STATUS_IS_OK(status)) {
6020 goto fail;
6024 if (access_mask & SEC_FLAG_SYSTEM_SECURITY) {
6025 bool ok;
6027 ok = security_token_has_privilege(get_current_nttok(conn),
6028 SEC_PRIV_SECURITY);
6029 if (!ok) {
6030 DBG_DEBUG("open on %s failed - "
6031 "SEC_FLAG_SYSTEM_SECURITY denied.\n",
6032 smb_fname_str_dbg(smb_fname));
6033 status = NT_STATUS_PRIVILEGE_NOT_HELD;
6034 goto fail;
6037 if (conn_using_smb2(conn->sconn) &&
6038 (access_mask == SEC_FLAG_SYSTEM_SECURITY))
6041 * No other bits set. Windows SMB2 refuses this.
6042 * See smbtorture3 SMB2-SACL test.
6044 * Note this is an SMB2-only behavior,
6045 * smbtorture3 SMB1-SYSTEM-SECURITY already tests
6046 * that SMB1 allows this.
6048 status = NT_STATUS_ACCESS_DENIED;
6049 goto fail;
6054 * Files or directories can't be opened DELETE_ON_CLOSE without
6055 * delete access.
6056 * BUG: https://bugzilla.samba.org/show_bug.cgi?id=13358
6058 if ((create_options & FILE_DELETE_ON_CLOSE) &&
6059 ((access_mask & DELETE_ACCESS) == 0)) {
6060 status = NT_STATUS_INVALID_PARAMETER;
6061 goto fail;
6064 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
6065 && is_named_stream(smb_fname))
6067 uint32_t base_create_disposition;
6068 struct smb_filename *smb_fname_base = NULL;
6069 uint32_t base_privflags;
6071 if (create_options & FILE_DIRECTORY_FILE) {
6072 DBG_DEBUG("Can't open a stream as directory\n");
6073 status = NT_STATUS_NOT_A_DIRECTORY;
6074 goto fail;
6077 switch (create_disposition) {
6078 case FILE_OPEN:
6079 base_create_disposition = FILE_OPEN;
6080 break;
6081 default:
6082 base_create_disposition = FILE_OPEN_IF;
6083 break;
6086 smb_fname_base = cp_smb_filename_nostream(
6087 talloc_tos(), smb_fname);
6089 if (smb_fname_base == NULL) {
6090 status = NT_STATUS_NO_MEMORY;
6091 goto fail;
6095 * We may be creating the basefile as part of creating the
6096 * stream, so it's legal if the basefile doesn't exist at this
6097 * point, the create_file_unixpath() below will create it. But
6098 * if the basefile exists we want a handle so we can fstat() it.
6101 ret = vfs_stat(conn, smb_fname_base);
6102 if (ret == -1 && errno != ENOENT) {
6103 status = map_nt_error_from_unix(errno);
6104 TALLOC_FREE(smb_fname_base);
6105 goto fail;
6107 if (ret == 0) {
6108 status = openat_pathref_fsp(conn->cwd_fsp,
6109 smb_fname_base);
6110 if (!NT_STATUS_IS_OK(status)) {
6111 DBG_ERR("open_smb_fname_fsp [%s] failed: %s\n",
6112 smb_fname_str_dbg(smb_fname_base),
6113 nt_errstr(status));
6114 TALLOC_FREE(smb_fname_base);
6115 goto fail;
6119 * https://bugzilla.samba.org/show_bug.cgi?id=10229
6120 * We need to check if the requested access mask
6121 * could be used to open the underlying file (if
6122 * it existed), as we're passing in zero for the
6123 * access mask to the base filename.
6125 status = check_base_file_access(smb_fname_base->fsp,
6126 access_mask);
6128 if (!NT_STATUS_IS_OK(status)) {
6129 DEBUG(10, ("Permission check "
6130 "for base %s failed: "
6131 "%s\n", smb_fname->base_name,
6132 nt_errstr(status)));
6133 TALLOC_FREE(smb_fname_base);
6134 goto fail;
6138 base_privflags = NTCREATEX_FLAG_STREAM_BASEOPEN;
6140 /* Open the base file. */
6141 status = create_file_unixpath(conn,
6142 NULL,
6143 dirfsp,
6144 smb_fname_base,
6146 FILE_SHARE_READ
6147 | FILE_SHARE_WRITE
6148 | FILE_SHARE_DELETE,
6149 base_create_disposition,
6153 NULL,
6155 base_privflags,
6156 NULL,
6157 NULL,
6158 &base_fsp,
6159 NULL);
6160 TALLOC_FREE(smb_fname_base);
6162 if (!NT_STATUS_IS_OK(status)) {
6163 DEBUG(10, ("create_file_unixpath for base %s failed: "
6164 "%s\n", smb_fname->base_name,
6165 nt_errstr(status)));
6166 goto fail;
6170 if (smb_fname->fsp != NULL) {
6172 fsp = smb_fname->fsp;
6175 * We're about to use smb_fname->fsp for the fresh open.
6177 * Every fsp passed in via smb_fname->fsp already
6178 * holds a fsp->fsp_name. If it is already this
6179 * fsp->fsp_name that we got passed in as our input
6180 * argument smb_fname, these two are assumed to have
6181 * the same lifetime: Every fsp hangs of "conn", and
6182 * fsp->fsp_name is its talloc child.
6185 if (smb_fname != smb_fname->fsp->fsp_name) {
6187 * "smb_fname" is temporary in this case, but
6188 * the destructor of smb_fname would also tear
6189 * down the fsp we're about to use. Unlink
6190 * them from each other.
6192 smb_fname_fsp_unlink(smb_fname);
6195 * "fsp" is ours now
6197 free_fsp_on_error = true;
6200 status = fsp_bind_smb(fsp, req);
6201 if (!NT_STATUS_IS_OK(status)) {
6202 goto fail;
6205 if (fsp_is_alternate_stream(fsp)) {
6206 struct files_struct *tmp_base_fsp = fsp->base_fsp;
6208 fsp_set_base_fsp(fsp, NULL);
6210 fd_close(tmp_base_fsp);
6211 file_free(NULL, tmp_base_fsp);
6213 } else {
6215 * No fsp passed in that we can use, create one
6217 status = file_new(req, conn, &fsp);
6218 if(!NT_STATUS_IS_OK(status)) {
6219 goto fail;
6221 free_fsp_on_error = true;
6223 status = fsp_set_smb_fname(fsp, smb_fname);
6224 if (!NT_STATUS_IS_OK(status)) {
6225 goto fail;
6229 SMB_ASSERT(fsp->fsp_name->fsp != NULL);
6230 SMB_ASSERT(fsp->fsp_name->fsp == fsp);
6232 if (base_fsp) {
6234 * We're opening the stream element of a
6235 * base_fsp we already opened. Set up the
6236 * base_fsp pointer.
6238 fsp_set_base_fsp(fsp, base_fsp);
6241 if (dirfsp != NULL) {
6242 status = SMB_VFS_PARENT_PATHNAME(
6243 conn,
6244 talloc_tos(),
6245 smb_fname,
6246 &parent_dir_fname,
6247 &smb_fname_atname);
6248 if (!NT_STATUS_IS_OK(status)) {
6249 goto fail;
6251 } else {
6253 * Get a pathref on the parent. We can re-use this for
6254 * multiple calls to check parent ACLs etc. to avoid
6255 * pathname calls.
6257 status = parent_pathref(talloc_tos(),
6258 conn->cwd_fsp,
6259 smb_fname,
6260 &parent_dir_fname,
6261 &smb_fname_atname);
6262 if (!NT_STATUS_IS_OK(status)) {
6263 goto fail;
6266 dirfsp = parent_dir_fname->fsp;
6267 status = fsp_set_smb_fname(dirfsp, parent_dir_fname);
6268 if (!NT_STATUS_IS_OK(status)) {
6269 goto fail;
6274 * If it's a request for a directory open, deal with it separately.
6277 if (create_options & FILE_DIRECTORY_FILE) {
6279 if (create_options & FILE_NON_DIRECTORY_FILE) {
6280 status = NT_STATUS_INVALID_PARAMETER;
6281 goto fail;
6284 /* Can't open a temp directory. IFS kit test. */
6285 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
6286 (file_attributes & FILE_ATTRIBUTE_TEMPORARY)) {
6287 status = NT_STATUS_INVALID_PARAMETER;
6288 goto fail;
6292 * We will get a create directory here if the Win32
6293 * app specified a security descriptor in the
6294 * CreateDirectory() call.
6297 oplock_request = 0;
6298 status = open_directory(conn,
6299 req,
6300 access_mask,
6301 share_access,
6302 create_disposition,
6303 create_options,
6304 file_attributes,
6305 dirfsp->fsp_name,
6306 smb_fname_atname,
6307 &info,
6308 fsp);
6309 } else {
6312 * Ordinary file case.
6315 if (allocation_size) {
6316 fsp->initial_allocation_size = smb_roundup(fsp->conn,
6317 allocation_size);
6320 status = open_file_ntcreate(conn,
6321 req,
6322 access_mask,
6323 share_access,
6324 create_disposition,
6325 create_options,
6326 file_attributes,
6327 oplock_request,
6328 lease,
6329 private_flags,
6330 dirfsp->fsp_name,
6331 smb_fname_atname,
6332 &info,
6333 fsp);
6334 if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
6336 /* A stream open never opens a directory */
6338 if (base_fsp) {
6339 status = NT_STATUS_FILE_IS_A_DIRECTORY;
6340 goto fail;
6344 * Fail the open if it was explicitly a non-directory
6345 * file.
6348 if (create_options & FILE_NON_DIRECTORY_FILE) {
6349 status = NT_STATUS_FILE_IS_A_DIRECTORY;
6350 goto fail;
6353 oplock_request = 0;
6354 status = open_directory(conn,
6355 req,
6356 access_mask,
6357 share_access,
6358 create_disposition,
6359 create_options,
6360 file_attributes,
6361 dirfsp->fsp_name,
6362 smb_fname_atname,
6363 &info,
6364 fsp);
6368 if (!NT_STATUS_IS_OK(status)) {
6369 goto fail;
6372 fsp->fsp_flags.is_fsa = true;
6374 if ((ea_list != NULL) &&
6375 ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN))) {
6376 status = set_ea(conn, fsp, ea_list);
6377 if (!NT_STATUS_IS_OK(status)) {
6378 goto fail;
6382 if (!fsp->fsp_flags.is_directory &&
6383 S_ISDIR(fsp->fsp_name->st.st_ex_mode))
6385 status = NT_STATUS_ACCESS_DENIED;
6386 goto fail;
6389 /* Save the requested allocation size. */
6390 if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
6391 if ((allocation_size > (uint64_t)fsp->fsp_name->st.st_ex_size)
6392 && !(fsp->fsp_flags.is_directory))
6394 fsp->initial_allocation_size = smb_roundup(
6395 fsp->conn, allocation_size);
6396 if (vfs_allocate_file_space(
6397 fsp, fsp->initial_allocation_size) == -1) {
6398 status = NT_STATUS_DISK_FULL;
6399 goto fail;
6401 } else {
6402 fsp->initial_allocation_size = smb_roundup(
6403 fsp->conn, (uint64_t)fsp->fsp_name->st.st_ex_size);
6405 } else {
6406 fsp->initial_allocation_size = 0;
6409 if ((info == FILE_WAS_CREATED) &&
6410 lp_nt_acl_support(SNUM(conn)) &&
6411 !fsp_is_alternate_stream(fsp)) {
6412 if (sd != NULL) {
6414 * According to the MS documentation, the only time the security
6415 * descriptor is applied to the opened file is iff we *created* the
6416 * file; an existing file stays the same.
6418 * Also, it seems (from observation) that you can open the file with
6419 * any access mask but you can still write the sd. We need to override
6420 * the granted access before we call set_sd
6421 * Patch for bug #2242 from Tom Lackemann <cessnatomny@yahoo.com>.
6424 uint32_t sec_info_sent;
6425 uint32_t saved_access_mask = fsp->access_mask;
6427 sec_info_sent = get_sec_info(sd);
6429 fsp->access_mask = FILE_GENERIC_ALL;
6431 if (sec_info_sent & (SECINFO_OWNER|
6432 SECINFO_GROUP|
6433 SECINFO_DACL|
6434 SECINFO_SACL)) {
6435 status = set_sd(fsp, sd, sec_info_sent);
6438 fsp->access_mask = saved_access_mask;
6440 if (!NT_STATUS_IS_OK(status)) {
6441 goto fail;
6443 } else if (lp_inherit_acls(SNUM(conn))) {
6444 /* Inherit from parent. Errors here are not fatal. */
6445 status = inherit_new_acl(dirfsp, fsp);
6446 if (!NT_STATUS_IS_OK(status)) {
6447 DEBUG(10,("inherit_new_acl: failed for %s with %s\n",
6448 fsp_str_dbg(fsp),
6449 nt_errstr(status) ));
6454 if ((conn->fs_capabilities & FILE_FILE_COMPRESSION)
6455 && (create_options & FILE_NO_COMPRESSION)
6456 && (info == FILE_WAS_CREATED)) {
6457 status = SMB_VFS_SET_COMPRESSION(conn, fsp, fsp,
6458 COMPRESSION_FORMAT_NONE);
6459 if (!NT_STATUS_IS_OK(status)) {
6460 DEBUG(1, ("failed to disable compression: %s\n",
6461 nt_errstr(status)));
6465 DEBUG(10, ("create_file_unixpath: info=%d\n", info));
6467 *result = fsp;
6468 if (pinfo != NULL) {
6469 *pinfo = info;
6472 smb_fname->st = fsp->fsp_name->st;
6474 TALLOC_FREE(parent_dir_fname);
6476 return NT_STATUS_OK;
6478 fail:
6479 DEBUG(10, ("create_file_unixpath: %s\n", nt_errstr(status)));
6481 if (fsp != NULL) {
6483 * The close_file below will close
6484 * fsp->base_fsp.
6486 base_fsp = NULL;
6487 close_file_smb(req, fsp, ERROR_CLOSE);
6488 if (free_fsp_on_error) {
6489 file_free(req, fsp);
6490 fsp = NULL;
6493 if (base_fsp != NULL) {
6494 close_file_free(req, &base_fsp, ERROR_CLOSE);
6497 TALLOC_FREE(parent_dir_fname);
6499 return status;
6502 NTSTATUS create_file_default(connection_struct *conn,
6503 struct smb_request *req,
6504 struct files_struct *dirfsp,
6505 struct smb_filename *smb_fname,
6506 uint32_t access_mask,
6507 uint32_t share_access,
6508 uint32_t create_disposition,
6509 uint32_t create_options,
6510 uint32_t file_attributes,
6511 uint32_t oplock_request,
6512 const struct smb2_lease *lease,
6513 uint64_t allocation_size,
6514 uint32_t private_flags,
6515 struct security_descriptor *sd,
6516 struct ea_list *ea_list,
6517 files_struct **result,
6518 int *pinfo,
6519 const struct smb2_create_blobs *in_context_blobs,
6520 struct smb2_create_blobs *out_context_blobs)
6522 int info = FILE_WAS_OPENED;
6523 files_struct *fsp = NULL;
6524 NTSTATUS status;
6525 bool stream_name = false;
6526 struct smb2_create_blob *posx = NULL;
6528 DBG_DEBUG("access_mask = 0x%" PRIu32
6529 " file_attributes = 0x%" PRIu32
6530 " share_access = 0x%" PRIu32
6531 " create_disposition = 0x%" PRIu32
6532 " create_options = 0x%" PRIu32
6533 " oplock_request = 0x%" PRIu32
6534 " private_flags = 0x%" PRIu32
6535 " ea_list = %p, sd = %p, fname = %s\n",
6536 access_mask,
6537 file_attributes,
6538 share_access,
6539 create_disposition,
6540 create_options,
6541 oplock_request,
6542 private_flags,
6543 ea_list,
6545 smb_fname_str_dbg(smb_fname));
6547 if (req != NULL) {
6549 * Remember the absolute time of the original request
6550 * with this mid. We'll use it later to see if this
6551 * has timed out.
6553 get_deferred_open_message_state(req, &req->request_time, NULL);
6557 * Check to see if this is a mac fork of some kind.
6560 stream_name = is_ntfs_stream_smb_fname(smb_fname);
6561 if (stream_name) {
6562 enum FAKE_FILE_TYPE fake_file_type;
6564 fake_file_type = is_fake_file(smb_fname);
6566 if (req != NULL && fake_file_type != FAKE_FILE_TYPE_NONE) {
6569 * Here we go! support for changing the disk quotas
6570 * --metze
6572 * We need to fake up to open this MAGIC QUOTA file
6573 * and return a valid FID.
6575 * w2k close this file directly after opening xp
6576 * also tries a QUERY_FILE_INFO on the file and then
6577 * close it
6579 status = open_fake_file(req, conn, req->vuid,
6580 fake_file_type, smb_fname,
6581 access_mask, &fsp);
6582 if (!NT_STATUS_IS_OK(status)) {
6583 goto fail;
6586 ZERO_STRUCT(smb_fname->st);
6587 goto done;
6590 if (!(conn->fs_capabilities & FILE_NAMED_STREAMS)) {
6591 status = NT_STATUS_OBJECT_NAME_INVALID;
6592 goto fail;
6596 if (is_ntfs_default_stream_smb_fname(smb_fname)) {
6597 int ret;
6598 /* We have to handle this error here. */
6599 if (create_options & FILE_DIRECTORY_FILE) {
6600 status = NT_STATUS_NOT_A_DIRECTORY;
6601 goto fail;
6603 ret = vfs_stat(conn, smb_fname);
6604 if (ret == 0 && VALID_STAT_OF_DIR(smb_fname->st)) {
6605 status = NT_STATUS_FILE_IS_A_DIRECTORY;
6606 goto fail;
6610 posx = smb2_create_blob_find(
6611 in_context_blobs, SMB2_CREATE_TAG_POSIX);
6612 if (posx != NULL) {
6613 uint32_t wire_mode_bits = 0;
6614 mode_t mode_bits = 0;
6615 SMB_STRUCT_STAT sbuf = { 0 };
6616 enum perm_type ptype =
6617 (create_options & FILE_DIRECTORY_FILE) ?
6618 PERM_NEW_DIR : PERM_NEW_FILE;
6620 if (posx->data.length != 4) {
6621 status = NT_STATUS_INVALID_PARAMETER;
6622 goto fail;
6625 wire_mode_bits = IVAL(posx->data.data, 0);
6626 status = unix_perms_from_wire(
6627 conn, &sbuf, wire_mode_bits, ptype, &mode_bits);
6628 if (!NT_STATUS_IS_OK(status)) {
6629 goto fail;
6632 * Remove type info from mode, leaving only the
6633 * permissions and setuid/gid bits.
6635 mode_bits &= ~S_IFMT;
6637 file_attributes = (FILE_FLAG_POSIX_SEMANTICS | mode_bits);
6640 status = create_file_unixpath(conn,
6641 req,
6642 dirfsp,
6643 smb_fname,
6644 access_mask,
6645 share_access,
6646 create_disposition,
6647 create_options,
6648 file_attributes,
6649 oplock_request,
6650 lease,
6651 allocation_size,
6652 private_flags,
6654 ea_list,
6655 &fsp,
6656 &info);
6657 if (!NT_STATUS_IS_OK(status)) {
6658 goto fail;
6661 done:
6662 DEBUG(10, ("create_file: info=%d\n", info));
6664 *result = fsp;
6665 if (pinfo != NULL) {
6666 *pinfo = info;
6668 return NT_STATUS_OK;
6670 fail:
6671 DEBUG(10, ("create_file: %s\n", nt_errstr(status)));
6673 if (fsp != NULL) {
6674 close_file_free(req, &fsp, ERROR_CLOSE);
6676 return status;