s3:smbd: let mkdir_internal() try VFS_RENAME_HOW_NO_REPLACE first
[samba4-gss.git] / source3 / smbd / open.c
bloba1c1c259e5c0f14d17b010d37d493cb9eb238958
1 /*
2 Unix SMB/CIFS implementation.
3 file opening and share modes
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Jeremy Allison 2001-2004
6 Copyright (C) Volker Lendecke 2005
7 Copyright (C) Ralph Boehme 2017
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "includes.h"
24 #include "system/filesys.h"
25 #include "lib/util/server_id.h"
26 #include "printing.h"
27 #include "locking/share_mode_lock.h"
28 #include "smbd/smbd.h"
29 #include "smbd/globals.h"
30 #include "fake_file.h"
31 #include "../libcli/security/security.h"
32 #include "../librpc/gen_ndr/ndr_security.h"
33 #include "../librpc/gen_ndr/ndr_open_files.h"
34 #include "../librpc/gen_ndr/idmap.h"
35 #include "../librpc/gen_ndr/ioctl.h"
36 #include "passdb/lookup_sid.h"
37 #include "auth.h"
38 #include "serverid.h"
39 #include "messages.h"
40 #include "source3/lib/dbwrap/dbwrap_watch.h"
41 #include "locking/leases_db.h"
42 #include "librpc/gen_ndr/ndr_leases_db.h"
43 #include "lib/util/time_basic.h"
44 #include "source3/smbd/dir.h"
46 #if defined(HAVE_LINUX_MAGIC_H)
47 #include <linux/magic.h>
48 #endif
50 static NTSTATUS inherit_new_acl(files_struct *dirfsp, files_struct *fsp);
52 extern const struct generic_mapping file_generic_mapping;
54 struct deferred_open_record {
55 struct smbXsrv_connection *xconn;
56 uint64_t mid;
58 bool async_open;
61 * Timer for async opens, needed because they don't use a watch on
62 * a locking.tdb record. This is currently only used for real async
63 * opens and just terminates smbd if the async open times out.
65 struct tevent_timer *te;
68 * For the samba kernel oplock case we use both a timeout and
69 * a watch on locking.tdb. This way in case it's smbd holding
70 * the kernel oplock we get directly notified for the retry
71 * once the kernel oplock is properly broken. Store the req
72 * here so that it can be timely discarded once the timer
73 * above fires.
75 struct tevent_req *watch_req;
78 /****************************************************************************
79 If the requester wanted DELETE_ACCESS and was rejected because
80 the file ACL didn't include DELETE_ACCESS, see if the parent ACL
81 overrides this.
82 ****************************************************************************/
84 static bool parent_override_delete(connection_struct *conn,
85 struct files_struct *dirfsp,
86 const struct smb_filename *smb_fname,
87 uint32_t access_mask,
88 uint32_t rejected_mask)
90 if ((access_mask & DELETE_ACCESS) && (rejected_mask & DELETE_ACCESS)) {
91 bool ok;
92 ok = can_delete_file_in_directory(conn, dirfsp, smb_fname);
93 return ok;
96 return false;
99 /****************************************************************************
100 Check if we have open rights.
101 ****************************************************************************/
103 static NTSTATUS smbd_check_access_rights_fname(
104 struct connection_struct *conn,
105 const struct smb_filename *smb_fname,
106 bool use_privs,
107 uint32_t access_mask,
108 uint32_t do_not_check_mask)
110 uint32_t rejected_share_access;
111 uint32_t effective_access;
113 rejected_share_access = access_mask & ~(conn->share_access);
115 if (rejected_share_access) {
116 DBG_DEBUG("rejected share access 0x%"PRIx32" on "
117 "%s (0x%"PRIx32")\n",
118 access_mask,
119 smb_fname_str_dbg(smb_fname),
120 rejected_share_access);
121 return NT_STATUS_ACCESS_DENIED;
124 effective_access = access_mask & ~do_not_check_mask;
125 if (effective_access == 0) {
126 DBG_DEBUG("do_not_check_mask override on %s. Granting 0x%x for free.\n",
127 smb_fname_str_dbg(smb_fname),
128 (unsigned int)access_mask);
129 return NT_STATUS_OK;
132 if (!use_privs && get_current_uid(conn) == (uid_t)0) {
133 /* I'm sorry sir, I didn't know you were root... */
134 DBG_DEBUG("root override on %s. Granting 0x%x\n",
135 smb_fname_str_dbg(smb_fname),
136 (unsigned int)access_mask);
137 return NT_STATUS_OK;
140 if ((access_mask & DELETE_ACCESS) &&
141 !lp_acl_check_permissions(SNUM(conn)))
143 DBG_DEBUG("Not checking ACL on DELETE_ACCESS on file %s. "
144 "Granting 0x%"PRIx32"\n",
145 smb_fname_str_dbg(smb_fname),
146 access_mask);
147 return NT_STATUS_OK;
150 if (access_mask == DELETE_ACCESS &&
151 VALID_STAT(smb_fname->st) &&
152 S_ISLNK(smb_fname->st.st_ex_mode))
154 /* We can always delete a symlink. */
155 DBG_DEBUG("Not checking ACL on DELETE_ACCESS on symlink %s.\n",
156 smb_fname_str_dbg(smb_fname));
157 return NT_STATUS_OK;
160 return NT_STATUS_MORE_PROCESSING_REQUIRED;
163 static NTSTATUS smbd_check_access_rights_sd(
164 struct connection_struct *conn,
165 struct files_struct *dirfsp,
166 const struct smb_filename *smb_fname,
167 struct security_descriptor *sd,
168 bool use_privs,
169 uint32_t access_mask,
170 uint32_t do_not_check_mask)
172 uint32_t rejected_mask = access_mask;
173 NTSTATUS status;
175 if (sd == NULL) {
176 goto access_denied;
179 status = se_file_access_check(sd,
180 get_current_nttok(conn),
181 use_privs,
182 (access_mask & ~do_not_check_mask),
183 &rejected_mask);
185 DBG_DEBUG("File [%s] requesting [0x%"PRIx32"] "
186 "returning [0x%"PRIx32"] (%s)\n",
187 smb_fname_str_dbg(smb_fname),
188 access_mask,
189 rejected_mask,
190 nt_errstr(status));
192 if (!NT_STATUS_IS_OK(status)) {
193 if (DEBUGLEVEL >= 10) {
194 DBG_DEBUG("acl for %s is:\n",
195 smb_fname_str_dbg(smb_fname));
196 NDR_PRINT_DEBUG(security_descriptor, sd);
200 TALLOC_FREE(sd);
202 if (NT_STATUS_IS_OK(status) ||
203 !NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED))
205 return status;
208 /* Here we know status == NT_STATUS_ACCESS_DENIED. */
210 access_denied:
212 if ((access_mask & FILE_WRITE_ATTRIBUTES) &&
213 (rejected_mask & FILE_WRITE_ATTRIBUTES) &&
214 !lp_store_dos_attributes(SNUM(conn)) &&
215 (lp_map_readonly(SNUM(conn)) ||
216 lp_map_archive(SNUM(conn)) ||
217 lp_map_hidden(SNUM(conn)) ||
218 lp_map_system(SNUM(conn))))
220 rejected_mask &= ~FILE_WRITE_ATTRIBUTES;
222 DBG_DEBUG("overrode FILE_WRITE_ATTRIBUTES on file %s\n",
223 smb_fname_str_dbg(smb_fname));
226 if (parent_override_delete(conn,
227 dirfsp,
228 smb_fname,
229 access_mask,
230 rejected_mask))
233 * Were we trying to do an open for delete and didn't get DELETE
234 * access. Check if the directory allows DELETE_CHILD.
235 * See here:
236 * http://blogs.msdn.com/oldnewthing/archive/2004/06/04/148426.aspx
237 * for details.
240 rejected_mask &= ~DELETE_ACCESS;
242 DBG_DEBUG("Overrode DELETE_ACCESS on file %s\n",
243 smb_fname_str_dbg(smb_fname));
246 if (rejected_mask != 0) {
247 return NT_STATUS_ACCESS_DENIED;
249 return NT_STATUS_OK;
252 NTSTATUS smbd_check_access_rights_fsp(struct files_struct *dirfsp,
253 struct files_struct *fsp,
254 bool use_privs,
255 uint32_t access_mask)
257 struct security_descriptor *sd = NULL;
258 uint32_t do_not_check_mask = 0;
259 NTSTATUS status;
261 /* Cope with fake/printer fsp's. */
262 if (fsp->fake_file_handle != NULL || fsp->print_file != NULL) {
263 if ((fsp->access_mask & access_mask) != access_mask) {
264 return NT_STATUS_ACCESS_DENIED;
266 return NT_STATUS_OK;
269 if (fsp_get_pathref_fd(fsp) == -1) {
271 * This is a POSIX open on a symlink. For the pathname
272 * version of this function we used to return the st_mode
273 * bits turned into an NT ACL. For a symlink the mode bits
274 * are always rwxrwxrwx which means the pathname version always
275 * returned NT_STATUS_OK for a symlink. For the handle reference
276 * to a symlink use the handle access bits.
278 if ((fsp->access_mask & access_mask) != access_mask) {
279 return NT_STATUS_ACCESS_DENIED;
281 return NT_STATUS_OK;
285 * If we can access the path to this file, by
286 * default we have FILE_READ_ATTRIBUTES from the
287 * containing directory. See the section:
288 * "Algorithm to Check Access to an Existing File"
289 * in MS-FSA.pdf.
291 * se_file_access_check() also takes care of
292 * owner WRITE_DAC and READ_CONTROL.
294 do_not_check_mask = FILE_READ_ATTRIBUTES;
297 * Samba 3.6 and earlier granted execute access even
298 * if the ACL did not contain execute rights.
299 * Samba 4.0 is more correct and checks it.
300 * The compatibility mode allows one to skip this check
301 * to smoothen upgrades.
303 if (lp_acl_allow_execute_always(SNUM(fsp->conn))) {
304 do_not_check_mask |= FILE_EXECUTE;
307 status = smbd_check_access_rights_fname(fsp->conn,
308 fsp->fsp_name,
309 use_privs,
310 access_mask,
311 do_not_check_mask);
312 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
313 return status;
316 status = SMB_VFS_FGET_NT_ACL(metadata_fsp(fsp),
317 (SECINFO_OWNER |
318 SECINFO_GROUP |
319 SECINFO_DACL),
320 talloc_tos(),
321 &sd);
322 if (!NT_STATUS_IS_OK(status)) {
323 DBG_DEBUG("Could not get acl on %s: %s\n",
324 fsp_str_dbg(fsp),
325 nt_errstr(status));
326 return status;
329 return smbd_check_access_rights_sd(fsp->conn,
330 dirfsp,
331 fsp->fsp_name,
333 use_privs,
334 access_mask,
335 do_not_check_mask);
339 * Given an fsp that represents a parent directory,
340 * check if the requested access can be granted.
342 NTSTATUS check_parent_access_fsp(struct files_struct *fsp,
343 uint32_t access_mask)
345 NTSTATUS status;
346 struct security_descriptor *parent_sd = NULL;
347 uint32_t access_granted = 0;
348 uint32_t name_hash;
349 bool delete_on_close_set;
350 TALLOC_CTX *frame = talloc_stackframe();
352 if (get_current_uid(fsp->conn) == (uid_t)0) {
353 /* I'm sorry sir, I didn't know you were root... */
354 DBG_DEBUG("root override on %s. Granting 0x%x\n",
355 fsp_str_dbg(fsp),
356 (unsigned int)access_mask);
357 status = NT_STATUS_OK;
358 goto out;
361 status = SMB_VFS_FGET_NT_ACL(fsp,
362 (SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL),
363 frame,
364 &parent_sd);
366 if (!NT_STATUS_IS_OK(status)) {
367 DBG_INFO("SMB_VFS_FGET_NT_ACL failed for "
368 "%s with error %s\n",
369 fsp_str_dbg(fsp),
370 nt_errstr(status));
371 goto out;
375 * If we can access the path to this file, by
376 * default we have FILE_READ_ATTRIBUTES from the
377 * containing directory. See the section:
378 * "Algorithm to Check Access to an Existing File"
379 * in MS-FSA.pdf.
381 * se_file_access_check() also takes care of
382 * owner WRITE_DAC and READ_CONTROL.
384 status = se_file_access_check(parent_sd,
385 get_current_nttok(fsp->conn),
386 false,
387 (access_mask & ~FILE_READ_ATTRIBUTES),
388 &access_granted);
389 if(!NT_STATUS_IS_OK(status)) {
390 DBG_INFO("access check "
391 "on directory %s for mask 0x%x returned (0x%x) %s\n",
392 fsp_str_dbg(fsp),
393 access_mask,
394 access_granted,
395 nt_errstr(status));
396 goto out;
399 if (!(access_mask & (SEC_DIR_ADD_FILE | SEC_DIR_ADD_SUBDIR))) {
400 status = NT_STATUS_OK;
401 goto out;
403 if (!lp_check_parent_directory_delete_on_close(SNUM(fsp->conn))) {
404 status = NT_STATUS_OK;
405 goto out;
408 /* Check if the directory has delete-on-close set */
409 status = file_name_hash(fsp->conn,
410 fsp->fsp_name->base_name,
411 &name_hash);
412 if (!NT_STATUS_IS_OK(status)) {
413 goto out;
416 get_file_infos(fsp->file_id, name_hash, &delete_on_close_set, NULL);
417 if (delete_on_close_set) {
418 status = NT_STATUS_DELETE_PENDING;
419 goto out;
422 status = NT_STATUS_OK;
424 out:
425 TALLOC_FREE(frame);
426 return status;
429 /****************************************************************************
430 Ensure when opening a base file for a stream open that we have permissions
431 to do so given the access mask on the base file.
432 ****************************************************************************/
434 static NTSTATUS check_base_file_access(struct files_struct *fsp,
435 uint32_t access_mask)
437 NTSTATUS status;
439 status = smbd_calculate_access_mask_fsp(fsp->conn->cwd_fsp,
440 fsp,
441 false,
442 access_mask,
443 &access_mask);
444 if (!NT_STATUS_IS_OK(status)) {
445 DEBUG(10, ("smbd_calculate_access_mask "
446 "on file %s returned %s\n",
447 fsp_str_dbg(fsp),
448 nt_errstr(status)));
449 return status;
452 if (access_mask & (FILE_WRITE_DATA|FILE_APPEND_DATA)) {
453 uint32_t dosattrs;
454 if (!CAN_WRITE(fsp->conn)) {
455 return NT_STATUS_ACCESS_DENIED;
457 dosattrs = fdos_mode(fsp);
458 if (dosattrs & FILE_ATTRIBUTE_READONLY) {
459 return NT_STATUS_ACCESS_DENIED;
463 return smbd_check_access_rights_fsp(fsp->conn->cwd_fsp,
464 fsp,
465 false,
466 access_mask);
469 static NTSTATUS chdir_below_conn(
470 TALLOC_CTX *mem_ctx,
471 connection_struct *conn,
472 const char *connectpath,
473 size_t connectpath_len,
474 struct smb_filename *dir_fname,
475 struct smb_filename **_oldwd_fname)
477 struct smb_filename *oldwd_fname = NULL;
478 struct smb_filename *smb_fname_dot = NULL;
479 struct smb_filename *real_fname = NULL;
480 const char *relative = NULL;
481 NTSTATUS status;
482 int ret;
483 bool ok;
485 if (!ISDOT(dir_fname->base_name)) {
487 oldwd_fname = vfs_GetWd(talloc_tos(), conn);
488 if (oldwd_fname == NULL) {
489 status = map_nt_error_from_unix(errno);
490 goto out;
493 /* Pin parent directory in place. */
494 ret = vfs_ChDir(conn, dir_fname);
495 if (ret == -1) {
496 status = map_nt_error_from_unix(errno);
497 DBG_DEBUG("chdir to %s failed: %s\n",
498 dir_fname->base_name,
499 strerror(errno));
500 goto out;
504 smb_fname_dot = synthetic_smb_fname(
505 talloc_tos(),
506 ".",
507 NULL,
508 NULL,
509 dir_fname->twrp,
510 dir_fname->flags);
511 if (smb_fname_dot == NULL) {
512 status = NT_STATUS_NO_MEMORY;
513 goto out;
516 real_fname = SMB_VFS_REALPATH(conn, talloc_tos(), smb_fname_dot);
517 if (real_fname == NULL) {
518 status = map_nt_error_from_unix(errno);
519 DBG_DEBUG("realpath in %s failed: %s\n",
520 dir_fname->base_name,
521 strerror(errno));
522 goto out;
524 TALLOC_FREE(smb_fname_dot);
526 ok = subdir_of(connectpath,
527 connectpath_len,
528 real_fname->base_name,
529 &relative);
530 if (ok) {
531 TALLOC_FREE(real_fname);
532 *_oldwd_fname = oldwd_fname;
533 return NT_STATUS_OK;
536 DBG_NOTICE("Bad access attempt: %s is a symlink "
537 "outside the share path\n"
538 "conn_rootdir =%s\n"
539 "resolved_name=%s\n",
540 dir_fname->base_name,
541 connectpath,
542 real_fname->base_name);
543 TALLOC_FREE(real_fname);
545 status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
547 out:
548 if (oldwd_fname != NULL) {
549 ret = vfs_ChDir(conn, oldwd_fname);
550 SMB_ASSERT(ret == 0);
551 TALLOC_FREE(oldwd_fname);
554 return status;
558 * Get the symlink target of dirfsp/symlink_name, making sure the
559 * target is below connection_path.
562 static NTSTATUS symlink_target_below_conn(
563 TALLOC_CTX *mem_ctx,
564 const char *connection_path,
565 struct files_struct *fsp,
566 struct files_struct *dirfsp,
567 struct smb_filename *symlink_name,
568 char **_target)
570 char *target = NULL;
571 char *absolute = NULL;
572 NTSTATUS status;
574 if (fsp_get_pathref_fd(fsp) != -1) {
576 * fsp is an O_PATH open, Linux does a "freadlink"
577 * with an empty name argument to readlinkat
579 status = readlink_talloc(talloc_tos(), fsp, NULL, &target);
580 } else {
581 status = readlink_talloc(
582 talloc_tos(), dirfsp, symlink_name, &target);
585 status = safe_symlink_target_path(talloc_tos(),
586 connection_path,
587 dirfsp->fsp_name->base_name,
588 target,
590 &absolute);
591 if (!NT_STATUS_IS_OK(status)) {
592 DBG_DEBUG("safe_symlink_target_path() failed: %s\n",
593 nt_errstr(status));
594 return status;
597 if (absolute[0] == '\0') {
599 * special case symlink to share root: "." is our
600 * share root filename
602 TALLOC_FREE(absolute);
603 absolute = talloc_strdup(talloc_tos(), ".");
604 if (absolute == NULL) {
605 return NT_STATUS_NO_MEMORY;
609 *_target = absolute;
610 return NT_STATUS_OK;
613 /****************************************************************************
614 Non-widelink open.
615 ****************************************************************************/
617 static NTSTATUS non_widelink_open(const struct files_struct *dirfsp,
618 files_struct *fsp,
619 struct smb_filename *smb_fname,
620 const struct vfs_open_how *_how)
622 struct connection_struct *conn = fsp->conn;
623 const char *connpath = SMB_VFS_CONNECTPATH(conn, dirfsp, smb_fname);
624 size_t connpath_len;
625 NTSTATUS status = NT_STATUS_OK;
626 int fd = -1;
627 char *orig_smb_fname_base = smb_fname->base_name;
628 struct smb_filename *orig_fsp_name = fsp->fsp_name;
629 struct smb_filename *smb_fname_rel = NULL;
630 struct smb_filename *oldwd_fname = NULL;
631 struct smb_filename *parent_dir_fname = NULL;
632 struct vfs_open_how how = *_how;
633 char *target = NULL;
634 size_t link_depth = 0;
635 int ret;
637 SMB_ASSERT(!fsp_is_alternate_stream(fsp));
639 if (connpath == NULL) {
641 * This can happen with shadow_copy2 if the snapshot
642 * path is not found
644 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
646 connpath_len = strlen(connpath);
648 again:
649 if (smb_fname->base_name[0] == '/') {
650 int cmp = strcmp(connpath, smb_fname->base_name);
651 if (cmp == 0) {
652 smb_fname->base_name = talloc_strdup(smb_fname, "");
653 if (smb_fname->base_name == NULL) {
654 status = NT_STATUS_NO_MEMORY;
655 goto out;
660 if (dirfsp == conn->cwd_fsp) {
662 status = SMB_VFS_PARENT_PATHNAME(fsp->conn,
663 talloc_tos(),
664 smb_fname,
665 &parent_dir_fname,
666 &smb_fname_rel);
667 if (!NT_STATUS_IS_OK(status)) {
668 goto out;
671 status = chdir_below_conn(
672 talloc_tos(),
673 conn,
674 connpath,
675 connpath_len,
676 parent_dir_fname,
677 &oldwd_fname);
678 if (!NT_STATUS_IS_OK(status)) {
679 goto out;
682 /* Setup fsp->fsp_name to be relative to cwd */
683 fsp->fsp_name = smb_fname_rel;
684 } else {
686 * fsp->fsp_name is unchanged as it is already correctly
687 * relative to dirfsp.
689 smb_fname_rel = smb_fname;
694 * Assert nobody can step in with a symlink on the
695 * path, there is no path anymore and we'll use
696 * O_NOFOLLOW to open.
698 char *slash = strchr_m(smb_fname_rel->base_name, '/');
699 SMB_ASSERT(slash == NULL);
702 how.flags |= O_NOFOLLOW;
704 fd = SMB_VFS_OPENAT(conn,
705 dirfsp,
706 smb_fname_rel,
707 fsp,
708 &how);
709 fsp_set_fd(fsp, fd); /* This preserves errno */
711 if (fd == -1) {
712 status = map_nt_error_from_unix(errno);
714 if (errno == ENOENT) {
715 goto out;
719 * ENOENT makes it worthless retrying with a
720 * stat, we know for sure the file does not
721 * exist. For everything else we want to know
722 * what's there.
724 ret = SMB_VFS_FSTATAT(
725 fsp->conn,
726 dirfsp,
727 smb_fname_rel,
728 &fsp->fsp_name->st,
729 AT_SYMLINK_NOFOLLOW);
731 if (ret == -1) {
733 * Keep the original error. Otherwise we would
734 * mask for example EROFS for open(O_CREAT),
735 * turning it into ENOENT.
737 goto out;
739 } else {
740 ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st);
743 if (ret == -1) {
744 status = map_nt_error_from_unix(errno);
745 DBG_DEBUG("fstat[at](%s) failed: %s\n",
746 smb_fname_str_dbg(smb_fname),
747 strerror(errno));
748 goto out;
751 fsp->fsp_flags.is_directory = S_ISDIR(fsp->fsp_name->st.st_ex_mode);
752 orig_fsp_name->st = fsp->fsp_name->st;
754 if (!S_ISLNK(fsp->fsp_name->st.st_ex_mode)) {
755 goto out;
759 * Found a symlink to follow in user space
762 if (fsp->fsp_name->flags & SMB_FILENAME_POSIX_PATH) {
763 /* Never follow symlinks on posix open. */
764 status = NT_STATUS_STOPPED_ON_SYMLINK;
765 goto out;
767 if (!lp_follow_symlinks(SNUM(conn))) {
768 /* Explicitly no symlinks. */
769 status = NT_STATUS_STOPPED_ON_SYMLINK;
770 goto out;
773 link_depth += 1;
774 if (link_depth >= 40) {
775 status = NT_STATUS_STOPPED_ON_SYMLINK;
776 goto out;
779 fsp->fsp_name = orig_fsp_name;
781 status = symlink_target_below_conn(
782 talloc_tos(),
783 connpath,
784 fsp,
785 discard_const_p(files_struct, dirfsp),
786 smb_fname_rel,
787 &target);
789 if (!NT_STATUS_IS_OK(status)) {
790 DBG_DEBUG("symlink_target_below_conn() failed: %s\n",
791 nt_errstr(status));
792 goto out;
796 * Close what openat(O_PATH) potentially left behind
798 fd_close(fsp);
800 if (smb_fname->base_name != orig_smb_fname_base) {
801 TALLOC_FREE(smb_fname->base_name);
803 smb_fname->base_name = target;
805 if (oldwd_fname != NULL) {
806 ret = vfs_ChDir(conn, oldwd_fname);
807 if (ret == -1) {
808 smb_panic("unable to get back to old directory\n");
810 TALLOC_FREE(oldwd_fname);
814 * And do it all again... As smb_fname is not relative to the passed in
815 * dirfsp anymore, we pass conn->cwd_fsp as dirfsp to
816 * non_widelink_open() to trigger the chdir(parentdir) logic.
818 dirfsp = conn->cwd_fsp;
820 goto again;
822 out:
823 fsp->fsp_name = orig_fsp_name;
824 smb_fname->base_name = orig_smb_fname_base;
826 TALLOC_FREE(parent_dir_fname);
828 if (!NT_STATUS_IS_OK(status)) {
829 fd_close(fsp);
832 if (oldwd_fname != NULL) {
833 ret = vfs_ChDir(conn, oldwd_fname);
834 if (ret == -1) {
835 smb_panic("unable to get back to old directory\n");
837 TALLOC_FREE(oldwd_fname);
839 return status;
842 /****************************************************************************
843 fd support routines - attempt to do a dos_open.
844 ****************************************************************************/
846 NTSTATUS fd_openat(const struct files_struct *dirfsp,
847 struct smb_filename *smb_fname,
848 files_struct *fsp,
849 const struct vfs_open_how *_how)
851 struct vfs_open_how how = *_how;
852 struct connection_struct *conn = fsp->conn;
853 NTSTATUS status = NT_STATUS_OK;
854 bool fsp_is_stream = fsp_is_alternate_stream(fsp);
855 bool smb_fname_is_stream = is_named_stream(smb_fname);
857 SMB_ASSERT(fsp_is_stream == smb_fname_is_stream);
860 * Never follow symlinks on a POSIX client. The
861 * client should be doing this.
864 if ((fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) || !lp_follow_symlinks(SNUM(conn))) {
865 how.flags |= O_NOFOLLOW;
868 if (fsp_is_stream) {
869 int fd;
871 fd = SMB_VFS_OPENAT(
872 conn,
873 NULL, /* stream open is relative to fsp->base_fsp */
874 smb_fname,
875 fsp,
876 &how);
877 if (fd == -1) {
878 status = map_nt_error_from_unix(errno);
880 fsp_set_fd(fsp, fd);
882 if (fd != -1) {
883 status = vfs_stat_fsp(fsp);
884 if (!NT_STATUS_IS_OK(status)) {
885 DBG_DEBUG("vfs_stat_fsp failed: %s\n",
886 nt_errstr(status));
887 fd_close(fsp);
891 return status;
895 * Only follow symlinks within a share
896 * definition.
898 status = non_widelink_open(dirfsp, fsp, smb_fname, &how);
899 if (!NT_STATUS_IS_OK(status)) {
900 if (NT_STATUS_EQUAL(status, NT_STATUS_TOO_MANY_OPENED_FILES)) {
901 static time_t last_warned = 0L;
903 if (time((time_t *) NULL) > last_warned) {
904 DEBUG(0,("Too many open files, unable "
905 "to open more! smbd's max "
906 "open files = %d\n",
907 lp_max_open_files()));
908 last_warned = time((time_t *) NULL);
912 DBG_DEBUG("name %s, flags = 0%o mode = 0%o, fd = %d. %s\n",
913 smb_fname_str_dbg(smb_fname),
914 how.flags,
915 (int)how.mode,
916 fsp_get_pathref_fd(fsp),
917 nt_errstr(status));
918 return status;
921 DBG_DEBUG("name %s, flags = 0%o mode = 0%o, fd = %d\n",
922 smb_fname_str_dbg(smb_fname),
923 how.flags,
924 (int)how.mode,
925 fsp_get_pathref_fd(fsp));
927 return status;
930 /****************************************************************************
931 Close the file associated with a fsp.
932 ****************************************************************************/
934 NTSTATUS fd_close(files_struct *fsp)
936 NTSTATUS stat_status = NT_STATUS_OK;
937 int ret;
939 if (fsp == fsp->conn->cwd_fsp) {
940 return NT_STATUS_OK;
943 if (fsp->fsp_flags.fstat_before_close) {
945 * capture status, if failure
946 * continue close processing
947 * and return status
949 stat_status = vfs_stat_fsp(fsp);
952 if (fsp->dptr) {
953 dptr_CloseDir(fsp);
955 if (fsp_get_pathref_fd(fsp) == -1) {
957 * Either a directory where the dptr_CloseDir() already closed
958 * the fd or a stat open.
960 return NT_STATUS_OK;
962 if (fh_get_refcount(fsp->fh) > 1) {
963 return NT_STATUS_OK; /* Shared handle. Only close last reference. */
966 ret = SMB_VFS_CLOSE(fsp);
967 fsp_set_fd(fsp, -1);
968 if (ret == -1) {
969 return map_nt_error_from_unix(errno);
971 return stat_status;
974 /****************************************************************************
975 Change the ownership of a file to that of the parent directory.
976 Do this by fd if possible.
977 ****************************************************************************/
979 static void change_file_owner_to_parent_fsp(struct files_struct *parent_fsp,
980 struct files_struct *fsp)
982 int ret;
984 if (parent_fsp->fsp_name->st.st_ex_uid == fsp->fsp_name->st.st_ex_uid) {
985 /* Already this uid - no need to change. */
986 DBG_DEBUG("file %s is already owned by uid %u\n",
987 fsp_str_dbg(fsp),
988 (unsigned int)fsp->fsp_name->st.st_ex_uid);
989 return;
992 become_root();
993 ret = SMB_VFS_FCHOWN(fsp,
994 parent_fsp->fsp_name->st.st_ex_uid,
995 (gid_t)-1);
996 unbecome_root();
997 if (ret == -1) {
998 DBG_ERR("failed to fchown "
999 "file %s to parent directory uid %u. Error "
1000 "was %s\n",
1001 fsp_str_dbg(fsp),
1002 (unsigned int)parent_fsp->fsp_name->st.st_ex_uid,
1003 strerror(errno));
1004 } else {
1005 DBG_DEBUG("changed new file %s to "
1006 "parent directory uid %u.\n",
1007 fsp_str_dbg(fsp),
1008 (unsigned int)parent_fsp->fsp_name->st.st_ex_uid);
1009 /* Ensure the uid entry is updated. */
1010 fsp->fsp_name->st.st_ex_uid =
1011 parent_fsp->fsp_name->st.st_ex_uid;
1015 static NTSTATUS change_dir_owner_to_parent_fsp(struct files_struct *parent_fsp,
1016 struct files_struct *fsp)
1018 NTSTATUS status;
1019 int ret;
1021 if (parent_fsp->fsp_name->st.st_ex_uid == fsp->fsp_name->st.st_ex_uid) {
1022 /* Already this uid - no need to change. */
1023 DBG_DEBUG("directory %s is already owned by uid %u\n",
1024 fsp_str_dbg(fsp),
1025 (unsigned int)fsp->fsp_name->st.st_ex_uid);
1026 return NT_STATUS_OK;
1029 become_root();
1030 ret = SMB_VFS_FCHOWN(fsp,
1031 parent_fsp->fsp_name->st.st_ex_uid,
1032 (gid_t)-1);
1033 unbecome_root();
1034 if (ret == -1) {
1035 status = map_nt_error_from_unix(errno);
1036 DBG_ERR("failed to chown "
1037 "directory %s to parent directory uid %u. "
1038 "Error was %s\n",
1039 fsp_str_dbg(fsp),
1040 (unsigned int)parent_fsp->fsp_name->st.st_ex_uid,
1041 nt_errstr(status));
1042 return status;
1045 DBG_DEBUG("changed ownership of new "
1046 "directory %s to parent directory uid %u.\n",
1047 fsp_str_dbg(fsp),
1048 (unsigned int)parent_fsp->fsp_name->st.st_ex_uid);
1050 /* Ensure the uid entry is updated. */
1051 fsp->fsp_name->st.st_ex_uid = parent_fsp->fsp_name->st.st_ex_uid;
1053 return NT_STATUS_OK;
1056 /****************************************************************************
1057 Open a file - returning a guaranteed ATOMIC indication of if the
1058 file was created or not.
1059 ****************************************************************************/
1061 static NTSTATUS fd_open_atomic(struct files_struct *dirfsp,
1062 struct smb_filename *smb_fname,
1063 files_struct *fsp,
1064 const struct vfs_open_how *_how,
1065 bool *file_created)
1067 struct vfs_open_how how = *_how;
1068 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
1069 NTSTATUS retry_status;
1070 bool file_existed = VALID_STAT(smb_fname->st);
1072 if (!(how.flags & O_CREAT)) {
1074 * We're not creating the file, just pass through.
1076 status = fd_openat(dirfsp, smb_fname, fsp, &how);
1077 *file_created = false;
1078 return status;
1081 if (how.flags & O_EXCL) {
1083 * Fail if already exists, just pass through.
1085 status = fd_openat(dirfsp, smb_fname, fsp, &how);
1088 * Here we've opened with O_CREAT|O_EXCL. If that went
1089 * NT_STATUS_OK, we *know* we created this file.
1091 *file_created = NT_STATUS_IS_OK(status);
1093 return status;
1097 * Now it gets tricky. We have O_CREAT, but not O_EXCL.
1098 * To know absolutely if we created the file or not,
1099 * we can never call O_CREAT without O_EXCL. So if
1100 * we think the file existed, try without O_CREAT|O_EXCL.
1101 * If we think the file didn't exist, try with
1102 * O_CREAT|O_EXCL.
1104 * The big problem here is dangling symlinks. Opening
1105 * without O_NOFOLLOW means both bad symlink
1106 * and missing path return -1, ENOENT from open(). As POSIX
1107 * is pathname based it's not possible to tell
1108 * the difference between these two cases in a
1109 * non-racy way, so change to try only two attempts before
1110 * giving up.
1112 * We don't have this problem for the O_NOFOLLOW
1113 * case as it just returns NT_STATUS_OBJECT_PATH_NOT_FOUND
1114 * mapped from the ELOOP POSIX error.
1117 if (file_existed) {
1118 how.flags = _how->flags & ~(O_CREAT);
1119 retry_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
1120 } else {
1121 how.flags = _how->flags | O_EXCL;
1122 retry_status = NT_STATUS_OBJECT_NAME_COLLISION;
1125 status = fd_openat(dirfsp, smb_fname, fsp, &how);
1126 if (NT_STATUS_IS_OK(status)) {
1127 *file_created = !file_existed;
1128 return NT_STATUS_OK;
1130 if (NT_STATUS_EQUAL(status, retry_status)) {
1132 file_existed = !file_existed;
1134 DBG_DEBUG("File %s %s. Retry.\n",
1135 fsp_str_dbg(fsp),
1136 file_existed ? "existed" : "did not exist");
1138 if (file_existed) {
1139 how.flags = _how->flags & ~(O_CREAT);
1140 } else {
1141 how.flags = _how->flags | O_EXCL;
1144 status = fd_openat(dirfsp, smb_fname, fsp, &how);
1147 *file_created = (NT_STATUS_IS_OK(status) && !file_existed);
1148 return status;
1151 static NTSTATUS reopen_from_fsp(struct files_struct *dirfsp,
1152 struct smb_filename *smb_fname,
1153 struct files_struct *fsp,
1154 const struct vfs_open_how *how,
1155 bool *p_file_created)
1157 NTSTATUS status;
1158 int old_fd;
1160 if (fsp->fsp_flags.have_proc_fds &&
1161 ((old_fd = fsp_get_pathref_fd(fsp)) != -1)) {
1163 struct sys_proc_fd_path_buf buf;
1164 struct smb_filename proc_fname = {
1165 .base_name = sys_proc_fd_path(old_fd, &buf),
1167 mode_t mode = fsp->fsp_name->st.st_ex_mode;
1168 int new_fd;
1170 SMB_ASSERT(fsp->fsp_flags.is_pathref);
1172 if (S_ISLNK(mode)) {
1173 return NT_STATUS_STOPPED_ON_SYMLINK;
1175 if (!(S_ISREG(mode) || S_ISDIR(mode))) {
1176 return NT_STATUS_IO_REPARSE_TAG_NOT_HANDLED;
1179 fsp->fsp_flags.is_pathref = false;
1181 new_fd = SMB_VFS_OPENAT(fsp->conn,
1182 fsp->conn->cwd_fsp,
1183 &proc_fname,
1184 fsp,
1185 how);
1186 if (new_fd == -1) {
1187 #if defined(HAVE_FSTATFS) && defined(HAVE_LINUX_MAGIC_H)
1188 if (S_ISDIR(fsp->fsp_name->st.st_ex_mode) &&
1189 (errno == ENOENT)) {
1190 struct statfs sbuf = {};
1191 int ret = fstatfs(old_fd, &sbuf);
1192 if (ret == -1) {
1193 DBG_ERR("fstatfs failed: %s\n",
1194 strerror(errno));
1195 } else if (sbuf.f_type == AUTOFS_SUPER_MAGIC) {
1197 * When reopening an as-yet
1198 * unmounted autofs mount
1199 * point we get ENOENT. We
1200 * have to retry pathbased.
1202 goto namebased_open;
1204 /* restore ENOENT if changed in the meantime */
1205 errno = ENOENT;
1207 #endif
1208 status = map_nt_error_from_unix(errno);
1209 fd_close(fsp);
1210 return status;
1213 status = fd_close(fsp);
1214 if (!NT_STATUS_IS_OK(status)) {
1215 return status;
1218 fsp_set_fd(fsp, new_fd);
1219 return NT_STATUS_OK;
1222 #if defined(HAVE_FSTATFS) && defined(HAVE_LINUX_MAGIC_H)
1223 namebased_open:
1224 #endif
1226 * Close the existing pathref fd and set the fsp flag
1227 * is_pathref to false so we get a "normal" fd this time.
1229 status = fd_close(fsp);
1230 if (!NT_STATUS_IS_OK(status)) {
1231 return status;
1234 fsp->fsp_flags.is_pathref = false;
1236 status = fd_open_atomic(dirfsp, smb_fname, fsp, how, p_file_created);
1237 return status;
1240 /****************************************************************************
1241 Open a file.
1242 ****************************************************************************/
1244 static NTSTATUS open_file(
1245 struct smb_request *req,
1246 struct files_struct *dirfsp,
1247 struct smb_filename *smb_fname_atname,
1248 files_struct *fsp,
1249 const struct vfs_open_how *_how,
1250 uint32_t access_mask, /* client requested access mask. */
1251 uint32_t open_access_mask, /* what we're actually using in the open. */
1252 uint32_t private_flags,
1253 bool *p_file_created)
1255 connection_struct *conn = fsp->conn;
1256 struct smb_filename *smb_fname = fsp->fsp_name;
1257 struct vfs_open_how how = *_how;
1258 NTSTATUS status = NT_STATUS_OK;
1259 bool file_existed = VALID_STAT(fsp->fsp_name->st);
1260 const uint32_t need_fd_mask =
1261 FILE_READ_DATA |
1262 FILE_WRITE_DATA |
1263 FILE_APPEND_DATA |
1264 FILE_EXECUTE |
1265 SEC_FLAG_SYSTEM_SECURITY;
1266 bool creating = !file_existed && (how.flags & O_CREAT);
1267 bool open_fd = false;
1268 bool posix_open = (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN);
1271 * Catch early an attempt to open an existing
1272 * directory as a file.
1274 if (file_existed && S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
1275 return NT_STATUS_FILE_IS_A_DIRECTORY;
1279 * This little piece of insanity is inspired by the
1280 * fact that an NT client can open a file for O_RDONLY,
1281 * but set the create disposition to FILE_EXISTS_TRUNCATE.
1282 * If the client *can* write to the file, then it expects to
1283 * truncate the file, even though it is opening for readonly.
1284 * Quicken uses this stupid trick in backup file creation...
1285 * Thanks *greatly* to "David W. Chapman Jr." <dwcjr@inethouston.net>
1286 * for helping track this one down. It didn't bite us in 2.0.x
1287 * as we always opened files read-write in that release. JRA.
1290 if (((how.flags & O_ACCMODE) == O_RDONLY) && (how.flags & O_TRUNC)) {
1291 DBG_DEBUG("truncate requested on read-only open for file %s\n",
1292 smb_fname_str_dbg(smb_fname));
1293 how.flags = (how.flags & ~O_ACCMODE) | O_RDWR;
1296 /* Check permissions */
1299 * This code was changed after seeing a client open request
1300 * containing the open mode of (DENY_WRITE/read-only) with
1301 * the 'create if not exist' bit set. The previous code
1302 * would fail to open the file read only on a read-only share
1303 * as it was checking the flags parameter directly against O_RDONLY,
1304 * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
1305 * JRA.
1308 if (!CAN_WRITE(conn)) {
1309 /* It's a read-only share - fail if we wanted to write. */
1310 if ((how.flags & O_ACCMODE) != O_RDONLY ||
1311 (how.flags & O_TRUNC) || (how.flags & O_APPEND)) {
1312 DEBUG(3,("Permission denied opening %s\n",
1313 smb_fname_str_dbg(smb_fname)));
1314 return NT_STATUS_ACCESS_DENIED;
1317 * We don't want to write - but we must make sure that
1318 * O_CREAT doesn't create the file if we have write
1319 * access into the directory.
1321 how.flags &= ~(O_CREAT | O_EXCL);
1324 if ((open_access_mask & need_fd_mask) || creating ||
1325 (how.flags & O_TRUNC)) {
1326 open_fd = true;
1329 if (open_fd) {
1330 int ret;
1332 #if defined(O_NONBLOCK) && defined(S_ISFIFO)
1334 * We would block on opening a FIFO with no one else on the
1335 * other end. Do what we used to do and add O_NONBLOCK to the
1336 * open flags. JRA.
1339 if (file_existed && S_ISFIFO(smb_fname->st.st_ex_mode)) {
1340 how.flags |= O_NONBLOCK;
1342 #endif
1344 if (!posix_open) {
1345 const char *wild = smb_fname->base_name;
1347 * Don't open files with Microsoft wildcard characters.
1349 if (fsp_is_alternate_stream(fsp)) {
1351 * wildcard characters are allowed in stream
1352 * names only test the basefilename
1354 wild = fsp->base_fsp->fsp_name->base_name;
1357 if (ms_has_wild(wild)) {
1358 return NT_STATUS_OBJECT_NAME_INVALID;
1362 /* Can we access this file ? */
1363 if (!fsp_is_alternate_stream(fsp)) {
1364 /* Only do this check on non-stream open. */
1365 if (file_existed) {
1366 status = smbd_check_access_rights_fsp(
1367 dirfsp,
1368 fsp,
1369 false,
1370 open_access_mask);
1372 if (!NT_STATUS_IS_OK(status)) {
1373 DBG_DEBUG("smbd_check_access_rights_fsp"
1374 " on file %s returned %s\n",
1375 fsp_str_dbg(fsp),
1376 nt_errstr(status));
1379 if (!NT_STATUS_IS_OK(status) &&
1380 !NT_STATUS_EQUAL(status,
1381 NT_STATUS_OBJECT_NAME_NOT_FOUND))
1383 return status;
1386 if (NT_STATUS_EQUAL(status,
1387 NT_STATUS_OBJECT_NAME_NOT_FOUND))
1389 DEBUG(10, ("open_file: "
1390 "file %s vanished since we "
1391 "checked for existence.\n",
1392 smb_fname_str_dbg(smb_fname)));
1393 file_existed = false;
1394 SET_STAT_INVALID(fsp->fsp_name->st);
1398 if (!file_existed) {
1399 if (!(how.flags & O_CREAT)) {
1400 /* File didn't exist and no O_CREAT. */
1401 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1404 status = check_parent_access_fsp(
1405 dirfsp,
1406 SEC_DIR_ADD_FILE);
1407 if (!NT_STATUS_IS_OK(status)) {
1408 DBG_DEBUG("check_parent_access_fsp on "
1409 "directory %s for file %s "
1410 "returned %s\n",
1411 smb_fname_str_dbg(
1412 dirfsp->fsp_name),
1413 smb_fname_str_dbg(smb_fname),
1414 nt_errstr(status));
1415 return status;
1421 * Actually do the open - if O_TRUNC is needed handle it
1422 * below under the share mode lock.
1424 how.flags &= ~O_TRUNC;
1425 status = reopen_from_fsp(dirfsp,
1426 smb_fname_atname,
1427 fsp,
1428 &how,
1429 p_file_created);
1430 if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) {
1432 * Non-O_PATH reopen that hit a race
1433 * condition: Someone has put a symlink where
1434 * we used to have a file. Can't happen with
1435 * O_PATH and reopening from /proc/self/fd/ or
1436 * equivalent.
1438 status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
1440 if (!NT_STATUS_IS_OK(status)) {
1441 DBG_NOTICE("Error opening file %s (%s) (in_flags=%d) "
1442 "(flags=%d)\n",
1443 smb_fname_str_dbg(smb_fname),
1444 nt_errstr(status),
1445 _how->flags,
1446 how.flags);
1447 return status;
1450 if (how.flags & O_NONBLOCK) {
1452 * GPFS can return ETIMEDOUT for pread on
1453 * nonblocking file descriptors when files
1454 * migrated to tape need to be recalled. I
1455 * could imagine this happens elsewhere
1456 * too. With blocking file descriptors this
1457 * does not happen.
1459 ret = vfs_set_blocking(fsp, true);
1460 if (ret == -1) {
1461 status = map_nt_error_from_unix(errno);
1462 DBG_WARNING("Could not set fd to blocking: "
1463 "%s\n", strerror(errno));
1464 fd_close(fsp);
1465 return status;
1469 if (*p_file_created) {
1470 /* We created this file. */
1472 bool need_re_stat = false;
1473 /* Do all inheritance work after we've
1474 done a successful fstat call and filled
1475 in the stat struct in fsp->fsp_name. */
1477 /* Inherit the ACL if required */
1478 if (lp_inherit_permissions(SNUM(conn))) {
1479 inherit_access_posix_acl(conn,
1480 dirfsp,
1481 smb_fname,
1482 how.mode);
1483 need_re_stat = true;
1486 /* Change the owner if required. */
1487 if (lp_inherit_owner(SNUM(conn)) != INHERIT_OWNER_NO) {
1488 change_file_owner_to_parent_fsp(dirfsp, fsp);
1489 need_re_stat = true;
1492 if (need_re_stat) {
1493 status = vfs_stat_fsp(fsp);
1495 * If we have an fd, this stat should succeed.
1497 if (!NT_STATUS_IS_OK(status)) {
1498 DBG_ERR("Error doing fstat on open "
1499 "file %s (%s)\n",
1500 smb_fname_str_dbg(smb_fname),
1501 nt_errstr(status));
1502 fd_close(fsp);
1503 return status;
1507 notify_fname(conn, NOTIFY_ACTION_ADDED,
1508 FILE_NOTIFY_CHANGE_FILE_NAME,
1509 smb_fname->base_name);
1511 } else {
1512 if (!file_existed) {
1513 /* File must exist for a stat open. */
1514 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1517 if (S_ISLNK(smb_fname->st.st_ex_mode) &&
1518 !posix_open)
1521 * Don't allow stat opens on symlinks directly unless
1522 * it's a POSIX open. Match the return code from
1523 * openat_pathref_fsp().
1525 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1528 if (!fsp->fsp_flags.is_pathref) {
1530 * There is only one legit case where end up here:
1531 * openat_pathref_fsp() failed to open a symlink, so the
1532 * fsp was created by fsp_new() which doesn't set
1533 * is_pathref. Other than that, we should always have a
1534 * pathref fsp at this point. The subsequent checks
1535 * assert this.
1537 if (!(smb_fname->flags & SMB_FILENAME_POSIX_PATH)) {
1538 DBG_ERR("[%s] is not a POSIX pathname\n",
1539 smb_fname_str_dbg(smb_fname));
1540 return NT_STATUS_INTERNAL_ERROR;
1542 if (!S_ISLNK(smb_fname->st.st_ex_mode)) {
1543 DBG_ERR("[%s] is not a symlink\n",
1544 smb_fname_str_dbg(smb_fname));
1545 return NT_STATUS_INTERNAL_ERROR;
1547 if (fsp_get_pathref_fd(fsp) != -1) {
1548 DBG_ERR("fd for [%s] is not -1: fd [%d]\n",
1549 smb_fname_str_dbg(smb_fname),
1550 fsp_get_pathref_fd(fsp));
1551 return NT_STATUS_INTERNAL_ERROR;
1556 * Access to streams is checked by checking the basefile and
1557 * that has already been checked by check_base_file_access()
1558 * in create_file_unixpath().
1560 if (!fsp_is_alternate_stream(fsp)) {
1561 status = smbd_check_access_rights_fsp(dirfsp,
1562 fsp,
1563 false,
1564 open_access_mask);
1566 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) &&
1567 posix_open &&
1568 S_ISLNK(smb_fname->st.st_ex_mode)) {
1569 /* This is a POSIX stat open for delete
1570 * or rename on a symlink that points
1571 * nowhere. Allow. */
1572 DEBUG(10,("open_file: allowing POSIX "
1573 "open on bad symlink %s\n",
1574 smb_fname_str_dbg(smb_fname)));
1575 status = NT_STATUS_OK;
1578 if (!NT_STATUS_IS_OK(status)) {
1579 DBG_DEBUG("smbd_check_access_rights_fsp on file "
1580 "%s returned %s\n",
1581 fsp_str_dbg(fsp),
1582 nt_errstr(status));
1583 return status;
1588 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
1589 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
1590 fsp->file_pid = req ? req->smbpid : 0;
1591 fsp->fsp_flags.can_lock = true;
1592 fsp->fsp_flags.can_read = ((access_mask & FILE_READ_DATA) != 0);
1593 fsp->fsp_flags.can_write =
1594 CAN_WRITE(conn) &&
1595 ((access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) != 0);
1596 if (fsp->fsp_name->twrp != 0) {
1597 fsp->fsp_flags.can_write = false;
1599 fsp->print_file = NULL;
1600 fsp->fsp_flags.modified = false;
1601 fsp->sent_oplock_break = NO_BREAK_SENT;
1602 fsp->fsp_flags.is_directory = false;
1603 if (is_in_path(smb_fname->base_name,
1604 conn->aio_write_behind_list,
1605 posix_open ? true : conn->case_sensitive)) {
1606 fsp->fsp_flags.aio_write_behind = true;
1609 DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
1610 conn->session_info->unix_info->unix_name,
1611 smb_fname_str_dbg(smb_fname),
1612 BOOLSTR(fsp->fsp_flags.can_read),
1613 BOOLSTR(fsp->fsp_flags.can_write),
1614 conn->num_files_open));
1616 return NT_STATUS_OK;
1619 static bool mask_conflict(
1620 uint32_t new_access,
1621 uint32_t existing_access,
1622 uint32_t access_mask,
1623 uint32_t new_sharemode,
1624 uint32_t existing_sharemode,
1625 uint32_t sharemode_mask)
1627 bool want_access = (new_access & access_mask);
1628 bool allow_existing = (existing_sharemode & sharemode_mask);
1629 bool have_access = (existing_access & access_mask);
1630 bool allow_new = (new_sharemode & sharemode_mask);
1632 if (want_access && !allow_existing) {
1633 DBG_DEBUG("Access request 0x%"PRIx32"/0x%"PRIx32" conflicts "
1634 "with existing sharemode 0x%"PRIx32"/0x%"PRIx32"\n",
1635 new_access,
1636 access_mask,
1637 existing_sharemode,
1638 sharemode_mask);
1639 return true;
1641 if (have_access && !allow_new) {
1642 DBG_DEBUG("Sharemode request 0x%"PRIx32"/0x%"PRIx32" conflicts "
1643 "with existing access 0x%"PRIx32"/0x%"PRIx32"\n",
1644 new_sharemode,
1645 sharemode_mask,
1646 existing_access,
1647 access_mask);
1648 return true;
1650 return false;
1653 /****************************************************************************
1654 Check if we can open a file with a share mode.
1655 Returns True if conflict, False if not.
1656 ****************************************************************************/
1658 static const uint32_t conflicting_access =
1659 FILE_WRITE_DATA|
1660 FILE_APPEND_DATA|
1661 FILE_READ_DATA|
1662 FILE_EXECUTE|
1663 DELETE_ACCESS;
1665 static bool share_conflict(uint32_t e_access_mask,
1666 uint32_t e_share_access,
1667 uint32_t access_mask,
1668 uint32_t share_access)
1670 bool conflict;
1672 DBG_DEBUG("existing access_mask = 0x%"PRIx32", "
1673 "existing share access = 0x%"PRIx32", "
1674 "access_mask = 0x%"PRIx32", "
1675 "share_access = 0x%"PRIx32"\n",
1676 e_access_mask,
1677 e_share_access,
1678 access_mask,
1679 share_access);
1681 if ((e_access_mask & conflicting_access) == 0) {
1682 DBG_DEBUG("No conflict due to "
1683 "existing access_mask = 0x%"PRIx32"\n",
1684 e_access_mask);
1685 return false;
1687 if ((access_mask & conflicting_access) == 0) {
1688 DBG_DEBUG("No conflict due to access_mask = 0x%"PRIx32"\n",
1689 access_mask);
1690 return false;
1693 conflict = mask_conflict(
1694 access_mask, e_access_mask, FILE_WRITE_DATA | FILE_APPEND_DATA,
1695 share_access, e_share_access, FILE_SHARE_WRITE);
1696 conflict |= mask_conflict(
1697 access_mask, e_access_mask, FILE_READ_DATA | FILE_EXECUTE,
1698 share_access, e_share_access, FILE_SHARE_READ);
1699 conflict |= mask_conflict(
1700 access_mask, e_access_mask, DELETE_ACCESS,
1701 share_access, e_share_access, FILE_SHARE_DELETE);
1703 DBG_DEBUG("conflict=%s\n", conflict ? "true" : "false");
1704 return conflict;
1707 #if defined(DEVELOPER)
1709 struct validate_my_share_entries_state {
1710 struct smbd_server_connection *sconn;
1711 struct file_id fid;
1712 struct server_id self;
1715 static bool validate_my_share_entries_fn(
1716 struct share_mode_entry *e,
1717 bool *modified,
1718 void *private_data)
1720 struct validate_my_share_entries_state *state = private_data;
1721 files_struct *fsp;
1723 if (!server_id_equal(&state->self, &e->pid)) {
1724 return false;
1727 if (e->op_mid == 0) {
1728 /* INTERNAL_OPEN_ONLY */
1729 return false;
1732 fsp = file_find_dif(state->sconn, state->fid, e->share_file_id);
1733 if (!fsp) {
1734 DBG_ERR("PANIC : %s\n",
1735 share_mode_str(talloc_tos(), 0, &state->fid, e));
1736 smb_panic("validate_my_share_entries: Cannot match a "
1737 "share entry with an open file\n");
1740 if (((uint16_t)fsp->oplock_type) != e->op_type) {
1741 goto panic;
1744 return false;
1746 panic:
1748 char *str;
1749 DBG_ERR("validate_my_share_entries: PANIC : %s\n",
1750 share_mode_str(talloc_tos(), 0, &state->fid, e));
1751 str = talloc_asprintf(talloc_tos(),
1752 "validate_my_share_entries: "
1753 "file %s, oplock_type = 0x%x, op_type = 0x%x\n",
1754 fsp->fsp_name->base_name,
1755 (unsigned int)fsp->oplock_type,
1756 (unsigned int)e->op_type);
1757 smb_panic(str);
1760 return false;
1762 #endif
1765 * Allowed access mask for stat opens relevant to oplocks
1767 bool is_oplock_stat_open(uint32_t access_mask)
1769 const uint32_t stat_open_bits =
1770 (SYNCHRONIZE_ACCESS|
1771 FILE_READ_ATTRIBUTES|
1772 FILE_WRITE_ATTRIBUTES);
1774 return (((access_mask & stat_open_bits) != 0) &&
1775 ((access_mask & ~stat_open_bits) == 0));
1779 * Allowed access mask for stat opens relevant to leases
1781 bool is_lease_stat_open(uint32_t access_mask)
1783 const uint32_t stat_open_bits =
1784 (SYNCHRONIZE_ACCESS|
1785 FILE_READ_ATTRIBUTES|
1786 FILE_WRITE_ATTRIBUTES|
1787 READ_CONTROL_ACCESS);
1789 return (((access_mask & stat_open_bits) != 0) &&
1790 ((access_mask & ~stat_open_bits) == 0));
1793 struct has_delete_on_close_state {
1794 bool ret;
1797 static bool has_delete_on_close_fn(
1798 struct share_mode_entry *e,
1799 bool *modified,
1800 void *private_data)
1802 struct has_delete_on_close_state *state = private_data;
1803 state->ret = !share_entry_stale_pid(e);
1804 return state->ret;
1807 static bool has_delete_on_close(struct share_mode_lock *lck,
1808 uint32_t name_hash)
1810 struct has_delete_on_close_state state = { .ret = false };
1811 bool ok;
1813 if (!is_delete_on_close_set(lck, name_hash)) {
1814 return false;
1817 ok= share_mode_forall_entries(lck, has_delete_on_close_fn, &state);
1818 if (!ok) {
1819 DBG_DEBUG("share_mode_forall_entries failed\n");
1820 return false;
1822 return state.ret;
1825 static void share_mode_flags_restrict(
1826 struct share_mode_lock *lck,
1827 uint32_t access_mask,
1828 uint32_t share_mode,
1829 uint32_t lease_type)
1831 uint32_t existing_access_mask, existing_share_mode;
1832 uint32_t existing_lease_type;
1834 share_mode_flags_get(
1835 lck,
1836 &existing_access_mask,
1837 &existing_share_mode,
1838 &existing_lease_type);
1840 existing_access_mask |= access_mask;
1841 if (access_mask & conflicting_access) {
1842 existing_share_mode &= share_mode;
1844 existing_lease_type |= lease_type;
1846 share_mode_flags_set(
1847 lck,
1848 existing_access_mask,
1849 existing_share_mode,
1850 existing_lease_type,
1851 NULL);
1854 /****************************************************************************
1855 Deal with share modes
1856 Invariant: Share mode must be locked on entry and exit.
1857 Returns -1 on error, or number of share modes on success (may be zero).
1858 ****************************************************************************/
1860 struct open_mode_check_state {
1861 struct file_id fid;
1862 uint32_t access_mask;
1863 uint32_t share_access;
1864 uint32_t lease_type;
1867 static bool open_mode_check_fn(
1868 struct share_mode_entry *e,
1869 bool *modified,
1870 void *private_data)
1872 struct open_mode_check_state *state = private_data;
1873 bool disconnected, stale;
1874 uint32_t access_mask, share_access, lease_type;
1876 disconnected = server_id_is_disconnected(&e->pid);
1877 if (disconnected) {
1878 return false;
1881 access_mask = state->access_mask | e->access_mask;
1882 share_access = state->share_access;
1883 if (e->access_mask & conflicting_access) {
1884 share_access &= e->share_access;
1886 lease_type = state->lease_type | get_lease_type(e, state->fid);
1888 if ((access_mask == state->access_mask) &&
1889 (share_access == state->share_access) &&
1890 (lease_type == state->lease_type)) {
1891 return false;
1894 stale = share_entry_stale_pid(e);
1895 if (stale) {
1896 return false;
1899 state->access_mask = access_mask;
1900 state->share_access = share_access;
1901 state->lease_type = lease_type;
1903 return false;
1906 static NTSTATUS open_mode_check(connection_struct *conn,
1907 struct file_id fid,
1908 struct share_mode_lock *lck,
1909 uint32_t access_mask,
1910 uint32_t share_access)
1912 struct open_mode_check_state state;
1913 bool ok, conflict;
1914 bool modified = false;
1916 if (is_oplock_stat_open(access_mask)) {
1917 /* Stat open that doesn't trigger oplock breaks or share mode
1918 * checks... ! JRA. */
1919 return NT_STATUS_OK;
1923 * Check if the share modes will give us access.
1926 #if defined(DEVELOPER)
1928 struct validate_my_share_entries_state validate_state = {
1929 .sconn = conn->sconn,
1930 .fid = fid,
1931 .self = messaging_server_id(conn->sconn->msg_ctx),
1933 ok = share_mode_forall_entries(
1934 lck, validate_my_share_entries_fn, &validate_state);
1935 SMB_ASSERT(ok);
1937 #endif
1939 share_mode_flags_get(
1940 lck, &state.access_mask, &state.share_access, NULL);
1942 conflict = share_conflict(
1943 state.access_mask,
1944 state.share_access,
1945 access_mask,
1946 share_access);
1947 if (!conflict) {
1948 DBG_DEBUG("No conflict due to share_mode_flags access\n");
1949 return NT_STATUS_OK;
1952 state = (struct open_mode_check_state) {
1953 .fid = fid,
1954 .share_access = (FILE_SHARE_READ|
1955 FILE_SHARE_WRITE|
1956 FILE_SHARE_DELETE),
1960 * Walk the share mode array to recalculate d->flags
1963 ok = share_mode_forall_entries(lck, open_mode_check_fn, &state);
1964 if (!ok) {
1965 DBG_DEBUG("share_mode_forall_entries failed\n");
1966 return NT_STATUS_INTERNAL_ERROR;
1969 share_mode_flags_set(
1970 lck,
1971 state.access_mask,
1972 state.share_access,
1973 state.lease_type,
1974 &modified);
1975 if (!modified) {
1977 * We only end up here if we had a sharing violation
1978 * from d->flags and have recalculated it.
1980 return NT_STATUS_SHARING_VIOLATION;
1983 conflict = share_conflict(
1984 state.access_mask,
1985 state.share_access,
1986 access_mask,
1987 share_access);
1988 if (!conflict) {
1989 DBG_DEBUG("No conflict due to share_mode_flags access\n");
1990 return NT_STATUS_OK;
1993 return NT_STATUS_SHARING_VIOLATION;
1997 * Send a break message to the oplock holder and delay the open for
1998 * our client.
2001 NTSTATUS send_break_message(struct messaging_context *msg_ctx,
2002 const struct file_id *id,
2003 const struct share_mode_entry *exclusive,
2004 uint16_t break_to)
2006 struct oplock_break_message msg = {
2007 .id = *id,
2008 .share_file_id = exclusive->share_file_id,
2009 .break_to = break_to,
2011 enum ndr_err_code ndr_err;
2012 uint8_t msgbuf[33];
2013 DATA_BLOB blob = {.data = msgbuf, .length = sizeof(msgbuf)};
2014 NTSTATUS status;
2016 if (DEBUGLVL(10)) {
2017 struct server_id_buf buf;
2018 DBG_DEBUG("Sending break message to %s\n",
2019 server_id_str_buf(exclusive->pid, &buf));
2020 NDR_PRINT_DEBUG(oplock_break_message, &msg);
2023 ndr_err = ndr_push_struct_into_fixed_blob(
2024 &blob,
2025 &msg,
2026 (ndr_push_flags_fn_t)ndr_push_oplock_break_message);
2027 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2028 DBG_WARNING("ndr_push_oplock_break_message failed: %s\n",
2029 ndr_errstr(ndr_err));
2030 return ndr_map_error2ntstatus(ndr_err);
2033 status = messaging_send(msg_ctx,
2034 exclusive->pid,
2035 MSG_SMB_BREAK_REQUEST,
2036 &blob);
2037 if (!NT_STATUS_IS_OK(status)) {
2038 DEBUG(3, ("Could not send oplock break message: %s\n",
2039 nt_errstr(status)));
2042 return status;
2045 struct validate_oplock_types_state {
2046 bool valid;
2047 bool batch;
2048 bool ex_or_batch;
2049 bool level2;
2050 bool no_oplock;
2051 uint32_t num_non_stat_opens;
2054 static bool validate_oplock_types_fn(
2055 struct share_mode_entry *e,
2056 bool *modified,
2057 void *private_data)
2059 struct validate_oplock_types_state *state = private_data;
2061 if (e->op_mid == 0) {
2062 /* INTERNAL_OPEN_ONLY */
2063 return false;
2066 if (e->op_type == NO_OPLOCK && is_oplock_stat_open(e->access_mask)) {
2068 * We ignore stat opens in the table - they always
2069 * have NO_OPLOCK and never get or cause breaks. JRA.
2071 return false;
2074 state->num_non_stat_opens += 1;
2076 if (BATCH_OPLOCK_TYPE(e->op_type)) {
2077 /* batch - can only be one. */
2078 if (share_entry_stale_pid(e)) {
2079 DBG_DEBUG("Found stale batch oplock\n");
2080 return false;
2082 if (state->ex_or_batch ||
2083 state->batch ||
2084 state->level2 ||
2085 state->no_oplock) {
2086 DBG_ERR("Bad batch oplock entry\n");
2087 state->valid = false;
2088 return true;
2090 state->batch = true;
2093 if (EXCLUSIVE_OPLOCK_TYPE(e->op_type)) {
2094 if (share_entry_stale_pid(e)) {
2095 DBG_DEBUG("Found stale duplicate oplock\n");
2096 return false;
2098 /* Exclusive or batch - can only be one. */
2099 if (state->ex_or_batch ||
2100 state->level2 ||
2101 state->no_oplock) {
2102 DBG_ERR("Bad exclusive or batch oplock entry\n");
2103 state->valid = false;
2104 return true;
2106 state->ex_or_batch = true;
2109 if (LEVEL_II_OPLOCK_TYPE(e->op_type)) {
2110 if (state->batch || state->ex_or_batch) {
2111 if (share_entry_stale_pid(e)) {
2112 DBG_DEBUG("Found stale LevelII oplock\n");
2113 return false;
2115 DBG_DEBUG("Bad levelII oplock entry\n");
2116 state->valid = false;
2117 return true;
2119 state->level2 = true;
2122 if (e->op_type == NO_OPLOCK) {
2123 if (state->batch || state->ex_or_batch) {
2124 if (share_entry_stale_pid(e)) {
2125 DBG_DEBUG("Found stale NO_OPLOCK entry\n");
2126 return false;
2128 DBG_ERR("Bad no oplock entry\n");
2129 state->valid = false;
2130 return true;
2132 state->no_oplock = true;
2135 return false;
2139 * Do internal consistency checks on the share mode for a file.
2142 static bool validate_oplock_types(struct share_mode_lock *lck)
2144 struct validate_oplock_types_state state = { .valid = true };
2145 static bool skip_validation;
2146 bool validate;
2147 bool ok;
2149 if (skip_validation) {
2150 return true;
2153 validate = lp_parm_bool(-1, "smbd", "validate_oplock_types", false);
2154 if (!validate) {
2155 DBG_DEBUG("smbd:validate_oplock_types not set to yes\n");
2156 skip_validation = true;
2157 return true;
2160 ok = share_mode_forall_entries(lck, validate_oplock_types_fn, &state);
2161 if (!ok) {
2162 DBG_DEBUG("share_mode_forall_entries failed\n");
2163 return false;
2165 if (!state.valid) {
2166 DBG_DEBUG("Got invalid oplock configuration\n");
2167 return false;
2170 if ((state.batch || state.ex_or_batch) &&
2171 (state.num_non_stat_opens != 1)) {
2172 DBG_WARNING("got batch (%d) or ex (%d) non-exclusively "
2173 "(%"PRIu32")\n",
2174 (int)state.batch,
2175 (int)state.ex_or_batch,
2176 state.num_non_stat_opens);
2177 return false;
2180 return true;
2183 static bool is_same_lease(const files_struct *fsp,
2184 const struct share_mode_entry *e,
2185 const struct smb2_lease *lease)
2187 if (e->op_type != LEASE_OPLOCK) {
2188 return false;
2190 if (lease == NULL) {
2191 return false;
2194 return smb2_lease_equal(fsp_client_guid(fsp),
2195 &lease->lease_key,
2196 &e->client_guid,
2197 &e->lease_key);
2200 static bool file_has_brlocks(files_struct *fsp)
2202 struct byte_range_lock *br_lck;
2204 br_lck = brl_get_locks_readonly(fsp);
2205 if (!br_lck)
2206 return false;
2208 return (brl_num_locks(br_lck) > 0);
2211 struct fsp_lease *find_fsp_lease(struct files_struct *new_fsp,
2212 const struct smb2_lease_key *key,
2213 uint32_t current_state,
2214 uint16_t lease_version,
2215 uint16_t lease_epoch)
2217 struct files_struct *fsp;
2220 * TODO: Measure how expensive this loop is with thousands of open
2221 * handles...
2224 for (fsp = file_find_di_first(new_fsp->conn->sconn, new_fsp->file_id, true);
2225 fsp != NULL;
2226 fsp = file_find_di_next(fsp, true)) {
2228 if (fsp == new_fsp) {
2229 continue;
2231 if (fsp->oplock_type != LEASE_OPLOCK) {
2232 continue;
2234 if (smb2_lease_key_equal(&fsp->lease->lease.lease_key, key)) {
2235 fsp->lease->ref_count += 1;
2236 return fsp->lease;
2240 /* Not found - must be leased in another smbd. */
2241 new_fsp->lease = talloc_zero(new_fsp->conn->sconn, struct fsp_lease);
2242 if (new_fsp->lease == NULL) {
2243 return NULL;
2245 new_fsp->lease->ref_count = 1;
2246 new_fsp->lease->sconn = new_fsp->conn->sconn;
2247 new_fsp->lease->lease.lease_key = *key;
2248 new_fsp->lease->lease.lease_state = current_state;
2250 * We internally treat all leases as V2 and update
2251 * the epoch, but when sending breaks it matters if
2252 * the requesting lease was v1 or v2.
2254 new_fsp->lease->lease.lease_version = lease_version;
2255 new_fsp->lease->lease.lease_epoch = lease_epoch;
2256 return new_fsp->lease;
2259 static NTSTATUS try_lease_upgrade(struct files_struct *fsp,
2260 struct share_mode_lock *lck,
2261 const struct GUID *client_guid,
2262 const struct smb2_lease *lease,
2263 uint32_t granted)
2265 bool do_upgrade;
2266 uint32_t current_state, breaking_to_requested, breaking_to_required;
2267 bool breaking;
2268 uint16_t lease_version, epoch;
2269 uint32_t existing, requested;
2270 NTSTATUS status;
2272 status = leases_db_get(
2273 client_guid,
2274 &lease->lease_key,
2275 &fsp->file_id,
2276 &current_state,
2277 &breaking,
2278 &breaking_to_requested,
2279 &breaking_to_required,
2280 &lease_version,
2281 &epoch);
2282 if (!NT_STATUS_IS_OK(status)) {
2283 return status;
2286 fsp->lease = find_fsp_lease(
2287 fsp,
2288 &lease->lease_key,
2289 current_state,
2290 lease_version,
2291 epoch);
2292 if (fsp->lease == NULL) {
2293 DEBUG(1, ("Did not find existing lease for file %s\n",
2294 fsp_str_dbg(fsp)));
2295 return NT_STATUS_NO_MEMORY;
2299 * Upgrade only if the requested lease is a strict upgrade.
2301 existing = current_state;
2302 requested = lease->lease_state;
2305 * Tricky: This test makes sure that "requested" is a
2306 * strict bitwise superset of "existing".
2308 do_upgrade = ((existing & requested) == existing);
2311 * Upgrade only if there's a change.
2313 do_upgrade &= (granted != existing);
2316 * Upgrade only if other leases don't prevent what was asked
2317 * for.
2319 do_upgrade &= (granted == requested);
2322 * only upgrade if we are not in breaking state
2324 do_upgrade &= !breaking;
2326 DEBUG(10, ("existing=%"PRIu32", requested=%"PRIu32", "
2327 "granted=%"PRIu32", do_upgrade=%d\n",
2328 existing, requested, granted, (int)do_upgrade));
2330 if (do_upgrade) {
2331 NTSTATUS set_status;
2333 current_state = granted;
2334 epoch += 1;
2336 set_status = leases_db_set(
2337 client_guid,
2338 &lease->lease_key,
2339 current_state,
2340 breaking,
2341 breaking_to_requested,
2342 breaking_to_required,
2343 lease_version,
2344 epoch);
2346 if (!NT_STATUS_IS_OK(set_status)) {
2347 DBG_DEBUG("leases_db_set failed: %s\n",
2348 nt_errstr(set_status));
2349 return set_status;
2353 fsp_lease_update(fsp);
2355 return NT_STATUS_OK;
2358 static NTSTATUS grant_new_fsp_lease(struct files_struct *fsp,
2359 struct share_mode_lock *lck,
2360 const struct GUID *client_guid,
2361 const struct smb2_lease *lease,
2362 uint32_t granted)
2364 NTSTATUS status;
2366 fsp->lease = talloc_zero(fsp->conn->sconn, struct fsp_lease);
2367 if (fsp->lease == NULL) {
2368 return NT_STATUS_INSUFFICIENT_RESOURCES;
2370 fsp->lease->ref_count = 1;
2371 fsp->lease->sconn = fsp->conn->sconn;
2372 fsp->lease->lease.lease_version = lease->lease_version;
2373 fsp->lease->lease.lease_key = lease->lease_key;
2374 fsp->lease->lease.lease_state = granted;
2375 fsp->lease->lease.lease_epoch = lease->lease_epoch + 1;
2377 status = leases_db_add(client_guid,
2378 &lease->lease_key,
2379 &fsp->file_id,
2380 fsp->lease->lease.lease_state,
2381 fsp->lease->lease.lease_version,
2382 fsp->lease->lease.lease_epoch,
2383 fsp->conn->connectpath,
2384 fsp->fsp_name->base_name,
2385 fsp->fsp_name->stream_name);
2386 if (!NT_STATUS_IS_OK(status)) {
2387 DEBUG(10, ("%s: leases_db_add failed: %s\n", __func__,
2388 nt_errstr(status)));
2389 TALLOC_FREE(fsp->lease);
2390 return NT_STATUS_INSUFFICIENT_RESOURCES;
2394 * We used to set lck->data->modified=true here without
2395 * actually modifying lck->data, triggering a needless
2396 * writeback of lck->data.
2398 * Apart from that writeback, setting modified=true has the
2399 * effect of triggering all waiters for this file to
2400 * retry. This only makes sense if any blocking condition
2401 * (i.e. waiting for a lease to be downgraded or removed) is
2402 * gone. This routine here only adds a lease, so it will never
2403 * free up resources that blocked waiters can now claim. So
2404 * that second effect also does not matter in this
2405 * routine. Thus setting lck->data->modified=true does not
2406 * need to be done here.
2409 return NT_STATUS_OK;
2412 static NTSTATUS grant_fsp_lease(struct files_struct *fsp,
2413 struct share_mode_lock *lck,
2414 const struct smb2_lease *lease,
2415 uint32_t granted)
2417 const struct GUID *client_guid = fsp_client_guid(fsp);
2418 NTSTATUS status;
2420 status = try_lease_upgrade(fsp, lck, client_guid, lease, granted);
2422 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
2423 status = grant_new_fsp_lease(
2424 fsp, lck, client_guid, lease, granted);
2427 return status;
2430 static int map_lease_type_to_oplock(uint32_t lease_type)
2432 int result = NO_OPLOCK;
2434 switch (lease_type) {
2435 case SMB2_LEASE_READ|SMB2_LEASE_WRITE|SMB2_LEASE_HANDLE:
2436 result = BATCH_OPLOCK|EXCLUSIVE_OPLOCK;
2437 break;
2438 case SMB2_LEASE_READ|SMB2_LEASE_WRITE:
2439 result = EXCLUSIVE_OPLOCK;
2440 break;
2441 case SMB2_LEASE_READ|SMB2_LEASE_HANDLE:
2442 case SMB2_LEASE_READ:
2443 result = LEVEL_II_OPLOCK;
2444 break;
2447 return result;
2450 struct delay_for_oplock_state {
2451 struct files_struct *fsp;
2452 const struct smb2_lease *lease;
2453 bool will_overwrite;
2454 uint32_t delay_mask;
2455 bool first_open_attempt;
2456 bool got_handle_lease;
2457 bool got_oplock;
2458 bool have_other_lease;
2459 uint32_t total_lease_types;
2460 bool delay;
2463 static bool delay_for_oplock_fn(
2464 struct share_mode_entry *e,
2465 bool *modified,
2466 void *private_data)
2468 struct delay_for_oplock_state *state = private_data;
2469 struct files_struct *fsp = state->fsp;
2470 const struct smb2_lease *lease = state->lease;
2471 bool e_is_lease = (e->op_type == LEASE_OPLOCK);
2472 uint32_t e_lease_type = SMB2_LEASE_NONE;
2473 uint32_t break_to;
2474 bool lease_is_breaking = false;
2476 if (e_is_lease) {
2477 NTSTATUS status;
2479 if (lease != NULL) {
2480 bool our_lease = is_same_lease(fsp, e, lease);
2481 if (our_lease) {
2482 DBG_DEBUG("Ignoring our own lease\n");
2483 return false;
2487 status = leases_db_get(
2488 &e->client_guid,
2489 &e->lease_key,
2490 &fsp->file_id,
2491 &e_lease_type, /* current_state */
2492 &lease_is_breaking,
2493 NULL, /* breaking_to_requested */
2494 NULL, /* breaking_to_required */
2495 NULL, /* lease_version */
2496 NULL); /* epoch */
2499 * leases_db_get() can return NT_STATUS_NOT_FOUND
2500 * if the share_mode_entry e is stale and the
2501 * lease record was already removed. In this case return
2502 * false so the traverse continues.
2505 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND) &&
2506 share_entry_stale_pid(e))
2508 struct GUID_txt_buf guid_strbuf;
2509 struct file_id_buf file_id_strbuf;
2510 DBG_DEBUG("leases_db_get for client_guid [%s] "
2511 "lease_key [%"PRIu64"/%"PRIu64"] "
2512 "file_id [%s] failed for stale "
2513 "share_mode_entry\n",
2514 GUID_buf_string(&e->client_guid, &guid_strbuf),
2515 e->lease_key.data[0],
2516 e->lease_key.data[1],
2517 file_id_str_buf(fsp->file_id, &file_id_strbuf));
2518 return false;
2520 if (!NT_STATUS_IS_OK(status)) {
2521 struct GUID_txt_buf guid_strbuf;
2522 struct file_id_buf file_id_strbuf;
2523 DBG_ERR("leases_db_get for client_guid [%s] "
2524 "lease_key [%"PRIu64"/%"PRIu64"] "
2525 "file_id [%s] failed: %s\n",
2526 GUID_buf_string(&e->client_guid, &guid_strbuf),
2527 e->lease_key.data[0],
2528 e->lease_key.data[1],
2529 file_id_str_buf(fsp->file_id, &file_id_strbuf),
2530 nt_errstr(status));
2531 smb_panic("leases_db_get() failed");
2533 } else {
2534 e_lease_type = get_lease_type(e, fsp->file_id);
2537 if (((e_lease_type & ~state->total_lease_types) != 0) &&
2538 !share_entry_stale_pid(e))
2540 state->total_lease_types |= e_lease_type;
2543 if (!state->got_handle_lease &&
2544 ((e_lease_type & SMB2_LEASE_HANDLE) != 0) &&
2545 !share_entry_stale_pid(e)) {
2546 state->got_handle_lease = true;
2549 if (!state->got_oplock &&
2550 (e->op_type != LEASE_OPLOCK) &&
2551 !share_entry_stale_pid(e)) {
2552 state->got_oplock = true;
2555 if (!state->have_other_lease &&
2556 !is_same_lease(fsp, e, lease) &&
2557 !share_entry_stale_pid(e)) {
2558 state->have_other_lease = true;
2561 if (e_is_lease && is_lease_stat_open(fsp->access_mask)) {
2562 return false;
2565 break_to = e_lease_type & ~state->delay_mask;
2567 if (state->will_overwrite) {
2568 break_to &= ~(SMB2_LEASE_HANDLE|SMB2_LEASE_READ);
2571 DBG_DEBUG("e_lease_type %u, will_overwrite: %u\n",
2572 (unsigned)e_lease_type,
2573 (unsigned)state->will_overwrite);
2575 if ((e_lease_type & ~break_to) == 0) {
2576 if (lease_is_breaking) {
2577 state->delay = true;
2579 return false;
2582 if (share_entry_stale_pid(e)) {
2583 return false;
2586 if (state->will_overwrite) {
2588 * If we break anyway break to NONE directly.
2589 * Otherwise vfs_set_filelen() will trigger the
2590 * break.
2592 break_to &= ~(SMB2_LEASE_READ|SMB2_LEASE_WRITE);
2595 if (!e_is_lease) {
2597 * Oplocks only support breaking to R or NONE.
2599 break_to &= ~(SMB2_LEASE_HANDLE|SMB2_LEASE_WRITE);
2602 DBG_DEBUG("breaking from %d to %d\n",
2603 (int)e_lease_type,
2604 (int)break_to);
2605 send_break_message(
2606 fsp->conn->sconn->msg_ctx, &fsp->file_id, e, break_to);
2607 if (e_lease_type & state->delay_mask) {
2608 state->delay = true;
2610 if (lease_is_breaking && !state->first_open_attempt) {
2611 state->delay = true;
2614 return false;
2617 static NTSTATUS delay_for_oplock(files_struct *fsp,
2618 int oplock_request,
2619 const struct smb2_lease *lease,
2620 struct share_mode_lock *lck,
2621 bool have_sharing_violation,
2622 uint32_t create_disposition,
2623 bool first_open_attempt,
2624 int *poplock_type,
2625 uint32_t *pgranted)
2627 struct delay_for_oplock_state state = {
2628 .fsp = fsp,
2629 .lease = lease,
2630 .first_open_attempt = first_open_attempt,
2632 uint32_t requested;
2633 uint32_t granted;
2634 int oplock_type;
2635 bool ok;
2637 *poplock_type = NO_OPLOCK;
2638 *pgranted = 0;
2640 if (fsp->fsp_flags.is_directory) {
2642 * No directory leases yet
2644 SMB_ASSERT(oplock_request == NO_OPLOCK);
2645 if (have_sharing_violation) {
2646 return NT_STATUS_SHARING_VIOLATION;
2648 return NT_STATUS_OK;
2651 if (oplock_request == LEASE_OPLOCK) {
2652 if (lease == NULL) {
2654 * The SMB2 layer should have checked this
2656 return NT_STATUS_INTERNAL_ERROR;
2659 requested = lease->lease_state;
2660 } else {
2661 requested = map_oplock_to_lease_type(
2662 oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK);
2665 share_mode_flags_get(lck, NULL, NULL, &state.total_lease_types);
2667 if (is_oplock_stat_open(fsp->access_mask)) {
2668 goto grant;
2671 state.delay_mask = have_sharing_violation ?
2672 SMB2_LEASE_HANDLE : SMB2_LEASE_WRITE;
2674 switch (create_disposition) {
2675 case FILE_SUPERSEDE:
2676 case FILE_OVERWRITE:
2677 case FILE_OVERWRITE_IF:
2678 state.will_overwrite = true;
2679 break;
2680 default:
2681 state.will_overwrite = false;
2682 break;
2685 state.total_lease_types = SMB2_LEASE_NONE;
2686 ok = share_mode_forall_entries(lck, delay_for_oplock_fn, &state);
2687 if (!ok) {
2688 return NT_STATUS_INTERNAL_ERROR;
2691 if (state.delay) {
2692 return NT_STATUS_RETRY;
2695 grant:
2696 if (have_sharing_violation) {
2697 return NT_STATUS_SHARING_VIOLATION;
2700 granted = requested;
2702 if (oplock_request == LEASE_OPLOCK) {
2703 if (lp_kernel_oplocks(SNUM(fsp->conn))) {
2704 DEBUG(10, ("No lease granted because kernel oplocks are enabled\n"));
2705 granted = SMB2_LEASE_NONE;
2707 if ((granted & (SMB2_LEASE_READ|SMB2_LEASE_WRITE)) == 0) {
2708 DEBUG(10, ("No read or write lease requested\n"));
2709 granted = SMB2_LEASE_NONE;
2711 if (granted == SMB2_LEASE_WRITE) {
2712 DEBUG(10, ("pure write lease requested\n"));
2713 granted = SMB2_LEASE_NONE;
2715 if (granted == (SMB2_LEASE_WRITE|SMB2_LEASE_HANDLE)) {
2716 DEBUG(10, ("write and handle lease requested\n"));
2717 granted = SMB2_LEASE_NONE;
2721 if (lp_locking(fsp->conn->params) && file_has_brlocks(fsp)) {
2722 DBG_DEBUG("file %s has byte range locks\n",
2723 fsp_str_dbg(fsp));
2724 granted &= ~SMB2_LEASE_READ;
2727 if (state.have_other_lease) {
2729 * Can grant only one writer
2731 granted &= ~SMB2_LEASE_WRITE;
2734 if ((granted & SMB2_LEASE_READ) && !(granted & SMB2_LEASE_WRITE)) {
2735 bool allow_level2 =
2736 (global_client_caps & CAP_LEVEL_II_OPLOCKS) &&
2737 lp_level2_oplocks(SNUM(fsp->conn));
2739 if (!allow_level2) {
2740 granted = SMB2_LEASE_NONE;
2744 if (oplock_request == LEASE_OPLOCK) {
2745 if (state.got_oplock) {
2746 granted &= ~SMB2_LEASE_HANDLE;
2749 oplock_type = LEASE_OPLOCK;
2750 } else {
2751 if (state.got_handle_lease) {
2752 granted = SMB2_LEASE_NONE;
2756 * Reflect possible downgrades from:
2757 * - map_lease_type_to_oplock() => "RH" to just LEVEL_II
2759 oplock_type = map_lease_type_to_oplock(granted);
2760 granted = map_oplock_to_lease_type(oplock_type);
2763 state.total_lease_types |= granted;
2766 uint32_t acc, sh, ls;
2767 share_mode_flags_get(lck, &acc, &sh, &ls);
2768 ls = state.total_lease_types;
2769 share_mode_flags_set(lck, acc, sh, ls, NULL);
2772 DBG_DEBUG("oplock type 0x%x granted (%s%s%s)(0x%x), on file %s, "
2773 "requested 0x%x (%s%s%s)(0x%x) => total (%s%s%s)(0x%x)\n",
2774 fsp->oplock_type,
2775 granted & SMB2_LEASE_READ ? "R":"",
2776 granted & SMB2_LEASE_WRITE ? "W":"",
2777 granted & SMB2_LEASE_HANDLE ? "H":"",
2778 granted,
2779 fsp_str_dbg(fsp),
2780 oplock_request,
2781 requested & SMB2_LEASE_READ ? "R":"",
2782 requested & SMB2_LEASE_WRITE ? "W":"",
2783 requested & SMB2_LEASE_HANDLE ? "H":"",
2784 requested,
2785 state.total_lease_types & SMB2_LEASE_READ ? "R":"",
2786 state.total_lease_types & SMB2_LEASE_WRITE ? "W":"",
2787 state.total_lease_types & SMB2_LEASE_HANDLE ? "H":"",
2788 state.total_lease_types);
2790 *poplock_type = oplock_type;
2791 *pgranted = granted;
2792 return NT_STATUS_OK;
2795 static NTSTATUS handle_share_mode_lease(
2796 files_struct *fsp,
2797 struct share_mode_lock *lck,
2798 uint32_t create_disposition,
2799 uint32_t access_mask,
2800 uint32_t share_access,
2801 int oplock_request,
2802 const struct smb2_lease *lease,
2803 bool first_open_attempt,
2804 int *poplock_type,
2805 uint32_t *pgranted)
2807 bool sharing_violation = false;
2808 NTSTATUS status;
2810 *poplock_type = NO_OPLOCK;
2811 *pgranted = 0;
2813 status = open_mode_check(
2814 fsp->conn, fsp->file_id, lck, access_mask, share_access);
2815 if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
2816 sharing_violation = true;
2817 status = NT_STATUS_OK; /* handled later */
2820 if (!NT_STATUS_IS_OK(status)) {
2821 return status;
2824 if (oplock_request == INTERNAL_OPEN_ONLY) {
2825 if (sharing_violation) {
2826 DBG_DEBUG("Sharing violation for internal open\n");
2827 return NT_STATUS_SHARING_VIOLATION;
2831 * Internal opens never do oplocks or leases. We don't
2832 * need to go through delay_for_oplock().
2834 return NT_STATUS_OK;
2837 status = delay_for_oplock(
2838 fsp,
2839 oplock_request,
2840 lease,
2841 lck,
2842 sharing_violation,
2843 create_disposition,
2844 first_open_attempt,
2845 poplock_type,
2846 pgranted);
2847 if (!NT_STATUS_IS_OK(status)) {
2848 return status;
2851 return NT_STATUS_OK;
2854 static bool request_timed_out(struct smb_request *req, struct timeval timeout)
2856 struct timeval end_time = timeval_sum(&req->request_time, &timeout);
2857 return timeval_expired(&end_time);
2860 struct defer_open_state {
2861 struct smbXsrv_connection *xconn;
2862 uint64_t mid;
2865 static void defer_open_done(struct tevent_req *req);
2868 * Defer an open and watch a locking.tdb record
2870 * This defers an open that gets rescheduled once the locking.tdb record watch
2871 * is triggered by a change to the record.
2873 * It is used to defer opens that triggered an oplock break and for the SMB1
2874 * sharing violation delay.
2876 static void defer_open(struct share_mode_lock *lck,
2877 struct timeval timeout,
2878 struct smb_request *req,
2879 struct file_id id)
2881 struct deferred_open_record *open_rec = NULL;
2882 struct timeval abs_timeout;
2883 struct defer_open_state *watch_state;
2884 struct tevent_req *watch_req;
2885 struct timeval_buf tvbuf1, tvbuf2;
2886 struct file_id_buf fbuf;
2887 bool ok;
2889 abs_timeout = timeval_sum(&req->request_time, &timeout);
2891 DBG_DEBUG("request time [%s] timeout [%s] mid [%" PRIu64 "] "
2892 "file_id [%s]\n",
2893 timeval_str_buf(&req->request_time, false, true, &tvbuf1),
2894 timeval_str_buf(&abs_timeout, false, true, &tvbuf2),
2895 req->mid,
2896 file_id_str_buf(id, &fbuf));
2898 open_rec = talloc_zero(NULL, struct deferred_open_record);
2899 if (open_rec == NULL) {
2900 TALLOC_FREE(lck);
2901 exit_server("talloc failed");
2904 watch_state = talloc(open_rec, struct defer_open_state);
2905 if (watch_state == NULL) {
2906 exit_server("talloc failed");
2908 watch_state->xconn = req->xconn;
2909 watch_state->mid = req->mid;
2911 DBG_DEBUG("deferring mid %" PRIu64 "\n", req->mid);
2913 watch_req = share_mode_watch_send(
2914 watch_state,
2915 req->sconn->ev_ctx,
2916 lck,
2917 (struct server_id){0});
2918 if (watch_req == NULL) {
2919 exit_server("Could not watch share mode record");
2921 tevent_req_set_callback(watch_req, defer_open_done, watch_state);
2923 ok = tevent_req_set_endtime(watch_req, req->sconn->ev_ctx, abs_timeout);
2924 if (!ok) {
2925 exit_server("tevent_req_set_endtime failed");
2928 ok = push_deferred_open_message_smb(req, timeout, id, open_rec);
2929 if (!ok) {
2930 TALLOC_FREE(lck);
2931 exit_server("push_deferred_open_message_smb failed");
2935 static void defer_open_done(struct tevent_req *req)
2937 struct defer_open_state *state = tevent_req_callback_data(
2938 req, struct defer_open_state);
2939 NTSTATUS status;
2940 bool ret;
2942 status = share_mode_watch_recv(req, NULL, NULL);
2943 TALLOC_FREE(req);
2944 if (!NT_STATUS_IS_OK(status)) {
2945 DEBUG(5, ("dbwrap_watched_watch_recv returned %s\n",
2946 nt_errstr(status)));
2948 * Even if it failed, retry anyway. TODO: We need a way to
2949 * tell a re-scheduled open about that error.
2953 DEBUG(10, ("scheduling mid %llu\n", (unsigned long long)state->mid));
2955 ret = schedule_deferred_open_message_smb(state->xconn, state->mid);
2956 SMB_ASSERT(ret);
2957 TALLOC_FREE(state);
2961 * Actually attempt the kernel oplock polling open.
2964 static void poll_open_fn(struct tevent_context *ev,
2965 struct tevent_timer *te,
2966 struct timeval current_time,
2967 void *private_data)
2969 struct deferred_open_record *open_rec = talloc_get_type_abort(
2970 private_data, struct deferred_open_record);
2971 bool ok;
2973 TALLOC_FREE(open_rec->watch_req);
2975 ok = schedule_deferred_open_message_smb(
2976 open_rec->xconn, open_rec->mid);
2977 if (!ok) {
2978 exit_server("schedule_deferred_open_message_smb failed");
2980 DBG_DEBUG("timer fired. Retrying open !\n");
2983 static void poll_open_done(struct tevent_req *subreq);
2985 struct poll_open_setup_watcher_state {
2986 TALLOC_CTX *mem_ctx;
2987 struct tevent_context *ev_ctx;
2988 struct tevent_req *watch_req;
2991 static void poll_open_setup_watcher_fn(struct share_mode_lock *lck,
2992 void *private_data)
2994 struct poll_open_setup_watcher_state *state =
2995 (struct poll_open_setup_watcher_state *)private_data;
2997 if (!validate_oplock_types(lck)) {
2998 smb_panic("validate_oplock_types failed");
3001 state->watch_req = share_mode_watch_send(
3002 state->mem_ctx,
3003 state->ev_ctx,
3004 lck,
3005 (struct server_id) {0});
3006 if (state->watch_req == NULL) {
3007 DBG_WARNING("share_mode_watch_send failed\n");
3008 return;
3013 * Reschedule an open for 1 second from now, if not timed out.
3015 static bool setup_poll_open(
3016 struct smb_request *req,
3017 const struct file_id *id,
3018 struct timeval max_timeout,
3019 struct timeval interval)
3021 static struct file_id zero_id = {};
3022 bool ok;
3023 struct deferred_open_record *open_rec = NULL;
3024 struct timeval endtime, next_interval;
3025 struct file_id_buf ftmp;
3027 if (request_timed_out(req, max_timeout)) {
3028 return false;
3031 open_rec = talloc_zero(NULL, struct deferred_open_record);
3032 if (open_rec == NULL) {
3033 DBG_WARNING("talloc failed\n");
3034 return false;
3036 open_rec->xconn = req->xconn;
3037 open_rec->mid = req->mid;
3040 * Make sure open_rec->te does not come later than the
3041 * request's maximum endtime.
3044 endtime = timeval_sum(&req->request_time, &max_timeout);
3045 next_interval = timeval_current_ofs(interval.tv_sec, interval.tv_usec);
3046 next_interval = timeval_min(&endtime, &next_interval);
3048 open_rec->te = tevent_add_timer(
3049 req->sconn->ev_ctx,
3050 open_rec,
3051 next_interval,
3052 poll_open_fn,
3053 open_rec);
3054 if (open_rec->te == NULL) {
3055 DBG_WARNING("tevent_add_timer failed\n");
3056 TALLOC_FREE(open_rec);
3057 return false;
3060 if (id != NULL) {
3061 struct poll_open_setup_watcher_state wstate = {
3062 .mem_ctx = open_rec,
3063 .ev_ctx = req->sconn->ev_ctx,
3065 NTSTATUS status;
3067 status = share_mode_do_locked_vfs_denied(*id,
3068 poll_open_setup_watcher_fn,
3069 &wstate);
3070 if (NT_STATUS_IS_OK(status)) {
3071 if (wstate.watch_req == NULL) {
3072 DBG_WARNING("share_mode_watch_send failed\n");
3073 TALLOC_FREE(open_rec);
3074 return false;
3076 open_rec->watch_req = wstate.watch_req;
3077 tevent_req_set_callback(open_rec->watch_req,
3078 poll_open_done,
3079 open_rec);
3080 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
3081 DBG_WARNING("share_mode_do_locked_vfs_denied failed - %s\n",
3082 nt_errstr(status));
3083 TALLOC_FREE(open_rec);
3084 return false;
3086 } else {
3087 id = &zero_id;
3090 ok = push_deferred_open_message_smb(req, max_timeout, *id, open_rec);
3091 if (!ok) {
3092 DBG_WARNING("push_deferred_open_message_smb failed\n");
3093 TALLOC_FREE(open_rec);
3094 return false;
3097 DBG_DEBUG("poll request time [%s] mid [%" PRIu64 "] file_id [%s]\n",
3098 timeval_string(talloc_tos(), &req->request_time, false),
3099 req->mid,
3100 file_id_str_buf(*id, &ftmp));
3102 return true;
3105 static void poll_open_done(struct tevent_req *subreq)
3107 struct deferred_open_record *open_rec = tevent_req_callback_data(
3108 subreq, struct deferred_open_record);
3109 NTSTATUS status;
3110 bool ok;
3112 status = share_mode_watch_recv(subreq, NULL, NULL);
3113 TALLOC_FREE(subreq);
3114 open_rec->watch_req = NULL;
3115 TALLOC_FREE(open_rec->te);
3117 DBG_DEBUG("dbwrap_watched_watch_recv returned %s\n",
3118 nt_errstr(status));
3120 ok = schedule_deferred_open_message_smb(
3121 open_rec->xconn, open_rec->mid);
3122 if (!ok) {
3123 exit_server("schedule_deferred_open_message_smb failed");
3127 bool defer_smb1_sharing_violation(struct smb_request *req)
3129 bool ok;
3130 int timeout_usecs;
3132 if (!lp_defer_sharing_violations()) {
3133 return false;
3137 * Try every 200msec up to (by default) one second. To be
3138 * precise, according to behaviour note <247> in [MS-CIFS],
3139 * the server tries 5 times. But up to one second should be
3140 * close enough.
3143 timeout_usecs = lp_parm_int(
3144 SNUM(req->conn),
3145 "smbd",
3146 "sharedelay",
3147 SHARING_VIOLATION_USEC_WAIT);
3149 ok = setup_poll_open(
3150 req,
3151 NULL,
3152 (struct timeval) { .tv_usec = timeout_usecs },
3153 (struct timeval) { .tv_usec = 200000 });
3154 return ok;
3157 /****************************************************************************
3158 On overwrite open ensure that the attributes match.
3159 ****************************************************************************/
3161 static bool open_match_attributes(connection_struct *conn,
3162 uint32_t old_dos_attr,
3163 uint32_t new_dos_attr,
3164 mode_t new_unx_mode,
3165 mode_t *returned_unx_mode)
3167 uint32_t noarch_old_dos_attr, noarch_new_dos_attr;
3169 noarch_old_dos_attr = (old_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
3170 noarch_new_dos_attr = (new_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
3172 if((noarch_old_dos_attr == 0 && noarch_new_dos_attr != 0) ||
3173 (noarch_old_dos_attr != 0 && ((noarch_old_dos_attr & noarch_new_dos_attr) == noarch_old_dos_attr))) {
3174 *returned_unx_mode = new_unx_mode;
3175 } else {
3176 *returned_unx_mode = (mode_t)0;
3179 DEBUG(10,("open_match_attributes: old_dos_attr = 0x%x, "
3180 "new_dos_attr = 0x%x "
3181 "returned_unx_mode = 0%o\n",
3182 (unsigned int)old_dos_attr,
3183 (unsigned int)new_dos_attr,
3184 (unsigned int)*returned_unx_mode ));
3186 /* If we're mapping SYSTEM and HIDDEN ensure they match. */
3187 if (lp_map_system(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
3188 if ((old_dos_attr & FILE_ATTRIBUTE_SYSTEM) &&
3189 !(new_dos_attr & FILE_ATTRIBUTE_SYSTEM)) {
3190 return False;
3193 if (lp_map_hidden(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
3194 if ((old_dos_attr & FILE_ATTRIBUTE_HIDDEN) &&
3195 !(new_dos_attr & FILE_ATTRIBUTE_HIDDEN)) {
3196 return False;
3199 return True;
3202 static void schedule_defer_open(struct share_mode_lock *lck,
3203 struct file_id id,
3204 struct smb_request *req)
3206 /* This is a relative time, added to the absolute
3207 request_time value to get the absolute timeout time.
3208 Note that if this is the second or greater time we enter
3209 this codepath for this particular request mid then
3210 request_time is left as the absolute time of the *first*
3211 time this request mid was processed. This is what allows
3212 the request to eventually time out. */
3214 struct timeval timeout;
3216 /* Normally the smbd we asked should respond within
3217 * OPLOCK_BREAK_TIMEOUT seconds regardless of whether
3218 * the client did, give twice the timeout as a safety
3219 * measure here in case the other smbd is stuck
3220 * somewhere else. */
3222 timeout = tevent_timeval_set(OPLOCK_BREAK_TIMEOUT * 2, 0);
3224 if (request_timed_out(req, timeout)) {
3225 return;
3228 defer_open(lck, timeout, req, id);
3231 /****************************************************************************
3232 Reschedule an open call that went asynchronous.
3233 ****************************************************************************/
3235 static void schedule_async_open_timer(struct tevent_context *ev,
3236 struct tevent_timer *te,
3237 struct timeval current_time,
3238 void *private_data)
3240 exit_server("async open timeout");
3243 static void schedule_async_open(struct smb_request *req)
3245 struct deferred_open_record *open_rec = NULL;
3246 struct timeval timeout = tevent_timeval_set(20, 0);
3247 bool ok;
3249 if (request_timed_out(req, timeout)) {
3250 return;
3253 open_rec = talloc_zero(NULL, struct deferred_open_record);
3254 if (open_rec == NULL) {
3255 exit_server("deferred_open_record_create failed");
3257 open_rec->async_open = true;
3259 ok = push_deferred_open_message_smb(
3260 req, timeout, (struct file_id){0}, open_rec);
3261 if (!ok) {
3262 exit_server("push_deferred_open_message_smb failed");
3265 open_rec->te = tevent_add_timer(req->sconn->ev_ctx,
3266 req,
3267 timeval_current_ofs(20, 0),
3268 schedule_async_open_timer,
3269 open_rec);
3270 if (open_rec->te == NULL) {
3271 exit_server("tevent_add_timer failed");
3275 static NTSTATUS check_and_store_share_mode(
3276 struct files_struct *fsp,
3277 struct smb_request *req,
3278 struct share_mode_lock *lck,
3279 uint32_t create_disposition,
3280 uint32_t access_mask,
3281 uint32_t share_access,
3282 int oplock_request,
3283 const struct smb2_lease *lease,
3284 bool first_open_attempt)
3286 NTSTATUS status;
3287 int oplock_type = NO_OPLOCK;
3288 uint32_t granted_lease = 0;
3289 const struct smb2_lease_key *lease_key = NULL;
3290 bool delete_on_close;
3291 bool ok;
3293 /* Get the types we need to examine. */
3294 if (!validate_oplock_types(lck)) {
3295 smb_panic("validate_oplock_types failed");
3298 delete_on_close = has_delete_on_close(lck, fsp->name_hash);
3299 if (delete_on_close) {
3300 return NT_STATUS_DELETE_PENDING;
3303 status = handle_share_mode_lease(fsp,
3304 lck,
3305 create_disposition,
3306 access_mask,
3307 share_access,
3308 oplock_request,
3309 lease,
3310 first_open_attempt,
3311 &oplock_type,
3312 &granted_lease);
3313 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
3314 schedule_defer_open(lck, fsp->file_id, req);
3315 return NT_STATUS_SHARING_VIOLATION;
3317 if (!NT_STATUS_IS_OK(status)) {
3318 return status;
3321 if (oplock_type == LEASE_OPLOCK) {
3322 lease_key = &lease->lease_key;
3325 share_mode_flags_restrict(lck, access_mask, share_access, 0);
3327 ok = set_share_mode(lck,
3328 fsp,
3329 get_current_uid(fsp->conn),
3330 req ? req->mid : 0,
3331 oplock_type,
3332 lease_key,
3333 share_access,
3334 access_mask);
3335 if (!ok) {
3336 return NT_STATUS_NO_MEMORY;
3339 if (oplock_type == LEASE_OPLOCK) {
3340 status = grant_fsp_lease(fsp, lck, lease, granted_lease);
3341 if (!NT_STATUS_IS_OK(status)) {
3342 del_share_mode(lck, fsp);
3343 return status;
3346 DBG_DEBUG("lease_state=%d\n", fsp->lease->lease.lease_state);
3349 fsp->oplock_type = oplock_type;
3351 return NT_STATUS_OK;
3354 /****************************************************************************
3355 Work out what access_mask to use from what the client sent us.
3356 ****************************************************************************/
3358 static NTSTATUS smbd_calculate_maximum_allowed_access_fsp(
3359 struct files_struct *dirfsp,
3360 struct files_struct *fsp,
3361 bool use_privs,
3362 uint32_t *p_access_mask)
3364 struct security_descriptor *sd = NULL;
3365 uint32_t access_granted = 0;
3366 uint32_t dosattrs;
3367 NTSTATUS status;
3369 /* Cope with symlinks */
3370 if (fsp == NULL || fsp_get_pathref_fd(fsp) == -1) {
3371 *p_access_mask = FILE_GENERIC_ALL;
3372 return NT_STATUS_OK;
3375 /* Cope with fake/printer fsp's. */
3376 if (fsp->fake_file_handle != NULL || fsp->print_file != NULL) {
3377 *p_access_mask = FILE_GENERIC_ALL;
3378 return NT_STATUS_OK;
3381 if (!use_privs && (get_current_uid(fsp->conn) == (uid_t)0)) {
3382 *p_access_mask |= FILE_GENERIC_ALL;
3383 return NT_STATUS_OK;
3386 status = SMB_VFS_FGET_NT_ACL(metadata_fsp(fsp),
3387 (SECINFO_OWNER |
3388 SECINFO_GROUP |
3389 SECINFO_DACL),
3390 talloc_tos(),
3391 &sd);
3393 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
3395 * File did not exist
3397 *p_access_mask = FILE_GENERIC_ALL;
3398 return NT_STATUS_OK;
3400 if (!NT_STATUS_IS_OK(status)) {
3401 DBG_ERR("Could not get acl on file %s: %s\n",
3402 fsp_str_dbg(fsp),
3403 nt_errstr(status));
3404 return status;
3408 * If we can access the path to this file, by
3409 * default we have FILE_READ_ATTRIBUTES from the
3410 * containing directory. See the section:
3411 * "Algorithm to Check Access to an Existing File"
3412 * in MS-FSA.pdf.
3414 * se_file_access_check()
3415 * also takes care of owner WRITE_DAC and READ_CONTROL.
3417 status = se_file_access_check(sd,
3418 get_current_nttok(fsp->conn),
3419 use_privs,
3420 (*p_access_mask & ~FILE_READ_ATTRIBUTES),
3421 &access_granted);
3423 TALLOC_FREE(sd);
3425 if (!NT_STATUS_IS_OK(status)) {
3426 DBG_ERR("Status %s on file %s: "
3427 "when calculating maximum access\n",
3428 nt_errstr(status),
3429 fsp_str_dbg(fsp));
3430 return status;
3433 *p_access_mask = (access_granted | FILE_READ_ATTRIBUTES);
3435 if (!(access_granted & DELETE_ACCESS)) {
3436 if (can_delete_file_in_directory(fsp->conn,
3437 dirfsp,
3438 fsp->fsp_name)) {
3439 *p_access_mask |= DELETE_ACCESS;
3443 dosattrs = fdos_mode(fsp);
3444 if ((dosattrs & FILE_ATTRIBUTE_READONLY) || !CAN_WRITE(fsp->conn)) {
3445 *p_access_mask &= ~(FILE_GENERIC_WRITE | DELETE_ACCESS);
3448 return NT_STATUS_OK;
3451 NTSTATUS smbd_calculate_access_mask_fsp(struct files_struct *dirfsp,
3452 struct files_struct *fsp,
3453 bool use_privs,
3454 uint32_t access_mask,
3455 uint32_t *access_mask_out)
3457 NTSTATUS status;
3458 uint32_t orig_access_mask = access_mask;
3459 uint32_t rejected_share_access;
3461 if (access_mask & SEC_MASK_INVALID) {
3462 DBG_DEBUG("access_mask [%8x] contains invalid bits\n",
3463 access_mask);
3464 return NT_STATUS_ACCESS_DENIED;
3468 * Convert GENERIC bits to specific bits.
3471 se_map_generic(&access_mask, &file_generic_mapping);
3473 /* Calculate MAXIMUM_ALLOWED_ACCESS if requested. */
3474 if (access_mask & MAXIMUM_ALLOWED_ACCESS) {
3476 status = smbd_calculate_maximum_allowed_access_fsp(
3477 dirfsp,
3478 fsp,
3479 use_privs,
3480 &access_mask);
3482 if (!NT_STATUS_IS_OK(status)) {
3483 return status;
3486 access_mask &= fsp->conn->share_access;
3489 rejected_share_access = access_mask & ~(fsp->conn->share_access);
3491 if (rejected_share_access) {
3492 DBG_INFO("Access denied on file %s: "
3493 "rejected by share access mask[0x%08X] "
3494 "orig[0x%08X] mapped[0x%08X] reject[0x%08X]\n",
3495 fsp_str_dbg(fsp),
3496 fsp->conn->share_access,
3497 orig_access_mask, access_mask,
3498 rejected_share_access);
3499 return NT_STATUS_ACCESS_DENIED;
3502 *access_mask_out = access_mask;
3503 return NT_STATUS_OK;
3506 /****************************************************************************
3507 Remove the deferred open entry under lock.
3508 ****************************************************************************/
3510 /****************************************************************************
3511 Return true if this is a state pointer to an asynchronous create.
3512 ****************************************************************************/
3514 bool is_deferred_open_async(const struct deferred_open_record *rec)
3516 return rec->async_open;
3519 static bool clear_ads(uint32_t create_disposition)
3521 bool ret = false;
3523 switch (create_disposition) {
3524 case FILE_SUPERSEDE:
3525 case FILE_OVERWRITE_IF:
3526 case FILE_OVERWRITE:
3527 ret = true;
3528 break;
3529 default:
3530 break;
3532 return ret;
3535 static int disposition_to_open_flags(uint32_t create_disposition)
3537 int ret = 0;
3540 * Currently we're using FILE_SUPERSEDE as the same as
3541 * FILE_OVERWRITE_IF but they really are
3542 * different. FILE_SUPERSEDE deletes an existing file
3543 * (requiring delete access) then recreates it.
3546 switch (create_disposition) {
3547 case FILE_SUPERSEDE:
3548 case FILE_OVERWRITE_IF:
3550 * If file exists replace/overwrite. If file doesn't
3551 * exist create.
3553 ret = O_CREAT|O_TRUNC;
3554 break;
3556 case FILE_OPEN:
3558 * If file exists open. If file doesn't exist error.
3560 ret = 0;
3561 break;
3563 case FILE_OVERWRITE:
3565 * If file exists overwrite. If file doesn't exist
3566 * error.
3568 ret = O_TRUNC;
3569 break;
3571 case FILE_CREATE:
3573 * If file exists error. If file doesn't exist create.
3575 ret = O_CREAT|O_EXCL;
3576 break;
3578 case FILE_OPEN_IF:
3580 * If file exists open. If file doesn't exist create.
3582 ret = O_CREAT;
3583 break;
3585 return ret;
3588 static int calculate_open_access_flags(uint32_t access_mask,
3589 uint32_t private_flags,
3590 NTTIME twrp)
3592 bool need_write, need_read;
3595 * Note that we ignore the append flag as append does not
3596 * mean the same thing under DOS and Unix.
3599 if (twrp != 0) {
3601 * Pave over the user requested mode and force O_RDONLY for the
3602 * file handle. Windows allows opening a VSS file with O_RDWR,
3603 * even though actual writes on the handle will fail.
3605 return O_RDONLY;
3608 need_write = (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA));
3609 if (!need_write) {
3610 return O_RDONLY;
3613 /* DENY_DOS opens are always underlying read-write on the
3614 file handle, no matter what the requested access mask
3615 says. */
3617 need_read =
3618 ((private_flags & NTCREATEX_FLAG_DENY_DOS) ||
3619 access_mask & (FILE_READ_ATTRIBUTES|FILE_READ_DATA|
3620 FILE_READ_EA|FILE_EXECUTE));
3622 if (!need_read) {
3623 return O_WRONLY;
3625 return O_RDWR;
3628 struct open_ntcreate_lock_state {
3629 struct share_mode_entry_prepare_state prepare_state;
3630 struct files_struct *fsp;
3631 const char *object_type;
3632 struct smb_request *req;
3633 uint32_t create_disposition;
3634 uint32_t access_mask;
3635 uint32_t share_access;
3636 int oplock_request;
3637 const struct smb2_lease *lease;
3638 bool first_open_attempt;
3639 bool keep_locked;
3640 NTSTATUS status;
3641 struct timespec write_time;
3642 share_mode_entry_prepare_unlock_fn_t cleanup_fn;
3645 static void open_ntcreate_lock_add_entry(struct share_mode_lock *lck,
3646 bool *keep_locked,
3647 void *private_data)
3649 struct open_ntcreate_lock_state *state =
3650 (struct open_ntcreate_lock_state *)private_data;
3653 * By default drop the g_lock again if we leave the
3654 * tdb chainlock.
3656 *keep_locked = false;
3658 state->status = check_and_store_share_mode(state->fsp,
3659 state->req,
3660 lck,
3661 state->create_disposition,
3662 state->access_mask,
3663 state->share_access,
3664 state->oplock_request,
3665 state->lease,
3666 state->first_open_attempt);
3667 if (!NT_STATUS_IS_OK(state->status)) {
3668 return;
3671 state->write_time = get_share_mode_write_time(lck);
3674 * keep the g_lock while existing the tdb chainlock,
3675 * we we're asked to, which mean we'll keep
3676 * the share_mode_lock during object creation,
3677 * or setting delete on close.
3679 *keep_locked = state->keep_locked;
3682 static void open_ntcreate_lock_cleanup_oplock(struct share_mode_lock *lck,
3683 void *private_data)
3685 struct open_ntcreate_lock_state *state =
3686 (struct open_ntcreate_lock_state *)private_data;
3687 bool ok;
3689 ok = remove_share_oplock(lck, state->fsp);
3690 if (!ok) {
3691 DBG_ERR("Could not remove oplock for %s %s\n",
3692 state->object_type, fsp_str_dbg(state->fsp));
3696 static void open_ntcreate_lock_cleanup_entry(struct share_mode_lock *lck,
3697 void *private_data)
3699 struct open_ntcreate_lock_state *state =
3700 (struct open_ntcreate_lock_state *)private_data;
3701 bool ok;
3703 ok = del_share_mode(lck, state->fsp);
3704 if (!ok) {
3705 DBG_ERR("Could not delete share entry for %s %s\n",
3706 state->object_type, fsp_str_dbg(state->fsp));
3710 static void possibly_set_archive(struct connection_struct *conn,
3711 struct files_struct *fsp,
3712 struct smb_filename *smb_fname,
3713 struct smb_filename *parent_dir_fname,
3714 int info,
3715 uint32_t dosattrs,
3716 mode_t *unx_mode)
3718 bool set_archive = false;
3719 int ret;
3721 if (info == FILE_WAS_OPENED) {
3722 return;
3725 /* Overwritten files should be initially set as archive */
3726 if ((info == FILE_WAS_OVERWRITTEN && lp_map_archive(SNUM(conn)))) {
3727 set_archive = true;
3728 } else if (lp_store_dos_attributes(SNUM(conn))) {
3729 set_archive = true;
3731 if (!set_archive) {
3732 return;
3735 ret = file_set_dosmode(conn,
3736 smb_fname,
3737 dosattrs | FILE_ATTRIBUTE_ARCHIVE,
3738 parent_dir_fname,
3739 true);
3740 if (ret != 0) {
3741 return;
3743 *unx_mode = smb_fname->st.st_ex_mode;
3746 /****************************************************************************
3747 Open a file with a share mode. Passed in an already created files_struct *.
3748 ****************************************************************************/
3750 static NTSTATUS open_file_ntcreate(connection_struct *conn,
3751 struct smb_request *req,
3752 uint32_t access_mask, /* access bits (FILE_READ_DATA etc.) */
3753 uint32_t share_access, /* share constants (FILE_SHARE_READ etc) */
3754 uint32_t create_disposition, /* FILE_OPEN_IF etc. */
3755 uint32_t create_options, /* options such as delete on close. */
3756 uint32_t new_dos_attributes, /* attributes used for new file. */
3757 int oplock_request, /* internal Samba oplock codes. */
3758 const struct smb2_lease *lease,
3759 /* Information (FILE_EXISTS etc.) */
3760 uint32_t private_flags, /* Samba specific flags. */
3761 struct smb_filename *parent_dir_fname, /* parent. */
3762 struct smb_filename *smb_fname_atname, /* atname relative to parent. */
3763 int *pinfo,
3764 files_struct *fsp)
3766 struct smb_filename *smb_fname = fsp->fsp_name;
3767 int flags=0;
3768 bool file_existed = VALID_STAT(smb_fname->st);
3769 bool def_acl = False;
3770 bool posix_open = False;
3771 bool new_file_created = False;
3772 bool first_open_attempt = true;
3773 bool is_twrp = (smb_fname_atname->twrp != 0);
3774 NTSTATUS fsp_open = NT_STATUS_ACCESS_DENIED;
3775 mode_t new_unx_mode = (mode_t)0;
3776 mode_t unx_mode = (mode_t)0;
3777 int info;
3778 uint32_t existing_dos_attributes = 0;
3779 struct open_ntcreate_lock_state lck_state = {};
3780 bool keep_locked = false;
3781 uint32_t open_access_mask = access_mask;
3782 NTSTATUS status;
3783 SMB_STRUCT_STAT saved_stat = smb_fname->st;
3784 struct timespec old_write_time;
3785 bool setup_poll = false;
3786 NTSTATUS ulstatus;
3788 if (conn->printer) {
3790 * Printers are handled completely differently.
3791 * Most of the passed parameters are ignored.
3794 if (pinfo) {
3795 *pinfo = FILE_WAS_CREATED;
3798 DBG_DEBUG("printer open fname=%s\n",
3799 smb_fname_str_dbg(smb_fname));
3801 if (!req) {
3802 DBG_ERR("printer open without an SMB request!\n");
3803 return NT_STATUS_INTERNAL_ERROR;
3806 return print_spool_open(fsp, smb_fname->base_name,
3807 req->vuid);
3810 if (new_dos_attributes & FILE_FLAG_POSIX_SEMANTICS) {
3811 posix_open = True;
3812 unx_mode = (mode_t)(new_dos_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
3813 new_dos_attributes = 0;
3814 } else {
3815 /* Windows allows a new file to be created and
3816 silently removes a FILE_ATTRIBUTE_DIRECTORY
3817 sent by the client. Do the same. */
3819 new_dos_attributes &= ~FILE_ATTRIBUTE_DIRECTORY;
3821 /* We add FILE_ATTRIBUTE_ARCHIVE to this as this mode is only used if the file is
3822 * created new. */
3823 unx_mode = unix_mode(
3824 conn,
3825 new_dos_attributes | FILE_ATTRIBUTE_ARCHIVE,
3826 smb_fname,
3827 parent_dir_fname->fsp);
3830 DEBUG(10, ("open_file_ntcreate: fname=%s, dos_attrs=0x%x "
3831 "access_mask=0x%x share_access=0x%x "
3832 "create_disposition = 0x%x create_options=0x%x "
3833 "unix mode=0%o oplock_request=%d private_flags = 0x%x\n",
3834 smb_fname_str_dbg(smb_fname), new_dos_attributes,
3835 access_mask, share_access, create_disposition,
3836 create_options, (unsigned int)unx_mode, oplock_request,
3837 (unsigned int)private_flags));
3839 if (req == NULL) {
3840 /* Ensure req == NULL means INTERNAL_OPEN_ONLY */
3841 SMB_ASSERT(oplock_request == INTERNAL_OPEN_ONLY);
3842 } else {
3843 /* And req != NULL means no INTERNAL_OPEN_ONLY */
3844 SMB_ASSERT(((oplock_request & INTERNAL_OPEN_ONLY) == 0));
3848 * Only non-internal opens can be deferred at all
3851 if (req) {
3852 struct deferred_open_record *open_rec;
3853 if (get_deferred_open_message_state(req, NULL, &open_rec)) {
3855 /* If it was an async create retry, the file
3856 didn't exist. */
3858 if (is_deferred_open_async(open_rec)) {
3859 SET_STAT_INVALID(smb_fname->st);
3860 file_existed = false;
3863 /* Ensure we don't reprocess this message. */
3864 remove_deferred_open_message_smb(req->xconn, req->mid);
3866 first_open_attempt = false;
3870 if (!posix_open) {
3871 new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
3872 if (file_existed) {
3874 * Only use stored DOS attributes for checks
3875 * against requested attributes (below via
3876 * open_match_attributes()), cf bug #11992
3877 * for details. -slow
3879 uint32_t attr = 0;
3881 status = SMB_VFS_FGET_DOS_ATTRIBUTES(
3882 conn,
3883 metadata_fsp(smb_fname->fsp),
3884 &attr);
3885 if (NT_STATUS_IS_OK(status)) {
3886 existing_dos_attributes = attr;
3891 /* ignore any oplock requests if oplocks are disabled */
3892 if (!lp_oplocks(SNUM(conn)) ||
3893 IS_VETO_OPLOCK_PATH(conn, smb_fname->base_name)) {
3894 /* Mask off everything except the private Samba bits. */
3895 oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
3898 /* this is for OS/2 long file names - say we don't support them */
3899 if (req != NULL && !req->posix_pathnames &&
3900 strstr(smb_fname->base_name,".+,;=[].")) {
3901 /* OS/2 Workplace shell fix may be main code stream in a later
3902 * release. */
3903 DEBUG(5,("open_file_ntcreate: OS/2 long filenames are not "
3904 "supported.\n"));
3905 if (use_nt_status()) {
3906 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3908 return NT_STATUS_DOS(ERRDOS, ERRcannotopen);
3911 switch( create_disposition ) {
3912 case FILE_OPEN:
3913 /* If file exists open. If file doesn't exist error. */
3914 if (!file_existed) {
3915 DEBUG(5,("open_file_ntcreate: FILE_OPEN "
3916 "requested for file %s and file "
3917 "doesn't exist.\n",
3918 smb_fname_str_dbg(smb_fname)));
3919 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3921 break;
3923 case FILE_OVERWRITE:
3924 /* If file exists overwrite. If file doesn't exist
3925 * error. */
3926 if (!file_existed) {
3927 DEBUG(5,("open_file_ntcreate: FILE_OVERWRITE "
3928 "requested for file %s and file "
3929 "doesn't exist.\n",
3930 smb_fname_str_dbg(smb_fname) ));
3931 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3933 if (is_twrp) {
3934 return NT_STATUS_MEDIA_WRITE_PROTECTED;
3936 break;
3938 case FILE_CREATE:
3939 /* If file exists error. If file doesn't exist
3940 * create. */
3941 if (file_existed) {
3942 DEBUG(5,("open_file_ntcreate: FILE_CREATE "
3943 "requested for file %s and file "
3944 "already exists.\n",
3945 smb_fname_str_dbg(smb_fname)));
3946 if (S_ISDIR(smb_fname->st.st_ex_mode)) {
3947 return NT_STATUS_FILE_IS_A_DIRECTORY;
3949 return NT_STATUS_OBJECT_NAME_COLLISION;
3951 if (is_twrp) {
3952 return NT_STATUS_MEDIA_WRITE_PROTECTED;
3954 break;
3956 case FILE_SUPERSEDE:
3957 case FILE_OVERWRITE_IF:
3958 if (is_twrp) {
3959 return NT_STATUS_MEDIA_WRITE_PROTECTED;
3961 break;
3962 case FILE_OPEN_IF:
3963 if (is_twrp) {
3964 if (!file_existed) {
3965 return NT_STATUS_MEDIA_WRITE_PROTECTED;
3967 create_disposition = FILE_OPEN;
3969 break;
3970 default:
3971 return NT_STATUS_INVALID_PARAMETER;
3974 flags = disposition_to_open_flags(create_disposition);
3976 /* We only care about matching attributes on file exists and
3977 * overwrite. */
3979 if (!posix_open && file_existed &&
3980 ((create_disposition == FILE_OVERWRITE) ||
3981 (create_disposition == FILE_OVERWRITE_IF))) {
3982 if (!open_match_attributes(conn, existing_dos_attributes,
3983 new_dos_attributes,
3984 unx_mode, &new_unx_mode)) {
3985 DEBUG(5,("open_file_ntcreate: attributes mismatch "
3986 "for file %s (%x %x) (0%o, 0%o)\n",
3987 smb_fname_str_dbg(smb_fname),
3988 existing_dos_attributes,
3989 new_dos_attributes,
3990 (unsigned int)smb_fname->st.st_ex_mode,
3991 (unsigned int)unx_mode ));
3992 return NT_STATUS_ACCESS_DENIED;
3996 status = smbd_calculate_access_mask_fsp(parent_dir_fname->fsp,
3997 smb_fname->fsp,
3998 false,
3999 access_mask,
4000 &access_mask);
4001 if (!NT_STATUS_IS_OK(status)) {
4002 DBG_DEBUG("smbd_calculate_access_mask_fsp "
4003 "on file %s returned %s\n",
4004 smb_fname_str_dbg(smb_fname),
4005 nt_errstr(status));
4006 return status;
4009 open_access_mask = access_mask;
4011 if (flags & O_TRUNC) {
4012 open_access_mask |= FILE_WRITE_DATA; /* This will cause oplock breaks. */
4015 if (file_existed) {
4017 * stat opens on existing files don't get oplocks.
4018 * They can get leases.
4020 * Note that we check for stat open on the *open_access_mask*,
4021 * i.e. the access mask we actually used to do the open,
4022 * not the one the client asked for (which is in
4023 * fsp->access_mask). This is due to the fact that
4024 * FILE_OVERWRITE and FILE_OVERWRITE_IF add in O_TRUNC,
4025 * which adds FILE_WRITE_DATA to open_access_mask.
4027 if (is_oplock_stat_open(open_access_mask) && lease == NULL) {
4028 oplock_request = NO_OPLOCK;
4032 DEBUG(10, ("open_file_ntcreate: fname=%s, after mapping "
4033 "access_mask=0x%x\n", smb_fname_str_dbg(smb_fname),
4034 access_mask));
4037 * Note that we ignore the append flag as append does not
4038 * mean the same thing under DOS and Unix.
4041 flags |= calculate_open_access_flags(access_mask,
4042 private_flags,
4043 smb_fname->twrp);
4046 * Currently we only look at FILE_WRITE_THROUGH for create options.
4049 #if defined(O_SYNC)
4050 if ((create_options & FILE_WRITE_THROUGH) && lp_strict_sync(SNUM(conn))) {
4051 flags |= O_SYNC;
4053 #endif /* O_SYNC */
4055 if (posix_open && (access_mask & FILE_APPEND_DATA)) {
4056 flags |= O_APPEND;
4059 if (!posix_open && !CAN_WRITE(conn)) {
4061 * We should really return a permission denied error if either
4062 * O_CREAT or O_TRUNC are set, but for compatibility with
4063 * older versions of Samba we just AND them out.
4065 flags &= ~(O_CREAT | O_TRUNC);
4069 * With kernel oplocks the open breaking an oplock
4070 * blocks until the oplock holder has given up the
4071 * oplock or closed the file. We prevent this by always
4072 * trying to open the file with O_NONBLOCK (see "man
4073 * fcntl" on Linux).
4075 * If a process that doesn't use the smbd open files
4076 * database or communication methods holds a kernel
4077 * oplock we must periodically poll for available open
4078 * using O_NONBLOCK.
4080 flags |= O_NONBLOCK;
4083 * Ensure we can't write on a read-only share or file.
4086 if (((flags & O_ACCMODE) != O_RDONLY) && file_existed &&
4087 (!CAN_WRITE(conn) ||
4088 (existing_dos_attributes & FILE_ATTRIBUTE_READONLY))) {
4089 DEBUG(5,("open_file_ntcreate: write access requested for "
4090 "file %s on read only %s\n",
4091 smb_fname_str_dbg(smb_fname),
4092 !CAN_WRITE(conn) ? "share" : "file" ));
4093 return NT_STATUS_ACCESS_DENIED;
4096 if (VALID_STAT(smb_fname->st)) {
4098 * Only try and create a file id before open
4099 * for an existing file. For a file being created
4100 * this won't do anything useful until the file
4101 * exists and has a valid stat struct.
4103 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
4105 fh_set_private_options(fsp->fh, private_flags);
4106 fsp->access_mask = open_access_mask; /* We change this to the
4107 * requested access_mask after
4108 * the open is done. */
4109 if (posix_open) {
4110 fsp->posix_flags |= FSP_POSIX_FLAGS_ALL;
4113 if ((create_options & FILE_DELETE_ON_CLOSE) && (flags & O_CREAT) &&
4114 !file_existed) {
4115 /* Delete on close semantics for new files. */
4116 status = can_set_delete_on_close(fsp,
4117 new_dos_attributes);
4118 if (!NT_STATUS_IS_OK(status)) {
4119 fd_close(fsp);
4120 return status;
4125 * Ensure we pay attention to default ACLs on directories if required.
4128 if ((flags & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
4129 (def_acl = directory_has_default_acl_fsp(parent_dir_fname->fsp))) {
4130 unx_mode = (0777 & lp_create_mask(SNUM(conn)));
4133 DEBUG(4,
4134 ("calling open_file with flags=0x%X mode=0%o, "
4135 "access_mask = 0x%x, open_access_mask = 0x%x\n",
4136 (unsigned int)flags,
4137 (unsigned int)unx_mode,
4138 (unsigned int)access_mask,
4139 (unsigned int)open_access_mask));
4142 struct vfs_open_how how = {
4143 .flags = flags,
4144 .mode = unx_mode,
4147 if (create_options & FILE_OPEN_FOR_BACKUP_INTENT) {
4148 how.resolve |= VFS_OPEN_HOW_WITH_BACKUP_INTENT;
4151 fsp_open = open_file(req,
4152 parent_dir_fname->fsp,
4153 smb_fname_atname,
4154 fsp,
4155 &how,
4156 access_mask,
4157 open_access_mask,
4158 private_flags,
4159 &new_file_created);
4161 if (NT_STATUS_EQUAL(fsp_open, NT_STATUS_NETWORK_BUSY)) {
4162 if (file_existed && S_ISFIFO(fsp->fsp_name->st.st_ex_mode)) {
4163 DEBUG(10, ("FIFO busy\n"));
4164 return NT_STATUS_NETWORK_BUSY;
4166 if (req == NULL) {
4167 DEBUG(10, ("Internal open busy\n"));
4168 return NT_STATUS_NETWORK_BUSY;
4171 * This handles the kernel oplock case:
4173 * the file has an active kernel oplock and the open() returned
4174 * EWOULDBLOCK/EAGAIN which maps to NETWORK_BUSY.
4176 * "Samba locking.tdb oplocks" are handled below after acquiring
4177 * the sharemode lock with get_share_mode_lock().
4179 setup_poll = true;
4182 if (NT_STATUS_EQUAL(fsp_open, NT_STATUS_RETRY)) {
4184 * EINTR from the open(2) syscall. Just setup a retry
4185 * in a bit. We can't use the sys_write() tight retry
4186 * loop here, as we might have to actually deal with
4187 * lease-break signals to avoid a deadlock.
4189 setup_poll = true;
4192 if (setup_poll) {
4194 * Retry once a second. If there's a share_mode_lock
4195 * around, also wait for it in case it was smbd
4196 * holding that kernel oplock that can quickly tell us
4197 * the oplock got removed.
4200 setup_poll_open(req,
4201 &fsp->file_id,
4202 tevent_timeval_set(OPLOCK_BREAK_TIMEOUT * 2,
4204 tevent_timeval_set(1, 0));
4206 return NT_STATUS_SHARING_VIOLATION;
4209 if (!NT_STATUS_IS_OK(fsp_open)) {
4210 bool wait_for_aio = NT_STATUS_EQUAL(
4211 fsp_open, NT_STATUS_MORE_PROCESSING_REQUIRED);
4212 if (wait_for_aio) {
4213 schedule_async_open(req);
4215 return fsp_open;
4218 if (new_file_created) {
4220 * As we atomically create using O_CREAT|O_EXCL,
4221 * then if new_file_created is true, then
4222 * file_existed *MUST* have been false (even
4223 * if the file was previously detected as being
4224 * there).
4226 file_existed = false;
4229 if (file_existed && !check_same_dev_ino(&saved_stat, &smb_fname->st)) {
4231 * The file did exist, but some other (local or NFS)
4232 * process either renamed/unlinked and re-created the
4233 * file with different dev/ino after we walked the path,
4234 * but before we did the open. We could retry the
4235 * open but it's a rare enough case it's easier to
4236 * just fail the open to prevent creating any problems
4237 * in the open file db having the wrong dev/ino key.
4239 fd_close(fsp);
4240 DBG_WARNING("file %s - dev/ino mismatch. "
4241 "Old (dev=%ju, ino=%ju). "
4242 "New (dev=%ju, ino=%ju). Failing open "
4243 "with NT_STATUS_ACCESS_DENIED.\n",
4244 smb_fname_str_dbg(smb_fname),
4245 (uintmax_t)saved_stat.st_ex_dev,
4246 (uintmax_t)saved_stat.st_ex_ino,
4247 (uintmax_t)smb_fname->st.st_ex_dev,
4248 (uintmax_t)smb_fname->st.st_ex_ino);
4249 return NT_STATUS_ACCESS_DENIED;
4252 old_write_time = smb_fname->st.st_ex_mtime;
4255 * Deal with the race condition where two smbd's detect the
4256 * file doesn't exist and do the create at the same time. One
4257 * of them will win and set a share mode, the other (ie. this
4258 * one) should check if the requested share mode for this
4259 * create is allowed.
4263 * Now the file exists and fsp is successfully opened,
4264 * fsp->dev and fsp->inode are valid and should replace the
4265 * dev=0,inode=0 from a non existent file. Spotted by
4266 * Nadav Danieli <nadavd@exanet.com>. JRA.
4269 if (new_file_created) {
4270 info = FILE_WAS_CREATED;
4271 } else {
4272 if (flags & O_TRUNC) {
4273 info = FILE_WAS_OVERWRITTEN;
4274 } else {
4275 info = FILE_WAS_OPENED;
4280 * If we created a new file, overwrite an existing one
4281 * or going to delete it later, we should keep
4282 * the share_mode_lock (g_lock) until we call
4283 * share_mode_entry_prepare_unlock()
4285 if (info != FILE_WAS_OPENED) {
4286 keep_locked = true;
4287 } else if (create_options & FILE_DELETE_ON_CLOSE) {
4288 keep_locked = true;
4291 lck_state = (struct open_ntcreate_lock_state) {
4292 .fsp = fsp,
4293 .object_type = "file",
4294 .req = req,
4295 .create_disposition = create_disposition,
4296 .access_mask = access_mask,
4297 .share_access = share_access,
4298 .oplock_request = oplock_request,
4299 .lease = lease,
4300 .first_open_attempt = first_open_attempt,
4301 .keep_locked = keep_locked,
4304 status = share_mode_entry_prepare_lock_add(&lck_state.prepare_state,
4305 fsp->file_id,
4306 conn->connectpath,
4307 smb_fname,
4308 &old_write_time,
4309 open_ntcreate_lock_add_entry,
4310 &lck_state);
4311 if (!NT_STATUS_IS_OK(status)) {
4312 DBG_ERR("share_mode_entry_prepare_lock_add() failed for %s - %s\n",
4313 smb_fname_str_dbg(smb_fname), nt_errstr(status));
4314 fd_close(fsp);
4315 return status;
4318 status = lck_state.status;
4319 if (!NT_STATUS_IS_OK(status)) {
4320 fd_close(fsp);
4321 return status;
4325 * From here we need to use 'goto unlock;' instead of return !!!
4328 if (fsp->oplock_type != NO_OPLOCK && fsp->oplock_type != LEASE_OPLOCK) {
4330 * Now ask for kernel oplocks
4331 * and cleanup on failure.
4333 status = set_file_oplock(fsp);
4334 if (!NT_STATUS_IS_OK(status)) {
4336 * Could not get the kernel oplock
4338 lck_state.cleanup_fn =
4339 open_ntcreate_lock_cleanup_oplock;
4340 fsp->oplock_type = NO_OPLOCK;
4344 /* Should we atomically (to the client at least) truncate ? */
4345 if ((!new_file_created) && (flags & O_TRUNC) &&
4346 (S_ISREG(fsp->fsp_name->st.st_ex_mode))) {
4347 int ret;
4349 ret = SMB_VFS_FTRUNCATE(fsp, 0);
4350 if (ret != 0) {
4351 status = map_nt_error_from_unix(errno);
4352 lck_state.cleanup_fn =
4353 open_ntcreate_lock_cleanup_entry;
4354 goto unlock;
4356 notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
4357 FILE_NOTIFY_CHANGE_SIZE
4358 | FILE_NOTIFY_CHANGE_ATTRIBUTES,
4359 fsp->fsp_name->base_name);
4363 * We have the share entry *locked*.....
4366 /* Delete streams if create_disposition requires it */
4367 if (!new_file_created &&
4368 clear_ads(create_disposition) &&
4369 !fsp_is_alternate_stream(fsp)) {
4370 status = delete_all_streams(conn, smb_fname);
4371 if (!NT_STATUS_IS_OK(status)) {
4372 lck_state.cleanup_fn =
4373 open_ntcreate_lock_cleanup_entry;
4374 goto unlock;
4378 if (!fsp->fsp_flags.is_pathref &&
4379 fsp_get_io_fd(fsp) != -1 &&
4380 lp_kernel_share_modes(SNUM(conn)))
4382 int ret;
4384 * Beware: streams implementing VFS modules may
4385 * implement streams in a way that fsp will have the
4386 * basefile open in the fsp fd, so lacking a distinct
4387 * fd for the stream the file-system sharemode will
4388 * apply on the basefile which is wrong. The actual
4389 * check is deferred to the VFS module implementing
4390 * the file-system sharemode call.
4392 ret = SMB_VFS_FILESYSTEM_SHAREMODE(fsp,
4393 share_access,
4394 access_mask);
4395 if (ret == -1){
4396 status = NT_STATUS_SHARING_VIOLATION;
4397 lck_state.cleanup_fn =
4398 open_ntcreate_lock_cleanup_entry;
4399 goto unlock;
4402 fsp->fsp_flags.kernel_share_modes_taken = true;
4406 * At this point onwards, we can guarantee that the share entry
4407 * is locked, whether we created the file or not, and that the
4408 * deny mode is compatible with all current opens.
4412 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
4413 * but we don't have to store this - just ignore it on access check.
4415 if (conn_using_smb2(conn->sconn)) {
4417 * SMB2 doesn't return it (according to Microsoft tests).
4418 * Test Case: TestSuite_ScenarioNo009GrantedAccessTestS0
4419 * File created with access = 0x7 (Read, Write, Delete)
4420 * Query Info on file returns 0x87 (Read, Write, Delete, Read Attributes)
4422 fsp->access_mask = access_mask;
4423 } else {
4424 /* But SMB1 does. */
4425 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
4428 if (pinfo) {
4429 *pinfo = info;
4432 /* Handle strange delete on close create semantics. */
4433 if (create_options & FILE_DELETE_ON_CLOSE) {
4434 if (!new_file_created) {
4435 status = can_set_delete_on_close(fsp,
4436 existing_dos_attributes);
4438 if (!NT_STATUS_IS_OK(status)) {
4439 /* Remember to delete the mode we just added. */
4440 lck_state.cleanup_fn =
4441 open_ntcreate_lock_cleanup_entry;
4442 goto unlock;
4445 /* Note that here we set the *initial* delete on close flag,
4446 not the regular one. The magic gets handled in close. */
4447 fsp->fsp_flags.initial_delete_on_close = true;
4450 possibly_set_archive(conn,
4451 fsp,
4452 smb_fname,
4453 parent_dir_fname,
4454 info,
4455 new_dos_attributes,
4456 &smb_fname->st.st_ex_mode);
4458 /* Determine sparse flag. */
4459 if (posix_open) {
4460 /* POSIX opens are sparse by default. */
4461 fsp->fsp_flags.is_sparse = true;
4462 } else {
4463 fsp->fsp_flags.is_sparse =
4464 (existing_dos_attributes & FILE_ATTRIBUTE_SPARSE);
4468 * Take care of inherited ACLs on created files - if default ACL not
4469 * selected.
4472 if (!posix_open && new_file_created && !def_acl) {
4473 if (unx_mode != smb_fname->st.st_ex_mode) {
4474 int ret = SMB_VFS_FCHMOD(fsp, unx_mode);
4475 if (ret == -1) {
4476 DBG_INFO("failed to reset "
4477 "attributes of file %s to 0%o\n",
4478 smb_fname_str_dbg(smb_fname),
4479 (unsigned int)unx_mode);
4483 } else if (new_unx_mode) {
4485 * We only get here in the case of:
4487 * a). Not a POSIX open.
4488 * b). File already existed.
4489 * c). File was overwritten.
4490 * d). Requested DOS attributes didn't match
4491 * the DOS attributes on the existing file.
4493 * In that case new_unx_mode has been set
4494 * equal to the calculated mode (including
4495 * possible inheritance of the mode from the
4496 * containing directory).
4498 * Note this mode was calculated with the
4499 * DOS attribute FILE_ATTRIBUTE_ARCHIVE added,
4500 * so the mode change here is suitable for
4501 * an overwritten file.
4504 if (new_unx_mode != smb_fname->st.st_ex_mode) {
4505 int ret = SMB_VFS_FCHMOD(fsp, new_unx_mode);
4506 if (ret == -1) {
4507 DBG_INFO("failed to reset "
4508 "attributes of file %s to 0%o\n",
4509 smb_fname_str_dbg(smb_fname),
4510 (unsigned int)new_unx_mode);
4516 * Deal with other opens having a modified write time.
4518 if (fsp_getinfo_ask_sharemode(fsp) &&
4519 !is_omit_timespec(&lck_state.write_time))
4521 update_stat_ex_mtime(&fsp->fsp_name->st, lck_state.write_time);
4524 status = NT_STATUS_OK;
4526 unlock:
4527 ulstatus = share_mode_entry_prepare_unlock(&lck_state.prepare_state,
4528 lck_state.cleanup_fn,
4529 &lck_state);
4530 if (!NT_STATUS_IS_OK(ulstatus)) {
4531 DBG_ERR("share_mode_entry_prepare_unlock() failed for %s - %s\n",
4532 smb_fname_str_dbg(smb_fname), nt_errstr(ulstatus));
4533 smb_panic("share_mode_entry_prepare_unlock() failed!");
4536 if (!NT_STATUS_IS_OK(status)) {
4537 fd_close(fsp);
4538 return status;
4541 return NT_STATUS_OK;
4544 static NTSTATUS apply_new_nt_acl(struct files_struct *dirfsp,
4545 struct files_struct *fsp,
4546 struct security_descriptor *sd)
4548 NTSTATUS status;
4550 if (sd != NULL) {
4552 * According to the MS documentation, the only time the security
4553 * descriptor is applied to the opened file is iff we *created* the
4554 * file; an existing file stays the same.
4556 * Also, it seems (from observation) that you can open the file with
4557 * any access mask but you can still write the sd. We need to override
4558 * the granted access before we call set_sd
4559 * Patch for bug #2242 from Tom Lackemann <cessnatomny@yahoo.com>.
4562 uint32_t sec_info_sent;
4563 uint32_t saved_access_mask = fsp->access_mask;
4565 sec_info_sent = get_sec_info(sd);
4567 fsp->access_mask = FILE_GENERIC_ALL;
4569 if (sec_info_sent & (SECINFO_OWNER|
4570 SECINFO_GROUP|
4571 SECINFO_DACL|
4572 SECINFO_SACL)) {
4573 status = set_sd(fsp, sd, sec_info_sent);
4574 } else {
4575 status = NT_STATUS_OK;
4578 fsp->access_mask = saved_access_mask;
4580 if (!NT_STATUS_IS_OK(status)) {
4581 DBG_WARNING("set_sd() failed for '%s': %s\n",
4582 fsp_str_dbg(fsp), nt_errstr(status));
4583 return status;
4586 return NT_STATUS_OK;
4589 if (!lp_inherit_acls(SNUM(fsp->conn))) {
4590 return NT_STATUS_OK;
4593 /* Inherit from parent. Errors here are not fatal. */
4594 status = inherit_new_acl(dirfsp, fsp);
4595 if (!NT_STATUS_IS_OK(status)) {
4596 DBG_WARNING("inherit_new_acl failed for %s with %s\n",
4597 fsp_str_dbg(fsp), nt_errstr(status));
4600 return NT_STATUS_OK;
4603 bool smbd_is_tmpname(const char *n, int *_unlink_flags)
4605 const char *p = n;
4606 int unlink_flags = INT_MAX;
4607 struct server_id id;
4608 bool exists;
4610 if (_unlink_flags != NULL) {
4611 *_unlink_flags = INT_MAX;
4614 if (!IS_SMBD_TMPNAME_PREFIX(n)) {
4615 return false;
4617 p += sizeof(SMBD_TMPNAME_PREFIX) - 1;
4618 switch (p[0]) {
4619 case 'D':
4620 unlink_flags = AT_REMOVEDIR;
4621 break;
4622 default:
4623 return false;
4625 p += 1;
4626 if (p[0] != ':') {
4627 return false;
4629 p += 1;
4631 id = server_id_from_string_ex(get_my_vnn(), '%', p);
4632 if (id.pid == UINT64_MAX) {
4633 return false;
4635 if (id.unique_id == 0) {
4636 return false;
4638 if (id.unique_id == SERVERID_UNIQUE_ID_NOT_TO_VERIFY) {
4639 return false;
4642 if (_unlink_flags == NULL) {
4643 return true;
4646 exists = serverid_exists(&id);
4647 if (!exists) {
4649 * let the caller know it's stale
4650 * and should be removed
4652 *_unlink_flags = unlink_flags;
4655 return true;
4658 static NTSTATUS mkdir_internal(connection_struct *conn,
4659 struct smb_filename *parent_dir_fname, /* parent. */
4660 struct smb_filename *smb_fname_atname, /* atname relative to parent. */
4661 struct smb_filename *smb_dname, /* full pathname from root of share. */
4662 struct security_descriptor *sd,
4663 uint32_t file_attributes,
4664 struct files_struct *fsp)
4666 TALLOC_CTX *frame = talloc_stackframe();
4667 const struct loadparm_substitution *lp_sub =
4668 loadparm_s3_global_substitution();
4669 mode_t mode;
4670 NTSTATUS status;
4671 bool posix_open = false;
4672 bool need_re_stat = false;
4673 uint32_t access_mask = SEC_DIR_ADD_SUBDIR;
4674 struct smb_filename *first_atname = NULL;
4675 struct smb_filename *tmp_atname = NULL;
4676 char *orig_dname = NULL;
4677 char *tmp_dname = NULL;
4678 int vfs_use_tmp = lp_vfs_mkdir_use_tmp_name(SNUM(conn));
4679 bool need_tmpname = false;
4680 struct server_id id = messaging_server_id(conn->sconn->msg_ctx);
4681 struct server_id_buf idbuf;
4682 char *idstr = server_id_str_buf_unique_ex(id, '%', &idbuf);
4683 struct vfs_open_how how = { .flags = O_RDONLY|O_DIRECTORY, };
4684 struct vfs_rename_how rhow = { .flags = VFS_RENAME_HOW_NO_REPLACE, };
4685 int ret;
4687 if (!CAN_WRITE(conn) || (access_mask & ~(conn->share_access))) {
4688 DBG_INFO("failing share access %s\n",
4689 lp_servicename(talloc_tos(), lp_sub, SNUM(conn)));
4690 TALLOC_FREE(frame);
4691 return NT_STATUS_ACCESS_DENIED;
4694 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
4695 posix_open = true;
4696 mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
4697 } else {
4698 mode = unix_mode(conn,
4699 FILE_ATTRIBUTE_DIRECTORY,
4700 smb_dname,
4701 parent_dir_fname->fsp);
4704 status = check_parent_access_fsp(parent_dir_fname->fsp, access_mask);
4705 if(!NT_STATUS_IS_OK(status)) {
4706 DBG_INFO("check_parent_access_fsp "
4707 "on directory %s for path %s returned %s\n",
4708 smb_fname_str_dbg(parent_dir_fname),
4709 smb_dname->base_name,
4710 nt_errstr(status));
4711 TALLOC_FREE(frame);
4712 return status;
4715 if (lp_inherit_acls(SNUM(conn))) {
4716 if (directory_has_default_acl_fsp(parent_dir_fname->fsp)) {
4717 mode = (0777 & lp_directory_mask(SNUM(conn)));
4719 need_tmpname = true;
4720 } else if (lp_store_dos_attributes(SNUM(conn))) {
4721 need_tmpname = true;
4722 } else if (lp_inherit_permissions(SNUM(conn))) {
4723 need_tmpname = true;
4724 } else if (lp_inherit_owner(SNUM(conn)) != INHERIT_OWNER_NO) {
4725 need_tmpname = true;
4726 } else if (lp_nt_acl_support(SNUM(conn)) && sd != NULL) {
4727 need_tmpname = true;
4730 if (vfs_use_tmp != Auto) {
4731 need_tmpname = vfs_use_tmp;
4734 if (!need_tmpname) {
4735 first_atname = smb_fname_atname;
4736 goto mkdir_first;
4740 * In order to avoid races where other clients could
4741 * see the directory before it is setup completely
4742 * we use a temporary name and rename it
4743 * when everything is ready.
4746 orig_dname = smb_dname->base_name;
4748 tmp_atname = cp_smb_filename(frame,
4749 smb_fname_atname);
4750 if (tmp_atname == NULL) {
4751 TALLOC_FREE(frame);
4752 return NT_STATUS_NO_MEMORY;
4754 TALLOC_FREE(tmp_atname->base_name);
4755 tmp_atname->base_name = talloc_asprintf(tmp_atname,
4756 "%s%s:%s",
4757 SMBD_TMPDIR_PREFIX,
4758 idstr,
4759 smb_fname_atname->base_name);
4760 if (tmp_atname == NULL) {
4761 TALLOC_FREE(frame);
4762 return NT_STATUS_NO_MEMORY;
4764 SMB_ASSERT(smbd_is_tmpname(tmp_atname->base_name, NULL));
4765 if (!ISDOT(parent_dir_fname->base_name)) {
4766 tmp_dname = talloc_asprintf(frame,
4767 "%s/%s",
4768 parent_dir_fname->base_name,
4769 tmp_atname->base_name);
4770 if (tmp_dname == NULL) {
4771 TALLOC_FREE(frame);
4772 return NT_STATUS_NO_MEMORY;
4774 } else {
4775 tmp_dname = talloc_strdup(frame, tmp_atname->base_name);
4776 if (tmp_dname == NULL) {
4777 TALLOC_FREE(frame);
4778 return NT_STATUS_NO_MEMORY;
4782 smb_dname->base_name = tmp_dname;
4784 DBG_DEBUG("temporary replace '%s' by '%s'\n",
4785 orig_dname, tmp_dname);
4787 first_atname = tmp_atname;
4789 mkdir_first:
4790 ret = SMB_VFS_MKDIRAT(conn,
4791 parent_dir_fname->fsp,
4792 first_atname,
4793 mode);
4794 if (ret != 0) {
4795 status = map_nt_error_from_unix(errno);
4796 DBG_NOTICE("MKDIRAT failed for '%s': %s\n",
4797 smb_fname_str_dbg(smb_dname), nt_errstr(status));
4798 goto restore_orig;
4802 * Make this a pathref fsp for now. open_directory() will reopen as a
4803 * full fsp.
4805 fsp->fsp_flags.is_pathref = true;
4807 status = fd_openat(parent_dir_fname->fsp, first_atname, fsp, &how);
4808 if (!NT_STATUS_IS_OK(status)) {
4809 DBG_ERR("fd_openat() failed for '%s': %s\n",
4810 smb_fname_str_dbg(smb_dname), nt_errstr(status));
4811 goto restore_orig;
4814 /* Ensure we're checking for a symlink here.... */
4815 /* We don't want to get caught by a symlink racer. */
4817 status = vfs_stat_fsp(fsp);
4818 if (!NT_STATUS_IS_OK(status)) {
4819 DBG_ERR("Could not stat directory '%s' just created: %s\n",
4820 smb_fname_str_dbg(smb_dname), nt_errstr(status));
4821 goto restore_orig;
4824 if (!S_ISDIR(smb_dname->st.st_ex_mode)) {
4825 DBG_ERR("Directory '%s' just created is not a directory !\n",
4826 smb_fname_str_dbg(smb_dname));
4827 status = NT_STATUS_NOT_A_DIRECTORY;
4828 goto restore_orig;
4831 if (lp_store_dos_attributes(SNUM(conn))) {
4832 file_set_dosmode(conn,
4833 smb_dname,
4834 file_attributes | FILE_ATTRIBUTE_DIRECTORY,
4835 parent_dir_fname,
4836 true);
4839 if (lp_inherit_permissions(SNUM(conn))) {
4840 inherit_access_posix_acl(conn, parent_dir_fname->fsp,
4841 smb_dname, mode);
4842 need_re_stat = true;
4845 if (!posix_open) {
4847 * Check if high bits should have been set,
4848 * then (if bits are missing): add them.
4849 * Consider bits automagically set by UNIX, i.e. SGID bit from parent
4850 * dir.
4852 if ((mode & ~(S_IRWXU|S_IRWXG|S_IRWXO)) &&
4853 (mode & ~smb_dname->st.st_ex_mode)) {
4854 SMB_VFS_FCHMOD(fsp,
4855 (smb_dname->st.st_ex_mode |
4856 (mode & ~smb_dname->st.st_ex_mode)));
4857 need_re_stat = true;
4861 /* Change the owner if required. */
4862 if (lp_inherit_owner(SNUM(conn)) != INHERIT_OWNER_NO) {
4863 change_dir_owner_to_parent_fsp(parent_dir_fname->fsp,
4864 fsp);
4865 need_re_stat = true;
4868 if (need_re_stat) {
4869 status = vfs_stat_fsp(fsp);
4870 if (!NT_STATUS_IS_OK(status)) {
4871 DBG_ERR("Could not stat directory '%s' just created: %s\n",
4872 smb_fname_str_dbg(smb_dname), nt_errstr(status));
4873 goto restore_orig;
4877 if (lp_nt_acl_support(SNUM(conn))) {
4878 status = apply_new_nt_acl(parent_dir_fname->fsp,
4879 fsp,
4880 sd);
4881 if (!NT_STATUS_IS_OK(status)) {
4882 DBG_WARNING("apply_new_nt_acl() failed for %s with %s\n",
4883 fsp_str_dbg(fsp),
4884 nt_errstr(status));
4885 goto do_unlink;
4889 if (!need_tmpname) {
4890 goto done;
4894 * A rename needs a valid stat for the source,
4895 * see vfs_fruit.c ...
4897 tmp_atname->st = smb_dname->st;
4900 * We first try VFS_RENAME_HOW_NO_REPLACE,
4901 * if it's implemented in the kernel,
4902 * we'll always get EEXIST if the target
4903 * exist, as it's handled at the linux vfs
4904 * layer. But if it doesn't exist we
4905 * can still get EINVAL if the actual
4906 * filesystem doesn't support RENAME_NOREPLACE.
4908 * If the kernel doesn't support rename2()
4909 * we get EINVAL instead of ENOSYS (this
4910 * is mapped in the libreplace replacement
4911 * (as well as the glibc replacement).
4913 ret = SMB_VFS_RENAMEAT(conn,
4914 parent_dir_fname->fsp,
4915 tmp_atname,
4916 parent_dir_fname->fsp,
4917 smb_fname_atname,
4918 &rhow);
4919 if (ret == -1 && errno == EINVAL) {
4921 * This is the strategie we use without having
4922 * renameat2(RENAME_NOREPLACE):
4924 * renameat() is able to replace a directory if the source is
4925 * also a directory.
4927 * So in order to avoid races as much as possible we do a
4928 * mkdirat() with mode 0 in order to catch EEXIST almost
4929 * atomically, when this code runs by two processes at the same
4930 * time.
4932 * Then a renameat() makes the temporary directory available for
4933 * clients.
4935 * This a much smaller window where the other clients may see
4936 * the incomplete directory, which has a mode of 0.
4939 rhow.flags &= ~VFS_RENAME_HOW_NO_REPLACE;
4941 DBG_DEBUG("MKDIRAT/RENAMEAT '%s' -> '%s'\n",
4942 tmp_dname, orig_dname);
4944 ret = SMB_VFS_MKDIRAT(conn,
4945 parent_dir_fname->fsp,
4946 smb_fname_atname,
4948 if (ret != 0) {
4949 status = map_nt_error_from_unix(errno);
4950 DBG_NOTICE("MKDIRAT failed for '%s': %s\n",
4951 orig_dname, nt_errstr(status));
4952 goto do_unlink;
4955 ret = SMB_VFS_RENAMEAT(conn,
4956 parent_dir_fname->fsp,
4957 tmp_atname,
4958 parent_dir_fname->fsp,
4959 smb_fname_atname,
4960 &rhow);
4963 if (ret != 0) {
4964 status = map_nt_error_from_unix(errno);
4965 DBG_NOTICE("RENAMEAT failed for '%s' -> '%s': %s\n",
4966 tmp_dname, orig_dname, nt_errstr(status));
4967 goto do_unlink;
4969 smb_fname_atname->st = tmp_atname->st;
4970 smb_dname->base_name = orig_dname;
4972 done:
4973 DBG_DEBUG("Created directory '%s'\n",
4974 smb_fname_str_dbg(smb_dname));
4976 notify_fname(conn, NOTIFY_ACTION_ADDED, FILE_NOTIFY_CHANGE_DIR_NAME,
4977 smb_dname->base_name);
4979 TALLOC_FREE(frame);
4980 return NT_STATUS_OK;
4982 do_unlink:
4983 DBG_NOTICE("%s: rollback and unlink '%s'\n",
4984 nt_errstr(status),
4985 tmp_dname);
4986 ret = SMB_VFS_UNLINKAT(conn,
4987 parent_dir_fname->fsp,
4988 tmp_atname,
4989 AT_REMOVEDIR);
4990 if (ret == 0) {
4991 DBG_NOTICE("SMB_VFS_UNLINKAT(%s): OK\n",
4992 tmp_dname);
4993 } else {
4994 NTSTATUS status2 = map_nt_error_from_unix(errno);
4995 DBG_WARNING("SMB_VFS_UNLINKAT(%s) ignoring %s\n",
4996 tmp_dname, nt_errstr(status2));
4999 restore_orig:
5000 if (!need_tmpname) {
5001 TALLOC_FREE(frame);
5002 return status;
5004 DBG_NOTICE("%s: restoring '%s' -> '%s'\n",
5005 nt_errstr(status),
5006 tmp_dname,
5007 orig_dname);
5008 SET_STAT_INVALID(smb_fname_atname->st);
5009 smb_dname->base_name = orig_dname;
5010 SET_STAT_INVALID(smb_dname->st);
5011 TALLOC_FREE(frame);
5012 return status;
5015 /****************************************************************************
5016 Open a directory from an NT SMB call.
5017 ****************************************************************************/
5019 static NTSTATUS open_directory(connection_struct *conn,
5020 struct smb_request *req,
5021 uint32_t access_mask,
5022 uint32_t share_access,
5023 uint32_t create_disposition,
5024 uint32_t create_options,
5025 uint32_t file_attributes,
5026 struct smb_filename *parent_dir_fname,
5027 struct smb_filename *smb_fname_atname,
5028 struct security_descriptor *sd,
5029 int *pinfo,
5030 struct files_struct *fsp)
5032 struct smb_filename *smb_dname = fsp->fsp_name;
5033 bool dir_existed = VALID_STAT(smb_dname->st);
5034 struct open_ntcreate_lock_state lck_state = {};
5035 bool keep_locked = false;
5036 NTSTATUS status;
5037 struct timespec mtimespec;
5038 int info = 0;
5039 uint32_t need_fd_access;
5040 NTSTATUS ulstatus;
5042 if (is_ntfs_stream_smb_fname(smb_dname)) {
5043 DEBUG(2, ("open_directory: %s is a stream name!\n",
5044 smb_fname_str_dbg(smb_dname)));
5045 return NT_STATUS_NOT_A_DIRECTORY;
5048 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS)) {
5049 /* Ensure we have a directory attribute. */
5050 file_attributes |= FILE_ATTRIBUTE_DIRECTORY;
5053 DBG_INFO("opening directory %s, access_mask = 0x%"PRIx32", "
5054 "share_access = 0x%"PRIx32" create_options = 0x%"PRIx32", "
5055 "create_disposition = 0x%"PRIx32", "
5056 "file_attributes = 0x%"PRIx32"\n",
5057 smb_fname_str_dbg(smb_dname),
5058 access_mask,
5059 share_access,
5060 create_options,
5061 create_disposition,
5062 file_attributes);
5064 status = smbd_calculate_access_mask_fsp(parent_dir_fname->fsp,
5065 smb_dname->fsp,
5066 false,
5067 access_mask,
5068 &access_mask);
5069 if (!NT_STATUS_IS_OK(status)) {
5070 DBG_DEBUG("smbd_calculate_access_mask_fsp "
5071 "on file %s returned %s\n",
5072 smb_fname_str_dbg(smb_dname),
5073 nt_errstr(status));
5074 return status;
5077 if ((access_mask & SEC_FLAG_SYSTEM_SECURITY) &&
5078 !security_token_has_privilege(get_current_nttok(conn),
5079 SEC_PRIV_SECURITY)) {
5080 DEBUG(10, ("open_directory: open on %s "
5081 "failed - SEC_FLAG_SYSTEM_SECURITY denied.\n",
5082 smb_fname_str_dbg(smb_dname)));
5083 return NT_STATUS_PRIVILEGE_NOT_HELD;
5086 switch( create_disposition ) {
5087 case FILE_OPEN:
5089 if (!dir_existed) {
5090 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5093 info = FILE_WAS_OPENED;
5094 break;
5096 case FILE_CREATE:
5098 /* If directory exists error. If directory doesn't
5099 * exist create. */
5101 if (dir_existed) {
5102 status = NT_STATUS_OBJECT_NAME_COLLISION;
5103 DEBUG(2, ("open_directory: unable to create "
5104 "%s. Error was %s\n",
5105 smb_fname_str_dbg(smb_dname),
5106 nt_errstr(status)));
5107 return status;
5110 if (smb_fname_atname->twrp != 0) {
5111 return NT_STATUS_MEDIA_WRITE_PROTECTED;
5114 status = mkdir_internal(conn,
5115 parent_dir_fname,
5116 smb_fname_atname,
5117 smb_dname,
5119 file_attributes,
5120 fsp);
5122 if (!NT_STATUS_IS_OK(status)) {
5123 DEBUG(2, ("open_directory: unable to create "
5124 "%s. Error was %s\n",
5125 smb_fname_str_dbg(smb_dname),
5126 nt_errstr(status)));
5127 return status;
5130 info = FILE_WAS_CREATED;
5131 break;
5133 case FILE_OPEN_IF:
5135 * If directory exists open. If directory doesn't
5136 * exist create.
5139 if (dir_existed) {
5140 status = NT_STATUS_OK;
5141 info = FILE_WAS_OPENED;
5142 } else {
5143 if (smb_fname_atname->twrp != 0) {
5144 return NT_STATUS_MEDIA_WRITE_PROTECTED;
5146 status = mkdir_internal(conn,
5147 parent_dir_fname,
5148 smb_fname_atname,
5149 smb_dname,
5151 file_attributes,
5152 fsp);
5154 if (NT_STATUS_IS_OK(status)) {
5155 info = FILE_WAS_CREATED;
5156 } else {
5157 int ret;
5158 /* Cope with create race. */
5159 if (!NT_STATUS_EQUAL(status,
5160 NT_STATUS_OBJECT_NAME_COLLISION)) {
5161 DEBUG(2, ("open_directory: unable to create "
5162 "%s. Error was %s\n",
5163 smb_fname_str_dbg(smb_dname),
5164 nt_errstr(status)));
5165 return status;
5169 * If mkdir_internal() returned
5170 * NT_STATUS_OBJECT_NAME_COLLISION
5171 * we still must lstat the path.
5173 ret = SMB_VFS_FSTATAT(
5174 conn,
5175 parent_dir_fname->fsp,
5176 smb_fname_atname,
5177 &smb_dname->st,
5178 AT_SYMLINK_NOFOLLOW);
5179 if (ret == -1) {
5180 DEBUG(2, ("Could not stat "
5181 "directory '%s' just "
5182 "opened: %s\n",
5183 smb_fname_str_dbg(
5184 smb_dname),
5185 strerror(errno)));
5186 return map_nt_error_from_unix(
5187 errno);
5190 info = FILE_WAS_OPENED;
5194 break;
5196 case FILE_SUPERSEDE:
5197 case FILE_OVERWRITE:
5198 case FILE_OVERWRITE_IF:
5199 default:
5200 DEBUG(5,("open_directory: invalid create_disposition "
5201 "0x%x for directory %s\n",
5202 (unsigned int)create_disposition,
5203 smb_fname_str_dbg(smb_dname)));
5204 return NT_STATUS_INVALID_PARAMETER;
5207 if(!S_ISDIR(smb_dname->st.st_ex_mode)) {
5208 DEBUG(5,("open_directory: %s is not a directory !\n",
5209 smb_fname_str_dbg(smb_dname)));
5210 return NT_STATUS_NOT_A_DIRECTORY;
5214 * Setup the files_struct for it.
5217 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_dname->st);
5218 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
5219 fsp->file_pid = req ? req->smbpid : 0;
5220 fsp->fsp_flags.can_lock = false;
5221 fsp->fsp_flags.can_read = false;
5222 fsp->fsp_flags.can_write = false;
5224 fh_set_private_options(fsp->fh, 0);
5226 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
5228 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
5229 fsp->print_file = NULL;
5230 fsp->fsp_flags.modified = false;
5231 fsp->oplock_type = NO_OPLOCK;
5232 fsp->sent_oplock_break = NO_BREAK_SENT;
5233 fsp->fsp_flags.is_directory = true;
5234 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
5235 fsp->posix_flags |= FSP_POSIX_FLAGS_ALL;
5238 /* Don't store old timestamps for directory
5239 handles in the internal database. We don't
5240 update them in there if new objects
5241 are created in the directory. Currently
5242 we only update timestamps on file writes.
5243 See bug #9870.
5245 mtimespec = make_omit_timespec();
5248 * Obviously for FILE_LIST_DIRECTORY we need to reopen to get an fd
5249 * usable for reading a directory. SMB2_FLUSH may be called on
5250 * directories opened with FILE_ADD_FILE and FILE_ADD_SUBDIRECTORY so
5251 * for those we need to reopen as well.
5253 need_fd_access =
5254 FILE_LIST_DIRECTORY |
5255 FILE_ADD_FILE |
5256 FILE_ADD_SUBDIRECTORY;
5258 if (access_mask & need_fd_access) {
5259 struct vfs_open_how how = {
5260 .flags = O_RDONLY | O_DIRECTORY,
5262 bool file_created;
5264 status = reopen_from_fsp(parent_dir_fname->fsp,
5265 smb_fname_atname,
5266 fsp,
5267 &how,
5268 &file_created);
5269 if (!NT_STATUS_IS_OK(status)) {
5270 DBG_INFO("Could not open fd for [%s]: %s\n",
5271 smb_fname_str_dbg(smb_dname),
5272 nt_errstr(status));
5273 return status;
5277 status = vfs_stat_fsp(fsp);
5278 if (!NT_STATUS_IS_OK(status)) {
5279 fd_close(fsp);
5280 return status;
5283 if(!S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
5284 DEBUG(5,("open_directory: %s is not a directory !\n",
5285 smb_fname_str_dbg(smb_dname)));
5286 fd_close(fsp);
5287 return NT_STATUS_NOT_A_DIRECTORY;
5290 /* Ensure there was no race condition. We need to check
5291 * dev/inode but not permissions, as these can change
5292 * legitimately */
5293 if (!check_same_dev_ino(&smb_dname->st, &fsp->fsp_name->st)) {
5294 DEBUG(5,("open_directory: stat struct differs for "
5295 "directory %s.\n",
5296 smb_fname_str_dbg(smb_dname)));
5297 fd_close(fsp);
5298 return NT_STATUS_ACCESS_DENIED;
5301 if (info == FILE_WAS_OPENED) {
5302 status = smbd_check_access_rights_fsp(parent_dir_fname->fsp,
5303 fsp,
5304 false,
5305 access_mask);
5306 if (!NT_STATUS_IS_OK(status)) {
5307 DBG_DEBUG("smbd_check_access_rights_fsp on "
5308 "file %s failed with %s\n",
5309 fsp_str_dbg(fsp),
5310 nt_errstr(status));
5311 fd_close(fsp);
5312 return status;
5317 * If we created a new directory or going to delete it later,
5318 * we should keep * the share_mode_lock (g_lock) until we call
5319 * share_mode_entry_prepare_unlock()
5321 if (info != FILE_WAS_OPENED) {
5322 keep_locked = true;
5323 } else if (create_options & FILE_DELETE_ON_CLOSE) {
5324 keep_locked = true;
5327 lck_state = (struct open_ntcreate_lock_state) {
5328 .fsp = fsp,
5329 .object_type = "directory",
5330 .req = req,
5331 .create_disposition = create_disposition,
5332 .access_mask = access_mask,
5333 .share_access = share_access,
5334 .oplock_request = NO_OPLOCK,
5335 .lease = NULL,
5336 .first_open_attempt = true,
5337 .keep_locked = keep_locked,
5340 status = share_mode_entry_prepare_lock_add(&lck_state.prepare_state,
5341 fsp->file_id,
5342 conn->connectpath,
5343 smb_dname,
5344 &mtimespec,
5345 open_ntcreate_lock_add_entry,
5346 &lck_state);
5347 if (!NT_STATUS_IS_OK(status)) {
5348 DBG_ERR("share_mode_entry_prepare_lock_add() failed for %s - %s\n",
5349 smb_fname_str_dbg(smb_dname), nt_errstr(status));
5350 fd_close(fsp);
5351 return status;
5354 status = lck_state.status;
5355 if (!NT_STATUS_IS_OK(status)) {
5356 fd_close(fsp);
5357 return status;
5361 * From here we need to use 'goto unlock;' instead of return !!!
5364 /* For directories the delete on close bit at open time seems
5365 always to be honored on close... See test 19 in Samba4 BASE-DELETE. */
5366 if (create_options & FILE_DELETE_ON_CLOSE) {
5367 status = can_set_delete_on_close(fsp, 0);
5368 if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
5369 lck_state.cleanup_fn =
5370 open_ntcreate_lock_cleanup_entry;
5371 goto unlock;
5374 if (NT_STATUS_IS_OK(status)) {
5375 /* Note that here we set the *initial* delete on close flag,
5376 not the regular one. The magic gets handled in close. */
5377 fsp->fsp_flags.initial_delete_on_close = true;
5382 * Deal with other opens having a modified write time.
5384 if (!is_omit_timespec(&lck_state.write_time)) {
5385 update_stat_ex_mtime(&fsp->fsp_name->st, lck_state.write_time);
5388 if (pinfo) {
5389 *pinfo = info;
5392 status = NT_STATUS_OK;
5394 unlock:
5395 ulstatus = share_mode_entry_prepare_unlock(&lck_state.prepare_state,
5396 lck_state.cleanup_fn,
5397 &lck_state);
5398 if (!NT_STATUS_IS_OK(ulstatus)) {
5399 DBG_ERR("share_mode_entry_prepare_unlock() failed for %s - %s\n",
5400 smb_fname_str_dbg(smb_dname), nt_errstr(ulstatus));
5401 smb_panic("share_mode_entry_prepare_unlock() failed!");
5404 if (!NT_STATUS_IS_OK(status)) {
5405 fd_close(fsp);
5406 return status;
5409 return NT_STATUS_OK;
5412 NTSTATUS create_directory(connection_struct *conn,
5413 struct smb_request *req,
5414 struct files_struct *dirfsp,
5415 struct smb_filename *smb_dname)
5417 NTSTATUS status;
5418 files_struct *fsp;
5420 status = SMB_VFS_CREATE_FILE(
5421 conn, /* conn */
5422 req, /* req */
5423 dirfsp, /* dirfsp */
5424 smb_dname, /* fname */
5425 FILE_READ_ATTRIBUTES, /* access_mask */
5426 FILE_SHARE_NONE, /* share_access */
5427 FILE_CREATE, /* create_disposition*/
5428 FILE_DIRECTORY_FILE, /* create_options */
5429 FILE_ATTRIBUTE_DIRECTORY, /* file_attributes */
5430 0, /* oplock_request */
5431 NULL, /* lease */
5432 0, /* allocation_size */
5433 0, /* private_flags */
5434 NULL, /* sd */
5435 NULL, /* ea_list */
5436 &fsp, /* result */
5437 NULL, /* pinfo */
5438 NULL, NULL); /* create context */
5440 if (NT_STATUS_IS_OK(status)) {
5441 close_file_free(req, &fsp, NORMAL_CLOSE);
5444 return status;
5447 /****************************************************************************
5448 Receive notification that one of our open files has been renamed by another
5449 smbd process.
5450 ****************************************************************************/
5452 void msg_file_was_renamed(struct messaging_context *msg_ctx,
5453 void *private_data,
5454 uint32_t msg_type,
5455 struct server_id src,
5456 DATA_BLOB *data)
5458 struct file_rename_message *msg = NULL;
5459 enum ndr_err_code ndr_err;
5460 files_struct *fsp;
5461 struct smb_filename *smb_fname = NULL;
5462 struct smbd_server_connection *sconn =
5463 talloc_get_type_abort(private_data,
5464 struct smbd_server_connection);
5466 msg = talloc(talloc_tos(), struct file_rename_message);
5467 if (msg == NULL) {
5468 DBG_WARNING("talloc failed\n");
5469 return;
5472 ndr_err = ndr_pull_struct_blob_all(
5473 data,
5474 msg,
5475 msg,
5476 (ndr_pull_flags_fn_t)ndr_pull_file_rename_message);
5477 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
5478 DBG_DEBUG("ndr_pull_file_rename_message failed: %s\n",
5479 ndr_errstr(ndr_err));
5480 goto out;
5482 if (DEBUGLEVEL >= 10) {
5483 struct server_id_buf buf;
5484 DBG_DEBUG("Got rename message from %s\n",
5485 server_id_str_buf(src, &buf));
5486 NDR_PRINT_DEBUG(file_rename_message, msg);
5489 /* stream_name must always be NULL if there is no stream. */
5490 if ((msg->stream_name != NULL) && (msg->stream_name[0] == '\0')) {
5491 msg->stream_name = NULL;
5494 smb_fname = synthetic_smb_fname(msg,
5495 msg->base_name,
5496 msg->stream_name,
5497 NULL,
5500 if (smb_fname == NULL) {
5501 DBG_DEBUG("synthetic_smb_fname failed\n");
5502 goto out;
5505 fsp = file_find_dif(sconn, msg->id, msg->share_file_id);
5506 if (fsp == NULL) {
5507 DBG_DEBUG("fsp not found\n");
5508 goto out;
5511 if (strcmp(fsp->conn->connectpath, msg->servicepath) == 0) {
5512 SMB_STRUCT_STAT fsp_orig_sbuf;
5513 NTSTATUS status;
5514 DBG_DEBUG("renaming file %s from %s -> %s\n",
5515 fsp_fnum_dbg(fsp),
5516 fsp_str_dbg(fsp),
5517 smb_fname_str_dbg(smb_fname));
5520 * The incoming smb_fname here has an
5521 * invalid stat struct from synthetic_smb_fname()
5522 * above.
5523 * Preserve the existing stat from the
5524 * open fsp after fsp_set_smb_fname()
5525 * overwrites with the invalid stat.
5527 * (We could just copy this into
5528 * smb_fname->st, but keep this code
5529 * identical to the fix in rename_open_files()
5530 * for clarity.
5532 * We will do an fstat before returning
5533 * any of this metadata to the client anyway.
5535 fsp_orig_sbuf = fsp->fsp_name->st;
5536 status = fsp_set_smb_fname(fsp, smb_fname);
5537 if (!NT_STATUS_IS_OK(status)) {
5538 DBG_DEBUG("fsp_set_smb_fname failed: %s\n",
5539 nt_errstr(status));
5541 fsp->fsp_name->st = fsp_orig_sbuf;
5542 } else {
5543 /* TODO. JRA. */
5545 * Now we have the complete path we can work out if
5546 * this is actually within this share and adjust
5547 * newname accordingly.
5549 DBG_DEBUG("share mismatch (sharepath %s not sharepath %s) "
5550 "%s from %s -> %s\n",
5551 fsp->conn->connectpath,
5552 msg->servicepath,
5553 fsp_fnum_dbg(fsp),
5554 fsp_str_dbg(fsp),
5555 smb_fname_str_dbg(smb_fname));
5557 out:
5558 TALLOC_FREE(msg);
5562 * If a main file is opened for delete, all streams need to be checked for
5563 * !FILE_SHARE_DELETE. Do this by opening with DELETE_ACCESS.
5564 * If that works, delete them all by setting the delete on close and close.
5567 static NTSTATUS open_streams_for_delete(connection_struct *conn,
5568 const struct smb_filename *smb_fname)
5570 struct stream_struct *stream_info = NULL;
5571 files_struct **streams = NULL;
5572 int j;
5573 unsigned int i, num_streams = 0;
5574 TALLOC_CTX *frame = talloc_stackframe();
5575 const struct smb_filename *pathref = NULL;
5576 NTSTATUS status;
5578 if (smb_fname->fsp == NULL) {
5579 struct smb_filename *tmp = NULL;
5580 status = synthetic_pathref(frame,
5581 conn->cwd_fsp,
5582 smb_fname->base_name,
5583 NULL,
5584 NULL,
5585 smb_fname->twrp,
5586 smb_fname->flags,
5587 &tmp);
5588 if (!NT_STATUS_IS_OK(status)) {
5589 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
5590 || NT_STATUS_EQUAL(status,
5591 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
5592 DBG_DEBUG("no streams around\n");
5593 TALLOC_FREE(frame);
5594 return NT_STATUS_OK;
5596 DBG_DEBUG("synthetic_pathref failed: %s\n",
5597 nt_errstr(status));
5598 goto fail;
5600 pathref = tmp;
5601 } else {
5602 pathref = smb_fname;
5604 status = vfs_fstreaminfo(pathref->fsp, talloc_tos(),
5605 &num_streams, &stream_info);
5607 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
5608 || NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
5609 DEBUG(10, ("no streams around\n"));
5610 TALLOC_FREE(frame);
5611 return NT_STATUS_OK;
5614 if (!NT_STATUS_IS_OK(status)) {
5615 DEBUG(10, ("vfs_fstreaminfo failed: %s\n",
5616 nt_errstr(status)));
5617 goto fail;
5620 DEBUG(10, ("open_streams_for_delete found %d streams\n",
5621 num_streams));
5623 if (num_streams == 0) {
5624 TALLOC_FREE(frame);
5625 return NT_STATUS_OK;
5628 streams = talloc_array(talloc_tos(), files_struct *, num_streams);
5629 if (streams == NULL) {
5630 DEBUG(0, ("talloc failed\n"));
5631 status = NT_STATUS_NO_MEMORY;
5632 goto fail;
5635 for (i=0; i<num_streams; i++) {
5636 struct smb_filename *smb_fname_cp;
5638 if (strequal(stream_info[i].name, "::$DATA")) {
5639 streams[i] = NULL;
5640 continue;
5643 smb_fname_cp = synthetic_smb_fname(talloc_tos(),
5644 smb_fname->base_name,
5645 stream_info[i].name,
5646 NULL,
5647 smb_fname->twrp,
5648 (smb_fname->flags &
5649 ~SMB_FILENAME_POSIX_PATH));
5650 if (smb_fname_cp == NULL) {
5651 status = NT_STATUS_NO_MEMORY;
5652 goto fail;
5655 status = openat_pathref_fsp(conn->cwd_fsp, smb_fname_cp);
5656 if (!NT_STATUS_IS_OK(status)) {
5657 DBG_DEBUG("Unable to open stream [%s]: %s\n",
5658 smb_fname_str_dbg(smb_fname_cp),
5659 nt_errstr(status));
5660 TALLOC_FREE(smb_fname_cp);
5661 break;
5664 status = SMB_VFS_CREATE_FILE(
5665 conn, /* conn */
5666 NULL, /* req */
5667 NULL, /* dirfsp */
5668 smb_fname_cp, /* fname */
5669 DELETE_ACCESS, /* access_mask */
5670 (FILE_SHARE_READ | /* share_access */
5671 FILE_SHARE_WRITE | FILE_SHARE_DELETE),
5672 FILE_OPEN, /* create_disposition*/
5673 0, /* create_options */
5674 FILE_ATTRIBUTE_NORMAL, /* file_attributes */
5675 0, /* oplock_request */
5676 NULL, /* lease */
5677 0, /* allocation_size */
5678 0, /* private_flags */
5679 NULL, /* sd */
5680 NULL, /* ea_list */
5681 &streams[i], /* result */
5682 NULL, /* pinfo */
5683 NULL, NULL); /* create context */
5685 if (!NT_STATUS_IS_OK(status)) {
5686 DEBUG(10, ("Could not open stream %s: %s\n",
5687 smb_fname_str_dbg(smb_fname_cp),
5688 nt_errstr(status)));
5690 TALLOC_FREE(smb_fname_cp);
5691 break;
5693 TALLOC_FREE(smb_fname_cp);
5697 * don't touch the variable "status" beyond this point :-)
5700 for (j = i-1 ; j >= 0; j--) {
5701 if (streams[j] == NULL) {
5702 continue;
5705 DEBUG(10, ("Closing stream # %d, %s\n", j,
5706 fsp_str_dbg(streams[j])));
5707 close_file_free(NULL, &streams[j], NORMAL_CLOSE);
5710 fail:
5711 TALLOC_FREE(frame);
5712 return status;
5715 /*********************************************************************
5716 Create a default ACL by inheriting from the parent. If no inheritance
5717 from the parent available, don't set anything. This will leave the actual
5718 permissions the new file or directory already got from the filesystem
5719 as the NT ACL when read.
5720 *********************************************************************/
5722 static NTSTATUS inherit_new_acl(files_struct *dirfsp, files_struct *fsp)
5724 TALLOC_CTX *frame = talloc_stackframe();
5725 struct security_descriptor *parent_desc = NULL;
5726 NTSTATUS status = NT_STATUS_OK;
5727 struct security_descriptor *psd = NULL;
5728 const struct dom_sid *owner_sid = NULL;
5729 const struct dom_sid *group_sid = NULL;
5730 uint32_t security_info_sent = (SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL);
5731 struct security_token *token = fsp->conn->session_info->security_token;
5732 bool inherit_owner =
5733 (lp_inherit_owner(SNUM(fsp->conn)) == INHERIT_OWNER_WINDOWS_AND_UNIX);
5734 bool inheritable_components = false;
5735 bool try_builtin_administrators = false;
5736 const struct dom_sid *BA_U_sid = NULL;
5737 const struct dom_sid *BA_G_sid = NULL;
5738 bool try_system = false;
5739 const struct dom_sid *SY_U_sid = NULL;
5740 const struct dom_sid *SY_G_sid = NULL;
5741 size_t size = 0;
5742 bool ok;
5744 status = SMB_VFS_FGET_NT_ACL(dirfsp,
5745 (SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL),
5746 frame,
5747 &parent_desc);
5748 if (!NT_STATUS_IS_OK(status)) {
5749 TALLOC_FREE(frame);
5750 return status;
5753 inheritable_components = sd_has_inheritable_components(parent_desc,
5754 fsp->fsp_flags.is_directory);
5756 if (!inheritable_components && !inherit_owner) {
5757 TALLOC_FREE(frame);
5758 /* Nothing to inherit and not setting owner. */
5759 return NT_STATUS_OK;
5762 /* Create an inherited descriptor from the parent. */
5764 if (DEBUGLEVEL >= 10) {
5765 DEBUG(10,("inherit_new_acl: parent acl for %s is:\n",
5766 fsp_str_dbg(fsp) ));
5767 NDR_PRINT_DEBUG(security_descriptor, parent_desc);
5770 /* Inherit from parent descriptor if "inherit owner" set. */
5771 if (inherit_owner) {
5772 owner_sid = parent_desc->owner_sid;
5773 group_sid = parent_desc->group_sid;
5776 if (owner_sid == NULL) {
5777 if (security_token_has_builtin_administrators(token)) {
5778 try_builtin_administrators = true;
5779 } else if (security_token_is_system(token)) {
5780 try_builtin_administrators = true;
5781 try_system = true;
5785 if (group_sid == NULL &&
5786 token->num_sids == PRIMARY_GROUP_SID_INDEX)
5788 if (security_token_is_system(token)) {
5789 try_builtin_administrators = true;
5790 try_system = true;
5794 if (try_builtin_administrators) {
5795 struct unixid ids = { .id = 0 };
5797 ok = sids_to_unixids(&global_sid_Builtin_Administrators, 1, &ids);
5798 if (ok) {
5799 switch (ids.type) {
5800 case ID_TYPE_BOTH:
5801 BA_U_sid = &global_sid_Builtin_Administrators;
5802 BA_G_sid = &global_sid_Builtin_Administrators;
5803 break;
5804 case ID_TYPE_UID:
5805 BA_U_sid = &global_sid_Builtin_Administrators;
5806 break;
5807 case ID_TYPE_GID:
5808 BA_G_sid = &global_sid_Builtin_Administrators;
5809 break;
5810 default:
5811 break;
5816 if (try_system) {
5817 struct unixid ids = { .id = 0 };
5819 ok = sids_to_unixids(&global_sid_System, 1, &ids);
5820 if (ok) {
5821 switch (ids.type) {
5822 case ID_TYPE_BOTH:
5823 SY_U_sid = &global_sid_System;
5824 SY_G_sid = &global_sid_System;
5825 break;
5826 case ID_TYPE_UID:
5827 SY_U_sid = &global_sid_System;
5828 break;
5829 case ID_TYPE_GID:
5830 SY_G_sid = &global_sid_System;
5831 break;
5832 default:
5833 break;
5838 if (owner_sid == NULL) {
5839 owner_sid = BA_U_sid;
5842 if (owner_sid == NULL) {
5843 owner_sid = SY_U_sid;
5846 if (group_sid == NULL) {
5847 group_sid = SY_G_sid;
5850 if (try_system && group_sid == NULL) {
5851 group_sid = BA_G_sid;
5854 if (owner_sid == NULL) {
5855 owner_sid = &token->sids[PRIMARY_USER_SID_INDEX];
5857 if (group_sid == NULL) {
5858 if (token->num_sids == PRIMARY_GROUP_SID_INDEX) {
5859 group_sid = &token->sids[PRIMARY_USER_SID_INDEX];
5860 } else {
5861 group_sid = &token->sids[PRIMARY_GROUP_SID_INDEX];
5865 status = se_create_child_secdesc(frame,
5866 &psd,
5867 &size,
5868 parent_desc,
5869 owner_sid,
5870 group_sid,
5871 fsp->fsp_flags.is_directory);
5872 if (!NT_STATUS_IS_OK(status)) {
5873 TALLOC_FREE(frame);
5874 return status;
5877 /* If inheritable_components == false,
5878 se_create_child_secdesc()
5879 creates a security descriptor with a NULL dacl
5880 entry, but with SEC_DESC_DACL_PRESENT. We need
5881 to remove that flag. */
5883 if (!inheritable_components) {
5884 security_info_sent &= ~SECINFO_DACL;
5885 psd->type &= ~SEC_DESC_DACL_PRESENT;
5888 if (DEBUGLEVEL >= 10) {
5889 DEBUG(10,("inherit_new_acl: child acl for %s is:\n",
5890 fsp_str_dbg(fsp) ));
5891 NDR_PRINT_DEBUG(security_descriptor, psd);
5894 if (inherit_owner) {
5895 /* We need to be root to force this. */
5896 become_root();
5898 status = SMB_VFS_FSET_NT_ACL(metadata_fsp(fsp),
5899 security_info_sent,
5900 psd);
5901 if (inherit_owner) {
5902 unbecome_root();
5904 TALLOC_FREE(frame);
5905 return status;
5909 * If we already have a lease, it must match the new file id. [MS-SMB2]
5910 * 3.3.5.9.8 speaks about INVALID_PARAMETER if an already used lease key is
5911 * used for a different file name.
5914 struct lease_match_state {
5915 /* Input parameters. */
5916 TALLOC_CTX *mem_ctx;
5917 const char *servicepath;
5918 const struct smb_filename *fname;
5919 bool file_existed;
5920 struct file_id id;
5921 /* Return parameters. */
5922 uint32_t num_file_ids;
5923 struct file_id *ids;
5924 NTSTATUS match_status;
5927 /*************************************************************
5928 File doesn't exist but this lease key+guid is already in use.
5930 This is only allowable in the dynamic share case where the
5931 service path must be different.
5933 There is a small race condition here in the multi-connection
5934 case where a client sends two create calls on different connections,
5935 where the file doesn't exist and one smbd creates the leases_db
5936 entry first, but this will get fixed by the multichannel cleanup
5937 when all identical client_guids get handled by a single smbd.
5938 **************************************************************/
5940 static void lease_match_parser_new_file(
5941 uint32_t num_files,
5942 const struct leases_db_file *files,
5943 struct lease_match_state *state)
5945 uint32_t i;
5947 for (i = 0; i < num_files; i++) {
5948 const struct leases_db_file *f = &files[i];
5949 if (strequal(state->servicepath, f->servicepath)) {
5950 state->match_status = NT_STATUS_INVALID_PARAMETER;
5951 return;
5955 /* Dynamic share case. Break leases on all other files. */
5956 state->match_status = leases_db_copy_file_ids(state->mem_ctx,
5957 num_files,
5958 files,
5959 &state->ids);
5960 if (!NT_STATUS_IS_OK(state->match_status)) {
5961 return;
5964 state->num_file_ids = num_files;
5965 state->match_status = NT_STATUS_OPLOCK_NOT_GRANTED;
5966 return;
5969 static void lease_match_parser(
5970 uint32_t num_files,
5971 const struct leases_db_file *files,
5972 void *private_data)
5974 struct lease_match_state *state =
5975 (struct lease_match_state *)private_data;
5976 uint32_t i;
5978 if (!state->file_existed) {
5980 * Deal with name mismatch or
5981 * possible dynamic share case separately
5982 * to make code clearer.
5984 lease_match_parser_new_file(num_files,
5985 files,
5986 state);
5987 return;
5990 /* File existed. */
5991 state->match_status = NT_STATUS_OK;
5993 for (i = 0; i < num_files; i++) {
5994 const struct leases_db_file *f = &files[i];
5996 /* Everything should be the same. */
5997 if (!file_id_equal(&state->id, &f->id)) {
5999 * The client asked for a lease on a
6000 * file that doesn't match the file_id
6001 * in the database.
6003 * Maybe this is a dynamic share, i.e.
6004 * a share where the servicepath is
6005 * different for different users (e.g.
6006 * the [HOMES] share.
6008 * If the servicepath is different, but the requested
6009 * file name + stream name is the same then this is
6010 * a dynamic share, the client is using the same share
6011 * name and doesn't know that the underlying servicepath
6012 * is different. It was expecting a lease on the
6013 * same file. Return NT_STATUS_OPLOCK_NOT_GRANTED
6014 * to break leases
6016 * Otherwise the client has messed up, or is
6017 * testing our error codes, so return
6018 * NT_STATUS_INVALID_PARAMETER.
6020 if (!strequal(f->servicepath, state->servicepath) &&
6021 strequal(f->base_name, state->fname->base_name) &&
6022 strequal(f->stream_name, state->fname->stream_name))
6025 * Name is the same but servicepath is
6026 * different, dynamic share. Break leases.
6028 state->match_status =
6029 NT_STATUS_OPLOCK_NOT_GRANTED;
6030 } else {
6031 state->match_status =
6032 NT_STATUS_INVALID_PARAMETER;
6034 break;
6036 if (!strequal(f->servicepath, state->servicepath)) {
6037 state->match_status = NT_STATUS_INVALID_PARAMETER;
6038 break;
6040 if (!strequal(f->base_name, state->fname->base_name)) {
6041 state->match_status = NT_STATUS_INVALID_PARAMETER;
6042 break;
6044 if (!strequal(f->stream_name, state->fname->stream_name)) {
6045 state->match_status = NT_STATUS_INVALID_PARAMETER;
6046 break;
6050 if (NT_STATUS_IS_OK(state->match_status)) {
6052 * Common case - just opening another handle on a
6053 * file on a non-dynamic share.
6055 return;
6058 if (NT_STATUS_EQUAL(state->match_status, NT_STATUS_INVALID_PARAMETER)) {
6059 /* Mismatched path. Error back to client. */
6060 return;
6064 * File id mismatch. Dynamic share case NT_STATUS_OPLOCK_NOT_GRANTED.
6065 * Don't allow leases.
6068 state->match_status = leases_db_copy_file_ids(state->mem_ctx,
6069 num_files,
6070 files,
6071 &state->ids);
6072 if (!NT_STATUS_IS_OK(state->match_status)) {
6073 return;
6076 state->num_file_ids = num_files;
6077 state->match_status = NT_STATUS_OPLOCK_NOT_GRANTED;
6078 return;
6081 struct lease_match_break_state {
6082 struct messaging_context *msg_ctx;
6083 const struct smb2_lease_key *lease_key;
6084 struct file_id id;
6086 bool found_lease;
6087 uint16_t version;
6088 uint16_t epoch;
6091 static bool lease_match_break_fn(
6092 struct share_mode_entry *e,
6093 void *private_data)
6095 struct lease_match_break_state *state = private_data;
6096 bool stale, equal;
6097 uint32_t e_lease_type = SMB2_LEASE_NONE;
6098 NTSTATUS status;
6100 stale = share_entry_stale_pid(e);
6101 if (stale) {
6102 return false;
6105 equal = smb2_lease_key_equal(&e->lease_key, state->lease_key);
6106 if (!equal) {
6107 return false;
6110 status = leases_db_get(
6111 &e->client_guid,
6112 &e->lease_key,
6113 &state->id,
6114 &e_lease_type, /* current_state */
6115 NULL, /* breaking */
6116 NULL, /* breaking_to_requested */
6117 NULL, /* breaking_to_required */
6118 &state->version, /* lease_version */
6119 &state->epoch); /* epoch */
6120 if (NT_STATUS_IS_OK(status)) {
6121 state->found_lease = true;
6122 } else {
6123 DBG_WARNING("Could not find version/epoch: %s\n",
6124 nt_errstr(status));
6125 return false;
6128 if (e_lease_type == SMB2_LEASE_NONE) {
6129 return false;
6131 send_break_message(state->msg_ctx, &state->id, e, SMB2_LEASE_NONE);
6134 * Windows 7 and 8 lease clients are broken in that they will
6135 * not respond to lease break requests whilst waiting for an
6136 * outstanding open request on that lease handle on the same
6137 * TCP connection, due to holding an internal inode lock.
6139 * This means we can't reschedule ourselves here, but must
6140 * return from the create.
6142 * Work around:
6144 * Send the breaks and then return SMB2_LEASE_NONE in the
6145 * lease handle to cause them to acknowledge the lease
6146 * break. Consultation with Microsoft engineering confirmed
6147 * this approach is safe.
6150 return false;
6153 static void lease_match_fid_fn(struct share_mode_lock *lck,
6154 void *private_data)
6156 bool ok;
6158 ok = share_mode_forall_leases(lck, lease_match_break_fn, private_data);
6159 if (!ok) {
6160 DBG_DEBUG("share_mode_forall_leases failed\n");
6164 static NTSTATUS lease_match(connection_struct *conn,
6165 struct smb_request *req,
6166 const struct smb2_lease_key *lease_key,
6167 const char *servicepath,
6168 const struct smb_filename *fname,
6169 uint16_t *p_version,
6170 uint16_t *p_epoch)
6172 struct smbd_server_connection *sconn = req->sconn;
6173 TALLOC_CTX *tos = talloc_tos();
6174 struct lease_match_state state = {
6175 .mem_ctx = tos,
6176 .servicepath = servicepath,
6177 .fname = fname,
6178 .match_status = NT_STATUS_OK
6180 uint32_t i;
6181 NTSTATUS status;
6183 state.file_existed = VALID_STAT(fname->st);
6184 if (state.file_existed) {
6185 state.id = vfs_file_id_from_sbuf(conn, &fname->st);
6188 status = leases_db_parse(&sconn->client->global->client_guid,
6189 lease_key, lease_match_parser, &state);
6190 if (!NT_STATUS_IS_OK(status)) {
6192 * Not found or error means okay: We can make the lease pass
6194 return NT_STATUS_OK;
6196 if (!NT_STATUS_EQUAL(state.match_status, NT_STATUS_OPLOCK_NOT_GRANTED)) {
6198 * Anything but NT_STATUS_OPLOCK_NOT_GRANTED, let the caller
6199 * deal with it.
6201 return state.match_status;
6204 /* We have to break all existing leases. */
6205 for (i = 0; i < state.num_file_ids; i++) {
6206 struct lease_match_break_state break_state = {
6207 .msg_ctx = conn->sconn->msg_ctx,
6208 .lease_key = lease_key,
6211 if (file_id_equal(&state.ids[i], &state.id)) {
6212 /* Don't need to break our own file. */
6213 continue;
6216 break_state.id = state.ids[i];
6218 status = share_mode_do_locked_vfs_denied(break_state.id,
6219 lease_match_fid_fn,
6220 &break_state);
6221 if (!NT_STATUS_IS_OK(status)) {
6222 /* Race condition - file already closed. */
6223 continue;
6226 if (break_state.found_lease) {
6227 *p_version = break_state.version;
6228 *p_epoch = break_state.epoch;
6232 * Ensure we don't grant anything more so we
6233 * never upgrade.
6235 return NT_STATUS_OPLOCK_NOT_GRANTED;
6239 * Wrapper around open_file_ntcreate and open_directory
6242 static NTSTATUS create_file_unixpath(connection_struct *conn,
6243 struct smb_request *req,
6244 struct files_struct *dirfsp,
6245 struct smb_filename *smb_fname,
6246 uint32_t access_mask,
6247 uint32_t share_access,
6248 uint32_t create_disposition,
6249 uint32_t create_options,
6250 uint32_t file_attributes,
6251 uint32_t oplock_request,
6252 const struct smb2_lease *lease,
6253 uint64_t allocation_size,
6254 uint32_t private_flags,
6255 struct security_descriptor *sd,
6256 struct ea_list *ea_list,
6258 files_struct **result,
6259 int *pinfo)
6261 struct smb2_lease none_lease;
6262 int info = FILE_WAS_OPENED;
6263 files_struct *base_fsp = NULL;
6264 files_struct *fsp = NULL;
6265 bool free_fsp_on_error = false;
6266 NTSTATUS status;
6267 int ret;
6268 struct smb_filename *parent_dir_fname = NULL;
6269 struct smb_filename *smb_fname_atname = NULL;
6271 DBG_DEBUG("access_mask = 0x%"PRIx32" "
6272 "file_attributes = 0x%"PRIx32" "
6273 "share_access = 0x%"PRIx32" "
6274 "create_disposition = 0x%"PRIx32" "
6275 "create_options = 0x%"PRIx32" "
6276 "oplock_request = 0x%"PRIx32" "
6277 "private_flags = 0x%"PRIx32" "
6278 "ea_list = %p, "
6279 "sd = %p, "
6280 "fname = %s\n",
6281 access_mask,
6282 file_attributes,
6283 share_access,
6284 create_disposition,
6285 create_options,
6286 oplock_request,
6287 private_flags,
6288 ea_list,
6290 smb_fname_str_dbg(smb_fname));
6292 if (create_options & FILE_OPEN_BY_FILE_ID) {
6293 status = NT_STATUS_NOT_SUPPORTED;
6294 goto fail;
6297 if (create_options & NTCREATEX_OPTIONS_INVALID_PARAM_MASK) {
6298 status = NT_STATUS_INVALID_PARAMETER;
6299 goto fail;
6302 if (!(create_options & FILE_OPEN_REPARSE_POINT) &&
6303 (smb_fname->fsp != NULL) && /* new files don't have an fsp */
6304 VALID_STAT(smb_fname->fsp->fsp_name->st))
6306 mode_t type = (smb_fname->fsp->fsp_name->st.st_ex_mode &
6307 S_IFMT);
6309 switch (type) {
6310 case S_IFREG:
6311 FALL_THROUGH;
6312 case S_IFDIR:
6313 break;
6314 case S_IFLNK:
6316 * We should never get this far with a symlink
6317 * "as such". Report as not existing.
6319 status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
6320 goto fail;
6321 default:
6322 status = NT_STATUS_IO_REPARSE_TAG_NOT_HANDLED;
6323 goto fail;
6327 if (req == NULL) {
6328 oplock_request |= INTERNAL_OPEN_ONLY;
6331 if (lease != NULL) {
6332 uint16_t epoch = lease->lease_epoch;
6333 uint16_t version = lease->lease_version;
6335 if (req == NULL) {
6336 DBG_WARNING("Got lease on internal open\n");
6337 status = NT_STATUS_INTERNAL_ERROR;
6338 goto fail;
6341 status = lease_match(conn,
6342 req,
6343 &lease->lease_key,
6344 conn->connectpath,
6345 smb_fname,
6346 &version,
6347 &epoch);
6348 if (NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) {
6349 /* Dynamic share file. No leases and update epoch... */
6350 none_lease = *lease;
6351 none_lease.lease_state = SMB2_LEASE_NONE;
6352 none_lease.lease_epoch = epoch;
6353 none_lease.lease_version = version;
6354 lease = &none_lease;
6355 } else if (!NT_STATUS_IS_OK(status)) {
6356 goto fail;
6360 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
6361 && (access_mask & DELETE_ACCESS)
6362 && !is_named_stream(smb_fname)) {
6364 * We can't open a file with DELETE access if any of the
6365 * streams is open without FILE_SHARE_DELETE
6367 status = open_streams_for_delete(conn, smb_fname);
6369 if (!NT_STATUS_IS_OK(status)) {
6370 goto fail;
6374 if (access_mask & SEC_FLAG_SYSTEM_SECURITY) {
6375 bool ok;
6377 ok = security_token_has_privilege(get_current_nttok(conn),
6378 SEC_PRIV_SECURITY);
6379 if (!ok) {
6380 DBG_DEBUG("open on %s failed - "
6381 "SEC_FLAG_SYSTEM_SECURITY denied.\n",
6382 smb_fname_str_dbg(smb_fname));
6383 status = NT_STATUS_PRIVILEGE_NOT_HELD;
6384 goto fail;
6387 if (conn_using_smb2(conn->sconn) &&
6388 (access_mask == SEC_FLAG_SYSTEM_SECURITY))
6391 * No other bits set. Windows SMB2 refuses this.
6392 * See smbtorture3 SMB2-SACL test.
6394 * Note this is an SMB2-only behavior,
6395 * smbtorture3 SMB1-SYSTEM-SECURITY already tests
6396 * that SMB1 allows this.
6398 status = NT_STATUS_ACCESS_DENIED;
6399 goto fail;
6404 * Files or directories can't be opened DELETE_ON_CLOSE without
6405 * delete access.
6406 * BUG: https://bugzilla.samba.org/show_bug.cgi?id=13358
6408 if ((create_options & FILE_DELETE_ON_CLOSE) &&
6409 ((access_mask & DELETE_ACCESS) == 0)) {
6410 status = NT_STATUS_INVALID_PARAMETER;
6411 goto fail;
6414 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
6415 && is_named_stream(smb_fname))
6417 uint32_t base_create_disposition;
6418 struct smb_filename *smb_fname_base = NULL;
6419 uint32_t base_privflags;
6421 if (create_options & FILE_DIRECTORY_FILE) {
6422 DBG_DEBUG("Can't open a stream as directory\n");
6423 status = NT_STATUS_NOT_A_DIRECTORY;
6424 goto fail;
6427 switch (create_disposition) {
6428 case FILE_OPEN:
6429 base_create_disposition = FILE_OPEN;
6430 break;
6431 default:
6432 base_create_disposition = FILE_OPEN_IF;
6433 break;
6436 smb_fname_base = cp_smb_filename_nostream(
6437 talloc_tos(), smb_fname);
6439 if (smb_fname_base == NULL) {
6440 status = NT_STATUS_NO_MEMORY;
6441 goto fail;
6445 * We may be creating the basefile as part of creating the
6446 * stream, so it's legal if the basefile doesn't exist at this
6447 * point, the create_file_unixpath() below will create it. But
6448 * if the basefile exists we want a handle so we can fstat() it.
6451 ret = vfs_stat(conn, smb_fname_base);
6452 if (ret == -1 && errno != ENOENT) {
6453 status = map_nt_error_from_unix(errno);
6454 TALLOC_FREE(smb_fname_base);
6455 goto fail;
6457 if (ret == 0) {
6458 status = openat_pathref_fsp(conn->cwd_fsp,
6459 smb_fname_base);
6460 if (!NT_STATUS_IS_OK(status)) {
6461 DBG_ERR("open_smb_fname_fsp [%s] failed: %s\n",
6462 smb_fname_str_dbg(smb_fname_base),
6463 nt_errstr(status));
6464 TALLOC_FREE(smb_fname_base);
6465 goto fail;
6469 * https://bugzilla.samba.org/show_bug.cgi?id=10229
6470 * We need to check if the requested access mask
6471 * could be used to open the underlying file (if
6472 * it existed), as we're passing in zero for the
6473 * access mask to the base filename.
6475 status = check_base_file_access(smb_fname_base->fsp,
6476 access_mask);
6478 if (!NT_STATUS_IS_OK(status)) {
6479 DEBUG(10, ("Permission check "
6480 "for base %s failed: "
6481 "%s\n", smb_fname->base_name,
6482 nt_errstr(status)));
6483 TALLOC_FREE(smb_fname_base);
6484 goto fail;
6488 base_privflags = NTCREATEX_FLAG_STREAM_BASEOPEN;
6490 /* Open the base file. */
6491 status = create_file_unixpath(conn,
6492 NULL,
6493 dirfsp,
6494 smb_fname_base,
6496 FILE_SHARE_READ
6497 | FILE_SHARE_WRITE
6498 | FILE_SHARE_DELETE,
6499 base_create_disposition,
6503 NULL,
6505 base_privflags,
6506 NULL,
6507 NULL,
6508 &base_fsp,
6509 NULL);
6510 TALLOC_FREE(smb_fname_base);
6512 if (!NT_STATUS_IS_OK(status)) {
6513 DEBUG(10, ("create_file_unixpath for base %s failed: "
6514 "%s\n", smb_fname->base_name,
6515 nt_errstr(status)));
6516 goto fail;
6520 if (smb_fname->fsp != NULL) {
6522 fsp = smb_fname->fsp;
6525 * We're about to use smb_fname->fsp for the fresh open.
6527 * Every fsp passed in via smb_fname->fsp already
6528 * holds a fsp->fsp_name. If it is already this
6529 * fsp->fsp_name that we got passed in as our input
6530 * argument smb_fname, these two are assumed to have
6531 * the same lifetime: Every fsp hangs of "conn", and
6532 * fsp->fsp_name is its talloc child.
6535 if (smb_fname != smb_fname->fsp->fsp_name) {
6537 * "smb_fname" is temporary in this case, but
6538 * the destructor of smb_fname would also tear
6539 * down the fsp we're about to use. Unlink
6540 * them from each other.
6542 smb_fname_fsp_unlink(smb_fname);
6545 * "fsp" is ours now
6547 free_fsp_on_error = true;
6550 status = fsp_bind_smb(fsp, req);
6551 if (!NT_STATUS_IS_OK(status)) {
6552 goto fail;
6555 if (fsp_is_alternate_stream(fsp)) {
6556 struct files_struct *tmp_base_fsp = fsp->base_fsp;
6558 fsp_set_base_fsp(fsp, NULL);
6560 fd_close(tmp_base_fsp);
6561 file_free(NULL, tmp_base_fsp);
6563 } else {
6565 * No fsp passed in that we can use, create one
6567 status = file_new(req, conn, &fsp);
6568 if(!NT_STATUS_IS_OK(status)) {
6569 goto fail;
6571 free_fsp_on_error = true;
6573 status = fsp_set_smb_fname(fsp, smb_fname);
6574 if (!NT_STATUS_IS_OK(status)) {
6575 goto fail;
6579 SMB_ASSERT(fsp->fsp_name->fsp != NULL);
6580 SMB_ASSERT(fsp->fsp_name->fsp == fsp);
6582 if (base_fsp) {
6584 * We're opening the stream element of a
6585 * base_fsp we already opened. Set up the
6586 * base_fsp pointer.
6588 fsp_set_base_fsp(fsp, base_fsp);
6591 if (dirfsp != NULL) {
6592 status = SMB_VFS_PARENT_PATHNAME(
6593 conn,
6594 talloc_tos(),
6595 smb_fname,
6596 &parent_dir_fname,
6597 &smb_fname_atname);
6598 if (!NT_STATUS_IS_OK(status)) {
6599 goto fail;
6601 } else {
6603 * Get a pathref on the parent. We can re-use this for
6604 * multiple calls to check parent ACLs etc. to avoid
6605 * pathname calls.
6607 status = parent_pathref(talloc_tos(),
6608 conn->cwd_fsp,
6609 smb_fname,
6610 &parent_dir_fname,
6611 &smb_fname_atname);
6612 if (!NT_STATUS_IS_OK(status)) {
6613 goto fail;
6616 dirfsp = parent_dir_fname->fsp;
6617 status = fsp_set_smb_fname(dirfsp, parent_dir_fname);
6618 if (!NT_STATUS_IS_OK(status)) {
6619 goto fail;
6624 * If it's a request for a directory open, deal with it separately.
6627 if (create_options & FILE_DIRECTORY_FILE) {
6629 if (create_options & FILE_NON_DIRECTORY_FILE) {
6630 status = NT_STATUS_INVALID_PARAMETER;
6631 goto fail;
6634 /* Can't open a temp directory. IFS kit test. */
6635 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
6636 (file_attributes & FILE_ATTRIBUTE_TEMPORARY)) {
6637 status = NT_STATUS_INVALID_PARAMETER;
6638 goto fail;
6642 * We will get a create directory here if the Win32
6643 * app specified a security descriptor in the
6644 * CreateDirectory() call.
6647 oplock_request = 0;
6648 status = open_directory(conn,
6649 req,
6650 access_mask,
6651 share_access,
6652 create_disposition,
6653 create_options,
6654 file_attributes,
6655 dirfsp->fsp_name,
6656 smb_fname_atname,
6658 &info,
6659 fsp);
6660 } else {
6663 * Ordinary file case.
6666 if (allocation_size) {
6667 fsp->initial_allocation_size = smb_roundup(fsp->conn,
6668 allocation_size);
6671 status = open_file_ntcreate(conn,
6672 req,
6673 access_mask,
6674 share_access,
6675 create_disposition,
6676 create_options,
6677 file_attributes,
6678 oplock_request,
6679 lease,
6680 private_flags,
6681 dirfsp->fsp_name,
6682 smb_fname_atname,
6683 &info,
6684 fsp);
6685 if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
6687 /* A stream open never opens a directory */
6689 if (base_fsp) {
6690 status = NT_STATUS_FILE_IS_A_DIRECTORY;
6691 goto fail;
6695 * Fail the open if it was explicitly a non-directory
6696 * file.
6699 if (create_options & FILE_NON_DIRECTORY_FILE) {
6700 status = NT_STATUS_FILE_IS_A_DIRECTORY;
6701 goto fail;
6704 oplock_request = 0;
6705 status = open_directory(conn,
6706 req,
6707 access_mask,
6708 share_access,
6709 create_disposition,
6710 create_options,
6711 file_attributes,
6712 dirfsp->fsp_name,
6713 smb_fname_atname,
6715 &info,
6716 fsp);
6720 if (!NT_STATUS_IS_OK(status)) {
6721 goto fail;
6724 fsp->fsp_flags.is_fsa = true;
6726 if ((ea_list != NULL) &&
6727 ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN))) {
6728 status = set_ea(conn, fsp, ea_list);
6729 if (!NT_STATUS_IS_OK(status)) {
6730 goto fail;
6734 if (!fsp->fsp_flags.is_directory &&
6735 S_ISDIR(fsp->fsp_name->st.st_ex_mode))
6737 status = NT_STATUS_ACCESS_DENIED;
6738 goto fail;
6741 /* Save the requested allocation size. */
6742 if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
6743 if ((allocation_size > (uint64_t)fsp->fsp_name->st.st_ex_size)
6744 && !(fsp->fsp_flags.is_directory))
6746 fsp->initial_allocation_size = smb_roundup(
6747 fsp->conn, allocation_size);
6748 if (vfs_allocate_file_space(
6749 fsp, fsp->initial_allocation_size) == -1) {
6750 status = NT_STATUS_DISK_FULL;
6751 goto fail;
6753 } else {
6754 fsp->initial_allocation_size = smb_roundup(
6755 fsp->conn, (uint64_t)fsp->fsp_name->st.st_ex_size);
6757 } else {
6758 fsp->initial_allocation_size = 0;
6761 if ((info == FILE_WAS_CREATED) &&
6762 !S_ISDIR(fsp->fsp_name->st.st_ex_mode) &&
6763 lp_nt_acl_support(SNUM(conn)) &&
6764 !fsp_is_alternate_stream(fsp)) {
6765 status = apply_new_nt_acl(dirfsp, fsp, sd);
6766 if (!NT_STATUS_IS_OK(status)) {
6767 DBG_WARNING("apply_new_nt_acl(): failed for %s with %s\n",
6768 fsp_str_dbg(fsp), nt_errstr(status));
6769 goto fail;
6773 if ((conn->fs_capabilities & FILE_FILE_COMPRESSION)
6774 && (create_options & FILE_NO_COMPRESSION)
6775 && (info == FILE_WAS_CREATED)) {
6776 status = SMB_VFS_SET_COMPRESSION(conn, fsp, fsp,
6777 COMPRESSION_FORMAT_NONE);
6778 if (!NT_STATUS_IS_OK(status)) {
6779 DEBUG(1, ("failed to disable compression: %s\n",
6780 nt_errstr(status)));
6784 DEBUG(10, ("create_file_unixpath: info=%d\n", info));
6786 *result = fsp;
6787 if (pinfo != NULL) {
6788 *pinfo = info;
6791 smb_fname->st = fsp->fsp_name->st;
6793 TALLOC_FREE(parent_dir_fname);
6795 return NT_STATUS_OK;
6797 fail:
6798 DEBUG(10, ("create_file_unixpath: %s\n", nt_errstr(status)));
6800 if (fsp != NULL) {
6802 * The close_file below will close
6803 * fsp->base_fsp.
6805 base_fsp = NULL;
6806 close_file_smb(req, fsp, ERROR_CLOSE);
6807 if (free_fsp_on_error) {
6808 file_free(req, fsp);
6809 fsp = NULL;
6812 if (base_fsp != NULL) {
6813 close_file_free(req, &base_fsp, ERROR_CLOSE);
6816 TALLOC_FREE(parent_dir_fname);
6818 return status;
6821 NTSTATUS create_file_default(connection_struct *conn,
6822 struct smb_request *req,
6823 struct files_struct *dirfsp,
6824 struct smb_filename *smb_fname,
6825 uint32_t access_mask,
6826 uint32_t share_access,
6827 uint32_t create_disposition,
6828 uint32_t create_options,
6829 uint32_t file_attributes,
6830 uint32_t oplock_request,
6831 const struct smb2_lease *lease,
6832 uint64_t allocation_size,
6833 uint32_t private_flags,
6834 struct security_descriptor *sd,
6835 struct ea_list *ea_list,
6836 files_struct **result,
6837 int *pinfo,
6838 const struct smb2_create_blobs *in_context_blobs,
6839 struct smb2_create_blobs *out_context_blobs)
6841 int info = FILE_WAS_OPENED;
6842 files_struct *fsp = NULL;
6843 NTSTATUS status;
6844 bool stream_name = false;
6845 struct smb2_create_blob *posx = NULL;
6847 DBG_DEBUG("access_mask = 0x%" PRIu32
6848 " file_attributes = 0x%" PRIu32
6849 " share_access = 0x%" PRIu32
6850 " create_disposition = 0x%" PRIu32
6851 " create_options = 0x%" PRIu32
6852 " oplock_request = 0x%" PRIu32
6853 " private_flags = 0x%" PRIu32
6854 " ea_list = %p, sd = %p, fname = %s\n",
6855 access_mask,
6856 file_attributes,
6857 share_access,
6858 create_disposition,
6859 create_options,
6860 oplock_request,
6861 private_flags,
6862 ea_list,
6864 smb_fname_str_dbg(smb_fname));
6866 if (req != NULL) {
6868 * Remember the absolute time of the original request
6869 * with this mid. We'll use it later to see if this
6870 * has timed out.
6872 get_deferred_open_message_state(req, &req->request_time, NULL);
6876 * Check to see if this is a mac fork of some kind.
6879 stream_name = is_ntfs_stream_smb_fname(smb_fname);
6880 if (stream_name) {
6881 enum FAKE_FILE_TYPE fake_file_type;
6883 fake_file_type = is_fake_file(smb_fname);
6885 if (req != NULL && fake_file_type != FAKE_FILE_TYPE_NONE) {
6888 * Here we go! support for changing the disk quotas
6889 * --metze
6891 * We need to fake up to open this MAGIC QUOTA file
6892 * and return a valid FID.
6894 * w2k close this file directly after opening xp
6895 * also tries a QUERY_FILE_INFO on the file and then
6896 * close it
6898 status = open_fake_file(req, conn, req->vuid,
6899 fake_file_type, smb_fname,
6900 access_mask, &fsp);
6901 if (!NT_STATUS_IS_OK(status)) {
6902 goto fail;
6905 ZERO_STRUCT(smb_fname->st);
6906 goto done;
6909 if (!(conn->fs_capabilities & FILE_NAMED_STREAMS)) {
6910 status = NT_STATUS_OBJECT_NAME_INVALID;
6911 goto fail;
6915 if (is_ntfs_default_stream_smb_fname(smb_fname)) {
6916 int ret;
6917 /* We have to handle this error here. */
6918 if (create_options & FILE_DIRECTORY_FILE) {
6919 status = NT_STATUS_NOT_A_DIRECTORY;
6920 goto fail;
6922 ret = vfs_stat(conn, smb_fname);
6923 if (ret == 0 && VALID_STAT_OF_DIR(smb_fname->st)) {
6924 status = NT_STATUS_FILE_IS_A_DIRECTORY;
6925 goto fail;
6929 posx = smb2_create_blob_find(
6930 in_context_blobs, SMB2_CREATE_TAG_POSIX);
6931 if (posx != NULL) {
6932 uint32_t wire_mode_bits = 0;
6933 mode_t mode_bits = 0;
6934 SMB_STRUCT_STAT sbuf = { 0 };
6935 enum perm_type ptype =
6936 (create_options & FILE_DIRECTORY_FILE) ?
6937 PERM_NEW_DIR : PERM_NEW_FILE;
6939 if (posx->data.length != 4) {
6940 status = NT_STATUS_INVALID_PARAMETER;
6941 goto fail;
6944 wire_mode_bits = IVAL(posx->data.data, 0);
6945 status = unix_perms_from_wire(
6946 conn, &sbuf, wire_mode_bits, ptype, &mode_bits);
6947 if (!NT_STATUS_IS_OK(status)) {
6948 goto fail;
6951 * Remove type info from mode, leaving only the
6952 * permissions and setuid/gid bits.
6954 mode_bits &= ~S_IFMT;
6956 file_attributes = (FILE_FLAG_POSIX_SEMANTICS | mode_bits);
6959 status = create_file_unixpath(conn,
6960 req,
6961 dirfsp,
6962 smb_fname,
6963 access_mask,
6964 share_access,
6965 create_disposition,
6966 create_options,
6967 file_attributes,
6968 oplock_request,
6969 lease,
6970 allocation_size,
6971 private_flags,
6973 ea_list,
6974 &fsp,
6975 &info);
6976 if (!NT_STATUS_IS_OK(status)) {
6977 goto fail;
6980 done:
6981 DEBUG(10, ("create_file: info=%d\n", info));
6983 *result = fsp;
6984 if (pinfo != NULL) {
6985 *pinfo = info;
6987 return NT_STATUS_OK;
6989 fail:
6990 DEBUG(10, ("create_file: %s\n", nt_errstr(status)));
6992 if (fsp != NULL) {
6993 close_file_free(req, &fsp, ERROR_CLOSE);
6995 return status;