2 * Unix SMB/CIFS implementation.
4 * This file began with some code from source3/smbd/open.c and modified it to
5 * 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 extern const struct generic_mapping file_generic_mapping
;
38 extern bool global_client_failed_oplock_break
;
40 struct deferred_open_record
{
41 bool delayed_for_oplocks
;
42 bool failed
; /* added for onefs_oplocks */
46 static NTSTATUS
onefs_create_file_unixpath(connection_struct
*conn
,
47 struct smb_request
*req
,
50 uint32_t share_access
,
51 uint32_t create_disposition
,
52 uint32_t create_options
,
53 uint32_t file_attributes
,
54 uint32_t oplock_request
,
55 uint64_t allocation_size
,
56 struct security_descriptor
*sd
,
57 struct ea_list
*ea_list
,
59 files_struct
**result
,
61 SMB_STRUCT_STAT
*psbuf
);
63 /****************************************************************************
65 ****************************************************************************/
67 static NTSTATUS
onefs_open_file(files_struct
*fsp
,
68 connection_struct
*conn
,
69 struct smb_request
*req
,
70 const char *parent_dir
,
73 SMB_STRUCT_STAT
*psbuf
,
77 uint32 open_access_mask
,
81 uint32 create_options
,
82 uint32_t new_dos_attributes
,
83 struct security_descriptor
*sd
,
86 NTSTATUS status
= NT_STATUS_OK
;
87 int accmode
= (flags
& O_ACCMODE
);
88 int local_flags
= flags
;
89 bool file_existed
= VALID_STAT(*psbuf
);
95 /* Check permissions */
98 * This code was changed after seeing a client open request
99 * containing the open mode of (DENY_WRITE/read-only) with
100 * the 'create if not exist' bit set. The previous code
101 * would fail to open the file read only on a read-only share
102 * as it was checking the flags parameter directly against O_RDONLY,
103 * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
107 if (!CAN_WRITE(conn
)) {
108 /* It's a read-only share - fail if we wanted to write. */
109 if(accmode
!= O_RDONLY
) {
110 DEBUG(3,("Permission denied opening %s\n", path
));
111 return NT_STATUS_ACCESS_DENIED
;
112 } else if(flags
& O_CREAT
) {
113 /* We don't want to write - but we must make sure that
114 O_CREAT doesn't create the file if we have write
115 access into the directory.
118 local_flags
&= ~O_CREAT
;
123 * This little piece of insanity is inspired by the
124 * fact that an NT client can open a file for O_RDONLY,
125 * but set the create disposition to FILE_EXISTS_TRUNCATE.
126 * If the client *can* write to the file, then it expects to
127 * truncate the file, even though it is opening for readonly.
128 * Quicken uses this stupid trick in backup file creation...
129 * Thanks *greatly* to "David W. Chapman Jr." <dwcjr@inethouston.net>
130 * for helping track this one down. It didn't bite us in 2.0.x
131 * as we always opened files read-write in that release. JRA.
134 if ((accmode
== O_RDONLY
) && ((flags
& O_TRUNC
) == O_TRUNC
)) {
135 DEBUG(10,("onefs_open_file: truncate requested on read-only "
136 "open for file %s\n", path
));
137 local_flags
= (flags
& ~O_ACCMODE
)|O_RDWR
;
140 #if defined(O_NONBLOCK) && defined(S_ISFIFO)
142 * We would block on opening a FIFO with no one else on the
143 * other end. Do what we used to do and add O_NONBLOCK to the
147 if (file_existed
&& S_ISFIFO(psbuf
->st_mode
)) {
148 local_flags
|= O_NONBLOCK
;
152 /* Don't create files with Microsoft wildcard characters. */
155 * wildcard characters are allowed in stream names
156 * only test the basefilename
158 wild
= fsp
->base_fsp
->fsp_name
;
162 if ((local_flags
& O_CREAT
) && !file_existed
&&
165 * XXX: may need to remvoe this return...
167 * We dont think this check needs to exist. All it does is
168 * block creating files with Microsoft wildcards, which is
169 * fine if the creation originated from NFS or locally and
170 * then was copied via Samba.
172 DEBUG(1, ("onefs_open_file: creating file with wildcard: %s\n",
174 return NT_STATUS_OBJECT_NAME_INVALID
;
177 /* Actually do the open */
181 * Never follow symlinks on a POSIX client. The
182 * client should be doing this.
185 if (fsp
->posix_open
|| !lp_symlinks(SNUM(conn
))) {
189 /* Don't request an oplock if oplocks are turned off for the
191 if (!lp_oplocks(SNUM(conn
)))
194 fsp
->fh
->fd
= onefs_sys_create_file(conn
,
209 if (fsp
->fh
->fd
== -1) {
210 if (errno
== EMFILE
) {
211 static time_t last_warned
= 0L;
213 if (time((time_t *) NULL
) > last_warned
) {
214 DEBUG(0, ("Too many open files, unable "
215 "to open more! smbd's max "
216 "open files = %d, also check "
217 "sysctl kern.maxfiles and "
218 "sysctl kern.maxfilesperproc\n",
219 lp_max_open_files()));
220 last_warned
= time((time_t *) NULL
);
224 status
= map_nt_error_from_unix(errno
);
225 DEBUG(3,("Error opening file %s (%s) (local_flags=%d) "
227 path
,nt_errstr(status
),local_flags
,flags
));
231 if ((local_flags
& O_CREAT
) && !file_existed
) {
233 /* Inherit the ACL if required */
234 if (lp_inherit_perms(SNUM(conn
))) {
235 inherit_access_posix_acl(conn
, parent_dir
, path
,
239 /* Change the owner if required. */
240 if (lp_inherit_owner(SNUM(conn
))) {
241 change_file_owner_to_parent(conn
, parent_dir
,
245 notify_fname(conn
, NOTIFY_ACTION_ADDED
,
246 FILE_NOTIFY_CHANGE_FILE_NAME
, path
);
252 if (fsp
->fh
->fd
== -1) {
253 ret
= SMB_VFS_STAT(conn
, path
, psbuf
);
255 ret
= SMB_VFS_FSTAT(fsp
, psbuf
);
256 /* If we have an fd, this stat should succeed. */
258 DEBUG(0,("Error doing fstat on open file %s "
259 "(%s)\n", path
,strerror(errno
) ));
263 /* For a non-io open, this stat failing means file not found. JRA */
265 status
= map_nt_error_from_unix(errno
);
272 * POSIX allows read-only opens of directories. We don't
273 * want to do this (we use a different code path for this)
274 * so catch a directory open and return an EISDIR. JRA.
277 if(S_ISDIR(psbuf
->st_mode
)) {
280 return NT_STATUS_FILE_IS_A_DIRECTORY
;
283 fsp
->mode
= psbuf
->st_mode
;
284 fsp
->file_id
= vfs_file_id_from_sbuf(conn
, psbuf
);
285 fsp
->vuid
= req
? req
->vuid
: UID_FIELD_INVALID
;
286 fsp
->file_pid
= req
? req
->smbpid
: 0;
287 fsp
->can_lock
= True
;
288 fsp
->can_read
= (access_mask
& (FILE_READ_DATA
)) ? True
: False
;
289 if (!CAN_WRITE(conn
)) {
290 fsp
->can_write
= False
;
292 fsp
->can_write
= (access_mask
& (FILE_WRITE_DATA
| FILE_APPEND_DATA
)) ?
295 fsp
->print_file
= False
;
296 fsp
->modified
= False
;
297 fsp
->sent_oplock_break
= NO_BREAK_SENT
;
298 fsp
->is_directory
= False
;
299 if (conn
->aio_write_behind_list
&&
300 is_in_path(path
, conn
->aio_write_behind_list
, conn
->case_sensitive
)) {
301 fsp
->aio_write_behind
= True
;
304 string_set(&fsp
->fsp_name
, path
);
305 fsp
->wcp
= NULL
; /* Write cache pointer. */
307 DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
308 conn
->server_info
->unix_name
,
310 BOOLSTR(fsp
->can_read
), BOOLSTR(fsp
->can_write
),
311 conn
->num_files_open
));
317 /****************************************************************************
318 Handle the 1 second delay in returning a SHARING_VIOLATION error.
319 ****************************************************************************/
321 static void defer_open(struct share_mode_lock
*lck
,
322 struct timeval request_time
,
323 struct timeval timeout
,
324 struct smb_request
*req
,
325 struct deferred_open_record
*state
)
331 for (i
=0; i
<lck
->num_share_modes
; i
++) {
332 struct share_mode_entry
*e
= &lck
->share_modes
[i
];
334 if (!is_deferred_open_entry(e
)) {
338 if (procid_is_me(&e
->pid
) && (e
->op_mid
== req
->mid
)) {
339 DEBUG(0, ("Trying to defer an already deferred "
340 "request: mid=%d, exiting\n", req
->mid
));
341 exit_server("attempt to defer a deferred request");
345 /* End paranoia check */
347 DEBUG(10,("defer_open_sharing_error: time [%u.%06u] adding deferred "
348 "open entry for mid %u\n",
349 (unsigned int)request_time
.tv_sec
,
350 (unsigned int)request_time
.tv_usec
,
351 (unsigned int)req
->mid
));
353 if (!push_deferred_smb_message(req
, request_time
, timeout
,
354 (char *)state
, sizeof(*state
))) {
355 exit_server("push_deferred_smb_message failed");
357 add_deferred_open(lck
, req
->mid
, request_time
, state
->id
);
360 * Push the MID of this packet on the signing queue.
361 * We only do this once, the first time we push the packet
362 * onto the deferred open queue, as this has a side effect
363 * of incrementing the response sequence number.
366 srv_defer_sign_response(req
->mid
);
369 static void schedule_defer_open(struct share_mode_lock
*lck
,
370 struct timeval request_time
,
371 struct smb_request
*req
)
373 struct deferred_open_record state
;
375 /* This is a relative time, added to the absolute
376 request_time value to get the absolute timeout time.
377 Note that if this is the second or greater time we enter
378 this codepath for this particular request mid then
379 request_time is left as the absolute time of the *first*
380 time this request mid was processed. This is what allows
381 the request to eventually time out. */
383 struct timeval timeout
;
385 /* Normally the smbd we asked should respond within
386 * OPLOCK_BREAK_TIMEOUT seconds regardless of whether
387 * the client did, give twice the timeout as a safety
388 * measure here in case the other smbd is stuck
391 timeout
= timeval_set(OPLOCK_BREAK_TIMEOUT
*2, 0);
393 /* Nothing actually uses state.delayed_for_oplocks
394 but it's handy to differentiate in debug messages
395 between a 30 second delay due to oplock break, and
396 a 1 second delay for share mode conflicts. */
398 state
.delayed_for_oplocks
= True
;
399 state
.failed
= False
;
402 if (!request_timed_out(request_time
, timeout
)) {
403 defer_open(lck
, request_time
, timeout
, req
, &state
);
407 /****************************************************************************
408 Open a file with a share mode. Passed in an already created files_struct.
409 ****************************************************************************/
410 NTSTATUS
onefs_open_file_ntcreate(connection_struct
*conn
,
411 struct smb_request
*req
,
415 uint32 create_disposition
,
416 uint32 create_options
,
417 uint32 new_dos_attributes
,
419 struct security_descriptor
*sd
,
422 SMB_STRUCT_STAT
*psbuf
)
426 bool file_existed
= VALID_STAT(*psbuf
);
427 bool def_acl
= False
;
428 bool posix_open
= False
;
429 bool new_file_created
= False
;
431 mode_t new_unx_mode
= (mode_t
)0;
432 mode_t unx_mode
= (mode_t
)0;
434 uint32 existing_dos_attributes
= 0;
435 struct pending_message_list
*pml
= NULL
;
436 struct timeval request_time
= timeval_zero();
437 struct share_mode_lock
*lck
= NULL
;
438 uint32 open_access_mask
= access_mask
;
444 uint64 oplock_waiter
;
445 uint32 createfile_attributes
= 0;
451 * Printers are handled completely differently.
452 * Most of the passed parameters are ignored.
456 *pinfo
= FILE_WAS_CREATED
;
459 DEBUG(10, ("onefs_open_file_ntcreate: printer open fname=%s\n",
462 return print_fsp_open(req
, conn
, fname
, req
->vuid
, fsp
);
465 if (!parent_dirname_talloc(talloc_tos(), fname
, &parent_dir
,
467 return NT_STATUS_NO_MEMORY
;
470 if (new_dos_attributes
& FILE_FLAG_POSIX_SEMANTICS
) {
472 unx_mode
= (mode_t
)(new_dos_attributes
& ~FILE_FLAG_POSIX_SEMANTICS
);
473 new_dos_attributes
= 0;
475 /* We add aARCH to this as this mode is only used if the file is
477 unx_mode
= unix_mode(conn
, new_dos_attributes
| aARCH
, fname
,
481 DEBUG(10,("onefs_open_file_ntcreate: fname=%s, dos_attrs=0x%x "
482 "access_mask=0x%x share_access=0x%x "
483 "create_disposition = 0x%x create_options=0x%x "
484 "unix mode=0%o oplock_request=0x%x\n",
485 fname
, new_dos_attributes
, access_mask
, share_access
,
486 create_disposition
, create_options
, unx_mode
,
489 if ((req
== NULL
) && ((oplock_request
& INTERNAL_OPEN_ONLY
) == 0)) {
490 DEBUG(0, ("No smb request but not an internal only open!\n"));
491 return NT_STATUS_INTERNAL_ERROR
;
495 * Only non-internal opens can be deferred at all
499 && ((pml
= get_open_deferred_message(req
->mid
)) != NULL
)) {
500 struct deferred_open_record
*state
=
501 (struct deferred_open_record
*)pml
->private_data
.data
;
503 /* Remember the absolute time of the original
504 request with this mid. We'll use it later to
505 see if this has timed out. */
507 request_time
= pml
->request_time
;
509 /* Remove the deferred open entry under lock. */
510 lck
= get_share_mode_lock(talloc_tos(), state
->id
, NULL
, NULL
,
513 DEBUG(0, ("could not get share mode lock\n"));
515 del_deferred_open_entry(lck
, req
->mid
);
519 /* Ensure we don't reprocess this message. */
520 remove_deferred_open_smb_message(req
->mid
);
523 * When receiving a semlock_async_failure message, the
524 * deferred open will be marked as "failed". Returning
528 DEBUG(0, ("onefs_open_file_ntcreate: "
529 "semlock_async_failure detected!\n"));
530 return NT_STATUS_INTERNAL_ERROR
;
534 status
= check_name(conn
, fname
);
535 if (!NT_STATUS_IS_OK(status
)) {
540 new_dos_attributes
&= SAMBA_ATTRIBUTES_MASK
;
542 existing_dos_attributes
= dos_mode(conn
, fname
, psbuf
);
546 /* Setup dos_attributes to be set by ifs_createfile */
547 if (lp_store_dos_attributes(SNUM(conn
))) {
548 createfile_attributes
= (new_dos_attributes
| aARCH
) &
549 ~(FILE_ATTRIBUTE_NONINDEXED
| FILE_ATTRIBUTE_COMPRESSED
);
552 /* Ignore oplock requests if oplocks are disabled. */
553 if (!lp_oplocks(SNUM(conn
)) || global_client_failed_oplock_break
||
554 IS_VETO_OPLOCK_PATH(conn
, fname
)) {
555 /* Mask off everything except the private Samba bits. */
556 oplock_request
&= SAMBA_PRIVATE_OPLOCK_MASK
;
559 /* this is for OS/2 long file names - say we don't support them */
560 if (!lp_posix_pathnames() && strstr(fname
,".+,;=[].")) {
561 /* OS/2 Workplace shell fix may be main code stream in a later
563 DEBUG(5,("onefs_open_file_ntcreate: OS/2 long filenames are "
564 "not supported.\n"));
565 if (use_nt_status()) {
566 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
568 return NT_STATUS_DOS(ERRDOS
, ERRcannotopen
);
571 switch( create_disposition
) {
573 * Currently we're using FILE_SUPERSEDE as the same as
574 * FILE_OVERWRITE_IF but they really are
575 * different. FILE_SUPERSEDE deletes an existing file
576 * (requiring delete access) then recreates it.
579 /* If file exists replace/overwrite. If file doesn't
582 * @todo: Clear all file attributes?
583 * http://www.osronline.com/article.cfm?article=302
584 * create if not exist, trunc if exist
586 * If file exists replace/overwrite. If file doesn't
589 flags2
|= (O_CREAT
| O_TRUNC
);
592 case FILE_OVERWRITE_IF
:
593 /* If file exists replace/overwrite. If file doesn't
595 flags2
|= (O_CREAT
| O_TRUNC
);
599 /* If file exists open. If file doesn't exist error. */
601 DEBUG(5,("onefs_open_file_ntcreate: FILE_OPEN "
602 "requested for file %s and file "
603 "doesn't exist.\n", fname
));
605 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
610 /* If file exists overwrite. If file doesn't exist
613 DEBUG(5, ("onefs_open_file_ntcreate: "
614 "FILE_OVERWRITE requested for file "
615 "%s and file doesn't exist.\n",
618 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
624 /* If file exists error. If file doesn't exist
627 DEBUG(5, ("onefs_open_file_ntcreate: "
628 "FILE_CREATE requested for file %s "
629 "and file already exists.\n",
631 if (S_ISDIR(psbuf
->st_mode
)) {
636 return map_nt_error_from_unix(errno
);
638 flags2
|= (O_CREAT
|O_EXCL
);
642 /* If file exists open. If file doesn't exist
648 return NT_STATUS_INVALID_PARAMETER
;
651 /* Match attributes on file exists and overwrite. */
652 if (!posix_open
&& file_existed
&&
653 ((create_disposition
== FILE_OVERWRITE
) ||
654 (create_disposition
== FILE_OVERWRITE_IF
))) {
655 if (!open_match_attributes(conn
, fname
,
656 existing_dos_attributes
,
657 new_dos_attributes
, psbuf
->st_mode
,
658 unx_mode
, &new_unx_mode
)) {
659 DEBUG(5, ("onefs_open_file_ntcreate: attributes "
660 "missmatch for file %s (%x %x) (0%o, 0%o)\n",
661 fname
, existing_dos_attributes
,
663 (unsigned int)psbuf
->st_mode
,
664 (unsigned int)unx_mode
));
666 return NT_STATUS_ACCESS_DENIED
;
671 * OneFS understands MAXIMUM_ALLOWED_ACCESS, so only hack the
672 * access_mask, but leave the MAA for the actual open in
675 open_access_mask
= access_mask
;
676 if (open_access_mask
& MAXIMUM_ALLOWED_ACCESS
) {
677 access_mask
|= FILE_GENERIC_ALL
;
680 /* Convert GENERIC bits to specific bits. */
681 se_map_generic(&access_mask
, &file_generic_mapping
);
682 se_map_generic(&open_access_mask
, &file_generic_mapping
);
684 if ((flags2
& O_TRUNC
) || (oplock_request
& FORCE_OPLOCK_BREAK_TO_NONE
)) {
685 /* This will cause oplock breaks. */
686 open_access_mask
|= FILE_WRITE_DATA
;
689 DEBUG(10, ("onefs_open_file_ntcreate: fname=%s, after mapping "
690 "open_access_mask=%#x, access_mask=0x%x\n",
691 fname
, open_access_mask
, access_mask
));
694 * Note that we ignore the append flag as append does not
695 * mean the same thing under DOS and Unix.
698 if ((access_mask
& (FILE_WRITE_DATA
| FILE_APPEND_DATA
)) ||
699 (oplock_request
& FORCE_OPLOCK_BREAK_TO_NONE
)) {
702 * DENY_DOS opens are always underlying read-write on the
703 * file handle, no matter what the requested access mask
704 * says. Stock samba just sets the flags, but since
705 * ifs_createfile uses the access_mask, it must be updated as
706 * well. This allows BASE-DENY* to pass.
708 if (create_options
& NTCREATEX_OPTIONS_PRIVATE_DENY_DOS
) {
710 DEBUG(10,("onefs_open_file_ntcreate: deny_dos: "
711 "Adding O_RDWR to flags "
712 "(0x%x) and some READ bits to "
713 "open_access_mask (0x%x)\n",
714 flags
, open_access_mask
));
717 open_access_mask
|= (FILE_READ_ATTRIBUTES
|
718 FILE_READ_DATA
| FILE_READ_EA
| FILE_EXECUTE
);
720 } else if (access_mask
& (FILE_READ_ATTRIBUTES
|
732 /* Currently we only look at FILE_WRITE_THROUGH for create options. */
734 if ((create_options
& FILE_WRITE_THROUGH
) &&
735 lp_strict_sync(SNUM(conn
))) {
740 if (posix_open
&& (access_mask
& FILE_APPEND_DATA
)) {
744 if (!posix_open
&& !CAN_WRITE(conn
)) {
746 * We should really return a permission denied error if either
747 * O_CREAT or O_TRUNC are set, but for compatibility with
748 * older versions of Samba we just AND them out.
750 flags2
&= ~(O_CREAT
|O_TRUNC
);
754 * Apparently this is necessary because we ship with
755 * lp_acl_check_permissions = no. It is set to no because our
756 * ifs_createfile does the access check correctly. This check
757 * was added in the last merge, and the question is why is it
758 * necessary? Check out Bug 25547 and Bug 14596. The key is
759 * to figure out what case this is covering, and do some
760 * testing to see if it's actually necessary. If it is, maybe
761 * it should go upstream in open.c.
763 if (!lp_acl_check_permissions(SNUM(conn
)) &&
764 (access_mask
& DELETE_ACCESS
)) {
765 return map_nt_error_from_unix(EACCES
);
769 /* Ensure we can't write on a read-only share or file. */
770 if (flags
!= O_RDONLY
&& file_existed
&&
771 (!CAN_WRITE(conn
) || IS_DOS_READONLY(existing_dos_attributes
))) {
772 DEBUG(5, ("onefs_open_file_ntcreate: write access requested "
773 "for file %s on read only %s\n",
774 fname
, !CAN_WRITE(conn
) ? "share" : "file" ));
776 return NT_STATUS_ACCESS_DENIED
;
779 DEBUG(10, ("fsp = %p\n", fsp
));
781 fsp
->file_id
= vfs_file_id_from_sbuf(conn
, psbuf
);
782 fsp
->share_access
= share_access
;
783 fsp
->fh
->private_options
= create_options
;
784 fsp
->access_mask
= open_access_mask
; /* We change this to the
785 * requested access_mask after
786 * the open is done. */
787 fsp
->posix_open
= posix_open
;
789 /* Ensure no SAMBA_PRIVATE bits can be set. */
790 fsp
->oplock_type
= (oplock_request
& ~SAMBA_PRIVATE_OPLOCK_MASK
);
792 if (timeval_is_zero(&request_time
)) {
793 request_time
= fsp
->open_time
;
797 struct timespec old_write_time
= get_mtimespec(psbuf
);
798 id
= vfs_file_id_from_sbuf(conn
, psbuf
);
800 lck
= get_share_mode_lock(talloc_tos(), id
,
802 fname
, &old_write_time
);
805 DEBUG(0, ("Could not get share mode lock\n"));
806 return NT_STATUS_SHARING_VIOLATION
;
809 if (lck
->delete_on_close
) {
810 /* DELETE_PENDING is not deferred for a second */
812 return NT_STATUS_DELETE_PENDING
;
816 SMB_ASSERT(!file_existed
|| (lck
!= NULL
));
819 * Ensure we pay attention to default ACLs on directories. May be
820 * neccessary depending on ACL policies.
822 if ((flags2
& O_CREAT
) && lp_inherit_acls(SNUM(conn
)) &&
823 (def_acl
= directory_has_default_acl(conn
, parent_dir
))) {
827 DEBUG(4,("calling onefs_open_file with flags=0x%X flags2=0x%X "
828 "mode=0%o, access_mask = 0x%x, open_access_mask = 0x%x\n",
829 (unsigned int)flags
, (unsigned int)flags2
,
830 (unsigned int)unx_mode
, (unsigned int)access_mask
,
831 (unsigned int)open_access_mask
));
833 oplock_waiter
= 1; //ifs_oplock_wait_record(mid);
835 if (oplock_waiter
== 0) {
836 return NT_STATUS_NO_MEMORY
;
840 status
= onefs_open_file(fsp
,
855 createfile_attributes
,
859 if (!NT_STATUS_IS_OK(status
)) {
861 /* OneFS Oplock Handling */
862 if (errno
== EINPROGRESS
) {
866 struct deferred_open_record state
;
867 struct timespec old_write_time
;
869 old_write_time
= get_mtimespec(psbuf
);
871 DEBUG(3, ("Someone created file %s with an "
872 "oplock after we looked: Retrying\n",
875 * We hit the race that when we did the stat
876 * on the file it did not exist, and someone
877 * has created it in between the stat and the
878 * open_file() call. Just retry immediately.
880 id
= vfs_file_id_from_sbuf(conn
, psbuf
);
881 if (!(lck
= get_share_mode_lock(talloc_tos(),
882 id
, conn
->connectpath
, fname
,
887 DEBUG(0, ("onefs_open_file_ntcreate: "
888 "Could not get share mode "
889 "lock for %s\n", fname
));
890 status
= NT_STATUS_SHARING_VIOLATION
;
891 goto cleanup_destroy
;
894 state
.delayed_for_oplocks
= False
;
898 defer_open(lck
, request_time
,
899 timeval_zero(), req
, &state
);
901 goto cleanup_destroy
;
903 /* Waiting for an oplock */
905 schedule_defer_open(lck
, request_time
, req
);
909 /* Check for a sharing violation */
910 if ((errno
== EAGAIN
) || (errno
== EWOULDBLOCK
)) {
911 uint32 can_access_mask
;
912 bool can_access
= True
;
914 /* Check if this can be done with the deny_dos and fcb
917 /* Try to find dup fsp if possible. */
919 (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS
|
920 NTCREATEX_OPTIONS_PRIVATE_DENY_FCB
)) {
923 DEBUG(0, ("DOS open without an SMB "
925 status
= NT_STATUS_INTERNAL_ERROR
;
926 goto cleanup_destroy
;
929 /* Use the client requested access mask here,
930 * not the one we open with. */
931 status
= fcb_or_dos_open(req
,
942 if (NT_STATUS_IS_OK(status
)) {
945 *pinfo
= FILE_WAS_OPENED
;
947 status
= NT_STATUS_OK
;
953 * This next line is a subtlety we need for
954 * MS-Access. If a file open will fail due to share
955 * permissions and also for security (access) reasons,
956 * we need to return the access failed error, not the
957 * share error. We can't open the file due to kernel
958 * oplock deadlock (it's possible we failed above on
959 * the open_mode_check()) so use a userspace check.
962 if (flags
& O_RDWR
) {
963 can_access_mask
= FILE_READ_DATA
|FILE_WRITE_DATA
;
964 } else if (flags
& O_WRONLY
) {
965 can_access_mask
= FILE_WRITE_DATA
;
967 can_access_mask
= FILE_READ_DATA
;
970 if (((can_access_mask
& FILE_WRITE_DATA
) && !CAN_WRITE(conn
)) ||
971 !can_access_file_data(conn
,fname
,psbuf
,can_access_mask
)) {
976 * If we're returning a share violation, ensure we
977 * cope with the braindead 1 second delay.
979 if (!(oplock_request
& INTERNAL_OPEN_ONLY
) &&
980 lp_defer_sharing_violations()) {
981 struct timeval timeout
;
982 struct deferred_open_record state
;
985 /* this is a hack to speed up torture tests
987 timeout_usecs
= lp_parm_int(SNUM(conn
),
989 SHARING_VIOLATION_USEC_WAIT
);
991 /* This is a relative time, added to the
992 absolute request_time value to get the
993 absolute timeout time. Note that if this
994 is the second or greater time we enter this
995 codepath for this particular request mid
996 then request_time is left as the absolute
997 time of the *first* time this request mid
998 was processed. This is what allows the
999 request to eventually time out. */
1001 timeout
= timeval_set(0, timeout_usecs
);
1003 /* Nothing actually uses
1004 state.delayed_for_oplocks but it's handy to
1005 differentiate in debug messages between a
1006 30 second delay due to oplock break, and a
1007 1 second delay for share mode conflicts. */
1009 state
.delayed_for_oplocks
= False
;
1011 state
.failed
= false;
1014 && !request_timed_out(request_time
,
1016 defer_open(lck
, request_time
, timeout
,
1023 * We have detected a sharing violation here
1024 * so return the correct error code
1026 status
= NT_STATUS_SHARING_VIOLATION
;
1028 status
= NT_STATUS_ACCESS_DENIED
;
1031 goto cleanup_destroy
;
1035 * Normal error, for example EACCES
1038 //destroy_ifs_callback_record(oplock_waiter);
1044 fsp
->oplock_type
= granted_oplock
;
1046 /* XXX uncomment for oplocks */
1047 //ifs_set_oplock_callback(oplock_waiter, fsp);
1048 //fsp->oplock_callback_id = oplock_waiter;
1050 if (!file_existed
) {
1051 struct timespec old_write_time
= get_mtimespec(psbuf
);
1053 * Deal with the race condition where two smbd's detect the
1054 * file doesn't exist and do the create at the same time. One
1055 * of them will win and set a share mode, the other (ie. this
1056 * one) should check if the requested share mode for this
1057 * create is allowed.
1061 * Now the file exists and fsp is successfully opened,
1062 * fsp->dev and fsp->inode are valid and should replace the
1063 * dev=0,inode=0 from a non existent file. Spotted by
1064 * Nadav Danieli <nadavd@exanet.com>. JRA.
1069 lck
= get_share_mode_lock(talloc_tos(), id
,
1071 fname
, &old_write_time
);
1074 DEBUG(0, ("onefs_open_file_ntcreate: Could not get "
1075 "share mode lock for %s\n", fname
));
1077 return NT_STATUS_SHARING_VIOLATION
;
1080 if (lck
->delete_on_close
) {
1081 status
= NT_STATUS_DELETE_PENDING
;
1084 if (!NT_STATUS_IS_OK(status
)) {
1085 struct deferred_open_record state
;
1089 state
.delayed_for_oplocks
= False
;
1092 /* Do it all over again immediately. In the second
1093 * round we will find that the file existed and handle
1094 * the DELETE_PENDING and FCB cases correctly. No need
1095 * to duplicate the code here. Essentially this is a
1096 * "goto top of this function", but don't tell
1100 defer_open(lck
, request_time
, timeval_zero(),
1108 * We exit this block with the share entry *locked*.....
1113 SMB_ASSERT(lck
!= NULL
);
1115 /* note that we ignore failure for the following. It is
1116 basically a hack for NFS, and NFS will never set one of
1117 these only read them. Nobody but Samba can ever set a deny
1118 mode and we have already checked our more authoritative
1119 locking database for permission to set this deny mode. If
1120 the kernel refuses the operations then the kernel is wrong.
1121 note that GPFS supports it as well - jmcd */
1123 if (fsp
->fh
->fd
!= -1) {
1124 ret_flock
= SMB_VFS_KERNEL_FLOCK(fsp
, share_access
);
1125 if(ret_flock
== -1 ){
1129 return NT_STATUS_SHARING_VIOLATION
;
1134 * At this point onwards, we can guarentee that the share entry
1135 * is locked, whether we created the file or not, and that the
1136 * deny mode is compatible with all current opens.
1139 /* Record the options we were opened with. */
1140 fsp
->share_access
= share_access
;
1141 fsp
->fh
->private_options
= create_options
;
1143 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
1145 fsp
->access_mask
= access_mask
| FILE_READ_ATTRIBUTES
;
1148 /* stat opens on existing files don't get oplocks. */
1149 if (is_stat_open(open_access_mask
)) {
1150 fsp
->oplock_type
= NO_OPLOCK
;
1153 if (!(flags2
& O_TRUNC
)) {
1154 info
= FILE_WAS_OPENED
;
1156 info
= FILE_WAS_OVERWRITTEN
;
1159 info
= FILE_WAS_CREATED
;
1167 * Setup the oplock info in both the shared memory and
1171 if ((fsp
->oplock_type
!= NO_OPLOCK
) &&
1172 (fsp
->oplock_type
!= FAKE_LEVEL_II_OPLOCK
)) {
1173 if (!set_file_oplock(fsp
, fsp
->oplock_type
)) {
1174 /* Could not get the kernel oplock */
1175 fsp
->oplock_type
= NO_OPLOCK
;
1179 if (info
== FILE_WAS_OVERWRITTEN
|| info
== FILE_WAS_CREATED
||
1180 info
== FILE_WAS_SUPERSEDED
) {
1181 new_file_created
= True
;
1184 set_share_mode(lck
, fsp
, conn
->server_info
->utok
.uid
, 0,
1187 /* Handle strange delete on close create semantics. */
1188 if (create_options
& FILE_DELETE_ON_CLOSE
) {
1189 status
= can_set_delete_on_close(fsp
, True
, new_dos_attributes
);
1191 if (!NT_STATUS_IS_OK(status
)) {
1192 /* Remember to delete the mode we just added. */
1193 del_share_mode(lck
, fsp
);
1198 /* Note that here we set the *inital* delete on close flag,
1199 not the regular one. The magic gets handled in close. */
1200 fsp
->initial_delete_on_close
= True
;
1204 * Take care of inherited ACLs on created files - if default ACL not
1206 * May be necessary depending on acl policies.
1208 if (!posix_open
&& !file_existed
&& !def_acl
&& !(VALID_STAT(*psbuf
)
1209 && (psbuf
->st_flags
& SF_HASNTFSACL
))) {
1211 int saved_errno
= errno
; /* We might get ENOSYS in the next
1214 if (SMB_VFS_FCHMOD_ACL(fsp
, unx_mode
) == -1 &&
1216 errno
= saved_errno
; /* Ignore ENOSYS */
1219 } else if (new_unx_mode
) {
1223 /* Attributes need changing. File already existed. */
1226 int saved_errno
= errno
; /* We might get ENOSYS in the
1228 ret
= SMB_VFS_FCHMOD_ACL(fsp
, new_unx_mode
);
1230 if (ret
== -1 && errno
== ENOSYS
) {
1231 errno
= saved_errno
; /* Ignore ENOSYS */
1233 DEBUG(5, ("onefs_open_file_ntcreate: reset "
1234 "attributes of file %s to 0%o\n",
1235 fname
, (unsigned int)new_unx_mode
));
1236 ret
= 0; /* Don't do the fchmod below. */
1241 (SMB_VFS_FCHMOD(fsp
, new_unx_mode
) == -1))
1242 DEBUG(5, ("onefs_open_file_ntcreate: failed to reset "
1243 "attributes of file %s to 0%o\n",
1244 fname
, (unsigned int)new_unx_mode
));
1247 /* If this is a successful open, we must remove any deferred open
1250 del_deferred_open_entry(lck
, req
->mid
);
1254 return NT_STATUS_OK
;
1258 /****************************************************************************
1259 Open a directory from an NT SMB call.
1260 ****************************************************************************/
1261 static NTSTATUS
onefs_open_directory(connection_struct
*conn
,
1262 struct smb_request
*req
,
1265 uint32 share_access
,
1266 uint32 create_disposition
,
1267 uint32 create_options
,
1268 uint32 file_attributes
,
1269 struct security_descriptor
*sd
,
1270 files_struct
**result
,
1272 SMB_STRUCT_STAT
*psbuf
)
1274 files_struct
*fsp
= NULL
;
1275 struct share_mode_lock
*lck
= NULL
;
1277 struct timespec mtimespec
;
1280 const char *dirname
;
1281 bool posix_open
= false;
1282 uint32 create_flags
= 0;
1283 uint32 mode
= lp_dir_mask(SNUM(conn
));
1285 DEBUG(5, ("onefs_open_directory: opening directory %s, "
1286 "access_mask = 0x%x, "
1287 "share_access = 0x%x create_options = 0x%x, "
1288 "create_disposition = 0x%x, file_attributes = 0x%x\n",
1289 fname
, (unsigned int)access_mask
, (unsigned int)share_access
,
1290 (unsigned int)create_options
, (unsigned int)create_disposition
,
1291 (unsigned int)file_attributes
));
1293 if (!(file_attributes
& FILE_FLAG_POSIX_SEMANTICS
) &&
1294 (conn
->fs_capabilities
& FILE_NAMED_STREAMS
) &&
1295 is_ntfs_stream_name(fname
)) {
1296 DEBUG(2, ("onefs_open_directory: %s is a stream name!\n", fname
));
1297 return NT_STATUS_NOT_A_DIRECTORY
;
1300 switch (create_disposition
) {
1302 /* If directory exists open. If directory doesn't
1305 info
= FILE_WAS_OPENED
;
1308 /* If directory exists error. If directory doesn't
1310 create_flags
= O_CREAT
| O_EXCL
;
1311 info
= FILE_WAS_CREATED
;
1314 /* If directory exists open. If directory doesn't
1317 /* Note: in order to return whether the directory was
1318 * opened or created, we first try to open and then try
1321 info
= FILE_WAS_OPENED
;
1323 case FILE_SUPERSEDE
:
1324 case FILE_OVERWRITE
:
1325 case FILE_OVERWRITE_IF
:
1327 DEBUG(5, ("onefs_open_directory: invalid "
1328 "create_disposition 0x%x for directory %s\n",
1329 (unsigned int)create_disposition
, fname
));
1330 return NT_STATUS_INVALID_PARAMETER
;
1334 * Check for write access to the share. Done in mkdir_internal() in
1337 if (!CAN_WRITE(conn
) && (create_flags
& O_CREAT
)) {
1338 return NT_STATUS_ACCESS_DENIED
;
1341 /* Get parent dirname */
1342 if (!parent_dirname_talloc(talloc_tos(), fname
, &parent_dir
,
1344 return NT_STATUS_NO_MEMORY
;
1347 if (file_attributes
& FILE_FLAG_POSIX_SEMANTICS
) {
1349 mode
= (mode_t
)(file_attributes
& ~FILE_FLAG_POSIX_SEMANTICS
);
1350 file_attributes
= 0;
1352 mode
= unix_mode(conn
, aDIR
, fname
, parent_dir
);
1356 * The NONINDEXED and COMPRESSED bits seem to always be cleared on
1357 * directories, no matter if you specify that they should be set.
1360 ~(FILE_ATTRIBUTE_NONINDEXED
| FILE_ATTRIBUTE_COMPRESSED
);
1362 status
= file_new(req
, conn
, &fsp
);
1363 if(!NT_STATUS_IS_OK(status
)) {
1368 * Actual open with retry magic to handle FILE_OPEN_IF which is
1369 * unique because the kernel won't tell us if the file was opened or
1373 fsp
->fh
->fd
= onefs_sys_create_file(conn
,
1380 create_flags
| O_DIRECTORY
,
1388 if (fsp
->fh
->fd
== -1) {
1389 DEBUG(3, ("Error opening %s. Errno=%d (%s).\n", fname
, errno
,
1391 SMB_ASSERT(errno
!= EINPROGRESS
);
1393 if (create_disposition
== FILE_OPEN_IF
) {
1394 if (errno
== ENOENT
) {
1395 /* Try again, creating it this time. */
1396 create_flags
= O_CREAT
| O_EXCL
;
1397 info
= FILE_WAS_CREATED
;
1399 } else if (errno
== EEXIST
) {
1400 /* Uggh. Try again again. */
1402 info
= FILE_WAS_OPENED
;
1407 /* Error cases below: */
1408 file_free(req
, fsp
);
1410 if ((errno
== ENOENT
) && (create_disposition
== FILE_OPEN
)) {
1411 DEBUG(5,("onefs_open_directory: FILE_OPEN requested "
1412 "for directory %s and it doesn't "
1413 "exist.\n", fname
));
1414 return NT_STATUS_OBJECT_NAME_NOT_FOUND
;
1415 } else if ((errno
== EEXIST
) &&
1416 (create_disposition
== FILE_CREATE
)) {
1417 DEBUG(5,("onefs_open_directory: FILE_CREATE "
1418 "requested for directory %s and it "
1419 "already exists.\n", fname
));
1420 return NT_STATUS_OBJECT_NAME_COLLISION
;
1421 } else if ((errno
== EAGAIN
) || (errno
== EWOULDBLOCK
)) {
1422 /* Catch sharing violations. */
1423 return NT_STATUS_SHARING_VIOLATION
;
1426 return map_nt_error_from_unix(errno
);
1429 if (info
== FILE_WAS_CREATED
) {
1431 /* Pulled from mkdir_internal() */
1432 if (SMB_VFS_LSTAT(conn
, fname
, psbuf
) == -1) {
1433 DEBUG(2, ("Could not stat directory '%s' just "
1434 "created: %s\n",fname
, strerror(errno
)));
1435 return map_nt_error_from_unix(errno
);
1438 if (!S_ISDIR(psbuf
->st_mode
)) {
1439 DEBUG(0, ("Directory just '%s' created is not a "
1440 "directory\n", fname
));
1441 return NT_STATUS_ACCESS_DENIED
;
1446 * Check if high bits should have been set, then (if
1447 * bits are missing): add them. Consider bits
1448 * automagically set by UNIX, i.e. SGID bit from
1451 if (mode
& ~(S_IRWXU
|S_IRWXG
|S_IRWXO
) &&
1452 (mode
& ~psbuf
->st_mode
)) {
1453 SMB_VFS_CHMOD(conn
, fname
, (psbuf
->st_mode
|
1454 (mode
& ~psbuf
->st_mode
)));
1458 /* Change the owner if required. */
1459 if (lp_inherit_owner(SNUM(conn
))) {
1460 change_dir_owner_to_parent(conn
, parent_dir
, fname
,
1464 notify_fname(conn
, NOTIFY_ACTION_ADDED
,
1465 FILE_NOTIFY_CHANGE_DIR_NAME
, fname
);
1468 /* Stat the fd for Samba bookkeeping. */
1469 if(SMB_VFS_FSTAT(fsp
, psbuf
) != 0) {
1471 file_free(req
, fsp
);
1472 return map_nt_error_from_unix(errno
);
1475 /* Setup the files_struct for it. */
1476 fsp
->mode
= psbuf
->st_mode
;
1477 fsp
->file_id
= vfs_file_id_from_sbuf(conn
, psbuf
);
1478 fsp
->vuid
= req
? req
->vuid
: UID_FIELD_INVALID
;
1479 fsp
->file_pid
= req
? req
->smbpid
: 0;
1480 fsp
->can_lock
= False
;
1481 fsp
->can_read
= False
;
1482 fsp
->can_write
= False
;
1484 fsp
->share_access
= share_access
;
1485 fsp
->fh
->private_options
= create_options
;
1487 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
1489 fsp
->access_mask
= access_mask
| FILE_READ_ATTRIBUTES
;
1490 fsp
->print_file
= False
;
1491 fsp
->modified
= False
;
1492 fsp
->oplock_type
= NO_OPLOCK
;
1493 fsp
->sent_oplock_break
= NO_BREAK_SENT
;
1494 fsp
->is_directory
= True
;
1495 fsp
->posix_open
= posix_open
;
1497 string_set(&fsp
->fsp_name
,fname
);
1499 mtimespec
= get_mtimespec(psbuf
);
1502 * Still set the samba share mode lock for correct delete-on-close
1503 * semantics and to make smbstatus more useful.
1505 lck
= get_share_mode_lock(talloc_tos(), fsp
->file_id
,
1510 DEBUG(0, ("onefs_open_directory: Could not get share mode "
1511 "lock for %s\n", fname
));
1513 file_free(req
, fsp
);
1514 return NT_STATUS_SHARING_VIOLATION
;
1517 if (lck
->delete_on_close
) {
1520 file_free(req
, fsp
);
1521 return NT_STATUS_DELETE_PENDING
;
1524 set_share_mode(lck
, fsp
, conn
->server_info
->utok
.uid
, 0, NO_OPLOCK
);
1527 * For directories the delete on close bit at open time seems
1528 * always to be honored on close... See test 19 in Samba4 BASE-DELETE.
1530 if (create_options
& FILE_DELETE_ON_CLOSE
) {
1531 status
= can_set_delete_on_close(fsp
, True
, 0);
1532 if (!NT_STATUS_IS_OK(status
) &&
1533 !NT_STATUS_EQUAL(status
, NT_STATUS_DIRECTORY_NOT_EMPTY
)) {
1536 file_free(req
, fsp
);
1540 if (NT_STATUS_IS_OK(status
)) {
1541 /* Note that here we set the *inital* delete on close flag,
1542 not the regular one. The magic gets handled in close. */
1543 fsp
->initial_delete_on_close
= True
;
1554 return NT_STATUS_OK
;
1558 * If a main file is opened for delete, all streams need to be checked for
1559 * !FILE_SHARE_DELETE. Do this by opening with DELETE_ACCESS.
1560 * If that works, delete them all by setting the delete on close and close.
1563 static NTSTATUS
open_streams_for_delete(connection_struct
*conn
,
1566 struct stream_struct
*stream_info
;
1567 files_struct
**streams
;
1569 unsigned int num_streams
;
1570 TALLOC_CTX
*frame
= talloc_stackframe();
1573 status
= SMB_VFS_STREAMINFO(conn
, NULL
, fname
, talloc_tos(),
1574 &num_streams
, &stream_info
);
1576 if (NT_STATUS_EQUAL(status
, NT_STATUS_NOT_IMPLEMENTED
)
1577 || NT_STATUS_EQUAL(status
, NT_STATUS_OBJECT_NAME_NOT_FOUND
)) {
1578 DEBUG(10, ("no streams around\n"));
1580 return NT_STATUS_OK
;
1583 if (!NT_STATUS_IS_OK(status
)) {
1584 DEBUG(10, ("SMB_VFS_STREAMINFO failed: %s\n",
1585 nt_errstr(status
)));
1589 DEBUG(10, ("open_streams_for_delete found %d streams\n",
1592 if (num_streams
== 0) {
1594 return NT_STATUS_OK
;
1597 streams
= TALLOC_ARRAY(talloc_tos(), files_struct
*, num_streams
);
1598 if (streams
== NULL
) {
1599 DEBUG(0, ("talloc failed\n"));
1600 status
= NT_STATUS_NO_MEMORY
;
1604 for (i
=0; i
<num_streams
; i
++) {
1607 if (strequal(stream_info
[i
].name
, "::$DATA")) {
1612 streamname
= talloc_asprintf(talloc_tos(), "%s%s", fname
,
1613 stream_info
[i
].name
);
1615 if (streamname
== NULL
) {
1616 DEBUG(0, ("talloc_aprintf failed\n"));
1617 status
= NT_STATUS_NO_MEMORY
;
1621 status
= onefs_create_file_unixpath
1624 streamname
, /* fname */
1625 DELETE_ACCESS
, /* access_mask */
1626 FILE_SHARE_READ
| FILE_SHARE_WRITE
1627 | FILE_SHARE_DELETE
, /* share_access */
1628 FILE_OPEN
, /* create_disposition*/
1629 NTCREATEX_OPTIONS_PRIVATE_STREAM_DELETE
, /* create_options */
1630 FILE_ATTRIBUTE_NORMAL
, /* file_attributes */
1631 0, /* oplock_request */
1632 0, /* allocation_size */
1635 &streams
[i
], /* result */
1639 TALLOC_FREE(streamname
);
1641 if (!NT_STATUS_IS_OK(status
)) {
1642 DEBUG(10, ("Could not open stream %s: %s\n",
1643 streamname
, nt_errstr(status
)));
1649 * don't touch the variable "status" beyond this point :-)
1652 for (i
-= 1 ; i
>= 0; i
--) {
1653 if (streams
[i
] == NULL
) {
1657 DEBUG(10, ("Closing stream # %d, %s\n", i
,
1658 streams
[i
]->fsp_name
));
1659 close_file(NULL
, streams
[i
], NORMAL_CLOSE
);
1668 * Wrapper around onefs_open_file_ntcreate and onefs_open_directory.
1670 static NTSTATUS
onefs_create_file_unixpath(connection_struct
*conn
,
1671 struct smb_request
*req
,
1673 uint32_t access_mask
,
1674 uint32_t share_access
,
1675 uint32_t create_disposition
,
1676 uint32_t create_options
,
1677 uint32_t file_attributes
,
1678 uint32_t oplock_request
,
1679 uint64_t allocation_size
,
1680 struct security_descriptor
*sd
,
1681 struct ea_list
*ea_list
,
1682 files_struct
**result
,
1684 SMB_STRUCT_STAT
*psbuf
)
1686 SMB_STRUCT_STAT sbuf
;
1687 int info
= FILE_WAS_OPENED
;
1688 files_struct
*base_fsp
= NULL
;
1689 files_struct
*fsp
= NULL
;
1692 DEBUG(10,("onefs_create_file_unixpath: access_mask = 0x%x "
1693 "file_attributes = 0x%x, share_access = 0x%x, "
1694 "create_disposition = 0x%x create_options = 0x%x "
1695 "oplock_request = 0x%x ea_list = 0x%p, sd = 0x%p, "
1697 (unsigned int)access_mask
,
1698 (unsigned int)file_attributes
,
1699 (unsigned int)share_access
,
1700 (unsigned int)create_disposition
,
1701 (unsigned int)create_options
,
1702 (unsigned int)oplock_request
,
1703 ea_list
, sd
, fname
));
1705 if (create_options
& FILE_OPEN_BY_FILE_ID
) {
1706 status
= NT_STATUS_NOT_SUPPORTED
;
1710 if (create_options
& NTCREATEX_OPTIONS_INVALID_PARAM_MASK
) {
1711 status
= NT_STATUS_INVALID_PARAMETER
;
1716 oplock_request
|= INTERNAL_OPEN_ONLY
;
1719 if (psbuf
!= NULL
) {
1723 if (SMB_VFS_STAT(conn
, fname
, &sbuf
) == -1) {
1724 SET_STAT_INVALID(sbuf
);
1728 if ((conn
->fs_capabilities
& FILE_NAMED_STREAMS
)
1729 && (access_mask
& DELETE_ACCESS
)
1730 && !is_ntfs_stream_name(fname
)) {
1732 * We can't open a file with DELETE access if any of the
1733 * streams is open without FILE_SHARE_DELETE
1735 status
= open_streams_for_delete(conn
, fname
);
1737 if (!NT_STATUS_IS_OK(status
)) {
1742 if ((conn
->fs_capabilities
& FILE_NAMED_STREAMS
)
1743 && is_ntfs_stream_name(fname
)
1744 && (!(create_options
& NTCREATEX_OPTIONS_PRIVATE_STREAM_DELETE
))) {
1746 uint32 base_create_disposition
;
1748 if (create_options
& FILE_DIRECTORY_FILE
) {
1749 status
= NT_STATUS_NOT_A_DIRECTORY
;
1753 status
= split_ntfs_stream_name(talloc_tos(), fname
,
1755 if (!NT_STATUS_IS_OK(status
)) {
1756 DEBUG(10, ("onefs_create_file_unixpath: "
1757 "split_ntfs_stream_name failed: %s\n",
1758 nt_errstr(status
)));
1762 SMB_ASSERT(!is_ntfs_stream_name(base
)); /* paranoia.. */
1764 switch (create_disposition
) {
1766 base_create_disposition
= FILE_OPEN
;
1769 base_create_disposition
= FILE_OPEN_IF
;
1773 status
= onefs_create_file_unixpath(
1777 0, /* access_mask */
1780 FILE_SHARE_DELETE
), /* share_access */
1781 base_create_disposition
, /* create_disposition*/
1782 0, /* create_options */
1783 0, /* file_attributes */
1784 NO_OPLOCK
, /* oplock_request */
1785 0, /* allocation_size */
1788 &base_fsp
, /* result */
1792 if (!NT_STATUS_IS_OK(status
)) {
1793 DEBUG(10, ("onefs_create_file_unixpath for base %s "
1794 "failed: %s\n", base
, nt_errstr(status
)));
1798 * we don't need to low level fd: This might conflict with
1804 /* Covert generic bits in the security descriptor. */
1806 security_acl_map_generic(sd
->dacl
, &file_generic_mapping
);
1807 security_acl_map_generic(sd
->sacl
, &file_generic_mapping
);
1811 * If it's a request for a directory open, deal with it separately.
1814 if (create_options
& FILE_DIRECTORY_FILE
) {
1816 if (create_options
& FILE_NON_DIRECTORY_FILE
) {
1817 status
= NT_STATUS_INVALID_PARAMETER
;
1821 /* Can't open a temp directory. IFS kit test. */
1822 if (!(file_attributes
& FILE_FLAG_POSIX_SEMANTICS
) &&
1823 (file_attributes
& FILE_ATTRIBUTE_TEMPORARY
)) {
1824 status
= NT_STATUS_INVALID_PARAMETER
;
1829 * We will get a create directory here if the Win32
1830 * app specified a security descriptor in the
1831 * CreateDirectory() call.
1834 status
= onefs_open_directory(
1838 access_mask
, /* access_mask */
1839 share_access
, /* share_access */
1840 create_disposition
, /* create_disposition*/
1841 create_options
, /* create_options */
1842 file_attributes
, /* file_attributes */
1850 * Ordinary file case.
1853 status
= file_new(req
, conn
, &fsp
);
1854 if(!NT_STATUS_IS_OK(status
)) {
1859 * We're opening the stream element of a base_fsp
1860 * we already opened. Set up the base_fsp pointer.
1863 fsp
->base_fsp
= base_fsp
;
1866 status
= onefs_open_file_ntcreate(
1870 access_mask
, /* access_mask */
1871 share_access
, /* share_access */
1872 create_disposition
, /* create_disposition*/
1873 create_options
, /* create_options */
1874 file_attributes
, /* file_attributes */
1875 oplock_request
, /* oplock_request */
1881 if(!NT_STATUS_IS_OK(status
)) {
1882 file_free(req
, fsp
);
1886 if (NT_STATUS_EQUAL(status
, NT_STATUS_FILE_IS_A_DIRECTORY
)) {
1888 /* A stream open never opens a directory */
1891 status
= NT_STATUS_FILE_IS_A_DIRECTORY
;
1896 * Fail the open if it was explicitly a non-directory
1900 if (create_options
& FILE_NON_DIRECTORY_FILE
) {
1901 status
= NT_STATUS_FILE_IS_A_DIRECTORY
;
1905 create_options
|= FILE_DIRECTORY_FILE
;
1907 status
= onefs_open_directory(
1911 access_mask
, /* access_mask */
1912 share_access
, /* share_access */
1913 create_disposition
, /* create_disposition*/
1914 create_options
, /* create_options */
1915 file_attributes
, /* file_attributes */
1923 if (!NT_STATUS_IS_OK(status
)) {
1927 fsp
->base_fsp
= base_fsp
;
1931 if ((ea_list
!= NULL
) && (info
== FILE_WAS_CREATED
)) {
1932 status
= set_ea(conn
, fsp
, fname
, ea_list
);
1933 if (!NT_STATUS_IS_OK(status
)) {
1938 if (!fsp
->is_directory
&& S_ISDIR(sbuf
.st_mode
)) {
1939 status
= NT_STATUS_ACCESS_DENIED
;
1943 /* Save the requested allocation size. */
1944 if ((info
== FILE_WAS_CREATED
) || (info
== FILE_WAS_OVERWRITTEN
)) {
1946 && (allocation_size
> sbuf
.st_size
)) {
1947 fsp
->initial_allocation_size
= smb_roundup(
1948 fsp
->conn
, allocation_size
);
1949 if (fsp
->is_directory
) {
1950 /* Can't set allocation size on a directory. */
1951 status
= NT_STATUS_ACCESS_DENIED
;
1954 if (vfs_allocate_file_space(
1955 fsp
, fsp
->initial_allocation_size
) == -1) {
1956 status
= NT_STATUS_DISK_FULL
;
1960 fsp
->initial_allocation_size
= smb_roundup(
1961 fsp
->conn
, (uint64_t)sbuf
.st_size
);
1965 DEBUG(10, ("onefs_create_file_unixpath: info=%d\n", info
));
1968 if (pinfo
!= NULL
) {
1971 if (psbuf
!= NULL
) {
1972 if ((fsp
->fh
== NULL
) || (fsp
->fh
->fd
== -1)) {
1976 SMB_VFS_FSTAT(fsp
, psbuf
);
1979 return NT_STATUS_OK
;
1982 DEBUG(10, ("onefs_create_file_unixpath: %s\n", nt_errstr(status
)));
1985 if (base_fsp
&& fsp
->base_fsp
== base_fsp
) {
1987 * The close_file below will close
1992 close_file(req
, fsp
, ERROR_CLOSE
);
1995 if (base_fsp
!= NULL
) {
1996 close_file(req
, base_fsp
, ERROR_CLOSE
);
2003 * SMB_VFS_CREATE_FILE interface to onefs.
2005 NTSTATUS
onefs_create_file(vfs_handle_struct
*handle
,
2006 struct smb_request
*req
,
2007 uint16_t root_dir_fid
,
2009 uint32_t create_file_flags
,
2010 uint32_t access_mask
,
2011 uint32_t share_access
,
2012 uint32_t create_disposition
,
2013 uint32_t create_options
,
2014 uint32_t file_attributes
,
2015 uint32_t oplock_request
,
2016 uint64_t allocation_size
,
2017 struct security_descriptor
*sd
,
2018 struct ea_list
*ea_list
,
2019 files_struct
**result
,
2021 SMB_STRUCT_STAT
*psbuf
)
2023 connection_struct
*conn
= handle
->conn
;
2024 struct case_semantics_state
*case_state
= NULL
;
2025 SMB_STRUCT_STAT sbuf
;
2026 int info
= FILE_WAS_OPENED
;
2027 files_struct
*fsp
= NULL
;
2030 DEBUG(10,("onefs_create_file: access_mask = 0x%x "
2031 "file_attributes = 0x%x, share_access = 0x%x, "
2032 "create_disposition = 0x%x create_options = 0x%x "
2033 "oplock_request = 0x%x "
2034 "root_dir_fid = 0x%x, ea_list = 0x%p, sd = 0x%p, "
2035 "create_file_flags = 0x%x, fname = %s\n",
2036 (unsigned int)access_mask
,
2037 (unsigned int)file_attributes
,
2038 (unsigned int)share_access
,
2039 (unsigned int)create_disposition
,
2040 (unsigned int)create_options
,
2041 (unsigned int)oplock_request
,
2042 (unsigned int)root_dir_fid
,
2043 ea_list
, sd
, create_file_flags
, fname
));
2045 /* Get the file name if root_dir_fid was specified. */
2046 if (root_dir_fid
!= 0) {
2049 status
= get_relative_fid_filename(conn
, req
, root_dir_fid
,
2051 if (!NT_STATUS_IS_OK(status
)) {
2058 /* Resolve the file name if this was a DFS pathname. */
2059 if ((req
!= NULL
) && (req
->flags2
& FLAGS2_DFS_PATHNAMES
)) {
2060 char *resolved_fname
;
2062 status
= resolve_dfspath(talloc_tos(), conn
, true, fname
,
2065 if (!NT_STATUS_IS_OK(status
)) {
2067 * For PATH_NOT_COVERED we had
2068 * reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
2069 * ERRSRV, ERRbadpath);
2070 * Need to fix in callers
2074 fname
= resolved_fname
;
2077 /* Check if POSIX semantics are wanted. */
2078 if (file_attributes
& FILE_FLAG_POSIX_SEMANTICS
) {
2079 case_state
= set_posix_case_semantics(talloc_tos(), conn
);
2082 /* Convert dos path to unix path if it hasn't already been done. */
2083 if (create_file_flags
& CFF_DOS_PATH
) {
2084 char *converted_fname
;
2086 SET_STAT_INVALID(sbuf
);
2088 status
= unix_convert(talloc_tos(), conn
, fname
, False
,
2089 &converted_fname
, NULL
, &sbuf
);
2090 if (!NT_STATUS_IS_OK(status
)) {
2093 fname
= converted_fname
;
2095 if (psbuf
!= NULL
) {
2098 if (SMB_VFS_STAT(conn
, fname
, &sbuf
) == -1) {
2099 SET_STAT_INVALID(sbuf
);
2105 TALLOC_FREE(case_state
);
2107 /* All file access must go through check_name() */
2108 status
= check_name(conn
, fname
);
2109 if (!NT_STATUS_IS_OK(status
)) {
2113 status
= onefs_create_file_unixpath(
2117 access_mask
, /* access_mask */
2118 share_access
, /* share_access */
2119 create_disposition
, /* create_disposition*/
2120 create_options
, /* create_options */
2121 file_attributes
, /* file_attributes */
2122 oplock_request
, /* oplock_request */
2123 allocation_size
, /* allocation_size */
2125 ea_list
, /* ea_list */
2130 if (!NT_STATUS_IS_OK(status
)) {
2134 DEBUG(10, ("onefs_create_file: info=%d\n", info
));
2137 if (pinfo
!= NULL
) {
2140 if (psbuf
!= NULL
) {
2143 return NT_STATUS_OK
;
2146 DEBUG(10, ("onefs_create_file: %s\n", nt_errstr(status
)));
2149 close_file(req
, fsp
, ERROR_CLOSE
);