vfs_gpfs: Move call to load GPFS library
[Samba.git] / source3 / smbd / open.c
blobda0498f9e7dccea9589388529823dce1ba54a828
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 compatibilty 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 (IS_DOS_READONLY(dosattrs)) {
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);
783 } else {
784 ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st);
787 if (ret == -1) {
788 status = map_nt_error_from_unix(errno);
789 DBG_DEBUG("fstat[at](%s) failed: %s\n",
790 smb_fname_str_dbg(smb_fname),
791 strerror(errno));
792 goto out;
795 fsp->fsp_flags.is_directory = S_ISDIR(fsp->fsp_name->st.st_ex_mode);
796 orig_fsp_name->st = fsp->fsp_name->st;
798 if (!S_ISLNK(fsp->fsp_name->st.st_ex_mode)) {
799 goto out;
803 * Found a symlink to follow in user space
806 if (fsp->fsp_name->flags & SMB_FILENAME_POSIX_PATH) {
807 /* Never follow symlinks on posix open. */
808 status = NT_STATUS_STOPPED_ON_SYMLINK;
809 goto out;
811 if (!lp_follow_symlinks(SNUM(conn))) {
812 /* Explicitly no symlinks. */
813 status = NT_STATUS_STOPPED_ON_SYMLINK;
814 goto out;
817 link_depth += 1;
818 if (link_depth >= 40) {
819 status = NT_STATUS_STOPPED_ON_SYMLINK;
820 goto out;
823 fsp->fsp_name = orig_fsp_name;
825 status = symlink_target_below_conn(
826 talloc_tos(),
827 connpath,
828 connpath_len,
829 fsp,
830 discard_const_p(files_struct, dirfsp),
831 smb_fname_rel,
832 &target);
834 if (!NT_STATUS_IS_OK(status)) {
835 DBG_DEBUG("symlink_target_below_conn() failed: %s\n",
836 nt_errstr(status));
837 goto out;
841 * Close what openat(O_PATH) potentially left behind
843 fd_close(fsp);
845 if (smb_fname->base_name != orig_smb_fname_base) {
846 TALLOC_FREE(smb_fname->base_name);
848 smb_fname->base_name = target;
850 if (oldwd_fname != NULL) {
851 ret = vfs_ChDir(conn, oldwd_fname);
852 if (ret == -1) {
853 smb_panic("unable to get back to old directory\n");
855 TALLOC_FREE(oldwd_fname);
859 * And do it all again... As smb_fname is not relative to the passed in
860 * dirfsp anymore, we pass conn->cwd_fsp as dirfsp to
861 * non_widelink_open() to trigger the chdir(parentdir) logic.
863 dirfsp = conn->cwd_fsp;
865 goto again;
867 out:
868 fsp->fsp_name = orig_fsp_name;
869 smb_fname->base_name = orig_smb_fname_base;
871 TALLOC_FREE(parent_dir_fname);
873 if (!NT_STATUS_IS_OK(status)) {
874 fd_close(fsp);
877 if (oldwd_fname != NULL) {
878 ret = vfs_ChDir(conn, oldwd_fname);
879 if (ret == -1) {
880 smb_panic("unable to get back to old directory\n");
882 TALLOC_FREE(oldwd_fname);
884 return status;
887 /****************************************************************************
888 fd support routines - attempt to do a dos_open.
889 ****************************************************************************/
891 NTSTATUS fd_openat(const struct files_struct *dirfsp,
892 struct smb_filename *smb_fname,
893 files_struct *fsp,
894 const struct vfs_open_how *_how)
896 struct vfs_open_how how = *_how;
897 struct connection_struct *conn = fsp->conn;
898 NTSTATUS status = NT_STATUS_OK;
899 bool fsp_is_stream = fsp_is_alternate_stream(fsp);
900 bool smb_fname_is_stream = is_named_stream(smb_fname);
902 SMB_ASSERT(fsp_is_stream == smb_fname_is_stream);
905 * Never follow symlinks on a POSIX client. The
906 * client should be doing this.
909 if ((fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) || !lp_follow_symlinks(SNUM(conn))) {
910 how.flags |= O_NOFOLLOW;
913 if (fsp_is_stream) {
914 int fd;
916 fd = SMB_VFS_OPENAT(
917 conn,
918 NULL, /* stream open is relative to fsp->base_fsp */
919 smb_fname,
920 fsp,
921 &how);
922 if (fd == -1) {
923 status = map_nt_error_from_unix(errno);
925 fsp_set_fd(fsp, fd);
927 if (fd != -1) {
928 status = vfs_stat_fsp(fsp);
929 if (!NT_STATUS_IS_OK(status)) {
930 DBG_DEBUG("vfs_stat_fsp failed: %s\n",
931 nt_errstr(status));
932 fd_close(fsp);
936 return status;
940 * Only follow symlinks within a share
941 * definition.
943 status = non_widelink_open(dirfsp, fsp, smb_fname, &how);
944 if (!NT_STATUS_IS_OK(status)) {
945 if (NT_STATUS_EQUAL(status, NT_STATUS_TOO_MANY_OPENED_FILES)) {
946 static time_t last_warned = 0L;
948 if (time((time_t *) NULL) > last_warned) {
949 DEBUG(0,("Too many open files, unable "
950 "to open more! smbd's max "
951 "open files = %d\n",
952 lp_max_open_files()));
953 last_warned = time((time_t *) NULL);
957 DBG_DEBUG("name %s, flags = 0%o mode = 0%o, fd = %d. %s\n",
958 smb_fname_str_dbg(smb_fname),
959 how.flags,
960 (int)how.mode,
961 fsp_get_pathref_fd(fsp),
962 nt_errstr(status));
963 return status;
966 DBG_DEBUG("name %s, flags = 0%o mode = 0%o, fd = %d\n",
967 smb_fname_str_dbg(smb_fname),
968 how.flags,
969 (int)how.mode,
970 fsp_get_pathref_fd(fsp));
972 return status;
975 /****************************************************************************
976 Close the file associated with a fsp.
977 ****************************************************************************/
979 NTSTATUS fd_close(files_struct *fsp)
981 NTSTATUS status;
982 int ret;
984 if (fsp == fsp->conn->cwd_fsp) {
985 return NT_STATUS_OK;
988 if (fsp->fsp_flags.fstat_before_close) {
989 status = vfs_stat_fsp(fsp);
990 if (!NT_STATUS_IS_OK(status)) {
991 return status;
995 if (fsp->dptr) {
996 dptr_CloseDir(fsp);
998 if (fsp_get_pathref_fd(fsp) == -1) {
1000 * Either a directory where the dptr_CloseDir() already closed
1001 * the fd or a stat open.
1003 return NT_STATUS_OK;
1005 if (fh_get_refcount(fsp->fh) > 1) {
1006 return NT_STATUS_OK; /* Shared handle. Only close last reference. */
1009 ret = SMB_VFS_CLOSE(fsp);
1010 fsp_set_fd(fsp, -1);
1011 if (ret == -1) {
1012 return map_nt_error_from_unix(errno);
1014 return NT_STATUS_OK;
1017 /****************************************************************************
1018 Change the ownership of a file to that of the parent directory.
1019 Do this by fd if possible.
1020 ****************************************************************************/
1022 static void change_file_owner_to_parent_fsp(struct files_struct *parent_fsp,
1023 struct files_struct *fsp)
1025 int ret;
1027 if (parent_fsp->fsp_name->st.st_ex_uid == fsp->fsp_name->st.st_ex_uid) {
1028 /* Already this uid - no need to change. */
1029 DBG_DEBUG("file %s is already owned by uid %u\n",
1030 fsp_str_dbg(fsp),
1031 (unsigned int)fsp->fsp_name->st.st_ex_uid);
1032 return;
1035 become_root();
1036 ret = SMB_VFS_FCHOWN(fsp,
1037 parent_fsp->fsp_name->st.st_ex_uid,
1038 (gid_t)-1);
1039 unbecome_root();
1040 if (ret == -1) {
1041 DBG_ERR("failed to fchown "
1042 "file %s to parent directory uid %u. Error "
1043 "was %s\n",
1044 fsp_str_dbg(fsp),
1045 (unsigned int)parent_fsp->fsp_name->st.st_ex_uid,
1046 strerror(errno));
1047 } else {
1048 DBG_DEBUG("changed new file %s to "
1049 "parent directory uid %u.\n",
1050 fsp_str_dbg(fsp),
1051 (unsigned int)parent_fsp->fsp_name->st.st_ex_uid);
1052 /* Ensure the uid entry is updated. */
1053 fsp->fsp_name->st.st_ex_uid =
1054 parent_fsp->fsp_name->st.st_ex_uid;
1058 static NTSTATUS change_dir_owner_to_parent_fsp(struct files_struct *parent_fsp,
1059 struct files_struct *fsp)
1061 NTSTATUS status;
1062 int ret;
1064 if (parent_fsp->fsp_name->st.st_ex_uid == fsp->fsp_name->st.st_ex_uid) {
1065 /* Already this uid - no need to change. */
1066 DBG_DEBUG("directory %s is already owned by uid %u\n",
1067 fsp_str_dbg(fsp),
1068 (unsigned int)fsp->fsp_name->st.st_ex_uid);
1069 return NT_STATUS_OK;
1072 become_root();
1073 ret = SMB_VFS_FCHOWN(fsp,
1074 parent_fsp->fsp_name->st.st_ex_uid,
1075 (gid_t)-1);
1076 unbecome_root();
1077 if (ret == -1) {
1078 status = map_nt_error_from_unix(errno);
1079 DBG_ERR("failed to chown "
1080 "directory %s to parent directory uid %u. "
1081 "Error was %s\n",
1082 fsp_str_dbg(fsp),
1083 (unsigned int)parent_fsp->fsp_name->st.st_ex_uid,
1084 nt_errstr(status));
1085 return status;
1088 DBG_DEBUG("changed ownership of new "
1089 "directory %s to parent directory uid %u.\n",
1090 fsp_str_dbg(fsp),
1091 (unsigned int)parent_fsp->fsp_name->st.st_ex_uid);
1093 /* Ensure the uid entry is updated. */
1094 fsp->fsp_name->st.st_ex_uid = parent_fsp->fsp_name->st.st_ex_uid;
1096 return NT_STATUS_OK;
1099 /****************************************************************************
1100 Open a file - returning a guaranteed ATOMIC indication of if the
1101 file was created or not.
1102 ****************************************************************************/
1104 static NTSTATUS fd_open_atomic(struct files_struct *dirfsp,
1105 struct smb_filename *smb_fname,
1106 files_struct *fsp,
1107 int flags,
1108 mode_t mode,
1109 bool *file_created)
1111 struct vfs_open_how how = { .flags = flags, .mode = mode, };
1112 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
1113 NTSTATUS retry_status;
1114 bool file_existed = VALID_STAT(smb_fname->st);
1116 if (!(how.flags & O_CREAT)) {
1118 * We're not creating the file, just pass through.
1120 status = fd_openat(dirfsp, smb_fname, fsp, &how);
1121 *file_created = false;
1122 return status;
1125 if (how.flags & O_EXCL) {
1127 * Fail if already exists, just pass through.
1129 status = fd_openat(dirfsp, smb_fname, fsp, &how);
1132 * Here we've opened with O_CREAT|O_EXCL. If that went
1133 * NT_STATUS_OK, we *know* we created this file.
1135 *file_created = NT_STATUS_IS_OK(status);
1137 return status;
1141 * Now it gets tricky. We have O_CREAT, but not O_EXCL.
1142 * To know absolutely if we created the file or not,
1143 * we can never call O_CREAT without O_EXCL. So if
1144 * we think the file existed, try without O_CREAT|O_EXCL.
1145 * If we think the file didn't exist, try with
1146 * O_CREAT|O_EXCL.
1148 * The big problem here is dangling symlinks. Opening
1149 * without O_NOFOLLOW means both bad symlink
1150 * and missing path return -1, ENOENT from open(). As POSIX
1151 * is pathname based it's not possible to tell
1152 * the difference between these two cases in a
1153 * non-racy way, so change to try only two attempts before
1154 * giving up.
1156 * We don't have this problem for the O_NOFOLLOW
1157 * case as it just returns NT_STATUS_OBJECT_PATH_NOT_FOUND
1158 * mapped from the ELOOP POSIX error.
1161 if (file_existed) {
1162 how.flags = flags & ~(O_CREAT);
1163 retry_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
1164 } else {
1165 how.flags = flags | O_EXCL;
1166 retry_status = NT_STATUS_OBJECT_NAME_COLLISION;
1169 status = fd_openat(dirfsp, smb_fname, fsp, &how);
1170 if (NT_STATUS_IS_OK(status)) {
1171 *file_created = !file_existed;
1172 return NT_STATUS_OK;
1174 if (NT_STATUS_EQUAL(status, retry_status)) {
1176 file_existed = !file_existed;
1178 DBG_DEBUG("File %s %s. Retry.\n",
1179 fsp_str_dbg(fsp),
1180 file_existed ? "existed" : "did not exist");
1182 if (file_existed) {
1183 how.flags = flags & ~(O_CREAT);
1184 } else {
1185 how.flags = flags | O_EXCL;
1188 status = fd_openat(dirfsp, smb_fname, fsp, &how);
1191 *file_created = (NT_STATUS_IS_OK(status) && !file_existed);
1192 return status;
1195 static NTSTATUS reopen_from_procfd(struct files_struct *fsp,
1196 int flags,
1197 mode_t mode)
1199 struct vfs_open_how how = { .flags = flags, .mode = mode };
1200 struct smb_filename proc_fname;
1201 const char *p = NULL;
1202 char buf[PATH_MAX];
1203 int old_fd;
1204 int new_fd;
1205 NTSTATUS status;
1207 if (!fsp->fsp_flags.have_proc_fds) {
1208 return NT_STATUS_MORE_PROCESSING_REQUIRED;
1211 old_fd = fsp_get_pathref_fd(fsp);
1212 if (old_fd == -1) {
1213 return NT_STATUS_MORE_PROCESSING_REQUIRED;
1216 if (!fsp->fsp_flags.is_pathref) {
1217 DBG_ERR("[%s] is not a pathref\n",
1218 fsp_str_dbg(fsp));
1219 #ifdef DEVELOPER
1220 smb_panic("Not a pathref");
1221 #endif
1222 return NT_STATUS_INVALID_HANDLE;
1225 p = sys_proc_fd_path(old_fd, buf, sizeof(buf));
1226 if (p == NULL) {
1227 return NT_STATUS_NO_MEMORY;
1230 proc_fname = (struct smb_filename) {
1231 .base_name = discard_const_p(char, p),
1234 fsp->fsp_flags.is_pathref = false;
1236 new_fd = SMB_VFS_OPENAT(fsp->conn,
1237 fsp->conn->cwd_fsp,
1238 &proc_fname,
1239 fsp,
1240 &how);
1241 if (new_fd == -1) {
1242 status = map_nt_error_from_unix(errno);
1243 fd_close(fsp);
1244 return status;
1247 status = fd_close(fsp);
1248 if (!NT_STATUS_IS_OK(status)) {
1249 return status;
1252 fsp_set_fd(fsp, new_fd);
1253 return NT_STATUS_OK;
1256 static NTSTATUS reopen_from_fsp(struct files_struct *dirfsp,
1257 struct smb_filename *smb_fname,
1258 struct files_struct *fsp,
1259 int flags,
1260 mode_t mode,
1261 bool *p_file_created)
1263 bool __unused_file_created = false;
1264 NTSTATUS status;
1266 if (p_file_created == NULL) {
1267 p_file_created = &__unused_file_created;
1271 * TODO: should we move this to the VFS layer?
1272 * SMB_VFS_REOPEN_FSP()?
1275 status = reopen_from_procfd(fsp,
1276 flags,
1277 mode);
1278 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1279 return status;
1283 * Close the existing pathref fd and set the fsp flag
1284 * is_pathref to false so we get a "normal" fd this time.
1286 status = fd_close(fsp);
1287 if (!NT_STATUS_IS_OK(status)) {
1288 return status;
1291 fsp->fsp_flags.is_pathref = false;
1293 status = fd_open_atomic(
1294 dirfsp,
1295 smb_fname,
1296 fsp,
1297 flags,
1298 mode,
1299 p_file_created);
1300 return status;
1303 /****************************************************************************
1304 Open a file.
1305 ****************************************************************************/
1307 static NTSTATUS open_file(struct smb_request *req,
1308 struct files_struct *dirfsp,
1309 struct smb_filename *smb_fname_atname,
1310 files_struct *fsp,
1311 int flags,
1312 mode_t unx_mode,
1313 uint32_t access_mask, /* client requested access mask. */
1314 uint32_t open_access_mask, /* what we're actually using in the open. */
1315 uint32_t private_flags,
1316 bool *p_file_created)
1318 connection_struct *conn = fsp->conn;
1319 struct smb_filename *smb_fname = fsp->fsp_name;
1320 NTSTATUS status = NT_STATUS_OK;
1321 int accmode = (flags & O_ACCMODE);
1322 int local_flags = flags;
1323 bool file_existed = VALID_STAT(fsp->fsp_name->st);
1324 const uint32_t need_fd_mask =
1325 FILE_READ_DATA |
1326 FILE_WRITE_DATA |
1327 FILE_APPEND_DATA |
1328 FILE_EXECUTE |
1329 SEC_FLAG_SYSTEM_SECURITY;
1330 bool creating = !file_existed && (flags & O_CREAT);
1331 bool truncating = (flags & O_TRUNC);
1332 bool open_fd = false;
1333 bool posix_open = (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN);
1336 * Catch early an attempt to open an existing
1337 * directory as a file.
1339 if (file_existed && S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
1340 return NT_STATUS_FILE_IS_A_DIRECTORY;
1343 /* Check permissions */
1346 * This code was changed after seeing a client open request
1347 * containing the open mode of (DENY_WRITE/read-only) with
1348 * the 'create if not exist' bit set. The previous code
1349 * would fail to open the file read only on a read-only share
1350 * as it was checking the flags parameter directly against O_RDONLY,
1351 * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
1352 * JRA.
1355 if (!CAN_WRITE(conn)) {
1356 /* It's a read-only share - fail if we wanted to write. */
1357 if(accmode != O_RDONLY || (flags & O_TRUNC) || (flags & O_APPEND)) {
1358 DEBUG(3,("Permission denied opening %s\n",
1359 smb_fname_str_dbg(smb_fname)));
1360 return NT_STATUS_ACCESS_DENIED;
1362 if (flags & O_CREAT) {
1363 /* We don't want to write - but we must make sure that
1364 O_CREAT doesn't create the file if we have write
1365 access into the directory.
1367 flags &= ~(O_CREAT|O_EXCL);
1368 local_flags &= ~(O_CREAT|O_EXCL);
1373 * This little piece of insanity is inspired by the
1374 * fact that an NT client can open a file for O_RDONLY,
1375 * but set the create disposition to FILE_EXISTS_TRUNCATE.
1376 * If the client *can* write to the file, then it expects to
1377 * truncate the file, even though it is opening for readonly.
1378 * Quicken uses this stupid trick in backup file creation...
1379 * Thanks *greatly* to "David W. Chapman Jr." <dwcjr@inethouston.net>
1380 * for helping track this one down. It didn't bite us in 2.0.x
1381 * as we always opened files read-write in that release. JRA.
1384 if ((accmode == O_RDONLY) && ((flags & O_TRUNC) == O_TRUNC)) {
1385 DEBUG(10,("open_file: truncate requested on read-only open "
1386 "for file %s\n", smb_fname_str_dbg(smb_fname)));
1387 local_flags = (flags & ~O_ACCMODE)|O_RDWR;
1390 if ((open_access_mask & need_fd_mask) || creating || truncating) {
1391 open_fd = true;
1394 if (open_fd) {
1395 const char *wild;
1396 int ret;
1398 #if defined(O_NONBLOCK) && defined(S_ISFIFO)
1400 * We would block on opening a FIFO with no one else on the
1401 * other end. Do what we used to do and add O_NONBLOCK to the
1402 * open flags. JRA.
1405 if (file_existed && S_ISFIFO(smb_fname->st.st_ex_mode)) {
1406 local_flags &= ~O_TRUNC; /* Can't truncate a FIFO. */
1407 local_flags |= O_NONBLOCK;
1408 truncating = false;
1410 #endif
1412 /* Don't create files with Microsoft wildcard characters. */
1413 if (fsp_is_alternate_stream(fsp)) {
1415 * wildcard characters are allowed in stream names
1416 * only test the basefilename
1418 wild = fsp->base_fsp->fsp_name->base_name;
1419 } else {
1420 wild = smb_fname->base_name;
1422 if ((local_flags & O_CREAT) && !file_existed &&
1423 !(fsp->posix_flags & FSP_POSIX_FLAGS_PATHNAMES) &&
1424 ms_has_wild(wild)) {
1425 return NT_STATUS_OBJECT_NAME_INVALID;
1428 /* Can we access this file ? */
1429 if (!fsp_is_alternate_stream(fsp)) {
1430 /* Only do this check on non-stream open. */
1431 if (file_existed) {
1432 status = smbd_check_access_rights_fsp(
1433 dirfsp,
1434 fsp,
1435 false,
1436 access_mask);
1438 if (!NT_STATUS_IS_OK(status)) {
1439 DBG_DEBUG("smbd_check_access_rights_fsp"
1440 " on file %s returned %s\n",
1441 fsp_str_dbg(fsp),
1442 nt_errstr(status));
1445 if (!NT_STATUS_IS_OK(status) &&
1446 !NT_STATUS_EQUAL(status,
1447 NT_STATUS_OBJECT_NAME_NOT_FOUND))
1449 return status;
1452 if (NT_STATUS_EQUAL(status,
1453 NT_STATUS_OBJECT_NAME_NOT_FOUND))
1455 DEBUG(10, ("open_file: "
1456 "file %s vanished since we "
1457 "checked for existence.\n",
1458 smb_fname_str_dbg(smb_fname)));
1459 file_existed = false;
1460 SET_STAT_INVALID(fsp->fsp_name->st);
1464 if (!file_existed) {
1465 if (!(local_flags & O_CREAT)) {
1466 /* File didn't exist and no O_CREAT. */
1467 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1470 status = check_parent_access_fsp(
1471 dirfsp,
1472 SEC_DIR_ADD_FILE);
1473 if (!NT_STATUS_IS_OK(status)) {
1474 DBG_DEBUG("check_parent_access_fsp on "
1475 "directory %s for file %s "
1476 "returned %s\n",
1477 smb_fname_str_dbg(
1478 dirfsp->fsp_name),
1479 smb_fname_str_dbg(smb_fname),
1480 nt_errstr(status));
1481 return status;
1487 * Actually do the open - if O_TRUNC is needed handle it
1488 * below under the share mode lock.
1490 status = reopen_from_fsp(dirfsp,
1491 smb_fname_atname,
1492 fsp,
1493 local_flags & ~O_TRUNC,
1494 unx_mode,
1495 p_file_created);
1496 if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) {
1498 * Non-O_PATH reopen that hit a race
1499 * condition: Someone has put a symlink where
1500 * we used to have a file. Can't happen with
1501 * O_PATH and reopening from /proc/self/fd/ or
1502 * equivalent.
1504 status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
1506 if (!NT_STATUS_IS_OK(status)) {
1507 DEBUG(3,("Error opening file %s (%s) (local_flags=%d) "
1508 "(flags=%d)\n", smb_fname_str_dbg(smb_fname),
1509 nt_errstr(status),local_flags,flags));
1510 return status;
1513 if (local_flags & O_NONBLOCK) {
1515 * GPFS can return ETIMEDOUT for pread on
1516 * nonblocking file descriptors when files
1517 * migrated to tape need to be recalled. I
1518 * could imagine this happens elsewhere
1519 * too. With blocking file descriptors this
1520 * does not happen.
1522 ret = vfs_set_blocking(fsp, true);
1523 if (ret == -1) {
1524 status = map_nt_error_from_unix(errno);
1525 DBG_WARNING("Could not set fd to blocking: "
1526 "%s\n", strerror(errno));
1527 fd_close(fsp);
1528 return status;
1532 if (*p_file_created) {
1533 /* We created this file. */
1535 bool need_re_stat = false;
1536 /* Do all inheritance work after we've
1537 done a successful fstat call and filled
1538 in the stat struct in fsp->fsp_name. */
1540 /* Inherit the ACL if required */
1541 if (lp_inherit_permissions(SNUM(conn))) {
1542 inherit_access_posix_acl(conn,
1543 dirfsp,
1544 smb_fname,
1545 unx_mode);
1546 need_re_stat = true;
1549 /* Change the owner if required. */
1550 if (lp_inherit_owner(SNUM(conn)) != INHERIT_OWNER_NO) {
1551 change_file_owner_to_parent_fsp(dirfsp, fsp);
1552 need_re_stat = true;
1555 if (need_re_stat) {
1556 status = vfs_stat_fsp(fsp);
1558 * If we have an fd, this stat should succeed.
1560 if (!NT_STATUS_IS_OK(status)) {
1561 DBG_ERR("Error doing fstat on open "
1562 "file %s (%s)\n",
1563 smb_fname_str_dbg(smb_fname),
1564 nt_errstr(status));
1565 fd_close(fsp);
1566 return status;
1570 notify_fname(conn, NOTIFY_ACTION_ADDED,
1571 FILE_NOTIFY_CHANGE_FILE_NAME,
1572 smb_fname->base_name);
1574 } else {
1575 if (!file_existed) {
1576 /* File must exist for a stat open. */
1577 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1580 if (S_ISLNK(smb_fname->st.st_ex_mode) &&
1581 !posix_open)
1584 * Don't allow stat opens on symlinks directly unless
1585 * it's a POSIX open. Match the return code from
1586 * openat_pathref_fsp().
1588 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1591 if (!fsp->fsp_flags.is_pathref) {
1593 * There is only one legit case where end up here:
1594 * openat_pathref_fsp() failed to open a symlink, so the
1595 * fsp was created by fsp_new() which doesn't set
1596 * is_pathref. Other then that, we should always have a
1597 * pathref fsp at this point. The subsequent checks
1598 * assert this.
1600 if (!(smb_fname->flags & SMB_FILENAME_POSIX_PATH)) {
1601 DBG_ERR("[%s] is not a POSIX pathname\n",
1602 smb_fname_str_dbg(smb_fname));
1603 return NT_STATUS_INTERNAL_ERROR;
1605 if (!S_ISLNK(smb_fname->st.st_ex_mode)) {
1606 DBG_ERR("[%s] is not a symlink\n",
1607 smb_fname_str_dbg(smb_fname));
1608 return NT_STATUS_INTERNAL_ERROR;
1610 if (fsp_get_pathref_fd(fsp) != -1) {
1611 DBG_ERR("fd for [%s] is not -1: fd [%d]\n",
1612 smb_fname_str_dbg(smb_fname),
1613 fsp_get_pathref_fd(fsp));
1614 return NT_STATUS_INTERNAL_ERROR;
1619 * Access to streams is checked by checking the basefile and
1620 * that has alreay been checked by check_base_file_access()
1621 * in create_file_unixpath().
1623 if (!fsp_is_alternate_stream(fsp)) {
1624 status = smbd_check_access_rights_fsp(dirfsp,
1625 fsp,
1626 false,
1627 access_mask);
1629 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) &&
1630 posix_open &&
1631 S_ISLNK(smb_fname->st.st_ex_mode)) {
1632 /* This is a POSIX stat open for delete
1633 * or rename on a symlink that points
1634 * nowhere. Allow. */
1635 DEBUG(10,("open_file: allowing POSIX "
1636 "open on bad symlink %s\n",
1637 smb_fname_str_dbg(smb_fname)));
1638 status = NT_STATUS_OK;
1641 if (!NT_STATUS_IS_OK(status)) {
1642 DBG_DEBUG("smbd_check_access_rights_fsp on file "
1643 "%s returned %s\n",
1644 fsp_str_dbg(fsp),
1645 nt_errstr(status));
1646 return status;
1651 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
1652 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
1653 fsp->file_pid = req ? req->smbpid : 0;
1654 fsp->fsp_flags.can_lock = true;
1655 fsp->fsp_flags.can_read = ((access_mask & FILE_READ_DATA) != 0);
1656 fsp->fsp_flags.can_write =
1657 CAN_WRITE(conn) &&
1658 ((access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) != 0);
1659 fsp->print_file = NULL;
1660 fsp->fsp_flags.modified = false;
1661 fsp->sent_oplock_break = NO_BREAK_SENT;
1662 fsp->fsp_flags.is_directory = false;
1663 if (conn->aio_write_behind_list &&
1664 is_in_path(smb_fname->base_name, conn->aio_write_behind_list,
1665 posix_open ? true: conn->case_sensitive)) {
1666 fsp->fsp_flags.aio_write_behind = true;
1669 DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
1670 conn->session_info->unix_info->unix_name,
1671 smb_fname_str_dbg(smb_fname),
1672 BOOLSTR(fsp->fsp_flags.can_read),
1673 BOOLSTR(fsp->fsp_flags.can_write),
1674 conn->num_files_open));
1676 return NT_STATUS_OK;
1679 static bool mask_conflict(
1680 uint32_t new_access,
1681 uint32_t existing_access,
1682 uint32_t access_mask,
1683 uint32_t new_sharemode,
1684 uint32_t existing_sharemode,
1685 uint32_t sharemode_mask)
1687 bool want_access = (new_access & access_mask);
1688 bool allow_existing = (existing_sharemode & sharemode_mask);
1689 bool have_access = (existing_access & access_mask);
1690 bool allow_new = (new_sharemode & sharemode_mask);
1692 if (want_access && !allow_existing) {
1693 DBG_DEBUG("Access request 0x%"PRIx32"/0x%"PRIx32" conflicts "
1694 "with existing sharemode 0x%"PRIx32"/0x%"PRIx32"\n",
1695 new_access,
1696 access_mask,
1697 existing_sharemode,
1698 sharemode_mask);
1699 return true;
1701 if (have_access && !allow_new) {
1702 DBG_DEBUG("Sharemode request 0x%"PRIx32"/0x%"PRIx32" conflicts "
1703 "with existing access 0x%"PRIx32"/0x%"PRIx32"\n",
1704 new_sharemode,
1705 sharemode_mask,
1706 existing_access,
1707 access_mask);
1708 return true;
1710 return false;
1713 /****************************************************************************
1714 Check if we can open a file with a share mode.
1715 Returns True if conflict, False if not.
1716 ****************************************************************************/
1718 static const uint32_t conflicting_access =
1719 FILE_WRITE_DATA|
1720 FILE_APPEND_DATA|
1721 FILE_READ_DATA|
1722 FILE_EXECUTE|
1723 DELETE_ACCESS;
1725 static bool share_conflict(uint32_t e_access_mask,
1726 uint32_t e_share_access,
1727 uint32_t access_mask,
1728 uint32_t share_access)
1730 bool conflict;
1732 DBG_DEBUG("existing access_mask = 0x%"PRIx32", "
1733 "existing share access = 0x%"PRIx32", "
1734 "access_mask = 0x%"PRIx32", "
1735 "share_access = 0x%"PRIx32"\n",
1736 e_access_mask,
1737 e_share_access,
1738 access_mask,
1739 share_access);
1741 if ((e_access_mask & conflicting_access) == 0) {
1742 DBG_DEBUG("No conflict due to "
1743 "existing access_mask = 0x%"PRIx32"\n",
1744 e_access_mask);
1745 return false;
1747 if ((access_mask & conflicting_access) == 0) {
1748 DBG_DEBUG("No conflict due to access_mask = 0x%"PRIx32"\n",
1749 access_mask);
1750 return false;
1753 conflict = mask_conflict(
1754 access_mask, e_access_mask, FILE_WRITE_DATA | FILE_APPEND_DATA,
1755 share_access, e_share_access, FILE_SHARE_WRITE);
1756 conflict |= mask_conflict(
1757 access_mask, e_access_mask, FILE_READ_DATA | FILE_EXECUTE,
1758 share_access, e_share_access, FILE_SHARE_READ);
1759 conflict |= mask_conflict(
1760 access_mask, e_access_mask, DELETE_ACCESS,
1761 share_access, e_share_access, FILE_SHARE_DELETE);
1763 DBG_DEBUG("conflict=%s\n", conflict ? "true" : "false");
1764 return conflict;
1767 #if defined(DEVELOPER)
1769 struct validate_my_share_entries_state {
1770 struct smbd_server_connection *sconn;
1771 struct file_id fid;
1772 struct server_id self;
1775 static bool validate_my_share_entries_fn(
1776 struct share_mode_entry *e,
1777 bool *modified,
1778 void *private_data)
1780 struct validate_my_share_entries_state *state = private_data;
1781 files_struct *fsp;
1783 if (!server_id_equal(&state->self, &e->pid)) {
1784 return false;
1787 if (e->op_mid == 0) {
1788 /* INTERNAL_OPEN_ONLY */
1789 return false;
1792 fsp = file_find_dif(state->sconn, state->fid, e->share_file_id);
1793 if (!fsp) {
1794 DBG_ERR("PANIC : %s\n",
1795 share_mode_str(talloc_tos(), 0, &state->fid, e));
1796 smb_panic("validate_my_share_entries: Cannot match a "
1797 "share entry with an open file\n");
1800 if (((uint16_t)fsp->oplock_type) != e->op_type) {
1801 goto panic;
1804 return false;
1806 panic:
1808 char *str;
1809 DBG_ERR("validate_my_share_entries: PANIC : %s\n",
1810 share_mode_str(talloc_tos(), 0, &state->fid, e));
1811 str = talloc_asprintf(talloc_tos(),
1812 "validate_my_share_entries: "
1813 "file %s, oplock_type = 0x%x, op_type = 0x%x\n",
1814 fsp->fsp_name->base_name,
1815 (unsigned int)fsp->oplock_type,
1816 (unsigned int)e->op_type);
1817 smb_panic(str);
1820 return false;
1822 #endif
1825 * Allowed access mask for stat opens relevant to oplocks
1827 bool is_oplock_stat_open(uint32_t access_mask)
1829 const uint32_t stat_open_bits =
1830 (SYNCHRONIZE_ACCESS|
1831 FILE_READ_ATTRIBUTES|
1832 FILE_WRITE_ATTRIBUTES);
1834 return (((access_mask & stat_open_bits) != 0) &&
1835 ((access_mask & ~stat_open_bits) == 0));
1839 * Allowed access mask for stat opens relevant to leases
1841 bool is_lease_stat_open(uint32_t access_mask)
1843 const uint32_t stat_open_bits =
1844 (SYNCHRONIZE_ACCESS|
1845 FILE_READ_ATTRIBUTES|
1846 FILE_WRITE_ATTRIBUTES|
1847 READ_CONTROL_ACCESS);
1849 return (((access_mask & stat_open_bits) != 0) &&
1850 ((access_mask & ~stat_open_bits) == 0));
1853 struct has_delete_on_close_state {
1854 bool ret;
1857 static bool has_delete_on_close_fn(
1858 struct share_mode_entry *e,
1859 bool *modified,
1860 void *private_data)
1862 struct has_delete_on_close_state *state = private_data;
1863 state->ret = !share_entry_stale_pid(e);
1864 return state->ret;
1867 static bool has_delete_on_close(struct share_mode_lock *lck,
1868 uint32_t name_hash)
1870 struct has_delete_on_close_state state = { .ret = false };
1871 bool ok;
1873 if (!is_delete_on_close_set(lck, name_hash)) {
1874 return false;
1877 ok= share_mode_forall_entries(lck, has_delete_on_close_fn, &state);
1878 if (!ok) {
1879 DBG_DEBUG("share_mode_forall_entries failed\n");
1880 return false;
1882 return state.ret;
1885 static void share_mode_flags_restrict(
1886 struct share_mode_lock *lck,
1887 uint32_t access_mask,
1888 uint32_t share_mode,
1889 uint32_t lease_type)
1891 uint32_t existing_access_mask, existing_share_mode;
1892 uint32_t existing_lease_type;
1894 share_mode_flags_get(
1895 lck,
1896 &existing_access_mask,
1897 &existing_share_mode,
1898 &existing_lease_type);
1900 existing_access_mask |= access_mask;
1901 if (access_mask & conflicting_access) {
1902 existing_share_mode &= share_mode;
1904 existing_lease_type |= lease_type;
1906 share_mode_flags_set(
1907 lck,
1908 existing_access_mask,
1909 existing_share_mode,
1910 existing_lease_type,
1911 NULL);
1914 /****************************************************************************
1915 Deal with share modes
1916 Invariant: Share mode must be locked on entry and exit.
1917 Returns -1 on error, or number of share modes on success (may be zero).
1918 ****************************************************************************/
1920 struct open_mode_check_state {
1921 struct file_id fid;
1922 uint32_t access_mask;
1923 uint32_t share_access;
1924 uint32_t lease_type;
1927 static bool open_mode_check_fn(
1928 struct share_mode_entry *e,
1929 bool *modified,
1930 void *private_data)
1932 struct open_mode_check_state *state = private_data;
1933 bool disconnected, stale;
1934 uint32_t access_mask, share_access, lease_type;
1936 disconnected = server_id_is_disconnected(&e->pid);
1937 if (disconnected) {
1938 return false;
1941 access_mask = state->access_mask | e->access_mask;
1942 share_access = state->share_access;
1943 if (e->access_mask & conflicting_access) {
1944 share_access &= e->share_access;
1946 lease_type = state->lease_type | get_lease_type(e, state->fid);
1948 if ((access_mask == state->access_mask) &&
1949 (share_access == state->share_access) &&
1950 (lease_type == state->lease_type)) {
1951 return false;
1954 stale = share_entry_stale_pid(e);
1955 if (stale) {
1956 return false;
1959 state->access_mask = access_mask;
1960 state->share_access = share_access;
1961 state->lease_type = lease_type;
1963 return false;
1966 static NTSTATUS open_mode_check(connection_struct *conn,
1967 struct file_id fid,
1968 struct share_mode_lock *lck,
1969 uint32_t access_mask,
1970 uint32_t share_access)
1972 struct open_mode_check_state state;
1973 bool ok, conflict;
1974 bool modified = false;
1976 if (is_oplock_stat_open(access_mask)) {
1977 /* Stat open that doesn't trigger oplock breaks or share mode
1978 * checks... ! JRA. */
1979 return NT_STATUS_OK;
1983 * Check if the share modes will give us access.
1986 #if defined(DEVELOPER)
1988 struct validate_my_share_entries_state validate_state = {
1989 .sconn = conn->sconn,
1990 .fid = fid,
1991 .self = messaging_server_id(conn->sconn->msg_ctx),
1993 ok = share_mode_forall_entries(
1994 lck, validate_my_share_entries_fn, &validate_state);
1995 SMB_ASSERT(ok);
1997 #endif
1999 share_mode_flags_get(
2000 lck, &state.access_mask, &state.share_access, NULL);
2002 conflict = share_conflict(
2003 state.access_mask,
2004 state.share_access,
2005 access_mask,
2006 share_access);
2007 if (!conflict) {
2008 DBG_DEBUG("No conflict due to share_mode_flags access\n");
2009 return NT_STATUS_OK;
2012 state = (struct open_mode_check_state) {
2013 .fid = fid,
2014 .share_access = (FILE_SHARE_READ|
2015 FILE_SHARE_WRITE|
2016 FILE_SHARE_DELETE),
2020 * Walk the share mode array to recalculate d->flags
2023 ok = share_mode_forall_entries(lck, open_mode_check_fn, &state);
2024 if (!ok) {
2025 DBG_DEBUG("share_mode_forall_entries failed\n");
2026 return NT_STATUS_INTERNAL_ERROR;
2029 share_mode_flags_set(
2030 lck,
2031 state.access_mask,
2032 state.share_access,
2033 state.lease_type,
2034 &modified);
2035 if (!modified) {
2037 * We only end up here if we had a sharing violation
2038 * from d->flags and have recalculated it.
2040 return NT_STATUS_SHARING_VIOLATION;
2043 conflict = share_conflict(
2044 state.access_mask,
2045 state.share_access,
2046 access_mask,
2047 share_access);
2048 if (!conflict) {
2049 DBG_DEBUG("No conflict due to share_mode_flags access\n");
2050 return NT_STATUS_OK;
2053 return NT_STATUS_SHARING_VIOLATION;
2057 * Send a break message to the oplock holder and delay the open for
2058 * our client.
2061 NTSTATUS send_break_message(struct messaging_context *msg_ctx,
2062 const struct file_id *id,
2063 const struct share_mode_entry *exclusive,
2064 uint16_t break_to)
2066 struct oplock_break_message msg = {
2067 .id = *id,
2068 .share_file_id = exclusive->share_file_id,
2069 .break_to = break_to,
2071 enum ndr_err_code ndr_err;
2072 DATA_BLOB blob;
2073 NTSTATUS status;
2075 if (DEBUGLVL(10)) {
2076 struct server_id_buf buf;
2077 DBG_DEBUG("Sending break message to %s\n",
2078 server_id_str_buf(exclusive->pid, &buf));
2079 NDR_PRINT_DEBUG(oplock_break_message, &msg);
2082 ndr_err = ndr_push_struct_blob(
2083 &blob,
2084 talloc_tos(),
2085 &msg,
2086 (ndr_push_flags_fn_t)ndr_push_oplock_break_message);
2087 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2088 DBG_WARNING("ndr_push_oplock_break_message failed: %s\n",
2089 ndr_errstr(ndr_err));
2090 return ndr_map_error2ntstatus(ndr_err);
2093 status = messaging_send(
2094 msg_ctx, exclusive->pid, MSG_SMB_BREAK_REQUEST, &blob);
2095 TALLOC_FREE(blob.data);
2096 if (!NT_STATUS_IS_OK(status)) {
2097 DEBUG(3, ("Could not send oplock break message: %s\n",
2098 nt_errstr(status)));
2101 return status;
2104 struct validate_oplock_types_state {
2105 bool valid;
2106 bool batch;
2107 bool ex_or_batch;
2108 bool level2;
2109 bool no_oplock;
2110 uint32_t num_non_stat_opens;
2113 static bool validate_oplock_types_fn(
2114 struct share_mode_entry *e,
2115 bool *modified,
2116 void *private_data)
2118 struct validate_oplock_types_state *state = private_data;
2120 if (e->op_mid == 0) {
2121 /* INTERNAL_OPEN_ONLY */
2122 return false;
2125 if (e->op_type == NO_OPLOCK && is_oplock_stat_open(e->access_mask)) {
2127 * We ignore stat opens in the table - they always
2128 * have NO_OPLOCK and never get or cause breaks. JRA.
2130 return false;
2133 state->num_non_stat_opens += 1;
2135 if (BATCH_OPLOCK_TYPE(e->op_type)) {
2136 /* batch - can only be one. */
2137 if (share_entry_stale_pid(e)) {
2138 DBG_DEBUG("Found stale batch oplock\n");
2139 return false;
2141 if (state->ex_or_batch ||
2142 state->batch ||
2143 state->level2 ||
2144 state->no_oplock) {
2145 DBG_ERR("Bad batch oplock entry\n");
2146 state->valid = false;
2147 return true;
2149 state->batch = true;
2152 if (EXCLUSIVE_OPLOCK_TYPE(e->op_type)) {
2153 if (share_entry_stale_pid(e)) {
2154 DBG_DEBUG("Found stale duplicate oplock\n");
2155 return false;
2157 /* Exclusive or batch - can only be one. */
2158 if (state->ex_or_batch ||
2159 state->level2 ||
2160 state->no_oplock) {
2161 DBG_ERR("Bad exclusive or batch oplock entry\n");
2162 state->valid = false;
2163 return true;
2165 state->ex_or_batch = true;
2168 if (LEVEL_II_OPLOCK_TYPE(e->op_type)) {
2169 if (state->batch || state->ex_or_batch) {
2170 if (share_entry_stale_pid(e)) {
2171 DBG_DEBUG("Found stale LevelII oplock\n");
2172 return false;
2174 DBG_DEBUG("Bad levelII oplock entry\n");
2175 state->valid = false;
2176 return true;
2178 state->level2 = true;
2181 if (e->op_type == NO_OPLOCK) {
2182 if (state->batch || state->ex_or_batch) {
2183 if (share_entry_stale_pid(e)) {
2184 DBG_DEBUG("Found stale NO_OPLOCK entry\n");
2185 return false;
2187 DBG_ERR("Bad no oplock entry\n");
2188 state->valid = false;
2189 return true;
2191 state->no_oplock = true;
2194 return false;
2198 * Do internal consistency checks on the share mode for a file.
2201 static bool validate_oplock_types(struct share_mode_lock *lck)
2203 struct validate_oplock_types_state state = { .valid = true };
2204 static bool skip_validation;
2205 bool validate;
2206 bool ok;
2208 if (skip_validation) {
2209 return true;
2212 validate = lp_parm_bool(-1, "smbd", "validate_oplock_types", false);
2213 if (!validate) {
2214 DBG_DEBUG("smbd:validate_oplock_types not set to yes\n");
2215 skip_validation = true;
2216 return true;
2219 ok = share_mode_forall_entries(lck, validate_oplock_types_fn, &state);
2220 if (!ok) {
2221 DBG_DEBUG("share_mode_forall_entries failed\n");
2222 return false;
2224 if (!state.valid) {
2225 DBG_DEBUG("Got invalid oplock configuration\n");
2226 return false;
2229 if ((state.batch || state.ex_or_batch) &&
2230 (state.num_non_stat_opens != 1)) {
2231 DBG_WARNING("got batch (%d) or ex (%d) non-exclusively "
2232 "(%"PRIu32")\n",
2233 (int)state.batch,
2234 (int)state.ex_or_batch,
2235 state.num_non_stat_opens);
2236 return false;
2239 return true;
2242 static bool is_same_lease(const files_struct *fsp,
2243 const struct share_mode_entry *e,
2244 const struct smb2_lease *lease)
2246 if (e->op_type != LEASE_OPLOCK) {
2247 return false;
2249 if (lease == NULL) {
2250 return false;
2253 return smb2_lease_equal(fsp_client_guid(fsp),
2254 &lease->lease_key,
2255 &e->client_guid,
2256 &e->lease_key);
2259 static bool file_has_brlocks(files_struct *fsp)
2261 struct byte_range_lock *br_lck;
2263 br_lck = brl_get_locks_readonly(fsp);
2264 if (!br_lck)
2265 return false;
2267 return (brl_num_locks(br_lck) > 0);
2270 struct fsp_lease *find_fsp_lease(struct files_struct *new_fsp,
2271 const struct smb2_lease_key *key,
2272 uint32_t current_state,
2273 uint16_t lease_version,
2274 uint16_t lease_epoch)
2276 struct files_struct *fsp;
2279 * TODO: Measure how expensive this loop is with thousands of open
2280 * handles...
2283 for (fsp = file_find_di_first(new_fsp->conn->sconn, new_fsp->file_id, true);
2284 fsp != NULL;
2285 fsp = file_find_di_next(fsp, true)) {
2287 if (fsp == new_fsp) {
2288 continue;
2290 if (fsp->oplock_type != LEASE_OPLOCK) {
2291 continue;
2293 if (smb2_lease_key_equal(&fsp->lease->lease.lease_key, key)) {
2294 fsp->lease->ref_count += 1;
2295 return fsp->lease;
2299 /* Not found - must be leased in another smbd. */
2300 new_fsp->lease = talloc_zero(new_fsp->conn->sconn, struct fsp_lease);
2301 if (new_fsp->lease == NULL) {
2302 return NULL;
2304 new_fsp->lease->ref_count = 1;
2305 new_fsp->lease->sconn = new_fsp->conn->sconn;
2306 new_fsp->lease->lease.lease_key = *key;
2307 new_fsp->lease->lease.lease_state = current_state;
2309 * We internally treat all leases as V2 and update
2310 * the epoch, but when sending breaks it matters if
2311 * the requesting lease was v1 or v2.
2313 new_fsp->lease->lease.lease_version = lease_version;
2314 new_fsp->lease->lease.lease_epoch = lease_epoch;
2315 return new_fsp->lease;
2318 static NTSTATUS try_lease_upgrade(struct files_struct *fsp,
2319 struct share_mode_lock *lck,
2320 const struct GUID *client_guid,
2321 const struct smb2_lease *lease,
2322 uint32_t granted)
2324 bool do_upgrade;
2325 uint32_t current_state, breaking_to_requested, breaking_to_required;
2326 bool breaking;
2327 uint16_t lease_version, epoch;
2328 uint32_t existing, requested;
2329 NTSTATUS status;
2331 status = leases_db_get(
2332 client_guid,
2333 &lease->lease_key,
2334 &fsp->file_id,
2335 &current_state,
2336 &breaking,
2337 &breaking_to_requested,
2338 &breaking_to_required,
2339 &lease_version,
2340 &epoch);
2341 if (!NT_STATUS_IS_OK(status)) {
2342 return status;
2345 fsp->lease = find_fsp_lease(
2346 fsp,
2347 &lease->lease_key,
2348 current_state,
2349 lease_version,
2350 epoch);
2351 if (fsp->lease == NULL) {
2352 DEBUG(1, ("Did not find existing lease for file %s\n",
2353 fsp_str_dbg(fsp)));
2354 return NT_STATUS_NO_MEMORY;
2358 * Upgrade only if the requested lease is a strict upgrade.
2360 existing = current_state;
2361 requested = lease->lease_state;
2364 * Tricky: This test makes sure that "requested" is a
2365 * strict bitwise superset of "existing".
2367 do_upgrade = ((existing & requested) == existing);
2370 * Upgrade only if there's a change.
2372 do_upgrade &= (granted != existing);
2375 * Upgrade only if other leases don't prevent what was asked
2376 * for.
2378 do_upgrade &= (granted == requested);
2381 * only upgrade if we are not in breaking state
2383 do_upgrade &= !breaking;
2385 DEBUG(10, ("existing=%"PRIu32", requested=%"PRIu32", "
2386 "granted=%"PRIu32", do_upgrade=%d\n",
2387 existing, requested, granted, (int)do_upgrade));
2389 if (do_upgrade) {
2390 NTSTATUS set_status;
2392 current_state = granted;
2393 epoch += 1;
2395 set_status = leases_db_set(
2396 client_guid,
2397 &lease->lease_key,
2398 current_state,
2399 breaking,
2400 breaking_to_requested,
2401 breaking_to_required,
2402 lease_version,
2403 epoch);
2405 if (!NT_STATUS_IS_OK(set_status)) {
2406 DBG_DEBUG("leases_db_set failed: %s\n",
2407 nt_errstr(set_status));
2408 return set_status;
2412 fsp_lease_update(fsp);
2414 return NT_STATUS_OK;
2417 static NTSTATUS grant_new_fsp_lease(struct files_struct *fsp,
2418 struct share_mode_lock *lck,
2419 const struct GUID *client_guid,
2420 const struct smb2_lease *lease,
2421 uint32_t granted)
2423 NTSTATUS status;
2425 fsp->lease = talloc_zero(fsp->conn->sconn, struct fsp_lease);
2426 if (fsp->lease == NULL) {
2427 return NT_STATUS_INSUFFICIENT_RESOURCES;
2429 fsp->lease->ref_count = 1;
2430 fsp->lease->sconn = fsp->conn->sconn;
2431 fsp->lease->lease.lease_version = lease->lease_version;
2432 fsp->lease->lease.lease_key = lease->lease_key;
2433 fsp->lease->lease.lease_state = granted;
2434 fsp->lease->lease.lease_epoch = lease->lease_epoch + 1;
2436 status = leases_db_add(client_guid,
2437 &lease->lease_key,
2438 &fsp->file_id,
2439 fsp->lease->lease.lease_state,
2440 fsp->lease->lease.lease_version,
2441 fsp->lease->lease.lease_epoch,
2442 fsp->conn->connectpath,
2443 fsp->fsp_name->base_name,
2444 fsp->fsp_name->stream_name);
2445 if (!NT_STATUS_IS_OK(status)) {
2446 DEBUG(10, ("%s: leases_db_add failed: %s\n", __func__,
2447 nt_errstr(status)));
2448 TALLOC_FREE(fsp->lease);
2449 return NT_STATUS_INSUFFICIENT_RESOURCES;
2453 * We used to set lck->data->modified=true here without
2454 * actually modifying lck->data, triggering a needless
2455 * writeback of lck->data.
2457 * Apart from that writeback, setting modified=true has the
2458 * effect of triggering all waiters for this file to
2459 * retry. This only makes sense if any blocking condition
2460 * (i.e. waiting for a lease to be downgraded or removed) is
2461 * gone. This routine here only adds a lease, so it will never
2462 * free up resources that blocked waiters can now claim. So
2463 * that second effect also does not matter in this
2464 * routine. Thus setting lck->data->modified=true does not
2465 * need to be done here.
2468 return NT_STATUS_OK;
2471 static NTSTATUS grant_fsp_lease(struct files_struct *fsp,
2472 struct share_mode_lock *lck,
2473 const struct smb2_lease *lease,
2474 uint32_t granted)
2476 const struct GUID *client_guid = fsp_client_guid(fsp);
2477 NTSTATUS status;
2479 status = try_lease_upgrade(fsp, lck, client_guid, lease, granted);
2481 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
2482 status = grant_new_fsp_lease(
2483 fsp, lck, client_guid, lease, granted);
2486 return status;
2489 static int map_lease_type_to_oplock(uint32_t lease_type)
2491 int result = NO_OPLOCK;
2493 switch (lease_type) {
2494 case SMB2_LEASE_READ|SMB2_LEASE_WRITE|SMB2_LEASE_HANDLE:
2495 result = BATCH_OPLOCK|EXCLUSIVE_OPLOCK;
2496 break;
2497 case SMB2_LEASE_READ|SMB2_LEASE_WRITE:
2498 result = EXCLUSIVE_OPLOCK;
2499 break;
2500 case SMB2_LEASE_READ|SMB2_LEASE_HANDLE:
2501 case SMB2_LEASE_READ:
2502 result = LEVEL_II_OPLOCK;
2503 break;
2506 return result;
2509 struct delay_for_oplock_state {
2510 struct files_struct *fsp;
2511 const struct smb2_lease *lease;
2512 bool will_overwrite;
2513 uint32_t delay_mask;
2514 bool first_open_attempt;
2515 bool got_handle_lease;
2516 bool got_oplock;
2517 bool have_other_lease;
2518 uint32_t total_lease_types;
2519 bool delay;
2522 static bool delay_for_oplock_fn(
2523 struct share_mode_entry *e,
2524 bool *modified,
2525 void *private_data)
2527 struct delay_for_oplock_state *state = private_data;
2528 struct files_struct *fsp = state->fsp;
2529 const struct smb2_lease *lease = state->lease;
2530 bool e_is_lease = (e->op_type == LEASE_OPLOCK);
2531 uint32_t e_lease_type = SMB2_LEASE_NONE;
2532 uint32_t break_to;
2533 bool lease_is_breaking = false;
2535 if (e_is_lease) {
2536 NTSTATUS status;
2538 if (lease != NULL) {
2539 bool our_lease = is_same_lease(fsp, e, lease);
2540 if (our_lease) {
2541 DBG_DEBUG("Ignoring our own lease\n");
2542 return false;
2546 status = leases_db_get(
2547 &e->client_guid,
2548 &e->lease_key,
2549 &fsp->file_id,
2550 &e_lease_type, /* current_state */
2551 &lease_is_breaking,
2552 NULL, /* breaking_to_requested */
2553 NULL, /* breaking_to_required */
2554 NULL, /* lease_version */
2555 NULL); /* epoch */
2558 * leases_db_get() can return NT_STATUS_NOT_FOUND
2559 * if the share_mode_entry e is stale and the
2560 * lease record was already removed. In this case return
2561 * false so the traverse continues.
2564 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND) &&
2565 share_entry_stale_pid(e))
2567 struct GUID_txt_buf guid_strbuf;
2568 struct file_id_buf file_id_strbuf;
2569 DBG_DEBUG("leases_db_get for client_guid [%s] "
2570 "lease_key [%"PRIu64"/%"PRIu64"] "
2571 "file_id [%s] failed for stale "
2572 "share_mode_entry\n",
2573 GUID_buf_string(&e->client_guid, &guid_strbuf),
2574 e->lease_key.data[0],
2575 e->lease_key.data[1],
2576 file_id_str_buf(fsp->file_id, &file_id_strbuf));
2577 return false;
2579 if (!NT_STATUS_IS_OK(status)) {
2580 struct GUID_txt_buf guid_strbuf;
2581 struct file_id_buf file_id_strbuf;
2582 DBG_ERR("leases_db_get for client_guid [%s] "
2583 "lease_key [%"PRIu64"/%"PRIu64"] "
2584 "file_id [%s] failed: %s\n",
2585 GUID_buf_string(&e->client_guid, &guid_strbuf),
2586 e->lease_key.data[0],
2587 e->lease_key.data[1],
2588 file_id_str_buf(fsp->file_id, &file_id_strbuf),
2589 nt_errstr(status));
2590 smb_panic("leases_db_get() failed");
2592 } else {
2593 e_lease_type = get_lease_type(e, fsp->file_id);
2596 if (((e_lease_type & ~state->total_lease_types) != 0) &&
2597 !share_entry_stale_pid(e))
2599 state->total_lease_types |= e_lease_type;
2602 if (!state->got_handle_lease &&
2603 ((e_lease_type & SMB2_LEASE_HANDLE) != 0) &&
2604 !share_entry_stale_pid(e)) {
2605 state->got_handle_lease = true;
2608 if (!state->got_oplock &&
2609 (e->op_type != LEASE_OPLOCK) &&
2610 !share_entry_stale_pid(e)) {
2611 state->got_oplock = true;
2614 if (!state->have_other_lease &&
2615 !is_same_lease(fsp, e, lease) &&
2616 !share_entry_stale_pid(e)) {
2617 state->have_other_lease = true;
2620 if (e_is_lease && is_lease_stat_open(fsp->access_mask)) {
2621 return false;
2624 break_to = e_lease_type & ~state->delay_mask;
2626 if (state->will_overwrite) {
2627 break_to &= ~(SMB2_LEASE_HANDLE|SMB2_LEASE_READ);
2630 DBG_DEBUG("e_lease_type %u, will_overwrite: %u\n",
2631 (unsigned)e_lease_type,
2632 (unsigned)state->will_overwrite);
2634 if ((e_lease_type & ~break_to) == 0) {
2635 if (lease_is_breaking) {
2636 state->delay = true;
2638 return false;
2641 if (share_entry_stale_pid(e)) {
2642 return false;
2645 if (state->will_overwrite) {
2647 * If we break anyway break to NONE directly.
2648 * Otherwise vfs_set_filelen() will trigger the
2649 * break.
2651 break_to &= ~(SMB2_LEASE_READ|SMB2_LEASE_WRITE);
2654 if (!e_is_lease) {
2656 * Oplocks only support breaking to R or NONE.
2658 break_to &= ~(SMB2_LEASE_HANDLE|SMB2_LEASE_WRITE);
2661 DBG_DEBUG("breaking from %d to %d\n",
2662 (int)e_lease_type,
2663 (int)break_to);
2664 send_break_message(
2665 fsp->conn->sconn->msg_ctx, &fsp->file_id, e, break_to);
2666 if (e_lease_type & state->delay_mask) {
2667 state->delay = true;
2669 if (lease_is_breaking && !state->first_open_attempt) {
2670 state->delay = true;
2673 return false;
2676 static NTSTATUS delay_for_oplock(files_struct *fsp,
2677 int oplock_request,
2678 const struct smb2_lease *lease,
2679 struct share_mode_lock *lck,
2680 bool have_sharing_violation,
2681 uint32_t create_disposition,
2682 bool first_open_attempt,
2683 int *poplock_type,
2684 uint32_t *pgranted)
2686 struct delay_for_oplock_state state = {
2687 .fsp = fsp,
2688 .lease = lease,
2689 .first_open_attempt = first_open_attempt,
2691 uint32_t requested;
2692 uint32_t granted;
2693 int oplock_type;
2694 bool ok;
2696 *poplock_type = NO_OPLOCK;
2697 *pgranted = 0;
2699 if (fsp->fsp_flags.is_directory) {
2701 * No directory leases yet
2703 SMB_ASSERT(oplock_request == NO_OPLOCK);
2704 if (have_sharing_violation) {
2705 return NT_STATUS_SHARING_VIOLATION;
2707 return NT_STATUS_OK;
2710 if (oplock_request == LEASE_OPLOCK) {
2711 if (lease == NULL) {
2713 * The SMB2 layer should have checked this
2715 return NT_STATUS_INTERNAL_ERROR;
2718 requested = lease->lease_state;
2719 } else {
2720 requested = map_oplock_to_lease_type(
2721 oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK);
2724 share_mode_flags_get(lck, NULL, NULL, &state.total_lease_types);
2726 if (is_oplock_stat_open(fsp->access_mask)) {
2727 goto grant;
2730 state.delay_mask = have_sharing_violation ?
2731 SMB2_LEASE_HANDLE : SMB2_LEASE_WRITE;
2733 switch (create_disposition) {
2734 case FILE_SUPERSEDE:
2735 case FILE_OVERWRITE:
2736 case FILE_OVERWRITE_IF:
2737 state.will_overwrite = true;
2738 break;
2739 default:
2740 state.will_overwrite = false;
2741 break;
2744 state.total_lease_types = SMB2_LEASE_NONE;
2745 ok = share_mode_forall_entries(lck, delay_for_oplock_fn, &state);
2746 if (!ok) {
2747 return NT_STATUS_INTERNAL_ERROR;
2750 if (state.delay) {
2751 return NT_STATUS_RETRY;
2754 grant:
2755 if (have_sharing_violation) {
2756 return NT_STATUS_SHARING_VIOLATION;
2759 granted = requested;
2761 if (oplock_request == LEASE_OPLOCK) {
2762 if (lp_kernel_oplocks(SNUM(fsp->conn))) {
2763 DEBUG(10, ("No lease granted because kernel oplocks are enabled\n"));
2764 granted = SMB2_LEASE_NONE;
2766 if ((granted & (SMB2_LEASE_READ|SMB2_LEASE_WRITE)) == 0) {
2767 DEBUG(10, ("No read or write lease requested\n"));
2768 granted = SMB2_LEASE_NONE;
2770 if (granted == SMB2_LEASE_WRITE) {
2771 DEBUG(10, ("pure write lease requested\n"));
2772 granted = SMB2_LEASE_NONE;
2774 if (granted == (SMB2_LEASE_WRITE|SMB2_LEASE_HANDLE)) {
2775 DEBUG(10, ("write and handle lease requested\n"));
2776 granted = SMB2_LEASE_NONE;
2780 if (lp_locking(fsp->conn->params) && file_has_brlocks(fsp)) {
2781 DBG_DEBUG("file %s has byte range locks\n",
2782 fsp_str_dbg(fsp));
2783 granted &= ~SMB2_LEASE_READ;
2786 if (state.have_other_lease) {
2788 * Can grant only one writer
2790 granted &= ~SMB2_LEASE_WRITE;
2793 if ((granted & SMB2_LEASE_READ) && !(granted & SMB2_LEASE_WRITE)) {
2794 bool allow_level2 =
2795 (global_client_caps & CAP_LEVEL_II_OPLOCKS) &&
2796 lp_level2_oplocks(SNUM(fsp->conn));
2798 if (!allow_level2) {
2799 granted = SMB2_LEASE_NONE;
2803 if (oplock_request == LEASE_OPLOCK) {
2804 if (state.got_oplock) {
2805 granted &= ~SMB2_LEASE_HANDLE;
2808 oplock_type = LEASE_OPLOCK;
2809 } else {
2810 if (state.got_handle_lease) {
2811 granted = SMB2_LEASE_NONE;
2815 * Reflect possible downgrades from:
2816 * - map_lease_type_to_oplock() => "RH" to just LEVEL_II
2818 oplock_type = map_lease_type_to_oplock(granted);
2819 granted = map_oplock_to_lease_type(oplock_type);
2822 state.total_lease_types |= granted;
2825 uint32_t acc, sh, ls;
2826 share_mode_flags_get(lck, &acc, &sh, &ls);
2827 ls = state.total_lease_types;
2828 share_mode_flags_set(lck, acc, sh, ls, NULL);
2831 DBG_DEBUG("oplock type 0x%x granted (%s%s%s)(0x%x), on file %s, "
2832 "requested 0x%x (%s%s%s)(0x%x) => total (%s%s%s)(0x%x)\n",
2833 fsp->oplock_type,
2834 granted & SMB2_LEASE_READ ? "R":"",
2835 granted & SMB2_LEASE_WRITE ? "W":"",
2836 granted & SMB2_LEASE_HANDLE ? "H":"",
2837 granted,
2838 fsp_str_dbg(fsp),
2839 oplock_request,
2840 requested & SMB2_LEASE_READ ? "R":"",
2841 requested & SMB2_LEASE_WRITE ? "W":"",
2842 requested & SMB2_LEASE_HANDLE ? "H":"",
2843 requested,
2844 state.total_lease_types & SMB2_LEASE_READ ? "R":"",
2845 state.total_lease_types & SMB2_LEASE_WRITE ? "W":"",
2846 state.total_lease_types & SMB2_LEASE_HANDLE ? "H":"",
2847 state.total_lease_types);
2849 *poplock_type = oplock_type;
2850 *pgranted = granted;
2851 return NT_STATUS_OK;
2854 static NTSTATUS handle_share_mode_lease(
2855 files_struct *fsp,
2856 struct share_mode_lock *lck,
2857 uint32_t create_disposition,
2858 uint32_t access_mask,
2859 uint32_t share_access,
2860 int oplock_request,
2861 const struct smb2_lease *lease,
2862 bool first_open_attempt,
2863 int *poplock_type,
2864 uint32_t *pgranted)
2866 bool sharing_violation = false;
2867 NTSTATUS status;
2869 *poplock_type = NO_OPLOCK;
2870 *pgranted = 0;
2872 status = open_mode_check(
2873 fsp->conn, fsp->file_id, lck, access_mask, share_access);
2874 if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
2875 sharing_violation = true;
2876 status = NT_STATUS_OK; /* handled later */
2879 if (!NT_STATUS_IS_OK(status)) {
2880 return status;
2883 if (oplock_request == INTERNAL_OPEN_ONLY) {
2884 if (sharing_violation) {
2885 DBG_DEBUG("Sharing violation for internal open\n");
2886 return NT_STATUS_SHARING_VIOLATION;
2890 * Internal opens never do oplocks or leases. We don't
2891 * need to go through delay_for_oplock().
2893 return NT_STATUS_OK;
2896 status = delay_for_oplock(
2897 fsp,
2898 oplock_request,
2899 lease,
2900 lck,
2901 sharing_violation,
2902 create_disposition,
2903 first_open_attempt,
2904 poplock_type,
2905 pgranted);
2906 if (!NT_STATUS_IS_OK(status)) {
2907 return status;
2910 return NT_STATUS_OK;
2913 static bool request_timed_out(struct smb_request *req, struct timeval timeout)
2915 struct timeval now, end_time;
2916 GetTimeOfDay(&now);
2917 end_time = timeval_sum(&req->request_time, &timeout);
2918 return (timeval_compare(&end_time, &now) < 0);
2921 struct defer_open_state {
2922 struct smbXsrv_connection *xconn;
2923 uint64_t mid;
2926 static void defer_open_done(struct tevent_req *req);
2929 * Defer an open and watch a locking.tdb record
2931 * This defers an open that gets rescheduled once the locking.tdb record watch
2932 * is triggered by a change to the record.
2934 * It is used to defer opens that triggered an oplock break and for the SMB1
2935 * sharing violation delay.
2937 static void defer_open(struct share_mode_lock *lck,
2938 struct timeval timeout,
2939 struct smb_request *req,
2940 struct file_id id)
2942 struct deferred_open_record *open_rec = NULL;
2943 struct timeval abs_timeout;
2944 struct defer_open_state *watch_state;
2945 struct tevent_req *watch_req;
2946 struct timeval_buf tvbuf1, tvbuf2;
2947 struct file_id_buf fbuf;
2948 bool ok;
2950 abs_timeout = timeval_sum(&req->request_time, &timeout);
2952 DBG_DEBUG("request time [%s] timeout [%s] mid [%" PRIu64 "] "
2953 "file_id [%s]\n",
2954 timeval_str_buf(&req->request_time, false, true, &tvbuf1),
2955 timeval_str_buf(&abs_timeout, false, true, &tvbuf2),
2956 req->mid,
2957 file_id_str_buf(id, &fbuf));
2959 open_rec = talloc_zero(NULL, struct deferred_open_record);
2960 if (open_rec == NULL) {
2961 TALLOC_FREE(lck);
2962 exit_server("talloc failed");
2965 watch_state = talloc(open_rec, struct defer_open_state);
2966 if (watch_state == NULL) {
2967 exit_server("talloc failed");
2969 watch_state->xconn = req->xconn;
2970 watch_state->mid = req->mid;
2972 DBG_DEBUG("defering mid %" PRIu64 "\n", req->mid);
2974 watch_req = share_mode_watch_send(
2975 watch_state,
2976 req->sconn->ev_ctx,
2977 lck,
2978 (struct server_id){0});
2979 if (watch_req == NULL) {
2980 exit_server("Could not watch share mode record");
2982 tevent_req_set_callback(watch_req, defer_open_done, watch_state);
2984 ok = tevent_req_set_endtime(watch_req, req->sconn->ev_ctx, abs_timeout);
2985 if (!ok) {
2986 exit_server("tevent_req_set_endtime failed");
2989 ok = push_deferred_open_message_smb(req, timeout, id, open_rec);
2990 if (!ok) {
2991 TALLOC_FREE(lck);
2992 exit_server("push_deferred_open_message_smb failed");
2996 static void defer_open_done(struct tevent_req *req)
2998 struct defer_open_state *state = tevent_req_callback_data(
2999 req, struct defer_open_state);
3000 NTSTATUS status;
3001 bool ret;
3003 status = share_mode_watch_recv(req, NULL, NULL);
3004 TALLOC_FREE(req);
3005 if (!NT_STATUS_IS_OK(status)) {
3006 DEBUG(5, ("dbwrap_watched_watch_recv returned %s\n",
3007 nt_errstr(status)));
3009 * Even if it failed, retry anyway. TODO: We need a way to
3010 * tell a re-scheduled open about that error.
3014 DEBUG(10, ("scheduling mid %llu\n", (unsigned long long)state->mid));
3016 ret = schedule_deferred_open_message_smb(state->xconn, state->mid);
3017 SMB_ASSERT(ret);
3018 TALLOC_FREE(state);
3022 * Actually attempt the kernel oplock polling open.
3025 static void poll_open_fn(struct tevent_context *ev,
3026 struct tevent_timer *te,
3027 struct timeval current_time,
3028 void *private_data)
3030 struct deferred_open_record *open_rec = talloc_get_type_abort(
3031 private_data, struct deferred_open_record);
3032 bool ok;
3034 TALLOC_FREE(open_rec->watch_req);
3036 ok = schedule_deferred_open_message_smb(
3037 open_rec->xconn, open_rec->mid);
3038 if (!ok) {
3039 exit_server("schedule_deferred_open_message_smb failed");
3041 DBG_DEBUG("timer fired. Retrying open !\n");
3044 static void poll_open_done(struct tevent_req *subreq);
3046 struct poll_open_setup_watcher_state {
3047 TALLOC_CTX *mem_ctx;
3048 struct tevent_context *ev_ctx;
3049 struct tevent_req *watch_req;
3052 static void poll_open_setup_watcher_fn(struct share_mode_lock *lck,
3053 void *private_data)
3055 struct poll_open_setup_watcher_state *state =
3056 (struct poll_open_setup_watcher_state *)private_data;
3058 if (!validate_oplock_types(lck)) {
3059 smb_panic("validate_oplock_types failed");
3062 state->watch_req = share_mode_watch_send(
3063 state->mem_ctx,
3064 state->ev_ctx,
3065 lck,
3066 (struct server_id) {0});
3067 if (state->watch_req == NULL) {
3068 DBG_WARNING("share_mode_watch_send failed\n");
3069 return;
3074 * Reschedule an open for 1 second from now, if not timed out.
3076 static bool setup_poll_open(
3077 struct smb_request *req,
3078 const struct file_id *id,
3079 struct timeval max_timeout,
3080 struct timeval interval)
3082 static struct file_id zero_id = {};
3083 bool ok;
3084 struct deferred_open_record *open_rec = NULL;
3085 struct timeval endtime, next_interval;
3086 struct file_id_buf ftmp;
3088 if (request_timed_out(req, max_timeout)) {
3089 return false;
3092 open_rec = talloc_zero(NULL, struct deferred_open_record);
3093 if (open_rec == NULL) {
3094 DBG_WARNING("talloc failed\n");
3095 return false;
3097 open_rec->xconn = req->xconn;
3098 open_rec->mid = req->mid;
3101 * Make sure open_rec->te does not come later than the
3102 * request's maximum endtime.
3105 endtime = timeval_sum(&req->request_time, &max_timeout);
3106 next_interval = timeval_current_ofs(interval.tv_sec, interval.tv_usec);
3107 next_interval = timeval_min(&endtime, &next_interval);
3109 open_rec->te = tevent_add_timer(
3110 req->sconn->ev_ctx,
3111 open_rec,
3112 next_interval,
3113 poll_open_fn,
3114 open_rec);
3115 if (open_rec->te == NULL) {
3116 DBG_WARNING("tevent_add_timer failed\n");
3117 TALLOC_FREE(open_rec);
3118 return false;
3121 if (id != NULL) {
3122 struct poll_open_setup_watcher_state wstate = {
3123 .mem_ctx = open_rec,
3124 .ev_ctx = req->sconn->ev_ctx,
3126 NTSTATUS status;
3128 status = share_mode_do_locked_vfs_denied(*id,
3129 poll_open_setup_watcher_fn,
3130 &wstate);
3131 if (NT_STATUS_IS_OK(status)) {
3132 if (wstate.watch_req == NULL) {
3133 DBG_WARNING("share_mode_watch_send failed\n");
3134 TALLOC_FREE(open_rec);
3135 return false;
3137 open_rec->watch_req = wstate.watch_req;
3138 tevent_req_set_callback(open_rec->watch_req,
3139 poll_open_done,
3140 open_rec);
3141 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
3142 DBG_WARNING("share_mode_do_locked_vfs_denied failed - %s\n",
3143 nt_errstr(status));
3144 TALLOC_FREE(open_rec);
3145 return false;
3147 } else {
3148 id = &zero_id;
3151 ok = push_deferred_open_message_smb(req, max_timeout, *id, open_rec);
3152 if (!ok) {
3153 DBG_WARNING("push_deferred_open_message_smb failed\n");
3154 TALLOC_FREE(open_rec);
3155 return false;
3158 DBG_DEBUG("poll request time [%s] mid [%" PRIu64 "] file_id [%s]\n",
3159 timeval_string(talloc_tos(), &req->request_time, false),
3160 req->mid,
3161 file_id_str_buf(*id, &ftmp));
3163 return true;
3166 static void poll_open_done(struct tevent_req *subreq)
3168 struct deferred_open_record *open_rec = tevent_req_callback_data(
3169 subreq, struct deferred_open_record);
3170 NTSTATUS status;
3171 bool ok;
3173 status = share_mode_watch_recv(subreq, NULL, NULL);
3174 TALLOC_FREE(subreq);
3175 open_rec->watch_req = NULL;
3176 TALLOC_FREE(open_rec->te);
3178 DBG_DEBUG("dbwrap_watched_watch_recv returned %s\n",
3179 nt_errstr(status));
3181 ok = schedule_deferred_open_message_smb(
3182 open_rec->xconn, open_rec->mid);
3183 if (!ok) {
3184 exit_server("schedule_deferred_open_message_smb failed");
3188 bool defer_smb1_sharing_violation(struct smb_request *req)
3190 bool ok;
3191 int timeout_usecs;
3193 if (!lp_defer_sharing_violations()) {
3194 return false;
3198 * Try every 200msec up to (by default) one second. To be
3199 * precise, according to behaviour note <247> in [MS-CIFS],
3200 * the server tries 5 times. But up to one second should be
3201 * close enough.
3204 timeout_usecs = lp_parm_int(
3205 SNUM(req->conn),
3206 "smbd",
3207 "sharedelay",
3208 SHARING_VIOLATION_USEC_WAIT);
3210 ok = setup_poll_open(
3211 req,
3212 NULL,
3213 (struct timeval) { .tv_usec = timeout_usecs },
3214 (struct timeval) { .tv_usec = 200000 });
3215 return ok;
3218 /****************************************************************************
3219 On overwrite open ensure that the attributes match.
3220 ****************************************************************************/
3222 static bool open_match_attributes(connection_struct *conn,
3223 uint32_t old_dos_attr,
3224 uint32_t new_dos_attr,
3225 mode_t new_unx_mode,
3226 mode_t *returned_unx_mode)
3228 uint32_t noarch_old_dos_attr, noarch_new_dos_attr;
3230 noarch_old_dos_attr = (old_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
3231 noarch_new_dos_attr = (new_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
3233 if((noarch_old_dos_attr == 0 && noarch_new_dos_attr != 0) ||
3234 (noarch_old_dos_attr != 0 && ((noarch_old_dos_attr & noarch_new_dos_attr) == noarch_old_dos_attr))) {
3235 *returned_unx_mode = new_unx_mode;
3236 } else {
3237 *returned_unx_mode = (mode_t)0;
3240 DEBUG(10,("open_match_attributes: old_dos_attr = 0x%x, "
3241 "new_dos_attr = 0x%x "
3242 "returned_unx_mode = 0%o\n",
3243 (unsigned int)old_dos_attr,
3244 (unsigned int)new_dos_attr,
3245 (unsigned int)*returned_unx_mode ));
3247 /* If we're mapping SYSTEM and HIDDEN ensure they match. */
3248 if (lp_map_system(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
3249 if ((old_dos_attr & FILE_ATTRIBUTE_SYSTEM) &&
3250 !(new_dos_attr & FILE_ATTRIBUTE_SYSTEM)) {
3251 return False;
3254 if (lp_map_hidden(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
3255 if ((old_dos_attr & FILE_ATTRIBUTE_HIDDEN) &&
3256 !(new_dos_attr & FILE_ATTRIBUTE_HIDDEN)) {
3257 return False;
3260 return True;
3263 static void schedule_defer_open(struct share_mode_lock *lck,
3264 struct file_id id,
3265 struct smb_request *req)
3267 /* This is a relative time, added to the absolute
3268 request_time value to get the absolute timeout time.
3269 Note that if this is the second or greater time we enter
3270 this codepath for this particular request mid then
3271 request_time is left as the absolute time of the *first*
3272 time this request mid was processed. This is what allows
3273 the request to eventually time out. */
3275 struct timeval timeout;
3277 /* Normally the smbd we asked should respond within
3278 * OPLOCK_BREAK_TIMEOUT seconds regardless of whether
3279 * the client did, give twice the timeout as a safety
3280 * measure here in case the other smbd is stuck
3281 * somewhere else. */
3283 timeout = timeval_set(OPLOCK_BREAK_TIMEOUT*2, 0);
3285 if (request_timed_out(req, timeout)) {
3286 return;
3289 defer_open(lck, timeout, req, id);
3292 /****************************************************************************
3293 Reschedule an open call that went asynchronous.
3294 ****************************************************************************/
3296 static void schedule_async_open_timer(struct tevent_context *ev,
3297 struct tevent_timer *te,
3298 struct timeval current_time,
3299 void *private_data)
3301 exit_server("async open timeout");
3304 static void schedule_async_open(struct smb_request *req)
3306 struct deferred_open_record *open_rec = NULL;
3307 struct timeval timeout = timeval_set(20, 0);
3308 bool ok;
3310 if (request_timed_out(req, timeout)) {
3311 return;
3314 open_rec = talloc_zero(NULL, struct deferred_open_record);
3315 if (open_rec == NULL) {
3316 exit_server("deferred_open_record_create failed");
3318 open_rec->async_open = true;
3320 ok = push_deferred_open_message_smb(
3321 req, timeout, (struct file_id){0}, open_rec);
3322 if (!ok) {
3323 exit_server("push_deferred_open_message_smb failed");
3326 open_rec->te = tevent_add_timer(req->sconn->ev_ctx,
3327 req,
3328 timeval_current_ofs(20, 0),
3329 schedule_async_open_timer,
3330 open_rec);
3331 if (open_rec->te == NULL) {
3332 exit_server("tevent_add_timer failed");
3336 static NTSTATUS check_and_store_share_mode(
3337 struct files_struct *fsp,
3338 struct smb_request *req,
3339 struct share_mode_lock *lck,
3340 uint32_t create_disposition,
3341 uint32_t access_mask,
3342 uint32_t share_access,
3343 int oplock_request,
3344 const struct smb2_lease *lease,
3345 bool first_open_attempt)
3347 NTSTATUS status;
3348 int oplock_type = NO_OPLOCK;
3349 uint32_t granted_lease = 0;
3350 const struct smb2_lease_key *lease_key = NULL;
3351 bool delete_on_close;
3352 bool ok;
3354 /* Get the types we need to examine. */
3355 if (!validate_oplock_types(lck)) {
3356 smb_panic("validate_oplock_types failed");
3359 delete_on_close = has_delete_on_close(lck, fsp->name_hash);
3360 if (delete_on_close) {
3361 return NT_STATUS_DELETE_PENDING;
3364 status = handle_share_mode_lease(fsp,
3365 lck,
3366 create_disposition,
3367 access_mask,
3368 share_access,
3369 oplock_request,
3370 lease,
3371 first_open_attempt,
3372 &oplock_type,
3373 &granted_lease);
3374 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
3375 schedule_defer_open(lck, fsp->file_id, req);
3376 return NT_STATUS_SHARING_VIOLATION;
3378 if (!NT_STATUS_IS_OK(status)) {
3379 return status;
3382 if (oplock_type == LEASE_OPLOCK) {
3383 lease_key = &lease->lease_key;
3386 share_mode_flags_restrict(lck, access_mask, share_access, 0);
3388 ok = set_share_mode(lck,
3389 fsp,
3390 get_current_uid(fsp->conn),
3391 req ? req->mid : 0,
3392 oplock_type,
3393 lease_key,
3394 share_access,
3395 access_mask);
3396 if (!ok) {
3397 return NT_STATUS_NO_MEMORY;
3400 if (oplock_type == LEASE_OPLOCK) {
3401 status = grant_fsp_lease(fsp, lck, lease, granted_lease);
3402 if (!NT_STATUS_IS_OK(status)) {
3403 del_share_mode(lck, fsp);
3404 return status;
3407 DBG_DEBUG("lease_state=%d\n", fsp->lease->lease.lease_state);
3410 fsp->oplock_type = oplock_type;
3412 return NT_STATUS_OK;
3415 /****************************************************************************
3416 Work out what access_mask to use from what the client sent us.
3417 ****************************************************************************/
3419 static NTSTATUS smbd_calculate_maximum_allowed_access_fsp(
3420 struct files_struct *dirfsp,
3421 struct files_struct *fsp,
3422 bool use_privs,
3423 uint32_t *p_access_mask)
3425 struct security_descriptor *sd = NULL;
3426 uint32_t access_granted = 0;
3427 uint32_t dosattrs;
3428 NTSTATUS status;
3430 /* Cope with symlinks */
3431 if (fsp == NULL || fsp_get_pathref_fd(fsp) == -1) {
3432 *p_access_mask = FILE_GENERIC_ALL;
3433 return NT_STATUS_OK;
3436 /* Cope with fake/printer fsp's. */
3437 if (fsp->fake_file_handle != NULL || fsp->print_file != NULL) {
3438 *p_access_mask = FILE_GENERIC_ALL;
3439 return NT_STATUS_OK;
3442 if (!use_privs && (get_current_uid(fsp->conn) == (uid_t)0)) {
3443 *p_access_mask |= FILE_GENERIC_ALL;
3444 return NT_STATUS_OK;
3447 status = SMB_VFS_FGET_NT_ACL(metadata_fsp(fsp),
3448 (SECINFO_OWNER |
3449 SECINFO_GROUP |
3450 SECINFO_DACL),
3451 talloc_tos(),
3452 &sd);
3454 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
3456 * File did not exist
3458 *p_access_mask = FILE_GENERIC_ALL;
3459 return NT_STATUS_OK;
3461 if (!NT_STATUS_IS_OK(status)) {
3462 DBG_ERR("Could not get acl on file %s: %s\n",
3463 fsp_str_dbg(fsp),
3464 nt_errstr(status));
3465 return status;
3469 * If we can access the path to this file, by
3470 * default we have FILE_READ_ATTRIBUTES from the
3471 * containing directory. See the section:
3472 * "Algorithm to Check Access to an Existing File"
3473 * in MS-FSA.pdf.
3475 * se_file_access_check()
3476 * also takes care of owner WRITE_DAC and READ_CONTROL.
3478 status = se_file_access_check(sd,
3479 get_current_nttok(fsp->conn),
3480 use_privs,
3481 (*p_access_mask & ~FILE_READ_ATTRIBUTES),
3482 &access_granted);
3484 TALLOC_FREE(sd);
3486 if (!NT_STATUS_IS_OK(status)) {
3487 DBG_ERR("Status %s on file %s: "
3488 "when calculating maximum access\n",
3489 nt_errstr(status),
3490 fsp_str_dbg(fsp));
3491 return status;
3494 *p_access_mask = (access_granted | FILE_READ_ATTRIBUTES);
3496 if (!(access_granted & DELETE_ACCESS)) {
3497 if (can_delete_file_in_directory(fsp->conn,
3498 dirfsp,
3499 fsp->fsp_name)) {
3500 *p_access_mask |= DELETE_ACCESS;
3504 dosattrs = fdos_mode(fsp);
3505 if (IS_DOS_READONLY(dosattrs) || !CAN_WRITE(fsp->conn)) {
3506 *p_access_mask &= ~(FILE_GENERIC_WRITE | DELETE_ACCESS);
3509 return NT_STATUS_OK;
3512 NTSTATUS smbd_calculate_access_mask_fsp(struct files_struct *dirfsp,
3513 struct files_struct *fsp,
3514 bool use_privs,
3515 uint32_t access_mask,
3516 uint32_t *access_mask_out)
3518 NTSTATUS status;
3519 uint32_t orig_access_mask = access_mask;
3520 uint32_t rejected_share_access;
3522 if (access_mask & SEC_MASK_INVALID) {
3523 DBG_DEBUG("access_mask [%8x] contains invalid bits\n",
3524 access_mask);
3525 return NT_STATUS_ACCESS_DENIED;
3529 * Convert GENERIC bits to specific bits.
3532 se_map_generic(&access_mask, &file_generic_mapping);
3534 /* Calculate MAXIMUM_ALLOWED_ACCESS if requested. */
3535 if (access_mask & MAXIMUM_ALLOWED_ACCESS) {
3537 status = smbd_calculate_maximum_allowed_access_fsp(
3538 dirfsp,
3539 fsp,
3540 use_privs,
3541 &access_mask);
3543 if (!NT_STATUS_IS_OK(status)) {
3544 return status;
3547 access_mask &= fsp->conn->share_access;
3550 rejected_share_access = access_mask & ~(fsp->conn->share_access);
3552 if (rejected_share_access) {
3553 DBG_INFO("Access denied on file %s: "
3554 "rejected by share access mask[0x%08X] "
3555 "orig[0x%08X] mapped[0x%08X] reject[0x%08X]\n",
3556 fsp_str_dbg(fsp),
3557 fsp->conn->share_access,
3558 orig_access_mask, access_mask,
3559 rejected_share_access);
3560 return NT_STATUS_ACCESS_DENIED;
3563 *access_mask_out = access_mask;
3564 return NT_STATUS_OK;
3567 /****************************************************************************
3568 Remove the deferred open entry under lock.
3569 ****************************************************************************/
3571 /****************************************************************************
3572 Return true if this is a state pointer to an asynchronous create.
3573 ****************************************************************************/
3575 bool is_deferred_open_async(const struct deferred_open_record *rec)
3577 return rec->async_open;
3580 static bool clear_ads(uint32_t create_disposition)
3582 bool ret = false;
3584 switch (create_disposition) {
3585 case FILE_SUPERSEDE:
3586 case FILE_OVERWRITE_IF:
3587 case FILE_OVERWRITE:
3588 ret = true;
3589 break;
3590 default:
3591 break;
3593 return ret;
3596 static int disposition_to_open_flags(uint32_t create_disposition)
3598 int ret = 0;
3601 * Currently we're using FILE_SUPERSEDE as the same as
3602 * FILE_OVERWRITE_IF but they really are
3603 * different. FILE_SUPERSEDE deletes an existing file
3604 * (requiring delete access) then recreates it.
3607 switch (create_disposition) {
3608 case FILE_SUPERSEDE:
3609 case FILE_OVERWRITE_IF:
3611 * If file exists replace/overwrite. If file doesn't
3612 * exist create.
3614 ret = O_CREAT|O_TRUNC;
3615 break;
3617 case FILE_OPEN:
3619 * If file exists open. If file doesn't exist error.
3621 ret = 0;
3622 break;
3624 case FILE_OVERWRITE:
3626 * If file exists overwrite. If file doesn't exist
3627 * error.
3629 ret = O_TRUNC;
3630 break;
3632 case FILE_CREATE:
3634 * If file exists error. If file doesn't exist create.
3636 ret = O_CREAT|O_EXCL;
3637 break;
3639 case FILE_OPEN_IF:
3641 * If file exists open. If file doesn't exist create.
3643 ret = O_CREAT;
3644 break;
3646 return ret;
3649 static int calculate_open_access_flags(uint32_t access_mask,
3650 uint32_t private_flags)
3652 bool need_write, need_read;
3655 * Note that we ignore the append flag as append does not
3656 * mean the same thing under DOS and Unix.
3659 need_write = (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA));
3660 if (!need_write) {
3661 return O_RDONLY;
3664 /* DENY_DOS opens are always underlying read-write on the
3665 file handle, no matter what the requested access mask
3666 says. */
3668 need_read =
3669 ((private_flags & NTCREATEX_FLAG_DENY_DOS) ||
3670 access_mask & (FILE_READ_ATTRIBUTES|FILE_READ_DATA|
3671 FILE_READ_EA|FILE_EXECUTE));
3673 if (!need_read) {
3674 return O_WRONLY;
3676 return O_RDWR;
3679 struct open_ntcreate_lock_state {
3680 struct share_mode_entry_prepare_state prepare_state;
3681 struct files_struct *fsp;
3682 const char *object_type;
3683 struct smb_request *req;
3684 uint32_t create_disposition;
3685 uint32_t access_mask;
3686 uint32_t share_access;
3687 int oplock_request;
3688 const struct smb2_lease *lease;
3689 bool first_open_attempt;
3690 bool keep_locked;
3691 NTSTATUS status;
3692 struct timespec write_time;
3693 share_mode_entry_prepare_unlock_fn_t cleanup_fn;
3696 static void open_ntcreate_lock_add_entry(struct share_mode_lock *lck,
3697 bool *keep_locked,
3698 void *private_data)
3700 struct open_ntcreate_lock_state *state =
3701 (struct open_ntcreate_lock_state *)private_data;
3704 * By default drop the g_lock again if we leave the
3705 * tdb chainlock.
3707 *keep_locked = false;
3709 state->status = check_and_store_share_mode(state->fsp,
3710 state->req,
3711 lck,
3712 state->create_disposition,
3713 state->access_mask,
3714 state->share_access,
3715 state->oplock_request,
3716 state->lease,
3717 state->first_open_attempt);
3718 if (!NT_STATUS_IS_OK(state->status)) {
3719 return;
3722 state->write_time = get_share_mode_write_time(lck);
3725 * keep the g_lock while existing the tdb chainlock,
3726 * we we're asked to, which mean we'll keep
3727 * the share_mode_lock during object creation,
3728 * or setting delete on close.
3730 *keep_locked = state->keep_locked;
3733 static void open_ntcreate_lock_cleanup_oplock(struct share_mode_lock *lck,
3734 void *private_data)
3736 struct open_ntcreate_lock_state *state =
3737 (struct open_ntcreate_lock_state *)private_data;
3738 bool ok;
3740 ok = remove_share_oplock(lck, state->fsp);
3741 if (!ok) {
3742 DBG_ERR("Could not remove oplock for %s %s\n",
3743 state->object_type, fsp_str_dbg(state->fsp));
3747 static void open_ntcreate_lock_cleanup_entry(struct share_mode_lock *lck,
3748 void *private_data)
3750 struct open_ntcreate_lock_state *state =
3751 (struct open_ntcreate_lock_state *)private_data;
3752 bool ok;
3754 ok = del_share_mode(lck, state->fsp);
3755 if (!ok) {
3756 DBG_ERR("Could not delete share entry for %s %s\n",
3757 state->object_type, fsp_str_dbg(state->fsp));
3761 /****************************************************************************
3762 Open a file with a share mode. Passed in an already created files_struct *.
3763 ****************************************************************************/
3765 static NTSTATUS open_file_ntcreate(connection_struct *conn,
3766 struct smb_request *req,
3767 uint32_t access_mask, /* access bits (FILE_READ_DATA etc.) */
3768 uint32_t share_access, /* share constants (FILE_SHARE_READ etc) */
3769 uint32_t create_disposition, /* FILE_OPEN_IF etc. */
3770 uint32_t create_options, /* options such as delete on close. */
3771 uint32_t new_dos_attributes, /* attributes used for new file. */
3772 int oplock_request, /* internal Samba oplock codes. */
3773 const struct smb2_lease *lease,
3774 /* Information (FILE_EXISTS etc.) */
3775 uint32_t private_flags, /* Samba specific flags. */
3776 struct smb_filename *parent_dir_fname, /* parent. */
3777 struct smb_filename *smb_fname_atname, /* atname relative to parent. */
3778 int *pinfo,
3779 files_struct *fsp)
3781 struct smb_filename *smb_fname = fsp->fsp_name;
3782 int flags=0;
3783 int flags2=0;
3784 bool file_existed = VALID_STAT(smb_fname->st);
3785 bool def_acl = False;
3786 bool posix_open = False;
3787 bool new_file_created = False;
3788 bool first_open_attempt = true;
3789 NTSTATUS fsp_open = NT_STATUS_ACCESS_DENIED;
3790 mode_t new_unx_mode = (mode_t)0;
3791 mode_t unx_mode = (mode_t)0;
3792 int info;
3793 uint32_t existing_dos_attributes = 0;
3794 struct open_ntcreate_lock_state lck_state = {};
3795 bool keep_locked = false;
3796 uint32_t open_access_mask = access_mask;
3797 NTSTATUS status;
3798 SMB_STRUCT_STAT saved_stat = smb_fname->st;
3799 struct timespec old_write_time;
3800 bool setup_poll = false;
3801 NTSTATUS ulstatus;
3803 if (conn->printer) {
3805 * Printers are handled completely differently.
3806 * Most of the passed parameters are ignored.
3809 if (pinfo) {
3810 *pinfo = FILE_WAS_CREATED;
3813 DEBUG(10, ("open_file_ntcreate: printer open fname=%s\n",
3814 smb_fname_str_dbg(smb_fname)));
3816 if (!req) {
3817 DEBUG(0,("open_file_ntcreate: printer open without "
3818 "an SMB request!\n"));
3819 return NT_STATUS_INTERNAL_ERROR;
3822 return print_spool_open(fsp, smb_fname->base_name,
3823 req->vuid);
3826 if (new_dos_attributes & FILE_FLAG_POSIX_SEMANTICS) {
3827 posix_open = True;
3828 unx_mode = (mode_t)(new_dos_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
3829 new_dos_attributes = 0;
3830 } else {
3831 /* Windows allows a new file to be created and
3832 silently removes a FILE_ATTRIBUTE_DIRECTORY
3833 sent by the client. Do the same. */
3835 new_dos_attributes &= ~FILE_ATTRIBUTE_DIRECTORY;
3837 /* We add FILE_ATTRIBUTE_ARCHIVE to this as this mode is only used if the file is
3838 * created new. */
3839 unx_mode = unix_mode(
3840 conn,
3841 new_dos_attributes | FILE_ATTRIBUTE_ARCHIVE,
3842 smb_fname,
3843 parent_dir_fname->fsp);
3846 DEBUG(10, ("open_file_ntcreate: fname=%s, dos_attrs=0x%x "
3847 "access_mask=0x%x share_access=0x%x "
3848 "create_disposition = 0x%x create_options=0x%x "
3849 "unix mode=0%o oplock_request=%d private_flags = 0x%x\n",
3850 smb_fname_str_dbg(smb_fname), new_dos_attributes,
3851 access_mask, share_access, create_disposition,
3852 create_options, (unsigned int)unx_mode, oplock_request,
3853 (unsigned int)private_flags));
3855 if (req == NULL) {
3856 /* Ensure req == NULL means INTERNAL_OPEN_ONLY */
3857 SMB_ASSERT(oplock_request == INTERNAL_OPEN_ONLY);
3858 } else {
3859 /* And req != NULL means no INTERNAL_OPEN_ONLY */
3860 SMB_ASSERT(((oplock_request & INTERNAL_OPEN_ONLY) == 0));
3864 * Only non-internal opens can be deferred at all
3867 if (req) {
3868 struct deferred_open_record *open_rec;
3869 if (get_deferred_open_message_state(req, NULL, &open_rec)) {
3871 /* If it was an async create retry, the file
3872 didn't exist. */
3874 if (is_deferred_open_async(open_rec)) {
3875 SET_STAT_INVALID(smb_fname->st);
3876 file_existed = false;
3879 /* Ensure we don't reprocess this message. */
3880 remove_deferred_open_message_smb(req->xconn, req->mid);
3882 first_open_attempt = false;
3886 if (!posix_open) {
3887 new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
3888 if (file_existed) {
3890 * Only use stored DOS attributes for checks
3891 * against requested attributes (below via
3892 * open_match_attributes()), cf bug #11992
3893 * for details. -slow
3895 uint32_t attr = 0;
3897 status = vfs_fget_dos_attributes(smb_fname->fsp, &attr);
3898 if (NT_STATUS_IS_OK(status)) {
3899 existing_dos_attributes = attr;
3904 /* ignore any oplock requests if oplocks are disabled */
3905 if (!lp_oplocks(SNUM(conn)) ||
3906 IS_VETO_OPLOCK_PATH(conn, smb_fname->base_name)) {
3907 /* Mask off everything except the private Samba bits. */
3908 oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
3911 /* this is for OS/2 long file names - say we don't support them */
3912 if (req != NULL && !req->posix_pathnames &&
3913 strstr(smb_fname->base_name,".+,;=[].")) {
3914 /* OS/2 Workplace shell fix may be main code stream in a later
3915 * release. */
3916 DEBUG(5,("open_file_ntcreate: OS/2 long filenames are not "
3917 "supported.\n"));
3918 if (use_nt_status()) {
3919 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3921 return NT_STATUS_DOS(ERRDOS, ERRcannotopen);
3924 switch( create_disposition ) {
3925 case FILE_OPEN:
3926 /* If file exists open. If file doesn't exist error. */
3927 if (!file_existed) {
3928 DEBUG(5,("open_file_ntcreate: FILE_OPEN "
3929 "requested for file %s and file "
3930 "doesn't exist.\n",
3931 smb_fname_str_dbg(smb_fname)));
3932 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3934 break;
3936 case FILE_OVERWRITE:
3937 /* If file exists overwrite. If file doesn't exist
3938 * error. */
3939 if (!file_existed) {
3940 DEBUG(5,("open_file_ntcreate: FILE_OVERWRITE "
3941 "requested for file %s and file "
3942 "doesn't exist.\n",
3943 smb_fname_str_dbg(smb_fname) ));
3944 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3946 break;
3948 case FILE_CREATE:
3949 /* If file exists error. If file doesn't exist
3950 * create. */
3951 if (file_existed) {
3952 DEBUG(5,("open_file_ntcreate: FILE_CREATE "
3953 "requested for file %s and file "
3954 "already exists.\n",
3955 smb_fname_str_dbg(smb_fname)));
3956 if (S_ISDIR(smb_fname->st.st_ex_mode)) {
3957 return NT_STATUS_FILE_IS_A_DIRECTORY;
3959 return NT_STATUS_OBJECT_NAME_COLLISION;
3961 break;
3963 case FILE_SUPERSEDE:
3964 case FILE_OVERWRITE_IF:
3965 case FILE_OPEN_IF:
3966 break;
3967 default:
3968 return NT_STATUS_INVALID_PARAMETER;
3971 flags2 = disposition_to_open_flags(create_disposition);
3973 /* We only care about matching attributes on file exists and
3974 * overwrite. */
3976 if (!posix_open && file_existed &&
3977 ((create_disposition == FILE_OVERWRITE) ||
3978 (create_disposition == FILE_OVERWRITE_IF))) {
3979 if (!open_match_attributes(conn, existing_dos_attributes,
3980 new_dos_attributes,
3981 unx_mode, &new_unx_mode)) {
3982 DEBUG(5,("open_file_ntcreate: attributes mismatch "
3983 "for file %s (%x %x) (0%o, 0%o)\n",
3984 smb_fname_str_dbg(smb_fname),
3985 existing_dos_attributes,
3986 new_dos_attributes,
3987 (unsigned int)smb_fname->st.st_ex_mode,
3988 (unsigned int)unx_mode ));
3989 return NT_STATUS_ACCESS_DENIED;
3993 status = smbd_calculate_access_mask_fsp(parent_dir_fname->fsp,
3994 smb_fname->fsp,
3995 false,
3996 access_mask,
3997 &access_mask);
3998 if (!NT_STATUS_IS_OK(status)) {
3999 DBG_DEBUG("smbd_calculate_access_mask_fsp "
4000 "on file %s returned %s\n",
4001 smb_fname_str_dbg(smb_fname),
4002 nt_errstr(status));
4003 return status;
4006 open_access_mask = access_mask;
4008 if (flags2 & O_TRUNC) {
4009 open_access_mask |= FILE_WRITE_DATA; /* This will cause oplock breaks. */
4012 if (file_existed) {
4014 * stat opens on existing files don't get oplocks.
4015 * They can get leases.
4017 * Note that we check for stat open on the *open_access_mask*,
4018 * i.e. the access mask we actually used to do the open,
4019 * not the one the client asked for (which is in
4020 * fsp->access_mask). This is due to the fact that
4021 * FILE_OVERWRITE and FILE_OVERWRITE_IF add in O_TRUNC,
4022 * which adds FILE_WRITE_DATA to open_access_mask.
4024 if (is_oplock_stat_open(open_access_mask) && lease == NULL) {
4025 oplock_request = NO_OPLOCK;
4029 DEBUG(10, ("open_file_ntcreate: fname=%s, after mapping "
4030 "access_mask=0x%x\n", smb_fname_str_dbg(smb_fname),
4031 access_mask));
4034 * Note that we ignore the append flag as append does not
4035 * mean the same thing under DOS and Unix.
4038 flags = calculate_open_access_flags(access_mask, private_flags);
4041 * Currently we only look at FILE_WRITE_THROUGH for create options.
4044 #if defined(O_SYNC)
4045 if ((create_options & FILE_WRITE_THROUGH) && lp_strict_sync(SNUM(conn))) {
4046 flags2 |= O_SYNC;
4048 #endif /* O_SYNC */
4050 if (posix_open && (access_mask & FILE_APPEND_DATA)) {
4051 flags2 |= O_APPEND;
4054 if (!posix_open && !CAN_WRITE(conn)) {
4056 * We should really return a permission denied error if either
4057 * O_CREAT or O_TRUNC are set, but for compatibility with
4058 * older versions of Samba we just AND them out.
4060 flags2 &= ~(O_CREAT|O_TRUNC);
4064 * With kernel oplocks the open breaking an oplock
4065 * blocks until the oplock holder has given up the
4066 * oplock or closed the file. We prevent this by always
4067 * trying to open the file with O_NONBLOCK (see "man
4068 * fcntl" on Linux).
4070 * If a process that doesn't use the smbd open files
4071 * database or communication methods holds a kernel
4072 * oplock we must periodically poll for available open
4073 * using O_NONBLOCK.
4075 flags2 |= O_NONBLOCK;
4078 * Ensure we can't write on a read-only share or file.
4081 if (flags != O_RDONLY && file_existed &&
4082 (!CAN_WRITE(conn) || IS_DOS_READONLY(existing_dos_attributes))) {
4083 DEBUG(5,("open_file_ntcreate: write access requested for "
4084 "file %s on read only %s\n",
4085 smb_fname_str_dbg(smb_fname),
4086 !CAN_WRITE(conn) ? "share" : "file" ));
4087 return NT_STATUS_ACCESS_DENIED;
4090 if (VALID_STAT(smb_fname->st)) {
4092 * Only try and create a file id before open
4093 * for an existing file. For a file being created
4094 * this won't do anything useful until the file
4095 * exists and has a valid stat struct.
4097 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
4099 fh_set_private_options(fsp->fh, private_flags);
4100 fsp->access_mask = open_access_mask; /* We change this to the
4101 * requested access_mask after
4102 * the open is done. */
4103 if (posix_open) {
4104 fsp->posix_flags |= FSP_POSIX_FLAGS_ALL;
4107 if ((create_options & FILE_DELETE_ON_CLOSE) &&
4108 (flags2 & O_CREAT) &&
4109 !file_existed) {
4110 /* Delete on close semantics for new files. */
4111 status = can_set_delete_on_close(fsp,
4112 new_dos_attributes);
4113 if (!NT_STATUS_IS_OK(status)) {
4114 fd_close(fsp);
4115 return status;
4120 * Ensure we pay attention to default ACLs on directories if required.
4123 if ((flags2 & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
4124 (def_acl = directory_has_default_acl_fsp(parent_dir_fname->fsp)))
4126 unx_mode = (0777 & lp_create_mask(SNUM(conn)));
4129 DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o, "
4130 "access_mask = 0x%x, open_access_mask = 0x%x\n",
4131 (unsigned int)flags, (unsigned int)flags2,
4132 (unsigned int)unx_mode, (unsigned int)access_mask,
4133 (unsigned int)open_access_mask));
4135 fsp_open = open_file(req,
4136 parent_dir_fname->fsp,
4137 smb_fname_atname,
4138 fsp,
4139 flags|flags2,
4140 unx_mode,
4141 access_mask,
4142 open_access_mask,
4143 private_flags,
4144 &new_file_created);
4145 if (NT_STATUS_EQUAL(fsp_open, NT_STATUS_NETWORK_BUSY)) {
4146 if (file_existed && S_ISFIFO(fsp->fsp_name->st.st_ex_mode)) {
4147 DEBUG(10, ("FIFO busy\n"));
4148 return NT_STATUS_NETWORK_BUSY;
4150 if (req == NULL) {
4151 DEBUG(10, ("Internal open busy\n"));
4152 return NT_STATUS_NETWORK_BUSY;
4155 * This handles the kernel oplock case:
4157 * the file has an active kernel oplock and the open() returned
4158 * EWOULDBLOCK/EAGAIN which maps to NETWORK_BUSY.
4160 * "Samba locking.tdb oplocks" are handled below after acquiring
4161 * the sharemode lock with get_share_mode_lock().
4163 setup_poll = true;
4166 if (NT_STATUS_EQUAL(fsp_open, NT_STATUS_RETRY)) {
4168 * EINTR from the open(2) syscall. Just setup a retry
4169 * in a bit. We can't use the sys_write() tight retry
4170 * loop here, as we might have to actually deal with
4171 * lease-break signals to avoid a deadlock.
4173 setup_poll = true;
4176 if (setup_poll) {
4178 * Retry once a second. If there's a share_mode_lock
4179 * around, also wait for it in case it was smbd
4180 * holding that kernel oplock that can quickly tell us
4181 * the oplock got removed.
4184 setup_poll_open(
4185 req,
4186 &fsp->file_id,
4187 timeval_set(OPLOCK_BREAK_TIMEOUT*2, 0),
4188 timeval_set(1, 0));
4190 return NT_STATUS_SHARING_VIOLATION;
4193 if (!NT_STATUS_IS_OK(fsp_open)) {
4194 bool wait_for_aio = NT_STATUS_EQUAL(
4195 fsp_open, NT_STATUS_MORE_PROCESSING_REQUIRED);
4196 if (wait_for_aio) {
4197 schedule_async_open(req);
4199 return fsp_open;
4202 if (new_file_created) {
4204 * As we atomically create using O_CREAT|O_EXCL,
4205 * then if new_file_created is true, then
4206 * file_existed *MUST* have been false (even
4207 * if the file was previously detected as being
4208 * there).
4210 file_existed = false;
4213 if (file_existed && !check_same_dev_ino(&saved_stat, &smb_fname->st)) {
4215 * The file did exist, but some other (local or NFS)
4216 * process either renamed/unlinked and re-created the
4217 * file with different dev/ino after we walked the path,
4218 * but before we did the open. We could retry the
4219 * open but it's a rare enough case it's easier to
4220 * just fail the open to prevent creating any problems
4221 * in the open file db having the wrong dev/ino key.
4223 fd_close(fsp);
4224 DBG_WARNING("file %s - dev/ino mismatch. "
4225 "Old (dev=%ju, ino=%ju). "
4226 "New (dev=%ju, ino=%ju). Failing open "
4227 "with NT_STATUS_ACCESS_DENIED.\n",
4228 smb_fname_str_dbg(smb_fname),
4229 (uintmax_t)saved_stat.st_ex_dev,
4230 (uintmax_t)saved_stat.st_ex_ino,
4231 (uintmax_t)smb_fname->st.st_ex_dev,
4232 (uintmax_t)smb_fname->st.st_ex_ino);
4233 return NT_STATUS_ACCESS_DENIED;
4236 old_write_time = smb_fname->st.st_ex_mtime;
4239 * Deal with the race condition where two smbd's detect the
4240 * file doesn't exist and do the create at the same time. One
4241 * of them will win and set a share mode, the other (ie. this
4242 * one) should check if the requested share mode for this
4243 * create is allowed.
4247 * Now the file exists and fsp is successfully opened,
4248 * fsp->dev and fsp->inode are valid and should replace the
4249 * dev=0,inode=0 from a non existent file. Spotted by
4250 * Nadav Danieli <nadavd@exanet.com>. JRA.
4253 if (new_file_created) {
4254 info = FILE_WAS_CREATED;
4255 } else {
4256 if (flags2 & O_TRUNC) {
4257 info = FILE_WAS_OVERWRITTEN;
4258 } else {
4259 info = FILE_WAS_OPENED;
4264 * If we created a new file, overwrite an existing one
4265 * or going to delete it later, we should keep
4266 * the share_mode_lock (g_lock) until we call
4267 * share_mode_entry_prepare_unlock()
4269 if (info != FILE_WAS_OPENED) {
4270 keep_locked = true;
4271 } else if (create_options & FILE_DELETE_ON_CLOSE) {
4272 keep_locked = true;
4275 lck_state = (struct open_ntcreate_lock_state) {
4276 .fsp = fsp,
4277 .object_type = "file",
4278 .req = req,
4279 .create_disposition = create_disposition,
4280 .access_mask = access_mask,
4281 .share_access = share_access,
4282 .oplock_request = oplock_request,
4283 .lease = lease,
4284 .first_open_attempt = first_open_attempt,
4285 .keep_locked = keep_locked,
4288 status = share_mode_entry_prepare_lock_add(&lck_state.prepare_state,
4289 fsp->file_id,
4290 conn->connectpath,
4291 smb_fname,
4292 &old_write_time,
4293 open_ntcreate_lock_add_entry,
4294 &lck_state);
4295 if (!NT_STATUS_IS_OK(status)) {
4296 DBG_ERR("share_mode_entry_prepare_lock_add() failed for %s - %s\n",
4297 smb_fname_str_dbg(smb_fname), nt_errstr(status));
4298 fd_close(fsp);
4299 return status;
4302 status = lck_state.status;
4303 if (!NT_STATUS_IS_OK(status)) {
4304 fd_close(fsp);
4305 return status;
4309 * From here we need to use 'goto unlock;' instead of return !!!
4312 if (fsp->oplock_type != NO_OPLOCK && fsp->oplock_type != LEASE_OPLOCK) {
4314 * Now ask for kernel oplocks
4315 * and cleanup on failure.
4317 status = set_file_oplock(fsp);
4318 if (!NT_STATUS_IS_OK(status)) {
4320 * Could not get the kernel oplock
4322 lck_state.cleanup_fn =
4323 open_ntcreate_lock_cleanup_oplock;
4324 fsp->oplock_type = NO_OPLOCK;
4328 /* Should we atomically (to the client at least) truncate ? */
4329 if ((!new_file_created) &&
4330 (flags2 & O_TRUNC) &&
4331 (S_ISREG(fsp->fsp_name->st.st_ex_mode))) {
4332 int ret;
4334 ret = SMB_VFS_FTRUNCATE(fsp, 0);
4335 if (ret != 0) {
4336 status = map_nt_error_from_unix(errno);
4337 lck_state.cleanup_fn =
4338 open_ntcreate_lock_cleanup_entry;
4339 goto unlock;
4341 notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
4342 FILE_NOTIFY_CHANGE_SIZE
4343 | FILE_NOTIFY_CHANGE_ATTRIBUTES,
4344 fsp->fsp_name->base_name);
4348 * We have the share entry *locked*.....
4351 /* Delete streams if create_disposition requires it */
4352 if (!new_file_created &&
4353 clear_ads(create_disposition) &&
4354 !fsp_is_alternate_stream(fsp)) {
4355 status = delete_all_streams(conn, smb_fname);
4356 if (!NT_STATUS_IS_OK(status)) {
4357 lck_state.cleanup_fn =
4358 open_ntcreate_lock_cleanup_entry;
4359 goto unlock;
4363 if (!fsp->fsp_flags.is_pathref &&
4364 fsp_get_io_fd(fsp) != -1 &&
4365 lp_kernel_share_modes(SNUM(conn)))
4367 int ret;
4369 * Beware: streams implementing VFS modules may
4370 * implement streams in a way that fsp will have the
4371 * basefile open in the fsp fd, so lacking a distinct
4372 * fd for the stream the file-system sharemode will
4373 * apply on the basefile which is wrong. The actual
4374 * check is deferred to the VFS module implementing
4375 * the file-system sharemode call.
4377 ret = SMB_VFS_FILESYSTEM_SHAREMODE(fsp,
4378 share_access,
4379 access_mask);
4380 if (ret == -1){
4381 status = NT_STATUS_SHARING_VIOLATION;
4382 lck_state.cleanup_fn =
4383 open_ntcreate_lock_cleanup_entry;
4384 goto unlock;
4387 fsp->fsp_flags.kernel_share_modes_taken = true;
4391 * At this point onwards, we can guarantee that the share entry
4392 * is locked, whether we created the file or not, and that the
4393 * deny mode is compatible with all current opens.
4397 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
4398 * but we don't have to store this - just ignore it on access check.
4400 if (conn->sconn->using_smb2) {
4402 * SMB2 doesn't return it (according to Microsoft tests).
4403 * Test Case: TestSuite_ScenarioNo009GrantedAccessTestS0
4404 * File created with access = 0x7 (Read, Write, Delete)
4405 * Query Info on file returns 0x87 (Read, Write, Delete, Read Attributes)
4407 fsp->access_mask = access_mask;
4408 } else {
4409 /* But SMB1 does. */
4410 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
4413 if (pinfo) {
4414 *pinfo = info;
4417 /* Handle strange delete on close create semantics. */
4418 if (create_options & FILE_DELETE_ON_CLOSE) {
4419 if (!new_file_created) {
4420 status = can_set_delete_on_close(fsp,
4421 existing_dos_attributes);
4423 if (!NT_STATUS_IS_OK(status)) {
4424 /* Remember to delete the mode we just added. */
4425 lck_state.cleanup_fn =
4426 open_ntcreate_lock_cleanup_entry;
4427 goto unlock;
4430 /* Note that here we set the *initial* delete on close flag,
4431 not the regular one. The magic gets handled in close. */
4432 fsp->fsp_flags.initial_delete_on_close = true;
4435 if (info != FILE_WAS_OPENED) {
4436 /* Overwritten files should be initially set as archive */
4437 if ((info == FILE_WAS_OVERWRITTEN && lp_map_archive(SNUM(conn))) ||
4438 lp_store_dos_attributes(SNUM(conn))) {
4439 (void)fdos_mode(fsp);
4440 if (!posix_open) {
4441 if (file_set_dosmode(conn, smb_fname,
4442 new_dos_attributes | FILE_ATTRIBUTE_ARCHIVE,
4443 parent_dir_fname, true) == 0) {
4444 unx_mode = smb_fname->st.st_ex_mode;
4450 /* Determine sparse flag. */
4451 if (posix_open) {
4452 /* POSIX opens are sparse by default. */
4453 fsp->fsp_flags.is_sparse = true;
4454 } else {
4455 fsp->fsp_flags.is_sparse =
4456 (existing_dos_attributes & FILE_ATTRIBUTE_SPARSE);
4460 * Take care of inherited ACLs on created files - if default ACL not
4461 * selected.
4464 if (!posix_open && new_file_created && !def_acl) {
4465 if (unx_mode != smb_fname->st.st_ex_mode) {
4466 int ret = SMB_VFS_FCHMOD(fsp, unx_mode);
4467 if (ret == -1) {
4468 DBG_INFO("failed to reset "
4469 "attributes of file %s to 0%o\n",
4470 smb_fname_str_dbg(smb_fname),
4471 (unsigned int)unx_mode);
4475 } else if (new_unx_mode) {
4477 * We only get here in the case of:
4479 * a). Not a POSIX open.
4480 * b). File already existed.
4481 * c). File was overwritten.
4482 * d). Requested DOS attributes didn't match
4483 * the DOS attributes on the existing file.
4485 * In that case new_unx_mode has been set
4486 * equal to the calculated mode (including
4487 * possible inheritance of the mode from the
4488 * containing directory).
4490 * Note this mode was calculated with the
4491 * DOS attribute FILE_ATTRIBUTE_ARCHIVE added,
4492 * so the mode change here is suitable for
4493 * an overwritten file.
4496 if (new_unx_mode != smb_fname->st.st_ex_mode) {
4497 int ret = SMB_VFS_FCHMOD(fsp, new_unx_mode);
4498 if (ret == -1) {
4499 DBG_INFO("failed to reset "
4500 "attributes of file %s to 0%o\n",
4501 smb_fname_str_dbg(smb_fname),
4502 (unsigned int)new_unx_mode);
4508 * Deal with other opens having a modified write time.
4510 if (fsp_getinfo_ask_sharemode(fsp) &&
4511 !is_omit_timespec(&lck_state.write_time))
4513 update_stat_ex_mtime(&fsp->fsp_name->st, lck_state.write_time);
4516 status = NT_STATUS_OK;
4518 unlock:
4519 ulstatus = share_mode_entry_prepare_unlock(&lck_state.prepare_state,
4520 lck_state.cleanup_fn,
4521 &lck_state);
4522 if (!NT_STATUS_IS_OK(ulstatus)) {
4523 DBG_ERR("share_mode_entry_prepare_unlock() failed for %s - %s\n",
4524 smb_fname_str_dbg(smb_fname), nt_errstr(ulstatus));
4525 smb_panic("share_mode_entry_prepare_unlock() failed!");
4528 if (!NT_STATUS_IS_OK(status)) {
4529 fd_close(fsp);
4530 return status;
4533 return NT_STATUS_OK;
4536 static NTSTATUS mkdir_internal(connection_struct *conn,
4537 struct smb_filename *parent_dir_fname, /* parent. */
4538 struct smb_filename *smb_fname_atname, /* atname relative to parent. */
4539 struct smb_filename *smb_dname, /* full pathname from root of share. */
4540 uint32_t file_attributes,
4541 struct files_struct *fsp)
4543 const struct loadparm_substitution *lp_sub =
4544 loadparm_s3_global_substitution();
4545 mode_t mode;
4546 NTSTATUS status;
4547 bool posix_open = false;
4548 bool need_re_stat = false;
4549 uint32_t access_mask = SEC_DIR_ADD_SUBDIR;
4550 struct vfs_open_how how = { .flags = O_RDONLY|O_DIRECTORY, };
4551 int ret;
4553 if (!CAN_WRITE(conn) || (access_mask & ~(conn->share_access))) {
4554 DEBUG(5,("mkdir_internal: failing share access "
4555 "%s\n", lp_servicename(talloc_tos(), lp_sub, SNUM(conn))));
4556 return NT_STATUS_ACCESS_DENIED;
4559 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
4560 posix_open = true;
4561 mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
4562 } else {
4563 mode = unix_mode(conn,
4564 FILE_ATTRIBUTE_DIRECTORY,
4565 smb_dname,
4566 parent_dir_fname->fsp);
4569 status = check_parent_access_fsp(parent_dir_fname->fsp, access_mask);
4570 if(!NT_STATUS_IS_OK(status)) {
4571 DBG_INFO("check_parent_access_fsp "
4572 "on directory %s for path %s returned %s\n",
4573 smb_fname_str_dbg(parent_dir_fname),
4574 smb_dname->base_name,
4575 nt_errstr(status));
4576 return status;
4579 if (lp_inherit_acls(SNUM(conn))) {
4580 if (directory_has_default_acl_fsp(parent_dir_fname->fsp)) {
4581 mode = (0777 & lp_directory_mask(SNUM(conn)));
4585 ret = SMB_VFS_MKDIRAT(conn,
4586 parent_dir_fname->fsp,
4587 smb_fname_atname,
4588 mode);
4589 if (ret != 0) {
4590 return map_nt_error_from_unix(errno);
4594 * Make this a pathref fsp for now. open_directory() will reopen as a
4595 * full fsp.
4597 fsp->fsp_flags.is_pathref = true;
4599 status = fd_openat(parent_dir_fname->fsp, smb_fname_atname, fsp, &how);
4600 if (!NT_STATUS_IS_OK(status)) {
4601 return status;
4604 /* Ensure we're checking for a symlink here.... */
4605 /* We don't want to get caught by a symlink racer. */
4607 status = vfs_stat_fsp(fsp);
4608 if (!NT_STATUS_IS_OK(status)) {
4609 DEBUG(2, ("Could not stat directory '%s' just created: %s\n",
4610 smb_fname_str_dbg(smb_dname), nt_errstr(status)));
4611 return status;
4614 if (!S_ISDIR(smb_dname->st.st_ex_mode)) {
4615 DEBUG(0, ("Directory '%s' just created is not a directory !\n",
4616 smb_fname_str_dbg(smb_dname)));
4617 return NT_STATUS_NOT_A_DIRECTORY;
4620 if (lp_store_dos_attributes(SNUM(conn)) && !posix_open) {
4621 file_set_dosmode(conn,
4622 smb_dname,
4623 file_attributes | FILE_ATTRIBUTE_DIRECTORY,
4624 parent_dir_fname,
4625 true);
4628 if (lp_inherit_permissions(SNUM(conn))) {
4629 inherit_access_posix_acl(conn, parent_dir_fname->fsp,
4630 smb_dname, mode);
4631 need_re_stat = true;
4634 if (!posix_open) {
4636 * Check if high bits should have been set,
4637 * then (if bits are missing): add them.
4638 * Consider bits automagically set by UNIX, i.e. SGID bit from parent
4639 * dir.
4641 if ((mode & ~(S_IRWXU|S_IRWXG|S_IRWXO)) &&
4642 (mode & ~smb_dname->st.st_ex_mode)) {
4643 SMB_VFS_FCHMOD(fsp,
4644 (smb_dname->st.st_ex_mode |
4645 (mode & ~smb_dname->st.st_ex_mode)));
4646 need_re_stat = true;
4650 /* Change the owner if required. */
4651 if (lp_inherit_owner(SNUM(conn)) != INHERIT_OWNER_NO) {
4652 change_dir_owner_to_parent_fsp(parent_dir_fname->fsp,
4653 fsp);
4654 need_re_stat = true;
4657 if (need_re_stat) {
4658 status = vfs_stat_fsp(fsp);
4659 if (!NT_STATUS_IS_OK(status)) {
4660 DEBUG(2, ("Could not stat directory '%s' just created: %s\n",
4661 smb_fname_str_dbg(smb_dname), nt_errstr(status)));
4662 return status;
4666 notify_fname(conn, NOTIFY_ACTION_ADDED, FILE_NOTIFY_CHANGE_DIR_NAME,
4667 smb_dname->base_name);
4669 return NT_STATUS_OK;
4672 /****************************************************************************
4673 Open a directory from an NT SMB call.
4674 ****************************************************************************/
4676 static NTSTATUS open_directory(connection_struct *conn,
4677 struct smb_request *req,
4678 uint32_t access_mask,
4679 uint32_t share_access,
4680 uint32_t create_disposition,
4681 uint32_t create_options,
4682 uint32_t file_attributes,
4683 struct smb_filename *parent_dir_fname,
4684 struct smb_filename *smb_fname_atname,
4685 int *pinfo,
4686 struct files_struct *fsp)
4688 struct smb_filename *smb_dname = fsp->fsp_name;
4689 bool dir_existed = VALID_STAT(smb_dname->st);
4690 struct open_ntcreate_lock_state lck_state = {};
4691 bool keep_locked = false;
4692 NTSTATUS status;
4693 struct timespec mtimespec;
4694 int info = 0;
4695 uint32_t need_fd_access;
4696 NTSTATUS ulstatus;
4698 if (is_ntfs_stream_smb_fname(smb_dname)) {
4699 DEBUG(2, ("open_directory: %s is a stream name!\n",
4700 smb_fname_str_dbg(smb_dname)));
4701 return NT_STATUS_NOT_A_DIRECTORY;
4704 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS)) {
4705 /* Ensure we have a directory attribute. */
4706 file_attributes |= FILE_ATTRIBUTE_DIRECTORY;
4709 DBG_INFO("opening directory %s, access_mask = 0x%"PRIx32", "
4710 "share_access = 0x%"PRIx32" create_options = 0x%"PRIx32", "
4711 "create_disposition = 0x%"PRIx32", "
4712 "file_attributes = 0x%"PRIx32"\n",
4713 smb_fname_str_dbg(smb_dname),
4714 access_mask,
4715 share_access,
4716 create_options,
4717 create_disposition,
4718 file_attributes);
4720 status = smbd_calculate_access_mask_fsp(parent_dir_fname->fsp,
4721 smb_dname->fsp,
4722 false,
4723 access_mask,
4724 &access_mask);
4725 if (!NT_STATUS_IS_OK(status)) {
4726 DBG_DEBUG("smbd_calculate_access_mask_fsp "
4727 "on file %s returned %s\n",
4728 smb_fname_str_dbg(smb_dname),
4729 nt_errstr(status));
4730 return status;
4733 if ((access_mask & SEC_FLAG_SYSTEM_SECURITY) &&
4734 !security_token_has_privilege(get_current_nttok(conn),
4735 SEC_PRIV_SECURITY)) {
4736 DEBUG(10, ("open_directory: open on %s "
4737 "failed - SEC_FLAG_SYSTEM_SECURITY denied.\n",
4738 smb_fname_str_dbg(smb_dname)));
4739 return NT_STATUS_PRIVILEGE_NOT_HELD;
4742 switch( create_disposition ) {
4743 case FILE_OPEN:
4745 if (!dir_existed) {
4746 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4749 info = FILE_WAS_OPENED;
4750 break;
4752 case FILE_CREATE:
4754 /* If directory exists error. If directory doesn't
4755 * exist create. */
4757 if (dir_existed) {
4758 status = NT_STATUS_OBJECT_NAME_COLLISION;
4759 DEBUG(2, ("open_directory: unable to create "
4760 "%s. Error was %s\n",
4761 smb_fname_str_dbg(smb_dname),
4762 nt_errstr(status)));
4763 return status;
4766 status = mkdir_internal(conn,
4767 parent_dir_fname,
4768 smb_fname_atname,
4769 smb_dname,
4770 file_attributes,
4771 fsp);
4773 if (!NT_STATUS_IS_OK(status)) {
4774 DEBUG(2, ("open_directory: unable to create "
4775 "%s. Error was %s\n",
4776 smb_fname_str_dbg(smb_dname),
4777 nt_errstr(status)));
4778 return status;
4781 info = FILE_WAS_CREATED;
4782 break;
4784 case FILE_OPEN_IF:
4786 * If directory exists open. If directory doesn't
4787 * exist create.
4790 if (dir_existed) {
4791 status = NT_STATUS_OK;
4792 info = FILE_WAS_OPENED;
4793 } else {
4794 status = mkdir_internal(conn,
4795 parent_dir_fname,
4796 smb_fname_atname,
4797 smb_dname,
4798 file_attributes,
4799 fsp);
4801 if (NT_STATUS_IS_OK(status)) {
4802 info = FILE_WAS_CREATED;
4803 } else {
4804 /* Cope with create race. */
4805 if (!NT_STATUS_EQUAL(status,
4806 NT_STATUS_OBJECT_NAME_COLLISION)) {
4807 DEBUG(2, ("open_directory: unable to create "
4808 "%s. Error was %s\n",
4809 smb_fname_str_dbg(smb_dname),
4810 nt_errstr(status)));
4811 return status;
4815 * If mkdir_internal() returned
4816 * NT_STATUS_OBJECT_NAME_COLLISION
4817 * we still must lstat the path.
4820 if (SMB_VFS_LSTAT(conn, smb_dname)
4821 == -1) {
4822 DEBUG(2, ("Could not stat "
4823 "directory '%s' just "
4824 "opened: %s\n",
4825 smb_fname_str_dbg(
4826 smb_dname),
4827 strerror(errno)));
4828 return map_nt_error_from_unix(
4829 errno);
4832 info = FILE_WAS_OPENED;
4836 break;
4838 case FILE_SUPERSEDE:
4839 case FILE_OVERWRITE:
4840 case FILE_OVERWRITE_IF:
4841 default:
4842 DEBUG(5,("open_directory: invalid create_disposition "
4843 "0x%x for directory %s\n",
4844 (unsigned int)create_disposition,
4845 smb_fname_str_dbg(smb_dname)));
4846 return NT_STATUS_INVALID_PARAMETER;
4849 if(!S_ISDIR(smb_dname->st.st_ex_mode)) {
4850 DEBUG(5,("open_directory: %s is not a directory !\n",
4851 smb_fname_str_dbg(smb_dname)));
4852 return NT_STATUS_NOT_A_DIRECTORY;
4856 * Setup the files_struct for it.
4859 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_dname->st);
4860 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
4861 fsp->file_pid = req ? req->smbpid : 0;
4862 fsp->fsp_flags.can_lock = false;
4863 fsp->fsp_flags.can_read = false;
4864 fsp->fsp_flags.can_write = false;
4866 fh_set_private_options(fsp->fh, 0);
4868 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
4870 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
4871 fsp->print_file = NULL;
4872 fsp->fsp_flags.modified = false;
4873 fsp->oplock_type = NO_OPLOCK;
4874 fsp->sent_oplock_break = NO_BREAK_SENT;
4875 fsp->fsp_flags.is_directory = true;
4876 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
4877 fsp->posix_flags |= FSP_POSIX_FLAGS_ALL;
4880 /* Don't store old timestamps for directory
4881 handles in the internal database. We don't
4882 update them in there if new objects
4883 are created in the directory. Currently
4884 we only update timestamps on file writes.
4885 See bug #9870.
4887 mtimespec = make_omit_timespec();
4890 * Obviously for FILE_LIST_DIRECTORY we need to reopen to get an fd
4891 * usable for reading a directory. SMB2_FLUSH may be called on
4892 * directories opened with FILE_ADD_FILE and FILE_ADD_SUBDIRECTORY so
4893 * for those we need to reopen as well.
4895 need_fd_access =
4896 FILE_LIST_DIRECTORY |
4897 FILE_ADD_FILE |
4898 FILE_ADD_SUBDIRECTORY;
4900 if (access_mask & need_fd_access) {
4901 status = reopen_from_fsp(
4902 fsp->conn->cwd_fsp,
4903 fsp->fsp_name,
4904 fsp,
4905 O_RDONLY | O_DIRECTORY,
4907 NULL);
4908 if (!NT_STATUS_IS_OK(status)) {
4909 DBG_INFO("Could not open fd for [%s]: %s\n",
4910 smb_fname_str_dbg(smb_dname),
4911 nt_errstr(status));
4912 return status;
4916 status = vfs_stat_fsp(fsp);
4917 if (!NT_STATUS_IS_OK(status)) {
4918 fd_close(fsp);
4919 return status;
4922 if(!S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
4923 DEBUG(5,("open_directory: %s is not a directory !\n",
4924 smb_fname_str_dbg(smb_dname)));
4925 fd_close(fsp);
4926 return NT_STATUS_NOT_A_DIRECTORY;
4929 /* Ensure there was no race condition. We need to check
4930 * dev/inode but not permissions, as these can change
4931 * legitimately */
4932 if (!check_same_dev_ino(&smb_dname->st, &fsp->fsp_name->st)) {
4933 DEBUG(5,("open_directory: stat struct differs for "
4934 "directory %s.\n",
4935 smb_fname_str_dbg(smb_dname)));
4936 fd_close(fsp);
4937 return NT_STATUS_ACCESS_DENIED;
4940 if (info == FILE_WAS_OPENED) {
4941 status = smbd_check_access_rights_fsp(parent_dir_fname->fsp,
4942 fsp,
4943 false,
4944 access_mask);
4945 if (!NT_STATUS_IS_OK(status)) {
4946 DBG_DEBUG("smbd_check_access_rights_fsp on "
4947 "file %s failed with %s\n",
4948 fsp_str_dbg(fsp),
4949 nt_errstr(status));
4950 fd_close(fsp);
4951 return status;
4956 * If we created a new directory or going to delete it later,
4957 * we should keep * the share_mode_lock (g_lock) until we call
4958 * share_mode_entry_prepare_unlock()
4960 if (info != FILE_WAS_OPENED) {
4961 keep_locked = true;
4962 } else if (create_options & FILE_DELETE_ON_CLOSE) {
4963 keep_locked = true;
4966 lck_state = (struct open_ntcreate_lock_state) {
4967 .fsp = fsp,
4968 .object_type = "directory",
4969 .req = req,
4970 .create_disposition = create_disposition,
4971 .access_mask = access_mask,
4972 .share_access = share_access,
4973 .oplock_request = NO_OPLOCK,
4974 .lease = NULL,
4975 .first_open_attempt = true,
4976 .keep_locked = keep_locked,
4979 status = share_mode_entry_prepare_lock_add(&lck_state.prepare_state,
4980 fsp->file_id,
4981 conn->connectpath,
4982 smb_dname,
4983 &mtimespec,
4984 open_ntcreate_lock_add_entry,
4985 &lck_state);
4986 if (!NT_STATUS_IS_OK(status)) {
4987 DBG_ERR("share_mode_entry_prepare_lock_add() failed for %s - %s\n",
4988 smb_fname_str_dbg(smb_dname), nt_errstr(status));
4989 fd_close(fsp);
4990 return status;
4993 status = lck_state.status;
4994 if (!NT_STATUS_IS_OK(status)) {
4995 fd_close(fsp);
4996 return status;
5000 * From here we need to use 'goto unlock;' instead of return !!!
5003 /* For directories the delete on close bit at open time seems
5004 always to be honored on close... See test 19 in Samba4 BASE-DELETE. */
5005 if (create_options & FILE_DELETE_ON_CLOSE) {
5006 status = can_set_delete_on_close(fsp, 0);
5007 if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
5008 lck_state.cleanup_fn =
5009 open_ntcreate_lock_cleanup_entry;
5010 goto unlock;
5013 if (NT_STATUS_IS_OK(status)) {
5014 /* Note that here we set the *initial* delete on close flag,
5015 not the regular one. The magic gets handled in close. */
5016 fsp->fsp_flags.initial_delete_on_close = true;
5021 * Deal with other opens having a modified write time.
5023 if (!is_omit_timespec(&lck_state.write_time)) {
5024 update_stat_ex_mtime(&fsp->fsp_name->st, lck_state.write_time);
5027 if (pinfo) {
5028 *pinfo = info;
5031 status = NT_STATUS_OK;
5033 unlock:
5034 ulstatus = share_mode_entry_prepare_unlock(&lck_state.prepare_state,
5035 lck_state.cleanup_fn,
5036 &lck_state);
5037 if (!NT_STATUS_IS_OK(ulstatus)) {
5038 DBG_ERR("share_mode_entry_prepare_unlock() failed for %s - %s\n",
5039 smb_fname_str_dbg(smb_dname), nt_errstr(ulstatus));
5040 smb_panic("share_mode_entry_prepare_unlock() failed!");
5043 if (!NT_STATUS_IS_OK(status)) {
5044 fd_close(fsp);
5045 return status;
5048 return NT_STATUS_OK;
5051 NTSTATUS create_directory(connection_struct *conn,
5052 struct smb_request *req,
5053 struct files_struct *dirfsp,
5054 struct smb_filename *smb_dname)
5056 NTSTATUS status;
5057 files_struct *fsp;
5059 status = SMB_VFS_CREATE_FILE(
5060 conn, /* conn */
5061 req, /* req */
5062 dirfsp, /* dirfsp */
5063 smb_dname, /* fname */
5064 FILE_READ_ATTRIBUTES, /* access_mask */
5065 FILE_SHARE_NONE, /* share_access */
5066 FILE_CREATE, /* create_disposition*/
5067 FILE_DIRECTORY_FILE, /* create_options */
5068 FILE_ATTRIBUTE_DIRECTORY, /* file_attributes */
5069 0, /* oplock_request */
5070 NULL, /* lease */
5071 0, /* allocation_size */
5072 0, /* private_flags */
5073 NULL, /* sd */
5074 NULL, /* ea_list */
5075 &fsp, /* result */
5076 NULL, /* pinfo */
5077 NULL, NULL); /* create context */
5079 if (NT_STATUS_IS_OK(status)) {
5080 close_file_free(req, &fsp, NORMAL_CLOSE);
5083 return status;
5086 /****************************************************************************
5087 Receive notification that one of our open files has been renamed by another
5088 smbd process.
5089 ****************************************************************************/
5091 void msg_file_was_renamed(struct messaging_context *msg_ctx,
5092 void *private_data,
5093 uint32_t msg_type,
5094 struct server_id src,
5095 DATA_BLOB *data)
5097 struct file_rename_message *msg = NULL;
5098 enum ndr_err_code ndr_err;
5099 files_struct *fsp;
5100 struct smb_filename *smb_fname = NULL;
5101 struct smbd_server_connection *sconn =
5102 talloc_get_type_abort(private_data,
5103 struct smbd_server_connection);
5105 msg = talloc(talloc_tos(), struct file_rename_message);
5106 if (msg == NULL) {
5107 DBG_WARNING("talloc failed\n");
5108 return;
5111 ndr_err = ndr_pull_struct_blob_all(
5112 data,
5113 msg,
5114 msg,
5115 (ndr_pull_flags_fn_t)ndr_pull_file_rename_message);
5116 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
5117 DBG_DEBUG("ndr_pull_oplock_break_message failed: %s\n",
5118 ndr_errstr(ndr_err));
5119 goto out;
5121 if (DEBUGLEVEL >= 10) {
5122 struct server_id_buf buf;
5123 DBG_DEBUG("Got rename message from %s\n",
5124 server_id_str_buf(src, &buf));
5125 NDR_PRINT_DEBUG(file_rename_message, msg);
5128 /* stream_name must always be NULL if there is no stream. */
5129 if ((msg->stream_name != NULL) && (msg->stream_name[0] == '\0')) {
5130 msg->stream_name = NULL;
5133 smb_fname = synthetic_smb_fname(msg,
5134 msg->base_name,
5135 msg->stream_name,
5136 NULL,
5139 if (smb_fname == NULL) {
5140 DBG_DEBUG("synthetic_smb_fname failed\n");
5141 goto out;
5144 fsp = file_find_dif(sconn, msg->id, msg->share_file_id);
5145 if (fsp == NULL) {
5146 DBG_DEBUG("fsp not found\n");
5147 goto out;
5150 if (strcmp(fsp->conn->connectpath, msg->servicepath) == 0) {
5151 SMB_STRUCT_STAT fsp_orig_sbuf;
5152 NTSTATUS status;
5153 DBG_DEBUG("renaming file %s from %s -> %s\n",
5154 fsp_fnum_dbg(fsp),
5155 fsp_str_dbg(fsp),
5156 smb_fname_str_dbg(smb_fname));
5159 * The incoming smb_fname here has an
5160 * invalid stat struct from synthetic_smb_fname()
5161 * above.
5162 * Preserve the existing stat from the
5163 * open fsp after fsp_set_smb_fname()
5164 * overwrites with the invalid stat.
5166 * (We could just copy this into
5167 * smb_fname->st, but keep this code
5168 * identical to the fix in rename_open_files()
5169 * for clarity.
5171 * We will do an fstat before returning
5172 * any of this metadata to the client anyway.
5174 fsp_orig_sbuf = fsp->fsp_name->st;
5175 status = fsp_set_smb_fname(fsp, smb_fname);
5176 if (!NT_STATUS_IS_OK(status)) {
5177 DBG_DEBUG("fsp_set_smb_fname failed: %s\n",
5178 nt_errstr(status));
5180 fsp->fsp_name->st = fsp_orig_sbuf;
5181 } else {
5182 /* TODO. JRA. */
5184 * Now we have the complete path we can work out if
5185 * this is actually within this share and adjust
5186 * newname accordingly.
5188 DBG_DEBUG("share mismatch (sharepath %s not sharepath %s) "
5189 "%s from %s -> %s\n",
5190 fsp->conn->connectpath,
5191 msg->servicepath,
5192 fsp_fnum_dbg(fsp),
5193 fsp_str_dbg(fsp),
5194 smb_fname_str_dbg(smb_fname));
5196 out:
5197 TALLOC_FREE(msg);
5201 * If a main file is opened for delete, all streams need to be checked for
5202 * !FILE_SHARE_DELETE. Do this by opening with DELETE_ACCESS.
5203 * If that works, delete them all by setting the delete on close and close.
5206 static NTSTATUS open_streams_for_delete(connection_struct *conn,
5207 const struct smb_filename *smb_fname)
5209 struct stream_struct *stream_info = NULL;
5210 files_struct **streams = NULL;
5211 int j;
5212 unsigned int i, num_streams = 0;
5213 TALLOC_CTX *frame = talloc_stackframe();
5214 const struct smb_filename *pathref = NULL;
5215 NTSTATUS status;
5217 if (smb_fname->fsp == NULL) {
5218 struct smb_filename *tmp = NULL;
5219 status = synthetic_pathref(frame,
5220 conn->cwd_fsp,
5221 smb_fname->base_name,
5222 NULL,
5223 NULL,
5224 smb_fname->twrp,
5225 smb_fname->flags,
5226 &tmp);
5227 if (!NT_STATUS_IS_OK(status)) {
5228 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
5229 || NT_STATUS_EQUAL(status,
5230 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
5231 DBG_DEBUG("no streams around\n");
5232 TALLOC_FREE(frame);
5233 return NT_STATUS_OK;
5235 DBG_DEBUG("synthetic_pathref failed: %s\n",
5236 nt_errstr(status));
5237 goto fail;
5239 pathref = tmp;
5240 } else {
5241 pathref = smb_fname;
5243 status = vfs_fstreaminfo(pathref->fsp, talloc_tos(),
5244 &num_streams, &stream_info);
5246 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
5247 || NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
5248 DEBUG(10, ("no streams around\n"));
5249 TALLOC_FREE(frame);
5250 return NT_STATUS_OK;
5253 if (!NT_STATUS_IS_OK(status)) {
5254 DEBUG(10, ("vfs_fstreaminfo failed: %s\n",
5255 nt_errstr(status)));
5256 goto fail;
5259 DEBUG(10, ("open_streams_for_delete found %d streams\n",
5260 num_streams));
5262 if (num_streams == 0) {
5263 TALLOC_FREE(frame);
5264 return NT_STATUS_OK;
5267 streams = talloc_array(talloc_tos(), files_struct *, num_streams);
5268 if (streams == NULL) {
5269 DEBUG(0, ("talloc failed\n"));
5270 status = NT_STATUS_NO_MEMORY;
5271 goto fail;
5274 for (i=0; i<num_streams; i++) {
5275 struct smb_filename *smb_fname_cp;
5277 if (strequal(stream_info[i].name, "::$DATA")) {
5278 streams[i] = NULL;
5279 continue;
5282 smb_fname_cp = synthetic_smb_fname(talloc_tos(),
5283 smb_fname->base_name,
5284 stream_info[i].name,
5285 NULL,
5286 smb_fname->twrp,
5287 (smb_fname->flags &
5288 ~SMB_FILENAME_POSIX_PATH));
5289 if (smb_fname_cp == NULL) {
5290 status = NT_STATUS_NO_MEMORY;
5291 goto fail;
5294 status = openat_pathref_fsp(conn->cwd_fsp, smb_fname_cp);
5295 if (!NT_STATUS_IS_OK(status)) {
5296 DBG_DEBUG("Unable to open stream [%s]: %s\n",
5297 smb_fname_str_dbg(smb_fname_cp),
5298 nt_errstr(status));
5299 TALLOC_FREE(smb_fname_cp);
5300 break;
5303 status = SMB_VFS_CREATE_FILE(
5304 conn, /* conn */
5305 NULL, /* req */
5306 NULL, /* dirfsp */
5307 smb_fname_cp, /* fname */
5308 DELETE_ACCESS, /* access_mask */
5309 (FILE_SHARE_READ | /* share_access */
5310 FILE_SHARE_WRITE | FILE_SHARE_DELETE),
5311 FILE_OPEN, /* create_disposition*/
5312 0, /* create_options */
5313 FILE_ATTRIBUTE_NORMAL, /* file_attributes */
5314 0, /* oplock_request */
5315 NULL, /* lease */
5316 0, /* allocation_size */
5317 0, /* private_flags */
5318 NULL, /* sd */
5319 NULL, /* ea_list */
5320 &streams[i], /* result */
5321 NULL, /* pinfo */
5322 NULL, NULL); /* create context */
5324 if (!NT_STATUS_IS_OK(status)) {
5325 DEBUG(10, ("Could not open stream %s: %s\n",
5326 smb_fname_str_dbg(smb_fname_cp),
5327 nt_errstr(status)));
5329 TALLOC_FREE(smb_fname_cp);
5330 break;
5332 TALLOC_FREE(smb_fname_cp);
5336 * don't touch the variable "status" beyond this point :-)
5339 for (j = i-1 ; j >= 0; j--) {
5340 if (streams[j] == NULL) {
5341 continue;
5344 DEBUG(10, ("Closing stream # %d, %s\n", j,
5345 fsp_str_dbg(streams[j])));
5346 close_file_free(NULL, &streams[j], NORMAL_CLOSE);
5349 fail:
5350 TALLOC_FREE(frame);
5351 return status;
5354 /*********************************************************************
5355 Create a default ACL by inheriting from the parent. If no inheritance
5356 from the parent available, don't set anything. This will leave the actual
5357 permissions the new file or directory already got from the filesystem
5358 as the NT ACL when read.
5359 *********************************************************************/
5361 static NTSTATUS inherit_new_acl(files_struct *dirfsp, files_struct *fsp)
5363 TALLOC_CTX *frame = talloc_stackframe();
5364 struct security_descriptor *parent_desc = NULL;
5365 NTSTATUS status = NT_STATUS_OK;
5366 struct security_descriptor *psd = NULL;
5367 const struct dom_sid *owner_sid = NULL;
5368 const struct dom_sid *group_sid = NULL;
5369 uint32_t security_info_sent = (SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL);
5370 struct security_token *token = fsp->conn->session_info->security_token;
5371 bool inherit_owner =
5372 (lp_inherit_owner(SNUM(fsp->conn)) == INHERIT_OWNER_WINDOWS_AND_UNIX);
5373 bool inheritable_components = false;
5374 bool try_builtin_administrators = false;
5375 const struct dom_sid *BA_U_sid = NULL;
5376 const struct dom_sid *BA_G_sid = NULL;
5377 bool try_system = false;
5378 const struct dom_sid *SY_U_sid = NULL;
5379 const struct dom_sid *SY_G_sid = NULL;
5380 size_t size = 0;
5381 bool ok;
5383 status = SMB_VFS_FGET_NT_ACL(dirfsp,
5384 (SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL),
5385 frame,
5386 &parent_desc);
5387 if (!NT_STATUS_IS_OK(status)) {
5388 TALLOC_FREE(frame);
5389 return status;
5392 inheritable_components = sd_has_inheritable_components(parent_desc,
5393 fsp->fsp_flags.is_directory);
5395 if (!inheritable_components && !inherit_owner) {
5396 TALLOC_FREE(frame);
5397 /* Nothing to inherit and not setting owner. */
5398 return NT_STATUS_OK;
5401 /* Create an inherited descriptor from the parent. */
5403 if (DEBUGLEVEL >= 10) {
5404 DEBUG(10,("inherit_new_acl: parent acl for %s is:\n",
5405 fsp_str_dbg(fsp) ));
5406 NDR_PRINT_DEBUG(security_descriptor, parent_desc);
5409 /* Inherit from parent descriptor if "inherit owner" set. */
5410 if (inherit_owner) {
5411 owner_sid = parent_desc->owner_sid;
5412 group_sid = parent_desc->group_sid;
5415 if (owner_sid == NULL) {
5416 if (security_token_has_builtin_administrators(token)) {
5417 try_builtin_administrators = true;
5418 } else if (security_token_is_system(token)) {
5419 try_builtin_administrators = true;
5420 try_system = true;
5424 if (group_sid == NULL &&
5425 token->num_sids == PRIMARY_GROUP_SID_INDEX)
5427 if (security_token_is_system(token)) {
5428 try_builtin_administrators = true;
5429 try_system = true;
5433 if (try_builtin_administrators) {
5434 struct unixid ids = { .id = 0 };
5436 ok = sids_to_unixids(&global_sid_Builtin_Administrators, 1, &ids);
5437 if (ok) {
5438 switch (ids.type) {
5439 case ID_TYPE_BOTH:
5440 BA_U_sid = &global_sid_Builtin_Administrators;
5441 BA_G_sid = &global_sid_Builtin_Administrators;
5442 break;
5443 case ID_TYPE_UID:
5444 BA_U_sid = &global_sid_Builtin_Administrators;
5445 break;
5446 case ID_TYPE_GID:
5447 BA_G_sid = &global_sid_Builtin_Administrators;
5448 break;
5449 default:
5450 break;
5455 if (try_system) {
5456 struct unixid ids = { .id = 0 };
5458 ok = sids_to_unixids(&global_sid_System, 1, &ids);
5459 if (ok) {
5460 switch (ids.type) {
5461 case ID_TYPE_BOTH:
5462 SY_U_sid = &global_sid_System;
5463 SY_G_sid = &global_sid_System;
5464 break;
5465 case ID_TYPE_UID:
5466 SY_U_sid = &global_sid_System;
5467 break;
5468 case ID_TYPE_GID:
5469 SY_G_sid = &global_sid_System;
5470 break;
5471 default:
5472 break;
5477 if (owner_sid == NULL) {
5478 owner_sid = BA_U_sid;
5481 if (owner_sid == NULL) {
5482 owner_sid = SY_U_sid;
5485 if (group_sid == NULL) {
5486 group_sid = SY_G_sid;
5489 if (try_system && group_sid == NULL) {
5490 group_sid = BA_G_sid;
5493 if (owner_sid == NULL) {
5494 owner_sid = &token->sids[PRIMARY_USER_SID_INDEX];
5496 if (group_sid == NULL) {
5497 if (token->num_sids == PRIMARY_GROUP_SID_INDEX) {
5498 group_sid = &token->sids[PRIMARY_USER_SID_INDEX];
5499 } else {
5500 group_sid = &token->sids[PRIMARY_GROUP_SID_INDEX];
5504 status = se_create_child_secdesc(frame,
5505 &psd,
5506 &size,
5507 parent_desc,
5508 owner_sid,
5509 group_sid,
5510 fsp->fsp_flags.is_directory);
5511 if (!NT_STATUS_IS_OK(status)) {
5512 TALLOC_FREE(frame);
5513 return status;
5516 /* If inheritable_components == false,
5517 se_create_child_secdesc()
5518 creates a security descriptor with a NULL dacl
5519 entry, but with SEC_DESC_DACL_PRESENT. We need
5520 to remove that flag. */
5522 if (!inheritable_components) {
5523 security_info_sent &= ~SECINFO_DACL;
5524 psd->type &= ~SEC_DESC_DACL_PRESENT;
5527 if (DEBUGLEVEL >= 10) {
5528 DEBUG(10,("inherit_new_acl: child acl for %s is:\n",
5529 fsp_str_dbg(fsp) ));
5530 NDR_PRINT_DEBUG(security_descriptor, psd);
5533 if (inherit_owner) {
5534 /* We need to be root to force this. */
5535 become_root();
5537 status = SMB_VFS_FSET_NT_ACL(metadata_fsp(fsp),
5538 security_info_sent,
5539 psd);
5540 if (inherit_owner) {
5541 unbecome_root();
5543 TALLOC_FREE(frame);
5544 return status;
5548 * If we already have a lease, it must match the new file id. [MS-SMB2]
5549 * 3.3.5.9.8 speaks about INVALID_PARAMETER if an already used lease key is
5550 * used for a different file name.
5553 struct lease_match_state {
5554 /* Input parameters. */
5555 TALLOC_CTX *mem_ctx;
5556 const char *servicepath;
5557 const struct smb_filename *fname;
5558 bool file_existed;
5559 struct file_id id;
5560 /* Return parameters. */
5561 uint32_t num_file_ids;
5562 struct file_id *ids;
5563 NTSTATUS match_status;
5566 /*************************************************************
5567 File doesn't exist but this lease key+guid is already in use.
5569 This is only allowable in the dynamic share case where the
5570 service path must be different.
5572 There is a small race condition here in the multi-connection
5573 case where a client sends two create calls on different connections,
5574 where the file doesn't exist and one smbd creates the leases_db
5575 entry first, but this will get fixed by the multichannel cleanup
5576 when all identical client_guids get handled by a single smbd.
5577 **************************************************************/
5579 static void lease_match_parser_new_file(
5580 uint32_t num_files,
5581 const struct leases_db_file *files,
5582 struct lease_match_state *state)
5584 uint32_t i;
5586 for (i = 0; i < num_files; i++) {
5587 const struct leases_db_file *f = &files[i];
5588 if (strequal(state->servicepath, f->servicepath)) {
5589 state->match_status = NT_STATUS_INVALID_PARAMETER;
5590 return;
5594 /* Dynamic share case. Break leases on all other files. */
5595 state->match_status = leases_db_copy_file_ids(state->mem_ctx,
5596 num_files,
5597 files,
5598 &state->ids);
5599 if (!NT_STATUS_IS_OK(state->match_status)) {
5600 return;
5603 state->num_file_ids = num_files;
5604 state->match_status = NT_STATUS_OPLOCK_NOT_GRANTED;
5605 return;
5608 static void lease_match_parser(
5609 uint32_t num_files,
5610 const struct leases_db_file *files,
5611 void *private_data)
5613 struct lease_match_state *state =
5614 (struct lease_match_state *)private_data;
5615 uint32_t i;
5617 if (!state->file_existed) {
5619 * Deal with name mismatch or
5620 * possible dynamic share case separately
5621 * to make code clearer.
5623 lease_match_parser_new_file(num_files,
5624 files,
5625 state);
5626 return;
5629 /* File existed. */
5630 state->match_status = NT_STATUS_OK;
5632 for (i = 0; i < num_files; i++) {
5633 const struct leases_db_file *f = &files[i];
5635 /* Everything should be the same. */
5636 if (!file_id_equal(&state->id, &f->id)) {
5638 * The client asked for a lease on a
5639 * file that doesn't match the file_id
5640 * in the database.
5642 * Maybe this is a dynamic share, i.e.
5643 * a share where the servicepath is
5644 * different for different users (e.g.
5645 * the [HOMES] share.
5647 * If the servicepath is different, but the requested
5648 * file name + stream name is the same then this is
5649 * a dynamic share, the client is using the same share
5650 * name and doesn't know that the underlying servicepath
5651 * is different. It was expecting a lease on the
5652 * same file. Return NT_STATUS_OPLOCK_NOT_GRANTED
5653 * to break leases
5655 * Otherwise the client has messed up, or is
5656 * testing our error codes, so return
5657 * NT_STATUS_INVALID_PARAMETER.
5659 if (!strequal(f->servicepath, state->servicepath) &&
5660 strequal(f->base_name, state->fname->base_name) &&
5661 strequal(f->stream_name, state->fname->stream_name))
5664 * Name is the same but servicepath is
5665 * different, dynamic share. Break leases.
5667 state->match_status =
5668 NT_STATUS_OPLOCK_NOT_GRANTED;
5669 } else {
5670 state->match_status =
5671 NT_STATUS_INVALID_PARAMETER;
5673 break;
5675 if (!strequal(f->servicepath, state->servicepath)) {
5676 state->match_status = NT_STATUS_INVALID_PARAMETER;
5677 break;
5679 if (!strequal(f->base_name, state->fname->base_name)) {
5680 state->match_status = NT_STATUS_INVALID_PARAMETER;
5681 break;
5683 if (!strequal(f->stream_name, state->fname->stream_name)) {
5684 state->match_status = NT_STATUS_INVALID_PARAMETER;
5685 break;
5689 if (NT_STATUS_IS_OK(state->match_status)) {
5691 * Common case - just opening another handle on a
5692 * file on a non-dynamic share.
5694 return;
5697 if (NT_STATUS_EQUAL(state->match_status, NT_STATUS_INVALID_PARAMETER)) {
5698 /* Mismatched path. Error back to client. */
5699 return;
5703 * File id mismatch. Dynamic share case NT_STATUS_OPLOCK_NOT_GRANTED.
5704 * Don't allow leases.
5707 state->match_status = leases_db_copy_file_ids(state->mem_ctx,
5708 num_files,
5709 files,
5710 &state->ids);
5711 if (!NT_STATUS_IS_OK(state->match_status)) {
5712 return;
5715 state->num_file_ids = num_files;
5716 state->match_status = NT_STATUS_OPLOCK_NOT_GRANTED;
5717 return;
5720 struct lease_match_break_state {
5721 struct messaging_context *msg_ctx;
5722 const struct smb2_lease_key *lease_key;
5723 struct file_id id;
5725 bool found_lease;
5726 uint16_t version;
5727 uint16_t epoch;
5730 static bool lease_match_break_fn(
5731 struct share_mode_entry *e,
5732 void *private_data)
5734 struct lease_match_break_state *state = private_data;
5735 bool stale, equal;
5736 uint32_t e_lease_type = SMB2_LEASE_NONE;
5737 NTSTATUS status;
5739 stale = share_entry_stale_pid(e);
5740 if (stale) {
5741 return false;
5744 equal = smb2_lease_key_equal(&e->lease_key, state->lease_key);
5745 if (!equal) {
5746 return false;
5749 status = leases_db_get(
5750 &e->client_guid,
5751 &e->lease_key,
5752 &state->id,
5753 &e_lease_type, /* current_state */
5754 NULL, /* breaking */
5755 NULL, /* breaking_to_requested */
5756 NULL, /* breaking_to_required */
5757 &state->version, /* lease_version */
5758 &state->epoch); /* epoch */
5759 if (NT_STATUS_IS_OK(status)) {
5760 state->found_lease = true;
5761 } else {
5762 DBG_WARNING("Could not find version/epoch: %s\n",
5763 nt_errstr(status));
5764 return false;
5767 if (e_lease_type == SMB2_LEASE_NONE) {
5768 return false;
5770 send_break_message(state->msg_ctx, &state->id, e, SMB2_LEASE_NONE);
5773 * Windows 7 and 8 lease clients are broken in that they will
5774 * not respond to lease break requests whilst waiting for an
5775 * outstanding open request on that lease handle on the same
5776 * TCP connection, due to holding an internal inode lock.
5778 * This means we can't reschedule ourselves here, but must
5779 * return from the create.
5781 * Work around:
5783 * Send the breaks and then return SMB2_LEASE_NONE in the
5784 * lease handle to cause them to acknowledge the lease
5785 * break. Consultation with Microsoft engineering confirmed
5786 * this approach is safe.
5789 return false;
5792 static void lease_match_fid_fn(struct share_mode_lock *lck,
5793 void *private_data)
5795 bool ok;
5797 ok = share_mode_forall_leases(lck, lease_match_break_fn, private_data);
5798 if (!ok) {
5799 DBG_DEBUG("share_mode_forall_leases failed\n");
5803 static NTSTATUS lease_match(connection_struct *conn,
5804 struct smb_request *req,
5805 const struct smb2_lease_key *lease_key,
5806 const char *servicepath,
5807 const struct smb_filename *fname,
5808 uint16_t *p_version,
5809 uint16_t *p_epoch)
5811 struct smbd_server_connection *sconn = req->sconn;
5812 TALLOC_CTX *tos = talloc_tos();
5813 struct lease_match_state state = {
5814 .mem_ctx = tos,
5815 .servicepath = servicepath,
5816 .fname = fname,
5817 .match_status = NT_STATUS_OK
5819 uint32_t i;
5820 NTSTATUS status;
5822 state.file_existed = VALID_STAT(fname->st);
5823 if (state.file_existed) {
5824 state.id = vfs_file_id_from_sbuf(conn, &fname->st);
5827 status = leases_db_parse(&sconn->client->global->client_guid,
5828 lease_key, lease_match_parser, &state);
5829 if (!NT_STATUS_IS_OK(status)) {
5831 * Not found or error means okay: We can make the lease pass
5833 return NT_STATUS_OK;
5835 if (!NT_STATUS_EQUAL(state.match_status, NT_STATUS_OPLOCK_NOT_GRANTED)) {
5837 * Anything but NT_STATUS_OPLOCK_NOT_GRANTED, let the caller
5838 * deal with it.
5840 return state.match_status;
5843 /* We have to break all existing leases. */
5844 for (i = 0; i < state.num_file_ids; i++) {
5845 struct lease_match_break_state break_state = {
5846 .msg_ctx = conn->sconn->msg_ctx,
5847 .lease_key = lease_key,
5850 if (file_id_equal(&state.ids[i], &state.id)) {
5851 /* Don't need to break our own file. */
5852 continue;
5855 break_state.id = state.ids[i];
5857 status = share_mode_do_locked_vfs_denied(break_state.id,
5858 lease_match_fid_fn,
5859 &break_state);
5860 if (!NT_STATUS_IS_OK(status)) {
5861 /* Race condition - file already closed. */
5862 continue;
5865 if (break_state.found_lease) {
5866 *p_version = break_state.version;
5867 *p_epoch = break_state.epoch;
5871 * Ensure we don't grant anything more so we
5872 * never upgrade.
5874 return NT_STATUS_OPLOCK_NOT_GRANTED;
5878 * Wrapper around open_file_ntcreate and open_directory
5881 static NTSTATUS create_file_unixpath(connection_struct *conn,
5882 struct smb_request *req,
5883 struct files_struct *dirfsp,
5884 struct smb_filename *smb_fname,
5885 uint32_t access_mask,
5886 uint32_t share_access,
5887 uint32_t create_disposition,
5888 uint32_t create_options,
5889 uint32_t file_attributes,
5890 uint32_t oplock_request,
5891 const struct smb2_lease *lease,
5892 uint64_t allocation_size,
5893 uint32_t private_flags,
5894 struct security_descriptor *sd,
5895 struct ea_list *ea_list,
5897 files_struct **result,
5898 int *pinfo)
5900 struct smb2_lease none_lease;
5901 int info = FILE_WAS_OPENED;
5902 files_struct *base_fsp = NULL;
5903 files_struct *fsp = NULL;
5904 bool free_fsp_on_error = false;
5905 NTSTATUS status;
5906 int ret;
5907 struct smb_filename *parent_dir_fname = NULL;
5908 struct smb_filename *smb_fname_atname = NULL;
5910 DBG_DEBUG("access_mask = 0x%"PRIx32" "
5911 "file_attributes = 0x%"PRIx32" "
5912 "share_access = 0x%"PRIx32" "
5913 "create_disposition = 0x%"PRIx32" "
5914 "create_options = 0x%"PRIx32" "
5915 "oplock_request = 0x%"PRIx32" "
5916 "private_flags = 0x%"PRIx32" "
5917 "ea_list = %p, "
5918 "sd = %p, "
5919 "fname = %s\n",
5920 access_mask,
5921 file_attributes,
5922 share_access,
5923 create_disposition,
5924 create_options,
5925 oplock_request,
5926 private_flags,
5927 ea_list,
5929 smb_fname_str_dbg(smb_fname));
5931 if (create_options & FILE_OPEN_BY_FILE_ID) {
5932 status = NT_STATUS_NOT_SUPPORTED;
5933 goto fail;
5936 if (create_options & NTCREATEX_OPTIONS_INVALID_PARAM_MASK) {
5937 status = NT_STATUS_INVALID_PARAMETER;
5938 goto fail;
5941 if (req == NULL) {
5942 oplock_request |= INTERNAL_OPEN_ONLY;
5945 if (lease != NULL) {
5946 uint16_t epoch = lease->lease_epoch;
5947 uint16_t version = lease->lease_version;
5949 if (req == NULL) {
5950 DBG_WARNING("Got lease on internal open\n");
5951 status = NT_STATUS_INTERNAL_ERROR;
5952 goto fail;
5955 status = lease_match(conn,
5956 req,
5957 &lease->lease_key,
5958 conn->connectpath,
5959 smb_fname,
5960 &version,
5961 &epoch);
5962 if (NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) {
5963 /* Dynamic share file. No leases and update epoch... */
5964 none_lease = *lease;
5965 none_lease.lease_state = SMB2_LEASE_NONE;
5966 none_lease.lease_epoch = epoch;
5967 none_lease.lease_version = version;
5968 lease = &none_lease;
5969 } else if (!NT_STATUS_IS_OK(status)) {
5970 goto fail;
5974 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
5975 && (access_mask & DELETE_ACCESS)
5976 && !is_named_stream(smb_fname)) {
5978 * We can't open a file with DELETE access if any of the
5979 * streams is open without FILE_SHARE_DELETE
5981 status = open_streams_for_delete(conn, smb_fname);
5983 if (!NT_STATUS_IS_OK(status)) {
5984 goto fail;
5988 if (access_mask & SEC_FLAG_SYSTEM_SECURITY) {
5989 bool ok;
5991 ok = security_token_has_privilege(get_current_nttok(conn),
5992 SEC_PRIV_SECURITY);
5993 if (!ok) {
5994 DBG_DEBUG("open on %s failed - "
5995 "SEC_FLAG_SYSTEM_SECURITY denied.\n",
5996 smb_fname_str_dbg(smb_fname));
5997 status = NT_STATUS_PRIVILEGE_NOT_HELD;
5998 goto fail;
6001 if (conn->sconn->using_smb2 &&
6002 (access_mask == SEC_FLAG_SYSTEM_SECURITY))
6005 * No other bits set. Windows SMB2 refuses this.
6006 * See smbtorture3 SMB2-SACL test.
6008 * Note this is an SMB2-only behavior,
6009 * smbtorture3 SMB1-SYSTEM-SECURITY already tests
6010 * that SMB1 allows this.
6012 status = NT_STATUS_ACCESS_DENIED;
6013 goto fail;
6018 * Files or directories can't be opened DELETE_ON_CLOSE without
6019 * delete access.
6020 * BUG: https://bugzilla.samba.org/show_bug.cgi?id=13358
6022 if (create_options & FILE_DELETE_ON_CLOSE) {
6023 if ((access_mask & DELETE_ACCESS) == 0) {
6024 status = NT_STATUS_INVALID_PARAMETER;
6025 goto fail;
6029 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
6030 && is_named_stream(smb_fname))
6032 uint32_t base_create_disposition;
6033 struct smb_filename *smb_fname_base = NULL;
6034 uint32_t base_privflags;
6036 if (create_options & FILE_DIRECTORY_FILE) {
6037 DBG_DEBUG("Can't open a stream as directory\n");
6038 status = NT_STATUS_NOT_A_DIRECTORY;
6039 goto fail;
6042 switch (create_disposition) {
6043 case FILE_OPEN:
6044 base_create_disposition = FILE_OPEN;
6045 break;
6046 default:
6047 base_create_disposition = FILE_OPEN_IF;
6048 break;
6051 smb_fname_base = cp_smb_filename_nostream(
6052 talloc_tos(), smb_fname);
6054 if (smb_fname_base == NULL) {
6055 status = NT_STATUS_NO_MEMORY;
6056 goto fail;
6060 * We may be creating the basefile as part of creating the
6061 * stream, so it's legal if the basefile doesn't exist at this
6062 * point, the create_file_unixpath() below will create it. But
6063 * if the basefile exists we want a handle so we can fstat() it.
6066 ret = vfs_stat(conn, smb_fname_base);
6067 if (ret == -1 && errno != ENOENT) {
6068 status = map_nt_error_from_unix(errno);
6069 TALLOC_FREE(smb_fname_base);
6070 goto fail;
6072 if (ret == 0) {
6073 status = openat_pathref_fsp(conn->cwd_fsp,
6074 smb_fname_base);
6075 if (!NT_STATUS_IS_OK(status)) {
6076 DBG_ERR("open_smb_fname_fsp [%s] failed: %s\n",
6077 smb_fname_str_dbg(smb_fname_base),
6078 nt_errstr(status));
6079 TALLOC_FREE(smb_fname_base);
6080 goto fail;
6084 * https://bugzilla.samba.org/show_bug.cgi?id=10229
6085 * We need to check if the requested access mask
6086 * could be used to open the underlying file (if
6087 * it existed), as we're passing in zero for the
6088 * access mask to the base filename.
6090 status = check_base_file_access(smb_fname_base->fsp,
6091 access_mask);
6093 if (!NT_STATUS_IS_OK(status)) {
6094 DEBUG(10, ("Permission check "
6095 "for base %s failed: "
6096 "%s\n", smb_fname->base_name,
6097 nt_errstr(status)));
6098 TALLOC_FREE(smb_fname_base);
6099 goto fail;
6103 base_privflags = NTCREATEX_FLAG_STREAM_BASEOPEN;
6105 /* Open the base file. */
6106 status = create_file_unixpath(conn,
6107 NULL,
6108 dirfsp,
6109 smb_fname_base,
6111 FILE_SHARE_READ
6112 | FILE_SHARE_WRITE
6113 | FILE_SHARE_DELETE,
6114 base_create_disposition,
6118 NULL,
6120 base_privflags,
6121 NULL,
6122 NULL,
6123 &base_fsp,
6124 NULL);
6125 TALLOC_FREE(smb_fname_base);
6127 if (!NT_STATUS_IS_OK(status)) {
6128 DEBUG(10, ("create_file_unixpath for base %s failed: "
6129 "%s\n", smb_fname->base_name,
6130 nt_errstr(status)));
6131 goto fail;
6135 if (smb_fname->fsp != NULL) {
6137 fsp = smb_fname->fsp;
6140 * We're about to use smb_fname->fsp for the fresh open.
6142 * Every fsp passed in via smb_fname->fsp already
6143 * holds a fsp->fsp_name. If it is already this
6144 * fsp->fsp_name that we got passed in as our input
6145 * argument smb_fname, these two are assumed to have
6146 * the same lifetime: Every fsp hangs of "conn", and
6147 * fsp->fsp_name is its talloc child.
6150 if (smb_fname != smb_fname->fsp->fsp_name) {
6152 * "smb_fname" is temporary in this case, but
6153 * the destructor of smb_fname would also tear
6154 * down the fsp we're about to use. Unlink
6155 * them from each other.
6157 smb_fname_fsp_unlink(smb_fname);
6160 * "fsp" is ours now
6162 free_fsp_on_error = true;
6165 status = fsp_bind_smb(fsp, req);
6166 if (!NT_STATUS_IS_OK(status)) {
6167 goto fail;
6170 if (fsp_is_alternate_stream(fsp)) {
6171 struct files_struct *tmp_base_fsp = fsp->base_fsp;
6173 fsp_set_base_fsp(fsp, NULL);
6175 fd_close(tmp_base_fsp);
6176 file_free(NULL, tmp_base_fsp);
6178 } else {
6180 * No fsp passed in that we can use, create one
6182 status = file_new(req, conn, &fsp);
6183 if(!NT_STATUS_IS_OK(status)) {
6184 goto fail;
6186 free_fsp_on_error = true;
6188 status = fsp_set_smb_fname(fsp, smb_fname);
6189 if (!NT_STATUS_IS_OK(status)) {
6190 goto fail;
6194 SMB_ASSERT(fsp->fsp_name->fsp != NULL);
6195 SMB_ASSERT(fsp->fsp_name->fsp == fsp);
6197 if (base_fsp) {
6199 * We're opening the stream element of a
6200 * base_fsp we already opened. Set up the
6201 * base_fsp pointer.
6203 fsp_set_base_fsp(fsp, base_fsp);
6206 if (dirfsp != NULL) {
6207 status = SMB_VFS_PARENT_PATHNAME(
6208 conn,
6209 talloc_tos(),
6210 smb_fname,
6211 &parent_dir_fname,
6212 &smb_fname_atname);
6213 if (!NT_STATUS_IS_OK(status)) {
6214 goto fail;
6216 } else {
6218 * Get a pathref on the parent. We can re-use this for
6219 * multiple calls to check parent ACLs etc. to avoid
6220 * pathname calls.
6222 status = parent_pathref(talloc_tos(),
6223 conn->cwd_fsp,
6224 smb_fname,
6225 &parent_dir_fname,
6226 &smb_fname_atname);
6227 if (!NT_STATUS_IS_OK(status)) {
6228 goto fail;
6231 dirfsp = parent_dir_fname->fsp;
6232 status = fsp_set_smb_fname(dirfsp, parent_dir_fname);
6233 if (!NT_STATUS_IS_OK(status)) {
6234 goto fail;
6239 * If it's a request for a directory open, deal with it separately.
6242 if (create_options & FILE_DIRECTORY_FILE) {
6244 if (create_options & FILE_NON_DIRECTORY_FILE) {
6245 status = NT_STATUS_INVALID_PARAMETER;
6246 goto fail;
6249 /* Can't open a temp directory. IFS kit test. */
6250 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
6251 (file_attributes & FILE_ATTRIBUTE_TEMPORARY)) {
6252 status = NT_STATUS_INVALID_PARAMETER;
6253 goto fail;
6257 * We will get a create directory here if the Win32
6258 * app specified a security descriptor in the
6259 * CreateDirectory() call.
6262 oplock_request = 0;
6263 status = open_directory(conn,
6264 req,
6265 access_mask,
6266 share_access,
6267 create_disposition,
6268 create_options,
6269 file_attributes,
6270 dirfsp->fsp_name,
6271 smb_fname_atname,
6272 &info,
6273 fsp);
6274 } else {
6277 * Ordinary file case.
6280 if (allocation_size) {
6281 fsp->initial_allocation_size = smb_roundup(fsp->conn,
6282 allocation_size);
6285 status = open_file_ntcreate(conn,
6286 req,
6287 access_mask,
6288 share_access,
6289 create_disposition,
6290 create_options,
6291 file_attributes,
6292 oplock_request,
6293 lease,
6294 private_flags,
6295 dirfsp->fsp_name,
6296 smb_fname_atname,
6297 &info,
6298 fsp);
6299 if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
6301 /* A stream open never opens a directory */
6303 if (base_fsp) {
6304 status = NT_STATUS_FILE_IS_A_DIRECTORY;
6305 goto fail;
6309 * Fail the open if it was explicitly a non-directory
6310 * file.
6313 if (create_options & FILE_NON_DIRECTORY_FILE) {
6314 status = NT_STATUS_FILE_IS_A_DIRECTORY;
6315 goto fail;
6318 oplock_request = 0;
6319 status = open_directory(conn,
6320 req,
6321 access_mask,
6322 share_access,
6323 create_disposition,
6324 create_options,
6325 file_attributes,
6326 dirfsp->fsp_name,
6327 smb_fname_atname,
6328 &info,
6329 fsp);
6333 if (!NT_STATUS_IS_OK(status)) {
6334 goto fail;
6337 fsp->fsp_flags.is_fsa = true;
6339 if ((ea_list != NULL) &&
6340 ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN))) {
6341 status = set_ea(conn, fsp, ea_list);
6342 if (!NT_STATUS_IS_OK(status)) {
6343 goto fail;
6347 if (!fsp->fsp_flags.is_directory &&
6348 S_ISDIR(fsp->fsp_name->st.st_ex_mode))
6350 status = NT_STATUS_ACCESS_DENIED;
6351 goto fail;
6354 /* Save the requested allocation size. */
6355 if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
6356 if ((allocation_size > (uint64_t)fsp->fsp_name->st.st_ex_size)
6357 && !(fsp->fsp_flags.is_directory))
6359 fsp->initial_allocation_size = smb_roundup(
6360 fsp->conn, allocation_size);
6361 if (vfs_allocate_file_space(
6362 fsp, fsp->initial_allocation_size) == -1) {
6363 status = NT_STATUS_DISK_FULL;
6364 goto fail;
6366 } else {
6367 fsp->initial_allocation_size = smb_roundup(
6368 fsp->conn, (uint64_t)fsp->fsp_name->st.st_ex_size);
6370 } else {
6371 fsp->initial_allocation_size = 0;
6374 if ((info == FILE_WAS_CREATED) &&
6375 lp_nt_acl_support(SNUM(conn)) &&
6376 !fsp_is_alternate_stream(fsp)) {
6377 if (sd != NULL) {
6379 * According to the MS documentation, the only time the security
6380 * descriptor is applied to the opened file is iff we *created* the
6381 * file; an existing file stays the same.
6383 * Also, it seems (from observation) that you can open the file with
6384 * any access mask but you can still write the sd. We need to override
6385 * the granted access before we call set_sd
6386 * Patch for bug #2242 from Tom Lackemann <cessnatomny@yahoo.com>.
6389 uint32_t sec_info_sent;
6390 uint32_t saved_access_mask = fsp->access_mask;
6392 sec_info_sent = get_sec_info(sd);
6394 fsp->access_mask = FILE_GENERIC_ALL;
6396 if (sec_info_sent & (SECINFO_OWNER|
6397 SECINFO_GROUP|
6398 SECINFO_DACL|
6399 SECINFO_SACL)) {
6400 status = set_sd(fsp, sd, sec_info_sent);
6403 fsp->access_mask = saved_access_mask;
6405 if (!NT_STATUS_IS_OK(status)) {
6406 goto fail;
6408 } else if (lp_inherit_acls(SNUM(conn))) {
6409 /* Inherit from parent. Errors here are not fatal. */
6410 status = inherit_new_acl(dirfsp, fsp);
6411 if (!NT_STATUS_IS_OK(status)) {
6412 DEBUG(10,("inherit_new_acl: failed for %s with %s\n",
6413 fsp_str_dbg(fsp),
6414 nt_errstr(status) ));
6419 if ((conn->fs_capabilities & FILE_FILE_COMPRESSION)
6420 && (create_options & FILE_NO_COMPRESSION)
6421 && (info == FILE_WAS_CREATED)) {
6422 status = SMB_VFS_SET_COMPRESSION(conn, fsp, fsp,
6423 COMPRESSION_FORMAT_NONE);
6424 if (!NT_STATUS_IS_OK(status)) {
6425 DEBUG(1, ("failed to disable compression: %s\n",
6426 nt_errstr(status)));
6430 DEBUG(10, ("create_file_unixpath: info=%d\n", info));
6432 *result = fsp;
6433 if (pinfo != NULL) {
6434 *pinfo = info;
6437 smb_fname->st = fsp->fsp_name->st;
6439 TALLOC_FREE(parent_dir_fname);
6441 return NT_STATUS_OK;
6443 fail:
6444 DEBUG(10, ("create_file_unixpath: %s\n", nt_errstr(status)));
6446 if (fsp != NULL) {
6448 * The close_file below will close
6449 * fsp->base_fsp.
6451 base_fsp = NULL;
6452 close_file_smb(req, fsp, ERROR_CLOSE);
6453 if (free_fsp_on_error) {
6454 file_free(req, fsp);
6455 fsp = NULL;
6458 if (base_fsp != NULL) {
6459 close_file_free(req, &base_fsp, ERROR_CLOSE);
6462 TALLOC_FREE(parent_dir_fname);
6464 return status;
6467 NTSTATUS create_file_default(connection_struct *conn,
6468 struct smb_request *req,
6469 struct files_struct *dirfsp,
6470 struct smb_filename *smb_fname,
6471 uint32_t access_mask,
6472 uint32_t share_access,
6473 uint32_t create_disposition,
6474 uint32_t create_options,
6475 uint32_t file_attributes,
6476 uint32_t oplock_request,
6477 const struct smb2_lease *lease,
6478 uint64_t allocation_size,
6479 uint32_t private_flags,
6480 struct security_descriptor *sd,
6481 struct ea_list *ea_list,
6482 files_struct **result,
6483 int *pinfo,
6484 const struct smb2_create_blobs *in_context_blobs,
6485 struct smb2_create_blobs *out_context_blobs)
6487 int info = FILE_WAS_OPENED;
6488 files_struct *fsp = NULL;
6489 NTSTATUS status;
6490 bool stream_name = false;
6491 struct smb2_create_blob *posx = NULL;
6493 DBG_DEBUG("create_file: access_mask = 0x%x "
6494 "file_attributes = 0x%x, share_access = 0x%x, "
6495 "create_disposition = 0x%x create_options = 0x%x "
6496 "oplock_request = 0x%x "
6497 "private_flags = 0x%x "
6498 "ea_list = %p, sd = %p, "
6499 "fname = %s\n",
6500 (unsigned int)access_mask,
6501 (unsigned int)file_attributes,
6502 (unsigned int)share_access,
6503 (unsigned int)create_disposition,
6504 (unsigned int)create_options,
6505 (unsigned int)oplock_request,
6506 (unsigned int)private_flags,
6507 ea_list,
6509 smb_fname_str_dbg(smb_fname));
6511 if (req != NULL) {
6513 * Remember the absolute time of the original request
6514 * with this mid. We'll use it later to see if this
6515 * has timed out.
6517 get_deferred_open_message_state(req, &req->request_time, NULL);
6521 * Check to see if this is a mac fork of some kind.
6524 stream_name = is_ntfs_stream_smb_fname(smb_fname);
6525 if (stream_name) {
6526 enum FAKE_FILE_TYPE fake_file_type;
6528 fake_file_type = is_fake_file(smb_fname);
6530 if (req != NULL && fake_file_type != FAKE_FILE_TYPE_NONE) {
6533 * Here we go! support for changing the disk quotas
6534 * --metze
6536 * We need to fake up to open this MAGIC QUOTA file
6537 * and return a valid FID.
6539 * w2k close this file directly after openening xp
6540 * also tries a QUERY_FILE_INFO on the file and then
6541 * close it
6543 status = open_fake_file(req, conn, req->vuid,
6544 fake_file_type, smb_fname,
6545 access_mask, &fsp);
6546 if (!NT_STATUS_IS_OK(status)) {
6547 goto fail;
6550 ZERO_STRUCT(smb_fname->st);
6551 goto done;
6554 if (!(conn->fs_capabilities & FILE_NAMED_STREAMS)) {
6555 status = NT_STATUS_OBJECT_NAME_INVALID;
6556 goto fail;
6560 if (is_ntfs_default_stream_smb_fname(smb_fname)) {
6561 int ret;
6562 /* We have to handle this error here. */
6563 if (create_options & FILE_DIRECTORY_FILE) {
6564 status = NT_STATUS_NOT_A_DIRECTORY;
6565 goto fail;
6567 ret = vfs_stat(conn, smb_fname);
6568 if (ret == 0 && VALID_STAT_OF_DIR(smb_fname->st)) {
6569 status = NT_STATUS_FILE_IS_A_DIRECTORY;
6570 goto fail;
6574 posx = smb2_create_blob_find(
6575 in_context_blobs, SMB2_CREATE_TAG_POSIX);
6576 if (posx != NULL) {
6577 uint32_t wire_mode_bits = 0;
6578 mode_t mode_bits = 0;
6579 SMB_STRUCT_STAT sbuf = { 0 };
6580 enum perm_type ptype =
6581 (create_options & FILE_DIRECTORY_FILE) ?
6582 PERM_NEW_DIR : PERM_NEW_FILE;
6584 if (posx->data.length != 4) {
6585 status = NT_STATUS_INVALID_PARAMETER;
6586 goto fail;
6589 wire_mode_bits = IVAL(posx->data.data, 0);
6590 status = unix_perms_from_wire(
6591 conn, &sbuf, wire_mode_bits, ptype, &mode_bits);
6592 if (!NT_STATUS_IS_OK(status)) {
6593 goto fail;
6596 * Remove type info from mode, leaving only the
6597 * permissions and setuid/gid bits.
6599 mode_bits &= ~S_IFMT;
6601 file_attributes = (FILE_FLAG_POSIX_SEMANTICS | mode_bits);
6604 status = create_file_unixpath(conn,
6605 req,
6606 dirfsp,
6607 smb_fname,
6608 access_mask,
6609 share_access,
6610 create_disposition,
6611 create_options,
6612 file_attributes,
6613 oplock_request,
6614 lease,
6615 allocation_size,
6616 private_flags,
6618 ea_list,
6619 &fsp,
6620 &info);
6621 if (!NT_STATUS_IS_OK(status)) {
6622 goto fail;
6625 done:
6626 DEBUG(10, ("create_file: info=%d\n", info));
6628 *result = fsp;
6629 if (pinfo != NULL) {
6630 *pinfo = info;
6632 return NT_STATUS_OK;
6634 fail:
6635 DEBUG(10, ("create_file: %s\n", nt_errstr(status)));
6637 if (fsp != NULL) {
6638 close_file_free(req, &fsp, ERROR_CLOSE);
6640 return status;