s3:vfs: add create tags to SMB_VFS_CREATEFILE
[Samba.git] / source3 / smbd / open.c
blobc6b67f4ae6864d0544b7a489fa44b0cdceed615f
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"
40 extern const struct generic_mapping file_generic_mapping;
42 struct deferred_open_record {
43 bool delayed_for_oplocks;
44 bool async_open;
45 struct file_id id;
48 /****************************************************************************
49 If the requester wanted DELETE_ACCESS and was rejected because
50 the file ACL didn't include DELETE_ACCESS, see if the parent ACL
51 overrides this.
52 ****************************************************************************/
54 static bool parent_override_delete(connection_struct *conn,
55 const struct smb_filename *smb_fname,
56 uint32_t access_mask,
57 uint32_t rejected_mask)
59 if ((access_mask & DELETE_ACCESS) &&
60 (rejected_mask & DELETE_ACCESS) &&
61 can_delete_file_in_directory(conn, smb_fname)) {
62 return true;
64 return false;
67 /****************************************************************************
68 Check if we have open rights.
69 ****************************************************************************/
71 NTSTATUS smbd_check_access_rights(struct connection_struct *conn,
72 const struct smb_filename *smb_fname,
73 bool use_privs,
74 uint32_t access_mask)
76 /* Check if we have rights to open. */
77 NTSTATUS status;
78 struct security_descriptor *sd = NULL;
79 uint32_t rejected_share_access;
80 uint32_t rejected_mask = access_mask;
81 uint32_t do_not_check_mask = 0;
83 rejected_share_access = access_mask & ~(conn->share_access);
85 if (rejected_share_access) {
86 DEBUG(10, ("smbd_check_access_rights: rejected share access 0x%x "
87 "on %s (0x%x)\n",
88 (unsigned int)access_mask,
89 smb_fname_str_dbg(smb_fname),
90 (unsigned int)rejected_share_access ));
91 return NT_STATUS_ACCESS_DENIED;
94 if (!use_privs && get_current_uid(conn) == (uid_t)0) {
95 /* I'm sorry sir, I didn't know you were root... */
96 DEBUG(10,("smbd_check_access_rights: root override "
97 "on %s. Granting 0x%x\n",
98 smb_fname_str_dbg(smb_fname),
99 (unsigned int)access_mask ));
100 return NT_STATUS_OK;
103 if ((access_mask & DELETE_ACCESS) && !lp_acl_check_permissions(SNUM(conn))) {
104 DEBUG(10,("smbd_check_access_rights: not checking ACL "
105 "on DELETE_ACCESS on file %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 &&
112 VALID_STAT(smb_fname->st) &&
113 S_ISLNK(smb_fname->st.st_ex_mode)) {
114 /* We can always delete a symlink. */
115 DEBUG(10,("smbd_check_access_rights: not checking ACL "
116 "on DELETE_ACCESS on symlink %s.\n",
117 smb_fname_str_dbg(smb_fname) ));
118 return NT_STATUS_OK;
121 status = SMB_VFS_GET_NT_ACL(conn, smb_fname->base_name,
122 (SECINFO_OWNER |
123 SECINFO_GROUP |
124 SECINFO_DACL), talloc_tos(), &sd);
126 if (!NT_STATUS_IS_OK(status)) {
127 DEBUG(10, ("smbd_check_access_rights: Could not get acl "
128 "on %s: %s\n",
129 smb_fname_str_dbg(smb_fname),
130 nt_errstr(status)));
132 if (NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
133 goto access_denied;
136 return status;
140 * If we can access the path to this file, by
141 * default we have FILE_READ_ATTRIBUTES from the
142 * containing directory. See the section:
143 * "Algorithm to Check Access to an Existing File"
144 * in MS-FSA.pdf.
146 * se_file_access_check() also takes care of
147 * owner WRITE_DAC and READ_CONTROL.
149 do_not_check_mask = FILE_READ_ATTRIBUTES;
152 * Samba 3.6 and earlier granted execute access even
153 * if the ACL did not contain execute rights.
154 * Samba 4.0 is more correct and checks it.
155 * The compatibilty mode allows to skip this check
156 * to smoothen upgrades.
158 if (lp_acl_allow_execute_always(SNUM(conn))) {
159 do_not_check_mask |= FILE_EXECUTE;
162 status = se_file_access_check(sd,
163 get_current_nttok(conn),
164 use_privs,
165 (access_mask & ~do_not_check_mask),
166 &rejected_mask);
168 DEBUG(10,("smbd_check_access_rights: file %s requesting "
169 "0x%x returning 0x%x (%s)\n",
170 smb_fname_str_dbg(smb_fname),
171 (unsigned int)access_mask,
172 (unsigned int)rejected_mask,
173 nt_errstr(status) ));
175 if (!NT_STATUS_IS_OK(status)) {
176 if (DEBUGLEVEL >= 10) {
177 DEBUG(10,("smbd_check_access_rights: acl for %s is:\n",
178 smb_fname_str_dbg(smb_fname) ));
179 NDR_PRINT_DEBUG(security_descriptor, sd);
183 TALLOC_FREE(sd);
185 if (NT_STATUS_IS_OK(status) ||
186 !NT_STATUS_EQUAL(status, NT_STATUS_ACCESS_DENIED)) {
187 return status;
190 /* Here we know status == NT_STATUS_ACCESS_DENIED. */
192 access_denied:
194 if ((access_mask & FILE_WRITE_ATTRIBUTES) &&
195 (rejected_mask & FILE_WRITE_ATTRIBUTES) &&
196 !lp_store_dos_attributes(SNUM(conn)) &&
197 (lp_map_readonly(SNUM(conn)) ||
198 lp_map_archive(SNUM(conn)) ||
199 lp_map_hidden(SNUM(conn)) ||
200 lp_map_system(SNUM(conn)))) {
201 rejected_mask &= ~FILE_WRITE_ATTRIBUTES;
203 DEBUG(10,("smbd_check_access_rights: "
204 "overrode "
205 "FILE_WRITE_ATTRIBUTES "
206 "on file %s\n",
207 smb_fname_str_dbg(smb_fname)));
210 if (parent_override_delete(conn,
211 smb_fname,
212 access_mask,
213 rejected_mask)) {
214 /* Were we trying to do an open
215 * for delete and didn't get DELETE
216 * access (only) ? Check if the
217 * directory allows DELETE_CHILD.
218 * See here:
219 * http://blogs.msdn.com/oldnewthing/archive/2004/06/04/148426.aspx
220 * for details. */
222 rejected_mask &= ~DELETE_ACCESS;
224 DEBUG(10,("smbd_check_access_rights: "
225 "overrode "
226 "DELETE_ACCESS on "
227 "file %s\n",
228 smb_fname_str_dbg(smb_fname)));
231 if (rejected_mask != 0) {
232 return NT_STATUS_ACCESS_DENIED;
234 return NT_STATUS_OK;
237 static NTSTATUS check_parent_access(struct connection_struct *conn,
238 struct smb_filename *smb_fname,
239 uint32_t access_mask)
241 NTSTATUS status;
242 char *parent_dir = NULL;
243 struct security_descriptor *parent_sd = NULL;
244 uint32_t access_granted = 0;
246 if (!parent_dirname(talloc_tos(),
247 smb_fname->base_name,
248 &parent_dir,
249 NULL)) {
250 return NT_STATUS_NO_MEMORY;
253 if (get_current_uid(conn) == (uid_t)0) {
254 /* I'm sorry sir, I didn't know you were root... */
255 DEBUG(10,("check_parent_access: root override "
256 "on %s. Granting 0x%x\n",
257 smb_fname_str_dbg(smb_fname),
258 (unsigned int)access_mask ));
259 return NT_STATUS_OK;
262 status = SMB_VFS_GET_NT_ACL(conn,
263 parent_dir,
264 SECINFO_DACL,
265 talloc_tos(),
266 &parent_sd);
268 if (!NT_STATUS_IS_OK(status)) {
269 DEBUG(5,("check_parent_access: SMB_VFS_GET_NT_ACL failed for "
270 "%s with error %s\n",
271 parent_dir,
272 nt_errstr(status)));
273 return status;
277 * If we can access the path to this file, by
278 * default we have FILE_READ_ATTRIBUTES from the
279 * containing directory. See the section:
280 * "Algorithm to Check Access to an Existing File"
281 * in MS-FSA.pdf.
283 * se_file_access_check() also takes care of
284 * owner WRITE_DAC and READ_CONTROL.
286 status = se_file_access_check(parent_sd,
287 get_current_nttok(conn),
288 false,
289 (access_mask & ~FILE_READ_ATTRIBUTES),
290 &access_granted);
291 if(!NT_STATUS_IS_OK(status)) {
292 DEBUG(5,("check_parent_access: access check "
293 "on directory %s for "
294 "path %s for mask 0x%x returned (0x%x) %s\n",
295 parent_dir,
296 smb_fname->base_name,
297 access_mask,
298 access_granted,
299 nt_errstr(status) ));
300 return status;
303 return NT_STATUS_OK;
306 /****************************************************************************
307 Ensure when opening a base file for a stream open that we have permissions
308 to do so given the access mask on the base file.
309 ****************************************************************************/
311 static NTSTATUS check_base_file_access(struct connection_struct *conn,
312 struct smb_filename *smb_fname,
313 uint32_t access_mask)
315 NTSTATUS status;
317 status = smbd_calculate_access_mask(conn, smb_fname,
318 false,
319 access_mask,
320 &access_mask);
321 if (!NT_STATUS_IS_OK(status)) {
322 DEBUG(10, ("smbd_calculate_access_mask "
323 "on file %s returned %s\n",
324 smb_fname_str_dbg(smb_fname),
325 nt_errstr(status)));
326 return status;
329 if (access_mask & (FILE_WRITE_DATA|FILE_APPEND_DATA)) {
330 uint32_t dosattrs;
331 if (!CAN_WRITE(conn)) {
332 return NT_STATUS_ACCESS_DENIED;
334 dosattrs = dos_mode(conn, smb_fname);
335 if (IS_DOS_READONLY(dosattrs)) {
336 return NT_STATUS_ACCESS_DENIED;
340 return smbd_check_access_rights(conn,
341 smb_fname,
342 false,
343 access_mask);
346 /****************************************************************************
347 fd support routines - attempt to do a dos_open.
348 ****************************************************************************/
350 NTSTATUS fd_open(struct connection_struct *conn,
351 files_struct *fsp,
352 int flags,
353 mode_t mode)
355 struct smb_filename *smb_fname = fsp->fsp_name;
356 NTSTATUS status = NT_STATUS_OK;
358 #ifdef O_NOFOLLOW
360 * Never follow symlinks on a POSIX client. The
361 * client should be doing this.
364 if (fsp->posix_open || !lp_follow_symlinks(SNUM(conn))) {
365 flags |= O_NOFOLLOW;
367 #endif
369 fsp->fh->fd = SMB_VFS_OPEN(conn, smb_fname, fsp, flags, mode);
370 if (fsp->fh->fd == -1) {
371 int posix_errno = errno;
372 #ifdef O_NOFOLLOW
373 #if defined(ENOTSUP) && defined(OSF1)
374 /* handle special Tru64 errno */
375 if (errno == ENOTSUP) {
376 posix_errno = ELOOP;
378 #endif /* ENOTSUP */
379 #ifdef EFTYPE
380 /* fix broken NetBSD errno */
381 if (errno == EFTYPE) {
382 posix_errno = ELOOP;
384 #endif /* EFTYPE */
385 /* fix broken FreeBSD errno */
386 if (errno == EMLINK) {
387 posix_errno = ELOOP;
389 #endif /* O_NOFOLLOW */
390 status = map_nt_error_from_unix(posix_errno);
391 if (errno == EMFILE) {
392 static time_t last_warned = 0L;
394 if (time((time_t *) NULL) > last_warned) {
395 DEBUG(0,("Too many open files, unable "
396 "to open more! smbd's max "
397 "open files = %d\n",
398 lp_max_open_files()));
399 last_warned = time((time_t *) NULL);
405 DEBUG(10,("fd_open: name %s, flags = 0%o mode = 0%o, fd = %d. %s\n",
406 smb_fname_str_dbg(smb_fname), flags, (int)mode, fsp->fh->fd,
407 (fsp->fh->fd == -1) ? strerror(errno) : "" ));
409 return status;
412 /****************************************************************************
413 Close the file associated with a fsp.
414 ****************************************************************************/
416 NTSTATUS fd_close(files_struct *fsp)
418 int ret;
420 if (fsp->dptr) {
421 dptr_CloseDir(fsp);
423 if (fsp->fh->fd == -1) {
424 return NT_STATUS_OK; /* What we used to call a stat open. */
426 if (fsp->fh->ref_count > 1) {
427 return NT_STATUS_OK; /* Shared handle. Only close last reference. */
430 ret = SMB_VFS_CLOSE(fsp);
431 fsp->fh->fd = -1;
432 if (ret == -1) {
433 return map_nt_error_from_unix(errno);
435 return NT_STATUS_OK;
438 /****************************************************************************
439 Change the ownership of a file to that of the parent directory.
440 Do this by fd if possible.
441 ****************************************************************************/
443 void change_file_owner_to_parent(connection_struct *conn,
444 const char *inherit_from_dir,
445 files_struct *fsp)
447 struct smb_filename *smb_fname_parent;
448 int ret;
450 smb_fname_parent = synthetic_smb_fname(talloc_tos(), inherit_from_dir,
451 NULL, NULL);
452 if (smb_fname_parent == NULL) {
453 return;
456 ret = SMB_VFS_STAT(conn, smb_fname_parent);
457 if (ret == -1) {
458 DEBUG(0,("change_file_owner_to_parent: failed to stat parent "
459 "directory %s. Error was %s\n",
460 smb_fname_str_dbg(smb_fname_parent),
461 strerror(errno)));
462 TALLOC_FREE(smb_fname_parent);
463 return;
466 if (smb_fname_parent->st.st_ex_uid == fsp->fsp_name->st.st_ex_uid) {
467 /* Already this uid - no need to change. */
468 DEBUG(10,("change_file_owner_to_parent: file %s "
469 "is already owned by uid %d\n",
470 fsp_str_dbg(fsp),
471 (int)fsp->fsp_name->st.st_ex_uid ));
472 TALLOC_FREE(smb_fname_parent);
473 return;
476 become_root();
477 ret = SMB_VFS_FCHOWN(fsp, smb_fname_parent->st.st_ex_uid, (gid_t)-1);
478 unbecome_root();
479 if (ret == -1) {
480 DEBUG(0,("change_file_owner_to_parent: failed to fchown "
481 "file %s to parent directory uid %u. Error "
482 "was %s\n", fsp_str_dbg(fsp),
483 (unsigned int)smb_fname_parent->st.st_ex_uid,
484 strerror(errno) ));
485 } else {
486 DEBUG(10,("change_file_owner_to_parent: changed new file %s to "
487 "parent directory uid %u.\n", fsp_str_dbg(fsp),
488 (unsigned int)smb_fname_parent->st.st_ex_uid));
489 /* Ensure the uid entry is updated. */
490 fsp->fsp_name->st.st_ex_uid = smb_fname_parent->st.st_ex_uid;
493 TALLOC_FREE(smb_fname_parent);
496 NTSTATUS change_dir_owner_to_parent(connection_struct *conn,
497 const char *inherit_from_dir,
498 const char *fname,
499 SMB_STRUCT_STAT *psbuf)
501 struct smb_filename *smb_fname_parent;
502 struct smb_filename *smb_fname_cwd = NULL;
503 char *saved_dir = NULL;
504 TALLOC_CTX *ctx = talloc_tos();
505 NTSTATUS status = NT_STATUS_OK;
506 int ret;
508 smb_fname_parent = synthetic_smb_fname(ctx, inherit_from_dir,
509 NULL, NULL);
510 if (smb_fname_parent == NULL) {
511 return NT_STATUS_NO_MEMORY;
514 ret = SMB_VFS_STAT(conn, smb_fname_parent);
515 if (ret == -1) {
516 status = map_nt_error_from_unix(errno);
517 DEBUG(0,("change_dir_owner_to_parent: failed to stat parent "
518 "directory %s. Error was %s\n",
519 smb_fname_str_dbg(smb_fname_parent),
520 strerror(errno)));
521 goto out;
524 /* We've already done an lstat into psbuf, and we know it's a
525 directory. If we can cd into the directory and the dev/ino
526 are the same then we can safely chown without races as
527 we're locking the directory in place by being in it. This
528 should work on any UNIX (thanks tridge :-). JRA.
531 saved_dir = vfs_GetWd(ctx,conn);
532 if (!saved_dir) {
533 status = map_nt_error_from_unix(errno);
534 DEBUG(0,("change_dir_owner_to_parent: failed to get "
535 "current working directory. Error was %s\n",
536 strerror(errno)));
537 goto out;
540 /* Chdir into the new path. */
541 if (vfs_ChDir(conn, fname) == -1) {
542 status = map_nt_error_from_unix(errno);
543 DEBUG(0,("change_dir_owner_to_parent: failed to change "
544 "current working directory to %s. Error "
545 "was %s\n", fname, strerror(errno) ));
546 goto chdir;
549 smb_fname_cwd = synthetic_smb_fname(ctx, ".", NULL, NULL);
550 if (smb_fname_cwd == NULL) {
551 status = NT_STATUS_NO_MEMORY;
552 goto chdir;
555 ret = SMB_VFS_STAT(conn, smb_fname_cwd);
556 if (ret == -1) {
557 status = map_nt_error_from_unix(errno);
558 DEBUG(0,("change_dir_owner_to_parent: failed to stat "
559 "directory '.' (%s) Error was %s\n",
560 fname, strerror(errno)));
561 goto chdir;
564 /* Ensure we're pointing at the same place. */
565 if (smb_fname_cwd->st.st_ex_dev != psbuf->st_ex_dev ||
566 smb_fname_cwd->st.st_ex_ino != psbuf->st_ex_ino) {
567 DEBUG(0,("change_dir_owner_to_parent: "
568 "device/inode on directory %s changed. "
569 "Refusing to chown !\n", fname ));
570 status = NT_STATUS_ACCESS_DENIED;
571 goto chdir;
574 if (smb_fname_parent->st.st_ex_uid == smb_fname_cwd->st.st_ex_uid) {
575 /* Already this uid - no need to change. */
576 DEBUG(10,("change_dir_owner_to_parent: directory %s "
577 "is already owned by uid %d\n",
578 fname,
579 (int)smb_fname_cwd->st.st_ex_uid ));
580 status = NT_STATUS_OK;
581 goto chdir;
584 become_root();
585 ret = SMB_VFS_LCHOWN(conn, ".", smb_fname_parent->st.st_ex_uid,
586 (gid_t)-1);
587 unbecome_root();
588 if (ret == -1) {
589 status = map_nt_error_from_unix(errno);
590 DEBUG(10,("change_dir_owner_to_parent: failed to chown "
591 "directory %s to parent directory uid %u. "
592 "Error was %s\n", fname,
593 (unsigned int)smb_fname_parent->st.st_ex_uid,
594 strerror(errno) ));
595 } else {
596 DEBUG(10,("change_dir_owner_to_parent: changed ownership of new "
597 "directory %s to parent directory uid %u.\n",
598 fname, (unsigned int)smb_fname_parent->st.st_ex_uid ));
599 /* Ensure the uid entry is updated. */
600 psbuf->st_ex_uid = smb_fname_parent->st.st_ex_uid;
603 chdir:
604 vfs_ChDir(conn,saved_dir);
605 out:
606 TALLOC_FREE(smb_fname_parent);
607 TALLOC_FREE(smb_fname_cwd);
608 return status;
611 /****************************************************************************
612 Open a file - returning a guaranteed ATOMIC indication of if the
613 file was created or not.
614 ****************************************************************************/
616 static NTSTATUS fd_open_atomic(struct connection_struct *conn,
617 files_struct *fsp,
618 int flags,
619 mode_t mode,
620 bool *file_created)
622 NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
623 bool file_existed = VALID_STAT(fsp->fsp_name->st);
625 *file_created = false;
627 if (!(flags & O_CREAT)) {
629 * We're not creating the file, just pass through.
631 return fd_open(conn, fsp, flags, mode);
634 if (flags & O_EXCL) {
636 * Fail if already exists, just pass through.
638 status = fd_open(conn, fsp, flags, mode);
641 * Here we've opened with O_CREAT|O_EXCL. If that went
642 * NT_STATUS_OK, we *know* we created this file.
644 *file_created = NT_STATUS_IS_OK(status);
646 return status;
650 * Now it gets tricky. We have O_CREAT, but not O_EXCL.
651 * To know absolutely if we created the file or not,
652 * we can never call O_CREAT without O_EXCL. So if
653 * we think the file existed, try without O_CREAT|O_EXCL.
654 * If we think the file didn't exist, try with
655 * O_CREAT|O_EXCL. Keep bouncing between these two
656 * requests until either the file is created, or
657 * opened. Either way, we keep going until we get
658 * a returnable result (error, or open/create).
661 while(1) {
662 int curr_flags = flags;
664 if (file_existed) {
665 /* Just try open, do not create. */
666 curr_flags &= ~(O_CREAT);
667 status = fd_open(conn, fsp, curr_flags, mode);
668 if (NT_STATUS_EQUAL(status,
669 NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
671 * Someone deleted it in the meantime.
672 * Retry with O_EXCL.
674 file_existed = false;
675 DEBUG(10,("fd_open_atomic: file %s existed. "
676 "Retry.\n",
677 smb_fname_str_dbg(fsp->fsp_name)));
678 continue;
680 } else {
681 /* Try create exclusively, fail if it exists. */
682 curr_flags |= O_EXCL;
683 status = fd_open(conn, fsp, curr_flags, mode);
684 if (NT_STATUS_EQUAL(status,
685 NT_STATUS_OBJECT_NAME_COLLISION)) {
687 * Someone created it in the meantime.
688 * Retry without O_CREAT.
690 file_existed = true;
691 DEBUG(10,("fd_open_atomic: file %s "
692 "did not exist. Retry.\n",
693 smb_fname_str_dbg(fsp->fsp_name)));
694 continue;
696 if (NT_STATUS_IS_OK(status)) {
698 * Here we've opened with O_CREAT|O_EXCL
699 * and got success. We *know* we created
700 * this file.
702 *file_created = true;
705 /* Create is done, or failed. */
706 break;
708 return status;
711 /****************************************************************************
712 Open a file.
713 ****************************************************************************/
715 static NTSTATUS open_file(files_struct *fsp,
716 connection_struct *conn,
717 struct smb_request *req,
718 const char *parent_dir,
719 int flags,
720 mode_t unx_mode,
721 uint32 access_mask, /* client requested access mask. */
722 uint32 open_access_mask, /* what we're actually using in the open. */
723 bool *p_file_created)
725 struct smb_filename *smb_fname = fsp->fsp_name;
726 NTSTATUS status = NT_STATUS_OK;
727 int accmode = (flags & O_ACCMODE);
728 int local_flags = flags;
729 bool file_existed = VALID_STAT(fsp->fsp_name->st);
731 fsp->fh->fd = -1;
732 errno = EPERM;
734 /* Check permissions */
737 * This code was changed after seeing a client open request
738 * containing the open mode of (DENY_WRITE/read-only) with
739 * the 'create if not exist' bit set. The previous code
740 * would fail to open the file read only on a read-only share
741 * as it was checking the flags parameter directly against O_RDONLY,
742 * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
743 * JRA.
746 if (!CAN_WRITE(conn)) {
747 /* It's a read-only share - fail if we wanted to write. */
748 if(accmode != O_RDONLY || (flags & O_TRUNC) || (flags & O_APPEND)) {
749 DEBUG(3,("Permission denied opening %s\n",
750 smb_fname_str_dbg(smb_fname)));
751 return NT_STATUS_ACCESS_DENIED;
753 if (flags & O_CREAT) {
754 /* We don't want to write - but we must make sure that
755 O_CREAT doesn't create the file if we have write
756 access into the directory.
758 flags &= ~(O_CREAT|O_EXCL);
759 local_flags &= ~(O_CREAT|O_EXCL);
764 * This little piece of insanity is inspired by the
765 * fact that an NT client can open a file for O_RDONLY,
766 * but set the create disposition to FILE_EXISTS_TRUNCATE.
767 * If the client *can* write to the file, then it expects to
768 * truncate the file, even though it is opening for readonly.
769 * Quicken uses this stupid trick in backup file creation...
770 * Thanks *greatly* to "David W. Chapman Jr." <dwcjr@inethouston.net>
771 * for helping track this one down. It didn't bite us in 2.0.x
772 * as we always opened files read-write in that release. JRA.
775 if ((accmode == O_RDONLY) && ((flags & O_TRUNC) == O_TRUNC)) {
776 DEBUG(10,("open_file: truncate requested on read-only open "
777 "for file %s\n", smb_fname_str_dbg(smb_fname)));
778 local_flags = (flags & ~O_ACCMODE)|O_RDWR;
781 if ((open_access_mask & (FILE_READ_DATA|FILE_WRITE_DATA|FILE_APPEND_DATA|FILE_EXECUTE)) ||
782 (!file_existed && (local_flags & O_CREAT)) ||
783 ((local_flags & O_TRUNC) == O_TRUNC) ) {
784 const char *wild;
785 int ret;
787 #if defined(O_NONBLOCK) && defined(S_ISFIFO)
789 * We would block on opening a FIFO with no one else on the
790 * other end. Do what we used to do and add O_NONBLOCK to the
791 * open flags. JRA.
794 if (file_existed && S_ISFIFO(smb_fname->st.st_ex_mode)) {
795 local_flags &= ~O_TRUNC; /* Can't truncate a FIFO. */
796 local_flags |= O_NONBLOCK;
798 #endif
800 /* Don't create files with Microsoft wildcard characters. */
801 if (fsp->base_fsp) {
803 * wildcard characters are allowed in stream names
804 * only test the basefilename
806 wild = fsp->base_fsp->fsp_name->base_name;
807 } else {
808 wild = smb_fname->base_name;
810 if ((local_flags & O_CREAT) && !file_existed &&
811 ms_has_wild(wild)) {
812 return NT_STATUS_OBJECT_NAME_INVALID;
815 /* Can we access this file ? */
816 if (!fsp->base_fsp) {
817 /* Only do this check on non-stream open. */
818 if (file_existed) {
819 status = smbd_check_access_rights(conn,
820 smb_fname,
821 false,
822 access_mask);
824 if (!NT_STATUS_IS_OK(status)) {
825 DEBUG(10, ("open_file: "
826 "smbd_check_access_rights "
827 "on file %s returned %s\n",
828 smb_fname_str_dbg(smb_fname),
829 nt_errstr(status)));
832 if (!NT_STATUS_IS_OK(status) &&
833 !NT_STATUS_EQUAL(status,
834 NT_STATUS_OBJECT_NAME_NOT_FOUND))
836 return status;
839 if (NT_STATUS_EQUAL(status,
840 NT_STATUS_OBJECT_NAME_NOT_FOUND))
842 DEBUG(10, ("open_file: "
843 "file %s vanished since we "
844 "checked for existence.\n",
845 smb_fname_str_dbg(smb_fname)));
846 file_existed = false;
847 SET_STAT_INVALID(fsp->fsp_name->st);
851 if (!file_existed) {
852 if (!(local_flags & O_CREAT)) {
853 /* File didn't exist and no O_CREAT. */
854 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
857 status = check_parent_access(conn,
858 smb_fname,
859 SEC_DIR_ADD_FILE);
860 if (!NT_STATUS_IS_OK(status)) {
861 DEBUG(10, ("open_file: "
862 "check_parent_access on "
863 "file %s returned %s\n",
864 smb_fname_str_dbg(smb_fname),
865 nt_errstr(status) ));
866 return status;
872 * Actually do the open - if O_TRUNC is needed handle it
873 * below under the share mode lock.
875 status = fd_open_atomic(conn, fsp, local_flags & ~O_TRUNC,
876 unx_mode, p_file_created);
877 if (!NT_STATUS_IS_OK(status)) {
878 DEBUG(3,("Error opening file %s (%s) (local_flags=%d) "
879 "(flags=%d)\n", smb_fname_str_dbg(smb_fname),
880 nt_errstr(status),local_flags,flags));
881 return status;
884 ret = SMB_VFS_FSTAT(fsp, &smb_fname->st);
885 if (ret == -1) {
886 /* If we have an fd, this stat should succeed. */
887 DEBUG(0,("Error doing fstat on open file %s "
888 "(%s)\n",
889 smb_fname_str_dbg(smb_fname),
890 strerror(errno) ));
891 status = map_nt_error_from_unix(errno);
892 fd_close(fsp);
893 return status;
896 if (*p_file_created) {
897 /* We created this file. */
899 bool need_re_stat = false;
900 /* Do all inheritance work after we've
901 done a successful fstat call and filled
902 in the stat struct in fsp->fsp_name. */
904 /* Inherit the ACL if required */
905 if (lp_inherit_permissions(SNUM(conn))) {
906 inherit_access_posix_acl(conn, parent_dir,
907 smb_fname->base_name,
908 unx_mode);
909 need_re_stat = true;
912 /* Change the owner if required. */
913 if (lp_inherit_owner(SNUM(conn))) {
914 change_file_owner_to_parent(conn, parent_dir,
915 fsp);
916 need_re_stat = true;
919 if (need_re_stat) {
920 ret = SMB_VFS_FSTAT(fsp, &smb_fname->st);
921 /* If we have an fd, this stat should succeed. */
922 if (ret == -1) {
923 DEBUG(0,("Error doing fstat on open file %s "
924 "(%s)\n",
925 smb_fname_str_dbg(smb_fname),
926 strerror(errno) ));
930 notify_fname(conn, NOTIFY_ACTION_ADDED,
931 FILE_NOTIFY_CHANGE_FILE_NAME,
932 smb_fname->base_name);
934 } else {
935 fsp->fh->fd = -1; /* What we used to call a stat open. */
936 if (!file_existed) {
937 /* File must exist for a stat open. */
938 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
941 status = smbd_check_access_rights(conn,
942 smb_fname,
943 false,
944 access_mask);
946 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND) &&
947 fsp->posix_open &&
948 S_ISLNK(smb_fname->st.st_ex_mode)) {
949 /* This is a POSIX stat open for delete
950 * or rename on a symlink that points
951 * nowhere. Allow. */
952 DEBUG(10,("open_file: allowing POSIX "
953 "open on bad symlink %s\n",
954 smb_fname_str_dbg(smb_fname)));
955 status = NT_STATUS_OK;
958 if (!NT_STATUS_IS_OK(status)) {
959 DEBUG(10,("open_file: "
960 "smbd_check_access_rights on file "
961 "%s returned %s\n",
962 smb_fname_str_dbg(smb_fname),
963 nt_errstr(status) ));
964 return status;
969 * POSIX allows read-only opens of directories. We don't
970 * want to do this (we use a different code path for this)
971 * so catch a directory open and return an EISDIR. JRA.
974 if(S_ISDIR(smb_fname->st.st_ex_mode)) {
975 fd_close(fsp);
976 errno = EISDIR;
977 return NT_STATUS_FILE_IS_A_DIRECTORY;
980 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
981 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
982 fsp->file_pid = req ? req->smbpid : 0;
983 fsp->can_lock = True;
984 fsp->can_read = ((access_mask & FILE_READ_DATA) != 0);
985 fsp->can_write =
986 CAN_WRITE(conn) &&
987 ((access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) != 0);
988 fsp->print_file = NULL;
989 fsp->modified = False;
990 fsp->sent_oplock_break = NO_BREAK_SENT;
991 fsp->is_directory = False;
992 if (conn->aio_write_behind_list &&
993 is_in_path(smb_fname->base_name, conn->aio_write_behind_list,
994 conn->case_sensitive)) {
995 fsp->aio_write_behind = True;
998 fsp->wcp = NULL; /* Write cache pointer. */
1000 DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
1001 conn->session_info->unix_info->unix_name,
1002 smb_fname_str_dbg(smb_fname),
1003 BOOLSTR(fsp->can_read), BOOLSTR(fsp->can_write),
1004 conn->num_files_open));
1006 errno = 0;
1007 return NT_STATUS_OK;
1010 /****************************************************************************
1011 Check if we can open a file with a share mode.
1012 Returns True if conflict, False if not.
1013 ****************************************************************************/
1015 static bool share_conflict(struct share_mode_entry *entry,
1016 uint32 access_mask,
1017 uint32 share_access)
1019 DEBUG(10,("share_conflict: entry->access_mask = 0x%x, "
1020 "entry->share_access = 0x%x, "
1021 "entry->private_options = 0x%x\n",
1022 (unsigned int)entry->access_mask,
1023 (unsigned int)entry->share_access,
1024 (unsigned int)entry->private_options));
1026 if (server_id_is_disconnected(&entry->pid)) {
1028 * note: cleanup should have been done by
1029 * delay_for_batch_oplocks()
1031 return false;
1034 DEBUG(10,("share_conflict: access_mask = 0x%x, share_access = 0x%x\n",
1035 (unsigned int)access_mask, (unsigned int)share_access));
1037 if ((entry->access_mask & (FILE_WRITE_DATA|
1038 FILE_APPEND_DATA|
1039 FILE_READ_DATA|
1040 FILE_EXECUTE|
1041 DELETE_ACCESS)) == 0) {
1042 DEBUG(10,("share_conflict: No conflict due to "
1043 "entry->access_mask = 0x%x\n",
1044 (unsigned int)entry->access_mask ));
1045 return False;
1048 if ((access_mask & (FILE_WRITE_DATA|
1049 FILE_APPEND_DATA|
1050 FILE_READ_DATA|
1051 FILE_EXECUTE|
1052 DELETE_ACCESS)) == 0) {
1053 DEBUG(10,("share_conflict: No conflict due to "
1054 "access_mask = 0x%x\n",
1055 (unsigned int)access_mask ));
1056 return False;
1059 #if 1 /* JRA TEST - Superdebug. */
1060 #define CHECK_MASK(num, am, right, sa, share) \
1061 DEBUG(10,("share_conflict: [%d] am (0x%x) & right (0x%x) = 0x%x\n", \
1062 (unsigned int)(num), (unsigned int)(am), \
1063 (unsigned int)(right), (unsigned int)(am)&(right) )); \
1064 DEBUG(10,("share_conflict: [%d] sa (0x%x) & share (0x%x) = 0x%x\n", \
1065 (unsigned int)(num), (unsigned int)(sa), \
1066 (unsigned int)(share), (unsigned int)(sa)&(share) )); \
1067 if (((am) & (right)) && !((sa) & (share))) { \
1068 DEBUG(10,("share_conflict: check %d conflict am = 0x%x, right = 0x%x, \
1069 sa = 0x%x, share = 0x%x\n", (num), (unsigned int)(am), (unsigned int)(right), (unsigned int)(sa), \
1070 (unsigned int)(share) )); \
1071 return True; \
1073 #else
1074 #define CHECK_MASK(num, am, right, sa, share) \
1075 if (((am) & (right)) && !((sa) & (share))) { \
1076 DEBUG(10,("share_conflict: check %d conflict am = 0x%x, right = 0x%x, \
1077 sa = 0x%x, share = 0x%x\n", (num), (unsigned int)(am), (unsigned int)(right), (unsigned int)(sa), \
1078 (unsigned int)(share) )); \
1079 return True; \
1081 #endif
1083 CHECK_MASK(1, entry->access_mask, FILE_WRITE_DATA | FILE_APPEND_DATA,
1084 share_access, FILE_SHARE_WRITE);
1085 CHECK_MASK(2, access_mask, FILE_WRITE_DATA | FILE_APPEND_DATA,
1086 entry->share_access, FILE_SHARE_WRITE);
1088 CHECK_MASK(3, entry->access_mask, FILE_READ_DATA | FILE_EXECUTE,
1089 share_access, FILE_SHARE_READ);
1090 CHECK_MASK(4, access_mask, FILE_READ_DATA | FILE_EXECUTE,
1091 entry->share_access, FILE_SHARE_READ);
1093 CHECK_MASK(5, entry->access_mask, DELETE_ACCESS,
1094 share_access, FILE_SHARE_DELETE);
1095 CHECK_MASK(6, access_mask, DELETE_ACCESS,
1096 entry->share_access, FILE_SHARE_DELETE);
1098 DEBUG(10,("share_conflict: No conflict.\n"));
1099 return False;
1102 #if defined(DEVELOPER)
1103 static void validate_my_share_entries(struct smbd_server_connection *sconn,
1104 int num,
1105 struct share_mode_entry *share_entry)
1107 struct server_id self = messaging_server_id(sconn->msg_ctx);
1108 files_struct *fsp;
1110 if (!serverid_equal(&self, &share_entry->pid)) {
1111 return;
1114 if (share_entry->op_mid == 0) {
1115 /* INTERNAL_OPEN_ONLY */
1116 return;
1119 if (!is_valid_share_mode_entry(share_entry)) {
1120 return;
1123 fsp = file_find_dif(sconn, share_entry->id,
1124 share_entry->share_file_id);
1125 if (!fsp) {
1126 DEBUG(0,("validate_my_share_entries: PANIC : %s\n",
1127 share_mode_str(talloc_tos(), num, share_entry) ));
1128 smb_panic("validate_my_share_entries: Cannot match a "
1129 "share entry with an open file\n");
1132 if (((uint16)fsp->oplock_type) != share_entry->op_type) {
1133 goto panic;
1136 return;
1138 panic:
1140 char *str;
1141 DEBUG(0,("validate_my_share_entries: PANIC : %s\n",
1142 share_mode_str(talloc_tos(), num, share_entry) ));
1143 str = talloc_asprintf(talloc_tos(),
1144 "validate_my_share_entries: "
1145 "file %s, oplock_type = 0x%x, op_type = 0x%x\n",
1146 fsp->fsp_name->base_name,
1147 (unsigned int)fsp->oplock_type,
1148 (unsigned int)share_entry->op_type );
1149 smb_panic(str);
1152 #endif
1154 bool is_stat_open(uint32 access_mask)
1156 const uint32_t stat_open_bits =
1157 (SYNCHRONIZE_ACCESS|
1158 FILE_READ_ATTRIBUTES|
1159 FILE_WRITE_ATTRIBUTES);
1161 return (((access_mask & stat_open_bits) != 0) &&
1162 ((access_mask & ~stat_open_bits) == 0));
1165 static bool has_delete_on_close(struct share_mode_lock *lck,
1166 uint32_t name_hash)
1168 struct share_mode_data *d = lck->data;
1169 uint32_t i;
1171 if (d->num_share_modes == 0) {
1172 return false;
1174 if (!is_delete_on_close_set(lck, name_hash)) {
1175 return false;
1177 for (i=0; i<d->num_share_modes; i++) {
1178 if (!share_mode_stale_pid(d, i)) {
1179 return true;
1182 return false;
1185 /****************************************************************************
1186 Deal with share modes
1187 Invariant: Share mode must be locked on entry and exit.
1188 Returns -1 on error, or number of share modes on success (may be zero).
1189 ****************************************************************************/
1191 static NTSTATUS open_mode_check(connection_struct *conn,
1192 struct share_mode_lock *lck,
1193 uint32 access_mask,
1194 uint32 share_access)
1196 int i;
1198 if(lck->data->num_share_modes == 0) {
1199 return NT_STATUS_OK;
1202 if (is_stat_open(access_mask)) {
1203 /* Stat open that doesn't trigger oplock breaks or share mode
1204 * checks... ! JRA. */
1205 return NT_STATUS_OK;
1209 * Check if the share modes will give us access.
1212 #if defined(DEVELOPER)
1213 for(i = 0; i < lck->data->num_share_modes; i++) {
1214 validate_my_share_entries(conn->sconn, i,
1215 &lck->data->share_modes[i]);
1217 #endif
1219 /* Now we check the share modes, after any oplock breaks. */
1220 for(i = 0; i < lck->data->num_share_modes; i++) {
1222 if (!is_valid_share_mode_entry(&lck->data->share_modes[i])) {
1223 continue;
1226 /* someone else has a share lock on it, check to see if we can
1227 * too */
1228 if (share_conflict(&lck->data->share_modes[i],
1229 access_mask, share_access)) {
1231 if (share_mode_stale_pid(lck->data, i)) {
1232 continue;
1235 return NT_STATUS_SHARING_VIOLATION;
1239 return NT_STATUS_OK;
1243 * Send a break message to the oplock holder and delay the open for
1244 * our client.
1247 static NTSTATUS send_break_message(struct messaging_context *msg_ctx,
1248 const struct share_mode_entry *exclusive,
1249 uint16_t break_to)
1251 NTSTATUS status;
1252 char msg[MSG_SMB_SHARE_MODE_ENTRY_SIZE];
1254 DEBUG(10, ("Sending break request to PID %s\n",
1255 procid_str_static(&exclusive->pid)));
1257 /* Create the message. */
1258 share_mode_entry_to_message(msg, exclusive);
1260 /* Overload entry->op_type */
1262 * This is a cut from uint32 to uint16, but so far only the lower 3
1263 * bits (LEASE_WRITE/HANDLE/READ are used anyway.
1265 SSVAL(msg,OP_BREAK_MSG_OP_TYPE_OFFSET, break_to);
1267 status = messaging_send_buf(msg_ctx, exclusive->pid,
1268 MSG_SMB_BREAK_REQUEST,
1269 (uint8 *)msg, sizeof(msg));
1270 if (!NT_STATUS_IS_OK(status)) {
1271 DEBUG(3, ("Could not send oplock break message: %s\n",
1272 nt_errstr(status)));
1275 return status;
1279 * Do internal consistency checks on the share mode for a file.
1282 static bool validate_oplock_types(struct share_mode_lock *lck)
1284 struct share_mode_data *d = lck->data;
1285 bool batch = false;
1286 bool ex_or_batch = false;
1287 bool level2 = false;
1288 bool no_oplock = false;
1289 uint32_t num_non_stat_opens = 0;
1290 uint32_t i;
1292 for (i=0; i<d->num_share_modes; i++) {
1293 struct share_mode_entry *e = &d->share_modes[i];
1295 if (!is_valid_share_mode_entry(e)) {
1296 continue;
1299 if (e->op_mid == 0) {
1300 /* INTERNAL_OPEN_ONLY */
1301 continue;
1304 if (e->op_type == NO_OPLOCK && is_stat_open(e->access_mask)) {
1305 /* We ignore stat opens in the table - they
1306 always have NO_OPLOCK and never get or
1307 cause breaks. JRA. */
1308 continue;
1311 num_non_stat_opens += 1;
1313 if (BATCH_OPLOCK_TYPE(e->op_type)) {
1314 /* batch - can only be one. */
1315 if (share_mode_stale_pid(d, i)) {
1316 DEBUG(10, ("Found stale batch oplock\n"));
1317 continue;
1319 if (ex_or_batch || batch || level2 || no_oplock) {
1320 DEBUG(0, ("Bad batch oplock entry %u.",
1321 (unsigned)i));
1322 return false;
1324 batch = true;
1327 if (EXCLUSIVE_OPLOCK_TYPE(e->op_type)) {
1328 if (share_mode_stale_pid(d, i)) {
1329 DEBUG(10, ("Found stale duplicate oplock\n"));
1330 continue;
1332 /* Exclusive or batch - can only be one. */
1333 if (ex_or_batch || level2 || no_oplock) {
1334 DEBUG(0, ("Bad exclusive or batch oplock "
1335 "entry %u.", (unsigned)i));
1336 return false;
1338 ex_or_batch = true;
1341 if (LEVEL_II_OPLOCK_TYPE(e->op_type)) {
1342 if (batch || ex_or_batch) {
1343 if (share_mode_stale_pid(d, i)) {
1344 DEBUG(10, ("Found stale LevelII "
1345 "oplock\n"));
1346 continue;
1348 DEBUG(0, ("Bad levelII oplock entry %u.",
1349 (unsigned)i));
1350 return false;
1352 level2 = true;
1355 if (e->op_type == NO_OPLOCK) {
1356 if (batch || ex_or_batch) {
1357 if (share_mode_stale_pid(d, i)) {
1358 DEBUG(10, ("Found stale NO_OPLOCK "
1359 "entry\n"));
1360 continue;
1362 DEBUG(0, ("Bad no oplock entry %u.",
1363 (unsigned)i));
1364 return false;
1366 no_oplock = true;
1370 remove_stale_share_mode_entries(d);
1372 if ((batch || ex_or_batch) && (num_non_stat_opens != 1)) {
1373 DEBUG(1, ("got batch (%d) or ex (%d) non-exclusively (%d)\n",
1374 (int)batch, (int)ex_or_batch,
1375 (int)d->num_share_modes));
1376 return false;
1379 return true;
1382 static bool delay_for_oplock(files_struct *fsp,
1383 int oplock_request,
1384 const struct smb2_lease *lease,
1385 struct share_mode_lock *lck,
1386 bool have_sharing_violation,
1387 uint32_t create_disposition,
1388 bool first_open_attempt)
1390 struct share_mode_data *d = lck->data;
1391 uint32_t i;
1392 bool delay = false;
1393 bool will_overwrite;
1395 if ((oplock_request & INTERNAL_OPEN_ONLY) ||
1396 is_stat_open(fsp->access_mask)) {
1397 return false;
1400 switch (create_disposition) {
1401 case FILE_SUPERSEDE:
1402 case FILE_OVERWRITE:
1403 case FILE_OVERWRITE_IF:
1404 will_overwrite = true;
1405 break;
1406 default:
1407 will_overwrite = false;
1408 break;
1411 for (i=0; i<d->num_share_modes; i++) {
1412 struct share_mode_entry *e = &d->share_modes[i];
1413 struct share_mode_lease *l = NULL;
1414 uint32_t e_lease_type = get_lease_type(d, e);
1415 uint32_t break_to;
1416 uint32_t delay_mask = 0;
1418 if (e->op_type == LEASE_OPLOCK) {
1419 l = &d->leases[e->lease_idx];
1422 if (have_sharing_violation) {
1423 delay_mask = SMB2_LEASE_HANDLE;
1424 } else {
1425 delay_mask = SMB2_LEASE_WRITE;
1428 break_to = e_lease_type & ~delay_mask;
1430 if (will_overwrite) {
1432 * we'll decide about SMB2_LEASE_READ later.
1434 * Maybe the break will be defered
1436 break_to &= ~SMB2_LEASE_HANDLE;
1439 DEBUG(10, ("entry %u: e_lease_type %u, will_overwrite: %u\n",
1440 (unsigned)i, (unsigned)e_lease_type,
1441 (unsigned)will_overwrite));
1443 if (lease != NULL && l != NULL) {
1444 bool ign;
1446 ign = smb2_lease_equal(fsp_client_guid(fsp),
1447 &lease->lease_key,
1448 &l->client_guid,
1449 &l->lease_key);
1450 if (ign) {
1451 continue;
1455 if ((e_lease_type & ~break_to) == 0) {
1456 if (l != NULL && l->breaking) {
1457 delay = true;
1459 continue;
1462 if (share_mode_stale_pid(d, i)) {
1463 continue;
1466 if (will_overwrite) {
1468 * If we break anyway break to NONE directly.
1469 * Otherwise vfs_set_filelen() will trigger the
1470 * break.
1472 break_to &= ~(SMB2_LEASE_READ|SMB2_LEASE_WRITE);
1475 if (e->op_type != LEASE_OPLOCK) {
1477 * Oplocks only support breaking to R or NONE.
1479 break_to &= ~(SMB2_LEASE_HANDLE|SMB2_LEASE_WRITE);
1482 DEBUG(10, ("breaking from %d to %d\n",
1483 (int)e_lease_type, (int)break_to));
1484 send_break_message(fsp->conn->sconn->msg_ctx, e,
1485 break_to);
1486 if (e_lease_type & delay_mask) {
1487 delay = true;
1489 if (l != NULL && l->breaking && !first_open_attempt) {
1490 delay = true;
1492 continue;
1495 return delay;
1498 static bool file_has_brlocks(files_struct *fsp)
1500 struct byte_range_lock *br_lck;
1502 br_lck = brl_get_locks_readonly(fsp);
1503 if (!br_lck)
1504 return false;
1506 return (brl_num_locks(br_lck) > 0);
1509 int find_share_mode_lease(struct share_mode_data *d,
1510 const struct GUID *client_guid,
1511 const struct smb2_lease_key *key)
1513 uint32_t i;
1515 for (i=0; i<d->num_leases; i++) {
1516 struct share_mode_lease *l = &d->leases[i];
1518 if (smb2_lease_equal(client_guid,
1519 key,
1520 &l->client_guid,
1521 &l->lease_key)) {
1522 return i;
1526 return -1;
1529 struct fsp_lease *find_fsp_lease(struct files_struct *new_fsp,
1530 const struct smb2_lease_key *key,
1531 const struct share_mode_lease *l)
1533 struct files_struct *fsp;
1536 * TODO: Measure how expensive this loop is with thousands of open
1537 * handles...
1540 for (fsp = file_find_di_first(new_fsp->conn->sconn, new_fsp->file_id);
1541 fsp != NULL;
1542 fsp = file_find_di_next(fsp)) {
1544 if (fsp == new_fsp) {
1545 continue;
1547 if (fsp->oplock_type != LEASE_OPLOCK) {
1548 continue;
1550 if (smb2_lease_key_equal(&fsp->lease->lease.lease_key, key)) {
1551 fsp->lease->ref_count += 1;
1552 return fsp->lease;
1556 /* Not found - must be leased in another smbd. */
1557 new_fsp->lease = talloc_zero(new_fsp->conn->sconn, struct fsp_lease);
1558 if (new_fsp->lease == NULL) {
1559 return NULL;
1561 new_fsp->lease->ref_count = 1;
1562 new_fsp->lease->sconn = new_fsp->conn->sconn;
1563 new_fsp->lease->lease.lease_key = *key;
1564 new_fsp->lease->lease.lease_state = l->current_state;
1566 * We internally treat all leases as V2 and update
1567 * the epoch, but when sending breaks it matters if
1568 * the requesting lease was v1 or v2.
1570 new_fsp->lease->lease.lease_version = l->lease_version;
1571 new_fsp->lease->lease.lease_epoch = l->epoch;
1572 return new_fsp->lease;
1575 static NTSTATUS grant_fsp_lease(struct files_struct *fsp,
1576 struct share_mode_lock *lck,
1577 const struct smb2_lease *lease,
1578 uint32_t *p_lease_idx,
1579 uint32_t granted)
1581 struct share_mode_data *d = lck->data;
1582 const struct GUID *client_guid = fsp_client_guid(fsp);
1583 struct share_mode_lease *tmp;
1584 NTSTATUS status;
1585 int idx;
1587 idx = find_share_mode_lease(d, client_guid, &lease->lease_key);
1589 if (idx != -1) {
1590 struct share_mode_lease *l = &d->leases[idx];
1591 bool do_upgrade;
1592 uint32_t existing, requested;
1594 fsp->lease = find_fsp_lease(fsp, &lease->lease_key, l);
1595 if (fsp->lease == NULL) {
1596 DEBUG(1, ("Did not find existing lease for file %s\n",
1597 fsp_str_dbg(fsp)));
1598 return NT_STATUS_NO_MEMORY;
1601 *p_lease_idx = idx;
1604 * Upgrade only if the requested lease is a strict upgrade.
1606 existing = l->current_state;
1607 requested = lease->lease_state;
1610 * Tricky: This test makes sure that "requested" is a
1611 * strict bitwise superset of "existing".
1613 do_upgrade = ((existing & requested) == existing);
1616 * Upgrade only if there's a change.
1618 do_upgrade &= (granted != existing);
1621 * Upgrade only if other leases don't prevent what was asked
1622 * for.
1624 do_upgrade &= (granted == requested);
1627 * only upgrade if we are not in breaking state
1629 do_upgrade &= !l->breaking;
1631 DEBUG(10, ("existing=%"PRIu32", requested=%"PRIu32", "
1632 "granted=%"PRIu32", do_upgrade=%d\n",
1633 existing, requested, granted, (int)do_upgrade));
1635 if (do_upgrade) {
1636 l->current_state = granted;
1637 l->epoch += 1;
1640 /* Ensure we're in sync with current lease state. */
1641 fsp_lease_update(lck, fsp_client_guid(fsp), fsp->lease);
1642 return NT_STATUS_OK;
1646 * Create new lease
1649 tmp = talloc_realloc(d, d->leases, struct share_mode_lease,
1650 d->num_leases+1);
1651 if (tmp == NULL) {
1653 * See [MS-SMB2]
1655 return NT_STATUS_INSUFFICIENT_RESOURCES;
1657 d->leases = tmp;
1659 fsp->lease = talloc_zero(fsp->conn->sconn, struct fsp_lease);
1660 if (fsp->lease == NULL) {
1661 return NT_STATUS_INSUFFICIENT_RESOURCES;
1663 fsp->lease->ref_count = 1;
1664 fsp->lease->sconn = fsp->conn->sconn;
1665 fsp->lease->lease.lease_version = lease->lease_version;
1666 fsp->lease->lease.lease_key = lease->lease_key;
1667 fsp->lease->lease.lease_state = granted;
1668 fsp->lease->lease.lease_epoch = lease->lease_epoch + 1;
1670 *p_lease_idx = d->num_leases;
1672 d->leases[d->num_leases] = (struct share_mode_lease) {
1673 .client_guid = *client_guid,
1674 .lease_key = fsp->lease->lease.lease_key,
1675 .current_state = fsp->lease->lease.lease_state,
1676 .lease_version = fsp->lease->lease.lease_version,
1677 .epoch = fsp->lease->lease.lease_epoch,
1680 status = leases_db_add(client_guid, &lease->lease_key,
1681 &fsp->file_id, fsp->fsp_name->base_name,
1682 fsp->fsp_name->stream_name);
1683 if (!NT_STATUS_IS_OK(status)) {
1684 DEBUG(10, ("%s: leases_db_add failed: %s\n", __func__,
1685 nt_errstr(status)));
1686 TALLOC_FREE(fsp->lease);
1687 return NT_STATUS_INSUFFICIENT_RESOURCES;
1690 d->num_leases += 1;
1691 d->modified = true;
1693 return NT_STATUS_OK;
1696 static bool is_same_lease(const files_struct *fsp,
1697 const struct share_mode_data *d,
1698 const struct share_mode_entry *e,
1699 const struct smb2_lease *lease)
1701 if (e->op_type != LEASE_OPLOCK) {
1702 return false;
1704 if (lease == NULL) {
1705 return false;
1708 return smb2_lease_equal(fsp_client_guid(fsp),
1709 &lease->lease_key,
1710 &d->leases[e->lease_idx].client_guid,
1711 &d->leases[e->lease_idx].lease_key);
1714 static NTSTATUS grant_fsp_oplock_type(struct smb_request *req,
1715 struct files_struct *fsp,
1716 struct share_mode_lock *lck,
1717 int oplock_request,
1718 struct smb2_lease *lease)
1720 struct share_mode_data *d = lck->data;
1721 bool got_handle_lease = false;
1722 bool got_oplock = false;
1723 uint32_t i;
1724 uint32_t granted;
1725 uint32_t lease_idx = UINT32_MAX;
1726 bool ok;
1727 NTSTATUS status;
1729 if (oplock_request & INTERNAL_OPEN_ONLY) {
1730 /* No oplocks on internal open. */
1731 oplock_request = NO_OPLOCK;
1732 DEBUG(10,("grant_fsp_oplock_type: oplock type 0x%x on file %s\n",
1733 fsp->oplock_type, fsp_str_dbg(fsp)));
1736 if (oplock_request == LEASE_OPLOCK) {
1737 if (lease == NULL) {
1739 * The SMB2 layer should have checked this
1741 return NT_STATUS_INTERNAL_ERROR;
1744 granted = lease->lease_state;
1746 if (lp_kernel_oplocks(SNUM(fsp->conn))) {
1747 DEBUG(10, ("No lease granted because kernel oplocks are enabled\n"));
1748 granted = SMB2_LEASE_NONE;
1750 if ((granted & (SMB2_LEASE_READ|SMB2_LEASE_WRITE)) == 0) {
1751 DEBUG(10, ("No read or write lease requested\n"));
1752 granted = SMB2_LEASE_NONE;
1754 if (granted == SMB2_LEASE_WRITE) {
1755 DEBUG(10, ("pure write lease requested\n"));
1756 granted = SMB2_LEASE_NONE;
1758 if (granted == (SMB2_LEASE_WRITE|SMB2_LEASE_HANDLE)) {
1759 DEBUG(10, ("write and handle lease requested\n"));
1760 granted = SMB2_LEASE_NONE;
1762 } else {
1763 granted = map_oplock_to_lease_type(
1764 oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK);
1767 if (lp_locking(fsp->conn->params) && file_has_brlocks(fsp)) {
1768 DEBUG(10,("grant_fsp_oplock_type: file %s has byte range locks\n",
1769 fsp_str_dbg(fsp)));
1770 granted &= ~SMB2_LEASE_READ;
1773 for (i=0; i<d->num_share_modes; i++) {
1774 struct share_mode_entry *e = &d->share_modes[i];
1775 uint32_t e_lease_type;
1777 e_lease_type = get_lease_type(d, e);
1779 if ((granted & SMB2_LEASE_WRITE) &&
1780 !is_same_lease(fsp, d, e, lease) &&
1781 !share_mode_stale_pid(d, i)) {
1783 * Can grant only one writer
1785 granted &= ~SMB2_LEASE_WRITE;
1788 if ((e_lease_type & SMB2_LEASE_HANDLE) && !got_handle_lease &&
1789 !share_mode_stale_pid(d, i)) {
1790 got_handle_lease = true;
1793 if ((e->op_type != LEASE_OPLOCK) && !got_oplock &&
1794 !share_mode_stale_pid(d, i)) {
1795 got_oplock = true;
1799 if ((granted & SMB2_LEASE_READ) && !(granted & SMB2_LEASE_WRITE)) {
1800 bool allow_level2 =
1801 (global_client_caps & CAP_LEVEL_II_OPLOCKS) &&
1802 lp_level2_oplocks(SNUM(fsp->conn));
1804 if (!allow_level2) {
1805 granted = SMB2_LEASE_NONE;
1809 if (oplock_request == LEASE_OPLOCK) {
1810 if (got_oplock) {
1811 granted &= ~SMB2_LEASE_HANDLE;
1814 fsp->oplock_type = LEASE_OPLOCK;
1816 status = grant_fsp_lease(fsp, lck, lease, &lease_idx,
1817 granted);
1818 if (!NT_STATUS_IS_OK(status)) {
1819 return status;
1822 *lease = fsp->lease->lease;
1823 DEBUG(10, ("lease_state=%d\n", lease->lease_state));
1824 } else {
1825 if (got_handle_lease) {
1826 granted = SMB2_LEASE_NONE;
1829 switch (granted) {
1830 case SMB2_LEASE_READ|SMB2_LEASE_WRITE|SMB2_LEASE_HANDLE:
1831 fsp->oplock_type = BATCH_OPLOCK|EXCLUSIVE_OPLOCK;
1832 break;
1833 case SMB2_LEASE_READ|SMB2_LEASE_WRITE:
1834 fsp->oplock_type = EXCLUSIVE_OPLOCK;
1835 break;
1836 case SMB2_LEASE_READ|SMB2_LEASE_HANDLE:
1837 case SMB2_LEASE_READ:
1838 fsp->oplock_type = LEVEL_II_OPLOCK;
1839 break;
1840 default:
1841 fsp->oplock_type = NO_OPLOCK;
1842 break;
1845 status = set_file_oplock(fsp);
1846 if (!NT_STATUS_IS_OK(status)) {
1848 * Could not get the kernel oplock
1850 fsp->oplock_type = NO_OPLOCK;
1854 ok = set_share_mode(lck, fsp, get_current_uid(fsp->conn),
1855 req ? req->mid : 0,
1856 fsp->oplock_type,
1857 lease_idx);
1858 if (!ok) {
1859 return NT_STATUS_NO_MEMORY;
1862 ok = update_num_read_oplocks(fsp, lck);
1863 if (!ok) {
1864 del_share_mode(lck, fsp);
1865 return NT_STATUS_INTERNAL_ERROR;
1868 DEBUG(10,("grant_fsp_oplock_type: oplock type 0x%x on file %s\n",
1869 fsp->oplock_type, fsp_str_dbg(fsp)));
1871 return NT_STATUS_OK;
1874 static bool request_timed_out(struct timeval request_time,
1875 struct timeval timeout)
1877 struct timeval now, end_time;
1878 GetTimeOfDay(&now);
1879 end_time = timeval_sum(&request_time, &timeout);
1880 return (timeval_compare(&end_time, &now) < 0);
1883 struct defer_open_state {
1884 struct smbXsrv_connection *xconn;
1885 uint64_t mid;
1888 static void defer_open_done(struct tevent_req *req);
1890 /****************************************************************************
1891 Handle the 1 second delay in returning a SHARING_VIOLATION error.
1892 ****************************************************************************/
1894 static void defer_open(struct share_mode_lock *lck,
1895 struct timeval request_time,
1896 struct timeval timeout,
1897 struct smb_request *req,
1898 struct deferred_open_record *state)
1900 struct deferred_open_record *open_rec;
1902 DEBUG(10,("defer_open_sharing_error: time [%u.%06u] adding deferred "
1903 "open entry for mid %llu\n",
1904 (unsigned int)request_time.tv_sec,
1905 (unsigned int)request_time.tv_usec,
1906 (unsigned long long)req->mid));
1908 open_rec = talloc(NULL, struct deferred_open_record);
1909 if (open_rec == NULL) {
1910 TALLOC_FREE(lck);
1911 exit_server("talloc failed");
1914 *open_rec = *state;
1916 if (lck) {
1917 struct defer_open_state *watch_state;
1918 struct tevent_req *watch_req;
1919 bool ret;
1921 watch_state = talloc(open_rec, struct defer_open_state);
1922 if (watch_state == NULL) {
1923 exit_server("talloc failed");
1925 watch_state->xconn = req->xconn;
1926 watch_state->mid = req->mid;
1928 DEBUG(10, ("defering mid %llu\n",
1929 (unsigned long long)req->mid));
1931 watch_req = dbwrap_record_watch_send(
1932 watch_state, req->sconn->ev_ctx, lck->data->record,
1933 req->sconn->msg_ctx);
1934 if (watch_req == NULL) {
1935 exit_server("Could not watch share mode record");
1937 tevent_req_set_callback(watch_req, defer_open_done,
1938 watch_state);
1940 ret = tevent_req_set_endtime(
1941 watch_req, req->sconn->ev_ctx,
1942 timeval_sum(&request_time, &timeout));
1943 SMB_ASSERT(ret);
1946 if (!push_deferred_open_message_smb(req, request_time, timeout,
1947 state->id, open_rec)) {
1948 TALLOC_FREE(lck);
1949 exit_server("push_deferred_open_message_smb failed");
1953 static void defer_open_done(struct tevent_req *req)
1955 struct defer_open_state *state = tevent_req_callback_data(
1956 req, struct defer_open_state);
1957 NTSTATUS status;
1958 bool ret;
1960 status = dbwrap_record_watch_recv(req, talloc_tos(), NULL);
1961 TALLOC_FREE(req);
1962 if (!NT_STATUS_IS_OK(status)) {
1963 DEBUG(5, ("dbwrap_record_watch_recv returned %s\n",
1964 nt_errstr(status)));
1966 * Even if it failed, retry anyway. TODO: We need a way to
1967 * tell a re-scheduled open about that error.
1971 DEBUG(10, ("scheduling mid %llu\n", (unsigned long long)state->mid));
1973 ret = schedule_deferred_open_message_smb(state->xconn, state->mid);
1974 SMB_ASSERT(ret);
1975 TALLOC_FREE(state);
1979 /****************************************************************************
1980 On overwrite open ensure that the attributes match.
1981 ****************************************************************************/
1983 static bool open_match_attributes(connection_struct *conn,
1984 uint32 old_dos_attr,
1985 uint32 new_dos_attr,
1986 mode_t existing_unx_mode,
1987 mode_t new_unx_mode,
1988 mode_t *returned_unx_mode)
1990 uint32 noarch_old_dos_attr, noarch_new_dos_attr;
1992 noarch_old_dos_attr = (old_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
1993 noarch_new_dos_attr = (new_dos_attr & ~FILE_ATTRIBUTE_ARCHIVE);
1995 if((noarch_old_dos_attr == 0 && noarch_new_dos_attr != 0) ||
1996 (noarch_old_dos_attr != 0 && ((noarch_old_dos_attr & noarch_new_dos_attr) == noarch_old_dos_attr))) {
1997 *returned_unx_mode = new_unx_mode;
1998 } else {
1999 *returned_unx_mode = (mode_t)0;
2002 DEBUG(10,("open_match_attributes: old_dos_attr = 0x%x, "
2003 "existing_unx_mode = 0%o, new_dos_attr = 0x%x "
2004 "returned_unx_mode = 0%o\n",
2005 (unsigned int)old_dos_attr,
2006 (unsigned int)existing_unx_mode,
2007 (unsigned int)new_dos_attr,
2008 (unsigned int)*returned_unx_mode ));
2010 /* If we're mapping SYSTEM and HIDDEN ensure they match. */
2011 if (lp_map_system(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
2012 if ((old_dos_attr & FILE_ATTRIBUTE_SYSTEM) &&
2013 !(new_dos_attr & FILE_ATTRIBUTE_SYSTEM)) {
2014 return False;
2017 if (lp_map_hidden(SNUM(conn)) || lp_store_dos_attributes(SNUM(conn))) {
2018 if ((old_dos_attr & FILE_ATTRIBUTE_HIDDEN) &&
2019 !(new_dos_attr & FILE_ATTRIBUTE_HIDDEN)) {
2020 return False;
2023 return True;
2026 /****************************************************************************
2027 Special FCB or DOS processing in the case of a sharing violation.
2028 Try and find a duplicated file handle.
2029 ****************************************************************************/
2031 static NTSTATUS fcb_or_dos_open(struct smb_request *req,
2032 connection_struct *conn,
2033 files_struct *fsp_to_dup_into,
2034 const struct smb_filename *smb_fname,
2035 struct file_id id,
2036 uint16 file_pid,
2037 uint64_t vuid,
2038 uint32 access_mask,
2039 uint32 share_access,
2040 uint32 create_options)
2042 files_struct *fsp;
2044 DEBUG(5,("fcb_or_dos_open: attempting old open semantics for "
2045 "file %s.\n", smb_fname_str_dbg(smb_fname)));
2047 for(fsp = file_find_di_first(conn->sconn, id); fsp;
2048 fsp = file_find_di_next(fsp)) {
2050 DEBUG(10,("fcb_or_dos_open: checking file %s, fd = %d, "
2051 "vuid = %llu, file_pid = %u, private_options = 0x%x "
2052 "access_mask = 0x%x\n", fsp_str_dbg(fsp),
2053 fsp->fh->fd, (unsigned long long)fsp->vuid,
2054 (unsigned int)fsp->file_pid,
2055 (unsigned int)fsp->fh->private_options,
2056 (unsigned int)fsp->access_mask ));
2058 if (fsp != fsp_to_dup_into &&
2059 fsp->fh->fd != -1 &&
2060 fsp->vuid == vuid &&
2061 fsp->file_pid == file_pid &&
2062 (fsp->fh->private_options & (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS |
2063 NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) &&
2064 (fsp->access_mask & FILE_WRITE_DATA) &&
2065 strequal(fsp->fsp_name->base_name, smb_fname->base_name) &&
2066 strequal(fsp->fsp_name->stream_name,
2067 smb_fname->stream_name)) {
2068 DEBUG(10,("fcb_or_dos_open: file match\n"));
2069 break;
2073 if (!fsp) {
2074 return NT_STATUS_NOT_FOUND;
2077 /* quite an insane set of semantics ... */
2078 if (is_executable(smb_fname->base_name) &&
2079 (fsp->fh->private_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS)) {
2080 DEBUG(10,("fcb_or_dos_open: file fail due to is_executable.\n"));
2081 return NT_STATUS_INVALID_PARAMETER;
2084 /* We need to duplicate this fsp. */
2085 return dup_file_fsp(req, fsp, access_mask, share_access,
2086 create_options, fsp_to_dup_into);
2089 static void schedule_defer_open(struct share_mode_lock *lck,
2090 struct file_id id,
2091 struct timeval request_time,
2092 struct smb_request *req)
2094 struct deferred_open_record state;
2096 /* This is a relative time, added to the absolute
2097 request_time value to get the absolute timeout time.
2098 Note that if this is the second or greater time we enter
2099 this codepath for this particular request mid then
2100 request_time is left as the absolute time of the *first*
2101 time this request mid was processed. This is what allows
2102 the request to eventually time out. */
2104 struct timeval timeout;
2106 /* Normally the smbd we asked should respond within
2107 * OPLOCK_BREAK_TIMEOUT seconds regardless of whether
2108 * the client did, give twice the timeout as a safety
2109 * measure here in case the other smbd is stuck
2110 * somewhere else. */
2112 timeout = timeval_set(OPLOCK_BREAK_TIMEOUT*2, 0);
2114 /* Nothing actually uses state.delayed_for_oplocks
2115 but it's handy to differentiate in debug messages
2116 between a 30 second delay due to oplock break, and
2117 a 1 second delay for share mode conflicts. */
2119 state.delayed_for_oplocks = True;
2120 state.async_open = false;
2121 state.id = id;
2123 if (!request_timed_out(request_time, timeout)) {
2124 defer_open(lck, request_time, timeout, req, &state);
2128 /****************************************************************************
2129 Reschedule an open call that went asynchronous.
2130 ****************************************************************************/
2132 static void schedule_async_open(struct timeval request_time,
2133 struct smb_request *req)
2135 struct deferred_open_record state;
2136 struct timeval timeout;
2138 timeout = timeval_set(20, 0);
2140 ZERO_STRUCT(state);
2141 state.delayed_for_oplocks = false;
2142 state.async_open = true;
2144 if (!request_timed_out(request_time, timeout)) {
2145 defer_open(NULL, request_time, timeout, req, &state);
2149 /****************************************************************************
2150 Work out what access_mask to use from what the client sent us.
2151 ****************************************************************************/
2153 static NTSTATUS smbd_calculate_maximum_allowed_access(
2154 connection_struct *conn,
2155 const struct smb_filename *smb_fname,
2156 bool use_privs,
2157 uint32_t *p_access_mask)
2159 struct security_descriptor *sd;
2160 uint32_t access_granted;
2161 NTSTATUS status;
2163 if (!use_privs && (get_current_uid(conn) == (uid_t)0)) {
2164 *p_access_mask |= FILE_GENERIC_ALL;
2165 return NT_STATUS_OK;
2168 status = SMB_VFS_GET_NT_ACL(conn, smb_fname->base_name,
2169 (SECINFO_OWNER |
2170 SECINFO_GROUP |
2171 SECINFO_DACL),
2172 talloc_tos(), &sd);
2174 if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
2176 * File did not exist
2178 *p_access_mask = FILE_GENERIC_ALL;
2179 return NT_STATUS_OK;
2181 if (!NT_STATUS_IS_OK(status)) {
2182 DEBUG(10,("Could not get acl on file %s: %s\n",
2183 smb_fname_str_dbg(smb_fname),
2184 nt_errstr(status)));
2185 return NT_STATUS_ACCESS_DENIED;
2189 * If we can access the path to this file, by
2190 * default we have FILE_READ_ATTRIBUTES from the
2191 * containing directory. See the section:
2192 * "Algorithm to Check Access to an Existing File"
2193 * in MS-FSA.pdf.
2195 * se_file_access_check()
2196 * also takes care of owner WRITE_DAC and READ_CONTROL.
2198 status = se_file_access_check(sd,
2199 get_current_nttok(conn),
2200 use_privs,
2201 (*p_access_mask & ~FILE_READ_ATTRIBUTES),
2202 &access_granted);
2204 TALLOC_FREE(sd);
2206 if (!NT_STATUS_IS_OK(status)) {
2207 DEBUG(10, ("Access denied on file %s: "
2208 "when calculating maximum access\n",
2209 smb_fname_str_dbg(smb_fname)));
2210 return NT_STATUS_ACCESS_DENIED;
2212 *p_access_mask = (access_granted | FILE_READ_ATTRIBUTES);
2214 if (!(access_granted & DELETE_ACCESS)) {
2215 if (can_delete_file_in_directory(conn, smb_fname)) {
2216 *p_access_mask |= DELETE_ACCESS;
2220 return NT_STATUS_OK;
2223 NTSTATUS smbd_calculate_access_mask(connection_struct *conn,
2224 const struct smb_filename *smb_fname,
2225 bool use_privs,
2226 uint32_t access_mask,
2227 uint32_t *access_mask_out)
2229 NTSTATUS status;
2230 uint32_t orig_access_mask = access_mask;
2231 uint32_t rejected_share_access;
2234 * Convert GENERIC bits to specific bits.
2237 se_map_generic(&access_mask, &file_generic_mapping);
2239 /* Calculate MAXIMUM_ALLOWED_ACCESS if requested. */
2240 if (access_mask & MAXIMUM_ALLOWED_ACCESS) {
2242 status = smbd_calculate_maximum_allowed_access(
2243 conn, smb_fname, use_privs, &access_mask);
2245 if (!NT_STATUS_IS_OK(status)) {
2246 return status;
2249 access_mask &= conn->share_access;
2252 rejected_share_access = access_mask & ~(conn->share_access);
2254 if (rejected_share_access) {
2255 DEBUG(10, ("smbd_calculate_access_mask: Access denied on "
2256 "file %s: rejected by share access mask[0x%08X] "
2257 "orig[0x%08X] mapped[0x%08X] reject[0x%08X]\n",
2258 smb_fname_str_dbg(smb_fname),
2259 conn->share_access,
2260 orig_access_mask, access_mask,
2261 rejected_share_access));
2262 return NT_STATUS_ACCESS_DENIED;
2265 *access_mask_out = access_mask;
2266 return NT_STATUS_OK;
2269 /****************************************************************************
2270 Remove the deferred open entry under lock.
2271 ****************************************************************************/
2273 /****************************************************************************
2274 Return true if this is a state pointer to an asynchronous create.
2275 ****************************************************************************/
2277 bool is_deferred_open_async(const struct deferred_open_record *rec)
2279 return rec->async_open;
2282 static bool clear_ads(uint32_t create_disposition)
2284 bool ret = false;
2286 switch (create_disposition) {
2287 case FILE_SUPERSEDE:
2288 case FILE_OVERWRITE_IF:
2289 case FILE_OVERWRITE:
2290 ret = true;
2291 break;
2292 default:
2293 break;
2295 return ret;
2298 static int disposition_to_open_flags(uint32_t create_disposition)
2300 int ret = 0;
2303 * Currently we're using FILE_SUPERSEDE as the same as
2304 * FILE_OVERWRITE_IF but they really are
2305 * different. FILE_SUPERSEDE deletes an existing file
2306 * (requiring delete access) then recreates it.
2309 switch (create_disposition) {
2310 case FILE_SUPERSEDE:
2311 case FILE_OVERWRITE_IF:
2313 * If file exists replace/overwrite. If file doesn't
2314 * exist create.
2316 ret = O_CREAT|O_TRUNC;
2317 break;
2319 case FILE_OPEN:
2321 * If file exists open. If file doesn't exist error.
2323 ret = 0;
2324 break;
2326 case FILE_OVERWRITE:
2328 * If file exists overwrite. If file doesn't exist
2329 * error.
2331 ret = O_TRUNC;
2332 break;
2334 case FILE_CREATE:
2336 * If file exists error. If file doesn't exist create.
2338 ret = O_CREAT|O_EXCL;
2339 break;
2341 case FILE_OPEN_IF:
2343 * If file exists open. If file doesn't exist create.
2345 ret = O_CREAT;
2346 break;
2348 return ret;
2351 static int calculate_open_access_flags(uint32_t access_mask,
2352 int oplock_request,
2353 uint32_t private_flags)
2355 bool need_write, need_read;
2358 * Note that we ignore the append flag as append does not
2359 * mean the same thing under DOS and Unix.
2362 need_write = (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA));
2363 if (!need_write) {
2364 return O_RDONLY;
2367 /* DENY_DOS opens are always underlying read-write on the
2368 file handle, no matter what the requested access mask
2369 says. */
2371 need_read =
2372 ((private_flags & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) ||
2373 access_mask & (FILE_READ_ATTRIBUTES|FILE_READ_DATA|
2374 FILE_READ_EA|FILE_EXECUTE));
2376 if (!need_read) {
2377 return O_WRONLY;
2379 return O_RDWR;
2382 /****************************************************************************
2383 Open a file with a share mode. Passed in an already created files_struct *.
2384 ****************************************************************************/
2386 static NTSTATUS open_file_ntcreate(connection_struct *conn,
2387 struct smb_request *req,
2388 uint32 access_mask, /* access bits (FILE_READ_DATA etc.) */
2389 uint32 share_access, /* share constants (FILE_SHARE_READ etc) */
2390 uint32 create_disposition, /* FILE_OPEN_IF etc. */
2391 uint32 create_options, /* options such as delete on close. */
2392 uint32 new_dos_attributes, /* attributes used for new file. */
2393 int oplock_request, /* internal Samba oplock codes. */
2394 struct smb2_lease *lease,
2395 /* Information (FILE_EXISTS etc.) */
2396 uint32_t private_flags, /* Samba specific flags. */
2397 int *pinfo,
2398 files_struct *fsp)
2400 struct smb_filename *smb_fname = fsp->fsp_name;
2401 int flags=0;
2402 int flags2=0;
2403 bool file_existed = VALID_STAT(smb_fname->st);
2404 bool def_acl = False;
2405 bool posix_open = False;
2406 bool new_file_created = False;
2407 bool first_open_attempt = true;
2408 NTSTATUS fsp_open = NT_STATUS_ACCESS_DENIED;
2409 mode_t new_unx_mode = (mode_t)0;
2410 mode_t unx_mode = (mode_t)0;
2411 int info;
2412 uint32 existing_dos_attributes = 0;
2413 struct timeval request_time = timeval_zero();
2414 struct share_mode_lock *lck = NULL;
2415 uint32 open_access_mask = access_mask;
2416 NTSTATUS status;
2417 char *parent_dir;
2418 SMB_STRUCT_STAT saved_stat = smb_fname->st;
2419 struct timespec old_write_time;
2420 struct file_id id;
2422 if (conn->printer) {
2424 * Printers are handled completely differently.
2425 * Most of the passed parameters are ignored.
2428 if (pinfo) {
2429 *pinfo = FILE_WAS_CREATED;
2432 DEBUG(10, ("open_file_ntcreate: printer open fname=%s\n",
2433 smb_fname_str_dbg(smb_fname)));
2435 if (!req) {
2436 DEBUG(0,("open_file_ntcreate: printer open without "
2437 "an SMB request!\n"));
2438 return NT_STATUS_INTERNAL_ERROR;
2441 return print_spool_open(fsp, smb_fname->base_name,
2442 req->vuid);
2445 if (!parent_dirname(talloc_tos(), smb_fname->base_name, &parent_dir,
2446 NULL)) {
2447 return NT_STATUS_NO_MEMORY;
2450 if (new_dos_attributes & FILE_FLAG_POSIX_SEMANTICS) {
2451 posix_open = True;
2452 unx_mode = (mode_t)(new_dos_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
2453 new_dos_attributes = 0;
2454 } else {
2455 /* Windows allows a new file to be created and
2456 silently removes a FILE_ATTRIBUTE_DIRECTORY
2457 sent by the client. Do the same. */
2459 new_dos_attributes &= ~FILE_ATTRIBUTE_DIRECTORY;
2461 /* We add FILE_ATTRIBUTE_ARCHIVE to this as this mode is only used if the file is
2462 * created new. */
2463 unx_mode = unix_mode(conn, new_dos_attributes | FILE_ATTRIBUTE_ARCHIVE,
2464 smb_fname, parent_dir);
2467 DEBUG(10, ("open_file_ntcreate: fname=%s, dos_attrs=0x%x "
2468 "access_mask=0x%x share_access=0x%x "
2469 "create_disposition = 0x%x create_options=0x%x "
2470 "unix mode=0%o oplock_request=%d private_flags = 0x%x\n",
2471 smb_fname_str_dbg(smb_fname), new_dos_attributes,
2472 access_mask, share_access, create_disposition,
2473 create_options, (unsigned int)unx_mode, oplock_request,
2474 (unsigned int)private_flags));
2476 if (req == NULL) {
2477 /* Ensure req == NULL means INTERNAL_OPEN_ONLY */
2478 SMB_ASSERT(((oplock_request & INTERNAL_OPEN_ONLY) != 0));
2479 } else {
2480 /* And req != NULL means no INTERNAL_OPEN_ONLY */
2481 SMB_ASSERT(((oplock_request & INTERNAL_OPEN_ONLY) == 0));
2485 * Only non-internal opens can be deferred at all
2488 if (req) {
2489 struct deferred_open_record *open_rec;
2490 if (get_deferred_open_message_state(req,
2491 &request_time,
2492 &open_rec)) {
2493 /* Remember the absolute time of the original
2494 request with this mid. We'll use it later to
2495 see if this has timed out. */
2497 /* If it was an async create retry, the file
2498 didn't exist. */
2500 if (is_deferred_open_async(open_rec)) {
2501 SET_STAT_INVALID(smb_fname->st);
2502 file_existed = false;
2505 /* Ensure we don't reprocess this message. */
2506 remove_deferred_open_message_smb(req->xconn, req->mid);
2508 first_open_attempt = false;
2512 if (!posix_open) {
2513 new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
2514 if (file_existed) {
2515 existing_dos_attributes = dos_mode(conn, smb_fname);
2519 /* ignore any oplock requests if oplocks are disabled */
2520 if (!lp_oplocks(SNUM(conn)) ||
2521 IS_VETO_OPLOCK_PATH(conn, smb_fname->base_name)) {
2522 /* Mask off everything except the private Samba bits. */
2523 oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
2526 /* this is for OS/2 long file names - say we don't support them */
2527 if (!lp_posix_pathnames() && strstr(smb_fname->base_name,".+,;=[].")) {
2528 /* OS/2 Workplace shell fix may be main code stream in a later
2529 * release. */
2530 DEBUG(5,("open_file_ntcreate: OS/2 long filenames are not "
2531 "supported.\n"));
2532 if (use_nt_status()) {
2533 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2535 return NT_STATUS_DOS(ERRDOS, ERRcannotopen);
2538 switch( create_disposition ) {
2539 case FILE_OPEN:
2540 /* If file exists open. If file doesn't exist error. */
2541 if (!file_existed) {
2542 DEBUG(5,("open_file_ntcreate: FILE_OPEN "
2543 "requested for file %s and file "
2544 "doesn't exist.\n",
2545 smb_fname_str_dbg(smb_fname)));
2546 errno = ENOENT;
2547 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2549 break;
2551 case FILE_OVERWRITE:
2552 /* If file exists overwrite. If file doesn't exist
2553 * error. */
2554 if (!file_existed) {
2555 DEBUG(5,("open_file_ntcreate: FILE_OVERWRITE "
2556 "requested for file %s and file "
2557 "doesn't exist.\n",
2558 smb_fname_str_dbg(smb_fname) ));
2559 errno = ENOENT;
2560 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
2562 break;
2564 case FILE_CREATE:
2565 /* If file exists error. If file doesn't exist
2566 * create. */
2567 if (file_existed) {
2568 DEBUG(5,("open_file_ntcreate: FILE_CREATE "
2569 "requested for file %s and file "
2570 "already exists.\n",
2571 smb_fname_str_dbg(smb_fname)));
2572 if (S_ISDIR(smb_fname->st.st_ex_mode)) {
2573 errno = EISDIR;
2574 } else {
2575 errno = EEXIST;
2577 return map_nt_error_from_unix(errno);
2579 break;
2581 case FILE_SUPERSEDE:
2582 case FILE_OVERWRITE_IF:
2583 case FILE_OPEN_IF:
2584 break;
2585 default:
2586 return NT_STATUS_INVALID_PARAMETER;
2589 flags2 = disposition_to_open_flags(create_disposition);
2591 /* We only care about matching attributes on file exists and
2592 * overwrite. */
2594 if (!posix_open && file_existed &&
2595 ((create_disposition == FILE_OVERWRITE) ||
2596 (create_disposition == FILE_OVERWRITE_IF))) {
2597 if (!open_match_attributes(conn, existing_dos_attributes,
2598 new_dos_attributes,
2599 smb_fname->st.st_ex_mode,
2600 unx_mode, &new_unx_mode)) {
2601 DEBUG(5,("open_file_ntcreate: attributes missmatch "
2602 "for file %s (%x %x) (0%o, 0%o)\n",
2603 smb_fname_str_dbg(smb_fname),
2604 existing_dos_attributes,
2605 new_dos_attributes,
2606 (unsigned int)smb_fname->st.st_ex_mode,
2607 (unsigned int)unx_mode ));
2608 errno = EACCES;
2609 return NT_STATUS_ACCESS_DENIED;
2613 status = smbd_calculate_access_mask(conn, smb_fname,
2614 false,
2615 access_mask,
2616 &access_mask);
2617 if (!NT_STATUS_IS_OK(status)) {
2618 DEBUG(10, ("open_file_ntcreate: smbd_calculate_access_mask "
2619 "on file %s returned %s\n",
2620 smb_fname_str_dbg(smb_fname), nt_errstr(status)));
2621 return status;
2624 open_access_mask = access_mask;
2626 if (flags2 & O_TRUNC) {
2627 open_access_mask |= FILE_WRITE_DATA; /* This will cause oplock breaks. */
2630 DEBUG(10, ("open_file_ntcreate: fname=%s, after mapping "
2631 "access_mask=0x%x\n", smb_fname_str_dbg(smb_fname),
2632 access_mask));
2635 * Note that we ignore the append flag as append does not
2636 * mean the same thing under DOS and Unix.
2639 flags = calculate_open_access_flags(access_mask, oplock_request,
2640 private_flags);
2643 * Currently we only look at FILE_WRITE_THROUGH for create options.
2646 #if defined(O_SYNC)
2647 if ((create_options & FILE_WRITE_THROUGH) && lp_strict_sync(SNUM(conn))) {
2648 flags2 |= O_SYNC;
2650 #endif /* O_SYNC */
2652 if (posix_open && (access_mask & FILE_APPEND_DATA)) {
2653 flags2 |= O_APPEND;
2656 if (!posix_open && !CAN_WRITE(conn)) {
2658 * We should really return a permission denied error if either
2659 * O_CREAT or O_TRUNC are set, but for compatibility with
2660 * older versions of Samba we just AND them out.
2662 flags2 &= ~(O_CREAT|O_TRUNC);
2665 if (first_open_attempt && lp_kernel_oplocks(SNUM(conn))) {
2667 * With kernel oplocks the open breaking an oplock
2668 * blocks until the oplock holder has given up the
2669 * oplock or closed the file. We prevent this by first
2670 * trying to open the file with O_NONBLOCK (see "man
2671 * fcntl" on Linux). For the second try, triggered by
2672 * an oplock break response, we do not need this
2673 * anymore.
2675 * This is true under the assumption that only Samba
2676 * requests kernel oplocks. Once someone else like
2677 * NFSv4 starts to use that API, we will have to
2678 * modify this by communicating with the NFSv4 server.
2680 flags2 |= O_NONBLOCK;
2684 * Ensure we can't write on a read-only share or file.
2687 if (flags != O_RDONLY && file_existed &&
2688 (!CAN_WRITE(conn) || IS_DOS_READONLY(existing_dos_attributes))) {
2689 DEBUG(5,("open_file_ntcreate: write access requested for "
2690 "file %s on read only %s\n",
2691 smb_fname_str_dbg(smb_fname),
2692 !CAN_WRITE(conn) ? "share" : "file" ));
2693 errno = EACCES;
2694 return NT_STATUS_ACCESS_DENIED;
2697 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
2698 fsp->share_access = share_access;
2699 fsp->fh->private_options = private_flags;
2700 fsp->access_mask = open_access_mask; /* We change this to the
2701 * requested access_mask after
2702 * the open is done. */
2703 fsp->posix_open = posix_open;
2705 if (timeval_is_zero(&request_time)) {
2706 request_time = fsp->open_time;
2710 * Ensure we pay attention to default ACLs on directories if required.
2713 if ((flags2 & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
2714 (def_acl = directory_has_default_acl(conn, parent_dir))) {
2715 unx_mode = (0777 & lp_create_mask(SNUM(conn)));
2718 DEBUG(4,("calling open_file with flags=0x%X flags2=0x%X mode=0%o, "
2719 "access_mask = 0x%x, open_access_mask = 0x%x\n",
2720 (unsigned int)flags, (unsigned int)flags2,
2721 (unsigned int)unx_mode, (unsigned int)access_mask,
2722 (unsigned int)open_access_mask));
2724 fsp_open = open_file(fsp, conn, req, parent_dir,
2725 flags|flags2, unx_mode, access_mask,
2726 open_access_mask, &new_file_created);
2728 if (NT_STATUS_EQUAL(fsp_open, NT_STATUS_NETWORK_BUSY)) {
2729 struct deferred_open_record state;
2732 * EWOULDBLOCK/EAGAIN maps to NETWORK_BUSY.
2734 if (file_existed && S_ISFIFO(fsp->fsp_name->st.st_ex_mode)) {
2735 DEBUG(10, ("FIFO busy\n"));
2736 return NT_STATUS_NETWORK_BUSY;
2738 if (req == NULL) {
2739 DEBUG(10, ("Internal open busy\n"));
2740 return NT_STATUS_NETWORK_BUSY;
2744 * From here on we assume this is an oplock break triggered
2747 lck = get_existing_share_mode_lock(talloc_tos(), fsp->file_id);
2748 if (lck == NULL) {
2749 state.delayed_for_oplocks = false;
2750 state.async_open = false;
2751 state.id = fsp->file_id;
2752 defer_open(NULL, request_time, timeval_set(0, 0),
2753 req, &state);
2754 DEBUG(10, ("No share mode lock found after "
2755 "EWOULDBLOCK, retrying sync\n"));
2756 return NT_STATUS_SHARING_VIOLATION;
2759 if (!validate_oplock_types(lck)) {
2760 smb_panic("validate_oplock_types failed");
2763 if (delay_for_oplock(fsp, 0, lease, lck, false,
2764 create_disposition, first_open_attempt)) {
2765 schedule_defer_open(lck, fsp->file_id, request_time,
2766 req);
2767 TALLOC_FREE(lck);
2768 DEBUG(10, ("Sent oplock break request to kernel "
2769 "oplock holder\n"));
2770 return NT_STATUS_SHARING_VIOLATION;
2774 * No oplock from Samba around. Immediately retry with
2775 * a blocking open.
2777 state.delayed_for_oplocks = false;
2778 state.async_open = false;
2779 state.id = fsp->file_id;
2780 defer_open(lck, request_time, timeval_set(0, 0), req, &state);
2781 TALLOC_FREE(lck);
2782 DEBUG(10, ("No Samba oplock around after EWOULDBLOCK. "
2783 "Retrying sync\n"));
2784 return NT_STATUS_SHARING_VIOLATION;
2787 if (!NT_STATUS_IS_OK(fsp_open)) {
2788 if (NT_STATUS_EQUAL(fsp_open, NT_STATUS_RETRY)) {
2789 schedule_async_open(request_time, req);
2791 return fsp_open;
2794 if (new_file_created) {
2796 * As we atomically create using O_CREAT|O_EXCL,
2797 * then if new_file_created is true, then
2798 * file_existed *MUST* have been false (even
2799 * if the file was previously detected as being
2800 * there).
2802 file_existed = false;
2805 if (file_existed && !check_same_dev_ino(&saved_stat, &smb_fname->st)) {
2807 * The file did exist, but some other (local or NFS)
2808 * process either renamed/unlinked and re-created the
2809 * file with different dev/ino after we walked the path,
2810 * but before we did the open. We could retry the
2811 * open but it's a rare enough case it's easier to
2812 * just fail the open to prevent creating any problems
2813 * in the open file db having the wrong dev/ino key.
2815 fd_close(fsp);
2816 DEBUG(1,("open_file_ntcreate: file %s - dev/ino mismatch. "
2817 "Old (dev=0x%llu, ino =0x%llu). "
2818 "New (dev=0x%llu, ino=0x%llu). Failing open "
2819 " with NT_STATUS_ACCESS_DENIED.\n",
2820 smb_fname_str_dbg(smb_fname),
2821 (unsigned long long)saved_stat.st_ex_dev,
2822 (unsigned long long)saved_stat.st_ex_ino,
2823 (unsigned long long)smb_fname->st.st_ex_dev,
2824 (unsigned long long)smb_fname->st.st_ex_ino));
2825 return NT_STATUS_ACCESS_DENIED;
2828 old_write_time = smb_fname->st.st_ex_mtime;
2831 * Deal with the race condition where two smbd's detect the
2832 * file doesn't exist and do the create at the same time. One
2833 * of them will win and set a share mode, the other (ie. this
2834 * one) should check if the requested share mode for this
2835 * create is allowed.
2839 * Now the file exists and fsp is successfully opened,
2840 * fsp->dev and fsp->inode are valid and should replace the
2841 * dev=0,inode=0 from a non existent file. Spotted by
2842 * Nadav Danieli <nadavd@exanet.com>. JRA.
2845 id = fsp->file_id;
2847 lck = get_share_mode_lock(talloc_tos(), id,
2848 conn->connectpath,
2849 smb_fname, &old_write_time);
2851 if (lck == NULL) {
2852 DEBUG(0, ("open_file_ntcreate: Could not get share "
2853 "mode lock for %s\n",
2854 smb_fname_str_dbg(smb_fname)));
2855 fd_close(fsp);
2856 return NT_STATUS_SHARING_VIOLATION;
2859 /* Get the types we need to examine. */
2860 if (!validate_oplock_types(lck)) {
2861 smb_panic("validate_oplock_types failed");
2864 if (has_delete_on_close(lck, fsp->name_hash)) {
2865 TALLOC_FREE(lck);
2866 fd_close(fsp);
2867 return NT_STATUS_DELETE_PENDING;
2870 status = open_mode_check(conn, lck,
2871 access_mask, share_access);
2873 if (NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION) ||
2874 (lck->data->num_share_modes > 0)) {
2876 * This comes from ancient times out of open_mode_check. I
2877 * have no clue whether this is still necessary. I can't think
2878 * of a case where this would actually matter further down in
2879 * this function. I leave it here for further investigation
2880 * :-)
2882 file_existed = true;
2885 if ((req != NULL) &&
2886 delay_for_oplock(
2887 fsp, oplock_request, lease, lck,
2888 NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION),
2889 create_disposition, first_open_attempt)) {
2890 schedule_defer_open(lck, fsp->file_id, request_time, req);
2891 TALLOC_FREE(lck);
2892 fd_close(fsp);
2893 return NT_STATUS_SHARING_VIOLATION;
2896 if (!NT_STATUS_IS_OK(status)) {
2897 uint32 can_access_mask;
2898 bool can_access = True;
2900 SMB_ASSERT(NT_STATUS_EQUAL(status, NT_STATUS_SHARING_VIOLATION));
2902 /* Check if this can be done with the deny_dos and fcb
2903 * calls. */
2904 if (private_flags &
2905 (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS|
2906 NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) {
2907 if (req == NULL) {
2908 DEBUG(0, ("DOS open without an SMB "
2909 "request!\n"));
2910 TALLOC_FREE(lck);
2911 fd_close(fsp);
2912 return NT_STATUS_INTERNAL_ERROR;
2915 /* Use the client requested access mask here,
2916 * not the one we open with. */
2917 status = fcb_or_dos_open(req,
2918 conn,
2919 fsp,
2920 smb_fname,
2922 req->smbpid,
2923 req->vuid,
2924 access_mask,
2925 share_access,
2926 create_options);
2928 if (NT_STATUS_IS_OK(status)) {
2929 TALLOC_FREE(lck);
2930 if (pinfo) {
2931 *pinfo = FILE_WAS_OPENED;
2933 return NT_STATUS_OK;
2938 * This next line is a subtlety we need for
2939 * MS-Access. If a file open will fail due to share
2940 * permissions and also for security (access) reasons,
2941 * we need to return the access failed error, not the
2942 * share error. We can't open the file due to kernel
2943 * oplock deadlock (it's possible we failed above on
2944 * the open_mode_check()) so use a userspace check.
2947 if (flags & O_RDWR) {
2948 can_access_mask = FILE_READ_DATA|FILE_WRITE_DATA;
2949 } else if (flags & O_WRONLY) {
2950 can_access_mask = FILE_WRITE_DATA;
2951 } else {
2952 can_access_mask = FILE_READ_DATA;
2955 if (((can_access_mask & FILE_WRITE_DATA) &&
2956 !CAN_WRITE(conn)) ||
2957 !NT_STATUS_IS_OK(smbd_check_access_rights(conn,
2958 smb_fname,
2959 false,
2960 can_access_mask))) {
2961 can_access = False;
2965 * If we're returning a share violation, ensure we
2966 * cope with the braindead 1 second delay (SMB1 only).
2969 if (!(oplock_request & INTERNAL_OPEN_ONLY) &&
2970 !conn->sconn->using_smb2 &&
2971 lp_defer_sharing_violations()) {
2972 struct timeval timeout;
2973 struct deferred_open_record state;
2974 int timeout_usecs;
2976 /* this is a hack to speed up torture tests
2977 in 'make test' */
2978 timeout_usecs = lp_parm_int(SNUM(conn),
2979 "smbd","sharedelay",
2980 SHARING_VIOLATION_USEC_WAIT);
2982 /* This is a relative time, added to the absolute
2983 request_time value to get the absolute timeout time.
2984 Note that if this is the second or greater time we enter
2985 this codepath for this particular request mid then
2986 request_time is left as the absolute time of the *first*
2987 time this request mid was processed. This is what allows
2988 the request to eventually time out. */
2990 timeout = timeval_set(0, timeout_usecs);
2992 /* Nothing actually uses state.delayed_for_oplocks
2993 but it's handy to differentiate in debug messages
2994 between a 30 second delay due to oplock break, and
2995 a 1 second delay for share mode conflicts. */
2997 state.delayed_for_oplocks = False;
2998 state.async_open = false;
2999 state.id = id;
3001 if ((req != NULL)
3002 && !request_timed_out(request_time,
3003 timeout)) {
3004 defer_open(lck, request_time, timeout,
3005 req, &state);
3009 TALLOC_FREE(lck);
3010 fd_close(fsp);
3011 if (can_access) {
3013 * We have detected a sharing violation here
3014 * so return the correct error code
3016 status = NT_STATUS_SHARING_VIOLATION;
3017 } else {
3018 status = NT_STATUS_ACCESS_DENIED;
3020 return status;
3023 /* Should we atomically (to the client at least) truncate ? */
3024 if ((!new_file_created) &&
3025 (flags2 & O_TRUNC) &&
3026 (!S_ISFIFO(fsp->fsp_name->st.st_ex_mode))) {
3027 int ret;
3029 ret = vfs_set_filelen(fsp, 0);
3030 if (ret != 0) {
3031 status = map_nt_error_from_unix(errno);
3032 TALLOC_FREE(lck);
3033 fd_close(fsp);
3034 return status;
3039 * We have the share entry *locked*.....
3042 /* Delete streams if create_disposition requires it */
3043 if (!new_file_created && clear_ads(create_disposition) &&
3044 !is_ntfs_stream_smb_fname(smb_fname)) {
3045 status = delete_all_streams(conn, smb_fname->base_name);
3046 if (!NT_STATUS_IS_OK(status)) {
3047 TALLOC_FREE(lck);
3048 fd_close(fsp);
3049 return status;
3053 /* note that we ignore failure for the following. It is
3054 basically a hack for NFS, and NFS will never set one of
3055 these only read them. Nobody but Samba can ever set a deny
3056 mode and we have already checked our more authoritative
3057 locking database for permission to set this deny mode. If
3058 the kernel refuses the operations then the kernel is wrong.
3059 note that GPFS supports it as well - jmcd */
3061 if (fsp->fh->fd != -1 && lp_kernel_share_modes(SNUM(conn))) {
3062 int ret_flock;
3063 ret_flock = SMB_VFS_KERNEL_FLOCK(fsp, share_access, access_mask);
3064 if(ret_flock == -1 ){
3066 TALLOC_FREE(lck);
3067 fd_close(fsp);
3069 return NT_STATUS_SHARING_VIOLATION;
3074 * At this point onwards, we can guarantee that the share entry
3075 * is locked, whether we created the file or not, and that the
3076 * deny mode is compatible with all current opens.
3080 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
3081 * but we don't have to store this - just ignore it on access check.
3083 if (conn->sconn->using_smb2) {
3085 * SMB2 doesn't return it (according to Microsoft tests).
3086 * Test Case: TestSuite_ScenarioNo009GrantedAccessTestS0
3087 * File created with access = 0x7 (Read, Write, Delete)
3088 * Query Info on file returns 0x87 (Read, Write, Delete, Read Attributes)
3090 fsp->access_mask = access_mask;
3091 } else {
3092 /* But SMB1 does. */
3093 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
3096 if (file_existed) {
3098 * stat opens on existing files don't get oplocks or leases.
3100 * Note that we check for stat open on the *open_access_mask*,
3101 * i.e. the access mask we actually used to do the open,
3102 * not the one the client asked for (which is in
3103 * fsp->access_mask). This is due to the fact that
3104 * FILE_OVERWRITE and FILE_OVERWRITE_IF add in O_TRUNC,
3105 * which adds FILE_WRITE_DATA to open_access_mask.
3107 if (is_stat_open(open_access_mask)) {
3108 if (lease) {
3109 lease->lease_state = SMB2_LEASE_NONE;
3110 } else {
3111 oplock_request = NO_OPLOCK;
3116 if (new_file_created) {
3117 info = FILE_WAS_CREATED;
3118 } else {
3119 if (flags2 & O_TRUNC) {
3120 info = FILE_WAS_OVERWRITTEN;
3121 } else {
3122 info = FILE_WAS_OPENED;
3126 if (pinfo) {
3127 *pinfo = info;
3131 * Setup the oplock info in both the shared memory and
3132 * file structs.
3134 status = grant_fsp_oplock_type(req, fsp, lck, oplock_request, lease);
3135 if (!NT_STATUS_IS_OK(status)) {
3136 TALLOC_FREE(lck);
3137 fd_close(fsp);
3138 return status;
3141 /* Handle strange delete on close create semantics. */
3142 if (create_options & FILE_DELETE_ON_CLOSE) {
3144 status = can_set_delete_on_close(fsp, new_dos_attributes);
3146 if (!NT_STATUS_IS_OK(status)) {
3147 /* Remember to delete the mode we just added. */
3148 del_share_mode(lck, fsp);
3149 TALLOC_FREE(lck);
3150 fd_close(fsp);
3151 return status;
3153 /* Note that here we set the *inital* delete on close flag,
3154 not the regular one. The magic gets handled in close. */
3155 fsp->initial_delete_on_close = True;
3158 if (info != FILE_WAS_OPENED) {
3159 /* Files should be initially set as archive */
3160 if (lp_map_archive(SNUM(conn)) ||
3161 lp_store_dos_attributes(SNUM(conn))) {
3162 if (!posix_open) {
3163 if (file_set_dosmode(conn, smb_fname,
3164 new_dos_attributes | FILE_ATTRIBUTE_ARCHIVE,
3165 parent_dir, true) == 0) {
3166 unx_mode = smb_fname->st.st_ex_mode;
3172 /* Determine sparse flag. */
3173 if (posix_open) {
3174 /* POSIX opens are sparse by default. */
3175 fsp->is_sparse = true;
3176 } else {
3177 fsp->is_sparse = (file_existed &&
3178 (existing_dos_attributes & FILE_ATTRIBUTE_SPARSE));
3182 * Take care of inherited ACLs on created files - if default ACL not
3183 * selected.
3186 if (!posix_open && new_file_created && !def_acl) {
3188 int saved_errno = errno; /* We might get ENOSYS in the next
3189 * call.. */
3191 if (SMB_VFS_FCHMOD_ACL(fsp, unx_mode) == -1 &&
3192 errno == ENOSYS) {
3193 errno = saved_errno; /* Ignore ENOSYS */
3196 } else if (new_unx_mode) {
3198 int ret = -1;
3200 /* Attributes need changing. File already existed. */
3203 int saved_errno = errno; /* We might get ENOSYS in the
3204 * next call.. */
3205 ret = SMB_VFS_FCHMOD_ACL(fsp, new_unx_mode);
3207 if (ret == -1 && errno == ENOSYS) {
3208 errno = saved_errno; /* Ignore ENOSYS */
3209 } else {
3210 DEBUG(5, ("open_file_ntcreate: reset "
3211 "attributes of file %s to 0%o\n",
3212 smb_fname_str_dbg(smb_fname),
3213 (unsigned int)new_unx_mode));
3214 ret = 0; /* Don't do the fchmod below. */
3218 if ((ret == -1) &&
3219 (SMB_VFS_FCHMOD(fsp, new_unx_mode) == -1))
3220 DEBUG(5, ("open_file_ntcreate: failed to reset "
3221 "attributes of file %s to 0%o\n",
3222 smb_fname_str_dbg(smb_fname),
3223 (unsigned int)new_unx_mode));
3228 * Deal with other opens having a modified write time.
3230 struct timespec write_time = get_share_mode_write_time(lck);
3232 if (!null_timespec(write_time)) {
3233 update_stat_ex_mtime(&fsp->fsp_name->st, write_time);
3237 TALLOC_FREE(lck);
3239 return NT_STATUS_OK;
3242 static NTSTATUS mkdir_internal(connection_struct *conn,
3243 struct smb_filename *smb_dname,
3244 uint32 file_attributes)
3246 mode_t mode;
3247 char *parent_dir = NULL;
3248 NTSTATUS status;
3249 bool posix_open = false;
3250 bool need_re_stat = false;
3251 uint32_t access_mask = SEC_DIR_ADD_SUBDIR;
3253 if (!CAN_WRITE(conn) || (access_mask & ~(conn->share_access))) {
3254 DEBUG(5,("mkdir_internal: failing share access "
3255 "%s\n", lp_servicename(talloc_tos(), SNUM(conn))));
3256 return NT_STATUS_ACCESS_DENIED;
3259 if (!parent_dirname(talloc_tos(), smb_dname->base_name, &parent_dir,
3260 NULL)) {
3261 return NT_STATUS_NO_MEMORY;
3264 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
3265 posix_open = true;
3266 mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
3267 } else {
3268 mode = unix_mode(conn, FILE_ATTRIBUTE_DIRECTORY, smb_dname, parent_dir);
3271 status = check_parent_access(conn,
3272 smb_dname,
3273 access_mask);
3274 if(!NT_STATUS_IS_OK(status)) {
3275 DEBUG(5,("mkdir_internal: check_parent_access "
3276 "on directory %s for path %s returned %s\n",
3277 parent_dir,
3278 smb_dname->base_name,
3279 nt_errstr(status) ));
3280 return status;
3283 if (SMB_VFS_MKDIR(conn, smb_dname->base_name, mode) != 0) {
3284 return map_nt_error_from_unix(errno);
3287 /* Ensure we're checking for a symlink here.... */
3288 /* We don't want to get caught by a symlink racer. */
3290 if (SMB_VFS_LSTAT(conn, smb_dname) == -1) {
3291 DEBUG(2, ("Could not stat directory '%s' just created: %s\n",
3292 smb_fname_str_dbg(smb_dname), strerror(errno)));
3293 return map_nt_error_from_unix(errno);
3296 if (!S_ISDIR(smb_dname->st.st_ex_mode)) {
3297 DEBUG(0, ("Directory '%s' just created is not a directory !\n",
3298 smb_fname_str_dbg(smb_dname)));
3299 return NT_STATUS_NOT_A_DIRECTORY;
3302 if (lp_store_dos_attributes(SNUM(conn))) {
3303 if (!posix_open) {
3304 file_set_dosmode(conn, smb_dname,
3305 file_attributes | FILE_ATTRIBUTE_DIRECTORY,
3306 parent_dir, true);
3310 if (lp_inherit_permissions(SNUM(conn))) {
3311 inherit_access_posix_acl(conn, parent_dir,
3312 smb_dname->base_name, mode);
3313 need_re_stat = true;
3316 if (!posix_open) {
3318 * Check if high bits should have been set,
3319 * then (if bits are missing): add them.
3320 * Consider bits automagically set by UNIX, i.e. SGID bit from parent
3321 * dir.
3323 if ((mode & ~(S_IRWXU|S_IRWXG|S_IRWXO)) &&
3324 (mode & ~smb_dname->st.st_ex_mode)) {
3325 SMB_VFS_CHMOD(conn, smb_dname->base_name,
3326 (smb_dname->st.st_ex_mode |
3327 (mode & ~smb_dname->st.st_ex_mode)));
3328 need_re_stat = true;
3332 /* Change the owner if required. */
3333 if (lp_inherit_owner(SNUM(conn))) {
3334 change_dir_owner_to_parent(conn, parent_dir,
3335 smb_dname->base_name,
3336 &smb_dname->st);
3337 need_re_stat = true;
3340 if (need_re_stat) {
3341 if (SMB_VFS_LSTAT(conn, smb_dname) == -1) {
3342 DEBUG(2, ("Could not stat directory '%s' just created: %s\n",
3343 smb_fname_str_dbg(smb_dname), strerror(errno)));
3344 return map_nt_error_from_unix(errno);
3348 notify_fname(conn, NOTIFY_ACTION_ADDED, FILE_NOTIFY_CHANGE_DIR_NAME,
3349 smb_dname->base_name);
3351 return NT_STATUS_OK;
3354 /****************************************************************************
3355 Open a directory from an NT SMB call.
3356 ****************************************************************************/
3358 static NTSTATUS open_directory(connection_struct *conn,
3359 struct smb_request *req,
3360 struct smb_filename *smb_dname,
3361 uint32 access_mask,
3362 uint32 share_access,
3363 uint32 create_disposition,
3364 uint32 create_options,
3365 uint32 file_attributes,
3366 int *pinfo,
3367 files_struct **result)
3369 files_struct *fsp = NULL;
3370 bool dir_existed = VALID_STAT(smb_dname->st) ? True : False;
3371 struct share_mode_lock *lck = NULL;
3372 NTSTATUS status;
3373 struct timespec mtimespec;
3374 int info = 0;
3375 bool ok;
3377 if (is_ntfs_stream_smb_fname(smb_dname)) {
3378 DEBUG(2, ("open_directory: %s is a stream name!\n",
3379 smb_fname_str_dbg(smb_dname)));
3380 return NT_STATUS_NOT_A_DIRECTORY;
3383 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS)) {
3384 /* Ensure we have a directory attribute. */
3385 file_attributes |= FILE_ATTRIBUTE_DIRECTORY;
3388 DEBUG(5,("open_directory: opening directory %s, access_mask = 0x%x, "
3389 "share_access = 0x%x create_options = 0x%x, "
3390 "create_disposition = 0x%x, file_attributes = 0x%x\n",
3391 smb_fname_str_dbg(smb_dname),
3392 (unsigned int)access_mask,
3393 (unsigned int)share_access,
3394 (unsigned int)create_options,
3395 (unsigned int)create_disposition,
3396 (unsigned int)file_attributes));
3398 status = smbd_calculate_access_mask(conn, smb_dname, false,
3399 access_mask, &access_mask);
3400 if (!NT_STATUS_IS_OK(status)) {
3401 DEBUG(10, ("open_directory: smbd_calculate_access_mask "
3402 "on file %s returned %s\n",
3403 smb_fname_str_dbg(smb_dname),
3404 nt_errstr(status)));
3405 return status;
3408 if ((access_mask & SEC_FLAG_SYSTEM_SECURITY) &&
3409 !security_token_has_privilege(get_current_nttok(conn),
3410 SEC_PRIV_SECURITY)) {
3411 DEBUG(10, ("open_directory: open on %s "
3412 "failed - SEC_FLAG_SYSTEM_SECURITY denied.\n",
3413 smb_fname_str_dbg(smb_dname)));
3414 return NT_STATUS_PRIVILEGE_NOT_HELD;
3417 switch( create_disposition ) {
3418 case FILE_OPEN:
3420 if (!dir_existed) {
3421 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
3424 info = FILE_WAS_OPENED;
3425 break;
3427 case FILE_CREATE:
3429 /* If directory exists error. If directory doesn't
3430 * exist create. */
3432 if (dir_existed) {
3433 status = NT_STATUS_OBJECT_NAME_COLLISION;
3434 DEBUG(2, ("open_directory: unable to create "
3435 "%s. Error was %s\n",
3436 smb_fname_str_dbg(smb_dname),
3437 nt_errstr(status)));
3438 return status;
3441 status = mkdir_internal(conn, smb_dname,
3442 file_attributes);
3444 if (!NT_STATUS_IS_OK(status)) {
3445 DEBUG(2, ("open_directory: unable to create "
3446 "%s. Error was %s\n",
3447 smb_fname_str_dbg(smb_dname),
3448 nt_errstr(status)));
3449 return status;
3452 info = FILE_WAS_CREATED;
3453 break;
3455 case FILE_OPEN_IF:
3457 * If directory exists open. If directory doesn't
3458 * exist create.
3461 if (dir_existed) {
3462 status = NT_STATUS_OK;
3463 info = FILE_WAS_OPENED;
3464 } else {
3465 status = mkdir_internal(conn, smb_dname,
3466 file_attributes);
3468 if (NT_STATUS_IS_OK(status)) {
3469 info = FILE_WAS_CREATED;
3470 } else {
3471 /* Cope with create race. */
3472 if (!NT_STATUS_EQUAL(status,
3473 NT_STATUS_OBJECT_NAME_COLLISION)) {
3474 DEBUG(2, ("open_directory: unable to create "
3475 "%s. Error was %s\n",
3476 smb_fname_str_dbg(smb_dname),
3477 nt_errstr(status)));
3478 return status;
3480 info = FILE_WAS_OPENED;
3484 break;
3486 case FILE_SUPERSEDE:
3487 case FILE_OVERWRITE:
3488 case FILE_OVERWRITE_IF:
3489 default:
3490 DEBUG(5,("open_directory: invalid create_disposition "
3491 "0x%x for directory %s\n",
3492 (unsigned int)create_disposition,
3493 smb_fname_str_dbg(smb_dname)));
3494 return NT_STATUS_INVALID_PARAMETER;
3497 if(!S_ISDIR(smb_dname->st.st_ex_mode)) {
3498 DEBUG(5,("open_directory: %s is not a directory !\n",
3499 smb_fname_str_dbg(smb_dname)));
3500 return NT_STATUS_NOT_A_DIRECTORY;
3503 if (info == FILE_WAS_OPENED) {
3504 status = smbd_check_access_rights(conn,
3505 smb_dname,
3506 false,
3507 access_mask);
3508 if (!NT_STATUS_IS_OK(status)) {
3509 DEBUG(10, ("open_directory: smbd_check_access_rights on "
3510 "file %s failed with %s\n",
3511 smb_fname_str_dbg(smb_dname),
3512 nt_errstr(status)));
3513 return status;
3517 status = file_new(req, conn, &fsp);
3518 if(!NT_STATUS_IS_OK(status)) {
3519 return status;
3523 * Setup the files_struct for it.
3526 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_dname->st);
3527 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
3528 fsp->file_pid = req ? req->smbpid : 0;
3529 fsp->can_lock = False;
3530 fsp->can_read = False;
3531 fsp->can_write = False;
3533 fsp->share_access = share_access;
3534 fsp->fh->private_options = 0;
3536 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
3538 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
3539 fsp->print_file = NULL;
3540 fsp->modified = False;
3541 fsp->oplock_type = NO_OPLOCK;
3542 fsp->sent_oplock_break = NO_BREAK_SENT;
3543 fsp->is_directory = True;
3544 fsp->posix_open = (file_attributes & FILE_FLAG_POSIX_SEMANTICS) ? True : False;
3545 status = fsp_set_smb_fname(fsp, smb_dname);
3546 if (!NT_STATUS_IS_OK(status)) {
3547 file_free(req, fsp);
3548 return status;
3551 /* Don't store old timestamps for directory
3552 handles in the internal database. We don't
3553 update them in there if new objects
3554 are creaded in the directory. Currently
3555 we only update timestamps on file writes.
3556 See bug #9870.
3558 ZERO_STRUCT(mtimespec);
3560 if (access_mask & (FILE_LIST_DIRECTORY|
3561 FILE_ADD_FILE|
3562 FILE_ADD_SUBDIRECTORY|
3563 FILE_TRAVERSE|
3564 DELETE_ACCESS|
3565 FILE_DELETE_CHILD)) {
3566 #ifdef O_DIRECTORY
3567 status = fd_open(conn, fsp, O_RDONLY|O_DIRECTORY, 0);
3568 #else
3569 /* POSIX allows us to open a directory with O_RDONLY. */
3570 status = fd_open(conn, fsp, O_RDONLY, 0);
3571 #endif
3572 if (!NT_STATUS_IS_OK(status)) {
3573 DEBUG(5, ("open_directory: Could not open fd for "
3574 "%s (%s)\n",
3575 smb_fname_str_dbg(smb_dname),
3576 nt_errstr(status)));
3577 file_free(req, fsp);
3578 return status;
3580 } else {
3581 fsp->fh->fd = -1;
3582 DEBUG(10, ("Not opening Directory %s\n",
3583 smb_fname_str_dbg(smb_dname)));
3586 status = vfs_stat_fsp(fsp);
3587 if (!NT_STATUS_IS_OK(status)) {
3588 fd_close(fsp);
3589 file_free(req, fsp);
3590 return status;
3593 /* Ensure there was no race condition. */
3594 if (!check_same_stat(&smb_dname->st, &fsp->fsp_name->st)) {
3595 DEBUG(5,("open_directory: stat struct differs for "
3596 "directory %s.\n",
3597 smb_fname_str_dbg(smb_dname)));
3598 fd_close(fsp);
3599 file_free(req, fsp);
3600 return NT_STATUS_ACCESS_DENIED;
3603 lck = get_share_mode_lock(talloc_tos(), fsp->file_id,
3604 conn->connectpath, smb_dname,
3605 &mtimespec);
3607 if (lck == NULL) {
3608 DEBUG(0, ("open_directory: Could not get share mode lock for "
3609 "%s\n", smb_fname_str_dbg(smb_dname)));
3610 fd_close(fsp);
3611 file_free(req, fsp);
3612 return NT_STATUS_SHARING_VIOLATION;
3615 if (has_delete_on_close(lck, fsp->name_hash)) {
3616 TALLOC_FREE(lck);
3617 fd_close(fsp);
3618 file_free(req, fsp);
3619 return NT_STATUS_DELETE_PENDING;
3622 status = open_mode_check(conn, lck,
3623 access_mask, share_access);
3625 if (!NT_STATUS_IS_OK(status)) {
3626 TALLOC_FREE(lck);
3627 fd_close(fsp);
3628 file_free(req, fsp);
3629 return status;
3632 ok = set_share_mode(lck, fsp, get_current_uid(conn),
3633 req ? req->mid : 0, NO_OPLOCK,
3634 UINT32_MAX);
3635 if (!ok) {
3636 TALLOC_FREE(lck);
3637 fd_close(fsp);
3638 file_free(req, fsp);
3639 return NT_STATUS_NO_MEMORY;
3642 /* For directories the delete on close bit at open time seems
3643 always to be honored on close... See test 19 in Samba4 BASE-DELETE. */
3644 if (create_options & FILE_DELETE_ON_CLOSE) {
3645 status = can_set_delete_on_close(fsp, 0);
3646 if (!NT_STATUS_IS_OK(status) && !NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
3647 del_share_mode(lck, fsp);
3648 TALLOC_FREE(lck);
3649 fd_close(fsp);
3650 file_free(req, fsp);
3651 return status;
3654 if (NT_STATUS_IS_OK(status)) {
3655 /* Note that here we set the *inital* delete on close flag,
3656 not the regular one. The magic gets handled in close. */
3657 fsp->initial_delete_on_close = True;
3663 * Deal with other opens having a modified write time. Is this
3664 * possible for directories?
3666 struct timespec write_time = get_share_mode_write_time(lck);
3668 if (!null_timespec(write_time)) {
3669 update_stat_ex_mtime(&fsp->fsp_name->st, write_time);
3673 TALLOC_FREE(lck);
3675 if (pinfo) {
3676 *pinfo = info;
3679 *result = fsp;
3680 return NT_STATUS_OK;
3683 NTSTATUS create_directory(connection_struct *conn, struct smb_request *req,
3684 struct smb_filename *smb_dname)
3686 NTSTATUS status;
3687 files_struct *fsp;
3689 status = SMB_VFS_CREATE_FILE(
3690 conn, /* conn */
3691 req, /* req */
3692 0, /* root_dir_fid */
3693 smb_dname, /* fname */
3694 FILE_READ_ATTRIBUTES, /* access_mask */
3695 FILE_SHARE_NONE, /* share_access */
3696 FILE_CREATE, /* create_disposition*/
3697 FILE_DIRECTORY_FILE, /* create_options */
3698 FILE_ATTRIBUTE_DIRECTORY, /* file_attributes */
3699 0, /* oplock_request */
3700 NULL, /* lease */
3701 0, /* allocation_size */
3702 0, /* private_flags */
3703 NULL, /* sd */
3704 NULL, /* ea_list */
3705 &fsp, /* result */
3706 NULL, /* pinfo */
3707 NULL, NULL); /* create context */
3709 if (NT_STATUS_IS_OK(status)) {
3710 close_file(req, fsp, NORMAL_CLOSE);
3713 return status;
3716 /****************************************************************************
3717 Receive notification that one of our open files has been renamed by another
3718 smbd process.
3719 ****************************************************************************/
3721 void msg_file_was_renamed(struct messaging_context *msg,
3722 void *private_data,
3723 uint32_t msg_type,
3724 struct server_id server_id,
3725 DATA_BLOB *data)
3727 files_struct *fsp;
3728 char *frm = (char *)data->data;
3729 struct file_id id;
3730 const char *sharepath;
3731 const char *base_name;
3732 const char *stream_name;
3733 struct smb_filename *smb_fname = NULL;
3734 size_t sp_len, bn_len;
3735 NTSTATUS status;
3736 struct smbd_server_connection *sconn =
3737 talloc_get_type_abort(private_data,
3738 struct smbd_server_connection);
3740 if (data->data == NULL
3741 || data->length < MSG_FILE_RENAMED_MIN_SIZE + 2) {
3742 DEBUG(0, ("msg_file_was_renamed: Got invalid msg len %d\n",
3743 (int)data->length));
3744 return;
3747 /* Unpack the message. */
3748 pull_file_id_24(frm, &id);
3749 sharepath = &frm[24];
3750 sp_len = strlen(sharepath);
3751 base_name = sharepath + sp_len + 1;
3752 bn_len = strlen(base_name);
3753 stream_name = sharepath + sp_len + 1 + bn_len + 1;
3755 /* stream_name must always be NULL if there is no stream. */
3756 if (stream_name[0] == '\0') {
3757 stream_name = NULL;
3760 smb_fname = synthetic_smb_fname(talloc_tos(), base_name,
3761 stream_name, NULL);
3762 if (smb_fname == NULL) {
3763 return;
3766 DEBUG(10,("msg_file_was_renamed: Got rename message for sharepath %s, new name %s, "
3767 "file_id %s\n",
3768 sharepath, smb_fname_str_dbg(smb_fname),
3769 file_id_string_tos(&id)));
3771 for(fsp = file_find_di_first(sconn, id); fsp;
3772 fsp = file_find_di_next(fsp)) {
3773 if (memcmp(fsp->conn->connectpath, sharepath, sp_len) == 0) {
3775 DEBUG(10,("msg_file_was_renamed: renaming file %s from %s -> %s\n",
3776 fsp_fnum_dbg(fsp), fsp_str_dbg(fsp),
3777 smb_fname_str_dbg(smb_fname)));
3778 status = fsp_set_smb_fname(fsp, smb_fname);
3779 if (!NT_STATUS_IS_OK(status)) {
3780 goto out;
3782 } else {
3783 /* TODO. JRA. */
3784 /* Now we have the complete path we can work out if this is
3785 actually within this share and adjust newname accordingly. */
3786 DEBUG(10,("msg_file_was_renamed: share mismatch (sharepath %s "
3787 "not sharepath %s) "
3788 "%s from %s -> %s\n",
3789 fsp->conn->connectpath,
3790 sharepath,
3791 fsp_fnum_dbg(fsp),
3792 fsp_str_dbg(fsp),
3793 smb_fname_str_dbg(smb_fname)));
3796 out:
3797 TALLOC_FREE(smb_fname);
3798 return;
3802 * If a main file is opened for delete, all streams need to be checked for
3803 * !FILE_SHARE_DELETE. Do this by opening with DELETE_ACCESS.
3804 * If that works, delete them all by setting the delete on close and close.
3807 NTSTATUS open_streams_for_delete(connection_struct *conn,
3808 const char *fname)
3810 struct stream_struct *stream_info = NULL;
3811 files_struct **streams = NULL;
3812 int i;
3813 unsigned int num_streams = 0;
3814 TALLOC_CTX *frame = talloc_stackframe();
3815 NTSTATUS status;
3817 status = vfs_streaminfo(conn, NULL, fname, talloc_tos(),
3818 &num_streams, &stream_info);
3820 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
3821 || NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
3822 DEBUG(10, ("no streams around\n"));
3823 TALLOC_FREE(frame);
3824 return NT_STATUS_OK;
3827 if (!NT_STATUS_IS_OK(status)) {
3828 DEBUG(10, ("vfs_streaminfo failed: %s\n",
3829 nt_errstr(status)));
3830 goto fail;
3833 DEBUG(10, ("open_streams_for_delete found %d streams\n",
3834 num_streams));
3836 if (num_streams == 0) {
3837 TALLOC_FREE(frame);
3838 return NT_STATUS_OK;
3841 streams = talloc_array(talloc_tos(), files_struct *, num_streams);
3842 if (streams == NULL) {
3843 DEBUG(0, ("talloc failed\n"));
3844 status = NT_STATUS_NO_MEMORY;
3845 goto fail;
3848 for (i=0; i<num_streams; i++) {
3849 struct smb_filename *smb_fname;
3851 if (strequal(stream_info[i].name, "::$DATA")) {
3852 streams[i] = NULL;
3853 continue;
3856 smb_fname = synthetic_smb_fname(
3857 talloc_tos(), fname, stream_info[i].name, NULL);
3858 if (smb_fname == NULL) {
3859 status = NT_STATUS_NO_MEMORY;
3860 goto fail;
3863 if (SMB_VFS_STAT(conn, smb_fname) == -1) {
3864 DEBUG(10, ("Unable to stat stream: %s\n",
3865 smb_fname_str_dbg(smb_fname)));
3868 status = SMB_VFS_CREATE_FILE(
3869 conn, /* conn */
3870 NULL, /* req */
3871 0, /* root_dir_fid */
3872 smb_fname, /* fname */
3873 DELETE_ACCESS, /* access_mask */
3874 (FILE_SHARE_READ | /* share_access */
3875 FILE_SHARE_WRITE | FILE_SHARE_DELETE),
3876 FILE_OPEN, /* create_disposition*/
3877 0, /* create_options */
3878 FILE_ATTRIBUTE_NORMAL, /* file_attributes */
3879 0, /* oplock_request */
3880 NULL, /* lease */
3881 0, /* allocation_size */
3882 NTCREATEX_OPTIONS_PRIVATE_STREAM_DELETE, /* private_flags */
3883 NULL, /* sd */
3884 NULL, /* ea_list */
3885 &streams[i], /* result */
3886 NULL, /* pinfo */
3887 NULL, NULL); /* create context */
3889 if (!NT_STATUS_IS_OK(status)) {
3890 DEBUG(10, ("Could not open stream %s: %s\n",
3891 smb_fname_str_dbg(smb_fname),
3892 nt_errstr(status)));
3894 TALLOC_FREE(smb_fname);
3895 break;
3897 TALLOC_FREE(smb_fname);
3901 * don't touch the variable "status" beyond this point :-)
3904 for (i -= 1 ; i >= 0; i--) {
3905 if (streams[i] == NULL) {
3906 continue;
3909 DEBUG(10, ("Closing stream # %d, %s\n", i,
3910 fsp_str_dbg(streams[i])));
3911 close_file(NULL, streams[i], NORMAL_CLOSE);
3914 fail:
3915 TALLOC_FREE(frame);
3916 return status;
3919 /*********************************************************************
3920 Create a default ACL by inheriting from the parent. If no inheritance
3921 from the parent available, don't set anything. This will leave the actual
3922 permissions the new file or directory already got from the filesystem
3923 as the NT ACL when read.
3924 *********************************************************************/
3926 static NTSTATUS inherit_new_acl(files_struct *fsp)
3928 TALLOC_CTX *frame = talloc_stackframe();
3929 char *parent_name = NULL;
3930 struct security_descriptor *parent_desc = NULL;
3931 NTSTATUS status = NT_STATUS_OK;
3932 struct security_descriptor *psd = NULL;
3933 const struct dom_sid *owner_sid = NULL;
3934 const struct dom_sid *group_sid = NULL;
3935 uint32_t security_info_sent = (SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL);
3936 struct security_token *token = fsp->conn->session_info->security_token;
3937 bool inherit_owner = lp_inherit_owner(SNUM(fsp->conn));
3938 bool inheritable_components = false;
3939 bool try_builtin_administrators = false;
3940 const struct dom_sid *BA_U_sid = NULL;
3941 const struct dom_sid *BA_G_sid = NULL;
3942 bool try_system = false;
3943 const struct dom_sid *SY_U_sid = NULL;
3944 const struct dom_sid *SY_G_sid = NULL;
3945 size_t size = 0;
3947 if (!parent_dirname(frame, fsp->fsp_name->base_name, &parent_name, NULL)) {
3948 TALLOC_FREE(frame);
3949 return NT_STATUS_NO_MEMORY;
3952 status = SMB_VFS_GET_NT_ACL(fsp->conn,
3953 parent_name,
3954 (SECINFO_OWNER | SECINFO_GROUP | SECINFO_DACL),
3955 frame,
3956 &parent_desc);
3957 if (!NT_STATUS_IS_OK(status)) {
3958 TALLOC_FREE(frame);
3959 return status;
3962 inheritable_components = sd_has_inheritable_components(parent_desc,
3963 fsp->is_directory);
3965 if (!inheritable_components && !inherit_owner) {
3966 TALLOC_FREE(frame);
3967 /* Nothing to inherit and not setting owner. */
3968 return NT_STATUS_OK;
3971 /* Create an inherited descriptor from the parent. */
3973 if (DEBUGLEVEL >= 10) {
3974 DEBUG(10,("inherit_new_acl: parent acl for %s is:\n",
3975 fsp_str_dbg(fsp) ));
3976 NDR_PRINT_DEBUG(security_descriptor, parent_desc);
3979 /* Inherit from parent descriptor if "inherit owner" set. */
3980 if (inherit_owner) {
3981 owner_sid = parent_desc->owner_sid;
3982 group_sid = parent_desc->group_sid;
3985 if (owner_sid == NULL) {
3986 if (security_token_has_builtin_administrators(token)) {
3987 try_builtin_administrators = true;
3988 } else if (security_token_is_system(token)) {
3989 try_builtin_administrators = true;
3990 try_system = true;
3994 if (group_sid == NULL &&
3995 token->num_sids == PRIMARY_GROUP_SID_INDEX)
3997 if (security_token_is_system(token)) {
3998 try_builtin_administrators = true;
3999 try_system = true;
4003 if (try_builtin_administrators) {
4004 struct unixid ids;
4005 bool ok;
4007 ZERO_STRUCT(ids);
4008 ok = sids_to_unixids(&global_sid_Builtin_Administrators, 1, &ids);
4009 if (ok) {
4010 switch (ids.type) {
4011 case ID_TYPE_BOTH:
4012 BA_U_sid = &global_sid_Builtin_Administrators;
4013 BA_G_sid = &global_sid_Builtin_Administrators;
4014 break;
4015 case ID_TYPE_UID:
4016 BA_U_sid = &global_sid_Builtin_Administrators;
4017 break;
4018 case ID_TYPE_GID:
4019 BA_G_sid = &global_sid_Builtin_Administrators;
4020 break;
4021 default:
4022 break;
4027 if (try_system) {
4028 struct unixid ids;
4029 bool ok;
4031 ZERO_STRUCT(ids);
4032 ok = sids_to_unixids(&global_sid_System, 1, &ids);
4033 if (ok) {
4034 switch (ids.type) {
4035 case ID_TYPE_BOTH:
4036 SY_U_sid = &global_sid_System;
4037 SY_G_sid = &global_sid_System;
4038 break;
4039 case ID_TYPE_UID:
4040 SY_U_sid = &global_sid_System;
4041 break;
4042 case ID_TYPE_GID:
4043 SY_G_sid = &global_sid_System;
4044 break;
4045 default:
4046 break;
4051 if (owner_sid == NULL) {
4052 owner_sid = BA_U_sid;
4055 if (owner_sid == NULL) {
4056 owner_sid = SY_U_sid;
4059 if (group_sid == NULL) {
4060 group_sid = SY_G_sid;
4063 if (try_system && group_sid == NULL) {
4064 group_sid = BA_G_sid;
4067 if (owner_sid == NULL) {
4068 owner_sid = &token->sids[PRIMARY_USER_SID_INDEX];
4070 if (group_sid == NULL) {
4071 if (token->num_sids == PRIMARY_GROUP_SID_INDEX) {
4072 group_sid = &token->sids[PRIMARY_USER_SID_INDEX];
4073 } else {
4074 group_sid = &token->sids[PRIMARY_GROUP_SID_INDEX];
4078 status = se_create_child_secdesc(frame,
4079 &psd,
4080 &size,
4081 parent_desc,
4082 owner_sid,
4083 group_sid,
4084 fsp->is_directory);
4085 if (!NT_STATUS_IS_OK(status)) {
4086 TALLOC_FREE(frame);
4087 return status;
4090 /* If inheritable_components == false,
4091 se_create_child_secdesc()
4092 creates a security desriptor with a NULL dacl
4093 entry, but with SEC_DESC_DACL_PRESENT. We need
4094 to remove that flag. */
4096 if (!inheritable_components) {
4097 security_info_sent &= ~SECINFO_DACL;
4098 psd->type &= ~SEC_DESC_DACL_PRESENT;
4101 if (DEBUGLEVEL >= 10) {
4102 DEBUG(10,("inherit_new_acl: child acl for %s is:\n",
4103 fsp_str_dbg(fsp) ));
4104 NDR_PRINT_DEBUG(security_descriptor, psd);
4107 if (inherit_owner) {
4108 /* We need to be root to force this. */
4109 become_root();
4111 status = SMB_VFS_FSET_NT_ACL(fsp,
4112 security_info_sent,
4113 psd);
4114 if (inherit_owner) {
4115 unbecome_root();
4117 TALLOC_FREE(frame);
4118 return status;
4122 * If we already have a lease, it must match the new file id. [MS-SMB2]
4123 * 3.3.5.9.8 speaks about INVALID_PARAMETER if an already used lease key is
4124 * used for a different file name.
4127 struct lease_fname_match_state {
4128 /* Input parameters. */
4129 const struct smb_filename *fname;
4130 bool file_existed;
4131 struct file_id id;
4132 /* Return parameters. */
4133 uint32_t num_file_ids;
4134 struct file_id *ids;
4135 NTSTATUS match_status;
4138 static void lease_fname_match_parser(
4139 uint32_t num_file_ids,
4140 struct file_id *ids, const char *filename, const char *stream_name,
4141 void *private_data)
4143 struct lease_fname_match_state *state =
4144 (struct lease_fname_match_state *)private_data;
4146 if (!strequal(filename, state->fname->base_name) ||
4147 !strequal(stream_name, state->fname->stream_name))
4149 /* Names don't match lease key. */
4150 state->match_status = NT_STATUS_INVALID_PARAMETER;
4151 return;
4154 if (state->file_existed &&
4155 num_file_ids == 1 &&
4156 file_id_equal(&ids[0],&state->id))
4158 /* Common case - non-dynamic share. We're ok.. */
4159 state->match_status = NT_STATUS_OK;
4160 return;
4164 * More than one file id, or not equal, or new file
4165 * being created and there's already an existing lease
4166 * on this (client_guid, lease id) pair.
4167 * Don't allow leases.
4170 state->match_status = NT_STATUS_OPLOCK_NOT_GRANTED;
4171 state->num_file_ids = num_file_ids;
4172 state->ids = talloc_memdup(talloc_tos(),
4173 ids,
4174 num_file_ids * sizeof(struct file_id));
4175 if (state->ids == NULL) {
4176 state->match_status = NT_STATUS_NO_MEMORY;
4180 static NTSTATUS lease_match(connection_struct *conn,
4181 struct smb_request *req,
4182 struct smb2_lease_key *lease_key,
4183 const struct smb_filename *fname,
4184 uint16_t *p_version,
4185 uint16_t *p_epoch)
4187 struct smbd_server_connection *sconn = req->sconn;
4188 struct lease_fname_match_state state = {
4189 .fname = fname,
4190 .match_status = NT_STATUS_OK
4192 uint32_t i;
4193 NTSTATUS status;
4195 state.file_existed = VALID_STAT(fname->st);
4196 if (state.file_existed) {
4197 state.id = vfs_file_id_from_sbuf(conn, &fname->st);
4198 } else {
4199 memset(&state.id, '\0', sizeof(state.id));
4202 status = leases_db_parse(&sconn->client->connections->smb2.client.guid,
4203 lease_key, lease_fname_match_parser, &state);
4204 if (!NT_STATUS_IS_OK(status)) {
4206 * Not found or error means okay: We can make the lease pass
4208 return NT_STATUS_OK;
4210 if (!NT_STATUS_EQUAL(state.match_status, NT_STATUS_OPLOCK_NOT_GRANTED)) {
4212 * Anything but NT_STATUS_OPLOCK_NOT_GRANTED, let the caller
4213 * deal with it.
4215 return state.match_status;
4218 /* We have to break all existing leases. */
4219 for (i = 0; i < state.num_file_ids; i++) {
4220 struct share_mode_lock *lck;
4221 struct share_mode_data *d;
4222 uint32_t j;
4224 if (file_id_equal(&state.ids[i], &state.id)) {
4225 /* Don't need to break our own file. */
4226 continue;
4229 lck = get_existing_share_mode_lock(talloc_tos(), state.ids[i]);
4230 if (lck == NULL) {
4231 /* Race condition - file already closed. */
4232 continue;
4234 d = lck->data;
4235 for (j=0; j<d->num_share_modes; j++) {
4236 struct share_mode_entry *e = &d->share_modes[j];
4237 uint32_t e_lease_type = get_lease_type(d, e);
4238 struct share_mode_lease *l = NULL;
4240 if (share_mode_stale_pid(d, j)) {
4241 continue;
4244 if (e->op_type == LEASE_OPLOCK) {
4245 l = &lck->data->leases[e->lease_idx];
4246 if (!smb2_lease_key_equal(&l->lease_key,
4247 lease_key)) {
4248 continue;
4250 *p_epoch = l->epoch;
4251 *p_version = l->lease_version;
4254 if (e_lease_type == SMB2_LEASE_NONE) {
4255 continue;
4258 send_break_message(conn->sconn->msg_ctx, e,
4259 SMB2_LEASE_NONE);
4262 * Windows 7 and 8 lease clients
4263 * are broken in that they will not
4264 * respond to lease break requests
4265 * whilst waiting for an outstanding
4266 * open request on that lease handle
4267 * on the same TCP connection, due
4268 * to holding an internal inode lock.
4270 * This means we can't reschedule
4271 * ourselves here, but must return
4272 * from the create.
4274 * Work around:
4276 * Send the breaks and then return
4277 * SMB2_LEASE_NONE in the lease handle
4278 * to cause them to acknowledge the
4279 * lease break. Consulatation with
4280 * Microsoft engineering confirmed
4281 * this approach is safe.
4285 TALLOC_FREE(lck);
4288 * Ensure we don't grant anything more so we
4289 * never upgrade.
4291 return NT_STATUS_OPLOCK_NOT_GRANTED;
4295 * Wrapper around open_file_ntcreate and open_directory
4298 static NTSTATUS create_file_unixpath(connection_struct *conn,
4299 struct smb_request *req,
4300 struct smb_filename *smb_fname,
4301 uint32_t access_mask,
4302 uint32_t share_access,
4303 uint32_t create_disposition,
4304 uint32_t create_options,
4305 uint32_t file_attributes,
4306 uint32_t oplock_request,
4307 struct smb2_lease *lease,
4308 uint64_t allocation_size,
4309 uint32_t private_flags,
4310 struct security_descriptor *sd,
4311 struct ea_list *ea_list,
4313 files_struct **result,
4314 int *pinfo)
4316 int info = FILE_WAS_OPENED;
4317 files_struct *base_fsp = NULL;
4318 files_struct *fsp = NULL;
4319 NTSTATUS status;
4321 DEBUG(10,("create_file_unixpath: access_mask = 0x%x "
4322 "file_attributes = 0x%x, share_access = 0x%x, "
4323 "create_disposition = 0x%x create_options = 0x%x "
4324 "oplock_request = 0x%x private_flags = 0x%x "
4325 "ea_list = 0x%p, sd = 0x%p, "
4326 "fname = %s\n",
4327 (unsigned int)access_mask,
4328 (unsigned int)file_attributes,
4329 (unsigned int)share_access,
4330 (unsigned int)create_disposition,
4331 (unsigned int)create_options,
4332 (unsigned int)oplock_request,
4333 (unsigned int)private_flags,
4334 ea_list, sd, smb_fname_str_dbg(smb_fname)));
4336 if (create_options & FILE_OPEN_BY_FILE_ID) {
4337 status = NT_STATUS_NOT_SUPPORTED;
4338 goto fail;
4341 if (create_options & NTCREATEX_OPTIONS_INVALID_PARAM_MASK) {
4342 status = NT_STATUS_INVALID_PARAMETER;
4343 goto fail;
4346 if (req == NULL) {
4347 oplock_request |= INTERNAL_OPEN_ONLY;
4350 if (lease != NULL) {
4351 uint16_t epoch = lease->lease_epoch;
4352 uint16_t version = lease->lease_version;
4353 status = lease_match(conn,
4354 req,
4355 &lease->lease_key,
4356 smb_fname,
4357 &version,
4358 &epoch);
4359 if (NT_STATUS_EQUAL(status, NT_STATUS_OPLOCK_NOT_GRANTED)) {
4360 /* Dynamic share file. No leases and update epoch... */
4361 lease->lease_state = SMB2_LEASE_NONE;
4362 lease->lease_epoch = epoch;
4363 lease->lease_version = version;
4364 } else if (!NT_STATUS_IS_OK(status)) {
4365 goto fail;
4369 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
4370 && (access_mask & DELETE_ACCESS)
4371 && !is_ntfs_stream_smb_fname(smb_fname)) {
4373 * We can't open a file with DELETE access if any of the
4374 * streams is open without FILE_SHARE_DELETE
4376 status = open_streams_for_delete(conn, smb_fname->base_name);
4378 if (!NT_STATUS_IS_OK(status)) {
4379 goto fail;
4383 if ((access_mask & SEC_FLAG_SYSTEM_SECURITY) &&
4384 !security_token_has_privilege(get_current_nttok(conn),
4385 SEC_PRIV_SECURITY)) {
4386 DEBUG(10, ("create_file_unixpath: open on %s "
4387 "failed - SEC_FLAG_SYSTEM_SECURITY denied.\n",
4388 smb_fname_str_dbg(smb_fname)));
4389 status = NT_STATUS_PRIVILEGE_NOT_HELD;
4390 goto fail;
4393 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
4394 && is_ntfs_stream_smb_fname(smb_fname)
4395 && (!(private_flags & NTCREATEX_OPTIONS_PRIVATE_STREAM_DELETE))) {
4396 uint32 base_create_disposition;
4397 struct smb_filename *smb_fname_base = NULL;
4399 if (create_options & FILE_DIRECTORY_FILE) {
4400 status = NT_STATUS_NOT_A_DIRECTORY;
4401 goto fail;
4404 switch (create_disposition) {
4405 case FILE_OPEN:
4406 base_create_disposition = FILE_OPEN;
4407 break;
4408 default:
4409 base_create_disposition = FILE_OPEN_IF;
4410 break;
4413 /* Create an smb_filename with stream_name == NULL. */
4414 smb_fname_base = synthetic_smb_fname(talloc_tos(),
4415 smb_fname->base_name,
4416 NULL, NULL);
4417 if (smb_fname_base == NULL) {
4418 status = NT_STATUS_NO_MEMORY;
4419 goto fail;
4422 if (SMB_VFS_STAT(conn, smb_fname_base) == -1) {
4423 DEBUG(10, ("Unable to stat stream: %s\n",
4424 smb_fname_str_dbg(smb_fname_base)));
4425 } else {
4427 * https://bugzilla.samba.org/show_bug.cgi?id=10229
4428 * We need to check if the requested access mask
4429 * could be used to open the underlying file (if
4430 * it existed), as we're passing in zero for the
4431 * access mask to the base filename.
4433 status = check_base_file_access(conn,
4434 smb_fname_base,
4435 access_mask);
4437 if (!NT_STATUS_IS_OK(status)) {
4438 DEBUG(10, ("Permission check "
4439 "for base %s failed: "
4440 "%s\n", smb_fname->base_name,
4441 nt_errstr(status)));
4442 goto fail;
4446 /* Open the base file. */
4447 status = create_file_unixpath(conn, NULL, smb_fname_base, 0,
4448 FILE_SHARE_READ
4449 | FILE_SHARE_WRITE
4450 | FILE_SHARE_DELETE,
4451 base_create_disposition,
4452 0, 0, 0, NULL, 0, 0, NULL, NULL,
4453 &base_fsp, NULL);
4454 TALLOC_FREE(smb_fname_base);
4456 if (!NT_STATUS_IS_OK(status)) {
4457 DEBUG(10, ("create_file_unixpath for base %s failed: "
4458 "%s\n", smb_fname->base_name,
4459 nt_errstr(status)));
4460 goto fail;
4462 /* we don't need the low level fd */
4463 fd_close(base_fsp);
4467 * If it's a request for a directory open, deal with it separately.
4470 if (create_options & FILE_DIRECTORY_FILE) {
4472 if (create_options & FILE_NON_DIRECTORY_FILE) {
4473 status = NT_STATUS_INVALID_PARAMETER;
4474 goto fail;
4477 /* Can't open a temp directory. IFS kit test. */
4478 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
4479 (file_attributes & FILE_ATTRIBUTE_TEMPORARY)) {
4480 status = NT_STATUS_INVALID_PARAMETER;
4481 goto fail;
4485 * We will get a create directory here if the Win32
4486 * app specified a security descriptor in the
4487 * CreateDirectory() call.
4490 oplock_request = 0;
4491 status = open_directory(
4492 conn, req, smb_fname, access_mask, share_access,
4493 create_disposition, create_options, file_attributes,
4494 &info, &fsp);
4495 } else {
4498 * Ordinary file case.
4501 status = file_new(req, conn, &fsp);
4502 if(!NT_STATUS_IS_OK(status)) {
4503 goto fail;
4506 status = fsp_set_smb_fname(fsp, smb_fname);
4507 if (!NT_STATUS_IS_OK(status)) {
4508 goto fail;
4511 if (base_fsp) {
4513 * We're opening the stream element of a
4514 * base_fsp we already opened. Set up the
4515 * base_fsp pointer.
4517 fsp->base_fsp = base_fsp;
4520 if (allocation_size) {
4521 fsp->initial_allocation_size = smb_roundup(fsp->conn,
4522 allocation_size);
4525 status = open_file_ntcreate(conn,
4526 req,
4527 access_mask,
4528 share_access,
4529 create_disposition,
4530 create_options,
4531 file_attributes,
4532 oplock_request,
4533 lease,
4534 private_flags,
4535 &info,
4536 fsp);
4538 if(!NT_STATUS_IS_OK(status)) {
4539 file_free(req, fsp);
4540 fsp = NULL;
4543 if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
4545 /* A stream open never opens a directory */
4547 if (base_fsp) {
4548 status = NT_STATUS_FILE_IS_A_DIRECTORY;
4549 goto fail;
4553 * Fail the open if it was explicitly a non-directory
4554 * file.
4557 if (create_options & FILE_NON_DIRECTORY_FILE) {
4558 status = NT_STATUS_FILE_IS_A_DIRECTORY;
4559 goto fail;
4562 oplock_request = 0;
4563 status = open_directory(
4564 conn, req, smb_fname, access_mask,
4565 share_access, create_disposition,
4566 create_options, file_attributes,
4567 &info, &fsp);
4571 if (!NT_STATUS_IS_OK(status)) {
4572 goto fail;
4575 fsp->base_fsp = base_fsp;
4577 if ((ea_list != NULL) &&
4578 ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN))) {
4579 status = set_ea(conn, fsp, fsp->fsp_name, ea_list);
4580 if (!NT_STATUS_IS_OK(status)) {
4581 goto fail;
4585 if (!fsp->is_directory && S_ISDIR(fsp->fsp_name->st.st_ex_mode)) {
4586 status = NT_STATUS_ACCESS_DENIED;
4587 goto fail;
4590 /* Save the requested allocation size. */
4591 if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
4592 if (allocation_size
4593 && (allocation_size > fsp->fsp_name->st.st_ex_size)) {
4594 fsp->initial_allocation_size = smb_roundup(
4595 fsp->conn, allocation_size);
4596 if (fsp->is_directory) {
4597 /* Can't set allocation size on a directory. */
4598 status = NT_STATUS_ACCESS_DENIED;
4599 goto fail;
4601 if (vfs_allocate_file_space(
4602 fsp, fsp->initial_allocation_size) == -1) {
4603 status = NT_STATUS_DISK_FULL;
4604 goto fail;
4606 } else {
4607 fsp->initial_allocation_size = smb_roundup(
4608 fsp->conn, (uint64_t)fsp->fsp_name->st.st_ex_size);
4610 } else {
4611 fsp->initial_allocation_size = 0;
4614 if ((info == FILE_WAS_CREATED) && lp_nt_acl_support(SNUM(conn)) &&
4615 fsp->base_fsp == NULL) {
4616 if (sd != NULL) {
4618 * According to the MS documentation, the only time the security
4619 * descriptor is applied to the opened file is iff we *created* the
4620 * file; an existing file stays the same.
4622 * Also, it seems (from observation) that you can open the file with
4623 * any access mask but you can still write the sd. We need to override
4624 * the granted access before we call set_sd
4625 * Patch for bug #2242 from Tom Lackemann <cessnatomny@yahoo.com>.
4628 uint32_t sec_info_sent;
4629 uint32_t saved_access_mask = fsp->access_mask;
4631 sec_info_sent = get_sec_info(sd);
4633 fsp->access_mask = FILE_GENERIC_ALL;
4635 if (sec_info_sent & (SECINFO_OWNER|
4636 SECINFO_GROUP|
4637 SECINFO_DACL|
4638 SECINFO_SACL)) {
4639 status = set_sd(fsp, sd, sec_info_sent);
4642 fsp->access_mask = saved_access_mask;
4644 if (!NT_STATUS_IS_OK(status)) {
4645 goto fail;
4647 } else if (lp_inherit_acls(SNUM(conn))) {
4648 /* Inherit from parent. Errors here are not fatal. */
4649 status = inherit_new_acl(fsp);
4650 if (!NT_STATUS_IS_OK(status)) {
4651 DEBUG(10,("inherit_new_acl: failed for %s with %s\n",
4652 fsp_str_dbg(fsp),
4653 nt_errstr(status) ));
4658 if ((conn->fs_capabilities & FILE_FILE_COMPRESSION)
4659 && (create_options & FILE_NO_COMPRESSION)
4660 && (info == FILE_WAS_CREATED)) {
4661 status = SMB_VFS_SET_COMPRESSION(conn, fsp, fsp,
4662 COMPRESSION_FORMAT_NONE);
4663 if (!NT_STATUS_IS_OK(status)) {
4664 DEBUG(1, ("failed to disable compression: %s\n",
4665 nt_errstr(status)));
4669 DEBUG(10, ("create_file_unixpath: info=%d\n", info));
4671 *result = fsp;
4672 if (pinfo != NULL) {
4673 *pinfo = info;
4676 smb_fname->st = fsp->fsp_name->st;
4678 return NT_STATUS_OK;
4680 fail:
4681 DEBUG(10, ("create_file_unixpath: %s\n", nt_errstr(status)));
4683 if (fsp != NULL) {
4684 if (base_fsp && fsp->base_fsp == base_fsp) {
4686 * The close_file below will close
4687 * fsp->base_fsp.
4689 base_fsp = NULL;
4691 close_file(req, fsp, ERROR_CLOSE);
4692 fsp = NULL;
4694 if (base_fsp != NULL) {
4695 close_file(req, base_fsp, ERROR_CLOSE);
4696 base_fsp = NULL;
4698 return status;
4702 * Calculate the full path name given a relative fid.
4704 NTSTATUS get_relative_fid_filename(connection_struct *conn,
4705 struct smb_request *req,
4706 uint16_t root_dir_fid,
4707 const struct smb_filename *smb_fname,
4708 struct smb_filename **smb_fname_out)
4710 files_struct *dir_fsp;
4711 char *parent_fname = NULL;
4712 char *new_base_name = NULL;
4713 NTSTATUS status;
4715 if (root_dir_fid == 0 || !smb_fname) {
4716 status = NT_STATUS_INTERNAL_ERROR;
4717 goto out;
4720 dir_fsp = file_fsp(req, root_dir_fid);
4722 if (dir_fsp == NULL) {
4723 status = NT_STATUS_INVALID_HANDLE;
4724 goto out;
4727 if (is_ntfs_stream_smb_fname(dir_fsp->fsp_name)) {
4728 status = NT_STATUS_INVALID_HANDLE;
4729 goto out;
4732 if (!dir_fsp->is_directory) {
4735 * Check to see if this is a mac fork of some kind.
4738 if ((conn->fs_capabilities & FILE_NAMED_STREAMS) &&
4739 is_ntfs_stream_smb_fname(smb_fname)) {
4740 status = NT_STATUS_OBJECT_PATH_NOT_FOUND;
4741 goto out;
4745 we need to handle the case when we get a
4746 relative open relative to a file and the
4747 pathname is blank - this is a reopen!
4748 (hint from demyn plantenberg)
4751 status = NT_STATUS_INVALID_HANDLE;
4752 goto out;
4755 if (ISDOT(dir_fsp->fsp_name->base_name)) {
4757 * We're at the toplevel dir, the final file name
4758 * must not contain ./, as this is filtered out
4759 * normally by srvstr_get_path and unix_convert
4760 * explicitly rejects paths containing ./.
4762 parent_fname = talloc_strdup(talloc_tos(), "");
4763 if (parent_fname == NULL) {
4764 status = NT_STATUS_NO_MEMORY;
4765 goto out;
4767 } else {
4768 size_t dir_name_len = strlen(dir_fsp->fsp_name->base_name);
4771 * Copy in the base directory name.
4774 parent_fname = talloc_array(talloc_tos(), char,
4775 dir_name_len+2);
4776 if (parent_fname == NULL) {
4777 status = NT_STATUS_NO_MEMORY;
4778 goto out;
4780 memcpy(parent_fname, dir_fsp->fsp_name->base_name,
4781 dir_name_len+1);
4784 * Ensure it ends in a '/'.
4785 * We used TALLOC_SIZE +2 to add space for the '/'.
4788 if(dir_name_len
4789 && (parent_fname[dir_name_len-1] != '\\')
4790 && (parent_fname[dir_name_len-1] != '/')) {
4791 parent_fname[dir_name_len] = '/';
4792 parent_fname[dir_name_len+1] = '\0';
4796 new_base_name = talloc_asprintf(talloc_tos(), "%s%s", parent_fname,
4797 smb_fname->base_name);
4798 if (new_base_name == NULL) {
4799 status = NT_STATUS_NO_MEMORY;
4800 goto out;
4803 status = filename_convert(req,
4804 conn,
4805 req->flags2 & FLAGS2_DFS_PATHNAMES,
4806 new_base_name,
4808 NULL,
4809 smb_fname_out);
4810 if (!NT_STATUS_IS_OK(status)) {
4811 goto out;
4814 out:
4815 TALLOC_FREE(parent_fname);
4816 TALLOC_FREE(new_base_name);
4817 return status;
4820 NTSTATUS create_file_default(connection_struct *conn,
4821 struct smb_request *req,
4822 uint16_t root_dir_fid,
4823 struct smb_filename *smb_fname,
4824 uint32_t access_mask,
4825 uint32_t share_access,
4826 uint32_t create_disposition,
4827 uint32_t create_options,
4828 uint32_t file_attributes,
4829 uint32_t oplock_request,
4830 struct smb2_lease *lease,
4831 uint64_t allocation_size,
4832 uint32_t private_flags,
4833 struct security_descriptor *sd,
4834 struct ea_list *ea_list,
4835 files_struct **result,
4836 int *pinfo,
4837 const struct smb2_create_blobs *in_context_blobs,
4838 struct smb2_create_blobs *out_context_blobs)
4840 int info = FILE_WAS_OPENED;
4841 files_struct *fsp = NULL;
4842 NTSTATUS status;
4843 bool stream_name = false;
4845 DEBUG(10,("create_file: access_mask = 0x%x "
4846 "file_attributes = 0x%x, share_access = 0x%x, "
4847 "create_disposition = 0x%x create_options = 0x%x "
4848 "oplock_request = 0x%x "
4849 "private_flags = 0x%x "
4850 "root_dir_fid = 0x%x, ea_list = 0x%p, sd = 0x%p, "
4851 "fname = %s\n",
4852 (unsigned int)access_mask,
4853 (unsigned int)file_attributes,
4854 (unsigned int)share_access,
4855 (unsigned int)create_disposition,
4856 (unsigned int)create_options,
4857 (unsigned int)oplock_request,
4858 (unsigned int)private_flags,
4859 (unsigned int)root_dir_fid,
4860 ea_list, sd, smb_fname_str_dbg(smb_fname)));
4863 * Calculate the filename from the root_dir_if if necessary.
4866 if (root_dir_fid != 0) {
4867 struct smb_filename *smb_fname_out = NULL;
4868 status = get_relative_fid_filename(conn, req, root_dir_fid,
4869 smb_fname, &smb_fname_out);
4870 if (!NT_STATUS_IS_OK(status)) {
4871 goto fail;
4873 smb_fname = smb_fname_out;
4877 * Check to see if this is a mac fork of some kind.
4880 stream_name = is_ntfs_stream_smb_fname(smb_fname);
4881 if (stream_name) {
4882 enum FAKE_FILE_TYPE fake_file_type;
4884 fake_file_type = is_fake_file(smb_fname);
4886 if (fake_file_type != FAKE_FILE_TYPE_NONE) {
4889 * Here we go! support for changing the disk quotas
4890 * --metze
4892 * We need to fake up to open this MAGIC QUOTA file
4893 * and return a valid FID.
4895 * w2k close this file directly after openening xp
4896 * also tries a QUERY_FILE_INFO on the file and then
4897 * close it
4899 status = open_fake_file(req, conn, req->vuid,
4900 fake_file_type, smb_fname,
4901 access_mask, &fsp);
4902 if (!NT_STATUS_IS_OK(status)) {
4903 goto fail;
4906 ZERO_STRUCT(smb_fname->st);
4907 goto done;
4910 if (!(conn->fs_capabilities & FILE_NAMED_STREAMS)) {
4911 status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
4912 goto fail;
4916 if (is_ntfs_default_stream_smb_fname(smb_fname)) {
4917 int ret;
4918 smb_fname->stream_name = NULL;
4919 /* We have to handle this error here. */
4920 if (create_options & FILE_DIRECTORY_FILE) {
4921 status = NT_STATUS_NOT_A_DIRECTORY;
4922 goto fail;
4924 if (lp_posix_pathnames()) {
4925 ret = SMB_VFS_LSTAT(conn, smb_fname);
4926 } else {
4927 ret = SMB_VFS_STAT(conn, smb_fname);
4930 if (ret == 0 && VALID_STAT_OF_DIR(smb_fname->st)) {
4931 status = NT_STATUS_FILE_IS_A_DIRECTORY;
4932 goto fail;
4936 status = create_file_unixpath(
4937 conn, req, smb_fname, access_mask, share_access,
4938 create_disposition, create_options, file_attributes,
4939 oplock_request, lease, allocation_size, private_flags,
4940 sd, ea_list,
4941 &fsp, &info);
4943 if (!NT_STATUS_IS_OK(status)) {
4944 goto fail;
4947 done:
4948 DEBUG(10, ("create_file: info=%d\n", info));
4950 *result = fsp;
4951 if (pinfo != NULL) {
4952 *pinfo = info;
4954 return NT_STATUS_OK;
4956 fail:
4957 DEBUG(10, ("create_file: %s\n", nt_errstr(status)));
4959 if (fsp != NULL) {
4960 close_file(req, fsp, ERROR_CLOSE);
4961 fsp = NULL;
4963 return status;