ctdb-server: Remove duplicate logic
[samba4-gss.git] / source3 / smbd / open.c
bloba05ccb6b7f3021efae7fffeb74ec857b91662387
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 "source3/lib/server_id_watch.h"
42 #include "locking/leases_db.h"
43 #include "librpc/gen_ndr/ndr_leases_db.h"
44 #include "lib/util/time_basic.h"
45 #include "source3/smbd/dir.h"
47 #if defined(HAVE_LINUX_MAGIC_H)
48 #include <linux/magic.h>
49 #endif
51 static NTSTATUS inherit_new_acl(files_struct *dirfsp, files_struct *fsp);
53 extern const struct generic_mapping file_generic_mapping;
55 struct deferred_open_record {
56 struct smbXsrv_connection *xconn;
57 uint64_t mid;
59 bool async_open;
62 * Timer for async opens, needed because they don't use a watch on
63 * a locking.tdb record. This is currently only used for real async
64 * opens and just terminates smbd if the async open times out.
66 struct tevent_timer *te;
69 * For the samba kernel oplock case we use both a timeout and
70 * a watch on locking.tdb. This way in case it's smbd holding
71 * the kernel oplock we get directly notified for the retry
72 * once the kernel oplock is properly broken. Store the req
73 * here so that it can be timely discarded once the timer
74 * above fires.
76 struct tevent_req *watch_req;
79 /****************************************************************************
80 If the requester wanted DELETE_ACCESS and was rejected because
81 the file ACL didn't include DELETE_ACCESS, see if the parent ACL
82 overrides this.
83 ****************************************************************************/
85 static bool parent_override_delete(connection_struct *conn,
86 struct files_struct *dirfsp,
87 const struct smb_filename *smb_fname,
88 uint32_t access_mask,
89 uint32_t rejected_mask)
91 if ((access_mask & DELETE_ACCESS) && (rejected_mask & DELETE_ACCESS)) {
92 bool ok;
93 ok = can_delete_file_in_directory(conn, dirfsp, smb_fname);
94 return ok;
97 return false;
100 /****************************************************************************
101 Check if we have open rights.
102 ****************************************************************************/
104 static NTSTATUS smbd_check_access_rights_fname(
105 struct connection_struct *conn,
106 const struct smb_filename *smb_fname,
107 bool use_privs,
108 uint32_t access_mask,
109 uint32_t do_not_check_mask)
111 uint32_t rejected_share_access;
112 uint32_t effective_access;
114 rejected_share_access = access_mask & ~(conn->share_access);
116 if (rejected_share_access) {
117 DBG_DEBUG("rejected share access 0x%"PRIx32" on "
118 "%s (0x%"PRIx32")\n",
119 access_mask,
120 smb_fname_str_dbg(smb_fname),
121 rejected_share_access);
122 return NT_STATUS_ACCESS_DENIED;
125 effective_access = access_mask & ~do_not_check_mask;
126 if (effective_access == 0) {
127 DBG_DEBUG("do_not_check_mask override on %s. Granting 0x%x for free.\n",
128 smb_fname_str_dbg(smb_fname),
129 (unsigned int)access_mask);
130 return NT_STATUS_OK;
133 if (!use_privs && get_current_uid(conn) == (uid_t)0) {
134 /* I'm sorry sir, I didn't know you were root... */
135 DBG_DEBUG("root override on %s. Granting 0x%x\n",
136 smb_fname_str_dbg(smb_fname),
137 (unsigned int)access_mask);
138 return NT_STATUS_OK;
141 if ((access_mask & DELETE_ACCESS) &&
142 !lp_acl_check_permissions(SNUM(conn)))
144 DBG_DEBUG("Not checking ACL on DELETE_ACCESS on file %s. "
145 "Granting 0x%"PRIx32"\n",
146 smb_fname_str_dbg(smb_fname),
147 access_mask);
148 return NT_STATUS_OK;
151 if (access_mask == DELETE_ACCESS &&
152 VALID_STAT(smb_fname->st) &&
153 S_ISLNK(smb_fname->st.st_ex_mode))
155 /* We can always delete a symlink. */
156 DBG_DEBUG("Not checking ACL on DELETE_ACCESS on symlink %s.\n",
157 smb_fname_str_dbg(smb_fname));
158 return NT_STATUS_OK;
161 return NT_STATUS_MORE_PROCESSING_REQUIRED;
164 static NTSTATUS smbd_check_access_rights_sd(
165 struct connection_struct *conn,
166 struct files_struct *dirfsp,
167 const struct smb_filename *smb_fname,
168 struct security_descriptor *sd,
169 bool use_privs,
170 uint32_t access_mask,
171 uint32_t do_not_check_mask)
173 uint32_t rejected_mask = access_mask;
174 NTSTATUS status;
176 if (sd == NULL) {
177 goto access_denied;
180 status = se_file_access_check(sd,
181 get_current_nttok(conn),
182 use_privs,
183 (access_mask & ~do_not_check_mask),
184 &rejected_mask);
186 DBG_DEBUG("File [%s] requesting [0x%"PRIx32"] "
187 "returning [0x%"PRIx32"] (%s)\n",
188 smb_fname_str_dbg(smb_fname),
189 access_mask,
190 rejected_mask,
191 nt_errstr(status));
193 if (!NT_STATUS_IS_OK(status)) {
194 if (DEBUGLEVEL >= 10) {
195 DBG_DEBUG("acl for %s is:\n",
196 smb_fname_str_dbg(smb_fname));
197 NDR_PRINT_DEBUG(security_descriptor, sd);
201 TALLOC_FREE(sd);
203 if (NT_STATUS_IS_OK(status) ||
204 !NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED))
206 return status;
209 /* Here we know status == NT_STATUS_ACCESS_DENIED. */
211 access_denied:
213 if ((access_mask & FILE_WRITE_ATTRIBUTES) &&
214 (rejected_mask & FILE_WRITE_ATTRIBUTES) &&
215 !lp_store_dos_attributes(SNUM(conn)) &&
216 (lp_map_readonly(SNUM(conn)) ||
217 lp_map_archive(SNUM(conn)) ||
218 lp_map_hidden(SNUM(conn)) ||
219 lp_map_system(SNUM(conn))))
221 rejected_mask &= ~FILE_WRITE_ATTRIBUTES;
223 DBG_DEBUG("overrode FILE_WRITE_ATTRIBUTES on file %s\n",
224 smb_fname_str_dbg(smb_fname));
227 if (parent_override_delete(conn,
228 dirfsp,
229 smb_fname,
230 access_mask,
231 rejected_mask))
234 * Were we trying to do an open for delete and didn't get DELETE
235 * access. Check if the directory allows DELETE_CHILD.
236 * See here:
237 * http://blogs.msdn.com/oldnewthing/archive/2004/06/04/148426.aspx
238 * for details.
241 rejected_mask &= ~DELETE_ACCESS;
243 DBG_DEBUG("Overrode DELETE_ACCESS on file %s\n",
244 smb_fname_str_dbg(smb_fname));
247 if (rejected_mask != 0) {
248 return NT_STATUS_ACCESS_DENIED;
250 return NT_STATUS_OK;
253 NTSTATUS smbd_check_access_rights_fsp(struct files_struct *dirfsp,
254 struct files_struct *fsp,
255 bool use_privs,
256 uint32_t access_mask)
258 struct security_descriptor *sd = NULL;
259 uint32_t do_not_check_mask = 0;
260 NTSTATUS status;
262 /* Cope with fake/printer fsp's. */
263 if (fsp->fake_file_handle != NULL || fsp->print_file != NULL) {
264 if ((fsp->access_mask & access_mask) != access_mask) {
265 return NT_STATUS_ACCESS_DENIED;
267 return NT_STATUS_OK;
270 if (fsp_get_pathref_fd(fsp) == -1) {
272 * This is a POSIX open on a symlink. For the pathname
273 * version of this function we used to return the st_mode
274 * bits turned into an NT ACL. For a symlink the mode bits
275 * are always rwxrwxrwx which means the pathname version always
276 * returned NT_STATUS_OK for a symlink. For the handle reference
277 * to a symlink use the handle access bits.
279 if ((fsp->access_mask & access_mask) != access_mask) {
280 return NT_STATUS_ACCESS_DENIED;
282 return NT_STATUS_OK;
286 * If we can access the path to this file, by
287 * default we have FILE_READ_ATTRIBUTES from the
288 * containing directory. See the section:
289 * "Algorithm to Check Access to an Existing File"
290 * in MS-FSA.pdf.
292 * se_file_access_check() also takes care of
293 * owner WRITE_DAC and READ_CONTROL.
295 do_not_check_mask = FILE_READ_ATTRIBUTES;
298 * Samba 3.6 and earlier granted execute access even
299 * if the ACL did not contain execute rights.
300 * Samba 4.0 is more correct and checks it.
301 * The compatibility mode allows one to skip this check
302 * to smoothen upgrades.
304 if (lp_acl_allow_execute_always(SNUM(fsp->conn))) {
305 do_not_check_mask |= FILE_EXECUTE;
308 status = smbd_check_access_rights_fname(fsp->conn,
309 fsp->fsp_name,
310 use_privs,
311 access_mask,
312 do_not_check_mask);
313 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
314 return status;
317 status = SMB_VFS_FGET_NT_ACL(metadata_fsp(fsp),
318 (SECINFO_OWNER |
319 SECINFO_GROUP |
320 SECINFO_DACL),
321 talloc_tos(),
322 &sd);
323 if (!NT_STATUS_IS_OK(status)) {
324 DBG_DEBUG("Could not get acl on %s: %s\n",
325 fsp_str_dbg(fsp),
326 nt_errstr(status));
327 return status;
330 return smbd_check_access_rights_sd(fsp->conn,
331 dirfsp,
332 fsp->fsp_name,
334 use_privs,
335 access_mask,
336 do_not_check_mask);
340 * Given an fsp that represents a parent directory,
341 * check if the requested access can be granted.
343 NTSTATUS check_parent_access_fsp(struct files_struct *fsp,
344 uint32_t access_mask)
346 NTSTATUS status;
347 struct security_descriptor *parent_sd = NULL;
348 uint32_t access_granted = 0;
349 uint32_t name_hash;
350 bool delete_on_close_set;
351 TALLOC_CTX *frame = talloc_stackframe();
353 if (get_current_uid(fsp->conn) == (uid_t)0) {
354 /* I'm sorry sir, I didn't know you were root... */
355 DBG_DEBUG("root override on %s. Granting 0x%x\n",
356 fsp_str_dbg(fsp),
357 (unsigned int)access_mask);
358 status = NT_STATUS_OK;
359 goto out;
362 status = SMB_VFS_FGET_NT_ACL(fsp,
363 (SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL),
364 frame,
365 &parent_sd);
367 if (!NT_STATUS_IS_OK(status)) {
368 DBG_INFO("SMB_VFS_FGET_NT_ACL failed for "
369 "%s with error %s\n",
370 fsp_str_dbg(fsp),
371 nt_errstr(status));
372 goto out;
376 * If we can access the path to this file, by
377 * default we have FILE_READ_ATTRIBUTES from the
378 * containing directory. See the section:
379 * "Algorithm to Check Access to an Existing File"
380 * in MS-FSA.pdf.
382 * se_file_access_check() also takes care of
383 * owner WRITE_DAC and READ_CONTROL.
385 status = se_file_access_check(parent_sd,
386 get_current_nttok(fsp->conn),
387 false,
388 (access_mask & ~FILE_READ_ATTRIBUTES),
389 &access_granted);
390 if(!NT_STATUS_IS_OK(status)) {
391 DBG_INFO("access check "
392 "on directory %s for mask 0x%x returned (0x%x) %s\n",
393 fsp_str_dbg(fsp),
394 access_mask,
395 access_granted,
396 nt_errstr(status));
397 goto out;
400 if (!(access_mask & (SEC_DIR_ADD_FILE | SEC_DIR_ADD_SUBDIR))) {
401 status = NT_STATUS_OK;
402 goto out;
404 if (!lp_check_parent_directory_delete_on_close(SNUM(fsp->conn))) {
405 status = NT_STATUS_OK;
406 goto out;
409 /* Check if the directory has delete-on-close set */
410 status = file_name_hash(fsp->conn,
411 fsp->fsp_name->base_name,
412 &name_hash);
413 if (!NT_STATUS_IS_OK(status)) {
414 goto out;
417 get_file_infos(fsp->file_id, name_hash, &delete_on_close_set, NULL);
418 if (delete_on_close_set) {
419 status = NT_STATUS_DELETE_PENDING;
420 goto out;
423 status = NT_STATUS_OK;
425 out:
426 TALLOC_FREE(frame);
427 return status;
430 /****************************************************************************
431 Ensure when opening a base file for a stream open that we have permissions
432 to do so given the access mask on the base file.
433 ****************************************************************************/
435 static NTSTATUS check_base_file_access(struct files_struct *fsp,
436 uint32_t access_mask)
438 NTSTATUS status;
440 status = smbd_calculate_access_mask_fsp(fsp->conn->cwd_fsp,
441 fsp,
442 false,
443 access_mask,
444 &access_mask);
445 if (!NT_STATUS_IS_OK(status)) {
446 DEBUG(10, ("smbd_calculate_access_mask "
447 "on file %s returned %s\n",
448 fsp_str_dbg(fsp),
449 nt_errstr(status)));
450 return status;
453 if (access_mask & (FILE_WRITE_DATA|FILE_APPEND_DATA)) {
454 uint32_t dosattrs;
455 if (!CAN_WRITE(fsp->conn)) {
456 return NT_STATUS_ACCESS_DENIED;
458 dosattrs = fdos_mode(fsp);
459 if (dosattrs & FILE_ATTRIBUTE_READONLY) {
460 return NT_STATUS_ACCESS_DENIED;
464 return smbd_check_access_rights_fsp(fsp->conn->cwd_fsp,
465 fsp,
466 false,
467 access_mask);
470 static NTSTATUS chdir_below_conn(
471 TALLOC_CTX *mem_ctx,
472 connection_struct *conn,
473 const char *connectpath,
474 size_t connectpath_len,
475 struct smb_filename *dir_fname,
476 struct smb_filename **_oldwd_fname)
478 struct smb_filename *oldwd_fname = NULL;
479 struct smb_filename *smb_fname_dot = NULL;
480 struct smb_filename *real_fname = NULL;
481 const char *relative = NULL;
482 NTSTATUS status;
483 int ret;
484 bool ok;
486 if (!ISDOT(dir_fname->base_name)) {
488 oldwd_fname = vfs_GetWd(talloc_tos(), conn);
489 if (oldwd_fname == NULL) {
490 status = map_nt_error_from_unix(errno);
491 goto out;
494 /* Pin parent directory in place. */
495 ret = vfs_ChDir(conn, dir_fname);
496 if (ret == -1) {
497 status = map_nt_error_from_unix(errno);
498 DBG_DEBUG("chdir to %s failed: %s\n",
499 dir_fname->base_name,
500 strerror(errno));
501 goto out;
505 smb_fname_dot = synthetic_smb_fname(
506 talloc_tos(),
507 ".",
508 NULL,
509 NULL,
510 dir_fname->twrp,
511 dir_fname->flags);
512 if (smb_fname_dot == NULL) {
513 status = NT_STATUS_NO_MEMORY;
514 goto out;
517 real_fname = SMB_VFS_REALPATH(conn, talloc_tos(), smb_fname_dot);
518 if (real_fname == NULL) {
519 status = map_nt_error_from_unix(errno);
520 DBG_DEBUG("realpath in %s failed: %s\n",
521 dir_fname->base_name,
522 strerror(errno));
523 goto out;
525 TALLOC_FREE(smb_fname_dot);
527 ok = subdir_of(connectpath,
528 connectpath_len,
529 real_fname->base_name,
530 &relative);
531 if (ok) {
532 TALLOC_FREE(real_fname);
533 *_oldwd_fname = oldwd_fname;
534 return NT_STATUS_OK;
537 DBG_NOTICE("Bad access attempt: %s is a symlink "
538 "outside the share path\n"
539 "conn_rootdir =%s\n"
540 "resolved_name=%s\n",
541 dir_fname->base_name,
542 connectpath,
543 real_fname->base_name);
544 TALLOC_FREE(real_fname);
546 status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
548 out:
549 if (oldwd_fname != NULL) {
550 ret = vfs_ChDir(conn, oldwd_fname);
551 SMB_ASSERT(ret == 0);
552 TALLOC_FREE(oldwd_fname);
555 return status;
559 * Get the symlink target of dirfsp/symlink_name, making sure the
560 * target is below connection_path.
563 static NTSTATUS symlink_target_below_conn(
564 TALLOC_CTX *mem_ctx,
565 const char *connection_path,
566 struct files_struct *fsp,
567 struct files_struct *dirfsp,
568 struct smb_filename *symlink_name,
569 char **_target)
571 char *target = NULL;
572 char *absolute = NULL;
573 NTSTATUS status;
575 if (fsp_get_pathref_fd(fsp) != -1) {
577 * fsp is an O_PATH open, Linux does a "freadlink"
578 * with an empty name argument to readlinkat
580 status = readlink_talloc(talloc_tos(), fsp, NULL, &target);
581 } else {
582 status = readlink_talloc(
583 talloc_tos(), dirfsp, symlink_name, &target);
586 if (!NT_STATUS_IS_OK(status)) {
587 return status;
590 status = safe_symlink_target_path(talloc_tos(),
591 connection_path,
592 dirfsp->fsp_name->base_name,
593 target,
595 &absolute);
596 if (!NT_STATUS_IS_OK(status)) {
597 DBG_DEBUG("safe_symlink_target_path() failed: %s\n",
598 nt_errstr(status));
599 return status;
602 if (absolute[0] == '\0') {
604 * special case symlink to share root: "." is our
605 * share root filename
607 TALLOC_FREE(absolute);
608 absolute = talloc_strdup(talloc_tos(), ".");
609 if (absolute == NULL) {
610 return NT_STATUS_NO_MEMORY;
614 *_target = absolute;
615 return NT_STATUS_OK;
618 /****************************************************************************
619 Non-widelink open.
620 ****************************************************************************/
622 static NTSTATUS non_widelink_open(const struct files_struct *dirfsp,
623 files_struct *fsp,
624 struct smb_filename *smb_fname,
625 const struct vfs_open_how *_how)
627 struct connection_struct *conn = fsp->conn;
628 const char *connpath = SMB_VFS_CONNECTPATH(conn, dirfsp, smb_fname);
629 size_t connpath_len;
630 NTSTATUS status = NT_STATUS_OK;
631 int fd = -1;
632 char *orig_smb_fname_base = smb_fname->base_name;
633 struct smb_filename *orig_fsp_name = fsp->fsp_name;
634 struct smb_filename *smb_fname_rel = NULL;
635 struct smb_filename *oldwd_fname = NULL;
636 struct smb_filename *parent_dir_fname = NULL;
637 struct vfs_open_how how = *_how;
638 char *target = NULL;
639 size_t link_depth = 0;
640 int ret;
642 SMB_ASSERT(!fsp_is_alternate_stream(fsp));
644 if (connpath == NULL) {
646 * This can happen with shadow_copy2 if the snapshot
647 * path is not found
649 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
651 connpath_len = strlen(connpath);
653 again:
654 if (smb_fname->base_name[0] == '/') {
655 int cmp = strcmp(connpath, smb_fname->base_name);
656 if (cmp == 0) {
657 smb_fname->base_name = talloc_strdup(smb_fname, "");
658 if (smb_fname->base_name == NULL) {
659 status = NT_STATUS_NO_MEMORY;
660 goto out;
665 if (dirfsp == conn->cwd_fsp) {
667 status = SMB_VFS_PARENT_PATHNAME(fsp->conn,
668 talloc_tos(),
669 smb_fname,
670 &parent_dir_fname,
671 &smb_fname_rel);
672 if (!NT_STATUS_IS_OK(status)) {
673 goto out;
676 status = chdir_below_conn(
677 talloc_tos(),
678 conn,
679 connpath,
680 connpath_len,
681 parent_dir_fname,
682 &oldwd_fname);
683 if (!NT_STATUS_IS_OK(status)) {
684 goto out;
687 /* Setup fsp->fsp_name to be relative to cwd */
688 fsp->fsp_name = smb_fname_rel;
689 } else {
691 * fsp->fsp_name is unchanged as it is already correctly
692 * relative to dirfsp.
694 smb_fname_rel = smb_fname;
699 * Assert nobody can step in with a symlink on the
700 * path, there is no path anymore and we'll use
701 * O_NOFOLLOW to open.
703 char *slash = strchr_m(smb_fname_rel->base_name, '/');
704 SMB_ASSERT(slash == NULL);
707 how.flags |= O_NOFOLLOW;
709 fd = SMB_VFS_OPENAT(conn,
710 dirfsp,
711 smb_fname_rel,
712 fsp,
713 &how);
714 fsp_set_fd(fsp, fd); /* This preserves errno */
716 if (fd == -1) {
717 status = map_nt_error_from_unix(errno);
719 if (errno == ENOENT) {
720 goto out;
724 * ENOENT makes it worthless retrying with a
725 * stat, we know for sure the file does not
726 * exist. For everything else we want to know
727 * what's there.
729 ret = SMB_VFS_FSTATAT(
730 fsp->conn,
731 dirfsp,
732 smb_fname_rel,
733 &fsp->fsp_name->st,
734 AT_SYMLINK_NOFOLLOW);
736 if (ret == -1) {
738 * Keep the original error. Otherwise we would
739 * mask for example EROFS for open(O_CREAT),
740 * turning it into ENOENT.
742 goto out;
744 } else {
745 ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st);
748 if (ret == -1) {
749 status = map_nt_error_from_unix(errno);
750 DBG_DEBUG("fstat[at](%s) failed: %s\n",
751 smb_fname_str_dbg(smb_fname),
752 strerror(errno));
753 goto out;
756 fsp->fsp_flags.is_directory = S_ISDIR(fsp->fsp_name->st.st_ex_mode);
757 orig_fsp_name->st = fsp->fsp_name->st;
759 if (!S_ISLNK(fsp->fsp_name->st.st_ex_mode)) {
760 goto out;
764 * Found a symlink to follow in user space
767 if (fsp->fsp_name->flags & SMB_FILENAME_POSIX_PATH) {
768 /* Never follow symlinks on posix open. */
769 status = NT_STATUS_STOPPED_ON_SYMLINK;
770 goto out;
772 if (!lp_follow_symlinks(SNUM(conn))) {
773 /* Explicitly no symlinks. */
774 status = NT_STATUS_STOPPED_ON_SYMLINK;
775 goto out;
778 link_depth += 1;
779 if (link_depth >= 40) {
780 status = NT_STATUS_STOPPED_ON_SYMLINK;
781 goto out;
784 fsp->fsp_name = orig_fsp_name;
786 status = symlink_target_below_conn(
787 talloc_tos(),
788 connpath,
789 fsp,
790 discard_const_p(files_struct, dirfsp),
791 smb_fname_rel,
792 &target);
794 if (!NT_STATUS_IS_OK(status)) {
795 DBG_DEBUG("symlink_target_below_conn() failed: %s\n",
796 nt_errstr(status));
797 goto out;
801 * Close what openat(O_PATH) potentially left behind
803 fd_close(fsp);
805 if (smb_fname->base_name != orig_smb_fname_base) {
806 TALLOC_FREE(smb_fname->base_name);
808 smb_fname->base_name = target;
810 if (oldwd_fname != NULL) {
811 ret = vfs_ChDir(conn, oldwd_fname);
812 if (ret == -1) {
813 smb_panic("unable to get back to old directory\n");
815 TALLOC_FREE(oldwd_fname);
819 * And do it all again... As smb_fname is not relative to the passed in
820 * dirfsp anymore, we pass conn->cwd_fsp as dirfsp to
821 * non_widelink_open() to trigger the chdir(parentdir) logic.
823 dirfsp = conn->cwd_fsp;
825 goto again;
827 out:
828 fsp->fsp_name = orig_fsp_name;
829 smb_fname->base_name = orig_smb_fname_base;
831 TALLOC_FREE(parent_dir_fname);
833 if (!NT_STATUS_IS_OK(status)) {
834 fd_close(fsp);
837 if (oldwd_fname != NULL) {
838 ret = vfs_ChDir(conn, oldwd_fname);
839 if (ret == -1) {
840 smb_panic("unable to get back to old directory\n");
842 TALLOC_FREE(oldwd_fname);
844 return status;
847 /****************************************************************************
848 fd support routines - attempt to do a dos_open.
849 ****************************************************************************/
851 NTSTATUS fd_openat(const struct files_struct *dirfsp,
852 struct smb_filename *smb_fname,
853 files_struct *fsp,
854 const struct vfs_open_how *_how)
856 struct vfs_open_how how = *_how;
857 struct connection_struct *conn = fsp->conn;
858 NTSTATUS status = NT_STATUS_OK;
859 bool fsp_is_stream = fsp_is_alternate_stream(fsp);
860 bool smb_fname_is_stream = is_named_stream(smb_fname);
862 SMB_ASSERT(fsp_is_stream == smb_fname_is_stream);
865 * Never follow symlinks on a POSIX client. The
866 * client should be doing this.
869 if (fsp->fsp_flags.posix_open || !lp_follow_symlinks(SNUM(conn))) {
870 how.flags |= O_NOFOLLOW;
873 if (fsp_is_stream) {
874 int fd;
876 fd = SMB_VFS_OPENAT(
877 conn,
878 NULL, /* stream open is relative to fsp->base_fsp */
879 smb_fname,
880 fsp,
881 &how);
882 if (fd == -1) {
883 status = map_nt_error_from_unix(errno);
885 fsp_set_fd(fsp, fd);
887 if (fd != -1) {
888 status = vfs_stat_fsp(fsp);
889 if (!NT_STATUS_IS_OK(status)) {
890 DBG_DEBUG("vfs_stat_fsp failed: %s\n",
891 nt_errstr(status));
892 fd_close(fsp);
896 return status;
900 * Only follow symlinks within a share
901 * definition.
903 status = non_widelink_open(dirfsp, fsp, smb_fname, &how);
904 if (!NT_STATUS_IS_OK(status)) {
905 if (NT_STATUS_EQUAL(status, NT_STATUS_TOO_MANY_OPENED_FILES)) {
906 static time_t last_warned = 0L;
908 if (time((time_t *) NULL) > last_warned) {
909 DEBUG(0,("Too many open files, unable "
910 "to open more! smbd's max "
911 "open files = %d\n",
912 lp_max_open_files()));
913 last_warned = time((time_t *) NULL);
917 DBG_DEBUG("name %s, flags = 0%o mode = 0%o, fd = %d. %s\n",
918 smb_fname_str_dbg(smb_fname),
919 how.flags,
920 (int)how.mode,
921 fsp_get_pathref_fd(fsp),
922 nt_errstr(status));
923 return status;
926 DBG_DEBUG("name %s, flags = 0%o mode = 0%o, fd = %d\n",
927 smb_fname_str_dbg(smb_fname),
928 how.flags,
929 (int)how.mode,
930 fsp_get_pathref_fd(fsp));
932 return status;
935 /****************************************************************************
936 Close the file associated with a fsp.
937 ****************************************************************************/
939 NTSTATUS fd_close(files_struct *fsp)
941 NTSTATUS stat_status = NT_STATUS_OK;
942 int ret;
944 if (fsp == fsp->conn->cwd_fsp) {
945 return NT_STATUS_OK;
948 if (fsp->fsp_flags.fstat_before_close) {
950 * capture status, if failure
951 * continue close processing
952 * and return status
954 stat_status = vfs_stat_fsp(fsp);
957 if (fsp->dptr) {
958 dptr_CloseDir(fsp);
960 if (fsp_get_pathref_fd(fsp) == -1) {
962 * Either a directory where the dptr_CloseDir() already closed
963 * the fd or a stat open.
965 return NT_STATUS_OK;
967 if (fh_get_refcount(fsp->fh) > 1) {
968 return NT_STATUS_OK; /* Shared handle. Only close last reference. */
971 ret = SMB_VFS_CLOSE(fsp);
972 fsp_set_fd(fsp, -1);
973 if (ret == -1) {
974 return map_nt_error_from_unix(errno);
976 return stat_status;
979 /****************************************************************************
980 Change the ownership of a file to that of the parent directory.
981 Do this by fd if possible.
982 ****************************************************************************/
984 static void change_file_owner_to_parent_fsp(struct files_struct *parent_fsp,
985 struct files_struct *fsp)
987 int ret;
989 if (parent_fsp->fsp_name->st.st_ex_uid == fsp->fsp_name->st.st_ex_uid) {
990 /* Already this uid - no need to change. */
991 DBG_DEBUG("file %s is already owned by uid %u\n",
992 fsp_str_dbg(fsp),
993 (unsigned int)fsp->fsp_name->st.st_ex_uid);
994 return;
997 become_root();
998 ret = SMB_VFS_FCHOWN(fsp,
999 parent_fsp->fsp_name->st.st_ex_uid,
1000 (gid_t)-1);
1001 unbecome_root();
1002 if (ret == -1) {
1003 DBG_ERR("failed to fchown "
1004 "file %s to parent directory uid %u. Error "
1005 "was %s\n",
1006 fsp_str_dbg(fsp),
1007 (unsigned int)parent_fsp->fsp_name->st.st_ex_uid,
1008 strerror(errno));
1009 } else {
1010 DBG_DEBUG("changed new file %s to "
1011 "parent directory uid %u.\n",
1012 fsp_str_dbg(fsp),
1013 (unsigned int)parent_fsp->fsp_name->st.st_ex_uid);
1014 /* Ensure the uid entry is updated. */
1015 fsp->fsp_name->st.st_ex_uid =
1016 parent_fsp->fsp_name->st.st_ex_uid;
1020 static NTSTATUS change_dir_owner_to_parent_fsp(struct files_struct *parent_fsp,
1021 struct files_struct *fsp)
1023 NTSTATUS status;
1024 int ret;
1026 if (parent_fsp->fsp_name->st.st_ex_uid == fsp->fsp_name->st.st_ex_uid) {
1027 /* Already this uid - no need to change. */
1028 DBG_DEBUG("directory %s is already owned by uid %u\n",
1029 fsp_str_dbg(fsp),
1030 (unsigned int)fsp->fsp_name->st.st_ex_uid);
1031 return NT_STATUS_OK;
1034 become_root();
1035 ret = SMB_VFS_FCHOWN(fsp,
1036 parent_fsp->fsp_name->st.st_ex_uid,
1037 (gid_t)-1);
1038 unbecome_root();
1039 if (ret == -1) {
1040 status = map_nt_error_from_unix(errno);
1041 DBG_ERR("failed to chown "
1042 "directory %s to parent directory uid %u. "
1043 "Error was %s\n",
1044 fsp_str_dbg(fsp),
1045 (unsigned int)parent_fsp->fsp_name->st.st_ex_uid,
1046 nt_errstr(status));
1047 return status;
1050 DBG_DEBUG("changed ownership of new "
1051 "directory %s to parent directory uid %u.\n",
1052 fsp_str_dbg(fsp),
1053 (unsigned int)parent_fsp->fsp_name->st.st_ex_uid);
1055 /* Ensure the uid entry is updated. */
1056 fsp->fsp_name->st.st_ex_uid = parent_fsp->fsp_name->st.st_ex_uid;
1058 return NT_STATUS_OK;
1061 /****************************************************************************
1062 Open a file - returning a guaranteed ATOMIC indication of if the
1063 file was created or not.
1064 ****************************************************************************/
1066 static NTSTATUS fd_open_atomic(struct files_struct *dirfsp,
1067 struct smb_filename *smb_fname,
1068 files_struct *fsp,
1069 const struct vfs_open_how *_how,
1070 bool *file_created)
1072 struct vfs_open_how how = *_how;
1073 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
1074 NTSTATUS retry_status;
1075 bool file_existed = VALID_STAT(smb_fname->st);
1077 if (!(how.flags & O_CREAT)) {
1079 * We're not creating the file, just pass through.
1081 status = fd_openat(dirfsp, smb_fname, fsp, &how);
1082 *file_created = false;
1083 return status;
1086 if (how.flags & O_EXCL) {
1088 * Fail if already exists, just pass through.
1090 status = fd_openat(dirfsp, smb_fname, fsp, &how);
1093 * Here we've opened with O_CREAT|O_EXCL. If that went
1094 * NT_STATUS_OK, we *know* we created this file.
1096 *file_created = NT_STATUS_IS_OK(status);
1098 return status;
1102 * Now it gets tricky. We have O_CREAT, but not O_EXCL.
1103 * To know absolutely if we created the file or not,
1104 * we can never call O_CREAT without O_EXCL. So if
1105 * we think the file existed, try without O_CREAT|O_EXCL.
1106 * If we think the file didn't exist, try with
1107 * O_CREAT|O_EXCL.
1109 * The big problem here is dangling symlinks. Opening
1110 * without O_NOFOLLOW means both bad symlink
1111 * and missing path return -1, ENOENT from open(). As POSIX
1112 * is pathname based it's not possible to tell
1113 * the difference between these two cases in a
1114 * non-racy way, so change to try only two attempts before
1115 * giving up.
1117 * We don't have this problem for the O_NOFOLLOW
1118 * case as it just returns NT_STATUS_OBJECT_PATH_NOT_FOUND
1119 * mapped from the ELOOP POSIX error.
1122 if (file_existed) {
1123 how.flags = _how->flags & ~(O_CREAT);
1124 retry_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
1125 } else {
1126 how.flags = _how->flags | O_EXCL;
1127 retry_status = NT_STATUS_OBJECT_NAME_COLLISION;
1130 status = fd_openat(dirfsp, smb_fname, fsp, &how);
1131 if (NT_STATUS_IS_OK(status)) {
1132 *file_created = !file_existed;
1133 return NT_STATUS_OK;
1135 if (NT_STATUS_EQUAL(status, retry_status)) {
1137 file_existed = !file_existed;
1139 DBG_DEBUG("File %s %s. Retry.\n",
1140 fsp_str_dbg(fsp),
1141 file_existed ? "existed" : "did not exist");
1143 if (file_existed) {
1144 how.flags = _how->flags & ~(O_CREAT);
1145 } else {
1146 how.flags = _how->flags | O_EXCL;
1149 status = fd_openat(dirfsp, smb_fname, fsp, &how);
1152 *file_created = (NT_STATUS_IS_OK(status) && !file_existed);
1153 return status;
1156 static NTSTATUS reopen_from_fsp(struct files_struct *dirfsp,
1157 struct smb_filename *smb_fname,
1158 struct files_struct *fsp,
1159 const struct vfs_open_how *how,
1160 bool *p_file_created)
1162 NTSTATUS status;
1163 int old_fd;
1165 if (fsp->fsp_flags.have_proc_fds &&
1166 ((old_fd = fsp_get_pathref_fd(fsp)) != -1)) {
1168 struct sys_proc_fd_path_buf buf;
1169 struct smb_filename proc_fname = {
1170 .base_name = sys_proc_fd_path(old_fd, &buf),
1172 mode_t mode = fsp->fsp_name->st.st_ex_mode;
1173 int new_fd;
1175 SMB_ASSERT(fsp->fsp_flags.is_pathref);
1177 if (S_ISLNK(mode)) {
1178 return NT_STATUS_STOPPED_ON_SYMLINK;
1180 if (!(S_ISREG(mode) || S_ISDIR(mode))) {
1181 return NT_STATUS_IO_REPARSE_TAG_NOT_HANDLED;
1184 fsp->fsp_flags.is_pathref = false;
1186 new_fd = SMB_VFS_OPENAT(fsp->conn,
1187 fsp->conn->cwd_fsp,
1188 &proc_fname,
1189 fsp,
1190 how);
1191 if (new_fd == -1) {
1192 #if defined(HAVE_FSTATFS) && defined(HAVE_LINUX_MAGIC_H)
1193 if (S_ISDIR(fsp->fsp_name->st.st_ex_mode) &&
1194 (errno == ENOENT)) {
1195 struct statfs sbuf = {};
1196 int ret = fstatfs(old_fd, &sbuf);
1197 if (ret == -1) {
1198 DBG_ERR("fstatfs failed: %s\n",
1199 strerror(errno));
1200 } else if (sbuf.f_type == AUTOFS_SUPER_MAGIC) {
1202 * When reopening an as-yet
1203 * unmounted autofs mount
1204 * point we get ENOENT. We
1205 * have to retry pathbased.
1207 goto namebased_open;
1209 /* restore ENOENT if changed in the meantime */
1210 errno = ENOENT;
1212 #endif
1213 status = map_nt_error_from_unix(errno);
1214 fd_close(fsp);
1215 return status;
1218 status = fd_close(fsp);
1219 if (!NT_STATUS_IS_OK(status)) {
1220 return status;
1223 fsp_set_fd(fsp, new_fd);
1224 return NT_STATUS_OK;
1227 #if defined(HAVE_FSTATFS) && defined(HAVE_LINUX_MAGIC_H)
1228 namebased_open:
1229 #endif
1231 * Close the existing pathref fd and set the fsp flag
1232 * is_pathref to false so we get a "normal" fd this time.
1234 status = fd_close(fsp);
1235 if (!NT_STATUS_IS_OK(status)) {
1236 return status;
1239 fsp->fsp_flags.is_pathref = false;
1241 status = fd_open_atomic(dirfsp, smb_fname, fsp, how, p_file_created);
1242 return status;
1245 /****************************************************************************
1246 Open a file.
1247 ****************************************************************************/
1249 static NTSTATUS open_file(
1250 struct smb_request *req,
1251 struct files_struct *dirfsp,
1252 struct smb_filename *smb_fname_atname,
1253 files_struct *fsp,
1254 const struct vfs_open_how *_how,
1255 uint32_t access_mask, /* client requested access mask. */
1256 uint32_t open_access_mask, /* what we're actually using in the open. */
1257 uint32_t private_flags,
1258 bool *p_file_created)
1260 connection_struct *conn = fsp->conn;
1261 struct smb_filename *smb_fname = fsp->fsp_name;
1262 struct vfs_open_how how = *_how;
1263 NTSTATUS status = NT_STATUS_OK;
1264 bool file_existed = VALID_STAT(fsp->fsp_name->st);
1265 const uint32_t need_fd_mask =
1266 FILE_READ_DATA |
1267 FILE_WRITE_DATA |
1268 FILE_APPEND_DATA |
1269 FILE_EXECUTE |
1270 SEC_FLAG_SYSTEM_SECURITY;
1271 bool creating = !file_existed && (how.flags & O_CREAT);
1272 bool open_fd = false;
1273 bool posix_open = fsp->fsp_flags.posix_open;
1276 * Catch early an attempt to open an existing
1277 * directory as a file.
1279 if (file_existed && S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
1280 return NT_STATUS_FILE_IS_A_DIRECTORY;
1284 * This little piece of insanity is inspired by the
1285 * fact that an NT client can open a file for O_RDONLY,
1286 * but set the create disposition to FILE_EXISTS_TRUNCATE.
1287 * If the client *can* write to the file, then it expects to
1288 * truncate the file, even though it is opening for readonly.
1289 * Quicken uses this stupid trick in backup file creation...
1290 * Thanks *greatly* to "David W. Chapman Jr." <dwcjr@inethouston.net>
1291 * for helping track this one down. It didn't bite us in 2.0.x
1292 * as we always opened files read-write in that release. JRA.
1295 if (((how.flags & O_ACCMODE) == O_RDONLY) && (how.flags & O_TRUNC)) {
1296 DBG_DEBUG("truncate requested on read-only open for file %s\n",
1297 smb_fname_str_dbg(smb_fname));
1298 how.flags = (how.flags & ~O_ACCMODE) | O_RDWR;
1301 /* Check permissions */
1304 * This code was changed after seeing a client open request
1305 * containing the open mode of (DENY_WRITE/read-only) with
1306 * the 'create if not exist' bit set. The previous code
1307 * would fail to open the file read only on a read-only share
1308 * as it was checking the flags parameter directly against O_RDONLY,
1309 * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
1310 * JRA.
1313 if (!CAN_WRITE(conn)) {
1314 /* It's a read-only share - fail if we wanted to write. */
1315 if ((how.flags & O_ACCMODE) != O_RDONLY ||
1316 (how.flags & O_TRUNC) || (how.flags & O_APPEND)) {
1317 DEBUG(3,("Permission denied opening %s\n",
1318 smb_fname_str_dbg(smb_fname)));
1319 return NT_STATUS_ACCESS_DENIED;
1322 * We don't want to write - but we must make sure that
1323 * O_CREAT doesn't create the file if we have write
1324 * access into the directory.
1326 how.flags &= ~(O_CREAT | O_EXCL);
1329 if ((open_access_mask & need_fd_mask) || creating ||
1330 (how.flags & O_TRUNC)) {
1331 open_fd = true;
1334 if (open_fd) {
1335 int ret;
1337 #if defined(O_NONBLOCK) && defined(S_ISFIFO)
1339 * We would block on opening a FIFO with no one else on the
1340 * other end. Do what we used to do and add O_NONBLOCK to the
1341 * open flags. JRA.
1344 if (file_existed && S_ISFIFO(smb_fname->st.st_ex_mode)) {
1345 how.flags |= O_NONBLOCK;
1347 #endif
1349 if (!posix_open) {
1350 const char *wild = smb_fname->base_name;
1352 * Don't open files with Microsoft wildcard characters.
1354 if (fsp_is_alternate_stream(fsp)) {
1356 * wildcard characters are allowed in stream
1357 * names only test the basefilename
1359 wild = fsp->base_fsp->fsp_name->base_name;
1362 if (ms_has_wild(wild)) {
1363 return NT_STATUS_OBJECT_NAME_INVALID;
1367 /* Can we access this file ? */
1368 if (!fsp_is_alternate_stream(fsp)) {
1369 /* Only do this check on non-stream open. */
1370 if (file_existed) {
1371 status = smbd_check_access_rights_fsp(
1372 dirfsp,
1373 fsp,
1374 false,
1375 open_access_mask);
1377 if (!NT_STATUS_IS_OK(status)) {
1378 DBG_DEBUG("smbd_check_access_rights_fsp"
1379 " on file %s returned %s\n",
1380 fsp_str_dbg(fsp),
1381 nt_errstr(status));
1384 if (!NT_STATUS_IS_OK(status) &&
1385 !NT_STATUS_EQUAL(status,
1386 NT_STATUS_OBJECT_NAME_NOT_FOUND))
1388 return status;
1391 if (NT_STATUS_EQUAL(status,
1392 NT_STATUS_OBJECT_NAME_NOT_FOUND))
1394 DEBUG(10, ("open_file: "
1395 "file %s vanished since we "
1396 "checked for existence.\n",
1397 smb_fname_str_dbg(smb_fname)));
1398 file_existed = false;
1399 SET_STAT_INVALID(fsp->fsp_name->st);
1403 if (!file_existed) {
1404 if (!(how.flags & O_CREAT)) {
1405 /* File didn't exist and no O_CREAT. */
1406 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1409 status = check_parent_access_fsp(
1410 dirfsp,
1411 SEC_DIR_ADD_FILE);
1412 if (!NT_STATUS_IS_OK(status)) {
1413 DBG_DEBUG("check_parent_access_fsp on "
1414 "directory %s for file %s "
1415 "returned %s\n",
1416 smb_fname_str_dbg(
1417 dirfsp->fsp_name),
1418 smb_fname_str_dbg(smb_fname),
1419 nt_errstr(status));
1420 return status;
1426 * Actually do the open - if O_TRUNC is needed handle it
1427 * below under the share mode lock.
1429 how.flags &= ~O_TRUNC;
1430 status = reopen_from_fsp(dirfsp,
1431 smb_fname_atname,
1432 fsp,
1433 &how,
1434 p_file_created);
1435 if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) {
1437 * Non-O_PATH reopen that hit a race
1438 * condition: Someone has put a symlink where
1439 * we used to have a file. Can't happen with
1440 * O_PATH and reopening from /proc/self/fd/ or
1441 * equivalent.
1443 status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
1445 if (!NT_STATUS_IS_OK(status)) {
1446 DBG_NOTICE("Error opening file %s (%s) (in_flags=%d) "
1447 "(flags=%d)\n",
1448 smb_fname_str_dbg(smb_fname),
1449 nt_errstr(status),
1450 _how->flags,
1451 how.flags);
1452 return status;
1455 if (how.flags & O_NONBLOCK) {
1457 * GPFS can return ETIMEDOUT for pread on
1458 * nonblocking file descriptors when files
1459 * migrated to tape need to be recalled. I
1460 * could imagine this happens elsewhere
1461 * too. With blocking file descriptors this
1462 * does not happen.
1464 ret = vfs_set_blocking(fsp, true);
1465 if (ret == -1) {
1466 status = map_nt_error_from_unix(errno);
1467 DBG_WARNING("Could not set fd to blocking: "
1468 "%s\n", strerror(errno));
1469 fd_close(fsp);
1470 return status;
1474 if (*p_file_created) {
1475 /* We created this file. */
1477 bool need_re_stat = false;
1478 /* Do all inheritance work after we've
1479 done a successful fstat call and filled
1480 in the stat struct in fsp->fsp_name. */
1482 /* Inherit the ACL if required */
1483 if (lp_inherit_permissions(SNUM(conn))) {
1484 inherit_access_posix_acl(conn,
1485 dirfsp,
1486 smb_fname,
1487 how.mode);
1488 need_re_stat = true;
1491 /* Change the owner if required. */
1492 if (lp_inherit_owner(SNUM(conn)) != INHERIT_OWNER_NO) {
1493 change_file_owner_to_parent_fsp(dirfsp, fsp);
1494 need_re_stat = true;
1497 if (need_re_stat) {
1498 status = vfs_stat_fsp(fsp);
1500 * If we have an fd, this stat should succeed.
1502 if (!NT_STATUS_IS_OK(status)) {
1503 DBG_ERR("Error doing fstat on open "
1504 "file %s (%s)\n",
1505 smb_fname_str_dbg(smb_fname),
1506 nt_errstr(status));
1507 fd_close(fsp);
1508 return status;
1512 } else {
1513 if (!file_existed) {
1514 /* File must exist for a stat open. */
1515 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1518 if (S_ISLNK(smb_fname->st.st_ex_mode) &&
1519 !posix_open)
1522 * Don't allow stat opens on symlinks directly unless
1523 * it's a POSIX open. Match the return code from
1524 * openat_pathref_fsp().
1526 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1529 if (!fsp->fsp_flags.is_pathref) {
1531 * There is only one legit case where end up here:
1532 * openat_pathref_fsp() failed to open a symlink, so the
1533 * fsp was created by fsp_new() which doesn't set
1534 * is_pathref. Other than that, we should always have a
1535 * pathref fsp at this point. The subsequent checks
1536 * assert this.
1538 if (!(smb_fname->flags & SMB_FILENAME_POSIX_PATH)) {
1539 DBG_ERR("[%s] is not a POSIX pathname\n",
1540 smb_fname_str_dbg(smb_fname));
1541 return NT_STATUS_INTERNAL_ERROR;
1543 if (!S_ISLNK(smb_fname->st.st_ex_mode)) {
1544 DBG_ERR("[%s] is not a symlink\n",
1545 smb_fname_str_dbg(smb_fname));
1546 return NT_STATUS_INTERNAL_ERROR;
1548 if (fsp_get_pathref_fd(fsp) != -1) {
1549 DBG_ERR("fd for [%s] is not -1: fd [%d]\n",
1550 smb_fname_str_dbg(smb_fname),
1551 fsp_get_pathref_fd(fsp));
1552 return NT_STATUS_INTERNAL_ERROR;
1557 * Access to streams is checked by checking the basefile and
1558 * that has already been checked by check_base_file_access()
1559 * in create_file_unixpath().
1561 if (!fsp_is_alternate_stream(fsp)) {
1562 status = smbd_check_access_rights_fsp(dirfsp,
1563 fsp,
1564 false,
1565 open_access_mask);
1567 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) &&
1568 posix_open &&
1569 S_ISLNK(smb_fname->st.st_ex_mode)) {
1570 /* This is a POSIX stat open for delete
1571 * or rename on a symlink that points
1572 * nowhere. Allow. */
1573 DEBUG(10,("open_file: allowing POSIX "
1574 "open on bad symlink %s\n",
1575 smb_fname_str_dbg(smb_fname)));
1576 status = NT_STATUS_OK;
1579 if (!NT_STATUS_IS_OK(status)) {
1580 DBG_DEBUG("smbd_check_access_rights_fsp on file "
1581 "%s returned %s\n",
1582 fsp_str_dbg(fsp),
1583 nt_errstr(status));
1584 return status;
1589 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
1590 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
1591 fsp->file_pid = req ? req->smbpid : 0;
1592 fsp->fsp_flags.can_lock = true;
1593 fsp->fsp_flags.can_read = ((access_mask & FILE_READ_DATA) != 0);
1594 fsp->fsp_flags.can_write =
1595 CAN_WRITE(conn) &&
1596 ((access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) != 0);
1597 if (fsp->fsp_name->twrp != 0) {
1598 fsp->fsp_flags.can_write = false;
1600 fsp->print_file = NULL;
1601 fsp->fsp_flags.modified = false;
1602 fsp->sent_oplock_break = NO_BREAK_SENT;
1603 fsp->fsp_flags.is_directory = false;
1604 if (is_in_path(smb_fname->base_name,
1605 conn->aio_write_behind_list,
1606 posix_open ? true : conn->case_sensitive)) {
1607 fsp->fsp_flags.aio_write_behind = true;
1610 DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
1611 conn->session_info->unix_info->unix_name,
1612 smb_fname_str_dbg(smb_fname),
1613 BOOLSTR(fsp->fsp_flags.can_read),
1614 BOOLSTR(fsp->fsp_flags.can_write),
1615 conn->num_files_open));
1617 return NT_STATUS_OK;
1620 static bool mask_conflict(
1621 uint32_t new_access,
1622 uint32_t existing_access,
1623 uint32_t access_mask,
1624 uint32_t new_sharemode,
1625 uint32_t existing_sharemode,
1626 uint32_t sharemode_mask)
1628 bool want_access = (new_access & access_mask);
1629 bool allow_existing = (existing_sharemode & sharemode_mask);
1630 bool have_access = (existing_access & access_mask);
1631 bool allow_new = (new_sharemode & sharemode_mask);
1633 if (want_access && !allow_existing) {
1634 DBG_DEBUG("Access request 0x%"PRIx32"/0x%"PRIx32" conflicts "
1635 "with existing sharemode 0x%"PRIx32"/0x%"PRIx32"\n",
1636 new_access,
1637 access_mask,
1638 existing_sharemode,
1639 sharemode_mask);
1640 return true;
1642 if (have_access && !allow_new) {
1643 DBG_DEBUG("Sharemode request 0x%"PRIx32"/0x%"PRIx32" conflicts "
1644 "with existing access 0x%"PRIx32"/0x%"PRIx32"\n",
1645 new_sharemode,
1646 sharemode_mask,
1647 existing_access,
1648 access_mask);
1649 return true;
1651 return false;
1654 /****************************************************************************
1655 Check if we can open a file with a share mode.
1656 Returns True if conflict, False if not.
1657 ****************************************************************************/
1659 static const uint32_t conflicting_access =
1660 FILE_WRITE_DATA|
1661 FILE_APPEND_DATA|
1662 FILE_READ_DATA|
1663 FILE_EXECUTE|
1664 DELETE_ACCESS;
1666 static bool share_conflict(uint32_t e_access_mask,
1667 uint32_t e_share_access,
1668 uint32_t access_mask,
1669 uint32_t share_access)
1671 bool conflict;
1673 DBG_DEBUG("existing access_mask = 0x%"PRIx32", "
1674 "existing share access = 0x%"PRIx32", "
1675 "access_mask = 0x%"PRIx32", "
1676 "share_access = 0x%"PRIx32"\n",
1677 e_access_mask,
1678 e_share_access,
1679 access_mask,
1680 share_access);
1682 if ((e_access_mask & conflicting_access) == 0) {
1683 DBG_DEBUG("No conflict due to "
1684 "existing access_mask = 0x%"PRIx32"\n",
1685 e_access_mask);
1686 return false;
1688 if ((access_mask & conflicting_access) == 0) {
1689 DBG_DEBUG("No conflict due to access_mask = 0x%"PRIx32"\n",
1690 access_mask);
1691 return false;
1694 conflict = mask_conflict(
1695 access_mask, e_access_mask, FILE_WRITE_DATA | FILE_APPEND_DATA,
1696 share_access, e_share_access, FILE_SHARE_WRITE);
1697 conflict |= mask_conflict(
1698 access_mask, e_access_mask, FILE_READ_DATA | FILE_EXECUTE,
1699 share_access, e_share_access, FILE_SHARE_READ);
1700 conflict |= mask_conflict(
1701 access_mask, e_access_mask, DELETE_ACCESS,
1702 share_access, e_share_access, FILE_SHARE_DELETE);
1704 DBG_DEBUG("conflict=%s\n", conflict ? "true" : "false");
1705 return conflict;
1708 #if defined(DEVELOPER)
1710 struct validate_my_share_entries_state {
1711 struct smbd_server_connection *sconn;
1712 struct file_id fid;
1713 struct server_id self;
1716 static bool validate_my_share_entries_fn(
1717 struct share_mode_entry *e,
1718 bool *modified,
1719 void *private_data)
1721 struct validate_my_share_entries_state *state = private_data;
1722 files_struct *fsp;
1724 if (!server_id_equal(&state->self, &e->pid)) {
1725 return false;
1728 if (e->op_mid == 0) {
1729 /* INTERNAL_OPEN_ONLY */
1730 return false;
1733 fsp = file_find_dif(state->sconn, state->fid, e->share_file_id);
1734 if (!fsp) {
1735 DBG_ERR("PANIC : %s\n",
1736 share_mode_str(talloc_tos(), 0, &state->fid, e));
1737 smb_panic("validate_my_share_entries: Cannot match a "
1738 "share entry with an open file\n");
1741 if (((uint16_t)fsp->oplock_type) != e->op_type) {
1742 goto panic;
1745 return false;
1747 panic:
1749 char *str;
1750 DBG_ERR("validate_my_share_entries: PANIC : %s\n",
1751 share_mode_str(talloc_tos(), 0, &state->fid, e));
1752 str = talloc_asprintf(talloc_tos(),
1753 "validate_my_share_entries: "
1754 "file %s, oplock_type = 0x%x, op_type = 0x%x\n",
1755 fsp->fsp_name->base_name,
1756 (unsigned int)fsp->oplock_type,
1757 (unsigned int)e->op_type);
1758 smb_panic(str);
1761 return false;
1763 #endif
1766 * Allowed access mask for stat opens relevant to oplocks
1768 bool is_oplock_stat_open(uint32_t access_mask)
1770 const uint32_t stat_open_bits =
1771 (SYNCHRONIZE_ACCESS|
1772 FILE_READ_ATTRIBUTES|
1773 FILE_WRITE_ATTRIBUTES);
1775 return (((access_mask & stat_open_bits) != 0) &&
1776 ((access_mask & ~stat_open_bits) == 0));
1780 * Allowed access mask for stat opens relevant to leases
1782 bool is_lease_stat_open(uint32_t access_mask)
1784 const uint32_t stat_open_bits =
1785 (SYNCHRONIZE_ACCESS|
1786 FILE_READ_ATTRIBUTES|
1787 FILE_WRITE_ATTRIBUTES|
1788 READ_CONTROL_ACCESS);
1790 return (((access_mask & stat_open_bits) != 0) &&
1791 ((access_mask & ~stat_open_bits) == 0));
1794 struct has_delete_on_close_state {
1795 bool ret;
1798 static bool has_delete_on_close_fn(
1799 struct share_mode_entry *e,
1800 bool *modified,
1801 void *private_data)
1803 struct has_delete_on_close_state *state = private_data;
1804 state->ret = !share_entry_stale_pid(e);
1805 return state->ret;
1808 static bool has_delete_on_close(struct share_mode_lock *lck,
1809 uint32_t name_hash)
1811 struct has_delete_on_close_state state = { .ret = false };
1812 bool ok;
1814 if (!is_delete_on_close_set(lck, name_hash)) {
1815 return false;
1818 ok= share_mode_forall_entries(lck, has_delete_on_close_fn, &state);
1819 if (!ok) {
1820 DBG_DEBUG("share_mode_forall_entries failed\n");
1821 return false;
1823 return state.ret;
1826 static void share_mode_flags_restrict(
1827 struct share_mode_lock *lck,
1828 uint32_t access_mask,
1829 uint32_t share_mode,
1830 uint32_t lease_type)
1832 uint32_t existing_access_mask, existing_share_mode;
1833 uint32_t existing_lease_type;
1835 share_mode_flags_get(
1836 lck,
1837 &existing_access_mask,
1838 &existing_share_mode,
1839 &existing_lease_type);
1841 existing_access_mask |= access_mask;
1842 if (access_mask & conflicting_access) {
1843 existing_share_mode &= share_mode;
1845 existing_lease_type |= lease_type;
1847 share_mode_flags_set(
1848 lck,
1849 existing_access_mask,
1850 existing_share_mode,
1851 existing_lease_type,
1852 NULL);
1855 /****************************************************************************
1856 Deal with share modes
1857 Invariant: Share mode must be locked on entry and exit.
1858 Returns -1 on error, or number of share modes on success (may be zero).
1859 ****************************************************************************/
1861 struct open_mode_check_state {
1862 struct file_id fid;
1863 uint32_t access_mask;
1864 uint32_t share_access;
1865 uint32_t lease_type;
1868 static bool open_mode_check_fn(
1869 struct share_mode_entry *e,
1870 bool *modified,
1871 void *private_data)
1873 struct open_mode_check_state *state = private_data;
1874 bool disconnected, stale;
1875 uint32_t access_mask, share_access, lease_type;
1877 disconnected = server_id_is_disconnected(&e->pid);
1878 if (disconnected) {
1879 return false;
1882 access_mask = state->access_mask | e->access_mask;
1883 share_access = state->share_access;
1884 if (e->access_mask & conflicting_access) {
1885 share_access &= e->share_access;
1887 lease_type = state->lease_type | get_lease_type(e, state->fid);
1889 if ((access_mask == state->access_mask) &&
1890 (share_access == state->share_access) &&
1891 (lease_type == state->lease_type)) {
1892 return false;
1895 stale = share_entry_stale_pid(e);
1896 if (stale) {
1897 return false;
1900 state->access_mask = access_mask;
1901 state->share_access = share_access;
1902 state->lease_type = lease_type;
1904 return false;
1907 static NTSTATUS open_mode_check(connection_struct *conn,
1908 struct file_id fid,
1909 struct share_mode_lock *lck,
1910 uint32_t access_mask,
1911 uint32_t share_access)
1913 struct open_mode_check_state state;
1914 bool ok, conflict;
1915 bool modified = false;
1917 if (is_oplock_stat_open(access_mask)) {
1918 /* Stat open that doesn't trigger oplock breaks or share mode
1919 * checks... ! JRA. */
1920 return NT_STATUS_OK;
1924 * Check if the share modes will give us access.
1927 #if defined(DEVELOPER)
1929 struct validate_my_share_entries_state validate_state = {
1930 .sconn = conn->sconn,
1931 .fid = fid,
1932 .self = messaging_server_id(conn->sconn->msg_ctx),
1934 ok = share_mode_forall_entries(
1935 lck, validate_my_share_entries_fn, &validate_state);
1936 SMB_ASSERT(ok);
1938 #endif
1940 share_mode_flags_get(
1941 lck, &state.access_mask, &state.share_access, NULL);
1943 conflict = share_conflict(
1944 state.access_mask,
1945 state.share_access,
1946 access_mask,
1947 share_access);
1948 if (!conflict) {
1949 DBG_DEBUG("No conflict due to share_mode_flags access\n");
1950 return NT_STATUS_OK;
1953 state = (struct open_mode_check_state) {
1954 .fid = fid,
1955 .share_access = (FILE_SHARE_READ|
1956 FILE_SHARE_WRITE|
1957 FILE_SHARE_DELETE),
1961 * Walk the share mode array to recalculate d->flags
1964 ok = share_mode_forall_entries(lck, open_mode_check_fn, &state);
1965 if (!ok) {
1966 DBG_DEBUG("share_mode_forall_entries failed\n");
1967 return NT_STATUS_INTERNAL_ERROR;
1970 share_mode_flags_set(
1971 lck,
1972 state.access_mask,
1973 state.share_access,
1974 state.lease_type,
1975 &modified);
1976 if (!modified) {
1978 * We only end up here if we had a sharing violation
1979 * from d->flags and have recalculated it.
1981 return NT_STATUS_SHARING_VIOLATION;
1984 conflict = share_conflict(
1985 state.access_mask,
1986 state.share_access,
1987 access_mask,
1988 share_access);
1989 if (!conflict) {
1990 DBG_DEBUG("No conflict due to share_mode_flags access\n");
1991 return NT_STATUS_OK;
1994 return NT_STATUS_SHARING_VIOLATION;
1998 * Send a break message to the oplock holder and delay the open for
1999 * our client.
2002 NTSTATUS send_break_message(struct messaging_context *msg_ctx,
2003 const struct file_id *id,
2004 const struct share_mode_entry *exclusive,
2005 uint16_t break_to)
2007 struct oplock_break_message msg = {
2008 .id = *id,
2009 .share_file_id = exclusive->share_file_id,
2010 .break_to = break_to,
2012 enum ndr_err_code ndr_err;
2013 uint8_t msgbuf[33];
2014 DATA_BLOB blob = {.data = msgbuf, .length = sizeof(msgbuf)};
2015 NTSTATUS status;
2017 if (DEBUGLVL(10)) {
2018 struct server_id_buf buf;
2019 DBG_DEBUG("Sending break message to %s\n",
2020 server_id_str_buf(exclusive->pid, &buf));
2021 NDR_PRINT_DEBUG(oplock_break_message, &msg);
2024 ndr_err = ndr_push_struct_into_fixed_blob(
2025 &blob,
2026 &msg,
2027 (ndr_push_flags_fn_t)ndr_push_oplock_break_message);
2028 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2029 DBG_WARNING("ndr_push_oplock_break_message failed: %s\n",
2030 ndr_errstr(ndr_err));
2031 return ndr_map_error2ntstatus(ndr_err);
2034 status = messaging_send(msg_ctx,
2035 exclusive->pid,
2036 MSG_SMB_BREAK_REQUEST,
2037 &blob);
2038 if (!NT_STATUS_IS_OK(status)) {
2039 DEBUG(3, ("Could not send oplock break message: %s\n",
2040 nt_errstr(status)));
2043 return status;
2046 struct validate_oplock_types_state {
2047 bool valid;
2048 bool batch;
2049 bool ex_or_batch;
2050 bool level2;
2051 bool no_oplock;
2052 uint32_t num_non_stat_opens;
2055 static bool validate_oplock_types_fn(
2056 struct share_mode_entry *e,
2057 bool *modified,
2058 void *private_data)
2060 struct validate_oplock_types_state *state = private_data;
2062 if (e->op_mid == 0) {
2063 /* INTERNAL_OPEN_ONLY */
2064 return false;
2067 if (e->op_type == NO_OPLOCK && is_oplock_stat_open(e->access_mask)) {
2069 * We ignore stat opens in the table - they always
2070 * have NO_OPLOCK and never get or cause breaks. JRA.
2072 return false;
2075 state->num_non_stat_opens += 1;
2077 if (BATCH_OPLOCK_TYPE(e->op_type)) {
2078 /* batch - can only be one. */
2079 if (share_entry_stale_pid(e)) {
2080 DBG_DEBUG("Found stale batch oplock\n");
2081 return false;
2083 if (state->ex_or_batch ||
2084 state->batch ||
2085 state->level2 ||
2086 state->no_oplock) {
2087 DBG_ERR("Bad batch oplock entry\n");
2088 state->valid = false;
2089 return true;
2091 state->batch = true;
2094 if (EXCLUSIVE_OPLOCK_TYPE(e->op_type)) {
2095 if (share_entry_stale_pid(e)) {
2096 DBG_DEBUG("Found stale duplicate oplock\n");
2097 return false;
2099 /* Exclusive or batch - can only be one. */
2100 if (state->ex_or_batch ||
2101 state->level2 ||
2102 state->no_oplock) {
2103 DBG_ERR("Bad exclusive or batch oplock entry\n");
2104 state->valid = false;
2105 return true;
2107 state->ex_or_batch = true;
2110 if (LEVEL_II_OPLOCK_TYPE(e->op_type)) {
2111 if (state->batch || state->ex_or_batch) {
2112 if (share_entry_stale_pid(e)) {
2113 DBG_DEBUG("Found stale LevelII oplock\n");
2114 return false;
2116 DBG_DEBUG("Bad levelII oplock entry\n");
2117 state->valid = false;
2118 return true;
2120 state->level2 = true;
2123 if (e->op_type == NO_OPLOCK) {
2124 if (state->batch || state->ex_or_batch) {
2125 if (share_entry_stale_pid(e)) {
2126 DBG_DEBUG("Found stale NO_OPLOCK entry\n");
2127 return false;
2129 DBG_ERR("Bad no oplock entry\n");
2130 state->valid = false;
2131 return true;
2133 state->no_oplock = true;
2136 return false;
2140 * Do internal consistency checks on the share mode for a file.
2143 static bool validate_oplock_types(struct share_mode_lock *lck)
2145 struct validate_oplock_types_state state = { .valid = true };
2146 static bool skip_validation;
2147 bool validate;
2148 bool ok;
2150 if (skip_validation) {
2151 return true;
2154 validate = lp_parm_bool(-1, "smbd", "validate_oplock_types", false);
2155 if (!validate) {
2156 DBG_DEBUG("smbd:validate_oplock_types not set to yes\n");
2157 skip_validation = true;
2158 return true;
2161 ok = share_mode_forall_entries(lck, validate_oplock_types_fn, &state);
2162 if (!ok) {
2163 DBG_DEBUG("share_mode_forall_entries failed\n");
2164 return false;
2166 if (!state.valid) {
2167 DBG_DEBUG("Got invalid oplock configuration\n");
2168 return false;
2171 if ((state.batch || state.ex_or_batch) &&
2172 (state.num_non_stat_opens != 1)) {
2173 DBG_WARNING("got batch (%d) or ex (%d) non-exclusively "
2174 "(%"PRIu32")\n",
2175 (int)state.batch,
2176 (int)state.ex_or_batch,
2177 state.num_non_stat_opens);
2178 return false;
2181 return true;
2184 static bool is_same_lease(const files_struct *fsp,
2185 const struct share_mode_entry *e,
2186 const struct smb2_lease *lease)
2188 if (e->op_type != LEASE_OPLOCK) {
2189 return false;
2191 if (lease == NULL) {
2192 return false;
2195 return smb2_lease_equal(fsp_client_guid(fsp),
2196 &lease->lease_key,
2197 &e->client_guid,
2198 &e->lease_key);
2201 static bool file_has_brlocks(files_struct *fsp)
2203 struct byte_range_lock *br_lck;
2205 br_lck = brl_get_locks_readonly(fsp);
2206 if (!br_lck)
2207 return false;
2209 return (brl_num_locks(br_lck) > 0);
2212 struct fsp_lease *find_fsp_lease(struct files_struct *new_fsp,
2213 const struct smb2_lease_key *key,
2214 uint32_t current_state,
2215 uint16_t lease_version,
2216 uint16_t lease_epoch)
2218 struct files_struct *fsp;
2221 * TODO: Measure how expensive this loop is with thousands of open
2222 * handles...
2225 for (fsp = file_find_di_first(new_fsp->conn->sconn, new_fsp->file_id, true);
2226 fsp != NULL;
2227 fsp = file_find_di_next(fsp, true)) {
2229 if (fsp == new_fsp) {
2230 continue;
2232 if (fsp->oplock_type != LEASE_OPLOCK) {
2233 continue;
2235 if (smb2_lease_key_equal(&fsp->lease->lease.lease_key, key)) {
2236 fsp->lease->ref_count += 1;
2237 return fsp->lease;
2241 /* Not found - must be leased in another smbd. */
2242 new_fsp->lease = talloc_zero(new_fsp->conn->sconn, struct fsp_lease);
2243 if (new_fsp->lease == NULL) {
2244 return NULL;
2246 new_fsp->lease->ref_count = 1;
2247 new_fsp->lease->sconn = new_fsp->conn->sconn;
2248 new_fsp->lease->lease.lease_key = *key;
2249 new_fsp->lease->lease.lease_state = current_state;
2251 * We internally treat all leases as V2 and update
2252 * the epoch, but when sending breaks it matters if
2253 * the requesting lease was v1 or v2.
2255 new_fsp->lease->lease.lease_version = lease_version;
2256 new_fsp->lease->lease.lease_epoch = lease_epoch;
2257 return new_fsp->lease;
2260 static NTSTATUS try_lease_upgrade(struct files_struct *fsp,
2261 struct share_mode_lock *lck,
2262 const struct GUID *client_guid,
2263 const struct smb2_lease *lease,
2264 uint32_t granted)
2266 bool do_upgrade;
2267 uint32_t current_state, breaking_to_requested, breaking_to_required;
2268 bool breaking;
2269 uint16_t lease_version, epoch;
2270 uint32_t existing, requested;
2271 NTSTATUS status;
2273 status = leases_db_get(
2274 client_guid,
2275 &lease->lease_key,
2276 &fsp->file_id,
2277 &current_state,
2278 &breaking,
2279 &breaking_to_requested,
2280 &breaking_to_required,
2281 &lease_version,
2282 &epoch);
2283 if (!NT_STATUS_IS_OK(status)) {
2284 return status;
2287 fsp->lease = find_fsp_lease(
2288 fsp,
2289 &lease->lease_key,
2290 current_state,
2291 lease_version,
2292 epoch);
2293 if (fsp->lease == NULL) {
2294 DEBUG(1, ("Did not find existing lease for file %s\n",
2295 fsp_str_dbg(fsp)));
2296 return NT_STATUS_NO_MEMORY;
2300 * Upgrade only if the requested lease is a strict upgrade.
2302 existing = current_state;
2303 requested = lease->lease_state;
2306 * Tricky: This test makes sure that "requested" is a
2307 * strict bitwise superset of "existing".
2309 do_upgrade = ((existing & requested) == existing);
2312 * Upgrade only if there's a change.
2314 do_upgrade &= (granted != existing);
2317 * Upgrade only if other leases don't prevent what was asked
2318 * for.
2320 do_upgrade &= (granted == requested);
2323 * only upgrade if we are not in breaking state
2325 do_upgrade &= !breaking;
2327 DEBUG(10, ("existing=%"PRIu32", requested=%"PRIu32", "
2328 "granted=%"PRIu32", do_upgrade=%d\n",
2329 existing, requested, granted, (int)do_upgrade));
2331 if (do_upgrade) {
2332 NTSTATUS set_status;
2334 current_state = granted;
2335 epoch += 1;
2337 set_status = leases_db_set(
2338 client_guid,
2339 &lease->lease_key,
2340 current_state,
2341 breaking,
2342 breaking_to_requested,
2343 breaking_to_required,
2344 lease_version,
2345 epoch);
2347 if (!NT_STATUS_IS_OK(set_status)) {
2348 DBG_DEBUG("leases_db_set failed: %s\n",
2349 nt_errstr(set_status));
2350 return set_status;
2354 fsp_lease_update(fsp);
2356 return NT_STATUS_OK;
2359 static NTSTATUS grant_new_fsp_lease(struct files_struct *fsp,
2360 struct share_mode_lock *lck,
2361 const struct GUID *client_guid,
2362 const struct smb2_lease *lease,
2363 uint32_t granted)
2365 NTSTATUS status;
2367 fsp->lease = talloc_zero(fsp->conn->sconn, struct fsp_lease);
2368 if (fsp->lease == NULL) {
2369 return NT_STATUS_INSUFFICIENT_RESOURCES;
2371 fsp->lease->ref_count = 1;
2372 fsp->lease->sconn = fsp->conn->sconn;
2373 fsp->lease->lease.lease_version = lease->lease_version;
2374 fsp->lease->lease.lease_key = lease->lease_key;
2375 fsp->lease->lease.parent_lease_key = lease->parent_lease_key;
2376 fsp->lease->lease.lease_flags = lease->lease_flags;
2377 fsp->lease->lease.lease_state = granted;
2378 fsp->lease->lease.lease_epoch = lease->lease_epoch + 1;
2380 status = leases_db_add(client_guid,
2381 &lease->lease_key,
2382 &fsp->file_id,
2383 fsp->lease->lease.lease_state,
2384 fsp->lease->lease.lease_version,
2385 fsp->lease->lease.lease_epoch,
2386 fsp->conn->connectpath,
2387 fsp->fsp_name->base_name,
2388 fsp->fsp_name->stream_name);
2389 if (!NT_STATUS_IS_OK(status)) {
2390 DEBUG(10, ("%s: leases_db_add failed: %s\n", __func__,
2391 nt_errstr(status)));
2392 TALLOC_FREE(fsp->lease);
2393 return NT_STATUS_INSUFFICIENT_RESOURCES;
2397 * We used to set lck->data->modified=true here without
2398 * actually modifying lck->data, triggering a needless
2399 * writeback of lck->data.
2401 * Apart from that writeback, setting modified=true has the
2402 * effect of triggering all waiters for this file to
2403 * retry. This only makes sense if any blocking condition
2404 * (i.e. waiting for a lease to be downgraded or removed) is
2405 * gone. This routine here only adds a lease, so it will never
2406 * free up resources that blocked waiters can now claim. So
2407 * that second effect also does not matter in this
2408 * routine. Thus setting lck->data->modified=true does not
2409 * need to be done here.
2412 return NT_STATUS_OK;
2415 static NTSTATUS grant_fsp_lease(struct files_struct *fsp,
2416 struct share_mode_lock *lck,
2417 const struct smb2_lease *lease,
2418 uint32_t granted)
2420 const struct GUID *client_guid = fsp_client_guid(fsp);
2421 NTSTATUS status;
2423 status = try_lease_upgrade(fsp, lck, client_guid, lease, granted);
2425 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
2426 status = grant_new_fsp_lease(
2427 fsp, lck, client_guid, lease, granted);
2430 return status;
2433 static int map_lease_type_to_oplock(uint32_t lease_type)
2435 int result = NO_OPLOCK;
2437 switch (lease_type) {
2438 case SMB2_LEASE_READ|SMB2_LEASE_WRITE|SMB2_LEASE_HANDLE:
2439 result = BATCH_OPLOCK|EXCLUSIVE_OPLOCK;
2440 break;
2441 case SMB2_LEASE_READ|SMB2_LEASE_WRITE:
2442 result = EXCLUSIVE_OPLOCK;
2443 break;
2444 case SMB2_LEASE_READ|SMB2_LEASE_HANDLE:
2445 case SMB2_LEASE_READ:
2446 result = LEVEL_II_OPLOCK;
2447 break;
2450 return result;
2453 struct blocker_debug_state {
2454 size_t num_blockers;
2457 struct delay_for_oplock_state {
2458 struct files_struct *fsp;
2459 const struct smb2_lease *lease;
2460 bool will_overwrite;
2461 uint32_t delay_mask;
2462 bool first_open_attempt;
2463 bool got_handle_lease;
2464 bool got_oplock;
2465 bool disallow_write_lease;
2466 uint32_t total_lease_types;
2467 bool delay;
2468 struct blocker_debug_state *blocker_debug_state;
2471 static int blocker_debug_state_destructor(struct blocker_debug_state *state)
2473 if (state->num_blockers == 0) {
2474 return 0;
2477 DBG_DEBUG("blocker_debug_state [%p] num_blockers [%zu]\n",
2478 state, state->num_blockers);
2479 return 0;
2482 static void delay_for_oplock_fn_watch_done(struct tevent_req *subreq);
2484 static bool delay_for_oplock_fn(
2485 struct share_mode_entry *e,
2486 bool *modified,
2487 void *private_data)
2489 struct delay_for_oplock_state *state = private_data;
2490 struct files_struct *fsp = state->fsp;
2491 const struct smb2_lease *lease = state->lease;
2492 bool e_is_lease = (e->op_type == LEASE_OPLOCK);
2493 uint32_t e_lease_type = SMB2_LEASE_NONE;
2494 uint32_t break_to;
2495 bool lease_is_breaking = false;
2496 struct tevent_req *subreq = NULL;
2497 struct server_id_buf idbuf = {};
2499 if (e_is_lease) {
2500 NTSTATUS status;
2502 if (lease != NULL) {
2503 bool our_lease = is_same_lease(fsp, e, lease);
2504 if (our_lease) {
2505 DBG_DEBUG("Ignoring our own lease\n");
2506 return false;
2510 status = leases_db_get(
2511 &e->client_guid,
2512 &e->lease_key,
2513 &fsp->file_id,
2514 &e_lease_type, /* current_state */
2515 &lease_is_breaking,
2516 NULL, /* breaking_to_requested */
2517 NULL, /* breaking_to_required */
2518 NULL, /* lease_version */
2519 NULL); /* epoch */
2522 * leases_db_get() can return NT_STATUS_NOT_FOUND
2523 * if the share_mode_entry e is stale and the
2524 * lease record was already removed. In this case return
2525 * false so the traverse continues.
2528 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND) &&
2529 share_entry_stale_pid(e))
2531 struct GUID_txt_buf guid_strbuf;
2532 struct file_id_buf file_id_strbuf;
2533 DBG_DEBUG("leases_db_get for client_guid [%s] "
2534 "lease_key [%"PRIu64"/%"PRIu64"] "
2535 "file_id [%s] failed for stale "
2536 "share_mode_entry\n",
2537 GUID_buf_string(&e->client_guid, &guid_strbuf),
2538 e->lease_key.data[0],
2539 e->lease_key.data[1],
2540 file_id_str_buf(fsp->file_id, &file_id_strbuf));
2541 return false;
2543 if (!NT_STATUS_IS_OK(status)) {
2544 struct GUID_txt_buf guid_strbuf;
2545 struct file_id_buf file_id_strbuf;
2546 DBG_ERR("leases_db_get for client_guid [%s] "
2547 "lease_key [%"PRIu64"/%"PRIu64"] "
2548 "file_id [%s] failed: %s\n",
2549 GUID_buf_string(&e->client_guid, &guid_strbuf),
2550 e->lease_key.data[0],
2551 e->lease_key.data[1],
2552 file_id_str_buf(fsp->file_id, &file_id_strbuf),
2553 nt_errstr(status));
2554 smb_panic("leases_db_get() failed");
2556 } else {
2557 e_lease_type = get_lease_type(e, fsp->file_id);
2560 if (((e_lease_type & ~state->total_lease_types) != 0) &&
2561 !share_entry_stale_pid(e))
2563 state->total_lease_types |= e_lease_type;
2566 if (!state->got_handle_lease &&
2567 ((e_lease_type & SMB2_LEASE_HANDLE) != 0) &&
2568 !share_entry_stale_pid(e)) {
2569 state->got_handle_lease = true;
2572 if (!state->got_oplock &&
2573 (e->op_type != NO_OPLOCK) &&
2574 (e->op_type != LEASE_OPLOCK) &&
2575 !share_entry_stale_pid(e)) {
2576 state->got_oplock = true;
2580 * Two things prevent a write lease
2581 * to be granted:
2583 * 1. Any oplock or lease (even broken to NONE)
2584 * 2. An open with an access mask other than
2585 * FILE_READ_ATTRIBUTES, FILE_WRITE_ATTRIBUTES
2586 * or SYNCHRONIZE_ACCESS
2588 if (!state->disallow_write_lease &&
2589 (e->op_type != NO_OPLOCK || !is_oplock_stat_open(e->access_mask)) &&
2590 !is_same_lease(fsp, e, lease) &&
2591 !share_entry_stale_pid(e))
2593 state->disallow_write_lease = true;
2596 if (e_is_lease && is_lease_stat_open(fsp->access_mask)) {
2597 return false;
2600 break_to = e_lease_type & ~state->delay_mask;
2602 if (state->will_overwrite) {
2603 break_to &= ~(SMB2_LEASE_HANDLE|SMB2_LEASE_READ);
2606 DBG_DEBUG("e_lease_type %u, will_overwrite: %u\n",
2607 (unsigned)e_lease_type,
2608 (unsigned)state->will_overwrite);
2610 if ((e_lease_type & ~break_to) == 0) {
2611 if (lease_is_breaking) {
2612 state->delay = true;
2614 return false;
2617 if (share_entry_stale_pid(e)) {
2618 return false;
2621 if (state->will_overwrite) {
2623 * If we break anyway break to NONE directly.
2624 * Otherwise vfs_set_filelen() will trigger the
2625 * break.
2627 break_to &= ~(SMB2_LEASE_READ|SMB2_LEASE_WRITE);
2630 if (!e_is_lease) {
2632 * Oplocks only support breaking to R or NONE.
2634 break_to &= ~(SMB2_LEASE_HANDLE|SMB2_LEASE_WRITE);
2637 DBG_DEBUG("breaking from %d to %d\n",
2638 (int)e_lease_type,
2639 (int)break_to);
2640 send_break_message(
2641 fsp->conn->sconn->msg_ctx, &fsp->file_id, e, break_to);
2642 if (e_lease_type & state->delay_mask) {
2643 state->delay = true;
2645 if (lease_is_breaking && !state->first_open_attempt) {
2646 state->delay = true;
2649 if (!state->delay) {
2650 return false;
2653 if (state->blocker_debug_state == NULL) {
2654 return false;
2657 subreq = server_id_watch_send(state->blocker_debug_state,
2658 fsp->conn->sconn->ev_ctx,
2659 e->pid);
2660 if (subreq == NULL) {
2661 DBG_ERR("server_id_watch_send(%s) returned NULL\n",
2662 server_id_str_buf(e->pid, &idbuf));
2663 return false;
2666 tevent_req_set_callback(subreq,
2667 delay_for_oplock_fn_watch_done,
2668 state->blocker_debug_state);
2670 state->blocker_debug_state->num_blockers++;
2672 DBG_DEBUG("Starting to watch pid [%s] state [%p] num_blockers [%zu]\n",
2673 server_id_str_buf(e->pid, &idbuf),
2674 state->blocker_debug_state,
2675 state->blocker_debug_state->num_blockers);
2677 return false;
2680 static void delay_for_oplock_fn_watch_done(struct tevent_req *subreq)
2682 struct blocker_debug_state *blocker_debug_state = tevent_req_callback_data(
2683 subreq, struct blocker_debug_state);
2684 struct server_id pid = {};
2685 struct server_id_buf idbuf = {};
2686 int ret;
2688 ret = server_id_watch_recv(subreq, &pid);
2689 if (ret != 0) {
2690 DBG_ERR("server_id_watch_recv failed %s\n", strerror(ret));
2691 return;
2694 DBG_DEBUG("state [%p] server_id_watch_recv() returned pid [%s] exited\n",
2695 blocker_debug_state,
2696 server_id_str_buf(pid, &idbuf));
2699 static NTSTATUS delay_for_oplock(files_struct *fsp,
2700 int oplock_request,
2701 const struct smb2_lease *lease,
2702 struct share_mode_lock *lck,
2703 bool have_sharing_violation,
2704 uint32_t create_disposition,
2705 bool first_open_attempt,
2706 int *poplock_type,
2707 uint32_t *pgranted,
2708 struct blocker_debug_state **blocker_debug_state)
2710 struct delay_for_oplock_state state = {
2711 .fsp = fsp,
2712 .lease = lease,
2713 .first_open_attempt = first_open_attempt,
2715 uint32_t requested;
2716 uint32_t granted;
2717 int oplock_type;
2718 bool ok;
2720 *poplock_type = NO_OPLOCK;
2721 *pgranted = 0;
2723 if (oplock_request == LEASE_OPLOCK) {
2724 if (lease == NULL) {
2726 * The SMB2 layer should have checked this
2728 return NT_STATUS_INTERNAL_ERROR;
2731 requested = lease->lease_state;
2732 if (fsp->fsp_flags.is_directory) {
2734 * According to "MS-FSA 2.1.5.18 Server Requests an
2735 * Oplock" this should fail with
2736 * STATUS_INVALID_PARAMETER, but Windows 2022 just
2737 * ignores the SMB2_LEASE_WRITE bit.
2739 requested &= ~SMB2_LEASE_WRITE;
2741 } else {
2742 requested = map_oplock_to_lease_type(
2743 oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK);
2746 share_mode_flags_get(lck, NULL, NULL, &state.total_lease_types);
2748 if (is_oplock_stat_open(fsp->access_mask)) {
2749 goto grant;
2752 if (lp_parm_bool(GLOBAL_SECTION_SNUM,
2753 "smbd lease break",
2754 "debug hung procs",
2755 false))
2757 state.blocker_debug_state = talloc_zero(fsp,
2758 struct blocker_debug_state);
2759 if (state.blocker_debug_state == NULL) {
2760 return NT_STATUS_NO_MEMORY;
2762 talloc_steal(talloc_tos(), state.blocker_debug_state);
2764 talloc_set_destructor(state.blocker_debug_state,
2765 blocker_debug_state_destructor);
2768 state.delay_mask = have_sharing_violation ?
2769 SMB2_LEASE_HANDLE : SMB2_LEASE_WRITE;
2771 switch (create_disposition) {
2772 case FILE_SUPERSEDE:
2773 case FILE_OVERWRITE:
2774 case FILE_OVERWRITE_IF:
2775 state.will_overwrite = true;
2776 break;
2777 default:
2778 state.will_overwrite = false;
2779 break;
2782 state.total_lease_types = SMB2_LEASE_NONE;
2783 ok = share_mode_forall_entries(lck, delay_for_oplock_fn, &state);
2784 if (!ok) {
2785 return NT_STATUS_INTERNAL_ERROR;
2788 if (state.delay) {
2789 *blocker_debug_state = state.blocker_debug_state;
2790 return NT_STATUS_RETRY;
2793 grant:
2794 if (have_sharing_violation) {
2795 return NT_STATUS_SHARING_VIOLATION;
2798 granted = requested;
2800 if (oplock_request == LEASE_OPLOCK) {
2801 if (lp_kernel_oplocks(SNUM(fsp->conn))) {
2802 DEBUG(10, ("No lease granted because kernel oplocks are enabled\n"));
2803 granted = SMB2_LEASE_NONE;
2805 if ((granted & (SMB2_LEASE_READ|SMB2_LEASE_WRITE)) == 0) {
2806 DEBUG(10, ("No read or write lease requested\n"));
2807 granted = SMB2_LEASE_NONE;
2809 if (granted == SMB2_LEASE_WRITE) {
2810 DEBUG(10, ("pure write lease requested\n"));
2811 granted = SMB2_LEASE_NONE;
2813 if (granted == (SMB2_LEASE_WRITE|SMB2_LEASE_HANDLE)) {
2814 DEBUG(10, ("write and handle lease requested\n"));
2815 granted = SMB2_LEASE_NONE;
2819 if (lp_locking(fsp->conn->params) && file_has_brlocks(fsp)) {
2820 DBG_DEBUG("file %s has byte range locks\n",
2821 fsp_str_dbg(fsp));
2822 granted &= ~SMB2_LEASE_READ;
2825 if (state.disallow_write_lease) {
2827 * Can grant only a write lease
2828 * if there are no other leases
2829 * and no other non-stat opens.
2831 granted &= ~SMB2_LEASE_WRITE;
2834 if ((granted & SMB2_LEASE_READ) && !(granted & SMB2_LEASE_WRITE)) {
2835 bool allow_level2 =
2836 (global_client_caps & CAP_LEVEL_II_OPLOCKS) &&
2837 lp_level2_oplocks(SNUM(fsp->conn));
2839 if (!allow_level2) {
2840 granted = SMB2_LEASE_NONE;
2844 if (oplock_request == LEASE_OPLOCK) {
2845 if (state.got_oplock) {
2846 granted &= ~SMB2_LEASE_HANDLE;
2849 oplock_type = LEASE_OPLOCK;
2850 } else {
2851 if (state.got_handle_lease) {
2852 granted = SMB2_LEASE_NONE;
2856 * Reflect possible downgrades from:
2857 * - map_lease_type_to_oplock() => "RH" to just LEVEL_II
2859 oplock_type = map_lease_type_to_oplock(granted);
2860 granted = map_oplock_to_lease_type(oplock_type);
2863 state.total_lease_types |= granted;
2866 uint32_t acc, sh, ls;
2867 share_mode_flags_get(lck, &acc, &sh, &ls);
2868 ls = state.total_lease_types;
2869 share_mode_flags_set(lck, acc, sh, ls, NULL);
2872 DBG_DEBUG("oplock type 0x%x granted (%s%s%s)(0x%x), on file %s, "
2873 "requested 0x%x (%s%s%s)(0x%x) => total (%s%s%s)(0x%x)\n",
2874 fsp->oplock_type,
2875 granted & SMB2_LEASE_READ ? "R":"",
2876 granted & SMB2_LEASE_WRITE ? "W":"",
2877 granted & SMB2_LEASE_HANDLE ? "H":"",
2878 granted,
2879 fsp_str_dbg(fsp),
2880 oplock_request,
2881 requested & SMB2_LEASE_READ ? "R":"",
2882 requested & SMB2_LEASE_WRITE ? "W":"",
2883 requested & SMB2_LEASE_HANDLE ? "H":"",
2884 requested,
2885 state.total_lease_types & SMB2_LEASE_READ ? "R":"",
2886 state.total_lease_types & SMB2_LEASE_WRITE ? "W":"",
2887 state.total_lease_types & SMB2_LEASE_HANDLE ? "H":"",
2888 state.total_lease_types);
2890 *poplock_type = oplock_type;
2891 *pgranted = granted;
2892 return NT_STATUS_OK;
2895 static NTSTATUS handle_share_mode_lease(
2896 files_struct *fsp,
2897 struct share_mode_lock *lck,
2898 uint32_t create_disposition,
2899 uint32_t access_mask,
2900 uint32_t share_access,
2901 int oplock_request,
2902 const struct smb2_lease *lease,
2903 bool first_open_attempt,
2904 int *poplock_type,
2905 uint32_t *pgranted,
2906 struct blocker_debug_state **blocker_debug_state)
2908 bool sharing_violation = false;
2909 NTSTATUS status;
2911 *poplock_type = NO_OPLOCK;
2912 *pgranted = 0;
2914 status = open_mode_check(
2915 fsp->conn, fsp->file_id, lck, access_mask, share_access);
2916 if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
2917 sharing_violation = true;
2918 status = NT_STATUS_OK; /* handled later */
2921 if (!NT_STATUS_IS_OK(status)) {
2922 return status;
2925 if (fsp->fsp_flags.is_directory &&
2926 oplock_request == LEASE_OPLOCK &&
2927 !lp_smb3_directory_leases())
2929 DBG_NOTICE("Ignoring disabled DirectoryLease request on [%s]\n",
2930 fsp_str_dbg(fsp));
2931 oplock_request = NO_OPLOCK;
2932 lease = NULL;
2935 if (oplock_request == INTERNAL_OPEN_ONLY) {
2936 if (sharing_violation) {
2937 DBG_DEBUG("Sharing violation for internal open\n");
2938 return NT_STATUS_SHARING_VIOLATION;
2942 * Internal opens never do oplocks or leases. We don't
2943 * need to go through delay_for_oplock().
2945 return NT_STATUS_OK;
2948 status = delay_for_oplock(
2949 fsp,
2950 oplock_request,
2951 lease,
2952 lck,
2953 sharing_violation,
2954 create_disposition,
2955 first_open_attempt,
2956 poplock_type,
2957 pgranted,
2958 blocker_debug_state);
2959 if (!NT_STATUS_IS_OK(status)) {
2960 return status;
2963 return NT_STATUS_OK;
2966 static bool request_timed_out(struct smb_request *req, struct timeval timeout)
2968 struct timeval end_time = timeval_sum(&req->request_time, &timeout);
2969 return timeval_expired(&end_time);
2972 struct defer_open_state {
2973 struct smbXsrv_connection *xconn;
2974 uint64_t mid;
2977 static void defer_open_done(struct tevent_req *req);
2980 * Defer an open and watch a locking.tdb record
2982 * This defers an open that gets rescheduled once the locking.tdb record watch
2983 * is triggered by a change to the record.
2985 * It is used to defer opens that triggered an oplock break and for the SMB1
2986 * sharing violation delay.
2988 static void defer_open(struct share_mode_lock *lck,
2989 struct timeval timeout,
2990 struct smb_request *req,
2991 struct file_id id,
2992 struct blocker_debug_state **blocker_debug_state)
2994 struct deferred_open_record *open_rec = NULL;
2995 struct timeval abs_timeout;
2996 struct defer_open_state *watch_state;
2997 struct tevent_req *watch_req;
2998 struct timeval_buf tvbuf1, tvbuf2;
2999 struct file_id_buf fbuf;
3000 bool ok;
3002 abs_timeout = timeval_sum(&req->request_time, &timeout);
3004 DBG_DEBUG("request time [%s] timeout [%s] mid [%" PRIu64 "] "
3005 "file_id [%s]\n",
3006 timeval_str_buf(&req->request_time, false, true, &tvbuf1),
3007 timeval_str_buf(&abs_timeout, false, true, &tvbuf2),
3008 req->mid,
3009 file_id_str_buf(id, &fbuf));
3011 open_rec = talloc_zero(NULL, struct deferred_open_record);
3012 if (open_rec == NULL) {
3013 TALLOC_FREE(lck);
3014 exit_server("talloc failed");
3017 watch_state = talloc(open_rec, struct defer_open_state);
3018 if (watch_state == NULL) {
3019 exit_server("talloc failed");
3021 watch_state->xconn = req->xconn;
3022 watch_state->mid = req->mid;
3024 DBG_DEBUG("deferring mid %" PRIu64 "\n", req->mid);
3026 watch_req = share_mode_watch_send(
3027 watch_state,
3028 req->sconn->ev_ctx,
3029 &id,
3030 (struct server_id){0});
3031 if (watch_req == NULL) {
3032 exit_server("Could not watch share mode record");
3034 tevent_req_set_callback(watch_req, defer_open_done, watch_state);
3036 talloc_move(watch_req, blocker_debug_state);
3038 ok = tevent_req_set_endtime(watch_req, req->sconn->ev_ctx, abs_timeout);
3039 if (!ok) {
3040 exit_server("tevent_req_set_endtime failed");
3043 ok = push_deferred_open_message_smb(req, timeout, id, open_rec);
3044 if (!ok) {
3045 TALLOC_FREE(lck);
3046 exit_server("push_deferred_open_message_smb failed");
3050 static void defer_open_done(struct tevent_req *req)
3052 struct defer_open_state *state = tevent_req_callback_data(
3053 req, struct defer_open_state);
3054 NTSTATUS status;
3055 bool ret;
3057 status = share_mode_watch_recv(req, NULL, NULL);
3058 TALLOC_FREE(req);
3059 if (!NT_STATUS_IS_OK(status)) {
3060 DBG_ERR("share_mode_watch_recv() returned %s, "
3061 "rescheduling mid %" PRIu64 "\n",
3062 nt_errstr(status), state->mid);
3064 * Even if it failed, retry anyway. TODO: We need a way to
3065 * tell a re-scheduled open about that error.
3069 DEBUG(10, ("scheduling mid %llu\n", (unsigned long long)state->mid));
3071 ret = schedule_deferred_open_message_smb(state->xconn, state->mid);
3072 SMB_ASSERT(ret);
3073 TALLOC_FREE(state);
3077 * Actually attempt the kernel oplock polling open.
3080 static void poll_open_fn(struct tevent_context *ev,
3081 struct tevent_timer *te,
3082 struct timeval current_time,
3083 void *private_data)
3085 struct deferred_open_record *open_rec = talloc_get_type_abort(
3086 private_data, struct deferred_open_record);
3087 bool ok;
3089 TALLOC_FREE(open_rec->watch_req);
3091 ok = schedule_deferred_open_message_smb(
3092 open_rec->xconn, open_rec->mid);
3093 if (!ok) {
3094 exit_server("schedule_deferred_open_message_smb failed");
3096 DBG_DEBUG("timer fired. Retrying open !\n");
3099 static void poll_open_done(struct tevent_req *subreq);
3101 struct poll_open_setup_watcher_state {
3102 TALLOC_CTX *mem_ctx;
3103 struct tevent_context *ev_ctx;
3104 struct tevent_req *watch_req;
3105 struct file_id id;
3108 static void poll_open_setup_watcher_fn(struct share_mode_lock *lck,
3109 void *private_data)
3111 struct poll_open_setup_watcher_state *state =
3112 (struct poll_open_setup_watcher_state *)private_data;
3114 if (!validate_oplock_types(lck)) {
3115 smb_panic("validate_oplock_types failed");
3118 state->watch_req = share_mode_watch_send(
3119 state->mem_ctx,
3120 state->ev_ctx,
3121 &state->id,
3122 (struct server_id) {0});
3123 if (state->watch_req == NULL) {
3124 DBG_WARNING("share_mode_watch_send failed\n");
3125 return;
3130 * Reschedule an open for 1 second from now, if not timed out.
3132 static bool setup_poll_open(
3133 struct smb_request *req,
3134 const struct file_id *id,
3135 struct timeval max_timeout,
3136 struct timeval interval)
3138 static struct file_id zero_id = {};
3139 bool ok;
3140 struct deferred_open_record *open_rec = NULL;
3141 struct timeval endtime, next_interval;
3142 struct file_id_buf ftmp;
3144 if (request_timed_out(req, max_timeout)) {
3145 return false;
3148 open_rec = talloc_zero(NULL, struct deferred_open_record);
3149 if (open_rec == NULL) {
3150 DBG_WARNING("talloc failed\n");
3151 return false;
3153 open_rec->xconn = req->xconn;
3154 open_rec->mid = req->mid;
3157 * Make sure open_rec->te does not come later than the
3158 * request's maximum endtime.
3161 endtime = timeval_sum(&req->request_time, &max_timeout);
3162 next_interval = timeval_current_ofs(interval.tv_sec, interval.tv_usec);
3163 next_interval = timeval_min(&endtime, &next_interval);
3165 open_rec->te = tevent_add_timer(
3166 req->sconn->ev_ctx,
3167 open_rec,
3168 next_interval,
3169 poll_open_fn,
3170 open_rec);
3171 if (open_rec->te == NULL) {
3172 DBG_WARNING("tevent_add_timer failed\n");
3173 TALLOC_FREE(open_rec);
3174 return false;
3177 if (id != NULL) {
3178 struct poll_open_setup_watcher_state wstate = {
3179 .mem_ctx = open_rec,
3180 .ev_ctx = req->sconn->ev_ctx,
3181 .id = *id,
3183 NTSTATUS status;
3185 status = share_mode_do_locked_vfs_denied(*id,
3186 poll_open_setup_watcher_fn,
3187 &wstate);
3188 if (NT_STATUS_IS_OK(status)) {
3189 if (wstate.watch_req == NULL) {
3190 DBG_WARNING("share_mode_watch_send failed\n");
3191 TALLOC_FREE(open_rec);
3192 return false;
3194 open_rec->watch_req = wstate.watch_req;
3195 tevent_req_set_callback(open_rec->watch_req,
3196 poll_open_done,
3197 open_rec);
3198 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
3199 DBG_WARNING("share_mode_do_locked_vfs_denied failed - %s\n",
3200 nt_errstr(status));
3201 TALLOC_FREE(open_rec);
3202 return false;
3204 } else {
3205 id = &zero_id;
3208 ok = push_deferred_open_message_smb(req, max_timeout, *id, open_rec);
3209 if (!ok) {
3210 DBG_WARNING("push_deferred_open_message_smb failed\n");
3211 TALLOC_FREE(open_rec);
3212 return false;
3215 DBG_DEBUG("poll request time [%s] mid [%" PRIu64 "] file_id [%s]\n",
3216 timeval_string(talloc_tos(), &req->request_time, false),
3217 req->mid,
3218 file_id_str_buf(*id, &ftmp));
3220 return true;
3223 static void poll_open_done(struct tevent_req *subreq)
3225 struct deferred_open_record *open_rec = tevent_req_callback_data(
3226 subreq, struct deferred_open_record);
3227 NTSTATUS status;
3228 bool ok;
3230 status = share_mode_watch_recv(subreq, NULL, NULL);
3231 TALLOC_FREE(subreq);
3232 open_rec->watch_req = NULL;
3233 TALLOC_FREE(open_rec->te);
3235 DBG_DEBUG("dbwrap_watched_watch_recv returned %s\n",
3236 nt_errstr(status));
3238 ok = schedule_deferred_open_message_smb(
3239 open_rec->xconn, open_rec->mid);
3240 if (!ok) {
3241 exit_server("schedule_deferred_open_message_smb failed");
3245 bool defer_smb1_sharing_violation(struct smb_request *req)
3247 bool ok;
3248 int timeout_usecs;
3250 if (!lp_defer_sharing_violations()) {
3251 return false;
3255 * Try every 200msec up to (by default) one second. To be
3256 * precise, according to behaviour note <247> in [MS-CIFS],
3257 * the server tries 5 times. But up to one second should be
3258 * close enough.
3261 timeout_usecs = lp_parm_int(
3262 SNUM(req->conn),
3263 "smbd",
3264 "sharedelay",
3265 SHARING_VIOLATION_USEC_WAIT);
3267 ok = setup_poll_open(
3268 req,
3269 NULL,
3270 (struct timeval) { .tv_usec = timeout_usecs },
3271 (struct timeval) { .tv_usec = 200000 });
3272 return ok;
3275 /****************************************************************************
3276 On overwrite open ensure that the attributes match.
3277 ****************************************************************************/
3279 static bool open_match_attributes(connection_struct *conn,
3280 uint32_t old_dos_attr,
3281 uint32_t new_dos_attr,
3282 mode_t new_unx_mode,
3283 mode_t *returned_unx_mode)
3285 uint32_t noarch_old_dos_attr, noarch_new_dos_attr;
3287 noarch_old_dos_attr = (old_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
3288 noarch_new_dos_attr = (new_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
3290 if((noarch_old_dos_attr == 0 && noarch_new_dos_attr != 0) ||
3291 (noarch_old_dos_attr != 0 && ((noarch_old_dos_attr & noarch_new_dos_attr) == noarch_old_dos_attr))) {
3292 *returned_unx_mode = new_unx_mode;
3293 } else {
3294 *returned_unx_mode = (mode_t)0;
3297 DEBUG(10,("open_match_attributes: old_dos_attr = 0x%x, "
3298 "new_dos_attr = 0x%x "
3299 "returned_unx_mode = 0%o\n",
3300 (unsigned int)old_dos_attr,
3301 (unsigned int)new_dos_attr,
3302 (unsigned int)*returned_unx_mode ));
3304 /* If we're mapping SYSTEM and HIDDEN ensure they match. */
3305 if (lp_map_system(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
3306 if ((old_dos_attr & FILE_ATTRIBUTE_SYSTEM) &&
3307 !(new_dos_attr & FILE_ATTRIBUTE_SYSTEM)) {
3308 return False;
3311 if (lp_map_hidden(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
3312 if ((old_dos_attr & FILE_ATTRIBUTE_HIDDEN) &&
3313 !(new_dos_attr & FILE_ATTRIBUTE_HIDDEN)) {
3314 return False;
3317 return True;
3320 static void schedule_defer_open(struct share_mode_lock *lck,
3321 struct file_id id,
3322 struct smb_request *req,
3323 struct blocker_debug_state **blocker_debug_state)
3325 /* This is a relative time, added to the absolute
3326 request_time value to get the absolute timeout time.
3327 Note that if this is the second or greater time we enter
3328 this codepath for this particular request mid then
3329 request_time is left as the absolute time of the *first*
3330 time this request mid was processed. This is what allows
3331 the request to eventually time out. */
3333 struct timeval timeout;
3335 /* Normally the smbd we asked should respond within
3336 * OPLOCK_BREAK_TIMEOUT seconds regardless of whether
3337 * the client did, give twice the timeout as a safety
3338 * measure here in case the other smbd is stuck
3339 * somewhere else. */
3341 timeout = tevent_timeval_set(OPLOCK_BREAK_TIMEOUT * 2, 0);
3343 if (request_timed_out(req, timeout)) {
3344 return;
3347 defer_open(lck, timeout, req, id, blocker_debug_state);
3350 /****************************************************************************
3351 Reschedule an open call that went asynchronous.
3352 ****************************************************************************/
3354 static void schedule_async_open_timer(struct tevent_context *ev,
3355 struct tevent_timer *te,
3356 struct timeval current_time,
3357 void *private_data)
3359 exit_server("async open timeout");
3362 static void schedule_async_open(struct smb_request *req)
3364 struct deferred_open_record *open_rec = NULL;
3365 struct timeval timeout = tevent_timeval_set(20, 0);
3366 bool ok;
3368 if (request_timed_out(req, timeout)) {
3369 return;
3372 open_rec = talloc_zero(NULL, struct deferred_open_record);
3373 if (open_rec == NULL) {
3374 exit_server("deferred_open_record_create failed");
3376 open_rec->async_open = true;
3378 ok = push_deferred_open_message_smb(
3379 req, timeout, (struct file_id){0}, open_rec);
3380 if (!ok) {
3381 exit_server("push_deferred_open_message_smb failed");
3384 open_rec->te = tevent_add_timer(req->sconn->ev_ctx,
3385 req,
3386 timeval_current_ofs(20, 0),
3387 schedule_async_open_timer,
3388 open_rec);
3389 if (open_rec->te == NULL) {
3390 exit_server("tevent_add_timer failed");
3394 static NTSTATUS check_and_store_share_mode(
3395 struct files_struct *fsp,
3396 struct smb_request *req,
3397 struct share_mode_lock *lck,
3398 uint32_t create_disposition,
3399 uint32_t access_mask,
3400 uint32_t open_access_mask,
3401 uint32_t share_access,
3402 int oplock_request,
3403 const struct smb2_lease *lease,
3404 bool first_open_attempt)
3406 NTSTATUS status;
3407 int oplock_type = NO_OPLOCK;
3408 uint32_t granted_lease = 0;
3409 const struct smb2_lease_key *lease_key = NULL;
3410 struct blocker_debug_state *blocker_debug_state = NULL;
3411 bool delete_on_close;
3412 bool ok;
3414 /* Get the types we need to examine. */
3415 if (!validate_oplock_types(lck)) {
3416 smb_panic("validate_oplock_types failed");
3419 delete_on_close = has_delete_on_close(lck, fsp->name_hash);
3420 if (delete_on_close) {
3421 return NT_STATUS_DELETE_PENDING;
3424 status = handle_share_mode_lease(fsp,
3425 lck,
3426 create_disposition,
3427 open_access_mask,
3428 share_access,
3429 oplock_request,
3430 lease,
3431 first_open_attempt,
3432 &oplock_type,
3433 &granted_lease,
3434 &blocker_debug_state);
3435 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
3436 schedule_defer_open(lck, fsp->file_id, req, &blocker_debug_state);
3437 return NT_STATUS_SHARING_VIOLATION;
3439 if (!NT_STATUS_IS_OK(status)) {
3440 return status;
3443 if (oplock_type == LEASE_OPLOCK) {
3444 lease_key = &lease->lease_key;
3447 share_mode_flags_restrict(lck, access_mask, share_access, 0);
3449 ok = set_share_mode(lck,
3450 fsp,
3451 get_current_uid(fsp->conn),
3452 req ? req->mid : 0,
3453 oplock_type,
3454 lease_key,
3455 share_access,
3456 access_mask);
3457 if (!ok) {
3458 return NT_STATUS_NO_MEMORY;
3461 if (oplock_type == LEASE_OPLOCK) {
3462 status = grant_fsp_lease(fsp, lck, lease, granted_lease);
3463 if (!NT_STATUS_IS_OK(status)) {
3464 del_share_mode(lck, fsp);
3465 return status;
3468 DBG_DEBUG("lease_state=%d\n", fsp->lease->lease.lease_state);
3471 fsp->oplock_type = oplock_type;
3473 return NT_STATUS_OK;
3476 /****************************************************************************
3477 Work out what access_mask to use from what the client sent us.
3478 ****************************************************************************/
3480 static NTSTATUS smbd_calculate_maximum_allowed_access_fsp(
3481 struct files_struct *dirfsp,
3482 struct files_struct *fsp,
3483 bool use_privs,
3484 uint32_t *p_access_mask)
3486 struct security_descriptor *sd = NULL;
3487 uint32_t access_granted = 0;
3488 uint32_t dosattrs;
3489 NTSTATUS status;
3491 /* Cope with symlinks */
3492 if (fsp == NULL || fsp_get_pathref_fd(fsp) == -1) {
3493 *p_access_mask = FILE_GENERIC_ALL;
3494 return NT_STATUS_OK;
3497 /* Cope with fake/printer fsp's. */
3498 if (fsp->fake_file_handle != NULL || fsp->print_file != NULL) {
3499 *p_access_mask = FILE_GENERIC_ALL;
3500 return NT_STATUS_OK;
3503 if (!use_privs && (get_current_uid(fsp->conn) == (uid_t)0)) {
3504 *p_access_mask |= FILE_GENERIC_ALL;
3505 return NT_STATUS_OK;
3508 status = SMB_VFS_FGET_NT_ACL(metadata_fsp(fsp),
3509 (SECINFO_OWNER |
3510 SECINFO_GROUP |
3511 SECINFO_DACL),
3512 talloc_tos(),
3513 &sd);
3515 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
3517 * File did not exist
3519 *p_access_mask = FILE_GENERIC_ALL;
3520 return NT_STATUS_OK;
3522 if (!NT_STATUS_IS_OK(status)) {
3523 DBG_ERR("Could not get acl on file %s: %s\n",
3524 fsp_str_dbg(fsp),
3525 nt_errstr(status));
3526 return status;
3530 * If we can access the path to this file, by
3531 * default we have FILE_READ_ATTRIBUTES from the
3532 * containing directory. See the section:
3533 * "Algorithm to Check Access to an Existing File"
3534 * in MS-FSA.pdf.
3536 * se_file_access_check()
3537 * also takes care of owner WRITE_DAC and READ_CONTROL.
3539 status = se_file_access_check(sd,
3540 get_current_nttok(fsp->conn),
3541 use_privs,
3542 (*p_access_mask & ~FILE_READ_ATTRIBUTES),
3543 &access_granted);
3545 TALLOC_FREE(sd);
3547 if (!NT_STATUS_IS_OK(status)) {
3548 DBG_ERR("Status %s on file %s: "
3549 "when calculating maximum access\n",
3550 nt_errstr(status),
3551 fsp_str_dbg(fsp));
3552 return status;
3555 *p_access_mask = (access_granted | FILE_READ_ATTRIBUTES);
3557 if (!(access_granted & DELETE_ACCESS)) {
3558 if (can_delete_file_in_directory(fsp->conn,
3559 dirfsp,
3560 fsp->fsp_name)) {
3561 *p_access_mask |= DELETE_ACCESS;
3565 dosattrs = fdos_mode(fsp);
3566 if ((dosattrs & FILE_ATTRIBUTE_READONLY) || !CAN_WRITE(fsp->conn)) {
3567 *p_access_mask &= ~(FILE_GENERIC_WRITE | DELETE_ACCESS);
3570 return NT_STATUS_OK;
3573 NTSTATUS smbd_calculate_access_mask_fsp(struct files_struct *dirfsp,
3574 struct files_struct *fsp,
3575 bool use_privs,
3576 uint32_t access_mask,
3577 uint32_t *access_mask_out)
3579 NTSTATUS status;
3580 uint32_t orig_access_mask = access_mask;
3581 uint32_t rejected_share_access;
3583 if (access_mask & SEC_MASK_INVALID) {
3584 DBG_DEBUG("access_mask [%8x] contains invalid bits\n",
3585 access_mask);
3586 return NT_STATUS_ACCESS_DENIED;
3590 * Convert GENERIC bits to specific bits.
3593 se_map_generic(&access_mask, &file_generic_mapping);
3595 /* Calculate MAXIMUM_ALLOWED_ACCESS if requested. */
3596 if (access_mask & MAXIMUM_ALLOWED_ACCESS) {
3598 status = smbd_calculate_maximum_allowed_access_fsp(
3599 dirfsp,
3600 fsp,
3601 use_privs,
3602 &access_mask);
3604 if (!NT_STATUS_IS_OK(status)) {
3605 return status;
3608 access_mask &= fsp->conn->share_access;
3611 rejected_share_access = access_mask & ~(fsp->conn->share_access);
3613 if (rejected_share_access) {
3614 DBG_INFO("Access denied on file %s: "
3615 "rejected by share access mask[0x%08X] "
3616 "orig[0x%08X] mapped[0x%08X] reject[0x%08X]\n",
3617 fsp_str_dbg(fsp),
3618 fsp->conn->share_access,
3619 orig_access_mask, access_mask,
3620 rejected_share_access);
3621 return NT_STATUS_ACCESS_DENIED;
3624 *access_mask_out = access_mask;
3625 return NT_STATUS_OK;
3628 /****************************************************************************
3629 Remove the deferred open entry under lock.
3630 ****************************************************************************/
3632 /****************************************************************************
3633 Return true if this is a state pointer to an asynchronous create.
3634 ****************************************************************************/
3636 bool is_deferred_open_async(const struct deferred_open_record *rec)
3638 return rec->async_open;
3641 static bool clear_ads(uint32_t create_disposition)
3643 bool ret = false;
3645 switch (create_disposition) {
3646 case FILE_SUPERSEDE:
3647 case FILE_OVERWRITE_IF:
3648 case FILE_OVERWRITE:
3649 ret = true;
3650 break;
3651 default:
3652 break;
3654 return ret;
3657 static int disposition_to_open_flags(uint32_t create_disposition)
3659 int ret = 0;
3662 * Currently we're using FILE_SUPERSEDE as the same as
3663 * FILE_OVERWRITE_IF but they really are
3664 * different. FILE_SUPERSEDE deletes an existing file
3665 * (requiring delete access) then recreates it.
3668 switch (create_disposition) {
3669 case FILE_SUPERSEDE:
3670 case FILE_OVERWRITE_IF:
3672 * If file exists replace/overwrite. If file doesn't
3673 * exist create.
3675 ret = O_CREAT|O_TRUNC;
3676 break;
3678 case FILE_OPEN:
3680 * If file exists open. If file doesn't exist error.
3682 ret = 0;
3683 break;
3685 case FILE_OVERWRITE:
3687 * If file exists overwrite. If file doesn't exist
3688 * error.
3690 ret = O_TRUNC;
3691 break;
3693 case FILE_CREATE:
3695 * If file exists error. If file doesn't exist create.
3697 ret = O_CREAT|O_EXCL;
3698 break;
3700 case FILE_OPEN_IF:
3702 * If file exists open. If file doesn't exist create.
3704 ret = O_CREAT;
3705 break;
3707 return ret;
3710 static int calculate_open_access_flags(uint32_t access_mask,
3711 uint32_t private_flags,
3712 NTTIME twrp)
3714 bool need_write, need_read;
3717 * Note that we ignore the append flag as append does not
3718 * mean the same thing under DOS and Unix.
3721 if (twrp != 0) {
3723 * Pave over the user requested mode and force O_RDONLY for the
3724 * file handle. Windows allows opening a VSS file with O_RDWR,
3725 * even though actual writes on the handle will fail.
3727 return O_RDONLY;
3730 need_write = (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA));
3731 if (!need_write) {
3732 return O_RDONLY;
3735 /* DENY_DOS opens are always underlying read-write on the
3736 file handle, no matter what the requested access mask
3737 says. */
3739 need_read =
3740 ((private_flags & NTCREATEX_FLAG_DENY_DOS) ||
3741 access_mask & (FILE_READ_ATTRIBUTES|FILE_READ_DATA|
3742 FILE_READ_EA|FILE_EXECUTE));
3744 if (!need_read) {
3745 return O_WRONLY;
3747 return O_RDWR;
3750 struct open_ntcreate_lock_state {
3751 struct share_mode_entry_prepare_state prepare_state;
3752 struct files_struct *fsp;
3753 const char *object_type;
3754 struct smb_request *req;
3755 uint32_t create_disposition;
3756 uint32_t access_mask;
3757 uint32_t open_access_mask;
3758 uint32_t share_access;
3759 int oplock_request;
3760 const struct smb2_lease *lease;
3761 bool first_open_attempt;
3762 bool keep_locked;
3763 NTSTATUS status;
3764 struct timespec write_time;
3765 share_mode_entry_prepare_unlock_fn_t cleanup_fn;
3768 static void open_ntcreate_lock_add_entry(struct share_mode_lock *lck,
3769 bool *keep_locked,
3770 void *private_data)
3772 struct open_ntcreate_lock_state *state =
3773 (struct open_ntcreate_lock_state *)private_data;
3776 * By default drop the g_lock again if we leave the
3777 * tdb chainlock.
3779 *keep_locked = false;
3781 state->status = check_and_store_share_mode(state->fsp,
3782 state->req,
3783 lck,
3784 state->create_disposition,
3785 state->access_mask,
3786 state->open_access_mask,
3787 state->share_access,
3788 state->oplock_request,
3789 state->lease,
3790 state->first_open_attempt);
3791 if (!NT_STATUS_IS_OK(state->status)) {
3792 return;
3795 state->write_time = get_share_mode_write_time(lck);
3798 * keep the g_lock while existing the tdb chainlock,
3799 * we we're asked to, which mean we'll keep
3800 * the share_mode_lock during object creation,
3801 * or setting delete on close.
3803 *keep_locked = state->keep_locked;
3806 static void open_ntcreate_lock_cleanup_oplock(struct share_mode_lock *lck,
3807 void *private_data)
3809 struct open_ntcreate_lock_state *state =
3810 (struct open_ntcreate_lock_state *)private_data;
3811 bool ok;
3813 ok = remove_share_oplock(lck, state->fsp);
3814 if (!ok) {
3815 DBG_ERR("Could not remove oplock for %s %s\n",
3816 state->object_type, fsp_str_dbg(state->fsp));
3820 static void open_ntcreate_lock_cleanup_entry(struct share_mode_lock *lck,
3821 void *private_data)
3823 struct open_ntcreate_lock_state *state =
3824 (struct open_ntcreate_lock_state *)private_data;
3825 bool ok;
3827 ok = del_share_mode(lck, state->fsp);
3828 if (!ok) {
3829 DBG_ERR("Could not delete share entry for %s %s\n",
3830 state->object_type, fsp_str_dbg(state->fsp));
3834 static void possibly_set_archive(struct connection_struct *conn,
3835 struct files_struct *fsp,
3836 struct smb_filename *smb_fname,
3837 struct smb_filename *parent_dir_fname,
3838 int info,
3839 uint32_t dosattrs,
3840 mode_t *unx_mode)
3842 bool set_archive = false;
3843 int ret;
3845 if (info == FILE_WAS_OPENED) {
3846 return;
3849 /* Overwritten files should be initially set as archive */
3850 if ((info == FILE_WAS_OVERWRITTEN && lp_map_archive(SNUM(conn)))) {
3851 set_archive = true;
3852 } else if (lp_store_dos_attributes(SNUM(conn))) {
3853 set_archive = true;
3855 if (!set_archive) {
3856 return;
3859 ret = file_set_dosmode(conn,
3860 smb_fname,
3861 dosattrs | FILE_ATTRIBUTE_ARCHIVE,
3862 parent_dir_fname,
3863 true);
3864 if (ret != 0) {
3865 return;
3867 *unx_mode = smb_fname->st.st_ex_mode;
3870 /****************************************************************************
3871 Open a file with a share mode. Passed in an already created files_struct *.
3872 ****************************************************************************/
3874 static NTSTATUS open_file_ntcreate(connection_struct *conn,
3875 struct smb_request *req,
3876 uint32_t access_mask, /* access bits (FILE_READ_DATA etc.) */
3877 uint32_t share_access, /* share constants (FILE_SHARE_READ etc) */
3878 uint32_t create_disposition, /* FILE_OPEN_IF etc. */
3879 uint32_t create_options, /* options such as delete on close. */
3880 uint32_t new_dos_attributes, /* attributes used for new file. */
3881 int oplock_request, /* internal Samba oplock codes. */
3882 const struct smb2_lease *lease,
3883 /* Information (FILE_EXISTS etc.) */
3884 uint32_t private_flags, /* Samba specific flags. */
3885 struct smb_filename *parent_dir_fname, /* parent. */
3886 struct smb_filename *smb_fname_atname, /* atname relative to parent. */
3887 int *pinfo,
3888 files_struct *fsp)
3890 struct smb_filename *smb_fname = fsp->fsp_name;
3891 int flags=0;
3892 bool file_existed = VALID_STAT(smb_fname->st);
3893 bool def_acl = False;
3894 bool posix_open = False;
3895 bool new_file_created = False;
3896 bool truncated = false;
3897 bool first_open_attempt = true;
3898 bool is_twrp = (smb_fname_atname->twrp != 0);
3899 NTSTATUS fsp_open = NT_STATUS_ACCESS_DENIED;
3900 mode_t new_unx_mode = (mode_t)0;
3901 mode_t unx_mode = (mode_t)0;
3902 int info;
3903 uint32_t existing_dos_attributes = 0;
3904 struct open_ntcreate_lock_state lck_state = {};
3905 bool keep_locked = false;
3906 uint32_t open_access_mask = access_mask;
3907 NTSTATUS status;
3908 SMB_STRUCT_STAT saved_stat = smb_fname->st;
3909 struct timespec old_write_time;
3910 bool setup_poll = false;
3911 NTSTATUS ulstatus;
3913 if (conn->printer) {
3915 * Printers are handled completely differently.
3916 * Most of the passed parameters are ignored.
3919 if (pinfo) {
3920 *pinfo = FILE_WAS_CREATED;
3923 DBG_DEBUG("printer open fname=%s\n",
3924 smb_fname_str_dbg(smb_fname));
3926 if (!req) {
3927 DBG_ERR("printer open without an SMB request!\n");
3928 return NT_STATUS_INTERNAL_ERROR;
3931 return print_spool_open(fsp, smb_fname->base_name,
3932 req->vuid);
3935 if (new_dos_attributes & FILE_FLAG_POSIX_SEMANTICS) {
3936 posix_open = True;
3937 unx_mode = (mode_t)(new_dos_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
3938 new_dos_attributes = 0;
3939 } else {
3940 /* Windows allows a new file to be created and
3941 silently removes a FILE_ATTRIBUTE_DIRECTORY
3942 sent by the client. Do the same. */
3944 new_dos_attributes &= ~FILE_ATTRIBUTE_DIRECTORY;
3946 /* We add FILE_ATTRIBUTE_ARCHIVE to this as this mode is only used if the file is
3947 * created new. */
3948 unx_mode = unix_mode(
3949 conn,
3950 new_dos_attributes | FILE_ATTRIBUTE_ARCHIVE,
3951 smb_fname,
3952 parent_dir_fname->fsp);
3955 DEBUG(10, ("open_file_ntcreate: fname=%s, dos_attrs=0x%x "
3956 "access_mask=0x%x share_access=0x%x "
3957 "create_disposition = 0x%x create_options=0x%x "
3958 "unix mode=0%o oplock_request=%d private_flags = 0x%x\n",
3959 smb_fname_str_dbg(smb_fname), new_dos_attributes,
3960 access_mask, share_access, create_disposition,
3961 create_options, (unsigned int)unx_mode, oplock_request,
3962 (unsigned int)private_flags));
3964 if (req == NULL) {
3965 /* Ensure req == NULL means INTERNAL_OPEN_ONLY */
3966 SMB_ASSERT(oplock_request == INTERNAL_OPEN_ONLY);
3967 } else {
3968 /* And req != NULL means no INTERNAL_OPEN_ONLY */
3969 SMB_ASSERT(((oplock_request & INTERNAL_OPEN_ONLY) == 0));
3973 * Only non-internal opens can be deferred at all
3976 if (req) {
3977 struct deferred_open_record *open_rec;
3978 if (get_deferred_open_message_state(req, NULL, &open_rec)) {
3980 /* If it was an async create retry, the file
3981 didn't exist. */
3983 if (is_deferred_open_async(open_rec)) {
3984 SET_STAT_INVALID(smb_fname->st);
3985 file_existed = false;
3988 /* Ensure we don't reprocess this message. */
3989 remove_deferred_open_message_smb(req->xconn, req->mid);
3991 first_open_attempt = false;
3995 if (!posix_open) {
3996 new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
3997 if (file_existed) {
3999 * Only use stored DOS attributes for checks
4000 * against requested attributes (below via
4001 * open_match_attributes()), cf bug #11992
4002 * for details. -slow
4004 uint32_t attr = 0;
4006 status = SMB_VFS_FGET_DOS_ATTRIBUTES(
4007 conn,
4008 metadata_fsp(smb_fname->fsp),
4009 &attr);
4010 if (NT_STATUS_IS_OK(status)) {
4011 existing_dos_attributes = attr;
4016 /* ignore any oplock requests if oplocks are disabled */
4017 if (!lp_oplocks(SNUM(conn)) ||
4018 IS_VETO_OPLOCK_PATH(conn, smb_fname->base_name)) {
4019 /* Mask off everything except the private Samba bits. */
4020 oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
4023 /* this is for OS/2 long file names - say we don't support them */
4024 if (req != NULL && !req->posix_pathnames &&
4025 strstr(smb_fname->base_name,".+,;=[].")) {
4026 /* OS/2 Workplace shell fix may be main code stream in a later
4027 * release. */
4028 DEBUG(5,("open_file_ntcreate: OS/2 long filenames are not "
4029 "supported.\n"));
4030 if (use_nt_status()) {
4031 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4033 return NT_STATUS_DOS(ERRDOS, ERRcannotopen);
4036 switch( create_disposition ) {
4037 case FILE_OPEN:
4038 /* If file exists open. If file doesn't exist error. */
4039 if (!file_existed) {
4040 DEBUG(5,("open_file_ntcreate: FILE_OPEN "
4041 "requested for file %s and file "
4042 "doesn't exist.\n",
4043 smb_fname_str_dbg(smb_fname)));
4044 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4046 break;
4048 case FILE_OVERWRITE:
4049 /* If file exists overwrite. If file doesn't exist
4050 * error. */
4051 if (!file_existed) {
4052 DEBUG(5,("open_file_ntcreate: FILE_OVERWRITE "
4053 "requested for file %s and file "
4054 "doesn't exist.\n",
4055 smb_fname_str_dbg(smb_fname) ));
4056 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4058 if (is_twrp) {
4059 return NT_STATUS_MEDIA_WRITE_PROTECTED;
4061 break;
4063 case FILE_CREATE:
4064 /* If file exists error. If file doesn't exist
4065 * create. */
4066 if (file_existed) {
4067 DEBUG(5,("open_file_ntcreate: FILE_CREATE "
4068 "requested for file %s and file "
4069 "already exists.\n",
4070 smb_fname_str_dbg(smb_fname)));
4071 if (S_ISDIR(smb_fname->st.st_ex_mode)) {
4072 return NT_STATUS_FILE_IS_A_DIRECTORY;
4074 return NT_STATUS_OBJECT_NAME_COLLISION;
4076 if (is_twrp) {
4077 return NT_STATUS_MEDIA_WRITE_PROTECTED;
4079 break;
4081 case FILE_SUPERSEDE:
4082 case FILE_OVERWRITE_IF:
4083 if (is_twrp) {
4084 return NT_STATUS_MEDIA_WRITE_PROTECTED;
4086 break;
4087 case FILE_OPEN_IF:
4088 if (is_twrp) {
4089 if (!file_existed) {
4090 return NT_STATUS_MEDIA_WRITE_PROTECTED;
4092 create_disposition = FILE_OPEN;
4094 break;
4095 default:
4096 return NT_STATUS_INVALID_PARAMETER;
4099 flags = disposition_to_open_flags(create_disposition);
4101 /* We only care about matching attributes on file exists and
4102 * overwrite. */
4104 if (!posix_open && file_existed &&
4105 ((create_disposition == FILE_OVERWRITE) ||
4106 (create_disposition == FILE_OVERWRITE_IF))) {
4107 if (!open_match_attributes(conn, existing_dos_attributes,
4108 new_dos_attributes,
4109 unx_mode, &new_unx_mode)) {
4110 DEBUG(5,("open_file_ntcreate: attributes mismatch "
4111 "for file %s (%x %x) (0%o, 0%o)\n",
4112 smb_fname_str_dbg(smb_fname),
4113 existing_dos_attributes,
4114 new_dos_attributes,
4115 (unsigned int)smb_fname->st.st_ex_mode,
4116 (unsigned int)unx_mode ));
4117 return NT_STATUS_ACCESS_DENIED;
4121 status = smbd_calculate_access_mask_fsp(parent_dir_fname->fsp,
4122 smb_fname->fsp,
4123 false,
4124 access_mask,
4125 &access_mask);
4126 if (!NT_STATUS_IS_OK(status)) {
4127 DBG_DEBUG("smbd_calculate_access_mask_fsp "
4128 "on file %s returned %s\n",
4129 smb_fname_str_dbg(smb_fname),
4130 nt_errstr(status));
4131 return status;
4134 open_access_mask = access_mask;
4136 if (flags & O_TRUNC) {
4137 open_access_mask |= FILE_WRITE_DATA; /* This will cause oplock breaks. */
4140 if (file_existed) {
4142 * stat opens on existing files don't get oplocks.
4143 * They can get leases.
4145 * Note that we check for stat open on the *open_access_mask*,
4146 * i.e. the access mask we actually used to do the open,
4147 * not the one the client asked for (which is in
4148 * fsp->access_mask). This is due to the fact that
4149 * FILE_OVERWRITE and FILE_OVERWRITE_IF add in O_TRUNC,
4150 * which adds FILE_WRITE_DATA to open_access_mask.
4152 if (is_oplock_stat_open(open_access_mask) && lease == NULL) {
4153 oplock_request = NO_OPLOCK;
4157 DEBUG(10, ("open_file_ntcreate: fname=%s, after mapping "
4158 "access_mask=0x%x\n", smb_fname_str_dbg(smb_fname),
4159 access_mask));
4162 * Note that we ignore the append flag as append does not
4163 * mean the same thing under DOS and Unix.
4166 flags |= calculate_open_access_flags(access_mask,
4167 private_flags,
4168 smb_fname->twrp);
4171 * Currently we only look at FILE_WRITE_THROUGH for create options.
4174 #if defined(O_SYNC)
4175 if ((create_options & FILE_WRITE_THROUGH) && lp_strict_sync(SNUM(conn))) {
4176 flags |= O_SYNC;
4178 #endif /* O_SYNC */
4180 if (posix_open && (access_mask & FILE_APPEND_DATA)) {
4181 flags |= O_APPEND;
4184 if (!posix_open && !CAN_WRITE(conn)) {
4186 * We should really return a permission denied error if either
4187 * O_CREAT or O_TRUNC are set, but for compatibility with
4188 * older versions of Samba we just AND them out.
4190 flags &= ~(O_CREAT | O_TRUNC);
4194 * With kernel oplocks the open breaking an oplock
4195 * blocks until the oplock holder has given up the
4196 * oplock or closed the file. We prevent this by always
4197 * trying to open the file with O_NONBLOCK (see "man
4198 * fcntl" on Linux).
4200 * If a process that doesn't use the smbd open files
4201 * database or communication methods holds a kernel
4202 * oplock we must periodically poll for available open
4203 * using O_NONBLOCK.
4205 flags |= O_NONBLOCK;
4208 * Ensure we can't write on a read-only share or file.
4211 if (((flags & O_ACCMODE) != O_RDONLY) && file_existed &&
4212 (!CAN_WRITE(conn) ||
4213 (existing_dos_attributes & FILE_ATTRIBUTE_READONLY))) {
4214 DEBUG(5,("open_file_ntcreate: write access requested for "
4215 "file %s on read only %s\n",
4216 smb_fname_str_dbg(smb_fname),
4217 !CAN_WRITE(conn) ? "share" : "file" ));
4218 return NT_STATUS_ACCESS_DENIED;
4221 if (VALID_STAT(smb_fname->st)) {
4223 * Only try and create a file id before open
4224 * for an existing file. For a file being created
4225 * this won't do anything useful until the file
4226 * exists and has a valid stat struct.
4228 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
4230 fh_set_private_options(fsp->fh, private_flags);
4231 fsp->access_mask = open_access_mask; /* We change this to the
4232 * requested access_mask after
4233 * the open is done. */
4234 if (posix_open) {
4235 fsp->fsp_flags.posix_open = true;
4238 if ((create_options & FILE_DELETE_ON_CLOSE) && (flags & O_CREAT) &&
4239 !file_existed) {
4240 /* Delete on close semantics for new files. */
4241 status = can_set_delete_on_close(fsp,
4242 new_dos_attributes);
4243 if (!NT_STATUS_IS_OK(status)) {
4244 fd_close(fsp);
4245 return status;
4250 * Ensure we pay attention to default ACLs on directories if required.
4253 if ((flags & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
4254 (def_acl = directory_has_default_acl_fsp(parent_dir_fname->fsp))) {
4255 unx_mode = (0777 & lp_create_mask(SNUM(conn)));
4258 DEBUG(4,
4259 ("calling open_file with flags=0x%X mode=0%o, "
4260 "access_mask = 0x%x, open_access_mask = 0x%x\n",
4261 (unsigned int)flags,
4262 (unsigned int)unx_mode,
4263 (unsigned int)access_mask,
4264 (unsigned int)open_access_mask));
4267 struct vfs_open_how how = {
4268 .flags = flags,
4269 .mode = unx_mode,
4272 if (create_options & FILE_OPEN_FOR_BACKUP_INTENT) {
4273 how.resolve |= VFS_OPEN_HOW_WITH_BACKUP_INTENT;
4276 fsp_open = open_file(req,
4277 parent_dir_fname->fsp,
4278 smb_fname_atname,
4279 fsp,
4280 &how,
4281 access_mask,
4282 open_access_mask,
4283 private_flags,
4284 &new_file_created);
4286 if (NT_STATUS_EQUAL(fsp_open, NT_STATUS_NETWORK_BUSY)) {
4287 if (file_existed && S_ISFIFO(fsp->fsp_name->st.st_ex_mode)) {
4288 DEBUG(10, ("FIFO busy\n"));
4289 return NT_STATUS_NETWORK_BUSY;
4291 if (req == NULL) {
4292 DEBUG(10, ("Internal open busy\n"));
4293 return NT_STATUS_NETWORK_BUSY;
4296 * This handles the kernel oplock case:
4298 * the file has an active kernel oplock and the open() returned
4299 * EWOULDBLOCK/EAGAIN which maps to NETWORK_BUSY.
4301 * "Samba locking.tdb oplocks" are handled below after acquiring
4302 * the sharemode lock with get_share_mode_lock().
4304 setup_poll = true;
4307 if (NT_STATUS_EQUAL(fsp_open, NT_STATUS_RETRY)) {
4309 * EINTR from the open(2) syscall. Just setup a retry
4310 * in a bit. We can't use the sys_write() tight retry
4311 * loop here, as we might have to actually deal with
4312 * lease-break signals to avoid a deadlock.
4314 setup_poll = true;
4317 if (setup_poll) {
4319 * Retry once a second. If there's a share_mode_lock
4320 * around, also wait for it in case it was smbd
4321 * holding that kernel oplock that can quickly tell us
4322 * the oplock got removed.
4325 setup_poll_open(req,
4326 &fsp->file_id,
4327 tevent_timeval_set(OPLOCK_BREAK_TIMEOUT * 2,
4329 tevent_timeval_set(1, 0));
4331 return NT_STATUS_SHARING_VIOLATION;
4334 if (!NT_STATUS_IS_OK(fsp_open)) {
4335 bool wait_for_aio = NT_STATUS_EQUAL(
4336 fsp_open, NT_STATUS_MORE_PROCESSING_REQUIRED);
4337 if (wait_for_aio) {
4338 schedule_async_open(req);
4340 return fsp_open;
4343 if (new_file_created) {
4345 * As we atomically create using O_CREAT|O_EXCL,
4346 * then if new_file_created is true, then
4347 * file_existed *MUST* have been false (even
4348 * if the file was previously detected as being
4349 * there).
4351 file_existed = false;
4354 if (file_existed && !check_same_dev_ino(&saved_stat, &smb_fname->st)) {
4356 * The file did exist, but some other (local or NFS)
4357 * process either renamed/unlinked and re-created the
4358 * file with different dev/ino after we walked the path,
4359 * but before we did the open. We could retry the
4360 * open but it's a rare enough case it's easier to
4361 * just fail the open to prevent creating any problems
4362 * in the open file db having the wrong dev/ino key.
4364 fd_close(fsp);
4365 DBG_WARNING("file %s - dev/ino mismatch. "
4366 "Old (dev=%ju, ino=%ju). "
4367 "New (dev=%ju, ino=%ju). Failing open "
4368 "with NT_STATUS_ACCESS_DENIED.\n",
4369 smb_fname_str_dbg(smb_fname),
4370 (uintmax_t)saved_stat.st_ex_dev,
4371 (uintmax_t)saved_stat.st_ex_ino,
4372 (uintmax_t)smb_fname->st.st_ex_dev,
4373 (uintmax_t)smb_fname->st.st_ex_ino);
4374 return NT_STATUS_ACCESS_DENIED;
4377 old_write_time = smb_fname->st.st_ex_mtime;
4380 * Deal with the race condition where two smbd's detect the
4381 * file doesn't exist and do the create at the same time. One
4382 * of them will win and set a share mode, the other (ie. this
4383 * one) should check if the requested share mode for this
4384 * create is allowed.
4388 * Now the file exists and fsp is successfully opened,
4389 * fsp->dev and fsp->inode are valid and should replace the
4390 * dev=0,inode=0 from a non existent file. Spotted by
4391 * Nadav Danieli <nadavd@exanet.com>. JRA.
4394 if (new_file_created) {
4395 info = FILE_WAS_CREATED;
4396 } else {
4397 if (flags & O_TRUNC) {
4398 info = FILE_WAS_OVERWRITTEN;
4399 } else {
4400 info = FILE_WAS_OPENED;
4405 * If we created a new file, overwrite an existing one
4406 * or going to delete it later, we should keep
4407 * the share_mode_lock (g_lock) until we call
4408 * share_mode_entry_prepare_unlock()
4410 if (info != FILE_WAS_OPENED) {
4411 keep_locked = true;
4412 } else if (create_options & FILE_DELETE_ON_CLOSE) {
4413 keep_locked = true;
4416 lck_state = (struct open_ntcreate_lock_state) {
4417 .fsp = fsp,
4418 .object_type = "file",
4419 .req = req,
4420 .create_disposition = create_disposition,
4421 .access_mask = access_mask,
4422 .open_access_mask = open_access_mask,
4423 .share_access = share_access,
4424 .oplock_request = oplock_request,
4425 .lease = lease,
4426 .first_open_attempt = first_open_attempt,
4427 .keep_locked = keep_locked,
4430 status = share_mode_entry_prepare_lock_add(&lck_state.prepare_state,
4431 fsp->file_id,
4432 conn->connectpath,
4433 smb_fname,
4434 &old_write_time,
4435 open_ntcreate_lock_add_entry,
4436 &lck_state);
4437 if (!NT_STATUS_IS_OK(status)) {
4438 DBG_ERR("share_mode_entry_prepare_lock_add() failed for %s - %s\n",
4439 smb_fname_str_dbg(smb_fname), nt_errstr(status));
4440 fd_close(fsp);
4441 return status;
4444 status = lck_state.status;
4445 if (!NT_STATUS_IS_OK(status)) {
4446 fd_close(fsp);
4447 return status;
4451 * From here we need to use 'goto unlock;' instead of return !!!
4454 if (fsp->oplock_type != NO_OPLOCK && fsp->oplock_type != LEASE_OPLOCK) {
4456 * Now ask for kernel oplocks
4457 * and cleanup on failure.
4459 status = set_file_oplock(fsp);
4460 if (!NT_STATUS_IS_OK(status)) {
4462 * Could not get the kernel oplock
4464 lck_state.cleanup_fn =
4465 open_ntcreate_lock_cleanup_oplock;
4466 fsp->oplock_type = NO_OPLOCK;
4470 /* Should we atomically (to the client at least) truncate ? */
4471 if ((!new_file_created) && (flags & O_TRUNC) &&
4472 (S_ISREG(fsp->fsp_name->st.st_ex_mode))) {
4473 int ret;
4475 ret = SMB_VFS_FTRUNCATE(fsp, 0);
4476 if (ret != 0) {
4477 status = map_nt_error_from_unix(errno);
4478 lck_state.cleanup_fn =
4479 open_ntcreate_lock_cleanup_entry;
4480 goto unlock;
4482 truncated = true;
4486 * We have the share entry *locked*.....
4489 /* Delete streams if create_disposition requires it */
4490 if (!new_file_created &&
4491 clear_ads(create_disposition) &&
4492 !fsp_is_alternate_stream(fsp)) {
4493 status = delete_all_streams(conn, smb_fname);
4494 if (!NT_STATUS_IS_OK(status)) {
4495 lck_state.cleanup_fn =
4496 open_ntcreate_lock_cleanup_entry;
4497 goto unlock;
4501 if (!fsp->fsp_flags.is_pathref &&
4502 fsp_get_io_fd(fsp) != -1 &&
4503 lp_kernel_share_modes(SNUM(conn)))
4505 int ret;
4507 * Beware: streams implementing VFS modules may
4508 * implement streams in a way that fsp will have the
4509 * basefile open in the fsp fd, so lacking a distinct
4510 * fd for the stream the file-system sharemode will
4511 * apply on the basefile which is wrong. The actual
4512 * check is deferred to the VFS module implementing
4513 * the file-system sharemode call.
4515 ret = SMB_VFS_FILESYSTEM_SHAREMODE(fsp,
4516 share_access,
4517 access_mask);
4518 if (ret == -1){
4519 status = NT_STATUS_SHARING_VIOLATION;
4520 lck_state.cleanup_fn =
4521 open_ntcreate_lock_cleanup_entry;
4522 goto unlock;
4525 fsp->fsp_flags.kernel_share_modes_taken = true;
4529 * At this point onwards, we can guarantee that the share entry
4530 * is locked, whether we created the file or not, and that the
4531 * deny mode is compatible with all current opens.
4535 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
4536 * but we don't have to store this - just ignore it on access check.
4538 if (conn_using_smb2(conn->sconn)) {
4540 * SMB2 doesn't return it (according to Microsoft tests).
4541 * Test Case: TestSuite_ScenarioNo009GrantedAccessTestS0
4542 * File created with access = 0x7 (Read, Write, Delete)
4543 * Query Info on file returns 0x87 (Read, Write, Delete, Read Attributes)
4545 fsp->access_mask = access_mask;
4546 } else {
4547 /* But SMB1 does. */
4548 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
4551 if (pinfo) {
4552 *pinfo = info;
4555 /* Handle strange delete on close create semantics. */
4556 if (create_options & FILE_DELETE_ON_CLOSE) {
4557 if (!new_file_created) {
4558 status = can_set_delete_on_close(fsp,
4559 existing_dos_attributes);
4561 if (!NT_STATUS_IS_OK(status)) {
4562 /* Remember to delete the mode we just added. */
4563 lck_state.cleanup_fn =
4564 open_ntcreate_lock_cleanup_entry;
4565 goto unlock;
4568 /* Note that here we set the *initial* delete on close flag,
4569 not the regular one. The magic gets handled in close. */
4570 fsp->fsp_flags.initial_delete_on_close = true;
4573 possibly_set_archive(conn,
4574 fsp,
4575 smb_fname,
4576 parent_dir_fname,
4577 info,
4578 new_dos_attributes,
4579 &smb_fname->st.st_ex_mode);
4581 /* Determine sparse flag. */
4582 if (posix_open) {
4583 /* POSIX opens are sparse by default. */
4584 fsp->fsp_flags.is_sparse = true;
4585 } else {
4586 fsp->fsp_flags.is_sparse =
4587 (existing_dos_attributes & FILE_ATTRIBUTE_SPARSE);
4591 * Take care of inherited ACLs on created files - if default ACL not
4592 * selected.
4595 if (!posix_open && new_file_created && !def_acl) {
4596 if (unx_mode != smb_fname->st.st_ex_mode) {
4597 int ret = SMB_VFS_FCHMOD(fsp, unx_mode);
4598 if (ret == -1) {
4599 DBG_INFO("failed to reset "
4600 "attributes of file %s to 0%o\n",
4601 smb_fname_str_dbg(smb_fname),
4602 (unsigned int)unx_mode);
4606 } else if (new_unx_mode) {
4608 * We only get here in the case of:
4610 * a). Not a POSIX open.
4611 * b). File already existed.
4612 * c). File was overwritten.
4613 * d). Requested DOS attributes didn't match
4614 * the DOS attributes on the existing file.
4616 * In that case new_unx_mode has been set
4617 * equal to the calculated mode (including
4618 * possible inheritance of the mode from the
4619 * containing directory).
4621 * Note this mode was calculated with the
4622 * DOS attribute FILE_ATTRIBUTE_ARCHIVE added,
4623 * so the mode change here is suitable for
4624 * an overwritten file.
4627 if (new_unx_mode != smb_fname->st.st_ex_mode) {
4628 int ret = SMB_VFS_FCHMOD(fsp, new_unx_mode);
4629 if (ret == -1) {
4630 DBG_INFO("failed to reset "
4631 "attributes of file %s to 0%o\n",
4632 smb_fname_str_dbg(smb_fname),
4633 (unsigned int)new_unx_mode);
4639 * Deal with other opens having a modified write time.
4641 if (fsp_getinfo_ask_sharemode(fsp) &&
4642 !is_omit_timespec(&lck_state.write_time))
4644 update_stat_ex_mtime(&fsp->fsp_name->st, lck_state.write_time);
4647 status = NT_STATUS_OK;
4649 unlock:
4650 ulstatus = share_mode_entry_prepare_unlock(&lck_state.prepare_state,
4651 lck_state.cleanup_fn,
4652 &lck_state);
4653 if (!NT_STATUS_IS_OK(ulstatus)) {
4654 DBG_ERR("share_mode_entry_prepare_unlock() failed for %s - %s\n",
4655 smb_fname_str_dbg(smb_fname), nt_errstr(ulstatus));
4656 smb_panic("share_mode_entry_prepare_unlock() failed!");
4659 if (info == FILE_WAS_CREATED) {
4660 notify_fname(conn,
4661 NOTIFY_ACTION_ADDED |
4662 NOTIFY_ACTION_DIRLEASE_BREAK,
4663 FILE_NOTIFY_CHANGE_FILE_NAME,
4664 smb_fname,
4665 fsp_get_smb2_lease(fsp));
4667 if (truncated) {
4668 notify_fname(fsp->conn,
4669 NOTIFY_ACTION_MODIFIED |
4670 NOTIFY_ACTION_DIRLEASE_BREAK,
4671 FILE_NOTIFY_CHANGE_SIZE |
4672 FILE_NOTIFY_CHANGE_ATTRIBUTES,
4673 fsp->fsp_name,
4674 fsp_get_smb2_lease(fsp));
4676 if (!NT_STATUS_IS_OK(status)) {
4677 fd_close(fsp);
4678 return status;
4681 return NT_STATUS_OK;
4684 static NTSTATUS apply_new_nt_acl(struct files_struct *dirfsp,
4685 struct files_struct *fsp,
4686 struct security_descriptor *sd)
4688 NTSTATUS status;
4690 if (sd != NULL) {
4692 * According to the MS documentation, the only time the security
4693 * descriptor is applied to the opened file is iff we *created* the
4694 * file; an existing file stays the same.
4696 * Also, it seems (from observation) that you can open the file with
4697 * any access mask but you can still write the sd. We need to override
4698 * the granted access before we call set_sd
4699 * Patch for bug #2242 from Tom Lackemann <cessnatomny@yahoo.com>.
4702 uint32_t sec_info_sent;
4703 uint32_t saved_access_mask = fsp->access_mask;
4705 sec_info_sent = get_sec_info(sd);
4707 fsp->access_mask = FILE_GENERIC_ALL;
4709 if (sec_info_sent & (SECINFO_OWNER|
4710 SECINFO_GROUP|
4711 SECINFO_DACL|
4712 SECINFO_SACL)) {
4713 status = set_sd(fsp, sd, sec_info_sent);
4714 } else {
4715 status = NT_STATUS_OK;
4718 fsp->access_mask = saved_access_mask;
4720 if (!NT_STATUS_IS_OK(status)) {
4721 DBG_WARNING("set_sd() failed for '%s': %s\n",
4722 fsp_str_dbg(fsp), nt_errstr(status));
4723 return status;
4726 return NT_STATUS_OK;
4729 if (!lp_inherit_acls(SNUM(fsp->conn))) {
4730 return NT_STATUS_OK;
4733 /* Inherit from parent. Errors here are not fatal. */
4734 status = inherit_new_acl(dirfsp, fsp);
4735 if (!NT_STATUS_IS_OK(status)) {
4736 DBG_WARNING("inherit_new_acl failed for %s with %s\n",
4737 fsp_str_dbg(fsp), nt_errstr(status));
4740 return NT_STATUS_OK;
4743 bool smbd_is_tmpname(const char *n, int *_unlink_flags)
4745 const char *p = n;
4746 int unlink_flags = INT_MAX;
4747 struct server_id id;
4748 bool exists;
4750 if (_unlink_flags != NULL) {
4751 *_unlink_flags = INT_MAX;
4754 if (!IS_SMBD_TMPNAME_PREFIX(n)) {
4755 return false;
4757 p += sizeof(SMBD_TMPNAME_PREFIX) - 1;
4758 switch (p[0]) {
4759 case 'D':
4760 unlink_flags = AT_REMOVEDIR;
4761 break;
4762 default:
4763 return false;
4765 p += 1;
4766 if (p[0] != ':') {
4767 return false;
4769 p += 1;
4771 id = server_id_from_string_ex(get_my_vnn(), '%', p);
4772 if (id.pid == UINT64_MAX) {
4773 return false;
4775 if (id.unique_id == 0) {
4776 return false;
4778 if (id.unique_id == SERVERID_UNIQUE_ID_NOT_TO_VERIFY) {
4779 return false;
4782 if (_unlink_flags == NULL) {
4783 return true;
4786 exists = serverid_exists(&id);
4787 if (!exists) {
4789 * let the caller know it's stale
4790 * and should be removed
4792 *_unlink_flags = unlink_flags;
4795 return true;
4798 static NTSTATUS mkdir_internal(connection_struct *conn,
4799 struct smb_filename *parent_dir_fname, /* parent. */
4800 struct smb_filename *smb_fname_atname, /* atname relative to parent. */
4801 struct smb_filename *smb_dname, /* full pathname from root of share. */
4802 struct security_descriptor *sd,
4803 uint32_t file_attributes,
4804 struct files_struct *fsp)
4806 TALLOC_CTX *frame = talloc_stackframe();
4807 const struct loadparm_substitution *lp_sub =
4808 loadparm_s3_global_substitution();
4809 mode_t mode;
4810 NTSTATUS status;
4811 bool posix_open = false;
4812 bool need_re_stat = false;
4813 uint32_t access_mask = SEC_DIR_ADD_SUBDIR;
4814 struct smb_filename *first_atname = NULL;
4815 struct smb_filename *tmp_atname = NULL;
4816 char *orig_dname = NULL;
4817 char *tmp_dname = NULL;
4818 int vfs_use_tmp = lp_vfs_mkdir_use_tmp_name(SNUM(conn));
4819 bool need_tmpname = false;
4820 struct server_id id = messaging_server_id(conn->sconn->msg_ctx);
4821 struct server_id_buf idbuf;
4822 char *idstr = server_id_str_buf_unique_ex(id, '%', &idbuf);
4823 struct vfs_open_how how = { .flags = O_RDONLY|O_DIRECTORY, };
4824 struct vfs_rename_how rhow = { .flags = VFS_RENAME_HOW_NO_REPLACE, };
4825 int ret;
4827 if (!CAN_WRITE(conn) || (access_mask & ~(conn->share_access))) {
4828 DBG_INFO("failing share access %s\n",
4829 lp_servicename(talloc_tos(), lp_sub, SNUM(conn)));
4830 TALLOC_FREE(frame);
4831 return NT_STATUS_ACCESS_DENIED;
4834 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
4835 posix_open = true;
4836 mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
4837 } else {
4838 mode = unix_mode(conn,
4839 FILE_ATTRIBUTE_DIRECTORY,
4840 smb_dname,
4841 parent_dir_fname->fsp);
4844 status = check_parent_access_fsp(parent_dir_fname->fsp, access_mask);
4845 if(!NT_STATUS_IS_OK(status)) {
4846 DBG_INFO("check_parent_access_fsp "
4847 "on directory %s for path %s returned %s\n",
4848 smb_fname_str_dbg(parent_dir_fname),
4849 smb_dname->base_name,
4850 nt_errstr(status));
4851 TALLOC_FREE(frame);
4852 return status;
4855 if (lp_inherit_acls(SNUM(conn))) {
4856 if (directory_has_default_acl_fsp(parent_dir_fname->fsp)) {
4857 mode = (0777 & lp_directory_mask(SNUM(conn)));
4859 need_tmpname = true;
4860 } else if (lp_store_dos_attributes(SNUM(conn))) {
4861 need_tmpname = true;
4862 } else if (lp_inherit_permissions(SNUM(conn))) {
4863 need_tmpname = true;
4864 } else if (lp_inherit_owner(SNUM(conn)) != INHERIT_OWNER_NO) {
4865 need_tmpname = true;
4866 } else if (lp_nt_acl_support(SNUM(conn)) && sd != NULL) {
4867 need_tmpname = true;
4870 if (vfs_use_tmp != Auto) {
4871 need_tmpname = vfs_use_tmp;
4874 if (!need_tmpname) {
4875 first_atname = smb_fname_atname;
4876 goto mkdir_first;
4880 * In order to avoid races where other clients could
4881 * see the directory before it is setup completely
4882 * we use a temporary name and rename it
4883 * when everything is ready.
4886 orig_dname = smb_dname->base_name;
4888 tmp_atname = cp_smb_filename(frame,
4889 smb_fname_atname);
4890 if (tmp_atname == NULL) {
4891 TALLOC_FREE(frame);
4892 return NT_STATUS_NO_MEMORY;
4894 TALLOC_FREE(tmp_atname->base_name);
4895 tmp_atname->base_name = talloc_asprintf(tmp_atname,
4896 "%s%s:%s",
4897 SMBD_TMPDIR_PREFIX,
4898 idstr,
4899 smb_fname_atname->base_name);
4900 if (tmp_atname == NULL) {
4901 TALLOC_FREE(frame);
4902 return NT_STATUS_NO_MEMORY;
4904 SMB_ASSERT(smbd_is_tmpname(tmp_atname->base_name, NULL));
4905 if (!ISDOT(parent_dir_fname->base_name)) {
4906 tmp_dname = talloc_asprintf(frame,
4907 "%s/%s",
4908 parent_dir_fname->base_name,
4909 tmp_atname->base_name);
4910 if (tmp_dname == NULL) {
4911 TALLOC_FREE(frame);
4912 return NT_STATUS_NO_MEMORY;
4914 } else {
4915 tmp_dname = talloc_strdup(frame, tmp_atname->base_name);
4916 if (tmp_dname == NULL) {
4917 TALLOC_FREE(frame);
4918 return NT_STATUS_NO_MEMORY;
4922 smb_dname->base_name = tmp_dname;
4924 DBG_DEBUG("temporary replace '%s' by '%s'\n",
4925 orig_dname, tmp_dname);
4927 first_atname = tmp_atname;
4929 mkdir_first:
4930 ret = SMB_VFS_MKDIRAT(conn,
4931 parent_dir_fname->fsp,
4932 first_atname,
4933 mode);
4934 if (ret != 0) {
4935 status = map_nt_error_from_unix(errno);
4936 DBG_NOTICE("MKDIRAT failed for '%s': %s\n",
4937 smb_fname_str_dbg(smb_dname), nt_errstr(status));
4938 goto restore_orig;
4942 * Make this a pathref fsp for now. open_directory() will reopen as a
4943 * full fsp.
4945 fsp->fsp_flags.is_pathref = true;
4947 status = fd_openat(parent_dir_fname->fsp, first_atname, fsp, &how);
4948 if (!NT_STATUS_IS_OK(status)) {
4949 DBG_ERR("fd_openat() failed for '%s': %s\n",
4950 smb_fname_str_dbg(smb_dname), nt_errstr(status));
4951 goto restore_orig;
4954 /* Ensure we're checking for a symlink here.... */
4955 /* We don't want to get caught by a symlink racer. */
4957 status = vfs_stat_fsp(fsp);
4958 if (!NT_STATUS_IS_OK(status)) {
4959 DBG_ERR("Could not stat directory '%s' just created: %s\n",
4960 smb_fname_str_dbg(smb_dname), nt_errstr(status));
4961 goto restore_orig;
4964 if (!S_ISDIR(smb_dname->st.st_ex_mode)) {
4965 DBG_ERR("Directory '%s' just created is not a directory !\n",
4966 smb_fname_str_dbg(smb_dname));
4967 status = NT_STATUS_NOT_A_DIRECTORY;
4968 goto restore_orig;
4971 if (lp_store_dos_attributes(SNUM(conn))) {
4972 file_set_dosmode(conn,
4973 smb_dname,
4974 file_attributes | FILE_ATTRIBUTE_DIRECTORY,
4975 parent_dir_fname,
4976 true);
4979 if (lp_inherit_permissions(SNUM(conn))) {
4980 inherit_access_posix_acl(conn, parent_dir_fname->fsp,
4981 smb_dname, mode);
4982 need_re_stat = true;
4985 if (!posix_open) {
4987 * Check if high bits should have been set,
4988 * then (if bits are missing): add them.
4989 * Consider bits automagically set by UNIX, i.e. SGID bit from parent
4990 * dir.
4992 if ((mode & ~(S_IRWXU|S_IRWXG|S_IRWXO)) &&
4993 (mode & ~smb_dname->st.st_ex_mode)) {
4994 SMB_VFS_FCHMOD(fsp,
4995 (smb_dname->st.st_ex_mode |
4996 (mode & ~smb_dname->st.st_ex_mode)));
4997 need_re_stat = true;
5001 /* Change the owner if required. */
5002 if (lp_inherit_owner(SNUM(conn)) != INHERIT_OWNER_NO) {
5003 change_dir_owner_to_parent_fsp(parent_dir_fname->fsp,
5004 fsp);
5005 need_re_stat = true;
5008 if (need_re_stat) {
5009 status = vfs_stat_fsp(fsp);
5010 if (!NT_STATUS_IS_OK(status)) {
5011 DBG_ERR("Could not stat directory '%s' just created: %s\n",
5012 smb_fname_str_dbg(smb_dname), nt_errstr(status));
5013 goto restore_orig;
5017 if (lp_nt_acl_support(SNUM(conn))) {
5018 status = apply_new_nt_acl(parent_dir_fname->fsp,
5019 fsp,
5020 sd);
5021 if (!NT_STATUS_IS_OK(status)) {
5022 DBG_WARNING("apply_new_nt_acl() failed for %s with %s\n",
5023 fsp_str_dbg(fsp),
5024 nt_errstr(status));
5025 goto do_unlink;
5029 if (!need_tmpname) {
5030 goto done;
5034 * A rename needs a valid stat for the source,
5035 * see vfs_fruit.c ...
5037 tmp_atname->st = smb_dname->st;
5040 * We first try VFS_RENAME_HOW_NO_REPLACE,
5041 * if it's implemented in the kernel,
5042 * we'll always get EEXIST if the target
5043 * exist, as it's handled at the linux vfs
5044 * layer. But if it doesn't exist we
5045 * can still get EINVAL if the actual
5046 * filesystem doesn't support RENAME_NOREPLACE.
5048 * If the kernel doesn't support rename2()
5049 * we get EINVAL instead of ENOSYS (this
5050 * is mapped in the libreplace replacement
5051 * (as well as the glibc replacement).
5053 ret = SMB_VFS_RENAMEAT(conn,
5054 parent_dir_fname->fsp,
5055 tmp_atname,
5056 parent_dir_fname->fsp,
5057 smb_fname_atname,
5058 &rhow);
5059 if (ret == -1 && errno == EINVAL) {
5061 * This is the strategie we use without having
5062 * renameat2(RENAME_NOREPLACE):
5064 * renameat() is able to replace a directory if the source is
5065 * also a directory.
5067 * So in order to avoid races as much as possible we do a
5068 * mkdirat() with mode 0 in order to catch EEXIST almost
5069 * atomically, when this code runs by two processes at the same
5070 * time.
5072 * Then a renameat() makes the temporary directory available for
5073 * clients.
5075 * This a much smaller window where the other clients may see
5076 * the incomplete directory, which has a mode of 0.
5079 rhow.flags &= ~VFS_RENAME_HOW_NO_REPLACE;
5081 DBG_DEBUG("MKDIRAT/RENAMEAT '%s' -> '%s'\n",
5082 tmp_dname, orig_dname);
5084 ret = SMB_VFS_MKDIRAT(conn,
5085 parent_dir_fname->fsp,
5086 smb_fname_atname,
5088 if (ret != 0) {
5089 status = map_nt_error_from_unix(errno);
5090 DBG_NOTICE("MKDIRAT failed for '%s': %s\n",
5091 orig_dname, nt_errstr(status));
5092 goto do_unlink;
5095 ret = SMB_VFS_RENAMEAT(conn,
5096 parent_dir_fname->fsp,
5097 tmp_atname,
5098 parent_dir_fname->fsp,
5099 smb_fname_atname,
5100 &rhow);
5103 if (ret != 0) {
5104 status = map_nt_error_from_unix(errno);
5105 DBG_NOTICE("RENAMEAT failed for '%s' -> '%s': %s\n",
5106 tmp_dname, orig_dname, nt_errstr(status));
5107 goto do_unlink;
5109 smb_fname_atname->st = tmp_atname->st;
5110 smb_dname->base_name = orig_dname;
5112 done:
5113 DBG_DEBUG("Created directory '%s'\n",
5114 smb_fname_str_dbg(smb_dname));
5116 TALLOC_FREE(frame);
5117 return NT_STATUS_OK;
5119 do_unlink:
5120 DBG_NOTICE("%s: rollback and unlink '%s'\n",
5121 nt_errstr(status),
5122 tmp_dname);
5123 ret = SMB_VFS_UNLINKAT(conn,
5124 parent_dir_fname->fsp,
5125 tmp_atname,
5126 AT_REMOVEDIR);
5127 if (ret == 0) {
5128 DBG_NOTICE("SMB_VFS_UNLINKAT(%s): OK\n",
5129 tmp_dname);
5130 } else {
5131 NTSTATUS status2 = map_nt_error_from_unix(errno);
5132 DBG_WARNING("SMB_VFS_UNLINKAT(%s) ignoring %s\n",
5133 tmp_dname, nt_errstr(status2));
5136 restore_orig:
5137 if (!need_tmpname) {
5138 TALLOC_FREE(frame);
5139 return status;
5141 DBG_NOTICE("%s: restoring '%s' -> '%s'\n",
5142 nt_errstr(status),
5143 tmp_dname,
5144 orig_dname);
5145 SET_STAT_INVALID(smb_fname_atname->st);
5146 smb_dname->base_name = orig_dname;
5147 SET_STAT_INVALID(smb_dname->st);
5148 TALLOC_FREE(frame);
5149 return status;
5152 /****************************************************************************
5153 Open a directory from an NT SMB call.
5154 ****************************************************************************/
5156 static NTSTATUS open_directory(connection_struct *conn,
5157 struct smb_request *req,
5158 uint32_t access_mask,
5159 uint32_t share_access,
5160 uint32_t create_disposition,
5161 uint32_t create_options,
5162 uint32_t file_attributes,
5163 struct smb_filename *parent_dir_fname,
5164 struct smb_filename *smb_fname_atname,
5165 uint32_t oplock_request,
5166 const struct smb2_lease *lease,
5167 struct security_descriptor *sd,
5168 int *pinfo,
5169 struct files_struct *fsp)
5171 struct smb_filename *smb_dname = fsp->fsp_name;
5172 bool dir_existed = VALID_STAT(smb_dname->st);
5173 bool deferred = false;
5174 struct open_ntcreate_lock_state lck_state = {};
5175 bool keep_locked = false;
5176 NTSTATUS status;
5177 struct timespec mtimespec;
5178 int info = 0;
5179 uint32_t need_fd_access;
5180 NTSTATUS ulstatus;
5182 if (is_ntfs_stream_smb_fname(smb_dname)) {
5183 DEBUG(2, ("open_directory: %s is a stream name!\n",
5184 smb_fname_str_dbg(smb_dname)));
5185 return NT_STATUS_NOT_A_DIRECTORY;
5188 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS)) {
5189 /* Ensure we have a directory attribute. */
5190 file_attributes |= FILE_ATTRIBUTE_DIRECTORY;
5193 DBG_INFO("opening directory %s, access_mask = 0x%"PRIx32", "
5194 "share_access = 0x%"PRIx32" create_options = 0x%"PRIx32", "
5195 "create_disposition = 0x%"PRIx32", "
5196 "file_attributes = 0x%"PRIx32"\n",
5197 smb_fname_str_dbg(smb_dname),
5198 access_mask,
5199 share_access,
5200 create_options,
5201 create_disposition,
5202 file_attributes);
5204 if (req == NULL) {
5205 /* Ensure req == NULL means INTERNAL_OPEN_ONLY */
5206 SMB_ASSERT(oplock_request == INTERNAL_OPEN_ONLY);
5207 } else {
5208 /* And req != NULL means no INTERNAL_OPEN_ONLY */
5209 SMB_ASSERT((oplock_request & INTERNAL_OPEN_ONLY) == 0);
5212 if (req != NULL) {
5213 struct deferred_open_record *open_rec = NULL;
5215 deferred = get_deferred_open_message_state(req, NULL, &open_rec);
5216 if (deferred) {
5217 remove_deferred_open_message_smb(req->xconn, req->mid);
5221 status = smbd_calculate_access_mask_fsp(parent_dir_fname->fsp,
5222 smb_dname->fsp,
5223 false,
5224 access_mask,
5225 &access_mask);
5226 if (!NT_STATUS_IS_OK(status)) {
5227 DBG_DEBUG("smbd_calculate_access_mask_fsp "
5228 "on file %s returned %s\n",
5229 smb_fname_str_dbg(smb_dname),
5230 nt_errstr(status));
5231 return status;
5234 if ((access_mask & SEC_FLAG_SYSTEM_SECURITY) &&
5235 !security_token_has_privilege(get_current_nttok(conn),
5236 SEC_PRIV_SECURITY)) {
5237 DEBUG(10, ("open_directory: open on %s "
5238 "failed - SEC_FLAG_SYSTEM_SECURITY denied.\n",
5239 smb_fname_str_dbg(smb_dname)));
5240 return NT_STATUS_PRIVILEGE_NOT_HELD;
5243 switch( create_disposition ) {
5244 case FILE_OPEN:
5246 if (!dir_existed) {
5247 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5250 info = FILE_WAS_OPENED;
5251 break;
5253 case FILE_CREATE:
5255 /* If directory exists error. If directory doesn't
5256 * exist create. */
5258 if (dir_existed) {
5259 status = NT_STATUS_OBJECT_NAME_COLLISION;
5260 DEBUG(2, ("open_directory: unable to create "
5261 "%s. Error was %s\n",
5262 smb_fname_str_dbg(smb_dname),
5263 nt_errstr(status)));
5264 return status;
5267 if (smb_fname_atname->twrp != 0) {
5268 return NT_STATUS_MEDIA_WRITE_PROTECTED;
5271 status = mkdir_internal(conn,
5272 parent_dir_fname,
5273 smb_fname_atname,
5274 smb_dname,
5276 file_attributes,
5277 fsp);
5279 if (!NT_STATUS_IS_OK(status)) {
5280 DEBUG(2, ("open_directory: unable to create "
5281 "%s. Error was %s\n",
5282 smb_fname_str_dbg(smb_dname),
5283 nt_errstr(status)));
5284 return status;
5287 info = FILE_WAS_CREATED;
5288 break;
5290 case FILE_OPEN_IF:
5292 * If directory exists open. If directory doesn't
5293 * exist create.
5296 if (dir_existed) {
5297 status = NT_STATUS_OK;
5298 info = FILE_WAS_OPENED;
5299 } else {
5300 if (smb_fname_atname->twrp != 0) {
5301 return NT_STATUS_MEDIA_WRITE_PROTECTED;
5303 status = mkdir_internal(conn,
5304 parent_dir_fname,
5305 smb_fname_atname,
5306 smb_dname,
5308 file_attributes,
5309 fsp);
5311 if (NT_STATUS_IS_OK(status)) {
5312 info = FILE_WAS_CREATED;
5313 } else {
5314 int ret;
5315 /* Cope with create race. */
5316 if (!NT_STATUS_EQUAL(status,
5317 NT_STATUS_OBJECT_NAME_COLLISION)) {
5318 DEBUG(2, ("open_directory: unable to create "
5319 "%s. Error was %s\n",
5320 smb_fname_str_dbg(smb_dname),
5321 nt_errstr(status)));
5322 return status;
5326 * If mkdir_internal() returned
5327 * NT_STATUS_OBJECT_NAME_COLLISION
5328 * we still must lstat the path.
5330 ret = SMB_VFS_FSTATAT(
5331 conn,
5332 parent_dir_fname->fsp,
5333 smb_fname_atname,
5334 &smb_dname->st,
5335 AT_SYMLINK_NOFOLLOW);
5336 if (ret == -1) {
5337 DEBUG(2, ("Could not stat "
5338 "directory '%s' just "
5339 "opened: %s\n",
5340 smb_fname_str_dbg(
5341 smb_dname),
5342 strerror(errno)));
5343 return map_nt_error_from_unix(
5344 errno);
5347 info = FILE_WAS_OPENED;
5351 break;
5353 case FILE_SUPERSEDE:
5354 case FILE_OVERWRITE:
5355 case FILE_OVERWRITE_IF:
5356 default:
5357 DEBUG(5,("open_directory: invalid create_disposition "
5358 "0x%x for directory %s\n",
5359 (unsigned int)create_disposition,
5360 smb_fname_str_dbg(smb_dname)));
5361 return NT_STATUS_INVALID_PARAMETER;
5364 if(!S_ISDIR(smb_dname->st.st_ex_mode)) {
5365 DEBUG(5,("open_directory: %s is not a directory !\n",
5366 smb_fname_str_dbg(smb_dname)));
5367 return NT_STATUS_NOT_A_DIRECTORY;
5371 * Setup the files_struct for it.
5374 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_dname->st);
5375 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
5376 fsp->file_pid = req ? req->smbpid : 0;
5377 fsp->fsp_flags.can_lock = false;
5378 fsp->fsp_flags.can_read = false;
5379 fsp->fsp_flags.can_write = false;
5381 fh_set_private_options(fsp->fh, 0);
5383 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
5385 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
5386 fsp->print_file = NULL;
5387 fsp->fsp_flags.modified = false;
5388 fsp->oplock_type = NO_OPLOCK;
5389 fsp->sent_oplock_break = NO_BREAK_SENT;
5390 fsp->fsp_flags.is_directory = true;
5391 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
5392 fsp->fsp_flags.posix_open = true;
5395 /* Don't store old timestamps for directory
5396 handles in the internal database. We don't
5397 update them in there if new objects
5398 are created in the directory. Currently
5399 we only update timestamps on file writes.
5400 See bug #9870.
5402 mtimespec = make_omit_timespec();
5405 * Obviously for FILE_LIST_DIRECTORY we need to reopen to get an fd
5406 * usable for reading a directory. SMB2_FLUSH may be called on
5407 * directories opened with FILE_ADD_FILE and FILE_ADD_SUBDIRECTORY so
5408 * for those we need to reopen as well.
5410 need_fd_access =
5411 FILE_LIST_DIRECTORY |
5412 FILE_ADD_FILE |
5413 FILE_ADD_SUBDIRECTORY;
5415 if (access_mask & need_fd_access) {
5416 struct vfs_open_how how = {
5417 .flags = O_RDONLY | O_DIRECTORY,
5419 bool file_created;
5421 status = reopen_from_fsp(parent_dir_fname->fsp,
5422 smb_fname_atname,
5423 fsp,
5424 &how,
5425 &file_created);
5426 if (!NT_STATUS_IS_OK(status)) {
5427 DBG_INFO("Could not open fd for [%s]: %s\n",
5428 smb_fname_str_dbg(smb_dname),
5429 nt_errstr(status));
5430 return status;
5434 status = vfs_stat_fsp(fsp);
5435 if (!NT_STATUS_IS_OK(status)) {
5436 fd_close(fsp);
5437 return status;
5440 if(!S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
5441 DEBUG(5,("open_directory: %s is not a directory !\n",
5442 smb_fname_str_dbg(smb_dname)));
5443 fd_close(fsp);
5444 return NT_STATUS_NOT_A_DIRECTORY;
5447 /* Ensure there was no race condition. We need to check
5448 * dev/inode but not permissions, as these can change
5449 * legitimately */
5450 if (!check_same_dev_ino(&smb_dname->st, &fsp->fsp_name->st)) {
5451 DEBUG(5,("open_directory: stat struct differs for "
5452 "directory %s.\n",
5453 smb_fname_str_dbg(smb_dname)));
5454 fd_close(fsp);
5455 return NT_STATUS_ACCESS_DENIED;
5458 if (info == FILE_WAS_OPENED) {
5459 status = smbd_check_access_rights_fsp(parent_dir_fname->fsp,
5460 fsp,
5461 false,
5462 access_mask);
5463 if (!NT_STATUS_IS_OK(status)) {
5464 DBG_DEBUG("smbd_check_access_rights_fsp on "
5465 "file %s failed with %s\n",
5466 fsp_str_dbg(fsp),
5467 nt_errstr(status));
5468 fd_close(fsp);
5469 return status;
5474 * If we created a new directory or going to delete it later,
5475 * we should keep * the share_mode_lock (g_lock) until we call
5476 * share_mode_entry_prepare_unlock()
5478 if (info != FILE_WAS_OPENED) {
5479 keep_locked = true;
5480 } else if (create_options & FILE_DELETE_ON_CLOSE) {
5481 keep_locked = true;
5484 lck_state = (struct open_ntcreate_lock_state) {
5485 .fsp = fsp,
5486 .object_type = "directory",
5487 .req = req,
5488 .create_disposition = create_disposition,
5489 .access_mask = access_mask,
5490 .open_access_mask = access_mask,
5491 .share_access = share_access,
5492 .oplock_request = oplock_request,
5493 .lease = lease,
5494 .first_open_attempt = !deferred,
5495 .keep_locked = keep_locked,
5498 status = share_mode_entry_prepare_lock_add(&lck_state.prepare_state,
5499 fsp->file_id,
5500 conn->connectpath,
5501 smb_dname,
5502 &mtimespec,
5503 open_ntcreate_lock_add_entry,
5504 &lck_state);
5505 if (!NT_STATUS_IS_OK(status)) {
5506 DBG_ERR("share_mode_entry_prepare_lock_add() failed for %s - %s\n",
5507 smb_fname_str_dbg(smb_dname), nt_errstr(status));
5508 fd_close(fsp);
5509 return status;
5512 status = lck_state.status;
5513 if (!NT_STATUS_IS_OK(status)) {
5514 fd_close(fsp);
5515 return status;
5519 * From here we need to use 'goto unlock;' instead of return !!!
5522 /* For directories the delete on close bit at open time seems
5523 always to be honored on close... See test 19 in Samba4 BASE-DELETE. */
5524 if (create_options & FILE_DELETE_ON_CLOSE) {
5525 status = can_set_delete_on_close(fsp, 0);
5526 if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
5527 lck_state.cleanup_fn =
5528 open_ntcreate_lock_cleanup_entry;
5529 goto unlock;
5532 if (NT_STATUS_IS_OK(status)) {
5533 /* Note that here we set the *initial* delete on close flag,
5534 not the regular one. The magic gets handled in close. */
5535 fsp->fsp_flags.initial_delete_on_close = true;
5540 * Deal with other opens having a modified write time.
5542 if (!is_omit_timespec(&lck_state.write_time)) {
5543 update_stat_ex_mtime(&fsp->fsp_name->st, lck_state.write_time);
5546 if (pinfo) {
5547 *pinfo = info;
5550 status = NT_STATUS_OK;
5552 unlock:
5553 ulstatus = share_mode_entry_prepare_unlock(&lck_state.prepare_state,
5554 lck_state.cleanup_fn,
5555 &lck_state);
5556 if (!NT_STATUS_IS_OK(ulstatus)) {
5557 DBG_ERR("share_mode_entry_prepare_unlock() failed for %s - %s\n",
5558 smb_fname_str_dbg(smb_dname), nt_errstr(ulstatus));
5559 smb_panic("share_mode_entry_prepare_unlock() failed!");
5562 if (info == FILE_WAS_CREATED) {
5563 notify_fname(conn,
5564 NOTIFY_ACTION_ADDED |
5565 NOTIFY_ACTION_DIRLEASE_BREAK,
5566 FILE_NOTIFY_CHANGE_DIR_NAME,
5567 smb_dname,
5568 fsp_get_smb2_lease(fsp));
5571 if (!NT_STATUS_IS_OK(status)) {
5572 fd_close(fsp);
5573 return status;
5576 return NT_STATUS_OK;
5579 NTSTATUS create_directory(connection_struct *conn,
5580 struct smb_request *req,
5581 struct files_struct *dirfsp,
5582 struct smb_filename *smb_dname)
5584 NTSTATUS status;
5585 files_struct *fsp;
5587 status = SMB_VFS_CREATE_FILE(
5588 conn, /* conn */
5589 req, /* req */
5590 dirfsp, /* dirfsp */
5591 smb_dname, /* fname */
5592 FILE_READ_ATTRIBUTES, /* access_mask */
5593 FILE_SHARE_NONE, /* share_access */
5594 FILE_CREATE, /* create_disposition*/
5595 FILE_DIRECTORY_FILE, /* create_options */
5596 FILE_ATTRIBUTE_DIRECTORY, /* file_attributes */
5597 0, /* oplock_request */
5598 NULL, /* lease */
5599 0, /* allocation_size */
5600 0, /* private_flags */
5601 NULL, /* sd */
5602 NULL, /* ea_list */
5603 &fsp, /* result */
5604 NULL, /* pinfo */
5605 NULL, NULL); /* create context */
5607 if (NT_STATUS_IS_OK(status)) {
5608 close_file_free(req, &fsp, NORMAL_CLOSE);
5611 return status;
5614 /****************************************************************************
5615 Receive notification that one of our open files has been renamed by another
5616 smbd process.
5617 ****************************************************************************/
5619 void msg_file_was_renamed(struct messaging_context *msg_ctx,
5620 void *private_data,
5621 uint32_t msg_type,
5622 struct server_id src,
5623 DATA_BLOB *data)
5625 struct file_rename_message *msg = NULL;
5626 enum ndr_err_code ndr_err;
5627 files_struct *fsp;
5628 struct smb_filename *smb_fname = NULL;
5629 struct smbd_server_connection *sconn =
5630 talloc_get_type_abort(private_data,
5631 struct smbd_server_connection);
5633 msg = talloc(talloc_tos(), struct file_rename_message);
5634 if (msg == NULL) {
5635 DBG_WARNING("talloc failed\n");
5636 return;
5639 ndr_err = ndr_pull_struct_blob_all(
5640 data,
5641 msg,
5642 msg,
5643 (ndr_pull_flags_fn_t)ndr_pull_file_rename_message);
5644 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
5645 DBG_DEBUG("ndr_pull_file_rename_message failed: %s\n",
5646 ndr_errstr(ndr_err));
5647 goto out;
5649 if (DEBUGLEVEL >= 10) {
5650 struct server_id_buf buf;
5651 DBG_DEBUG("Got rename message from %s\n",
5652 server_id_str_buf(src, &buf));
5653 NDR_PRINT_DEBUG(file_rename_message, msg);
5656 /* stream_name must always be NULL if there is no stream. */
5657 if ((msg->stream_name != NULL) && (msg->stream_name[0] == '\0')) {
5658 msg->stream_name = NULL;
5661 smb_fname = synthetic_smb_fname(msg,
5662 msg->base_name,
5663 msg->stream_name,
5664 NULL,
5667 if (smb_fname == NULL) {
5668 DBG_DEBUG("synthetic_smb_fname failed\n");
5669 goto out;
5672 fsp = file_find_dif(sconn, msg->id, msg->share_file_id);
5673 if (fsp == NULL) {
5674 DBG_DEBUG("fsp not found\n");
5675 goto out;
5678 if (strcmp(fsp->conn->connectpath, msg->servicepath) == 0) {
5679 SMB_STRUCT_STAT fsp_orig_sbuf;
5680 NTSTATUS status;
5681 DBG_DEBUG("renaming file %s from %s -> %s\n",
5682 fsp_fnum_dbg(fsp),
5683 fsp_str_dbg(fsp),
5684 smb_fname_str_dbg(smb_fname));
5687 * The incoming smb_fname here has an
5688 * invalid stat struct from synthetic_smb_fname()
5689 * above.
5690 * Preserve the existing stat from the
5691 * open fsp after fsp_set_smb_fname()
5692 * overwrites with the invalid stat.
5694 * (We could just copy this into
5695 * smb_fname->st, but keep this code
5696 * identical to the fix in rename_open_files()
5697 * for clarity.
5699 * We will do an fstat before returning
5700 * any of this metadata to the client anyway.
5702 fsp_orig_sbuf = fsp->fsp_name->st;
5703 status = fsp_set_smb_fname(fsp, smb_fname);
5704 if (!NT_STATUS_IS_OK(status)) {
5705 DBG_DEBUG("fsp_set_smb_fname failed: %s\n",
5706 nt_errstr(status));
5708 fsp->fsp_name->st = fsp_orig_sbuf;
5709 } else {
5710 /* TODO. JRA. */
5712 * Now we have the complete path we can work out if
5713 * this is actually within this share and adjust
5714 * newname accordingly.
5716 DBG_DEBUG("share mismatch (sharepath %s not sharepath %s) "
5717 "%s from %s -> %s\n",
5718 fsp->conn->connectpath,
5719 msg->servicepath,
5720 fsp_fnum_dbg(fsp),
5721 fsp_str_dbg(fsp),
5722 smb_fname_str_dbg(smb_fname));
5724 out:
5725 TALLOC_FREE(msg);
5729 * If a main file is opened for delete, all streams need to be checked for
5730 * !FILE_SHARE_DELETE. Do this by opening with DELETE_ACCESS.
5731 * If that works, delete them all by setting the delete on close and close.
5734 static NTSTATUS open_streams_for_delete(connection_struct *conn,
5735 const struct smb_filename *smb_fname)
5737 struct stream_struct *stream_info = NULL;
5738 files_struct **streams = NULL;
5739 int j;
5740 unsigned int i, num_streams = 0;
5741 TALLOC_CTX *frame = talloc_stackframe();
5742 const struct smb_filename *pathref = NULL;
5743 NTSTATUS status;
5745 if (smb_fname->fsp == NULL) {
5746 struct smb_filename *tmp = NULL;
5747 status = synthetic_pathref(frame,
5748 conn->cwd_fsp,
5749 smb_fname->base_name,
5750 NULL,
5751 NULL,
5752 smb_fname->twrp,
5753 smb_fname->flags,
5754 &tmp);
5755 if (!NT_STATUS_IS_OK(status)) {
5756 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
5757 || NT_STATUS_EQUAL(status,
5758 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
5759 DBG_DEBUG("no streams around\n");
5760 TALLOC_FREE(frame);
5761 return NT_STATUS_OK;
5763 DBG_DEBUG("synthetic_pathref failed: %s\n",
5764 nt_errstr(status));
5765 goto fail;
5767 pathref = tmp;
5768 } else {
5769 pathref = smb_fname;
5771 status = vfs_fstreaminfo(pathref->fsp, talloc_tos(),
5772 &num_streams, &stream_info);
5774 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
5775 || NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
5776 DEBUG(10, ("no streams around\n"));
5777 TALLOC_FREE(frame);
5778 return NT_STATUS_OK;
5781 if (!NT_STATUS_IS_OK(status)) {
5782 DEBUG(10, ("vfs_fstreaminfo failed: %s\n",
5783 nt_errstr(status)));
5784 goto fail;
5787 DEBUG(10, ("open_streams_for_delete found %d streams\n",
5788 num_streams));
5790 if (num_streams == 0) {
5791 TALLOC_FREE(frame);
5792 return NT_STATUS_OK;
5795 streams = talloc_array(talloc_tos(), files_struct *, num_streams);
5796 if (streams == NULL) {
5797 DEBUG(0, ("talloc failed\n"));
5798 status = NT_STATUS_NO_MEMORY;
5799 goto fail;
5802 for (i=0; i<num_streams; i++) {
5803 struct smb_filename *smb_fname_cp;
5805 if (strequal(stream_info[i].name, "::$DATA")) {
5806 streams[i] = NULL;
5807 continue;
5810 smb_fname_cp = synthetic_smb_fname(talloc_tos(),
5811 smb_fname->base_name,
5812 stream_info[i].name,
5813 NULL,
5814 smb_fname->twrp,
5815 (smb_fname->flags &
5816 ~SMB_FILENAME_POSIX_PATH));
5817 if (smb_fname_cp == NULL) {
5818 status = NT_STATUS_NO_MEMORY;
5819 goto fail;
5822 status = openat_pathref_fsp(conn->cwd_fsp, smb_fname_cp);
5823 if (!NT_STATUS_IS_OK(status)) {
5824 DBG_DEBUG("Unable to open stream [%s]: %s\n",
5825 smb_fname_str_dbg(smb_fname_cp),
5826 nt_errstr(status));
5827 TALLOC_FREE(smb_fname_cp);
5828 break;
5831 status = SMB_VFS_CREATE_FILE(
5832 conn, /* conn */
5833 NULL, /* req */
5834 NULL, /* dirfsp */
5835 smb_fname_cp, /* fname */
5836 DELETE_ACCESS, /* access_mask */
5837 (FILE_SHARE_READ | /* share_access */
5838 FILE_SHARE_WRITE | FILE_SHARE_DELETE),
5839 FILE_OPEN, /* create_disposition*/
5840 0, /* create_options */
5841 FILE_ATTRIBUTE_NORMAL, /* file_attributes */
5842 0, /* oplock_request */
5843 NULL, /* lease */
5844 0, /* allocation_size */
5845 0, /* private_flags */
5846 NULL, /* sd */
5847 NULL, /* ea_list */
5848 &streams[i], /* result */
5849 NULL, /* pinfo */
5850 NULL, NULL); /* create context */
5852 if (!NT_STATUS_IS_OK(status)) {
5853 DEBUG(10, ("Could not open stream %s: %s\n",
5854 smb_fname_str_dbg(smb_fname_cp),
5855 nt_errstr(status)));
5857 TALLOC_FREE(smb_fname_cp);
5858 break;
5860 TALLOC_FREE(smb_fname_cp);
5864 * don't touch the variable "status" beyond this point :-)
5867 for (j = i-1 ; j >= 0; j--) {
5868 if (streams[j] == NULL) {
5869 continue;
5872 DEBUG(10, ("Closing stream # %d, %s\n", j,
5873 fsp_str_dbg(streams[j])));
5874 close_file_free(NULL, &streams[j], NORMAL_CLOSE);
5877 fail:
5878 TALLOC_FREE(frame);
5879 return status;
5882 /*********************************************************************
5883 Create a default ACL by inheriting from the parent. If no inheritance
5884 from the parent available, don't set anything. This will leave the actual
5885 permissions the new file or directory already got from the filesystem
5886 as the NT ACL when read.
5887 *********************************************************************/
5889 static NTSTATUS inherit_new_acl(files_struct *dirfsp, files_struct *fsp)
5891 TALLOC_CTX *frame = talloc_stackframe();
5892 struct security_descriptor *parent_desc = NULL;
5893 NTSTATUS status = NT_STATUS_OK;
5894 struct security_descriptor *psd = NULL;
5895 const struct dom_sid *owner_sid = NULL;
5896 const struct dom_sid *group_sid = NULL;
5897 uint32_t security_info_sent = (SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL);
5898 struct security_token *token = fsp->conn->session_info->security_token;
5899 bool inherit_owner =
5900 (lp_inherit_owner(SNUM(fsp->conn)) == INHERIT_OWNER_WINDOWS_AND_UNIX);
5901 bool inheritable_components = false;
5902 bool try_builtin_administrators = false;
5903 const struct dom_sid *BA_U_sid = NULL;
5904 const struct dom_sid *BA_G_sid = NULL;
5905 bool try_system = false;
5906 const struct dom_sid *SY_U_sid = NULL;
5907 const struct dom_sid *SY_G_sid = NULL;
5908 size_t size = 0;
5909 bool ok;
5911 status = SMB_VFS_FGET_NT_ACL(dirfsp,
5912 (SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL),
5913 frame,
5914 &parent_desc);
5915 if (!NT_STATUS_IS_OK(status)) {
5916 TALLOC_FREE(frame);
5917 return status;
5920 inheritable_components = sd_has_inheritable_components(parent_desc,
5921 fsp->fsp_flags.is_directory);
5923 if (!inheritable_components && !inherit_owner) {
5924 TALLOC_FREE(frame);
5925 /* Nothing to inherit and not setting owner. */
5926 return NT_STATUS_OK;
5929 /* Create an inherited descriptor from the parent. */
5931 if (DEBUGLEVEL >= 10) {
5932 DEBUG(10,("inherit_new_acl: parent acl for %s is:\n",
5933 fsp_str_dbg(fsp) ));
5934 NDR_PRINT_DEBUG(security_descriptor, parent_desc);
5937 /* Inherit from parent descriptor if "inherit owner" set. */
5938 if (inherit_owner) {
5939 owner_sid = parent_desc->owner_sid;
5940 group_sid = parent_desc->group_sid;
5943 if (owner_sid == NULL) {
5944 if (security_token_has_builtin_administrators(token)) {
5945 try_builtin_administrators = true;
5946 } else if (security_token_is_system(token)) {
5947 try_builtin_administrators = true;
5948 try_system = true;
5952 if (group_sid == NULL &&
5953 token->num_sids == PRIMARY_GROUP_SID_INDEX)
5955 if (security_token_is_system(token)) {
5956 try_builtin_administrators = true;
5957 try_system = true;
5961 if (try_builtin_administrators) {
5962 struct unixid ids = { .id = 0 };
5964 ok = sids_to_unixids(&global_sid_Builtin_Administrators, 1, &ids);
5965 if (ok) {
5966 switch (ids.type) {
5967 case ID_TYPE_BOTH:
5968 BA_U_sid = &global_sid_Builtin_Administrators;
5969 BA_G_sid = &global_sid_Builtin_Administrators;
5970 break;
5971 case ID_TYPE_UID:
5972 BA_U_sid = &global_sid_Builtin_Administrators;
5973 break;
5974 case ID_TYPE_GID:
5975 BA_G_sid = &global_sid_Builtin_Administrators;
5976 break;
5977 default:
5978 break;
5983 if (try_system) {
5984 struct unixid ids = { .id = 0 };
5986 ok = sids_to_unixids(&global_sid_System, 1, &ids);
5987 if (ok) {
5988 switch (ids.type) {
5989 case ID_TYPE_BOTH:
5990 SY_U_sid = &global_sid_System;
5991 SY_G_sid = &global_sid_System;
5992 break;
5993 case ID_TYPE_UID:
5994 SY_U_sid = &global_sid_System;
5995 break;
5996 case ID_TYPE_GID:
5997 SY_G_sid = &global_sid_System;
5998 break;
5999 default:
6000 break;
6005 if (owner_sid == NULL) {
6006 owner_sid = BA_U_sid;
6009 if (owner_sid == NULL) {
6010 owner_sid = SY_U_sid;
6013 if (group_sid == NULL) {
6014 group_sid = SY_G_sid;
6017 if (try_system && group_sid == NULL) {
6018 group_sid = BA_G_sid;
6021 if (owner_sid == NULL) {
6022 owner_sid = &token->sids[PRIMARY_USER_SID_INDEX];
6024 if (group_sid == NULL) {
6025 if (token->num_sids == PRIMARY_GROUP_SID_INDEX) {
6026 group_sid = &token->sids[PRIMARY_USER_SID_INDEX];
6027 } else {
6028 group_sid = &token->sids[PRIMARY_GROUP_SID_INDEX];
6032 status = se_create_child_secdesc(frame,
6033 &psd,
6034 &size,
6035 parent_desc,
6036 owner_sid,
6037 group_sid,
6038 fsp->fsp_flags.is_directory);
6039 if (!NT_STATUS_IS_OK(status)) {
6040 TALLOC_FREE(frame);
6041 return status;
6044 /* If inheritable_components == false,
6045 se_create_child_secdesc()
6046 creates a security descriptor with a NULL dacl
6047 entry, but with SEC_DESC_DACL_PRESENT. We need
6048 to remove that flag. */
6050 if (!inheritable_components) {
6051 security_info_sent &= ~SECINFO_DACL;
6052 psd->type &= ~SEC_DESC_DACL_PRESENT;
6055 if (DEBUGLEVEL >= 10) {
6056 DEBUG(10,("inherit_new_acl: child acl for %s is:\n",
6057 fsp_str_dbg(fsp) ));
6058 NDR_PRINT_DEBUG(security_descriptor, psd);
6061 if (inherit_owner) {
6062 /* We need to be root to force this. */
6063 become_root();
6065 status = SMB_VFS_FSET_NT_ACL(metadata_fsp(fsp),
6066 security_info_sent,
6067 psd);
6068 if (inherit_owner) {
6069 unbecome_root();
6071 TALLOC_FREE(frame);
6072 return status;
6076 * If we already have a lease, it must match the new file id. [MS-SMB2]
6077 * 3.3.5.9.8 speaks about INVALID_PARAMETER if an already used lease key is
6078 * used for a different file name.
6081 struct lease_match_state {
6082 /* Input parameters. */
6083 TALLOC_CTX *mem_ctx;
6084 const char *servicepath;
6085 const struct smb_filename *fname;
6086 bool file_existed;
6087 struct file_id id;
6088 /* Return parameters. */
6089 uint32_t num_file_ids;
6090 struct file_id *ids;
6091 NTSTATUS match_status;
6094 /*************************************************************
6095 File doesn't exist but this lease key+guid is already in use.
6097 This is only allowable in the dynamic share case where the
6098 service path must be different.
6100 There is a small race condition here in the multi-connection
6101 case where a client sends two create calls on different connections,
6102 where the file doesn't exist and one smbd creates the leases_db
6103 entry first, but this will get fixed by the multichannel cleanup
6104 when all identical client_guids get handled by a single smbd.
6105 **************************************************************/
6107 static void lease_match_parser_new_file(
6108 uint32_t num_files,
6109 const struct leases_db_file *files,
6110 struct lease_match_state *state)
6112 uint32_t i;
6114 for (i = 0; i < num_files; i++) {
6115 const struct leases_db_file *f = &files[i];
6116 if (strequal(state->servicepath, f->servicepath)) {
6117 state->match_status = NT_STATUS_INVALID_PARAMETER;
6118 return;
6122 /* Dynamic share case. Break leases on all other files. */
6123 state->match_status = leases_db_copy_file_ids(state->mem_ctx,
6124 num_files,
6125 files,
6126 &state->ids);
6127 if (!NT_STATUS_IS_OK(state->match_status)) {
6128 return;
6131 state->num_file_ids = num_files;
6132 state->match_status = NT_STATUS_OPLOCK_NOT_GRANTED;
6133 return;
6136 static void lease_match_parser(
6137 uint32_t num_files,
6138 const struct leases_db_file *files,
6139 void *private_data)
6141 struct lease_match_state *state =
6142 (struct lease_match_state *)private_data;
6143 uint32_t i;
6145 if (!state->file_existed) {
6147 * Deal with name mismatch or
6148 * possible dynamic share case separately
6149 * to make code clearer.
6151 lease_match_parser_new_file(num_files,
6152 files,
6153 state);
6154 return;
6157 /* File existed. */
6158 state->match_status = NT_STATUS_OK;
6160 for (i = 0; i < num_files; i++) {
6161 const struct leases_db_file *f = &files[i];
6163 /* Everything should be the same. */
6164 if (!file_id_equal(&state->id, &f->id)) {
6166 * The client asked for a lease on a
6167 * file that doesn't match the file_id
6168 * in the database.
6170 * Maybe this is a dynamic share, i.e.
6171 * a share where the servicepath is
6172 * different for different users (e.g.
6173 * the [HOMES] share.
6175 * If the servicepath is different, but the requested
6176 * file name + stream name is the same then this is
6177 * a dynamic share, the client is using the same share
6178 * name and doesn't know that the underlying servicepath
6179 * is different. It was expecting a lease on the
6180 * same file. Return NT_STATUS_OPLOCK_NOT_GRANTED
6181 * to break leases
6183 * Otherwise the client has messed up, or is
6184 * testing our error codes, so return
6185 * NT_STATUS_INVALID_PARAMETER.
6187 if (!strequal(f->servicepath, state->servicepath) &&
6188 strequal(f->base_name, state->fname->base_name) &&
6189 strequal(f->stream_name, state->fname->stream_name))
6192 * Name is the same but servicepath is
6193 * different, dynamic share. Break leases.
6195 state->match_status =
6196 NT_STATUS_OPLOCK_NOT_GRANTED;
6197 } else {
6198 state->match_status =
6199 NT_STATUS_INVALID_PARAMETER;
6201 break;
6203 if (!strequal(f->servicepath, state->servicepath)) {
6204 state->match_status = NT_STATUS_INVALID_PARAMETER;
6205 break;
6207 if (!strequal(f->base_name, state->fname->base_name)) {
6208 state->match_status = NT_STATUS_INVALID_PARAMETER;
6209 break;
6211 if (!strequal(f->stream_name, state->fname->stream_name)) {
6212 state->match_status = NT_STATUS_INVALID_PARAMETER;
6213 break;
6217 if (NT_STATUS_IS_OK(state->match_status)) {
6219 * Common case - just opening another handle on a
6220 * file on a non-dynamic share.
6222 return;
6225 if (NT_STATUS_EQUAL(state->match_status, NT_STATUS_INVALID_PARAMETER)) {
6226 /* Mismatched path. Error back to client. */
6227 return;
6231 * File id mismatch. Dynamic share case NT_STATUS_OPLOCK_NOT_GRANTED.
6232 * Don't allow leases.
6235 state->match_status = leases_db_copy_file_ids(state->mem_ctx,
6236 num_files,
6237 files,
6238 &state->ids);
6239 if (!NT_STATUS_IS_OK(state->match_status)) {
6240 return;
6243 state->num_file_ids = num_files;
6244 state->match_status = NT_STATUS_OPLOCK_NOT_GRANTED;
6245 return;
6248 struct lease_match_break_state {
6249 struct messaging_context *msg_ctx;
6250 const struct smb2_lease_key *lease_key;
6251 struct file_id id;
6253 bool found_lease;
6254 uint16_t version;
6255 uint16_t epoch;
6258 static bool lease_match_break_fn(
6259 struct share_mode_entry *e,
6260 void *private_data)
6262 struct lease_match_break_state *state = private_data;
6263 bool stale, equal;
6264 uint32_t e_lease_type = SMB2_LEASE_NONE;
6265 NTSTATUS status;
6267 stale = share_entry_stale_pid(e);
6268 if (stale) {
6269 return false;
6272 equal = smb2_lease_key_equal(&e->lease_key, state->lease_key);
6273 if (!equal) {
6274 return false;
6277 status = leases_db_get(
6278 &e->client_guid,
6279 &e->lease_key,
6280 &state->id,
6281 &e_lease_type, /* current_state */
6282 NULL, /* breaking */
6283 NULL, /* breaking_to_requested */
6284 NULL, /* breaking_to_required */
6285 &state->version, /* lease_version */
6286 &state->epoch); /* epoch */
6287 if (NT_STATUS_IS_OK(status)) {
6288 state->found_lease = true;
6289 } else {
6290 DBG_WARNING("Could not find version/epoch: %s\n",
6291 nt_errstr(status));
6292 return false;
6295 if (e_lease_type == SMB2_LEASE_NONE) {
6296 return false;
6298 send_break_message(state->msg_ctx, &state->id, e, SMB2_LEASE_NONE);
6301 * Windows 7 and 8 lease clients are broken in that they will
6302 * not respond to lease break requests whilst waiting for an
6303 * outstanding open request on that lease handle on the same
6304 * TCP connection, due to holding an internal inode lock.
6306 * This means we can't reschedule ourselves here, but must
6307 * return from the create.
6309 * Work around:
6311 * Send the breaks and then return SMB2_LEASE_NONE in the
6312 * lease handle to cause them to acknowledge the lease
6313 * break. Consultation with Microsoft engineering confirmed
6314 * this approach is safe.
6317 return false;
6320 static void lease_match_fid_fn(struct share_mode_lock *lck,
6321 void *private_data)
6323 bool ok;
6325 ok = share_mode_forall_leases(lck, lease_match_break_fn, private_data);
6326 if (!ok) {
6327 DBG_DEBUG("share_mode_forall_leases failed\n");
6331 static NTSTATUS lease_match(connection_struct *conn,
6332 struct smb_request *req,
6333 const struct smb2_lease_key *lease_key,
6334 const char *servicepath,
6335 const struct smb_filename *fname,
6336 uint16_t *p_version,
6337 uint16_t *p_epoch)
6339 struct smbd_server_connection *sconn = req->sconn;
6340 TALLOC_CTX *tos = talloc_tos();
6341 struct lease_match_state state = {
6342 .mem_ctx = tos,
6343 .servicepath = servicepath,
6344 .fname = fname,
6345 .match_status = NT_STATUS_OK
6347 uint32_t i;
6348 NTSTATUS status;
6350 state.file_existed = VALID_STAT(fname->st);
6351 if (state.file_existed) {
6352 state.id = vfs_file_id_from_sbuf(conn, &fname->st);
6355 status = leases_db_parse(&sconn->client->global->client_guid,
6356 lease_key, lease_match_parser, &state);
6357 if (!NT_STATUS_IS_OK(status)) {
6359 * Not found or error means okay: We can make the lease pass
6361 return NT_STATUS_OK;
6363 if (!NT_STATUS_EQUAL(state.match_status, NT_STATUS_OPLOCK_NOT_GRANTED)) {
6365 * Anything but NT_STATUS_OPLOCK_NOT_GRANTED, let the caller
6366 * deal with it.
6368 return state.match_status;
6371 /* We have to break all existing leases. */
6372 for (i = 0; i < state.num_file_ids; i++) {
6373 struct lease_match_break_state break_state = {
6374 .msg_ctx = conn->sconn->msg_ctx,
6375 .lease_key = lease_key,
6378 if (file_id_equal(&state.ids[i], &state.id)) {
6379 /* Don't need to break our own file. */
6380 continue;
6383 break_state.id = state.ids[i];
6385 status = share_mode_do_locked_vfs_denied(break_state.id,
6386 lease_match_fid_fn,
6387 &break_state);
6388 if (!NT_STATUS_IS_OK(status)) {
6389 /* Race condition - file already closed. */
6390 continue;
6393 if (break_state.found_lease) {
6394 *p_version = break_state.version;
6395 *p_epoch = break_state.epoch;
6399 * Ensure we don't grant anything more so we
6400 * never upgrade.
6402 return NT_STATUS_OPLOCK_NOT_GRANTED;
6406 * Wrapper around open_file_ntcreate and open_directory
6409 static NTSTATUS create_file_unixpath(connection_struct *conn,
6410 struct smb_request *req,
6411 struct files_struct *dirfsp,
6412 struct smb_filename *smb_fname,
6413 uint32_t access_mask,
6414 uint32_t share_access,
6415 uint32_t create_disposition,
6416 uint32_t create_options,
6417 uint32_t file_attributes,
6418 uint32_t oplock_request,
6419 const struct smb2_lease *lease,
6420 uint64_t allocation_size,
6421 uint32_t private_flags,
6422 struct security_descriptor *sd,
6423 struct ea_list *ea_list,
6425 files_struct **result,
6426 int *pinfo)
6428 struct smb2_lease none_lease;
6429 int info = FILE_WAS_OPENED;
6430 files_struct *base_fsp = NULL;
6431 files_struct *fsp = NULL;
6432 bool free_fsp_on_error = false;
6433 NTSTATUS status;
6434 int ret;
6435 struct smb_filename *parent_dir_fname = NULL;
6436 struct smb_filename *smb_fname_atname = NULL;
6438 DBG_DEBUG("access_mask = 0x%"PRIx32" "
6439 "file_attributes = 0x%"PRIx32" "
6440 "share_access = 0x%"PRIx32" "
6441 "create_disposition = 0x%"PRIx32" "
6442 "create_options = 0x%"PRIx32" "
6443 "oplock_request = 0x%"PRIx32" "
6444 "private_flags = 0x%"PRIx32" "
6445 "ea_list = %p, "
6446 "sd = %p, "
6447 "fname = %s\n",
6448 access_mask,
6449 file_attributes,
6450 share_access,
6451 create_disposition,
6452 create_options,
6453 oplock_request,
6454 private_flags,
6455 ea_list,
6457 smb_fname_str_dbg(smb_fname));
6459 if (create_options & FILE_OPEN_BY_FILE_ID) {
6460 status = NT_STATUS_NOT_SUPPORTED;
6461 goto fail;
6464 if (create_options & NTCREATEX_OPTIONS_INVALID_PARAM_MASK) {
6465 status = NT_STATUS_INVALID_PARAMETER;
6466 goto fail;
6469 if (!(create_options & FILE_OPEN_REPARSE_POINT) &&
6470 (smb_fname->fsp != NULL) && /* new files don't have an fsp */
6471 VALID_STAT(smb_fname->fsp->fsp_name->st))
6473 mode_t type = (smb_fname->fsp->fsp_name->st.st_ex_mode &
6474 S_IFMT);
6476 switch (type) {
6477 case S_IFREG:
6478 FALL_THROUGH;
6479 case S_IFDIR:
6480 break;
6481 case S_IFLNK:
6483 * We should never get this far with a symlink
6484 * "as such". Report as not existing.
6486 status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
6487 goto fail;
6488 default:
6489 status = NT_STATUS_IO_REPARSE_TAG_NOT_HANDLED;
6490 goto fail;
6494 if (req == NULL) {
6495 oplock_request |= INTERNAL_OPEN_ONLY;
6498 if (lease != NULL) {
6499 uint16_t epoch = lease->lease_epoch;
6500 uint16_t version = lease->lease_version;
6502 if (req == NULL) {
6503 DBG_WARNING("Got lease on internal open\n");
6504 status = NT_STATUS_INTERNAL_ERROR;
6505 goto fail;
6508 status = lease_match(conn,
6509 req,
6510 &lease->lease_key,
6511 conn->connectpath,
6512 smb_fname,
6513 &version,
6514 &epoch);
6515 if (NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) {
6516 /* Dynamic share file. No leases and update epoch... */
6517 none_lease = *lease;
6518 none_lease.lease_state = SMB2_LEASE_NONE;
6519 none_lease.lease_epoch = epoch;
6520 none_lease.lease_version = version;
6521 lease = &none_lease;
6522 } else if (!NT_STATUS_IS_OK(status)) {
6523 goto fail;
6527 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
6528 && (access_mask & DELETE_ACCESS)
6529 && !is_named_stream(smb_fname)) {
6531 * We can't open a file with DELETE access if any of the
6532 * streams is open without FILE_SHARE_DELETE
6534 status = open_streams_for_delete(conn, smb_fname);
6536 if (!NT_STATUS_IS_OK(status)) {
6537 goto fail;
6541 if (access_mask & SEC_FLAG_SYSTEM_SECURITY) {
6542 bool ok;
6544 ok = security_token_has_privilege(get_current_nttok(conn),
6545 SEC_PRIV_SECURITY);
6546 if (!ok) {
6547 DBG_DEBUG("open on %s failed - "
6548 "SEC_FLAG_SYSTEM_SECURITY denied.\n",
6549 smb_fname_str_dbg(smb_fname));
6550 status = NT_STATUS_PRIVILEGE_NOT_HELD;
6551 goto fail;
6554 if (conn_using_smb2(conn->sconn) &&
6555 (access_mask == SEC_FLAG_SYSTEM_SECURITY))
6558 * No other bits set. Windows SMB2 refuses this.
6559 * See smbtorture3 SMB2-SACL test.
6561 * Note this is an SMB2-only behavior,
6562 * smbtorture3 SMB1-SYSTEM-SECURITY already tests
6563 * that SMB1 allows this.
6565 status = NT_STATUS_ACCESS_DENIED;
6566 goto fail;
6571 * Files or directories can't be opened DELETE_ON_CLOSE without
6572 * delete access.
6573 * BUG: https://bugzilla.samba.org/show_bug.cgi?id=13358
6575 if ((create_options & FILE_DELETE_ON_CLOSE) &&
6576 ((access_mask & DELETE_ACCESS) == 0)) {
6577 status = NT_STATUS_INVALID_PARAMETER;
6578 goto fail;
6581 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
6582 && is_named_stream(smb_fname))
6584 uint32_t base_create_disposition;
6585 struct smb_filename *smb_fname_base = NULL;
6586 uint32_t base_privflags;
6588 if (create_options & FILE_DIRECTORY_FILE) {
6589 DBG_DEBUG("Can't open a stream as directory\n");
6590 status = NT_STATUS_NOT_A_DIRECTORY;
6591 goto fail;
6594 switch (create_disposition) {
6595 case FILE_OPEN:
6596 base_create_disposition = FILE_OPEN;
6597 break;
6598 default:
6599 base_create_disposition = FILE_OPEN_IF;
6600 break;
6603 smb_fname_base = cp_smb_filename_nostream(
6604 talloc_tos(), smb_fname);
6606 if (smb_fname_base == NULL) {
6607 status = NT_STATUS_NO_MEMORY;
6608 goto fail;
6612 * We may be creating the basefile as part of creating the
6613 * stream, so it's legal if the basefile doesn't exist at this
6614 * point, the create_file_unixpath() below will create it. But
6615 * if the basefile exists we want a handle so we can fstat() it.
6618 ret = vfs_stat(conn, smb_fname_base);
6619 if (ret == -1 && errno != ENOENT) {
6620 status = map_nt_error_from_unix(errno);
6621 TALLOC_FREE(smb_fname_base);
6622 goto fail;
6624 if (ret == 0) {
6625 status = openat_pathref_fsp(conn->cwd_fsp,
6626 smb_fname_base);
6627 if (!NT_STATUS_IS_OK(status)) {
6628 DBG_ERR("open_smb_fname_fsp [%s] failed: %s\n",
6629 smb_fname_str_dbg(smb_fname_base),
6630 nt_errstr(status));
6631 TALLOC_FREE(smb_fname_base);
6632 goto fail;
6636 * https://bugzilla.samba.org/show_bug.cgi?id=10229
6637 * We need to check if the requested access mask
6638 * could be used to open the underlying file (if
6639 * it existed), as we're passing in zero for the
6640 * access mask to the base filename.
6642 status = check_base_file_access(smb_fname_base->fsp,
6643 access_mask);
6645 if (!NT_STATUS_IS_OK(status)) {
6646 DEBUG(10, ("Permission check "
6647 "for base %s failed: "
6648 "%s\n", smb_fname->base_name,
6649 nt_errstr(status)));
6650 TALLOC_FREE(smb_fname_base);
6651 goto fail;
6655 base_privflags = NTCREATEX_FLAG_STREAM_BASEOPEN;
6657 /* Open the base file. */
6658 status = create_file_unixpath(conn,
6659 NULL,
6660 dirfsp,
6661 smb_fname_base,
6663 FILE_SHARE_READ
6664 | FILE_SHARE_WRITE
6665 | FILE_SHARE_DELETE,
6666 base_create_disposition,
6670 NULL,
6672 base_privflags,
6673 NULL,
6674 NULL,
6675 &base_fsp,
6676 NULL);
6677 TALLOC_FREE(smb_fname_base);
6679 if (!NT_STATUS_IS_OK(status)) {
6680 DEBUG(10, ("create_file_unixpath for base %s failed: "
6681 "%s\n", smb_fname->base_name,
6682 nt_errstr(status)));
6683 goto fail;
6687 if (smb_fname->fsp != NULL) {
6689 fsp = smb_fname->fsp;
6692 * We're about to use smb_fname->fsp for the fresh open.
6694 * Every fsp passed in via smb_fname->fsp already
6695 * holds a fsp->fsp_name. If it is already this
6696 * fsp->fsp_name that we got passed in as our input
6697 * argument smb_fname, these two are assumed to have
6698 * the same lifetime: Every fsp hangs of "conn", and
6699 * fsp->fsp_name is its talloc child.
6702 if (smb_fname != smb_fname->fsp->fsp_name) {
6704 * "smb_fname" is temporary in this case, but
6705 * the destructor of smb_fname would also tear
6706 * down the fsp we're about to use. Unlink
6707 * them from each other.
6709 smb_fname_fsp_unlink(smb_fname);
6712 * "fsp" is ours now
6714 free_fsp_on_error = true;
6717 status = fsp_bind_smb(fsp, req);
6718 if (!NT_STATUS_IS_OK(status)) {
6719 goto fail;
6722 if (fsp_is_alternate_stream(fsp)) {
6723 struct files_struct *tmp_base_fsp = fsp->base_fsp;
6725 fsp_set_base_fsp(fsp, NULL);
6727 fd_close(tmp_base_fsp);
6728 file_free(NULL, tmp_base_fsp);
6730 } else {
6732 * No fsp passed in that we can use, create one
6734 status = file_new(req, conn, &fsp);
6735 if(!NT_STATUS_IS_OK(status)) {
6736 goto fail;
6738 free_fsp_on_error = true;
6740 status = fsp_set_smb_fname(fsp, smb_fname);
6741 if (!NT_STATUS_IS_OK(status)) {
6742 goto fail;
6746 SMB_ASSERT(fsp->fsp_name->fsp != NULL);
6747 SMB_ASSERT(fsp->fsp_name->fsp == fsp);
6749 if (base_fsp) {
6751 * We're opening the stream element of a
6752 * base_fsp we already opened. Set up the
6753 * base_fsp pointer.
6755 fsp_set_base_fsp(fsp, base_fsp);
6758 if (dirfsp != NULL) {
6759 status = SMB_VFS_PARENT_PATHNAME(
6760 conn,
6761 talloc_tos(),
6762 smb_fname,
6763 &parent_dir_fname,
6764 &smb_fname_atname);
6765 if (!NT_STATUS_IS_OK(status)) {
6766 goto fail;
6768 } else {
6770 * Get a pathref on the parent. We can re-use this for
6771 * multiple calls to check parent ACLs etc. to avoid
6772 * pathname calls.
6774 status = parent_pathref(talloc_tos(),
6775 conn->cwd_fsp,
6776 smb_fname,
6777 &parent_dir_fname,
6778 &smb_fname_atname);
6779 if (!NT_STATUS_IS_OK(status)) {
6780 goto fail;
6783 dirfsp = parent_dir_fname->fsp;
6784 status = fsp_set_smb_fname(dirfsp, parent_dir_fname);
6785 if (!NT_STATUS_IS_OK(status)) {
6786 goto fail;
6791 * If it's a request for a directory open, deal with it separately.
6794 if (create_options & FILE_DIRECTORY_FILE) {
6796 if (create_options & FILE_NON_DIRECTORY_FILE) {
6797 status = NT_STATUS_INVALID_PARAMETER;
6798 goto fail;
6801 /* Can't open a temp directory. IFS kit test. */
6802 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
6803 (file_attributes & FILE_ATTRIBUTE_TEMPORARY)) {
6804 status = NT_STATUS_INVALID_PARAMETER;
6805 goto fail;
6809 * We will get a create directory here if the Win32
6810 * app specified a security descriptor in the
6811 * CreateDirectory() call.
6814 status = open_directory(conn,
6815 req,
6816 access_mask,
6817 share_access,
6818 create_disposition,
6819 create_options,
6820 file_attributes,
6821 dirfsp->fsp_name,
6822 smb_fname_atname,
6823 oplock_request,
6824 lease,
6826 &info,
6827 fsp);
6828 } else {
6831 * Ordinary file case.
6834 if (allocation_size) {
6835 fsp->initial_allocation_size = smb_roundup(fsp->conn,
6836 allocation_size);
6839 status = open_file_ntcreate(conn,
6840 req,
6841 access_mask,
6842 share_access,
6843 create_disposition,
6844 create_options,
6845 file_attributes,
6846 oplock_request,
6847 lease,
6848 private_flags,
6849 dirfsp->fsp_name,
6850 smb_fname_atname,
6851 &info,
6852 fsp);
6853 if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
6855 /* A stream open never opens a directory */
6857 if (base_fsp) {
6858 status = NT_STATUS_FILE_IS_A_DIRECTORY;
6859 goto fail;
6863 * Fail the open if it was explicitly a non-directory
6864 * file.
6867 if (create_options & FILE_NON_DIRECTORY_FILE) {
6868 status = NT_STATUS_FILE_IS_A_DIRECTORY;
6869 goto fail;
6872 status = open_directory(conn,
6873 req,
6874 access_mask,
6875 share_access,
6876 create_disposition,
6877 create_options,
6878 file_attributes,
6879 dirfsp->fsp_name,
6880 smb_fname_atname,
6881 oplock_request,
6882 lease,
6884 &info,
6885 fsp);
6889 if (!NT_STATUS_IS_OK(status)) {
6890 goto fail;
6893 fsp->fsp_flags.is_fsa = true;
6895 if ((ea_list != NULL) &&
6896 ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN))) {
6897 status = set_ea(conn, fsp, ea_list);
6898 if (!NT_STATUS_IS_OK(status)) {
6899 goto fail;
6903 if (!fsp->fsp_flags.is_directory &&
6904 S_ISDIR(fsp->fsp_name->st.st_ex_mode))
6906 status = NT_STATUS_ACCESS_DENIED;
6907 goto fail;
6910 /* Save the requested allocation size. */
6911 if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
6912 if ((allocation_size > (uint64_t)fsp->fsp_name->st.st_ex_size)
6913 && !(fsp->fsp_flags.is_directory))
6915 fsp->initial_allocation_size = smb_roundup(
6916 fsp->conn, allocation_size);
6917 if (vfs_allocate_file_space(
6918 fsp, fsp->initial_allocation_size) == -1) {
6919 status = NT_STATUS_DISK_FULL;
6920 goto fail;
6922 } else {
6923 fsp->initial_allocation_size = smb_roundup(
6924 fsp->conn, (uint64_t)fsp->fsp_name->st.st_ex_size);
6926 } else {
6927 fsp->initial_allocation_size = 0;
6930 if ((info == FILE_WAS_CREATED) &&
6931 !S_ISDIR(fsp->fsp_name->st.st_ex_mode) &&
6932 lp_nt_acl_support(SNUM(conn)) &&
6933 !fsp_is_alternate_stream(fsp)) {
6934 status = apply_new_nt_acl(dirfsp, fsp, sd);
6935 if (!NT_STATUS_IS_OK(status)) {
6936 DBG_WARNING("apply_new_nt_acl(): failed for %s with %s\n",
6937 fsp_str_dbg(fsp), nt_errstr(status));
6938 goto fail;
6942 if ((conn->fs_capabilities & FILE_FILE_COMPRESSION)
6943 && (create_options & FILE_NO_COMPRESSION)
6944 && (info == FILE_WAS_CREATED)) {
6945 status = SMB_VFS_SET_COMPRESSION(conn, fsp, fsp,
6946 COMPRESSION_FORMAT_NONE);
6947 if (!NT_STATUS_IS_OK(status)) {
6948 DEBUG(1, ("failed to disable compression: %s\n",
6949 nt_errstr(status)));
6953 DEBUG(10, ("create_file_unixpath: info=%d\n", info));
6955 *result = fsp;
6956 if (pinfo != NULL) {
6957 *pinfo = info;
6960 smb_fname->st = fsp->fsp_name->st;
6962 TALLOC_FREE(parent_dir_fname);
6964 return NT_STATUS_OK;
6966 fail:
6967 DEBUG(10, ("create_file_unixpath: %s\n", nt_errstr(status)));
6969 if (fsp != NULL) {
6971 * The close_file below will close
6972 * fsp->base_fsp.
6974 base_fsp = NULL;
6975 close_file_smb(req, fsp, ERROR_CLOSE);
6976 if (free_fsp_on_error) {
6977 file_free(req, fsp);
6978 fsp = NULL;
6981 if (base_fsp != NULL) {
6982 close_file_free(req, &base_fsp, ERROR_CLOSE);
6985 TALLOC_FREE(parent_dir_fname);
6987 return status;
6990 static NTSTATUS check_posix_create_context(connection_struct *conn,
6991 struct smb_request *req,
6992 const struct smb2_create_blobs *in_context_blobs,
6993 uint32_t create_options,
6994 uint32_t *file_attributes)
6996 uint32_t wire_mode_bits = 0;
6997 NTSTATUS status;
6998 mode_t mode_bits = 0;
6999 SMB_STRUCT_STAT sbuf = { 0 };
7000 struct smb2_create_blob *posx = NULL;
7002 if (req == NULL || !req->posix_pathnames) {
7003 return NT_STATUS_OK;
7006 posx = smb2_create_blob_find(
7007 in_context_blobs, SMB2_CREATE_TAG_POSIX);
7008 if (posx == NULL) {
7009 return NT_STATUS_OK;
7012 if (posx->data.length != 4) {
7013 return NT_STATUS_INVALID_PARAMETER;
7016 wire_mode_bits = IVAL(posx->data.data, 0);
7017 status = unix_perms_from_wire(conn,
7018 &sbuf,
7019 wire_mode_bits,
7020 &mode_bits);
7021 if (!NT_STATUS_IS_OK(status)) {
7022 return status;
7024 if (create_options & FILE_DIRECTORY_FILE) {
7025 mode_bits = apply_conf_dir_mask(conn, mode_bits);
7026 } else {
7027 mode_bits = apply_conf_file_mask(conn, mode_bits);
7030 * Remove type info from mode, leaving only the
7031 * permissions and setuid/gid bits.
7033 mode_bits &= ~S_IFMT;
7035 *file_attributes = (FILE_FLAG_POSIX_SEMANTICS | mode_bits);
7037 return NT_STATUS_OK;
7040 NTSTATUS create_file_default(connection_struct *conn,
7041 struct smb_request *req,
7042 struct files_struct *dirfsp,
7043 struct smb_filename *smb_fname,
7044 uint32_t access_mask,
7045 uint32_t share_access,
7046 uint32_t create_disposition,
7047 uint32_t create_options,
7048 uint32_t file_attributes,
7049 uint32_t oplock_request,
7050 const struct smb2_lease *lease,
7051 uint64_t allocation_size,
7052 uint32_t private_flags,
7053 struct security_descriptor *sd,
7054 struct ea_list *ea_list,
7055 files_struct **result,
7056 int *pinfo,
7057 const struct smb2_create_blobs *in_context_blobs,
7058 struct smb2_create_blobs *out_context_blobs)
7060 int info = FILE_WAS_OPENED;
7061 files_struct *fsp = NULL;
7062 NTSTATUS status;
7063 bool stream_name = false;
7065 DBG_DEBUG("access_mask = 0x%" PRIu32
7066 " file_attributes = 0x%" PRIu32
7067 " share_access = 0x%" PRIu32
7068 " create_disposition = 0x%" PRIu32
7069 " create_options = 0x%" PRIu32
7070 " oplock_request = 0x%" PRIu32
7071 " private_flags = 0x%" PRIu32
7072 " ea_list = %p, sd = %p, fname = %s\n",
7073 access_mask,
7074 file_attributes,
7075 share_access,
7076 create_disposition,
7077 create_options,
7078 oplock_request,
7079 private_flags,
7080 ea_list,
7082 smb_fname_str_dbg(smb_fname));
7084 if (req != NULL) {
7086 * Remember the absolute time of the original request
7087 * with this mid. We'll use it later to see if this
7088 * has timed out.
7090 get_deferred_open_message_state(req, &req->request_time, NULL);
7094 * Check to see if this is a mac fork of some kind.
7097 stream_name = is_ntfs_stream_smb_fname(smb_fname);
7098 if (stream_name) {
7099 enum FAKE_FILE_TYPE fake_file_type;
7101 fake_file_type = is_fake_file(smb_fname);
7103 if (req != NULL && fake_file_type != FAKE_FILE_TYPE_NONE) {
7106 * Here we go! support for changing the disk quotas
7107 * --metze
7109 * We need to fake up to open this MAGIC QUOTA file
7110 * and return a valid FID.
7112 * w2k close this file directly after opening xp
7113 * also tries a QUERY_FILE_INFO on the file and then
7114 * close it
7116 status = open_fake_file(req, conn, req->vuid,
7117 fake_file_type, smb_fname,
7118 access_mask, &fsp);
7119 if (!NT_STATUS_IS_OK(status)) {
7120 goto fail;
7123 ZERO_STRUCT(smb_fname->st);
7124 goto done;
7127 if (!(conn->fs_capabilities & FILE_NAMED_STREAMS)) {
7128 status = NT_STATUS_OBJECT_NAME_INVALID;
7129 goto fail;
7133 if (is_ntfs_default_stream_smb_fname(smb_fname)) {
7134 int ret;
7135 /* We have to handle this error here. */
7136 if (create_options & FILE_DIRECTORY_FILE) {
7137 status = NT_STATUS_NOT_A_DIRECTORY;
7138 goto fail;
7140 ret = vfs_stat(conn, smb_fname);
7141 if (ret == 0 && VALID_STAT_OF_DIR(smb_fname->st)) {
7142 status = NT_STATUS_FILE_IS_A_DIRECTORY;
7143 goto fail;
7147 status = check_posix_create_context(conn,
7148 req,
7149 in_context_blobs,
7150 create_options,
7151 &file_attributes);
7152 if (!NT_STATUS_IS_OK(status)) {
7153 goto fail;
7156 status = create_file_unixpath(conn,
7157 req,
7158 dirfsp,
7159 smb_fname,
7160 access_mask,
7161 share_access,
7162 create_disposition,
7163 create_options,
7164 file_attributes,
7165 oplock_request,
7166 lease,
7167 allocation_size,
7168 private_flags,
7170 ea_list,
7171 &fsp,
7172 &info);
7173 if (!NT_STATUS_IS_OK(status)) {
7174 goto fail;
7177 done:
7178 DEBUG(10, ("create_file: info=%d\n", info));
7180 *result = fsp;
7181 if (pinfo != NULL) {
7182 *pinfo = info;
7184 return NT_STATUS_OK;
7186 fail:
7187 DEBUG(10, ("create_file: %s\n", nt_errstr(status)));
7189 if (fsp != NULL) {
7190 close_file_free(req, &fsp, ERROR_CLOSE);
7192 return status;