smbd: Simplify reopen_from_fsp()
[Samba.git] / source3 / smbd / open.c
blob9e5bf2f67311b9e1d73717d72ac89066e62aa023
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 int new_fd;
1234 SMB_ASSERT(fsp->fsp_flags.is_pathref);
1236 fsp->fsp_flags.is_pathref = false;
1238 new_fd = SMB_VFS_OPENAT(fsp->conn,
1239 fsp->conn->cwd_fsp,
1240 &proc_fname,
1241 fsp,
1242 how);
1243 if (new_fd == -1) {
1244 status = map_nt_error_from_unix(errno);
1245 fd_close(fsp);
1246 return status;
1249 status = fd_close(fsp);
1250 if (!NT_STATUS_IS_OK(status)) {
1251 return status;
1254 fsp_set_fd(fsp, new_fd);
1255 return NT_STATUS_OK;
1259 * Close the existing pathref fd and set the fsp flag
1260 * is_pathref to false so we get a "normal" fd this time.
1262 status = fd_close(fsp);
1263 if (!NT_STATUS_IS_OK(status)) {
1264 return status;
1267 fsp->fsp_flags.is_pathref = false;
1269 status = fd_open_atomic(dirfsp, smb_fname, fsp, how, p_file_created);
1270 return status;
1273 /****************************************************************************
1274 Open a file.
1275 ****************************************************************************/
1277 static NTSTATUS open_file(
1278 struct smb_request *req,
1279 struct files_struct *dirfsp,
1280 struct smb_filename *smb_fname_atname,
1281 files_struct *fsp,
1282 const struct vfs_open_how *_how,
1283 uint32_t access_mask, /* client requested access mask. */
1284 uint32_t open_access_mask, /* what we're actually using in the open. */
1285 uint32_t private_flags,
1286 bool *p_file_created)
1288 connection_struct *conn = fsp->conn;
1289 struct smb_filename *smb_fname = fsp->fsp_name;
1290 struct vfs_open_how how = *_how;
1291 NTSTATUS status = NT_STATUS_OK;
1292 bool file_existed = VALID_STAT(fsp->fsp_name->st);
1293 const uint32_t need_fd_mask =
1294 FILE_READ_DATA |
1295 FILE_WRITE_DATA |
1296 FILE_APPEND_DATA |
1297 FILE_EXECUTE |
1298 SEC_FLAG_SYSTEM_SECURITY;
1299 bool creating = !file_existed && (how.flags & O_CREAT);
1300 bool open_fd = false;
1301 bool posix_open = (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN);
1304 * Catch early an attempt to open an existing
1305 * directory as a file.
1307 if (file_existed && S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
1308 return NT_STATUS_FILE_IS_A_DIRECTORY;
1312 * This little piece of insanity is inspired by the
1313 * fact that an NT client can open a file for O_RDONLY,
1314 * but set the create disposition to FILE_EXISTS_TRUNCATE.
1315 * If the client *can* write to the file, then it expects to
1316 * truncate the file, even though it is opening for readonly.
1317 * Quicken uses this stupid trick in backup file creation...
1318 * Thanks *greatly* to "David W. Chapman Jr." <dwcjr@inethouston.net>
1319 * for helping track this one down. It didn't bite us in 2.0.x
1320 * as we always opened files read-write in that release. JRA.
1323 if (((how.flags & O_ACCMODE) == O_RDONLY) && (how.flags & O_TRUNC)) {
1324 DBG_DEBUG("truncate requested on read-only open for file %s\n",
1325 smb_fname_str_dbg(smb_fname));
1326 how.flags = (how.flags & ~O_ACCMODE) | O_RDWR;
1329 /* Check permissions */
1332 * This code was changed after seeing a client open request
1333 * containing the open mode of (DENY_WRITE/read-only) with
1334 * the 'create if not exist' bit set. The previous code
1335 * would fail to open the file read only on a read-only share
1336 * as it was checking the flags parameter directly against O_RDONLY,
1337 * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
1338 * JRA.
1341 if (!CAN_WRITE(conn)) {
1342 /* It's a read-only share - fail if we wanted to write. */
1343 if ((how.flags & O_ACCMODE) != O_RDONLY ||
1344 (how.flags & O_TRUNC) || (how.flags & O_APPEND)) {
1345 DEBUG(3,("Permission denied opening %s\n",
1346 smb_fname_str_dbg(smb_fname)));
1347 return NT_STATUS_ACCESS_DENIED;
1350 * We don't want to write - but we must make sure that
1351 * O_CREAT doesn't create the file if we have write
1352 * access into the directory.
1354 how.flags &= ~(O_CREAT | O_EXCL);
1357 if ((open_access_mask & need_fd_mask) || creating ||
1358 (how.flags & O_TRUNC)) {
1359 open_fd = true;
1362 if (open_fd) {
1363 int ret;
1365 #if defined(O_NONBLOCK) && defined(S_ISFIFO)
1367 * We would block on opening a FIFO with no one else on the
1368 * other end. Do what we used to do and add O_NONBLOCK to the
1369 * open flags. JRA.
1372 if (file_existed && S_ISFIFO(smb_fname->st.st_ex_mode)) {
1373 how.flags |= O_NONBLOCK;
1375 #endif
1377 if (!posix_open) {
1378 const char *wild = smb_fname->base_name;
1380 * Don't open files with Microsoft wildcard characters.
1382 if (fsp_is_alternate_stream(fsp)) {
1384 * wildcard characters are allowed in stream
1385 * names only test the basefilename
1387 wild = fsp->base_fsp->fsp_name->base_name;
1390 if (ms_has_wild(wild)) {
1391 return NT_STATUS_OBJECT_NAME_INVALID;
1395 /* Can we access this file ? */
1396 if (!fsp_is_alternate_stream(fsp)) {
1397 /* Only do this check on non-stream open. */
1398 if (file_existed) {
1399 status = smbd_check_access_rights_fsp(
1400 dirfsp,
1401 fsp,
1402 false,
1403 open_access_mask);
1405 if (!NT_STATUS_IS_OK(status)) {
1406 DBG_DEBUG("smbd_check_access_rights_fsp"
1407 " on file %s returned %s\n",
1408 fsp_str_dbg(fsp),
1409 nt_errstr(status));
1412 if (!NT_STATUS_IS_OK(status) &&
1413 !NT_STATUS_EQUAL(status,
1414 NT_STATUS_OBJECT_NAME_NOT_FOUND))
1416 return status;
1419 if (NT_STATUS_EQUAL(status,
1420 NT_STATUS_OBJECT_NAME_NOT_FOUND))
1422 DEBUG(10, ("open_file: "
1423 "file %s vanished since we "
1424 "checked for existence.\n",
1425 smb_fname_str_dbg(smb_fname)));
1426 file_existed = false;
1427 SET_STAT_INVALID(fsp->fsp_name->st);
1431 if (!file_existed) {
1432 if (!(how.flags & O_CREAT)) {
1433 /* File didn't exist and no O_CREAT. */
1434 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1437 status = check_parent_access_fsp(
1438 dirfsp,
1439 SEC_DIR_ADD_FILE);
1440 if (!NT_STATUS_IS_OK(status)) {
1441 DBG_DEBUG("check_parent_access_fsp on "
1442 "directory %s for file %s "
1443 "returned %s\n",
1444 smb_fname_str_dbg(
1445 dirfsp->fsp_name),
1446 smb_fname_str_dbg(smb_fname),
1447 nt_errstr(status));
1448 return status;
1454 * Actually do the open - if O_TRUNC is needed handle it
1455 * below under the share mode lock.
1457 how.flags &= ~O_TRUNC;
1458 status = reopen_from_fsp(dirfsp,
1459 smb_fname_atname,
1460 fsp,
1461 &how,
1462 p_file_created);
1463 if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) {
1465 * Non-O_PATH reopen that hit a race
1466 * condition: Someone has put a symlink where
1467 * we used to have a file. Can't happen with
1468 * O_PATH and reopening from /proc/self/fd/ or
1469 * equivalent.
1471 status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
1473 if (!NT_STATUS_IS_OK(status)) {
1474 DBG_NOTICE("Error opening file %s (%s) (in_flags=%d) "
1475 "(flags=%d)\n",
1476 smb_fname_str_dbg(smb_fname),
1477 nt_errstr(status),
1478 _how->flags,
1479 how.flags);
1480 return status;
1483 if (how.flags & O_NONBLOCK) {
1485 * GPFS can return ETIMEDOUT for pread on
1486 * nonblocking file descriptors when files
1487 * migrated to tape need to be recalled. I
1488 * could imagine this happens elsewhere
1489 * too. With blocking file descriptors this
1490 * does not happen.
1492 ret = vfs_set_blocking(fsp, true);
1493 if (ret == -1) {
1494 status = map_nt_error_from_unix(errno);
1495 DBG_WARNING("Could not set fd to blocking: "
1496 "%s\n", strerror(errno));
1497 fd_close(fsp);
1498 return status;
1502 if (*p_file_created) {
1503 /* We created this file. */
1505 bool need_re_stat = false;
1506 /* Do all inheritance work after we've
1507 done a successful fstat call and filled
1508 in the stat struct in fsp->fsp_name. */
1510 /* Inherit the ACL if required */
1511 if (lp_inherit_permissions(SNUM(conn))) {
1512 inherit_access_posix_acl(conn,
1513 dirfsp,
1514 smb_fname,
1515 how.mode);
1516 need_re_stat = true;
1519 /* Change the owner if required. */
1520 if (lp_inherit_owner(SNUM(conn)) != INHERIT_OWNER_NO) {
1521 change_file_owner_to_parent_fsp(dirfsp, fsp);
1522 need_re_stat = true;
1525 if (need_re_stat) {
1526 status = vfs_stat_fsp(fsp);
1528 * If we have an fd, this stat should succeed.
1530 if (!NT_STATUS_IS_OK(status)) {
1531 DBG_ERR("Error doing fstat on open "
1532 "file %s (%s)\n",
1533 smb_fname_str_dbg(smb_fname),
1534 nt_errstr(status));
1535 fd_close(fsp);
1536 return status;
1540 notify_fname(conn, NOTIFY_ACTION_ADDED,
1541 FILE_NOTIFY_CHANGE_FILE_NAME,
1542 smb_fname->base_name);
1544 } else {
1545 if (!file_existed) {
1546 /* File must exist for a stat open. */
1547 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1550 if (S_ISLNK(smb_fname->st.st_ex_mode) &&
1551 !posix_open)
1554 * Don't allow stat opens on symlinks directly unless
1555 * it's a POSIX open. Match the return code from
1556 * openat_pathref_fsp().
1558 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1561 if (!fsp->fsp_flags.is_pathref) {
1563 * There is only one legit case where end up here:
1564 * openat_pathref_fsp() failed to open a symlink, so the
1565 * fsp was created by fsp_new() which doesn't set
1566 * is_pathref. Other than that, we should always have a
1567 * pathref fsp at this point. The subsequent checks
1568 * assert this.
1570 if (!(smb_fname->flags & SMB_FILENAME_POSIX_PATH)) {
1571 DBG_ERR("[%s] is not a POSIX pathname\n",
1572 smb_fname_str_dbg(smb_fname));
1573 return NT_STATUS_INTERNAL_ERROR;
1575 if (!S_ISLNK(smb_fname->st.st_ex_mode)) {
1576 DBG_ERR("[%s] is not a symlink\n",
1577 smb_fname_str_dbg(smb_fname));
1578 return NT_STATUS_INTERNAL_ERROR;
1580 if (fsp_get_pathref_fd(fsp) != -1) {
1581 DBG_ERR("fd for [%s] is not -1: fd [%d]\n",
1582 smb_fname_str_dbg(smb_fname),
1583 fsp_get_pathref_fd(fsp));
1584 return NT_STATUS_INTERNAL_ERROR;
1589 * Access to streams is checked by checking the basefile and
1590 * that has already been checked by check_base_file_access()
1591 * in create_file_unixpath().
1593 if (!fsp_is_alternate_stream(fsp)) {
1594 status = smbd_check_access_rights_fsp(dirfsp,
1595 fsp,
1596 false,
1597 open_access_mask);
1599 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) &&
1600 posix_open &&
1601 S_ISLNK(smb_fname->st.st_ex_mode)) {
1602 /* This is a POSIX stat open for delete
1603 * or rename on a symlink that points
1604 * nowhere. Allow. */
1605 DEBUG(10,("open_file: allowing POSIX "
1606 "open on bad symlink %s\n",
1607 smb_fname_str_dbg(smb_fname)));
1608 status = NT_STATUS_OK;
1611 if (!NT_STATUS_IS_OK(status)) {
1612 DBG_DEBUG("smbd_check_access_rights_fsp on file "
1613 "%s returned %s\n",
1614 fsp_str_dbg(fsp),
1615 nt_errstr(status));
1616 return status;
1621 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
1622 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
1623 fsp->file_pid = req ? req->smbpid : 0;
1624 fsp->fsp_flags.can_lock = true;
1625 fsp->fsp_flags.can_read = ((access_mask & FILE_READ_DATA) != 0);
1626 fsp->fsp_flags.can_write =
1627 CAN_WRITE(conn) &&
1628 ((access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) != 0);
1629 fsp->print_file = NULL;
1630 fsp->fsp_flags.modified = false;
1631 fsp->sent_oplock_break = NO_BREAK_SENT;
1632 fsp->fsp_flags.is_directory = false;
1633 if (is_in_path(smb_fname->base_name,
1634 conn->aio_write_behind_list,
1635 posix_open ? true : conn->case_sensitive)) {
1636 fsp->fsp_flags.aio_write_behind = true;
1639 DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
1640 conn->session_info->unix_info->unix_name,
1641 smb_fname_str_dbg(smb_fname),
1642 BOOLSTR(fsp->fsp_flags.can_read),
1643 BOOLSTR(fsp->fsp_flags.can_write),
1644 conn->num_files_open));
1646 return NT_STATUS_OK;
1649 static bool mask_conflict(
1650 uint32_t new_access,
1651 uint32_t existing_access,
1652 uint32_t access_mask,
1653 uint32_t new_sharemode,
1654 uint32_t existing_sharemode,
1655 uint32_t sharemode_mask)
1657 bool want_access = (new_access & access_mask);
1658 bool allow_existing = (existing_sharemode & sharemode_mask);
1659 bool have_access = (existing_access & access_mask);
1660 bool allow_new = (new_sharemode & sharemode_mask);
1662 if (want_access && !allow_existing) {
1663 DBG_DEBUG("Access request 0x%"PRIx32"/0x%"PRIx32" conflicts "
1664 "with existing sharemode 0x%"PRIx32"/0x%"PRIx32"\n",
1665 new_access,
1666 access_mask,
1667 existing_sharemode,
1668 sharemode_mask);
1669 return true;
1671 if (have_access && !allow_new) {
1672 DBG_DEBUG("Sharemode request 0x%"PRIx32"/0x%"PRIx32" conflicts "
1673 "with existing access 0x%"PRIx32"/0x%"PRIx32"\n",
1674 new_sharemode,
1675 sharemode_mask,
1676 existing_access,
1677 access_mask);
1678 return true;
1680 return false;
1683 /****************************************************************************
1684 Check if we can open a file with a share mode.
1685 Returns True if conflict, False if not.
1686 ****************************************************************************/
1688 static const uint32_t conflicting_access =
1689 FILE_WRITE_DATA|
1690 FILE_APPEND_DATA|
1691 FILE_READ_DATA|
1692 FILE_EXECUTE|
1693 DELETE_ACCESS;
1695 static bool share_conflict(uint32_t e_access_mask,
1696 uint32_t e_share_access,
1697 uint32_t access_mask,
1698 uint32_t share_access)
1700 bool conflict;
1702 DBG_DEBUG("existing access_mask = 0x%"PRIx32", "
1703 "existing share access = 0x%"PRIx32", "
1704 "access_mask = 0x%"PRIx32", "
1705 "share_access = 0x%"PRIx32"\n",
1706 e_access_mask,
1707 e_share_access,
1708 access_mask,
1709 share_access);
1711 if ((e_access_mask & conflicting_access) == 0) {
1712 DBG_DEBUG("No conflict due to "
1713 "existing access_mask = 0x%"PRIx32"\n",
1714 e_access_mask);
1715 return false;
1717 if ((access_mask & conflicting_access) == 0) {
1718 DBG_DEBUG("No conflict due to access_mask = 0x%"PRIx32"\n",
1719 access_mask);
1720 return false;
1723 conflict = mask_conflict(
1724 access_mask, e_access_mask, FILE_WRITE_DATA | FILE_APPEND_DATA,
1725 share_access, e_share_access, FILE_SHARE_WRITE);
1726 conflict |= mask_conflict(
1727 access_mask, e_access_mask, FILE_READ_DATA | FILE_EXECUTE,
1728 share_access, e_share_access, FILE_SHARE_READ);
1729 conflict |= mask_conflict(
1730 access_mask, e_access_mask, DELETE_ACCESS,
1731 share_access, e_share_access, FILE_SHARE_DELETE);
1733 DBG_DEBUG("conflict=%s\n", conflict ? "true" : "false");
1734 return conflict;
1737 #if defined(DEVELOPER)
1739 struct validate_my_share_entries_state {
1740 struct smbd_server_connection *sconn;
1741 struct file_id fid;
1742 struct server_id self;
1745 static bool validate_my_share_entries_fn(
1746 struct share_mode_entry *e,
1747 bool *modified,
1748 void *private_data)
1750 struct validate_my_share_entries_state *state = private_data;
1751 files_struct *fsp;
1753 if (!server_id_equal(&state->self, &e->pid)) {
1754 return false;
1757 if (e->op_mid == 0) {
1758 /* INTERNAL_OPEN_ONLY */
1759 return false;
1762 fsp = file_find_dif(state->sconn, state->fid, e->share_file_id);
1763 if (!fsp) {
1764 DBG_ERR("PANIC : %s\n",
1765 share_mode_str(talloc_tos(), 0, &state->fid, e));
1766 smb_panic("validate_my_share_entries: Cannot match a "
1767 "share entry with an open file\n");
1770 if (((uint16_t)fsp->oplock_type) != e->op_type) {
1771 goto panic;
1774 return false;
1776 panic:
1778 char *str;
1779 DBG_ERR("validate_my_share_entries: PANIC : %s\n",
1780 share_mode_str(talloc_tos(), 0, &state->fid, e));
1781 str = talloc_asprintf(talloc_tos(),
1782 "validate_my_share_entries: "
1783 "file %s, oplock_type = 0x%x, op_type = 0x%x\n",
1784 fsp->fsp_name->base_name,
1785 (unsigned int)fsp->oplock_type,
1786 (unsigned int)e->op_type);
1787 smb_panic(str);
1790 return false;
1792 #endif
1795 * Allowed access mask for stat opens relevant to oplocks
1797 bool is_oplock_stat_open(uint32_t access_mask)
1799 const uint32_t stat_open_bits =
1800 (SYNCHRONIZE_ACCESS|
1801 FILE_READ_ATTRIBUTES|
1802 FILE_WRITE_ATTRIBUTES);
1804 return (((access_mask & stat_open_bits) != 0) &&
1805 ((access_mask & ~stat_open_bits) == 0));
1809 * Allowed access mask for stat opens relevant to leases
1811 bool is_lease_stat_open(uint32_t access_mask)
1813 const uint32_t stat_open_bits =
1814 (SYNCHRONIZE_ACCESS|
1815 FILE_READ_ATTRIBUTES|
1816 FILE_WRITE_ATTRIBUTES|
1817 READ_CONTROL_ACCESS);
1819 return (((access_mask & stat_open_bits) != 0) &&
1820 ((access_mask & ~stat_open_bits) == 0));
1823 struct has_delete_on_close_state {
1824 bool ret;
1827 static bool has_delete_on_close_fn(
1828 struct share_mode_entry *e,
1829 bool *modified,
1830 void *private_data)
1832 struct has_delete_on_close_state *state = private_data;
1833 state->ret = !share_entry_stale_pid(e);
1834 return state->ret;
1837 static bool has_delete_on_close(struct share_mode_lock *lck,
1838 uint32_t name_hash)
1840 struct has_delete_on_close_state state = { .ret = false };
1841 bool ok;
1843 if (!is_delete_on_close_set(lck, name_hash)) {
1844 return false;
1847 ok= share_mode_forall_entries(lck, has_delete_on_close_fn, &state);
1848 if (!ok) {
1849 DBG_DEBUG("share_mode_forall_entries failed\n");
1850 return false;
1852 return state.ret;
1855 static void share_mode_flags_restrict(
1856 struct share_mode_lock *lck,
1857 uint32_t access_mask,
1858 uint32_t share_mode,
1859 uint32_t lease_type)
1861 uint32_t existing_access_mask, existing_share_mode;
1862 uint32_t existing_lease_type;
1864 share_mode_flags_get(
1865 lck,
1866 &existing_access_mask,
1867 &existing_share_mode,
1868 &existing_lease_type);
1870 existing_access_mask |= access_mask;
1871 if (access_mask & conflicting_access) {
1872 existing_share_mode &= share_mode;
1874 existing_lease_type |= lease_type;
1876 share_mode_flags_set(
1877 lck,
1878 existing_access_mask,
1879 existing_share_mode,
1880 existing_lease_type,
1881 NULL);
1884 /****************************************************************************
1885 Deal with share modes
1886 Invariant: Share mode must be locked on entry and exit.
1887 Returns -1 on error, or number of share modes on success (may be zero).
1888 ****************************************************************************/
1890 struct open_mode_check_state {
1891 struct file_id fid;
1892 uint32_t access_mask;
1893 uint32_t share_access;
1894 uint32_t lease_type;
1897 static bool open_mode_check_fn(
1898 struct share_mode_entry *e,
1899 bool *modified,
1900 void *private_data)
1902 struct open_mode_check_state *state = private_data;
1903 bool disconnected, stale;
1904 uint32_t access_mask, share_access, lease_type;
1906 disconnected = server_id_is_disconnected(&e->pid);
1907 if (disconnected) {
1908 return false;
1911 access_mask = state->access_mask | e->access_mask;
1912 share_access = state->share_access;
1913 if (e->access_mask & conflicting_access) {
1914 share_access &= e->share_access;
1916 lease_type = state->lease_type | get_lease_type(e, state->fid);
1918 if ((access_mask == state->access_mask) &&
1919 (share_access == state->share_access) &&
1920 (lease_type == state->lease_type)) {
1921 return false;
1924 stale = share_entry_stale_pid(e);
1925 if (stale) {
1926 return false;
1929 state->access_mask = access_mask;
1930 state->share_access = share_access;
1931 state->lease_type = lease_type;
1933 return false;
1936 static NTSTATUS open_mode_check(connection_struct *conn,
1937 struct file_id fid,
1938 struct share_mode_lock *lck,
1939 uint32_t access_mask,
1940 uint32_t share_access)
1942 struct open_mode_check_state state;
1943 bool ok, conflict;
1944 bool modified = false;
1946 if (is_oplock_stat_open(access_mask)) {
1947 /* Stat open that doesn't trigger oplock breaks or share mode
1948 * checks... ! JRA. */
1949 return NT_STATUS_OK;
1953 * Check if the share modes will give us access.
1956 #if defined(DEVELOPER)
1958 struct validate_my_share_entries_state validate_state = {
1959 .sconn = conn->sconn,
1960 .fid = fid,
1961 .self = messaging_server_id(conn->sconn->msg_ctx),
1963 ok = share_mode_forall_entries(
1964 lck, validate_my_share_entries_fn, &validate_state);
1965 SMB_ASSERT(ok);
1967 #endif
1969 share_mode_flags_get(
1970 lck, &state.access_mask, &state.share_access, NULL);
1972 conflict = share_conflict(
1973 state.access_mask,
1974 state.share_access,
1975 access_mask,
1976 share_access);
1977 if (!conflict) {
1978 DBG_DEBUG("No conflict due to share_mode_flags access\n");
1979 return NT_STATUS_OK;
1982 state = (struct open_mode_check_state) {
1983 .fid = fid,
1984 .share_access = (FILE_SHARE_READ|
1985 FILE_SHARE_WRITE|
1986 FILE_SHARE_DELETE),
1990 * Walk the share mode array to recalculate d->flags
1993 ok = share_mode_forall_entries(lck, open_mode_check_fn, &state);
1994 if (!ok) {
1995 DBG_DEBUG("share_mode_forall_entries failed\n");
1996 return NT_STATUS_INTERNAL_ERROR;
1999 share_mode_flags_set(
2000 lck,
2001 state.access_mask,
2002 state.share_access,
2003 state.lease_type,
2004 &modified);
2005 if (!modified) {
2007 * We only end up here if we had a sharing violation
2008 * from d->flags and have recalculated it.
2010 return NT_STATUS_SHARING_VIOLATION;
2013 conflict = share_conflict(
2014 state.access_mask,
2015 state.share_access,
2016 access_mask,
2017 share_access);
2018 if (!conflict) {
2019 DBG_DEBUG("No conflict due to share_mode_flags access\n");
2020 return NT_STATUS_OK;
2023 return NT_STATUS_SHARING_VIOLATION;
2027 * Send a break message to the oplock holder and delay the open for
2028 * our client.
2031 NTSTATUS send_break_message(struct messaging_context *msg_ctx,
2032 const struct file_id *id,
2033 const struct share_mode_entry *exclusive,
2034 uint16_t break_to)
2036 struct oplock_break_message msg = {
2037 .id = *id,
2038 .share_file_id = exclusive->share_file_id,
2039 .break_to = break_to,
2041 enum ndr_err_code ndr_err;
2042 DATA_BLOB blob;
2043 NTSTATUS status;
2045 if (DEBUGLVL(10)) {
2046 struct server_id_buf buf;
2047 DBG_DEBUG("Sending break message to %s\n",
2048 server_id_str_buf(exclusive->pid, &buf));
2049 NDR_PRINT_DEBUG(oplock_break_message, &msg);
2052 ndr_err = ndr_push_struct_blob(
2053 &blob,
2054 talloc_tos(),
2055 &msg,
2056 (ndr_push_flags_fn_t)ndr_push_oplock_break_message);
2057 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2058 DBG_WARNING("ndr_push_oplock_break_message failed: %s\n",
2059 ndr_errstr(ndr_err));
2060 return ndr_map_error2ntstatus(ndr_err);
2063 status = messaging_send(
2064 msg_ctx, exclusive->pid, MSG_SMB_BREAK_REQUEST, &blob);
2065 TALLOC_FREE(blob.data);
2066 if (!NT_STATUS_IS_OK(status)) {
2067 DEBUG(3, ("Could not send oplock break message: %s\n",
2068 nt_errstr(status)));
2071 return status;
2074 struct validate_oplock_types_state {
2075 bool valid;
2076 bool batch;
2077 bool ex_or_batch;
2078 bool level2;
2079 bool no_oplock;
2080 uint32_t num_non_stat_opens;
2083 static bool validate_oplock_types_fn(
2084 struct share_mode_entry *e,
2085 bool *modified,
2086 void *private_data)
2088 struct validate_oplock_types_state *state = private_data;
2090 if (e->op_mid == 0) {
2091 /* INTERNAL_OPEN_ONLY */
2092 return false;
2095 if (e->op_type == NO_OPLOCK && is_oplock_stat_open(e->access_mask)) {
2097 * We ignore stat opens in the table - they always
2098 * have NO_OPLOCK and never get or cause breaks. JRA.
2100 return false;
2103 state->num_non_stat_opens += 1;
2105 if (BATCH_OPLOCK_TYPE(e->op_type)) {
2106 /* batch - can only be one. */
2107 if (share_entry_stale_pid(e)) {
2108 DBG_DEBUG("Found stale batch oplock\n");
2109 return false;
2111 if (state->ex_or_batch ||
2112 state->batch ||
2113 state->level2 ||
2114 state->no_oplock) {
2115 DBG_ERR("Bad batch oplock entry\n");
2116 state->valid = false;
2117 return true;
2119 state->batch = true;
2122 if (EXCLUSIVE_OPLOCK_TYPE(e->op_type)) {
2123 if (share_entry_stale_pid(e)) {
2124 DBG_DEBUG("Found stale duplicate oplock\n");
2125 return false;
2127 /* Exclusive or batch - can only be one. */
2128 if (state->ex_or_batch ||
2129 state->level2 ||
2130 state->no_oplock) {
2131 DBG_ERR("Bad exclusive or batch oplock entry\n");
2132 state->valid = false;
2133 return true;
2135 state->ex_or_batch = true;
2138 if (LEVEL_II_OPLOCK_TYPE(e->op_type)) {
2139 if (state->batch || state->ex_or_batch) {
2140 if (share_entry_stale_pid(e)) {
2141 DBG_DEBUG("Found stale LevelII oplock\n");
2142 return false;
2144 DBG_DEBUG("Bad levelII oplock entry\n");
2145 state->valid = false;
2146 return true;
2148 state->level2 = true;
2151 if (e->op_type == NO_OPLOCK) {
2152 if (state->batch || state->ex_or_batch) {
2153 if (share_entry_stale_pid(e)) {
2154 DBG_DEBUG("Found stale NO_OPLOCK entry\n");
2155 return false;
2157 DBG_ERR("Bad no oplock entry\n");
2158 state->valid = false;
2159 return true;
2161 state->no_oplock = true;
2164 return false;
2168 * Do internal consistency checks on the share mode for a file.
2171 static bool validate_oplock_types(struct share_mode_lock *lck)
2173 struct validate_oplock_types_state state = { .valid = true };
2174 static bool skip_validation;
2175 bool validate;
2176 bool ok;
2178 if (skip_validation) {
2179 return true;
2182 validate = lp_parm_bool(-1, "smbd", "validate_oplock_types", false);
2183 if (!validate) {
2184 DBG_DEBUG("smbd:validate_oplock_types not set to yes\n");
2185 skip_validation = true;
2186 return true;
2189 ok = share_mode_forall_entries(lck, validate_oplock_types_fn, &state);
2190 if (!ok) {
2191 DBG_DEBUG("share_mode_forall_entries failed\n");
2192 return false;
2194 if (!state.valid) {
2195 DBG_DEBUG("Got invalid oplock configuration\n");
2196 return false;
2199 if ((state.batch || state.ex_or_batch) &&
2200 (state.num_non_stat_opens != 1)) {
2201 DBG_WARNING("got batch (%d) or ex (%d) non-exclusively "
2202 "(%"PRIu32")\n",
2203 (int)state.batch,
2204 (int)state.ex_or_batch,
2205 state.num_non_stat_opens);
2206 return false;
2209 return true;
2212 static bool is_same_lease(const files_struct *fsp,
2213 const struct share_mode_entry *e,
2214 const struct smb2_lease *lease)
2216 if (e->op_type != LEASE_OPLOCK) {
2217 return false;
2219 if (lease == NULL) {
2220 return false;
2223 return smb2_lease_equal(fsp_client_guid(fsp),
2224 &lease->lease_key,
2225 &e->client_guid,
2226 &e->lease_key);
2229 static bool file_has_brlocks(files_struct *fsp)
2231 struct byte_range_lock *br_lck;
2233 br_lck = brl_get_locks_readonly(fsp);
2234 if (!br_lck)
2235 return false;
2237 return (brl_num_locks(br_lck) > 0);
2240 struct fsp_lease *find_fsp_lease(struct files_struct *new_fsp,
2241 const struct smb2_lease_key *key,
2242 uint32_t current_state,
2243 uint16_t lease_version,
2244 uint16_t lease_epoch)
2246 struct files_struct *fsp;
2249 * TODO: Measure how expensive this loop is with thousands of open
2250 * handles...
2253 for (fsp = file_find_di_first(new_fsp->conn->sconn, new_fsp->file_id, true);
2254 fsp != NULL;
2255 fsp = file_find_di_next(fsp, true)) {
2257 if (fsp == new_fsp) {
2258 continue;
2260 if (fsp->oplock_type != LEASE_OPLOCK) {
2261 continue;
2263 if (smb2_lease_key_equal(&fsp->lease->lease.lease_key, key)) {
2264 fsp->lease->ref_count += 1;
2265 return fsp->lease;
2269 /* Not found - must be leased in another smbd. */
2270 new_fsp->lease = talloc_zero(new_fsp->conn->sconn, struct fsp_lease);
2271 if (new_fsp->lease == NULL) {
2272 return NULL;
2274 new_fsp->lease->ref_count = 1;
2275 new_fsp->lease->sconn = new_fsp->conn->sconn;
2276 new_fsp->lease->lease.lease_key = *key;
2277 new_fsp->lease->lease.lease_state = current_state;
2279 * We internally treat all leases as V2 and update
2280 * the epoch, but when sending breaks it matters if
2281 * the requesting lease was v1 or v2.
2283 new_fsp->lease->lease.lease_version = lease_version;
2284 new_fsp->lease->lease.lease_epoch = lease_epoch;
2285 return new_fsp->lease;
2288 static NTSTATUS try_lease_upgrade(struct files_struct *fsp,
2289 struct share_mode_lock *lck,
2290 const struct GUID *client_guid,
2291 const struct smb2_lease *lease,
2292 uint32_t granted)
2294 bool do_upgrade;
2295 uint32_t current_state, breaking_to_requested, breaking_to_required;
2296 bool breaking;
2297 uint16_t lease_version, epoch;
2298 uint32_t existing, requested;
2299 NTSTATUS status;
2301 status = leases_db_get(
2302 client_guid,
2303 &lease->lease_key,
2304 &fsp->file_id,
2305 &current_state,
2306 &breaking,
2307 &breaking_to_requested,
2308 &breaking_to_required,
2309 &lease_version,
2310 &epoch);
2311 if (!NT_STATUS_IS_OK(status)) {
2312 return status;
2315 fsp->lease = find_fsp_lease(
2316 fsp,
2317 &lease->lease_key,
2318 current_state,
2319 lease_version,
2320 epoch);
2321 if (fsp->lease == NULL) {
2322 DEBUG(1, ("Did not find existing lease for file %s\n",
2323 fsp_str_dbg(fsp)));
2324 return NT_STATUS_NO_MEMORY;
2328 * Upgrade only if the requested lease is a strict upgrade.
2330 existing = current_state;
2331 requested = lease->lease_state;
2334 * Tricky: This test makes sure that "requested" is a
2335 * strict bitwise superset of "existing".
2337 do_upgrade = ((existing & requested) == existing);
2340 * Upgrade only if there's a change.
2342 do_upgrade &= (granted != existing);
2345 * Upgrade only if other leases don't prevent what was asked
2346 * for.
2348 do_upgrade &= (granted == requested);
2351 * only upgrade if we are not in breaking state
2353 do_upgrade &= !breaking;
2355 DEBUG(10, ("existing=%"PRIu32", requested=%"PRIu32", "
2356 "granted=%"PRIu32", do_upgrade=%d\n",
2357 existing, requested, granted, (int)do_upgrade));
2359 if (do_upgrade) {
2360 NTSTATUS set_status;
2362 current_state = granted;
2363 epoch += 1;
2365 set_status = leases_db_set(
2366 client_guid,
2367 &lease->lease_key,
2368 current_state,
2369 breaking,
2370 breaking_to_requested,
2371 breaking_to_required,
2372 lease_version,
2373 epoch);
2375 if (!NT_STATUS_IS_OK(set_status)) {
2376 DBG_DEBUG("leases_db_set failed: %s\n",
2377 nt_errstr(set_status));
2378 return set_status;
2382 fsp_lease_update(fsp);
2384 return NT_STATUS_OK;
2387 static NTSTATUS grant_new_fsp_lease(struct files_struct *fsp,
2388 struct share_mode_lock *lck,
2389 const struct GUID *client_guid,
2390 const struct smb2_lease *lease,
2391 uint32_t granted)
2393 NTSTATUS status;
2395 fsp->lease = talloc_zero(fsp->conn->sconn, struct fsp_lease);
2396 if (fsp->lease == NULL) {
2397 return NT_STATUS_INSUFFICIENT_RESOURCES;
2399 fsp->lease->ref_count = 1;
2400 fsp->lease->sconn = fsp->conn->sconn;
2401 fsp->lease->lease.lease_version = lease->lease_version;
2402 fsp->lease->lease.lease_key = lease->lease_key;
2403 fsp->lease->lease.lease_state = granted;
2404 fsp->lease->lease.lease_epoch = lease->lease_epoch + 1;
2406 status = leases_db_add(client_guid,
2407 &lease->lease_key,
2408 &fsp->file_id,
2409 fsp->lease->lease.lease_state,
2410 fsp->lease->lease.lease_version,
2411 fsp->lease->lease.lease_epoch,
2412 fsp->conn->connectpath,
2413 fsp->fsp_name->base_name,
2414 fsp->fsp_name->stream_name);
2415 if (!NT_STATUS_IS_OK(status)) {
2416 DEBUG(10, ("%s: leases_db_add failed: %s\n", __func__,
2417 nt_errstr(status)));
2418 TALLOC_FREE(fsp->lease);
2419 return NT_STATUS_INSUFFICIENT_RESOURCES;
2423 * We used to set lck->data->modified=true here without
2424 * actually modifying lck->data, triggering a needless
2425 * writeback of lck->data.
2427 * Apart from that writeback, setting modified=true has the
2428 * effect of triggering all waiters for this file to
2429 * retry. This only makes sense if any blocking condition
2430 * (i.e. waiting for a lease to be downgraded or removed) is
2431 * gone. This routine here only adds a lease, so it will never
2432 * free up resources that blocked waiters can now claim. So
2433 * that second effect also does not matter in this
2434 * routine. Thus setting lck->data->modified=true does not
2435 * need to be done here.
2438 return NT_STATUS_OK;
2441 static NTSTATUS grant_fsp_lease(struct files_struct *fsp,
2442 struct share_mode_lock *lck,
2443 const struct smb2_lease *lease,
2444 uint32_t granted)
2446 const struct GUID *client_guid = fsp_client_guid(fsp);
2447 NTSTATUS status;
2449 status = try_lease_upgrade(fsp, lck, client_guid, lease, granted);
2451 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
2452 status = grant_new_fsp_lease(
2453 fsp, lck, client_guid, lease, granted);
2456 return status;
2459 static int map_lease_type_to_oplock(uint32_t lease_type)
2461 int result = NO_OPLOCK;
2463 switch (lease_type) {
2464 case SMB2_LEASE_READ|SMB2_LEASE_WRITE|SMB2_LEASE_HANDLE:
2465 result = BATCH_OPLOCK|EXCLUSIVE_OPLOCK;
2466 break;
2467 case SMB2_LEASE_READ|SMB2_LEASE_WRITE:
2468 result = EXCLUSIVE_OPLOCK;
2469 break;
2470 case SMB2_LEASE_READ|SMB2_LEASE_HANDLE:
2471 case SMB2_LEASE_READ:
2472 result = LEVEL_II_OPLOCK;
2473 break;
2476 return result;
2479 struct delay_for_oplock_state {
2480 struct files_struct *fsp;
2481 const struct smb2_lease *lease;
2482 bool will_overwrite;
2483 uint32_t delay_mask;
2484 bool first_open_attempt;
2485 bool got_handle_lease;
2486 bool got_oplock;
2487 bool have_other_lease;
2488 uint32_t total_lease_types;
2489 bool delay;
2492 static bool delay_for_oplock_fn(
2493 struct share_mode_entry *e,
2494 bool *modified,
2495 void *private_data)
2497 struct delay_for_oplock_state *state = private_data;
2498 struct files_struct *fsp = state->fsp;
2499 const struct smb2_lease *lease = state->lease;
2500 bool e_is_lease = (e->op_type == LEASE_OPLOCK);
2501 uint32_t e_lease_type = SMB2_LEASE_NONE;
2502 uint32_t break_to;
2503 bool lease_is_breaking = false;
2505 if (e_is_lease) {
2506 NTSTATUS status;
2508 if (lease != NULL) {
2509 bool our_lease = is_same_lease(fsp, e, lease);
2510 if (our_lease) {
2511 DBG_DEBUG("Ignoring our own lease\n");
2512 return false;
2516 status = leases_db_get(
2517 &e->client_guid,
2518 &e->lease_key,
2519 &fsp->file_id,
2520 &e_lease_type, /* current_state */
2521 &lease_is_breaking,
2522 NULL, /* breaking_to_requested */
2523 NULL, /* breaking_to_required */
2524 NULL, /* lease_version */
2525 NULL); /* epoch */
2528 * leases_db_get() can return NT_STATUS_NOT_FOUND
2529 * if the share_mode_entry e is stale and the
2530 * lease record was already removed. In this case return
2531 * false so the traverse continues.
2534 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND) &&
2535 share_entry_stale_pid(e))
2537 struct GUID_txt_buf guid_strbuf;
2538 struct file_id_buf file_id_strbuf;
2539 DBG_DEBUG("leases_db_get for client_guid [%s] "
2540 "lease_key [%"PRIu64"/%"PRIu64"] "
2541 "file_id [%s] failed for stale "
2542 "share_mode_entry\n",
2543 GUID_buf_string(&e->client_guid, &guid_strbuf),
2544 e->lease_key.data[0],
2545 e->lease_key.data[1],
2546 file_id_str_buf(fsp->file_id, &file_id_strbuf));
2547 return false;
2549 if (!NT_STATUS_IS_OK(status)) {
2550 struct GUID_txt_buf guid_strbuf;
2551 struct file_id_buf file_id_strbuf;
2552 DBG_ERR("leases_db_get for client_guid [%s] "
2553 "lease_key [%"PRIu64"/%"PRIu64"] "
2554 "file_id [%s] failed: %s\n",
2555 GUID_buf_string(&e->client_guid, &guid_strbuf),
2556 e->lease_key.data[0],
2557 e->lease_key.data[1],
2558 file_id_str_buf(fsp->file_id, &file_id_strbuf),
2559 nt_errstr(status));
2560 smb_panic("leases_db_get() failed");
2562 } else {
2563 e_lease_type = get_lease_type(e, fsp->file_id);
2566 if (((e_lease_type & ~state->total_lease_types) != 0) &&
2567 !share_entry_stale_pid(e))
2569 state->total_lease_types |= e_lease_type;
2572 if (!state->got_handle_lease &&
2573 ((e_lease_type & SMB2_LEASE_HANDLE) != 0) &&
2574 !share_entry_stale_pid(e)) {
2575 state->got_handle_lease = true;
2578 if (!state->got_oplock &&
2579 (e->op_type != LEASE_OPLOCK) &&
2580 !share_entry_stale_pid(e)) {
2581 state->got_oplock = true;
2584 if (!state->have_other_lease &&
2585 !is_same_lease(fsp, e, lease) &&
2586 !share_entry_stale_pid(e)) {
2587 state->have_other_lease = true;
2590 if (e_is_lease && is_lease_stat_open(fsp->access_mask)) {
2591 return false;
2594 break_to = e_lease_type & ~state->delay_mask;
2596 if (state->will_overwrite) {
2597 break_to &= ~(SMB2_LEASE_HANDLE|SMB2_LEASE_READ);
2600 DBG_DEBUG("e_lease_type %u, will_overwrite: %u\n",
2601 (unsigned)e_lease_type,
2602 (unsigned)state->will_overwrite);
2604 if ((e_lease_type & ~break_to) == 0) {
2605 if (lease_is_breaking) {
2606 state->delay = true;
2608 return false;
2611 if (share_entry_stale_pid(e)) {
2612 return false;
2615 if (state->will_overwrite) {
2617 * If we break anyway break to NONE directly.
2618 * Otherwise vfs_set_filelen() will trigger the
2619 * break.
2621 break_to &= ~(SMB2_LEASE_READ|SMB2_LEASE_WRITE);
2624 if (!e_is_lease) {
2626 * Oplocks only support breaking to R or NONE.
2628 break_to &= ~(SMB2_LEASE_HANDLE|SMB2_LEASE_WRITE);
2631 DBG_DEBUG("breaking from %d to %d\n",
2632 (int)e_lease_type,
2633 (int)break_to);
2634 send_break_message(
2635 fsp->conn->sconn->msg_ctx, &fsp->file_id, e, break_to);
2636 if (e_lease_type & state->delay_mask) {
2637 state->delay = true;
2639 if (lease_is_breaking && !state->first_open_attempt) {
2640 state->delay = true;
2643 return false;
2646 static NTSTATUS delay_for_oplock(files_struct *fsp,
2647 int oplock_request,
2648 const struct smb2_lease *lease,
2649 struct share_mode_lock *lck,
2650 bool have_sharing_violation,
2651 uint32_t create_disposition,
2652 bool first_open_attempt,
2653 int *poplock_type,
2654 uint32_t *pgranted)
2656 struct delay_for_oplock_state state = {
2657 .fsp = fsp,
2658 .lease = lease,
2659 .first_open_attempt = first_open_attempt,
2661 uint32_t requested;
2662 uint32_t granted;
2663 int oplock_type;
2664 bool ok;
2666 *poplock_type = NO_OPLOCK;
2667 *pgranted = 0;
2669 if (fsp->fsp_flags.is_directory) {
2671 * No directory leases yet
2673 SMB_ASSERT(oplock_request == NO_OPLOCK);
2674 if (have_sharing_violation) {
2675 return NT_STATUS_SHARING_VIOLATION;
2677 return NT_STATUS_OK;
2680 if (oplock_request == LEASE_OPLOCK) {
2681 if (lease == NULL) {
2683 * The SMB2 layer should have checked this
2685 return NT_STATUS_INTERNAL_ERROR;
2688 requested = lease->lease_state;
2689 } else {
2690 requested = map_oplock_to_lease_type(
2691 oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK);
2694 share_mode_flags_get(lck, NULL, NULL, &state.total_lease_types);
2696 if (is_oplock_stat_open(fsp->access_mask)) {
2697 goto grant;
2700 state.delay_mask = have_sharing_violation ?
2701 SMB2_LEASE_HANDLE : SMB2_LEASE_WRITE;
2703 switch (create_disposition) {
2704 case FILE_SUPERSEDE:
2705 case FILE_OVERWRITE:
2706 case FILE_OVERWRITE_IF:
2707 state.will_overwrite = true;
2708 break;
2709 default:
2710 state.will_overwrite = false;
2711 break;
2714 state.total_lease_types = SMB2_LEASE_NONE;
2715 ok = share_mode_forall_entries(lck, delay_for_oplock_fn, &state);
2716 if (!ok) {
2717 return NT_STATUS_INTERNAL_ERROR;
2720 if (state.delay) {
2721 return NT_STATUS_RETRY;
2724 grant:
2725 if (have_sharing_violation) {
2726 return NT_STATUS_SHARING_VIOLATION;
2729 granted = requested;
2731 if (oplock_request == LEASE_OPLOCK) {
2732 if (lp_kernel_oplocks(SNUM(fsp->conn))) {
2733 DEBUG(10, ("No lease granted because kernel oplocks are enabled\n"));
2734 granted = SMB2_LEASE_NONE;
2736 if ((granted & (SMB2_LEASE_READ|SMB2_LEASE_WRITE)) == 0) {
2737 DEBUG(10, ("No read or write lease requested\n"));
2738 granted = SMB2_LEASE_NONE;
2740 if (granted == SMB2_LEASE_WRITE) {
2741 DEBUG(10, ("pure write lease requested\n"));
2742 granted = SMB2_LEASE_NONE;
2744 if (granted == (SMB2_LEASE_WRITE|SMB2_LEASE_HANDLE)) {
2745 DEBUG(10, ("write and handle lease requested\n"));
2746 granted = SMB2_LEASE_NONE;
2750 if (lp_locking(fsp->conn->params) && file_has_brlocks(fsp)) {
2751 DBG_DEBUG("file %s has byte range locks\n",
2752 fsp_str_dbg(fsp));
2753 granted &= ~SMB2_LEASE_READ;
2756 if (state.have_other_lease) {
2758 * Can grant only one writer
2760 granted &= ~SMB2_LEASE_WRITE;
2763 if ((granted & SMB2_LEASE_READ) && !(granted & SMB2_LEASE_WRITE)) {
2764 bool allow_level2 =
2765 (global_client_caps & CAP_LEVEL_II_OPLOCKS) &&
2766 lp_level2_oplocks(SNUM(fsp->conn));
2768 if (!allow_level2) {
2769 granted = SMB2_LEASE_NONE;
2773 if (oplock_request == LEASE_OPLOCK) {
2774 if (state.got_oplock) {
2775 granted &= ~SMB2_LEASE_HANDLE;
2778 oplock_type = LEASE_OPLOCK;
2779 } else {
2780 if (state.got_handle_lease) {
2781 granted = SMB2_LEASE_NONE;
2785 * Reflect possible downgrades from:
2786 * - map_lease_type_to_oplock() => "RH" to just LEVEL_II
2788 oplock_type = map_lease_type_to_oplock(granted);
2789 granted = map_oplock_to_lease_type(oplock_type);
2792 state.total_lease_types |= granted;
2795 uint32_t acc, sh, ls;
2796 share_mode_flags_get(lck, &acc, &sh, &ls);
2797 ls = state.total_lease_types;
2798 share_mode_flags_set(lck, acc, sh, ls, NULL);
2801 DBG_DEBUG("oplock type 0x%x granted (%s%s%s)(0x%x), on file %s, "
2802 "requested 0x%x (%s%s%s)(0x%x) => total (%s%s%s)(0x%x)\n",
2803 fsp->oplock_type,
2804 granted & SMB2_LEASE_READ ? "R":"",
2805 granted & SMB2_LEASE_WRITE ? "W":"",
2806 granted & SMB2_LEASE_HANDLE ? "H":"",
2807 granted,
2808 fsp_str_dbg(fsp),
2809 oplock_request,
2810 requested & SMB2_LEASE_READ ? "R":"",
2811 requested & SMB2_LEASE_WRITE ? "W":"",
2812 requested & SMB2_LEASE_HANDLE ? "H":"",
2813 requested,
2814 state.total_lease_types & SMB2_LEASE_READ ? "R":"",
2815 state.total_lease_types & SMB2_LEASE_WRITE ? "W":"",
2816 state.total_lease_types & SMB2_LEASE_HANDLE ? "H":"",
2817 state.total_lease_types);
2819 *poplock_type = oplock_type;
2820 *pgranted = granted;
2821 return NT_STATUS_OK;
2824 static NTSTATUS handle_share_mode_lease(
2825 files_struct *fsp,
2826 struct share_mode_lock *lck,
2827 uint32_t create_disposition,
2828 uint32_t access_mask,
2829 uint32_t share_access,
2830 int oplock_request,
2831 const struct smb2_lease *lease,
2832 bool first_open_attempt,
2833 int *poplock_type,
2834 uint32_t *pgranted)
2836 bool sharing_violation = false;
2837 NTSTATUS status;
2839 *poplock_type = NO_OPLOCK;
2840 *pgranted = 0;
2842 status = open_mode_check(
2843 fsp->conn, fsp->file_id, lck, access_mask, share_access);
2844 if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
2845 sharing_violation = true;
2846 status = NT_STATUS_OK; /* handled later */
2849 if (!NT_STATUS_IS_OK(status)) {
2850 return status;
2853 if (oplock_request == INTERNAL_OPEN_ONLY) {
2854 if (sharing_violation) {
2855 DBG_DEBUG("Sharing violation for internal open\n");
2856 return NT_STATUS_SHARING_VIOLATION;
2860 * Internal opens never do oplocks or leases. We don't
2861 * need to go through delay_for_oplock().
2863 return NT_STATUS_OK;
2866 status = delay_for_oplock(
2867 fsp,
2868 oplock_request,
2869 lease,
2870 lck,
2871 sharing_violation,
2872 create_disposition,
2873 first_open_attempt,
2874 poplock_type,
2875 pgranted);
2876 if (!NT_STATUS_IS_OK(status)) {
2877 return status;
2880 return NT_STATUS_OK;
2883 static bool request_timed_out(struct smb_request *req, struct timeval timeout)
2885 struct timeval now, end_time;
2886 GetTimeOfDay(&now);
2887 end_time = timeval_sum(&req->request_time, &timeout);
2888 return (timeval_compare(&end_time, &now) < 0);
2891 struct defer_open_state {
2892 struct smbXsrv_connection *xconn;
2893 uint64_t mid;
2896 static void defer_open_done(struct tevent_req *req);
2899 * Defer an open and watch a locking.tdb record
2901 * This defers an open that gets rescheduled once the locking.tdb record watch
2902 * is triggered by a change to the record.
2904 * It is used to defer opens that triggered an oplock break and for the SMB1
2905 * sharing violation delay.
2907 static void defer_open(struct share_mode_lock *lck,
2908 struct timeval timeout,
2909 struct smb_request *req,
2910 struct file_id id)
2912 struct deferred_open_record *open_rec = NULL;
2913 struct timeval abs_timeout;
2914 struct defer_open_state *watch_state;
2915 struct tevent_req *watch_req;
2916 struct timeval_buf tvbuf1, tvbuf2;
2917 struct file_id_buf fbuf;
2918 bool ok;
2920 abs_timeout = timeval_sum(&req->request_time, &timeout);
2922 DBG_DEBUG("request time [%s] timeout [%s] mid [%" PRIu64 "] "
2923 "file_id [%s]\n",
2924 timeval_str_buf(&req->request_time, false, true, &tvbuf1),
2925 timeval_str_buf(&abs_timeout, false, true, &tvbuf2),
2926 req->mid,
2927 file_id_str_buf(id, &fbuf));
2929 open_rec = talloc_zero(NULL, struct deferred_open_record);
2930 if (open_rec == NULL) {
2931 TALLOC_FREE(lck);
2932 exit_server("talloc failed");
2935 watch_state = talloc(open_rec, struct defer_open_state);
2936 if (watch_state == NULL) {
2937 exit_server("talloc failed");
2939 watch_state->xconn = req->xconn;
2940 watch_state->mid = req->mid;
2942 DBG_DEBUG("deferring mid %" PRIu64 "\n", req->mid);
2944 watch_req = share_mode_watch_send(
2945 watch_state,
2946 req->sconn->ev_ctx,
2947 lck,
2948 (struct server_id){0});
2949 if (watch_req == NULL) {
2950 exit_server("Could not watch share mode record");
2952 tevent_req_set_callback(watch_req, defer_open_done, watch_state);
2954 ok = tevent_req_set_endtime(watch_req, req->sconn->ev_ctx, abs_timeout);
2955 if (!ok) {
2956 exit_server("tevent_req_set_endtime failed");
2959 ok = push_deferred_open_message_smb(req, timeout, id, open_rec);
2960 if (!ok) {
2961 TALLOC_FREE(lck);
2962 exit_server("push_deferred_open_message_smb failed");
2966 static void defer_open_done(struct tevent_req *req)
2968 struct defer_open_state *state = tevent_req_callback_data(
2969 req, struct defer_open_state);
2970 NTSTATUS status;
2971 bool ret;
2973 status = share_mode_watch_recv(req, NULL, NULL);
2974 TALLOC_FREE(req);
2975 if (!NT_STATUS_IS_OK(status)) {
2976 DEBUG(5, ("dbwrap_watched_watch_recv returned %s\n",
2977 nt_errstr(status)));
2979 * Even if it failed, retry anyway. TODO: We need a way to
2980 * tell a re-scheduled open about that error.
2984 DEBUG(10, ("scheduling mid %llu\n", (unsigned long long)state->mid));
2986 ret = schedule_deferred_open_message_smb(state->xconn, state->mid);
2987 SMB_ASSERT(ret);
2988 TALLOC_FREE(state);
2992 * Actually attempt the kernel oplock polling open.
2995 static void poll_open_fn(struct tevent_context *ev,
2996 struct tevent_timer *te,
2997 struct timeval current_time,
2998 void *private_data)
3000 struct deferred_open_record *open_rec = talloc_get_type_abort(
3001 private_data, struct deferred_open_record);
3002 bool ok;
3004 TALLOC_FREE(open_rec->watch_req);
3006 ok = schedule_deferred_open_message_smb(
3007 open_rec->xconn, open_rec->mid);
3008 if (!ok) {
3009 exit_server("schedule_deferred_open_message_smb failed");
3011 DBG_DEBUG("timer fired. Retrying open !\n");
3014 static void poll_open_done(struct tevent_req *subreq);
3016 struct poll_open_setup_watcher_state {
3017 TALLOC_CTX *mem_ctx;
3018 struct tevent_context *ev_ctx;
3019 struct tevent_req *watch_req;
3022 static void poll_open_setup_watcher_fn(struct share_mode_lock *lck,
3023 void *private_data)
3025 struct poll_open_setup_watcher_state *state =
3026 (struct poll_open_setup_watcher_state *)private_data;
3028 if (!validate_oplock_types(lck)) {
3029 smb_panic("validate_oplock_types failed");
3032 state->watch_req = share_mode_watch_send(
3033 state->mem_ctx,
3034 state->ev_ctx,
3035 lck,
3036 (struct server_id) {0});
3037 if (state->watch_req == NULL) {
3038 DBG_WARNING("share_mode_watch_send failed\n");
3039 return;
3044 * Reschedule an open for 1 second from now, if not timed out.
3046 static bool setup_poll_open(
3047 struct smb_request *req,
3048 const struct file_id *id,
3049 struct timeval max_timeout,
3050 struct timeval interval)
3052 static struct file_id zero_id = {};
3053 bool ok;
3054 struct deferred_open_record *open_rec = NULL;
3055 struct timeval endtime, next_interval;
3056 struct file_id_buf ftmp;
3058 if (request_timed_out(req, max_timeout)) {
3059 return false;
3062 open_rec = talloc_zero(NULL, struct deferred_open_record);
3063 if (open_rec == NULL) {
3064 DBG_WARNING("talloc failed\n");
3065 return false;
3067 open_rec->xconn = req->xconn;
3068 open_rec->mid = req->mid;
3071 * Make sure open_rec->te does not come later than the
3072 * request's maximum endtime.
3075 endtime = timeval_sum(&req->request_time, &max_timeout);
3076 next_interval = timeval_current_ofs(interval.tv_sec, interval.tv_usec);
3077 next_interval = timeval_min(&endtime, &next_interval);
3079 open_rec->te = tevent_add_timer(
3080 req->sconn->ev_ctx,
3081 open_rec,
3082 next_interval,
3083 poll_open_fn,
3084 open_rec);
3085 if (open_rec->te == NULL) {
3086 DBG_WARNING("tevent_add_timer failed\n");
3087 TALLOC_FREE(open_rec);
3088 return false;
3091 if (id != NULL) {
3092 struct poll_open_setup_watcher_state wstate = {
3093 .mem_ctx = open_rec,
3094 .ev_ctx = req->sconn->ev_ctx,
3096 NTSTATUS status;
3098 status = share_mode_do_locked_vfs_denied(*id,
3099 poll_open_setup_watcher_fn,
3100 &wstate);
3101 if (NT_STATUS_IS_OK(status)) {
3102 if (wstate.watch_req == NULL) {
3103 DBG_WARNING("share_mode_watch_send failed\n");
3104 TALLOC_FREE(open_rec);
3105 return false;
3107 open_rec->watch_req = wstate.watch_req;
3108 tevent_req_set_callback(open_rec->watch_req,
3109 poll_open_done,
3110 open_rec);
3111 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
3112 DBG_WARNING("share_mode_do_locked_vfs_denied failed - %s\n",
3113 nt_errstr(status));
3114 TALLOC_FREE(open_rec);
3115 return false;
3117 } else {
3118 id = &zero_id;
3121 ok = push_deferred_open_message_smb(req, max_timeout, *id, open_rec);
3122 if (!ok) {
3123 DBG_WARNING("push_deferred_open_message_smb failed\n");
3124 TALLOC_FREE(open_rec);
3125 return false;
3128 DBG_DEBUG("poll request time [%s] mid [%" PRIu64 "] file_id [%s]\n",
3129 timeval_string(talloc_tos(), &req->request_time, false),
3130 req->mid,
3131 file_id_str_buf(*id, &ftmp));
3133 return true;
3136 static void poll_open_done(struct tevent_req *subreq)
3138 struct deferred_open_record *open_rec = tevent_req_callback_data(
3139 subreq, struct deferred_open_record);
3140 NTSTATUS status;
3141 bool ok;
3143 status = share_mode_watch_recv(subreq, NULL, NULL);
3144 TALLOC_FREE(subreq);
3145 open_rec->watch_req = NULL;
3146 TALLOC_FREE(open_rec->te);
3148 DBG_DEBUG("dbwrap_watched_watch_recv returned %s\n",
3149 nt_errstr(status));
3151 ok = schedule_deferred_open_message_smb(
3152 open_rec->xconn, open_rec->mid);
3153 if (!ok) {
3154 exit_server("schedule_deferred_open_message_smb failed");
3158 bool defer_smb1_sharing_violation(struct smb_request *req)
3160 bool ok;
3161 int timeout_usecs;
3163 if (!lp_defer_sharing_violations()) {
3164 return false;
3168 * Try every 200msec up to (by default) one second. To be
3169 * precise, according to behaviour note <247> in [MS-CIFS],
3170 * the server tries 5 times. But up to one second should be
3171 * close enough.
3174 timeout_usecs = lp_parm_int(
3175 SNUM(req->conn),
3176 "smbd",
3177 "sharedelay",
3178 SHARING_VIOLATION_USEC_WAIT);
3180 ok = setup_poll_open(
3181 req,
3182 NULL,
3183 (struct timeval) { .tv_usec = timeout_usecs },
3184 (struct timeval) { .tv_usec = 200000 });
3185 return ok;
3188 /****************************************************************************
3189 On overwrite open ensure that the attributes match.
3190 ****************************************************************************/
3192 static bool open_match_attributes(connection_struct *conn,
3193 uint32_t old_dos_attr,
3194 uint32_t new_dos_attr,
3195 mode_t new_unx_mode,
3196 mode_t *returned_unx_mode)
3198 uint32_t noarch_old_dos_attr, noarch_new_dos_attr;
3200 noarch_old_dos_attr = (old_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
3201 noarch_new_dos_attr = (new_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
3203 if((noarch_old_dos_attr == 0 && noarch_new_dos_attr != 0) ||
3204 (noarch_old_dos_attr != 0 && ((noarch_old_dos_attr & noarch_new_dos_attr) == noarch_old_dos_attr))) {
3205 *returned_unx_mode = new_unx_mode;
3206 } else {
3207 *returned_unx_mode = (mode_t)0;
3210 DEBUG(10,("open_match_attributes: old_dos_attr = 0x%x, "
3211 "new_dos_attr = 0x%x "
3212 "returned_unx_mode = 0%o\n",
3213 (unsigned int)old_dos_attr,
3214 (unsigned int)new_dos_attr,
3215 (unsigned int)*returned_unx_mode ));
3217 /* If we're mapping SYSTEM and HIDDEN ensure they match. */
3218 if (lp_map_system(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
3219 if ((old_dos_attr & FILE_ATTRIBUTE_SYSTEM) &&
3220 !(new_dos_attr & FILE_ATTRIBUTE_SYSTEM)) {
3221 return False;
3224 if (lp_map_hidden(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
3225 if ((old_dos_attr & FILE_ATTRIBUTE_HIDDEN) &&
3226 !(new_dos_attr & FILE_ATTRIBUTE_HIDDEN)) {
3227 return False;
3230 return True;
3233 static void schedule_defer_open(struct share_mode_lock *lck,
3234 struct file_id id,
3235 struct smb_request *req)
3237 /* This is a relative time, added to the absolute
3238 request_time value to get the absolute timeout time.
3239 Note that if this is the second or greater time we enter
3240 this codepath for this particular request mid then
3241 request_time is left as the absolute time of the *first*
3242 time this request mid was processed. This is what allows
3243 the request to eventually time out. */
3245 struct timeval timeout;
3247 /* Normally the smbd we asked should respond within
3248 * OPLOCK_BREAK_TIMEOUT seconds regardless of whether
3249 * the client did, give twice the timeout as a safety
3250 * measure here in case the other smbd is stuck
3251 * somewhere else. */
3253 timeout = timeval_set(OPLOCK_BREAK_TIMEOUT*2, 0);
3255 if (request_timed_out(req, timeout)) {
3256 return;
3259 defer_open(lck, timeout, req, id);
3262 /****************************************************************************
3263 Reschedule an open call that went asynchronous.
3264 ****************************************************************************/
3266 static void schedule_async_open_timer(struct tevent_context *ev,
3267 struct tevent_timer *te,
3268 struct timeval current_time,
3269 void *private_data)
3271 exit_server("async open timeout");
3274 static void schedule_async_open(struct smb_request *req)
3276 struct deferred_open_record *open_rec = NULL;
3277 struct timeval timeout = timeval_set(20, 0);
3278 bool ok;
3280 if (request_timed_out(req, timeout)) {
3281 return;
3284 open_rec = talloc_zero(NULL, struct deferred_open_record);
3285 if (open_rec == NULL) {
3286 exit_server("deferred_open_record_create failed");
3288 open_rec->async_open = true;
3290 ok = push_deferred_open_message_smb(
3291 req, timeout, (struct file_id){0}, open_rec);
3292 if (!ok) {
3293 exit_server("push_deferred_open_message_smb failed");
3296 open_rec->te = tevent_add_timer(req->sconn->ev_ctx,
3297 req,
3298 timeval_current_ofs(20, 0),
3299 schedule_async_open_timer,
3300 open_rec);
3301 if (open_rec->te == NULL) {
3302 exit_server("tevent_add_timer failed");
3306 static NTSTATUS check_and_store_share_mode(
3307 struct files_struct *fsp,
3308 struct smb_request *req,
3309 struct share_mode_lock *lck,
3310 uint32_t create_disposition,
3311 uint32_t access_mask,
3312 uint32_t share_access,
3313 int oplock_request,
3314 const struct smb2_lease *lease,
3315 bool first_open_attempt)
3317 NTSTATUS status;
3318 int oplock_type = NO_OPLOCK;
3319 uint32_t granted_lease = 0;
3320 const struct smb2_lease_key *lease_key = NULL;
3321 bool delete_on_close;
3322 bool ok;
3324 /* Get the types we need to examine. */
3325 if (!validate_oplock_types(lck)) {
3326 smb_panic("validate_oplock_types failed");
3329 delete_on_close = has_delete_on_close(lck, fsp->name_hash);
3330 if (delete_on_close) {
3331 return NT_STATUS_DELETE_PENDING;
3334 status = handle_share_mode_lease(fsp,
3335 lck,
3336 create_disposition,
3337 access_mask,
3338 share_access,
3339 oplock_request,
3340 lease,
3341 first_open_attempt,
3342 &oplock_type,
3343 &granted_lease);
3344 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
3345 schedule_defer_open(lck, fsp->file_id, req);
3346 return NT_STATUS_SHARING_VIOLATION;
3348 if (!NT_STATUS_IS_OK(status)) {
3349 return status;
3352 if (oplock_type == LEASE_OPLOCK) {
3353 lease_key = &lease->lease_key;
3356 share_mode_flags_restrict(lck, access_mask, share_access, 0);
3358 ok = set_share_mode(lck,
3359 fsp,
3360 get_current_uid(fsp->conn),
3361 req ? req->mid : 0,
3362 oplock_type,
3363 lease_key,
3364 share_access,
3365 access_mask);
3366 if (!ok) {
3367 return NT_STATUS_NO_MEMORY;
3370 if (oplock_type == LEASE_OPLOCK) {
3371 status = grant_fsp_lease(fsp, lck, lease, granted_lease);
3372 if (!NT_STATUS_IS_OK(status)) {
3373 del_share_mode(lck, fsp);
3374 return status;
3377 DBG_DEBUG("lease_state=%d\n", fsp->lease->lease.lease_state);
3380 fsp->oplock_type = oplock_type;
3382 return NT_STATUS_OK;
3385 /****************************************************************************
3386 Work out what access_mask to use from what the client sent us.
3387 ****************************************************************************/
3389 static NTSTATUS smbd_calculate_maximum_allowed_access_fsp(
3390 struct files_struct *dirfsp,
3391 struct files_struct *fsp,
3392 bool use_privs,
3393 uint32_t *p_access_mask)
3395 struct security_descriptor *sd = NULL;
3396 uint32_t access_granted = 0;
3397 uint32_t dosattrs;
3398 NTSTATUS status;
3400 /* Cope with symlinks */
3401 if (fsp == NULL || fsp_get_pathref_fd(fsp) == -1) {
3402 *p_access_mask = FILE_GENERIC_ALL;
3403 return NT_STATUS_OK;
3406 /* Cope with fake/printer fsp's. */
3407 if (fsp->fake_file_handle != NULL || fsp->print_file != NULL) {
3408 *p_access_mask = FILE_GENERIC_ALL;
3409 return NT_STATUS_OK;
3412 if (!use_privs && (get_current_uid(fsp->conn) == (uid_t)0)) {
3413 *p_access_mask |= FILE_GENERIC_ALL;
3414 return NT_STATUS_OK;
3417 status = SMB_VFS_FGET_NT_ACL(metadata_fsp(fsp),
3418 (SECINFO_OWNER |
3419 SECINFO_GROUP |
3420 SECINFO_DACL),
3421 talloc_tos(),
3422 &sd);
3424 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
3426 * File did not exist
3428 *p_access_mask = FILE_GENERIC_ALL;
3429 return NT_STATUS_OK;
3431 if (!NT_STATUS_IS_OK(status)) {
3432 DBG_ERR("Could not get acl on file %s: %s\n",
3433 fsp_str_dbg(fsp),
3434 nt_errstr(status));
3435 return status;
3439 * If we can access the path to this file, by
3440 * default we have FILE_READ_ATTRIBUTES from the
3441 * containing directory. See the section:
3442 * "Algorithm to Check Access to an Existing File"
3443 * in MS-FSA.pdf.
3445 * se_file_access_check()
3446 * also takes care of owner WRITE_DAC and READ_CONTROL.
3448 status = se_file_access_check(sd,
3449 get_current_nttok(fsp->conn),
3450 use_privs,
3451 (*p_access_mask & ~FILE_READ_ATTRIBUTES),
3452 &access_granted);
3454 TALLOC_FREE(sd);
3456 if (!NT_STATUS_IS_OK(status)) {
3457 DBG_ERR("Status %s on file %s: "
3458 "when calculating maximum access\n",
3459 nt_errstr(status),
3460 fsp_str_dbg(fsp));
3461 return status;
3464 *p_access_mask = (access_granted | FILE_READ_ATTRIBUTES);
3466 if (!(access_granted & DELETE_ACCESS)) {
3467 if (can_delete_file_in_directory(fsp->conn,
3468 dirfsp,
3469 fsp->fsp_name)) {
3470 *p_access_mask |= DELETE_ACCESS;
3474 dosattrs = fdos_mode(fsp);
3475 if ((dosattrs & FILE_ATTRIBUTE_READONLY) || !CAN_WRITE(fsp->conn)) {
3476 *p_access_mask &= ~(FILE_GENERIC_WRITE | DELETE_ACCESS);
3479 return NT_STATUS_OK;
3482 NTSTATUS smbd_calculate_access_mask_fsp(struct files_struct *dirfsp,
3483 struct files_struct *fsp,
3484 bool use_privs,
3485 uint32_t access_mask,
3486 uint32_t *access_mask_out)
3488 NTSTATUS status;
3489 uint32_t orig_access_mask = access_mask;
3490 uint32_t rejected_share_access;
3492 if (access_mask & SEC_MASK_INVALID) {
3493 DBG_DEBUG("access_mask [%8x] contains invalid bits\n",
3494 access_mask);
3495 return NT_STATUS_ACCESS_DENIED;
3499 * Convert GENERIC bits to specific bits.
3502 se_map_generic(&access_mask, &file_generic_mapping);
3504 /* Calculate MAXIMUM_ALLOWED_ACCESS if requested. */
3505 if (access_mask & MAXIMUM_ALLOWED_ACCESS) {
3507 status = smbd_calculate_maximum_allowed_access_fsp(
3508 dirfsp,
3509 fsp,
3510 use_privs,
3511 &access_mask);
3513 if (!NT_STATUS_IS_OK(status)) {
3514 return status;
3517 access_mask &= fsp->conn->share_access;
3520 rejected_share_access = access_mask & ~(fsp->conn->share_access);
3522 if (rejected_share_access) {
3523 DBG_INFO("Access denied on file %s: "
3524 "rejected by share access mask[0x%08X] "
3525 "orig[0x%08X] mapped[0x%08X] reject[0x%08X]\n",
3526 fsp_str_dbg(fsp),
3527 fsp->conn->share_access,
3528 orig_access_mask, access_mask,
3529 rejected_share_access);
3530 return NT_STATUS_ACCESS_DENIED;
3533 *access_mask_out = access_mask;
3534 return NT_STATUS_OK;
3537 /****************************************************************************
3538 Remove the deferred open entry under lock.
3539 ****************************************************************************/
3541 /****************************************************************************
3542 Return true if this is a state pointer to an asynchronous create.
3543 ****************************************************************************/
3545 bool is_deferred_open_async(const struct deferred_open_record *rec)
3547 return rec->async_open;
3550 static bool clear_ads(uint32_t create_disposition)
3552 bool ret = false;
3554 switch (create_disposition) {
3555 case FILE_SUPERSEDE:
3556 case FILE_OVERWRITE_IF:
3557 case FILE_OVERWRITE:
3558 ret = true;
3559 break;
3560 default:
3561 break;
3563 return ret;
3566 static int disposition_to_open_flags(uint32_t create_disposition)
3568 int ret = 0;
3571 * Currently we're using FILE_SUPERSEDE as the same as
3572 * FILE_OVERWRITE_IF but they really are
3573 * different. FILE_SUPERSEDE deletes an existing file
3574 * (requiring delete access) then recreates it.
3577 switch (create_disposition) {
3578 case FILE_SUPERSEDE:
3579 case FILE_OVERWRITE_IF:
3581 * If file exists replace/overwrite. If file doesn't
3582 * exist create.
3584 ret = O_CREAT|O_TRUNC;
3585 break;
3587 case FILE_OPEN:
3589 * If file exists open. If file doesn't exist error.
3591 ret = 0;
3592 break;
3594 case FILE_OVERWRITE:
3596 * If file exists overwrite. If file doesn't exist
3597 * error.
3599 ret = O_TRUNC;
3600 break;
3602 case FILE_CREATE:
3604 * If file exists error. If file doesn't exist create.
3606 ret = O_CREAT|O_EXCL;
3607 break;
3609 case FILE_OPEN_IF:
3611 * If file exists open. If file doesn't exist create.
3613 ret = O_CREAT;
3614 break;
3616 return ret;
3619 static int calculate_open_access_flags(uint32_t access_mask,
3620 uint32_t private_flags)
3622 bool need_write, need_read;
3625 * Note that we ignore the append flag as append does not
3626 * mean the same thing under DOS and Unix.
3629 need_write = (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA));
3630 if (!need_write) {
3631 return O_RDONLY;
3634 /* DENY_DOS opens are always underlying read-write on the
3635 file handle, no matter what the requested access mask
3636 says. */
3638 need_read =
3639 ((private_flags & NTCREATEX_FLAG_DENY_DOS) ||
3640 access_mask & (FILE_READ_ATTRIBUTES|FILE_READ_DATA|
3641 FILE_READ_EA|FILE_EXECUTE));
3643 if (!need_read) {
3644 return O_WRONLY;
3646 return O_RDWR;
3649 struct open_ntcreate_lock_state {
3650 struct share_mode_entry_prepare_state prepare_state;
3651 struct files_struct *fsp;
3652 const char *object_type;
3653 struct smb_request *req;
3654 uint32_t create_disposition;
3655 uint32_t access_mask;
3656 uint32_t share_access;
3657 int oplock_request;
3658 const struct smb2_lease *lease;
3659 bool first_open_attempt;
3660 bool keep_locked;
3661 NTSTATUS status;
3662 struct timespec write_time;
3663 share_mode_entry_prepare_unlock_fn_t cleanup_fn;
3666 static void open_ntcreate_lock_add_entry(struct share_mode_lock *lck,
3667 bool *keep_locked,
3668 void *private_data)
3670 struct open_ntcreate_lock_state *state =
3671 (struct open_ntcreate_lock_state *)private_data;
3674 * By default drop the g_lock again if we leave the
3675 * tdb chainlock.
3677 *keep_locked = false;
3679 state->status = check_and_store_share_mode(state->fsp,
3680 state->req,
3681 lck,
3682 state->create_disposition,
3683 state->access_mask,
3684 state->share_access,
3685 state->oplock_request,
3686 state->lease,
3687 state->first_open_attempt);
3688 if (!NT_STATUS_IS_OK(state->status)) {
3689 return;
3692 state->write_time = get_share_mode_write_time(lck);
3695 * keep the g_lock while existing the tdb chainlock,
3696 * we we're asked to, which mean we'll keep
3697 * the share_mode_lock during object creation,
3698 * or setting delete on close.
3700 *keep_locked = state->keep_locked;
3703 static void open_ntcreate_lock_cleanup_oplock(struct share_mode_lock *lck,
3704 void *private_data)
3706 struct open_ntcreate_lock_state *state =
3707 (struct open_ntcreate_lock_state *)private_data;
3708 bool ok;
3710 ok = remove_share_oplock(lck, state->fsp);
3711 if (!ok) {
3712 DBG_ERR("Could not remove oplock for %s %s\n",
3713 state->object_type, fsp_str_dbg(state->fsp));
3717 static void open_ntcreate_lock_cleanup_entry(struct share_mode_lock *lck,
3718 void *private_data)
3720 struct open_ntcreate_lock_state *state =
3721 (struct open_ntcreate_lock_state *)private_data;
3722 bool ok;
3724 ok = del_share_mode(lck, state->fsp);
3725 if (!ok) {
3726 DBG_ERR("Could not delete share entry for %s %s\n",
3727 state->object_type, fsp_str_dbg(state->fsp));
3731 /****************************************************************************
3732 Open a file with a share mode. Passed in an already created files_struct *.
3733 ****************************************************************************/
3735 static NTSTATUS open_file_ntcreate(connection_struct *conn,
3736 struct smb_request *req,
3737 uint32_t access_mask, /* access bits (FILE_READ_DATA etc.) */
3738 uint32_t share_access, /* share constants (FILE_SHARE_READ etc) */
3739 uint32_t create_disposition, /* FILE_OPEN_IF etc. */
3740 uint32_t create_options, /* options such as delete on close. */
3741 uint32_t new_dos_attributes, /* attributes used for new file. */
3742 int oplock_request, /* internal Samba oplock codes. */
3743 const struct smb2_lease *lease,
3744 /* Information (FILE_EXISTS etc.) */
3745 uint32_t private_flags, /* Samba specific flags. */
3746 struct smb_filename *parent_dir_fname, /* parent. */
3747 struct smb_filename *smb_fname_atname, /* atname relative to parent. */
3748 int *pinfo,
3749 files_struct *fsp)
3751 struct smb_filename *smb_fname = fsp->fsp_name;
3752 int flags=0;
3753 bool file_existed = VALID_STAT(smb_fname->st);
3754 bool def_acl = False;
3755 bool posix_open = False;
3756 bool new_file_created = False;
3757 bool first_open_attempt = true;
3758 NTSTATUS fsp_open = NT_STATUS_ACCESS_DENIED;
3759 mode_t new_unx_mode = (mode_t)0;
3760 mode_t unx_mode = (mode_t)0;
3761 int info;
3762 uint32_t existing_dos_attributes = 0;
3763 struct open_ntcreate_lock_state lck_state = {};
3764 bool keep_locked = false;
3765 uint32_t open_access_mask = access_mask;
3766 NTSTATUS status;
3767 SMB_STRUCT_STAT saved_stat = smb_fname->st;
3768 struct timespec old_write_time;
3769 bool setup_poll = false;
3770 NTSTATUS ulstatus;
3772 if (conn->printer) {
3774 * Printers are handled completely differently.
3775 * Most of the passed parameters are ignored.
3778 if (pinfo) {
3779 *pinfo = FILE_WAS_CREATED;
3782 DBG_DEBUG("printer open fname=%s\n",
3783 smb_fname_str_dbg(smb_fname));
3785 if (!req) {
3786 DBG_ERR("printer open without an SMB request!\n");
3787 return NT_STATUS_INTERNAL_ERROR;
3790 return print_spool_open(fsp, smb_fname->base_name,
3791 req->vuid);
3794 if (new_dos_attributes & FILE_FLAG_POSIX_SEMANTICS) {
3795 posix_open = True;
3796 unx_mode = (mode_t)(new_dos_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
3797 new_dos_attributes = 0;
3798 } else {
3799 /* Windows allows a new file to be created and
3800 silently removes a FILE_ATTRIBUTE_DIRECTORY
3801 sent by the client. Do the same. */
3803 new_dos_attributes &= ~FILE_ATTRIBUTE_DIRECTORY;
3805 /* We add FILE_ATTRIBUTE_ARCHIVE to this as this mode is only used if the file is
3806 * created new. */
3807 unx_mode = unix_mode(
3808 conn,
3809 new_dos_attributes | FILE_ATTRIBUTE_ARCHIVE,
3810 smb_fname,
3811 parent_dir_fname->fsp);
3814 DEBUG(10, ("open_file_ntcreate: fname=%s, dos_attrs=0x%x "
3815 "access_mask=0x%x share_access=0x%x "
3816 "create_disposition = 0x%x create_options=0x%x "
3817 "unix mode=0%o oplock_request=%d private_flags = 0x%x\n",
3818 smb_fname_str_dbg(smb_fname), new_dos_attributes,
3819 access_mask, share_access, create_disposition,
3820 create_options, (unsigned int)unx_mode, oplock_request,
3821 (unsigned int)private_flags));
3823 if (req == NULL) {
3824 /* Ensure req == NULL means INTERNAL_OPEN_ONLY */
3825 SMB_ASSERT(oplock_request == INTERNAL_OPEN_ONLY);
3826 } else {
3827 /* And req != NULL means no INTERNAL_OPEN_ONLY */
3828 SMB_ASSERT(((oplock_request & INTERNAL_OPEN_ONLY) == 0));
3832 * Only non-internal opens can be deferred at all
3835 if (req) {
3836 struct deferred_open_record *open_rec;
3837 if (get_deferred_open_message_state(req, NULL, &open_rec)) {
3839 /* If it was an async create retry, the file
3840 didn't exist. */
3842 if (is_deferred_open_async(open_rec)) {
3843 SET_STAT_INVALID(smb_fname->st);
3844 file_existed = false;
3847 /* Ensure we don't reprocess this message. */
3848 remove_deferred_open_message_smb(req->xconn, req->mid);
3850 first_open_attempt = false;
3854 if (!posix_open) {
3855 new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
3856 if (file_existed) {
3858 * Only use stored DOS attributes for checks
3859 * against requested attributes (below via
3860 * open_match_attributes()), cf bug #11992
3861 * for details. -slow
3863 uint32_t attr = 0;
3865 status = vfs_fget_dos_attributes(smb_fname->fsp, &attr);
3866 if (NT_STATUS_IS_OK(status)) {
3867 existing_dos_attributes = attr;
3872 /* ignore any oplock requests if oplocks are disabled */
3873 if (!lp_oplocks(SNUM(conn)) ||
3874 IS_VETO_OPLOCK_PATH(conn, smb_fname->base_name)) {
3875 /* Mask off everything except the private Samba bits. */
3876 oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
3879 /* this is for OS/2 long file names - say we don't support them */
3880 if (req != NULL && !req->posix_pathnames &&
3881 strstr(smb_fname->base_name,".+,;=[].")) {
3882 /* OS/2 Workplace shell fix may be main code stream in a later
3883 * release. */
3884 DEBUG(5,("open_file_ntcreate: OS/2 long filenames are not "
3885 "supported.\n"));
3886 if (use_nt_status()) {
3887 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3889 return NT_STATUS_DOS(ERRDOS, ERRcannotopen);
3892 switch( create_disposition ) {
3893 case FILE_OPEN:
3894 /* If file exists open. If file doesn't exist error. */
3895 if (!file_existed) {
3896 DEBUG(5,("open_file_ntcreate: FILE_OPEN "
3897 "requested for file %s and file "
3898 "doesn't exist.\n",
3899 smb_fname_str_dbg(smb_fname)));
3900 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3902 break;
3904 case FILE_OVERWRITE:
3905 /* If file exists overwrite. If file doesn't exist
3906 * error. */
3907 if (!file_existed) {
3908 DEBUG(5,("open_file_ntcreate: FILE_OVERWRITE "
3909 "requested for file %s and file "
3910 "doesn't exist.\n",
3911 smb_fname_str_dbg(smb_fname) ));
3912 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3914 break;
3916 case FILE_CREATE:
3917 /* If file exists error. If file doesn't exist
3918 * create. */
3919 if (file_existed) {
3920 DEBUG(5,("open_file_ntcreate: FILE_CREATE "
3921 "requested for file %s and file "
3922 "already exists.\n",
3923 smb_fname_str_dbg(smb_fname)));
3924 if (S_ISDIR(smb_fname->st.st_ex_mode)) {
3925 return NT_STATUS_FILE_IS_A_DIRECTORY;
3927 return NT_STATUS_OBJECT_NAME_COLLISION;
3929 break;
3931 case FILE_SUPERSEDE:
3932 case FILE_OVERWRITE_IF:
3933 case FILE_OPEN_IF:
3934 break;
3935 default:
3936 return NT_STATUS_INVALID_PARAMETER;
3939 flags = disposition_to_open_flags(create_disposition);
3941 /* We only care about matching attributes on file exists and
3942 * overwrite. */
3944 if (!posix_open && file_existed &&
3945 ((create_disposition == FILE_OVERWRITE) ||
3946 (create_disposition == FILE_OVERWRITE_IF))) {
3947 if (!open_match_attributes(conn, existing_dos_attributes,
3948 new_dos_attributes,
3949 unx_mode, &new_unx_mode)) {
3950 DEBUG(5,("open_file_ntcreate: attributes mismatch "
3951 "for file %s (%x %x) (0%o, 0%o)\n",
3952 smb_fname_str_dbg(smb_fname),
3953 existing_dos_attributes,
3954 new_dos_attributes,
3955 (unsigned int)smb_fname->st.st_ex_mode,
3956 (unsigned int)unx_mode ));
3957 return NT_STATUS_ACCESS_DENIED;
3961 status = smbd_calculate_access_mask_fsp(parent_dir_fname->fsp,
3962 smb_fname->fsp,
3963 false,
3964 access_mask,
3965 &access_mask);
3966 if (!NT_STATUS_IS_OK(status)) {
3967 DBG_DEBUG("smbd_calculate_access_mask_fsp "
3968 "on file %s returned %s\n",
3969 smb_fname_str_dbg(smb_fname),
3970 nt_errstr(status));
3971 return status;
3974 open_access_mask = access_mask;
3976 if (flags & O_TRUNC) {
3977 open_access_mask |= FILE_WRITE_DATA; /* This will cause oplock breaks. */
3980 if (file_existed) {
3982 * stat opens on existing files don't get oplocks.
3983 * They can get leases.
3985 * Note that we check for stat open on the *open_access_mask*,
3986 * i.e. the access mask we actually used to do the open,
3987 * not the one the client asked for (which is in
3988 * fsp->access_mask). This is due to the fact that
3989 * FILE_OVERWRITE and FILE_OVERWRITE_IF add in O_TRUNC,
3990 * which adds FILE_WRITE_DATA to open_access_mask.
3992 if (is_oplock_stat_open(open_access_mask) && lease == NULL) {
3993 oplock_request = NO_OPLOCK;
3997 DEBUG(10, ("open_file_ntcreate: fname=%s, after mapping "
3998 "access_mask=0x%x\n", smb_fname_str_dbg(smb_fname),
3999 access_mask));
4002 * Note that we ignore the append flag as append does not
4003 * mean the same thing under DOS and Unix.
4006 flags |= calculate_open_access_flags(access_mask, private_flags);
4009 * Currently we only look at FILE_WRITE_THROUGH for create options.
4012 #if defined(O_SYNC)
4013 if ((create_options & FILE_WRITE_THROUGH) && lp_strict_sync(SNUM(conn))) {
4014 flags |= O_SYNC;
4016 #endif /* O_SYNC */
4018 if (posix_open && (access_mask & FILE_APPEND_DATA)) {
4019 flags |= O_APPEND;
4022 if (!posix_open && !CAN_WRITE(conn)) {
4024 * We should really return a permission denied error if either
4025 * O_CREAT or O_TRUNC are set, but for compatibility with
4026 * older versions of Samba we just AND them out.
4028 flags &= ~(O_CREAT | O_TRUNC);
4032 * With kernel oplocks the open breaking an oplock
4033 * blocks until the oplock holder has given up the
4034 * oplock or closed the file. We prevent this by always
4035 * trying to open the file with O_NONBLOCK (see "man
4036 * fcntl" on Linux).
4038 * If a process that doesn't use the smbd open files
4039 * database or communication methods holds a kernel
4040 * oplock we must periodically poll for available open
4041 * using O_NONBLOCK.
4043 flags |= O_NONBLOCK;
4046 * Ensure we can't write on a read-only share or file.
4049 if (((flags & O_ACCMODE) != O_RDONLY) && file_existed &&
4050 (!CAN_WRITE(conn) ||
4051 (existing_dos_attributes & FILE_ATTRIBUTE_READONLY))) {
4052 DEBUG(5,("open_file_ntcreate: write access requested for "
4053 "file %s on read only %s\n",
4054 smb_fname_str_dbg(smb_fname),
4055 !CAN_WRITE(conn) ? "share" : "file" ));
4056 return NT_STATUS_ACCESS_DENIED;
4059 if (VALID_STAT(smb_fname->st)) {
4061 * Only try and create a file id before open
4062 * for an existing file. For a file being created
4063 * this won't do anything useful until the file
4064 * exists and has a valid stat struct.
4066 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
4068 fh_set_private_options(fsp->fh, private_flags);
4069 fsp->access_mask = open_access_mask; /* We change this to the
4070 * requested access_mask after
4071 * the open is done. */
4072 if (posix_open) {
4073 fsp->posix_flags |= FSP_POSIX_FLAGS_ALL;
4076 if ((create_options & FILE_DELETE_ON_CLOSE) && (flags & O_CREAT) &&
4077 !file_existed) {
4078 /* Delete on close semantics for new files. */
4079 status = can_set_delete_on_close(fsp,
4080 new_dos_attributes);
4081 if (!NT_STATUS_IS_OK(status)) {
4082 fd_close(fsp);
4083 return status;
4088 * Ensure we pay attention to default ACLs on directories if required.
4091 if ((flags & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
4092 (def_acl = directory_has_default_acl_fsp(parent_dir_fname->fsp))) {
4093 unx_mode = (0777 & lp_create_mask(SNUM(conn)));
4096 DEBUG(4,
4097 ("calling open_file with flags=0x%X mode=0%o, "
4098 "access_mask = 0x%x, open_access_mask = 0x%x\n",
4099 (unsigned int)flags,
4100 (unsigned int)unx_mode,
4101 (unsigned int)access_mask,
4102 (unsigned int)open_access_mask));
4105 struct vfs_open_how how = {
4106 .flags = flags,
4107 .mode = unx_mode,
4110 if (create_options & FILE_OPEN_FOR_BACKUP_INTENT) {
4111 how.resolve |= VFS_OPEN_HOW_WITH_BACKUP_INTENT;
4114 fsp_open = open_file(req,
4115 parent_dir_fname->fsp,
4116 smb_fname_atname,
4117 fsp,
4118 &how,
4119 access_mask,
4120 open_access_mask,
4121 private_flags,
4122 &new_file_created);
4124 if (NT_STATUS_EQUAL(fsp_open, NT_STATUS_NETWORK_BUSY)) {
4125 if (file_existed && S_ISFIFO(fsp->fsp_name->st.st_ex_mode)) {
4126 DEBUG(10, ("FIFO busy\n"));
4127 return NT_STATUS_NETWORK_BUSY;
4129 if (req == NULL) {
4130 DEBUG(10, ("Internal open busy\n"));
4131 return NT_STATUS_NETWORK_BUSY;
4134 * This handles the kernel oplock case:
4136 * the file has an active kernel oplock and the open() returned
4137 * EWOULDBLOCK/EAGAIN which maps to NETWORK_BUSY.
4139 * "Samba locking.tdb oplocks" are handled below after acquiring
4140 * the sharemode lock with get_share_mode_lock().
4142 setup_poll = true;
4145 if (NT_STATUS_EQUAL(fsp_open, NT_STATUS_RETRY)) {
4147 * EINTR from the open(2) syscall. Just setup a retry
4148 * in a bit. We can't use the sys_write() tight retry
4149 * loop here, as we might have to actually deal with
4150 * lease-break signals to avoid a deadlock.
4152 setup_poll = true;
4155 if (setup_poll) {
4157 * Retry once a second. If there's a share_mode_lock
4158 * around, also wait for it in case it was smbd
4159 * holding that kernel oplock that can quickly tell us
4160 * the oplock got removed.
4163 setup_poll_open(
4164 req,
4165 &fsp->file_id,
4166 timeval_set(OPLOCK_BREAK_TIMEOUT*2, 0),
4167 timeval_set(1, 0));
4169 return NT_STATUS_SHARING_VIOLATION;
4172 if (!NT_STATUS_IS_OK(fsp_open)) {
4173 bool wait_for_aio = NT_STATUS_EQUAL(
4174 fsp_open, NT_STATUS_MORE_PROCESSING_REQUIRED);
4175 if (wait_for_aio) {
4176 schedule_async_open(req);
4178 return fsp_open;
4181 if (new_file_created) {
4183 * As we atomically create using O_CREAT|O_EXCL,
4184 * then if new_file_created is true, then
4185 * file_existed *MUST* have been false (even
4186 * if the file was previously detected as being
4187 * there).
4189 file_existed = false;
4192 if (file_existed && !check_same_dev_ino(&saved_stat, &smb_fname->st)) {
4194 * The file did exist, but some other (local or NFS)
4195 * process either renamed/unlinked and re-created the
4196 * file with different dev/ino after we walked the path,
4197 * but before we did the open. We could retry the
4198 * open but it's a rare enough case it's easier to
4199 * just fail the open to prevent creating any problems
4200 * in the open file db having the wrong dev/ino key.
4202 fd_close(fsp);
4203 DBG_WARNING("file %s - dev/ino mismatch. "
4204 "Old (dev=%ju, ino=%ju). "
4205 "New (dev=%ju, ino=%ju). Failing open "
4206 "with NT_STATUS_ACCESS_DENIED.\n",
4207 smb_fname_str_dbg(smb_fname),
4208 (uintmax_t)saved_stat.st_ex_dev,
4209 (uintmax_t)saved_stat.st_ex_ino,
4210 (uintmax_t)smb_fname->st.st_ex_dev,
4211 (uintmax_t)smb_fname->st.st_ex_ino);
4212 return NT_STATUS_ACCESS_DENIED;
4215 old_write_time = smb_fname->st.st_ex_mtime;
4218 * Deal with the race condition where two smbd's detect the
4219 * file doesn't exist and do the create at the same time. One
4220 * of them will win and set a share mode, the other (ie. this
4221 * one) should check if the requested share mode for this
4222 * create is allowed.
4226 * Now the file exists and fsp is successfully opened,
4227 * fsp->dev and fsp->inode are valid and should replace the
4228 * dev=0,inode=0 from a non existent file. Spotted by
4229 * Nadav Danieli <nadavd@exanet.com>. JRA.
4232 if (new_file_created) {
4233 info = FILE_WAS_CREATED;
4234 } else {
4235 if (flags & O_TRUNC) {
4236 info = FILE_WAS_OVERWRITTEN;
4237 } else {
4238 info = FILE_WAS_OPENED;
4243 * If we created a new file, overwrite an existing one
4244 * or going to delete it later, we should keep
4245 * the share_mode_lock (g_lock) until we call
4246 * share_mode_entry_prepare_unlock()
4248 if (info != FILE_WAS_OPENED) {
4249 keep_locked = true;
4250 } else if (create_options & FILE_DELETE_ON_CLOSE) {
4251 keep_locked = true;
4254 lck_state = (struct open_ntcreate_lock_state) {
4255 .fsp = fsp,
4256 .object_type = "file",
4257 .req = req,
4258 .create_disposition = create_disposition,
4259 .access_mask = access_mask,
4260 .share_access = share_access,
4261 .oplock_request = oplock_request,
4262 .lease = lease,
4263 .first_open_attempt = first_open_attempt,
4264 .keep_locked = keep_locked,
4267 status = share_mode_entry_prepare_lock_add(&lck_state.prepare_state,
4268 fsp->file_id,
4269 conn->connectpath,
4270 smb_fname,
4271 &old_write_time,
4272 open_ntcreate_lock_add_entry,
4273 &lck_state);
4274 if (!NT_STATUS_IS_OK(status)) {
4275 DBG_ERR("share_mode_entry_prepare_lock_add() failed for %s - %s\n",
4276 smb_fname_str_dbg(smb_fname), nt_errstr(status));
4277 fd_close(fsp);
4278 return status;
4281 status = lck_state.status;
4282 if (!NT_STATUS_IS_OK(status)) {
4283 fd_close(fsp);
4284 return status;
4288 * From here we need to use 'goto unlock;' instead of return !!!
4291 if (fsp->oplock_type != NO_OPLOCK && fsp->oplock_type != LEASE_OPLOCK) {
4293 * Now ask for kernel oplocks
4294 * and cleanup on failure.
4296 status = set_file_oplock(fsp);
4297 if (!NT_STATUS_IS_OK(status)) {
4299 * Could not get the kernel oplock
4301 lck_state.cleanup_fn =
4302 open_ntcreate_lock_cleanup_oplock;
4303 fsp->oplock_type = NO_OPLOCK;
4307 /* Should we atomically (to the client at least) truncate ? */
4308 if ((!new_file_created) && (flags & O_TRUNC) &&
4309 (S_ISREG(fsp->fsp_name->st.st_ex_mode))) {
4310 int ret;
4312 ret = SMB_VFS_FTRUNCATE(fsp, 0);
4313 if (ret != 0) {
4314 status = map_nt_error_from_unix(errno);
4315 lck_state.cleanup_fn =
4316 open_ntcreate_lock_cleanup_entry;
4317 goto unlock;
4319 notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
4320 FILE_NOTIFY_CHANGE_SIZE
4321 | FILE_NOTIFY_CHANGE_ATTRIBUTES,
4322 fsp->fsp_name->base_name);
4326 * We have the share entry *locked*.....
4329 /* Delete streams if create_disposition requires it */
4330 if (!new_file_created &&
4331 clear_ads(create_disposition) &&
4332 !fsp_is_alternate_stream(fsp)) {
4333 status = delete_all_streams(conn, smb_fname);
4334 if (!NT_STATUS_IS_OK(status)) {
4335 lck_state.cleanup_fn =
4336 open_ntcreate_lock_cleanup_entry;
4337 goto unlock;
4341 if (!fsp->fsp_flags.is_pathref &&
4342 fsp_get_io_fd(fsp) != -1 &&
4343 lp_kernel_share_modes(SNUM(conn)))
4345 int ret;
4347 * Beware: streams implementing VFS modules may
4348 * implement streams in a way that fsp will have the
4349 * basefile open in the fsp fd, so lacking a distinct
4350 * fd for the stream the file-system sharemode will
4351 * apply on the basefile which is wrong. The actual
4352 * check is deferred to the VFS module implementing
4353 * the file-system sharemode call.
4355 ret = SMB_VFS_FILESYSTEM_SHAREMODE(fsp,
4356 share_access,
4357 access_mask);
4358 if (ret == -1){
4359 status = NT_STATUS_SHARING_VIOLATION;
4360 lck_state.cleanup_fn =
4361 open_ntcreate_lock_cleanup_entry;
4362 goto unlock;
4365 fsp->fsp_flags.kernel_share_modes_taken = true;
4369 * At this point onwards, we can guarantee that the share entry
4370 * is locked, whether we created the file or not, and that the
4371 * deny mode is compatible with all current opens.
4375 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
4376 * but we don't have to store this - just ignore it on access check.
4378 if (conn->sconn->using_smb2) {
4380 * SMB2 doesn't return it (according to Microsoft tests).
4381 * Test Case: TestSuite_ScenarioNo009GrantedAccessTestS0
4382 * File created with access = 0x7 (Read, Write, Delete)
4383 * Query Info on file returns 0x87 (Read, Write, Delete, Read Attributes)
4385 fsp->access_mask = access_mask;
4386 } else {
4387 /* But SMB1 does. */
4388 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
4391 if (pinfo) {
4392 *pinfo = info;
4395 /* Handle strange delete on close create semantics. */
4396 if (create_options & FILE_DELETE_ON_CLOSE) {
4397 if (!new_file_created) {
4398 status = can_set_delete_on_close(fsp,
4399 existing_dos_attributes);
4401 if (!NT_STATUS_IS_OK(status)) {
4402 /* Remember to delete the mode we just added. */
4403 lck_state.cleanup_fn =
4404 open_ntcreate_lock_cleanup_entry;
4405 goto unlock;
4408 /* Note that here we set the *initial* delete on close flag,
4409 not the regular one. The magic gets handled in close. */
4410 fsp->fsp_flags.initial_delete_on_close = true;
4413 if (info != FILE_WAS_OPENED) {
4414 /* Overwritten files should be initially set as archive */
4415 if ((info == FILE_WAS_OVERWRITTEN && lp_map_archive(SNUM(conn))) ||
4416 lp_store_dos_attributes(SNUM(conn))) {
4417 (void)fdos_mode(fsp);
4418 if (!posix_open) {
4419 if (file_set_dosmode(conn, smb_fname,
4420 new_dos_attributes | FILE_ATTRIBUTE_ARCHIVE,
4421 parent_dir_fname, true) == 0) {
4422 unx_mode = smb_fname->st.st_ex_mode;
4428 /* Determine sparse flag. */
4429 if (posix_open) {
4430 /* POSIX opens are sparse by default. */
4431 fsp->fsp_flags.is_sparse = true;
4432 } else {
4433 fsp->fsp_flags.is_sparse =
4434 (existing_dos_attributes & FILE_ATTRIBUTE_SPARSE);
4438 * Take care of inherited ACLs on created files - if default ACL not
4439 * selected.
4442 if (!posix_open && new_file_created && !def_acl) {
4443 if (unx_mode != smb_fname->st.st_ex_mode) {
4444 int ret = SMB_VFS_FCHMOD(fsp, unx_mode);
4445 if (ret == -1) {
4446 DBG_INFO("failed to reset "
4447 "attributes of file %s to 0%o\n",
4448 smb_fname_str_dbg(smb_fname),
4449 (unsigned int)unx_mode);
4453 } else if (new_unx_mode) {
4455 * We only get here in the case of:
4457 * a). Not a POSIX open.
4458 * b). File already existed.
4459 * c). File was overwritten.
4460 * d). Requested DOS attributes didn't match
4461 * the DOS attributes on the existing file.
4463 * In that case new_unx_mode has been set
4464 * equal to the calculated mode (including
4465 * possible inheritance of the mode from the
4466 * containing directory).
4468 * Note this mode was calculated with the
4469 * DOS attribute FILE_ATTRIBUTE_ARCHIVE added,
4470 * so the mode change here is suitable for
4471 * an overwritten file.
4474 if (new_unx_mode != smb_fname->st.st_ex_mode) {
4475 int ret = SMB_VFS_FCHMOD(fsp, new_unx_mode);
4476 if (ret == -1) {
4477 DBG_INFO("failed to reset "
4478 "attributes of file %s to 0%o\n",
4479 smb_fname_str_dbg(smb_fname),
4480 (unsigned int)new_unx_mode);
4486 * Deal with other opens having a modified write time.
4488 if (fsp_getinfo_ask_sharemode(fsp) &&
4489 !is_omit_timespec(&lck_state.write_time))
4491 update_stat_ex_mtime(&fsp->fsp_name->st, lck_state.write_time);
4494 status = NT_STATUS_OK;
4496 unlock:
4497 ulstatus = share_mode_entry_prepare_unlock(&lck_state.prepare_state,
4498 lck_state.cleanup_fn,
4499 &lck_state);
4500 if (!NT_STATUS_IS_OK(ulstatus)) {
4501 DBG_ERR("share_mode_entry_prepare_unlock() failed for %s - %s\n",
4502 smb_fname_str_dbg(smb_fname), nt_errstr(ulstatus));
4503 smb_panic("share_mode_entry_prepare_unlock() failed!");
4506 if (!NT_STATUS_IS_OK(status)) {
4507 fd_close(fsp);
4508 return status;
4511 return NT_STATUS_OK;
4514 static NTSTATUS mkdir_internal(connection_struct *conn,
4515 struct smb_filename *parent_dir_fname, /* parent. */
4516 struct smb_filename *smb_fname_atname, /* atname relative to parent. */
4517 struct smb_filename *smb_dname, /* full pathname from root of share. */
4518 uint32_t file_attributes,
4519 struct files_struct *fsp)
4521 const struct loadparm_substitution *lp_sub =
4522 loadparm_s3_global_substitution();
4523 mode_t mode;
4524 NTSTATUS status;
4525 bool posix_open = false;
4526 bool need_re_stat = false;
4527 uint32_t access_mask = SEC_DIR_ADD_SUBDIR;
4528 struct vfs_open_how how = { .flags = O_RDONLY|O_DIRECTORY, };
4529 int ret;
4531 if (!CAN_WRITE(conn) || (access_mask & ~(conn->share_access))) {
4532 DEBUG(5,("mkdir_internal: failing share access "
4533 "%s\n", lp_servicename(talloc_tos(), lp_sub, SNUM(conn))));
4534 return NT_STATUS_ACCESS_DENIED;
4537 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
4538 posix_open = true;
4539 mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
4540 } else {
4541 mode = unix_mode(conn,
4542 FILE_ATTRIBUTE_DIRECTORY,
4543 smb_dname,
4544 parent_dir_fname->fsp);
4547 status = check_parent_access_fsp(parent_dir_fname->fsp, access_mask);
4548 if(!NT_STATUS_IS_OK(status)) {
4549 DBG_INFO("check_parent_access_fsp "
4550 "on directory %s for path %s returned %s\n",
4551 smb_fname_str_dbg(parent_dir_fname),
4552 smb_dname->base_name,
4553 nt_errstr(status));
4554 return status;
4557 if (lp_inherit_acls(SNUM(conn))) {
4558 if (directory_has_default_acl_fsp(parent_dir_fname->fsp)) {
4559 mode = (0777 & lp_directory_mask(SNUM(conn)));
4563 ret = SMB_VFS_MKDIRAT(conn,
4564 parent_dir_fname->fsp,
4565 smb_fname_atname,
4566 mode);
4567 if (ret != 0) {
4568 return map_nt_error_from_unix(errno);
4572 * Make this a pathref fsp for now. open_directory() will reopen as a
4573 * full fsp.
4575 fsp->fsp_flags.is_pathref = true;
4577 status = fd_openat(parent_dir_fname->fsp, smb_fname_atname, fsp, &how);
4578 if (!NT_STATUS_IS_OK(status)) {
4579 return status;
4582 /* Ensure we're checking for a symlink here.... */
4583 /* We don't want to get caught by a symlink racer. */
4585 status = vfs_stat_fsp(fsp);
4586 if (!NT_STATUS_IS_OK(status)) {
4587 DEBUG(2, ("Could not stat directory '%s' just created: %s\n",
4588 smb_fname_str_dbg(smb_dname), nt_errstr(status)));
4589 return status;
4592 if (!S_ISDIR(smb_dname->st.st_ex_mode)) {
4593 DEBUG(0, ("Directory '%s' just created is not a directory !\n",
4594 smb_fname_str_dbg(smb_dname)));
4595 return NT_STATUS_NOT_A_DIRECTORY;
4598 if (lp_store_dos_attributes(SNUM(conn)) && !posix_open) {
4599 file_set_dosmode(conn,
4600 smb_dname,
4601 file_attributes | FILE_ATTRIBUTE_DIRECTORY,
4602 parent_dir_fname,
4603 true);
4606 if (lp_inherit_permissions(SNUM(conn))) {
4607 inherit_access_posix_acl(conn, parent_dir_fname->fsp,
4608 smb_dname, mode);
4609 need_re_stat = true;
4612 if (!posix_open) {
4614 * Check if high bits should have been set,
4615 * then (if bits are missing): add them.
4616 * Consider bits automagically set by UNIX, i.e. SGID bit from parent
4617 * dir.
4619 if ((mode & ~(S_IRWXU|S_IRWXG|S_IRWXO)) &&
4620 (mode & ~smb_dname->st.st_ex_mode)) {
4621 SMB_VFS_FCHMOD(fsp,
4622 (smb_dname->st.st_ex_mode |
4623 (mode & ~smb_dname->st.st_ex_mode)));
4624 need_re_stat = true;
4628 /* Change the owner if required. */
4629 if (lp_inherit_owner(SNUM(conn)) != INHERIT_OWNER_NO) {
4630 change_dir_owner_to_parent_fsp(parent_dir_fname->fsp,
4631 fsp);
4632 need_re_stat = true;
4635 if (need_re_stat) {
4636 status = vfs_stat_fsp(fsp);
4637 if (!NT_STATUS_IS_OK(status)) {
4638 DEBUG(2, ("Could not stat directory '%s' just created: %s\n",
4639 smb_fname_str_dbg(smb_dname), nt_errstr(status)));
4640 return status;
4644 notify_fname(conn, NOTIFY_ACTION_ADDED, FILE_NOTIFY_CHANGE_DIR_NAME,
4645 smb_dname->base_name);
4647 return NT_STATUS_OK;
4650 /****************************************************************************
4651 Open a directory from an NT SMB call.
4652 ****************************************************************************/
4654 static NTSTATUS open_directory(connection_struct *conn,
4655 struct smb_request *req,
4656 uint32_t access_mask,
4657 uint32_t share_access,
4658 uint32_t create_disposition,
4659 uint32_t create_options,
4660 uint32_t file_attributes,
4661 struct smb_filename *parent_dir_fname,
4662 struct smb_filename *smb_fname_atname,
4663 int *pinfo,
4664 struct files_struct *fsp)
4666 struct smb_filename *smb_dname = fsp->fsp_name;
4667 bool dir_existed = VALID_STAT(smb_dname->st);
4668 struct open_ntcreate_lock_state lck_state = {};
4669 bool keep_locked = false;
4670 NTSTATUS status;
4671 struct timespec mtimespec;
4672 int info = 0;
4673 uint32_t need_fd_access;
4674 NTSTATUS ulstatus;
4676 if (is_ntfs_stream_smb_fname(smb_dname)) {
4677 DEBUG(2, ("open_directory: %s is a stream name!\n",
4678 smb_fname_str_dbg(smb_dname)));
4679 return NT_STATUS_NOT_A_DIRECTORY;
4682 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS)) {
4683 /* Ensure we have a directory attribute. */
4684 file_attributes |= FILE_ATTRIBUTE_DIRECTORY;
4687 DBG_INFO("opening directory %s, access_mask = 0x%"PRIx32", "
4688 "share_access = 0x%"PRIx32" create_options = 0x%"PRIx32", "
4689 "create_disposition = 0x%"PRIx32", "
4690 "file_attributes = 0x%"PRIx32"\n",
4691 smb_fname_str_dbg(smb_dname),
4692 access_mask,
4693 share_access,
4694 create_options,
4695 create_disposition,
4696 file_attributes);
4698 status = smbd_calculate_access_mask_fsp(parent_dir_fname->fsp,
4699 smb_dname->fsp,
4700 false,
4701 access_mask,
4702 &access_mask);
4703 if (!NT_STATUS_IS_OK(status)) {
4704 DBG_DEBUG("smbd_calculate_access_mask_fsp "
4705 "on file %s returned %s\n",
4706 smb_fname_str_dbg(smb_dname),
4707 nt_errstr(status));
4708 return status;
4711 if ((access_mask & SEC_FLAG_SYSTEM_SECURITY) &&
4712 !security_token_has_privilege(get_current_nttok(conn),
4713 SEC_PRIV_SECURITY)) {
4714 DEBUG(10, ("open_directory: open on %s "
4715 "failed - SEC_FLAG_SYSTEM_SECURITY denied.\n",
4716 smb_fname_str_dbg(smb_dname)));
4717 return NT_STATUS_PRIVILEGE_NOT_HELD;
4720 switch( create_disposition ) {
4721 case FILE_OPEN:
4723 if (!dir_existed) {
4724 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4727 info = FILE_WAS_OPENED;
4728 break;
4730 case FILE_CREATE:
4732 /* If directory exists error. If directory doesn't
4733 * exist create. */
4735 if (dir_existed) {
4736 status = NT_STATUS_OBJECT_NAME_COLLISION;
4737 DEBUG(2, ("open_directory: unable to create "
4738 "%s. Error was %s\n",
4739 smb_fname_str_dbg(smb_dname),
4740 nt_errstr(status)));
4741 return status;
4744 status = mkdir_internal(conn,
4745 parent_dir_fname,
4746 smb_fname_atname,
4747 smb_dname,
4748 file_attributes,
4749 fsp);
4751 if (!NT_STATUS_IS_OK(status)) {
4752 DEBUG(2, ("open_directory: unable to create "
4753 "%s. Error was %s\n",
4754 smb_fname_str_dbg(smb_dname),
4755 nt_errstr(status)));
4756 return status;
4759 info = FILE_WAS_CREATED;
4760 break;
4762 case FILE_OPEN_IF:
4764 * If directory exists open. If directory doesn't
4765 * exist create.
4768 if (dir_existed) {
4769 status = NT_STATUS_OK;
4770 info = FILE_WAS_OPENED;
4771 } else {
4772 status = mkdir_internal(conn,
4773 parent_dir_fname,
4774 smb_fname_atname,
4775 smb_dname,
4776 file_attributes,
4777 fsp);
4779 if (NT_STATUS_IS_OK(status)) {
4780 info = FILE_WAS_CREATED;
4781 } else {
4782 int ret;
4783 /* Cope with create race. */
4784 if (!NT_STATUS_EQUAL(status,
4785 NT_STATUS_OBJECT_NAME_COLLISION)) {
4786 DEBUG(2, ("open_directory: unable to create "
4787 "%s. Error was %s\n",
4788 smb_fname_str_dbg(smb_dname),
4789 nt_errstr(status)));
4790 return status;
4794 * If mkdir_internal() returned
4795 * NT_STATUS_OBJECT_NAME_COLLISION
4796 * we still must lstat the path.
4798 ret = SMB_VFS_FSTATAT(
4799 conn,
4800 parent_dir_fname->fsp,
4801 smb_fname_atname,
4802 &smb_dname->st,
4803 AT_SYMLINK_NOFOLLOW);
4804 if (ret == -1) {
4805 DEBUG(2, ("Could not stat "
4806 "directory '%s' just "
4807 "opened: %s\n",
4808 smb_fname_str_dbg(
4809 smb_dname),
4810 strerror(errno)));
4811 return map_nt_error_from_unix(
4812 errno);
4815 info = FILE_WAS_OPENED;
4819 break;
4821 case FILE_SUPERSEDE:
4822 case FILE_OVERWRITE:
4823 case FILE_OVERWRITE_IF:
4824 default:
4825 DEBUG(5,("open_directory: invalid create_disposition "
4826 "0x%x for directory %s\n",
4827 (unsigned int)create_disposition,
4828 smb_fname_str_dbg(smb_dname)));
4829 return NT_STATUS_INVALID_PARAMETER;
4832 if(!S_ISDIR(smb_dname->st.st_ex_mode)) {
4833 DEBUG(5,("open_directory: %s is not a directory !\n",
4834 smb_fname_str_dbg(smb_dname)));
4835 return NT_STATUS_NOT_A_DIRECTORY;
4839 * Setup the files_struct for it.
4842 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_dname->st);
4843 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
4844 fsp->file_pid = req ? req->smbpid : 0;
4845 fsp->fsp_flags.can_lock = false;
4846 fsp->fsp_flags.can_read = false;
4847 fsp->fsp_flags.can_write = false;
4849 fh_set_private_options(fsp->fh, 0);
4851 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
4853 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
4854 fsp->print_file = NULL;
4855 fsp->fsp_flags.modified = false;
4856 fsp->oplock_type = NO_OPLOCK;
4857 fsp->sent_oplock_break = NO_BREAK_SENT;
4858 fsp->fsp_flags.is_directory = true;
4859 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
4860 fsp->posix_flags |= FSP_POSIX_FLAGS_ALL;
4863 /* Don't store old timestamps for directory
4864 handles in the internal database. We don't
4865 update them in there if new objects
4866 are created in the directory. Currently
4867 we only update timestamps on file writes.
4868 See bug #9870.
4870 mtimespec = make_omit_timespec();
4873 * Obviously for FILE_LIST_DIRECTORY we need to reopen to get an fd
4874 * usable for reading a directory. SMB2_FLUSH may be called on
4875 * directories opened with FILE_ADD_FILE and FILE_ADD_SUBDIRECTORY so
4876 * for those we need to reopen as well.
4878 need_fd_access =
4879 FILE_LIST_DIRECTORY |
4880 FILE_ADD_FILE |
4881 FILE_ADD_SUBDIRECTORY;
4883 if (access_mask & need_fd_access) {
4884 struct vfs_open_how how = {
4885 .flags = O_RDONLY | O_DIRECTORY,
4887 bool file_created;
4889 status = reopen_from_fsp(fsp->conn->cwd_fsp,
4890 fsp->fsp_name,
4891 fsp,
4892 &how,
4893 &file_created);
4894 if (!NT_STATUS_IS_OK(status)) {
4895 DBG_INFO("Could not open fd for [%s]: %s\n",
4896 smb_fname_str_dbg(smb_dname),
4897 nt_errstr(status));
4898 return status;
4902 status = vfs_stat_fsp(fsp);
4903 if (!NT_STATUS_IS_OK(status)) {
4904 fd_close(fsp);
4905 return status;
4908 if(!S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
4909 DEBUG(5,("open_directory: %s is not a directory !\n",
4910 smb_fname_str_dbg(smb_dname)));
4911 fd_close(fsp);
4912 return NT_STATUS_NOT_A_DIRECTORY;
4915 /* Ensure there was no race condition. We need to check
4916 * dev/inode but not permissions, as these can change
4917 * legitimately */
4918 if (!check_same_dev_ino(&smb_dname->st, &fsp->fsp_name->st)) {
4919 DEBUG(5,("open_directory: stat struct differs for "
4920 "directory %s.\n",
4921 smb_fname_str_dbg(smb_dname)));
4922 fd_close(fsp);
4923 return NT_STATUS_ACCESS_DENIED;
4926 if (info == FILE_WAS_OPENED) {
4927 status = smbd_check_access_rights_fsp(parent_dir_fname->fsp,
4928 fsp,
4929 false,
4930 access_mask);
4931 if (!NT_STATUS_IS_OK(status)) {
4932 DBG_DEBUG("smbd_check_access_rights_fsp on "
4933 "file %s failed with %s\n",
4934 fsp_str_dbg(fsp),
4935 nt_errstr(status));
4936 fd_close(fsp);
4937 return status;
4942 * If we created a new directory or going to delete it later,
4943 * we should keep * the share_mode_lock (g_lock) until we call
4944 * share_mode_entry_prepare_unlock()
4946 if (info != FILE_WAS_OPENED) {
4947 keep_locked = true;
4948 } else if (create_options & FILE_DELETE_ON_CLOSE) {
4949 keep_locked = true;
4952 lck_state = (struct open_ntcreate_lock_state) {
4953 .fsp = fsp,
4954 .object_type = "directory",
4955 .req = req,
4956 .create_disposition = create_disposition,
4957 .access_mask = access_mask,
4958 .share_access = share_access,
4959 .oplock_request = NO_OPLOCK,
4960 .lease = NULL,
4961 .first_open_attempt = true,
4962 .keep_locked = keep_locked,
4965 status = share_mode_entry_prepare_lock_add(&lck_state.prepare_state,
4966 fsp->file_id,
4967 conn->connectpath,
4968 smb_dname,
4969 &mtimespec,
4970 open_ntcreate_lock_add_entry,
4971 &lck_state);
4972 if (!NT_STATUS_IS_OK(status)) {
4973 DBG_ERR("share_mode_entry_prepare_lock_add() failed for %s - %s\n",
4974 smb_fname_str_dbg(smb_dname), nt_errstr(status));
4975 fd_close(fsp);
4976 return status;
4979 status = lck_state.status;
4980 if (!NT_STATUS_IS_OK(status)) {
4981 fd_close(fsp);
4982 return status;
4986 * From here we need to use 'goto unlock;' instead of return !!!
4989 /* For directories the delete on close bit at open time seems
4990 always to be honored on close... See test 19 in Samba4 BASE-DELETE. */
4991 if (create_options & FILE_DELETE_ON_CLOSE) {
4992 status = can_set_delete_on_close(fsp, 0);
4993 if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
4994 lck_state.cleanup_fn =
4995 open_ntcreate_lock_cleanup_entry;
4996 goto unlock;
4999 if (NT_STATUS_IS_OK(status)) {
5000 /* Note that here we set the *initial* delete on close flag,
5001 not the regular one. The magic gets handled in close. */
5002 fsp->fsp_flags.initial_delete_on_close = true;
5007 * Deal with other opens having a modified write time.
5009 if (!is_omit_timespec(&lck_state.write_time)) {
5010 update_stat_ex_mtime(&fsp->fsp_name->st, lck_state.write_time);
5013 if (pinfo) {
5014 *pinfo = info;
5017 status = NT_STATUS_OK;
5019 unlock:
5020 ulstatus = share_mode_entry_prepare_unlock(&lck_state.prepare_state,
5021 lck_state.cleanup_fn,
5022 &lck_state);
5023 if (!NT_STATUS_IS_OK(ulstatus)) {
5024 DBG_ERR("share_mode_entry_prepare_unlock() failed for %s - %s\n",
5025 smb_fname_str_dbg(smb_dname), nt_errstr(ulstatus));
5026 smb_panic("share_mode_entry_prepare_unlock() failed!");
5029 if (!NT_STATUS_IS_OK(status)) {
5030 fd_close(fsp);
5031 return status;
5034 return NT_STATUS_OK;
5037 NTSTATUS create_directory(connection_struct *conn,
5038 struct smb_request *req,
5039 struct files_struct *dirfsp,
5040 struct smb_filename *smb_dname)
5042 NTSTATUS status;
5043 files_struct *fsp;
5045 status = SMB_VFS_CREATE_FILE(
5046 conn, /* conn */
5047 req, /* req */
5048 dirfsp, /* dirfsp */
5049 smb_dname, /* fname */
5050 FILE_READ_ATTRIBUTES, /* access_mask */
5051 FILE_SHARE_NONE, /* share_access */
5052 FILE_CREATE, /* create_disposition*/
5053 FILE_DIRECTORY_FILE, /* create_options */
5054 FILE_ATTRIBUTE_DIRECTORY, /* file_attributes */
5055 0, /* oplock_request */
5056 NULL, /* lease */
5057 0, /* allocation_size */
5058 0, /* private_flags */
5059 NULL, /* sd */
5060 NULL, /* ea_list */
5061 &fsp, /* result */
5062 NULL, /* pinfo */
5063 NULL, NULL); /* create context */
5065 if (NT_STATUS_IS_OK(status)) {
5066 close_file_free(req, &fsp, NORMAL_CLOSE);
5069 return status;
5072 /****************************************************************************
5073 Receive notification that one of our open files has been renamed by another
5074 smbd process.
5075 ****************************************************************************/
5077 void msg_file_was_renamed(struct messaging_context *msg_ctx,
5078 void *private_data,
5079 uint32_t msg_type,
5080 struct server_id src,
5081 DATA_BLOB *data)
5083 struct file_rename_message *msg = NULL;
5084 enum ndr_err_code ndr_err;
5085 files_struct *fsp;
5086 struct smb_filename *smb_fname = NULL;
5087 struct smbd_server_connection *sconn =
5088 talloc_get_type_abort(private_data,
5089 struct smbd_server_connection);
5091 msg = talloc(talloc_tos(), struct file_rename_message);
5092 if (msg == NULL) {
5093 DBG_WARNING("talloc failed\n");
5094 return;
5097 ndr_err = ndr_pull_struct_blob_all(
5098 data,
5099 msg,
5100 msg,
5101 (ndr_pull_flags_fn_t)ndr_pull_file_rename_message);
5102 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
5103 DBG_DEBUG("ndr_pull_oplock_break_message failed: %s\n",
5104 ndr_errstr(ndr_err));
5105 goto out;
5107 if (DEBUGLEVEL >= 10) {
5108 struct server_id_buf buf;
5109 DBG_DEBUG("Got rename message from %s\n",
5110 server_id_str_buf(src, &buf));
5111 NDR_PRINT_DEBUG(file_rename_message, msg);
5114 /* stream_name must always be NULL if there is no stream. */
5115 if ((msg->stream_name != NULL) && (msg->stream_name[0] == '\0')) {
5116 msg->stream_name = NULL;
5119 smb_fname = synthetic_smb_fname(msg,
5120 msg->base_name,
5121 msg->stream_name,
5122 NULL,
5125 if (smb_fname == NULL) {
5126 DBG_DEBUG("synthetic_smb_fname failed\n");
5127 goto out;
5130 fsp = file_find_dif(sconn, msg->id, msg->share_file_id);
5131 if (fsp == NULL) {
5132 DBG_DEBUG("fsp not found\n");
5133 goto out;
5136 if (strcmp(fsp->conn->connectpath, msg->servicepath) == 0) {
5137 SMB_STRUCT_STAT fsp_orig_sbuf;
5138 NTSTATUS status;
5139 DBG_DEBUG("renaming file %s from %s -> %s\n",
5140 fsp_fnum_dbg(fsp),
5141 fsp_str_dbg(fsp),
5142 smb_fname_str_dbg(smb_fname));
5145 * The incoming smb_fname here has an
5146 * invalid stat struct from synthetic_smb_fname()
5147 * above.
5148 * Preserve the existing stat from the
5149 * open fsp after fsp_set_smb_fname()
5150 * overwrites with the invalid stat.
5152 * (We could just copy this into
5153 * smb_fname->st, but keep this code
5154 * identical to the fix in rename_open_files()
5155 * for clarity.
5157 * We will do an fstat before returning
5158 * any of this metadata to the client anyway.
5160 fsp_orig_sbuf = fsp->fsp_name->st;
5161 status = fsp_set_smb_fname(fsp, smb_fname);
5162 if (!NT_STATUS_IS_OK(status)) {
5163 DBG_DEBUG("fsp_set_smb_fname failed: %s\n",
5164 nt_errstr(status));
5166 fsp->fsp_name->st = fsp_orig_sbuf;
5167 } else {
5168 /* TODO. JRA. */
5170 * Now we have the complete path we can work out if
5171 * this is actually within this share and adjust
5172 * newname accordingly.
5174 DBG_DEBUG("share mismatch (sharepath %s not sharepath %s) "
5175 "%s from %s -> %s\n",
5176 fsp->conn->connectpath,
5177 msg->servicepath,
5178 fsp_fnum_dbg(fsp),
5179 fsp_str_dbg(fsp),
5180 smb_fname_str_dbg(smb_fname));
5182 out:
5183 TALLOC_FREE(msg);
5187 * If a main file is opened for delete, all streams need to be checked for
5188 * !FILE_SHARE_DELETE. Do this by opening with DELETE_ACCESS.
5189 * If that works, delete them all by setting the delete on close and close.
5192 static NTSTATUS open_streams_for_delete(connection_struct *conn,
5193 const struct smb_filename *smb_fname)
5195 struct stream_struct *stream_info = NULL;
5196 files_struct **streams = NULL;
5197 int j;
5198 unsigned int i, num_streams = 0;
5199 TALLOC_CTX *frame = talloc_stackframe();
5200 const struct smb_filename *pathref = NULL;
5201 NTSTATUS status;
5203 if (smb_fname->fsp == NULL) {
5204 struct smb_filename *tmp = NULL;
5205 status = synthetic_pathref(frame,
5206 conn->cwd_fsp,
5207 smb_fname->base_name,
5208 NULL,
5209 NULL,
5210 smb_fname->twrp,
5211 smb_fname->flags,
5212 &tmp);
5213 if (!NT_STATUS_IS_OK(status)) {
5214 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
5215 || NT_STATUS_EQUAL(status,
5216 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
5217 DBG_DEBUG("no streams around\n");
5218 TALLOC_FREE(frame);
5219 return NT_STATUS_OK;
5221 DBG_DEBUG("synthetic_pathref failed: %s\n",
5222 nt_errstr(status));
5223 goto fail;
5225 pathref = tmp;
5226 } else {
5227 pathref = smb_fname;
5229 status = vfs_fstreaminfo(pathref->fsp, talloc_tos(),
5230 &num_streams, &stream_info);
5232 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
5233 || NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
5234 DEBUG(10, ("no streams around\n"));
5235 TALLOC_FREE(frame);
5236 return NT_STATUS_OK;
5239 if (!NT_STATUS_IS_OK(status)) {
5240 DEBUG(10, ("vfs_fstreaminfo failed: %s\n",
5241 nt_errstr(status)));
5242 goto fail;
5245 DEBUG(10, ("open_streams_for_delete found %d streams\n",
5246 num_streams));
5248 if (num_streams == 0) {
5249 TALLOC_FREE(frame);
5250 return NT_STATUS_OK;
5253 streams = talloc_array(talloc_tos(), files_struct *, num_streams);
5254 if (streams == NULL) {
5255 DEBUG(0, ("talloc failed\n"));
5256 status = NT_STATUS_NO_MEMORY;
5257 goto fail;
5260 for (i=0; i<num_streams; i++) {
5261 struct smb_filename *smb_fname_cp;
5263 if (strequal(stream_info[i].name, "::$DATA")) {
5264 streams[i] = NULL;
5265 continue;
5268 smb_fname_cp = synthetic_smb_fname(talloc_tos(),
5269 smb_fname->base_name,
5270 stream_info[i].name,
5271 NULL,
5272 smb_fname->twrp,
5273 (smb_fname->flags &
5274 ~SMB_FILENAME_POSIX_PATH));
5275 if (smb_fname_cp == NULL) {
5276 status = NT_STATUS_NO_MEMORY;
5277 goto fail;
5280 status = openat_pathref_fsp(conn->cwd_fsp, smb_fname_cp);
5281 if (!NT_STATUS_IS_OK(status)) {
5282 DBG_DEBUG("Unable to open stream [%s]: %s\n",
5283 smb_fname_str_dbg(smb_fname_cp),
5284 nt_errstr(status));
5285 TALLOC_FREE(smb_fname_cp);
5286 break;
5289 status = SMB_VFS_CREATE_FILE(
5290 conn, /* conn */
5291 NULL, /* req */
5292 NULL, /* dirfsp */
5293 smb_fname_cp, /* fname */
5294 DELETE_ACCESS, /* access_mask */
5295 (FILE_SHARE_READ | /* share_access */
5296 FILE_SHARE_WRITE | FILE_SHARE_DELETE),
5297 FILE_OPEN, /* create_disposition*/
5298 0, /* create_options */
5299 FILE_ATTRIBUTE_NORMAL, /* file_attributes */
5300 0, /* oplock_request */
5301 NULL, /* lease */
5302 0, /* allocation_size */
5303 0, /* private_flags */
5304 NULL, /* sd */
5305 NULL, /* ea_list */
5306 &streams[i], /* result */
5307 NULL, /* pinfo */
5308 NULL, NULL); /* create context */
5310 if (!NT_STATUS_IS_OK(status)) {
5311 DEBUG(10, ("Could not open stream %s: %s\n",
5312 smb_fname_str_dbg(smb_fname_cp),
5313 nt_errstr(status)));
5315 TALLOC_FREE(smb_fname_cp);
5316 break;
5318 TALLOC_FREE(smb_fname_cp);
5322 * don't touch the variable "status" beyond this point :-)
5325 for (j = i-1 ; j >= 0; j--) {
5326 if (streams[j] == NULL) {
5327 continue;
5330 DEBUG(10, ("Closing stream # %d, %s\n", j,
5331 fsp_str_dbg(streams[j])));
5332 close_file_free(NULL, &streams[j], NORMAL_CLOSE);
5335 fail:
5336 TALLOC_FREE(frame);
5337 return status;
5340 /*********************************************************************
5341 Create a default ACL by inheriting from the parent. If no inheritance
5342 from the parent available, don't set anything. This will leave the actual
5343 permissions the new file or directory already got from the filesystem
5344 as the NT ACL when read.
5345 *********************************************************************/
5347 static NTSTATUS inherit_new_acl(files_struct *dirfsp, files_struct *fsp)
5349 TALLOC_CTX *frame = talloc_stackframe();
5350 struct security_descriptor *parent_desc = NULL;
5351 NTSTATUS status = NT_STATUS_OK;
5352 struct security_descriptor *psd = NULL;
5353 const struct dom_sid *owner_sid = NULL;
5354 const struct dom_sid *group_sid = NULL;
5355 uint32_t security_info_sent = (SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL);
5356 struct security_token *token = fsp->conn->session_info->security_token;
5357 bool inherit_owner =
5358 (lp_inherit_owner(SNUM(fsp->conn)) == INHERIT_OWNER_WINDOWS_AND_UNIX);
5359 bool inheritable_components = false;
5360 bool try_builtin_administrators = false;
5361 const struct dom_sid *BA_U_sid = NULL;
5362 const struct dom_sid *BA_G_sid = NULL;
5363 bool try_system = false;
5364 const struct dom_sid *SY_U_sid = NULL;
5365 const struct dom_sid *SY_G_sid = NULL;
5366 size_t size = 0;
5367 bool ok;
5369 status = SMB_VFS_FGET_NT_ACL(dirfsp,
5370 (SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL),
5371 frame,
5372 &parent_desc);
5373 if (!NT_STATUS_IS_OK(status)) {
5374 TALLOC_FREE(frame);
5375 return status;
5378 inheritable_components = sd_has_inheritable_components(parent_desc,
5379 fsp->fsp_flags.is_directory);
5381 if (!inheritable_components && !inherit_owner) {
5382 TALLOC_FREE(frame);
5383 /* Nothing to inherit and not setting owner. */
5384 return NT_STATUS_OK;
5387 /* Create an inherited descriptor from the parent. */
5389 if (DEBUGLEVEL >= 10) {
5390 DEBUG(10,("inherit_new_acl: parent acl for %s is:\n",
5391 fsp_str_dbg(fsp) ));
5392 NDR_PRINT_DEBUG(security_descriptor, parent_desc);
5395 /* Inherit from parent descriptor if "inherit owner" set. */
5396 if (inherit_owner) {
5397 owner_sid = parent_desc->owner_sid;
5398 group_sid = parent_desc->group_sid;
5401 if (owner_sid == NULL) {
5402 if (security_token_has_builtin_administrators(token)) {
5403 try_builtin_administrators = true;
5404 } else if (security_token_is_system(token)) {
5405 try_builtin_administrators = true;
5406 try_system = true;
5410 if (group_sid == NULL &&
5411 token->num_sids == PRIMARY_GROUP_SID_INDEX)
5413 if (security_token_is_system(token)) {
5414 try_builtin_administrators = true;
5415 try_system = true;
5419 if (try_builtin_administrators) {
5420 struct unixid ids = { .id = 0 };
5422 ok = sids_to_unixids(&global_sid_Builtin_Administrators, 1, &ids);
5423 if (ok) {
5424 switch (ids.type) {
5425 case ID_TYPE_BOTH:
5426 BA_U_sid = &global_sid_Builtin_Administrators;
5427 BA_G_sid = &global_sid_Builtin_Administrators;
5428 break;
5429 case ID_TYPE_UID:
5430 BA_U_sid = &global_sid_Builtin_Administrators;
5431 break;
5432 case ID_TYPE_GID:
5433 BA_G_sid = &global_sid_Builtin_Administrators;
5434 break;
5435 default:
5436 break;
5441 if (try_system) {
5442 struct unixid ids = { .id = 0 };
5444 ok = sids_to_unixids(&global_sid_System, 1, &ids);
5445 if (ok) {
5446 switch (ids.type) {
5447 case ID_TYPE_BOTH:
5448 SY_U_sid = &global_sid_System;
5449 SY_G_sid = &global_sid_System;
5450 break;
5451 case ID_TYPE_UID:
5452 SY_U_sid = &global_sid_System;
5453 break;
5454 case ID_TYPE_GID:
5455 SY_G_sid = &global_sid_System;
5456 break;
5457 default:
5458 break;
5463 if (owner_sid == NULL) {
5464 owner_sid = BA_U_sid;
5467 if (owner_sid == NULL) {
5468 owner_sid = SY_U_sid;
5471 if (group_sid == NULL) {
5472 group_sid = SY_G_sid;
5475 if (try_system && group_sid == NULL) {
5476 group_sid = BA_G_sid;
5479 if (owner_sid == NULL) {
5480 owner_sid = &token->sids[PRIMARY_USER_SID_INDEX];
5482 if (group_sid == NULL) {
5483 if (token->num_sids == PRIMARY_GROUP_SID_INDEX) {
5484 group_sid = &token->sids[PRIMARY_USER_SID_INDEX];
5485 } else {
5486 group_sid = &token->sids[PRIMARY_GROUP_SID_INDEX];
5490 status = se_create_child_secdesc(frame,
5491 &psd,
5492 &size,
5493 parent_desc,
5494 owner_sid,
5495 group_sid,
5496 fsp->fsp_flags.is_directory);
5497 if (!NT_STATUS_IS_OK(status)) {
5498 TALLOC_FREE(frame);
5499 return status;
5502 /* If inheritable_components == false,
5503 se_create_child_secdesc()
5504 creates a security descriptor with a NULL dacl
5505 entry, but with SEC_DESC_DACL_PRESENT. We need
5506 to remove that flag. */
5508 if (!inheritable_components) {
5509 security_info_sent &= ~SECINFO_DACL;
5510 psd->type &= ~SEC_DESC_DACL_PRESENT;
5513 if (DEBUGLEVEL >= 10) {
5514 DEBUG(10,("inherit_new_acl: child acl for %s is:\n",
5515 fsp_str_dbg(fsp) ));
5516 NDR_PRINT_DEBUG(security_descriptor, psd);
5519 if (inherit_owner) {
5520 /* We need to be root to force this. */
5521 become_root();
5523 status = SMB_VFS_FSET_NT_ACL(metadata_fsp(fsp),
5524 security_info_sent,
5525 psd);
5526 if (inherit_owner) {
5527 unbecome_root();
5529 TALLOC_FREE(frame);
5530 return status;
5534 * If we already have a lease, it must match the new file id. [MS-SMB2]
5535 * 3.3.5.9.8 speaks about INVALID_PARAMETER if an already used lease key is
5536 * used for a different file name.
5539 struct lease_match_state {
5540 /* Input parameters. */
5541 TALLOC_CTX *mem_ctx;
5542 const char *servicepath;
5543 const struct smb_filename *fname;
5544 bool file_existed;
5545 struct file_id id;
5546 /* Return parameters. */
5547 uint32_t num_file_ids;
5548 struct file_id *ids;
5549 NTSTATUS match_status;
5552 /*************************************************************
5553 File doesn't exist but this lease key+guid is already in use.
5555 This is only allowable in the dynamic share case where the
5556 service path must be different.
5558 There is a small race condition here in the multi-connection
5559 case where a client sends two create calls on different connections,
5560 where the file doesn't exist and one smbd creates the leases_db
5561 entry first, but this will get fixed by the multichannel cleanup
5562 when all identical client_guids get handled by a single smbd.
5563 **************************************************************/
5565 static void lease_match_parser_new_file(
5566 uint32_t num_files,
5567 const struct leases_db_file *files,
5568 struct lease_match_state *state)
5570 uint32_t i;
5572 for (i = 0; i < num_files; i++) {
5573 const struct leases_db_file *f = &files[i];
5574 if (strequal(state->servicepath, f->servicepath)) {
5575 state->match_status = NT_STATUS_INVALID_PARAMETER;
5576 return;
5580 /* Dynamic share case. Break leases on all other files. */
5581 state->match_status = leases_db_copy_file_ids(state->mem_ctx,
5582 num_files,
5583 files,
5584 &state->ids);
5585 if (!NT_STATUS_IS_OK(state->match_status)) {
5586 return;
5589 state->num_file_ids = num_files;
5590 state->match_status = NT_STATUS_OPLOCK_NOT_GRANTED;
5591 return;
5594 static void lease_match_parser(
5595 uint32_t num_files,
5596 const struct leases_db_file *files,
5597 void *private_data)
5599 struct lease_match_state *state =
5600 (struct lease_match_state *)private_data;
5601 uint32_t i;
5603 if (!state->file_existed) {
5605 * Deal with name mismatch or
5606 * possible dynamic share case separately
5607 * to make code clearer.
5609 lease_match_parser_new_file(num_files,
5610 files,
5611 state);
5612 return;
5615 /* File existed. */
5616 state->match_status = NT_STATUS_OK;
5618 for (i = 0; i < num_files; i++) {
5619 const struct leases_db_file *f = &files[i];
5621 /* Everything should be the same. */
5622 if (!file_id_equal(&state->id, &f->id)) {
5624 * The client asked for a lease on a
5625 * file that doesn't match the file_id
5626 * in the database.
5628 * Maybe this is a dynamic share, i.e.
5629 * a share where the servicepath is
5630 * different for different users (e.g.
5631 * the [HOMES] share.
5633 * If the servicepath is different, but the requested
5634 * file name + stream name is the same then this is
5635 * a dynamic share, the client is using the same share
5636 * name and doesn't know that the underlying servicepath
5637 * is different. It was expecting a lease on the
5638 * same file. Return NT_STATUS_OPLOCK_NOT_GRANTED
5639 * to break leases
5641 * Otherwise the client has messed up, or is
5642 * testing our error codes, so return
5643 * NT_STATUS_INVALID_PARAMETER.
5645 if (!strequal(f->servicepath, state->servicepath) &&
5646 strequal(f->base_name, state->fname->base_name) &&
5647 strequal(f->stream_name, state->fname->stream_name))
5650 * Name is the same but servicepath is
5651 * different, dynamic share. Break leases.
5653 state->match_status =
5654 NT_STATUS_OPLOCK_NOT_GRANTED;
5655 } else {
5656 state->match_status =
5657 NT_STATUS_INVALID_PARAMETER;
5659 break;
5661 if (!strequal(f->servicepath, state->servicepath)) {
5662 state->match_status = NT_STATUS_INVALID_PARAMETER;
5663 break;
5665 if (!strequal(f->base_name, state->fname->base_name)) {
5666 state->match_status = NT_STATUS_INVALID_PARAMETER;
5667 break;
5669 if (!strequal(f->stream_name, state->fname->stream_name)) {
5670 state->match_status = NT_STATUS_INVALID_PARAMETER;
5671 break;
5675 if (NT_STATUS_IS_OK(state->match_status)) {
5677 * Common case - just opening another handle on a
5678 * file on a non-dynamic share.
5680 return;
5683 if (NT_STATUS_EQUAL(state->match_status, NT_STATUS_INVALID_PARAMETER)) {
5684 /* Mismatched path. Error back to client. */
5685 return;
5689 * File id mismatch. Dynamic share case NT_STATUS_OPLOCK_NOT_GRANTED.
5690 * Don't allow leases.
5693 state->match_status = leases_db_copy_file_ids(state->mem_ctx,
5694 num_files,
5695 files,
5696 &state->ids);
5697 if (!NT_STATUS_IS_OK(state->match_status)) {
5698 return;
5701 state->num_file_ids = num_files;
5702 state->match_status = NT_STATUS_OPLOCK_NOT_GRANTED;
5703 return;
5706 struct lease_match_break_state {
5707 struct messaging_context *msg_ctx;
5708 const struct smb2_lease_key *lease_key;
5709 struct file_id id;
5711 bool found_lease;
5712 uint16_t version;
5713 uint16_t epoch;
5716 static bool lease_match_break_fn(
5717 struct share_mode_entry *e,
5718 void *private_data)
5720 struct lease_match_break_state *state = private_data;
5721 bool stale, equal;
5722 uint32_t e_lease_type = SMB2_LEASE_NONE;
5723 NTSTATUS status;
5725 stale = share_entry_stale_pid(e);
5726 if (stale) {
5727 return false;
5730 equal = smb2_lease_key_equal(&e->lease_key, state->lease_key);
5731 if (!equal) {
5732 return false;
5735 status = leases_db_get(
5736 &e->client_guid,
5737 &e->lease_key,
5738 &state->id,
5739 &e_lease_type, /* current_state */
5740 NULL, /* breaking */
5741 NULL, /* breaking_to_requested */
5742 NULL, /* breaking_to_required */
5743 &state->version, /* lease_version */
5744 &state->epoch); /* epoch */
5745 if (NT_STATUS_IS_OK(status)) {
5746 state->found_lease = true;
5747 } else {
5748 DBG_WARNING("Could not find version/epoch: %s\n",
5749 nt_errstr(status));
5750 return false;
5753 if (e_lease_type == SMB2_LEASE_NONE) {
5754 return false;
5756 send_break_message(state->msg_ctx, &state->id, e, SMB2_LEASE_NONE);
5759 * Windows 7 and 8 lease clients are broken in that they will
5760 * not respond to lease break requests whilst waiting for an
5761 * outstanding open request on that lease handle on the same
5762 * TCP connection, due to holding an internal inode lock.
5764 * This means we can't reschedule ourselves here, but must
5765 * return from the create.
5767 * Work around:
5769 * Send the breaks and then return SMB2_LEASE_NONE in the
5770 * lease handle to cause them to acknowledge the lease
5771 * break. Consultation with Microsoft engineering confirmed
5772 * this approach is safe.
5775 return false;
5778 static void lease_match_fid_fn(struct share_mode_lock *lck,
5779 void *private_data)
5781 bool ok;
5783 ok = share_mode_forall_leases(lck, lease_match_break_fn, private_data);
5784 if (!ok) {
5785 DBG_DEBUG("share_mode_forall_leases failed\n");
5789 static NTSTATUS lease_match(connection_struct *conn,
5790 struct smb_request *req,
5791 const struct smb2_lease_key *lease_key,
5792 const char *servicepath,
5793 const struct smb_filename *fname,
5794 uint16_t *p_version,
5795 uint16_t *p_epoch)
5797 struct smbd_server_connection *sconn = req->sconn;
5798 TALLOC_CTX *tos = talloc_tos();
5799 struct lease_match_state state = {
5800 .mem_ctx = tos,
5801 .servicepath = servicepath,
5802 .fname = fname,
5803 .match_status = NT_STATUS_OK
5805 uint32_t i;
5806 NTSTATUS status;
5808 state.file_existed = VALID_STAT(fname->st);
5809 if (state.file_existed) {
5810 state.id = vfs_file_id_from_sbuf(conn, &fname->st);
5813 status = leases_db_parse(&sconn->client->global->client_guid,
5814 lease_key, lease_match_parser, &state);
5815 if (!NT_STATUS_IS_OK(status)) {
5817 * Not found or error means okay: We can make the lease pass
5819 return NT_STATUS_OK;
5821 if (!NT_STATUS_EQUAL(state.match_status, NT_STATUS_OPLOCK_NOT_GRANTED)) {
5823 * Anything but NT_STATUS_OPLOCK_NOT_GRANTED, let the caller
5824 * deal with it.
5826 return state.match_status;
5829 /* We have to break all existing leases. */
5830 for (i = 0; i < state.num_file_ids; i++) {
5831 struct lease_match_break_state break_state = {
5832 .msg_ctx = conn->sconn->msg_ctx,
5833 .lease_key = lease_key,
5836 if (file_id_equal(&state.ids[i], &state.id)) {
5837 /* Don't need to break our own file. */
5838 continue;
5841 break_state.id = state.ids[i];
5843 status = share_mode_do_locked_vfs_denied(break_state.id,
5844 lease_match_fid_fn,
5845 &break_state);
5846 if (!NT_STATUS_IS_OK(status)) {
5847 /* Race condition - file already closed. */
5848 continue;
5851 if (break_state.found_lease) {
5852 *p_version = break_state.version;
5853 *p_epoch = break_state.epoch;
5857 * Ensure we don't grant anything more so we
5858 * never upgrade.
5860 return NT_STATUS_OPLOCK_NOT_GRANTED;
5864 * Wrapper around open_file_ntcreate and open_directory
5867 static NTSTATUS create_file_unixpath(connection_struct *conn,
5868 struct smb_request *req,
5869 struct files_struct *dirfsp,
5870 struct smb_filename *smb_fname,
5871 uint32_t access_mask,
5872 uint32_t share_access,
5873 uint32_t create_disposition,
5874 uint32_t create_options,
5875 uint32_t file_attributes,
5876 uint32_t oplock_request,
5877 const struct smb2_lease *lease,
5878 uint64_t allocation_size,
5879 uint32_t private_flags,
5880 struct security_descriptor *sd,
5881 struct ea_list *ea_list,
5883 files_struct **result,
5884 int *pinfo)
5886 struct smb2_lease none_lease;
5887 int info = FILE_WAS_OPENED;
5888 files_struct *base_fsp = NULL;
5889 files_struct *fsp = NULL;
5890 bool free_fsp_on_error = false;
5891 NTSTATUS status;
5892 int ret;
5893 struct smb_filename *parent_dir_fname = NULL;
5894 struct smb_filename *smb_fname_atname = NULL;
5896 DBG_DEBUG("access_mask = 0x%"PRIx32" "
5897 "file_attributes = 0x%"PRIx32" "
5898 "share_access = 0x%"PRIx32" "
5899 "create_disposition = 0x%"PRIx32" "
5900 "create_options = 0x%"PRIx32" "
5901 "oplock_request = 0x%"PRIx32" "
5902 "private_flags = 0x%"PRIx32" "
5903 "ea_list = %p, "
5904 "sd = %p, "
5905 "fname = %s\n",
5906 access_mask,
5907 file_attributes,
5908 share_access,
5909 create_disposition,
5910 create_options,
5911 oplock_request,
5912 private_flags,
5913 ea_list,
5915 smb_fname_str_dbg(smb_fname));
5917 if (create_options & FILE_OPEN_BY_FILE_ID) {
5918 status = NT_STATUS_NOT_SUPPORTED;
5919 goto fail;
5922 if (create_options & NTCREATEX_OPTIONS_INVALID_PARAM_MASK) {
5923 status = NT_STATUS_INVALID_PARAMETER;
5924 goto fail;
5927 if (req == NULL) {
5928 oplock_request |= INTERNAL_OPEN_ONLY;
5931 if (lease != NULL) {
5932 uint16_t epoch = lease->lease_epoch;
5933 uint16_t version = lease->lease_version;
5935 if (req == NULL) {
5936 DBG_WARNING("Got lease on internal open\n");
5937 status = NT_STATUS_INTERNAL_ERROR;
5938 goto fail;
5941 status = lease_match(conn,
5942 req,
5943 &lease->lease_key,
5944 conn->connectpath,
5945 smb_fname,
5946 &version,
5947 &epoch);
5948 if (NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) {
5949 /* Dynamic share file. No leases and update epoch... */
5950 none_lease = *lease;
5951 none_lease.lease_state = SMB2_LEASE_NONE;
5952 none_lease.lease_epoch = epoch;
5953 none_lease.lease_version = version;
5954 lease = &none_lease;
5955 } else if (!NT_STATUS_IS_OK(status)) {
5956 goto fail;
5960 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
5961 && (access_mask & DELETE_ACCESS)
5962 && !is_named_stream(smb_fname)) {
5964 * We can't open a file with DELETE access if any of the
5965 * streams is open without FILE_SHARE_DELETE
5967 status = open_streams_for_delete(conn, smb_fname);
5969 if (!NT_STATUS_IS_OK(status)) {
5970 goto fail;
5974 if (access_mask & SEC_FLAG_SYSTEM_SECURITY) {
5975 bool ok;
5977 ok = security_token_has_privilege(get_current_nttok(conn),
5978 SEC_PRIV_SECURITY);
5979 if (!ok) {
5980 DBG_DEBUG("open on %s failed - "
5981 "SEC_FLAG_SYSTEM_SECURITY denied.\n",
5982 smb_fname_str_dbg(smb_fname));
5983 status = NT_STATUS_PRIVILEGE_NOT_HELD;
5984 goto fail;
5987 if (conn->sconn->using_smb2 &&
5988 (access_mask == SEC_FLAG_SYSTEM_SECURITY))
5991 * No other bits set. Windows SMB2 refuses this.
5992 * See smbtorture3 SMB2-SACL test.
5994 * Note this is an SMB2-only behavior,
5995 * smbtorture3 SMB1-SYSTEM-SECURITY already tests
5996 * that SMB1 allows this.
5998 status = NT_STATUS_ACCESS_DENIED;
5999 goto fail;
6004 * Files or directories can't be opened DELETE_ON_CLOSE without
6005 * delete access.
6006 * BUG: https://bugzilla.samba.org/show_bug.cgi?id=13358
6008 if ((create_options & FILE_DELETE_ON_CLOSE) &&
6009 ((access_mask & DELETE_ACCESS) == 0)) {
6010 status = NT_STATUS_INVALID_PARAMETER;
6011 goto fail;
6014 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
6015 && is_named_stream(smb_fname))
6017 uint32_t base_create_disposition;
6018 struct smb_filename *smb_fname_base = NULL;
6019 uint32_t base_privflags;
6021 if (create_options & FILE_DIRECTORY_FILE) {
6022 DBG_DEBUG("Can't open a stream as directory\n");
6023 status = NT_STATUS_NOT_A_DIRECTORY;
6024 goto fail;
6027 switch (create_disposition) {
6028 case FILE_OPEN:
6029 base_create_disposition = FILE_OPEN;
6030 break;
6031 default:
6032 base_create_disposition = FILE_OPEN_IF;
6033 break;
6036 smb_fname_base = cp_smb_filename_nostream(
6037 talloc_tos(), smb_fname);
6039 if (smb_fname_base == NULL) {
6040 status = NT_STATUS_NO_MEMORY;
6041 goto fail;
6045 * We may be creating the basefile as part of creating the
6046 * stream, so it's legal if the basefile doesn't exist at this
6047 * point, the create_file_unixpath() below will create it. But
6048 * if the basefile exists we want a handle so we can fstat() it.
6051 ret = vfs_stat(conn, smb_fname_base);
6052 if (ret == -1 && errno != ENOENT) {
6053 status = map_nt_error_from_unix(errno);
6054 TALLOC_FREE(smb_fname_base);
6055 goto fail;
6057 if (ret == 0) {
6058 status = openat_pathref_fsp(conn->cwd_fsp,
6059 smb_fname_base);
6060 if (!NT_STATUS_IS_OK(status)) {
6061 DBG_ERR("open_smb_fname_fsp [%s] failed: %s\n",
6062 smb_fname_str_dbg(smb_fname_base),
6063 nt_errstr(status));
6064 TALLOC_FREE(smb_fname_base);
6065 goto fail;
6069 * https://bugzilla.samba.org/show_bug.cgi?id=10229
6070 * We need to check if the requested access mask
6071 * could be used to open the underlying file (if
6072 * it existed), as we're passing in zero for the
6073 * access mask to the base filename.
6075 status = check_base_file_access(smb_fname_base->fsp,
6076 access_mask);
6078 if (!NT_STATUS_IS_OK(status)) {
6079 DEBUG(10, ("Permission check "
6080 "for base %s failed: "
6081 "%s\n", smb_fname->base_name,
6082 nt_errstr(status)));
6083 TALLOC_FREE(smb_fname_base);
6084 goto fail;
6088 base_privflags = NTCREATEX_FLAG_STREAM_BASEOPEN;
6090 /* Open the base file. */
6091 status = create_file_unixpath(conn,
6092 NULL,
6093 dirfsp,
6094 smb_fname_base,
6096 FILE_SHARE_READ
6097 | FILE_SHARE_WRITE
6098 | FILE_SHARE_DELETE,
6099 base_create_disposition,
6103 NULL,
6105 base_privflags,
6106 NULL,
6107 NULL,
6108 &base_fsp,
6109 NULL);
6110 TALLOC_FREE(smb_fname_base);
6112 if (!NT_STATUS_IS_OK(status)) {
6113 DEBUG(10, ("create_file_unixpath for base %s failed: "
6114 "%s\n", smb_fname->base_name,
6115 nt_errstr(status)));
6116 goto fail;
6120 if (smb_fname->fsp != NULL) {
6122 fsp = smb_fname->fsp;
6125 * We're about to use smb_fname->fsp for the fresh open.
6127 * Every fsp passed in via smb_fname->fsp already
6128 * holds a fsp->fsp_name. If it is already this
6129 * fsp->fsp_name that we got passed in as our input
6130 * argument smb_fname, these two are assumed to have
6131 * the same lifetime: Every fsp hangs of "conn", and
6132 * fsp->fsp_name is its talloc child.
6135 if (smb_fname != smb_fname->fsp->fsp_name) {
6137 * "smb_fname" is temporary in this case, but
6138 * the destructor of smb_fname would also tear
6139 * down the fsp we're about to use. Unlink
6140 * them from each other.
6142 smb_fname_fsp_unlink(smb_fname);
6145 * "fsp" is ours now
6147 free_fsp_on_error = true;
6150 status = fsp_bind_smb(fsp, req);
6151 if (!NT_STATUS_IS_OK(status)) {
6152 goto fail;
6155 if (fsp_is_alternate_stream(fsp)) {
6156 struct files_struct *tmp_base_fsp = fsp->base_fsp;
6158 fsp_set_base_fsp(fsp, NULL);
6160 fd_close(tmp_base_fsp);
6161 file_free(NULL, tmp_base_fsp);
6163 } else {
6165 * No fsp passed in that we can use, create one
6167 status = file_new(req, conn, &fsp);
6168 if(!NT_STATUS_IS_OK(status)) {
6169 goto fail;
6171 free_fsp_on_error = true;
6173 status = fsp_set_smb_fname(fsp, smb_fname);
6174 if (!NT_STATUS_IS_OK(status)) {
6175 goto fail;
6179 SMB_ASSERT(fsp->fsp_name->fsp != NULL);
6180 SMB_ASSERT(fsp->fsp_name->fsp == fsp);
6182 if (base_fsp) {
6184 * We're opening the stream element of a
6185 * base_fsp we already opened. Set up the
6186 * base_fsp pointer.
6188 fsp_set_base_fsp(fsp, base_fsp);
6191 if (dirfsp != NULL) {
6192 status = SMB_VFS_PARENT_PATHNAME(
6193 conn,
6194 talloc_tos(),
6195 smb_fname,
6196 &parent_dir_fname,
6197 &smb_fname_atname);
6198 if (!NT_STATUS_IS_OK(status)) {
6199 goto fail;
6201 } else {
6203 * Get a pathref on the parent. We can re-use this for
6204 * multiple calls to check parent ACLs etc. to avoid
6205 * pathname calls.
6207 status = parent_pathref(talloc_tos(),
6208 conn->cwd_fsp,
6209 smb_fname,
6210 &parent_dir_fname,
6211 &smb_fname_atname);
6212 if (!NT_STATUS_IS_OK(status)) {
6213 goto fail;
6216 dirfsp = parent_dir_fname->fsp;
6217 status = fsp_set_smb_fname(dirfsp, parent_dir_fname);
6218 if (!NT_STATUS_IS_OK(status)) {
6219 goto fail;
6224 * If it's a request for a directory open, deal with it separately.
6227 if (create_options & FILE_DIRECTORY_FILE) {
6229 if (create_options & FILE_NON_DIRECTORY_FILE) {
6230 status = NT_STATUS_INVALID_PARAMETER;
6231 goto fail;
6234 /* Can't open a temp directory. IFS kit test. */
6235 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
6236 (file_attributes & FILE_ATTRIBUTE_TEMPORARY)) {
6237 status = NT_STATUS_INVALID_PARAMETER;
6238 goto fail;
6242 * We will get a create directory here if the Win32
6243 * app specified a security descriptor in the
6244 * CreateDirectory() call.
6247 oplock_request = 0;
6248 status = open_directory(conn,
6249 req,
6250 access_mask,
6251 share_access,
6252 create_disposition,
6253 create_options,
6254 file_attributes,
6255 dirfsp->fsp_name,
6256 smb_fname_atname,
6257 &info,
6258 fsp);
6259 } else {
6262 * Ordinary file case.
6265 if (allocation_size) {
6266 fsp->initial_allocation_size = smb_roundup(fsp->conn,
6267 allocation_size);
6270 status = open_file_ntcreate(conn,
6271 req,
6272 access_mask,
6273 share_access,
6274 create_disposition,
6275 create_options,
6276 file_attributes,
6277 oplock_request,
6278 lease,
6279 private_flags,
6280 dirfsp->fsp_name,
6281 smb_fname_atname,
6282 &info,
6283 fsp);
6284 if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
6286 /* A stream open never opens a directory */
6288 if (base_fsp) {
6289 status = NT_STATUS_FILE_IS_A_DIRECTORY;
6290 goto fail;
6294 * Fail the open if it was explicitly a non-directory
6295 * file.
6298 if (create_options & FILE_NON_DIRECTORY_FILE) {
6299 status = NT_STATUS_FILE_IS_A_DIRECTORY;
6300 goto fail;
6303 oplock_request = 0;
6304 status = open_directory(conn,
6305 req,
6306 access_mask,
6307 share_access,
6308 create_disposition,
6309 create_options,
6310 file_attributes,
6311 dirfsp->fsp_name,
6312 smb_fname_atname,
6313 &info,
6314 fsp);
6318 if (!NT_STATUS_IS_OK(status)) {
6319 goto fail;
6322 fsp->fsp_flags.is_fsa = true;
6324 if ((ea_list != NULL) &&
6325 ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN))) {
6326 status = set_ea(conn, fsp, ea_list);
6327 if (!NT_STATUS_IS_OK(status)) {
6328 goto fail;
6332 if (!fsp->fsp_flags.is_directory &&
6333 S_ISDIR(fsp->fsp_name->st.st_ex_mode))
6335 status = NT_STATUS_ACCESS_DENIED;
6336 goto fail;
6339 /* Save the requested allocation size. */
6340 if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
6341 if ((allocation_size > (uint64_t)fsp->fsp_name->st.st_ex_size)
6342 && !(fsp->fsp_flags.is_directory))
6344 fsp->initial_allocation_size = smb_roundup(
6345 fsp->conn, allocation_size);
6346 if (vfs_allocate_file_space(
6347 fsp, fsp->initial_allocation_size) == -1) {
6348 status = NT_STATUS_DISK_FULL;
6349 goto fail;
6351 } else {
6352 fsp->initial_allocation_size = smb_roundup(
6353 fsp->conn, (uint64_t)fsp->fsp_name->st.st_ex_size);
6355 } else {
6356 fsp->initial_allocation_size = 0;
6359 if ((info == FILE_WAS_CREATED) &&
6360 lp_nt_acl_support(SNUM(conn)) &&
6361 !fsp_is_alternate_stream(fsp)) {
6362 if (sd != NULL) {
6364 * According to the MS documentation, the only time the security
6365 * descriptor is applied to the opened file is iff we *created* the
6366 * file; an existing file stays the same.
6368 * Also, it seems (from observation) that you can open the file with
6369 * any access mask but you can still write the sd. We need to override
6370 * the granted access before we call set_sd
6371 * Patch for bug #2242 from Tom Lackemann <cessnatomny@yahoo.com>.
6374 uint32_t sec_info_sent;
6375 uint32_t saved_access_mask = fsp->access_mask;
6377 sec_info_sent = get_sec_info(sd);
6379 fsp->access_mask = FILE_GENERIC_ALL;
6381 if (sec_info_sent & (SECINFO_OWNER|
6382 SECINFO_GROUP|
6383 SECINFO_DACL|
6384 SECINFO_SACL)) {
6385 status = set_sd(fsp, sd, sec_info_sent);
6388 fsp->access_mask = saved_access_mask;
6390 if (!NT_STATUS_IS_OK(status)) {
6391 goto fail;
6393 } else if (lp_inherit_acls(SNUM(conn))) {
6394 /* Inherit from parent. Errors here are not fatal. */
6395 status = inherit_new_acl(dirfsp, fsp);
6396 if (!NT_STATUS_IS_OK(status)) {
6397 DEBUG(10,("inherit_new_acl: failed for %s with %s\n",
6398 fsp_str_dbg(fsp),
6399 nt_errstr(status) ));
6404 if ((conn->fs_capabilities & FILE_FILE_COMPRESSION)
6405 && (create_options & FILE_NO_COMPRESSION)
6406 && (info == FILE_WAS_CREATED)) {
6407 status = SMB_VFS_SET_COMPRESSION(conn, fsp, fsp,
6408 COMPRESSION_FORMAT_NONE);
6409 if (!NT_STATUS_IS_OK(status)) {
6410 DEBUG(1, ("failed to disable compression: %s\n",
6411 nt_errstr(status)));
6415 DEBUG(10, ("create_file_unixpath: info=%d\n", info));
6417 *result = fsp;
6418 if (pinfo != NULL) {
6419 *pinfo = info;
6422 smb_fname->st = fsp->fsp_name->st;
6424 TALLOC_FREE(parent_dir_fname);
6426 return NT_STATUS_OK;
6428 fail:
6429 DEBUG(10, ("create_file_unixpath: %s\n", nt_errstr(status)));
6431 if (fsp != NULL) {
6433 * The close_file below will close
6434 * fsp->base_fsp.
6436 base_fsp = NULL;
6437 close_file_smb(req, fsp, ERROR_CLOSE);
6438 if (free_fsp_on_error) {
6439 file_free(req, fsp);
6440 fsp = NULL;
6443 if (base_fsp != NULL) {
6444 close_file_free(req, &base_fsp, ERROR_CLOSE);
6447 TALLOC_FREE(parent_dir_fname);
6449 return status;
6452 NTSTATUS create_file_default(connection_struct *conn,
6453 struct smb_request *req,
6454 struct files_struct *dirfsp,
6455 struct smb_filename *smb_fname,
6456 uint32_t access_mask,
6457 uint32_t share_access,
6458 uint32_t create_disposition,
6459 uint32_t create_options,
6460 uint32_t file_attributes,
6461 uint32_t oplock_request,
6462 const struct smb2_lease *lease,
6463 uint64_t allocation_size,
6464 uint32_t private_flags,
6465 struct security_descriptor *sd,
6466 struct ea_list *ea_list,
6467 files_struct **result,
6468 int *pinfo,
6469 const struct smb2_create_blobs *in_context_blobs,
6470 struct smb2_create_blobs *out_context_blobs)
6472 int info = FILE_WAS_OPENED;
6473 files_struct *fsp = NULL;
6474 NTSTATUS status;
6475 bool stream_name = false;
6476 struct smb2_create_blob *posx = NULL;
6478 DBG_DEBUG("access_mask = 0x%" PRIu32
6479 " file_attributes = 0x%" PRIu32
6480 " share_access = 0x%" PRIu32
6481 " create_disposition = 0x%" PRIu32
6482 " create_options = 0x%" PRIu32
6483 " oplock_request = 0x%" PRIu32
6484 " private_flags = 0x%" PRIu32
6485 " ea_list = %p, sd = %p, fname = %s\n",
6486 access_mask,
6487 file_attributes,
6488 share_access,
6489 create_disposition,
6490 create_options,
6491 oplock_request,
6492 private_flags,
6493 ea_list,
6495 smb_fname_str_dbg(smb_fname));
6497 if (req != NULL) {
6499 * Remember the absolute time of the original request
6500 * with this mid. We'll use it later to see if this
6501 * has timed out.
6503 get_deferred_open_message_state(req, &req->request_time, NULL);
6507 * Check to see if this is a mac fork of some kind.
6510 stream_name = is_ntfs_stream_smb_fname(smb_fname);
6511 if (stream_name) {
6512 enum FAKE_FILE_TYPE fake_file_type;
6514 fake_file_type = is_fake_file(smb_fname);
6516 if (req != NULL && fake_file_type != FAKE_FILE_TYPE_NONE) {
6519 * Here we go! support for changing the disk quotas
6520 * --metze
6522 * We need to fake up to open this MAGIC QUOTA file
6523 * and return a valid FID.
6525 * w2k close this file directly after opening xp
6526 * also tries a QUERY_FILE_INFO on the file and then
6527 * close it
6529 status = open_fake_file(req, conn, req->vuid,
6530 fake_file_type, smb_fname,
6531 access_mask, &fsp);
6532 if (!NT_STATUS_IS_OK(status)) {
6533 goto fail;
6536 ZERO_STRUCT(smb_fname->st);
6537 goto done;
6540 if (!(conn->fs_capabilities & FILE_NAMED_STREAMS)) {
6541 status = NT_STATUS_OBJECT_NAME_INVALID;
6542 goto fail;
6546 if (is_ntfs_default_stream_smb_fname(smb_fname)) {
6547 int ret;
6548 /* We have to handle this error here. */
6549 if (create_options & FILE_DIRECTORY_FILE) {
6550 status = NT_STATUS_NOT_A_DIRECTORY;
6551 goto fail;
6553 ret = vfs_stat(conn, smb_fname);
6554 if (ret == 0 && VALID_STAT_OF_DIR(smb_fname->st)) {
6555 status = NT_STATUS_FILE_IS_A_DIRECTORY;
6556 goto fail;
6560 posx = smb2_create_blob_find(
6561 in_context_blobs, SMB2_CREATE_TAG_POSIX);
6562 if (posx != NULL) {
6563 uint32_t wire_mode_bits = 0;
6564 mode_t mode_bits = 0;
6565 SMB_STRUCT_STAT sbuf = { 0 };
6566 enum perm_type ptype =
6567 (create_options & FILE_DIRECTORY_FILE) ?
6568 PERM_NEW_DIR : PERM_NEW_FILE;
6570 if (posx->data.length != 4) {
6571 status = NT_STATUS_INVALID_PARAMETER;
6572 goto fail;
6575 wire_mode_bits = IVAL(posx->data.data, 0);
6576 status = unix_perms_from_wire(
6577 conn, &sbuf, wire_mode_bits, ptype, &mode_bits);
6578 if (!NT_STATUS_IS_OK(status)) {
6579 goto fail;
6582 * Remove type info from mode, leaving only the
6583 * permissions and setuid/gid bits.
6585 mode_bits &= ~S_IFMT;
6587 file_attributes = (FILE_FLAG_POSIX_SEMANTICS | mode_bits);
6590 status = create_file_unixpath(conn,
6591 req,
6592 dirfsp,
6593 smb_fname,
6594 access_mask,
6595 share_access,
6596 create_disposition,
6597 create_options,
6598 file_attributes,
6599 oplock_request,
6600 lease,
6601 allocation_size,
6602 private_flags,
6604 ea_list,
6605 &fsp,
6606 &info);
6607 if (!NT_STATUS_IS_OK(status)) {
6608 goto fail;
6611 done:
6612 DEBUG(10, ("create_file: info=%d\n", info));
6614 *result = fsp;
6615 if (pinfo != NULL) {
6616 *pinfo = info;
6618 return NT_STATUS_OK;
6620 fail:
6621 DEBUG(10, ("create_file: %s\n", nt_errstr(status)));
6623 if (fsp != NULL) {
6624 close_file_free(req, &fsp, ERROR_CLOSE);
6626 return status;