2 * Unix SMB/CIFS implementation.
4 * This file began with some code from source3/smbd/open.c and has been
5 * modified it work with ifs_createfile.
7 * ifs_createfile is a CIFS-specific syscall for opening/files and
8 * directories. It adds support for:
9 * - Full in-kernel access checks using a windows access_mask
10 * - Cluster-coherent share mode locks
11 * - Cluster-coherent oplocks
13 * - Setting security descriptors at create time
14 * - Setting dos_attributes at create time
16 * Copyright (C) Andrew Tridgell 1992-1998
17 * Copyright (C) Jeremy Allison 2001-2004
18 * Copyright (C) Volker Lendecke 2005
19 * Copyright (C) Tim Prouty, 2008
21 * This program is free software; you can redistribute it and/or modify
22 * it under the terms of the GNU General Public License as published by
23 * the Free Software Foundation; either version 3 of the License, or
24 * (at your option) any later version.
26 * This program is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 * GNU General Public License for more details.
31 * You should have received a copy of the GNU General Public License
32 * along with this program; if not, see <http://www.gnu.org/licenses/>.
37 #include "onefs_config.h"
38 #include "oplock_onefs.h"
39 #include "smbd/globals.h"
41 extern const struct generic_mapping file_generic_mapping;
43 struct onefs_fsp_data {
44 uint64_t oplock_callback_id;
47 static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
48 struct smb_request *req,
51 uint32_t share_access,
52 uint32_t create_disposition,
53 uint32_t create_options,
54 uint32_t file_attributes,
55 uint32_t oplock_request,
56 uint64_t allocation_size,
57 struct security_descriptor *sd,
58 struct ea_list *ea_list,
59 files_struct **result,
61 struct onefs_fsp_data *fsp_data,
62 SMB_STRUCT_STAT *psbuf);
64 /****************************************************************************
66 ****************************************************************************/
68 static NTSTATUS onefs_open_file(files_struct *fsp,
69 connection_struct *conn,
70 struct smb_request *req,
71 const char *parent_dir,
74 SMB_STRUCT_STAT *psbuf,
78 uint32 open_access_mask,
82 uint32 create_options,
83 uint32_t new_dos_attributes,
84 struct security_descriptor *sd,
87 NTSTATUS status = NT_STATUS_OK;
88 int accmode = (flags & O_ACCMODE);
89 int local_flags = flags;
90 bool file_existed = VALID_STAT(*psbuf);
99 /* Check permissions */
102 * This code was changed after seeing a client open request
103 * containing the open mode of (DENY_WRITE/read-only) with
104 * the 'create if not exist' bit set. The previous code
105 * would fail to open the file read only on a read-only share
106 * as it was checking the flags parameter directly against O_RDONLY,
107 * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
111 if (!CAN_WRITE(conn)) {
112 /* It's a read-only share - fail if we wanted to write. */
113 if(accmode != O_RDONLY) {
114 DEBUG(3,("Permission denied opening %s\n", path));
115 return NT_STATUS_ACCESS_DENIED;
116 } else if(flags & O_CREAT) {
117 /* We don't want to write - but we must make sure that
118 O_CREAT doesn't create the file if we have write
119 access into the directory.
122 local_flags &= ~O_CREAT;
127 * This little piece of insanity is inspired by the
128 * fact that an NT client can open a file for O_RDONLY,
129 * but set the create disposition to FILE_EXISTS_TRUNCATE.
130 * If the client *can* write to the file, then it expects to
131 * truncate the file, even though it is opening for readonly.
132 * Quicken uses this stupid trick in backup file creation...
133 * Thanks *greatly* to "David W. Chapman Jr." <dwcjr@inethouston.net>
134 * for helping track this one down. It didn't bite us in 2.0.x
135 * as we always opened files read-write in that release. JRA.
138 if ((accmode == O_RDONLY) && ((flags & O_TRUNC) == O_TRUNC)) {
139 DEBUG(10,("onefs_open_file: truncate requested on read-only "
140 "open for file %s\n", path));
141 local_flags = (flags & ~O_ACCMODE)|O_RDWR;
144 #if defined(O_NONBLOCK) && defined(S_ISFIFO)
146 * We would block on opening a FIFO with no one else on the
147 * other end. Do what we used to do and add O_NONBLOCK to the
151 if (file_existed && S_ISFIFO(psbuf->st_mode)) {
152 local_flags |= O_NONBLOCK;
156 /* Don't create files with Microsoft wildcard characters. */
159 * wildcard characters are allowed in stream names
160 * only test the basefilename
162 wild = fsp->base_fsp->fsp_name;
166 if ((local_flags & O_CREAT) && !file_existed &&
169 * XXX: may need to remvoe this return...
171 * We dont think this check needs to exist. All it does is
172 * block creating files with Microsoft wildcards, which is
173 * fine if the creation originated from NFS or locally and
174 * then was copied via Samba.
176 DEBUG(1, ("onefs_open_file: creating file with wildcard: %s\n",
178 return NT_STATUS_OBJECT_NAME_INVALID;
181 /* Actually do the open */
185 * Never follow symlinks on a POSIX client. The
186 * client should be doing this.
189 if (fsp->posix_open || !lp_symlinks(SNUM(conn))) {
193 /* Stream handling */
194 if (is_ntfs_stream_name(path)) {
195 status = onefs_split_ntfs_stream_name(talloc_tos(), path,
198 /* It's a stream, so pass in the base_fd */
199 if ((conn->fs_capabilities & FILE_NAMED_STREAMS) && stream != NULL) {
200 SMB_ASSERT(fsp->base_fsp);
203 * We have never seen an oplock taken on a stream, and our
204 * current implementation doesn't support it. If a request is
205 * seen, log a loud error message and ignore the requested
208 if ((oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK) !=
210 DEBUG(0, ("Oplock(%d) being requested on a stream! "
211 "Ignoring oplock request: base=%s, "
213 oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK,
215 /* Recover by requesting NO_OPLOCK instead. */
216 oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
219 DEBUG(10,("Opening a stream: base=%s(%d), stream=%s\n",
220 base, fsp->base_fsp->fh->fd, stream));
222 base_fd = fsp->base_fsp->fh->fd;
225 fsp->fh->fd = onefs_sys_create_file(conn,
227 stream != NULL ? stream :
228 (base != NULL ? base : path),
241 if (fsp->fh->fd == -1) {
242 if (errno == EMFILE) {
243 static time_t last_warned = 0L;
245 if (time((time_t *) NULL) > last_warned) {
246 DEBUG(0, ("Too many open files, unable "
247 "to open more! smbd's max "
248 "open files = %d, also check "
249 "sysctl kern.maxfiles and "
250 "sysctl kern.maxfilesperproc\n",
251 lp_max_open_files()));
252 last_warned = time((time_t *) NULL);
256 status = map_nt_error_from_unix(errno);
257 DEBUG(3,("Error opening file %s (%s) (local_flags=%d) "
259 path, strerror(errno), local_flags, flags));
263 if ((local_flags & O_CREAT) && !file_existed) {
265 /* Inherit the ACL if required */
266 if (lp_inherit_perms(SNUM(conn))) {
267 inherit_access_posix_acl(conn, parent_dir, path,
271 /* Change the owner if required. */
272 if (lp_inherit_owner(SNUM(conn))) {
273 change_file_owner_to_parent(conn, parent_dir,
277 notify_fname(conn, NOTIFY_ACTION_ADDED,
278 FILE_NOTIFY_CHANGE_FILE_NAME, path);
284 if (fsp->fh->fd == -1) {
285 ret = SMB_VFS_STAT(conn, path, psbuf);
287 ret = SMB_VFS_FSTAT(fsp, psbuf);
288 /* If we have an fd, this stat should succeed. */
290 DEBUG(0,("Error doing fstat on open file %s "
291 "(%s)\n", path,strerror(errno) ));
295 /* For a non-io open, this stat failing means file not found. JRA */
297 status = map_nt_error_from_unix(errno);
304 * POSIX allows read-only opens of directories. We don't
305 * want to do this (we use a different code path for this)
306 * so catch a directory open and return an EISDIR. JRA.
309 if(S_ISDIR(psbuf->st_mode)) {
312 return NT_STATUS_FILE_IS_A_DIRECTORY;
315 fsp->mode = psbuf->st_mode;
316 fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf);
317 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
318 fsp->file_pid = req ? req->smbpid : 0;
319 fsp->can_lock = True;
320 fsp->can_read = (access_mask & (FILE_READ_DATA)) ? True : False;
321 if (!CAN_WRITE(conn)) {
322 fsp->can_write = False;
324 fsp->can_write = (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ?
327 fsp->print_file = False;
328 fsp->modified = False;
329 fsp->sent_oplock_break = NO_BREAK_SENT;
330 fsp->is_directory = False;
331 if (conn->aio_write_behind_list &&
332 is_in_path(path, conn->aio_write_behind_list, conn->case_sensitive)) {
333 fsp->aio_write_behind = True;
336 string_set(&fsp->fsp_name, path);
337 fsp->wcp = NULL; /* Write cache pointer. */
339 DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
340 conn->server_info->unix_name,
342 BOOLSTR(fsp->can_read), BOOLSTR(fsp->can_write),
343 conn->num_files_open));
349 /****************************************************************************
350 Handle the 1 second delay in returning a SHARING_VIOLATION error.
351 ****************************************************************************/
353 static void defer_open(struct share_mode_lock *lck,
354 struct timeval request_time,
355 struct timeval timeout,
356 struct smb_request *req,
357 struct deferred_open_record *state)
363 for (i=0; i<lck->num_share_modes; i++) {
364 struct share_mode_entry *e = &lck->share_modes[i];
366 if (!is_deferred_open_entry(e)) {
370 if (procid_is_me(&e->pid) && (e->op_mid == req->mid)) {
371 DEBUG(0, ("Trying to defer an already deferred "
372 "request: mid=%d, exiting\n", req->mid));
373 exit_server("attempt to defer a deferred request");
377 /* End paranoia check */
379 DEBUG(10,("defer_open_sharing_error: time [%u.%06u] adding deferred "
380 "open entry for mid %u\n",
381 (unsigned int)request_time.tv_sec,
382 (unsigned int)request_time.tv_usec,
383 (unsigned int)req->mid));
385 if (!push_deferred_smb_message(req, request_time, timeout,
386 (char *)state, sizeof(*state))) {
387 exit_server("push_deferred_smb_message failed");
389 add_deferred_open(lck, req->mid, request_time, state->id);
392 static void schedule_defer_open(struct share_mode_lock *lck,
393 struct timeval request_time,
394 struct smb_request *req)
396 struct deferred_open_record state;
398 /* This is a relative time, added to the absolute
399 request_time value to get the absolute timeout time.
400 Note that if this is the second or greater time we enter
401 this codepath for this particular request mid then
402 request_time is left as the absolute time of the *first*
403 time this request mid was processed. This is what allows
404 the request to eventually time out. */
406 struct timeval timeout;
408 /* Normally the smbd we asked should respond within
409 * OPLOCK_BREAK_TIMEOUT seconds regardless of whether
410 * the client did, give twice the timeout as a safety
411 * measure here in case the other smbd is stuck
415 * On OneFS, the kernel will always send an oplock_revoked message
416 * before this timeout is hit.
418 timeout = timeval_set(OPLOCK_BREAK_TIMEOUT*10, 0);
420 /* Nothing actually uses state.delayed_for_oplocks
421 but it's handy to differentiate in debug messages
422 between a 30 second delay due to oplock break, and
423 a 1 second delay for share mode conflicts. */
425 state.delayed_for_oplocks = True;
426 state.failed = false;
429 if (!request_timed_out(request_time, timeout)) {
430 defer_open(lck, request_time, timeout, req, &state);
434 /****************************************************************************
435 Open a file with a share mode. Passed in an already created files_struct.
436 ****************************************************************************/
437 NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
438 struct smb_request *req,
442 uint32 create_disposition,
443 uint32 create_options,
444 uint32 new_dos_attributes,
446 struct security_descriptor *sd,
449 struct onefs_fsp_data *fsp_data,
450 SMB_STRUCT_STAT *psbuf)
454 bool file_existed = VALID_STAT(*psbuf);
455 bool def_acl = False;
456 bool posix_open = False;
457 bool new_file_created = False;
458 bool clear_ads = False;
460 mode_t new_unx_mode = (mode_t)0;
461 mode_t unx_mode = (mode_t)0;
463 uint32 existing_dos_attributes = 0;
464 struct pending_message_list *pml = NULL;
465 struct timeval request_time = timeval_zero();
466 struct share_mode_lock *lck = NULL;
467 uint32 open_access_mask = access_mask;
473 uint64_t oplock_callback_id = 0;
474 uint32 createfile_attributes = 0;
480 * Printers are handled completely differently.
481 * Most of the passed parameters are ignored.
485 *pinfo = FILE_WAS_CREATED;
488 DEBUG(10, ("onefs_open_file_ntcreate: printer open fname=%s\n",
491 return print_fsp_open(req, conn, fname, req->vuid, fsp, psbuf);
494 if (!parent_dirname(talloc_tos(), fname, &parent_dir, &newname)) {
495 return NT_STATUS_NO_MEMORY;
498 if (new_dos_attributes & FILE_FLAG_POSIX_SEMANTICS) {
500 unx_mode = (mode_t)(new_dos_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
501 new_dos_attributes = 0;
503 /* We add aARCH to this as this mode is only used if the file is
505 unx_mode = unix_mode(conn, new_dos_attributes | aARCH, fname,
509 DEBUG(10,("onefs_open_file_ntcreate: fname=%s, dos_attrs=0x%x "
510 "access_mask=0x%x share_access=0x%x "
511 "create_disposition = 0x%x create_options=0x%x "
512 "unix mode=0%o oplock_request=0x%x\n",
513 fname, new_dos_attributes, access_mask, share_access,
514 create_disposition, create_options, unx_mode,
518 * Any non-stat-only open has the potential to contend oplocks, which
519 * means to avoid blocking in the kernel (which is unacceptable), the
520 * open must be deferred. In order to defer opens, req must not be
521 * NULL. The known cases of calling with a NULL req:
523 * 1. Open the base file of a stream: Always done stat-only
525 * 2. Open the stream: Oplocks are disallowed on streams, so an
526 * oplock will never be contended.
528 * 3. open_file_fchmod(), which is called from 3 places:
529 * A. try_chown: Posix acls only. Never called on onefs.
530 * B. set_ea_dos_attributes: Can't be called from onefs, because
531 * SMB_VFS_SETXATTR return ENOSYS.
532 * C. file_set_dos_mode: This would only happen if the "dos
533 * filemode" smb.conf parameter is set to yes. We ship with
534 * it off, but if a customer were to turn it on it would be
537 if (req == NULL && !is_stat_open(access_mask) && !is_ntfs_stream_name(fname)) {
538 smb_panic("NULL req on a non-stat-open!");
541 if ((req == NULL) && ((oplock_request & INTERNAL_OPEN_ONLY) == 0)) {
542 DEBUG(0, ("No smb request but not an internal only open!\n"));
543 return NT_STATUS_INTERNAL_ERROR;
547 * Only non-internal opens can be deferred at all
551 && ((pml = get_open_deferred_message(req->mid)) != NULL)) {
552 struct deferred_open_record *state =
553 (struct deferred_open_record *)pml->private_data.data;
555 /* Remember the absolute time of the original
556 request with this mid. We'll use it later to
557 see if this has timed out. */
559 request_time = pml->request_time;
561 /* Remove the deferred open entry under lock. */
562 lck = get_share_mode_lock(talloc_tos(), state->id, NULL, NULL,
565 DEBUG(0, ("could not get share mode lock\n"));
567 del_deferred_open_entry(lck, req->mid);
571 /* Ensure we don't reprocess this message. */
572 remove_deferred_open_smb_message(req->mid);
575 * When receiving a semlock_async_failure message, the
576 * deferred open will be marked as "failed". Returning
580 DEBUG(0, ("onefs_open_file_ntcreate: "
581 "semlock_async_failure detected!\n"));
582 return NT_STATUS_INTERNAL_ERROR;
586 status = check_name(conn, fname);
587 if (!NT_STATUS_IS_OK(status)) {
592 new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
594 existing_dos_attributes = dos_mode(conn, fname, psbuf);
598 /* Setup dos_attributes to be set by ifs_createfile */
599 if (lp_store_dos_attributes(SNUM(conn))) {
600 createfile_attributes = (new_dos_attributes | aARCH) &
601 ~(FILE_ATTRIBUTE_NONINDEXED | FILE_ATTRIBUTE_COMPRESSED);
604 /* Ignore oplock requests if oplocks are disabled. */
605 if (!lp_oplocks(SNUM(conn)) || global_client_failed_oplock_break ||
606 IS_VETO_OPLOCK_PATH(conn, fname)) {
607 /* Mask off everything except the private Samba bits. */
608 oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
611 /* this is for OS/2 long file names - say we don't support them */
612 if (!lp_posix_pathnames() && strstr(fname,".+,;=[].")) {
613 /* OS/2 Workplace shell fix may be main code stream in a later
615 DEBUG(5,("onefs_open_file_ntcreate: OS/2 long filenames are "
616 "not supported.\n"));
617 if (use_nt_status()) {
618 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
620 return NT_STATUS_DOS(ERRDOS, ERRcannotopen);
623 switch( create_disposition ) {
625 * Currently we're using FILE_SUPERSEDE as the same as
626 * FILE_OVERWRITE_IF but they really are
627 * different. FILE_SUPERSEDE deletes an existing file
628 * (requiring delete access) then recreates it.
632 * @todo: Clear all file attributes?
633 * http://www.osronline.com/article.cfm?article=302
634 * create if not exist, trunc if exist
636 * If file exists replace/overwrite. If file doesn't
639 flags2 |= (O_CREAT | O_TRUNC);
643 case FILE_OVERWRITE_IF:
644 /* If file exists replace/overwrite. If file doesn't
646 flags2 |= (O_CREAT | O_TRUNC);
651 /* If file exists open. If file doesn't exist error. */
653 DEBUG(5,("onefs_open_file_ntcreate: FILE_OPEN "
654 "requested for file %s and file "
655 "doesn't exist.\n", fname ));
657 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
662 /* If file exists overwrite. If file doesn't exist
665 DEBUG(5, ("onefs_open_file_ntcreate: "
666 "FILE_OVERWRITE requested for file "
667 "%s and file doesn't exist.\n",
670 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
677 /* If file exists error. If file doesn't exist
680 DEBUG(5, ("onefs_open_file_ntcreate: "
681 "FILE_CREATE requested for file %s "
682 "and file already exists.\n",
684 if (S_ISDIR(psbuf->st_mode)) {
689 return map_nt_error_from_unix(errno);
691 flags2 |= (O_CREAT|O_EXCL);
695 /* If file exists open. If file doesn't exist
701 return NT_STATUS_INVALID_PARAMETER;
704 /* Match attributes on file exists and overwrite. */
705 if (!posix_open && file_existed &&
706 ((create_disposition == FILE_OVERWRITE) ||
707 (create_disposition == FILE_OVERWRITE_IF))) {
708 if (!open_match_attributes(conn, fname,
709 existing_dos_attributes,
710 new_dos_attributes, psbuf->st_mode,
711 unx_mode, &new_unx_mode)) {
712 DEBUG(5, ("onefs_open_file_ntcreate: attributes "
713 "missmatch for file %s (%x %x) (0%o, 0%o)\n",
714 fname, existing_dos_attributes,
716 (unsigned int)psbuf->st_mode,
717 (unsigned int)unx_mode ));
719 return NT_STATUS_ACCESS_DENIED;
724 * OneFS understands MAXIMUM_ALLOWED_ACCESS, so only hack the
725 * access_mask, but leave the MAA for the actual open in
728 open_access_mask = access_mask;
729 if (open_access_mask & MAXIMUM_ALLOWED_ACCESS) {
730 access_mask |= FILE_GENERIC_ALL;
733 /* Convert GENERIC bits to specific bits. */
734 se_map_generic(&access_mask, &file_generic_mapping);
735 se_map_generic(&open_access_mask, &file_generic_mapping);
737 if ((flags2 & O_TRUNC) || (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE)) {
738 /* This will cause oplock breaks. */
739 open_access_mask |= FILE_WRITE_DATA;
742 if (lp_parm_bool(SNUM(fsp->conn), PARM_ONEFS_TYPE,
743 PARM_IGNORE_SACLS, PARM_IGNORE_SACLS_DEFAULT)) {
744 access_mask &= ~SYSTEM_SECURITY_ACCESS;
747 DEBUG(10, ("onefs_open_file_ntcreate: fname=%s, after mapping "
748 "open_access_mask=%#x, access_mask=0x%x\n",
749 fname, open_access_mask, access_mask));
752 * Note that we ignore the append flag as append does not
753 * mean the same thing under DOS and Unix.
756 if ((access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ||
757 (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE)) {
760 * DENY_DOS opens are always underlying read-write on the
761 * file handle, no matter what the requested access mask
762 * says. Stock samba just sets the flags, but since
763 * ifs_createfile uses the access_mask, it must be updated as
764 * well. This allows BASE-DENY* to pass.
766 if (create_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) {
768 DEBUG(10,("onefs_open_file_ntcreate: deny_dos: "
769 "Adding O_RDWR to flags "
770 "(0x%x) and some READ bits to "
771 "open_access_mask (0x%x)\n",
772 flags, open_access_mask));
775 open_access_mask |= (FILE_READ_ATTRIBUTES |
776 FILE_READ_DATA | FILE_READ_EA | FILE_EXECUTE);
778 } else if (access_mask & (FILE_READ_ATTRIBUTES |
790 /* Currently we only look at FILE_WRITE_THROUGH for create options. */
792 if ((create_options & FILE_WRITE_THROUGH) &&
793 lp_strict_sync(SNUM(conn))) {
798 if (posix_open && (access_mask & FILE_APPEND_DATA)) {
802 if (!posix_open && !CAN_WRITE(conn)) {
804 * We should really return a permission denied error if either
805 * O_CREAT or O_TRUNC are set, but for compatibility with
806 * older versions of Samba we just AND them out.
808 flags2 &= ~(O_CREAT|O_TRUNC);
810 /* Deny DELETE_ACCESS explicitly if the share is read only. */
811 if (access_mask & DELETE_ACCESS) {
812 return map_nt_error_from_unix(EACCES);
816 /* Ensure we can't write on a read-only share or file. */
817 if (flags != O_RDONLY && file_existed &&
818 (!CAN_WRITE(conn) || IS_DOS_READONLY(existing_dos_attributes))) {
819 DEBUG(5, ("onefs_open_file_ntcreate: write access requested "
820 "for file %s on read only %s\n",
821 fname, !CAN_WRITE(conn) ? "share" : "file" ));
823 return NT_STATUS_ACCESS_DENIED;
826 DEBUG(10, ("fsp = %p\n", fsp));
828 fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf);
829 fsp->share_access = share_access;
830 fsp->fh->private_options = create_options;
831 fsp->access_mask = open_access_mask; /* We change this to the
832 * requested access_mask after
833 * the open is done. */
834 fsp->posix_open = posix_open;
836 /* Ensure no SAMBA_PRIVATE bits can be set. */
837 fsp->oplock_type = (oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK);
839 if (timeval_is_zero(&request_time)) {
840 request_time = fsp->open_time;
844 struct timespec old_write_time = get_mtimespec(psbuf);
845 id = vfs_file_id_from_sbuf(conn, psbuf);
847 lck = get_share_mode_lock(talloc_tos(), id,
849 fname, &old_write_time);
852 DEBUG(0, ("Could not get share mode lock\n"));
853 return NT_STATUS_SHARING_VIOLATION;
856 if (lck->delete_on_close) {
857 /* DELETE_PENDING is not deferred for a second */
859 return NT_STATUS_DELETE_PENDING;
863 SMB_ASSERT(!file_existed || (lck != NULL));
866 * Ensure we pay attention to default ACLs on directories. May be
867 * neccessary depending on ACL policies.
869 if ((flags2 & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
870 (def_acl = directory_has_default_acl(conn, parent_dir))) {
874 DEBUG(4,("calling onefs_open_file with flags=0x%X flags2=0x%X "
875 "mode=0%o, access_mask = 0x%x, open_access_mask = 0x%x\n",
876 (unsigned int)flags, (unsigned int)flags2,
877 (unsigned int)unx_mode, (unsigned int)access_mask,
878 (unsigned int)open_access_mask));
881 * Since the open is guaranteed to be stat only if req == NULL, a
882 * callback record is only needed if req != NULL.
885 SMB_ASSERT(fsp_data);
886 oplock_callback_id = onefs_oplock_wait_record(req->mid);
887 if (oplock_callback_id == 0) {
888 return NT_STATUS_NO_MEMORY;
892 * It is also already asserted it's either a stream or a
893 * stat-only open at this point.
895 SMB_ASSERT(fsp->oplock_type == NO_OPLOCK);
899 status = onefs_open_file(fsp,
914 createfile_attributes,
918 if (!NT_STATUS_IS_OK(status)) {
920 /* OneFS Oplock Handling */
921 if (errno == EINPROGRESS) {
925 struct deferred_open_record state;
926 struct timespec old_write_time;
928 old_write_time = get_mtimespec(psbuf);
930 DEBUG(3, ("Someone created file %s with an "
931 "oplock after we looked: Retrying\n",
934 * We hit the race that when we did the stat
935 * on the file it did not exist, and someone
936 * has created it in between the stat and the
937 * open_file() call. Just retry immediately.
939 id = vfs_file_id_from_sbuf(conn, psbuf);
940 if (!(lck = get_share_mode_lock(talloc_tos(),
941 id, conn->connectpath, fname,
946 DEBUG(0, ("onefs_open_file_ntcreate: "
947 "Could not get share mode "
948 "lock for %s\n", fname));
949 status = NT_STATUS_SHARING_VIOLATION;
950 goto cleanup_destroy;
953 state.delayed_for_oplocks = False;
957 defer_open(lck, request_time,
958 timeval_zero(), req, &state);
960 goto cleanup_destroy;
962 /* Waiting for an oplock */
963 DEBUG(5,("Async createfile because a client has an "
964 "oplock on %s\n", fname));
967 schedule_defer_open(lck, request_time, req);
971 /* Check for a sharing violation */
972 if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
973 uint32 can_access_mask;
974 bool can_access = True;
976 /* Check if this can be done with the deny_dos and fcb
979 /* Try to find dup fsp if possible. */
981 (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS|
982 NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) {
985 DEBUG(0, ("DOS open without an SMB "
987 status = NT_STATUS_INTERNAL_ERROR;
988 goto cleanup_destroy;
991 /* Use the client requested access mask here,
992 * not the one we open with. */
993 status = fcb_or_dos_open(req,
1004 if (NT_STATUS_IS_OK(status)) {
1007 *pinfo = FILE_WAS_OPENED;
1009 status = NT_STATUS_OK;
1015 * This next line is a subtlety we need for
1016 * MS-Access. If a file open will fail due to share
1017 * permissions and also for security (access) reasons,
1018 * we need to return the access failed error, not the
1019 * share error. We can't open the file due to kernel
1020 * oplock deadlock (it's possible we failed above on
1021 * the open_mode_check()) so use a userspace check.
1024 if (flags & O_RDWR) {
1025 can_access_mask = FILE_READ_DATA|FILE_WRITE_DATA;
1026 } else if (flags & O_WRONLY) {
1027 can_access_mask = FILE_WRITE_DATA;
1029 can_access_mask = FILE_READ_DATA;
1032 if (((can_access_mask & FILE_WRITE_DATA) && !CAN_WRITE(conn)) ||
1033 !can_access_file_data(conn,fname,psbuf,can_access_mask)) {
1038 * If we're returning a share violation, ensure we
1039 * cope with the braindead 1 second delay.
1041 if (!(oplock_request & INTERNAL_OPEN_ONLY) &&
1042 lp_defer_sharing_violations()) {
1043 struct timeval timeout;
1044 struct deferred_open_record state;
1047 /* this is a hack to speed up torture tests
1049 timeout_usecs = lp_parm_int(SNUM(conn),
1050 "smbd","sharedelay",
1051 SHARING_VIOLATION_USEC_WAIT);
1053 /* This is a relative time, added to the
1054 absolute request_time value to get the
1055 absolute timeout time. Note that if this
1056 is the second or greater time we enter this
1057 codepath for this particular request mid
1058 then request_time is left as the absolute
1059 time of the *first* time this request mid
1060 was processed. This is what allows the
1061 request to eventually time out. */
1063 timeout = timeval_set(0, timeout_usecs);
1065 /* Nothing actually uses
1066 state.delayed_for_oplocks but it's handy to
1067 differentiate in debug messages between a
1068 30 second delay due to oplock break, and a
1069 1 second delay for share mode conflicts. */
1071 state.delayed_for_oplocks = False;
1073 state.failed = false;
1076 && !request_timed_out(request_time,
1078 defer_open(lck, request_time, timeout,
1085 * We have detected a sharing violation here
1086 * so return the correct error code
1088 status = NT_STATUS_SHARING_VIOLATION;
1090 status = NT_STATUS_ACCESS_DENIED;
1093 goto cleanup_destroy;
1097 * Normal error, for example EACCES
1100 if (oplock_callback_id != 0) {
1101 destroy_onefs_callback_record(oplock_callback_id);
1108 fsp->oplock_type = granted_oplock;
1110 if (oplock_callback_id != 0) {
1111 onefs_set_oplock_callback(oplock_callback_id, fsp);
1112 fsp_data->oplock_callback_id = oplock_callback_id;
1114 SMB_ASSERT(fsp->oplock_type == NO_OPLOCK);
1117 if (!file_existed) {
1118 struct timespec old_write_time = get_mtimespec(psbuf);
1120 * Deal with the race condition where two smbd's detect the
1121 * file doesn't exist and do the create at the same time. One
1122 * of them will win and set a share mode, the other (ie. this
1123 * one) should check if the requested share mode for this
1124 * create is allowed.
1128 * Now the file exists and fsp is successfully opened,
1129 * fsp->dev and fsp->inode are valid and should replace the
1130 * dev=0,inode=0 from a non existent file. Spotted by
1131 * Nadav Danieli <nadavd@exanet.com>. JRA.
1136 lck = get_share_mode_lock(talloc_tos(), id,
1138 fname, &old_write_time);
1141 DEBUG(0, ("onefs_open_file_ntcreate: Could not get "
1142 "share mode lock for %s\n", fname));
1144 return NT_STATUS_SHARING_VIOLATION;
1147 if (lck->delete_on_close) {
1148 status = NT_STATUS_DELETE_PENDING;
1151 if (!NT_STATUS_IS_OK(status)) {
1152 struct deferred_open_record state;
1156 state.delayed_for_oplocks = False;
1159 /* Do it all over again immediately. In the second
1160 * round we will find that the file existed and handle
1161 * the DELETE_PENDING and FCB cases correctly. No need
1162 * to duplicate the code here. Essentially this is a
1163 * "goto top of this function", but don't tell
1167 defer_open(lck, request_time, timeval_zero(),
1175 * We exit this block with the share entry *locked*.....
1180 SMB_ASSERT(lck != NULL);
1182 /* Delete streams if create_disposition requires it */
1183 if (file_existed && clear_ads && !is_ntfs_stream_name(fname)) {
1184 status = delete_all_streams(conn, fname);
1185 if (!NT_STATUS_IS_OK(status)) {
1192 /* note that we ignore failure for the following. It is
1193 basically a hack for NFS, and NFS will never set one of
1194 these only read them. Nobody but Samba can ever set a deny
1195 mode and we have already checked our more authoritative
1196 locking database for permission to set this deny mode. If
1197 the kernel refuses the operations then the kernel is wrong.
1198 note that GPFS supports it as well - jmcd */
1200 if (fsp->fh->fd != -1) {
1201 ret_flock = SMB_VFS_KERNEL_FLOCK(fsp, share_access);
1202 if(ret_flock == -1 ){
1206 return NT_STATUS_SHARING_VIOLATION;
1211 * At this point onwards, we can guarentee that the share entry
1212 * is locked, whether we created the file or not, and that the
1213 * deny mode is compatible with all current opens.
1216 /* Record the options we were opened with. */
1217 fsp->share_access = share_access;
1218 fsp->fh->private_options = create_options;
1220 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
1222 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
1225 /* stat opens on existing files don't get oplocks. */
1226 if (is_stat_open(open_access_mask)) {
1227 fsp->oplock_type = NO_OPLOCK;
1230 if (!(flags2 & O_TRUNC)) {
1231 info = FILE_WAS_OPENED;
1233 info = FILE_WAS_OVERWRITTEN;
1236 info = FILE_WAS_CREATED;
1244 * Setup the oplock info in both the shared memory and
1248 if ((fsp->oplock_type != NO_OPLOCK) &&
1249 (fsp->oplock_type != FAKE_LEVEL_II_OPLOCK)) {
1250 if (!set_file_oplock(fsp, fsp->oplock_type)) {
1251 /* Could not get the kernel oplock */
1252 fsp->oplock_type = NO_OPLOCK;
1256 if (fsp->oplock_type == LEVEL_II_OPLOCK &&
1257 (!lp_level2_oplocks(SNUM(conn)) ||
1258 !(global_client_caps & CAP_LEVEL_II_OPLOCKS))) {
1260 DEBUG(5, ("Downgrading level2 oplock on open "
1261 "because level2 oplocks = off\n"));
1263 release_file_oplock(fsp);
1266 if (info == FILE_WAS_OVERWRITTEN || info == FILE_WAS_CREATED ||
1267 info == FILE_WAS_SUPERSEDED) {
1268 new_file_created = True;
1271 set_share_mode(lck, fsp, conn->server_info->utok.uid, 0,
1274 /* Handle strange delete on close create semantics. */
1275 if (create_options & FILE_DELETE_ON_CLOSE) {
1276 status = can_set_delete_on_close(fsp, True, new_dos_attributes);
1278 if (!NT_STATUS_IS_OK(status)) {
1279 /* Remember to delete the mode we just added. */
1280 del_share_mode(lck, fsp);
1285 /* Note that here we set the *inital* delete on close flag,
1286 not the regular one. The magic gets handled in close. */
1287 fsp->initial_delete_on_close = True;
1291 * Take care of inherited ACLs on created files - if default ACL not
1293 * May be necessary depending on acl policies.
1295 if (!posix_open && !file_existed && !def_acl && !(VALID_STAT(*psbuf)
1296 && (psbuf->st_flags & SF_HASNTFSACL))) {
1298 int saved_errno = errno; /* We might get ENOSYS in the next
1301 if (SMB_VFS_FCHMOD_ACL(fsp, unx_mode) == -1 &&
1303 errno = saved_errno; /* Ignore ENOSYS */
1306 } else if (new_unx_mode) {
1310 /* Attributes need changing. File already existed. */
1313 int saved_errno = errno; /* We might get ENOSYS in the
1315 ret = SMB_VFS_FCHMOD_ACL(fsp, new_unx_mode);
1317 if (ret == -1 && errno == ENOSYS) {
1318 errno = saved_errno; /* Ignore ENOSYS */
1320 DEBUG(5, ("onefs_open_file_ntcreate: reset "
1321 "attributes of file %s to 0%o\n",
1322 fname, (unsigned int)new_unx_mode));
1323 ret = 0; /* Don't do the fchmod below. */
1328 (SMB_VFS_FCHMOD(fsp, new_unx_mode) == -1))
1329 DEBUG(5, ("onefs_open_file_ntcreate: failed to reset "
1330 "attributes of file %s to 0%o\n",
1331 fname, (unsigned int)new_unx_mode));
1334 /* If this is a successful open, we must remove any deferred open
1337 del_deferred_open_entry(lck, req->mid);
1341 return NT_STATUS_OK;
1345 /****************************************************************************
1346 Open a directory from an NT SMB call.
1347 ****************************************************************************/
1348 static NTSTATUS onefs_open_directory(connection_struct *conn,
1349 struct smb_request *req,
1352 uint32 share_access,
1353 uint32 create_disposition,
1354 uint32 create_options,
1355 uint32 file_attributes,
1356 struct security_descriptor *sd,
1357 files_struct **result,
1359 SMB_STRUCT_STAT *psbuf)
1361 files_struct *fsp = NULL;
1362 struct share_mode_lock *lck = NULL;
1364 struct timespec mtimespec;
1367 const char *dirname;
1368 bool posix_open = false;
1369 uint32 create_flags = 0;
1370 uint32 mode = lp_dir_mask(SNUM(conn));
1372 DEBUG(5, ("onefs_open_directory: opening directory %s, "
1373 "access_mask = 0x%x, "
1374 "share_access = 0x%x create_options = 0x%x, "
1375 "create_disposition = 0x%x, file_attributes = 0x%x\n",
1376 fname, (unsigned int)access_mask, (unsigned int)share_access,
1377 (unsigned int)create_options, (unsigned int)create_disposition,
1378 (unsigned int)file_attributes));
1380 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
1381 (conn->fs_capabilities & FILE_NAMED_STREAMS) &&
1382 is_ntfs_stream_name(fname)) {
1383 DEBUG(2, ("onefs_open_directory: %s is a stream name!\n", fname));
1384 return NT_STATUS_NOT_A_DIRECTORY;
1387 switch (create_disposition) {
1389 /* If directory exists open. If directory doesn't
1392 info = FILE_WAS_OPENED;
1395 /* If directory exists error. If directory doesn't
1397 create_flags = O_CREAT | O_EXCL;
1398 info = FILE_WAS_CREATED;
1401 /* If directory exists open. If directory doesn't
1404 /* Note: in order to return whether the directory was
1405 * opened or created, we first try to open and then try
1408 info = FILE_WAS_OPENED;
1410 case FILE_SUPERSEDE:
1411 case FILE_OVERWRITE:
1412 case FILE_OVERWRITE_IF:
1414 DEBUG(5, ("onefs_open_directory: invalid "
1415 "create_disposition 0x%x for directory %s\n",
1416 (unsigned int)create_disposition, fname));
1417 return NT_STATUS_INVALID_PARAMETER;
1421 * Check for write access to the share. Done in mkdir_internal() in
1424 if (!CAN_WRITE(conn) && (create_flags & O_CREAT)) {
1425 return NT_STATUS_ACCESS_DENIED;
1428 /* Get parent dirname */
1429 if (!parent_dirname(talloc_tos(), fname, &parent_dir, &dirname)) {
1430 return NT_STATUS_NO_MEMORY;
1433 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
1435 mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
1436 file_attributes = 0;
1438 mode = unix_mode(conn, aDIR, fname, parent_dir);
1442 * The NONINDEXED and COMPRESSED bits seem to always be cleared on
1443 * directories, no matter if you specify that they should be set.
1446 ~(FILE_ATTRIBUTE_NONINDEXED | FILE_ATTRIBUTE_COMPRESSED);
1448 status = file_new(req, conn, &fsp);
1449 if(!NT_STATUS_IS_OK(status)) {
1454 * Actual open with retry magic to handle FILE_OPEN_IF which is
1455 * unique because the kernel won't tell us if the file was opened or
1459 fsp->fh->fd = onefs_sys_create_file(conn,
1466 create_flags | O_DIRECTORY,
1474 if (fsp->fh->fd == -1) {
1475 DEBUG(3, ("Error opening %s. Errno=%d (%s).\n", fname, errno,
1477 SMB_ASSERT(errno != EINPROGRESS);
1479 if (create_disposition == FILE_OPEN_IF) {
1480 if (errno == ENOENT) {
1481 /* Try again, creating it this time. */
1482 create_flags = O_CREAT | O_EXCL;
1483 info = FILE_WAS_CREATED;
1485 } else if (errno == EEXIST) {
1486 /* Uggh. Try again again. */
1488 info = FILE_WAS_OPENED;
1493 /* Error cases below: */
1494 file_free(req, fsp);
1496 if ((errno == ENOENT) && (create_disposition == FILE_OPEN)) {
1497 DEBUG(5,("onefs_open_directory: FILE_OPEN requested "
1498 "for directory %s and it doesn't "
1499 "exist.\n", fname ));
1500 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1501 } else if ((errno == EEXIST) &&
1502 (create_disposition == FILE_CREATE)) {
1503 DEBUG(5,("onefs_open_directory: FILE_CREATE "
1504 "requested for directory %s and it "
1505 "already exists.\n", fname ));
1506 return NT_STATUS_OBJECT_NAME_COLLISION;
1507 } else if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
1508 /* Catch sharing violations. */
1509 return NT_STATUS_SHARING_VIOLATION;
1512 return map_nt_error_from_unix(errno);
1515 if (info == FILE_WAS_CREATED) {
1517 /* Pulled from mkdir_internal() */
1518 if (SMB_VFS_LSTAT(conn, fname, psbuf) == -1) {
1519 DEBUG(2, ("Could not stat directory '%s' just "
1520 "created: %s\n",fname, strerror(errno)));
1521 return map_nt_error_from_unix(errno);
1524 if (!S_ISDIR(psbuf->st_mode)) {
1525 DEBUG(0, ("Directory just '%s' created is not a "
1526 "directory\n", fname));
1527 return NT_STATUS_ACCESS_DENIED;
1532 * Check if high bits should have been set, then (if
1533 * bits are missing): add them. Consider bits
1534 * automagically set by UNIX, i.e. SGID bit from
1537 if (mode & ~(S_IRWXU|S_IRWXG|S_IRWXO) &&
1538 (mode & ~psbuf->st_mode)) {
1539 SMB_VFS_CHMOD(conn, fname, (psbuf->st_mode |
1540 (mode & ~psbuf->st_mode)));
1544 /* Change the owner if required. */
1545 if (lp_inherit_owner(SNUM(conn))) {
1546 change_dir_owner_to_parent(conn, parent_dir, fname,
1550 notify_fname(conn, NOTIFY_ACTION_ADDED,
1551 FILE_NOTIFY_CHANGE_DIR_NAME, fname);
1554 /* Stat the fd for Samba bookkeeping. */
1555 if(SMB_VFS_FSTAT(fsp, psbuf) != 0) {
1557 file_free(req, fsp);
1558 return map_nt_error_from_unix(errno);
1561 /* Setup the files_struct for it. */
1562 fsp->mode = psbuf->st_mode;
1563 fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf);
1564 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
1565 fsp->file_pid = req ? req->smbpid : 0;
1566 fsp->can_lock = False;
1567 fsp->can_read = False;
1568 fsp->can_write = False;
1570 fsp->share_access = share_access;
1571 fsp->fh->private_options = create_options;
1573 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
1575 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
1576 fsp->print_file = False;
1577 fsp->modified = False;
1578 fsp->oplock_type = NO_OPLOCK;
1579 fsp->sent_oplock_break = NO_BREAK_SENT;
1580 fsp->is_directory = True;
1581 fsp->posix_open = posix_open;
1583 string_set(&fsp->fsp_name,fname);
1585 mtimespec = get_mtimespec(psbuf);
1588 * Still set the samba share mode lock for correct delete-on-close
1589 * semantics and to make smbstatus more useful.
1591 lck = get_share_mode_lock(talloc_tos(), fsp->file_id,
1596 DEBUG(0, ("onefs_open_directory: Could not get share mode "
1597 "lock for %s\n", fname));
1599 file_free(req, fsp);
1600 return NT_STATUS_SHARING_VIOLATION;
1603 if (lck->delete_on_close) {
1606 file_free(req, fsp);
1607 return NT_STATUS_DELETE_PENDING;
1610 set_share_mode(lck, fsp, conn->server_info->utok.uid, 0, NO_OPLOCK);
1613 * For directories the delete on close bit at open time seems
1614 * always to be honored on close... See test 19 in Samba4 BASE-DELETE.
1616 if (create_options & FILE_DELETE_ON_CLOSE) {
1617 status = can_set_delete_on_close(fsp, True, 0);
1618 if (!NT_STATUS_IS_OK(status) &&
1619 !NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
1622 file_free(req, fsp);
1626 if (NT_STATUS_IS_OK(status)) {
1627 /* Note that here we set the *inital* delete on close flag,
1628 not the regular one. The magic gets handled in close. */
1629 fsp->initial_delete_on_close = True;
1640 return NT_STATUS_OK;
1644 * Wrapper around onefs_open_file_ntcreate and onefs_open_directory.
1646 static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
1647 struct smb_request *req,
1649 uint32_t access_mask,
1650 uint32_t share_access,
1651 uint32_t create_disposition,
1652 uint32_t create_options,
1653 uint32_t file_attributes,
1654 uint32_t oplock_request,
1655 uint64_t allocation_size,
1656 struct security_descriptor *sd,
1657 struct ea_list *ea_list,
1658 files_struct **result,
1660 struct onefs_fsp_data *fsp_data,
1661 SMB_STRUCT_STAT *psbuf)
1663 SMB_STRUCT_STAT sbuf;
1664 int info = FILE_WAS_OPENED;
1665 files_struct *base_fsp = NULL;
1666 files_struct *fsp = NULL;
1669 DEBUG(10,("onefs_create_file_unixpath: access_mask = 0x%x "
1670 "file_attributes = 0x%x, share_access = 0x%x, "
1671 "create_disposition = 0x%x create_options = 0x%x "
1672 "oplock_request = 0x%x ea_list = 0x%p, sd = 0x%p, "
1674 (unsigned int)access_mask,
1675 (unsigned int)file_attributes,
1676 (unsigned int)share_access,
1677 (unsigned int)create_disposition,
1678 (unsigned int)create_options,
1679 (unsigned int)oplock_request,
1680 ea_list, sd, fname));
1682 if (create_options & FILE_OPEN_BY_FILE_ID) {
1683 status = NT_STATUS_NOT_SUPPORTED;
1687 if (create_options & NTCREATEX_OPTIONS_INVALID_PARAM_MASK) {
1688 status = NT_STATUS_INVALID_PARAMETER;
1693 SMB_ASSERT((oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK) ==
1695 oplock_request |= INTERNAL_OPEN_ONLY;
1698 if (psbuf != NULL) {
1702 if (SMB_VFS_STAT(conn, fname, &sbuf) == -1) {
1703 SET_STAT_INVALID(sbuf);
1707 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
1708 && (access_mask & DELETE_ACCESS)
1709 && !is_ntfs_stream_name(fname)) {
1711 * We can't open a file with DELETE access if any of the
1712 * streams is open without FILE_SHARE_DELETE
1714 status = open_streams_for_delete(conn, fname);
1716 if (!NT_STATUS_IS_OK(status)) {
1721 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
1722 && is_ntfs_stream_name(fname)) {
1724 uint32 base_create_disposition;
1726 if (create_options & FILE_DIRECTORY_FILE) {
1727 status = NT_STATUS_NOT_A_DIRECTORY;
1731 status = onefs_split_ntfs_stream_name(talloc_tos(), fname,
1733 if (!NT_STATUS_IS_OK(status)) {
1734 DEBUG(10, ("onefs_create_file_unixpath: "
1735 "split_ntfs_stream_name failed: %s\n",
1736 nt_errstr(status)));
1740 SMB_ASSERT(!is_ntfs_stream_name(base)); /* paranoia.. */
1742 switch (create_disposition) {
1744 base_create_disposition = FILE_OPEN;
1747 base_create_disposition = FILE_OPEN_IF;
1751 status = onefs_create_file_unixpath(
1755 SYNCHRONIZE_ACCESS, /* access_mask */
1758 FILE_SHARE_DELETE), /* share_access */
1759 base_create_disposition, /* create_disposition*/
1760 0, /* create_options */
1761 file_attributes, /* file_attributes */
1762 NO_OPLOCK, /* oplock_request */
1763 0, /* allocation_size */
1766 &base_fsp, /* result */
1768 NULL, /* fsp_data */
1771 if (!NT_STATUS_IS_OK(status)) {
1772 DEBUG(10, ("onefs_create_file_unixpath for base %s "
1773 "failed: %s\n", base, nt_errstr(status)));
1778 /* Covert generic bits in the security descriptor. */
1780 security_acl_map_generic(sd->dacl, &file_generic_mapping);
1781 security_acl_map_generic(sd->sacl, &file_generic_mapping);
1785 * If it's a request for a directory open, deal with it separately.
1788 if (create_options & FILE_DIRECTORY_FILE) {
1790 if (create_options & FILE_NON_DIRECTORY_FILE) {
1791 status = NT_STATUS_INVALID_PARAMETER;
1795 /* Can't open a temp directory. IFS kit test. */
1796 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
1797 (file_attributes & FILE_ATTRIBUTE_TEMPORARY)) {
1798 status = NT_STATUS_INVALID_PARAMETER;
1803 * We will get a create directory here if the Win32
1804 * app specified a security descriptor in the
1805 * CreateDirectory() call.
1808 status = onefs_open_directory(
1812 access_mask, /* access_mask */
1813 share_access, /* share_access */
1814 create_disposition, /* create_disposition*/
1815 create_options, /* create_options */
1816 file_attributes, /* file_attributes */
1824 * Ordinary file case.
1827 status = file_new(req, conn, &fsp);
1828 if(!NT_STATUS_IS_OK(status)) {
1833 * We're opening the stream element of a base_fsp
1834 * we already opened. Set up the base_fsp pointer.
1837 fsp->base_fsp = base_fsp;
1840 status = onefs_open_file_ntcreate(
1844 access_mask, /* access_mask */
1845 share_access, /* share_access */
1846 create_disposition, /* create_disposition*/
1847 create_options, /* create_options */
1848 file_attributes, /* file_attributes */
1849 oplock_request, /* oplock_request */
1853 fsp_data, /* fsp_data */
1856 if(!NT_STATUS_IS_OK(status)) {
1857 file_free(req, fsp);
1861 if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
1863 /* A stream open never opens a directory */
1866 status = NT_STATUS_FILE_IS_A_DIRECTORY;
1871 * Fail the open if it was explicitly a non-directory
1875 if (create_options & FILE_NON_DIRECTORY_FILE) {
1876 status = NT_STATUS_FILE_IS_A_DIRECTORY;
1880 create_options |= FILE_DIRECTORY_FILE;
1882 status = onefs_open_directory(
1886 access_mask, /* access_mask */
1887 share_access, /* share_access */
1888 create_disposition, /* create_disposition*/
1889 create_options, /* create_options */
1890 file_attributes, /* file_attributes */
1898 if (!NT_STATUS_IS_OK(status)) {
1902 fsp->base_fsp = base_fsp;
1906 if ((ea_list != NULL) && (info == FILE_WAS_CREATED)) {
1907 status = set_ea(conn, fsp, fname, ea_list);
1908 if (!NT_STATUS_IS_OK(status)) {
1913 if (!fsp->is_directory && S_ISDIR(sbuf.st_mode)) {
1914 status = NT_STATUS_ACCESS_DENIED;
1918 /* Save the requested allocation size. */
1919 if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
1921 && (allocation_size > sbuf.st_size)) {
1922 fsp->initial_allocation_size = smb_roundup(
1923 fsp->conn, allocation_size);
1924 if (fsp->is_directory) {
1925 /* Can't set allocation size on a directory. */
1926 status = NT_STATUS_ACCESS_DENIED;
1929 if (vfs_allocate_file_space(
1930 fsp, fsp->initial_allocation_size) == -1) {
1931 status = NT_STATUS_DISK_FULL;
1935 fsp->initial_allocation_size = smb_roundup(
1936 fsp->conn, (uint64_t)sbuf.st_size);
1940 DEBUG(10, ("onefs_create_file_unixpath: info=%d\n", info));
1943 if (pinfo != NULL) {
1946 if (psbuf != NULL) {
1947 if ((fsp->fh == NULL) || (fsp->fh->fd == -1)) {
1951 SMB_VFS_FSTAT(fsp, psbuf);
1954 return NT_STATUS_OK;
1957 DEBUG(10, ("onefs_create_file_unixpath: %s\n", nt_errstr(status)));
1960 if (base_fsp && fsp->base_fsp == base_fsp) {
1962 * The close_file below will close
1967 close_file(req, fsp, ERROR_CLOSE);
1970 if (base_fsp != NULL) {
1971 close_file(req, base_fsp, ERROR_CLOSE);
1977 static void destroy_onefs_fsp_data(void *p_data)
1979 struct onefs_fsp_data *fsp_data = (struct onefs_fsp_data *)p_data;
1981 destroy_onefs_callback_record(fsp_data->oplock_callback_id);
1985 * SMB_VFS_CREATE_FILE interface to onefs.
1987 NTSTATUS onefs_create_file(vfs_handle_struct *handle,
1988 struct smb_request *req,
1989 uint16_t root_dir_fid,
1991 uint32_t create_file_flags,
1992 uint32_t access_mask,
1993 uint32_t share_access,
1994 uint32_t create_disposition,
1995 uint32_t create_options,
1996 uint32_t file_attributes,
1997 uint32_t oplock_request,
1998 uint64_t allocation_size,
1999 struct security_descriptor *sd,
2000 struct ea_list *ea_list,
2001 files_struct **result,
2003 SMB_STRUCT_STAT *psbuf)
2005 connection_struct *conn = handle->conn;
2006 struct case_semantics_state *case_state = NULL;
2007 struct onefs_fsp_data fsp_data = {};
2008 SMB_STRUCT_STAT sbuf;
2009 int info = FILE_WAS_OPENED;
2010 files_struct *fsp = NULL;
2013 DEBUG(10,("onefs_create_file: access_mask = 0x%x "
2014 "file_attributes = 0x%x, share_access = 0x%x, "
2015 "create_disposition = 0x%x create_options = 0x%x "
2016 "oplock_request = 0x%x "
2017 "root_dir_fid = 0x%x, ea_list = 0x%p, sd = 0x%p, "
2018 "create_file_flags = 0x%x, fname = %s\n",
2019 (unsigned int)access_mask,
2020 (unsigned int)file_attributes,
2021 (unsigned int)share_access,
2022 (unsigned int)create_disposition,
2023 (unsigned int)create_options,
2024 (unsigned int)oplock_request,
2025 (unsigned int)root_dir_fid,
2026 ea_list, sd, create_file_flags, fname));
2028 /* Get the file name if root_dir_fid was specified. */
2029 if (root_dir_fid != 0) {
2032 status = get_relative_fid_filename(conn, req, root_dir_fid,
2034 if (!NT_STATUS_IS_OK(status)) {
2041 /* Resolve the file name if this was a DFS pathname. */
2042 if ((req != NULL) && (req->flags2 & FLAGS2_DFS_PATHNAMES)) {
2043 char *resolved_fname;
2045 status = resolve_dfspath(talloc_tos(), conn, true, fname,
2048 if (!NT_STATUS_IS_OK(status)) {
2050 * For PATH_NOT_COVERED we had
2051 * reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
2052 * ERRSRV, ERRbadpath);
2053 * Need to fix in callers
2057 fname = resolved_fname;
2060 /* Check if POSIX semantics are wanted. */
2061 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
2062 case_state = set_posix_case_semantics(talloc_tos(), conn);
2065 /* Convert dos path to unix path if it hasn't already been done. */
2066 if (create_file_flags & CFF_DOS_PATH) {
2067 char *converted_fname;
2069 SET_STAT_INVALID(sbuf);
2071 status = unix_convert(talloc_tos(), conn, fname, False,
2072 &converted_fname, NULL, &sbuf);
2073 if (!NT_STATUS_IS_OK(status)) {
2076 fname = converted_fname;
2078 if (psbuf != NULL) {
2081 if (SMB_VFS_STAT(conn, fname, &sbuf) == -1) {
2082 SET_STAT_INVALID(sbuf);
2088 TALLOC_FREE(case_state);
2090 /* All file access must go through check_name() */
2091 status = check_name(conn, fname);
2092 if (!NT_STATUS_IS_OK(status)) {
2096 status = onefs_create_file_unixpath(
2100 access_mask, /* access_mask */
2101 share_access, /* share_access */
2102 create_disposition, /* create_disposition*/
2103 create_options, /* create_options */
2104 file_attributes, /* file_attributes */
2105 oplock_request, /* oplock_request */
2106 allocation_size, /* allocation_size */
2108 ea_list, /* ea_list */
2111 &fsp_data, /* fsp_data */
2114 if (!NT_STATUS_IS_OK(status)) {
2118 DEBUG(10, ("onefs_create_file: info=%d\n", info));
2121 * Setup private onefs_fsp_data. Currently the private data struct is
2122 * only used to store the oplock_callback_id so that when the file is
2123 * closed, the onefs_callback_record can be properly cleaned up in the
2124 * oplock_onefs sub-system.
2127 struct onefs_fsp_data *fsp_data_tmp = NULL;
2128 fsp_data_tmp = (struct onefs_fsp_data *)
2129 VFS_ADD_FSP_EXTENSION(handle, fsp, struct onefs_fsp_data,
2130 &destroy_onefs_fsp_data);
2132 if (fsp_data_tmp == NULL) {
2133 status = NT_STATUS_NO_MEMORY;
2137 *fsp_data_tmp = fsp_data;
2141 if (pinfo != NULL) {
2144 if (psbuf != NULL) {
2147 return NT_STATUS_OK;
2150 DEBUG(10, ("onefs_create_file: %s\n", nt_errstr(status)));
2153 close_file(req, fsp, ERROR_CLOSE);