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 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, psbuf);
465 if (!parent_dirname(talloc_tos(), fname, &parent_dir, &newname)) {
466 return NT_STATUS_NO_MEMORY;
469 if (new_dos_attributes & FILE_FLAG_POSIX_SEMANTICS) {
471 unx_mode = (mode_t)(new_dos_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
472 new_dos_attributes = 0;
474 /* We add aARCH to this as this mode is only used if the file is
476 unx_mode = unix_mode(conn, new_dos_attributes | aARCH, fname,
480 DEBUG(10,("onefs_open_file_ntcreate: fname=%s, dos_attrs=0x%x "
481 "access_mask=0x%x share_access=0x%x "
482 "create_disposition = 0x%x create_options=0x%x "
483 "unix mode=0%o oplock_request=0x%x\n",
484 fname, new_dos_attributes, access_mask, share_access,
485 create_disposition, create_options, unx_mode,
488 if ((req == NULL) && ((oplock_request & INTERNAL_OPEN_ONLY) == 0)) {
489 DEBUG(0, ("No smb request but not an internal only open!\n"));
490 return NT_STATUS_INTERNAL_ERROR;
494 * Only non-internal opens can be deferred at all
498 && ((pml = get_open_deferred_message(req->mid)) != NULL)) {
499 struct deferred_open_record *state =
500 (struct deferred_open_record *)pml->private_data.data;
502 /* Remember the absolute time of the original
503 request with this mid. We'll use it later to
504 see if this has timed out. */
506 request_time = pml->request_time;
508 /* Remove the deferred open entry under lock. */
509 lck = get_share_mode_lock(talloc_tos(), state->id, NULL, NULL,
512 DEBUG(0, ("could not get share mode lock\n"));
514 del_deferred_open_entry(lck, req->mid);
518 /* Ensure we don't reprocess this message. */
519 remove_deferred_open_smb_message(req->mid);
522 * When receiving a semlock_async_failure message, the
523 * deferred open will be marked as "failed". Returning
527 DEBUG(0, ("onefs_open_file_ntcreate: "
528 "semlock_async_failure detected!\n"));
529 return NT_STATUS_INTERNAL_ERROR;
533 status = check_name(conn, fname);
534 if (!NT_STATUS_IS_OK(status)) {
539 new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
541 existing_dos_attributes = dos_mode(conn, fname, psbuf);
545 /* Setup dos_attributes to be set by ifs_createfile */
546 if (lp_store_dos_attributes(SNUM(conn))) {
547 createfile_attributes = (new_dos_attributes | aARCH) &
548 ~(FILE_ATTRIBUTE_NONINDEXED | FILE_ATTRIBUTE_COMPRESSED);
551 /* Ignore oplock requests if oplocks are disabled. */
552 if (!lp_oplocks(SNUM(conn)) || global_client_failed_oplock_break ||
553 IS_VETO_OPLOCK_PATH(conn, fname)) {
554 /* Mask off everything except the private Samba bits. */
555 oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
558 /* this is for OS/2 long file names - say we don't support them */
559 if (!lp_posix_pathnames() && strstr(fname,".+,;=[].")) {
560 /* OS/2 Workplace shell fix may be main code stream in a later
562 DEBUG(5,("onefs_open_file_ntcreate: OS/2 long filenames are "
563 "not supported.\n"));
564 if (use_nt_status()) {
565 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
567 return NT_STATUS_DOS(ERRDOS, ERRcannotopen);
570 switch( create_disposition ) {
572 * Currently we're using FILE_SUPERSEDE as the same as
573 * FILE_OVERWRITE_IF but they really are
574 * different. FILE_SUPERSEDE deletes an existing file
575 * (requiring delete access) then recreates it.
578 /* If file exists replace/overwrite. If file doesn't
581 * @todo: Clear all file attributes?
582 * http://www.osronline.com/article.cfm?article=302
583 * create if not exist, trunc if exist
585 * If file exists replace/overwrite. If file doesn't
588 flags2 |= (O_CREAT | O_TRUNC);
591 case FILE_OVERWRITE_IF:
592 /* If file exists replace/overwrite. If file doesn't
594 flags2 |= (O_CREAT | O_TRUNC);
598 /* If file exists open. If file doesn't exist error. */
600 DEBUG(5,("onefs_open_file_ntcreate: FILE_OPEN "
601 "requested for file %s and file "
602 "doesn't exist.\n", fname ));
604 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
609 /* If file exists overwrite. If file doesn't exist
612 DEBUG(5, ("onefs_open_file_ntcreate: "
613 "FILE_OVERWRITE requested for file "
614 "%s and file doesn't exist.\n",
617 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
623 /* If file exists error. If file doesn't exist
626 DEBUG(5, ("onefs_open_file_ntcreate: "
627 "FILE_CREATE requested for file %s "
628 "and file already exists.\n",
630 if (S_ISDIR(psbuf->st_mode)) {
635 return map_nt_error_from_unix(errno);
637 flags2 |= (O_CREAT|O_EXCL);
641 /* If file exists open. If file doesn't exist
647 return NT_STATUS_INVALID_PARAMETER;
650 /* Match attributes on file exists and overwrite. */
651 if (!posix_open && file_existed &&
652 ((create_disposition == FILE_OVERWRITE) ||
653 (create_disposition == FILE_OVERWRITE_IF))) {
654 if (!open_match_attributes(conn, fname,
655 existing_dos_attributes,
656 new_dos_attributes, psbuf->st_mode,
657 unx_mode, &new_unx_mode)) {
658 DEBUG(5, ("onefs_open_file_ntcreate: attributes "
659 "missmatch for file %s (%x %x) (0%o, 0%o)\n",
660 fname, existing_dos_attributes,
662 (unsigned int)psbuf->st_mode,
663 (unsigned int)unx_mode ));
665 return NT_STATUS_ACCESS_DENIED;
670 * OneFS understands MAXIMUM_ALLOWED_ACCESS, so only hack the
671 * access_mask, but leave the MAA for the actual open in
674 open_access_mask = access_mask;
675 if (open_access_mask & MAXIMUM_ALLOWED_ACCESS) {
676 access_mask |= FILE_GENERIC_ALL;
679 /* Convert GENERIC bits to specific bits. */
680 se_map_generic(&access_mask, &file_generic_mapping);
681 se_map_generic(&open_access_mask, &file_generic_mapping);
683 if ((flags2 & O_TRUNC) || (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE)) {
684 /* This will cause oplock breaks. */
685 open_access_mask |= FILE_WRITE_DATA;
688 DEBUG(10, ("onefs_open_file_ntcreate: fname=%s, after mapping "
689 "open_access_mask=%#x, access_mask=0x%x\n",
690 fname, open_access_mask, access_mask));
693 * Note that we ignore the append flag as append does not
694 * mean the same thing under DOS and Unix.
697 if ((access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ||
698 (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE)) {
701 * DENY_DOS opens are always underlying read-write on the
702 * file handle, no matter what the requested access mask
703 * says. Stock samba just sets the flags, but since
704 * ifs_createfile uses the access_mask, it must be updated as
705 * well. This allows BASE-DENY* to pass.
707 if (create_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) {
709 DEBUG(10,("onefs_open_file_ntcreate: deny_dos: "
710 "Adding O_RDWR to flags "
711 "(0x%x) and some READ bits to "
712 "open_access_mask (0x%x)\n",
713 flags, open_access_mask));
716 open_access_mask |= (FILE_READ_ATTRIBUTES |
717 FILE_READ_DATA | FILE_READ_EA | FILE_EXECUTE);
719 } else if (access_mask & (FILE_READ_ATTRIBUTES |
731 /* Currently we only look at FILE_WRITE_THROUGH for create options. */
733 if ((create_options & FILE_WRITE_THROUGH) &&
734 lp_strict_sync(SNUM(conn))) {
739 if (posix_open && (access_mask & FILE_APPEND_DATA)) {
743 if (!posix_open && !CAN_WRITE(conn)) {
745 * We should really return a permission denied error if either
746 * O_CREAT or O_TRUNC are set, but for compatibility with
747 * older versions of Samba we just AND them out.
749 flags2 &= ~(O_CREAT|O_TRUNC);
753 * Apparently this is necessary because we ship with
754 * lp_acl_check_permissions = no. It is set to no because our
755 * ifs_createfile does the access check correctly. This check
756 * was added in the last merge, and the question is why is it
757 * necessary? Check out Bug 25547 and Bug 14596. The key is
758 * to figure out what case this is covering, and do some
759 * testing to see if it's actually necessary. If it is, maybe
760 * it should go upstream in open.c.
762 if (!lp_acl_check_permissions(SNUM(conn)) &&
763 (access_mask & DELETE_ACCESS)) {
764 return map_nt_error_from_unix(EACCES);
768 /* Ensure we can't write on a read-only share or file. */
769 if (flags != O_RDONLY && file_existed &&
770 (!CAN_WRITE(conn) || IS_DOS_READONLY(existing_dos_attributes))) {
771 DEBUG(5, ("onefs_open_file_ntcreate: write access requested "
772 "for file %s on read only %s\n",
773 fname, !CAN_WRITE(conn) ? "share" : "file" ));
775 return NT_STATUS_ACCESS_DENIED;
778 DEBUG(10, ("fsp = %p\n", fsp));
780 fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf);
781 fsp->share_access = share_access;
782 fsp->fh->private_options = create_options;
783 fsp->access_mask = open_access_mask; /* We change this to the
784 * requested access_mask after
785 * the open is done. */
786 fsp->posix_open = posix_open;
788 /* Ensure no SAMBA_PRIVATE bits can be set. */
789 fsp->oplock_type = (oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK);
791 if (timeval_is_zero(&request_time)) {
792 request_time = fsp->open_time;
796 struct timespec old_write_time = get_mtimespec(psbuf);
797 id = vfs_file_id_from_sbuf(conn, psbuf);
799 lck = get_share_mode_lock(talloc_tos(), id,
801 fname, &old_write_time);
804 DEBUG(0, ("Could not get share mode lock\n"));
805 return NT_STATUS_SHARING_VIOLATION;
808 if (lck->delete_on_close) {
809 /* DELETE_PENDING is not deferred for a second */
811 return NT_STATUS_DELETE_PENDING;
815 SMB_ASSERT(!file_existed || (lck != NULL));
818 * Ensure we pay attention to default ACLs on directories. May be
819 * neccessary depending on ACL policies.
821 if ((flags2 & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
822 (def_acl = directory_has_default_acl(conn, parent_dir))) {
826 DEBUG(4,("calling onefs_open_file with flags=0x%X flags2=0x%X "
827 "mode=0%o, access_mask = 0x%x, open_access_mask = 0x%x\n",
828 (unsigned int)flags, (unsigned int)flags2,
829 (unsigned int)unx_mode, (unsigned int)access_mask,
830 (unsigned int)open_access_mask));
832 oplock_waiter = 1; //ifs_oplock_wait_record(mid);
834 if (oplock_waiter == 0) {
835 return NT_STATUS_NO_MEMORY;
839 status = onefs_open_file(fsp,
854 createfile_attributes,
858 if (!NT_STATUS_IS_OK(status)) {
860 /* OneFS Oplock Handling */
861 if (errno == EINPROGRESS) {
865 struct deferred_open_record state;
866 struct timespec old_write_time;
868 old_write_time = get_mtimespec(psbuf);
870 DEBUG(3, ("Someone created file %s with an "
871 "oplock after we looked: Retrying\n",
874 * We hit the race that when we did the stat
875 * on the file it did not exist, and someone
876 * has created it in between the stat and the
877 * open_file() call. Just retry immediately.
879 id = vfs_file_id_from_sbuf(conn, psbuf);
880 if (!(lck = get_share_mode_lock(talloc_tos(),
881 id, conn->connectpath, fname,
886 DEBUG(0, ("onefs_open_file_ntcreate: "
887 "Could not get share mode "
888 "lock for %s\n", fname));
889 status = NT_STATUS_SHARING_VIOLATION;
890 goto cleanup_destroy;
893 state.delayed_for_oplocks = False;
897 defer_open(lck, request_time,
898 timeval_zero(), req, &state);
900 goto cleanup_destroy;
902 /* Waiting for an oplock */
904 schedule_defer_open(lck, request_time, req);
908 /* Check for a sharing violation */
909 if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
910 uint32 can_access_mask;
911 bool can_access = True;
913 /* Check if this can be done with the deny_dos and fcb
916 /* Try to find dup fsp if possible. */
918 (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS|
919 NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) {
922 DEBUG(0, ("DOS open without an SMB "
924 status = NT_STATUS_INTERNAL_ERROR;
925 goto cleanup_destroy;
928 /* Use the client requested access mask here,
929 * not the one we open with. */
930 status = fcb_or_dos_open(req,
941 if (NT_STATUS_IS_OK(status)) {
944 *pinfo = FILE_WAS_OPENED;
946 status = NT_STATUS_OK;
952 * This next line is a subtlety we need for
953 * MS-Access. If a file open will fail due to share
954 * permissions and also for security (access) reasons,
955 * we need to return the access failed error, not the
956 * share error. We can't open the file due to kernel
957 * oplock deadlock (it's possible we failed above on
958 * the open_mode_check()) so use a userspace check.
961 if (flags & O_RDWR) {
962 can_access_mask = FILE_READ_DATA|FILE_WRITE_DATA;
963 } else if (flags & O_WRONLY) {
964 can_access_mask = FILE_WRITE_DATA;
966 can_access_mask = FILE_READ_DATA;
969 if (((can_access_mask & FILE_WRITE_DATA) && !CAN_WRITE(conn)) ||
970 !can_access_file_data(conn,fname,psbuf,can_access_mask)) {
975 * If we're returning a share violation, ensure we
976 * cope with the braindead 1 second delay.
978 if (!(oplock_request & INTERNAL_OPEN_ONLY) &&
979 lp_defer_sharing_violations()) {
980 struct timeval timeout;
981 struct deferred_open_record state;
984 /* this is a hack to speed up torture tests
986 timeout_usecs = lp_parm_int(SNUM(conn),
988 SHARING_VIOLATION_USEC_WAIT);
990 /* This is a relative time, added to the
991 absolute request_time value to get the
992 absolute timeout time. Note that if this
993 is the second or greater time we enter this
994 codepath for this particular request mid
995 then request_time is left as the absolute
996 time of the *first* time this request mid
997 was processed. This is what allows the
998 request to eventually time out. */
1000 timeout = timeval_set(0, timeout_usecs);
1002 /* Nothing actually uses
1003 state.delayed_for_oplocks but it's handy to
1004 differentiate in debug messages between a
1005 30 second delay due to oplock break, and a
1006 1 second delay for share mode conflicts. */
1008 state.delayed_for_oplocks = False;
1010 state.failed = false;
1013 && !request_timed_out(request_time,
1015 defer_open(lck, request_time, timeout,
1022 * We have detected a sharing violation here
1023 * so return the correct error code
1025 status = NT_STATUS_SHARING_VIOLATION;
1027 status = NT_STATUS_ACCESS_DENIED;
1030 goto cleanup_destroy;
1034 * Normal error, for example EACCES
1037 //destroy_ifs_callback_record(oplock_waiter);
1043 fsp->oplock_type = granted_oplock;
1045 /* XXX uncomment for oplocks */
1046 //ifs_set_oplock_callback(oplock_waiter, fsp);
1047 //fsp->oplock_callback_id = oplock_waiter;
1049 if (!file_existed) {
1050 struct timespec old_write_time = get_mtimespec(psbuf);
1052 * Deal with the race condition where two smbd's detect the
1053 * file doesn't exist and do the create at the same time. One
1054 * of them will win and set a share mode, the other (ie. this
1055 * one) should check if the requested share mode for this
1056 * create is allowed.
1060 * Now the file exists and fsp is successfully opened,
1061 * fsp->dev and fsp->inode are valid and should replace the
1062 * dev=0,inode=0 from a non existent file. Spotted by
1063 * Nadav Danieli <nadavd@exanet.com>. JRA.
1068 lck = get_share_mode_lock(talloc_tos(), id,
1070 fname, &old_write_time);
1073 DEBUG(0, ("onefs_open_file_ntcreate: Could not get "
1074 "share mode lock for %s\n", fname));
1076 return NT_STATUS_SHARING_VIOLATION;
1079 if (lck->delete_on_close) {
1080 status = NT_STATUS_DELETE_PENDING;
1083 if (!NT_STATUS_IS_OK(status)) {
1084 struct deferred_open_record state;
1088 state.delayed_for_oplocks = False;
1091 /* Do it all over again immediately. In the second
1092 * round we will find that the file existed and handle
1093 * the DELETE_PENDING and FCB cases correctly. No need
1094 * to duplicate the code here. Essentially this is a
1095 * "goto top of this function", but don't tell
1099 defer_open(lck, request_time, timeval_zero(),
1107 * We exit this block with the share entry *locked*.....
1112 SMB_ASSERT(lck != NULL);
1114 /* note that we ignore failure for the following. It is
1115 basically a hack for NFS, and NFS will never set one of
1116 these only read them. Nobody but Samba can ever set a deny
1117 mode and we have already checked our more authoritative
1118 locking database for permission to set this deny mode. If
1119 the kernel refuses the operations then the kernel is wrong.
1120 note that GPFS supports it as well - jmcd */
1122 if (fsp->fh->fd != -1) {
1123 ret_flock = SMB_VFS_KERNEL_FLOCK(fsp, share_access);
1124 if(ret_flock == -1 ){
1128 return NT_STATUS_SHARING_VIOLATION;
1133 * At this point onwards, we can guarentee that the share entry
1134 * is locked, whether we created the file or not, and that the
1135 * deny mode is compatible with all current opens.
1138 /* Record the options we were opened with. */
1139 fsp->share_access = share_access;
1140 fsp->fh->private_options = create_options;
1142 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
1144 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
1147 /* stat opens on existing files don't get oplocks. */
1148 if (is_stat_open(open_access_mask)) {
1149 fsp->oplock_type = NO_OPLOCK;
1152 if (!(flags2 & O_TRUNC)) {
1153 info = FILE_WAS_OPENED;
1155 info = FILE_WAS_OVERWRITTEN;
1158 info = FILE_WAS_CREATED;
1166 * Setup the oplock info in both the shared memory and
1170 if ((fsp->oplock_type != NO_OPLOCK) &&
1171 (fsp->oplock_type != FAKE_LEVEL_II_OPLOCK)) {
1172 if (!set_file_oplock(fsp, fsp->oplock_type)) {
1173 /* Could not get the kernel oplock */
1174 fsp->oplock_type = NO_OPLOCK;
1178 if (info == FILE_WAS_OVERWRITTEN || info == FILE_WAS_CREATED ||
1179 info == FILE_WAS_SUPERSEDED) {
1180 new_file_created = True;
1183 set_share_mode(lck, fsp, conn->server_info->utok.uid, 0,
1186 /* Handle strange delete on close create semantics. */
1187 if (create_options & FILE_DELETE_ON_CLOSE) {
1188 status = can_set_delete_on_close(fsp, True, new_dos_attributes);
1190 if (!NT_STATUS_IS_OK(status)) {
1191 /* Remember to delete the mode we just added. */
1192 del_share_mode(lck, fsp);
1197 /* Note that here we set the *inital* delete on close flag,
1198 not the regular one. The magic gets handled in close. */
1199 fsp->initial_delete_on_close = True;
1203 * Take care of inherited ACLs on created files - if default ACL not
1205 * May be necessary depending on acl policies.
1207 if (!posix_open && !file_existed && !def_acl && !(VALID_STAT(*psbuf)
1208 && (psbuf->st_flags & SF_HASNTFSACL))) {
1210 int saved_errno = errno; /* We might get ENOSYS in the next
1213 if (SMB_VFS_FCHMOD_ACL(fsp, unx_mode) == -1 &&
1215 errno = saved_errno; /* Ignore ENOSYS */
1218 } else if (new_unx_mode) {
1222 /* Attributes need changing. File already existed. */
1225 int saved_errno = errno; /* We might get ENOSYS in the
1227 ret = SMB_VFS_FCHMOD_ACL(fsp, new_unx_mode);
1229 if (ret == -1 && errno == ENOSYS) {
1230 errno = saved_errno; /* Ignore ENOSYS */
1232 DEBUG(5, ("onefs_open_file_ntcreate: reset "
1233 "attributes of file %s to 0%o\n",
1234 fname, (unsigned int)new_unx_mode));
1235 ret = 0; /* Don't do the fchmod below. */
1240 (SMB_VFS_FCHMOD(fsp, new_unx_mode) == -1))
1241 DEBUG(5, ("onefs_open_file_ntcreate: failed to reset "
1242 "attributes of file %s to 0%o\n",
1243 fname, (unsigned int)new_unx_mode));
1246 /* If this is a successful open, we must remove any deferred open
1249 del_deferred_open_entry(lck, req->mid);
1253 return NT_STATUS_OK;
1257 /****************************************************************************
1258 Open a directory from an NT SMB call.
1259 ****************************************************************************/
1260 static NTSTATUS onefs_open_directory(connection_struct *conn,
1261 struct smb_request *req,
1264 uint32 share_access,
1265 uint32 create_disposition,
1266 uint32 create_options,
1267 uint32 file_attributes,
1268 struct security_descriptor *sd,
1269 files_struct **result,
1271 SMB_STRUCT_STAT *psbuf)
1273 files_struct *fsp = NULL;
1274 struct share_mode_lock *lck = NULL;
1276 struct timespec mtimespec;
1279 const char *dirname;
1280 bool posix_open = false;
1281 uint32 create_flags = 0;
1282 uint32 mode = lp_dir_mask(SNUM(conn));
1284 DEBUG(5, ("onefs_open_directory: opening directory %s, "
1285 "access_mask = 0x%x, "
1286 "share_access = 0x%x create_options = 0x%x, "
1287 "create_disposition = 0x%x, file_attributes = 0x%x\n",
1288 fname, (unsigned int)access_mask, (unsigned int)share_access,
1289 (unsigned int)create_options, (unsigned int)create_disposition,
1290 (unsigned int)file_attributes));
1292 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
1293 (conn->fs_capabilities & FILE_NAMED_STREAMS) &&
1294 is_ntfs_stream_name(fname)) {
1295 DEBUG(2, ("onefs_open_directory: %s is a stream name!\n", fname));
1296 return NT_STATUS_NOT_A_DIRECTORY;
1299 switch (create_disposition) {
1301 /* If directory exists open. If directory doesn't
1304 info = FILE_WAS_OPENED;
1307 /* If directory exists error. If directory doesn't
1309 create_flags = O_CREAT | O_EXCL;
1310 info = FILE_WAS_CREATED;
1313 /* If directory exists open. If directory doesn't
1316 /* Note: in order to return whether the directory was
1317 * opened or created, we first try to open and then try
1320 info = FILE_WAS_OPENED;
1322 case FILE_SUPERSEDE:
1323 case FILE_OVERWRITE:
1324 case FILE_OVERWRITE_IF:
1326 DEBUG(5, ("onefs_open_directory: invalid "
1327 "create_disposition 0x%x for directory %s\n",
1328 (unsigned int)create_disposition, fname));
1329 return NT_STATUS_INVALID_PARAMETER;
1333 * Check for write access to the share. Done in mkdir_internal() in
1336 if (!CAN_WRITE(conn) && (create_flags & O_CREAT)) {
1337 return NT_STATUS_ACCESS_DENIED;
1340 /* Get parent dirname */
1341 if (!parent_dirname(talloc_tos(), fname, &parent_dir, &dirname)) {
1342 return NT_STATUS_NO_MEMORY;
1345 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
1347 mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
1348 file_attributes = 0;
1350 mode = unix_mode(conn, aDIR, fname, parent_dir);
1354 * The NONINDEXED and COMPRESSED bits seem to always be cleared on
1355 * directories, no matter if you specify that they should be set.
1358 ~(FILE_ATTRIBUTE_NONINDEXED | FILE_ATTRIBUTE_COMPRESSED);
1360 status = file_new(req, conn, &fsp);
1361 if(!NT_STATUS_IS_OK(status)) {
1366 * Actual open with retry magic to handle FILE_OPEN_IF which is
1367 * unique because the kernel won't tell us if the file was opened or
1371 fsp->fh->fd = onefs_sys_create_file(conn,
1378 create_flags | O_DIRECTORY,
1386 if (fsp->fh->fd == -1) {
1387 DEBUG(3, ("Error opening %s. Errno=%d (%s).\n", fname, errno,
1389 SMB_ASSERT(errno != EINPROGRESS);
1391 if (create_disposition == FILE_OPEN_IF) {
1392 if (errno == ENOENT) {
1393 /* Try again, creating it this time. */
1394 create_flags = O_CREAT | O_EXCL;
1395 info = FILE_WAS_CREATED;
1397 } else if (errno == EEXIST) {
1398 /* Uggh. Try again again. */
1400 info = FILE_WAS_OPENED;
1405 /* Error cases below: */
1406 file_free(req, fsp);
1408 if ((errno == ENOENT) && (create_disposition == FILE_OPEN)) {
1409 DEBUG(5,("onefs_open_directory: FILE_OPEN requested "
1410 "for directory %s and it doesn't "
1411 "exist.\n", fname ));
1412 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1413 } else if ((errno == EEXIST) &&
1414 (create_disposition == FILE_CREATE)) {
1415 DEBUG(5,("onefs_open_directory: FILE_CREATE "
1416 "requested for directory %s and it "
1417 "already exists.\n", fname ));
1418 return NT_STATUS_OBJECT_NAME_COLLISION;
1419 } else if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
1420 /* Catch sharing violations. */
1421 return NT_STATUS_SHARING_VIOLATION;
1424 return map_nt_error_from_unix(errno);
1427 if (info == FILE_WAS_CREATED) {
1429 /* Pulled from mkdir_internal() */
1430 if (SMB_VFS_LSTAT(conn, fname, psbuf) == -1) {
1431 DEBUG(2, ("Could not stat directory '%s' just "
1432 "created: %s\n",fname, strerror(errno)));
1433 return map_nt_error_from_unix(errno);
1436 if (!S_ISDIR(psbuf->st_mode)) {
1437 DEBUG(0, ("Directory just '%s' created is not a "
1438 "directory\n", fname));
1439 return NT_STATUS_ACCESS_DENIED;
1444 * Check if high bits should have been set, then (if
1445 * bits are missing): add them. Consider bits
1446 * automagically set by UNIX, i.e. SGID bit from
1449 if (mode & ~(S_IRWXU|S_IRWXG|S_IRWXO) &&
1450 (mode & ~psbuf->st_mode)) {
1451 SMB_VFS_CHMOD(conn, fname, (psbuf->st_mode |
1452 (mode & ~psbuf->st_mode)));
1456 /* Change the owner if required. */
1457 if (lp_inherit_owner(SNUM(conn))) {
1458 change_dir_owner_to_parent(conn, parent_dir, fname,
1462 notify_fname(conn, NOTIFY_ACTION_ADDED,
1463 FILE_NOTIFY_CHANGE_DIR_NAME, fname);
1466 /* Stat the fd for Samba bookkeeping. */
1467 if(SMB_VFS_FSTAT(fsp, psbuf) != 0) {
1469 file_free(req, fsp);
1470 return map_nt_error_from_unix(errno);
1473 /* Setup the files_struct for it. */
1474 fsp->mode = psbuf->st_mode;
1475 fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf);
1476 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
1477 fsp->file_pid = req ? req->smbpid : 0;
1478 fsp->can_lock = False;
1479 fsp->can_read = False;
1480 fsp->can_write = False;
1482 fsp->share_access = share_access;
1483 fsp->fh->private_options = create_options;
1485 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
1487 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
1488 fsp->print_file = False;
1489 fsp->modified = False;
1490 fsp->oplock_type = NO_OPLOCK;
1491 fsp->sent_oplock_break = NO_BREAK_SENT;
1492 fsp->is_directory = True;
1493 fsp->posix_open = posix_open;
1495 string_set(&fsp->fsp_name,fname);
1497 mtimespec = get_mtimespec(psbuf);
1500 * Still set the samba share mode lock for correct delete-on-close
1501 * semantics and to make smbstatus more useful.
1503 lck = get_share_mode_lock(talloc_tos(), fsp->file_id,
1508 DEBUG(0, ("onefs_open_directory: Could not get share mode "
1509 "lock for %s\n", fname));
1511 file_free(req, fsp);
1512 return NT_STATUS_SHARING_VIOLATION;
1515 if (lck->delete_on_close) {
1518 file_free(req, fsp);
1519 return NT_STATUS_DELETE_PENDING;
1522 set_share_mode(lck, fsp, conn->server_info->utok.uid, 0, NO_OPLOCK);
1525 * For directories the delete on close bit at open time seems
1526 * always to be honored on close... See test 19 in Samba4 BASE-DELETE.
1528 if (create_options & FILE_DELETE_ON_CLOSE) {
1529 status = can_set_delete_on_close(fsp, True, 0);
1530 if (!NT_STATUS_IS_OK(status) &&
1531 !NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
1534 file_free(req, fsp);
1538 if (NT_STATUS_IS_OK(status)) {
1539 /* Note that here we set the *inital* delete on close flag,
1540 not the regular one. The magic gets handled in close. */
1541 fsp->initial_delete_on_close = True;
1552 return NT_STATUS_OK;
1556 * If a main file is opened for delete, all streams need to be checked for
1557 * !FILE_SHARE_DELETE. Do this by opening with DELETE_ACCESS.
1558 * If that works, delete them all by setting the delete on close and close.
1561 static NTSTATUS open_streams_for_delete(connection_struct *conn,
1564 struct stream_struct *stream_info;
1565 files_struct **streams;
1567 unsigned int num_streams;
1568 TALLOC_CTX *frame = talloc_stackframe();
1571 status = SMB_VFS_STREAMINFO(conn, NULL, fname, talloc_tos(),
1572 &num_streams, &stream_info);
1574 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
1575 || NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
1576 DEBUG(10, ("no streams around\n"));
1578 return NT_STATUS_OK;
1581 if (!NT_STATUS_IS_OK(status)) {
1582 DEBUG(10, ("SMB_VFS_STREAMINFO failed: %s\n",
1583 nt_errstr(status)));
1587 DEBUG(10, ("open_streams_for_delete found %d streams\n",
1590 if (num_streams == 0) {
1592 return NT_STATUS_OK;
1595 streams = TALLOC_ARRAY(talloc_tos(), files_struct *, num_streams);
1596 if (streams == NULL) {
1597 DEBUG(0, ("talloc failed\n"));
1598 status = NT_STATUS_NO_MEMORY;
1602 for (i=0; i<num_streams; i++) {
1605 if (strequal(stream_info[i].name, "::$DATA")) {
1610 streamname = talloc_asprintf(talloc_tos(), "%s%s", fname,
1611 stream_info[i].name);
1613 if (streamname == NULL) {
1614 DEBUG(0, ("talloc_aprintf failed\n"));
1615 status = NT_STATUS_NO_MEMORY;
1619 status = onefs_create_file_unixpath
1622 streamname, /* fname */
1623 DELETE_ACCESS, /* access_mask */
1624 FILE_SHARE_READ | FILE_SHARE_WRITE
1625 | FILE_SHARE_DELETE, /* share_access */
1626 FILE_OPEN, /* create_disposition*/
1627 NTCREATEX_OPTIONS_PRIVATE_STREAM_DELETE, /* create_options */
1628 FILE_ATTRIBUTE_NORMAL, /* file_attributes */
1629 0, /* oplock_request */
1630 0, /* allocation_size */
1633 &streams[i], /* result */
1637 TALLOC_FREE(streamname);
1639 if (!NT_STATUS_IS_OK(status)) {
1640 DEBUG(10, ("Could not open stream %s: %s\n",
1641 streamname, nt_errstr(status)));
1647 * don't touch the variable "status" beyond this point :-)
1650 for (i -= 1 ; i >= 0; i--) {
1651 if (streams[i] == NULL) {
1655 DEBUG(10, ("Closing stream # %d, %s\n", i,
1656 streams[i]->fsp_name));
1657 close_file(NULL, streams[i], NORMAL_CLOSE);
1666 * Wrapper around onefs_open_file_ntcreate and onefs_open_directory.
1668 static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
1669 struct smb_request *req,
1671 uint32_t access_mask,
1672 uint32_t share_access,
1673 uint32_t create_disposition,
1674 uint32_t create_options,
1675 uint32_t file_attributes,
1676 uint32_t oplock_request,
1677 uint64_t allocation_size,
1678 struct security_descriptor *sd,
1679 struct ea_list *ea_list,
1680 files_struct **result,
1682 SMB_STRUCT_STAT *psbuf)
1684 SMB_STRUCT_STAT sbuf;
1685 int info = FILE_WAS_OPENED;
1686 files_struct *base_fsp = NULL;
1687 files_struct *fsp = NULL;
1690 DEBUG(10,("onefs_create_file_unixpath: access_mask = 0x%x "
1691 "file_attributes = 0x%x, share_access = 0x%x, "
1692 "create_disposition = 0x%x create_options = 0x%x "
1693 "oplock_request = 0x%x ea_list = 0x%p, sd = 0x%p, "
1695 (unsigned int)access_mask,
1696 (unsigned int)file_attributes,
1697 (unsigned int)share_access,
1698 (unsigned int)create_disposition,
1699 (unsigned int)create_options,
1700 (unsigned int)oplock_request,
1701 ea_list, sd, fname));
1703 if (create_options & FILE_OPEN_BY_FILE_ID) {
1704 status = NT_STATUS_NOT_SUPPORTED;
1708 if (create_options & NTCREATEX_OPTIONS_INVALID_PARAM_MASK) {
1709 status = NT_STATUS_INVALID_PARAMETER;
1714 oplock_request |= INTERNAL_OPEN_ONLY;
1717 if (psbuf != NULL) {
1721 if (SMB_VFS_STAT(conn, fname, &sbuf) == -1) {
1722 SET_STAT_INVALID(sbuf);
1726 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
1727 && (access_mask & DELETE_ACCESS)
1728 && !is_ntfs_stream_name(fname)) {
1730 * We can't open a file with DELETE access if any of the
1731 * streams is open without FILE_SHARE_DELETE
1733 status = open_streams_for_delete(conn, fname);
1735 if (!NT_STATUS_IS_OK(status)) {
1740 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
1741 && is_ntfs_stream_name(fname)
1742 && (!(create_options & NTCREATEX_OPTIONS_PRIVATE_STREAM_DELETE))) {
1744 uint32 base_create_disposition;
1746 if (create_options & FILE_DIRECTORY_FILE) {
1747 status = NT_STATUS_NOT_A_DIRECTORY;
1751 status = split_ntfs_stream_name(talloc_tos(), fname,
1753 if (!NT_STATUS_IS_OK(status)) {
1754 DEBUG(10, ("onefs_create_file_unixpath: "
1755 "split_ntfs_stream_name failed: %s\n",
1756 nt_errstr(status)));
1760 SMB_ASSERT(!is_ntfs_stream_name(base)); /* paranoia.. */
1762 switch (create_disposition) {
1764 base_create_disposition = FILE_OPEN;
1767 base_create_disposition = FILE_OPEN_IF;
1771 status = onefs_create_file_unixpath(
1775 0, /* access_mask */
1778 FILE_SHARE_DELETE), /* share_access */
1779 base_create_disposition, /* create_disposition*/
1780 0, /* create_options */
1781 0, /* file_attributes */
1782 NO_OPLOCK, /* oplock_request */
1783 0, /* allocation_size */
1786 &base_fsp, /* result */
1790 if (!NT_STATUS_IS_OK(status)) {
1791 DEBUG(10, ("onefs_create_file_unixpath for base %s "
1792 "failed: %s\n", base, nt_errstr(status)));
1796 * we don't need to low level fd: This might conflict with
1802 /* Covert generic bits in the security descriptor. */
1804 security_acl_map_generic(sd->dacl, &file_generic_mapping);
1805 security_acl_map_generic(sd->sacl, &file_generic_mapping);
1809 * If it's a request for a directory open, deal with it separately.
1812 if (create_options & FILE_DIRECTORY_FILE) {
1814 if (create_options & FILE_NON_DIRECTORY_FILE) {
1815 status = NT_STATUS_INVALID_PARAMETER;
1819 /* Can't open a temp directory. IFS kit test. */
1820 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
1821 (file_attributes & FILE_ATTRIBUTE_TEMPORARY)) {
1822 status = NT_STATUS_INVALID_PARAMETER;
1827 * We will get a create directory here if the Win32
1828 * app specified a security descriptor in the
1829 * CreateDirectory() call.
1832 status = onefs_open_directory(
1836 access_mask, /* access_mask */
1837 share_access, /* share_access */
1838 create_disposition, /* create_disposition*/
1839 create_options, /* create_options */
1840 file_attributes, /* file_attributes */
1848 * Ordinary file case.
1851 status = file_new(req, conn, &fsp);
1852 if(!NT_STATUS_IS_OK(status)) {
1857 * We're opening the stream element of a base_fsp
1858 * we already opened. Set up the base_fsp pointer.
1861 fsp->base_fsp = base_fsp;
1864 status = onefs_open_file_ntcreate(
1868 access_mask, /* access_mask */
1869 share_access, /* share_access */
1870 create_disposition, /* create_disposition*/
1871 create_options, /* create_options */
1872 file_attributes, /* file_attributes */
1873 oplock_request, /* oplock_request */
1879 if(!NT_STATUS_IS_OK(status)) {
1880 file_free(req, fsp);
1884 if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
1886 /* A stream open never opens a directory */
1889 status = NT_STATUS_FILE_IS_A_DIRECTORY;
1894 * Fail the open if it was explicitly a non-directory
1898 if (create_options & FILE_NON_DIRECTORY_FILE) {
1899 status = NT_STATUS_FILE_IS_A_DIRECTORY;
1903 create_options |= FILE_DIRECTORY_FILE;
1905 status = onefs_open_directory(
1909 access_mask, /* access_mask */
1910 share_access, /* share_access */
1911 create_disposition, /* create_disposition*/
1912 create_options, /* create_options */
1913 file_attributes, /* file_attributes */
1921 if (!NT_STATUS_IS_OK(status)) {
1925 fsp->base_fsp = base_fsp;
1929 if ((ea_list != NULL) && (info == FILE_WAS_CREATED)) {
1930 status = set_ea(conn, fsp, fname, ea_list);
1931 if (!NT_STATUS_IS_OK(status)) {
1936 if (!fsp->is_directory && S_ISDIR(sbuf.st_mode)) {
1937 status = NT_STATUS_ACCESS_DENIED;
1941 /* Save the requested allocation size. */
1942 if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
1944 && (allocation_size > sbuf.st_size)) {
1945 fsp->initial_allocation_size = smb_roundup(
1946 fsp->conn, allocation_size);
1947 if (fsp->is_directory) {
1948 /* Can't set allocation size on a directory. */
1949 status = NT_STATUS_ACCESS_DENIED;
1952 if (vfs_allocate_file_space(
1953 fsp, fsp->initial_allocation_size) == -1) {
1954 status = NT_STATUS_DISK_FULL;
1958 fsp->initial_allocation_size = smb_roundup(
1959 fsp->conn, (uint64_t)sbuf.st_size);
1963 DEBUG(10, ("onefs_create_file_unixpath: info=%d\n", info));
1966 if (pinfo != NULL) {
1969 if (psbuf != NULL) {
1970 if ((fsp->fh == NULL) || (fsp->fh->fd == -1)) {
1974 SMB_VFS_FSTAT(fsp, psbuf);
1977 return NT_STATUS_OK;
1980 DEBUG(10, ("onefs_create_file_unixpath: %s\n", nt_errstr(status)));
1983 if (base_fsp && fsp->base_fsp == base_fsp) {
1985 * The close_file below will close
1990 close_file(req, fsp, ERROR_CLOSE);
1993 if (base_fsp != NULL) {
1994 close_file(req, base_fsp, ERROR_CLOSE);
2001 * SMB_VFS_CREATE_FILE interface to onefs.
2003 NTSTATUS onefs_create_file(vfs_handle_struct *handle,
2004 struct smb_request *req,
2005 uint16_t root_dir_fid,
2007 uint32_t create_file_flags,
2008 uint32_t access_mask,
2009 uint32_t share_access,
2010 uint32_t create_disposition,
2011 uint32_t create_options,
2012 uint32_t file_attributes,
2013 uint32_t oplock_request,
2014 uint64_t allocation_size,
2015 struct security_descriptor *sd,
2016 struct ea_list *ea_list,
2017 files_struct **result,
2019 SMB_STRUCT_STAT *psbuf)
2021 connection_struct *conn = handle->conn;
2022 struct case_semantics_state *case_state = NULL;
2023 SMB_STRUCT_STAT sbuf;
2024 int info = FILE_WAS_OPENED;
2025 files_struct *fsp = NULL;
2028 DEBUG(10,("onefs_create_file: access_mask = 0x%x "
2029 "file_attributes = 0x%x, share_access = 0x%x, "
2030 "create_disposition = 0x%x create_options = 0x%x "
2031 "oplock_request = 0x%x "
2032 "root_dir_fid = 0x%x, ea_list = 0x%p, sd = 0x%p, "
2033 "create_file_flags = 0x%x, fname = %s\n",
2034 (unsigned int)access_mask,
2035 (unsigned int)file_attributes,
2036 (unsigned int)share_access,
2037 (unsigned int)create_disposition,
2038 (unsigned int)create_options,
2039 (unsigned int)oplock_request,
2040 (unsigned int)root_dir_fid,
2041 ea_list, sd, create_file_flags, fname));
2043 /* Get the file name if root_dir_fid was specified. */
2044 if (root_dir_fid != 0) {
2047 status = get_relative_fid_filename(conn, req, root_dir_fid,
2049 if (!NT_STATUS_IS_OK(status)) {
2056 /* Resolve the file name if this was a DFS pathname. */
2057 if ((req != NULL) && (req->flags2 & FLAGS2_DFS_PATHNAMES)) {
2058 char *resolved_fname;
2060 status = resolve_dfspath(talloc_tos(), conn, true, fname,
2063 if (!NT_STATUS_IS_OK(status)) {
2065 * For PATH_NOT_COVERED we had
2066 * reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
2067 * ERRSRV, ERRbadpath);
2068 * Need to fix in callers
2072 fname = resolved_fname;
2075 /* Check if POSIX semantics are wanted. */
2076 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
2077 case_state = set_posix_case_semantics(talloc_tos(), conn);
2080 /* Convert dos path to unix path if it hasn't already been done. */
2081 if (create_file_flags & CFF_DOS_PATH) {
2082 char *converted_fname;
2084 SET_STAT_INVALID(sbuf);
2086 status = unix_convert(talloc_tos(), conn, fname, False,
2087 &converted_fname, NULL, &sbuf);
2088 if (!NT_STATUS_IS_OK(status)) {
2091 fname = converted_fname;
2093 if (psbuf != NULL) {
2096 if (SMB_VFS_STAT(conn, fname, &sbuf) == -1) {
2097 SET_STAT_INVALID(sbuf);
2103 TALLOC_FREE(case_state);
2105 /* All file access must go through check_name() */
2106 status = check_name(conn, fname);
2107 if (!NT_STATUS_IS_OK(status)) {
2111 status = onefs_create_file_unixpath(
2115 access_mask, /* access_mask */
2116 share_access, /* share_access */
2117 create_disposition, /* create_disposition*/
2118 create_options, /* create_options */
2119 file_attributes, /* file_attributes */
2120 oplock_request, /* oplock_request */
2121 allocation_size, /* allocation_size */
2123 ea_list, /* ea_list */
2128 if (!NT_STATUS_IS_OK(status)) {
2132 DEBUG(10, ("onefs_create_file: info=%d\n", info));
2135 if (pinfo != NULL) {
2138 if (psbuf != NULL) {
2141 return NT_STATUS_OK;
2144 DEBUG(10, ("onefs_create_file: %s\n", nt_errstr(status)));
2147 close_file(req, fsp, ERROR_CLOSE);