utils: Fix up 14a533680245
[samba4-gss.git] / source3 / smbd / open.c
blob4f69a7749d8c870ebb0c650f0eff3cc52e379e35
1 /*
2 Unix SMB/CIFS implementation.
3 file opening and share modes
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Jeremy Allison 2001-2004
6 Copyright (C) Volker Lendecke 2005
7 Copyright (C) Ralph Boehme 2017
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "includes.h"
24 #include "system/filesys.h"
25 #include "lib/util/server_id.h"
26 #include "printing.h"
27 #include "locking/share_mode_lock.h"
28 #include "smbd/smbd.h"
29 #include "smbd/globals.h"
30 #include "fake_file.h"
31 #include "../libcli/security/security.h"
32 #include "../librpc/gen_ndr/ndr_security.h"
33 #include "../librpc/gen_ndr/ndr_open_files.h"
34 #include "../librpc/gen_ndr/idmap.h"
35 #include "../librpc/gen_ndr/ioctl.h"
36 #include "passdb/lookup_sid.h"
37 #include "auth.h"
38 #include "serverid.h"
39 #include "messages.h"
40 #include "source3/lib/dbwrap/dbwrap_watch.h"
41 #include "source3/lib/server_id_watch.h"
42 #include "locking/leases_db.h"
43 #include "librpc/gen_ndr/ndr_leases_db.h"
44 #include "lib/util/time_basic.h"
45 #include "source3/smbd/dir.h"
47 #if defined(HAVE_LINUX_MAGIC_H)
48 #include <linux/magic.h>
49 #endif
51 static NTSTATUS inherit_new_acl(files_struct *dirfsp, files_struct *fsp);
53 extern const struct generic_mapping file_generic_mapping;
55 struct deferred_open_record {
56 struct smbXsrv_connection *xconn;
57 uint64_t mid;
59 bool async_open;
62 * Timer for async opens, needed because they don't use a watch on
63 * a locking.tdb record. This is currently only used for real async
64 * opens and just terminates smbd if the async open times out.
66 struct tevent_timer *te;
69 * For the samba kernel oplock case we use both a timeout and
70 * a watch on locking.tdb. This way in case it's smbd holding
71 * the kernel oplock we get directly notified for the retry
72 * once the kernel oplock is properly broken. Store the req
73 * here so that it can be timely discarded once the timer
74 * above fires.
76 struct tevent_req *watch_req;
79 /****************************************************************************
80 If the requester wanted DELETE_ACCESS and was rejected because
81 the file ACL didn't include DELETE_ACCESS, see if the parent ACL
82 overrides this.
83 ****************************************************************************/
85 static bool parent_override_delete(connection_struct *conn,
86 struct files_struct *dirfsp,
87 const struct smb_filename *smb_fname,
88 uint32_t access_mask,
89 uint32_t rejected_mask)
91 if ((access_mask & DELETE_ACCESS) && (rejected_mask & DELETE_ACCESS)) {
92 bool ok;
93 ok = can_delete_file_in_directory(conn, dirfsp, smb_fname);
94 return ok;
97 return false;
100 /****************************************************************************
101 Check if we have open rights.
102 ****************************************************************************/
104 static NTSTATUS smbd_check_access_rights_fname(
105 struct connection_struct *conn,
106 const struct smb_filename *smb_fname,
107 bool use_privs,
108 uint32_t access_mask,
109 uint32_t do_not_check_mask)
111 uint32_t rejected_share_access;
112 uint32_t effective_access;
114 rejected_share_access = access_mask & ~(conn->share_access);
116 if (rejected_share_access) {
117 DBG_DEBUG("rejected share access 0x%"PRIx32" on "
118 "%s (0x%"PRIx32")\n",
119 access_mask,
120 smb_fname_str_dbg(smb_fname),
121 rejected_share_access);
122 return NT_STATUS_ACCESS_DENIED;
125 effective_access = access_mask & ~do_not_check_mask;
126 if (effective_access == 0) {
127 DBG_DEBUG("do_not_check_mask override on %s. Granting 0x%x for free.\n",
128 smb_fname_str_dbg(smb_fname),
129 (unsigned int)access_mask);
130 return NT_STATUS_OK;
133 if (!use_privs && get_current_uid(conn) == (uid_t)0) {
134 /* I'm sorry sir, I didn't know you were root... */
135 DBG_DEBUG("root override on %s. Granting 0x%x\n",
136 smb_fname_str_dbg(smb_fname),
137 (unsigned int)access_mask);
138 return NT_STATUS_OK;
141 if ((access_mask & DELETE_ACCESS) &&
142 !lp_acl_check_permissions(SNUM(conn)))
144 DBG_DEBUG("Not checking ACL on DELETE_ACCESS on file %s. "
145 "Granting 0x%"PRIx32"\n",
146 smb_fname_str_dbg(smb_fname),
147 access_mask);
148 return NT_STATUS_OK;
151 if (access_mask == DELETE_ACCESS &&
152 VALID_STAT(smb_fname->st) &&
153 S_ISLNK(smb_fname->st.st_ex_mode))
155 /* We can always delete a symlink. */
156 DBG_DEBUG("Not checking ACL on DELETE_ACCESS on symlink %s.\n",
157 smb_fname_str_dbg(smb_fname));
158 return NT_STATUS_OK;
161 return NT_STATUS_MORE_PROCESSING_REQUIRED;
164 static NTSTATUS smbd_check_access_rights_sd(
165 struct connection_struct *conn,
166 struct files_struct *dirfsp,
167 const struct smb_filename *smb_fname,
168 struct security_descriptor *sd,
169 bool use_privs,
170 uint32_t access_mask,
171 uint32_t do_not_check_mask)
173 uint32_t rejected_mask = access_mask;
174 NTSTATUS status;
176 if (sd == NULL) {
177 goto access_denied;
180 status = se_file_access_check(sd,
181 get_current_nttok(conn),
182 use_privs,
183 (access_mask & ~do_not_check_mask),
184 &rejected_mask);
186 DBG_DEBUG("File [%s] requesting [0x%"PRIx32"] "
187 "returning [0x%"PRIx32"] (%s)\n",
188 smb_fname_str_dbg(smb_fname),
189 access_mask,
190 rejected_mask,
191 nt_errstr(status));
193 if (!NT_STATUS_IS_OK(status)) {
194 if (DEBUGLEVEL >= 10) {
195 DBG_DEBUG("acl for %s is:\n",
196 smb_fname_str_dbg(smb_fname));
197 NDR_PRINT_DEBUG(security_descriptor, sd);
201 TALLOC_FREE(sd);
203 if (NT_STATUS_IS_OK(status) ||
204 !NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED))
206 return status;
209 /* Here we know status == NT_STATUS_ACCESS_DENIED. */
211 access_denied:
213 if ((access_mask & FILE_WRITE_ATTRIBUTES) &&
214 (rejected_mask & FILE_WRITE_ATTRIBUTES) &&
215 !lp_store_dos_attributes(SNUM(conn)) &&
216 (lp_map_readonly(SNUM(conn)) ||
217 lp_map_archive(SNUM(conn)) ||
218 lp_map_hidden(SNUM(conn)) ||
219 lp_map_system(SNUM(conn))))
221 rejected_mask &= ~FILE_WRITE_ATTRIBUTES;
223 DBG_DEBUG("overrode FILE_WRITE_ATTRIBUTES on file %s\n",
224 smb_fname_str_dbg(smb_fname));
227 if (parent_override_delete(conn,
228 dirfsp,
229 smb_fname,
230 access_mask,
231 rejected_mask))
234 * Were we trying to do an open for delete and didn't get DELETE
235 * access. Check if the directory allows DELETE_CHILD.
236 * See here:
237 * http://blogs.msdn.com/oldnewthing/archive/2004/06/04/148426.aspx
238 * for details.
241 rejected_mask &= ~DELETE_ACCESS;
243 DBG_DEBUG("Overrode DELETE_ACCESS on file %s\n",
244 smb_fname_str_dbg(smb_fname));
247 if (rejected_mask != 0) {
248 return NT_STATUS_ACCESS_DENIED;
250 return NT_STATUS_OK;
253 NTSTATUS smbd_check_access_rights_fsp(struct files_struct *dirfsp,
254 struct files_struct *fsp,
255 bool use_privs,
256 uint32_t access_mask)
258 struct security_descriptor *sd = NULL;
259 uint32_t do_not_check_mask = 0;
260 NTSTATUS status;
262 /* Cope with fake/printer fsp's. */
263 if (fsp->fake_file_handle != NULL || fsp->print_file != NULL) {
264 if ((fsp->access_mask & access_mask) != access_mask) {
265 return NT_STATUS_ACCESS_DENIED;
267 return NT_STATUS_OK;
270 if (fsp_get_pathref_fd(fsp) == -1) {
272 * This is a POSIX open on a symlink. For the pathname
273 * version of this function we used to return the st_mode
274 * bits turned into an NT ACL. For a symlink the mode bits
275 * are always rwxrwxrwx which means the pathname version always
276 * returned NT_STATUS_OK for a symlink. For the handle reference
277 * to a symlink use the handle access bits.
279 if ((fsp->access_mask & access_mask) != access_mask) {
280 return NT_STATUS_ACCESS_DENIED;
282 return NT_STATUS_OK;
286 * If we can access the path to this file, by
287 * default we have FILE_READ_ATTRIBUTES from the
288 * containing directory. See the section:
289 * "Algorithm to Check Access to an Existing File"
290 * in MS-FSA.pdf.
292 * se_file_access_check() also takes care of
293 * owner WRITE_DAC and READ_CONTROL.
295 do_not_check_mask = FILE_READ_ATTRIBUTES;
298 * Samba 3.6 and earlier granted execute access even
299 * if the ACL did not contain execute rights.
300 * Samba 4.0 is more correct and checks it.
301 * The compatibility mode allows one to skip this check
302 * to smoothen upgrades.
304 if (lp_acl_allow_execute_always(SNUM(fsp->conn))) {
305 do_not_check_mask |= FILE_EXECUTE;
308 status = smbd_check_access_rights_fname(fsp->conn,
309 fsp->fsp_name,
310 use_privs,
311 access_mask,
312 do_not_check_mask);
313 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
314 return status;
317 status = SMB_VFS_FGET_NT_ACL(metadata_fsp(fsp),
318 (SECINFO_OWNER |
319 SECINFO_GROUP |
320 SECINFO_DACL),
321 talloc_tos(),
322 &sd);
323 if (!NT_STATUS_IS_OK(status)) {
324 DBG_DEBUG("Could not get acl on %s: %s\n",
325 fsp_str_dbg(fsp),
326 nt_errstr(status));
327 return status;
330 return smbd_check_access_rights_sd(fsp->conn,
331 dirfsp,
332 fsp->fsp_name,
334 use_privs,
335 access_mask,
336 do_not_check_mask);
340 * Given an fsp that represents a parent directory,
341 * check if the requested access can be granted.
343 NTSTATUS check_parent_access_fsp(struct files_struct *fsp,
344 uint32_t access_mask)
346 NTSTATUS status;
347 struct security_descriptor *parent_sd = NULL;
348 uint32_t access_granted = 0;
349 uint32_t name_hash;
350 bool delete_on_close_set;
351 TALLOC_CTX *frame = talloc_stackframe();
353 if (get_current_uid(fsp->conn) == (uid_t)0) {
354 /* I'm sorry sir, I didn't know you were root... */
355 DBG_DEBUG("root override on %s. Granting 0x%x\n",
356 fsp_str_dbg(fsp),
357 (unsigned int)access_mask);
358 status = NT_STATUS_OK;
359 goto out;
362 status = SMB_VFS_FGET_NT_ACL(fsp,
363 (SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL),
364 frame,
365 &parent_sd);
367 if (!NT_STATUS_IS_OK(status)) {
368 DBG_INFO("SMB_VFS_FGET_NT_ACL failed for "
369 "%s with error %s\n",
370 fsp_str_dbg(fsp),
371 nt_errstr(status));
372 goto out;
376 * If we can access the path to this file, by
377 * default we have FILE_READ_ATTRIBUTES from the
378 * containing directory. See the section:
379 * "Algorithm to Check Access to an Existing File"
380 * in MS-FSA.pdf.
382 * se_file_access_check() also takes care of
383 * owner WRITE_DAC and READ_CONTROL.
385 status = se_file_access_check(parent_sd,
386 get_current_nttok(fsp->conn),
387 false,
388 (access_mask & ~FILE_READ_ATTRIBUTES),
389 &access_granted);
390 if(!NT_STATUS_IS_OK(status)) {
391 DBG_INFO("access check "
392 "on directory %s for mask 0x%x returned (0x%x) %s\n",
393 fsp_str_dbg(fsp),
394 access_mask,
395 access_granted,
396 nt_errstr(status));
397 goto out;
400 if (!(access_mask & (SEC_DIR_ADD_FILE | SEC_DIR_ADD_SUBDIR))) {
401 status = NT_STATUS_OK;
402 goto out;
404 if (!lp_check_parent_directory_delete_on_close(SNUM(fsp->conn))) {
405 status = NT_STATUS_OK;
406 goto out;
409 /* Check if the directory has delete-on-close set */
410 status = file_name_hash(fsp->conn,
411 fsp->fsp_name->base_name,
412 &name_hash);
413 if (!NT_STATUS_IS_OK(status)) {
414 goto out;
417 get_file_infos(fsp->file_id, name_hash, &delete_on_close_set, NULL);
418 if (delete_on_close_set) {
419 status = NT_STATUS_DELETE_PENDING;
420 goto out;
423 status = NT_STATUS_OK;
425 out:
426 TALLOC_FREE(frame);
427 return status;
430 /****************************************************************************
431 Ensure when opening a base file for a stream open that we have permissions
432 to do so given the access mask on the base file.
433 ****************************************************************************/
435 static NTSTATUS check_base_file_access(struct files_struct *fsp,
436 uint32_t access_mask)
438 NTSTATUS status;
440 status = smbd_calculate_access_mask_fsp(fsp->conn->cwd_fsp,
441 fsp,
442 false,
443 access_mask,
444 &access_mask);
445 if (!NT_STATUS_IS_OK(status)) {
446 DEBUG(10, ("smbd_calculate_access_mask "
447 "on file %s returned %s\n",
448 fsp_str_dbg(fsp),
449 nt_errstr(status)));
450 return status;
453 if (access_mask & (FILE_WRITE_DATA|FILE_APPEND_DATA)) {
454 uint32_t dosattrs;
455 if (!CAN_WRITE(fsp->conn)) {
456 return NT_STATUS_ACCESS_DENIED;
458 dosattrs = fdos_mode(fsp);
459 if (dosattrs & FILE_ATTRIBUTE_READONLY) {
460 return NT_STATUS_ACCESS_DENIED;
464 return smbd_check_access_rights_fsp(fsp->conn->cwd_fsp,
465 fsp,
466 false,
467 access_mask);
470 static NTSTATUS chdir_below_conn(
471 TALLOC_CTX *mem_ctx,
472 connection_struct *conn,
473 const char *connectpath,
474 size_t connectpath_len,
475 struct smb_filename *dir_fname,
476 struct smb_filename **_oldwd_fname)
478 struct smb_filename *oldwd_fname = NULL;
479 struct smb_filename *smb_fname_dot = NULL;
480 struct smb_filename *real_fname = NULL;
481 const char *relative = NULL;
482 NTSTATUS status;
483 int ret;
484 bool ok;
486 if (!ISDOT(dir_fname->base_name)) {
488 oldwd_fname = vfs_GetWd(talloc_tos(), conn);
489 if (oldwd_fname == NULL) {
490 status = map_nt_error_from_unix(errno);
491 goto out;
494 /* Pin parent directory in place. */
495 ret = vfs_ChDir(conn, dir_fname);
496 if (ret == -1) {
497 status = map_nt_error_from_unix(errno);
498 DBG_DEBUG("chdir to %s failed: %s\n",
499 dir_fname->base_name,
500 strerror(errno));
501 goto out;
505 smb_fname_dot = synthetic_smb_fname(
506 talloc_tos(),
507 ".",
508 NULL,
509 NULL,
510 dir_fname->twrp,
511 dir_fname->flags);
512 if (smb_fname_dot == NULL) {
513 status = NT_STATUS_NO_MEMORY;
514 goto out;
517 real_fname = SMB_VFS_REALPATH(conn, talloc_tos(), smb_fname_dot);
518 if (real_fname == NULL) {
519 status = map_nt_error_from_unix(errno);
520 DBG_DEBUG("realpath in %s failed: %s\n",
521 dir_fname->base_name,
522 strerror(errno));
523 goto out;
525 TALLOC_FREE(smb_fname_dot);
527 ok = subdir_of(connectpath,
528 connectpath_len,
529 real_fname->base_name,
530 &relative);
531 if (ok) {
532 TALLOC_FREE(real_fname);
533 *_oldwd_fname = oldwd_fname;
534 return NT_STATUS_OK;
537 DBG_NOTICE("Bad access attempt: %s is a symlink "
538 "outside the share path\n"
539 "conn_rootdir =%s\n"
540 "resolved_name=%s\n",
541 dir_fname->base_name,
542 connectpath,
543 real_fname->base_name);
544 TALLOC_FREE(real_fname);
546 status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
548 out:
549 if (oldwd_fname != NULL) {
550 ret = vfs_ChDir(conn, oldwd_fname);
551 SMB_ASSERT(ret == 0);
552 TALLOC_FREE(oldwd_fname);
555 return status;
559 * Get the symlink target of dirfsp/symlink_name, making sure the
560 * target is below connection_path.
563 static NTSTATUS symlink_target_below_conn(
564 TALLOC_CTX *mem_ctx,
565 const char *connection_path,
566 struct files_struct *fsp,
567 struct files_struct *dirfsp,
568 struct smb_filename *symlink_name,
569 char **_target)
571 char *target = NULL;
572 char *absolute = NULL;
573 NTSTATUS status;
575 if (fsp_get_pathref_fd(fsp) != -1) {
577 * fsp is an O_PATH open, Linux does a "freadlink"
578 * with an empty name argument to readlinkat
580 status = readlink_talloc(talloc_tos(), fsp, NULL, &target);
581 } else {
582 status = readlink_talloc(
583 talloc_tos(), dirfsp, symlink_name, &target);
586 if (!NT_STATUS_IS_OK(status)) {
587 return status;
590 status = safe_symlink_target_path(talloc_tos(),
591 connection_path,
592 dirfsp->fsp_name->base_name,
593 target,
595 &absolute);
596 if (!NT_STATUS_IS_OK(status)) {
597 DBG_DEBUG("safe_symlink_target_path() failed: %s\n",
598 nt_errstr(status));
599 return status;
602 if (absolute[0] == '\0') {
604 * special case symlink to share root: "." is our
605 * share root filename
607 TALLOC_FREE(absolute);
608 absolute = talloc_strdup(talloc_tos(), ".");
609 if (absolute == NULL) {
610 return NT_STATUS_NO_MEMORY;
614 *_target = absolute;
615 return NT_STATUS_OK;
618 /****************************************************************************
619 Non-widelink open.
620 ****************************************************************************/
622 static NTSTATUS non_widelink_open(const struct files_struct *dirfsp,
623 files_struct *fsp,
624 struct smb_filename *smb_fname,
625 const struct vfs_open_how *_how)
627 struct connection_struct *conn = fsp->conn;
628 const char *connpath = SMB_VFS_CONNECTPATH(conn, dirfsp, smb_fname);
629 size_t connpath_len;
630 NTSTATUS status = NT_STATUS_OK;
631 int fd = -1;
632 char *orig_smb_fname_base = smb_fname->base_name;
633 struct smb_filename *orig_fsp_name = fsp->fsp_name;
634 struct smb_filename *smb_fname_rel = NULL;
635 struct smb_filename *oldwd_fname = NULL;
636 struct smb_filename *parent_dir_fname = NULL;
637 struct vfs_open_how how = *_how;
638 char *target = NULL;
639 size_t link_depth = 0;
640 int ret;
642 SMB_ASSERT(!fsp_is_alternate_stream(fsp));
644 if (connpath == NULL) {
646 * This can happen with shadow_copy2 if the snapshot
647 * path is not found
649 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
651 connpath_len = strlen(connpath);
653 again:
654 if (smb_fname->base_name[0] == '/') {
655 int cmp = strcmp(connpath, smb_fname->base_name);
656 if (cmp == 0) {
657 smb_fname->base_name = talloc_strdup(smb_fname, "");
658 if (smb_fname->base_name == NULL) {
659 status = NT_STATUS_NO_MEMORY;
660 goto out;
665 if (dirfsp == conn->cwd_fsp) {
667 status = SMB_VFS_PARENT_PATHNAME(fsp->conn,
668 talloc_tos(),
669 smb_fname,
670 &parent_dir_fname,
671 &smb_fname_rel);
672 if (!NT_STATUS_IS_OK(status)) {
673 goto out;
676 status = chdir_below_conn(
677 talloc_tos(),
678 conn,
679 connpath,
680 connpath_len,
681 parent_dir_fname,
682 &oldwd_fname);
683 if (!NT_STATUS_IS_OK(status)) {
684 goto out;
687 /* Setup fsp->fsp_name to be relative to cwd */
688 fsp->fsp_name = smb_fname_rel;
689 } else {
691 * fsp->fsp_name is unchanged as it is already correctly
692 * relative to dirfsp.
694 smb_fname_rel = smb_fname;
699 * Assert nobody can step in with a symlink on the
700 * path, there is no path anymore and we'll use
701 * O_NOFOLLOW to open.
703 char *slash = strchr_m(smb_fname_rel->base_name, '/');
704 SMB_ASSERT(slash == NULL);
707 how.flags |= O_NOFOLLOW;
709 fd = SMB_VFS_OPENAT(conn,
710 dirfsp,
711 smb_fname_rel,
712 fsp,
713 &how);
714 fsp_set_fd(fsp, fd); /* This preserves errno */
716 if (fd == -1) {
717 status = map_nt_error_from_unix(errno);
719 if (errno == ENOENT) {
720 goto out;
724 * ENOENT makes it worthless retrying with a
725 * stat, we know for sure the file does not
726 * exist. For everything else we want to know
727 * what's there.
729 ret = SMB_VFS_FSTATAT(
730 fsp->conn,
731 dirfsp,
732 smb_fname_rel,
733 &fsp->fsp_name->st,
734 AT_SYMLINK_NOFOLLOW);
736 if (ret == -1) {
738 * Keep the original error. Otherwise we would
739 * mask for example EROFS for open(O_CREAT),
740 * turning it into ENOENT.
742 goto out;
744 } else {
745 ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st);
748 if (ret == -1) {
749 status = map_nt_error_from_unix(errno);
750 DBG_DEBUG("fstat[at](%s) failed: %s\n",
751 smb_fname_str_dbg(smb_fname),
752 strerror(errno));
753 goto out;
756 fsp->fsp_flags.is_directory = S_ISDIR(fsp->fsp_name->st.st_ex_mode);
757 orig_fsp_name->st = fsp->fsp_name->st;
759 if (!S_ISLNK(fsp->fsp_name->st.st_ex_mode)) {
760 goto out;
764 * Found a symlink to follow in user space
767 if (fsp->fsp_name->flags & SMB_FILENAME_POSIX_PATH) {
768 /* Never follow symlinks on posix open. */
769 status = NT_STATUS_STOPPED_ON_SYMLINK;
770 goto out;
772 if (!lp_follow_symlinks(SNUM(conn))) {
773 /* Explicitly no symlinks. */
774 status = NT_STATUS_STOPPED_ON_SYMLINK;
775 goto out;
778 link_depth += 1;
779 if (link_depth >= 40) {
780 status = NT_STATUS_STOPPED_ON_SYMLINK;
781 goto out;
784 fsp->fsp_name = orig_fsp_name;
786 status = symlink_target_below_conn(
787 talloc_tos(),
788 connpath,
789 fsp,
790 discard_const_p(files_struct, dirfsp),
791 smb_fname_rel,
792 &target);
794 if (!NT_STATUS_IS_OK(status)) {
795 DBG_DEBUG("symlink_target_below_conn() failed: %s\n",
796 nt_errstr(status));
797 goto out;
801 * Close what openat(O_PATH) potentially left behind
803 fd_close(fsp);
805 if (smb_fname->base_name != orig_smb_fname_base) {
806 TALLOC_FREE(smb_fname->base_name);
808 smb_fname->base_name = target;
810 if (oldwd_fname != NULL) {
811 ret = vfs_ChDir(conn, oldwd_fname);
812 if (ret == -1) {
813 smb_panic("unable to get back to old directory\n");
815 TALLOC_FREE(oldwd_fname);
819 * And do it all again... As smb_fname is not relative to the passed in
820 * dirfsp anymore, we pass conn->cwd_fsp as dirfsp to
821 * non_widelink_open() to trigger the chdir(parentdir) logic.
823 dirfsp = conn->cwd_fsp;
825 goto again;
827 out:
828 fsp->fsp_name = orig_fsp_name;
829 smb_fname->base_name = orig_smb_fname_base;
831 TALLOC_FREE(parent_dir_fname);
833 if (!NT_STATUS_IS_OK(status)) {
834 fd_close(fsp);
837 if (oldwd_fname != NULL) {
838 ret = vfs_ChDir(conn, oldwd_fname);
839 if (ret == -1) {
840 smb_panic("unable to get back to old directory\n");
842 TALLOC_FREE(oldwd_fname);
844 return status;
847 /****************************************************************************
848 fd support routines - attempt to do a dos_open.
849 ****************************************************************************/
851 NTSTATUS fd_openat(const struct files_struct *dirfsp,
852 struct smb_filename *smb_fname,
853 files_struct *fsp,
854 const struct vfs_open_how *_how)
856 struct vfs_open_how how = *_how;
857 struct connection_struct *conn = fsp->conn;
858 NTSTATUS status = NT_STATUS_OK;
859 bool fsp_is_stream = fsp_is_alternate_stream(fsp);
860 bool smb_fname_is_stream = is_named_stream(smb_fname);
862 SMB_ASSERT(fsp_is_stream == smb_fname_is_stream);
865 * Never follow symlinks on a POSIX client. The
866 * client should be doing this.
869 if ((fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) || !lp_follow_symlinks(SNUM(conn))) {
870 how.flags |= O_NOFOLLOW;
873 if (fsp_is_stream) {
874 int fd;
876 fd = SMB_VFS_OPENAT(
877 conn,
878 NULL, /* stream open is relative to fsp->base_fsp */
879 smb_fname,
880 fsp,
881 &how);
882 if (fd == -1) {
883 status = map_nt_error_from_unix(errno);
885 fsp_set_fd(fsp, fd);
887 if (fd != -1) {
888 status = vfs_stat_fsp(fsp);
889 if (!NT_STATUS_IS_OK(status)) {
890 DBG_DEBUG("vfs_stat_fsp failed: %s\n",
891 nt_errstr(status));
892 fd_close(fsp);
896 return status;
900 * Only follow symlinks within a share
901 * definition.
903 status = non_widelink_open(dirfsp, fsp, smb_fname, &how);
904 if (!NT_STATUS_IS_OK(status)) {
905 if (NT_STATUS_EQUAL(status, NT_STATUS_TOO_MANY_OPENED_FILES)) {
906 static time_t last_warned = 0L;
908 if (time((time_t *) NULL) > last_warned) {
909 DEBUG(0,("Too many open files, unable "
910 "to open more! smbd's max "
911 "open files = %d\n",
912 lp_max_open_files()));
913 last_warned = time((time_t *) NULL);
917 DBG_DEBUG("name %s, flags = 0%o mode = 0%o, fd = %d. %s\n",
918 smb_fname_str_dbg(smb_fname),
919 how.flags,
920 (int)how.mode,
921 fsp_get_pathref_fd(fsp),
922 nt_errstr(status));
923 return status;
926 DBG_DEBUG("name %s, flags = 0%o mode = 0%o, fd = %d\n",
927 smb_fname_str_dbg(smb_fname),
928 how.flags,
929 (int)how.mode,
930 fsp_get_pathref_fd(fsp));
932 return status;
935 /****************************************************************************
936 Close the file associated with a fsp.
937 ****************************************************************************/
939 NTSTATUS fd_close(files_struct *fsp)
941 NTSTATUS stat_status = NT_STATUS_OK;
942 int ret;
944 if (fsp == fsp->conn->cwd_fsp) {
945 return NT_STATUS_OK;
948 if (fsp->fsp_flags.fstat_before_close) {
950 * capture status, if failure
951 * continue close processing
952 * and return status
954 stat_status = vfs_stat_fsp(fsp);
957 if (fsp->dptr) {
958 dptr_CloseDir(fsp);
960 if (fsp_get_pathref_fd(fsp) == -1) {
962 * Either a directory where the dptr_CloseDir() already closed
963 * the fd or a stat open.
965 return NT_STATUS_OK;
967 if (fh_get_refcount(fsp->fh) > 1) {
968 return NT_STATUS_OK; /* Shared handle. Only close last reference. */
971 ret = SMB_VFS_CLOSE(fsp);
972 fsp_set_fd(fsp, -1);
973 if (ret == -1) {
974 return map_nt_error_from_unix(errno);
976 return stat_status;
979 /****************************************************************************
980 Change the ownership of a file to that of the parent directory.
981 Do this by fd if possible.
982 ****************************************************************************/
984 static void change_file_owner_to_parent_fsp(struct files_struct *parent_fsp,
985 struct files_struct *fsp)
987 int ret;
989 if (parent_fsp->fsp_name->st.st_ex_uid == fsp->fsp_name->st.st_ex_uid) {
990 /* Already this uid - no need to change. */
991 DBG_DEBUG("file %s is already owned by uid %u\n",
992 fsp_str_dbg(fsp),
993 (unsigned int)fsp->fsp_name->st.st_ex_uid);
994 return;
997 become_root();
998 ret = SMB_VFS_FCHOWN(fsp,
999 parent_fsp->fsp_name->st.st_ex_uid,
1000 (gid_t)-1);
1001 unbecome_root();
1002 if (ret == -1) {
1003 DBG_ERR("failed to fchown "
1004 "file %s to parent directory uid %u. Error "
1005 "was %s\n",
1006 fsp_str_dbg(fsp),
1007 (unsigned int)parent_fsp->fsp_name->st.st_ex_uid,
1008 strerror(errno));
1009 } else {
1010 DBG_DEBUG("changed new file %s to "
1011 "parent directory uid %u.\n",
1012 fsp_str_dbg(fsp),
1013 (unsigned int)parent_fsp->fsp_name->st.st_ex_uid);
1014 /* Ensure the uid entry is updated. */
1015 fsp->fsp_name->st.st_ex_uid =
1016 parent_fsp->fsp_name->st.st_ex_uid;
1020 static NTSTATUS change_dir_owner_to_parent_fsp(struct files_struct *parent_fsp,
1021 struct files_struct *fsp)
1023 NTSTATUS status;
1024 int ret;
1026 if (parent_fsp->fsp_name->st.st_ex_uid == fsp->fsp_name->st.st_ex_uid) {
1027 /* Already this uid - no need to change. */
1028 DBG_DEBUG("directory %s is already owned by uid %u\n",
1029 fsp_str_dbg(fsp),
1030 (unsigned int)fsp->fsp_name->st.st_ex_uid);
1031 return NT_STATUS_OK;
1034 become_root();
1035 ret = SMB_VFS_FCHOWN(fsp,
1036 parent_fsp->fsp_name->st.st_ex_uid,
1037 (gid_t)-1);
1038 unbecome_root();
1039 if (ret == -1) {
1040 status = map_nt_error_from_unix(errno);
1041 DBG_ERR("failed to chown "
1042 "directory %s to parent directory uid %u. "
1043 "Error was %s\n",
1044 fsp_str_dbg(fsp),
1045 (unsigned int)parent_fsp->fsp_name->st.st_ex_uid,
1046 nt_errstr(status));
1047 return status;
1050 DBG_DEBUG("changed ownership of new "
1051 "directory %s to parent directory uid %u.\n",
1052 fsp_str_dbg(fsp),
1053 (unsigned int)parent_fsp->fsp_name->st.st_ex_uid);
1055 /* Ensure the uid entry is updated. */
1056 fsp->fsp_name->st.st_ex_uid = parent_fsp->fsp_name->st.st_ex_uid;
1058 return NT_STATUS_OK;
1061 /****************************************************************************
1062 Open a file - returning a guaranteed ATOMIC indication of if the
1063 file was created or not.
1064 ****************************************************************************/
1066 static NTSTATUS fd_open_atomic(struct files_struct *dirfsp,
1067 struct smb_filename *smb_fname,
1068 files_struct *fsp,
1069 const struct vfs_open_how *_how,
1070 bool *file_created)
1072 struct vfs_open_how how = *_how;
1073 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
1074 NTSTATUS retry_status;
1075 bool file_existed = VALID_STAT(smb_fname->st);
1077 if (!(how.flags & O_CREAT)) {
1079 * We're not creating the file, just pass through.
1081 status = fd_openat(dirfsp, smb_fname, fsp, &how);
1082 *file_created = false;
1083 return status;
1086 if (how.flags & O_EXCL) {
1088 * Fail if already exists, just pass through.
1090 status = fd_openat(dirfsp, smb_fname, fsp, &how);
1093 * Here we've opened with O_CREAT|O_EXCL. If that went
1094 * NT_STATUS_OK, we *know* we created this file.
1096 *file_created = NT_STATUS_IS_OK(status);
1098 return status;
1102 * Now it gets tricky. We have O_CREAT, but not O_EXCL.
1103 * To know absolutely if we created the file or not,
1104 * we can never call O_CREAT without O_EXCL. So if
1105 * we think the file existed, try without O_CREAT|O_EXCL.
1106 * If we think the file didn't exist, try with
1107 * O_CREAT|O_EXCL.
1109 * The big problem here is dangling symlinks. Opening
1110 * without O_NOFOLLOW means both bad symlink
1111 * and missing path return -1, ENOENT from open(). As POSIX
1112 * is pathname based it's not possible to tell
1113 * the difference between these two cases in a
1114 * non-racy way, so change to try only two attempts before
1115 * giving up.
1117 * We don't have this problem for the O_NOFOLLOW
1118 * case as it just returns NT_STATUS_OBJECT_PATH_NOT_FOUND
1119 * mapped from the ELOOP POSIX error.
1122 if (file_existed) {
1123 how.flags = _how->flags & ~(O_CREAT);
1124 retry_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
1125 } else {
1126 how.flags = _how->flags | O_EXCL;
1127 retry_status = NT_STATUS_OBJECT_NAME_COLLISION;
1130 status = fd_openat(dirfsp, smb_fname, fsp, &how);
1131 if (NT_STATUS_IS_OK(status)) {
1132 *file_created = !file_existed;
1133 return NT_STATUS_OK;
1135 if (NT_STATUS_EQUAL(status, retry_status)) {
1137 file_existed = !file_existed;
1139 DBG_DEBUG("File %s %s. Retry.\n",
1140 fsp_str_dbg(fsp),
1141 file_existed ? "existed" : "did not exist");
1143 if (file_existed) {
1144 how.flags = _how->flags & ~(O_CREAT);
1145 } else {
1146 how.flags = _how->flags | O_EXCL;
1149 status = fd_openat(dirfsp, smb_fname, fsp, &how);
1152 *file_created = (NT_STATUS_IS_OK(status) && !file_existed);
1153 return status;
1156 static NTSTATUS reopen_from_fsp(struct files_struct *dirfsp,
1157 struct smb_filename *smb_fname,
1158 struct files_struct *fsp,
1159 const struct vfs_open_how *how,
1160 bool *p_file_created)
1162 NTSTATUS status;
1163 int old_fd;
1165 if (fsp->fsp_flags.have_proc_fds &&
1166 ((old_fd = fsp_get_pathref_fd(fsp)) != -1)) {
1168 struct sys_proc_fd_path_buf buf;
1169 struct smb_filename proc_fname = {
1170 .base_name = sys_proc_fd_path(old_fd, &buf),
1172 mode_t mode = fsp->fsp_name->st.st_ex_mode;
1173 int new_fd;
1175 SMB_ASSERT(fsp->fsp_flags.is_pathref);
1177 if (S_ISLNK(mode)) {
1178 return NT_STATUS_STOPPED_ON_SYMLINK;
1180 if (!(S_ISREG(mode) || S_ISDIR(mode))) {
1181 return NT_STATUS_IO_REPARSE_TAG_NOT_HANDLED;
1184 fsp->fsp_flags.is_pathref = false;
1186 new_fd = SMB_VFS_OPENAT(fsp->conn,
1187 fsp->conn->cwd_fsp,
1188 &proc_fname,
1189 fsp,
1190 how);
1191 if (new_fd == -1) {
1192 #if defined(HAVE_FSTATFS) && defined(HAVE_LINUX_MAGIC_H)
1193 if (S_ISDIR(fsp->fsp_name->st.st_ex_mode) &&
1194 (errno == ENOENT)) {
1195 struct statfs sbuf = {};
1196 int ret = fstatfs(old_fd, &sbuf);
1197 if (ret == -1) {
1198 DBG_ERR("fstatfs failed: %s\n",
1199 strerror(errno));
1200 } else if (sbuf.f_type == AUTOFS_SUPER_MAGIC) {
1202 * When reopening an as-yet
1203 * unmounted autofs mount
1204 * point we get ENOENT. We
1205 * have to retry pathbased.
1207 goto namebased_open;
1209 /* restore ENOENT if changed in the meantime */
1210 errno = ENOENT;
1212 #endif
1213 status = map_nt_error_from_unix(errno);
1214 fd_close(fsp);
1215 return status;
1218 status = fd_close(fsp);
1219 if (!NT_STATUS_IS_OK(status)) {
1220 return status;
1223 fsp_set_fd(fsp, new_fd);
1224 return NT_STATUS_OK;
1227 #if defined(HAVE_FSTATFS) && defined(HAVE_LINUX_MAGIC_H)
1228 namebased_open:
1229 #endif
1231 * Close the existing pathref fd and set the fsp flag
1232 * is_pathref to false so we get a "normal" fd this time.
1234 status = fd_close(fsp);
1235 if (!NT_STATUS_IS_OK(status)) {
1236 return status;
1239 fsp->fsp_flags.is_pathref = false;
1241 status = fd_open_atomic(dirfsp, smb_fname, fsp, how, p_file_created);
1242 return status;
1245 /****************************************************************************
1246 Open a file.
1247 ****************************************************************************/
1249 static NTSTATUS open_file(
1250 struct smb_request *req,
1251 struct files_struct *dirfsp,
1252 struct smb_filename *smb_fname_atname,
1253 files_struct *fsp,
1254 const struct vfs_open_how *_how,
1255 uint32_t access_mask, /* client requested access mask. */
1256 uint32_t open_access_mask, /* what we're actually using in the open. */
1257 uint32_t private_flags,
1258 bool *p_file_created)
1260 connection_struct *conn = fsp->conn;
1261 struct smb_filename *smb_fname = fsp->fsp_name;
1262 struct vfs_open_how how = *_how;
1263 NTSTATUS status = NT_STATUS_OK;
1264 bool file_existed = VALID_STAT(fsp->fsp_name->st);
1265 const uint32_t need_fd_mask =
1266 FILE_READ_DATA |
1267 FILE_WRITE_DATA |
1268 FILE_APPEND_DATA |
1269 FILE_EXECUTE |
1270 SEC_FLAG_SYSTEM_SECURITY;
1271 bool creating = !file_existed && (how.flags & O_CREAT);
1272 bool open_fd = false;
1273 bool posix_open = (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN);
1276 * Catch early an attempt to open an existing
1277 * directory as a file.
1279 if (file_existed && S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
1280 return NT_STATUS_FILE_IS_A_DIRECTORY;
1284 * This little piece of insanity is inspired by the
1285 * fact that an NT client can open a file for O_RDONLY,
1286 * but set the create disposition to FILE_EXISTS_TRUNCATE.
1287 * If the client *can* write to the file, then it expects to
1288 * truncate the file, even though it is opening for readonly.
1289 * Quicken uses this stupid trick in backup file creation...
1290 * Thanks *greatly* to "David W. Chapman Jr." <dwcjr@inethouston.net>
1291 * for helping track this one down. It didn't bite us in 2.0.x
1292 * as we always opened files read-write in that release. JRA.
1295 if (((how.flags & O_ACCMODE) == O_RDONLY) && (how.flags & O_TRUNC)) {
1296 DBG_DEBUG("truncate requested on read-only open for file %s\n",
1297 smb_fname_str_dbg(smb_fname));
1298 how.flags = (how.flags & ~O_ACCMODE) | O_RDWR;
1301 /* Check permissions */
1304 * This code was changed after seeing a client open request
1305 * containing the open mode of (DENY_WRITE/read-only) with
1306 * the 'create if not exist' bit set. The previous code
1307 * would fail to open the file read only on a read-only share
1308 * as it was checking the flags parameter directly against O_RDONLY,
1309 * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
1310 * JRA.
1313 if (!CAN_WRITE(conn)) {
1314 /* It's a read-only share - fail if we wanted to write. */
1315 if ((how.flags & O_ACCMODE) != O_RDONLY ||
1316 (how.flags & O_TRUNC) || (how.flags & O_APPEND)) {
1317 DEBUG(3,("Permission denied opening %s\n",
1318 smb_fname_str_dbg(smb_fname)));
1319 return NT_STATUS_ACCESS_DENIED;
1322 * We don't want to write - but we must make sure that
1323 * O_CREAT doesn't create the file if we have write
1324 * access into the directory.
1326 how.flags &= ~(O_CREAT | O_EXCL);
1329 if ((open_access_mask & need_fd_mask) || creating ||
1330 (how.flags & O_TRUNC)) {
1331 open_fd = true;
1334 if (open_fd) {
1335 int ret;
1337 #if defined(O_NONBLOCK) && defined(S_ISFIFO)
1339 * We would block on opening a FIFO with no one else on the
1340 * other end. Do what we used to do and add O_NONBLOCK to the
1341 * open flags. JRA.
1344 if (file_existed && S_ISFIFO(smb_fname->st.st_ex_mode)) {
1345 how.flags |= O_NONBLOCK;
1347 #endif
1349 if (!posix_open) {
1350 const char *wild = smb_fname->base_name;
1352 * Don't open files with Microsoft wildcard characters.
1354 if (fsp_is_alternate_stream(fsp)) {
1356 * wildcard characters are allowed in stream
1357 * names only test the basefilename
1359 wild = fsp->base_fsp->fsp_name->base_name;
1362 if (ms_has_wild(wild)) {
1363 return NT_STATUS_OBJECT_NAME_INVALID;
1367 /* Can we access this file ? */
1368 if (!fsp_is_alternate_stream(fsp)) {
1369 /* Only do this check on non-stream open. */
1370 if (file_existed) {
1371 status = smbd_check_access_rights_fsp(
1372 dirfsp,
1373 fsp,
1374 false,
1375 open_access_mask);
1377 if (!NT_STATUS_IS_OK(status)) {
1378 DBG_DEBUG("smbd_check_access_rights_fsp"
1379 " on file %s returned %s\n",
1380 fsp_str_dbg(fsp),
1381 nt_errstr(status));
1384 if (!NT_STATUS_IS_OK(status) &&
1385 !NT_STATUS_EQUAL(status,
1386 NT_STATUS_OBJECT_NAME_NOT_FOUND))
1388 return status;
1391 if (NT_STATUS_EQUAL(status,
1392 NT_STATUS_OBJECT_NAME_NOT_FOUND))
1394 DEBUG(10, ("open_file: "
1395 "file %s vanished since we "
1396 "checked for existence.\n",
1397 smb_fname_str_dbg(smb_fname)));
1398 file_existed = false;
1399 SET_STAT_INVALID(fsp->fsp_name->st);
1403 if (!file_existed) {
1404 if (!(how.flags & O_CREAT)) {
1405 /* File didn't exist and no O_CREAT. */
1406 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1409 status = check_parent_access_fsp(
1410 dirfsp,
1411 SEC_DIR_ADD_FILE);
1412 if (!NT_STATUS_IS_OK(status)) {
1413 DBG_DEBUG("check_parent_access_fsp on "
1414 "directory %s for file %s "
1415 "returned %s\n",
1416 smb_fname_str_dbg(
1417 dirfsp->fsp_name),
1418 smb_fname_str_dbg(smb_fname),
1419 nt_errstr(status));
1420 return status;
1426 * Actually do the open - if O_TRUNC is needed handle it
1427 * below under the share mode lock.
1429 how.flags &= ~O_TRUNC;
1430 status = reopen_from_fsp(dirfsp,
1431 smb_fname_atname,
1432 fsp,
1433 &how,
1434 p_file_created);
1435 if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) {
1437 * Non-O_PATH reopen that hit a race
1438 * condition: Someone has put a symlink where
1439 * we used to have a file. Can't happen with
1440 * O_PATH and reopening from /proc/self/fd/ or
1441 * equivalent.
1443 status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
1445 if (!NT_STATUS_IS_OK(status)) {
1446 DBG_NOTICE("Error opening file %s (%s) (in_flags=%d) "
1447 "(flags=%d)\n",
1448 smb_fname_str_dbg(smb_fname),
1449 nt_errstr(status),
1450 _how->flags,
1451 how.flags);
1452 return status;
1455 if (how.flags & O_NONBLOCK) {
1457 * GPFS can return ETIMEDOUT for pread on
1458 * nonblocking file descriptors when files
1459 * migrated to tape need to be recalled. I
1460 * could imagine this happens elsewhere
1461 * too. With blocking file descriptors this
1462 * does not happen.
1464 ret = vfs_set_blocking(fsp, true);
1465 if (ret == -1) {
1466 status = map_nt_error_from_unix(errno);
1467 DBG_WARNING("Could not set fd to blocking: "
1468 "%s\n", strerror(errno));
1469 fd_close(fsp);
1470 return status;
1474 if (*p_file_created) {
1475 /* We created this file. */
1477 bool need_re_stat = false;
1478 /* Do all inheritance work after we've
1479 done a successful fstat call and filled
1480 in the stat struct in fsp->fsp_name. */
1482 /* Inherit the ACL if required */
1483 if (lp_inherit_permissions(SNUM(conn))) {
1484 inherit_access_posix_acl(conn,
1485 dirfsp,
1486 smb_fname,
1487 how.mode);
1488 need_re_stat = true;
1491 /* Change the owner if required. */
1492 if (lp_inherit_owner(SNUM(conn)) != INHERIT_OWNER_NO) {
1493 change_file_owner_to_parent_fsp(dirfsp, fsp);
1494 need_re_stat = true;
1497 if (need_re_stat) {
1498 status = vfs_stat_fsp(fsp);
1500 * If we have an fd, this stat should succeed.
1502 if (!NT_STATUS_IS_OK(status)) {
1503 DBG_ERR("Error doing fstat on open "
1504 "file %s (%s)\n",
1505 smb_fname_str_dbg(smb_fname),
1506 nt_errstr(status));
1507 fd_close(fsp);
1508 return status;
1512 notify_fname(conn, NOTIFY_ACTION_ADDED,
1513 FILE_NOTIFY_CHANGE_FILE_NAME,
1514 smb_fname->base_name);
1516 } else {
1517 if (!file_existed) {
1518 /* File must exist for a stat open. */
1519 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1522 if (S_ISLNK(smb_fname->st.st_ex_mode) &&
1523 !posix_open)
1526 * Don't allow stat opens on symlinks directly unless
1527 * it's a POSIX open. Match the return code from
1528 * openat_pathref_fsp().
1530 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1533 if (!fsp->fsp_flags.is_pathref) {
1535 * There is only one legit case where end up here:
1536 * openat_pathref_fsp() failed to open a symlink, so the
1537 * fsp was created by fsp_new() which doesn't set
1538 * is_pathref. Other than that, we should always have a
1539 * pathref fsp at this point. The subsequent checks
1540 * assert this.
1542 if (!(smb_fname->flags & SMB_FILENAME_POSIX_PATH)) {
1543 DBG_ERR("[%s] is not a POSIX pathname\n",
1544 smb_fname_str_dbg(smb_fname));
1545 return NT_STATUS_INTERNAL_ERROR;
1547 if (!S_ISLNK(smb_fname->st.st_ex_mode)) {
1548 DBG_ERR("[%s] is not a symlink\n",
1549 smb_fname_str_dbg(smb_fname));
1550 return NT_STATUS_INTERNAL_ERROR;
1552 if (fsp_get_pathref_fd(fsp) != -1) {
1553 DBG_ERR("fd for [%s] is not -1: fd [%d]\n",
1554 smb_fname_str_dbg(smb_fname),
1555 fsp_get_pathref_fd(fsp));
1556 return NT_STATUS_INTERNAL_ERROR;
1561 * Access to streams is checked by checking the basefile and
1562 * that has already been checked by check_base_file_access()
1563 * in create_file_unixpath().
1565 if (!fsp_is_alternate_stream(fsp)) {
1566 status = smbd_check_access_rights_fsp(dirfsp,
1567 fsp,
1568 false,
1569 open_access_mask);
1571 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) &&
1572 posix_open &&
1573 S_ISLNK(smb_fname->st.st_ex_mode)) {
1574 /* This is a POSIX stat open for delete
1575 * or rename on a symlink that points
1576 * nowhere. Allow. */
1577 DEBUG(10,("open_file: allowing POSIX "
1578 "open on bad symlink %s\n",
1579 smb_fname_str_dbg(smb_fname)));
1580 status = NT_STATUS_OK;
1583 if (!NT_STATUS_IS_OK(status)) {
1584 DBG_DEBUG("smbd_check_access_rights_fsp on file "
1585 "%s returned %s\n",
1586 fsp_str_dbg(fsp),
1587 nt_errstr(status));
1588 return status;
1593 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
1594 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
1595 fsp->file_pid = req ? req->smbpid : 0;
1596 fsp->fsp_flags.can_lock = true;
1597 fsp->fsp_flags.can_read = ((access_mask & FILE_READ_DATA) != 0);
1598 fsp->fsp_flags.can_write =
1599 CAN_WRITE(conn) &&
1600 ((access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) != 0);
1601 if (fsp->fsp_name->twrp != 0) {
1602 fsp->fsp_flags.can_write = false;
1604 fsp->print_file = NULL;
1605 fsp->fsp_flags.modified = false;
1606 fsp->sent_oplock_break = NO_BREAK_SENT;
1607 fsp->fsp_flags.is_directory = false;
1608 if (is_in_path(smb_fname->base_name,
1609 conn->aio_write_behind_list,
1610 posix_open ? true : conn->case_sensitive)) {
1611 fsp->fsp_flags.aio_write_behind = true;
1614 DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
1615 conn->session_info->unix_info->unix_name,
1616 smb_fname_str_dbg(smb_fname),
1617 BOOLSTR(fsp->fsp_flags.can_read),
1618 BOOLSTR(fsp->fsp_flags.can_write),
1619 conn->num_files_open));
1621 return NT_STATUS_OK;
1624 static bool mask_conflict(
1625 uint32_t new_access,
1626 uint32_t existing_access,
1627 uint32_t access_mask,
1628 uint32_t new_sharemode,
1629 uint32_t existing_sharemode,
1630 uint32_t sharemode_mask)
1632 bool want_access = (new_access & access_mask);
1633 bool allow_existing = (existing_sharemode & sharemode_mask);
1634 bool have_access = (existing_access & access_mask);
1635 bool allow_new = (new_sharemode & sharemode_mask);
1637 if (want_access && !allow_existing) {
1638 DBG_DEBUG("Access request 0x%"PRIx32"/0x%"PRIx32" conflicts "
1639 "with existing sharemode 0x%"PRIx32"/0x%"PRIx32"\n",
1640 new_access,
1641 access_mask,
1642 existing_sharemode,
1643 sharemode_mask);
1644 return true;
1646 if (have_access && !allow_new) {
1647 DBG_DEBUG("Sharemode request 0x%"PRIx32"/0x%"PRIx32" conflicts "
1648 "with existing access 0x%"PRIx32"/0x%"PRIx32"\n",
1649 new_sharemode,
1650 sharemode_mask,
1651 existing_access,
1652 access_mask);
1653 return true;
1655 return false;
1658 /****************************************************************************
1659 Check if we can open a file with a share mode.
1660 Returns True if conflict, False if not.
1661 ****************************************************************************/
1663 static const uint32_t conflicting_access =
1664 FILE_WRITE_DATA|
1665 FILE_APPEND_DATA|
1666 FILE_READ_DATA|
1667 FILE_EXECUTE|
1668 DELETE_ACCESS;
1670 static bool share_conflict(uint32_t e_access_mask,
1671 uint32_t e_share_access,
1672 uint32_t access_mask,
1673 uint32_t share_access)
1675 bool conflict;
1677 DBG_DEBUG("existing access_mask = 0x%"PRIx32", "
1678 "existing share access = 0x%"PRIx32", "
1679 "access_mask = 0x%"PRIx32", "
1680 "share_access = 0x%"PRIx32"\n",
1681 e_access_mask,
1682 e_share_access,
1683 access_mask,
1684 share_access);
1686 if ((e_access_mask & conflicting_access) == 0) {
1687 DBG_DEBUG("No conflict due to "
1688 "existing access_mask = 0x%"PRIx32"\n",
1689 e_access_mask);
1690 return false;
1692 if ((access_mask & conflicting_access) == 0) {
1693 DBG_DEBUG("No conflict due to access_mask = 0x%"PRIx32"\n",
1694 access_mask);
1695 return false;
1698 conflict = mask_conflict(
1699 access_mask, e_access_mask, FILE_WRITE_DATA | FILE_APPEND_DATA,
1700 share_access, e_share_access, FILE_SHARE_WRITE);
1701 conflict |= mask_conflict(
1702 access_mask, e_access_mask, FILE_READ_DATA | FILE_EXECUTE,
1703 share_access, e_share_access, FILE_SHARE_READ);
1704 conflict |= mask_conflict(
1705 access_mask, e_access_mask, DELETE_ACCESS,
1706 share_access, e_share_access, FILE_SHARE_DELETE);
1708 DBG_DEBUG("conflict=%s\n", conflict ? "true" : "false");
1709 return conflict;
1712 #if defined(DEVELOPER)
1714 struct validate_my_share_entries_state {
1715 struct smbd_server_connection *sconn;
1716 struct file_id fid;
1717 struct server_id self;
1720 static bool validate_my_share_entries_fn(
1721 struct share_mode_entry *e,
1722 bool *modified,
1723 void *private_data)
1725 struct validate_my_share_entries_state *state = private_data;
1726 files_struct *fsp;
1728 if (!server_id_equal(&state->self, &e->pid)) {
1729 return false;
1732 if (e->op_mid == 0) {
1733 /* INTERNAL_OPEN_ONLY */
1734 return false;
1737 fsp = file_find_dif(state->sconn, state->fid, e->share_file_id);
1738 if (!fsp) {
1739 DBG_ERR("PANIC : %s\n",
1740 share_mode_str(talloc_tos(), 0, &state->fid, e));
1741 smb_panic("validate_my_share_entries: Cannot match a "
1742 "share entry with an open file\n");
1745 if (((uint16_t)fsp->oplock_type) != e->op_type) {
1746 goto panic;
1749 return false;
1751 panic:
1753 char *str;
1754 DBG_ERR("validate_my_share_entries: PANIC : %s\n",
1755 share_mode_str(talloc_tos(), 0, &state->fid, e));
1756 str = talloc_asprintf(talloc_tos(),
1757 "validate_my_share_entries: "
1758 "file %s, oplock_type = 0x%x, op_type = 0x%x\n",
1759 fsp->fsp_name->base_name,
1760 (unsigned int)fsp->oplock_type,
1761 (unsigned int)e->op_type);
1762 smb_panic(str);
1765 return false;
1767 #endif
1770 * Allowed access mask for stat opens relevant to oplocks
1772 bool is_oplock_stat_open(uint32_t access_mask)
1774 const uint32_t stat_open_bits =
1775 (SYNCHRONIZE_ACCESS|
1776 FILE_READ_ATTRIBUTES|
1777 FILE_WRITE_ATTRIBUTES);
1779 return (((access_mask & stat_open_bits) != 0) &&
1780 ((access_mask & ~stat_open_bits) == 0));
1784 * Allowed access mask for stat opens relevant to leases
1786 bool is_lease_stat_open(uint32_t access_mask)
1788 const uint32_t stat_open_bits =
1789 (SYNCHRONIZE_ACCESS|
1790 FILE_READ_ATTRIBUTES|
1791 FILE_WRITE_ATTRIBUTES|
1792 READ_CONTROL_ACCESS);
1794 return (((access_mask & stat_open_bits) != 0) &&
1795 ((access_mask & ~stat_open_bits) == 0));
1798 struct has_delete_on_close_state {
1799 bool ret;
1802 static bool has_delete_on_close_fn(
1803 struct share_mode_entry *e,
1804 bool *modified,
1805 void *private_data)
1807 struct has_delete_on_close_state *state = private_data;
1808 state->ret = !share_entry_stale_pid(e);
1809 return state->ret;
1812 static bool has_delete_on_close(struct share_mode_lock *lck,
1813 uint32_t name_hash)
1815 struct has_delete_on_close_state state = { .ret = false };
1816 bool ok;
1818 if (!is_delete_on_close_set(lck, name_hash)) {
1819 return false;
1822 ok= share_mode_forall_entries(lck, has_delete_on_close_fn, &state);
1823 if (!ok) {
1824 DBG_DEBUG("share_mode_forall_entries failed\n");
1825 return false;
1827 return state.ret;
1830 static void share_mode_flags_restrict(
1831 struct share_mode_lock *lck,
1832 uint32_t access_mask,
1833 uint32_t share_mode,
1834 uint32_t lease_type)
1836 uint32_t existing_access_mask, existing_share_mode;
1837 uint32_t existing_lease_type;
1839 share_mode_flags_get(
1840 lck,
1841 &existing_access_mask,
1842 &existing_share_mode,
1843 &existing_lease_type);
1845 existing_access_mask |= access_mask;
1846 if (access_mask & conflicting_access) {
1847 existing_share_mode &= share_mode;
1849 existing_lease_type |= lease_type;
1851 share_mode_flags_set(
1852 lck,
1853 existing_access_mask,
1854 existing_share_mode,
1855 existing_lease_type,
1856 NULL);
1859 /****************************************************************************
1860 Deal with share modes
1861 Invariant: Share mode must be locked on entry and exit.
1862 Returns -1 on error, or number of share modes on success (may be zero).
1863 ****************************************************************************/
1865 struct open_mode_check_state {
1866 struct file_id fid;
1867 uint32_t access_mask;
1868 uint32_t share_access;
1869 uint32_t lease_type;
1872 static bool open_mode_check_fn(
1873 struct share_mode_entry *e,
1874 bool *modified,
1875 void *private_data)
1877 struct open_mode_check_state *state = private_data;
1878 bool disconnected, stale;
1879 uint32_t access_mask, share_access, lease_type;
1881 disconnected = server_id_is_disconnected(&e->pid);
1882 if (disconnected) {
1883 return false;
1886 access_mask = state->access_mask | e->access_mask;
1887 share_access = state->share_access;
1888 if (e->access_mask & conflicting_access) {
1889 share_access &= e->share_access;
1891 lease_type = state->lease_type | get_lease_type(e, state->fid);
1893 if ((access_mask == state->access_mask) &&
1894 (share_access == state->share_access) &&
1895 (lease_type == state->lease_type)) {
1896 return false;
1899 stale = share_entry_stale_pid(e);
1900 if (stale) {
1901 return false;
1904 state->access_mask = access_mask;
1905 state->share_access = share_access;
1906 state->lease_type = lease_type;
1908 return false;
1911 static NTSTATUS open_mode_check(connection_struct *conn,
1912 struct file_id fid,
1913 struct share_mode_lock *lck,
1914 uint32_t access_mask,
1915 uint32_t share_access)
1917 struct open_mode_check_state state;
1918 bool ok, conflict;
1919 bool modified = false;
1921 if (is_oplock_stat_open(access_mask)) {
1922 /* Stat open that doesn't trigger oplock breaks or share mode
1923 * checks... ! JRA. */
1924 return NT_STATUS_OK;
1928 * Check if the share modes will give us access.
1931 #if defined(DEVELOPER)
1933 struct validate_my_share_entries_state validate_state = {
1934 .sconn = conn->sconn,
1935 .fid = fid,
1936 .self = messaging_server_id(conn->sconn->msg_ctx),
1938 ok = share_mode_forall_entries(
1939 lck, validate_my_share_entries_fn, &validate_state);
1940 SMB_ASSERT(ok);
1942 #endif
1944 share_mode_flags_get(
1945 lck, &state.access_mask, &state.share_access, NULL);
1947 conflict = share_conflict(
1948 state.access_mask,
1949 state.share_access,
1950 access_mask,
1951 share_access);
1952 if (!conflict) {
1953 DBG_DEBUG("No conflict due to share_mode_flags access\n");
1954 return NT_STATUS_OK;
1957 state = (struct open_mode_check_state) {
1958 .fid = fid,
1959 .share_access = (FILE_SHARE_READ|
1960 FILE_SHARE_WRITE|
1961 FILE_SHARE_DELETE),
1965 * Walk the share mode array to recalculate d->flags
1968 ok = share_mode_forall_entries(lck, open_mode_check_fn, &state);
1969 if (!ok) {
1970 DBG_DEBUG("share_mode_forall_entries failed\n");
1971 return NT_STATUS_INTERNAL_ERROR;
1974 share_mode_flags_set(
1975 lck,
1976 state.access_mask,
1977 state.share_access,
1978 state.lease_type,
1979 &modified);
1980 if (!modified) {
1982 * We only end up here if we had a sharing violation
1983 * from d->flags and have recalculated it.
1985 return NT_STATUS_SHARING_VIOLATION;
1988 conflict = share_conflict(
1989 state.access_mask,
1990 state.share_access,
1991 access_mask,
1992 share_access);
1993 if (!conflict) {
1994 DBG_DEBUG("No conflict due to share_mode_flags access\n");
1995 return NT_STATUS_OK;
1998 return NT_STATUS_SHARING_VIOLATION;
2002 * Send a break message to the oplock holder and delay the open for
2003 * our client.
2006 NTSTATUS send_break_message(struct messaging_context *msg_ctx,
2007 const struct file_id *id,
2008 const struct share_mode_entry *exclusive,
2009 uint16_t break_to)
2011 struct oplock_break_message msg = {
2012 .id = *id,
2013 .share_file_id = exclusive->share_file_id,
2014 .break_to = break_to,
2016 enum ndr_err_code ndr_err;
2017 uint8_t msgbuf[33];
2018 DATA_BLOB blob = {.data = msgbuf, .length = sizeof(msgbuf)};
2019 NTSTATUS status;
2021 if (DEBUGLVL(10)) {
2022 struct server_id_buf buf;
2023 DBG_DEBUG("Sending break message to %s\n",
2024 server_id_str_buf(exclusive->pid, &buf));
2025 NDR_PRINT_DEBUG(oplock_break_message, &msg);
2028 ndr_err = ndr_push_struct_into_fixed_blob(
2029 &blob,
2030 &msg,
2031 (ndr_push_flags_fn_t)ndr_push_oplock_break_message);
2032 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
2033 DBG_WARNING("ndr_push_oplock_break_message failed: %s\n",
2034 ndr_errstr(ndr_err));
2035 return ndr_map_error2ntstatus(ndr_err);
2038 status = messaging_send(msg_ctx,
2039 exclusive->pid,
2040 MSG_SMB_BREAK_REQUEST,
2041 &blob);
2042 if (!NT_STATUS_IS_OK(status)) {
2043 DEBUG(3, ("Could not send oplock break message: %s\n",
2044 nt_errstr(status)));
2047 return status;
2050 struct validate_oplock_types_state {
2051 bool valid;
2052 bool batch;
2053 bool ex_or_batch;
2054 bool level2;
2055 bool no_oplock;
2056 uint32_t num_non_stat_opens;
2059 static bool validate_oplock_types_fn(
2060 struct share_mode_entry *e,
2061 bool *modified,
2062 void *private_data)
2064 struct validate_oplock_types_state *state = private_data;
2066 if (e->op_mid == 0) {
2067 /* INTERNAL_OPEN_ONLY */
2068 return false;
2071 if (e->op_type == NO_OPLOCK && is_oplock_stat_open(e->access_mask)) {
2073 * We ignore stat opens in the table - they always
2074 * have NO_OPLOCK and never get or cause breaks. JRA.
2076 return false;
2079 state->num_non_stat_opens += 1;
2081 if (BATCH_OPLOCK_TYPE(e->op_type)) {
2082 /* batch - can only be one. */
2083 if (share_entry_stale_pid(e)) {
2084 DBG_DEBUG("Found stale batch oplock\n");
2085 return false;
2087 if (state->ex_or_batch ||
2088 state->batch ||
2089 state->level2 ||
2090 state->no_oplock) {
2091 DBG_ERR("Bad batch oplock entry\n");
2092 state->valid = false;
2093 return true;
2095 state->batch = true;
2098 if (EXCLUSIVE_OPLOCK_TYPE(e->op_type)) {
2099 if (share_entry_stale_pid(e)) {
2100 DBG_DEBUG("Found stale duplicate oplock\n");
2101 return false;
2103 /* Exclusive or batch - can only be one. */
2104 if (state->ex_or_batch ||
2105 state->level2 ||
2106 state->no_oplock) {
2107 DBG_ERR("Bad exclusive or batch oplock entry\n");
2108 state->valid = false;
2109 return true;
2111 state->ex_or_batch = true;
2114 if (LEVEL_II_OPLOCK_TYPE(e->op_type)) {
2115 if (state->batch || state->ex_or_batch) {
2116 if (share_entry_stale_pid(e)) {
2117 DBG_DEBUG("Found stale LevelII oplock\n");
2118 return false;
2120 DBG_DEBUG("Bad levelII oplock entry\n");
2121 state->valid = false;
2122 return true;
2124 state->level2 = true;
2127 if (e->op_type == NO_OPLOCK) {
2128 if (state->batch || state->ex_or_batch) {
2129 if (share_entry_stale_pid(e)) {
2130 DBG_DEBUG("Found stale NO_OPLOCK entry\n");
2131 return false;
2133 DBG_ERR("Bad no oplock entry\n");
2134 state->valid = false;
2135 return true;
2137 state->no_oplock = true;
2140 return false;
2144 * Do internal consistency checks on the share mode for a file.
2147 static bool validate_oplock_types(struct share_mode_lock *lck)
2149 struct validate_oplock_types_state state = { .valid = true };
2150 static bool skip_validation;
2151 bool validate;
2152 bool ok;
2154 if (skip_validation) {
2155 return true;
2158 validate = lp_parm_bool(-1, "smbd", "validate_oplock_types", false);
2159 if (!validate) {
2160 DBG_DEBUG("smbd:validate_oplock_types not set to yes\n");
2161 skip_validation = true;
2162 return true;
2165 ok = share_mode_forall_entries(lck, validate_oplock_types_fn, &state);
2166 if (!ok) {
2167 DBG_DEBUG("share_mode_forall_entries failed\n");
2168 return false;
2170 if (!state.valid) {
2171 DBG_DEBUG("Got invalid oplock configuration\n");
2172 return false;
2175 if ((state.batch || state.ex_or_batch) &&
2176 (state.num_non_stat_opens != 1)) {
2177 DBG_WARNING("got batch (%d) or ex (%d) non-exclusively "
2178 "(%"PRIu32")\n",
2179 (int)state.batch,
2180 (int)state.ex_or_batch,
2181 state.num_non_stat_opens);
2182 return false;
2185 return true;
2188 static bool is_same_lease(const files_struct *fsp,
2189 const struct share_mode_entry *e,
2190 const struct smb2_lease *lease)
2192 if (e->op_type != LEASE_OPLOCK) {
2193 return false;
2195 if (lease == NULL) {
2196 return false;
2199 return smb2_lease_equal(fsp_client_guid(fsp),
2200 &lease->lease_key,
2201 &e->client_guid,
2202 &e->lease_key);
2205 static bool file_has_brlocks(files_struct *fsp)
2207 struct byte_range_lock *br_lck;
2209 br_lck = brl_get_locks_readonly(fsp);
2210 if (!br_lck)
2211 return false;
2213 return (brl_num_locks(br_lck) > 0);
2216 struct fsp_lease *find_fsp_lease(struct files_struct *new_fsp,
2217 const struct smb2_lease_key *key,
2218 uint32_t current_state,
2219 uint16_t lease_version,
2220 uint16_t lease_epoch)
2222 struct files_struct *fsp;
2225 * TODO: Measure how expensive this loop is with thousands of open
2226 * handles...
2229 for (fsp = file_find_di_first(new_fsp->conn->sconn, new_fsp->file_id, true);
2230 fsp != NULL;
2231 fsp = file_find_di_next(fsp, true)) {
2233 if (fsp == new_fsp) {
2234 continue;
2236 if (fsp->oplock_type != LEASE_OPLOCK) {
2237 continue;
2239 if (smb2_lease_key_equal(&fsp->lease->lease.lease_key, key)) {
2240 fsp->lease->ref_count += 1;
2241 return fsp->lease;
2245 /* Not found - must be leased in another smbd. */
2246 new_fsp->lease = talloc_zero(new_fsp->conn->sconn, struct fsp_lease);
2247 if (new_fsp->lease == NULL) {
2248 return NULL;
2250 new_fsp->lease->ref_count = 1;
2251 new_fsp->lease->sconn = new_fsp->conn->sconn;
2252 new_fsp->lease->lease.lease_key = *key;
2253 new_fsp->lease->lease.lease_state = current_state;
2255 * We internally treat all leases as V2 and update
2256 * the epoch, but when sending breaks it matters if
2257 * the requesting lease was v1 or v2.
2259 new_fsp->lease->lease.lease_version = lease_version;
2260 new_fsp->lease->lease.lease_epoch = lease_epoch;
2261 return new_fsp->lease;
2264 static NTSTATUS try_lease_upgrade(struct files_struct *fsp,
2265 struct share_mode_lock *lck,
2266 const struct GUID *client_guid,
2267 const struct smb2_lease *lease,
2268 uint32_t granted)
2270 bool do_upgrade;
2271 uint32_t current_state, breaking_to_requested, breaking_to_required;
2272 bool breaking;
2273 uint16_t lease_version, epoch;
2274 uint32_t existing, requested;
2275 NTSTATUS status;
2277 status = leases_db_get(
2278 client_guid,
2279 &lease->lease_key,
2280 &fsp->file_id,
2281 &current_state,
2282 &breaking,
2283 &breaking_to_requested,
2284 &breaking_to_required,
2285 &lease_version,
2286 &epoch);
2287 if (!NT_STATUS_IS_OK(status)) {
2288 return status;
2291 fsp->lease = find_fsp_lease(
2292 fsp,
2293 &lease->lease_key,
2294 current_state,
2295 lease_version,
2296 epoch);
2297 if (fsp->lease == NULL) {
2298 DEBUG(1, ("Did not find existing lease for file %s\n",
2299 fsp_str_dbg(fsp)));
2300 return NT_STATUS_NO_MEMORY;
2304 * Upgrade only if the requested lease is a strict upgrade.
2306 existing = current_state;
2307 requested = lease->lease_state;
2310 * Tricky: This test makes sure that "requested" is a
2311 * strict bitwise superset of "existing".
2313 do_upgrade = ((existing & requested) == existing);
2316 * Upgrade only if there's a change.
2318 do_upgrade &= (granted != existing);
2321 * Upgrade only if other leases don't prevent what was asked
2322 * for.
2324 do_upgrade &= (granted == requested);
2327 * only upgrade if we are not in breaking state
2329 do_upgrade &= !breaking;
2331 DEBUG(10, ("existing=%"PRIu32", requested=%"PRIu32", "
2332 "granted=%"PRIu32", do_upgrade=%d\n",
2333 existing, requested, granted, (int)do_upgrade));
2335 if (do_upgrade) {
2336 NTSTATUS set_status;
2338 current_state = granted;
2339 epoch += 1;
2341 set_status = leases_db_set(
2342 client_guid,
2343 &lease->lease_key,
2344 current_state,
2345 breaking,
2346 breaking_to_requested,
2347 breaking_to_required,
2348 lease_version,
2349 epoch);
2351 if (!NT_STATUS_IS_OK(set_status)) {
2352 DBG_DEBUG("leases_db_set failed: %s\n",
2353 nt_errstr(set_status));
2354 return set_status;
2358 fsp_lease_update(fsp);
2360 return NT_STATUS_OK;
2363 static NTSTATUS grant_new_fsp_lease(struct files_struct *fsp,
2364 struct share_mode_lock *lck,
2365 const struct GUID *client_guid,
2366 const struct smb2_lease *lease,
2367 uint32_t granted)
2369 NTSTATUS status;
2371 fsp->lease = talloc_zero(fsp->conn->sconn, struct fsp_lease);
2372 if (fsp->lease == NULL) {
2373 return NT_STATUS_INSUFFICIENT_RESOURCES;
2375 fsp->lease->ref_count = 1;
2376 fsp->lease->sconn = fsp->conn->sconn;
2377 fsp->lease->lease.lease_version = lease->lease_version;
2378 fsp->lease->lease.lease_key = lease->lease_key;
2379 fsp->lease->lease.lease_state = granted;
2380 fsp->lease->lease.lease_epoch = lease->lease_epoch + 1;
2382 status = leases_db_add(client_guid,
2383 &lease->lease_key,
2384 &fsp->file_id,
2385 fsp->lease->lease.lease_state,
2386 fsp->lease->lease.lease_version,
2387 fsp->lease->lease.lease_epoch,
2388 fsp->conn->connectpath,
2389 fsp->fsp_name->base_name,
2390 fsp->fsp_name->stream_name);
2391 if (!NT_STATUS_IS_OK(status)) {
2392 DEBUG(10, ("%s: leases_db_add failed: %s\n", __func__,
2393 nt_errstr(status)));
2394 TALLOC_FREE(fsp->lease);
2395 return NT_STATUS_INSUFFICIENT_RESOURCES;
2399 * We used to set lck->data->modified=true here without
2400 * actually modifying lck->data, triggering a needless
2401 * writeback of lck->data.
2403 * Apart from that writeback, setting modified=true has the
2404 * effect of triggering all waiters for this file to
2405 * retry. This only makes sense if any blocking condition
2406 * (i.e. waiting for a lease to be downgraded or removed) is
2407 * gone. This routine here only adds a lease, so it will never
2408 * free up resources that blocked waiters can now claim. So
2409 * that second effect also does not matter in this
2410 * routine. Thus setting lck->data->modified=true does not
2411 * need to be done here.
2414 return NT_STATUS_OK;
2417 static NTSTATUS grant_fsp_lease(struct files_struct *fsp,
2418 struct share_mode_lock *lck,
2419 const struct smb2_lease *lease,
2420 uint32_t granted)
2422 const struct GUID *client_guid = fsp_client_guid(fsp);
2423 NTSTATUS status;
2425 status = try_lease_upgrade(fsp, lck, client_guid, lease, granted);
2427 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
2428 status = grant_new_fsp_lease(
2429 fsp, lck, client_guid, lease, granted);
2432 return status;
2435 static int map_lease_type_to_oplock(uint32_t lease_type)
2437 int result = NO_OPLOCK;
2439 switch (lease_type) {
2440 case SMB2_LEASE_READ|SMB2_LEASE_WRITE|SMB2_LEASE_HANDLE:
2441 result = BATCH_OPLOCK|EXCLUSIVE_OPLOCK;
2442 break;
2443 case SMB2_LEASE_READ|SMB2_LEASE_WRITE:
2444 result = EXCLUSIVE_OPLOCK;
2445 break;
2446 case SMB2_LEASE_READ|SMB2_LEASE_HANDLE:
2447 case SMB2_LEASE_READ:
2448 result = LEVEL_II_OPLOCK;
2449 break;
2452 return result;
2455 struct blocker_debug_state {
2456 size_t num_blockers;
2459 struct delay_for_oplock_state {
2460 struct files_struct *fsp;
2461 const struct smb2_lease *lease;
2462 bool will_overwrite;
2463 uint32_t delay_mask;
2464 bool first_open_attempt;
2465 bool got_handle_lease;
2466 bool got_oplock;
2467 bool have_other_lease;
2468 uint32_t total_lease_types;
2469 bool delay;
2470 struct blocker_debug_state *blocker_debug_state;
2473 static int blocker_debug_state_destructor(struct blocker_debug_state *state)
2475 if (state->num_blockers == 0) {
2476 return 0;
2479 DBG_DEBUG("blocker_debug_state [%p] num_blockers [%zu]\n",
2480 state, state->num_blockers);
2481 return 0;
2484 static void delay_for_oplock_fn_watch_done(struct tevent_req *subreq);
2486 static bool delay_for_oplock_fn(
2487 struct share_mode_entry *e,
2488 bool *modified,
2489 void *private_data)
2491 struct delay_for_oplock_state *state = private_data;
2492 struct files_struct *fsp = state->fsp;
2493 const struct smb2_lease *lease = state->lease;
2494 bool e_is_lease = (e->op_type == LEASE_OPLOCK);
2495 uint32_t e_lease_type = SMB2_LEASE_NONE;
2496 uint32_t break_to;
2497 bool lease_is_breaking = false;
2498 struct tevent_req *subreq = NULL;
2499 struct server_id_buf idbuf = {};
2501 if (e_is_lease) {
2502 NTSTATUS status;
2504 if (lease != NULL) {
2505 bool our_lease = is_same_lease(fsp, e, lease);
2506 if (our_lease) {
2507 DBG_DEBUG("Ignoring our own lease\n");
2508 return false;
2512 status = leases_db_get(
2513 &e->client_guid,
2514 &e->lease_key,
2515 &fsp->file_id,
2516 &e_lease_type, /* current_state */
2517 &lease_is_breaking,
2518 NULL, /* breaking_to_requested */
2519 NULL, /* breaking_to_required */
2520 NULL, /* lease_version */
2521 NULL); /* epoch */
2524 * leases_db_get() can return NT_STATUS_NOT_FOUND
2525 * if the share_mode_entry e is stale and the
2526 * lease record was already removed. In this case return
2527 * false so the traverse continues.
2530 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND) &&
2531 share_entry_stale_pid(e))
2533 struct GUID_txt_buf guid_strbuf;
2534 struct file_id_buf file_id_strbuf;
2535 DBG_DEBUG("leases_db_get for client_guid [%s] "
2536 "lease_key [%"PRIu64"/%"PRIu64"] "
2537 "file_id [%s] failed for stale "
2538 "share_mode_entry\n",
2539 GUID_buf_string(&e->client_guid, &guid_strbuf),
2540 e->lease_key.data[0],
2541 e->lease_key.data[1],
2542 file_id_str_buf(fsp->file_id, &file_id_strbuf));
2543 return false;
2545 if (!NT_STATUS_IS_OK(status)) {
2546 struct GUID_txt_buf guid_strbuf;
2547 struct file_id_buf file_id_strbuf;
2548 DBG_ERR("leases_db_get for client_guid [%s] "
2549 "lease_key [%"PRIu64"/%"PRIu64"] "
2550 "file_id [%s] failed: %s\n",
2551 GUID_buf_string(&e->client_guid, &guid_strbuf),
2552 e->lease_key.data[0],
2553 e->lease_key.data[1],
2554 file_id_str_buf(fsp->file_id, &file_id_strbuf),
2555 nt_errstr(status));
2556 smb_panic("leases_db_get() failed");
2558 } else {
2559 e_lease_type = get_lease_type(e, fsp->file_id);
2562 if (((e_lease_type & ~state->total_lease_types) != 0) &&
2563 !share_entry_stale_pid(e))
2565 state->total_lease_types |= e_lease_type;
2568 if (!state->got_handle_lease &&
2569 ((e_lease_type & SMB2_LEASE_HANDLE) != 0) &&
2570 !share_entry_stale_pid(e)) {
2571 state->got_handle_lease = true;
2574 if (!state->got_oplock &&
2575 (e->op_type != LEASE_OPLOCK) &&
2576 !share_entry_stale_pid(e)) {
2577 state->got_oplock = true;
2580 if (!state->have_other_lease &&
2581 !is_same_lease(fsp, e, lease) &&
2582 !share_entry_stale_pid(e)) {
2583 state->have_other_lease = true;
2586 if (e_is_lease && is_lease_stat_open(fsp->access_mask)) {
2587 return false;
2590 break_to = e_lease_type & ~state->delay_mask;
2592 if (state->will_overwrite) {
2593 break_to &= ~(SMB2_LEASE_HANDLE|SMB2_LEASE_READ);
2596 DBG_DEBUG("e_lease_type %u, will_overwrite: %u\n",
2597 (unsigned)e_lease_type,
2598 (unsigned)state->will_overwrite);
2600 if ((e_lease_type & ~break_to) == 0) {
2601 if (lease_is_breaking) {
2602 state->delay = true;
2604 return false;
2607 if (share_entry_stale_pid(e)) {
2608 return false;
2611 if (state->will_overwrite) {
2613 * If we break anyway break to NONE directly.
2614 * Otherwise vfs_set_filelen() will trigger the
2615 * break.
2617 break_to &= ~(SMB2_LEASE_READ|SMB2_LEASE_WRITE);
2620 if (!e_is_lease) {
2622 * Oplocks only support breaking to R or NONE.
2624 break_to &= ~(SMB2_LEASE_HANDLE|SMB2_LEASE_WRITE);
2627 DBG_DEBUG("breaking from %d to %d\n",
2628 (int)e_lease_type,
2629 (int)break_to);
2630 send_break_message(
2631 fsp->conn->sconn->msg_ctx, &fsp->file_id, e, break_to);
2632 if (e_lease_type & state->delay_mask) {
2633 state->delay = true;
2635 if (lease_is_breaking && !state->first_open_attempt) {
2636 state->delay = true;
2639 if (!state->delay) {
2640 return false;
2643 if (state->blocker_debug_state == NULL) {
2644 return false;
2647 subreq = server_id_watch_send(state->blocker_debug_state,
2648 fsp->conn->sconn->ev_ctx,
2649 e->pid);
2650 if (subreq == NULL) {
2651 DBG_ERR("server_id_watch_send(%s) returned NULL\n",
2652 server_id_str_buf(e->pid, &idbuf));
2653 return false;
2656 tevent_req_set_callback(subreq,
2657 delay_for_oplock_fn_watch_done,
2658 state->blocker_debug_state);
2660 state->blocker_debug_state->num_blockers++;
2662 DBG_DEBUG("Starting to watch pid [%s] state [%p] num_blockers [%zu]\n",
2663 server_id_str_buf(e->pid, &idbuf),
2664 state->blocker_debug_state,
2665 state->blocker_debug_state->num_blockers);
2667 return false;
2670 static void delay_for_oplock_fn_watch_done(struct tevent_req *subreq)
2672 struct blocker_debug_state *blocker_debug_state = tevent_req_callback_data(
2673 subreq, struct blocker_debug_state);
2674 struct server_id pid = {};
2675 struct server_id_buf idbuf = {};
2676 int ret;
2678 ret = server_id_watch_recv(subreq, &pid);
2679 if (ret != 0) {
2680 DBG_ERR("server_id_watch_recv failed %s\n", strerror(ret));
2681 return;
2684 DBG_DEBUG("state [%p] server_id_watch_recv() returned pid [%s] exited\n",
2685 blocker_debug_state,
2686 server_id_str_buf(pid, &idbuf));
2689 static NTSTATUS delay_for_oplock(files_struct *fsp,
2690 int oplock_request,
2691 const struct smb2_lease *lease,
2692 struct share_mode_lock *lck,
2693 bool have_sharing_violation,
2694 uint32_t create_disposition,
2695 bool first_open_attempt,
2696 int *poplock_type,
2697 uint32_t *pgranted,
2698 struct blocker_debug_state **blocker_debug_state)
2700 struct delay_for_oplock_state state = {
2701 .fsp = fsp,
2702 .lease = lease,
2703 .first_open_attempt = first_open_attempt,
2705 uint32_t requested;
2706 uint32_t granted;
2707 int oplock_type;
2708 bool ok;
2710 *poplock_type = NO_OPLOCK;
2711 *pgranted = 0;
2713 if (fsp->fsp_flags.is_directory) {
2715 * No directory leases yet
2717 SMB_ASSERT(oplock_request == NO_OPLOCK);
2718 if (have_sharing_violation) {
2719 return NT_STATUS_SHARING_VIOLATION;
2721 return NT_STATUS_OK;
2724 if (oplock_request == LEASE_OPLOCK) {
2725 if (lease == NULL) {
2727 * The SMB2 layer should have checked this
2729 return NT_STATUS_INTERNAL_ERROR;
2732 requested = lease->lease_state;
2733 } else {
2734 requested = map_oplock_to_lease_type(
2735 oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK);
2738 share_mode_flags_get(lck, NULL, NULL, &state.total_lease_types);
2740 if (is_oplock_stat_open(fsp->access_mask)) {
2741 goto grant;
2744 if (lp_parm_bool(GLOBAL_SECTION_SNUM,
2745 "smbd lease break",
2746 "debug hung procs",
2747 false))
2749 state.blocker_debug_state = talloc_zero(fsp,
2750 struct blocker_debug_state);
2751 if (state.blocker_debug_state == NULL) {
2752 return NT_STATUS_NO_MEMORY;
2754 talloc_steal(talloc_tos(), state.blocker_debug_state);
2756 talloc_set_destructor(state.blocker_debug_state,
2757 blocker_debug_state_destructor);
2760 state.delay_mask = have_sharing_violation ?
2761 SMB2_LEASE_HANDLE : SMB2_LEASE_WRITE;
2763 switch (create_disposition) {
2764 case FILE_SUPERSEDE:
2765 case FILE_OVERWRITE:
2766 case FILE_OVERWRITE_IF:
2767 state.will_overwrite = true;
2768 break;
2769 default:
2770 state.will_overwrite = false;
2771 break;
2774 state.total_lease_types = SMB2_LEASE_NONE;
2775 ok = share_mode_forall_entries(lck, delay_for_oplock_fn, &state);
2776 if (!ok) {
2777 return NT_STATUS_INTERNAL_ERROR;
2780 if (state.delay) {
2781 *blocker_debug_state = state.blocker_debug_state;
2782 return NT_STATUS_RETRY;
2785 grant:
2786 if (have_sharing_violation) {
2787 return NT_STATUS_SHARING_VIOLATION;
2790 granted = requested;
2792 if (oplock_request == LEASE_OPLOCK) {
2793 if (lp_kernel_oplocks(SNUM(fsp->conn))) {
2794 DEBUG(10, ("No lease granted because kernel oplocks are enabled\n"));
2795 granted = SMB2_LEASE_NONE;
2797 if ((granted & (SMB2_LEASE_READ|SMB2_LEASE_WRITE)) == 0) {
2798 DEBUG(10, ("No read or write lease requested\n"));
2799 granted = SMB2_LEASE_NONE;
2801 if (granted == SMB2_LEASE_WRITE) {
2802 DEBUG(10, ("pure write lease requested\n"));
2803 granted = SMB2_LEASE_NONE;
2805 if (granted == (SMB2_LEASE_WRITE|SMB2_LEASE_HANDLE)) {
2806 DEBUG(10, ("write and handle lease requested\n"));
2807 granted = SMB2_LEASE_NONE;
2811 if (lp_locking(fsp->conn->params) && file_has_brlocks(fsp)) {
2812 DBG_DEBUG("file %s has byte range locks\n",
2813 fsp_str_dbg(fsp));
2814 granted &= ~SMB2_LEASE_READ;
2817 if (state.have_other_lease) {
2819 * Can grant only one writer
2821 granted &= ~SMB2_LEASE_WRITE;
2824 if ((granted & SMB2_LEASE_READ) && !(granted & SMB2_LEASE_WRITE)) {
2825 bool allow_level2 =
2826 (global_client_caps & CAP_LEVEL_II_OPLOCKS) &&
2827 lp_level2_oplocks(SNUM(fsp->conn));
2829 if (!allow_level2) {
2830 granted = SMB2_LEASE_NONE;
2834 if (oplock_request == LEASE_OPLOCK) {
2835 if (state.got_oplock) {
2836 granted &= ~SMB2_LEASE_HANDLE;
2839 oplock_type = LEASE_OPLOCK;
2840 } else {
2841 if (state.got_handle_lease) {
2842 granted = SMB2_LEASE_NONE;
2846 * Reflect possible downgrades from:
2847 * - map_lease_type_to_oplock() => "RH" to just LEVEL_II
2849 oplock_type = map_lease_type_to_oplock(granted);
2850 granted = map_oplock_to_lease_type(oplock_type);
2853 state.total_lease_types |= granted;
2856 uint32_t acc, sh, ls;
2857 share_mode_flags_get(lck, &acc, &sh, &ls);
2858 ls = state.total_lease_types;
2859 share_mode_flags_set(lck, acc, sh, ls, NULL);
2862 DBG_DEBUG("oplock type 0x%x granted (%s%s%s)(0x%x), on file %s, "
2863 "requested 0x%x (%s%s%s)(0x%x) => total (%s%s%s)(0x%x)\n",
2864 fsp->oplock_type,
2865 granted & SMB2_LEASE_READ ? "R":"",
2866 granted & SMB2_LEASE_WRITE ? "W":"",
2867 granted & SMB2_LEASE_HANDLE ? "H":"",
2868 granted,
2869 fsp_str_dbg(fsp),
2870 oplock_request,
2871 requested & SMB2_LEASE_READ ? "R":"",
2872 requested & SMB2_LEASE_WRITE ? "W":"",
2873 requested & SMB2_LEASE_HANDLE ? "H":"",
2874 requested,
2875 state.total_lease_types & SMB2_LEASE_READ ? "R":"",
2876 state.total_lease_types & SMB2_LEASE_WRITE ? "W":"",
2877 state.total_lease_types & SMB2_LEASE_HANDLE ? "H":"",
2878 state.total_lease_types);
2880 *poplock_type = oplock_type;
2881 *pgranted = granted;
2882 return NT_STATUS_OK;
2885 static NTSTATUS handle_share_mode_lease(
2886 files_struct *fsp,
2887 struct share_mode_lock *lck,
2888 uint32_t create_disposition,
2889 uint32_t access_mask,
2890 uint32_t share_access,
2891 int oplock_request,
2892 const struct smb2_lease *lease,
2893 bool first_open_attempt,
2894 int *poplock_type,
2895 uint32_t *pgranted,
2896 struct blocker_debug_state **blocker_debug_state)
2898 bool sharing_violation = false;
2899 NTSTATUS status;
2901 *poplock_type = NO_OPLOCK;
2902 *pgranted = 0;
2904 status = open_mode_check(
2905 fsp->conn, fsp->file_id, lck, access_mask, share_access);
2906 if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
2907 sharing_violation = true;
2908 status = NT_STATUS_OK; /* handled later */
2911 if (!NT_STATUS_IS_OK(status)) {
2912 return status;
2915 if (oplock_request == INTERNAL_OPEN_ONLY) {
2916 if (sharing_violation) {
2917 DBG_DEBUG("Sharing violation for internal open\n");
2918 return NT_STATUS_SHARING_VIOLATION;
2922 * Internal opens never do oplocks or leases. We don't
2923 * need to go through delay_for_oplock().
2925 return NT_STATUS_OK;
2928 status = delay_for_oplock(
2929 fsp,
2930 oplock_request,
2931 lease,
2932 lck,
2933 sharing_violation,
2934 create_disposition,
2935 first_open_attempt,
2936 poplock_type,
2937 pgranted,
2938 blocker_debug_state);
2939 if (!NT_STATUS_IS_OK(status)) {
2940 return status;
2943 return NT_STATUS_OK;
2946 static bool request_timed_out(struct smb_request *req, struct timeval timeout)
2948 struct timeval end_time = timeval_sum(&req->request_time, &timeout);
2949 return timeval_expired(&end_time);
2952 struct defer_open_state {
2953 struct smbXsrv_connection *xconn;
2954 uint64_t mid;
2957 static void defer_open_done(struct tevent_req *req);
2960 * Defer an open and watch a locking.tdb record
2962 * This defers an open that gets rescheduled once the locking.tdb record watch
2963 * is triggered by a change to the record.
2965 * It is used to defer opens that triggered an oplock break and for the SMB1
2966 * sharing violation delay.
2968 static void defer_open(struct share_mode_lock *lck,
2969 struct timeval timeout,
2970 struct smb_request *req,
2971 struct file_id id,
2972 struct blocker_debug_state **blocker_debug_state)
2974 struct deferred_open_record *open_rec = NULL;
2975 struct timeval abs_timeout;
2976 struct defer_open_state *watch_state;
2977 struct tevent_req *watch_req;
2978 struct timeval_buf tvbuf1, tvbuf2;
2979 struct file_id_buf fbuf;
2980 bool ok;
2982 abs_timeout = timeval_sum(&req->request_time, &timeout);
2984 DBG_DEBUG("request time [%s] timeout [%s] mid [%" PRIu64 "] "
2985 "file_id [%s]\n",
2986 timeval_str_buf(&req->request_time, false, true, &tvbuf1),
2987 timeval_str_buf(&abs_timeout, false, true, &tvbuf2),
2988 req->mid,
2989 file_id_str_buf(id, &fbuf));
2991 open_rec = talloc_zero(NULL, struct deferred_open_record);
2992 if (open_rec == NULL) {
2993 TALLOC_FREE(lck);
2994 exit_server("talloc failed");
2997 watch_state = talloc(open_rec, struct defer_open_state);
2998 if (watch_state == NULL) {
2999 exit_server("talloc failed");
3001 watch_state->xconn = req->xconn;
3002 watch_state->mid = req->mid;
3004 DBG_DEBUG("deferring mid %" PRIu64 "\n", req->mid);
3006 watch_req = share_mode_watch_send(
3007 watch_state,
3008 req->sconn->ev_ctx,
3009 lck,
3010 (struct server_id){0});
3011 if (watch_req == NULL) {
3012 exit_server("Could not watch share mode record");
3014 tevent_req_set_callback(watch_req, defer_open_done, watch_state);
3016 talloc_move(watch_req, blocker_debug_state);
3018 ok = tevent_req_set_endtime(watch_req, req->sconn->ev_ctx, abs_timeout);
3019 if (!ok) {
3020 exit_server("tevent_req_set_endtime failed");
3023 ok = push_deferred_open_message_smb(req, timeout, id, open_rec);
3024 if (!ok) {
3025 TALLOC_FREE(lck);
3026 exit_server("push_deferred_open_message_smb failed");
3030 static void defer_open_done(struct tevent_req *req)
3032 struct defer_open_state *state = tevent_req_callback_data(
3033 req, struct defer_open_state);
3034 NTSTATUS status;
3035 bool ret;
3037 status = share_mode_watch_recv(req, NULL, NULL);
3038 TALLOC_FREE(req);
3039 if (!NT_STATUS_IS_OK(status)) {
3040 DBG_ERR("share_mode_watch_recv() returned %s, "
3041 "rescheduling mid %" PRIu64 "\n",
3042 nt_errstr(status), state->mid);
3044 * Even if it failed, retry anyway. TODO: We need a way to
3045 * tell a re-scheduled open about that error.
3049 DEBUG(10, ("scheduling mid %llu\n", (unsigned long long)state->mid));
3051 ret = schedule_deferred_open_message_smb(state->xconn, state->mid);
3052 SMB_ASSERT(ret);
3053 TALLOC_FREE(state);
3057 * Actually attempt the kernel oplock polling open.
3060 static void poll_open_fn(struct tevent_context *ev,
3061 struct tevent_timer *te,
3062 struct timeval current_time,
3063 void *private_data)
3065 struct deferred_open_record *open_rec = talloc_get_type_abort(
3066 private_data, struct deferred_open_record);
3067 bool ok;
3069 TALLOC_FREE(open_rec->watch_req);
3071 ok = schedule_deferred_open_message_smb(
3072 open_rec->xconn, open_rec->mid);
3073 if (!ok) {
3074 exit_server("schedule_deferred_open_message_smb failed");
3076 DBG_DEBUG("timer fired. Retrying open !\n");
3079 static void poll_open_done(struct tevent_req *subreq);
3081 struct poll_open_setup_watcher_state {
3082 TALLOC_CTX *mem_ctx;
3083 struct tevent_context *ev_ctx;
3084 struct tevent_req *watch_req;
3087 static void poll_open_setup_watcher_fn(struct share_mode_lock *lck,
3088 void *private_data)
3090 struct poll_open_setup_watcher_state *state =
3091 (struct poll_open_setup_watcher_state *)private_data;
3093 if (!validate_oplock_types(lck)) {
3094 smb_panic("validate_oplock_types failed");
3097 state->watch_req = share_mode_watch_send(
3098 state->mem_ctx,
3099 state->ev_ctx,
3100 lck,
3101 (struct server_id) {0});
3102 if (state->watch_req == NULL) {
3103 DBG_WARNING("share_mode_watch_send failed\n");
3104 return;
3109 * Reschedule an open for 1 second from now, if not timed out.
3111 static bool setup_poll_open(
3112 struct smb_request *req,
3113 const struct file_id *id,
3114 struct timeval max_timeout,
3115 struct timeval interval)
3117 static struct file_id zero_id = {};
3118 bool ok;
3119 struct deferred_open_record *open_rec = NULL;
3120 struct timeval endtime, next_interval;
3121 struct file_id_buf ftmp;
3123 if (request_timed_out(req, max_timeout)) {
3124 return false;
3127 open_rec = talloc_zero(NULL, struct deferred_open_record);
3128 if (open_rec == NULL) {
3129 DBG_WARNING("talloc failed\n");
3130 return false;
3132 open_rec->xconn = req->xconn;
3133 open_rec->mid = req->mid;
3136 * Make sure open_rec->te does not come later than the
3137 * request's maximum endtime.
3140 endtime = timeval_sum(&req->request_time, &max_timeout);
3141 next_interval = timeval_current_ofs(interval.tv_sec, interval.tv_usec);
3142 next_interval = timeval_min(&endtime, &next_interval);
3144 open_rec->te = tevent_add_timer(
3145 req->sconn->ev_ctx,
3146 open_rec,
3147 next_interval,
3148 poll_open_fn,
3149 open_rec);
3150 if (open_rec->te == NULL) {
3151 DBG_WARNING("tevent_add_timer failed\n");
3152 TALLOC_FREE(open_rec);
3153 return false;
3156 if (id != NULL) {
3157 struct poll_open_setup_watcher_state wstate = {
3158 .mem_ctx = open_rec,
3159 .ev_ctx = req->sconn->ev_ctx,
3161 NTSTATUS status;
3163 status = share_mode_do_locked_vfs_denied(*id,
3164 poll_open_setup_watcher_fn,
3165 &wstate);
3166 if (NT_STATUS_IS_OK(status)) {
3167 if (wstate.watch_req == NULL) {
3168 DBG_WARNING("share_mode_watch_send failed\n");
3169 TALLOC_FREE(open_rec);
3170 return false;
3172 open_rec->watch_req = wstate.watch_req;
3173 tevent_req_set_callback(open_rec->watch_req,
3174 poll_open_done,
3175 open_rec);
3176 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
3177 DBG_WARNING("share_mode_do_locked_vfs_denied failed - %s\n",
3178 nt_errstr(status));
3179 TALLOC_FREE(open_rec);
3180 return false;
3182 } else {
3183 id = &zero_id;
3186 ok = push_deferred_open_message_smb(req, max_timeout, *id, open_rec);
3187 if (!ok) {
3188 DBG_WARNING("push_deferred_open_message_smb failed\n");
3189 TALLOC_FREE(open_rec);
3190 return false;
3193 DBG_DEBUG("poll request time [%s] mid [%" PRIu64 "] file_id [%s]\n",
3194 timeval_string(talloc_tos(), &req->request_time, false),
3195 req->mid,
3196 file_id_str_buf(*id, &ftmp));
3198 return true;
3201 static void poll_open_done(struct tevent_req *subreq)
3203 struct deferred_open_record *open_rec = tevent_req_callback_data(
3204 subreq, struct deferred_open_record);
3205 NTSTATUS status;
3206 bool ok;
3208 status = share_mode_watch_recv(subreq, NULL, NULL);
3209 TALLOC_FREE(subreq);
3210 open_rec->watch_req = NULL;
3211 TALLOC_FREE(open_rec->te);
3213 DBG_DEBUG("dbwrap_watched_watch_recv returned %s\n",
3214 nt_errstr(status));
3216 ok = schedule_deferred_open_message_smb(
3217 open_rec->xconn, open_rec->mid);
3218 if (!ok) {
3219 exit_server("schedule_deferred_open_message_smb failed");
3223 bool defer_smb1_sharing_violation(struct smb_request *req)
3225 bool ok;
3226 int timeout_usecs;
3228 if (!lp_defer_sharing_violations()) {
3229 return false;
3233 * Try every 200msec up to (by default) one second. To be
3234 * precise, according to behaviour note <247> in [MS-CIFS],
3235 * the server tries 5 times. But up to one second should be
3236 * close enough.
3239 timeout_usecs = lp_parm_int(
3240 SNUM(req->conn),
3241 "smbd",
3242 "sharedelay",
3243 SHARING_VIOLATION_USEC_WAIT);
3245 ok = setup_poll_open(
3246 req,
3247 NULL,
3248 (struct timeval) { .tv_usec = timeout_usecs },
3249 (struct timeval) { .tv_usec = 200000 });
3250 return ok;
3253 /****************************************************************************
3254 On overwrite open ensure that the attributes match.
3255 ****************************************************************************/
3257 static bool open_match_attributes(connection_struct *conn,
3258 uint32_t old_dos_attr,
3259 uint32_t new_dos_attr,
3260 mode_t new_unx_mode,
3261 mode_t *returned_unx_mode)
3263 uint32_t noarch_old_dos_attr, noarch_new_dos_attr;
3265 noarch_old_dos_attr = (old_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
3266 noarch_new_dos_attr = (new_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
3268 if((noarch_old_dos_attr == 0 && noarch_new_dos_attr != 0) ||
3269 (noarch_old_dos_attr != 0 && ((noarch_old_dos_attr & noarch_new_dos_attr) == noarch_old_dos_attr))) {
3270 *returned_unx_mode = new_unx_mode;
3271 } else {
3272 *returned_unx_mode = (mode_t)0;
3275 DEBUG(10,("open_match_attributes: old_dos_attr = 0x%x, "
3276 "new_dos_attr = 0x%x "
3277 "returned_unx_mode = 0%o\n",
3278 (unsigned int)old_dos_attr,
3279 (unsigned int)new_dos_attr,
3280 (unsigned int)*returned_unx_mode ));
3282 /* If we're mapping SYSTEM and HIDDEN ensure they match. */
3283 if (lp_map_system(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
3284 if ((old_dos_attr & FILE_ATTRIBUTE_SYSTEM) &&
3285 !(new_dos_attr & FILE_ATTRIBUTE_SYSTEM)) {
3286 return False;
3289 if (lp_map_hidden(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
3290 if ((old_dos_attr & FILE_ATTRIBUTE_HIDDEN) &&
3291 !(new_dos_attr & FILE_ATTRIBUTE_HIDDEN)) {
3292 return False;
3295 return True;
3298 static void schedule_defer_open(struct share_mode_lock *lck,
3299 struct file_id id,
3300 struct smb_request *req,
3301 struct blocker_debug_state **blocker_debug_state)
3303 /* This is a relative time, added to the absolute
3304 request_time value to get the absolute timeout time.
3305 Note that if this is the second or greater time we enter
3306 this codepath for this particular request mid then
3307 request_time is left as the absolute time of the *first*
3308 time this request mid was processed. This is what allows
3309 the request to eventually time out. */
3311 struct timeval timeout;
3313 /* Normally the smbd we asked should respond within
3314 * OPLOCK_BREAK_TIMEOUT seconds regardless of whether
3315 * the client did, give twice the timeout as a safety
3316 * measure here in case the other smbd is stuck
3317 * somewhere else. */
3319 timeout = tevent_timeval_set(OPLOCK_BREAK_TIMEOUT * 2, 0);
3321 if (request_timed_out(req, timeout)) {
3322 return;
3325 defer_open(lck, timeout, req, id, blocker_debug_state);
3328 /****************************************************************************
3329 Reschedule an open call that went asynchronous.
3330 ****************************************************************************/
3332 static void schedule_async_open_timer(struct tevent_context *ev,
3333 struct tevent_timer *te,
3334 struct timeval current_time,
3335 void *private_data)
3337 exit_server("async open timeout");
3340 static void schedule_async_open(struct smb_request *req)
3342 struct deferred_open_record *open_rec = NULL;
3343 struct timeval timeout = tevent_timeval_set(20, 0);
3344 bool ok;
3346 if (request_timed_out(req, timeout)) {
3347 return;
3350 open_rec = talloc_zero(NULL, struct deferred_open_record);
3351 if (open_rec == NULL) {
3352 exit_server("deferred_open_record_create failed");
3354 open_rec->async_open = true;
3356 ok = push_deferred_open_message_smb(
3357 req, timeout, (struct file_id){0}, open_rec);
3358 if (!ok) {
3359 exit_server("push_deferred_open_message_smb failed");
3362 open_rec->te = tevent_add_timer(req->sconn->ev_ctx,
3363 req,
3364 timeval_current_ofs(20, 0),
3365 schedule_async_open_timer,
3366 open_rec);
3367 if (open_rec->te == NULL) {
3368 exit_server("tevent_add_timer failed");
3372 static NTSTATUS check_and_store_share_mode(
3373 struct files_struct *fsp,
3374 struct smb_request *req,
3375 struct share_mode_lock *lck,
3376 uint32_t create_disposition,
3377 uint32_t access_mask,
3378 uint32_t share_access,
3379 int oplock_request,
3380 const struct smb2_lease *lease,
3381 bool first_open_attempt)
3383 NTSTATUS status;
3384 int oplock_type = NO_OPLOCK;
3385 uint32_t granted_lease = 0;
3386 const struct smb2_lease_key *lease_key = NULL;
3387 struct blocker_debug_state *blocker_debug_state = NULL;
3388 bool delete_on_close;
3389 bool ok;
3391 /* Get the types we need to examine. */
3392 if (!validate_oplock_types(lck)) {
3393 smb_panic("validate_oplock_types failed");
3396 delete_on_close = has_delete_on_close(lck, fsp->name_hash);
3397 if (delete_on_close) {
3398 return NT_STATUS_DELETE_PENDING;
3401 status = handle_share_mode_lease(fsp,
3402 lck,
3403 create_disposition,
3404 access_mask,
3405 share_access,
3406 oplock_request,
3407 lease,
3408 first_open_attempt,
3409 &oplock_type,
3410 &granted_lease,
3411 &blocker_debug_state);
3412 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
3413 schedule_defer_open(lck, fsp->file_id, req, &blocker_debug_state);
3414 return NT_STATUS_SHARING_VIOLATION;
3416 if (!NT_STATUS_IS_OK(status)) {
3417 return status;
3420 if (oplock_type == LEASE_OPLOCK) {
3421 lease_key = &lease->lease_key;
3424 share_mode_flags_restrict(lck, access_mask, share_access, 0);
3426 ok = set_share_mode(lck,
3427 fsp,
3428 get_current_uid(fsp->conn),
3429 req ? req->mid : 0,
3430 oplock_type,
3431 lease_key,
3432 share_access,
3433 access_mask);
3434 if (!ok) {
3435 return NT_STATUS_NO_MEMORY;
3438 if (oplock_type == LEASE_OPLOCK) {
3439 status = grant_fsp_lease(fsp, lck, lease, granted_lease);
3440 if (!NT_STATUS_IS_OK(status)) {
3441 del_share_mode(lck, fsp);
3442 return status;
3445 DBG_DEBUG("lease_state=%d\n", fsp->lease->lease.lease_state);
3448 fsp->oplock_type = oplock_type;
3450 return NT_STATUS_OK;
3453 /****************************************************************************
3454 Work out what access_mask to use from what the client sent us.
3455 ****************************************************************************/
3457 static NTSTATUS smbd_calculate_maximum_allowed_access_fsp(
3458 struct files_struct *dirfsp,
3459 struct files_struct *fsp,
3460 bool use_privs,
3461 uint32_t *p_access_mask)
3463 struct security_descriptor *sd = NULL;
3464 uint32_t access_granted = 0;
3465 uint32_t dosattrs;
3466 NTSTATUS status;
3468 /* Cope with symlinks */
3469 if (fsp == NULL || fsp_get_pathref_fd(fsp) == -1) {
3470 *p_access_mask = FILE_GENERIC_ALL;
3471 return NT_STATUS_OK;
3474 /* Cope with fake/printer fsp's. */
3475 if (fsp->fake_file_handle != NULL || fsp->print_file != NULL) {
3476 *p_access_mask = FILE_GENERIC_ALL;
3477 return NT_STATUS_OK;
3480 if (!use_privs && (get_current_uid(fsp->conn) == (uid_t)0)) {
3481 *p_access_mask |= FILE_GENERIC_ALL;
3482 return NT_STATUS_OK;
3485 status = SMB_VFS_FGET_NT_ACL(metadata_fsp(fsp),
3486 (SECINFO_OWNER |
3487 SECINFO_GROUP |
3488 SECINFO_DACL),
3489 talloc_tos(),
3490 &sd);
3492 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
3494 * File did not exist
3496 *p_access_mask = FILE_GENERIC_ALL;
3497 return NT_STATUS_OK;
3499 if (!NT_STATUS_IS_OK(status)) {
3500 DBG_ERR("Could not get acl on file %s: %s\n",
3501 fsp_str_dbg(fsp),
3502 nt_errstr(status));
3503 return status;
3507 * If we can access the path to this file, by
3508 * default we have FILE_READ_ATTRIBUTES from the
3509 * containing directory. See the section:
3510 * "Algorithm to Check Access to an Existing File"
3511 * in MS-FSA.pdf.
3513 * se_file_access_check()
3514 * also takes care of owner WRITE_DAC and READ_CONTROL.
3516 status = se_file_access_check(sd,
3517 get_current_nttok(fsp->conn),
3518 use_privs,
3519 (*p_access_mask & ~FILE_READ_ATTRIBUTES),
3520 &access_granted);
3522 TALLOC_FREE(sd);
3524 if (!NT_STATUS_IS_OK(status)) {
3525 DBG_ERR("Status %s on file %s: "
3526 "when calculating maximum access\n",
3527 nt_errstr(status),
3528 fsp_str_dbg(fsp));
3529 return status;
3532 *p_access_mask = (access_granted | FILE_READ_ATTRIBUTES);
3534 if (!(access_granted & DELETE_ACCESS)) {
3535 if (can_delete_file_in_directory(fsp->conn,
3536 dirfsp,
3537 fsp->fsp_name)) {
3538 *p_access_mask |= DELETE_ACCESS;
3542 dosattrs = fdos_mode(fsp);
3543 if ((dosattrs & FILE_ATTRIBUTE_READONLY) || !CAN_WRITE(fsp->conn)) {
3544 *p_access_mask &= ~(FILE_GENERIC_WRITE | DELETE_ACCESS);
3547 return NT_STATUS_OK;
3550 NTSTATUS smbd_calculate_access_mask_fsp(struct files_struct *dirfsp,
3551 struct files_struct *fsp,
3552 bool use_privs,
3553 uint32_t access_mask,
3554 uint32_t *access_mask_out)
3556 NTSTATUS status;
3557 uint32_t orig_access_mask = access_mask;
3558 uint32_t rejected_share_access;
3560 if (access_mask & SEC_MASK_INVALID) {
3561 DBG_DEBUG("access_mask [%8x] contains invalid bits\n",
3562 access_mask);
3563 return NT_STATUS_ACCESS_DENIED;
3567 * Convert GENERIC bits to specific bits.
3570 se_map_generic(&access_mask, &file_generic_mapping);
3572 /* Calculate MAXIMUM_ALLOWED_ACCESS if requested. */
3573 if (access_mask & MAXIMUM_ALLOWED_ACCESS) {
3575 status = smbd_calculate_maximum_allowed_access_fsp(
3576 dirfsp,
3577 fsp,
3578 use_privs,
3579 &access_mask);
3581 if (!NT_STATUS_IS_OK(status)) {
3582 return status;
3585 access_mask &= fsp->conn->share_access;
3588 rejected_share_access = access_mask & ~(fsp->conn->share_access);
3590 if (rejected_share_access) {
3591 DBG_INFO("Access denied on file %s: "
3592 "rejected by share access mask[0x%08X] "
3593 "orig[0x%08X] mapped[0x%08X] reject[0x%08X]\n",
3594 fsp_str_dbg(fsp),
3595 fsp->conn->share_access,
3596 orig_access_mask, access_mask,
3597 rejected_share_access);
3598 return NT_STATUS_ACCESS_DENIED;
3601 *access_mask_out = access_mask;
3602 return NT_STATUS_OK;
3605 /****************************************************************************
3606 Remove the deferred open entry under lock.
3607 ****************************************************************************/
3609 /****************************************************************************
3610 Return true if this is a state pointer to an asynchronous create.
3611 ****************************************************************************/
3613 bool is_deferred_open_async(const struct deferred_open_record *rec)
3615 return rec->async_open;
3618 static bool clear_ads(uint32_t create_disposition)
3620 bool ret = false;
3622 switch (create_disposition) {
3623 case FILE_SUPERSEDE:
3624 case FILE_OVERWRITE_IF:
3625 case FILE_OVERWRITE:
3626 ret = true;
3627 break;
3628 default:
3629 break;
3631 return ret;
3634 static int disposition_to_open_flags(uint32_t create_disposition)
3636 int ret = 0;
3639 * Currently we're using FILE_SUPERSEDE as the same as
3640 * FILE_OVERWRITE_IF but they really are
3641 * different. FILE_SUPERSEDE deletes an existing file
3642 * (requiring delete access) then recreates it.
3645 switch (create_disposition) {
3646 case FILE_SUPERSEDE:
3647 case FILE_OVERWRITE_IF:
3649 * If file exists replace/overwrite. If file doesn't
3650 * exist create.
3652 ret = O_CREAT|O_TRUNC;
3653 break;
3655 case FILE_OPEN:
3657 * If file exists open. If file doesn't exist error.
3659 ret = 0;
3660 break;
3662 case FILE_OVERWRITE:
3664 * If file exists overwrite. If file doesn't exist
3665 * error.
3667 ret = O_TRUNC;
3668 break;
3670 case FILE_CREATE:
3672 * If file exists error. If file doesn't exist create.
3674 ret = O_CREAT|O_EXCL;
3675 break;
3677 case FILE_OPEN_IF:
3679 * If file exists open. If file doesn't exist create.
3681 ret = O_CREAT;
3682 break;
3684 return ret;
3687 static int calculate_open_access_flags(uint32_t access_mask,
3688 uint32_t private_flags,
3689 NTTIME twrp)
3691 bool need_write, need_read;
3694 * Note that we ignore the append flag as append does not
3695 * mean the same thing under DOS and Unix.
3698 if (twrp != 0) {
3700 * Pave over the user requested mode and force O_RDONLY for the
3701 * file handle. Windows allows opening a VSS file with O_RDWR,
3702 * even though actual writes on the handle will fail.
3704 return O_RDONLY;
3707 need_write = (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA));
3708 if (!need_write) {
3709 return O_RDONLY;
3712 /* DENY_DOS opens are always underlying read-write on the
3713 file handle, no matter what the requested access mask
3714 says. */
3716 need_read =
3717 ((private_flags & NTCREATEX_FLAG_DENY_DOS) ||
3718 access_mask & (FILE_READ_ATTRIBUTES|FILE_READ_DATA|
3719 FILE_READ_EA|FILE_EXECUTE));
3721 if (!need_read) {
3722 return O_WRONLY;
3724 return O_RDWR;
3727 struct open_ntcreate_lock_state {
3728 struct share_mode_entry_prepare_state prepare_state;
3729 struct files_struct *fsp;
3730 const char *object_type;
3731 struct smb_request *req;
3732 uint32_t create_disposition;
3733 uint32_t access_mask;
3734 uint32_t share_access;
3735 int oplock_request;
3736 const struct smb2_lease *lease;
3737 bool first_open_attempt;
3738 bool keep_locked;
3739 NTSTATUS status;
3740 struct timespec write_time;
3741 share_mode_entry_prepare_unlock_fn_t cleanup_fn;
3744 static void open_ntcreate_lock_add_entry(struct share_mode_lock *lck,
3745 bool *keep_locked,
3746 void *private_data)
3748 struct open_ntcreate_lock_state *state =
3749 (struct open_ntcreate_lock_state *)private_data;
3752 * By default drop the g_lock again if we leave the
3753 * tdb chainlock.
3755 *keep_locked = false;
3757 state->status = check_and_store_share_mode(state->fsp,
3758 state->req,
3759 lck,
3760 state->create_disposition,
3761 state->access_mask,
3762 state->share_access,
3763 state->oplock_request,
3764 state->lease,
3765 state->first_open_attempt);
3766 if (!NT_STATUS_IS_OK(state->status)) {
3767 return;
3770 state->write_time = get_share_mode_write_time(lck);
3773 * keep the g_lock while existing the tdb chainlock,
3774 * we we're asked to, which mean we'll keep
3775 * the share_mode_lock during object creation,
3776 * or setting delete on close.
3778 *keep_locked = state->keep_locked;
3781 static void open_ntcreate_lock_cleanup_oplock(struct share_mode_lock *lck,
3782 void *private_data)
3784 struct open_ntcreate_lock_state *state =
3785 (struct open_ntcreate_lock_state *)private_data;
3786 bool ok;
3788 ok = remove_share_oplock(lck, state->fsp);
3789 if (!ok) {
3790 DBG_ERR("Could not remove oplock for %s %s\n",
3791 state->object_type, fsp_str_dbg(state->fsp));
3795 static void open_ntcreate_lock_cleanup_entry(struct share_mode_lock *lck,
3796 void *private_data)
3798 struct open_ntcreate_lock_state *state =
3799 (struct open_ntcreate_lock_state *)private_data;
3800 bool ok;
3802 ok = del_share_mode(lck, state->fsp);
3803 if (!ok) {
3804 DBG_ERR("Could not delete share entry for %s %s\n",
3805 state->object_type, fsp_str_dbg(state->fsp));
3809 static void possibly_set_archive(struct connection_struct *conn,
3810 struct files_struct *fsp,
3811 struct smb_filename *smb_fname,
3812 struct smb_filename *parent_dir_fname,
3813 int info,
3814 uint32_t dosattrs,
3815 mode_t *unx_mode)
3817 bool set_archive = false;
3818 int ret;
3820 if (info == FILE_WAS_OPENED) {
3821 return;
3824 /* Overwritten files should be initially set as archive */
3825 if ((info == FILE_WAS_OVERWRITTEN && lp_map_archive(SNUM(conn)))) {
3826 set_archive = true;
3827 } else if (lp_store_dos_attributes(SNUM(conn))) {
3828 set_archive = true;
3830 if (!set_archive) {
3831 return;
3834 ret = file_set_dosmode(conn,
3835 smb_fname,
3836 dosattrs | FILE_ATTRIBUTE_ARCHIVE,
3837 parent_dir_fname,
3838 true);
3839 if (ret != 0) {
3840 return;
3842 *unx_mode = smb_fname->st.st_ex_mode;
3845 /****************************************************************************
3846 Open a file with a share mode. Passed in an already created files_struct *.
3847 ****************************************************************************/
3849 static NTSTATUS open_file_ntcreate(connection_struct *conn,
3850 struct smb_request *req,
3851 uint32_t access_mask, /* access bits (FILE_READ_DATA etc.) */
3852 uint32_t share_access, /* share constants (FILE_SHARE_READ etc) */
3853 uint32_t create_disposition, /* FILE_OPEN_IF etc. */
3854 uint32_t create_options, /* options such as delete on close. */
3855 uint32_t new_dos_attributes, /* attributes used for new file. */
3856 int oplock_request, /* internal Samba oplock codes. */
3857 const struct smb2_lease *lease,
3858 /* Information (FILE_EXISTS etc.) */
3859 uint32_t private_flags, /* Samba specific flags. */
3860 struct smb_filename *parent_dir_fname, /* parent. */
3861 struct smb_filename *smb_fname_atname, /* atname relative to parent. */
3862 int *pinfo,
3863 files_struct *fsp)
3865 struct smb_filename *smb_fname = fsp->fsp_name;
3866 int flags=0;
3867 bool file_existed = VALID_STAT(smb_fname->st);
3868 bool def_acl = False;
3869 bool posix_open = False;
3870 bool new_file_created = False;
3871 bool first_open_attempt = true;
3872 bool is_twrp = (smb_fname_atname->twrp != 0);
3873 NTSTATUS fsp_open = NT_STATUS_ACCESS_DENIED;
3874 mode_t new_unx_mode = (mode_t)0;
3875 mode_t unx_mode = (mode_t)0;
3876 int info;
3877 uint32_t existing_dos_attributes = 0;
3878 struct open_ntcreate_lock_state lck_state = {};
3879 bool keep_locked = false;
3880 uint32_t open_access_mask = access_mask;
3881 NTSTATUS status;
3882 SMB_STRUCT_STAT saved_stat = smb_fname->st;
3883 struct timespec old_write_time;
3884 bool setup_poll = false;
3885 NTSTATUS ulstatus;
3887 if (conn->printer) {
3889 * Printers are handled completely differently.
3890 * Most of the passed parameters are ignored.
3893 if (pinfo) {
3894 *pinfo = FILE_WAS_CREATED;
3897 DBG_DEBUG("printer open fname=%s\n",
3898 smb_fname_str_dbg(smb_fname));
3900 if (!req) {
3901 DBG_ERR("printer open without an SMB request!\n");
3902 return NT_STATUS_INTERNAL_ERROR;
3905 return print_spool_open(fsp, smb_fname->base_name,
3906 req->vuid);
3909 if (new_dos_attributes & FILE_FLAG_POSIX_SEMANTICS) {
3910 posix_open = True;
3911 unx_mode = (mode_t)(new_dos_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
3912 new_dos_attributes = 0;
3913 } else {
3914 /* Windows allows a new file to be created and
3915 silently removes a FILE_ATTRIBUTE_DIRECTORY
3916 sent by the client. Do the same. */
3918 new_dos_attributes &= ~FILE_ATTRIBUTE_DIRECTORY;
3920 /* We add FILE_ATTRIBUTE_ARCHIVE to this as this mode is only used if the file is
3921 * created new. */
3922 unx_mode = unix_mode(
3923 conn,
3924 new_dos_attributes | FILE_ATTRIBUTE_ARCHIVE,
3925 smb_fname,
3926 parent_dir_fname->fsp);
3929 DEBUG(10, ("open_file_ntcreate: fname=%s, dos_attrs=0x%x "
3930 "access_mask=0x%x share_access=0x%x "
3931 "create_disposition = 0x%x create_options=0x%x "
3932 "unix mode=0%o oplock_request=%d private_flags = 0x%x\n",
3933 smb_fname_str_dbg(smb_fname), new_dos_attributes,
3934 access_mask, share_access, create_disposition,
3935 create_options, (unsigned int)unx_mode, oplock_request,
3936 (unsigned int)private_flags));
3938 if (req == NULL) {
3939 /* Ensure req == NULL means INTERNAL_OPEN_ONLY */
3940 SMB_ASSERT(oplock_request == INTERNAL_OPEN_ONLY);
3941 } else {
3942 /* And req != NULL means no INTERNAL_OPEN_ONLY */
3943 SMB_ASSERT(((oplock_request & INTERNAL_OPEN_ONLY) == 0));
3947 * Only non-internal opens can be deferred at all
3950 if (req) {
3951 struct deferred_open_record *open_rec;
3952 if (get_deferred_open_message_state(req, NULL, &open_rec)) {
3954 /* If it was an async create retry, the file
3955 didn't exist. */
3957 if (is_deferred_open_async(open_rec)) {
3958 SET_STAT_INVALID(smb_fname->st);
3959 file_existed = false;
3962 /* Ensure we don't reprocess this message. */
3963 remove_deferred_open_message_smb(req->xconn, req->mid);
3965 first_open_attempt = false;
3969 if (!posix_open) {
3970 new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
3971 if (file_existed) {
3973 * Only use stored DOS attributes for checks
3974 * against requested attributes (below via
3975 * open_match_attributes()), cf bug #11992
3976 * for details. -slow
3978 uint32_t attr = 0;
3980 status = SMB_VFS_FGET_DOS_ATTRIBUTES(
3981 conn,
3982 metadata_fsp(smb_fname->fsp),
3983 &attr);
3984 if (NT_STATUS_IS_OK(status)) {
3985 existing_dos_attributes = attr;
3990 /* ignore any oplock requests if oplocks are disabled */
3991 if (!lp_oplocks(SNUM(conn)) ||
3992 IS_VETO_OPLOCK_PATH(conn, smb_fname->base_name)) {
3993 /* Mask off everything except the private Samba bits. */
3994 oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
3997 /* this is for OS/2 long file names - say we don't support them */
3998 if (req != NULL && !req->posix_pathnames &&
3999 strstr(smb_fname->base_name,".+,;=[].")) {
4000 /* OS/2 Workplace shell fix may be main code stream in a later
4001 * release. */
4002 DEBUG(5,("open_file_ntcreate: OS/2 long filenames are not "
4003 "supported.\n"));
4004 if (use_nt_status()) {
4005 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4007 return NT_STATUS_DOS(ERRDOS, ERRcannotopen);
4010 switch( create_disposition ) {
4011 case FILE_OPEN:
4012 /* If file exists open. If file doesn't exist error. */
4013 if (!file_existed) {
4014 DEBUG(5,("open_file_ntcreate: FILE_OPEN "
4015 "requested for file %s and file "
4016 "doesn't exist.\n",
4017 smb_fname_str_dbg(smb_fname)));
4018 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4020 break;
4022 case FILE_OVERWRITE:
4023 /* If file exists overwrite. If file doesn't exist
4024 * error. */
4025 if (!file_existed) {
4026 DEBUG(5,("open_file_ntcreate: FILE_OVERWRITE "
4027 "requested for file %s and file "
4028 "doesn't exist.\n",
4029 smb_fname_str_dbg(smb_fname) ));
4030 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4032 if (is_twrp) {
4033 return NT_STATUS_MEDIA_WRITE_PROTECTED;
4035 break;
4037 case FILE_CREATE:
4038 /* If file exists error. If file doesn't exist
4039 * create. */
4040 if (file_existed) {
4041 DEBUG(5,("open_file_ntcreate: FILE_CREATE "
4042 "requested for file %s and file "
4043 "already exists.\n",
4044 smb_fname_str_dbg(smb_fname)));
4045 if (S_ISDIR(smb_fname->st.st_ex_mode)) {
4046 return NT_STATUS_FILE_IS_A_DIRECTORY;
4048 return NT_STATUS_OBJECT_NAME_COLLISION;
4050 if (is_twrp) {
4051 return NT_STATUS_MEDIA_WRITE_PROTECTED;
4053 break;
4055 case FILE_SUPERSEDE:
4056 case FILE_OVERWRITE_IF:
4057 if (is_twrp) {
4058 return NT_STATUS_MEDIA_WRITE_PROTECTED;
4060 break;
4061 case FILE_OPEN_IF:
4062 if (is_twrp) {
4063 if (!file_existed) {
4064 return NT_STATUS_MEDIA_WRITE_PROTECTED;
4066 create_disposition = FILE_OPEN;
4068 break;
4069 default:
4070 return NT_STATUS_INVALID_PARAMETER;
4073 flags = disposition_to_open_flags(create_disposition);
4075 /* We only care about matching attributes on file exists and
4076 * overwrite. */
4078 if (!posix_open && file_existed &&
4079 ((create_disposition == FILE_OVERWRITE) ||
4080 (create_disposition == FILE_OVERWRITE_IF))) {
4081 if (!open_match_attributes(conn, existing_dos_attributes,
4082 new_dos_attributes,
4083 unx_mode, &new_unx_mode)) {
4084 DEBUG(5,("open_file_ntcreate: attributes mismatch "
4085 "for file %s (%x %x) (0%o, 0%o)\n",
4086 smb_fname_str_dbg(smb_fname),
4087 existing_dos_attributes,
4088 new_dos_attributes,
4089 (unsigned int)smb_fname->st.st_ex_mode,
4090 (unsigned int)unx_mode ));
4091 return NT_STATUS_ACCESS_DENIED;
4095 status = smbd_calculate_access_mask_fsp(parent_dir_fname->fsp,
4096 smb_fname->fsp,
4097 false,
4098 access_mask,
4099 &access_mask);
4100 if (!NT_STATUS_IS_OK(status)) {
4101 DBG_DEBUG("smbd_calculate_access_mask_fsp "
4102 "on file %s returned %s\n",
4103 smb_fname_str_dbg(smb_fname),
4104 nt_errstr(status));
4105 return status;
4108 open_access_mask = access_mask;
4110 if (flags & O_TRUNC) {
4111 open_access_mask |= FILE_WRITE_DATA; /* This will cause oplock breaks. */
4114 if (file_existed) {
4116 * stat opens on existing files don't get oplocks.
4117 * They can get leases.
4119 * Note that we check for stat open on the *open_access_mask*,
4120 * i.e. the access mask we actually used to do the open,
4121 * not the one the client asked for (which is in
4122 * fsp->access_mask). This is due to the fact that
4123 * FILE_OVERWRITE and FILE_OVERWRITE_IF add in O_TRUNC,
4124 * which adds FILE_WRITE_DATA to open_access_mask.
4126 if (is_oplock_stat_open(open_access_mask) && lease == NULL) {
4127 oplock_request = NO_OPLOCK;
4131 DEBUG(10, ("open_file_ntcreate: fname=%s, after mapping "
4132 "access_mask=0x%x\n", smb_fname_str_dbg(smb_fname),
4133 access_mask));
4136 * Note that we ignore the append flag as append does not
4137 * mean the same thing under DOS and Unix.
4140 flags |= calculate_open_access_flags(access_mask,
4141 private_flags,
4142 smb_fname->twrp);
4145 * Currently we only look at FILE_WRITE_THROUGH for create options.
4148 #if defined(O_SYNC)
4149 if ((create_options & FILE_WRITE_THROUGH) && lp_strict_sync(SNUM(conn))) {
4150 flags |= O_SYNC;
4152 #endif /* O_SYNC */
4154 if (posix_open && (access_mask & FILE_APPEND_DATA)) {
4155 flags |= O_APPEND;
4158 if (!posix_open && !CAN_WRITE(conn)) {
4160 * We should really return a permission denied error if either
4161 * O_CREAT or O_TRUNC are set, but for compatibility with
4162 * older versions of Samba we just AND them out.
4164 flags &= ~(O_CREAT | O_TRUNC);
4168 * With kernel oplocks the open breaking an oplock
4169 * blocks until the oplock holder has given up the
4170 * oplock or closed the file. We prevent this by always
4171 * trying to open the file with O_NONBLOCK (see "man
4172 * fcntl" on Linux).
4174 * If a process that doesn't use the smbd open files
4175 * database or communication methods holds a kernel
4176 * oplock we must periodically poll for available open
4177 * using O_NONBLOCK.
4179 flags |= O_NONBLOCK;
4182 * Ensure we can't write on a read-only share or file.
4185 if (((flags & O_ACCMODE) != O_RDONLY) && file_existed &&
4186 (!CAN_WRITE(conn) ||
4187 (existing_dos_attributes & FILE_ATTRIBUTE_READONLY))) {
4188 DEBUG(5,("open_file_ntcreate: write access requested for "
4189 "file %s on read only %s\n",
4190 smb_fname_str_dbg(smb_fname),
4191 !CAN_WRITE(conn) ? "share" : "file" ));
4192 return NT_STATUS_ACCESS_DENIED;
4195 if (VALID_STAT(smb_fname->st)) {
4197 * Only try and create a file id before open
4198 * for an existing file. For a file being created
4199 * this won't do anything useful until the file
4200 * exists and has a valid stat struct.
4202 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
4204 fh_set_private_options(fsp->fh, private_flags);
4205 fsp->access_mask = open_access_mask; /* We change this to the
4206 * requested access_mask after
4207 * the open is done. */
4208 if (posix_open) {
4209 fsp->posix_flags |= FSP_POSIX_FLAGS_ALL;
4212 if ((create_options & FILE_DELETE_ON_CLOSE) && (flags & O_CREAT) &&
4213 !file_existed) {
4214 /* Delete on close semantics for new files. */
4215 status = can_set_delete_on_close(fsp,
4216 new_dos_attributes);
4217 if (!NT_STATUS_IS_OK(status)) {
4218 fd_close(fsp);
4219 return status;
4224 * Ensure we pay attention to default ACLs on directories if required.
4227 if ((flags & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
4228 (def_acl = directory_has_default_acl_fsp(parent_dir_fname->fsp))) {
4229 unx_mode = (0777 & lp_create_mask(SNUM(conn)));
4232 DEBUG(4,
4233 ("calling open_file with flags=0x%X mode=0%o, "
4234 "access_mask = 0x%x, open_access_mask = 0x%x\n",
4235 (unsigned int)flags,
4236 (unsigned int)unx_mode,
4237 (unsigned int)access_mask,
4238 (unsigned int)open_access_mask));
4241 struct vfs_open_how how = {
4242 .flags = flags,
4243 .mode = unx_mode,
4246 if (create_options & FILE_OPEN_FOR_BACKUP_INTENT) {
4247 how.resolve |= VFS_OPEN_HOW_WITH_BACKUP_INTENT;
4250 fsp_open = open_file(req,
4251 parent_dir_fname->fsp,
4252 smb_fname_atname,
4253 fsp,
4254 &how,
4255 access_mask,
4256 open_access_mask,
4257 private_flags,
4258 &new_file_created);
4260 if (NT_STATUS_EQUAL(fsp_open, NT_STATUS_NETWORK_BUSY)) {
4261 if (file_existed && S_ISFIFO(fsp->fsp_name->st.st_ex_mode)) {
4262 DEBUG(10, ("FIFO busy\n"));
4263 return NT_STATUS_NETWORK_BUSY;
4265 if (req == NULL) {
4266 DEBUG(10, ("Internal open busy\n"));
4267 return NT_STATUS_NETWORK_BUSY;
4270 * This handles the kernel oplock case:
4272 * the file has an active kernel oplock and the open() returned
4273 * EWOULDBLOCK/EAGAIN which maps to NETWORK_BUSY.
4275 * "Samba locking.tdb oplocks" are handled below after acquiring
4276 * the sharemode lock with get_share_mode_lock().
4278 setup_poll = true;
4281 if (NT_STATUS_EQUAL(fsp_open, NT_STATUS_RETRY)) {
4283 * EINTR from the open(2) syscall. Just setup a retry
4284 * in a bit. We can't use the sys_write() tight retry
4285 * loop here, as we might have to actually deal with
4286 * lease-break signals to avoid a deadlock.
4288 setup_poll = true;
4291 if (setup_poll) {
4293 * Retry once a second. If there's a share_mode_lock
4294 * around, also wait for it in case it was smbd
4295 * holding that kernel oplock that can quickly tell us
4296 * the oplock got removed.
4299 setup_poll_open(req,
4300 &fsp->file_id,
4301 tevent_timeval_set(OPLOCK_BREAK_TIMEOUT * 2,
4303 tevent_timeval_set(1, 0));
4305 return NT_STATUS_SHARING_VIOLATION;
4308 if (!NT_STATUS_IS_OK(fsp_open)) {
4309 bool wait_for_aio = NT_STATUS_EQUAL(
4310 fsp_open, NT_STATUS_MORE_PROCESSING_REQUIRED);
4311 if (wait_for_aio) {
4312 schedule_async_open(req);
4314 return fsp_open;
4317 if (new_file_created) {
4319 * As we atomically create using O_CREAT|O_EXCL,
4320 * then if new_file_created is true, then
4321 * file_existed *MUST* have been false (even
4322 * if the file was previously detected as being
4323 * there).
4325 file_existed = false;
4328 if (file_existed && !check_same_dev_ino(&saved_stat, &smb_fname->st)) {
4330 * The file did exist, but some other (local or NFS)
4331 * process either renamed/unlinked and re-created the
4332 * file with different dev/ino after we walked the path,
4333 * but before we did the open. We could retry the
4334 * open but it's a rare enough case it's easier to
4335 * just fail the open to prevent creating any problems
4336 * in the open file db having the wrong dev/ino key.
4338 fd_close(fsp);
4339 DBG_WARNING("file %s - dev/ino mismatch. "
4340 "Old (dev=%ju, ino=%ju). "
4341 "New (dev=%ju, ino=%ju). Failing open "
4342 "with NT_STATUS_ACCESS_DENIED.\n",
4343 smb_fname_str_dbg(smb_fname),
4344 (uintmax_t)saved_stat.st_ex_dev,
4345 (uintmax_t)saved_stat.st_ex_ino,
4346 (uintmax_t)smb_fname->st.st_ex_dev,
4347 (uintmax_t)smb_fname->st.st_ex_ino);
4348 return NT_STATUS_ACCESS_DENIED;
4351 old_write_time = smb_fname->st.st_ex_mtime;
4354 * Deal with the race condition where two smbd's detect the
4355 * file doesn't exist and do the create at the same time. One
4356 * of them will win and set a share mode, the other (ie. this
4357 * one) should check if the requested share mode for this
4358 * create is allowed.
4362 * Now the file exists and fsp is successfully opened,
4363 * fsp->dev and fsp->inode are valid and should replace the
4364 * dev=0,inode=0 from a non existent file. Spotted by
4365 * Nadav Danieli <nadavd@exanet.com>. JRA.
4368 if (new_file_created) {
4369 info = FILE_WAS_CREATED;
4370 } else {
4371 if (flags & O_TRUNC) {
4372 info = FILE_WAS_OVERWRITTEN;
4373 } else {
4374 info = FILE_WAS_OPENED;
4379 * If we created a new file, overwrite an existing one
4380 * or going to delete it later, we should keep
4381 * the share_mode_lock (g_lock) until we call
4382 * share_mode_entry_prepare_unlock()
4384 if (info != FILE_WAS_OPENED) {
4385 keep_locked = true;
4386 } else if (create_options & FILE_DELETE_ON_CLOSE) {
4387 keep_locked = true;
4390 lck_state = (struct open_ntcreate_lock_state) {
4391 .fsp = fsp,
4392 .object_type = "file",
4393 .req = req,
4394 .create_disposition = create_disposition,
4395 .access_mask = access_mask,
4396 .share_access = share_access,
4397 .oplock_request = oplock_request,
4398 .lease = lease,
4399 .first_open_attempt = first_open_attempt,
4400 .keep_locked = keep_locked,
4403 status = share_mode_entry_prepare_lock_add(&lck_state.prepare_state,
4404 fsp->file_id,
4405 conn->connectpath,
4406 smb_fname,
4407 &old_write_time,
4408 open_ntcreate_lock_add_entry,
4409 &lck_state);
4410 if (!NT_STATUS_IS_OK(status)) {
4411 DBG_ERR("share_mode_entry_prepare_lock_add() failed for %s - %s\n",
4412 smb_fname_str_dbg(smb_fname), nt_errstr(status));
4413 fd_close(fsp);
4414 return status;
4417 status = lck_state.status;
4418 if (!NT_STATUS_IS_OK(status)) {
4419 fd_close(fsp);
4420 return status;
4424 * From here we need to use 'goto unlock;' instead of return !!!
4427 if (fsp->oplock_type != NO_OPLOCK && fsp->oplock_type != LEASE_OPLOCK) {
4429 * Now ask for kernel oplocks
4430 * and cleanup on failure.
4432 status = set_file_oplock(fsp);
4433 if (!NT_STATUS_IS_OK(status)) {
4435 * Could not get the kernel oplock
4437 lck_state.cleanup_fn =
4438 open_ntcreate_lock_cleanup_oplock;
4439 fsp->oplock_type = NO_OPLOCK;
4443 /* Should we atomically (to the client at least) truncate ? */
4444 if ((!new_file_created) && (flags & O_TRUNC) &&
4445 (S_ISREG(fsp->fsp_name->st.st_ex_mode))) {
4446 int ret;
4448 ret = SMB_VFS_FTRUNCATE(fsp, 0);
4449 if (ret != 0) {
4450 status = map_nt_error_from_unix(errno);
4451 lck_state.cleanup_fn =
4452 open_ntcreate_lock_cleanup_entry;
4453 goto unlock;
4455 notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
4456 FILE_NOTIFY_CHANGE_SIZE
4457 | FILE_NOTIFY_CHANGE_ATTRIBUTES,
4458 fsp->fsp_name->base_name);
4462 * We have the share entry *locked*.....
4465 /* Delete streams if create_disposition requires it */
4466 if (!new_file_created &&
4467 clear_ads(create_disposition) &&
4468 !fsp_is_alternate_stream(fsp)) {
4469 status = delete_all_streams(conn, smb_fname);
4470 if (!NT_STATUS_IS_OK(status)) {
4471 lck_state.cleanup_fn =
4472 open_ntcreate_lock_cleanup_entry;
4473 goto unlock;
4477 if (!fsp->fsp_flags.is_pathref &&
4478 fsp_get_io_fd(fsp) != -1 &&
4479 lp_kernel_share_modes(SNUM(conn)))
4481 int ret;
4483 * Beware: streams implementing VFS modules may
4484 * implement streams in a way that fsp will have the
4485 * basefile open in the fsp fd, so lacking a distinct
4486 * fd for the stream the file-system sharemode will
4487 * apply on the basefile which is wrong. The actual
4488 * check is deferred to the VFS module implementing
4489 * the file-system sharemode call.
4491 ret = SMB_VFS_FILESYSTEM_SHAREMODE(fsp,
4492 share_access,
4493 access_mask);
4494 if (ret == -1){
4495 status = NT_STATUS_SHARING_VIOLATION;
4496 lck_state.cleanup_fn =
4497 open_ntcreate_lock_cleanup_entry;
4498 goto unlock;
4501 fsp->fsp_flags.kernel_share_modes_taken = true;
4505 * At this point onwards, we can guarantee that the share entry
4506 * is locked, whether we created the file or not, and that the
4507 * deny mode is compatible with all current opens.
4511 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
4512 * but we don't have to store this - just ignore it on access check.
4514 if (conn_using_smb2(conn->sconn)) {
4516 * SMB2 doesn't return it (according to Microsoft tests).
4517 * Test Case: TestSuite_ScenarioNo009GrantedAccessTestS0
4518 * File created with access = 0x7 (Read, Write, Delete)
4519 * Query Info on file returns 0x87 (Read, Write, Delete, Read Attributes)
4521 fsp->access_mask = access_mask;
4522 } else {
4523 /* But SMB1 does. */
4524 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
4527 if (pinfo) {
4528 *pinfo = info;
4531 /* Handle strange delete on close create semantics. */
4532 if (create_options & FILE_DELETE_ON_CLOSE) {
4533 if (!new_file_created) {
4534 status = can_set_delete_on_close(fsp,
4535 existing_dos_attributes);
4537 if (!NT_STATUS_IS_OK(status)) {
4538 /* Remember to delete the mode we just added. */
4539 lck_state.cleanup_fn =
4540 open_ntcreate_lock_cleanup_entry;
4541 goto unlock;
4544 /* Note that here we set the *initial* delete on close flag,
4545 not the regular one. The magic gets handled in close. */
4546 fsp->fsp_flags.initial_delete_on_close = true;
4549 possibly_set_archive(conn,
4550 fsp,
4551 smb_fname,
4552 parent_dir_fname,
4553 info,
4554 new_dos_attributes,
4555 &smb_fname->st.st_ex_mode);
4557 /* Determine sparse flag. */
4558 if (posix_open) {
4559 /* POSIX opens are sparse by default. */
4560 fsp->fsp_flags.is_sparse = true;
4561 } else {
4562 fsp->fsp_flags.is_sparse =
4563 (existing_dos_attributes & FILE_ATTRIBUTE_SPARSE);
4567 * Take care of inherited ACLs on created files - if default ACL not
4568 * selected.
4571 if (!posix_open && new_file_created && !def_acl) {
4572 if (unx_mode != smb_fname->st.st_ex_mode) {
4573 int ret = SMB_VFS_FCHMOD(fsp, unx_mode);
4574 if (ret == -1) {
4575 DBG_INFO("failed to reset "
4576 "attributes of file %s to 0%o\n",
4577 smb_fname_str_dbg(smb_fname),
4578 (unsigned int)unx_mode);
4582 } else if (new_unx_mode) {
4584 * We only get here in the case of:
4586 * a). Not a POSIX open.
4587 * b). File already existed.
4588 * c). File was overwritten.
4589 * d). Requested DOS attributes didn't match
4590 * the DOS attributes on the existing file.
4592 * In that case new_unx_mode has been set
4593 * equal to the calculated mode (including
4594 * possible inheritance of the mode from the
4595 * containing directory).
4597 * Note this mode was calculated with the
4598 * DOS attribute FILE_ATTRIBUTE_ARCHIVE added,
4599 * so the mode change here is suitable for
4600 * an overwritten file.
4603 if (new_unx_mode != smb_fname->st.st_ex_mode) {
4604 int ret = SMB_VFS_FCHMOD(fsp, new_unx_mode);
4605 if (ret == -1) {
4606 DBG_INFO("failed to reset "
4607 "attributes of file %s to 0%o\n",
4608 smb_fname_str_dbg(smb_fname),
4609 (unsigned int)new_unx_mode);
4615 * Deal with other opens having a modified write time.
4617 if (fsp_getinfo_ask_sharemode(fsp) &&
4618 !is_omit_timespec(&lck_state.write_time))
4620 update_stat_ex_mtime(&fsp->fsp_name->st, lck_state.write_time);
4623 status = NT_STATUS_OK;
4625 unlock:
4626 ulstatus = share_mode_entry_prepare_unlock(&lck_state.prepare_state,
4627 lck_state.cleanup_fn,
4628 &lck_state);
4629 if (!NT_STATUS_IS_OK(ulstatus)) {
4630 DBG_ERR("share_mode_entry_prepare_unlock() failed for %s - %s\n",
4631 smb_fname_str_dbg(smb_fname), nt_errstr(ulstatus));
4632 smb_panic("share_mode_entry_prepare_unlock() failed!");
4635 if (!NT_STATUS_IS_OK(status)) {
4636 fd_close(fsp);
4637 return status;
4640 return NT_STATUS_OK;
4643 static NTSTATUS apply_new_nt_acl(struct files_struct *dirfsp,
4644 struct files_struct *fsp,
4645 struct security_descriptor *sd)
4647 NTSTATUS status;
4649 if (sd != NULL) {
4651 * According to the MS documentation, the only time the security
4652 * descriptor is applied to the opened file is iff we *created* the
4653 * file; an existing file stays the same.
4655 * Also, it seems (from observation) that you can open the file with
4656 * any access mask but you can still write the sd. We need to override
4657 * the granted access before we call set_sd
4658 * Patch for bug #2242 from Tom Lackemann <cessnatomny@yahoo.com>.
4661 uint32_t sec_info_sent;
4662 uint32_t saved_access_mask = fsp->access_mask;
4664 sec_info_sent = get_sec_info(sd);
4666 fsp->access_mask = FILE_GENERIC_ALL;
4668 if (sec_info_sent & (SECINFO_OWNER|
4669 SECINFO_GROUP|
4670 SECINFO_DACL|
4671 SECINFO_SACL)) {
4672 status = set_sd(fsp, sd, sec_info_sent);
4673 } else {
4674 status = NT_STATUS_OK;
4677 fsp->access_mask = saved_access_mask;
4679 if (!NT_STATUS_IS_OK(status)) {
4680 DBG_WARNING("set_sd() failed for '%s': %s\n",
4681 fsp_str_dbg(fsp), nt_errstr(status));
4682 return status;
4685 return NT_STATUS_OK;
4688 if (!lp_inherit_acls(SNUM(fsp->conn))) {
4689 return NT_STATUS_OK;
4692 /* Inherit from parent. Errors here are not fatal. */
4693 status = inherit_new_acl(dirfsp, fsp);
4694 if (!NT_STATUS_IS_OK(status)) {
4695 DBG_WARNING("inherit_new_acl failed for %s with %s\n",
4696 fsp_str_dbg(fsp), nt_errstr(status));
4699 return NT_STATUS_OK;
4702 bool smbd_is_tmpname(const char *n, int *_unlink_flags)
4704 const char *p = n;
4705 int unlink_flags = INT_MAX;
4706 struct server_id id;
4707 bool exists;
4709 if (_unlink_flags != NULL) {
4710 *_unlink_flags = INT_MAX;
4713 if (!IS_SMBD_TMPNAME_PREFIX(n)) {
4714 return false;
4716 p += sizeof(SMBD_TMPNAME_PREFIX) - 1;
4717 switch (p[0]) {
4718 case 'D':
4719 unlink_flags = AT_REMOVEDIR;
4720 break;
4721 default:
4722 return false;
4724 p += 1;
4725 if (p[0] != ':') {
4726 return false;
4728 p += 1;
4730 id = server_id_from_string_ex(get_my_vnn(), '%', p);
4731 if (id.pid == UINT64_MAX) {
4732 return false;
4734 if (id.unique_id == 0) {
4735 return false;
4737 if (id.unique_id == SERVERID_UNIQUE_ID_NOT_TO_VERIFY) {
4738 return false;
4741 if (_unlink_flags == NULL) {
4742 return true;
4745 exists = serverid_exists(&id);
4746 if (!exists) {
4748 * let the caller know it's stale
4749 * and should be removed
4751 *_unlink_flags = unlink_flags;
4754 return true;
4757 static NTSTATUS mkdir_internal(connection_struct *conn,
4758 struct smb_filename *parent_dir_fname, /* parent. */
4759 struct smb_filename *smb_fname_atname, /* atname relative to parent. */
4760 struct smb_filename *smb_dname, /* full pathname from root of share. */
4761 struct security_descriptor *sd,
4762 uint32_t file_attributes,
4763 struct files_struct *fsp)
4765 TALLOC_CTX *frame = talloc_stackframe();
4766 const struct loadparm_substitution *lp_sub =
4767 loadparm_s3_global_substitution();
4768 mode_t mode;
4769 NTSTATUS status;
4770 bool posix_open = false;
4771 bool need_re_stat = false;
4772 uint32_t access_mask = SEC_DIR_ADD_SUBDIR;
4773 struct smb_filename *first_atname = NULL;
4774 struct smb_filename *tmp_atname = NULL;
4775 char *orig_dname = NULL;
4776 char *tmp_dname = NULL;
4777 int vfs_use_tmp = lp_vfs_mkdir_use_tmp_name(SNUM(conn));
4778 bool need_tmpname = false;
4779 struct server_id id = messaging_server_id(conn->sconn->msg_ctx);
4780 struct server_id_buf idbuf;
4781 char *idstr = server_id_str_buf_unique_ex(id, '%', &idbuf);
4782 struct vfs_open_how how = { .flags = O_RDONLY|O_DIRECTORY, };
4783 struct vfs_rename_how rhow = { .flags = VFS_RENAME_HOW_NO_REPLACE, };
4784 int ret;
4786 if (!CAN_WRITE(conn) || (access_mask & ~(conn->share_access))) {
4787 DBG_INFO("failing share access %s\n",
4788 lp_servicename(talloc_tos(), lp_sub, SNUM(conn)));
4789 TALLOC_FREE(frame);
4790 return NT_STATUS_ACCESS_DENIED;
4793 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
4794 posix_open = true;
4795 mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
4796 } else {
4797 mode = unix_mode(conn,
4798 FILE_ATTRIBUTE_DIRECTORY,
4799 smb_dname,
4800 parent_dir_fname->fsp);
4803 status = check_parent_access_fsp(parent_dir_fname->fsp, access_mask);
4804 if(!NT_STATUS_IS_OK(status)) {
4805 DBG_INFO("check_parent_access_fsp "
4806 "on directory %s for path %s returned %s\n",
4807 smb_fname_str_dbg(parent_dir_fname),
4808 smb_dname->base_name,
4809 nt_errstr(status));
4810 TALLOC_FREE(frame);
4811 return status;
4814 if (lp_inherit_acls(SNUM(conn))) {
4815 if (directory_has_default_acl_fsp(parent_dir_fname->fsp)) {
4816 mode = (0777 & lp_directory_mask(SNUM(conn)));
4818 need_tmpname = true;
4819 } else if (lp_store_dos_attributes(SNUM(conn))) {
4820 need_tmpname = true;
4821 } else if (lp_inherit_permissions(SNUM(conn))) {
4822 need_tmpname = true;
4823 } else if (lp_inherit_owner(SNUM(conn)) != INHERIT_OWNER_NO) {
4824 need_tmpname = true;
4825 } else if (lp_nt_acl_support(SNUM(conn)) && sd != NULL) {
4826 need_tmpname = true;
4829 if (vfs_use_tmp != Auto) {
4830 need_tmpname = vfs_use_tmp;
4833 if (!need_tmpname) {
4834 first_atname = smb_fname_atname;
4835 goto mkdir_first;
4839 * In order to avoid races where other clients could
4840 * see the directory before it is setup completely
4841 * we use a temporary name and rename it
4842 * when everything is ready.
4845 orig_dname = smb_dname->base_name;
4847 tmp_atname = cp_smb_filename(frame,
4848 smb_fname_atname);
4849 if (tmp_atname == NULL) {
4850 TALLOC_FREE(frame);
4851 return NT_STATUS_NO_MEMORY;
4853 TALLOC_FREE(tmp_atname->base_name);
4854 tmp_atname->base_name = talloc_asprintf(tmp_atname,
4855 "%s%s:%s",
4856 SMBD_TMPDIR_PREFIX,
4857 idstr,
4858 smb_fname_atname->base_name);
4859 if (tmp_atname == NULL) {
4860 TALLOC_FREE(frame);
4861 return NT_STATUS_NO_MEMORY;
4863 SMB_ASSERT(smbd_is_tmpname(tmp_atname->base_name, NULL));
4864 if (!ISDOT(parent_dir_fname->base_name)) {
4865 tmp_dname = talloc_asprintf(frame,
4866 "%s/%s",
4867 parent_dir_fname->base_name,
4868 tmp_atname->base_name);
4869 if (tmp_dname == NULL) {
4870 TALLOC_FREE(frame);
4871 return NT_STATUS_NO_MEMORY;
4873 } else {
4874 tmp_dname = talloc_strdup(frame, tmp_atname->base_name);
4875 if (tmp_dname == NULL) {
4876 TALLOC_FREE(frame);
4877 return NT_STATUS_NO_MEMORY;
4881 smb_dname->base_name = tmp_dname;
4883 DBG_DEBUG("temporary replace '%s' by '%s'\n",
4884 orig_dname, tmp_dname);
4886 first_atname = tmp_atname;
4888 mkdir_first:
4889 ret = SMB_VFS_MKDIRAT(conn,
4890 parent_dir_fname->fsp,
4891 first_atname,
4892 mode);
4893 if (ret != 0) {
4894 status = map_nt_error_from_unix(errno);
4895 DBG_NOTICE("MKDIRAT failed for '%s': %s\n",
4896 smb_fname_str_dbg(smb_dname), nt_errstr(status));
4897 goto restore_orig;
4901 * Make this a pathref fsp for now. open_directory() will reopen as a
4902 * full fsp.
4904 fsp->fsp_flags.is_pathref = true;
4906 status = fd_openat(parent_dir_fname->fsp, first_atname, fsp, &how);
4907 if (!NT_STATUS_IS_OK(status)) {
4908 DBG_ERR("fd_openat() failed for '%s': %s\n",
4909 smb_fname_str_dbg(smb_dname), nt_errstr(status));
4910 goto restore_orig;
4913 /* Ensure we're checking for a symlink here.... */
4914 /* We don't want to get caught by a symlink racer. */
4916 status = vfs_stat_fsp(fsp);
4917 if (!NT_STATUS_IS_OK(status)) {
4918 DBG_ERR("Could not stat directory '%s' just created: %s\n",
4919 smb_fname_str_dbg(smb_dname), nt_errstr(status));
4920 goto restore_orig;
4923 if (!S_ISDIR(smb_dname->st.st_ex_mode)) {
4924 DBG_ERR("Directory '%s' just created is not a directory !\n",
4925 smb_fname_str_dbg(smb_dname));
4926 status = NT_STATUS_NOT_A_DIRECTORY;
4927 goto restore_orig;
4930 if (lp_store_dos_attributes(SNUM(conn))) {
4931 file_set_dosmode(conn,
4932 smb_dname,
4933 file_attributes | FILE_ATTRIBUTE_DIRECTORY,
4934 parent_dir_fname,
4935 true);
4938 if (lp_inherit_permissions(SNUM(conn))) {
4939 inherit_access_posix_acl(conn, parent_dir_fname->fsp,
4940 smb_dname, mode);
4941 need_re_stat = true;
4944 if (!posix_open) {
4946 * Check if high bits should have been set,
4947 * then (if bits are missing): add them.
4948 * Consider bits automagically set by UNIX, i.e. SGID bit from parent
4949 * dir.
4951 if ((mode & ~(S_IRWXU|S_IRWXG|S_IRWXO)) &&
4952 (mode & ~smb_dname->st.st_ex_mode)) {
4953 SMB_VFS_FCHMOD(fsp,
4954 (smb_dname->st.st_ex_mode |
4955 (mode & ~smb_dname->st.st_ex_mode)));
4956 need_re_stat = true;
4960 /* Change the owner if required. */
4961 if (lp_inherit_owner(SNUM(conn)) != INHERIT_OWNER_NO) {
4962 change_dir_owner_to_parent_fsp(parent_dir_fname->fsp,
4963 fsp);
4964 need_re_stat = true;
4967 if (need_re_stat) {
4968 status = vfs_stat_fsp(fsp);
4969 if (!NT_STATUS_IS_OK(status)) {
4970 DBG_ERR("Could not stat directory '%s' just created: %s\n",
4971 smb_fname_str_dbg(smb_dname), nt_errstr(status));
4972 goto restore_orig;
4976 if (lp_nt_acl_support(SNUM(conn))) {
4977 status = apply_new_nt_acl(parent_dir_fname->fsp,
4978 fsp,
4979 sd);
4980 if (!NT_STATUS_IS_OK(status)) {
4981 DBG_WARNING("apply_new_nt_acl() failed for %s with %s\n",
4982 fsp_str_dbg(fsp),
4983 nt_errstr(status));
4984 goto do_unlink;
4988 if (!need_tmpname) {
4989 goto done;
4993 * A rename needs a valid stat for the source,
4994 * see vfs_fruit.c ...
4996 tmp_atname->st = smb_dname->st;
4999 * We first try VFS_RENAME_HOW_NO_REPLACE,
5000 * if it's implemented in the kernel,
5001 * we'll always get EEXIST if the target
5002 * exist, as it's handled at the linux vfs
5003 * layer. But if it doesn't exist we
5004 * can still get EINVAL if the actual
5005 * filesystem doesn't support RENAME_NOREPLACE.
5007 * If the kernel doesn't support rename2()
5008 * we get EINVAL instead of ENOSYS (this
5009 * is mapped in the libreplace replacement
5010 * (as well as the glibc replacement).
5012 ret = SMB_VFS_RENAMEAT(conn,
5013 parent_dir_fname->fsp,
5014 tmp_atname,
5015 parent_dir_fname->fsp,
5016 smb_fname_atname,
5017 &rhow);
5018 if (ret == -1 && errno == EINVAL) {
5020 * This is the strategie we use without having
5021 * renameat2(RENAME_NOREPLACE):
5023 * renameat() is able to replace a directory if the source is
5024 * also a directory.
5026 * So in order to avoid races as much as possible we do a
5027 * mkdirat() with mode 0 in order to catch EEXIST almost
5028 * atomically, when this code runs by two processes at the same
5029 * time.
5031 * Then a renameat() makes the temporary directory available for
5032 * clients.
5034 * This a much smaller window where the other clients may see
5035 * the incomplete directory, which has a mode of 0.
5038 rhow.flags &= ~VFS_RENAME_HOW_NO_REPLACE;
5040 DBG_DEBUG("MKDIRAT/RENAMEAT '%s' -> '%s'\n",
5041 tmp_dname, orig_dname);
5043 ret = SMB_VFS_MKDIRAT(conn,
5044 parent_dir_fname->fsp,
5045 smb_fname_atname,
5047 if (ret != 0) {
5048 status = map_nt_error_from_unix(errno);
5049 DBG_NOTICE("MKDIRAT failed for '%s': %s\n",
5050 orig_dname, nt_errstr(status));
5051 goto do_unlink;
5054 ret = SMB_VFS_RENAMEAT(conn,
5055 parent_dir_fname->fsp,
5056 tmp_atname,
5057 parent_dir_fname->fsp,
5058 smb_fname_atname,
5059 &rhow);
5062 if (ret != 0) {
5063 status = map_nt_error_from_unix(errno);
5064 DBG_NOTICE("RENAMEAT failed for '%s' -> '%s': %s\n",
5065 tmp_dname, orig_dname, nt_errstr(status));
5066 goto do_unlink;
5068 smb_fname_atname->st = tmp_atname->st;
5069 smb_dname->base_name = orig_dname;
5071 done:
5072 DBG_DEBUG("Created directory '%s'\n",
5073 smb_fname_str_dbg(smb_dname));
5075 notify_fname(conn, NOTIFY_ACTION_ADDED, FILE_NOTIFY_CHANGE_DIR_NAME,
5076 smb_dname->base_name);
5078 TALLOC_FREE(frame);
5079 return NT_STATUS_OK;
5081 do_unlink:
5082 DBG_NOTICE("%s: rollback and unlink '%s'\n",
5083 nt_errstr(status),
5084 tmp_dname);
5085 ret = SMB_VFS_UNLINKAT(conn,
5086 parent_dir_fname->fsp,
5087 tmp_atname,
5088 AT_REMOVEDIR);
5089 if (ret == 0) {
5090 DBG_NOTICE("SMB_VFS_UNLINKAT(%s): OK\n",
5091 tmp_dname);
5092 } else {
5093 NTSTATUS status2 = map_nt_error_from_unix(errno);
5094 DBG_WARNING("SMB_VFS_UNLINKAT(%s) ignoring %s\n",
5095 tmp_dname, nt_errstr(status2));
5098 restore_orig:
5099 if (!need_tmpname) {
5100 TALLOC_FREE(frame);
5101 return status;
5103 DBG_NOTICE("%s: restoring '%s' -> '%s'\n",
5104 nt_errstr(status),
5105 tmp_dname,
5106 orig_dname);
5107 SET_STAT_INVALID(smb_fname_atname->st);
5108 smb_dname->base_name = orig_dname;
5109 SET_STAT_INVALID(smb_dname->st);
5110 TALLOC_FREE(frame);
5111 return status;
5114 /****************************************************************************
5115 Open a directory from an NT SMB call.
5116 ****************************************************************************/
5118 static NTSTATUS open_directory(connection_struct *conn,
5119 struct smb_request *req,
5120 uint32_t access_mask,
5121 uint32_t share_access,
5122 uint32_t create_disposition,
5123 uint32_t create_options,
5124 uint32_t file_attributes,
5125 struct smb_filename *parent_dir_fname,
5126 struct smb_filename *smb_fname_atname,
5127 struct security_descriptor *sd,
5128 int *pinfo,
5129 struct files_struct *fsp)
5131 struct smb_filename *smb_dname = fsp->fsp_name;
5132 bool dir_existed = VALID_STAT(smb_dname->st);
5133 struct open_ntcreate_lock_state lck_state = {};
5134 bool keep_locked = false;
5135 NTSTATUS status;
5136 struct timespec mtimespec;
5137 int info = 0;
5138 uint32_t need_fd_access;
5139 NTSTATUS ulstatus;
5141 if (is_ntfs_stream_smb_fname(smb_dname)) {
5142 DEBUG(2, ("open_directory: %s is a stream name!\n",
5143 smb_fname_str_dbg(smb_dname)));
5144 return NT_STATUS_NOT_A_DIRECTORY;
5147 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS)) {
5148 /* Ensure we have a directory attribute. */
5149 file_attributes |= FILE_ATTRIBUTE_DIRECTORY;
5152 DBG_INFO("opening directory %s, access_mask = 0x%"PRIx32", "
5153 "share_access = 0x%"PRIx32" create_options = 0x%"PRIx32", "
5154 "create_disposition = 0x%"PRIx32", "
5155 "file_attributes = 0x%"PRIx32"\n",
5156 smb_fname_str_dbg(smb_dname),
5157 access_mask,
5158 share_access,
5159 create_options,
5160 create_disposition,
5161 file_attributes);
5163 status = smbd_calculate_access_mask_fsp(parent_dir_fname->fsp,
5164 smb_dname->fsp,
5165 false,
5166 access_mask,
5167 &access_mask);
5168 if (!NT_STATUS_IS_OK(status)) {
5169 DBG_DEBUG("smbd_calculate_access_mask_fsp "
5170 "on file %s returned %s\n",
5171 smb_fname_str_dbg(smb_dname),
5172 nt_errstr(status));
5173 return status;
5176 if ((access_mask & SEC_FLAG_SYSTEM_SECURITY) &&
5177 !security_token_has_privilege(get_current_nttok(conn),
5178 SEC_PRIV_SECURITY)) {
5179 DEBUG(10, ("open_directory: open on %s "
5180 "failed - SEC_FLAG_SYSTEM_SECURITY denied.\n",
5181 smb_fname_str_dbg(smb_dname)));
5182 return NT_STATUS_PRIVILEGE_NOT_HELD;
5185 switch( create_disposition ) {
5186 case FILE_OPEN:
5188 if (!dir_existed) {
5189 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
5192 info = FILE_WAS_OPENED;
5193 break;
5195 case FILE_CREATE:
5197 /* If directory exists error. If directory doesn't
5198 * exist create. */
5200 if (dir_existed) {
5201 status = NT_STATUS_OBJECT_NAME_COLLISION;
5202 DEBUG(2, ("open_directory: unable to create "
5203 "%s. Error was %s\n",
5204 smb_fname_str_dbg(smb_dname),
5205 nt_errstr(status)));
5206 return status;
5209 if (smb_fname_atname->twrp != 0) {
5210 return NT_STATUS_MEDIA_WRITE_PROTECTED;
5213 status = mkdir_internal(conn,
5214 parent_dir_fname,
5215 smb_fname_atname,
5216 smb_dname,
5218 file_attributes,
5219 fsp);
5221 if (!NT_STATUS_IS_OK(status)) {
5222 DEBUG(2, ("open_directory: unable to create "
5223 "%s. Error was %s\n",
5224 smb_fname_str_dbg(smb_dname),
5225 nt_errstr(status)));
5226 return status;
5229 info = FILE_WAS_CREATED;
5230 break;
5232 case FILE_OPEN_IF:
5234 * If directory exists open. If directory doesn't
5235 * exist create.
5238 if (dir_existed) {
5239 status = NT_STATUS_OK;
5240 info = FILE_WAS_OPENED;
5241 } else {
5242 if (smb_fname_atname->twrp != 0) {
5243 return NT_STATUS_MEDIA_WRITE_PROTECTED;
5245 status = mkdir_internal(conn,
5246 parent_dir_fname,
5247 smb_fname_atname,
5248 smb_dname,
5250 file_attributes,
5251 fsp);
5253 if (NT_STATUS_IS_OK(status)) {
5254 info = FILE_WAS_CREATED;
5255 } else {
5256 int ret;
5257 /* Cope with create race. */
5258 if (!NT_STATUS_EQUAL(status,
5259 NT_STATUS_OBJECT_NAME_COLLISION)) {
5260 DEBUG(2, ("open_directory: unable to create "
5261 "%s. Error was %s\n",
5262 smb_fname_str_dbg(smb_dname),
5263 nt_errstr(status)));
5264 return status;
5268 * If mkdir_internal() returned
5269 * NT_STATUS_OBJECT_NAME_COLLISION
5270 * we still must lstat the path.
5272 ret = SMB_VFS_FSTATAT(
5273 conn,
5274 parent_dir_fname->fsp,
5275 smb_fname_atname,
5276 &smb_dname->st,
5277 AT_SYMLINK_NOFOLLOW);
5278 if (ret == -1) {
5279 DEBUG(2, ("Could not stat "
5280 "directory '%s' just "
5281 "opened: %s\n",
5282 smb_fname_str_dbg(
5283 smb_dname),
5284 strerror(errno)));
5285 return map_nt_error_from_unix(
5286 errno);
5289 info = FILE_WAS_OPENED;
5293 break;
5295 case FILE_SUPERSEDE:
5296 case FILE_OVERWRITE:
5297 case FILE_OVERWRITE_IF:
5298 default:
5299 DEBUG(5,("open_directory: invalid create_disposition "
5300 "0x%x for directory %s\n",
5301 (unsigned int)create_disposition,
5302 smb_fname_str_dbg(smb_dname)));
5303 return NT_STATUS_INVALID_PARAMETER;
5306 if(!S_ISDIR(smb_dname->st.st_ex_mode)) {
5307 DEBUG(5,("open_directory: %s is not a directory !\n",
5308 smb_fname_str_dbg(smb_dname)));
5309 return NT_STATUS_NOT_A_DIRECTORY;
5313 * Setup the files_struct for it.
5316 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_dname->st);
5317 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
5318 fsp->file_pid = req ? req->smbpid : 0;
5319 fsp->fsp_flags.can_lock = false;
5320 fsp->fsp_flags.can_read = false;
5321 fsp->fsp_flags.can_write = false;
5323 fh_set_private_options(fsp->fh, 0);
5325 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
5327 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
5328 fsp->print_file = NULL;
5329 fsp->fsp_flags.modified = false;
5330 fsp->oplock_type = NO_OPLOCK;
5331 fsp->sent_oplock_break = NO_BREAK_SENT;
5332 fsp->fsp_flags.is_directory = true;
5333 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
5334 fsp->posix_flags |= FSP_POSIX_FLAGS_ALL;
5337 /* Don't store old timestamps for directory
5338 handles in the internal database. We don't
5339 update them in there if new objects
5340 are created in the directory. Currently
5341 we only update timestamps on file writes.
5342 See bug #9870.
5344 mtimespec = make_omit_timespec();
5347 * Obviously for FILE_LIST_DIRECTORY we need to reopen to get an fd
5348 * usable for reading a directory. SMB2_FLUSH may be called on
5349 * directories opened with FILE_ADD_FILE and FILE_ADD_SUBDIRECTORY so
5350 * for those we need to reopen as well.
5352 need_fd_access =
5353 FILE_LIST_DIRECTORY |
5354 FILE_ADD_FILE |
5355 FILE_ADD_SUBDIRECTORY;
5357 if (access_mask & need_fd_access) {
5358 struct vfs_open_how how = {
5359 .flags = O_RDONLY | O_DIRECTORY,
5361 bool file_created;
5363 status = reopen_from_fsp(parent_dir_fname->fsp,
5364 smb_fname_atname,
5365 fsp,
5366 &how,
5367 &file_created);
5368 if (!NT_STATUS_IS_OK(status)) {
5369 DBG_INFO("Could not open fd for [%s]: %s\n",
5370 smb_fname_str_dbg(smb_dname),
5371 nt_errstr(status));
5372 return status;
5376 status = vfs_stat_fsp(fsp);
5377 if (!NT_STATUS_IS_OK(status)) {
5378 fd_close(fsp);
5379 return status;
5382 if(!S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
5383 DEBUG(5,("open_directory: %s is not a directory !\n",
5384 smb_fname_str_dbg(smb_dname)));
5385 fd_close(fsp);
5386 return NT_STATUS_NOT_A_DIRECTORY;
5389 /* Ensure there was no race condition. We need to check
5390 * dev/inode but not permissions, as these can change
5391 * legitimately */
5392 if (!check_same_dev_ino(&smb_dname->st, &fsp->fsp_name->st)) {
5393 DEBUG(5,("open_directory: stat struct differs for "
5394 "directory %s.\n",
5395 smb_fname_str_dbg(smb_dname)));
5396 fd_close(fsp);
5397 return NT_STATUS_ACCESS_DENIED;
5400 if (info == FILE_WAS_OPENED) {
5401 status = smbd_check_access_rights_fsp(parent_dir_fname->fsp,
5402 fsp,
5403 false,
5404 access_mask);
5405 if (!NT_STATUS_IS_OK(status)) {
5406 DBG_DEBUG("smbd_check_access_rights_fsp on "
5407 "file %s failed with %s\n",
5408 fsp_str_dbg(fsp),
5409 nt_errstr(status));
5410 fd_close(fsp);
5411 return status;
5416 * If we created a new directory or going to delete it later,
5417 * we should keep * the share_mode_lock (g_lock) until we call
5418 * share_mode_entry_prepare_unlock()
5420 if (info != FILE_WAS_OPENED) {
5421 keep_locked = true;
5422 } else if (create_options & FILE_DELETE_ON_CLOSE) {
5423 keep_locked = true;
5426 lck_state = (struct open_ntcreate_lock_state) {
5427 .fsp = fsp,
5428 .object_type = "directory",
5429 .req = req,
5430 .create_disposition = create_disposition,
5431 .access_mask = access_mask,
5432 .share_access = share_access,
5433 .oplock_request = NO_OPLOCK,
5434 .lease = NULL,
5435 .first_open_attempt = true,
5436 .keep_locked = keep_locked,
5439 status = share_mode_entry_prepare_lock_add(&lck_state.prepare_state,
5440 fsp->file_id,
5441 conn->connectpath,
5442 smb_dname,
5443 &mtimespec,
5444 open_ntcreate_lock_add_entry,
5445 &lck_state);
5446 if (!NT_STATUS_IS_OK(status)) {
5447 DBG_ERR("share_mode_entry_prepare_lock_add() failed for %s - %s\n",
5448 smb_fname_str_dbg(smb_dname), nt_errstr(status));
5449 fd_close(fsp);
5450 return status;
5453 status = lck_state.status;
5454 if (!NT_STATUS_IS_OK(status)) {
5455 fd_close(fsp);
5456 return status;
5460 * From here we need to use 'goto unlock;' instead of return !!!
5463 /* For directories the delete on close bit at open time seems
5464 always to be honored on close... See test 19 in Samba4 BASE-DELETE. */
5465 if (create_options & FILE_DELETE_ON_CLOSE) {
5466 status = can_set_delete_on_close(fsp, 0);
5467 if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
5468 lck_state.cleanup_fn =
5469 open_ntcreate_lock_cleanup_entry;
5470 goto unlock;
5473 if (NT_STATUS_IS_OK(status)) {
5474 /* Note that here we set the *initial* delete on close flag,
5475 not the regular one. The magic gets handled in close. */
5476 fsp->fsp_flags.initial_delete_on_close = true;
5481 * Deal with other opens having a modified write time.
5483 if (!is_omit_timespec(&lck_state.write_time)) {
5484 update_stat_ex_mtime(&fsp->fsp_name->st, lck_state.write_time);
5487 if (pinfo) {
5488 *pinfo = info;
5491 status = NT_STATUS_OK;
5493 unlock:
5494 ulstatus = share_mode_entry_prepare_unlock(&lck_state.prepare_state,
5495 lck_state.cleanup_fn,
5496 &lck_state);
5497 if (!NT_STATUS_IS_OK(ulstatus)) {
5498 DBG_ERR("share_mode_entry_prepare_unlock() failed for %s - %s\n",
5499 smb_fname_str_dbg(smb_dname), nt_errstr(ulstatus));
5500 smb_panic("share_mode_entry_prepare_unlock() failed!");
5503 if (!NT_STATUS_IS_OK(status)) {
5504 fd_close(fsp);
5505 return status;
5508 return NT_STATUS_OK;
5511 NTSTATUS create_directory(connection_struct *conn,
5512 struct smb_request *req,
5513 struct files_struct *dirfsp,
5514 struct smb_filename *smb_dname)
5516 NTSTATUS status;
5517 files_struct *fsp;
5519 status = SMB_VFS_CREATE_FILE(
5520 conn, /* conn */
5521 req, /* req */
5522 dirfsp, /* dirfsp */
5523 smb_dname, /* fname */
5524 FILE_READ_ATTRIBUTES, /* access_mask */
5525 FILE_SHARE_NONE, /* share_access */
5526 FILE_CREATE, /* create_disposition*/
5527 FILE_DIRECTORY_FILE, /* create_options */
5528 FILE_ATTRIBUTE_DIRECTORY, /* file_attributes */
5529 0, /* oplock_request */
5530 NULL, /* lease */
5531 0, /* allocation_size */
5532 0, /* private_flags */
5533 NULL, /* sd */
5534 NULL, /* ea_list */
5535 &fsp, /* result */
5536 NULL, /* pinfo */
5537 NULL, NULL); /* create context */
5539 if (NT_STATUS_IS_OK(status)) {
5540 close_file_free(req, &fsp, NORMAL_CLOSE);
5543 return status;
5546 /****************************************************************************
5547 Receive notification that one of our open files has been renamed by another
5548 smbd process.
5549 ****************************************************************************/
5551 void msg_file_was_renamed(struct messaging_context *msg_ctx,
5552 void *private_data,
5553 uint32_t msg_type,
5554 struct server_id src,
5555 DATA_BLOB *data)
5557 struct file_rename_message *msg = NULL;
5558 enum ndr_err_code ndr_err;
5559 files_struct *fsp;
5560 struct smb_filename *smb_fname = NULL;
5561 struct smbd_server_connection *sconn =
5562 talloc_get_type_abort(private_data,
5563 struct smbd_server_connection);
5565 msg = talloc(talloc_tos(), struct file_rename_message);
5566 if (msg == NULL) {
5567 DBG_WARNING("talloc failed\n");
5568 return;
5571 ndr_err = ndr_pull_struct_blob_all(
5572 data,
5573 msg,
5574 msg,
5575 (ndr_pull_flags_fn_t)ndr_pull_file_rename_message);
5576 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
5577 DBG_DEBUG("ndr_pull_file_rename_message failed: %s\n",
5578 ndr_errstr(ndr_err));
5579 goto out;
5581 if (DEBUGLEVEL >= 10) {
5582 struct server_id_buf buf;
5583 DBG_DEBUG("Got rename message from %s\n",
5584 server_id_str_buf(src, &buf));
5585 NDR_PRINT_DEBUG(file_rename_message, msg);
5588 /* stream_name must always be NULL if there is no stream. */
5589 if ((msg->stream_name != NULL) && (msg->stream_name[0] == '\0')) {
5590 msg->stream_name = NULL;
5593 smb_fname = synthetic_smb_fname(msg,
5594 msg->base_name,
5595 msg->stream_name,
5596 NULL,
5599 if (smb_fname == NULL) {
5600 DBG_DEBUG("synthetic_smb_fname failed\n");
5601 goto out;
5604 fsp = file_find_dif(sconn, msg->id, msg->share_file_id);
5605 if (fsp == NULL) {
5606 DBG_DEBUG("fsp not found\n");
5607 goto out;
5610 if (strcmp(fsp->conn->connectpath, msg->servicepath) == 0) {
5611 SMB_STRUCT_STAT fsp_orig_sbuf;
5612 NTSTATUS status;
5613 DBG_DEBUG("renaming file %s from %s -> %s\n",
5614 fsp_fnum_dbg(fsp),
5615 fsp_str_dbg(fsp),
5616 smb_fname_str_dbg(smb_fname));
5619 * The incoming smb_fname here has an
5620 * invalid stat struct from synthetic_smb_fname()
5621 * above.
5622 * Preserve the existing stat from the
5623 * open fsp after fsp_set_smb_fname()
5624 * overwrites with the invalid stat.
5626 * (We could just copy this into
5627 * smb_fname->st, but keep this code
5628 * identical to the fix in rename_open_files()
5629 * for clarity.
5631 * We will do an fstat before returning
5632 * any of this metadata to the client anyway.
5634 fsp_orig_sbuf = fsp->fsp_name->st;
5635 status = fsp_set_smb_fname(fsp, smb_fname);
5636 if (!NT_STATUS_IS_OK(status)) {
5637 DBG_DEBUG("fsp_set_smb_fname failed: %s\n",
5638 nt_errstr(status));
5640 fsp->fsp_name->st = fsp_orig_sbuf;
5641 } else {
5642 /* TODO. JRA. */
5644 * Now we have the complete path we can work out if
5645 * this is actually within this share and adjust
5646 * newname accordingly.
5648 DBG_DEBUG("share mismatch (sharepath %s not sharepath %s) "
5649 "%s from %s -> %s\n",
5650 fsp->conn->connectpath,
5651 msg->servicepath,
5652 fsp_fnum_dbg(fsp),
5653 fsp_str_dbg(fsp),
5654 smb_fname_str_dbg(smb_fname));
5656 out:
5657 TALLOC_FREE(msg);
5661 * If a main file is opened for delete, all streams need to be checked for
5662 * !FILE_SHARE_DELETE. Do this by opening with DELETE_ACCESS.
5663 * If that works, delete them all by setting the delete on close and close.
5666 static NTSTATUS open_streams_for_delete(connection_struct *conn,
5667 const struct smb_filename *smb_fname)
5669 struct stream_struct *stream_info = NULL;
5670 files_struct **streams = NULL;
5671 int j;
5672 unsigned int i, num_streams = 0;
5673 TALLOC_CTX *frame = talloc_stackframe();
5674 const struct smb_filename *pathref = NULL;
5675 NTSTATUS status;
5677 if (smb_fname->fsp == NULL) {
5678 struct smb_filename *tmp = NULL;
5679 status = synthetic_pathref(frame,
5680 conn->cwd_fsp,
5681 smb_fname->base_name,
5682 NULL,
5683 NULL,
5684 smb_fname->twrp,
5685 smb_fname->flags,
5686 &tmp);
5687 if (!NT_STATUS_IS_OK(status)) {
5688 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
5689 || NT_STATUS_EQUAL(status,
5690 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
5691 DBG_DEBUG("no streams around\n");
5692 TALLOC_FREE(frame);
5693 return NT_STATUS_OK;
5695 DBG_DEBUG("synthetic_pathref failed: %s\n",
5696 nt_errstr(status));
5697 goto fail;
5699 pathref = tmp;
5700 } else {
5701 pathref = smb_fname;
5703 status = vfs_fstreaminfo(pathref->fsp, talloc_tos(),
5704 &num_streams, &stream_info);
5706 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
5707 || NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
5708 DEBUG(10, ("no streams around\n"));
5709 TALLOC_FREE(frame);
5710 return NT_STATUS_OK;
5713 if (!NT_STATUS_IS_OK(status)) {
5714 DEBUG(10, ("vfs_fstreaminfo failed: %s\n",
5715 nt_errstr(status)));
5716 goto fail;
5719 DEBUG(10, ("open_streams_for_delete found %d streams\n",
5720 num_streams));
5722 if (num_streams == 0) {
5723 TALLOC_FREE(frame);
5724 return NT_STATUS_OK;
5727 streams = talloc_array(talloc_tos(), files_struct *, num_streams);
5728 if (streams == NULL) {
5729 DEBUG(0, ("talloc failed\n"));
5730 status = NT_STATUS_NO_MEMORY;
5731 goto fail;
5734 for (i=0; i<num_streams; i++) {
5735 struct smb_filename *smb_fname_cp;
5737 if (strequal(stream_info[i].name, "::$DATA")) {
5738 streams[i] = NULL;
5739 continue;
5742 smb_fname_cp = synthetic_smb_fname(talloc_tos(),
5743 smb_fname->base_name,
5744 stream_info[i].name,
5745 NULL,
5746 smb_fname->twrp,
5747 (smb_fname->flags &
5748 ~SMB_FILENAME_POSIX_PATH));
5749 if (smb_fname_cp == NULL) {
5750 status = NT_STATUS_NO_MEMORY;
5751 goto fail;
5754 status = openat_pathref_fsp(conn->cwd_fsp, smb_fname_cp);
5755 if (!NT_STATUS_IS_OK(status)) {
5756 DBG_DEBUG("Unable to open stream [%s]: %s\n",
5757 smb_fname_str_dbg(smb_fname_cp),
5758 nt_errstr(status));
5759 TALLOC_FREE(smb_fname_cp);
5760 break;
5763 status = SMB_VFS_CREATE_FILE(
5764 conn, /* conn */
5765 NULL, /* req */
5766 NULL, /* dirfsp */
5767 smb_fname_cp, /* fname */
5768 DELETE_ACCESS, /* access_mask */
5769 (FILE_SHARE_READ | /* share_access */
5770 FILE_SHARE_WRITE | FILE_SHARE_DELETE),
5771 FILE_OPEN, /* create_disposition*/
5772 0, /* create_options */
5773 FILE_ATTRIBUTE_NORMAL, /* file_attributes */
5774 0, /* oplock_request */
5775 NULL, /* lease */
5776 0, /* allocation_size */
5777 0, /* private_flags */
5778 NULL, /* sd */
5779 NULL, /* ea_list */
5780 &streams[i], /* result */
5781 NULL, /* pinfo */
5782 NULL, NULL); /* create context */
5784 if (!NT_STATUS_IS_OK(status)) {
5785 DEBUG(10, ("Could not open stream %s: %s\n",
5786 smb_fname_str_dbg(smb_fname_cp),
5787 nt_errstr(status)));
5789 TALLOC_FREE(smb_fname_cp);
5790 break;
5792 TALLOC_FREE(smb_fname_cp);
5796 * don't touch the variable "status" beyond this point :-)
5799 for (j = i-1 ; j >= 0; j--) {
5800 if (streams[j] == NULL) {
5801 continue;
5804 DEBUG(10, ("Closing stream # %d, %s\n", j,
5805 fsp_str_dbg(streams[j])));
5806 close_file_free(NULL, &streams[j], NORMAL_CLOSE);
5809 fail:
5810 TALLOC_FREE(frame);
5811 return status;
5814 /*********************************************************************
5815 Create a default ACL by inheriting from the parent. If no inheritance
5816 from the parent available, don't set anything. This will leave the actual
5817 permissions the new file or directory already got from the filesystem
5818 as the NT ACL when read.
5819 *********************************************************************/
5821 static NTSTATUS inherit_new_acl(files_struct *dirfsp, files_struct *fsp)
5823 TALLOC_CTX *frame = talloc_stackframe();
5824 struct security_descriptor *parent_desc = NULL;
5825 NTSTATUS status = NT_STATUS_OK;
5826 struct security_descriptor *psd = NULL;
5827 const struct dom_sid *owner_sid = NULL;
5828 const struct dom_sid *group_sid = NULL;
5829 uint32_t security_info_sent = (SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL);
5830 struct security_token *token = fsp->conn->session_info->security_token;
5831 bool inherit_owner =
5832 (lp_inherit_owner(SNUM(fsp->conn)) == INHERIT_OWNER_WINDOWS_AND_UNIX);
5833 bool inheritable_components = false;
5834 bool try_builtin_administrators = false;
5835 const struct dom_sid *BA_U_sid = NULL;
5836 const struct dom_sid *BA_G_sid = NULL;
5837 bool try_system = false;
5838 const struct dom_sid *SY_U_sid = NULL;
5839 const struct dom_sid *SY_G_sid = NULL;
5840 size_t size = 0;
5841 bool ok;
5843 status = SMB_VFS_FGET_NT_ACL(dirfsp,
5844 (SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL),
5845 frame,
5846 &parent_desc);
5847 if (!NT_STATUS_IS_OK(status)) {
5848 TALLOC_FREE(frame);
5849 return status;
5852 inheritable_components = sd_has_inheritable_components(parent_desc,
5853 fsp->fsp_flags.is_directory);
5855 if (!inheritable_components && !inherit_owner) {
5856 TALLOC_FREE(frame);
5857 /* Nothing to inherit and not setting owner. */
5858 return NT_STATUS_OK;
5861 /* Create an inherited descriptor from the parent. */
5863 if (DEBUGLEVEL >= 10) {
5864 DEBUG(10,("inherit_new_acl: parent acl for %s is:\n",
5865 fsp_str_dbg(fsp) ));
5866 NDR_PRINT_DEBUG(security_descriptor, parent_desc);
5869 /* Inherit from parent descriptor if "inherit owner" set. */
5870 if (inherit_owner) {
5871 owner_sid = parent_desc->owner_sid;
5872 group_sid = parent_desc->group_sid;
5875 if (owner_sid == NULL) {
5876 if (security_token_has_builtin_administrators(token)) {
5877 try_builtin_administrators = true;
5878 } else if (security_token_is_system(token)) {
5879 try_builtin_administrators = true;
5880 try_system = true;
5884 if (group_sid == NULL &&
5885 token->num_sids == PRIMARY_GROUP_SID_INDEX)
5887 if (security_token_is_system(token)) {
5888 try_builtin_administrators = true;
5889 try_system = true;
5893 if (try_builtin_administrators) {
5894 struct unixid ids = { .id = 0 };
5896 ok = sids_to_unixids(&global_sid_Builtin_Administrators, 1, &ids);
5897 if (ok) {
5898 switch (ids.type) {
5899 case ID_TYPE_BOTH:
5900 BA_U_sid = &global_sid_Builtin_Administrators;
5901 BA_G_sid = &global_sid_Builtin_Administrators;
5902 break;
5903 case ID_TYPE_UID:
5904 BA_U_sid = &global_sid_Builtin_Administrators;
5905 break;
5906 case ID_TYPE_GID:
5907 BA_G_sid = &global_sid_Builtin_Administrators;
5908 break;
5909 default:
5910 break;
5915 if (try_system) {
5916 struct unixid ids = { .id = 0 };
5918 ok = sids_to_unixids(&global_sid_System, 1, &ids);
5919 if (ok) {
5920 switch (ids.type) {
5921 case ID_TYPE_BOTH:
5922 SY_U_sid = &global_sid_System;
5923 SY_G_sid = &global_sid_System;
5924 break;
5925 case ID_TYPE_UID:
5926 SY_U_sid = &global_sid_System;
5927 break;
5928 case ID_TYPE_GID:
5929 SY_G_sid = &global_sid_System;
5930 break;
5931 default:
5932 break;
5937 if (owner_sid == NULL) {
5938 owner_sid = BA_U_sid;
5941 if (owner_sid == NULL) {
5942 owner_sid = SY_U_sid;
5945 if (group_sid == NULL) {
5946 group_sid = SY_G_sid;
5949 if (try_system && group_sid == NULL) {
5950 group_sid = BA_G_sid;
5953 if (owner_sid == NULL) {
5954 owner_sid = &token->sids[PRIMARY_USER_SID_INDEX];
5956 if (group_sid == NULL) {
5957 if (token->num_sids == PRIMARY_GROUP_SID_INDEX) {
5958 group_sid = &token->sids[PRIMARY_USER_SID_INDEX];
5959 } else {
5960 group_sid = &token->sids[PRIMARY_GROUP_SID_INDEX];
5964 status = se_create_child_secdesc(frame,
5965 &psd,
5966 &size,
5967 parent_desc,
5968 owner_sid,
5969 group_sid,
5970 fsp->fsp_flags.is_directory);
5971 if (!NT_STATUS_IS_OK(status)) {
5972 TALLOC_FREE(frame);
5973 return status;
5976 /* If inheritable_components == false,
5977 se_create_child_secdesc()
5978 creates a security descriptor with a NULL dacl
5979 entry, but with SEC_DESC_DACL_PRESENT. We need
5980 to remove that flag. */
5982 if (!inheritable_components) {
5983 security_info_sent &= ~SECINFO_DACL;
5984 psd->type &= ~SEC_DESC_DACL_PRESENT;
5987 if (DEBUGLEVEL >= 10) {
5988 DEBUG(10,("inherit_new_acl: child acl for %s is:\n",
5989 fsp_str_dbg(fsp) ));
5990 NDR_PRINT_DEBUG(security_descriptor, psd);
5993 if (inherit_owner) {
5994 /* We need to be root to force this. */
5995 become_root();
5997 status = SMB_VFS_FSET_NT_ACL(metadata_fsp(fsp),
5998 security_info_sent,
5999 psd);
6000 if (inherit_owner) {
6001 unbecome_root();
6003 TALLOC_FREE(frame);
6004 return status;
6008 * If we already have a lease, it must match the new file id. [MS-SMB2]
6009 * 3.3.5.9.8 speaks about INVALID_PARAMETER if an already used lease key is
6010 * used for a different file name.
6013 struct lease_match_state {
6014 /* Input parameters. */
6015 TALLOC_CTX *mem_ctx;
6016 const char *servicepath;
6017 const struct smb_filename *fname;
6018 bool file_existed;
6019 struct file_id id;
6020 /* Return parameters. */
6021 uint32_t num_file_ids;
6022 struct file_id *ids;
6023 NTSTATUS match_status;
6026 /*************************************************************
6027 File doesn't exist but this lease key+guid is already in use.
6029 This is only allowable in the dynamic share case where the
6030 service path must be different.
6032 There is a small race condition here in the multi-connection
6033 case where a client sends two create calls on different connections,
6034 where the file doesn't exist and one smbd creates the leases_db
6035 entry first, but this will get fixed by the multichannel cleanup
6036 when all identical client_guids get handled by a single smbd.
6037 **************************************************************/
6039 static void lease_match_parser_new_file(
6040 uint32_t num_files,
6041 const struct leases_db_file *files,
6042 struct lease_match_state *state)
6044 uint32_t i;
6046 for (i = 0; i < num_files; i++) {
6047 const struct leases_db_file *f = &files[i];
6048 if (strequal(state->servicepath, f->servicepath)) {
6049 state->match_status = NT_STATUS_INVALID_PARAMETER;
6050 return;
6054 /* Dynamic share case. Break leases on all other files. */
6055 state->match_status = leases_db_copy_file_ids(state->mem_ctx,
6056 num_files,
6057 files,
6058 &state->ids);
6059 if (!NT_STATUS_IS_OK(state->match_status)) {
6060 return;
6063 state->num_file_ids = num_files;
6064 state->match_status = NT_STATUS_OPLOCK_NOT_GRANTED;
6065 return;
6068 static void lease_match_parser(
6069 uint32_t num_files,
6070 const struct leases_db_file *files,
6071 void *private_data)
6073 struct lease_match_state *state =
6074 (struct lease_match_state *)private_data;
6075 uint32_t i;
6077 if (!state->file_existed) {
6079 * Deal with name mismatch or
6080 * possible dynamic share case separately
6081 * to make code clearer.
6083 lease_match_parser_new_file(num_files,
6084 files,
6085 state);
6086 return;
6089 /* File existed. */
6090 state->match_status = NT_STATUS_OK;
6092 for (i = 0; i < num_files; i++) {
6093 const struct leases_db_file *f = &files[i];
6095 /* Everything should be the same. */
6096 if (!file_id_equal(&state->id, &f->id)) {
6098 * The client asked for a lease on a
6099 * file that doesn't match the file_id
6100 * in the database.
6102 * Maybe this is a dynamic share, i.e.
6103 * a share where the servicepath is
6104 * different for different users (e.g.
6105 * the [HOMES] share.
6107 * If the servicepath is different, but the requested
6108 * file name + stream name is the same then this is
6109 * a dynamic share, the client is using the same share
6110 * name and doesn't know that the underlying servicepath
6111 * is different. It was expecting a lease on the
6112 * same file. Return NT_STATUS_OPLOCK_NOT_GRANTED
6113 * to break leases
6115 * Otherwise the client has messed up, or is
6116 * testing our error codes, so return
6117 * NT_STATUS_INVALID_PARAMETER.
6119 if (!strequal(f->servicepath, state->servicepath) &&
6120 strequal(f->base_name, state->fname->base_name) &&
6121 strequal(f->stream_name, state->fname->stream_name))
6124 * Name is the same but servicepath is
6125 * different, dynamic share. Break leases.
6127 state->match_status =
6128 NT_STATUS_OPLOCK_NOT_GRANTED;
6129 } else {
6130 state->match_status =
6131 NT_STATUS_INVALID_PARAMETER;
6133 break;
6135 if (!strequal(f->servicepath, state->servicepath)) {
6136 state->match_status = NT_STATUS_INVALID_PARAMETER;
6137 break;
6139 if (!strequal(f->base_name, state->fname->base_name)) {
6140 state->match_status = NT_STATUS_INVALID_PARAMETER;
6141 break;
6143 if (!strequal(f->stream_name, state->fname->stream_name)) {
6144 state->match_status = NT_STATUS_INVALID_PARAMETER;
6145 break;
6149 if (NT_STATUS_IS_OK(state->match_status)) {
6151 * Common case - just opening another handle on a
6152 * file on a non-dynamic share.
6154 return;
6157 if (NT_STATUS_EQUAL(state->match_status, NT_STATUS_INVALID_PARAMETER)) {
6158 /* Mismatched path. Error back to client. */
6159 return;
6163 * File id mismatch. Dynamic share case NT_STATUS_OPLOCK_NOT_GRANTED.
6164 * Don't allow leases.
6167 state->match_status = leases_db_copy_file_ids(state->mem_ctx,
6168 num_files,
6169 files,
6170 &state->ids);
6171 if (!NT_STATUS_IS_OK(state->match_status)) {
6172 return;
6175 state->num_file_ids = num_files;
6176 state->match_status = NT_STATUS_OPLOCK_NOT_GRANTED;
6177 return;
6180 struct lease_match_break_state {
6181 struct messaging_context *msg_ctx;
6182 const struct smb2_lease_key *lease_key;
6183 struct file_id id;
6185 bool found_lease;
6186 uint16_t version;
6187 uint16_t epoch;
6190 static bool lease_match_break_fn(
6191 struct share_mode_entry *e,
6192 void *private_data)
6194 struct lease_match_break_state *state = private_data;
6195 bool stale, equal;
6196 uint32_t e_lease_type = SMB2_LEASE_NONE;
6197 NTSTATUS status;
6199 stale = share_entry_stale_pid(e);
6200 if (stale) {
6201 return false;
6204 equal = smb2_lease_key_equal(&e->lease_key, state->lease_key);
6205 if (!equal) {
6206 return false;
6209 status = leases_db_get(
6210 &e->client_guid,
6211 &e->lease_key,
6212 &state->id,
6213 &e_lease_type, /* current_state */
6214 NULL, /* breaking */
6215 NULL, /* breaking_to_requested */
6216 NULL, /* breaking_to_required */
6217 &state->version, /* lease_version */
6218 &state->epoch); /* epoch */
6219 if (NT_STATUS_IS_OK(status)) {
6220 state->found_lease = true;
6221 } else {
6222 DBG_WARNING("Could not find version/epoch: %s\n",
6223 nt_errstr(status));
6224 return false;
6227 if (e_lease_type == SMB2_LEASE_NONE) {
6228 return false;
6230 send_break_message(state->msg_ctx, &state->id, e, SMB2_LEASE_NONE);
6233 * Windows 7 and 8 lease clients are broken in that they will
6234 * not respond to lease break requests whilst waiting for an
6235 * outstanding open request on that lease handle on the same
6236 * TCP connection, due to holding an internal inode lock.
6238 * This means we can't reschedule ourselves here, but must
6239 * return from the create.
6241 * Work around:
6243 * Send the breaks and then return SMB2_LEASE_NONE in the
6244 * lease handle to cause them to acknowledge the lease
6245 * break. Consultation with Microsoft engineering confirmed
6246 * this approach is safe.
6249 return false;
6252 static void lease_match_fid_fn(struct share_mode_lock *lck,
6253 void *private_data)
6255 bool ok;
6257 ok = share_mode_forall_leases(lck, lease_match_break_fn, private_data);
6258 if (!ok) {
6259 DBG_DEBUG("share_mode_forall_leases failed\n");
6263 static NTSTATUS lease_match(connection_struct *conn,
6264 struct smb_request *req,
6265 const struct smb2_lease_key *lease_key,
6266 const char *servicepath,
6267 const struct smb_filename *fname,
6268 uint16_t *p_version,
6269 uint16_t *p_epoch)
6271 struct smbd_server_connection *sconn = req->sconn;
6272 TALLOC_CTX *tos = talloc_tos();
6273 struct lease_match_state state = {
6274 .mem_ctx = tos,
6275 .servicepath = servicepath,
6276 .fname = fname,
6277 .match_status = NT_STATUS_OK
6279 uint32_t i;
6280 NTSTATUS status;
6282 state.file_existed = VALID_STAT(fname->st);
6283 if (state.file_existed) {
6284 state.id = vfs_file_id_from_sbuf(conn, &fname->st);
6287 status = leases_db_parse(&sconn->client->global->client_guid,
6288 lease_key, lease_match_parser, &state);
6289 if (!NT_STATUS_IS_OK(status)) {
6291 * Not found or error means okay: We can make the lease pass
6293 return NT_STATUS_OK;
6295 if (!NT_STATUS_EQUAL(state.match_status, NT_STATUS_OPLOCK_NOT_GRANTED)) {
6297 * Anything but NT_STATUS_OPLOCK_NOT_GRANTED, let the caller
6298 * deal with it.
6300 return state.match_status;
6303 /* We have to break all existing leases. */
6304 for (i = 0; i < state.num_file_ids; i++) {
6305 struct lease_match_break_state break_state = {
6306 .msg_ctx = conn->sconn->msg_ctx,
6307 .lease_key = lease_key,
6310 if (file_id_equal(&state.ids[i], &state.id)) {
6311 /* Don't need to break our own file. */
6312 continue;
6315 break_state.id = state.ids[i];
6317 status = share_mode_do_locked_vfs_denied(break_state.id,
6318 lease_match_fid_fn,
6319 &break_state);
6320 if (!NT_STATUS_IS_OK(status)) {
6321 /* Race condition - file already closed. */
6322 continue;
6325 if (break_state.found_lease) {
6326 *p_version = break_state.version;
6327 *p_epoch = break_state.epoch;
6331 * Ensure we don't grant anything more so we
6332 * never upgrade.
6334 return NT_STATUS_OPLOCK_NOT_GRANTED;
6338 * Wrapper around open_file_ntcreate and open_directory
6341 static NTSTATUS create_file_unixpath(connection_struct *conn,
6342 struct smb_request *req,
6343 struct files_struct *dirfsp,
6344 struct smb_filename *smb_fname,
6345 uint32_t access_mask,
6346 uint32_t share_access,
6347 uint32_t create_disposition,
6348 uint32_t create_options,
6349 uint32_t file_attributes,
6350 uint32_t oplock_request,
6351 const struct smb2_lease *lease,
6352 uint64_t allocation_size,
6353 uint32_t private_flags,
6354 struct security_descriptor *sd,
6355 struct ea_list *ea_list,
6357 files_struct **result,
6358 int *pinfo)
6360 struct smb2_lease none_lease;
6361 int info = FILE_WAS_OPENED;
6362 files_struct *base_fsp = NULL;
6363 files_struct *fsp = NULL;
6364 bool free_fsp_on_error = false;
6365 NTSTATUS status;
6366 int ret;
6367 struct smb_filename *parent_dir_fname = NULL;
6368 struct smb_filename *smb_fname_atname = NULL;
6370 DBG_DEBUG("access_mask = 0x%"PRIx32" "
6371 "file_attributes = 0x%"PRIx32" "
6372 "share_access = 0x%"PRIx32" "
6373 "create_disposition = 0x%"PRIx32" "
6374 "create_options = 0x%"PRIx32" "
6375 "oplock_request = 0x%"PRIx32" "
6376 "private_flags = 0x%"PRIx32" "
6377 "ea_list = %p, "
6378 "sd = %p, "
6379 "fname = %s\n",
6380 access_mask,
6381 file_attributes,
6382 share_access,
6383 create_disposition,
6384 create_options,
6385 oplock_request,
6386 private_flags,
6387 ea_list,
6389 smb_fname_str_dbg(smb_fname));
6391 if (create_options & FILE_OPEN_BY_FILE_ID) {
6392 status = NT_STATUS_NOT_SUPPORTED;
6393 goto fail;
6396 if (create_options & NTCREATEX_OPTIONS_INVALID_PARAM_MASK) {
6397 status = NT_STATUS_INVALID_PARAMETER;
6398 goto fail;
6401 if (!(create_options & FILE_OPEN_REPARSE_POINT) &&
6402 (smb_fname->fsp != NULL) && /* new files don't have an fsp */
6403 VALID_STAT(smb_fname->fsp->fsp_name->st))
6405 mode_t type = (smb_fname->fsp->fsp_name->st.st_ex_mode &
6406 S_IFMT);
6408 switch (type) {
6409 case S_IFREG:
6410 FALL_THROUGH;
6411 case S_IFDIR:
6412 break;
6413 case S_IFLNK:
6415 * We should never get this far with a symlink
6416 * "as such". Report as not existing.
6418 status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
6419 goto fail;
6420 default:
6421 status = NT_STATUS_IO_REPARSE_TAG_NOT_HANDLED;
6422 goto fail;
6426 if (req == NULL) {
6427 oplock_request |= INTERNAL_OPEN_ONLY;
6430 if (lease != NULL) {
6431 uint16_t epoch = lease->lease_epoch;
6432 uint16_t version = lease->lease_version;
6434 if (req == NULL) {
6435 DBG_WARNING("Got lease on internal open\n");
6436 status = NT_STATUS_INTERNAL_ERROR;
6437 goto fail;
6440 status = lease_match(conn,
6441 req,
6442 &lease->lease_key,
6443 conn->connectpath,
6444 smb_fname,
6445 &version,
6446 &epoch);
6447 if (NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) {
6448 /* Dynamic share file. No leases and update epoch... */
6449 none_lease = *lease;
6450 none_lease.lease_state = SMB2_LEASE_NONE;
6451 none_lease.lease_epoch = epoch;
6452 none_lease.lease_version = version;
6453 lease = &none_lease;
6454 } else if (!NT_STATUS_IS_OK(status)) {
6455 goto fail;
6459 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
6460 && (access_mask & DELETE_ACCESS)
6461 && !is_named_stream(smb_fname)) {
6463 * We can't open a file with DELETE access if any of the
6464 * streams is open without FILE_SHARE_DELETE
6466 status = open_streams_for_delete(conn, smb_fname);
6468 if (!NT_STATUS_IS_OK(status)) {
6469 goto fail;
6473 if (access_mask & SEC_FLAG_SYSTEM_SECURITY) {
6474 bool ok;
6476 ok = security_token_has_privilege(get_current_nttok(conn),
6477 SEC_PRIV_SECURITY);
6478 if (!ok) {
6479 DBG_DEBUG("open on %s failed - "
6480 "SEC_FLAG_SYSTEM_SECURITY denied.\n",
6481 smb_fname_str_dbg(smb_fname));
6482 status = NT_STATUS_PRIVILEGE_NOT_HELD;
6483 goto fail;
6486 if (conn_using_smb2(conn->sconn) &&
6487 (access_mask == SEC_FLAG_SYSTEM_SECURITY))
6490 * No other bits set. Windows SMB2 refuses this.
6491 * See smbtorture3 SMB2-SACL test.
6493 * Note this is an SMB2-only behavior,
6494 * smbtorture3 SMB1-SYSTEM-SECURITY already tests
6495 * that SMB1 allows this.
6497 status = NT_STATUS_ACCESS_DENIED;
6498 goto fail;
6503 * Files or directories can't be opened DELETE_ON_CLOSE without
6504 * delete access.
6505 * BUG: https://bugzilla.samba.org/show_bug.cgi?id=13358
6507 if ((create_options & FILE_DELETE_ON_CLOSE) &&
6508 ((access_mask & DELETE_ACCESS) == 0)) {
6509 status = NT_STATUS_INVALID_PARAMETER;
6510 goto fail;
6513 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
6514 && is_named_stream(smb_fname))
6516 uint32_t base_create_disposition;
6517 struct smb_filename *smb_fname_base = NULL;
6518 uint32_t base_privflags;
6520 if (create_options & FILE_DIRECTORY_FILE) {
6521 DBG_DEBUG("Can't open a stream as directory\n");
6522 status = NT_STATUS_NOT_A_DIRECTORY;
6523 goto fail;
6526 switch (create_disposition) {
6527 case FILE_OPEN:
6528 base_create_disposition = FILE_OPEN;
6529 break;
6530 default:
6531 base_create_disposition = FILE_OPEN_IF;
6532 break;
6535 smb_fname_base = cp_smb_filename_nostream(
6536 talloc_tos(), smb_fname);
6538 if (smb_fname_base == NULL) {
6539 status = NT_STATUS_NO_MEMORY;
6540 goto fail;
6544 * We may be creating the basefile as part of creating the
6545 * stream, so it's legal if the basefile doesn't exist at this
6546 * point, the create_file_unixpath() below will create it. But
6547 * if the basefile exists we want a handle so we can fstat() it.
6550 ret = vfs_stat(conn, smb_fname_base);
6551 if (ret == -1 && errno != ENOENT) {
6552 status = map_nt_error_from_unix(errno);
6553 TALLOC_FREE(smb_fname_base);
6554 goto fail;
6556 if (ret == 0) {
6557 status = openat_pathref_fsp(conn->cwd_fsp,
6558 smb_fname_base);
6559 if (!NT_STATUS_IS_OK(status)) {
6560 DBG_ERR("open_smb_fname_fsp [%s] failed: %s\n",
6561 smb_fname_str_dbg(smb_fname_base),
6562 nt_errstr(status));
6563 TALLOC_FREE(smb_fname_base);
6564 goto fail;
6568 * https://bugzilla.samba.org/show_bug.cgi?id=10229
6569 * We need to check if the requested access mask
6570 * could be used to open the underlying file (if
6571 * it existed), as we're passing in zero for the
6572 * access mask to the base filename.
6574 status = check_base_file_access(smb_fname_base->fsp,
6575 access_mask);
6577 if (!NT_STATUS_IS_OK(status)) {
6578 DEBUG(10, ("Permission check "
6579 "for base %s failed: "
6580 "%s\n", smb_fname->base_name,
6581 nt_errstr(status)));
6582 TALLOC_FREE(smb_fname_base);
6583 goto fail;
6587 base_privflags = NTCREATEX_FLAG_STREAM_BASEOPEN;
6589 /* Open the base file. */
6590 status = create_file_unixpath(conn,
6591 NULL,
6592 dirfsp,
6593 smb_fname_base,
6595 FILE_SHARE_READ
6596 | FILE_SHARE_WRITE
6597 | FILE_SHARE_DELETE,
6598 base_create_disposition,
6602 NULL,
6604 base_privflags,
6605 NULL,
6606 NULL,
6607 &base_fsp,
6608 NULL);
6609 TALLOC_FREE(smb_fname_base);
6611 if (!NT_STATUS_IS_OK(status)) {
6612 DEBUG(10, ("create_file_unixpath for base %s failed: "
6613 "%s\n", smb_fname->base_name,
6614 nt_errstr(status)));
6615 goto fail;
6619 if (smb_fname->fsp != NULL) {
6621 fsp = smb_fname->fsp;
6624 * We're about to use smb_fname->fsp for the fresh open.
6626 * Every fsp passed in via smb_fname->fsp already
6627 * holds a fsp->fsp_name. If it is already this
6628 * fsp->fsp_name that we got passed in as our input
6629 * argument smb_fname, these two are assumed to have
6630 * the same lifetime: Every fsp hangs of "conn", and
6631 * fsp->fsp_name is its talloc child.
6634 if (smb_fname != smb_fname->fsp->fsp_name) {
6636 * "smb_fname" is temporary in this case, but
6637 * the destructor of smb_fname would also tear
6638 * down the fsp we're about to use. Unlink
6639 * them from each other.
6641 smb_fname_fsp_unlink(smb_fname);
6644 * "fsp" is ours now
6646 free_fsp_on_error = true;
6649 status = fsp_bind_smb(fsp, req);
6650 if (!NT_STATUS_IS_OK(status)) {
6651 goto fail;
6654 if (fsp_is_alternate_stream(fsp)) {
6655 struct files_struct *tmp_base_fsp = fsp->base_fsp;
6657 fsp_set_base_fsp(fsp, NULL);
6659 fd_close(tmp_base_fsp);
6660 file_free(NULL, tmp_base_fsp);
6662 } else {
6664 * No fsp passed in that we can use, create one
6666 status = file_new(req, conn, &fsp);
6667 if(!NT_STATUS_IS_OK(status)) {
6668 goto fail;
6670 free_fsp_on_error = true;
6672 status = fsp_set_smb_fname(fsp, smb_fname);
6673 if (!NT_STATUS_IS_OK(status)) {
6674 goto fail;
6678 SMB_ASSERT(fsp->fsp_name->fsp != NULL);
6679 SMB_ASSERT(fsp->fsp_name->fsp == fsp);
6681 if (base_fsp) {
6683 * We're opening the stream element of a
6684 * base_fsp we already opened. Set up the
6685 * base_fsp pointer.
6687 fsp_set_base_fsp(fsp, base_fsp);
6690 if (dirfsp != NULL) {
6691 status = SMB_VFS_PARENT_PATHNAME(
6692 conn,
6693 talloc_tos(),
6694 smb_fname,
6695 &parent_dir_fname,
6696 &smb_fname_atname);
6697 if (!NT_STATUS_IS_OK(status)) {
6698 goto fail;
6700 } else {
6702 * Get a pathref on the parent. We can re-use this for
6703 * multiple calls to check parent ACLs etc. to avoid
6704 * pathname calls.
6706 status = parent_pathref(talloc_tos(),
6707 conn->cwd_fsp,
6708 smb_fname,
6709 &parent_dir_fname,
6710 &smb_fname_atname);
6711 if (!NT_STATUS_IS_OK(status)) {
6712 goto fail;
6715 dirfsp = parent_dir_fname->fsp;
6716 status = fsp_set_smb_fname(dirfsp, parent_dir_fname);
6717 if (!NT_STATUS_IS_OK(status)) {
6718 goto fail;
6723 * If it's a request for a directory open, deal with it separately.
6726 if (create_options & FILE_DIRECTORY_FILE) {
6728 if (create_options & FILE_NON_DIRECTORY_FILE) {
6729 status = NT_STATUS_INVALID_PARAMETER;
6730 goto fail;
6733 /* Can't open a temp directory. IFS kit test. */
6734 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
6735 (file_attributes & FILE_ATTRIBUTE_TEMPORARY)) {
6736 status = NT_STATUS_INVALID_PARAMETER;
6737 goto fail;
6741 * We will get a create directory here if the Win32
6742 * app specified a security descriptor in the
6743 * CreateDirectory() call.
6746 oplock_request = 0;
6747 status = open_directory(conn,
6748 req,
6749 access_mask,
6750 share_access,
6751 create_disposition,
6752 create_options,
6753 file_attributes,
6754 dirfsp->fsp_name,
6755 smb_fname_atname,
6757 &info,
6758 fsp);
6759 } else {
6762 * Ordinary file case.
6765 if (allocation_size) {
6766 fsp->initial_allocation_size = smb_roundup(fsp->conn,
6767 allocation_size);
6770 status = open_file_ntcreate(conn,
6771 req,
6772 access_mask,
6773 share_access,
6774 create_disposition,
6775 create_options,
6776 file_attributes,
6777 oplock_request,
6778 lease,
6779 private_flags,
6780 dirfsp->fsp_name,
6781 smb_fname_atname,
6782 &info,
6783 fsp);
6784 if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
6786 /* A stream open never opens a directory */
6788 if (base_fsp) {
6789 status = NT_STATUS_FILE_IS_A_DIRECTORY;
6790 goto fail;
6794 * Fail the open if it was explicitly a non-directory
6795 * file.
6798 if (create_options & FILE_NON_DIRECTORY_FILE) {
6799 status = NT_STATUS_FILE_IS_A_DIRECTORY;
6800 goto fail;
6803 oplock_request = 0;
6804 status = open_directory(conn,
6805 req,
6806 access_mask,
6807 share_access,
6808 create_disposition,
6809 create_options,
6810 file_attributes,
6811 dirfsp->fsp_name,
6812 smb_fname_atname,
6814 &info,
6815 fsp);
6819 if (!NT_STATUS_IS_OK(status)) {
6820 goto fail;
6823 fsp->fsp_flags.is_fsa = true;
6825 if ((ea_list != NULL) &&
6826 ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN))) {
6827 status = set_ea(conn, fsp, ea_list);
6828 if (!NT_STATUS_IS_OK(status)) {
6829 goto fail;
6833 if (!fsp->fsp_flags.is_directory &&
6834 S_ISDIR(fsp->fsp_name->st.st_ex_mode))
6836 status = NT_STATUS_ACCESS_DENIED;
6837 goto fail;
6840 /* Save the requested allocation size. */
6841 if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
6842 if ((allocation_size > (uint64_t)fsp->fsp_name->st.st_ex_size)
6843 && !(fsp->fsp_flags.is_directory))
6845 fsp->initial_allocation_size = smb_roundup(
6846 fsp->conn, allocation_size);
6847 if (vfs_allocate_file_space(
6848 fsp, fsp->initial_allocation_size) == -1) {
6849 status = NT_STATUS_DISK_FULL;
6850 goto fail;
6852 } else {
6853 fsp->initial_allocation_size = smb_roundup(
6854 fsp->conn, (uint64_t)fsp->fsp_name->st.st_ex_size);
6856 } else {
6857 fsp->initial_allocation_size = 0;
6860 if ((info == FILE_WAS_CREATED) &&
6861 !S_ISDIR(fsp->fsp_name->st.st_ex_mode) &&
6862 lp_nt_acl_support(SNUM(conn)) &&
6863 !fsp_is_alternate_stream(fsp)) {
6864 status = apply_new_nt_acl(dirfsp, fsp, sd);
6865 if (!NT_STATUS_IS_OK(status)) {
6866 DBG_WARNING("apply_new_nt_acl(): failed for %s with %s\n",
6867 fsp_str_dbg(fsp), nt_errstr(status));
6868 goto fail;
6872 if ((conn->fs_capabilities & FILE_FILE_COMPRESSION)
6873 && (create_options & FILE_NO_COMPRESSION)
6874 && (info == FILE_WAS_CREATED)) {
6875 status = SMB_VFS_SET_COMPRESSION(conn, fsp, fsp,
6876 COMPRESSION_FORMAT_NONE);
6877 if (!NT_STATUS_IS_OK(status)) {
6878 DEBUG(1, ("failed to disable compression: %s\n",
6879 nt_errstr(status)));
6883 DEBUG(10, ("create_file_unixpath: info=%d\n", info));
6885 *result = fsp;
6886 if (pinfo != NULL) {
6887 *pinfo = info;
6890 smb_fname->st = fsp->fsp_name->st;
6892 TALLOC_FREE(parent_dir_fname);
6894 return NT_STATUS_OK;
6896 fail:
6897 DEBUG(10, ("create_file_unixpath: %s\n", nt_errstr(status)));
6899 if (fsp != NULL) {
6901 * The close_file below will close
6902 * fsp->base_fsp.
6904 base_fsp = NULL;
6905 close_file_smb(req, fsp, ERROR_CLOSE);
6906 if (free_fsp_on_error) {
6907 file_free(req, fsp);
6908 fsp = NULL;
6911 if (base_fsp != NULL) {
6912 close_file_free(req, &base_fsp, ERROR_CLOSE);
6915 TALLOC_FREE(parent_dir_fname);
6917 return status;
6920 NTSTATUS create_file_default(connection_struct *conn,
6921 struct smb_request *req,
6922 struct files_struct *dirfsp,
6923 struct smb_filename *smb_fname,
6924 uint32_t access_mask,
6925 uint32_t share_access,
6926 uint32_t create_disposition,
6927 uint32_t create_options,
6928 uint32_t file_attributes,
6929 uint32_t oplock_request,
6930 const struct smb2_lease *lease,
6931 uint64_t allocation_size,
6932 uint32_t private_flags,
6933 struct security_descriptor *sd,
6934 struct ea_list *ea_list,
6935 files_struct **result,
6936 int *pinfo,
6937 const struct smb2_create_blobs *in_context_blobs,
6938 struct smb2_create_blobs *out_context_blobs)
6940 int info = FILE_WAS_OPENED;
6941 files_struct *fsp = NULL;
6942 NTSTATUS status;
6943 bool stream_name = false;
6944 struct smb2_create_blob *posx = NULL;
6946 DBG_DEBUG("access_mask = 0x%" PRIu32
6947 " file_attributes = 0x%" PRIu32
6948 " share_access = 0x%" PRIu32
6949 " create_disposition = 0x%" PRIu32
6950 " create_options = 0x%" PRIu32
6951 " oplock_request = 0x%" PRIu32
6952 " private_flags = 0x%" PRIu32
6953 " ea_list = %p, sd = %p, fname = %s\n",
6954 access_mask,
6955 file_attributes,
6956 share_access,
6957 create_disposition,
6958 create_options,
6959 oplock_request,
6960 private_flags,
6961 ea_list,
6963 smb_fname_str_dbg(smb_fname));
6965 if (req != NULL) {
6967 * Remember the absolute time of the original request
6968 * with this mid. We'll use it later to see if this
6969 * has timed out.
6971 get_deferred_open_message_state(req, &req->request_time, NULL);
6975 * Check to see if this is a mac fork of some kind.
6978 stream_name = is_ntfs_stream_smb_fname(smb_fname);
6979 if (stream_name) {
6980 enum FAKE_FILE_TYPE fake_file_type;
6982 fake_file_type = is_fake_file(smb_fname);
6984 if (req != NULL && fake_file_type != FAKE_FILE_TYPE_NONE) {
6987 * Here we go! support for changing the disk quotas
6988 * --metze
6990 * We need to fake up to open this MAGIC QUOTA file
6991 * and return a valid FID.
6993 * w2k close this file directly after opening xp
6994 * also tries a QUERY_FILE_INFO on the file and then
6995 * close it
6997 status = open_fake_file(req, conn, req->vuid,
6998 fake_file_type, smb_fname,
6999 access_mask, &fsp);
7000 if (!NT_STATUS_IS_OK(status)) {
7001 goto fail;
7004 ZERO_STRUCT(smb_fname->st);
7005 goto done;
7008 if (!(conn->fs_capabilities & FILE_NAMED_STREAMS)) {
7009 status = NT_STATUS_OBJECT_NAME_INVALID;
7010 goto fail;
7014 if (is_ntfs_default_stream_smb_fname(smb_fname)) {
7015 int ret;
7016 /* We have to handle this error here. */
7017 if (create_options & FILE_DIRECTORY_FILE) {
7018 status = NT_STATUS_NOT_A_DIRECTORY;
7019 goto fail;
7021 ret = vfs_stat(conn, smb_fname);
7022 if (ret == 0 && VALID_STAT_OF_DIR(smb_fname->st)) {
7023 status = NT_STATUS_FILE_IS_A_DIRECTORY;
7024 goto fail;
7028 posx = smb2_create_blob_find(
7029 in_context_blobs, SMB2_CREATE_TAG_POSIX);
7030 if (posx != NULL) {
7031 uint32_t wire_mode_bits = 0;
7032 mode_t mode_bits = 0;
7033 SMB_STRUCT_STAT sbuf = { 0 };
7035 if (posx->data.length != 4) {
7036 status = NT_STATUS_INVALID_PARAMETER;
7037 goto fail;
7040 wire_mode_bits = IVAL(posx->data.data, 0);
7041 status = unix_perms_from_wire(conn,
7042 &sbuf,
7043 wire_mode_bits,
7044 &mode_bits);
7045 if (!NT_STATUS_IS_OK(status)) {
7046 goto fail;
7048 if (create_options & FILE_DIRECTORY_FILE) {
7049 mode_bits = apply_conf_dir_mask(conn, mode_bits);
7050 } else {
7051 mode_bits = apply_conf_file_mask(conn, mode_bits);
7054 * Remove type info from mode, leaving only the
7055 * permissions and setuid/gid bits.
7057 mode_bits &= ~S_IFMT;
7059 file_attributes = (FILE_FLAG_POSIX_SEMANTICS | mode_bits);
7062 status = create_file_unixpath(conn,
7063 req,
7064 dirfsp,
7065 smb_fname,
7066 access_mask,
7067 share_access,
7068 create_disposition,
7069 create_options,
7070 file_attributes,
7071 oplock_request,
7072 lease,
7073 allocation_size,
7074 private_flags,
7076 ea_list,
7077 &fsp,
7078 &info);
7079 if (!NT_STATUS_IS_OK(status)) {
7080 goto fail;
7083 done:
7084 DEBUG(10, ("create_file: info=%d\n", info));
7086 *result = fsp;
7087 if (pinfo != NULL) {
7088 *pinfo = info;
7090 return NT_STATUS_OK;
7092 fail:
7093 DEBUG(10, ("create_file: %s\n", nt_errstr(status)));
7095 if (fsp != NULL) {
7096 close_file_free(req, &fsp, ERROR_CLOSE);
7098 return status;