Fix starvation of pending writes in CTDB queues
[Samba.git] / source3 / smbd / open.c
blob3b1e9700db3163f0e1fe5b53f7408714ec7dd917
1 /*
2 Unix SMB/CIFS implementation.
3 file opening and share modes
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Jeremy Allison 2001-2004
6 Copyright (C) Volker Lendecke 2005
7 Copyright (C) Ralph Boehme 2017
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "includes.h"
24 #include "system/filesys.h"
25 #include "lib/util/server_id.h"
26 #include "printing.h"
27 #include "locking/share_mode_lock.h"
28 #include "smbd/smbd.h"
29 #include "smbd/globals.h"
30 #include "fake_file.h"
31 #include "../libcli/security/security.h"
32 #include "../librpc/gen_ndr/ndr_security.h"
33 #include "../librpc/gen_ndr/ndr_open_files.h"
34 #include "../librpc/gen_ndr/idmap.h"
35 #include "../librpc/gen_ndr/ioctl.h"
36 #include "passdb/lookup_sid.h"
37 #include "auth.h"
38 #include "serverid.h"
39 #include "messages.h"
40 #include "source3/lib/dbwrap/dbwrap_watch.h"
41 #include "locking/leases_db.h"
42 #include "librpc/gen_ndr/ndr_leases_db.h"
43 #include "lib/util/time_basic.h"
44 #include "source3/smbd/dir.h"
46 #if defined(HAVE_LINUX_MAGIC_H)
47 #include <linux/magic.h>
48 #endif
50 extern const struct generic_mapping file_generic_mapping;
52 struct deferred_open_record {
53 struct smbXsrv_connection *xconn;
54 uint64_t mid;
56 bool async_open;
59 * Timer for async opens, needed because they don't use a watch on
60 * a locking.tdb record. This is currently only used for real async
61 * opens and just terminates smbd if the async open times out.
63 struct tevent_timer *te;
66 * For the samba kernel oplock case we use both a timeout and
67 * a watch on locking.tdb. This way in case it's smbd holding
68 * the kernel oplock we get directly notified for the retry
69 * once the kernel oplock is properly broken. Store the req
70 * here so that it can be timely discarded once the timer
71 * above fires.
73 struct tevent_req *watch_req;
76 /****************************************************************************
77 If the requester wanted DELETE_ACCESS and was rejected because
78 the file ACL didn't include DELETE_ACCESS, see if the parent ACL
79 overrides this.
80 ****************************************************************************/
82 static bool parent_override_delete(connection_struct *conn,
83 struct files_struct *dirfsp,
84 const struct smb_filename *smb_fname,
85 uint32_t access_mask,
86 uint32_t rejected_mask)
88 if ((access_mask & DELETE_ACCESS) &&
89 (rejected_mask & DELETE_ACCESS) &&
90 can_delete_file_in_directory(conn,
91 dirfsp,
92 smb_fname))
94 return true;
96 return false;
99 /****************************************************************************
100 Check if we have open rights.
101 ****************************************************************************/
103 static NTSTATUS smbd_check_access_rights_fname(
104 struct connection_struct *conn,
105 const struct smb_filename *smb_fname,
106 bool use_privs,
107 uint32_t access_mask,
108 uint32_t do_not_check_mask)
110 uint32_t rejected_share_access;
111 uint32_t effective_access;
113 rejected_share_access = access_mask & ~(conn->share_access);
115 if (rejected_share_access) {
116 DBG_DEBUG("rejected share access 0x%"PRIx32" on "
117 "%s (0x%"PRIx32")\n",
118 access_mask,
119 smb_fname_str_dbg(smb_fname),
120 rejected_share_access);
121 return NT_STATUS_ACCESS_DENIED;
124 effective_access = access_mask & ~do_not_check_mask;
125 if (effective_access == 0) {
126 DBG_DEBUG("do_not_check_mask override on %s. Granting 0x%x for free.\n",
127 smb_fname_str_dbg(smb_fname),
128 (unsigned int)access_mask);
129 return NT_STATUS_OK;
132 if (!use_privs && get_current_uid(conn) == (uid_t)0) {
133 /* I'm sorry sir, I didn't know you were root... */
134 DBG_DEBUG("root override on %s. Granting 0x%x\n",
135 smb_fname_str_dbg(smb_fname),
136 (unsigned int)access_mask);
137 return NT_STATUS_OK;
140 if ((access_mask & DELETE_ACCESS) &&
141 !lp_acl_check_permissions(SNUM(conn)))
143 DBG_DEBUG("Not checking ACL on DELETE_ACCESS on file %s. "
144 "Granting 0x%"PRIx32"\n",
145 smb_fname_str_dbg(smb_fname),
146 access_mask);
147 return NT_STATUS_OK;
150 if (access_mask == DELETE_ACCESS &&
151 VALID_STAT(smb_fname->st) &&
152 S_ISLNK(smb_fname->st.st_ex_mode))
154 /* We can always delete a symlink. */
155 DBG_DEBUG("Not checking ACL on DELETE_ACCESS on symlink %s.\n",
156 smb_fname_str_dbg(smb_fname));
157 return NT_STATUS_OK;
160 return NT_STATUS_MORE_PROCESSING_REQUIRED;
163 static NTSTATUS smbd_check_access_rights_sd(
164 struct connection_struct *conn,
165 struct files_struct *dirfsp,
166 const struct smb_filename *smb_fname,
167 struct security_descriptor *sd,
168 bool use_privs,
169 uint32_t access_mask,
170 uint32_t do_not_check_mask)
172 uint32_t rejected_mask = access_mask;
173 NTSTATUS status;
175 if (sd == NULL) {
176 goto access_denied;
179 status = se_file_access_check(sd,
180 get_current_nttok(conn),
181 use_privs,
182 (access_mask & ~do_not_check_mask),
183 &rejected_mask);
185 DBG_DEBUG("File [%s] requesting [0x%"PRIx32"] "
186 "returning [0x%"PRIx32"] (%s)\n",
187 smb_fname_str_dbg(smb_fname),
188 access_mask,
189 rejected_mask,
190 nt_errstr(status));
192 if (!NT_STATUS_IS_OK(status)) {
193 if (DEBUGLEVEL >= 10) {
194 DBG_DEBUG("acl for %s is:\n",
195 smb_fname_str_dbg(smb_fname));
196 NDR_PRINT_DEBUG(security_descriptor, sd);
200 TALLOC_FREE(sd);
202 if (NT_STATUS_IS_OK(status) ||
203 !NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED))
205 return status;
208 /* Here we know status == NT_STATUS_ACCESS_DENIED. */
210 access_denied:
212 if ((access_mask & FILE_WRITE_ATTRIBUTES) &&
213 (rejected_mask & FILE_WRITE_ATTRIBUTES) &&
214 !lp_store_dos_attributes(SNUM(conn)) &&
215 (lp_map_readonly(SNUM(conn)) ||
216 lp_map_archive(SNUM(conn)) ||
217 lp_map_hidden(SNUM(conn)) ||
218 lp_map_system(SNUM(conn))))
220 rejected_mask &= ~FILE_WRITE_ATTRIBUTES;
222 DBG_DEBUG("overrode FILE_WRITE_ATTRIBUTES on file %s\n",
223 smb_fname_str_dbg(smb_fname));
226 if (parent_override_delete(conn,
227 dirfsp,
228 smb_fname,
229 access_mask,
230 rejected_mask))
233 * Were we trying to do an open for delete and didn't get DELETE
234 * access. Check if the directory allows DELETE_CHILD.
235 * See here:
236 * http://blogs.msdn.com/oldnewthing/archive/2004/06/04/148426.aspx
237 * for details.
240 rejected_mask &= ~DELETE_ACCESS;
242 DBG_DEBUG("Overrode DELETE_ACCESS on file %s\n",
243 smb_fname_str_dbg(smb_fname));
246 if (rejected_mask != 0) {
247 return NT_STATUS_ACCESS_DENIED;
249 return NT_STATUS_OK;
252 NTSTATUS smbd_check_access_rights_fsp(struct files_struct *dirfsp,
253 struct files_struct *fsp,
254 bool use_privs,
255 uint32_t access_mask)
257 struct security_descriptor *sd = NULL;
258 uint32_t do_not_check_mask = 0;
259 NTSTATUS status;
261 /* Cope with fake/printer fsp's. */
262 if (fsp->fake_file_handle != NULL || fsp->print_file != NULL) {
263 if ((fsp->access_mask & access_mask) != access_mask) {
264 return NT_STATUS_ACCESS_DENIED;
266 return NT_STATUS_OK;
269 if (fsp_get_pathref_fd(fsp) == -1) {
271 * This is a POSIX open on a symlink. For the pathname
272 * version of this function we used to return the st_mode
273 * bits turned into an NT ACL. For a symlink the mode bits
274 * are always rwxrwxrwx which means the pathname version always
275 * returned NT_STATUS_OK for a symlink. For the handle reference
276 * to a symlink use the handle access bits.
278 if ((fsp->access_mask & access_mask) != access_mask) {
279 return NT_STATUS_ACCESS_DENIED;
281 return NT_STATUS_OK;
285 * If we can access the path to this file, by
286 * default we have FILE_READ_ATTRIBUTES from the
287 * containing directory. See the section:
288 * "Algorithm to Check Access to an Existing File"
289 * in MS-FSA.pdf.
291 * se_file_access_check() also takes care of
292 * owner WRITE_DAC and READ_CONTROL.
294 do_not_check_mask = FILE_READ_ATTRIBUTES;
297 * Samba 3.6 and earlier granted execute access even
298 * if the ACL did not contain execute rights.
299 * Samba 4.0 is more correct and checks it.
300 * The compatibility mode allows one to skip this check
301 * to smoothen upgrades.
303 if (lp_acl_allow_execute_always(SNUM(fsp->conn))) {
304 do_not_check_mask |= FILE_EXECUTE;
307 status = smbd_check_access_rights_fname(fsp->conn,
308 fsp->fsp_name,
309 use_privs,
310 access_mask,
311 do_not_check_mask);
312 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
313 return status;
316 status = SMB_VFS_FGET_NT_ACL(metadata_fsp(fsp),
317 (SECINFO_OWNER |
318 SECINFO_GROUP |
319 SECINFO_DACL),
320 talloc_tos(),
321 &sd);
322 if (!NT_STATUS_IS_OK(status)) {
323 DBG_DEBUG("Could not get acl on %s: %s\n",
324 fsp_str_dbg(fsp),
325 nt_errstr(status));
326 return status;
329 return smbd_check_access_rights_sd(fsp->conn,
330 dirfsp,
331 fsp->fsp_name,
333 use_privs,
334 access_mask,
335 do_not_check_mask);
339 * Given an fsp that represents a parent directory,
340 * check if the requested access can be granted.
342 NTSTATUS check_parent_access_fsp(struct files_struct *fsp,
343 uint32_t access_mask)
345 NTSTATUS status;
346 struct security_descriptor *parent_sd = NULL;
347 uint32_t access_granted = 0;
348 uint32_t name_hash;
349 bool delete_on_close_set;
350 TALLOC_CTX *frame = talloc_stackframe();
352 if (get_current_uid(fsp->conn) == (uid_t)0) {
353 /* I'm sorry sir, I didn't know you were root... */
354 DBG_DEBUG("root override on %s. Granting 0x%x\n",
355 fsp_str_dbg(fsp),
356 (unsigned int)access_mask);
357 status = NT_STATUS_OK;
358 goto out;
361 status = SMB_VFS_FGET_NT_ACL(fsp,
362 (SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL),
363 frame,
364 &parent_sd);
366 if (!NT_STATUS_IS_OK(status)) {
367 DBG_INFO("SMB_VFS_FGET_NT_ACL failed for "
368 "%s with error %s\n",
369 fsp_str_dbg(fsp),
370 nt_errstr(status));
371 goto out;
375 * If we can access the path to this file, by
376 * default we have FILE_READ_ATTRIBUTES from the
377 * containing directory. See the section:
378 * "Algorithm to Check Access to an Existing File"
379 * in MS-FSA.pdf.
381 * se_file_access_check() also takes care of
382 * owner WRITE_DAC and READ_CONTROL.
384 status = se_file_access_check(parent_sd,
385 get_current_nttok(fsp->conn),
386 false,
387 (access_mask & ~FILE_READ_ATTRIBUTES),
388 &access_granted);
389 if(!NT_STATUS_IS_OK(status)) {
390 DBG_INFO("access check "
391 "on directory %s for mask 0x%x returned (0x%x) %s\n",
392 fsp_str_dbg(fsp),
393 access_mask,
394 access_granted,
395 nt_errstr(status));
396 goto out;
399 if (!(access_mask & (SEC_DIR_ADD_FILE | SEC_DIR_ADD_SUBDIR))) {
400 status = NT_STATUS_OK;
401 goto out;
403 if (!lp_check_parent_directory_delete_on_close(SNUM(fsp->conn))) {
404 status = NT_STATUS_OK;
405 goto out;
408 /* Check if the directory has delete-on-close set */
409 status = file_name_hash(fsp->conn,
410 fsp->fsp_name->base_name,
411 &name_hash);
412 if (!NT_STATUS_IS_OK(status)) {
413 goto out;
416 get_file_infos(fsp->file_id, name_hash, &delete_on_close_set, NULL);
417 if (delete_on_close_set) {
418 status = NT_STATUS_DELETE_PENDING;
419 goto out;
422 status = NT_STATUS_OK;
424 out:
425 TALLOC_FREE(frame);
426 return status;
429 /****************************************************************************
430 Ensure when opening a base file for a stream open that we have permissions
431 to do so given the access mask on the base file.
432 ****************************************************************************/
434 static NTSTATUS check_base_file_access(struct files_struct *fsp,
435 uint32_t access_mask)
437 NTSTATUS status;
439 status = smbd_calculate_access_mask_fsp(fsp->conn->cwd_fsp,
440 fsp,
441 false,
442 access_mask,
443 &access_mask);
444 if (!NT_STATUS_IS_OK(status)) {
445 DEBUG(10, ("smbd_calculate_access_mask "
446 "on file %s returned %s\n",
447 fsp_str_dbg(fsp),
448 nt_errstr(status)));
449 return status;
452 if (access_mask & (FILE_WRITE_DATA|FILE_APPEND_DATA)) {
453 uint32_t dosattrs;
454 if (!CAN_WRITE(fsp->conn)) {
455 return NT_STATUS_ACCESS_DENIED;
457 dosattrs = fdos_mode(fsp);
458 if (dosattrs & FILE_ATTRIBUTE_READONLY) {
459 return NT_STATUS_ACCESS_DENIED;
463 return smbd_check_access_rights_fsp(fsp->conn->cwd_fsp,
464 fsp,
465 false,
466 access_mask);
469 static NTSTATUS chdir_below_conn(
470 TALLOC_CTX *mem_ctx,
471 connection_struct *conn,
472 const char *connectpath,
473 size_t connectpath_len,
474 struct smb_filename *dir_fname,
475 struct smb_filename **_oldwd_fname)
477 struct smb_filename *oldwd_fname = NULL;
478 struct smb_filename *smb_fname_dot = NULL;
479 struct smb_filename *real_fname = NULL;
480 const char *relative = NULL;
481 NTSTATUS status;
482 int ret;
483 bool ok;
485 if (!ISDOT(dir_fname->base_name)) {
487 oldwd_fname = vfs_GetWd(talloc_tos(), conn);
488 if (oldwd_fname == NULL) {
489 status = map_nt_error_from_unix(errno);
490 goto out;
493 /* Pin parent directory in place. */
494 ret = vfs_ChDir(conn, dir_fname);
495 if (ret == -1) {
496 status = map_nt_error_from_unix(errno);
497 DBG_DEBUG("chdir to %s failed: %s\n",
498 dir_fname->base_name,
499 strerror(errno));
500 goto out;
504 smb_fname_dot = synthetic_smb_fname(
505 talloc_tos(),
506 ".",
507 NULL,
508 NULL,
509 dir_fname->twrp,
510 dir_fname->flags);
511 if (smb_fname_dot == NULL) {
512 status = NT_STATUS_NO_MEMORY;
513 goto out;
516 real_fname = SMB_VFS_REALPATH(conn, talloc_tos(), smb_fname_dot);
517 if (real_fname == NULL) {
518 status = map_nt_error_from_unix(errno);
519 DBG_DEBUG("realpath in %s failed: %s\n",
520 dir_fname->base_name,
521 strerror(errno));
522 goto out;
524 TALLOC_FREE(smb_fname_dot);
526 ok = subdir_of(connectpath,
527 connectpath_len,
528 real_fname->base_name,
529 &relative);
530 if (ok) {
531 TALLOC_FREE(real_fname);
532 *_oldwd_fname = oldwd_fname;
533 return NT_STATUS_OK;
536 DBG_NOTICE("Bad access attempt: %s is a symlink "
537 "outside the share path\n"
538 "conn_rootdir =%s\n"
539 "resolved_name=%s\n",
540 dir_fname->base_name,
541 connectpath,
542 real_fname->base_name);
543 TALLOC_FREE(real_fname);
545 status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
547 out:
548 if (oldwd_fname != NULL) {
549 ret = vfs_ChDir(conn, oldwd_fname);
550 SMB_ASSERT(ret == 0);
551 TALLOC_FREE(oldwd_fname);
554 return status;
558 * Get the symlink target of dirfsp/symlink_name, making sure the
559 * target is below connection_path.
562 static NTSTATUS symlink_target_below_conn(
563 TALLOC_CTX *mem_ctx,
564 const char *connection_path,
565 struct files_struct *fsp,
566 struct files_struct *dirfsp,
567 struct smb_filename *symlink_name,
568 char **_target)
570 char *target = NULL;
571 char *absolute = NULL;
572 NTSTATUS status;
574 if (fsp_get_pathref_fd(fsp) != -1) {
576 * fsp is an O_PATH open, Linux does a "freadlink"
577 * with an empty name argument to readlinkat
579 status = readlink_talloc(talloc_tos(), fsp, NULL, &target);
580 } else {
581 status = readlink_talloc(
582 talloc_tos(), dirfsp, symlink_name, &target);
585 status = safe_symlink_target_path(talloc_tos(),
586 connection_path,
587 dirfsp->fsp_name->base_name,
588 target,
590 &absolute);
591 if (!NT_STATUS_IS_OK(status)) {
592 DBG_DEBUG("safe_symlink_target_path() failed: %s\n",
593 nt_errstr(status));
594 return status;
597 if (absolute[0] == '\0') {
599 * special case symlink to share root: "." is our
600 * share root filename
602 TALLOC_FREE(absolute);
603 absolute = talloc_strdup(talloc_tos(), ".");
604 if (absolute == NULL) {
605 return NT_STATUS_NO_MEMORY;
609 *_target = absolute;
610 return NT_STATUS_OK;
613 /****************************************************************************
614 Non-widelink open.
615 ****************************************************************************/
617 static NTSTATUS non_widelink_open(const struct files_struct *dirfsp,
618 files_struct *fsp,
619 struct smb_filename *smb_fname,
620 const struct vfs_open_how *_how)
622 struct connection_struct *conn = fsp->conn;
623 const char *connpath = SMB_VFS_CONNECTPATH(conn, dirfsp, smb_fname);
624 size_t connpath_len;
625 NTSTATUS status = NT_STATUS_OK;
626 int fd = -1;
627 char *orig_smb_fname_base = smb_fname->base_name;
628 struct smb_filename *orig_fsp_name = fsp->fsp_name;
629 struct smb_filename *smb_fname_rel = NULL;
630 struct smb_filename *oldwd_fname = NULL;
631 struct smb_filename *parent_dir_fname = NULL;
632 struct vfs_open_how how = *_how;
633 char *target = NULL;
634 size_t link_depth = 0;
635 int ret;
637 SMB_ASSERT(!fsp_is_alternate_stream(fsp));
639 if (connpath == NULL) {
641 * This can happen with shadow_copy2 if the snapshot
642 * path is not found
644 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
646 connpath_len = strlen(connpath);
648 again:
649 if (smb_fname->base_name[0] == '/') {
650 int cmp = strcmp(connpath, smb_fname->base_name);
651 if (cmp == 0) {
652 smb_fname->base_name = talloc_strdup(smb_fname, "");
653 if (smb_fname->base_name == NULL) {
654 status = NT_STATUS_NO_MEMORY;
655 goto out;
660 if (dirfsp == conn->cwd_fsp) {
662 status = SMB_VFS_PARENT_PATHNAME(fsp->conn,
663 talloc_tos(),
664 smb_fname,
665 &parent_dir_fname,
666 &smb_fname_rel);
667 if (!NT_STATUS_IS_OK(status)) {
668 goto out;
671 status = chdir_below_conn(
672 talloc_tos(),
673 conn,
674 connpath,
675 connpath_len,
676 parent_dir_fname,
677 &oldwd_fname);
678 if (!NT_STATUS_IS_OK(status)) {
679 goto out;
682 /* Setup fsp->fsp_name to be relative to cwd */
683 fsp->fsp_name = smb_fname_rel;
684 } else {
686 * fsp->fsp_name is unchanged as it is already correctly
687 * relative to dirfsp.
689 smb_fname_rel = smb_fname;
694 * Assert nobody can step in with a symlink on the
695 * path, there is no path anymore and we'll use
696 * O_NOFOLLOW to open.
698 char *slash = strchr_m(smb_fname_rel->base_name, '/');
699 SMB_ASSERT(slash == NULL);
702 how.flags |= O_NOFOLLOW;
704 fd = SMB_VFS_OPENAT(conn,
705 dirfsp,
706 smb_fname_rel,
707 fsp,
708 &how);
709 fsp_set_fd(fsp, fd); /* This preserves errno */
711 if (fd == -1) {
712 status = map_nt_error_from_unix(errno);
714 if (errno == ENOENT) {
715 goto out;
719 * ENOENT makes it worthless retrying with a
720 * stat, we know for sure the file does not
721 * exist. For everything else we want to know
722 * what's there.
724 ret = SMB_VFS_FSTATAT(
725 fsp->conn,
726 dirfsp,
727 smb_fname_rel,
728 &fsp->fsp_name->st,
729 AT_SYMLINK_NOFOLLOW);
731 if (ret == -1) {
733 * Keep the original error. Otherwise we would
734 * mask for example EROFS for open(O_CREAT),
735 * turning it into ENOENT.
737 goto out;
739 } else {
740 ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st);
743 if (ret == -1) {
744 status = map_nt_error_from_unix(errno);
745 DBG_DEBUG("fstat[at](%s) failed: %s\n",
746 smb_fname_str_dbg(smb_fname),
747 strerror(errno));
748 goto out;
751 fsp->fsp_flags.is_directory = S_ISDIR(fsp->fsp_name->st.st_ex_mode);
752 orig_fsp_name->st = fsp->fsp_name->st;
754 if (!S_ISLNK(fsp->fsp_name->st.st_ex_mode)) {
755 goto out;
759 * Found a symlink to follow in user space
762 if (fsp->fsp_name->flags & SMB_FILENAME_POSIX_PATH) {
763 /* Never follow symlinks on posix open. */
764 status = NT_STATUS_STOPPED_ON_SYMLINK;
765 goto out;
767 if (!lp_follow_symlinks(SNUM(conn))) {
768 /* Explicitly no symlinks. */
769 status = NT_STATUS_STOPPED_ON_SYMLINK;
770 goto out;
773 link_depth += 1;
774 if (link_depth >= 40) {
775 status = NT_STATUS_STOPPED_ON_SYMLINK;
776 goto out;
779 fsp->fsp_name = orig_fsp_name;
781 status = symlink_target_below_conn(
782 talloc_tos(),
783 connpath,
784 fsp,
785 discard_const_p(files_struct, dirfsp),
786 smb_fname_rel,
787 &target);
789 if (!NT_STATUS_IS_OK(status)) {
790 DBG_DEBUG("symlink_target_below_conn() failed: %s\n",
791 nt_errstr(status));
792 goto out;
796 * Close what openat(O_PATH) potentially left behind
798 fd_close(fsp);
800 if (smb_fname->base_name != orig_smb_fname_base) {
801 TALLOC_FREE(smb_fname->base_name);
803 smb_fname->base_name = target;
805 if (oldwd_fname != NULL) {
806 ret = vfs_ChDir(conn, oldwd_fname);
807 if (ret == -1) {
808 smb_panic("unable to get back to old directory\n");
810 TALLOC_FREE(oldwd_fname);
814 * And do it all again... As smb_fname is not relative to the passed in
815 * dirfsp anymore, we pass conn->cwd_fsp as dirfsp to
816 * non_widelink_open() to trigger the chdir(parentdir) logic.
818 dirfsp = conn->cwd_fsp;
820 goto again;
822 out:
823 fsp->fsp_name = orig_fsp_name;
824 smb_fname->base_name = orig_smb_fname_base;
826 TALLOC_FREE(parent_dir_fname);
828 if (!NT_STATUS_IS_OK(status)) {
829 fd_close(fsp);
832 if (oldwd_fname != NULL) {
833 ret = vfs_ChDir(conn, oldwd_fname);
834 if (ret == -1) {
835 smb_panic("unable to get back to old directory\n");
837 TALLOC_FREE(oldwd_fname);
839 return status;
842 /****************************************************************************
843 fd support routines - attempt to do a dos_open.
844 ****************************************************************************/
846 NTSTATUS fd_openat(const struct files_struct *dirfsp,
847 struct smb_filename *smb_fname,
848 files_struct *fsp,
849 const struct vfs_open_how *_how)
851 struct vfs_open_how how = *_how;
852 struct connection_struct *conn = fsp->conn;
853 NTSTATUS status = NT_STATUS_OK;
854 bool fsp_is_stream = fsp_is_alternate_stream(fsp);
855 bool smb_fname_is_stream = is_named_stream(smb_fname);
857 SMB_ASSERT(fsp_is_stream == smb_fname_is_stream);
860 * Never follow symlinks on a POSIX client. The
861 * client should be doing this.
864 if ((fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) || !lp_follow_symlinks(SNUM(conn))) {
865 how.flags |= O_NOFOLLOW;
868 if (fsp_is_stream) {
869 int fd;
871 fd = SMB_VFS_OPENAT(
872 conn,
873 NULL, /* stream open is relative to fsp->base_fsp */
874 smb_fname,
875 fsp,
876 &how);
877 if (fd == -1) {
878 status = map_nt_error_from_unix(errno);
880 fsp_set_fd(fsp, fd);
882 if (fd != -1) {
883 status = vfs_stat_fsp(fsp);
884 if (!NT_STATUS_IS_OK(status)) {
885 DBG_DEBUG("vfs_stat_fsp failed: %s\n",
886 nt_errstr(status));
887 fd_close(fsp);
891 return status;
895 * Only follow symlinks within a share
896 * definition.
898 status = non_widelink_open(dirfsp, fsp, smb_fname, &how);
899 if (!NT_STATUS_IS_OK(status)) {
900 if (NT_STATUS_EQUAL(status, NT_STATUS_TOO_MANY_OPENED_FILES)) {
901 static time_t last_warned = 0L;
903 if (time((time_t *) NULL) > last_warned) {
904 DEBUG(0,("Too many open files, unable "
905 "to open more! smbd's max "
906 "open files = %d\n",
907 lp_max_open_files()));
908 last_warned = time((time_t *) NULL);
912 DBG_DEBUG("name %s, flags = 0%o mode = 0%o, fd = %d. %s\n",
913 smb_fname_str_dbg(smb_fname),
914 how.flags,
915 (int)how.mode,
916 fsp_get_pathref_fd(fsp),
917 nt_errstr(status));
918 return status;
921 DBG_DEBUG("name %s, flags = 0%o mode = 0%o, fd = %d\n",
922 smb_fname_str_dbg(smb_fname),
923 how.flags,
924 (int)how.mode,
925 fsp_get_pathref_fd(fsp));
927 return status;
930 /****************************************************************************
931 Close the file associated with a fsp.
932 ****************************************************************************/
934 NTSTATUS fd_close(files_struct *fsp)
936 NTSTATUS stat_status = NT_STATUS_OK;
937 int ret;
939 if (fsp == fsp->conn->cwd_fsp) {
940 return NT_STATUS_OK;
943 if (fsp->fsp_flags.fstat_before_close) {
945 * capture status, if failure
946 * continue close processing
947 * and return status
949 stat_status = vfs_stat_fsp(fsp);
952 if (fsp->dptr) {
953 dptr_CloseDir(fsp);
955 if (fsp_get_pathref_fd(fsp) == -1) {
957 * Either a directory where the dptr_CloseDir() already closed
958 * the fd or a stat open.
960 return NT_STATUS_OK;
962 if (fh_get_refcount(fsp->fh) > 1) {
963 return NT_STATUS_OK; /* Shared handle. Only close last reference. */
966 ret = SMB_VFS_CLOSE(fsp);
967 fsp_set_fd(fsp, -1);
968 if (ret == -1) {
969 return map_nt_error_from_unix(errno);
971 return stat_status;
974 /****************************************************************************
975 Change the ownership of a file to that of the parent directory.
976 Do this by fd if possible.
977 ****************************************************************************/
979 static void change_file_owner_to_parent_fsp(struct files_struct *parent_fsp,
980 struct files_struct *fsp)
982 int ret;
984 if (parent_fsp->fsp_name->st.st_ex_uid == fsp->fsp_name->st.st_ex_uid) {
985 /* Already this uid - no need to change. */
986 DBG_DEBUG("file %s is already owned by uid %u\n",
987 fsp_str_dbg(fsp),
988 (unsigned int)fsp->fsp_name->st.st_ex_uid);
989 return;
992 become_root();
993 ret = SMB_VFS_FCHOWN(fsp,
994 parent_fsp->fsp_name->st.st_ex_uid,
995 (gid_t)-1);
996 unbecome_root();
997 if (ret == -1) {
998 DBG_ERR("failed to fchown "
999 "file %s to parent directory uid %u. Error "
1000 "was %s\n",
1001 fsp_str_dbg(fsp),
1002 (unsigned int)parent_fsp->fsp_name->st.st_ex_uid,
1003 strerror(errno));
1004 } else {
1005 DBG_DEBUG("changed new file %s to "
1006 "parent directory uid %u.\n",
1007 fsp_str_dbg(fsp),
1008 (unsigned int)parent_fsp->fsp_name->st.st_ex_uid);
1009 /* Ensure the uid entry is updated. */
1010 fsp->fsp_name->st.st_ex_uid =
1011 parent_fsp->fsp_name->st.st_ex_uid;
1015 static NTSTATUS change_dir_owner_to_parent_fsp(struct files_struct *parent_fsp,
1016 struct files_struct *fsp)
1018 NTSTATUS status;
1019 int ret;
1021 if (parent_fsp->fsp_name->st.st_ex_uid == fsp->fsp_name->st.st_ex_uid) {
1022 /* Already this uid - no need to change. */
1023 DBG_DEBUG("directory %s is already owned by uid %u\n",
1024 fsp_str_dbg(fsp),
1025 (unsigned int)fsp->fsp_name->st.st_ex_uid);
1026 return NT_STATUS_OK;
1029 become_root();
1030 ret = SMB_VFS_FCHOWN(fsp,
1031 parent_fsp->fsp_name->st.st_ex_uid,
1032 (gid_t)-1);
1033 unbecome_root();
1034 if (ret == -1) {
1035 status = map_nt_error_from_unix(errno);
1036 DBG_ERR("failed to chown "
1037 "directory %s to parent directory uid %u. "
1038 "Error was %s\n",
1039 fsp_str_dbg(fsp),
1040 (unsigned int)parent_fsp->fsp_name->st.st_ex_uid,
1041 nt_errstr(status));
1042 return status;
1045 DBG_DEBUG("changed ownership of new "
1046 "directory %s to parent directory uid %u.\n",
1047 fsp_str_dbg(fsp),
1048 (unsigned int)parent_fsp->fsp_name->st.st_ex_uid);
1050 /* Ensure the uid entry is updated. */
1051 fsp->fsp_name->st.st_ex_uid = parent_fsp->fsp_name->st.st_ex_uid;
1053 return NT_STATUS_OK;
1056 /****************************************************************************
1057 Open a file - returning a guaranteed ATOMIC indication of if the
1058 file was created or not.
1059 ****************************************************************************/
1061 static NTSTATUS fd_open_atomic(struct files_struct *dirfsp,
1062 struct smb_filename *smb_fname,
1063 files_struct *fsp,
1064 const struct vfs_open_how *_how,
1065 bool *file_created)
1067 struct vfs_open_how how = *_how;
1068 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
1069 NTSTATUS retry_status;
1070 bool file_existed = VALID_STAT(smb_fname->st);
1072 if (!(how.flags & O_CREAT)) {
1074 * We're not creating the file, just pass through.
1076 status = fd_openat(dirfsp, smb_fname, fsp, &how);
1077 *file_created = false;
1078 return status;
1081 if (how.flags & O_EXCL) {
1083 * Fail if already exists, just pass through.
1085 status = fd_openat(dirfsp, smb_fname, fsp, &how);
1088 * Here we've opened with O_CREAT|O_EXCL. If that went
1089 * NT_STATUS_OK, we *know* we created this file.
1091 *file_created = NT_STATUS_IS_OK(status);
1093 return status;
1097 * Now it gets tricky. We have O_CREAT, but not O_EXCL.
1098 * To know absolutely if we created the file or not,
1099 * we can never call O_CREAT without O_EXCL. So if
1100 * we think the file existed, try without O_CREAT|O_EXCL.
1101 * If we think the file didn't exist, try with
1102 * O_CREAT|O_EXCL.
1104 * The big problem here is dangling symlinks. Opening
1105 * without O_NOFOLLOW means both bad symlink
1106 * and missing path return -1, ENOENT from open(). As POSIX
1107 * is pathname based it's not possible to tell
1108 * the difference between these two cases in a
1109 * non-racy way, so change to try only two attempts before
1110 * giving up.
1112 * We don't have this problem for the O_NOFOLLOW
1113 * case as it just returns NT_STATUS_OBJECT_PATH_NOT_FOUND
1114 * mapped from the ELOOP POSIX error.
1117 if (file_existed) {
1118 how.flags = _how->flags & ~(O_CREAT);
1119 retry_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
1120 } else {
1121 how.flags = _how->flags | O_EXCL;
1122 retry_status = NT_STATUS_OBJECT_NAME_COLLISION;
1125 status = fd_openat(dirfsp, smb_fname, fsp, &how);
1126 if (NT_STATUS_IS_OK(status)) {
1127 *file_created = !file_existed;
1128 return NT_STATUS_OK;
1130 if (NT_STATUS_EQUAL(status, retry_status)) {
1132 file_existed = !file_existed;
1134 DBG_DEBUG("File %s %s. Retry.\n",
1135 fsp_str_dbg(fsp),
1136 file_existed ? "existed" : "did not exist");
1138 if (file_existed) {
1139 how.flags = _how->flags & ~(O_CREAT);
1140 } else {
1141 how.flags = _how->flags | O_EXCL;
1144 status = fd_openat(dirfsp, smb_fname, fsp, &how);
1147 *file_created = (NT_STATUS_IS_OK(status) && !file_existed);
1148 return status;
1151 static NTSTATUS reopen_from_fsp(struct files_struct *dirfsp,
1152 struct smb_filename *smb_fname,
1153 struct files_struct *fsp,
1154 const struct vfs_open_how *how,
1155 bool *p_file_created)
1157 NTSTATUS status;
1158 int old_fd;
1160 if (fsp->fsp_flags.have_proc_fds &&
1161 ((old_fd = fsp_get_pathref_fd(fsp)) != -1)) {
1163 struct sys_proc_fd_path_buf buf;
1164 struct smb_filename proc_fname = {
1165 .base_name = sys_proc_fd_path(old_fd, &buf),
1167 mode_t mode = fsp->fsp_name->st.st_ex_mode;
1168 int new_fd;
1170 SMB_ASSERT(fsp->fsp_flags.is_pathref);
1172 if (S_ISLNK(mode)) {
1173 return NT_STATUS_STOPPED_ON_SYMLINK;
1175 if (!(S_ISREG(mode) || S_ISDIR(mode))) {
1176 return NT_STATUS_IO_REPARSE_TAG_NOT_HANDLED;
1179 fsp->fsp_flags.is_pathref = false;
1181 new_fd = SMB_VFS_OPENAT(fsp->conn,
1182 fsp->conn->cwd_fsp,
1183 &proc_fname,
1184 fsp,
1185 how);
1186 if (new_fd == -1) {
1187 #if defined(HAVE_FSTATFS) && defined(HAVE_LINUX_MAGIC_H)
1188 if (S_ISDIR(fsp->fsp_name->st.st_ex_mode) &&
1189 (errno == ENOENT)) {
1190 struct statfs sbuf = {};
1191 int ret = fstatfs(old_fd, &sbuf);
1192 if (ret == -1) {
1193 int saved_errno = errno;
1194 DBG_ERR("fstatfs failed: %s\n",
1195 strerror(errno));
1196 errno = saved_errno;
1197 } else if (sbuf.f_type == AUTOFS_SUPER_MAGIC) {
1199 * When reopening an as-yet
1200 * unmounted autofs mount
1201 * point we get ENOENT. We
1202 * have to retry pathbased.
1204 goto namebased_open;
1207 #endif
1208 status = map_nt_error_from_unix(errno);
1209 fd_close(fsp);
1210 return status;
1213 status = fd_close(fsp);
1214 if (!NT_STATUS_IS_OK(status)) {
1215 return status;
1218 fsp_set_fd(fsp, new_fd);
1219 return NT_STATUS_OK;
1222 namebased_open:
1224 * Close the existing pathref fd and set the fsp flag
1225 * is_pathref to false so we get a "normal" fd this time.
1227 status = fd_close(fsp);
1228 if (!NT_STATUS_IS_OK(status)) {
1229 return status;
1232 fsp->fsp_flags.is_pathref = false;
1234 status = fd_open_atomic(dirfsp, smb_fname, fsp, how, p_file_created);
1235 return status;
1238 /****************************************************************************
1239 Open a file.
1240 ****************************************************************************/
1242 static NTSTATUS open_file(
1243 struct smb_request *req,
1244 struct files_struct *dirfsp,
1245 struct smb_filename *smb_fname_atname,
1246 files_struct *fsp,
1247 const struct vfs_open_how *_how,
1248 uint32_t access_mask, /* client requested access mask. */
1249 uint32_t open_access_mask, /* what we're actually using in the open. */
1250 uint32_t private_flags,
1251 bool *p_file_created)
1253 connection_struct *conn = fsp->conn;
1254 struct smb_filename *smb_fname = fsp->fsp_name;
1255 struct vfs_open_how how = *_how;
1256 NTSTATUS status = NT_STATUS_OK;
1257 bool file_existed = VALID_STAT(fsp->fsp_name->st);
1258 const uint32_t need_fd_mask =
1259 FILE_READ_DATA |
1260 FILE_WRITE_DATA |
1261 FILE_APPEND_DATA |
1262 FILE_EXECUTE |
1263 SEC_FLAG_SYSTEM_SECURITY;
1264 bool creating = !file_existed && (how.flags & O_CREAT);
1265 bool open_fd = false;
1266 bool posix_open = (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN);
1269 * Catch early an attempt to open an existing
1270 * directory as a file.
1272 if (file_existed && S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
1273 return NT_STATUS_FILE_IS_A_DIRECTORY;
1277 * This little piece of insanity is inspired by the
1278 * fact that an NT client can open a file for O_RDONLY,
1279 * but set the create disposition to FILE_EXISTS_TRUNCATE.
1280 * If the client *can* write to the file, then it expects to
1281 * truncate the file, even though it is opening for readonly.
1282 * Quicken uses this stupid trick in backup file creation...
1283 * Thanks *greatly* to "David W. Chapman Jr." <dwcjr@inethouston.net>
1284 * for helping track this one down. It didn't bite us in 2.0.x
1285 * as we always opened files read-write in that release. JRA.
1288 if (((how.flags & O_ACCMODE) == O_RDONLY) && (how.flags & O_TRUNC)) {
1289 DBG_DEBUG("truncate requested on read-only open for file %s\n",
1290 smb_fname_str_dbg(smb_fname));
1291 how.flags = (how.flags & ~O_ACCMODE) | O_RDWR;
1294 /* Check permissions */
1297 * This code was changed after seeing a client open request
1298 * containing the open mode of (DENY_WRITE/read-only) with
1299 * the 'create if not exist' bit set. The previous code
1300 * would fail to open the file read only on a read-only share
1301 * as it was checking the flags parameter directly against O_RDONLY,
1302 * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
1303 * JRA.
1306 if (!CAN_WRITE(conn)) {
1307 /* It's a read-only share - fail if we wanted to write. */
1308 if ((how.flags & O_ACCMODE) != O_RDONLY ||
1309 (how.flags & O_TRUNC) || (how.flags & O_APPEND)) {
1310 DEBUG(3,("Permission denied opening %s\n",
1311 smb_fname_str_dbg(smb_fname)));
1312 return NT_STATUS_ACCESS_DENIED;
1315 * We don't want to write - but we must make sure that
1316 * O_CREAT doesn't create the file if we have write
1317 * access into the directory.
1319 how.flags &= ~(O_CREAT | O_EXCL);
1322 if ((open_access_mask & need_fd_mask) || creating ||
1323 (how.flags & O_TRUNC)) {
1324 open_fd = true;
1327 if (open_fd) {
1328 int ret;
1330 #if defined(O_NONBLOCK) && defined(S_ISFIFO)
1332 * We would block on opening a FIFO with no one else on the
1333 * other end. Do what we used to do and add O_NONBLOCK to the
1334 * open flags. JRA.
1337 if (file_existed && S_ISFIFO(smb_fname->st.st_ex_mode)) {
1338 how.flags |= O_NONBLOCK;
1340 #endif
1342 if (!posix_open) {
1343 const char *wild = smb_fname->base_name;
1345 * Don't open files with Microsoft wildcard characters.
1347 if (fsp_is_alternate_stream(fsp)) {
1349 * wildcard characters are allowed in stream
1350 * names only test the basefilename
1352 wild = fsp->base_fsp->fsp_name->base_name;
1355 if (ms_has_wild(wild)) {
1356 return NT_STATUS_OBJECT_NAME_INVALID;
1360 /* Can we access this file ? */
1361 if (!fsp_is_alternate_stream(fsp)) {
1362 /* Only do this check on non-stream open. */
1363 if (file_existed) {
1364 status = smbd_check_access_rights_fsp(
1365 dirfsp,
1366 fsp,
1367 false,
1368 open_access_mask);
1370 if (!NT_STATUS_IS_OK(status)) {
1371 DBG_DEBUG("smbd_check_access_rights_fsp"
1372 " on file %s returned %s\n",
1373 fsp_str_dbg(fsp),
1374 nt_errstr(status));
1377 if (!NT_STATUS_IS_OK(status) &&
1378 !NT_STATUS_EQUAL(status,
1379 NT_STATUS_OBJECT_NAME_NOT_FOUND))
1381 return status;
1384 if (NT_STATUS_EQUAL(status,
1385 NT_STATUS_OBJECT_NAME_NOT_FOUND))
1387 DEBUG(10, ("open_file: "
1388 "file %s vanished since we "
1389 "checked for existence.\n",
1390 smb_fname_str_dbg(smb_fname)));
1391 file_existed = false;
1392 SET_STAT_INVALID(fsp->fsp_name->st);
1396 if (!file_existed) {
1397 if (!(how.flags & O_CREAT)) {
1398 /* File didn't exist and no O_CREAT. */
1399 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1402 status = check_parent_access_fsp(
1403 dirfsp,
1404 SEC_DIR_ADD_FILE);
1405 if (!NT_STATUS_IS_OK(status)) {
1406 DBG_DEBUG("check_parent_access_fsp on "
1407 "directory %s for file %s "
1408 "returned %s\n",
1409 smb_fname_str_dbg(
1410 dirfsp->fsp_name),
1411 smb_fname_str_dbg(smb_fname),
1412 nt_errstr(status));
1413 return status;
1419 * Actually do the open - if O_TRUNC is needed handle it
1420 * below under the share mode lock.
1422 how.flags &= ~O_TRUNC;
1423 status = reopen_from_fsp(dirfsp,
1424 smb_fname_atname,
1425 fsp,
1426 &how,
1427 p_file_created);
1428 if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) {
1430 * Non-O_PATH reopen that hit a race
1431 * condition: Someone has put a symlink where
1432 * we used to have a file. Can't happen with
1433 * O_PATH and reopening from /proc/self/fd/ or
1434 * equivalent.
1436 status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
1438 if (!NT_STATUS_IS_OK(status)) {
1439 DBG_NOTICE("Error opening file %s (%s) (in_flags=%d) "
1440 "(flags=%d)\n",
1441 smb_fname_str_dbg(smb_fname),
1442 nt_errstr(status),
1443 _how->flags,
1444 how.flags);
1445 return status;
1448 if (how.flags & O_NONBLOCK) {
1450 * GPFS can return ETIMEDOUT for pread on
1451 * nonblocking file descriptors when files
1452 * migrated to tape need to be recalled. I
1453 * could imagine this happens elsewhere
1454 * too. With blocking file descriptors this
1455 * does not happen.
1457 ret = vfs_set_blocking(fsp, true);
1458 if (ret == -1) {
1459 status = map_nt_error_from_unix(errno);
1460 DBG_WARNING("Could not set fd to blocking: "
1461 "%s\n", strerror(errno));
1462 fd_close(fsp);
1463 return status;
1467 if (*p_file_created) {
1468 /* We created this file. */
1470 bool need_re_stat = false;
1471 /* Do all inheritance work after we've
1472 done a successful fstat call and filled
1473 in the stat struct in fsp->fsp_name. */
1475 /* Inherit the ACL if required */
1476 if (lp_inherit_permissions(SNUM(conn))) {
1477 inherit_access_posix_acl(conn,
1478 dirfsp,
1479 smb_fname,
1480 how.mode);
1481 need_re_stat = true;
1484 /* Change the owner if required. */
1485 if (lp_inherit_owner(SNUM(conn)) != INHERIT_OWNER_NO) {
1486 change_file_owner_to_parent_fsp(dirfsp, fsp);
1487 need_re_stat = true;
1490 if (need_re_stat) {
1491 status = vfs_stat_fsp(fsp);
1493 * If we have an fd, this stat should succeed.
1495 if (!NT_STATUS_IS_OK(status)) {
1496 DBG_ERR("Error doing fstat on open "
1497 "file %s (%s)\n",
1498 smb_fname_str_dbg(smb_fname),
1499 nt_errstr(status));
1500 fd_close(fsp);
1501 return status;
1505 notify_fname(conn, NOTIFY_ACTION_ADDED,
1506 FILE_NOTIFY_CHANGE_FILE_NAME,
1507 smb_fname->base_name);
1509 } else {
1510 if (!file_existed) {
1511 /* File must exist for a stat open. */
1512 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1515 if (S_ISLNK(smb_fname->st.st_ex_mode) &&
1516 !posix_open)
1519 * Don't allow stat opens on symlinks directly unless
1520 * it's a POSIX open. Match the return code from
1521 * openat_pathref_fsp().
1523 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1526 if (!fsp->fsp_flags.is_pathref) {
1528 * There is only one legit case where end up here:
1529 * openat_pathref_fsp() failed to open a symlink, so the
1530 * fsp was created by fsp_new() which doesn't set
1531 * is_pathref. Other than that, we should always have a
1532 * pathref fsp at this point. The subsequent checks
1533 * assert this.
1535 if (!(smb_fname->flags & SMB_FILENAME_POSIX_PATH)) {
1536 DBG_ERR("[%s] is not a POSIX pathname\n",
1537 smb_fname_str_dbg(smb_fname));
1538 return NT_STATUS_INTERNAL_ERROR;
1540 if (!S_ISLNK(smb_fname->st.st_ex_mode)) {
1541 DBG_ERR("[%s] is not a symlink\n",
1542 smb_fname_str_dbg(smb_fname));
1543 return NT_STATUS_INTERNAL_ERROR;
1545 if (fsp_get_pathref_fd(fsp) != -1) {
1546 DBG_ERR("fd for [%s] is not -1: fd [%d]\n",
1547 smb_fname_str_dbg(smb_fname),
1548 fsp_get_pathref_fd(fsp));
1549 return NT_STATUS_INTERNAL_ERROR;
1554 * Access to streams is checked by checking the basefile and
1555 * that has already been checked by check_base_file_access()
1556 * in create_file_unixpath().
1558 if (!fsp_is_alternate_stream(fsp)) {
1559 status = smbd_check_access_rights_fsp(dirfsp,
1560 fsp,
1561 false,
1562 open_access_mask);
1564 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) &&
1565 posix_open &&
1566 S_ISLNK(smb_fname->st.st_ex_mode)) {
1567 /* This is a POSIX stat open for delete
1568 * or rename on a symlink that points
1569 * nowhere. Allow. */
1570 DEBUG(10,("open_file: allowing POSIX "
1571 "open on bad symlink %s\n",
1572 smb_fname_str_dbg(smb_fname)));
1573 status = NT_STATUS_OK;
1576 if (!NT_STATUS_IS_OK(status)) {
1577 DBG_DEBUG("smbd_check_access_rights_fsp on file "
1578 "%s returned %s\n",
1579 fsp_str_dbg(fsp),
1580 nt_errstr(status));
1581 return status;
1586 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
1587 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
1588 fsp->file_pid = req ? req->smbpid : 0;
1589 fsp->fsp_flags.can_lock = true;
1590 fsp->fsp_flags.can_read = ((access_mask & FILE_READ_DATA) != 0);
1591 fsp->fsp_flags.can_write =
1592 CAN_WRITE(conn) &&
1593 ((access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) != 0);
1594 if (fsp->fsp_name->twrp != 0) {
1595 fsp->fsp_flags.can_write = false;
1597 fsp->print_file = NULL;
1598 fsp->fsp_flags.modified = false;
1599 fsp->sent_oplock_break = NO_BREAK_SENT;
1600 fsp->fsp_flags.is_directory = false;
1601 if (is_in_path(smb_fname->base_name,
1602 conn->aio_write_behind_list,
1603 posix_open ? true : conn->case_sensitive)) {
1604 fsp->fsp_flags.aio_write_behind = true;
1607 DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
1608 conn->session_info->unix_info->unix_name,
1609 smb_fname_str_dbg(smb_fname),
1610 BOOLSTR(fsp->fsp_flags.can_read),
1611 BOOLSTR(fsp->fsp_flags.can_write),
1612 conn->num_files_open));
1614 return NT_STATUS_OK;
1617 static bool mask_conflict(
1618 uint32_t new_access,
1619 uint32_t existing_access,
1620 uint32_t access_mask,
1621 uint32_t new_sharemode,
1622 uint32_t existing_sharemode,
1623 uint32_t sharemode_mask)
1625 bool want_access = (new_access & access_mask);
1626 bool allow_existing = (existing_sharemode & sharemode_mask);
1627 bool have_access = (existing_access & access_mask);
1628 bool allow_new = (new_sharemode & sharemode_mask);
1630 if (want_access && !allow_existing) {
1631 DBG_DEBUG("Access request 0x%"PRIx32"/0x%"PRIx32" conflicts "
1632 "with existing sharemode 0x%"PRIx32"/0x%"PRIx32"\n",
1633 new_access,
1634 access_mask,
1635 existing_sharemode,
1636 sharemode_mask);
1637 return true;
1639 if (have_access && !allow_new) {
1640 DBG_DEBUG("Sharemode request 0x%"PRIx32"/0x%"PRIx32" conflicts "
1641 "with existing access 0x%"PRIx32"/0x%"PRIx32"\n",
1642 new_sharemode,
1643 sharemode_mask,
1644 existing_access,
1645 access_mask);
1646 return true;
1648 return false;
1651 /****************************************************************************
1652 Check if we can open a file with a share mode.
1653 Returns True if conflict, False if not.
1654 ****************************************************************************/
1656 static const uint32_t conflicting_access =
1657 FILE_WRITE_DATA|
1658 FILE_APPEND_DATA|
1659 FILE_READ_DATA|
1660 FILE_EXECUTE|
1661 DELETE_ACCESS;
1663 static bool share_conflict(uint32_t e_access_mask,
1664 uint32_t e_share_access,
1665 uint32_t access_mask,
1666 uint32_t share_access)
1668 bool conflict;
1670 DBG_DEBUG("existing access_mask = 0x%"PRIx32", "
1671 "existing share access = 0x%"PRIx32", "
1672 "access_mask = 0x%"PRIx32", "
1673 "share_access = 0x%"PRIx32"\n",
1674 e_access_mask,
1675 e_share_access,
1676 access_mask,
1677 share_access);
1679 if ((e_access_mask & conflicting_access) == 0) {
1680 DBG_DEBUG("No conflict due to "
1681 "existing access_mask = 0x%"PRIx32"\n",
1682 e_access_mask);
1683 return false;
1685 if ((access_mask & conflicting_access) == 0) {
1686 DBG_DEBUG("No conflict due to access_mask = 0x%"PRIx32"\n",
1687 access_mask);
1688 return false;
1691 conflict = mask_conflict(
1692 access_mask, e_access_mask, FILE_WRITE_DATA | FILE_APPEND_DATA,
1693 share_access, e_share_access, FILE_SHARE_WRITE);
1694 conflict |= mask_conflict(
1695 access_mask, e_access_mask, FILE_READ_DATA | FILE_EXECUTE,
1696 share_access, e_share_access, FILE_SHARE_READ);
1697 conflict |= mask_conflict(
1698 access_mask, e_access_mask, DELETE_ACCESS,
1699 share_access, e_share_access, FILE_SHARE_DELETE);
1701 DBG_DEBUG("conflict=%s\n", conflict ? "true" : "false");
1702 return conflict;
1705 #if defined(DEVELOPER)
1707 struct validate_my_share_entries_state {
1708 struct smbd_server_connection *sconn;
1709 struct file_id fid;
1710 struct server_id self;
1713 static bool validate_my_share_entries_fn(
1714 struct share_mode_entry *e,
1715 bool *modified,
1716 void *private_data)
1718 struct validate_my_share_entries_state *state = private_data;
1719 files_struct *fsp;
1721 if (!server_id_equal(&state->self, &e->pid)) {
1722 return false;
1725 if (e->op_mid == 0) {
1726 /* INTERNAL_OPEN_ONLY */
1727 return false;
1730 fsp = file_find_dif(state->sconn, state->fid, e->share_file_id);
1731 if (!fsp) {
1732 DBG_ERR("PANIC : %s\n",
1733 share_mode_str(talloc_tos(), 0, &state->fid, e));
1734 smb_panic("validate_my_share_entries: Cannot match a "
1735 "share entry with an open file\n");
1738 if (((uint16_t)fsp->oplock_type) != e->op_type) {
1739 goto panic;
1742 return false;
1744 panic:
1746 char *str;
1747 DBG_ERR("validate_my_share_entries: PANIC : %s\n",
1748 share_mode_str(talloc_tos(), 0, &state->fid, e));
1749 str = talloc_asprintf(talloc_tos(),
1750 "validate_my_share_entries: "
1751 "file %s, oplock_type = 0x%x, op_type = 0x%x\n",
1752 fsp->fsp_name->base_name,
1753 (unsigned int)fsp->oplock_type,
1754 (unsigned int)e->op_type);
1755 smb_panic(str);
1758 return false;
1760 #endif
1763 * Allowed access mask for stat opens relevant to oplocks
1765 bool is_oplock_stat_open(uint32_t access_mask)
1767 const uint32_t stat_open_bits =
1768 (SYNCHRONIZE_ACCESS|
1769 FILE_READ_ATTRIBUTES|
1770 FILE_WRITE_ATTRIBUTES);
1772 return (((access_mask & stat_open_bits) != 0) &&
1773 ((access_mask & ~stat_open_bits) == 0));
1777 * Allowed access mask for stat opens relevant to leases
1779 bool is_lease_stat_open(uint32_t access_mask)
1781 const uint32_t stat_open_bits =
1782 (SYNCHRONIZE_ACCESS|
1783 FILE_READ_ATTRIBUTES|
1784 FILE_WRITE_ATTRIBUTES|
1785 READ_CONTROL_ACCESS);
1787 return (((access_mask & stat_open_bits) != 0) &&
1788 ((access_mask & ~stat_open_bits) == 0));
1791 struct has_delete_on_close_state {
1792 bool ret;
1795 static bool has_delete_on_close_fn(
1796 struct share_mode_entry *e,
1797 bool *modified,
1798 void *private_data)
1800 struct has_delete_on_close_state *state = private_data;
1801 state->ret = !share_entry_stale_pid(e);
1802 return state->ret;
1805 static bool has_delete_on_close(struct share_mode_lock *lck,
1806 uint32_t name_hash)
1808 struct has_delete_on_close_state state = { .ret = false };
1809 bool ok;
1811 if (!is_delete_on_close_set(lck, name_hash)) {
1812 return false;
1815 ok= share_mode_forall_entries(lck, has_delete_on_close_fn, &state);
1816 if (!ok) {
1817 DBG_DEBUG("share_mode_forall_entries failed\n");
1818 return false;
1820 return state.ret;
1823 static void share_mode_flags_restrict(
1824 struct share_mode_lock *lck,
1825 uint32_t access_mask,
1826 uint32_t share_mode,
1827 uint32_t lease_type)
1829 uint32_t existing_access_mask, existing_share_mode;
1830 uint32_t existing_lease_type;
1832 share_mode_flags_get(
1833 lck,
1834 &existing_access_mask,
1835 &existing_share_mode,
1836 &existing_lease_type);
1838 existing_access_mask |= access_mask;
1839 if (access_mask & conflicting_access) {
1840 existing_share_mode &= share_mode;
1842 existing_lease_type |= lease_type;
1844 share_mode_flags_set(
1845 lck,
1846 existing_access_mask,
1847 existing_share_mode,
1848 existing_lease_type,
1849 NULL);
1852 /****************************************************************************
1853 Deal with share modes
1854 Invariant: Share mode must be locked on entry and exit.
1855 Returns -1 on error, or number of share modes on success (may be zero).
1856 ****************************************************************************/
1858 struct open_mode_check_state {
1859 struct file_id fid;
1860 uint32_t access_mask;
1861 uint32_t share_access;
1862 uint32_t lease_type;
1865 static bool open_mode_check_fn(
1866 struct share_mode_entry *e,
1867 bool *modified,
1868 void *private_data)
1870 struct open_mode_check_state *state = private_data;
1871 bool disconnected, stale;
1872 uint32_t access_mask, share_access, lease_type;
1874 disconnected = server_id_is_disconnected(&e->pid);
1875 if (disconnected) {
1876 return false;
1879 access_mask = state->access_mask | e->access_mask;
1880 share_access = state->share_access;
1881 if (e->access_mask & conflicting_access) {
1882 share_access &= e->share_access;
1884 lease_type = state->lease_type | get_lease_type(e, state->fid);
1886 if ((access_mask == state->access_mask) &&
1887 (share_access == state->share_access) &&
1888 (lease_type == state->lease_type)) {
1889 return false;
1892 stale = share_entry_stale_pid(e);
1893 if (stale) {
1894 return false;
1897 state->access_mask = access_mask;
1898 state->share_access = share_access;
1899 state->lease_type = lease_type;
1901 return false;
1904 static NTSTATUS open_mode_check(connection_struct *conn,
1905 struct file_id fid,
1906 struct share_mode_lock *lck,
1907 uint32_t access_mask,
1908 uint32_t share_access)
1910 struct open_mode_check_state state;
1911 bool ok, conflict;
1912 bool modified = false;
1914 if (is_oplock_stat_open(access_mask)) {
1915 /* Stat open that doesn't trigger oplock breaks or share mode
1916 * checks... ! JRA. */
1917 return NT_STATUS_OK;
1921 * Check if the share modes will give us access.
1924 #if defined(DEVELOPER)
1926 struct validate_my_share_entries_state validate_state = {
1927 .sconn = conn->sconn,
1928 .fid = fid,
1929 .self = messaging_server_id(conn->sconn->msg_ctx),
1931 ok = share_mode_forall_entries(
1932 lck, validate_my_share_entries_fn, &validate_state);
1933 SMB_ASSERT(ok);
1935 #endif
1937 share_mode_flags_get(
1938 lck, &state.access_mask, &state.share_access, NULL);
1940 conflict = share_conflict(
1941 state.access_mask,
1942 state.share_access,
1943 access_mask,
1944 share_access);
1945 if (!conflict) {
1946 DBG_DEBUG("No conflict due to share_mode_flags access\n");
1947 return NT_STATUS_OK;
1950 state = (struct open_mode_check_state) {
1951 .fid = fid,
1952 .share_access = (FILE_SHARE_READ|
1953 FILE_SHARE_WRITE|
1954 FILE_SHARE_DELETE),
1958 * Walk the share mode array to recalculate d->flags
1961 ok = share_mode_forall_entries(lck, open_mode_check_fn, &state);
1962 if (!ok) {
1963 DBG_DEBUG("share_mode_forall_entries failed\n");
1964 return NT_STATUS_INTERNAL_ERROR;
1967 share_mode_flags_set(
1968 lck,
1969 state.access_mask,
1970 state.share_access,
1971 state.lease_type,
1972 &modified);
1973 if (!modified) {
1975 * We only end up here if we had a sharing violation
1976 * from d->flags and have recalculated it.
1978 return NT_STATUS_SHARING_VIOLATION;
1981 conflict = share_conflict(
1982 state.access_mask,
1983 state.share_access,
1984 access_mask,
1985 share_access);
1986 if (!conflict) {
1987 DBG_DEBUG("No conflict due to share_mode_flags access\n");
1988 return NT_STATUS_OK;
1991 return NT_STATUS_SHARING_VIOLATION;
1995 * Send a break message to the oplock holder and delay the open for
1996 * our client.
1999 NTSTATUS send_break_message(struct messaging_context *msg_ctx,
2000 const struct file_id *id,
2001 const struct share_mode_entry *exclusive,
2002 uint16_t break_to)
2004 struct oplock_break_message msg = {
2005 .id = *id,
2006 .share_file_id = exclusive->share_file_id,
2007 .break_to = break_to,
2009 enum ndr_err_code ndr_err;
2010 uint8_t msgbuf[33];
2011 DATA_BLOB blob = {.data = msgbuf, .length = sizeof(msgbuf)};
2012 NTSTATUS status;
2014 if (DEBUGLVL(10)) {
2015 struct server_id_buf buf;
2016 DBG_DEBUG("Sending break message to %s\n",
2017 server_id_str_buf(exclusive->pid, &buf));
2018 NDR_PRINT_DEBUG(oplock_break_message, &msg);
2021 ndr_err = ndr_push_struct_into_fixed_blob(
2022 &blob,
2023 &msg,
2024 (ndr_push_flags_fn_t)ndr_push_oplock_break_message);
2025 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2026 DBG_WARNING("ndr_push_oplock_break_message failed: %s\n",
2027 ndr_errstr(ndr_err));
2028 return ndr_map_error2ntstatus(ndr_err);
2031 status = messaging_send(msg_ctx,
2032 exclusive->pid,
2033 MSG_SMB_BREAK_REQUEST,
2034 &blob);
2035 if (!NT_STATUS_IS_OK(status)) {
2036 DEBUG(3, ("Could not send oplock break message: %s\n",
2037 nt_errstr(status)));
2040 return status;
2043 struct validate_oplock_types_state {
2044 bool valid;
2045 bool batch;
2046 bool ex_or_batch;
2047 bool level2;
2048 bool no_oplock;
2049 uint32_t num_non_stat_opens;
2052 static bool validate_oplock_types_fn(
2053 struct share_mode_entry *e,
2054 bool *modified,
2055 void *private_data)
2057 struct validate_oplock_types_state *state = private_data;
2059 if (e->op_mid == 0) {
2060 /* INTERNAL_OPEN_ONLY */
2061 return false;
2064 if (e->op_type == NO_OPLOCK && is_oplock_stat_open(e->access_mask)) {
2066 * We ignore stat opens in the table - they always
2067 * have NO_OPLOCK and never get or cause breaks. JRA.
2069 return false;
2072 state->num_non_stat_opens += 1;
2074 if (BATCH_OPLOCK_TYPE(e->op_type)) {
2075 /* batch - can only be one. */
2076 if (share_entry_stale_pid(e)) {
2077 DBG_DEBUG("Found stale batch oplock\n");
2078 return false;
2080 if (state->ex_or_batch ||
2081 state->batch ||
2082 state->level2 ||
2083 state->no_oplock) {
2084 DBG_ERR("Bad batch oplock entry\n");
2085 state->valid = false;
2086 return true;
2088 state->batch = true;
2091 if (EXCLUSIVE_OPLOCK_TYPE(e->op_type)) {
2092 if (share_entry_stale_pid(e)) {
2093 DBG_DEBUG("Found stale duplicate oplock\n");
2094 return false;
2096 /* Exclusive or batch - can only be one. */
2097 if (state->ex_or_batch ||
2098 state->level2 ||
2099 state->no_oplock) {
2100 DBG_ERR("Bad exclusive or batch oplock entry\n");
2101 state->valid = false;
2102 return true;
2104 state->ex_or_batch = true;
2107 if (LEVEL_II_OPLOCK_TYPE(e->op_type)) {
2108 if (state->batch || state->ex_or_batch) {
2109 if (share_entry_stale_pid(e)) {
2110 DBG_DEBUG("Found stale LevelII oplock\n");
2111 return false;
2113 DBG_DEBUG("Bad levelII oplock entry\n");
2114 state->valid = false;
2115 return true;
2117 state->level2 = true;
2120 if (e->op_type == NO_OPLOCK) {
2121 if (state->batch || state->ex_or_batch) {
2122 if (share_entry_stale_pid(e)) {
2123 DBG_DEBUG("Found stale NO_OPLOCK entry\n");
2124 return false;
2126 DBG_ERR("Bad no oplock entry\n");
2127 state->valid = false;
2128 return true;
2130 state->no_oplock = true;
2133 return false;
2137 * Do internal consistency checks on the share mode for a file.
2140 static bool validate_oplock_types(struct share_mode_lock *lck)
2142 struct validate_oplock_types_state state = { .valid = true };
2143 static bool skip_validation;
2144 bool validate;
2145 bool ok;
2147 if (skip_validation) {
2148 return true;
2151 validate = lp_parm_bool(-1, "smbd", "validate_oplock_types", false);
2152 if (!validate) {
2153 DBG_DEBUG("smbd:validate_oplock_types not set to yes\n");
2154 skip_validation = true;
2155 return true;
2158 ok = share_mode_forall_entries(lck, validate_oplock_types_fn, &state);
2159 if (!ok) {
2160 DBG_DEBUG("share_mode_forall_entries failed\n");
2161 return false;
2163 if (!state.valid) {
2164 DBG_DEBUG("Got invalid oplock configuration\n");
2165 return false;
2168 if ((state.batch || state.ex_or_batch) &&
2169 (state.num_non_stat_opens != 1)) {
2170 DBG_WARNING("got batch (%d) or ex (%d) non-exclusively "
2171 "(%"PRIu32")\n",
2172 (int)state.batch,
2173 (int)state.ex_or_batch,
2174 state.num_non_stat_opens);
2175 return false;
2178 return true;
2181 static bool is_same_lease(const files_struct *fsp,
2182 const struct share_mode_entry *e,
2183 const struct smb2_lease *lease)
2185 if (e->op_type != LEASE_OPLOCK) {
2186 return false;
2188 if (lease == NULL) {
2189 return false;
2192 return smb2_lease_equal(fsp_client_guid(fsp),
2193 &lease->lease_key,
2194 &e->client_guid,
2195 &e->lease_key);
2198 static bool file_has_brlocks(files_struct *fsp)
2200 struct byte_range_lock *br_lck;
2202 br_lck = brl_get_locks_readonly(fsp);
2203 if (!br_lck)
2204 return false;
2206 return (brl_num_locks(br_lck) > 0);
2209 struct fsp_lease *find_fsp_lease(struct files_struct *new_fsp,
2210 const struct smb2_lease_key *key,
2211 uint32_t current_state,
2212 uint16_t lease_version,
2213 uint16_t lease_epoch)
2215 struct files_struct *fsp;
2218 * TODO: Measure how expensive this loop is with thousands of open
2219 * handles...
2222 for (fsp = file_find_di_first(new_fsp->conn->sconn, new_fsp->file_id, true);
2223 fsp != NULL;
2224 fsp = file_find_di_next(fsp, true)) {
2226 if (fsp == new_fsp) {
2227 continue;
2229 if (fsp->oplock_type != LEASE_OPLOCK) {
2230 continue;
2232 if (smb2_lease_key_equal(&fsp->lease->lease.lease_key, key)) {
2233 fsp->lease->ref_count += 1;
2234 return fsp->lease;
2238 /* Not found - must be leased in another smbd. */
2239 new_fsp->lease = talloc_zero(new_fsp->conn->sconn, struct fsp_lease);
2240 if (new_fsp->lease == NULL) {
2241 return NULL;
2243 new_fsp->lease->ref_count = 1;
2244 new_fsp->lease->sconn = new_fsp->conn->sconn;
2245 new_fsp->lease->lease.lease_key = *key;
2246 new_fsp->lease->lease.lease_state = current_state;
2248 * We internally treat all leases as V2 and update
2249 * the epoch, but when sending breaks it matters if
2250 * the requesting lease was v1 or v2.
2252 new_fsp->lease->lease.lease_version = lease_version;
2253 new_fsp->lease->lease.lease_epoch = lease_epoch;
2254 return new_fsp->lease;
2257 static NTSTATUS try_lease_upgrade(struct files_struct *fsp,
2258 struct share_mode_lock *lck,
2259 const struct GUID *client_guid,
2260 const struct smb2_lease *lease,
2261 uint32_t granted)
2263 bool do_upgrade;
2264 uint32_t current_state, breaking_to_requested, breaking_to_required;
2265 bool breaking;
2266 uint16_t lease_version, epoch;
2267 uint32_t existing, requested;
2268 NTSTATUS status;
2270 status = leases_db_get(
2271 client_guid,
2272 &lease->lease_key,
2273 &fsp->file_id,
2274 &current_state,
2275 &breaking,
2276 &breaking_to_requested,
2277 &breaking_to_required,
2278 &lease_version,
2279 &epoch);
2280 if (!NT_STATUS_IS_OK(status)) {
2281 return status;
2284 fsp->lease = find_fsp_lease(
2285 fsp,
2286 &lease->lease_key,
2287 current_state,
2288 lease_version,
2289 epoch);
2290 if (fsp->lease == NULL) {
2291 DEBUG(1, ("Did not find existing lease for file %s\n",
2292 fsp_str_dbg(fsp)));
2293 return NT_STATUS_NO_MEMORY;
2297 * Upgrade only if the requested lease is a strict upgrade.
2299 existing = current_state;
2300 requested = lease->lease_state;
2303 * Tricky: This test makes sure that "requested" is a
2304 * strict bitwise superset of "existing".
2306 do_upgrade = ((existing & requested) == existing);
2309 * Upgrade only if there's a change.
2311 do_upgrade &= (granted != existing);
2314 * Upgrade only if other leases don't prevent what was asked
2315 * for.
2317 do_upgrade &= (granted == requested);
2320 * only upgrade if we are not in breaking state
2322 do_upgrade &= !breaking;
2324 DEBUG(10, ("existing=%"PRIu32", requested=%"PRIu32", "
2325 "granted=%"PRIu32", do_upgrade=%d\n",
2326 existing, requested, granted, (int)do_upgrade));
2328 if (do_upgrade) {
2329 NTSTATUS set_status;
2331 current_state = granted;
2332 epoch += 1;
2334 set_status = leases_db_set(
2335 client_guid,
2336 &lease->lease_key,
2337 current_state,
2338 breaking,
2339 breaking_to_requested,
2340 breaking_to_required,
2341 lease_version,
2342 epoch);
2344 if (!NT_STATUS_IS_OK(set_status)) {
2345 DBG_DEBUG("leases_db_set failed: %s\n",
2346 nt_errstr(set_status));
2347 return set_status;
2351 fsp_lease_update(fsp);
2353 return NT_STATUS_OK;
2356 static NTSTATUS grant_new_fsp_lease(struct files_struct *fsp,
2357 struct share_mode_lock *lck,
2358 const struct GUID *client_guid,
2359 const struct smb2_lease *lease,
2360 uint32_t granted)
2362 NTSTATUS status;
2364 fsp->lease = talloc_zero(fsp->conn->sconn, struct fsp_lease);
2365 if (fsp->lease == NULL) {
2366 return NT_STATUS_INSUFFICIENT_RESOURCES;
2368 fsp->lease->ref_count = 1;
2369 fsp->lease->sconn = fsp->conn->sconn;
2370 fsp->lease->lease.lease_version = lease->lease_version;
2371 fsp->lease->lease.lease_key = lease->lease_key;
2372 fsp->lease->lease.lease_state = granted;
2373 fsp->lease->lease.lease_epoch = lease->lease_epoch + 1;
2375 status = leases_db_add(client_guid,
2376 &lease->lease_key,
2377 &fsp->file_id,
2378 fsp->lease->lease.lease_state,
2379 fsp->lease->lease.lease_version,
2380 fsp->lease->lease.lease_epoch,
2381 fsp->conn->connectpath,
2382 fsp->fsp_name->base_name,
2383 fsp->fsp_name->stream_name);
2384 if (!NT_STATUS_IS_OK(status)) {
2385 DEBUG(10, ("%s: leases_db_add failed: %s\n", __func__,
2386 nt_errstr(status)));
2387 TALLOC_FREE(fsp->lease);
2388 return NT_STATUS_INSUFFICIENT_RESOURCES;
2392 * We used to set lck->data->modified=true here without
2393 * actually modifying lck->data, triggering a needless
2394 * writeback of lck->data.
2396 * Apart from that writeback, setting modified=true has the
2397 * effect of triggering all waiters for this file to
2398 * retry. This only makes sense if any blocking condition
2399 * (i.e. waiting for a lease to be downgraded or removed) is
2400 * gone. This routine here only adds a lease, so it will never
2401 * free up resources that blocked waiters can now claim. So
2402 * that second effect also does not matter in this
2403 * routine. Thus setting lck->data->modified=true does not
2404 * need to be done here.
2407 return NT_STATUS_OK;
2410 static NTSTATUS grant_fsp_lease(struct files_struct *fsp,
2411 struct share_mode_lock *lck,
2412 const struct smb2_lease *lease,
2413 uint32_t granted)
2415 const struct GUID *client_guid = fsp_client_guid(fsp);
2416 NTSTATUS status;
2418 status = try_lease_upgrade(fsp, lck, client_guid, lease, granted);
2420 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
2421 status = grant_new_fsp_lease(
2422 fsp, lck, client_guid, lease, granted);
2425 return status;
2428 static int map_lease_type_to_oplock(uint32_t lease_type)
2430 int result = NO_OPLOCK;
2432 switch (lease_type) {
2433 case SMB2_LEASE_READ|SMB2_LEASE_WRITE|SMB2_LEASE_HANDLE:
2434 result = BATCH_OPLOCK|EXCLUSIVE_OPLOCK;
2435 break;
2436 case SMB2_LEASE_READ|SMB2_LEASE_WRITE:
2437 result = EXCLUSIVE_OPLOCK;
2438 break;
2439 case SMB2_LEASE_READ|SMB2_LEASE_HANDLE:
2440 case SMB2_LEASE_READ:
2441 result = LEVEL_II_OPLOCK;
2442 break;
2445 return result;
2448 struct delay_for_oplock_state {
2449 struct files_struct *fsp;
2450 const struct smb2_lease *lease;
2451 bool will_overwrite;
2452 uint32_t delay_mask;
2453 bool first_open_attempt;
2454 bool got_handle_lease;
2455 bool got_oplock;
2456 bool have_other_lease;
2457 uint32_t total_lease_types;
2458 bool delay;
2461 static bool delay_for_oplock_fn(
2462 struct share_mode_entry *e,
2463 bool *modified,
2464 void *private_data)
2466 struct delay_for_oplock_state *state = private_data;
2467 struct files_struct *fsp = state->fsp;
2468 const struct smb2_lease *lease = state->lease;
2469 bool e_is_lease = (e->op_type == LEASE_OPLOCK);
2470 uint32_t e_lease_type = SMB2_LEASE_NONE;
2471 uint32_t break_to;
2472 bool lease_is_breaking = false;
2474 if (e_is_lease) {
2475 NTSTATUS status;
2477 if (lease != NULL) {
2478 bool our_lease = is_same_lease(fsp, e, lease);
2479 if (our_lease) {
2480 DBG_DEBUG("Ignoring our own lease\n");
2481 return false;
2485 status = leases_db_get(
2486 &e->client_guid,
2487 &e->lease_key,
2488 &fsp->file_id,
2489 &e_lease_type, /* current_state */
2490 &lease_is_breaking,
2491 NULL, /* breaking_to_requested */
2492 NULL, /* breaking_to_required */
2493 NULL, /* lease_version */
2494 NULL); /* epoch */
2497 * leases_db_get() can return NT_STATUS_NOT_FOUND
2498 * if the share_mode_entry e is stale and the
2499 * lease record was already removed. In this case return
2500 * false so the traverse continues.
2503 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND) &&
2504 share_entry_stale_pid(e))
2506 struct GUID_txt_buf guid_strbuf;
2507 struct file_id_buf file_id_strbuf;
2508 DBG_DEBUG("leases_db_get for client_guid [%s] "
2509 "lease_key [%"PRIu64"/%"PRIu64"] "
2510 "file_id [%s] failed for stale "
2511 "share_mode_entry\n",
2512 GUID_buf_string(&e->client_guid, &guid_strbuf),
2513 e->lease_key.data[0],
2514 e->lease_key.data[1],
2515 file_id_str_buf(fsp->file_id, &file_id_strbuf));
2516 return false;
2518 if (!NT_STATUS_IS_OK(status)) {
2519 struct GUID_txt_buf guid_strbuf;
2520 struct file_id_buf file_id_strbuf;
2521 DBG_ERR("leases_db_get for client_guid [%s] "
2522 "lease_key [%"PRIu64"/%"PRIu64"] "
2523 "file_id [%s] failed: %s\n",
2524 GUID_buf_string(&e->client_guid, &guid_strbuf),
2525 e->lease_key.data[0],
2526 e->lease_key.data[1],
2527 file_id_str_buf(fsp->file_id, &file_id_strbuf),
2528 nt_errstr(status));
2529 smb_panic("leases_db_get() failed");
2531 } else {
2532 e_lease_type = get_lease_type(e, fsp->file_id);
2535 if (((e_lease_type & ~state->total_lease_types) != 0) &&
2536 !share_entry_stale_pid(e))
2538 state->total_lease_types |= e_lease_type;
2541 if (!state->got_handle_lease &&
2542 ((e_lease_type & SMB2_LEASE_HANDLE) != 0) &&
2543 !share_entry_stale_pid(e)) {
2544 state->got_handle_lease = true;
2547 if (!state->got_oplock &&
2548 (e->op_type != LEASE_OPLOCK) &&
2549 !share_entry_stale_pid(e)) {
2550 state->got_oplock = true;
2553 if (!state->have_other_lease &&
2554 !is_same_lease(fsp, e, lease) &&
2555 !share_entry_stale_pid(e)) {
2556 state->have_other_lease = true;
2559 if (e_is_lease && is_lease_stat_open(fsp->access_mask)) {
2560 return false;
2563 break_to = e_lease_type & ~state->delay_mask;
2565 if (state->will_overwrite) {
2566 break_to &= ~(SMB2_LEASE_HANDLE|SMB2_LEASE_READ);
2569 DBG_DEBUG("e_lease_type %u, will_overwrite: %u\n",
2570 (unsigned)e_lease_type,
2571 (unsigned)state->will_overwrite);
2573 if ((e_lease_type & ~break_to) == 0) {
2574 if (lease_is_breaking) {
2575 state->delay = true;
2577 return false;
2580 if (share_entry_stale_pid(e)) {
2581 return false;
2584 if (state->will_overwrite) {
2586 * If we break anyway break to NONE directly.
2587 * Otherwise vfs_set_filelen() will trigger the
2588 * break.
2590 break_to &= ~(SMB2_LEASE_READ|SMB2_LEASE_WRITE);
2593 if (!e_is_lease) {
2595 * Oplocks only support breaking to R or NONE.
2597 break_to &= ~(SMB2_LEASE_HANDLE|SMB2_LEASE_WRITE);
2600 DBG_DEBUG("breaking from %d to %d\n",
2601 (int)e_lease_type,
2602 (int)break_to);
2603 send_break_message(
2604 fsp->conn->sconn->msg_ctx, &fsp->file_id, e, break_to);
2605 if (e_lease_type & state->delay_mask) {
2606 state->delay = true;
2608 if (lease_is_breaking && !state->first_open_attempt) {
2609 state->delay = true;
2612 return false;
2615 static NTSTATUS delay_for_oplock(files_struct *fsp,
2616 int oplock_request,
2617 const struct smb2_lease *lease,
2618 struct share_mode_lock *lck,
2619 bool have_sharing_violation,
2620 uint32_t create_disposition,
2621 bool first_open_attempt,
2622 int *poplock_type,
2623 uint32_t *pgranted)
2625 struct delay_for_oplock_state state = {
2626 .fsp = fsp,
2627 .lease = lease,
2628 .first_open_attempt = first_open_attempt,
2630 uint32_t requested;
2631 uint32_t granted;
2632 int oplock_type;
2633 bool ok;
2635 *poplock_type = NO_OPLOCK;
2636 *pgranted = 0;
2638 if (fsp->fsp_flags.is_directory) {
2640 * No directory leases yet
2642 SMB_ASSERT(oplock_request == NO_OPLOCK);
2643 if (have_sharing_violation) {
2644 return NT_STATUS_SHARING_VIOLATION;
2646 return NT_STATUS_OK;
2649 if (oplock_request == LEASE_OPLOCK) {
2650 if (lease == NULL) {
2652 * The SMB2 layer should have checked this
2654 return NT_STATUS_INTERNAL_ERROR;
2657 requested = lease->lease_state;
2658 } else {
2659 requested = map_oplock_to_lease_type(
2660 oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK);
2663 share_mode_flags_get(lck, NULL, NULL, &state.total_lease_types);
2665 if (is_oplock_stat_open(fsp->access_mask)) {
2666 goto grant;
2669 state.delay_mask = have_sharing_violation ?
2670 SMB2_LEASE_HANDLE : SMB2_LEASE_WRITE;
2672 switch (create_disposition) {
2673 case FILE_SUPERSEDE:
2674 case FILE_OVERWRITE:
2675 case FILE_OVERWRITE_IF:
2676 state.will_overwrite = true;
2677 break;
2678 default:
2679 state.will_overwrite = false;
2680 break;
2683 state.total_lease_types = SMB2_LEASE_NONE;
2684 ok = share_mode_forall_entries(lck, delay_for_oplock_fn, &state);
2685 if (!ok) {
2686 return NT_STATUS_INTERNAL_ERROR;
2689 if (state.delay) {
2690 return NT_STATUS_RETRY;
2693 grant:
2694 if (have_sharing_violation) {
2695 return NT_STATUS_SHARING_VIOLATION;
2698 granted = requested;
2700 if (oplock_request == LEASE_OPLOCK) {
2701 if (lp_kernel_oplocks(SNUM(fsp->conn))) {
2702 DEBUG(10, ("No lease granted because kernel oplocks are enabled\n"));
2703 granted = SMB2_LEASE_NONE;
2705 if ((granted & (SMB2_LEASE_READ|SMB2_LEASE_WRITE)) == 0) {
2706 DEBUG(10, ("No read or write lease requested\n"));
2707 granted = SMB2_LEASE_NONE;
2709 if (granted == SMB2_LEASE_WRITE) {
2710 DEBUG(10, ("pure write lease requested\n"));
2711 granted = SMB2_LEASE_NONE;
2713 if (granted == (SMB2_LEASE_WRITE|SMB2_LEASE_HANDLE)) {
2714 DEBUG(10, ("write and handle lease requested\n"));
2715 granted = SMB2_LEASE_NONE;
2719 if (lp_locking(fsp->conn->params) && file_has_brlocks(fsp)) {
2720 DBG_DEBUG("file %s has byte range locks\n",
2721 fsp_str_dbg(fsp));
2722 granted &= ~SMB2_LEASE_READ;
2725 if (state.have_other_lease) {
2727 * Can grant only one writer
2729 granted &= ~SMB2_LEASE_WRITE;
2732 if ((granted & SMB2_LEASE_READ) && !(granted & SMB2_LEASE_WRITE)) {
2733 bool allow_level2 =
2734 (global_client_caps & CAP_LEVEL_II_OPLOCKS) &&
2735 lp_level2_oplocks(SNUM(fsp->conn));
2737 if (!allow_level2) {
2738 granted = SMB2_LEASE_NONE;
2742 if (oplock_request == LEASE_OPLOCK) {
2743 if (state.got_oplock) {
2744 granted &= ~SMB2_LEASE_HANDLE;
2747 oplock_type = LEASE_OPLOCK;
2748 } else {
2749 if (state.got_handle_lease) {
2750 granted = SMB2_LEASE_NONE;
2754 * Reflect possible downgrades from:
2755 * - map_lease_type_to_oplock() => "RH" to just LEVEL_II
2757 oplock_type = map_lease_type_to_oplock(granted);
2758 granted = map_oplock_to_lease_type(oplock_type);
2761 state.total_lease_types |= granted;
2764 uint32_t acc, sh, ls;
2765 share_mode_flags_get(lck, &acc, &sh, &ls);
2766 ls = state.total_lease_types;
2767 share_mode_flags_set(lck, acc, sh, ls, NULL);
2770 DBG_DEBUG("oplock type 0x%x granted (%s%s%s)(0x%x), on file %s, "
2771 "requested 0x%x (%s%s%s)(0x%x) => total (%s%s%s)(0x%x)\n",
2772 fsp->oplock_type,
2773 granted & SMB2_LEASE_READ ? "R":"",
2774 granted & SMB2_LEASE_WRITE ? "W":"",
2775 granted & SMB2_LEASE_HANDLE ? "H":"",
2776 granted,
2777 fsp_str_dbg(fsp),
2778 oplock_request,
2779 requested & SMB2_LEASE_READ ? "R":"",
2780 requested & SMB2_LEASE_WRITE ? "W":"",
2781 requested & SMB2_LEASE_HANDLE ? "H":"",
2782 requested,
2783 state.total_lease_types & SMB2_LEASE_READ ? "R":"",
2784 state.total_lease_types & SMB2_LEASE_WRITE ? "W":"",
2785 state.total_lease_types & SMB2_LEASE_HANDLE ? "H":"",
2786 state.total_lease_types);
2788 *poplock_type = oplock_type;
2789 *pgranted = granted;
2790 return NT_STATUS_OK;
2793 static NTSTATUS handle_share_mode_lease(
2794 files_struct *fsp,
2795 struct share_mode_lock *lck,
2796 uint32_t create_disposition,
2797 uint32_t access_mask,
2798 uint32_t share_access,
2799 int oplock_request,
2800 const struct smb2_lease *lease,
2801 bool first_open_attempt,
2802 int *poplock_type,
2803 uint32_t *pgranted)
2805 bool sharing_violation = false;
2806 NTSTATUS status;
2808 *poplock_type = NO_OPLOCK;
2809 *pgranted = 0;
2811 status = open_mode_check(
2812 fsp->conn, fsp->file_id, lck, access_mask, share_access);
2813 if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
2814 sharing_violation = true;
2815 status = NT_STATUS_OK; /* handled later */
2818 if (!NT_STATUS_IS_OK(status)) {
2819 return status;
2822 if (oplock_request == INTERNAL_OPEN_ONLY) {
2823 if (sharing_violation) {
2824 DBG_DEBUG("Sharing violation for internal open\n");
2825 return NT_STATUS_SHARING_VIOLATION;
2829 * Internal opens never do oplocks or leases. We don't
2830 * need to go through delay_for_oplock().
2832 return NT_STATUS_OK;
2835 status = delay_for_oplock(
2836 fsp,
2837 oplock_request,
2838 lease,
2839 lck,
2840 sharing_violation,
2841 create_disposition,
2842 first_open_attempt,
2843 poplock_type,
2844 pgranted);
2845 if (!NT_STATUS_IS_OK(status)) {
2846 return status;
2849 return NT_STATUS_OK;
2852 static bool request_timed_out(struct smb_request *req, struct timeval timeout)
2854 struct timeval end_time = timeval_sum(&req->request_time, &timeout);
2855 return timeval_expired(&end_time);
2858 struct defer_open_state {
2859 struct smbXsrv_connection *xconn;
2860 uint64_t mid;
2863 static void defer_open_done(struct tevent_req *req);
2866 * Defer an open and watch a locking.tdb record
2868 * This defers an open that gets rescheduled once the locking.tdb record watch
2869 * is triggered by a change to the record.
2871 * It is used to defer opens that triggered an oplock break and for the SMB1
2872 * sharing violation delay.
2874 static void defer_open(struct share_mode_lock *lck,
2875 struct timeval timeout,
2876 struct smb_request *req,
2877 struct file_id id)
2879 struct deferred_open_record *open_rec = NULL;
2880 struct timeval abs_timeout;
2881 struct defer_open_state *watch_state;
2882 struct tevent_req *watch_req;
2883 struct timeval_buf tvbuf1, tvbuf2;
2884 struct file_id_buf fbuf;
2885 bool ok;
2887 abs_timeout = timeval_sum(&req->request_time, &timeout);
2889 DBG_DEBUG("request time [%s] timeout [%s] mid [%" PRIu64 "] "
2890 "file_id [%s]\n",
2891 timeval_str_buf(&req->request_time, false, true, &tvbuf1),
2892 timeval_str_buf(&abs_timeout, false, true, &tvbuf2),
2893 req->mid,
2894 file_id_str_buf(id, &fbuf));
2896 open_rec = talloc_zero(NULL, struct deferred_open_record);
2897 if (open_rec == NULL) {
2898 TALLOC_FREE(lck);
2899 exit_server("talloc failed");
2902 watch_state = talloc(open_rec, struct defer_open_state);
2903 if (watch_state == NULL) {
2904 exit_server("talloc failed");
2906 watch_state->xconn = req->xconn;
2907 watch_state->mid = req->mid;
2909 DBG_DEBUG("deferring mid %" PRIu64 "\n", req->mid);
2911 watch_req = share_mode_watch_send(
2912 watch_state,
2913 req->sconn->ev_ctx,
2914 lck,
2915 (struct server_id){0});
2916 if (watch_req == NULL) {
2917 exit_server("Could not watch share mode record");
2919 tevent_req_set_callback(watch_req, defer_open_done, watch_state);
2921 ok = tevent_req_set_endtime(watch_req, req->sconn->ev_ctx, abs_timeout);
2922 if (!ok) {
2923 exit_server("tevent_req_set_endtime failed");
2926 ok = push_deferred_open_message_smb(req, timeout, id, open_rec);
2927 if (!ok) {
2928 TALLOC_FREE(lck);
2929 exit_server("push_deferred_open_message_smb failed");
2933 static void defer_open_done(struct tevent_req *req)
2935 struct defer_open_state *state = tevent_req_callback_data(
2936 req, struct defer_open_state);
2937 NTSTATUS status;
2938 bool ret;
2940 status = share_mode_watch_recv(req, NULL, NULL);
2941 TALLOC_FREE(req);
2942 if (!NT_STATUS_IS_OK(status)) {
2943 DEBUG(5, ("dbwrap_watched_watch_recv returned %s\n",
2944 nt_errstr(status)));
2946 * Even if it failed, retry anyway. TODO: We need a way to
2947 * tell a re-scheduled open about that error.
2951 DEBUG(10, ("scheduling mid %llu\n", (unsigned long long)state->mid));
2953 ret = schedule_deferred_open_message_smb(state->xconn, state->mid);
2954 SMB_ASSERT(ret);
2955 TALLOC_FREE(state);
2959 * Actually attempt the kernel oplock polling open.
2962 static void poll_open_fn(struct tevent_context *ev,
2963 struct tevent_timer *te,
2964 struct timeval current_time,
2965 void *private_data)
2967 struct deferred_open_record *open_rec = talloc_get_type_abort(
2968 private_data, struct deferred_open_record);
2969 bool ok;
2971 TALLOC_FREE(open_rec->watch_req);
2973 ok = schedule_deferred_open_message_smb(
2974 open_rec->xconn, open_rec->mid);
2975 if (!ok) {
2976 exit_server("schedule_deferred_open_message_smb failed");
2978 DBG_DEBUG("timer fired. Retrying open !\n");
2981 static void poll_open_done(struct tevent_req *subreq);
2983 struct poll_open_setup_watcher_state {
2984 TALLOC_CTX *mem_ctx;
2985 struct tevent_context *ev_ctx;
2986 struct tevent_req *watch_req;
2989 static void poll_open_setup_watcher_fn(struct share_mode_lock *lck,
2990 void *private_data)
2992 struct poll_open_setup_watcher_state *state =
2993 (struct poll_open_setup_watcher_state *)private_data;
2995 if (!validate_oplock_types(lck)) {
2996 smb_panic("validate_oplock_types failed");
2999 state->watch_req = share_mode_watch_send(
3000 state->mem_ctx,
3001 state->ev_ctx,
3002 lck,
3003 (struct server_id) {0});
3004 if (state->watch_req == NULL) {
3005 DBG_WARNING("share_mode_watch_send failed\n");
3006 return;
3011 * Reschedule an open for 1 second from now, if not timed out.
3013 static bool setup_poll_open(
3014 struct smb_request *req,
3015 const struct file_id *id,
3016 struct timeval max_timeout,
3017 struct timeval interval)
3019 static struct file_id zero_id = {};
3020 bool ok;
3021 struct deferred_open_record *open_rec = NULL;
3022 struct timeval endtime, next_interval;
3023 struct file_id_buf ftmp;
3025 if (request_timed_out(req, max_timeout)) {
3026 return false;
3029 open_rec = talloc_zero(NULL, struct deferred_open_record);
3030 if (open_rec == NULL) {
3031 DBG_WARNING("talloc failed\n");
3032 return false;
3034 open_rec->xconn = req->xconn;
3035 open_rec->mid = req->mid;
3038 * Make sure open_rec->te does not come later than the
3039 * request's maximum endtime.
3042 endtime = timeval_sum(&req->request_time, &max_timeout);
3043 next_interval = timeval_current_ofs(interval.tv_sec, interval.tv_usec);
3044 next_interval = timeval_min(&endtime, &next_interval);
3046 open_rec->te = tevent_add_timer(
3047 req->sconn->ev_ctx,
3048 open_rec,
3049 next_interval,
3050 poll_open_fn,
3051 open_rec);
3052 if (open_rec->te == NULL) {
3053 DBG_WARNING("tevent_add_timer failed\n");
3054 TALLOC_FREE(open_rec);
3055 return false;
3058 if (id != NULL) {
3059 struct poll_open_setup_watcher_state wstate = {
3060 .mem_ctx = open_rec,
3061 .ev_ctx = req->sconn->ev_ctx,
3063 NTSTATUS status;
3065 status = share_mode_do_locked_vfs_denied(*id,
3066 poll_open_setup_watcher_fn,
3067 &wstate);
3068 if (NT_STATUS_IS_OK(status)) {
3069 if (wstate.watch_req == NULL) {
3070 DBG_WARNING("share_mode_watch_send failed\n");
3071 TALLOC_FREE(open_rec);
3072 return false;
3074 open_rec->watch_req = wstate.watch_req;
3075 tevent_req_set_callback(open_rec->watch_req,
3076 poll_open_done,
3077 open_rec);
3078 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
3079 DBG_WARNING("share_mode_do_locked_vfs_denied failed - %s\n",
3080 nt_errstr(status));
3081 TALLOC_FREE(open_rec);
3082 return false;
3084 } else {
3085 id = &zero_id;
3088 ok = push_deferred_open_message_smb(req, max_timeout, *id, open_rec);
3089 if (!ok) {
3090 DBG_WARNING("push_deferred_open_message_smb failed\n");
3091 TALLOC_FREE(open_rec);
3092 return false;
3095 DBG_DEBUG("poll request time [%s] mid [%" PRIu64 "] file_id [%s]\n",
3096 timeval_string(talloc_tos(), &req->request_time, false),
3097 req->mid,
3098 file_id_str_buf(*id, &ftmp));
3100 return true;
3103 static void poll_open_done(struct tevent_req *subreq)
3105 struct deferred_open_record *open_rec = tevent_req_callback_data(
3106 subreq, struct deferred_open_record);
3107 NTSTATUS status;
3108 bool ok;
3110 status = share_mode_watch_recv(subreq, NULL, NULL);
3111 TALLOC_FREE(subreq);
3112 open_rec->watch_req = NULL;
3113 TALLOC_FREE(open_rec->te);
3115 DBG_DEBUG("dbwrap_watched_watch_recv returned %s\n",
3116 nt_errstr(status));
3118 ok = schedule_deferred_open_message_smb(
3119 open_rec->xconn, open_rec->mid);
3120 if (!ok) {
3121 exit_server("schedule_deferred_open_message_smb failed");
3125 bool defer_smb1_sharing_violation(struct smb_request *req)
3127 bool ok;
3128 int timeout_usecs;
3130 if (!lp_defer_sharing_violations()) {
3131 return false;
3135 * Try every 200msec up to (by default) one second. To be
3136 * precise, according to behaviour note <247> in [MS-CIFS],
3137 * the server tries 5 times. But up to one second should be
3138 * close enough.
3141 timeout_usecs = lp_parm_int(
3142 SNUM(req->conn),
3143 "smbd",
3144 "sharedelay",
3145 SHARING_VIOLATION_USEC_WAIT);
3147 ok = setup_poll_open(
3148 req,
3149 NULL,
3150 (struct timeval) { .tv_usec = timeout_usecs },
3151 (struct timeval) { .tv_usec = 200000 });
3152 return ok;
3155 /****************************************************************************
3156 On overwrite open ensure that the attributes match.
3157 ****************************************************************************/
3159 static bool open_match_attributes(connection_struct *conn,
3160 uint32_t old_dos_attr,
3161 uint32_t new_dos_attr,
3162 mode_t new_unx_mode,
3163 mode_t *returned_unx_mode)
3165 uint32_t noarch_old_dos_attr, noarch_new_dos_attr;
3167 noarch_old_dos_attr = (old_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
3168 noarch_new_dos_attr = (new_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
3170 if((noarch_old_dos_attr == 0 && noarch_new_dos_attr != 0) ||
3171 (noarch_old_dos_attr != 0 && ((noarch_old_dos_attr & noarch_new_dos_attr) == noarch_old_dos_attr))) {
3172 *returned_unx_mode = new_unx_mode;
3173 } else {
3174 *returned_unx_mode = (mode_t)0;
3177 DEBUG(10,("open_match_attributes: old_dos_attr = 0x%x, "
3178 "new_dos_attr = 0x%x "
3179 "returned_unx_mode = 0%o\n",
3180 (unsigned int)old_dos_attr,
3181 (unsigned int)new_dos_attr,
3182 (unsigned int)*returned_unx_mode ));
3184 /* If we're mapping SYSTEM and HIDDEN ensure they match. */
3185 if (lp_map_system(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
3186 if ((old_dos_attr & FILE_ATTRIBUTE_SYSTEM) &&
3187 !(new_dos_attr & FILE_ATTRIBUTE_SYSTEM)) {
3188 return False;
3191 if (lp_map_hidden(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
3192 if ((old_dos_attr & FILE_ATTRIBUTE_HIDDEN) &&
3193 !(new_dos_attr & FILE_ATTRIBUTE_HIDDEN)) {
3194 return False;
3197 return True;
3200 static void schedule_defer_open(struct share_mode_lock *lck,
3201 struct file_id id,
3202 struct smb_request *req)
3204 /* This is a relative time, added to the absolute
3205 request_time value to get the absolute timeout time.
3206 Note that if this is the second or greater time we enter
3207 this codepath for this particular request mid then
3208 request_time is left as the absolute time of the *first*
3209 time this request mid was processed. This is what allows
3210 the request to eventually time out. */
3212 struct timeval timeout;
3214 /* Normally the smbd we asked should respond within
3215 * OPLOCK_BREAK_TIMEOUT seconds regardless of whether
3216 * the client did, give twice the timeout as a safety
3217 * measure here in case the other smbd is stuck
3218 * somewhere else. */
3220 timeout = tevent_timeval_set(OPLOCK_BREAK_TIMEOUT * 2, 0);
3222 if (request_timed_out(req, timeout)) {
3223 return;
3226 defer_open(lck, timeout, req, id);
3229 /****************************************************************************
3230 Reschedule an open call that went asynchronous.
3231 ****************************************************************************/
3233 static void schedule_async_open_timer(struct tevent_context *ev,
3234 struct tevent_timer *te,
3235 struct timeval current_time,
3236 void *private_data)
3238 exit_server("async open timeout");
3241 static void schedule_async_open(struct smb_request *req)
3243 struct deferred_open_record *open_rec = NULL;
3244 struct timeval timeout = tevent_timeval_set(20, 0);
3245 bool ok;
3247 if (request_timed_out(req, timeout)) {
3248 return;
3251 open_rec = talloc_zero(NULL, struct deferred_open_record);
3252 if (open_rec == NULL) {
3253 exit_server("deferred_open_record_create failed");
3255 open_rec->async_open = true;
3257 ok = push_deferred_open_message_smb(
3258 req, timeout, (struct file_id){0}, open_rec);
3259 if (!ok) {
3260 exit_server("push_deferred_open_message_smb failed");
3263 open_rec->te = tevent_add_timer(req->sconn->ev_ctx,
3264 req,
3265 timeval_current_ofs(20, 0),
3266 schedule_async_open_timer,
3267 open_rec);
3268 if (open_rec->te == NULL) {
3269 exit_server("tevent_add_timer failed");
3273 static NTSTATUS check_and_store_share_mode(
3274 struct files_struct *fsp,
3275 struct smb_request *req,
3276 struct share_mode_lock *lck,
3277 uint32_t create_disposition,
3278 uint32_t access_mask,
3279 uint32_t share_access,
3280 int oplock_request,
3281 const struct smb2_lease *lease,
3282 bool first_open_attempt)
3284 NTSTATUS status;
3285 int oplock_type = NO_OPLOCK;
3286 uint32_t granted_lease = 0;
3287 const struct smb2_lease_key *lease_key = NULL;
3288 bool delete_on_close;
3289 bool ok;
3291 /* Get the types we need to examine. */
3292 if (!validate_oplock_types(lck)) {
3293 smb_panic("validate_oplock_types failed");
3296 delete_on_close = has_delete_on_close(lck, fsp->name_hash);
3297 if (delete_on_close) {
3298 return NT_STATUS_DELETE_PENDING;
3301 status = handle_share_mode_lease(fsp,
3302 lck,
3303 create_disposition,
3304 access_mask,
3305 share_access,
3306 oplock_request,
3307 lease,
3308 first_open_attempt,
3309 &oplock_type,
3310 &granted_lease);
3311 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
3312 schedule_defer_open(lck, fsp->file_id, req);
3313 return NT_STATUS_SHARING_VIOLATION;
3315 if (!NT_STATUS_IS_OK(status)) {
3316 return status;
3319 if (oplock_type == LEASE_OPLOCK) {
3320 lease_key = &lease->lease_key;
3323 share_mode_flags_restrict(lck, access_mask, share_access, 0);
3325 ok = set_share_mode(lck,
3326 fsp,
3327 get_current_uid(fsp->conn),
3328 req ? req->mid : 0,
3329 oplock_type,
3330 lease_key,
3331 share_access,
3332 access_mask);
3333 if (!ok) {
3334 return NT_STATUS_NO_MEMORY;
3337 if (oplock_type == LEASE_OPLOCK) {
3338 status = grant_fsp_lease(fsp, lck, lease, granted_lease);
3339 if (!NT_STATUS_IS_OK(status)) {
3340 del_share_mode(lck, fsp);
3341 return status;
3344 DBG_DEBUG("lease_state=%d\n", fsp->lease->lease.lease_state);
3347 fsp->oplock_type = oplock_type;
3349 return NT_STATUS_OK;
3352 /****************************************************************************
3353 Work out what access_mask to use from what the client sent us.
3354 ****************************************************************************/
3356 static NTSTATUS smbd_calculate_maximum_allowed_access_fsp(
3357 struct files_struct *dirfsp,
3358 struct files_struct *fsp,
3359 bool use_privs,
3360 uint32_t *p_access_mask)
3362 struct security_descriptor *sd = NULL;
3363 uint32_t access_granted = 0;
3364 uint32_t dosattrs;
3365 NTSTATUS status;
3367 /* Cope with symlinks */
3368 if (fsp == NULL || fsp_get_pathref_fd(fsp) == -1) {
3369 *p_access_mask = FILE_GENERIC_ALL;
3370 return NT_STATUS_OK;
3373 /* Cope with fake/printer fsp's. */
3374 if (fsp->fake_file_handle != NULL || fsp->print_file != NULL) {
3375 *p_access_mask = FILE_GENERIC_ALL;
3376 return NT_STATUS_OK;
3379 if (!use_privs && (get_current_uid(fsp->conn) == (uid_t)0)) {
3380 *p_access_mask |= FILE_GENERIC_ALL;
3381 return NT_STATUS_OK;
3384 status = SMB_VFS_FGET_NT_ACL(metadata_fsp(fsp),
3385 (SECINFO_OWNER |
3386 SECINFO_GROUP |
3387 SECINFO_DACL),
3388 talloc_tos(),
3389 &sd);
3391 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
3393 * File did not exist
3395 *p_access_mask = FILE_GENERIC_ALL;
3396 return NT_STATUS_OK;
3398 if (!NT_STATUS_IS_OK(status)) {
3399 DBG_ERR("Could not get acl on file %s: %s\n",
3400 fsp_str_dbg(fsp),
3401 nt_errstr(status));
3402 return status;
3406 * If we can access the path to this file, by
3407 * default we have FILE_READ_ATTRIBUTES from the
3408 * containing directory. See the section:
3409 * "Algorithm to Check Access to an Existing File"
3410 * in MS-FSA.pdf.
3412 * se_file_access_check()
3413 * also takes care of owner WRITE_DAC and READ_CONTROL.
3415 status = se_file_access_check(sd,
3416 get_current_nttok(fsp->conn),
3417 use_privs,
3418 (*p_access_mask & ~FILE_READ_ATTRIBUTES),
3419 &access_granted);
3421 TALLOC_FREE(sd);
3423 if (!NT_STATUS_IS_OK(status)) {
3424 DBG_ERR("Status %s on file %s: "
3425 "when calculating maximum access\n",
3426 nt_errstr(status),
3427 fsp_str_dbg(fsp));
3428 return status;
3431 *p_access_mask = (access_granted | FILE_READ_ATTRIBUTES);
3433 if (!(access_granted & DELETE_ACCESS)) {
3434 if (can_delete_file_in_directory(fsp->conn,
3435 dirfsp,
3436 fsp->fsp_name)) {
3437 *p_access_mask |= DELETE_ACCESS;
3441 dosattrs = fdos_mode(fsp);
3442 if ((dosattrs & FILE_ATTRIBUTE_READONLY) || !CAN_WRITE(fsp->conn)) {
3443 *p_access_mask &= ~(FILE_GENERIC_WRITE | DELETE_ACCESS);
3446 return NT_STATUS_OK;
3449 NTSTATUS smbd_calculate_access_mask_fsp(struct files_struct *dirfsp,
3450 struct files_struct *fsp,
3451 bool use_privs,
3452 uint32_t access_mask,
3453 uint32_t *access_mask_out)
3455 NTSTATUS status;
3456 uint32_t orig_access_mask = access_mask;
3457 uint32_t rejected_share_access;
3459 if (access_mask & SEC_MASK_INVALID) {
3460 DBG_DEBUG("access_mask [%8x] contains invalid bits\n",
3461 access_mask);
3462 return NT_STATUS_ACCESS_DENIED;
3466 * Convert GENERIC bits to specific bits.
3469 se_map_generic(&access_mask, &file_generic_mapping);
3471 /* Calculate MAXIMUM_ALLOWED_ACCESS if requested. */
3472 if (access_mask & MAXIMUM_ALLOWED_ACCESS) {
3474 status = smbd_calculate_maximum_allowed_access_fsp(
3475 dirfsp,
3476 fsp,
3477 use_privs,
3478 &access_mask);
3480 if (!NT_STATUS_IS_OK(status)) {
3481 return status;
3484 access_mask &= fsp->conn->share_access;
3487 rejected_share_access = access_mask & ~(fsp->conn->share_access);
3489 if (rejected_share_access) {
3490 DBG_INFO("Access denied on file %s: "
3491 "rejected by share access mask[0x%08X] "
3492 "orig[0x%08X] mapped[0x%08X] reject[0x%08X]\n",
3493 fsp_str_dbg(fsp),
3494 fsp->conn->share_access,
3495 orig_access_mask, access_mask,
3496 rejected_share_access);
3497 return NT_STATUS_ACCESS_DENIED;
3500 *access_mask_out = access_mask;
3501 return NT_STATUS_OK;
3504 /****************************************************************************
3505 Remove the deferred open entry under lock.
3506 ****************************************************************************/
3508 /****************************************************************************
3509 Return true if this is a state pointer to an asynchronous create.
3510 ****************************************************************************/
3512 bool is_deferred_open_async(const struct deferred_open_record *rec)
3514 return rec->async_open;
3517 static bool clear_ads(uint32_t create_disposition)
3519 bool ret = false;
3521 switch (create_disposition) {
3522 case FILE_SUPERSEDE:
3523 case FILE_OVERWRITE_IF:
3524 case FILE_OVERWRITE:
3525 ret = true;
3526 break;
3527 default:
3528 break;
3530 return ret;
3533 static int disposition_to_open_flags(uint32_t create_disposition)
3535 int ret = 0;
3538 * Currently we're using FILE_SUPERSEDE as the same as
3539 * FILE_OVERWRITE_IF but they really are
3540 * different. FILE_SUPERSEDE deletes an existing file
3541 * (requiring delete access) then recreates it.
3544 switch (create_disposition) {
3545 case FILE_SUPERSEDE:
3546 case FILE_OVERWRITE_IF:
3548 * If file exists replace/overwrite. If file doesn't
3549 * exist create.
3551 ret = O_CREAT|O_TRUNC;
3552 break;
3554 case FILE_OPEN:
3556 * If file exists open. If file doesn't exist error.
3558 ret = 0;
3559 break;
3561 case FILE_OVERWRITE:
3563 * If file exists overwrite. If file doesn't exist
3564 * error.
3566 ret = O_TRUNC;
3567 break;
3569 case FILE_CREATE:
3571 * If file exists error. If file doesn't exist create.
3573 ret = O_CREAT|O_EXCL;
3574 break;
3576 case FILE_OPEN_IF:
3578 * If file exists open. If file doesn't exist create.
3580 ret = O_CREAT;
3581 break;
3583 return ret;
3586 static int calculate_open_access_flags(uint32_t access_mask,
3587 uint32_t private_flags,
3588 NTTIME twrp)
3590 bool need_write, need_read;
3593 * Note that we ignore the append flag as append does not
3594 * mean the same thing under DOS and Unix.
3597 if (twrp != 0) {
3599 * Pave over the user requested mode and force O_RDONLY for the
3600 * file handle. Windows allows opening a VSS file with O_RDWR,
3601 * even though actual writes on the handle will fail.
3603 return O_RDONLY;
3606 need_write = (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA));
3607 if (!need_write) {
3608 return O_RDONLY;
3611 /* DENY_DOS opens are always underlying read-write on the
3612 file handle, no matter what the requested access mask
3613 says. */
3615 need_read =
3616 ((private_flags & NTCREATEX_FLAG_DENY_DOS) ||
3617 access_mask & (FILE_READ_ATTRIBUTES|FILE_READ_DATA|
3618 FILE_READ_EA|FILE_EXECUTE));
3620 if (!need_read) {
3621 return O_WRONLY;
3623 return O_RDWR;
3626 struct open_ntcreate_lock_state {
3627 struct share_mode_entry_prepare_state prepare_state;
3628 struct files_struct *fsp;
3629 const char *object_type;
3630 struct smb_request *req;
3631 uint32_t create_disposition;
3632 uint32_t access_mask;
3633 uint32_t share_access;
3634 int oplock_request;
3635 const struct smb2_lease *lease;
3636 bool first_open_attempt;
3637 bool keep_locked;
3638 NTSTATUS status;
3639 struct timespec write_time;
3640 share_mode_entry_prepare_unlock_fn_t cleanup_fn;
3643 static void open_ntcreate_lock_add_entry(struct share_mode_lock *lck,
3644 bool *keep_locked,
3645 void *private_data)
3647 struct open_ntcreate_lock_state *state =
3648 (struct open_ntcreate_lock_state *)private_data;
3651 * By default drop the g_lock again if we leave the
3652 * tdb chainlock.
3654 *keep_locked = false;
3656 state->status = check_and_store_share_mode(state->fsp,
3657 state->req,
3658 lck,
3659 state->create_disposition,
3660 state->access_mask,
3661 state->share_access,
3662 state->oplock_request,
3663 state->lease,
3664 state->first_open_attempt);
3665 if (!NT_STATUS_IS_OK(state->status)) {
3666 return;
3669 state->write_time = get_share_mode_write_time(lck);
3672 * keep the g_lock while existing the tdb chainlock,
3673 * we we're asked to, which mean we'll keep
3674 * the share_mode_lock during object creation,
3675 * or setting delete on close.
3677 *keep_locked = state->keep_locked;
3680 static void open_ntcreate_lock_cleanup_oplock(struct share_mode_lock *lck,
3681 void *private_data)
3683 struct open_ntcreate_lock_state *state =
3684 (struct open_ntcreate_lock_state *)private_data;
3685 bool ok;
3687 ok = remove_share_oplock(lck, state->fsp);
3688 if (!ok) {
3689 DBG_ERR("Could not remove oplock for %s %s\n",
3690 state->object_type, fsp_str_dbg(state->fsp));
3694 static void open_ntcreate_lock_cleanup_entry(struct share_mode_lock *lck,
3695 void *private_data)
3697 struct open_ntcreate_lock_state *state =
3698 (struct open_ntcreate_lock_state *)private_data;
3699 bool ok;
3701 ok = del_share_mode(lck, state->fsp);
3702 if (!ok) {
3703 DBG_ERR("Could not delete share entry for %s %s\n",
3704 state->object_type, fsp_str_dbg(state->fsp));
3708 static void possibly_set_archive(struct connection_struct *conn,
3709 struct files_struct *fsp,
3710 struct smb_filename *smb_fname,
3711 struct smb_filename *parent_dir_fname,
3712 int info,
3713 uint32_t dosattrs,
3714 mode_t *unx_mode)
3716 bool set_archive = false;
3717 int ret;
3719 if (info == FILE_WAS_OPENED) {
3720 return;
3723 /* Overwritten files should be initially set as archive */
3724 if ((info == FILE_WAS_OVERWRITTEN && lp_map_archive(SNUM(conn)))) {
3725 set_archive = true;
3726 } else if (lp_store_dos_attributes(SNUM(conn))) {
3727 set_archive = true;
3729 if (!set_archive) {
3730 return;
3733 ret = file_set_dosmode(conn,
3734 smb_fname,
3735 dosattrs | FILE_ATTRIBUTE_ARCHIVE,
3736 parent_dir_fname,
3737 true);
3738 if (ret != 0) {
3739 return;
3741 *unx_mode = smb_fname->st.st_ex_mode;
3744 /****************************************************************************
3745 Open a file with a share mode. Passed in an already created files_struct *.
3746 ****************************************************************************/
3748 static NTSTATUS open_file_ntcreate(connection_struct *conn,
3749 struct smb_request *req,
3750 uint32_t access_mask, /* access bits (FILE_READ_DATA etc.) */
3751 uint32_t share_access, /* share constants (FILE_SHARE_READ etc) */
3752 uint32_t create_disposition, /* FILE_OPEN_IF etc. */
3753 uint32_t create_options, /* options such as delete on close. */
3754 uint32_t new_dos_attributes, /* attributes used for new file. */
3755 int oplock_request, /* internal Samba oplock codes. */
3756 const struct smb2_lease *lease,
3757 /* Information (FILE_EXISTS etc.) */
3758 uint32_t private_flags, /* Samba specific flags. */
3759 struct smb_filename *parent_dir_fname, /* parent. */
3760 struct smb_filename *smb_fname_atname, /* atname relative to parent. */
3761 int *pinfo,
3762 files_struct *fsp)
3764 struct smb_filename *smb_fname = fsp->fsp_name;
3765 int flags=0;
3766 bool file_existed = VALID_STAT(smb_fname->st);
3767 bool def_acl = False;
3768 bool posix_open = False;
3769 bool new_file_created = False;
3770 bool first_open_attempt = true;
3771 bool is_twrp = (smb_fname_atname->twrp != 0);
3772 NTSTATUS fsp_open = NT_STATUS_ACCESS_DENIED;
3773 mode_t new_unx_mode = (mode_t)0;
3774 mode_t unx_mode = (mode_t)0;
3775 int info;
3776 uint32_t existing_dos_attributes = 0;
3777 struct open_ntcreate_lock_state lck_state = {};
3778 bool keep_locked = false;
3779 uint32_t open_access_mask = access_mask;
3780 NTSTATUS status;
3781 SMB_STRUCT_STAT saved_stat = smb_fname->st;
3782 struct timespec old_write_time;
3783 bool setup_poll = false;
3784 NTSTATUS ulstatus;
3786 if (conn->printer) {
3788 * Printers are handled completely differently.
3789 * Most of the passed parameters are ignored.
3792 if (pinfo) {
3793 *pinfo = FILE_WAS_CREATED;
3796 DBG_DEBUG("printer open fname=%s\n",
3797 smb_fname_str_dbg(smb_fname));
3799 if (!req) {
3800 DBG_ERR("printer open without an SMB request!\n");
3801 return NT_STATUS_INTERNAL_ERROR;
3804 return print_spool_open(fsp, smb_fname->base_name,
3805 req->vuid);
3808 if (new_dos_attributes & FILE_FLAG_POSIX_SEMANTICS) {
3809 posix_open = True;
3810 unx_mode = (mode_t)(new_dos_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
3811 new_dos_attributes = 0;
3812 } else {
3813 /* Windows allows a new file to be created and
3814 silently removes a FILE_ATTRIBUTE_DIRECTORY
3815 sent by the client. Do the same. */
3817 new_dos_attributes &= ~FILE_ATTRIBUTE_DIRECTORY;
3819 /* We add FILE_ATTRIBUTE_ARCHIVE to this as this mode is only used if the file is
3820 * created new. */
3821 unx_mode = unix_mode(
3822 conn,
3823 new_dos_attributes | FILE_ATTRIBUTE_ARCHIVE,
3824 smb_fname,
3825 parent_dir_fname->fsp);
3828 DEBUG(10, ("open_file_ntcreate: fname=%s, dos_attrs=0x%x "
3829 "access_mask=0x%x share_access=0x%x "
3830 "create_disposition = 0x%x create_options=0x%x "
3831 "unix mode=0%o oplock_request=%d private_flags = 0x%x\n",
3832 smb_fname_str_dbg(smb_fname), new_dos_attributes,
3833 access_mask, share_access, create_disposition,
3834 create_options, (unsigned int)unx_mode, oplock_request,
3835 (unsigned int)private_flags));
3837 if (req == NULL) {
3838 /* Ensure req == NULL means INTERNAL_OPEN_ONLY */
3839 SMB_ASSERT(oplock_request == INTERNAL_OPEN_ONLY);
3840 } else {
3841 /* And req != NULL means no INTERNAL_OPEN_ONLY */
3842 SMB_ASSERT(((oplock_request & INTERNAL_OPEN_ONLY) == 0));
3846 * Only non-internal opens can be deferred at all
3849 if (req) {
3850 struct deferred_open_record *open_rec;
3851 if (get_deferred_open_message_state(req, NULL, &open_rec)) {
3853 /* If it was an async create retry, the file
3854 didn't exist. */
3856 if (is_deferred_open_async(open_rec)) {
3857 SET_STAT_INVALID(smb_fname->st);
3858 file_existed = false;
3861 /* Ensure we don't reprocess this message. */
3862 remove_deferred_open_message_smb(req->xconn, req->mid);
3864 first_open_attempt = false;
3868 if (!posix_open) {
3869 new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
3870 if (file_existed) {
3872 * Only use stored DOS attributes for checks
3873 * against requested attributes (below via
3874 * open_match_attributes()), cf bug #11992
3875 * for details. -slow
3877 uint32_t attr = 0;
3879 status = SMB_VFS_FGET_DOS_ATTRIBUTES(
3880 conn,
3881 metadata_fsp(smb_fname->fsp),
3882 &attr);
3883 if (NT_STATUS_IS_OK(status)) {
3884 existing_dos_attributes = attr;
3889 /* ignore any oplock requests if oplocks are disabled */
3890 if (!lp_oplocks(SNUM(conn)) ||
3891 IS_VETO_OPLOCK_PATH(conn, smb_fname->base_name)) {
3892 /* Mask off everything except the private Samba bits. */
3893 oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
3896 /* this is for OS/2 long file names - say we don't support them */
3897 if (req != NULL && !req->posix_pathnames &&
3898 strstr(smb_fname->base_name,".+,;=[].")) {
3899 /* OS/2 Workplace shell fix may be main code stream in a later
3900 * release. */
3901 DEBUG(5,("open_file_ntcreate: OS/2 long filenames are not "
3902 "supported.\n"));
3903 if (use_nt_status()) {
3904 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3906 return NT_STATUS_DOS(ERRDOS, ERRcannotopen);
3909 switch( create_disposition ) {
3910 case FILE_OPEN:
3911 /* If file exists open. If file doesn't exist error. */
3912 if (!file_existed) {
3913 DEBUG(5,("open_file_ntcreate: FILE_OPEN "
3914 "requested for file %s and file "
3915 "doesn't exist.\n",
3916 smb_fname_str_dbg(smb_fname)));
3917 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3919 break;
3921 case FILE_OVERWRITE:
3922 /* If file exists overwrite. If file doesn't exist
3923 * error. */
3924 if (!file_existed) {
3925 DEBUG(5,("open_file_ntcreate: FILE_OVERWRITE "
3926 "requested for file %s and file "
3927 "doesn't exist.\n",
3928 smb_fname_str_dbg(smb_fname) ));
3929 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3931 if (is_twrp) {
3932 return NT_STATUS_MEDIA_WRITE_PROTECTED;
3934 break;
3936 case FILE_CREATE:
3937 /* If file exists error. If file doesn't exist
3938 * create. */
3939 if (file_existed) {
3940 DEBUG(5,("open_file_ntcreate: FILE_CREATE "
3941 "requested for file %s and file "
3942 "already exists.\n",
3943 smb_fname_str_dbg(smb_fname)));
3944 if (S_ISDIR(smb_fname->st.st_ex_mode)) {
3945 return NT_STATUS_FILE_IS_A_DIRECTORY;
3947 return NT_STATUS_OBJECT_NAME_COLLISION;
3949 if (is_twrp) {
3950 return NT_STATUS_MEDIA_WRITE_PROTECTED;
3952 break;
3954 case FILE_SUPERSEDE:
3955 case FILE_OVERWRITE_IF:
3956 if (is_twrp) {
3957 return NT_STATUS_MEDIA_WRITE_PROTECTED;
3959 break;
3960 case FILE_OPEN_IF:
3961 if (is_twrp) {
3962 if (!file_existed) {
3963 return NT_STATUS_MEDIA_WRITE_PROTECTED;
3965 create_disposition = FILE_OPEN;
3967 break;
3968 default:
3969 return NT_STATUS_INVALID_PARAMETER;
3972 flags = disposition_to_open_flags(create_disposition);
3974 /* We only care about matching attributes on file exists and
3975 * overwrite. */
3977 if (!posix_open && file_existed &&
3978 ((create_disposition == FILE_OVERWRITE) ||
3979 (create_disposition == FILE_OVERWRITE_IF))) {
3980 if (!open_match_attributes(conn, existing_dos_attributes,
3981 new_dos_attributes,
3982 unx_mode, &new_unx_mode)) {
3983 DEBUG(5,("open_file_ntcreate: attributes mismatch "
3984 "for file %s (%x %x) (0%o, 0%o)\n",
3985 smb_fname_str_dbg(smb_fname),
3986 existing_dos_attributes,
3987 new_dos_attributes,
3988 (unsigned int)smb_fname->st.st_ex_mode,
3989 (unsigned int)unx_mode ));
3990 return NT_STATUS_ACCESS_DENIED;
3994 status = smbd_calculate_access_mask_fsp(parent_dir_fname->fsp,
3995 smb_fname->fsp,
3996 false,
3997 access_mask,
3998 &access_mask);
3999 if (!NT_STATUS_IS_OK(status)) {
4000 DBG_DEBUG("smbd_calculate_access_mask_fsp "
4001 "on file %s returned %s\n",
4002 smb_fname_str_dbg(smb_fname),
4003 nt_errstr(status));
4004 return status;
4007 open_access_mask = access_mask;
4009 if (flags & O_TRUNC) {
4010 open_access_mask |= FILE_WRITE_DATA; /* This will cause oplock breaks. */
4013 if (file_existed) {
4015 * stat opens on existing files don't get oplocks.
4016 * They can get leases.
4018 * Note that we check for stat open on the *open_access_mask*,
4019 * i.e. the access mask we actually used to do the open,
4020 * not the one the client asked for (which is in
4021 * fsp->access_mask). This is due to the fact that
4022 * FILE_OVERWRITE and FILE_OVERWRITE_IF add in O_TRUNC,
4023 * which adds FILE_WRITE_DATA to open_access_mask.
4025 if (is_oplock_stat_open(open_access_mask) && lease == NULL) {
4026 oplock_request = NO_OPLOCK;
4030 DEBUG(10, ("open_file_ntcreate: fname=%s, after mapping "
4031 "access_mask=0x%x\n", smb_fname_str_dbg(smb_fname),
4032 access_mask));
4035 * Note that we ignore the append flag as append does not
4036 * mean the same thing under DOS and Unix.
4039 flags |= calculate_open_access_flags(access_mask,
4040 private_flags,
4041 smb_fname->twrp);
4044 * Currently we only look at FILE_WRITE_THROUGH for create options.
4047 #if defined(O_SYNC)
4048 if ((create_options & FILE_WRITE_THROUGH) && lp_strict_sync(SNUM(conn))) {
4049 flags |= O_SYNC;
4051 #endif /* O_SYNC */
4053 if (posix_open && (access_mask & FILE_APPEND_DATA)) {
4054 flags |= O_APPEND;
4057 if (!posix_open && !CAN_WRITE(conn)) {
4059 * We should really return a permission denied error if either
4060 * O_CREAT or O_TRUNC are set, but for compatibility with
4061 * older versions of Samba we just AND them out.
4063 flags &= ~(O_CREAT | O_TRUNC);
4067 * With kernel oplocks the open breaking an oplock
4068 * blocks until the oplock holder has given up the
4069 * oplock or closed the file. We prevent this by always
4070 * trying to open the file with O_NONBLOCK (see "man
4071 * fcntl" on Linux).
4073 * If a process that doesn't use the smbd open files
4074 * database or communication methods holds a kernel
4075 * oplock we must periodically poll for available open
4076 * using O_NONBLOCK.
4078 flags |= O_NONBLOCK;
4081 * Ensure we can't write on a read-only share or file.
4084 if (((flags & O_ACCMODE) != O_RDONLY) && file_existed &&
4085 (!CAN_WRITE(conn) ||
4086 (existing_dos_attributes & FILE_ATTRIBUTE_READONLY))) {
4087 DEBUG(5,("open_file_ntcreate: write access requested for "
4088 "file %s on read only %s\n",
4089 smb_fname_str_dbg(smb_fname),
4090 !CAN_WRITE(conn) ? "share" : "file" ));
4091 return NT_STATUS_ACCESS_DENIED;
4094 if (VALID_STAT(smb_fname->st)) {
4096 * Only try and create a file id before open
4097 * for an existing file. For a file being created
4098 * this won't do anything useful until the file
4099 * exists and has a valid stat struct.
4101 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
4103 fh_set_private_options(fsp->fh, private_flags);
4104 fsp->access_mask = open_access_mask; /* We change this to the
4105 * requested access_mask after
4106 * the open is done. */
4107 if (posix_open) {
4108 fsp->posix_flags |= FSP_POSIX_FLAGS_ALL;
4111 if ((create_options & FILE_DELETE_ON_CLOSE) && (flags & O_CREAT) &&
4112 !file_existed) {
4113 /* Delete on close semantics for new files. */
4114 status = can_set_delete_on_close(fsp,
4115 new_dos_attributes);
4116 if (!NT_STATUS_IS_OK(status)) {
4117 fd_close(fsp);
4118 return status;
4123 * Ensure we pay attention to default ACLs on directories if required.
4126 if ((flags & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
4127 (def_acl = directory_has_default_acl_fsp(parent_dir_fname->fsp))) {
4128 unx_mode = (0777 & lp_create_mask(SNUM(conn)));
4131 DEBUG(4,
4132 ("calling open_file with flags=0x%X mode=0%o, "
4133 "access_mask = 0x%x, open_access_mask = 0x%x\n",
4134 (unsigned int)flags,
4135 (unsigned int)unx_mode,
4136 (unsigned int)access_mask,
4137 (unsigned int)open_access_mask));
4140 struct vfs_open_how how = {
4141 .flags = flags,
4142 .mode = unx_mode,
4145 if (create_options & FILE_OPEN_FOR_BACKUP_INTENT) {
4146 how.resolve |= VFS_OPEN_HOW_WITH_BACKUP_INTENT;
4149 fsp_open = open_file(req,
4150 parent_dir_fname->fsp,
4151 smb_fname_atname,
4152 fsp,
4153 &how,
4154 access_mask,
4155 open_access_mask,
4156 private_flags,
4157 &new_file_created);
4159 if (NT_STATUS_EQUAL(fsp_open, NT_STATUS_NETWORK_BUSY)) {
4160 if (file_existed && S_ISFIFO(fsp->fsp_name->st.st_ex_mode)) {
4161 DEBUG(10, ("FIFO busy\n"));
4162 return NT_STATUS_NETWORK_BUSY;
4164 if (req == NULL) {
4165 DEBUG(10, ("Internal open busy\n"));
4166 return NT_STATUS_NETWORK_BUSY;
4169 * This handles the kernel oplock case:
4171 * the file has an active kernel oplock and the open() returned
4172 * EWOULDBLOCK/EAGAIN which maps to NETWORK_BUSY.
4174 * "Samba locking.tdb oplocks" are handled below after acquiring
4175 * the sharemode lock with get_share_mode_lock().
4177 setup_poll = true;
4180 if (NT_STATUS_EQUAL(fsp_open, NT_STATUS_RETRY)) {
4182 * EINTR from the open(2) syscall. Just setup a retry
4183 * in a bit. We can't use the sys_write() tight retry
4184 * loop here, as we might have to actually deal with
4185 * lease-break signals to avoid a deadlock.
4187 setup_poll = true;
4190 if (setup_poll) {
4192 * Retry once a second. If there's a share_mode_lock
4193 * around, also wait for it in case it was smbd
4194 * holding that kernel oplock that can quickly tell us
4195 * the oplock got removed.
4198 setup_poll_open(req,
4199 &fsp->file_id,
4200 tevent_timeval_set(OPLOCK_BREAK_TIMEOUT * 2,
4202 tevent_timeval_set(1, 0));
4204 return NT_STATUS_SHARING_VIOLATION;
4207 if (!NT_STATUS_IS_OK(fsp_open)) {
4208 bool wait_for_aio = NT_STATUS_EQUAL(
4209 fsp_open, NT_STATUS_MORE_PROCESSING_REQUIRED);
4210 if (wait_for_aio) {
4211 schedule_async_open(req);
4213 return fsp_open;
4216 if (new_file_created) {
4218 * As we atomically create using O_CREAT|O_EXCL,
4219 * then if new_file_created is true, then
4220 * file_existed *MUST* have been false (even
4221 * if the file was previously detected as being
4222 * there).
4224 file_existed = false;
4227 if (file_existed && !check_same_dev_ino(&saved_stat, &smb_fname->st)) {
4229 * The file did exist, but some other (local or NFS)
4230 * process either renamed/unlinked and re-created the
4231 * file with different dev/ino after we walked the path,
4232 * but before we did the open. We could retry the
4233 * open but it's a rare enough case it's easier to
4234 * just fail the open to prevent creating any problems
4235 * in the open file db having the wrong dev/ino key.
4237 fd_close(fsp);
4238 DBG_WARNING("file %s - dev/ino mismatch. "
4239 "Old (dev=%ju, ino=%ju). "
4240 "New (dev=%ju, ino=%ju). Failing open "
4241 "with NT_STATUS_ACCESS_DENIED.\n",
4242 smb_fname_str_dbg(smb_fname),
4243 (uintmax_t)saved_stat.st_ex_dev,
4244 (uintmax_t)saved_stat.st_ex_ino,
4245 (uintmax_t)smb_fname->st.st_ex_dev,
4246 (uintmax_t)smb_fname->st.st_ex_ino);
4247 return NT_STATUS_ACCESS_DENIED;
4250 old_write_time = smb_fname->st.st_ex_mtime;
4253 * Deal with the race condition where two smbd's detect the
4254 * file doesn't exist and do the create at the same time. One
4255 * of them will win and set a share mode, the other (ie. this
4256 * one) should check if the requested share mode for this
4257 * create is allowed.
4261 * Now the file exists and fsp is successfully opened,
4262 * fsp->dev and fsp->inode are valid and should replace the
4263 * dev=0,inode=0 from a non existent file. Spotted by
4264 * Nadav Danieli <nadavd@exanet.com>. JRA.
4267 if (new_file_created) {
4268 info = FILE_WAS_CREATED;
4269 } else {
4270 if (flags & O_TRUNC) {
4271 info = FILE_WAS_OVERWRITTEN;
4272 } else {
4273 info = FILE_WAS_OPENED;
4278 * If we created a new file, overwrite an existing one
4279 * or going to delete it later, we should keep
4280 * the share_mode_lock (g_lock) until we call
4281 * share_mode_entry_prepare_unlock()
4283 if (info != FILE_WAS_OPENED) {
4284 keep_locked = true;
4285 } else if (create_options & FILE_DELETE_ON_CLOSE) {
4286 keep_locked = true;
4289 lck_state = (struct open_ntcreate_lock_state) {
4290 .fsp = fsp,
4291 .object_type = "file",
4292 .req = req,
4293 .create_disposition = create_disposition,
4294 .access_mask = access_mask,
4295 .share_access = share_access,
4296 .oplock_request = oplock_request,
4297 .lease = lease,
4298 .first_open_attempt = first_open_attempt,
4299 .keep_locked = keep_locked,
4302 status = share_mode_entry_prepare_lock_add(&lck_state.prepare_state,
4303 fsp->file_id,
4304 conn->connectpath,
4305 smb_fname,
4306 &old_write_time,
4307 open_ntcreate_lock_add_entry,
4308 &lck_state);
4309 if (!NT_STATUS_IS_OK(status)) {
4310 DBG_ERR("share_mode_entry_prepare_lock_add() failed for %s - %s\n",
4311 smb_fname_str_dbg(smb_fname), nt_errstr(status));
4312 fd_close(fsp);
4313 return status;
4316 status = lck_state.status;
4317 if (!NT_STATUS_IS_OK(status)) {
4318 fd_close(fsp);
4319 return status;
4323 * From here we need to use 'goto unlock;' instead of return !!!
4326 if (fsp->oplock_type != NO_OPLOCK && fsp->oplock_type != LEASE_OPLOCK) {
4328 * Now ask for kernel oplocks
4329 * and cleanup on failure.
4331 status = set_file_oplock(fsp);
4332 if (!NT_STATUS_IS_OK(status)) {
4334 * Could not get the kernel oplock
4336 lck_state.cleanup_fn =
4337 open_ntcreate_lock_cleanup_oplock;
4338 fsp->oplock_type = NO_OPLOCK;
4342 /* Should we atomically (to the client at least) truncate ? */
4343 if ((!new_file_created) && (flags & O_TRUNC) &&
4344 (S_ISREG(fsp->fsp_name->st.st_ex_mode))) {
4345 int ret;
4347 ret = SMB_VFS_FTRUNCATE(fsp, 0);
4348 if (ret != 0) {
4349 status = map_nt_error_from_unix(errno);
4350 lck_state.cleanup_fn =
4351 open_ntcreate_lock_cleanup_entry;
4352 goto unlock;
4354 notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
4355 FILE_NOTIFY_CHANGE_SIZE
4356 | FILE_NOTIFY_CHANGE_ATTRIBUTES,
4357 fsp->fsp_name->base_name);
4361 * We have the share entry *locked*.....
4364 /* Delete streams if create_disposition requires it */
4365 if (!new_file_created &&
4366 clear_ads(create_disposition) &&
4367 !fsp_is_alternate_stream(fsp)) {
4368 status = delete_all_streams(conn, smb_fname);
4369 if (!NT_STATUS_IS_OK(status)) {
4370 lck_state.cleanup_fn =
4371 open_ntcreate_lock_cleanup_entry;
4372 goto unlock;
4376 if (!fsp->fsp_flags.is_pathref &&
4377 fsp_get_io_fd(fsp) != -1 &&
4378 lp_kernel_share_modes(SNUM(conn)))
4380 int ret;
4382 * Beware: streams implementing VFS modules may
4383 * implement streams in a way that fsp will have the
4384 * basefile open in the fsp fd, so lacking a distinct
4385 * fd for the stream the file-system sharemode will
4386 * apply on the basefile which is wrong. The actual
4387 * check is deferred to the VFS module implementing
4388 * the file-system sharemode call.
4390 ret = SMB_VFS_FILESYSTEM_SHAREMODE(fsp,
4391 share_access,
4392 access_mask);
4393 if (ret == -1){
4394 status = NT_STATUS_SHARING_VIOLATION;
4395 lck_state.cleanup_fn =
4396 open_ntcreate_lock_cleanup_entry;
4397 goto unlock;
4400 fsp->fsp_flags.kernel_share_modes_taken = true;
4404 * At this point onwards, we can guarantee that the share entry
4405 * is locked, whether we created the file or not, and that the
4406 * deny mode is compatible with all current opens.
4410 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
4411 * but we don't have to store this - just ignore it on access check.
4413 if (conn_using_smb2(conn->sconn)) {
4415 * SMB2 doesn't return it (according to Microsoft tests).
4416 * Test Case: TestSuite_ScenarioNo009GrantedAccessTestS0
4417 * File created with access = 0x7 (Read, Write, Delete)
4418 * Query Info on file returns 0x87 (Read, Write, Delete, Read Attributes)
4420 fsp->access_mask = access_mask;
4421 } else {
4422 /* But SMB1 does. */
4423 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
4426 if (pinfo) {
4427 *pinfo = info;
4430 /* Handle strange delete on close create semantics. */
4431 if (create_options & FILE_DELETE_ON_CLOSE) {
4432 if (!new_file_created) {
4433 status = can_set_delete_on_close(fsp,
4434 existing_dos_attributes);
4436 if (!NT_STATUS_IS_OK(status)) {
4437 /* Remember to delete the mode we just added. */
4438 lck_state.cleanup_fn =
4439 open_ntcreate_lock_cleanup_entry;
4440 goto unlock;
4443 /* Note that here we set the *initial* delete on close flag,
4444 not the regular one. The magic gets handled in close. */
4445 fsp->fsp_flags.initial_delete_on_close = true;
4448 possibly_set_archive(conn,
4449 fsp,
4450 smb_fname,
4451 parent_dir_fname,
4452 info,
4453 new_dos_attributes,
4454 &smb_fname->st.st_ex_mode);
4456 /* Determine sparse flag. */
4457 if (posix_open) {
4458 /* POSIX opens are sparse by default. */
4459 fsp->fsp_flags.is_sparse = true;
4460 } else {
4461 fsp->fsp_flags.is_sparse =
4462 (existing_dos_attributes & FILE_ATTRIBUTE_SPARSE);
4466 * Take care of inherited ACLs on created files - if default ACL not
4467 * selected.
4470 if (!posix_open && new_file_created && !def_acl) {
4471 if (unx_mode != smb_fname->st.st_ex_mode) {
4472 int ret = SMB_VFS_FCHMOD(fsp, unx_mode);
4473 if (ret == -1) {
4474 DBG_INFO("failed to reset "
4475 "attributes of file %s to 0%o\n",
4476 smb_fname_str_dbg(smb_fname),
4477 (unsigned int)unx_mode);
4481 } else if (new_unx_mode) {
4483 * We only get here in the case of:
4485 * a). Not a POSIX open.
4486 * b). File already existed.
4487 * c). File was overwritten.
4488 * d). Requested DOS attributes didn't match
4489 * the DOS attributes on the existing file.
4491 * In that case new_unx_mode has been set
4492 * equal to the calculated mode (including
4493 * possible inheritance of the mode from the
4494 * containing directory).
4496 * Note this mode was calculated with the
4497 * DOS attribute FILE_ATTRIBUTE_ARCHIVE added,
4498 * so the mode change here is suitable for
4499 * an overwritten file.
4502 if (new_unx_mode != smb_fname->st.st_ex_mode) {
4503 int ret = SMB_VFS_FCHMOD(fsp, new_unx_mode);
4504 if (ret == -1) {
4505 DBG_INFO("failed to reset "
4506 "attributes of file %s to 0%o\n",
4507 smb_fname_str_dbg(smb_fname),
4508 (unsigned int)new_unx_mode);
4514 * Deal with other opens having a modified write time.
4516 if (fsp_getinfo_ask_sharemode(fsp) &&
4517 !is_omit_timespec(&lck_state.write_time))
4519 update_stat_ex_mtime(&fsp->fsp_name->st, lck_state.write_time);
4522 status = NT_STATUS_OK;
4524 unlock:
4525 ulstatus = share_mode_entry_prepare_unlock(&lck_state.prepare_state,
4526 lck_state.cleanup_fn,
4527 &lck_state);
4528 if (!NT_STATUS_IS_OK(ulstatus)) {
4529 DBG_ERR("share_mode_entry_prepare_unlock() failed for %s - %s\n",
4530 smb_fname_str_dbg(smb_fname), nt_errstr(ulstatus));
4531 smb_panic("share_mode_entry_prepare_unlock() failed!");
4534 if (!NT_STATUS_IS_OK(status)) {
4535 fd_close(fsp);
4536 return status;
4539 return NT_STATUS_OK;
4542 static NTSTATUS mkdir_internal(connection_struct *conn,
4543 struct smb_filename *parent_dir_fname, /* parent. */
4544 struct smb_filename *smb_fname_atname, /* atname relative to parent. */
4545 struct smb_filename *smb_dname, /* full pathname from root of share. */
4546 uint32_t file_attributes,
4547 struct files_struct *fsp)
4549 const struct loadparm_substitution *lp_sub =
4550 loadparm_s3_global_substitution();
4551 mode_t mode;
4552 NTSTATUS status;
4553 bool posix_open = false;
4554 bool need_re_stat = false;
4555 uint32_t access_mask = SEC_DIR_ADD_SUBDIR;
4556 struct vfs_open_how how = { .flags = O_RDONLY|O_DIRECTORY, };
4557 int ret;
4559 if (!CAN_WRITE(conn) || (access_mask & ~(conn->share_access))) {
4560 DEBUG(5,("mkdir_internal: failing share access "
4561 "%s\n", lp_servicename(talloc_tos(), lp_sub, SNUM(conn))));
4562 return NT_STATUS_ACCESS_DENIED;
4565 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
4566 posix_open = true;
4567 mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
4568 } else {
4569 mode = unix_mode(conn,
4570 FILE_ATTRIBUTE_DIRECTORY,
4571 smb_dname,
4572 parent_dir_fname->fsp);
4575 status = check_parent_access_fsp(parent_dir_fname->fsp, access_mask);
4576 if(!NT_STATUS_IS_OK(status)) {
4577 DBG_INFO("check_parent_access_fsp "
4578 "on directory %s for path %s returned %s\n",
4579 smb_fname_str_dbg(parent_dir_fname),
4580 smb_dname->base_name,
4581 nt_errstr(status));
4582 return status;
4585 if (lp_inherit_acls(SNUM(conn))) {
4586 if (directory_has_default_acl_fsp(parent_dir_fname->fsp)) {
4587 mode = (0777 & lp_directory_mask(SNUM(conn)));
4591 ret = SMB_VFS_MKDIRAT(conn,
4592 parent_dir_fname->fsp,
4593 smb_fname_atname,
4594 mode);
4595 if (ret != 0) {
4596 return map_nt_error_from_unix(errno);
4600 * Make this a pathref fsp for now. open_directory() will reopen as a
4601 * full fsp.
4603 fsp->fsp_flags.is_pathref = true;
4605 status = fd_openat(parent_dir_fname->fsp, smb_fname_atname, fsp, &how);
4606 if (!NT_STATUS_IS_OK(status)) {
4607 return status;
4610 /* Ensure we're checking for a symlink here.... */
4611 /* We don't want to get caught by a symlink racer. */
4613 status = vfs_stat_fsp(fsp);
4614 if (!NT_STATUS_IS_OK(status)) {
4615 DEBUG(2, ("Could not stat directory '%s' just created: %s\n",
4616 smb_fname_str_dbg(smb_dname), nt_errstr(status)));
4617 return status;
4620 if (!S_ISDIR(smb_dname->st.st_ex_mode)) {
4621 DEBUG(0, ("Directory '%s' just created is not a directory !\n",
4622 smb_fname_str_dbg(smb_dname)));
4623 return NT_STATUS_NOT_A_DIRECTORY;
4626 if (lp_store_dos_attributes(SNUM(conn))) {
4627 file_set_dosmode(conn,
4628 smb_dname,
4629 file_attributes | FILE_ATTRIBUTE_DIRECTORY,
4630 parent_dir_fname,
4631 true);
4634 if (lp_inherit_permissions(SNUM(conn))) {
4635 inherit_access_posix_acl(conn, parent_dir_fname->fsp,
4636 smb_dname, mode);
4637 need_re_stat = true;
4640 if (!posix_open) {
4642 * Check if high bits should have been set,
4643 * then (if bits are missing): add them.
4644 * Consider bits automagically set by UNIX, i.e. SGID bit from parent
4645 * dir.
4647 if ((mode & ~(S_IRWXU|S_IRWXG|S_IRWXO)) &&
4648 (mode & ~smb_dname->st.st_ex_mode)) {
4649 SMB_VFS_FCHMOD(fsp,
4650 (smb_dname->st.st_ex_mode |
4651 (mode & ~smb_dname->st.st_ex_mode)));
4652 need_re_stat = true;
4656 /* Change the owner if required. */
4657 if (lp_inherit_owner(SNUM(conn)) != INHERIT_OWNER_NO) {
4658 change_dir_owner_to_parent_fsp(parent_dir_fname->fsp,
4659 fsp);
4660 need_re_stat = true;
4663 if (need_re_stat) {
4664 status = vfs_stat_fsp(fsp);
4665 if (!NT_STATUS_IS_OK(status)) {
4666 DEBUG(2, ("Could not stat directory '%s' just created: %s\n",
4667 smb_fname_str_dbg(smb_dname), nt_errstr(status)));
4668 return status;
4672 notify_fname(conn, NOTIFY_ACTION_ADDED, FILE_NOTIFY_CHANGE_DIR_NAME,
4673 smb_dname->base_name);
4675 return NT_STATUS_OK;
4678 /****************************************************************************
4679 Open a directory from an NT SMB call.
4680 ****************************************************************************/
4682 static NTSTATUS open_directory(connection_struct *conn,
4683 struct smb_request *req,
4684 uint32_t access_mask,
4685 uint32_t share_access,
4686 uint32_t create_disposition,
4687 uint32_t create_options,
4688 uint32_t file_attributes,
4689 struct smb_filename *parent_dir_fname,
4690 struct smb_filename *smb_fname_atname,
4691 int *pinfo,
4692 struct files_struct *fsp)
4694 struct smb_filename *smb_dname = fsp->fsp_name;
4695 bool dir_existed = VALID_STAT(smb_dname->st);
4696 struct open_ntcreate_lock_state lck_state = {};
4697 bool keep_locked = false;
4698 NTSTATUS status;
4699 struct timespec mtimespec;
4700 int info = 0;
4701 uint32_t need_fd_access;
4702 NTSTATUS ulstatus;
4704 if (is_ntfs_stream_smb_fname(smb_dname)) {
4705 DEBUG(2, ("open_directory: %s is a stream name!\n",
4706 smb_fname_str_dbg(smb_dname)));
4707 return NT_STATUS_NOT_A_DIRECTORY;
4710 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS)) {
4711 /* Ensure we have a directory attribute. */
4712 file_attributes |= FILE_ATTRIBUTE_DIRECTORY;
4715 DBG_INFO("opening directory %s, access_mask = 0x%"PRIx32", "
4716 "share_access = 0x%"PRIx32" create_options = 0x%"PRIx32", "
4717 "create_disposition = 0x%"PRIx32", "
4718 "file_attributes = 0x%"PRIx32"\n",
4719 smb_fname_str_dbg(smb_dname),
4720 access_mask,
4721 share_access,
4722 create_options,
4723 create_disposition,
4724 file_attributes);
4726 status = smbd_calculate_access_mask_fsp(parent_dir_fname->fsp,
4727 smb_dname->fsp,
4728 false,
4729 access_mask,
4730 &access_mask);
4731 if (!NT_STATUS_IS_OK(status)) {
4732 DBG_DEBUG("smbd_calculate_access_mask_fsp "
4733 "on file %s returned %s\n",
4734 smb_fname_str_dbg(smb_dname),
4735 nt_errstr(status));
4736 return status;
4739 if ((access_mask & SEC_FLAG_SYSTEM_SECURITY) &&
4740 !security_token_has_privilege(get_current_nttok(conn),
4741 SEC_PRIV_SECURITY)) {
4742 DEBUG(10, ("open_directory: open on %s "
4743 "failed - SEC_FLAG_SYSTEM_SECURITY denied.\n",
4744 smb_fname_str_dbg(smb_dname)));
4745 return NT_STATUS_PRIVILEGE_NOT_HELD;
4748 switch( create_disposition ) {
4749 case FILE_OPEN:
4751 if (!dir_existed) {
4752 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4755 info = FILE_WAS_OPENED;
4756 break;
4758 case FILE_CREATE:
4760 /* If directory exists error. If directory doesn't
4761 * exist create. */
4763 if (dir_existed) {
4764 status = NT_STATUS_OBJECT_NAME_COLLISION;
4765 DEBUG(2, ("open_directory: unable to create "
4766 "%s. Error was %s\n",
4767 smb_fname_str_dbg(smb_dname),
4768 nt_errstr(status)));
4769 return status;
4772 if (smb_fname_atname->twrp != 0) {
4773 return NT_STATUS_MEDIA_WRITE_PROTECTED;
4776 status = mkdir_internal(conn,
4777 parent_dir_fname,
4778 smb_fname_atname,
4779 smb_dname,
4780 file_attributes,
4781 fsp);
4783 if (!NT_STATUS_IS_OK(status)) {
4784 DEBUG(2, ("open_directory: unable to create "
4785 "%s. Error was %s\n",
4786 smb_fname_str_dbg(smb_dname),
4787 nt_errstr(status)));
4788 return status;
4791 info = FILE_WAS_CREATED;
4792 break;
4794 case FILE_OPEN_IF:
4796 * If directory exists open. If directory doesn't
4797 * exist create.
4800 if (dir_existed) {
4801 status = NT_STATUS_OK;
4802 info = FILE_WAS_OPENED;
4803 } else {
4804 if (smb_fname_atname->twrp != 0) {
4805 return NT_STATUS_MEDIA_WRITE_PROTECTED;
4807 status = mkdir_internal(conn,
4808 parent_dir_fname,
4809 smb_fname_atname,
4810 smb_dname,
4811 file_attributes,
4812 fsp);
4814 if (NT_STATUS_IS_OK(status)) {
4815 info = FILE_WAS_CREATED;
4816 } else {
4817 int ret;
4818 /* Cope with create race. */
4819 if (!NT_STATUS_EQUAL(status,
4820 NT_STATUS_OBJECT_NAME_COLLISION)) {
4821 DEBUG(2, ("open_directory: unable to create "
4822 "%s. Error was %s\n",
4823 smb_fname_str_dbg(smb_dname),
4824 nt_errstr(status)));
4825 return status;
4829 * If mkdir_internal() returned
4830 * NT_STATUS_OBJECT_NAME_COLLISION
4831 * we still must lstat the path.
4833 ret = SMB_VFS_FSTATAT(
4834 conn,
4835 parent_dir_fname->fsp,
4836 smb_fname_atname,
4837 &smb_dname->st,
4838 AT_SYMLINK_NOFOLLOW);
4839 if (ret == -1) {
4840 DEBUG(2, ("Could not stat "
4841 "directory '%s' just "
4842 "opened: %s\n",
4843 smb_fname_str_dbg(
4844 smb_dname),
4845 strerror(errno)));
4846 return map_nt_error_from_unix(
4847 errno);
4850 info = FILE_WAS_OPENED;
4854 break;
4856 case FILE_SUPERSEDE:
4857 case FILE_OVERWRITE:
4858 case FILE_OVERWRITE_IF:
4859 default:
4860 DEBUG(5,("open_directory: invalid create_disposition "
4861 "0x%x for directory %s\n",
4862 (unsigned int)create_disposition,
4863 smb_fname_str_dbg(smb_dname)));
4864 return NT_STATUS_INVALID_PARAMETER;
4867 if(!S_ISDIR(smb_dname->st.st_ex_mode)) {
4868 DEBUG(5,("open_directory: %s is not a directory !\n",
4869 smb_fname_str_dbg(smb_dname)));
4870 return NT_STATUS_NOT_A_DIRECTORY;
4874 * Setup the files_struct for it.
4877 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_dname->st);
4878 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
4879 fsp->file_pid = req ? req->smbpid : 0;
4880 fsp->fsp_flags.can_lock = false;
4881 fsp->fsp_flags.can_read = false;
4882 fsp->fsp_flags.can_write = false;
4884 fh_set_private_options(fsp->fh, 0);
4886 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
4888 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
4889 fsp->print_file = NULL;
4890 fsp->fsp_flags.modified = false;
4891 fsp->oplock_type = NO_OPLOCK;
4892 fsp->sent_oplock_break = NO_BREAK_SENT;
4893 fsp->fsp_flags.is_directory = true;
4894 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
4895 fsp->posix_flags |= FSP_POSIX_FLAGS_ALL;
4898 /* Don't store old timestamps for directory
4899 handles in the internal database. We don't
4900 update them in there if new objects
4901 are created in the directory. Currently
4902 we only update timestamps on file writes.
4903 See bug #9870.
4905 mtimespec = make_omit_timespec();
4908 * Obviously for FILE_LIST_DIRECTORY we need to reopen to get an fd
4909 * usable for reading a directory. SMB2_FLUSH may be called on
4910 * directories opened with FILE_ADD_FILE and FILE_ADD_SUBDIRECTORY so
4911 * for those we need to reopen as well.
4913 need_fd_access =
4914 FILE_LIST_DIRECTORY |
4915 FILE_ADD_FILE |
4916 FILE_ADD_SUBDIRECTORY;
4918 if (access_mask & need_fd_access) {
4919 struct vfs_open_how how = {
4920 .flags = O_RDONLY | O_DIRECTORY,
4922 bool file_created;
4924 status = reopen_from_fsp(parent_dir_fname->fsp,
4925 smb_fname_atname,
4926 fsp,
4927 &how,
4928 &file_created);
4929 if (!NT_STATUS_IS_OK(status)) {
4930 DBG_INFO("Could not open fd for [%s]: %s\n",
4931 smb_fname_str_dbg(smb_dname),
4932 nt_errstr(status));
4933 return status;
4937 status = vfs_stat_fsp(fsp);
4938 if (!NT_STATUS_IS_OK(status)) {
4939 fd_close(fsp);
4940 return status;
4943 if(!S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
4944 DEBUG(5,("open_directory: %s is not a directory !\n",
4945 smb_fname_str_dbg(smb_dname)));
4946 fd_close(fsp);
4947 return NT_STATUS_NOT_A_DIRECTORY;
4950 /* Ensure there was no race condition. We need to check
4951 * dev/inode but not permissions, as these can change
4952 * legitimately */
4953 if (!check_same_dev_ino(&smb_dname->st, &fsp->fsp_name->st)) {
4954 DEBUG(5,("open_directory: stat struct differs for "
4955 "directory %s.\n",
4956 smb_fname_str_dbg(smb_dname)));
4957 fd_close(fsp);
4958 return NT_STATUS_ACCESS_DENIED;
4961 if (info == FILE_WAS_OPENED) {
4962 status = smbd_check_access_rights_fsp(parent_dir_fname->fsp,
4963 fsp,
4964 false,
4965 access_mask);
4966 if (!NT_STATUS_IS_OK(status)) {
4967 DBG_DEBUG("smbd_check_access_rights_fsp on "
4968 "file %s failed with %s\n",
4969 fsp_str_dbg(fsp),
4970 nt_errstr(status));
4971 fd_close(fsp);
4972 return status;
4977 * If we created a new directory or going to delete it later,
4978 * we should keep * the share_mode_lock (g_lock) until we call
4979 * share_mode_entry_prepare_unlock()
4981 if (info != FILE_WAS_OPENED) {
4982 keep_locked = true;
4983 } else if (create_options & FILE_DELETE_ON_CLOSE) {
4984 keep_locked = true;
4987 lck_state = (struct open_ntcreate_lock_state) {
4988 .fsp = fsp,
4989 .object_type = "directory",
4990 .req = req,
4991 .create_disposition = create_disposition,
4992 .access_mask = access_mask,
4993 .share_access = share_access,
4994 .oplock_request = NO_OPLOCK,
4995 .lease = NULL,
4996 .first_open_attempt = true,
4997 .keep_locked = keep_locked,
5000 status = share_mode_entry_prepare_lock_add(&lck_state.prepare_state,
5001 fsp->file_id,
5002 conn->connectpath,
5003 smb_dname,
5004 &mtimespec,
5005 open_ntcreate_lock_add_entry,
5006 &lck_state);
5007 if (!NT_STATUS_IS_OK(status)) {
5008 DBG_ERR("share_mode_entry_prepare_lock_add() failed for %s - %s\n",
5009 smb_fname_str_dbg(smb_dname), nt_errstr(status));
5010 fd_close(fsp);
5011 return status;
5014 status = lck_state.status;
5015 if (!NT_STATUS_IS_OK(status)) {
5016 fd_close(fsp);
5017 return status;
5021 * From here we need to use 'goto unlock;' instead of return !!!
5024 /* For directories the delete on close bit at open time seems
5025 always to be honored on close... See test 19 in Samba4 BASE-DELETE. */
5026 if (create_options & FILE_DELETE_ON_CLOSE) {
5027 status = can_set_delete_on_close(fsp, 0);
5028 if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
5029 lck_state.cleanup_fn =
5030 open_ntcreate_lock_cleanup_entry;
5031 goto unlock;
5034 if (NT_STATUS_IS_OK(status)) {
5035 /* Note that here we set the *initial* delete on close flag,
5036 not the regular one. The magic gets handled in close. */
5037 fsp->fsp_flags.initial_delete_on_close = true;
5042 * Deal with other opens having a modified write time.
5044 if (!is_omit_timespec(&lck_state.write_time)) {
5045 update_stat_ex_mtime(&fsp->fsp_name->st, lck_state.write_time);
5048 if (pinfo) {
5049 *pinfo = info;
5052 status = NT_STATUS_OK;
5054 unlock:
5055 ulstatus = share_mode_entry_prepare_unlock(&lck_state.prepare_state,
5056 lck_state.cleanup_fn,
5057 &lck_state);
5058 if (!NT_STATUS_IS_OK(ulstatus)) {
5059 DBG_ERR("share_mode_entry_prepare_unlock() failed for %s - %s\n",
5060 smb_fname_str_dbg(smb_dname), nt_errstr(ulstatus));
5061 smb_panic("share_mode_entry_prepare_unlock() failed!");
5064 if (!NT_STATUS_IS_OK(status)) {
5065 fd_close(fsp);
5066 return status;
5069 return NT_STATUS_OK;
5072 NTSTATUS create_directory(connection_struct *conn,
5073 struct smb_request *req,
5074 struct files_struct *dirfsp,
5075 struct smb_filename *smb_dname)
5077 NTSTATUS status;
5078 files_struct *fsp;
5080 status = SMB_VFS_CREATE_FILE(
5081 conn, /* conn */
5082 req, /* req */
5083 dirfsp, /* dirfsp */
5084 smb_dname, /* fname */
5085 FILE_READ_ATTRIBUTES, /* access_mask */
5086 FILE_SHARE_NONE, /* share_access */
5087 FILE_CREATE, /* create_disposition*/
5088 FILE_DIRECTORY_FILE, /* create_options */
5089 FILE_ATTRIBUTE_DIRECTORY, /* file_attributes */
5090 0, /* oplock_request */
5091 NULL, /* lease */
5092 0, /* allocation_size */
5093 0, /* private_flags */
5094 NULL, /* sd */
5095 NULL, /* ea_list */
5096 &fsp, /* result */
5097 NULL, /* pinfo */
5098 NULL, NULL); /* create context */
5100 if (NT_STATUS_IS_OK(status)) {
5101 close_file_free(req, &fsp, NORMAL_CLOSE);
5104 return status;
5107 /****************************************************************************
5108 Receive notification that one of our open files has been renamed by another
5109 smbd process.
5110 ****************************************************************************/
5112 void msg_file_was_renamed(struct messaging_context *msg_ctx,
5113 void *private_data,
5114 uint32_t msg_type,
5115 struct server_id src,
5116 DATA_BLOB *data)
5118 struct file_rename_message *msg = NULL;
5119 enum ndr_err_code ndr_err;
5120 files_struct *fsp;
5121 struct smb_filename *smb_fname = NULL;
5122 struct smbd_server_connection *sconn =
5123 talloc_get_type_abort(private_data,
5124 struct smbd_server_connection);
5126 msg = talloc(talloc_tos(), struct file_rename_message);
5127 if (msg == NULL) {
5128 DBG_WARNING("talloc failed\n");
5129 return;
5132 ndr_err = ndr_pull_struct_blob_all(
5133 data,
5134 msg,
5135 msg,
5136 (ndr_pull_flags_fn_t)ndr_pull_file_rename_message);
5137 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
5138 DBG_DEBUG("ndr_pull_file_rename_message failed: %s\n",
5139 ndr_errstr(ndr_err));
5140 goto out;
5142 if (DEBUGLEVEL >= 10) {
5143 struct server_id_buf buf;
5144 DBG_DEBUG("Got rename message from %s\n",
5145 server_id_str_buf(src, &buf));
5146 NDR_PRINT_DEBUG(file_rename_message, msg);
5149 /* stream_name must always be NULL if there is no stream. */
5150 if ((msg->stream_name != NULL) && (msg->stream_name[0] == '\0')) {
5151 msg->stream_name = NULL;
5154 smb_fname = synthetic_smb_fname(msg,
5155 msg->base_name,
5156 msg->stream_name,
5157 NULL,
5160 if (smb_fname == NULL) {
5161 DBG_DEBUG("synthetic_smb_fname failed\n");
5162 goto out;
5165 fsp = file_find_dif(sconn, msg->id, msg->share_file_id);
5166 if (fsp == NULL) {
5167 DBG_DEBUG("fsp not found\n");
5168 goto out;
5171 if (strcmp(fsp->conn->connectpath, msg->servicepath) == 0) {
5172 SMB_STRUCT_STAT fsp_orig_sbuf;
5173 NTSTATUS status;
5174 DBG_DEBUG("renaming file %s from %s -> %s\n",
5175 fsp_fnum_dbg(fsp),
5176 fsp_str_dbg(fsp),
5177 smb_fname_str_dbg(smb_fname));
5180 * The incoming smb_fname here has an
5181 * invalid stat struct from synthetic_smb_fname()
5182 * above.
5183 * Preserve the existing stat from the
5184 * open fsp after fsp_set_smb_fname()
5185 * overwrites with the invalid stat.
5187 * (We could just copy this into
5188 * smb_fname->st, but keep this code
5189 * identical to the fix in rename_open_files()
5190 * for clarity.
5192 * We will do an fstat before returning
5193 * any of this metadata to the client anyway.
5195 fsp_orig_sbuf = fsp->fsp_name->st;
5196 status = fsp_set_smb_fname(fsp, smb_fname);
5197 if (!NT_STATUS_IS_OK(status)) {
5198 DBG_DEBUG("fsp_set_smb_fname failed: %s\n",
5199 nt_errstr(status));
5201 fsp->fsp_name->st = fsp_orig_sbuf;
5202 } else {
5203 /* TODO. JRA. */
5205 * Now we have the complete path we can work out if
5206 * this is actually within this share and adjust
5207 * newname accordingly.
5209 DBG_DEBUG("share mismatch (sharepath %s not sharepath %s) "
5210 "%s from %s -> %s\n",
5211 fsp->conn->connectpath,
5212 msg->servicepath,
5213 fsp_fnum_dbg(fsp),
5214 fsp_str_dbg(fsp),
5215 smb_fname_str_dbg(smb_fname));
5217 out:
5218 TALLOC_FREE(msg);
5222 * If a main file is opened for delete, all streams need to be checked for
5223 * !FILE_SHARE_DELETE. Do this by opening with DELETE_ACCESS.
5224 * If that works, delete them all by setting the delete on close and close.
5227 static NTSTATUS open_streams_for_delete(connection_struct *conn,
5228 const struct smb_filename *smb_fname)
5230 struct stream_struct *stream_info = NULL;
5231 files_struct **streams = NULL;
5232 int j;
5233 unsigned int i, num_streams = 0;
5234 TALLOC_CTX *frame = talloc_stackframe();
5235 const struct smb_filename *pathref = NULL;
5236 NTSTATUS status;
5238 if (smb_fname->fsp == NULL) {
5239 struct smb_filename *tmp = NULL;
5240 status = synthetic_pathref(frame,
5241 conn->cwd_fsp,
5242 smb_fname->base_name,
5243 NULL,
5244 NULL,
5245 smb_fname->twrp,
5246 smb_fname->flags,
5247 &tmp);
5248 if (!NT_STATUS_IS_OK(status)) {
5249 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
5250 || NT_STATUS_EQUAL(status,
5251 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
5252 DBG_DEBUG("no streams around\n");
5253 TALLOC_FREE(frame);
5254 return NT_STATUS_OK;
5256 DBG_DEBUG("synthetic_pathref failed: %s\n",
5257 nt_errstr(status));
5258 goto fail;
5260 pathref = tmp;
5261 } else {
5262 pathref = smb_fname;
5264 status = vfs_fstreaminfo(pathref->fsp, talloc_tos(),
5265 &num_streams, &stream_info);
5267 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
5268 || NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
5269 DEBUG(10, ("no streams around\n"));
5270 TALLOC_FREE(frame);
5271 return NT_STATUS_OK;
5274 if (!NT_STATUS_IS_OK(status)) {
5275 DEBUG(10, ("vfs_fstreaminfo failed: %s\n",
5276 nt_errstr(status)));
5277 goto fail;
5280 DEBUG(10, ("open_streams_for_delete found %d streams\n",
5281 num_streams));
5283 if (num_streams == 0) {
5284 TALLOC_FREE(frame);
5285 return NT_STATUS_OK;
5288 streams = talloc_array(talloc_tos(), files_struct *, num_streams);
5289 if (streams == NULL) {
5290 DEBUG(0, ("talloc failed\n"));
5291 status = NT_STATUS_NO_MEMORY;
5292 goto fail;
5295 for (i=0; i<num_streams; i++) {
5296 struct smb_filename *smb_fname_cp;
5298 if (strequal(stream_info[i].name, "::$DATA")) {
5299 streams[i] = NULL;
5300 continue;
5303 smb_fname_cp = synthetic_smb_fname(talloc_tos(),
5304 smb_fname->base_name,
5305 stream_info[i].name,
5306 NULL,
5307 smb_fname->twrp,
5308 (smb_fname->flags &
5309 ~SMB_FILENAME_POSIX_PATH));
5310 if (smb_fname_cp == NULL) {
5311 status = NT_STATUS_NO_MEMORY;
5312 goto fail;
5315 status = openat_pathref_fsp(conn->cwd_fsp, smb_fname_cp);
5316 if (!NT_STATUS_IS_OK(status)) {
5317 DBG_DEBUG("Unable to open stream [%s]: %s\n",
5318 smb_fname_str_dbg(smb_fname_cp),
5319 nt_errstr(status));
5320 TALLOC_FREE(smb_fname_cp);
5321 break;
5324 status = SMB_VFS_CREATE_FILE(
5325 conn, /* conn */
5326 NULL, /* req */
5327 NULL, /* dirfsp */
5328 smb_fname_cp, /* fname */
5329 DELETE_ACCESS, /* access_mask */
5330 (FILE_SHARE_READ | /* share_access */
5331 FILE_SHARE_WRITE | FILE_SHARE_DELETE),
5332 FILE_OPEN, /* create_disposition*/
5333 0, /* create_options */
5334 FILE_ATTRIBUTE_NORMAL, /* file_attributes */
5335 0, /* oplock_request */
5336 NULL, /* lease */
5337 0, /* allocation_size */
5338 0, /* private_flags */
5339 NULL, /* sd */
5340 NULL, /* ea_list */
5341 &streams[i], /* result */
5342 NULL, /* pinfo */
5343 NULL, NULL); /* create context */
5345 if (!NT_STATUS_IS_OK(status)) {
5346 DEBUG(10, ("Could not open stream %s: %s\n",
5347 smb_fname_str_dbg(smb_fname_cp),
5348 nt_errstr(status)));
5350 TALLOC_FREE(smb_fname_cp);
5351 break;
5353 TALLOC_FREE(smb_fname_cp);
5357 * don't touch the variable "status" beyond this point :-)
5360 for (j = i-1 ; j >= 0; j--) {
5361 if (streams[j] == NULL) {
5362 continue;
5365 DEBUG(10, ("Closing stream # %d, %s\n", j,
5366 fsp_str_dbg(streams[j])));
5367 close_file_free(NULL, &streams[j], NORMAL_CLOSE);
5370 fail:
5371 TALLOC_FREE(frame);
5372 return status;
5375 /*********************************************************************
5376 Create a default ACL by inheriting from the parent. If no inheritance
5377 from the parent available, don't set anything. This will leave the actual
5378 permissions the new file or directory already got from the filesystem
5379 as the NT ACL when read.
5380 *********************************************************************/
5382 static NTSTATUS inherit_new_acl(files_struct *dirfsp, files_struct *fsp)
5384 TALLOC_CTX *frame = talloc_stackframe();
5385 struct security_descriptor *parent_desc = NULL;
5386 NTSTATUS status = NT_STATUS_OK;
5387 struct security_descriptor *psd = NULL;
5388 const struct dom_sid *owner_sid = NULL;
5389 const struct dom_sid *group_sid = NULL;
5390 uint32_t security_info_sent = (SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL);
5391 struct security_token *token = fsp->conn->session_info->security_token;
5392 bool inherit_owner =
5393 (lp_inherit_owner(SNUM(fsp->conn)) == INHERIT_OWNER_WINDOWS_AND_UNIX);
5394 bool inheritable_components = false;
5395 bool try_builtin_administrators = false;
5396 const struct dom_sid *BA_U_sid = NULL;
5397 const struct dom_sid *BA_G_sid = NULL;
5398 bool try_system = false;
5399 const struct dom_sid *SY_U_sid = NULL;
5400 const struct dom_sid *SY_G_sid = NULL;
5401 size_t size = 0;
5402 bool ok;
5404 status = SMB_VFS_FGET_NT_ACL(dirfsp,
5405 (SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL),
5406 frame,
5407 &parent_desc);
5408 if (!NT_STATUS_IS_OK(status)) {
5409 TALLOC_FREE(frame);
5410 return status;
5413 inheritable_components = sd_has_inheritable_components(parent_desc,
5414 fsp->fsp_flags.is_directory);
5416 if (!inheritable_components && !inherit_owner) {
5417 TALLOC_FREE(frame);
5418 /* Nothing to inherit and not setting owner. */
5419 return NT_STATUS_OK;
5422 /* Create an inherited descriptor from the parent. */
5424 if (DEBUGLEVEL >= 10) {
5425 DEBUG(10,("inherit_new_acl: parent acl for %s is:\n",
5426 fsp_str_dbg(fsp) ));
5427 NDR_PRINT_DEBUG(security_descriptor, parent_desc);
5430 /* Inherit from parent descriptor if "inherit owner" set. */
5431 if (inherit_owner) {
5432 owner_sid = parent_desc->owner_sid;
5433 group_sid = parent_desc->group_sid;
5436 if (owner_sid == NULL) {
5437 if (security_token_has_builtin_administrators(token)) {
5438 try_builtin_administrators = true;
5439 } else if (security_token_is_system(token)) {
5440 try_builtin_administrators = true;
5441 try_system = true;
5445 if (group_sid == NULL &&
5446 token->num_sids == PRIMARY_GROUP_SID_INDEX)
5448 if (security_token_is_system(token)) {
5449 try_builtin_administrators = true;
5450 try_system = true;
5454 if (try_builtin_administrators) {
5455 struct unixid ids = { .id = 0 };
5457 ok = sids_to_unixids(&global_sid_Builtin_Administrators, 1, &ids);
5458 if (ok) {
5459 switch (ids.type) {
5460 case ID_TYPE_BOTH:
5461 BA_U_sid = &global_sid_Builtin_Administrators;
5462 BA_G_sid = &global_sid_Builtin_Administrators;
5463 break;
5464 case ID_TYPE_UID:
5465 BA_U_sid = &global_sid_Builtin_Administrators;
5466 break;
5467 case ID_TYPE_GID:
5468 BA_G_sid = &global_sid_Builtin_Administrators;
5469 break;
5470 default:
5471 break;
5476 if (try_system) {
5477 struct unixid ids = { .id = 0 };
5479 ok = sids_to_unixids(&global_sid_System, 1, &ids);
5480 if (ok) {
5481 switch (ids.type) {
5482 case ID_TYPE_BOTH:
5483 SY_U_sid = &global_sid_System;
5484 SY_G_sid = &global_sid_System;
5485 break;
5486 case ID_TYPE_UID:
5487 SY_U_sid = &global_sid_System;
5488 break;
5489 case ID_TYPE_GID:
5490 SY_G_sid = &global_sid_System;
5491 break;
5492 default:
5493 break;
5498 if (owner_sid == NULL) {
5499 owner_sid = BA_U_sid;
5502 if (owner_sid == NULL) {
5503 owner_sid = SY_U_sid;
5506 if (group_sid == NULL) {
5507 group_sid = SY_G_sid;
5510 if (try_system && group_sid == NULL) {
5511 group_sid = BA_G_sid;
5514 if (owner_sid == NULL) {
5515 owner_sid = &token->sids[PRIMARY_USER_SID_INDEX];
5517 if (group_sid == NULL) {
5518 if (token->num_sids == PRIMARY_GROUP_SID_INDEX) {
5519 group_sid = &token->sids[PRIMARY_USER_SID_INDEX];
5520 } else {
5521 group_sid = &token->sids[PRIMARY_GROUP_SID_INDEX];
5525 status = se_create_child_secdesc(frame,
5526 &psd,
5527 &size,
5528 parent_desc,
5529 owner_sid,
5530 group_sid,
5531 fsp->fsp_flags.is_directory);
5532 if (!NT_STATUS_IS_OK(status)) {
5533 TALLOC_FREE(frame);
5534 return status;
5537 /* If inheritable_components == false,
5538 se_create_child_secdesc()
5539 creates a security descriptor with a NULL dacl
5540 entry, but with SEC_DESC_DACL_PRESENT. We need
5541 to remove that flag. */
5543 if (!inheritable_components) {
5544 security_info_sent &= ~SECINFO_DACL;
5545 psd->type &= ~SEC_DESC_DACL_PRESENT;
5548 if (DEBUGLEVEL >= 10) {
5549 DEBUG(10,("inherit_new_acl: child acl for %s is:\n",
5550 fsp_str_dbg(fsp) ));
5551 NDR_PRINT_DEBUG(security_descriptor, psd);
5554 if (inherit_owner) {
5555 /* We need to be root to force this. */
5556 become_root();
5558 status = SMB_VFS_FSET_NT_ACL(metadata_fsp(fsp),
5559 security_info_sent,
5560 psd);
5561 if (inherit_owner) {
5562 unbecome_root();
5564 TALLOC_FREE(frame);
5565 return status;
5569 * If we already have a lease, it must match the new file id. [MS-SMB2]
5570 * 3.3.5.9.8 speaks about INVALID_PARAMETER if an already used lease key is
5571 * used for a different file name.
5574 struct lease_match_state {
5575 /* Input parameters. */
5576 TALLOC_CTX *mem_ctx;
5577 const char *servicepath;
5578 const struct smb_filename *fname;
5579 bool file_existed;
5580 struct file_id id;
5581 /* Return parameters. */
5582 uint32_t num_file_ids;
5583 struct file_id *ids;
5584 NTSTATUS match_status;
5587 /*************************************************************
5588 File doesn't exist but this lease key+guid is already in use.
5590 This is only allowable in the dynamic share case where the
5591 service path must be different.
5593 There is a small race condition here in the multi-connection
5594 case where a client sends two create calls on different connections,
5595 where the file doesn't exist and one smbd creates the leases_db
5596 entry first, but this will get fixed by the multichannel cleanup
5597 when all identical client_guids get handled by a single smbd.
5598 **************************************************************/
5600 static void lease_match_parser_new_file(
5601 uint32_t num_files,
5602 const struct leases_db_file *files,
5603 struct lease_match_state *state)
5605 uint32_t i;
5607 for (i = 0; i < num_files; i++) {
5608 const struct leases_db_file *f = &files[i];
5609 if (strequal(state->servicepath, f->servicepath)) {
5610 state->match_status = NT_STATUS_INVALID_PARAMETER;
5611 return;
5615 /* Dynamic share case. Break leases on all other files. */
5616 state->match_status = leases_db_copy_file_ids(state->mem_ctx,
5617 num_files,
5618 files,
5619 &state->ids);
5620 if (!NT_STATUS_IS_OK(state->match_status)) {
5621 return;
5624 state->num_file_ids = num_files;
5625 state->match_status = NT_STATUS_OPLOCK_NOT_GRANTED;
5626 return;
5629 static void lease_match_parser(
5630 uint32_t num_files,
5631 const struct leases_db_file *files,
5632 void *private_data)
5634 struct lease_match_state *state =
5635 (struct lease_match_state *)private_data;
5636 uint32_t i;
5638 if (!state->file_existed) {
5640 * Deal with name mismatch or
5641 * possible dynamic share case separately
5642 * to make code clearer.
5644 lease_match_parser_new_file(num_files,
5645 files,
5646 state);
5647 return;
5650 /* File existed. */
5651 state->match_status = NT_STATUS_OK;
5653 for (i = 0; i < num_files; i++) {
5654 const struct leases_db_file *f = &files[i];
5656 /* Everything should be the same. */
5657 if (!file_id_equal(&state->id, &f->id)) {
5659 * The client asked for a lease on a
5660 * file that doesn't match the file_id
5661 * in the database.
5663 * Maybe this is a dynamic share, i.e.
5664 * a share where the servicepath is
5665 * different for different users (e.g.
5666 * the [HOMES] share.
5668 * If the servicepath is different, but the requested
5669 * file name + stream name is the same then this is
5670 * a dynamic share, the client is using the same share
5671 * name and doesn't know that the underlying servicepath
5672 * is different. It was expecting a lease on the
5673 * same file. Return NT_STATUS_OPLOCK_NOT_GRANTED
5674 * to break leases
5676 * Otherwise the client has messed up, or is
5677 * testing our error codes, so return
5678 * NT_STATUS_INVALID_PARAMETER.
5680 if (!strequal(f->servicepath, state->servicepath) &&
5681 strequal(f->base_name, state->fname->base_name) &&
5682 strequal(f->stream_name, state->fname->stream_name))
5685 * Name is the same but servicepath is
5686 * different, dynamic share. Break leases.
5688 state->match_status =
5689 NT_STATUS_OPLOCK_NOT_GRANTED;
5690 } else {
5691 state->match_status =
5692 NT_STATUS_INVALID_PARAMETER;
5694 break;
5696 if (!strequal(f->servicepath, state->servicepath)) {
5697 state->match_status = NT_STATUS_INVALID_PARAMETER;
5698 break;
5700 if (!strequal(f->base_name, state->fname->base_name)) {
5701 state->match_status = NT_STATUS_INVALID_PARAMETER;
5702 break;
5704 if (!strequal(f->stream_name, state->fname->stream_name)) {
5705 state->match_status = NT_STATUS_INVALID_PARAMETER;
5706 break;
5710 if (NT_STATUS_IS_OK(state->match_status)) {
5712 * Common case - just opening another handle on a
5713 * file on a non-dynamic share.
5715 return;
5718 if (NT_STATUS_EQUAL(state->match_status, NT_STATUS_INVALID_PARAMETER)) {
5719 /* Mismatched path. Error back to client. */
5720 return;
5724 * File id mismatch. Dynamic share case NT_STATUS_OPLOCK_NOT_GRANTED.
5725 * Don't allow leases.
5728 state->match_status = leases_db_copy_file_ids(state->mem_ctx,
5729 num_files,
5730 files,
5731 &state->ids);
5732 if (!NT_STATUS_IS_OK(state->match_status)) {
5733 return;
5736 state->num_file_ids = num_files;
5737 state->match_status = NT_STATUS_OPLOCK_NOT_GRANTED;
5738 return;
5741 struct lease_match_break_state {
5742 struct messaging_context *msg_ctx;
5743 const struct smb2_lease_key *lease_key;
5744 struct file_id id;
5746 bool found_lease;
5747 uint16_t version;
5748 uint16_t epoch;
5751 static bool lease_match_break_fn(
5752 struct share_mode_entry *e,
5753 void *private_data)
5755 struct lease_match_break_state *state = private_data;
5756 bool stale, equal;
5757 uint32_t e_lease_type = SMB2_LEASE_NONE;
5758 NTSTATUS status;
5760 stale = share_entry_stale_pid(e);
5761 if (stale) {
5762 return false;
5765 equal = smb2_lease_key_equal(&e->lease_key, state->lease_key);
5766 if (!equal) {
5767 return false;
5770 status = leases_db_get(
5771 &e->client_guid,
5772 &e->lease_key,
5773 &state->id,
5774 &e_lease_type, /* current_state */
5775 NULL, /* breaking */
5776 NULL, /* breaking_to_requested */
5777 NULL, /* breaking_to_required */
5778 &state->version, /* lease_version */
5779 &state->epoch); /* epoch */
5780 if (NT_STATUS_IS_OK(status)) {
5781 state->found_lease = true;
5782 } else {
5783 DBG_WARNING("Could not find version/epoch: %s\n",
5784 nt_errstr(status));
5785 return false;
5788 if (e_lease_type == SMB2_LEASE_NONE) {
5789 return false;
5791 send_break_message(state->msg_ctx, &state->id, e, SMB2_LEASE_NONE);
5794 * Windows 7 and 8 lease clients are broken in that they will
5795 * not respond to lease break requests whilst waiting for an
5796 * outstanding open request on that lease handle on the same
5797 * TCP connection, due to holding an internal inode lock.
5799 * This means we can't reschedule ourselves here, but must
5800 * return from the create.
5802 * Work around:
5804 * Send the breaks and then return SMB2_LEASE_NONE in the
5805 * lease handle to cause them to acknowledge the lease
5806 * break. Consultation with Microsoft engineering confirmed
5807 * this approach is safe.
5810 return false;
5813 static void lease_match_fid_fn(struct share_mode_lock *lck,
5814 void *private_data)
5816 bool ok;
5818 ok = share_mode_forall_leases(lck, lease_match_break_fn, private_data);
5819 if (!ok) {
5820 DBG_DEBUG("share_mode_forall_leases failed\n");
5824 static NTSTATUS lease_match(connection_struct *conn,
5825 struct smb_request *req,
5826 const struct smb2_lease_key *lease_key,
5827 const char *servicepath,
5828 const struct smb_filename *fname,
5829 uint16_t *p_version,
5830 uint16_t *p_epoch)
5832 struct smbd_server_connection *sconn = req->sconn;
5833 TALLOC_CTX *tos = talloc_tos();
5834 struct lease_match_state state = {
5835 .mem_ctx = tos,
5836 .servicepath = servicepath,
5837 .fname = fname,
5838 .match_status = NT_STATUS_OK
5840 uint32_t i;
5841 NTSTATUS status;
5843 state.file_existed = VALID_STAT(fname->st);
5844 if (state.file_existed) {
5845 state.id = vfs_file_id_from_sbuf(conn, &fname->st);
5848 status = leases_db_parse(&sconn->client->global->client_guid,
5849 lease_key, lease_match_parser, &state);
5850 if (!NT_STATUS_IS_OK(status)) {
5852 * Not found or error means okay: We can make the lease pass
5854 return NT_STATUS_OK;
5856 if (!NT_STATUS_EQUAL(state.match_status, NT_STATUS_OPLOCK_NOT_GRANTED)) {
5858 * Anything but NT_STATUS_OPLOCK_NOT_GRANTED, let the caller
5859 * deal with it.
5861 return state.match_status;
5864 /* We have to break all existing leases. */
5865 for (i = 0; i < state.num_file_ids; i++) {
5866 struct lease_match_break_state break_state = {
5867 .msg_ctx = conn->sconn->msg_ctx,
5868 .lease_key = lease_key,
5871 if (file_id_equal(&state.ids[i], &state.id)) {
5872 /* Don't need to break our own file. */
5873 continue;
5876 break_state.id = state.ids[i];
5878 status = share_mode_do_locked_vfs_denied(break_state.id,
5879 lease_match_fid_fn,
5880 &break_state);
5881 if (!NT_STATUS_IS_OK(status)) {
5882 /* Race condition - file already closed. */
5883 continue;
5886 if (break_state.found_lease) {
5887 *p_version = break_state.version;
5888 *p_epoch = break_state.epoch;
5892 * Ensure we don't grant anything more so we
5893 * never upgrade.
5895 return NT_STATUS_OPLOCK_NOT_GRANTED;
5899 * Wrapper around open_file_ntcreate and open_directory
5902 static NTSTATUS create_file_unixpath(connection_struct *conn,
5903 struct smb_request *req,
5904 struct files_struct *dirfsp,
5905 struct smb_filename *smb_fname,
5906 uint32_t access_mask,
5907 uint32_t share_access,
5908 uint32_t create_disposition,
5909 uint32_t create_options,
5910 uint32_t file_attributes,
5911 uint32_t oplock_request,
5912 const struct smb2_lease *lease,
5913 uint64_t allocation_size,
5914 uint32_t private_flags,
5915 struct security_descriptor *sd,
5916 struct ea_list *ea_list,
5918 files_struct **result,
5919 int *pinfo)
5921 struct smb2_lease none_lease;
5922 int info = FILE_WAS_OPENED;
5923 files_struct *base_fsp = NULL;
5924 files_struct *fsp = NULL;
5925 bool free_fsp_on_error = false;
5926 NTSTATUS status;
5927 int ret;
5928 struct smb_filename *parent_dir_fname = NULL;
5929 struct smb_filename *smb_fname_atname = NULL;
5931 DBG_DEBUG("access_mask = 0x%"PRIx32" "
5932 "file_attributes = 0x%"PRIx32" "
5933 "share_access = 0x%"PRIx32" "
5934 "create_disposition = 0x%"PRIx32" "
5935 "create_options = 0x%"PRIx32" "
5936 "oplock_request = 0x%"PRIx32" "
5937 "private_flags = 0x%"PRIx32" "
5938 "ea_list = %p, "
5939 "sd = %p, "
5940 "fname = %s\n",
5941 access_mask,
5942 file_attributes,
5943 share_access,
5944 create_disposition,
5945 create_options,
5946 oplock_request,
5947 private_flags,
5948 ea_list,
5950 smb_fname_str_dbg(smb_fname));
5952 if (create_options & FILE_OPEN_BY_FILE_ID) {
5953 status = NT_STATUS_NOT_SUPPORTED;
5954 goto fail;
5957 if (create_options & NTCREATEX_OPTIONS_INVALID_PARAM_MASK) {
5958 status = NT_STATUS_INVALID_PARAMETER;
5959 goto fail;
5962 if (!(create_options & FILE_OPEN_REPARSE_POINT) &&
5963 (smb_fname->fsp != NULL) && /* new files don't have an fsp */
5964 VALID_STAT(smb_fname->fsp->fsp_name->st))
5966 mode_t type = (smb_fname->fsp->fsp_name->st.st_ex_mode &
5967 S_IFMT);
5969 switch (type) {
5970 case S_IFREG:
5971 FALL_THROUGH;
5972 case S_IFDIR:
5973 break;
5974 case S_IFLNK:
5976 * We should never get this far with a symlink
5977 * "as such". Report as not existing.
5979 status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
5980 goto fail;
5981 default:
5982 status = NT_STATUS_IO_REPARSE_TAG_NOT_HANDLED;
5983 goto fail;
5987 if (req == NULL) {
5988 oplock_request |= INTERNAL_OPEN_ONLY;
5991 if (lease != NULL) {
5992 uint16_t epoch = lease->lease_epoch;
5993 uint16_t version = lease->lease_version;
5995 if (req == NULL) {
5996 DBG_WARNING("Got lease on internal open\n");
5997 status = NT_STATUS_INTERNAL_ERROR;
5998 goto fail;
6001 status = lease_match(conn,
6002 req,
6003 &lease->lease_key,
6004 conn->connectpath,
6005 smb_fname,
6006 &version,
6007 &epoch);
6008 if (NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) {
6009 /* Dynamic share file. No leases and update epoch... */
6010 none_lease = *lease;
6011 none_lease.lease_state = SMB2_LEASE_NONE;
6012 none_lease.lease_epoch = epoch;
6013 none_lease.lease_version = version;
6014 lease = &none_lease;
6015 } else if (!NT_STATUS_IS_OK(status)) {
6016 goto fail;
6020 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
6021 && (access_mask & DELETE_ACCESS)
6022 && !is_named_stream(smb_fname)) {
6024 * We can't open a file with DELETE access if any of the
6025 * streams is open without FILE_SHARE_DELETE
6027 status = open_streams_for_delete(conn, smb_fname);
6029 if (!NT_STATUS_IS_OK(status)) {
6030 goto fail;
6034 if (access_mask & SEC_FLAG_SYSTEM_SECURITY) {
6035 bool ok;
6037 ok = security_token_has_privilege(get_current_nttok(conn),
6038 SEC_PRIV_SECURITY);
6039 if (!ok) {
6040 DBG_DEBUG("open on %s failed - "
6041 "SEC_FLAG_SYSTEM_SECURITY denied.\n",
6042 smb_fname_str_dbg(smb_fname));
6043 status = NT_STATUS_PRIVILEGE_NOT_HELD;
6044 goto fail;
6047 if (conn_using_smb2(conn->sconn) &&
6048 (access_mask == SEC_FLAG_SYSTEM_SECURITY))
6051 * No other bits set. Windows SMB2 refuses this.
6052 * See smbtorture3 SMB2-SACL test.
6054 * Note this is an SMB2-only behavior,
6055 * smbtorture3 SMB1-SYSTEM-SECURITY already tests
6056 * that SMB1 allows this.
6058 status = NT_STATUS_ACCESS_DENIED;
6059 goto fail;
6064 * Files or directories can't be opened DELETE_ON_CLOSE without
6065 * delete access.
6066 * BUG: https://bugzilla.samba.org/show_bug.cgi?id=13358
6068 if ((create_options & FILE_DELETE_ON_CLOSE) &&
6069 ((access_mask & DELETE_ACCESS) == 0)) {
6070 status = NT_STATUS_INVALID_PARAMETER;
6071 goto fail;
6074 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
6075 && is_named_stream(smb_fname))
6077 uint32_t base_create_disposition;
6078 struct smb_filename *smb_fname_base = NULL;
6079 uint32_t base_privflags;
6081 if (create_options & FILE_DIRECTORY_FILE) {
6082 DBG_DEBUG("Can't open a stream as directory\n");
6083 status = NT_STATUS_NOT_A_DIRECTORY;
6084 goto fail;
6087 switch (create_disposition) {
6088 case FILE_OPEN:
6089 base_create_disposition = FILE_OPEN;
6090 break;
6091 default:
6092 base_create_disposition = FILE_OPEN_IF;
6093 break;
6096 smb_fname_base = cp_smb_filename_nostream(
6097 talloc_tos(), smb_fname);
6099 if (smb_fname_base == NULL) {
6100 status = NT_STATUS_NO_MEMORY;
6101 goto fail;
6105 * We may be creating the basefile as part of creating the
6106 * stream, so it's legal if the basefile doesn't exist at this
6107 * point, the create_file_unixpath() below will create it. But
6108 * if the basefile exists we want a handle so we can fstat() it.
6111 ret = vfs_stat(conn, smb_fname_base);
6112 if (ret == -1 && errno != ENOENT) {
6113 status = map_nt_error_from_unix(errno);
6114 TALLOC_FREE(smb_fname_base);
6115 goto fail;
6117 if (ret == 0) {
6118 status = openat_pathref_fsp(conn->cwd_fsp,
6119 smb_fname_base);
6120 if (!NT_STATUS_IS_OK(status)) {
6121 DBG_ERR("open_smb_fname_fsp [%s] failed: %s\n",
6122 smb_fname_str_dbg(smb_fname_base),
6123 nt_errstr(status));
6124 TALLOC_FREE(smb_fname_base);
6125 goto fail;
6129 * https://bugzilla.samba.org/show_bug.cgi?id=10229
6130 * We need to check if the requested access mask
6131 * could be used to open the underlying file (if
6132 * it existed), as we're passing in zero for the
6133 * access mask to the base filename.
6135 status = check_base_file_access(smb_fname_base->fsp,
6136 access_mask);
6138 if (!NT_STATUS_IS_OK(status)) {
6139 DEBUG(10, ("Permission check "
6140 "for base %s failed: "
6141 "%s\n", smb_fname->base_name,
6142 nt_errstr(status)));
6143 TALLOC_FREE(smb_fname_base);
6144 goto fail;
6148 base_privflags = NTCREATEX_FLAG_STREAM_BASEOPEN;
6150 /* Open the base file. */
6151 status = create_file_unixpath(conn,
6152 NULL,
6153 dirfsp,
6154 smb_fname_base,
6156 FILE_SHARE_READ
6157 | FILE_SHARE_WRITE
6158 | FILE_SHARE_DELETE,
6159 base_create_disposition,
6163 NULL,
6165 base_privflags,
6166 NULL,
6167 NULL,
6168 &base_fsp,
6169 NULL);
6170 TALLOC_FREE(smb_fname_base);
6172 if (!NT_STATUS_IS_OK(status)) {
6173 DEBUG(10, ("create_file_unixpath for base %s failed: "
6174 "%s\n", smb_fname->base_name,
6175 nt_errstr(status)));
6176 goto fail;
6180 if (smb_fname->fsp != NULL) {
6182 fsp = smb_fname->fsp;
6185 * We're about to use smb_fname->fsp for the fresh open.
6187 * Every fsp passed in via smb_fname->fsp already
6188 * holds a fsp->fsp_name. If it is already this
6189 * fsp->fsp_name that we got passed in as our input
6190 * argument smb_fname, these two are assumed to have
6191 * the same lifetime: Every fsp hangs of "conn", and
6192 * fsp->fsp_name is its talloc child.
6195 if (smb_fname != smb_fname->fsp->fsp_name) {
6197 * "smb_fname" is temporary in this case, but
6198 * the destructor of smb_fname would also tear
6199 * down the fsp we're about to use. Unlink
6200 * them from each other.
6202 smb_fname_fsp_unlink(smb_fname);
6205 * "fsp" is ours now
6207 free_fsp_on_error = true;
6210 status = fsp_bind_smb(fsp, req);
6211 if (!NT_STATUS_IS_OK(status)) {
6212 goto fail;
6215 if (fsp_is_alternate_stream(fsp)) {
6216 struct files_struct *tmp_base_fsp = fsp->base_fsp;
6218 fsp_set_base_fsp(fsp, NULL);
6220 fd_close(tmp_base_fsp);
6221 file_free(NULL, tmp_base_fsp);
6223 } else {
6225 * No fsp passed in that we can use, create one
6227 status = file_new(req, conn, &fsp);
6228 if(!NT_STATUS_IS_OK(status)) {
6229 goto fail;
6231 free_fsp_on_error = true;
6233 status = fsp_set_smb_fname(fsp, smb_fname);
6234 if (!NT_STATUS_IS_OK(status)) {
6235 goto fail;
6239 SMB_ASSERT(fsp->fsp_name->fsp != NULL);
6240 SMB_ASSERT(fsp->fsp_name->fsp == fsp);
6242 if (base_fsp) {
6244 * We're opening the stream element of a
6245 * base_fsp we already opened. Set up the
6246 * base_fsp pointer.
6248 fsp_set_base_fsp(fsp, base_fsp);
6251 if (dirfsp != NULL) {
6252 status = SMB_VFS_PARENT_PATHNAME(
6253 conn,
6254 talloc_tos(),
6255 smb_fname,
6256 &parent_dir_fname,
6257 &smb_fname_atname);
6258 if (!NT_STATUS_IS_OK(status)) {
6259 goto fail;
6261 } else {
6263 * Get a pathref on the parent. We can re-use this for
6264 * multiple calls to check parent ACLs etc. to avoid
6265 * pathname calls.
6267 status = parent_pathref(talloc_tos(),
6268 conn->cwd_fsp,
6269 smb_fname,
6270 &parent_dir_fname,
6271 &smb_fname_atname);
6272 if (!NT_STATUS_IS_OK(status)) {
6273 goto fail;
6276 dirfsp = parent_dir_fname->fsp;
6277 status = fsp_set_smb_fname(dirfsp, parent_dir_fname);
6278 if (!NT_STATUS_IS_OK(status)) {
6279 goto fail;
6284 * If it's a request for a directory open, deal with it separately.
6287 if (create_options & FILE_DIRECTORY_FILE) {
6289 if (create_options & FILE_NON_DIRECTORY_FILE) {
6290 status = NT_STATUS_INVALID_PARAMETER;
6291 goto fail;
6294 /* Can't open a temp directory. IFS kit test. */
6295 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
6296 (file_attributes & FILE_ATTRIBUTE_TEMPORARY)) {
6297 status = NT_STATUS_INVALID_PARAMETER;
6298 goto fail;
6302 * We will get a create directory here if the Win32
6303 * app specified a security descriptor in the
6304 * CreateDirectory() call.
6307 oplock_request = 0;
6308 status = open_directory(conn,
6309 req,
6310 access_mask,
6311 share_access,
6312 create_disposition,
6313 create_options,
6314 file_attributes,
6315 dirfsp->fsp_name,
6316 smb_fname_atname,
6317 &info,
6318 fsp);
6319 } else {
6322 * Ordinary file case.
6325 if (allocation_size) {
6326 fsp->initial_allocation_size = smb_roundup(fsp->conn,
6327 allocation_size);
6330 status = open_file_ntcreate(conn,
6331 req,
6332 access_mask,
6333 share_access,
6334 create_disposition,
6335 create_options,
6336 file_attributes,
6337 oplock_request,
6338 lease,
6339 private_flags,
6340 dirfsp->fsp_name,
6341 smb_fname_atname,
6342 &info,
6343 fsp);
6344 if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
6346 /* A stream open never opens a directory */
6348 if (base_fsp) {
6349 status = NT_STATUS_FILE_IS_A_DIRECTORY;
6350 goto fail;
6354 * Fail the open if it was explicitly a non-directory
6355 * file.
6358 if (create_options & FILE_NON_DIRECTORY_FILE) {
6359 status = NT_STATUS_FILE_IS_A_DIRECTORY;
6360 goto fail;
6363 oplock_request = 0;
6364 status = open_directory(conn,
6365 req,
6366 access_mask,
6367 share_access,
6368 create_disposition,
6369 create_options,
6370 file_attributes,
6371 dirfsp->fsp_name,
6372 smb_fname_atname,
6373 &info,
6374 fsp);
6378 if (!NT_STATUS_IS_OK(status)) {
6379 goto fail;
6382 fsp->fsp_flags.is_fsa = true;
6384 if ((ea_list != NULL) &&
6385 ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN))) {
6386 status = set_ea(conn, fsp, ea_list);
6387 if (!NT_STATUS_IS_OK(status)) {
6388 goto fail;
6392 if (!fsp->fsp_flags.is_directory &&
6393 S_ISDIR(fsp->fsp_name->st.st_ex_mode))
6395 status = NT_STATUS_ACCESS_DENIED;
6396 goto fail;
6399 /* Save the requested allocation size. */
6400 if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
6401 if ((allocation_size > (uint64_t)fsp->fsp_name->st.st_ex_size)
6402 && !(fsp->fsp_flags.is_directory))
6404 fsp->initial_allocation_size = smb_roundup(
6405 fsp->conn, allocation_size);
6406 if (vfs_allocate_file_space(
6407 fsp, fsp->initial_allocation_size) == -1) {
6408 status = NT_STATUS_DISK_FULL;
6409 goto fail;
6411 } else {
6412 fsp->initial_allocation_size = smb_roundup(
6413 fsp->conn, (uint64_t)fsp->fsp_name->st.st_ex_size);
6415 } else {
6416 fsp->initial_allocation_size = 0;
6419 if ((info == FILE_WAS_CREATED) &&
6420 lp_nt_acl_support(SNUM(conn)) &&
6421 !fsp_is_alternate_stream(fsp)) {
6422 if (sd != NULL) {
6424 * According to the MS documentation, the only time the security
6425 * descriptor is applied to the opened file is iff we *created* the
6426 * file; an existing file stays the same.
6428 * Also, it seems (from observation) that you can open the file with
6429 * any access mask but you can still write the sd. We need to override
6430 * the granted access before we call set_sd
6431 * Patch for bug #2242 from Tom Lackemann <cessnatomny@yahoo.com>.
6434 uint32_t sec_info_sent;
6435 uint32_t saved_access_mask = fsp->access_mask;
6437 sec_info_sent = get_sec_info(sd);
6439 fsp->access_mask = FILE_GENERIC_ALL;
6441 if (sec_info_sent & (SECINFO_OWNER|
6442 SECINFO_GROUP|
6443 SECINFO_DACL|
6444 SECINFO_SACL)) {
6445 status = set_sd(fsp, sd, sec_info_sent);
6448 fsp->access_mask = saved_access_mask;
6450 if (!NT_STATUS_IS_OK(status)) {
6451 goto fail;
6453 } else if (lp_inherit_acls(SNUM(conn))) {
6454 /* Inherit from parent. Errors here are not fatal. */
6455 status = inherit_new_acl(dirfsp, fsp);
6456 if (!NT_STATUS_IS_OK(status)) {
6457 DEBUG(10,("inherit_new_acl: failed for %s with %s\n",
6458 fsp_str_dbg(fsp),
6459 nt_errstr(status) ));
6464 if ((conn->fs_capabilities & FILE_FILE_COMPRESSION)
6465 && (create_options & FILE_NO_COMPRESSION)
6466 && (info == FILE_WAS_CREATED)) {
6467 status = SMB_VFS_SET_COMPRESSION(conn, fsp, fsp,
6468 COMPRESSION_FORMAT_NONE);
6469 if (!NT_STATUS_IS_OK(status)) {
6470 DEBUG(1, ("failed to disable compression: %s\n",
6471 nt_errstr(status)));
6475 DEBUG(10, ("create_file_unixpath: info=%d\n", info));
6477 *result = fsp;
6478 if (pinfo != NULL) {
6479 *pinfo = info;
6482 smb_fname->st = fsp->fsp_name->st;
6484 TALLOC_FREE(parent_dir_fname);
6486 return NT_STATUS_OK;
6488 fail:
6489 DEBUG(10, ("create_file_unixpath: %s\n", nt_errstr(status)));
6491 if (fsp != NULL) {
6493 * The close_file below will close
6494 * fsp->base_fsp.
6496 base_fsp = NULL;
6497 close_file_smb(req, fsp, ERROR_CLOSE);
6498 if (free_fsp_on_error) {
6499 file_free(req, fsp);
6500 fsp = NULL;
6503 if (base_fsp != NULL) {
6504 close_file_free(req, &base_fsp, ERROR_CLOSE);
6507 TALLOC_FREE(parent_dir_fname);
6509 return status;
6512 NTSTATUS create_file_default(connection_struct *conn,
6513 struct smb_request *req,
6514 struct files_struct *dirfsp,
6515 struct smb_filename *smb_fname,
6516 uint32_t access_mask,
6517 uint32_t share_access,
6518 uint32_t create_disposition,
6519 uint32_t create_options,
6520 uint32_t file_attributes,
6521 uint32_t oplock_request,
6522 const struct smb2_lease *lease,
6523 uint64_t allocation_size,
6524 uint32_t private_flags,
6525 struct security_descriptor *sd,
6526 struct ea_list *ea_list,
6527 files_struct **result,
6528 int *pinfo,
6529 const struct smb2_create_blobs *in_context_blobs,
6530 struct smb2_create_blobs *out_context_blobs)
6532 int info = FILE_WAS_OPENED;
6533 files_struct *fsp = NULL;
6534 NTSTATUS status;
6535 bool stream_name = false;
6536 struct smb2_create_blob *posx = NULL;
6538 DBG_DEBUG("access_mask = 0x%" PRIu32
6539 " file_attributes = 0x%" PRIu32
6540 " share_access = 0x%" PRIu32
6541 " create_disposition = 0x%" PRIu32
6542 " create_options = 0x%" PRIu32
6543 " oplock_request = 0x%" PRIu32
6544 " private_flags = 0x%" PRIu32
6545 " ea_list = %p, sd = %p, fname = %s\n",
6546 access_mask,
6547 file_attributes,
6548 share_access,
6549 create_disposition,
6550 create_options,
6551 oplock_request,
6552 private_flags,
6553 ea_list,
6555 smb_fname_str_dbg(smb_fname));
6557 if (req != NULL) {
6559 * Remember the absolute time of the original request
6560 * with this mid. We'll use it later to see if this
6561 * has timed out.
6563 get_deferred_open_message_state(req, &req->request_time, NULL);
6567 * Check to see if this is a mac fork of some kind.
6570 stream_name = is_ntfs_stream_smb_fname(smb_fname);
6571 if (stream_name) {
6572 enum FAKE_FILE_TYPE fake_file_type;
6574 fake_file_type = is_fake_file(smb_fname);
6576 if (req != NULL && fake_file_type != FAKE_FILE_TYPE_NONE) {
6579 * Here we go! support for changing the disk quotas
6580 * --metze
6582 * We need to fake up to open this MAGIC QUOTA file
6583 * and return a valid FID.
6585 * w2k close this file directly after opening xp
6586 * also tries a QUERY_FILE_INFO on the file and then
6587 * close it
6589 status = open_fake_file(req, conn, req->vuid,
6590 fake_file_type, smb_fname,
6591 access_mask, &fsp);
6592 if (!NT_STATUS_IS_OK(status)) {
6593 goto fail;
6596 ZERO_STRUCT(smb_fname->st);
6597 goto done;
6600 if (!(conn->fs_capabilities & FILE_NAMED_STREAMS)) {
6601 status = NT_STATUS_OBJECT_NAME_INVALID;
6602 goto fail;
6606 if (is_ntfs_default_stream_smb_fname(smb_fname)) {
6607 int ret;
6608 /* We have to handle this error here. */
6609 if (create_options & FILE_DIRECTORY_FILE) {
6610 status = NT_STATUS_NOT_A_DIRECTORY;
6611 goto fail;
6613 ret = vfs_stat(conn, smb_fname);
6614 if (ret == 0 && VALID_STAT_OF_DIR(smb_fname->st)) {
6615 status = NT_STATUS_FILE_IS_A_DIRECTORY;
6616 goto fail;
6620 posx = smb2_create_blob_find(
6621 in_context_blobs, SMB2_CREATE_TAG_POSIX);
6622 if (posx != NULL) {
6623 uint32_t wire_mode_bits = 0;
6624 mode_t mode_bits = 0;
6625 SMB_STRUCT_STAT sbuf = { 0 };
6626 enum perm_type ptype =
6627 (create_options & FILE_DIRECTORY_FILE) ?
6628 PERM_NEW_DIR : PERM_NEW_FILE;
6630 if (posx->data.length != 4) {
6631 status = NT_STATUS_INVALID_PARAMETER;
6632 goto fail;
6635 wire_mode_bits = IVAL(posx->data.data, 0);
6636 status = unix_perms_from_wire(
6637 conn, &sbuf, wire_mode_bits, ptype, &mode_bits);
6638 if (!NT_STATUS_IS_OK(status)) {
6639 goto fail;
6642 * Remove type info from mode, leaving only the
6643 * permissions and setuid/gid bits.
6645 mode_bits &= ~S_IFMT;
6647 file_attributes = (FILE_FLAG_POSIX_SEMANTICS | mode_bits);
6650 status = create_file_unixpath(conn,
6651 req,
6652 dirfsp,
6653 smb_fname,
6654 access_mask,
6655 share_access,
6656 create_disposition,
6657 create_options,
6658 file_attributes,
6659 oplock_request,
6660 lease,
6661 allocation_size,
6662 private_flags,
6664 ea_list,
6665 &fsp,
6666 &info);
6667 if (!NT_STATUS_IS_OK(status)) {
6668 goto fail;
6671 done:
6672 DEBUG(10, ("create_file: info=%d\n", info));
6674 *result = fsp;
6675 if (pinfo != NULL) {
6676 *pinfo = info;
6678 return NT_STATUS_OK;
6680 fail:
6681 DEBUG(10, ("create_file: %s\n", nt_errstr(status)));
6683 if (fsp != NULL) {
6684 close_file_free(req, &fsp, ERROR_CLOSE);
6686 return status;