tests: Check symlinks are readable as reparse points
[samba4-gss.git] / source3 / smbd / open.c
blob6554467379f3b9021ad7f601d71e9ce2fac6cd3b
1 /*
2 Unix SMB/CIFS implementation.
3 file opening and share modes
4 Copyright (C) Andrew Tridgell 1992-1998
5 Copyright (C) Jeremy Allison 2001-2004
6 Copyright (C) Volker Lendecke 2005
7 Copyright (C) Ralph Boehme 2017
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
23 #include "includes.h"
24 #include "system/filesys.h"
25 #include "lib/util/server_id.h"
26 #include "printing.h"
27 #include "locking/share_mode_lock.h"
28 #include "smbd/smbd.h"
29 #include "smbd/globals.h"
30 #include "fake_file.h"
31 #include "../libcli/security/security.h"
32 #include "../librpc/gen_ndr/ndr_security.h"
33 #include "../librpc/gen_ndr/ndr_open_files.h"
34 #include "../librpc/gen_ndr/idmap.h"
35 #include "../librpc/gen_ndr/ioctl.h"
36 #include "passdb/lookup_sid.h"
37 #include "auth.h"
38 #include "serverid.h"
39 #include "messages.h"
40 #include "source3/lib/dbwrap/dbwrap_watch.h"
41 #include "source3/lib/server_id_watch.h"
42 #include "locking/leases_db.h"
43 #include "librpc/gen_ndr/ndr_leases_db.h"
44 #include "lib/util/time_basic.h"
45 #include "source3/smbd/dir.h"
47 #if defined(HAVE_LINUX_MAGIC_H)
48 #include <linux/magic.h>
49 #endif
51 static NTSTATUS inherit_new_acl(files_struct *dirfsp, files_struct *fsp);
53 extern const struct generic_mapping file_generic_mapping;
55 struct deferred_open_record {
56 struct smbXsrv_connection *xconn;
57 uint64_t mid;
59 bool async_open;
62 * Timer for async opens, needed because they don't use a watch on
63 * a locking.tdb record. This is currently only used for real async
64 * opens and just terminates smbd if the async open times out.
66 struct tevent_timer *te;
69 * For the samba kernel oplock case we use both a timeout and
70 * a watch on locking.tdb. This way in case it's smbd holding
71 * the kernel oplock we get directly notified for the retry
72 * once the kernel oplock is properly broken. Store the req
73 * here so that it can be timely discarded once the timer
74 * above fires.
76 struct tevent_req *watch_req;
79 /****************************************************************************
80 If the requester wanted DELETE_ACCESS and was rejected because
81 the file ACL didn't include DELETE_ACCESS, see if the parent ACL
82 overrides this.
83 ****************************************************************************/
85 static bool parent_override_delete(connection_struct *conn,
86 struct files_struct *dirfsp,
87 const struct smb_filename *smb_fname,
88 uint32_t access_mask,
89 uint32_t rejected_mask)
91 if ((access_mask & DELETE_ACCESS) && (rejected_mask & DELETE_ACCESS)) {
92 bool ok;
93 ok = can_delete_file_in_directory(conn, dirfsp, smb_fname);
94 return ok;
97 return false;
100 /****************************************************************************
101 Check if we have open rights.
102 ****************************************************************************/
104 static NTSTATUS smbd_check_access_rights_fname(
105 struct connection_struct *conn,
106 const struct smb_filename *smb_fname,
107 bool use_privs,
108 uint32_t access_mask,
109 uint32_t do_not_check_mask)
111 uint32_t rejected_share_access;
112 uint32_t effective_access;
114 rejected_share_access = access_mask & ~(conn->share_access);
116 if (rejected_share_access) {
117 DBG_DEBUG("rejected share access 0x%"PRIx32" on "
118 "%s (0x%"PRIx32")\n",
119 access_mask,
120 smb_fname_str_dbg(smb_fname),
121 rejected_share_access);
122 return NT_STATUS_ACCESS_DENIED;
125 effective_access = access_mask & ~do_not_check_mask;
126 if (effective_access == 0) {
127 DBG_DEBUG("do_not_check_mask override on %s. Granting 0x%x for free.\n",
128 smb_fname_str_dbg(smb_fname),
129 (unsigned int)access_mask);
130 return NT_STATUS_OK;
133 if (!use_privs && get_current_uid(conn) == (uid_t)0) {
134 /* I'm sorry sir, I didn't know you were root... */
135 DBG_DEBUG("root override on %s. Granting 0x%x\n",
136 smb_fname_str_dbg(smb_fname),
137 (unsigned int)access_mask);
138 return NT_STATUS_OK;
141 if ((access_mask & DELETE_ACCESS) &&
142 !lp_acl_check_permissions(SNUM(conn)))
144 DBG_DEBUG("Not checking ACL on DELETE_ACCESS on file %s. "
145 "Granting 0x%"PRIx32"\n",
146 smb_fname_str_dbg(smb_fname),
147 access_mask);
148 return NT_STATUS_OK;
151 if (access_mask == DELETE_ACCESS &&
152 VALID_STAT(smb_fname->st) &&
153 S_ISLNK(smb_fname->st.st_ex_mode))
155 /* We can always delete a symlink. */
156 DBG_DEBUG("Not checking ACL on DELETE_ACCESS on symlink %s.\n",
157 smb_fname_str_dbg(smb_fname));
158 return NT_STATUS_OK;
161 return NT_STATUS_MORE_PROCESSING_REQUIRED;
164 static NTSTATUS smbd_check_access_rights_sd(
165 struct connection_struct *conn,
166 struct files_struct *dirfsp,
167 const struct smb_filename *smb_fname,
168 struct security_descriptor *sd,
169 bool use_privs,
170 uint32_t access_mask,
171 uint32_t do_not_check_mask)
173 uint32_t rejected_mask = access_mask;
174 NTSTATUS status;
176 if (sd == NULL) {
177 goto access_denied;
180 status = se_file_access_check(sd,
181 get_current_nttok(conn),
182 use_privs,
183 (access_mask & ~do_not_check_mask),
184 &rejected_mask);
186 DBG_DEBUG("File [%s] requesting [0x%"PRIx32"] "
187 "returning [0x%"PRIx32"] (%s)\n",
188 smb_fname_str_dbg(smb_fname),
189 access_mask,
190 rejected_mask,
191 nt_errstr(status));
193 if (!NT_STATUS_IS_OK(status)) {
194 if (DEBUGLEVEL >= 10) {
195 DBG_DEBUG("acl for %s is:\n",
196 smb_fname_str_dbg(smb_fname));
197 NDR_PRINT_DEBUG(security_descriptor, sd);
201 TALLOC_FREE(sd);
203 if (NT_STATUS_IS_OK(status) ||
204 !NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED))
206 return status;
209 /* Here we know status == NT_STATUS_ACCESS_DENIED. */
211 access_denied:
213 if ((access_mask & FILE_WRITE_ATTRIBUTES) &&
214 (rejected_mask & FILE_WRITE_ATTRIBUTES) &&
215 !lp_store_dos_attributes(SNUM(conn)) &&
216 (lp_map_readonly(SNUM(conn)) ||
217 lp_map_archive(SNUM(conn)) ||
218 lp_map_hidden(SNUM(conn)) ||
219 lp_map_system(SNUM(conn))))
221 rejected_mask &= ~FILE_WRITE_ATTRIBUTES;
223 DBG_DEBUG("overrode FILE_WRITE_ATTRIBUTES on file %s\n",
224 smb_fname_str_dbg(smb_fname));
227 if (parent_override_delete(conn,
228 dirfsp,
229 smb_fname,
230 access_mask,
231 rejected_mask))
234 * Were we trying to do an open for delete and didn't get DELETE
235 * access. Check if the directory allows DELETE_CHILD.
236 * See here:
237 * http://blogs.msdn.com/oldnewthing/archive/2004/06/04/148426.aspx
238 * for details.
241 rejected_mask &= ~DELETE_ACCESS;
243 DBG_DEBUG("Overrode DELETE_ACCESS on file %s\n",
244 smb_fname_str_dbg(smb_fname));
247 if (rejected_mask != 0) {
248 return NT_STATUS_ACCESS_DENIED;
250 return NT_STATUS_OK;
253 NTSTATUS smbd_check_access_rights_fsp(struct files_struct *dirfsp,
254 struct files_struct *fsp,
255 bool use_privs,
256 uint32_t access_mask)
258 struct security_descriptor *sd = NULL;
259 uint32_t do_not_check_mask = 0;
260 NTSTATUS status;
262 /* Cope with fake/printer fsp's. */
263 if (fsp->fake_file_handle != NULL || fsp->print_file != NULL) {
264 if ((fsp->access_mask & access_mask) != access_mask) {
265 return NT_STATUS_ACCESS_DENIED;
267 return NT_STATUS_OK;
270 if (fsp_get_pathref_fd(fsp) == -1) {
272 * This is a POSIX open on a symlink. For the pathname
273 * version of this function we used to return the st_mode
274 * bits turned into an NT ACL. For a symlink the mode bits
275 * are always rwxrwxrwx which means the pathname version always
276 * returned NT_STATUS_OK for a symlink. For the handle reference
277 * to a symlink use the handle access bits.
279 if ((fsp->access_mask & access_mask) != access_mask) {
280 return NT_STATUS_ACCESS_DENIED;
282 return NT_STATUS_OK;
286 * If we can access the path to this file, by
287 * default we have FILE_READ_ATTRIBUTES from the
288 * containing directory. See the section:
289 * "Algorithm to Check Access to an Existing File"
290 * in MS-FSA.pdf.
292 * se_file_access_check() also takes care of
293 * owner WRITE_DAC and READ_CONTROL.
295 do_not_check_mask = FILE_READ_ATTRIBUTES;
298 * Samba 3.6 and earlier granted execute access even
299 * if the ACL did not contain execute rights.
300 * Samba 4.0 is more correct and checks it.
301 * The compatibility mode allows one to skip this check
302 * to smoothen upgrades.
304 if (lp_acl_allow_execute_always(SNUM(fsp->conn))) {
305 do_not_check_mask |= FILE_EXECUTE;
308 status = smbd_check_access_rights_fname(fsp->conn,
309 fsp->fsp_name,
310 use_privs,
311 access_mask,
312 do_not_check_mask);
313 if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
314 return status;
317 status = SMB_VFS_FGET_NT_ACL(metadata_fsp(fsp),
318 (SECINFO_OWNER |
319 SECINFO_GROUP |
320 SECINFO_DACL),
321 talloc_tos(),
322 &sd);
323 if (!NT_STATUS_IS_OK(status)) {
324 DBG_DEBUG("Could not get acl on %s: %s\n",
325 fsp_str_dbg(fsp),
326 nt_errstr(status));
327 return status;
330 return smbd_check_access_rights_sd(fsp->conn,
331 dirfsp,
332 fsp->fsp_name,
334 use_privs,
335 access_mask,
336 do_not_check_mask);
340 * Given an fsp that represents a parent directory,
341 * check if the requested access can be granted.
343 NTSTATUS check_parent_access_fsp(struct files_struct *fsp,
344 uint32_t access_mask)
346 NTSTATUS status;
347 struct security_descriptor *parent_sd = NULL;
348 uint32_t access_granted = 0;
349 uint32_t name_hash;
350 bool delete_on_close_set;
351 TALLOC_CTX *frame = talloc_stackframe();
353 if (get_current_uid(fsp->conn) == (uid_t)0) {
354 /* I'm sorry sir, I didn't know you were root... */
355 DBG_DEBUG("root override on %s. Granting 0x%x\n",
356 fsp_str_dbg(fsp),
357 (unsigned int)access_mask);
358 status = NT_STATUS_OK;
359 goto out;
362 status = SMB_VFS_FGET_NT_ACL(fsp,
363 (SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL),
364 frame,
365 &parent_sd);
367 if (!NT_STATUS_IS_OK(status)) {
368 DBG_INFO("SMB_VFS_FGET_NT_ACL failed for "
369 "%s with error %s\n",
370 fsp_str_dbg(fsp),
371 nt_errstr(status));
372 goto out;
376 * If we can access the path to this file, by
377 * default we have FILE_READ_ATTRIBUTES from the
378 * containing directory. See the section:
379 * "Algorithm to Check Access to an Existing File"
380 * in MS-FSA.pdf.
382 * se_file_access_check() also takes care of
383 * owner WRITE_DAC and READ_CONTROL.
385 status = se_file_access_check(parent_sd,
386 get_current_nttok(fsp->conn),
387 false,
388 (access_mask & ~FILE_READ_ATTRIBUTES),
389 &access_granted);
390 if(!NT_STATUS_IS_OK(status)) {
391 DBG_INFO("access check "
392 "on directory %s for mask 0x%x returned (0x%x) %s\n",
393 fsp_str_dbg(fsp),
394 access_mask,
395 access_granted,
396 nt_errstr(status));
397 goto out;
400 if (!(access_mask & (SEC_DIR_ADD_FILE | SEC_DIR_ADD_SUBDIR))) {
401 status = NT_STATUS_OK;
402 goto out;
404 if (!lp_check_parent_directory_delete_on_close(SNUM(fsp->conn))) {
405 status = NT_STATUS_OK;
406 goto out;
409 /* Check if the directory has delete-on-close set */
410 status = file_name_hash(fsp->conn,
411 fsp->fsp_name->base_name,
412 &name_hash);
413 if (!NT_STATUS_IS_OK(status)) {
414 goto out;
417 get_file_infos(fsp->file_id, name_hash, &delete_on_close_set, NULL);
418 if (delete_on_close_set) {
419 status = NT_STATUS_DELETE_PENDING;
420 goto out;
423 status = NT_STATUS_OK;
425 out:
426 TALLOC_FREE(frame);
427 return status;
430 /****************************************************************************
431 Ensure when opening a base file for a stream open that we have permissions
432 to do so given the access mask on the base file.
433 ****************************************************************************/
435 static NTSTATUS check_base_file_access(struct files_struct *fsp,
436 uint32_t access_mask)
438 NTSTATUS status;
440 status = smbd_calculate_access_mask_fsp(fsp->conn->cwd_fsp,
441 fsp,
442 false,
443 access_mask,
444 &access_mask);
445 if (!NT_STATUS_IS_OK(status)) {
446 DEBUG(10, ("smbd_calculate_access_mask "
447 "on file %s returned %s\n",
448 fsp_str_dbg(fsp),
449 nt_errstr(status)));
450 return status;
453 if (access_mask & (FILE_WRITE_DATA|FILE_APPEND_DATA)) {
454 uint32_t dosattrs;
455 if (!CAN_WRITE(fsp->conn)) {
456 return NT_STATUS_ACCESS_DENIED;
458 dosattrs = fdos_mode(fsp);
459 if (dosattrs & FILE_ATTRIBUTE_READONLY) {
460 return NT_STATUS_ACCESS_DENIED;
464 return smbd_check_access_rights_fsp(fsp->conn->cwd_fsp,
465 fsp,
466 false,
467 access_mask);
470 /****************************************************************************
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,
476 files_struct *fsp,
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;
489 int fd;
491 SMB_ASSERT(fsp_is_stream == smb_fname_is_stream);
493 if (fsp_is_stream) {
494 fd = SMB_VFS_OPENAT(
495 conn,
496 NULL, /* stream open is relative to fsp->base_fsp */
497 smb_fname,
498 fsp,
499 &how);
500 if (fd == -1) {
501 status = map_nt_error_from_unix(errno);
503 goto done;
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);
514 if (fd >= 0) {
515 fsp_set_fd(fsp, fd);
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);
522 return NT_STATUS_OK;
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.
532 SMB_VFS_CLOSE(fsp);
533 fsp_set_fd(fsp, -1);
534 fd = -1;
538 if (name_in[0] == '/') {
540 * filename_convert_dirfsp can't deal with absolute
541 * paths, make this relative to "/"
543 name_in += 1;
544 status = open_rootdir_pathref_fsp(conn, &root_fsp);
545 if (!NT_STATUS_IS_OK(status)) {
546 return status;
548 dirfsp = root_fsp;
551 if (ISDOT(name_in)) {
553 * filename_convert_dirfsp does not like ".", use ""
555 name_in += 1;
558 status = filename_convert_dirfsp_rel(
559 talloc_tos(),
560 conn,
561 discard_const_p(struct files_struct, dirfsp),
562 name_in,
563 UCF_POSIX_PATHNAMES, /* no case insensitive search */
564 smb_fname->twrp,
565 &dirfsp_conv,
566 &smb_fname_conv,
567 &smb_fname_rel);
569 dirfsp = NULL;
570 if (root_fsp != NULL) {
571 fd_close(root_fsp);
572 file_free(NULL, root_fsp);
573 root_fsp = NULL;
576 if (!NT_STATUS_IS_OK(status)) {
577 DBG_DEBUG("filename_convert_dirfsp_rel returned %s\n",
578 nt_errstr(status));
579 return status;
582 fd = SMB_VFS_OPENAT(conn, dirfsp_conv, smb_fname_rel, fsp, &how);
584 if (fd == -1) {
585 status = map_nt_error_from_unix(errno);
588 fd_close(dirfsp_conv);
589 file_free(NULL, dirfsp_conv);
590 dirfsp_conv = NULL;
591 TALLOC_FREE(smb_fname_conv);
593 done:
594 fsp_set_fd(fsp, fd); /* This preserves errno */
596 if (fd == -1) {
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 "
603 "open files = %d\n",
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),
611 how.flags,
612 (int)how.mode,
613 fsp_get_pathref_fd(fsp),
614 nt_errstr(status));
615 return status;
616 } else {
617 status = vfs_stat_fsp(fsp);
618 if (!NT_STATUS_IS_OK(status)) {
619 DBG_DEBUG("vfs_stat_fsp failed: %s\n",
620 nt_errstr(status));
621 fd_close(fsp);
622 return status;
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),
631 how.flags,
632 (int)how.mode,
633 fsp_get_pathref_fd(fsp));
635 return status;
638 /****************************************************************************
639 Close the file associated with a fsp.
640 ****************************************************************************/
642 NTSTATUS fd_close(files_struct *fsp)
644 NTSTATUS stat_status = NT_STATUS_OK;
645 int ret;
647 if (fsp == fsp->conn->cwd_fsp) {
648 return NT_STATUS_OK;
651 if (fsp->fsp_flags.fstat_before_close) {
653 * capture status, if failure
654 * continue close processing
655 * and return status
657 stat_status = vfs_stat_fsp(fsp);
660 if (fsp->dptr) {
661 dptr_CloseDir(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.
668 return NT_STATUS_OK;
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);
675 fsp_set_fd(fsp, -1);
676 if (ret == -1) {
677 return map_nt_error_from_unix(errno);
679 return stat_status;
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)
690 int ret;
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",
695 fsp_str_dbg(fsp),
696 (unsigned int)fsp->fsp_name->st.st_ex_uid);
697 return;
700 become_root();
701 ret = SMB_VFS_FCHOWN(fsp,
702 parent_fsp->fsp_name->st.st_ex_uid,
703 (gid_t)-1);
704 unbecome_root();
705 if (ret == -1) {
706 DBG_ERR("failed to fchown "
707 "file %s to parent directory uid %u. Error "
708 "was %s\n",
709 fsp_str_dbg(fsp),
710 (unsigned int)parent_fsp->fsp_name->st.st_ex_uid,
711 strerror(errno));
712 } else {
713 DBG_DEBUG("changed new file %s to "
714 "parent directory uid %u.\n",
715 fsp_str_dbg(fsp),
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)
726 NTSTATUS status;
727 int ret;
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",
732 fsp_str_dbg(fsp),
733 (unsigned int)fsp->fsp_name->st.st_ex_uid);
734 return NT_STATUS_OK;
737 become_root();
738 ret = SMB_VFS_FCHOWN(fsp,
739 parent_fsp->fsp_name->st.st_ex_uid,
740 (gid_t)-1);
741 unbecome_root();
742 if (ret == -1) {
743 status = map_nt_error_from_unix(errno);
744 DBG_ERR("failed to chown "
745 "directory %s to parent directory uid %u. "
746 "Error was %s\n",
747 fsp_str_dbg(fsp),
748 (unsigned int)parent_fsp->fsp_name->st.st_ex_uid,
749 nt_errstr(status));
750 return status;
753 DBG_DEBUG("changed ownership of new "
754 "directory %s to parent directory uid %u.\n",
755 fsp_str_dbg(fsp),
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;
761 return NT_STATUS_OK;
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,
771 files_struct *fsp,
772 const struct vfs_open_how *_how,
773 bool *file_created)
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;
786 return status;
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);
801 return 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
810 * O_CREAT|O_EXCL.
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
818 * giving up.
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.
825 if (file_existed) {
826 how.flags = _how->flags & ~(O_CREAT);
827 retry_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
828 } else {
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;
836 return NT_STATUS_OK;
838 if (NT_STATUS_EQUAL(status, retry_status)) {
840 file_existed = !file_existed;
842 DBG_DEBUG("File %s %s. Retry.\n",
843 fsp_str_dbg(fsp),
844 file_existed ? "existed" : "did not exist");
846 if (file_existed) {
847 how.flags = _how->flags & ~(O_CREAT);
848 } else {
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);
856 return status;
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)
865 NTSTATUS status;
866 int old_fd;
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;
876 int new_fd;
878 if (S_ISLNK(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,
888 fsp->conn->cwd_fsp,
889 &proc_fname,
890 fsp,
891 how);
892 if (new_fd == -1) {
893 #if defined(HAVE_FSTATFS) && defined(HAVE_LINUX_MAGIC_H)
894 if (S_ISDIR(fsp->fsp_name->st.st_ex_mode) &&
895 (errno == ENOENT)) {
896 struct statfs sbuf = {};
897 int ret = fstatfs(old_fd, &sbuf);
898 if (ret == -1) {
899 DBG_ERR("fstatfs failed: %s\n",
900 strerror(errno));
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.
908 goto namebased_open;
910 /* restore ENOENT if changed in the meantime */
911 errno = ENOENT;
913 #endif
914 status = map_nt_error_from_unix(errno);
915 fd_close(fsp);
916 return status;
919 status = fd_close(fsp);
920 if (!NT_STATUS_IS_OK(status)) {
921 return status;
924 fsp_set_fd(fsp, new_fd);
925 return NT_STATUS_OK;
928 #if defined(HAVE_FSTATFS) && defined(HAVE_LINUX_MAGIC_H)
929 namebased_open:
930 #endif
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)) {
937 return status;
940 fsp->fsp_flags.is_pathref = false;
942 status = fd_open_atomic(dirfsp, smb_fname, fsp, how, p_file_created);
943 return status;
946 /****************************************************************************
947 Open a file.
948 ****************************************************************************/
950 static NTSTATUS open_file(
951 struct smb_request *req,
952 struct files_struct *dirfsp,
953 struct smb_filename *smb_fname_atname,
954 files_struct *fsp,
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 =
967 FILE_READ_DATA |
968 FILE_WRITE_DATA |
969 FILE_APPEND_DATA |
970 FILE_EXECUTE |
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.
1011 * JRA.
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)) {
1032 open_fd = true;
1035 if (open_fd) {
1036 int ret;
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
1042 * open flags. JRA.
1045 if (file_existed && S_ISFIFO(smb_fname->st.st_ex_mode)) {
1046 how.flags |= O_NONBLOCK;
1048 #endif
1050 if (!posix_open) {
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. */
1071 if (file_existed) {
1072 status = smbd_check_access_rights_fsp(
1073 dirfsp,
1074 fsp,
1075 false,
1076 open_access_mask);
1078 if (!NT_STATUS_IS_OK(status)) {
1079 DBG_DEBUG("smbd_check_access_rights_fsp"
1080 " on file %s returned %s\n",
1081 fsp_str_dbg(fsp),
1082 nt_errstr(status));
1085 if (!NT_STATUS_IS_OK(status) &&
1086 !NT_STATUS_EQUAL(status,
1087 NT_STATUS_OBJECT_NAME_NOT_FOUND))
1089 return status;
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(
1111 dirfsp,
1112 SEC_DIR_ADD_FILE);
1113 if (!NT_STATUS_IS_OK(status)) {
1114 DBG_DEBUG("check_parent_access_fsp on "
1115 "directory %s for file %s "
1116 "returned %s\n",
1117 smb_fname_str_dbg(
1118 dirfsp->fsp_name),
1119 smb_fname_str_dbg(smb_fname),
1120 nt_errstr(status));
1121 return status;
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,
1132 smb_fname_atname,
1133 fsp,
1134 &how,
1135 p_file_created);
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
1142 * equivalent.
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) "
1148 "(flags=%d)\n",
1149 smb_fname_str_dbg(smb_fname),
1150 nt_errstr(status),
1151 _how->flags,
1152 how.flags);
1153 return status;
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
1163 * does not happen.
1165 ret = vfs_set_blocking(fsp, true);
1166 if (ret == -1) {
1167 status = map_nt_error_from_unix(errno);
1168 DBG_WARNING("Could not set fd to blocking: "
1169 "%s\n", strerror(errno));
1170 fd_close(fsp);
1171 return status;
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,
1186 dirfsp,
1187 smb_fname,
1188 how.mode);
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;
1198 if (need_re_stat) {
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 "
1205 "file %s (%s)\n",
1206 smb_fname_str_dbg(smb_fname),
1207 nt_errstr(status));
1208 fd_close(fsp);
1209 return status;
1213 } else {
1214 if (!file_existed) {
1215 /* File must exist for a stat open. */
1216 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1219 if (!fsp->fsp_flags.is_pathref) {
1221 * There is only one legit case where end up here:
1222 * openat_pathref_fsp() failed to open a symlink, so the
1223 * fsp was created by fsp_new() which doesn't set
1224 * is_pathref. Other than that, we should always have a
1225 * pathref fsp at this point. The subsequent checks
1226 * assert this.
1228 if (!S_ISLNK(smb_fname->st.st_ex_mode)) {
1229 DBG_ERR("[%s] is not a symlink\n",
1230 smb_fname_str_dbg(smb_fname));
1231 return NT_STATUS_INTERNAL_ERROR;
1233 if (fsp_get_pathref_fd(fsp) != -1) {
1234 DBG_ERR("fd for [%s] is not -1: fd [%d]\n",
1235 smb_fname_str_dbg(smb_fname),
1236 fsp_get_pathref_fd(fsp));
1237 return NT_STATUS_INTERNAL_ERROR;
1242 * Access to streams is checked by checking the basefile and
1243 * that has already been checked by check_base_file_access()
1244 * in create_file_unixpath().
1246 if (!fsp_is_alternate_stream(fsp)) {
1247 status = smbd_check_access_rights_fsp(dirfsp,
1248 fsp,
1249 false,
1250 open_access_mask);
1252 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) &&
1253 posix_open &&
1254 S_ISLNK(smb_fname->st.st_ex_mode)) {
1255 /* This is a POSIX stat open for delete
1256 * or rename on a symlink that points
1257 * nowhere. Allow. */
1258 DEBUG(10,("open_file: allowing POSIX "
1259 "open on bad symlink %s\n",
1260 smb_fname_str_dbg(smb_fname)));
1261 status = NT_STATUS_OK;
1264 if (!NT_STATUS_IS_OK(status)) {
1265 DBG_DEBUG("smbd_check_access_rights_fsp on file "
1266 "%s returned %s\n",
1267 fsp_str_dbg(fsp),
1268 nt_errstr(status));
1269 return status;
1274 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
1275 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
1276 fsp->file_pid = req ? req->smbpid : 0;
1277 if (file_existed && S_ISLNK(smb_fname->st.st_ex_mode)) {
1278 fsp->fsp_flags.can_lock = false;
1279 fsp->fsp_flags.can_read = false;
1280 fsp->fsp_flags.can_write = false;
1281 } else {
1282 fsp->fsp_flags.can_lock = true;
1283 fsp->fsp_flags.can_read = ((access_mask & FILE_READ_DATA) !=
1285 fsp->fsp_flags.can_write = CAN_WRITE(conn) &&
1286 ((access_mask &
1287 (FILE_WRITE_DATA |
1288 FILE_APPEND_DATA)) != 0) &&
1289 (fsp->fsp_name->twrp == 0);
1291 fsp->print_file = NULL;
1292 fsp->fsp_flags.modified = false;
1293 fsp->sent_oplock_break = NO_BREAK_SENT;
1294 fsp->fsp_flags.is_directory = false;
1295 if (is_in_path(smb_fname->base_name,
1296 conn->aio_write_behind_list,
1297 posix_open ? true : conn->case_sensitive)) {
1298 fsp->fsp_flags.aio_write_behind = true;
1301 DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
1302 conn->session_info->unix_info->unix_name,
1303 smb_fname_str_dbg(smb_fname),
1304 BOOLSTR(fsp->fsp_flags.can_read),
1305 BOOLSTR(fsp->fsp_flags.can_write),
1306 conn->num_files_open));
1308 return NT_STATUS_OK;
1311 static bool mask_conflict(
1312 uint32_t new_access,
1313 uint32_t existing_access,
1314 uint32_t access_mask,
1315 uint32_t new_sharemode,
1316 uint32_t existing_sharemode,
1317 uint32_t sharemode_mask)
1319 bool want_access = (new_access & access_mask);
1320 bool allow_existing = (existing_sharemode & sharemode_mask);
1321 bool have_access = (existing_access & access_mask);
1322 bool allow_new = (new_sharemode & sharemode_mask);
1324 if (want_access && !allow_existing) {
1325 DBG_DEBUG("Access request 0x%"PRIx32"/0x%"PRIx32" conflicts "
1326 "with existing sharemode 0x%"PRIx32"/0x%"PRIx32"\n",
1327 new_access,
1328 access_mask,
1329 existing_sharemode,
1330 sharemode_mask);
1331 return true;
1333 if (have_access && !allow_new) {
1334 DBG_DEBUG("Sharemode request 0x%"PRIx32"/0x%"PRIx32" conflicts "
1335 "with existing access 0x%"PRIx32"/0x%"PRIx32"\n",
1336 new_sharemode,
1337 sharemode_mask,
1338 existing_access,
1339 access_mask);
1340 return true;
1342 return false;
1345 /****************************************************************************
1346 Check if we can open a file with a share mode.
1347 Returns True if conflict, False if not.
1348 ****************************************************************************/
1350 static const uint32_t conflicting_access =
1351 FILE_WRITE_DATA|
1352 FILE_APPEND_DATA|
1353 FILE_READ_DATA|
1354 FILE_EXECUTE|
1355 DELETE_ACCESS;
1357 static bool share_conflict(uint32_t e_access_mask,
1358 uint32_t e_share_access,
1359 uint32_t access_mask,
1360 uint32_t share_access)
1362 bool conflict;
1364 DBG_DEBUG("existing access_mask = 0x%"PRIx32", "
1365 "existing share access = 0x%"PRIx32", "
1366 "access_mask = 0x%"PRIx32", "
1367 "share_access = 0x%"PRIx32"\n",
1368 e_access_mask,
1369 e_share_access,
1370 access_mask,
1371 share_access);
1373 if ((e_access_mask & conflicting_access) == 0) {
1374 DBG_DEBUG("No conflict due to "
1375 "existing access_mask = 0x%"PRIx32"\n",
1376 e_access_mask);
1377 return false;
1379 if ((access_mask & conflicting_access) == 0) {
1380 DBG_DEBUG("No conflict due to access_mask = 0x%"PRIx32"\n",
1381 access_mask);
1382 return false;
1385 conflict = mask_conflict(
1386 access_mask, e_access_mask, FILE_WRITE_DATA | FILE_APPEND_DATA,
1387 share_access, e_share_access, FILE_SHARE_WRITE);
1388 conflict |= mask_conflict(
1389 access_mask, e_access_mask, FILE_READ_DATA | FILE_EXECUTE,
1390 share_access, e_share_access, FILE_SHARE_READ);
1391 conflict |= mask_conflict(
1392 access_mask, e_access_mask, DELETE_ACCESS,
1393 share_access, e_share_access, FILE_SHARE_DELETE);
1395 DBG_DEBUG("conflict=%s\n", conflict ? "true" : "false");
1396 return conflict;
1399 #if defined(DEVELOPER)
1401 struct validate_my_share_entries_state {
1402 struct smbd_server_connection *sconn;
1403 struct file_id fid;
1404 struct server_id self;
1407 static bool validate_my_share_entries_fn(
1408 struct share_mode_entry *e,
1409 bool *modified,
1410 void *private_data)
1412 struct validate_my_share_entries_state *state = private_data;
1413 files_struct *fsp;
1415 if (!server_id_equal(&state->self, &e->pid)) {
1416 return false;
1419 if (e->op_mid == 0) {
1420 /* INTERNAL_OPEN_ONLY */
1421 return false;
1424 fsp = file_find_dif(state->sconn, state->fid, e->share_file_id);
1425 if (!fsp) {
1426 DBG_ERR("PANIC : %s\n",
1427 share_mode_str(talloc_tos(), 0, &state->fid, e));
1428 smb_panic("validate_my_share_entries: Cannot match a "
1429 "share entry with an open file\n");
1432 if (((uint16_t)fsp->oplock_type) != e->op_type) {
1433 goto panic;
1436 return false;
1438 panic:
1440 char *str;
1441 DBG_ERR("validate_my_share_entries: PANIC : %s\n",
1442 share_mode_str(talloc_tos(), 0, &state->fid, e));
1443 str = talloc_asprintf(talloc_tos(),
1444 "validate_my_share_entries: "
1445 "file %s, oplock_type = 0x%x, op_type = 0x%x\n",
1446 fsp->fsp_name->base_name,
1447 (unsigned int)fsp->oplock_type,
1448 (unsigned int)e->op_type);
1449 smb_panic(str);
1452 return false;
1454 #endif
1457 * Allowed access mask for stat opens relevant to oplocks
1459 bool is_oplock_stat_open(uint32_t access_mask)
1461 const uint32_t stat_open_bits =
1462 (SYNCHRONIZE_ACCESS|
1463 FILE_READ_ATTRIBUTES|
1464 FILE_WRITE_ATTRIBUTES);
1466 return (((access_mask & stat_open_bits) != 0) &&
1467 ((access_mask & ~stat_open_bits) == 0));
1471 * Allowed access mask for stat opens relevant to leases
1473 bool is_lease_stat_open(uint32_t access_mask)
1475 const uint32_t stat_open_bits =
1476 (SYNCHRONIZE_ACCESS|
1477 FILE_READ_ATTRIBUTES|
1478 FILE_WRITE_ATTRIBUTES|
1479 READ_CONTROL_ACCESS);
1481 return (((access_mask & stat_open_bits) != 0) &&
1482 ((access_mask & ~stat_open_bits) == 0));
1485 struct has_delete_on_close_state {
1486 bool ret;
1489 static bool has_delete_on_close_fn(
1490 struct share_mode_entry *e,
1491 bool *modified,
1492 void *private_data)
1494 struct has_delete_on_close_state *state = private_data;
1495 state->ret = !share_entry_stale_pid(e);
1496 return state->ret;
1499 static bool has_delete_on_close(struct share_mode_lock *lck,
1500 uint32_t name_hash)
1502 struct has_delete_on_close_state state = { .ret = false };
1503 bool ok;
1505 if (!is_delete_on_close_set(lck, name_hash)) {
1506 return false;
1509 ok= share_mode_forall_entries(lck, has_delete_on_close_fn, &state);
1510 if (!ok) {
1511 DBG_DEBUG("share_mode_forall_entries failed\n");
1512 return false;
1514 return state.ret;
1517 static void share_mode_flags_restrict(
1518 struct share_mode_lock *lck,
1519 uint32_t access_mask,
1520 uint32_t share_mode,
1521 uint32_t lease_type)
1523 uint32_t existing_access_mask, existing_share_mode;
1524 uint32_t existing_lease_type;
1526 share_mode_flags_get(
1527 lck,
1528 &existing_access_mask,
1529 &existing_share_mode,
1530 &existing_lease_type);
1532 existing_access_mask |= access_mask;
1533 if (access_mask & conflicting_access) {
1534 existing_share_mode &= share_mode;
1536 existing_lease_type |= lease_type;
1538 share_mode_flags_set(
1539 lck,
1540 existing_access_mask,
1541 existing_share_mode,
1542 existing_lease_type,
1543 NULL);
1546 /****************************************************************************
1547 Deal with share modes
1548 Invariant: Share mode must be locked on entry and exit.
1549 Returns -1 on error, or number of share modes on success (may be zero).
1550 ****************************************************************************/
1552 struct open_mode_check_state {
1553 struct file_id fid;
1554 uint32_t access_mask;
1555 uint32_t share_access;
1556 uint32_t lease_type;
1559 static bool open_mode_check_fn(
1560 struct share_mode_entry *e,
1561 bool *modified,
1562 void *private_data)
1564 struct open_mode_check_state *state = private_data;
1565 bool disconnected, stale;
1566 uint32_t access_mask, share_access, lease_type;
1568 disconnected = server_id_is_disconnected(&e->pid);
1569 if (disconnected) {
1570 return false;
1573 access_mask = state->access_mask | e->access_mask;
1574 share_access = state->share_access;
1575 if (e->access_mask & conflicting_access) {
1576 share_access &= e->share_access;
1578 lease_type = state->lease_type | get_lease_type(e, state->fid);
1580 if ((access_mask == state->access_mask) &&
1581 (share_access == state->share_access) &&
1582 (lease_type == state->lease_type)) {
1583 return false;
1586 stale = share_entry_stale_pid(e);
1587 if (stale) {
1588 return false;
1591 state->access_mask = access_mask;
1592 state->share_access = share_access;
1593 state->lease_type = lease_type;
1595 return false;
1598 static NTSTATUS open_mode_check(connection_struct *conn,
1599 struct file_id fid,
1600 struct share_mode_lock *lck,
1601 uint32_t access_mask,
1602 uint32_t share_access)
1604 struct open_mode_check_state state;
1605 bool ok, conflict;
1606 bool modified = false;
1608 if (is_oplock_stat_open(access_mask)) {
1609 /* Stat open that doesn't trigger oplock breaks or share mode
1610 * checks... ! JRA. */
1611 return NT_STATUS_OK;
1615 * Check if the share modes will give us access.
1618 #if defined(DEVELOPER)
1620 struct validate_my_share_entries_state validate_state = {
1621 .sconn = conn->sconn,
1622 .fid = fid,
1623 .self = messaging_server_id(conn->sconn->msg_ctx),
1625 ok = share_mode_forall_entries(
1626 lck, validate_my_share_entries_fn, &validate_state);
1627 SMB_ASSERT(ok);
1629 #endif
1631 share_mode_flags_get(
1632 lck, &state.access_mask, &state.share_access, NULL);
1634 conflict = share_conflict(
1635 state.access_mask,
1636 state.share_access,
1637 access_mask,
1638 share_access);
1639 if (!conflict) {
1640 DBG_DEBUG("No conflict due to share_mode_flags access\n");
1641 return NT_STATUS_OK;
1644 state = (struct open_mode_check_state) {
1645 .fid = fid,
1646 .share_access = (FILE_SHARE_READ|
1647 FILE_SHARE_WRITE|
1648 FILE_SHARE_DELETE),
1652 * Walk the share mode array to recalculate d->flags
1655 ok = share_mode_forall_entries(lck, open_mode_check_fn, &state);
1656 if (!ok) {
1657 DBG_DEBUG("share_mode_forall_entries failed\n");
1658 return NT_STATUS_INTERNAL_ERROR;
1661 share_mode_flags_set(
1662 lck,
1663 state.access_mask,
1664 state.share_access,
1665 state.lease_type,
1666 &modified);
1667 if (!modified) {
1669 * We only end up here if we had a sharing violation
1670 * from d->flags and have recalculated it.
1672 return NT_STATUS_SHARING_VIOLATION;
1675 conflict = share_conflict(
1676 state.access_mask,
1677 state.share_access,
1678 access_mask,
1679 share_access);
1680 if (!conflict) {
1681 DBG_DEBUG("No conflict due to share_mode_flags access\n");
1682 return NT_STATUS_OK;
1685 return NT_STATUS_SHARING_VIOLATION;
1689 * Send a break message to the oplock holder and delay the open for
1690 * our client.
1693 NTSTATUS send_break_message(struct messaging_context *msg_ctx,
1694 const struct file_id *id,
1695 const struct share_mode_entry *exclusive,
1696 uint16_t break_to)
1698 struct oplock_break_message msg = {
1699 .id = *id,
1700 .share_file_id = exclusive->share_file_id,
1701 .break_to = break_to,
1703 enum ndr_err_code ndr_err;
1704 uint8_t msgbuf[33];
1705 DATA_BLOB blob = {.data = msgbuf, .length = sizeof(msgbuf)};
1706 NTSTATUS status;
1708 if (DEBUGLVL(10)) {
1709 struct server_id_buf buf;
1710 DBG_DEBUG("Sending break message to %s\n",
1711 server_id_str_buf(exclusive->pid, &buf));
1712 NDR_PRINT_DEBUG(oplock_break_message, &msg);
1715 ndr_err = ndr_push_struct_into_fixed_blob(
1716 &blob,
1717 &msg,
1718 (ndr_push_flags_fn_t)ndr_push_oplock_break_message);
1719 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1720 DBG_WARNING("ndr_push_oplock_break_message failed: %s\n",
1721 ndr_errstr(ndr_err));
1722 return ndr_map_error2ntstatus(ndr_err);
1725 status = messaging_send(msg_ctx,
1726 exclusive->pid,
1727 MSG_SMB_BREAK_REQUEST,
1728 &blob);
1729 if (!NT_STATUS_IS_OK(status)) {
1730 DEBUG(3, ("Could not send oplock break message: %s\n",
1731 nt_errstr(status)));
1734 return status;
1737 struct validate_oplock_types_state {
1738 bool valid;
1739 bool batch;
1740 bool ex_or_batch;
1741 bool level2;
1742 bool no_oplock;
1743 uint32_t num_non_stat_opens;
1746 static bool validate_oplock_types_fn(
1747 struct share_mode_entry *e,
1748 bool *modified,
1749 void *private_data)
1751 struct validate_oplock_types_state *state = private_data;
1753 if (e->op_mid == 0) {
1754 /* INTERNAL_OPEN_ONLY */
1755 return false;
1758 if (e->op_type == NO_OPLOCK && is_oplock_stat_open(e->access_mask)) {
1760 * We ignore stat opens in the table - they always
1761 * have NO_OPLOCK and never get or cause breaks. JRA.
1763 return false;
1766 state->num_non_stat_opens += 1;
1768 if (BATCH_OPLOCK_TYPE(e->op_type)) {
1769 /* batch - can only be one. */
1770 if (share_entry_stale_pid(e)) {
1771 DBG_DEBUG("Found stale batch oplock\n");
1772 return false;
1774 if (state->ex_or_batch ||
1775 state->batch ||
1776 state->level2 ||
1777 state->no_oplock) {
1778 DBG_ERR("Bad batch oplock entry\n");
1779 state->valid = false;
1780 return true;
1782 state->batch = true;
1785 if (EXCLUSIVE_OPLOCK_TYPE(e->op_type)) {
1786 if (share_entry_stale_pid(e)) {
1787 DBG_DEBUG("Found stale duplicate oplock\n");
1788 return false;
1790 /* Exclusive or batch - can only be one. */
1791 if (state->ex_or_batch ||
1792 state->level2 ||
1793 state->no_oplock) {
1794 DBG_ERR("Bad exclusive or batch oplock entry\n");
1795 state->valid = false;
1796 return true;
1798 state->ex_or_batch = true;
1801 if (LEVEL_II_OPLOCK_TYPE(e->op_type)) {
1802 if (state->batch || state->ex_or_batch) {
1803 if (share_entry_stale_pid(e)) {
1804 DBG_DEBUG("Found stale LevelII oplock\n");
1805 return false;
1807 DBG_DEBUG("Bad levelII oplock entry\n");
1808 state->valid = false;
1809 return true;
1811 state->level2 = true;
1814 if (e->op_type == NO_OPLOCK) {
1815 if (state->batch || state->ex_or_batch) {
1816 if (share_entry_stale_pid(e)) {
1817 DBG_DEBUG("Found stale NO_OPLOCK entry\n");
1818 return false;
1820 DBG_ERR("Bad no oplock entry\n");
1821 state->valid = false;
1822 return true;
1824 state->no_oplock = true;
1827 return false;
1831 * Do internal consistency checks on the share mode for a file.
1834 static bool validate_oplock_types(struct share_mode_lock *lck)
1836 struct validate_oplock_types_state state = { .valid = true };
1837 static bool skip_validation;
1838 bool validate;
1839 bool ok;
1841 if (skip_validation) {
1842 return true;
1845 validate = lp_parm_bool(-1, "smbd", "validate_oplock_types", false);
1846 if (!validate) {
1847 DBG_DEBUG("smbd:validate_oplock_types not set to yes\n");
1848 skip_validation = true;
1849 return true;
1852 ok = share_mode_forall_entries(lck, validate_oplock_types_fn, &state);
1853 if (!ok) {
1854 DBG_DEBUG("share_mode_forall_entries failed\n");
1855 return false;
1857 if (!state.valid) {
1858 DBG_DEBUG("Got invalid oplock configuration\n");
1859 return false;
1862 if ((state.batch || state.ex_or_batch) &&
1863 (state.num_non_stat_opens != 1)) {
1864 DBG_WARNING("got batch (%d) or ex (%d) non-exclusively "
1865 "(%"PRIu32")\n",
1866 (int)state.batch,
1867 (int)state.ex_or_batch,
1868 state.num_non_stat_opens);
1869 return false;
1872 return true;
1875 static bool is_same_lease(const files_struct *fsp,
1876 const struct share_mode_entry *e,
1877 const struct smb2_lease *lease)
1879 if (e->op_type != LEASE_OPLOCK) {
1880 return false;
1882 if (lease == NULL) {
1883 return false;
1886 return smb2_lease_equal(fsp_client_guid(fsp),
1887 &lease->lease_key,
1888 &e->client_guid,
1889 &e->lease_key);
1892 static bool file_has_brlocks(files_struct *fsp)
1894 struct byte_range_lock *br_lck;
1896 br_lck = brl_get_locks_readonly(fsp);
1897 if (!br_lck)
1898 return false;
1900 return (brl_num_locks(br_lck) > 0);
1903 struct fsp_lease *find_fsp_lease(struct files_struct *new_fsp,
1904 const struct smb2_lease_key *key,
1905 uint32_t current_state,
1906 uint16_t lease_version,
1907 uint16_t lease_epoch)
1909 struct files_struct *fsp;
1912 * TODO: Measure how expensive this loop is with thousands of open
1913 * handles...
1916 for (fsp = file_find_di_first(new_fsp->conn->sconn, new_fsp->file_id, true);
1917 fsp != NULL;
1918 fsp = file_find_di_next(fsp, true)) {
1920 if (fsp == new_fsp) {
1921 continue;
1923 if (fsp->oplock_type != LEASE_OPLOCK) {
1924 continue;
1926 if (smb2_lease_key_equal(&fsp->lease->lease.lease_key, key)) {
1927 fsp->lease->ref_count += 1;
1928 return fsp->lease;
1932 /* Not found - must be leased in another smbd. */
1933 new_fsp->lease = talloc_zero(new_fsp->conn->sconn, struct fsp_lease);
1934 if (new_fsp->lease == NULL) {
1935 return NULL;
1937 new_fsp->lease->ref_count = 1;
1938 new_fsp->lease->sconn = new_fsp->conn->sconn;
1939 new_fsp->lease->lease.lease_key = *key;
1940 new_fsp->lease->lease.lease_state = current_state;
1942 * We internally treat all leases as V2 and update
1943 * the epoch, but when sending breaks it matters if
1944 * the requesting lease was v1 or v2.
1946 new_fsp->lease->lease.lease_version = lease_version;
1947 new_fsp->lease->lease.lease_epoch = lease_epoch;
1948 return new_fsp->lease;
1951 static NTSTATUS try_lease_upgrade(struct files_struct *fsp,
1952 struct share_mode_lock *lck,
1953 const struct GUID *client_guid,
1954 const struct smb2_lease *lease,
1955 uint32_t granted)
1957 bool do_upgrade;
1958 uint32_t current_state, breaking_to_requested, breaking_to_required;
1959 bool breaking;
1960 uint16_t lease_version, epoch;
1961 uint32_t existing, requested;
1962 NTSTATUS status;
1964 status = leases_db_get(
1965 client_guid,
1966 &lease->lease_key,
1967 &fsp->file_id,
1968 &current_state,
1969 &breaking,
1970 &breaking_to_requested,
1971 &breaking_to_required,
1972 &lease_version,
1973 &epoch);
1974 if (!NT_STATUS_IS_OK(status)) {
1975 return status;
1978 fsp->lease = find_fsp_lease(
1979 fsp,
1980 &lease->lease_key,
1981 current_state,
1982 lease_version,
1983 epoch);
1984 if (fsp->lease == NULL) {
1985 DEBUG(1, ("Did not find existing lease for file %s\n",
1986 fsp_str_dbg(fsp)));
1987 return NT_STATUS_NO_MEMORY;
1991 * Upgrade only if the requested lease is a strict upgrade.
1993 existing = current_state;
1994 requested = lease->lease_state;
1997 * Tricky: This test makes sure that "requested" is a
1998 * strict bitwise superset of "existing".
2000 do_upgrade = ((existing & requested) == existing);
2003 * Upgrade only if there's a change.
2005 do_upgrade &= (granted != existing);
2008 * Upgrade only if other leases don't prevent what was asked
2009 * for.
2011 do_upgrade &= (granted == requested);
2014 * only upgrade if we are not in breaking state
2016 do_upgrade &= !breaking;
2018 DEBUG(10, ("existing=%"PRIu32", requested=%"PRIu32", "
2019 "granted=%"PRIu32", do_upgrade=%d\n",
2020 existing, requested, granted, (int)do_upgrade));
2022 if (do_upgrade) {
2023 NTSTATUS set_status;
2025 current_state = granted;
2026 epoch += 1;
2028 set_status = leases_db_set(
2029 client_guid,
2030 &lease->lease_key,
2031 current_state,
2032 breaking,
2033 breaking_to_requested,
2034 breaking_to_required,
2035 lease_version,
2036 epoch);
2038 if (!NT_STATUS_IS_OK(set_status)) {
2039 DBG_DEBUG("leases_db_set failed: %s\n",
2040 nt_errstr(set_status));
2041 return set_status;
2045 fsp_lease_update(fsp);
2047 return NT_STATUS_OK;
2050 static NTSTATUS grant_new_fsp_lease(struct files_struct *fsp,
2051 struct share_mode_lock *lck,
2052 const struct GUID *client_guid,
2053 const struct smb2_lease *lease,
2054 uint32_t granted)
2056 NTSTATUS status;
2058 fsp->lease = talloc_zero(fsp->conn->sconn, struct fsp_lease);
2059 if (fsp->lease == NULL) {
2060 return NT_STATUS_INSUFFICIENT_RESOURCES;
2062 fsp->lease->ref_count = 1;
2063 fsp->lease->sconn = fsp->conn->sconn;
2064 fsp->lease->lease.lease_version = lease->lease_version;
2065 fsp->lease->lease.lease_key = lease->lease_key;
2066 fsp->lease->lease.parent_lease_key = lease->parent_lease_key;
2067 fsp->lease->lease.lease_flags = lease->lease_flags;
2068 fsp->lease->lease.lease_state = granted;
2069 fsp->lease->lease.lease_epoch = lease->lease_epoch + 1;
2071 status = leases_db_add(client_guid,
2072 &lease->lease_key,
2073 &fsp->file_id,
2074 fsp->lease->lease.lease_state,
2075 fsp->lease->lease.lease_version,
2076 fsp->lease->lease.lease_epoch,
2077 fsp->conn->connectpath,
2078 fsp->fsp_name->base_name,
2079 fsp->fsp_name->stream_name);
2080 if (!NT_STATUS_IS_OK(status)) {
2081 DEBUG(10, ("%s: leases_db_add failed: %s\n", __func__,
2082 nt_errstr(status)));
2083 TALLOC_FREE(fsp->lease);
2084 return NT_STATUS_INSUFFICIENT_RESOURCES;
2088 * We used to set lck->data->modified=true here without
2089 * actually modifying lck->data, triggering a needless
2090 * writeback of lck->data.
2092 * Apart from that writeback, setting modified=true has the
2093 * effect of triggering all waiters for this file to
2094 * retry. This only makes sense if any blocking condition
2095 * (i.e. waiting for a lease to be downgraded or removed) is
2096 * gone. This routine here only adds a lease, so it will never
2097 * free up resources that blocked waiters can now claim. So
2098 * that second effect also does not matter in this
2099 * routine. Thus setting lck->data->modified=true does not
2100 * need to be done here.
2103 return NT_STATUS_OK;
2106 static NTSTATUS grant_fsp_lease(struct files_struct *fsp,
2107 struct share_mode_lock *lck,
2108 const struct smb2_lease *lease,
2109 uint32_t granted)
2111 const struct GUID *client_guid = fsp_client_guid(fsp);
2112 NTSTATUS status;
2114 status = try_lease_upgrade(fsp, lck, client_guid, lease, granted);
2116 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
2117 status = grant_new_fsp_lease(
2118 fsp, lck, client_guid, lease, granted);
2121 return status;
2124 static int map_lease_type_to_oplock(uint32_t lease_type)
2126 int result = NO_OPLOCK;
2128 switch (lease_type) {
2129 case SMB2_LEASE_READ|SMB2_LEASE_WRITE|SMB2_LEASE_HANDLE:
2130 result = BATCH_OPLOCK|EXCLUSIVE_OPLOCK;
2131 break;
2132 case SMB2_LEASE_READ|SMB2_LEASE_WRITE:
2133 result = EXCLUSIVE_OPLOCK;
2134 break;
2135 case SMB2_LEASE_READ|SMB2_LEASE_HANDLE:
2136 case SMB2_LEASE_READ:
2137 result = LEVEL_II_OPLOCK;
2138 break;
2141 return result;
2144 struct blocker_debug_state {
2145 size_t num_blockers;
2148 struct delay_for_oplock_state {
2149 struct files_struct *fsp;
2150 const struct smb2_lease *lease;
2151 bool will_overwrite;
2152 uint32_t delay_mask;
2153 bool first_open_attempt;
2154 bool got_handle_lease;
2155 bool got_oplock;
2156 bool disallow_write_lease;
2157 uint32_t total_lease_types;
2158 bool delay;
2159 struct blocker_debug_state *blocker_debug_state;
2162 static int blocker_debug_state_destructor(struct blocker_debug_state *state)
2164 if (state->num_blockers == 0) {
2165 return 0;
2168 DBG_DEBUG("blocker_debug_state [%p] num_blockers [%zu]\n",
2169 state, state->num_blockers);
2170 return 0;
2173 static void delay_for_oplock_fn_watch_done(struct tevent_req *subreq);
2175 static bool delay_for_oplock_fn(
2176 struct share_mode_entry *e,
2177 bool *modified,
2178 void *private_data)
2180 struct delay_for_oplock_state *state = private_data;
2181 struct files_struct *fsp = state->fsp;
2182 const struct smb2_lease *lease = state->lease;
2183 bool e_is_lease = (e->op_type == LEASE_OPLOCK);
2184 uint32_t e_lease_type = SMB2_LEASE_NONE;
2185 uint32_t break_to;
2186 bool lease_is_breaking = false;
2187 struct tevent_req *subreq = NULL;
2188 struct server_id_buf idbuf = {};
2190 if (e_is_lease) {
2191 NTSTATUS status;
2193 if (lease != NULL) {
2194 bool our_lease = is_same_lease(fsp, e, lease);
2195 if (our_lease) {
2196 DBG_DEBUG("Ignoring our own lease\n");
2197 return false;
2201 status = leases_db_get(
2202 &e->client_guid,
2203 &e->lease_key,
2204 &fsp->file_id,
2205 &e_lease_type, /* current_state */
2206 &lease_is_breaking,
2207 NULL, /* breaking_to_requested */
2208 NULL, /* breaking_to_required */
2209 NULL, /* lease_version */
2210 NULL); /* epoch */
2213 * leases_db_get() can return NT_STATUS_NOT_FOUND
2214 * if the share_mode_entry e is stale and the
2215 * lease record was already removed. In this case return
2216 * false so the traverse continues.
2219 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND) &&
2220 share_entry_stale_pid(e))
2222 struct GUID_txt_buf guid_strbuf;
2223 struct file_id_buf file_id_strbuf;
2224 DBG_DEBUG("leases_db_get for client_guid [%s] "
2225 "lease_key [%"PRIu64"/%"PRIu64"] "
2226 "file_id [%s] failed for stale "
2227 "share_mode_entry\n",
2228 GUID_buf_string(&e->client_guid, &guid_strbuf),
2229 e->lease_key.data[0],
2230 e->lease_key.data[1],
2231 file_id_str_buf(fsp->file_id, &file_id_strbuf));
2232 return false;
2234 if (!NT_STATUS_IS_OK(status)) {
2235 struct GUID_txt_buf guid_strbuf;
2236 struct file_id_buf file_id_strbuf;
2237 DBG_ERR("leases_db_get for client_guid [%s] "
2238 "lease_key [%"PRIu64"/%"PRIu64"] "
2239 "file_id [%s] failed: %s\n",
2240 GUID_buf_string(&e->client_guid, &guid_strbuf),
2241 e->lease_key.data[0],
2242 e->lease_key.data[1],
2243 file_id_str_buf(fsp->file_id, &file_id_strbuf),
2244 nt_errstr(status));
2245 smb_panic("leases_db_get() failed");
2247 } else {
2248 e_lease_type = get_lease_type(e, fsp->file_id);
2251 if (((e_lease_type & ~state->total_lease_types) != 0) &&
2252 !share_entry_stale_pid(e))
2254 state->total_lease_types |= e_lease_type;
2257 if (!state->got_handle_lease &&
2258 ((e_lease_type & SMB2_LEASE_HANDLE) != 0) &&
2259 !share_entry_stale_pid(e)) {
2260 state->got_handle_lease = true;
2263 if (!state->got_oplock &&
2264 (e->op_type != NO_OPLOCK) &&
2265 (e->op_type != LEASE_OPLOCK) &&
2266 !share_entry_stale_pid(e)) {
2267 state->got_oplock = true;
2271 * Two things prevent a write lease
2272 * to be granted:
2274 * 1. Any oplock or lease (even broken to NONE)
2275 * 2. An open with an access mask other than
2276 * FILE_READ_ATTRIBUTES, FILE_WRITE_ATTRIBUTES
2277 * or SYNCHRONIZE_ACCESS
2279 if (!state->disallow_write_lease &&
2280 (e->op_type != NO_OPLOCK || !is_oplock_stat_open(e->access_mask)) &&
2281 !is_same_lease(fsp, e, lease) &&
2282 !share_entry_stale_pid(e))
2284 state->disallow_write_lease = true;
2287 if (e_is_lease && is_lease_stat_open(fsp->access_mask)) {
2288 return false;
2291 break_to = e_lease_type & ~state->delay_mask;
2293 if (state->will_overwrite) {
2294 break_to &= ~(SMB2_LEASE_HANDLE|SMB2_LEASE_READ);
2297 DBG_DEBUG("e_lease_type %u, will_overwrite: %u\n",
2298 (unsigned)e_lease_type,
2299 (unsigned)state->will_overwrite);
2301 if ((e_lease_type & ~break_to) == 0) {
2302 if (lease_is_breaking) {
2303 state->delay = true;
2305 return false;
2308 if (share_entry_stale_pid(e)) {
2309 return false;
2312 if (state->will_overwrite) {
2314 * If we break anyway break to NONE directly.
2315 * Otherwise vfs_set_filelen() will trigger the
2316 * break.
2318 break_to &= ~(SMB2_LEASE_READ|SMB2_LEASE_WRITE);
2321 if (!e_is_lease) {
2323 * Oplocks only support breaking to R or NONE.
2325 break_to &= ~(SMB2_LEASE_HANDLE|SMB2_LEASE_WRITE);
2328 DBG_DEBUG("breaking from %d to %d\n",
2329 (int)e_lease_type,
2330 (int)break_to);
2331 send_break_message(
2332 fsp->conn->sconn->msg_ctx, &fsp->file_id, e, break_to);
2333 if (e_lease_type & state->delay_mask) {
2334 state->delay = true;
2336 if (lease_is_breaking && !state->first_open_attempt) {
2337 state->delay = true;
2340 if (!state->delay) {
2341 return false;
2344 if (state->blocker_debug_state == NULL) {
2345 return false;
2348 subreq = server_id_watch_send(state->blocker_debug_state,
2349 fsp->conn->sconn->ev_ctx,
2350 e->pid);
2351 if (subreq == NULL) {
2352 DBG_ERR("server_id_watch_send(%s) returned NULL\n",
2353 server_id_str_buf(e->pid, &idbuf));
2354 return false;
2357 tevent_req_set_callback(subreq,
2358 delay_for_oplock_fn_watch_done,
2359 state->blocker_debug_state);
2361 state->blocker_debug_state->num_blockers++;
2363 DBG_DEBUG("Starting to watch pid [%s] state [%p] num_blockers [%zu]\n",
2364 server_id_str_buf(e->pid, &idbuf),
2365 state->blocker_debug_state,
2366 state->blocker_debug_state->num_blockers);
2368 return false;
2371 static void delay_for_oplock_fn_watch_done(struct tevent_req *subreq)
2373 struct blocker_debug_state *blocker_debug_state = tevent_req_callback_data(
2374 subreq, struct blocker_debug_state);
2375 struct server_id pid = {};
2376 struct server_id_buf idbuf = {};
2377 int ret;
2379 ret = server_id_watch_recv(subreq, &pid);
2380 if (ret != 0) {
2381 DBG_ERR("server_id_watch_recv failed %s\n", strerror(ret));
2382 return;
2385 DBG_DEBUG("state [%p] server_id_watch_recv() returned pid [%s] exited\n",
2386 blocker_debug_state,
2387 server_id_str_buf(pid, &idbuf));
2390 static NTSTATUS delay_for_oplock(files_struct *fsp,
2391 int oplock_request,
2392 const struct smb2_lease *lease,
2393 struct share_mode_lock *lck,
2394 bool have_sharing_violation,
2395 uint32_t create_disposition,
2396 bool first_open_attempt,
2397 int *poplock_type,
2398 uint32_t *pgranted,
2399 struct blocker_debug_state **blocker_debug_state)
2401 struct delay_for_oplock_state state = {
2402 .fsp = fsp,
2403 .lease = lease,
2404 .first_open_attempt = first_open_attempt,
2406 uint32_t requested;
2407 uint32_t granted;
2408 int oplock_type;
2409 bool ok;
2411 *poplock_type = NO_OPLOCK;
2412 *pgranted = 0;
2414 if (oplock_request == LEASE_OPLOCK) {
2415 if (lease == NULL) {
2417 * The SMB2 layer should have checked this
2419 return NT_STATUS_INTERNAL_ERROR;
2422 requested = lease->lease_state;
2423 if (fsp->fsp_flags.is_directory) {
2425 * According to "MS-FSA 2.1.5.18 Server Requests an
2426 * Oplock" this should fail with
2427 * STATUS_INVALID_PARAMETER, but Windows 2022 just
2428 * ignores the SMB2_LEASE_WRITE bit.
2430 requested &= ~SMB2_LEASE_WRITE;
2432 } else {
2433 requested = map_oplock_to_lease_type(
2434 oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK);
2437 share_mode_flags_get(lck, NULL, NULL, &state.total_lease_types);
2439 if (is_oplock_stat_open(fsp->access_mask)) {
2440 goto grant;
2443 if (lp_parm_bool(GLOBAL_SECTION_SNUM,
2444 "smbd lease break",
2445 "debug hung procs",
2446 false))
2448 state.blocker_debug_state = talloc_zero(fsp,
2449 struct blocker_debug_state);
2450 if (state.blocker_debug_state == NULL) {
2451 return NT_STATUS_NO_MEMORY;
2453 talloc_steal(talloc_tos(), state.blocker_debug_state);
2455 talloc_set_destructor(state.blocker_debug_state,
2456 blocker_debug_state_destructor);
2459 state.delay_mask = have_sharing_violation ?
2460 SMB2_LEASE_HANDLE : SMB2_LEASE_WRITE;
2462 switch (create_disposition) {
2463 case FILE_SUPERSEDE:
2464 case FILE_OVERWRITE:
2465 case FILE_OVERWRITE_IF:
2466 state.will_overwrite = true;
2467 break;
2468 default:
2469 state.will_overwrite = false;
2470 break;
2473 state.total_lease_types = SMB2_LEASE_NONE;
2474 ok = share_mode_forall_entries(lck, delay_for_oplock_fn, &state);
2475 if (!ok) {
2476 return NT_STATUS_INTERNAL_ERROR;
2479 if (state.delay) {
2480 *blocker_debug_state = state.blocker_debug_state;
2481 return NT_STATUS_RETRY;
2484 grant:
2485 if (have_sharing_violation) {
2486 return NT_STATUS_SHARING_VIOLATION;
2489 granted = requested;
2491 if (oplock_request == LEASE_OPLOCK) {
2492 if (lp_kernel_oplocks(SNUM(fsp->conn))) {
2493 DEBUG(10, ("No lease granted because kernel oplocks are enabled\n"));
2494 granted = SMB2_LEASE_NONE;
2496 if ((granted & (SMB2_LEASE_READ|SMB2_LEASE_WRITE)) == 0) {
2497 DEBUG(10, ("No read or write lease requested\n"));
2498 granted = SMB2_LEASE_NONE;
2500 if (granted == SMB2_LEASE_WRITE) {
2501 DEBUG(10, ("pure write lease requested\n"));
2502 granted = SMB2_LEASE_NONE;
2504 if (granted == (SMB2_LEASE_WRITE|SMB2_LEASE_HANDLE)) {
2505 DEBUG(10, ("write and handle lease requested\n"));
2506 granted = SMB2_LEASE_NONE;
2510 if (lp_locking(fsp->conn->params) && file_has_brlocks(fsp)) {
2511 DBG_DEBUG("file %s has byte range locks\n",
2512 fsp_str_dbg(fsp));
2513 granted &= ~SMB2_LEASE_READ;
2516 if (state.disallow_write_lease) {
2518 * Can grant only a write lease
2519 * if there are no other leases
2520 * and no other non-stat opens.
2522 granted &= ~SMB2_LEASE_WRITE;
2525 if ((granted & SMB2_LEASE_READ) && !(granted & SMB2_LEASE_WRITE)) {
2526 bool allow_level2 =
2527 (global_client_caps & CAP_LEVEL_II_OPLOCKS) &&
2528 lp_level2_oplocks(SNUM(fsp->conn));
2530 if (!allow_level2) {
2531 granted = SMB2_LEASE_NONE;
2535 if (oplock_request == LEASE_OPLOCK) {
2536 if (state.got_oplock) {
2537 granted &= ~SMB2_LEASE_HANDLE;
2540 oplock_type = LEASE_OPLOCK;
2541 } else {
2542 if (state.got_handle_lease) {
2543 granted = SMB2_LEASE_NONE;
2547 * Reflect possible downgrades from:
2548 * - map_lease_type_to_oplock() => "RH" to just LEVEL_II
2550 oplock_type = map_lease_type_to_oplock(granted);
2551 granted = map_oplock_to_lease_type(oplock_type);
2554 state.total_lease_types |= granted;
2557 uint32_t acc, sh, ls;
2558 share_mode_flags_get(lck, &acc, &sh, &ls);
2559 ls = state.total_lease_types;
2560 share_mode_flags_set(lck, acc, sh, ls, NULL);
2563 DBG_DEBUG("oplock type 0x%x granted (%s%s%s)(0x%x), on file %s, "
2564 "requested 0x%x (%s%s%s)(0x%x) => total (%s%s%s)(0x%x)\n",
2565 fsp->oplock_type,
2566 granted & SMB2_LEASE_READ ? "R":"",
2567 granted & SMB2_LEASE_WRITE ? "W":"",
2568 granted & SMB2_LEASE_HANDLE ? "H":"",
2569 granted,
2570 fsp_str_dbg(fsp),
2571 oplock_request,
2572 requested & SMB2_LEASE_READ ? "R":"",
2573 requested & SMB2_LEASE_WRITE ? "W":"",
2574 requested & SMB2_LEASE_HANDLE ? "H":"",
2575 requested,
2576 state.total_lease_types & SMB2_LEASE_READ ? "R":"",
2577 state.total_lease_types & SMB2_LEASE_WRITE ? "W":"",
2578 state.total_lease_types & SMB2_LEASE_HANDLE ? "H":"",
2579 state.total_lease_types);
2581 *poplock_type = oplock_type;
2582 *pgranted = granted;
2583 return NT_STATUS_OK;
2586 static NTSTATUS handle_share_mode_lease(
2587 files_struct *fsp,
2588 struct share_mode_lock *lck,
2589 uint32_t create_disposition,
2590 uint32_t access_mask,
2591 uint32_t share_access,
2592 int oplock_request,
2593 const struct smb2_lease *lease,
2594 bool first_open_attempt,
2595 int *poplock_type,
2596 uint32_t *pgranted,
2597 struct blocker_debug_state **blocker_debug_state)
2599 bool sharing_violation = false;
2600 NTSTATUS status;
2602 *poplock_type = NO_OPLOCK;
2603 *pgranted = 0;
2605 status = open_mode_check(
2606 fsp->conn, fsp->file_id, lck, access_mask, share_access);
2607 if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
2608 sharing_violation = true;
2609 status = NT_STATUS_OK; /* handled later */
2612 if (!NT_STATUS_IS_OK(status)) {
2613 return status;
2616 if (fsp->fsp_flags.is_directory &&
2617 oplock_request == LEASE_OPLOCK &&
2618 !lp_smb3_directory_leases())
2620 DBG_NOTICE("Ignoring disabled DirectoryLease request on [%s]\n",
2621 fsp_str_dbg(fsp));
2622 oplock_request = NO_OPLOCK;
2623 lease = NULL;
2626 if (oplock_request == INTERNAL_OPEN_ONLY) {
2627 if (sharing_violation) {
2628 DBG_DEBUG("Sharing violation for internal open\n");
2629 return NT_STATUS_SHARING_VIOLATION;
2633 * Internal opens never do oplocks or leases. We don't
2634 * need to go through delay_for_oplock().
2636 return NT_STATUS_OK;
2639 status = delay_for_oplock(
2640 fsp,
2641 oplock_request,
2642 lease,
2643 lck,
2644 sharing_violation,
2645 create_disposition,
2646 first_open_attempt,
2647 poplock_type,
2648 pgranted,
2649 blocker_debug_state);
2650 if (!NT_STATUS_IS_OK(status)) {
2651 return status;
2654 return NT_STATUS_OK;
2657 static bool request_timed_out(struct smb_request *req, struct timeval timeout)
2659 struct timeval end_time = timeval_sum(&req->request_time, &timeout);
2660 return timeval_expired(&end_time);
2663 struct defer_open_state {
2664 struct smbXsrv_connection *xconn;
2665 uint64_t mid;
2668 static void defer_open_done(struct tevent_req *req);
2671 * Defer an open and watch a locking.tdb record
2673 * This defers an open that gets rescheduled once the locking.tdb record watch
2674 * is triggered by a change to the record.
2676 * It is used to defer opens that triggered an oplock break and for the SMB1
2677 * sharing violation delay.
2679 static void defer_open(struct share_mode_lock *lck,
2680 struct timeval timeout,
2681 struct smb_request *req,
2682 struct file_id id,
2683 struct blocker_debug_state **blocker_debug_state)
2685 struct deferred_open_record *open_rec = NULL;
2686 struct timeval abs_timeout;
2687 struct defer_open_state *watch_state;
2688 struct tevent_req *watch_req;
2689 struct timeval_buf tvbuf1, tvbuf2;
2690 struct file_id_buf fbuf;
2691 bool ok;
2693 abs_timeout = timeval_sum(&req->request_time, &timeout);
2695 DBG_DEBUG("request time [%s] timeout [%s] mid [%" PRIu64 "] "
2696 "file_id [%s]\n",
2697 timeval_str_buf(&req->request_time, false, true, &tvbuf1),
2698 timeval_str_buf(&abs_timeout, false, true, &tvbuf2),
2699 req->mid,
2700 file_id_str_buf(id, &fbuf));
2702 open_rec = talloc_zero(NULL, struct deferred_open_record);
2703 if (open_rec == NULL) {
2704 TALLOC_FREE(lck);
2705 exit_server("talloc failed");
2708 watch_state = talloc(open_rec, struct defer_open_state);
2709 if (watch_state == NULL) {
2710 exit_server("talloc failed");
2712 watch_state->xconn = req->xconn;
2713 watch_state->mid = req->mid;
2715 DBG_DEBUG("deferring mid %" PRIu64 "\n", req->mid);
2717 watch_req = share_mode_watch_send(
2718 watch_state,
2719 req->sconn->ev_ctx,
2720 &id,
2721 (struct server_id){0});
2722 if (watch_req == NULL) {
2723 exit_server("Could not watch share mode record");
2725 tevent_req_set_callback(watch_req, defer_open_done, watch_state);
2727 talloc_move(watch_req, blocker_debug_state);
2729 ok = tevent_req_set_endtime(watch_req, req->sconn->ev_ctx, abs_timeout);
2730 if (!ok) {
2731 exit_server("tevent_req_set_endtime failed");
2734 ok = push_deferred_open_message_smb(req, timeout, id, open_rec);
2735 if (!ok) {
2736 TALLOC_FREE(lck);
2737 exit_server("push_deferred_open_message_smb failed");
2741 static void defer_open_done(struct tevent_req *req)
2743 struct defer_open_state *state = tevent_req_callback_data(
2744 req, struct defer_open_state);
2745 NTSTATUS status;
2746 bool ret;
2748 status = share_mode_watch_recv(req, NULL, NULL);
2749 TALLOC_FREE(req);
2750 if (!NT_STATUS_IS_OK(status)) {
2751 DBG_ERR("share_mode_watch_recv() returned %s, "
2752 "rescheduling mid %" PRIu64 "\n",
2753 nt_errstr(status), state->mid);
2755 * Even if it failed, retry anyway. TODO: We need a way to
2756 * tell a re-scheduled open about that error.
2760 DEBUG(10, ("scheduling mid %llu\n", (unsigned long long)state->mid));
2762 ret = schedule_deferred_open_message_smb(state->xconn, state->mid);
2763 SMB_ASSERT(ret);
2764 TALLOC_FREE(state);
2768 * Actually attempt the kernel oplock polling open.
2771 static void poll_open_fn(struct tevent_context *ev,
2772 struct tevent_timer *te,
2773 struct timeval current_time,
2774 void *private_data)
2776 struct deferred_open_record *open_rec = talloc_get_type_abort(
2777 private_data, struct deferred_open_record);
2778 bool ok;
2780 TALLOC_FREE(open_rec->watch_req);
2782 ok = schedule_deferred_open_message_smb(
2783 open_rec->xconn, open_rec->mid);
2784 if (!ok) {
2785 exit_server("schedule_deferred_open_message_smb failed");
2787 DBG_DEBUG("timer fired. Retrying open !\n");
2790 static void poll_open_done(struct tevent_req *subreq);
2792 struct poll_open_setup_watcher_state {
2793 TALLOC_CTX *mem_ctx;
2794 struct tevent_context *ev_ctx;
2795 struct tevent_req *watch_req;
2796 struct file_id id;
2799 static void poll_open_setup_watcher_fn(struct share_mode_lock *lck,
2800 void *private_data)
2802 struct poll_open_setup_watcher_state *state =
2803 (struct poll_open_setup_watcher_state *)private_data;
2805 if (!validate_oplock_types(lck)) {
2806 smb_panic("validate_oplock_types failed");
2809 state->watch_req = share_mode_watch_send(
2810 state->mem_ctx,
2811 state->ev_ctx,
2812 &state->id,
2813 (struct server_id) {0});
2814 if (state->watch_req == NULL) {
2815 DBG_WARNING("share_mode_watch_send failed\n");
2816 return;
2821 * Reschedule an open for 1 second from now, if not timed out.
2823 static bool setup_poll_open(
2824 struct smb_request *req,
2825 const struct file_id *id,
2826 struct timeval max_timeout,
2827 struct timeval interval)
2829 static struct file_id zero_id = {};
2830 bool ok;
2831 struct deferred_open_record *open_rec = NULL;
2832 struct timeval endtime, next_interval;
2833 struct file_id_buf ftmp;
2835 if (request_timed_out(req, max_timeout)) {
2836 return false;
2839 open_rec = talloc_zero(NULL, struct deferred_open_record);
2840 if (open_rec == NULL) {
2841 DBG_WARNING("talloc failed\n");
2842 return false;
2844 open_rec->xconn = req->xconn;
2845 open_rec->mid = req->mid;
2848 * Make sure open_rec->te does not come later than the
2849 * request's maximum endtime.
2852 endtime = timeval_sum(&req->request_time, &max_timeout);
2853 next_interval = timeval_current_ofs(interval.tv_sec, interval.tv_usec);
2854 next_interval = timeval_min(&endtime, &next_interval);
2856 open_rec->te = tevent_add_timer(
2857 req->sconn->ev_ctx,
2858 open_rec,
2859 next_interval,
2860 poll_open_fn,
2861 open_rec);
2862 if (open_rec->te == NULL) {
2863 DBG_WARNING("tevent_add_timer failed\n");
2864 TALLOC_FREE(open_rec);
2865 return false;
2868 if (id != NULL) {
2869 struct poll_open_setup_watcher_state wstate = {
2870 .mem_ctx = open_rec,
2871 .ev_ctx = req->sconn->ev_ctx,
2872 .id = *id,
2874 NTSTATUS status;
2876 status = share_mode_do_locked_vfs_denied(*id,
2877 poll_open_setup_watcher_fn,
2878 &wstate);
2879 if (NT_STATUS_IS_OK(status)) {
2880 if (wstate.watch_req == NULL) {
2881 DBG_WARNING("share_mode_watch_send failed\n");
2882 TALLOC_FREE(open_rec);
2883 return false;
2885 open_rec->watch_req = wstate.watch_req;
2886 tevent_req_set_callback(open_rec->watch_req,
2887 poll_open_done,
2888 open_rec);
2889 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
2890 DBG_WARNING("share_mode_do_locked_vfs_denied failed - %s\n",
2891 nt_errstr(status));
2892 TALLOC_FREE(open_rec);
2893 return false;
2895 } else {
2896 id = &zero_id;
2899 ok = push_deferred_open_message_smb(req, max_timeout, *id, open_rec);
2900 if (!ok) {
2901 DBG_WARNING("push_deferred_open_message_smb failed\n");
2902 TALLOC_FREE(open_rec);
2903 return false;
2906 DBG_DEBUG("poll request time [%s] mid [%" PRIu64 "] file_id [%s]\n",
2907 timeval_string(talloc_tos(), &req->request_time, false),
2908 req->mid,
2909 file_id_str_buf(*id, &ftmp));
2911 return true;
2914 static void poll_open_done(struct tevent_req *subreq)
2916 struct deferred_open_record *open_rec = tevent_req_callback_data(
2917 subreq, struct deferred_open_record);
2918 NTSTATUS status;
2919 bool ok;
2921 status = share_mode_watch_recv(subreq, NULL, NULL);
2922 TALLOC_FREE(subreq);
2923 open_rec->watch_req = NULL;
2924 TALLOC_FREE(open_rec->te);
2926 DBG_DEBUG("dbwrap_watched_watch_recv returned %s\n",
2927 nt_errstr(status));
2929 ok = schedule_deferred_open_message_smb(
2930 open_rec->xconn, open_rec->mid);
2931 if (!ok) {
2932 exit_server("schedule_deferred_open_message_smb failed");
2936 bool defer_smb1_sharing_violation(struct smb_request *req)
2938 bool ok;
2939 int timeout_usecs;
2941 if (!lp_defer_sharing_violations()) {
2942 return false;
2946 * Try every 200msec up to (by default) one second. To be
2947 * precise, according to behaviour note <247> in [MS-CIFS],
2948 * the server tries 5 times. But up to one second should be
2949 * close enough.
2952 timeout_usecs = lp_parm_int(
2953 SNUM(req->conn),
2954 "smbd",
2955 "sharedelay",
2956 SHARING_VIOLATION_USEC_WAIT);
2958 ok = setup_poll_open(
2959 req,
2960 NULL,
2961 (struct timeval) { .tv_usec = timeout_usecs },
2962 (struct timeval) { .tv_usec = 200000 });
2963 return ok;
2966 /****************************************************************************
2967 On overwrite open ensure that the attributes match.
2968 ****************************************************************************/
2970 static bool open_match_attributes(connection_struct *conn,
2971 uint32_t old_dos_attr,
2972 uint32_t new_dos_attr,
2973 mode_t new_unx_mode,
2974 mode_t *returned_unx_mode)
2976 uint32_t noarch_old_dos_attr, noarch_new_dos_attr;
2978 noarch_old_dos_attr = (old_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
2979 noarch_new_dos_attr = (new_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
2981 if((noarch_old_dos_attr == 0 && noarch_new_dos_attr != 0) ||
2982 (noarch_old_dos_attr != 0 && ((noarch_old_dos_attr & noarch_new_dos_attr) == noarch_old_dos_attr))) {
2983 *returned_unx_mode = new_unx_mode;
2984 } else {
2985 *returned_unx_mode = (mode_t)0;
2988 DEBUG(10,("open_match_attributes: old_dos_attr = 0x%x, "
2989 "new_dos_attr = 0x%x "
2990 "returned_unx_mode = 0%o\n",
2991 (unsigned int)old_dos_attr,
2992 (unsigned int)new_dos_attr,
2993 (unsigned int)*returned_unx_mode ));
2995 /* If we're mapping SYSTEM and HIDDEN ensure they match. */
2996 if (lp_map_system(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
2997 if ((old_dos_attr & FILE_ATTRIBUTE_SYSTEM) &&
2998 !(new_dos_attr & FILE_ATTRIBUTE_SYSTEM)) {
2999 return False;
3002 if (lp_map_hidden(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
3003 if ((old_dos_attr & FILE_ATTRIBUTE_HIDDEN) &&
3004 !(new_dos_attr & FILE_ATTRIBUTE_HIDDEN)) {
3005 return False;
3008 return True;
3011 static void schedule_defer_open(struct share_mode_lock *lck,
3012 struct file_id id,
3013 struct smb_request *req,
3014 struct blocker_debug_state **blocker_debug_state)
3016 /* This is a relative time, added to the absolute
3017 request_time value to get the absolute timeout time.
3018 Note that if this is the second or greater time we enter
3019 this codepath for this particular request mid then
3020 request_time is left as the absolute time of the *first*
3021 time this request mid was processed. This is what allows
3022 the request to eventually time out. */
3024 struct timeval timeout;
3026 /* Normally the smbd we asked should respond within
3027 * OPLOCK_BREAK_TIMEOUT seconds regardless of whether
3028 * the client did, give twice the timeout as a safety
3029 * measure here in case the other smbd is stuck
3030 * somewhere else. */
3032 timeout = tevent_timeval_set(OPLOCK_BREAK_TIMEOUT * 2, 0);
3034 if (request_timed_out(req, timeout)) {
3035 return;
3038 defer_open(lck, timeout, req, id, blocker_debug_state);
3041 /****************************************************************************
3042 Reschedule an open call that went asynchronous.
3043 ****************************************************************************/
3045 static void schedule_async_open_timer(struct tevent_context *ev,
3046 struct tevent_timer *te,
3047 struct timeval current_time,
3048 void *private_data)
3050 exit_server("async open timeout");
3053 static void schedule_async_open(struct smb_request *req)
3055 struct deferred_open_record *open_rec = NULL;
3056 struct timeval timeout = tevent_timeval_set(20, 0);
3057 bool ok;
3059 if (request_timed_out(req, timeout)) {
3060 return;
3063 open_rec = talloc_zero(NULL, struct deferred_open_record);
3064 if (open_rec == NULL) {
3065 exit_server("deferred_open_record_create failed");
3067 open_rec->async_open = true;
3069 ok = push_deferred_open_message_smb(
3070 req, timeout, (struct file_id){0}, open_rec);
3071 if (!ok) {
3072 exit_server("push_deferred_open_message_smb failed");
3075 open_rec->te = tevent_add_timer(req->sconn->ev_ctx,
3076 req,
3077 timeval_current_ofs(20, 0),
3078 schedule_async_open_timer,
3079 open_rec);
3080 if (open_rec->te == NULL) {
3081 exit_server("tevent_add_timer failed");
3085 static NTSTATUS check_and_store_share_mode(
3086 struct files_struct *fsp,
3087 struct smb_request *req,
3088 struct share_mode_lock *lck,
3089 uint32_t create_disposition,
3090 uint32_t access_mask,
3091 uint32_t open_access_mask,
3092 uint32_t share_access,
3093 int oplock_request,
3094 const struct smb2_lease *lease,
3095 bool first_open_attempt)
3097 NTSTATUS status;
3098 int oplock_type = NO_OPLOCK;
3099 uint32_t granted_lease = 0;
3100 const struct smb2_lease_key *lease_key = NULL;
3101 struct blocker_debug_state *blocker_debug_state = NULL;
3102 bool delete_on_close;
3103 bool ok;
3105 /* Get the types we need to examine. */
3106 if (!validate_oplock_types(lck)) {
3107 smb_panic("validate_oplock_types failed");
3110 delete_on_close = has_delete_on_close(lck, fsp->name_hash);
3111 if (delete_on_close) {
3112 return NT_STATUS_DELETE_PENDING;
3115 status = handle_share_mode_lease(fsp,
3116 lck,
3117 create_disposition,
3118 open_access_mask,
3119 share_access,
3120 oplock_request,
3121 lease,
3122 first_open_attempt,
3123 &oplock_type,
3124 &granted_lease,
3125 &blocker_debug_state);
3126 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
3127 schedule_defer_open(lck, fsp->file_id, req, &blocker_debug_state);
3128 return NT_STATUS_SHARING_VIOLATION;
3130 if (!NT_STATUS_IS_OK(status)) {
3131 return status;
3134 if (oplock_type == LEASE_OPLOCK) {
3135 lease_key = &lease->lease_key;
3138 share_mode_flags_restrict(lck, access_mask, share_access, 0);
3140 ok = set_share_mode(lck,
3141 fsp,
3142 get_current_uid(fsp->conn),
3143 req ? req->mid : 0,
3144 oplock_type,
3145 lease_key,
3146 share_access,
3147 access_mask);
3148 if (!ok) {
3149 return NT_STATUS_NO_MEMORY;
3152 if (oplock_type == LEASE_OPLOCK) {
3153 status = grant_fsp_lease(fsp, lck, lease, granted_lease);
3154 if (!NT_STATUS_IS_OK(status)) {
3155 del_share_mode(lck, fsp);
3156 return status;
3159 DBG_DEBUG("lease_state=%d\n", fsp->lease->lease.lease_state);
3162 fsp->oplock_type = oplock_type;
3164 return NT_STATUS_OK;
3167 /****************************************************************************
3168 Work out what access_mask to use from what the client sent us.
3169 ****************************************************************************/
3171 static NTSTATUS smbd_calculate_maximum_allowed_access_fsp(
3172 struct files_struct *dirfsp,
3173 struct files_struct *fsp,
3174 bool use_privs,
3175 uint32_t *p_access_mask)
3177 struct security_descriptor *sd = NULL;
3178 uint32_t access_granted = 0;
3179 uint32_t dosattrs;
3180 NTSTATUS status;
3182 /* Cope with symlinks */
3183 if (fsp == NULL || fsp_get_pathref_fd(fsp) == -1) {
3184 *p_access_mask = FILE_GENERIC_ALL;
3185 return NT_STATUS_OK;
3188 /* Cope with fake/printer fsp's. */
3189 if (fsp->fake_file_handle != NULL || fsp->print_file != NULL) {
3190 *p_access_mask = FILE_GENERIC_ALL;
3191 return NT_STATUS_OK;
3194 if (!use_privs && (get_current_uid(fsp->conn) == (uid_t)0)) {
3195 *p_access_mask |= FILE_GENERIC_ALL;
3196 return NT_STATUS_OK;
3199 status = SMB_VFS_FGET_NT_ACL(metadata_fsp(fsp),
3200 (SECINFO_OWNER |
3201 SECINFO_GROUP |
3202 SECINFO_DACL),
3203 talloc_tos(),
3204 &sd);
3206 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
3208 * File did not exist
3210 *p_access_mask = FILE_GENERIC_ALL;
3211 return NT_STATUS_OK;
3213 if (!NT_STATUS_IS_OK(status)) {
3214 DBG_ERR("Could not get acl on file %s: %s\n",
3215 fsp_str_dbg(fsp),
3216 nt_errstr(status));
3217 return status;
3221 * If we can access the path to this file, by
3222 * default we have FILE_READ_ATTRIBUTES from the
3223 * containing directory. See the section:
3224 * "Algorithm to Check Access to an Existing File"
3225 * in MS-FSA.pdf.
3227 * se_file_access_check()
3228 * also takes care of owner WRITE_DAC and READ_CONTROL.
3230 status = se_file_access_check(sd,
3231 get_current_nttok(fsp->conn),
3232 use_privs,
3233 (*p_access_mask & ~FILE_READ_ATTRIBUTES),
3234 &access_granted);
3236 TALLOC_FREE(sd);
3238 if (!NT_STATUS_IS_OK(status)) {
3239 DBG_ERR("Status %s on file %s: "
3240 "when calculating maximum access\n",
3241 nt_errstr(status),
3242 fsp_str_dbg(fsp));
3243 return status;
3246 *p_access_mask = (access_granted | FILE_READ_ATTRIBUTES);
3248 if (!(access_granted & DELETE_ACCESS)) {
3249 if (can_delete_file_in_directory(fsp->conn,
3250 dirfsp,
3251 fsp->fsp_name)) {
3252 *p_access_mask |= DELETE_ACCESS;
3256 dosattrs = fdos_mode(fsp);
3257 if ((dosattrs & FILE_ATTRIBUTE_READONLY) || !CAN_WRITE(fsp->conn)) {
3258 *p_access_mask &= ~(FILE_GENERIC_WRITE | DELETE_ACCESS);
3261 return NT_STATUS_OK;
3264 NTSTATUS smbd_calculate_access_mask_fsp(struct files_struct *dirfsp,
3265 struct files_struct *fsp,
3266 bool use_privs,
3267 uint32_t access_mask,
3268 uint32_t *access_mask_out)
3270 NTSTATUS status;
3271 uint32_t orig_access_mask = access_mask;
3272 uint32_t rejected_share_access;
3274 if (access_mask & SEC_MASK_INVALID) {
3275 DBG_DEBUG("access_mask [%8x] contains invalid bits\n",
3276 access_mask);
3277 return NT_STATUS_ACCESS_DENIED;
3281 * Convert GENERIC bits to specific bits.
3284 se_map_generic(&access_mask, &file_generic_mapping);
3286 /* Calculate MAXIMUM_ALLOWED_ACCESS if requested. */
3287 if (access_mask & MAXIMUM_ALLOWED_ACCESS) {
3289 status = smbd_calculate_maximum_allowed_access_fsp(
3290 dirfsp,
3291 fsp,
3292 use_privs,
3293 &access_mask);
3295 if (!NT_STATUS_IS_OK(status)) {
3296 return status;
3299 access_mask &= fsp->conn->share_access;
3302 rejected_share_access = access_mask & ~(fsp->conn->share_access);
3304 if (rejected_share_access) {
3305 DBG_INFO("Access denied on file %s: "
3306 "rejected by share access mask[0x%08X] "
3307 "orig[0x%08X] mapped[0x%08X] reject[0x%08X]\n",
3308 fsp_str_dbg(fsp),
3309 fsp->conn->share_access,
3310 orig_access_mask, access_mask,
3311 rejected_share_access);
3312 return NT_STATUS_ACCESS_DENIED;
3315 *access_mask_out = access_mask;
3316 return NT_STATUS_OK;
3319 /****************************************************************************
3320 Remove the deferred open entry under lock.
3321 ****************************************************************************/
3323 /****************************************************************************
3324 Return true if this is a state pointer to an asynchronous create.
3325 ****************************************************************************/
3327 bool is_deferred_open_async(const struct deferred_open_record *rec)
3329 return rec->async_open;
3332 static bool clear_ads(uint32_t create_disposition)
3334 bool ret = false;
3336 switch (create_disposition) {
3337 case FILE_SUPERSEDE:
3338 case FILE_OVERWRITE_IF:
3339 case FILE_OVERWRITE:
3340 ret = true;
3341 break;
3342 default:
3343 break;
3345 return ret;
3348 static int disposition_to_open_flags(uint32_t create_disposition)
3350 int ret = 0;
3353 * Currently we're using FILE_SUPERSEDE as the same as
3354 * FILE_OVERWRITE_IF but they really are
3355 * different. FILE_SUPERSEDE deletes an existing file
3356 * (requiring delete access) then recreates it.
3359 switch (create_disposition) {
3360 case FILE_SUPERSEDE:
3361 case FILE_OVERWRITE_IF:
3363 * If file exists replace/overwrite. If file doesn't
3364 * exist create.
3366 ret = O_CREAT|O_TRUNC;
3367 break;
3369 case FILE_OPEN:
3371 * If file exists open. If file doesn't exist error.
3373 ret = 0;
3374 break;
3376 case FILE_OVERWRITE:
3378 * If file exists overwrite. If file doesn't exist
3379 * error.
3381 ret = O_TRUNC;
3382 break;
3384 case FILE_CREATE:
3386 * If file exists error. If file doesn't exist create.
3388 ret = O_CREAT|O_EXCL;
3389 break;
3391 case FILE_OPEN_IF:
3393 * If file exists open. If file doesn't exist create.
3395 ret = O_CREAT;
3396 break;
3398 return ret;
3401 static int calculate_open_access_flags(uint32_t access_mask,
3402 uint32_t private_flags,
3403 NTTIME twrp)
3405 bool need_write, need_read;
3408 * Note that we ignore the append flag as append does not
3409 * mean the same thing under DOS and Unix.
3412 if (twrp != 0) {
3414 * Pave over the user requested mode and force O_RDONLY for the
3415 * file handle. Windows allows opening a VSS file with O_RDWR,
3416 * even though actual writes on the handle will fail.
3418 return O_RDONLY;
3421 need_write = (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA));
3422 if (!need_write) {
3423 return O_RDONLY;
3426 /* DENY_DOS opens are always underlying read-write on the
3427 file handle, no matter what the requested access mask
3428 says. */
3430 need_read =
3431 ((private_flags & NTCREATEX_FLAG_DENY_DOS) ||
3432 access_mask & (FILE_READ_ATTRIBUTES|FILE_READ_DATA|
3433 FILE_READ_EA|FILE_EXECUTE));
3435 if (!need_read) {
3436 return O_WRONLY;
3438 return O_RDWR;
3441 struct open_ntcreate_lock_state {
3442 struct share_mode_entry_prepare_state prepare_state;
3443 struct files_struct *fsp;
3444 const char *object_type;
3445 struct smb_request *req;
3446 uint32_t create_disposition;
3447 uint32_t access_mask;
3448 uint32_t open_access_mask;
3449 uint32_t share_access;
3450 int oplock_request;
3451 const struct smb2_lease *lease;
3452 bool first_open_attempt;
3453 bool keep_locked;
3454 NTSTATUS status;
3455 struct timespec write_time;
3456 share_mode_entry_prepare_unlock_fn_t cleanup_fn;
3459 static void open_ntcreate_lock_add_entry(struct share_mode_lock *lck,
3460 bool *keep_locked,
3461 void *private_data)
3463 struct open_ntcreate_lock_state *state =
3464 (struct open_ntcreate_lock_state *)private_data;
3467 * By default drop the g_lock again if we leave the
3468 * tdb chainlock.
3470 *keep_locked = false;
3472 state->status = check_and_store_share_mode(state->fsp,
3473 state->req,
3474 lck,
3475 state->create_disposition,
3476 state->access_mask,
3477 state->open_access_mask,
3478 state->share_access,
3479 state->oplock_request,
3480 state->lease,
3481 state->first_open_attempt);
3482 if (!NT_STATUS_IS_OK(state->status)) {
3483 return;
3486 state->write_time = get_share_mode_write_time(lck);
3489 * keep the g_lock while existing the tdb chainlock,
3490 * we we're asked to, which mean we'll keep
3491 * the share_mode_lock during object creation,
3492 * or setting delete on close.
3494 *keep_locked = state->keep_locked;
3497 static void open_ntcreate_lock_cleanup_oplock(struct share_mode_lock *lck,
3498 void *private_data)
3500 struct open_ntcreate_lock_state *state =
3501 (struct open_ntcreate_lock_state *)private_data;
3502 bool ok;
3504 ok = remove_share_oplock(lck, state->fsp);
3505 if (!ok) {
3506 DBG_ERR("Could not remove oplock for %s %s\n",
3507 state->object_type, fsp_str_dbg(state->fsp));
3511 static void open_ntcreate_lock_cleanup_entry(struct share_mode_lock *lck,
3512 void *private_data)
3514 struct open_ntcreate_lock_state *state =
3515 (struct open_ntcreate_lock_state *)private_data;
3516 bool ok;
3518 ok = del_share_mode(lck, state->fsp);
3519 if (!ok) {
3520 DBG_ERR("Could not delete share entry for %s %s\n",
3521 state->object_type, fsp_str_dbg(state->fsp));
3525 static void possibly_set_archive(struct connection_struct *conn,
3526 struct files_struct *fsp,
3527 struct smb_filename *smb_fname,
3528 struct smb_filename *parent_dir_fname,
3529 int info,
3530 uint32_t dosattrs,
3531 mode_t *unx_mode)
3533 bool set_archive = false;
3534 int ret;
3536 if (info == FILE_WAS_OPENED) {
3537 return;
3540 /* Overwritten files should be initially set as archive */
3541 if ((info == FILE_WAS_OVERWRITTEN && lp_map_archive(SNUM(conn)))) {
3542 set_archive = true;
3543 } else if (lp_store_dos_attributes(SNUM(conn))) {
3544 set_archive = true;
3546 if (!set_archive) {
3547 return;
3550 ret = file_set_dosmode(conn,
3551 smb_fname,
3552 dosattrs | FILE_ATTRIBUTE_ARCHIVE,
3553 parent_dir_fname,
3554 true);
3555 if (ret != 0) {
3556 return;
3558 *unx_mode = smb_fname->st.st_ex_mode;
3561 /****************************************************************************
3562 Open a file with a share mode. Passed in an already created files_struct *.
3563 ****************************************************************************/
3565 static NTSTATUS open_file_ntcreate(connection_struct *conn,
3566 struct smb_request *req,
3567 uint32_t access_mask, /* access bits (FILE_READ_DATA etc.) */
3568 uint32_t share_access, /* share constants (FILE_SHARE_READ etc) */
3569 uint32_t create_disposition, /* FILE_OPEN_IF etc. */
3570 uint32_t create_options, /* options such as delete on close. */
3571 uint32_t new_dos_attributes, /* attributes used for new file. */
3572 int oplock_request, /* internal Samba oplock codes. */
3573 const struct smb2_lease *lease,
3574 /* Information (FILE_EXISTS etc.) */
3575 uint32_t private_flags, /* Samba specific flags. */
3576 struct smb_filename *parent_dir_fname, /* parent. */
3577 struct smb_filename *smb_fname_atname, /* atname relative to parent. */
3578 int *pinfo,
3579 files_struct *fsp)
3581 struct smb_filename *smb_fname = fsp->fsp_name;
3582 int flags=0;
3583 bool file_existed = VALID_STAT(smb_fname->st);
3584 bool def_acl = False;
3585 bool posix_open = False;
3586 bool new_file_created = False;
3587 bool truncated = false;
3588 bool first_open_attempt = true;
3589 bool is_twrp = (smb_fname_atname->twrp != 0);
3590 NTSTATUS fsp_open = NT_STATUS_ACCESS_DENIED;
3591 mode_t new_unx_mode = (mode_t)0;
3592 mode_t unx_mode = (mode_t)0;
3593 int info;
3594 uint32_t existing_dos_attributes = 0;
3595 struct open_ntcreate_lock_state lck_state = {};
3596 bool keep_locked = false;
3597 uint32_t open_access_mask = access_mask;
3598 NTSTATUS status;
3599 SMB_STRUCT_STAT saved_stat = smb_fname->st;
3600 struct timespec old_write_time;
3601 bool setup_poll = false;
3602 NTSTATUS ulstatus;
3604 if (conn->printer) {
3606 * Printers are handled completely differently.
3607 * Most of the passed parameters are ignored.
3610 if (pinfo) {
3611 *pinfo = FILE_WAS_CREATED;
3614 DBG_DEBUG("printer open fname=%s\n",
3615 smb_fname_str_dbg(smb_fname));
3617 if (!req) {
3618 DBG_ERR("printer open without an SMB request!\n");
3619 return NT_STATUS_INTERNAL_ERROR;
3622 return print_spool_open(fsp, smb_fname->base_name,
3623 req->vuid);
3626 if (new_dos_attributes & FILE_FLAG_POSIX_SEMANTICS) {
3627 posix_open = True;
3628 unx_mode = (mode_t)(new_dos_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
3629 new_dos_attributes = 0;
3630 } else {
3631 /* Windows allows a new file to be created and
3632 silently removes a FILE_ATTRIBUTE_DIRECTORY
3633 sent by the client. Do the same. */
3635 new_dos_attributes &= ~FILE_ATTRIBUTE_DIRECTORY;
3637 /* We add FILE_ATTRIBUTE_ARCHIVE to this as this mode is only used if the file is
3638 * created new. */
3639 unx_mode = unix_mode(
3640 conn,
3641 new_dos_attributes | FILE_ATTRIBUTE_ARCHIVE,
3642 smb_fname,
3643 parent_dir_fname->fsp);
3646 DEBUG(10, ("open_file_ntcreate: fname=%s, dos_attrs=0x%x "
3647 "access_mask=0x%x share_access=0x%x "
3648 "create_disposition = 0x%x create_options=0x%x "
3649 "unix mode=0%o oplock_request=%d private_flags = 0x%x\n",
3650 smb_fname_str_dbg(smb_fname), new_dos_attributes,
3651 access_mask, share_access, create_disposition,
3652 create_options, (unsigned int)unx_mode, oplock_request,
3653 (unsigned int)private_flags));
3655 if (req == NULL) {
3656 /* Ensure req == NULL means INTERNAL_OPEN_ONLY */
3657 SMB_ASSERT(oplock_request == INTERNAL_OPEN_ONLY);
3658 } else {
3659 /* And req != NULL means no INTERNAL_OPEN_ONLY */
3660 SMB_ASSERT(((oplock_request & INTERNAL_OPEN_ONLY) == 0));
3664 * Only non-internal opens can be deferred at all
3667 if (req) {
3668 struct deferred_open_record *open_rec;
3669 if (get_deferred_open_message_state(req, NULL, &open_rec)) {
3671 /* If it was an async create retry, the file
3672 didn't exist. */
3674 if (is_deferred_open_async(open_rec)) {
3675 SET_STAT_INVALID(smb_fname->st);
3676 file_existed = false;
3679 /* Ensure we don't reprocess this message. */
3680 remove_deferred_open_message_smb(req->xconn, req->mid);
3682 first_open_attempt = false;
3686 if (!posix_open) {
3687 new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
3688 if (file_existed) {
3690 * Only use stored DOS attributes for checks
3691 * against requested attributes (below via
3692 * open_match_attributes()), cf bug #11992
3693 * for details. -slow
3695 uint32_t attr = 0;
3697 status = SMB_VFS_FGET_DOS_ATTRIBUTES(
3698 conn,
3699 metadata_fsp(smb_fname->fsp),
3700 &attr);
3701 if (NT_STATUS_IS_OK(status)) {
3702 existing_dos_attributes = attr;
3707 /* ignore any oplock requests if oplocks are disabled */
3708 if (!lp_oplocks(SNUM(conn)) ||
3709 IS_VETO_OPLOCK_PATH(conn, smb_fname->base_name)) {
3710 /* Mask off everything except the private Samba bits. */
3711 oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
3714 /* this is for OS/2 long file names - say we don't support them */
3715 if (req != NULL && !req->posix_pathnames &&
3716 strstr(smb_fname->base_name,".+,;=[].")) {
3717 /* OS/2 Workplace shell fix may be main code stream in a later
3718 * release. */
3719 DEBUG(5,("open_file_ntcreate: OS/2 long filenames are not "
3720 "supported.\n"));
3721 if (use_nt_status()) {
3722 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3724 return NT_STATUS_DOS(ERRDOS, ERRcannotopen);
3727 switch( create_disposition ) {
3728 case FILE_OPEN:
3729 /* If file exists open. If file doesn't exist error. */
3730 if (!file_existed) {
3731 DEBUG(5,("open_file_ntcreate: FILE_OPEN "
3732 "requested for file %s and file "
3733 "doesn't exist.\n",
3734 smb_fname_str_dbg(smb_fname)));
3735 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3737 break;
3739 case FILE_OVERWRITE:
3740 /* If file exists overwrite. If file doesn't exist
3741 * error. */
3742 if (!file_existed) {
3743 DEBUG(5,("open_file_ntcreate: FILE_OVERWRITE "
3744 "requested for file %s and file "
3745 "doesn't exist.\n",
3746 smb_fname_str_dbg(smb_fname) ));
3747 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3749 if (is_twrp) {
3750 return NT_STATUS_MEDIA_WRITE_PROTECTED;
3752 break;
3754 case FILE_CREATE:
3755 /* If file exists error. If file doesn't exist
3756 * create. */
3757 if (file_existed) {
3758 DEBUG(5,("open_file_ntcreate: FILE_CREATE "
3759 "requested for file %s and file "
3760 "already exists.\n",
3761 smb_fname_str_dbg(smb_fname)));
3762 if (S_ISDIR(smb_fname->st.st_ex_mode)) {
3763 return NT_STATUS_FILE_IS_A_DIRECTORY;
3765 return NT_STATUS_OBJECT_NAME_COLLISION;
3767 if (is_twrp) {
3768 return NT_STATUS_MEDIA_WRITE_PROTECTED;
3770 break;
3772 case FILE_SUPERSEDE:
3773 case FILE_OVERWRITE_IF:
3774 if (is_twrp) {
3775 return NT_STATUS_MEDIA_WRITE_PROTECTED;
3777 break;
3778 case FILE_OPEN_IF:
3779 if (is_twrp) {
3780 if (!file_existed) {
3781 return NT_STATUS_MEDIA_WRITE_PROTECTED;
3783 create_disposition = FILE_OPEN;
3785 break;
3786 default:
3787 return NT_STATUS_INVALID_PARAMETER;
3790 flags = disposition_to_open_flags(create_disposition);
3792 /* We only care about matching attributes on file exists and
3793 * overwrite. */
3795 if (!posix_open && file_existed &&
3796 ((create_disposition == FILE_OVERWRITE) ||
3797 (create_disposition == FILE_OVERWRITE_IF))) {
3798 if (!open_match_attributes(conn, existing_dos_attributes,
3799 new_dos_attributes,
3800 unx_mode, &new_unx_mode)) {
3801 DEBUG(5,("open_file_ntcreate: attributes mismatch "
3802 "for file %s (%x %x) (0%o, 0%o)\n",
3803 smb_fname_str_dbg(smb_fname),
3804 existing_dos_attributes,
3805 new_dos_attributes,
3806 (unsigned int)smb_fname->st.st_ex_mode,
3807 (unsigned int)unx_mode ));
3808 return NT_STATUS_ACCESS_DENIED;
3812 status = smbd_calculate_access_mask_fsp(parent_dir_fname->fsp,
3813 smb_fname->fsp,
3814 false,
3815 access_mask,
3816 &access_mask);
3817 if (!NT_STATUS_IS_OK(status)) {
3818 DBG_DEBUG("smbd_calculate_access_mask_fsp "
3819 "on file %s returned %s\n",
3820 smb_fname_str_dbg(smb_fname),
3821 nt_errstr(status));
3822 return status;
3825 open_access_mask = access_mask;
3827 if (flags & O_TRUNC) {
3828 open_access_mask |= FILE_WRITE_DATA; /* This will cause oplock breaks. */
3831 if (file_existed) {
3833 * stat opens on existing files don't get oplocks.
3834 * They can get leases.
3836 * Note that we check for stat open on the *open_access_mask*,
3837 * i.e. the access mask we actually used to do the open,
3838 * not the one the client asked for (which is in
3839 * fsp->access_mask). This is due to the fact that
3840 * FILE_OVERWRITE and FILE_OVERWRITE_IF add in O_TRUNC,
3841 * which adds FILE_WRITE_DATA to open_access_mask.
3843 if (is_oplock_stat_open(open_access_mask) && lease == NULL) {
3844 oplock_request = NO_OPLOCK;
3848 DEBUG(10, ("open_file_ntcreate: fname=%s, after mapping "
3849 "access_mask=0x%x\n", smb_fname_str_dbg(smb_fname),
3850 access_mask));
3853 * Note that we ignore the append flag as append does not
3854 * mean the same thing under DOS and Unix.
3857 flags |= calculate_open_access_flags(access_mask,
3858 private_flags,
3859 smb_fname->twrp);
3862 * Currently we only look at FILE_WRITE_THROUGH for create options.
3865 #if defined(O_SYNC)
3866 if ((create_options & FILE_WRITE_THROUGH) && lp_strict_sync(SNUM(conn))) {
3867 flags |= O_SYNC;
3869 #endif /* O_SYNC */
3871 if (posix_open && (access_mask & FILE_APPEND_DATA)) {
3872 flags |= O_APPEND;
3875 if (!posix_open && !CAN_WRITE(conn)) {
3877 * We should really return a permission denied error if either
3878 * O_CREAT or O_TRUNC are set, but for compatibility with
3879 * older versions of Samba we just AND them out.
3881 flags &= ~(O_CREAT | O_TRUNC);
3885 * With kernel oplocks the open breaking an oplock
3886 * blocks until the oplock holder has given up the
3887 * oplock or closed the file. We prevent this by always
3888 * trying to open the file with O_NONBLOCK (see "man
3889 * fcntl" on Linux).
3891 * If a process that doesn't use the smbd open files
3892 * database or communication methods holds a kernel
3893 * oplock we must periodically poll for available open
3894 * using O_NONBLOCK.
3896 flags |= O_NONBLOCK;
3899 * Ensure we can't write on a read-only share or file.
3902 if (((flags & O_ACCMODE) != O_RDONLY) && file_existed &&
3903 (!CAN_WRITE(conn) ||
3904 (existing_dos_attributes & FILE_ATTRIBUTE_READONLY))) {
3905 DEBUG(5,("open_file_ntcreate: write access requested for "
3906 "file %s on read only %s\n",
3907 smb_fname_str_dbg(smb_fname),
3908 !CAN_WRITE(conn) ? "share" : "file" ));
3909 return NT_STATUS_ACCESS_DENIED;
3912 if (VALID_STAT(smb_fname->st)) {
3914 * Only try and create a file id before open
3915 * for an existing file. For a file being created
3916 * this won't do anything useful until the file
3917 * exists and has a valid stat struct.
3919 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
3921 fh_set_private_options(fsp->fh, private_flags);
3922 fsp->access_mask = open_access_mask; /* We change this to the
3923 * requested access_mask after
3924 * the open is done. */
3925 if (posix_open) {
3926 fsp->fsp_flags.posix_open = true;
3929 if ((create_options & FILE_DELETE_ON_CLOSE) && (flags & O_CREAT) &&
3930 !file_existed) {
3931 /* Delete on close semantics for new files. */
3932 status = can_set_delete_on_close(fsp,
3933 new_dos_attributes);
3934 if (!NT_STATUS_IS_OK(status)) {
3935 fd_close(fsp);
3936 return status;
3941 * Ensure we pay attention to default ACLs on directories if required.
3944 if ((flags & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
3945 (def_acl = directory_has_default_acl_fsp(parent_dir_fname->fsp))) {
3946 unx_mode = (0777 & lp_create_mask(SNUM(conn)));
3949 DEBUG(4,
3950 ("calling open_file with flags=0x%X mode=0%o, "
3951 "access_mask = 0x%x, open_access_mask = 0x%x\n",
3952 (unsigned int)flags,
3953 (unsigned int)unx_mode,
3954 (unsigned int)access_mask,
3955 (unsigned int)open_access_mask));
3958 struct vfs_open_how how = {
3959 .flags = flags,
3960 .mode = unx_mode,
3963 if (create_options & FILE_OPEN_FOR_BACKUP_INTENT) {
3964 how.resolve |= VFS_OPEN_HOW_WITH_BACKUP_INTENT;
3967 fsp_open = open_file(req,
3968 parent_dir_fname->fsp,
3969 smb_fname_atname,
3970 fsp,
3971 &how,
3972 access_mask,
3973 open_access_mask,
3974 private_flags,
3975 &new_file_created);
3977 if (NT_STATUS_EQUAL(fsp_open, NT_STATUS_NETWORK_BUSY)) {
3978 if (file_existed && S_ISFIFO(fsp->fsp_name->st.st_ex_mode)) {
3979 DEBUG(10, ("FIFO busy\n"));
3980 return NT_STATUS_NETWORK_BUSY;
3982 if (req == NULL) {
3983 DEBUG(10, ("Internal open busy\n"));
3984 return NT_STATUS_NETWORK_BUSY;
3987 * This handles the kernel oplock case:
3989 * the file has an active kernel oplock and the open() returned
3990 * EWOULDBLOCK/EAGAIN which maps to NETWORK_BUSY.
3992 * "Samba locking.tdb oplocks" are handled below after acquiring
3993 * the sharemode lock with get_share_mode_lock().
3995 setup_poll = true;
3998 if (NT_STATUS_EQUAL(fsp_open, NT_STATUS_RETRY)) {
4000 * EINTR from the open(2) syscall. Just setup a retry
4001 * in a bit. We can't use the sys_write() tight retry
4002 * loop here, as we might have to actually deal with
4003 * lease-break signals to avoid a deadlock.
4005 setup_poll = true;
4008 if (setup_poll) {
4010 * Retry once a second. If there's a share_mode_lock
4011 * around, also wait for it in case it was smbd
4012 * holding that kernel oplock that can quickly tell us
4013 * the oplock got removed.
4016 setup_poll_open(req,
4017 &fsp->file_id,
4018 tevent_timeval_set(OPLOCK_BREAK_TIMEOUT * 2,
4020 tevent_timeval_set(1, 0));
4022 return NT_STATUS_SHARING_VIOLATION;
4025 if (!NT_STATUS_IS_OK(fsp_open)) {
4026 bool wait_for_aio = NT_STATUS_EQUAL(
4027 fsp_open, NT_STATUS_MORE_PROCESSING_REQUIRED);
4028 if (wait_for_aio) {
4029 schedule_async_open(req);
4031 return fsp_open;
4034 if (new_file_created) {
4036 * As we atomically create using O_CREAT|O_EXCL,
4037 * then if new_file_created is true, then
4038 * file_existed *MUST* have been false (even
4039 * if the file was previously detected as being
4040 * there).
4042 file_existed = false;
4045 if (file_existed && !check_same_dev_ino(&saved_stat, &smb_fname->st)) {
4047 * The file did exist, but some other (local or NFS)
4048 * process either renamed/unlinked and re-created the
4049 * file with different dev/ino after we walked the path,
4050 * but before we did the open. We could retry the
4051 * open but it's a rare enough case it's easier to
4052 * just fail the open to prevent creating any problems
4053 * in the open file db having the wrong dev/ino key.
4055 fd_close(fsp);
4056 DBG_WARNING("file %s - dev/ino mismatch. "
4057 "Old (dev=%ju, ino=%ju). "
4058 "New (dev=%ju, ino=%ju). Failing open "
4059 "with NT_STATUS_ACCESS_DENIED.\n",
4060 smb_fname_str_dbg(smb_fname),
4061 (uintmax_t)saved_stat.st_ex_dev,
4062 (uintmax_t)saved_stat.st_ex_ino,
4063 (uintmax_t)smb_fname->st.st_ex_dev,
4064 (uintmax_t)smb_fname->st.st_ex_ino);
4065 return NT_STATUS_ACCESS_DENIED;
4068 old_write_time = smb_fname->st.st_ex_mtime;
4071 * Deal with the race condition where two smbd's detect the
4072 * file doesn't exist and do the create at the same time. One
4073 * of them will win and set a share mode, the other (ie. this
4074 * one) should check if the requested share mode for this
4075 * create is allowed.
4079 * Now the file exists and fsp is successfully opened,
4080 * fsp->dev and fsp->inode are valid and should replace the
4081 * dev=0,inode=0 from a non existent file. Spotted by
4082 * Nadav Danieli <nadavd@exanet.com>. JRA.
4085 if (new_file_created) {
4086 info = FILE_WAS_CREATED;
4087 } else {
4088 if (flags & O_TRUNC) {
4089 info = FILE_WAS_OVERWRITTEN;
4090 } else {
4091 info = FILE_WAS_OPENED;
4096 * If we created a new file, overwrite an existing one
4097 * or going to delete it later, we should keep
4098 * the share_mode_lock (g_lock) until we call
4099 * share_mode_entry_prepare_unlock()
4101 if (info != FILE_WAS_OPENED) {
4102 keep_locked = true;
4103 } else if (create_options & FILE_DELETE_ON_CLOSE) {
4104 keep_locked = true;
4107 lck_state = (struct open_ntcreate_lock_state) {
4108 .fsp = fsp,
4109 .object_type = "file",
4110 .req = req,
4111 .create_disposition = create_disposition,
4112 .access_mask = access_mask,
4113 .open_access_mask = open_access_mask,
4114 .share_access = share_access,
4115 .oplock_request = oplock_request,
4116 .lease = lease,
4117 .first_open_attempt = first_open_attempt,
4118 .keep_locked = keep_locked,
4121 status = share_mode_entry_prepare_lock_add(&lck_state.prepare_state,
4122 fsp->file_id,
4123 conn->connectpath,
4124 smb_fname,
4125 &old_write_time,
4126 open_ntcreate_lock_add_entry,
4127 &lck_state);
4128 if (!NT_STATUS_IS_OK(status)) {
4129 DBG_ERR("share_mode_entry_prepare_lock_add() failed for %s - %s\n",
4130 smb_fname_str_dbg(smb_fname), nt_errstr(status));
4131 fd_close(fsp);
4132 return status;
4135 status = lck_state.status;
4136 if (!NT_STATUS_IS_OK(status)) {
4137 fd_close(fsp);
4138 return status;
4142 * From here we need to use 'goto unlock;' instead of return !!!
4145 if (fsp->oplock_type != NO_OPLOCK && fsp->oplock_type != LEASE_OPLOCK) {
4147 * Now ask for kernel oplocks
4148 * and cleanup on failure.
4150 status = set_file_oplock(fsp);
4151 if (!NT_STATUS_IS_OK(status)) {
4153 * Could not get the kernel oplock
4155 lck_state.cleanup_fn =
4156 open_ntcreate_lock_cleanup_oplock;
4157 fsp->oplock_type = NO_OPLOCK;
4161 /* Should we atomically (to the client at least) truncate ? */
4162 if ((!new_file_created) && (flags & O_TRUNC) &&
4163 (S_ISREG(fsp->fsp_name->st.st_ex_mode))) {
4164 int ret;
4166 ret = SMB_VFS_FTRUNCATE(fsp, 0);
4167 if (ret != 0) {
4168 status = map_nt_error_from_unix(errno);
4169 lck_state.cleanup_fn =
4170 open_ntcreate_lock_cleanup_entry;
4171 goto unlock;
4173 truncated = true;
4177 * We have the share entry *locked*.....
4180 /* Delete streams if create_disposition requires it */
4181 if (!new_file_created &&
4182 clear_ads(create_disposition) &&
4183 !fsp_is_alternate_stream(fsp)) {
4184 status = delete_all_streams(conn, smb_fname);
4185 if (!NT_STATUS_IS_OK(status)) {
4186 lck_state.cleanup_fn =
4187 open_ntcreate_lock_cleanup_entry;
4188 goto unlock;
4192 if (!fsp->fsp_flags.is_pathref &&
4193 fsp_get_io_fd(fsp) != -1 &&
4194 lp_kernel_share_modes(SNUM(conn)))
4196 int ret;
4198 * Beware: streams implementing VFS modules may
4199 * implement streams in a way that fsp will have the
4200 * basefile open in the fsp fd, so lacking a distinct
4201 * fd for the stream the file-system sharemode will
4202 * apply on the basefile which is wrong. The actual
4203 * check is deferred to the VFS module implementing
4204 * the file-system sharemode call.
4206 ret = SMB_VFS_FILESYSTEM_SHAREMODE(fsp,
4207 share_access,
4208 access_mask);
4209 if (ret == -1){
4210 status = NT_STATUS_SHARING_VIOLATION;
4211 lck_state.cleanup_fn =
4212 open_ntcreate_lock_cleanup_entry;
4213 goto unlock;
4216 fsp->fsp_flags.kernel_share_modes_taken = true;
4220 * At this point onwards, we can guarantee that the share entry
4221 * is locked, whether we created the file or not, and that the
4222 * deny mode is compatible with all current opens.
4226 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
4227 * but we don't have to store this - just ignore it on access check.
4229 if (conn_using_smb2(conn->sconn)) {
4231 * SMB2 doesn't return it (according to Microsoft tests).
4232 * Test Case: TestSuite_ScenarioNo009GrantedAccessTestS0
4233 * File created with access = 0x7 (Read, Write, Delete)
4234 * Query Info on file returns 0x87 (Read, Write, Delete, Read Attributes)
4236 fsp->access_mask = access_mask;
4237 } else {
4238 /* But SMB1 does. */
4239 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
4242 if (pinfo) {
4243 *pinfo = info;
4246 /* Handle strange delete on close create semantics. */
4247 if (create_options & FILE_DELETE_ON_CLOSE) {
4248 if (!new_file_created) {
4249 status = can_set_delete_on_close(fsp,
4250 existing_dos_attributes);
4252 if (!NT_STATUS_IS_OK(status)) {
4253 /* Remember to delete the mode we just added. */
4254 lck_state.cleanup_fn =
4255 open_ntcreate_lock_cleanup_entry;
4256 goto unlock;
4259 /* Note that here we set the *initial* delete on close flag,
4260 not the regular one. The magic gets handled in close. */
4261 fsp->fsp_flags.initial_delete_on_close = true;
4264 possibly_set_archive(conn,
4265 fsp,
4266 smb_fname,
4267 parent_dir_fname,
4268 info,
4269 new_dos_attributes,
4270 &smb_fname->st.st_ex_mode);
4272 /* Determine sparse flag. */
4273 if (posix_open) {
4274 /* POSIX opens are sparse by default. */
4275 fsp->fsp_flags.is_sparse = true;
4276 } else {
4277 fsp->fsp_flags.is_sparse =
4278 (existing_dos_attributes & FILE_ATTRIBUTE_SPARSE);
4282 * Take care of inherited ACLs on created files - if default ACL not
4283 * selected.
4286 if (!posix_open && new_file_created && !def_acl) {
4287 if (unx_mode != smb_fname->st.st_ex_mode) {
4288 int ret = SMB_VFS_FCHMOD(fsp, unx_mode);
4289 if (ret == -1) {
4290 DBG_INFO("failed to reset "
4291 "attributes of file %s to 0%o\n",
4292 smb_fname_str_dbg(smb_fname),
4293 (unsigned int)unx_mode);
4297 } else if (new_unx_mode) {
4299 * We only get here in the case of:
4301 * a). Not a POSIX open.
4302 * b). File already existed.
4303 * c). File was overwritten.
4304 * d). Requested DOS attributes didn't match
4305 * the DOS attributes on the existing file.
4307 * In that case new_unx_mode has been set
4308 * equal to the calculated mode (including
4309 * possible inheritance of the mode from the
4310 * containing directory).
4312 * Note this mode was calculated with the
4313 * DOS attribute FILE_ATTRIBUTE_ARCHIVE added,
4314 * so the mode change here is suitable for
4315 * an overwritten file.
4318 if (new_unx_mode != smb_fname->st.st_ex_mode) {
4319 int ret = SMB_VFS_FCHMOD(fsp, new_unx_mode);
4320 if (ret == -1) {
4321 DBG_INFO("failed to reset "
4322 "attributes of file %s to 0%o\n",
4323 smb_fname_str_dbg(smb_fname),
4324 (unsigned int)new_unx_mode);
4330 * Deal with other opens having a modified write time.
4332 if (fsp_getinfo_ask_sharemode(fsp) &&
4333 !is_omit_timespec(&lck_state.write_time))
4335 update_stat_ex_mtime(&fsp->fsp_name->st, lck_state.write_time);
4338 status = NT_STATUS_OK;
4340 unlock:
4341 ulstatus = share_mode_entry_prepare_unlock(&lck_state.prepare_state,
4342 lck_state.cleanup_fn,
4343 &lck_state);
4344 if (!NT_STATUS_IS_OK(ulstatus)) {
4345 DBG_ERR("share_mode_entry_prepare_unlock() failed for %s - %s\n",
4346 smb_fname_str_dbg(smb_fname), nt_errstr(ulstatus));
4347 smb_panic("share_mode_entry_prepare_unlock() failed!");
4350 if (info == FILE_WAS_CREATED) {
4351 notify_fname(conn,
4352 NOTIFY_ACTION_ADDED |
4353 NOTIFY_ACTION_DIRLEASE_BREAK,
4354 FILE_NOTIFY_CHANGE_FILE_NAME,
4355 smb_fname,
4356 fsp_get_smb2_lease(fsp));
4358 if (truncated) {
4359 notify_fname(fsp->conn,
4360 NOTIFY_ACTION_MODIFIED |
4361 NOTIFY_ACTION_DIRLEASE_BREAK,
4362 FILE_NOTIFY_CHANGE_SIZE |
4363 FILE_NOTIFY_CHANGE_ATTRIBUTES,
4364 fsp->fsp_name,
4365 fsp_get_smb2_lease(fsp));
4367 if (!NT_STATUS_IS_OK(status)) {
4368 fd_close(fsp);
4369 return status;
4372 return NT_STATUS_OK;
4375 static NTSTATUS apply_new_nt_acl(struct files_struct *dirfsp,
4376 struct files_struct *fsp,
4377 struct security_descriptor *sd)
4379 NTSTATUS status;
4381 if (sd != NULL) {
4383 * According to the MS documentation, the only time the security
4384 * descriptor is applied to the opened file is iff we *created* the
4385 * file; an existing file stays the same.
4387 * Also, it seems (from observation) that you can open the file with
4388 * any access mask but you can still write the sd. We need to override
4389 * the granted access before we call set_sd
4390 * Patch for bug #2242 from Tom Lackemann <cessnatomny@yahoo.com>.
4393 uint32_t sec_info_sent;
4394 uint32_t saved_access_mask = fsp->access_mask;
4396 sec_info_sent = get_sec_info(sd);
4398 fsp->access_mask = FILE_GENERIC_ALL;
4400 if (sec_info_sent & (SECINFO_OWNER|
4401 SECINFO_GROUP|
4402 SECINFO_DACL|
4403 SECINFO_SACL)) {
4404 status = set_sd(fsp, sd, sec_info_sent);
4405 } else {
4406 status = NT_STATUS_OK;
4409 fsp->access_mask = saved_access_mask;
4411 if (!NT_STATUS_IS_OK(status)) {
4412 DBG_WARNING("set_sd() failed for '%s': %s\n",
4413 fsp_str_dbg(fsp), nt_errstr(status));
4414 return status;
4417 return NT_STATUS_OK;
4420 if (!lp_inherit_acls(SNUM(fsp->conn))) {
4421 return NT_STATUS_OK;
4424 /* Inherit from parent. Errors here are not fatal. */
4425 status = inherit_new_acl(dirfsp, fsp);
4426 if (!NT_STATUS_IS_OK(status)) {
4427 DBG_WARNING("inherit_new_acl failed for %s with %s\n",
4428 fsp_str_dbg(fsp), nt_errstr(status));
4431 return NT_STATUS_OK;
4434 bool smbd_is_tmpname(const char *n, int *_unlink_flags)
4436 const char *p = n;
4437 int unlink_flags = INT_MAX;
4438 struct server_id id;
4439 bool exists;
4441 if (_unlink_flags != NULL) {
4442 *_unlink_flags = INT_MAX;
4445 if (!IS_SMBD_TMPNAME_PREFIX(n)) {
4446 return false;
4448 p += sizeof(SMBD_TMPNAME_PREFIX) - 1;
4449 switch (p[0]) {
4450 case 'D':
4451 unlink_flags = AT_REMOVEDIR;
4452 break;
4453 default:
4454 return false;
4456 p += 1;
4457 if (p[0] != ':') {
4458 return false;
4460 p += 1;
4462 id = server_id_from_string_ex(get_my_vnn(), '%', p);
4463 if (id.pid == UINT64_MAX) {
4464 return false;
4466 if (id.unique_id == 0) {
4467 return false;
4469 if (id.unique_id == SERVERID_UNIQUE_ID_NOT_TO_VERIFY) {
4470 return false;
4473 if (_unlink_flags == NULL) {
4474 return true;
4477 exists = serverid_exists(&id);
4478 if (!exists) {
4480 * let the caller know it's stale
4481 * and should be removed
4483 *_unlink_flags = unlink_flags;
4486 return true;
4489 static NTSTATUS mkdir_internal(connection_struct *conn,
4490 struct smb_filename *parent_dir_fname, /* parent. */
4491 struct smb_filename *smb_fname_atname, /* atname relative to parent. */
4492 struct smb_filename *smb_dname, /* full pathname from root of share. */
4493 struct security_descriptor *sd,
4494 uint32_t file_attributes,
4495 struct files_struct *fsp)
4497 TALLOC_CTX *frame = talloc_stackframe();
4498 const struct loadparm_substitution *lp_sub =
4499 loadparm_s3_global_substitution();
4500 mode_t mode;
4501 NTSTATUS status;
4502 bool posix_open = false;
4503 bool need_re_stat = false;
4504 uint32_t access_mask = SEC_DIR_ADD_SUBDIR;
4505 struct smb_filename *first_atname = NULL;
4506 struct smb_filename *tmp_atname = NULL;
4507 char *orig_dname = NULL;
4508 char *tmp_dname = NULL;
4509 int vfs_use_tmp = lp_vfs_mkdir_use_tmp_name(SNUM(conn));
4510 bool need_tmpname = false;
4511 struct server_id id = messaging_server_id(conn->sconn->msg_ctx);
4512 struct server_id_buf idbuf;
4513 char *idstr = server_id_str_buf_unique_ex(id, '%', &idbuf);
4514 struct vfs_open_how how = { .flags = O_RDONLY|O_DIRECTORY, };
4515 struct vfs_rename_how rhow = { .flags = VFS_RENAME_HOW_NO_REPLACE, };
4516 int ret;
4518 if (!CAN_WRITE(conn) || (access_mask & ~(conn->share_access))) {
4519 DBG_INFO("failing share access %s\n",
4520 lp_servicename(talloc_tos(), lp_sub, SNUM(conn)));
4521 TALLOC_FREE(frame);
4522 return NT_STATUS_ACCESS_DENIED;
4525 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
4526 posix_open = true;
4527 mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
4528 } else {
4529 mode = unix_mode(conn,
4530 FILE_ATTRIBUTE_DIRECTORY,
4531 smb_dname,
4532 parent_dir_fname->fsp);
4535 status = check_parent_access_fsp(parent_dir_fname->fsp, access_mask);
4536 if(!NT_STATUS_IS_OK(status)) {
4537 DBG_INFO("check_parent_access_fsp "
4538 "on directory %s for path %s returned %s\n",
4539 smb_fname_str_dbg(parent_dir_fname),
4540 smb_dname->base_name,
4541 nt_errstr(status));
4542 TALLOC_FREE(frame);
4543 return status;
4546 if (lp_inherit_acls(SNUM(conn))) {
4547 if (directory_has_default_acl_fsp(parent_dir_fname->fsp)) {
4548 mode = (0777 & lp_directory_mask(SNUM(conn)));
4550 need_tmpname = true;
4551 } else if (lp_store_dos_attributes(SNUM(conn))) {
4552 need_tmpname = true;
4553 } else if (lp_inherit_permissions(SNUM(conn))) {
4554 need_tmpname = true;
4555 } else if (lp_inherit_owner(SNUM(conn)) != INHERIT_OWNER_NO) {
4556 need_tmpname = true;
4557 } else if (lp_nt_acl_support(SNUM(conn)) && sd != NULL) {
4558 need_tmpname = true;
4561 if (vfs_use_tmp != Auto) {
4562 need_tmpname = vfs_use_tmp;
4565 if (!need_tmpname) {
4566 first_atname = smb_fname_atname;
4567 goto mkdir_first;
4571 * In order to avoid races where other clients could
4572 * see the directory before it is setup completely
4573 * we use a temporary name and rename it
4574 * when everything is ready.
4577 orig_dname = smb_dname->base_name;
4579 tmp_atname = cp_smb_filename(frame,
4580 smb_fname_atname);
4581 if (tmp_atname == NULL) {
4582 TALLOC_FREE(frame);
4583 return NT_STATUS_NO_MEMORY;
4585 TALLOC_FREE(tmp_atname->base_name);
4586 tmp_atname->base_name = talloc_asprintf(tmp_atname,
4587 "%s%s:%s",
4588 SMBD_TMPDIR_PREFIX,
4589 idstr,
4590 smb_fname_atname->base_name);
4591 if (tmp_atname == NULL) {
4592 TALLOC_FREE(frame);
4593 return NT_STATUS_NO_MEMORY;
4595 SMB_ASSERT(smbd_is_tmpname(tmp_atname->base_name, NULL));
4596 if (!ISDOT(parent_dir_fname->base_name)) {
4597 tmp_dname = talloc_asprintf(frame,
4598 "%s/%s",
4599 parent_dir_fname->base_name,
4600 tmp_atname->base_name);
4601 if (tmp_dname == NULL) {
4602 TALLOC_FREE(frame);
4603 return NT_STATUS_NO_MEMORY;
4605 } else {
4606 tmp_dname = talloc_strdup(frame, tmp_atname->base_name);
4607 if (tmp_dname == NULL) {
4608 TALLOC_FREE(frame);
4609 return NT_STATUS_NO_MEMORY;
4613 smb_dname->base_name = tmp_dname;
4615 DBG_DEBUG("temporary replace '%s' by '%s'\n",
4616 orig_dname, tmp_dname);
4618 first_atname = tmp_atname;
4620 mkdir_first:
4621 ret = SMB_VFS_MKDIRAT(conn,
4622 parent_dir_fname->fsp,
4623 first_atname,
4624 mode);
4625 if (ret != 0) {
4626 status = map_nt_error_from_unix(errno);
4627 DBG_NOTICE("MKDIRAT failed for '%s': %s\n",
4628 smb_fname_str_dbg(smb_dname), nt_errstr(status));
4629 goto restore_orig;
4633 * Make this a pathref fsp for now. open_directory() will reopen as a
4634 * full fsp.
4636 fsp->fsp_flags.is_pathref = true;
4638 status = fd_openat(parent_dir_fname->fsp, first_atname, fsp, &how);
4639 if (!NT_STATUS_IS_OK(status)) {
4640 DBG_ERR("fd_openat() failed for '%s': %s\n",
4641 smb_fname_str_dbg(smb_dname), nt_errstr(status));
4642 goto restore_orig;
4645 /* Ensure we're checking for a symlink here.... */
4646 /* We don't want to get caught by a symlink racer. */
4648 status = vfs_stat_fsp(fsp);
4649 if (!NT_STATUS_IS_OK(status)) {
4650 DBG_ERR("Could not stat directory '%s' just created: %s\n",
4651 smb_fname_str_dbg(smb_dname), nt_errstr(status));
4652 goto restore_orig;
4655 if (!S_ISDIR(smb_dname->st.st_ex_mode)) {
4656 DBG_ERR("Directory '%s' just created is not a directory !\n",
4657 smb_fname_str_dbg(smb_dname));
4658 status = NT_STATUS_NOT_A_DIRECTORY;
4659 goto restore_orig;
4662 if (lp_store_dos_attributes(SNUM(conn))) {
4663 file_set_dosmode(conn,
4664 smb_dname,
4665 file_attributes | FILE_ATTRIBUTE_DIRECTORY,
4666 parent_dir_fname,
4667 true);
4670 if (lp_inherit_permissions(SNUM(conn))) {
4671 inherit_access_posix_acl(conn, parent_dir_fname->fsp,
4672 smb_dname, mode);
4673 need_re_stat = true;
4676 if (!posix_open) {
4678 * Check if high bits should have been set,
4679 * then (if bits are missing): add them.
4680 * Consider bits automagically set by UNIX, i.e. SGID bit from parent
4681 * dir.
4683 if ((mode & ~(S_IRWXU|S_IRWXG|S_IRWXO)) &&
4684 (mode & ~smb_dname->st.st_ex_mode)) {
4685 SMB_VFS_FCHMOD(fsp,
4686 (smb_dname->st.st_ex_mode |
4687 (mode & ~smb_dname->st.st_ex_mode)));
4688 need_re_stat = true;
4692 /* Change the owner if required. */
4693 if (lp_inherit_owner(SNUM(conn)) != INHERIT_OWNER_NO) {
4694 change_dir_owner_to_parent_fsp(parent_dir_fname->fsp,
4695 fsp);
4696 need_re_stat = true;
4699 if (need_re_stat) {
4700 status = vfs_stat_fsp(fsp);
4701 if (!NT_STATUS_IS_OK(status)) {
4702 DBG_ERR("Could not stat directory '%s' just created: %s\n",
4703 smb_fname_str_dbg(smb_dname), nt_errstr(status));
4704 goto restore_orig;
4708 if (lp_nt_acl_support(SNUM(conn))) {
4709 status = apply_new_nt_acl(parent_dir_fname->fsp,
4710 fsp,
4711 sd);
4712 if (!NT_STATUS_IS_OK(status)) {
4713 DBG_WARNING("apply_new_nt_acl() failed for %s with %s\n",
4714 fsp_str_dbg(fsp),
4715 nt_errstr(status));
4716 goto do_unlink;
4720 if (!need_tmpname) {
4721 goto done;
4725 * A rename needs a valid stat for the source,
4726 * see vfs_fruit.c ...
4728 tmp_atname->st = smb_dname->st;
4731 * We first try VFS_RENAME_HOW_NO_REPLACE,
4732 * if it's implemented in the kernel,
4733 * we'll always get EEXIST if the target
4734 * exist, as it's handled at the linux vfs
4735 * layer. But if it doesn't exist we
4736 * can still get EINVAL if the actual
4737 * filesystem doesn't support RENAME_NOREPLACE.
4739 * If the kernel doesn't support rename2()
4740 * we get EINVAL instead of ENOSYS (this
4741 * is mapped in the libreplace replacement
4742 * (as well as the glibc replacement).
4744 ret = SMB_VFS_RENAMEAT(conn,
4745 parent_dir_fname->fsp,
4746 tmp_atname,
4747 parent_dir_fname->fsp,
4748 smb_fname_atname,
4749 &rhow);
4750 if (ret == -1 && errno == EINVAL) {
4752 * This is the strategie we use without having
4753 * renameat2(RENAME_NOREPLACE):
4755 * renameat() is able to replace a directory if the source is
4756 * also a directory.
4758 * So in order to avoid races as much as possible we do a
4759 * mkdirat() with mode 0 in order to catch EEXIST almost
4760 * atomically, when this code runs by two processes at the same
4761 * time.
4763 * Then a renameat() makes the temporary directory available for
4764 * clients.
4766 * This a much smaller window where the other clients may see
4767 * the incomplete directory, which has a mode of 0.
4770 rhow.flags &= ~VFS_RENAME_HOW_NO_REPLACE;
4772 DBG_DEBUG("MKDIRAT/RENAMEAT '%s' -> '%s'\n",
4773 tmp_dname, orig_dname);
4775 ret = SMB_VFS_MKDIRAT(conn,
4776 parent_dir_fname->fsp,
4777 smb_fname_atname,
4779 if (ret != 0) {
4780 status = map_nt_error_from_unix(errno);
4781 DBG_NOTICE("MKDIRAT failed for '%s': %s\n",
4782 orig_dname, nt_errstr(status));
4783 goto do_unlink;
4786 ret = SMB_VFS_RENAMEAT(conn,
4787 parent_dir_fname->fsp,
4788 tmp_atname,
4789 parent_dir_fname->fsp,
4790 smb_fname_atname,
4791 &rhow);
4794 if (ret != 0) {
4795 status = map_nt_error_from_unix(errno);
4796 DBG_NOTICE("RENAMEAT failed for '%s' -> '%s': %s\n",
4797 tmp_dname, orig_dname, nt_errstr(status));
4798 goto do_unlink;
4800 smb_fname_atname->st = tmp_atname->st;
4801 smb_dname->base_name = orig_dname;
4803 done:
4804 DBG_DEBUG("Created directory '%s'\n",
4805 smb_fname_str_dbg(smb_dname));
4807 TALLOC_FREE(frame);
4808 return NT_STATUS_OK;
4810 do_unlink:
4811 DBG_NOTICE("%s: rollback and unlink '%s'\n",
4812 nt_errstr(status),
4813 tmp_dname);
4814 ret = SMB_VFS_UNLINKAT(conn,
4815 parent_dir_fname->fsp,
4816 tmp_atname,
4817 AT_REMOVEDIR);
4818 if (ret == 0) {
4819 DBG_NOTICE("SMB_VFS_UNLINKAT(%s): OK\n",
4820 tmp_dname);
4821 } else {
4822 NTSTATUS status2 = map_nt_error_from_unix(errno);
4823 DBG_WARNING("SMB_VFS_UNLINKAT(%s) ignoring %s\n",
4824 tmp_dname, nt_errstr(status2));
4827 restore_orig:
4828 if (!need_tmpname) {
4829 TALLOC_FREE(frame);
4830 return status;
4832 DBG_NOTICE("%s: restoring '%s' -> '%s'\n",
4833 nt_errstr(status),
4834 tmp_dname,
4835 orig_dname);
4836 SET_STAT_INVALID(smb_fname_atname->st);
4837 smb_dname->base_name = orig_dname;
4838 SET_STAT_INVALID(smb_dname->st);
4839 TALLOC_FREE(frame);
4840 return status;
4843 /****************************************************************************
4844 Open a directory from an NT SMB call.
4845 ****************************************************************************/
4847 static NTSTATUS open_directory(connection_struct *conn,
4848 struct smb_request *req,
4849 uint32_t access_mask,
4850 uint32_t share_access,
4851 uint32_t create_disposition,
4852 uint32_t create_options,
4853 uint32_t file_attributes,
4854 struct smb_filename *parent_dir_fname,
4855 struct smb_filename *smb_fname_atname,
4856 uint32_t oplock_request,
4857 const struct smb2_lease *lease,
4858 struct security_descriptor *sd,
4859 int *pinfo,
4860 struct files_struct *fsp)
4862 struct smb_filename *smb_dname = fsp->fsp_name;
4863 bool dir_existed = VALID_STAT(smb_dname->st);
4864 bool deferred = false;
4865 struct open_ntcreate_lock_state lck_state = {};
4866 bool keep_locked = false;
4867 NTSTATUS status;
4868 struct timespec mtimespec;
4869 int info = 0;
4870 uint32_t need_fd_access;
4871 NTSTATUS ulstatus;
4873 if (is_ntfs_stream_smb_fname(smb_dname)) {
4874 DEBUG(2, ("open_directory: %s is a stream name!\n",
4875 smb_fname_str_dbg(smb_dname)));
4876 return NT_STATUS_NOT_A_DIRECTORY;
4879 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS)) {
4880 /* Ensure we have a directory attribute. */
4881 file_attributes |= FILE_ATTRIBUTE_DIRECTORY;
4884 DBG_INFO("opening directory %s, access_mask = 0x%"PRIx32", "
4885 "share_access = 0x%"PRIx32" create_options = 0x%"PRIx32", "
4886 "create_disposition = 0x%"PRIx32", "
4887 "file_attributes = 0x%"PRIx32"\n",
4888 smb_fname_str_dbg(smb_dname),
4889 access_mask,
4890 share_access,
4891 create_options,
4892 create_disposition,
4893 file_attributes);
4895 if (req == NULL) {
4896 /* Ensure req == NULL means INTERNAL_OPEN_ONLY */
4897 SMB_ASSERT(oplock_request == INTERNAL_OPEN_ONLY);
4898 } else {
4899 /* And req != NULL means no INTERNAL_OPEN_ONLY */
4900 SMB_ASSERT((oplock_request & INTERNAL_OPEN_ONLY) == 0);
4903 if (req != NULL) {
4904 struct deferred_open_record *open_rec = NULL;
4906 deferred = get_deferred_open_message_state(req, NULL, &open_rec);
4907 if (deferred) {
4908 remove_deferred_open_message_smb(req->xconn, req->mid);
4912 status = smbd_calculate_access_mask_fsp(parent_dir_fname->fsp,
4913 smb_dname->fsp,
4914 false,
4915 access_mask,
4916 &access_mask);
4917 if (!NT_STATUS_IS_OK(status)) {
4918 DBG_DEBUG("smbd_calculate_access_mask_fsp "
4919 "on file %s returned %s\n",
4920 smb_fname_str_dbg(smb_dname),
4921 nt_errstr(status));
4922 return status;
4925 if ((access_mask & SEC_FLAG_SYSTEM_SECURITY) &&
4926 !security_token_has_privilege(get_current_nttok(conn),
4927 SEC_PRIV_SECURITY)) {
4928 DEBUG(10, ("open_directory: open on %s "
4929 "failed - SEC_FLAG_SYSTEM_SECURITY denied.\n",
4930 smb_fname_str_dbg(smb_dname)));
4931 return NT_STATUS_PRIVILEGE_NOT_HELD;
4934 switch( create_disposition ) {
4935 case FILE_OPEN:
4937 if (!dir_existed) {
4938 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4941 info = FILE_WAS_OPENED;
4942 break;
4944 case FILE_CREATE:
4946 /* If directory exists error. If directory doesn't
4947 * exist create. */
4949 if (dir_existed) {
4950 status = NT_STATUS_OBJECT_NAME_COLLISION;
4951 DEBUG(2, ("open_directory: unable to create "
4952 "%s. Error was %s\n",
4953 smb_fname_str_dbg(smb_dname),
4954 nt_errstr(status)));
4955 return status;
4958 if (smb_fname_atname->twrp != 0) {
4959 return NT_STATUS_MEDIA_WRITE_PROTECTED;
4962 status = mkdir_internal(conn,
4963 parent_dir_fname,
4964 smb_fname_atname,
4965 smb_dname,
4967 file_attributes,
4968 fsp);
4970 if (!NT_STATUS_IS_OK(status)) {
4971 DEBUG(2, ("open_directory: unable to create "
4972 "%s. Error was %s\n",
4973 smb_fname_str_dbg(smb_dname),
4974 nt_errstr(status)));
4975 return status;
4978 info = FILE_WAS_CREATED;
4979 break;
4981 case FILE_OPEN_IF:
4983 * If directory exists open. If directory doesn't
4984 * exist create.
4987 if (dir_existed) {
4988 status = NT_STATUS_OK;
4989 info = FILE_WAS_OPENED;
4990 } else {
4991 if (smb_fname_atname->twrp != 0) {
4992 return NT_STATUS_MEDIA_WRITE_PROTECTED;
4994 status = mkdir_internal(conn,
4995 parent_dir_fname,
4996 smb_fname_atname,
4997 smb_dname,
4999 file_attributes,
5000 fsp);
5002 if (NT_STATUS_IS_OK(status)) {
5003 info = FILE_WAS_CREATED;
5004 } else {
5005 int ret;
5006 /* Cope with create race. */
5007 if (!NT_STATUS_EQUAL(status,
5008 NT_STATUS_OBJECT_NAME_COLLISION)) {
5009 DEBUG(2, ("open_directory: unable to create "
5010 "%s. Error was %s\n",
5011 smb_fname_str_dbg(smb_dname),
5012 nt_errstr(status)));
5013 return status;
5017 * If mkdir_internal() returned
5018 * NT_STATUS_OBJECT_NAME_COLLISION
5019 * we still must lstat the path.
5021 ret = SMB_VFS_FSTATAT(
5022 conn,
5023 parent_dir_fname->fsp,
5024 smb_fname_atname,
5025 &smb_dname->st,
5026 AT_SYMLINK_NOFOLLOW);
5027 if (ret == -1) {
5028 DEBUG(2, ("Could not stat "
5029 "directory '%s' just "
5030 "opened: %s\n",
5031 smb_fname_str_dbg(
5032 smb_dname),
5033 strerror(errno)));
5034 return map_nt_error_from_unix(
5035 errno);
5038 info = FILE_WAS_OPENED;
5042 break;
5044 case FILE_SUPERSEDE:
5045 case FILE_OVERWRITE:
5046 case FILE_OVERWRITE_IF:
5047 default:
5048 DEBUG(5,("open_directory: invalid create_disposition "
5049 "0x%x for directory %s\n",
5050 (unsigned int)create_disposition,
5051 smb_fname_str_dbg(smb_dname)));
5052 return NT_STATUS_INVALID_PARAMETER;
5055 if(!S_ISDIR(smb_dname->st.st_ex_mode)) {
5056 DEBUG(5,("open_directory: %s is not a directory !\n",
5057 smb_fname_str_dbg(smb_dname)));
5058 return NT_STATUS_NOT_A_DIRECTORY;
5062 * Setup the files_struct for it.
5065 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_dname->st);
5066 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
5067 fsp->file_pid = req ? req->smbpid : 0;
5068 fsp->fsp_flags.can_lock = false;
5069 fsp->fsp_flags.can_read = false;
5070 fsp->fsp_flags.can_write = false;
5072 fh_set_private_options(fsp->fh, 0);
5074 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
5076 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
5077 fsp->print_file = NULL;
5078 fsp->fsp_flags.modified = false;
5079 fsp->oplock_type = NO_OPLOCK;
5080 fsp->sent_oplock_break = NO_BREAK_SENT;
5081 fsp->fsp_flags.is_directory = true;
5082 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
5083 fsp->fsp_flags.posix_open = true;
5086 /* Don't store old timestamps for directory
5087 handles in the internal database. We don't
5088 update them in there if new objects
5089 are created in the directory. Currently
5090 we only update timestamps on file writes.
5091 See bug #9870.
5093 mtimespec = make_omit_timespec();
5096 * Obviously for FILE_LIST_DIRECTORY we need to reopen to get an fd
5097 * usable for reading a directory. SMB2_FLUSH may be called on
5098 * directories opened with FILE_ADD_FILE and FILE_ADD_SUBDIRECTORY so
5099 * for those we need to reopen as well.
5101 need_fd_access =
5102 FILE_LIST_DIRECTORY |
5103 FILE_ADD_FILE |
5104 FILE_ADD_SUBDIRECTORY;
5106 if (access_mask & need_fd_access) {
5107 struct vfs_open_how how = {
5108 .flags = O_RDONLY | O_DIRECTORY,
5110 bool file_created;
5112 status = reopen_from_fsp(parent_dir_fname->fsp,
5113 smb_fname_atname,
5114 fsp,
5115 &how,
5116 &file_created);
5117 if (!NT_STATUS_IS_OK(status)) {
5118 DBG_INFO("Could not open fd for [%s]: %s\n",
5119 smb_fname_str_dbg(smb_dname),
5120 nt_errstr(status));
5121 return status;
5125 status = vfs_stat_fsp(fsp);
5126 if (!NT_STATUS_IS_OK(status)) {
5127 fd_close(fsp);
5128 return status;
5131 if(!S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
5132 DEBUG(5,("open_directory: %s is not a directory !\n",
5133 smb_fname_str_dbg(smb_dname)));
5134 fd_close(fsp);
5135 return NT_STATUS_NOT_A_DIRECTORY;
5138 /* Ensure there was no race condition. We need to check
5139 * dev/inode but not permissions, as these can change
5140 * legitimately */
5141 if (!check_same_dev_ino(&smb_dname->st, &fsp->fsp_name->st)) {
5142 DEBUG(5,("open_directory: stat struct differs for "
5143 "directory %s.\n",
5144 smb_fname_str_dbg(smb_dname)));
5145 fd_close(fsp);
5146 return NT_STATUS_ACCESS_DENIED;
5149 if (info == FILE_WAS_OPENED) {
5150 status = smbd_check_access_rights_fsp(parent_dir_fname->fsp,
5151 fsp,
5152 false,
5153 access_mask);
5154 if (!NT_STATUS_IS_OK(status)) {
5155 DBG_DEBUG("smbd_check_access_rights_fsp on "
5156 "file %s failed with %s\n",
5157 fsp_str_dbg(fsp),
5158 nt_errstr(status));
5159 fd_close(fsp);
5160 return status;
5165 * If we created a new directory or going to delete it later,
5166 * we should keep * the share_mode_lock (g_lock) until we call
5167 * share_mode_entry_prepare_unlock()
5169 if (info != FILE_WAS_OPENED) {
5170 keep_locked = true;
5171 } else if (create_options & FILE_DELETE_ON_CLOSE) {
5172 keep_locked = true;
5175 lck_state = (struct open_ntcreate_lock_state) {
5176 .fsp = fsp,
5177 .object_type = "directory",
5178 .req = req,
5179 .create_disposition = create_disposition,
5180 .access_mask = access_mask,
5181 .open_access_mask = access_mask,
5182 .share_access = share_access,
5183 .oplock_request = oplock_request,
5184 .lease = lease,
5185 .first_open_attempt = !deferred,
5186 .keep_locked = keep_locked,
5189 status = share_mode_entry_prepare_lock_add(&lck_state.prepare_state,
5190 fsp->file_id,
5191 conn->connectpath,
5192 smb_dname,
5193 &mtimespec,
5194 open_ntcreate_lock_add_entry,
5195 &lck_state);
5196 if (!NT_STATUS_IS_OK(status)) {
5197 DBG_ERR("share_mode_entry_prepare_lock_add() failed for %s - %s\n",
5198 smb_fname_str_dbg(smb_dname), nt_errstr(status));
5199 fd_close(fsp);
5200 return status;
5203 status = lck_state.status;
5204 if (!NT_STATUS_IS_OK(status)) {
5205 fd_close(fsp);
5206 return status;
5210 * From here we need to use 'goto unlock;' instead of return !!!
5213 /* For directories the delete on close bit at open time seems
5214 always to be honored on close... See test 19 in Samba4 BASE-DELETE. */
5215 if (create_options & FILE_DELETE_ON_CLOSE) {
5216 status = can_set_delete_on_close(fsp, 0);
5217 if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
5218 lck_state.cleanup_fn =
5219 open_ntcreate_lock_cleanup_entry;
5220 goto unlock;
5223 if (NT_STATUS_IS_OK(status)) {
5224 /* Note that here we set the *initial* delete on close flag,
5225 not the regular one. The magic gets handled in close. */
5226 fsp->fsp_flags.initial_delete_on_close = true;
5231 * Deal with other opens having a modified write time.
5233 if (!is_omit_timespec(&lck_state.write_time)) {
5234 update_stat_ex_mtime(&fsp->fsp_name->st, lck_state.write_time);
5237 if (pinfo) {
5238 *pinfo = info;
5241 status = NT_STATUS_OK;
5243 unlock:
5244 ulstatus = share_mode_entry_prepare_unlock(&lck_state.prepare_state,
5245 lck_state.cleanup_fn,
5246 &lck_state);
5247 if (!NT_STATUS_IS_OK(ulstatus)) {
5248 DBG_ERR("share_mode_entry_prepare_unlock() failed for %s - %s\n",
5249 smb_fname_str_dbg(smb_dname), nt_errstr(ulstatus));
5250 smb_panic("share_mode_entry_prepare_unlock() failed!");
5253 if (info == FILE_WAS_CREATED) {
5254 notify_fname(conn,
5255 NOTIFY_ACTION_ADDED |
5256 NOTIFY_ACTION_DIRLEASE_BREAK,
5257 FILE_NOTIFY_CHANGE_DIR_NAME,
5258 smb_dname,
5259 fsp_get_smb2_lease(fsp));
5262 if (!NT_STATUS_IS_OK(status)) {
5263 fd_close(fsp);
5264 return status;
5267 return NT_STATUS_OK;
5270 NTSTATUS create_directory(connection_struct *conn,
5271 struct smb_request *req,
5272 struct files_struct *dirfsp,
5273 struct smb_filename *smb_dname)
5275 NTSTATUS status;
5276 files_struct *fsp;
5278 status = SMB_VFS_CREATE_FILE(
5279 conn, /* conn */
5280 req, /* req */
5281 dirfsp, /* dirfsp */
5282 smb_dname, /* fname */
5283 FILE_READ_ATTRIBUTES, /* access_mask */
5284 FILE_SHARE_NONE, /* share_access */
5285 FILE_CREATE, /* create_disposition*/
5286 FILE_DIRECTORY_FILE, /* create_options */
5287 FILE_ATTRIBUTE_DIRECTORY, /* file_attributes */
5288 0, /* oplock_request */
5289 NULL, /* lease */
5290 0, /* allocation_size */
5291 0, /* private_flags */
5292 NULL, /* sd */
5293 NULL, /* ea_list */
5294 &fsp, /* result */
5295 NULL, /* pinfo */
5296 NULL, NULL); /* create context */
5298 if (NT_STATUS_IS_OK(status)) {
5299 close_file_free(req, &fsp, NORMAL_CLOSE);
5302 return status;
5305 /****************************************************************************
5306 Receive notification that one of our open files has been renamed by another
5307 smbd process.
5308 ****************************************************************************/
5310 void msg_file_was_renamed(struct messaging_context *msg_ctx,
5311 void *private_data,
5312 uint32_t msg_type,
5313 struct server_id src,
5314 DATA_BLOB *data)
5316 struct file_rename_message *msg = NULL;
5317 enum ndr_err_code ndr_err;
5318 files_struct *fsp;
5319 struct smb_filename *smb_fname = NULL;
5320 struct smbd_server_connection *sconn =
5321 talloc_get_type_abort(private_data,
5322 struct smbd_server_connection);
5324 msg = talloc(talloc_tos(), struct file_rename_message);
5325 if (msg == NULL) {
5326 DBG_WARNING("talloc failed\n");
5327 return;
5330 ndr_err = ndr_pull_struct_blob_all(
5331 data,
5332 msg,
5333 msg,
5334 (ndr_pull_flags_fn_t)ndr_pull_file_rename_message);
5335 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
5336 DBG_DEBUG("ndr_pull_file_rename_message failed: %s\n",
5337 ndr_errstr(ndr_err));
5338 goto out;
5340 if (DEBUGLEVEL >= 10) {
5341 struct server_id_buf buf;
5342 DBG_DEBUG("Got rename message from %s\n",
5343 server_id_str_buf(src, &buf));
5344 NDR_PRINT_DEBUG(file_rename_message, msg);
5347 /* stream_name must always be NULL if there is no stream. */
5348 if ((msg->stream_name != NULL) && (msg->stream_name[0] == '\0')) {
5349 msg->stream_name = NULL;
5352 smb_fname = synthetic_smb_fname(msg,
5353 msg->base_name,
5354 msg->stream_name,
5355 NULL,
5358 if (smb_fname == NULL) {
5359 DBG_DEBUG("synthetic_smb_fname failed\n");
5360 goto out;
5363 fsp = file_find_dif(sconn, msg->id, msg->share_file_id);
5364 if (fsp == NULL) {
5365 DBG_DEBUG("fsp not found\n");
5366 goto out;
5369 if (strcmp(fsp->conn->connectpath, msg->servicepath) == 0) {
5370 SMB_STRUCT_STAT fsp_orig_sbuf;
5371 NTSTATUS status;
5372 DBG_DEBUG("renaming file %s from %s -> %s\n",
5373 fsp_fnum_dbg(fsp),
5374 fsp_str_dbg(fsp),
5375 smb_fname_str_dbg(smb_fname));
5378 * The incoming smb_fname here has an
5379 * invalid stat struct from synthetic_smb_fname()
5380 * above.
5381 * Preserve the existing stat from the
5382 * open fsp after fsp_set_smb_fname()
5383 * overwrites with the invalid stat.
5385 * (We could just copy this into
5386 * smb_fname->st, but keep this code
5387 * identical to the fix in rename_open_files()
5388 * for clarity.
5390 * We will do an fstat before returning
5391 * any of this metadata to the client anyway.
5393 fsp_orig_sbuf = fsp->fsp_name->st;
5394 status = fsp_set_smb_fname(fsp, smb_fname);
5395 if (!NT_STATUS_IS_OK(status)) {
5396 DBG_DEBUG("fsp_set_smb_fname failed: %s\n",
5397 nt_errstr(status));
5399 fsp->fsp_name->st = fsp_orig_sbuf;
5400 } else {
5401 /* TODO. JRA. */
5403 * Now we have the complete path we can work out if
5404 * this is actually within this share and adjust
5405 * newname accordingly.
5407 DBG_DEBUG("share mismatch (sharepath %s not sharepath %s) "
5408 "%s from %s -> %s\n",
5409 fsp->conn->connectpath,
5410 msg->servicepath,
5411 fsp_fnum_dbg(fsp),
5412 fsp_str_dbg(fsp),
5413 smb_fname_str_dbg(smb_fname));
5415 out:
5416 TALLOC_FREE(msg);
5420 * If a main file is opened for delete, all streams need to be checked for
5421 * !FILE_SHARE_DELETE. Do this by opening with DELETE_ACCESS.
5422 * If that works, delete them all by setting the delete on close and close.
5425 static NTSTATUS open_streams_for_delete(connection_struct *conn,
5426 const struct smb_filename *smb_fname)
5428 struct stream_struct *stream_info = NULL;
5429 files_struct **streams = NULL;
5430 int j;
5431 unsigned int i, num_streams = 0;
5432 TALLOC_CTX *frame = talloc_stackframe();
5433 const struct smb_filename *pathref = NULL;
5434 NTSTATUS status;
5436 if (smb_fname->fsp == NULL) {
5437 struct smb_filename *tmp = NULL;
5438 status = synthetic_pathref(frame,
5439 conn->cwd_fsp,
5440 smb_fname->base_name,
5441 NULL,
5442 NULL,
5443 smb_fname->twrp,
5444 smb_fname->flags,
5445 &tmp);
5446 if (!NT_STATUS_IS_OK(status)) {
5447 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
5448 || NT_STATUS_EQUAL(status,
5449 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
5450 DBG_DEBUG("no streams around\n");
5451 TALLOC_FREE(frame);
5452 return NT_STATUS_OK;
5454 DBG_DEBUG("synthetic_pathref failed: %s\n",
5455 nt_errstr(status));
5456 goto fail;
5458 pathref = tmp;
5459 } else {
5460 pathref = smb_fname;
5462 status = vfs_fstreaminfo(pathref->fsp, talloc_tos(),
5463 &num_streams, &stream_info);
5465 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
5466 || NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
5467 DEBUG(10, ("no streams around\n"));
5468 TALLOC_FREE(frame);
5469 return NT_STATUS_OK;
5472 if (!NT_STATUS_IS_OK(status)) {
5473 DEBUG(10, ("vfs_fstreaminfo failed: %s\n",
5474 nt_errstr(status)));
5475 goto fail;
5478 DEBUG(10, ("open_streams_for_delete found %d streams\n",
5479 num_streams));
5481 if (num_streams == 0) {
5482 TALLOC_FREE(frame);
5483 return NT_STATUS_OK;
5486 streams = talloc_array(talloc_tos(), files_struct *, num_streams);
5487 if (streams == NULL) {
5488 DEBUG(0, ("talloc failed\n"));
5489 status = NT_STATUS_NO_MEMORY;
5490 goto fail;
5493 for (i=0; i<num_streams; i++) {
5494 struct smb_filename *smb_fname_cp;
5496 if (strequal(stream_info[i].name, "::$DATA")) {
5497 streams[i] = NULL;
5498 continue;
5501 smb_fname_cp = synthetic_smb_fname(talloc_tos(),
5502 smb_fname->base_name,
5503 stream_info[i].name,
5504 NULL,
5505 smb_fname->twrp,
5506 (smb_fname->flags &
5507 ~SMB_FILENAME_POSIX_PATH));
5508 if (smb_fname_cp == NULL) {
5509 status = NT_STATUS_NO_MEMORY;
5510 goto fail;
5513 status = openat_pathref_fsp(conn->cwd_fsp, smb_fname_cp);
5514 if (!NT_STATUS_IS_OK(status)) {
5515 DBG_DEBUG("Unable to open stream [%s]: %s\n",
5516 smb_fname_str_dbg(smb_fname_cp),
5517 nt_errstr(status));
5518 TALLOC_FREE(smb_fname_cp);
5519 break;
5522 status = SMB_VFS_CREATE_FILE(
5523 conn, /* conn */
5524 NULL, /* req */
5525 NULL, /* dirfsp */
5526 smb_fname_cp, /* fname */
5527 DELETE_ACCESS, /* access_mask */
5528 (FILE_SHARE_READ | /* share_access */
5529 FILE_SHARE_WRITE | FILE_SHARE_DELETE),
5530 FILE_OPEN, /* create_disposition*/
5531 0, /* create_options */
5532 FILE_ATTRIBUTE_NORMAL, /* file_attributes */
5533 0, /* oplock_request */
5534 NULL, /* lease */
5535 0, /* allocation_size */
5536 0, /* private_flags */
5537 NULL, /* sd */
5538 NULL, /* ea_list */
5539 &streams[i], /* result */
5540 NULL, /* pinfo */
5541 NULL, NULL); /* create context */
5543 if (!NT_STATUS_IS_OK(status)) {
5544 DEBUG(10, ("Could not open stream %s: %s\n",
5545 smb_fname_str_dbg(smb_fname_cp),
5546 nt_errstr(status)));
5548 TALLOC_FREE(smb_fname_cp);
5549 break;
5551 TALLOC_FREE(smb_fname_cp);
5555 * don't touch the variable "status" beyond this point :-)
5558 for (j = i-1 ; j >= 0; j--) {
5559 if (streams[j] == NULL) {
5560 continue;
5563 DEBUG(10, ("Closing stream # %d, %s\n", j,
5564 fsp_str_dbg(streams[j])));
5565 close_file_free(NULL, &streams[j], NORMAL_CLOSE);
5568 fail:
5569 TALLOC_FREE(frame);
5570 return status;
5573 /*********************************************************************
5574 Create a default ACL by inheriting from the parent. If no inheritance
5575 from the parent available, don't set anything. This will leave the actual
5576 permissions the new file or directory already got from the filesystem
5577 as the NT ACL when read.
5578 *********************************************************************/
5580 static NTSTATUS inherit_new_acl(files_struct *dirfsp, files_struct *fsp)
5582 TALLOC_CTX *frame = talloc_stackframe();
5583 struct security_descriptor *parent_desc = NULL;
5584 NTSTATUS status = NT_STATUS_OK;
5585 struct security_descriptor *psd = NULL;
5586 const struct dom_sid *owner_sid = NULL;
5587 const struct dom_sid *group_sid = NULL;
5588 uint32_t security_info_sent = (SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL);
5589 struct security_token *token = fsp->conn->session_info->security_token;
5590 bool inherit_owner =
5591 (lp_inherit_owner(SNUM(fsp->conn)) == INHERIT_OWNER_WINDOWS_AND_UNIX);
5592 bool inheritable_components = false;
5593 bool try_builtin_administrators = false;
5594 const struct dom_sid *BA_U_sid = NULL;
5595 const struct dom_sid *BA_G_sid = NULL;
5596 bool try_system = false;
5597 const struct dom_sid *SY_U_sid = NULL;
5598 const struct dom_sid *SY_G_sid = NULL;
5599 size_t size = 0;
5600 bool ok;
5602 status = SMB_VFS_FGET_NT_ACL(dirfsp,
5603 (SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL),
5604 frame,
5605 &parent_desc);
5606 if (!NT_STATUS_IS_OK(status)) {
5607 TALLOC_FREE(frame);
5608 return status;
5611 inheritable_components = sd_has_inheritable_components(parent_desc,
5612 fsp->fsp_flags.is_directory);
5614 if (!inheritable_components && !inherit_owner) {
5615 TALLOC_FREE(frame);
5616 /* Nothing to inherit and not setting owner. */
5617 return NT_STATUS_OK;
5620 /* Create an inherited descriptor from the parent. */
5622 if (DEBUGLEVEL >= 10) {
5623 DEBUG(10,("inherit_new_acl: parent acl for %s is:\n",
5624 fsp_str_dbg(fsp) ));
5625 NDR_PRINT_DEBUG(security_descriptor, parent_desc);
5628 /* Inherit from parent descriptor if "inherit owner" set. */
5629 if (inherit_owner) {
5630 owner_sid = parent_desc->owner_sid;
5631 group_sid = parent_desc->group_sid;
5634 if (owner_sid == NULL) {
5635 if (security_token_has_builtin_administrators(token)) {
5636 try_builtin_administrators = true;
5637 } else if (security_token_is_system(token)) {
5638 try_builtin_administrators = true;
5639 try_system = true;
5643 if (group_sid == NULL &&
5644 token->num_sids == PRIMARY_GROUP_SID_INDEX)
5646 if (security_token_is_system(token)) {
5647 try_builtin_administrators = true;
5648 try_system = true;
5652 if (try_builtin_administrators) {
5653 struct unixid ids = { .id = 0 };
5655 ok = sids_to_unixids(&global_sid_Builtin_Administrators, 1, &ids);
5656 if (ok) {
5657 switch (ids.type) {
5658 case ID_TYPE_BOTH:
5659 BA_U_sid = &global_sid_Builtin_Administrators;
5660 BA_G_sid = &global_sid_Builtin_Administrators;
5661 break;
5662 case ID_TYPE_UID:
5663 BA_U_sid = &global_sid_Builtin_Administrators;
5664 break;
5665 case ID_TYPE_GID:
5666 BA_G_sid = &global_sid_Builtin_Administrators;
5667 break;
5668 default:
5669 break;
5674 if (try_system) {
5675 struct unixid ids = { .id = 0 };
5677 ok = sids_to_unixids(&global_sid_System, 1, &ids);
5678 if (ok) {
5679 switch (ids.type) {
5680 case ID_TYPE_BOTH:
5681 SY_U_sid = &global_sid_System;
5682 SY_G_sid = &global_sid_System;
5683 break;
5684 case ID_TYPE_UID:
5685 SY_U_sid = &global_sid_System;
5686 break;
5687 case ID_TYPE_GID:
5688 SY_G_sid = &global_sid_System;
5689 break;
5690 default:
5691 break;
5696 if (owner_sid == NULL) {
5697 owner_sid = BA_U_sid;
5700 if (owner_sid == NULL) {
5701 owner_sid = SY_U_sid;
5704 if (group_sid == NULL) {
5705 group_sid = SY_G_sid;
5708 if (try_system && group_sid == NULL) {
5709 group_sid = BA_G_sid;
5712 if (owner_sid == NULL) {
5713 owner_sid = &token->sids[PRIMARY_USER_SID_INDEX];
5715 if (group_sid == NULL) {
5716 if (token->num_sids == PRIMARY_GROUP_SID_INDEX) {
5717 group_sid = &token->sids[PRIMARY_USER_SID_INDEX];
5718 } else {
5719 group_sid = &token->sids[PRIMARY_GROUP_SID_INDEX];
5723 status = se_create_child_secdesc(frame,
5724 &psd,
5725 &size,
5726 parent_desc,
5727 owner_sid,
5728 group_sid,
5729 fsp->fsp_flags.is_directory);
5730 if (!NT_STATUS_IS_OK(status)) {
5731 TALLOC_FREE(frame);
5732 return status;
5735 /* If inheritable_components == false,
5736 se_create_child_secdesc()
5737 creates a security descriptor with a NULL dacl
5738 entry, but with SEC_DESC_DACL_PRESENT. We need
5739 to remove that flag. */
5741 if (!inheritable_components) {
5742 security_info_sent &= ~SECINFO_DACL;
5743 psd->type &= ~SEC_DESC_DACL_PRESENT;
5746 if (DEBUGLEVEL >= 10) {
5747 DEBUG(10,("inherit_new_acl: child acl for %s is:\n",
5748 fsp_str_dbg(fsp) ));
5749 NDR_PRINT_DEBUG(security_descriptor, psd);
5752 if (inherit_owner) {
5753 /* We need to be root to force this. */
5754 become_root();
5756 status = SMB_VFS_FSET_NT_ACL(metadata_fsp(fsp),
5757 security_info_sent,
5758 psd);
5759 if (inherit_owner) {
5760 unbecome_root();
5762 TALLOC_FREE(frame);
5763 return status;
5767 * If we already have a lease, it must match the new file id. [MS-SMB2]
5768 * 3.3.5.9.8 speaks about INVALID_PARAMETER if an already used lease key is
5769 * used for a different file name.
5772 struct lease_match_state {
5773 /* Input parameters. */
5774 TALLOC_CTX *mem_ctx;
5775 const char *servicepath;
5776 const struct smb_filename *fname;
5777 bool file_existed;
5778 struct file_id id;
5779 /* Return parameters. */
5780 uint32_t num_file_ids;
5781 struct file_id *ids;
5782 NTSTATUS match_status;
5785 /*************************************************************
5786 File doesn't exist but this lease key+guid is already in use.
5788 This is only allowable in the dynamic share case where the
5789 service path must be different.
5791 There is a small race condition here in the multi-connection
5792 case where a client sends two create calls on different connections,
5793 where the file doesn't exist and one smbd creates the leases_db
5794 entry first, but this will get fixed by the multichannel cleanup
5795 when all identical client_guids get handled by a single smbd.
5796 **************************************************************/
5798 static void lease_match_parser_new_file(
5799 uint32_t num_files,
5800 const struct leases_db_file *files,
5801 struct lease_match_state *state)
5803 uint32_t i;
5805 for (i = 0; i < num_files; i++) {
5806 const struct leases_db_file *f = &files[i];
5807 if (strequal(state->servicepath, f->servicepath)) {
5808 state->match_status = NT_STATUS_INVALID_PARAMETER;
5809 return;
5813 /* Dynamic share case. Break leases on all other files. */
5814 state->match_status = leases_db_copy_file_ids(state->mem_ctx,
5815 num_files,
5816 files,
5817 &state->ids);
5818 if (!NT_STATUS_IS_OK(state->match_status)) {
5819 return;
5822 state->num_file_ids = num_files;
5823 state->match_status = NT_STATUS_OPLOCK_NOT_GRANTED;
5824 return;
5827 static void lease_match_parser(
5828 uint32_t num_files,
5829 const struct leases_db_file *files,
5830 void *private_data)
5832 struct lease_match_state *state =
5833 (struct lease_match_state *)private_data;
5834 uint32_t i;
5836 if (!state->file_existed) {
5838 * Deal with name mismatch or
5839 * possible dynamic share case separately
5840 * to make code clearer.
5842 lease_match_parser_new_file(num_files,
5843 files,
5844 state);
5845 return;
5848 /* File existed. */
5849 state->match_status = NT_STATUS_OK;
5851 for (i = 0; i < num_files; i++) {
5852 const struct leases_db_file *f = &files[i];
5854 /* Everything should be the same. */
5855 if (!file_id_equal(&state->id, &f->id)) {
5857 * The client asked for a lease on a
5858 * file that doesn't match the file_id
5859 * in the database.
5861 * Maybe this is a dynamic share, i.e.
5862 * a share where the servicepath is
5863 * different for different users (e.g.
5864 * the [HOMES] share.
5866 * If the servicepath is different, but the requested
5867 * file name + stream name is the same then this is
5868 * a dynamic share, the client is using the same share
5869 * name and doesn't know that the underlying servicepath
5870 * is different. It was expecting a lease on the
5871 * same file. Return NT_STATUS_OPLOCK_NOT_GRANTED
5872 * to break leases
5874 * Otherwise the client has messed up, or is
5875 * testing our error codes, so return
5876 * NT_STATUS_INVALID_PARAMETER.
5878 if (!strequal(f->servicepath, state->servicepath) &&
5879 strequal(f->base_name, state->fname->base_name) &&
5880 strequal(f->stream_name, state->fname->stream_name))
5883 * Name is the same but servicepath is
5884 * different, dynamic share. Break leases.
5886 state->match_status =
5887 NT_STATUS_OPLOCK_NOT_GRANTED;
5888 } else {
5889 state->match_status =
5890 NT_STATUS_INVALID_PARAMETER;
5892 break;
5894 if (!strequal(f->servicepath, state->servicepath)) {
5895 state->match_status = NT_STATUS_INVALID_PARAMETER;
5896 break;
5898 if (!strequal(f->base_name, state->fname->base_name)) {
5899 state->match_status = NT_STATUS_INVALID_PARAMETER;
5900 break;
5902 if (!strequal(f->stream_name, state->fname->stream_name)) {
5903 state->match_status = NT_STATUS_INVALID_PARAMETER;
5904 break;
5908 if (NT_STATUS_IS_OK(state->match_status)) {
5910 * Common case - just opening another handle on a
5911 * file on a non-dynamic share.
5913 return;
5916 if (NT_STATUS_EQUAL(state->match_status, NT_STATUS_INVALID_PARAMETER)) {
5917 /* Mismatched path. Error back to client. */
5918 return;
5922 * File id mismatch. Dynamic share case NT_STATUS_OPLOCK_NOT_GRANTED.
5923 * Don't allow leases.
5926 state->match_status = leases_db_copy_file_ids(state->mem_ctx,
5927 num_files,
5928 files,
5929 &state->ids);
5930 if (!NT_STATUS_IS_OK(state->match_status)) {
5931 return;
5934 state->num_file_ids = num_files;
5935 state->match_status = NT_STATUS_OPLOCK_NOT_GRANTED;
5936 return;
5939 struct lease_match_break_state {
5940 struct messaging_context *msg_ctx;
5941 const struct smb2_lease_key *lease_key;
5942 struct file_id id;
5944 bool found_lease;
5945 uint16_t version;
5946 uint16_t epoch;
5949 static bool lease_match_break_fn(
5950 struct share_mode_entry *e,
5951 void *private_data)
5953 struct lease_match_break_state *state = private_data;
5954 bool stale, equal;
5955 uint32_t e_lease_type = SMB2_LEASE_NONE;
5956 NTSTATUS status;
5958 stale = share_entry_stale_pid(e);
5959 if (stale) {
5960 return false;
5963 equal = smb2_lease_key_equal(&e->lease_key, state->lease_key);
5964 if (!equal) {
5965 return false;
5968 status = leases_db_get(
5969 &e->client_guid,
5970 &e->lease_key,
5971 &state->id,
5972 &e_lease_type, /* current_state */
5973 NULL, /* breaking */
5974 NULL, /* breaking_to_requested */
5975 NULL, /* breaking_to_required */
5976 &state->version, /* lease_version */
5977 &state->epoch); /* epoch */
5978 if (NT_STATUS_IS_OK(status)) {
5979 state->found_lease = true;
5980 } else {
5981 DBG_WARNING("Could not find version/epoch: %s\n",
5982 nt_errstr(status));
5983 return false;
5986 if (e_lease_type == SMB2_LEASE_NONE) {
5987 return false;
5989 send_break_message(state->msg_ctx, &state->id, e, SMB2_LEASE_NONE);
5992 * Windows 7 and 8 lease clients are broken in that they will
5993 * not respond to lease break requests whilst waiting for an
5994 * outstanding open request on that lease handle on the same
5995 * TCP connection, due to holding an internal inode lock.
5997 * This means we can't reschedule ourselves here, but must
5998 * return from the create.
6000 * Work around:
6002 * Send the breaks and then return SMB2_LEASE_NONE in the
6003 * lease handle to cause them to acknowledge the lease
6004 * break. Consultation with Microsoft engineering confirmed
6005 * this approach is safe.
6008 return false;
6011 static void lease_match_fid_fn(struct share_mode_lock *lck,
6012 void *private_data)
6014 bool ok;
6016 ok = share_mode_forall_leases(lck, lease_match_break_fn, private_data);
6017 if (!ok) {
6018 DBG_DEBUG("share_mode_forall_leases failed\n");
6022 static NTSTATUS lease_match(connection_struct *conn,
6023 struct smb_request *req,
6024 const struct smb2_lease_key *lease_key,
6025 const char *servicepath,
6026 const struct smb_filename *fname,
6027 uint16_t *p_version,
6028 uint16_t *p_epoch)
6030 struct smbd_server_connection *sconn = req->sconn;
6031 TALLOC_CTX *tos = talloc_tos();
6032 struct lease_match_state state = {
6033 .mem_ctx = tos,
6034 .servicepath = servicepath,
6035 .fname = fname,
6036 .match_status = NT_STATUS_OK
6038 uint32_t i;
6039 NTSTATUS status;
6041 state.file_existed = VALID_STAT(fname->st);
6042 if (state.file_existed) {
6043 state.id = vfs_file_id_from_sbuf(conn, &fname->st);
6046 status = leases_db_parse(&sconn->client->global->client_guid,
6047 lease_key, lease_match_parser, &state);
6048 if (!NT_STATUS_IS_OK(status)) {
6050 * Not found or error means okay: We can make the lease pass
6052 return NT_STATUS_OK;
6054 if (!NT_STATUS_EQUAL(state.match_status, NT_STATUS_OPLOCK_NOT_GRANTED)) {
6056 * Anything but NT_STATUS_OPLOCK_NOT_GRANTED, let the caller
6057 * deal with it.
6059 return state.match_status;
6062 /* We have to break all existing leases. */
6063 for (i = 0; i < state.num_file_ids; i++) {
6064 struct lease_match_break_state break_state = {
6065 .msg_ctx = conn->sconn->msg_ctx,
6066 .lease_key = lease_key,
6069 if (file_id_equal(&state.ids[i], &state.id)) {
6070 /* Don't need to break our own file. */
6071 continue;
6074 break_state.id = state.ids[i];
6076 status = share_mode_do_locked_vfs_denied(break_state.id,
6077 lease_match_fid_fn,
6078 &break_state);
6079 if (!NT_STATUS_IS_OK(status)) {
6080 /* Race condition - file already closed. */
6081 continue;
6084 if (break_state.found_lease) {
6085 *p_version = break_state.version;
6086 *p_epoch = break_state.epoch;
6090 * Ensure we don't grant anything more so we
6091 * never upgrade.
6093 return NT_STATUS_OPLOCK_NOT_GRANTED;
6097 * Wrapper around open_file_ntcreate and open_directory
6100 static NTSTATUS create_file_unixpath(connection_struct *conn,
6101 struct smb_request *req,
6102 struct files_struct *dirfsp,
6103 struct smb_filename *smb_fname,
6104 uint32_t access_mask,
6105 uint32_t share_access,
6106 uint32_t create_disposition,
6107 uint32_t create_options,
6108 uint32_t file_attributes,
6109 uint32_t oplock_request,
6110 const struct smb2_lease *lease,
6111 uint64_t allocation_size,
6112 uint32_t private_flags,
6113 struct security_descriptor *sd,
6114 struct ea_list *ea_list,
6116 files_struct **result,
6117 int *pinfo)
6119 struct smb2_lease none_lease;
6120 int info = FILE_WAS_OPENED;
6121 files_struct *base_fsp = NULL;
6122 files_struct *fsp = NULL;
6123 bool free_fsp_on_error = false;
6124 NTSTATUS status;
6125 int ret;
6126 struct smb_filename *parent_dir_fname = NULL;
6127 struct smb_filename *smb_fname_atname = NULL;
6129 DBG_DEBUG("access_mask = 0x%"PRIx32" "
6130 "file_attributes = 0x%"PRIx32" "
6131 "share_access = 0x%"PRIx32" "
6132 "create_disposition = 0x%"PRIx32" "
6133 "create_options = 0x%"PRIx32" "
6134 "oplock_request = 0x%"PRIx32" "
6135 "private_flags = 0x%"PRIx32" "
6136 "ea_list = %p, "
6137 "sd = %p, "
6138 "fname = %s\n",
6139 access_mask,
6140 file_attributes,
6141 share_access,
6142 create_disposition,
6143 create_options,
6144 oplock_request,
6145 private_flags,
6146 ea_list,
6148 smb_fname_str_dbg(smb_fname));
6150 if (create_options & FILE_OPEN_BY_FILE_ID) {
6151 status = NT_STATUS_NOT_SUPPORTED;
6152 goto fail;
6155 if (create_options & NTCREATEX_OPTIONS_INVALID_PARAM_MASK) {
6156 status = NT_STATUS_INVALID_PARAMETER;
6157 goto fail;
6160 if (!(create_options & FILE_OPEN_REPARSE_POINT) &&
6161 (smb_fname->fsp != NULL) && /* new files don't have an fsp */
6162 VALID_STAT(smb_fname->fsp->fsp_name->st))
6164 mode_t type = (smb_fname->fsp->fsp_name->st.st_ex_mode &
6165 S_IFMT);
6167 switch (type) {
6168 case S_IFREG:
6169 FALL_THROUGH;
6170 case S_IFDIR:
6171 break;
6172 case S_IFLNK:
6174 * We should never get this far with a symlink
6175 * "as such". Report as not existing.
6177 status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
6178 goto fail;
6179 default:
6180 status = NT_STATUS_IO_REPARSE_TAG_NOT_HANDLED;
6181 goto fail;
6185 if (req == NULL) {
6186 oplock_request |= INTERNAL_OPEN_ONLY;
6189 if (lease != NULL) {
6190 uint16_t epoch = lease->lease_epoch;
6191 uint16_t version = lease->lease_version;
6193 if (req == NULL) {
6194 DBG_WARNING("Got lease on internal open\n");
6195 status = NT_STATUS_INTERNAL_ERROR;
6196 goto fail;
6199 status = lease_match(conn,
6200 req,
6201 &lease->lease_key,
6202 conn->connectpath,
6203 smb_fname,
6204 &version,
6205 &epoch);
6206 if (NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) {
6207 /* Dynamic share file. No leases and update epoch... */
6208 none_lease = *lease;
6209 none_lease.lease_state = SMB2_LEASE_NONE;
6210 none_lease.lease_epoch = epoch;
6211 none_lease.lease_version = version;
6212 lease = &none_lease;
6213 } else if (!NT_STATUS_IS_OK(status)) {
6214 goto fail;
6218 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
6219 && (access_mask & DELETE_ACCESS)
6220 && !is_named_stream(smb_fname)) {
6222 * We can't open a file with DELETE access if any of the
6223 * streams is open without FILE_SHARE_DELETE
6225 status = open_streams_for_delete(conn, smb_fname);
6227 if (!NT_STATUS_IS_OK(status)) {
6228 goto fail;
6232 if (access_mask & SEC_FLAG_SYSTEM_SECURITY) {
6233 bool ok;
6235 ok = security_token_has_privilege(get_current_nttok(conn),
6236 SEC_PRIV_SECURITY);
6237 if (!ok) {
6238 DBG_DEBUG("open on %s failed - "
6239 "SEC_FLAG_SYSTEM_SECURITY denied.\n",
6240 smb_fname_str_dbg(smb_fname));
6241 status = NT_STATUS_PRIVILEGE_NOT_HELD;
6242 goto fail;
6245 if (conn_using_smb2(conn->sconn) &&
6246 (access_mask == SEC_FLAG_SYSTEM_SECURITY))
6249 * No other bits set. Windows SMB2 refuses this.
6250 * See smbtorture3 SMB2-SACL test.
6252 * Note this is an SMB2-only behavior,
6253 * smbtorture3 SMB1-SYSTEM-SECURITY already tests
6254 * that SMB1 allows this.
6256 status = NT_STATUS_ACCESS_DENIED;
6257 goto fail;
6262 * Files or directories can't be opened DELETE_ON_CLOSE without
6263 * delete access.
6264 * BUG: https://bugzilla.samba.org/show_bug.cgi?id=13358
6266 if ((create_options & FILE_DELETE_ON_CLOSE) &&
6267 ((access_mask & DELETE_ACCESS) == 0)) {
6268 status = NT_STATUS_INVALID_PARAMETER;
6269 goto fail;
6272 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
6273 && is_named_stream(smb_fname))
6275 uint32_t base_create_disposition;
6276 struct smb_filename *smb_fname_base = NULL;
6277 uint32_t base_privflags;
6279 if (create_options & FILE_DIRECTORY_FILE) {
6280 DBG_DEBUG("Can't open a stream as directory\n");
6281 status = NT_STATUS_NOT_A_DIRECTORY;
6282 goto fail;
6285 switch (create_disposition) {
6286 case FILE_OPEN:
6287 base_create_disposition = FILE_OPEN;
6288 break;
6289 default:
6290 base_create_disposition = FILE_OPEN_IF;
6291 break;
6294 smb_fname_base = cp_smb_filename_nostream(
6295 talloc_tos(), smb_fname);
6297 if (smb_fname_base == NULL) {
6298 status = NT_STATUS_NO_MEMORY;
6299 goto fail;
6303 * We may be creating the basefile as part of creating the
6304 * stream, so it's legal if the basefile doesn't exist at this
6305 * point, the create_file_unixpath() below will create it. But
6306 * if the basefile exists we want a handle so we can fstat() it.
6309 ret = vfs_stat(conn, smb_fname_base);
6310 if (ret == -1 && errno != ENOENT) {
6311 status = map_nt_error_from_unix(errno);
6312 TALLOC_FREE(smb_fname_base);
6313 goto fail;
6315 if (ret == 0) {
6316 status = openat_pathref_fsp(conn->cwd_fsp,
6317 smb_fname_base);
6318 if (!NT_STATUS_IS_OK(status)) {
6319 DBG_ERR("open_smb_fname_fsp [%s] failed: %s\n",
6320 smb_fname_str_dbg(smb_fname_base),
6321 nt_errstr(status));
6322 TALLOC_FREE(smb_fname_base);
6323 goto fail;
6327 * https://bugzilla.samba.org/show_bug.cgi?id=10229
6328 * We need to check if the requested access mask
6329 * could be used to open the underlying file (if
6330 * it existed), as we're passing in zero for the
6331 * access mask to the base filename.
6333 status = check_base_file_access(smb_fname_base->fsp,
6334 access_mask);
6336 if (!NT_STATUS_IS_OK(status)) {
6337 DEBUG(10, ("Permission check "
6338 "for base %s failed: "
6339 "%s\n", smb_fname->base_name,
6340 nt_errstr(status)));
6341 TALLOC_FREE(smb_fname_base);
6342 goto fail;
6346 base_privflags = NTCREATEX_FLAG_STREAM_BASEOPEN;
6348 /* Open the base file. */
6349 status = create_file_unixpath(conn,
6350 NULL,
6351 dirfsp,
6352 smb_fname_base,
6354 FILE_SHARE_READ
6355 | FILE_SHARE_WRITE
6356 | FILE_SHARE_DELETE,
6357 base_create_disposition,
6361 NULL,
6363 base_privflags,
6364 NULL,
6365 NULL,
6366 &base_fsp,
6367 NULL);
6368 TALLOC_FREE(smb_fname_base);
6370 if (!NT_STATUS_IS_OK(status)) {
6371 DEBUG(10, ("create_file_unixpath for base %s failed: "
6372 "%s\n", smb_fname->base_name,
6373 nt_errstr(status)));
6374 goto fail;
6378 if (smb_fname->fsp != NULL) {
6380 fsp = smb_fname->fsp;
6383 * We're about to use smb_fname->fsp for the fresh open.
6385 * Every fsp passed in via smb_fname->fsp already
6386 * holds a fsp->fsp_name. If it is already this
6387 * fsp->fsp_name that we got passed in as our input
6388 * argument smb_fname, these two are assumed to have
6389 * the same lifetime: Every fsp hangs of "conn", and
6390 * fsp->fsp_name is its talloc child.
6393 if (smb_fname != smb_fname->fsp->fsp_name) {
6395 * "smb_fname" is temporary in this case, but
6396 * the destructor of smb_fname would also tear
6397 * down the fsp we're about to use. Unlink
6398 * them from each other.
6400 smb_fname_fsp_unlink(smb_fname);
6403 * "fsp" is ours now
6405 free_fsp_on_error = true;
6408 status = fsp_bind_smb(fsp, req);
6409 if (!NT_STATUS_IS_OK(status)) {
6410 goto fail;
6413 if (fsp_is_alternate_stream(fsp)) {
6414 struct files_struct *tmp_base_fsp = fsp->base_fsp;
6416 fsp_set_base_fsp(fsp, NULL);
6418 fd_close(tmp_base_fsp);
6419 file_free(NULL, tmp_base_fsp);
6421 } else {
6423 * No fsp passed in that we can use, create one
6425 status = file_new(req, conn, &fsp);
6426 if(!NT_STATUS_IS_OK(status)) {
6427 goto fail;
6429 free_fsp_on_error = true;
6431 status = fsp_set_smb_fname(fsp, smb_fname);
6432 if (!NT_STATUS_IS_OK(status)) {
6433 goto fail;
6437 SMB_ASSERT(fsp->fsp_name->fsp != NULL);
6438 SMB_ASSERT(fsp->fsp_name->fsp == fsp);
6440 if (base_fsp) {
6442 * We're opening the stream element of a
6443 * base_fsp we already opened. Set up the
6444 * base_fsp pointer.
6446 fsp_set_base_fsp(fsp, base_fsp);
6449 if (dirfsp != NULL) {
6450 status = SMB_VFS_PARENT_PATHNAME(
6451 conn,
6452 talloc_tos(),
6453 smb_fname,
6454 &parent_dir_fname,
6455 &smb_fname_atname);
6456 if (!NT_STATUS_IS_OK(status)) {
6457 goto fail;
6459 } else {
6461 * Get a pathref on the parent. We can re-use this for
6462 * multiple calls to check parent ACLs etc. to avoid
6463 * pathname calls.
6465 status = parent_pathref(talloc_tos(),
6466 conn->cwd_fsp,
6467 smb_fname,
6468 &parent_dir_fname,
6469 &smb_fname_atname);
6470 if (!NT_STATUS_IS_OK(status)) {
6471 goto fail;
6474 dirfsp = parent_dir_fname->fsp;
6475 status = fsp_set_smb_fname(dirfsp, parent_dir_fname);
6476 if (!NT_STATUS_IS_OK(status)) {
6477 goto fail;
6482 * If it's a request for a directory open, deal with it separately.
6485 if (create_options & FILE_DIRECTORY_FILE) {
6487 if (create_options & FILE_NON_DIRECTORY_FILE) {
6488 status = NT_STATUS_INVALID_PARAMETER;
6489 goto fail;
6492 /* Can't open a temp directory. IFS kit test. */
6493 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
6494 (file_attributes & FILE_ATTRIBUTE_TEMPORARY)) {
6495 status = NT_STATUS_INVALID_PARAMETER;
6496 goto fail;
6500 * We will get a create directory here if the Win32
6501 * app specified a security descriptor in the
6502 * CreateDirectory() call.
6505 status = open_directory(conn,
6506 req,
6507 access_mask,
6508 share_access,
6509 create_disposition,
6510 create_options,
6511 file_attributes,
6512 dirfsp->fsp_name,
6513 smb_fname_atname,
6514 oplock_request,
6515 lease,
6517 &info,
6518 fsp);
6519 } else {
6522 * Ordinary file case.
6525 if (allocation_size) {
6526 fsp->initial_allocation_size = smb_roundup(fsp->conn,
6527 allocation_size);
6530 status = open_file_ntcreate(conn,
6531 req,
6532 access_mask,
6533 share_access,
6534 create_disposition,
6535 create_options,
6536 file_attributes,
6537 oplock_request,
6538 lease,
6539 private_flags,
6540 dirfsp->fsp_name,
6541 smb_fname_atname,
6542 &info,
6543 fsp);
6544 if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
6546 /* A stream open never opens a directory */
6548 if (base_fsp) {
6549 status = NT_STATUS_FILE_IS_A_DIRECTORY;
6550 goto fail;
6554 * Fail the open if it was explicitly a non-directory
6555 * file.
6558 if (create_options & FILE_NON_DIRECTORY_FILE) {
6559 status = NT_STATUS_FILE_IS_A_DIRECTORY;
6560 goto fail;
6563 status = open_directory(conn,
6564 req,
6565 access_mask,
6566 share_access,
6567 create_disposition,
6568 create_options,
6569 file_attributes,
6570 dirfsp->fsp_name,
6571 smb_fname_atname,
6572 oplock_request,
6573 lease,
6575 &info,
6576 fsp);
6580 if (!NT_STATUS_IS_OK(status)) {
6581 goto fail;
6584 fsp->fsp_flags.is_fsa = true;
6586 if ((ea_list != NULL) &&
6587 ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN))) {
6588 status = set_ea(conn, fsp, ea_list);
6589 if (!NT_STATUS_IS_OK(status)) {
6590 goto fail;
6594 if (!fsp->fsp_flags.is_directory &&
6595 S_ISDIR(fsp->fsp_name->st.st_ex_mode))
6597 status = NT_STATUS_ACCESS_DENIED;
6598 goto fail;
6601 /* Save the requested allocation size. */
6602 if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
6603 if ((allocation_size > (uint64_t)fsp->fsp_name->st.st_ex_size)
6604 && !(fsp->fsp_flags.is_directory))
6606 fsp->initial_allocation_size = smb_roundup(
6607 fsp->conn, allocation_size);
6608 if (vfs_allocate_file_space(
6609 fsp, fsp->initial_allocation_size) == -1) {
6610 status = NT_STATUS_DISK_FULL;
6611 goto fail;
6613 } else {
6614 fsp->initial_allocation_size = smb_roundup(
6615 fsp->conn, (uint64_t)fsp->fsp_name->st.st_ex_size);
6617 } else {
6618 fsp->initial_allocation_size = 0;
6621 if ((info == FILE_WAS_CREATED) &&
6622 !S_ISDIR(fsp->fsp_name->st.st_ex_mode) &&
6623 lp_nt_acl_support(SNUM(conn)) &&
6624 !fsp_is_alternate_stream(fsp)) {
6625 status = apply_new_nt_acl(dirfsp, fsp, sd);
6626 if (!NT_STATUS_IS_OK(status)) {
6627 DBG_WARNING("apply_new_nt_acl(): failed for %s with %s\n",
6628 fsp_str_dbg(fsp), nt_errstr(status));
6629 goto fail;
6633 if ((conn->fs_capabilities & FILE_FILE_COMPRESSION)
6634 && (create_options & FILE_NO_COMPRESSION)
6635 && (info == FILE_WAS_CREATED)) {
6636 status = SMB_VFS_SET_COMPRESSION(conn, fsp, fsp,
6637 COMPRESSION_FORMAT_NONE);
6638 if (!NT_STATUS_IS_OK(status)) {
6639 DEBUG(1, ("failed to disable compression: %s\n",
6640 nt_errstr(status)));
6644 DEBUG(10, ("create_file_unixpath: info=%d\n", info));
6646 *result = fsp;
6647 if (pinfo != NULL) {
6648 *pinfo = info;
6651 smb_fname->st = fsp->fsp_name->st;
6653 TALLOC_FREE(parent_dir_fname);
6655 return NT_STATUS_OK;
6657 fail:
6658 DEBUG(10, ("create_file_unixpath: %s\n", nt_errstr(status)));
6660 if (fsp != NULL) {
6662 * The close_file below will close
6663 * fsp->base_fsp.
6665 base_fsp = NULL;
6666 close_file_smb(req, fsp, ERROR_CLOSE);
6667 if (free_fsp_on_error) {
6668 file_free(req, fsp);
6669 fsp = NULL;
6672 if (base_fsp != NULL) {
6673 close_file_free(req, &base_fsp, ERROR_CLOSE);
6676 TALLOC_FREE(parent_dir_fname);
6678 return status;
6681 static NTSTATUS check_posix_create_context(connection_struct *conn,
6682 struct smb_request *req,
6683 const struct smb2_create_blobs *in_context_blobs,
6684 uint32_t create_options,
6685 uint32_t *file_attributes)
6687 uint32_t wire_mode_bits = 0;
6688 NTSTATUS status;
6689 mode_t mode_bits = 0;
6690 SMB_STRUCT_STAT sbuf = { 0 };
6691 struct smb2_create_blob *posx = NULL;
6693 if (req == NULL || !req->posix_pathnames) {
6694 return NT_STATUS_OK;
6697 posx = smb2_create_blob_find(
6698 in_context_blobs, SMB2_CREATE_TAG_POSIX);
6699 if (posx == NULL) {
6700 return NT_STATUS_OK;
6703 if (posx->data.length != 4) {
6704 return NT_STATUS_INVALID_PARAMETER;
6707 wire_mode_bits = IVAL(posx->data.data, 0);
6708 status = unix_perms_from_wire(conn,
6709 &sbuf,
6710 wire_mode_bits,
6711 &mode_bits);
6712 if (!NT_STATUS_IS_OK(status)) {
6713 return status;
6715 if (create_options & FILE_DIRECTORY_FILE) {
6716 mode_bits = apply_conf_dir_mask(conn, mode_bits);
6717 } else {
6718 mode_bits = apply_conf_file_mask(conn, mode_bits);
6721 * Remove type info from mode, leaving only the
6722 * permissions and setuid/gid bits.
6724 mode_bits &= ~S_IFMT;
6726 *file_attributes = (FILE_FLAG_POSIX_SEMANTICS | mode_bits);
6728 return NT_STATUS_OK;
6731 NTSTATUS create_file_default(connection_struct *conn,
6732 struct smb_request *req,
6733 struct files_struct *dirfsp,
6734 struct smb_filename *smb_fname,
6735 uint32_t access_mask,
6736 uint32_t share_access,
6737 uint32_t create_disposition,
6738 uint32_t create_options,
6739 uint32_t file_attributes,
6740 uint32_t oplock_request,
6741 const struct smb2_lease *lease,
6742 uint64_t allocation_size,
6743 uint32_t private_flags,
6744 struct security_descriptor *sd,
6745 struct ea_list *ea_list,
6746 files_struct **result,
6747 int *pinfo,
6748 const struct smb2_create_blobs *in_context_blobs,
6749 struct smb2_create_blobs *out_context_blobs)
6751 int info = FILE_WAS_OPENED;
6752 files_struct *fsp = NULL;
6753 NTSTATUS status;
6754 bool stream_name = false;
6756 DBG_DEBUG("access_mask = 0x%" PRIu32
6757 " file_attributes = 0x%" PRIu32
6758 " share_access = 0x%" PRIu32
6759 " create_disposition = 0x%" PRIu32
6760 " create_options = 0x%" PRIu32
6761 " oplock_request = 0x%" PRIu32
6762 " private_flags = 0x%" PRIu32
6763 " ea_list = %p, sd = %p, fname = %s\n",
6764 access_mask,
6765 file_attributes,
6766 share_access,
6767 create_disposition,
6768 create_options,
6769 oplock_request,
6770 private_flags,
6771 ea_list,
6773 smb_fname_str_dbg(smb_fname));
6775 if (req != NULL) {
6777 * Remember the absolute time of the original request
6778 * with this mid. We'll use it later to see if this
6779 * has timed out.
6781 get_deferred_open_message_state(req, &req->request_time, NULL);
6785 * Check to see if this is a mac fork of some kind.
6788 stream_name = is_ntfs_stream_smb_fname(smb_fname);
6789 if (stream_name) {
6790 enum FAKE_FILE_TYPE fake_file_type;
6792 fake_file_type = is_fake_file(smb_fname);
6794 if (req != NULL && fake_file_type != FAKE_FILE_TYPE_NONE) {
6797 * Here we go! support for changing the disk quotas
6798 * --metze
6800 * We need to fake up to open this MAGIC QUOTA file
6801 * and return a valid FID.
6803 * w2k close this file directly after opening xp
6804 * also tries a QUERY_FILE_INFO on the file and then
6805 * close it
6807 status = open_fake_file(req, conn, req->vuid,
6808 fake_file_type, smb_fname,
6809 access_mask, &fsp);
6810 if (!NT_STATUS_IS_OK(status)) {
6811 goto fail;
6814 ZERO_STRUCT(smb_fname->st);
6815 goto done;
6818 if (!(conn->fs_capabilities & FILE_NAMED_STREAMS)) {
6819 status = NT_STATUS_OBJECT_NAME_INVALID;
6820 goto fail;
6824 if (is_ntfs_default_stream_smb_fname(smb_fname)) {
6825 int ret;
6826 /* We have to handle this error here. */
6827 if (create_options & FILE_DIRECTORY_FILE) {
6828 status = NT_STATUS_NOT_A_DIRECTORY;
6829 goto fail;
6831 ret = vfs_stat(conn, smb_fname);
6832 if (ret == 0 && VALID_STAT_OF_DIR(smb_fname->st)) {
6833 status = NT_STATUS_FILE_IS_A_DIRECTORY;
6834 goto fail;
6838 status = check_posix_create_context(conn,
6839 req,
6840 in_context_blobs,
6841 create_options,
6842 &file_attributes);
6843 if (!NT_STATUS_IS_OK(status)) {
6844 goto fail;
6847 status = create_file_unixpath(conn,
6848 req,
6849 dirfsp,
6850 smb_fname,
6851 access_mask,
6852 share_access,
6853 create_disposition,
6854 create_options,
6855 file_attributes,
6856 oplock_request,
6857 lease,
6858 allocation_size,
6859 private_flags,
6861 ea_list,
6862 &fsp,
6863 &info);
6864 if (!NT_STATUS_IS_OK(status)) {
6865 goto fail;
6868 done:
6869 DEBUG(10, ("create_file: info=%d\n", info));
6871 *result = fsp;
6872 if (pinfo != NULL) {
6873 *pinfo = info;
6875 return NT_STATUS_OK;
6877 fail:
6878 DEBUG(10, ("create_file: %s\n", nt_errstr(status)));
6880 if (fsp != NULL) {
6881 close_file_free(req, &fsp, ERROR_CLOSE);
6883 return status;