2 * Unix SMB/CIFS implementation.
4 * This file began with some code from source3/smbd/open.c and has been
5 * modified it work with ifs_createfile.
7 * ifs_createfile is a CIFS-specific syscall for opening/files and
8 * directories. It adds support for:
9 * - Full in-kernel access checks using a windows access_mask
10 * - Cluster-coherent share mode locks
11 * - Cluster-coherent oplocks
13 * - Setting security descriptors at create time
14 * - Setting dos_attributes at create time
16 * Copyright (C) Andrew Tridgell 1992-1998
17 * Copyright (C) Jeremy Allison 2001-2004
18 * Copyright (C) Volker Lendecke 2005
19 * Copyright (C) Tim Prouty, 2008
21 * This program is free software; you can redistribute it and/or modify
22 * it under the terms of the GNU General Public License as published by
23 * the Free Software Foundation; either version 3 of the License, or
24 * (at your option) any later version.
26 * This program is distributed in the hope that it will be useful,
27 * but WITHOUT ANY WARRANTY; without even the implied warranty of
28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
29 * GNU General Public License for more details.
31 * You should have received a copy of the GNU General Public License
32 * along with this program; if not, see <http://www.gnu.org/licenses/>.
37 #include "onefs_config.h"
38 #include "oplock_onefs.h"
39 #include "smbd/globals.h"
41 extern const struct generic_mapping file_generic_mapping;
43 struct onefs_fsp_data {
44 uint64_t oplock_callback_id;
47 static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
48 struct smb_request *req,
51 uint32_t share_access,
52 uint32_t create_disposition,
53 uint32_t create_options,
54 uint32_t file_attributes,
55 uint32_t oplock_request,
56 uint64_t allocation_size,
57 struct security_descriptor *sd,
58 struct ea_list *ea_list,
59 files_struct **result,
61 struct onefs_fsp_data *fsp_data,
62 SMB_STRUCT_STAT *psbuf);
64 /****************************************************************************
66 ****************************************************************************/
68 static NTSTATUS onefs_open_file(files_struct *fsp,
69 connection_struct *conn,
70 struct smb_request *req,
71 const char *parent_dir,
74 SMB_STRUCT_STAT *psbuf,
78 uint32 open_access_mask,
82 uint32 create_options,
83 uint32_t new_dos_attributes,
84 struct security_descriptor *sd,
87 NTSTATUS status = NT_STATUS_OK;
88 int accmode = (flags & O_ACCMODE);
89 int local_flags = flags;
90 bool file_existed = VALID_STAT(*psbuf);
99 /* Check permissions */
102 * This code was changed after seeing a client open request
103 * containing the open mode of (DENY_WRITE/read-only) with
104 * the 'create if not exist' bit set. The previous code
105 * would fail to open the file read only on a read-only share
106 * as it was checking the flags parameter directly against O_RDONLY,
107 * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
111 if (!CAN_WRITE(conn)) {
112 /* It's a read-only share - fail if we wanted to write. */
113 if(accmode != O_RDONLY) {
114 DEBUG(3,("Permission denied opening %s\n", path));
115 return NT_STATUS_ACCESS_DENIED;
116 } else if(flags & O_CREAT) {
117 /* We don't want to write - but we must make sure that
118 O_CREAT doesn't create the file if we have write
119 access into the directory.
122 local_flags &= ~O_CREAT;
127 * This little piece of insanity is inspired by the
128 * fact that an NT client can open a file for O_RDONLY,
129 * but set the create disposition to FILE_EXISTS_TRUNCATE.
130 * If the client *can* write to the file, then it expects to
131 * truncate the file, even though it is opening for readonly.
132 * Quicken uses this stupid trick in backup file creation...
133 * Thanks *greatly* to "David W. Chapman Jr." <dwcjr@inethouston.net>
134 * for helping track this one down. It didn't bite us in 2.0.x
135 * as we always opened files read-write in that release. JRA.
138 if ((accmode == O_RDONLY) && ((flags & O_TRUNC) == O_TRUNC)) {
139 DEBUG(10,("onefs_open_file: truncate requested on read-only "
140 "open for file %s\n", path));
141 local_flags = (flags & ~O_ACCMODE)|O_RDWR;
144 #if defined(O_NONBLOCK) && defined(S_ISFIFO)
146 * We would block on opening a FIFO with no one else on the
147 * other end. Do what we used to do and add O_NONBLOCK to the
151 if (file_existed && S_ISFIFO(psbuf->st_mode)) {
152 local_flags |= O_NONBLOCK;
156 /* Don't create files with Microsoft wildcard characters. */
159 * wildcard characters are allowed in stream names
160 * only test the basefilename
162 wild = fsp->base_fsp->fsp_name;
166 if ((local_flags & O_CREAT) && !file_existed &&
169 * XXX: may need to remvoe this return...
171 * We dont think this check needs to exist. All it does is
172 * block creating files with Microsoft wildcards, which is
173 * fine if the creation originated from NFS or locally and
174 * then was copied via Samba.
176 DEBUG(1, ("onefs_open_file: creating file with wildcard: %s\n",
178 return NT_STATUS_OBJECT_NAME_INVALID;
181 /* Actually do the open */
185 * Never follow symlinks on a POSIX client. The
186 * client should be doing this.
189 if (fsp->posix_open || !lp_symlinks(SNUM(conn))) {
193 /* Stream handling */
194 if (is_ntfs_stream_name(path)) {
195 status = onefs_split_ntfs_stream_name(talloc_tos(), path,
198 /* It's a stream, so pass in the base_fd */
199 if ((conn->fs_capabilities & FILE_NAMED_STREAMS) && stream != NULL) {
200 SMB_ASSERT(fsp->base_fsp);
202 DEBUG(10,("Opening a stream: base=%s(%d), stream=%s\n",
203 base, fsp->base_fsp->fh->fd, stream));
205 base_fd = fsp->base_fsp->fh->fd;
208 fsp->fh->fd = onefs_sys_create_file(conn,
210 stream != NULL ? stream :
211 (base != NULL ? base : path),
224 if (fsp->fh->fd == -1) {
225 if (errno == EMFILE) {
226 static time_t last_warned = 0L;
228 if (time((time_t *) NULL) > last_warned) {
229 DEBUG(0, ("Too many open files, unable "
230 "to open more! smbd's max "
231 "open files = %d, also check "
232 "sysctl kern.maxfiles and "
233 "sysctl kern.maxfilesperproc\n",
234 lp_max_open_files()));
235 last_warned = time((time_t *) NULL);
239 status = map_nt_error_from_unix(errno);
240 DEBUG(3,("Error opening file %s (%s) (local_flags=%d) "
242 path, strerror(errno), local_flags, flags));
246 if ((local_flags & O_CREAT) && !file_existed) {
248 /* Inherit the ACL if required */
249 if (lp_inherit_perms(SNUM(conn))) {
250 inherit_access_posix_acl(conn, parent_dir, path,
254 /* Change the owner if required. */
255 if (lp_inherit_owner(SNUM(conn))) {
256 change_file_owner_to_parent(conn, parent_dir,
260 notify_fname(conn, NOTIFY_ACTION_ADDED,
261 FILE_NOTIFY_CHANGE_FILE_NAME, path);
267 if (fsp->fh->fd == -1) {
268 ret = SMB_VFS_STAT(conn, path, psbuf);
270 ret = SMB_VFS_FSTAT(fsp, psbuf);
271 /* If we have an fd, this stat should succeed. */
273 DEBUG(0,("Error doing fstat on open file %s "
274 "(%s)\n", path,strerror(errno) ));
278 /* For a non-io open, this stat failing means file not found. JRA */
280 status = map_nt_error_from_unix(errno);
287 * POSIX allows read-only opens of directories. We don't
288 * want to do this (we use a different code path for this)
289 * so catch a directory open and return an EISDIR. JRA.
292 if(S_ISDIR(psbuf->st_mode)) {
295 return NT_STATUS_FILE_IS_A_DIRECTORY;
298 fsp->mode = psbuf->st_mode;
299 fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf);
300 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
301 fsp->file_pid = req ? req->smbpid : 0;
302 fsp->can_lock = True;
303 fsp->can_read = (access_mask & (FILE_READ_DATA)) ? True : False;
304 if (!CAN_WRITE(conn)) {
305 fsp->can_write = False;
307 fsp->can_write = (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ?
310 fsp->print_file = False;
311 fsp->modified = False;
312 fsp->sent_oplock_break = NO_BREAK_SENT;
313 fsp->is_directory = False;
314 if (conn->aio_write_behind_list &&
315 is_in_path(path, conn->aio_write_behind_list, conn->case_sensitive)) {
316 fsp->aio_write_behind = True;
319 string_set(&fsp->fsp_name, path);
320 fsp->wcp = NULL; /* Write cache pointer. */
322 DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
323 conn->server_info->unix_name,
325 BOOLSTR(fsp->can_read), BOOLSTR(fsp->can_write),
326 conn->num_files_open));
332 /****************************************************************************
333 Handle the 1 second delay in returning a SHARING_VIOLATION error.
334 ****************************************************************************/
336 static void defer_open(struct share_mode_lock *lck,
337 struct timeval request_time,
338 struct timeval timeout,
339 struct smb_request *req,
340 struct deferred_open_record *state)
346 for (i=0; i<lck->num_share_modes; i++) {
347 struct share_mode_entry *e = &lck->share_modes[i];
349 if (!is_deferred_open_entry(e)) {
353 if (procid_is_me(&e->pid) && (e->op_mid == req->mid)) {
354 DEBUG(0, ("Trying to defer an already deferred "
355 "request: mid=%d, exiting\n", req->mid));
356 exit_server("attempt to defer a deferred request");
360 /* End paranoia check */
362 DEBUG(10,("defer_open_sharing_error: time [%u.%06u] adding deferred "
363 "open entry for mid %u\n",
364 (unsigned int)request_time.tv_sec,
365 (unsigned int)request_time.tv_usec,
366 (unsigned int)req->mid));
368 if (!push_deferred_smb_message(req, request_time, timeout,
369 (char *)state, sizeof(*state))) {
370 exit_server("push_deferred_smb_message failed");
372 add_deferred_open(lck, req->mid, request_time, state->id);
375 static void schedule_defer_open(struct share_mode_lock *lck,
376 struct timeval request_time,
377 struct smb_request *req)
379 struct deferred_open_record state;
381 /* This is a relative time, added to the absolute
382 request_time value to get the absolute timeout time.
383 Note that if this is the second or greater time we enter
384 this codepath for this particular request mid then
385 request_time is left as the absolute time of the *first*
386 time this request mid was processed. This is what allows
387 the request to eventually time out. */
389 struct timeval timeout;
391 /* Normally the smbd we asked should respond within
392 * OPLOCK_BREAK_TIMEOUT seconds regardless of whether
393 * the client did, give twice the timeout as a safety
394 * measure here in case the other smbd is stuck
398 * On OneFS, the kernel will always send an oplock_revoked message
399 * before this timeout is hit.
401 timeout = timeval_set(OPLOCK_BREAK_TIMEOUT*10, 0);
403 /* Nothing actually uses state.delayed_for_oplocks
404 but it's handy to differentiate in debug messages
405 between a 30 second delay due to oplock break, and
406 a 1 second delay for share mode conflicts. */
408 state.delayed_for_oplocks = True;
409 state.failed = false;
412 if (!request_timed_out(request_time, timeout)) {
413 defer_open(lck, request_time, timeout, req, &state);
417 /****************************************************************************
418 Open a file with a share mode. Passed in an already created files_struct.
419 ****************************************************************************/
420 NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
421 struct smb_request *req,
425 uint32 create_disposition,
426 uint32 create_options,
427 uint32 new_dos_attributes,
429 struct security_descriptor *sd,
432 struct onefs_fsp_data *fsp_data,
433 SMB_STRUCT_STAT *psbuf)
437 bool file_existed = VALID_STAT(*psbuf);
438 bool def_acl = False;
439 bool posix_open = False;
440 bool new_file_created = False;
441 bool clear_ads = False;
443 mode_t new_unx_mode = (mode_t)0;
444 mode_t unx_mode = (mode_t)0;
446 uint32 existing_dos_attributes = 0;
447 struct pending_message_list *pml = NULL;
448 struct timeval request_time = timeval_zero();
449 struct share_mode_lock *lck = NULL;
450 uint32 open_access_mask = access_mask;
456 uint64_t oplock_callback_id = 0;
457 uint32 createfile_attributes = 0;
463 * Printers are handled completely differently.
464 * Most of the passed parameters are ignored.
468 *pinfo = FILE_WAS_CREATED;
471 DEBUG(10, ("onefs_open_file_ntcreate: printer open fname=%s\n",
474 return print_fsp_open(req, conn, fname, req->vuid, fsp, psbuf);
477 if (!parent_dirname(talloc_tos(), fname, &parent_dir, &newname)) {
478 return NT_STATUS_NO_MEMORY;
481 if (new_dos_attributes & FILE_FLAG_POSIX_SEMANTICS) {
483 unx_mode = (mode_t)(new_dos_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
484 new_dos_attributes = 0;
486 /* We add aARCH to this as this mode is only used if the file is
488 unx_mode = unix_mode(conn, new_dos_attributes | aARCH, fname,
492 DEBUG(10,("onefs_open_file_ntcreate: fname=%s, dos_attrs=0x%x "
493 "access_mask=0x%x share_access=0x%x "
494 "create_disposition = 0x%x create_options=0x%x "
495 "unix mode=0%o oplock_request=0x%x\n",
496 fname, new_dos_attributes, access_mask, share_access,
497 create_disposition, create_options, unx_mode,
501 * Any non-stat-only open has the potential to contend oplocks, which
502 * means to avoid blocking in the kernel (which is unacceptable), the
503 * open must be deferred. In order to defer opens, req must not be
504 * NULL. The known cases of calling with a NULL req:
506 * 1. Open the base file of a stream: Always done stat-only
508 * 2. open_file_fchmod(), which is called from 3 places:
509 * A. try_chown: Posix acls only. Never called on onefs.
510 * B. set_ea_dos_attributes: Can't be called from onefs, because
511 * SMB_VFS_SETXATTR return ENOSYS.
512 * C. file_set_dos_mode: This would only happen if the "dos
513 * filemode" smb.conf parameter is set to yes. We ship with
514 * it off, but if a customer were to turn it on it would be
517 if (req == NULL && !is_stat_open(access_mask) && !is_ntfs_stream_name(fname)) {
518 smb_panic("NULL req on a non-stat-open!");
521 if ((req == NULL) && ((oplock_request & INTERNAL_OPEN_ONLY) == 0)) {
522 DEBUG(0, ("No smb request but not an internal only open!\n"));
523 return NT_STATUS_INTERNAL_ERROR;
527 * Only non-internal opens can be deferred at all
531 && ((pml = get_open_deferred_message(req->mid)) != NULL)) {
532 struct deferred_open_record *state =
533 (struct deferred_open_record *)pml->private_data.data;
535 /* Remember the absolute time of the original
536 request with this mid. We'll use it later to
537 see if this has timed out. */
539 request_time = pml->request_time;
541 /* Remove the deferred open entry under lock. */
542 lck = get_share_mode_lock(talloc_tos(), state->id, NULL, NULL,
545 DEBUG(0, ("could not get share mode lock\n"));
547 del_deferred_open_entry(lck, req->mid);
551 /* Ensure we don't reprocess this message. */
552 remove_deferred_open_smb_message(req->mid);
555 * When receiving a semlock_async_failure message, the
556 * deferred open will be marked as "failed". Returning
560 DEBUG(0, ("onefs_open_file_ntcreate: "
561 "semlock_async_failure detected!\n"));
562 return NT_STATUS_INTERNAL_ERROR;
566 status = check_name(conn, fname);
567 if (!NT_STATUS_IS_OK(status)) {
572 new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
574 existing_dos_attributes = dos_mode(conn, fname, psbuf);
578 /* Setup dos_attributes to be set by ifs_createfile */
579 if (lp_store_dos_attributes(SNUM(conn))) {
580 createfile_attributes = (new_dos_attributes | aARCH) &
581 ~(FILE_ATTRIBUTE_NONINDEXED | FILE_ATTRIBUTE_COMPRESSED);
584 /* Ignore oplock requests if oplocks are disabled. */
585 if (!lp_oplocks(SNUM(conn)) || global_client_failed_oplock_break ||
586 IS_VETO_OPLOCK_PATH(conn, fname)) {
587 /* Mask off everything except the private Samba bits. */
588 oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
591 /* this is for OS/2 long file names - say we don't support them */
592 if (!lp_posix_pathnames() && strstr(fname,".+,;=[].")) {
593 /* OS/2 Workplace shell fix may be main code stream in a later
595 DEBUG(5,("onefs_open_file_ntcreate: OS/2 long filenames are "
596 "not supported.\n"));
597 if (use_nt_status()) {
598 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
600 return NT_STATUS_DOS(ERRDOS, ERRcannotopen);
603 switch( create_disposition ) {
605 * Currently we're using FILE_SUPERSEDE as the same as
606 * FILE_OVERWRITE_IF but they really are
607 * different. FILE_SUPERSEDE deletes an existing file
608 * (requiring delete access) then recreates it.
612 * @todo: Clear all file attributes?
613 * http://www.osronline.com/article.cfm?article=302
614 * create if not exist, trunc if exist
616 * If file exists replace/overwrite. If file doesn't
619 flags2 |= (O_CREAT | O_TRUNC);
623 case FILE_OVERWRITE_IF:
624 /* If file exists replace/overwrite. If file doesn't
626 flags2 |= (O_CREAT | O_TRUNC);
631 /* If file exists open. If file doesn't exist error. */
633 DEBUG(5,("onefs_open_file_ntcreate: FILE_OPEN "
634 "requested for file %s and file "
635 "doesn't exist.\n", fname ));
637 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
642 /* If file exists overwrite. If file doesn't exist
645 DEBUG(5, ("onefs_open_file_ntcreate: "
646 "FILE_OVERWRITE requested for file "
647 "%s and file doesn't exist.\n",
650 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
657 /* If file exists error. If file doesn't exist
660 DEBUG(5, ("onefs_open_file_ntcreate: "
661 "FILE_CREATE requested for file %s "
662 "and file already exists.\n",
664 if (S_ISDIR(psbuf->st_mode)) {
669 return map_nt_error_from_unix(errno);
671 flags2 |= (O_CREAT|O_EXCL);
675 /* If file exists open. If file doesn't exist
681 return NT_STATUS_INVALID_PARAMETER;
684 /* Match attributes on file exists and overwrite. */
685 if (!posix_open && file_existed &&
686 ((create_disposition == FILE_OVERWRITE) ||
687 (create_disposition == FILE_OVERWRITE_IF))) {
688 if (!open_match_attributes(conn, fname,
689 existing_dos_attributes,
690 new_dos_attributes, psbuf->st_mode,
691 unx_mode, &new_unx_mode)) {
692 DEBUG(5, ("onefs_open_file_ntcreate: attributes "
693 "missmatch for file %s (%x %x) (0%o, 0%o)\n",
694 fname, existing_dos_attributes,
696 (unsigned int)psbuf->st_mode,
697 (unsigned int)unx_mode ));
699 return NT_STATUS_ACCESS_DENIED;
704 * OneFS understands MAXIMUM_ALLOWED_ACCESS, so only hack the
705 * access_mask, but leave the MAA for the actual open in
708 open_access_mask = access_mask;
709 if (open_access_mask & MAXIMUM_ALLOWED_ACCESS) {
710 access_mask |= FILE_GENERIC_ALL;
713 /* Convert GENERIC bits to specific bits. */
714 se_map_generic(&access_mask, &file_generic_mapping);
715 se_map_generic(&open_access_mask, &file_generic_mapping);
717 if ((flags2 & O_TRUNC) || (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE)) {
718 /* This will cause oplock breaks. */
719 open_access_mask |= FILE_WRITE_DATA;
722 DEBUG(10, ("onefs_open_file_ntcreate: fname=%s, after mapping "
723 "open_access_mask=%#x, access_mask=0x%x\n",
724 fname, open_access_mask, access_mask));
727 * Note that we ignore the append flag as append does not
728 * mean the same thing under DOS and Unix.
731 if ((access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ||
732 (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE)) {
735 * DENY_DOS opens are always underlying read-write on the
736 * file handle, no matter what the requested access mask
737 * says. Stock samba just sets the flags, but since
738 * ifs_createfile uses the access_mask, it must be updated as
739 * well. This allows BASE-DENY* to pass.
741 if (create_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) {
743 DEBUG(10,("onefs_open_file_ntcreate: deny_dos: "
744 "Adding O_RDWR to flags "
745 "(0x%x) and some READ bits to "
746 "open_access_mask (0x%x)\n",
747 flags, open_access_mask));
750 open_access_mask |= (FILE_READ_ATTRIBUTES |
751 FILE_READ_DATA | FILE_READ_EA | FILE_EXECUTE);
753 } else if (access_mask & (FILE_READ_ATTRIBUTES |
765 /* Currently we only look at FILE_WRITE_THROUGH for create options. */
767 if ((create_options & FILE_WRITE_THROUGH) &&
768 lp_strict_sync(SNUM(conn))) {
773 if (posix_open && (access_mask & FILE_APPEND_DATA)) {
777 if (!posix_open && !CAN_WRITE(conn)) {
779 * We should really return a permission denied error if either
780 * O_CREAT or O_TRUNC are set, but for compatibility with
781 * older versions of Samba we just AND them out.
783 flags2 &= ~(O_CREAT|O_TRUNC);
785 /* Deny DELETE_ACCESS explicitly if the share is read only. */
786 if (access_mask & DELETE_ACCESS) {
787 return map_nt_error_from_unix(EACCES);
791 /* Ensure we can't write on a read-only share or file. */
792 if (flags != O_RDONLY && file_existed &&
793 (!CAN_WRITE(conn) || IS_DOS_READONLY(existing_dos_attributes))) {
794 DEBUG(5, ("onefs_open_file_ntcreate: write access requested "
795 "for file %s on read only %s\n",
796 fname, !CAN_WRITE(conn) ? "share" : "file" ));
798 return NT_STATUS_ACCESS_DENIED;
801 DEBUG(10, ("fsp = %p\n", fsp));
803 fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf);
804 fsp->share_access = share_access;
805 fsp->fh->private_options = create_options;
806 fsp->access_mask = open_access_mask; /* We change this to the
807 * requested access_mask after
808 * the open is done. */
809 fsp->posix_open = posix_open;
811 /* Ensure no SAMBA_PRIVATE bits can be set. */
812 fsp->oplock_type = (oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK);
814 if (timeval_is_zero(&request_time)) {
815 request_time = fsp->open_time;
819 struct timespec old_write_time = get_mtimespec(psbuf);
820 id = vfs_file_id_from_sbuf(conn, psbuf);
822 lck = get_share_mode_lock(talloc_tos(), id,
824 fname, &old_write_time);
827 DEBUG(0, ("Could not get share mode lock\n"));
828 return NT_STATUS_SHARING_VIOLATION;
831 if (lck->delete_on_close) {
832 /* DELETE_PENDING is not deferred for a second */
834 return NT_STATUS_DELETE_PENDING;
838 SMB_ASSERT(!file_existed || (lck != NULL));
841 * Ensure we pay attention to default ACLs on directories. May be
842 * neccessary depending on ACL policies.
844 if ((flags2 & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
845 (def_acl = directory_has_default_acl(conn, parent_dir))) {
849 DEBUG(4,("calling onefs_open_file with flags=0x%X flags2=0x%X "
850 "mode=0%o, access_mask = 0x%x, open_access_mask = 0x%x\n",
851 (unsigned int)flags, (unsigned int)flags2,
852 (unsigned int)unx_mode, (unsigned int)access_mask,
853 (unsigned int)open_access_mask));
856 * Since the open is guaranteed to be stat only if req == NULL, a
857 * callback record is only needed if req != NULL.
860 SMB_ASSERT(fsp_data);
861 oplock_callback_id = onefs_oplock_wait_record(req->mid);
862 if (oplock_callback_id == 0) {
863 return NT_STATUS_NO_MEMORY;
867 * It is also already asserted it's either a stream or a
868 * stat-only open at this point.
870 SMB_ASSERT(fsp->oplock_type == NO_OPLOCK);
874 status = onefs_open_file(fsp,
889 createfile_attributes,
893 if (!NT_STATUS_IS_OK(status)) {
895 /* OneFS Oplock Handling */
896 if (errno == EINPROGRESS) {
900 struct deferred_open_record state;
901 struct timespec old_write_time;
903 old_write_time = get_mtimespec(psbuf);
905 DEBUG(3, ("Someone created file %s with an "
906 "oplock after we looked: Retrying\n",
909 * We hit the race that when we did the stat
910 * on the file it did not exist, and someone
911 * has created it in between the stat and the
912 * open_file() call. Just retry immediately.
914 id = vfs_file_id_from_sbuf(conn, psbuf);
915 if (!(lck = get_share_mode_lock(talloc_tos(),
916 id, conn->connectpath, fname,
921 DEBUG(0, ("onefs_open_file_ntcreate: "
922 "Could not get share mode "
923 "lock for %s\n", fname));
924 status = NT_STATUS_SHARING_VIOLATION;
925 goto cleanup_destroy;
928 state.delayed_for_oplocks = False;
932 defer_open(lck, request_time,
933 timeval_zero(), req, &state);
935 goto cleanup_destroy;
937 /* Waiting for an oplock */
938 DEBUG(5,("Async createfile because a client has an "
939 "oplock on %s\n", fname));
942 schedule_defer_open(lck, request_time, req);
946 /* Check for a sharing violation */
947 if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
948 uint32 can_access_mask;
949 bool can_access = True;
951 /* Check if this can be done with the deny_dos and fcb
954 /* Try to find dup fsp if possible. */
956 (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS|
957 NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) {
960 DEBUG(0, ("DOS open without an SMB "
962 status = NT_STATUS_INTERNAL_ERROR;
963 goto cleanup_destroy;
966 /* Use the client requested access mask here,
967 * not the one we open with. */
968 status = fcb_or_dos_open(req,
979 if (NT_STATUS_IS_OK(status)) {
981 *pinfo = FILE_WAS_OPENED;
983 status = NT_STATUS_OK;
989 * This next line is a subtlety we need for
990 * MS-Access. If a file open will fail due to share
991 * permissions and also for security (access) reasons,
992 * we need to return the access failed error, not the
993 * share error. We can't open the file due to kernel
994 * oplock deadlock (it's possible we failed above on
995 * the open_mode_check()) so use a userspace check.
998 if (flags & O_RDWR) {
999 can_access_mask = FILE_READ_DATA|FILE_WRITE_DATA;
1000 } else if (flags & O_WRONLY) {
1001 can_access_mask = FILE_WRITE_DATA;
1003 can_access_mask = FILE_READ_DATA;
1006 if (((can_access_mask & FILE_WRITE_DATA) && !CAN_WRITE(conn)) ||
1007 !can_access_file_data(conn,fname,psbuf,can_access_mask)) {
1012 * If we're returning a share violation, ensure we
1013 * cope with the braindead 1 second delay.
1015 if (!(oplock_request & INTERNAL_OPEN_ONLY) &&
1016 lp_defer_sharing_violations()) {
1017 struct timeval timeout;
1018 struct deferred_open_record state;
1021 /* this is a hack to speed up torture tests
1023 timeout_usecs = lp_parm_int(SNUM(conn),
1024 "smbd","sharedelay",
1025 SHARING_VIOLATION_USEC_WAIT);
1027 /* This is a relative time, added to the
1028 absolute request_time value to get the
1029 absolute timeout time. Note that if this
1030 is the second or greater time we enter this
1031 codepath for this particular request mid
1032 then request_time is left as the absolute
1033 time of the *first* time this request mid
1034 was processed. This is what allows the
1035 request to eventually time out. */
1037 timeout = timeval_set(0, timeout_usecs);
1039 /* Nothing actually uses
1040 state.delayed_for_oplocks but it's handy to
1041 differentiate in debug messages between a
1042 30 second delay due to oplock break, and a
1043 1 second delay for share mode conflicts. */
1045 state.delayed_for_oplocks = False;
1047 state.failed = false;
1050 && !request_timed_out(request_time,
1052 defer_open(lck, request_time, timeout,
1059 * We have detected a sharing violation here
1060 * so return the correct error code
1062 status = NT_STATUS_SHARING_VIOLATION;
1064 status = NT_STATUS_ACCESS_DENIED;
1067 goto cleanup_destroy;
1071 * Normal error, for example EACCES
1074 if (oplock_callback_id != 0) {
1075 destroy_onefs_callback_record(oplock_callback_id);
1082 fsp->oplock_type = granted_oplock;
1084 if (oplock_callback_id != 0) {
1085 onefs_set_oplock_callback(oplock_callback_id, fsp);
1086 fsp_data->oplock_callback_id = oplock_callback_id;
1088 SMB_ASSERT(fsp->oplock_type == NO_OPLOCK);
1091 if (!file_existed) {
1092 struct timespec old_write_time = get_mtimespec(psbuf);
1094 * Deal with the race condition where two smbd's detect the
1095 * file doesn't exist and do the create at the same time. One
1096 * of them will win and set a share mode, the other (ie. this
1097 * one) should check if the requested share mode for this
1098 * create is allowed.
1102 * Now the file exists and fsp is successfully opened,
1103 * fsp->dev and fsp->inode are valid and should replace the
1104 * dev=0,inode=0 from a non existent file. Spotted by
1105 * Nadav Danieli <nadavd@exanet.com>. JRA.
1110 lck = get_share_mode_lock(talloc_tos(), id,
1112 fname, &old_write_time);
1115 DEBUG(0, ("onefs_open_file_ntcreate: Could not get "
1116 "share mode lock for %s\n", fname));
1118 return NT_STATUS_SHARING_VIOLATION;
1121 if (lck->delete_on_close) {
1122 status = NT_STATUS_DELETE_PENDING;
1125 if (!NT_STATUS_IS_OK(status)) {
1126 struct deferred_open_record state;
1130 state.delayed_for_oplocks = False;
1133 /* Do it all over again immediately. In the second
1134 * round we will find that the file existed and handle
1135 * the DELETE_PENDING and FCB cases correctly. No need
1136 * to duplicate the code here. Essentially this is a
1137 * "goto top of this function", but don't tell
1141 defer_open(lck, request_time, timeval_zero(),
1149 * We exit this block with the share entry *locked*.....
1154 SMB_ASSERT(lck != NULL);
1156 /* Delete streams if create_disposition requires it */
1157 if (file_existed && clear_ads && !is_ntfs_stream_name(fname)) {
1158 status = delete_all_streams(conn, fname);
1159 if (!NT_STATUS_IS_OK(status)) {
1166 /* note that we ignore failure for the following. It is
1167 basically a hack for NFS, and NFS will never set one of
1168 these only read them. Nobody but Samba can ever set a deny
1169 mode and we have already checked our more authoritative
1170 locking database for permission to set this deny mode. If
1171 the kernel refuses the operations then the kernel is wrong.
1172 note that GPFS supports it as well - jmcd */
1174 if (fsp->fh->fd != -1) {
1175 ret_flock = SMB_VFS_KERNEL_FLOCK(fsp, share_access);
1176 if(ret_flock == -1 ){
1180 return NT_STATUS_SHARING_VIOLATION;
1185 * At this point onwards, we can guarentee that the share entry
1186 * is locked, whether we created the file or not, and that the
1187 * deny mode is compatible with all current opens.
1190 /* Record the options we were opened with. */
1191 fsp->share_access = share_access;
1192 fsp->fh->private_options = create_options;
1194 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
1196 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
1199 /* stat opens on existing files don't get oplocks. */
1200 if (is_stat_open(open_access_mask)) {
1201 fsp->oplock_type = NO_OPLOCK;
1204 if (!(flags2 & O_TRUNC)) {
1205 info = FILE_WAS_OPENED;
1207 info = FILE_WAS_OVERWRITTEN;
1210 info = FILE_WAS_CREATED;
1218 * Setup the oplock info in both the shared memory and
1222 if ((fsp->oplock_type != NO_OPLOCK) &&
1223 (fsp->oplock_type != FAKE_LEVEL_II_OPLOCK)) {
1224 if (!set_file_oplock(fsp, fsp->oplock_type)) {
1225 /* Could not get the kernel oplock */
1226 fsp->oplock_type = NO_OPLOCK;
1230 if (fsp->oplock_type == LEVEL_II_OPLOCK &&
1231 (!lp_level2_oplocks(SNUM(conn)) ||
1232 !(global_client_caps & CAP_LEVEL_II_OPLOCKS))) {
1234 DEBUG(5, ("Downgrading level2 oplock on open "
1235 "because level2 oplocks = off\n"));
1237 release_file_oplock(fsp);
1240 if (info == FILE_WAS_OVERWRITTEN || info == FILE_WAS_CREATED ||
1241 info == FILE_WAS_SUPERSEDED) {
1242 new_file_created = True;
1245 set_share_mode(lck, fsp, conn->server_info->utok.uid, 0,
1248 /* Handle strange delete on close create semantics. */
1249 if (create_options & FILE_DELETE_ON_CLOSE) {
1250 status = can_set_delete_on_close(fsp, True, new_dos_attributes);
1252 if (!NT_STATUS_IS_OK(status)) {
1253 /* Remember to delete the mode we just added. */
1254 del_share_mode(lck, fsp);
1259 /* Note that here we set the *inital* delete on close flag,
1260 not the regular one. The magic gets handled in close. */
1261 fsp->initial_delete_on_close = True;
1265 * Take care of inherited ACLs on created files - if default ACL not
1267 * May be necessary depending on acl policies.
1269 if (!posix_open && !file_existed && !def_acl && !(VALID_STAT(*psbuf)
1270 && (psbuf->st_flags & SF_HASNTFSACL))) {
1272 int saved_errno = errno; /* We might get ENOSYS in the next
1275 if (SMB_VFS_FCHMOD_ACL(fsp, unx_mode) == -1 &&
1277 errno = saved_errno; /* Ignore ENOSYS */
1280 } else if (new_unx_mode) {
1284 /* Attributes need changing. File already existed. */
1287 int saved_errno = errno; /* We might get ENOSYS in the
1289 ret = SMB_VFS_FCHMOD_ACL(fsp, new_unx_mode);
1291 if (ret == -1 && errno == ENOSYS) {
1292 errno = saved_errno; /* Ignore ENOSYS */
1294 DEBUG(5, ("onefs_open_file_ntcreate: reset "
1295 "attributes of file %s to 0%o\n",
1296 fname, (unsigned int)new_unx_mode));
1297 ret = 0; /* Don't do the fchmod below. */
1302 (SMB_VFS_FCHMOD(fsp, new_unx_mode) == -1))
1303 DEBUG(5, ("onefs_open_file_ntcreate: failed to reset "
1304 "attributes of file %s to 0%o\n",
1305 fname, (unsigned int)new_unx_mode));
1308 /* If this is a successful open, we must remove any deferred open
1311 del_deferred_open_entry(lck, req->mid);
1315 return NT_STATUS_OK;
1319 /****************************************************************************
1320 Open a directory from an NT SMB call.
1321 ****************************************************************************/
1322 static NTSTATUS onefs_open_directory(connection_struct *conn,
1323 struct smb_request *req,
1326 uint32 share_access,
1327 uint32 create_disposition,
1328 uint32 create_options,
1329 uint32 file_attributes,
1330 struct security_descriptor *sd,
1331 files_struct **result,
1333 SMB_STRUCT_STAT *psbuf)
1335 files_struct *fsp = NULL;
1336 struct share_mode_lock *lck = NULL;
1338 struct timespec mtimespec;
1341 const char *dirname;
1342 bool posix_open = false;
1343 uint32 create_flags = 0;
1344 uint32 mode = lp_dir_mask(SNUM(conn));
1346 DEBUG(5, ("onefs_open_directory: opening directory %s, "
1347 "access_mask = 0x%x, "
1348 "share_access = 0x%x create_options = 0x%x, "
1349 "create_disposition = 0x%x, file_attributes = 0x%x\n",
1350 fname, (unsigned int)access_mask, (unsigned int)share_access,
1351 (unsigned int)create_options, (unsigned int)create_disposition,
1352 (unsigned int)file_attributes));
1354 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
1355 (conn->fs_capabilities & FILE_NAMED_STREAMS) &&
1356 is_ntfs_stream_name(fname)) {
1357 DEBUG(2, ("onefs_open_directory: %s is a stream name!\n", fname));
1358 return NT_STATUS_NOT_A_DIRECTORY;
1361 switch (create_disposition) {
1363 /* If directory exists open. If directory doesn't
1366 info = FILE_WAS_OPENED;
1369 /* If directory exists error. If directory doesn't
1371 create_flags = O_CREAT | O_EXCL;
1372 info = FILE_WAS_CREATED;
1375 /* If directory exists open. If directory doesn't
1378 /* Note: in order to return whether the directory was
1379 * opened or created, we first try to open and then try
1382 info = FILE_WAS_OPENED;
1384 case FILE_SUPERSEDE:
1385 case FILE_OVERWRITE:
1386 case FILE_OVERWRITE_IF:
1388 DEBUG(5, ("onefs_open_directory: invalid "
1389 "create_disposition 0x%x for directory %s\n",
1390 (unsigned int)create_disposition, fname));
1391 return NT_STATUS_INVALID_PARAMETER;
1395 * Check for write access to the share. Done in mkdir_internal() in
1398 if (!CAN_WRITE(conn) && (create_flags & O_CREAT)) {
1399 return NT_STATUS_ACCESS_DENIED;
1402 /* Get parent dirname */
1403 if (!parent_dirname(talloc_tos(), fname, &parent_dir, &dirname)) {
1404 return NT_STATUS_NO_MEMORY;
1407 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
1409 mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
1410 file_attributes = 0;
1412 mode = unix_mode(conn, aDIR, fname, parent_dir);
1416 * The NONINDEXED and COMPRESSED bits seem to always be cleared on
1417 * directories, no matter if you specify that they should be set.
1420 ~(FILE_ATTRIBUTE_NONINDEXED | FILE_ATTRIBUTE_COMPRESSED);
1422 status = file_new(req, conn, &fsp);
1423 if(!NT_STATUS_IS_OK(status)) {
1428 * Actual open with retry magic to handle FILE_OPEN_IF which is
1429 * unique because the kernel won't tell us if the file was opened or
1433 fsp->fh->fd = onefs_sys_create_file(conn,
1440 create_flags | O_DIRECTORY,
1448 if (fsp->fh->fd == -1) {
1449 DEBUG(3, ("Error opening %s. Errno=%d (%s).\n", fname, errno,
1451 SMB_ASSERT(errno != EINPROGRESS);
1453 if (create_disposition == FILE_OPEN_IF) {
1454 if (errno == ENOENT) {
1455 /* Try again, creating it this time. */
1456 create_flags = O_CREAT | O_EXCL;
1457 info = FILE_WAS_CREATED;
1459 } else if (errno == EEXIST) {
1460 /* Uggh. Try again again. */
1462 info = FILE_WAS_OPENED;
1467 /* Error cases below: */
1468 file_free(req, fsp);
1470 if ((errno == ENOENT) && (create_disposition == FILE_OPEN)) {
1471 DEBUG(5,("onefs_open_directory: FILE_OPEN requested "
1472 "for directory %s and it doesn't "
1473 "exist.\n", fname ));
1474 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1475 } else if ((errno == EEXIST) &&
1476 (create_disposition == FILE_CREATE)) {
1477 DEBUG(5,("onefs_open_directory: FILE_CREATE "
1478 "requested for directory %s and it "
1479 "already exists.\n", fname ));
1480 return NT_STATUS_OBJECT_NAME_COLLISION;
1481 } else if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
1482 /* Catch sharing violations. */
1483 return NT_STATUS_SHARING_VIOLATION;
1486 return map_nt_error_from_unix(errno);
1489 if (info == FILE_WAS_CREATED) {
1491 /* Pulled from mkdir_internal() */
1492 if (SMB_VFS_LSTAT(conn, fname, psbuf) == -1) {
1493 DEBUG(2, ("Could not stat directory '%s' just "
1494 "created: %s\n",fname, strerror(errno)));
1495 return map_nt_error_from_unix(errno);
1498 if (!S_ISDIR(psbuf->st_mode)) {
1499 DEBUG(0, ("Directory just '%s' created is not a "
1500 "directory\n", fname));
1501 return NT_STATUS_ACCESS_DENIED;
1506 * Check if high bits should have been set, then (if
1507 * bits are missing): add them. Consider bits
1508 * automagically set by UNIX, i.e. SGID bit from
1511 if (mode & ~(S_IRWXU|S_IRWXG|S_IRWXO) &&
1512 (mode & ~psbuf->st_mode)) {
1513 SMB_VFS_CHMOD(conn, fname, (psbuf->st_mode |
1514 (mode & ~psbuf->st_mode)));
1518 /* Change the owner if required. */
1519 if (lp_inherit_owner(SNUM(conn))) {
1520 change_dir_owner_to_parent(conn, parent_dir, fname,
1524 notify_fname(conn, NOTIFY_ACTION_ADDED,
1525 FILE_NOTIFY_CHANGE_DIR_NAME, fname);
1528 /* Stat the fd for Samba bookkeeping. */
1529 if(SMB_VFS_FSTAT(fsp, psbuf) != 0) {
1531 file_free(req, fsp);
1532 return map_nt_error_from_unix(errno);
1535 /* Setup the files_struct for it. */
1536 fsp->mode = psbuf->st_mode;
1537 fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf);
1538 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
1539 fsp->file_pid = req ? req->smbpid : 0;
1540 fsp->can_lock = False;
1541 fsp->can_read = False;
1542 fsp->can_write = False;
1544 fsp->share_access = share_access;
1545 fsp->fh->private_options = create_options;
1547 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
1549 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
1550 fsp->print_file = False;
1551 fsp->modified = False;
1552 fsp->oplock_type = NO_OPLOCK;
1553 fsp->sent_oplock_break = NO_BREAK_SENT;
1554 fsp->is_directory = True;
1555 fsp->posix_open = posix_open;
1557 string_set(&fsp->fsp_name,fname);
1559 mtimespec = get_mtimespec(psbuf);
1562 * Still set the samba share mode lock for correct delete-on-close
1563 * semantics and to make smbstatus more useful.
1565 lck = get_share_mode_lock(talloc_tos(), fsp->file_id,
1570 DEBUG(0, ("onefs_open_directory: Could not get share mode "
1571 "lock for %s\n", fname));
1573 file_free(req, fsp);
1574 return NT_STATUS_SHARING_VIOLATION;
1577 if (lck->delete_on_close) {
1580 file_free(req, fsp);
1581 return NT_STATUS_DELETE_PENDING;
1584 set_share_mode(lck, fsp, conn->server_info->utok.uid, 0, NO_OPLOCK);
1587 * For directories the delete on close bit at open time seems
1588 * always to be honored on close... See test 19 in Samba4 BASE-DELETE.
1590 if (create_options & FILE_DELETE_ON_CLOSE) {
1591 status = can_set_delete_on_close(fsp, True, 0);
1592 if (!NT_STATUS_IS_OK(status) &&
1593 !NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
1596 file_free(req, fsp);
1600 if (NT_STATUS_IS_OK(status)) {
1601 /* Note that here we set the *inital* delete on close flag,
1602 not the regular one. The magic gets handled in close. */
1603 fsp->initial_delete_on_close = True;
1614 return NT_STATUS_OK;
1618 * Wrapper around onefs_open_file_ntcreate and onefs_open_directory.
1620 static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
1621 struct smb_request *req,
1623 uint32_t access_mask,
1624 uint32_t share_access,
1625 uint32_t create_disposition,
1626 uint32_t create_options,
1627 uint32_t file_attributes,
1628 uint32_t oplock_request,
1629 uint64_t allocation_size,
1630 struct security_descriptor *sd,
1631 struct ea_list *ea_list,
1632 files_struct **result,
1634 struct onefs_fsp_data *fsp_data,
1635 SMB_STRUCT_STAT *psbuf)
1637 SMB_STRUCT_STAT sbuf;
1638 int info = FILE_WAS_OPENED;
1639 files_struct *base_fsp = NULL;
1640 files_struct *fsp = NULL;
1643 DEBUG(10,("onefs_create_file_unixpath: access_mask = 0x%x "
1644 "file_attributes = 0x%x, share_access = 0x%x, "
1645 "create_disposition = 0x%x create_options = 0x%x "
1646 "oplock_request = 0x%x ea_list = 0x%p, sd = 0x%p, "
1648 (unsigned int)access_mask,
1649 (unsigned int)file_attributes,
1650 (unsigned int)share_access,
1651 (unsigned int)create_disposition,
1652 (unsigned int)create_options,
1653 (unsigned int)oplock_request,
1654 ea_list, sd, fname));
1656 if (create_options & FILE_OPEN_BY_FILE_ID) {
1657 status = NT_STATUS_NOT_SUPPORTED;
1661 if (create_options & NTCREATEX_OPTIONS_INVALID_PARAM_MASK) {
1662 status = NT_STATUS_INVALID_PARAMETER;
1667 SMB_ASSERT((oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK) ==
1669 oplock_request |= INTERNAL_OPEN_ONLY;
1672 if (psbuf != NULL) {
1676 if (SMB_VFS_STAT(conn, fname, &sbuf) == -1) {
1677 SET_STAT_INVALID(sbuf);
1681 if (lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE,
1682 PARM_IGNORE_SACLS, PARM_IGNORE_SACLS_DEFAULT)) {
1683 access_mask &= ~SYSTEM_SECURITY_ACCESS;
1686 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
1687 && (access_mask & DELETE_ACCESS)
1688 && !is_ntfs_stream_name(fname)) {
1690 * We can't open a file with DELETE access if any of the
1691 * streams is open without FILE_SHARE_DELETE
1693 status = open_streams_for_delete(conn, fname);
1695 if (!NT_STATUS_IS_OK(status)) {
1700 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
1701 && is_ntfs_stream_name(fname)) {
1703 uint32 base_create_disposition;
1705 if (create_options & FILE_DIRECTORY_FILE) {
1706 status = NT_STATUS_NOT_A_DIRECTORY;
1710 status = onefs_split_ntfs_stream_name(talloc_tos(), fname,
1712 if (!NT_STATUS_IS_OK(status)) {
1713 DEBUG(10, ("onefs_create_file_unixpath: "
1714 "split_ntfs_stream_name failed: %s\n",
1715 nt_errstr(status)));
1719 SMB_ASSERT(!is_ntfs_stream_name(base)); /* paranoia.. */
1721 switch (create_disposition) {
1723 base_create_disposition = FILE_OPEN;
1726 base_create_disposition = FILE_OPEN_IF;
1730 status = onefs_create_file_unixpath(
1734 SYNCHRONIZE_ACCESS, /* access_mask */
1737 FILE_SHARE_DELETE), /* share_access */
1738 base_create_disposition, /* create_disposition*/
1739 0, /* create_options */
1740 file_attributes, /* file_attributes */
1741 NO_OPLOCK, /* oplock_request */
1742 0, /* allocation_size */
1745 &base_fsp, /* result */
1747 NULL, /* fsp_data */
1750 if (!NT_STATUS_IS_OK(status)) {
1751 DEBUG(10, ("onefs_create_file_unixpath for base %s "
1752 "failed: %s\n", base, nt_errstr(status)));
1757 * Testing against windows xp/2003/vista shows that oplocks
1758 * can actually be requested and granted on streams (see the
1759 * RAW-OPLOCK-STREAM1 smbtorture test).
1761 if ((oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK) !=
1763 DEBUG(5, ("Oplock(%d) being requested on a stream! "
1764 "Ignoring oplock request: fname=%s\n",
1765 oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK,
1767 /* Request NO_OPLOCK instead. */
1768 oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
1772 /* Covert generic bits in the security descriptor. */
1774 security_acl_map_generic(sd->dacl, &file_generic_mapping);
1775 security_acl_map_generic(sd->sacl, &file_generic_mapping);
1779 * If it's a request for a directory open, deal with it separately.
1782 if (create_options & FILE_DIRECTORY_FILE) {
1784 if (create_options & FILE_NON_DIRECTORY_FILE) {
1785 status = NT_STATUS_INVALID_PARAMETER;
1789 /* Can't open a temp directory. IFS kit test. */
1790 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
1791 (file_attributes & FILE_ATTRIBUTE_TEMPORARY)) {
1792 status = NT_STATUS_INVALID_PARAMETER;
1797 * We will get a create directory here if the Win32
1798 * app specified a security descriptor in the
1799 * CreateDirectory() call.
1802 status = onefs_open_directory(
1806 access_mask, /* access_mask */
1807 share_access, /* share_access */
1808 create_disposition, /* create_disposition*/
1809 create_options, /* create_options */
1810 file_attributes, /* file_attributes */
1818 * Ordinary file case.
1821 status = file_new(req, conn, &fsp);
1822 if(!NT_STATUS_IS_OK(status)) {
1827 * We're opening the stream element of a base_fsp
1828 * we already opened. Set up the base_fsp pointer.
1831 fsp->base_fsp = base_fsp;
1834 status = onefs_open_file_ntcreate(
1838 access_mask, /* access_mask */
1839 share_access, /* share_access */
1840 create_disposition, /* create_disposition*/
1841 create_options, /* create_options */
1842 file_attributes, /* file_attributes */
1843 oplock_request, /* oplock_request */
1847 fsp_data, /* fsp_data */
1850 if(!NT_STATUS_IS_OK(status)) {
1851 file_free(req, fsp);
1855 if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
1857 /* A stream open never opens a directory */
1860 status = NT_STATUS_FILE_IS_A_DIRECTORY;
1865 * Fail the open if it was explicitly a non-directory
1869 if (create_options & FILE_NON_DIRECTORY_FILE) {
1870 status = NT_STATUS_FILE_IS_A_DIRECTORY;
1874 create_options |= FILE_DIRECTORY_FILE;
1876 status = onefs_open_directory(
1880 access_mask, /* access_mask */
1881 share_access, /* share_access */
1882 create_disposition, /* create_disposition*/
1883 create_options, /* create_options */
1884 file_attributes, /* file_attributes */
1892 if (!NT_STATUS_IS_OK(status)) {
1896 fsp->base_fsp = base_fsp;
1900 if ((ea_list != NULL) && (info == FILE_WAS_CREATED)) {
1901 status = set_ea(conn, fsp, fname, ea_list);
1902 if (!NT_STATUS_IS_OK(status)) {
1907 if (!fsp->is_directory && S_ISDIR(sbuf.st_mode)) {
1908 status = NT_STATUS_ACCESS_DENIED;
1912 /* Save the requested allocation size. */
1913 if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
1915 && (allocation_size > sbuf.st_size)) {
1916 fsp->initial_allocation_size = smb_roundup(
1917 fsp->conn, allocation_size);
1918 if (fsp->is_directory) {
1919 /* Can't set allocation size on a directory. */
1920 status = NT_STATUS_ACCESS_DENIED;
1923 if (vfs_allocate_file_space(
1924 fsp, fsp->initial_allocation_size) == -1) {
1925 status = NT_STATUS_DISK_FULL;
1929 fsp->initial_allocation_size = smb_roundup(
1930 fsp->conn, (uint64_t)sbuf.st_size);
1934 DEBUG(10, ("onefs_create_file_unixpath: info=%d\n", info));
1937 if (pinfo != NULL) {
1940 if (psbuf != NULL) {
1941 if ((fsp->fh == NULL) || (fsp->fh->fd == -1)) {
1945 SMB_VFS_FSTAT(fsp, psbuf);
1948 return NT_STATUS_OK;
1951 DEBUG(10, ("onefs_create_file_unixpath: %s\n", nt_errstr(status)));
1954 if (base_fsp && fsp->base_fsp == base_fsp) {
1956 * The close_file below will close
1961 close_file(req, fsp, ERROR_CLOSE);
1964 if (base_fsp != NULL) {
1965 close_file(req, base_fsp, ERROR_CLOSE);
1971 static void destroy_onefs_fsp_data(void *p_data)
1973 struct onefs_fsp_data *fsp_data = (struct onefs_fsp_data *)p_data;
1975 destroy_onefs_callback_record(fsp_data->oplock_callback_id);
1979 * SMB_VFS_CREATE_FILE interface to onefs.
1981 NTSTATUS onefs_create_file(vfs_handle_struct *handle,
1982 struct smb_request *req,
1983 uint16_t root_dir_fid,
1985 uint32_t create_file_flags,
1986 uint32_t access_mask,
1987 uint32_t share_access,
1988 uint32_t create_disposition,
1989 uint32_t create_options,
1990 uint32_t file_attributes,
1991 uint32_t oplock_request,
1992 uint64_t allocation_size,
1993 struct security_descriptor *sd,
1994 struct ea_list *ea_list,
1995 files_struct **result,
1997 SMB_STRUCT_STAT *psbuf)
1999 connection_struct *conn = handle->conn;
2000 struct case_semantics_state *case_state = NULL;
2001 struct onefs_fsp_data fsp_data = {};
2002 SMB_STRUCT_STAT sbuf;
2003 int info = FILE_WAS_OPENED;
2004 files_struct *fsp = NULL;
2007 DEBUG(10,("onefs_create_file: access_mask = 0x%x "
2008 "file_attributes = 0x%x, share_access = 0x%x, "
2009 "create_disposition = 0x%x create_options = 0x%x "
2010 "oplock_request = 0x%x "
2011 "root_dir_fid = 0x%x, ea_list = 0x%p, sd = 0x%p, "
2012 "create_file_flags = 0x%x, fname = %s\n",
2013 (unsigned int)access_mask,
2014 (unsigned int)file_attributes,
2015 (unsigned int)share_access,
2016 (unsigned int)create_disposition,
2017 (unsigned int)create_options,
2018 (unsigned int)oplock_request,
2019 (unsigned int)root_dir_fid,
2020 ea_list, sd, create_file_flags, fname));
2022 /* Get the file name if root_dir_fid was specified. */
2023 if (root_dir_fid != 0) {
2026 status = get_relative_fid_filename(conn, req, root_dir_fid,
2028 if (!NT_STATUS_IS_OK(status)) {
2035 /* Resolve the file name if this was a DFS pathname. */
2036 if ((req != NULL) && (req->flags2 & FLAGS2_DFS_PATHNAMES)) {
2037 char *resolved_fname;
2039 status = resolve_dfspath(talloc_tos(), conn, true, fname,
2042 if (!NT_STATUS_IS_OK(status)) {
2044 * For PATH_NOT_COVERED we had
2045 * reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
2046 * ERRSRV, ERRbadpath);
2047 * Need to fix in callers
2051 fname = resolved_fname;
2054 /* Check if POSIX semantics are wanted. */
2055 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
2056 case_state = set_posix_case_semantics(talloc_tos(), conn);
2059 /* Convert dos path to unix path if it hasn't already been done. */
2060 if (create_file_flags & CFF_DOS_PATH) {
2061 char *converted_fname;
2063 SET_STAT_INVALID(sbuf);
2065 status = unix_convert(talloc_tos(), conn, fname, False,
2066 &converted_fname, NULL, &sbuf);
2067 if (!NT_STATUS_IS_OK(status)) {
2070 fname = converted_fname;
2072 if (psbuf != NULL) {
2075 if (SMB_VFS_STAT(conn, fname, &sbuf) == -1) {
2076 SET_STAT_INVALID(sbuf);
2082 TALLOC_FREE(case_state);
2084 /* All file access must go through check_name() */
2085 status = check_name(conn, fname);
2086 if (!NT_STATUS_IS_OK(status)) {
2090 status = onefs_create_file_unixpath(
2094 access_mask, /* access_mask */
2095 share_access, /* share_access */
2096 create_disposition, /* create_disposition*/
2097 create_options, /* create_options */
2098 file_attributes, /* file_attributes */
2099 oplock_request, /* oplock_request */
2100 allocation_size, /* allocation_size */
2102 ea_list, /* ea_list */
2105 &fsp_data, /* fsp_data */
2108 if (!NT_STATUS_IS_OK(status)) {
2112 DEBUG(10, ("onefs_create_file: info=%d\n", info));
2115 * Setup private onefs_fsp_data. Currently the private data struct is
2116 * only used to store the oplock_callback_id so that when the file is
2117 * closed, the onefs_callback_record can be properly cleaned up in the
2118 * oplock_onefs sub-system.
2121 struct onefs_fsp_data *fsp_data_tmp = NULL;
2122 fsp_data_tmp = (struct onefs_fsp_data *)
2123 VFS_ADD_FSP_EXTENSION(handle, fsp, struct onefs_fsp_data,
2124 &destroy_onefs_fsp_data);
2126 if (fsp_data_tmp == NULL) {
2127 status = NT_STATUS_NO_MEMORY;
2131 *fsp_data_tmp = fsp_data;
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);