ctdb-common: Map ENOENT for a missing event script to ENOEXEC
[samba.git] / source3 / smbd / open.c
blob909fbac505ddcaaca653d40b840f3496ee6b78d9
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 (S_ISLNK(smb_fname->st.st_ex_mode) &&
1220 !posix_open)
1223 * Don't allow stat opens on symlinks directly unless
1224 * it's a POSIX open. Match the return code from
1225 * openat_pathref_fsp().
1227 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1230 if (!fsp->fsp_flags.is_pathref) {
1232 * There is only one legit case where end up here:
1233 * openat_pathref_fsp() failed to open a symlink, so the
1234 * fsp was created by fsp_new() which doesn't set
1235 * is_pathref. Other than that, we should always have a
1236 * pathref fsp at this point. The subsequent checks
1237 * assert this.
1239 if (!(smb_fname->flags & SMB_FILENAME_POSIX_PATH)) {
1240 DBG_ERR("[%s] is not a POSIX pathname\n",
1241 smb_fname_str_dbg(smb_fname));
1242 return NT_STATUS_INTERNAL_ERROR;
1244 if (!S_ISLNK(smb_fname->st.st_ex_mode)) {
1245 DBG_ERR("[%s] is not a symlink\n",
1246 smb_fname_str_dbg(smb_fname));
1247 return NT_STATUS_INTERNAL_ERROR;
1249 if (fsp_get_pathref_fd(fsp) != -1) {
1250 DBG_ERR("fd for [%s] is not -1: fd [%d]\n",
1251 smb_fname_str_dbg(smb_fname),
1252 fsp_get_pathref_fd(fsp));
1253 return NT_STATUS_INTERNAL_ERROR;
1258 * Access to streams is checked by checking the basefile and
1259 * that has already been checked by check_base_file_access()
1260 * in create_file_unixpath().
1262 if (!fsp_is_alternate_stream(fsp)) {
1263 status = smbd_check_access_rights_fsp(dirfsp,
1264 fsp,
1265 false,
1266 open_access_mask);
1268 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) &&
1269 posix_open &&
1270 S_ISLNK(smb_fname->st.st_ex_mode)) {
1271 /* This is a POSIX stat open for delete
1272 * or rename on a symlink that points
1273 * nowhere. Allow. */
1274 DEBUG(10,("open_file: allowing POSIX "
1275 "open on bad symlink %s\n",
1276 smb_fname_str_dbg(smb_fname)));
1277 status = NT_STATUS_OK;
1280 if (!NT_STATUS_IS_OK(status)) {
1281 DBG_DEBUG("smbd_check_access_rights_fsp on file "
1282 "%s returned %s\n",
1283 fsp_str_dbg(fsp),
1284 nt_errstr(status));
1285 return status;
1290 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
1291 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
1292 fsp->file_pid = req ? req->smbpid : 0;
1293 fsp->fsp_flags.can_lock = true;
1294 fsp->fsp_flags.can_read = ((access_mask & FILE_READ_DATA) != 0);
1295 fsp->fsp_flags.can_write =
1296 CAN_WRITE(conn) &&
1297 ((access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) != 0);
1298 if (fsp->fsp_name->twrp != 0) {
1299 fsp->fsp_flags.can_write = false;
1301 fsp->print_file = NULL;
1302 fsp->fsp_flags.modified = false;
1303 fsp->sent_oplock_break = NO_BREAK_SENT;
1304 fsp->fsp_flags.is_directory = false;
1305 if (is_in_path(smb_fname->base_name,
1306 conn->aio_write_behind_list,
1307 posix_open ? true : conn->case_sensitive)) {
1308 fsp->fsp_flags.aio_write_behind = true;
1311 DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
1312 conn->session_info->unix_info->unix_name,
1313 smb_fname_str_dbg(smb_fname),
1314 BOOLSTR(fsp->fsp_flags.can_read),
1315 BOOLSTR(fsp->fsp_flags.can_write),
1316 conn->num_files_open));
1318 return NT_STATUS_OK;
1321 static bool mask_conflict(
1322 uint32_t new_access,
1323 uint32_t existing_access,
1324 uint32_t access_mask,
1325 uint32_t new_sharemode,
1326 uint32_t existing_sharemode,
1327 uint32_t sharemode_mask)
1329 bool want_access = (new_access & access_mask);
1330 bool allow_existing = (existing_sharemode & sharemode_mask);
1331 bool have_access = (existing_access & access_mask);
1332 bool allow_new = (new_sharemode & sharemode_mask);
1334 if (want_access && !allow_existing) {
1335 DBG_DEBUG("Access request 0x%"PRIx32"/0x%"PRIx32" conflicts "
1336 "with existing sharemode 0x%"PRIx32"/0x%"PRIx32"\n",
1337 new_access,
1338 access_mask,
1339 existing_sharemode,
1340 sharemode_mask);
1341 return true;
1343 if (have_access && !allow_new) {
1344 DBG_DEBUG("Sharemode request 0x%"PRIx32"/0x%"PRIx32" conflicts "
1345 "with existing access 0x%"PRIx32"/0x%"PRIx32"\n",
1346 new_sharemode,
1347 sharemode_mask,
1348 existing_access,
1349 access_mask);
1350 return true;
1352 return false;
1355 /****************************************************************************
1356 Check if we can open a file with a share mode.
1357 Returns True if conflict, False if not.
1358 ****************************************************************************/
1360 static const uint32_t conflicting_access =
1361 FILE_WRITE_DATA|
1362 FILE_APPEND_DATA|
1363 FILE_READ_DATA|
1364 FILE_EXECUTE|
1365 DELETE_ACCESS;
1367 static bool share_conflict(uint32_t e_access_mask,
1368 uint32_t e_share_access,
1369 uint32_t access_mask,
1370 uint32_t share_access)
1372 bool conflict;
1374 DBG_DEBUG("existing access_mask = 0x%"PRIx32", "
1375 "existing share access = 0x%"PRIx32", "
1376 "access_mask = 0x%"PRIx32", "
1377 "share_access = 0x%"PRIx32"\n",
1378 e_access_mask,
1379 e_share_access,
1380 access_mask,
1381 share_access);
1383 if ((e_access_mask & conflicting_access) == 0) {
1384 DBG_DEBUG("No conflict due to "
1385 "existing access_mask = 0x%"PRIx32"\n",
1386 e_access_mask);
1387 return false;
1389 if ((access_mask & conflicting_access) == 0) {
1390 DBG_DEBUG("No conflict due to access_mask = 0x%"PRIx32"\n",
1391 access_mask);
1392 return false;
1395 conflict = mask_conflict(
1396 access_mask, e_access_mask, FILE_WRITE_DATA | FILE_APPEND_DATA,
1397 share_access, e_share_access, FILE_SHARE_WRITE);
1398 conflict |= mask_conflict(
1399 access_mask, e_access_mask, FILE_READ_DATA | FILE_EXECUTE,
1400 share_access, e_share_access, FILE_SHARE_READ);
1401 conflict |= mask_conflict(
1402 access_mask, e_access_mask, DELETE_ACCESS,
1403 share_access, e_share_access, FILE_SHARE_DELETE);
1405 DBG_DEBUG("conflict=%s\n", conflict ? "true" : "false");
1406 return conflict;
1409 #if defined(DEVELOPER)
1411 struct validate_my_share_entries_state {
1412 struct smbd_server_connection *sconn;
1413 struct file_id fid;
1414 struct server_id self;
1417 static bool validate_my_share_entries_fn(
1418 struct share_mode_entry *e,
1419 bool *modified,
1420 void *private_data)
1422 struct validate_my_share_entries_state *state = private_data;
1423 files_struct *fsp;
1425 if (!server_id_equal(&state->self, &e->pid)) {
1426 return false;
1429 if (e->op_mid == 0) {
1430 /* INTERNAL_OPEN_ONLY */
1431 return false;
1434 fsp = file_find_dif(state->sconn, state->fid, e->share_file_id);
1435 if (!fsp) {
1436 DBG_ERR("PANIC : %s\n",
1437 share_mode_str(talloc_tos(), 0, &state->fid, e));
1438 smb_panic("validate_my_share_entries: Cannot match a "
1439 "share entry with an open file\n");
1442 if (((uint16_t)fsp->oplock_type) != e->op_type) {
1443 goto panic;
1446 return false;
1448 panic:
1450 char *str;
1451 DBG_ERR("validate_my_share_entries: PANIC : %s\n",
1452 share_mode_str(talloc_tos(), 0, &state->fid, e));
1453 str = talloc_asprintf(talloc_tos(),
1454 "validate_my_share_entries: "
1455 "file %s, oplock_type = 0x%x, op_type = 0x%x\n",
1456 fsp->fsp_name->base_name,
1457 (unsigned int)fsp->oplock_type,
1458 (unsigned int)e->op_type);
1459 smb_panic(str);
1462 return false;
1464 #endif
1467 * Allowed access mask for stat opens relevant to oplocks
1469 bool is_oplock_stat_open(uint32_t access_mask)
1471 const uint32_t stat_open_bits =
1472 (SYNCHRONIZE_ACCESS|
1473 FILE_READ_ATTRIBUTES|
1474 FILE_WRITE_ATTRIBUTES);
1476 return (((access_mask & stat_open_bits) != 0) &&
1477 ((access_mask & ~stat_open_bits) == 0));
1481 * Allowed access mask for stat opens relevant to leases
1483 bool is_lease_stat_open(uint32_t access_mask)
1485 const uint32_t stat_open_bits =
1486 (SYNCHRONIZE_ACCESS|
1487 FILE_READ_ATTRIBUTES|
1488 FILE_WRITE_ATTRIBUTES|
1489 READ_CONTROL_ACCESS);
1491 return (((access_mask & stat_open_bits) != 0) &&
1492 ((access_mask & ~stat_open_bits) == 0));
1495 struct has_delete_on_close_state {
1496 bool ret;
1499 static bool has_delete_on_close_fn(
1500 struct share_mode_entry *e,
1501 bool *modified,
1502 void *private_data)
1504 struct has_delete_on_close_state *state = private_data;
1505 state->ret = !share_entry_stale_pid(e);
1506 return state->ret;
1509 static bool has_delete_on_close(struct share_mode_lock *lck,
1510 uint32_t name_hash)
1512 struct has_delete_on_close_state state = { .ret = false };
1513 bool ok;
1515 if (!is_delete_on_close_set(lck, name_hash)) {
1516 return false;
1519 ok= share_mode_forall_entries(lck, has_delete_on_close_fn, &state);
1520 if (!ok) {
1521 DBG_DEBUG("share_mode_forall_entries failed\n");
1522 return false;
1524 return state.ret;
1527 static void share_mode_flags_restrict(
1528 struct share_mode_lock *lck,
1529 uint32_t access_mask,
1530 uint32_t share_mode,
1531 uint32_t lease_type)
1533 uint32_t existing_access_mask, existing_share_mode;
1534 uint32_t existing_lease_type;
1536 share_mode_flags_get(
1537 lck,
1538 &existing_access_mask,
1539 &existing_share_mode,
1540 &existing_lease_type);
1542 existing_access_mask |= access_mask;
1543 if (access_mask & conflicting_access) {
1544 existing_share_mode &= share_mode;
1546 existing_lease_type |= lease_type;
1548 share_mode_flags_set(
1549 lck,
1550 existing_access_mask,
1551 existing_share_mode,
1552 existing_lease_type,
1553 NULL);
1556 /****************************************************************************
1557 Deal with share modes
1558 Invariant: Share mode must be locked on entry and exit.
1559 Returns -1 on error, or number of share modes on success (may be zero).
1560 ****************************************************************************/
1562 struct open_mode_check_state {
1563 struct file_id fid;
1564 uint32_t access_mask;
1565 uint32_t share_access;
1566 uint32_t lease_type;
1569 static bool open_mode_check_fn(
1570 struct share_mode_entry *e,
1571 bool *modified,
1572 void *private_data)
1574 struct open_mode_check_state *state = private_data;
1575 bool disconnected, stale;
1576 uint32_t access_mask, share_access, lease_type;
1578 disconnected = server_id_is_disconnected(&e->pid);
1579 if (disconnected) {
1580 return false;
1583 access_mask = state->access_mask | e->access_mask;
1584 share_access = state->share_access;
1585 if (e->access_mask & conflicting_access) {
1586 share_access &= e->share_access;
1588 lease_type = state->lease_type | get_lease_type(e, state->fid);
1590 if ((access_mask == state->access_mask) &&
1591 (share_access == state->share_access) &&
1592 (lease_type == state->lease_type)) {
1593 return false;
1596 stale = share_entry_stale_pid(e);
1597 if (stale) {
1598 return false;
1601 state->access_mask = access_mask;
1602 state->share_access = share_access;
1603 state->lease_type = lease_type;
1605 return false;
1608 static NTSTATUS open_mode_check(connection_struct *conn,
1609 struct file_id fid,
1610 struct share_mode_lock *lck,
1611 uint32_t access_mask,
1612 uint32_t share_access)
1614 struct open_mode_check_state state;
1615 bool ok, conflict;
1616 bool modified = false;
1618 if (is_oplock_stat_open(access_mask)) {
1619 /* Stat open that doesn't trigger oplock breaks or share mode
1620 * checks... ! JRA. */
1621 return NT_STATUS_OK;
1625 * Check if the share modes will give us access.
1628 #if defined(DEVELOPER)
1630 struct validate_my_share_entries_state validate_state = {
1631 .sconn = conn->sconn,
1632 .fid = fid,
1633 .self = messaging_server_id(conn->sconn->msg_ctx),
1635 ok = share_mode_forall_entries(
1636 lck, validate_my_share_entries_fn, &validate_state);
1637 SMB_ASSERT(ok);
1639 #endif
1641 share_mode_flags_get(
1642 lck, &state.access_mask, &state.share_access, NULL);
1644 conflict = share_conflict(
1645 state.access_mask,
1646 state.share_access,
1647 access_mask,
1648 share_access);
1649 if (!conflict) {
1650 DBG_DEBUG("No conflict due to share_mode_flags access\n");
1651 return NT_STATUS_OK;
1654 state = (struct open_mode_check_state) {
1655 .fid = fid,
1656 .share_access = (FILE_SHARE_READ|
1657 FILE_SHARE_WRITE|
1658 FILE_SHARE_DELETE),
1662 * Walk the share mode array to recalculate d->flags
1665 ok = share_mode_forall_entries(lck, open_mode_check_fn, &state);
1666 if (!ok) {
1667 DBG_DEBUG("share_mode_forall_entries failed\n");
1668 return NT_STATUS_INTERNAL_ERROR;
1671 share_mode_flags_set(
1672 lck,
1673 state.access_mask,
1674 state.share_access,
1675 state.lease_type,
1676 &modified);
1677 if (!modified) {
1679 * We only end up here if we had a sharing violation
1680 * from d->flags and have recalculated it.
1682 return NT_STATUS_SHARING_VIOLATION;
1685 conflict = share_conflict(
1686 state.access_mask,
1687 state.share_access,
1688 access_mask,
1689 share_access);
1690 if (!conflict) {
1691 DBG_DEBUG("No conflict due to share_mode_flags access\n");
1692 return NT_STATUS_OK;
1695 return NT_STATUS_SHARING_VIOLATION;
1699 * Send a break message to the oplock holder and delay the open for
1700 * our client.
1703 NTSTATUS send_break_message(struct messaging_context *msg_ctx,
1704 const struct file_id *id,
1705 const struct share_mode_entry *exclusive,
1706 uint16_t break_to)
1708 struct oplock_break_message msg = {
1709 .id = *id,
1710 .share_file_id = exclusive->share_file_id,
1711 .break_to = break_to,
1713 enum ndr_err_code ndr_err;
1714 uint8_t msgbuf[33];
1715 DATA_BLOB blob = {.data = msgbuf, .length = sizeof(msgbuf)};
1716 NTSTATUS status;
1718 if (DEBUGLVL(10)) {
1719 struct server_id_buf buf;
1720 DBG_DEBUG("Sending break message to %s\n",
1721 server_id_str_buf(exclusive->pid, &buf));
1722 NDR_PRINT_DEBUG(oplock_break_message, &msg);
1725 ndr_err = ndr_push_struct_into_fixed_blob(
1726 &blob,
1727 &msg,
1728 (ndr_push_flags_fn_t)ndr_push_oplock_break_message);
1729 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
1730 DBG_WARNING("ndr_push_oplock_break_message failed: %s\n",
1731 ndr_errstr(ndr_err));
1732 return ndr_map_error2ntstatus(ndr_err);
1735 status = messaging_send(msg_ctx,
1736 exclusive->pid,
1737 MSG_SMB_BREAK_REQUEST,
1738 &blob);
1739 if (!NT_STATUS_IS_OK(status)) {
1740 DEBUG(3, ("Could not send oplock break message: %s\n",
1741 nt_errstr(status)));
1744 return status;
1747 struct validate_oplock_types_state {
1748 bool valid;
1749 bool batch;
1750 bool ex_or_batch;
1751 bool level2;
1752 bool no_oplock;
1753 uint32_t num_non_stat_opens;
1756 static bool validate_oplock_types_fn(
1757 struct share_mode_entry *e,
1758 bool *modified,
1759 void *private_data)
1761 struct validate_oplock_types_state *state = private_data;
1763 if (e->op_mid == 0) {
1764 /* INTERNAL_OPEN_ONLY */
1765 return false;
1768 if (e->op_type == NO_OPLOCK && is_oplock_stat_open(e->access_mask)) {
1770 * We ignore stat opens in the table - they always
1771 * have NO_OPLOCK and never get or cause breaks. JRA.
1773 return false;
1776 state->num_non_stat_opens += 1;
1778 if (BATCH_OPLOCK_TYPE(e->op_type)) {
1779 /* batch - can only be one. */
1780 if (share_entry_stale_pid(e)) {
1781 DBG_DEBUG("Found stale batch oplock\n");
1782 return false;
1784 if (state->ex_or_batch ||
1785 state->batch ||
1786 state->level2 ||
1787 state->no_oplock) {
1788 DBG_ERR("Bad batch oplock entry\n");
1789 state->valid = false;
1790 return true;
1792 state->batch = true;
1795 if (EXCLUSIVE_OPLOCK_TYPE(e->op_type)) {
1796 if (share_entry_stale_pid(e)) {
1797 DBG_DEBUG("Found stale duplicate oplock\n");
1798 return false;
1800 /* Exclusive or batch - can only be one. */
1801 if (state->ex_or_batch ||
1802 state->level2 ||
1803 state->no_oplock) {
1804 DBG_ERR("Bad exclusive or batch oplock entry\n");
1805 state->valid = false;
1806 return true;
1808 state->ex_or_batch = true;
1811 if (LEVEL_II_OPLOCK_TYPE(e->op_type)) {
1812 if (state->batch || state->ex_or_batch) {
1813 if (share_entry_stale_pid(e)) {
1814 DBG_DEBUG("Found stale LevelII oplock\n");
1815 return false;
1817 DBG_DEBUG("Bad levelII oplock entry\n");
1818 state->valid = false;
1819 return true;
1821 state->level2 = true;
1824 if (e->op_type == NO_OPLOCK) {
1825 if (state->batch || state->ex_or_batch) {
1826 if (share_entry_stale_pid(e)) {
1827 DBG_DEBUG("Found stale NO_OPLOCK entry\n");
1828 return false;
1830 DBG_ERR("Bad no oplock entry\n");
1831 state->valid = false;
1832 return true;
1834 state->no_oplock = true;
1837 return false;
1841 * Do internal consistency checks on the share mode for a file.
1844 static bool validate_oplock_types(struct share_mode_lock *lck)
1846 struct validate_oplock_types_state state = { .valid = true };
1847 static bool skip_validation;
1848 bool validate;
1849 bool ok;
1851 if (skip_validation) {
1852 return true;
1855 validate = lp_parm_bool(-1, "smbd", "validate_oplock_types", false);
1856 if (!validate) {
1857 DBG_DEBUG("smbd:validate_oplock_types not set to yes\n");
1858 skip_validation = true;
1859 return true;
1862 ok = share_mode_forall_entries(lck, validate_oplock_types_fn, &state);
1863 if (!ok) {
1864 DBG_DEBUG("share_mode_forall_entries failed\n");
1865 return false;
1867 if (!state.valid) {
1868 DBG_DEBUG("Got invalid oplock configuration\n");
1869 return false;
1872 if ((state.batch || state.ex_or_batch) &&
1873 (state.num_non_stat_opens != 1)) {
1874 DBG_WARNING("got batch (%d) or ex (%d) non-exclusively "
1875 "(%"PRIu32")\n",
1876 (int)state.batch,
1877 (int)state.ex_or_batch,
1878 state.num_non_stat_opens);
1879 return false;
1882 return true;
1885 static bool is_same_lease(const files_struct *fsp,
1886 const struct share_mode_entry *e,
1887 const struct smb2_lease *lease)
1889 if (e->op_type != LEASE_OPLOCK) {
1890 return false;
1892 if (lease == NULL) {
1893 return false;
1896 return smb2_lease_equal(fsp_client_guid(fsp),
1897 &lease->lease_key,
1898 &e->client_guid,
1899 &e->lease_key);
1902 static bool file_has_brlocks(files_struct *fsp)
1904 struct byte_range_lock *br_lck;
1906 br_lck = brl_get_locks_readonly(fsp);
1907 if (!br_lck)
1908 return false;
1910 return (brl_num_locks(br_lck) > 0);
1913 struct fsp_lease *find_fsp_lease(struct files_struct *new_fsp,
1914 const struct smb2_lease_key *key,
1915 uint32_t current_state,
1916 uint16_t lease_version,
1917 uint16_t lease_epoch)
1919 struct files_struct *fsp;
1922 * TODO: Measure how expensive this loop is with thousands of open
1923 * handles...
1926 for (fsp = file_find_di_first(new_fsp->conn->sconn, new_fsp->file_id, true);
1927 fsp != NULL;
1928 fsp = file_find_di_next(fsp, true)) {
1930 if (fsp == new_fsp) {
1931 continue;
1933 if (fsp->oplock_type != LEASE_OPLOCK) {
1934 continue;
1936 if (smb2_lease_key_equal(&fsp->lease->lease.lease_key, key)) {
1937 fsp->lease->ref_count += 1;
1938 return fsp->lease;
1942 /* Not found - must be leased in another smbd. */
1943 new_fsp->lease = talloc_zero(new_fsp->conn->sconn, struct fsp_lease);
1944 if (new_fsp->lease == NULL) {
1945 return NULL;
1947 new_fsp->lease->ref_count = 1;
1948 new_fsp->lease->sconn = new_fsp->conn->sconn;
1949 new_fsp->lease->lease.lease_key = *key;
1950 new_fsp->lease->lease.lease_state = current_state;
1952 * We internally treat all leases as V2 and update
1953 * the epoch, but when sending breaks it matters if
1954 * the requesting lease was v1 or v2.
1956 new_fsp->lease->lease.lease_version = lease_version;
1957 new_fsp->lease->lease.lease_epoch = lease_epoch;
1958 return new_fsp->lease;
1961 static NTSTATUS try_lease_upgrade(struct files_struct *fsp,
1962 struct share_mode_lock *lck,
1963 const struct GUID *client_guid,
1964 const struct smb2_lease *lease,
1965 uint32_t granted)
1967 bool do_upgrade;
1968 uint32_t current_state, breaking_to_requested, breaking_to_required;
1969 bool breaking;
1970 uint16_t lease_version, epoch;
1971 uint32_t existing, requested;
1972 NTSTATUS status;
1974 status = leases_db_get(
1975 client_guid,
1976 &lease->lease_key,
1977 &fsp->file_id,
1978 &current_state,
1979 &breaking,
1980 &breaking_to_requested,
1981 &breaking_to_required,
1982 &lease_version,
1983 &epoch);
1984 if (!NT_STATUS_IS_OK(status)) {
1985 return status;
1988 fsp->lease = find_fsp_lease(
1989 fsp,
1990 &lease->lease_key,
1991 current_state,
1992 lease_version,
1993 epoch);
1994 if (fsp->lease == NULL) {
1995 DEBUG(1, ("Did not find existing lease for file %s\n",
1996 fsp_str_dbg(fsp)));
1997 return NT_STATUS_NO_MEMORY;
2001 * Upgrade only if the requested lease is a strict upgrade.
2003 existing = current_state;
2004 requested = lease->lease_state;
2007 * Tricky: This test makes sure that "requested" is a
2008 * strict bitwise superset of "existing".
2010 do_upgrade = ((existing & requested) == existing);
2013 * Upgrade only if there's a change.
2015 do_upgrade &= (granted != existing);
2018 * Upgrade only if other leases don't prevent what was asked
2019 * for.
2021 do_upgrade &= (granted == requested);
2024 * only upgrade if we are not in breaking state
2026 do_upgrade &= !breaking;
2028 DEBUG(10, ("existing=%"PRIu32", requested=%"PRIu32", "
2029 "granted=%"PRIu32", do_upgrade=%d\n",
2030 existing, requested, granted, (int)do_upgrade));
2032 if (do_upgrade) {
2033 NTSTATUS set_status;
2035 current_state = granted;
2036 epoch += 1;
2038 set_status = leases_db_set(
2039 client_guid,
2040 &lease->lease_key,
2041 current_state,
2042 breaking,
2043 breaking_to_requested,
2044 breaking_to_required,
2045 lease_version,
2046 epoch);
2048 if (!NT_STATUS_IS_OK(set_status)) {
2049 DBG_DEBUG("leases_db_set failed: %s\n",
2050 nt_errstr(set_status));
2051 return set_status;
2055 fsp_lease_update(fsp);
2057 return NT_STATUS_OK;
2060 static NTSTATUS grant_new_fsp_lease(struct files_struct *fsp,
2061 struct share_mode_lock *lck,
2062 const struct GUID *client_guid,
2063 const struct smb2_lease *lease,
2064 uint32_t granted)
2066 NTSTATUS status;
2068 fsp->lease = talloc_zero(fsp->conn->sconn, struct fsp_lease);
2069 if (fsp->lease == NULL) {
2070 return NT_STATUS_INSUFFICIENT_RESOURCES;
2072 fsp->lease->ref_count = 1;
2073 fsp->lease->sconn = fsp->conn->sconn;
2074 fsp->lease->lease.lease_version = lease->lease_version;
2075 fsp->lease->lease.lease_key = lease->lease_key;
2076 fsp->lease->lease.parent_lease_key = lease->parent_lease_key;
2077 fsp->lease->lease.lease_flags = lease->lease_flags;
2078 fsp->lease->lease.lease_state = granted;
2079 fsp->lease->lease.lease_epoch = lease->lease_epoch + 1;
2081 status = leases_db_add(client_guid,
2082 &lease->lease_key,
2083 &fsp->file_id,
2084 fsp->lease->lease.lease_state,
2085 fsp->lease->lease.lease_version,
2086 fsp->lease->lease.lease_epoch,
2087 fsp->conn->connectpath,
2088 fsp->fsp_name->base_name,
2089 fsp->fsp_name->stream_name);
2090 if (!NT_STATUS_IS_OK(status)) {
2091 DEBUG(10, ("%s: leases_db_add failed: %s\n", __func__,
2092 nt_errstr(status)));
2093 TALLOC_FREE(fsp->lease);
2094 return NT_STATUS_INSUFFICIENT_RESOURCES;
2098 * We used to set lck->data->modified=true here without
2099 * actually modifying lck->data, triggering a needless
2100 * writeback of lck->data.
2102 * Apart from that writeback, setting modified=true has the
2103 * effect of triggering all waiters for this file to
2104 * retry. This only makes sense if any blocking condition
2105 * (i.e. waiting for a lease to be downgraded or removed) is
2106 * gone. This routine here only adds a lease, so it will never
2107 * free up resources that blocked waiters can now claim. So
2108 * that second effect also does not matter in this
2109 * routine. Thus setting lck->data->modified=true does not
2110 * need to be done here.
2113 return NT_STATUS_OK;
2116 static NTSTATUS grant_fsp_lease(struct files_struct *fsp,
2117 struct share_mode_lock *lck,
2118 const struct smb2_lease *lease,
2119 uint32_t granted)
2121 const struct GUID *client_guid = fsp_client_guid(fsp);
2122 NTSTATUS status;
2124 status = try_lease_upgrade(fsp, lck, client_guid, lease, granted);
2126 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
2127 status = grant_new_fsp_lease(
2128 fsp, lck, client_guid, lease, granted);
2131 return status;
2134 static int map_lease_type_to_oplock(uint32_t lease_type)
2136 int result = NO_OPLOCK;
2138 switch (lease_type) {
2139 case SMB2_LEASE_READ|SMB2_LEASE_WRITE|SMB2_LEASE_HANDLE:
2140 result = BATCH_OPLOCK|EXCLUSIVE_OPLOCK;
2141 break;
2142 case SMB2_LEASE_READ|SMB2_LEASE_WRITE:
2143 result = EXCLUSIVE_OPLOCK;
2144 break;
2145 case SMB2_LEASE_READ|SMB2_LEASE_HANDLE:
2146 case SMB2_LEASE_READ:
2147 result = LEVEL_II_OPLOCK;
2148 break;
2151 return result;
2154 struct blocker_debug_state {
2155 size_t num_blockers;
2158 struct delay_for_oplock_state {
2159 struct files_struct *fsp;
2160 const struct smb2_lease *lease;
2161 bool will_overwrite;
2162 uint32_t delay_mask;
2163 bool first_open_attempt;
2164 bool got_handle_lease;
2165 bool got_oplock;
2166 bool disallow_write_lease;
2167 uint32_t total_lease_types;
2168 bool delay;
2169 struct blocker_debug_state *blocker_debug_state;
2172 static int blocker_debug_state_destructor(struct blocker_debug_state *state)
2174 if (state->num_blockers == 0) {
2175 return 0;
2178 DBG_DEBUG("blocker_debug_state [%p] num_blockers [%zu]\n",
2179 state, state->num_blockers);
2180 return 0;
2183 static void delay_for_oplock_fn_watch_done(struct tevent_req *subreq);
2185 static bool delay_for_oplock_fn(
2186 struct share_mode_entry *e,
2187 bool *modified,
2188 void *private_data)
2190 struct delay_for_oplock_state *state = private_data;
2191 struct files_struct *fsp = state->fsp;
2192 const struct smb2_lease *lease = state->lease;
2193 bool e_is_lease = (e->op_type == LEASE_OPLOCK);
2194 uint32_t e_lease_type = SMB2_LEASE_NONE;
2195 uint32_t break_to;
2196 bool lease_is_breaking = false;
2197 struct tevent_req *subreq = NULL;
2198 struct server_id_buf idbuf = {};
2200 if (e_is_lease) {
2201 NTSTATUS status;
2203 if (lease != NULL) {
2204 bool our_lease = is_same_lease(fsp, e, lease);
2205 if (our_lease) {
2206 DBG_DEBUG("Ignoring our own lease\n");
2207 return false;
2211 status = leases_db_get(
2212 &e->client_guid,
2213 &e->lease_key,
2214 &fsp->file_id,
2215 &e_lease_type, /* current_state */
2216 &lease_is_breaking,
2217 NULL, /* breaking_to_requested */
2218 NULL, /* breaking_to_required */
2219 NULL, /* lease_version */
2220 NULL); /* epoch */
2223 * leases_db_get() can return NT_STATUS_NOT_FOUND
2224 * if the share_mode_entry e is stale and the
2225 * lease record was already removed. In this case return
2226 * false so the traverse continues.
2229 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND) &&
2230 share_entry_stale_pid(e))
2232 struct GUID_txt_buf guid_strbuf;
2233 struct file_id_buf file_id_strbuf;
2234 DBG_DEBUG("leases_db_get for client_guid [%s] "
2235 "lease_key [%"PRIu64"/%"PRIu64"] "
2236 "file_id [%s] failed for stale "
2237 "share_mode_entry\n",
2238 GUID_buf_string(&e->client_guid, &guid_strbuf),
2239 e->lease_key.data[0],
2240 e->lease_key.data[1],
2241 file_id_str_buf(fsp->file_id, &file_id_strbuf));
2242 return false;
2244 if (!NT_STATUS_IS_OK(status)) {
2245 struct GUID_txt_buf guid_strbuf;
2246 struct file_id_buf file_id_strbuf;
2247 DBG_ERR("leases_db_get for client_guid [%s] "
2248 "lease_key [%"PRIu64"/%"PRIu64"] "
2249 "file_id [%s] failed: %s\n",
2250 GUID_buf_string(&e->client_guid, &guid_strbuf),
2251 e->lease_key.data[0],
2252 e->lease_key.data[1],
2253 file_id_str_buf(fsp->file_id, &file_id_strbuf),
2254 nt_errstr(status));
2255 smb_panic("leases_db_get() failed");
2257 } else {
2258 e_lease_type = get_lease_type(e, fsp->file_id);
2261 if (((e_lease_type & ~state->total_lease_types) != 0) &&
2262 !share_entry_stale_pid(e))
2264 state->total_lease_types |= e_lease_type;
2267 if (!state->got_handle_lease &&
2268 ((e_lease_type & SMB2_LEASE_HANDLE) != 0) &&
2269 !share_entry_stale_pid(e)) {
2270 state->got_handle_lease = true;
2273 if (!state->got_oplock &&
2274 (e->op_type != NO_OPLOCK) &&
2275 (e->op_type != LEASE_OPLOCK) &&
2276 !share_entry_stale_pid(e)) {
2277 state->got_oplock = true;
2281 * Two things prevent a write lease
2282 * to be granted:
2284 * 1. Any oplock or lease (even broken to NONE)
2285 * 2. An open with an access mask other than
2286 * FILE_READ_ATTRIBUTES, FILE_WRITE_ATTRIBUTES
2287 * or SYNCHRONIZE_ACCESS
2289 if (!state->disallow_write_lease &&
2290 (e->op_type != NO_OPLOCK || !is_oplock_stat_open(e->access_mask)) &&
2291 !is_same_lease(fsp, e, lease) &&
2292 !share_entry_stale_pid(e))
2294 state->disallow_write_lease = true;
2297 if (e_is_lease && is_lease_stat_open(fsp->access_mask)) {
2298 return false;
2301 break_to = e_lease_type & ~state->delay_mask;
2303 if (state->will_overwrite) {
2304 break_to &= ~(SMB2_LEASE_HANDLE|SMB2_LEASE_READ);
2307 DBG_DEBUG("e_lease_type %u, will_overwrite: %u\n",
2308 (unsigned)e_lease_type,
2309 (unsigned)state->will_overwrite);
2311 if ((e_lease_type & ~break_to) == 0) {
2312 if (lease_is_breaking) {
2313 state->delay = true;
2315 return false;
2318 if (share_entry_stale_pid(e)) {
2319 return false;
2322 if (state->will_overwrite) {
2324 * If we break anyway break to NONE directly.
2325 * Otherwise vfs_set_filelen() will trigger the
2326 * break.
2328 break_to &= ~(SMB2_LEASE_READ|SMB2_LEASE_WRITE);
2331 if (!e_is_lease) {
2333 * Oplocks only support breaking to R or NONE.
2335 break_to &= ~(SMB2_LEASE_HANDLE|SMB2_LEASE_WRITE);
2338 DBG_DEBUG("breaking from %d to %d\n",
2339 (int)e_lease_type,
2340 (int)break_to);
2341 send_break_message(
2342 fsp->conn->sconn->msg_ctx, &fsp->file_id, e, break_to);
2343 if (e_lease_type & state->delay_mask) {
2344 state->delay = true;
2346 if (lease_is_breaking && !state->first_open_attempt) {
2347 state->delay = true;
2350 if (!state->delay) {
2351 return false;
2354 if (state->blocker_debug_state == NULL) {
2355 return false;
2358 subreq = server_id_watch_send(state->blocker_debug_state,
2359 fsp->conn->sconn->ev_ctx,
2360 e->pid);
2361 if (subreq == NULL) {
2362 DBG_ERR("server_id_watch_send(%s) returned NULL\n",
2363 server_id_str_buf(e->pid, &idbuf));
2364 return false;
2367 tevent_req_set_callback(subreq,
2368 delay_for_oplock_fn_watch_done,
2369 state->blocker_debug_state);
2371 state->blocker_debug_state->num_blockers++;
2373 DBG_DEBUG("Starting to watch pid [%s] state [%p] num_blockers [%zu]\n",
2374 server_id_str_buf(e->pid, &idbuf),
2375 state->blocker_debug_state,
2376 state->blocker_debug_state->num_blockers);
2378 return false;
2381 static void delay_for_oplock_fn_watch_done(struct tevent_req *subreq)
2383 struct blocker_debug_state *blocker_debug_state = tevent_req_callback_data(
2384 subreq, struct blocker_debug_state);
2385 struct server_id pid = {};
2386 struct server_id_buf idbuf = {};
2387 int ret;
2389 ret = server_id_watch_recv(subreq, &pid);
2390 if (ret != 0) {
2391 DBG_ERR("server_id_watch_recv failed %s\n", strerror(ret));
2392 return;
2395 DBG_DEBUG("state [%p] server_id_watch_recv() returned pid [%s] exited\n",
2396 blocker_debug_state,
2397 server_id_str_buf(pid, &idbuf));
2400 static NTSTATUS delay_for_oplock(files_struct *fsp,
2401 int oplock_request,
2402 const struct smb2_lease *lease,
2403 struct share_mode_lock *lck,
2404 bool have_sharing_violation,
2405 uint32_t create_disposition,
2406 bool first_open_attempt,
2407 int *poplock_type,
2408 uint32_t *pgranted,
2409 struct blocker_debug_state **blocker_debug_state)
2411 struct delay_for_oplock_state state = {
2412 .fsp = fsp,
2413 .lease = lease,
2414 .first_open_attempt = first_open_attempt,
2416 uint32_t requested;
2417 uint32_t granted;
2418 int oplock_type;
2419 bool ok;
2421 *poplock_type = NO_OPLOCK;
2422 *pgranted = 0;
2424 if (oplock_request == LEASE_OPLOCK) {
2425 if (lease == NULL) {
2427 * The SMB2 layer should have checked this
2429 return NT_STATUS_INTERNAL_ERROR;
2432 requested = lease->lease_state;
2433 if (fsp->fsp_flags.is_directory) {
2435 * According to "MS-FSA 2.1.5.18 Server Requests an
2436 * Oplock" this should fail with
2437 * STATUS_INVALID_PARAMETER, but Windows 2022 just
2438 * ignores the SMB2_LEASE_WRITE bit.
2440 requested &= ~SMB2_LEASE_WRITE;
2442 } else {
2443 requested = map_oplock_to_lease_type(
2444 oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK);
2447 share_mode_flags_get(lck, NULL, NULL, &state.total_lease_types);
2449 if (is_oplock_stat_open(fsp->access_mask)) {
2450 goto grant;
2453 if (lp_parm_bool(GLOBAL_SECTION_SNUM,
2454 "smbd lease break",
2455 "debug hung procs",
2456 false))
2458 state.blocker_debug_state = talloc_zero(fsp,
2459 struct blocker_debug_state);
2460 if (state.blocker_debug_state == NULL) {
2461 return NT_STATUS_NO_MEMORY;
2463 talloc_steal(talloc_tos(), state.blocker_debug_state);
2465 talloc_set_destructor(state.blocker_debug_state,
2466 blocker_debug_state_destructor);
2469 state.delay_mask = have_sharing_violation ?
2470 SMB2_LEASE_HANDLE : SMB2_LEASE_WRITE;
2472 switch (create_disposition) {
2473 case FILE_SUPERSEDE:
2474 case FILE_OVERWRITE:
2475 case FILE_OVERWRITE_IF:
2476 state.will_overwrite = true;
2477 break;
2478 default:
2479 state.will_overwrite = false;
2480 break;
2483 state.total_lease_types = SMB2_LEASE_NONE;
2484 ok = share_mode_forall_entries(lck, delay_for_oplock_fn, &state);
2485 if (!ok) {
2486 return NT_STATUS_INTERNAL_ERROR;
2489 if (state.delay) {
2490 *blocker_debug_state = state.blocker_debug_state;
2491 return NT_STATUS_RETRY;
2494 grant:
2495 if (have_sharing_violation) {
2496 return NT_STATUS_SHARING_VIOLATION;
2499 granted = requested;
2501 if (oplock_request == LEASE_OPLOCK) {
2502 if (lp_kernel_oplocks(SNUM(fsp->conn))) {
2503 DEBUG(10, ("No lease granted because kernel oplocks are enabled\n"));
2504 granted = SMB2_LEASE_NONE;
2506 if ((granted & (SMB2_LEASE_READ|SMB2_LEASE_WRITE)) == 0) {
2507 DEBUG(10, ("No read or write lease requested\n"));
2508 granted = SMB2_LEASE_NONE;
2510 if (granted == SMB2_LEASE_WRITE) {
2511 DEBUG(10, ("pure write lease requested\n"));
2512 granted = SMB2_LEASE_NONE;
2514 if (granted == (SMB2_LEASE_WRITE|SMB2_LEASE_HANDLE)) {
2515 DEBUG(10, ("write and handle lease requested\n"));
2516 granted = SMB2_LEASE_NONE;
2520 if (lp_locking(fsp->conn->params) && file_has_brlocks(fsp)) {
2521 DBG_DEBUG("file %s has byte range locks\n",
2522 fsp_str_dbg(fsp));
2523 granted &= ~SMB2_LEASE_READ;
2526 if (state.disallow_write_lease) {
2528 * Can grant only a write lease
2529 * if there are no other leases
2530 * and no other non-stat opens.
2532 granted &= ~SMB2_LEASE_WRITE;
2535 if ((granted & SMB2_LEASE_READ) && !(granted & SMB2_LEASE_WRITE)) {
2536 bool allow_level2 =
2537 (global_client_caps & CAP_LEVEL_II_OPLOCKS) &&
2538 lp_level2_oplocks(SNUM(fsp->conn));
2540 if (!allow_level2) {
2541 granted = SMB2_LEASE_NONE;
2545 if (oplock_request == LEASE_OPLOCK) {
2546 if (state.got_oplock) {
2547 granted &= ~SMB2_LEASE_HANDLE;
2550 oplock_type = LEASE_OPLOCK;
2551 } else {
2552 if (state.got_handle_lease) {
2553 granted = SMB2_LEASE_NONE;
2557 * Reflect possible downgrades from:
2558 * - map_lease_type_to_oplock() => "RH" to just LEVEL_II
2560 oplock_type = map_lease_type_to_oplock(granted);
2561 granted = map_oplock_to_lease_type(oplock_type);
2564 state.total_lease_types |= granted;
2567 uint32_t acc, sh, ls;
2568 share_mode_flags_get(lck, &acc, &sh, &ls);
2569 ls = state.total_lease_types;
2570 share_mode_flags_set(lck, acc, sh, ls, NULL);
2573 DBG_DEBUG("oplock type 0x%x granted (%s%s%s)(0x%x), on file %s, "
2574 "requested 0x%x (%s%s%s)(0x%x) => total (%s%s%s)(0x%x)\n",
2575 fsp->oplock_type,
2576 granted & SMB2_LEASE_READ ? "R":"",
2577 granted & SMB2_LEASE_WRITE ? "W":"",
2578 granted & SMB2_LEASE_HANDLE ? "H":"",
2579 granted,
2580 fsp_str_dbg(fsp),
2581 oplock_request,
2582 requested & SMB2_LEASE_READ ? "R":"",
2583 requested & SMB2_LEASE_WRITE ? "W":"",
2584 requested & SMB2_LEASE_HANDLE ? "H":"",
2585 requested,
2586 state.total_lease_types & SMB2_LEASE_READ ? "R":"",
2587 state.total_lease_types & SMB2_LEASE_WRITE ? "W":"",
2588 state.total_lease_types & SMB2_LEASE_HANDLE ? "H":"",
2589 state.total_lease_types);
2591 *poplock_type = oplock_type;
2592 *pgranted = granted;
2593 return NT_STATUS_OK;
2596 static NTSTATUS handle_share_mode_lease(
2597 files_struct *fsp,
2598 struct share_mode_lock *lck,
2599 uint32_t create_disposition,
2600 uint32_t access_mask,
2601 uint32_t share_access,
2602 int oplock_request,
2603 const struct smb2_lease *lease,
2604 bool first_open_attempt,
2605 int *poplock_type,
2606 uint32_t *pgranted,
2607 struct blocker_debug_state **blocker_debug_state)
2609 bool sharing_violation = false;
2610 NTSTATUS status;
2612 *poplock_type = NO_OPLOCK;
2613 *pgranted = 0;
2615 status = open_mode_check(
2616 fsp->conn, fsp->file_id, lck, access_mask, share_access);
2617 if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION)) {
2618 sharing_violation = true;
2619 status = NT_STATUS_OK; /* handled later */
2622 if (!NT_STATUS_IS_OK(status)) {
2623 return status;
2626 if (fsp->fsp_flags.is_directory &&
2627 oplock_request == LEASE_OPLOCK &&
2628 !lp_smb3_directory_leases())
2630 DBG_NOTICE("Ignoring disabled DirectoryLease request on [%s]\n",
2631 fsp_str_dbg(fsp));
2632 oplock_request = NO_OPLOCK;
2633 lease = NULL;
2636 if (oplock_request == INTERNAL_OPEN_ONLY) {
2637 if (sharing_violation) {
2638 DBG_DEBUG("Sharing violation for internal open\n");
2639 return NT_STATUS_SHARING_VIOLATION;
2643 * Internal opens never do oplocks or leases. We don't
2644 * need to go through delay_for_oplock().
2646 return NT_STATUS_OK;
2649 status = delay_for_oplock(
2650 fsp,
2651 oplock_request,
2652 lease,
2653 lck,
2654 sharing_violation,
2655 create_disposition,
2656 first_open_attempt,
2657 poplock_type,
2658 pgranted,
2659 blocker_debug_state);
2660 if (!NT_STATUS_IS_OK(status)) {
2661 return status;
2664 return NT_STATUS_OK;
2667 static bool request_timed_out(struct smb_request *req, struct timeval timeout)
2669 struct timeval end_time = timeval_sum(&req->request_time, &timeout);
2670 return timeval_expired(&end_time);
2673 struct defer_open_state {
2674 struct smbXsrv_connection *xconn;
2675 uint64_t mid;
2678 static void defer_open_done(struct tevent_req *req);
2681 * Defer an open and watch a locking.tdb record
2683 * This defers an open that gets rescheduled once the locking.tdb record watch
2684 * is triggered by a change to the record.
2686 * It is used to defer opens that triggered an oplock break and for the SMB1
2687 * sharing violation delay.
2689 static void defer_open(struct share_mode_lock *lck,
2690 struct timeval timeout,
2691 struct smb_request *req,
2692 struct file_id id,
2693 struct blocker_debug_state **blocker_debug_state)
2695 struct deferred_open_record *open_rec = NULL;
2696 struct timeval abs_timeout;
2697 struct defer_open_state *watch_state;
2698 struct tevent_req *watch_req;
2699 struct timeval_buf tvbuf1, tvbuf2;
2700 struct file_id_buf fbuf;
2701 bool ok;
2703 abs_timeout = timeval_sum(&req->request_time, &timeout);
2705 DBG_DEBUG("request time [%s] timeout [%s] mid [%" PRIu64 "] "
2706 "file_id [%s]\n",
2707 timeval_str_buf(&req->request_time, false, true, &tvbuf1),
2708 timeval_str_buf(&abs_timeout, false, true, &tvbuf2),
2709 req->mid,
2710 file_id_str_buf(id, &fbuf));
2712 open_rec = talloc_zero(NULL, struct deferred_open_record);
2713 if (open_rec == NULL) {
2714 TALLOC_FREE(lck);
2715 exit_server("talloc failed");
2718 watch_state = talloc(open_rec, struct defer_open_state);
2719 if (watch_state == NULL) {
2720 exit_server("talloc failed");
2722 watch_state->xconn = req->xconn;
2723 watch_state->mid = req->mid;
2725 DBG_DEBUG("deferring mid %" PRIu64 "\n", req->mid);
2727 watch_req = share_mode_watch_send(
2728 watch_state,
2729 req->sconn->ev_ctx,
2730 &id,
2731 (struct server_id){0});
2732 if (watch_req == NULL) {
2733 exit_server("Could not watch share mode record");
2735 tevent_req_set_callback(watch_req, defer_open_done, watch_state);
2737 talloc_move(watch_req, blocker_debug_state);
2739 ok = tevent_req_set_endtime(watch_req, req->sconn->ev_ctx, abs_timeout);
2740 if (!ok) {
2741 exit_server("tevent_req_set_endtime failed");
2744 ok = push_deferred_open_message_smb(req, timeout, id, open_rec);
2745 if (!ok) {
2746 TALLOC_FREE(lck);
2747 exit_server("push_deferred_open_message_smb failed");
2751 static void defer_open_done(struct tevent_req *req)
2753 struct defer_open_state *state = tevent_req_callback_data(
2754 req, struct defer_open_state);
2755 NTSTATUS status;
2756 bool ret;
2758 status = share_mode_watch_recv(req, NULL, NULL);
2759 TALLOC_FREE(req);
2760 if (!NT_STATUS_IS_OK(status)) {
2761 DBG_ERR("share_mode_watch_recv() returned %s, "
2762 "rescheduling mid %" PRIu64 "\n",
2763 nt_errstr(status), state->mid);
2765 * Even if it failed, retry anyway. TODO: We need a way to
2766 * tell a re-scheduled open about that error.
2770 DEBUG(10, ("scheduling mid %llu\n", (unsigned long long)state->mid));
2772 ret = schedule_deferred_open_message_smb(state->xconn, state->mid);
2773 SMB_ASSERT(ret);
2774 TALLOC_FREE(state);
2778 * Actually attempt the kernel oplock polling open.
2781 static void poll_open_fn(struct tevent_context *ev,
2782 struct tevent_timer *te,
2783 struct timeval current_time,
2784 void *private_data)
2786 struct deferred_open_record *open_rec = talloc_get_type_abort(
2787 private_data, struct deferred_open_record);
2788 bool ok;
2790 TALLOC_FREE(open_rec->watch_req);
2792 ok = schedule_deferred_open_message_smb(
2793 open_rec->xconn, open_rec->mid);
2794 if (!ok) {
2795 exit_server("schedule_deferred_open_message_smb failed");
2797 DBG_DEBUG("timer fired. Retrying open !\n");
2800 static void poll_open_done(struct tevent_req *subreq);
2802 struct poll_open_setup_watcher_state {
2803 TALLOC_CTX *mem_ctx;
2804 struct tevent_context *ev_ctx;
2805 struct tevent_req *watch_req;
2806 struct file_id id;
2809 static void poll_open_setup_watcher_fn(struct share_mode_lock *lck,
2810 void *private_data)
2812 struct poll_open_setup_watcher_state *state =
2813 (struct poll_open_setup_watcher_state *)private_data;
2815 if (!validate_oplock_types(lck)) {
2816 smb_panic("validate_oplock_types failed");
2819 state->watch_req = share_mode_watch_send(
2820 state->mem_ctx,
2821 state->ev_ctx,
2822 &state->id,
2823 (struct server_id) {0});
2824 if (state->watch_req == NULL) {
2825 DBG_WARNING("share_mode_watch_send failed\n");
2826 return;
2831 * Reschedule an open for 1 second from now, if not timed out.
2833 static bool setup_poll_open(
2834 struct smb_request *req,
2835 const struct file_id *id,
2836 struct timeval max_timeout,
2837 struct timeval interval)
2839 static struct file_id zero_id = {};
2840 bool ok;
2841 struct deferred_open_record *open_rec = NULL;
2842 struct timeval endtime, next_interval;
2843 struct file_id_buf ftmp;
2845 if (request_timed_out(req, max_timeout)) {
2846 return false;
2849 open_rec = talloc_zero(NULL, struct deferred_open_record);
2850 if (open_rec == NULL) {
2851 DBG_WARNING("talloc failed\n");
2852 return false;
2854 open_rec->xconn = req->xconn;
2855 open_rec->mid = req->mid;
2858 * Make sure open_rec->te does not come later than the
2859 * request's maximum endtime.
2862 endtime = timeval_sum(&req->request_time, &max_timeout);
2863 next_interval = timeval_current_ofs(interval.tv_sec, interval.tv_usec);
2864 next_interval = timeval_min(&endtime, &next_interval);
2866 open_rec->te = tevent_add_timer(
2867 req->sconn->ev_ctx,
2868 open_rec,
2869 next_interval,
2870 poll_open_fn,
2871 open_rec);
2872 if (open_rec->te == NULL) {
2873 DBG_WARNING("tevent_add_timer failed\n");
2874 TALLOC_FREE(open_rec);
2875 return false;
2878 if (id != NULL) {
2879 struct poll_open_setup_watcher_state wstate = {
2880 .mem_ctx = open_rec,
2881 .ev_ctx = req->sconn->ev_ctx,
2882 .id = *id,
2884 NTSTATUS status;
2886 status = share_mode_do_locked_vfs_denied(*id,
2887 poll_open_setup_watcher_fn,
2888 &wstate);
2889 if (NT_STATUS_IS_OK(status)) {
2890 if (wstate.watch_req == NULL) {
2891 DBG_WARNING("share_mode_watch_send failed\n");
2892 TALLOC_FREE(open_rec);
2893 return false;
2895 open_rec->watch_req = wstate.watch_req;
2896 tevent_req_set_callback(open_rec->watch_req,
2897 poll_open_done,
2898 open_rec);
2899 } else if (!NT_STATUS_EQUAL(status, NT_STATUS_NOT_FOUND)) {
2900 DBG_WARNING("share_mode_do_locked_vfs_denied failed - %s\n",
2901 nt_errstr(status));
2902 TALLOC_FREE(open_rec);
2903 return false;
2905 } else {
2906 id = &zero_id;
2909 ok = push_deferred_open_message_smb(req, max_timeout, *id, open_rec);
2910 if (!ok) {
2911 DBG_WARNING("push_deferred_open_message_smb failed\n");
2912 TALLOC_FREE(open_rec);
2913 return false;
2916 DBG_DEBUG("poll request time [%s] mid [%" PRIu64 "] file_id [%s]\n",
2917 timeval_string(talloc_tos(), &req->request_time, false),
2918 req->mid,
2919 file_id_str_buf(*id, &ftmp));
2921 return true;
2924 static void poll_open_done(struct tevent_req *subreq)
2926 struct deferred_open_record *open_rec = tevent_req_callback_data(
2927 subreq, struct deferred_open_record);
2928 NTSTATUS status;
2929 bool ok;
2931 status = share_mode_watch_recv(subreq, NULL, NULL);
2932 TALLOC_FREE(subreq);
2933 open_rec->watch_req = NULL;
2934 TALLOC_FREE(open_rec->te);
2936 DBG_DEBUG("dbwrap_watched_watch_recv returned %s\n",
2937 nt_errstr(status));
2939 ok = schedule_deferred_open_message_smb(
2940 open_rec->xconn, open_rec->mid);
2941 if (!ok) {
2942 exit_server("schedule_deferred_open_message_smb failed");
2946 bool defer_smb1_sharing_violation(struct smb_request *req)
2948 bool ok;
2949 int timeout_usecs;
2951 if (!lp_defer_sharing_violations()) {
2952 return false;
2956 * Try every 200msec up to (by default) one second. To be
2957 * precise, according to behaviour note <247> in [MS-CIFS],
2958 * the server tries 5 times. But up to one second should be
2959 * close enough.
2962 timeout_usecs = lp_parm_int(
2963 SNUM(req->conn),
2964 "smbd",
2965 "sharedelay",
2966 SHARING_VIOLATION_USEC_WAIT);
2968 ok = setup_poll_open(
2969 req,
2970 NULL,
2971 (struct timeval) { .tv_usec = timeout_usecs },
2972 (struct timeval) { .tv_usec = 200000 });
2973 return ok;
2976 /****************************************************************************
2977 On overwrite open ensure that the attributes match.
2978 ****************************************************************************/
2980 static bool open_match_attributes(connection_struct *conn,
2981 uint32_t old_dos_attr,
2982 uint32_t new_dos_attr,
2983 mode_t new_unx_mode,
2984 mode_t *returned_unx_mode)
2986 uint32_t noarch_old_dos_attr, noarch_new_dos_attr;
2988 noarch_old_dos_attr = (old_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
2989 noarch_new_dos_attr = (new_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
2991 if((noarch_old_dos_attr == 0 && noarch_new_dos_attr != 0) ||
2992 (noarch_old_dos_attr != 0 && ((noarch_old_dos_attr & noarch_new_dos_attr) == noarch_old_dos_attr))) {
2993 *returned_unx_mode = new_unx_mode;
2994 } else {
2995 *returned_unx_mode = (mode_t)0;
2998 DEBUG(10,("open_match_attributes: old_dos_attr = 0x%x, "
2999 "new_dos_attr = 0x%x "
3000 "returned_unx_mode = 0%o\n",
3001 (unsigned int)old_dos_attr,
3002 (unsigned int)new_dos_attr,
3003 (unsigned int)*returned_unx_mode ));
3005 /* If we're mapping SYSTEM and HIDDEN ensure they match. */
3006 if (lp_map_system(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
3007 if ((old_dos_attr & FILE_ATTRIBUTE_SYSTEM) &&
3008 !(new_dos_attr & FILE_ATTRIBUTE_SYSTEM)) {
3009 return False;
3012 if (lp_map_hidden(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
3013 if ((old_dos_attr & FILE_ATTRIBUTE_HIDDEN) &&
3014 !(new_dos_attr & FILE_ATTRIBUTE_HIDDEN)) {
3015 return False;
3018 return True;
3021 static void schedule_defer_open(struct share_mode_lock *lck,
3022 struct file_id id,
3023 struct smb_request *req,
3024 struct blocker_debug_state **blocker_debug_state)
3026 /* This is a relative time, added to the absolute
3027 request_time value to get the absolute timeout time.
3028 Note that if this is the second or greater time we enter
3029 this codepath for this particular request mid then
3030 request_time is left as the absolute time of the *first*
3031 time this request mid was processed. This is what allows
3032 the request to eventually time out. */
3034 struct timeval timeout;
3036 /* Normally the smbd we asked should respond within
3037 * OPLOCK_BREAK_TIMEOUT seconds regardless of whether
3038 * the client did, give twice the timeout as a safety
3039 * measure here in case the other smbd is stuck
3040 * somewhere else. */
3042 timeout = tevent_timeval_set(OPLOCK_BREAK_TIMEOUT * 2, 0);
3044 if (request_timed_out(req, timeout)) {
3045 return;
3048 defer_open(lck, timeout, req, id, blocker_debug_state);
3051 /****************************************************************************
3052 Reschedule an open call that went asynchronous.
3053 ****************************************************************************/
3055 static void schedule_async_open_timer(struct tevent_context *ev,
3056 struct tevent_timer *te,
3057 struct timeval current_time,
3058 void *private_data)
3060 exit_server("async open timeout");
3063 static void schedule_async_open(struct smb_request *req)
3065 struct deferred_open_record *open_rec = NULL;
3066 struct timeval timeout = tevent_timeval_set(20, 0);
3067 bool ok;
3069 if (request_timed_out(req, timeout)) {
3070 return;
3073 open_rec = talloc_zero(NULL, struct deferred_open_record);
3074 if (open_rec == NULL) {
3075 exit_server("deferred_open_record_create failed");
3077 open_rec->async_open = true;
3079 ok = push_deferred_open_message_smb(
3080 req, timeout, (struct file_id){0}, open_rec);
3081 if (!ok) {
3082 exit_server("push_deferred_open_message_smb failed");
3085 open_rec->te = tevent_add_timer(req->sconn->ev_ctx,
3086 req,
3087 timeval_current_ofs(20, 0),
3088 schedule_async_open_timer,
3089 open_rec);
3090 if (open_rec->te == NULL) {
3091 exit_server("tevent_add_timer failed");
3095 static NTSTATUS check_and_store_share_mode(
3096 struct files_struct *fsp,
3097 struct smb_request *req,
3098 struct share_mode_lock *lck,
3099 uint32_t create_disposition,
3100 uint32_t access_mask,
3101 uint32_t open_access_mask,
3102 uint32_t share_access,
3103 int oplock_request,
3104 const struct smb2_lease *lease,
3105 bool first_open_attempt)
3107 NTSTATUS status;
3108 int oplock_type = NO_OPLOCK;
3109 uint32_t granted_lease = 0;
3110 const struct smb2_lease_key *lease_key = NULL;
3111 struct blocker_debug_state *blocker_debug_state = NULL;
3112 bool delete_on_close;
3113 bool ok;
3115 /* Get the types we need to examine. */
3116 if (!validate_oplock_types(lck)) {
3117 smb_panic("validate_oplock_types failed");
3120 delete_on_close = has_delete_on_close(lck, fsp->name_hash);
3121 if (delete_on_close) {
3122 return NT_STATUS_DELETE_PENDING;
3125 status = handle_share_mode_lease(fsp,
3126 lck,
3127 create_disposition,
3128 open_access_mask,
3129 share_access,
3130 oplock_request,
3131 lease,
3132 first_open_attempt,
3133 &oplock_type,
3134 &granted_lease,
3135 &blocker_debug_state);
3136 if (NT_STATUS_EQUAL(status, NT_STATUS_RETRY)) {
3137 schedule_defer_open(lck, fsp->file_id, req, &blocker_debug_state);
3138 return NT_STATUS_SHARING_VIOLATION;
3140 if (!NT_STATUS_IS_OK(status)) {
3141 return status;
3144 if (oplock_type == LEASE_OPLOCK) {
3145 lease_key = &lease->lease_key;
3148 share_mode_flags_restrict(lck, access_mask, share_access, 0);
3150 ok = set_share_mode(lck,
3151 fsp,
3152 get_current_uid(fsp->conn),
3153 req ? req->mid : 0,
3154 oplock_type,
3155 lease_key,
3156 share_access,
3157 access_mask);
3158 if (!ok) {
3159 return NT_STATUS_NO_MEMORY;
3162 if (oplock_type == LEASE_OPLOCK) {
3163 status = grant_fsp_lease(fsp, lck, lease, granted_lease);
3164 if (!NT_STATUS_IS_OK(status)) {
3165 del_share_mode(lck, fsp);
3166 return status;
3169 DBG_DEBUG("lease_state=%d\n", fsp->lease->lease.lease_state);
3172 fsp->oplock_type = oplock_type;
3174 return NT_STATUS_OK;
3177 /****************************************************************************
3178 Work out what access_mask to use from what the client sent us.
3179 ****************************************************************************/
3181 static NTSTATUS smbd_calculate_maximum_allowed_access_fsp(
3182 struct files_struct *dirfsp,
3183 struct files_struct *fsp,
3184 bool use_privs,
3185 uint32_t *p_access_mask)
3187 struct security_descriptor *sd = NULL;
3188 uint32_t access_granted = 0;
3189 uint32_t dosattrs;
3190 NTSTATUS status;
3192 /* Cope with symlinks */
3193 if (fsp == NULL || fsp_get_pathref_fd(fsp) == -1) {
3194 *p_access_mask = FILE_GENERIC_ALL;
3195 return NT_STATUS_OK;
3198 /* Cope with fake/printer fsp's. */
3199 if (fsp->fake_file_handle != NULL || fsp->print_file != NULL) {
3200 *p_access_mask = FILE_GENERIC_ALL;
3201 return NT_STATUS_OK;
3204 if (!use_privs && (get_current_uid(fsp->conn) == (uid_t)0)) {
3205 *p_access_mask |= FILE_GENERIC_ALL;
3206 return NT_STATUS_OK;
3209 status = SMB_VFS_FGET_NT_ACL(metadata_fsp(fsp),
3210 (SECINFO_OWNER |
3211 SECINFO_GROUP |
3212 SECINFO_DACL),
3213 talloc_tos(),
3214 &sd);
3216 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
3218 * File did not exist
3220 *p_access_mask = FILE_GENERIC_ALL;
3221 return NT_STATUS_OK;
3223 if (!NT_STATUS_IS_OK(status)) {
3224 DBG_ERR("Could not get acl on file %s: %s\n",
3225 fsp_str_dbg(fsp),
3226 nt_errstr(status));
3227 return status;
3231 * If we can access the path to this file, by
3232 * default we have FILE_READ_ATTRIBUTES from the
3233 * containing directory. See the section:
3234 * "Algorithm to Check Access to an Existing File"
3235 * in MS-FSA.pdf.
3237 * se_file_access_check()
3238 * also takes care of owner WRITE_DAC and READ_CONTROL.
3240 status = se_file_access_check(sd,
3241 get_current_nttok(fsp->conn),
3242 use_privs,
3243 (*p_access_mask & ~FILE_READ_ATTRIBUTES),
3244 &access_granted);
3246 TALLOC_FREE(sd);
3248 if (!NT_STATUS_IS_OK(status)) {
3249 DBG_ERR("Status %s on file %s: "
3250 "when calculating maximum access\n",
3251 nt_errstr(status),
3252 fsp_str_dbg(fsp));
3253 return status;
3256 *p_access_mask = (access_granted | FILE_READ_ATTRIBUTES);
3258 if (!(access_granted & DELETE_ACCESS)) {
3259 if (can_delete_file_in_directory(fsp->conn,
3260 dirfsp,
3261 fsp->fsp_name)) {
3262 *p_access_mask |= DELETE_ACCESS;
3266 dosattrs = fdos_mode(fsp);
3267 if ((dosattrs & FILE_ATTRIBUTE_READONLY) || !CAN_WRITE(fsp->conn)) {
3268 *p_access_mask &= ~(FILE_GENERIC_WRITE | DELETE_ACCESS);
3271 return NT_STATUS_OK;
3274 NTSTATUS smbd_calculate_access_mask_fsp(struct files_struct *dirfsp,
3275 struct files_struct *fsp,
3276 bool use_privs,
3277 uint32_t access_mask,
3278 uint32_t *access_mask_out)
3280 NTSTATUS status;
3281 uint32_t orig_access_mask = access_mask;
3282 uint32_t rejected_share_access;
3284 if (access_mask & SEC_MASK_INVALID) {
3285 DBG_DEBUG("access_mask [%8x] contains invalid bits\n",
3286 access_mask);
3287 return NT_STATUS_ACCESS_DENIED;
3291 * Convert GENERIC bits to specific bits.
3294 se_map_generic(&access_mask, &file_generic_mapping);
3296 /* Calculate MAXIMUM_ALLOWED_ACCESS if requested. */
3297 if (access_mask & MAXIMUM_ALLOWED_ACCESS) {
3299 status = smbd_calculate_maximum_allowed_access_fsp(
3300 dirfsp,
3301 fsp,
3302 use_privs,
3303 &access_mask);
3305 if (!NT_STATUS_IS_OK(status)) {
3306 return status;
3309 access_mask &= fsp->conn->share_access;
3312 rejected_share_access = access_mask & ~(fsp->conn->share_access);
3314 if (rejected_share_access) {
3315 DBG_INFO("Access denied on file %s: "
3316 "rejected by share access mask[0x%08X] "
3317 "orig[0x%08X] mapped[0x%08X] reject[0x%08X]\n",
3318 fsp_str_dbg(fsp),
3319 fsp->conn->share_access,
3320 orig_access_mask, access_mask,
3321 rejected_share_access);
3322 return NT_STATUS_ACCESS_DENIED;
3325 *access_mask_out = access_mask;
3326 return NT_STATUS_OK;
3329 /****************************************************************************
3330 Remove the deferred open entry under lock.
3331 ****************************************************************************/
3333 /****************************************************************************
3334 Return true if this is a state pointer to an asynchronous create.
3335 ****************************************************************************/
3337 bool is_deferred_open_async(const struct deferred_open_record *rec)
3339 return rec->async_open;
3342 static bool clear_ads(uint32_t create_disposition)
3344 bool ret = false;
3346 switch (create_disposition) {
3347 case FILE_SUPERSEDE:
3348 case FILE_OVERWRITE_IF:
3349 case FILE_OVERWRITE:
3350 ret = true;
3351 break;
3352 default:
3353 break;
3355 return ret;
3358 static int disposition_to_open_flags(uint32_t create_disposition)
3360 int ret = 0;
3363 * Currently we're using FILE_SUPERSEDE as the same as
3364 * FILE_OVERWRITE_IF but they really are
3365 * different. FILE_SUPERSEDE deletes an existing file
3366 * (requiring delete access) then recreates it.
3369 switch (create_disposition) {
3370 case FILE_SUPERSEDE:
3371 case FILE_OVERWRITE_IF:
3373 * If file exists replace/overwrite. If file doesn't
3374 * exist create.
3376 ret = O_CREAT|O_TRUNC;
3377 break;
3379 case FILE_OPEN:
3381 * If file exists open. If file doesn't exist error.
3383 ret = 0;
3384 break;
3386 case FILE_OVERWRITE:
3388 * If file exists overwrite. If file doesn't exist
3389 * error.
3391 ret = O_TRUNC;
3392 break;
3394 case FILE_CREATE:
3396 * If file exists error. If file doesn't exist create.
3398 ret = O_CREAT|O_EXCL;
3399 break;
3401 case FILE_OPEN_IF:
3403 * If file exists open. If file doesn't exist create.
3405 ret = O_CREAT;
3406 break;
3408 return ret;
3411 static int calculate_open_access_flags(uint32_t access_mask,
3412 uint32_t private_flags,
3413 NTTIME twrp)
3415 bool need_write, need_read;
3418 * Note that we ignore the append flag as append does not
3419 * mean the same thing under DOS and Unix.
3422 if (twrp != 0) {
3424 * Pave over the user requested mode and force O_RDONLY for the
3425 * file handle. Windows allows opening a VSS file with O_RDWR,
3426 * even though actual writes on the handle will fail.
3428 return O_RDONLY;
3431 need_write = (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA));
3432 if (!need_write) {
3433 return O_RDONLY;
3436 /* DENY_DOS opens are always underlying read-write on the
3437 file handle, no matter what the requested access mask
3438 says. */
3440 need_read =
3441 ((private_flags & NTCREATEX_FLAG_DENY_DOS) ||
3442 access_mask & (FILE_READ_ATTRIBUTES|FILE_READ_DATA|
3443 FILE_READ_EA|FILE_EXECUTE));
3445 if (!need_read) {
3446 return O_WRONLY;
3448 return O_RDWR;
3451 struct open_ntcreate_lock_state {
3452 struct share_mode_entry_prepare_state prepare_state;
3453 struct files_struct *fsp;
3454 const char *object_type;
3455 struct smb_request *req;
3456 uint32_t create_disposition;
3457 uint32_t access_mask;
3458 uint32_t open_access_mask;
3459 uint32_t share_access;
3460 int oplock_request;
3461 const struct smb2_lease *lease;
3462 bool first_open_attempt;
3463 bool keep_locked;
3464 NTSTATUS status;
3465 struct timespec write_time;
3466 share_mode_entry_prepare_unlock_fn_t cleanup_fn;
3469 static void open_ntcreate_lock_add_entry(struct share_mode_lock *lck,
3470 bool *keep_locked,
3471 void *private_data)
3473 struct open_ntcreate_lock_state *state =
3474 (struct open_ntcreate_lock_state *)private_data;
3477 * By default drop the g_lock again if we leave the
3478 * tdb chainlock.
3480 *keep_locked = false;
3482 state->status = check_and_store_share_mode(state->fsp,
3483 state->req,
3484 lck,
3485 state->create_disposition,
3486 state->access_mask,
3487 state->open_access_mask,
3488 state->share_access,
3489 state->oplock_request,
3490 state->lease,
3491 state->first_open_attempt);
3492 if (!NT_STATUS_IS_OK(state->status)) {
3493 return;
3496 state->write_time = get_share_mode_write_time(lck);
3499 * keep the g_lock while existing the tdb chainlock,
3500 * we we're asked to, which mean we'll keep
3501 * the share_mode_lock during object creation,
3502 * or setting delete on close.
3504 *keep_locked = state->keep_locked;
3507 static void open_ntcreate_lock_cleanup_oplock(struct share_mode_lock *lck,
3508 void *private_data)
3510 struct open_ntcreate_lock_state *state =
3511 (struct open_ntcreate_lock_state *)private_data;
3512 bool ok;
3514 ok = remove_share_oplock(lck, state->fsp);
3515 if (!ok) {
3516 DBG_ERR("Could not remove oplock for %s %s\n",
3517 state->object_type, fsp_str_dbg(state->fsp));
3521 static void open_ntcreate_lock_cleanup_entry(struct share_mode_lock *lck,
3522 void *private_data)
3524 struct open_ntcreate_lock_state *state =
3525 (struct open_ntcreate_lock_state *)private_data;
3526 bool ok;
3528 ok = del_share_mode(lck, state->fsp);
3529 if (!ok) {
3530 DBG_ERR("Could not delete share entry for %s %s\n",
3531 state->object_type, fsp_str_dbg(state->fsp));
3535 static void possibly_set_archive(struct connection_struct *conn,
3536 struct files_struct *fsp,
3537 struct smb_filename *smb_fname,
3538 struct smb_filename *parent_dir_fname,
3539 int info,
3540 uint32_t dosattrs,
3541 mode_t *unx_mode)
3543 bool set_archive = false;
3544 int ret;
3546 if (info == FILE_WAS_OPENED) {
3547 return;
3550 /* Overwritten files should be initially set as archive */
3551 if ((info == FILE_WAS_OVERWRITTEN && lp_map_archive(SNUM(conn)))) {
3552 set_archive = true;
3553 } else if (lp_store_dos_attributes(SNUM(conn))) {
3554 set_archive = true;
3556 if (!set_archive) {
3557 return;
3560 ret = file_set_dosmode(conn,
3561 smb_fname,
3562 dosattrs | FILE_ATTRIBUTE_ARCHIVE,
3563 parent_dir_fname,
3564 true);
3565 if (ret != 0) {
3566 return;
3568 *unx_mode = smb_fname->st.st_ex_mode;
3571 /****************************************************************************
3572 Open a file with a share mode. Passed in an already created files_struct *.
3573 ****************************************************************************/
3575 static NTSTATUS open_file_ntcreate(connection_struct *conn,
3576 struct smb_request *req,
3577 uint32_t access_mask, /* access bits (FILE_READ_DATA etc.) */
3578 uint32_t share_access, /* share constants (FILE_SHARE_READ etc) */
3579 uint32_t create_disposition, /* FILE_OPEN_IF etc. */
3580 uint32_t create_options, /* options such as delete on close. */
3581 uint32_t new_dos_attributes, /* attributes used for new file. */
3582 int oplock_request, /* internal Samba oplock codes. */
3583 const struct smb2_lease *lease,
3584 /* Information (FILE_EXISTS etc.) */
3585 uint32_t private_flags, /* Samba specific flags. */
3586 struct smb_filename *parent_dir_fname, /* parent. */
3587 struct smb_filename *smb_fname_atname, /* atname relative to parent. */
3588 int *pinfo,
3589 files_struct *fsp)
3591 struct smb_filename *smb_fname = fsp->fsp_name;
3592 int flags=0;
3593 bool file_existed = VALID_STAT(smb_fname->st);
3594 bool def_acl = False;
3595 bool posix_open = False;
3596 bool new_file_created = False;
3597 bool truncated = false;
3598 bool first_open_attempt = true;
3599 bool is_twrp = (smb_fname_atname->twrp != 0);
3600 NTSTATUS fsp_open = NT_STATUS_ACCESS_DENIED;
3601 mode_t new_unx_mode = (mode_t)0;
3602 mode_t unx_mode = (mode_t)0;
3603 int info;
3604 uint32_t existing_dos_attributes = 0;
3605 struct open_ntcreate_lock_state lck_state = {};
3606 bool keep_locked = false;
3607 uint32_t open_access_mask = access_mask;
3608 NTSTATUS status;
3609 SMB_STRUCT_STAT saved_stat = smb_fname->st;
3610 struct timespec old_write_time;
3611 bool setup_poll = false;
3612 NTSTATUS ulstatus;
3614 if (conn->printer) {
3616 * Printers are handled completely differently.
3617 * Most of the passed parameters are ignored.
3620 if (pinfo) {
3621 *pinfo = FILE_WAS_CREATED;
3624 DBG_DEBUG("printer open fname=%s\n",
3625 smb_fname_str_dbg(smb_fname));
3627 if (!req) {
3628 DBG_ERR("printer open without an SMB request!\n");
3629 return NT_STATUS_INTERNAL_ERROR;
3632 return print_spool_open(fsp, smb_fname->base_name,
3633 req->vuid);
3636 if (new_dos_attributes & FILE_FLAG_POSIX_SEMANTICS) {
3637 posix_open = True;
3638 unx_mode = (mode_t)(new_dos_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
3639 new_dos_attributes = 0;
3640 } else {
3641 /* Windows allows a new file to be created and
3642 silently removes a FILE_ATTRIBUTE_DIRECTORY
3643 sent by the client. Do the same. */
3645 new_dos_attributes &= ~FILE_ATTRIBUTE_DIRECTORY;
3647 /* We add FILE_ATTRIBUTE_ARCHIVE to this as this mode is only used if the file is
3648 * created new. */
3649 unx_mode = unix_mode(
3650 conn,
3651 new_dos_attributes | FILE_ATTRIBUTE_ARCHIVE,
3652 smb_fname,
3653 parent_dir_fname->fsp);
3656 DEBUG(10, ("open_file_ntcreate: fname=%s, dos_attrs=0x%x "
3657 "access_mask=0x%x share_access=0x%x "
3658 "create_disposition = 0x%x create_options=0x%x "
3659 "unix mode=0%o oplock_request=%d private_flags = 0x%x\n",
3660 smb_fname_str_dbg(smb_fname), new_dos_attributes,
3661 access_mask, share_access, create_disposition,
3662 create_options, (unsigned int)unx_mode, oplock_request,
3663 (unsigned int)private_flags));
3665 if (req == NULL) {
3666 /* Ensure req == NULL means INTERNAL_OPEN_ONLY */
3667 SMB_ASSERT(oplock_request == INTERNAL_OPEN_ONLY);
3668 } else {
3669 /* And req != NULL means no INTERNAL_OPEN_ONLY */
3670 SMB_ASSERT(((oplock_request & INTERNAL_OPEN_ONLY) == 0));
3674 * Only non-internal opens can be deferred at all
3677 if (req) {
3678 struct deferred_open_record *open_rec;
3679 if (get_deferred_open_message_state(req, NULL, &open_rec)) {
3681 /* If it was an async create retry, the file
3682 didn't exist. */
3684 if (is_deferred_open_async(open_rec)) {
3685 SET_STAT_INVALID(smb_fname->st);
3686 file_existed = false;
3689 /* Ensure we don't reprocess this message. */
3690 remove_deferred_open_message_smb(req->xconn, req->mid);
3692 first_open_attempt = false;
3696 if (!posix_open) {
3697 new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
3698 if (file_existed) {
3700 * Only use stored DOS attributes for checks
3701 * against requested attributes (below via
3702 * open_match_attributes()), cf bug #11992
3703 * for details. -slow
3705 uint32_t attr = 0;
3707 status = SMB_VFS_FGET_DOS_ATTRIBUTES(
3708 conn,
3709 metadata_fsp(smb_fname->fsp),
3710 &attr);
3711 if (NT_STATUS_IS_OK(status)) {
3712 existing_dos_attributes = attr;
3717 /* ignore any oplock requests if oplocks are disabled */
3718 if (!lp_oplocks(SNUM(conn)) ||
3719 IS_VETO_OPLOCK_PATH(conn, smb_fname->base_name)) {
3720 /* Mask off everything except the private Samba bits. */
3721 oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
3724 /* this is for OS/2 long file names - say we don't support them */
3725 if (req != NULL && !req->posix_pathnames &&
3726 strstr(smb_fname->base_name,".+,;=[].")) {
3727 /* OS/2 Workplace shell fix may be main code stream in a later
3728 * release. */
3729 DEBUG(5,("open_file_ntcreate: OS/2 long filenames are not "
3730 "supported.\n"));
3731 if (use_nt_status()) {
3732 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3734 return NT_STATUS_DOS(ERRDOS, ERRcannotopen);
3737 switch( create_disposition ) {
3738 case FILE_OPEN:
3739 /* If file exists open. If file doesn't exist error. */
3740 if (!file_existed) {
3741 DEBUG(5,("open_file_ntcreate: FILE_OPEN "
3742 "requested for file %s and file "
3743 "doesn't exist.\n",
3744 smb_fname_str_dbg(smb_fname)));
3745 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3747 break;
3749 case FILE_OVERWRITE:
3750 /* If file exists overwrite. If file doesn't exist
3751 * error. */
3752 if (!file_existed) {
3753 DEBUG(5,("open_file_ntcreate: FILE_OVERWRITE "
3754 "requested for file %s and file "
3755 "doesn't exist.\n",
3756 smb_fname_str_dbg(smb_fname) ));
3757 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3759 if (is_twrp) {
3760 return NT_STATUS_MEDIA_WRITE_PROTECTED;
3762 break;
3764 case FILE_CREATE:
3765 /* If file exists error. If file doesn't exist
3766 * create. */
3767 if (file_existed) {
3768 DEBUG(5,("open_file_ntcreate: FILE_CREATE "
3769 "requested for file %s and file "
3770 "already exists.\n",
3771 smb_fname_str_dbg(smb_fname)));
3772 if (S_ISDIR(smb_fname->st.st_ex_mode)) {
3773 return NT_STATUS_FILE_IS_A_DIRECTORY;
3775 return NT_STATUS_OBJECT_NAME_COLLISION;
3777 if (is_twrp) {
3778 return NT_STATUS_MEDIA_WRITE_PROTECTED;
3780 break;
3782 case FILE_SUPERSEDE:
3783 case FILE_OVERWRITE_IF:
3784 if (is_twrp) {
3785 return NT_STATUS_MEDIA_WRITE_PROTECTED;
3787 break;
3788 case FILE_OPEN_IF:
3789 if (is_twrp) {
3790 if (!file_existed) {
3791 return NT_STATUS_MEDIA_WRITE_PROTECTED;
3793 create_disposition = FILE_OPEN;
3795 break;
3796 default:
3797 return NT_STATUS_INVALID_PARAMETER;
3800 flags = disposition_to_open_flags(create_disposition);
3802 /* We only care about matching attributes on file exists and
3803 * overwrite. */
3805 if (!posix_open && file_existed &&
3806 ((create_disposition == FILE_OVERWRITE) ||
3807 (create_disposition == FILE_OVERWRITE_IF))) {
3808 if (!open_match_attributes(conn, existing_dos_attributes,
3809 new_dos_attributes,
3810 unx_mode, &new_unx_mode)) {
3811 DEBUG(5,("open_file_ntcreate: attributes mismatch "
3812 "for file %s (%x %x) (0%o, 0%o)\n",
3813 smb_fname_str_dbg(smb_fname),
3814 existing_dos_attributes,
3815 new_dos_attributes,
3816 (unsigned int)smb_fname->st.st_ex_mode,
3817 (unsigned int)unx_mode ));
3818 return NT_STATUS_ACCESS_DENIED;
3822 status = smbd_calculate_access_mask_fsp(parent_dir_fname->fsp,
3823 smb_fname->fsp,
3824 false,
3825 access_mask,
3826 &access_mask);
3827 if (!NT_STATUS_IS_OK(status)) {
3828 DBG_DEBUG("smbd_calculate_access_mask_fsp "
3829 "on file %s returned %s\n",
3830 smb_fname_str_dbg(smb_fname),
3831 nt_errstr(status));
3832 return status;
3835 open_access_mask = access_mask;
3837 if (flags & O_TRUNC) {
3838 open_access_mask |= FILE_WRITE_DATA; /* This will cause oplock breaks. */
3841 if (file_existed) {
3843 * stat opens on existing files don't get oplocks.
3844 * They can get leases.
3846 * Note that we check for stat open on the *open_access_mask*,
3847 * i.e. the access mask we actually used to do the open,
3848 * not the one the client asked for (which is in
3849 * fsp->access_mask). This is due to the fact that
3850 * FILE_OVERWRITE and FILE_OVERWRITE_IF add in O_TRUNC,
3851 * which adds FILE_WRITE_DATA to open_access_mask.
3853 if (is_oplock_stat_open(open_access_mask) && lease == NULL) {
3854 oplock_request = NO_OPLOCK;
3858 DEBUG(10, ("open_file_ntcreate: fname=%s, after mapping "
3859 "access_mask=0x%x\n", smb_fname_str_dbg(smb_fname),
3860 access_mask));
3863 * Note that we ignore the append flag as append does not
3864 * mean the same thing under DOS and Unix.
3867 flags |= calculate_open_access_flags(access_mask,
3868 private_flags,
3869 smb_fname->twrp);
3872 * Currently we only look at FILE_WRITE_THROUGH for create options.
3875 #if defined(O_SYNC)
3876 if ((create_options & FILE_WRITE_THROUGH) && lp_strict_sync(SNUM(conn))) {
3877 flags |= O_SYNC;
3879 #endif /* O_SYNC */
3881 if (posix_open && (access_mask & FILE_APPEND_DATA)) {
3882 flags |= O_APPEND;
3885 if (!posix_open && !CAN_WRITE(conn)) {
3887 * We should really return a permission denied error if either
3888 * O_CREAT or O_TRUNC are set, but for compatibility with
3889 * older versions of Samba we just AND them out.
3891 flags &= ~(O_CREAT | O_TRUNC);
3895 * With kernel oplocks the open breaking an oplock
3896 * blocks until the oplock holder has given up the
3897 * oplock or closed the file. We prevent this by always
3898 * trying to open the file with O_NONBLOCK (see "man
3899 * fcntl" on Linux).
3901 * If a process that doesn't use the smbd open files
3902 * database or communication methods holds a kernel
3903 * oplock we must periodically poll for available open
3904 * using O_NONBLOCK.
3906 flags |= O_NONBLOCK;
3909 * Ensure we can't write on a read-only share or file.
3912 if (((flags & O_ACCMODE) != O_RDONLY) && file_existed &&
3913 (!CAN_WRITE(conn) ||
3914 (existing_dos_attributes & FILE_ATTRIBUTE_READONLY))) {
3915 DEBUG(5,("open_file_ntcreate: write access requested for "
3916 "file %s on read only %s\n",
3917 smb_fname_str_dbg(smb_fname),
3918 !CAN_WRITE(conn) ? "share" : "file" ));
3919 return NT_STATUS_ACCESS_DENIED;
3922 if (VALID_STAT(smb_fname->st)) {
3924 * Only try and create a file id before open
3925 * for an existing file. For a file being created
3926 * this won't do anything useful until the file
3927 * exists and has a valid stat struct.
3929 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
3931 fh_set_private_options(fsp->fh, private_flags);
3932 fsp->access_mask = open_access_mask; /* We change this to the
3933 * requested access_mask after
3934 * the open is done. */
3935 if (posix_open) {
3936 fsp->fsp_flags.posix_open = true;
3939 if ((create_options & FILE_DELETE_ON_CLOSE) && (flags & O_CREAT) &&
3940 !file_existed) {
3941 /* Delete on close semantics for new files. */
3942 status = can_set_delete_on_close(fsp,
3943 new_dos_attributes);
3944 if (!NT_STATUS_IS_OK(status)) {
3945 fd_close(fsp);
3946 return status;
3951 * Ensure we pay attention to default ACLs on directories if required.
3954 if ((flags & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
3955 (def_acl = directory_has_default_acl_fsp(parent_dir_fname->fsp))) {
3956 unx_mode = (0777 & lp_create_mask(SNUM(conn)));
3959 DEBUG(4,
3960 ("calling open_file with flags=0x%X mode=0%o, "
3961 "access_mask = 0x%x, open_access_mask = 0x%x\n",
3962 (unsigned int)flags,
3963 (unsigned int)unx_mode,
3964 (unsigned int)access_mask,
3965 (unsigned int)open_access_mask));
3968 struct vfs_open_how how = {
3969 .flags = flags,
3970 .mode = unx_mode,
3973 if (create_options & FILE_OPEN_FOR_BACKUP_INTENT) {
3974 how.resolve |= VFS_OPEN_HOW_WITH_BACKUP_INTENT;
3977 fsp_open = open_file(req,
3978 parent_dir_fname->fsp,
3979 smb_fname_atname,
3980 fsp,
3981 &how,
3982 access_mask,
3983 open_access_mask,
3984 private_flags,
3985 &new_file_created);
3987 if (NT_STATUS_EQUAL(fsp_open, NT_STATUS_NETWORK_BUSY)) {
3988 if (file_existed && S_ISFIFO(fsp->fsp_name->st.st_ex_mode)) {
3989 DEBUG(10, ("FIFO busy\n"));
3990 return NT_STATUS_NETWORK_BUSY;
3992 if (req == NULL) {
3993 DEBUG(10, ("Internal open busy\n"));
3994 return NT_STATUS_NETWORK_BUSY;
3997 * This handles the kernel oplock case:
3999 * the file has an active kernel oplock and the open() returned
4000 * EWOULDBLOCK/EAGAIN which maps to NETWORK_BUSY.
4002 * "Samba locking.tdb oplocks" are handled below after acquiring
4003 * the sharemode lock with get_share_mode_lock().
4005 setup_poll = true;
4008 if (NT_STATUS_EQUAL(fsp_open, NT_STATUS_RETRY)) {
4010 * EINTR from the open(2) syscall. Just setup a retry
4011 * in a bit. We can't use the sys_write() tight retry
4012 * loop here, as we might have to actually deal with
4013 * lease-break signals to avoid a deadlock.
4015 setup_poll = true;
4018 if (setup_poll) {
4020 * Retry once a second. If there's a share_mode_lock
4021 * around, also wait for it in case it was smbd
4022 * holding that kernel oplock that can quickly tell us
4023 * the oplock got removed.
4026 setup_poll_open(req,
4027 &fsp->file_id,
4028 tevent_timeval_set(OPLOCK_BREAK_TIMEOUT * 2,
4030 tevent_timeval_set(1, 0));
4032 return NT_STATUS_SHARING_VIOLATION;
4035 if (!NT_STATUS_IS_OK(fsp_open)) {
4036 bool wait_for_aio = NT_STATUS_EQUAL(
4037 fsp_open, NT_STATUS_MORE_PROCESSING_REQUIRED);
4038 if (wait_for_aio) {
4039 schedule_async_open(req);
4041 return fsp_open;
4044 if (new_file_created) {
4046 * As we atomically create using O_CREAT|O_EXCL,
4047 * then if new_file_created is true, then
4048 * file_existed *MUST* have been false (even
4049 * if the file was previously detected as being
4050 * there).
4052 file_existed = false;
4055 if (file_existed && !check_same_dev_ino(&saved_stat, &smb_fname->st)) {
4057 * The file did exist, but some other (local or NFS)
4058 * process either renamed/unlinked and re-created the
4059 * file with different dev/ino after we walked the path,
4060 * but before we did the open. We could retry the
4061 * open but it's a rare enough case it's easier to
4062 * just fail the open to prevent creating any problems
4063 * in the open file db having the wrong dev/ino key.
4065 fd_close(fsp);
4066 DBG_WARNING("file %s - dev/ino mismatch. "
4067 "Old (dev=%ju, ino=%ju). "
4068 "New (dev=%ju, ino=%ju). Failing open "
4069 "with NT_STATUS_ACCESS_DENIED.\n",
4070 smb_fname_str_dbg(smb_fname),
4071 (uintmax_t)saved_stat.st_ex_dev,
4072 (uintmax_t)saved_stat.st_ex_ino,
4073 (uintmax_t)smb_fname->st.st_ex_dev,
4074 (uintmax_t)smb_fname->st.st_ex_ino);
4075 return NT_STATUS_ACCESS_DENIED;
4078 old_write_time = smb_fname->st.st_ex_mtime;
4081 * Deal with the race condition where two smbd's detect the
4082 * file doesn't exist and do the create at the same time. One
4083 * of them will win and set a share mode, the other (ie. this
4084 * one) should check if the requested share mode for this
4085 * create is allowed.
4089 * Now the file exists and fsp is successfully opened,
4090 * fsp->dev and fsp->inode are valid and should replace the
4091 * dev=0,inode=0 from a non existent file. Spotted by
4092 * Nadav Danieli <nadavd@exanet.com>. JRA.
4095 if (new_file_created) {
4096 info = FILE_WAS_CREATED;
4097 } else {
4098 if (flags & O_TRUNC) {
4099 info = FILE_WAS_OVERWRITTEN;
4100 } else {
4101 info = FILE_WAS_OPENED;
4106 * If we created a new file, overwrite an existing one
4107 * or going to delete it later, we should keep
4108 * the share_mode_lock (g_lock) until we call
4109 * share_mode_entry_prepare_unlock()
4111 if (info != FILE_WAS_OPENED) {
4112 keep_locked = true;
4113 } else if (create_options & FILE_DELETE_ON_CLOSE) {
4114 keep_locked = true;
4117 lck_state = (struct open_ntcreate_lock_state) {
4118 .fsp = fsp,
4119 .object_type = "file",
4120 .req = req,
4121 .create_disposition = create_disposition,
4122 .access_mask = access_mask,
4123 .open_access_mask = open_access_mask,
4124 .share_access = share_access,
4125 .oplock_request = oplock_request,
4126 .lease = lease,
4127 .first_open_attempt = first_open_attempt,
4128 .keep_locked = keep_locked,
4131 status = share_mode_entry_prepare_lock_add(&lck_state.prepare_state,
4132 fsp->file_id,
4133 conn->connectpath,
4134 smb_fname,
4135 &old_write_time,
4136 open_ntcreate_lock_add_entry,
4137 &lck_state);
4138 if (!NT_STATUS_IS_OK(status)) {
4139 DBG_ERR("share_mode_entry_prepare_lock_add() failed for %s - %s\n",
4140 smb_fname_str_dbg(smb_fname), nt_errstr(status));
4141 fd_close(fsp);
4142 return status;
4145 status = lck_state.status;
4146 if (!NT_STATUS_IS_OK(status)) {
4147 fd_close(fsp);
4148 return status;
4152 * From here we need to use 'goto unlock;' instead of return !!!
4155 if (fsp->oplock_type != NO_OPLOCK && fsp->oplock_type != LEASE_OPLOCK) {
4157 * Now ask for kernel oplocks
4158 * and cleanup on failure.
4160 status = set_file_oplock(fsp);
4161 if (!NT_STATUS_IS_OK(status)) {
4163 * Could not get the kernel oplock
4165 lck_state.cleanup_fn =
4166 open_ntcreate_lock_cleanup_oplock;
4167 fsp->oplock_type = NO_OPLOCK;
4171 /* Should we atomically (to the client at least) truncate ? */
4172 if ((!new_file_created) && (flags & O_TRUNC) &&
4173 (S_ISREG(fsp->fsp_name->st.st_ex_mode))) {
4174 int ret;
4176 ret = SMB_VFS_FTRUNCATE(fsp, 0);
4177 if (ret != 0) {
4178 status = map_nt_error_from_unix(errno);
4179 lck_state.cleanup_fn =
4180 open_ntcreate_lock_cleanup_entry;
4181 goto unlock;
4183 truncated = true;
4187 * We have the share entry *locked*.....
4190 /* Delete streams if create_disposition requires it */
4191 if (!new_file_created &&
4192 clear_ads(create_disposition) &&
4193 !fsp_is_alternate_stream(fsp)) {
4194 status = delete_all_streams(conn, smb_fname);
4195 if (!NT_STATUS_IS_OK(status)) {
4196 lck_state.cleanup_fn =
4197 open_ntcreate_lock_cleanup_entry;
4198 goto unlock;
4202 if (!fsp->fsp_flags.is_pathref &&
4203 fsp_get_io_fd(fsp) != -1 &&
4204 lp_kernel_share_modes(SNUM(conn)))
4206 int ret;
4208 * Beware: streams implementing VFS modules may
4209 * implement streams in a way that fsp will have the
4210 * basefile open in the fsp fd, so lacking a distinct
4211 * fd for the stream the file-system sharemode will
4212 * apply on the basefile which is wrong. The actual
4213 * check is deferred to the VFS module implementing
4214 * the file-system sharemode call.
4216 ret = SMB_VFS_FILESYSTEM_SHAREMODE(fsp,
4217 share_access,
4218 access_mask);
4219 if (ret == -1){
4220 status = NT_STATUS_SHARING_VIOLATION;
4221 lck_state.cleanup_fn =
4222 open_ntcreate_lock_cleanup_entry;
4223 goto unlock;
4226 fsp->fsp_flags.kernel_share_modes_taken = true;
4230 * At this point onwards, we can guarantee that the share entry
4231 * is locked, whether we created the file or not, and that the
4232 * deny mode is compatible with all current opens.
4236 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
4237 * but we don't have to store this - just ignore it on access check.
4239 if (conn_using_smb2(conn->sconn)) {
4241 * SMB2 doesn't return it (according to Microsoft tests).
4242 * Test Case: TestSuite_ScenarioNo009GrantedAccessTestS0
4243 * File created with access = 0x7 (Read, Write, Delete)
4244 * Query Info on file returns 0x87 (Read, Write, Delete, Read Attributes)
4246 fsp->access_mask = access_mask;
4247 } else {
4248 /* But SMB1 does. */
4249 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
4252 if (pinfo) {
4253 *pinfo = info;
4256 /* Handle strange delete on close create semantics. */
4257 if (create_options & FILE_DELETE_ON_CLOSE) {
4258 if (!new_file_created) {
4259 status = can_set_delete_on_close(fsp,
4260 existing_dos_attributes);
4262 if (!NT_STATUS_IS_OK(status)) {
4263 /* Remember to delete the mode we just added. */
4264 lck_state.cleanup_fn =
4265 open_ntcreate_lock_cleanup_entry;
4266 goto unlock;
4269 /* Note that here we set the *initial* delete on close flag,
4270 not the regular one. The magic gets handled in close. */
4271 fsp->fsp_flags.initial_delete_on_close = true;
4274 possibly_set_archive(conn,
4275 fsp,
4276 smb_fname,
4277 parent_dir_fname,
4278 info,
4279 new_dos_attributes,
4280 &smb_fname->st.st_ex_mode);
4282 /* Determine sparse flag. */
4283 if (posix_open) {
4284 /* POSIX opens are sparse by default. */
4285 fsp->fsp_flags.is_sparse = true;
4286 } else {
4287 fsp->fsp_flags.is_sparse =
4288 (existing_dos_attributes & FILE_ATTRIBUTE_SPARSE);
4292 * Take care of inherited ACLs on created files - if default ACL not
4293 * selected.
4296 if (!posix_open && new_file_created && !def_acl) {
4297 if (unx_mode != smb_fname->st.st_ex_mode) {
4298 int ret = SMB_VFS_FCHMOD(fsp, unx_mode);
4299 if (ret == -1) {
4300 DBG_INFO("failed to reset "
4301 "attributes of file %s to 0%o\n",
4302 smb_fname_str_dbg(smb_fname),
4303 (unsigned int)unx_mode);
4307 } else if (new_unx_mode) {
4309 * We only get here in the case of:
4311 * a). Not a POSIX open.
4312 * b). File already existed.
4313 * c). File was overwritten.
4314 * d). Requested DOS attributes didn't match
4315 * the DOS attributes on the existing file.
4317 * In that case new_unx_mode has been set
4318 * equal to the calculated mode (including
4319 * possible inheritance of the mode from the
4320 * containing directory).
4322 * Note this mode was calculated with the
4323 * DOS attribute FILE_ATTRIBUTE_ARCHIVE added,
4324 * so the mode change here is suitable for
4325 * an overwritten file.
4328 if (new_unx_mode != smb_fname->st.st_ex_mode) {
4329 int ret = SMB_VFS_FCHMOD(fsp, new_unx_mode);
4330 if (ret == -1) {
4331 DBG_INFO("failed to reset "
4332 "attributes of file %s to 0%o\n",
4333 smb_fname_str_dbg(smb_fname),
4334 (unsigned int)new_unx_mode);
4340 * Deal with other opens having a modified write time.
4342 if (fsp_getinfo_ask_sharemode(fsp) &&
4343 !is_omit_timespec(&lck_state.write_time))
4345 update_stat_ex_mtime(&fsp->fsp_name->st, lck_state.write_time);
4348 status = NT_STATUS_OK;
4350 unlock:
4351 ulstatus = share_mode_entry_prepare_unlock(&lck_state.prepare_state,
4352 lck_state.cleanup_fn,
4353 &lck_state);
4354 if (!NT_STATUS_IS_OK(ulstatus)) {
4355 DBG_ERR("share_mode_entry_prepare_unlock() failed for %s - %s\n",
4356 smb_fname_str_dbg(smb_fname), nt_errstr(ulstatus));
4357 smb_panic("share_mode_entry_prepare_unlock() failed!");
4360 if (info == FILE_WAS_CREATED) {
4361 notify_fname(conn,
4362 NOTIFY_ACTION_ADDED |
4363 NOTIFY_ACTION_DIRLEASE_BREAK,
4364 FILE_NOTIFY_CHANGE_FILE_NAME,
4365 smb_fname,
4366 fsp_get_smb2_lease(fsp));
4368 if (truncated) {
4369 notify_fname(fsp->conn,
4370 NOTIFY_ACTION_MODIFIED |
4371 NOTIFY_ACTION_DIRLEASE_BREAK,
4372 FILE_NOTIFY_CHANGE_SIZE |
4373 FILE_NOTIFY_CHANGE_ATTRIBUTES,
4374 fsp->fsp_name,
4375 fsp_get_smb2_lease(fsp));
4377 if (!NT_STATUS_IS_OK(status)) {
4378 fd_close(fsp);
4379 return status;
4382 return NT_STATUS_OK;
4385 static NTSTATUS apply_new_nt_acl(struct files_struct *dirfsp,
4386 struct files_struct *fsp,
4387 struct security_descriptor *sd)
4389 NTSTATUS status;
4391 if (sd != NULL) {
4393 * According to the MS documentation, the only time the security
4394 * descriptor is applied to the opened file is iff we *created* the
4395 * file; an existing file stays the same.
4397 * Also, it seems (from observation) that you can open the file with
4398 * any access mask but you can still write the sd. We need to override
4399 * the granted access before we call set_sd
4400 * Patch for bug #2242 from Tom Lackemann <cessnatomny@yahoo.com>.
4403 uint32_t sec_info_sent;
4404 uint32_t saved_access_mask = fsp->access_mask;
4406 sec_info_sent = get_sec_info(sd);
4408 fsp->access_mask = FILE_GENERIC_ALL;
4410 if (sec_info_sent & (SECINFO_OWNER|
4411 SECINFO_GROUP|
4412 SECINFO_DACL|
4413 SECINFO_SACL)) {
4414 status = set_sd(fsp, sd, sec_info_sent);
4415 } else {
4416 status = NT_STATUS_OK;
4419 fsp->access_mask = saved_access_mask;
4421 if (!NT_STATUS_IS_OK(status)) {
4422 DBG_WARNING("set_sd() failed for '%s': %s\n",
4423 fsp_str_dbg(fsp), nt_errstr(status));
4424 return status;
4427 return NT_STATUS_OK;
4430 if (!lp_inherit_acls(SNUM(fsp->conn))) {
4431 return NT_STATUS_OK;
4434 /* Inherit from parent. Errors here are not fatal. */
4435 status = inherit_new_acl(dirfsp, fsp);
4436 if (!NT_STATUS_IS_OK(status)) {
4437 DBG_WARNING("inherit_new_acl failed for %s with %s\n",
4438 fsp_str_dbg(fsp), nt_errstr(status));
4441 return NT_STATUS_OK;
4444 bool smbd_is_tmpname(const char *n, int *_unlink_flags)
4446 const char *p = n;
4447 int unlink_flags = INT_MAX;
4448 struct server_id id;
4449 bool exists;
4451 if (_unlink_flags != NULL) {
4452 *_unlink_flags = INT_MAX;
4455 if (!IS_SMBD_TMPNAME_PREFIX(n)) {
4456 return false;
4458 p += sizeof(SMBD_TMPNAME_PREFIX) - 1;
4459 switch (p[0]) {
4460 case 'D':
4461 unlink_flags = AT_REMOVEDIR;
4462 break;
4463 default:
4464 return false;
4466 p += 1;
4467 if (p[0] != ':') {
4468 return false;
4470 p += 1;
4472 id = server_id_from_string_ex(get_my_vnn(), '%', p);
4473 if (id.pid == UINT64_MAX) {
4474 return false;
4476 if (id.unique_id == 0) {
4477 return false;
4479 if (id.unique_id == SERVERID_UNIQUE_ID_NOT_TO_VERIFY) {
4480 return false;
4483 if (_unlink_flags == NULL) {
4484 return true;
4487 exists = serverid_exists(&id);
4488 if (!exists) {
4490 * let the caller know it's stale
4491 * and should be removed
4493 *_unlink_flags = unlink_flags;
4496 return true;
4499 static NTSTATUS mkdir_internal(connection_struct *conn,
4500 struct smb_filename *parent_dir_fname, /* parent. */
4501 struct smb_filename *smb_fname_atname, /* atname relative to parent. */
4502 struct smb_filename *smb_dname, /* full pathname from root of share. */
4503 struct security_descriptor *sd,
4504 uint32_t file_attributes,
4505 struct files_struct *fsp)
4507 TALLOC_CTX *frame = talloc_stackframe();
4508 const struct loadparm_substitution *lp_sub =
4509 loadparm_s3_global_substitution();
4510 mode_t mode;
4511 NTSTATUS status;
4512 bool posix_open = false;
4513 bool need_re_stat = false;
4514 uint32_t access_mask = SEC_DIR_ADD_SUBDIR;
4515 struct smb_filename *first_atname = NULL;
4516 struct smb_filename *tmp_atname = NULL;
4517 char *orig_dname = NULL;
4518 char *tmp_dname = NULL;
4519 int vfs_use_tmp = lp_vfs_mkdir_use_tmp_name(SNUM(conn));
4520 bool need_tmpname = false;
4521 struct server_id id = messaging_server_id(conn->sconn->msg_ctx);
4522 struct server_id_buf idbuf;
4523 char *idstr = server_id_str_buf_unique_ex(id, '%', &idbuf);
4524 struct vfs_open_how how = { .flags = O_RDONLY|O_DIRECTORY, };
4525 struct vfs_rename_how rhow = { .flags = VFS_RENAME_HOW_NO_REPLACE, };
4526 int ret;
4528 if (!CAN_WRITE(conn) || (access_mask & ~(conn->share_access))) {
4529 DBG_INFO("failing share access %s\n",
4530 lp_servicename(talloc_tos(), lp_sub, SNUM(conn)));
4531 TALLOC_FREE(frame);
4532 return NT_STATUS_ACCESS_DENIED;
4535 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
4536 posix_open = true;
4537 mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
4538 } else {
4539 mode = unix_mode(conn,
4540 FILE_ATTRIBUTE_DIRECTORY,
4541 smb_dname,
4542 parent_dir_fname->fsp);
4545 status = check_parent_access_fsp(parent_dir_fname->fsp, access_mask);
4546 if(!NT_STATUS_IS_OK(status)) {
4547 DBG_INFO("check_parent_access_fsp "
4548 "on directory %s for path %s returned %s\n",
4549 smb_fname_str_dbg(parent_dir_fname),
4550 smb_dname->base_name,
4551 nt_errstr(status));
4552 TALLOC_FREE(frame);
4553 return status;
4556 if (lp_inherit_acls(SNUM(conn))) {
4557 if (directory_has_default_acl_fsp(parent_dir_fname->fsp)) {
4558 mode = (0777 & lp_directory_mask(SNUM(conn)));
4560 need_tmpname = true;
4561 } else if (lp_store_dos_attributes(SNUM(conn))) {
4562 need_tmpname = true;
4563 } else if (lp_inherit_permissions(SNUM(conn))) {
4564 need_tmpname = true;
4565 } else if (lp_inherit_owner(SNUM(conn)) != INHERIT_OWNER_NO) {
4566 need_tmpname = true;
4567 } else if (lp_nt_acl_support(SNUM(conn)) && sd != NULL) {
4568 need_tmpname = true;
4571 if (vfs_use_tmp != Auto) {
4572 need_tmpname = vfs_use_tmp;
4575 if (!need_tmpname) {
4576 first_atname = smb_fname_atname;
4577 goto mkdir_first;
4581 * In order to avoid races where other clients could
4582 * see the directory before it is setup completely
4583 * we use a temporary name and rename it
4584 * when everything is ready.
4587 orig_dname = smb_dname->base_name;
4589 tmp_atname = cp_smb_filename(frame,
4590 smb_fname_atname);
4591 if (tmp_atname == NULL) {
4592 TALLOC_FREE(frame);
4593 return NT_STATUS_NO_MEMORY;
4595 TALLOC_FREE(tmp_atname->base_name);
4596 tmp_atname->base_name = talloc_asprintf(tmp_atname,
4597 "%s%s:%s",
4598 SMBD_TMPDIR_PREFIX,
4599 idstr,
4600 smb_fname_atname->base_name);
4601 if (tmp_atname == NULL) {
4602 TALLOC_FREE(frame);
4603 return NT_STATUS_NO_MEMORY;
4605 SMB_ASSERT(smbd_is_tmpname(tmp_atname->base_name, NULL));
4606 if (!ISDOT(parent_dir_fname->base_name)) {
4607 tmp_dname = talloc_asprintf(frame,
4608 "%s/%s",
4609 parent_dir_fname->base_name,
4610 tmp_atname->base_name);
4611 if (tmp_dname == NULL) {
4612 TALLOC_FREE(frame);
4613 return NT_STATUS_NO_MEMORY;
4615 } else {
4616 tmp_dname = talloc_strdup(frame, tmp_atname->base_name);
4617 if (tmp_dname == NULL) {
4618 TALLOC_FREE(frame);
4619 return NT_STATUS_NO_MEMORY;
4623 smb_dname->base_name = tmp_dname;
4625 DBG_DEBUG("temporary replace '%s' by '%s'\n",
4626 orig_dname, tmp_dname);
4628 first_atname = tmp_atname;
4630 mkdir_first:
4631 ret = SMB_VFS_MKDIRAT(conn,
4632 parent_dir_fname->fsp,
4633 first_atname,
4634 mode);
4635 if (ret != 0) {
4636 status = map_nt_error_from_unix(errno);
4637 DBG_NOTICE("MKDIRAT failed for '%s': %s\n",
4638 smb_fname_str_dbg(smb_dname), nt_errstr(status));
4639 goto restore_orig;
4643 * Make this a pathref fsp for now. open_directory() will reopen as a
4644 * full fsp.
4646 fsp->fsp_flags.is_pathref = true;
4648 status = fd_openat(parent_dir_fname->fsp, first_atname, fsp, &how);
4649 if (!NT_STATUS_IS_OK(status)) {
4650 DBG_ERR("fd_openat() failed for '%s': %s\n",
4651 smb_fname_str_dbg(smb_dname), nt_errstr(status));
4652 goto restore_orig;
4655 /* Ensure we're checking for a symlink here.... */
4656 /* We don't want to get caught by a symlink racer. */
4658 status = vfs_stat_fsp(fsp);
4659 if (!NT_STATUS_IS_OK(status)) {
4660 DBG_ERR("Could not stat directory '%s' just created: %s\n",
4661 smb_fname_str_dbg(smb_dname), nt_errstr(status));
4662 goto restore_orig;
4665 if (!S_ISDIR(smb_dname->st.st_ex_mode)) {
4666 DBG_ERR("Directory '%s' just created is not a directory !\n",
4667 smb_fname_str_dbg(smb_dname));
4668 status = NT_STATUS_NOT_A_DIRECTORY;
4669 goto restore_orig;
4672 if (lp_store_dos_attributes(SNUM(conn))) {
4673 file_set_dosmode(conn,
4674 smb_dname,
4675 file_attributes | FILE_ATTRIBUTE_DIRECTORY,
4676 parent_dir_fname,
4677 true);
4680 if (lp_inherit_permissions(SNUM(conn))) {
4681 inherit_access_posix_acl(conn, parent_dir_fname->fsp,
4682 smb_dname, mode);
4683 need_re_stat = true;
4686 if (!posix_open) {
4688 * Check if high bits should have been set,
4689 * then (if bits are missing): add them.
4690 * Consider bits automagically set by UNIX, i.e. SGID bit from parent
4691 * dir.
4693 if ((mode & ~(S_IRWXU|S_IRWXG|S_IRWXO)) &&
4694 (mode & ~smb_dname->st.st_ex_mode)) {
4695 SMB_VFS_FCHMOD(fsp,
4696 (smb_dname->st.st_ex_mode |
4697 (mode & ~smb_dname->st.st_ex_mode)));
4698 need_re_stat = true;
4702 /* Change the owner if required. */
4703 if (lp_inherit_owner(SNUM(conn)) != INHERIT_OWNER_NO) {
4704 change_dir_owner_to_parent_fsp(parent_dir_fname->fsp,
4705 fsp);
4706 need_re_stat = true;
4709 if (need_re_stat) {
4710 status = vfs_stat_fsp(fsp);
4711 if (!NT_STATUS_IS_OK(status)) {
4712 DBG_ERR("Could not stat directory '%s' just created: %s\n",
4713 smb_fname_str_dbg(smb_dname), nt_errstr(status));
4714 goto restore_orig;
4718 if (lp_nt_acl_support(SNUM(conn))) {
4719 status = apply_new_nt_acl(parent_dir_fname->fsp,
4720 fsp,
4721 sd);
4722 if (!NT_STATUS_IS_OK(status)) {
4723 DBG_WARNING("apply_new_nt_acl() failed for %s with %s\n",
4724 fsp_str_dbg(fsp),
4725 nt_errstr(status));
4726 goto do_unlink;
4730 if (!need_tmpname) {
4731 goto done;
4735 * A rename needs a valid stat for the source,
4736 * see vfs_fruit.c ...
4738 tmp_atname->st = smb_dname->st;
4741 * We first try VFS_RENAME_HOW_NO_REPLACE,
4742 * if it's implemented in the kernel,
4743 * we'll always get EEXIST if the target
4744 * exist, as it's handled at the linux vfs
4745 * layer. But if it doesn't exist we
4746 * can still get EINVAL if the actual
4747 * filesystem doesn't support RENAME_NOREPLACE.
4749 * If the kernel doesn't support rename2()
4750 * we get EINVAL instead of ENOSYS (this
4751 * is mapped in the libreplace replacement
4752 * (as well as the glibc replacement).
4754 ret = SMB_VFS_RENAMEAT(conn,
4755 parent_dir_fname->fsp,
4756 tmp_atname,
4757 parent_dir_fname->fsp,
4758 smb_fname_atname,
4759 &rhow);
4760 if (ret == -1 && errno == EINVAL) {
4762 * This is the strategie we use without having
4763 * renameat2(RENAME_NOREPLACE):
4765 * renameat() is able to replace a directory if the source is
4766 * also a directory.
4768 * So in order to avoid races as much as possible we do a
4769 * mkdirat() with mode 0 in order to catch EEXIST almost
4770 * atomically, when this code runs by two processes at the same
4771 * time.
4773 * Then a renameat() makes the temporary directory available for
4774 * clients.
4776 * This a much smaller window where the other clients may see
4777 * the incomplete directory, which has a mode of 0.
4780 rhow.flags &= ~VFS_RENAME_HOW_NO_REPLACE;
4782 DBG_DEBUG("MKDIRAT/RENAMEAT '%s' -> '%s'\n",
4783 tmp_dname, orig_dname);
4785 ret = SMB_VFS_MKDIRAT(conn,
4786 parent_dir_fname->fsp,
4787 smb_fname_atname,
4789 if (ret != 0) {
4790 status = map_nt_error_from_unix(errno);
4791 DBG_NOTICE("MKDIRAT failed for '%s': %s\n",
4792 orig_dname, nt_errstr(status));
4793 goto do_unlink;
4796 ret = SMB_VFS_RENAMEAT(conn,
4797 parent_dir_fname->fsp,
4798 tmp_atname,
4799 parent_dir_fname->fsp,
4800 smb_fname_atname,
4801 &rhow);
4804 if (ret != 0) {
4805 status = map_nt_error_from_unix(errno);
4806 DBG_NOTICE("RENAMEAT failed for '%s' -> '%s': %s\n",
4807 tmp_dname, orig_dname, nt_errstr(status));
4808 goto do_unlink;
4810 smb_fname_atname->st = tmp_atname->st;
4811 smb_dname->base_name = orig_dname;
4813 done:
4814 DBG_DEBUG("Created directory '%s'\n",
4815 smb_fname_str_dbg(smb_dname));
4817 TALLOC_FREE(frame);
4818 return NT_STATUS_OK;
4820 do_unlink:
4821 DBG_NOTICE("%s: rollback and unlink '%s'\n",
4822 nt_errstr(status),
4823 tmp_dname);
4824 ret = SMB_VFS_UNLINKAT(conn,
4825 parent_dir_fname->fsp,
4826 tmp_atname,
4827 AT_REMOVEDIR);
4828 if (ret == 0) {
4829 DBG_NOTICE("SMB_VFS_UNLINKAT(%s): OK\n",
4830 tmp_dname);
4831 } else {
4832 NTSTATUS status2 = map_nt_error_from_unix(errno);
4833 DBG_WARNING("SMB_VFS_UNLINKAT(%s) ignoring %s\n",
4834 tmp_dname, nt_errstr(status2));
4837 restore_orig:
4838 if (!need_tmpname) {
4839 TALLOC_FREE(frame);
4840 return status;
4842 DBG_NOTICE("%s: restoring '%s' -> '%s'\n",
4843 nt_errstr(status),
4844 tmp_dname,
4845 orig_dname);
4846 SET_STAT_INVALID(smb_fname_atname->st);
4847 smb_dname->base_name = orig_dname;
4848 SET_STAT_INVALID(smb_dname->st);
4849 TALLOC_FREE(frame);
4850 return status;
4853 /****************************************************************************
4854 Open a directory from an NT SMB call.
4855 ****************************************************************************/
4857 static NTSTATUS open_directory(connection_struct *conn,
4858 struct smb_request *req,
4859 uint32_t access_mask,
4860 uint32_t share_access,
4861 uint32_t create_disposition,
4862 uint32_t create_options,
4863 uint32_t file_attributes,
4864 struct smb_filename *parent_dir_fname,
4865 struct smb_filename *smb_fname_atname,
4866 uint32_t oplock_request,
4867 const struct smb2_lease *lease,
4868 struct security_descriptor *sd,
4869 int *pinfo,
4870 struct files_struct *fsp)
4872 struct smb_filename *smb_dname = fsp->fsp_name;
4873 bool dir_existed = VALID_STAT(smb_dname->st);
4874 bool deferred = false;
4875 struct open_ntcreate_lock_state lck_state = {};
4876 bool keep_locked = false;
4877 NTSTATUS status;
4878 struct timespec mtimespec;
4879 int info = 0;
4880 uint32_t need_fd_access;
4881 NTSTATUS ulstatus;
4883 if (is_ntfs_stream_smb_fname(smb_dname)) {
4884 DEBUG(2, ("open_directory: %s is a stream name!\n",
4885 smb_fname_str_dbg(smb_dname)));
4886 return NT_STATUS_NOT_A_DIRECTORY;
4889 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS)) {
4890 /* Ensure we have a directory attribute. */
4891 file_attributes |= FILE_ATTRIBUTE_DIRECTORY;
4894 DBG_INFO("opening directory %s, access_mask = 0x%"PRIx32", "
4895 "share_access = 0x%"PRIx32" create_options = 0x%"PRIx32", "
4896 "create_disposition = 0x%"PRIx32", "
4897 "file_attributes = 0x%"PRIx32"\n",
4898 smb_fname_str_dbg(smb_dname),
4899 access_mask,
4900 share_access,
4901 create_options,
4902 create_disposition,
4903 file_attributes);
4905 if (req == NULL) {
4906 /* Ensure req == NULL means INTERNAL_OPEN_ONLY */
4907 SMB_ASSERT(oplock_request == INTERNAL_OPEN_ONLY);
4908 } else {
4909 /* And req != NULL means no INTERNAL_OPEN_ONLY */
4910 SMB_ASSERT((oplock_request & INTERNAL_OPEN_ONLY) == 0);
4913 if (req != NULL) {
4914 struct deferred_open_record *open_rec = NULL;
4916 deferred = get_deferred_open_message_state(req, NULL, &open_rec);
4917 if (deferred) {
4918 remove_deferred_open_message_smb(req->xconn, req->mid);
4922 status = smbd_calculate_access_mask_fsp(parent_dir_fname->fsp,
4923 smb_dname->fsp,
4924 false,
4925 access_mask,
4926 &access_mask);
4927 if (!NT_STATUS_IS_OK(status)) {
4928 DBG_DEBUG("smbd_calculate_access_mask_fsp "
4929 "on file %s returned %s\n",
4930 smb_fname_str_dbg(smb_dname),
4931 nt_errstr(status));
4932 return status;
4935 if ((access_mask & SEC_FLAG_SYSTEM_SECURITY) &&
4936 !security_token_has_privilege(get_current_nttok(conn),
4937 SEC_PRIV_SECURITY)) {
4938 DEBUG(10, ("open_directory: open on %s "
4939 "failed - SEC_FLAG_SYSTEM_SECURITY denied.\n",
4940 smb_fname_str_dbg(smb_dname)));
4941 return NT_STATUS_PRIVILEGE_NOT_HELD;
4944 switch( create_disposition ) {
4945 case FILE_OPEN:
4947 if (!dir_existed) {
4948 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
4951 info = FILE_WAS_OPENED;
4952 break;
4954 case FILE_CREATE:
4956 /* If directory exists error. If directory doesn't
4957 * exist create. */
4959 if (dir_existed) {
4960 status = NT_STATUS_OBJECT_NAME_COLLISION;
4961 DEBUG(2, ("open_directory: unable to create "
4962 "%s. Error was %s\n",
4963 smb_fname_str_dbg(smb_dname),
4964 nt_errstr(status)));
4965 return status;
4968 if (smb_fname_atname->twrp != 0) {
4969 return NT_STATUS_MEDIA_WRITE_PROTECTED;
4972 status = mkdir_internal(conn,
4973 parent_dir_fname,
4974 smb_fname_atname,
4975 smb_dname,
4977 file_attributes,
4978 fsp);
4980 if (!NT_STATUS_IS_OK(status)) {
4981 DEBUG(2, ("open_directory: unable to create "
4982 "%s. Error was %s\n",
4983 smb_fname_str_dbg(smb_dname),
4984 nt_errstr(status)));
4985 return status;
4988 info = FILE_WAS_CREATED;
4989 break;
4991 case FILE_OPEN_IF:
4993 * If directory exists open. If directory doesn't
4994 * exist create.
4997 if (dir_existed) {
4998 status = NT_STATUS_OK;
4999 info = FILE_WAS_OPENED;
5000 } else {
5001 if (smb_fname_atname->twrp != 0) {
5002 return NT_STATUS_MEDIA_WRITE_PROTECTED;
5004 status = mkdir_internal(conn,
5005 parent_dir_fname,
5006 smb_fname_atname,
5007 smb_dname,
5009 file_attributes,
5010 fsp);
5012 if (NT_STATUS_IS_OK(status)) {
5013 info = FILE_WAS_CREATED;
5014 } else {
5015 int ret;
5016 /* Cope with create race. */
5017 if (!NT_STATUS_EQUAL(status,
5018 NT_STATUS_OBJECT_NAME_COLLISION)) {
5019 DEBUG(2, ("open_directory: unable to create "
5020 "%s. Error was %s\n",
5021 smb_fname_str_dbg(smb_dname),
5022 nt_errstr(status)));
5023 return status;
5027 * If mkdir_internal() returned
5028 * NT_STATUS_OBJECT_NAME_COLLISION
5029 * we still must lstat the path.
5031 ret = SMB_VFS_FSTATAT(
5032 conn,
5033 parent_dir_fname->fsp,
5034 smb_fname_atname,
5035 &smb_dname->st,
5036 AT_SYMLINK_NOFOLLOW);
5037 if (ret == -1) {
5038 DEBUG(2, ("Could not stat "
5039 "directory '%s' just "
5040 "opened: %s\n",
5041 smb_fname_str_dbg(
5042 smb_dname),
5043 strerror(errno)));
5044 return map_nt_error_from_unix(
5045 errno);
5048 info = FILE_WAS_OPENED;
5052 break;
5054 case FILE_SUPERSEDE:
5055 case FILE_OVERWRITE:
5056 case FILE_OVERWRITE_IF:
5057 default:
5058 DEBUG(5,("open_directory: invalid create_disposition "
5059 "0x%x for directory %s\n",
5060 (unsigned int)create_disposition,
5061 smb_fname_str_dbg(smb_dname)));
5062 return NT_STATUS_INVALID_PARAMETER;
5065 if(!S_ISDIR(smb_dname->st.st_ex_mode)) {
5066 DEBUG(5,("open_directory: %s is not a directory !\n",
5067 smb_fname_str_dbg(smb_dname)));
5068 return NT_STATUS_NOT_A_DIRECTORY;
5072 * Setup the files_struct for it.
5075 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_dname->st);
5076 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
5077 fsp->file_pid = req ? req->smbpid : 0;
5078 fsp->fsp_flags.can_lock = false;
5079 fsp->fsp_flags.can_read = false;
5080 fsp->fsp_flags.can_write = false;
5082 fh_set_private_options(fsp->fh, 0);
5084 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
5086 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
5087 fsp->print_file = NULL;
5088 fsp->fsp_flags.modified = false;
5089 fsp->oplock_type = NO_OPLOCK;
5090 fsp->sent_oplock_break = NO_BREAK_SENT;
5091 fsp->fsp_flags.is_directory = true;
5092 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
5093 fsp->fsp_flags.posix_open = true;
5096 /* Don't store old timestamps for directory
5097 handles in the internal database. We don't
5098 update them in there if new objects
5099 are created in the directory. Currently
5100 we only update timestamps on file writes.
5101 See bug #9870.
5103 mtimespec = make_omit_timespec();
5106 * Obviously for FILE_LIST_DIRECTORY we need to reopen to get an fd
5107 * usable for reading a directory. SMB2_FLUSH may be called on
5108 * directories opened with FILE_ADD_FILE and FILE_ADD_SUBDIRECTORY so
5109 * for those we need to reopen as well.
5111 need_fd_access =
5112 FILE_LIST_DIRECTORY |
5113 FILE_ADD_FILE |
5114 FILE_ADD_SUBDIRECTORY;
5116 if (access_mask & need_fd_access) {
5117 struct vfs_open_how how = {
5118 .flags = O_RDONLY | O_DIRECTORY,
5120 bool file_created;
5122 status = reopen_from_fsp(parent_dir_fname->fsp,
5123 smb_fname_atname,
5124 fsp,
5125 &how,
5126 &file_created);
5127 if (!NT_STATUS_IS_OK(status)) {
5128 DBG_INFO("Could not open fd for [%s]: %s\n",
5129 smb_fname_str_dbg(smb_dname),
5130 nt_errstr(status));
5131 return status;
5135 status = vfs_stat_fsp(fsp);
5136 if (!NT_STATUS_IS_OK(status)) {
5137 fd_close(fsp);
5138 return status;
5141 if(!S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
5142 DEBUG(5,("open_directory: %s is not a directory !\n",
5143 smb_fname_str_dbg(smb_dname)));
5144 fd_close(fsp);
5145 return NT_STATUS_NOT_A_DIRECTORY;
5148 /* Ensure there was no race condition. We need to check
5149 * dev/inode but not permissions, as these can change
5150 * legitimately */
5151 if (!check_same_dev_ino(&smb_dname->st, &fsp->fsp_name->st)) {
5152 DEBUG(5,("open_directory: stat struct differs for "
5153 "directory %s.\n",
5154 smb_fname_str_dbg(smb_dname)));
5155 fd_close(fsp);
5156 return NT_STATUS_ACCESS_DENIED;
5159 if (info == FILE_WAS_OPENED) {
5160 status = smbd_check_access_rights_fsp(parent_dir_fname->fsp,
5161 fsp,
5162 false,
5163 access_mask);
5164 if (!NT_STATUS_IS_OK(status)) {
5165 DBG_DEBUG("smbd_check_access_rights_fsp on "
5166 "file %s failed with %s\n",
5167 fsp_str_dbg(fsp),
5168 nt_errstr(status));
5169 fd_close(fsp);
5170 return status;
5175 * If we created a new directory or going to delete it later,
5176 * we should keep * the share_mode_lock (g_lock) until we call
5177 * share_mode_entry_prepare_unlock()
5179 if (info != FILE_WAS_OPENED) {
5180 keep_locked = true;
5181 } else if (create_options & FILE_DELETE_ON_CLOSE) {
5182 keep_locked = true;
5185 lck_state = (struct open_ntcreate_lock_state) {
5186 .fsp = fsp,
5187 .object_type = "directory",
5188 .req = req,
5189 .create_disposition = create_disposition,
5190 .access_mask = access_mask,
5191 .open_access_mask = access_mask,
5192 .share_access = share_access,
5193 .oplock_request = oplock_request,
5194 .lease = lease,
5195 .first_open_attempt = !deferred,
5196 .keep_locked = keep_locked,
5199 status = share_mode_entry_prepare_lock_add(&lck_state.prepare_state,
5200 fsp->file_id,
5201 conn->connectpath,
5202 smb_dname,
5203 &mtimespec,
5204 open_ntcreate_lock_add_entry,
5205 &lck_state);
5206 if (!NT_STATUS_IS_OK(status)) {
5207 DBG_ERR("share_mode_entry_prepare_lock_add() failed for %s - %s\n",
5208 smb_fname_str_dbg(smb_dname), nt_errstr(status));
5209 fd_close(fsp);
5210 return status;
5213 status = lck_state.status;
5214 if (!NT_STATUS_IS_OK(status)) {
5215 fd_close(fsp);
5216 return status;
5220 * From here we need to use 'goto unlock;' instead of return !!!
5223 /* For directories the delete on close bit at open time seems
5224 always to be honored on close... See test 19 in Samba4 BASE-DELETE. */
5225 if (create_options & FILE_DELETE_ON_CLOSE) {
5226 status = can_set_delete_on_close(fsp, 0);
5227 if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
5228 lck_state.cleanup_fn =
5229 open_ntcreate_lock_cleanup_entry;
5230 goto unlock;
5233 if (NT_STATUS_IS_OK(status)) {
5234 /* Note that here we set the *initial* delete on close flag,
5235 not the regular one. The magic gets handled in close. */
5236 fsp->fsp_flags.initial_delete_on_close = true;
5241 * Deal with other opens having a modified write time.
5243 if (!is_omit_timespec(&lck_state.write_time)) {
5244 update_stat_ex_mtime(&fsp->fsp_name->st, lck_state.write_time);
5247 if (pinfo) {
5248 *pinfo = info;
5251 status = NT_STATUS_OK;
5253 unlock:
5254 ulstatus = share_mode_entry_prepare_unlock(&lck_state.prepare_state,
5255 lck_state.cleanup_fn,
5256 &lck_state);
5257 if (!NT_STATUS_IS_OK(ulstatus)) {
5258 DBG_ERR("share_mode_entry_prepare_unlock() failed for %s - %s\n",
5259 smb_fname_str_dbg(smb_dname), nt_errstr(ulstatus));
5260 smb_panic("share_mode_entry_prepare_unlock() failed!");
5263 if (info == FILE_WAS_CREATED) {
5264 notify_fname(conn,
5265 NOTIFY_ACTION_ADDED |
5266 NOTIFY_ACTION_DIRLEASE_BREAK,
5267 FILE_NOTIFY_CHANGE_DIR_NAME,
5268 smb_dname,
5269 fsp_get_smb2_lease(fsp));
5272 if (!NT_STATUS_IS_OK(status)) {
5273 fd_close(fsp);
5274 return status;
5277 return NT_STATUS_OK;
5280 NTSTATUS create_directory(connection_struct *conn,
5281 struct smb_request *req,
5282 struct files_struct *dirfsp,
5283 struct smb_filename *smb_dname)
5285 NTSTATUS status;
5286 files_struct *fsp;
5288 status = SMB_VFS_CREATE_FILE(
5289 conn, /* conn */
5290 req, /* req */
5291 dirfsp, /* dirfsp */
5292 smb_dname, /* fname */
5293 FILE_READ_ATTRIBUTES, /* access_mask */
5294 FILE_SHARE_NONE, /* share_access */
5295 FILE_CREATE, /* create_disposition*/
5296 FILE_DIRECTORY_FILE, /* create_options */
5297 FILE_ATTRIBUTE_DIRECTORY, /* file_attributes */
5298 0, /* oplock_request */
5299 NULL, /* lease */
5300 0, /* allocation_size */
5301 0, /* private_flags */
5302 NULL, /* sd */
5303 NULL, /* ea_list */
5304 &fsp, /* result */
5305 NULL, /* pinfo */
5306 NULL, NULL); /* create context */
5308 if (NT_STATUS_IS_OK(status)) {
5309 close_file_free(req, &fsp, NORMAL_CLOSE);
5312 return status;
5315 /****************************************************************************
5316 Receive notification that one of our open files has been renamed by another
5317 smbd process.
5318 ****************************************************************************/
5320 void msg_file_was_renamed(struct messaging_context *msg_ctx,
5321 void *private_data,
5322 uint32_t msg_type,
5323 struct server_id src,
5324 DATA_BLOB *data)
5326 struct file_rename_message *msg = NULL;
5327 enum ndr_err_code ndr_err;
5328 files_struct *fsp;
5329 struct smb_filename *smb_fname = NULL;
5330 struct smbd_server_connection *sconn =
5331 talloc_get_type_abort(private_data,
5332 struct smbd_server_connection);
5334 msg = talloc(talloc_tos(), struct file_rename_message);
5335 if (msg == NULL) {
5336 DBG_WARNING("talloc failed\n");
5337 return;
5340 ndr_err = ndr_pull_struct_blob_all(
5341 data,
5342 msg,
5343 msg,
5344 (ndr_pull_flags_fn_t)ndr_pull_file_rename_message);
5345 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
5346 DBG_DEBUG("ndr_pull_file_rename_message failed: %s\n",
5347 ndr_errstr(ndr_err));
5348 goto out;
5350 if (DEBUGLEVEL >= 10) {
5351 struct server_id_buf buf;
5352 DBG_DEBUG("Got rename message from %s\n",
5353 server_id_str_buf(src, &buf));
5354 NDR_PRINT_DEBUG(file_rename_message, msg);
5357 /* stream_name must always be NULL if there is no stream. */
5358 if ((msg->stream_name != NULL) && (msg->stream_name[0] == '\0')) {
5359 msg->stream_name = NULL;
5362 smb_fname = synthetic_smb_fname(msg,
5363 msg->base_name,
5364 msg->stream_name,
5365 NULL,
5368 if (smb_fname == NULL) {
5369 DBG_DEBUG("synthetic_smb_fname failed\n");
5370 goto out;
5373 fsp = file_find_dif(sconn, msg->id, msg->share_file_id);
5374 if (fsp == NULL) {
5375 DBG_DEBUG("fsp not found\n");
5376 goto out;
5379 if (strcmp(fsp->conn->connectpath, msg->servicepath) == 0) {
5380 SMB_STRUCT_STAT fsp_orig_sbuf;
5381 NTSTATUS status;
5382 DBG_DEBUG("renaming file %s from %s -> %s\n",
5383 fsp_fnum_dbg(fsp),
5384 fsp_str_dbg(fsp),
5385 smb_fname_str_dbg(smb_fname));
5388 * The incoming smb_fname here has an
5389 * invalid stat struct from synthetic_smb_fname()
5390 * above.
5391 * Preserve the existing stat from the
5392 * open fsp after fsp_set_smb_fname()
5393 * overwrites with the invalid stat.
5395 * (We could just copy this into
5396 * smb_fname->st, but keep this code
5397 * identical to the fix in rename_open_files()
5398 * for clarity.
5400 * We will do an fstat before returning
5401 * any of this metadata to the client anyway.
5403 fsp_orig_sbuf = fsp->fsp_name->st;
5404 status = fsp_set_smb_fname(fsp, smb_fname);
5405 if (!NT_STATUS_IS_OK(status)) {
5406 DBG_DEBUG("fsp_set_smb_fname failed: %s\n",
5407 nt_errstr(status));
5409 fsp->fsp_name->st = fsp_orig_sbuf;
5410 } else {
5411 /* TODO. JRA. */
5413 * Now we have the complete path we can work out if
5414 * this is actually within this share and adjust
5415 * newname accordingly.
5417 DBG_DEBUG("share mismatch (sharepath %s not sharepath %s) "
5418 "%s from %s -> %s\n",
5419 fsp->conn->connectpath,
5420 msg->servicepath,
5421 fsp_fnum_dbg(fsp),
5422 fsp_str_dbg(fsp),
5423 smb_fname_str_dbg(smb_fname));
5425 out:
5426 TALLOC_FREE(msg);
5430 * If a main file is opened for delete, all streams need to be checked for
5431 * !FILE_SHARE_DELETE. Do this by opening with DELETE_ACCESS.
5432 * If that works, delete them all by setting the delete on close and close.
5435 static NTSTATUS open_streams_for_delete(connection_struct *conn,
5436 const struct smb_filename *smb_fname)
5438 struct stream_struct *stream_info = NULL;
5439 files_struct **streams = NULL;
5440 int j;
5441 unsigned int i, num_streams = 0;
5442 TALLOC_CTX *frame = talloc_stackframe();
5443 const struct smb_filename *pathref = NULL;
5444 NTSTATUS status;
5446 if (smb_fname->fsp == NULL) {
5447 struct smb_filename *tmp = NULL;
5448 status = synthetic_pathref(frame,
5449 conn->cwd_fsp,
5450 smb_fname->base_name,
5451 NULL,
5452 NULL,
5453 smb_fname->twrp,
5454 smb_fname->flags,
5455 &tmp);
5456 if (!NT_STATUS_IS_OK(status)) {
5457 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
5458 || NT_STATUS_EQUAL(status,
5459 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
5460 DBG_DEBUG("no streams around\n");
5461 TALLOC_FREE(frame);
5462 return NT_STATUS_OK;
5464 DBG_DEBUG("synthetic_pathref failed: %s\n",
5465 nt_errstr(status));
5466 goto fail;
5468 pathref = tmp;
5469 } else {
5470 pathref = smb_fname;
5472 status = vfs_fstreaminfo(pathref->fsp, talloc_tos(),
5473 &num_streams, &stream_info);
5475 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
5476 || NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
5477 DEBUG(10, ("no streams around\n"));
5478 TALLOC_FREE(frame);
5479 return NT_STATUS_OK;
5482 if (!NT_STATUS_IS_OK(status)) {
5483 DEBUG(10, ("vfs_fstreaminfo failed: %s\n",
5484 nt_errstr(status)));
5485 goto fail;
5488 DEBUG(10, ("open_streams_for_delete found %d streams\n",
5489 num_streams));
5491 if (num_streams == 0) {
5492 TALLOC_FREE(frame);
5493 return NT_STATUS_OK;
5496 streams = talloc_array(talloc_tos(), files_struct *, num_streams);
5497 if (streams == NULL) {
5498 DEBUG(0, ("talloc failed\n"));
5499 status = NT_STATUS_NO_MEMORY;
5500 goto fail;
5503 for (i=0; i<num_streams; i++) {
5504 struct smb_filename *smb_fname_cp;
5506 if (strequal(stream_info[i].name, "::$DATA")) {
5507 streams[i] = NULL;
5508 continue;
5511 smb_fname_cp = synthetic_smb_fname(talloc_tos(),
5512 smb_fname->base_name,
5513 stream_info[i].name,
5514 NULL,
5515 smb_fname->twrp,
5516 (smb_fname->flags &
5517 ~SMB_FILENAME_POSIX_PATH));
5518 if (smb_fname_cp == NULL) {
5519 status = NT_STATUS_NO_MEMORY;
5520 goto fail;
5523 status = openat_pathref_fsp(conn->cwd_fsp, smb_fname_cp);
5524 if (!NT_STATUS_IS_OK(status)) {
5525 DBG_DEBUG("Unable to open stream [%s]: %s\n",
5526 smb_fname_str_dbg(smb_fname_cp),
5527 nt_errstr(status));
5528 TALLOC_FREE(smb_fname_cp);
5529 break;
5532 status = SMB_VFS_CREATE_FILE(
5533 conn, /* conn */
5534 NULL, /* req */
5535 NULL, /* dirfsp */
5536 smb_fname_cp, /* fname */
5537 DELETE_ACCESS, /* access_mask */
5538 (FILE_SHARE_READ | /* share_access */
5539 FILE_SHARE_WRITE | FILE_SHARE_DELETE),
5540 FILE_OPEN, /* create_disposition*/
5541 0, /* create_options */
5542 FILE_ATTRIBUTE_NORMAL, /* file_attributes */
5543 0, /* oplock_request */
5544 NULL, /* lease */
5545 0, /* allocation_size */
5546 0, /* private_flags */
5547 NULL, /* sd */
5548 NULL, /* ea_list */
5549 &streams[i], /* result */
5550 NULL, /* pinfo */
5551 NULL, NULL); /* create context */
5553 if (!NT_STATUS_IS_OK(status)) {
5554 DEBUG(10, ("Could not open stream %s: %s\n",
5555 smb_fname_str_dbg(smb_fname_cp),
5556 nt_errstr(status)));
5558 TALLOC_FREE(smb_fname_cp);
5559 break;
5561 TALLOC_FREE(smb_fname_cp);
5565 * don't touch the variable "status" beyond this point :-)
5568 for (j = i-1 ; j >= 0; j--) {
5569 if (streams[j] == NULL) {
5570 continue;
5573 DEBUG(10, ("Closing stream # %d, %s\n", j,
5574 fsp_str_dbg(streams[j])));
5575 close_file_free(NULL, &streams[j], NORMAL_CLOSE);
5578 fail:
5579 TALLOC_FREE(frame);
5580 return status;
5583 /*********************************************************************
5584 Create a default ACL by inheriting from the parent. If no inheritance
5585 from the parent available, don't set anything. This will leave the actual
5586 permissions the new file or directory already got from the filesystem
5587 as the NT ACL when read.
5588 *********************************************************************/
5590 static NTSTATUS inherit_new_acl(files_struct *dirfsp, files_struct *fsp)
5592 TALLOC_CTX *frame = talloc_stackframe();
5593 struct security_descriptor *parent_desc = NULL;
5594 NTSTATUS status = NT_STATUS_OK;
5595 struct security_descriptor *psd = NULL;
5596 const struct dom_sid *owner_sid = NULL;
5597 const struct dom_sid *group_sid = NULL;
5598 uint32_t security_info_sent = (SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL);
5599 struct security_token *token = fsp->conn->session_info->security_token;
5600 bool inherit_owner =
5601 (lp_inherit_owner(SNUM(fsp->conn)) == INHERIT_OWNER_WINDOWS_AND_UNIX);
5602 bool inheritable_components = false;
5603 bool try_builtin_administrators = false;
5604 const struct dom_sid *BA_U_sid = NULL;
5605 const struct dom_sid *BA_G_sid = NULL;
5606 bool try_system = false;
5607 const struct dom_sid *SY_U_sid = NULL;
5608 const struct dom_sid *SY_G_sid = NULL;
5609 size_t size = 0;
5610 bool ok;
5612 status = SMB_VFS_FGET_NT_ACL(dirfsp,
5613 (SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL),
5614 frame,
5615 &parent_desc);
5616 if (!NT_STATUS_IS_OK(status)) {
5617 TALLOC_FREE(frame);
5618 return status;
5621 inheritable_components = sd_has_inheritable_components(parent_desc,
5622 fsp->fsp_flags.is_directory);
5624 if (!inheritable_components && !inherit_owner) {
5625 TALLOC_FREE(frame);
5626 /* Nothing to inherit and not setting owner. */
5627 return NT_STATUS_OK;
5630 /* Create an inherited descriptor from the parent. */
5632 if (DEBUGLEVEL >= 10) {
5633 DEBUG(10,("inherit_new_acl: parent acl for %s is:\n",
5634 fsp_str_dbg(fsp) ));
5635 NDR_PRINT_DEBUG(security_descriptor, parent_desc);
5638 /* Inherit from parent descriptor if "inherit owner" set. */
5639 if (inherit_owner) {
5640 owner_sid = parent_desc->owner_sid;
5641 group_sid = parent_desc->group_sid;
5644 if (owner_sid == NULL) {
5645 if (security_token_has_builtin_administrators(token)) {
5646 try_builtin_administrators = true;
5647 } else if (security_token_is_system(token)) {
5648 try_builtin_administrators = true;
5649 try_system = true;
5653 if (group_sid == NULL &&
5654 token->num_sids == PRIMARY_GROUP_SID_INDEX)
5656 if (security_token_is_system(token)) {
5657 try_builtin_administrators = true;
5658 try_system = true;
5662 if (try_builtin_administrators) {
5663 struct unixid ids = { .id = 0 };
5665 ok = sids_to_unixids(&global_sid_Builtin_Administrators, 1, &ids);
5666 if (ok) {
5667 switch (ids.type) {
5668 case ID_TYPE_BOTH:
5669 BA_U_sid = &global_sid_Builtin_Administrators;
5670 BA_G_sid = &global_sid_Builtin_Administrators;
5671 break;
5672 case ID_TYPE_UID:
5673 BA_U_sid = &global_sid_Builtin_Administrators;
5674 break;
5675 case ID_TYPE_GID:
5676 BA_G_sid = &global_sid_Builtin_Administrators;
5677 break;
5678 default:
5679 break;
5684 if (try_system) {
5685 struct unixid ids = { .id = 0 };
5687 ok = sids_to_unixids(&global_sid_System, 1, &ids);
5688 if (ok) {
5689 switch (ids.type) {
5690 case ID_TYPE_BOTH:
5691 SY_U_sid = &global_sid_System;
5692 SY_G_sid = &global_sid_System;
5693 break;
5694 case ID_TYPE_UID:
5695 SY_U_sid = &global_sid_System;
5696 break;
5697 case ID_TYPE_GID:
5698 SY_G_sid = &global_sid_System;
5699 break;
5700 default:
5701 break;
5706 if (owner_sid == NULL) {
5707 owner_sid = BA_U_sid;
5710 if (owner_sid == NULL) {
5711 owner_sid = SY_U_sid;
5714 if (group_sid == NULL) {
5715 group_sid = SY_G_sid;
5718 if (try_system && group_sid == NULL) {
5719 group_sid = BA_G_sid;
5722 if (owner_sid == NULL) {
5723 owner_sid = &token->sids[PRIMARY_USER_SID_INDEX];
5725 if (group_sid == NULL) {
5726 if (token->num_sids == PRIMARY_GROUP_SID_INDEX) {
5727 group_sid = &token->sids[PRIMARY_USER_SID_INDEX];
5728 } else {
5729 group_sid = &token->sids[PRIMARY_GROUP_SID_INDEX];
5733 status = se_create_child_secdesc(frame,
5734 &psd,
5735 &size,
5736 parent_desc,
5737 owner_sid,
5738 group_sid,
5739 fsp->fsp_flags.is_directory);
5740 if (!NT_STATUS_IS_OK(status)) {
5741 TALLOC_FREE(frame);
5742 return status;
5745 /* If inheritable_components == false,
5746 se_create_child_secdesc()
5747 creates a security descriptor with a NULL dacl
5748 entry, but with SEC_DESC_DACL_PRESENT. We need
5749 to remove that flag. */
5751 if (!inheritable_components) {
5752 security_info_sent &= ~SECINFO_DACL;
5753 psd->type &= ~SEC_DESC_DACL_PRESENT;
5756 if (DEBUGLEVEL >= 10) {
5757 DEBUG(10,("inherit_new_acl: child acl for %s is:\n",
5758 fsp_str_dbg(fsp) ));
5759 NDR_PRINT_DEBUG(security_descriptor, psd);
5762 if (inherit_owner) {
5763 /* We need to be root to force this. */
5764 become_root();
5766 status = SMB_VFS_FSET_NT_ACL(metadata_fsp(fsp),
5767 security_info_sent,
5768 psd);
5769 if (inherit_owner) {
5770 unbecome_root();
5772 TALLOC_FREE(frame);
5773 return status;
5777 * If we already have a lease, it must match the new file id. [MS-SMB2]
5778 * 3.3.5.9.8 speaks about INVALID_PARAMETER if an already used lease key is
5779 * used for a different file name.
5782 struct lease_match_state {
5783 /* Input parameters. */
5784 TALLOC_CTX *mem_ctx;
5785 const char *servicepath;
5786 const struct smb_filename *fname;
5787 bool file_existed;
5788 struct file_id id;
5789 /* Return parameters. */
5790 uint32_t num_file_ids;
5791 struct file_id *ids;
5792 NTSTATUS match_status;
5795 /*************************************************************
5796 File doesn't exist but this lease key+guid is already in use.
5798 This is only allowable in the dynamic share case where the
5799 service path must be different.
5801 There is a small race condition here in the multi-connection
5802 case where a client sends two create calls on different connections,
5803 where the file doesn't exist and one smbd creates the leases_db
5804 entry first, but this will get fixed by the multichannel cleanup
5805 when all identical client_guids get handled by a single smbd.
5806 **************************************************************/
5808 static void lease_match_parser_new_file(
5809 uint32_t num_files,
5810 const struct leases_db_file *files,
5811 struct lease_match_state *state)
5813 uint32_t i;
5815 for (i = 0; i < num_files; i++) {
5816 const struct leases_db_file *f = &files[i];
5817 if (strequal(state->servicepath, f->servicepath)) {
5818 state->match_status = NT_STATUS_INVALID_PARAMETER;
5819 return;
5823 /* Dynamic share case. Break leases on all other files. */
5824 state->match_status = leases_db_copy_file_ids(state->mem_ctx,
5825 num_files,
5826 files,
5827 &state->ids);
5828 if (!NT_STATUS_IS_OK(state->match_status)) {
5829 return;
5832 state->num_file_ids = num_files;
5833 state->match_status = NT_STATUS_OPLOCK_NOT_GRANTED;
5834 return;
5837 static void lease_match_parser(
5838 uint32_t num_files,
5839 const struct leases_db_file *files,
5840 void *private_data)
5842 struct lease_match_state *state =
5843 (struct lease_match_state *)private_data;
5844 uint32_t i;
5846 if (!state->file_existed) {
5848 * Deal with name mismatch or
5849 * possible dynamic share case separately
5850 * to make code clearer.
5852 lease_match_parser_new_file(num_files,
5853 files,
5854 state);
5855 return;
5858 /* File existed. */
5859 state->match_status = NT_STATUS_OK;
5861 for (i = 0; i < num_files; i++) {
5862 const struct leases_db_file *f = &files[i];
5864 /* Everything should be the same. */
5865 if (!file_id_equal(&state->id, &f->id)) {
5867 * The client asked for a lease on a
5868 * file that doesn't match the file_id
5869 * in the database.
5871 * Maybe this is a dynamic share, i.e.
5872 * a share where the servicepath is
5873 * different for different users (e.g.
5874 * the [HOMES] share.
5876 * If the servicepath is different, but the requested
5877 * file name + stream name is the same then this is
5878 * a dynamic share, the client is using the same share
5879 * name and doesn't know that the underlying servicepath
5880 * is different. It was expecting a lease on the
5881 * same file. Return NT_STATUS_OPLOCK_NOT_GRANTED
5882 * to break leases
5884 * Otherwise the client has messed up, or is
5885 * testing our error codes, so return
5886 * NT_STATUS_INVALID_PARAMETER.
5888 if (!strequal(f->servicepath, state->servicepath) &&
5889 strequal(f->base_name, state->fname->base_name) &&
5890 strequal(f->stream_name, state->fname->stream_name))
5893 * Name is the same but servicepath is
5894 * different, dynamic share. Break leases.
5896 state->match_status =
5897 NT_STATUS_OPLOCK_NOT_GRANTED;
5898 } else {
5899 state->match_status =
5900 NT_STATUS_INVALID_PARAMETER;
5902 break;
5904 if (!strequal(f->servicepath, state->servicepath)) {
5905 state->match_status = NT_STATUS_INVALID_PARAMETER;
5906 break;
5908 if (!strequal(f->base_name, state->fname->base_name)) {
5909 state->match_status = NT_STATUS_INVALID_PARAMETER;
5910 break;
5912 if (!strequal(f->stream_name, state->fname->stream_name)) {
5913 state->match_status = NT_STATUS_INVALID_PARAMETER;
5914 break;
5918 if (NT_STATUS_IS_OK(state->match_status)) {
5920 * Common case - just opening another handle on a
5921 * file on a non-dynamic share.
5923 return;
5926 if (NT_STATUS_EQUAL(state->match_status, NT_STATUS_INVALID_PARAMETER)) {
5927 /* Mismatched path. Error back to client. */
5928 return;
5932 * File id mismatch. Dynamic share case NT_STATUS_OPLOCK_NOT_GRANTED.
5933 * Don't allow leases.
5936 state->match_status = leases_db_copy_file_ids(state->mem_ctx,
5937 num_files,
5938 files,
5939 &state->ids);
5940 if (!NT_STATUS_IS_OK(state->match_status)) {
5941 return;
5944 state->num_file_ids = num_files;
5945 state->match_status = NT_STATUS_OPLOCK_NOT_GRANTED;
5946 return;
5949 struct lease_match_break_state {
5950 struct messaging_context *msg_ctx;
5951 const struct smb2_lease_key *lease_key;
5952 struct file_id id;
5954 bool found_lease;
5955 uint16_t version;
5956 uint16_t epoch;
5959 static bool lease_match_break_fn(
5960 struct share_mode_entry *e,
5961 void *private_data)
5963 struct lease_match_break_state *state = private_data;
5964 bool stale, equal;
5965 uint32_t e_lease_type = SMB2_LEASE_NONE;
5966 NTSTATUS status;
5968 stale = share_entry_stale_pid(e);
5969 if (stale) {
5970 return false;
5973 equal = smb2_lease_key_equal(&e->lease_key, state->lease_key);
5974 if (!equal) {
5975 return false;
5978 status = leases_db_get(
5979 &e->client_guid,
5980 &e->lease_key,
5981 &state->id,
5982 &e_lease_type, /* current_state */
5983 NULL, /* breaking */
5984 NULL, /* breaking_to_requested */
5985 NULL, /* breaking_to_required */
5986 &state->version, /* lease_version */
5987 &state->epoch); /* epoch */
5988 if (NT_STATUS_IS_OK(status)) {
5989 state->found_lease = true;
5990 } else {
5991 DBG_WARNING("Could not find version/epoch: %s\n",
5992 nt_errstr(status));
5993 return false;
5996 if (e_lease_type == SMB2_LEASE_NONE) {
5997 return false;
5999 send_break_message(state->msg_ctx, &state->id, e, SMB2_LEASE_NONE);
6002 * Windows 7 and 8 lease clients are broken in that they will
6003 * not respond to lease break requests whilst waiting for an
6004 * outstanding open request on that lease handle on the same
6005 * TCP connection, due to holding an internal inode lock.
6007 * This means we can't reschedule ourselves here, but must
6008 * return from the create.
6010 * Work around:
6012 * Send the breaks and then return SMB2_LEASE_NONE in the
6013 * lease handle to cause them to acknowledge the lease
6014 * break. Consultation with Microsoft engineering confirmed
6015 * this approach is safe.
6018 return false;
6021 static void lease_match_fid_fn(struct share_mode_lock *lck,
6022 void *private_data)
6024 bool ok;
6026 ok = share_mode_forall_leases(lck, lease_match_break_fn, private_data);
6027 if (!ok) {
6028 DBG_DEBUG("share_mode_forall_leases failed\n");
6032 static NTSTATUS lease_match(connection_struct *conn,
6033 struct smb_request *req,
6034 const struct smb2_lease_key *lease_key,
6035 const char *servicepath,
6036 const struct smb_filename *fname,
6037 uint16_t *p_version,
6038 uint16_t *p_epoch)
6040 struct smbd_server_connection *sconn = req->sconn;
6041 TALLOC_CTX *tos = talloc_tos();
6042 struct lease_match_state state = {
6043 .mem_ctx = tos,
6044 .servicepath = servicepath,
6045 .fname = fname,
6046 .match_status = NT_STATUS_OK
6048 uint32_t i;
6049 NTSTATUS status;
6051 state.file_existed = VALID_STAT(fname->st);
6052 if (state.file_existed) {
6053 state.id = vfs_file_id_from_sbuf(conn, &fname->st);
6056 status = leases_db_parse(&sconn->client->global->client_guid,
6057 lease_key, lease_match_parser, &state);
6058 if (!NT_STATUS_IS_OK(status)) {
6060 * Not found or error means okay: We can make the lease pass
6062 return NT_STATUS_OK;
6064 if (!NT_STATUS_EQUAL(state.match_status, NT_STATUS_OPLOCK_NOT_GRANTED)) {
6066 * Anything but NT_STATUS_OPLOCK_NOT_GRANTED, let the caller
6067 * deal with it.
6069 return state.match_status;
6072 /* We have to break all existing leases. */
6073 for (i = 0; i < state.num_file_ids; i++) {
6074 struct lease_match_break_state break_state = {
6075 .msg_ctx = conn->sconn->msg_ctx,
6076 .lease_key = lease_key,
6079 if (file_id_equal(&state.ids[i], &state.id)) {
6080 /* Don't need to break our own file. */
6081 continue;
6084 break_state.id = state.ids[i];
6086 status = share_mode_do_locked_vfs_denied(break_state.id,
6087 lease_match_fid_fn,
6088 &break_state);
6089 if (!NT_STATUS_IS_OK(status)) {
6090 /* Race condition - file already closed. */
6091 continue;
6094 if (break_state.found_lease) {
6095 *p_version = break_state.version;
6096 *p_epoch = break_state.epoch;
6100 * Ensure we don't grant anything more so we
6101 * never upgrade.
6103 return NT_STATUS_OPLOCK_NOT_GRANTED;
6107 * Wrapper around open_file_ntcreate and open_directory
6110 static NTSTATUS create_file_unixpath(connection_struct *conn,
6111 struct smb_request *req,
6112 struct files_struct *dirfsp,
6113 struct smb_filename *smb_fname,
6114 uint32_t access_mask,
6115 uint32_t share_access,
6116 uint32_t create_disposition,
6117 uint32_t create_options,
6118 uint32_t file_attributes,
6119 uint32_t oplock_request,
6120 const struct smb2_lease *lease,
6121 uint64_t allocation_size,
6122 uint32_t private_flags,
6123 struct security_descriptor *sd,
6124 struct ea_list *ea_list,
6126 files_struct **result,
6127 int *pinfo)
6129 struct smb2_lease none_lease;
6130 int info = FILE_WAS_OPENED;
6131 files_struct *base_fsp = NULL;
6132 files_struct *fsp = NULL;
6133 bool free_fsp_on_error = false;
6134 NTSTATUS status;
6135 int ret;
6136 struct smb_filename *parent_dir_fname = NULL;
6137 struct smb_filename *smb_fname_atname = NULL;
6139 DBG_DEBUG("access_mask = 0x%"PRIx32" "
6140 "file_attributes = 0x%"PRIx32" "
6141 "share_access = 0x%"PRIx32" "
6142 "create_disposition = 0x%"PRIx32" "
6143 "create_options = 0x%"PRIx32" "
6144 "oplock_request = 0x%"PRIx32" "
6145 "private_flags = 0x%"PRIx32" "
6146 "ea_list = %p, "
6147 "sd = %p, "
6148 "fname = %s\n",
6149 access_mask,
6150 file_attributes,
6151 share_access,
6152 create_disposition,
6153 create_options,
6154 oplock_request,
6155 private_flags,
6156 ea_list,
6158 smb_fname_str_dbg(smb_fname));
6160 if (create_options & FILE_OPEN_BY_FILE_ID) {
6161 status = NT_STATUS_NOT_SUPPORTED;
6162 goto fail;
6165 if (create_options & NTCREATEX_OPTIONS_INVALID_PARAM_MASK) {
6166 status = NT_STATUS_INVALID_PARAMETER;
6167 goto fail;
6170 if (!(create_options & FILE_OPEN_REPARSE_POINT) &&
6171 (smb_fname->fsp != NULL) && /* new files don't have an fsp */
6172 VALID_STAT(smb_fname->fsp->fsp_name->st))
6174 mode_t type = (smb_fname->fsp->fsp_name->st.st_ex_mode &
6175 S_IFMT);
6177 switch (type) {
6178 case S_IFREG:
6179 FALL_THROUGH;
6180 case S_IFDIR:
6181 break;
6182 case S_IFLNK:
6184 * We should never get this far with a symlink
6185 * "as such". Report as not existing.
6187 status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
6188 goto fail;
6189 default:
6190 status = NT_STATUS_IO_REPARSE_TAG_NOT_HANDLED;
6191 goto fail;
6195 if (req == NULL) {
6196 oplock_request |= INTERNAL_OPEN_ONLY;
6199 if (lease != NULL) {
6200 uint16_t epoch = lease->lease_epoch;
6201 uint16_t version = lease->lease_version;
6203 if (req == NULL) {
6204 DBG_WARNING("Got lease on internal open\n");
6205 status = NT_STATUS_INTERNAL_ERROR;
6206 goto fail;
6209 status = lease_match(conn,
6210 req,
6211 &lease->lease_key,
6212 conn->connectpath,
6213 smb_fname,
6214 &version,
6215 &epoch);
6216 if (NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) {
6217 /* Dynamic share file. No leases and update epoch... */
6218 none_lease = *lease;
6219 none_lease.lease_state = SMB2_LEASE_NONE;
6220 none_lease.lease_epoch = epoch;
6221 none_lease.lease_version = version;
6222 lease = &none_lease;
6223 } else if (!NT_STATUS_IS_OK(status)) {
6224 goto fail;
6228 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
6229 && (access_mask & DELETE_ACCESS)
6230 && !is_named_stream(smb_fname)) {
6232 * We can't open a file with DELETE access if any of the
6233 * streams is open without FILE_SHARE_DELETE
6235 status = open_streams_for_delete(conn, smb_fname);
6237 if (!NT_STATUS_IS_OK(status)) {
6238 goto fail;
6242 if (access_mask & SEC_FLAG_SYSTEM_SECURITY) {
6243 bool ok;
6245 ok = security_token_has_privilege(get_current_nttok(conn),
6246 SEC_PRIV_SECURITY);
6247 if (!ok) {
6248 DBG_DEBUG("open on %s failed - "
6249 "SEC_FLAG_SYSTEM_SECURITY denied.\n",
6250 smb_fname_str_dbg(smb_fname));
6251 status = NT_STATUS_PRIVILEGE_NOT_HELD;
6252 goto fail;
6255 if (conn_using_smb2(conn->sconn) &&
6256 (access_mask == SEC_FLAG_SYSTEM_SECURITY))
6259 * No other bits set. Windows SMB2 refuses this.
6260 * See smbtorture3 SMB2-SACL test.
6262 * Note this is an SMB2-only behavior,
6263 * smbtorture3 SMB1-SYSTEM-SECURITY already tests
6264 * that SMB1 allows this.
6266 status = NT_STATUS_ACCESS_DENIED;
6267 goto fail;
6272 * Files or directories can't be opened DELETE_ON_CLOSE without
6273 * delete access.
6274 * BUG: https://bugzilla.samba.org/show_bug.cgi?id=13358
6276 if ((create_options & FILE_DELETE_ON_CLOSE) &&
6277 ((access_mask & DELETE_ACCESS) == 0)) {
6278 status = NT_STATUS_INVALID_PARAMETER;
6279 goto fail;
6282 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
6283 && is_named_stream(smb_fname))
6285 uint32_t base_create_disposition;
6286 struct smb_filename *smb_fname_base = NULL;
6287 uint32_t base_privflags;
6289 if (create_options & FILE_DIRECTORY_FILE) {
6290 DBG_DEBUG("Can't open a stream as directory\n");
6291 status = NT_STATUS_NOT_A_DIRECTORY;
6292 goto fail;
6295 switch (create_disposition) {
6296 case FILE_OPEN:
6297 base_create_disposition = FILE_OPEN;
6298 break;
6299 default:
6300 base_create_disposition = FILE_OPEN_IF;
6301 break;
6304 smb_fname_base = cp_smb_filename_nostream(
6305 talloc_tos(), smb_fname);
6307 if (smb_fname_base == NULL) {
6308 status = NT_STATUS_NO_MEMORY;
6309 goto fail;
6313 * We may be creating the basefile as part of creating the
6314 * stream, so it's legal if the basefile doesn't exist at this
6315 * point, the create_file_unixpath() below will create it. But
6316 * if the basefile exists we want a handle so we can fstat() it.
6319 ret = vfs_stat(conn, smb_fname_base);
6320 if (ret == -1 && errno != ENOENT) {
6321 status = map_nt_error_from_unix(errno);
6322 TALLOC_FREE(smb_fname_base);
6323 goto fail;
6325 if (ret == 0) {
6326 status = openat_pathref_fsp(conn->cwd_fsp,
6327 smb_fname_base);
6328 if (!NT_STATUS_IS_OK(status)) {
6329 DBG_ERR("open_smb_fname_fsp [%s] failed: %s\n",
6330 smb_fname_str_dbg(smb_fname_base),
6331 nt_errstr(status));
6332 TALLOC_FREE(smb_fname_base);
6333 goto fail;
6337 * https://bugzilla.samba.org/show_bug.cgi?id=10229
6338 * We need to check if the requested access mask
6339 * could be used to open the underlying file (if
6340 * it existed), as we're passing in zero for the
6341 * access mask to the base filename.
6343 status = check_base_file_access(smb_fname_base->fsp,
6344 access_mask);
6346 if (!NT_STATUS_IS_OK(status)) {
6347 DEBUG(10, ("Permission check "
6348 "for base %s failed: "
6349 "%s\n", smb_fname->base_name,
6350 nt_errstr(status)));
6351 TALLOC_FREE(smb_fname_base);
6352 goto fail;
6356 base_privflags = NTCREATEX_FLAG_STREAM_BASEOPEN;
6358 /* Open the base file. */
6359 status = create_file_unixpath(conn,
6360 NULL,
6361 dirfsp,
6362 smb_fname_base,
6364 FILE_SHARE_READ
6365 | FILE_SHARE_WRITE
6366 | FILE_SHARE_DELETE,
6367 base_create_disposition,
6371 NULL,
6373 base_privflags,
6374 NULL,
6375 NULL,
6376 &base_fsp,
6377 NULL);
6378 TALLOC_FREE(smb_fname_base);
6380 if (!NT_STATUS_IS_OK(status)) {
6381 DEBUG(10, ("create_file_unixpath for base %s failed: "
6382 "%s\n", smb_fname->base_name,
6383 nt_errstr(status)));
6384 goto fail;
6388 if (smb_fname->fsp != NULL) {
6390 fsp = smb_fname->fsp;
6393 * We're about to use smb_fname->fsp for the fresh open.
6395 * Every fsp passed in via smb_fname->fsp already
6396 * holds a fsp->fsp_name. If it is already this
6397 * fsp->fsp_name that we got passed in as our input
6398 * argument smb_fname, these two are assumed to have
6399 * the same lifetime: Every fsp hangs of "conn", and
6400 * fsp->fsp_name is its talloc child.
6403 if (smb_fname != smb_fname->fsp->fsp_name) {
6405 * "smb_fname" is temporary in this case, but
6406 * the destructor of smb_fname would also tear
6407 * down the fsp we're about to use. Unlink
6408 * them from each other.
6410 smb_fname_fsp_unlink(smb_fname);
6413 * "fsp" is ours now
6415 free_fsp_on_error = true;
6418 status = fsp_bind_smb(fsp, req);
6419 if (!NT_STATUS_IS_OK(status)) {
6420 goto fail;
6423 if (fsp_is_alternate_stream(fsp)) {
6424 struct files_struct *tmp_base_fsp = fsp->base_fsp;
6426 fsp_set_base_fsp(fsp, NULL);
6428 fd_close(tmp_base_fsp);
6429 file_free(NULL, tmp_base_fsp);
6431 } else {
6433 * No fsp passed in that we can use, create one
6435 status = file_new(req, conn, &fsp);
6436 if(!NT_STATUS_IS_OK(status)) {
6437 goto fail;
6439 free_fsp_on_error = true;
6441 status = fsp_set_smb_fname(fsp, smb_fname);
6442 if (!NT_STATUS_IS_OK(status)) {
6443 goto fail;
6447 SMB_ASSERT(fsp->fsp_name->fsp != NULL);
6448 SMB_ASSERT(fsp->fsp_name->fsp == fsp);
6450 if (base_fsp) {
6452 * We're opening the stream element of a
6453 * base_fsp we already opened. Set up the
6454 * base_fsp pointer.
6456 fsp_set_base_fsp(fsp, base_fsp);
6459 if (dirfsp != NULL) {
6460 status = SMB_VFS_PARENT_PATHNAME(
6461 conn,
6462 talloc_tos(),
6463 smb_fname,
6464 &parent_dir_fname,
6465 &smb_fname_atname);
6466 if (!NT_STATUS_IS_OK(status)) {
6467 goto fail;
6469 } else {
6471 * Get a pathref on the parent. We can re-use this for
6472 * multiple calls to check parent ACLs etc. to avoid
6473 * pathname calls.
6475 status = parent_pathref(talloc_tos(),
6476 conn->cwd_fsp,
6477 smb_fname,
6478 &parent_dir_fname,
6479 &smb_fname_atname);
6480 if (!NT_STATUS_IS_OK(status)) {
6481 goto fail;
6484 dirfsp = parent_dir_fname->fsp;
6485 status = fsp_set_smb_fname(dirfsp, parent_dir_fname);
6486 if (!NT_STATUS_IS_OK(status)) {
6487 goto fail;
6492 * If it's a request for a directory open, deal with it separately.
6495 if (create_options & FILE_DIRECTORY_FILE) {
6497 if (create_options & FILE_NON_DIRECTORY_FILE) {
6498 status = NT_STATUS_INVALID_PARAMETER;
6499 goto fail;
6502 /* Can't open a temp directory. IFS kit test. */
6503 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
6504 (file_attributes & FILE_ATTRIBUTE_TEMPORARY)) {
6505 status = NT_STATUS_INVALID_PARAMETER;
6506 goto fail;
6510 * We will get a create directory here if the Win32
6511 * app specified a security descriptor in the
6512 * CreateDirectory() call.
6515 status = open_directory(conn,
6516 req,
6517 access_mask,
6518 share_access,
6519 create_disposition,
6520 create_options,
6521 file_attributes,
6522 dirfsp->fsp_name,
6523 smb_fname_atname,
6524 oplock_request,
6525 lease,
6527 &info,
6528 fsp);
6529 } else {
6532 * Ordinary file case.
6535 if (allocation_size) {
6536 fsp->initial_allocation_size = smb_roundup(fsp->conn,
6537 allocation_size);
6540 status = open_file_ntcreate(conn,
6541 req,
6542 access_mask,
6543 share_access,
6544 create_disposition,
6545 create_options,
6546 file_attributes,
6547 oplock_request,
6548 lease,
6549 private_flags,
6550 dirfsp->fsp_name,
6551 smb_fname_atname,
6552 &info,
6553 fsp);
6554 if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
6556 /* A stream open never opens a directory */
6558 if (base_fsp) {
6559 status = NT_STATUS_FILE_IS_A_DIRECTORY;
6560 goto fail;
6564 * Fail the open if it was explicitly a non-directory
6565 * file.
6568 if (create_options & FILE_NON_DIRECTORY_FILE) {
6569 status = NT_STATUS_FILE_IS_A_DIRECTORY;
6570 goto fail;
6573 status = open_directory(conn,
6574 req,
6575 access_mask,
6576 share_access,
6577 create_disposition,
6578 create_options,
6579 file_attributes,
6580 dirfsp->fsp_name,
6581 smb_fname_atname,
6582 oplock_request,
6583 lease,
6585 &info,
6586 fsp);
6590 if (!NT_STATUS_IS_OK(status)) {
6591 goto fail;
6594 fsp->fsp_flags.is_fsa = true;
6596 if ((ea_list != NULL) &&
6597 ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN))) {
6598 status = set_ea(conn, fsp, ea_list);
6599 if (!NT_STATUS_IS_OK(status)) {
6600 goto fail;
6604 if (!fsp->fsp_flags.is_directory &&
6605 S_ISDIR(fsp->fsp_name->st.st_ex_mode))
6607 status = NT_STATUS_ACCESS_DENIED;
6608 goto fail;
6611 /* Save the requested allocation size. */
6612 if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
6613 if ((allocation_size > (uint64_t)fsp->fsp_name->st.st_ex_size)
6614 && !(fsp->fsp_flags.is_directory))
6616 fsp->initial_allocation_size = smb_roundup(
6617 fsp->conn, allocation_size);
6618 if (vfs_allocate_file_space(
6619 fsp, fsp->initial_allocation_size) == -1) {
6620 status = NT_STATUS_DISK_FULL;
6621 goto fail;
6623 } else {
6624 fsp->initial_allocation_size = smb_roundup(
6625 fsp->conn, (uint64_t)fsp->fsp_name->st.st_ex_size);
6627 } else {
6628 fsp->initial_allocation_size = 0;
6631 if ((info == FILE_WAS_CREATED) &&
6632 !S_ISDIR(fsp->fsp_name->st.st_ex_mode) &&
6633 lp_nt_acl_support(SNUM(conn)) &&
6634 !fsp_is_alternate_stream(fsp)) {
6635 status = apply_new_nt_acl(dirfsp, fsp, sd);
6636 if (!NT_STATUS_IS_OK(status)) {
6637 DBG_WARNING("apply_new_nt_acl(): failed for %s with %s\n",
6638 fsp_str_dbg(fsp), nt_errstr(status));
6639 goto fail;
6643 if ((conn->fs_capabilities & FILE_FILE_COMPRESSION)
6644 && (create_options & FILE_NO_COMPRESSION)
6645 && (info == FILE_WAS_CREATED)) {
6646 status = SMB_VFS_SET_COMPRESSION(conn, fsp, fsp,
6647 COMPRESSION_FORMAT_NONE);
6648 if (!NT_STATUS_IS_OK(status)) {
6649 DEBUG(1, ("failed to disable compression: %s\n",
6650 nt_errstr(status)));
6654 DEBUG(10, ("create_file_unixpath: info=%d\n", info));
6656 *result = fsp;
6657 if (pinfo != NULL) {
6658 *pinfo = info;
6661 smb_fname->st = fsp->fsp_name->st;
6663 TALLOC_FREE(parent_dir_fname);
6665 return NT_STATUS_OK;
6667 fail:
6668 DEBUG(10, ("create_file_unixpath: %s\n", nt_errstr(status)));
6670 if (fsp != NULL) {
6672 * The close_file below will close
6673 * fsp->base_fsp.
6675 base_fsp = NULL;
6676 close_file_smb(req, fsp, ERROR_CLOSE);
6677 if (free_fsp_on_error) {
6678 file_free(req, fsp);
6679 fsp = NULL;
6682 if (base_fsp != NULL) {
6683 close_file_free(req, &base_fsp, ERROR_CLOSE);
6686 TALLOC_FREE(parent_dir_fname);
6688 return status;
6691 static NTSTATUS check_posix_create_context(connection_struct *conn,
6692 struct smb_request *req,
6693 const struct smb2_create_blobs *in_context_blobs,
6694 uint32_t create_options,
6695 uint32_t *file_attributes)
6697 uint32_t wire_mode_bits = 0;
6698 NTSTATUS status;
6699 mode_t mode_bits = 0;
6700 SMB_STRUCT_STAT sbuf = { 0 };
6701 struct smb2_create_blob *posx = NULL;
6703 if (req == NULL || !req->posix_pathnames) {
6704 return NT_STATUS_OK;
6707 posx = smb2_create_blob_find(
6708 in_context_blobs, SMB2_CREATE_TAG_POSIX);
6709 if (posx == NULL) {
6710 return NT_STATUS_OK;
6713 if (posx->data.length != 4) {
6714 return NT_STATUS_INVALID_PARAMETER;
6717 wire_mode_bits = IVAL(posx->data.data, 0);
6718 status = unix_perms_from_wire(conn,
6719 &sbuf,
6720 wire_mode_bits,
6721 &mode_bits);
6722 if (!NT_STATUS_IS_OK(status)) {
6723 return status;
6725 if (create_options & FILE_DIRECTORY_FILE) {
6726 mode_bits = apply_conf_dir_mask(conn, mode_bits);
6727 } else {
6728 mode_bits = apply_conf_file_mask(conn, mode_bits);
6731 * Remove type info from mode, leaving only the
6732 * permissions and setuid/gid bits.
6734 mode_bits &= ~S_IFMT;
6736 *file_attributes = (FILE_FLAG_POSIX_SEMANTICS | mode_bits);
6738 return NT_STATUS_OK;
6741 NTSTATUS create_file_default(connection_struct *conn,
6742 struct smb_request *req,
6743 struct files_struct *dirfsp,
6744 struct smb_filename *smb_fname,
6745 uint32_t access_mask,
6746 uint32_t share_access,
6747 uint32_t create_disposition,
6748 uint32_t create_options,
6749 uint32_t file_attributes,
6750 uint32_t oplock_request,
6751 const struct smb2_lease *lease,
6752 uint64_t allocation_size,
6753 uint32_t private_flags,
6754 struct security_descriptor *sd,
6755 struct ea_list *ea_list,
6756 files_struct **result,
6757 int *pinfo,
6758 const struct smb2_create_blobs *in_context_blobs,
6759 struct smb2_create_blobs *out_context_blobs)
6761 int info = FILE_WAS_OPENED;
6762 files_struct *fsp = NULL;
6763 NTSTATUS status;
6764 bool stream_name = false;
6766 DBG_DEBUG("access_mask = 0x%" PRIu32
6767 " file_attributes = 0x%" PRIu32
6768 " share_access = 0x%" PRIu32
6769 " create_disposition = 0x%" PRIu32
6770 " create_options = 0x%" PRIu32
6771 " oplock_request = 0x%" PRIu32
6772 " private_flags = 0x%" PRIu32
6773 " ea_list = %p, sd = %p, fname = %s\n",
6774 access_mask,
6775 file_attributes,
6776 share_access,
6777 create_disposition,
6778 create_options,
6779 oplock_request,
6780 private_flags,
6781 ea_list,
6783 smb_fname_str_dbg(smb_fname));
6785 if (req != NULL) {
6787 * Remember the absolute time of the original request
6788 * with this mid. We'll use it later to see if this
6789 * has timed out.
6791 get_deferred_open_message_state(req, &req->request_time, NULL);
6795 * Check to see if this is a mac fork of some kind.
6798 stream_name = is_ntfs_stream_smb_fname(smb_fname);
6799 if (stream_name) {
6800 enum FAKE_FILE_TYPE fake_file_type;
6802 fake_file_type = is_fake_file(smb_fname);
6804 if (req != NULL && fake_file_type != FAKE_FILE_TYPE_NONE) {
6807 * Here we go! support for changing the disk quotas
6808 * --metze
6810 * We need to fake up to open this MAGIC QUOTA file
6811 * and return a valid FID.
6813 * w2k close this file directly after opening xp
6814 * also tries a QUERY_FILE_INFO on the file and then
6815 * close it
6817 status = open_fake_file(req, conn, req->vuid,
6818 fake_file_type, smb_fname,
6819 access_mask, &fsp);
6820 if (!NT_STATUS_IS_OK(status)) {
6821 goto fail;
6824 ZERO_STRUCT(smb_fname->st);
6825 goto done;
6828 if (!(conn->fs_capabilities & FILE_NAMED_STREAMS)) {
6829 status = NT_STATUS_OBJECT_NAME_INVALID;
6830 goto fail;
6834 if (is_ntfs_default_stream_smb_fname(smb_fname)) {
6835 int ret;
6836 /* We have to handle this error here. */
6837 if (create_options & FILE_DIRECTORY_FILE) {
6838 status = NT_STATUS_NOT_A_DIRECTORY;
6839 goto fail;
6841 ret = vfs_stat(conn, smb_fname);
6842 if (ret == 0 && VALID_STAT_OF_DIR(smb_fname->st)) {
6843 status = NT_STATUS_FILE_IS_A_DIRECTORY;
6844 goto fail;
6848 status = check_posix_create_context(conn,
6849 req,
6850 in_context_blobs,
6851 create_options,
6852 &file_attributes);
6853 if (!NT_STATUS_IS_OK(status)) {
6854 goto fail;
6857 status = create_file_unixpath(conn,
6858 req,
6859 dirfsp,
6860 smb_fname,
6861 access_mask,
6862 share_access,
6863 create_disposition,
6864 create_options,
6865 file_attributes,
6866 oplock_request,
6867 lease,
6868 allocation_size,
6869 private_flags,
6871 ea_list,
6872 &fsp,
6873 &info);
6874 if (!NT_STATUS_IS_OK(status)) {
6875 goto fail;
6878 done:
6879 DEBUG(10, ("create_file: info=%d\n", info));
6881 *result = fsp;
6882 if (pinfo != NULL) {
6883 *pinfo = info;
6885 return NT_STATUS_OK;
6887 fail:
6888 DEBUG(10, ("create_file: %s\n", nt_errstr(status)));
6890 if (fsp != NULL) {
6891 close_file_free(req, &fsp, ERROR_CLOSE);
6893 return status;