VFS: Rename kernel_flock to filesystem_sharemode
[Samba.git] / source3 / smbd / open.c
blob8318972286d8dbf79d3730034eb4117b1c6df4f1
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 "smb1_utils.h"
25 #include "system/filesys.h"
26 #include "lib/util/server_id.h"
27 #include "printing.h"
28 #include "locking/share_mode_lock.h"
29 #include "smbd/smbd.h"
30 #include "smbd/globals.h"
31 #include "fake_file.h"
32 #include "../libcli/security/security.h"
33 #include "../librpc/gen_ndr/ndr_security.h"
34 #include "../librpc/gen_ndr/ndr_open_files.h"
35 #include "../librpc/gen_ndr/idmap.h"
36 #include "../librpc/gen_ndr/ioctl.h"
37 #include "passdb/lookup_sid.h"
38 #include "auth.h"
39 #include "serverid.h"
40 #include "messages.h"
41 #include "source3/lib/dbwrap/dbwrap_watch.h"
42 #include "locking/leases_db.h"
43 #include "librpc/gen_ndr/ndr_leases_db.h"
44 #include "lib/util/time_basic.h"
46 extern const struct generic_mapping file_generic_mapping;
48 struct deferred_open_record {
49 struct smbXsrv_connection *xconn;
50 uint64_t mid;
52 bool async_open;
55 * Timer for async opens, needed because they don't use a watch on
56 * a locking.tdb record. This is currently only used for real async
57 * opens and just terminates smbd if the async open times out.
59 struct tevent_timer *te;
62 * For the samba kernel oplock case we use both a timeout and
63 * a watch on locking.tdb. This way in case it's smbd holding
64 * the kernel oplock we get directly notified for the retry
65 * once the kernel oplock is properly broken. Store the req
66 * here so that it can be timely discarded once the timer
67 * above fires.
69 struct tevent_req *watch_req;
72 /****************************************************************************
73 If the requester wanted DELETE_ACCESS and was rejected because
74 the file ACL didn't include DELETE_ACCESS, see if the parent ACL
75 overrides this.
76 ****************************************************************************/
78 static bool parent_override_delete(connection_struct *conn,
79 struct files_struct *dirfsp,
80 const struct smb_filename *smb_fname,
81 uint32_t access_mask,
82 uint32_t rejected_mask)
84 if ((access_mask & DELETE_ACCESS) &&
85 (rejected_mask & DELETE_ACCESS) &&
86 can_delete_file_in_directory(conn,
87 dirfsp,
88 smb_fname))
90 return true;
92 return false;
95 /****************************************************************************
96 Check if we have open rights.
97 ****************************************************************************/
99 static NTSTATUS smbd_check_access_rights_sd(
100 struct connection_struct *conn,
101 struct files_struct *dirfsp,
102 const struct smb_filename *smb_fname,
103 struct security_descriptor *sd,
104 bool use_privs,
105 uint32_t access_mask)
107 uint32_t rejected_share_access;
108 uint32_t rejected_mask = access_mask;
109 uint32_t do_not_check_mask = 0;
110 NTSTATUS status;
112 rejected_share_access = access_mask & ~(conn->share_access);
114 if (rejected_share_access) {
115 DBG_DEBUG("rejected share access 0x%x on %s (0x%x)\n",
116 (unsigned int)access_mask,
117 smb_fname_str_dbg(smb_fname),
118 (unsigned int)rejected_share_access);
119 return NT_STATUS_ACCESS_DENIED;
122 if (!use_privs && get_current_uid(conn) == (uid_t)0) {
123 /* I'm sorry sir, I didn't know you were root... */
124 DBG_DEBUG("root override on %s. Granting 0x%x\n",
125 smb_fname_str_dbg(smb_fname),
126 (unsigned int)access_mask);
127 return NT_STATUS_OK;
130 if ((access_mask & DELETE_ACCESS) &&
131 !lp_acl_check_permissions(SNUM(conn)))
133 DBG_DEBUG("Not checking ACL on DELETE_ACCESS on file %s. "
134 "Granting 0x%x\n",
135 smb_fname_str_dbg(smb_fname),
136 (unsigned int)access_mask);
137 return NT_STATUS_OK;
140 if (access_mask == DELETE_ACCESS &&
141 VALID_STAT(smb_fname->st) &&
142 S_ISLNK(smb_fname->st.st_ex_mode))
144 /* We can always delete a symlink. */
145 DBG_DEBUG("Not checking ACL on DELETE_ACCESS on symlink %s.\n",
146 smb_fname_str_dbg(smb_fname));
147 return NT_STATUS_OK;
150 if (sd == NULL) {
151 goto access_denied;
155 * If we can access the path to this file, by
156 * default we have FILE_READ_ATTRIBUTES from the
157 * containing directory. See the section:
158 * "Algorithm to Check Access to an Existing File"
159 * in MS-FSA.pdf.
161 * se_file_access_check() also takes care of
162 * owner WRITE_DAC and READ_CONTROL.
164 do_not_check_mask = FILE_READ_ATTRIBUTES;
167 * Samba 3.6 and earlier granted execute access even
168 * if the ACL did not contain execute rights.
169 * Samba 4.0 is more correct and checks it.
170 * The compatibilty mode allows one to skip this check
171 * to smoothen upgrades.
173 if (lp_acl_allow_execute_always(SNUM(conn))) {
174 do_not_check_mask |= FILE_EXECUTE;
177 status = se_file_access_check(sd,
178 get_current_nttok(conn),
179 use_privs,
180 (access_mask & ~do_not_check_mask),
181 &rejected_mask);
183 DBG_DEBUG("File [%s] requesting [0x%x] returning [0x%x] (%s)\n",
184 smb_fname_str_dbg(smb_fname),
185 (unsigned int)access_mask,
186 (unsigned int)rejected_mask,
187 nt_errstr(status));
189 if (!NT_STATUS_IS_OK(status)) {
190 if (DEBUGLEVEL >= 10) {
191 DBG_DEBUG("acl for %s is:\n",
192 smb_fname_str_dbg(smb_fname));
193 NDR_PRINT_DEBUG(security_descriptor, sd);
197 TALLOC_FREE(sd);
199 if (NT_STATUS_IS_OK(status) ||
200 !NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED))
202 return status;
205 /* Here we know status == NT_STATUS_ACCESS_DENIED. */
207 access_denied:
209 if ((access_mask & FILE_WRITE_ATTRIBUTES) &&
210 (rejected_mask & FILE_WRITE_ATTRIBUTES) &&
211 !lp_store_dos_attributes(SNUM(conn)) &&
212 (lp_map_readonly(SNUM(conn)) ||
213 lp_map_archive(SNUM(conn)) ||
214 lp_map_hidden(SNUM(conn)) ||
215 lp_map_system(SNUM(conn))))
217 rejected_mask &= ~FILE_WRITE_ATTRIBUTES;
219 DBG_DEBUG("overrode FILE_WRITE_ATTRIBUTES on file %s\n",
220 smb_fname_str_dbg(smb_fname));
223 if (parent_override_delete(conn,
224 dirfsp,
225 smb_fname,
226 access_mask,
227 rejected_mask))
230 * Were we trying to do an open for delete and didn't get DELETE
231 * access. Check if the directory allows DELETE_CHILD.
232 * See here:
233 * http://blogs.msdn.com/oldnewthing/archive/2004/06/04/148426.aspx
234 * for details.
237 rejected_mask &= ~DELETE_ACCESS;
239 DBG_DEBUG("Overrode DELETE_ACCESS on file %s\n",
240 smb_fname_str_dbg(smb_fname));
243 if (rejected_mask != 0) {
244 return NT_STATUS_ACCESS_DENIED;
246 return NT_STATUS_OK;
249 NTSTATUS smbd_check_access_rights_fsp(struct files_struct *dirfsp,
250 struct files_struct *fsp,
251 bool use_privs,
252 uint32_t access_mask)
254 struct security_descriptor *sd = NULL;
255 NTSTATUS status;
257 /* Cope with fake/printer fsp's. */
258 if (fsp->fake_file_handle != NULL || fsp->print_file != NULL) {
259 if ((fsp->access_mask & access_mask) != access_mask) {
260 return NT_STATUS_ACCESS_DENIED;
262 return NT_STATUS_OK;
265 if (fsp_get_pathref_fd(fsp) == -1) {
267 * This is a POSIX open on a symlink. For the pathname
268 * verison of this function we used to return the st_mode
269 * bits turned into an NT ACL. For a symlink the mode bits
270 * are always rwxrwxrwx which means the pathname version always
271 * returned NT_STATUS_OK for a symlink. For the handle reference
272 * to a symlink use the handle access bits.
274 if ((fsp->access_mask & access_mask) != access_mask) {
275 return NT_STATUS_ACCESS_DENIED;
277 return NT_STATUS_OK;
280 status = SMB_VFS_FGET_NT_ACL(fsp,
281 (SECINFO_OWNER |
282 SECINFO_GROUP |
283 SECINFO_DACL),
284 talloc_tos(),
285 &sd);
286 if (!NT_STATUS_IS_OK(status)) {
287 DBG_DEBUG("Could not get acl on %s: %s\n",
288 fsp_str_dbg(fsp),
289 nt_errstr(status));
290 return status;
293 return smbd_check_access_rights_sd(fsp->conn,
294 dirfsp,
295 fsp->fsp_name,
297 use_privs,
298 access_mask);
302 * Given an fsp that represents a parent directory,
303 * check if the requested access can be granted.
305 NTSTATUS check_parent_access_fsp(struct files_struct *fsp,
306 uint32_t access_mask)
308 NTSTATUS status;
309 struct security_descriptor *parent_sd = NULL;
310 uint32_t access_granted = 0;
311 struct share_mode_lock *lck = NULL;
312 uint32_t name_hash;
313 bool delete_on_close_set;
314 TALLOC_CTX *frame = talloc_stackframe();
316 if (get_current_uid(fsp->conn) == (uid_t)0) {
317 /* I'm sorry sir, I didn't know you were root... */
318 DBG_DEBUG("root override on %s. Granting 0x%x\n",
319 fsp_str_dbg(fsp),
320 (unsigned int)access_mask);
321 status = NT_STATUS_OK;
322 goto out;
325 status = SMB_VFS_FGET_NT_ACL(fsp,
326 SECINFO_DACL,
327 frame,
328 &parent_sd);
330 if (!NT_STATUS_IS_OK(status)) {
331 DBG_INFO("SMB_VFS_FGET_NT_ACL failed for "
332 "%s with error %s\n",
333 fsp_str_dbg(fsp),
334 nt_errstr(status));
335 goto out;
339 * If we can access the path to this file, by
340 * default we have FILE_READ_ATTRIBUTES from the
341 * containing directory. See the section:
342 * "Algorithm to Check Access to an Existing File"
343 * in MS-FSA.pdf.
345 * se_file_access_check() also takes care of
346 * owner WRITE_DAC and READ_CONTROL.
348 status = se_file_access_check(parent_sd,
349 get_current_nttok(fsp->conn),
350 false,
351 (access_mask & ~FILE_READ_ATTRIBUTES),
352 &access_granted);
353 if(!NT_STATUS_IS_OK(status)) {
354 DBG_INFO("access check "
355 "on directory %s for mask 0x%x returned (0x%x) %s\n",
356 fsp_str_dbg(fsp),
357 access_mask,
358 access_granted,
359 nt_errstr(status));
360 goto out;
363 if (!(access_mask & (SEC_DIR_ADD_FILE | SEC_DIR_ADD_SUBDIR))) {
364 status = NT_STATUS_OK;
365 goto out;
367 if (!lp_check_parent_directory_delete_on_close(SNUM(fsp->conn))) {
368 status = NT_STATUS_OK;
369 goto out;
372 /* Check if the directory has delete-on-close set */
373 status = file_name_hash(fsp->conn,
374 fsp->fsp_name->base_name,
375 &name_hash);
376 if (!NT_STATUS_IS_OK(status)) {
377 goto out;
381 * Don't take a lock here. We just need a snapshot
382 * of the current state of delete on close and this is
383 * called in a codepath where we may already have a lock
384 * (and we explicitly can't hold 2 locks at the same time
385 * as that may deadlock).
387 lck = fetch_share_mode_unlocked(frame, fsp->file_id);
388 if (lck == NULL) {
389 status = NT_STATUS_OK;
390 goto out;
393 delete_on_close_set = is_delete_on_close_set(lck, name_hash);
394 if (delete_on_close_set) {
395 status = NT_STATUS_DELETE_PENDING;
396 goto out;
399 status = NT_STATUS_OK;
401 out:
402 TALLOC_FREE(frame);
403 return status;
406 /****************************************************************************
407 Ensure when opening a base file for a stream open that we have permissions
408 to do so given the access mask on the base file.
409 ****************************************************************************/
411 static NTSTATUS check_base_file_access(struct files_struct *fsp,
412 uint32_t access_mask)
414 NTSTATUS status;
416 status = smbd_calculate_access_mask_fsp(fsp->conn->cwd_fsp,
417 fsp,
418 false,
419 access_mask,
420 &access_mask);
421 if (!NT_STATUS_IS_OK(status)) {
422 DEBUG(10, ("smbd_calculate_access_mask "
423 "on file %s returned %s\n",
424 fsp_str_dbg(fsp),
425 nt_errstr(status)));
426 return status;
429 if (access_mask & (FILE_WRITE_DATA|FILE_APPEND_DATA)) {
430 uint32_t dosattrs;
431 if (!CAN_WRITE(fsp->conn)) {
432 return NT_STATUS_ACCESS_DENIED;
434 dosattrs = fdos_mode(fsp);
435 if (IS_DOS_READONLY(dosattrs)) {
436 return NT_STATUS_ACCESS_DENIED;
440 return smbd_check_access_rights_fsp(fsp->conn->cwd_fsp,
441 fsp,
442 false,
443 access_mask);
446 /****************************************************************************
447 Handle differing symlink errno's
448 ****************************************************************************/
450 static NTSTATUS link_errno_convert(int err)
452 #if defined(ENOTSUP) && defined(OSF1)
453 /* handle special Tru64 errno */
454 if (err == ENOTSUP) {
455 err = ELOOP;
457 #endif /* ENOTSUP */
458 #ifdef EFTYPE
459 /* fix broken NetBSD errno */
460 if (err == EFTYPE) {
461 err = ELOOP;
463 #endif /* EFTYPE */
464 /* fix broken FreeBSD errno */
465 if (err == EMLINK) {
466 err = ELOOP;
468 if (err == ELOOP) {
469 return NT_STATUS_STOPPED_ON_SYMLINK;
471 return map_nt_error_from_unix(err);
474 static NTSTATUS non_widelink_open(const struct files_struct *dirfsp,
475 files_struct *fsp,
476 struct smb_filename *smb_fname,
477 int flags,
478 mode_t mode,
479 unsigned int link_depth);
481 /****************************************************************************
482 Follow a symlink in userspace.
483 ****************************************************************************/
485 static NTSTATUS process_symlink_open(const struct files_struct *dirfsp,
486 files_struct *fsp,
487 struct smb_filename *smb_fname,
488 int flags,
489 mode_t mode,
490 unsigned int link_depth)
492 struct connection_struct *conn = dirfsp->conn;
493 const char *conn_rootdir = NULL;
494 struct smb_filename conn_rootdir_fname = { 0 };
495 char *link_target = NULL;
496 int link_len = -1;
497 struct smb_filename *oldwd_fname = NULL;
498 size_t rootdir_len = 0;
499 struct smb_filename *resolved_fname = NULL;
500 char *resolved_name = NULL;
501 bool matched = false;
502 struct smb_filename *full_fname = NULL;
503 NTSTATUS status;
505 conn_rootdir = SMB_VFS_CONNECTPATH(conn, smb_fname);
506 if (conn_rootdir == NULL) {
507 return NT_STATUS_NO_MEMORY;
510 * With shadow_copy2 conn_rootdir can be talloc_freed
511 * whilst we use it in this function. We must take a copy.
513 conn_rootdir_fname.base_name = talloc_strdup(talloc_tos(),
514 conn_rootdir);
515 if (conn_rootdir_fname.base_name == NULL) {
516 return NT_STATUS_NO_MEMORY;
520 * Ensure we don't get stuck in a symlink loop.
522 link_depth++;
523 if (link_depth >= 20) {
524 status = NT_STATUS_STOPPED_ON_SYMLINK;
525 goto out;
528 /* Allocate space for the link target. */
529 link_target = talloc_array(talloc_tos(), char, PATH_MAX);
530 if (link_target == NULL) {
531 status = NT_STATUS_NO_MEMORY;
532 goto out;
536 * Read the link target. We do this just to verify that smb_fname indeed
537 * points at a symbolic link and return NT_STATUS_NOT_A_DIRECTORY
538 * and failure in case smb_fname is NOT a symlink.
540 * The caller needs this piece of information to distinguish two cases
541 * where open() fails with errno=ENOTDIR, cf the comment in
542 * non_widelink_open().
544 * We rely on SMB_VFS_REALPATH() to resolve the path including the
545 * symlink. Once we have SMB_VFS_STATX() or something similar in our VFS
546 * we may want to use that instead of SMB_VFS_READLINKAT().
548 link_len = SMB_VFS_READLINKAT(conn,
549 dirfsp,
550 smb_fname,
551 link_target,
552 PATH_MAX - 1);
553 if (link_len == -1) {
554 status = NT_STATUS_INVALID_PARAMETER;
555 goto out;
558 full_fname = full_path_from_dirfsp_atname(
559 talloc_tos(), dirfsp, smb_fname);
560 if (full_fname == NULL) {
561 status = NT_STATUS_NO_MEMORY;
562 goto out;
565 /* Convert to an absolute path. */
566 resolved_fname = SMB_VFS_REALPATH(conn, talloc_tos(), full_fname);
567 if (resolved_fname == NULL) {
568 status = map_nt_error_from_unix(errno);
569 goto out;
571 resolved_name = resolved_fname->base_name;
574 * We know conn_rootdir starts with '/' and
575 * does not end in '/'. FIXME ! Should we
576 * smb_assert this ?
578 rootdir_len = strlen(conn_rootdir_fname.base_name);
580 matched = (strncmp(conn_rootdir_fname.base_name,
581 resolved_name,
582 rootdir_len) == 0);
583 if (!matched) {
584 status = NT_STATUS_STOPPED_ON_SYMLINK;
585 goto out;
589 * Turn into a path relative to the share root.
591 if (resolved_name[rootdir_len] == '\0') {
592 /* Link to the root of the share. */
593 TALLOC_FREE(smb_fname->base_name);
594 smb_fname->base_name = talloc_strdup(smb_fname, ".");
595 } else if (resolved_name[rootdir_len] == '/') {
596 TALLOC_FREE(smb_fname->base_name);
597 smb_fname->base_name = talloc_strdup(smb_fname,
598 &resolved_name[rootdir_len+1]);
599 } else {
600 status = NT_STATUS_STOPPED_ON_SYMLINK;
601 goto out;
604 if (smb_fname->base_name == NULL) {
605 status = NT_STATUS_NO_MEMORY;
606 goto out;
609 oldwd_fname = vfs_GetWd(talloc_tos(), dirfsp->conn);
610 if (oldwd_fname == NULL) {
611 status = map_nt_error_from_unix(errno);
612 goto out;
615 /* Ensure we operate from the root of the share. */
616 if (vfs_ChDir(conn, &conn_rootdir_fname) == -1) {
617 status = map_nt_error_from_unix(errno);
618 goto out;
622 * And do it all again... As smb_fname is not relative to the passed in
623 * dirfsp anymore, we pass conn->cwd_fsp as dirfsp to
624 * non_widelink_open() to trigger the chdir(parentdir) logic.
626 status = non_widelink_open(conn->cwd_fsp,
627 fsp,
628 smb_fname,
629 flags,
630 mode,
631 link_depth);
633 out:
635 TALLOC_FREE(resolved_fname);
636 TALLOC_FREE(link_target);
637 TALLOC_FREE(conn_rootdir_fname.base_name);
638 if (oldwd_fname != NULL) {
639 int ret = vfs_ChDir(conn, oldwd_fname);
640 if (ret == -1) {
641 smb_panic("unable to get back to old directory\n");
643 TALLOC_FREE(oldwd_fname);
646 return status;
649 /****************************************************************************
650 Non-widelink open.
651 ****************************************************************************/
653 static NTSTATUS non_widelink_open(const struct files_struct *dirfsp,
654 files_struct *fsp,
655 struct smb_filename *smb_fname,
656 int flags,
657 mode_t mode,
658 unsigned int link_depth)
660 struct connection_struct *conn = fsp->conn;
661 NTSTATUS saved_status;
662 NTSTATUS status = NT_STATUS_OK;
663 int fd = -1;
664 struct smb_filename *orig_fsp_name = fsp->fsp_name;
665 struct smb_filename *orig_base_fsp_name = NULL;
666 struct smb_filename *smb_fname_rel = NULL;
667 struct smb_filename *oldwd_fname = NULL;
668 struct smb_filename *parent_dir_fname = NULL;
669 bool have_opath = false;
670 int ret;
672 #ifdef O_PATH
673 have_opath = true;
674 #endif
676 if (dirfsp == conn->cwd_fsp) {
677 if (fsp->fsp_flags.is_directory) {
678 parent_dir_fname = cp_smb_filename(talloc_tos(), smb_fname);
679 if (parent_dir_fname == NULL) {
680 status = NT_STATUS_NO_MEMORY;
681 goto out;
684 smb_fname_rel = synthetic_smb_fname(parent_dir_fname,
685 ".",
686 smb_fname->stream_name,
687 &smb_fname->st,
688 smb_fname->twrp,
689 smb_fname->flags);
690 if (smb_fname_rel == NULL) {
691 status = NT_STATUS_NO_MEMORY;
692 goto out;
694 } else {
695 status = SMB_VFS_PARENT_PATHNAME(fsp->conn,
696 talloc_tos(),
697 smb_fname,
698 &parent_dir_fname,
699 &smb_fname_rel);
700 if (!NT_STATUS_IS_OK(status)) {
701 goto out;
705 if (!ISDOT(parent_dir_fname->base_name)) {
706 oldwd_fname = vfs_GetWd(talloc_tos(), conn);
707 if (oldwd_fname == NULL) {
708 status = map_nt_error_from_unix(errno);
709 goto out;
712 /* Pin parent directory in place. */
713 if (vfs_ChDir(conn, parent_dir_fname) == -1) {
714 status = map_nt_error_from_unix(errno);
715 goto out;
719 /* Ensure the relative path is below the share. */
720 status = check_reduced_name(conn, parent_dir_fname, smb_fname_rel);
721 if (!NT_STATUS_IS_OK(status)) {
722 goto out;
725 /* Setup fsp->fsp_name to be relative to cwd */
726 fsp->fsp_name = smb_fname_rel;
728 /* Also setup base_fsp to be relative to the new cwd */
729 if (fsp->base_fsp != NULL) {
730 struct smb_filename *base_smb_fname_rel = NULL;
732 /* Check the invarient is true. */
733 SMB_ASSERT(fsp->base_fsp->fsp_name->fsp ==
734 fsp->base_fsp);
736 base_smb_fname_rel = synthetic_smb_fname(
737 talloc_tos(),
738 smb_fname_rel->base_name,
739 NULL,
740 &smb_fname_rel->st,
741 smb_fname_rel->twrp,
742 smb_fname_rel->flags);
743 if (base_smb_fname_rel == NULL) {
744 status = NT_STATUS_NO_MEMORY;
745 goto out;
748 base_smb_fname_rel->fsp = fsp->base_fsp;
750 orig_base_fsp_name = fsp->base_fsp->fsp_name;
751 fsp->base_fsp->fsp_name = base_smb_fname_rel;
754 * We should have preserved the invarient
755 * fsp->base_fsp->fsp_name->fsp == fsp->base_fsp.
757 SMB_ASSERT(fsp->base_fsp->fsp_name->fsp ==
758 fsp->base_fsp);
760 } else {
762 * fsp->fsp_name is unchanged as it is already correctly
763 * relative to conn->cwd.
765 smb_fname_rel = smb_fname;
768 flags |= O_NOFOLLOW;
770 fd = SMB_VFS_OPENAT(conn,
771 dirfsp,
772 smb_fname_rel,
773 fsp,
774 flags,
775 mode);
776 if (fd == -1) {
777 status = link_errno_convert(errno);
779 fsp_set_fd(fsp, fd);
781 if (fd != -1) {
782 ret = SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st);
783 if (ret != 0) {
784 status = map_nt_error_from_unix(errno);
785 goto out;
787 orig_fsp_name->st = fsp->fsp_name->st;
790 if (!is_ntfs_stream_smb_fname(fsp->fsp_name) &&
791 fsp->fsp_flags.is_pathref &&
792 have_opath)
795 * Opening with O_PATH and O_NOFOLLOW opens a handle on the
796 * symlink. In follow symlink=yes mode we must avoid this and
797 * instead should open a handle on the symlink target.
799 * Check for this case by doing an fstat, forcing
800 * process_symlink_open() codepath down below by setting fd=-1
801 * and errno=ELOOP.
803 if (S_ISLNK(fsp->fsp_name->st.st_ex_mode)) {
804 ret = SMB_VFS_CLOSE(fsp);
805 SMB_ASSERT(ret == 0);
807 fsp_set_fd(fsp, -1);
808 fd = -1;
809 status = NT_STATUS_STOPPED_ON_SYMLINK;
813 if ((fd == -1) &&
814 (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK) ||
815 NT_STATUS_EQUAL(status, NT_STATUS_NOT_A_DIRECTORY)))
818 * Trying to open a symlink to a directory with O_NOFOLLOW and
819 * O_DIRECTORY can return either of ELOOP and ENOTDIR. So
820 * ENOTDIR really means: might be a symlink, but we're not sure.
821 * In this case, we just assume there's a symlink. If we were
822 * wrong, process_symlink_open() will return EINVAL. We check
823 * this below, and fall back to returning the initial
824 * saved_errno.
826 * BUG: https://bugzilla.samba.org/show_bug.cgi?id=12860
828 saved_status = status;
830 if (fsp->fsp_name->flags & SMB_FILENAME_POSIX_PATH) {
831 /* Never follow symlinks on posix open. */
832 goto out;
834 if (!lp_follow_symlinks(SNUM(conn))) {
835 /* Explicitly no symlinks. */
836 goto out;
839 fsp->fsp_name = orig_fsp_name;
842 * We may have a symlink. Follow in userspace
843 * to ensure it's under the share definition.
845 status = process_symlink_open(dirfsp,
846 fsp,
847 smb_fname_rel,
848 flags,
849 mode,
850 link_depth);
851 if (NT_STATUS_EQUAL(status, NT_STATUS_INVALID_PARAMETER) &&
852 NT_STATUS_EQUAL(saved_status, NT_STATUS_NOT_A_DIRECTORY))
854 status = saved_status;
858 out:
859 fsp->fsp_name = orig_fsp_name;
860 if (fsp->base_fsp != NULL) {
861 /* Save off the temporary name. */
862 struct smb_filename *base_smb_fname_rel =
863 fsp->base_fsp->fsp_name;
864 /* It no longer has an associated fsp. */
865 base_smb_fname_rel->fsp = NULL;
867 /* Replace the original name. */
868 fsp->base_fsp->fsp_name = orig_base_fsp_name;
870 * We should have preserved the invarient
871 * fsp->base_fsp->fsp_name->fsp == fsp->base_fsp.
873 SMB_ASSERT(fsp->base_fsp->fsp_name->fsp == fsp->base_fsp);
874 TALLOC_FREE(base_smb_fname_rel);
876 TALLOC_FREE(parent_dir_fname);
878 if (oldwd_fname != NULL) {
879 ret = vfs_ChDir(conn, oldwd_fname);
880 if (ret == -1) {
881 smb_panic("unable to get back to old directory\n");
883 TALLOC_FREE(oldwd_fname);
885 return status;
888 /****************************************************************************
889 fd support routines - attempt to do a dos_open.
890 ****************************************************************************/
892 NTSTATUS fd_openat(const struct files_struct *dirfsp,
893 struct smb_filename *smb_fname,
894 files_struct *fsp,
895 int flags,
896 mode_t mode)
898 struct connection_struct *conn = fsp->conn;
899 NTSTATUS status = NT_STATUS_OK;
902 * Never follow symlinks on a POSIX client. The
903 * client should be doing this.
906 if ((fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) || !lp_follow_symlinks(SNUM(conn))) {
907 flags |= O_NOFOLLOW;
911 * Only follow symlinks within a share
912 * definition.
914 status = non_widelink_open(dirfsp, fsp, smb_fname, flags, mode, 0);
915 if (!NT_STATUS_IS_OK(status)) {
916 if (NT_STATUS_EQUAL(status, NT_STATUS_TOO_MANY_OPENED_FILES)) {
917 static time_t last_warned = 0L;
919 if (time((time_t *) NULL) > last_warned) {
920 DEBUG(0,("Too many open files, unable "
921 "to open more! smbd's max "
922 "open files = %d\n",
923 lp_max_open_files()));
924 last_warned = time((time_t *) NULL);
928 DBG_DEBUG("name %s, flags = 0%o mode = 0%o, fd = %d. %s\n",
929 smb_fname_str_dbg(smb_fname), flags, (int)mode,
930 fsp_get_pathref_fd(fsp), nt_errstr(status));
931 return status;
934 DBG_DEBUG("name %s, flags = 0%o mode = 0%o, fd = %d\n",
935 smb_fname_str_dbg(smb_fname), flags, (int)mode,
936 fsp_get_pathref_fd(fsp));
938 return status;
941 /****************************************************************************
942 Close the file associated with a fsp.
943 ****************************************************************************/
945 NTSTATUS fd_close(files_struct *fsp)
947 int ret;
949 if (fsp == fsp->conn->cwd_fsp) {
950 return NT_STATUS_OK;
953 if (fsp->dptr) {
954 dptr_CloseDir(fsp);
956 if (fsp_get_pathref_fd(fsp) == -1) {
958 * Either a directory where the dptr_CloseDir() already closed
959 * the fd or a stat open.
961 return NT_STATUS_OK;
963 if (fh_get_refcount(fsp->fh) > 1) {
964 return NT_STATUS_OK; /* Shared handle. Only close last reference. */
967 ret = SMB_VFS_CLOSE(fsp);
968 fsp_set_fd(fsp, -1);
969 if (ret == -1) {
970 return map_nt_error_from_unix(errno);
972 return NT_STATUS_OK;
975 /****************************************************************************
976 Change the ownership of a file to that of the parent directory.
977 Do this by fd if possible.
978 ****************************************************************************/
980 static void change_file_owner_to_parent_fsp(struct files_struct *parent_fsp,
981 struct files_struct *fsp)
983 int ret;
985 if (parent_fsp->fsp_name->st.st_ex_uid == fsp->fsp_name->st.st_ex_uid) {
986 /* Already this uid - no need to change. */
987 DBG_DEBUG("file %s is already owned by uid %u\n",
988 fsp_str_dbg(fsp),
989 (unsigned int)fsp->fsp_name->st.st_ex_uid);
990 return;
993 become_root();
994 ret = SMB_VFS_FCHOWN(fsp,
995 parent_fsp->fsp_name->st.st_ex_uid,
996 (gid_t)-1);
997 unbecome_root();
998 if (ret == -1) {
999 DBG_ERR("failed to fchown "
1000 "file %s to parent directory uid %u. Error "
1001 "was %s\n",
1002 fsp_str_dbg(fsp),
1003 (unsigned int)parent_fsp->fsp_name->st.st_ex_uid,
1004 strerror(errno));
1005 } else {
1006 DBG_DEBUG("changed new file %s to "
1007 "parent directory uid %u.\n",
1008 fsp_str_dbg(fsp),
1009 (unsigned int)parent_fsp->fsp_name->st.st_ex_uid);
1010 /* Ensure the uid entry is updated. */
1011 fsp->fsp_name->st.st_ex_uid =
1012 parent_fsp->fsp_name->st.st_ex_uid;
1016 static NTSTATUS change_dir_owner_to_parent_fsp(struct files_struct *parent_fsp,
1017 struct files_struct *fsp)
1019 NTSTATUS status;
1020 int ret;
1022 if (parent_fsp->fsp_name->st.st_ex_uid == fsp->fsp_name->st.st_ex_uid) {
1023 /* Already this uid - no need to change. */
1024 DBG_DEBUG("directory %s is already owned by uid %u\n",
1025 fsp_str_dbg(fsp),
1026 (unsigned int)fsp->fsp_name->st.st_ex_uid);
1027 return NT_STATUS_OK;
1030 become_root();
1031 ret = SMB_VFS_FCHOWN(fsp,
1032 parent_fsp->fsp_name->st.st_ex_uid,
1033 (gid_t)-1);
1034 unbecome_root();
1035 if (ret == -1) {
1036 status = map_nt_error_from_unix(errno);
1037 DBG_ERR("failed to chown "
1038 "directory %s to parent directory uid %u. "
1039 "Error was %s\n",
1040 fsp_str_dbg(fsp),
1041 (unsigned int)parent_fsp->fsp_name->st.st_ex_uid,
1042 nt_errstr(status));
1043 return status;
1046 DBG_DEBUG("changed ownership of new "
1047 "directory %s to parent directory uid %u.\n",
1048 fsp_str_dbg(fsp),
1049 (unsigned int)parent_fsp->fsp_name->st.st_ex_uid);
1051 /* Ensure the uid entry is updated. */
1052 fsp->fsp_name->st.st_ex_uid = parent_fsp->fsp_name->st.st_ex_uid;
1054 return NT_STATUS_OK;
1057 /****************************************************************************
1058 Open a file - returning a guaranteed ATOMIC indication of if the
1059 file was created or not.
1060 ****************************************************************************/
1062 static NTSTATUS fd_open_atomic(files_struct *fsp,
1063 int flags,
1064 mode_t mode,
1065 bool *file_created)
1067 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
1068 NTSTATUS retry_status;
1069 bool file_existed = VALID_STAT(fsp->fsp_name->st);
1070 int curr_flags;
1072 if (!(flags & O_CREAT)) {
1074 * We're not creating the file, just pass through.
1076 status = fd_openat(fsp->conn->cwd_fsp, fsp->fsp_name, fsp, flags, mode);
1077 *file_created = false;
1078 return status;
1081 if (flags & O_EXCL) {
1083 * Fail if already exists, just pass through.
1085 status = fd_openat(fsp->conn->cwd_fsp, fsp->fsp_name, fsp, flags, mode);
1088 * Here we've opened with O_CREAT|O_EXCL. If that went
1089 * NT_STATUS_OK, we *know* we created this file.
1091 *file_created = NT_STATUS_IS_OK(status);
1093 return status;
1097 * Now it gets tricky. We have O_CREAT, but not O_EXCL.
1098 * To know absolutely if we created the file or not,
1099 * we can never call O_CREAT without O_EXCL. So if
1100 * we think the file existed, try without O_CREAT|O_EXCL.
1101 * If we think the file didn't exist, try with
1102 * O_CREAT|O_EXCL.
1104 * The big problem here is dangling symlinks. Opening
1105 * without O_NOFOLLOW means both bad symlink
1106 * and missing path return -1, ENOENT from open(). As POSIX
1107 * is pathname based it's not possible to tell
1108 * the difference between these two cases in a
1109 * non-racy way, so change to try only two attempts before
1110 * giving up.
1112 * We don't have this problem for the O_NOFOLLOW
1113 * case as it just returns NT_STATUS_OBJECT_PATH_NOT_FOUND
1114 * mapped from the ELOOP POSIX error.
1117 if (file_existed) {
1118 curr_flags = flags & ~(O_CREAT);
1119 retry_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
1120 } else {
1121 curr_flags = flags | O_EXCL;
1122 retry_status = NT_STATUS_OBJECT_NAME_COLLISION;
1125 status = fd_openat(fsp->conn->cwd_fsp, fsp->fsp_name, fsp, curr_flags, mode);
1126 if (NT_STATUS_IS_OK(status)) {
1127 *file_created = !file_existed;
1128 return NT_STATUS_OK;
1130 if (NT_STATUS_EQUAL(status, retry_status)) {
1132 file_existed = !file_existed;
1134 DBG_DEBUG("File %s %s. Retry.\n",
1135 fsp_str_dbg(fsp),
1136 file_existed ? "existed" : "did not exist");
1138 if (file_existed) {
1139 curr_flags = flags & ~(O_CREAT);
1140 } else {
1141 curr_flags = flags | O_EXCL;
1144 status = fd_openat(fsp->conn->cwd_fsp, fsp->fsp_name, fsp, curr_flags, mode);
1147 *file_created = (NT_STATUS_IS_OK(status) && !file_existed);
1148 return status;
1151 static NTSTATUS reopen_from_procfd(struct files_struct *fsp,
1152 int flags,
1153 mode_t mode)
1155 struct smb_filename proc_fname;
1156 const char *p = NULL;
1157 char buf[PATH_MAX];
1158 int old_fd;
1159 int new_fd;
1160 NTSTATUS status;
1161 int ret;
1163 if (!fsp->fsp_flags.have_proc_fds) {
1164 return NT_STATUS_MORE_PROCESSING_REQUIRED;
1167 old_fd = fsp_get_pathref_fd(fsp);
1168 if (old_fd == -1) {
1169 return NT_STATUS_MORE_PROCESSING_REQUIRED;
1172 if (!fsp->fsp_flags.is_pathref) {
1173 DBG_ERR("[%s] is not a pathref\n",
1174 fsp_str_dbg(fsp));
1175 #ifdef DEVELOPER
1176 smb_panic("Not a pathref");
1177 #endif
1178 return NT_STATUS_INVALID_HANDLE;
1181 p = sys_proc_fd_path(old_fd, buf, sizeof(buf));
1182 if (p == NULL) {
1183 return NT_STATUS_NO_MEMORY;
1186 proc_fname = (struct smb_filename) {
1187 .base_name = discard_const_p(char, p),
1190 fsp->fsp_flags.is_pathref = false;
1192 new_fd = SMB_VFS_OPENAT(fsp->conn,
1193 fsp->conn->cwd_fsp,
1194 &proc_fname,
1195 fsp,
1196 flags,
1197 mode);
1198 if (new_fd == -1) {
1199 status = map_nt_error_from_unix(errno);
1200 SMB_VFS_CLOSE(fsp);
1201 fsp_set_fd(fsp, -1);
1202 return status;
1205 ret = SMB_VFS_CLOSE(fsp);
1206 fsp_set_fd(fsp, -1);
1207 if (ret != 0) {
1208 return map_nt_error_from_unix(errno);
1211 fsp_set_fd(fsp, new_fd);
1212 return NT_STATUS_OK;
1215 static NTSTATUS reopen_from_fsp(struct files_struct *fsp,
1216 int flags,
1217 mode_t mode,
1218 bool *p_file_created)
1220 bool __unused_file_created = false;
1221 NTSTATUS status;
1223 if (p_file_created == NULL) {
1224 p_file_created = &__unused_file_created;
1228 * TODO: should we move this to the VFS layer?
1229 * SMB_VFS_REOPEN_FSP()?
1232 status = reopen_from_procfd(fsp,
1233 flags,
1234 mode);
1235 if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
1237 * Close the existing pathref fd and set the fsp flag
1238 * is_pathref to false so we get a "normal" fd this
1239 * time.
1241 status = fd_close(fsp);
1242 if (!NT_STATUS_IS_OK(status)) {
1243 return status;
1246 fsp->fsp_flags.is_pathref = false;
1248 status = fd_open_atomic(fsp,
1249 flags,
1250 mode,
1251 p_file_created);
1254 return status;
1257 /****************************************************************************
1258 Open a file.
1259 ****************************************************************************/
1261 static NTSTATUS open_file(files_struct *fsp,
1262 struct smb_request *req,
1263 struct smb_filename *parent_dir,
1264 int flags,
1265 mode_t unx_mode,
1266 uint32_t access_mask, /* client requested access mask. */
1267 uint32_t open_access_mask, /* what we're actually using in the open. */
1268 uint32_t private_flags,
1269 bool *p_file_created)
1271 connection_struct *conn = fsp->conn;
1272 struct smb_filename *smb_fname = fsp->fsp_name;
1273 NTSTATUS status = NT_STATUS_OK;
1274 int accmode = (flags & O_ACCMODE);
1275 int local_flags = flags;
1276 bool file_existed = VALID_STAT(fsp->fsp_name->st);
1277 uint32_t need_fd_mask =
1278 FILE_READ_DATA |
1279 FILE_WRITE_DATA |
1280 FILE_APPEND_DATA |
1281 FILE_EXECUTE |
1282 SEC_FLAG_SYSTEM_SECURITY;
1283 bool creating = !file_existed && (flags & O_CREAT);
1284 bool truncating = (flags & O_TRUNC);
1285 bool open_fd = false;
1288 * Catch early an attempt to open an existing
1289 * directory as a file.
1291 if (file_existed && S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
1292 return NT_STATUS_FILE_IS_A_DIRECTORY;
1295 /* Check permissions */
1298 * This code was changed after seeing a client open request
1299 * containing the open mode of (DENY_WRITE/read-only) with
1300 * the 'create if not exist' bit set. The previous code
1301 * would fail to open the file read only on a read-only share
1302 * as it was checking the flags parameter directly against O_RDONLY,
1303 * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
1304 * JRA.
1307 if (!CAN_WRITE(conn)) {
1308 /* It's a read-only share - fail if we wanted to write. */
1309 if(accmode != O_RDONLY || (flags & O_TRUNC) || (flags & O_APPEND)) {
1310 DEBUG(3,("Permission denied opening %s\n",
1311 smb_fname_str_dbg(smb_fname)));
1312 return NT_STATUS_ACCESS_DENIED;
1314 if (flags & O_CREAT) {
1315 /* We don't want to write - but we must make sure that
1316 O_CREAT doesn't create the file if we have write
1317 access into the directory.
1319 flags &= ~(O_CREAT|O_EXCL);
1320 local_flags &= ~(O_CREAT|O_EXCL);
1325 * This little piece of insanity is inspired by the
1326 * fact that an NT client can open a file for O_RDONLY,
1327 * but set the create disposition to FILE_EXISTS_TRUNCATE.
1328 * If the client *can* write to the file, then it expects to
1329 * truncate the file, even though it is opening for readonly.
1330 * Quicken uses this stupid trick in backup file creation...
1331 * Thanks *greatly* to "David W. Chapman Jr." <dwcjr@inethouston.net>
1332 * for helping track this one down. It didn't bite us in 2.0.x
1333 * as we always opened files read-write in that release. JRA.
1336 if ((accmode == O_RDONLY) && ((flags & O_TRUNC) == O_TRUNC)) {
1337 DEBUG(10,("open_file: truncate requested on read-only open "
1338 "for file %s\n", smb_fname_str_dbg(smb_fname)));
1339 local_flags = (flags & ~O_ACCMODE)|O_RDWR;
1342 if ((open_access_mask & need_fd_mask) || creating || truncating) {
1343 open_fd = true;
1346 if (open_fd) {
1347 const char *wild;
1348 int ret;
1350 #if defined(O_NONBLOCK) && defined(S_ISFIFO)
1352 * We would block on opening a FIFO with no one else on the
1353 * other end. Do what we used to do and add O_NONBLOCK to the
1354 * open flags. JRA.
1357 if (file_existed && S_ISFIFO(smb_fname->st.st_ex_mode)) {
1358 local_flags &= ~O_TRUNC; /* Can't truncate a FIFO. */
1359 local_flags |= O_NONBLOCK;
1360 truncating = false;
1362 #endif
1364 /* Don't create files with Microsoft wildcard characters. */
1365 if (fsp->base_fsp) {
1367 * wildcard characters are allowed in stream names
1368 * only test the basefilename
1370 wild = fsp->base_fsp->fsp_name->base_name;
1371 } else {
1372 wild = smb_fname->base_name;
1374 if ((local_flags & O_CREAT) && !file_existed &&
1375 !(fsp->posix_flags & FSP_POSIX_FLAGS_PATHNAMES) &&
1376 ms_has_wild(wild)) {
1377 return NT_STATUS_OBJECT_NAME_INVALID;
1380 /* Can we access this file ? */
1381 if (!fsp->base_fsp) {
1382 /* Only do this check on non-stream open. */
1383 if (file_existed) {
1384 status = smbd_check_access_rights_fsp(
1385 parent_dir->fsp,
1386 fsp,
1387 false,
1388 access_mask);
1390 if (!NT_STATUS_IS_OK(status)) {
1391 DBG_DEBUG("smbd_check_access_rights_fsp"
1392 " on file %s returned %s\n",
1393 fsp_str_dbg(fsp),
1394 nt_errstr(status));
1397 if (!NT_STATUS_IS_OK(status) &&
1398 !NT_STATUS_EQUAL(status,
1399 NT_STATUS_OBJECT_NAME_NOT_FOUND))
1401 return status;
1404 if (NT_STATUS_EQUAL(status,
1405 NT_STATUS_OBJECT_NAME_NOT_FOUND))
1407 DEBUG(10, ("open_file: "
1408 "file %s vanished since we "
1409 "checked for existence.\n",
1410 smb_fname_str_dbg(smb_fname)));
1411 file_existed = false;
1412 SET_STAT_INVALID(fsp->fsp_name->st);
1416 if (!file_existed) {
1417 if (!(local_flags & O_CREAT)) {
1418 /* File didn't exist and no O_CREAT. */
1419 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1422 status = check_parent_access_fsp(
1423 parent_dir->fsp,
1424 SEC_DIR_ADD_FILE);
1425 if (!NT_STATUS_IS_OK(status)) {
1426 DBG_DEBUG("check_parent_access_fsp on "
1427 "directory %s for file %s "
1428 "returned %s\n",
1429 smb_fname_str_dbg(parent_dir),
1430 smb_fname_str_dbg(smb_fname),
1431 nt_errstr(status));
1432 return status;
1438 * Actually do the open - if O_TRUNC is needed handle it
1439 * below under the share mode lock.
1441 status = reopen_from_fsp(fsp,
1442 local_flags & ~O_TRUNC,
1443 unx_mode,
1444 p_file_created);
1445 if (NT_STATUS_EQUAL(status, NT_STATUS_STOPPED_ON_SYMLINK)) {
1447 * POSIX client that hit a symlink. We don't want to
1448 * return NT_STATUS_STOPPED_ON_SYMLINK to avoid handling
1449 * this special error code in all callers, so we map
1450 * this to NT_STATUS_OBJECT_PATH_NOT_FOUND. Historically
1451 * the lower level functions returned status code mapped
1452 * from errno by map_nt_error_from_unix() where ELOOP is
1453 * mapped to NT_STATUS_OBJECT_PATH_NOT_FOUND.
1455 status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
1457 if (!NT_STATUS_IS_OK(status)) {
1458 DEBUG(3,("Error opening file %s (%s) (local_flags=%d) "
1459 "(flags=%d)\n", smb_fname_str_dbg(smb_fname),
1460 nt_errstr(status),local_flags,flags));
1461 return status;
1464 if (local_flags & O_NONBLOCK) {
1466 * GPFS can return ETIMEDOUT for pread on
1467 * nonblocking file descriptors when files
1468 * migrated to tape need to be recalled. I
1469 * could imagine this happens elsewhere
1470 * too. With blocking file descriptors this
1471 * does not happen.
1473 ret = vfs_set_blocking(fsp, true);
1474 if (ret == -1) {
1475 status = map_nt_error_from_unix(errno);
1476 DBG_WARNING("Could not set fd to blocking: "
1477 "%s\n", strerror(errno));
1478 fd_close(fsp);
1479 return status;
1483 if (*p_file_created) {
1484 /* We created this file. */
1486 bool need_re_stat = false;
1487 /* Do all inheritance work after we've
1488 done a successful fstat call and filled
1489 in the stat struct in fsp->fsp_name. */
1491 /* Inherit the ACL if required */
1492 if (lp_inherit_permissions(SNUM(conn))) {
1493 inherit_access_posix_acl(conn,
1494 parent_dir,
1495 smb_fname,
1496 unx_mode);
1497 need_re_stat = true;
1500 /* Change the owner if required. */
1501 if (lp_inherit_owner(SNUM(conn)) != INHERIT_OWNER_NO) {
1502 change_file_owner_to_parent_fsp(parent_dir->fsp,
1503 fsp);
1504 need_re_stat = true;
1507 if (need_re_stat) {
1508 ret = SMB_VFS_FSTAT(fsp, &smb_fname->st);
1510 * If we have an fd, this stat should succeed.
1512 if (ret == -1) {
1513 status = map_nt_error_from_unix(errno);
1514 DBG_ERR("Error doing fstat on open "
1515 "file %s (%s)\n",
1516 smb_fname_str_dbg(smb_fname),
1517 nt_errstr(status));
1518 fd_close(fsp);
1519 return status;
1523 notify_fname(conn, NOTIFY_ACTION_ADDED,
1524 FILE_NOTIFY_CHANGE_FILE_NAME,
1525 smb_fname->base_name);
1527 } else {
1528 if (!file_existed) {
1529 /* File must exist for a stat open. */
1530 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1533 if (S_ISLNK(smb_fname->st.st_ex_mode) &&
1534 !(fsp->posix_flags & FSP_POSIX_FLAGS_OPEN))
1537 * Don't allow stat opens on symlinks directly unless
1538 * it's a POSIX open.
1540 return NT_STATUS_OBJECT_PATH_NOT_FOUND;
1543 if (!fsp->fsp_flags.is_pathref) {
1545 * There is only one legit case where end up here:
1546 * openat_pathref_fsp() failed to open a symlink, so the
1547 * fsp was created by fsp_new() which doesn't set
1548 * is_pathref. Other then that, we should always have a
1549 * pathref fsp at this point. The subsequent checks
1550 * assert this.
1552 if (!(smb_fname->flags & SMB_FILENAME_POSIX_PATH)) {
1553 DBG_ERR("[%s] is not a POSIX pathname\n",
1554 smb_fname_str_dbg(smb_fname));
1555 return NT_STATUS_INTERNAL_ERROR;
1557 if (!S_ISLNK(smb_fname->st.st_ex_mode)) {
1558 DBG_ERR("[%s] is not a symlink\n",
1559 smb_fname_str_dbg(smb_fname));
1560 return NT_STATUS_INTERNAL_ERROR;
1562 if (fsp_get_pathref_fd(fsp) != -1) {
1563 DBG_ERR("fd for [%s] is not -1: fd [%d]\n",
1564 smb_fname_str_dbg(smb_fname),
1565 fsp_get_pathref_fd(fsp));
1566 return NT_STATUS_INTERNAL_ERROR;
1570 status = smbd_check_access_rights_fsp(parent_dir->fsp,
1571 fsp,
1572 false,
1573 access_mask);
1575 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) &&
1576 (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) &&
1577 S_ISLNK(smb_fname->st.st_ex_mode)) {
1578 /* This is a POSIX stat open for delete
1579 * or rename on a symlink that points
1580 * nowhere. Allow. */
1581 DEBUG(10,("open_file: allowing POSIX "
1582 "open on bad symlink %s\n",
1583 smb_fname_str_dbg(smb_fname)));
1584 status = NT_STATUS_OK;
1587 if (!NT_STATUS_IS_OK(status)) {
1588 DBG_DEBUG("smbd_check_access_rights_fsp on file "
1589 "%s returned %s\n",
1590 fsp_str_dbg(fsp),
1591 nt_errstr(status));
1592 return status;
1596 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
1597 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
1598 fsp->file_pid = req ? req->smbpid : 0;
1599 fsp->fsp_flags.can_lock = true;
1600 fsp->fsp_flags.can_read = ((access_mask & FILE_READ_DATA) != 0);
1601 fsp->fsp_flags.can_write =
1602 CAN_WRITE(conn) &&
1603 ((access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) != 0);
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 (conn->aio_write_behind_list &&
1609 is_in_path(smb_fname->base_name, conn->aio_write_behind_list,
1610 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 DATA_BLOB blob;
2018 NTSTATUS status;
2020 if (DEBUGLVL(10)) {
2021 struct server_id_buf buf;
2022 DBG_DEBUG("Sending break message to %s\n",
2023 server_id_str_buf(exclusive->pid, &buf));
2024 NDR_PRINT_DEBUG(oplock_break_message, &msg);
2027 ndr_err = ndr_push_struct_blob(
2028 &blob,
2029 talloc_tos(),
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(
2039 msg_ctx, exclusive->pid, MSG_SMB_BREAK_REQUEST, &blob);
2040 TALLOC_FREE(blob.data);
2041 if (!NT_STATUS_IS_OK(status)) {
2042 DEBUG(3, ("Could not send oplock break message: %s\n",
2043 nt_errstr(status)));
2046 return status;
2049 struct validate_oplock_types_state {
2050 bool valid;
2051 bool batch;
2052 bool ex_or_batch;
2053 bool level2;
2054 bool no_oplock;
2055 uint32_t num_non_stat_opens;
2058 static bool validate_oplock_types_fn(
2059 struct share_mode_entry *e,
2060 bool *modified,
2061 void *private_data)
2063 struct validate_oplock_types_state *state = private_data;
2065 if (e->op_mid == 0) {
2066 /* INTERNAL_OPEN_ONLY */
2067 return false;
2070 if (e->op_type == NO_OPLOCK && is_oplock_stat_open(e->access_mask)) {
2072 * We ignore stat opens in the table - they always
2073 * have NO_OPLOCK and never get or cause breaks. JRA.
2075 return false;
2078 state->num_non_stat_opens += 1;
2080 if (BATCH_OPLOCK_TYPE(e->op_type)) {
2081 /* batch - can only be one. */
2082 if (share_entry_stale_pid(e)) {
2083 DBG_DEBUG("Found stale batch oplock\n");
2084 return false;
2086 if (state->ex_or_batch ||
2087 state->batch ||
2088 state->level2 ||
2089 state->no_oplock) {
2090 DBG_ERR("Bad batch oplock entry\n");
2091 state->valid = false;
2092 return true;
2094 state->batch = true;
2097 if (EXCLUSIVE_OPLOCK_TYPE(e->op_type)) {
2098 if (share_entry_stale_pid(e)) {
2099 DBG_DEBUG("Found stale duplicate oplock\n");
2100 return false;
2102 /* Exclusive or batch - can only be one. */
2103 if (state->ex_or_batch ||
2104 state->level2 ||
2105 state->no_oplock) {
2106 DBG_ERR("Bad exclusive or batch oplock entry\n");
2107 state->valid = false;
2108 return true;
2110 state->ex_or_batch = true;
2113 if (LEVEL_II_OPLOCK_TYPE(e->op_type)) {
2114 if (state->batch || state->ex_or_batch) {
2115 if (share_entry_stale_pid(e)) {
2116 DBG_DEBUG("Found stale LevelII oplock\n");
2117 return false;
2119 DBG_DEBUG("Bad levelII oplock entry\n");
2120 state->valid = false;
2121 return true;
2123 state->level2 = true;
2126 if (e->op_type == NO_OPLOCK) {
2127 if (state->batch || state->ex_or_batch) {
2128 if (share_entry_stale_pid(e)) {
2129 DBG_DEBUG("Found stale NO_OPLOCK entry\n");
2130 return false;
2132 DBG_ERR("Bad no oplock entry\n");
2133 state->valid = false;
2134 return true;
2136 state->no_oplock = true;
2139 return false;
2143 * Do internal consistency checks on the share mode for a file.
2146 static bool validate_oplock_types(struct share_mode_lock *lck)
2148 struct validate_oplock_types_state state = { .valid = true };
2149 bool ok;
2151 ok = share_mode_forall_entries(lck, validate_oplock_types_fn, &state);
2152 if (!ok) {
2153 DBG_DEBUG("share_mode_forall_entries failed\n");
2154 return false;
2156 if (!state.valid) {
2157 DBG_DEBUG("Got invalid oplock configuration\n");
2158 return false;
2161 if ((state.batch || state.ex_or_batch) &&
2162 (state.num_non_stat_opens != 1)) {
2163 DBG_WARNING("got batch (%d) or ex (%d) non-exclusively "
2164 "(%"PRIu32")\n",
2165 (int)state.batch,
2166 (int)state.ex_or_batch,
2167 state.num_non_stat_opens);
2168 return false;
2171 return true;
2174 static bool is_same_lease(const files_struct *fsp,
2175 const struct share_mode_entry *e,
2176 const struct smb2_lease *lease)
2178 if (e->op_type != LEASE_OPLOCK) {
2179 return false;
2181 if (lease == NULL) {
2182 return false;
2185 return smb2_lease_equal(fsp_client_guid(fsp),
2186 &lease->lease_key,
2187 &e->client_guid,
2188 &e->lease_key);
2191 static bool file_has_brlocks(files_struct *fsp)
2193 struct byte_range_lock *br_lck;
2195 br_lck = brl_get_locks_readonly(fsp);
2196 if (!br_lck)
2197 return false;
2199 return (brl_num_locks(br_lck) > 0);
2202 struct fsp_lease *find_fsp_lease(struct files_struct *new_fsp,
2203 const struct smb2_lease_key *key,
2204 uint32_t current_state,
2205 uint16_t lease_version,
2206 uint16_t lease_epoch)
2208 struct files_struct *fsp;
2211 * TODO: Measure how expensive this loop is with thousands of open
2212 * handles...
2215 for (fsp = file_find_di_first(new_fsp->conn->sconn, new_fsp->file_id, true);
2216 fsp != NULL;
2217 fsp = file_find_di_next(fsp, true)) {
2219 if (fsp == new_fsp) {
2220 continue;
2222 if (fsp->oplock_type != LEASE_OPLOCK) {
2223 continue;
2225 if (smb2_lease_key_equal(&fsp->lease->lease.lease_key, key)) {
2226 fsp->lease->ref_count += 1;
2227 return fsp->lease;
2231 /* Not found - must be leased in another smbd. */
2232 new_fsp->lease = talloc_zero(new_fsp->conn->sconn, struct fsp_lease);
2233 if (new_fsp->lease == NULL) {
2234 return NULL;
2236 new_fsp->lease->ref_count = 1;
2237 new_fsp->lease->sconn = new_fsp->conn->sconn;
2238 new_fsp->lease->lease.lease_key = *key;
2239 new_fsp->lease->lease.lease_state = current_state;
2241 * We internally treat all leases as V2 and update
2242 * the epoch, but when sending breaks it matters if
2243 * the requesting lease was v1 or v2.
2245 new_fsp->lease->lease.lease_version = lease_version;
2246 new_fsp->lease->lease.lease_epoch = lease_epoch;
2247 return new_fsp->lease;
2250 static NTSTATUS try_lease_upgrade(struct files_struct *fsp,
2251 struct share_mode_lock *lck,
2252 const struct GUID *client_guid,
2253 const struct smb2_lease *lease,
2254 uint32_t granted)
2256 bool do_upgrade;
2257 uint32_t current_state, breaking_to_requested, breaking_to_required;
2258 bool breaking;
2259 uint16_t lease_version, epoch;
2260 uint32_t existing, requested;
2261 NTSTATUS status;
2263 status = leases_db_get(
2264 client_guid,
2265 &lease->lease_key,
2266 &fsp->file_id,
2267 &current_state,
2268 &breaking,
2269 &breaking_to_requested,
2270 &breaking_to_required,
2271 &lease_version,
2272 &epoch);
2273 if (!NT_STATUS_IS_OK(status)) {
2274 return status;
2277 fsp->lease = find_fsp_lease(
2278 fsp,
2279 &lease->lease_key,
2280 current_state,
2281 lease_version,
2282 epoch);
2283 if (fsp->lease == NULL) {
2284 DEBUG(1, ("Did not find existing lease for file %s\n",
2285 fsp_str_dbg(fsp)));
2286 return NT_STATUS_NO_MEMORY;
2290 * Upgrade only if the requested lease is a strict upgrade.
2292 existing = current_state;
2293 requested = lease->lease_state;
2296 * Tricky: This test makes sure that "requested" is a
2297 * strict bitwise superset of "existing".
2299 do_upgrade = ((existing & requested) == existing);
2302 * Upgrade only if there's a change.
2304 do_upgrade &= (granted != existing);
2307 * Upgrade only if other leases don't prevent what was asked
2308 * for.
2310 do_upgrade &= (granted == requested);
2313 * only upgrade if we are not in breaking state
2315 do_upgrade &= !breaking;
2317 DEBUG(10, ("existing=%"PRIu32", requested=%"PRIu32", "
2318 "granted=%"PRIu32", do_upgrade=%d\n",
2319 existing, requested, granted, (int)do_upgrade));
2321 if (do_upgrade) {
2322 NTSTATUS set_status;
2324 current_state = granted;
2325 epoch += 1;
2327 set_status = leases_db_set(
2328 client_guid,
2329 &lease->lease_key,
2330 current_state,
2331 breaking,
2332 breaking_to_requested,
2333 breaking_to_required,
2334 lease_version,
2335 epoch);
2337 if (!NT_STATUS_IS_OK(set_status)) {
2338 DBG_DEBUG("leases_db_set failed: %s\n",
2339 nt_errstr(set_status));
2340 return set_status;
2344 fsp_lease_update(fsp);
2346 return NT_STATUS_OK;
2349 static NTSTATUS grant_new_fsp_lease(struct files_struct *fsp,
2350 struct share_mode_lock *lck,
2351 const struct GUID *client_guid,
2352 const struct smb2_lease *lease,
2353 uint32_t granted)
2355 NTSTATUS status;
2357 fsp->lease = talloc_zero(fsp->conn->sconn, struct fsp_lease);
2358 if (fsp->lease == NULL) {
2359 return NT_STATUS_INSUFFICIENT_RESOURCES;
2361 fsp->lease->ref_count = 1;
2362 fsp->lease->sconn = fsp->conn->sconn;
2363 fsp->lease->lease.lease_version = lease->lease_version;
2364 fsp->lease->lease.lease_key = lease->lease_key;
2365 fsp->lease->lease.lease_state = granted;
2366 fsp->lease->lease.lease_epoch = lease->lease_epoch + 1;
2368 status = leases_db_add(client_guid,
2369 &lease->lease_key,
2370 &fsp->file_id,
2371 fsp->lease->lease.lease_state,
2372 fsp->lease->lease.lease_version,
2373 fsp->lease->lease.lease_epoch,
2374 fsp->conn->connectpath,
2375 fsp->fsp_name->base_name,
2376 fsp->fsp_name->stream_name);
2377 if (!NT_STATUS_IS_OK(status)) {
2378 DEBUG(10, ("%s: leases_db_add failed: %s\n", __func__,
2379 nt_errstr(status)));
2380 TALLOC_FREE(fsp->lease);
2381 return NT_STATUS_INSUFFICIENT_RESOURCES;
2385 * We used to set lck->data->modified=true here without
2386 * actually modifying lck->data, triggering a needless
2387 * writeback of lck->data.
2389 * Apart from that writeback, setting modified=true has the
2390 * effect of triggering all waiters for this file to
2391 * retry. This only makes sense if any blocking condition
2392 * (i.e. waiting for a lease to be downgraded or removed) is
2393 * gone. This routine here only adds a lease, so it will never
2394 * free up resources that blocked waiters can now claim. So
2395 * that second effect also does not matter in this
2396 * routine. Thus setting lck->data->modified=true does not
2397 * need to be done here.
2400 return NT_STATUS_OK;
2403 static NTSTATUS grant_fsp_lease(struct files_struct *fsp,
2404 struct share_mode_lock *lck,
2405 const struct smb2_lease *lease,
2406 uint32_t granted)
2408 const struct GUID *client_guid = fsp_client_guid(fsp);
2409 NTSTATUS status;
2411 status = try_lease_upgrade(fsp, lck, client_guid, lease, granted);
2413 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
2414 status = grant_new_fsp_lease(
2415 fsp, lck, client_guid, lease, granted);
2418 return status;
2421 static int map_lease_type_to_oplock(uint32_t lease_type)
2423 int result = NO_OPLOCK;
2425 switch (lease_type) {
2426 case SMB2_LEASE_READ|SMB2_LEASE_WRITE|SMB2_LEASE_HANDLE:
2427 result = BATCH_OPLOCK|EXCLUSIVE_OPLOCK;
2428 break;
2429 case SMB2_LEASE_READ|SMB2_LEASE_WRITE:
2430 result = EXCLUSIVE_OPLOCK;
2431 break;
2432 case SMB2_LEASE_READ|SMB2_LEASE_HANDLE:
2433 case SMB2_LEASE_READ:
2434 result = LEVEL_II_OPLOCK;
2435 break;
2438 return result;
2441 struct delay_for_oplock_state {
2442 struct files_struct *fsp;
2443 const struct smb2_lease *lease;
2444 bool will_overwrite;
2445 uint32_t delay_mask;
2446 bool first_open_attempt;
2447 bool got_handle_lease;
2448 bool got_oplock;
2449 bool have_other_lease;
2450 bool delay;
2453 static bool delay_for_oplock_fn(
2454 struct share_mode_entry *e,
2455 bool *modified,
2456 void *private_data)
2458 struct delay_for_oplock_state *state = private_data;
2459 struct files_struct *fsp = state->fsp;
2460 const struct smb2_lease *lease = state->lease;
2461 bool e_is_lease = (e->op_type == LEASE_OPLOCK);
2462 uint32_t e_lease_type = get_lease_type(e, fsp->file_id);
2463 uint32_t break_to;
2464 bool lease_is_breaking = false;
2466 if (e_is_lease) {
2467 NTSTATUS status;
2469 if (lease != NULL) {
2470 bool our_lease = is_same_lease(fsp, e, lease);
2471 if (our_lease) {
2472 DBG_DEBUG("Ignoring our own lease\n");
2473 return false;
2477 status = leases_db_get(
2478 &e->client_guid,
2479 &e->lease_key,
2480 &fsp->file_id,
2481 NULL, /* current_state */
2482 &lease_is_breaking,
2483 NULL, /* breaking_to_requested */
2484 NULL, /* breaking_to_required */
2485 NULL, /* lease_version */
2486 NULL); /* epoch */
2489 * leases_db_get() can return NT_STATUS_NOT_FOUND
2490 * if the share_mode_entry e is stale and the
2491 * lease record was already removed. In this case return
2492 * false so the traverse continues.
2495 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND) &&
2496 share_entry_stale_pid(e))
2498 struct GUID_txt_buf guid_strbuf;
2499 struct file_id_buf file_id_strbuf;
2500 DBG_DEBUG("leases_db_get for client_guid [%s] "
2501 "lease_key [%"PRIu64"/%"PRIu64"] "
2502 "file_id [%s] failed for stale "
2503 "share_mode_entry\n",
2504 GUID_buf_string(&e->client_guid, &guid_strbuf),
2505 e->lease_key.data[0],
2506 e->lease_key.data[1],
2507 file_id_str_buf(fsp->file_id, &file_id_strbuf));
2508 return false;
2510 if (!NT_STATUS_IS_OK(status)) {
2511 struct GUID_txt_buf guid_strbuf;
2512 struct file_id_buf file_id_strbuf;
2513 DBG_ERR("leases_db_get for client_guid [%s] "
2514 "lease_key [%"PRIu64"/%"PRIu64"] "
2515 "file_id [%s] failed: %s\n",
2516 GUID_buf_string(&e->client_guid, &guid_strbuf),
2517 e->lease_key.data[0],
2518 e->lease_key.data[1],
2519 file_id_str_buf(fsp->file_id, &file_id_strbuf),
2520 nt_errstr(status));
2521 smb_panic("leases_db_get() failed");
2525 if (!state->got_handle_lease &&
2526 ((e_lease_type & SMB2_LEASE_HANDLE) != 0) &&
2527 !share_entry_stale_pid(e)) {
2528 state->got_handle_lease = true;
2531 if (!state->got_oplock &&
2532 (e->op_type != LEASE_OPLOCK) &&
2533 !share_entry_stale_pid(e)) {
2534 state->got_oplock = true;
2537 if (!state->have_other_lease &&
2538 !is_same_lease(fsp, e, lease) &&
2539 !share_entry_stale_pid(e)) {
2540 state->have_other_lease = true;
2543 if (e_is_lease && is_lease_stat_open(fsp->access_mask)) {
2544 return false;
2547 break_to = e_lease_type & ~state->delay_mask;
2549 if (state->will_overwrite) {
2550 break_to &= ~(SMB2_LEASE_HANDLE|SMB2_LEASE_READ);
2553 DBG_DEBUG("e_lease_type %u, will_overwrite: %u\n",
2554 (unsigned)e_lease_type,
2555 (unsigned)state->will_overwrite);
2557 if ((e_lease_type & ~break_to) == 0) {
2558 if (lease_is_breaking) {
2559 state->delay = true;
2561 return false;
2564 if (share_entry_stale_pid(e)) {
2565 return false;
2568 if (state->will_overwrite) {
2570 * If we break anyway break to NONE directly.
2571 * Otherwise vfs_set_filelen() will trigger the
2572 * break.
2574 break_to &= ~(SMB2_LEASE_READ|SMB2_LEASE_WRITE);
2577 if (!e_is_lease) {
2579 * Oplocks only support breaking to R or NONE.
2581 break_to &= ~(SMB2_LEASE_HANDLE|SMB2_LEASE_WRITE);
2584 DBG_DEBUG("breaking from %d to %d\n",
2585 (int)e_lease_type,
2586 (int)break_to);
2587 send_break_message(
2588 fsp->conn->sconn->msg_ctx, &fsp->file_id, e, break_to);
2589 if (e_lease_type & state->delay_mask) {
2590 state->delay = true;
2592 if (lease_is_breaking && !state->first_open_attempt) {
2593 state->delay = true;
2596 return false;
2599 static NTSTATUS delay_for_oplock(files_struct *fsp,
2600 int oplock_request,
2601 const struct smb2_lease *lease,
2602 struct share_mode_lock *lck,
2603 bool have_sharing_violation,
2604 uint32_t create_disposition,
2605 bool first_open_attempt)
2607 struct delay_for_oplock_state state = {
2608 .fsp = fsp,
2609 .lease = lease,
2610 .first_open_attempt = first_open_attempt,
2612 uint32_t granted;
2613 NTSTATUS status;
2614 bool ok;
2616 if (is_oplock_stat_open(fsp->access_mask)) {
2617 goto grant;
2620 state.delay_mask = have_sharing_violation ?
2621 SMB2_LEASE_HANDLE : SMB2_LEASE_WRITE;
2623 switch (create_disposition) {
2624 case FILE_SUPERSEDE:
2625 case FILE_OVERWRITE:
2626 case FILE_OVERWRITE_IF:
2627 state.will_overwrite = true;
2628 break;
2629 default:
2630 state.will_overwrite = false;
2631 break;
2634 ok = share_mode_forall_entries(lck, delay_for_oplock_fn, &state);
2635 if (!ok) {
2636 return NT_STATUS_INTERNAL_ERROR;
2639 if (state.delay) {
2640 return NT_STATUS_RETRY;
2643 grant:
2644 if (have_sharing_violation) {
2645 return NT_STATUS_SHARING_VIOLATION;
2648 if (oplock_request == LEASE_OPLOCK) {
2649 if (lease == NULL) {
2651 * The SMB2 layer should have checked this
2653 return NT_STATUS_INTERNAL_ERROR;
2656 granted = lease->lease_state;
2658 if (lp_kernel_oplocks(SNUM(fsp->conn))) {
2659 DEBUG(10, ("No lease granted because kernel oplocks are enabled\n"));
2660 granted = SMB2_LEASE_NONE;
2662 if ((granted & (SMB2_LEASE_READ|SMB2_LEASE_WRITE)) == 0) {
2663 DEBUG(10, ("No read or write lease requested\n"));
2664 granted = SMB2_LEASE_NONE;
2666 if (granted == SMB2_LEASE_WRITE) {
2667 DEBUG(10, ("pure write lease requested\n"));
2668 granted = SMB2_LEASE_NONE;
2670 if (granted == (SMB2_LEASE_WRITE|SMB2_LEASE_HANDLE)) {
2671 DEBUG(10, ("write and handle lease requested\n"));
2672 granted = SMB2_LEASE_NONE;
2674 } else {
2675 granted = map_oplock_to_lease_type(
2676 oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK);
2679 if (lp_locking(fsp->conn->params) && file_has_brlocks(fsp)) {
2680 DBG_DEBUG("file %s has byte range locks\n",
2681 fsp_str_dbg(fsp));
2682 granted &= ~SMB2_LEASE_READ;
2685 if (state.have_other_lease) {
2687 * Can grant only one writer
2689 granted &= ~SMB2_LEASE_WRITE;
2692 if ((granted & SMB2_LEASE_READ) && !(granted & SMB2_LEASE_WRITE)) {
2693 bool allow_level2 =
2694 (global_client_caps & CAP_LEVEL_II_OPLOCKS) &&
2695 lp_level2_oplocks(SNUM(fsp->conn));
2697 if (!allow_level2) {
2698 granted = SMB2_LEASE_NONE;
2702 if (oplock_request == LEASE_OPLOCK) {
2703 if (state.got_oplock) {
2704 granted &= ~SMB2_LEASE_HANDLE;
2707 fsp->oplock_type = LEASE_OPLOCK;
2709 status = grant_fsp_lease(fsp, lck, lease, granted);
2710 if (!NT_STATUS_IS_OK(status)) {
2711 return status;
2715 DBG_DEBUG("lease_state=%d\n", fsp->lease->lease.lease_state);
2716 } else {
2717 if (state.got_handle_lease) {
2718 granted = SMB2_LEASE_NONE;
2721 fsp->oplock_type = map_lease_type_to_oplock(granted);
2723 status = set_file_oplock(fsp);
2724 if (!NT_STATUS_IS_OK(status)) {
2726 * Could not get the kernel oplock
2728 fsp->oplock_type = NO_OPLOCK;
2732 if (granted & SMB2_LEASE_READ) {
2733 uint32_t acc, sh, ls;
2734 share_mode_flags_get(lck, &acc, &sh, &ls);
2735 ls |= SHARE_MODE_LEASE_READ;
2736 share_mode_flags_set(lck, acc, sh, ls, NULL);
2739 DBG_DEBUG("oplock type 0x%x on file %s\n",
2740 fsp->oplock_type, fsp_str_dbg(fsp));
2742 return NT_STATUS_OK;
2745 static NTSTATUS handle_share_mode_lease(
2746 files_struct *fsp,
2747 struct share_mode_lock *lck,
2748 uint32_t create_disposition,
2749 uint32_t access_mask,
2750 uint32_t share_access,
2751 int oplock_request,
2752 const struct smb2_lease *lease,
2753 bool first_open_attempt)
2755 bool sharing_violation = false;
2756 NTSTATUS status;
2758 status = open_mode_check(
2759 fsp->conn, fsp->file_id, lck, access_mask, share_access);
2760 if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
2761 sharing_violation = true;
2762 status = NT_STATUS_OK; /* handled later */
2765 if (!NT_STATUS_IS_OK(status)) {
2766 return status;
2769 if (oplock_request == INTERNAL_OPEN_ONLY) {
2770 if (sharing_violation) {
2771 DBG_DEBUG("Sharing violation for internal open\n");
2772 return NT_STATUS_SHARING_VIOLATION;
2776 * Internal opens never do oplocks or leases. We don't
2777 * need to go through delay_for_oplock().
2779 fsp->oplock_type = NO_OPLOCK;
2781 return NT_STATUS_OK;
2784 status = delay_for_oplock(
2785 fsp,
2786 oplock_request,
2787 lease,
2788 lck,
2789 sharing_violation,
2790 create_disposition,
2791 first_open_attempt);
2792 if (!NT_STATUS_IS_OK(status)) {
2793 return status;
2796 return NT_STATUS_OK;
2799 static bool request_timed_out(struct smb_request *req, struct timeval timeout)
2801 struct timeval now, end_time;
2802 GetTimeOfDay(&now);
2803 end_time = timeval_sum(&req->request_time, &timeout);
2804 return (timeval_compare(&end_time, &now) < 0);
2807 struct defer_open_state {
2808 struct smbXsrv_connection *xconn;
2809 uint64_t mid;
2812 static void defer_open_done(struct tevent_req *req);
2815 * Defer an open and watch a locking.tdb record
2817 * This defers an open that gets rescheduled once the locking.tdb record watch
2818 * is triggered by a change to the record.
2820 * It is used to defer opens that triggered an oplock break and for the SMB1
2821 * sharing violation delay.
2823 static void defer_open(struct share_mode_lock *lck,
2824 struct timeval timeout,
2825 struct smb_request *req,
2826 struct file_id id)
2828 struct deferred_open_record *open_rec = NULL;
2829 struct timeval abs_timeout;
2830 struct defer_open_state *watch_state;
2831 struct tevent_req *watch_req;
2832 struct timeval_buf tvbuf1, tvbuf2;
2833 struct file_id_buf fbuf;
2834 bool ok;
2836 abs_timeout = timeval_sum(&req->request_time, &timeout);
2838 DBG_DEBUG("request time [%s] timeout [%s] mid [%" PRIu64 "] "
2839 "file_id [%s]\n",
2840 timeval_str_buf(&req->request_time, false, true, &tvbuf1),
2841 timeval_str_buf(&abs_timeout, false, true, &tvbuf2),
2842 req->mid,
2843 file_id_str_buf(id, &fbuf));
2845 open_rec = talloc_zero(NULL, struct deferred_open_record);
2846 if (open_rec == NULL) {
2847 TALLOC_FREE(lck);
2848 exit_server("talloc failed");
2851 watch_state = talloc(open_rec, struct defer_open_state);
2852 if (watch_state == NULL) {
2853 exit_server("talloc failed");
2855 watch_state->xconn = req->xconn;
2856 watch_state->mid = req->mid;
2858 DBG_DEBUG("defering mid %" PRIu64 "\n", req->mid);
2860 watch_req = share_mode_watch_send(
2861 watch_state,
2862 req->sconn->ev_ctx,
2863 lck,
2864 (struct server_id){0});
2865 if (watch_req == NULL) {
2866 exit_server("Could not watch share mode record");
2868 tevent_req_set_callback(watch_req, defer_open_done, watch_state);
2870 ok = tevent_req_set_endtime(watch_req, req->sconn->ev_ctx, abs_timeout);
2871 if (!ok) {
2872 exit_server("tevent_req_set_endtime failed");
2875 ok = push_deferred_open_message_smb(req, timeout, id, open_rec);
2876 if (!ok) {
2877 TALLOC_FREE(lck);
2878 exit_server("push_deferred_open_message_smb failed");
2882 static void defer_open_done(struct tevent_req *req)
2884 struct defer_open_state *state = tevent_req_callback_data(
2885 req, struct defer_open_state);
2886 NTSTATUS status;
2887 bool ret;
2889 status = share_mode_watch_recv(req, NULL, NULL);
2890 TALLOC_FREE(req);
2891 if (!NT_STATUS_IS_OK(status)) {
2892 DEBUG(5, ("dbwrap_watched_watch_recv returned %s\n",
2893 nt_errstr(status)));
2895 * Even if it failed, retry anyway. TODO: We need a way to
2896 * tell a re-scheduled open about that error.
2900 DEBUG(10, ("scheduling mid %llu\n", (unsigned long long)state->mid));
2902 ret = schedule_deferred_open_message_smb(state->xconn, state->mid);
2903 SMB_ASSERT(ret);
2904 TALLOC_FREE(state);
2908 * Actually attempt the kernel oplock polling open.
2911 static void poll_open_fn(struct tevent_context *ev,
2912 struct tevent_timer *te,
2913 struct timeval current_time,
2914 void *private_data)
2916 struct deferred_open_record *open_rec = talloc_get_type_abort(
2917 private_data, struct deferred_open_record);
2918 bool ok;
2920 TALLOC_FREE(open_rec->watch_req);
2922 ok = schedule_deferred_open_message_smb(
2923 open_rec->xconn, open_rec->mid);
2924 if (!ok) {
2925 exit_server("schedule_deferred_open_message_smb failed");
2927 DBG_DEBUG("timer fired. Retrying open !\n");
2930 static void poll_open_done(struct tevent_req *subreq);
2933 * Reschedule an open for 1 second from now, if not timed out.
2935 static bool setup_poll_open(
2936 struct smb_request *req,
2937 struct share_mode_lock *lck,
2938 struct file_id id,
2939 struct timeval max_timeout,
2940 struct timeval interval)
2942 bool ok;
2943 struct deferred_open_record *open_rec = NULL;
2944 struct timeval endtime, next_interval;
2945 struct file_id_buf ftmp;
2947 if (request_timed_out(req, max_timeout)) {
2948 return false;
2951 open_rec = talloc_zero(NULL, struct deferred_open_record);
2952 if (open_rec == NULL) {
2953 DBG_WARNING("talloc failed\n");
2954 return false;
2956 open_rec->xconn = req->xconn;
2957 open_rec->mid = req->mid;
2960 * Make sure open_rec->te does not come later than the
2961 * request's maximum endtime.
2964 endtime = timeval_sum(&req->request_time, &max_timeout);
2965 next_interval = timeval_current_ofs(interval.tv_sec, interval.tv_usec);
2966 next_interval = timeval_min(&endtime, &next_interval);
2968 open_rec->te = tevent_add_timer(
2969 req->sconn->ev_ctx,
2970 open_rec,
2971 next_interval,
2972 poll_open_fn,
2973 open_rec);
2974 if (open_rec->te == NULL) {
2975 DBG_WARNING("tevent_add_timer failed\n");
2976 TALLOC_FREE(open_rec);
2977 return false;
2980 if (lck != NULL) {
2981 open_rec->watch_req = share_mode_watch_send(
2982 open_rec,
2983 req->sconn->ev_ctx,
2984 lck,
2985 (struct server_id) {0});
2986 if (open_rec->watch_req == NULL) {
2987 DBG_WARNING("share_mode_watch_send failed\n");
2988 TALLOC_FREE(open_rec);
2989 return false;
2991 tevent_req_set_callback(
2992 open_rec->watch_req, poll_open_done, open_rec);
2995 ok = push_deferred_open_message_smb(req, max_timeout, id, open_rec);
2996 if (!ok) {
2997 DBG_WARNING("push_deferred_open_message_smb failed\n");
2998 TALLOC_FREE(open_rec);
2999 return false;
3002 DBG_DEBUG("poll request time [%s] mid [%" PRIu64 "] file_id [%s]\n",
3003 timeval_string(talloc_tos(), &req->request_time, false),
3004 req->mid,
3005 file_id_str_buf(id, &ftmp));
3007 return true;
3010 static void poll_open_done(struct tevent_req *subreq)
3012 struct deferred_open_record *open_rec = tevent_req_callback_data(
3013 subreq, struct deferred_open_record);
3014 NTSTATUS status;
3015 bool ok;
3017 status = share_mode_watch_recv(subreq, NULL, NULL);
3018 TALLOC_FREE(subreq);
3019 open_rec->watch_req = NULL;
3020 TALLOC_FREE(open_rec->te);
3022 DBG_DEBUG("dbwrap_watched_watch_recv returned %s\n",
3023 nt_errstr(status));
3025 ok = schedule_deferred_open_message_smb(
3026 open_rec->xconn, open_rec->mid);
3027 if (!ok) {
3028 exit_server("schedule_deferred_open_message_smb failed");
3032 bool defer_smb1_sharing_violation(struct smb_request *req)
3034 bool ok;
3035 int timeout_usecs;
3037 if (!lp_defer_sharing_violations()) {
3038 return false;
3042 * Try every 200msec up to (by default) one second. To be
3043 * precise, according to behaviour note <247> in [MS-CIFS],
3044 * the server tries 5 times. But up to one second should be
3045 * close enough.
3048 timeout_usecs = lp_parm_int(
3049 SNUM(req->conn),
3050 "smbd",
3051 "sharedelay",
3052 SHARING_VIOLATION_USEC_WAIT);
3054 ok = setup_poll_open(
3055 req,
3056 NULL,
3057 (struct file_id) {0},
3058 (struct timeval) { .tv_usec = timeout_usecs },
3059 (struct timeval) { .tv_usec = 200000 });
3060 return ok;
3063 /****************************************************************************
3064 On overwrite open ensure that the attributes match.
3065 ****************************************************************************/
3067 static bool open_match_attributes(connection_struct *conn,
3068 uint32_t old_dos_attr,
3069 uint32_t new_dos_attr,
3070 mode_t new_unx_mode,
3071 mode_t *returned_unx_mode)
3073 uint32_t noarch_old_dos_attr, noarch_new_dos_attr;
3075 noarch_old_dos_attr = (old_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
3076 noarch_new_dos_attr = (new_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
3078 if((noarch_old_dos_attr == 0 && noarch_new_dos_attr != 0) ||
3079 (noarch_old_dos_attr != 0 && ((noarch_old_dos_attr & noarch_new_dos_attr) == noarch_old_dos_attr))) {
3080 *returned_unx_mode = new_unx_mode;
3081 } else {
3082 *returned_unx_mode = (mode_t)0;
3085 DEBUG(10,("open_match_attributes: old_dos_attr = 0x%x, "
3086 "new_dos_attr = 0x%x "
3087 "returned_unx_mode = 0%o\n",
3088 (unsigned int)old_dos_attr,
3089 (unsigned int)new_dos_attr,
3090 (unsigned int)*returned_unx_mode ));
3092 /* If we're mapping SYSTEM and HIDDEN ensure they match. */
3093 if (lp_map_system(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
3094 if ((old_dos_attr & FILE_ATTRIBUTE_SYSTEM) &&
3095 !(new_dos_attr & FILE_ATTRIBUTE_SYSTEM)) {
3096 return False;
3099 if (lp_map_hidden(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
3100 if ((old_dos_attr & FILE_ATTRIBUTE_HIDDEN) &&
3101 !(new_dos_attr & FILE_ATTRIBUTE_HIDDEN)) {
3102 return False;
3105 return True;
3108 static void schedule_defer_open(struct share_mode_lock *lck,
3109 struct file_id id,
3110 struct smb_request *req)
3112 /* This is a relative time, added to the absolute
3113 request_time value to get the absolute timeout time.
3114 Note that if this is the second or greater time we enter
3115 this codepath for this particular request mid then
3116 request_time is left as the absolute time of the *first*
3117 time this request mid was processed. This is what allows
3118 the request to eventually time out. */
3120 struct timeval timeout;
3122 /* Normally the smbd we asked should respond within
3123 * OPLOCK_BREAK_TIMEOUT seconds regardless of whether
3124 * the client did, give twice the timeout as a safety
3125 * measure here in case the other smbd is stuck
3126 * somewhere else. */
3128 timeout = timeval_set(OPLOCK_BREAK_TIMEOUT*2, 0);
3130 if (request_timed_out(req, timeout)) {
3131 return;
3134 defer_open(lck, timeout, req, id);
3137 /****************************************************************************
3138 Reschedule an open call that went asynchronous.
3139 ****************************************************************************/
3141 static void schedule_async_open_timer(struct tevent_context *ev,
3142 struct tevent_timer *te,
3143 struct timeval current_time,
3144 void *private_data)
3146 exit_server("async open timeout");
3149 static void schedule_async_open(struct smb_request *req)
3151 struct deferred_open_record *open_rec = NULL;
3152 struct timeval timeout = timeval_set(20, 0);
3153 bool ok;
3155 if (request_timed_out(req, timeout)) {
3156 return;
3159 open_rec = talloc_zero(NULL, struct deferred_open_record);
3160 if (open_rec == NULL) {
3161 exit_server("deferred_open_record_create failed");
3163 open_rec->async_open = true;
3165 ok = push_deferred_open_message_smb(
3166 req, timeout, (struct file_id){0}, open_rec);
3167 if (!ok) {
3168 exit_server("push_deferred_open_message_smb failed");
3171 open_rec->te = tevent_add_timer(req->sconn->ev_ctx,
3172 req,
3173 timeval_current_ofs(20, 0),
3174 schedule_async_open_timer,
3175 open_rec);
3176 if (open_rec->te == NULL) {
3177 exit_server("tevent_add_timer failed");
3181 /****************************************************************************
3182 Work out what access_mask to use from what the client sent us.
3183 ****************************************************************************/
3185 static NTSTATUS smbd_calculate_maximum_allowed_access_fsp(
3186 struct files_struct *dirfsp,
3187 struct files_struct *fsp,
3188 bool use_privs,
3189 uint32_t *p_access_mask)
3191 struct security_descriptor *sd = NULL;
3192 uint32_t access_granted = 0;
3193 NTSTATUS status;
3195 /* Cope with symlinks */
3196 if (fsp == NULL || fsp_get_pathref_fd(fsp) == -1) {
3197 *p_access_mask = FILE_GENERIC_ALL;
3198 return NT_STATUS_OK;
3201 /* Cope with fake/printer fsp's. */
3202 if (fsp->fake_file_handle != NULL || fsp->print_file != NULL) {
3203 *p_access_mask = FILE_GENERIC_ALL;
3204 return NT_STATUS_OK;
3207 if (!use_privs && (get_current_uid(fsp->conn) == (uid_t)0)) {
3208 *p_access_mask |= FILE_GENERIC_ALL;
3209 return NT_STATUS_OK;
3212 status = SMB_VFS_FGET_NT_ACL(fsp,
3213 (SECINFO_OWNER |
3214 SECINFO_GROUP |
3215 SECINFO_DACL),
3216 talloc_tos(),
3217 &sd);
3219 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
3221 * File did not exist
3223 *p_access_mask = FILE_GENERIC_ALL;
3224 return NT_STATUS_OK;
3226 if (!NT_STATUS_IS_OK(status)) {
3227 DBG_ERR("Could not get acl on file %s: %s\n",
3228 fsp_str_dbg(fsp),
3229 nt_errstr(status));
3230 return status;
3234 * If we can access the path to this file, by
3235 * default we have FILE_READ_ATTRIBUTES from the
3236 * containing directory. See the section:
3237 * "Algorithm to Check Access to an Existing File"
3238 * in MS-FSA.pdf.
3240 * se_file_access_check()
3241 * also takes care of owner WRITE_DAC and READ_CONTROL.
3243 status = se_file_access_check(sd,
3244 get_current_nttok(fsp->conn),
3245 use_privs,
3246 (*p_access_mask & ~FILE_READ_ATTRIBUTES),
3247 &access_granted);
3249 TALLOC_FREE(sd);
3251 if (!NT_STATUS_IS_OK(status)) {
3252 DBG_ERR("Status %s on file %s: "
3253 "when calculating maximum access\n",
3254 nt_errstr(status),
3255 fsp_str_dbg(fsp));
3256 return status;
3259 *p_access_mask = (access_granted | FILE_READ_ATTRIBUTES);
3261 if (!(access_granted & DELETE_ACCESS)) {
3262 if (can_delete_file_in_directory(fsp->conn,
3263 dirfsp,
3264 fsp->fsp_name)) {
3265 *p_access_mask |= DELETE_ACCESS;
3269 return NT_STATUS_OK;
3272 NTSTATUS smbd_calculate_access_mask_fsp(struct files_struct *dirfsp,
3273 struct files_struct *fsp,
3274 bool use_privs,
3275 uint32_t access_mask,
3276 uint32_t *access_mask_out)
3278 NTSTATUS status;
3279 uint32_t orig_access_mask = access_mask;
3280 uint32_t rejected_share_access;
3282 if (access_mask & SEC_MASK_INVALID) {
3283 DBG_DEBUG("access_mask [%8x] contains invalid bits\n",
3284 access_mask);
3285 return NT_STATUS_ACCESS_DENIED;
3289 * Convert GENERIC bits to specific bits.
3292 se_map_generic(&access_mask, &file_generic_mapping);
3294 /* Calculate MAXIMUM_ALLOWED_ACCESS if requested. */
3295 if (access_mask & MAXIMUM_ALLOWED_ACCESS) {
3297 status = smbd_calculate_maximum_allowed_access_fsp(
3298 dirfsp,
3299 fsp,
3300 use_privs,
3301 &access_mask);
3303 if (!NT_STATUS_IS_OK(status)) {
3304 return status;
3307 access_mask &= fsp->conn->share_access;
3310 rejected_share_access = access_mask & ~(fsp->conn->share_access);
3312 if (rejected_share_access) {
3313 DBG_ERR("Access denied on file %s: "
3314 "rejected by share access mask[0x%08X] "
3315 "orig[0x%08X] mapped[0x%08X] reject[0x%08X]\n",
3316 fsp_str_dbg(fsp),
3317 fsp->conn->share_access,
3318 orig_access_mask, access_mask,
3319 rejected_share_access);
3320 return NT_STATUS_ACCESS_DENIED;
3323 *access_mask_out = access_mask;
3324 return NT_STATUS_OK;
3327 /****************************************************************************
3328 Remove the deferred open entry under lock.
3329 ****************************************************************************/
3331 /****************************************************************************
3332 Return true if this is a state pointer to an asynchronous create.
3333 ****************************************************************************/
3335 bool is_deferred_open_async(const struct deferred_open_record *rec)
3337 return rec->async_open;
3340 static bool clear_ads(uint32_t create_disposition)
3342 bool ret = false;
3344 switch (create_disposition) {
3345 case FILE_SUPERSEDE:
3346 case FILE_OVERWRITE_IF:
3347 case FILE_OVERWRITE:
3348 ret = true;
3349 break;
3350 default:
3351 break;
3353 return ret;
3356 static int disposition_to_open_flags(uint32_t create_disposition)
3358 int ret = 0;
3361 * Currently we're using FILE_SUPERSEDE as the same as
3362 * FILE_OVERWRITE_IF but they really are
3363 * different. FILE_SUPERSEDE deletes an existing file
3364 * (requiring delete access) then recreates it.
3367 switch (create_disposition) {
3368 case FILE_SUPERSEDE:
3369 case FILE_OVERWRITE_IF:
3371 * If file exists replace/overwrite. If file doesn't
3372 * exist create.
3374 ret = O_CREAT|O_TRUNC;
3375 break;
3377 case FILE_OPEN:
3379 * If file exists open. If file doesn't exist error.
3381 ret = 0;
3382 break;
3384 case FILE_OVERWRITE:
3386 * If file exists overwrite. If file doesn't exist
3387 * error.
3389 ret = O_TRUNC;
3390 break;
3392 case FILE_CREATE:
3394 * If file exists error. If file doesn't exist create.
3396 ret = O_CREAT|O_EXCL;
3397 break;
3399 case FILE_OPEN_IF:
3401 * If file exists open. If file doesn't exist create.
3403 ret = O_CREAT;
3404 break;
3406 return ret;
3409 static int calculate_open_access_flags(uint32_t access_mask,
3410 uint32_t private_flags)
3412 bool need_write, need_read;
3415 * Note that we ignore the append flag as append does not
3416 * mean the same thing under DOS and Unix.
3419 need_write = (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA));
3420 if (!need_write) {
3421 return O_RDONLY;
3424 /* DENY_DOS opens are always underlying read-write on the
3425 file handle, no matter what the requested access mask
3426 says. */
3428 need_read =
3429 ((private_flags & NTCREATEX_FLAG_DENY_DOS) ||
3430 access_mask & (FILE_READ_ATTRIBUTES|FILE_READ_DATA|
3431 FILE_READ_EA|FILE_EXECUTE));
3433 if (!need_read) {
3434 return O_WRONLY;
3436 return O_RDWR;
3439 /****************************************************************************
3440 Open a file with a share mode. Passed in an already created files_struct *.
3441 ****************************************************************************/
3443 static NTSTATUS open_file_ntcreate(connection_struct *conn,
3444 struct smb_request *req,
3445 uint32_t access_mask, /* access bits (FILE_READ_DATA etc.) */
3446 uint32_t share_access, /* share constants (FILE_SHARE_READ etc) */
3447 uint32_t create_disposition, /* FILE_OPEN_IF etc. */
3448 uint32_t create_options, /* options such as delete on close. */
3449 uint32_t new_dos_attributes, /* attributes used for new file. */
3450 int oplock_request, /* internal Samba oplock codes. */
3451 const struct smb2_lease *lease,
3452 /* Information (FILE_EXISTS etc.) */
3453 uint32_t private_flags, /* Samba specific flags. */
3454 struct smb_filename *parent_dir_fname, /* parent. */
3455 struct smb_filename *smb_fname_atname, /* atname relative to parent. */
3456 int *pinfo,
3457 files_struct *fsp)
3459 struct smb_filename *smb_fname = fsp->fsp_name;
3460 int flags=0;
3461 int flags2=0;
3462 bool file_existed = VALID_STAT(smb_fname->st);
3463 bool def_acl = False;
3464 bool posix_open = False;
3465 bool new_file_created = False;
3466 bool first_open_attempt = true;
3467 NTSTATUS fsp_open = NT_STATUS_ACCESS_DENIED;
3468 mode_t new_unx_mode = (mode_t)0;
3469 mode_t unx_mode = (mode_t)0;
3470 int info;
3471 uint32_t existing_dos_attributes = 0;
3472 struct share_mode_lock *lck = NULL;
3473 uint32_t open_access_mask = access_mask;
3474 NTSTATUS status;
3475 SMB_STRUCT_STAT saved_stat = smb_fname->st;
3476 struct timespec old_write_time;
3477 bool setup_poll = false;
3478 bool ok;
3480 if (conn->printer) {
3482 * Printers are handled completely differently.
3483 * Most of the passed parameters are ignored.
3486 if (pinfo) {
3487 *pinfo = FILE_WAS_CREATED;
3490 DEBUG(10, ("open_file_ntcreate: printer open fname=%s\n",
3491 smb_fname_str_dbg(smb_fname)));
3493 if (!req) {
3494 DEBUG(0,("open_file_ntcreate: printer open without "
3495 "an SMB request!\n"));
3496 return NT_STATUS_INTERNAL_ERROR;
3499 return print_spool_open(fsp, smb_fname->base_name,
3500 req->vuid);
3503 if (new_dos_attributes & FILE_FLAG_POSIX_SEMANTICS) {
3504 posix_open = True;
3505 unx_mode = (mode_t)(new_dos_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
3506 new_dos_attributes = 0;
3507 } else {
3508 /* Windows allows a new file to be created and
3509 silently removes a FILE_ATTRIBUTE_DIRECTORY
3510 sent by the client. Do the same. */
3512 new_dos_attributes &= ~FILE_ATTRIBUTE_DIRECTORY;
3514 /* We add FILE_ATTRIBUTE_ARCHIVE to this as this mode is only used if the file is
3515 * created new. */
3516 unx_mode = unix_mode(conn, new_dos_attributes | FILE_ATTRIBUTE_ARCHIVE,
3517 smb_fname, parent_dir_fname);
3520 DEBUG(10, ("open_file_ntcreate: fname=%s, dos_attrs=0x%x "
3521 "access_mask=0x%x share_access=0x%x "
3522 "create_disposition = 0x%x create_options=0x%x "
3523 "unix mode=0%o oplock_request=%d private_flags = 0x%x\n",
3524 smb_fname_str_dbg(smb_fname), new_dos_attributes,
3525 access_mask, share_access, create_disposition,
3526 create_options, (unsigned int)unx_mode, oplock_request,
3527 (unsigned int)private_flags));
3529 if (req == NULL) {
3530 /* Ensure req == NULL means INTERNAL_OPEN_ONLY */
3531 SMB_ASSERT(oplock_request == INTERNAL_OPEN_ONLY);
3532 } else {
3533 /* And req != NULL means no INTERNAL_OPEN_ONLY */
3534 SMB_ASSERT(((oplock_request & INTERNAL_OPEN_ONLY) == 0));
3538 * Only non-internal opens can be deferred at all
3541 if (req) {
3542 struct deferred_open_record *open_rec;
3543 if (get_deferred_open_message_state(req, NULL, &open_rec)) {
3545 /* If it was an async create retry, the file
3546 didn't exist. */
3548 if (is_deferred_open_async(open_rec)) {
3549 SET_STAT_INVALID(smb_fname->st);
3550 file_existed = false;
3553 /* Ensure we don't reprocess this message. */
3554 remove_deferred_open_message_smb(req->xconn, req->mid);
3556 first_open_attempt = false;
3560 if (!posix_open) {
3561 new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
3562 if (file_existed) {
3564 * Only use stored DOS attributes for checks
3565 * against requested attributes (below via
3566 * open_match_attributes()), cf bug #11992
3567 * for details. -slow
3569 uint32_t attr = 0;
3571 status = SMB_VFS_FGET_DOS_ATTRIBUTES(conn, smb_fname->fsp, &attr);
3572 if (NT_STATUS_IS_OK(status)) {
3573 existing_dos_attributes = attr;
3578 /* ignore any oplock requests if oplocks are disabled */
3579 if (!lp_oplocks(SNUM(conn)) ||
3580 IS_VETO_OPLOCK_PATH(conn, smb_fname->base_name)) {
3581 /* Mask off everything except the private Samba bits. */
3582 oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
3585 /* this is for OS/2 long file names - say we don't support them */
3586 if (req != NULL && !req->posix_pathnames &&
3587 strstr(smb_fname->base_name,".+,;=[].")) {
3588 /* OS/2 Workplace shell fix may be main code stream in a later
3589 * release. */
3590 DEBUG(5,("open_file_ntcreate: OS/2 long filenames are not "
3591 "supported.\n"));
3592 if (use_nt_status()) {
3593 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3595 return NT_STATUS_DOS(ERRDOS, ERRcannotopen);
3598 switch( create_disposition ) {
3599 case FILE_OPEN:
3600 /* If file exists open. If file doesn't exist error. */
3601 if (!file_existed) {
3602 DEBUG(5,("open_file_ntcreate: FILE_OPEN "
3603 "requested for file %s and file "
3604 "doesn't exist.\n",
3605 smb_fname_str_dbg(smb_fname)));
3606 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3608 break;
3610 case FILE_OVERWRITE:
3611 /* If file exists overwrite. If file doesn't exist
3612 * error. */
3613 if (!file_existed) {
3614 DEBUG(5,("open_file_ntcreate: FILE_OVERWRITE "
3615 "requested for file %s and file "
3616 "doesn't exist.\n",
3617 smb_fname_str_dbg(smb_fname) ));
3618 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3620 break;
3622 case FILE_CREATE:
3623 /* If file exists error. If file doesn't exist
3624 * create. */
3625 if (file_existed) {
3626 DEBUG(5,("open_file_ntcreate: FILE_CREATE "
3627 "requested for file %s and file "
3628 "already exists.\n",
3629 smb_fname_str_dbg(smb_fname)));
3630 if (S_ISDIR(smb_fname->st.st_ex_mode)) {
3631 return NT_STATUS_FILE_IS_A_DIRECTORY;
3633 return NT_STATUS_OBJECT_NAME_COLLISION;
3635 break;
3637 case FILE_SUPERSEDE:
3638 case FILE_OVERWRITE_IF:
3639 case FILE_OPEN_IF:
3640 break;
3641 default:
3642 return NT_STATUS_INVALID_PARAMETER;
3645 flags2 = disposition_to_open_flags(create_disposition);
3647 /* We only care about matching attributes on file exists and
3648 * overwrite. */
3650 if (!posix_open && file_existed &&
3651 ((create_disposition == FILE_OVERWRITE) ||
3652 (create_disposition == FILE_OVERWRITE_IF))) {
3653 if (!open_match_attributes(conn, existing_dos_attributes,
3654 new_dos_attributes,
3655 unx_mode, &new_unx_mode)) {
3656 DEBUG(5,("open_file_ntcreate: attributes mismatch "
3657 "for file %s (%x %x) (0%o, 0%o)\n",
3658 smb_fname_str_dbg(smb_fname),
3659 existing_dos_attributes,
3660 new_dos_attributes,
3661 (unsigned int)smb_fname->st.st_ex_mode,
3662 (unsigned int)unx_mode ));
3663 return NT_STATUS_ACCESS_DENIED;
3667 status = smbd_calculate_access_mask_fsp(parent_dir_fname->fsp,
3668 smb_fname->fsp,
3669 false,
3670 access_mask,
3671 &access_mask);
3672 if (!NT_STATUS_IS_OK(status)) {
3673 DBG_DEBUG("smbd_calculate_access_mask_fsp "
3674 "on file %s returned %s\n",
3675 smb_fname_str_dbg(smb_fname),
3676 nt_errstr(status));
3677 return status;
3680 open_access_mask = access_mask;
3682 if (flags2 & O_TRUNC) {
3683 open_access_mask |= FILE_WRITE_DATA; /* This will cause oplock breaks. */
3686 if (file_existed) {
3688 * stat opens on existing files don't get oplocks.
3689 * They can get leases.
3691 * Note that we check for stat open on the *open_access_mask*,
3692 * i.e. the access mask we actually used to do the open,
3693 * not the one the client asked for (which is in
3694 * fsp->access_mask). This is due to the fact that
3695 * FILE_OVERWRITE and FILE_OVERWRITE_IF add in O_TRUNC,
3696 * which adds FILE_WRITE_DATA to open_access_mask.
3698 if (is_oplock_stat_open(open_access_mask) && lease == NULL) {
3699 oplock_request = NO_OPLOCK;
3703 DEBUG(10, ("open_file_ntcreate: fname=%s, after mapping "
3704 "access_mask=0x%x\n", smb_fname_str_dbg(smb_fname),
3705 access_mask));
3708 * Note that we ignore the append flag as append does not
3709 * mean the same thing under DOS and Unix.
3712 flags = calculate_open_access_flags(access_mask, private_flags);
3715 * Currently we only look at FILE_WRITE_THROUGH for create options.
3718 #if defined(O_SYNC)
3719 if ((create_options & FILE_WRITE_THROUGH) && lp_strict_sync(SNUM(conn))) {
3720 flags2 |= O_SYNC;
3722 #endif /* O_SYNC */
3724 if (posix_open && (access_mask & FILE_APPEND_DATA)) {
3725 flags2 |= O_APPEND;
3728 if (!posix_open && !CAN_WRITE(conn)) {
3730 * We should really return a permission denied error if either
3731 * O_CREAT or O_TRUNC are set, but for compatibility with
3732 * older versions of Samba we just AND them out.
3734 flags2 &= ~(O_CREAT|O_TRUNC);
3738 * With kernel oplocks the open breaking an oplock
3739 * blocks until the oplock holder has given up the
3740 * oplock or closed the file. We prevent this by always
3741 * trying to open the file with O_NONBLOCK (see "man
3742 * fcntl" on Linux).
3744 * If a process that doesn't use the smbd open files
3745 * database or communication methods holds a kernel
3746 * oplock we must periodically poll for available open
3747 * using O_NONBLOCK.
3749 flags2 |= O_NONBLOCK;
3752 * Ensure we can't write on a read-only share or file.
3755 if (flags != O_RDONLY && file_existed &&
3756 (!CAN_WRITE(conn) || IS_DOS_READONLY(existing_dos_attributes))) {
3757 DEBUG(5,("open_file_ntcreate: write access requested for "
3758 "file %s on read only %s\n",
3759 smb_fname_str_dbg(smb_fname),
3760 !CAN_WRITE(conn) ? "share" : "file" ));
3761 return NT_STATUS_ACCESS_DENIED;
3764 if (VALID_STAT(smb_fname->st)) {
3766 * Only try and create a file id before open
3767 * for an existing file. For a file being created
3768 * this won't do anything useful until the file
3769 * exists and has a valid stat struct.
3771 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
3773 fh_set_private_options(fsp->fh, private_flags);
3774 fsp->access_mask = open_access_mask; /* We change this to the
3775 * requested access_mask after
3776 * the open is done. */
3777 if (posix_open) {
3778 fsp->posix_flags |= FSP_POSIX_FLAGS_ALL;
3781 if ((create_options & FILE_DELETE_ON_CLOSE) &&
3782 (flags2 & O_CREAT) &&
3783 !file_existed) {
3784 /* Delete on close semantics for new files. */
3785 status = can_set_delete_on_close(fsp,
3786 new_dos_attributes);
3787 if (!NT_STATUS_IS_OK(status)) {
3788 fd_close(fsp);
3789 return status;
3794 * Ensure we pay attention to default ACLs on directories if required.
3797 if ((flags2 & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
3798 (def_acl = directory_has_default_acl_fsp(parent_dir_fname->fsp)))
3800 unx_mode = (0777 & lp_create_mask(SNUM(conn)));
3803 DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o, "
3804 "access_mask = 0x%x, open_access_mask = 0x%x\n",
3805 (unsigned int)flags, (unsigned int)flags2,
3806 (unsigned int)unx_mode, (unsigned int)access_mask,
3807 (unsigned int)open_access_mask));
3809 fsp_open = open_file(fsp,
3810 req,
3811 parent_dir_fname,
3812 flags|flags2,
3813 unx_mode,
3814 access_mask,
3815 open_access_mask,
3816 private_flags,
3817 &new_file_created);
3818 if (NT_STATUS_EQUAL(fsp_open, NT_STATUS_NETWORK_BUSY)) {
3819 if (file_existed && S_ISFIFO(fsp->fsp_name->st.st_ex_mode)) {
3820 DEBUG(10, ("FIFO busy\n"));
3821 return NT_STATUS_NETWORK_BUSY;
3823 if (req == NULL) {
3824 DEBUG(10, ("Internal open busy\n"));
3825 return NT_STATUS_NETWORK_BUSY;
3828 * This handles the kernel oplock case:
3830 * the file has an active kernel oplock and the open() returned
3831 * EWOULDBLOCK/EAGAIN which maps to NETWORK_BUSY.
3833 * "Samba locking.tdb oplocks" are handled below after acquiring
3834 * the sharemode lock with get_share_mode_lock().
3836 setup_poll = true;
3839 if (NT_STATUS_EQUAL(fsp_open, NT_STATUS_RETRY)) {
3841 * EINTR from the open(2) syscall. Just setup a retry
3842 * in a bit. We can't use the sys_write() tight retry
3843 * loop here, as we might have to actually deal with
3844 * lease-break signals to avoid a deadlock.
3846 setup_poll = true;
3849 if (setup_poll) {
3851 * From here on we assume this is an oplock break triggered
3854 lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
3856 if ((lck != NULL) && !validate_oplock_types(lck)) {
3857 smb_panic("validate_oplock_types failed");
3861 * Retry once a second. If there's a share_mode_lock
3862 * around, also wait for it in case it was smbd
3863 * holding that kernel oplock that can quickly tell us
3864 * the oplock got removed.
3867 setup_poll_open(
3868 req,
3869 lck,
3870 fsp->file_id,
3871 timeval_set(OPLOCK_BREAK_TIMEOUT*2, 0),
3872 timeval_set(1, 0));
3874 TALLOC_FREE(lck);
3876 return NT_STATUS_SHARING_VIOLATION;
3879 if (!NT_STATUS_IS_OK(fsp_open)) {
3880 bool wait_for_aio = NT_STATUS_EQUAL(
3881 fsp_open, NT_STATUS_MORE_PROCESSING_REQUIRED);
3882 if (wait_for_aio) {
3883 schedule_async_open(req);
3885 return fsp_open;
3888 if (new_file_created) {
3890 * As we atomically create using O_CREAT|O_EXCL,
3891 * then if new_file_created is true, then
3892 * file_existed *MUST* have been false (even
3893 * if the file was previously detected as being
3894 * there).
3896 file_existed = false;
3899 if (file_existed && !check_same_dev_ino(&saved_stat, &smb_fname->st)) {
3901 * The file did exist, but some other (local or NFS)
3902 * process either renamed/unlinked and re-created the
3903 * file with different dev/ino after we walked the path,
3904 * but before we did the open. We could retry the
3905 * open but it's a rare enough case it's easier to
3906 * just fail the open to prevent creating any problems
3907 * in the open file db having the wrong dev/ino key.
3909 fd_close(fsp);
3910 DBG_WARNING("file %s - dev/ino mismatch. "
3911 "Old (dev=%ju, ino=%ju). "
3912 "New (dev=%ju, ino=%ju). Failing open "
3913 "with NT_STATUS_ACCESS_DENIED.\n",
3914 smb_fname_str_dbg(smb_fname),
3915 (uintmax_t)saved_stat.st_ex_dev,
3916 (uintmax_t)saved_stat.st_ex_ino,
3917 (uintmax_t)smb_fname->st.st_ex_dev,
3918 (uintmax_t)smb_fname->st.st_ex_ino);
3919 return NT_STATUS_ACCESS_DENIED;
3922 old_write_time = smb_fname->st.st_ex_mtime;
3925 * Deal with the race condition where two smbd's detect the
3926 * file doesn't exist and do the create at the same time. One
3927 * of them will win and set a share mode, the other (ie. this
3928 * one) should check if the requested share mode for this
3929 * create is allowed.
3933 * Now the file exists and fsp is successfully opened,
3934 * fsp->dev and fsp->inode are valid and should replace the
3935 * dev=0,inode=0 from a non existent file. Spotted by
3936 * Nadav Danieli <nadavd@exanet.com>. JRA.
3939 lck = get_share_mode_lock(talloc_tos(), fsp->file_id,
3940 conn->connectpath,
3941 smb_fname, &old_write_time);
3943 if (lck == NULL) {
3944 DEBUG(0, ("open_file_ntcreate: Could not get share "
3945 "mode lock for %s\n",
3946 smb_fname_str_dbg(smb_fname)));
3947 fd_close(fsp);
3948 return NT_STATUS_SHARING_VIOLATION;
3951 /* Get the types we need to examine. */
3952 if (!validate_oplock_types(lck)) {
3953 smb_panic("validate_oplock_types failed");
3956 if (has_delete_on_close(lck, fsp->name_hash)) {
3957 TALLOC_FREE(lck);
3958 fd_close(fsp);
3959 return NT_STATUS_DELETE_PENDING;
3962 status = handle_share_mode_lease(
3963 fsp,
3964 lck,
3965 create_disposition,
3966 access_mask,
3967 share_access,
3968 oplock_request,
3969 lease,
3970 first_open_attempt);
3972 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
3973 schedule_defer_open(lck, fsp->file_id, req);
3974 TALLOC_FREE(lck);
3975 fd_close(fsp);
3976 return NT_STATUS_SHARING_VIOLATION;
3979 if (!NT_STATUS_IS_OK(status)) {
3980 TALLOC_FREE(lck);
3981 fd_close(fsp);
3982 return status;
3985 share_mode_flags_restrict(lck, access_mask, share_access, 0);
3987 ok = set_share_mode(
3988 lck,
3989 fsp,
3990 get_current_uid(fsp->conn),
3991 req ? req->mid : 0,
3992 fsp->oplock_type,
3993 share_access,
3994 access_mask);
3995 if (!ok) {
3996 if (fsp->oplock_type == LEASE_OPLOCK) {
3997 status = remove_lease_if_stale(
3998 lck,
3999 fsp_client_guid(fsp),
4000 &fsp->lease->lease.lease_key);
4001 if (!NT_STATUS_IS_OK(status)) {
4002 DBG_WARNING("remove_lease_if_stale "
4003 "failed: %s\n",
4004 nt_errstr(status));
4007 TALLOC_FREE(lck);
4008 fd_close(fsp);
4009 return NT_STATUS_NO_MEMORY;
4012 /* Should we atomically (to the client at least) truncate ? */
4013 if ((!new_file_created) &&
4014 (flags2 & O_TRUNC) &&
4015 (S_ISREG(fsp->fsp_name->st.st_ex_mode))) {
4016 int ret;
4018 ret = SMB_VFS_FTRUNCATE(fsp, 0);
4019 if (ret != 0) {
4020 status = map_nt_error_from_unix(errno);
4021 del_share_mode(lck, fsp);
4022 TALLOC_FREE(lck);
4023 fd_close(fsp);
4024 return status;
4026 notify_fname(fsp->conn, NOTIFY_ACTION_MODIFIED,
4027 FILE_NOTIFY_CHANGE_SIZE
4028 | FILE_NOTIFY_CHANGE_ATTRIBUTES,
4029 fsp->fsp_name->base_name);
4033 * We have the share entry *locked*.....
4036 /* Delete streams if create_disposition requires it */
4037 if (!new_file_created && clear_ads(create_disposition) &&
4038 !is_ntfs_stream_smb_fname(smb_fname)) {
4039 status = delete_all_streams(conn, smb_fname);
4040 if (!NT_STATUS_IS_OK(status)) {
4041 del_share_mode(lck, fsp);
4042 TALLOC_FREE(lck);
4043 fd_close(fsp);
4044 return status;
4048 if (!fsp->fsp_flags.is_pathref &&
4049 fsp_get_io_fd(fsp) != -1 &&
4050 lp_kernel_share_modes(SNUM(conn)))
4052 int ret_flock;
4054 * Beware: streams implementing VFS modules may
4055 * implement streams in a way that fsp will have the
4056 * basefile open in the fsp fd, so lacking a distinct
4057 * fd for the stream the file-system sharemode will
4058 * apply on the basefile which is wrong. The actual
4059 * check is deferred to the VFS module implementing
4060 * the file-system sharemode call.
4062 ret_flock = SMB_VFS_FILESYSTEM_SHAREMODE(fsp,
4063 share_access,
4064 access_mask);
4065 if(ret_flock == -1 ){
4067 del_share_mode(lck, fsp);
4068 TALLOC_FREE(lck);
4069 fd_close(fsp);
4071 return NT_STATUS_SHARING_VIOLATION;
4074 fsp->fsp_flags.kernel_share_modes_taken = true;
4078 * At this point onwards, we can guarantee that the share entry
4079 * is locked, whether we created the file or not, and that the
4080 * deny mode is compatible with all current opens.
4084 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
4085 * but we don't have to store this - just ignore it on access check.
4087 if (conn->sconn->using_smb2) {
4089 * SMB2 doesn't return it (according to Microsoft tests).
4090 * Test Case: TestSuite_ScenarioNo009GrantedAccessTestS0
4091 * File created with access = 0x7 (Read, Write, Delete)
4092 * Query Info on file returns 0x87 (Read, Write, Delete, Read Attributes)
4094 fsp->access_mask = access_mask;
4095 } else {
4096 /* But SMB1 does. */
4097 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
4100 if (new_file_created) {
4101 info = FILE_WAS_CREATED;
4102 } else {
4103 if (flags2 & O_TRUNC) {
4104 info = FILE_WAS_OVERWRITTEN;
4105 } else {
4106 info = FILE_WAS_OPENED;
4110 if (pinfo) {
4111 *pinfo = info;
4114 /* Handle strange delete on close create semantics. */
4115 if (create_options & FILE_DELETE_ON_CLOSE) {
4116 if (!new_file_created) {
4117 status = can_set_delete_on_close(fsp,
4118 existing_dos_attributes);
4120 if (!NT_STATUS_IS_OK(status)) {
4121 /* Remember to delete the mode we just added. */
4122 del_share_mode(lck, fsp);
4123 TALLOC_FREE(lck);
4124 fd_close(fsp);
4125 return status;
4128 /* Note that here we set the *initial* delete on close flag,
4129 not the regular one. The magic gets handled in close. */
4130 fsp->fsp_flags.initial_delete_on_close = true;
4134 * If we created a file and it's not a stream, this is the point where
4135 * we set the itime (aka invented time) that get's stored in the DOS
4136 * attribute xattr. The value is going to be either what the filesystem
4137 * provided or a copy of the creation date.
4139 * Either way, we turn the itime into a File-ID, unless the filesystem
4140 * provided one (unlikely).
4142 if (info == FILE_WAS_CREATED && !is_named_stream(smb_fname)) {
4143 smb_fname->st.st_ex_iflags &= ~ST_EX_IFLAG_CALCULATED_ITIME;
4145 if (lp_store_dos_attributes(SNUM(conn)) &&
4146 smb_fname->st.st_ex_iflags & ST_EX_IFLAG_CALCULATED_FILE_ID)
4148 uint64_t file_id;
4150 file_id = make_file_id_from_itime(&smb_fname->st);
4151 update_stat_ex_file_id(&smb_fname->st, file_id);
4155 if (info != FILE_WAS_OPENED) {
4156 /* Overwritten files should be initially set as archive */
4157 if ((info == FILE_WAS_OVERWRITTEN && lp_map_archive(SNUM(conn))) ||
4158 lp_store_dos_attributes(SNUM(conn))) {
4159 (void)fdos_mode(fsp);
4160 if (!posix_open) {
4161 if (file_set_dosmode(conn, smb_fname,
4162 new_dos_attributes | FILE_ATTRIBUTE_ARCHIVE,
4163 parent_dir_fname, true) == 0) {
4164 unx_mode = smb_fname->st.st_ex_mode;
4170 /* Determine sparse flag. */
4171 if (posix_open) {
4172 /* POSIX opens are sparse by default. */
4173 fsp->fsp_flags.is_sparse = true;
4174 } else {
4175 fsp->fsp_flags.is_sparse =
4176 (existing_dos_attributes & FILE_ATTRIBUTE_SPARSE);
4180 * Take care of inherited ACLs on created files - if default ACL not
4181 * selected.
4184 if (!posix_open && new_file_created && !def_acl) {
4185 if (unx_mode != smb_fname->st.st_ex_mode) {
4186 int ret = SMB_VFS_FCHMOD(fsp, unx_mode);
4187 if (ret == -1) {
4188 DBG_INFO("failed to reset "
4189 "attributes of file %s to 0%o\n",
4190 smb_fname_str_dbg(smb_fname),
4191 (unsigned int)unx_mode);
4195 } else if (new_unx_mode) {
4197 * We only get here in the case of:
4199 * a). Not a POSIX open.
4200 * b). File already existed.
4201 * c). File was overwritten.
4202 * d). Requested DOS attributes didn't match
4203 * the DOS attributes on the existing file.
4205 * In that case new_unx_mode has been set
4206 * equal to the calculated mode (including
4207 * possible inheritance of the mode from the
4208 * containing directory).
4210 * Note this mode was calculated with the
4211 * DOS attribute FILE_ATTRIBUTE_ARCHIVE added,
4212 * so the mode change here is suitable for
4213 * an overwritten file.
4216 if (new_unx_mode != smb_fname->st.st_ex_mode) {
4217 int ret = SMB_VFS_FCHMOD(fsp, new_unx_mode);
4218 if (ret == -1) {
4219 DBG_INFO("failed to reset "
4220 "attributes of file %s to 0%o\n",
4221 smb_fname_str_dbg(smb_fname),
4222 (unsigned int)new_unx_mode);
4229 * Deal with other opens having a modified write time.
4231 struct timespec write_time = get_share_mode_write_time(lck);
4233 if (!is_omit_timespec(&write_time)) {
4234 update_stat_ex_mtime(&fsp->fsp_name->st, write_time);
4238 TALLOC_FREE(lck);
4240 return NT_STATUS_OK;
4243 static NTSTATUS mkdir_internal(connection_struct *conn,
4244 struct smb_filename *parent_dir_fname, /* parent. */
4245 struct smb_filename *smb_fname_atname, /* atname relative to parent. */
4246 struct smb_filename *smb_dname, /* full pathname from root of share. */
4247 uint32_t file_attributes,
4248 struct files_struct *fsp)
4250 const struct loadparm_substitution *lp_sub =
4251 loadparm_s3_global_substitution();
4252 mode_t mode;
4253 NTSTATUS status;
4254 bool posix_open = false;
4255 bool need_re_stat = false;
4256 uint32_t access_mask = SEC_DIR_ADD_SUBDIR;
4257 int ret;
4259 if (!CAN_WRITE(conn) || (access_mask & ~(conn->share_access))) {
4260 DEBUG(5,("mkdir_internal: failing share access "
4261 "%s\n", lp_servicename(talloc_tos(), lp_sub, SNUM(conn))));
4262 return NT_STATUS_ACCESS_DENIED;
4265 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
4266 posix_open = true;
4267 mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
4268 } else {
4269 mode = unix_mode(conn,
4270 FILE_ATTRIBUTE_DIRECTORY,
4271 smb_dname,
4272 parent_dir_fname);
4275 status = check_parent_access_fsp(parent_dir_fname->fsp, access_mask);
4276 if(!NT_STATUS_IS_OK(status)) {
4277 DBG_INFO("check_parent_access_fsp "
4278 "on directory %s for path %s returned %s\n",
4279 smb_fname_str_dbg(parent_dir_fname),
4280 smb_dname->base_name,
4281 nt_errstr(status));
4282 return status;
4285 if (lp_inherit_acls(SNUM(conn))) {
4286 if (directory_has_default_acl_fsp(parent_dir_fname->fsp)) {
4287 mode = (0777 & lp_directory_mask(SNUM(conn)));
4291 ret = SMB_VFS_MKDIRAT(conn,
4292 parent_dir_fname->fsp,
4293 smb_fname_atname,
4294 mode);
4295 if (ret != 0) {
4296 return map_nt_error_from_unix(errno);
4300 * Make this a pathref fsp for now. open_directory() will reopen as a
4301 * full fsp.
4303 fsp->fsp_flags.is_pathref = true;
4305 status = fd_openat(conn->cwd_fsp, smb_dname, fsp, O_RDONLY | O_DIRECTORY, 0);
4306 if (!NT_STATUS_IS_OK(status)) {
4307 return status;
4310 /* Ensure we're checking for a symlink here.... */
4311 /* We don't want to get caught by a symlink racer. */
4313 if (SMB_VFS_FSTAT(fsp, &smb_dname->st) == -1) {
4314 DEBUG(2, ("Could not stat directory '%s' just created: %s\n",
4315 smb_fname_str_dbg(smb_dname), strerror(errno)));
4316 return map_nt_error_from_unix(errno);
4319 if (!S_ISDIR(smb_dname->st.st_ex_mode)) {
4320 DEBUG(0, ("Directory '%s' just created is not a directory !\n",
4321 smb_fname_str_dbg(smb_dname)));
4322 return NT_STATUS_NOT_A_DIRECTORY;
4325 smb_dname->st.st_ex_iflags &= ~ST_EX_IFLAG_CALCULATED_ITIME;
4327 if (lp_store_dos_attributes(SNUM(conn))) {
4328 if (smb_dname->st.st_ex_iflags & ST_EX_IFLAG_CALCULATED_FILE_ID)
4330 uint64_t file_id;
4332 file_id = make_file_id_from_itime(&smb_dname->st);
4333 update_stat_ex_file_id(&smb_dname->st, file_id);
4336 if (!posix_open) {
4337 file_set_dosmode(conn, smb_dname,
4338 file_attributes | FILE_ATTRIBUTE_DIRECTORY,
4339 parent_dir_fname, true);
4343 if (lp_inherit_permissions(SNUM(conn))) {
4344 inherit_access_posix_acl(conn, parent_dir_fname,
4345 smb_dname, mode);
4346 need_re_stat = true;
4349 if (!posix_open) {
4351 * Check if high bits should have been set,
4352 * then (if bits are missing): add them.
4353 * Consider bits automagically set by UNIX, i.e. SGID bit from parent
4354 * dir.
4356 if ((mode & ~(S_IRWXU|S_IRWXG|S_IRWXO)) &&
4357 (mode & ~smb_dname->st.st_ex_mode)) {
4358 SMB_VFS_FCHMOD(fsp,
4359 (smb_dname->st.st_ex_mode |
4360 (mode & ~smb_dname->st.st_ex_mode)));
4361 need_re_stat = true;
4365 /* Change the owner if required. */
4366 if (lp_inherit_owner(SNUM(conn)) != INHERIT_OWNER_NO) {
4367 change_dir_owner_to_parent_fsp(parent_dir_fname->fsp,
4368 fsp);
4369 need_re_stat = true;
4372 if (need_re_stat) {
4373 if (SMB_VFS_FSTAT(fsp, &smb_dname->st) == -1) {
4374 DEBUG(2, ("Could not stat directory '%s' just created: %s\n",
4375 smb_fname_str_dbg(smb_dname), strerror(errno)));
4376 return map_nt_error_from_unix(errno);
4380 notify_fname(conn, NOTIFY_ACTION_ADDED, FILE_NOTIFY_CHANGE_DIR_NAME,
4381 smb_dname->base_name);
4383 return NT_STATUS_OK;
4386 /****************************************************************************
4387 Open a directory from an NT SMB call.
4388 ****************************************************************************/
4390 static NTSTATUS open_directory(connection_struct *conn,
4391 struct smb_request *req,
4392 uint32_t access_mask,
4393 uint32_t share_access,
4394 uint32_t create_disposition,
4395 uint32_t create_options,
4396 uint32_t file_attributes,
4397 struct smb_filename *parent_dir_fname,
4398 struct smb_filename *smb_fname_atname,
4399 int *pinfo,
4400 struct files_struct *fsp)
4402 struct smb_filename *smb_dname = fsp->fsp_name;
4403 bool dir_existed = VALID_STAT(smb_dname->st);
4404 struct share_mode_lock *lck = NULL;
4405 NTSTATUS status;
4406 struct timespec mtimespec;
4407 int info = 0;
4408 bool ok;
4409 uint32_t need_fd_access;
4411 if (is_ntfs_stream_smb_fname(smb_dname)) {
4412 DEBUG(2, ("open_directory: %s is a stream name!\n",
4413 smb_fname_str_dbg(smb_dname)));
4414 return NT_STATUS_NOT_A_DIRECTORY;
4417 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS)) {
4418 /* Ensure we have a directory attribute. */
4419 file_attributes |= FILE_ATTRIBUTE_DIRECTORY;
4422 DBG_INFO("opening directory %s, access_mask = 0x%"PRIx32", "
4423 "share_access = 0x%"PRIx32" create_options = 0x%"PRIx32", "
4424 "create_disposition = 0x%"PRIx32", "
4425 "file_attributes = 0x%"PRIx32"\n",
4426 smb_fname_str_dbg(smb_dname),
4427 access_mask,
4428 share_access,
4429 create_options,
4430 create_disposition,
4431 file_attributes);
4433 status = smbd_calculate_access_mask_fsp(parent_dir_fname->fsp,
4434 smb_dname->fsp,
4435 false,
4436 access_mask,
4437 &access_mask);
4438 if (!NT_STATUS_IS_OK(status)) {
4439 DBG_DEBUG("smbd_calculate_access_mask_fsp "
4440 "on file %s returned %s\n",
4441 smb_fname_str_dbg(smb_dname),
4442 nt_errstr(status));
4443 return status;
4446 if ((access_mask & SEC_FLAG_SYSTEM_SECURITY) &&
4447 !security_token_has_privilege(get_current_nttok(conn),
4448 SEC_PRIV_SECURITY)) {
4449 DEBUG(10, ("open_directory: open on %s "
4450 "failed - SEC_FLAG_SYSTEM_SECURITY denied.\n",
4451 smb_fname_str_dbg(smb_dname)));
4452 return NT_STATUS_PRIVILEGE_NOT_HELD;
4455 switch( create_disposition ) {
4456 case FILE_OPEN:
4458 if (!dir_existed) {
4459 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4462 info = FILE_WAS_OPENED;
4463 break;
4465 case FILE_CREATE:
4467 /* If directory exists error. If directory doesn't
4468 * exist create. */
4470 if (dir_existed) {
4471 status = NT_STATUS_OBJECT_NAME_COLLISION;
4472 DEBUG(2, ("open_directory: unable to create "
4473 "%s. Error was %s\n",
4474 smb_fname_str_dbg(smb_dname),
4475 nt_errstr(status)));
4476 return status;
4479 status = mkdir_internal(conn,
4480 parent_dir_fname,
4481 smb_fname_atname,
4482 smb_dname,
4483 file_attributes,
4484 fsp);
4486 if (!NT_STATUS_IS_OK(status)) {
4487 DEBUG(2, ("open_directory: unable to create "
4488 "%s. Error was %s\n",
4489 smb_fname_str_dbg(smb_dname),
4490 nt_errstr(status)));
4491 return status;
4494 info = FILE_WAS_CREATED;
4495 break;
4497 case FILE_OPEN_IF:
4499 * If directory exists open. If directory doesn't
4500 * exist create.
4503 if (dir_existed) {
4504 status = NT_STATUS_OK;
4505 info = FILE_WAS_OPENED;
4506 } else {
4507 status = mkdir_internal(conn,
4508 parent_dir_fname,
4509 smb_fname_atname,
4510 smb_dname,
4511 file_attributes,
4512 fsp);
4514 if (NT_STATUS_IS_OK(status)) {
4515 info = FILE_WAS_CREATED;
4516 } else {
4517 /* Cope with create race. */
4518 if (!NT_STATUS_EQUAL(status,
4519 NT_STATUS_OBJECT_NAME_COLLISION)) {
4520 DEBUG(2, ("open_directory: unable to create "
4521 "%s. Error was %s\n",
4522 smb_fname_str_dbg(smb_dname),
4523 nt_errstr(status)));
4524 return status;
4528 * If mkdir_internal() returned
4529 * NT_STATUS_OBJECT_NAME_COLLISION
4530 * we still must lstat the path.
4533 if (SMB_VFS_LSTAT(conn, smb_dname)
4534 == -1) {
4535 DEBUG(2, ("Could not stat "
4536 "directory '%s' just "
4537 "opened: %s\n",
4538 smb_fname_str_dbg(
4539 smb_dname),
4540 strerror(errno)));
4541 return map_nt_error_from_unix(
4542 errno);
4545 info = FILE_WAS_OPENED;
4549 break;
4551 case FILE_SUPERSEDE:
4552 case FILE_OVERWRITE:
4553 case FILE_OVERWRITE_IF:
4554 default:
4555 DEBUG(5,("open_directory: invalid create_disposition "
4556 "0x%x for directory %s\n",
4557 (unsigned int)create_disposition,
4558 smb_fname_str_dbg(smb_dname)));
4559 return NT_STATUS_INVALID_PARAMETER;
4562 if(!S_ISDIR(smb_dname->st.st_ex_mode)) {
4563 DEBUG(5,("open_directory: %s is not a directory !\n",
4564 smb_fname_str_dbg(smb_dname)));
4565 return NT_STATUS_NOT_A_DIRECTORY;
4569 * Setup the files_struct for it.
4572 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_dname->st);
4573 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
4574 fsp->file_pid = req ? req->smbpid : 0;
4575 fsp->fsp_flags.can_lock = false;
4576 fsp->fsp_flags.can_read = false;
4577 fsp->fsp_flags.can_write = false;
4579 fh_set_private_options(fsp->fh, 0);
4581 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
4583 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
4584 fsp->print_file = NULL;
4585 fsp->fsp_flags.modified = false;
4586 fsp->oplock_type = NO_OPLOCK;
4587 fsp->sent_oplock_break = NO_BREAK_SENT;
4588 fsp->fsp_flags.is_directory = true;
4589 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
4590 fsp->posix_flags |= FSP_POSIX_FLAGS_ALL;
4593 /* Don't store old timestamps for directory
4594 handles in the internal database. We don't
4595 update them in there if new objects
4596 are created in the directory. Currently
4597 we only update timestamps on file writes.
4598 See bug #9870.
4600 mtimespec = make_omit_timespec();
4603 * Obviously for FILE_LIST_DIRECTORY we need to reopen to get an fd
4604 * usable for reading a directory. SMB2_FLUSH may be called on
4605 * directories opened with FILE_ADD_FILE and FILE_ADD_SUBDIRECTORY so
4606 * for those we need to reopen as well.
4608 need_fd_access =
4609 FILE_LIST_DIRECTORY |
4610 FILE_ADD_FILE |
4611 FILE_ADD_SUBDIRECTORY;
4613 if (access_mask & need_fd_access) {
4614 status = reopen_from_fsp(fsp, O_RDONLY | O_DIRECTORY, 0, NULL);
4615 if (!NT_STATUS_IS_OK(status)) {
4616 DBG_INFO("Could not open fd for [%s]: %s\n",
4617 smb_fname_str_dbg(smb_dname),
4618 nt_errstr(status));
4619 return status;
4623 status = vfs_stat_fsp(fsp);
4624 if (!NT_STATUS_IS_OK(status)) {
4625 fd_close(fsp);
4626 return status;
4629 if(!S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
4630 DEBUG(5,("open_directory: %s is not a directory !\n",
4631 smb_fname_str_dbg(smb_dname)));
4632 fd_close(fsp);
4633 return NT_STATUS_NOT_A_DIRECTORY;
4636 /* Ensure there was no race condition. We need to check
4637 * dev/inode but not permissions, as these can change
4638 * legitimately */
4639 if (!check_same_dev_ino(&smb_dname->st, &fsp->fsp_name->st)) {
4640 DEBUG(5,("open_directory: stat struct differs for "
4641 "directory %s.\n",
4642 smb_fname_str_dbg(smb_dname)));
4643 fd_close(fsp);
4644 return NT_STATUS_ACCESS_DENIED;
4647 if (info == FILE_WAS_OPENED) {
4648 status = smbd_check_access_rights_fsp(parent_dir_fname->fsp,
4649 fsp,
4650 false,
4651 access_mask);
4652 if (!NT_STATUS_IS_OK(status)) {
4653 DBG_DEBUG("smbd_check_access_rights_fsp on "
4654 "file %s failed with %s\n",
4655 fsp_str_dbg(fsp),
4656 nt_errstr(status));
4657 fd_close(fsp);
4658 return status;
4662 lck = get_share_mode_lock(talloc_tos(), fsp->file_id,
4663 conn->connectpath, smb_dname,
4664 &mtimespec);
4666 if (lck == NULL) {
4667 DEBUG(0, ("open_directory: Could not get share mode lock for "
4668 "%s\n", smb_fname_str_dbg(smb_dname)));
4669 fd_close(fsp);
4670 return NT_STATUS_SHARING_VIOLATION;
4673 if (has_delete_on_close(lck, fsp->name_hash)) {
4674 TALLOC_FREE(lck);
4675 fd_close(fsp);
4676 return NT_STATUS_DELETE_PENDING;
4679 status = open_mode_check(conn, fsp->file_id, lck,
4680 access_mask, share_access);
4682 if (!NT_STATUS_IS_OK(status)) {
4683 TALLOC_FREE(lck);
4684 fd_close(fsp);
4685 return status;
4688 share_mode_flags_restrict(lck, access_mask, share_access, 0);
4690 ok = set_share_mode(
4691 lck,
4692 fsp,
4693 get_current_uid(conn),
4694 req ? req->mid : 0,
4695 NO_OPLOCK,
4696 share_access,
4697 fsp->access_mask);
4698 if (!ok) {
4699 TALLOC_FREE(lck);
4700 fd_close(fsp);
4701 return NT_STATUS_NO_MEMORY;
4704 /* For directories the delete on close bit at open time seems
4705 always to be honored on close... See test 19 in Samba4 BASE-DELETE. */
4706 if (create_options & FILE_DELETE_ON_CLOSE) {
4707 status = can_set_delete_on_close(fsp, 0);
4708 if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
4709 del_share_mode(lck, fsp);
4710 TALLOC_FREE(lck);
4711 fd_close(fsp);
4712 return status;
4715 if (NT_STATUS_IS_OK(status)) {
4716 /* Note that here we set the *initial* delete on close flag,
4717 not the regular one. The magic gets handled in close. */
4718 fsp->fsp_flags.initial_delete_on_close = true;
4724 * Deal with other opens having a modified write time. Is this
4725 * possible for directories?
4727 struct timespec write_time = get_share_mode_write_time(lck);
4729 if (!is_omit_timespec(&write_time)) {
4730 update_stat_ex_mtime(&fsp->fsp_name->st, write_time);
4734 TALLOC_FREE(lck);
4736 if (pinfo) {
4737 *pinfo = info;
4740 return NT_STATUS_OK;
4743 NTSTATUS create_directory(connection_struct *conn, struct smb_request *req,
4744 struct smb_filename *smb_dname)
4746 NTSTATUS status;
4747 files_struct *fsp;
4749 status = SMB_VFS_CREATE_FILE(
4750 conn, /* conn */
4751 req, /* req */
4752 smb_dname, /* fname */
4753 FILE_READ_ATTRIBUTES, /* access_mask */
4754 FILE_SHARE_NONE, /* share_access */
4755 FILE_CREATE, /* create_disposition*/
4756 FILE_DIRECTORY_FILE, /* create_options */
4757 FILE_ATTRIBUTE_DIRECTORY, /* file_attributes */
4758 0, /* oplock_request */
4759 NULL, /* lease */
4760 0, /* allocation_size */
4761 0, /* private_flags */
4762 NULL, /* sd */
4763 NULL, /* ea_list */
4764 &fsp, /* result */
4765 NULL, /* pinfo */
4766 NULL, NULL); /* create context */
4768 if (NT_STATUS_IS_OK(status)) {
4769 close_file(req, fsp, NORMAL_CLOSE);
4772 return status;
4775 /****************************************************************************
4776 Receive notification that one of our open files has been renamed by another
4777 smbd process.
4778 ****************************************************************************/
4780 void msg_file_was_renamed(struct messaging_context *msg_ctx,
4781 void *private_data,
4782 uint32_t msg_type,
4783 struct server_id src,
4784 DATA_BLOB *data)
4786 struct file_rename_message *msg = NULL;
4787 enum ndr_err_code ndr_err;
4788 files_struct *fsp;
4789 struct smb_filename *smb_fname = NULL;
4790 struct smbd_server_connection *sconn =
4791 talloc_get_type_abort(private_data,
4792 struct smbd_server_connection);
4794 msg = talloc(talloc_tos(), struct file_rename_message);
4795 if (msg == NULL) {
4796 DBG_WARNING("talloc failed\n");
4797 return;
4800 ndr_err = ndr_pull_struct_blob_all(
4801 data,
4802 msg,
4803 msg,
4804 (ndr_pull_flags_fn_t)ndr_pull_file_rename_message);
4805 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
4806 DBG_DEBUG("ndr_pull_oplock_break_message failed: %s\n",
4807 ndr_errstr(ndr_err));
4808 goto out;
4810 if (DEBUGLEVEL >= 10) {
4811 struct server_id_buf buf;
4812 DBG_DEBUG("Got rename message from %s\n",
4813 server_id_str_buf(src, &buf));
4814 NDR_PRINT_DEBUG(file_rename_message, msg);
4817 /* stream_name must always be NULL if there is no stream. */
4818 if ((msg->stream_name != NULL) && (msg->stream_name[0] == '\0')) {
4819 msg->stream_name = NULL;
4822 smb_fname = synthetic_smb_fname(msg,
4823 msg->base_name,
4824 msg->stream_name,
4825 NULL,
4828 if (smb_fname == NULL) {
4829 DBG_DEBUG("synthetic_smb_fname failed\n");
4830 goto out;
4833 fsp = file_find_dif(sconn, msg->id, msg->share_file_id);
4834 if (fsp == NULL) {
4835 DBG_DEBUG("fsp not found\n");
4836 goto out;
4839 if (strcmp(fsp->conn->connectpath, msg->servicepath) == 0) {
4840 NTSTATUS status;
4841 DBG_DEBUG("renaming file %s from %s -> %s\n",
4842 fsp_fnum_dbg(fsp),
4843 fsp_str_dbg(fsp),
4844 smb_fname_str_dbg(smb_fname));
4845 status = fsp_set_smb_fname(fsp, smb_fname);
4846 if (!NT_STATUS_IS_OK(status)) {
4847 DBG_DEBUG("fsp_set_smb_fname failed: %s\n",
4848 nt_errstr(status));
4850 } else {
4851 /* TODO. JRA. */
4853 * Now we have the complete path we can work out if
4854 * this is actually within this share and adjust
4855 * newname accordingly.
4857 DBG_DEBUG("share mismatch (sharepath %s not sharepath %s) "
4858 "%s from %s -> %s\n",
4859 fsp->conn->connectpath,
4860 msg->servicepath,
4861 fsp_fnum_dbg(fsp),
4862 fsp_str_dbg(fsp),
4863 smb_fname_str_dbg(smb_fname));
4865 out:
4866 TALLOC_FREE(msg);
4870 * If a main file is opened for delete, all streams need to be checked for
4871 * !FILE_SHARE_DELETE. Do this by opening with DELETE_ACCESS.
4872 * If that works, delete them all by setting the delete on close and close.
4875 static NTSTATUS open_streams_for_delete(connection_struct *conn,
4876 const struct smb_filename *smb_fname)
4878 struct stream_struct *stream_info = NULL;
4879 files_struct **streams = NULL;
4880 int j;
4881 unsigned int i, num_streams = 0;
4882 TALLOC_CTX *frame = talloc_stackframe();
4883 const struct smb_filename *pathref = NULL;
4884 NTSTATUS status;
4886 if (smb_fname->fsp == NULL) {
4887 struct smb_filename *tmp = NULL;
4888 status = synthetic_pathref(frame,
4889 conn->cwd_fsp,
4890 smb_fname->base_name,
4891 NULL,
4892 NULL,
4893 smb_fname->twrp,
4894 smb_fname->flags,
4895 &tmp);
4896 if (!NT_STATUS_IS_OK(status)) {
4897 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
4898 || NT_STATUS_EQUAL(status,
4899 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4900 DBG_DEBUG("no streams around\n");
4901 TALLOC_FREE(frame);
4902 return NT_STATUS_OK;
4904 DBG_DEBUG("synthetic_pathref failed: %s\n",
4905 nt_errstr(status));
4906 goto fail;
4908 pathref = tmp;
4909 } else {
4910 pathref = smb_fname;
4912 status = vfs_fstreaminfo(pathref->fsp, talloc_tos(),
4913 &num_streams, &stream_info);
4915 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
4916 || NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4917 DEBUG(10, ("no streams around\n"));
4918 TALLOC_FREE(frame);
4919 return NT_STATUS_OK;
4922 if (!NT_STATUS_IS_OK(status)) {
4923 DEBUG(10, ("vfs_fstreaminfo failed: %s\n",
4924 nt_errstr(status)));
4925 goto fail;
4928 DEBUG(10, ("open_streams_for_delete found %d streams\n",
4929 num_streams));
4931 if (num_streams == 0) {
4932 TALLOC_FREE(frame);
4933 return NT_STATUS_OK;
4936 streams = talloc_array(talloc_tos(), files_struct *, num_streams);
4937 if (streams == NULL) {
4938 DEBUG(0, ("talloc failed\n"));
4939 status = NT_STATUS_NO_MEMORY;
4940 goto fail;
4943 for (i=0; i<num_streams; i++) {
4944 struct smb_filename *smb_fname_cp;
4946 if (strequal(stream_info[i].name, "::$DATA")) {
4947 streams[i] = NULL;
4948 continue;
4951 smb_fname_cp = synthetic_smb_fname(talloc_tos(),
4952 smb_fname->base_name,
4953 stream_info[i].name,
4954 NULL,
4955 smb_fname->twrp,
4956 (smb_fname->flags &
4957 ~SMB_FILENAME_POSIX_PATH));
4958 if (smb_fname_cp == NULL) {
4959 status = NT_STATUS_NO_MEMORY;
4960 goto fail;
4963 if (SMB_VFS_STAT(conn, smb_fname_cp) == -1) {
4964 DEBUG(10, ("Unable to stat stream: %s\n",
4965 smb_fname_str_dbg(smb_fname_cp)));
4968 status = openat_pathref_fsp(conn->cwd_fsp, smb_fname_cp);
4969 if (!NT_STATUS_IS_OK(status)) {
4970 DBG_DEBUG("Unable to open stream [%s]: %s\n",
4971 smb_fname_str_dbg(smb_fname_cp),
4972 nt_errstr(status));
4973 TALLOC_FREE(smb_fname_cp);
4974 break;
4977 status = SMB_VFS_CREATE_FILE(
4978 conn, /* conn */
4979 NULL, /* req */
4980 smb_fname_cp, /* fname */
4981 DELETE_ACCESS, /* access_mask */
4982 (FILE_SHARE_READ | /* share_access */
4983 FILE_SHARE_WRITE | FILE_SHARE_DELETE),
4984 FILE_OPEN, /* create_disposition*/
4985 0, /* create_options */
4986 FILE_ATTRIBUTE_NORMAL, /* file_attributes */
4987 0, /* oplock_request */
4988 NULL, /* lease */
4989 0, /* allocation_size */
4990 0, /* private_flags */
4991 NULL, /* sd */
4992 NULL, /* ea_list */
4993 &streams[i], /* result */
4994 NULL, /* pinfo */
4995 NULL, NULL); /* create context */
4997 if (!NT_STATUS_IS_OK(status)) {
4998 DEBUG(10, ("Could not open stream %s: %s\n",
4999 smb_fname_str_dbg(smb_fname_cp),
5000 nt_errstr(status)));
5002 TALLOC_FREE(smb_fname_cp);
5003 break;
5005 TALLOC_FREE(smb_fname_cp);
5009 * don't touch the variable "status" beyond this point :-)
5012 for (j = i-1 ; j >= 0; j--) {
5013 if (streams[j] == NULL) {
5014 continue;
5017 DEBUG(10, ("Closing stream # %d, %s\n", j,
5018 fsp_str_dbg(streams[j])));
5019 close_file(NULL, streams[j], NORMAL_CLOSE);
5022 fail:
5023 TALLOC_FREE(frame);
5024 return status;
5027 /*********************************************************************
5028 Create a default ACL by inheriting from the parent. If no inheritance
5029 from the parent available, don't set anything. This will leave the actual
5030 permissions the new file or directory already got from the filesystem
5031 as the NT ACL when read.
5032 *********************************************************************/
5034 static NTSTATUS inherit_new_acl(struct smb_filename *parent_dir_fname,
5035 files_struct *fsp)
5037 TALLOC_CTX *frame = talloc_stackframe();
5038 struct security_descriptor *parent_desc = NULL;
5039 NTSTATUS status = NT_STATUS_OK;
5040 struct security_descriptor *psd = NULL;
5041 const struct dom_sid *owner_sid = NULL;
5042 const struct dom_sid *group_sid = NULL;
5043 uint32_t security_info_sent = (SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL);
5044 struct security_token *token = fsp->conn->session_info->security_token;
5045 bool inherit_owner =
5046 (lp_inherit_owner(SNUM(fsp->conn)) == INHERIT_OWNER_WINDOWS_AND_UNIX);
5047 bool inheritable_components = false;
5048 bool try_builtin_administrators = false;
5049 const struct dom_sid *BA_U_sid = NULL;
5050 const struct dom_sid *BA_G_sid = NULL;
5051 bool try_system = false;
5052 const struct dom_sid *SY_U_sid = NULL;
5053 const struct dom_sid *SY_G_sid = NULL;
5054 size_t size = 0;
5055 bool ok;
5057 status = SMB_VFS_FGET_NT_ACL(parent_dir_fname->fsp,
5058 (SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL),
5059 frame,
5060 &parent_desc);
5061 if (!NT_STATUS_IS_OK(status)) {
5062 TALLOC_FREE(frame);
5063 return status;
5066 inheritable_components = sd_has_inheritable_components(parent_desc,
5067 fsp->fsp_flags.is_directory);
5069 if (!inheritable_components && !inherit_owner) {
5070 TALLOC_FREE(frame);
5071 /* Nothing to inherit and not setting owner. */
5072 return NT_STATUS_OK;
5075 /* Create an inherited descriptor from the parent. */
5077 if (DEBUGLEVEL >= 10) {
5078 DEBUG(10,("inherit_new_acl: parent acl for %s is:\n",
5079 fsp_str_dbg(fsp) ));
5080 NDR_PRINT_DEBUG(security_descriptor, parent_desc);
5083 /* Inherit from parent descriptor if "inherit owner" set. */
5084 if (inherit_owner) {
5085 owner_sid = parent_desc->owner_sid;
5086 group_sid = parent_desc->group_sid;
5089 if (owner_sid == NULL) {
5090 if (security_token_has_builtin_administrators(token)) {
5091 try_builtin_administrators = true;
5092 } else if (security_token_is_system(token)) {
5093 try_builtin_administrators = true;
5094 try_system = true;
5098 if (group_sid == NULL &&
5099 token->num_sids == PRIMARY_GROUP_SID_INDEX)
5101 if (security_token_is_system(token)) {
5102 try_builtin_administrators = true;
5103 try_system = true;
5107 if (try_builtin_administrators) {
5108 struct unixid ids;
5110 ZERO_STRUCT(ids);
5111 ok = sids_to_unixids(&global_sid_Builtin_Administrators, 1, &ids);
5112 if (ok) {
5113 switch (ids.type) {
5114 case ID_TYPE_BOTH:
5115 BA_U_sid = &global_sid_Builtin_Administrators;
5116 BA_G_sid = &global_sid_Builtin_Administrators;
5117 break;
5118 case ID_TYPE_UID:
5119 BA_U_sid = &global_sid_Builtin_Administrators;
5120 break;
5121 case ID_TYPE_GID:
5122 BA_G_sid = &global_sid_Builtin_Administrators;
5123 break;
5124 default:
5125 break;
5130 if (try_system) {
5131 struct unixid ids;
5133 ZERO_STRUCT(ids);
5134 ok = sids_to_unixids(&global_sid_System, 1, &ids);
5135 if (ok) {
5136 switch (ids.type) {
5137 case ID_TYPE_BOTH:
5138 SY_U_sid = &global_sid_System;
5139 SY_G_sid = &global_sid_System;
5140 break;
5141 case ID_TYPE_UID:
5142 SY_U_sid = &global_sid_System;
5143 break;
5144 case ID_TYPE_GID:
5145 SY_G_sid = &global_sid_System;
5146 break;
5147 default:
5148 break;
5153 if (owner_sid == NULL) {
5154 owner_sid = BA_U_sid;
5157 if (owner_sid == NULL) {
5158 owner_sid = SY_U_sid;
5161 if (group_sid == NULL) {
5162 group_sid = SY_G_sid;
5165 if (try_system && group_sid == NULL) {
5166 group_sid = BA_G_sid;
5169 if (owner_sid == NULL) {
5170 owner_sid = &token->sids[PRIMARY_USER_SID_INDEX];
5172 if (group_sid == NULL) {
5173 if (token->num_sids == PRIMARY_GROUP_SID_INDEX) {
5174 group_sid = &token->sids[PRIMARY_USER_SID_INDEX];
5175 } else {
5176 group_sid = &token->sids[PRIMARY_GROUP_SID_INDEX];
5180 status = se_create_child_secdesc(frame,
5181 &psd,
5182 &size,
5183 parent_desc,
5184 owner_sid,
5185 group_sid,
5186 fsp->fsp_flags.is_directory);
5187 if (!NT_STATUS_IS_OK(status)) {
5188 TALLOC_FREE(frame);
5189 return status;
5192 /* If inheritable_components == false,
5193 se_create_child_secdesc()
5194 creates a security descriptor with a NULL dacl
5195 entry, but with SEC_DESC_DACL_PRESENT. We need
5196 to remove that flag. */
5198 if (!inheritable_components) {
5199 security_info_sent &= ~SECINFO_DACL;
5200 psd->type &= ~SEC_DESC_DACL_PRESENT;
5203 if (DEBUGLEVEL >= 10) {
5204 DEBUG(10,("inherit_new_acl: child acl for %s is:\n",
5205 fsp_str_dbg(fsp) ));
5206 NDR_PRINT_DEBUG(security_descriptor, psd);
5209 if (inherit_owner) {
5210 /* We need to be root to force this. */
5211 become_root();
5213 status = SMB_VFS_FSET_NT_ACL(fsp,
5214 security_info_sent,
5215 psd);
5216 if (inherit_owner) {
5217 unbecome_root();
5219 TALLOC_FREE(frame);
5220 return status;
5224 * If we already have a lease, it must match the new file id. [MS-SMB2]
5225 * 3.3.5.9.8 speaks about INVALID_PARAMETER if an already used lease key is
5226 * used for a different file name.
5229 struct lease_match_state {
5230 /* Input parameters. */
5231 TALLOC_CTX *mem_ctx;
5232 const char *servicepath;
5233 const struct smb_filename *fname;
5234 bool file_existed;
5235 struct file_id id;
5236 /* Return parameters. */
5237 uint32_t num_file_ids;
5238 struct file_id *ids;
5239 NTSTATUS match_status;
5242 /*************************************************************
5243 File doesn't exist but this lease key+guid is already in use.
5245 This is only allowable in the dynamic share case where the
5246 service path must be different.
5248 There is a small race condition here in the multi-connection
5249 case where a client sends two create calls on different connections,
5250 where the file doesn't exist and one smbd creates the leases_db
5251 entry first, but this will get fixed by the multichannel cleanup
5252 when all identical client_guids get handled by a single smbd.
5253 **************************************************************/
5255 static void lease_match_parser_new_file(
5256 uint32_t num_files,
5257 const struct leases_db_file *files,
5258 struct lease_match_state *state)
5260 uint32_t i;
5262 for (i = 0; i < num_files; i++) {
5263 const struct leases_db_file *f = &files[i];
5264 if (strequal(state->servicepath, f->servicepath)) {
5265 state->match_status = NT_STATUS_INVALID_PARAMETER;
5266 return;
5270 /* Dynamic share case. Break leases on all other files. */
5271 state->match_status = leases_db_copy_file_ids(state->mem_ctx,
5272 num_files,
5273 files,
5274 &state->ids);
5275 if (!NT_STATUS_IS_OK(state->match_status)) {
5276 return;
5279 state->num_file_ids = num_files;
5280 state->match_status = NT_STATUS_OPLOCK_NOT_GRANTED;
5281 return;
5284 static void lease_match_parser(
5285 uint32_t num_files,
5286 const struct leases_db_file *files,
5287 void *private_data)
5289 struct lease_match_state *state =
5290 (struct lease_match_state *)private_data;
5291 uint32_t i;
5293 if (!state->file_existed) {
5295 * Deal with name mismatch or
5296 * possible dynamic share case separately
5297 * to make code clearer.
5299 lease_match_parser_new_file(num_files,
5300 files,
5301 state);
5302 return;
5305 /* File existed. */
5306 state->match_status = NT_STATUS_OK;
5308 for (i = 0; i < num_files; i++) {
5309 const struct leases_db_file *f = &files[i];
5311 /* Everything should be the same. */
5312 if (!file_id_equal(&state->id, &f->id)) {
5313 /* This should catch all dynamic share cases. */
5314 state->match_status = NT_STATUS_OPLOCK_NOT_GRANTED;
5315 break;
5317 if (!strequal(f->servicepath, state->servicepath)) {
5318 state->match_status = NT_STATUS_INVALID_PARAMETER;
5319 break;
5321 if (!strequal(f->base_name, state->fname->base_name)) {
5322 state->match_status = NT_STATUS_INVALID_PARAMETER;
5323 break;
5325 if (!strequal(f->stream_name, state->fname->stream_name)) {
5326 state->match_status = NT_STATUS_INVALID_PARAMETER;
5327 break;
5331 if (NT_STATUS_IS_OK(state->match_status)) {
5333 * Common case - just opening another handle on a
5334 * file on a non-dynamic share.
5336 return;
5339 if (NT_STATUS_EQUAL(state->match_status, NT_STATUS_INVALID_PARAMETER)) {
5340 /* Mismatched path. Error back to client. */
5341 return;
5345 * File id mismatch. Dynamic share case NT_STATUS_OPLOCK_NOT_GRANTED.
5346 * Don't allow leases.
5349 state->match_status = leases_db_copy_file_ids(state->mem_ctx,
5350 num_files,
5351 files,
5352 &state->ids);
5353 if (!NT_STATUS_IS_OK(state->match_status)) {
5354 return;
5357 state->num_file_ids = num_files;
5358 state->match_status = NT_STATUS_OPLOCK_NOT_GRANTED;
5359 return;
5362 struct lease_match_break_state {
5363 struct messaging_context *msg_ctx;
5364 const struct smb2_lease_key *lease_key;
5365 struct file_id id;
5367 bool found_lease;
5368 uint16_t version;
5369 uint16_t epoch;
5372 static bool lease_match_break_fn(
5373 struct share_mode_entry *e,
5374 void *private_data)
5376 struct lease_match_break_state *state = private_data;
5377 bool stale, equal;
5378 uint32_t e_lease_type;
5379 NTSTATUS status;
5381 stale = share_entry_stale_pid(e);
5382 if (stale) {
5383 return false;
5386 equal = smb2_lease_key_equal(&e->lease_key, state->lease_key);
5387 if (!equal) {
5388 return false;
5391 status = leases_db_get(
5392 &e->client_guid,
5393 &e->lease_key,
5394 &state->id,
5395 NULL, /* current_state */
5396 NULL, /* breaking */
5397 NULL, /* breaking_to_requested */
5398 NULL, /* breaking_to_required */
5399 &state->version, /* lease_version */
5400 &state->epoch); /* epoch */
5401 if (NT_STATUS_IS_OK(status)) {
5402 state->found_lease = true;
5403 } else {
5404 DBG_WARNING("Could not find version/epoch: %s\n",
5405 nt_errstr(status));
5408 e_lease_type = get_lease_type(e, state->id);
5409 if (e_lease_type == SMB2_LEASE_NONE) {
5410 return false;
5412 send_break_message(state->msg_ctx, &state->id, e, SMB2_LEASE_NONE);
5415 * Windows 7 and 8 lease clients are broken in that they will
5416 * not respond to lease break requests whilst waiting for an
5417 * outstanding open request on that lease handle on the same
5418 * TCP connection, due to holding an internal inode lock.
5420 * This means we can't reschedule ourselves here, but must
5421 * return from the create.
5423 * Work around:
5425 * Send the breaks and then return SMB2_LEASE_NONE in the
5426 * lease handle to cause them to acknowledge the lease
5427 * break. Consultation with Microsoft engineering confirmed
5428 * this approach is safe.
5431 return false;
5434 static NTSTATUS lease_match(connection_struct *conn,
5435 struct smb_request *req,
5436 const struct smb2_lease_key *lease_key,
5437 const char *servicepath,
5438 const struct smb_filename *fname,
5439 uint16_t *p_version,
5440 uint16_t *p_epoch)
5442 struct smbd_server_connection *sconn = req->sconn;
5443 TALLOC_CTX *tos = talloc_tos();
5444 struct lease_match_state state = {
5445 .mem_ctx = tos,
5446 .servicepath = servicepath,
5447 .fname = fname,
5448 .match_status = NT_STATUS_OK
5450 uint32_t i;
5451 NTSTATUS status;
5453 state.file_existed = VALID_STAT(fname->st);
5454 if (state.file_existed) {
5455 state.id = vfs_file_id_from_sbuf(conn, &fname->st);
5458 status = leases_db_parse(&sconn->client->global->client_guid,
5459 lease_key, lease_match_parser, &state);
5460 if (!NT_STATUS_IS_OK(status)) {
5462 * Not found or error means okay: We can make the lease pass
5464 return NT_STATUS_OK;
5466 if (!NT_STATUS_EQUAL(state.match_status, NT_STATUS_OPLOCK_NOT_GRANTED)) {
5468 * Anything but NT_STATUS_OPLOCK_NOT_GRANTED, let the caller
5469 * deal with it.
5471 return state.match_status;
5474 /* We have to break all existing leases. */
5475 for (i = 0; i < state.num_file_ids; i++) {
5476 struct lease_match_break_state break_state = {
5477 .msg_ctx = conn->sconn->msg_ctx,
5478 .lease_key = lease_key,
5480 struct share_mode_lock *lck;
5481 bool ok;
5483 if (file_id_equal(&state.ids[i], &state.id)) {
5484 /* Don't need to break our own file. */
5485 continue;
5488 break_state.id = state.ids[i];
5490 lck = get_existing_share_mode_lock(
5491 talloc_tos(), break_state.id);
5492 if (lck == NULL) {
5493 /* Race condition - file already closed. */
5494 continue;
5497 ok = share_mode_forall_leases(
5498 lck, lease_match_break_fn, &break_state);
5499 if (!ok) {
5500 DBG_DEBUG("share_mode_forall_leases failed\n");
5501 continue;
5504 TALLOC_FREE(lck);
5506 if (break_state.found_lease) {
5507 *p_version = break_state.version;
5508 *p_epoch = break_state.epoch;
5512 * Ensure we don't grant anything more so we
5513 * never upgrade.
5515 return NT_STATUS_OPLOCK_NOT_GRANTED;
5519 * Wrapper around open_file_ntcreate and open_directory
5522 static NTSTATUS create_file_unixpath(connection_struct *conn,
5523 struct smb_request *req,
5524 struct smb_filename *smb_fname,
5525 uint32_t access_mask,
5526 uint32_t share_access,
5527 uint32_t create_disposition,
5528 uint32_t create_options,
5529 uint32_t file_attributes,
5530 uint32_t oplock_request,
5531 const struct smb2_lease *lease,
5532 uint64_t allocation_size,
5533 uint32_t private_flags,
5534 struct security_descriptor *sd,
5535 struct ea_list *ea_list,
5537 files_struct **result,
5538 int *pinfo)
5540 struct smb2_lease none_lease;
5541 int info = FILE_WAS_OPENED;
5542 files_struct *base_fsp = NULL;
5543 files_struct *fsp = NULL;
5544 NTSTATUS status;
5545 int ret;
5546 struct smb_filename *parent_dir_fname = NULL;
5547 struct smb_filename *smb_fname_atname = NULL;
5549 DBG_DEBUG("create_file_unixpath: access_mask = 0x%x "
5550 "file_attributes = 0x%x, share_access = 0x%x, "
5551 "create_disposition = 0x%x create_options = 0x%x "
5552 "oplock_request = 0x%x private_flags = 0x%x "
5553 "ea_list = %p, sd = %p, "
5554 "fname = %s\n",
5555 (unsigned int)access_mask,
5556 (unsigned int)file_attributes,
5557 (unsigned int)share_access,
5558 (unsigned int)create_disposition,
5559 (unsigned int)create_options,
5560 (unsigned int)oplock_request,
5561 (unsigned int)private_flags,
5562 ea_list, sd, smb_fname_str_dbg(smb_fname));
5564 if (create_options & FILE_OPEN_BY_FILE_ID) {
5565 status = NT_STATUS_NOT_SUPPORTED;
5566 goto fail;
5569 if (create_options & NTCREATEX_OPTIONS_INVALID_PARAM_MASK) {
5570 status = NT_STATUS_INVALID_PARAMETER;
5571 goto fail;
5574 if (req == NULL) {
5575 oplock_request |= INTERNAL_OPEN_ONLY;
5578 if (lease != NULL) {
5579 uint16_t epoch = lease->lease_epoch;
5580 uint16_t version = lease->lease_version;
5582 if (req == NULL) {
5583 DBG_WARNING("Got lease on internal open\n");
5584 status = NT_STATUS_INTERNAL_ERROR;
5585 goto fail;
5588 status = lease_match(conn,
5589 req,
5590 &lease->lease_key,
5591 conn->connectpath,
5592 smb_fname,
5593 &version,
5594 &epoch);
5595 if (NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) {
5596 /* Dynamic share file. No leases and update epoch... */
5597 none_lease = *lease;
5598 none_lease.lease_state = SMB2_LEASE_NONE;
5599 none_lease.lease_epoch = epoch;
5600 none_lease.lease_version = version;
5601 lease = &none_lease;
5602 } else if (!NT_STATUS_IS_OK(status)) {
5603 goto fail;
5607 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
5608 && (access_mask & DELETE_ACCESS)
5609 && !is_ntfs_stream_smb_fname(smb_fname)) {
5611 * We can't open a file with DELETE access if any of the
5612 * streams is open without FILE_SHARE_DELETE
5614 status = open_streams_for_delete(conn, smb_fname);
5616 if (!NT_STATUS_IS_OK(status)) {
5617 goto fail;
5621 if (access_mask & SEC_FLAG_SYSTEM_SECURITY) {
5622 bool ok;
5624 ok = security_token_has_privilege(get_current_nttok(conn),
5625 SEC_PRIV_SECURITY);
5626 if (!ok) {
5627 DBG_DEBUG("open on %s failed - "
5628 "SEC_FLAG_SYSTEM_SECURITY denied.\n",
5629 smb_fname_str_dbg(smb_fname));
5630 status = NT_STATUS_PRIVILEGE_NOT_HELD;
5631 goto fail;
5634 if (conn->sconn->using_smb2 &&
5635 (access_mask == SEC_FLAG_SYSTEM_SECURITY))
5638 * No other bits set. Windows SMB2 refuses this.
5639 * See smbtorture3 SMB2-SACL test.
5641 * Note this is an SMB2-only behavior,
5642 * smbtorture3 SMB1-SYSTEM-SECURITY already tests
5643 * that SMB1 allows this.
5645 status = NT_STATUS_ACCESS_DENIED;
5646 goto fail;
5651 * Files or directories can't be opened DELETE_ON_CLOSE without
5652 * delete access.
5653 * BUG: https://bugzilla.samba.org/show_bug.cgi?id=13358
5655 if (create_options & FILE_DELETE_ON_CLOSE) {
5656 if ((access_mask & DELETE_ACCESS) == 0) {
5657 status = NT_STATUS_INVALID_PARAMETER;
5658 goto fail;
5662 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
5663 && is_ntfs_stream_smb_fname(smb_fname))
5665 uint32_t base_create_disposition;
5666 struct smb_filename *smb_fname_base = NULL;
5667 uint32_t base_privflags;
5669 if (create_options & FILE_DIRECTORY_FILE) {
5670 status = NT_STATUS_NOT_A_DIRECTORY;
5671 goto fail;
5674 switch (create_disposition) {
5675 case FILE_OPEN:
5676 base_create_disposition = FILE_OPEN;
5677 break;
5678 default:
5679 base_create_disposition = FILE_OPEN_IF;
5680 break;
5683 /* Create an smb_filename with stream_name == NULL. */
5684 smb_fname_base = synthetic_smb_fname(talloc_tos(),
5685 smb_fname->base_name,
5686 NULL,
5687 &smb_fname->st,
5688 smb_fname->twrp,
5689 smb_fname->flags);
5690 if (smb_fname_base == NULL) {
5691 status = NT_STATUS_NO_MEMORY;
5692 goto fail;
5696 * We may be creating the basefile as part of creating the
5697 * stream, so it's legal if the basefile doesn't exist at this
5698 * point, the create_file_unixpath() below will create it. But
5699 * if the basefile exists we want a handle so we can fstat() it.
5702 ret = vfs_stat(conn, smb_fname_base);
5703 if (ret == -1 && errno != ENOENT) {
5704 status = map_nt_error_from_unix(errno);
5705 TALLOC_FREE(smb_fname_base);
5706 goto fail;
5708 if (ret == 0) {
5709 status = openat_pathref_fsp(conn->cwd_fsp,
5710 smb_fname_base);
5711 if (!NT_STATUS_IS_OK(status)) {
5712 DBG_ERR("open_smb_fname_fsp [%s] failed: %s\n",
5713 smb_fname_str_dbg(smb_fname_base),
5714 nt_errstr(status));
5715 TALLOC_FREE(smb_fname_base);
5716 goto fail;
5720 * https://bugzilla.samba.org/show_bug.cgi?id=10229
5721 * We need to check if the requested access mask
5722 * could be used to open the underlying file (if
5723 * it existed), as we're passing in zero for the
5724 * access mask to the base filename.
5726 status = check_base_file_access(smb_fname_base->fsp,
5727 access_mask);
5729 if (!NT_STATUS_IS_OK(status)) {
5730 DEBUG(10, ("Permission check "
5731 "for base %s failed: "
5732 "%s\n", smb_fname->base_name,
5733 nt_errstr(status)));
5734 TALLOC_FREE(smb_fname_base);
5735 goto fail;
5739 base_privflags = NTCREATEX_FLAG_STREAM_BASEOPEN;
5741 /* Open the base file. */
5742 status = create_file_unixpath(conn,
5743 NULL,
5744 smb_fname_base,
5746 FILE_SHARE_READ
5747 | FILE_SHARE_WRITE
5748 | FILE_SHARE_DELETE,
5749 base_create_disposition,
5753 NULL,
5755 base_privflags,
5756 NULL,
5757 NULL,
5758 &base_fsp,
5759 NULL);
5760 TALLOC_FREE(smb_fname_base);
5762 if (!NT_STATUS_IS_OK(status)) {
5763 DEBUG(10, ("create_file_unixpath for base %s failed: "
5764 "%s\n", smb_fname->base_name,
5765 nt_errstr(status)));
5766 goto fail;
5771 * Now either reuse smb_fname->fsp or allocate a new fsp if
5772 * smb_fname->fsp is NULL. The latter will be the case when processing a
5773 * request to create a file that doesn't exist.
5775 if (smb_fname->fsp != NULL) {
5776 bool need_fsp_unlink = true;
5779 * This is really subtle. If someone passes in an smb_fname
5780 * where smb_fname actually is taken from fsp->fsp_name, then
5781 * the lifetime of these objects is meant to be the same.
5783 * This is commonly the case from an SMB1 path-based call,
5784 * (call_trans2qfilepathinfo) where we use the pathref fsp
5785 * (smb_fname->fsp) as the handle. In this case we must not
5786 * unlink smb_fname->fsp from it's owner.
5788 * The asserts below:
5790 * SMB_ASSERT(fsp->fsp_name->fsp != NULL);
5791 * SMB_ASSERT(fsp->fsp_name->fsp == fsp);
5793 * ensure the required invarients are met.
5795 if (smb_fname->fsp->fsp_name == smb_fname) {
5796 need_fsp_unlink = false;
5799 fsp = smb_fname->fsp;
5801 if (need_fsp_unlink) {
5803 * Unlink the fsp from the smb_fname so the fsp is not
5804 * autoclosed by the smb_fname pathref fsp talloc
5805 * destructor.
5807 smb_fname_fsp_unlink(smb_fname);
5810 status = fsp_bind_smb(fsp, req);
5811 if (!NT_STATUS_IS_OK(status)) {
5812 goto fail;
5815 if (fsp->base_fsp != NULL) {
5816 struct files_struct *tmp_base_fsp = fsp->base_fsp;
5818 fsp_set_base_fsp(fsp, NULL);
5820 fd_close(tmp_base_fsp);
5821 file_free(NULL, tmp_base_fsp);
5825 if (fsp == NULL) {
5826 /* Creating file */
5827 status = file_new(req, conn, &fsp);
5828 if(!NT_STATUS_IS_OK(status)) {
5829 goto fail;
5832 status = fsp_set_smb_fname(fsp, smb_fname);
5833 if (!NT_STATUS_IS_OK(status)) {
5834 goto fail;
5838 SMB_ASSERT(fsp->fsp_name->fsp != NULL);
5839 SMB_ASSERT(fsp->fsp_name->fsp == fsp);
5841 if (base_fsp) {
5843 * We're opening the stream element of a
5844 * base_fsp we already opened. Set up the
5845 * base_fsp pointer.
5847 fsp_set_base_fsp(fsp, base_fsp);
5851 * Get a pathref on the parent. We can re-use this
5852 * for multiple calls to check parent ACLs etc. to
5853 * avoid pathname calls.
5855 status = parent_pathref(talloc_tos(),
5856 conn->cwd_fsp,
5857 smb_fname,
5858 &parent_dir_fname,
5859 &smb_fname_atname);
5860 if (!NT_STATUS_IS_OK(status)) {
5861 goto fail;
5865 * If it's a request for a directory open, deal with it separately.
5868 if (create_options & FILE_DIRECTORY_FILE) {
5870 if (create_options & FILE_NON_DIRECTORY_FILE) {
5871 status = NT_STATUS_INVALID_PARAMETER;
5872 goto fail;
5875 /* Can't open a temp directory. IFS kit test. */
5876 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
5877 (file_attributes & FILE_ATTRIBUTE_TEMPORARY)) {
5878 status = NT_STATUS_INVALID_PARAMETER;
5879 goto fail;
5883 * We will get a create directory here if the Win32
5884 * app specified a security descriptor in the
5885 * CreateDirectory() call.
5888 oplock_request = 0;
5889 status = open_directory(conn,
5890 req,
5891 access_mask,
5892 share_access,
5893 create_disposition,
5894 create_options,
5895 file_attributes,
5896 parent_dir_fname,
5897 smb_fname_atname,
5898 &info,
5899 fsp);
5900 } else {
5903 * Ordinary file case.
5906 if (allocation_size) {
5907 fsp->initial_allocation_size = smb_roundup(fsp->conn,
5908 allocation_size);
5911 status = open_file_ntcreate(conn,
5912 req,
5913 access_mask,
5914 share_access,
5915 create_disposition,
5916 create_options,
5917 file_attributes,
5918 oplock_request,
5919 lease,
5920 private_flags,
5921 parent_dir_fname,
5922 smb_fname_atname,
5923 &info,
5924 fsp);
5925 if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
5927 /* A stream open never opens a directory */
5929 if (base_fsp) {
5930 status = NT_STATUS_FILE_IS_A_DIRECTORY;
5931 goto fail;
5935 * Fail the open if it was explicitly a non-directory
5936 * file.
5939 if (create_options & FILE_NON_DIRECTORY_FILE) {
5940 status = NT_STATUS_FILE_IS_A_DIRECTORY;
5941 goto fail;
5944 oplock_request = 0;
5945 status = open_directory(conn,
5946 req,
5947 access_mask,
5948 share_access,
5949 create_disposition,
5950 create_options,
5951 file_attributes,
5952 parent_dir_fname,
5953 smb_fname_atname,
5954 &info,
5955 fsp);
5959 if (!NT_STATUS_IS_OK(status)) {
5960 goto fail;
5963 fsp->fsp_flags.is_fsa = true;
5965 if ((ea_list != NULL) &&
5966 ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN))) {
5967 status = set_ea(conn, fsp, ea_list);
5968 if (!NT_STATUS_IS_OK(status)) {
5969 goto fail;
5973 if (!fsp->fsp_flags.is_directory &&
5974 S_ISDIR(fsp->fsp_name->st.st_ex_mode))
5976 status = NT_STATUS_ACCESS_DENIED;
5977 goto fail;
5980 /* Save the requested allocation size. */
5981 if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
5982 if ((allocation_size > (uint64_t)fsp->fsp_name->st.st_ex_size)
5983 && !(fsp->fsp_flags.is_directory))
5985 fsp->initial_allocation_size = smb_roundup(
5986 fsp->conn, allocation_size);
5987 if (vfs_allocate_file_space(
5988 fsp, fsp->initial_allocation_size) == -1) {
5989 status = NT_STATUS_DISK_FULL;
5990 goto fail;
5992 } else {
5993 fsp->initial_allocation_size = smb_roundup(
5994 fsp->conn, (uint64_t)fsp->fsp_name->st.st_ex_size);
5996 } else {
5997 fsp->initial_allocation_size = 0;
6000 if ((info == FILE_WAS_CREATED) && lp_nt_acl_support(SNUM(conn)) &&
6001 fsp->base_fsp == NULL) {
6002 if (sd != NULL) {
6004 * According to the MS documentation, the only time the security
6005 * descriptor is applied to the opened file is iff we *created* the
6006 * file; an existing file stays the same.
6008 * Also, it seems (from observation) that you can open the file with
6009 * any access mask but you can still write the sd. We need to override
6010 * the granted access before we call set_sd
6011 * Patch for bug #2242 from Tom Lackemann <cessnatomny@yahoo.com>.
6014 uint32_t sec_info_sent;
6015 uint32_t saved_access_mask = fsp->access_mask;
6017 sec_info_sent = get_sec_info(sd);
6019 fsp->access_mask = FILE_GENERIC_ALL;
6021 if (sec_info_sent & (SECINFO_OWNER|
6022 SECINFO_GROUP|
6023 SECINFO_DACL|
6024 SECINFO_SACL)) {
6025 status = set_sd(fsp, sd, sec_info_sent);
6028 fsp->access_mask = saved_access_mask;
6030 if (!NT_STATUS_IS_OK(status)) {
6031 goto fail;
6033 } else if (lp_inherit_acls(SNUM(conn))) {
6034 /* Inherit from parent. Errors here are not fatal. */
6035 status = inherit_new_acl(parent_dir_fname, fsp);
6036 if (!NT_STATUS_IS_OK(status)) {
6037 DEBUG(10,("inherit_new_acl: failed for %s with %s\n",
6038 fsp_str_dbg(fsp),
6039 nt_errstr(status) ));
6044 if ((conn->fs_capabilities & FILE_FILE_COMPRESSION)
6045 && (create_options & FILE_NO_COMPRESSION)
6046 && (info == FILE_WAS_CREATED)) {
6047 status = SMB_VFS_SET_COMPRESSION(conn, fsp, fsp,
6048 COMPRESSION_FORMAT_NONE);
6049 if (!NT_STATUS_IS_OK(status)) {
6050 DEBUG(1, ("failed to disable compression: %s\n",
6051 nt_errstr(status)));
6055 DEBUG(10, ("create_file_unixpath: info=%d\n", info));
6057 *result = fsp;
6058 if (pinfo != NULL) {
6059 *pinfo = info;
6062 smb_fname->st = fsp->fsp_name->st;
6064 TALLOC_FREE(parent_dir_fname);
6066 return NT_STATUS_OK;
6068 fail:
6069 DEBUG(10, ("create_file_unixpath: %s\n", nt_errstr(status)));
6071 if (fsp != NULL) {
6073 * The close_file below will close
6074 * fsp->base_fsp.
6076 base_fsp = NULL;
6077 close_file(req, fsp, ERROR_CLOSE);
6078 fsp = NULL;
6080 if (base_fsp != NULL) {
6081 close_file(req, base_fsp, ERROR_CLOSE);
6082 base_fsp = NULL;
6085 TALLOC_FREE(parent_dir_fname);
6087 return status;
6090 NTSTATUS create_file_default(connection_struct *conn,
6091 struct smb_request *req,
6092 struct smb_filename *smb_fname,
6093 uint32_t access_mask,
6094 uint32_t share_access,
6095 uint32_t create_disposition,
6096 uint32_t create_options,
6097 uint32_t file_attributes,
6098 uint32_t oplock_request,
6099 const struct smb2_lease *lease,
6100 uint64_t allocation_size,
6101 uint32_t private_flags,
6102 struct security_descriptor *sd,
6103 struct ea_list *ea_list,
6104 files_struct **result,
6105 int *pinfo,
6106 const struct smb2_create_blobs *in_context_blobs,
6107 struct smb2_create_blobs *out_context_blobs)
6109 int info = FILE_WAS_OPENED;
6110 files_struct *fsp = NULL;
6111 NTSTATUS status;
6112 bool stream_name = false;
6113 struct smb2_create_blob *posx = NULL;
6115 DBG_DEBUG("create_file: access_mask = 0x%x "
6116 "file_attributes = 0x%x, share_access = 0x%x, "
6117 "create_disposition = 0x%x create_options = 0x%x "
6118 "oplock_request = 0x%x "
6119 "private_flags = 0x%x "
6120 "ea_list = %p, sd = %p, "
6121 "fname = %s\n",
6122 (unsigned int)access_mask,
6123 (unsigned int)file_attributes,
6124 (unsigned int)share_access,
6125 (unsigned int)create_disposition,
6126 (unsigned int)create_options,
6127 (unsigned int)oplock_request,
6128 (unsigned int)private_flags,
6129 ea_list,
6131 smb_fname_str_dbg(smb_fname));
6133 if (req != NULL) {
6135 * Remember the absolute time of the original request
6136 * with this mid. We'll use it later to see if this
6137 * has timed out.
6139 get_deferred_open_message_state(req, &req->request_time, NULL);
6143 * Check to see if this is a mac fork of some kind.
6146 stream_name = is_ntfs_stream_smb_fname(smb_fname);
6147 if (stream_name) {
6148 enum FAKE_FILE_TYPE fake_file_type;
6150 fake_file_type = is_fake_file(smb_fname);
6152 if (req != NULL && fake_file_type != FAKE_FILE_TYPE_NONE) {
6155 * Here we go! support for changing the disk quotas
6156 * --metze
6158 * We need to fake up to open this MAGIC QUOTA file
6159 * and return a valid FID.
6161 * w2k close this file directly after openening xp
6162 * also tries a QUERY_FILE_INFO on the file and then
6163 * close it
6165 status = open_fake_file(req, conn, req->vuid,
6166 fake_file_type, smb_fname,
6167 access_mask, &fsp);
6168 if (!NT_STATUS_IS_OK(status)) {
6169 goto fail;
6172 ZERO_STRUCT(smb_fname->st);
6173 goto done;
6176 if (!(conn->fs_capabilities & FILE_NAMED_STREAMS)) {
6177 status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
6178 goto fail;
6182 if (is_ntfs_default_stream_smb_fname(smb_fname)) {
6183 int ret;
6184 smb_fname->stream_name = NULL;
6185 /* We have to handle this error here. */
6186 if (create_options & FILE_DIRECTORY_FILE) {
6187 status = NT_STATUS_NOT_A_DIRECTORY;
6188 goto fail;
6190 ret = vfs_stat(conn, smb_fname);
6191 if (ret == 0 && VALID_STAT_OF_DIR(smb_fname->st)) {
6192 status = NT_STATUS_FILE_IS_A_DIRECTORY;
6193 goto fail;
6197 posx = smb2_create_blob_find(
6198 in_context_blobs, SMB2_CREATE_TAG_POSIX);
6199 if (posx != NULL) {
6200 uint32_t wire_mode_bits = 0;
6201 mode_t mode_bits = 0;
6202 SMB_STRUCT_STAT sbuf = { 0 };
6203 enum perm_type ptype =
6204 (create_options & FILE_DIRECTORY_FILE) ?
6205 PERM_NEW_DIR : PERM_NEW_FILE;
6207 if (posx->data.length != 4) {
6208 status = NT_STATUS_INVALID_PARAMETER;
6209 goto fail;
6212 wire_mode_bits = IVAL(posx->data.data, 0);
6213 status = unix_perms_from_wire(
6214 conn, &sbuf, wire_mode_bits, ptype, &mode_bits);
6215 if (!NT_STATUS_IS_OK(status)) {
6216 goto fail;
6219 * Remove type info from mode, leaving only the
6220 * permissions and setuid/gid bits.
6222 mode_bits &= ~S_IFMT;
6224 file_attributes = (FILE_FLAG_POSIX_SEMANTICS | mode_bits);
6227 status = create_file_unixpath(conn,
6228 req,
6229 smb_fname,
6230 access_mask,
6231 share_access,
6232 create_disposition,
6233 create_options,
6234 file_attributes,
6235 oplock_request,
6236 lease,
6237 allocation_size,
6238 private_flags,
6240 ea_list,
6241 &fsp,
6242 &info);
6243 if (!NT_STATUS_IS_OK(status)) {
6244 goto fail;
6247 done:
6248 DEBUG(10, ("create_file: info=%d\n", info));
6250 *result = fsp;
6251 if (pinfo != NULL) {
6252 *pinfo = info;
6254 return NT_STATUS_OK;
6256 fail:
6257 DEBUG(10, ("create_file: %s\n", nt_errstr(status)));
6259 if (fsp != NULL) {
6260 close_file(req, fsp, ERROR_CLOSE);
6261 fsp = NULL;
6263 return status;