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/>.
23 #include "system/filesys.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"
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
;
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
52 ****************************************************************************/
54 static bool parent_override_delete(connection_struct
*conn
,
55 const struct smb_filename
*smb_fname
,
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
)) {
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
,
76 /* Check if we have rights to open. */
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 "
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
));
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
));
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
) ));
121 status
= SMB_VFS_GET_NT_ACL(conn
, smb_fname
->base_name
,
124 SECINFO_DACL
), talloc_tos(), &sd
);
126 if (!NT_STATUS_IS_OK(status
)) {
127 DEBUG(10, ("smbd_check_access_rights: Could not get acl "
129 smb_fname_str_dbg(smb_fname
),
132 if (NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
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"
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
),
165 (access_mask
& ~do_not_check_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
);
185 if (NT_STATUS_IS_OK(status
) ||
186 !NT_STATUS_EQUAL(status
, NT_STATUS_ACCESS_DENIED
)) {
190 /* Here we know status == NT_STATUS_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: "
205 "FILE_WRITE_ATTRIBUTES "
207 smb_fname_str_dbg(smb_fname
)));
210 if (parent_override_delete(conn
,
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.
219 * http://blogs.msdn.com/oldnewthing/archive/2004/06/04/148426.aspx
222 rejected_mask
&= ~DELETE_ACCESS
;
224 DEBUG(10,("smbd_check_access_rights: "
228 smb_fname_str_dbg(smb_fname
)));
231 if (rejected_mask
!= 0) {
232 return NT_STATUS_ACCESS_DENIED
;
237 static NTSTATUS
check_parent_access(struct connection_struct
*conn
,
238 struct smb_filename
*smb_fname
,
239 uint32_t access_mask
)
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
,
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
));
262 status
= SMB_VFS_GET_NT_ACL(conn
,
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",
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"
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
),
289 (access_mask
& ~FILE_READ_ATTRIBUTES
),
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",
296 smb_fname
->base_name
,
299 nt_errstr(status
) ));
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
)
317 status
= smbd_calculate_access_mask(conn
, smb_fname
,
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
),
329 if (access_mask
& (FILE_WRITE_DATA
|FILE_APPEND_DATA
)) {
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
,
346 /****************************************************************************
347 fd support routines - attempt to do a dos_open.
348 ****************************************************************************/
350 NTSTATUS
fd_open(struct connection_struct
*conn
,
355 struct smb_filename
*smb_fname
= fsp
->fsp_name
;
356 NTSTATUS status
= NT_STATUS_OK
;
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
))) {
369 fsp
->fh
->fd
= SMB_VFS_OPEN(conn
, smb_fname
, fsp
, flags
, mode
);
370 if (fsp
->fh
->fd
== -1) {
371 int posix_errno
= errno
;
373 #if defined(ENOTSUP) && defined(OSF1)
374 /* handle special Tru64 errno */
375 if (errno
== ENOTSUP
) {
380 /* fix broken NetBSD errno */
381 if (errno
== EFTYPE
) {
385 /* fix broken FreeBSD errno */
386 if (errno
== EMLINK
) {
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 "
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
) : "" ));
412 /****************************************************************************
413 Close the file associated with a fsp.
414 ****************************************************************************/
416 NTSTATUS
fd_close(files_struct
*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
);
433 return map_nt_error_from_unix(errno
);
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
,
447 struct smb_filename
*smb_fname_parent
;
450 smb_fname_parent
= synthetic_smb_fname(talloc_tos(), inherit_from_dir
,
452 if (smb_fname_parent
== NULL
) {
456 ret
= SMB_VFS_STAT(conn
, smb_fname_parent
);
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
),
462 TALLOC_FREE(smb_fname_parent
);
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",
471 (int)fsp
->fsp_name
->st
.st_ex_uid
));
472 TALLOC_FREE(smb_fname_parent
);
477 ret
= SMB_VFS_FCHOWN(fsp
, smb_fname_parent
->st
.st_ex_uid
, (gid_t
)-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
,
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
,
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
;
508 smb_fname_parent
= synthetic_smb_fname(ctx
, inherit_from_dir
,
510 if (smb_fname_parent
== NULL
) {
511 return NT_STATUS_NO_MEMORY
;
514 ret
= SMB_VFS_STAT(conn
, smb_fname_parent
);
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
),
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
);
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",
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
) ));
549 smb_fname_cwd
= synthetic_smb_fname(ctx
, ".", NULL
, NULL
);
550 if (smb_fname_cwd
== NULL
) {
551 status
= NT_STATUS_NO_MEMORY
;
555 ret
= SMB_VFS_STAT(conn
, smb_fname_cwd
);
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
)));
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
;
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",
579 (int)smb_fname_cwd
->st
.st_ex_uid
));
580 status
= NT_STATUS_OK
;
585 ret
= SMB_VFS_LCHOWN(conn
, ".", smb_fname_parent
->st
.st_ex_uid
,
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
,
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
;
604 vfs_ChDir(conn
,saved_dir
);
606 TALLOC_FREE(smb_fname_parent
);
607 TALLOC_FREE(smb_fname_cwd
);
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
,
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
);
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).
662 int curr_flags
= flags
;
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.
674 file_existed
= false;
675 DEBUG(10,("fd_open_atomic: file %s existed. "
677 smb_fname_str_dbg(fsp
->fsp_name
)));
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.
691 DEBUG(10,("fd_open_atomic: file %s "
692 "did not exist. Retry.\n",
693 smb_fname_str_dbg(fsp
->fsp_name
)));
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
702 *file_created
= true;
705 /* Create is done, or failed. */
711 /****************************************************************************
713 ****************************************************************************/
715 static NTSTATUS
open_file(files_struct
*fsp
,
716 connection_struct
*conn
,
717 struct smb_request
*req
,
718 const char *parent_dir
,
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
);
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.
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
) ) {
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
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
;
800 /* Don't create files with Microsoft wildcard characters. */
803 * wildcard characters are allowed in stream names
804 * only test the basefilename
806 wild
= fsp
->base_fsp
->fsp_name
->base_name
;
808 wild
= smb_fname
->base_name
;
810 if ((local_flags
& O_CREAT
) && !file_existed
&&
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. */
819 status
= smbd_check_access_rights(conn
,
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
),
832 if (!NT_STATUS_IS_OK(status
) &&
833 !NT_STATUS_EQUAL(status
,
834 NT_STATUS_OBJECT_NAME_NOT_FOUND
))
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
);
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
,
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
) ));
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
));
884 ret
= SMB_VFS_FSTAT(fsp
, &smb_fname
->st
);
886 /* If we have an fd, this stat should succeed. */
887 DEBUG(0,("Error doing fstat on open file %s "
889 smb_fname_str_dbg(smb_fname
),
891 status
= map_nt_error_from_unix(errno
);
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
,
912 /* Change the owner if required. */
913 if (lp_inherit_owner(SNUM(conn
))) {
914 change_file_owner_to_parent(conn
, parent_dir
,
920 ret
= SMB_VFS_FSTAT(fsp
, &smb_fname
->st
);
921 /* If we have an fd, this stat should succeed. */
923 DEBUG(0,("Error doing fstat on open file %s "
925 smb_fname_str_dbg(smb_fname
),
930 notify_fname(conn
, NOTIFY_ACTION_ADDED
,
931 FILE_NOTIFY_CHANGE_FILE_NAME
,
932 smb_fname
->base_name
);
935 fsp
->fh
->fd
= -1; /* What we used to call a stat open. */
937 /* File must exist for a stat open. */
938 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
941 status
= smbd_check_access_rights(conn
,
946 if (NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
) &&
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
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 "
962 smb_fname_str_dbg(smb_fname
),
963 nt_errstr(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
)) {
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);
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
));
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
,
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()
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
|
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
));
1048 if ((access_mask
& (FILE_WRITE_DATA
|
1052 DELETE_ACCESS
)) == 0) {
1053 DEBUG(10,("share_conflict: No conflict due to "
1054 "access_mask = 0x%x\n",
1055 (unsigned int)access_mask
));
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) )); \
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) )); \
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"));
1102 #if defined(DEVELOPER)
1103 static void validate_my_share_entries(struct smbd_server_connection
*sconn
,
1105 struct share_mode_entry
*share_entry
)
1107 struct server_id self
= messaging_server_id(sconn
->msg_ctx
);
1110 if (!serverid_equal(&self
, &share_entry
->pid
)) {
1114 if (share_entry
->op_mid
== 0) {
1115 /* INTERNAL_OPEN_ONLY */
1119 if (!is_valid_share_mode_entry(share_entry
)) {
1123 fsp
= file_find_dif(sconn
, share_entry
->id
,
1124 share_entry
->share_file_id
);
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
) {
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
);
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
,
1168 struct share_mode_data
*d
= lck
->data
;
1171 if (d
->num_share_modes
== 0) {
1174 if (!is_delete_on_close_set(lck
, name_hash
)) {
1177 for (i
=0; i
<d
->num_share_modes
; i
++) {
1178 if (!share_mode_stale_pid(d
, i
)) {
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
,
1194 uint32 share_access
)
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
]);
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
])) {
1226 /* someone else has a share lock on it, check to see if we can
1228 if (share_conflict(&lck
->data
->share_modes
[i
],
1229 access_mask
, share_access
)) {
1231 if (share_mode_stale_pid(lck
->data
, i
)) {
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
1247 static NTSTATUS
send_break_message(struct messaging_context
*msg_ctx
,
1248 const struct share_mode_entry
*exclusive
,
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
)));
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
;
1286 bool ex_or_batch
= false;
1287 bool level2
= false;
1288 bool no_oplock
= false;
1289 uint32_t num_non_stat_opens
= 0;
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
)) {
1299 if (e
->op_mid
== 0) {
1300 /* INTERNAL_OPEN_ONLY */
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. */
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"));
1319 if (ex_or_batch
|| batch
|| level2
|| no_oplock
) {
1320 DEBUG(0, ("Bad batch oplock entry %u.",
1327 if (EXCLUSIVE_OPLOCK_TYPE(e
->op_type
)) {
1328 if (share_mode_stale_pid(d
, i
)) {
1329 DEBUG(10, ("Found stale duplicate oplock\n"));
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
));
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 "
1348 DEBUG(0, ("Bad levelII oplock entry %u.",
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 "
1362 DEBUG(0, ("Bad no oplock entry %u.",
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
));
1382 static bool delay_for_oplock(files_struct
*fsp
,
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
;
1393 bool will_overwrite
;
1395 if ((oplock_request
& INTERNAL_OPEN_ONLY
) ||
1396 is_stat_open(fsp
->access_mask
)) {
1400 switch (create_disposition
) {
1401 case FILE_SUPERSEDE
:
1402 case FILE_OVERWRITE
:
1403 case FILE_OVERWRITE_IF
:
1404 will_overwrite
= true;
1407 will_overwrite
= false;
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
);
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
;
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
) {
1446 ign
= smb2_lease_equal(fsp_client_guid(fsp
),
1455 if ((e_lease_type
& ~break_to
) == 0) {
1456 if (l
!= NULL
&& l
->breaking
) {
1462 if (share_mode_stale_pid(d
, i
)) {
1466 if (will_overwrite
) {
1468 * If we break anyway break to NONE directly.
1469 * Otherwise vfs_set_filelen() will trigger the
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
,
1486 if (e_lease_type
& delay_mask
) {
1489 if (l
!= NULL
&& l
->breaking
&& !first_open_attempt
) {
1498 static bool file_has_brlocks(files_struct
*fsp
)
1500 struct byte_range_lock
*br_lck
;
1502 br_lck
= brl_get_locks_readonly(fsp
);
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
)
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
,
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
1540 for (fsp
= file_find_di_first(new_fsp
->conn
->sconn
, new_fsp
->file_id
);
1542 fsp
= file_find_di_next(fsp
)) {
1544 if (fsp
== new_fsp
) {
1547 if (fsp
->oplock_type
!= LEASE_OPLOCK
) {
1550 if (smb2_lease_key_equal(&fsp
->lease
->lease
.lease_key
, key
)) {
1551 fsp
->lease
->ref_count
+= 1;
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
) {
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
,
1581 struct share_mode_data
*d
= lck
->data
;
1582 const struct GUID
*client_guid
= fsp_client_guid(fsp
);
1583 struct share_mode_lease
*tmp
;
1587 idx
= find_share_mode_lease(d
, client_guid
, &lease
->lease_key
);
1590 struct share_mode_lease
*l
= &d
->leases
[idx
];
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",
1598 return NT_STATUS_NO_MEMORY
;
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
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
));
1636 l
->current_state
= granted
;
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
;
1649 tmp
= talloc_realloc(d
, d
->leases
, struct share_mode_lease
,
1655 return NT_STATUS_INSUFFICIENT_RESOURCES
;
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
;
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
) {
1704 if (lease
== NULL
) {
1708 return smb2_lease_equal(fsp_client_guid(fsp
),
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
,
1718 struct smb2_lease
*lease
)
1720 struct share_mode_data
*d
= lck
->data
;
1721 bool got_handle_lease
= false;
1722 bool got_oplock
= false;
1725 uint32_t lease_idx
= UINT32_MAX
;
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
;
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",
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
)) {
1799 if ((granted
& SMB2_LEASE_READ
) && !(granted
& SMB2_LEASE_WRITE
)) {
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
) {
1811 granted
&= ~SMB2_LEASE_HANDLE
;
1814 fsp
->oplock_type
= LEASE_OPLOCK
;
1816 status
= grant_fsp_lease(fsp
, lck
, lease
, &lease_idx
,
1818 if (!NT_STATUS_IS_OK(status
)) {
1822 *lease
= fsp
->lease
->lease
;
1823 DEBUG(10, ("lease_state=%d\n", lease
->lease_state
));
1825 if (got_handle_lease
) {
1826 granted
= SMB2_LEASE_NONE
;
1830 case SMB2_LEASE_READ
|SMB2_LEASE_WRITE
|SMB2_LEASE_HANDLE
:
1831 fsp
->oplock_type
= BATCH_OPLOCK
|EXCLUSIVE_OPLOCK
;
1833 case SMB2_LEASE_READ
|SMB2_LEASE_WRITE
:
1834 fsp
->oplock_type
= EXCLUSIVE_OPLOCK
;
1836 case SMB2_LEASE_READ
|SMB2_LEASE_HANDLE
:
1837 case SMB2_LEASE_READ
:
1838 fsp
->oplock_type
= LEVEL_II_OPLOCK
;
1841 fsp
->oplock_type
= NO_OPLOCK
;
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
),
1859 return NT_STATUS_NO_MEMORY
;
1862 ok
= update_num_read_oplocks(fsp
, lck
);
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
;
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
;
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
) {
1911 exit_server("talloc failed");
1917 struct defer_open_state
*watch_state
;
1918 struct tevent_req
*watch_req
;
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
,
1940 ret
= tevent_req_set_endtime(
1941 watch_req
, req
->sconn
->ev_ctx
,
1942 timeval_sum(&request_time
, &timeout
));
1946 if (!push_deferred_open_message_smb(req
, request_time
, timeout
,
1947 state
->id
, open_rec
)) {
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
);
1960 status
= dbwrap_record_watch_recv(req
, talloc_tos(), NULL
);
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
);
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
;
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
)) {
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
)) {
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
,
2039 uint32 share_access
,
2040 uint32 create_options
)
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"));
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
,
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;
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);
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
,
2157 uint32_t *p_access_mask
)
2159 struct security_descriptor
*sd
;
2160 uint32_t access_granted
;
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
,
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"
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
),
2201 (*p_access_mask
& ~FILE_READ_ATTRIBUTES
),
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
,
2226 uint32_t access_mask
,
2227 uint32_t *access_mask_out
)
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
)) {
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
),
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
)
2286 switch (create_disposition
) {
2287 case FILE_SUPERSEDE
:
2288 case FILE_OVERWRITE_IF
:
2289 case FILE_OVERWRITE
:
2298 static int disposition_to_open_flags(uint32_t create_disposition
)
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
2316 ret
= O_CREAT
|O_TRUNC
;
2321 * If file exists open. If file doesn't exist error.
2326 case FILE_OVERWRITE
:
2328 * If file exists overwrite. If file doesn't exist
2336 * If file exists error. If file doesn't exist create.
2338 ret
= O_CREAT
|O_EXCL
;
2343 * If file exists open. If file doesn't exist create.
2351 static int calculate_open_access_flags(uint32_t access_mask
,
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
));
2367 /* DENY_DOS opens are always underlying read-write on the
2368 file handle, no matter what the requested access mask
2372 ((private_flags
& NTCREATEX_OPTIONS_PRIVATE_DENY_DOS
) ||
2373 access_mask
& (FILE_READ_ATTRIBUTES
|FILE_READ_DATA
|
2374 FILE_READ_EA
|FILE_EXECUTE
));
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. */
2400 struct smb_filename
*smb_fname
= fsp
->fsp_name
;
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;
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
;
2418 SMB_STRUCT_STAT saved_stat
= smb_fname
->st
;
2419 struct timespec old_write_time
;
2422 if (conn
->printer
) {
2424 * Printers are handled completely differently.
2425 * Most of the passed parameters are ignored.
2429 *pinfo
= FILE_WAS_CREATED
;
2432 DEBUG(10, ("open_file_ntcreate: printer open fname=%s\n",
2433 smb_fname_str_dbg(smb_fname
)));
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
,
2445 if (!parent_dirname(talloc_tos(), smb_fname
->base_name
, &parent_dir
,
2447 return NT_STATUS_NO_MEMORY
;
2450 if (new_dos_attributes
& FILE_FLAG_POSIX_SEMANTICS
) {
2452 unx_mode
= (mode_t
)(new_dos_attributes
& ~FILE_FLAG_POSIX_SEMANTICS
);
2453 new_dos_attributes
= 0;
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
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
));
2477 /* Ensure req == NULL means INTERNAL_OPEN_ONLY */
2478 SMB_ASSERT(((oplock_request
& INTERNAL_OPEN_ONLY
) != 0));
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
2489 struct deferred_open_record
*open_rec
;
2490 if (get_deferred_open_message_state(req
,
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
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;
2513 new_dos_attributes
&= SAMBA_ATTRIBUTES_MASK
;
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
2530 DEBUG(5,("open_file_ntcreate: OS/2 long filenames are not "
2532 if (use_nt_status()) {
2533 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2535 return NT_STATUS_DOS(ERRDOS
, ERRcannotopen
);
2538 switch( create_disposition
) {
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 "
2545 smb_fname_str_dbg(smb_fname
)));
2547 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2551 case FILE_OVERWRITE
:
2552 /* If file exists overwrite. If file doesn't exist
2554 if (!file_existed
) {
2555 DEBUG(5,("open_file_ntcreate: FILE_OVERWRITE "
2556 "requested for file %s and file "
2558 smb_fname_str_dbg(smb_fname
) ));
2560 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
2565 /* If file exists error. If file doesn't exist
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
)) {
2577 return map_nt_error_from_unix(errno
);
2581 case FILE_SUPERSEDE
:
2582 case FILE_OVERWRITE_IF
:
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
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
,
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
,
2606 (unsigned int)smb_fname
->st
.st_ex_mode
,
2607 (unsigned int)unx_mode
));
2609 return NT_STATUS_ACCESS_DENIED
;
2613 status
= smbd_calculate_access_mask(conn
, smb_fname
,
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
)));
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
),
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
,
2643 * Currently we only look at FILE_WRITE_THROUGH for create options.
2647 if ((create_options
& FILE_WRITE_THROUGH
) && lp_strict_sync(SNUM(conn
))) {
2652 if (posix_open
&& (access_mask
& FILE_APPEND_DATA
)) {
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
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" ));
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
;
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
);
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),
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
,
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
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
);
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
);
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
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.
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.
2847 lck
= get_share_mode_lock(talloc_tos(), id
,
2849 smb_fname
, &old_write_time
);
2852 DEBUG(0, ("open_file_ntcreate: Could not get share "
2853 "mode lock for %s\n",
2854 smb_fname_str_dbg(smb_fname
)));
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
)) {
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
2882 file_existed
= true;
2885 if ((req
!= NULL
) &&
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
);
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
2905 (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS
|
2906 NTCREATEX_OPTIONS_PRIVATE_DENY_FCB
)) {
2908 DEBUG(0, ("DOS open without an SMB "
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
,
2928 if (NT_STATUS_IS_OK(status
)) {
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
;
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
,
2960 can_access_mask
))) {
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
;
2976 /* this is a hack to speed up torture tests
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;
3002 && !request_timed_out(request_time
,
3004 defer_open(lck
, request_time
, timeout
,
3013 * We have detected a sharing violation here
3014 * so return the correct error code
3016 status
= NT_STATUS_SHARING_VIOLATION
;
3018 status
= NT_STATUS_ACCESS_DENIED
;
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
))) {
3029 ret
= vfs_set_filelen(fsp
, 0);
3031 status
= map_nt_error_from_unix(errno
);
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
)) {
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
))) {
3063 ret_flock
= SMB_VFS_KERNEL_FLOCK(fsp
, share_access
, access_mask
);
3064 if(ret_flock
== -1 ){
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
;
3092 /* But SMB1 does. */
3093 fsp
->access_mask
= access_mask
| FILE_READ_ATTRIBUTES
;
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
)) {
3109 lease
->lease_state
= SMB2_LEASE_NONE
;
3111 oplock_request
= NO_OPLOCK
;
3116 if (new_file_created
) {
3117 info
= FILE_WAS_CREATED
;
3119 if (flags2
& O_TRUNC
) {
3120 info
= FILE_WAS_OVERWRITTEN
;
3122 info
= FILE_WAS_OPENED
;
3131 * Setup the oplock info in both the shared memory and
3134 status
= grant_fsp_oplock_type(req
, fsp
, lck
, oplock_request
, lease
);
3135 if (!NT_STATUS_IS_OK(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
);
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
))) {
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. */
3174 /* POSIX opens are sparse by default. */
3175 fsp
->is_sparse
= true;
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
3186 if (!posix_open
&& new_file_created
&& !def_acl
) {
3188 int saved_errno
= errno
; /* We might get ENOSYS in the next
3191 if (SMB_VFS_FCHMOD_ACL(fsp
, unx_mode
) == -1 &&
3193 errno
= saved_errno
; /* Ignore ENOSYS */
3196 } else if (new_unx_mode
) {
3200 /* Attributes need changing. File already existed. */
3203 int saved_errno
= errno
; /* We might get ENOSYS in the
3205 ret
= SMB_VFS_FCHMOD_ACL(fsp
, new_unx_mode
);
3207 if (ret
== -1 && errno
== ENOSYS
) {
3208 errno
= saved_errno
; /* Ignore ENOSYS */
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. */
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
);
3239 return NT_STATUS_OK
;
3242 static NTSTATUS
mkdir_internal(connection_struct
*conn
,
3243 struct smb_filename
*smb_dname
,
3244 uint32 file_attributes
)
3247 char *parent_dir
= NULL
;
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
,
3261 return NT_STATUS_NO_MEMORY
;
3264 if (file_attributes
& FILE_FLAG_POSIX_SEMANTICS
) {
3266 mode
= (mode_t
)(file_attributes
& ~FILE_FLAG_POSIX_SEMANTICS
);
3268 mode
= unix_mode(conn
, FILE_ATTRIBUTE_DIRECTORY
, smb_dname
, parent_dir
);
3271 status
= check_parent_access(conn
,
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",
3278 smb_dname
->base_name
,
3279 nt_errstr(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
))) {
3304 file_set_dosmode(conn
, smb_dname
,
3305 file_attributes
| FILE_ATTRIBUTE_DIRECTORY
,
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;
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
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
,
3337 need_re_stat
= true;
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
,
3362 uint32 share_access
,
3363 uint32 create_disposition
,
3364 uint32 create_options
,
3365 uint32 file_attributes
,
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
;
3373 struct timespec mtimespec
;
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
)));
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
) {
3421 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
3424 info
= FILE_WAS_OPENED
;
3429 /* If directory exists error. If directory doesn't
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
)));
3441 status
= mkdir_internal(conn
, smb_dname
,
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
)));
3452 info
= FILE_WAS_CREATED
;
3457 * If directory exists open. If directory doesn't
3462 status
= NT_STATUS_OK
;
3463 info
= FILE_WAS_OPENED
;
3465 status
= mkdir_internal(conn
, smb_dname
,
3468 if (NT_STATUS_IS_OK(status
)) {
3469 info
= FILE_WAS_CREATED
;
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
)));
3480 info
= FILE_WAS_OPENED
;
3486 case FILE_SUPERSEDE
:
3487 case FILE_OVERWRITE
:
3488 case FILE_OVERWRITE_IF
:
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
,
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
)));
3517 status
= file_new(req
, conn
, &fsp
);
3518 if(!NT_STATUS_IS_OK(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
);
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.
3558 ZERO_STRUCT(mtimespec
);
3560 if (access_mask
& (FILE_LIST_DIRECTORY
|
3562 FILE_ADD_SUBDIRECTORY
|
3565 FILE_DELETE_CHILD
)) {
3567 status
= fd_open(conn
, fsp
, O_RDONLY
|O_DIRECTORY
, 0);
3569 /* POSIX allows us to open a directory with O_RDONLY. */
3570 status
= fd_open(conn
, fsp
, O_RDONLY
, 0);
3572 if (!NT_STATUS_IS_OK(status
)) {
3573 DEBUG(5, ("open_directory: Could not open fd for "
3575 smb_fname_str_dbg(smb_dname
),
3576 nt_errstr(status
)));
3577 file_free(req
, fsp
);
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
)) {
3589 file_free(req
, fsp
);
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 "
3597 smb_fname_str_dbg(smb_dname
)));
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
,
3608 DEBUG(0, ("open_directory: Could not get share mode lock for "
3609 "%s\n", smb_fname_str_dbg(smb_dname
)));
3611 file_free(req
, fsp
);
3612 return NT_STATUS_SHARING_VIOLATION
;
3615 if (has_delete_on_close(lck
, fsp
->name_hash
)) {
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
)) {
3628 file_free(req
, fsp
);
3632 ok
= set_share_mode(lck
, fsp
, get_current_uid(conn
),
3633 req
? req
->mid
: 0, NO_OPLOCK
,
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
);
3650 file_free(req
, fsp
);
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
);
3680 return NT_STATUS_OK
;
3683 NTSTATUS
create_directory(connection_struct
*conn
, struct smb_request
*req
,
3684 struct smb_filename
*smb_dname
)
3689 status
= SMB_VFS_CREATE_FILE(
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 */
3701 0, /* allocation_size */
3702 0, /* private_flags */
3707 NULL
, NULL
); /* create context */
3709 if (NT_STATUS_IS_OK(status
)) {
3710 close_file(req
, fsp
, NORMAL_CLOSE
);
3716 /****************************************************************************
3717 Receive notification that one of our open files has been renamed by another
3719 ****************************************************************************/
3721 void msg_file_was_renamed(struct messaging_context
*msg
,
3724 struct server_id server_id
,
3728 char *frm
= (char *)data
->data
;
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
;
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
));
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') {
3760 smb_fname
= synthetic_smb_fname(talloc_tos(), base_name
,
3762 if (smb_fname
== NULL
) {
3766 DEBUG(10,("msg_file_was_renamed: Got rename message for sharepath %s, new name %s, "
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
)) {
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
,
3793 smb_fname_str_dbg(smb_fname
)));
3797 TALLOC_FREE(smb_fname
);
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
,
3810 struct stream_struct
*stream_info
= NULL
;
3811 files_struct
**streams
= NULL
;
3813 unsigned int num_streams
= 0;
3814 TALLOC_CTX
*frame
= talloc_stackframe();
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"));
3824 return NT_STATUS_OK
;
3827 if (!NT_STATUS_IS_OK(status
)) {
3828 DEBUG(10, ("vfs_streaminfo failed: %s\n",
3829 nt_errstr(status
)));
3833 DEBUG(10, ("open_streams_for_delete found %d streams\n",
3836 if (num_streams
== 0) {
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
;
3848 for (i
=0; i
<num_streams
; i
++) {
3849 struct smb_filename
*smb_fname
;
3851 if (strequal(stream_info
[i
].name
, "::$DATA")) {
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
;
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(
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 */
3881 0, /* allocation_size */
3882 NTCREATEX_OPTIONS_PRIVATE_STREAM_DELETE
, /* private_flags */
3885 &streams
[i
], /* result */
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
);
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
) {
3909 DEBUG(10, ("Closing stream # %d, %s\n", i
,
3910 fsp_str_dbg(streams
[i
])));
3911 close_file(NULL
, streams
[i
], NORMAL_CLOSE
);
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
;
3947 if (!parent_dirname(frame
, fsp
->fsp_name
->base_name
, &parent_name
, NULL
)) {
3949 return NT_STATUS_NO_MEMORY
;
3952 status
= SMB_VFS_GET_NT_ACL(fsp
->conn
,
3954 (SECINFO_OWNER
| SECINFO_GROUP
| SECINFO_DACL
),
3957 if (!NT_STATUS_IS_OK(status
)) {
3962 inheritable_components
= sd_has_inheritable_components(parent_desc
,
3965 if (!inheritable_components
&& !inherit_owner
) {
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;
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;
4003 if (try_builtin_administrators
) {
4008 ok
= sids_to_unixids(&global_sid_Builtin_Administrators
, 1, &ids
);
4012 BA_U_sid
= &global_sid_Builtin_Administrators
;
4013 BA_G_sid
= &global_sid_Builtin_Administrators
;
4016 BA_U_sid
= &global_sid_Builtin_Administrators
;
4019 BA_G_sid
= &global_sid_Builtin_Administrators
;
4032 ok
= sids_to_unixids(&global_sid_System
, 1, &ids
);
4036 SY_U_sid
= &global_sid_System
;
4037 SY_G_sid
= &global_sid_System
;
4040 SY_U_sid
= &global_sid_System
;
4043 SY_G_sid
= &global_sid_System
;
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
];
4074 group_sid
= &token
->sids
[PRIMARY_GROUP_SID_INDEX
];
4078 status
= se_create_child_secdesc(frame
,
4085 if (!NT_STATUS_IS_OK(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. */
4111 status
= SMB_VFS_FSET_NT_ACL(fsp
,
4114 if (inherit_owner
) {
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
;
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
,
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
;
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
;
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(),
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
,
4187 struct smbd_server_connection
*sconn
= req
->sconn
;
4188 struct lease_fname_match_state state
= {
4190 .match_status
= NT_STATUS_OK
4195 state
.file_existed
= VALID_STAT(fname
->st
);
4196 if (state
.file_existed
) {
4197 state
.id
= vfs_file_id_from_sbuf(conn
, &fname
->st
);
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
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
;
4224 if (file_id_equal(&state
.ids
[i
], &state
.id
)) {
4225 /* Don't need to break our own file. */
4229 lck
= get_existing_share_mode_lock(talloc_tos(), state
.ids
[i
]);
4231 /* Race condition - file already closed. */
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
)) {
4244 if (e
->op_type
== LEASE_OPLOCK
) {
4245 l
= &lck
->data
->leases
[e
->lease_idx
];
4246 if (!smb2_lease_key_equal(&l
->lease_key
,
4250 *p_epoch
= l
->epoch
;
4251 *p_version
= l
->lease_version
;
4254 if (e_lease_type
== SMB2_LEASE_NONE
) {
4258 send_break_message(conn
->sconn
->msg_ctx
, e
,
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
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.
4288 * Ensure we don't grant anything more so we
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
,
4316 int info
= FILE_WAS_OPENED
;
4317 files_struct
*base_fsp
= NULL
;
4318 files_struct
*fsp
= NULL
;
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, "
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
;
4341 if (create_options
& NTCREATEX_OPTIONS_INVALID_PARAM_MASK
) {
4342 status
= NT_STATUS_INVALID_PARAMETER
;
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
,
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
)) {
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
)) {
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
;
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
;
4404 switch (create_disposition
) {
4406 base_create_disposition
= FILE_OPEN
;
4409 base_create_disposition
= FILE_OPEN_IF
;
4413 /* Create an smb_filename with stream_name == NULL. */
4414 smb_fname_base
= synthetic_smb_fname(talloc_tos(),
4415 smb_fname
->base_name
,
4417 if (smb_fname_base
== NULL
) {
4418 status
= NT_STATUS_NO_MEMORY
;
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
)));
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
,
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
)));
4446 /* Open the base file. */
4447 status
= create_file_unixpath(conn
, NULL
, smb_fname_base
, 0,
4450 | FILE_SHARE_DELETE
,
4451 base_create_disposition
,
4452 0, 0, 0, NULL
, 0, 0, NULL
, 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
)));
4462 /* we don't need the low level fd */
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
;
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
;
4485 * We will get a create directory here if the Win32
4486 * app specified a security descriptor in the
4487 * CreateDirectory() call.
4491 status
= open_directory(
4492 conn
, req
, smb_fname
, access_mask
, share_access
,
4493 create_disposition
, create_options
, file_attributes
,
4498 * Ordinary file case.
4501 status
= file_new(req
, conn
, &fsp
);
4502 if(!NT_STATUS_IS_OK(status
)) {
4506 status
= fsp_set_smb_fname(fsp
, smb_fname
);
4507 if (!NT_STATUS_IS_OK(status
)) {
4513 * We're opening the stream element of a
4514 * base_fsp we already opened. Set up the
4517 fsp
->base_fsp
= base_fsp
;
4520 if (allocation_size
) {
4521 fsp
->initial_allocation_size
= smb_roundup(fsp
->conn
,
4525 status
= open_file_ntcreate(conn
,
4538 if(!NT_STATUS_IS_OK(status
)) {
4539 file_free(req
, fsp
);
4543 if (NT_STATUS_EQUAL(status
, NT_STATUS_FILE_IS_A_DIRECTORY
)) {
4545 /* A stream open never opens a directory */
4548 status
= NT_STATUS_FILE_IS_A_DIRECTORY
;
4553 * Fail the open if it was explicitly a non-directory
4557 if (create_options
& FILE_NON_DIRECTORY_FILE
) {
4558 status
= NT_STATUS_FILE_IS_A_DIRECTORY
;
4563 status
= open_directory(
4564 conn
, req
, smb_fname
, access_mask
,
4565 share_access
, create_disposition
,
4566 create_options
, file_attributes
,
4571 if (!NT_STATUS_IS_OK(status
)) {
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
)) {
4585 if (!fsp
->is_directory
&& S_ISDIR(fsp
->fsp_name
->st
.st_ex_mode
)) {
4586 status
= NT_STATUS_ACCESS_DENIED
;
4590 /* Save the requested allocation size. */
4591 if ((info
== FILE_WAS_CREATED
) || (info
== FILE_WAS_OVERWRITTEN
)) {
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
;
4601 if (vfs_allocate_file_space(
4602 fsp
, fsp
->initial_allocation_size
) == -1) {
4603 status
= NT_STATUS_DISK_FULL
;
4607 fsp
->initial_allocation_size
= smb_roundup(
4608 fsp
->conn
, (uint64_t)fsp
->fsp_name
->st
.st_ex_size
);
4611 fsp
->initial_allocation_size
= 0;
4614 if ((info
== FILE_WAS_CREATED
) && lp_nt_acl_support(SNUM(conn
)) &&
4615 fsp
->base_fsp
== 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
|
4639 status
= set_sd(fsp
, sd
, sec_info_sent
);
4642 fsp
->access_mask
= saved_access_mask
;
4644 if (!NT_STATUS_IS_OK(status
)) {
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",
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
));
4672 if (pinfo
!= NULL
) {
4676 smb_fname
->st
= fsp
->fsp_name
->st
;
4678 return NT_STATUS_OK
;
4681 DEBUG(10, ("create_file_unixpath: %s\n", nt_errstr(status
)));
4684 if (base_fsp
&& fsp
->base_fsp
== base_fsp
) {
4686 * The close_file below will close
4691 close_file(req
, fsp
, ERROR_CLOSE
);
4694 if (base_fsp
!= NULL
) {
4695 close_file(req
, base_fsp
, ERROR_CLOSE
);
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
;
4715 if (root_dir_fid
== 0 || !smb_fname
) {
4716 status
= NT_STATUS_INTERNAL_ERROR
;
4720 dir_fsp
= file_fsp(req
, root_dir_fid
);
4722 if (dir_fsp
== NULL
) {
4723 status
= NT_STATUS_INVALID_HANDLE
;
4727 if (is_ntfs_stream_smb_fname(dir_fsp
->fsp_name
)) {
4728 status
= NT_STATUS_INVALID_HANDLE
;
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
;
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
;
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
;
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,
4776 if (parent_fname
== NULL
) {
4777 status
= NT_STATUS_NO_MEMORY
;
4780 memcpy(parent_fname
, dir_fsp
->fsp_name
->base_name
,
4784 * Ensure it ends in a '/'.
4785 * We used TALLOC_SIZE +2 to add space for the '/'.
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
;
4803 status
= filename_convert(req
,
4805 req
->flags2
& FLAGS2_DFS_PATHNAMES
,
4810 if (!NT_STATUS_IS_OK(status
)) {
4815 TALLOC_FREE(parent_fname
);
4816 TALLOC_FREE(new_base_name
);
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
,
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
;
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, "
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
)) {
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
);
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
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
4899 status
= open_fake_file(req
, conn
, req
->vuid
,
4900 fake_file_type
, smb_fname
,
4902 if (!NT_STATUS_IS_OK(status
)) {
4906 ZERO_STRUCT(smb_fname
->st
);
4910 if (!(conn
->fs_capabilities
& FILE_NAMED_STREAMS
)) {
4911 status
= NT_STATUS_OBJECT_NAME_NOT_FOUND
;
4916 if (is_ntfs_default_stream_smb_fname(smb_fname
)) {
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
;
4924 if (lp_posix_pathnames()) {
4925 ret
= SMB_VFS_LSTAT(conn
, smb_fname
);
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
;
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
,
4943 if (!NT_STATUS_IS_OK(status
)) {
4948 DEBUG(10, ("create_file: info=%d\n", info
));
4951 if (pinfo
!= NULL
) {
4954 return NT_STATUS_OK
;
4957 DEBUG(10, ("create_file: %s\n", nt_errstr(status
)));
4960 close_file(req
, fsp
, ERROR_CLOSE
);