smbd: remove now unneccessary wrapper vfs_fget_dos_attributes()
[Samba.git] / source3 / smbd / open.c
blobcb1e2adbf1e3b03a5e54edf23d6909ec85662da8
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"
45 extern const struct generic_mapping file_generic_mapping;
47 struct deferred_open_record {
48 struct smbXsrv_connection *xconn;
49 uint64_t mid;
51 bool async_open;
54 * Timer for async opens, needed because they don't use a watch on
55 * a locking.tdb record. This is currently only used for real async
56 * opens and just terminates smbd if the async open times out.
58 struct tevent_timer *te;
61 * For the samba kernel oplock case we use both a timeout and
62 * a watch on locking.tdb. This way in case it's smbd holding
63 * the kernel oplock we get directly notified for the retry
64 * once the kernel oplock is properly broken. Store the req
65 * here so that it can be timely discarded once the timer
66 * above fires.
68 struct tevent_req *watch_req;
71 /****************************************************************************
72 If the requester wanted DELETE_ACCESS and was rejected because
73 the file ACL didn't include DELETE_ACCESS, see if the parent ACL
74 overrides this.
75 ****************************************************************************/
77 static bool parent_override_delete(connection_struct *conn,
78 struct files_struct *dirfsp,
79 const struct smb_filename *smb_fname,
80 uint32_t access_mask,
81 uint32_t rejected_mask)
83 if ((access_mask & DELETE_ACCESS) &&
84 (rejected_mask & DELETE_ACCESS) &&
85 can_delete_file_in_directory(conn,
86 dirfsp,
87 smb_fname))
89 return true;
91 return false;
94 /****************************************************************************
95 Check if we have open rights.
96 ****************************************************************************/
98 static NTSTATUS smbd_check_access_rights_fname(
99 struct connection_struct *conn,
100 const struct smb_filename *smb_fname,
101 bool use_privs,
102 uint32_t access_mask,
103 uint32_t do_not_check_mask)
105 uint32_t rejected_share_access;
106 uint32_t effective_access;
108 rejected_share_access = access_mask & ~(conn->share_access);
110 if (rejected_share_access) {
111 DBG_DEBUG("rejected share access 0x%"PRIx32" on "
112 "%s (0x%"PRIx32")\n",
113 access_mask,
114 smb_fname_str_dbg(smb_fname),
115 rejected_share_access);
116 return NT_STATUS_ACCESS_DENIED;
119 effective_access = access_mask & ~do_not_check_mask;
120 if (effective_access == 0) {
121 DBG_DEBUG("do_not_check_mask override on %s. Granting 0x%x for free.\n",
122 smb_fname_str_dbg(smb_fname),
123 (unsigned int)access_mask);
124 return NT_STATUS_OK;
127 if (!use_privs && get_current_uid(conn) == (uid_t)0) {
128 /* I'm sorry sir, I didn't know you were root... */
129 DBG_DEBUG("root override on %s. Granting 0x%x\n",
130 smb_fname_str_dbg(smb_fname),
131 (unsigned int)access_mask);
132 return NT_STATUS_OK;
135 if ((access_mask & DELETE_ACCESS) &&
136 !lp_acl_check_permissions(SNUM(conn)))
138 DBG_DEBUG("Not checking ACL on DELETE_ACCESS on file %s. "
139 "Granting 0x%"PRIx32"\n",
140 smb_fname_str_dbg(smb_fname),
141 access_mask);
142 return NT_STATUS_OK;
145 if (access_mask == DELETE_ACCESS &&
146 VALID_STAT(smb_fname->st) &&
147 S_ISLNK(smb_fname->st.st_ex_mode))
149 /* We can always delete a symlink. */
150 DBG_DEBUG("Not checking ACL on DELETE_ACCESS on symlink %s.\n",
151 smb_fname_str_dbg(smb_fname));
152 return NT_STATUS_OK;
155 return NT_STATUS_MORE_PROCESSING_REQUIRED;
158 static NTSTATUS smbd_check_access_rights_sd(
159 struct connection_struct *conn,
160 struct files_struct *dirfsp,
161 const struct smb_filename *smb_fname,
162 struct security_descriptor *sd,
163 bool use_privs,
164 uint32_t access_mask,
165 uint32_t do_not_check_mask)
167 uint32_t rejected_mask = access_mask;
168 NTSTATUS status;
170 if (sd == NULL) {
171 goto access_denied;
174 status = se_file_access_check(sd,
175 get_current_nttok(conn),
176 use_privs,
177 (access_mask & ~do_not_check_mask),
178 &rejected_mask);
180 DBG_DEBUG("File [%s] requesting [0x%"PRIx32"] "
181 "returning [0x%"PRIx32"] (%s)\n",
182 smb_fname_str_dbg(smb_fname),
183 access_mask,
184 rejected_mask,
185 nt_errstr(status));
187 if (!NT_STATUS_IS_OK(status)) {
188 if (DEBUGLEVEL >= 10) {
189 DBG_DEBUG("acl for %s is:\n",
190 smb_fname_str_dbg(smb_fname));
191 NDR_PRINT_DEBUG(security_descriptor, sd);
195 TALLOC_FREE(sd);
197 if (NT_STATUS_IS_OK(status) ||
198 !NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED))
200 return status;
203 /* Here we know status == NT_STATUS_ACCESS_DENIED. */
205 access_denied:
207 if ((access_mask & FILE_WRITE_ATTRIBUTES) &&
208 (rejected_mask & FILE_WRITE_ATTRIBUTES) &&
209 !lp_store_dos_attributes(SNUM(conn)) &&
210 (lp_map_readonly(SNUM(conn)) ||
211 lp_map_archive(SNUM(conn)) ||
212 lp_map_hidden(SNUM(conn)) ||
213 lp_map_system(SNUM(conn))))
215 rejected_mask &= ~FILE_WRITE_ATTRIBUTES;
217 DBG_DEBUG("overrode FILE_WRITE_ATTRIBUTES on file %s\n",
218 smb_fname_str_dbg(smb_fname));
221 if (parent_override_delete(conn,
222 dirfsp,
223 smb_fname,
224 access_mask,
225 rejected_mask))
228 * Were we trying to do an open for delete and didn't get DELETE
229 * access. Check if the directory allows DELETE_CHILD.
230 * See here:
231 * http://blogs.msdn.com/oldnewthing/archive/2004/06/04/148426.aspx
232 * for details.
235 rejected_mask &= ~DELETE_ACCESS;
237 DBG_DEBUG("Overrode DELETE_ACCESS on file %s\n",
238 smb_fname_str_dbg(smb_fname));
241 if (rejected_mask != 0) {
242 return NT_STATUS_ACCESS_DENIED;
244 return NT_STATUS_OK;
247 NTSTATUS smbd_check_access_rights_fsp(struct files_struct *dirfsp,
248 struct files_struct *fsp,
249 bool use_privs,
250 uint32_t access_mask)
252 struct security_descriptor *sd = NULL;
253 uint32_t do_not_check_mask = 0;
254 NTSTATUS status;
256 /* Cope with fake/printer fsp's. */
257 if (fsp->fake_file_handle != NULL || fsp->print_file != NULL) {
258 if ((fsp->access_mask & access_mask) != access_mask) {
259 return NT_STATUS_ACCESS_DENIED;
261 return NT_STATUS_OK;
264 if (fsp_get_pathref_fd(fsp) == -1) {
266 * This is a POSIX open on a symlink. For the pathname
267 * version of this function we used to return the st_mode
268 * bits turned into an NT ACL. For a symlink the mode bits
269 * are always rwxrwxrwx which means the pathname version always
270 * returned NT_STATUS_OK for a symlink. For the handle reference
271 * to a symlink use the handle access bits.
273 if ((fsp->access_mask & access_mask) != access_mask) {
274 return NT_STATUS_ACCESS_DENIED;
276 return NT_STATUS_OK;
280 * If we can access the path to this file, by
281 * default we have FILE_READ_ATTRIBUTES from the
282 * containing directory. See the section:
283 * "Algorithm to Check Access to an Existing File"
284 * in MS-FSA.pdf.
286 * se_file_access_check() also takes care of
287 * owner WRITE_DAC and READ_CONTROL.
289 do_not_check_mask = FILE_READ_ATTRIBUTES;
292 * Samba 3.6 and earlier granted execute access even
293 * if the ACL did not contain execute rights.
294 * Samba 4.0 is more correct and checks it.
295 * The compatibility mode allows one to skip this check
296 * to smoothen upgrades.
298 if (lp_acl_allow_execute_always(SNUM(fsp->conn))) {
299 do_not_check_mask |= FILE_EXECUTE;
302 status = smbd_check_access_rights_fname(fsp->conn,
303 fsp->fsp_name,
304 use_privs,
305 access_mask,
306 do_not_check_mask);
307 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
308 return status;
311 status = SMB_VFS_FGET_NT_ACL(metadata_fsp(fsp),
312 (SECINFO_OWNER |
313 SECINFO_GROUP |
314 SECINFO_DACL),
315 talloc_tos(),
316 &sd);
317 if (!NT_STATUS_IS_OK(status)) {
318 DBG_DEBUG("Could not get acl on %s: %s\n",
319 fsp_str_dbg(fsp),
320 nt_errstr(status));
321 return status;
324 return smbd_check_access_rights_sd(fsp->conn,
325 dirfsp,
326 fsp->fsp_name,
328 use_privs,
329 access_mask,
330 do_not_check_mask);
334 * Given an fsp that represents a parent directory,
335 * check if the requested access can be granted.
337 NTSTATUS check_parent_access_fsp(struct files_struct *fsp,
338 uint32_t access_mask)
340 NTSTATUS status;
341 struct security_descriptor *parent_sd = NULL;
342 uint32_t access_granted = 0;
343 struct share_mode_lock *lck = NULL;
344 uint32_t name_hash;
345 bool delete_on_close_set;
346 TALLOC_CTX *frame = talloc_stackframe();
348 if (get_current_uid(fsp->conn) == (uid_t)0) {
349 /* I'm sorry sir, I didn't know you were root... */
350 DBG_DEBUG("root override on %s. Granting 0x%x\n",
351 fsp_str_dbg(fsp),
352 (unsigned int)access_mask);
353 status = NT_STATUS_OK;
354 goto out;
357 status = SMB_VFS_FGET_NT_ACL(fsp,
358 SECINFO_DACL,
359 frame,
360 &parent_sd);
362 if (!NT_STATUS_IS_OK(status)) {
363 DBG_INFO("SMB_VFS_FGET_NT_ACL failed for "
364 "%s with error %s\n",
365 fsp_str_dbg(fsp),
366 nt_errstr(status));
367 goto out;
371 * If we can access the path to this file, by
372 * default we have FILE_READ_ATTRIBUTES from the
373 * containing directory. See the section:
374 * "Algorithm to Check Access to an Existing File"
375 * in MS-FSA.pdf.
377 * se_file_access_check() also takes care of
378 * owner WRITE_DAC and READ_CONTROL.
380 status = se_file_access_check(parent_sd,
381 get_current_nttok(fsp->conn),
382 false,
383 (access_mask & ~FILE_READ_ATTRIBUTES),
384 &access_granted);
385 if(!NT_STATUS_IS_OK(status)) {
386 DBG_INFO("access check "
387 "on directory %s for mask 0x%x returned (0x%x) %s\n",
388 fsp_str_dbg(fsp),
389 access_mask,
390 access_granted,
391 nt_errstr(status));
392 goto out;
395 if (!(access_mask & (SEC_DIR_ADD_FILE | SEC_DIR_ADD_SUBDIR))) {
396 status = NT_STATUS_OK;
397 goto out;
399 if (!lp_check_parent_directory_delete_on_close(SNUM(fsp->conn))) {
400 status = NT_STATUS_OK;
401 goto out;
404 /* Check if the directory has delete-on-close set */
405 status = file_name_hash(fsp->conn,
406 fsp->fsp_name->base_name,
407 &name_hash);
408 if (!NT_STATUS_IS_OK(status)) {
409 goto out;
413 * Don't take a lock here. We just need a snapshot
414 * of the current state of delete on close and this is
415 * called in a codepath where we may already have a lock
416 * (and we explicitly can't hold 2 locks at the same time
417 * as that may deadlock).
419 lck = fetch_share_mode_unlocked(frame, fsp->file_id);
420 if (lck == NULL) {
421 status = NT_STATUS_OK;
422 goto out;
425 delete_on_close_set = is_delete_on_close_set(lck, name_hash);
426 if (delete_on_close_set) {
427 status = NT_STATUS_DELETE_PENDING;
428 goto out;
431 status = NT_STATUS_OK;
433 out:
434 TALLOC_FREE(frame);
435 return status;
438 /****************************************************************************
439 Ensure when opening a base file for a stream open that we have permissions
440 to do so given the access mask on the base file.
441 ****************************************************************************/
443 static NTSTATUS check_base_file_access(struct files_struct *fsp,
444 uint32_t access_mask)
446 NTSTATUS status;
448 status = smbd_calculate_access_mask_fsp(fsp->conn->cwd_fsp,
449 fsp,
450 false,
451 access_mask,
452 &access_mask);
453 if (!NT_STATUS_IS_OK(status)) {
454 DEBUG(10, ("smbd_calculate_access_mask "
455 "on file %s returned %s\n",
456 fsp_str_dbg(fsp),
457 nt_errstr(status)));
458 return status;
461 if (access_mask & (FILE_WRITE_DATA|FILE_APPEND_DATA)) {
462 uint32_t dosattrs;
463 if (!CAN_WRITE(fsp->conn)) {
464 return NT_STATUS_ACCESS_DENIED;
466 dosattrs = fdos_mode(fsp);
467 if (dosattrs & FILE_ATTRIBUTE_READONLY) {
468 return NT_STATUS_ACCESS_DENIED;
472 return smbd_check_access_rights_fsp(fsp->conn->cwd_fsp,
473 fsp,
474 false,
475 access_mask);
478 static NTSTATUS chdir_below_conn(
479 TALLOC_CTX *mem_ctx,
480 connection_struct *conn,
481 const char *connectpath,
482 size_t connectpath_len,
483 struct smb_filename *dir_fname,
484 struct smb_filename **_oldwd_fname)
486 struct smb_filename *oldwd_fname = NULL;
487 struct smb_filename *smb_fname_dot = NULL;
488 struct smb_filename *real_fname = NULL;
489 const char *relative = NULL;
490 NTSTATUS status;
491 int ret;
492 bool ok;
494 if (!ISDOT(dir_fname->base_name)) {
496 oldwd_fname = vfs_GetWd(talloc_tos(), conn);
497 if (oldwd_fname == NULL) {
498 status = map_nt_error_from_unix(errno);
499 goto out;
502 /* Pin parent directory in place. */
503 ret = vfs_ChDir(conn, dir_fname);
504 if (ret == -1) {
505 status = map_nt_error_from_unix(errno);
506 DBG_DEBUG("chdir to %s failed: %s\n",
507 dir_fname->base_name,
508 strerror(errno));
509 goto out;
513 smb_fname_dot = synthetic_smb_fname(
514 talloc_tos(),
515 ".",
516 NULL,
517 NULL,
518 dir_fname->twrp,
519 dir_fname->flags);
520 if (smb_fname_dot == NULL) {
521 status = NT_STATUS_NO_MEMORY;
522 goto out;
525 real_fname = SMB_VFS_REALPATH(conn, talloc_tos(), smb_fname_dot);
526 if (real_fname == NULL) {
527 status = map_nt_error_from_unix(errno);
528 DBG_DEBUG("realpath in %s failed: %s\n",
529 dir_fname->base_name,
530 strerror(errno));
531 goto out;
533 TALLOC_FREE(smb_fname_dot);
535 ok = subdir_of(connectpath,
536 connectpath_len,
537 real_fname->base_name,
538 &relative);
539 if (ok) {
540 TALLOC_FREE(real_fname);
541 *_oldwd_fname = oldwd_fname;
542 return NT_STATUS_OK;
545 DBG_NOTICE("Bad access attempt: %s is a symlink "
546 "outside the share path\n"
547 "conn_rootdir =%s\n"
548 "resolved_name=%s\n",
549 dir_fname->base_name,
550 connectpath,
551 real_fname->base_name);
552 TALLOC_FREE(real_fname);
554 status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
556 out:
557 if (oldwd_fname != NULL) {
558 ret = vfs_ChDir(conn, oldwd_fname);
559 SMB_ASSERT(ret == 0);
560 TALLOC_FREE(oldwd_fname);
563 return status;
567 * Get the symlink target of dirfsp/symlink_name, making sure the
568 * target is below connection_path.
571 static NTSTATUS symlink_target_below_conn(
572 TALLOC_CTX *mem_ctx,
573 const char *connection_path,
574 size_t connection_path_len,
575 struct files_struct *fsp,
576 struct files_struct *dirfsp,
577 struct smb_filename *symlink_name,
578 char **_target)
580 char *target = NULL;
581 char *absolute = NULL;
582 const char *relative = NULL;
583 NTSTATUS status;
584 bool ok;
586 if (fsp_get_pathref_fd(fsp) != -1) {
588 * fsp is an O_PATH open, Linux does a "freadlink"
589 * with an empty name argument to readlinkat
591 status = readlink_talloc(talloc_tos(), fsp, NULL, &target);
592 } else {
593 status = readlink_talloc(
594 talloc_tos(), dirfsp, symlink_name, &target);
597 if (!NT_STATUS_IS_OK(status)) {
598 DBG_DEBUG("readlink_talloc failed: %s\n", nt_errstr(status));
599 return status;
602 if (target[0] != '/') {
603 char *tmp = talloc_asprintf(
604 talloc_tos(),
605 "%s/%s/%s",
606 connection_path,
607 dirfsp->fsp_name->base_name,
608 target);
610 TALLOC_FREE(target);
612 if (tmp == NULL) {
613 return NT_STATUS_NO_MEMORY;
615 target = tmp;
618 DBG_DEBUG("redirecting to %s\n", target);
620 absolute = canonicalize_absolute_path(talloc_tos(), target);
621 TALLOC_FREE(target);
623 if (absolute == NULL) {
624 return NT_STATUS_NO_MEMORY;
628 * We're doing the "below connection_path" here because it's
629 * cheap. It might be that we get a symlink out of the share,
630 * pointing to yet another symlink getting us back into the
631 * share. If we need that, we would have to remove the check
632 * here.
634 ok = subdir_of(
635 connection_path,
636 connection_path_len,
637 absolute,
638 &relative);
639 if (!ok) {
640 DBG_NOTICE("Bad access attempt: %s is a symlink "
641 "outside the share path\n"
642 "conn_rootdir =%s\n"
643 "resolved_name=%s\n",
644 symlink_name->base_name,
645 connection_path,
646 absolute);
647 TALLOC_FREE(absolute);
648 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
651 if (relative[0] == '\0') {
653 * special case symlink to share root: "." is our
654 * share root filename
656 absolute[0] = '.';
657 absolute[1] = '\0';
658 } else {
659 memmove(absolute, relative, strlen(relative)+1);
662 *_target = absolute;
663 return NT_STATUS_OK;
666 /****************************************************************************
667 Non-widelink open.
668 ****************************************************************************/
670 static NTSTATUS non_widelink_open(const struct files_struct *dirfsp,
671 files_struct *fsp,
672 struct smb_filename *smb_fname,
673 const struct vfs_open_how *_how)
675 struct connection_struct *conn = fsp->conn;
676 const char *connpath = SMB_VFS_CONNECTPATH(conn, dirfsp, smb_fname);
677 size_t connpath_len;
678 NTSTATUS status = NT_STATUS_OK;
679 int fd = -1;
680 char *orig_smb_fname_base = smb_fname->base_name;
681 struct smb_filename *orig_fsp_name = fsp->fsp_name;
682 struct smb_filename *smb_fname_rel = NULL;
683 struct smb_filename *oldwd_fname = NULL;
684 struct smb_filename *parent_dir_fname = NULL;
685 struct vfs_open_how how = *_how;
686 char *target = NULL;
687 size_t link_depth = 0;
688 int ret;
690 SMB_ASSERT(!fsp_is_alternate_stream(fsp));
692 if (connpath == NULL) {
694 * This can happen with shadow_copy2 if the snapshot
695 * path is not found
697 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
699 connpath_len = strlen(connpath);
701 again:
702 if (smb_fname->base_name[0] == '/') {
703 int cmp = strcmp(connpath, smb_fname->base_name);
704 if (cmp == 0) {
705 smb_fname->base_name = talloc_strdup(smb_fname, "");
706 if (smb_fname->base_name == NULL) {
707 status = NT_STATUS_NO_MEMORY;
708 goto out;
713 if (dirfsp == conn->cwd_fsp) {
715 status = SMB_VFS_PARENT_PATHNAME(fsp->conn,
716 talloc_tos(),
717 smb_fname,
718 &parent_dir_fname,
719 &smb_fname_rel);
720 if (!NT_STATUS_IS_OK(status)) {
721 goto out;
724 status = chdir_below_conn(
725 talloc_tos(),
726 conn,
727 connpath,
728 connpath_len,
729 parent_dir_fname,
730 &oldwd_fname);
731 if (!NT_STATUS_IS_OK(status)) {
732 goto out;
735 /* Setup fsp->fsp_name to be relative to cwd */
736 fsp->fsp_name = smb_fname_rel;
737 } else {
739 * fsp->fsp_name is unchanged as it is already correctly
740 * relative to conn->cwd.
742 smb_fname_rel = smb_fname;
747 * Assert nobody can step in with a symlink on the
748 * path, there is no path anymore and we'll use
749 * O_NOFOLLOW to open.
751 char *slash = strchr_m(smb_fname_rel->base_name, '/');
752 SMB_ASSERT(slash == NULL);
755 how.flags |= O_NOFOLLOW;
757 fd = SMB_VFS_OPENAT(conn,
758 dirfsp,
759 smb_fname_rel,
760 fsp,
761 &how);
762 fsp_set_fd(fsp, fd); /* This preserves errno */
764 if (fd == -1) {
765 status = map_nt_error_from_unix(errno);
767 if (errno == ENOENT) {
768 goto out;
772 * ENOENT makes it worthless retrying with a
773 * stat, we know for sure the file does not
774 * exist. For everything else we want to know
775 * what's there.
777 ret = SMB_VFS_FSTATAT(
778 fsp->conn,
779 dirfsp,
780 smb_fname_rel,
781 &fsp->fsp_name->st,
782 AT_SYMLINK_NOFOLLOW);
784 if (ret == -1) {
786 * Keep the original error. Otherwise we would
787 * mask for example EROFS for open(O_CREAT),
788 * turning it into ENOENT.
790 goto out;
792 } else {
793 ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st);
796 if (ret == -1) {
797 status = map_nt_error_from_unix(errno);
798 DBG_DEBUG("fstat[at](%s) failed: %s\n",
799 smb_fname_str_dbg(smb_fname),
800 strerror(errno));
801 goto out;
804 fsp->fsp_flags.is_directory = S_ISDIR(fsp->fsp_name->st.st_ex_mode);
805 orig_fsp_name->st = fsp->fsp_name->st;
807 if (!S_ISLNK(fsp->fsp_name->st.st_ex_mode)) {
808 goto out;
812 * Found a symlink to follow in user space
815 if (fsp->fsp_name->flags & SMB_FILENAME_POSIX_PATH) {
816 /* Never follow symlinks on posix open. */
817 status = NT_STATUS_STOPPED_ON_SYMLINK;
818 goto out;
820 if (!lp_follow_symlinks(SNUM(conn))) {
821 /* Explicitly no symlinks. */
822 status = NT_STATUS_STOPPED_ON_SYMLINK;
823 goto out;
826 link_depth += 1;
827 if (link_depth >= 40) {
828 status = NT_STATUS_STOPPED_ON_SYMLINK;
829 goto out;
832 fsp->fsp_name = orig_fsp_name;
834 status = symlink_target_below_conn(
835 talloc_tos(),
836 connpath,
837 connpath_len,
838 fsp,
839 discard_const_p(files_struct, dirfsp),
840 smb_fname_rel,
841 &target);
843 if (!NT_STATUS_IS_OK(status)) {
844 DBG_DEBUG("symlink_target_below_conn() failed: %s\n",
845 nt_errstr(status));
846 goto out;
850 * Close what openat(O_PATH) potentially left behind
852 fd_close(fsp);
854 if (smb_fname->base_name != orig_smb_fname_base) {
855 TALLOC_FREE(smb_fname->base_name);
857 smb_fname->base_name = target;
859 if (oldwd_fname != NULL) {
860 ret = vfs_ChDir(conn, oldwd_fname);
861 if (ret == -1) {
862 smb_panic("unable to get back to old directory\n");
864 TALLOC_FREE(oldwd_fname);
868 * And do it all again... As smb_fname is not relative to the passed in
869 * dirfsp anymore, we pass conn->cwd_fsp as dirfsp to
870 * non_widelink_open() to trigger the chdir(parentdir) logic.
872 dirfsp = conn->cwd_fsp;
874 goto again;
876 out:
877 fsp->fsp_name = orig_fsp_name;
878 smb_fname->base_name = orig_smb_fname_base;
880 TALLOC_FREE(parent_dir_fname);
882 if (!NT_STATUS_IS_OK(status)) {
883 fd_close(fsp);
886 if (oldwd_fname != NULL) {
887 ret = vfs_ChDir(conn, oldwd_fname);
888 if (ret == -1) {
889 smb_panic("unable to get back to old directory\n");
891 TALLOC_FREE(oldwd_fname);
893 return status;
896 /****************************************************************************
897 fd support routines - attempt to do a dos_open.
898 ****************************************************************************/
900 NTSTATUS fd_openat(const struct files_struct *dirfsp,
901 struct smb_filename *smb_fname,
902 files_struct *fsp,
903 const struct vfs_open_how *_how)
905 struct vfs_open_how how = *_how;
906 struct connection_struct *conn = fsp->conn;
907 NTSTATUS status = NT_STATUS_OK;
908 bool fsp_is_stream = fsp_is_alternate_stream(fsp);
909 bool smb_fname_is_stream = is_named_stream(smb_fname);
911 SMB_ASSERT(fsp_is_stream == smb_fname_is_stream);
914 * Never follow symlinks on a POSIX client. The
915 * client should be doing this.
918 if ((fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) || !lp_follow_symlinks(SNUM(conn))) {
919 how.flags |= O_NOFOLLOW;
922 if (fsp_is_stream) {
923 int fd;
925 fd = SMB_VFS_OPENAT(
926 conn,
927 NULL, /* stream open is relative to fsp->base_fsp */
928 smb_fname,
929 fsp,
930 &how);
931 if (fd == -1) {
932 status = map_nt_error_from_unix(errno);
934 fsp_set_fd(fsp, fd);
936 if (fd != -1) {
937 status = vfs_stat_fsp(fsp);
938 if (!NT_STATUS_IS_OK(status)) {
939 DBG_DEBUG("vfs_stat_fsp failed: %s\n",
940 nt_errstr(status));
941 fd_close(fsp);
945 return status;
949 * Only follow symlinks within a share
950 * definition.
952 status = non_widelink_open(dirfsp, fsp, smb_fname, &how);
953 if (!NT_STATUS_IS_OK(status)) {
954 if (NT_STATUS_EQUAL(status, NT_STATUS_TOO_MANY_OPENED_FILES)) {
955 static time_t last_warned = 0L;
957 if (time((time_t *) NULL) > last_warned) {
958 DEBUG(0,("Too many open files, unable "
959 "to open more! smbd's max "
960 "open files = %d\n",
961 lp_max_open_files()));
962 last_warned = time((time_t *) NULL);
966 DBG_DEBUG("name %s, flags = 0%o mode = 0%o, fd = %d. %s\n",
967 smb_fname_str_dbg(smb_fname),
968 how.flags,
969 (int)how.mode,
970 fsp_get_pathref_fd(fsp),
971 nt_errstr(status));
972 return status;
975 DBG_DEBUG("name %s, flags = 0%o mode = 0%o, fd = %d\n",
976 smb_fname_str_dbg(smb_fname),
977 how.flags,
978 (int)how.mode,
979 fsp_get_pathref_fd(fsp));
981 return status;
984 /****************************************************************************
985 Close the file associated with a fsp.
986 ****************************************************************************/
988 NTSTATUS fd_close(files_struct *fsp)
990 NTSTATUS status;
991 int ret;
993 if (fsp == fsp->conn->cwd_fsp) {
994 return NT_STATUS_OK;
997 if (fsp->fsp_flags.fstat_before_close) {
998 status = vfs_stat_fsp(fsp);
999 if (!NT_STATUS_IS_OK(status)) {
1001 * If this is a stream and delete-on-close was set, the
1002 * backing object (an xattr from streams_xattr) might
1003 * already be deleted so fstat() fails with
1004 * NT_STATUS_NOT_FOUND. So if fsp refers to a stream we
1005 * ignore the error and only bail for normal files where
1006 * an fstat() should still work. NB. We cannot use
1007 * fsp_is_alternate_stream(fsp) for this as the base_fsp
1008 * has already been closed at this point and so the value
1009 * fsp_is_alternate_stream() checks for is already NULL.
1011 if (fsp->fsp_name->stream_name == NULL) {
1012 return status;
1017 if (fsp->dptr) {
1018 dptr_CloseDir(fsp);
1020 if (fsp_get_pathref_fd(fsp) == -1) {
1022 * Either a directory where the dptr_CloseDir() already closed
1023 * the fd or a stat open.
1025 return NT_STATUS_OK;
1027 if (fh_get_refcount(fsp->fh) > 1) {
1028 return NT_STATUS_OK; /* Shared handle. Only close last reference. */
1031 ret = SMB_VFS_CLOSE(fsp);
1032 fsp_set_fd(fsp, -1);
1033 if (ret == -1) {
1034 return map_nt_error_from_unix(errno);
1036 return NT_STATUS_OK;
1039 /****************************************************************************
1040 Change the ownership of a file to that of the parent directory.
1041 Do this by fd if possible.
1042 ****************************************************************************/
1044 static void change_file_owner_to_parent_fsp(struct files_struct *parent_fsp,
1045 struct files_struct *fsp)
1047 int ret;
1049 if (parent_fsp->fsp_name->st.st_ex_uid == fsp->fsp_name->st.st_ex_uid) {
1050 /* Already this uid - no need to change. */
1051 DBG_DEBUG("file %s is already owned by uid %u\n",
1052 fsp_str_dbg(fsp),
1053 (unsigned int)fsp->fsp_name->st.st_ex_uid);
1054 return;
1057 become_root();
1058 ret = SMB_VFS_FCHOWN(fsp,
1059 parent_fsp->fsp_name->st.st_ex_uid,
1060 (gid_t)-1);
1061 unbecome_root();
1062 if (ret == -1) {
1063 DBG_ERR("failed to fchown "
1064 "file %s to parent directory uid %u. Error "
1065 "was %s\n",
1066 fsp_str_dbg(fsp),
1067 (unsigned int)parent_fsp->fsp_name->st.st_ex_uid,
1068 strerror(errno));
1069 } else {
1070 DBG_DEBUG("changed new file %s to "
1071 "parent directory uid %u.\n",
1072 fsp_str_dbg(fsp),
1073 (unsigned int)parent_fsp->fsp_name->st.st_ex_uid);
1074 /* Ensure the uid entry is updated. */
1075 fsp->fsp_name->st.st_ex_uid =
1076 parent_fsp->fsp_name->st.st_ex_uid;
1080 static NTSTATUS change_dir_owner_to_parent_fsp(struct files_struct *parent_fsp,
1081 struct files_struct *fsp)
1083 NTSTATUS status;
1084 int ret;
1086 if (parent_fsp->fsp_name->st.st_ex_uid == fsp->fsp_name->st.st_ex_uid) {
1087 /* Already this uid - no need to change. */
1088 DBG_DEBUG("directory %s is already owned by uid %u\n",
1089 fsp_str_dbg(fsp),
1090 (unsigned int)fsp->fsp_name->st.st_ex_uid);
1091 return NT_STATUS_OK;
1094 become_root();
1095 ret = SMB_VFS_FCHOWN(fsp,
1096 parent_fsp->fsp_name->st.st_ex_uid,
1097 (gid_t)-1);
1098 unbecome_root();
1099 if (ret == -1) {
1100 status = map_nt_error_from_unix(errno);
1101 DBG_ERR("failed to chown "
1102 "directory %s to parent directory uid %u. "
1103 "Error was %s\n",
1104 fsp_str_dbg(fsp),
1105 (unsigned int)parent_fsp->fsp_name->st.st_ex_uid,
1106 nt_errstr(status));
1107 return status;
1110 DBG_DEBUG("changed ownership of new "
1111 "directory %s to parent directory uid %u.\n",
1112 fsp_str_dbg(fsp),
1113 (unsigned int)parent_fsp->fsp_name->st.st_ex_uid);
1115 /* Ensure the uid entry is updated. */
1116 fsp->fsp_name->st.st_ex_uid = parent_fsp->fsp_name->st.st_ex_uid;
1118 return NT_STATUS_OK;
1121 /****************************************************************************
1122 Open a file - returning a guaranteed ATOMIC indication of if the
1123 file was created or not.
1124 ****************************************************************************/
1126 static NTSTATUS fd_open_atomic(struct files_struct *dirfsp,
1127 struct smb_filename *smb_fname,
1128 files_struct *fsp,
1129 const struct vfs_open_how *_how,
1130 bool *file_created)
1132 struct vfs_open_how how = *_how;
1133 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
1134 NTSTATUS retry_status;
1135 bool file_existed = VALID_STAT(smb_fname->st);
1137 if (!(how.flags & O_CREAT)) {
1139 * We're not creating the file, just pass through.
1141 status = fd_openat(dirfsp, smb_fname, fsp, &how);
1142 *file_created = false;
1143 return status;
1146 if (how.flags & O_EXCL) {
1148 * Fail if already exists, just pass through.
1150 status = fd_openat(dirfsp, smb_fname, fsp, &how);
1153 * Here we've opened with O_CREAT|O_EXCL. If that went
1154 * NT_STATUS_OK, we *know* we created this file.
1156 *file_created = NT_STATUS_IS_OK(status);
1158 return status;
1162 * Now it gets tricky. We have O_CREAT, but not O_EXCL.
1163 * To know absolutely if we created the file or not,
1164 * we can never call O_CREAT without O_EXCL. So if
1165 * we think the file existed, try without O_CREAT|O_EXCL.
1166 * If we think the file didn't exist, try with
1167 * O_CREAT|O_EXCL.
1169 * The big problem here is dangling symlinks. Opening
1170 * without O_NOFOLLOW means both bad symlink
1171 * and missing path return -1, ENOENT from open(). As POSIX
1172 * is pathname based it's not possible to tell
1173 * the difference between these two cases in a
1174 * non-racy way, so change to try only two attempts before
1175 * giving up.
1177 * We don't have this problem for the O_NOFOLLOW
1178 * case as it just returns NT_STATUS_OBJECT_PATH_NOT_FOUND
1179 * mapped from the ELOOP POSIX error.
1182 if (file_existed) {
1183 how.flags = _how->flags & ~(O_CREAT);
1184 retry_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
1185 } else {
1186 how.flags = _how->flags | O_EXCL;
1187 retry_status = NT_STATUS_OBJECT_NAME_COLLISION;
1190 status = fd_openat(dirfsp, smb_fname, fsp, &how);
1191 if (NT_STATUS_IS_OK(status)) {
1192 *file_created = !file_existed;
1193 return NT_STATUS_OK;
1195 if (NT_STATUS_EQUAL(status, retry_status)) {
1197 file_existed = !file_existed;
1199 DBG_DEBUG("File %s %s. Retry.\n",
1200 fsp_str_dbg(fsp),
1201 file_existed ? "existed" : "did not exist");
1203 if (file_existed) {
1204 how.flags = _how->flags & ~(O_CREAT);
1205 } else {
1206 how.flags = _how->flags | O_EXCL;
1209 status = fd_openat(dirfsp, smb_fname, fsp, &how);
1212 *file_created = (NT_STATUS_IS_OK(status) && !file_existed);
1213 return status;
1216 static NTSTATUS reopen_from_fsp(struct files_struct *dirfsp,
1217 struct smb_filename *smb_fname,
1218 struct files_struct *fsp,
1219 const struct vfs_open_how *how,
1220 bool *p_file_created)
1222 NTSTATUS status;
1223 int old_fd;
1225 if (fsp->fsp_flags.have_proc_fds &&
1226 ((old_fd = fsp_get_pathref_fd(fsp)) != -1)) {
1228 struct sys_proc_fd_path_buf buf;
1229 struct smb_filename proc_fname = (struct smb_filename){
1230 .base_name = sys_proc_fd_path(old_fd, &buf),
1232 mode_t mode = fsp->fsp_name->st.st_ex_mode;
1233 int new_fd;
1235 SMB_ASSERT(fsp->fsp_flags.is_pathref);
1237 if (S_ISLNK(mode)) {
1238 return NT_STATUS_STOPPED_ON_SYMLINK;
1240 if (!(S_ISREG(mode) || S_ISDIR(mode))) {
1241 return NT_STATUS_IO_REPARSE_TAG_NOT_HANDLED;
1244 fsp->fsp_flags.is_pathref = false;
1246 new_fd = SMB_VFS_OPENAT(fsp->conn,
1247 fsp->conn->cwd_fsp,
1248 &proc_fname,
1249 fsp,
1250 how);
1251 if (new_fd == -1) {
1252 status = map_nt_error_from_unix(errno);
1253 fd_close(fsp);
1254 return status;
1257 status = fd_close(fsp);
1258 if (!NT_STATUS_IS_OK(status)) {
1259 return status;
1262 fsp_set_fd(fsp, new_fd);
1263 return NT_STATUS_OK;
1267 * Close the existing pathref fd and set the fsp flag
1268 * is_pathref to false so we get a "normal" fd this time.
1270 status = fd_close(fsp);
1271 if (!NT_STATUS_IS_OK(status)) {
1272 return status;
1275 fsp->fsp_flags.is_pathref = false;
1277 status = fd_open_atomic(dirfsp, smb_fname, fsp, how, p_file_created);
1278 return status;
1281 /****************************************************************************
1282 Open a file.
1283 ****************************************************************************/
1285 static NTSTATUS open_file(
1286 struct smb_request *req,
1287 struct files_struct *dirfsp,
1288 struct smb_filename *smb_fname_atname,
1289 files_struct *fsp,
1290 const struct vfs_open_how *_how,
1291 uint32_t access_mask, /* client requested access mask. */
1292 uint32_t open_access_mask, /* what we're actually using in the open. */
1293 uint32_t private_flags,
1294 bool *p_file_created)
1296 connection_struct *conn = fsp->conn;
1297 struct smb_filename *smb_fname = fsp->fsp_name;
1298 struct vfs_open_how how = *_how;
1299 NTSTATUS status = NT_STATUS_OK;
1300 bool file_existed = VALID_STAT(fsp->fsp_name->st);
1301 const uint32_t need_fd_mask =
1302 FILE_READ_DATA |
1303 FILE_WRITE_DATA |
1304 FILE_APPEND_DATA |
1305 FILE_EXECUTE |
1306 SEC_FLAG_SYSTEM_SECURITY;
1307 bool creating = !file_existed && (how.flags & O_CREAT);
1308 bool open_fd = false;
1309 bool posix_open = (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN);
1312 * Catch early an attempt to open an existing
1313 * directory as a file.
1315 if (file_existed && S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
1316 return NT_STATUS_FILE_IS_A_DIRECTORY;
1320 * This little piece of insanity is inspired by the
1321 * fact that an NT client can open a file for O_RDONLY,
1322 * but set the create disposition to FILE_EXISTS_TRUNCATE.
1323 * If the client *can* write to the file, then it expects to
1324 * truncate the file, even though it is opening for readonly.
1325 * Quicken uses this stupid trick in backup file creation...
1326 * Thanks *greatly* to "David W. Chapman Jr." <dwcjr@inethouston.net>
1327 * for helping track this one down. It didn't bite us in 2.0.x
1328 * as we always opened files read-write in that release. JRA.
1331 if (((how.flags & O_ACCMODE) == O_RDONLY) && (how.flags & O_TRUNC)) {
1332 DBG_DEBUG("truncate requested on read-only open for file %s\n",
1333 smb_fname_str_dbg(smb_fname));
1334 how.flags = (how.flags & ~O_ACCMODE) | O_RDWR;
1337 /* Check permissions */
1340 * This code was changed after seeing a client open request
1341 * containing the open mode of (DENY_WRITE/read-only) with
1342 * the 'create if not exist' bit set. The previous code
1343 * would fail to open the file read only on a read-only share
1344 * as it was checking the flags parameter directly against O_RDONLY,
1345 * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
1346 * JRA.
1349 if (!CAN_WRITE(conn)) {
1350 /* It's a read-only share - fail if we wanted to write. */
1351 if ((how.flags & O_ACCMODE) != O_RDONLY ||
1352 (how.flags & O_TRUNC) || (how.flags & O_APPEND)) {
1353 DEBUG(3,("Permission denied opening %s\n",
1354 smb_fname_str_dbg(smb_fname)));
1355 return NT_STATUS_ACCESS_DENIED;
1358 * We don't want to write - but we must make sure that
1359 * O_CREAT doesn't create the file if we have write
1360 * access into the directory.
1362 how.flags &= ~(O_CREAT | O_EXCL);
1365 if ((open_access_mask & need_fd_mask) || creating ||
1366 (how.flags & O_TRUNC)) {
1367 open_fd = true;
1370 if (open_fd) {
1371 int ret;
1373 #if defined(O_NONBLOCK) && defined(S_ISFIFO)
1375 * We would block on opening a FIFO with no one else on the
1376 * other end. Do what we used to do and add O_NONBLOCK to the
1377 * open flags. JRA.
1380 if (file_existed && S_ISFIFO(smb_fname->st.st_ex_mode)) {
1381 how.flags |= O_NONBLOCK;
1383 #endif
1385 if (!posix_open) {
1386 const char *wild = smb_fname->base_name;
1388 * Don't open files with Microsoft wildcard characters.
1390 if (fsp_is_alternate_stream(fsp)) {
1392 * wildcard characters are allowed in stream
1393 * names only test the basefilename
1395 wild = fsp->base_fsp->fsp_name->base_name;
1398 if (ms_has_wild(wild)) {
1399 return NT_STATUS_OBJECT_NAME_INVALID;
1403 /* Can we access this file ? */
1404 if (!fsp_is_alternate_stream(fsp)) {
1405 /* Only do this check on non-stream open. */
1406 if (file_existed) {
1407 status = smbd_check_access_rights_fsp(
1408 dirfsp,
1409 fsp,
1410 false,
1411 open_access_mask);
1413 if (!NT_STATUS_IS_OK(status)) {
1414 DBG_DEBUG("smbd_check_access_rights_fsp"
1415 " on file %s returned %s\n",
1416 fsp_str_dbg(fsp),
1417 nt_errstr(status));
1420 if (!NT_STATUS_IS_OK(status) &&
1421 !NT_STATUS_EQUAL(status,
1422 NT_STATUS_OBJECT_NAME_NOT_FOUND))
1424 return status;
1427 if (NT_STATUS_EQUAL(status,
1428 NT_STATUS_OBJECT_NAME_NOT_FOUND))
1430 DEBUG(10, ("open_file: "
1431 "file %s vanished since we "
1432 "checked for existence.\n",
1433 smb_fname_str_dbg(smb_fname)));
1434 file_existed = false;
1435 SET_STAT_INVALID(fsp->fsp_name->st);
1439 if (!file_existed) {
1440 if (!(how.flags & O_CREAT)) {
1441 /* File didn't exist and no O_CREAT. */
1442 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1445 status = check_parent_access_fsp(
1446 dirfsp,
1447 SEC_DIR_ADD_FILE);
1448 if (!NT_STATUS_IS_OK(status)) {
1449 DBG_DEBUG("check_parent_access_fsp on "
1450 "directory %s for file %s "
1451 "returned %s\n",
1452 smb_fname_str_dbg(
1453 dirfsp->fsp_name),
1454 smb_fname_str_dbg(smb_fname),
1455 nt_errstr(status));
1456 return status;
1462 * Actually do the open - if O_TRUNC is needed handle it
1463 * below under the share mode lock.
1465 how.flags &= ~O_TRUNC;
1466 status = reopen_from_fsp(dirfsp,
1467 smb_fname_atname,
1468 fsp,
1469 &how,
1470 p_file_created);
1471 if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) {
1473 * Non-O_PATH reopen that hit a race
1474 * condition: Someone has put a symlink where
1475 * we used to have a file. Can't happen with
1476 * O_PATH and reopening from /proc/self/fd/ or
1477 * equivalent.
1479 status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
1481 if (!NT_STATUS_IS_OK(status)) {
1482 DBG_NOTICE("Error opening file %s (%s) (in_flags=%d) "
1483 "(flags=%d)\n",
1484 smb_fname_str_dbg(smb_fname),
1485 nt_errstr(status),
1486 _how->flags,
1487 how.flags);
1488 return status;
1491 if (how.flags & O_NONBLOCK) {
1493 * GPFS can return ETIMEDOUT for pread on
1494 * nonblocking file descriptors when files
1495 * migrated to tape need to be recalled. I
1496 * could imagine this happens elsewhere
1497 * too. With blocking file descriptors this
1498 * does not happen.
1500 ret = vfs_set_blocking(fsp, true);
1501 if (ret == -1) {
1502 status = map_nt_error_from_unix(errno);
1503 DBG_WARNING("Could not set fd to blocking: "
1504 "%s\n", strerror(errno));
1505 fd_close(fsp);
1506 return status;
1510 if (*p_file_created) {
1511 /* We created this file. */
1513 bool need_re_stat = false;
1514 /* Do all inheritance work after we've
1515 done a successful fstat call and filled
1516 in the stat struct in fsp->fsp_name. */
1518 /* Inherit the ACL if required */
1519 if (lp_inherit_permissions(SNUM(conn))) {
1520 inherit_access_posix_acl(conn,
1521 dirfsp,
1522 smb_fname,
1523 how.mode);
1524 need_re_stat = true;
1527 /* Change the owner if required. */
1528 if (lp_inherit_owner(SNUM(conn)) != INHERIT_OWNER_NO) {
1529 change_file_owner_to_parent_fsp(dirfsp, fsp);
1530 need_re_stat = true;
1533 if (need_re_stat) {
1534 status = vfs_stat_fsp(fsp);
1536 * If we have an fd, this stat should succeed.
1538 if (!NT_STATUS_IS_OK(status)) {
1539 DBG_ERR("Error doing fstat on open "
1540 "file %s (%s)\n",
1541 smb_fname_str_dbg(smb_fname),
1542 nt_errstr(status));
1543 fd_close(fsp);
1544 return status;
1548 notify_fname(conn, NOTIFY_ACTION_ADDED,
1549 FILE_NOTIFY_CHANGE_FILE_NAME,
1550 smb_fname->base_name);
1552 } else {
1553 if (!file_existed) {
1554 /* File must exist for a stat open. */
1555 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1558 if (S_ISLNK(smb_fname->st.st_ex_mode) &&
1559 !posix_open)
1562 * Don't allow stat opens on symlinks directly unless
1563 * it's a POSIX open. Match the return code from
1564 * openat_pathref_fsp().
1566 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1569 if (!fsp->fsp_flags.is_pathref) {
1571 * There is only one legit case where end up here:
1572 * openat_pathref_fsp() failed to open a symlink, so the
1573 * fsp was created by fsp_new() which doesn't set
1574 * is_pathref. Other than that, we should always have a
1575 * pathref fsp at this point. The subsequent checks
1576 * assert this.
1578 if (!(smb_fname->flags & SMB_FILENAME_POSIX_PATH)) {
1579 DBG_ERR("[%s] is not a POSIX pathname\n",
1580 smb_fname_str_dbg(smb_fname));
1581 return NT_STATUS_INTERNAL_ERROR;
1583 if (!S_ISLNK(smb_fname->st.st_ex_mode)) {
1584 DBG_ERR("[%s] is not a symlink\n",
1585 smb_fname_str_dbg(smb_fname));
1586 return NT_STATUS_INTERNAL_ERROR;
1588 if (fsp_get_pathref_fd(fsp) != -1) {
1589 DBG_ERR("fd for [%s] is not -1: fd [%d]\n",
1590 smb_fname_str_dbg(smb_fname),
1591 fsp_get_pathref_fd(fsp));
1592 return NT_STATUS_INTERNAL_ERROR;
1597 * Access to streams is checked by checking the basefile and
1598 * that has already been checked by check_base_file_access()
1599 * in create_file_unixpath().
1601 if (!fsp_is_alternate_stream(fsp)) {
1602 status = smbd_check_access_rights_fsp(dirfsp,
1603 fsp,
1604 false,
1605 open_access_mask);
1607 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) &&
1608 posix_open &&
1609 S_ISLNK(smb_fname->st.st_ex_mode)) {
1610 /* This is a POSIX stat open for delete
1611 * or rename on a symlink that points
1612 * nowhere. Allow. */
1613 DEBUG(10,("open_file: allowing POSIX "
1614 "open on bad symlink %s\n",
1615 smb_fname_str_dbg(smb_fname)));
1616 status = NT_STATUS_OK;
1619 if (!NT_STATUS_IS_OK(status)) {
1620 DBG_DEBUG("smbd_check_access_rights_fsp on file "
1621 "%s returned %s\n",
1622 fsp_str_dbg(fsp),
1623 nt_errstr(status));
1624 return status;
1629 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
1630 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
1631 fsp->file_pid = req ? req->smbpid : 0;
1632 fsp->fsp_flags.can_lock = true;
1633 fsp->fsp_flags.can_read = ((access_mask & FILE_READ_DATA) != 0);
1634 fsp->fsp_flags.can_write =
1635 CAN_WRITE(conn) &&
1636 ((access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) != 0);
1637 fsp->print_file = NULL;
1638 fsp->fsp_flags.modified = false;
1639 fsp->sent_oplock_break = NO_BREAK_SENT;
1640 fsp->fsp_flags.is_directory = false;
1641 if (is_in_path(smb_fname->base_name,
1642 conn->aio_write_behind_list,
1643 posix_open ? true : conn->case_sensitive)) {
1644 fsp->fsp_flags.aio_write_behind = true;
1647 DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
1648 conn->session_info->unix_info->unix_name,
1649 smb_fname_str_dbg(smb_fname),
1650 BOOLSTR(fsp->fsp_flags.can_read),
1651 BOOLSTR(fsp->fsp_flags.can_write),
1652 conn->num_files_open));
1654 return NT_STATUS_OK;
1657 static bool mask_conflict(
1658 uint32_t new_access,
1659 uint32_t existing_access,
1660 uint32_t access_mask,
1661 uint32_t new_sharemode,
1662 uint32_t existing_sharemode,
1663 uint32_t sharemode_mask)
1665 bool want_access = (new_access & access_mask);
1666 bool allow_existing = (existing_sharemode & sharemode_mask);
1667 bool have_access = (existing_access & access_mask);
1668 bool allow_new = (new_sharemode & sharemode_mask);
1670 if (want_access && !allow_existing) {
1671 DBG_DEBUG("Access request 0x%"PRIx32"/0x%"PRIx32" conflicts "
1672 "with existing sharemode 0x%"PRIx32"/0x%"PRIx32"\n",
1673 new_access,
1674 access_mask,
1675 existing_sharemode,
1676 sharemode_mask);
1677 return true;
1679 if (have_access && !allow_new) {
1680 DBG_DEBUG("Sharemode request 0x%"PRIx32"/0x%"PRIx32" conflicts "
1681 "with existing access 0x%"PRIx32"/0x%"PRIx32"\n",
1682 new_sharemode,
1683 sharemode_mask,
1684 existing_access,
1685 access_mask);
1686 return true;
1688 return false;
1691 /****************************************************************************
1692 Check if we can open a file with a share mode.
1693 Returns True if conflict, False if not.
1694 ****************************************************************************/
1696 static const uint32_t conflicting_access =
1697 FILE_WRITE_DATA|
1698 FILE_APPEND_DATA|
1699 FILE_READ_DATA|
1700 FILE_EXECUTE|
1701 DELETE_ACCESS;
1703 static bool share_conflict(uint32_t e_access_mask,
1704 uint32_t e_share_access,
1705 uint32_t access_mask,
1706 uint32_t share_access)
1708 bool conflict;
1710 DBG_DEBUG("existing access_mask = 0x%"PRIx32", "
1711 "existing share access = 0x%"PRIx32", "
1712 "access_mask = 0x%"PRIx32", "
1713 "share_access = 0x%"PRIx32"\n",
1714 e_access_mask,
1715 e_share_access,
1716 access_mask,
1717 share_access);
1719 if ((e_access_mask & conflicting_access) == 0) {
1720 DBG_DEBUG("No conflict due to "
1721 "existing access_mask = 0x%"PRIx32"\n",
1722 e_access_mask);
1723 return false;
1725 if ((access_mask & conflicting_access) == 0) {
1726 DBG_DEBUG("No conflict due to access_mask = 0x%"PRIx32"\n",
1727 access_mask);
1728 return false;
1731 conflict = mask_conflict(
1732 access_mask, e_access_mask, FILE_WRITE_DATA | FILE_APPEND_DATA,
1733 share_access, e_share_access, FILE_SHARE_WRITE);
1734 conflict |= mask_conflict(
1735 access_mask, e_access_mask, FILE_READ_DATA | FILE_EXECUTE,
1736 share_access, e_share_access, FILE_SHARE_READ);
1737 conflict |= mask_conflict(
1738 access_mask, e_access_mask, DELETE_ACCESS,
1739 share_access, e_share_access, FILE_SHARE_DELETE);
1741 DBG_DEBUG("conflict=%s\n", conflict ? "true" : "false");
1742 return conflict;
1745 #if defined(DEVELOPER)
1747 struct validate_my_share_entries_state {
1748 struct smbd_server_connection *sconn;
1749 struct file_id fid;
1750 struct server_id self;
1753 static bool validate_my_share_entries_fn(
1754 struct share_mode_entry *e,
1755 bool *modified,
1756 void *private_data)
1758 struct validate_my_share_entries_state *state = private_data;
1759 files_struct *fsp;
1761 if (!server_id_equal(&state->self, &e->pid)) {
1762 return false;
1765 if (e->op_mid == 0) {
1766 /* INTERNAL_OPEN_ONLY */
1767 return false;
1770 fsp = file_find_dif(state->sconn, state->fid, e->share_file_id);
1771 if (!fsp) {
1772 DBG_ERR("PANIC : %s\n",
1773 share_mode_str(talloc_tos(), 0, &state->fid, e));
1774 smb_panic("validate_my_share_entries: Cannot match a "
1775 "share entry with an open file\n");
1778 if (((uint16_t)fsp->oplock_type) != e->op_type) {
1779 goto panic;
1782 return false;
1784 panic:
1786 char *str;
1787 DBG_ERR("validate_my_share_entries: PANIC : %s\n",
1788 share_mode_str(talloc_tos(), 0, &state->fid, e));
1789 str = talloc_asprintf(talloc_tos(),
1790 "validate_my_share_entries: "
1791 "file %s, oplock_type = 0x%x, op_type = 0x%x\n",
1792 fsp->fsp_name->base_name,
1793 (unsigned int)fsp->oplock_type,
1794 (unsigned int)e->op_type);
1795 smb_panic(str);
1798 return false;
1800 #endif
1803 * Allowed access mask for stat opens relevant to oplocks
1805 bool is_oplock_stat_open(uint32_t access_mask)
1807 const uint32_t stat_open_bits =
1808 (SYNCHRONIZE_ACCESS|
1809 FILE_READ_ATTRIBUTES|
1810 FILE_WRITE_ATTRIBUTES);
1812 return (((access_mask & stat_open_bits) != 0) &&
1813 ((access_mask & ~stat_open_bits) == 0));
1817 * Allowed access mask for stat opens relevant to leases
1819 bool is_lease_stat_open(uint32_t access_mask)
1821 const uint32_t stat_open_bits =
1822 (SYNCHRONIZE_ACCESS|
1823 FILE_READ_ATTRIBUTES|
1824 FILE_WRITE_ATTRIBUTES|
1825 READ_CONTROL_ACCESS);
1827 return (((access_mask & stat_open_bits) != 0) &&
1828 ((access_mask & ~stat_open_bits) == 0));
1831 struct has_delete_on_close_state {
1832 bool ret;
1835 static bool has_delete_on_close_fn(
1836 struct share_mode_entry *e,
1837 bool *modified,
1838 void *private_data)
1840 struct has_delete_on_close_state *state = private_data;
1841 state->ret = !share_entry_stale_pid(e);
1842 return state->ret;
1845 static bool has_delete_on_close(struct share_mode_lock *lck,
1846 uint32_t name_hash)
1848 struct has_delete_on_close_state state = { .ret = false };
1849 bool ok;
1851 if (!is_delete_on_close_set(lck, name_hash)) {
1852 return false;
1855 ok= share_mode_forall_entries(lck, has_delete_on_close_fn, &state);
1856 if (!ok) {
1857 DBG_DEBUG("share_mode_forall_entries failed\n");
1858 return false;
1860 return state.ret;
1863 static void share_mode_flags_restrict(
1864 struct share_mode_lock *lck,
1865 uint32_t access_mask,
1866 uint32_t share_mode,
1867 uint32_t lease_type)
1869 uint32_t existing_access_mask, existing_share_mode;
1870 uint32_t existing_lease_type;
1872 share_mode_flags_get(
1873 lck,
1874 &existing_access_mask,
1875 &existing_share_mode,
1876 &existing_lease_type);
1878 existing_access_mask |= access_mask;
1879 if (access_mask & conflicting_access) {
1880 existing_share_mode &= share_mode;
1882 existing_lease_type |= lease_type;
1884 share_mode_flags_set(
1885 lck,
1886 existing_access_mask,
1887 existing_share_mode,
1888 existing_lease_type,
1889 NULL);
1892 /****************************************************************************
1893 Deal with share modes
1894 Invariant: Share mode must be locked on entry and exit.
1895 Returns -1 on error, or number of share modes on success (may be zero).
1896 ****************************************************************************/
1898 struct open_mode_check_state {
1899 struct file_id fid;
1900 uint32_t access_mask;
1901 uint32_t share_access;
1902 uint32_t lease_type;
1905 static bool open_mode_check_fn(
1906 struct share_mode_entry *e,
1907 bool *modified,
1908 void *private_data)
1910 struct open_mode_check_state *state = private_data;
1911 bool disconnected, stale;
1912 uint32_t access_mask, share_access, lease_type;
1914 disconnected = server_id_is_disconnected(&e->pid);
1915 if (disconnected) {
1916 return false;
1919 access_mask = state->access_mask | e->access_mask;
1920 share_access = state->share_access;
1921 if (e->access_mask & conflicting_access) {
1922 share_access &= e->share_access;
1924 lease_type = state->lease_type | get_lease_type(e, state->fid);
1926 if ((access_mask == state->access_mask) &&
1927 (share_access == state->share_access) &&
1928 (lease_type == state->lease_type)) {
1929 return false;
1932 stale = share_entry_stale_pid(e);
1933 if (stale) {
1934 return false;
1937 state->access_mask = access_mask;
1938 state->share_access = share_access;
1939 state->lease_type = lease_type;
1941 return false;
1944 static NTSTATUS open_mode_check(connection_struct *conn,
1945 struct file_id fid,
1946 struct share_mode_lock *lck,
1947 uint32_t access_mask,
1948 uint32_t share_access)
1950 struct open_mode_check_state state;
1951 bool ok, conflict;
1952 bool modified = false;
1954 if (is_oplock_stat_open(access_mask)) {
1955 /* Stat open that doesn't trigger oplock breaks or share mode
1956 * checks... ! JRA. */
1957 return NT_STATUS_OK;
1961 * Check if the share modes will give us access.
1964 #if defined(DEVELOPER)
1966 struct validate_my_share_entries_state validate_state = {
1967 .sconn = conn->sconn,
1968 .fid = fid,
1969 .self = messaging_server_id(conn->sconn->msg_ctx),
1971 ok = share_mode_forall_entries(
1972 lck, validate_my_share_entries_fn, &validate_state);
1973 SMB_ASSERT(ok);
1975 #endif
1977 share_mode_flags_get(
1978 lck, &state.access_mask, &state.share_access, NULL);
1980 conflict = share_conflict(
1981 state.access_mask,
1982 state.share_access,
1983 access_mask,
1984 share_access);
1985 if (!conflict) {
1986 DBG_DEBUG("No conflict due to share_mode_flags access\n");
1987 return NT_STATUS_OK;
1990 state = (struct open_mode_check_state) {
1991 .fid = fid,
1992 .share_access = (FILE_SHARE_READ|
1993 FILE_SHARE_WRITE|
1994 FILE_SHARE_DELETE),
1998 * Walk the share mode array to recalculate d->flags
2001 ok = share_mode_forall_entries(lck, open_mode_check_fn, &state);
2002 if (!ok) {
2003 DBG_DEBUG("share_mode_forall_entries failed\n");
2004 return NT_STATUS_INTERNAL_ERROR;
2007 share_mode_flags_set(
2008 lck,
2009 state.access_mask,
2010 state.share_access,
2011 state.lease_type,
2012 &modified);
2013 if (!modified) {
2015 * We only end up here if we had a sharing violation
2016 * from d->flags and have recalculated it.
2018 return NT_STATUS_SHARING_VIOLATION;
2021 conflict = share_conflict(
2022 state.access_mask,
2023 state.share_access,
2024 access_mask,
2025 share_access);
2026 if (!conflict) {
2027 DBG_DEBUG("No conflict due to share_mode_flags access\n");
2028 return NT_STATUS_OK;
2031 return NT_STATUS_SHARING_VIOLATION;
2035 * Send a break message to the oplock holder and delay the open for
2036 * our client.
2039 NTSTATUS send_break_message(struct messaging_context *msg_ctx,
2040 const struct file_id *id,
2041 const struct share_mode_entry *exclusive,
2042 uint16_t break_to)
2044 struct oplock_break_message msg = {
2045 .id = *id,
2046 .share_file_id = exclusive->share_file_id,
2047 .break_to = break_to,
2049 enum ndr_err_code ndr_err;
2050 DATA_BLOB blob;
2051 NTSTATUS status;
2053 if (DEBUGLVL(10)) {
2054 struct server_id_buf buf;
2055 DBG_DEBUG("Sending break message to %s\n",
2056 server_id_str_buf(exclusive->pid, &buf));
2057 NDR_PRINT_DEBUG(oplock_break_message, &msg);
2060 ndr_err = ndr_push_struct_blob(
2061 &blob,
2062 talloc_tos(),
2063 &msg,
2064 (ndr_push_flags_fn_t)ndr_push_oplock_break_message);
2065 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2066 DBG_WARNING("ndr_push_oplock_break_message failed: %s\n",
2067 ndr_errstr(ndr_err));
2068 return ndr_map_error2ntstatus(ndr_err);
2071 status = messaging_send(
2072 msg_ctx, exclusive->pid, MSG_SMB_BREAK_REQUEST, &blob);
2073 TALLOC_FREE(blob.data);
2074 if (!NT_STATUS_IS_OK(status)) {
2075 DEBUG(3, ("Could not send oplock break message: %s\n",
2076 nt_errstr(status)));
2079 return status;
2082 struct validate_oplock_types_state {
2083 bool valid;
2084 bool batch;
2085 bool ex_or_batch;
2086 bool level2;
2087 bool no_oplock;
2088 uint32_t num_non_stat_opens;
2091 static bool validate_oplock_types_fn(
2092 struct share_mode_entry *e,
2093 bool *modified,
2094 void *private_data)
2096 struct validate_oplock_types_state *state = private_data;
2098 if (e->op_mid == 0) {
2099 /* INTERNAL_OPEN_ONLY */
2100 return false;
2103 if (e->op_type == NO_OPLOCK && is_oplock_stat_open(e->access_mask)) {
2105 * We ignore stat opens in the table - they always
2106 * have NO_OPLOCK and never get or cause breaks. JRA.
2108 return false;
2111 state->num_non_stat_opens += 1;
2113 if (BATCH_OPLOCK_TYPE(e->op_type)) {
2114 /* batch - can only be one. */
2115 if (share_entry_stale_pid(e)) {
2116 DBG_DEBUG("Found stale batch oplock\n");
2117 return false;
2119 if (state->ex_or_batch ||
2120 state->batch ||
2121 state->level2 ||
2122 state->no_oplock) {
2123 DBG_ERR("Bad batch oplock entry\n");
2124 state->valid = false;
2125 return true;
2127 state->batch = true;
2130 if (EXCLUSIVE_OPLOCK_TYPE(e->op_type)) {
2131 if (share_entry_stale_pid(e)) {
2132 DBG_DEBUG("Found stale duplicate oplock\n");
2133 return false;
2135 /* Exclusive or batch - can only be one. */
2136 if (state->ex_or_batch ||
2137 state->level2 ||
2138 state->no_oplock) {
2139 DBG_ERR("Bad exclusive or batch oplock entry\n");
2140 state->valid = false;
2141 return true;
2143 state->ex_or_batch = true;
2146 if (LEVEL_II_OPLOCK_TYPE(e->op_type)) {
2147 if (state->batch || state->ex_or_batch) {
2148 if (share_entry_stale_pid(e)) {
2149 DBG_DEBUG("Found stale LevelII oplock\n");
2150 return false;
2152 DBG_DEBUG("Bad levelII oplock entry\n");
2153 state->valid = false;
2154 return true;
2156 state->level2 = true;
2159 if (e->op_type == NO_OPLOCK) {
2160 if (state->batch || state->ex_or_batch) {
2161 if (share_entry_stale_pid(e)) {
2162 DBG_DEBUG("Found stale NO_OPLOCK entry\n");
2163 return false;
2165 DBG_ERR("Bad no oplock entry\n");
2166 state->valid = false;
2167 return true;
2169 state->no_oplock = true;
2172 return false;
2176 * Do internal consistency checks on the share mode for a file.
2179 static bool validate_oplock_types(struct share_mode_lock *lck)
2181 struct validate_oplock_types_state state = { .valid = true };
2182 static bool skip_validation;
2183 bool validate;
2184 bool ok;
2186 if (skip_validation) {
2187 return true;
2190 validate = lp_parm_bool(-1, "smbd", "validate_oplock_types", false);
2191 if (!validate) {
2192 DBG_DEBUG("smbd:validate_oplock_types not set to yes\n");
2193 skip_validation = true;
2194 return true;
2197 ok = share_mode_forall_entries(lck, validate_oplock_types_fn, &state);
2198 if (!ok) {
2199 DBG_DEBUG("share_mode_forall_entries failed\n");
2200 return false;
2202 if (!state.valid) {
2203 DBG_DEBUG("Got invalid oplock configuration\n");
2204 return false;
2207 if ((state.batch || state.ex_or_batch) &&
2208 (state.num_non_stat_opens != 1)) {
2209 DBG_WARNING("got batch (%d) or ex (%d) non-exclusively "
2210 "(%"PRIu32")\n",
2211 (int)state.batch,
2212 (int)state.ex_or_batch,
2213 state.num_non_stat_opens);
2214 return false;
2217 return true;
2220 static bool is_same_lease(const files_struct *fsp,
2221 const struct share_mode_entry *e,
2222 const struct smb2_lease *lease)
2224 if (e->op_type != LEASE_OPLOCK) {
2225 return false;
2227 if (lease == NULL) {
2228 return false;
2231 return smb2_lease_equal(fsp_client_guid(fsp),
2232 &lease->lease_key,
2233 &e->client_guid,
2234 &e->lease_key);
2237 static bool file_has_brlocks(files_struct *fsp)
2239 struct byte_range_lock *br_lck;
2241 br_lck = brl_get_locks_readonly(fsp);
2242 if (!br_lck)
2243 return false;
2245 return (brl_num_locks(br_lck) > 0);
2248 struct fsp_lease *find_fsp_lease(struct files_struct *new_fsp,
2249 const struct smb2_lease_key *key,
2250 uint32_t current_state,
2251 uint16_t lease_version,
2252 uint16_t lease_epoch)
2254 struct files_struct *fsp;
2257 * TODO: Measure how expensive this loop is with thousands of open
2258 * handles...
2261 for (fsp = file_find_di_first(new_fsp->conn->sconn, new_fsp->file_id, true);
2262 fsp != NULL;
2263 fsp = file_find_di_next(fsp, true)) {
2265 if (fsp == new_fsp) {
2266 continue;
2268 if (fsp->oplock_type != LEASE_OPLOCK) {
2269 continue;
2271 if (smb2_lease_key_equal(&fsp->lease->lease.lease_key, key)) {
2272 fsp->lease->ref_count += 1;
2273 return fsp->lease;
2277 /* Not found - must be leased in another smbd. */
2278 new_fsp->lease = talloc_zero(new_fsp->conn->sconn, struct fsp_lease);
2279 if (new_fsp->lease == NULL) {
2280 return NULL;
2282 new_fsp->lease->ref_count = 1;
2283 new_fsp->lease->sconn = new_fsp->conn->sconn;
2284 new_fsp->lease->lease.lease_key = *key;
2285 new_fsp->lease->lease.lease_state = current_state;
2287 * We internally treat all leases as V2 and update
2288 * the epoch, but when sending breaks it matters if
2289 * the requesting lease was v1 or v2.
2291 new_fsp->lease->lease.lease_version = lease_version;
2292 new_fsp->lease->lease.lease_epoch = lease_epoch;
2293 return new_fsp->lease;
2296 static NTSTATUS try_lease_upgrade(struct files_struct *fsp,
2297 struct share_mode_lock *lck,
2298 const struct GUID *client_guid,
2299 const struct smb2_lease *lease,
2300 uint32_t granted)
2302 bool do_upgrade;
2303 uint32_t current_state, breaking_to_requested, breaking_to_required;
2304 bool breaking;
2305 uint16_t lease_version, epoch;
2306 uint32_t existing, requested;
2307 NTSTATUS status;
2309 status = leases_db_get(
2310 client_guid,
2311 &lease->lease_key,
2312 &fsp->file_id,
2313 &current_state,
2314 &breaking,
2315 &breaking_to_requested,
2316 &breaking_to_required,
2317 &lease_version,
2318 &epoch);
2319 if (!NT_STATUS_IS_OK(status)) {
2320 return status;
2323 fsp->lease = find_fsp_lease(
2324 fsp,
2325 &lease->lease_key,
2326 current_state,
2327 lease_version,
2328 epoch);
2329 if (fsp->lease == NULL) {
2330 DEBUG(1, ("Did not find existing lease for file %s\n",
2331 fsp_str_dbg(fsp)));
2332 return NT_STATUS_NO_MEMORY;
2336 * Upgrade only if the requested lease is a strict upgrade.
2338 existing = current_state;
2339 requested = lease->lease_state;
2342 * Tricky: This test makes sure that "requested" is a
2343 * strict bitwise superset of "existing".
2345 do_upgrade = ((existing & requested) == existing);
2348 * Upgrade only if there's a change.
2350 do_upgrade &= (granted != existing);
2353 * Upgrade only if other leases don't prevent what was asked
2354 * for.
2356 do_upgrade &= (granted == requested);
2359 * only upgrade if we are not in breaking state
2361 do_upgrade &= !breaking;
2363 DEBUG(10, ("existing=%"PRIu32", requested=%"PRIu32", "
2364 "granted=%"PRIu32", do_upgrade=%d\n",
2365 existing, requested, granted, (int)do_upgrade));
2367 if (do_upgrade) {
2368 NTSTATUS set_status;
2370 current_state = granted;
2371 epoch += 1;
2373 set_status = leases_db_set(
2374 client_guid,
2375 &lease->lease_key,
2376 current_state,
2377 breaking,
2378 breaking_to_requested,
2379 breaking_to_required,
2380 lease_version,
2381 epoch);
2383 if (!NT_STATUS_IS_OK(set_status)) {
2384 DBG_DEBUG("leases_db_set failed: %s\n",
2385 nt_errstr(set_status));
2386 return set_status;
2390 fsp_lease_update(fsp);
2392 return NT_STATUS_OK;
2395 static NTSTATUS grant_new_fsp_lease(struct files_struct *fsp,
2396 struct share_mode_lock *lck,
2397 const struct GUID *client_guid,
2398 const struct smb2_lease *lease,
2399 uint32_t granted)
2401 NTSTATUS status;
2403 fsp->lease = talloc_zero(fsp->conn->sconn, struct fsp_lease);
2404 if (fsp->lease == NULL) {
2405 return NT_STATUS_INSUFFICIENT_RESOURCES;
2407 fsp->lease->ref_count = 1;
2408 fsp->lease->sconn = fsp->conn->sconn;
2409 fsp->lease->lease.lease_version = lease->lease_version;
2410 fsp->lease->lease.lease_key = lease->lease_key;
2411 fsp->lease->lease.lease_state = granted;
2412 fsp->lease->lease.lease_epoch = lease->lease_epoch + 1;
2414 status = leases_db_add(client_guid,
2415 &lease->lease_key,
2416 &fsp->file_id,
2417 fsp->lease->lease.lease_state,
2418 fsp->lease->lease.lease_version,
2419 fsp->lease->lease.lease_epoch,
2420 fsp->conn->connectpath,
2421 fsp->fsp_name->base_name,
2422 fsp->fsp_name->stream_name);
2423 if (!NT_STATUS_IS_OK(status)) {
2424 DEBUG(10, ("%s: leases_db_add failed: %s\n", __func__,
2425 nt_errstr(status)));
2426 TALLOC_FREE(fsp->lease);
2427 return NT_STATUS_INSUFFICIENT_RESOURCES;
2431 * We used to set lck->data->modified=true here without
2432 * actually modifying lck->data, triggering a needless
2433 * writeback of lck->data.
2435 * Apart from that writeback, setting modified=true has the
2436 * effect of triggering all waiters for this file to
2437 * retry. This only makes sense if any blocking condition
2438 * (i.e. waiting for a lease to be downgraded or removed) is
2439 * gone. This routine here only adds a lease, so it will never
2440 * free up resources that blocked waiters can now claim. So
2441 * that second effect also does not matter in this
2442 * routine. Thus setting lck->data->modified=true does not
2443 * need to be done here.
2446 return NT_STATUS_OK;
2449 static NTSTATUS grant_fsp_lease(struct files_struct *fsp,
2450 struct share_mode_lock *lck,
2451 const struct smb2_lease *lease,
2452 uint32_t granted)
2454 const struct GUID *client_guid = fsp_client_guid(fsp);
2455 NTSTATUS status;
2457 status = try_lease_upgrade(fsp, lck, client_guid, lease, granted);
2459 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
2460 status = grant_new_fsp_lease(
2461 fsp, lck, client_guid, lease, granted);
2464 return status;
2467 static int map_lease_type_to_oplock(uint32_t lease_type)
2469 int result = NO_OPLOCK;
2471 switch (lease_type) {
2472 case SMB2_LEASE_READ|SMB2_LEASE_WRITE|SMB2_LEASE_HANDLE:
2473 result = BATCH_OPLOCK|EXCLUSIVE_OPLOCK;
2474 break;
2475 case SMB2_LEASE_READ|SMB2_LEASE_WRITE:
2476 result = EXCLUSIVE_OPLOCK;
2477 break;
2478 case SMB2_LEASE_READ|SMB2_LEASE_HANDLE:
2479 case SMB2_LEASE_READ:
2480 result = LEVEL_II_OPLOCK;
2481 break;
2484 return result;
2487 struct delay_for_oplock_state {
2488 struct files_struct *fsp;
2489 const struct smb2_lease *lease;
2490 bool will_overwrite;
2491 uint32_t delay_mask;
2492 bool first_open_attempt;
2493 bool got_handle_lease;
2494 bool got_oplock;
2495 bool have_other_lease;
2496 uint32_t total_lease_types;
2497 bool delay;
2500 static bool delay_for_oplock_fn(
2501 struct share_mode_entry *e,
2502 bool *modified,
2503 void *private_data)
2505 struct delay_for_oplock_state *state = private_data;
2506 struct files_struct *fsp = state->fsp;
2507 const struct smb2_lease *lease = state->lease;
2508 bool e_is_lease = (e->op_type == LEASE_OPLOCK);
2509 uint32_t e_lease_type = SMB2_LEASE_NONE;
2510 uint32_t break_to;
2511 bool lease_is_breaking = false;
2513 if (e_is_lease) {
2514 NTSTATUS status;
2516 if (lease != NULL) {
2517 bool our_lease = is_same_lease(fsp, e, lease);
2518 if (our_lease) {
2519 DBG_DEBUG("Ignoring our own lease\n");
2520 return false;
2524 status = leases_db_get(
2525 &e->client_guid,
2526 &e->lease_key,
2527 &fsp->file_id,
2528 &e_lease_type, /* current_state */
2529 &lease_is_breaking,
2530 NULL, /* breaking_to_requested */
2531 NULL, /* breaking_to_required */
2532 NULL, /* lease_version */
2533 NULL); /* epoch */
2536 * leases_db_get() can return NT_STATUS_NOT_FOUND
2537 * if the share_mode_entry e is stale and the
2538 * lease record was already removed. In this case return
2539 * false so the traverse continues.
2542 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND) &&
2543 share_entry_stale_pid(e))
2545 struct GUID_txt_buf guid_strbuf;
2546 struct file_id_buf file_id_strbuf;
2547 DBG_DEBUG("leases_db_get for client_guid [%s] "
2548 "lease_key [%"PRIu64"/%"PRIu64"] "
2549 "file_id [%s] failed for stale "
2550 "share_mode_entry\n",
2551 GUID_buf_string(&e->client_guid, &guid_strbuf),
2552 e->lease_key.data[0],
2553 e->lease_key.data[1],
2554 file_id_str_buf(fsp->file_id, &file_id_strbuf));
2555 return false;
2557 if (!NT_STATUS_IS_OK(status)) {
2558 struct GUID_txt_buf guid_strbuf;
2559 struct file_id_buf file_id_strbuf;
2560 DBG_ERR("leases_db_get for client_guid [%s] "
2561 "lease_key [%"PRIu64"/%"PRIu64"] "
2562 "file_id [%s] failed: %s\n",
2563 GUID_buf_string(&e->client_guid, &guid_strbuf),
2564 e->lease_key.data[0],
2565 e->lease_key.data[1],
2566 file_id_str_buf(fsp->file_id, &file_id_strbuf),
2567 nt_errstr(status));
2568 smb_panic("leases_db_get() failed");
2570 } else {
2571 e_lease_type = get_lease_type(e, fsp->file_id);
2574 if (((e_lease_type & ~state->total_lease_types) != 0) &&
2575 !share_entry_stale_pid(e))
2577 state->total_lease_types |= e_lease_type;
2580 if (!state->got_handle_lease &&
2581 ((e_lease_type & SMB2_LEASE_HANDLE) != 0) &&
2582 !share_entry_stale_pid(e)) {
2583 state->got_handle_lease = true;
2586 if (!state->got_oplock &&
2587 (e->op_type != LEASE_OPLOCK) &&
2588 !share_entry_stale_pid(e)) {
2589 state->got_oplock = true;
2592 if (!state->have_other_lease &&
2593 !is_same_lease(fsp, e, lease) &&
2594 !share_entry_stale_pid(e)) {
2595 state->have_other_lease = true;
2598 if (e_is_lease && is_lease_stat_open(fsp->access_mask)) {
2599 return false;
2602 break_to = e_lease_type & ~state->delay_mask;
2604 if (state->will_overwrite) {
2605 break_to &= ~(SMB2_LEASE_HANDLE|SMB2_LEASE_READ);
2608 DBG_DEBUG("e_lease_type %u, will_overwrite: %u\n",
2609 (unsigned)e_lease_type,
2610 (unsigned)state->will_overwrite);
2612 if ((e_lease_type & ~break_to) == 0) {
2613 if (lease_is_breaking) {
2614 state->delay = true;
2616 return false;
2619 if (share_entry_stale_pid(e)) {
2620 return false;
2623 if (state->will_overwrite) {
2625 * If we break anyway break to NONE directly.
2626 * Otherwise vfs_set_filelen() will trigger the
2627 * break.
2629 break_to &= ~(SMB2_LEASE_READ|SMB2_LEASE_WRITE);
2632 if (!e_is_lease) {
2634 * Oplocks only support breaking to R or NONE.
2636 break_to &= ~(SMB2_LEASE_HANDLE|SMB2_LEASE_WRITE);
2639 DBG_DEBUG("breaking from %d to %d\n",
2640 (int)e_lease_type,
2641 (int)break_to);
2642 send_break_message(
2643 fsp->conn->sconn->msg_ctx, &fsp->file_id, e, break_to);
2644 if (e_lease_type & state->delay_mask) {
2645 state->delay = true;
2647 if (lease_is_breaking && !state->first_open_attempt) {
2648 state->delay = true;
2651 return false;
2654 static NTSTATUS delay_for_oplock(files_struct *fsp,
2655 int oplock_request,
2656 const struct smb2_lease *lease,
2657 struct share_mode_lock *lck,
2658 bool have_sharing_violation,
2659 uint32_t create_disposition,
2660 bool first_open_attempt,
2661 int *poplock_type,
2662 uint32_t *pgranted)
2664 struct delay_for_oplock_state state = {
2665 .fsp = fsp,
2666 .lease = lease,
2667 .first_open_attempt = first_open_attempt,
2669 uint32_t requested;
2670 uint32_t granted;
2671 int oplock_type;
2672 bool ok;
2674 *poplock_type = NO_OPLOCK;
2675 *pgranted = 0;
2677 if (fsp->fsp_flags.is_directory) {
2679 * No directory leases yet
2681 SMB_ASSERT(oplock_request == NO_OPLOCK);
2682 if (have_sharing_violation) {
2683 return NT_STATUS_SHARING_VIOLATION;
2685 return NT_STATUS_OK;
2688 if (oplock_request == LEASE_OPLOCK) {
2689 if (lease == NULL) {
2691 * The SMB2 layer should have checked this
2693 return NT_STATUS_INTERNAL_ERROR;
2696 requested = lease->lease_state;
2697 } else {
2698 requested = map_oplock_to_lease_type(
2699 oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK);
2702 share_mode_flags_get(lck, NULL, NULL, &state.total_lease_types);
2704 if (is_oplock_stat_open(fsp->access_mask)) {
2705 goto grant;
2708 state.delay_mask = have_sharing_violation ?
2709 SMB2_LEASE_HANDLE : SMB2_LEASE_WRITE;
2711 switch (create_disposition) {
2712 case FILE_SUPERSEDE:
2713 case FILE_OVERWRITE:
2714 case FILE_OVERWRITE_IF:
2715 state.will_overwrite = true;
2716 break;
2717 default:
2718 state.will_overwrite = false;
2719 break;
2722 state.total_lease_types = SMB2_LEASE_NONE;
2723 ok = share_mode_forall_entries(lck, delay_for_oplock_fn, &state);
2724 if (!ok) {
2725 return NT_STATUS_INTERNAL_ERROR;
2728 if (state.delay) {
2729 return NT_STATUS_RETRY;
2732 grant:
2733 if (have_sharing_violation) {
2734 return NT_STATUS_SHARING_VIOLATION;
2737 granted = requested;
2739 if (oplock_request == LEASE_OPLOCK) {
2740 if (lp_kernel_oplocks(SNUM(fsp->conn))) {
2741 DEBUG(10, ("No lease granted because kernel oplocks are enabled\n"));
2742 granted = SMB2_LEASE_NONE;
2744 if ((granted & (SMB2_LEASE_READ|SMB2_LEASE_WRITE)) == 0) {
2745 DEBUG(10, ("No read or write lease requested\n"));
2746 granted = SMB2_LEASE_NONE;
2748 if (granted == SMB2_LEASE_WRITE) {
2749 DEBUG(10, ("pure write lease requested\n"));
2750 granted = SMB2_LEASE_NONE;
2752 if (granted == (SMB2_LEASE_WRITE|SMB2_LEASE_HANDLE)) {
2753 DEBUG(10, ("write and handle lease requested\n"));
2754 granted = SMB2_LEASE_NONE;
2758 if (lp_locking(fsp->conn->params) && file_has_brlocks(fsp)) {
2759 DBG_DEBUG("file %s has byte range locks\n",
2760 fsp_str_dbg(fsp));
2761 granted &= ~SMB2_LEASE_READ;
2764 if (state.have_other_lease) {
2766 * Can grant only one writer
2768 granted &= ~SMB2_LEASE_WRITE;
2771 if ((granted & SMB2_LEASE_READ) && !(granted & SMB2_LEASE_WRITE)) {
2772 bool allow_level2 =
2773 (global_client_caps & CAP_LEVEL_II_OPLOCKS) &&
2774 lp_level2_oplocks(SNUM(fsp->conn));
2776 if (!allow_level2) {
2777 granted = SMB2_LEASE_NONE;
2781 if (oplock_request == LEASE_OPLOCK) {
2782 if (state.got_oplock) {
2783 granted &= ~SMB2_LEASE_HANDLE;
2786 oplock_type = LEASE_OPLOCK;
2787 } else {
2788 if (state.got_handle_lease) {
2789 granted = SMB2_LEASE_NONE;
2793 * Reflect possible downgrades from:
2794 * - map_lease_type_to_oplock() => "RH" to just LEVEL_II
2796 oplock_type = map_lease_type_to_oplock(granted);
2797 granted = map_oplock_to_lease_type(oplock_type);
2800 state.total_lease_types |= granted;
2803 uint32_t acc, sh, ls;
2804 share_mode_flags_get(lck, &acc, &sh, &ls);
2805 ls = state.total_lease_types;
2806 share_mode_flags_set(lck, acc, sh, ls, NULL);
2809 DBG_DEBUG("oplock type 0x%x granted (%s%s%s)(0x%x), on file %s, "
2810 "requested 0x%x (%s%s%s)(0x%x) => total (%s%s%s)(0x%x)\n",
2811 fsp->oplock_type,
2812 granted & SMB2_LEASE_READ ? "R":"",
2813 granted & SMB2_LEASE_WRITE ? "W":"",
2814 granted & SMB2_LEASE_HANDLE ? "H":"",
2815 granted,
2816 fsp_str_dbg(fsp),
2817 oplock_request,
2818 requested & SMB2_LEASE_READ ? "R":"",
2819 requested & SMB2_LEASE_WRITE ? "W":"",
2820 requested & SMB2_LEASE_HANDLE ? "H":"",
2821 requested,
2822 state.total_lease_types & SMB2_LEASE_READ ? "R":"",
2823 state.total_lease_types & SMB2_LEASE_WRITE ? "W":"",
2824 state.total_lease_types & SMB2_LEASE_HANDLE ? "H":"",
2825 state.total_lease_types);
2827 *poplock_type = oplock_type;
2828 *pgranted = granted;
2829 return NT_STATUS_OK;
2832 static NTSTATUS handle_share_mode_lease(
2833 files_struct *fsp,
2834 struct share_mode_lock *lck,
2835 uint32_t create_disposition,
2836 uint32_t access_mask,
2837 uint32_t share_access,
2838 int oplock_request,
2839 const struct smb2_lease *lease,
2840 bool first_open_attempt,
2841 int *poplock_type,
2842 uint32_t *pgranted)
2844 bool sharing_violation = false;
2845 NTSTATUS status;
2847 *poplock_type = NO_OPLOCK;
2848 *pgranted = 0;
2850 status = open_mode_check(
2851 fsp->conn, fsp->file_id, lck, access_mask, share_access);
2852 if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
2853 sharing_violation = true;
2854 status = NT_STATUS_OK; /* handled later */
2857 if (!NT_STATUS_IS_OK(status)) {
2858 return status;
2861 if (oplock_request == INTERNAL_OPEN_ONLY) {
2862 if (sharing_violation) {
2863 DBG_DEBUG("Sharing violation for internal open\n");
2864 return NT_STATUS_SHARING_VIOLATION;
2868 * Internal opens never do oplocks or leases. We don't
2869 * need to go through delay_for_oplock().
2871 return NT_STATUS_OK;
2874 status = delay_for_oplock(
2875 fsp,
2876 oplock_request,
2877 lease,
2878 lck,
2879 sharing_violation,
2880 create_disposition,
2881 first_open_attempt,
2882 poplock_type,
2883 pgranted);
2884 if (!NT_STATUS_IS_OK(status)) {
2885 return status;
2888 return NT_STATUS_OK;
2891 static bool request_timed_out(struct smb_request *req, struct timeval timeout)
2893 struct timeval now, end_time;
2894 GetTimeOfDay(&now);
2895 end_time = timeval_sum(&req->request_time, &timeout);
2896 return (timeval_compare(&end_time, &now) < 0);
2899 struct defer_open_state {
2900 struct smbXsrv_connection *xconn;
2901 uint64_t mid;
2904 static void defer_open_done(struct tevent_req *req);
2907 * Defer an open and watch a locking.tdb record
2909 * This defers an open that gets rescheduled once the locking.tdb record watch
2910 * is triggered by a change to the record.
2912 * It is used to defer opens that triggered an oplock break and for the SMB1
2913 * sharing violation delay.
2915 static void defer_open(struct share_mode_lock *lck,
2916 struct timeval timeout,
2917 struct smb_request *req,
2918 struct file_id id)
2920 struct deferred_open_record *open_rec = NULL;
2921 struct timeval abs_timeout;
2922 struct defer_open_state *watch_state;
2923 struct tevent_req *watch_req;
2924 struct timeval_buf tvbuf1, tvbuf2;
2925 struct file_id_buf fbuf;
2926 bool ok;
2928 abs_timeout = timeval_sum(&req->request_time, &timeout);
2930 DBG_DEBUG("request time [%s] timeout [%s] mid [%" PRIu64 "] "
2931 "file_id [%s]\n",
2932 timeval_str_buf(&req->request_time, false, true, &tvbuf1),
2933 timeval_str_buf(&abs_timeout, false, true, &tvbuf2),
2934 req->mid,
2935 file_id_str_buf(id, &fbuf));
2937 open_rec = talloc_zero(NULL, struct deferred_open_record);
2938 if (open_rec == NULL) {
2939 TALLOC_FREE(lck);
2940 exit_server("talloc failed");
2943 watch_state = talloc(open_rec, struct defer_open_state);
2944 if (watch_state == NULL) {
2945 exit_server("talloc failed");
2947 watch_state->xconn = req->xconn;
2948 watch_state->mid = req->mid;
2950 DBG_DEBUG("deferring mid %" PRIu64 "\n", req->mid);
2952 watch_req = share_mode_watch_send(
2953 watch_state,
2954 req->sconn->ev_ctx,
2955 lck,
2956 (struct server_id){0});
2957 if (watch_req == NULL) {
2958 exit_server("Could not watch share mode record");
2960 tevent_req_set_callback(watch_req, defer_open_done, watch_state);
2962 ok = tevent_req_set_endtime(watch_req, req->sconn->ev_ctx, abs_timeout);
2963 if (!ok) {
2964 exit_server("tevent_req_set_endtime failed");
2967 ok = push_deferred_open_message_smb(req, timeout, id, open_rec);
2968 if (!ok) {
2969 TALLOC_FREE(lck);
2970 exit_server("push_deferred_open_message_smb failed");
2974 static void defer_open_done(struct tevent_req *req)
2976 struct defer_open_state *state = tevent_req_callback_data(
2977 req, struct defer_open_state);
2978 NTSTATUS status;
2979 bool ret;
2981 status = share_mode_watch_recv(req, NULL, NULL);
2982 TALLOC_FREE(req);
2983 if (!NT_STATUS_IS_OK(status)) {
2984 DEBUG(5, ("dbwrap_watched_watch_recv returned %s\n",
2985 nt_errstr(status)));
2987 * Even if it failed, retry anyway. TODO: We need a way to
2988 * tell a re-scheduled open about that error.
2992 DEBUG(10, ("scheduling mid %llu\n", (unsigned long long)state->mid));
2994 ret = schedule_deferred_open_message_smb(state->xconn, state->mid);
2995 SMB_ASSERT(ret);
2996 TALLOC_FREE(state);
3000 * Actually attempt the kernel oplock polling open.
3003 static void poll_open_fn(struct tevent_context *ev,
3004 struct tevent_timer *te,
3005 struct timeval current_time,
3006 void *private_data)
3008 struct deferred_open_record *open_rec = talloc_get_type_abort(
3009 private_data, struct deferred_open_record);
3010 bool ok;
3012 TALLOC_FREE(open_rec->watch_req);
3014 ok = schedule_deferred_open_message_smb(
3015 open_rec->xconn, open_rec->mid);
3016 if (!ok) {
3017 exit_server("schedule_deferred_open_message_smb failed");
3019 DBG_DEBUG("timer fired. Retrying open !\n");
3022 static void poll_open_done(struct tevent_req *subreq);
3024 struct poll_open_setup_watcher_state {
3025 TALLOC_CTX *mem_ctx;
3026 struct tevent_context *ev_ctx;
3027 struct tevent_req *watch_req;
3030 static void poll_open_setup_watcher_fn(struct share_mode_lock *lck,
3031 void *private_data)
3033 struct poll_open_setup_watcher_state *state =
3034 (struct poll_open_setup_watcher_state *)private_data;
3036 if (!validate_oplock_types(lck)) {
3037 smb_panic("validate_oplock_types failed");
3040 state->watch_req = share_mode_watch_send(
3041 state->mem_ctx,
3042 state->ev_ctx,
3043 lck,
3044 (struct server_id) {0});
3045 if (state->watch_req == NULL) {
3046 DBG_WARNING("share_mode_watch_send failed\n");
3047 return;
3052 * Reschedule an open for 1 second from now, if not timed out.
3054 static bool setup_poll_open(
3055 struct smb_request *req,
3056 const struct file_id *id,
3057 struct timeval max_timeout,
3058 struct timeval interval)
3060 static struct file_id zero_id = {};
3061 bool ok;
3062 struct deferred_open_record *open_rec = NULL;
3063 struct timeval endtime, next_interval;
3064 struct file_id_buf ftmp;
3066 if (request_timed_out(req, max_timeout)) {
3067 return false;
3070 open_rec = talloc_zero(NULL, struct deferred_open_record);
3071 if (open_rec == NULL) {
3072 DBG_WARNING("talloc failed\n");
3073 return false;
3075 open_rec->xconn = req->xconn;
3076 open_rec->mid = req->mid;
3079 * Make sure open_rec->te does not come later than the
3080 * request's maximum endtime.
3083 endtime = timeval_sum(&req->request_time, &max_timeout);
3084 next_interval = timeval_current_ofs(interval.tv_sec, interval.tv_usec);
3085 next_interval = timeval_min(&endtime, &next_interval);
3087 open_rec->te = tevent_add_timer(
3088 req->sconn->ev_ctx,
3089 open_rec,
3090 next_interval,
3091 poll_open_fn,
3092 open_rec);
3093 if (open_rec->te == NULL) {
3094 DBG_WARNING("tevent_add_timer failed\n");
3095 TALLOC_FREE(open_rec);
3096 return false;
3099 if (id != NULL) {
3100 struct poll_open_setup_watcher_state wstate = {
3101 .mem_ctx = open_rec,
3102 .ev_ctx = req->sconn->ev_ctx,
3104 NTSTATUS status;
3106 status = share_mode_do_locked_vfs_denied(*id,
3107 poll_open_setup_watcher_fn,
3108 &wstate);
3109 if (NT_STATUS_IS_OK(status)) {
3110 if (wstate.watch_req == NULL) {
3111 DBG_WARNING("share_mode_watch_send failed\n");
3112 TALLOC_FREE(open_rec);
3113 return false;
3115 open_rec->watch_req = wstate.watch_req;
3116 tevent_req_set_callback(open_rec->watch_req,
3117 poll_open_done,
3118 open_rec);
3119 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
3120 DBG_WARNING("share_mode_do_locked_vfs_denied failed - %s\n",
3121 nt_errstr(status));
3122 TALLOC_FREE(open_rec);
3123 return false;
3125 } else {
3126 id = &zero_id;
3129 ok = push_deferred_open_message_smb(req, max_timeout, *id, open_rec);
3130 if (!ok) {
3131 DBG_WARNING("push_deferred_open_message_smb failed\n");
3132 TALLOC_FREE(open_rec);
3133 return false;
3136 DBG_DEBUG("poll request time [%s] mid [%" PRIu64 "] file_id [%s]\n",
3137 timeval_string(talloc_tos(), &req->request_time, false),
3138 req->mid,
3139 file_id_str_buf(*id, &ftmp));
3141 return true;
3144 static void poll_open_done(struct tevent_req *subreq)
3146 struct deferred_open_record *open_rec = tevent_req_callback_data(
3147 subreq, struct deferred_open_record);
3148 NTSTATUS status;
3149 bool ok;
3151 status = share_mode_watch_recv(subreq, NULL, NULL);
3152 TALLOC_FREE(subreq);
3153 open_rec->watch_req = NULL;
3154 TALLOC_FREE(open_rec->te);
3156 DBG_DEBUG("dbwrap_watched_watch_recv returned %s\n",
3157 nt_errstr(status));
3159 ok = schedule_deferred_open_message_smb(
3160 open_rec->xconn, open_rec->mid);
3161 if (!ok) {
3162 exit_server("schedule_deferred_open_message_smb failed");
3166 bool defer_smb1_sharing_violation(struct smb_request *req)
3168 bool ok;
3169 int timeout_usecs;
3171 if (!lp_defer_sharing_violations()) {
3172 return false;
3176 * Try every 200msec up to (by default) one second. To be
3177 * precise, according to behaviour note <247> in [MS-CIFS],
3178 * the server tries 5 times. But up to one second should be
3179 * close enough.
3182 timeout_usecs = lp_parm_int(
3183 SNUM(req->conn),
3184 "smbd",
3185 "sharedelay",
3186 SHARING_VIOLATION_USEC_WAIT);
3188 ok = setup_poll_open(
3189 req,
3190 NULL,
3191 (struct timeval) { .tv_usec = timeout_usecs },
3192 (struct timeval) { .tv_usec = 200000 });
3193 return ok;
3196 /****************************************************************************
3197 On overwrite open ensure that the attributes match.
3198 ****************************************************************************/
3200 static bool open_match_attributes(connection_struct *conn,
3201 uint32_t old_dos_attr,
3202 uint32_t new_dos_attr,
3203 mode_t new_unx_mode,
3204 mode_t *returned_unx_mode)
3206 uint32_t noarch_old_dos_attr, noarch_new_dos_attr;
3208 noarch_old_dos_attr = (old_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
3209 noarch_new_dos_attr = (new_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
3211 if((noarch_old_dos_attr == 0 && noarch_new_dos_attr != 0) ||
3212 (noarch_old_dos_attr != 0 && ((noarch_old_dos_attr & noarch_new_dos_attr) == noarch_old_dos_attr))) {
3213 *returned_unx_mode = new_unx_mode;
3214 } else {
3215 *returned_unx_mode = (mode_t)0;
3218 DEBUG(10,("open_match_attributes: old_dos_attr = 0x%x, "
3219 "new_dos_attr = 0x%x "
3220 "returned_unx_mode = 0%o\n",
3221 (unsigned int)old_dos_attr,
3222 (unsigned int)new_dos_attr,
3223 (unsigned int)*returned_unx_mode ));
3225 /* If we're mapping SYSTEM and HIDDEN ensure they match. */
3226 if (lp_map_system(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
3227 if ((old_dos_attr & FILE_ATTRIBUTE_SYSTEM) &&
3228 !(new_dos_attr & FILE_ATTRIBUTE_SYSTEM)) {
3229 return False;
3232 if (lp_map_hidden(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
3233 if ((old_dos_attr & FILE_ATTRIBUTE_HIDDEN) &&
3234 !(new_dos_attr & FILE_ATTRIBUTE_HIDDEN)) {
3235 return False;
3238 return True;
3241 static void schedule_defer_open(struct share_mode_lock *lck,
3242 struct file_id id,
3243 struct smb_request *req)
3245 /* This is a relative time, added to the absolute
3246 request_time value to get the absolute timeout time.
3247 Note that if this is the second or greater time we enter
3248 this codepath for this particular request mid then
3249 request_time is left as the absolute time of the *first*
3250 time this request mid was processed. This is what allows
3251 the request to eventually time out. */
3253 struct timeval timeout;
3255 /* Normally the smbd we asked should respond within
3256 * OPLOCK_BREAK_TIMEOUT seconds regardless of whether
3257 * the client did, give twice the timeout as a safety
3258 * measure here in case the other smbd is stuck
3259 * somewhere else. */
3261 timeout = timeval_set(OPLOCK_BREAK_TIMEOUT*2, 0);
3263 if (request_timed_out(req, timeout)) {
3264 return;
3267 defer_open(lck, timeout, req, id);
3270 /****************************************************************************
3271 Reschedule an open call that went asynchronous.
3272 ****************************************************************************/
3274 static void schedule_async_open_timer(struct tevent_context *ev,
3275 struct tevent_timer *te,
3276 struct timeval current_time,
3277 void *private_data)
3279 exit_server("async open timeout");
3282 static void schedule_async_open(struct smb_request *req)
3284 struct deferred_open_record *open_rec = NULL;
3285 struct timeval timeout = timeval_set(20, 0);
3286 bool ok;
3288 if (request_timed_out(req, timeout)) {
3289 return;
3292 open_rec = talloc_zero(NULL, struct deferred_open_record);
3293 if (open_rec == NULL) {
3294 exit_server("deferred_open_record_create failed");
3296 open_rec->async_open = true;
3298 ok = push_deferred_open_message_smb(
3299 req, timeout, (struct file_id){0}, open_rec);
3300 if (!ok) {
3301 exit_server("push_deferred_open_message_smb failed");
3304 open_rec->te = tevent_add_timer(req->sconn->ev_ctx,
3305 req,
3306 timeval_current_ofs(20, 0),
3307 schedule_async_open_timer,
3308 open_rec);
3309 if (open_rec->te == NULL) {
3310 exit_server("tevent_add_timer failed");
3314 static NTSTATUS check_and_store_share_mode(
3315 struct files_struct *fsp,
3316 struct smb_request *req,
3317 struct share_mode_lock *lck,
3318 uint32_t create_disposition,
3319 uint32_t access_mask,
3320 uint32_t share_access,
3321 int oplock_request,
3322 const struct smb2_lease *lease,
3323 bool first_open_attempt)
3325 NTSTATUS status;
3326 int oplock_type = NO_OPLOCK;
3327 uint32_t granted_lease = 0;
3328 const struct smb2_lease_key *lease_key = NULL;
3329 bool delete_on_close;
3330 bool ok;
3332 /* Get the types we need to examine. */
3333 if (!validate_oplock_types(lck)) {
3334 smb_panic("validate_oplock_types failed");
3337 delete_on_close = has_delete_on_close(lck, fsp->name_hash);
3338 if (delete_on_close) {
3339 return NT_STATUS_DELETE_PENDING;
3342 status = handle_share_mode_lease(fsp,
3343 lck,
3344 create_disposition,
3345 access_mask,
3346 share_access,
3347 oplock_request,
3348 lease,
3349 first_open_attempt,
3350 &oplock_type,
3351 &granted_lease);
3352 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
3353 schedule_defer_open(lck, fsp->file_id, req);
3354 return NT_STATUS_SHARING_VIOLATION;
3356 if (!NT_STATUS_IS_OK(status)) {
3357 return status;
3360 if (oplock_type == LEASE_OPLOCK) {
3361 lease_key = &lease->lease_key;
3364 share_mode_flags_restrict(lck, access_mask, share_access, 0);
3366 ok = set_share_mode(lck,
3367 fsp,
3368 get_current_uid(fsp->conn),
3369 req ? req->mid : 0,
3370 oplock_type,
3371 lease_key,
3372 share_access,
3373 access_mask);
3374 if (!ok) {
3375 return NT_STATUS_NO_MEMORY;
3378 if (oplock_type == LEASE_OPLOCK) {
3379 status = grant_fsp_lease(fsp, lck, lease, granted_lease);
3380 if (!NT_STATUS_IS_OK(status)) {
3381 del_share_mode(lck, fsp);
3382 return status;
3385 DBG_DEBUG("lease_state=%d\n", fsp->lease->lease.lease_state);
3388 fsp->oplock_type = oplock_type;
3390 return NT_STATUS_OK;
3393 /****************************************************************************
3394 Work out what access_mask to use from what the client sent us.
3395 ****************************************************************************/
3397 static NTSTATUS smbd_calculate_maximum_allowed_access_fsp(
3398 struct files_struct *dirfsp,
3399 struct files_struct *fsp,
3400 bool use_privs,
3401 uint32_t *p_access_mask)
3403 struct security_descriptor *sd = NULL;
3404 uint32_t access_granted = 0;
3405 uint32_t dosattrs;
3406 NTSTATUS status;
3408 /* Cope with symlinks */
3409 if (fsp == NULL || fsp_get_pathref_fd(fsp) == -1) {
3410 *p_access_mask = FILE_GENERIC_ALL;
3411 return NT_STATUS_OK;
3414 /* Cope with fake/printer fsp's. */
3415 if (fsp->fake_file_handle != NULL || fsp->print_file != NULL) {
3416 *p_access_mask = FILE_GENERIC_ALL;
3417 return NT_STATUS_OK;
3420 if (!use_privs && (get_current_uid(fsp->conn) == (uid_t)0)) {
3421 *p_access_mask |= FILE_GENERIC_ALL;
3422 return NT_STATUS_OK;
3425 status = SMB_VFS_FGET_NT_ACL(metadata_fsp(fsp),
3426 (SECINFO_OWNER |
3427 SECINFO_GROUP |
3428 SECINFO_DACL),
3429 talloc_tos(),
3430 &sd);
3432 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
3434 * File did not exist
3436 *p_access_mask = FILE_GENERIC_ALL;
3437 return NT_STATUS_OK;
3439 if (!NT_STATUS_IS_OK(status)) {
3440 DBG_ERR("Could not get acl on file %s: %s\n",
3441 fsp_str_dbg(fsp),
3442 nt_errstr(status));
3443 return status;
3447 * If we can access the path to this file, by
3448 * default we have FILE_READ_ATTRIBUTES from the
3449 * containing directory. See the section:
3450 * "Algorithm to Check Access to an Existing File"
3451 * in MS-FSA.pdf.
3453 * se_file_access_check()
3454 * also takes care of owner WRITE_DAC and READ_CONTROL.
3456 status = se_file_access_check(sd,
3457 get_current_nttok(fsp->conn),
3458 use_privs,
3459 (*p_access_mask & ~FILE_READ_ATTRIBUTES),
3460 &access_granted);
3462 TALLOC_FREE(sd);
3464 if (!NT_STATUS_IS_OK(status)) {
3465 DBG_ERR("Status %s on file %s: "
3466 "when calculating maximum access\n",
3467 nt_errstr(status),
3468 fsp_str_dbg(fsp));
3469 return status;
3472 *p_access_mask = (access_granted | FILE_READ_ATTRIBUTES);
3474 if (!(access_granted & DELETE_ACCESS)) {
3475 if (can_delete_file_in_directory(fsp->conn,
3476 dirfsp,
3477 fsp->fsp_name)) {
3478 *p_access_mask |= DELETE_ACCESS;
3482 dosattrs = fdos_mode(fsp);
3483 if ((dosattrs & FILE_ATTRIBUTE_READONLY) || !CAN_WRITE(fsp->conn)) {
3484 *p_access_mask &= ~(FILE_GENERIC_WRITE | DELETE_ACCESS);
3487 return NT_STATUS_OK;
3490 NTSTATUS smbd_calculate_access_mask_fsp(struct files_struct *dirfsp,
3491 struct files_struct *fsp,
3492 bool use_privs,
3493 uint32_t access_mask,
3494 uint32_t *access_mask_out)
3496 NTSTATUS status;
3497 uint32_t orig_access_mask = access_mask;
3498 uint32_t rejected_share_access;
3500 if (access_mask & SEC_MASK_INVALID) {
3501 DBG_DEBUG("access_mask [%8x] contains invalid bits\n",
3502 access_mask);
3503 return NT_STATUS_ACCESS_DENIED;
3507 * Convert GENERIC bits to specific bits.
3510 se_map_generic(&access_mask, &file_generic_mapping);
3512 /* Calculate MAXIMUM_ALLOWED_ACCESS if requested. */
3513 if (access_mask & MAXIMUM_ALLOWED_ACCESS) {
3515 status = smbd_calculate_maximum_allowed_access_fsp(
3516 dirfsp,
3517 fsp,
3518 use_privs,
3519 &access_mask);
3521 if (!NT_STATUS_IS_OK(status)) {
3522 return status;
3525 access_mask &= fsp->conn->share_access;
3528 rejected_share_access = access_mask & ~(fsp->conn->share_access);
3530 if (rejected_share_access) {
3531 DBG_INFO("Access denied on file %s: "
3532 "rejected by share access mask[0x%08X] "
3533 "orig[0x%08X] mapped[0x%08X] reject[0x%08X]\n",
3534 fsp_str_dbg(fsp),
3535 fsp->conn->share_access,
3536 orig_access_mask, access_mask,
3537 rejected_share_access);
3538 return NT_STATUS_ACCESS_DENIED;
3541 *access_mask_out = access_mask;
3542 return NT_STATUS_OK;
3545 /****************************************************************************
3546 Remove the deferred open entry under lock.
3547 ****************************************************************************/
3549 /****************************************************************************
3550 Return true if this is a state pointer to an asynchronous create.
3551 ****************************************************************************/
3553 bool is_deferred_open_async(const struct deferred_open_record *rec)
3555 return rec->async_open;
3558 static bool clear_ads(uint32_t create_disposition)
3560 bool ret = false;
3562 switch (create_disposition) {
3563 case FILE_SUPERSEDE:
3564 case FILE_OVERWRITE_IF:
3565 case FILE_OVERWRITE:
3566 ret = true;
3567 break;
3568 default:
3569 break;
3571 return ret;
3574 static int disposition_to_open_flags(uint32_t create_disposition)
3576 int ret = 0;
3579 * Currently we're using FILE_SUPERSEDE as the same as
3580 * FILE_OVERWRITE_IF but they really are
3581 * different. FILE_SUPERSEDE deletes an existing file
3582 * (requiring delete access) then recreates it.
3585 switch (create_disposition) {
3586 case FILE_SUPERSEDE:
3587 case FILE_OVERWRITE_IF:
3589 * If file exists replace/overwrite. If file doesn't
3590 * exist create.
3592 ret = O_CREAT|O_TRUNC;
3593 break;
3595 case FILE_OPEN:
3597 * If file exists open. If file doesn't exist error.
3599 ret = 0;
3600 break;
3602 case FILE_OVERWRITE:
3604 * If file exists overwrite. If file doesn't exist
3605 * error.
3607 ret = O_TRUNC;
3608 break;
3610 case FILE_CREATE:
3612 * If file exists error. If file doesn't exist create.
3614 ret = O_CREAT|O_EXCL;
3615 break;
3617 case FILE_OPEN_IF:
3619 * If file exists open. If file doesn't exist create.
3621 ret = O_CREAT;
3622 break;
3624 return ret;
3627 static int calculate_open_access_flags(uint32_t access_mask,
3628 uint32_t private_flags)
3630 bool need_write, need_read;
3633 * Note that we ignore the append flag as append does not
3634 * mean the same thing under DOS and Unix.
3637 need_write = (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA));
3638 if (!need_write) {
3639 return O_RDONLY;
3642 /* DENY_DOS opens are always underlying read-write on the
3643 file handle, no matter what the requested access mask
3644 says. */
3646 need_read =
3647 ((private_flags & NTCREATEX_FLAG_DENY_DOS) ||
3648 access_mask & (FILE_READ_ATTRIBUTES|FILE_READ_DATA|
3649 FILE_READ_EA|FILE_EXECUTE));
3651 if (!need_read) {
3652 return O_WRONLY;
3654 return O_RDWR;
3657 struct open_ntcreate_lock_state {
3658 struct share_mode_entry_prepare_state prepare_state;
3659 struct files_struct *fsp;
3660 const char *object_type;
3661 struct smb_request *req;
3662 uint32_t create_disposition;
3663 uint32_t access_mask;
3664 uint32_t share_access;
3665 int oplock_request;
3666 const struct smb2_lease *lease;
3667 bool first_open_attempt;
3668 bool keep_locked;
3669 NTSTATUS status;
3670 struct timespec write_time;
3671 share_mode_entry_prepare_unlock_fn_t cleanup_fn;
3674 static void open_ntcreate_lock_add_entry(struct share_mode_lock *lck,
3675 bool *keep_locked,
3676 void *private_data)
3678 struct open_ntcreate_lock_state *state =
3679 (struct open_ntcreate_lock_state *)private_data;
3682 * By default drop the g_lock again if we leave the
3683 * tdb chainlock.
3685 *keep_locked = false;
3687 state->status = check_and_store_share_mode(state->fsp,
3688 state->req,
3689 lck,
3690 state->create_disposition,
3691 state->access_mask,
3692 state->share_access,
3693 state->oplock_request,
3694 state->lease,
3695 state->first_open_attempt);
3696 if (!NT_STATUS_IS_OK(state->status)) {
3697 return;
3700 state->write_time = get_share_mode_write_time(lck);
3703 * keep the g_lock while existing the tdb chainlock,
3704 * we we're asked to, which mean we'll keep
3705 * the share_mode_lock during object creation,
3706 * or setting delete on close.
3708 *keep_locked = state->keep_locked;
3711 static void open_ntcreate_lock_cleanup_oplock(struct share_mode_lock *lck,
3712 void *private_data)
3714 struct open_ntcreate_lock_state *state =
3715 (struct open_ntcreate_lock_state *)private_data;
3716 bool ok;
3718 ok = remove_share_oplock(lck, state->fsp);
3719 if (!ok) {
3720 DBG_ERR("Could not remove oplock for %s %s\n",
3721 state->object_type, fsp_str_dbg(state->fsp));
3725 static void open_ntcreate_lock_cleanup_entry(struct share_mode_lock *lck,
3726 void *private_data)
3728 struct open_ntcreate_lock_state *state =
3729 (struct open_ntcreate_lock_state *)private_data;
3730 bool ok;
3732 ok = del_share_mode(lck, state->fsp);
3733 if (!ok) {
3734 DBG_ERR("Could not delete share entry for %s %s\n",
3735 state->object_type, fsp_str_dbg(state->fsp));
3739 static void possibly_set_archive(struct connection_struct *conn,
3740 struct files_struct *fsp,
3741 struct smb_filename *smb_fname,
3742 struct smb_filename *parent_dir_fname,
3743 int info,
3744 uint32_t dosattrs,
3745 mode_t *unx_mode)
3747 bool set_archive = false;
3748 int ret;
3750 if (info == FILE_WAS_OPENED) {
3751 return;
3754 /* Overwritten files should be initially set as archive */
3755 if ((info == FILE_WAS_OVERWRITTEN && lp_map_archive(SNUM(conn)))) {
3756 set_archive = true;
3757 } else if (lp_store_dos_attributes(SNUM(conn))) {
3758 set_archive = true;
3760 if (!set_archive) {
3761 return;
3764 ret = file_set_dosmode(conn,
3765 smb_fname,
3766 dosattrs | FILE_ATTRIBUTE_ARCHIVE,
3767 parent_dir_fname,
3768 true);
3769 if (ret != 0) {
3770 return;
3772 *unx_mode = smb_fname->st.st_ex_mode;
3775 /****************************************************************************
3776 Open a file with a share mode. Passed in an already created files_struct *.
3777 ****************************************************************************/
3779 static NTSTATUS open_file_ntcreate(connection_struct *conn,
3780 struct smb_request *req,
3781 uint32_t access_mask, /* access bits (FILE_READ_DATA etc.) */
3782 uint32_t share_access, /* share constants (FILE_SHARE_READ etc) */
3783 uint32_t create_disposition, /* FILE_OPEN_IF etc. */
3784 uint32_t create_options, /* options such as delete on close. */
3785 uint32_t new_dos_attributes, /* attributes used for new file. */
3786 int oplock_request, /* internal Samba oplock codes. */
3787 const struct smb2_lease *lease,
3788 /* Information (FILE_EXISTS etc.) */
3789 uint32_t private_flags, /* Samba specific flags. */
3790 struct smb_filename *parent_dir_fname, /* parent. */
3791 struct smb_filename *smb_fname_atname, /* atname relative to parent. */
3792 int *pinfo,
3793 files_struct *fsp)
3795 struct smb_filename *smb_fname = fsp->fsp_name;
3796 int flags=0;
3797 bool file_existed = VALID_STAT(smb_fname->st);
3798 bool def_acl = False;
3799 bool posix_open = False;
3800 bool new_file_created = False;
3801 bool first_open_attempt = true;
3802 NTSTATUS fsp_open = NT_STATUS_ACCESS_DENIED;
3803 mode_t new_unx_mode = (mode_t)0;
3804 mode_t unx_mode = (mode_t)0;
3805 int info;
3806 uint32_t existing_dos_attributes = 0;
3807 struct open_ntcreate_lock_state lck_state = {};
3808 bool keep_locked = false;
3809 uint32_t open_access_mask = access_mask;
3810 NTSTATUS status;
3811 SMB_STRUCT_STAT saved_stat = smb_fname->st;
3812 struct timespec old_write_time;
3813 bool setup_poll = false;
3814 NTSTATUS ulstatus;
3816 if (conn->printer) {
3818 * Printers are handled completely differently.
3819 * Most of the passed parameters are ignored.
3822 if (pinfo) {
3823 *pinfo = FILE_WAS_CREATED;
3826 DBG_DEBUG("printer open fname=%s\n",
3827 smb_fname_str_dbg(smb_fname));
3829 if (!req) {
3830 DBG_ERR("printer open without an SMB request!\n");
3831 return NT_STATUS_INTERNAL_ERROR;
3834 return print_spool_open(fsp, smb_fname->base_name,
3835 req->vuid);
3838 if (new_dos_attributes & FILE_FLAG_POSIX_SEMANTICS) {
3839 posix_open = True;
3840 unx_mode = (mode_t)(new_dos_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
3841 new_dos_attributes = 0;
3842 } else {
3843 /* Windows allows a new file to be created and
3844 silently removes a FILE_ATTRIBUTE_DIRECTORY
3845 sent by the client. Do the same. */
3847 new_dos_attributes &= ~FILE_ATTRIBUTE_DIRECTORY;
3849 /* We add FILE_ATTRIBUTE_ARCHIVE to this as this mode is only used if the file is
3850 * created new. */
3851 unx_mode = unix_mode(
3852 conn,
3853 new_dos_attributes | FILE_ATTRIBUTE_ARCHIVE,
3854 smb_fname,
3855 parent_dir_fname->fsp);
3858 DEBUG(10, ("open_file_ntcreate: fname=%s, dos_attrs=0x%x "
3859 "access_mask=0x%x share_access=0x%x "
3860 "create_disposition = 0x%x create_options=0x%x "
3861 "unix mode=0%o oplock_request=%d private_flags = 0x%x\n",
3862 smb_fname_str_dbg(smb_fname), new_dos_attributes,
3863 access_mask, share_access, create_disposition,
3864 create_options, (unsigned int)unx_mode, oplock_request,
3865 (unsigned int)private_flags));
3867 if (req == NULL) {
3868 /* Ensure req == NULL means INTERNAL_OPEN_ONLY */
3869 SMB_ASSERT(oplock_request == INTERNAL_OPEN_ONLY);
3870 } else {
3871 /* And req != NULL means no INTERNAL_OPEN_ONLY */
3872 SMB_ASSERT(((oplock_request & INTERNAL_OPEN_ONLY) == 0));
3876 * Only non-internal opens can be deferred at all
3879 if (req) {
3880 struct deferred_open_record *open_rec;
3881 if (get_deferred_open_message_state(req, NULL, &open_rec)) {
3883 /* If it was an async create retry, the file
3884 didn't exist. */
3886 if (is_deferred_open_async(open_rec)) {
3887 SET_STAT_INVALID(smb_fname->st);
3888 file_existed = false;
3891 /* Ensure we don't reprocess this message. */
3892 remove_deferred_open_message_smb(req->xconn, req->mid);
3894 first_open_attempt = false;
3898 if (!posix_open) {
3899 new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
3900 if (file_existed) {
3902 * Only use stored DOS attributes for checks
3903 * against requested attributes (below via
3904 * open_match_attributes()), cf bug #11992
3905 * for details. -slow
3907 uint32_t attr = 0;
3909 status = SMB_VFS_FGET_DOS_ATTRIBUTES(
3910 conn,
3911 metadata_fsp(smb_fname->fsp),
3912 &attr);
3913 if (NT_STATUS_IS_OK(status)) {
3914 existing_dos_attributes = attr;
3919 /* ignore any oplock requests if oplocks are disabled */
3920 if (!lp_oplocks(SNUM(conn)) ||
3921 IS_VETO_OPLOCK_PATH(conn, smb_fname->base_name)) {
3922 /* Mask off everything except the private Samba bits. */
3923 oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
3926 /* this is for OS/2 long file names - say we don't support them */
3927 if (req != NULL && !req->posix_pathnames &&
3928 strstr(smb_fname->base_name,".+,;=[].")) {
3929 /* OS/2 Workplace shell fix may be main code stream in a later
3930 * release. */
3931 DEBUG(5,("open_file_ntcreate: OS/2 long filenames are not "
3932 "supported.\n"));
3933 if (use_nt_status()) {
3934 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3936 return NT_STATUS_DOS(ERRDOS, ERRcannotopen);
3939 switch( create_disposition ) {
3940 case FILE_OPEN:
3941 /* If file exists open. If file doesn't exist error. */
3942 if (!file_existed) {
3943 DEBUG(5,("open_file_ntcreate: FILE_OPEN "
3944 "requested for file %s and file "
3945 "doesn't exist.\n",
3946 smb_fname_str_dbg(smb_fname)));
3947 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3949 break;
3951 case FILE_OVERWRITE:
3952 /* If file exists overwrite. If file doesn't exist
3953 * error. */
3954 if (!file_existed) {
3955 DEBUG(5,("open_file_ntcreate: FILE_OVERWRITE "
3956 "requested for file %s and file "
3957 "doesn't exist.\n",
3958 smb_fname_str_dbg(smb_fname) ));
3959 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3961 break;
3963 case FILE_CREATE:
3964 /* If file exists error. If file doesn't exist
3965 * create. */
3966 if (file_existed) {
3967 DEBUG(5,("open_file_ntcreate: FILE_CREATE "
3968 "requested for file %s and file "
3969 "already exists.\n",
3970 smb_fname_str_dbg(smb_fname)));
3971 if (S_ISDIR(smb_fname->st.st_ex_mode)) {
3972 return NT_STATUS_FILE_IS_A_DIRECTORY;
3974 return NT_STATUS_OBJECT_NAME_COLLISION;
3976 break;
3978 case FILE_SUPERSEDE:
3979 case FILE_OVERWRITE_IF:
3980 case FILE_OPEN_IF:
3981 break;
3982 default:
3983 return NT_STATUS_INVALID_PARAMETER;
3986 flags = disposition_to_open_flags(create_disposition);
3988 /* We only care about matching attributes on file exists and
3989 * overwrite. */
3991 if (!posix_open && file_existed &&
3992 ((create_disposition == FILE_OVERWRITE) ||
3993 (create_disposition == FILE_OVERWRITE_IF))) {
3994 if (!open_match_attributes(conn, existing_dos_attributes,
3995 new_dos_attributes,
3996 unx_mode, &new_unx_mode)) {
3997 DEBUG(5,("open_file_ntcreate: attributes mismatch "
3998 "for file %s (%x %x) (0%o, 0%o)\n",
3999 smb_fname_str_dbg(smb_fname),
4000 existing_dos_attributes,
4001 new_dos_attributes,
4002 (unsigned int)smb_fname->st.st_ex_mode,
4003 (unsigned int)unx_mode ));
4004 return NT_STATUS_ACCESS_DENIED;
4008 status = smbd_calculate_access_mask_fsp(parent_dir_fname->fsp,
4009 smb_fname->fsp,
4010 false,
4011 access_mask,
4012 &access_mask);
4013 if (!NT_STATUS_IS_OK(status)) {
4014 DBG_DEBUG("smbd_calculate_access_mask_fsp "
4015 "on file %s returned %s\n",
4016 smb_fname_str_dbg(smb_fname),
4017 nt_errstr(status));
4018 return status;
4021 open_access_mask = access_mask;
4023 if (flags & O_TRUNC) {
4024 open_access_mask |= FILE_WRITE_DATA; /* This will cause oplock breaks. */
4027 if (file_existed) {
4029 * stat opens on existing files don't get oplocks.
4030 * They can get leases.
4032 * Note that we check for stat open on the *open_access_mask*,
4033 * i.e. the access mask we actually used to do the open,
4034 * not the one the client asked for (which is in
4035 * fsp->access_mask). This is due to the fact that
4036 * FILE_OVERWRITE and FILE_OVERWRITE_IF add in O_TRUNC,
4037 * which adds FILE_WRITE_DATA to open_access_mask.
4039 if (is_oplock_stat_open(open_access_mask) && lease == NULL) {
4040 oplock_request = NO_OPLOCK;
4044 DEBUG(10, ("open_file_ntcreate: fname=%s, after mapping "
4045 "access_mask=0x%x\n", smb_fname_str_dbg(smb_fname),
4046 access_mask));
4049 * Note that we ignore the append flag as append does not
4050 * mean the same thing under DOS and Unix.
4053 flags |= calculate_open_access_flags(access_mask, private_flags);
4056 * Currently we only look at FILE_WRITE_THROUGH for create options.
4059 #if defined(O_SYNC)
4060 if ((create_options & FILE_WRITE_THROUGH) && lp_strict_sync(SNUM(conn))) {
4061 flags |= O_SYNC;
4063 #endif /* O_SYNC */
4065 if (posix_open && (access_mask & FILE_APPEND_DATA)) {
4066 flags |= O_APPEND;
4069 if (!posix_open && !CAN_WRITE(conn)) {
4071 * We should really return a permission denied error if either
4072 * O_CREAT or O_TRUNC are set, but for compatibility with
4073 * older versions of Samba we just AND them out.
4075 flags &= ~(O_CREAT | O_TRUNC);
4079 * With kernel oplocks the open breaking an oplock
4080 * blocks until the oplock holder has given up the
4081 * oplock or closed the file. We prevent this by always
4082 * trying to open the file with O_NONBLOCK (see "man
4083 * fcntl" on Linux).
4085 * If a process that doesn't use the smbd open files
4086 * database or communication methods holds a kernel
4087 * oplock we must periodically poll for available open
4088 * using O_NONBLOCK.
4090 flags |= O_NONBLOCK;
4093 * Ensure we can't write on a read-only share or file.
4096 if (((flags & O_ACCMODE) != O_RDONLY) && file_existed &&
4097 (!CAN_WRITE(conn) ||
4098 (existing_dos_attributes & FILE_ATTRIBUTE_READONLY))) {
4099 DEBUG(5,("open_file_ntcreate: write access requested for "
4100 "file %s on read only %s\n",
4101 smb_fname_str_dbg(smb_fname),
4102 !CAN_WRITE(conn) ? "share" : "file" ));
4103 return NT_STATUS_ACCESS_DENIED;
4106 if (VALID_STAT(smb_fname->st)) {
4108 * Only try and create a file id before open
4109 * for an existing file. For a file being created
4110 * this won't do anything useful until the file
4111 * exists and has a valid stat struct.
4113 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
4115 fh_set_private_options(fsp->fh, private_flags);
4116 fsp->access_mask = open_access_mask; /* We change this to the
4117 * requested access_mask after
4118 * the open is done. */
4119 if (posix_open) {
4120 fsp->posix_flags |= FSP_POSIX_FLAGS_ALL;
4123 if ((create_options & FILE_DELETE_ON_CLOSE) && (flags & O_CREAT) &&
4124 !file_existed) {
4125 /* Delete on close semantics for new files. */
4126 status = can_set_delete_on_close(fsp,
4127 new_dos_attributes);
4128 if (!NT_STATUS_IS_OK(status)) {
4129 fd_close(fsp);
4130 return status;
4135 * Ensure we pay attention to default ACLs on directories if required.
4138 if ((flags & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
4139 (def_acl = directory_has_default_acl_fsp(parent_dir_fname->fsp))) {
4140 unx_mode = (0777 & lp_create_mask(SNUM(conn)));
4143 DEBUG(4,
4144 ("calling open_file with flags=0x%X mode=0%o, "
4145 "access_mask = 0x%x, open_access_mask = 0x%x\n",
4146 (unsigned int)flags,
4147 (unsigned int)unx_mode,
4148 (unsigned int)access_mask,
4149 (unsigned int)open_access_mask));
4152 struct vfs_open_how how = {
4153 .flags = flags,
4154 .mode = unx_mode,
4157 if (create_options & FILE_OPEN_FOR_BACKUP_INTENT) {
4158 how.resolve |= VFS_OPEN_HOW_WITH_BACKUP_INTENT;
4161 fsp_open = open_file(req,
4162 parent_dir_fname->fsp,
4163 smb_fname_atname,
4164 fsp,
4165 &how,
4166 access_mask,
4167 open_access_mask,
4168 private_flags,
4169 &new_file_created);
4171 if (NT_STATUS_EQUAL(fsp_open, NT_STATUS_NETWORK_BUSY)) {
4172 if (file_existed && S_ISFIFO(fsp->fsp_name->st.st_ex_mode)) {
4173 DEBUG(10, ("FIFO busy\n"));
4174 return NT_STATUS_NETWORK_BUSY;
4176 if (req == NULL) {
4177 DEBUG(10, ("Internal open busy\n"));
4178 return NT_STATUS_NETWORK_BUSY;
4181 * This handles the kernel oplock case:
4183 * the file has an active kernel oplock and the open() returned
4184 * EWOULDBLOCK/EAGAIN which maps to NETWORK_BUSY.
4186 * "Samba locking.tdb oplocks" are handled below after acquiring
4187 * the sharemode lock with get_share_mode_lock().
4189 setup_poll = true;
4192 if (NT_STATUS_EQUAL(fsp_open, NT_STATUS_RETRY)) {
4194 * EINTR from the open(2) syscall. Just setup a retry
4195 * in a bit. We can't use the sys_write() tight retry
4196 * loop here, as we might have to actually deal with
4197 * lease-break signals to avoid a deadlock.
4199 setup_poll = true;
4202 if (setup_poll) {
4204 * Retry once a second. If there's a share_mode_lock
4205 * around, also wait for it in case it was smbd
4206 * holding that kernel oplock that can quickly tell us
4207 * the oplock got removed.
4210 setup_poll_open(
4211 req,
4212 &fsp->file_id,
4213 timeval_set(OPLOCK_BREAK_TIMEOUT*2, 0),
4214 timeval_set(1, 0));
4216 return NT_STATUS_SHARING_VIOLATION;
4219 if (!NT_STATUS_IS_OK(fsp_open)) {
4220 bool wait_for_aio = NT_STATUS_EQUAL(
4221 fsp_open, NT_STATUS_MORE_PROCESSING_REQUIRED);
4222 if (wait_for_aio) {
4223 schedule_async_open(req);
4225 return fsp_open;
4228 if (new_file_created) {
4230 * As we atomically create using O_CREAT|O_EXCL,
4231 * then if new_file_created is true, then
4232 * file_existed *MUST* have been false (even
4233 * if the file was previously detected as being
4234 * there).
4236 file_existed = false;
4239 if (file_existed && !check_same_dev_ino(&saved_stat, &smb_fname->st)) {
4241 * The file did exist, but some other (local or NFS)
4242 * process either renamed/unlinked and re-created the
4243 * file with different dev/ino after we walked the path,
4244 * but before we did the open. We could retry the
4245 * open but it's a rare enough case it's easier to
4246 * just fail the open to prevent creating any problems
4247 * in the open file db having the wrong dev/ino key.
4249 fd_close(fsp);
4250 DBG_WARNING("file %s - dev/ino mismatch. "
4251 "Old (dev=%ju, ino=%ju). "
4252 "New (dev=%ju, ino=%ju). Failing open "
4253 "with NT_STATUS_ACCESS_DENIED.\n",
4254 smb_fname_str_dbg(smb_fname),
4255 (uintmax_t)saved_stat.st_ex_dev,
4256 (uintmax_t)saved_stat.st_ex_ino,
4257 (uintmax_t)smb_fname->st.st_ex_dev,
4258 (uintmax_t)smb_fname->st.st_ex_ino);
4259 return NT_STATUS_ACCESS_DENIED;
4262 old_write_time = smb_fname->st.st_ex_mtime;
4265 * Deal with the race condition where two smbd's detect the
4266 * file doesn't exist and do the create at the same time. One
4267 * of them will win and set a share mode, the other (ie. this
4268 * one) should check if the requested share mode for this
4269 * create is allowed.
4273 * Now the file exists and fsp is successfully opened,
4274 * fsp->dev and fsp->inode are valid and should replace the
4275 * dev=0,inode=0 from a non existent file. Spotted by
4276 * Nadav Danieli <nadavd@exanet.com>. JRA.
4279 if (new_file_created) {
4280 info = FILE_WAS_CREATED;
4281 } else {
4282 if (flags & O_TRUNC) {
4283 info = FILE_WAS_OVERWRITTEN;
4284 } else {
4285 info = FILE_WAS_OPENED;
4290 * If we created a new file, overwrite an existing one
4291 * or going to delete it later, we should keep
4292 * the share_mode_lock (g_lock) until we call
4293 * share_mode_entry_prepare_unlock()
4295 if (info != FILE_WAS_OPENED) {
4296 keep_locked = true;
4297 } else if (create_options & FILE_DELETE_ON_CLOSE) {
4298 keep_locked = true;
4301 lck_state = (struct open_ntcreate_lock_state) {
4302 .fsp = fsp,
4303 .object_type = "file",
4304 .req = req,
4305 .create_disposition = create_disposition,
4306 .access_mask = access_mask,
4307 .share_access = share_access,
4308 .oplock_request = oplock_request,
4309 .lease = lease,
4310 .first_open_attempt = first_open_attempt,
4311 .keep_locked = keep_locked,
4314 status = share_mode_entry_prepare_lock_add(&lck_state.prepare_state,
4315 fsp->file_id,
4316 conn->connectpath,
4317 smb_fname,
4318 &old_write_time,
4319 open_ntcreate_lock_add_entry,
4320 &lck_state);
4321 if (!NT_STATUS_IS_OK(status)) {
4322 DBG_ERR("share_mode_entry_prepare_lock_add() failed for %s - %s\n",
4323 smb_fname_str_dbg(smb_fname), nt_errstr(status));
4324 fd_close(fsp);
4325 return status;
4328 status = lck_state.status;
4329 if (!NT_STATUS_IS_OK(status)) {
4330 fd_close(fsp);
4331 return status;
4335 * From here we need to use 'goto unlock;' instead of return !!!
4338 if (fsp->oplock_type != NO_OPLOCK && fsp->oplock_type != LEASE_OPLOCK) {
4340 * Now ask for kernel oplocks
4341 * and cleanup on failure.
4343 status = set_file_oplock(fsp);
4344 if (!NT_STATUS_IS_OK(status)) {
4346 * Could not get the kernel oplock
4348 lck_state.cleanup_fn =
4349 open_ntcreate_lock_cleanup_oplock;
4350 fsp->oplock_type = NO_OPLOCK;
4354 /* Should we atomically (to the client at least) truncate ? */
4355 if ((!new_file_created) && (flags & O_TRUNC) &&
4356 (S_ISREG(fsp->fsp_name->st.st_ex_mode))) {
4357 int ret;
4359 ret = SMB_VFS_FTRUNCATE(fsp, 0);
4360 if (ret != 0) {
4361 status = map_nt_error_from_unix(errno);
4362 lck_state.cleanup_fn =
4363 open_ntcreate_lock_cleanup_entry;
4364 goto unlock;
4366 notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
4367 FILE_NOTIFY_CHANGE_SIZE
4368 | FILE_NOTIFY_CHANGE_ATTRIBUTES,
4369 fsp->fsp_name->base_name);
4373 * We have the share entry *locked*.....
4376 /* Delete streams if create_disposition requires it */
4377 if (!new_file_created &&
4378 clear_ads(create_disposition) &&
4379 !fsp_is_alternate_stream(fsp)) {
4380 status = delete_all_streams(conn, smb_fname);
4381 if (!NT_STATUS_IS_OK(status)) {
4382 lck_state.cleanup_fn =
4383 open_ntcreate_lock_cleanup_entry;
4384 goto unlock;
4388 if (!fsp->fsp_flags.is_pathref &&
4389 fsp_get_io_fd(fsp) != -1 &&
4390 lp_kernel_share_modes(SNUM(conn)))
4392 int ret;
4394 * Beware: streams implementing VFS modules may
4395 * implement streams in a way that fsp will have the
4396 * basefile open in the fsp fd, so lacking a distinct
4397 * fd for the stream the file-system sharemode will
4398 * apply on the basefile which is wrong. The actual
4399 * check is deferred to the VFS module implementing
4400 * the file-system sharemode call.
4402 ret = SMB_VFS_FILESYSTEM_SHAREMODE(fsp,
4403 share_access,
4404 access_mask);
4405 if (ret == -1){
4406 status = NT_STATUS_SHARING_VIOLATION;
4407 lck_state.cleanup_fn =
4408 open_ntcreate_lock_cleanup_entry;
4409 goto unlock;
4412 fsp->fsp_flags.kernel_share_modes_taken = true;
4416 * At this point onwards, we can guarantee that the share entry
4417 * is locked, whether we created the file or not, and that the
4418 * deny mode is compatible with all current opens.
4422 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
4423 * but we don't have to store this - just ignore it on access check.
4425 if (conn->sconn->using_smb2) {
4427 * SMB2 doesn't return it (according to Microsoft tests).
4428 * Test Case: TestSuite_ScenarioNo009GrantedAccessTestS0
4429 * File created with access = 0x7 (Read, Write, Delete)
4430 * Query Info on file returns 0x87 (Read, Write, Delete, Read Attributes)
4432 fsp->access_mask = access_mask;
4433 } else {
4434 /* But SMB1 does. */
4435 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
4438 if (pinfo) {
4439 *pinfo = info;
4442 /* Handle strange delete on close create semantics. */
4443 if (create_options & FILE_DELETE_ON_CLOSE) {
4444 if (!new_file_created) {
4445 status = can_set_delete_on_close(fsp,
4446 existing_dos_attributes);
4448 if (!NT_STATUS_IS_OK(status)) {
4449 /* Remember to delete the mode we just added. */
4450 lck_state.cleanup_fn =
4451 open_ntcreate_lock_cleanup_entry;
4452 goto unlock;
4455 /* Note that here we set the *initial* delete on close flag,
4456 not the regular one. The magic gets handled in close. */
4457 fsp->fsp_flags.initial_delete_on_close = true;
4460 possibly_set_archive(conn,
4461 fsp,
4462 smb_fname,
4463 parent_dir_fname,
4464 info,
4465 new_dos_attributes,
4466 &smb_fname->st.st_ex_mode);
4468 /* Determine sparse flag. */
4469 if (posix_open) {
4470 /* POSIX opens are sparse by default. */
4471 fsp->fsp_flags.is_sparse = true;
4472 } else {
4473 fsp->fsp_flags.is_sparse =
4474 (existing_dos_attributes & FILE_ATTRIBUTE_SPARSE);
4478 * Take care of inherited ACLs on created files - if default ACL not
4479 * selected.
4482 if (!posix_open && new_file_created && !def_acl) {
4483 if (unx_mode != smb_fname->st.st_ex_mode) {
4484 int ret = SMB_VFS_FCHMOD(fsp, unx_mode);
4485 if (ret == -1) {
4486 DBG_INFO("failed to reset "
4487 "attributes of file %s to 0%o\n",
4488 smb_fname_str_dbg(smb_fname),
4489 (unsigned int)unx_mode);
4493 } else if (new_unx_mode) {
4495 * We only get here in the case of:
4497 * a). Not a POSIX open.
4498 * b). File already existed.
4499 * c). File was overwritten.
4500 * d). Requested DOS attributes didn't match
4501 * the DOS attributes on the existing file.
4503 * In that case new_unx_mode has been set
4504 * equal to the calculated mode (including
4505 * possible inheritance of the mode from the
4506 * containing directory).
4508 * Note this mode was calculated with the
4509 * DOS attribute FILE_ATTRIBUTE_ARCHIVE added,
4510 * so the mode change here is suitable for
4511 * an overwritten file.
4514 if (new_unx_mode != smb_fname->st.st_ex_mode) {
4515 int ret = SMB_VFS_FCHMOD(fsp, new_unx_mode);
4516 if (ret == -1) {
4517 DBG_INFO("failed to reset "
4518 "attributes of file %s to 0%o\n",
4519 smb_fname_str_dbg(smb_fname),
4520 (unsigned int)new_unx_mode);
4526 * Deal with other opens having a modified write time.
4528 if (fsp_getinfo_ask_sharemode(fsp) &&
4529 !is_omit_timespec(&lck_state.write_time))
4531 update_stat_ex_mtime(&fsp->fsp_name->st, lck_state.write_time);
4534 status = NT_STATUS_OK;
4536 unlock:
4537 ulstatus = share_mode_entry_prepare_unlock(&lck_state.prepare_state,
4538 lck_state.cleanup_fn,
4539 &lck_state);
4540 if (!NT_STATUS_IS_OK(ulstatus)) {
4541 DBG_ERR("share_mode_entry_prepare_unlock() failed for %s - %s\n",
4542 smb_fname_str_dbg(smb_fname), nt_errstr(ulstatus));
4543 smb_panic("share_mode_entry_prepare_unlock() failed!");
4546 if (!NT_STATUS_IS_OK(status)) {
4547 fd_close(fsp);
4548 return status;
4551 return NT_STATUS_OK;
4554 static NTSTATUS mkdir_internal(connection_struct *conn,
4555 struct smb_filename *parent_dir_fname, /* parent. */
4556 struct smb_filename *smb_fname_atname, /* atname relative to parent. */
4557 struct smb_filename *smb_dname, /* full pathname from root of share. */
4558 uint32_t file_attributes,
4559 struct files_struct *fsp)
4561 const struct loadparm_substitution *lp_sub =
4562 loadparm_s3_global_substitution();
4563 mode_t mode;
4564 NTSTATUS status;
4565 bool posix_open = false;
4566 bool need_re_stat = false;
4567 uint32_t access_mask = SEC_DIR_ADD_SUBDIR;
4568 struct vfs_open_how how = { .flags = O_RDONLY|O_DIRECTORY, };
4569 int ret;
4571 if (!CAN_WRITE(conn) || (access_mask & ~(conn->share_access))) {
4572 DEBUG(5,("mkdir_internal: failing share access "
4573 "%s\n", lp_servicename(talloc_tos(), lp_sub, SNUM(conn))));
4574 return NT_STATUS_ACCESS_DENIED;
4577 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
4578 posix_open = true;
4579 mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
4580 } else {
4581 mode = unix_mode(conn,
4582 FILE_ATTRIBUTE_DIRECTORY,
4583 smb_dname,
4584 parent_dir_fname->fsp);
4587 status = check_parent_access_fsp(parent_dir_fname->fsp, access_mask);
4588 if(!NT_STATUS_IS_OK(status)) {
4589 DBG_INFO("check_parent_access_fsp "
4590 "on directory %s for path %s returned %s\n",
4591 smb_fname_str_dbg(parent_dir_fname),
4592 smb_dname->base_name,
4593 nt_errstr(status));
4594 return status;
4597 if (lp_inherit_acls(SNUM(conn))) {
4598 if (directory_has_default_acl_fsp(parent_dir_fname->fsp)) {
4599 mode = (0777 & lp_directory_mask(SNUM(conn)));
4603 ret = SMB_VFS_MKDIRAT(conn,
4604 parent_dir_fname->fsp,
4605 smb_fname_atname,
4606 mode);
4607 if (ret != 0) {
4608 return map_nt_error_from_unix(errno);
4612 * Make this a pathref fsp for now. open_directory() will reopen as a
4613 * full fsp.
4615 fsp->fsp_flags.is_pathref = true;
4617 status = fd_openat(parent_dir_fname->fsp, smb_fname_atname, fsp, &how);
4618 if (!NT_STATUS_IS_OK(status)) {
4619 return status;
4622 /* Ensure we're checking for a symlink here.... */
4623 /* We don't want to get caught by a symlink racer. */
4625 status = vfs_stat_fsp(fsp);
4626 if (!NT_STATUS_IS_OK(status)) {
4627 DEBUG(2, ("Could not stat directory '%s' just created: %s\n",
4628 smb_fname_str_dbg(smb_dname), nt_errstr(status)));
4629 return status;
4632 if (!S_ISDIR(smb_dname->st.st_ex_mode)) {
4633 DEBUG(0, ("Directory '%s' just created is not a directory !\n",
4634 smb_fname_str_dbg(smb_dname)));
4635 return NT_STATUS_NOT_A_DIRECTORY;
4638 if (lp_store_dos_attributes(SNUM(conn))) {
4639 file_set_dosmode(conn,
4640 smb_dname,
4641 file_attributes | FILE_ATTRIBUTE_DIRECTORY,
4642 parent_dir_fname,
4643 true);
4646 if (lp_inherit_permissions(SNUM(conn))) {
4647 inherit_access_posix_acl(conn, parent_dir_fname->fsp,
4648 smb_dname, mode);
4649 need_re_stat = true;
4652 if (!posix_open) {
4654 * Check if high bits should have been set,
4655 * then (if bits are missing): add them.
4656 * Consider bits automagically set by UNIX, i.e. SGID bit from parent
4657 * dir.
4659 if ((mode & ~(S_IRWXU|S_IRWXG|S_IRWXO)) &&
4660 (mode & ~smb_dname->st.st_ex_mode)) {
4661 SMB_VFS_FCHMOD(fsp,
4662 (smb_dname->st.st_ex_mode |
4663 (mode & ~smb_dname->st.st_ex_mode)));
4664 need_re_stat = true;
4668 /* Change the owner if required. */
4669 if (lp_inherit_owner(SNUM(conn)) != INHERIT_OWNER_NO) {
4670 change_dir_owner_to_parent_fsp(parent_dir_fname->fsp,
4671 fsp);
4672 need_re_stat = true;
4675 if (need_re_stat) {
4676 status = vfs_stat_fsp(fsp);
4677 if (!NT_STATUS_IS_OK(status)) {
4678 DEBUG(2, ("Could not stat directory '%s' just created: %s\n",
4679 smb_fname_str_dbg(smb_dname), nt_errstr(status)));
4680 return status;
4684 notify_fname(conn, NOTIFY_ACTION_ADDED, FILE_NOTIFY_CHANGE_DIR_NAME,
4685 smb_dname->base_name);
4687 return NT_STATUS_OK;
4690 /****************************************************************************
4691 Open a directory from an NT SMB call.
4692 ****************************************************************************/
4694 static NTSTATUS open_directory(connection_struct *conn,
4695 struct smb_request *req,
4696 uint32_t access_mask,
4697 uint32_t share_access,
4698 uint32_t create_disposition,
4699 uint32_t create_options,
4700 uint32_t file_attributes,
4701 struct smb_filename *parent_dir_fname,
4702 struct smb_filename *smb_fname_atname,
4703 int *pinfo,
4704 struct files_struct *fsp)
4706 struct smb_filename *smb_dname = fsp->fsp_name;
4707 bool dir_existed = VALID_STAT(smb_dname->st);
4708 struct open_ntcreate_lock_state lck_state = {};
4709 bool keep_locked = false;
4710 NTSTATUS status;
4711 struct timespec mtimespec;
4712 int info = 0;
4713 uint32_t need_fd_access;
4714 NTSTATUS ulstatus;
4716 if (is_ntfs_stream_smb_fname(smb_dname)) {
4717 DEBUG(2, ("open_directory: %s is a stream name!\n",
4718 smb_fname_str_dbg(smb_dname)));
4719 return NT_STATUS_NOT_A_DIRECTORY;
4722 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS)) {
4723 /* Ensure we have a directory attribute. */
4724 file_attributes |= FILE_ATTRIBUTE_DIRECTORY;
4727 DBG_INFO("opening directory %s, access_mask = 0x%"PRIx32", "
4728 "share_access = 0x%"PRIx32" create_options = 0x%"PRIx32", "
4729 "create_disposition = 0x%"PRIx32", "
4730 "file_attributes = 0x%"PRIx32"\n",
4731 smb_fname_str_dbg(smb_dname),
4732 access_mask,
4733 share_access,
4734 create_options,
4735 create_disposition,
4736 file_attributes);
4738 status = smbd_calculate_access_mask_fsp(parent_dir_fname->fsp,
4739 smb_dname->fsp,
4740 false,
4741 access_mask,
4742 &access_mask);
4743 if (!NT_STATUS_IS_OK(status)) {
4744 DBG_DEBUG("smbd_calculate_access_mask_fsp "
4745 "on file %s returned %s\n",
4746 smb_fname_str_dbg(smb_dname),
4747 nt_errstr(status));
4748 return status;
4751 if ((access_mask & SEC_FLAG_SYSTEM_SECURITY) &&
4752 !security_token_has_privilege(get_current_nttok(conn),
4753 SEC_PRIV_SECURITY)) {
4754 DEBUG(10, ("open_directory: open on %s "
4755 "failed - SEC_FLAG_SYSTEM_SECURITY denied.\n",
4756 smb_fname_str_dbg(smb_dname)));
4757 return NT_STATUS_PRIVILEGE_NOT_HELD;
4760 switch( create_disposition ) {
4761 case FILE_OPEN:
4763 if (!dir_existed) {
4764 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4767 info = FILE_WAS_OPENED;
4768 break;
4770 case FILE_CREATE:
4772 /* If directory exists error. If directory doesn't
4773 * exist create. */
4775 if (dir_existed) {
4776 status = NT_STATUS_OBJECT_NAME_COLLISION;
4777 DEBUG(2, ("open_directory: unable to create "
4778 "%s. Error was %s\n",
4779 smb_fname_str_dbg(smb_dname),
4780 nt_errstr(status)));
4781 return status;
4784 status = mkdir_internal(conn,
4785 parent_dir_fname,
4786 smb_fname_atname,
4787 smb_dname,
4788 file_attributes,
4789 fsp);
4791 if (!NT_STATUS_IS_OK(status)) {
4792 DEBUG(2, ("open_directory: unable to create "
4793 "%s. Error was %s\n",
4794 smb_fname_str_dbg(smb_dname),
4795 nt_errstr(status)));
4796 return status;
4799 info = FILE_WAS_CREATED;
4800 break;
4802 case FILE_OPEN_IF:
4804 * If directory exists open. If directory doesn't
4805 * exist create.
4808 if (dir_existed) {
4809 status = NT_STATUS_OK;
4810 info = FILE_WAS_OPENED;
4811 } else {
4812 status = mkdir_internal(conn,
4813 parent_dir_fname,
4814 smb_fname_atname,
4815 smb_dname,
4816 file_attributes,
4817 fsp);
4819 if (NT_STATUS_IS_OK(status)) {
4820 info = FILE_WAS_CREATED;
4821 } else {
4822 int ret;
4823 /* Cope with create race. */
4824 if (!NT_STATUS_EQUAL(status,
4825 NT_STATUS_OBJECT_NAME_COLLISION)) {
4826 DEBUG(2, ("open_directory: unable to create "
4827 "%s. Error was %s\n",
4828 smb_fname_str_dbg(smb_dname),
4829 nt_errstr(status)));
4830 return status;
4834 * If mkdir_internal() returned
4835 * NT_STATUS_OBJECT_NAME_COLLISION
4836 * we still must lstat the path.
4838 ret = SMB_VFS_FSTATAT(
4839 conn,
4840 parent_dir_fname->fsp,
4841 smb_fname_atname,
4842 &smb_dname->st,
4843 AT_SYMLINK_NOFOLLOW);
4844 if (ret == -1) {
4845 DEBUG(2, ("Could not stat "
4846 "directory '%s' just "
4847 "opened: %s\n",
4848 smb_fname_str_dbg(
4849 smb_dname),
4850 strerror(errno)));
4851 return map_nt_error_from_unix(
4852 errno);
4855 info = FILE_WAS_OPENED;
4859 break;
4861 case FILE_SUPERSEDE:
4862 case FILE_OVERWRITE:
4863 case FILE_OVERWRITE_IF:
4864 default:
4865 DEBUG(5,("open_directory: invalid create_disposition "
4866 "0x%x for directory %s\n",
4867 (unsigned int)create_disposition,
4868 smb_fname_str_dbg(smb_dname)));
4869 return NT_STATUS_INVALID_PARAMETER;
4872 if(!S_ISDIR(smb_dname->st.st_ex_mode)) {
4873 DEBUG(5,("open_directory: %s is not a directory !\n",
4874 smb_fname_str_dbg(smb_dname)));
4875 return NT_STATUS_NOT_A_DIRECTORY;
4879 * Setup the files_struct for it.
4882 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_dname->st);
4883 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
4884 fsp->file_pid = req ? req->smbpid : 0;
4885 fsp->fsp_flags.can_lock = false;
4886 fsp->fsp_flags.can_read = false;
4887 fsp->fsp_flags.can_write = false;
4889 fh_set_private_options(fsp->fh, 0);
4891 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
4893 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
4894 fsp->print_file = NULL;
4895 fsp->fsp_flags.modified = false;
4896 fsp->oplock_type = NO_OPLOCK;
4897 fsp->sent_oplock_break = NO_BREAK_SENT;
4898 fsp->fsp_flags.is_directory = true;
4899 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
4900 fsp->posix_flags |= FSP_POSIX_FLAGS_ALL;
4903 /* Don't store old timestamps for directory
4904 handles in the internal database. We don't
4905 update them in there if new objects
4906 are created in the directory. Currently
4907 we only update timestamps on file writes.
4908 See bug #9870.
4910 mtimespec = make_omit_timespec();
4913 * Obviously for FILE_LIST_DIRECTORY we need to reopen to get an fd
4914 * usable for reading a directory. SMB2_FLUSH may be called on
4915 * directories opened with FILE_ADD_FILE and FILE_ADD_SUBDIRECTORY so
4916 * for those we need to reopen as well.
4918 need_fd_access =
4919 FILE_LIST_DIRECTORY |
4920 FILE_ADD_FILE |
4921 FILE_ADD_SUBDIRECTORY;
4923 if (access_mask & need_fd_access) {
4924 struct vfs_open_how how = {
4925 .flags = O_RDONLY | O_DIRECTORY,
4927 bool file_created;
4929 status = reopen_from_fsp(fsp->conn->cwd_fsp,
4930 fsp->fsp_name,
4931 fsp,
4932 &how,
4933 &file_created);
4934 if (!NT_STATUS_IS_OK(status)) {
4935 DBG_INFO("Could not open fd for [%s]: %s\n",
4936 smb_fname_str_dbg(smb_dname),
4937 nt_errstr(status));
4938 return status;
4942 status = vfs_stat_fsp(fsp);
4943 if (!NT_STATUS_IS_OK(status)) {
4944 fd_close(fsp);
4945 return status;
4948 if(!S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
4949 DEBUG(5,("open_directory: %s is not a directory !\n",
4950 smb_fname_str_dbg(smb_dname)));
4951 fd_close(fsp);
4952 return NT_STATUS_NOT_A_DIRECTORY;
4955 /* Ensure there was no race condition. We need to check
4956 * dev/inode but not permissions, as these can change
4957 * legitimately */
4958 if (!check_same_dev_ino(&smb_dname->st, &fsp->fsp_name->st)) {
4959 DEBUG(5,("open_directory: stat struct differs for "
4960 "directory %s.\n",
4961 smb_fname_str_dbg(smb_dname)));
4962 fd_close(fsp);
4963 return NT_STATUS_ACCESS_DENIED;
4966 if (info == FILE_WAS_OPENED) {
4967 status = smbd_check_access_rights_fsp(parent_dir_fname->fsp,
4968 fsp,
4969 false,
4970 access_mask);
4971 if (!NT_STATUS_IS_OK(status)) {
4972 DBG_DEBUG("smbd_check_access_rights_fsp on "
4973 "file %s failed with %s\n",
4974 fsp_str_dbg(fsp),
4975 nt_errstr(status));
4976 fd_close(fsp);
4977 return status;
4982 * If we created a new directory or going to delete it later,
4983 * we should keep * the share_mode_lock (g_lock) until we call
4984 * share_mode_entry_prepare_unlock()
4986 if (info != FILE_WAS_OPENED) {
4987 keep_locked = true;
4988 } else if (create_options & FILE_DELETE_ON_CLOSE) {
4989 keep_locked = true;
4992 lck_state = (struct open_ntcreate_lock_state) {
4993 .fsp = fsp,
4994 .object_type = "directory",
4995 .req = req,
4996 .create_disposition = create_disposition,
4997 .access_mask = access_mask,
4998 .share_access = share_access,
4999 .oplock_request = NO_OPLOCK,
5000 .lease = NULL,
5001 .first_open_attempt = true,
5002 .keep_locked = keep_locked,
5005 status = share_mode_entry_prepare_lock_add(&lck_state.prepare_state,
5006 fsp->file_id,
5007 conn->connectpath,
5008 smb_dname,
5009 &mtimespec,
5010 open_ntcreate_lock_add_entry,
5011 &lck_state);
5012 if (!NT_STATUS_IS_OK(status)) {
5013 DBG_ERR("share_mode_entry_prepare_lock_add() failed for %s - %s\n",
5014 smb_fname_str_dbg(smb_dname), nt_errstr(status));
5015 fd_close(fsp);
5016 return status;
5019 status = lck_state.status;
5020 if (!NT_STATUS_IS_OK(status)) {
5021 fd_close(fsp);
5022 return status;
5026 * From here we need to use 'goto unlock;' instead of return !!!
5029 /* For directories the delete on close bit at open time seems
5030 always to be honored on close... See test 19 in Samba4 BASE-DELETE. */
5031 if (create_options & FILE_DELETE_ON_CLOSE) {
5032 status = can_set_delete_on_close(fsp, 0);
5033 if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
5034 lck_state.cleanup_fn =
5035 open_ntcreate_lock_cleanup_entry;
5036 goto unlock;
5039 if (NT_STATUS_IS_OK(status)) {
5040 /* Note that here we set the *initial* delete on close flag,
5041 not the regular one. The magic gets handled in close. */
5042 fsp->fsp_flags.initial_delete_on_close = true;
5047 * Deal with other opens having a modified write time.
5049 if (!is_omit_timespec(&lck_state.write_time)) {
5050 update_stat_ex_mtime(&fsp->fsp_name->st, lck_state.write_time);
5053 if (pinfo) {
5054 *pinfo = info;
5057 status = NT_STATUS_OK;
5059 unlock:
5060 ulstatus = share_mode_entry_prepare_unlock(&lck_state.prepare_state,
5061 lck_state.cleanup_fn,
5062 &lck_state);
5063 if (!NT_STATUS_IS_OK(ulstatus)) {
5064 DBG_ERR("share_mode_entry_prepare_unlock() failed for %s - %s\n",
5065 smb_fname_str_dbg(smb_dname), nt_errstr(ulstatus));
5066 smb_panic("share_mode_entry_prepare_unlock() failed!");
5069 if (!NT_STATUS_IS_OK(status)) {
5070 fd_close(fsp);
5071 return status;
5074 return NT_STATUS_OK;
5077 NTSTATUS create_directory(connection_struct *conn,
5078 struct smb_request *req,
5079 struct files_struct *dirfsp,
5080 struct smb_filename *smb_dname)
5082 NTSTATUS status;
5083 files_struct *fsp;
5085 status = SMB_VFS_CREATE_FILE(
5086 conn, /* conn */
5087 req, /* req */
5088 dirfsp, /* dirfsp */
5089 smb_dname, /* fname */
5090 FILE_READ_ATTRIBUTES, /* access_mask */
5091 FILE_SHARE_NONE, /* share_access */
5092 FILE_CREATE, /* create_disposition*/
5093 FILE_DIRECTORY_FILE, /* create_options */
5094 FILE_ATTRIBUTE_DIRECTORY, /* file_attributes */
5095 0, /* oplock_request */
5096 NULL, /* lease */
5097 0, /* allocation_size */
5098 0, /* private_flags */
5099 NULL, /* sd */
5100 NULL, /* ea_list */
5101 &fsp, /* result */
5102 NULL, /* pinfo */
5103 NULL, NULL); /* create context */
5105 if (NT_STATUS_IS_OK(status)) {
5106 close_file_free(req, &fsp, NORMAL_CLOSE);
5109 return status;
5112 /****************************************************************************
5113 Receive notification that one of our open files has been renamed by another
5114 smbd process.
5115 ****************************************************************************/
5117 void msg_file_was_renamed(struct messaging_context *msg_ctx,
5118 void *private_data,
5119 uint32_t msg_type,
5120 struct server_id src,
5121 DATA_BLOB *data)
5123 struct file_rename_message *msg = NULL;
5124 enum ndr_err_code ndr_err;
5125 files_struct *fsp;
5126 struct smb_filename *smb_fname = NULL;
5127 struct smbd_server_connection *sconn =
5128 talloc_get_type_abort(private_data,
5129 struct smbd_server_connection);
5131 msg = talloc(talloc_tos(), struct file_rename_message);
5132 if (msg == NULL) {
5133 DBG_WARNING("talloc failed\n");
5134 return;
5137 ndr_err = ndr_pull_struct_blob_all(
5138 data,
5139 msg,
5140 msg,
5141 (ndr_pull_flags_fn_t)ndr_pull_file_rename_message);
5142 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
5143 DBG_DEBUG("ndr_pull_oplock_break_message failed: %s\n",
5144 ndr_errstr(ndr_err));
5145 goto out;
5147 if (DEBUGLEVEL >= 10) {
5148 struct server_id_buf buf;
5149 DBG_DEBUG("Got rename message from %s\n",
5150 server_id_str_buf(src, &buf));
5151 NDR_PRINT_DEBUG(file_rename_message, msg);
5154 /* stream_name must always be NULL if there is no stream. */
5155 if ((msg->stream_name != NULL) && (msg->stream_name[0] == '\0')) {
5156 msg->stream_name = NULL;
5159 smb_fname = synthetic_smb_fname(msg,
5160 msg->base_name,
5161 msg->stream_name,
5162 NULL,
5165 if (smb_fname == NULL) {
5166 DBG_DEBUG("synthetic_smb_fname failed\n");
5167 goto out;
5170 fsp = file_find_dif(sconn, msg->id, msg->share_file_id);
5171 if (fsp == NULL) {
5172 DBG_DEBUG("fsp not found\n");
5173 goto out;
5176 if (strcmp(fsp->conn->connectpath, msg->servicepath) == 0) {
5177 SMB_STRUCT_STAT fsp_orig_sbuf;
5178 NTSTATUS status;
5179 DBG_DEBUG("renaming file %s from %s -> %s\n",
5180 fsp_fnum_dbg(fsp),
5181 fsp_str_dbg(fsp),
5182 smb_fname_str_dbg(smb_fname));
5185 * The incoming smb_fname here has an
5186 * invalid stat struct from synthetic_smb_fname()
5187 * above.
5188 * Preserve the existing stat from the
5189 * open fsp after fsp_set_smb_fname()
5190 * overwrites with the invalid stat.
5192 * (We could just copy this into
5193 * smb_fname->st, but keep this code
5194 * identical to the fix in rename_open_files()
5195 * for clarity.
5197 * We will do an fstat before returning
5198 * any of this metadata to the client anyway.
5200 fsp_orig_sbuf = fsp->fsp_name->st;
5201 status = fsp_set_smb_fname(fsp, smb_fname);
5202 if (!NT_STATUS_IS_OK(status)) {
5203 DBG_DEBUG("fsp_set_smb_fname failed: %s\n",
5204 nt_errstr(status));
5206 fsp->fsp_name->st = fsp_orig_sbuf;
5207 } else {
5208 /* TODO. JRA. */
5210 * Now we have the complete path we can work out if
5211 * this is actually within this share and adjust
5212 * newname accordingly.
5214 DBG_DEBUG("share mismatch (sharepath %s not sharepath %s) "
5215 "%s from %s -> %s\n",
5216 fsp->conn->connectpath,
5217 msg->servicepath,
5218 fsp_fnum_dbg(fsp),
5219 fsp_str_dbg(fsp),
5220 smb_fname_str_dbg(smb_fname));
5222 out:
5223 TALLOC_FREE(msg);
5227 * If a main file is opened for delete, all streams need to be checked for
5228 * !FILE_SHARE_DELETE. Do this by opening with DELETE_ACCESS.
5229 * If that works, delete them all by setting the delete on close and close.
5232 static NTSTATUS open_streams_for_delete(connection_struct *conn,
5233 const struct smb_filename *smb_fname)
5235 struct stream_struct *stream_info = NULL;
5236 files_struct **streams = NULL;
5237 int j;
5238 unsigned int i, num_streams = 0;
5239 TALLOC_CTX *frame = talloc_stackframe();
5240 const struct smb_filename *pathref = NULL;
5241 NTSTATUS status;
5243 if (smb_fname->fsp == NULL) {
5244 struct smb_filename *tmp = NULL;
5245 status = synthetic_pathref(frame,
5246 conn->cwd_fsp,
5247 smb_fname->base_name,
5248 NULL,
5249 NULL,
5250 smb_fname->twrp,
5251 smb_fname->flags,
5252 &tmp);
5253 if (!NT_STATUS_IS_OK(status)) {
5254 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
5255 || NT_STATUS_EQUAL(status,
5256 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
5257 DBG_DEBUG("no streams around\n");
5258 TALLOC_FREE(frame);
5259 return NT_STATUS_OK;
5261 DBG_DEBUG("synthetic_pathref failed: %s\n",
5262 nt_errstr(status));
5263 goto fail;
5265 pathref = tmp;
5266 } else {
5267 pathref = smb_fname;
5269 status = vfs_fstreaminfo(pathref->fsp, talloc_tos(),
5270 &num_streams, &stream_info);
5272 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
5273 || NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
5274 DEBUG(10, ("no streams around\n"));
5275 TALLOC_FREE(frame);
5276 return NT_STATUS_OK;
5279 if (!NT_STATUS_IS_OK(status)) {
5280 DEBUG(10, ("vfs_fstreaminfo failed: %s\n",
5281 nt_errstr(status)));
5282 goto fail;
5285 DEBUG(10, ("open_streams_for_delete found %d streams\n",
5286 num_streams));
5288 if (num_streams == 0) {
5289 TALLOC_FREE(frame);
5290 return NT_STATUS_OK;
5293 streams = talloc_array(talloc_tos(), files_struct *, num_streams);
5294 if (streams == NULL) {
5295 DEBUG(0, ("talloc failed\n"));
5296 status = NT_STATUS_NO_MEMORY;
5297 goto fail;
5300 for (i=0; i<num_streams; i++) {
5301 struct smb_filename *smb_fname_cp;
5303 if (strequal(stream_info[i].name, "::$DATA")) {
5304 streams[i] = NULL;
5305 continue;
5308 smb_fname_cp = synthetic_smb_fname(talloc_tos(),
5309 smb_fname->base_name,
5310 stream_info[i].name,
5311 NULL,
5312 smb_fname->twrp,
5313 (smb_fname->flags &
5314 ~SMB_FILENAME_POSIX_PATH));
5315 if (smb_fname_cp == NULL) {
5316 status = NT_STATUS_NO_MEMORY;
5317 goto fail;
5320 status = openat_pathref_fsp(conn->cwd_fsp, smb_fname_cp);
5321 if (!NT_STATUS_IS_OK(status)) {
5322 DBG_DEBUG("Unable to open stream [%s]: %s\n",
5323 smb_fname_str_dbg(smb_fname_cp),
5324 nt_errstr(status));
5325 TALLOC_FREE(smb_fname_cp);
5326 break;
5329 status = SMB_VFS_CREATE_FILE(
5330 conn, /* conn */
5331 NULL, /* req */
5332 NULL, /* dirfsp */
5333 smb_fname_cp, /* fname */
5334 DELETE_ACCESS, /* access_mask */
5335 (FILE_SHARE_READ | /* share_access */
5336 FILE_SHARE_WRITE | FILE_SHARE_DELETE),
5337 FILE_OPEN, /* create_disposition*/
5338 0, /* create_options */
5339 FILE_ATTRIBUTE_NORMAL, /* file_attributes */
5340 0, /* oplock_request */
5341 NULL, /* lease */
5342 0, /* allocation_size */
5343 0, /* private_flags */
5344 NULL, /* sd */
5345 NULL, /* ea_list */
5346 &streams[i], /* result */
5347 NULL, /* pinfo */
5348 NULL, NULL); /* create context */
5350 if (!NT_STATUS_IS_OK(status)) {
5351 DEBUG(10, ("Could not open stream %s: %s\n",
5352 smb_fname_str_dbg(smb_fname_cp),
5353 nt_errstr(status)));
5355 TALLOC_FREE(smb_fname_cp);
5356 break;
5358 TALLOC_FREE(smb_fname_cp);
5362 * don't touch the variable "status" beyond this point :-)
5365 for (j = i-1 ; j >= 0; j--) {
5366 if (streams[j] == NULL) {
5367 continue;
5370 DEBUG(10, ("Closing stream # %d, %s\n", j,
5371 fsp_str_dbg(streams[j])));
5372 close_file_free(NULL, &streams[j], NORMAL_CLOSE);
5375 fail:
5376 TALLOC_FREE(frame);
5377 return status;
5380 /*********************************************************************
5381 Create a default ACL by inheriting from the parent. If no inheritance
5382 from the parent available, don't set anything. This will leave the actual
5383 permissions the new file or directory already got from the filesystem
5384 as the NT ACL when read.
5385 *********************************************************************/
5387 static NTSTATUS inherit_new_acl(files_struct *dirfsp, files_struct *fsp)
5389 TALLOC_CTX *frame = talloc_stackframe();
5390 struct security_descriptor *parent_desc = NULL;
5391 NTSTATUS status = NT_STATUS_OK;
5392 struct security_descriptor *psd = NULL;
5393 const struct dom_sid *owner_sid = NULL;
5394 const struct dom_sid *group_sid = NULL;
5395 uint32_t security_info_sent = (SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL);
5396 struct security_token *token = fsp->conn->session_info->security_token;
5397 bool inherit_owner =
5398 (lp_inherit_owner(SNUM(fsp->conn)) == INHERIT_OWNER_WINDOWS_AND_UNIX);
5399 bool inheritable_components = false;
5400 bool try_builtin_administrators = false;
5401 const struct dom_sid *BA_U_sid = NULL;
5402 const struct dom_sid *BA_G_sid = NULL;
5403 bool try_system = false;
5404 const struct dom_sid *SY_U_sid = NULL;
5405 const struct dom_sid *SY_G_sid = NULL;
5406 size_t size = 0;
5407 bool ok;
5409 status = SMB_VFS_FGET_NT_ACL(dirfsp,
5410 (SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL),
5411 frame,
5412 &parent_desc);
5413 if (!NT_STATUS_IS_OK(status)) {
5414 TALLOC_FREE(frame);
5415 return status;
5418 inheritable_components = sd_has_inheritable_components(parent_desc,
5419 fsp->fsp_flags.is_directory);
5421 if (!inheritable_components && !inherit_owner) {
5422 TALLOC_FREE(frame);
5423 /* Nothing to inherit and not setting owner. */
5424 return NT_STATUS_OK;
5427 /* Create an inherited descriptor from the parent. */
5429 if (DEBUGLEVEL >= 10) {
5430 DEBUG(10,("inherit_new_acl: parent acl for %s is:\n",
5431 fsp_str_dbg(fsp) ));
5432 NDR_PRINT_DEBUG(security_descriptor, parent_desc);
5435 /* Inherit from parent descriptor if "inherit owner" set. */
5436 if (inherit_owner) {
5437 owner_sid = parent_desc->owner_sid;
5438 group_sid = parent_desc->group_sid;
5441 if (owner_sid == NULL) {
5442 if (security_token_has_builtin_administrators(token)) {
5443 try_builtin_administrators = true;
5444 } else if (security_token_is_system(token)) {
5445 try_builtin_administrators = true;
5446 try_system = true;
5450 if (group_sid == NULL &&
5451 token->num_sids == PRIMARY_GROUP_SID_INDEX)
5453 if (security_token_is_system(token)) {
5454 try_builtin_administrators = true;
5455 try_system = true;
5459 if (try_builtin_administrators) {
5460 struct unixid ids = { .id = 0 };
5462 ok = sids_to_unixids(&global_sid_Builtin_Administrators, 1, &ids);
5463 if (ok) {
5464 switch (ids.type) {
5465 case ID_TYPE_BOTH:
5466 BA_U_sid = &global_sid_Builtin_Administrators;
5467 BA_G_sid = &global_sid_Builtin_Administrators;
5468 break;
5469 case ID_TYPE_UID:
5470 BA_U_sid = &global_sid_Builtin_Administrators;
5471 break;
5472 case ID_TYPE_GID:
5473 BA_G_sid = &global_sid_Builtin_Administrators;
5474 break;
5475 default:
5476 break;
5481 if (try_system) {
5482 struct unixid ids = { .id = 0 };
5484 ok = sids_to_unixids(&global_sid_System, 1, &ids);
5485 if (ok) {
5486 switch (ids.type) {
5487 case ID_TYPE_BOTH:
5488 SY_U_sid = &global_sid_System;
5489 SY_G_sid = &global_sid_System;
5490 break;
5491 case ID_TYPE_UID:
5492 SY_U_sid = &global_sid_System;
5493 break;
5494 case ID_TYPE_GID:
5495 SY_G_sid = &global_sid_System;
5496 break;
5497 default:
5498 break;
5503 if (owner_sid == NULL) {
5504 owner_sid = BA_U_sid;
5507 if (owner_sid == NULL) {
5508 owner_sid = SY_U_sid;
5511 if (group_sid == NULL) {
5512 group_sid = SY_G_sid;
5515 if (try_system && group_sid == NULL) {
5516 group_sid = BA_G_sid;
5519 if (owner_sid == NULL) {
5520 owner_sid = &token->sids[PRIMARY_USER_SID_INDEX];
5522 if (group_sid == NULL) {
5523 if (token->num_sids == PRIMARY_GROUP_SID_INDEX) {
5524 group_sid = &token->sids[PRIMARY_USER_SID_INDEX];
5525 } else {
5526 group_sid = &token->sids[PRIMARY_GROUP_SID_INDEX];
5530 status = se_create_child_secdesc(frame,
5531 &psd,
5532 &size,
5533 parent_desc,
5534 owner_sid,
5535 group_sid,
5536 fsp->fsp_flags.is_directory);
5537 if (!NT_STATUS_IS_OK(status)) {
5538 TALLOC_FREE(frame);
5539 return status;
5542 /* If inheritable_components == false,
5543 se_create_child_secdesc()
5544 creates a security descriptor with a NULL dacl
5545 entry, but with SEC_DESC_DACL_PRESENT. We need
5546 to remove that flag. */
5548 if (!inheritable_components) {
5549 security_info_sent &= ~SECINFO_DACL;
5550 psd->type &= ~SEC_DESC_DACL_PRESENT;
5553 if (DEBUGLEVEL >= 10) {
5554 DEBUG(10,("inherit_new_acl: child acl for %s is:\n",
5555 fsp_str_dbg(fsp) ));
5556 NDR_PRINT_DEBUG(security_descriptor, psd);
5559 if (inherit_owner) {
5560 /* We need to be root to force this. */
5561 become_root();
5563 status = SMB_VFS_FSET_NT_ACL(metadata_fsp(fsp),
5564 security_info_sent,
5565 psd);
5566 if (inherit_owner) {
5567 unbecome_root();
5569 TALLOC_FREE(frame);
5570 return status;
5574 * If we already have a lease, it must match the new file id. [MS-SMB2]
5575 * 3.3.5.9.8 speaks about INVALID_PARAMETER if an already used lease key is
5576 * used for a different file name.
5579 struct lease_match_state {
5580 /* Input parameters. */
5581 TALLOC_CTX *mem_ctx;
5582 const char *servicepath;
5583 const struct smb_filename *fname;
5584 bool file_existed;
5585 struct file_id id;
5586 /* Return parameters. */
5587 uint32_t num_file_ids;
5588 struct file_id *ids;
5589 NTSTATUS match_status;
5592 /*************************************************************
5593 File doesn't exist but this lease key+guid is already in use.
5595 This is only allowable in the dynamic share case where the
5596 service path must be different.
5598 There is a small race condition here in the multi-connection
5599 case where a client sends two create calls on different connections,
5600 where the file doesn't exist and one smbd creates the leases_db
5601 entry first, but this will get fixed by the multichannel cleanup
5602 when all identical client_guids get handled by a single smbd.
5603 **************************************************************/
5605 static void lease_match_parser_new_file(
5606 uint32_t num_files,
5607 const struct leases_db_file *files,
5608 struct lease_match_state *state)
5610 uint32_t i;
5612 for (i = 0; i < num_files; i++) {
5613 const struct leases_db_file *f = &files[i];
5614 if (strequal(state->servicepath, f->servicepath)) {
5615 state->match_status = NT_STATUS_INVALID_PARAMETER;
5616 return;
5620 /* Dynamic share case. Break leases on all other files. */
5621 state->match_status = leases_db_copy_file_ids(state->mem_ctx,
5622 num_files,
5623 files,
5624 &state->ids);
5625 if (!NT_STATUS_IS_OK(state->match_status)) {
5626 return;
5629 state->num_file_ids = num_files;
5630 state->match_status = NT_STATUS_OPLOCK_NOT_GRANTED;
5631 return;
5634 static void lease_match_parser(
5635 uint32_t num_files,
5636 const struct leases_db_file *files,
5637 void *private_data)
5639 struct lease_match_state *state =
5640 (struct lease_match_state *)private_data;
5641 uint32_t i;
5643 if (!state->file_existed) {
5645 * Deal with name mismatch or
5646 * possible dynamic share case separately
5647 * to make code clearer.
5649 lease_match_parser_new_file(num_files,
5650 files,
5651 state);
5652 return;
5655 /* File existed. */
5656 state->match_status = NT_STATUS_OK;
5658 for (i = 0; i < num_files; i++) {
5659 const struct leases_db_file *f = &files[i];
5661 /* Everything should be the same. */
5662 if (!file_id_equal(&state->id, &f->id)) {
5664 * The client asked for a lease on a
5665 * file that doesn't match the file_id
5666 * in the database.
5668 * Maybe this is a dynamic share, i.e.
5669 * a share where the servicepath is
5670 * different for different users (e.g.
5671 * the [HOMES] share.
5673 * If the servicepath is different, but the requested
5674 * file name + stream name is the same then this is
5675 * a dynamic share, the client is using the same share
5676 * name and doesn't know that the underlying servicepath
5677 * is different. It was expecting a lease on the
5678 * same file. Return NT_STATUS_OPLOCK_NOT_GRANTED
5679 * to break leases
5681 * Otherwise the client has messed up, or is
5682 * testing our error codes, so return
5683 * NT_STATUS_INVALID_PARAMETER.
5685 if (!strequal(f->servicepath, state->servicepath) &&
5686 strequal(f->base_name, state->fname->base_name) &&
5687 strequal(f->stream_name, state->fname->stream_name))
5690 * Name is the same but servicepath is
5691 * different, dynamic share. Break leases.
5693 state->match_status =
5694 NT_STATUS_OPLOCK_NOT_GRANTED;
5695 } else {
5696 state->match_status =
5697 NT_STATUS_INVALID_PARAMETER;
5699 break;
5701 if (!strequal(f->servicepath, state->servicepath)) {
5702 state->match_status = NT_STATUS_INVALID_PARAMETER;
5703 break;
5705 if (!strequal(f->base_name, state->fname->base_name)) {
5706 state->match_status = NT_STATUS_INVALID_PARAMETER;
5707 break;
5709 if (!strequal(f->stream_name, state->fname->stream_name)) {
5710 state->match_status = NT_STATUS_INVALID_PARAMETER;
5711 break;
5715 if (NT_STATUS_IS_OK(state->match_status)) {
5717 * Common case - just opening another handle on a
5718 * file on a non-dynamic share.
5720 return;
5723 if (NT_STATUS_EQUAL(state->match_status, NT_STATUS_INVALID_PARAMETER)) {
5724 /* Mismatched path. Error back to client. */
5725 return;
5729 * File id mismatch. Dynamic share case NT_STATUS_OPLOCK_NOT_GRANTED.
5730 * Don't allow leases.
5733 state->match_status = leases_db_copy_file_ids(state->mem_ctx,
5734 num_files,
5735 files,
5736 &state->ids);
5737 if (!NT_STATUS_IS_OK(state->match_status)) {
5738 return;
5741 state->num_file_ids = num_files;
5742 state->match_status = NT_STATUS_OPLOCK_NOT_GRANTED;
5743 return;
5746 struct lease_match_break_state {
5747 struct messaging_context *msg_ctx;
5748 const struct smb2_lease_key *lease_key;
5749 struct file_id id;
5751 bool found_lease;
5752 uint16_t version;
5753 uint16_t epoch;
5756 static bool lease_match_break_fn(
5757 struct share_mode_entry *e,
5758 void *private_data)
5760 struct lease_match_break_state *state = private_data;
5761 bool stale, equal;
5762 uint32_t e_lease_type = SMB2_LEASE_NONE;
5763 NTSTATUS status;
5765 stale = share_entry_stale_pid(e);
5766 if (stale) {
5767 return false;
5770 equal = smb2_lease_key_equal(&e->lease_key, state->lease_key);
5771 if (!equal) {
5772 return false;
5775 status = leases_db_get(
5776 &e->client_guid,
5777 &e->lease_key,
5778 &state->id,
5779 &e_lease_type, /* current_state */
5780 NULL, /* breaking */
5781 NULL, /* breaking_to_requested */
5782 NULL, /* breaking_to_required */
5783 &state->version, /* lease_version */
5784 &state->epoch); /* epoch */
5785 if (NT_STATUS_IS_OK(status)) {
5786 state->found_lease = true;
5787 } else {
5788 DBG_WARNING("Could not find version/epoch: %s\n",
5789 nt_errstr(status));
5790 return false;
5793 if (e_lease_type == SMB2_LEASE_NONE) {
5794 return false;
5796 send_break_message(state->msg_ctx, &state->id, e, SMB2_LEASE_NONE);
5799 * Windows 7 and 8 lease clients are broken in that they will
5800 * not respond to lease break requests whilst waiting for an
5801 * outstanding open request on that lease handle on the same
5802 * TCP connection, due to holding an internal inode lock.
5804 * This means we can't reschedule ourselves here, but must
5805 * return from the create.
5807 * Work around:
5809 * Send the breaks and then return SMB2_LEASE_NONE in the
5810 * lease handle to cause them to acknowledge the lease
5811 * break. Consultation with Microsoft engineering confirmed
5812 * this approach is safe.
5815 return false;
5818 static void lease_match_fid_fn(struct share_mode_lock *lck,
5819 void *private_data)
5821 bool ok;
5823 ok = share_mode_forall_leases(lck, lease_match_break_fn, private_data);
5824 if (!ok) {
5825 DBG_DEBUG("share_mode_forall_leases failed\n");
5829 static NTSTATUS lease_match(connection_struct *conn,
5830 struct smb_request *req,
5831 const struct smb2_lease_key *lease_key,
5832 const char *servicepath,
5833 const struct smb_filename *fname,
5834 uint16_t *p_version,
5835 uint16_t *p_epoch)
5837 struct smbd_server_connection *sconn = req->sconn;
5838 TALLOC_CTX *tos = talloc_tos();
5839 struct lease_match_state state = {
5840 .mem_ctx = tos,
5841 .servicepath = servicepath,
5842 .fname = fname,
5843 .match_status = NT_STATUS_OK
5845 uint32_t i;
5846 NTSTATUS status;
5848 state.file_existed = VALID_STAT(fname->st);
5849 if (state.file_existed) {
5850 state.id = vfs_file_id_from_sbuf(conn, &fname->st);
5853 status = leases_db_parse(&sconn->client->global->client_guid,
5854 lease_key, lease_match_parser, &state);
5855 if (!NT_STATUS_IS_OK(status)) {
5857 * Not found or error means okay: We can make the lease pass
5859 return NT_STATUS_OK;
5861 if (!NT_STATUS_EQUAL(state.match_status, NT_STATUS_OPLOCK_NOT_GRANTED)) {
5863 * Anything but NT_STATUS_OPLOCK_NOT_GRANTED, let the caller
5864 * deal with it.
5866 return state.match_status;
5869 /* We have to break all existing leases. */
5870 for (i = 0; i < state.num_file_ids; i++) {
5871 struct lease_match_break_state break_state = {
5872 .msg_ctx = conn->sconn->msg_ctx,
5873 .lease_key = lease_key,
5876 if (file_id_equal(&state.ids[i], &state.id)) {
5877 /* Don't need to break our own file. */
5878 continue;
5881 break_state.id = state.ids[i];
5883 status = share_mode_do_locked_vfs_denied(break_state.id,
5884 lease_match_fid_fn,
5885 &break_state);
5886 if (!NT_STATUS_IS_OK(status)) {
5887 /* Race condition - file already closed. */
5888 continue;
5891 if (break_state.found_lease) {
5892 *p_version = break_state.version;
5893 *p_epoch = break_state.epoch;
5897 * Ensure we don't grant anything more so we
5898 * never upgrade.
5900 return NT_STATUS_OPLOCK_NOT_GRANTED;
5904 * Wrapper around open_file_ntcreate and open_directory
5907 static NTSTATUS create_file_unixpath(connection_struct *conn,
5908 struct smb_request *req,
5909 struct files_struct *dirfsp,
5910 struct smb_filename *smb_fname,
5911 uint32_t access_mask,
5912 uint32_t share_access,
5913 uint32_t create_disposition,
5914 uint32_t create_options,
5915 uint32_t file_attributes,
5916 uint32_t oplock_request,
5917 const struct smb2_lease *lease,
5918 uint64_t allocation_size,
5919 uint32_t private_flags,
5920 struct security_descriptor *sd,
5921 struct ea_list *ea_list,
5923 files_struct **result,
5924 int *pinfo)
5926 struct smb2_lease none_lease;
5927 int info = FILE_WAS_OPENED;
5928 files_struct *base_fsp = NULL;
5929 files_struct *fsp = NULL;
5930 bool free_fsp_on_error = false;
5931 NTSTATUS status;
5932 int ret;
5933 struct smb_filename *parent_dir_fname = NULL;
5934 struct smb_filename *smb_fname_atname = NULL;
5936 DBG_DEBUG("access_mask = 0x%"PRIx32" "
5937 "file_attributes = 0x%"PRIx32" "
5938 "share_access = 0x%"PRIx32" "
5939 "create_disposition = 0x%"PRIx32" "
5940 "create_options = 0x%"PRIx32" "
5941 "oplock_request = 0x%"PRIx32" "
5942 "private_flags = 0x%"PRIx32" "
5943 "ea_list = %p, "
5944 "sd = %p, "
5945 "fname = %s\n",
5946 access_mask,
5947 file_attributes,
5948 share_access,
5949 create_disposition,
5950 create_options,
5951 oplock_request,
5952 private_flags,
5953 ea_list,
5955 smb_fname_str_dbg(smb_fname));
5957 if (create_options & FILE_OPEN_BY_FILE_ID) {
5958 status = NT_STATUS_NOT_SUPPORTED;
5959 goto fail;
5962 if (create_options & NTCREATEX_OPTIONS_INVALID_PARAM_MASK) {
5963 status = NT_STATUS_INVALID_PARAMETER;
5964 goto fail;
5967 if (!(create_options & FILE_OPEN_REPARSE_POINT) &&
5968 (smb_fname->fsp != NULL) && /* new files don't have an fsp */
5969 VALID_STAT(smb_fname->fsp->fsp_name->st))
5971 mode_t type = (smb_fname->fsp->fsp_name->st.st_ex_mode &
5972 S_IFMT);
5974 switch (type) {
5975 case S_IFREG:
5976 FALL_THROUGH;
5977 case S_IFDIR:
5978 break;
5979 case S_IFLNK:
5981 * We should never get this far with a symlink
5982 * "as such". Report as not existing.
5984 status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
5985 goto fail;
5986 default:
5987 status = NT_STATUS_IO_REPARSE_TAG_NOT_HANDLED;
5988 goto fail;
5992 if (req == NULL) {
5993 oplock_request |= INTERNAL_OPEN_ONLY;
5996 if (lease != NULL) {
5997 uint16_t epoch = lease->lease_epoch;
5998 uint16_t version = lease->lease_version;
6000 if (req == NULL) {
6001 DBG_WARNING("Got lease on internal open\n");
6002 status = NT_STATUS_INTERNAL_ERROR;
6003 goto fail;
6006 status = lease_match(conn,
6007 req,
6008 &lease->lease_key,
6009 conn->connectpath,
6010 smb_fname,
6011 &version,
6012 &epoch);
6013 if (NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) {
6014 /* Dynamic share file. No leases and update epoch... */
6015 none_lease = *lease;
6016 none_lease.lease_state = SMB2_LEASE_NONE;
6017 none_lease.lease_epoch = epoch;
6018 none_lease.lease_version = version;
6019 lease = &none_lease;
6020 } else if (!NT_STATUS_IS_OK(status)) {
6021 goto fail;
6025 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
6026 && (access_mask & DELETE_ACCESS)
6027 && !is_named_stream(smb_fname)) {
6029 * We can't open a file with DELETE access if any of the
6030 * streams is open without FILE_SHARE_DELETE
6032 status = open_streams_for_delete(conn, smb_fname);
6034 if (!NT_STATUS_IS_OK(status)) {
6035 goto fail;
6039 if (access_mask & SEC_FLAG_SYSTEM_SECURITY) {
6040 bool ok;
6042 ok = security_token_has_privilege(get_current_nttok(conn),
6043 SEC_PRIV_SECURITY);
6044 if (!ok) {
6045 DBG_DEBUG("open on %s failed - "
6046 "SEC_FLAG_SYSTEM_SECURITY denied.\n",
6047 smb_fname_str_dbg(smb_fname));
6048 status = NT_STATUS_PRIVILEGE_NOT_HELD;
6049 goto fail;
6052 if (conn->sconn->using_smb2 &&
6053 (access_mask == SEC_FLAG_SYSTEM_SECURITY))
6056 * No other bits set. Windows SMB2 refuses this.
6057 * See smbtorture3 SMB2-SACL test.
6059 * Note this is an SMB2-only behavior,
6060 * smbtorture3 SMB1-SYSTEM-SECURITY already tests
6061 * that SMB1 allows this.
6063 status = NT_STATUS_ACCESS_DENIED;
6064 goto fail;
6069 * Files or directories can't be opened DELETE_ON_CLOSE without
6070 * delete access.
6071 * BUG: https://bugzilla.samba.org/show_bug.cgi?id=13358
6073 if ((create_options & FILE_DELETE_ON_CLOSE) &&
6074 ((access_mask & DELETE_ACCESS) == 0)) {
6075 status = NT_STATUS_INVALID_PARAMETER;
6076 goto fail;
6079 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
6080 && is_named_stream(smb_fname))
6082 uint32_t base_create_disposition;
6083 struct smb_filename *smb_fname_base = NULL;
6084 uint32_t base_privflags;
6086 if (create_options & FILE_DIRECTORY_FILE) {
6087 DBG_DEBUG("Can't open a stream as directory\n");
6088 status = NT_STATUS_NOT_A_DIRECTORY;
6089 goto fail;
6092 switch (create_disposition) {
6093 case FILE_OPEN:
6094 base_create_disposition = FILE_OPEN;
6095 break;
6096 default:
6097 base_create_disposition = FILE_OPEN_IF;
6098 break;
6101 smb_fname_base = cp_smb_filename_nostream(
6102 talloc_tos(), smb_fname);
6104 if (smb_fname_base == NULL) {
6105 status = NT_STATUS_NO_MEMORY;
6106 goto fail;
6110 * We may be creating the basefile as part of creating the
6111 * stream, so it's legal if the basefile doesn't exist at this
6112 * point, the create_file_unixpath() below will create it. But
6113 * if the basefile exists we want a handle so we can fstat() it.
6116 ret = vfs_stat(conn, smb_fname_base);
6117 if (ret == -1 && errno != ENOENT) {
6118 status = map_nt_error_from_unix(errno);
6119 TALLOC_FREE(smb_fname_base);
6120 goto fail;
6122 if (ret == 0) {
6123 status = openat_pathref_fsp(conn->cwd_fsp,
6124 smb_fname_base);
6125 if (!NT_STATUS_IS_OK(status)) {
6126 DBG_ERR("open_smb_fname_fsp [%s] failed: %s\n",
6127 smb_fname_str_dbg(smb_fname_base),
6128 nt_errstr(status));
6129 TALLOC_FREE(smb_fname_base);
6130 goto fail;
6134 * https://bugzilla.samba.org/show_bug.cgi?id=10229
6135 * We need to check if the requested access mask
6136 * could be used to open the underlying file (if
6137 * it existed), as we're passing in zero for the
6138 * access mask to the base filename.
6140 status = check_base_file_access(smb_fname_base->fsp,
6141 access_mask);
6143 if (!NT_STATUS_IS_OK(status)) {
6144 DEBUG(10, ("Permission check "
6145 "for base %s failed: "
6146 "%s\n", smb_fname->base_name,
6147 nt_errstr(status)));
6148 TALLOC_FREE(smb_fname_base);
6149 goto fail;
6153 base_privflags = NTCREATEX_FLAG_STREAM_BASEOPEN;
6155 /* Open the base file. */
6156 status = create_file_unixpath(conn,
6157 NULL,
6158 dirfsp,
6159 smb_fname_base,
6161 FILE_SHARE_READ
6162 | FILE_SHARE_WRITE
6163 | FILE_SHARE_DELETE,
6164 base_create_disposition,
6168 NULL,
6170 base_privflags,
6171 NULL,
6172 NULL,
6173 &base_fsp,
6174 NULL);
6175 TALLOC_FREE(smb_fname_base);
6177 if (!NT_STATUS_IS_OK(status)) {
6178 DEBUG(10, ("create_file_unixpath for base %s failed: "
6179 "%s\n", smb_fname->base_name,
6180 nt_errstr(status)));
6181 goto fail;
6185 if (smb_fname->fsp != NULL) {
6187 fsp = smb_fname->fsp;
6190 * We're about to use smb_fname->fsp for the fresh open.
6192 * Every fsp passed in via smb_fname->fsp already
6193 * holds a fsp->fsp_name. If it is already this
6194 * fsp->fsp_name that we got passed in as our input
6195 * argument smb_fname, these two are assumed to have
6196 * the same lifetime: Every fsp hangs of "conn", and
6197 * fsp->fsp_name is its talloc child.
6200 if (smb_fname != smb_fname->fsp->fsp_name) {
6202 * "smb_fname" is temporary in this case, but
6203 * the destructor of smb_fname would also tear
6204 * down the fsp we're about to use. Unlink
6205 * them from each other.
6207 smb_fname_fsp_unlink(smb_fname);
6210 * "fsp" is ours now
6212 free_fsp_on_error = true;
6215 status = fsp_bind_smb(fsp, req);
6216 if (!NT_STATUS_IS_OK(status)) {
6217 goto fail;
6220 if (fsp_is_alternate_stream(fsp)) {
6221 struct files_struct *tmp_base_fsp = fsp->base_fsp;
6223 fsp_set_base_fsp(fsp, NULL);
6225 fd_close(tmp_base_fsp);
6226 file_free(NULL, tmp_base_fsp);
6228 } else {
6230 * No fsp passed in that we can use, create one
6232 status = file_new(req, conn, &fsp);
6233 if(!NT_STATUS_IS_OK(status)) {
6234 goto fail;
6236 free_fsp_on_error = true;
6238 status = fsp_set_smb_fname(fsp, smb_fname);
6239 if (!NT_STATUS_IS_OK(status)) {
6240 goto fail;
6244 SMB_ASSERT(fsp->fsp_name->fsp != NULL);
6245 SMB_ASSERT(fsp->fsp_name->fsp == fsp);
6247 if (base_fsp) {
6249 * We're opening the stream element of a
6250 * base_fsp we already opened. Set up the
6251 * base_fsp pointer.
6253 fsp_set_base_fsp(fsp, base_fsp);
6256 if (dirfsp != NULL) {
6257 status = SMB_VFS_PARENT_PATHNAME(
6258 conn,
6259 talloc_tos(),
6260 smb_fname,
6261 &parent_dir_fname,
6262 &smb_fname_atname);
6263 if (!NT_STATUS_IS_OK(status)) {
6264 goto fail;
6266 } else {
6268 * Get a pathref on the parent. We can re-use this for
6269 * multiple calls to check parent ACLs etc. to avoid
6270 * pathname calls.
6272 status = parent_pathref(talloc_tos(),
6273 conn->cwd_fsp,
6274 smb_fname,
6275 &parent_dir_fname,
6276 &smb_fname_atname);
6277 if (!NT_STATUS_IS_OK(status)) {
6278 goto fail;
6281 dirfsp = parent_dir_fname->fsp;
6282 status = fsp_set_smb_fname(dirfsp, parent_dir_fname);
6283 if (!NT_STATUS_IS_OK(status)) {
6284 goto fail;
6289 * If it's a request for a directory open, deal with it separately.
6292 if (create_options & FILE_DIRECTORY_FILE) {
6294 if (create_options & FILE_NON_DIRECTORY_FILE) {
6295 status = NT_STATUS_INVALID_PARAMETER;
6296 goto fail;
6299 /* Can't open a temp directory. IFS kit test. */
6300 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
6301 (file_attributes & FILE_ATTRIBUTE_TEMPORARY)) {
6302 status = NT_STATUS_INVALID_PARAMETER;
6303 goto fail;
6307 * We will get a create directory here if the Win32
6308 * app specified a security descriptor in the
6309 * CreateDirectory() call.
6312 oplock_request = 0;
6313 status = open_directory(conn,
6314 req,
6315 access_mask,
6316 share_access,
6317 create_disposition,
6318 create_options,
6319 file_attributes,
6320 dirfsp->fsp_name,
6321 smb_fname_atname,
6322 &info,
6323 fsp);
6324 } else {
6327 * Ordinary file case.
6330 if (allocation_size) {
6331 fsp->initial_allocation_size = smb_roundup(fsp->conn,
6332 allocation_size);
6335 status = open_file_ntcreate(conn,
6336 req,
6337 access_mask,
6338 share_access,
6339 create_disposition,
6340 create_options,
6341 file_attributes,
6342 oplock_request,
6343 lease,
6344 private_flags,
6345 dirfsp->fsp_name,
6346 smb_fname_atname,
6347 &info,
6348 fsp);
6349 if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
6351 /* A stream open never opens a directory */
6353 if (base_fsp) {
6354 status = NT_STATUS_FILE_IS_A_DIRECTORY;
6355 goto fail;
6359 * Fail the open if it was explicitly a non-directory
6360 * file.
6363 if (create_options & FILE_NON_DIRECTORY_FILE) {
6364 status = NT_STATUS_FILE_IS_A_DIRECTORY;
6365 goto fail;
6368 oplock_request = 0;
6369 status = open_directory(conn,
6370 req,
6371 access_mask,
6372 share_access,
6373 create_disposition,
6374 create_options,
6375 file_attributes,
6376 dirfsp->fsp_name,
6377 smb_fname_atname,
6378 &info,
6379 fsp);
6383 if (!NT_STATUS_IS_OK(status)) {
6384 goto fail;
6387 fsp->fsp_flags.is_fsa = true;
6389 if ((ea_list != NULL) &&
6390 ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN))) {
6391 status = set_ea(conn, fsp, ea_list);
6392 if (!NT_STATUS_IS_OK(status)) {
6393 goto fail;
6397 if (!fsp->fsp_flags.is_directory &&
6398 S_ISDIR(fsp->fsp_name->st.st_ex_mode))
6400 status = NT_STATUS_ACCESS_DENIED;
6401 goto fail;
6404 /* Save the requested allocation size. */
6405 if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
6406 if ((allocation_size > (uint64_t)fsp->fsp_name->st.st_ex_size)
6407 && !(fsp->fsp_flags.is_directory))
6409 fsp->initial_allocation_size = smb_roundup(
6410 fsp->conn, allocation_size);
6411 if (vfs_allocate_file_space(
6412 fsp, fsp->initial_allocation_size) == -1) {
6413 status = NT_STATUS_DISK_FULL;
6414 goto fail;
6416 } else {
6417 fsp->initial_allocation_size = smb_roundup(
6418 fsp->conn, (uint64_t)fsp->fsp_name->st.st_ex_size);
6420 } else {
6421 fsp->initial_allocation_size = 0;
6424 if ((info == FILE_WAS_CREATED) &&
6425 lp_nt_acl_support(SNUM(conn)) &&
6426 !fsp_is_alternate_stream(fsp)) {
6427 if (sd != NULL) {
6429 * According to the MS documentation, the only time the security
6430 * descriptor is applied to the opened file is iff we *created* the
6431 * file; an existing file stays the same.
6433 * Also, it seems (from observation) that you can open the file with
6434 * any access mask but you can still write the sd. We need to override
6435 * the granted access before we call set_sd
6436 * Patch for bug #2242 from Tom Lackemann <cessnatomny@yahoo.com>.
6439 uint32_t sec_info_sent;
6440 uint32_t saved_access_mask = fsp->access_mask;
6442 sec_info_sent = get_sec_info(sd);
6444 fsp->access_mask = FILE_GENERIC_ALL;
6446 if (sec_info_sent & (SECINFO_OWNER|
6447 SECINFO_GROUP|
6448 SECINFO_DACL|
6449 SECINFO_SACL)) {
6450 status = set_sd(fsp, sd, sec_info_sent);
6453 fsp->access_mask = saved_access_mask;
6455 if (!NT_STATUS_IS_OK(status)) {
6456 goto fail;
6458 } else if (lp_inherit_acls(SNUM(conn))) {
6459 /* Inherit from parent. Errors here are not fatal. */
6460 status = inherit_new_acl(dirfsp, fsp);
6461 if (!NT_STATUS_IS_OK(status)) {
6462 DEBUG(10,("inherit_new_acl: failed for %s with %s\n",
6463 fsp_str_dbg(fsp),
6464 nt_errstr(status) ));
6469 if ((conn->fs_capabilities & FILE_FILE_COMPRESSION)
6470 && (create_options & FILE_NO_COMPRESSION)
6471 && (info == FILE_WAS_CREATED)) {
6472 status = SMB_VFS_SET_COMPRESSION(conn, fsp, fsp,
6473 COMPRESSION_FORMAT_NONE);
6474 if (!NT_STATUS_IS_OK(status)) {
6475 DEBUG(1, ("failed to disable compression: %s\n",
6476 nt_errstr(status)));
6480 DEBUG(10, ("create_file_unixpath: info=%d\n", info));
6482 *result = fsp;
6483 if (pinfo != NULL) {
6484 *pinfo = info;
6487 smb_fname->st = fsp->fsp_name->st;
6489 TALLOC_FREE(parent_dir_fname);
6491 return NT_STATUS_OK;
6493 fail:
6494 DEBUG(10, ("create_file_unixpath: %s\n", nt_errstr(status)));
6496 if (fsp != NULL) {
6498 * The close_file below will close
6499 * fsp->base_fsp.
6501 base_fsp = NULL;
6502 close_file_smb(req, fsp, ERROR_CLOSE);
6503 if (free_fsp_on_error) {
6504 file_free(req, fsp);
6505 fsp = NULL;
6508 if (base_fsp != NULL) {
6509 close_file_free(req, &base_fsp, ERROR_CLOSE);
6512 TALLOC_FREE(parent_dir_fname);
6514 return status;
6517 NTSTATUS create_file_default(connection_struct *conn,
6518 struct smb_request *req,
6519 struct files_struct *dirfsp,
6520 struct smb_filename *smb_fname,
6521 uint32_t access_mask,
6522 uint32_t share_access,
6523 uint32_t create_disposition,
6524 uint32_t create_options,
6525 uint32_t file_attributes,
6526 uint32_t oplock_request,
6527 const struct smb2_lease *lease,
6528 uint64_t allocation_size,
6529 uint32_t private_flags,
6530 struct security_descriptor *sd,
6531 struct ea_list *ea_list,
6532 files_struct **result,
6533 int *pinfo,
6534 const struct smb2_create_blobs *in_context_blobs,
6535 struct smb2_create_blobs *out_context_blobs)
6537 int info = FILE_WAS_OPENED;
6538 files_struct *fsp = NULL;
6539 NTSTATUS status;
6540 bool stream_name = false;
6541 struct smb2_create_blob *posx = NULL;
6543 DBG_DEBUG("access_mask = 0x%" PRIu32
6544 " file_attributes = 0x%" PRIu32
6545 " share_access = 0x%" PRIu32
6546 " create_disposition = 0x%" PRIu32
6547 " create_options = 0x%" PRIu32
6548 " oplock_request = 0x%" PRIu32
6549 " private_flags = 0x%" PRIu32
6550 " ea_list = %p, sd = %p, fname = %s\n",
6551 access_mask,
6552 file_attributes,
6553 share_access,
6554 create_disposition,
6555 create_options,
6556 oplock_request,
6557 private_flags,
6558 ea_list,
6560 smb_fname_str_dbg(smb_fname));
6562 if (req != NULL) {
6564 * Remember the absolute time of the original request
6565 * with this mid. We'll use it later to see if this
6566 * has timed out.
6568 get_deferred_open_message_state(req, &req->request_time, NULL);
6572 * Check to see if this is a mac fork of some kind.
6575 stream_name = is_ntfs_stream_smb_fname(smb_fname);
6576 if (stream_name) {
6577 enum FAKE_FILE_TYPE fake_file_type;
6579 fake_file_type = is_fake_file(smb_fname);
6581 if (req != NULL && fake_file_type != FAKE_FILE_TYPE_NONE) {
6584 * Here we go! support for changing the disk quotas
6585 * --metze
6587 * We need to fake up to open this MAGIC QUOTA file
6588 * and return a valid FID.
6590 * w2k close this file directly after opening xp
6591 * also tries a QUERY_FILE_INFO on the file and then
6592 * close it
6594 status = open_fake_file(req, conn, req->vuid,
6595 fake_file_type, smb_fname,
6596 access_mask, &fsp);
6597 if (!NT_STATUS_IS_OK(status)) {
6598 goto fail;
6601 ZERO_STRUCT(smb_fname->st);
6602 goto done;
6605 if (!(conn->fs_capabilities & FILE_NAMED_STREAMS)) {
6606 status = NT_STATUS_OBJECT_NAME_INVALID;
6607 goto fail;
6611 if (is_ntfs_default_stream_smb_fname(smb_fname)) {
6612 int ret;
6613 /* We have to handle this error here. */
6614 if (create_options & FILE_DIRECTORY_FILE) {
6615 status = NT_STATUS_NOT_A_DIRECTORY;
6616 goto fail;
6618 ret = vfs_stat(conn, smb_fname);
6619 if (ret == 0 && VALID_STAT_OF_DIR(smb_fname->st)) {
6620 status = NT_STATUS_FILE_IS_A_DIRECTORY;
6621 goto fail;
6625 posx = smb2_create_blob_find(
6626 in_context_blobs, SMB2_CREATE_TAG_POSIX);
6627 if (posx != NULL) {
6628 uint32_t wire_mode_bits = 0;
6629 mode_t mode_bits = 0;
6630 SMB_STRUCT_STAT sbuf = { 0 };
6631 enum perm_type ptype =
6632 (create_options & FILE_DIRECTORY_FILE) ?
6633 PERM_NEW_DIR : PERM_NEW_FILE;
6635 if (posx->data.length != 4) {
6636 status = NT_STATUS_INVALID_PARAMETER;
6637 goto fail;
6640 wire_mode_bits = IVAL(posx->data.data, 0);
6641 status = unix_perms_from_wire(
6642 conn, &sbuf, wire_mode_bits, ptype, &mode_bits);
6643 if (!NT_STATUS_IS_OK(status)) {
6644 goto fail;
6647 * Remove type info from mode, leaving only the
6648 * permissions and setuid/gid bits.
6650 mode_bits &= ~S_IFMT;
6652 file_attributes = (FILE_FLAG_POSIX_SEMANTICS | mode_bits);
6655 status = create_file_unixpath(conn,
6656 req,
6657 dirfsp,
6658 smb_fname,
6659 access_mask,
6660 share_access,
6661 create_disposition,
6662 create_options,
6663 file_attributes,
6664 oplock_request,
6665 lease,
6666 allocation_size,
6667 private_flags,
6669 ea_list,
6670 &fsp,
6671 &info);
6672 if (!NT_STATUS_IS_OK(status)) {
6673 goto fail;
6676 done:
6677 DEBUG(10, ("create_file: info=%d\n", info));
6679 *result = fsp;
6680 if (pinfo != NULL) {
6681 *pinfo = info;
6683 return NT_STATUS_OK;
6685 fail:
6686 DEBUG(10, ("create_file: %s\n", nt_errstr(status)));
6688 if (fsp != NULL) {
6689 close_file_free(req, &fsp, ERROR_CLOSE);
6691 return status;