s3: VFS: Protect errno if sys_getwd() fails across free() call.
[Samba.git] / source3 / smbd / open.c
blobfa0d78b15793421522127ce45f79e212a5ec9264
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
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include "includes.h"
23 #include "system/filesys.h"
24 #include "printing.h"
25 #include "smbd/smbd.h"
26 #include "smbd/globals.h"
27 #include "fake_file.h"
28 #include "../libcli/security/security.h"
29 #include "../librpc/gen_ndr/ndr_security.h"
30 #include "../librpc/gen_ndr/open_files.h"
31 #include "../librpc/gen_ndr/idmap.h"
32 #include "../librpc/gen_ndr/ioctl.h"
33 #include "passdb/lookup_sid.h"
34 #include "auth.h"
35 #include "serverid.h"
36 #include "messages.h"
37 #include "source3/lib/dbwrap/dbwrap_watch.h"
38 #include "locking/leases_db.h"
39 #include "librpc/gen_ndr/ndr_leases_db.h"
41 extern const struct generic_mapping file_generic_mapping;
43 struct deferred_open_record {
44 bool delayed_for_oplocks;
45 bool async_open;
46 struct file_id id;
49 * Timer for async opens, needed because they don't use a watch on
50 * a locking.tdb record. This is currently only used for real async
51 * opens and just terminates smbd if the async open times out.
53 struct tevent_timer *te;
56 /****************************************************************************
57 If the requester wanted DELETE_ACCESS and was rejected because
58 the file ACL didn't include DELETE_ACCESS, see if the parent ACL
59 overrides this.
60 ****************************************************************************/
62 static bool parent_override_delete(connection_struct *conn,
63 const struct smb_filename *smb_fname,
64 uint32_t access_mask,
65 uint32_t rejected_mask)
67 if ((access_mask & DELETE_ACCESS) &&
68 (rejected_mask & DELETE_ACCESS) &&
69 can_delete_file_in_directory(conn, smb_fname)) {
70 return true;
72 return false;
75 /****************************************************************************
76 Check if we have open rights.
77 ****************************************************************************/
79 NTSTATUS smbd_check_access_rights(struct connection_struct *conn,
80 const struct smb_filename *smb_fname,
81 bool use_privs,
82 uint32_t access_mask)
84 /* Check if we have rights to open. */
85 NTSTATUS status;
86 struct security_descriptor *sd = NULL;
87 uint32_t rejected_share_access;
88 uint32_t rejected_mask = access_mask;
89 uint32_t do_not_check_mask = 0;
91 rejected_share_access = access_mask & ~(conn->share_access);
93 if (rejected_share_access) {
94 DEBUG(10, ("smbd_check_access_rights: rejected share access 0x%x "
95 "on %s (0x%x)\n",
96 (unsigned int)access_mask,
97 smb_fname_str_dbg(smb_fname),
98 (unsigned int)rejected_share_access ));
99 return NT_STATUS_ACCESS_DENIED;
102 if (!use_privs && get_current_uid(conn) == (uid_t)0) {
103 /* I'm sorry sir, I didn't know you were root... */
104 DEBUG(10,("smbd_check_access_rights: root override "
105 "on %s. Granting 0x%x\n",
106 smb_fname_str_dbg(smb_fname),
107 (unsigned int)access_mask ));
108 return NT_STATUS_OK;
111 if ((access_mask & DELETE_ACCESS) && !lp_acl_check_permissions(SNUM(conn))) {
112 DEBUG(10,("smbd_check_access_rights: not checking ACL "
113 "on DELETE_ACCESS on file %s. Granting 0x%x\n",
114 smb_fname_str_dbg(smb_fname),
115 (unsigned int)access_mask ));
116 return NT_STATUS_OK;
119 if (access_mask == DELETE_ACCESS &&
120 VALID_STAT(smb_fname->st) &&
121 S_ISLNK(smb_fname->st.st_ex_mode)) {
122 /* We can always delete a symlink. */
123 DEBUG(10,("smbd_check_access_rights: not checking ACL "
124 "on DELETE_ACCESS on symlink %s.\n",
125 smb_fname_str_dbg(smb_fname) ));
126 return NT_STATUS_OK;
129 status = SMB_VFS_GET_NT_ACL(conn, smb_fname,
130 (SECINFO_OWNER |
131 SECINFO_GROUP |
132 SECINFO_DACL), talloc_tos(), &sd);
134 if (!NT_STATUS_IS_OK(status)) {
135 DEBUG(10, ("smbd_check_access_rights: Could not get acl "
136 "on %s: %s\n",
137 smb_fname_str_dbg(smb_fname),
138 nt_errstr(status)));
140 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
141 goto access_denied;
144 return status;
148 * If we can access the path to this file, by
149 * default we have FILE_READ_ATTRIBUTES from the
150 * containing directory. See the section:
151 * "Algorithm to Check Access to an Existing File"
152 * in MS-FSA.pdf.
154 * se_file_access_check() also takes care of
155 * owner WRITE_DAC and READ_CONTROL.
157 do_not_check_mask = FILE_READ_ATTRIBUTES;
160 * Samba 3.6 and earlier granted execute access even
161 * if the ACL did not contain execute rights.
162 * Samba 4.0 is more correct and checks it.
163 * The compatibilty mode allows one to skip this check
164 * to smoothen upgrades.
166 if (lp_acl_allow_execute_always(SNUM(conn))) {
167 do_not_check_mask |= FILE_EXECUTE;
170 status = se_file_access_check(sd,
171 get_current_nttok(conn),
172 use_privs,
173 (access_mask & ~do_not_check_mask),
174 &rejected_mask);
176 DEBUG(10,("smbd_check_access_rights: file %s requesting "
177 "0x%x returning 0x%x (%s)\n",
178 smb_fname_str_dbg(smb_fname),
179 (unsigned int)access_mask,
180 (unsigned int)rejected_mask,
181 nt_errstr(status) ));
183 if (!NT_STATUS_IS_OK(status)) {
184 if (DEBUGLEVEL >= 10) {
185 DEBUG(10,("smbd_check_access_rights: acl for %s is:\n",
186 smb_fname_str_dbg(smb_fname) ));
187 NDR_PRINT_DEBUG(security_descriptor, sd);
191 TALLOC_FREE(sd);
193 if (NT_STATUS_IS_OK(status) ||
194 !NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
195 return status;
198 /* Here we know status == NT_STATUS_ACCESS_DENIED. */
200 access_denied:
202 if ((access_mask & FILE_WRITE_ATTRIBUTES) &&
203 (rejected_mask & FILE_WRITE_ATTRIBUTES) &&
204 !lp_store_dos_attributes(SNUM(conn)) &&
205 (lp_map_readonly(SNUM(conn)) ||
206 lp_map_archive(SNUM(conn)) ||
207 lp_map_hidden(SNUM(conn)) ||
208 lp_map_system(SNUM(conn)))) {
209 rejected_mask &= ~FILE_WRITE_ATTRIBUTES;
211 DEBUG(10,("smbd_check_access_rights: "
212 "overrode "
213 "FILE_WRITE_ATTRIBUTES "
214 "on file %s\n",
215 smb_fname_str_dbg(smb_fname)));
218 if (parent_override_delete(conn,
219 smb_fname,
220 access_mask,
221 rejected_mask)) {
222 /* Were we trying to do an open
223 * for delete and didn't get DELETE
224 * access (only) ? Check if the
225 * directory allows DELETE_CHILD.
226 * See here:
227 * http://blogs.msdn.com/oldnewthing/archive/2004/06/04/148426.aspx
228 * for details. */
230 rejected_mask &= ~DELETE_ACCESS;
232 DEBUG(10,("smbd_check_access_rights: "
233 "overrode "
234 "DELETE_ACCESS on "
235 "file %s\n",
236 smb_fname_str_dbg(smb_fname)));
239 if (rejected_mask != 0) {
240 return NT_STATUS_ACCESS_DENIED;
242 return NT_STATUS_OK;
245 NTSTATUS check_parent_access(struct connection_struct *conn,
246 struct smb_filename *smb_fname,
247 uint32_t access_mask)
249 NTSTATUS status;
250 char *parent_dir = NULL;
251 struct security_descriptor *parent_sd = NULL;
252 uint32_t access_granted = 0;
253 struct smb_filename *parent_smb_fname = NULL;
255 if (!parent_dirname(talloc_tos(),
256 smb_fname->base_name,
257 &parent_dir,
258 NULL)) {
259 return NT_STATUS_NO_MEMORY;
262 parent_smb_fname = synthetic_smb_fname(talloc_tos(),
263 parent_dir,
264 NULL,
265 NULL,
266 smb_fname->flags);
267 if (parent_smb_fname == NULL) {
268 return NT_STATUS_NO_MEMORY;
271 if (get_current_uid(conn) == (uid_t)0) {
272 /* I'm sorry sir, I didn't know you were root... */
273 DEBUG(10,("check_parent_access: root override "
274 "on %s. Granting 0x%x\n",
275 smb_fname_str_dbg(smb_fname),
276 (unsigned int)access_mask ));
277 return NT_STATUS_OK;
280 status = SMB_VFS_GET_NT_ACL(conn,
281 parent_smb_fname,
282 SECINFO_DACL,
283 talloc_tos(),
284 &parent_sd);
286 if (!NT_STATUS_IS_OK(status)) {
287 DEBUG(5,("check_parent_access: SMB_VFS_GET_NT_ACL failed for "
288 "%s with error %s\n",
289 parent_dir,
290 nt_errstr(status)));
291 return status;
295 * If we can access the path to this file, by
296 * default we have FILE_READ_ATTRIBUTES from the
297 * containing directory. See the section:
298 * "Algorithm to Check Access to an Existing File"
299 * in MS-FSA.pdf.
301 * se_file_access_check() also takes care of
302 * owner WRITE_DAC and READ_CONTROL.
304 status = se_file_access_check(parent_sd,
305 get_current_nttok(conn),
306 false,
307 (access_mask & ~FILE_READ_ATTRIBUTES),
308 &access_granted);
309 if(!NT_STATUS_IS_OK(status)) {
310 DEBUG(5,("check_parent_access: access check "
311 "on directory %s for "
312 "path %s for mask 0x%x returned (0x%x) %s\n",
313 parent_dir,
314 smb_fname->base_name,
315 access_mask,
316 access_granted,
317 nt_errstr(status) ));
318 return status;
321 return NT_STATUS_OK;
324 /****************************************************************************
325 Ensure when opening a base file for a stream open that we have permissions
326 to do so given the access mask on the base file.
327 ****************************************************************************/
329 static NTSTATUS check_base_file_access(struct connection_struct *conn,
330 struct smb_filename *smb_fname,
331 uint32_t access_mask)
333 NTSTATUS status;
335 status = smbd_calculate_access_mask(conn, smb_fname,
336 false,
337 access_mask,
338 &access_mask);
339 if (!NT_STATUS_IS_OK(status)) {
340 DEBUG(10, ("smbd_calculate_access_mask "
341 "on file %s returned %s\n",
342 smb_fname_str_dbg(smb_fname),
343 nt_errstr(status)));
344 return status;
347 if (access_mask & (FILE_WRITE_DATA|FILE_APPEND_DATA)) {
348 uint32_t dosattrs;
349 if (!CAN_WRITE(conn)) {
350 return NT_STATUS_ACCESS_DENIED;
352 dosattrs = dos_mode(conn, smb_fname);
353 if (IS_DOS_READONLY(dosattrs)) {
354 return NT_STATUS_ACCESS_DENIED;
358 return smbd_check_access_rights(conn,
359 smb_fname,
360 false,
361 access_mask);
364 /****************************************************************************
365 Handle differing symlink errno's
366 ****************************************************************************/
368 static int link_errno_convert(int err)
370 #if defined(ENOTSUP) && defined(OSF1)
371 /* handle special Tru64 errno */
372 if (err == ENOTSUP) {
373 err = ELOOP;
375 #endif /* ENOTSUP */
376 #ifdef EFTYPE
377 /* fix broken NetBSD errno */
378 if (err == EFTYPE) {
379 err = ELOOP;
381 #endif /* EFTYPE */
382 /* fix broken FreeBSD errno */
383 if (err == EMLINK) {
384 err = ELOOP;
386 return err;
389 static int non_widelink_open(struct connection_struct *conn,
390 const char *conn_rootdir,
391 files_struct *fsp,
392 struct smb_filename *smb_fname,
393 int flags,
394 mode_t mode,
395 unsigned int link_depth);
397 /****************************************************************************
398 Follow a symlink in userspace.
399 ****************************************************************************/
401 static int process_symlink_open(struct connection_struct *conn,
402 const char *conn_rootdir,
403 files_struct *fsp,
404 struct smb_filename *smb_fname,
405 int flags,
406 mode_t mode,
407 unsigned int link_depth)
409 int fd = -1;
410 char *link_target = NULL;
411 int link_len = -1;
412 char *oldwd = NULL;
413 size_t rootdir_len = 0;
414 char *resolved_name = NULL;
415 bool matched = false;
416 int saved_errno = 0;
419 * Ensure we don't get stuck in a symlink loop.
421 link_depth++;
422 if (link_depth >= 20) {
423 errno = ELOOP;
424 goto out;
427 /* Allocate space for the link target. */
428 link_target = talloc_array(talloc_tos(), char, PATH_MAX);
429 if (link_target == NULL) {
430 errno = ENOMEM;
431 goto out;
434 /* Read the link target. */
435 link_len = SMB_VFS_READLINK(conn,
436 smb_fname->base_name,
437 link_target,
438 PATH_MAX - 1);
439 if (link_len == -1) {
440 goto out;
443 /* Ensure it's at least null terminated. */
444 link_target[link_len] = '\0';
446 /* Convert to an absolute path. */
447 resolved_name = SMB_VFS_REALPATH(conn, link_target);
448 if (resolved_name == NULL) {
449 goto out;
453 * We know conn_rootdir starts with '/' and
454 * does not end in '/'. FIXME ! Should we
455 * smb_assert this ?
457 rootdir_len = strlen(conn_rootdir);
459 matched = (strncmp(conn_rootdir, resolved_name, rootdir_len) == 0);
460 if (!matched) {
461 errno = EACCES;
462 goto out;
466 * Turn into a path relative to the share root.
468 if (resolved_name[rootdir_len] == '\0') {
469 /* Link to the root of the share. */
470 smb_fname->base_name = talloc_strdup(talloc_tos(), ".");
471 if (smb_fname->base_name == NULL) {
472 errno = ENOMEM;
473 goto out;
475 } else if (resolved_name[rootdir_len] == '/') {
476 smb_fname->base_name = &resolved_name[rootdir_len+1];
477 } else {
478 errno = EACCES;
479 goto out;
482 oldwd = vfs_GetWd(talloc_tos(), conn);
483 if (oldwd == NULL) {
484 goto out;
487 /* Ensure we operate from the root of the share. */
488 if (vfs_ChDir(conn, conn_rootdir) == -1) {
489 goto out;
492 /* And do it all again.. */
493 fd = non_widelink_open(conn,
494 conn_rootdir,
495 fsp,
496 smb_fname,
497 flags,
498 mode,
499 link_depth);
500 if (fd == -1) {
501 saved_errno = errno;
504 out:
506 SAFE_FREE(resolved_name);
507 TALLOC_FREE(link_target);
508 if (oldwd != NULL) {
509 int ret = vfs_ChDir(conn, oldwd);
510 if (ret == -1) {
511 smb_panic("unable to get back to old directory\n");
513 TALLOC_FREE(oldwd);
515 if (saved_errno != 0) {
516 errno = saved_errno;
518 return fd;
521 /****************************************************************************
522 Non-widelink open.
523 ****************************************************************************/
525 static int non_widelink_open(struct connection_struct *conn,
526 const char *conn_rootdir,
527 files_struct *fsp,
528 struct smb_filename *smb_fname,
529 int flags,
530 mode_t mode,
531 unsigned int link_depth)
533 NTSTATUS status;
534 int fd = -1;
535 struct smb_filename *smb_fname_rel = NULL;
536 int saved_errno = 0;
537 char *oldwd = NULL;
538 char *parent_dir = NULL;
539 const char *final_component = NULL;
540 bool is_directory = false;
541 bool ok;
543 #ifdef O_DIRECTORY
544 if (flags & O_DIRECTORY) {
545 is_directory = true;
547 #endif
549 if (is_directory) {
550 parent_dir = talloc_strdup(talloc_tos(), smb_fname->base_name);
551 if (parent_dir == NULL) {
552 saved_errno = errno;
553 goto out;
556 final_component = ".";
557 } else {
558 ok = parent_dirname(talloc_tos(),
559 smb_fname->base_name,
560 &parent_dir,
561 &final_component);
562 if (!ok) {
563 saved_errno = errno;
564 goto out;
568 oldwd = vfs_GetWd(talloc_tos(), conn);
569 if (oldwd == NULL) {
570 goto out;
573 /* Pin parent directory in place. */
574 if (vfs_ChDir(conn, parent_dir) == -1) {
575 goto out;
578 /* Ensure the relative path is below the share. */
579 status = check_reduced_name(conn, parent_dir, final_component);
580 if (!NT_STATUS_IS_OK(status)) {
581 saved_errno = map_errno_from_nt_status(status);
582 goto out;
585 smb_fname_rel = synthetic_smb_fname(talloc_tos(),
586 final_component,
587 smb_fname->stream_name,
588 &smb_fname->st,
589 smb_fname->flags);
591 flags |= O_NOFOLLOW;
594 struct smb_filename *tmp_name = fsp->fsp_name;
595 fsp->fsp_name = smb_fname_rel;
596 fd = SMB_VFS_OPEN(conn, smb_fname_rel, fsp, flags, mode);
597 fsp->fsp_name = tmp_name;
600 if (fd == -1) {
601 saved_errno = link_errno_convert(errno);
603 * Trying to open a symlink to a directory with O_NOFOLLOW and
604 * O_DIRECTORY can return either of ELOOP and ENOTDIR. So
605 * ENOTDIR really means: might be a symlink, but we're not sure.
606 * In this case, we just assume there's a symlink. If we were
607 * wrong, process_symlink_open() will return EINVAL. We check
608 * this below, and fall back to returning the initial
609 * saved_errno.
611 * BUG: https://bugzilla.samba.org/show_bug.cgi?id=12860
613 if (saved_errno == ELOOP || saved_errno == ENOTDIR) {
614 if (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) {
615 /* Never follow symlinks on posix open. */
616 goto out;
618 if (!lp_follow_symlinks(SNUM(conn))) {
619 /* Explicitly no symlinks. */
620 goto out;
623 * We may have a symlink. Follow in userspace
624 * to ensure it's under the share definition.
626 fd = process_symlink_open(conn,
627 conn_rootdir,
628 fsp,
629 smb_fname_rel,
630 flags,
631 mode,
632 link_depth);
633 if (fd == -1) {
634 if (saved_errno == ENOTDIR &&
635 errno == EINVAL) {
637 * O_DIRECTORY on neither a directory,
638 * nor a symlink. Just return
639 * saved_errno from initial open()
641 goto out;
643 saved_errno =
644 link_errno_convert(errno);
649 out:
651 TALLOC_FREE(parent_dir);
652 TALLOC_FREE(smb_fname_rel);
654 if (oldwd != NULL) {
655 int ret = vfs_ChDir(conn, oldwd);
656 if (ret == -1) {
657 smb_panic("unable to get back to old directory\n");
659 TALLOC_FREE(oldwd);
661 if (saved_errno != 0) {
662 errno = saved_errno;
664 return fd;
667 /****************************************************************************
668 fd support routines - attempt to do a dos_open.
669 ****************************************************************************/
671 NTSTATUS fd_open(struct connection_struct *conn,
672 files_struct *fsp,
673 int flags,
674 mode_t mode)
676 struct smb_filename *smb_fname = fsp->fsp_name;
677 NTSTATUS status = NT_STATUS_OK;
680 * Never follow symlinks on a POSIX client. The
681 * client should be doing this.
684 if ((fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) || !lp_follow_symlinks(SNUM(conn))) {
685 flags |= O_NOFOLLOW;
688 /* Ensure path is below share definition. */
689 if (!lp_widelinks(SNUM(conn))) {
690 const char *conn_rootdir = SMB_VFS_CONNECTPATH(conn,
691 smb_fname->base_name);
692 if (conn_rootdir == NULL) {
693 return NT_STATUS_NO_MEMORY;
696 * Only follow symlinks within a share
697 * definition.
699 fsp->fh->fd = non_widelink_open(conn,
700 conn_rootdir,
701 fsp,
702 smb_fname,
703 flags,
704 mode,
706 } else {
707 fsp->fh->fd = SMB_VFS_OPEN(conn, smb_fname, fsp, flags, mode);
710 if (fsp->fh->fd == -1) {
711 int posix_errno = link_errno_convert(errno);
712 status = map_nt_error_from_unix(posix_errno);
713 if (errno == EMFILE) {
714 static time_t last_warned = 0L;
716 if (time((time_t *) NULL) > last_warned) {
717 DEBUG(0,("Too many open files, unable "
718 "to open more! smbd's max "
719 "open files = %d\n",
720 lp_max_open_files()));
721 last_warned = time((time_t *) NULL);
727 DEBUG(10,("fd_open: name %s, flags = 0%o mode = 0%o, fd = %d. %s\n",
728 smb_fname_str_dbg(smb_fname), flags, (int)mode, fsp->fh->fd,
729 (fsp->fh->fd == -1) ? strerror(errno) : "" ));
731 return status;
734 /****************************************************************************
735 Close the file associated with a fsp.
736 ****************************************************************************/
738 NTSTATUS fd_close(files_struct *fsp)
740 int ret;
742 if (fsp->dptr) {
743 dptr_CloseDir(fsp);
745 if (fsp->fh->fd == -1) {
746 return NT_STATUS_OK; /* What we used to call a stat open. */
748 if (fsp->fh->ref_count > 1) {
749 return NT_STATUS_OK; /* Shared handle. Only close last reference. */
752 ret = SMB_VFS_CLOSE(fsp);
753 fsp->fh->fd = -1;
754 if (ret == -1) {
755 return map_nt_error_from_unix(errno);
757 return NT_STATUS_OK;
760 /****************************************************************************
761 Change the ownership of a file to that of the parent directory.
762 Do this by fd if possible.
763 ****************************************************************************/
765 void change_file_owner_to_parent(connection_struct *conn,
766 const char *inherit_from_dir,
767 files_struct *fsp)
769 struct smb_filename *smb_fname_parent;
770 int ret;
772 smb_fname_parent = synthetic_smb_fname(talloc_tos(),
773 inherit_from_dir,
774 NULL,
775 NULL,
777 if (smb_fname_parent == NULL) {
778 return;
781 ret = SMB_VFS_STAT(conn, smb_fname_parent);
782 if (ret == -1) {
783 DEBUG(0,("change_file_owner_to_parent: failed to stat parent "
784 "directory %s. Error was %s\n",
785 smb_fname_str_dbg(smb_fname_parent),
786 strerror(errno)));
787 TALLOC_FREE(smb_fname_parent);
788 return;
791 if (smb_fname_parent->st.st_ex_uid == fsp->fsp_name->st.st_ex_uid) {
792 /* Already this uid - no need to change. */
793 DEBUG(10,("change_file_owner_to_parent: file %s "
794 "is already owned by uid %d\n",
795 fsp_str_dbg(fsp),
796 (int)fsp->fsp_name->st.st_ex_uid ));
797 TALLOC_FREE(smb_fname_parent);
798 return;
801 become_root();
802 ret = SMB_VFS_FCHOWN(fsp, smb_fname_parent->st.st_ex_uid, (gid_t)-1);
803 unbecome_root();
804 if (ret == -1) {
805 DEBUG(0,("change_file_owner_to_parent: failed to fchown "
806 "file %s to parent directory uid %u. Error "
807 "was %s\n", fsp_str_dbg(fsp),
808 (unsigned int)smb_fname_parent->st.st_ex_uid,
809 strerror(errno) ));
810 } else {
811 DEBUG(10,("change_file_owner_to_parent: changed new file %s to "
812 "parent directory uid %u.\n", fsp_str_dbg(fsp),
813 (unsigned int)smb_fname_parent->st.st_ex_uid));
814 /* Ensure the uid entry is updated. */
815 fsp->fsp_name->st.st_ex_uid = smb_fname_parent->st.st_ex_uid;
818 TALLOC_FREE(smb_fname_parent);
821 NTSTATUS change_dir_owner_to_parent(connection_struct *conn,
822 const char *inherit_from_dir,
823 const char *fname,
824 SMB_STRUCT_STAT *psbuf)
826 struct smb_filename *smb_fname_parent;
827 struct smb_filename *smb_fname_cwd = NULL;
828 char *saved_dir = NULL;
829 TALLOC_CTX *ctx = talloc_tos();
830 NTSTATUS status = NT_STATUS_OK;
831 int ret;
833 smb_fname_parent = synthetic_smb_fname(ctx,
834 inherit_from_dir,
835 NULL,
836 NULL,
838 if (smb_fname_parent == NULL) {
839 return NT_STATUS_NO_MEMORY;
842 ret = SMB_VFS_STAT(conn, smb_fname_parent);
843 if (ret == -1) {
844 status = map_nt_error_from_unix(errno);
845 DEBUG(0,("change_dir_owner_to_parent: failed to stat parent "
846 "directory %s. Error was %s\n",
847 smb_fname_str_dbg(smb_fname_parent),
848 strerror(errno)));
849 goto out;
852 /* We've already done an lstat into psbuf, and we know it's a
853 directory. If we can cd into the directory and the dev/ino
854 are the same then we can safely chown without races as
855 we're locking the directory in place by being in it. This
856 should work on any UNIX (thanks tridge :-). JRA.
859 saved_dir = vfs_GetWd(ctx,conn);
860 if (!saved_dir) {
861 status = map_nt_error_from_unix(errno);
862 DEBUG(0,("change_dir_owner_to_parent: failed to get "
863 "current working directory. Error was %s\n",
864 strerror(errno)));
865 goto out;
868 /* Chdir into the new path. */
869 if (vfs_ChDir(conn, fname) == -1) {
870 status = map_nt_error_from_unix(errno);
871 DEBUG(0,("change_dir_owner_to_parent: failed to change "
872 "current working directory to %s. Error "
873 "was %s\n", fname, strerror(errno) ));
874 goto chdir;
877 smb_fname_cwd = synthetic_smb_fname(ctx, ".", NULL, NULL, 0);
878 if (smb_fname_cwd == NULL) {
879 status = NT_STATUS_NO_MEMORY;
880 goto chdir;
883 ret = SMB_VFS_STAT(conn, smb_fname_cwd);
884 if (ret == -1) {
885 status = map_nt_error_from_unix(errno);
886 DEBUG(0,("change_dir_owner_to_parent: failed to stat "
887 "directory '.' (%s) Error was %s\n",
888 fname, strerror(errno)));
889 goto chdir;
892 /* Ensure we're pointing at the same place. */
893 if (smb_fname_cwd->st.st_ex_dev != psbuf->st_ex_dev ||
894 smb_fname_cwd->st.st_ex_ino != psbuf->st_ex_ino) {
895 DEBUG(0,("change_dir_owner_to_parent: "
896 "device/inode on directory %s changed. "
897 "Refusing to chown !\n", fname ));
898 status = NT_STATUS_ACCESS_DENIED;
899 goto chdir;
902 if (smb_fname_parent->st.st_ex_uid == smb_fname_cwd->st.st_ex_uid) {
903 /* Already this uid - no need to change. */
904 DEBUG(10,("change_dir_owner_to_parent: directory %s "
905 "is already owned by uid %d\n",
906 fname,
907 (int)smb_fname_cwd->st.st_ex_uid ));
908 status = NT_STATUS_OK;
909 goto chdir;
912 become_root();
913 ret = SMB_VFS_LCHOWN(conn,
914 smb_fname_cwd,
915 smb_fname_parent->st.st_ex_uid,
916 (gid_t)-1);
917 unbecome_root();
918 if (ret == -1) {
919 status = map_nt_error_from_unix(errno);
920 DEBUG(10,("change_dir_owner_to_parent: failed to chown "
921 "directory %s to parent directory uid %u. "
922 "Error was %s\n", fname,
923 (unsigned int)smb_fname_parent->st.st_ex_uid,
924 strerror(errno) ));
925 } else {
926 DEBUG(10,("change_dir_owner_to_parent: changed ownership of new "
927 "directory %s to parent directory uid %u.\n",
928 fname, (unsigned int)smb_fname_parent->st.st_ex_uid ));
929 /* Ensure the uid entry is updated. */
930 psbuf->st_ex_uid = smb_fname_parent->st.st_ex_uid;
933 chdir:
934 vfs_ChDir(conn,saved_dir);
935 out:
936 TALLOC_FREE(smb_fname_parent);
937 TALLOC_FREE(smb_fname_cwd);
938 return status;
941 /****************************************************************************
942 Open a file - returning a guaranteed ATOMIC indication of if the
943 file was created or not.
944 ****************************************************************************/
946 static NTSTATUS fd_open_atomic(struct connection_struct *conn,
947 files_struct *fsp,
948 int flags,
949 mode_t mode,
950 bool *file_created)
952 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
953 NTSTATUS retry_status;
954 bool file_existed = VALID_STAT(fsp->fsp_name->st);
955 int curr_flags;
957 *file_created = false;
959 if (!(flags & O_CREAT)) {
961 * We're not creating the file, just pass through.
963 return fd_open(conn, fsp, flags, mode);
966 if (flags & O_EXCL) {
968 * Fail if already exists, just pass through.
970 status = fd_open(conn, fsp, flags, mode);
973 * Here we've opened with O_CREAT|O_EXCL. If that went
974 * NT_STATUS_OK, we *know* we created this file.
976 *file_created = NT_STATUS_IS_OK(status);
978 return status;
982 * Now it gets tricky. We have O_CREAT, but not O_EXCL.
983 * To know absolutely if we created the file or not,
984 * we can never call O_CREAT without O_EXCL. So if
985 * we think the file existed, try without O_CREAT|O_EXCL.
986 * If we think the file didn't exist, try with
987 * O_CREAT|O_EXCL.
989 * The big problem here is dangling symlinks. Opening
990 * without O_NOFOLLOW means both bad symlink
991 * and missing path return -1, ENOENT from open(). As POSIX
992 * is pathname based it's not possible to tell
993 * the difference between these two cases in a
994 * non-racy way, so change to try only two attempts before
995 * giving up.
997 * We don't have this problem for the O_NOFOLLOW
998 * case as it just returns NT_STATUS_OBJECT_PATH_NOT_FOUND
999 * mapped from the ELOOP POSIX error.
1002 curr_flags = flags;
1004 if (file_existed) {
1005 curr_flags &= ~(O_CREAT);
1006 retry_status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
1007 } else {
1008 curr_flags |= O_EXCL;
1009 retry_status = NT_STATUS_OBJECT_NAME_COLLISION;
1012 status = fd_open(conn, fsp, curr_flags, mode);
1013 if (NT_STATUS_IS_OK(status)) {
1014 if (!file_existed) {
1015 *file_created = true;
1017 return NT_STATUS_OK;
1019 if (!NT_STATUS_EQUAL(status, retry_status)) {
1020 return status;
1023 curr_flags = flags;
1026 * Keep file_existed up to date for clarity.
1028 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
1029 file_existed = false;
1030 curr_flags |= O_EXCL;
1031 DBG_DEBUG("file %s did not exist. Retry.\n",
1032 smb_fname_str_dbg(fsp->fsp_name));
1033 } else {
1034 file_existed = true;
1035 curr_flags &= ~(O_CREAT);
1036 DBG_DEBUG("file %s existed. Retry.\n",
1037 smb_fname_str_dbg(fsp->fsp_name));
1040 status = fd_open(conn, fsp, curr_flags, mode);
1042 if (NT_STATUS_IS_OK(status) && (!file_existed)) {
1043 *file_created = true;
1046 return status;
1049 /****************************************************************************
1050 Open a file.
1051 ****************************************************************************/
1053 static NTSTATUS open_file(files_struct *fsp,
1054 connection_struct *conn,
1055 struct smb_request *req,
1056 const char *parent_dir,
1057 int flags,
1058 mode_t unx_mode,
1059 uint32_t access_mask, /* client requested access mask. */
1060 uint32_t open_access_mask, /* what we're actually using in the open. */
1061 bool *p_file_created)
1063 struct smb_filename *smb_fname = fsp->fsp_name;
1064 NTSTATUS status = NT_STATUS_OK;
1065 int accmode = (flags & O_ACCMODE);
1066 int local_flags = flags;
1067 bool file_existed = VALID_STAT(fsp->fsp_name->st);
1069 fsp->fh->fd = -1;
1070 errno = EPERM;
1072 /* Check permissions */
1075 * This code was changed after seeing a client open request
1076 * containing the open mode of (DENY_WRITE/read-only) with
1077 * the 'create if not exist' bit set. The previous code
1078 * would fail to open the file read only on a read-only share
1079 * as it was checking the flags parameter directly against O_RDONLY,
1080 * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
1081 * JRA.
1084 if (!CAN_WRITE(conn)) {
1085 /* It's a read-only share - fail if we wanted to write. */
1086 if(accmode != O_RDONLY || (flags & O_TRUNC) || (flags & O_APPEND)) {
1087 DEBUG(3,("Permission denied opening %s\n",
1088 smb_fname_str_dbg(smb_fname)));
1089 return NT_STATUS_ACCESS_DENIED;
1091 if (flags & O_CREAT) {
1092 /* We don't want to write - but we must make sure that
1093 O_CREAT doesn't create the file if we have write
1094 access into the directory.
1096 flags &= ~(O_CREAT|O_EXCL);
1097 local_flags &= ~(O_CREAT|O_EXCL);
1102 * This little piece of insanity is inspired by the
1103 * fact that an NT client can open a file for O_RDONLY,
1104 * but set the create disposition to FILE_EXISTS_TRUNCATE.
1105 * If the client *can* write to the file, then it expects to
1106 * truncate the file, even though it is opening for readonly.
1107 * Quicken uses this stupid trick in backup file creation...
1108 * Thanks *greatly* to "David W. Chapman Jr." <dwcjr@inethouston.net>
1109 * for helping track this one down. It didn't bite us in 2.0.x
1110 * as we always opened files read-write in that release. JRA.
1113 if ((accmode == O_RDONLY) && ((flags & O_TRUNC) == O_TRUNC)) {
1114 DEBUG(10,("open_file: truncate requested on read-only open "
1115 "for file %s\n", smb_fname_str_dbg(smb_fname)));
1116 local_flags = (flags & ~O_ACCMODE)|O_RDWR;
1119 if ((open_access_mask & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_EXECUTE)) ||
1120 (!file_existed && (local_flags & O_CREAT)) ||
1121 ((local_flags & O_TRUNC) == O_TRUNC) ) {
1122 const char *wild;
1123 int ret;
1125 #if defined(O_NONBLOCK) && defined(S_ISFIFO)
1127 * We would block on opening a FIFO with no one else on the
1128 * other end. Do what we used to do and add O_NONBLOCK to the
1129 * open flags. JRA.
1132 if (file_existed && S_ISFIFO(smb_fname->st.st_ex_mode)) {
1133 local_flags &= ~O_TRUNC; /* Can't truncate a FIFO. */
1134 local_flags |= O_NONBLOCK;
1136 #endif
1138 /* Don't create files with Microsoft wildcard characters. */
1139 if (fsp->base_fsp) {
1141 * wildcard characters are allowed in stream names
1142 * only test the basefilename
1144 wild = fsp->base_fsp->fsp_name->base_name;
1145 } else {
1146 wild = smb_fname->base_name;
1148 if ((local_flags & O_CREAT) && !file_existed &&
1149 !(fsp->posix_flags & FSP_POSIX_FLAGS_PATHNAMES) &&
1150 ms_has_wild(wild)) {
1151 return NT_STATUS_OBJECT_NAME_INVALID;
1154 /* Can we access this file ? */
1155 if (!fsp->base_fsp) {
1156 /* Only do this check on non-stream open. */
1157 if (file_existed) {
1158 status = smbd_check_access_rights(conn,
1159 smb_fname,
1160 false,
1161 access_mask);
1163 if (!NT_STATUS_IS_OK(status)) {
1164 DEBUG(10, ("open_file: "
1165 "smbd_check_access_rights "
1166 "on file %s returned %s\n",
1167 smb_fname_str_dbg(smb_fname),
1168 nt_errstr(status)));
1171 if (!NT_STATUS_IS_OK(status) &&
1172 !NT_STATUS_EQUAL(status,
1173 NT_STATUS_OBJECT_NAME_NOT_FOUND))
1175 return status;
1178 if (NT_STATUS_EQUAL(status,
1179 NT_STATUS_OBJECT_NAME_NOT_FOUND))
1181 DEBUG(10, ("open_file: "
1182 "file %s vanished since we "
1183 "checked for existence.\n",
1184 smb_fname_str_dbg(smb_fname)));
1185 file_existed = false;
1186 SET_STAT_INVALID(fsp->fsp_name->st);
1190 if (!file_existed) {
1191 if (!(local_flags & O_CREAT)) {
1192 /* File didn't exist and no O_CREAT. */
1193 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1196 status = check_parent_access(conn,
1197 smb_fname,
1198 SEC_DIR_ADD_FILE);
1199 if (!NT_STATUS_IS_OK(status)) {
1200 DEBUG(10, ("open_file: "
1201 "check_parent_access on "
1202 "file %s returned %s\n",
1203 smb_fname_str_dbg(smb_fname),
1204 nt_errstr(status) ));
1205 return status;
1211 * Actually do the open - if O_TRUNC is needed handle it
1212 * below under the share mode lock.
1214 status = fd_open_atomic(conn, fsp, local_flags & ~O_TRUNC,
1215 unx_mode, p_file_created);
1216 if (!NT_STATUS_IS_OK(status)) {
1217 DEBUG(3,("Error opening file %s (%s) (local_flags=%d) "
1218 "(flags=%d)\n", smb_fname_str_dbg(smb_fname),
1219 nt_errstr(status),local_flags,flags));
1220 return status;
1223 if (local_flags & O_NONBLOCK) {
1225 * GPFS can return ETIMEDOUT for pread on
1226 * nonblocking file descriptors when files
1227 * migrated to tape need to be recalled. I
1228 * could imagine this happens elsehwere
1229 * too. With blocking file descriptors this
1230 * does not happen.
1232 ret = set_blocking(fsp->fh->fd, true);
1233 if (ret == -1) {
1234 status = map_nt_error_from_unix(errno);
1235 DBG_WARNING("Could not set fd to blocking: "
1236 "%s\n", strerror(errno));
1237 fd_close(fsp);
1238 return status;
1242 ret = SMB_VFS_FSTAT(fsp, &smb_fname->st);
1243 if (ret == -1) {
1244 /* If we have an fd, this stat should succeed. */
1245 DEBUG(0,("Error doing fstat on open file %s "
1246 "(%s)\n",
1247 smb_fname_str_dbg(smb_fname),
1248 strerror(errno) ));
1249 status = map_nt_error_from_unix(errno);
1250 fd_close(fsp);
1251 return status;
1254 if (*p_file_created) {
1255 /* We created this file. */
1257 bool need_re_stat = false;
1258 /* Do all inheritance work after we've
1259 done a successful fstat call and filled
1260 in the stat struct in fsp->fsp_name. */
1262 /* Inherit the ACL if required */
1263 if (lp_inherit_permissions(SNUM(conn))) {
1264 inherit_access_posix_acl(conn, parent_dir,
1265 smb_fname->base_name,
1266 unx_mode);
1267 need_re_stat = true;
1270 /* Change the owner if required. */
1271 if (lp_inherit_owner(SNUM(conn)) != INHERIT_OWNER_NO) {
1272 change_file_owner_to_parent(conn, parent_dir,
1273 fsp);
1274 need_re_stat = true;
1277 if (need_re_stat) {
1278 ret = SMB_VFS_FSTAT(fsp, &smb_fname->st);
1279 /* If we have an fd, this stat should succeed. */
1280 if (ret == -1) {
1281 DEBUG(0,("Error doing fstat on open file %s "
1282 "(%s)\n",
1283 smb_fname_str_dbg(smb_fname),
1284 strerror(errno) ));
1288 notify_fname(conn, NOTIFY_ACTION_ADDED,
1289 FILE_NOTIFY_CHANGE_FILE_NAME,
1290 smb_fname->base_name);
1292 } else {
1293 fsp->fh->fd = -1; /* What we used to call a stat open. */
1294 if (!file_existed) {
1295 /* File must exist for a stat open. */
1296 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1299 status = smbd_check_access_rights(conn,
1300 smb_fname,
1301 false,
1302 access_mask);
1304 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) &&
1305 (fsp->posix_flags & FSP_POSIX_FLAGS_OPEN) &&
1306 S_ISLNK(smb_fname->st.st_ex_mode)) {
1307 /* This is a POSIX stat open for delete
1308 * or rename on a symlink that points
1309 * nowhere. Allow. */
1310 DEBUG(10,("open_file: allowing POSIX "
1311 "open on bad symlink %s\n",
1312 smb_fname_str_dbg(smb_fname)));
1313 status = NT_STATUS_OK;
1316 if (!NT_STATUS_IS_OK(status)) {
1317 DEBUG(10,("open_file: "
1318 "smbd_check_access_rights on file "
1319 "%s returned %s\n",
1320 smb_fname_str_dbg(smb_fname),
1321 nt_errstr(status) ));
1322 return status;
1327 * POSIX allows read-only opens of directories. We don't
1328 * want to do this (we use a different code path for this)
1329 * so catch a directory open and return an EISDIR. JRA.
1332 if(S_ISDIR(smb_fname->st.st_ex_mode)) {
1333 fd_close(fsp);
1334 errno = EISDIR;
1335 return NT_STATUS_FILE_IS_A_DIRECTORY;
1338 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
1339 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
1340 fsp->file_pid = req ? req->smbpid : 0;
1341 fsp->can_lock = True;
1342 fsp->can_read = ((access_mask & FILE_READ_DATA) != 0);
1343 fsp->can_write =
1344 CAN_WRITE(conn) &&
1345 ((access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) != 0);
1346 fsp->print_file = NULL;
1347 fsp->modified = False;
1348 fsp->sent_oplock_break = NO_BREAK_SENT;
1349 fsp->is_directory = False;
1350 if (conn->aio_write_behind_list &&
1351 is_in_path(smb_fname->base_name, conn->aio_write_behind_list,
1352 conn->case_sensitive)) {
1353 fsp->aio_write_behind = True;
1356 fsp->wcp = NULL; /* Write cache pointer. */
1358 DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
1359 conn->session_info->unix_info->unix_name,
1360 smb_fname_str_dbg(smb_fname),
1361 BOOLSTR(fsp->can_read), BOOLSTR(fsp->can_write),
1362 conn->num_files_open));
1364 errno = 0;
1365 return NT_STATUS_OK;
1368 /****************************************************************************
1369 Check if we can open a file with a share mode.
1370 Returns True if conflict, False if not.
1371 ****************************************************************************/
1373 static bool share_conflict(struct share_mode_entry *entry,
1374 uint32_t access_mask,
1375 uint32_t share_access)
1377 DEBUG(10,("share_conflict: entry->access_mask = 0x%x, "
1378 "entry->share_access = 0x%x, "
1379 "entry->private_options = 0x%x\n",
1380 (unsigned int)entry->access_mask,
1381 (unsigned int)entry->share_access,
1382 (unsigned int)entry->private_options));
1384 if (server_id_is_disconnected(&entry->pid)) {
1386 * note: cleanup should have been done by
1387 * delay_for_batch_oplocks()
1389 return false;
1392 DEBUG(10,("share_conflict: access_mask = 0x%x, share_access = 0x%x\n",
1393 (unsigned int)access_mask, (unsigned int)share_access));
1395 if ((entry->access_mask & (FILE_WRITE_DATA|
1396 FILE_APPEND_DATA|
1397 FILE_READ_DATA|
1398 FILE_EXECUTE|
1399 DELETE_ACCESS)) == 0) {
1400 DEBUG(10,("share_conflict: No conflict due to "
1401 "entry->access_mask = 0x%x\n",
1402 (unsigned int)entry->access_mask ));
1403 return False;
1406 if ((access_mask & (FILE_WRITE_DATA|
1407 FILE_APPEND_DATA|
1408 FILE_READ_DATA|
1409 FILE_EXECUTE|
1410 DELETE_ACCESS)) == 0) {
1411 DEBUG(10,("share_conflict: No conflict due to "
1412 "access_mask = 0x%x\n",
1413 (unsigned int)access_mask ));
1414 return False;
1417 #if 1 /* JRA TEST - Superdebug. */
1418 #define CHECK_MASK(num, am, right, sa, share) \
1419 DEBUG(10,("share_conflict: [%d] am (0x%x) & right (0x%x) = 0x%x\n", \
1420 (unsigned int)(num), (unsigned int)(am), \
1421 (unsigned int)(right), (unsigned int)(am)&(right) )); \
1422 DEBUG(10,("share_conflict: [%d] sa (0x%x) & share (0x%x) = 0x%x\n", \
1423 (unsigned int)(num), (unsigned int)(sa), \
1424 (unsigned int)(share), (unsigned int)(sa)&(share) )); \
1425 if (((am) & (right)) && !((sa) & (share))) { \
1426 DEBUG(10,("share_conflict: check %d conflict am = 0x%x, right = 0x%x, \
1427 sa = 0x%x, share = 0x%x\n", (num), (unsigned int)(am), (unsigned int)(right), (unsigned int)(sa), \
1428 (unsigned int)(share) )); \
1429 return True; \
1431 #else
1432 #define CHECK_MASK(num, am, right, sa, share) \
1433 if (((am) & (right)) && !((sa) & (share))) { \
1434 DEBUG(10,("share_conflict: check %d conflict am = 0x%x, right = 0x%x, \
1435 sa = 0x%x, share = 0x%x\n", (num), (unsigned int)(am), (unsigned int)(right), (unsigned int)(sa), \
1436 (unsigned int)(share) )); \
1437 return True; \
1439 #endif
1441 CHECK_MASK(1, entry->access_mask, FILE_WRITE_DATA | FILE_APPEND_DATA,
1442 share_access, FILE_SHARE_WRITE);
1443 CHECK_MASK(2, access_mask, FILE_WRITE_DATA | FILE_APPEND_DATA,
1444 entry->share_access, FILE_SHARE_WRITE);
1446 CHECK_MASK(3, entry->access_mask, FILE_READ_DATA | FILE_EXECUTE,
1447 share_access, FILE_SHARE_READ);
1448 CHECK_MASK(4, access_mask, FILE_READ_DATA | FILE_EXECUTE,
1449 entry->share_access, FILE_SHARE_READ);
1451 CHECK_MASK(5, entry->access_mask, DELETE_ACCESS,
1452 share_access, FILE_SHARE_DELETE);
1453 CHECK_MASK(6, access_mask, DELETE_ACCESS,
1454 entry->share_access, FILE_SHARE_DELETE);
1456 DEBUG(10,("share_conflict: No conflict.\n"));
1457 return False;
1460 #if defined(DEVELOPER)
1461 static void validate_my_share_entries(struct smbd_server_connection *sconn,
1462 int num,
1463 struct share_mode_entry *share_entry)
1465 struct server_id self = messaging_server_id(sconn->msg_ctx);
1466 files_struct *fsp;
1468 if (!serverid_equal(&self, &share_entry->pid)) {
1469 return;
1472 if (share_entry->op_mid == 0) {
1473 /* INTERNAL_OPEN_ONLY */
1474 return;
1477 if (!is_valid_share_mode_entry(share_entry)) {
1478 return;
1481 fsp = file_find_dif(sconn, share_entry->id,
1482 share_entry->share_file_id);
1483 if (!fsp) {
1484 DEBUG(0,("validate_my_share_entries: PANIC : %s\n",
1485 share_mode_str(talloc_tos(), num, share_entry) ));
1486 smb_panic("validate_my_share_entries: Cannot match a "
1487 "share entry with an open file\n");
1490 if (((uint16_t)fsp->oplock_type) != share_entry->op_type) {
1491 goto panic;
1494 return;
1496 panic:
1498 char *str;
1499 DEBUG(0,("validate_my_share_entries: PANIC : %s\n",
1500 share_mode_str(talloc_tos(), num, share_entry) ));
1501 str = talloc_asprintf(talloc_tos(),
1502 "validate_my_share_entries: "
1503 "file %s, oplock_type = 0x%x, op_type = 0x%x\n",
1504 fsp->fsp_name->base_name,
1505 (unsigned int)fsp->oplock_type,
1506 (unsigned int)share_entry->op_type );
1507 smb_panic(str);
1510 #endif
1512 bool is_stat_open(uint32_t access_mask)
1514 const uint32_t stat_open_bits =
1515 (SYNCHRONIZE_ACCESS|
1516 FILE_READ_ATTRIBUTES|
1517 FILE_WRITE_ATTRIBUTES);
1519 return (((access_mask & stat_open_bits) != 0) &&
1520 ((access_mask & ~stat_open_bits) == 0));
1523 static bool has_delete_on_close(struct share_mode_lock *lck,
1524 uint32_t name_hash)
1526 struct share_mode_data *d = lck->data;
1527 uint32_t i;
1529 if (d->num_share_modes == 0) {
1530 return false;
1532 if (!is_delete_on_close_set(lck, name_hash)) {
1533 return false;
1535 for (i=0; i<d->num_share_modes; i++) {
1536 if (!share_mode_stale_pid(d, i)) {
1537 return true;
1540 return false;
1543 /****************************************************************************
1544 Deal with share modes
1545 Invariant: Share mode must be locked on entry and exit.
1546 Returns -1 on error, or number of share modes on success (may be zero).
1547 ****************************************************************************/
1549 static NTSTATUS open_mode_check(connection_struct *conn,
1550 struct share_mode_lock *lck,
1551 uint32_t access_mask,
1552 uint32_t share_access)
1554 uint32_t i;
1556 if(lck->data->num_share_modes == 0) {
1557 return NT_STATUS_OK;
1560 if (is_stat_open(access_mask)) {
1561 /* Stat open that doesn't trigger oplock breaks or share mode
1562 * checks... ! JRA. */
1563 return NT_STATUS_OK;
1567 * Check if the share modes will give us access.
1570 #if defined(DEVELOPER)
1571 for(i = 0; i < lck->data->num_share_modes; i++) {
1572 validate_my_share_entries(conn->sconn, i,
1573 &lck->data->share_modes[i]);
1575 #endif
1577 /* Now we check the share modes, after any oplock breaks. */
1578 for(i = 0; i < lck->data->num_share_modes; i++) {
1580 if (!is_valid_share_mode_entry(&lck->data->share_modes[i])) {
1581 continue;
1584 /* someone else has a share lock on it, check to see if we can
1585 * too */
1586 if (share_conflict(&lck->data->share_modes[i],
1587 access_mask, share_access)) {
1589 if (share_mode_stale_pid(lck->data, i)) {
1590 continue;
1593 return NT_STATUS_SHARING_VIOLATION;
1597 return NT_STATUS_OK;
1601 * Send a break message to the oplock holder and delay the open for
1602 * our client.
1605 NTSTATUS send_break_message(struct messaging_context *msg_ctx,
1606 const struct share_mode_entry *exclusive,
1607 uint16_t break_to)
1609 NTSTATUS status;
1610 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
1611 struct server_id_buf tmp;
1613 DEBUG(10, ("Sending break request to PID %s\n",
1614 server_id_str_buf(exclusive->pid, &tmp)));
1616 /* Create the message. */
1617 share_mode_entry_to_message(msg, exclusive);
1619 /* Overload entry->op_type */
1621 * This is a cut from uint32_t to uint16_t, but so far only the lower 3
1622 * bits (LEASE_WRITE/HANDLE/READ are used anyway.
1624 SSVAL(msg,OP_BREAK_MSG_OP_TYPE_OFFSET, break_to);
1626 status = messaging_send_buf(msg_ctx, exclusive->pid,
1627 MSG_SMB_BREAK_REQUEST,
1628 (uint8_t *)msg, sizeof(msg));
1629 if (!NT_STATUS_IS_OK(status)) {
1630 DEBUG(3, ("Could not send oplock break message: %s\n",
1631 nt_errstr(status)));
1634 return status;
1638 * Do internal consistency checks on the share mode for a file.
1641 static bool validate_oplock_types(struct share_mode_lock *lck)
1643 struct share_mode_data *d = lck->data;
1644 bool batch = false;
1645 bool ex_or_batch = false;
1646 bool level2 = false;
1647 bool no_oplock = false;
1648 uint32_t num_non_stat_opens = 0;
1649 uint32_t i;
1651 for (i=0; i<d->num_share_modes; i++) {
1652 struct share_mode_entry *e = &d->share_modes[i];
1654 if (!is_valid_share_mode_entry(e)) {
1655 continue;
1658 if (e->op_mid == 0) {
1659 /* INTERNAL_OPEN_ONLY */
1660 continue;
1663 if (e->op_type == NO_OPLOCK && is_stat_open(e->access_mask)) {
1664 /* We ignore stat opens in the table - they
1665 always have NO_OPLOCK and never get or
1666 cause breaks. JRA. */
1667 continue;
1670 num_non_stat_opens += 1;
1672 if (BATCH_OPLOCK_TYPE(e->op_type)) {
1673 /* batch - can only be one. */
1674 if (share_mode_stale_pid(d, i)) {
1675 DEBUG(10, ("Found stale batch oplock\n"));
1676 continue;
1678 if (ex_or_batch || batch || level2 || no_oplock) {
1679 DEBUG(0, ("Bad batch oplock entry %u.",
1680 (unsigned)i));
1681 return false;
1683 batch = true;
1686 if (EXCLUSIVE_OPLOCK_TYPE(e->op_type)) {
1687 if (share_mode_stale_pid(d, i)) {
1688 DEBUG(10, ("Found stale duplicate oplock\n"));
1689 continue;
1691 /* Exclusive or batch - can only be one. */
1692 if (ex_or_batch || level2 || no_oplock) {
1693 DEBUG(0, ("Bad exclusive or batch oplock "
1694 "entry %u.", (unsigned)i));
1695 return false;
1697 ex_or_batch = true;
1700 if (LEVEL_II_OPLOCK_TYPE(e->op_type)) {
1701 if (batch || ex_or_batch) {
1702 if (share_mode_stale_pid(d, i)) {
1703 DEBUG(10, ("Found stale LevelII "
1704 "oplock\n"));
1705 continue;
1707 DEBUG(0, ("Bad levelII oplock entry %u.",
1708 (unsigned)i));
1709 return false;
1711 level2 = true;
1714 if (e->op_type == NO_OPLOCK) {
1715 if (batch || ex_or_batch) {
1716 if (share_mode_stale_pid(d, i)) {
1717 DEBUG(10, ("Found stale NO_OPLOCK "
1718 "entry\n"));
1719 continue;
1721 DEBUG(0, ("Bad no oplock entry %u.",
1722 (unsigned)i));
1723 return false;
1725 no_oplock = true;
1729 remove_stale_share_mode_entries(d);
1731 if ((batch || ex_or_batch) && (num_non_stat_opens != 1)) {
1732 DEBUG(1, ("got batch (%d) or ex (%d) non-exclusively (%d)\n",
1733 (int)batch, (int)ex_or_batch,
1734 (int)d->num_share_modes));
1735 return false;
1738 return true;
1741 static bool delay_for_oplock(files_struct *fsp,
1742 int oplock_request,
1743 const struct smb2_lease *lease,
1744 struct share_mode_lock *lck,
1745 bool have_sharing_violation,
1746 uint32_t create_disposition,
1747 bool first_open_attempt)
1749 struct share_mode_data *d = lck->data;
1750 uint32_t i;
1751 bool delay = false;
1752 bool will_overwrite;
1754 if ((oplock_request & INTERNAL_OPEN_ONLY) ||
1755 is_stat_open(fsp->access_mask)) {
1756 return false;
1759 switch (create_disposition) {
1760 case FILE_SUPERSEDE:
1761 case FILE_OVERWRITE:
1762 case FILE_OVERWRITE_IF:
1763 will_overwrite = true;
1764 break;
1765 default:
1766 will_overwrite = false;
1767 break;
1770 for (i=0; i<d->num_share_modes; i++) {
1771 struct share_mode_entry *e = &d->share_modes[i];
1772 struct share_mode_lease *l = NULL;
1773 uint32_t e_lease_type = get_lease_type(d, e);
1774 uint32_t break_to;
1775 uint32_t delay_mask = 0;
1777 if (e->op_type == LEASE_OPLOCK) {
1778 l = &d->leases[e->lease_idx];
1781 if (have_sharing_violation) {
1782 delay_mask = SMB2_LEASE_HANDLE;
1783 } else {
1784 delay_mask = SMB2_LEASE_WRITE;
1787 break_to = e_lease_type & ~delay_mask;
1789 if (will_overwrite) {
1791 * we'll decide about SMB2_LEASE_READ later.
1793 * Maybe the break will be defered
1795 break_to &= ~SMB2_LEASE_HANDLE;
1798 DEBUG(10, ("entry %u: e_lease_type %u, will_overwrite: %u\n",
1799 (unsigned)i, (unsigned)e_lease_type,
1800 (unsigned)will_overwrite));
1802 if (lease != NULL && l != NULL) {
1803 bool ign;
1805 ign = smb2_lease_equal(fsp_client_guid(fsp),
1806 &lease->lease_key,
1807 &l->client_guid,
1808 &l->lease_key);
1809 if (ign) {
1810 continue;
1814 if ((e_lease_type & ~break_to) == 0) {
1815 if (l != NULL && l->breaking) {
1816 delay = true;
1818 continue;
1821 if (share_mode_stale_pid(d, i)) {
1822 continue;
1825 if (will_overwrite) {
1827 * If we break anyway break to NONE directly.
1828 * Otherwise vfs_set_filelen() will trigger the
1829 * break.
1831 break_to &= ~(SMB2_LEASE_READ|SMB2_LEASE_WRITE);
1834 if (e->op_type != LEASE_OPLOCK) {
1836 * Oplocks only support breaking to R or NONE.
1838 break_to &= ~(SMB2_LEASE_HANDLE|SMB2_LEASE_WRITE);
1841 DEBUG(10, ("breaking from %d to %d\n",
1842 (int)e_lease_type, (int)break_to));
1843 send_break_message(fsp->conn->sconn->msg_ctx, e,
1844 break_to);
1845 if (e_lease_type & delay_mask) {
1846 delay = true;
1848 if (l != NULL && l->breaking && !first_open_attempt) {
1849 delay = true;
1851 continue;
1854 return delay;
1858 * Return lease or oplock state from a share mode
1860 static uint32_t get_lease_type_from_share_mode(const struct share_mode_data *d)
1862 uint32_t e_lease_type = 0;
1863 uint32_t i;
1865 for (i=0; i < d->num_share_modes; i++) {
1866 struct share_mode_entry *e = &d->share_modes[i];
1868 e_lease_type |= get_lease_type(d, e);
1871 return e_lease_type;
1874 static bool file_has_brlocks(files_struct *fsp)
1876 struct byte_range_lock *br_lck;
1878 br_lck = brl_get_locks_readonly(fsp);
1879 if (!br_lck)
1880 return false;
1882 return (brl_num_locks(br_lck) > 0);
1885 int find_share_mode_lease(struct share_mode_data *d,
1886 const struct GUID *client_guid,
1887 const struct smb2_lease_key *key)
1889 uint32_t i;
1891 for (i=0; i<d->num_leases; i++) {
1892 struct share_mode_lease *l = &d->leases[i];
1894 if (smb2_lease_equal(client_guid,
1895 key,
1896 &l->client_guid,
1897 &l->lease_key)) {
1898 return i;
1902 return -1;
1905 struct fsp_lease *find_fsp_lease(struct files_struct *new_fsp,
1906 const struct smb2_lease_key *key,
1907 const struct share_mode_lease *l)
1909 struct files_struct *fsp;
1912 * TODO: Measure how expensive this loop is with thousands of open
1913 * handles...
1916 for (fsp = file_find_di_first(new_fsp->conn->sconn, new_fsp->file_id);
1917 fsp != NULL;
1918 fsp = file_find_di_next(fsp)) {
1920 if (fsp == new_fsp) {
1921 continue;
1923 if (fsp->oplock_type != LEASE_OPLOCK) {
1924 continue;
1926 if (smb2_lease_key_equal(&fsp->lease->lease.lease_key, key)) {
1927 fsp->lease->ref_count += 1;
1928 return fsp->lease;
1932 /* Not found - must be leased in another smbd. */
1933 new_fsp->lease = talloc_zero(new_fsp->conn->sconn, struct fsp_lease);
1934 if (new_fsp->lease == NULL) {
1935 return NULL;
1937 new_fsp->lease->ref_count = 1;
1938 new_fsp->lease->sconn = new_fsp->conn->sconn;
1939 new_fsp->lease->lease.lease_key = *key;
1940 new_fsp->lease->lease.lease_state = l->current_state;
1942 * We internally treat all leases as V2 and update
1943 * the epoch, but when sending breaks it matters if
1944 * the requesting lease was v1 or v2.
1946 new_fsp->lease->lease.lease_version = l->lease_version;
1947 new_fsp->lease->lease.lease_epoch = l->epoch;
1948 return new_fsp->lease;
1951 static NTSTATUS grant_fsp_lease(struct files_struct *fsp,
1952 struct share_mode_lock *lck,
1953 const struct smb2_lease *lease,
1954 uint32_t *p_lease_idx,
1955 uint32_t granted)
1957 struct share_mode_data *d = lck->data;
1958 const struct GUID *client_guid = fsp_client_guid(fsp);
1959 struct share_mode_lease *tmp;
1960 NTSTATUS status;
1961 int idx;
1963 idx = find_share_mode_lease(d, client_guid, &lease->lease_key);
1965 if (idx != -1) {
1966 struct share_mode_lease *l = &d->leases[idx];
1967 bool do_upgrade;
1968 uint32_t existing, requested;
1970 fsp->lease = find_fsp_lease(fsp, &lease->lease_key, l);
1971 if (fsp->lease == NULL) {
1972 DEBUG(1, ("Did not find existing lease for file %s\n",
1973 fsp_str_dbg(fsp)));
1974 return NT_STATUS_NO_MEMORY;
1977 *p_lease_idx = idx;
1980 * Upgrade only if the requested lease is a strict upgrade.
1982 existing = l->current_state;
1983 requested = lease->lease_state;
1986 * Tricky: This test makes sure that "requested" is a
1987 * strict bitwise superset of "existing".
1989 do_upgrade = ((existing & requested) == existing);
1992 * Upgrade only if there's a change.
1994 do_upgrade &= (granted != existing);
1997 * Upgrade only if other leases don't prevent what was asked
1998 * for.
2000 do_upgrade &= (granted == requested);
2003 * only upgrade if we are not in breaking state
2005 do_upgrade &= !l->breaking;
2007 DEBUG(10, ("existing=%"PRIu32", requested=%"PRIu32", "
2008 "granted=%"PRIu32", do_upgrade=%d\n",
2009 existing, requested, granted, (int)do_upgrade));
2011 if (do_upgrade) {
2012 l->current_state = granted;
2013 l->epoch += 1;
2016 /* Ensure we're in sync with current lease state. */
2017 fsp_lease_update(lck, fsp_client_guid(fsp), fsp->lease);
2018 return NT_STATUS_OK;
2022 * Create new lease
2025 tmp = talloc_realloc(d, d->leases, struct share_mode_lease,
2026 d->num_leases+1);
2027 if (tmp == NULL) {
2029 * See [MS-SMB2]
2031 return NT_STATUS_INSUFFICIENT_RESOURCES;
2033 d->leases = tmp;
2035 fsp->lease = talloc_zero(fsp->conn->sconn, struct fsp_lease);
2036 if (fsp->lease == NULL) {
2037 return NT_STATUS_INSUFFICIENT_RESOURCES;
2039 fsp->lease->ref_count = 1;
2040 fsp->lease->sconn = fsp->conn->sconn;
2041 fsp->lease->lease.lease_version = lease->lease_version;
2042 fsp->lease->lease.lease_key = lease->lease_key;
2043 fsp->lease->lease.lease_state = granted;
2044 fsp->lease->lease.lease_epoch = lease->lease_epoch + 1;
2046 *p_lease_idx = d->num_leases;
2048 d->leases[d->num_leases] = (struct share_mode_lease) {
2049 .client_guid = *client_guid,
2050 .lease_key = fsp->lease->lease.lease_key,
2051 .current_state = fsp->lease->lease.lease_state,
2052 .lease_version = fsp->lease->lease.lease_version,
2053 .epoch = fsp->lease->lease.lease_epoch,
2056 status = leases_db_add(client_guid,
2057 &lease->lease_key,
2058 &fsp->file_id,
2059 fsp->conn->connectpath,
2060 fsp->fsp_name->base_name,
2061 fsp->fsp_name->stream_name);
2062 if (!NT_STATUS_IS_OK(status)) {
2063 DEBUG(10, ("%s: leases_db_add failed: %s\n", __func__,
2064 nt_errstr(status)));
2065 TALLOC_FREE(fsp->lease);
2066 return NT_STATUS_INSUFFICIENT_RESOURCES;
2069 d->num_leases += 1;
2070 d->modified = true;
2072 return NT_STATUS_OK;
2075 static bool is_same_lease(const files_struct *fsp,
2076 const struct share_mode_data *d,
2077 const struct share_mode_entry *e,
2078 const struct smb2_lease *lease)
2080 if (e->op_type != LEASE_OPLOCK) {
2081 return false;
2083 if (lease == NULL) {
2084 return false;
2087 return smb2_lease_equal(fsp_client_guid(fsp),
2088 &lease->lease_key,
2089 &d->leases[e->lease_idx].client_guid,
2090 &d->leases[e->lease_idx].lease_key);
2093 static NTSTATUS grant_fsp_oplock_type(struct smb_request *req,
2094 struct files_struct *fsp,
2095 struct share_mode_lock *lck,
2096 int oplock_request,
2097 struct smb2_lease *lease)
2099 struct share_mode_data *d = lck->data;
2100 bool got_handle_lease = false;
2101 bool got_oplock = false;
2102 uint32_t i;
2103 uint32_t granted;
2104 uint32_t lease_idx = UINT32_MAX;
2105 bool ok;
2106 NTSTATUS status;
2108 if (oplock_request & INTERNAL_OPEN_ONLY) {
2109 /* No oplocks on internal open. */
2110 oplock_request = NO_OPLOCK;
2111 DEBUG(10,("grant_fsp_oplock_type: oplock type 0x%x on file %s\n",
2112 fsp->oplock_type, fsp_str_dbg(fsp)));
2115 if (oplock_request == LEASE_OPLOCK) {
2116 if (lease == NULL) {
2118 * The SMB2 layer should have checked this
2120 return NT_STATUS_INTERNAL_ERROR;
2123 granted = lease->lease_state;
2125 if (lp_kernel_oplocks(SNUM(fsp->conn))) {
2126 DEBUG(10, ("No lease granted because kernel oplocks are enabled\n"));
2127 granted = SMB2_LEASE_NONE;
2129 if ((granted & (SMB2_LEASE_READ|SMB2_LEASE_WRITE)) == 0) {
2130 DEBUG(10, ("No read or write lease requested\n"));
2131 granted = SMB2_LEASE_NONE;
2133 if (granted == SMB2_LEASE_WRITE) {
2134 DEBUG(10, ("pure write lease requested\n"));
2135 granted = SMB2_LEASE_NONE;
2137 if (granted == (SMB2_LEASE_WRITE|SMB2_LEASE_HANDLE)) {
2138 DEBUG(10, ("write and handle lease requested\n"));
2139 granted = SMB2_LEASE_NONE;
2141 } else {
2142 granted = map_oplock_to_lease_type(
2143 oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK);
2146 if (lp_locking(fsp->conn->params) && file_has_brlocks(fsp)) {
2147 DEBUG(10,("grant_fsp_oplock_type: file %s has byte range locks\n",
2148 fsp_str_dbg(fsp)));
2149 granted &= ~SMB2_LEASE_READ;
2152 for (i=0; i<d->num_share_modes; i++) {
2153 struct share_mode_entry *e = &d->share_modes[i];
2154 uint32_t e_lease_type;
2156 e_lease_type = get_lease_type(d, e);
2158 if ((granted & SMB2_LEASE_WRITE) &&
2159 !is_same_lease(fsp, d, e, lease) &&
2160 !share_mode_stale_pid(d, i)) {
2162 * Can grant only one writer
2164 granted &= ~SMB2_LEASE_WRITE;
2167 if ((e_lease_type & SMB2_LEASE_HANDLE) && !got_handle_lease &&
2168 !share_mode_stale_pid(d, i)) {
2169 got_handle_lease = true;
2172 if ((e->op_type != LEASE_OPLOCK) && !got_oplock &&
2173 !share_mode_stale_pid(d, i)) {
2174 got_oplock = true;
2178 if ((granted & SMB2_LEASE_READ) && !(granted & SMB2_LEASE_WRITE)) {
2179 bool allow_level2 =
2180 (global_client_caps & CAP_LEVEL_II_OPLOCKS) &&
2181 lp_level2_oplocks(SNUM(fsp->conn));
2183 if (!allow_level2) {
2184 granted = SMB2_LEASE_NONE;
2188 if (oplock_request == LEASE_OPLOCK) {
2189 if (got_oplock) {
2190 granted &= ~SMB2_LEASE_HANDLE;
2193 fsp->oplock_type = LEASE_OPLOCK;
2195 status = grant_fsp_lease(fsp, lck, lease, &lease_idx,
2196 granted);
2197 if (!NT_STATUS_IS_OK(status)) {
2198 return status;
2201 *lease = fsp->lease->lease;
2202 DEBUG(10, ("lease_state=%d\n", lease->lease_state));
2203 } else {
2204 if (got_handle_lease) {
2205 granted = SMB2_LEASE_NONE;
2208 switch (granted) {
2209 case SMB2_LEASE_READ|SMB2_LEASE_WRITE|SMB2_LEASE_HANDLE:
2210 fsp->oplock_type = BATCH_OPLOCK|EXCLUSIVE_OPLOCK;
2211 break;
2212 case SMB2_LEASE_READ|SMB2_LEASE_WRITE:
2213 fsp->oplock_type = EXCLUSIVE_OPLOCK;
2214 break;
2215 case SMB2_LEASE_READ|SMB2_LEASE_HANDLE:
2216 case SMB2_LEASE_READ:
2217 fsp->oplock_type = LEVEL_II_OPLOCK;
2218 break;
2219 default:
2220 fsp->oplock_type = NO_OPLOCK;
2221 break;
2224 status = set_file_oplock(fsp);
2225 if (!NT_STATUS_IS_OK(status)) {
2227 * Could not get the kernel oplock
2229 fsp->oplock_type = NO_OPLOCK;
2233 ok = set_share_mode(lck, fsp, get_current_uid(fsp->conn),
2234 req ? req->mid : 0,
2235 fsp->oplock_type,
2236 lease_idx);
2237 if (!ok) {
2238 return NT_STATUS_NO_MEMORY;
2241 ok = update_num_read_oplocks(fsp, lck);
2242 if (!ok) {
2243 del_share_mode(lck, fsp);
2244 return NT_STATUS_INTERNAL_ERROR;
2247 DEBUG(10,("grant_fsp_oplock_type: oplock type 0x%x on file %s\n",
2248 fsp->oplock_type, fsp_str_dbg(fsp)));
2250 return NT_STATUS_OK;
2253 static bool request_timed_out(struct timeval request_time,
2254 struct timeval timeout)
2256 struct timeval now, end_time;
2257 GetTimeOfDay(&now);
2258 end_time = timeval_sum(&request_time, &timeout);
2259 return (timeval_compare(&end_time, &now) < 0);
2262 static struct deferred_open_record *deferred_open_record_create(
2263 bool delayed_for_oplocks,
2264 bool async_open,
2265 struct file_id id)
2267 struct deferred_open_record *record = NULL;
2269 record = talloc(NULL, struct deferred_open_record);
2270 if (record == NULL) {
2271 return NULL;
2274 *record = (struct deferred_open_record) {
2275 .delayed_for_oplocks = delayed_for_oplocks,
2276 .async_open = async_open,
2277 .id = id,
2280 return record;
2283 struct defer_open_state {
2284 struct smbXsrv_connection *xconn;
2285 uint64_t mid;
2286 struct file_id file_id;
2287 struct timeval request_time;
2288 struct timeval timeout;
2289 bool kernel_oplock;
2290 uint32_t lease_type;
2293 static void defer_open_done(struct tevent_req *req);
2296 * Defer an open and watch a locking.tdb record
2298 * This defers an open that gets rescheduled once the locking.tdb record watch
2299 * is triggered by a change to the record.
2301 * It is used to defer opens that triggered an oplock break and for the SMB1
2302 * sharing violation delay.
2304 static void defer_open(struct share_mode_lock *lck,
2305 struct timeval request_time,
2306 struct timeval timeout,
2307 struct smb_request *req,
2308 bool delayed_for_oplocks,
2309 bool kernel_oplock,
2310 struct file_id id)
2312 struct deferred_open_record *open_rec = NULL;
2313 struct timeval abs_timeout;
2314 struct defer_open_state *watch_state;
2315 struct tevent_req *watch_req;
2316 bool ok;
2318 abs_timeout = timeval_sum(&request_time, &timeout);
2320 DBG_DEBUG("request time [%s] timeout [%s] mid [%" PRIu64 "] "
2321 "delayed_for_oplocks [%s] kernel_oplock [%s] file_id [%s]\n",
2322 timeval_string(talloc_tos(), &request_time, false),
2323 timeval_string(talloc_tos(), &abs_timeout, false),
2324 req->mid,
2325 delayed_for_oplocks ? "yes" : "no",
2326 kernel_oplock ? "yes" : "no",
2327 file_id_string_tos(&id));
2329 open_rec = deferred_open_record_create(delayed_for_oplocks,
2330 false,
2331 id);
2332 if (open_rec == NULL) {
2333 TALLOC_FREE(lck);
2334 exit_server("talloc failed");
2337 watch_state = talloc(open_rec, struct defer_open_state);
2338 if (watch_state == NULL) {
2339 exit_server("talloc failed");
2341 watch_state->xconn = req->xconn;
2342 watch_state->mid = req->mid;
2343 watch_state->file_id = lck->data->id;
2344 watch_state->request_time = request_time;
2345 watch_state->timeout = timeout;
2346 watch_state->kernel_oplock = kernel_oplock;
2347 watch_state->lease_type = get_lease_type_from_share_mode(lck->data);
2349 DBG_DEBUG("defering mid %" PRIu64 "\n", req->mid);
2351 watch_req = dbwrap_watched_watch_send(watch_state,
2352 req->sconn->ev_ctx,
2353 lck->data->record,
2354 (struct server_id){0});
2355 if (watch_req == NULL) {
2356 exit_server("Could not watch share mode record");
2358 tevent_req_set_callback(watch_req, defer_open_done, watch_state);
2360 ok = tevent_req_set_endtime(watch_req, req->sconn->ev_ctx, abs_timeout);
2361 if (!ok) {
2362 exit_server("tevent_req_set_endtime failed");
2365 ok = push_deferred_open_message_smb(req, request_time, timeout,
2366 open_rec->id, open_rec);
2367 if (!ok) {
2368 TALLOC_FREE(lck);
2369 exit_server("push_deferred_open_message_smb failed");
2373 static void defer_open_done(struct tevent_req *req)
2375 struct defer_open_state *state = tevent_req_callback_data(
2376 req, struct defer_open_state);
2377 struct tevent_req *watch_req = NULL;
2378 struct share_mode_lock *lck = NULL;
2379 bool schedule_req = true;
2380 struct timeval timeout;
2381 NTSTATUS status;
2382 bool ok;
2384 status = dbwrap_watched_watch_recv(req, talloc_tos(), NULL, NULL,
2385 NULL);
2386 TALLOC_FREE(req);
2387 if (!NT_STATUS_IS_OK(status)) {
2388 DEBUG(5, ("dbwrap_watched_watch_recv returned %s\n",
2389 nt_errstr(status)));
2391 * Even if it failed, retry anyway. TODO: We need a way to
2392 * tell a re-scheduled open about that error.
2394 if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT) &&
2395 state->kernel_oplock)
2398 * If we reschedule but the kernel oplock is still hold
2399 * we would block in the second open as that will be a
2400 * blocking open attempt.
2402 exit_server("Kernel oplock holder didn't "
2403 "respond to break message");
2407 if (state->kernel_oplock) {
2408 lck = get_existing_share_mode_lock(talloc_tos(), state->file_id);
2409 if (lck != NULL) {
2410 uint32_t lease_type;
2412 lease_type = get_lease_type_from_share_mode(lck->data);
2414 if ((lease_type != 0) &&
2415 (lease_type == state->lease_type))
2417 DBG_DEBUG("Unchanged lease: %" PRIu32 "\n",
2418 lease_type);
2419 schedule_req = false;
2424 if (schedule_req) {
2425 DBG_DEBUG("scheduling mid %" PRIu64 "\n", state->mid);
2427 ok = schedule_deferred_open_message_smb(state->xconn,
2428 state->mid);
2429 if (!ok) {
2430 exit_server("schedule_deferred_open_message_smb failed");
2432 TALLOC_FREE(lck);
2433 TALLOC_FREE(state);
2434 return;
2437 DBG_DEBUG("Keep waiting for oplock release for [%s/%s%s] "
2438 "mid: %" PRIu64 "\n",
2439 lck->data->servicepath,
2440 lck->data->base_name,
2441 lck->data->stream_name ? lck->data->stream_name : "",
2442 state->mid);
2444 watch_req = dbwrap_watched_watch_send(state,
2445 state->xconn->ev_ctx,
2446 lck->data->record,
2447 (struct server_id){0});
2448 if (watch_req == NULL) {
2449 exit_server("Could not watch share mode record");
2451 tevent_req_set_callback(watch_req, defer_open_done, state);
2453 timeout = timeval_sum(&state->request_time, &state->timeout);
2454 ok = tevent_req_set_endtime(watch_req, state->xconn->ev_ctx, timeout);
2455 if (!ok) {
2456 exit_server("tevent_req_set_endtime failed");
2459 TALLOC_FREE(lck);
2463 * Reschedule an open for immediate execution
2465 static void retry_open(struct timeval request_time,
2466 struct smb_request *req,
2467 struct file_id id)
2469 struct deferred_open_record *open_rec = NULL;
2470 bool ok;
2472 DBG_DEBUG("request time [%s] mid [%" PRIu64 "] file_id [%s]\n",
2473 timeval_string(talloc_tos(), &request_time, false),
2474 req->mid,
2475 file_id_string_tos(&id));
2477 open_rec = deferred_open_record_create(false, false, id);
2478 if (open_rec == NULL) {
2479 exit_server("talloc failed");
2482 ok = push_deferred_open_message_smb(req,
2483 request_time,
2484 timeval_set(0, 0),
2486 open_rec);
2487 if (!ok) {
2488 exit_server("push_deferred_open_message_smb failed");
2491 ok = schedule_deferred_open_message_smb(req->xconn, req->mid);
2492 if (!ok) {
2493 exit_server("schedule_deferred_open_message_smb failed");
2497 /****************************************************************************
2498 On overwrite open ensure that the attributes match.
2499 ****************************************************************************/
2501 static bool open_match_attributes(connection_struct *conn,
2502 uint32_t old_dos_attr,
2503 uint32_t new_dos_attr,
2504 mode_t existing_unx_mode,
2505 mode_t new_unx_mode,
2506 mode_t *returned_unx_mode)
2508 uint32_t noarch_old_dos_attr, noarch_new_dos_attr;
2510 noarch_old_dos_attr = (old_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
2511 noarch_new_dos_attr = (new_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
2513 if((noarch_old_dos_attr == 0 && noarch_new_dos_attr != 0) ||
2514 (noarch_old_dos_attr != 0 && ((noarch_old_dos_attr & noarch_new_dos_attr) == noarch_old_dos_attr))) {
2515 *returned_unx_mode = new_unx_mode;
2516 } else {
2517 *returned_unx_mode = (mode_t)0;
2520 DEBUG(10,("open_match_attributes: old_dos_attr = 0x%x, "
2521 "existing_unx_mode = 0%o, new_dos_attr = 0x%x "
2522 "returned_unx_mode = 0%o\n",
2523 (unsigned int)old_dos_attr,
2524 (unsigned int)existing_unx_mode,
2525 (unsigned int)new_dos_attr,
2526 (unsigned int)*returned_unx_mode ));
2528 /* If we're mapping SYSTEM and HIDDEN ensure they match. */
2529 if (lp_map_system(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
2530 if ((old_dos_attr & FILE_ATTRIBUTE_SYSTEM) &&
2531 !(new_dos_attr & FILE_ATTRIBUTE_SYSTEM)) {
2532 return False;
2535 if (lp_map_hidden(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
2536 if ((old_dos_attr & FILE_ATTRIBUTE_HIDDEN) &&
2537 !(new_dos_attr & FILE_ATTRIBUTE_HIDDEN)) {
2538 return False;
2541 return True;
2544 /****************************************************************************
2545 Special FCB or DOS processing in the case of a sharing violation.
2546 Try and find a duplicated file handle.
2547 ****************************************************************************/
2549 static NTSTATUS fcb_or_dos_open(struct smb_request *req,
2550 connection_struct *conn,
2551 files_struct *fsp_to_dup_into,
2552 const struct smb_filename *smb_fname,
2553 struct file_id id,
2554 uint16_t file_pid,
2555 uint64_t vuid,
2556 uint32_t access_mask,
2557 uint32_t share_access,
2558 uint32_t create_options)
2560 files_struct *fsp;
2562 DEBUG(5,("fcb_or_dos_open: attempting old open semantics for "
2563 "file %s.\n", smb_fname_str_dbg(smb_fname)));
2565 for(fsp = file_find_di_first(conn->sconn, id); fsp;
2566 fsp = file_find_di_next(fsp)) {
2568 DEBUG(10,("fcb_or_dos_open: checking file %s, fd = %d, "
2569 "vuid = %llu, file_pid = %u, private_options = 0x%x "
2570 "access_mask = 0x%x\n", fsp_str_dbg(fsp),
2571 fsp->fh->fd, (unsigned long long)fsp->vuid,
2572 (unsigned int)fsp->file_pid,
2573 (unsigned int)fsp->fh->private_options,
2574 (unsigned int)fsp->access_mask ));
2576 if (fsp != fsp_to_dup_into &&
2577 fsp->fh->fd != -1 &&
2578 fsp->vuid == vuid &&
2579 fsp->file_pid == file_pid &&
2580 (fsp->fh->private_options & (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS |
2581 NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) &&
2582 (fsp->access_mask & FILE_WRITE_DATA) &&
2583 strequal(fsp->fsp_name->base_name, smb_fname->base_name) &&
2584 strequal(fsp->fsp_name->stream_name,
2585 smb_fname->stream_name)) {
2586 DEBUG(10,("fcb_or_dos_open: file match\n"));
2587 break;
2591 if (!fsp) {
2592 return NT_STATUS_NOT_FOUND;
2595 /* quite an insane set of semantics ... */
2596 if (is_executable(smb_fname->base_name) &&
2597 (fsp->fh->private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS)) {
2598 DEBUG(10,("fcb_or_dos_open: file fail due to is_executable.\n"));
2599 return NT_STATUS_INVALID_PARAMETER;
2602 /* We need to duplicate this fsp. */
2603 return dup_file_fsp(req, fsp, access_mask, share_access,
2604 create_options, fsp_to_dup_into);
2607 static void schedule_defer_open(struct share_mode_lock *lck,
2608 struct file_id id,
2609 struct timeval request_time,
2610 struct smb_request *req,
2611 bool kernel_oplock)
2613 /* This is a relative time, added to the absolute
2614 request_time value to get the absolute timeout time.
2615 Note that if this is the second or greater time we enter
2616 this codepath for this particular request mid then
2617 request_time is left as the absolute time of the *first*
2618 time this request mid was processed. This is what allows
2619 the request to eventually time out. */
2621 struct timeval timeout;
2623 /* Normally the smbd we asked should respond within
2624 * OPLOCK_BREAK_TIMEOUT seconds regardless of whether
2625 * the client did, give twice the timeout as a safety
2626 * measure here in case the other smbd is stuck
2627 * somewhere else. */
2629 timeout = timeval_set(OPLOCK_BREAK_TIMEOUT*2, 0);
2631 if (request_timed_out(request_time, timeout)) {
2632 return;
2635 defer_open(lck, request_time, timeout, req, true, kernel_oplock, id);
2638 /****************************************************************************
2639 Reschedule an open call that went asynchronous.
2640 ****************************************************************************/
2642 static void schedule_async_open_timer(struct tevent_context *ev,
2643 struct tevent_timer *te,
2644 struct timeval current_time,
2645 void *private_data)
2647 exit_server("async open timeout");
2650 static void schedule_async_open(struct timeval request_time,
2651 struct smb_request *req)
2653 struct deferred_open_record *open_rec = NULL;
2654 struct timeval timeout = timeval_set(20, 0);
2655 bool ok;
2657 if (request_timed_out(request_time, timeout)) {
2658 return;
2661 open_rec = deferred_open_record_create(false, true, (struct file_id){0});
2662 if (open_rec == NULL) {
2663 exit_server("deferred_open_record_create failed");
2666 ok = push_deferred_open_message_smb(req, request_time, timeout,
2667 (struct file_id){0}, open_rec);
2668 if (!ok) {
2669 exit_server("push_deferred_open_message_smb failed");
2672 open_rec->te = tevent_add_timer(req->sconn->ev_ctx,
2673 req,
2674 timeval_current_ofs(20, 0),
2675 schedule_async_open_timer,
2676 open_rec);
2677 if (open_rec->te == NULL) {
2678 exit_server("tevent_add_timer failed");
2682 /****************************************************************************
2683 Work out what access_mask to use from what the client sent us.
2684 ****************************************************************************/
2686 static NTSTATUS smbd_calculate_maximum_allowed_access(
2687 connection_struct *conn,
2688 const struct smb_filename *smb_fname,
2689 bool use_privs,
2690 uint32_t *p_access_mask)
2692 struct security_descriptor *sd;
2693 uint32_t access_granted;
2694 NTSTATUS status;
2696 if (!use_privs && (get_current_uid(conn) == (uid_t)0)) {
2697 *p_access_mask |= FILE_GENERIC_ALL;
2698 return NT_STATUS_OK;
2701 status = SMB_VFS_GET_NT_ACL(conn, smb_fname,
2702 (SECINFO_OWNER |
2703 SECINFO_GROUP |
2704 SECINFO_DACL),
2705 talloc_tos(), &sd);
2707 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
2709 * File did not exist
2711 *p_access_mask = FILE_GENERIC_ALL;
2712 return NT_STATUS_OK;
2714 if (!NT_STATUS_IS_OK(status)) {
2715 DEBUG(10,("Could not get acl on file %s: %s\n",
2716 smb_fname_str_dbg(smb_fname),
2717 nt_errstr(status)));
2718 return NT_STATUS_ACCESS_DENIED;
2722 * If we can access the path to this file, by
2723 * default we have FILE_READ_ATTRIBUTES from the
2724 * containing directory. See the section:
2725 * "Algorithm to Check Access to an Existing File"
2726 * in MS-FSA.pdf.
2728 * se_file_access_check()
2729 * also takes care of owner WRITE_DAC and READ_CONTROL.
2731 status = se_file_access_check(sd,
2732 get_current_nttok(conn),
2733 use_privs,
2734 (*p_access_mask & ~FILE_READ_ATTRIBUTES),
2735 &access_granted);
2737 TALLOC_FREE(sd);
2739 if (!NT_STATUS_IS_OK(status)) {
2740 DEBUG(10, ("Access denied on file %s: "
2741 "when calculating maximum access\n",
2742 smb_fname_str_dbg(smb_fname)));
2743 return NT_STATUS_ACCESS_DENIED;
2745 *p_access_mask = (access_granted | FILE_READ_ATTRIBUTES);
2747 if (!(access_granted & DELETE_ACCESS)) {
2748 if (can_delete_file_in_directory(conn, smb_fname)) {
2749 *p_access_mask |= DELETE_ACCESS;
2753 return NT_STATUS_OK;
2756 NTSTATUS smbd_calculate_access_mask(connection_struct *conn,
2757 const struct smb_filename *smb_fname,
2758 bool use_privs,
2759 uint32_t access_mask,
2760 uint32_t *access_mask_out)
2762 NTSTATUS status;
2763 uint32_t orig_access_mask = access_mask;
2764 uint32_t rejected_share_access;
2766 if (access_mask & SEC_MASK_INVALID) {
2767 DBG_DEBUG("access_mask [%8x] contains invalid bits\n",
2768 access_mask);
2769 return NT_STATUS_ACCESS_DENIED;
2773 * Convert GENERIC bits to specific bits.
2776 se_map_generic(&access_mask, &file_generic_mapping);
2778 /* Calculate MAXIMUM_ALLOWED_ACCESS if requested. */
2779 if (access_mask & MAXIMUM_ALLOWED_ACCESS) {
2781 status = smbd_calculate_maximum_allowed_access(
2782 conn, smb_fname, use_privs, &access_mask);
2784 if (!NT_STATUS_IS_OK(status)) {
2785 return status;
2788 access_mask &= conn->share_access;
2791 rejected_share_access = access_mask & ~(conn->share_access);
2793 if (rejected_share_access) {
2794 DEBUG(10, ("smbd_calculate_access_mask: Access denied on "
2795 "file %s: rejected by share access mask[0x%08X] "
2796 "orig[0x%08X] mapped[0x%08X] reject[0x%08X]\n",
2797 smb_fname_str_dbg(smb_fname),
2798 conn->share_access,
2799 orig_access_mask, access_mask,
2800 rejected_share_access));
2801 return NT_STATUS_ACCESS_DENIED;
2804 *access_mask_out = access_mask;
2805 return NT_STATUS_OK;
2808 /****************************************************************************
2809 Remove the deferred open entry under lock.
2810 ****************************************************************************/
2812 /****************************************************************************
2813 Return true if this is a state pointer to an asynchronous create.
2814 ****************************************************************************/
2816 bool is_deferred_open_async(const struct deferred_open_record *rec)
2818 return rec->async_open;
2821 static bool clear_ads(uint32_t create_disposition)
2823 bool ret = false;
2825 switch (create_disposition) {
2826 case FILE_SUPERSEDE:
2827 case FILE_OVERWRITE_IF:
2828 case FILE_OVERWRITE:
2829 ret = true;
2830 break;
2831 default:
2832 break;
2834 return ret;
2837 static int disposition_to_open_flags(uint32_t create_disposition)
2839 int ret = 0;
2842 * Currently we're using FILE_SUPERSEDE as the same as
2843 * FILE_OVERWRITE_IF but they really are
2844 * different. FILE_SUPERSEDE deletes an existing file
2845 * (requiring delete access) then recreates it.
2848 switch (create_disposition) {
2849 case FILE_SUPERSEDE:
2850 case FILE_OVERWRITE_IF:
2852 * If file exists replace/overwrite. If file doesn't
2853 * exist create.
2855 ret = O_CREAT|O_TRUNC;
2856 break;
2858 case FILE_OPEN:
2860 * If file exists open. If file doesn't exist error.
2862 ret = 0;
2863 break;
2865 case FILE_OVERWRITE:
2867 * If file exists overwrite. If file doesn't exist
2868 * error.
2870 ret = O_TRUNC;
2871 break;
2873 case FILE_CREATE:
2875 * If file exists error. If file doesn't exist create.
2877 ret = O_CREAT|O_EXCL;
2878 break;
2880 case FILE_OPEN_IF:
2882 * If file exists open. If file doesn't exist create.
2884 ret = O_CREAT;
2885 break;
2887 return ret;
2890 static int calculate_open_access_flags(uint32_t access_mask,
2891 uint32_t private_flags)
2893 bool need_write, need_read;
2896 * Note that we ignore the append flag as append does not
2897 * mean the same thing under DOS and Unix.
2900 need_write = (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA));
2901 if (!need_write) {
2902 return O_RDONLY;
2905 /* DENY_DOS opens are always underlying read-write on the
2906 file handle, no matter what the requested access mask
2907 says. */
2909 need_read =
2910 ((private_flags & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) ||
2911 access_mask & (FILE_READ_ATTRIBUTES|FILE_READ_DATA|
2912 FILE_READ_EA|FILE_EXECUTE));
2914 if (!need_read) {
2915 return O_WRONLY;
2917 return O_RDWR;
2920 /****************************************************************************
2921 Open a file with a share mode. Passed in an already created files_struct *.
2922 ****************************************************************************/
2924 static NTSTATUS open_file_ntcreate(connection_struct *conn,
2925 struct smb_request *req,
2926 uint32_t access_mask, /* access bits (FILE_READ_DATA etc.) */
2927 uint32_t share_access, /* share constants (FILE_SHARE_READ etc) */
2928 uint32_t create_disposition, /* FILE_OPEN_IF etc. */
2929 uint32_t create_options, /* options such as delete on close. */
2930 uint32_t new_dos_attributes, /* attributes used for new file. */
2931 int oplock_request, /* internal Samba oplock codes. */
2932 struct smb2_lease *lease,
2933 /* Information (FILE_EXISTS etc.) */
2934 uint32_t private_flags, /* Samba specific flags. */
2935 int *pinfo,
2936 files_struct *fsp)
2938 struct smb_filename *smb_fname = fsp->fsp_name;
2939 int flags=0;
2940 int flags2=0;
2941 bool file_existed = VALID_STAT(smb_fname->st);
2942 bool def_acl = False;
2943 bool posix_open = False;
2944 bool new_file_created = False;
2945 bool first_open_attempt = true;
2946 NTSTATUS fsp_open = NT_STATUS_ACCESS_DENIED;
2947 mode_t new_unx_mode = (mode_t)0;
2948 mode_t unx_mode = (mode_t)0;
2949 int info;
2950 uint32_t existing_dos_attributes = 0;
2951 struct timeval request_time = timeval_zero();
2952 struct share_mode_lock *lck = NULL;
2953 uint32_t open_access_mask = access_mask;
2954 NTSTATUS status;
2955 char *parent_dir;
2956 SMB_STRUCT_STAT saved_stat = smb_fname->st;
2957 struct timespec old_write_time;
2958 struct file_id id;
2960 if (conn->printer) {
2962 * Printers are handled completely differently.
2963 * Most of the passed parameters are ignored.
2966 if (pinfo) {
2967 *pinfo = FILE_WAS_CREATED;
2970 DEBUG(10, ("open_file_ntcreate: printer open fname=%s\n",
2971 smb_fname_str_dbg(smb_fname)));
2973 if (!req) {
2974 DEBUG(0,("open_file_ntcreate: printer open without "
2975 "an SMB request!\n"));
2976 return NT_STATUS_INTERNAL_ERROR;
2979 return print_spool_open(fsp, smb_fname->base_name,
2980 req->vuid);
2983 if (!parent_dirname(talloc_tos(), smb_fname->base_name, &parent_dir,
2984 NULL)) {
2985 return NT_STATUS_NO_MEMORY;
2988 if (new_dos_attributes & FILE_FLAG_POSIX_SEMANTICS) {
2989 posix_open = True;
2990 unx_mode = (mode_t)(new_dos_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
2991 new_dos_attributes = 0;
2992 } else {
2993 /* Windows allows a new file to be created and
2994 silently removes a FILE_ATTRIBUTE_DIRECTORY
2995 sent by the client. Do the same. */
2997 new_dos_attributes &= ~FILE_ATTRIBUTE_DIRECTORY;
2999 /* We add FILE_ATTRIBUTE_ARCHIVE to this as this mode is only used if the file is
3000 * created new. */
3001 unx_mode = unix_mode(conn, new_dos_attributes | FILE_ATTRIBUTE_ARCHIVE,
3002 smb_fname, parent_dir);
3005 DEBUG(10, ("open_file_ntcreate: fname=%s, dos_attrs=0x%x "
3006 "access_mask=0x%x share_access=0x%x "
3007 "create_disposition = 0x%x create_options=0x%x "
3008 "unix mode=0%o oplock_request=%d private_flags = 0x%x\n",
3009 smb_fname_str_dbg(smb_fname), new_dos_attributes,
3010 access_mask, share_access, create_disposition,
3011 create_options, (unsigned int)unx_mode, oplock_request,
3012 (unsigned int)private_flags));
3014 if (req == NULL) {
3015 /* Ensure req == NULL means INTERNAL_OPEN_ONLY */
3016 SMB_ASSERT(((oplock_request & INTERNAL_OPEN_ONLY) != 0));
3017 } else {
3018 /* And req != NULL means no INTERNAL_OPEN_ONLY */
3019 SMB_ASSERT(((oplock_request & INTERNAL_OPEN_ONLY) == 0));
3023 * Only non-internal opens can be deferred at all
3026 if (req) {
3027 struct deferred_open_record *open_rec;
3028 if (get_deferred_open_message_state(req,
3029 &request_time,
3030 &open_rec)) {
3031 /* Remember the absolute time of the original
3032 request with this mid. We'll use it later to
3033 see if this has timed out. */
3035 /* If it was an async create retry, the file
3036 didn't exist. */
3038 if (is_deferred_open_async(open_rec)) {
3039 SET_STAT_INVALID(smb_fname->st);
3040 file_existed = false;
3043 /* Ensure we don't reprocess this message. */
3044 remove_deferred_open_message_smb(req->xconn, req->mid);
3046 first_open_attempt = false;
3050 if (!posix_open) {
3051 new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
3052 if (file_existed) {
3054 * Only use strored DOS attributes for checks
3055 * against requested attributes (below via
3056 * open_match_attributes()), cf bug #11992
3057 * for details. -slow
3059 uint32_t attr = 0;
3061 status = SMB_VFS_GET_DOS_ATTRIBUTES(conn, smb_fname, &attr);
3062 if (NT_STATUS_IS_OK(status)) {
3063 existing_dos_attributes = attr;
3068 /* ignore any oplock requests if oplocks are disabled */
3069 if (!lp_oplocks(SNUM(conn)) ||
3070 IS_VETO_OPLOCK_PATH(conn, smb_fname->base_name)) {
3071 /* Mask off everything except the private Samba bits. */
3072 oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
3075 /* this is for OS/2 long file names - say we don't support them */
3076 if (req != NULL && !req->posix_pathnames &&
3077 strstr(smb_fname->base_name,".+,;=[].")) {
3078 /* OS/2 Workplace shell fix may be main code stream in a later
3079 * release. */
3080 DEBUG(5,("open_file_ntcreate: OS/2 long filenames are not "
3081 "supported.\n"));
3082 if (use_nt_status()) {
3083 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3085 return NT_STATUS_DOS(ERRDOS, ERRcannotopen);
3088 switch( create_disposition ) {
3089 case FILE_OPEN:
3090 /* If file exists open. If file doesn't exist error. */
3091 if (!file_existed) {
3092 DEBUG(5,("open_file_ntcreate: FILE_OPEN "
3093 "requested for file %s and file "
3094 "doesn't exist.\n",
3095 smb_fname_str_dbg(smb_fname)));
3096 errno = ENOENT;
3097 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3099 break;
3101 case FILE_OVERWRITE:
3102 /* If file exists overwrite. If file doesn't exist
3103 * error. */
3104 if (!file_existed) {
3105 DEBUG(5,("open_file_ntcreate: FILE_OVERWRITE "
3106 "requested for file %s and file "
3107 "doesn't exist.\n",
3108 smb_fname_str_dbg(smb_fname) ));
3109 errno = ENOENT;
3110 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3112 break;
3114 case FILE_CREATE:
3115 /* If file exists error. If file doesn't exist
3116 * create. */
3117 if (file_existed) {
3118 DEBUG(5,("open_file_ntcreate: FILE_CREATE "
3119 "requested for file %s and file "
3120 "already exists.\n",
3121 smb_fname_str_dbg(smb_fname)));
3122 if (S_ISDIR(smb_fname->st.st_ex_mode)) {
3123 errno = EISDIR;
3124 } else {
3125 errno = EEXIST;
3127 return map_nt_error_from_unix(errno);
3129 break;
3131 case FILE_SUPERSEDE:
3132 case FILE_OVERWRITE_IF:
3133 case FILE_OPEN_IF:
3134 break;
3135 default:
3136 return NT_STATUS_INVALID_PARAMETER;
3139 flags2 = disposition_to_open_flags(create_disposition);
3141 /* We only care about matching attributes on file exists and
3142 * overwrite. */
3144 if (!posix_open && file_existed &&
3145 ((create_disposition == FILE_OVERWRITE) ||
3146 (create_disposition == FILE_OVERWRITE_IF))) {
3147 if (!open_match_attributes(conn, existing_dos_attributes,
3148 new_dos_attributes,
3149 smb_fname->st.st_ex_mode,
3150 unx_mode, &new_unx_mode)) {
3151 DEBUG(5,("open_file_ntcreate: attributes missmatch "
3152 "for file %s (%x %x) (0%o, 0%o)\n",
3153 smb_fname_str_dbg(smb_fname),
3154 existing_dos_attributes,
3155 new_dos_attributes,
3156 (unsigned int)smb_fname->st.st_ex_mode,
3157 (unsigned int)unx_mode ));
3158 errno = EACCES;
3159 return NT_STATUS_ACCESS_DENIED;
3163 status = smbd_calculate_access_mask(conn, smb_fname,
3164 false,
3165 access_mask,
3166 &access_mask);
3167 if (!NT_STATUS_IS_OK(status)) {
3168 DEBUG(10, ("open_file_ntcreate: smbd_calculate_access_mask "
3169 "on file %s returned %s\n",
3170 smb_fname_str_dbg(smb_fname), nt_errstr(status)));
3171 return status;
3174 open_access_mask = access_mask;
3176 if (flags2 & O_TRUNC) {
3177 open_access_mask |= FILE_WRITE_DATA; /* This will cause oplock breaks. */
3180 DEBUG(10, ("open_file_ntcreate: fname=%s, after mapping "
3181 "access_mask=0x%x\n", smb_fname_str_dbg(smb_fname),
3182 access_mask));
3185 * Note that we ignore the append flag as append does not
3186 * mean the same thing under DOS and Unix.
3189 flags = calculate_open_access_flags(access_mask, private_flags);
3192 * Currently we only look at FILE_WRITE_THROUGH for create options.
3195 #if defined(O_SYNC)
3196 if ((create_options & FILE_WRITE_THROUGH) && lp_strict_sync(SNUM(conn))) {
3197 flags2 |= O_SYNC;
3199 #endif /* O_SYNC */
3201 if (posix_open && (access_mask & FILE_APPEND_DATA)) {
3202 flags2 |= O_APPEND;
3205 if (!posix_open && !CAN_WRITE(conn)) {
3207 * We should really return a permission denied error if either
3208 * O_CREAT or O_TRUNC are set, but for compatibility with
3209 * older versions of Samba we just AND them out.
3211 flags2 &= ~(O_CREAT|O_TRUNC);
3214 if (first_open_attempt && lp_kernel_oplocks(SNUM(conn))) {
3216 * With kernel oplocks the open breaking an oplock
3217 * blocks until the oplock holder has given up the
3218 * oplock or closed the file. We prevent this by first
3219 * trying to open the file with O_NONBLOCK (see "man
3220 * fcntl" on Linux). For the second try, triggered by
3221 * an oplock break response, we do not need this
3222 * anymore.
3224 * This is true under the assumption that only Samba
3225 * requests kernel oplocks. Once someone else like
3226 * NFSv4 starts to use that API, we will have to
3227 * modify this by communicating with the NFSv4 server.
3229 flags2 |= O_NONBLOCK;
3233 * Ensure we can't write on a read-only share or file.
3236 if (flags != O_RDONLY && file_existed &&
3237 (!CAN_WRITE(conn) || IS_DOS_READONLY(existing_dos_attributes))) {
3238 DEBUG(5,("open_file_ntcreate: write access requested for "
3239 "file %s on read only %s\n",
3240 smb_fname_str_dbg(smb_fname),
3241 !CAN_WRITE(conn) ? "share" : "file" ));
3242 errno = EACCES;
3243 return NT_STATUS_ACCESS_DENIED;
3246 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
3247 fsp->share_access = share_access;
3248 fsp->fh->private_options = private_flags;
3249 fsp->access_mask = open_access_mask; /* We change this to the
3250 * requested access_mask after
3251 * the open is done. */
3252 if (posix_open) {
3253 fsp->posix_flags |= FSP_POSIX_FLAGS_ALL;
3256 if (timeval_is_zero(&request_time)) {
3257 request_time = fsp->open_time;
3261 * Ensure we pay attention to default ACLs on directories if required.
3264 if ((flags2 & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
3265 (def_acl = directory_has_default_acl(conn, parent_dir))) {
3266 unx_mode = (0777 & lp_create_mask(SNUM(conn)));
3269 DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o, "
3270 "access_mask = 0x%x, open_access_mask = 0x%x\n",
3271 (unsigned int)flags, (unsigned int)flags2,
3272 (unsigned int)unx_mode, (unsigned int)access_mask,
3273 (unsigned int)open_access_mask));
3275 fsp_open = open_file(fsp, conn, req, parent_dir,
3276 flags|flags2, unx_mode, access_mask,
3277 open_access_mask, &new_file_created);
3279 if (NT_STATUS_EQUAL(fsp_open, NT_STATUS_NETWORK_BUSY)) {
3280 bool delay;
3283 * This handles the kernel oplock case:
3285 * the file has an active kernel oplock and the open() returned
3286 * EWOULDBLOCK/EAGAIN which maps to NETWORK_BUSY.
3288 * "Samba locking.tdb oplocks" are handled below after acquiring
3289 * the sharemode lock with get_share_mode_lock().
3291 if (file_existed && S_ISFIFO(fsp->fsp_name->st.st_ex_mode)) {
3292 DEBUG(10, ("FIFO busy\n"));
3293 return NT_STATUS_NETWORK_BUSY;
3295 if (req == NULL) {
3296 DEBUG(10, ("Internal open busy\n"));
3297 return NT_STATUS_NETWORK_BUSY;
3301 * From here on we assume this is an oplock break triggered
3304 lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
3305 if (lck == NULL) {
3306 retry_open(request_time, req, fsp->file_id);
3307 DEBUG(10, ("No share mode lock found after "
3308 "EWOULDBLOCK, retrying sync\n"));
3309 return NT_STATUS_SHARING_VIOLATION;
3312 if (!validate_oplock_types(lck)) {
3313 smb_panic("validate_oplock_types failed");
3316 delay = delay_for_oplock(fsp, 0, lease, lck, false,
3317 create_disposition,
3318 first_open_attempt);
3319 if (delay) {
3320 schedule_defer_open(lck, fsp->file_id, request_time,
3321 req, true);
3322 TALLOC_FREE(lck);
3323 DEBUG(10, ("Sent oplock break request to kernel "
3324 "oplock holder\n"));
3325 return NT_STATUS_SHARING_VIOLATION;
3329 * No oplock from Samba around. Immediately retry with
3330 * a blocking open.
3332 retry_open(request_time, req, fsp->file_id);
3334 TALLOC_FREE(lck);
3335 DEBUG(10, ("No Samba oplock around after EWOULDBLOCK. "
3336 "Retrying sync\n"));
3337 return NT_STATUS_SHARING_VIOLATION;
3340 if (!NT_STATUS_IS_OK(fsp_open)) {
3341 if (NT_STATUS_EQUAL(fsp_open, NT_STATUS_RETRY)) {
3342 schedule_async_open(request_time, req);
3344 return fsp_open;
3347 if (new_file_created) {
3349 * As we atomically create using O_CREAT|O_EXCL,
3350 * then if new_file_created is true, then
3351 * file_existed *MUST* have been false (even
3352 * if the file was previously detected as being
3353 * there).
3355 file_existed = false;
3358 if (file_existed && !check_same_dev_ino(&saved_stat, &smb_fname->st)) {
3360 * The file did exist, but some other (local or NFS)
3361 * process either renamed/unlinked and re-created the
3362 * file with different dev/ino after we walked the path,
3363 * but before we did the open. We could retry the
3364 * open but it's a rare enough case it's easier to
3365 * just fail the open to prevent creating any problems
3366 * in the open file db having the wrong dev/ino key.
3368 fd_close(fsp);
3369 DEBUG(1,("open_file_ntcreate: file %s - dev/ino mismatch. "
3370 "Old (dev=0x%llu, ino =0x%llu). "
3371 "New (dev=0x%llu, ino=0x%llu). Failing open "
3372 " with NT_STATUS_ACCESS_DENIED.\n",
3373 smb_fname_str_dbg(smb_fname),
3374 (unsigned long long)saved_stat.st_ex_dev,
3375 (unsigned long long)saved_stat.st_ex_ino,
3376 (unsigned long long)smb_fname->st.st_ex_dev,
3377 (unsigned long long)smb_fname->st.st_ex_ino));
3378 return NT_STATUS_ACCESS_DENIED;
3381 old_write_time = smb_fname->st.st_ex_mtime;
3384 * Deal with the race condition where two smbd's detect the
3385 * file doesn't exist and do the create at the same time. One
3386 * of them will win and set a share mode, the other (ie. this
3387 * one) should check if the requested share mode for this
3388 * create is allowed.
3392 * Now the file exists and fsp is successfully opened,
3393 * fsp->dev and fsp->inode are valid and should replace the
3394 * dev=0,inode=0 from a non existent file. Spotted by
3395 * Nadav Danieli <nadavd@exanet.com>. JRA.
3398 id = fsp->file_id;
3400 lck = get_share_mode_lock(talloc_tos(), id,
3401 conn->connectpath,
3402 smb_fname, &old_write_time);
3404 if (lck == NULL) {
3405 DEBUG(0, ("open_file_ntcreate: Could not get share "
3406 "mode lock for %s\n",
3407 smb_fname_str_dbg(smb_fname)));
3408 fd_close(fsp);
3409 return NT_STATUS_SHARING_VIOLATION;
3412 /* Get the types we need to examine. */
3413 if (!validate_oplock_types(lck)) {
3414 smb_panic("validate_oplock_types failed");
3417 if (has_delete_on_close(lck, fsp->name_hash)) {
3418 TALLOC_FREE(lck);
3419 fd_close(fsp);
3420 return NT_STATUS_DELETE_PENDING;
3423 status = open_mode_check(conn, lck,
3424 access_mask, share_access);
3426 if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION) ||
3427 (lck->data->num_share_modes > 0)) {
3429 * This comes from ancient times out of open_mode_check. I
3430 * have no clue whether this is still necessary. I can't think
3431 * of a case where this would actually matter further down in
3432 * this function. I leave it here for further investigation
3433 * :-)
3435 file_existed = true;
3438 if (req != NULL) {
3440 * Handle oplocks, deferring the request if delay_for_oplock()
3441 * triggered a break message and we have to wait for the break
3442 * response.
3444 bool delay;
3445 bool sharing_violation = NT_STATUS_EQUAL(
3446 status, NT_STATUS_SHARING_VIOLATION);
3448 delay = delay_for_oplock(fsp, oplock_request, lease, lck,
3449 sharing_violation,
3450 create_disposition,
3451 first_open_attempt);
3452 if (delay) {
3453 schedule_defer_open(lck, fsp->file_id,
3454 request_time, req, false);
3455 TALLOC_FREE(lck);
3456 fd_close(fsp);
3457 return NT_STATUS_SHARING_VIOLATION;
3461 if (!NT_STATUS_IS_OK(status)) {
3462 uint32_t can_access_mask;
3463 bool can_access = True;
3465 SMB_ASSERT(NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION));
3467 /* Check if this can be done with the deny_dos and fcb
3468 * calls. */
3469 if (private_flags &
3470 (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS|
3471 NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) {
3472 if (req == NULL) {
3473 DEBUG(0, ("DOS open without an SMB "
3474 "request!\n"));
3475 TALLOC_FREE(lck);
3476 fd_close(fsp);
3477 return NT_STATUS_INTERNAL_ERROR;
3480 /* Use the client requested access mask here,
3481 * not the one we open with. */
3482 status = fcb_or_dos_open(req,
3483 conn,
3484 fsp,
3485 smb_fname,
3487 req->smbpid,
3488 req->vuid,
3489 access_mask,
3490 share_access,
3491 create_options);
3493 if (NT_STATUS_IS_OK(status)) {
3494 TALLOC_FREE(lck);
3495 if (pinfo) {
3496 *pinfo = FILE_WAS_OPENED;
3498 return NT_STATUS_OK;
3503 * This next line is a subtlety we need for
3504 * MS-Access. If a file open will fail due to share
3505 * permissions and also for security (access) reasons,
3506 * we need to return the access failed error, not the
3507 * share error. We can't open the file due to kernel
3508 * oplock deadlock (it's possible we failed above on
3509 * the open_mode_check()) so use a userspace check.
3512 if (flags & O_RDWR) {
3513 can_access_mask = FILE_READ_DATA|FILE_WRITE_DATA;
3514 } else if (flags & O_WRONLY) {
3515 can_access_mask = FILE_WRITE_DATA;
3516 } else {
3517 can_access_mask = FILE_READ_DATA;
3520 if (((can_access_mask & FILE_WRITE_DATA) &&
3521 !CAN_WRITE(conn)) ||
3522 !NT_STATUS_IS_OK(smbd_check_access_rights(conn,
3523 smb_fname,
3524 false,
3525 can_access_mask))) {
3526 can_access = False;
3530 * If we're returning a share violation, ensure we
3531 * cope with the braindead 1 second delay (SMB1 only).
3534 if (!(oplock_request & INTERNAL_OPEN_ONLY) &&
3535 !conn->sconn->using_smb2 &&
3536 lp_defer_sharing_violations()) {
3537 struct timeval timeout;
3538 int timeout_usecs;
3540 /* this is a hack to speed up torture tests
3541 in 'make test' */
3542 timeout_usecs = lp_parm_int(SNUM(conn),
3543 "smbd","sharedelay",
3544 SHARING_VIOLATION_USEC_WAIT);
3546 /* This is a relative time, added to the absolute
3547 request_time value to get the absolute timeout time.
3548 Note that if this is the second or greater time we enter
3549 this codepath for this particular request mid then
3550 request_time is left as the absolute time of the *first*
3551 time this request mid was processed. This is what allows
3552 the request to eventually time out. */
3554 timeout = timeval_set(0, timeout_usecs);
3556 if (!request_timed_out(request_time, timeout)) {
3557 defer_open(lck, request_time, timeout, req,
3558 false, false, id);
3562 TALLOC_FREE(lck);
3563 fd_close(fsp);
3564 if (can_access) {
3566 * We have detected a sharing violation here
3567 * so return the correct error code
3569 status = NT_STATUS_SHARING_VIOLATION;
3570 } else {
3571 status = NT_STATUS_ACCESS_DENIED;
3573 return status;
3576 /* Should we atomically (to the client at least) truncate ? */
3577 if ((!new_file_created) &&
3578 (flags2 & O_TRUNC) &&
3579 (!S_ISFIFO(fsp->fsp_name->st.st_ex_mode))) {
3580 int ret;
3582 ret = vfs_set_filelen(fsp, 0);
3583 if (ret != 0) {
3584 status = map_nt_error_from_unix(errno);
3585 TALLOC_FREE(lck);
3586 fd_close(fsp);
3587 return status;
3592 * We have the share entry *locked*.....
3595 /* Delete streams if create_disposition requires it */
3596 if (!new_file_created && clear_ads(create_disposition) &&
3597 !is_ntfs_stream_smb_fname(smb_fname)) {
3598 status = delete_all_streams(conn, smb_fname);
3599 if (!NT_STATUS_IS_OK(status)) {
3600 TALLOC_FREE(lck);
3601 fd_close(fsp);
3602 return status;
3606 /* note that we ignore failure for the following. It is
3607 basically a hack for NFS, and NFS will never set one of
3608 these only read them. Nobody but Samba can ever set a deny
3609 mode and we have already checked our more authoritative
3610 locking database for permission to set this deny mode. If
3611 the kernel refuses the operations then the kernel is wrong.
3612 note that GPFS supports it as well - jmcd */
3614 if (fsp->fh->fd != -1 && lp_kernel_share_modes(SNUM(conn))) {
3615 int ret_flock;
3617 * Beware: streams implementing VFS modules may
3618 * implement streams in a way that fsp will have the
3619 * basefile open in the fsp fd, so lacking a distinct
3620 * fd for the stream kernel_flock will apply on the
3621 * basefile which is wrong. The actual check is
3622 * deffered to the VFS module implementing the
3623 * kernel_flock call.
3625 ret_flock = SMB_VFS_KERNEL_FLOCK(fsp, share_access, access_mask);
3626 if(ret_flock == -1 ){
3628 TALLOC_FREE(lck);
3629 fd_close(fsp);
3631 return NT_STATUS_SHARING_VIOLATION;
3634 fsp->kernel_share_modes_taken = true;
3638 * At this point onwards, we can guarantee that the share entry
3639 * is locked, whether we created the file or not, and that the
3640 * deny mode is compatible with all current opens.
3644 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
3645 * but we don't have to store this - just ignore it on access check.
3647 if (conn->sconn->using_smb2) {
3649 * SMB2 doesn't return it (according to Microsoft tests).
3650 * Test Case: TestSuite_ScenarioNo009GrantedAccessTestS0
3651 * File created with access = 0x7 (Read, Write, Delete)
3652 * Query Info on file returns 0x87 (Read, Write, Delete, Read Attributes)
3654 fsp->access_mask = access_mask;
3655 } else {
3656 /* But SMB1 does. */
3657 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
3660 if (file_existed) {
3662 * stat opens on existing files don't get oplocks.
3663 * They can get leases.
3665 * Note that we check for stat open on the *open_access_mask*,
3666 * i.e. the access mask we actually used to do the open,
3667 * not the one the client asked for (which is in
3668 * fsp->access_mask). This is due to the fact that
3669 * FILE_OVERWRITE and FILE_OVERWRITE_IF add in O_TRUNC,
3670 * which adds FILE_WRITE_DATA to open_access_mask.
3672 if (is_stat_open(open_access_mask) && lease == NULL) {
3673 oplock_request = NO_OPLOCK;
3677 if (new_file_created) {
3678 info = FILE_WAS_CREATED;
3679 } else {
3680 if (flags2 & O_TRUNC) {
3681 info = FILE_WAS_OVERWRITTEN;
3682 } else {
3683 info = FILE_WAS_OPENED;
3687 if (pinfo) {
3688 *pinfo = info;
3692 * Setup the oplock info in both the shared memory and
3693 * file structs.
3695 status = grant_fsp_oplock_type(req, fsp, lck, oplock_request, lease);
3696 if (!NT_STATUS_IS_OK(status)) {
3697 TALLOC_FREE(lck);
3698 fd_close(fsp);
3699 return status;
3702 /* Handle strange delete on close create semantics. */
3703 if (create_options & FILE_DELETE_ON_CLOSE) {
3705 status = can_set_delete_on_close(fsp, new_dos_attributes);
3707 if (!NT_STATUS_IS_OK(status)) {
3708 /* Remember to delete the mode we just added. */
3709 del_share_mode(lck, fsp);
3710 TALLOC_FREE(lck);
3711 fd_close(fsp);
3712 return status;
3714 /* Note that here we set the *inital* delete on close flag,
3715 not the regular one. The magic gets handled in close. */
3716 fsp->initial_delete_on_close = True;
3719 if (info != FILE_WAS_OPENED) {
3720 /* Overwritten files should be initially set as archive */
3721 if ((info == FILE_WAS_OVERWRITTEN && lp_map_archive(SNUM(conn))) ||
3722 lp_store_dos_attributes(SNUM(conn))) {
3723 if (!posix_open) {
3724 if (file_set_dosmode(conn, smb_fname,
3725 new_dos_attributes | FILE_ATTRIBUTE_ARCHIVE,
3726 parent_dir, true) == 0) {
3727 unx_mode = smb_fname->st.st_ex_mode;
3733 /* Determine sparse flag. */
3734 if (posix_open) {
3735 /* POSIX opens are sparse by default. */
3736 fsp->is_sparse = true;
3737 } else {
3738 fsp->is_sparse = (file_existed &&
3739 (existing_dos_attributes & FILE_ATTRIBUTE_SPARSE));
3743 * Take care of inherited ACLs on created files - if default ACL not
3744 * selected.
3747 if (!posix_open && new_file_created && !def_acl) {
3749 int saved_errno = errno; /* We might get ENOSYS in the next
3750 * call.. */
3752 if (SMB_VFS_FCHMOD_ACL(fsp, unx_mode) == -1 &&
3753 errno == ENOSYS) {
3754 errno = saved_errno; /* Ignore ENOSYS */
3757 } else if (new_unx_mode) {
3759 int ret = -1;
3761 /* Attributes need changing. File already existed. */
3764 int saved_errno = errno; /* We might get ENOSYS in the
3765 * next call.. */
3766 ret = SMB_VFS_FCHMOD_ACL(fsp, new_unx_mode);
3768 if (ret == -1 && errno == ENOSYS) {
3769 errno = saved_errno; /* Ignore ENOSYS */
3770 } else {
3771 DEBUG(5, ("open_file_ntcreate: reset "
3772 "attributes of file %s to 0%o\n",
3773 smb_fname_str_dbg(smb_fname),
3774 (unsigned int)new_unx_mode));
3775 ret = 0; /* Don't do the fchmod below. */
3779 if ((ret == -1) &&
3780 (SMB_VFS_FCHMOD(fsp, new_unx_mode) == -1))
3781 DEBUG(5, ("open_file_ntcreate: failed to reset "
3782 "attributes of file %s to 0%o\n",
3783 smb_fname_str_dbg(smb_fname),
3784 (unsigned int)new_unx_mode));
3789 * Deal with other opens having a modified write time.
3791 struct timespec write_time = get_share_mode_write_time(lck);
3793 if (!null_timespec(write_time)) {
3794 update_stat_ex_mtime(&fsp->fsp_name->st, write_time);
3798 TALLOC_FREE(lck);
3800 return NT_STATUS_OK;
3803 static NTSTATUS mkdir_internal(connection_struct *conn,
3804 struct smb_filename *smb_dname,
3805 uint32_t file_attributes)
3807 mode_t mode;
3808 char *parent_dir = NULL;
3809 NTSTATUS status;
3810 bool posix_open = false;
3811 bool need_re_stat = false;
3812 uint32_t access_mask = SEC_DIR_ADD_SUBDIR;
3814 if (!CAN_WRITE(conn) || (access_mask & ~(conn->share_access))) {
3815 DEBUG(5,("mkdir_internal: failing share access "
3816 "%s\n", lp_servicename(talloc_tos(), SNUM(conn))));
3817 return NT_STATUS_ACCESS_DENIED;
3820 if (!parent_dirname(talloc_tos(), smb_dname->base_name, &parent_dir,
3821 NULL)) {
3822 return NT_STATUS_NO_MEMORY;
3825 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
3826 posix_open = true;
3827 mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
3828 } else {
3829 mode = unix_mode(conn, FILE_ATTRIBUTE_DIRECTORY, smb_dname, parent_dir);
3832 status = check_parent_access(conn,
3833 smb_dname,
3834 access_mask);
3835 if(!NT_STATUS_IS_OK(status)) {
3836 DEBUG(5,("mkdir_internal: check_parent_access "
3837 "on directory %s for path %s returned %s\n",
3838 parent_dir,
3839 smb_dname->base_name,
3840 nt_errstr(status) ));
3841 return status;
3844 if (SMB_VFS_MKDIR(conn, smb_dname, mode) != 0) {
3845 return map_nt_error_from_unix(errno);
3848 /* Ensure we're checking for a symlink here.... */
3849 /* We don't want to get caught by a symlink racer. */
3851 if (SMB_VFS_LSTAT(conn, smb_dname) == -1) {
3852 DEBUG(2, ("Could not stat directory '%s' just created: %s\n",
3853 smb_fname_str_dbg(smb_dname), strerror(errno)));
3854 return map_nt_error_from_unix(errno);
3857 if (!S_ISDIR(smb_dname->st.st_ex_mode)) {
3858 DEBUG(0, ("Directory '%s' just created is not a directory !\n",
3859 smb_fname_str_dbg(smb_dname)));
3860 return NT_STATUS_NOT_A_DIRECTORY;
3863 if (lp_store_dos_attributes(SNUM(conn))) {
3864 if (!posix_open) {
3865 file_set_dosmode(conn, smb_dname,
3866 file_attributes | FILE_ATTRIBUTE_DIRECTORY,
3867 parent_dir, true);
3871 if (lp_inherit_permissions(SNUM(conn))) {
3872 inherit_access_posix_acl(conn, parent_dir,
3873 smb_dname->base_name, mode);
3874 need_re_stat = true;
3877 if (!posix_open) {
3879 * Check if high bits should have been set,
3880 * then (if bits are missing): add them.
3881 * Consider bits automagically set by UNIX, i.e. SGID bit from parent
3882 * dir.
3884 if ((mode & ~(S_IRWXU|S_IRWXG|S_IRWXO)) &&
3885 (mode & ~smb_dname->st.st_ex_mode)) {
3886 SMB_VFS_CHMOD(conn, smb_dname,
3887 (smb_dname->st.st_ex_mode |
3888 (mode & ~smb_dname->st.st_ex_mode)));
3889 need_re_stat = true;
3893 /* Change the owner if required. */
3894 if (lp_inherit_owner(SNUM(conn)) != INHERIT_OWNER_NO) {
3895 change_dir_owner_to_parent(conn, parent_dir,
3896 smb_dname->base_name,
3897 &smb_dname->st);
3898 need_re_stat = true;
3901 if (need_re_stat) {
3902 if (SMB_VFS_LSTAT(conn, smb_dname) == -1) {
3903 DEBUG(2, ("Could not stat directory '%s' just created: %s\n",
3904 smb_fname_str_dbg(smb_dname), strerror(errno)));
3905 return map_nt_error_from_unix(errno);
3909 notify_fname(conn, NOTIFY_ACTION_ADDED, FILE_NOTIFY_CHANGE_DIR_NAME,
3910 smb_dname->base_name);
3912 return NT_STATUS_OK;
3915 /****************************************************************************
3916 Open a directory from an NT SMB call.
3917 ****************************************************************************/
3919 static NTSTATUS open_directory(connection_struct *conn,
3920 struct smb_request *req,
3921 struct smb_filename *smb_dname,
3922 uint32_t access_mask,
3923 uint32_t share_access,
3924 uint32_t create_disposition,
3925 uint32_t create_options,
3926 uint32_t file_attributes,
3927 int *pinfo,
3928 files_struct **result)
3930 files_struct *fsp = NULL;
3931 bool dir_existed = VALID_STAT(smb_dname->st) ? True : False;
3932 struct share_mode_lock *lck = NULL;
3933 NTSTATUS status;
3934 struct timespec mtimespec;
3935 int info = 0;
3936 bool ok;
3938 if (is_ntfs_stream_smb_fname(smb_dname)) {
3939 DEBUG(2, ("open_directory: %s is a stream name!\n",
3940 smb_fname_str_dbg(smb_dname)));
3941 return NT_STATUS_NOT_A_DIRECTORY;
3944 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS)) {
3945 /* Ensure we have a directory attribute. */
3946 file_attributes |= FILE_ATTRIBUTE_DIRECTORY;
3949 DEBUG(5,("open_directory: opening directory %s, access_mask = 0x%x, "
3950 "share_access = 0x%x create_options = 0x%x, "
3951 "create_disposition = 0x%x, file_attributes = 0x%x\n",
3952 smb_fname_str_dbg(smb_dname),
3953 (unsigned int)access_mask,
3954 (unsigned int)share_access,
3955 (unsigned int)create_options,
3956 (unsigned int)create_disposition,
3957 (unsigned int)file_attributes));
3959 status = smbd_calculate_access_mask(conn, smb_dname, false,
3960 access_mask, &access_mask);
3961 if (!NT_STATUS_IS_OK(status)) {
3962 DEBUG(10, ("open_directory: smbd_calculate_access_mask "
3963 "on file %s returned %s\n",
3964 smb_fname_str_dbg(smb_dname),
3965 nt_errstr(status)));
3966 return status;
3969 if ((access_mask & SEC_FLAG_SYSTEM_SECURITY) &&
3970 !security_token_has_privilege(get_current_nttok(conn),
3971 SEC_PRIV_SECURITY)) {
3972 DEBUG(10, ("open_directory: open on %s "
3973 "failed - SEC_FLAG_SYSTEM_SECURITY denied.\n",
3974 smb_fname_str_dbg(smb_dname)));
3975 return NT_STATUS_PRIVILEGE_NOT_HELD;
3978 switch( create_disposition ) {
3979 case FILE_OPEN:
3981 if (!dir_existed) {
3982 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3985 info = FILE_WAS_OPENED;
3986 break;
3988 case FILE_CREATE:
3990 /* If directory exists error. If directory doesn't
3991 * exist create. */
3993 if (dir_existed) {
3994 status = NT_STATUS_OBJECT_NAME_COLLISION;
3995 DEBUG(2, ("open_directory: unable to create "
3996 "%s. Error was %s\n",
3997 smb_fname_str_dbg(smb_dname),
3998 nt_errstr(status)));
3999 return status;
4002 status = mkdir_internal(conn, smb_dname,
4003 file_attributes);
4005 if (!NT_STATUS_IS_OK(status)) {
4006 DEBUG(2, ("open_directory: unable to create "
4007 "%s. Error was %s\n",
4008 smb_fname_str_dbg(smb_dname),
4009 nt_errstr(status)));
4010 return status;
4013 info = FILE_WAS_CREATED;
4014 break;
4016 case FILE_OPEN_IF:
4018 * If directory exists open. If directory doesn't
4019 * exist create.
4022 if (dir_existed) {
4023 status = NT_STATUS_OK;
4024 info = FILE_WAS_OPENED;
4025 } else {
4026 status = mkdir_internal(conn, smb_dname,
4027 file_attributes);
4029 if (NT_STATUS_IS_OK(status)) {
4030 info = FILE_WAS_CREATED;
4031 } else {
4032 /* Cope with create race. */
4033 if (!NT_STATUS_EQUAL(status,
4034 NT_STATUS_OBJECT_NAME_COLLISION)) {
4035 DEBUG(2, ("open_directory: unable to create "
4036 "%s. Error was %s\n",
4037 smb_fname_str_dbg(smb_dname),
4038 nt_errstr(status)));
4039 return status;
4043 * If mkdir_internal() returned
4044 * NT_STATUS_OBJECT_NAME_COLLISION
4045 * we still must lstat the path.
4048 if (SMB_VFS_LSTAT(conn, smb_dname)
4049 == -1) {
4050 DEBUG(2, ("Could not stat "
4051 "directory '%s' just "
4052 "opened: %s\n",
4053 smb_fname_str_dbg(
4054 smb_dname),
4055 strerror(errno)));
4056 return map_nt_error_from_unix(
4057 errno);
4060 info = FILE_WAS_OPENED;
4064 break;
4066 case FILE_SUPERSEDE:
4067 case FILE_OVERWRITE:
4068 case FILE_OVERWRITE_IF:
4069 default:
4070 DEBUG(5,("open_directory: invalid create_disposition "
4071 "0x%x for directory %s\n",
4072 (unsigned int)create_disposition,
4073 smb_fname_str_dbg(smb_dname)));
4074 return NT_STATUS_INVALID_PARAMETER;
4077 if(!S_ISDIR(smb_dname->st.st_ex_mode)) {
4078 DEBUG(5,("open_directory: %s is not a directory !\n",
4079 smb_fname_str_dbg(smb_dname)));
4080 return NT_STATUS_NOT_A_DIRECTORY;
4083 if (info == FILE_WAS_OPENED) {
4084 status = smbd_check_access_rights(conn,
4085 smb_dname,
4086 false,
4087 access_mask);
4088 if (!NT_STATUS_IS_OK(status)) {
4089 DEBUG(10, ("open_directory: smbd_check_access_rights on "
4090 "file %s failed with %s\n",
4091 smb_fname_str_dbg(smb_dname),
4092 nt_errstr(status)));
4093 return status;
4097 status = file_new(req, conn, &fsp);
4098 if(!NT_STATUS_IS_OK(status)) {
4099 return status;
4103 * Setup the files_struct for it.
4106 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_dname->st);
4107 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
4108 fsp->file_pid = req ? req->smbpid : 0;
4109 fsp->can_lock = False;
4110 fsp->can_read = False;
4111 fsp->can_write = False;
4113 fsp->share_access = share_access;
4114 fsp->fh->private_options = 0;
4116 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
4118 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
4119 fsp->print_file = NULL;
4120 fsp->modified = False;
4121 fsp->oplock_type = NO_OPLOCK;
4122 fsp->sent_oplock_break = NO_BREAK_SENT;
4123 fsp->is_directory = True;
4124 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
4125 fsp->posix_flags |= FSP_POSIX_FLAGS_ALL;
4127 status = fsp_set_smb_fname(fsp, smb_dname);
4128 if (!NT_STATUS_IS_OK(status)) {
4129 file_free(req, fsp);
4130 return status;
4133 /* Don't store old timestamps for directory
4134 handles in the internal database. We don't
4135 update them in there if new objects
4136 are creaded in the directory. Currently
4137 we only update timestamps on file writes.
4138 See bug #9870.
4140 ZERO_STRUCT(mtimespec);
4142 if (access_mask & (FILE_LIST_DIRECTORY|
4143 FILE_ADD_FILE|
4144 FILE_ADD_SUBDIRECTORY|
4145 FILE_TRAVERSE|
4146 DELETE_ACCESS|
4147 FILE_DELETE_CHILD)) {
4148 #ifdef O_DIRECTORY
4149 status = fd_open(conn, fsp, O_RDONLY|O_DIRECTORY, 0);
4150 #else
4151 /* POSIX allows us to open a directory with O_RDONLY. */
4152 status = fd_open(conn, fsp, O_RDONLY, 0);
4153 #endif
4154 if (!NT_STATUS_IS_OK(status)) {
4155 DEBUG(5, ("open_directory: Could not open fd for "
4156 "%s (%s)\n",
4157 smb_fname_str_dbg(smb_dname),
4158 nt_errstr(status)));
4159 file_free(req, fsp);
4160 return status;
4162 } else {
4163 fsp->fh->fd = -1;
4164 DEBUG(10, ("Not opening Directory %s\n",
4165 smb_fname_str_dbg(smb_dname)));
4168 status = vfs_stat_fsp(fsp);
4169 if (!NT_STATUS_IS_OK(status)) {
4170 fd_close(fsp);
4171 file_free(req, fsp);
4172 return status;
4175 if(!S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
4176 DEBUG(5,("open_directory: %s is not a directory !\n",
4177 smb_fname_str_dbg(smb_dname)));
4178 fd_close(fsp);
4179 file_free(req, fsp);
4180 return NT_STATUS_NOT_A_DIRECTORY;
4183 /* Ensure there was no race condition. We need to check
4184 * dev/inode but not permissions, as these can change
4185 * legitimately */
4186 if (!check_same_dev_ino(&smb_dname->st, &fsp->fsp_name->st)) {
4187 DEBUG(5,("open_directory: stat struct differs for "
4188 "directory %s.\n",
4189 smb_fname_str_dbg(smb_dname)));
4190 fd_close(fsp);
4191 file_free(req, fsp);
4192 return NT_STATUS_ACCESS_DENIED;
4195 lck = get_share_mode_lock(talloc_tos(), fsp->file_id,
4196 conn->connectpath, smb_dname,
4197 &mtimespec);
4199 if (lck == NULL) {
4200 DEBUG(0, ("open_directory: Could not get share mode lock for "
4201 "%s\n", smb_fname_str_dbg(smb_dname)));
4202 fd_close(fsp);
4203 file_free(req, fsp);
4204 return NT_STATUS_SHARING_VIOLATION;
4207 if (has_delete_on_close(lck, fsp->name_hash)) {
4208 TALLOC_FREE(lck);
4209 fd_close(fsp);
4210 file_free(req, fsp);
4211 return NT_STATUS_DELETE_PENDING;
4214 status = open_mode_check(conn, lck,
4215 access_mask, share_access);
4217 if (!NT_STATUS_IS_OK(status)) {
4218 TALLOC_FREE(lck);
4219 fd_close(fsp);
4220 file_free(req, fsp);
4221 return status;
4224 ok = set_share_mode(lck, fsp, get_current_uid(conn),
4225 req ? req->mid : 0, NO_OPLOCK,
4226 UINT32_MAX);
4227 if (!ok) {
4228 TALLOC_FREE(lck);
4229 fd_close(fsp);
4230 file_free(req, fsp);
4231 return NT_STATUS_NO_MEMORY;
4234 /* For directories the delete on close bit at open time seems
4235 always to be honored on close... See test 19 in Samba4 BASE-DELETE. */
4236 if (create_options & FILE_DELETE_ON_CLOSE) {
4237 status = can_set_delete_on_close(fsp, 0);
4238 if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
4239 del_share_mode(lck, fsp);
4240 TALLOC_FREE(lck);
4241 fd_close(fsp);
4242 file_free(req, fsp);
4243 return status;
4246 if (NT_STATUS_IS_OK(status)) {
4247 /* Note that here we set the *inital* delete on close flag,
4248 not the regular one. The magic gets handled in close. */
4249 fsp->initial_delete_on_close = True;
4255 * Deal with other opens having a modified write time. Is this
4256 * possible for directories?
4258 struct timespec write_time = get_share_mode_write_time(lck);
4260 if (!null_timespec(write_time)) {
4261 update_stat_ex_mtime(&fsp->fsp_name->st, write_time);
4265 TALLOC_FREE(lck);
4267 if (pinfo) {
4268 *pinfo = info;
4271 *result = fsp;
4272 return NT_STATUS_OK;
4275 NTSTATUS create_directory(connection_struct *conn, struct smb_request *req,
4276 struct smb_filename *smb_dname)
4278 NTSTATUS status;
4279 files_struct *fsp;
4281 status = SMB_VFS_CREATE_FILE(
4282 conn, /* conn */
4283 req, /* req */
4284 0, /* root_dir_fid */
4285 smb_dname, /* fname */
4286 FILE_READ_ATTRIBUTES, /* access_mask */
4287 FILE_SHARE_NONE, /* share_access */
4288 FILE_CREATE, /* create_disposition*/
4289 FILE_DIRECTORY_FILE, /* create_options */
4290 FILE_ATTRIBUTE_DIRECTORY, /* file_attributes */
4291 0, /* oplock_request */
4292 NULL, /* lease */
4293 0, /* allocation_size */
4294 0, /* private_flags */
4295 NULL, /* sd */
4296 NULL, /* ea_list */
4297 &fsp, /* result */
4298 NULL, /* pinfo */
4299 NULL, NULL); /* create context */
4301 if (NT_STATUS_IS_OK(status)) {
4302 close_file(req, fsp, NORMAL_CLOSE);
4305 return status;
4308 /****************************************************************************
4309 Receive notification that one of our open files has been renamed by another
4310 smbd process.
4311 ****************************************************************************/
4313 void msg_file_was_renamed(struct messaging_context *msg,
4314 void *private_data,
4315 uint32_t msg_type,
4316 struct server_id server_id,
4317 DATA_BLOB *data)
4319 files_struct *fsp;
4320 char *frm = (char *)data->data;
4321 struct file_id id;
4322 const char *sharepath;
4323 const char *base_name;
4324 const char *stream_name;
4325 struct smb_filename *smb_fname = NULL;
4326 size_t sp_len, bn_len;
4327 NTSTATUS status;
4328 struct smbd_server_connection *sconn =
4329 talloc_get_type_abort(private_data,
4330 struct smbd_server_connection);
4332 if (data->data == NULL
4333 || data->length < MSG_FILE_RENAMED_MIN_SIZE + 2) {
4334 DEBUG(0, ("msg_file_was_renamed: Got invalid msg len %d\n",
4335 (int)data->length));
4336 return;
4339 /* Unpack the message. */
4340 pull_file_id_24(frm, &id);
4341 sharepath = &frm[24];
4342 sp_len = strlen(sharepath);
4343 base_name = sharepath + sp_len + 1;
4344 bn_len = strlen(base_name);
4345 stream_name = sharepath + sp_len + 1 + bn_len + 1;
4347 /* stream_name must always be NULL if there is no stream. */
4348 if (stream_name[0] == '\0') {
4349 stream_name = NULL;
4352 smb_fname = synthetic_smb_fname(talloc_tos(),
4353 base_name,
4354 stream_name,
4355 NULL,
4357 if (smb_fname == NULL) {
4358 return;
4361 DEBUG(10,("msg_file_was_renamed: Got rename message for sharepath %s, new name %s, "
4362 "file_id %s\n",
4363 sharepath, smb_fname_str_dbg(smb_fname),
4364 file_id_string_tos(&id)));
4366 for(fsp = file_find_di_first(sconn, id); fsp;
4367 fsp = file_find_di_next(fsp)) {
4368 if (memcmp(fsp->conn->connectpath, sharepath, sp_len) == 0) {
4370 DEBUG(10,("msg_file_was_renamed: renaming file %s from %s -> %s\n",
4371 fsp_fnum_dbg(fsp), fsp_str_dbg(fsp),
4372 smb_fname_str_dbg(smb_fname)));
4373 status = fsp_set_smb_fname(fsp, smb_fname);
4374 if (!NT_STATUS_IS_OK(status)) {
4375 goto out;
4377 } else {
4378 /* TODO. JRA. */
4379 /* Now we have the complete path we can work out if this is
4380 actually within this share and adjust newname accordingly. */
4381 DEBUG(10,("msg_file_was_renamed: share mismatch (sharepath %s "
4382 "not sharepath %s) "
4383 "%s from %s -> %s\n",
4384 fsp->conn->connectpath,
4385 sharepath,
4386 fsp_fnum_dbg(fsp),
4387 fsp_str_dbg(fsp),
4388 smb_fname_str_dbg(smb_fname)));
4391 out:
4392 TALLOC_FREE(smb_fname);
4393 return;
4397 * If a main file is opened for delete, all streams need to be checked for
4398 * !FILE_SHARE_DELETE. Do this by opening with DELETE_ACCESS.
4399 * If that works, delete them all by setting the delete on close and close.
4402 static NTSTATUS open_streams_for_delete(connection_struct *conn,
4403 const struct smb_filename *smb_fname)
4405 struct stream_struct *stream_info = NULL;
4406 files_struct **streams = NULL;
4407 int i;
4408 unsigned int num_streams = 0;
4409 TALLOC_CTX *frame = talloc_stackframe();
4410 NTSTATUS status;
4412 status = vfs_streaminfo(conn, NULL, smb_fname, talloc_tos(),
4413 &num_streams, &stream_info);
4415 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
4416 || NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
4417 DEBUG(10, ("no streams around\n"));
4418 TALLOC_FREE(frame);
4419 return NT_STATUS_OK;
4422 if (!NT_STATUS_IS_OK(status)) {
4423 DEBUG(10, ("vfs_streaminfo failed: %s\n",
4424 nt_errstr(status)));
4425 goto fail;
4428 DEBUG(10, ("open_streams_for_delete found %d streams\n",
4429 num_streams));
4431 if (num_streams == 0) {
4432 TALLOC_FREE(frame);
4433 return NT_STATUS_OK;
4436 streams = talloc_array(talloc_tos(), files_struct *, num_streams);
4437 if (streams == NULL) {
4438 DEBUG(0, ("talloc failed\n"));
4439 status = NT_STATUS_NO_MEMORY;
4440 goto fail;
4443 for (i=0; i<num_streams; i++) {
4444 struct smb_filename *smb_fname_cp;
4446 if (strequal(stream_info[i].name, "::$DATA")) {
4447 streams[i] = NULL;
4448 continue;
4451 smb_fname_cp = synthetic_smb_fname(talloc_tos(),
4452 smb_fname->base_name,
4453 stream_info[i].name,
4454 NULL,
4455 (smb_fname->flags &
4456 ~SMB_FILENAME_POSIX_PATH));
4457 if (smb_fname_cp == NULL) {
4458 status = NT_STATUS_NO_MEMORY;
4459 goto fail;
4462 if (SMB_VFS_STAT(conn, smb_fname_cp) == -1) {
4463 DEBUG(10, ("Unable to stat stream: %s\n",
4464 smb_fname_str_dbg(smb_fname_cp)));
4467 status = SMB_VFS_CREATE_FILE(
4468 conn, /* conn */
4469 NULL, /* req */
4470 0, /* root_dir_fid */
4471 smb_fname_cp, /* fname */
4472 DELETE_ACCESS, /* access_mask */
4473 (FILE_SHARE_READ | /* share_access */
4474 FILE_SHARE_WRITE | FILE_SHARE_DELETE),
4475 FILE_OPEN, /* create_disposition*/
4476 0, /* create_options */
4477 FILE_ATTRIBUTE_NORMAL, /* file_attributes */
4478 0, /* oplock_request */
4479 NULL, /* lease */
4480 0, /* allocation_size */
4481 NTCREATEX_OPTIONS_PRIVATE_STREAM_DELETE, /* private_flags */
4482 NULL, /* sd */
4483 NULL, /* ea_list */
4484 &streams[i], /* result */
4485 NULL, /* pinfo */
4486 NULL, NULL); /* create context */
4488 if (!NT_STATUS_IS_OK(status)) {
4489 DEBUG(10, ("Could not open stream %s: %s\n",
4490 smb_fname_str_dbg(smb_fname_cp),
4491 nt_errstr(status)));
4493 TALLOC_FREE(smb_fname_cp);
4494 break;
4496 TALLOC_FREE(smb_fname_cp);
4500 * don't touch the variable "status" beyond this point :-)
4503 for (i -= 1 ; i >= 0; i--) {
4504 if (streams[i] == NULL) {
4505 continue;
4508 DEBUG(10, ("Closing stream # %d, %s\n", i,
4509 fsp_str_dbg(streams[i])));
4510 close_file(NULL, streams[i], NORMAL_CLOSE);
4513 fail:
4514 TALLOC_FREE(frame);
4515 return status;
4518 /*********************************************************************
4519 Create a default ACL by inheriting from the parent. If no inheritance
4520 from the parent available, don't set anything. This will leave the actual
4521 permissions the new file or directory already got from the filesystem
4522 as the NT ACL when read.
4523 *********************************************************************/
4525 static NTSTATUS inherit_new_acl(files_struct *fsp)
4527 TALLOC_CTX *frame = talloc_stackframe();
4528 char *parent_name = NULL;
4529 struct security_descriptor *parent_desc = NULL;
4530 NTSTATUS status = NT_STATUS_OK;
4531 struct security_descriptor *psd = NULL;
4532 const struct dom_sid *owner_sid = NULL;
4533 const struct dom_sid *group_sid = NULL;
4534 uint32_t security_info_sent = (SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL);
4535 struct security_token *token = fsp->conn->session_info->security_token;
4536 bool inherit_owner =
4537 (lp_inherit_owner(SNUM(fsp->conn)) == INHERIT_OWNER_WINDOWS_AND_UNIX);
4538 bool inheritable_components = false;
4539 bool try_builtin_administrators = false;
4540 const struct dom_sid *BA_U_sid = NULL;
4541 const struct dom_sid *BA_G_sid = NULL;
4542 bool try_system = false;
4543 const struct dom_sid *SY_U_sid = NULL;
4544 const struct dom_sid *SY_G_sid = NULL;
4545 size_t size = 0;
4546 struct smb_filename *parent_smb_fname = NULL;
4548 if (!parent_dirname(frame, fsp->fsp_name->base_name, &parent_name, NULL)) {
4549 TALLOC_FREE(frame);
4550 return NT_STATUS_NO_MEMORY;
4552 parent_smb_fname = synthetic_smb_fname(talloc_tos(),
4553 parent_name,
4554 NULL,
4555 NULL,
4556 fsp->fsp_name->flags);
4558 if (parent_smb_fname == NULL) {
4559 TALLOC_FREE(frame);
4560 return NT_STATUS_NO_MEMORY;
4563 status = SMB_VFS_GET_NT_ACL(fsp->conn,
4564 parent_smb_fname,
4565 (SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL),
4566 frame,
4567 &parent_desc);
4568 if (!NT_STATUS_IS_OK(status)) {
4569 TALLOC_FREE(frame);
4570 return status;
4573 inheritable_components = sd_has_inheritable_components(parent_desc,
4574 fsp->is_directory);
4576 if (!inheritable_components && !inherit_owner) {
4577 TALLOC_FREE(frame);
4578 /* Nothing to inherit and not setting owner. */
4579 return NT_STATUS_OK;
4582 /* Create an inherited descriptor from the parent. */
4584 if (DEBUGLEVEL >= 10) {
4585 DEBUG(10,("inherit_new_acl: parent acl for %s is:\n",
4586 fsp_str_dbg(fsp) ));
4587 NDR_PRINT_DEBUG(security_descriptor, parent_desc);
4590 /* Inherit from parent descriptor if "inherit owner" set. */
4591 if (inherit_owner) {
4592 owner_sid = parent_desc->owner_sid;
4593 group_sid = parent_desc->group_sid;
4596 if (owner_sid == NULL) {
4597 if (security_token_has_builtin_administrators(token)) {
4598 try_builtin_administrators = true;
4599 } else if (security_token_is_system(token)) {
4600 try_builtin_administrators = true;
4601 try_system = true;
4605 if (group_sid == NULL &&
4606 token->num_sids == PRIMARY_GROUP_SID_INDEX)
4608 if (security_token_is_system(token)) {
4609 try_builtin_administrators = true;
4610 try_system = true;
4614 if (try_builtin_administrators) {
4615 struct unixid ids;
4616 bool ok;
4618 ZERO_STRUCT(ids);
4619 ok = sids_to_unixids(&global_sid_Builtin_Administrators, 1, &ids);
4620 if (ok) {
4621 switch (ids.type) {
4622 case ID_TYPE_BOTH:
4623 BA_U_sid = &global_sid_Builtin_Administrators;
4624 BA_G_sid = &global_sid_Builtin_Administrators;
4625 break;
4626 case ID_TYPE_UID:
4627 BA_U_sid = &global_sid_Builtin_Administrators;
4628 break;
4629 case ID_TYPE_GID:
4630 BA_G_sid = &global_sid_Builtin_Administrators;
4631 break;
4632 default:
4633 break;
4638 if (try_system) {
4639 struct unixid ids;
4640 bool ok;
4642 ZERO_STRUCT(ids);
4643 ok = sids_to_unixids(&global_sid_System, 1, &ids);
4644 if (ok) {
4645 switch (ids.type) {
4646 case ID_TYPE_BOTH:
4647 SY_U_sid = &global_sid_System;
4648 SY_G_sid = &global_sid_System;
4649 break;
4650 case ID_TYPE_UID:
4651 SY_U_sid = &global_sid_System;
4652 break;
4653 case ID_TYPE_GID:
4654 SY_G_sid = &global_sid_System;
4655 break;
4656 default:
4657 break;
4662 if (owner_sid == NULL) {
4663 owner_sid = BA_U_sid;
4666 if (owner_sid == NULL) {
4667 owner_sid = SY_U_sid;
4670 if (group_sid == NULL) {
4671 group_sid = SY_G_sid;
4674 if (try_system && group_sid == NULL) {
4675 group_sid = BA_G_sid;
4678 if (owner_sid == NULL) {
4679 owner_sid = &token->sids[PRIMARY_USER_SID_INDEX];
4681 if (group_sid == NULL) {
4682 if (token->num_sids == PRIMARY_GROUP_SID_INDEX) {
4683 group_sid = &token->sids[PRIMARY_USER_SID_INDEX];
4684 } else {
4685 group_sid = &token->sids[PRIMARY_GROUP_SID_INDEX];
4689 status = se_create_child_secdesc(frame,
4690 &psd,
4691 &size,
4692 parent_desc,
4693 owner_sid,
4694 group_sid,
4695 fsp->is_directory);
4696 if (!NT_STATUS_IS_OK(status)) {
4697 TALLOC_FREE(frame);
4698 return status;
4701 /* If inheritable_components == false,
4702 se_create_child_secdesc()
4703 creates a security desriptor with a NULL dacl
4704 entry, but with SEC_DESC_DACL_PRESENT. We need
4705 to remove that flag. */
4707 if (!inheritable_components) {
4708 security_info_sent &= ~SECINFO_DACL;
4709 psd->type &= ~SEC_DESC_DACL_PRESENT;
4712 if (DEBUGLEVEL >= 10) {
4713 DEBUG(10,("inherit_new_acl: child acl for %s is:\n",
4714 fsp_str_dbg(fsp) ));
4715 NDR_PRINT_DEBUG(security_descriptor, psd);
4718 if (inherit_owner) {
4719 /* We need to be root to force this. */
4720 become_root();
4722 status = SMB_VFS_FSET_NT_ACL(fsp,
4723 security_info_sent,
4724 psd);
4725 if (inherit_owner) {
4726 unbecome_root();
4728 TALLOC_FREE(frame);
4729 return status;
4733 * If we already have a lease, it must match the new file id. [MS-SMB2]
4734 * 3.3.5.9.8 speaks about INVALID_PARAMETER if an already used lease key is
4735 * used for a different file name.
4738 struct lease_match_state {
4739 /* Input parameters. */
4740 TALLOC_CTX *mem_ctx;
4741 const char *servicepath;
4742 const struct smb_filename *fname;
4743 bool file_existed;
4744 struct file_id id;
4745 /* Return parameters. */
4746 uint32_t num_file_ids;
4747 struct file_id *ids;
4748 NTSTATUS match_status;
4751 /*************************************************************
4752 File doesn't exist but this lease key+guid is already in use.
4754 This is only allowable in the dynamic share case where the
4755 service path must be different.
4757 There is a small race condition here in the multi-connection
4758 case where a client sends two create calls on different connections,
4759 where the file doesn't exist and one smbd creates the leases_db
4760 entry first, but this will get fixed by the multichannel cleanup
4761 when all identical client_guids get handled by a single smbd.
4762 **************************************************************/
4764 static void lease_match_parser_new_file(
4765 uint32_t num_files,
4766 const struct leases_db_file *files,
4767 struct lease_match_state *state)
4769 uint32_t i;
4771 for (i = 0; i < num_files; i++) {
4772 const struct leases_db_file *f = &files[i];
4773 if (strequal(state->servicepath, f->servicepath)) {
4774 state->match_status = NT_STATUS_INVALID_PARAMETER;
4775 return;
4779 /* Dynamic share case. Break leases on all other files. */
4780 state->match_status = leases_db_copy_file_ids(state->mem_ctx,
4781 num_files,
4782 files,
4783 &state->ids);
4784 if (!NT_STATUS_IS_OK(state->match_status)) {
4785 return;
4788 state->num_file_ids = num_files;
4789 state->match_status = NT_STATUS_OPLOCK_NOT_GRANTED;
4790 return;
4793 static void lease_match_parser(
4794 uint32_t num_files,
4795 const struct leases_db_file *files,
4796 void *private_data)
4798 struct lease_match_state *state =
4799 (struct lease_match_state *)private_data;
4800 uint32_t i;
4802 if (!state->file_existed) {
4804 * Deal with name mismatch or
4805 * possible dynamic share case separately
4806 * to make code clearer.
4808 lease_match_parser_new_file(num_files,
4809 files,
4810 state);
4811 return;
4814 /* File existed. */
4815 state->match_status = NT_STATUS_OK;
4817 for (i = 0; i < num_files; i++) {
4818 const struct leases_db_file *f = &files[i];
4820 /* Everything should be the same. */
4821 if (!file_id_equal(&state->id, &f->id)) {
4822 /* This should catch all dynamic share cases. */
4823 state->match_status = NT_STATUS_OPLOCK_NOT_GRANTED;
4824 break;
4826 if (!strequal(f->servicepath, state->servicepath)) {
4827 state->match_status = NT_STATUS_INVALID_PARAMETER;
4828 break;
4830 if (!strequal(f->base_name, state->fname->base_name)) {
4831 state->match_status = NT_STATUS_INVALID_PARAMETER;
4832 break;
4834 if (!strequal(f->stream_name, state->fname->stream_name)) {
4835 state->match_status = NT_STATUS_INVALID_PARAMETER;
4836 break;
4840 if (NT_STATUS_IS_OK(state->match_status)) {
4842 * Common case - just opening another handle on a
4843 * file on a non-dynamic share.
4845 return;
4848 if (NT_STATUS_EQUAL(state->match_status, NT_STATUS_INVALID_PARAMETER)) {
4849 /* Mismatched path. Error back to client. */
4850 return;
4854 * File id mismatch. Dynamic share case NT_STATUS_OPLOCK_NOT_GRANTED.
4855 * Don't allow leases.
4858 state->match_status = leases_db_copy_file_ids(state->mem_ctx,
4859 num_files,
4860 files,
4861 &state->ids);
4862 if (!NT_STATUS_IS_OK(state->match_status)) {
4863 return;
4866 state->num_file_ids = num_files;
4867 state->match_status = NT_STATUS_OPLOCK_NOT_GRANTED;
4868 return;
4871 static NTSTATUS lease_match(connection_struct *conn,
4872 struct smb_request *req,
4873 struct smb2_lease_key *lease_key,
4874 const char *servicepath,
4875 const struct smb_filename *fname,
4876 uint16_t *p_version,
4877 uint16_t *p_epoch)
4879 struct smbd_server_connection *sconn = req->sconn;
4880 TALLOC_CTX *tos = talloc_tos();
4881 struct lease_match_state state = {
4882 .mem_ctx = tos,
4883 .servicepath = servicepath,
4884 .fname = fname,
4885 .match_status = NT_STATUS_OK
4887 uint32_t i;
4888 NTSTATUS status;
4890 state.file_existed = VALID_STAT(fname->st);
4891 if (state.file_existed) {
4892 state.id = vfs_file_id_from_sbuf(conn, &fname->st);
4893 } else {
4894 memset(&state.id, '\0', sizeof(state.id));
4897 status = leases_db_parse(&sconn->client->connections->smb2.client.guid,
4898 lease_key, lease_match_parser, &state);
4899 if (!NT_STATUS_IS_OK(status)) {
4901 * Not found or error means okay: We can make the lease pass
4903 return NT_STATUS_OK;
4905 if (!NT_STATUS_EQUAL(state.match_status, NT_STATUS_OPLOCK_NOT_GRANTED)) {
4907 * Anything but NT_STATUS_OPLOCK_NOT_GRANTED, let the caller
4908 * deal with it.
4910 return state.match_status;
4913 /* We have to break all existing leases. */
4914 for (i = 0; i < state.num_file_ids; i++) {
4915 struct share_mode_lock *lck;
4916 struct share_mode_data *d;
4917 uint32_t j;
4919 if (file_id_equal(&state.ids[i], &state.id)) {
4920 /* Don't need to break our own file. */
4921 continue;
4924 lck = get_existing_share_mode_lock(talloc_tos(), state.ids[i]);
4925 if (lck == NULL) {
4926 /* Race condition - file already closed. */
4927 continue;
4929 d = lck->data;
4930 for (j=0; j<d->num_share_modes; j++) {
4931 struct share_mode_entry *e = &d->share_modes[j];
4932 uint32_t e_lease_type = get_lease_type(d, e);
4933 struct share_mode_lease *l = NULL;
4935 if (share_mode_stale_pid(d, j)) {
4936 continue;
4939 if (e->op_type == LEASE_OPLOCK) {
4940 l = &lck->data->leases[e->lease_idx];
4941 if (!smb2_lease_key_equal(&l->lease_key,
4942 lease_key)) {
4943 continue;
4945 *p_epoch = l->epoch;
4946 *p_version = l->lease_version;
4949 if (e_lease_type == SMB2_LEASE_NONE) {
4950 continue;
4953 send_break_message(conn->sconn->msg_ctx, e,
4954 SMB2_LEASE_NONE);
4957 * Windows 7 and 8 lease clients
4958 * are broken in that they will not
4959 * respond to lease break requests
4960 * whilst waiting for an outstanding
4961 * open request on that lease handle
4962 * on the same TCP connection, due
4963 * to holding an internal inode lock.
4965 * This means we can't reschedule
4966 * ourselves here, but must return
4967 * from the create.
4969 * Work around:
4971 * Send the breaks and then return
4972 * SMB2_LEASE_NONE in the lease handle
4973 * to cause them to acknowledge the
4974 * lease break. Consulatation with
4975 * Microsoft engineering confirmed
4976 * this approach is safe.
4980 TALLOC_FREE(lck);
4983 * Ensure we don't grant anything more so we
4984 * never upgrade.
4986 return NT_STATUS_OPLOCK_NOT_GRANTED;
4990 * Wrapper around open_file_ntcreate and open_directory
4993 static NTSTATUS create_file_unixpath(connection_struct *conn,
4994 struct smb_request *req,
4995 struct smb_filename *smb_fname,
4996 uint32_t access_mask,
4997 uint32_t share_access,
4998 uint32_t create_disposition,
4999 uint32_t create_options,
5000 uint32_t file_attributes,
5001 uint32_t oplock_request,
5002 struct smb2_lease *lease,
5003 uint64_t allocation_size,
5004 uint32_t private_flags,
5005 struct security_descriptor *sd,
5006 struct ea_list *ea_list,
5008 files_struct **result,
5009 int *pinfo)
5011 int info = FILE_WAS_OPENED;
5012 files_struct *base_fsp = NULL;
5013 files_struct *fsp = NULL;
5014 NTSTATUS status;
5016 DEBUG(10,("create_file_unixpath: access_mask = 0x%x "
5017 "file_attributes = 0x%x, share_access = 0x%x, "
5018 "create_disposition = 0x%x create_options = 0x%x "
5019 "oplock_request = 0x%x private_flags = 0x%x "
5020 "ea_list = 0x%p, sd = 0x%p, "
5021 "fname = %s\n",
5022 (unsigned int)access_mask,
5023 (unsigned int)file_attributes,
5024 (unsigned int)share_access,
5025 (unsigned int)create_disposition,
5026 (unsigned int)create_options,
5027 (unsigned int)oplock_request,
5028 (unsigned int)private_flags,
5029 ea_list, sd, smb_fname_str_dbg(smb_fname)));
5031 if (create_options & FILE_OPEN_BY_FILE_ID) {
5032 status = NT_STATUS_NOT_SUPPORTED;
5033 goto fail;
5036 if (create_options & NTCREATEX_OPTIONS_INVALID_PARAM_MASK) {
5037 status = NT_STATUS_INVALID_PARAMETER;
5038 goto fail;
5041 if (req == NULL) {
5042 oplock_request |= INTERNAL_OPEN_ONLY;
5045 if (lease != NULL) {
5046 uint16_t epoch = lease->lease_epoch;
5047 uint16_t version = lease->lease_version;
5048 status = lease_match(conn,
5049 req,
5050 &lease->lease_key,
5051 conn->connectpath,
5052 smb_fname,
5053 &version,
5054 &epoch);
5055 if (NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) {
5056 /* Dynamic share file. No leases and update epoch... */
5057 lease->lease_state = SMB2_LEASE_NONE;
5058 lease->lease_epoch = epoch;
5059 lease->lease_version = version;
5060 } else if (!NT_STATUS_IS_OK(status)) {
5061 goto fail;
5065 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
5066 && (access_mask & DELETE_ACCESS)
5067 && !is_ntfs_stream_smb_fname(smb_fname)) {
5069 * We can't open a file with DELETE access if any of the
5070 * streams is open without FILE_SHARE_DELETE
5072 status = open_streams_for_delete(conn, smb_fname);
5074 if (!NT_STATUS_IS_OK(status)) {
5075 goto fail;
5079 if ((access_mask & SEC_FLAG_SYSTEM_SECURITY) &&
5080 !security_token_has_privilege(get_current_nttok(conn),
5081 SEC_PRIV_SECURITY)) {
5082 DEBUG(10, ("create_file_unixpath: open on %s "
5083 "failed - SEC_FLAG_SYSTEM_SECURITY denied.\n",
5084 smb_fname_str_dbg(smb_fname)));
5085 status = NT_STATUS_PRIVILEGE_NOT_HELD;
5086 goto fail;
5089 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
5090 && is_ntfs_stream_smb_fname(smb_fname)
5091 && (!(private_flags & NTCREATEX_OPTIONS_PRIVATE_STREAM_DELETE))) {
5092 uint32_t base_create_disposition;
5093 struct smb_filename *smb_fname_base = NULL;
5095 if (create_options & FILE_DIRECTORY_FILE) {
5096 status = NT_STATUS_NOT_A_DIRECTORY;
5097 goto fail;
5100 switch (create_disposition) {
5101 case FILE_OPEN:
5102 base_create_disposition = FILE_OPEN;
5103 break;
5104 default:
5105 base_create_disposition = FILE_OPEN_IF;
5106 break;
5109 /* Create an smb_filename with stream_name == NULL. */
5110 smb_fname_base = synthetic_smb_fname(talloc_tos(),
5111 smb_fname->base_name,
5112 NULL,
5113 NULL,
5114 smb_fname->flags);
5115 if (smb_fname_base == NULL) {
5116 status = NT_STATUS_NO_MEMORY;
5117 goto fail;
5120 if (SMB_VFS_STAT(conn, smb_fname_base) == -1) {
5121 DEBUG(10, ("Unable to stat stream: %s\n",
5122 smb_fname_str_dbg(smb_fname_base)));
5123 } else {
5125 * https://bugzilla.samba.org/show_bug.cgi?id=10229
5126 * We need to check if the requested access mask
5127 * could be used to open the underlying file (if
5128 * it existed), as we're passing in zero for the
5129 * access mask to the base filename.
5131 status = check_base_file_access(conn,
5132 smb_fname_base,
5133 access_mask);
5135 if (!NT_STATUS_IS_OK(status)) {
5136 DEBUG(10, ("Permission check "
5137 "for base %s failed: "
5138 "%s\n", smb_fname->base_name,
5139 nt_errstr(status)));
5140 goto fail;
5144 /* Open the base file. */
5145 status = create_file_unixpath(conn, NULL, smb_fname_base, 0,
5146 FILE_SHARE_READ
5147 | FILE_SHARE_WRITE
5148 | FILE_SHARE_DELETE,
5149 base_create_disposition,
5150 0, 0, 0, NULL, 0, 0, NULL, NULL,
5151 &base_fsp, NULL);
5152 TALLOC_FREE(smb_fname_base);
5154 if (!NT_STATUS_IS_OK(status)) {
5155 DEBUG(10, ("create_file_unixpath for base %s failed: "
5156 "%s\n", smb_fname->base_name,
5157 nt_errstr(status)));
5158 goto fail;
5160 /* we don't need the low level fd */
5161 fd_close(base_fsp);
5165 * If it's a request for a directory open, deal with it separately.
5168 if (create_options & FILE_DIRECTORY_FILE) {
5170 if (create_options & FILE_NON_DIRECTORY_FILE) {
5171 status = NT_STATUS_INVALID_PARAMETER;
5172 goto fail;
5175 /* Can't open a temp directory. IFS kit test. */
5176 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
5177 (file_attributes & FILE_ATTRIBUTE_TEMPORARY)) {
5178 status = NT_STATUS_INVALID_PARAMETER;
5179 goto fail;
5183 * We will get a create directory here if the Win32
5184 * app specified a security descriptor in the
5185 * CreateDirectory() call.
5188 oplock_request = 0;
5189 status = open_directory(
5190 conn, req, smb_fname, access_mask, share_access,
5191 create_disposition, create_options, file_attributes,
5192 &info, &fsp);
5193 } else {
5196 * Ordinary file case.
5199 status = file_new(req, conn, &fsp);
5200 if(!NT_STATUS_IS_OK(status)) {
5201 goto fail;
5204 status = fsp_set_smb_fname(fsp, smb_fname);
5205 if (!NT_STATUS_IS_OK(status)) {
5206 goto fail;
5209 if (base_fsp) {
5211 * We're opening the stream element of a
5212 * base_fsp we already opened. Set up the
5213 * base_fsp pointer.
5215 fsp->base_fsp = base_fsp;
5218 if (allocation_size) {
5219 fsp->initial_allocation_size = smb_roundup(fsp->conn,
5220 allocation_size);
5223 status = open_file_ntcreate(conn,
5224 req,
5225 access_mask,
5226 share_access,
5227 create_disposition,
5228 create_options,
5229 file_attributes,
5230 oplock_request,
5231 lease,
5232 private_flags,
5233 &info,
5234 fsp);
5236 if(!NT_STATUS_IS_OK(status)) {
5237 file_free(req, fsp);
5238 fsp = NULL;
5241 if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
5243 /* A stream open never opens a directory */
5245 if (base_fsp) {
5246 status = NT_STATUS_FILE_IS_A_DIRECTORY;
5247 goto fail;
5251 * Fail the open if it was explicitly a non-directory
5252 * file.
5255 if (create_options & FILE_NON_DIRECTORY_FILE) {
5256 status = NT_STATUS_FILE_IS_A_DIRECTORY;
5257 goto fail;
5260 oplock_request = 0;
5261 status = open_directory(
5262 conn, req, smb_fname, access_mask,
5263 share_access, create_disposition,
5264 create_options, file_attributes,
5265 &info, &fsp);
5269 if (!NT_STATUS_IS_OK(status)) {
5270 goto fail;
5273 fsp->base_fsp = base_fsp;
5275 if ((ea_list != NULL) &&
5276 ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN))) {
5277 status = set_ea(conn, fsp, fsp->fsp_name, ea_list);
5278 if (!NT_STATUS_IS_OK(status)) {
5279 goto fail;
5283 if (!fsp->is_directory && S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
5284 status = NT_STATUS_ACCESS_DENIED;
5285 goto fail;
5288 /* Save the requested allocation size. */
5289 if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
5290 if ((allocation_size > fsp->fsp_name->st.st_ex_size)
5291 && !(fsp->is_directory))
5293 fsp->initial_allocation_size = smb_roundup(
5294 fsp->conn, allocation_size);
5295 if (vfs_allocate_file_space(
5296 fsp, fsp->initial_allocation_size) == -1) {
5297 status = NT_STATUS_DISK_FULL;
5298 goto fail;
5300 } else {
5301 fsp->initial_allocation_size = smb_roundup(
5302 fsp->conn, (uint64_t)fsp->fsp_name->st.st_ex_size);
5304 } else {
5305 fsp->initial_allocation_size = 0;
5308 if ((info == FILE_WAS_CREATED) && lp_nt_acl_support(SNUM(conn)) &&
5309 fsp->base_fsp == NULL) {
5310 if (sd != NULL) {
5312 * According to the MS documentation, the only time the security
5313 * descriptor is applied to the opened file is iff we *created* the
5314 * file; an existing file stays the same.
5316 * Also, it seems (from observation) that you can open the file with
5317 * any access mask but you can still write the sd. We need to override
5318 * the granted access before we call set_sd
5319 * Patch for bug #2242 from Tom Lackemann <cessnatomny@yahoo.com>.
5322 uint32_t sec_info_sent;
5323 uint32_t saved_access_mask = fsp->access_mask;
5325 sec_info_sent = get_sec_info(sd);
5327 fsp->access_mask = FILE_GENERIC_ALL;
5329 if (sec_info_sent & (SECINFO_OWNER|
5330 SECINFO_GROUP|
5331 SECINFO_DACL|
5332 SECINFO_SACL)) {
5333 status = set_sd(fsp, sd, sec_info_sent);
5336 fsp->access_mask = saved_access_mask;
5338 if (!NT_STATUS_IS_OK(status)) {
5339 goto fail;
5341 } else if (lp_inherit_acls(SNUM(conn))) {
5342 /* Inherit from parent. Errors here are not fatal. */
5343 status = inherit_new_acl(fsp);
5344 if (!NT_STATUS_IS_OK(status)) {
5345 DEBUG(10,("inherit_new_acl: failed for %s with %s\n",
5346 fsp_str_dbg(fsp),
5347 nt_errstr(status) ));
5352 if ((conn->fs_capabilities & FILE_FILE_COMPRESSION)
5353 && (create_options & FILE_NO_COMPRESSION)
5354 && (info == FILE_WAS_CREATED)) {
5355 status = SMB_VFS_SET_COMPRESSION(conn, fsp, fsp,
5356 COMPRESSION_FORMAT_NONE);
5357 if (!NT_STATUS_IS_OK(status)) {
5358 DEBUG(1, ("failed to disable compression: %s\n",
5359 nt_errstr(status)));
5363 DEBUG(10, ("create_file_unixpath: info=%d\n", info));
5365 *result = fsp;
5366 if (pinfo != NULL) {
5367 *pinfo = info;
5370 smb_fname->st = fsp->fsp_name->st;
5372 return NT_STATUS_OK;
5374 fail:
5375 DEBUG(10, ("create_file_unixpath: %s\n", nt_errstr(status)));
5377 if (fsp != NULL) {
5378 if (base_fsp && fsp->base_fsp == base_fsp) {
5380 * The close_file below will close
5381 * fsp->base_fsp.
5383 base_fsp = NULL;
5385 close_file(req, fsp, ERROR_CLOSE);
5386 fsp = NULL;
5388 if (base_fsp != NULL) {
5389 close_file(req, base_fsp, ERROR_CLOSE);
5390 base_fsp = NULL;
5392 return status;
5396 * Calculate the full path name given a relative fid.
5398 NTSTATUS get_relative_fid_filename(connection_struct *conn,
5399 struct smb_request *req,
5400 uint16_t root_dir_fid,
5401 const struct smb_filename *smb_fname,
5402 struct smb_filename **smb_fname_out)
5404 files_struct *dir_fsp;
5405 char *parent_fname = NULL;
5406 char *new_base_name = NULL;
5407 uint32_t ucf_flags = ((req != NULL && req->posix_pathnames) ?
5408 UCF_POSIX_PATHNAMES : 0);
5409 NTSTATUS status;
5411 if (root_dir_fid == 0 || !smb_fname) {
5412 status = NT_STATUS_INTERNAL_ERROR;
5413 goto out;
5416 dir_fsp = file_fsp(req, root_dir_fid);
5418 if (dir_fsp == NULL) {
5419 status = NT_STATUS_INVALID_HANDLE;
5420 goto out;
5423 if (is_ntfs_stream_smb_fname(dir_fsp->fsp_name)) {
5424 status = NT_STATUS_INVALID_HANDLE;
5425 goto out;
5428 if (!dir_fsp->is_directory) {
5431 * Check to see if this is a mac fork of some kind.
5434 if ((conn->fs_capabilities & FILE_NAMED_STREAMS) &&
5435 is_ntfs_stream_smb_fname(smb_fname)) {
5436 status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
5437 goto out;
5441 we need to handle the case when we get a
5442 relative open relative to a file and the
5443 pathname is blank - this is a reopen!
5444 (hint from demyn plantenberg)
5447 status = NT_STATUS_INVALID_HANDLE;
5448 goto out;
5451 if (ISDOT(dir_fsp->fsp_name->base_name)) {
5453 * We're at the toplevel dir, the final file name
5454 * must not contain ./, as this is filtered out
5455 * normally by srvstr_get_path and unix_convert
5456 * explicitly rejects paths containing ./.
5458 parent_fname = talloc_strdup(talloc_tos(), "");
5459 if (parent_fname == NULL) {
5460 status = NT_STATUS_NO_MEMORY;
5461 goto out;
5463 } else {
5464 size_t dir_name_len = strlen(dir_fsp->fsp_name->base_name);
5467 * Copy in the base directory name.
5470 parent_fname = talloc_array(talloc_tos(), char,
5471 dir_name_len+2);
5472 if (parent_fname == NULL) {
5473 status = NT_STATUS_NO_MEMORY;
5474 goto out;
5476 memcpy(parent_fname, dir_fsp->fsp_name->base_name,
5477 dir_name_len+1);
5480 * Ensure it ends in a '/'.
5481 * We used TALLOC_SIZE +2 to add space for the '/'.
5484 if(dir_name_len
5485 && (parent_fname[dir_name_len-1] != '\\')
5486 && (parent_fname[dir_name_len-1] != '/')) {
5487 parent_fname[dir_name_len] = '/';
5488 parent_fname[dir_name_len+1] = '\0';
5492 new_base_name = talloc_asprintf(talloc_tos(), "%s%s", parent_fname,
5493 smb_fname->base_name);
5494 if (new_base_name == NULL) {
5495 status = NT_STATUS_NO_MEMORY;
5496 goto out;
5499 status = filename_convert(req,
5500 conn,
5501 req->flags2 & FLAGS2_DFS_PATHNAMES,
5502 new_base_name,
5503 ucf_flags,
5504 NULL,
5505 smb_fname_out);
5506 if (!NT_STATUS_IS_OK(status)) {
5507 goto out;
5510 out:
5511 TALLOC_FREE(parent_fname);
5512 TALLOC_FREE(new_base_name);
5513 return status;
5516 NTSTATUS create_file_default(connection_struct *conn,
5517 struct smb_request *req,
5518 uint16_t root_dir_fid,
5519 struct smb_filename *smb_fname,
5520 uint32_t access_mask,
5521 uint32_t share_access,
5522 uint32_t create_disposition,
5523 uint32_t create_options,
5524 uint32_t file_attributes,
5525 uint32_t oplock_request,
5526 struct smb2_lease *lease,
5527 uint64_t allocation_size,
5528 uint32_t private_flags,
5529 struct security_descriptor *sd,
5530 struct ea_list *ea_list,
5531 files_struct **result,
5532 int *pinfo,
5533 const struct smb2_create_blobs *in_context_blobs,
5534 struct smb2_create_blobs *out_context_blobs)
5536 int info = FILE_WAS_OPENED;
5537 files_struct *fsp = NULL;
5538 NTSTATUS status;
5539 bool stream_name = false;
5541 DEBUG(10,("create_file: access_mask = 0x%x "
5542 "file_attributes = 0x%x, share_access = 0x%x, "
5543 "create_disposition = 0x%x create_options = 0x%x "
5544 "oplock_request = 0x%x "
5545 "private_flags = 0x%x "
5546 "root_dir_fid = 0x%x, ea_list = 0x%p, sd = 0x%p, "
5547 "fname = %s\n",
5548 (unsigned int)access_mask,
5549 (unsigned int)file_attributes,
5550 (unsigned int)share_access,
5551 (unsigned int)create_disposition,
5552 (unsigned int)create_options,
5553 (unsigned int)oplock_request,
5554 (unsigned int)private_flags,
5555 (unsigned int)root_dir_fid,
5556 ea_list, sd, smb_fname_str_dbg(smb_fname)));
5559 * Calculate the filename from the root_dir_if if necessary.
5562 if (root_dir_fid != 0) {
5563 struct smb_filename *smb_fname_out = NULL;
5564 status = get_relative_fid_filename(conn, req, root_dir_fid,
5565 smb_fname, &smb_fname_out);
5566 if (!NT_STATUS_IS_OK(status)) {
5567 goto fail;
5569 smb_fname = smb_fname_out;
5573 * Check to see if this is a mac fork of some kind.
5576 stream_name = is_ntfs_stream_smb_fname(smb_fname);
5577 if (stream_name) {
5578 enum FAKE_FILE_TYPE fake_file_type;
5580 fake_file_type = is_fake_file(smb_fname);
5582 if (fake_file_type != FAKE_FILE_TYPE_NONE) {
5585 * Here we go! support for changing the disk quotas
5586 * --metze
5588 * We need to fake up to open this MAGIC QUOTA file
5589 * and return a valid FID.
5591 * w2k close this file directly after openening xp
5592 * also tries a QUERY_FILE_INFO on the file and then
5593 * close it
5595 status = open_fake_file(req, conn, req->vuid,
5596 fake_file_type, smb_fname,
5597 access_mask, &fsp);
5598 if (!NT_STATUS_IS_OK(status)) {
5599 goto fail;
5602 ZERO_STRUCT(smb_fname->st);
5603 goto done;
5606 if (!(conn->fs_capabilities & FILE_NAMED_STREAMS)) {
5607 status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
5608 goto fail;
5612 if (is_ntfs_default_stream_smb_fname(smb_fname)) {
5613 int ret;
5614 smb_fname->stream_name = NULL;
5615 /* We have to handle this error here. */
5616 if (create_options & FILE_DIRECTORY_FILE) {
5617 status = NT_STATUS_NOT_A_DIRECTORY;
5618 goto fail;
5620 if (req != NULL && req->posix_pathnames) {
5621 ret = SMB_VFS_LSTAT(conn, smb_fname);
5622 } else {
5623 ret = SMB_VFS_STAT(conn, smb_fname);
5626 if (ret == 0 && VALID_STAT_OF_DIR(smb_fname->st)) {
5627 status = NT_STATUS_FILE_IS_A_DIRECTORY;
5628 goto fail;
5632 status = create_file_unixpath(
5633 conn, req, smb_fname, access_mask, share_access,
5634 create_disposition, create_options, file_attributes,
5635 oplock_request, lease, allocation_size, private_flags,
5636 sd, ea_list,
5637 &fsp, &info);
5639 if (!NT_STATUS_IS_OK(status)) {
5640 goto fail;
5643 done:
5644 DEBUG(10, ("create_file: info=%d\n", info));
5646 *result = fsp;
5647 if (pinfo != NULL) {
5648 *pinfo = info;
5650 return NT_STATUS_OK;
5652 fail:
5653 DEBUG(10, ("create_file: %s\n", nt_errstr(status)));
5655 if (fsp != NULL) {
5656 close_file(req, fsp, ERROR_CLOSE);
5657 fsp = NULL;
5659 return status;