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/>.
24 #include "system/filesys.h"
25 #include "lib/util/server_id.h"
27 #include "locking/share_mode_lock.h"
28 #include "smbd/smbd.h"
29 #include "smbd/globals.h"
30 #include "fake_file.h"
31 #include "../libcli/security/security.h"
32 #include "../librpc/gen_ndr/ndr_security.h"
33 #include "../librpc/gen_ndr/ndr_open_files.h"
34 #include "../librpc/gen_ndr/idmap.h"
35 #include "../librpc/gen_ndr/ioctl.h"
36 #include "passdb/lookup_sid.h"
40 #include "source3/lib/dbwrap/dbwrap_watch.h"
41 #include "source3/lib/server_id_watch.h"
42 #include "locking/leases_db.h"
43 #include "librpc/gen_ndr/ndr_leases_db.h"
44 #include "lib/util/time_basic.h"
45 #include "source3/smbd/dir.h"
47 #if defined(HAVE_LINUX_MAGIC_H)
48 #include <linux/magic.h>
51 static NTSTATUS
inherit_new_acl(files_struct
*dirfsp
, files_struct
*fsp
);
53 extern const struct generic_mapping file_generic_mapping
;
55 struct deferred_open_record
{
56 struct smbXsrv_connection
*xconn
;
62 * Timer for async opens, needed because they don't use a watch on
63 * a locking.tdb record. This is currently only used for real async
64 * opens and just terminates smbd if the async open times out.
66 struct tevent_timer
*te
;
69 * For the samba kernel oplock case we use both a timeout and
70 * a watch on locking.tdb. This way in case it's smbd holding
71 * the kernel oplock we get directly notified for the retry
72 * once the kernel oplock is properly broken. Store the req
73 * here so that it can be timely discarded once the timer
76 struct tevent_req
*watch_req
;
79 /****************************************************************************
80 If the requester wanted DELETE_ACCESS and was rejected because
81 the file ACL didn't include DELETE_ACCESS, see if the parent ACL
83 ****************************************************************************/
85 static bool parent_override_delete(connection_struct
*conn
,
86 struct files_struct
*dirfsp
,
87 const struct smb_filename
*smb_fname
,
89 uint32_t rejected_mask
)
91 if ((access_mask
& DELETE_ACCESS
) && (rejected_mask
& DELETE_ACCESS
)) {
93 ok
= can_delete_file_in_directory(conn
, dirfsp
, smb_fname
);
100 /****************************************************************************
101 Check if we have open rights.
102 ****************************************************************************/
104 static NTSTATUS
smbd_check_access_rights_fname(
105 struct connection_struct
*conn
,
106 const struct smb_filename
*smb_fname
,
108 uint32_t access_mask
,
109 uint32_t do_not_check_mask
)
111 uint32_t rejected_share_access
;
112 uint32_t effective_access
;
114 rejected_share_access
= access_mask
& ~(conn
->share_access
);
116 if (rejected_share_access
) {
117 DBG_DEBUG("rejected share access 0x%"PRIx32
" on "
118 "%s (0x%"PRIx32
")\n",
120 smb_fname_str_dbg(smb_fname
),
121 rejected_share_access
);
122 return NT_STATUS_ACCESS_DENIED
;
125 effective_access
= access_mask
& ~do_not_check_mask
;
126 if (effective_access
== 0) {
127 DBG_DEBUG("do_not_check_mask override on %s. Granting 0x%x for free.\n",
128 smb_fname_str_dbg(smb_fname
),
129 (unsigned int)access_mask
);
133 if (!use_privs
&& get_current_uid(conn
) == (uid_t
)0) {
134 /* I'm sorry sir, I didn't know you were root... */
135 DBG_DEBUG("root override on %s. Granting 0x%x\n",
136 smb_fname_str_dbg(smb_fname
),
137 (unsigned int)access_mask
);
141 if ((access_mask
& DELETE_ACCESS
) &&
142 !lp_acl_check_permissions(SNUM(conn
)))
144 DBG_DEBUG("Not checking ACL on DELETE_ACCESS on file %s. "
145 "Granting 0x%"PRIx32
"\n",
146 smb_fname_str_dbg(smb_fname
),
151 if (access_mask
== DELETE_ACCESS
&&
152 VALID_STAT(smb_fname
->st
) &&
153 S_ISLNK(smb_fname
->st
.st_ex_mode
))
155 /* We can always delete a symlink. */
156 DBG_DEBUG("Not checking ACL on DELETE_ACCESS on symlink %s.\n",
157 smb_fname_str_dbg(smb_fname
));
161 return NT_STATUS_MORE_PROCESSING_REQUIRED
;
164 static NTSTATUS
smbd_check_access_rights_sd(
165 struct connection_struct
*conn
,
166 struct files_struct
*dirfsp
,
167 const struct smb_filename
*smb_fname
,
168 struct security_descriptor
*sd
,
170 uint32_t access_mask
,
171 uint32_t do_not_check_mask
)
173 uint32_t rejected_mask
= access_mask
;
180 status
= se_file_access_check(sd
,
181 get_current_nttok(conn
),
183 (access_mask
& ~do_not_check_mask
),
186 DBG_DEBUG("File [%s] requesting [0x%"PRIx32
"] "
187 "returning [0x%"PRIx32
"] (%s)\n",
188 smb_fname_str_dbg(smb_fname
),
193 if (!NT_STATUS_IS_OK(status
)) {
194 if (DEBUGLEVEL
>= 10) {
195 DBG_DEBUG("acl for %s is:\n",
196 smb_fname_str_dbg(smb_fname
));
197 NDR_PRINT_DEBUG(security_descriptor
, sd
);
203 if (NT_STATUS_IS_OK(status
) ||
204 !NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
))
209 /* Here we know status == NT_STATUS_ACCESS_DENIED. */
213 if ((access_mask
& FILE_WRITE_ATTRIBUTES
) &&
214 (rejected_mask
& FILE_WRITE_ATTRIBUTES
) &&
215 !lp_store_dos_attributes(SNUM(conn
)) &&
216 (lp_map_readonly(SNUM(conn
)) ||
217 lp_map_archive(SNUM(conn
)) ||
218 lp_map_hidden(SNUM(conn
)) ||
219 lp_map_system(SNUM(conn
))))
221 rejected_mask
&= ~FILE_WRITE_ATTRIBUTES
;
223 DBG_DEBUG("overrode FILE_WRITE_ATTRIBUTES on file %s\n",
224 smb_fname_str_dbg(smb_fname
));
227 if (parent_override_delete(conn
,
234 * Were we trying to do an open for delete and didn't get DELETE
235 * access. Check if the directory allows DELETE_CHILD.
237 * http://blogs.msdn.com/oldnewthing/archive/2004/06/04/148426.aspx
241 rejected_mask
&= ~DELETE_ACCESS
;
243 DBG_DEBUG("Overrode DELETE_ACCESS on file %s\n",
244 smb_fname_str_dbg(smb_fname
));
247 if (rejected_mask
!= 0) {
248 return NT_STATUS_ACCESS_DENIED
;
253 NTSTATUS
smbd_check_access_rights_fsp(struct files_struct
*dirfsp
,
254 struct files_struct
*fsp
,
256 uint32_t access_mask
)
258 struct security_descriptor
*sd
= NULL
;
259 uint32_t do_not_check_mask
= 0;
262 /* Cope with fake/printer fsp's. */
263 if (fsp
->fake_file_handle
!= NULL
|| fsp
->print_file
!= NULL
) {
264 if ((fsp
->access_mask
& access_mask
) != access_mask
) {
265 return NT_STATUS_ACCESS_DENIED
;
270 if (fsp_get_pathref_fd(fsp
) == -1) {
272 * This is a POSIX open on a symlink. For the pathname
273 * version of this function we used to return the st_mode
274 * bits turned into an NT ACL. For a symlink the mode bits
275 * are always rwxrwxrwx which means the pathname version always
276 * returned NT_STATUS_OK for a symlink. For the handle reference
277 * to a symlink use the handle access bits.
279 if ((fsp
->access_mask
& access_mask
) != access_mask
) {
280 return NT_STATUS_ACCESS_DENIED
;
286 * If we can access the path to this file, by
287 * default we have FILE_READ_ATTRIBUTES from the
288 * containing directory. See the section:
289 * "Algorithm to Check Access to an Existing File"
292 * se_file_access_check() also takes care of
293 * owner WRITE_DAC and READ_CONTROL.
295 do_not_check_mask
= FILE_READ_ATTRIBUTES
;
298 * Samba 3.6 and earlier granted execute access even
299 * if the ACL did not contain execute rights.
300 * Samba 4.0 is more correct and checks it.
301 * The compatibility mode allows one to skip this check
302 * to smoothen upgrades.
304 if (lp_acl_allow_execute_always(SNUM(fsp
->conn
))) {
305 do_not_check_mask
|= FILE_EXECUTE
;
308 status
= smbd_check_access_rights_fname(fsp
->conn
,
313 if (!NT_STATUS_EQUAL(status
, NT_STATUS_MORE_PROCESSING_REQUIRED
)) {
317 status
= SMB_VFS_FGET_NT_ACL(metadata_fsp(fsp
),
323 if (!NT_STATUS_IS_OK(status
)) {
324 DBG_DEBUG("Could not get acl on %s: %s\n",
330 return smbd_check_access_rights_sd(fsp
->conn
,
340 * Given an fsp that represents a parent directory,
341 * check if the requested access can be granted.
343 NTSTATUS
check_parent_access_fsp(struct files_struct
*fsp
,
344 uint32_t access_mask
)
347 struct security_descriptor
*parent_sd
= NULL
;
348 uint32_t access_granted
= 0;
350 bool delete_on_close_set
;
351 TALLOC_CTX
*frame
= talloc_stackframe();
353 if (get_current_uid(fsp
->conn
) == (uid_t
)0) {
354 /* I'm sorry sir, I didn't know you were root... */
355 DBG_DEBUG("root override on %s. Granting 0x%x\n",
357 (unsigned int)access_mask
);
358 status
= NT_STATUS_OK
;
362 status
= SMB_VFS_FGET_NT_ACL(fsp
,
363 (SECINFO_OWNER
| SECINFO_GROUP
| SECINFO_DACL
),
367 if (!NT_STATUS_IS_OK(status
)) {
368 DBG_INFO("SMB_VFS_FGET_NT_ACL failed for "
369 "%s with error %s\n",
376 * If we can access the path to this file, by
377 * default we have FILE_READ_ATTRIBUTES from the
378 * containing directory. See the section:
379 * "Algorithm to Check Access to an Existing File"
382 * se_file_access_check() also takes care of
383 * owner WRITE_DAC and READ_CONTROL.
385 status
= se_file_access_check(parent_sd
,
386 get_current_nttok(fsp
->conn
),
388 (access_mask
& ~FILE_READ_ATTRIBUTES
),
390 if(!NT_STATUS_IS_OK(status
)) {
391 DBG_INFO("access check "
392 "on directory %s for mask 0x%x returned (0x%x) %s\n",
400 if (!(access_mask
& (SEC_DIR_ADD_FILE
| SEC_DIR_ADD_SUBDIR
))) {
401 status
= NT_STATUS_OK
;
404 if (!lp_check_parent_directory_delete_on_close(SNUM(fsp
->conn
))) {
405 status
= NT_STATUS_OK
;
409 /* Check if the directory has delete-on-close set */
410 status
= file_name_hash(fsp
->conn
,
411 fsp
->fsp_name
->base_name
,
413 if (!NT_STATUS_IS_OK(status
)) {
417 get_file_infos(fsp
->file_id
, name_hash
, &delete_on_close_set
, NULL
);
418 if (delete_on_close_set
) {
419 status
= NT_STATUS_DELETE_PENDING
;
423 status
= NT_STATUS_OK
;
430 /****************************************************************************
431 Ensure when opening a base file for a stream open that we have permissions
432 to do so given the access mask on the base file.
433 ****************************************************************************/
435 static NTSTATUS
check_base_file_access(struct files_struct
*fsp
,
436 uint32_t access_mask
)
440 status
= smbd_calculate_access_mask_fsp(fsp
->conn
->cwd_fsp
,
445 if (!NT_STATUS_IS_OK(status
)) {
446 DEBUG(10, ("smbd_calculate_access_mask "
447 "on file %s returned %s\n",
453 if (access_mask
& (FILE_WRITE_DATA
|FILE_APPEND_DATA
)) {
455 if (!CAN_WRITE(fsp
->conn
)) {
456 return NT_STATUS_ACCESS_DENIED
;
458 dosattrs
= fdos_mode(fsp
);
459 if (dosattrs
& FILE_ATTRIBUTE_READONLY
) {
460 return NT_STATUS_ACCESS_DENIED
;
464 return smbd_check_access_rights_fsp(fsp
->conn
->cwd_fsp
,
470 /****************************************************************************
471 fd support routines - attempt to do a dos_open.
472 ****************************************************************************/
474 NTSTATUS
fd_openat(const struct files_struct
*dirfsp
,
475 struct smb_filename
*smb_fname
,
477 const struct vfs_open_how
*_how
)
479 struct vfs_open_how how
= *_how
;
480 struct connection_struct
*conn
= fsp
->conn
;
481 NTSTATUS status
= NT_STATUS_OK
;
482 bool fsp_is_stream
= fsp_is_alternate_stream(fsp
);
483 bool smb_fname_is_stream
= is_named_stream(smb_fname
);
484 struct files_struct
*dirfsp_conv
= NULL
;
485 struct smb_filename
*smb_fname_conv
= NULL
;
486 struct smb_filename
*smb_fname_rel
= NULL
;
487 struct files_struct
*root_fsp
= NULL
;
488 const char *name_in
= smb_fname
->base_name
;
491 SMB_ASSERT(fsp_is_stream
== smb_fname_is_stream
);
496 NULL
, /* stream open is relative to fsp->base_fsp */
501 status
= map_nt_error_from_unix(errno
);
506 how
.flags
|= O_NOFOLLOW
; /* just to be sure */
508 if (strchr(smb_fname
->base_name
, '/') == NULL
) {
510 * With O_NOFOLLOW and no intermediate path components
511 * we can try directly.
513 fd
= SMB_VFS_OPENAT(conn
, dirfsp
, smb_fname
, fsp
, &how
);
516 status
= vfs_stat_fsp(fsp
);
517 if (NT_STATUS_IS_OK(status
) &&
518 !S_ISLNK(fsp
->fsp_name
->st
.st_ex_mode
)) {
519 smb_fname
->st
= fsp
->fsp_name
->st
;
520 fsp
->fsp_flags
.is_directory
= S_ISDIR(
521 fsp
->fsp_name
->st
.st_ex_mode
);
526 * We found a symlink in the lcomp via O_PATH,
527 * let filename_convert_dirfsp_rel follow
528 * it. This means we're going to open the
529 * symlink twice, but this is something to
530 * optimize when it becomes a problem.
538 if (name_in
[0] == '/') {
540 * filename_convert_dirfsp can't deal with absolute
541 * paths, make this relative to "/"
544 status
= open_rootdir_pathref_fsp(conn
, &root_fsp
);
545 if (!NT_STATUS_IS_OK(status
)) {
551 if (ISDOT(name_in
)) {
553 * filename_convert_dirfsp does not like ".", use ""
558 status
= filename_convert_dirfsp_rel(
561 discard_const_p(struct files_struct
, dirfsp
),
563 UCF_POSIX_PATHNAMES
, /* no case insensitive search */
570 if (root_fsp
!= NULL
) {
572 file_free(NULL
, root_fsp
);
576 if (!NT_STATUS_IS_OK(status
)) {
577 DBG_DEBUG("filename_convert_dirfsp_rel returned %s\n",
582 fd
= SMB_VFS_OPENAT(conn
, dirfsp_conv
, smb_fname_rel
, fsp
, &how
);
585 status
= map_nt_error_from_unix(errno
);
588 fd_close(dirfsp_conv
);
589 file_free(NULL
, dirfsp_conv
);
591 TALLOC_FREE(smb_fname_conv
);
594 fsp_set_fd(fsp
, fd
); /* This preserves errno */
597 if (NT_STATUS_EQUAL(status
, NT_STATUS_TOO_MANY_OPENED_FILES
)) {
598 static time_t last_warned
= 0L;
600 if (time((time_t *) NULL
) > last_warned
) {
601 DEBUG(0,("Too many open files, unable "
602 "to open more! smbd's max "
604 lp_max_open_files()));
605 last_warned
= time((time_t *) NULL
);
609 DBG_DEBUG("name %s, flags = 0%o mode = 0%o, fd = %d. %s\n",
610 smb_fname_str_dbg(smb_fname
),
613 fsp_get_pathref_fd(fsp
),
617 status
= vfs_stat_fsp(fsp
);
618 if (!NT_STATUS_IS_OK(status
)) {
619 DBG_DEBUG("vfs_stat_fsp failed: %s\n",
626 smb_fname
->st
= fsp
->fsp_name
->st
;
627 fsp
->fsp_flags
.is_directory
= S_ISDIR(fsp
->fsp_name
->st
.st_ex_mode
);
629 DBG_DEBUG("name %s, flags = 0%o mode = 0%o, fd = %d\n",
630 smb_fname_str_dbg(smb_fname
),
633 fsp_get_pathref_fd(fsp
));
638 /****************************************************************************
639 Close the file associated with a fsp.
640 ****************************************************************************/
642 NTSTATUS
fd_close(files_struct
*fsp
)
644 NTSTATUS stat_status
= NT_STATUS_OK
;
647 if (fsp
== fsp
->conn
->cwd_fsp
) {
651 if (fsp
->fsp_flags
.fstat_before_close
) {
653 * capture status, if failure
654 * continue close processing
657 stat_status
= vfs_stat_fsp(fsp
);
663 if (fsp_get_pathref_fd(fsp
) == -1) {
665 * Either a directory where the dptr_CloseDir() already closed
666 * the fd or a stat open.
670 if (fh_get_refcount(fsp
->fh
) > 1) {
671 return NT_STATUS_OK
; /* Shared handle. Only close last reference. */
674 ret
= SMB_VFS_CLOSE(fsp
);
677 return map_nt_error_from_unix(errno
);
682 /****************************************************************************
683 Change the ownership of a file to that of the parent directory.
684 Do this by fd if possible.
685 ****************************************************************************/
687 static void change_file_owner_to_parent_fsp(struct files_struct
*parent_fsp
,
688 struct files_struct
*fsp
)
692 if (parent_fsp
->fsp_name
->st
.st_ex_uid
== fsp
->fsp_name
->st
.st_ex_uid
) {
693 /* Already this uid - no need to change. */
694 DBG_DEBUG("file %s is already owned by uid %u\n",
696 (unsigned int)fsp
->fsp_name
->st
.st_ex_uid
);
701 ret
= SMB_VFS_FCHOWN(fsp
,
702 parent_fsp
->fsp_name
->st
.st_ex_uid
,
706 DBG_ERR("failed to fchown "
707 "file %s to parent directory uid %u. Error "
710 (unsigned int)parent_fsp
->fsp_name
->st
.st_ex_uid
,
713 DBG_DEBUG("changed new file %s to "
714 "parent directory uid %u.\n",
716 (unsigned int)parent_fsp
->fsp_name
->st
.st_ex_uid
);
717 /* Ensure the uid entry is updated. */
718 fsp
->fsp_name
->st
.st_ex_uid
=
719 parent_fsp
->fsp_name
->st
.st_ex_uid
;
723 static NTSTATUS
change_dir_owner_to_parent_fsp(struct files_struct
*parent_fsp
,
724 struct files_struct
*fsp
)
729 if (parent_fsp
->fsp_name
->st
.st_ex_uid
== fsp
->fsp_name
->st
.st_ex_uid
) {
730 /* Already this uid - no need to change. */
731 DBG_DEBUG("directory %s is already owned by uid %u\n",
733 (unsigned int)fsp
->fsp_name
->st
.st_ex_uid
);
738 ret
= SMB_VFS_FCHOWN(fsp
,
739 parent_fsp
->fsp_name
->st
.st_ex_uid
,
743 status
= map_nt_error_from_unix(errno
);
744 DBG_ERR("failed to chown "
745 "directory %s to parent directory uid %u. "
748 (unsigned int)parent_fsp
->fsp_name
->st
.st_ex_uid
,
753 DBG_DEBUG("changed ownership of new "
754 "directory %s to parent directory uid %u.\n",
756 (unsigned int)parent_fsp
->fsp_name
->st
.st_ex_uid
);
758 /* Ensure the uid entry is updated. */
759 fsp
->fsp_name
->st
.st_ex_uid
= parent_fsp
->fsp_name
->st
.st_ex_uid
;
764 /****************************************************************************
765 Open a file - returning a guaranteed ATOMIC indication of if the
766 file was created or not.
767 ****************************************************************************/
769 static NTSTATUS
fd_open_atomic(struct files_struct
*dirfsp
,
770 struct smb_filename
*smb_fname
,
772 const struct vfs_open_how
*_how
,
775 struct vfs_open_how how
= *_how
;
776 NTSTATUS status
= NT_STATUS_UNSUCCESSFUL
;
777 NTSTATUS retry_status
;
778 bool file_existed
= VALID_STAT(smb_fname
->st
);
780 if (!(how
.flags
& O_CREAT
)) {
782 * We're not creating the file, just pass through.
784 status
= fd_openat(dirfsp
, smb_fname
, fsp
, &how
);
785 *file_created
= false;
789 if (how
.flags
& O_EXCL
) {
791 * Fail if already exists, just pass through.
793 status
= fd_openat(dirfsp
, smb_fname
, fsp
, &how
);
796 * Here we've opened with O_CREAT|O_EXCL. If that went
797 * NT_STATUS_OK, we *know* we created this file.
799 *file_created
= NT_STATUS_IS_OK(status
);
805 * Now it gets tricky. We have O_CREAT, but not O_EXCL.
806 * To know absolutely if we created the file or not,
807 * we can never call O_CREAT without O_EXCL. So if
808 * we think the file existed, try without O_CREAT|O_EXCL.
809 * If we think the file didn't exist, try with
812 * The big problem here is dangling symlinks. Opening
813 * without O_NOFOLLOW means both bad symlink
814 * and missing path return -1, ENOENT from open(). As POSIX
815 * is pathname based it's not possible to tell
816 * the difference between these two cases in a
817 * non-racy way, so change to try only two attempts before
820 * We don't have this problem for the O_NOFOLLOW
821 * case as it just returns NT_STATUS_OBJECT_PATH_NOT_FOUND
822 * mapped from the ELOOP POSIX error.
826 how
.flags
= _how
->flags
& ~(O_CREAT
);
827 retry_status
= NT_STATUS_OBJECT_NAME_NOT_FOUND
;
829 how
.flags
= _how
->flags
| O_EXCL
;
830 retry_status
= NT_STATUS_OBJECT_NAME_COLLISION
;
833 status
= fd_openat(dirfsp
, smb_fname
, fsp
, &how
);
834 if (NT_STATUS_IS_OK(status
)) {
835 *file_created
= !file_existed
;
838 if (NT_STATUS_EQUAL(status
, retry_status
)) {
840 file_existed
= !file_existed
;
842 DBG_DEBUG("File %s %s. Retry.\n",
844 file_existed
? "existed" : "did not exist");
847 how
.flags
= _how
->flags
& ~(O_CREAT
);
849 how
.flags
= _how
->flags
| O_EXCL
;
852 status
= fd_openat(dirfsp
, smb_fname
, fsp
, &how
);
855 *file_created
= (NT_STATUS_IS_OK(status
) && !file_existed
);
859 NTSTATUS
reopen_from_fsp(struct files_struct
*dirfsp
,
860 struct smb_filename
*smb_fname
,
861 struct files_struct
*fsp
,
862 const struct vfs_open_how
*how
,
863 bool *p_file_created
)
868 if (fsp
->fsp_flags
.have_proc_fds
&&
869 ((old_fd
= fsp_get_pathref_fd(fsp
)) != -1)) {
871 struct sys_proc_fd_path_buf buf
;
872 struct smb_filename proc_fname
= {
873 .base_name
= sys_proc_fd_path(old_fd
, &buf
),
875 mode_t mode
= fsp
->fsp_name
->st
.st_ex_mode
;
879 return NT_STATUS_STOPPED_ON_SYMLINK
;
881 if (!(S_ISREG(mode
) || S_ISDIR(mode
))) {
882 return NT_STATUS_IO_REPARSE_TAG_NOT_HANDLED
;
885 fsp
->fsp_flags
.is_pathref
= false;
887 new_fd
= SMB_VFS_OPENAT(fsp
->conn
,
893 #if defined(HAVE_FSTATFS) && defined(HAVE_LINUX_MAGIC_H)
894 if (S_ISDIR(fsp
->fsp_name
->st
.st_ex_mode
) &&
896 struct statfs sbuf
= {};
897 int ret
= fstatfs(old_fd
, &sbuf
);
899 DBG_ERR("fstatfs failed: %s\n",
901 } else if (sbuf
.f_type
== AUTOFS_SUPER_MAGIC
) {
903 * When reopening an as-yet
904 * unmounted autofs mount
905 * point we get ENOENT. We
906 * have to retry pathbased.
910 /* restore ENOENT if changed in the meantime */
914 status
= map_nt_error_from_unix(errno
);
919 status
= fd_close(fsp
);
920 if (!NT_STATUS_IS_OK(status
)) {
924 fsp_set_fd(fsp
, new_fd
);
928 #if defined(HAVE_FSTATFS) && defined(HAVE_LINUX_MAGIC_H)
932 * Close the existing pathref fd and set the fsp flag
933 * is_pathref to false so we get a "normal" fd this time.
935 status
= fd_close(fsp
);
936 if (!NT_STATUS_IS_OK(status
)) {
940 fsp
->fsp_flags
.is_pathref
= false;
942 status
= fd_open_atomic(dirfsp
, smb_fname
, fsp
, how
, p_file_created
);
946 /****************************************************************************
948 ****************************************************************************/
950 static NTSTATUS
open_file(
951 struct smb_request
*req
,
952 struct files_struct
*dirfsp
,
953 struct smb_filename
*smb_fname_atname
,
955 const struct vfs_open_how
*_how
,
956 uint32_t access_mask
, /* client requested access mask. */
957 uint32_t open_access_mask
, /* what we're actually using in the open. */
958 uint32_t private_flags
,
959 bool *p_file_created
)
961 connection_struct
*conn
= fsp
->conn
;
962 struct smb_filename
*smb_fname
= fsp
->fsp_name
;
963 struct vfs_open_how how
= *_how
;
964 NTSTATUS status
= NT_STATUS_OK
;
965 bool file_existed
= VALID_STAT(fsp
->fsp_name
->st
);
966 const uint32_t need_fd_mask
=
971 SEC_FLAG_SYSTEM_SECURITY
;
972 bool creating
= !file_existed
&& (how
.flags
& O_CREAT
);
973 bool open_fd
= false;
974 bool posix_open
= fsp
->fsp_flags
.posix_open
;
977 * Catch early an attempt to open an existing
978 * directory as a file.
980 if (file_existed
&& S_ISDIR(fsp
->fsp_name
->st
.st_ex_mode
)) {
981 return NT_STATUS_FILE_IS_A_DIRECTORY
;
985 * This little piece of insanity is inspired by the
986 * fact that an NT client can open a file for O_RDONLY,
987 * but set the create disposition to FILE_EXISTS_TRUNCATE.
988 * If the client *can* write to the file, then it expects to
989 * truncate the file, even though it is opening for readonly.
990 * Quicken uses this stupid trick in backup file creation...
991 * Thanks *greatly* to "David W. Chapman Jr." <dwcjr@inethouston.net>
992 * for helping track this one down. It didn't bite us in 2.0.x
993 * as we always opened files read-write in that release. JRA.
996 if (((how
.flags
& O_ACCMODE
) == O_RDONLY
) && (how
.flags
& O_TRUNC
)) {
997 DBG_DEBUG("truncate requested on read-only open for file %s\n",
998 smb_fname_str_dbg(smb_fname
));
999 how
.flags
= (how
.flags
& ~O_ACCMODE
) | O_RDWR
;
1002 /* Check permissions */
1005 * This code was changed after seeing a client open request
1006 * containing the open mode of (DENY_WRITE/read-only) with
1007 * the 'create if not exist' bit set. The previous code
1008 * would fail to open the file read only on a read-only share
1009 * as it was checking the flags parameter directly against O_RDONLY,
1010 * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
1014 if (!CAN_WRITE(conn
)) {
1015 /* It's a read-only share - fail if we wanted to write. */
1016 if ((how
.flags
& O_ACCMODE
) != O_RDONLY
||
1017 (how
.flags
& O_TRUNC
) || (how
.flags
& O_APPEND
)) {
1018 DEBUG(3,("Permission denied opening %s\n",
1019 smb_fname_str_dbg(smb_fname
)));
1020 return NT_STATUS_ACCESS_DENIED
;
1023 * We don't want to write - but we must make sure that
1024 * O_CREAT doesn't create the file if we have write
1025 * access into the directory.
1027 how
.flags
&= ~(O_CREAT
| O_EXCL
);
1030 if ((open_access_mask
& need_fd_mask
) || creating
||
1031 (how
.flags
& O_TRUNC
)) {
1038 #if defined(O_NONBLOCK) && defined(S_ISFIFO)
1040 * We would block on opening a FIFO with no one else on the
1041 * other end. Do what we used to do and add O_NONBLOCK to the
1045 if (file_existed
&& S_ISFIFO(smb_fname
->st
.st_ex_mode
)) {
1046 how
.flags
|= O_NONBLOCK
;
1051 const char *wild
= smb_fname
->base_name
;
1053 * Don't open files with Microsoft wildcard characters.
1055 if (fsp_is_alternate_stream(fsp
)) {
1057 * wildcard characters are allowed in stream
1058 * names only test the basefilename
1060 wild
= fsp
->base_fsp
->fsp_name
->base_name
;
1063 if (ms_has_wild(wild
)) {
1064 return NT_STATUS_OBJECT_NAME_INVALID
;
1068 /* Can we access this file ? */
1069 if (!fsp_is_alternate_stream(fsp
)) {
1070 /* Only do this check on non-stream open. */
1072 status
= smbd_check_access_rights_fsp(
1078 if (!NT_STATUS_IS_OK(status
)) {
1079 DBG_DEBUG("smbd_check_access_rights_fsp"
1080 " on file %s returned %s\n",
1085 if (!NT_STATUS_IS_OK(status
) &&
1086 !NT_STATUS_EQUAL(status
,
1087 NT_STATUS_OBJECT_NAME_NOT_FOUND
))
1092 if (NT_STATUS_EQUAL(status
,
1093 NT_STATUS_OBJECT_NAME_NOT_FOUND
))
1095 DEBUG(10, ("open_file: "
1096 "file %s vanished since we "
1097 "checked for existence.\n",
1098 smb_fname_str_dbg(smb_fname
)));
1099 file_existed
= false;
1100 SET_STAT_INVALID(fsp
->fsp_name
->st
);
1104 if (!file_existed
) {
1105 if (!(how
.flags
& O_CREAT
)) {
1106 /* File didn't exist and no O_CREAT. */
1107 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1110 status
= check_parent_access_fsp(
1113 if (!NT_STATUS_IS_OK(status
)) {
1114 DBG_DEBUG("check_parent_access_fsp on "
1115 "directory %s for file %s "
1119 smb_fname_str_dbg(smb_fname
),
1127 * Actually do the open - if O_TRUNC is needed handle it
1128 * below under the share mode lock.
1130 how
.flags
&= ~O_TRUNC
;
1131 status
= reopen_from_fsp(dirfsp
,
1136 if (NT_STATUS_EQUAL(status
, NT_STATUS_STOPPED_ON_SYMLINK
)) {
1138 * Non-O_PATH reopen that hit a race
1139 * condition: Someone has put a symlink where
1140 * we used to have a file. Can't happen with
1141 * O_PATH and reopening from /proc/self/fd/ or
1144 status
= NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1146 if (!NT_STATUS_IS_OK(status
)) {
1147 DBG_NOTICE("Error opening file %s (%s) (in_flags=%d) "
1149 smb_fname_str_dbg(smb_fname
),
1156 if (how
.flags
& O_NONBLOCK
) {
1158 * GPFS can return ETIMEDOUT for pread on
1159 * nonblocking file descriptors when files
1160 * migrated to tape need to be recalled. I
1161 * could imagine this happens elsewhere
1162 * too. With blocking file descriptors this
1165 ret
= vfs_set_blocking(fsp
, true);
1167 status
= map_nt_error_from_unix(errno
);
1168 DBG_WARNING("Could not set fd to blocking: "
1169 "%s\n", strerror(errno
));
1175 if (*p_file_created
) {
1176 /* We created this file. */
1178 bool need_re_stat
= false;
1179 /* Do all inheritance work after we've
1180 done a successful fstat call and filled
1181 in the stat struct in fsp->fsp_name. */
1183 /* Inherit the ACL if required */
1184 if (lp_inherit_permissions(SNUM(conn
))) {
1185 inherit_access_posix_acl(conn
,
1189 need_re_stat
= true;
1192 /* Change the owner if required. */
1193 if (lp_inherit_owner(SNUM(conn
)) != INHERIT_OWNER_NO
) {
1194 change_file_owner_to_parent_fsp(dirfsp
, fsp
);
1195 need_re_stat
= true;
1199 status
= vfs_stat_fsp(fsp
);
1201 * If we have an fd, this stat should succeed.
1203 if (!NT_STATUS_IS_OK(status
)) {
1204 DBG_ERR("Error doing fstat on open "
1206 smb_fname_str_dbg(smb_fname
),
1214 if (!file_existed
) {
1215 /* File must exist for a stat open. */
1216 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1219 if (S_ISLNK(smb_fname
->st
.st_ex_mode
) &&
1223 * Don't allow stat opens on symlinks directly unless
1224 * it's a POSIX open. Match the return code from
1225 * openat_pathref_fsp().
1227 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1230 if (!fsp
->fsp_flags
.is_pathref
) {
1232 * There is only one legit case where end up here:
1233 * openat_pathref_fsp() failed to open a symlink, so the
1234 * fsp was created by fsp_new() which doesn't set
1235 * is_pathref. Other than that, we should always have a
1236 * pathref fsp at this point. The subsequent checks
1239 if (!(smb_fname
->flags
& SMB_FILENAME_POSIX_PATH
)) {
1240 DBG_ERR("[%s] is not a POSIX pathname\n",
1241 smb_fname_str_dbg(smb_fname
));
1242 return NT_STATUS_INTERNAL_ERROR
;
1244 if (!S_ISLNK(smb_fname
->st
.st_ex_mode
)) {
1245 DBG_ERR("[%s] is not a symlink\n",
1246 smb_fname_str_dbg(smb_fname
));
1247 return NT_STATUS_INTERNAL_ERROR
;
1249 if (fsp_get_pathref_fd(fsp
) != -1) {
1250 DBG_ERR("fd for [%s] is not -1: fd [%d]\n",
1251 smb_fname_str_dbg(smb_fname
),
1252 fsp_get_pathref_fd(fsp
));
1253 return NT_STATUS_INTERNAL_ERROR
;
1258 * Access to streams is checked by checking the basefile and
1259 * that has already been checked by check_base_file_access()
1260 * in create_file_unixpath().
1262 if (!fsp_is_alternate_stream(fsp
)) {
1263 status
= smbd_check_access_rights_fsp(dirfsp
,
1268 if (NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
) &&
1270 S_ISLNK(smb_fname
->st
.st_ex_mode
)) {
1271 /* This is a POSIX stat open for delete
1272 * or rename on a symlink that points
1273 * nowhere. Allow. */
1274 DEBUG(10,("open_file: allowing POSIX "
1275 "open on bad symlink %s\n",
1276 smb_fname_str_dbg(smb_fname
)));
1277 status
= NT_STATUS_OK
;
1280 if (!NT_STATUS_IS_OK(status
)) {
1281 DBG_DEBUG("smbd_check_access_rights_fsp on file "
1290 fsp
->file_id
= vfs_file_id_from_sbuf(conn
, &smb_fname
->st
);
1291 fsp
->vuid
= req
? req
->vuid
: UID_FIELD_INVALID
;
1292 fsp
->file_pid
= req
? req
->smbpid
: 0;
1293 fsp
->fsp_flags
.can_lock
= true;
1294 fsp
->fsp_flags
.can_read
= ((access_mask
& FILE_READ_DATA
) != 0);
1295 fsp
->fsp_flags
.can_write
=
1297 ((access_mask
& (FILE_WRITE_DATA
| FILE_APPEND_DATA
)) != 0);
1298 if (fsp
->fsp_name
->twrp
!= 0) {
1299 fsp
->fsp_flags
.can_write
= false;
1301 fsp
->print_file
= NULL
;
1302 fsp
->fsp_flags
.modified
= false;
1303 fsp
->sent_oplock_break
= NO_BREAK_SENT
;
1304 fsp
->fsp_flags
.is_directory
= false;
1305 if (is_in_path(smb_fname
->base_name
,
1306 conn
->aio_write_behind_list
,
1307 posix_open
? true : conn
->case_sensitive
)) {
1308 fsp
->fsp_flags
.aio_write_behind
= true;
1311 DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
1312 conn
->session_info
->unix_info
->unix_name
,
1313 smb_fname_str_dbg(smb_fname
),
1314 BOOLSTR(fsp
->fsp_flags
.can_read
),
1315 BOOLSTR(fsp
->fsp_flags
.can_write
),
1316 conn
->num_files_open
));
1318 return NT_STATUS_OK
;
1321 static bool mask_conflict(
1322 uint32_t new_access
,
1323 uint32_t existing_access
,
1324 uint32_t access_mask
,
1325 uint32_t new_sharemode
,
1326 uint32_t existing_sharemode
,
1327 uint32_t sharemode_mask
)
1329 bool want_access
= (new_access
& access_mask
);
1330 bool allow_existing
= (existing_sharemode
& sharemode_mask
);
1331 bool have_access
= (existing_access
& access_mask
);
1332 bool allow_new
= (new_sharemode
& sharemode_mask
);
1334 if (want_access
&& !allow_existing
) {
1335 DBG_DEBUG("Access request 0x%"PRIx32
"/0x%"PRIx32
" conflicts "
1336 "with existing sharemode 0x%"PRIx32
"/0x%"PRIx32
"\n",
1343 if (have_access
&& !allow_new
) {
1344 DBG_DEBUG("Sharemode request 0x%"PRIx32
"/0x%"PRIx32
" conflicts "
1345 "with existing access 0x%"PRIx32
"/0x%"PRIx32
"\n",
1355 /****************************************************************************
1356 Check if we can open a file with a share mode.
1357 Returns True if conflict, False if not.
1358 ****************************************************************************/
1360 static const uint32_t conflicting_access
=
1367 static bool share_conflict(uint32_t e_access_mask
,
1368 uint32_t e_share_access
,
1369 uint32_t access_mask
,
1370 uint32_t share_access
)
1374 DBG_DEBUG("existing access_mask = 0x%"PRIx32
", "
1375 "existing share access = 0x%"PRIx32
", "
1376 "access_mask = 0x%"PRIx32
", "
1377 "share_access = 0x%"PRIx32
"\n",
1383 if ((e_access_mask
& conflicting_access
) == 0) {
1384 DBG_DEBUG("No conflict due to "
1385 "existing access_mask = 0x%"PRIx32
"\n",
1389 if ((access_mask
& conflicting_access
) == 0) {
1390 DBG_DEBUG("No conflict due to access_mask = 0x%"PRIx32
"\n",
1395 conflict
= mask_conflict(
1396 access_mask
, e_access_mask
, FILE_WRITE_DATA
| FILE_APPEND_DATA
,
1397 share_access
, e_share_access
, FILE_SHARE_WRITE
);
1398 conflict
|= mask_conflict(
1399 access_mask
, e_access_mask
, FILE_READ_DATA
| FILE_EXECUTE
,
1400 share_access
, e_share_access
, FILE_SHARE_READ
);
1401 conflict
|= mask_conflict(
1402 access_mask
, e_access_mask
, DELETE_ACCESS
,
1403 share_access
, e_share_access
, FILE_SHARE_DELETE
);
1405 DBG_DEBUG("conflict=%s\n", conflict
? "true" : "false");
1409 #if defined(DEVELOPER)
1411 struct validate_my_share_entries_state
{
1412 struct smbd_server_connection
*sconn
;
1414 struct server_id self
;
1417 static bool validate_my_share_entries_fn(
1418 struct share_mode_entry
*e
,
1422 struct validate_my_share_entries_state
*state
= private_data
;
1425 if (!server_id_equal(&state
->self
, &e
->pid
)) {
1429 if (e
->op_mid
== 0) {
1430 /* INTERNAL_OPEN_ONLY */
1434 fsp
= file_find_dif(state
->sconn
, state
->fid
, e
->share_file_id
);
1436 DBG_ERR("PANIC : %s\n",
1437 share_mode_str(talloc_tos(), 0, &state
->fid
, e
));
1438 smb_panic("validate_my_share_entries: Cannot match a "
1439 "share entry with an open file\n");
1442 if (((uint16_t)fsp
->oplock_type
) != e
->op_type
) {
1451 DBG_ERR("validate_my_share_entries: PANIC : %s\n",
1452 share_mode_str(talloc_tos(), 0, &state
->fid
, e
));
1453 str
= talloc_asprintf(talloc_tos(),
1454 "validate_my_share_entries: "
1455 "file %s, oplock_type = 0x%x, op_type = 0x%x\n",
1456 fsp
->fsp_name
->base_name
,
1457 (unsigned int)fsp
->oplock_type
,
1458 (unsigned int)e
->op_type
);
1467 * Allowed access mask for stat opens relevant to oplocks
1469 bool is_oplock_stat_open(uint32_t access_mask
)
1471 const uint32_t stat_open_bits
=
1472 (SYNCHRONIZE_ACCESS
|
1473 FILE_READ_ATTRIBUTES
|
1474 FILE_WRITE_ATTRIBUTES
);
1476 return (((access_mask
& stat_open_bits
) != 0) &&
1477 ((access_mask
& ~stat_open_bits
) == 0));
1481 * Allowed access mask for stat opens relevant to leases
1483 bool is_lease_stat_open(uint32_t access_mask
)
1485 const uint32_t stat_open_bits
=
1486 (SYNCHRONIZE_ACCESS
|
1487 FILE_READ_ATTRIBUTES
|
1488 FILE_WRITE_ATTRIBUTES
|
1489 READ_CONTROL_ACCESS
);
1491 return (((access_mask
& stat_open_bits
) != 0) &&
1492 ((access_mask
& ~stat_open_bits
) == 0));
1495 struct has_delete_on_close_state
{
1499 static bool has_delete_on_close_fn(
1500 struct share_mode_entry
*e
,
1504 struct has_delete_on_close_state
*state
= private_data
;
1505 state
->ret
= !share_entry_stale_pid(e
);
1509 static bool has_delete_on_close(struct share_mode_lock
*lck
,
1512 struct has_delete_on_close_state state
= { .ret
= false };
1515 if (!is_delete_on_close_set(lck
, name_hash
)) {
1519 ok
= share_mode_forall_entries(lck
, has_delete_on_close_fn
, &state
);
1521 DBG_DEBUG("share_mode_forall_entries failed\n");
1527 static void share_mode_flags_restrict(
1528 struct share_mode_lock
*lck
,
1529 uint32_t access_mask
,
1530 uint32_t share_mode
,
1531 uint32_t lease_type
)
1533 uint32_t existing_access_mask
, existing_share_mode
;
1534 uint32_t existing_lease_type
;
1536 share_mode_flags_get(
1538 &existing_access_mask
,
1539 &existing_share_mode
,
1540 &existing_lease_type
);
1542 existing_access_mask
|= access_mask
;
1543 if (access_mask
& conflicting_access
) {
1544 existing_share_mode
&= share_mode
;
1546 existing_lease_type
|= lease_type
;
1548 share_mode_flags_set(
1550 existing_access_mask
,
1551 existing_share_mode
,
1552 existing_lease_type
,
1556 /****************************************************************************
1557 Deal with share modes
1558 Invariant: Share mode must be locked on entry and exit.
1559 Returns -1 on error, or number of share modes on success (may be zero).
1560 ****************************************************************************/
1562 struct open_mode_check_state
{
1564 uint32_t access_mask
;
1565 uint32_t share_access
;
1566 uint32_t lease_type
;
1569 static bool open_mode_check_fn(
1570 struct share_mode_entry
*e
,
1574 struct open_mode_check_state
*state
= private_data
;
1575 bool disconnected
, stale
;
1576 uint32_t access_mask
, share_access
, lease_type
;
1578 disconnected
= server_id_is_disconnected(&e
->pid
);
1583 access_mask
= state
->access_mask
| e
->access_mask
;
1584 share_access
= state
->share_access
;
1585 if (e
->access_mask
& conflicting_access
) {
1586 share_access
&= e
->share_access
;
1588 lease_type
= state
->lease_type
| get_lease_type(e
, state
->fid
);
1590 if ((access_mask
== state
->access_mask
) &&
1591 (share_access
== state
->share_access
) &&
1592 (lease_type
== state
->lease_type
)) {
1596 stale
= share_entry_stale_pid(e
);
1601 state
->access_mask
= access_mask
;
1602 state
->share_access
= share_access
;
1603 state
->lease_type
= lease_type
;
1608 static NTSTATUS
open_mode_check(connection_struct
*conn
,
1610 struct share_mode_lock
*lck
,
1611 uint32_t access_mask
,
1612 uint32_t share_access
)
1614 struct open_mode_check_state state
;
1616 bool modified
= false;
1618 if (is_oplock_stat_open(access_mask
)) {
1619 /* Stat open that doesn't trigger oplock breaks or share mode
1620 * checks... ! JRA. */
1621 return NT_STATUS_OK
;
1625 * Check if the share modes will give us access.
1628 #if defined(DEVELOPER)
1630 struct validate_my_share_entries_state validate_state
= {
1631 .sconn
= conn
->sconn
,
1633 .self
= messaging_server_id(conn
->sconn
->msg_ctx
),
1635 ok
= share_mode_forall_entries(
1636 lck
, validate_my_share_entries_fn
, &validate_state
);
1641 share_mode_flags_get(
1642 lck
, &state
.access_mask
, &state
.share_access
, NULL
);
1644 conflict
= share_conflict(
1650 DBG_DEBUG("No conflict due to share_mode_flags access\n");
1651 return NT_STATUS_OK
;
1654 state
= (struct open_mode_check_state
) {
1656 .share_access
= (FILE_SHARE_READ
|
1662 * Walk the share mode array to recalculate d->flags
1665 ok
= share_mode_forall_entries(lck
, open_mode_check_fn
, &state
);
1667 DBG_DEBUG("share_mode_forall_entries failed\n");
1668 return NT_STATUS_INTERNAL_ERROR
;
1671 share_mode_flags_set(
1679 * We only end up here if we had a sharing violation
1680 * from d->flags and have recalculated it.
1682 return NT_STATUS_SHARING_VIOLATION
;
1685 conflict
= share_conflict(
1691 DBG_DEBUG("No conflict due to share_mode_flags access\n");
1692 return NT_STATUS_OK
;
1695 return NT_STATUS_SHARING_VIOLATION
;
1699 * Send a break message to the oplock holder and delay the open for
1703 NTSTATUS
send_break_message(struct messaging_context
*msg_ctx
,
1704 const struct file_id
*id
,
1705 const struct share_mode_entry
*exclusive
,
1708 struct oplock_break_message msg
= {
1710 .share_file_id
= exclusive
->share_file_id
,
1711 .break_to
= break_to
,
1713 enum ndr_err_code ndr_err
;
1715 DATA_BLOB blob
= {.data
= msgbuf
, .length
= sizeof(msgbuf
)};
1719 struct server_id_buf buf
;
1720 DBG_DEBUG("Sending break message to %s\n",
1721 server_id_str_buf(exclusive
->pid
, &buf
));
1722 NDR_PRINT_DEBUG(oplock_break_message
, &msg
);
1725 ndr_err
= ndr_push_struct_into_fixed_blob(
1728 (ndr_push_flags_fn_t
)ndr_push_oplock_break_message
);
1729 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
1730 DBG_WARNING("ndr_push_oplock_break_message failed: %s\n",
1731 ndr_errstr(ndr_err
));
1732 return ndr_map_error2ntstatus(ndr_err
);
1735 status
= messaging_send(msg_ctx
,
1737 MSG_SMB_BREAK_REQUEST
,
1739 if (!NT_STATUS_IS_OK(status
)) {
1740 DEBUG(3, ("Could not send oplock break message: %s\n",
1741 nt_errstr(status
)));
1747 struct validate_oplock_types_state
{
1753 uint32_t num_non_stat_opens
;
1756 static bool validate_oplock_types_fn(
1757 struct share_mode_entry
*e
,
1761 struct validate_oplock_types_state
*state
= private_data
;
1763 if (e
->op_mid
== 0) {
1764 /* INTERNAL_OPEN_ONLY */
1768 if (e
->op_type
== NO_OPLOCK
&& is_oplock_stat_open(e
->access_mask
)) {
1770 * We ignore stat opens in the table - they always
1771 * have NO_OPLOCK and never get or cause breaks. JRA.
1776 state
->num_non_stat_opens
+= 1;
1778 if (BATCH_OPLOCK_TYPE(e
->op_type
)) {
1779 /* batch - can only be one. */
1780 if (share_entry_stale_pid(e
)) {
1781 DBG_DEBUG("Found stale batch oplock\n");
1784 if (state
->ex_or_batch
||
1788 DBG_ERR("Bad batch oplock entry\n");
1789 state
->valid
= false;
1792 state
->batch
= true;
1795 if (EXCLUSIVE_OPLOCK_TYPE(e
->op_type
)) {
1796 if (share_entry_stale_pid(e
)) {
1797 DBG_DEBUG("Found stale duplicate oplock\n");
1800 /* Exclusive or batch - can only be one. */
1801 if (state
->ex_or_batch
||
1804 DBG_ERR("Bad exclusive or batch oplock entry\n");
1805 state
->valid
= false;
1808 state
->ex_or_batch
= true;
1811 if (LEVEL_II_OPLOCK_TYPE(e
->op_type
)) {
1812 if (state
->batch
|| state
->ex_or_batch
) {
1813 if (share_entry_stale_pid(e
)) {
1814 DBG_DEBUG("Found stale LevelII oplock\n");
1817 DBG_DEBUG("Bad levelII oplock entry\n");
1818 state
->valid
= false;
1821 state
->level2
= true;
1824 if (e
->op_type
== NO_OPLOCK
) {
1825 if (state
->batch
|| state
->ex_or_batch
) {
1826 if (share_entry_stale_pid(e
)) {
1827 DBG_DEBUG("Found stale NO_OPLOCK entry\n");
1830 DBG_ERR("Bad no oplock entry\n");
1831 state
->valid
= false;
1834 state
->no_oplock
= true;
1841 * Do internal consistency checks on the share mode for a file.
1844 static bool validate_oplock_types(struct share_mode_lock
*lck
)
1846 struct validate_oplock_types_state state
= { .valid
= true };
1847 static bool skip_validation
;
1851 if (skip_validation
) {
1855 validate
= lp_parm_bool(-1, "smbd", "validate_oplock_types", false);
1857 DBG_DEBUG("smbd:validate_oplock_types not set to yes\n");
1858 skip_validation
= true;
1862 ok
= share_mode_forall_entries(lck
, validate_oplock_types_fn
, &state
);
1864 DBG_DEBUG("share_mode_forall_entries failed\n");
1868 DBG_DEBUG("Got invalid oplock configuration\n");
1872 if ((state
.batch
|| state
.ex_or_batch
) &&
1873 (state
.num_non_stat_opens
!= 1)) {
1874 DBG_WARNING("got batch (%d) or ex (%d) non-exclusively "
1877 (int)state
.ex_or_batch
,
1878 state
.num_non_stat_opens
);
1885 static bool is_same_lease(const files_struct
*fsp
,
1886 const struct share_mode_entry
*e
,
1887 const struct smb2_lease
*lease
)
1889 if (e
->op_type
!= LEASE_OPLOCK
) {
1892 if (lease
== NULL
) {
1896 return smb2_lease_equal(fsp_client_guid(fsp
),
1902 static bool file_has_brlocks(files_struct
*fsp
)
1904 struct byte_range_lock
*br_lck
;
1906 br_lck
= brl_get_locks_readonly(fsp
);
1910 return (brl_num_locks(br_lck
) > 0);
1913 struct fsp_lease
*find_fsp_lease(struct files_struct
*new_fsp
,
1914 const struct smb2_lease_key
*key
,
1915 uint32_t current_state
,
1916 uint16_t lease_version
,
1917 uint16_t lease_epoch
)
1919 struct files_struct
*fsp
;
1922 * TODO: Measure how expensive this loop is with thousands of open
1926 for (fsp
= file_find_di_first(new_fsp
->conn
->sconn
, new_fsp
->file_id
, true);
1928 fsp
= file_find_di_next(fsp
, true)) {
1930 if (fsp
== new_fsp
) {
1933 if (fsp
->oplock_type
!= LEASE_OPLOCK
) {
1936 if (smb2_lease_key_equal(&fsp
->lease
->lease
.lease_key
, key
)) {
1937 fsp
->lease
->ref_count
+= 1;
1942 /* Not found - must be leased in another smbd. */
1943 new_fsp
->lease
= talloc_zero(new_fsp
->conn
->sconn
, struct fsp_lease
);
1944 if (new_fsp
->lease
== NULL
) {
1947 new_fsp
->lease
->ref_count
= 1;
1948 new_fsp
->lease
->sconn
= new_fsp
->conn
->sconn
;
1949 new_fsp
->lease
->lease
.lease_key
= *key
;
1950 new_fsp
->lease
->lease
.lease_state
= current_state
;
1952 * We internally treat all leases as V2 and update
1953 * the epoch, but when sending breaks it matters if
1954 * the requesting lease was v1 or v2.
1956 new_fsp
->lease
->lease
.lease_version
= lease_version
;
1957 new_fsp
->lease
->lease
.lease_epoch
= lease_epoch
;
1958 return new_fsp
->lease
;
1961 static NTSTATUS
try_lease_upgrade(struct files_struct
*fsp
,
1962 struct share_mode_lock
*lck
,
1963 const struct GUID
*client_guid
,
1964 const struct smb2_lease
*lease
,
1968 uint32_t current_state
, breaking_to_requested
, breaking_to_required
;
1970 uint16_t lease_version
, epoch
;
1971 uint32_t existing
, requested
;
1974 status
= leases_db_get(
1980 &breaking_to_requested
,
1981 &breaking_to_required
,
1984 if (!NT_STATUS_IS_OK(status
)) {
1988 fsp
->lease
= find_fsp_lease(
1994 if (fsp
->lease
== NULL
) {
1995 DEBUG(1, ("Did not find existing lease for file %s\n",
1997 return NT_STATUS_NO_MEMORY
;
2001 * Upgrade only if the requested lease is a strict upgrade.
2003 existing
= current_state
;
2004 requested
= lease
->lease_state
;
2007 * Tricky: This test makes sure that "requested" is a
2008 * strict bitwise superset of "existing".
2010 do_upgrade
= ((existing
& requested
) == existing
);
2013 * Upgrade only if there's a change.
2015 do_upgrade
&= (granted
!= existing
);
2018 * Upgrade only if other leases don't prevent what was asked
2021 do_upgrade
&= (granted
== requested
);
2024 * only upgrade if we are not in breaking state
2026 do_upgrade
&= !breaking
;
2028 DEBUG(10, ("existing=%"PRIu32
", requested=%"PRIu32
", "
2029 "granted=%"PRIu32
", do_upgrade=%d\n",
2030 existing
, requested
, granted
, (int)do_upgrade
));
2033 NTSTATUS set_status
;
2035 current_state
= granted
;
2038 set_status
= leases_db_set(
2043 breaking_to_requested
,
2044 breaking_to_required
,
2048 if (!NT_STATUS_IS_OK(set_status
)) {
2049 DBG_DEBUG("leases_db_set failed: %s\n",
2050 nt_errstr(set_status
));
2055 fsp_lease_update(fsp
);
2057 return NT_STATUS_OK
;
2060 static NTSTATUS
grant_new_fsp_lease(struct files_struct
*fsp
,
2061 struct share_mode_lock
*lck
,
2062 const struct GUID
*client_guid
,
2063 const struct smb2_lease
*lease
,
2068 fsp
->lease
= talloc_zero(fsp
->conn
->sconn
, struct fsp_lease
);
2069 if (fsp
->lease
== NULL
) {
2070 return NT_STATUS_INSUFFICIENT_RESOURCES
;
2072 fsp
->lease
->ref_count
= 1;
2073 fsp
->lease
->sconn
= fsp
->conn
->sconn
;
2074 fsp
->lease
->lease
.lease_version
= lease
->lease_version
;
2075 fsp
->lease
->lease
.lease_key
= lease
->lease_key
;
2076 fsp
->lease
->lease
.parent_lease_key
= lease
->parent_lease_key
;
2077 fsp
->lease
->lease
.lease_flags
= lease
->lease_flags
;
2078 fsp
->lease
->lease
.lease_state
= granted
;
2079 fsp
->lease
->lease
.lease_epoch
= lease
->lease_epoch
+ 1;
2081 status
= leases_db_add(client_guid
,
2084 fsp
->lease
->lease
.lease_state
,
2085 fsp
->lease
->lease
.lease_version
,
2086 fsp
->lease
->lease
.lease_epoch
,
2087 fsp
->conn
->connectpath
,
2088 fsp
->fsp_name
->base_name
,
2089 fsp
->fsp_name
->stream_name
);
2090 if (!NT_STATUS_IS_OK(status
)) {
2091 DEBUG(10, ("%s: leases_db_add failed: %s\n", __func__
,
2092 nt_errstr(status
)));
2093 TALLOC_FREE(fsp
->lease
);
2094 return NT_STATUS_INSUFFICIENT_RESOURCES
;
2098 * We used to set lck->data->modified=true here without
2099 * actually modifying lck->data, triggering a needless
2100 * writeback of lck->data.
2102 * Apart from that writeback, setting modified=true has the
2103 * effect of triggering all waiters for this file to
2104 * retry. This only makes sense if any blocking condition
2105 * (i.e. waiting for a lease to be downgraded or removed) is
2106 * gone. This routine here only adds a lease, so it will never
2107 * free up resources that blocked waiters can now claim. So
2108 * that second effect also does not matter in this
2109 * routine. Thus setting lck->data->modified=true does not
2110 * need to be done here.
2113 return NT_STATUS_OK
;
2116 static NTSTATUS
grant_fsp_lease(struct files_struct
*fsp
,
2117 struct share_mode_lock
*lck
,
2118 const struct smb2_lease
*lease
,
2121 const struct GUID
*client_guid
= fsp_client_guid(fsp
);
2124 status
= try_lease_upgrade(fsp
, lck
, client_guid
, lease
, granted
);
2126 if (NT_STATUS_EQUAL(status
, NT_STATUS_NOT_FOUND
)) {
2127 status
= grant_new_fsp_lease(
2128 fsp
, lck
, client_guid
, lease
, granted
);
2134 static int map_lease_type_to_oplock(uint32_t lease_type
)
2136 int result
= NO_OPLOCK
;
2138 switch (lease_type
) {
2139 case SMB2_LEASE_READ
|SMB2_LEASE_WRITE
|SMB2_LEASE_HANDLE
:
2140 result
= BATCH_OPLOCK
|EXCLUSIVE_OPLOCK
;
2142 case SMB2_LEASE_READ
|SMB2_LEASE_WRITE
:
2143 result
= EXCLUSIVE_OPLOCK
;
2145 case SMB2_LEASE_READ
|SMB2_LEASE_HANDLE
:
2146 case SMB2_LEASE_READ
:
2147 result
= LEVEL_II_OPLOCK
;
2154 struct blocker_debug_state
{
2155 size_t num_blockers
;
2158 struct delay_for_oplock_state
{
2159 struct files_struct
*fsp
;
2160 const struct smb2_lease
*lease
;
2161 bool will_overwrite
;
2162 uint32_t delay_mask
;
2163 bool first_open_attempt
;
2164 bool got_handle_lease
;
2166 bool disallow_write_lease
;
2167 uint32_t total_lease_types
;
2169 struct blocker_debug_state
*blocker_debug_state
;
2172 static int blocker_debug_state_destructor(struct blocker_debug_state
*state
)
2174 if (state
->num_blockers
== 0) {
2178 DBG_DEBUG("blocker_debug_state [%p] num_blockers [%zu]\n",
2179 state
, state
->num_blockers
);
2183 static void delay_for_oplock_fn_watch_done(struct tevent_req
*subreq
);
2185 static bool delay_for_oplock_fn(
2186 struct share_mode_entry
*e
,
2190 struct delay_for_oplock_state
*state
= private_data
;
2191 struct files_struct
*fsp
= state
->fsp
;
2192 const struct smb2_lease
*lease
= state
->lease
;
2193 bool e_is_lease
= (e
->op_type
== LEASE_OPLOCK
);
2194 uint32_t e_lease_type
= SMB2_LEASE_NONE
;
2196 bool lease_is_breaking
= false;
2197 struct tevent_req
*subreq
= NULL
;
2198 struct server_id_buf idbuf
= {};
2203 if (lease
!= NULL
) {
2204 bool our_lease
= is_same_lease(fsp
, e
, lease
);
2206 DBG_DEBUG("Ignoring our own lease\n");
2211 status
= leases_db_get(
2215 &e_lease_type
, /* current_state */
2217 NULL
, /* breaking_to_requested */
2218 NULL
, /* breaking_to_required */
2219 NULL
, /* lease_version */
2223 * leases_db_get() can return NT_STATUS_NOT_FOUND
2224 * if the share_mode_entry e is stale and the
2225 * lease record was already removed. In this case return
2226 * false so the traverse continues.
2229 if (NT_STATUS_EQUAL(status
, NT_STATUS_NOT_FOUND
) &&
2230 share_entry_stale_pid(e
))
2232 struct GUID_txt_buf guid_strbuf
;
2233 struct file_id_buf file_id_strbuf
;
2234 DBG_DEBUG("leases_db_get for client_guid [%s] "
2235 "lease_key [%"PRIu64
"/%"PRIu64
"] "
2236 "file_id [%s] failed for stale "
2237 "share_mode_entry\n",
2238 GUID_buf_string(&e
->client_guid
, &guid_strbuf
),
2239 e
->lease_key
.data
[0],
2240 e
->lease_key
.data
[1],
2241 file_id_str_buf(fsp
->file_id
, &file_id_strbuf
));
2244 if (!NT_STATUS_IS_OK(status
)) {
2245 struct GUID_txt_buf guid_strbuf
;
2246 struct file_id_buf file_id_strbuf
;
2247 DBG_ERR("leases_db_get for client_guid [%s] "
2248 "lease_key [%"PRIu64
"/%"PRIu64
"] "
2249 "file_id [%s] failed: %s\n",
2250 GUID_buf_string(&e
->client_guid
, &guid_strbuf
),
2251 e
->lease_key
.data
[0],
2252 e
->lease_key
.data
[1],
2253 file_id_str_buf(fsp
->file_id
, &file_id_strbuf
),
2255 smb_panic("leases_db_get() failed");
2258 e_lease_type
= get_lease_type(e
, fsp
->file_id
);
2261 if (((e_lease_type
& ~state
->total_lease_types
) != 0) &&
2262 !share_entry_stale_pid(e
))
2264 state
->total_lease_types
|= e_lease_type
;
2267 if (!state
->got_handle_lease
&&
2268 ((e_lease_type
& SMB2_LEASE_HANDLE
) != 0) &&
2269 !share_entry_stale_pid(e
)) {
2270 state
->got_handle_lease
= true;
2273 if (!state
->got_oplock
&&
2274 (e
->op_type
!= NO_OPLOCK
) &&
2275 (e
->op_type
!= LEASE_OPLOCK
) &&
2276 !share_entry_stale_pid(e
)) {
2277 state
->got_oplock
= true;
2281 * Two things prevent a write lease
2284 * 1. Any oplock or lease (even broken to NONE)
2285 * 2. An open with an access mask other than
2286 * FILE_READ_ATTRIBUTES, FILE_WRITE_ATTRIBUTES
2287 * or SYNCHRONIZE_ACCESS
2289 if (!state
->disallow_write_lease
&&
2290 (e
->op_type
!= NO_OPLOCK
|| !is_oplock_stat_open(e
->access_mask
)) &&
2291 !is_same_lease(fsp
, e
, lease
) &&
2292 !share_entry_stale_pid(e
))
2294 state
->disallow_write_lease
= true;
2297 if (e_is_lease
&& is_lease_stat_open(fsp
->access_mask
)) {
2301 break_to
= e_lease_type
& ~state
->delay_mask
;
2303 if (state
->will_overwrite
) {
2304 break_to
&= ~(SMB2_LEASE_HANDLE
|SMB2_LEASE_READ
);
2307 DBG_DEBUG("e_lease_type %u, will_overwrite: %u\n",
2308 (unsigned)e_lease_type
,
2309 (unsigned)state
->will_overwrite
);
2311 if ((e_lease_type
& ~break_to
) == 0) {
2312 if (lease_is_breaking
) {
2313 state
->delay
= true;
2318 if (share_entry_stale_pid(e
)) {
2322 if (state
->will_overwrite
) {
2324 * If we break anyway break to NONE directly.
2325 * Otherwise vfs_set_filelen() will trigger the
2328 break_to
&= ~(SMB2_LEASE_READ
|SMB2_LEASE_WRITE
);
2333 * Oplocks only support breaking to R or NONE.
2335 break_to
&= ~(SMB2_LEASE_HANDLE
|SMB2_LEASE_WRITE
);
2338 DBG_DEBUG("breaking from %d to %d\n",
2342 fsp
->conn
->sconn
->msg_ctx
, &fsp
->file_id
, e
, break_to
);
2343 if (e_lease_type
& state
->delay_mask
) {
2344 state
->delay
= true;
2346 if (lease_is_breaking
&& !state
->first_open_attempt
) {
2347 state
->delay
= true;
2350 if (!state
->delay
) {
2354 if (state
->blocker_debug_state
== NULL
) {
2358 subreq
= server_id_watch_send(state
->blocker_debug_state
,
2359 fsp
->conn
->sconn
->ev_ctx
,
2361 if (subreq
== NULL
) {
2362 DBG_ERR("server_id_watch_send(%s) returned NULL\n",
2363 server_id_str_buf(e
->pid
, &idbuf
));
2367 tevent_req_set_callback(subreq
,
2368 delay_for_oplock_fn_watch_done
,
2369 state
->blocker_debug_state
);
2371 state
->blocker_debug_state
->num_blockers
++;
2373 DBG_DEBUG("Starting to watch pid [%s] state [%p] num_blockers [%zu]\n",
2374 server_id_str_buf(e
->pid
, &idbuf
),
2375 state
->blocker_debug_state
,
2376 state
->blocker_debug_state
->num_blockers
);
2381 static void delay_for_oplock_fn_watch_done(struct tevent_req
*subreq
)
2383 struct blocker_debug_state
*blocker_debug_state
= tevent_req_callback_data(
2384 subreq
, struct blocker_debug_state
);
2385 struct server_id pid
= {};
2386 struct server_id_buf idbuf
= {};
2389 ret
= server_id_watch_recv(subreq
, &pid
);
2391 DBG_ERR("server_id_watch_recv failed %s\n", strerror(ret
));
2395 DBG_DEBUG("state [%p] server_id_watch_recv() returned pid [%s] exited\n",
2396 blocker_debug_state
,
2397 server_id_str_buf(pid
, &idbuf
));
2400 static NTSTATUS
delay_for_oplock(files_struct
*fsp
,
2402 const struct smb2_lease
*lease
,
2403 struct share_mode_lock
*lck
,
2404 bool have_sharing_violation
,
2405 uint32_t create_disposition
,
2406 bool first_open_attempt
,
2409 struct blocker_debug_state
**blocker_debug_state
)
2411 struct delay_for_oplock_state state
= {
2414 .first_open_attempt
= first_open_attempt
,
2421 *poplock_type
= NO_OPLOCK
;
2424 if (oplock_request
== LEASE_OPLOCK
) {
2425 if (lease
== NULL
) {
2427 * The SMB2 layer should have checked this
2429 return NT_STATUS_INTERNAL_ERROR
;
2432 requested
= lease
->lease_state
;
2433 if (fsp
->fsp_flags
.is_directory
) {
2435 * According to "MS-FSA 2.1.5.18 Server Requests an
2436 * Oplock" this should fail with
2437 * STATUS_INVALID_PARAMETER, but Windows 2022 just
2438 * ignores the SMB2_LEASE_WRITE bit.
2440 requested
&= ~SMB2_LEASE_WRITE
;
2443 requested
= map_oplock_to_lease_type(
2444 oplock_request
& ~SAMBA_PRIVATE_OPLOCK_MASK
);
2447 share_mode_flags_get(lck
, NULL
, NULL
, &state
.total_lease_types
);
2449 if (is_oplock_stat_open(fsp
->access_mask
)) {
2453 if (lp_parm_bool(GLOBAL_SECTION_SNUM
,
2458 state
.blocker_debug_state
= talloc_zero(fsp
,
2459 struct blocker_debug_state
);
2460 if (state
.blocker_debug_state
== NULL
) {
2461 return NT_STATUS_NO_MEMORY
;
2463 talloc_steal(talloc_tos(), state
.blocker_debug_state
);
2465 talloc_set_destructor(state
.blocker_debug_state
,
2466 blocker_debug_state_destructor
);
2469 state
.delay_mask
= have_sharing_violation
?
2470 SMB2_LEASE_HANDLE
: SMB2_LEASE_WRITE
;
2472 switch (create_disposition
) {
2473 case FILE_SUPERSEDE
:
2474 case FILE_OVERWRITE
:
2475 case FILE_OVERWRITE_IF
:
2476 state
.will_overwrite
= true;
2479 state
.will_overwrite
= false;
2483 state
.total_lease_types
= SMB2_LEASE_NONE
;
2484 ok
= share_mode_forall_entries(lck
, delay_for_oplock_fn
, &state
);
2486 return NT_STATUS_INTERNAL_ERROR
;
2490 *blocker_debug_state
= state
.blocker_debug_state
;
2491 return NT_STATUS_RETRY
;
2495 if (have_sharing_violation
) {
2496 return NT_STATUS_SHARING_VIOLATION
;
2499 granted
= requested
;
2501 if (oplock_request
== LEASE_OPLOCK
) {
2502 if (lp_kernel_oplocks(SNUM(fsp
->conn
))) {
2503 DEBUG(10, ("No lease granted because kernel oplocks are enabled\n"));
2504 granted
= SMB2_LEASE_NONE
;
2506 if ((granted
& (SMB2_LEASE_READ
|SMB2_LEASE_WRITE
)) == 0) {
2507 DEBUG(10, ("No read or write lease requested\n"));
2508 granted
= SMB2_LEASE_NONE
;
2510 if (granted
== SMB2_LEASE_WRITE
) {
2511 DEBUG(10, ("pure write lease requested\n"));
2512 granted
= SMB2_LEASE_NONE
;
2514 if (granted
== (SMB2_LEASE_WRITE
|SMB2_LEASE_HANDLE
)) {
2515 DEBUG(10, ("write and handle lease requested\n"));
2516 granted
= SMB2_LEASE_NONE
;
2520 if (lp_locking(fsp
->conn
->params
) && file_has_brlocks(fsp
)) {
2521 DBG_DEBUG("file %s has byte range locks\n",
2523 granted
&= ~SMB2_LEASE_READ
;
2526 if (state
.disallow_write_lease
) {
2528 * Can grant only a write lease
2529 * if there are no other leases
2530 * and no other non-stat opens.
2532 granted
&= ~SMB2_LEASE_WRITE
;
2535 if ((granted
& SMB2_LEASE_READ
) && !(granted
& SMB2_LEASE_WRITE
)) {
2537 (global_client_caps
& CAP_LEVEL_II_OPLOCKS
) &&
2538 lp_level2_oplocks(SNUM(fsp
->conn
));
2540 if (!allow_level2
) {
2541 granted
= SMB2_LEASE_NONE
;
2545 if (oplock_request
== LEASE_OPLOCK
) {
2546 if (state
.got_oplock
) {
2547 granted
&= ~SMB2_LEASE_HANDLE
;
2550 oplock_type
= LEASE_OPLOCK
;
2552 if (state
.got_handle_lease
) {
2553 granted
= SMB2_LEASE_NONE
;
2557 * Reflect possible downgrades from:
2558 * - map_lease_type_to_oplock() => "RH" to just LEVEL_II
2560 oplock_type
= map_lease_type_to_oplock(granted
);
2561 granted
= map_oplock_to_lease_type(oplock_type
);
2564 state
.total_lease_types
|= granted
;
2567 uint32_t acc
, sh
, ls
;
2568 share_mode_flags_get(lck
, &acc
, &sh
, &ls
);
2569 ls
= state
.total_lease_types
;
2570 share_mode_flags_set(lck
, acc
, sh
, ls
, NULL
);
2573 DBG_DEBUG("oplock type 0x%x granted (%s%s%s)(0x%x), on file %s, "
2574 "requested 0x%x (%s%s%s)(0x%x) => total (%s%s%s)(0x%x)\n",
2576 granted
& SMB2_LEASE_READ
? "R":"",
2577 granted
& SMB2_LEASE_WRITE
? "W":"",
2578 granted
& SMB2_LEASE_HANDLE
? "H":"",
2582 requested
& SMB2_LEASE_READ
? "R":"",
2583 requested
& SMB2_LEASE_WRITE
? "W":"",
2584 requested
& SMB2_LEASE_HANDLE
? "H":"",
2586 state
.total_lease_types
& SMB2_LEASE_READ
? "R":"",
2587 state
.total_lease_types
& SMB2_LEASE_WRITE
? "W":"",
2588 state
.total_lease_types
& SMB2_LEASE_HANDLE
? "H":"",
2589 state
.total_lease_types
);
2591 *poplock_type
= oplock_type
;
2592 *pgranted
= granted
;
2593 return NT_STATUS_OK
;
2596 static NTSTATUS
handle_share_mode_lease(
2598 struct share_mode_lock
*lck
,
2599 uint32_t create_disposition
,
2600 uint32_t access_mask
,
2601 uint32_t share_access
,
2603 const struct smb2_lease
*lease
,
2604 bool first_open_attempt
,
2607 struct blocker_debug_state
**blocker_debug_state
)
2609 bool sharing_violation
= false;
2612 *poplock_type
= NO_OPLOCK
;
2615 status
= open_mode_check(
2616 fsp
->conn
, fsp
->file_id
, lck
, access_mask
, share_access
);
2617 if (NT_STATUS_EQUAL(status
, NT_STATUS_SHARING_VIOLATION
)) {
2618 sharing_violation
= true;
2619 status
= NT_STATUS_OK
; /* handled later */
2622 if (!NT_STATUS_IS_OK(status
)) {
2626 if (fsp
->fsp_flags
.is_directory
&&
2627 oplock_request
== LEASE_OPLOCK
&&
2628 !lp_smb3_directory_leases())
2630 DBG_NOTICE("Ignoring disabled DirectoryLease request on [%s]\n",
2632 oplock_request
= NO_OPLOCK
;
2636 if (oplock_request
== INTERNAL_OPEN_ONLY
) {
2637 if (sharing_violation
) {
2638 DBG_DEBUG("Sharing violation for internal open\n");
2639 return NT_STATUS_SHARING_VIOLATION
;
2643 * Internal opens never do oplocks or leases. We don't
2644 * need to go through delay_for_oplock().
2646 return NT_STATUS_OK
;
2649 status
= delay_for_oplock(
2659 blocker_debug_state
);
2660 if (!NT_STATUS_IS_OK(status
)) {
2664 return NT_STATUS_OK
;
2667 static bool request_timed_out(struct smb_request
*req
, struct timeval timeout
)
2669 struct timeval end_time
= timeval_sum(&req
->request_time
, &timeout
);
2670 return timeval_expired(&end_time
);
2673 struct defer_open_state
{
2674 struct smbXsrv_connection
*xconn
;
2678 static void defer_open_done(struct tevent_req
*req
);
2681 * Defer an open and watch a locking.tdb record
2683 * This defers an open that gets rescheduled once the locking.tdb record watch
2684 * is triggered by a change to the record.
2686 * It is used to defer opens that triggered an oplock break and for the SMB1
2687 * sharing violation delay.
2689 static void defer_open(struct share_mode_lock
*lck
,
2690 struct timeval timeout
,
2691 struct smb_request
*req
,
2693 struct blocker_debug_state
**blocker_debug_state
)
2695 struct deferred_open_record
*open_rec
= NULL
;
2696 struct timeval abs_timeout
;
2697 struct defer_open_state
*watch_state
;
2698 struct tevent_req
*watch_req
;
2699 struct timeval_buf tvbuf1
, tvbuf2
;
2700 struct file_id_buf fbuf
;
2703 abs_timeout
= timeval_sum(&req
->request_time
, &timeout
);
2705 DBG_DEBUG("request time [%s] timeout [%s] mid [%" PRIu64
"] "
2707 timeval_str_buf(&req
->request_time
, false, true, &tvbuf1
),
2708 timeval_str_buf(&abs_timeout
, false, true, &tvbuf2
),
2710 file_id_str_buf(id
, &fbuf
));
2712 open_rec
= talloc_zero(NULL
, struct deferred_open_record
);
2713 if (open_rec
== NULL
) {
2715 exit_server("talloc failed");
2718 watch_state
= talloc(open_rec
, struct defer_open_state
);
2719 if (watch_state
== NULL
) {
2720 exit_server("talloc failed");
2722 watch_state
->xconn
= req
->xconn
;
2723 watch_state
->mid
= req
->mid
;
2725 DBG_DEBUG("deferring mid %" PRIu64
"\n", req
->mid
);
2727 watch_req
= share_mode_watch_send(
2731 (struct server_id
){0});
2732 if (watch_req
== NULL
) {
2733 exit_server("Could not watch share mode record");
2735 tevent_req_set_callback(watch_req
, defer_open_done
, watch_state
);
2737 talloc_move(watch_req
, blocker_debug_state
);
2739 ok
= tevent_req_set_endtime(watch_req
, req
->sconn
->ev_ctx
, abs_timeout
);
2741 exit_server("tevent_req_set_endtime failed");
2744 ok
= push_deferred_open_message_smb(req
, timeout
, id
, open_rec
);
2747 exit_server("push_deferred_open_message_smb failed");
2751 static void defer_open_done(struct tevent_req
*req
)
2753 struct defer_open_state
*state
= tevent_req_callback_data(
2754 req
, struct defer_open_state
);
2758 status
= share_mode_watch_recv(req
, NULL
, NULL
);
2760 if (!NT_STATUS_IS_OK(status
)) {
2761 DBG_ERR("share_mode_watch_recv() returned %s, "
2762 "rescheduling mid %" PRIu64
"\n",
2763 nt_errstr(status
), state
->mid
);
2765 * Even if it failed, retry anyway. TODO: We need a way to
2766 * tell a re-scheduled open about that error.
2770 DEBUG(10, ("scheduling mid %llu\n", (unsigned long long)state
->mid
));
2772 ret
= schedule_deferred_open_message_smb(state
->xconn
, state
->mid
);
2778 * Actually attempt the kernel oplock polling open.
2781 static void poll_open_fn(struct tevent_context
*ev
,
2782 struct tevent_timer
*te
,
2783 struct timeval current_time
,
2786 struct deferred_open_record
*open_rec
= talloc_get_type_abort(
2787 private_data
, struct deferred_open_record
);
2790 TALLOC_FREE(open_rec
->watch_req
);
2792 ok
= schedule_deferred_open_message_smb(
2793 open_rec
->xconn
, open_rec
->mid
);
2795 exit_server("schedule_deferred_open_message_smb failed");
2797 DBG_DEBUG("timer fired. Retrying open !\n");
2800 static void poll_open_done(struct tevent_req
*subreq
);
2802 struct poll_open_setup_watcher_state
{
2803 TALLOC_CTX
*mem_ctx
;
2804 struct tevent_context
*ev_ctx
;
2805 struct tevent_req
*watch_req
;
2809 static void poll_open_setup_watcher_fn(struct share_mode_lock
*lck
,
2812 struct poll_open_setup_watcher_state
*state
=
2813 (struct poll_open_setup_watcher_state
*)private_data
;
2815 if (!validate_oplock_types(lck
)) {
2816 smb_panic("validate_oplock_types failed");
2819 state
->watch_req
= share_mode_watch_send(
2823 (struct server_id
) {0});
2824 if (state
->watch_req
== NULL
) {
2825 DBG_WARNING("share_mode_watch_send failed\n");
2831 * Reschedule an open for 1 second from now, if not timed out.
2833 static bool setup_poll_open(
2834 struct smb_request
*req
,
2835 const struct file_id
*id
,
2836 struct timeval max_timeout
,
2837 struct timeval interval
)
2839 static struct file_id zero_id
= {};
2841 struct deferred_open_record
*open_rec
= NULL
;
2842 struct timeval endtime
, next_interval
;
2843 struct file_id_buf ftmp
;
2845 if (request_timed_out(req
, max_timeout
)) {
2849 open_rec
= talloc_zero(NULL
, struct deferred_open_record
);
2850 if (open_rec
== NULL
) {
2851 DBG_WARNING("talloc failed\n");
2854 open_rec
->xconn
= req
->xconn
;
2855 open_rec
->mid
= req
->mid
;
2858 * Make sure open_rec->te does not come later than the
2859 * request's maximum endtime.
2862 endtime
= timeval_sum(&req
->request_time
, &max_timeout
);
2863 next_interval
= timeval_current_ofs(interval
.tv_sec
, interval
.tv_usec
);
2864 next_interval
= timeval_min(&endtime
, &next_interval
);
2866 open_rec
->te
= tevent_add_timer(
2872 if (open_rec
->te
== NULL
) {
2873 DBG_WARNING("tevent_add_timer failed\n");
2874 TALLOC_FREE(open_rec
);
2879 struct poll_open_setup_watcher_state wstate
= {
2880 .mem_ctx
= open_rec
,
2881 .ev_ctx
= req
->sconn
->ev_ctx
,
2886 status
= share_mode_do_locked_vfs_denied(*id
,
2887 poll_open_setup_watcher_fn
,
2889 if (NT_STATUS_IS_OK(status
)) {
2890 if (wstate
.watch_req
== NULL
) {
2891 DBG_WARNING("share_mode_watch_send failed\n");
2892 TALLOC_FREE(open_rec
);
2895 open_rec
->watch_req
= wstate
.watch_req
;
2896 tevent_req_set_callback(open_rec
->watch_req
,
2899 } else if (!NT_STATUS_EQUAL(status
, NT_STATUS_NOT_FOUND
)) {
2900 DBG_WARNING("share_mode_do_locked_vfs_denied failed - %s\n",
2902 TALLOC_FREE(open_rec
);
2909 ok
= push_deferred_open_message_smb(req
, max_timeout
, *id
, open_rec
);
2911 DBG_WARNING("push_deferred_open_message_smb failed\n");
2912 TALLOC_FREE(open_rec
);
2916 DBG_DEBUG("poll request time [%s] mid [%" PRIu64
"] file_id [%s]\n",
2917 timeval_string(talloc_tos(), &req
->request_time
, false),
2919 file_id_str_buf(*id
, &ftmp
));
2924 static void poll_open_done(struct tevent_req
*subreq
)
2926 struct deferred_open_record
*open_rec
= tevent_req_callback_data(
2927 subreq
, struct deferred_open_record
);
2931 status
= share_mode_watch_recv(subreq
, NULL
, NULL
);
2932 TALLOC_FREE(subreq
);
2933 open_rec
->watch_req
= NULL
;
2934 TALLOC_FREE(open_rec
->te
);
2936 DBG_DEBUG("dbwrap_watched_watch_recv returned %s\n",
2939 ok
= schedule_deferred_open_message_smb(
2940 open_rec
->xconn
, open_rec
->mid
);
2942 exit_server("schedule_deferred_open_message_smb failed");
2946 bool defer_smb1_sharing_violation(struct smb_request
*req
)
2951 if (!lp_defer_sharing_violations()) {
2956 * Try every 200msec up to (by default) one second. To be
2957 * precise, according to behaviour note <247> in [MS-CIFS],
2958 * the server tries 5 times. But up to one second should be
2962 timeout_usecs
= lp_parm_int(
2966 SHARING_VIOLATION_USEC_WAIT
);
2968 ok
= setup_poll_open(
2971 (struct timeval
) { .tv_usec
= timeout_usecs
},
2972 (struct timeval
) { .tv_usec
= 200000 });
2976 /****************************************************************************
2977 On overwrite open ensure that the attributes match.
2978 ****************************************************************************/
2980 static bool open_match_attributes(connection_struct
*conn
,
2981 uint32_t old_dos_attr
,
2982 uint32_t new_dos_attr
,
2983 mode_t new_unx_mode
,
2984 mode_t
*returned_unx_mode
)
2986 uint32_t noarch_old_dos_attr
, noarch_new_dos_attr
;
2988 noarch_old_dos_attr
= (old_dos_attr
& ~FILE_ATTRIBUTE_ARCHIVE
);
2989 noarch_new_dos_attr
= (new_dos_attr
& ~FILE_ATTRIBUTE_ARCHIVE
);
2991 if((noarch_old_dos_attr
== 0 && noarch_new_dos_attr
!= 0) ||
2992 (noarch_old_dos_attr
!= 0 && ((noarch_old_dos_attr
& noarch_new_dos_attr
) == noarch_old_dos_attr
))) {
2993 *returned_unx_mode
= new_unx_mode
;
2995 *returned_unx_mode
= (mode_t
)0;
2998 DEBUG(10,("open_match_attributes: old_dos_attr = 0x%x, "
2999 "new_dos_attr = 0x%x "
3000 "returned_unx_mode = 0%o\n",
3001 (unsigned int)old_dos_attr
,
3002 (unsigned int)new_dos_attr
,
3003 (unsigned int)*returned_unx_mode
));
3005 /* If we're mapping SYSTEM and HIDDEN ensure they match. */
3006 if (lp_map_system(SNUM(conn
)) || lp_store_dos_attributes(SNUM(conn
))) {
3007 if ((old_dos_attr
& FILE_ATTRIBUTE_SYSTEM
) &&
3008 !(new_dos_attr
& FILE_ATTRIBUTE_SYSTEM
)) {
3012 if (lp_map_hidden(SNUM(conn
)) || lp_store_dos_attributes(SNUM(conn
))) {
3013 if ((old_dos_attr
& FILE_ATTRIBUTE_HIDDEN
) &&
3014 !(new_dos_attr
& FILE_ATTRIBUTE_HIDDEN
)) {
3021 static void schedule_defer_open(struct share_mode_lock
*lck
,
3023 struct smb_request
*req
,
3024 struct blocker_debug_state
**blocker_debug_state
)
3026 /* This is a relative time, added to the absolute
3027 request_time value to get the absolute timeout time.
3028 Note that if this is the second or greater time we enter
3029 this codepath for this particular request mid then
3030 request_time is left as the absolute time of the *first*
3031 time this request mid was processed. This is what allows
3032 the request to eventually time out. */
3034 struct timeval timeout
;
3036 /* Normally the smbd we asked should respond within
3037 * OPLOCK_BREAK_TIMEOUT seconds regardless of whether
3038 * the client did, give twice the timeout as a safety
3039 * measure here in case the other smbd is stuck
3040 * somewhere else. */
3042 timeout
= tevent_timeval_set(OPLOCK_BREAK_TIMEOUT
* 2, 0);
3044 if (request_timed_out(req
, timeout
)) {
3048 defer_open(lck
, timeout
, req
, id
, blocker_debug_state
);
3051 /****************************************************************************
3052 Reschedule an open call that went asynchronous.
3053 ****************************************************************************/
3055 static void schedule_async_open_timer(struct tevent_context
*ev
,
3056 struct tevent_timer
*te
,
3057 struct timeval current_time
,
3060 exit_server("async open timeout");
3063 static void schedule_async_open(struct smb_request
*req
)
3065 struct deferred_open_record
*open_rec
= NULL
;
3066 struct timeval timeout
= tevent_timeval_set(20, 0);
3069 if (request_timed_out(req
, timeout
)) {
3073 open_rec
= talloc_zero(NULL
, struct deferred_open_record
);
3074 if (open_rec
== NULL
) {
3075 exit_server("deferred_open_record_create failed");
3077 open_rec
->async_open
= true;
3079 ok
= push_deferred_open_message_smb(
3080 req
, timeout
, (struct file_id
){0}, open_rec
);
3082 exit_server("push_deferred_open_message_smb failed");
3085 open_rec
->te
= tevent_add_timer(req
->sconn
->ev_ctx
,
3087 timeval_current_ofs(20, 0),
3088 schedule_async_open_timer
,
3090 if (open_rec
->te
== NULL
) {
3091 exit_server("tevent_add_timer failed");
3095 static NTSTATUS
check_and_store_share_mode(
3096 struct files_struct
*fsp
,
3097 struct smb_request
*req
,
3098 struct share_mode_lock
*lck
,
3099 uint32_t create_disposition
,
3100 uint32_t access_mask
,
3101 uint32_t open_access_mask
,
3102 uint32_t share_access
,
3104 const struct smb2_lease
*lease
,
3105 bool first_open_attempt
)
3108 int oplock_type
= NO_OPLOCK
;
3109 uint32_t granted_lease
= 0;
3110 const struct smb2_lease_key
*lease_key
= NULL
;
3111 struct blocker_debug_state
*blocker_debug_state
= NULL
;
3112 bool delete_on_close
;
3115 /* Get the types we need to examine. */
3116 if (!validate_oplock_types(lck
)) {
3117 smb_panic("validate_oplock_types failed");
3120 delete_on_close
= has_delete_on_close(lck
, fsp
->name_hash
);
3121 if (delete_on_close
) {
3122 return NT_STATUS_DELETE_PENDING
;
3125 status
= handle_share_mode_lease(fsp
,
3135 &blocker_debug_state
);
3136 if (NT_STATUS_EQUAL(status
, NT_STATUS_RETRY
)) {
3137 schedule_defer_open(lck
, fsp
->file_id
, req
, &blocker_debug_state
);
3138 return NT_STATUS_SHARING_VIOLATION
;
3140 if (!NT_STATUS_IS_OK(status
)) {
3144 if (oplock_type
== LEASE_OPLOCK
) {
3145 lease_key
= &lease
->lease_key
;
3148 share_mode_flags_restrict(lck
, access_mask
, share_access
, 0);
3150 ok
= set_share_mode(lck
,
3152 get_current_uid(fsp
->conn
),
3159 return NT_STATUS_NO_MEMORY
;
3162 if (oplock_type
== LEASE_OPLOCK
) {
3163 status
= grant_fsp_lease(fsp
, lck
, lease
, granted_lease
);
3164 if (!NT_STATUS_IS_OK(status
)) {
3165 del_share_mode(lck
, fsp
);
3169 DBG_DEBUG("lease_state=%d\n", fsp
->lease
->lease
.lease_state
);
3172 fsp
->oplock_type
= oplock_type
;
3174 return NT_STATUS_OK
;
3177 /****************************************************************************
3178 Work out what access_mask to use from what the client sent us.
3179 ****************************************************************************/
3181 static NTSTATUS
smbd_calculate_maximum_allowed_access_fsp(
3182 struct files_struct
*dirfsp
,
3183 struct files_struct
*fsp
,
3185 uint32_t *p_access_mask
)
3187 struct security_descriptor
*sd
= NULL
;
3188 uint32_t access_granted
= 0;
3192 /* Cope with symlinks */
3193 if (fsp
== NULL
|| fsp_get_pathref_fd(fsp
) == -1) {
3194 *p_access_mask
= FILE_GENERIC_ALL
;
3195 return NT_STATUS_OK
;
3198 /* Cope with fake/printer fsp's. */
3199 if (fsp
->fake_file_handle
!= NULL
|| fsp
->print_file
!= NULL
) {
3200 *p_access_mask
= FILE_GENERIC_ALL
;
3201 return NT_STATUS_OK
;
3204 if (!use_privs
&& (get_current_uid(fsp
->conn
) == (uid_t
)0)) {
3205 *p_access_mask
|= FILE_GENERIC_ALL
;
3206 return NT_STATUS_OK
;
3209 status
= SMB_VFS_FGET_NT_ACL(metadata_fsp(fsp
),
3216 if (NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
3218 * File did not exist
3220 *p_access_mask
= FILE_GENERIC_ALL
;
3221 return NT_STATUS_OK
;
3223 if (!NT_STATUS_IS_OK(status
)) {
3224 DBG_ERR("Could not get acl on file %s: %s\n",
3231 * If we can access the path to this file, by
3232 * default we have FILE_READ_ATTRIBUTES from the
3233 * containing directory. See the section:
3234 * "Algorithm to Check Access to an Existing File"
3237 * se_file_access_check()
3238 * also takes care of owner WRITE_DAC and READ_CONTROL.
3240 status
= se_file_access_check(sd
,
3241 get_current_nttok(fsp
->conn
),
3243 (*p_access_mask
& ~FILE_READ_ATTRIBUTES
),
3248 if (!NT_STATUS_IS_OK(status
)) {
3249 DBG_ERR("Status %s on file %s: "
3250 "when calculating maximum access\n",
3256 *p_access_mask
= (access_granted
| FILE_READ_ATTRIBUTES
);
3258 if (!(access_granted
& DELETE_ACCESS
)) {
3259 if (can_delete_file_in_directory(fsp
->conn
,
3262 *p_access_mask
|= DELETE_ACCESS
;
3266 dosattrs
= fdos_mode(fsp
);
3267 if ((dosattrs
& FILE_ATTRIBUTE_READONLY
) || !CAN_WRITE(fsp
->conn
)) {
3268 *p_access_mask
&= ~(FILE_GENERIC_WRITE
| DELETE_ACCESS
);
3271 return NT_STATUS_OK
;
3274 NTSTATUS
smbd_calculate_access_mask_fsp(struct files_struct
*dirfsp
,
3275 struct files_struct
*fsp
,
3277 uint32_t access_mask
,
3278 uint32_t *access_mask_out
)
3281 uint32_t orig_access_mask
= access_mask
;
3282 uint32_t rejected_share_access
;
3284 if (access_mask
& SEC_MASK_INVALID
) {
3285 DBG_DEBUG("access_mask [%8x] contains invalid bits\n",
3287 return NT_STATUS_ACCESS_DENIED
;
3291 * Convert GENERIC bits to specific bits.
3294 se_map_generic(&access_mask
, &file_generic_mapping
);
3296 /* Calculate MAXIMUM_ALLOWED_ACCESS if requested. */
3297 if (access_mask
& MAXIMUM_ALLOWED_ACCESS
) {
3299 status
= smbd_calculate_maximum_allowed_access_fsp(
3305 if (!NT_STATUS_IS_OK(status
)) {
3309 access_mask
&= fsp
->conn
->share_access
;
3312 rejected_share_access
= access_mask
& ~(fsp
->conn
->share_access
);
3314 if (rejected_share_access
) {
3315 DBG_INFO("Access denied on file %s: "
3316 "rejected by share access mask[0x%08X] "
3317 "orig[0x%08X] mapped[0x%08X] reject[0x%08X]\n",
3319 fsp
->conn
->share_access
,
3320 orig_access_mask
, access_mask
,
3321 rejected_share_access
);
3322 return NT_STATUS_ACCESS_DENIED
;
3325 *access_mask_out
= access_mask
;
3326 return NT_STATUS_OK
;
3329 /****************************************************************************
3330 Remove the deferred open entry under lock.
3331 ****************************************************************************/
3333 /****************************************************************************
3334 Return true if this is a state pointer to an asynchronous create.
3335 ****************************************************************************/
3337 bool is_deferred_open_async(const struct deferred_open_record
*rec
)
3339 return rec
->async_open
;
3342 static bool clear_ads(uint32_t create_disposition
)
3346 switch (create_disposition
) {
3347 case FILE_SUPERSEDE
:
3348 case FILE_OVERWRITE_IF
:
3349 case FILE_OVERWRITE
:
3358 static int disposition_to_open_flags(uint32_t create_disposition
)
3363 * Currently we're using FILE_SUPERSEDE as the same as
3364 * FILE_OVERWRITE_IF but they really are
3365 * different. FILE_SUPERSEDE deletes an existing file
3366 * (requiring delete access) then recreates it.
3369 switch (create_disposition
) {
3370 case FILE_SUPERSEDE
:
3371 case FILE_OVERWRITE_IF
:
3373 * If file exists replace/overwrite. If file doesn't
3376 ret
= O_CREAT
|O_TRUNC
;
3381 * If file exists open. If file doesn't exist error.
3386 case FILE_OVERWRITE
:
3388 * If file exists overwrite. If file doesn't exist
3396 * If file exists error. If file doesn't exist create.
3398 ret
= O_CREAT
|O_EXCL
;
3403 * If file exists open. If file doesn't exist create.
3411 static int calculate_open_access_flags(uint32_t access_mask
,
3412 uint32_t private_flags
,
3415 bool need_write
, need_read
;
3418 * Note that we ignore the append flag as append does not
3419 * mean the same thing under DOS and Unix.
3424 * Pave over the user requested mode and force O_RDONLY for the
3425 * file handle. Windows allows opening a VSS file with O_RDWR,
3426 * even though actual writes on the handle will fail.
3431 need_write
= (access_mask
& (FILE_WRITE_DATA
| FILE_APPEND_DATA
));
3436 /* DENY_DOS opens are always underlying read-write on the
3437 file handle, no matter what the requested access mask
3441 ((private_flags
& NTCREATEX_FLAG_DENY_DOS
) ||
3442 access_mask
& (FILE_READ_ATTRIBUTES
|FILE_READ_DATA
|
3443 FILE_READ_EA
|FILE_EXECUTE
));
3451 struct open_ntcreate_lock_state
{
3452 struct share_mode_entry_prepare_state prepare_state
;
3453 struct files_struct
*fsp
;
3454 const char *object_type
;
3455 struct smb_request
*req
;
3456 uint32_t create_disposition
;
3457 uint32_t access_mask
;
3458 uint32_t open_access_mask
;
3459 uint32_t share_access
;
3461 const struct smb2_lease
*lease
;
3462 bool first_open_attempt
;
3465 struct timespec write_time
;
3466 share_mode_entry_prepare_unlock_fn_t cleanup_fn
;
3469 static void open_ntcreate_lock_add_entry(struct share_mode_lock
*lck
,
3473 struct open_ntcreate_lock_state
*state
=
3474 (struct open_ntcreate_lock_state
*)private_data
;
3477 * By default drop the g_lock again if we leave the
3480 *keep_locked
= false;
3482 state
->status
= check_and_store_share_mode(state
->fsp
,
3485 state
->create_disposition
,
3487 state
->open_access_mask
,
3488 state
->share_access
,
3489 state
->oplock_request
,
3491 state
->first_open_attempt
);
3492 if (!NT_STATUS_IS_OK(state
->status
)) {
3496 state
->write_time
= get_share_mode_write_time(lck
);
3499 * keep the g_lock while existing the tdb chainlock,
3500 * we we're asked to, which mean we'll keep
3501 * the share_mode_lock during object creation,
3502 * or setting delete on close.
3504 *keep_locked
= state
->keep_locked
;
3507 static void open_ntcreate_lock_cleanup_oplock(struct share_mode_lock
*lck
,
3510 struct open_ntcreate_lock_state
*state
=
3511 (struct open_ntcreate_lock_state
*)private_data
;
3514 ok
= remove_share_oplock(lck
, state
->fsp
);
3516 DBG_ERR("Could not remove oplock for %s %s\n",
3517 state
->object_type
, fsp_str_dbg(state
->fsp
));
3521 static void open_ntcreate_lock_cleanup_entry(struct share_mode_lock
*lck
,
3524 struct open_ntcreate_lock_state
*state
=
3525 (struct open_ntcreate_lock_state
*)private_data
;
3528 ok
= del_share_mode(lck
, state
->fsp
);
3530 DBG_ERR("Could not delete share entry for %s %s\n",
3531 state
->object_type
, fsp_str_dbg(state
->fsp
));
3535 static void possibly_set_archive(struct connection_struct
*conn
,
3536 struct files_struct
*fsp
,
3537 struct smb_filename
*smb_fname
,
3538 struct smb_filename
*parent_dir_fname
,
3543 bool set_archive
= false;
3546 if (info
== FILE_WAS_OPENED
) {
3550 /* Overwritten files should be initially set as archive */
3551 if ((info
== FILE_WAS_OVERWRITTEN
&& lp_map_archive(SNUM(conn
)))) {
3553 } else if (lp_store_dos_attributes(SNUM(conn
))) {
3560 ret
= file_set_dosmode(conn
,
3562 dosattrs
| FILE_ATTRIBUTE_ARCHIVE
,
3568 *unx_mode
= smb_fname
->st
.st_ex_mode
;
3571 /****************************************************************************
3572 Open a file with a share mode. Passed in an already created files_struct *.
3573 ****************************************************************************/
3575 static NTSTATUS
open_file_ntcreate(connection_struct
*conn
,
3576 struct smb_request
*req
,
3577 uint32_t access_mask
, /* access bits (FILE_READ_DATA etc.) */
3578 uint32_t share_access
, /* share constants (FILE_SHARE_READ etc) */
3579 uint32_t create_disposition
, /* FILE_OPEN_IF etc. */
3580 uint32_t create_options
, /* options such as delete on close. */
3581 uint32_t new_dos_attributes
, /* attributes used for new file. */
3582 int oplock_request
, /* internal Samba oplock codes. */
3583 const struct smb2_lease
*lease
,
3584 /* Information (FILE_EXISTS etc.) */
3585 uint32_t private_flags
, /* Samba specific flags. */
3586 struct smb_filename
*parent_dir_fname
, /* parent. */
3587 struct smb_filename
*smb_fname_atname
, /* atname relative to parent. */
3591 struct smb_filename
*smb_fname
= fsp
->fsp_name
;
3593 bool file_existed
= VALID_STAT(smb_fname
->st
);
3594 bool def_acl
= False
;
3595 bool posix_open
= False
;
3596 bool new_file_created
= False
;
3597 bool truncated
= false;
3598 bool first_open_attempt
= true;
3599 bool is_twrp
= (smb_fname_atname
->twrp
!= 0);
3600 NTSTATUS fsp_open
= NT_STATUS_ACCESS_DENIED
;
3601 mode_t new_unx_mode
= (mode_t
)0;
3602 mode_t unx_mode
= (mode_t
)0;
3604 uint32_t existing_dos_attributes
= 0;
3605 struct open_ntcreate_lock_state lck_state
= {};
3606 bool keep_locked
= false;
3607 uint32_t open_access_mask
= access_mask
;
3609 SMB_STRUCT_STAT saved_stat
= smb_fname
->st
;
3610 struct timespec old_write_time
;
3611 bool setup_poll
= false;
3614 if (conn
->printer
) {
3616 * Printers are handled completely differently.
3617 * Most of the passed parameters are ignored.
3621 *pinfo
= FILE_WAS_CREATED
;
3624 DBG_DEBUG("printer open fname=%s\n",
3625 smb_fname_str_dbg(smb_fname
));
3628 DBG_ERR("printer open without an SMB request!\n");
3629 return NT_STATUS_INTERNAL_ERROR
;
3632 return print_spool_open(fsp
, smb_fname
->base_name
,
3636 if (new_dos_attributes
& FILE_FLAG_POSIX_SEMANTICS
) {
3638 unx_mode
= (mode_t
)(new_dos_attributes
& ~FILE_FLAG_POSIX_SEMANTICS
);
3639 new_dos_attributes
= 0;
3641 /* Windows allows a new file to be created and
3642 silently removes a FILE_ATTRIBUTE_DIRECTORY
3643 sent by the client. Do the same. */
3645 new_dos_attributes
&= ~FILE_ATTRIBUTE_DIRECTORY
;
3647 /* We add FILE_ATTRIBUTE_ARCHIVE to this as this mode is only used if the file is
3649 unx_mode
= unix_mode(
3651 new_dos_attributes
| FILE_ATTRIBUTE_ARCHIVE
,
3653 parent_dir_fname
->fsp
);
3656 DEBUG(10, ("open_file_ntcreate: fname=%s, dos_attrs=0x%x "
3657 "access_mask=0x%x share_access=0x%x "
3658 "create_disposition = 0x%x create_options=0x%x "
3659 "unix mode=0%o oplock_request=%d private_flags = 0x%x\n",
3660 smb_fname_str_dbg(smb_fname
), new_dos_attributes
,
3661 access_mask
, share_access
, create_disposition
,
3662 create_options
, (unsigned int)unx_mode
, oplock_request
,
3663 (unsigned int)private_flags
));
3666 /* Ensure req == NULL means INTERNAL_OPEN_ONLY */
3667 SMB_ASSERT(oplock_request
== INTERNAL_OPEN_ONLY
);
3669 /* And req != NULL means no INTERNAL_OPEN_ONLY */
3670 SMB_ASSERT(((oplock_request
& INTERNAL_OPEN_ONLY
) == 0));
3674 * Only non-internal opens can be deferred at all
3678 struct deferred_open_record
*open_rec
;
3679 if (get_deferred_open_message_state(req
, NULL
, &open_rec
)) {
3681 /* If it was an async create retry, the file
3684 if (is_deferred_open_async(open_rec
)) {
3685 SET_STAT_INVALID(smb_fname
->st
);
3686 file_existed
= false;
3689 /* Ensure we don't reprocess this message. */
3690 remove_deferred_open_message_smb(req
->xconn
, req
->mid
);
3692 first_open_attempt
= false;
3697 new_dos_attributes
&= SAMBA_ATTRIBUTES_MASK
;
3700 * Only use stored DOS attributes for checks
3701 * against requested attributes (below via
3702 * open_match_attributes()), cf bug #11992
3703 * for details. -slow
3707 status
= SMB_VFS_FGET_DOS_ATTRIBUTES(
3709 metadata_fsp(smb_fname
->fsp
),
3711 if (NT_STATUS_IS_OK(status
)) {
3712 existing_dos_attributes
= attr
;
3717 /* ignore any oplock requests if oplocks are disabled */
3718 if (!lp_oplocks(SNUM(conn
)) ||
3719 IS_VETO_OPLOCK_PATH(conn
, smb_fname
->base_name
)) {
3720 /* Mask off everything except the private Samba bits. */
3721 oplock_request
&= SAMBA_PRIVATE_OPLOCK_MASK
;
3724 /* this is for OS/2 long file names - say we don't support them */
3725 if (req
!= NULL
&& !req
->posix_pathnames
&&
3726 strstr(smb_fname
->base_name
,".+,;=[].")) {
3727 /* OS/2 Workplace shell fix may be main code stream in a later
3729 DEBUG(5,("open_file_ntcreate: OS/2 long filenames are not "
3731 if (use_nt_status()) {
3732 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
3734 return NT_STATUS_DOS(ERRDOS
, ERRcannotopen
);
3737 switch( create_disposition
) {
3739 /* If file exists open. If file doesn't exist error. */
3740 if (!file_existed
) {
3741 DEBUG(5,("open_file_ntcreate: FILE_OPEN "
3742 "requested for file %s and file "
3744 smb_fname_str_dbg(smb_fname
)));
3745 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
3749 case FILE_OVERWRITE
:
3750 /* If file exists overwrite. If file doesn't exist
3752 if (!file_existed
) {
3753 DEBUG(5,("open_file_ntcreate: FILE_OVERWRITE "
3754 "requested for file %s and file "
3756 smb_fname_str_dbg(smb_fname
) ));
3757 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
3760 return NT_STATUS_MEDIA_WRITE_PROTECTED
;
3765 /* If file exists error. If file doesn't exist
3768 DEBUG(5,("open_file_ntcreate: FILE_CREATE "
3769 "requested for file %s and file "
3770 "already exists.\n",
3771 smb_fname_str_dbg(smb_fname
)));
3772 if (S_ISDIR(smb_fname
->st
.st_ex_mode
)) {
3773 return NT_STATUS_FILE_IS_A_DIRECTORY
;
3775 return NT_STATUS_OBJECT_NAME_COLLISION
;
3778 return NT_STATUS_MEDIA_WRITE_PROTECTED
;
3782 case FILE_SUPERSEDE
:
3783 case FILE_OVERWRITE_IF
:
3785 return NT_STATUS_MEDIA_WRITE_PROTECTED
;
3790 if (!file_existed
) {
3791 return NT_STATUS_MEDIA_WRITE_PROTECTED
;
3793 create_disposition
= FILE_OPEN
;
3797 return NT_STATUS_INVALID_PARAMETER
;
3800 flags
= disposition_to_open_flags(create_disposition
);
3802 /* We only care about matching attributes on file exists and
3805 if (!posix_open
&& file_existed
&&
3806 ((create_disposition
== FILE_OVERWRITE
) ||
3807 (create_disposition
== FILE_OVERWRITE_IF
))) {
3808 if (!open_match_attributes(conn
, existing_dos_attributes
,
3810 unx_mode
, &new_unx_mode
)) {
3811 DEBUG(5,("open_file_ntcreate: attributes mismatch "
3812 "for file %s (%x %x) (0%o, 0%o)\n",
3813 smb_fname_str_dbg(smb_fname
),
3814 existing_dos_attributes
,
3816 (unsigned int)smb_fname
->st
.st_ex_mode
,
3817 (unsigned int)unx_mode
));
3818 return NT_STATUS_ACCESS_DENIED
;
3822 status
= smbd_calculate_access_mask_fsp(parent_dir_fname
->fsp
,
3827 if (!NT_STATUS_IS_OK(status
)) {
3828 DBG_DEBUG("smbd_calculate_access_mask_fsp "
3829 "on file %s returned %s\n",
3830 smb_fname_str_dbg(smb_fname
),
3835 open_access_mask
= access_mask
;
3837 if (flags
& O_TRUNC
) {
3838 open_access_mask
|= FILE_WRITE_DATA
; /* This will cause oplock breaks. */
3843 * stat opens on existing files don't get oplocks.
3844 * They can get leases.
3846 * Note that we check for stat open on the *open_access_mask*,
3847 * i.e. the access mask we actually used to do the open,
3848 * not the one the client asked for (which is in
3849 * fsp->access_mask). This is due to the fact that
3850 * FILE_OVERWRITE and FILE_OVERWRITE_IF add in O_TRUNC,
3851 * which adds FILE_WRITE_DATA to open_access_mask.
3853 if (is_oplock_stat_open(open_access_mask
) && lease
== NULL
) {
3854 oplock_request
= NO_OPLOCK
;
3858 DEBUG(10, ("open_file_ntcreate: fname=%s, after mapping "
3859 "access_mask=0x%x\n", smb_fname_str_dbg(smb_fname
),
3863 * Note that we ignore the append flag as append does not
3864 * mean the same thing under DOS and Unix.
3867 flags
|= calculate_open_access_flags(access_mask
,
3872 * Currently we only look at FILE_WRITE_THROUGH for create options.
3876 if ((create_options
& FILE_WRITE_THROUGH
) && lp_strict_sync(SNUM(conn
))) {
3881 if (posix_open
&& (access_mask
& FILE_APPEND_DATA
)) {
3885 if (!posix_open
&& !CAN_WRITE(conn
)) {
3887 * We should really return a permission denied error if either
3888 * O_CREAT or O_TRUNC are set, but for compatibility with
3889 * older versions of Samba we just AND them out.
3891 flags
&= ~(O_CREAT
| O_TRUNC
);
3895 * With kernel oplocks the open breaking an oplock
3896 * blocks until the oplock holder has given up the
3897 * oplock or closed the file. We prevent this by always
3898 * trying to open the file with O_NONBLOCK (see "man
3901 * If a process that doesn't use the smbd open files
3902 * database or communication methods holds a kernel
3903 * oplock we must periodically poll for available open
3906 flags
|= O_NONBLOCK
;
3909 * Ensure we can't write on a read-only share or file.
3912 if (((flags
& O_ACCMODE
) != O_RDONLY
) && file_existed
&&
3913 (!CAN_WRITE(conn
) ||
3914 (existing_dos_attributes
& FILE_ATTRIBUTE_READONLY
))) {
3915 DEBUG(5,("open_file_ntcreate: write access requested for "
3916 "file %s on read only %s\n",
3917 smb_fname_str_dbg(smb_fname
),
3918 !CAN_WRITE(conn
) ? "share" : "file" ));
3919 return NT_STATUS_ACCESS_DENIED
;
3922 if (VALID_STAT(smb_fname
->st
)) {
3924 * Only try and create a file id before open
3925 * for an existing file. For a file being created
3926 * this won't do anything useful until the file
3927 * exists and has a valid stat struct.
3929 fsp
->file_id
= vfs_file_id_from_sbuf(conn
, &smb_fname
->st
);
3931 fh_set_private_options(fsp
->fh
, private_flags
);
3932 fsp
->access_mask
= open_access_mask
; /* We change this to the
3933 * requested access_mask after
3934 * the open is done. */
3936 fsp
->fsp_flags
.posix_open
= true;
3939 if ((create_options
& FILE_DELETE_ON_CLOSE
) && (flags
& O_CREAT
) &&
3941 /* Delete on close semantics for new files. */
3942 status
= can_set_delete_on_close(fsp
,
3943 new_dos_attributes
);
3944 if (!NT_STATUS_IS_OK(status
)) {
3951 * Ensure we pay attention to default ACLs on directories if required.
3954 if ((flags
& O_CREAT
) && lp_inherit_acls(SNUM(conn
)) &&
3955 (def_acl
= directory_has_default_acl_fsp(parent_dir_fname
->fsp
))) {
3956 unx_mode
= (0777 & lp_create_mask(SNUM(conn
)));
3960 ("calling open_file with flags=0x%X mode=0%o, "
3961 "access_mask = 0x%x, open_access_mask = 0x%x\n",
3962 (unsigned int)flags
,
3963 (unsigned int)unx_mode
,
3964 (unsigned int)access_mask
,
3965 (unsigned int)open_access_mask
));
3968 struct vfs_open_how how
= {
3973 if (create_options
& FILE_OPEN_FOR_BACKUP_INTENT
) {
3974 how
.resolve
|= VFS_OPEN_HOW_WITH_BACKUP_INTENT
;
3977 fsp_open
= open_file(req
,
3978 parent_dir_fname
->fsp
,
3987 if (NT_STATUS_EQUAL(fsp_open
, NT_STATUS_NETWORK_BUSY
)) {
3988 if (file_existed
&& S_ISFIFO(fsp
->fsp_name
->st
.st_ex_mode
)) {
3989 DEBUG(10, ("FIFO busy\n"));
3990 return NT_STATUS_NETWORK_BUSY
;
3993 DEBUG(10, ("Internal open busy\n"));
3994 return NT_STATUS_NETWORK_BUSY
;
3997 * This handles the kernel oplock case:
3999 * the file has an active kernel oplock and the open() returned
4000 * EWOULDBLOCK/EAGAIN which maps to NETWORK_BUSY.
4002 * "Samba locking.tdb oplocks" are handled below after acquiring
4003 * the sharemode lock with get_share_mode_lock().
4008 if (NT_STATUS_EQUAL(fsp_open
, NT_STATUS_RETRY
)) {
4010 * EINTR from the open(2) syscall. Just setup a retry
4011 * in a bit. We can't use the sys_write() tight retry
4012 * loop here, as we might have to actually deal with
4013 * lease-break signals to avoid a deadlock.
4020 * Retry once a second. If there's a share_mode_lock
4021 * around, also wait for it in case it was smbd
4022 * holding that kernel oplock that can quickly tell us
4023 * the oplock got removed.
4026 setup_poll_open(req
,
4028 tevent_timeval_set(OPLOCK_BREAK_TIMEOUT
* 2,
4030 tevent_timeval_set(1, 0));
4032 return NT_STATUS_SHARING_VIOLATION
;
4035 if (!NT_STATUS_IS_OK(fsp_open
)) {
4036 bool wait_for_aio
= NT_STATUS_EQUAL(
4037 fsp_open
, NT_STATUS_MORE_PROCESSING_REQUIRED
);
4039 schedule_async_open(req
);
4044 if (new_file_created
) {
4046 * As we atomically create using O_CREAT|O_EXCL,
4047 * then if new_file_created is true, then
4048 * file_existed *MUST* have been false (even
4049 * if the file was previously detected as being
4052 file_existed
= false;
4055 if (file_existed
&& !check_same_dev_ino(&saved_stat
, &smb_fname
->st
)) {
4057 * The file did exist, but some other (local or NFS)
4058 * process either renamed/unlinked and re-created the
4059 * file with different dev/ino after we walked the path,
4060 * but before we did the open. We could retry the
4061 * open but it's a rare enough case it's easier to
4062 * just fail the open to prevent creating any problems
4063 * in the open file db having the wrong dev/ino key.
4066 DBG_WARNING("file %s - dev/ino mismatch. "
4067 "Old (dev=%ju, ino=%ju). "
4068 "New (dev=%ju, ino=%ju). Failing open "
4069 "with NT_STATUS_ACCESS_DENIED.\n",
4070 smb_fname_str_dbg(smb_fname
),
4071 (uintmax_t)saved_stat
.st_ex_dev
,
4072 (uintmax_t)saved_stat
.st_ex_ino
,
4073 (uintmax_t)smb_fname
->st
.st_ex_dev
,
4074 (uintmax_t)smb_fname
->st
.st_ex_ino
);
4075 return NT_STATUS_ACCESS_DENIED
;
4078 old_write_time
= smb_fname
->st
.st_ex_mtime
;
4081 * Deal with the race condition where two smbd's detect the
4082 * file doesn't exist and do the create at the same time. One
4083 * of them will win and set a share mode, the other (ie. this
4084 * one) should check if the requested share mode for this
4085 * create is allowed.
4089 * Now the file exists and fsp is successfully opened,
4090 * fsp->dev and fsp->inode are valid and should replace the
4091 * dev=0,inode=0 from a non existent file. Spotted by
4092 * Nadav Danieli <nadavd@exanet.com>. JRA.
4095 if (new_file_created
) {
4096 info
= FILE_WAS_CREATED
;
4098 if (flags
& O_TRUNC
) {
4099 info
= FILE_WAS_OVERWRITTEN
;
4101 info
= FILE_WAS_OPENED
;
4106 * If we created a new file, overwrite an existing one
4107 * or going to delete it later, we should keep
4108 * the share_mode_lock (g_lock) until we call
4109 * share_mode_entry_prepare_unlock()
4111 if (info
!= FILE_WAS_OPENED
) {
4113 } else if (create_options
& FILE_DELETE_ON_CLOSE
) {
4117 lck_state
= (struct open_ntcreate_lock_state
) {
4119 .object_type
= "file",
4121 .create_disposition
= create_disposition
,
4122 .access_mask
= access_mask
,
4123 .open_access_mask
= open_access_mask
,
4124 .share_access
= share_access
,
4125 .oplock_request
= oplock_request
,
4127 .first_open_attempt
= first_open_attempt
,
4128 .keep_locked
= keep_locked
,
4131 status
= share_mode_entry_prepare_lock_add(&lck_state
.prepare_state
,
4136 open_ntcreate_lock_add_entry
,
4138 if (!NT_STATUS_IS_OK(status
)) {
4139 DBG_ERR("share_mode_entry_prepare_lock_add() failed for %s - %s\n",
4140 smb_fname_str_dbg(smb_fname
), nt_errstr(status
));
4145 status
= lck_state
.status
;
4146 if (!NT_STATUS_IS_OK(status
)) {
4152 * From here we need to use 'goto unlock;' instead of return !!!
4155 if (fsp
->oplock_type
!= NO_OPLOCK
&& fsp
->oplock_type
!= LEASE_OPLOCK
) {
4157 * Now ask for kernel oplocks
4158 * and cleanup on failure.
4160 status
= set_file_oplock(fsp
);
4161 if (!NT_STATUS_IS_OK(status
)) {
4163 * Could not get the kernel oplock
4165 lck_state
.cleanup_fn
=
4166 open_ntcreate_lock_cleanup_oplock
;
4167 fsp
->oplock_type
= NO_OPLOCK
;
4171 /* Should we atomically (to the client at least) truncate ? */
4172 if ((!new_file_created
) && (flags
& O_TRUNC
) &&
4173 (S_ISREG(fsp
->fsp_name
->st
.st_ex_mode
))) {
4176 ret
= SMB_VFS_FTRUNCATE(fsp
, 0);
4178 status
= map_nt_error_from_unix(errno
);
4179 lck_state
.cleanup_fn
=
4180 open_ntcreate_lock_cleanup_entry
;
4187 * We have the share entry *locked*.....
4190 /* Delete streams if create_disposition requires it */
4191 if (!new_file_created
&&
4192 clear_ads(create_disposition
) &&
4193 !fsp_is_alternate_stream(fsp
)) {
4194 status
= delete_all_streams(conn
, smb_fname
);
4195 if (!NT_STATUS_IS_OK(status
)) {
4196 lck_state
.cleanup_fn
=
4197 open_ntcreate_lock_cleanup_entry
;
4202 if (!fsp
->fsp_flags
.is_pathref
&&
4203 fsp_get_io_fd(fsp
) != -1 &&
4204 lp_kernel_share_modes(SNUM(conn
)))
4208 * Beware: streams implementing VFS modules may
4209 * implement streams in a way that fsp will have the
4210 * basefile open in the fsp fd, so lacking a distinct
4211 * fd for the stream the file-system sharemode will
4212 * apply on the basefile which is wrong. The actual
4213 * check is deferred to the VFS module implementing
4214 * the file-system sharemode call.
4216 ret
= SMB_VFS_FILESYSTEM_SHAREMODE(fsp
,
4220 status
= NT_STATUS_SHARING_VIOLATION
;
4221 lck_state
.cleanup_fn
=
4222 open_ntcreate_lock_cleanup_entry
;
4226 fsp
->fsp_flags
.kernel_share_modes_taken
= true;
4230 * At this point onwards, we can guarantee that the share entry
4231 * is locked, whether we created the file or not, and that the
4232 * deny mode is compatible with all current opens.
4236 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
4237 * but we don't have to store this - just ignore it on access check.
4239 if (conn_using_smb2(conn
->sconn
)) {
4241 * SMB2 doesn't return it (according to Microsoft tests).
4242 * Test Case: TestSuite_ScenarioNo009GrantedAccessTestS0
4243 * File created with access = 0x7 (Read, Write, Delete)
4244 * Query Info on file returns 0x87 (Read, Write, Delete, Read Attributes)
4246 fsp
->access_mask
= access_mask
;
4248 /* But SMB1 does. */
4249 fsp
->access_mask
= access_mask
| FILE_READ_ATTRIBUTES
;
4256 /* Handle strange delete on close create semantics. */
4257 if (create_options
& FILE_DELETE_ON_CLOSE
) {
4258 if (!new_file_created
) {
4259 status
= can_set_delete_on_close(fsp
,
4260 existing_dos_attributes
);
4262 if (!NT_STATUS_IS_OK(status
)) {
4263 /* Remember to delete the mode we just added. */
4264 lck_state
.cleanup_fn
=
4265 open_ntcreate_lock_cleanup_entry
;
4269 /* Note that here we set the *initial* delete on close flag,
4270 not the regular one. The magic gets handled in close. */
4271 fsp
->fsp_flags
.initial_delete_on_close
= true;
4274 possibly_set_archive(conn
,
4280 &smb_fname
->st
.st_ex_mode
);
4282 /* Determine sparse flag. */
4284 /* POSIX opens are sparse by default. */
4285 fsp
->fsp_flags
.is_sparse
= true;
4287 fsp
->fsp_flags
.is_sparse
=
4288 (existing_dos_attributes
& FILE_ATTRIBUTE_SPARSE
);
4292 * Take care of inherited ACLs on created files - if default ACL not
4296 if (!posix_open
&& new_file_created
&& !def_acl
) {
4297 if (unx_mode
!= smb_fname
->st
.st_ex_mode
) {
4298 int ret
= SMB_VFS_FCHMOD(fsp
, unx_mode
);
4300 DBG_INFO("failed to reset "
4301 "attributes of file %s to 0%o\n",
4302 smb_fname_str_dbg(smb_fname
),
4303 (unsigned int)unx_mode
);
4307 } else if (new_unx_mode
) {
4309 * We only get here in the case of:
4311 * a). Not a POSIX open.
4312 * b). File already existed.
4313 * c). File was overwritten.
4314 * d). Requested DOS attributes didn't match
4315 * the DOS attributes on the existing file.
4317 * In that case new_unx_mode has been set
4318 * equal to the calculated mode (including
4319 * possible inheritance of the mode from the
4320 * containing directory).
4322 * Note this mode was calculated with the
4323 * DOS attribute FILE_ATTRIBUTE_ARCHIVE added,
4324 * so the mode change here is suitable for
4325 * an overwritten file.
4328 if (new_unx_mode
!= smb_fname
->st
.st_ex_mode
) {
4329 int ret
= SMB_VFS_FCHMOD(fsp
, new_unx_mode
);
4331 DBG_INFO("failed to reset "
4332 "attributes of file %s to 0%o\n",
4333 smb_fname_str_dbg(smb_fname
),
4334 (unsigned int)new_unx_mode
);
4340 * Deal with other opens having a modified write time.
4342 if (fsp_getinfo_ask_sharemode(fsp
) &&
4343 !is_omit_timespec(&lck_state
.write_time
))
4345 update_stat_ex_mtime(&fsp
->fsp_name
->st
, lck_state
.write_time
);
4348 status
= NT_STATUS_OK
;
4351 ulstatus
= share_mode_entry_prepare_unlock(&lck_state
.prepare_state
,
4352 lck_state
.cleanup_fn
,
4354 if (!NT_STATUS_IS_OK(ulstatus
)) {
4355 DBG_ERR("share_mode_entry_prepare_unlock() failed for %s - %s\n",
4356 smb_fname_str_dbg(smb_fname
), nt_errstr(ulstatus
));
4357 smb_panic("share_mode_entry_prepare_unlock() failed!");
4360 if (info
== FILE_WAS_CREATED
) {
4362 NOTIFY_ACTION_ADDED
|
4363 NOTIFY_ACTION_DIRLEASE_BREAK
,
4364 FILE_NOTIFY_CHANGE_FILE_NAME
,
4366 fsp_get_smb2_lease(fsp
));
4369 notify_fname(fsp
->conn
,
4370 NOTIFY_ACTION_MODIFIED
|
4371 NOTIFY_ACTION_DIRLEASE_BREAK
,
4372 FILE_NOTIFY_CHANGE_SIZE
|
4373 FILE_NOTIFY_CHANGE_ATTRIBUTES
,
4375 fsp_get_smb2_lease(fsp
));
4377 if (!NT_STATUS_IS_OK(status
)) {
4382 return NT_STATUS_OK
;
4385 static NTSTATUS
apply_new_nt_acl(struct files_struct
*dirfsp
,
4386 struct files_struct
*fsp
,
4387 struct security_descriptor
*sd
)
4393 * According to the MS documentation, the only time the security
4394 * descriptor is applied to the opened file is iff we *created* the
4395 * file; an existing file stays the same.
4397 * Also, it seems (from observation) that you can open the file with
4398 * any access mask but you can still write the sd. We need to override
4399 * the granted access before we call set_sd
4400 * Patch for bug #2242 from Tom Lackemann <cessnatomny@yahoo.com>.
4403 uint32_t sec_info_sent
;
4404 uint32_t saved_access_mask
= fsp
->access_mask
;
4406 sec_info_sent
= get_sec_info(sd
);
4408 fsp
->access_mask
= FILE_GENERIC_ALL
;
4410 if (sec_info_sent
& (SECINFO_OWNER
|
4414 status
= set_sd(fsp
, sd
, sec_info_sent
);
4416 status
= NT_STATUS_OK
;
4419 fsp
->access_mask
= saved_access_mask
;
4421 if (!NT_STATUS_IS_OK(status
)) {
4422 DBG_WARNING("set_sd() failed for '%s': %s\n",
4423 fsp_str_dbg(fsp
), nt_errstr(status
));
4427 return NT_STATUS_OK
;
4430 if (!lp_inherit_acls(SNUM(fsp
->conn
))) {
4431 return NT_STATUS_OK
;
4434 /* Inherit from parent. Errors here are not fatal. */
4435 status
= inherit_new_acl(dirfsp
, fsp
);
4436 if (!NT_STATUS_IS_OK(status
)) {
4437 DBG_WARNING("inherit_new_acl failed for %s with %s\n",
4438 fsp_str_dbg(fsp
), nt_errstr(status
));
4441 return NT_STATUS_OK
;
4444 bool smbd_is_tmpname(const char *n
, int *_unlink_flags
)
4447 int unlink_flags
= INT_MAX
;
4448 struct server_id id
;
4451 if (_unlink_flags
!= NULL
) {
4452 *_unlink_flags
= INT_MAX
;
4455 if (!IS_SMBD_TMPNAME_PREFIX(n
)) {
4458 p
+= sizeof(SMBD_TMPNAME_PREFIX
) - 1;
4461 unlink_flags
= AT_REMOVEDIR
;
4472 id
= server_id_from_string_ex(get_my_vnn(), '%', p
);
4473 if (id
.pid
== UINT64_MAX
) {
4476 if (id
.unique_id
== 0) {
4479 if (id
.unique_id
== SERVERID_UNIQUE_ID_NOT_TO_VERIFY
) {
4483 if (_unlink_flags
== NULL
) {
4487 exists
= serverid_exists(&id
);
4490 * let the caller know it's stale
4491 * and should be removed
4493 *_unlink_flags
= unlink_flags
;
4499 static NTSTATUS
mkdir_internal(connection_struct
*conn
,
4500 struct smb_filename
*parent_dir_fname
, /* parent. */
4501 struct smb_filename
*smb_fname_atname
, /* atname relative to parent. */
4502 struct smb_filename
*smb_dname
, /* full pathname from root of share. */
4503 struct security_descriptor
*sd
,
4504 uint32_t file_attributes
,
4505 struct files_struct
*fsp
)
4507 TALLOC_CTX
*frame
= talloc_stackframe();
4508 const struct loadparm_substitution
*lp_sub
=
4509 loadparm_s3_global_substitution();
4512 bool posix_open
= false;
4513 bool need_re_stat
= false;
4514 uint32_t access_mask
= SEC_DIR_ADD_SUBDIR
;
4515 struct smb_filename
*first_atname
= NULL
;
4516 struct smb_filename
*tmp_atname
= NULL
;
4517 char *orig_dname
= NULL
;
4518 char *tmp_dname
= NULL
;
4519 int vfs_use_tmp
= lp_vfs_mkdir_use_tmp_name(SNUM(conn
));
4520 bool need_tmpname
= false;
4521 struct server_id id
= messaging_server_id(conn
->sconn
->msg_ctx
);
4522 struct server_id_buf idbuf
;
4523 char *idstr
= server_id_str_buf_unique_ex(id
, '%', &idbuf
);
4524 struct vfs_open_how how
= { .flags
= O_RDONLY
|O_DIRECTORY
, };
4525 struct vfs_rename_how rhow
= { .flags
= VFS_RENAME_HOW_NO_REPLACE
, };
4528 if (!CAN_WRITE(conn
) || (access_mask
& ~(conn
->share_access
))) {
4529 DBG_INFO("failing share access %s\n",
4530 lp_servicename(talloc_tos(), lp_sub
, SNUM(conn
)));
4532 return NT_STATUS_ACCESS_DENIED
;
4535 if (file_attributes
& FILE_FLAG_POSIX_SEMANTICS
) {
4537 mode
= (mode_t
)(file_attributes
& ~FILE_FLAG_POSIX_SEMANTICS
);
4539 mode
= unix_mode(conn
,
4540 FILE_ATTRIBUTE_DIRECTORY
,
4542 parent_dir_fname
->fsp
);
4545 status
= check_parent_access_fsp(parent_dir_fname
->fsp
, access_mask
);
4546 if(!NT_STATUS_IS_OK(status
)) {
4547 DBG_INFO("check_parent_access_fsp "
4548 "on directory %s for path %s returned %s\n",
4549 smb_fname_str_dbg(parent_dir_fname
),
4550 smb_dname
->base_name
,
4556 if (lp_inherit_acls(SNUM(conn
))) {
4557 if (directory_has_default_acl_fsp(parent_dir_fname
->fsp
)) {
4558 mode
= (0777 & lp_directory_mask(SNUM(conn
)));
4560 need_tmpname
= true;
4561 } else if (lp_store_dos_attributes(SNUM(conn
))) {
4562 need_tmpname
= true;
4563 } else if (lp_inherit_permissions(SNUM(conn
))) {
4564 need_tmpname
= true;
4565 } else if (lp_inherit_owner(SNUM(conn
)) != INHERIT_OWNER_NO
) {
4566 need_tmpname
= true;
4567 } else if (lp_nt_acl_support(SNUM(conn
)) && sd
!= NULL
) {
4568 need_tmpname
= true;
4571 if (vfs_use_tmp
!= Auto
) {
4572 need_tmpname
= vfs_use_tmp
;
4575 if (!need_tmpname
) {
4576 first_atname
= smb_fname_atname
;
4581 * In order to avoid races where other clients could
4582 * see the directory before it is setup completely
4583 * we use a temporary name and rename it
4584 * when everything is ready.
4587 orig_dname
= smb_dname
->base_name
;
4589 tmp_atname
= cp_smb_filename(frame
,
4591 if (tmp_atname
== NULL
) {
4593 return NT_STATUS_NO_MEMORY
;
4595 TALLOC_FREE(tmp_atname
->base_name
);
4596 tmp_atname
->base_name
= talloc_asprintf(tmp_atname
,
4600 smb_fname_atname
->base_name
);
4601 if (tmp_atname
== NULL
) {
4603 return NT_STATUS_NO_MEMORY
;
4605 SMB_ASSERT(smbd_is_tmpname(tmp_atname
->base_name
, NULL
));
4606 if (!ISDOT(parent_dir_fname
->base_name
)) {
4607 tmp_dname
= talloc_asprintf(frame
,
4609 parent_dir_fname
->base_name
,
4610 tmp_atname
->base_name
);
4611 if (tmp_dname
== NULL
) {
4613 return NT_STATUS_NO_MEMORY
;
4616 tmp_dname
= talloc_strdup(frame
, tmp_atname
->base_name
);
4617 if (tmp_dname
== NULL
) {
4619 return NT_STATUS_NO_MEMORY
;
4623 smb_dname
->base_name
= tmp_dname
;
4625 DBG_DEBUG("temporary replace '%s' by '%s'\n",
4626 orig_dname
, tmp_dname
);
4628 first_atname
= tmp_atname
;
4631 ret
= SMB_VFS_MKDIRAT(conn
,
4632 parent_dir_fname
->fsp
,
4636 status
= map_nt_error_from_unix(errno
);
4637 DBG_NOTICE("MKDIRAT failed for '%s': %s\n",
4638 smb_fname_str_dbg(smb_dname
), nt_errstr(status
));
4643 * Make this a pathref fsp for now. open_directory() will reopen as a
4646 fsp
->fsp_flags
.is_pathref
= true;
4648 status
= fd_openat(parent_dir_fname
->fsp
, first_atname
, fsp
, &how
);
4649 if (!NT_STATUS_IS_OK(status
)) {
4650 DBG_ERR("fd_openat() failed for '%s': %s\n",
4651 smb_fname_str_dbg(smb_dname
), nt_errstr(status
));
4655 /* Ensure we're checking for a symlink here.... */
4656 /* We don't want to get caught by a symlink racer. */
4658 status
= vfs_stat_fsp(fsp
);
4659 if (!NT_STATUS_IS_OK(status
)) {
4660 DBG_ERR("Could not stat directory '%s' just created: %s\n",
4661 smb_fname_str_dbg(smb_dname
), nt_errstr(status
));
4665 if (!S_ISDIR(smb_dname
->st
.st_ex_mode
)) {
4666 DBG_ERR("Directory '%s' just created is not a directory !\n",
4667 smb_fname_str_dbg(smb_dname
));
4668 status
= NT_STATUS_NOT_A_DIRECTORY
;
4672 if (lp_store_dos_attributes(SNUM(conn
))) {
4673 file_set_dosmode(conn
,
4675 file_attributes
| FILE_ATTRIBUTE_DIRECTORY
,
4680 if (lp_inherit_permissions(SNUM(conn
))) {
4681 inherit_access_posix_acl(conn
, parent_dir_fname
->fsp
,
4683 need_re_stat
= true;
4688 * Check if high bits should have been set,
4689 * then (if bits are missing): add them.
4690 * Consider bits automagically set by UNIX, i.e. SGID bit from parent
4693 if ((mode
& ~(S_IRWXU
|S_IRWXG
|S_IRWXO
)) &&
4694 (mode
& ~smb_dname
->st
.st_ex_mode
)) {
4696 (smb_dname
->st
.st_ex_mode
|
4697 (mode
& ~smb_dname
->st
.st_ex_mode
)));
4698 need_re_stat
= true;
4702 /* Change the owner if required. */
4703 if (lp_inherit_owner(SNUM(conn
)) != INHERIT_OWNER_NO
) {
4704 change_dir_owner_to_parent_fsp(parent_dir_fname
->fsp
,
4706 need_re_stat
= true;
4710 status
= vfs_stat_fsp(fsp
);
4711 if (!NT_STATUS_IS_OK(status
)) {
4712 DBG_ERR("Could not stat directory '%s' just created: %s\n",
4713 smb_fname_str_dbg(smb_dname
), nt_errstr(status
));
4718 if (lp_nt_acl_support(SNUM(conn
))) {
4719 status
= apply_new_nt_acl(parent_dir_fname
->fsp
,
4722 if (!NT_STATUS_IS_OK(status
)) {
4723 DBG_WARNING("apply_new_nt_acl() failed for %s with %s\n",
4730 if (!need_tmpname
) {
4735 * A rename needs a valid stat for the source,
4736 * see vfs_fruit.c ...
4738 tmp_atname
->st
= smb_dname
->st
;
4741 * We first try VFS_RENAME_HOW_NO_REPLACE,
4742 * if it's implemented in the kernel,
4743 * we'll always get EEXIST if the target
4744 * exist, as it's handled at the linux vfs
4745 * layer. But if it doesn't exist we
4746 * can still get EINVAL if the actual
4747 * filesystem doesn't support RENAME_NOREPLACE.
4749 * If the kernel doesn't support rename2()
4750 * we get EINVAL instead of ENOSYS (this
4751 * is mapped in the libreplace replacement
4752 * (as well as the glibc replacement).
4754 ret
= SMB_VFS_RENAMEAT(conn
,
4755 parent_dir_fname
->fsp
,
4757 parent_dir_fname
->fsp
,
4760 if (ret
== -1 && errno
== EINVAL
) {
4762 * This is the strategie we use without having
4763 * renameat2(RENAME_NOREPLACE):
4765 * renameat() is able to replace a directory if the source is
4768 * So in order to avoid races as much as possible we do a
4769 * mkdirat() with mode 0 in order to catch EEXIST almost
4770 * atomically, when this code runs by two processes at the same
4773 * Then a renameat() makes the temporary directory available for
4776 * This a much smaller window where the other clients may see
4777 * the incomplete directory, which has a mode of 0.
4780 rhow
.flags
&= ~VFS_RENAME_HOW_NO_REPLACE
;
4782 DBG_DEBUG("MKDIRAT/RENAMEAT '%s' -> '%s'\n",
4783 tmp_dname
, orig_dname
);
4785 ret
= SMB_VFS_MKDIRAT(conn
,
4786 parent_dir_fname
->fsp
,
4790 status
= map_nt_error_from_unix(errno
);
4791 DBG_NOTICE("MKDIRAT failed for '%s': %s\n",
4792 orig_dname
, nt_errstr(status
));
4796 ret
= SMB_VFS_RENAMEAT(conn
,
4797 parent_dir_fname
->fsp
,
4799 parent_dir_fname
->fsp
,
4805 status
= map_nt_error_from_unix(errno
);
4806 DBG_NOTICE("RENAMEAT failed for '%s' -> '%s': %s\n",
4807 tmp_dname
, orig_dname
, nt_errstr(status
));
4810 smb_fname_atname
->st
= tmp_atname
->st
;
4811 smb_dname
->base_name
= orig_dname
;
4814 DBG_DEBUG("Created directory '%s'\n",
4815 smb_fname_str_dbg(smb_dname
));
4818 return NT_STATUS_OK
;
4821 DBG_NOTICE("%s: rollback and unlink '%s'\n",
4824 ret
= SMB_VFS_UNLINKAT(conn
,
4825 parent_dir_fname
->fsp
,
4829 DBG_NOTICE("SMB_VFS_UNLINKAT(%s): OK\n",
4832 NTSTATUS status2
= map_nt_error_from_unix(errno
);
4833 DBG_WARNING("SMB_VFS_UNLINKAT(%s) ignoring %s\n",
4834 tmp_dname
, nt_errstr(status2
));
4838 if (!need_tmpname
) {
4842 DBG_NOTICE("%s: restoring '%s' -> '%s'\n",
4846 SET_STAT_INVALID(smb_fname_atname
->st
);
4847 smb_dname
->base_name
= orig_dname
;
4848 SET_STAT_INVALID(smb_dname
->st
);
4853 /****************************************************************************
4854 Open a directory from an NT SMB call.
4855 ****************************************************************************/
4857 static NTSTATUS
open_directory(connection_struct
*conn
,
4858 struct smb_request
*req
,
4859 uint32_t access_mask
,
4860 uint32_t share_access
,
4861 uint32_t create_disposition
,
4862 uint32_t create_options
,
4863 uint32_t file_attributes
,
4864 struct smb_filename
*parent_dir_fname
,
4865 struct smb_filename
*smb_fname_atname
,
4866 uint32_t oplock_request
,
4867 const struct smb2_lease
*lease
,
4868 struct security_descriptor
*sd
,
4870 struct files_struct
*fsp
)
4872 struct smb_filename
*smb_dname
= fsp
->fsp_name
;
4873 bool dir_existed
= VALID_STAT(smb_dname
->st
);
4874 bool deferred
= false;
4875 struct open_ntcreate_lock_state lck_state
= {};
4876 bool keep_locked
= false;
4878 struct timespec mtimespec
;
4880 uint32_t need_fd_access
;
4883 if (is_ntfs_stream_smb_fname(smb_dname
)) {
4884 DEBUG(2, ("open_directory: %s is a stream name!\n",
4885 smb_fname_str_dbg(smb_dname
)));
4886 return NT_STATUS_NOT_A_DIRECTORY
;
4889 if (!(file_attributes
& FILE_FLAG_POSIX_SEMANTICS
)) {
4890 /* Ensure we have a directory attribute. */
4891 file_attributes
|= FILE_ATTRIBUTE_DIRECTORY
;
4894 DBG_INFO("opening directory %s, access_mask = 0x%"PRIx32
", "
4895 "share_access = 0x%"PRIx32
" create_options = 0x%"PRIx32
", "
4896 "create_disposition = 0x%"PRIx32
", "
4897 "file_attributes = 0x%"PRIx32
"\n",
4898 smb_fname_str_dbg(smb_dname
),
4906 /* Ensure req == NULL means INTERNAL_OPEN_ONLY */
4907 SMB_ASSERT(oplock_request
== INTERNAL_OPEN_ONLY
);
4909 /* And req != NULL means no INTERNAL_OPEN_ONLY */
4910 SMB_ASSERT((oplock_request
& INTERNAL_OPEN_ONLY
) == 0);
4914 struct deferred_open_record
*open_rec
= NULL
;
4916 deferred
= get_deferred_open_message_state(req
, NULL
, &open_rec
);
4918 remove_deferred_open_message_smb(req
->xconn
, req
->mid
);
4922 status
= smbd_calculate_access_mask_fsp(parent_dir_fname
->fsp
,
4927 if (!NT_STATUS_IS_OK(status
)) {
4928 DBG_DEBUG("smbd_calculate_access_mask_fsp "
4929 "on file %s returned %s\n",
4930 smb_fname_str_dbg(smb_dname
),
4935 if ((access_mask
& SEC_FLAG_SYSTEM_SECURITY
) &&
4936 !security_token_has_privilege(get_current_nttok(conn
),
4937 SEC_PRIV_SECURITY
)) {
4938 DEBUG(10, ("open_directory: open on %s "
4939 "failed - SEC_FLAG_SYSTEM_SECURITY denied.\n",
4940 smb_fname_str_dbg(smb_dname
)));
4941 return NT_STATUS_PRIVILEGE_NOT_HELD
;
4944 switch( create_disposition
) {
4948 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
4951 info
= FILE_WAS_OPENED
;
4956 /* If directory exists error. If directory doesn't
4960 status
= NT_STATUS_OBJECT_NAME_COLLISION
;
4961 DEBUG(2, ("open_directory: unable to create "
4962 "%s. Error was %s\n",
4963 smb_fname_str_dbg(smb_dname
),
4964 nt_errstr(status
)));
4968 if (smb_fname_atname
->twrp
!= 0) {
4969 return NT_STATUS_MEDIA_WRITE_PROTECTED
;
4972 status
= mkdir_internal(conn
,
4980 if (!NT_STATUS_IS_OK(status
)) {
4981 DEBUG(2, ("open_directory: unable to create "
4982 "%s. Error was %s\n",
4983 smb_fname_str_dbg(smb_dname
),
4984 nt_errstr(status
)));
4988 info
= FILE_WAS_CREATED
;
4993 * If directory exists open. If directory doesn't
4998 status
= NT_STATUS_OK
;
4999 info
= FILE_WAS_OPENED
;
5001 if (smb_fname_atname
->twrp
!= 0) {
5002 return NT_STATUS_MEDIA_WRITE_PROTECTED
;
5004 status
= mkdir_internal(conn
,
5012 if (NT_STATUS_IS_OK(status
)) {
5013 info
= FILE_WAS_CREATED
;
5016 /* Cope with create race. */
5017 if (!NT_STATUS_EQUAL(status
,
5018 NT_STATUS_OBJECT_NAME_COLLISION
)) {
5019 DEBUG(2, ("open_directory: unable to create "
5020 "%s. Error was %s\n",
5021 smb_fname_str_dbg(smb_dname
),
5022 nt_errstr(status
)));
5027 * If mkdir_internal() returned
5028 * NT_STATUS_OBJECT_NAME_COLLISION
5029 * we still must lstat the path.
5031 ret
= SMB_VFS_FSTATAT(
5033 parent_dir_fname
->fsp
,
5036 AT_SYMLINK_NOFOLLOW
);
5038 DEBUG(2, ("Could not stat "
5039 "directory '%s' just "
5044 return map_nt_error_from_unix(
5048 info
= FILE_WAS_OPENED
;
5054 case FILE_SUPERSEDE
:
5055 case FILE_OVERWRITE
:
5056 case FILE_OVERWRITE_IF
:
5058 DEBUG(5,("open_directory: invalid create_disposition "
5059 "0x%x for directory %s\n",
5060 (unsigned int)create_disposition
,
5061 smb_fname_str_dbg(smb_dname
)));
5062 return NT_STATUS_INVALID_PARAMETER
;
5065 if(!S_ISDIR(smb_dname
->st
.st_ex_mode
)) {
5066 DEBUG(5,("open_directory: %s is not a directory !\n",
5067 smb_fname_str_dbg(smb_dname
)));
5068 return NT_STATUS_NOT_A_DIRECTORY
;
5072 * Setup the files_struct for it.
5075 fsp
->file_id
= vfs_file_id_from_sbuf(conn
, &smb_dname
->st
);
5076 fsp
->vuid
= req
? req
->vuid
: UID_FIELD_INVALID
;
5077 fsp
->file_pid
= req
? req
->smbpid
: 0;
5078 fsp
->fsp_flags
.can_lock
= false;
5079 fsp
->fsp_flags
.can_read
= false;
5080 fsp
->fsp_flags
.can_write
= false;
5082 fh_set_private_options(fsp
->fh
, 0);
5084 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
5086 fsp
->access_mask
= access_mask
| FILE_READ_ATTRIBUTES
;
5087 fsp
->print_file
= NULL
;
5088 fsp
->fsp_flags
.modified
= false;
5089 fsp
->oplock_type
= NO_OPLOCK
;
5090 fsp
->sent_oplock_break
= NO_BREAK_SENT
;
5091 fsp
->fsp_flags
.is_directory
= true;
5092 if (file_attributes
& FILE_FLAG_POSIX_SEMANTICS
) {
5093 fsp
->fsp_flags
.posix_open
= true;
5096 /* Don't store old timestamps for directory
5097 handles in the internal database. We don't
5098 update them in there if new objects
5099 are created in the directory. Currently
5100 we only update timestamps on file writes.
5103 mtimespec
= make_omit_timespec();
5106 * Obviously for FILE_LIST_DIRECTORY we need to reopen to get an fd
5107 * usable for reading a directory. SMB2_FLUSH may be called on
5108 * directories opened with FILE_ADD_FILE and FILE_ADD_SUBDIRECTORY so
5109 * for those we need to reopen as well.
5112 FILE_LIST_DIRECTORY
|
5114 FILE_ADD_SUBDIRECTORY
;
5116 if (access_mask
& need_fd_access
) {
5117 struct vfs_open_how how
= {
5118 .flags
= O_RDONLY
| O_DIRECTORY
,
5122 status
= reopen_from_fsp(parent_dir_fname
->fsp
,
5127 if (!NT_STATUS_IS_OK(status
)) {
5128 DBG_INFO("Could not open fd for [%s]: %s\n",
5129 smb_fname_str_dbg(smb_dname
),
5135 status
= vfs_stat_fsp(fsp
);
5136 if (!NT_STATUS_IS_OK(status
)) {
5141 if(!S_ISDIR(fsp
->fsp_name
->st
.st_ex_mode
)) {
5142 DEBUG(5,("open_directory: %s is not a directory !\n",
5143 smb_fname_str_dbg(smb_dname
)));
5145 return NT_STATUS_NOT_A_DIRECTORY
;
5148 /* Ensure there was no race condition. We need to check
5149 * dev/inode but not permissions, as these can change
5151 if (!check_same_dev_ino(&smb_dname
->st
, &fsp
->fsp_name
->st
)) {
5152 DEBUG(5,("open_directory: stat struct differs for "
5154 smb_fname_str_dbg(smb_dname
)));
5156 return NT_STATUS_ACCESS_DENIED
;
5159 if (info
== FILE_WAS_OPENED
) {
5160 status
= smbd_check_access_rights_fsp(parent_dir_fname
->fsp
,
5164 if (!NT_STATUS_IS_OK(status
)) {
5165 DBG_DEBUG("smbd_check_access_rights_fsp on "
5166 "file %s failed with %s\n",
5175 * If we created a new directory or going to delete it later,
5176 * we should keep * the share_mode_lock (g_lock) until we call
5177 * share_mode_entry_prepare_unlock()
5179 if (info
!= FILE_WAS_OPENED
) {
5181 } else if (create_options
& FILE_DELETE_ON_CLOSE
) {
5185 lck_state
= (struct open_ntcreate_lock_state
) {
5187 .object_type
= "directory",
5189 .create_disposition
= create_disposition
,
5190 .access_mask
= access_mask
,
5191 .open_access_mask
= access_mask
,
5192 .share_access
= share_access
,
5193 .oplock_request
= oplock_request
,
5195 .first_open_attempt
= !deferred
,
5196 .keep_locked
= keep_locked
,
5199 status
= share_mode_entry_prepare_lock_add(&lck_state
.prepare_state
,
5204 open_ntcreate_lock_add_entry
,
5206 if (!NT_STATUS_IS_OK(status
)) {
5207 DBG_ERR("share_mode_entry_prepare_lock_add() failed for %s - %s\n",
5208 smb_fname_str_dbg(smb_dname
), nt_errstr(status
));
5213 status
= lck_state
.status
;
5214 if (!NT_STATUS_IS_OK(status
)) {
5220 * From here we need to use 'goto unlock;' instead of return !!!
5223 /* For directories the delete on close bit at open time seems
5224 always to be honored on close... See test 19 in Samba4 BASE-DELETE. */
5225 if (create_options
& FILE_DELETE_ON_CLOSE
) {
5226 status
= can_set_delete_on_close(fsp
, 0);
5227 if (!NT_STATUS_IS_OK(status
) && !NT_STATUS_EQUAL(status
, NT_STATUS_DIRECTORY_NOT_EMPTY
)) {
5228 lck_state
.cleanup_fn
=
5229 open_ntcreate_lock_cleanup_entry
;
5233 if (NT_STATUS_IS_OK(status
)) {
5234 /* Note that here we set the *initial* delete on close flag,
5235 not the regular one. The magic gets handled in close. */
5236 fsp
->fsp_flags
.initial_delete_on_close
= true;
5241 * Deal with other opens having a modified write time.
5243 if (!is_omit_timespec(&lck_state
.write_time
)) {
5244 update_stat_ex_mtime(&fsp
->fsp_name
->st
, lck_state
.write_time
);
5251 status
= NT_STATUS_OK
;
5254 ulstatus
= share_mode_entry_prepare_unlock(&lck_state
.prepare_state
,
5255 lck_state
.cleanup_fn
,
5257 if (!NT_STATUS_IS_OK(ulstatus
)) {
5258 DBG_ERR("share_mode_entry_prepare_unlock() failed for %s - %s\n",
5259 smb_fname_str_dbg(smb_dname
), nt_errstr(ulstatus
));
5260 smb_panic("share_mode_entry_prepare_unlock() failed!");
5263 if (info
== FILE_WAS_CREATED
) {
5265 NOTIFY_ACTION_ADDED
|
5266 NOTIFY_ACTION_DIRLEASE_BREAK
,
5267 FILE_NOTIFY_CHANGE_DIR_NAME
,
5269 fsp_get_smb2_lease(fsp
));
5272 if (!NT_STATUS_IS_OK(status
)) {
5277 return NT_STATUS_OK
;
5280 NTSTATUS
create_directory(connection_struct
*conn
,
5281 struct smb_request
*req
,
5282 struct files_struct
*dirfsp
,
5283 struct smb_filename
*smb_dname
)
5288 status
= SMB_VFS_CREATE_FILE(
5291 dirfsp
, /* dirfsp */
5292 smb_dname
, /* fname */
5293 FILE_READ_ATTRIBUTES
, /* access_mask */
5294 FILE_SHARE_NONE
, /* share_access */
5295 FILE_CREATE
, /* create_disposition*/
5296 FILE_DIRECTORY_FILE
, /* create_options */
5297 FILE_ATTRIBUTE_DIRECTORY
, /* file_attributes */
5298 0, /* oplock_request */
5300 0, /* allocation_size */
5301 0, /* private_flags */
5306 NULL
, NULL
); /* create context */
5308 if (NT_STATUS_IS_OK(status
)) {
5309 close_file_free(req
, &fsp
, NORMAL_CLOSE
);
5315 /****************************************************************************
5316 Receive notification that one of our open files has been renamed by another
5318 ****************************************************************************/
5320 void msg_file_was_renamed(struct messaging_context
*msg_ctx
,
5323 struct server_id src
,
5326 struct file_rename_message
*msg
= NULL
;
5327 enum ndr_err_code ndr_err
;
5329 struct smb_filename
*smb_fname
= NULL
;
5330 struct smbd_server_connection
*sconn
=
5331 talloc_get_type_abort(private_data
,
5332 struct smbd_server_connection
);
5334 msg
= talloc(talloc_tos(), struct file_rename_message
);
5336 DBG_WARNING("talloc failed\n");
5340 ndr_err
= ndr_pull_struct_blob_all(
5344 (ndr_pull_flags_fn_t
)ndr_pull_file_rename_message
);
5345 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
5346 DBG_DEBUG("ndr_pull_file_rename_message failed: %s\n",
5347 ndr_errstr(ndr_err
));
5350 if (DEBUGLEVEL
>= 10) {
5351 struct server_id_buf buf
;
5352 DBG_DEBUG("Got rename message from %s\n",
5353 server_id_str_buf(src
, &buf
));
5354 NDR_PRINT_DEBUG(file_rename_message
, msg
);
5357 /* stream_name must always be NULL if there is no stream. */
5358 if ((msg
->stream_name
!= NULL
) && (msg
->stream_name
[0] == '\0')) {
5359 msg
->stream_name
= NULL
;
5362 smb_fname
= synthetic_smb_fname(msg
,
5368 if (smb_fname
== NULL
) {
5369 DBG_DEBUG("synthetic_smb_fname failed\n");
5373 fsp
= file_find_dif(sconn
, msg
->id
, msg
->share_file_id
);
5375 DBG_DEBUG("fsp not found\n");
5379 if (strcmp(fsp
->conn
->connectpath
, msg
->servicepath
) == 0) {
5380 SMB_STRUCT_STAT fsp_orig_sbuf
;
5382 DBG_DEBUG("renaming file %s from %s -> %s\n",
5385 smb_fname_str_dbg(smb_fname
));
5388 * The incoming smb_fname here has an
5389 * invalid stat struct from synthetic_smb_fname()
5391 * Preserve the existing stat from the
5392 * open fsp after fsp_set_smb_fname()
5393 * overwrites with the invalid stat.
5395 * (We could just copy this into
5396 * smb_fname->st, but keep this code
5397 * identical to the fix in rename_open_files()
5400 * We will do an fstat before returning
5401 * any of this metadata to the client anyway.
5403 fsp_orig_sbuf
= fsp
->fsp_name
->st
;
5404 status
= fsp_set_smb_fname(fsp
, smb_fname
);
5405 if (!NT_STATUS_IS_OK(status
)) {
5406 DBG_DEBUG("fsp_set_smb_fname failed: %s\n",
5409 fsp
->fsp_name
->st
= fsp_orig_sbuf
;
5413 * Now we have the complete path we can work out if
5414 * this is actually within this share and adjust
5415 * newname accordingly.
5417 DBG_DEBUG("share mismatch (sharepath %s not sharepath %s) "
5418 "%s from %s -> %s\n",
5419 fsp
->conn
->connectpath
,
5423 smb_fname_str_dbg(smb_fname
));
5430 * If a main file is opened for delete, all streams need to be checked for
5431 * !FILE_SHARE_DELETE. Do this by opening with DELETE_ACCESS.
5432 * If that works, delete them all by setting the delete on close and close.
5435 static NTSTATUS
open_streams_for_delete(connection_struct
*conn
,
5436 const struct smb_filename
*smb_fname
)
5438 struct stream_struct
*stream_info
= NULL
;
5439 files_struct
**streams
= NULL
;
5441 unsigned int i
, num_streams
= 0;
5442 TALLOC_CTX
*frame
= talloc_stackframe();
5443 const struct smb_filename
*pathref
= NULL
;
5446 if (smb_fname
->fsp
== NULL
) {
5447 struct smb_filename
*tmp
= NULL
;
5448 status
= synthetic_pathref(frame
,
5450 smb_fname
->base_name
,
5456 if (!NT_STATUS_IS_OK(status
)) {
5457 if (NT_STATUS_EQUAL(status
, NT_STATUS_NOT_IMPLEMENTED
)
5458 || NT_STATUS_EQUAL(status
,
5459 NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
5460 DBG_DEBUG("no streams around\n");
5462 return NT_STATUS_OK
;
5464 DBG_DEBUG("synthetic_pathref failed: %s\n",
5470 pathref
= smb_fname
;
5472 status
= vfs_fstreaminfo(pathref
->fsp
, talloc_tos(),
5473 &num_streams
, &stream_info
);
5475 if (NT_STATUS_EQUAL(status
, NT_STATUS_NOT_IMPLEMENTED
)
5476 || NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
5477 DEBUG(10, ("no streams around\n"));
5479 return NT_STATUS_OK
;
5482 if (!NT_STATUS_IS_OK(status
)) {
5483 DEBUG(10, ("vfs_fstreaminfo failed: %s\n",
5484 nt_errstr(status
)));
5488 DEBUG(10, ("open_streams_for_delete found %d streams\n",
5491 if (num_streams
== 0) {
5493 return NT_STATUS_OK
;
5496 streams
= talloc_array(talloc_tos(), files_struct
*, num_streams
);
5497 if (streams
== NULL
) {
5498 DEBUG(0, ("talloc failed\n"));
5499 status
= NT_STATUS_NO_MEMORY
;
5503 for (i
=0; i
<num_streams
; i
++) {
5504 struct smb_filename
*smb_fname_cp
;
5506 if (strequal(stream_info
[i
].name
, "::$DATA")) {
5511 smb_fname_cp
= synthetic_smb_fname(talloc_tos(),
5512 smb_fname
->base_name
,
5513 stream_info
[i
].name
,
5517 ~SMB_FILENAME_POSIX_PATH
));
5518 if (smb_fname_cp
== NULL
) {
5519 status
= NT_STATUS_NO_MEMORY
;
5523 status
= openat_pathref_fsp(conn
->cwd_fsp
, smb_fname_cp
);
5524 if (!NT_STATUS_IS_OK(status
)) {
5525 DBG_DEBUG("Unable to open stream [%s]: %s\n",
5526 smb_fname_str_dbg(smb_fname_cp
),
5528 TALLOC_FREE(smb_fname_cp
);
5532 status
= SMB_VFS_CREATE_FILE(
5536 smb_fname_cp
, /* fname */
5537 DELETE_ACCESS
, /* access_mask */
5538 (FILE_SHARE_READ
| /* share_access */
5539 FILE_SHARE_WRITE
| FILE_SHARE_DELETE
),
5540 FILE_OPEN
, /* create_disposition*/
5541 0, /* create_options */
5542 FILE_ATTRIBUTE_NORMAL
, /* file_attributes */
5543 0, /* oplock_request */
5545 0, /* allocation_size */
5546 0, /* private_flags */
5549 &streams
[i
], /* result */
5551 NULL
, NULL
); /* create context */
5553 if (!NT_STATUS_IS_OK(status
)) {
5554 DEBUG(10, ("Could not open stream %s: %s\n",
5555 smb_fname_str_dbg(smb_fname_cp
),
5556 nt_errstr(status
)));
5558 TALLOC_FREE(smb_fname_cp
);
5561 TALLOC_FREE(smb_fname_cp
);
5565 * don't touch the variable "status" beyond this point :-)
5568 for (j
= i
-1 ; j
>= 0; j
--) {
5569 if (streams
[j
] == NULL
) {
5573 DEBUG(10, ("Closing stream # %d, %s\n", j
,
5574 fsp_str_dbg(streams
[j
])));
5575 close_file_free(NULL
, &streams
[j
], NORMAL_CLOSE
);
5583 /*********************************************************************
5584 Create a default ACL by inheriting from the parent. If no inheritance
5585 from the parent available, don't set anything. This will leave the actual
5586 permissions the new file or directory already got from the filesystem
5587 as the NT ACL when read.
5588 *********************************************************************/
5590 static NTSTATUS
inherit_new_acl(files_struct
*dirfsp
, files_struct
*fsp
)
5592 TALLOC_CTX
*frame
= talloc_stackframe();
5593 struct security_descriptor
*parent_desc
= NULL
;
5594 NTSTATUS status
= NT_STATUS_OK
;
5595 struct security_descriptor
*psd
= NULL
;
5596 const struct dom_sid
*owner_sid
= NULL
;
5597 const struct dom_sid
*group_sid
= NULL
;
5598 uint32_t security_info_sent
= (SECINFO_OWNER
| SECINFO_GROUP
| SECINFO_DACL
);
5599 struct security_token
*token
= fsp
->conn
->session_info
->security_token
;
5600 bool inherit_owner
=
5601 (lp_inherit_owner(SNUM(fsp
->conn
)) == INHERIT_OWNER_WINDOWS_AND_UNIX
);
5602 bool inheritable_components
= false;
5603 bool try_builtin_administrators
= false;
5604 const struct dom_sid
*BA_U_sid
= NULL
;
5605 const struct dom_sid
*BA_G_sid
= NULL
;
5606 bool try_system
= false;
5607 const struct dom_sid
*SY_U_sid
= NULL
;
5608 const struct dom_sid
*SY_G_sid
= NULL
;
5612 status
= SMB_VFS_FGET_NT_ACL(dirfsp
,
5613 (SECINFO_OWNER
| SECINFO_GROUP
| SECINFO_DACL
),
5616 if (!NT_STATUS_IS_OK(status
)) {
5621 inheritable_components
= sd_has_inheritable_components(parent_desc
,
5622 fsp
->fsp_flags
.is_directory
);
5624 if (!inheritable_components
&& !inherit_owner
) {
5626 /* Nothing to inherit and not setting owner. */
5627 return NT_STATUS_OK
;
5630 /* Create an inherited descriptor from the parent. */
5632 if (DEBUGLEVEL
>= 10) {
5633 DEBUG(10,("inherit_new_acl: parent acl for %s is:\n",
5634 fsp_str_dbg(fsp
) ));
5635 NDR_PRINT_DEBUG(security_descriptor
, parent_desc
);
5638 /* Inherit from parent descriptor if "inherit owner" set. */
5639 if (inherit_owner
) {
5640 owner_sid
= parent_desc
->owner_sid
;
5641 group_sid
= parent_desc
->group_sid
;
5644 if (owner_sid
== NULL
) {
5645 if (security_token_has_builtin_administrators(token
)) {
5646 try_builtin_administrators
= true;
5647 } else if (security_token_is_system(token
)) {
5648 try_builtin_administrators
= true;
5653 if (group_sid
== NULL
&&
5654 token
->num_sids
== PRIMARY_GROUP_SID_INDEX
)
5656 if (security_token_is_system(token
)) {
5657 try_builtin_administrators
= true;
5662 if (try_builtin_administrators
) {
5663 struct unixid ids
= { .id
= 0 };
5665 ok
= sids_to_unixids(&global_sid_Builtin_Administrators
, 1, &ids
);
5669 BA_U_sid
= &global_sid_Builtin_Administrators
;
5670 BA_G_sid
= &global_sid_Builtin_Administrators
;
5673 BA_U_sid
= &global_sid_Builtin_Administrators
;
5676 BA_G_sid
= &global_sid_Builtin_Administrators
;
5685 struct unixid ids
= { .id
= 0 };
5687 ok
= sids_to_unixids(&global_sid_System
, 1, &ids
);
5691 SY_U_sid
= &global_sid_System
;
5692 SY_G_sid
= &global_sid_System
;
5695 SY_U_sid
= &global_sid_System
;
5698 SY_G_sid
= &global_sid_System
;
5706 if (owner_sid
== NULL
) {
5707 owner_sid
= BA_U_sid
;
5710 if (owner_sid
== NULL
) {
5711 owner_sid
= SY_U_sid
;
5714 if (group_sid
== NULL
) {
5715 group_sid
= SY_G_sid
;
5718 if (try_system
&& group_sid
== NULL
) {
5719 group_sid
= BA_G_sid
;
5722 if (owner_sid
== NULL
) {
5723 owner_sid
= &token
->sids
[PRIMARY_USER_SID_INDEX
];
5725 if (group_sid
== NULL
) {
5726 if (token
->num_sids
== PRIMARY_GROUP_SID_INDEX
) {
5727 group_sid
= &token
->sids
[PRIMARY_USER_SID_INDEX
];
5729 group_sid
= &token
->sids
[PRIMARY_GROUP_SID_INDEX
];
5733 status
= se_create_child_secdesc(frame
,
5739 fsp
->fsp_flags
.is_directory
);
5740 if (!NT_STATUS_IS_OK(status
)) {
5745 /* If inheritable_components == false,
5746 se_create_child_secdesc()
5747 creates a security descriptor with a NULL dacl
5748 entry, but with SEC_DESC_DACL_PRESENT. We need
5749 to remove that flag. */
5751 if (!inheritable_components
) {
5752 security_info_sent
&= ~SECINFO_DACL
;
5753 psd
->type
&= ~SEC_DESC_DACL_PRESENT
;
5756 if (DEBUGLEVEL
>= 10) {
5757 DEBUG(10,("inherit_new_acl: child acl for %s is:\n",
5758 fsp_str_dbg(fsp
) ));
5759 NDR_PRINT_DEBUG(security_descriptor
, psd
);
5762 if (inherit_owner
) {
5763 /* We need to be root to force this. */
5766 status
= SMB_VFS_FSET_NT_ACL(metadata_fsp(fsp
),
5769 if (inherit_owner
) {
5777 * If we already have a lease, it must match the new file id. [MS-SMB2]
5778 * 3.3.5.9.8 speaks about INVALID_PARAMETER if an already used lease key is
5779 * used for a different file name.
5782 struct lease_match_state
{
5783 /* Input parameters. */
5784 TALLOC_CTX
*mem_ctx
;
5785 const char *servicepath
;
5786 const struct smb_filename
*fname
;
5789 /* Return parameters. */
5790 uint32_t num_file_ids
;
5791 struct file_id
*ids
;
5792 NTSTATUS match_status
;
5795 /*************************************************************
5796 File doesn't exist but this lease key+guid is already in use.
5798 This is only allowable in the dynamic share case where the
5799 service path must be different.
5801 There is a small race condition here in the multi-connection
5802 case where a client sends two create calls on different connections,
5803 where the file doesn't exist and one smbd creates the leases_db
5804 entry first, but this will get fixed by the multichannel cleanup
5805 when all identical client_guids get handled by a single smbd.
5806 **************************************************************/
5808 static void lease_match_parser_new_file(
5810 const struct leases_db_file
*files
,
5811 struct lease_match_state
*state
)
5815 for (i
= 0; i
< num_files
; i
++) {
5816 const struct leases_db_file
*f
= &files
[i
];
5817 if (strequal(state
->servicepath
, f
->servicepath
)) {
5818 state
->match_status
= NT_STATUS_INVALID_PARAMETER
;
5823 /* Dynamic share case. Break leases on all other files. */
5824 state
->match_status
= leases_db_copy_file_ids(state
->mem_ctx
,
5828 if (!NT_STATUS_IS_OK(state
->match_status
)) {
5832 state
->num_file_ids
= num_files
;
5833 state
->match_status
= NT_STATUS_OPLOCK_NOT_GRANTED
;
5837 static void lease_match_parser(
5839 const struct leases_db_file
*files
,
5842 struct lease_match_state
*state
=
5843 (struct lease_match_state
*)private_data
;
5846 if (!state
->file_existed
) {
5848 * Deal with name mismatch or
5849 * possible dynamic share case separately
5850 * to make code clearer.
5852 lease_match_parser_new_file(num_files
,
5859 state
->match_status
= NT_STATUS_OK
;
5861 for (i
= 0; i
< num_files
; i
++) {
5862 const struct leases_db_file
*f
= &files
[i
];
5864 /* Everything should be the same. */
5865 if (!file_id_equal(&state
->id
, &f
->id
)) {
5867 * The client asked for a lease on a
5868 * file that doesn't match the file_id
5871 * Maybe this is a dynamic share, i.e.
5872 * a share where the servicepath is
5873 * different for different users (e.g.
5874 * the [HOMES] share.
5876 * If the servicepath is different, but the requested
5877 * file name + stream name is the same then this is
5878 * a dynamic share, the client is using the same share
5879 * name and doesn't know that the underlying servicepath
5880 * is different. It was expecting a lease on the
5881 * same file. Return NT_STATUS_OPLOCK_NOT_GRANTED
5884 * Otherwise the client has messed up, or is
5885 * testing our error codes, so return
5886 * NT_STATUS_INVALID_PARAMETER.
5888 if (!strequal(f
->servicepath
, state
->servicepath
) &&
5889 strequal(f
->base_name
, state
->fname
->base_name
) &&
5890 strequal(f
->stream_name
, state
->fname
->stream_name
))
5893 * Name is the same but servicepath is
5894 * different, dynamic share. Break leases.
5896 state
->match_status
=
5897 NT_STATUS_OPLOCK_NOT_GRANTED
;
5899 state
->match_status
=
5900 NT_STATUS_INVALID_PARAMETER
;
5904 if (!strequal(f
->servicepath
, state
->servicepath
)) {
5905 state
->match_status
= NT_STATUS_INVALID_PARAMETER
;
5908 if (!strequal(f
->base_name
, state
->fname
->base_name
)) {
5909 state
->match_status
= NT_STATUS_INVALID_PARAMETER
;
5912 if (!strequal(f
->stream_name
, state
->fname
->stream_name
)) {
5913 state
->match_status
= NT_STATUS_INVALID_PARAMETER
;
5918 if (NT_STATUS_IS_OK(state
->match_status
)) {
5920 * Common case - just opening another handle on a
5921 * file on a non-dynamic share.
5926 if (NT_STATUS_EQUAL(state
->match_status
, NT_STATUS_INVALID_PARAMETER
)) {
5927 /* Mismatched path. Error back to client. */
5932 * File id mismatch. Dynamic share case NT_STATUS_OPLOCK_NOT_GRANTED.
5933 * Don't allow leases.
5936 state
->match_status
= leases_db_copy_file_ids(state
->mem_ctx
,
5940 if (!NT_STATUS_IS_OK(state
->match_status
)) {
5944 state
->num_file_ids
= num_files
;
5945 state
->match_status
= NT_STATUS_OPLOCK_NOT_GRANTED
;
5949 struct lease_match_break_state
{
5950 struct messaging_context
*msg_ctx
;
5951 const struct smb2_lease_key
*lease_key
;
5959 static bool lease_match_break_fn(
5960 struct share_mode_entry
*e
,
5963 struct lease_match_break_state
*state
= private_data
;
5965 uint32_t e_lease_type
= SMB2_LEASE_NONE
;
5968 stale
= share_entry_stale_pid(e
);
5973 equal
= smb2_lease_key_equal(&e
->lease_key
, state
->lease_key
);
5978 status
= leases_db_get(
5982 &e_lease_type
, /* current_state */
5983 NULL
, /* breaking */
5984 NULL
, /* breaking_to_requested */
5985 NULL
, /* breaking_to_required */
5986 &state
->version
, /* lease_version */
5987 &state
->epoch
); /* epoch */
5988 if (NT_STATUS_IS_OK(status
)) {
5989 state
->found_lease
= true;
5991 DBG_WARNING("Could not find version/epoch: %s\n",
5996 if (e_lease_type
== SMB2_LEASE_NONE
) {
5999 send_break_message(state
->msg_ctx
, &state
->id
, e
, SMB2_LEASE_NONE
);
6002 * Windows 7 and 8 lease clients are broken in that they will
6003 * not respond to lease break requests whilst waiting for an
6004 * outstanding open request on that lease handle on the same
6005 * TCP connection, due to holding an internal inode lock.
6007 * This means we can't reschedule ourselves here, but must
6008 * return from the create.
6012 * Send the breaks and then return SMB2_LEASE_NONE in the
6013 * lease handle to cause them to acknowledge the lease
6014 * break. Consultation with Microsoft engineering confirmed
6015 * this approach is safe.
6021 static void lease_match_fid_fn(struct share_mode_lock
*lck
,
6026 ok
= share_mode_forall_leases(lck
, lease_match_break_fn
, private_data
);
6028 DBG_DEBUG("share_mode_forall_leases failed\n");
6032 static NTSTATUS
lease_match(connection_struct
*conn
,
6033 struct smb_request
*req
,
6034 const struct smb2_lease_key
*lease_key
,
6035 const char *servicepath
,
6036 const struct smb_filename
*fname
,
6037 uint16_t *p_version
,
6040 struct smbd_server_connection
*sconn
= req
->sconn
;
6041 TALLOC_CTX
*tos
= talloc_tos();
6042 struct lease_match_state state
= {
6044 .servicepath
= servicepath
,
6046 .match_status
= NT_STATUS_OK
6051 state
.file_existed
= VALID_STAT(fname
->st
);
6052 if (state
.file_existed
) {
6053 state
.id
= vfs_file_id_from_sbuf(conn
, &fname
->st
);
6056 status
= leases_db_parse(&sconn
->client
->global
->client_guid
,
6057 lease_key
, lease_match_parser
, &state
);
6058 if (!NT_STATUS_IS_OK(status
)) {
6060 * Not found or error means okay: We can make the lease pass
6062 return NT_STATUS_OK
;
6064 if (!NT_STATUS_EQUAL(state
.match_status
, NT_STATUS_OPLOCK_NOT_GRANTED
)) {
6066 * Anything but NT_STATUS_OPLOCK_NOT_GRANTED, let the caller
6069 return state
.match_status
;
6072 /* We have to break all existing leases. */
6073 for (i
= 0; i
< state
.num_file_ids
; i
++) {
6074 struct lease_match_break_state break_state
= {
6075 .msg_ctx
= conn
->sconn
->msg_ctx
,
6076 .lease_key
= lease_key
,
6079 if (file_id_equal(&state
.ids
[i
], &state
.id
)) {
6080 /* Don't need to break our own file. */
6084 break_state
.id
= state
.ids
[i
];
6086 status
= share_mode_do_locked_vfs_denied(break_state
.id
,
6089 if (!NT_STATUS_IS_OK(status
)) {
6090 /* Race condition - file already closed. */
6094 if (break_state
.found_lease
) {
6095 *p_version
= break_state
.version
;
6096 *p_epoch
= break_state
.epoch
;
6100 * Ensure we don't grant anything more so we
6103 return NT_STATUS_OPLOCK_NOT_GRANTED
;
6107 * Wrapper around open_file_ntcreate and open_directory
6110 static NTSTATUS
create_file_unixpath(connection_struct
*conn
,
6111 struct smb_request
*req
,
6112 struct files_struct
*dirfsp
,
6113 struct smb_filename
*smb_fname
,
6114 uint32_t access_mask
,
6115 uint32_t share_access
,
6116 uint32_t create_disposition
,
6117 uint32_t create_options
,
6118 uint32_t file_attributes
,
6119 uint32_t oplock_request
,
6120 const struct smb2_lease
*lease
,
6121 uint64_t allocation_size
,
6122 uint32_t private_flags
,
6123 struct security_descriptor
*sd
,
6124 struct ea_list
*ea_list
,
6126 files_struct
**result
,
6129 struct smb2_lease none_lease
;
6130 int info
= FILE_WAS_OPENED
;
6131 files_struct
*base_fsp
= NULL
;
6132 files_struct
*fsp
= NULL
;
6133 bool free_fsp_on_error
= false;
6136 struct smb_filename
*parent_dir_fname
= NULL
;
6137 struct smb_filename
*smb_fname_atname
= NULL
;
6139 DBG_DEBUG("access_mask = 0x%"PRIx32
" "
6140 "file_attributes = 0x%"PRIx32
" "
6141 "share_access = 0x%"PRIx32
" "
6142 "create_disposition = 0x%"PRIx32
" "
6143 "create_options = 0x%"PRIx32
" "
6144 "oplock_request = 0x%"PRIx32
" "
6145 "private_flags = 0x%"PRIx32
" "
6158 smb_fname_str_dbg(smb_fname
));
6160 if (create_options
& FILE_OPEN_BY_FILE_ID
) {
6161 status
= NT_STATUS_NOT_SUPPORTED
;
6165 if (create_options
& NTCREATEX_OPTIONS_INVALID_PARAM_MASK
) {
6166 status
= NT_STATUS_INVALID_PARAMETER
;
6170 if (!(create_options
& FILE_OPEN_REPARSE_POINT
) &&
6171 (smb_fname
->fsp
!= NULL
) && /* new files don't have an fsp */
6172 VALID_STAT(smb_fname
->fsp
->fsp_name
->st
))
6174 mode_t type
= (smb_fname
->fsp
->fsp_name
->st
.st_ex_mode
&
6184 * We should never get this far with a symlink
6185 * "as such". Report as not existing.
6187 status
= NT_STATUS_OBJECT_NAME_NOT_FOUND
;
6190 status
= NT_STATUS_IO_REPARSE_TAG_NOT_HANDLED
;
6196 oplock_request
|= INTERNAL_OPEN_ONLY
;
6199 if (lease
!= NULL
) {
6200 uint16_t epoch
= lease
->lease_epoch
;
6201 uint16_t version
= lease
->lease_version
;
6204 DBG_WARNING("Got lease on internal open\n");
6205 status
= NT_STATUS_INTERNAL_ERROR
;
6209 status
= lease_match(conn
,
6216 if (NT_STATUS_EQUAL(status
, NT_STATUS_OPLOCK_NOT_GRANTED
)) {
6217 /* Dynamic share file. No leases and update epoch... */
6218 none_lease
= *lease
;
6219 none_lease
.lease_state
= SMB2_LEASE_NONE
;
6220 none_lease
.lease_epoch
= epoch
;
6221 none_lease
.lease_version
= version
;
6222 lease
= &none_lease
;
6223 } else if (!NT_STATUS_IS_OK(status
)) {
6228 if ((conn
->fs_capabilities
& FILE_NAMED_STREAMS
)
6229 && (access_mask
& DELETE_ACCESS
)
6230 && !is_named_stream(smb_fname
)) {
6232 * We can't open a file with DELETE access if any of the
6233 * streams is open without FILE_SHARE_DELETE
6235 status
= open_streams_for_delete(conn
, smb_fname
);
6237 if (!NT_STATUS_IS_OK(status
)) {
6242 if (access_mask
& SEC_FLAG_SYSTEM_SECURITY
) {
6245 ok
= security_token_has_privilege(get_current_nttok(conn
),
6248 DBG_DEBUG("open on %s failed - "
6249 "SEC_FLAG_SYSTEM_SECURITY denied.\n",
6250 smb_fname_str_dbg(smb_fname
));
6251 status
= NT_STATUS_PRIVILEGE_NOT_HELD
;
6255 if (conn_using_smb2(conn
->sconn
) &&
6256 (access_mask
== SEC_FLAG_SYSTEM_SECURITY
))
6259 * No other bits set. Windows SMB2 refuses this.
6260 * See smbtorture3 SMB2-SACL test.
6262 * Note this is an SMB2-only behavior,
6263 * smbtorture3 SMB1-SYSTEM-SECURITY already tests
6264 * that SMB1 allows this.
6266 status
= NT_STATUS_ACCESS_DENIED
;
6272 * Files or directories can't be opened DELETE_ON_CLOSE without
6274 * BUG: https://bugzilla.samba.org/show_bug.cgi?id=13358
6276 if ((create_options
& FILE_DELETE_ON_CLOSE
) &&
6277 ((access_mask
& DELETE_ACCESS
) == 0)) {
6278 status
= NT_STATUS_INVALID_PARAMETER
;
6282 if ((conn
->fs_capabilities
& FILE_NAMED_STREAMS
)
6283 && is_named_stream(smb_fname
))
6285 uint32_t base_create_disposition
;
6286 struct smb_filename
*smb_fname_base
= NULL
;
6287 uint32_t base_privflags
;
6289 if (create_options
& FILE_DIRECTORY_FILE
) {
6290 DBG_DEBUG("Can't open a stream as directory\n");
6291 status
= NT_STATUS_NOT_A_DIRECTORY
;
6295 switch (create_disposition
) {
6297 base_create_disposition
= FILE_OPEN
;
6300 base_create_disposition
= FILE_OPEN_IF
;
6304 smb_fname_base
= cp_smb_filename_nostream(
6305 talloc_tos(), smb_fname
);
6307 if (smb_fname_base
== NULL
) {
6308 status
= NT_STATUS_NO_MEMORY
;
6313 * We may be creating the basefile as part of creating the
6314 * stream, so it's legal if the basefile doesn't exist at this
6315 * point, the create_file_unixpath() below will create it. But
6316 * if the basefile exists we want a handle so we can fstat() it.
6319 ret
= vfs_stat(conn
, smb_fname_base
);
6320 if (ret
== -1 && errno
!= ENOENT
) {
6321 status
= map_nt_error_from_unix(errno
);
6322 TALLOC_FREE(smb_fname_base
);
6326 status
= openat_pathref_fsp(conn
->cwd_fsp
,
6328 if (!NT_STATUS_IS_OK(status
)) {
6329 DBG_ERR("open_smb_fname_fsp [%s] failed: %s\n",
6330 smb_fname_str_dbg(smb_fname_base
),
6332 TALLOC_FREE(smb_fname_base
);
6337 * https://bugzilla.samba.org/show_bug.cgi?id=10229
6338 * We need to check if the requested access mask
6339 * could be used to open the underlying file (if
6340 * it existed), as we're passing in zero for the
6341 * access mask to the base filename.
6343 status
= check_base_file_access(smb_fname_base
->fsp
,
6346 if (!NT_STATUS_IS_OK(status
)) {
6347 DEBUG(10, ("Permission check "
6348 "for base %s failed: "
6349 "%s\n", smb_fname
->base_name
,
6350 nt_errstr(status
)));
6351 TALLOC_FREE(smb_fname_base
);
6356 base_privflags
= NTCREATEX_FLAG_STREAM_BASEOPEN
;
6358 /* Open the base file. */
6359 status
= create_file_unixpath(conn
,
6366 | FILE_SHARE_DELETE
,
6367 base_create_disposition
,
6378 TALLOC_FREE(smb_fname_base
);
6380 if (!NT_STATUS_IS_OK(status
)) {
6381 DEBUG(10, ("create_file_unixpath for base %s failed: "
6382 "%s\n", smb_fname
->base_name
,
6383 nt_errstr(status
)));
6388 if (smb_fname
->fsp
!= NULL
) {
6390 fsp
= smb_fname
->fsp
;
6393 * We're about to use smb_fname->fsp for the fresh open.
6395 * Every fsp passed in via smb_fname->fsp already
6396 * holds a fsp->fsp_name. If it is already this
6397 * fsp->fsp_name that we got passed in as our input
6398 * argument smb_fname, these two are assumed to have
6399 * the same lifetime: Every fsp hangs of "conn", and
6400 * fsp->fsp_name is its talloc child.
6403 if (smb_fname
!= smb_fname
->fsp
->fsp_name
) {
6405 * "smb_fname" is temporary in this case, but
6406 * the destructor of smb_fname would also tear
6407 * down the fsp we're about to use. Unlink
6408 * them from each other.
6410 smb_fname_fsp_unlink(smb_fname
);
6415 free_fsp_on_error
= true;
6418 status
= fsp_bind_smb(fsp
, req
);
6419 if (!NT_STATUS_IS_OK(status
)) {
6423 if (fsp_is_alternate_stream(fsp
)) {
6424 struct files_struct
*tmp_base_fsp
= fsp
->base_fsp
;
6426 fsp_set_base_fsp(fsp
, NULL
);
6428 fd_close(tmp_base_fsp
);
6429 file_free(NULL
, tmp_base_fsp
);
6433 * No fsp passed in that we can use, create one
6435 status
= file_new(req
, conn
, &fsp
);
6436 if(!NT_STATUS_IS_OK(status
)) {
6439 free_fsp_on_error
= true;
6441 status
= fsp_set_smb_fname(fsp
, smb_fname
);
6442 if (!NT_STATUS_IS_OK(status
)) {
6447 SMB_ASSERT(fsp
->fsp_name
->fsp
!= NULL
);
6448 SMB_ASSERT(fsp
->fsp_name
->fsp
== fsp
);
6452 * We're opening the stream element of a
6453 * base_fsp we already opened. Set up the
6456 fsp_set_base_fsp(fsp
, base_fsp
);
6459 if (dirfsp
!= NULL
) {
6460 status
= SMB_VFS_PARENT_PATHNAME(
6466 if (!NT_STATUS_IS_OK(status
)) {
6471 * Get a pathref on the parent. We can re-use this for
6472 * multiple calls to check parent ACLs etc. to avoid
6475 status
= parent_pathref(talloc_tos(),
6480 if (!NT_STATUS_IS_OK(status
)) {
6484 dirfsp
= parent_dir_fname
->fsp
;
6485 status
= fsp_set_smb_fname(dirfsp
, parent_dir_fname
);
6486 if (!NT_STATUS_IS_OK(status
)) {
6492 * If it's a request for a directory open, deal with it separately.
6495 if (create_options
& FILE_DIRECTORY_FILE
) {
6497 if (create_options
& FILE_NON_DIRECTORY_FILE
) {
6498 status
= NT_STATUS_INVALID_PARAMETER
;
6502 /* Can't open a temp directory. IFS kit test. */
6503 if (!(file_attributes
& FILE_FLAG_POSIX_SEMANTICS
) &&
6504 (file_attributes
& FILE_ATTRIBUTE_TEMPORARY
)) {
6505 status
= NT_STATUS_INVALID_PARAMETER
;
6510 * We will get a create directory here if the Win32
6511 * app specified a security descriptor in the
6512 * CreateDirectory() call.
6515 status
= open_directory(conn
,
6532 * Ordinary file case.
6535 if (allocation_size
) {
6536 fsp
->initial_allocation_size
= smb_roundup(fsp
->conn
,
6540 status
= open_file_ntcreate(conn
,
6554 if (NT_STATUS_EQUAL(status
, NT_STATUS_FILE_IS_A_DIRECTORY
)) {
6556 /* A stream open never opens a directory */
6559 status
= NT_STATUS_FILE_IS_A_DIRECTORY
;
6564 * Fail the open if it was explicitly a non-directory
6568 if (create_options
& FILE_NON_DIRECTORY_FILE
) {
6569 status
= NT_STATUS_FILE_IS_A_DIRECTORY
;
6573 status
= open_directory(conn
,
6590 if (!NT_STATUS_IS_OK(status
)) {
6594 fsp
->fsp_flags
.is_fsa
= true;
6596 if ((ea_list
!= NULL
) &&
6597 ((info
== FILE_WAS_CREATED
) || (info
== FILE_WAS_OVERWRITTEN
))) {
6598 status
= set_ea(conn
, fsp
, ea_list
);
6599 if (!NT_STATUS_IS_OK(status
)) {
6604 if (!fsp
->fsp_flags
.is_directory
&&
6605 S_ISDIR(fsp
->fsp_name
->st
.st_ex_mode
))
6607 status
= NT_STATUS_ACCESS_DENIED
;
6611 /* Save the requested allocation size. */
6612 if ((info
== FILE_WAS_CREATED
) || (info
== FILE_WAS_OVERWRITTEN
)) {
6613 if ((allocation_size
> (uint64_t)fsp
->fsp_name
->st
.st_ex_size
)
6614 && !(fsp
->fsp_flags
.is_directory
))
6616 fsp
->initial_allocation_size
= smb_roundup(
6617 fsp
->conn
, allocation_size
);
6618 if (vfs_allocate_file_space(
6619 fsp
, fsp
->initial_allocation_size
) == -1) {
6620 status
= NT_STATUS_DISK_FULL
;
6624 fsp
->initial_allocation_size
= smb_roundup(
6625 fsp
->conn
, (uint64_t)fsp
->fsp_name
->st
.st_ex_size
);
6628 fsp
->initial_allocation_size
= 0;
6631 if ((info
== FILE_WAS_CREATED
) &&
6632 !S_ISDIR(fsp
->fsp_name
->st
.st_ex_mode
) &&
6633 lp_nt_acl_support(SNUM(conn
)) &&
6634 !fsp_is_alternate_stream(fsp
)) {
6635 status
= apply_new_nt_acl(dirfsp
, fsp
, sd
);
6636 if (!NT_STATUS_IS_OK(status
)) {
6637 DBG_WARNING("apply_new_nt_acl(): failed for %s with %s\n",
6638 fsp_str_dbg(fsp
), nt_errstr(status
));
6643 if ((conn
->fs_capabilities
& FILE_FILE_COMPRESSION
)
6644 && (create_options
& FILE_NO_COMPRESSION
)
6645 && (info
== FILE_WAS_CREATED
)) {
6646 status
= SMB_VFS_SET_COMPRESSION(conn
, fsp
, fsp
,
6647 COMPRESSION_FORMAT_NONE
);
6648 if (!NT_STATUS_IS_OK(status
)) {
6649 DEBUG(1, ("failed to disable compression: %s\n",
6650 nt_errstr(status
)));
6654 DEBUG(10, ("create_file_unixpath: info=%d\n", info
));
6657 if (pinfo
!= NULL
) {
6661 smb_fname
->st
= fsp
->fsp_name
->st
;
6663 TALLOC_FREE(parent_dir_fname
);
6665 return NT_STATUS_OK
;
6668 DEBUG(10, ("create_file_unixpath: %s\n", nt_errstr(status
)));
6672 * The close_file below will close
6676 close_file_smb(req
, fsp
, ERROR_CLOSE
);
6677 if (free_fsp_on_error
) {
6678 file_free(req
, fsp
);
6682 if (base_fsp
!= NULL
) {
6683 close_file_free(req
, &base_fsp
, ERROR_CLOSE
);
6686 TALLOC_FREE(parent_dir_fname
);
6691 static NTSTATUS
check_posix_create_context(connection_struct
*conn
,
6692 struct smb_request
*req
,
6693 const struct smb2_create_blobs
*in_context_blobs
,
6694 uint32_t create_options
,
6695 uint32_t *file_attributes
)
6697 uint32_t wire_mode_bits
= 0;
6699 mode_t mode_bits
= 0;
6700 SMB_STRUCT_STAT sbuf
= { 0 };
6701 struct smb2_create_blob
*posx
= NULL
;
6703 if (req
== NULL
|| !req
->posix_pathnames
) {
6704 return NT_STATUS_OK
;
6707 posx
= smb2_create_blob_find(
6708 in_context_blobs
, SMB2_CREATE_TAG_POSIX
);
6710 return NT_STATUS_OK
;
6713 if (posx
->data
.length
!= 4) {
6714 return NT_STATUS_INVALID_PARAMETER
;
6717 wire_mode_bits
= IVAL(posx
->data
.data
, 0);
6718 status
= unix_perms_from_wire(conn
,
6722 if (!NT_STATUS_IS_OK(status
)) {
6725 if (create_options
& FILE_DIRECTORY_FILE
) {
6726 mode_bits
= apply_conf_dir_mask(conn
, mode_bits
);
6728 mode_bits
= apply_conf_file_mask(conn
, mode_bits
);
6731 * Remove type info from mode, leaving only the
6732 * permissions and setuid/gid bits.
6734 mode_bits
&= ~S_IFMT
;
6736 *file_attributes
= (FILE_FLAG_POSIX_SEMANTICS
| mode_bits
);
6738 return NT_STATUS_OK
;
6741 NTSTATUS
create_file_default(connection_struct
*conn
,
6742 struct smb_request
*req
,
6743 struct files_struct
*dirfsp
,
6744 struct smb_filename
*smb_fname
,
6745 uint32_t access_mask
,
6746 uint32_t share_access
,
6747 uint32_t create_disposition
,
6748 uint32_t create_options
,
6749 uint32_t file_attributes
,
6750 uint32_t oplock_request
,
6751 const struct smb2_lease
*lease
,
6752 uint64_t allocation_size
,
6753 uint32_t private_flags
,
6754 struct security_descriptor
*sd
,
6755 struct ea_list
*ea_list
,
6756 files_struct
**result
,
6758 const struct smb2_create_blobs
*in_context_blobs
,
6759 struct smb2_create_blobs
*out_context_blobs
)
6761 int info
= FILE_WAS_OPENED
;
6762 files_struct
*fsp
= NULL
;
6764 bool stream_name
= false;
6766 DBG_DEBUG("access_mask = 0x%" PRIu32
6767 " file_attributes = 0x%" PRIu32
6768 " share_access = 0x%" PRIu32
6769 " create_disposition = 0x%" PRIu32
6770 " create_options = 0x%" PRIu32
6771 " oplock_request = 0x%" PRIu32
6772 " private_flags = 0x%" PRIu32
6773 " ea_list = %p, sd = %p, fname = %s\n",
6783 smb_fname_str_dbg(smb_fname
));
6787 * Remember the absolute time of the original request
6788 * with this mid. We'll use it later to see if this
6791 get_deferred_open_message_state(req
, &req
->request_time
, NULL
);
6795 * Check to see if this is a mac fork of some kind.
6798 stream_name
= is_ntfs_stream_smb_fname(smb_fname
);
6800 enum FAKE_FILE_TYPE fake_file_type
;
6802 fake_file_type
= is_fake_file(smb_fname
);
6804 if (req
!= NULL
&& fake_file_type
!= FAKE_FILE_TYPE_NONE
) {
6807 * Here we go! support for changing the disk quotas
6810 * We need to fake up to open this MAGIC QUOTA file
6811 * and return a valid FID.
6813 * w2k close this file directly after opening xp
6814 * also tries a QUERY_FILE_INFO on the file and then
6817 status
= open_fake_file(req
, conn
, req
->vuid
,
6818 fake_file_type
, smb_fname
,
6820 if (!NT_STATUS_IS_OK(status
)) {
6824 ZERO_STRUCT(smb_fname
->st
);
6828 if (!(conn
->fs_capabilities
& FILE_NAMED_STREAMS
)) {
6829 status
= NT_STATUS_OBJECT_NAME_INVALID
;
6834 if (is_ntfs_default_stream_smb_fname(smb_fname
)) {
6836 /* We have to handle this error here. */
6837 if (create_options
& FILE_DIRECTORY_FILE
) {
6838 status
= NT_STATUS_NOT_A_DIRECTORY
;
6841 ret
= vfs_stat(conn
, smb_fname
);
6842 if (ret
== 0 && VALID_STAT_OF_DIR(smb_fname
->st
)) {
6843 status
= NT_STATUS_FILE_IS_A_DIRECTORY
;
6848 status
= check_posix_create_context(conn
,
6853 if (!NT_STATUS_IS_OK(status
)) {
6857 status
= create_file_unixpath(conn
,
6874 if (!NT_STATUS_IS_OK(status
)) {
6879 DEBUG(10, ("create_file: info=%d\n", info
));
6882 if (pinfo
!= NULL
) {
6885 return NT_STATUS_OK
;
6888 DEBUG(10, ("create_file: %s\n", nt_errstr(status
)));
6891 close_file_free(req
, &fsp
, ERROR_CLOSE
);