2 * Unix SMB/CIFS implementation.
4 * This file began with some code from source3/smbd/open.c and has been
5 * modified it work with ifs_createfile.
7 * ifs_createfile is a CIFS-specific syscall for opening/files and
8 * directories. It adds support for:
9 * - Full in-kernel access checks using a windows access_mask
10 * - Cluster-coherent share mode locks
11 * - Cluster-coherent oplocks
13 * - Setting security descriptors at create time
14 * - Setting dos_attributes at create time
16 * Copyright (C) Andrew Tridgell 1992-1998
17 * Copyright (C) Jeremy Allison 2001-2004
18 * Copyright (C) Volker Lendecke 2005
19 * Copyright (C) Tim Prouty, 2008
21 * This program is free software; you can redistribute it and/or modify
22 * it under the terms of the GNU General Public License as published by
23 * the Free Software Foundation; either version 3 of the License, or
24 * (at your option) any later version.
26 * This program is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 * GNU General Public License for more details.
31 * You should have received a copy of the GNU General Public License
32 * along with this program; if not, see <http://www.gnu.org/licenses/>.
37 #include "onefs_config.h"
38 #include "oplock_onefs.h"
39 #include "smbd/globals.h"
41 extern const struct generic_mapping file_generic_mapping
;
43 struct onefs_fsp_data
{
44 uint64_t oplock_callback_id
;
47 static NTSTATUS
onefs_create_file_unixpath(connection_struct
*conn
,
48 struct smb_request
*req
,
51 uint32_t share_access
,
52 uint32_t create_disposition
,
53 uint32_t create_options
,
54 uint32_t file_attributes
,
55 uint32_t oplock_request
,
56 uint64_t allocation_size
,
57 struct security_descriptor
*sd
,
58 struct ea_list
*ea_list
,
59 files_struct
**result
,
61 struct onefs_fsp_data
*fsp_data
,
62 SMB_STRUCT_STAT
*psbuf
);
64 /****************************************************************************
66 ****************************************************************************/
68 static NTSTATUS
onefs_open_file(files_struct
*fsp
,
69 connection_struct
*conn
,
70 struct smb_request
*req
,
71 const char *parent_dir
,
74 SMB_STRUCT_STAT
*psbuf
,
78 uint32 open_access_mask
,
82 uint32 create_options
,
83 uint32_t new_dos_attributes
,
84 struct security_descriptor
*sd
,
87 NTSTATUS status
= NT_STATUS_OK
;
88 int accmode
= (flags
& O_ACCMODE
);
89 int local_flags
= flags
;
90 bool file_existed
= VALID_STAT(*psbuf
);
99 /* Check permissions */
102 * This code was changed after seeing a client open request
103 * containing the open mode of (DENY_WRITE/read-only) with
104 * the 'create if not exist' bit set. The previous code
105 * would fail to open the file read only on a read-only share
106 * as it was checking the flags parameter directly against O_RDONLY,
107 * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
111 if (!CAN_WRITE(conn
)) {
112 /* It's a read-only share - fail if we wanted to write. */
113 if(accmode
!= O_RDONLY
) {
114 DEBUG(3,("Permission denied opening %s\n", path
));
115 return NT_STATUS_ACCESS_DENIED
;
116 } else if(flags
& O_CREAT
) {
117 /* We don't want to write - but we must make sure that
118 O_CREAT doesn't create the file if we have write
119 access into the directory.
122 local_flags
&= ~O_CREAT
;
127 * This little piece of insanity is inspired by the
128 * fact that an NT client can open a file for O_RDONLY,
129 * but set the create disposition to FILE_EXISTS_TRUNCATE.
130 * If the client *can* write to the file, then it expects to
131 * truncate the file, even though it is opening for readonly.
132 * Quicken uses this stupid trick in backup file creation...
133 * Thanks *greatly* to "David W. Chapman Jr." <dwcjr@inethouston.net>
134 * for helping track this one down. It didn't bite us in 2.0.x
135 * as we always opened files read-write in that release. JRA.
138 if ((accmode
== O_RDONLY
) && ((flags
& O_TRUNC
) == O_TRUNC
)) {
139 DEBUG(10,("onefs_open_file: truncate requested on read-only "
140 "open for file %s\n", path
));
141 local_flags
= (flags
& ~O_ACCMODE
)|O_RDWR
;
144 #if defined(O_NONBLOCK) && defined(S_ISFIFO)
146 * We would block on opening a FIFO with no one else on the
147 * other end. Do what we used to do and add O_NONBLOCK to the
151 if (file_existed
&& S_ISFIFO(psbuf
->st_mode
)) {
152 local_flags
|= O_NONBLOCK
;
156 /* Don't create files with Microsoft wildcard characters. */
159 * wildcard characters are allowed in stream names
160 * only test the basefilename
162 wild
= fsp
->base_fsp
->fsp_name
;
166 if ((local_flags
& O_CREAT
) && !file_existed
&&
169 * XXX: may need to remvoe this return...
171 * We dont think this check needs to exist. All it does is
172 * block creating files with Microsoft wildcards, which is
173 * fine if the creation originated from NFS or locally and
174 * then was copied via Samba.
176 DEBUG(1, ("onefs_open_file: creating file with wildcard: %s\n",
178 return NT_STATUS_OBJECT_NAME_INVALID
;
181 /* Actually do the open */
185 * Never follow symlinks on a POSIX client. The
186 * client should be doing this.
189 if (fsp
->posix_open
|| !lp_symlinks(SNUM(conn
))) {
193 /* Stream handling */
194 if (is_ntfs_stream_name(path
)) {
195 status
= onefs_split_ntfs_stream_name(talloc_tos(), path
,
198 /* It's a stream, so pass in the base_fd */
199 if ((conn
->fs_capabilities
& FILE_NAMED_STREAMS
) && stream
!= NULL
) {
200 SMB_ASSERT(fsp
->base_fsp
);
202 DEBUG(10,("Opening a stream: base=%s(%d), stream=%s\n",
203 base
, fsp
->base_fsp
->fh
->fd
, stream
));
205 base_fd
= fsp
->base_fsp
->fh
->fd
;
208 fsp
->fh
->fd
= onefs_sys_create_file(conn
,
210 stream
!= NULL
? stream
:
211 (base
!= NULL
? base
: path
),
224 if (fsp
->fh
->fd
== -1) {
225 if (errno
== EMFILE
) {
226 static time_t last_warned
= 0L;
228 if (time((time_t *) NULL
) > last_warned
) {
229 DEBUG(0, ("Too many open files, unable "
230 "to open more! smbd's max "
231 "open files = %d, also check "
232 "sysctl kern.maxfiles and "
233 "sysctl kern.maxfilesperproc\n",
234 lp_max_open_files()));
235 last_warned
= time((time_t *) NULL
);
239 status
= map_nt_error_from_unix(errno
);
240 DEBUG(3,("Error opening file %s (%s) (local_flags=%d) "
242 path
, strerror(errno
), local_flags
, flags
));
246 if ((local_flags
& O_CREAT
) && !file_existed
) {
248 /* Inherit the ACL if required */
249 if (lp_inherit_perms(SNUM(conn
))) {
250 inherit_access_posix_acl(conn
, parent_dir
, path
,
254 /* Change the owner if required. */
255 if (lp_inherit_owner(SNUM(conn
))) {
256 change_file_owner_to_parent(conn
, parent_dir
,
260 notify_fname(conn
, NOTIFY_ACTION_ADDED
,
261 FILE_NOTIFY_CHANGE_FILE_NAME
, path
);
267 if (fsp
->fh
->fd
== -1) {
268 ret
= SMB_VFS_STAT(conn
, path
, psbuf
);
270 ret
= SMB_VFS_FSTAT(fsp
, psbuf
);
271 /* If we have an fd, this stat should succeed. */
273 DEBUG(0,("Error doing fstat on open file %s "
274 "(%s)\n", path
,strerror(errno
) ));
278 /* For a non-io open, this stat failing means file not found. JRA */
280 status
= map_nt_error_from_unix(errno
);
287 * POSIX allows read-only opens of directories. We don't
288 * want to do this (we use a different code path for this)
289 * so catch a directory open and return an EISDIR. JRA.
292 if(S_ISDIR(psbuf
->st_mode
)) {
295 return NT_STATUS_FILE_IS_A_DIRECTORY
;
298 fsp
->mode
= psbuf
->st_mode
;
299 fsp
->file_id
= vfs_file_id_from_sbuf(conn
, psbuf
);
300 fsp
->vuid
= req
? req
->vuid
: UID_FIELD_INVALID
;
301 fsp
->file_pid
= req
? req
->smbpid
: 0;
302 fsp
->can_lock
= True
;
303 fsp
->can_read
= (access_mask
& (FILE_READ_DATA
)) ? True
: False
;
304 if (!CAN_WRITE(conn
)) {
305 fsp
->can_write
= False
;
307 fsp
->can_write
= (access_mask
& (FILE_WRITE_DATA
| FILE_APPEND_DATA
)) ?
310 fsp
->print_file
= False
;
311 fsp
->modified
= False
;
312 fsp
->sent_oplock_break
= NO_BREAK_SENT
;
313 fsp
->is_directory
= False
;
314 if (conn
->aio_write_behind_list
&&
315 is_in_path(path
, conn
->aio_write_behind_list
, conn
->case_sensitive
)) {
316 fsp
->aio_write_behind
= True
;
319 string_set(&fsp
->fsp_name
, path
);
320 fsp
->wcp
= NULL
; /* Write cache pointer. */
322 DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
323 conn
->server_info
->unix_name
,
325 BOOLSTR(fsp
->can_read
), BOOLSTR(fsp
->can_write
),
326 conn
->num_files_open
));
332 /****************************************************************************
333 Handle the 1 second delay in returning a SHARING_VIOLATION error.
334 ****************************************************************************/
336 static void defer_open(struct share_mode_lock
*lck
,
337 struct timeval request_time
,
338 struct timeval timeout
,
339 struct smb_request
*req
,
340 struct deferred_open_record
*state
)
346 for (i
=0; i
<lck
->num_share_modes
; i
++) {
347 struct share_mode_entry
*e
= &lck
->share_modes
[i
];
349 if (!is_deferred_open_entry(e
)) {
353 if (procid_is_me(&e
->pid
) && (e
->op_mid
== req
->mid
)) {
354 DEBUG(0, ("Trying to defer an already deferred "
355 "request: mid=%d, exiting\n", req
->mid
));
356 exit_server("attempt to defer a deferred request");
360 /* End paranoia check */
362 DEBUG(10,("defer_open_sharing_error: time [%u.%06u] adding deferred "
363 "open entry for mid %u\n",
364 (unsigned int)request_time
.tv_sec
,
365 (unsigned int)request_time
.tv_usec
,
366 (unsigned int)req
->mid
));
368 if (!push_deferred_smb_message(req
, request_time
, timeout
,
369 (char *)state
, sizeof(*state
))) {
370 exit_server("push_deferred_smb_message failed");
372 add_deferred_open(lck
, req
->mid
, request_time
, state
->id
);
375 * Push the MID of this packet on the signing queue.
376 * We only do this once, the first time we push the packet
377 * onto the deferred open queue, as this has a side effect
378 * of incrementing the response sequence number.
381 srv_defer_sign_response(req
->mid
);
384 static void schedule_defer_open(struct share_mode_lock
*lck
,
385 struct timeval request_time
,
386 struct smb_request
*req
)
388 struct deferred_open_record state
;
390 /* This is a relative time, added to the absolute
391 request_time value to get the absolute timeout time.
392 Note that if this is the second or greater time we enter
393 this codepath for this particular request mid then
394 request_time is left as the absolute time of the *first*
395 time this request mid was processed. This is what allows
396 the request to eventually time out. */
398 struct timeval timeout
;
400 /* Normally the smbd we asked should respond within
401 * OPLOCK_BREAK_TIMEOUT seconds regardless of whether
402 * the client did, give twice the timeout as a safety
403 * measure here in case the other smbd is stuck
407 * On OneFS, the kernel will always send an oplock_revoked message
408 * before this timeout is hit.
410 timeout
= timeval_set(OPLOCK_BREAK_TIMEOUT
*10, 0);
412 /* Nothing actually uses state.delayed_for_oplocks
413 but it's handy to differentiate in debug messages
414 between a 30 second delay due to oplock break, and
415 a 1 second delay for share mode conflicts. */
417 state
.delayed_for_oplocks
= True
;
418 state
.failed
= false;
421 if (!request_timed_out(request_time
, timeout
)) {
422 defer_open(lck
, request_time
, timeout
, req
, &state
);
426 /****************************************************************************
427 Open a file with a share mode. Passed in an already created files_struct.
428 ****************************************************************************/
429 NTSTATUS
onefs_open_file_ntcreate(connection_struct
*conn
,
430 struct smb_request
*req
,
434 uint32 create_disposition
,
435 uint32 create_options
,
436 uint32 new_dos_attributes
,
438 struct security_descriptor
*sd
,
441 struct onefs_fsp_data
*fsp_data
,
442 SMB_STRUCT_STAT
*psbuf
)
446 bool file_existed
= VALID_STAT(*psbuf
);
447 bool def_acl
= False
;
448 bool posix_open
= False
;
449 bool new_file_created
= False
;
450 bool clear_ads
= False
;
452 mode_t new_unx_mode
= (mode_t
)0;
453 mode_t unx_mode
= (mode_t
)0;
455 uint32 existing_dos_attributes
= 0;
456 struct pending_message_list
*pml
= NULL
;
457 struct timeval request_time
= timeval_zero();
458 struct share_mode_lock
*lck
= NULL
;
459 uint32 open_access_mask
= access_mask
;
465 uint64_t oplock_callback_id
= 0;
466 uint32 createfile_attributes
= 0;
472 * Printers are handled completely differently.
473 * Most of the passed parameters are ignored.
477 *pinfo
= FILE_WAS_CREATED
;
480 DEBUG(10, ("onefs_open_file_ntcreate: printer open fname=%s\n",
483 return print_fsp_open(req
, conn
, fname
, req
->vuid
, fsp
, psbuf
);
486 if (!parent_dirname(talloc_tos(), fname
, &parent_dir
, &newname
)) {
487 return NT_STATUS_NO_MEMORY
;
490 if (new_dos_attributes
& FILE_FLAG_POSIX_SEMANTICS
) {
492 unx_mode
= (mode_t
)(new_dos_attributes
& ~FILE_FLAG_POSIX_SEMANTICS
);
493 new_dos_attributes
= 0;
495 /* We add aARCH to this as this mode is only used if the file is
497 unx_mode
= unix_mode(conn
, new_dos_attributes
| aARCH
, fname
,
501 DEBUG(10,("onefs_open_file_ntcreate: fname=%s, dos_attrs=0x%x "
502 "access_mask=0x%x share_access=0x%x "
503 "create_disposition = 0x%x create_options=0x%x "
504 "unix mode=0%o oplock_request=0x%x\n",
505 fname
, new_dos_attributes
, access_mask
, share_access
,
506 create_disposition
, create_options
, unx_mode
,
510 * Any non-stat-only open has the potential to contend oplocks, which
511 * means to avoid blocking in the kernel (which is unacceptable), the
512 * open must be deferred. In order to defer opens, req must not be
513 * NULL. The known cases of calling with a NULL req:
515 * 1. Open the base file of a stream: Always done stat-only
517 * 2. open_file_fchmod(), which is called from 3 places:
518 * A. try_chown: Posix acls only. Never called on onefs.
519 * B. set_ea_dos_attributes: Can't be called from onefs, because
520 * SMB_VFS_SETXATTR return ENOSYS.
521 * C. file_set_dos_mode: This would only happen if the "dos
522 * filemode" smb.conf parameter is set to yes. We ship with
523 * it off, but if a customer were to turn it on it would be
526 if (req
== NULL
&& !is_stat_open(access_mask
) && !is_ntfs_stream_name(fname
)) {
527 smb_panic("NULL req on a non-stat-open!");
530 if ((req
== NULL
) && ((oplock_request
& INTERNAL_OPEN_ONLY
) == 0)) {
531 DEBUG(0, ("No smb request but not an internal only open!\n"));
532 return NT_STATUS_INTERNAL_ERROR
;
536 * Only non-internal opens can be deferred at all
540 && ((pml
= get_open_deferred_message(req
->mid
)) != NULL
)) {
541 struct deferred_open_record
*state
=
542 (struct deferred_open_record
*)pml
->private_data
.data
;
544 /* Remember the absolute time of the original
545 request with this mid. We'll use it later to
546 see if this has timed out. */
548 request_time
= pml
->request_time
;
550 /* Remove the deferred open entry under lock. */
551 lck
= get_share_mode_lock(talloc_tos(), state
->id
, NULL
, NULL
,
554 DEBUG(0, ("could not get share mode lock\n"));
556 del_deferred_open_entry(lck
, req
->mid
);
560 /* Ensure we don't reprocess this message. */
561 remove_deferred_open_smb_message(req
->mid
);
564 * When receiving a semlock_async_failure message, the
565 * deferred open will be marked as "failed". Returning
569 DEBUG(0, ("onefs_open_file_ntcreate: "
570 "semlock_async_failure detected!\n"));
571 return NT_STATUS_INTERNAL_ERROR
;
575 status
= check_name(conn
, fname
);
576 if (!NT_STATUS_IS_OK(status
)) {
581 new_dos_attributes
&= SAMBA_ATTRIBUTES_MASK
;
583 existing_dos_attributes
= dos_mode(conn
, fname
, psbuf
);
587 /* Setup dos_attributes to be set by ifs_createfile */
588 if (lp_store_dos_attributes(SNUM(conn
))) {
589 createfile_attributes
= (new_dos_attributes
| aARCH
) &
590 ~(FILE_ATTRIBUTE_NONINDEXED
| FILE_ATTRIBUTE_COMPRESSED
);
593 /* Ignore oplock requests if oplocks are disabled. */
594 if (!lp_oplocks(SNUM(conn
)) || global_client_failed_oplock_break
||
595 IS_VETO_OPLOCK_PATH(conn
, fname
)) {
596 /* Mask off everything except the private Samba bits. */
597 oplock_request
&= SAMBA_PRIVATE_OPLOCK_MASK
;
600 /* this is for OS/2 long file names - say we don't support them */
601 if (!lp_posix_pathnames() && strstr(fname
,".+,;=[].")) {
602 /* OS/2 Workplace shell fix may be main code stream in a later
604 DEBUG(5,("onefs_open_file_ntcreate: OS/2 long filenames are "
605 "not supported.\n"));
606 if (use_nt_status()) {
607 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
609 return NT_STATUS_DOS(ERRDOS
, ERRcannotopen
);
612 switch( create_disposition
) {
614 * Currently we're using FILE_SUPERSEDE as the same as
615 * FILE_OVERWRITE_IF but they really are
616 * different. FILE_SUPERSEDE deletes an existing file
617 * (requiring delete access) then recreates it.
621 * @todo: Clear all file attributes?
622 * http://www.osronline.com/article.cfm?article=302
623 * create if not exist, trunc if exist
625 * If file exists replace/overwrite. If file doesn't
628 flags2
|= (O_CREAT
| O_TRUNC
);
632 case FILE_OVERWRITE_IF
:
633 /* If file exists replace/overwrite. If file doesn't
635 flags2
|= (O_CREAT
| O_TRUNC
);
640 /* If file exists open. If file doesn't exist error. */
642 DEBUG(5,("onefs_open_file_ntcreate: FILE_OPEN "
643 "requested for file %s and file "
644 "doesn't exist.\n", fname
));
646 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
651 /* If file exists overwrite. If file doesn't exist
654 DEBUG(5, ("onefs_open_file_ntcreate: "
655 "FILE_OVERWRITE requested for file "
656 "%s and file doesn't exist.\n",
659 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
666 /* If file exists error. If file doesn't exist
669 DEBUG(5, ("onefs_open_file_ntcreate: "
670 "FILE_CREATE requested for file %s "
671 "and file already exists.\n",
673 if (S_ISDIR(psbuf
->st_mode
)) {
678 return map_nt_error_from_unix(errno
);
680 flags2
|= (O_CREAT
|O_EXCL
);
684 /* If file exists open. If file doesn't exist
690 return NT_STATUS_INVALID_PARAMETER
;
693 /* Match attributes on file exists and overwrite. */
694 if (!posix_open
&& file_existed
&&
695 ((create_disposition
== FILE_OVERWRITE
) ||
696 (create_disposition
== FILE_OVERWRITE_IF
))) {
697 if (!open_match_attributes(conn
, fname
,
698 existing_dos_attributes
,
699 new_dos_attributes
, psbuf
->st_mode
,
700 unx_mode
, &new_unx_mode
)) {
701 DEBUG(5, ("onefs_open_file_ntcreate: attributes "
702 "missmatch for file %s (%x %x) (0%o, 0%o)\n",
703 fname
, existing_dos_attributes
,
705 (unsigned int)psbuf
->st_mode
,
706 (unsigned int)unx_mode
));
708 return NT_STATUS_ACCESS_DENIED
;
713 * OneFS understands MAXIMUM_ALLOWED_ACCESS, so only hack the
714 * access_mask, but leave the MAA for the actual open in
717 open_access_mask
= access_mask
;
718 if (open_access_mask
& MAXIMUM_ALLOWED_ACCESS
) {
719 access_mask
|= FILE_GENERIC_ALL
;
722 /* Convert GENERIC bits to specific bits. */
723 se_map_generic(&access_mask
, &file_generic_mapping
);
724 se_map_generic(&open_access_mask
, &file_generic_mapping
);
726 if ((flags2
& O_TRUNC
) || (oplock_request
& FORCE_OPLOCK_BREAK_TO_NONE
)) {
727 /* This will cause oplock breaks. */
728 open_access_mask
|= FILE_WRITE_DATA
;
731 DEBUG(10, ("onefs_open_file_ntcreate: fname=%s, after mapping "
732 "open_access_mask=%#x, access_mask=0x%x\n",
733 fname
, open_access_mask
, access_mask
));
736 * Note that we ignore the append flag as append does not
737 * mean the same thing under DOS and Unix.
740 if ((access_mask
& (FILE_WRITE_DATA
| FILE_APPEND_DATA
)) ||
741 (oplock_request
& FORCE_OPLOCK_BREAK_TO_NONE
)) {
744 * DENY_DOS opens are always underlying read-write on the
745 * file handle, no matter what the requested access mask
746 * says. Stock samba just sets the flags, but since
747 * ifs_createfile uses the access_mask, it must be updated as
748 * well. This allows BASE-DENY* to pass.
750 if (create_options
& NTCREATEX_OPTIONS_PRIVATE_DENY_DOS
) {
752 DEBUG(10,("onefs_open_file_ntcreate: deny_dos: "
753 "Adding O_RDWR to flags "
754 "(0x%x) and some READ bits to "
755 "open_access_mask (0x%x)\n",
756 flags
, open_access_mask
));
759 open_access_mask
|= (FILE_READ_ATTRIBUTES
|
760 FILE_READ_DATA
| FILE_READ_EA
| FILE_EXECUTE
);
762 } else if (access_mask
& (FILE_READ_ATTRIBUTES
|
774 /* Currently we only look at FILE_WRITE_THROUGH for create options. */
776 if ((create_options
& FILE_WRITE_THROUGH
) &&
777 lp_strict_sync(SNUM(conn
))) {
782 if (posix_open
&& (access_mask
& FILE_APPEND_DATA
)) {
786 if (!posix_open
&& !CAN_WRITE(conn
)) {
788 * We should really return a permission denied error if either
789 * O_CREAT or O_TRUNC are set, but for compatibility with
790 * older versions of Samba we just AND them out.
792 flags2
&= ~(O_CREAT
|O_TRUNC
);
794 /* Deny DELETE_ACCESS explicitly if the share is read only. */
795 if (access_mask
& DELETE_ACCESS
) {
796 return map_nt_error_from_unix(EACCES
);
800 /* Ensure we can't write on a read-only share or file. */
801 if (flags
!= O_RDONLY
&& file_existed
&&
802 (!CAN_WRITE(conn
) || IS_DOS_READONLY(existing_dos_attributes
))) {
803 DEBUG(5, ("onefs_open_file_ntcreate: write access requested "
804 "for file %s on read only %s\n",
805 fname
, !CAN_WRITE(conn
) ? "share" : "file" ));
807 return NT_STATUS_ACCESS_DENIED
;
810 DEBUG(10, ("fsp = %p\n", fsp
));
812 fsp
->file_id
= vfs_file_id_from_sbuf(conn
, psbuf
);
813 fsp
->share_access
= share_access
;
814 fsp
->fh
->private_options
= create_options
;
815 fsp
->access_mask
= open_access_mask
; /* We change this to the
816 * requested access_mask after
817 * the open is done. */
818 fsp
->posix_open
= posix_open
;
820 /* Ensure no SAMBA_PRIVATE bits can be set. */
821 fsp
->oplock_type
= (oplock_request
& ~SAMBA_PRIVATE_OPLOCK_MASK
);
823 if (timeval_is_zero(&request_time
)) {
824 request_time
= fsp
->open_time
;
828 struct timespec old_write_time
= get_mtimespec(psbuf
);
829 id
= vfs_file_id_from_sbuf(conn
, psbuf
);
831 lck
= get_share_mode_lock(talloc_tos(), id
,
833 fname
, &old_write_time
);
836 DEBUG(0, ("Could not get share mode lock\n"));
837 return NT_STATUS_SHARING_VIOLATION
;
840 if (lck
->delete_on_close
) {
841 /* DELETE_PENDING is not deferred for a second */
843 return NT_STATUS_DELETE_PENDING
;
847 SMB_ASSERT(!file_existed
|| (lck
!= NULL
));
850 * Ensure we pay attention to default ACLs on directories. May be
851 * neccessary depending on ACL policies.
853 if ((flags2
& O_CREAT
) && lp_inherit_acls(SNUM(conn
)) &&
854 (def_acl
= directory_has_default_acl(conn
, parent_dir
))) {
858 DEBUG(4,("calling onefs_open_file with flags=0x%X flags2=0x%X "
859 "mode=0%o, access_mask = 0x%x, open_access_mask = 0x%x\n",
860 (unsigned int)flags
, (unsigned int)flags2
,
861 (unsigned int)unx_mode
, (unsigned int)access_mask
,
862 (unsigned int)open_access_mask
));
865 * Since the open is guaranteed to be stat only if req == NULL, a
866 * callback record is only needed if req != NULL.
869 SMB_ASSERT(fsp_data
);
870 oplock_callback_id
= onefs_oplock_wait_record(req
->mid
);
871 if (oplock_callback_id
== 0) {
872 return NT_STATUS_NO_MEMORY
;
876 * It is also already asserted it's either a stream or a
877 * stat-only open at this point.
879 SMB_ASSERT(fsp
->oplock_type
== NO_OPLOCK
);
883 status
= onefs_open_file(fsp
,
898 createfile_attributes
,
902 if (!NT_STATUS_IS_OK(status
)) {
904 /* OneFS Oplock Handling */
905 if (errno
== EINPROGRESS
) {
909 struct deferred_open_record state
;
910 struct timespec old_write_time
;
912 old_write_time
= get_mtimespec(psbuf
);
914 DEBUG(3, ("Someone created file %s with an "
915 "oplock after we looked: Retrying\n",
918 * We hit the race that when we did the stat
919 * on the file it did not exist, and someone
920 * has created it in between the stat and the
921 * open_file() call. Just retry immediately.
923 id
= vfs_file_id_from_sbuf(conn
, psbuf
);
924 if (!(lck
= get_share_mode_lock(talloc_tos(),
925 id
, conn
->connectpath
, fname
,
930 DEBUG(0, ("onefs_open_file_ntcreate: "
931 "Could not get share mode "
932 "lock for %s\n", fname
));
933 status
= NT_STATUS_SHARING_VIOLATION
;
934 goto cleanup_destroy
;
937 state
.delayed_for_oplocks
= False
;
941 defer_open(lck
, request_time
,
942 timeval_zero(), req
, &state
);
944 goto cleanup_destroy
;
946 /* Waiting for an oplock */
947 DEBUG(5,("Async createfile because a client has an "
948 "oplock on %s\n", fname
));
951 schedule_defer_open(lck
, request_time
, req
);
955 /* Check for a sharing violation */
956 if ((errno
== EAGAIN
) || (errno
== EWOULDBLOCK
)) {
957 uint32 can_access_mask
;
958 bool can_access
= True
;
960 /* Check if this can be done with the deny_dos and fcb
963 /* Try to find dup fsp if possible. */
965 (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS
|
966 NTCREATEX_OPTIONS_PRIVATE_DENY_FCB
)) {
969 DEBUG(0, ("DOS open without an SMB "
971 status
= NT_STATUS_INTERNAL_ERROR
;
972 goto cleanup_destroy
;
975 /* Use the client requested access mask here,
976 * not the one we open with. */
977 status
= fcb_or_dos_open(req
,
988 if (NT_STATUS_IS_OK(status
)) {
990 *pinfo
= FILE_WAS_OPENED
;
992 status
= NT_STATUS_OK
;
998 * This next line is a subtlety we need for
999 * MS-Access. If a file open will fail due to share
1000 * permissions and also for security (access) reasons,
1001 * we need to return the access failed error, not the
1002 * share error. We can't open the file due to kernel
1003 * oplock deadlock (it's possible we failed above on
1004 * the open_mode_check()) so use a userspace check.
1007 if (flags
& O_RDWR
) {
1008 can_access_mask
= FILE_READ_DATA
|FILE_WRITE_DATA
;
1009 } else if (flags
& O_WRONLY
) {
1010 can_access_mask
= FILE_WRITE_DATA
;
1012 can_access_mask
= FILE_READ_DATA
;
1015 if (((can_access_mask
& FILE_WRITE_DATA
) && !CAN_WRITE(conn
)) ||
1016 !can_access_file_data(conn
,fname
,psbuf
,can_access_mask
)) {
1021 * If we're returning a share violation, ensure we
1022 * cope with the braindead 1 second delay.
1024 if (!(oplock_request
& INTERNAL_OPEN_ONLY
) &&
1025 lp_defer_sharing_violations()) {
1026 struct timeval timeout
;
1027 struct deferred_open_record state
;
1030 /* this is a hack to speed up torture tests
1032 timeout_usecs
= lp_parm_int(SNUM(conn
),
1033 "smbd","sharedelay",
1034 SHARING_VIOLATION_USEC_WAIT
);
1036 /* This is a relative time, added to the
1037 absolute request_time value to get the
1038 absolute timeout time. Note that if this
1039 is the second or greater time we enter this
1040 codepath for this particular request mid
1041 then request_time is left as the absolute
1042 time of the *first* time this request mid
1043 was processed. This is what allows the
1044 request to eventually time out. */
1046 timeout
= timeval_set(0, timeout_usecs
);
1048 /* Nothing actually uses
1049 state.delayed_for_oplocks but it's handy to
1050 differentiate in debug messages between a
1051 30 second delay due to oplock break, and a
1052 1 second delay for share mode conflicts. */
1054 state
.delayed_for_oplocks
= False
;
1056 state
.failed
= false;
1059 && !request_timed_out(request_time
,
1061 defer_open(lck
, request_time
, timeout
,
1068 * We have detected a sharing violation here
1069 * so return the correct error code
1071 status
= NT_STATUS_SHARING_VIOLATION
;
1073 status
= NT_STATUS_ACCESS_DENIED
;
1076 goto cleanup_destroy
;
1080 * Normal error, for example EACCES
1083 if (oplock_callback_id
!= 0) {
1084 destroy_onefs_callback_record(oplock_callback_id
);
1091 fsp
->oplock_type
= granted_oplock
;
1093 if (oplock_callback_id
!= 0) {
1094 onefs_set_oplock_callback(oplock_callback_id
, fsp
);
1095 fsp_data
->oplock_callback_id
= oplock_callback_id
;
1097 SMB_ASSERT(fsp
->oplock_type
== NO_OPLOCK
);
1100 if (!file_existed
) {
1101 struct timespec old_write_time
= get_mtimespec(psbuf
);
1103 * Deal with the race condition where two smbd's detect the
1104 * file doesn't exist and do the create at the same time. One
1105 * of them will win and set a share mode, the other (ie. this
1106 * one) should check if the requested share mode for this
1107 * create is allowed.
1111 * Now the file exists and fsp is successfully opened,
1112 * fsp->dev and fsp->inode are valid and should replace the
1113 * dev=0,inode=0 from a non existent file. Spotted by
1114 * Nadav Danieli <nadavd@exanet.com>. JRA.
1119 lck
= get_share_mode_lock(talloc_tos(), id
,
1121 fname
, &old_write_time
);
1124 DEBUG(0, ("onefs_open_file_ntcreate: Could not get "
1125 "share mode lock for %s\n", fname
));
1127 return NT_STATUS_SHARING_VIOLATION
;
1130 if (lck
->delete_on_close
) {
1131 status
= NT_STATUS_DELETE_PENDING
;
1134 if (!NT_STATUS_IS_OK(status
)) {
1135 struct deferred_open_record state
;
1139 state
.delayed_for_oplocks
= False
;
1142 /* Do it all over again immediately. In the second
1143 * round we will find that the file existed and handle
1144 * the DELETE_PENDING and FCB cases correctly. No need
1145 * to duplicate the code here. Essentially this is a
1146 * "goto top of this function", but don't tell
1150 defer_open(lck
, request_time
, timeval_zero(),
1158 * We exit this block with the share entry *locked*.....
1163 SMB_ASSERT(lck
!= NULL
);
1165 /* Delete streams if create_disposition requires it */
1166 if (file_existed
&& clear_ads
&& !is_ntfs_stream_name(fname
)) {
1167 status
= delete_all_streams(conn
, fname
);
1168 if (!NT_STATUS_IS_OK(status
)) {
1175 /* note that we ignore failure for the following. It is
1176 basically a hack for NFS, and NFS will never set one of
1177 these only read them. Nobody but Samba can ever set a deny
1178 mode and we have already checked our more authoritative
1179 locking database for permission to set this deny mode. If
1180 the kernel refuses the operations then the kernel is wrong.
1181 note that GPFS supports it as well - jmcd */
1183 if (fsp
->fh
->fd
!= -1) {
1184 ret_flock
= SMB_VFS_KERNEL_FLOCK(fsp
, share_access
);
1185 if(ret_flock
== -1 ){
1189 return NT_STATUS_SHARING_VIOLATION
;
1194 * At this point onwards, we can guarentee that the share entry
1195 * is locked, whether we created the file or not, and that the
1196 * deny mode is compatible with all current opens.
1199 /* Record the options we were opened with. */
1200 fsp
->share_access
= share_access
;
1201 fsp
->fh
->private_options
= create_options
;
1203 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
1205 fsp
->access_mask
= access_mask
| FILE_READ_ATTRIBUTES
;
1208 /* stat opens on existing files don't get oplocks. */
1209 if (is_stat_open(open_access_mask
)) {
1210 fsp
->oplock_type
= NO_OPLOCK
;
1213 if (!(flags2
& O_TRUNC
)) {
1214 info
= FILE_WAS_OPENED
;
1216 info
= FILE_WAS_OVERWRITTEN
;
1219 info
= FILE_WAS_CREATED
;
1227 * Setup the oplock info in both the shared memory and
1231 if ((fsp
->oplock_type
!= NO_OPLOCK
) &&
1232 (fsp
->oplock_type
!= FAKE_LEVEL_II_OPLOCK
)) {
1233 if (!set_file_oplock(fsp
, fsp
->oplock_type
)) {
1234 /* Could not get the kernel oplock */
1235 fsp
->oplock_type
= NO_OPLOCK
;
1239 if (fsp
->oplock_type
== LEVEL_II_OPLOCK
&&
1240 (!lp_level2_oplocks(SNUM(conn
)) ||
1241 !(global_client_caps
& CAP_LEVEL_II_OPLOCKS
))) {
1243 DEBUG(5, ("Downgrading level2 oplock on open "
1244 "because level2 oplocks = off\n"));
1246 release_file_oplock(fsp
);
1249 if (info
== FILE_WAS_OVERWRITTEN
|| info
== FILE_WAS_CREATED
||
1250 info
== FILE_WAS_SUPERSEDED
) {
1251 new_file_created
= True
;
1254 set_share_mode(lck
, fsp
, conn
->server_info
->utok
.uid
, 0,
1257 /* Handle strange delete on close create semantics. */
1258 if (create_options
& FILE_DELETE_ON_CLOSE
) {
1259 status
= can_set_delete_on_close(fsp
, True
, new_dos_attributes
);
1261 if (!NT_STATUS_IS_OK(status
)) {
1262 /* Remember to delete the mode we just added. */
1263 del_share_mode(lck
, fsp
);
1268 /* Note that here we set the *inital* delete on close flag,
1269 not the regular one. The magic gets handled in close. */
1270 fsp
->initial_delete_on_close
= True
;
1274 * Take care of inherited ACLs on created files - if default ACL not
1276 * May be necessary depending on acl policies.
1278 if (!posix_open
&& !file_existed
&& !def_acl
&& !(VALID_STAT(*psbuf
)
1279 && (psbuf
->st_flags
& SF_HASNTFSACL
))) {
1281 int saved_errno
= errno
; /* We might get ENOSYS in the next
1284 if (SMB_VFS_FCHMOD_ACL(fsp
, unx_mode
) == -1 &&
1286 errno
= saved_errno
; /* Ignore ENOSYS */
1289 } else if (new_unx_mode
) {
1293 /* Attributes need changing. File already existed. */
1296 int saved_errno
= errno
; /* We might get ENOSYS in the
1298 ret
= SMB_VFS_FCHMOD_ACL(fsp
, new_unx_mode
);
1300 if (ret
== -1 && errno
== ENOSYS
) {
1301 errno
= saved_errno
; /* Ignore ENOSYS */
1303 DEBUG(5, ("onefs_open_file_ntcreate: reset "
1304 "attributes of file %s to 0%o\n",
1305 fname
, (unsigned int)new_unx_mode
));
1306 ret
= 0; /* Don't do the fchmod below. */
1311 (SMB_VFS_FCHMOD(fsp
, new_unx_mode
) == -1))
1312 DEBUG(5, ("onefs_open_file_ntcreate: failed to reset "
1313 "attributes of file %s to 0%o\n",
1314 fname
, (unsigned int)new_unx_mode
));
1317 /* If this is a successful open, we must remove any deferred open
1320 del_deferred_open_entry(lck
, req
->mid
);
1324 return NT_STATUS_OK
;
1328 /****************************************************************************
1329 Open a directory from an NT SMB call.
1330 ****************************************************************************/
1331 static NTSTATUS
onefs_open_directory(connection_struct
*conn
,
1332 struct smb_request
*req
,
1335 uint32 share_access
,
1336 uint32 create_disposition
,
1337 uint32 create_options
,
1338 uint32 file_attributes
,
1339 struct security_descriptor
*sd
,
1340 files_struct
**result
,
1342 SMB_STRUCT_STAT
*psbuf
)
1344 files_struct
*fsp
= NULL
;
1345 struct share_mode_lock
*lck
= NULL
;
1347 struct timespec mtimespec
;
1350 const char *dirname
;
1351 bool posix_open
= false;
1352 uint32 create_flags
= 0;
1353 uint32 mode
= lp_dir_mask(SNUM(conn
));
1355 DEBUG(5, ("onefs_open_directory: opening directory %s, "
1356 "access_mask = 0x%x, "
1357 "share_access = 0x%x create_options = 0x%x, "
1358 "create_disposition = 0x%x, file_attributes = 0x%x\n",
1359 fname
, (unsigned int)access_mask
, (unsigned int)share_access
,
1360 (unsigned int)create_options
, (unsigned int)create_disposition
,
1361 (unsigned int)file_attributes
));
1363 if (!(file_attributes
& FILE_FLAG_POSIX_SEMANTICS
) &&
1364 (conn
->fs_capabilities
& FILE_NAMED_STREAMS
) &&
1365 is_ntfs_stream_name(fname
)) {
1366 DEBUG(2, ("onefs_open_directory: %s is a stream name!\n", fname
));
1367 return NT_STATUS_NOT_A_DIRECTORY
;
1370 switch (create_disposition
) {
1372 /* If directory exists open. If directory doesn't
1375 info
= FILE_WAS_OPENED
;
1378 /* If directory exists error. If directory doesn't
1380 create_flags
= O_CREAT
| O_EXCL
;
1381 info
= FILE_WAS_CREATED
;
1384 /* If directory exists open. If directory doesn't
1387 /* Note: in order to return whether the directory was
1388 * opened or created, we first try to open and then try
1391 info
= FILE_WAS_OPENED
;
1393 case FILE_SUPERSEDE
:
1394 case FILE_OVERWRITE
:
1395 case FILE_OVERWRITE_IF
:
1397 DEBUG(5, ("onefs_open_directory: invalid "
1398 "create_disposition 0x%x for directory %s\n",
1399 (unsigned int)create_disposition
, fname
));
1400 return NT_STATUS_INVALID_PARAMETER
;
1404 * Check for write access to the share. Done in mkdir_internal() in
1407 if (!CAN_WRITE(conn
) && (create_flags
& O_CREAT
)) {
1408 return NT_STATUS_ACCESS_DENIED
;
1411 /* Get parent dirname */
1412 if (!parent_dirname(talloc_tos(), fname
, &parent_dir
, &dirname
)) {
1413 return NT_STATUS_NO_MEMORY
;
1416 if (file_attributes
& FILE_FLAG_POSIX_SEMANTICS
) {
1418 mode
= (mode_t
)(file_attributes
& ~FILE_FLAG_POSIX_SEMANTICS
);
1419 file_attributes
= 0;
1421 mode
= unix_mode(conn
, aDIR
, fname
, parent_dir
);
1425 * The NONINDEXED and COMPRESSED bits seem to always be cleared on
1426 * directories, no matter if you specify that they should be set.
1429 ~(FILE_ATTRIBUTE_NONINDEXED
| FILE_ATTRIBUTE_COMPRESSED
);
1431 status
= file_new(req
, conn
, &fsp
);
1432 if(!NT_STATUS_IS_OK(status
)) {
1437 * Actual open with retry magic to handle FILE_OPEN_IF which is
1438 * unique because the kernel won't tell us if the file was opened or
1442 fsp
->fh
->fd
= onefs_sys_create_file(conn
,
1449 create_flags
| O_DIRECTORY
,
1457 if (fsp
->fh
->fd
== -1) {
1458 DEBUG(3, ("Error opening %s. Errno=%d (%s).\n", fname
, errno
,
1460 SMB_ASSERT(errno
!= EINPROGRESS
);
1462 if (create_disposition
== FILE_OPEN_IF
) {
1463 if (errno
== ENOENT
) {
1464 /* Try again, creating it this time. */
1465 create_flags
= O_CREAT
| O_EXCL
;
1466 info
= FILE_WAS_CREATED
;
1468 } else if (errno
== EEXIST
) {
1469 /* Uggh. Try again again. */
1471 info
= FILE_WAS_OPENED
;
1476 /* Error cases below: */
1477 file_free(req
, fsp
);
1479 if ((errno
== ENOENT
) && (create_disposition
== FILE_OPEN
)) {
1480 DEBUG(5,("onefs_open_directory: FILE_OPEN requested "
1481 "for directory %s and it doesn't "
1482 "exist.\n", fname
));
1483 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1484 } else if ((errno
== EEXIST
) &&
1485 (create_disposition
== FILE_CREATE
)) {
1486 DEBUG(5,("onefs_open_directory: FILE_CREATE "
1487 "requested for directory %s and it "
1488 "already exists.\n", fname
));
1489 return NT_STATUS_OBJECT_NAME_COLLISION
;
1490 } else if ((errno
== EAGAIN
) || (errno
== EWOULDBLOCK
)) {
1491 /* Catch sharing violations. */
1492 return NT_STATUS_SHARING_VIOLATION
;
1495 return map_nt_error_from_unix(errno
);
1498 if (info
== FILE_WAS_CREATED
) {
1500 /* Pulled from mkdir_internal() */
1501 if (SMB_VFS_LSTAT(conn
, fname
, psbuf
) == -1) {
1502 DEBUG(2, ("Could not stat directory '%s' just "
1503 "created: %s\n",fname
, strerror(errno
)));
1504 return map_nt_error_from_unix(errno
);
1507 if (!S_ISDIR(psbuf
->st_mode
)) {
1508 DEBUG(0, ("Directory just '%s' created is not a "
1509 "directory\n", fname
));
1510 return NT_STATUS_ACCESS_DENIED
;
1515 * Check if high bits should have been set, then (if
1516 * bits are missing): add them. Consider bits
1517 * automagically set by UNIX, i.e. SGID bit from
1520 if (mode
& ~(S_IRWXU
|S_IRWXG
|S_IRWXO
) &&
1521 (mode
& ~psbuf
->st_mode
)) {
1522 SMB_VFS_CHMOD(conn
, fname
, (psbuf
->st_mode
|
1523 (mode
& ~psbuf
->st_mode
)));
1527 /* Change the owner if required. */
1528 if (lp_inherit_owner(SNUM(conn
))) {
1529 change_dir_owner_to_parent(conn
, parent_dir
, fname
,
1533 notify_fname(conn
, NOTIFY_ACTION_ADDED
,
1534 FILE_NOTIFY_CHANGE_DIR_NAME
, fname
);
1537 /* Stat the fd for Samba bookkeeping. */
1538 if(SMB_VFS_FSTAT(fsp
, psbuf
) != 0) {
1540 file_free(req
, fsp
);
1541 return map_nt_error_from_unix(errno
);
1544 /* Setup the files_struct for it. */
1545 fsp
->mode
= psbuf
->st_mode
;
1546 fsp
->file_id
= vfs_file_id_from_sbuf(conn
, psbuf
);
1547 fsp
->vuid
= req
? req
->vuid
: UID_FIELD_INVALID
;
1548 fsp
->file_pid
= req
? req
->smbpid
: 0;
1549 fsp
->can_lock
= False
;
1550 fsp
->can_read
= False
;
1551 fsp
->can_write
= False
;
1553 fsp
->share_access
= share_access
;
1554 fsp
->fh
->private_options
= create_options
;
1556 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
1558 fsp
->access_mask
= access_mask
| FILE_READ_ATTRIBUTES
;
1559 fsp
->print_file
= False
;
1560 fsp
->modified
= False
;
1561 fsp
->oplock_type
= NO_OPLOCK
;
1562 fsp
->sent_oplock_break
= NO_BREAK_SENT
;
1563 fsp
->is_directory
= True
;
1564 fsp
->posix_open
= posix_open
;
1566 string_set(&fsp
->fsp_name
,fname
);
1568 mtimespec
= get_mtimespec(psbuf
);
1571 * Still set the samba share mode lock for correct delete-on-close
1572 * semantics and to make smbstatus more useful.
1574 lck
= get_share_mode_lock(talloc_tos(), fsp
->file_id
,
1579 DEBUG(0, ("onefs_open_directory: Could not get share mode "
1580 "lock for %s\n", fname
));
1582 file_free(req
, fsp
);
1583 return NT_STATUS_SHARING_VIOLATION
;
1586 if (lck
->delete_on_close
) {
1589 file_free(req
, fsp
);
1590 return NT_STATUS_DELETE_PENDING
;
1593 set_share_mode(lck
, fsp
, conn
->server_info
->utok
.uid
, 0, NO_OPLOCK
);
1596 * For directories the delete on close bit at open time seems
1597 * always to be honored on close... See test 19 in Samba4 BASE-DELETE.
1599 if (create_options
& FILE_DELETE_ON_CLOSE
) {
1600 status
= can_set_delete_on_close(fsp
, True
, 0);
1601 if (!NT_STATUS_IS_OK(status
) &&
1602 !NT_STATUS_EQUAL(status
, NT_STATUS_DIRECTORY_NOT_EMPTY
)) {
1605 file_free(req
, fsp
);
1609 if (NT_STATUS_IS_OK(status
)) {
1610 /* Note that here we set the *inital* delete on close flag,
1611 not the regular one. The magic gets handled in close. */
1612 fsp
->initial_delete_on_close
= True
;
1623 return NT_STATUS_OK
;
1627 * Wrapper around onefs_open_file_ntcreate and onefs_open_directory.
1629 static NTSTATUS
onefs_create_file_unixpath(connection_struct
*conn
,
1630 struct smb_request
*req
,
1632 uint32_t access_mask
,
1633 uint32_t share_access
,
1634 uint32_t create_disposition
,
1635 uint32_t create_options
,
1636 uint32_t file_attributes
,
1637 uint32_t oplock_request
,
1638 uint64_t allocation_size
,
1639 struct security_descriptor
*sd
,
1640 struct ea_list
*ea_list
,
1641 files_struct
**result
,
1643 struct onefs_fsp_data
*fsp_data
,
1644 SMB_STRUCT_STAT
*psbuf
)
1646 SMB_STRUCT_STAT sbuf
;
1647 int info
= FILE_WAS_OPENED
;
1648 files_struct
*base_fsp
= NULL
;
1649 files_struct
*fsp
= NULL
;
1652 DEBUG(10,("onefs_create_file_unixpath: access_mask = 0x%x "
1653 "file_attributes = 0x%x, share_access = 0x%x, "
1654 "create_disposition = 0x%x create_options = 0x%x "
1655 "oplock_request = 0x%x ea_list = 0x%p, sd = 0x%p, "
1657 (unsigned int)access_mask
,
1658 (unsigned int)file_attributes
,
1659 (unsigned int)share_access
,
1660 (unsigned int)create_disposition
,
1661 (unsigned int)create_options
,
1662 (unsigned int)oplock_request
,
1663 ea_list
, sd
, fname
));
1665 if (create_options
& FILE_OPEN_BY_FILE_ID
) {
1666 status
= NT_STATUS_NOT_SUPPORTED
;
1670 if (create_options
& NTCREATEX_OPTIONS_INVALID_PARAM_MASK
) {
1671 status
= NT_STATUS_INVALID_PARAMETER
;
1676 SMB_ASSERT((oplock_request
& ~SAMBA_PRIVATE_OPLOCK_MASK
) ==
1678 oplock_request
|= INTERNAL_OPEN_ONLY
;
1681 if (psbuf
!= NULL
) {
1685 if (SMB_VFS_STAT(conn
, fname
, &sbuf
) == -1) {
1686 SET_STAT_INVALID(sbuf
);
1690 if (lp_parm_bool(SNUM(conn
), PARM_ONEFS_TYPE
,
1691 PARM_IGNORE_SACLS
, PARM_IGNORE_SACLS_DEFAULT
)) {
1692 access_mask
&= ~SYSTEM_SECURITY_ACCESS
;
1695 if ((conn
->fs_capabilities
& FILE_NAMED_STREAMS
)
1696 && (access_mask
& DELETE_ACCESS
)
1697 && !is_ntfs_stream_name(fname
)) {
1699 * We can't open a file with DELETE access if any of the
1700 * streams is open without FILE_SHARE_DELETE
1702 status
= open_streams_for_delete(conn
, fname
);
1704 if (!NT_STATUS_IS_OK(status
)) {
1709 if ((conn
->fs_capabilities
& FILE_NAMED_STREAMS
)
1710 && is_ntfs_stream_name(fname
)) {
1712 uint32 base_create_disposition
;
1714 if (create_options
& FILE_DIRECTORY_FILE
) {
1715 status
= NT_STATUS_NOT_A_DIRECTORY
;
1719 status
= onefs_split_ntfs_stream_name(talloc_tos(), fname
,
1721 if (!NT_STATUS_IS_OK(status
)) {
1722 DEBUG(10, ("onefs_create_file_unixpath: "
1723 "split_ntfs_stream_name failed: %s\n",
1724 nt_errstr(status
)));
1728 SMB_ASSERT(!is_ntfs_stream_name(base
)); /* paranoia.. */
1730 switch (create_disposition
) {
1732 base_create_disposition
= FILE_OPEN
;
1735 base_create_disposition
= FILE_OPEN_IF
;
1739 status
= onefs_create_file_unixpath(
1743 SYNCHRONIZE_ACCESS
, /* access_mask */
1746 FILE_SHARE_DELETE
), /* share_access */
1747 base_create_disposition
, /* create_disposition*/
1748 0, /* create_options */
1749 file_attributes
, /* file_attributes */
1750 NO_OPLOCK
, /* oplock_request */
1751 0, /* allocation_size */
1754 &base_fsp
, /* result */
1756 NULL
, /* fsp_data */
1759 if (!NT_STATUS_IS_OK(status
)) {
1760 DEBUG(10, ("onefs_create_file_unixpath for base %s "
1761 "failed: %s\n", base
, nt_errstr(status
)));
1766 * Testing against windows xp/2003/vista shows that oplocks
1767 * can actually be requested and granted on streams (see the
1768 * RAW-OPLOCK-STREAM1 smbtorture test).
1770 if ((oplock_request
& ~SAMBA_PRIVATE_OPLOCK_MASK
) !=
1772 DEBUG(5, ("Oplock(%d) being requested on a stream! "
1773 "Ignoring oplock request: fname=%s\n",
1774 oplock_request
& ~SAMBA_PRIVATE_OPLOCK_MASK
,
1776 /* Request NO_OPLOCK instead. */
1777 oplock_request
&= SAMBA_PRIVATE_OPLOCK_MASK
;
1781 /* Covert generic bits in the security descriptor. */
1783 security_acl_map_generic(sd
->dacl
, &file_generic_mapping
);
1784 security_acl_map_generic(sd
->sacl
, &file_generic_mapping
);
1788 * If it's a request for a directory open, deal with it separately.
1791 if (create_options
& FILE_DIRECTORY_FILE
) {
1793 if (create_options
& FILE_NON_DIRECTORY_FILE
) {
1794 status
= NT_STATUS_INVALID_PARAMETER
;
1798 /* Can't open a temp directory. IFS kit test. */
1799 if (!(file_attributes
& FILE_FLAG_POSIX_SEMANTICS
) &&
1800 (file_attributes
& FILE_ATTRIBUTE_TEMPORARY
)) {
1801 status
= NT_STATUS_INVALID_PARAMETER
;
1806 * We will get a create directory here if the Win32
1807 * app specified a security descriptor in the
1808 * CreateDirectory() call.
1811 status
= onefs_open_directory(
1815 access_mask
, /* access_mask */
1816 share_access
, /* share_access */
1817 create_disposition
, /* create_disposition*/
1818 create_options
, /* create_options */
1819 file_attributes
, /* file_attributes */
1827 * Ordinary file case.
1830 status
= file_new(req
, conn
, &fsp
);
1831 if(!NT_STATUS_IS_OK(status
)) {
1836 * We're opening the stream element of a base_fsp
1837 * we already opened. Set up the base_fsp pointer.
1840 fsp
->base_fsp
= base_fsp
;
1843 status
= onefs_open_file_ntcreate(
1847 access_mask
, /* access_mask */
1848 share_access
, /* share_access */
1849 create_disposition
, /* create_disposition*/
1850 create_options
, /* create_options */
1851 file_attributes
, /* file_attributes */
1852 oplock_request
, /* oplock_request */
1856 fsp_data
, /* fsp_data */
1859 if(!NT_STATUS_IS_OK(status
)) {
1860 file_free(req
, fsp
);
1864 if (NT_STATUS_EQUAL(status
, NT_STATUS_FILE_IS_A_DIRECTORY
)) {
1866 /* A stream open never opens a directory */
1869 status
= NT_STATUS_FILE_IS_A_DIRECTORY
;
1874 * Fail the open if it was explicitly a non-directory
1878 if (create_options
& FILE_NON_DIRECTORY_FILE
) {
1879 status
= NT_STATUS_FILE_IS_A_DIRECTORY
;
1883 create_options
|= FILE_DIRECTORY_FILE
;
1885 status
= onefs_open_directory(
1889 access_mask
, /* access_mask */
1890 share_access
, /* share_access */
1891 create_disposition
, /* create_disposition*/
1892 create_options
, /* create_options */
1893 file_attributes
, /* file_attributes */
1901 if (!NT_STATUS_IS_OK(status
)) {
1905 fsp
->base_fsp
= base_fsp
;
1909 if ((ea_list
!= NULL
) && (info
== FILE_WAS_CREATED
)) {
1910 status
= set_ea(conn
, fsp
, fname
, ea_list
);
1911 if (!NT_STATUS_IS_OK(status
)) {
1916 if (!fsp
->is_directory
&& S_ISDIR(sbuf
.st_mode
)) {
1917 status
= NT_STATUS_ACCESS_DENIED
;
1921 /* Save the requested allocation size. */
1922 if ((info
== FILE_WAS_CREATED
) || (info
== FILE_WAS_OVERWRITTEN
)) {
1924 && (allocation_size
> sbuf
.st_size
)) {
1925 fsp
->initial_allocation_size
= smb_roundup(
1926 fsp
->conn
, allocation_size
);
1927 if (fsp
->is_directory
) {
1928 /* Can't set allocation size on a directory. */
1929 status
= NT_STATUS_ACCESS_DENIED
;
1932 if (vfs_allocate_file_space(
1933 fsp
, fsp
->initial_allocation_size
) == -1) {
1934 status
= NT_STATUS_DISK_FULL
;
1938 fsp
->initial_allocation_size
= smb_roundup(
1939 fsp
->conn
, (uint64_t)sbuf
.st_size
);
1943 DEBUG(10, ("onefs_create_file_unixpath: info=%d\n", info
));
1946 if (pinfo
!= NULL
) {
1949 if (psbuf
!= NULL
) {
1950 if ((fsp
->fh
== NULL
) || (fsp
->fh
->fd
== -1)) {
1954 SMB_VFS_FSTAT(fsp
, psbuf
);
1957 return NT_STATUS_OK
;
1960 DEBUG(10, ("onefs_create_file_unixpath: %s\n", nt_errstr(status
)));
1963 if (base_fsp
&& fsp
->base_fsp
== base_fsp
) {
1965 * The close_file below will close
1970 close_file(req
, fsp
, ERROR_CLOSE
);
1973 if (base_fsp
!= NULL
) {
1974 close_file(req
, base_fsp
, ERROR_CLOSE
);
1980 static void destroy_onefs_fsp_data(void *p_data
)
1982 struct onefs_fsp_data
*fsp_data
= (struct onefs_fsp_data
*)p_data
;
1984 destroy_onefs_callback_record(fsp_data
->oplock_callback_id
);
1988 * SMB_VFS_CREATE_FILE interface to onefs.
1990 NTSTATUS
onefs_create_file(vfs_handle_struct
*handle
,
1991 struct smb_request
*req
,
1992 uint16_t root_dir_fid
,
1994 uint32_t create_file_flags
,
1995 uint32_t access_mask
,
1996 uint32_t share_access
,
1997 uint32_t create_disposition
,
1998 uint32_t create_options
,
1999 uint32_t file_attributes
,
2000 uint32_t oplock_request
,
2001 uint64_t allocation_size
,
2002 struct security_descriptor
*sd
,
2003 struct ea_list
*ea_list
,
2004 files_struct
**result
,
2006 SMB_STRUCT_STAT
*psbuf
)
2008 connection_struct
*conn
= handle
->conn
;
2009 struct case_semantics_state
*case_state
= NULL
;
2010 struct onefs_fsp_data fsp_data
= {};
2011 SMB_STRUCT_STAT sbuf
;
2012 int info
= FILE_WAS_OPENED
;
2013 files_struct
*fsp
= NULL
;
2016 DEBUG(10,("onefs_create_file: access_mask = 0x%x "
2017 "file_attributes = 0x%x, share_access = 0x%x, "
2018 "create_disposition = 0x%x create_options = 0x%x "
2019 "oplock_request = 0x%x "
2020 "root_dir_fid = 0x%x, ea_list = 0x%p, sd = 0x%p, "
2021 "create_file_flags = 0x%x, fname = %s\n",
2022 (unsigned int)access_mask
,
2023 (unsigned int)file_attributes
,
2024 (unsigned int)share_access
,
2025 (unsigned int)create_disposition
,
2026 (unsigned int)create_options
,
2027 (unsigned int)oplock_request
,
2028 (unsigned int)root_dir_fid
,
2029 ea_list
, sd
, create_file_flags
, fname
));
2031 /* Get the file name if root_dir_fid was specified. */
2032 if (root_dir_fid
!= 0) {
2035 status
= get_relative_fid_filename(conn
, req
, root_dir_fid
,
2037 if (!NT_STATUS_IS_OK(status
)) {
2044 /* Resolve the file name if this was a DFS pathname. */
2045 if ((req
!= NULL
) && (req
->flags2
& FLAGS2_DFS_PATHNAMES
)) {
2046 char *resolved_fname
;
2048 status
= resolve_dfspath(talloc_tos(), conn
, true, fname
,
2051 if (!NT_STATUS_IS_OK(status
)) {
2053 * For PATH_NOT_COVERED we had
2054 * reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
2055 * ERRSRV, ERRbadpath);
2056 * Need to fix in callers
2060 fname
= resolved_fname
;
2063 /* Check if POSIX semantics are wanted. */
2064 if (file_attributes
& FILE_FLAG_POSIX_SEMANTICS
) {
2065 case_state
= set_posix_case_semantics(talloc_tos(), conn
);
2068 /* Convert dos path to unix path if it hasn't already been done. */
2069 if (create_file_flags
& CFF_DOS_PATH
) {
2070 char *converted_fname
;
2072 SET_STAT_INVALID(sbuf
);
2074 status
= unix_convert(talloc_tos(), conn
, fname
, False
,
2075 &converted_fname
, NULL
, &sbuf
);
2076 if (!NT_STATUS_IS_OK(status
)) {
2079 fname
= converted_fname
;
2081 if (psbuf
!= NULL
) {
2084 if (SMB_VFS_STAT(conn
, fname
, &sbuf
) == -1) {
2085 SET_STAT_INVALID(sbuf
);
2091 TALLOC_FREE(case_state
);
2093 /* All file access must go through check_name() */
2094 status
= check_name(conn
, fname
);
2095 if (!NT_STATUS_IS_OK(status
)) {
2099 status
= onefs_create_file_unixpath(
2103 access_mask
, /* access_mask */
2104 share_access
, /* share_access */
2105 create_disposition
, /* create_disposition*/
2106 create_options
, /* create_options */
2107 file_attributes
, /* file_attributes */
2108 oplock_request
, /* oplock_request */
2109 allocation_size
, /* allocation_size */
2111 ea_list
, /* ea_list */
2114 &fsp_data
, /* fsp_data */
2117 if (!NT_STATUS_IS_OK(status
)) {
2121 DEBUG(10, ("onefs_create_file: info=%d\n", info
));
2124 * Setup private onefs_fsp_data. Currently the private data struct is
2125 * only used to store the oplock_callback_id so that when the file is
2126 * closed, the onefs_callback_record can be properly cleaned up in the
2127 * oplock_onefs sub-system.
2130 struct onefs_fsp_data
*fsp_data_tmp
= NULL
;
2131 fsp_data_tmp
= (struct onefs_fsp_data
*)
2132 VFS_ADD_FSP_EXTENSION(handle
, fsp
, struct onefs_fsp_data
,
2133 &destroy_onefs_fsp_data
);
2135 if (fsp_data_tmp
== NULL
) {
2136 status
= NT_STATUS_NO_MEMORY
;
2140 *fsp_data_tmp
= fsp_data
;
2144 if (pinfo
!= NULL
) {
2147 if (psbuf
!= NULL
) {
2150 return NT_STATUS_OK
;
2153 DEBUG(10, ("onefs_create_file: %s\n", nt_errstr(status
)));
2156 close_file(req
, fsp
, ERROR_CLOSE
);