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,
49 struct smb_filename *smb_fname,
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);
63 /****************************************************************************
65 ****************************************************************************/
67 static NTSTATUS onefs_open_file(files_struct *fsp,
68 connection_struct *conn,
69 struct smb_request *req,
70 const char *parent_dir,
71 struct smb_filename *smb_fname,
75 uint32 open_access_mask,
79 uint32 create_options,
80 uint32_t new_dos_attributes,
81 struct security_descriptor *sd,
85 struct smb_filename *smb_fname_onefs = NULL;
86 NTSTATUS status = NT_STATUS_OK;
87 int accmode = (flags & O_ACCMODE);
88 int local_flags = flags;
89 bool file_existed = VALID_STAT(smb_fname->st);
96 /* Check permissions */
99 * This code was changed after seeing a client open request
100 * containing the open mode of (DENY_WRITE/read-only) with
101 * the 'create if not exist' bit set. The previous code
102 * would fail to open the file read only on a read-only share
103 * as it was checking the flags parameter directly against O_RDONLY,
104 * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
108 if (!CAN_WRITE(conn)) {
109 /* It's a read-only share - fail if we wanted to write. */
110 if(accmode != O_RDONLY) {
111 DEBUG(3, ("Permission denied opening %s\n",
112 smb_fname_str_dbg(smb_fname)));
113 return NT_STATUS_ACCESS_DENIED;
114 } else if(flags & O_CREAT) {
115 /* We don't want to write - but we must make sure that
116 O_CREAT doesn't create the file if we have write
117 access into the directory.
120 local_flags &= ~O_CREAT;
125 * This little piece of insanity is inspired by the
126 * fact that an NT client can open a file for O_RDONLY,
127 * but set the create disposition to FILE_EXISTS_TRUNCATE.
128 * If the client *can* write to the file, then it expects to
129 * truncate the file, even though it is opening for readonly.
130 * Quicken uses this stupid trick in backup file creation...
131 * Thanks *greatly* to "David W. Chapman Jr." <dwcjr@inethouston.net>
132 * for helping track this one down. It didn't bite us in 2.0.x
133 * as we always opened files read-write in that release. JRA.
136 if ((accmode == O_RDONLY) && ((flags & O_TRUNC) == O_TRUNC)) {
137 DEBUG(10,("onefs_open_file: truncate requested on read-only "
138 "open for file %s\n", smb_fname_str_dbg(smb_fname)));
139 local_flags = (flags & ~O_ACCMODE)|O_RDWR;
142 #if defined(O_NONBLOCK) && defined(S_ISFIFO)
144 * We would block on opening a FIFO with no one else on the
145 * other end. Do what we used to do and add O_NONBLOCK to the
149 if (file_existed && S_ISFIFO(smb_fname->st.st_ex_mode)) {
150 local_flags |= O_NONBLOCK;
154 /* Don't create files with Microsoft wildcard characters. */
157 * wildcard characters are allowed in stream names
158 * only test the basefilename
160 wild = fsp->base_fsp->fsp_name;
162 wild = smb_fname->base_name;
164 if ((local_flags & O_CREAT) && !file_existed &&
167 * XXX: may need to remvoe this return...
169 * We dont think this check needs to exist. All it does is
170 * block creating files with Microsoft wildcards, which is
171 * fine if the creation originated from NFS or locally and
172 * then was copied via Samba.
174 DEBUG(1, ("onefs_open_file: creating file with wildcard: %s\n",
175 smb_fname_str_dbg(smb_fname)));
176 return NT_STATUS_OBJECT_NAME_INVALID;
179 /* Actually do the open */
183 * Never follow symlinks on a POSIX client. The
184 * client should be doing this.
187 if (fsp->posix_open || !lp_symlinks(SNUM(conn))) {
191 /* Setup a onefs-style smb_fname struct. */
192 status = onefs_stream_prep_smb_fname(talloc_tos(), smb_fname,
194 if (!NT_STATUS_IS_OK(status)) {
198 /* If it's a stream pass in the base_fd */
199 if ((conn->fs_capabilities & FILE_NAMED_STREAMS) &&
200 is_ntfs_stream_smb_fname(smb_fname_onefs)) {
201 SMB_ASSERT(fsp->base_fsp);
203 DEBUG(10, ("Opening a stream: base=%s(%d), stream=%s\n",
204 smb_fname_onefs->base_name, fsp->base_fsp->fh->fd,
205 smb_fname_onefs->stream_name));
207 base_fd = fsp->base_fsp->fh->fd;
210 fsp->fh->fd = onefs_sys_create_file(conn,
212 smb_fname_onefs->stream_name != NULL ?
213 smb_fname_onefs->stream_name :
214 smb_fname_onefs->base_name,
226 TALLOC_FREE(smb_fname_onefs);
228 if (fsp->fh->fd == -1) {
229 if (errno == EMFILE) {
230 static time_t last_warned = 0L;
232 if (time((time_t *) NULL) > last_warned) {
233 DEBUG(0, ("Too many open files, unable "
234 "to open more! smbd's max "
235 "open files = %d, also check "
236 "sysctl kern.maxfiles and "
237 "sysctl kern.maxfilesperproc\n",
238 lp_max_open_files()));
239 last_warned = time((time_t *) NULL);
243 status = map_nt_error_from_unix(errno);
244 DEBUG(3, ("Error opening file %s (%s) (local_flags=%d) "
245 "(flags=%d)\n", smb_fname_str_dbg(smb_fname),
246 strerror(errno), local_flags, flags));
250 if ((local_flags & O_CREAT) && !file_existed) {
252 /* Inherit the ACL if required */
253 if (lp_inherit_perms(SNUM(conn))) {
254 inherit_access_posix_acl(conn, parent_dir,
255 smb_fname->base_name, unx_mode);
258 /* Change the owner if required. */
259 if (lp_inherit_owner(SNUM(conn))) {
260 change_file_owner_to_parent(conn, parent_dir,
264 notify_fname(conn, NOTIFY_ACTION_ADDED,
265 FILE_NOTIFY_CHANGE_FILE_NAME, smb_fname->base_name);
271 if (fsp->fh->fd == -1) {
272 ret = SMB_VFS_STAT(conn, smb_fname);
274 ret = SMB_VFS_FSTAT(fsp, &smb_fname->st);
275 /* If we have an fd, this stat should succeed. */
277 DEBUG(0, ("Error doing fstat on open file %s "
279 smb_fname_str_dbg(smb_fname),
284 /* For a non-io open, this stat failing means file not found. JRA */
286 status = map_nt_error_from_unix(errno);
293 * POSIX allows read-only opens of directories. We don't
294 * want to do this (we use a different code path for this)
295 * so catch a directory open and return an EISDIR. JRA.
298 if(S_ISDIR(smb_fname->st.st_ex_mode)) {
301 return NT_STATUS_FILE_IS_A_DIRECTORY;
304 fsp->mode = smb_fname->st.st_ex_mode;
305 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
306 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
307 fsp->file_pid = req ? req->smbpid : 0;
308 fsp->can_lock = True;
309 fsp->can_read = (access_mask & (FILE_READ_DATA)) ? True : False;
310 if (!CAN_WRITE(conn)) {
311 fsp->can_write = False;
313 fsp->can_write = (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ?
316 fsp->print_file = False;
317 fsp->modified = False;
318 fsp->sent_oplock_break = NO_BREAK_SENT;
319 fsp->is_directory = False;
320 if (conn->aio_write_behind_list &&
321 is_in_path(smb_fname->base_name, conn->aio_write_behind_list,
322 conn->case_sensitive)) {
323 fsp->aio_write_behind = True;
326 status = get_full_smb_filename(talloc_tos(), smb_fname,
328 if (!NT_STATUS_IS_OK(status)) {
332 string_set(&fsp->fsp_name, path);
335 fsp->wcp = NULL; /* Write cache pointer. */
337 DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
338 conn->server_info->unix_name,
339 smb_fname_str_dbg(smb_fname),
340 BOOLSTR(fsp->can_read), BOOLSTR(fsp->can_write),
341 conn->num_files_open));
347 /****************************************************************************
348 Handle the 1 second delay in returning a SHARING_VIOLATION error.
349 ****************************************************************************/
351 static void defer_open(struct share_mode_lock *lck,
352 struct timeval request_time,
353 struct timeval timeout,
354 struct smb_request *req,
355 struct deferred_open_record *state)
361 for (i=0; i<lck->num_share_modes; i++) {
362 struct share_mode_entry *e = &lck->share_modes[i];
364 if (!is_deferred_open_entry(e)) {
368 if (procid_is_me(&e->pid) && (e->op_mid == req->mid)) {
369 DEBUG(0, ("Trying to defer an already deferred "
370 "request: mid=%d, exiting\n", req->mid));
371 exit_server("attempt to defer a deferred request");
375 /* End paranoia check */
377 DEBUG(10,("defer_open_sharing_error: time [%u.%06u] adding deferred "
378 "open entry for mid %u\n",
379 (unsigned int)request_time.tv_sec,
380 (unsigned int)request_time.tv_usec,
381 (unsigned int)req->mid));
383 if (!push_deferred_smb_message(req, request_time, timeout,
384 (char *)state, sizeof(*state))) {
385 exit_server("push_deferred_smb_message failed");
387 add_deferred_open(lck, req->mid, request_time, state->id);
390 static void schedule_defer_open(struct share_mode_lock *lck,
391 struct timeval request_time,
392 struct smb_request *req)
394 struct deferred_open_record state;
396 /* This is a relative time, added to the absolute
397 request_time value to get the absolute timeout time.
398 Note that if this is the second or greater time we enter
399 this codepath for this particular request mid then
400 request_time is left as the absolute time of the *first*
401 time this request mid was processed. This is what allows
402 the request to eventually time out. */
404 struct timeval timeout;
406 /* Normally the smbd we asked should respond within
407 * OPLOCK_BREAK_TIMEOUT seconds regardless of whether
408 * the client did, give twice the timeout as a safety
409 * measure here in case the other smbd is stuck
413 * On OneFS, the kernel will always send an oplock_revoked message
414 * before this timeout is hit.
416 timeout = timeval_set(OPLOCK_BREAK_TIMEOUT*10, 0);
418 /* Nothing actually uses state.delayed_for_oplocks
419 but it's handy to differentiate in debug messages
420 between a 30 second delay due to oplock break, and
421 a 1 second delay for share mode conflicts. */
423 state.delayed_for_oplocks = True;
424 state.failed = false;
427 if (!request_timed_out(request_time, timeout)) {
428 defer_open(lck, request_time, timeout, req, &state);
432 /****************************************************************************
433 Open a file with a share mode. Passed in an already created files_struct.
434 ****************************************************************************/
435 NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
436 struct smb_request *req,
437 struct smb_filename *smb_fname,
440 uint32 create_disposition,
441 uint32 create_options,
442 uint32 new_dos_attributes,
444 struct security_descriptor *sd,
447 struct onefs_fsp_data *fsp_data)
451 bool file_existed = VALID_STAT(smb_fname->st);
452 bool def_acl = False;
453 bool posix_open = False;
454 bool new_file_created = False;
455 bool clear_ads = False;
457 mode_t new_unx_mode = (mode_t)0;
458 mode_t unx_mode = (mode_t)0;
460 uint32 existing_dos_attributes = 0;
461 struct pending_message_list *pml = NULL;
462 struct timeval request_time = timeval_zero();
463 struct share_mode_lock *lck = NULL;
464 uint32 open_access_mask = access_mask;
469 uint64_t oplock_callback_id = 0;
470 uint32 createfile_attributes = 0;
476 * Printers are handled completely differently.
477 * Most of the passed parameters are ignored.
481 *pinfo = FILE_WAS_CREATED;
484 DEBUG(10, ("onefs_open_file_ntcreate: printer open fname=%s\n",
485 smb_fname_str_dbg(smb_fname)));
487 return print_fsp_open(req, conn, smb_fname->base_name,
488 req->vuid, fsp, &smb_fname->st);
491 if (!parent_dirname(talloc_tos(), smb_fname->base_name, &parent_dir,
493 return NT_STATUS_NO_MEMORY;
496 if (new_dos_attributes & FILE_FLAG_POSIX_SEMANTICS) {
498 unx_mode = (mode_t)(new_dos_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
499 new_dos_attributes = 0;
501 /* We add aARCH to this as this mode is only used if the file is
503 unx_mode = unix_mode(conn, new_dos_attributes | aARCH,
504 smb_fname, parent_dir);
507 DEBUG(10,("onefs_open_file_ntcreate: fname=%s, dos_attrs=0x%x "
508 "access_mask=0x%x share_access=0x%x "
509 "create_disposition = 0x%x create_options=0x%x "
510 "unix mode=0%o oplock_request=0x%x\n",
511 smb_fname_str_dbg(smb_fname), new_dos_attributes,
512 access_mask, share_access, create_disposition,
513 create_options, unx_mode, oplock_request));
516 * Any non-stat-only open has the potential to contend oplocks, which
517 * means to avoid blocking in the kernel (which is unacceptable), the
518 * open must be deferred. In order to defer opens, req must not be
519 * NULL. The known cases of calling with a NULL req:
521 * 1. Open the base file of a stream: Always done stat-only
523 * 2. open_file_fchmod(), which is called from 3 places:
524 * A. try_chown: Posix acls only. Never called on onefs.
525 * B. set_ea_dos_attributes: Can't be called from onefs, because
526 * SMB_VFS_SETXATTR return ENOSYS.
527 * C. file_set_dos_mode: This would only happen if the "dos
528 * filemode" smb.conf parameter is set to yes. We ship with
529 * it off, but if a customer were to turn it on it would be
532 if (req == NULL && !is_stat_open(access_mask) &&
533 !is_ntfs_stream_smb_fname(smb_fname)) {
534 smb_panic("NULL req on a non-stat-open!");
537 if ((req == NULL) && ((oplock_request & INTERNAL_OPEN_ONLY) == 0)) {
538 DEBUG(0, ("No smb request but not an internal only open!\n"));
539 return NT_STATUS_INTERNAL_ERROR;
543 * Only non-internal opens can be deferred at all
547 && ((pml = get_open_deferred_message(req->mid)) != NULL)) {
548 struct deferred_open_record *state =
549 (struct deferred_open_record *)pml->private_data.data;
551 /* Remember the absolute time of the original
552 request with this mid. We'll use it later to
553 see if this has timed out. */
555 request_time = pml->request_time;
557 /* Remove the deferred open entry under lock. */
558 lck = get_share_mode_lock(talloc_tos(), state->id, NULL, NULL,
561 DEBUG(0, ("could not get share mode lock\n"));
563 del_deferred_open_entry(lck, req->mid);
567 /* Ensure we don't reprocess this message. */
568 remove_deferred_open_smb_message(req->mid);
571 * When receiving a semlock_async_failure message, the
572 * deferred open will be marked as "failed". Returning
576 DEBUG(0, ("onefs_open_file_ntcreate: "
577 "semlock_async_failure detected!\n"));
578 return NT_STATUS_INTERNAL_ERROR;
582 status = check_name(conn, smb_fname->base_name);
583 if (!NT_STATUS_IS_OK(status)) {
588 new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
590 existing_dos_attributes = dos_mode(conn, smb_fname);
594 /* Setup dos_attributes to be set by ifs_createfile */
595 if (lp_store_dos_attributes(SNUM(conn))) {
596 createfile_attributes = (new_dos_attributes | aARCH) &
597 ~(FILE_ATTRIBUTE_NONINDEXED | FILE_ATTRIBUTE_COMPRESSED);
600 /* Ignore oplock requests if oplocks are disabled. */
601 if (!lp_oplocks(SNUM(conn)) || global_client_failed_oplock_break ||
602 IS_VETO_OPLOCK_PATH(conn, smb_fname->base_name)) {
603 /* Mask off everything except the private Samba bits. */
604 oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
607 /* this is for OS/2 long file names - say we don't support them */
608 if (!lp_posix_pathnames() && strstr(smb_fname->base_name,".+,;=[].")) {
609 /* OS/2 Workplace shell fix may be main code stream in a later
611 DEBUG(5,("onefs_open_file_ntcreate: OS/2 long filenames are "
612 "not supported.\n"));
613 if (use_nt_status()) {
614 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
616 return NT_STATUS_DOS(ERRDOS, ERRcannotopen);
619 switch( create_disposition ) {
621 * Currently we're using FILE_SUPERSEDE as the same as
622 * FILE_OVERWRITE_IF but they really are
623 * different. FILE_SUPERSEDE deletes an existing file
624 * (requiring delete access) then recreates it.
628 * @todo: Clear all file attributes?
629 * http://www.osronline.com/article.cfm?article=302
630 * create if not exist, trunc if exist
632 * If file exists replace/overwrite. If file doesn't
635 flags2 |= (O_CREAT | O_TRUNC);
639 case FILE_OVERWRITE_IF:
640 /* If file exists replace/overwrite. If file doesn't
642 flags2 |= (O_CREAT | O_TRUNC);
647 /* If file exists open. If file doesn't exist error. */
649 DEBUG(5,("onefs_open_file_ntcreate: FILE_OPEN "
650 "requested for file %s and file "
652 smb_fname_str_dbg(smb_fname)));
654 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
659 /* If file exists overwrite. If file doesn't exist
662 DEBUG(5, ("onefs_open_file_ntcreate: "
663 "FILE_OVERWRITE requested for file "
664 "%s and file doesn't exist.\n",
665 smb_fname_str_dbg(smb_fname)));
667 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
674 /* If file exists error. If file doesn't exist
677 DEBUG(5, ("onefs_open_file_ntcreate: "
678 "FILE_CREATE requested for file %s "
679 "and file already exists.\n",
680 smb_fname_str_dbg(smb_fname)));
681 if (S_ISDIR(smb_fname->st.st_ex_mode)) {
686 return map_nt_error_from_unix(errno);
688 flags2 |= (O_CREAT|O_EXCL);
692 /* If file exists open. If file doesn't exist
698 return NT_STATUS_INVALID_PARAMETER;
701 /* Match attributes on file exists and overwrite. */
702 if (!posix_open && file_existed &&
703 ((create_disposition == FILE_OVERWRITE) ||
704 (create_disposition == FILE_OVERWRITE_IF))) {
705 if (!open_match_attributes(conn, existing_dos_attributes,
707 smb_fname->st.st_ex_mode,
708 unx_mode, &new_unx_mode)) {
709 DEBUG(5, ("onefs_open_file_ntcreate: attributes "
710 "missmatch for file %s (%x %x) (0%o, 0%o)\n",
711 smb_fname_str_dbg(smb_fname),
712 existing_dos_attributes,
714 (unsigned int)smb_fname->st.st_ex_mode,
715 (unsigned int)unx_mode ));
717 return NT_STATUS_ACCESS_DENIED;
722 * OneFS understands MAXIMUM_ALLOWED_ACCESS, so only hack the
723 * access_mask, but leave the MAA for the actual open in
726 open_access_mask = access_mask;
727 if (open_access_mask & MAXIMUM_ALLOWED_ACCESS) {
728 access_mask |= FILE_GENERIC_ALL;
731 /* Convert GENERIC bits to specific bits. */
732 se_map_generic(&access_mask, &file_generic_mapping);
733 se_map_generic(&open_access_mask, &file_generic_mapping);
735 if ((flags2 & O_TRUNC) || (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE)) {
736 /* This will cause oplock breaks. */
737 open_access_mask |= FILE_WRITE_DATA;
740 DEBUG(10, ("onefs_open_file_ntcreate: fname=%s, after mapping "
741 "open_access_mask=%#x, access_mask=0x%x\n",
742 smb_fname_str_dbg(smb_fname), open_access_mask,
746 * Note that we ignore the append flag as append does not
747 * mean the same thing under DOS and Unix.
750 if ((access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ||
751 (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE)) {
754 * DENY_DOS opens are always underlying read-write on the
755 * file handle, no matter what the requested access mask
756 * says. Stock samba just sets the flags, but since
757 * ifs_createfile uses the access_mask, it must be updated as
758 * well. This allows BASE-DENY* to pass.
760 if (create_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) {
762 DEBUG(10,("onefs_open_file_ntcreate: deny_dos: "
763 "Adding O_RDWR to flags "
764 "(0x%x) and some READ bits to "
765 "open_access_mask (0x%x)\n",
766 flags, open_access_mask));
769 open_access_mask |= (FILE_READ_ATTRIBUTES |
770 FILE_READ_DATA | FILE_READ_EA | FILE_EXECUTE);
772 } else if (access_mask & (FILE_READ_ATTRIBUTES |
784 /* Currently we only look at FILE_WRITE_THROUGH for create options. */
786 if ((create_options & FILE_WRITE_THROUGH) &&
787 lp_strict_sync(SNUM(conn))) {
792 if (posix_open && (access_mask & FILE_APPEND_DATA)) {
796 if (!posix_open && !CAN_WRITE(conn)) {
798 * We should really return a permission denied error if either
799 * O_CREAT or O_TRUNC are set, but for compatibility with
800 * older versions of Samba we just AND them out.
802 flags2 &= ~(O_CREAT|O_TRUNC);
804 /* Deny DELETE_ACCESS explicitly if the share is read only. */
805 if (access_mask & DELETE_ACCESS) {
806 return map_nt_error_from_unix(EACCES);
810 /* Ensure we can't write on a read-only share or file. */
811 if (flags != O_RDONLY && file_existed &&
812 (!CAN_WRITE(conn) || IS_DOS_READONLY(existing_dos_attributes))) {
813 DEBUG(5, ("onefs_open_file_ntcreate: write access requested "
814 "for file %s on read only %s\n",
815 smb_fname_str_dbg(smb_fname),
816 !CAN_WRITE(conn) ? "share" : "file" ));
818 return NT_STATUS_ACCESS_DENIED;
821 DEBUG(10, ("fsp = %p\n", fsp));
823 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
824 fsp->share_access = share_access;
825 fsp->fh->private_options = create_options;
826 fsp->access_mask = open_access_mask; /* We change this to the
827 * requested access_mask after
828 * the open is done. */
829 fsp->posix_open = posix_open;
831 /* Ensure no SAMBA_PRIVATE bits can be set. */
832 fsp->oplock_type = (oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK);
834 if (timeval_is_zero(&request_time)) {
835 request_time = fsp->open_time;
839 struct timespec old_write_time = smb_fname->st.st_ex_mtime;
840 id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
842 lck = get_share_mode_lock(talloc_tos(), id,
844 smb_fname, &old_write_time);
847 DEBUG(0, ("Could not get share mode lock\n"));
848 return NT_STATUS_SHARING_VIOLATION;
851 if (lck->delete_on_close) {
852 /* DELETE_PENDING is not deferred for a second */
854 return NT_STATUS_DELETE_PENDING;
858 SMB_ASSERT(!file_existed || (lck != NULL));
861 * Ensure we pay attention to default ACLs on directories. May be
862 * neccessary depending on ACL policies.
864 if ((flags2 & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
865 (def_acl = directory_has_default_acl(conn, parent_dir))) {
869 DEBUG(4,("calling onefs_open_file with flags=0x%X flags2=0x%X "
870 "mode=0%o, access_mask = 0x%x, open_access_mask = 0x%x\n",
871 (unsigned int)flags, (unsigned int)flags2,
872 (unsigned int)unx_mode, (unsigned int)access_mask,
873 (unsigned int)open_access_mask));
876 * Since the open is guaranteed to be stat only if req == NULL, a
877 * callback record is only needed if req != NULL.
880 SMB_ASSERT(fsp_data);
881 oplock_callback_id = onefs_oplock_wait_record(req->mid);
882 if (oplock_callback_id == 0) {
883 return NT_STATUS_NO_MEMORY;
887 * It is also already asserted it's either a stream or a
888 * stat-only open at this point.
890 SMB_ASSERT(fsp->oplock_type == NO_OPLOCK);
894 status = onefs_open_file(fsp,
907 createfile_attributes,
911 if (!NT_STATUS_IS_OK(status)) {
913 /* OneFS Oplock Handling */
914 if (errno == EINPROGRESS) {
918 struct deferred_open_record state;
919 struct timespec old_write_time;
921 old_write_time = smb_fname->st.st_ex_mtime;
923 DEBUG(3, ("Someone created file %s with an "
924 "oplock after we looked: Retrying\n",
925 smb_fname_str_dbg(smb_fname)));
927 * We hit the race that when we did the stat
928 * on the file it did not exist, and someone
929 * has created it in between the stat and the
930 * open_file() call. Just retry immediately.
932 id = vfs_file_id_from_sbuf(conn,
934 if (!(lck = get_share_mode_lock(talloc_tos(),
935 id, conn->connectpath, smb_fname,
940 DEBUG(0, ("onefs_open_file_ntcreate: "
941 "Could not get share mode "
943 smb_fname_str_dbg(smb_fname)));
944 status = NT_STATUS_SHARING_VIOLATION;
945 goto cleanup_destroy;
948 state.delayed_for_oplocks = False;
952 defer_open(lck, request_time,
953 timeval_zero(), req, &state);
955 goto cleanup_destroy;
957 /* Waiting for an oplock */
958 DEBUG(5,("Async createfile because a client has an "
960 smb_fname_str_dbg(smb_fname)));
963 schedule_defer_open(lck, request_time, req);
967 /* Check for a sharing violation */
968 if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
969 uint32 can_access_mask;
970 bool can_access = True;
972 /* Check if this can be done with the deny_dos and fcb
975 /* Try to find dup fsp if possible. */
977 (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS|
978 NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) {
981 DEBUG(0, ("DOS open without an SMB "
983 status = NT_STATUS_INTERNAL_ERROR;
984 goto cleanup_destroy;
987 /* Use the client requested access mask here,
988 * not the one we open with. */
989 status = fcb_or_dos_open(req,
1000 if (NT_STATUS_IS_OK(status)) {
1002 *pinfo = FILE_WAS_OPENED;
1004 status = NT_STATUS_OK;
1010 * This next line is a subtlety we need for
1011 * MS-Access. If a file open will fail due to share
1012 * permissions and also for security (access) reasons,
1013 * we need to return the access failed error, not the
1014 * share error. We can't open the file due to kernel
1015 * oplock deadlock (it's possible we failed above on
1016 * the open_mode_check()) so use a userspace check.
1019 if (flags & O_RDWR) {
1020 can_access_mask = FILE_READ_DATA|FILE_WRITE_DATA;
1021 } else if (flags & O_WRONLY) {
1022 can_access_mask = FILE_WRITE_DATA;
1024 can_access_mask = FILE_READ_DATA;
1027 if (((can_access_mask & FILE_WRITE_DATA) &&
1028 !CAN_WRITE(conn)) ||
1029 !can_access_file_data(conn, smb_fname,
1035 * If we're returning a share violation, ensure we
1036 * cope with the braindead 1 second delay.
1038 if (!(oplock_request & INTERNAL_OPEN_ONLY) &&
1039 lp_defer_sharing_violations()) {
1040 struct timeval timeout;
1041 struct deferred_open_record state;
1044 /* this is a hack to speed up torture tests
1046 timeout_usecs = lp_parm_int(SNUM(conn),
1047 "smbd","sharedelay",
1048 SHARING_VIOLATION_USEC_WAIT);
1050 /* This is a relative time, added to the
1051 absolute request_time value to get the
1052 absolute timeout time. Note that if this
1053 is the second or greater time we enter this
1054 codepath for this particular request mid
1055 then request_time is left as the absolute
1056 time of the *first* time this request mid
1057 was processed. This is what allows the
1058 request to eventually time out. */
1060 timeout = timeval_set(0, timeout_usecs);
1062 /* Nothing actually uses
1063 state.delayed_for_oplocks but it's handy to
1064 differentiate in debug messages between a
1065 30 second delay due to oplock break, and a
1066 1 second delay for share mode conflicts. */
1068 state.delayed_for_oplocks = False;
1070 state.failed = false;
1073 && !request_timed_out(request_time,
1075 defer_open(lck, request_time, timeout,
1082 * We have detected a sharing violation here
1083 * so return the correct error code
1085 status = NT_STATUS_SHARING_VIOLATION;
1087 status = NT_STATUS_ACCESS_DENIED;
1090 goto cleanup_destroy;
1094 * Normal error, for example EACCES
1097 if (oplock_callback_id != 0) {
1098 destroy_onefs_callback_record(oplock_callback_id);
1105 fsp->oplock_type = granted_oplock;
1107 if (oplock_callback_id != 0) {
1108 onefs_set_oplock_callback(oplock_callback_id, fsp);
1109 fsp_data->oplock_callback_id = oplock_callback_id;
1111 SMB_ASSERT(fsp->oplock_type == NO_OPLOCK);
1114 if (!file_existed) {
1115 struct timespec old_write_time = smb_fname->st.st_ex_mtime;
1117 * Deal with the race condition where two smbd's detect the
1118 * file doesn't exist and do the create at the same time. One
1119 * of them will win and set a share mode, the other (ie. this
1120 * one) should check if the requested share mode for this
1121 * create is allowed.
1125 * Now the file exists and fsp is successfully opened,
1126 * fsp->dev and fsp->inode are valid and should replace the
1127 * dev=0,inode=0 from a non existent file. Spotted by
1128 * Nadav Danieli <nadavd@exanet.com>. JRA.
1133 lck = get_share_mode_lock(talloc_tos(), id,
1135 smb_fname, &old_write_time);
1138 DEBUG(0, ("onefs_open_file_ntcreate: Could not get "
1139 "share mode lock for %s\n",
1140 smb_fname_str_dbg(smb_fname)));
1142 return NT_STATUS_SHARING_VIOLATION;
1145 if (lck->delete_on_close) {
1146 status = NT_STATUS_DELETE_PENDING;
1149 if (!NT_STATUS_IS_OK(status)) {
1150 struct deferred_open_record state;
1154 state.delayed_for_oplocks = False;
1157 /* Do it all over again immediately. In the second
1158 * round we will find that the file existed and handle
1159 * the DELETE_PENDING and FCB cases correctly. No need
1160 * to duplicate the code here. Essentially this is a
1161 * "goto top of this function", but don't tell
1165 defer_open(lck, request_time, timeval_zero(),
1173 * We exit this block with the share entry *locked*.....
1178 SMB_ASSERT(lck != NULL);
1180 /* Delete streams if create_disposition requires it */
1181 if (file_existed && clear_ads &&
1182 !is_ntfs_stream_smb_fname(smb_fname)) {
1183 status = delete_all_streams(conn, smb_fname->base_name);
1184 if (!NT_STATUS_IS_OK(status)) {
1191 /* note that we ignore failure for the following. It is
1192 basically a hack for NFS, and NFS will never set one of
1193 these only read them. Nobody but Samba can ever set a deny
1194 mode and we have already checked our more authoritative
1195 locking database for permission to set this deny mode. If
1196 the kernel refuses the operations then the kernel is wrong.
1197 note that GPFS supports it as well - jmcd */
1199 if (fsp->fh->fd != -1) {
1200 ret_flock = SMB_VFS_KERNEL_FLOCK(fsp, share_access);
1201 if(ret_flock == -1 ){
1205 return NT_STATUS_SHARING_VIOLATION;
1210 * At this point onwards, we can guarentee that the share entry
1211 * is locked, whether we created the file or not, and that the
1212 * deny mode is compatible with all current opens.
1215 /* Record the options we were opened with. */
1216 fsp->share_access = share_access;
1217 fsp->fh->private_options = create_options;
1219 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
1221 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
1224 /* stat opens on existing files don't get oplocks. */
1225 if (is_stat_open(open_access_mask)) {
1226 fsp->oplock_type = NO_OPLOCK;
1229 if (!(flags2 & O_TRUNC)) {
1230 info = FILE_WAS_OPENED;
1232 info = FILE_WAS_OVERWRITTEN;
1235 info = FILE_WAS_CREATED;
1243 * Setup the oplock info in both the shared memory and
1247 if ((fsp->oplock_type != NO_OPLOCK) &&
1248 (fsp->oplock_type != FAKE_LEVEL_II_OPLOCK)) {
1249 if (!set_file_oplock(fsp, fsp->oplock_type)) {
1250 /* Could not get the kernel oplock */
1251 fsp->oplock_type = NO_OPLOCK;
1255 if (fsp->oplock_type == LEVEL_II_OPLOCK &&
1256 (!lp_level2_oplocks(SNUM(conn)) ||
1257 !(global_client_caps & CAP_LEVEL_II_OPLOCKS))) {
1259 DEBUG(5, ("Downgrading level2 oplock on open "
1260 "because level2 oplocks = off\n"));
1262 release_file_oplock(fsp);
1265 if (info == FILE_WAS_OVERWRITTEN || info == FILE_WAS_CREATED ||
1266 info == FILE_WAS_SUPERSEDED) {
1267 new_file_created = True;
1270 set_share_mode(lck, fsp, conn->server_info->utok.uid, 0,
1273 /* Handle strange delete on close create semantics. */
1274 if (create_options & FILE_DELETE_ON_CLOSE) {
1275 status = can_set_delete_on_close(fsp, True, new_dos_attributes);
1277 if (!NT_STATUS_IS_OK(status)) {
1278 /* Remember to delete the mode we just added. */
1279 del_share_mode(lck, fsp);
1284 /* Note that here we set the *inital* delete on close flag,
1285 not the regular one. The magic gets handled in close. */
1286 fsp->initial_delete_on_close = True;
1290 * Take care of inherited ACLs on created files - if default ACL not
1292 * May be necessary depending on acl policies.
1294 if (!posix_open && !file_existed && !def_acl &&
1295 !(VALID_STAT(smb_fname->st) &&
1296 (smb_fname->st.st_ex_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 smb_fname_str_dbg(smb_fname),
1323 (unsigned int)new_unx_mode));
1324 ret = 0; /* Don't do the fchmod below. */
1329 (SMB_VFS_FCHMOD(fsp, new_unx_mode) == -1))
1330 DEBUG(5, ("onefs_open_file_ntcreate: failed to reset "
1331 "attributes of file %s to 0%o\n",
1332 smb_fname_str_dbg(smb_fname),
1333 (unsigned int)new_unx_mode));
1336 /* If this is a successful open, we must remove any deferred open
1339 del_deferred_open_entry(lck, req->mid);
1343 return NT_STATUS_OK;
1347 /****************************************************************************
1348 Open a directory from an NT SMB call.
1349 ****************************************************************************/
1350 static NTSTATUS onefs_open_directory(connection_struct *conn,
1351 struct smb_request *req,
1352 struct smb_filename *smb_dname,
1354 uint32 share_access,
1355 uint32 create_disposition,
1356 uint32 create_options,
1357 uint32 file_attributes,
1358 struct security_descriptor *sd,
1359 files_struct **result,
1362 files_struct *fsp = NULL;
1363 struct share_mode_lock *lck = NULL;
1365 struct timespec mtimespec;
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 smb_fname_str_dbg(smb_dname), (unsigned int)access_mask,
1377 (unsigned int)share_access, (unsigned int)create_options,
1378 (unsigned int)create_disposition,
1379 (unsigned int)file_attributes));
1381 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
1382 (conn->fs_capabilities & FILE_NAMED_STREAMS) &&
1383 is_ntfs_stream_smb_fname(smb_dname)) {
1384 DEBUG(2, ("onefs_open_directory: %s is a stream name!\n",
1385 smb_fname_str_dbg(smb_dname)));
1386 return NT_STATUS_NOT_A_DIRECTORY;
1389 switch (create_disposition) {
1391 /* If directory exists open. If directory doesn't
1394 info = FILE_WAS_OPENED;
1397 /* If directory exists error. If directory doesn't
1399 create_flags = O_CREAT | O_EXCL;
1400 info = FILE_WAS_CREATED;
1403 /* If directory exists open. If directory doesn't
1406 /* Note: in order to return whether the directory was
1407 * opened or created, we first try to open and then try
1410 info = FILE_WAS_OPENED;
1412 case FILE_SUPERSEDE:
1413 case FILE_OVERWRITE:
1414 case FILE_OVERWRITE_IF:
1416 DEBUG(5, ("onefs_open_directory: invalid "
1417 "create_disposition 0x%x for directory %s\n",
1418 (unsigned int)create_disposition,
1419 smb_fname_str_dbg(smb_dname)));
1420 return NT_STATUS_INVALID_PARAMETER;
1424 * Check for write access to the share. Done in mkdir_internal() in
1427 if (!CAN_WRITE(conn) && (create_flags & O_CREAT)) {
1428 return NT_STATUS_ACCESS_DENIED;
1431 /* Get parent dirname */
1432 if (!parent_dirname(talloc_tos(), smb_dname->base_name, &parent_dir,
1434 return NT_STATUS_NO_MEMORY;
1437 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
1439 mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
1440 file_attributes = 0;
1442 mode = unix_mode(conn, aDIR, smb_dname, parent_dir);
1446 * The NONINDEXED and COMPRESSED bits seem to always be cleared on
1447 * directories, no matter if you specify that they should be set.
1450 ~(FILE_ATTRIBUTE_NONINDEXED | FILE_ATTRIBUTE_COMPRESSED);
1452 status = file_new(req, conn, &fsp);
1453 if(!NT_STATUS_IS_OK(status)) {
1458 * Actual open with retry magic to handle FILE_OPEN_IF which is
1459 * unique because the kernel won't tell us if the file was opened or
1463 fsp->fh->fd = onefs_sys_create_file(conn,
1465 smb_dname->base_name,
1470 create_flags | O_DIRECTORY,
1478 if (fsp->fh->fd == -1) {
1479 DEBUG(3, ("Error opening %s. Errno=%d (%s).\n",
1480 smb_fname_str_dbg(smb_dname), errno,
1482 SMB_ASSERT(errno != EINPROGRESS);
1484 if (create_disposition == FILE_OPEN_IF) {
1485 if (errno == ENOENT) {
1486 /* Try again, creating it this time. */
1487 create_flags = O_CREAT | O_EXCL;
1488 info = FILE_WAS_CREATED;
1490 } else if (errno == EEXIST) {
1491 /* Uggh. Try again again. */
1493 info = FILE_WAS_OPENED;
1498 /* Error cases below: */
1499 file_free(req, fsp);
1501 if ((errno == ENOENT) && (create_disposition == FILE_OPEN)) {
1502 DEBUG(5, ("onefs_open_directory: FILE_OPEN requested "
1503 "for directory %s and it doesn't "
1504 "exist.\n", smb_fname_str_dbg(smb_dname)));
1505 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1506 } else if ((errno == EEXIST) &&
1507 (create_disposition == FILE_CREATE)) {
1508 DEBUG(5, ("onefs_open_directory: FILE_CREATE "
1509 "requested for directory %s and it "
1510 "already exists.\n",
1511 smb_fname_str_dbg(smb_dname)));
1512 return NT_STATUS_OBJECT_NAME_COLLISION;
1513 } else if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
1514 /* Catch sharing violations. */
1515 return NT_STATUS_SHARING_VIOLATION;
1518 return map_nt_error_from_unix(errno);
1521 if (info == FILE_WAS_CREATED) {
1523 /* Pulled from mkdir_internal() */
1524 if (SMB_VFS_LSTAT(conn, smb_dname) == -1) {
1525 DEBUG(2, ("Could not stat directory '%s' just "
1527 smb_fname_str_dbg(smb_dname),
1529 return map_nt_error_from_unix(errno);
1532 if (!S_ISDIR(smb_dname->st.st_ex_mode)) {
1533 DEBUG(0, ("Directory just '%s' created is not a "
1535 smb_fname_str_dbg(smb_dname)));
1536 return NT_STATUS_ACCESS_DENIED;
1541 * Check if high bits should have been set, then (if
1542 * bits are missing): add them. Consider bits
1543 * automagically set by UNIX, i.e. SGID bit from
1546 if (mode & ~(S_IRWXU|S_IRWXG|S_IRWXO) &&
1547 (mode & ~smb_dname->st.st_ex_mode)) {
1548 SMB_VFS_CHMOD(conn, smb_dname->base_name,
1549 (smb_dname->st.st_ex_mode |
1550 (mode & ~smb_dname->st.st_ex_mode)));
1554 /* Change the owner if required. */
1555 if (lp_inherit_owner(SNUM(conn))) {
1556 change_dir_owner_to_parent(conn, parent_dir,
1557 smb_dname->base_name,
1561 notify_fname(conn, NOTIFY_ACTION_ADDED,
1562 FILE_NOTIFY_CHANGE_DIR_NAME,
1563 smb_dname->base_name);
1566 /* Stat the fd for Samba bookkeeping. */
1567 if(SMB_VFS_FSTAT(fsp, &smb_dname->st) != 0) {
1569 file_free(req, fsp);
1570 return map_nt_error_from_unix(errno);
1573 /* Setup the files_struct for it. */
1574 fsp->mode = smb_dname->st.st_ex_mode;
1575 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_dname->st);
1576 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
1577 fsp->file_pid = req ? req->smbpid : 0;
1578 fsp->can_lock = False;
1579 fsp->can_read = False;
1580 fsp->can_write = False;
1582 fsp->share_access = share_access;
1583 fsp->fh->private_options = create_options;
1585 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
1587 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
1588 fsp->print_file = False;
1589 fsp->modified = False;
1590 fsp->oplock_type = NO_OPLOCK;
1591 fsp->sent_oplock_break = NO_BREAK_SENT;
1592 fsp->is_directory = True;
1593 fsp->posix_open = posix_open;
1595 string_set(&fsp->fsp_name, smb_dname->base_name);
1597 mtimespec = smb_dname->st.st_ex_mtime;
1600 * Still set the samba share mode lock for correct delete-on-close
1601 * semantics and to make smbstatus more useful.
1603 lck = get_share_mode_lock(talloc_tos(), fsp->file_id,
1604 conn->connectpath, smb_dname, &mtimespec);
1607 DEBUG(0, ("onefs_open_directory: Could not get share mode "
1608 "lock for %s\n", smb_fname_str_dbg(smb_dname)));
1610 file_free(req, fsp);
1611 return NT_STATUS_SHARING_VIOLATION;
1614 if (lck->delete_on_close) {
1617 file_free(req, fsp);
1618 return NT_STATUS_DELETE_PENDING;
1621 set_share_mode(lck, fsp, conn->server_info->utok.uid, 0, NO_OPLOCK);
1624 * For directories the delete on close bit at open time seems
1625 * always to be honored on close... See test 19 in Samba4 BASE-DELETE.
1627 if (create_options & FILE_DELETE_ON_CLOSE) {
1628 status = can_set_delete_on_close(fsp, True, 0);
1629 if (!NT_STATUS_IS_OK(status) &&
1630 !NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
1633 file_free(req, fsp);
1637 if (NT_STATUS_IS_OK(status)) {
1638 /* Note that here we set the *inital* delete on close flag,
1639 not the regular one. The magic gets handled in close. */
1640 fsp->initial_delete_on_close = True;
1651 return NT_STATUS_OK;
1655 * Wrapper around onefs_open_file_ntcreate and onefs_open_directory.
1657 static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
1658 struct smb_request *req,
1659 struct smb_filename *smb_fname,
1660 uint32_t access_mask,
1661 uint32_t share_access,
1662 uint32_t create_disposition,
1663 uint32_t create_options,
1664 uint32_t file_attributes,
1665 uint32_t oplock_request,
1666 uint64_t allocation_size,
1667 struct security_descriptor *sd,
1668 struct ea_list *ea_list,
1669 files_struct **result,
1671 struct onefs_fsp_data *fsp_data)
1673 int info = FILE_WAS_OPENED;
1674 files_struct *base_fsp = NULL;
1675 files_struct *fsp = NULL;
1678 DEBUG(10,("onefs_create_file_unixpath: access_mask = 0x%x "
1679 "file_attributes = 0x%x, share_access = 0x%x, "
1680 "create_disposition = 0x%x create_options = 0x%x "
1681 "oplock_request = 0x%x ea_list = 0x%p, sd = 0x%p, "
1683 (unsigned int)access_mask,
1684 (unsigned int)file_attributes,
1685 (unsigned int)share_access,
1686 (unsigned int)create_disposition,
1687 (unsigned int)create_options,
1688 (unsigned int)oplock_request,
1689 ea_list, sd, smb_fname_str_dbg(smb_fname)));
1691 if (create_options & FILE_OPEN_BY_FILE_ID) {
1692 status = NT_STATUS_NOT_SUPPORTED;
1696 if (create_options & NTCREATEX_OPTIONS_INVALID_PARAM_MASK) {
1697 status = NT_STATUS_INVALID_PARAMETER;
1702 SMB_ASSERT((oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK) ==
1704 oplock_request |= INTERNAL_OPEN_ONLY;
1707 if (lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE,
1708 PARM_IGNORE_SACLS, PARM_IGNORE_SACLS_DEFAULT)) {
1709 access_mask &= ~SYSTEM_SECURITY_ACCESS;
1712 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
1713 && (access_mask & DELETE_ACCESS)
1714 && !is_ntfs_stream_smb_fname(smb_fname)) {
1716 * We can't open a file with DELETE access if any of the
1717 * streams is open without FILE_SHARE_DELETE
1719 status = open_streams_for_delete(conn, smb_fname->base_name);
1721 if (!NT_STATUS_IS_OK(status)) {
1726 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
1727 && is_ntfs_stream_smb_fname(smb_fname)) {
1728 uint32 base_create_disposition;
1729 struct smb_filename *smb_fname_base = NULL;
1731 if (create_options & FILE_DIRECTORY_FILE) {
1732 status = NT_STATUS_NOT_A_DIRECTORY;
1736 switch (create_disposition) {
1738 base_create_disposition = FILE_OPEN;
1741 base_create_disposition = FILE_OPEN_IF;
1745 /* Create an smb_filename with stream_name == NULL. */
1746 status = create_synthetic_smb_fname(talloc_tos(),
1747 smb_fname->base_name,
1750 if (!NT_STATUS_IS_OK(status)) {
1754 if (SMB_VFS_STAT(conn, smb_fname_base) == -1) {
1755 DEBUG(10, ("Unable to stat stream: %s\n",
1756 smb_fname_str_dbg(smb_fname_base)));
1759 status = onefs_create_file_unixpath(
1762 smb_fname_base, /* fname */
1763 SYNCHRONIZE_ACCESS, /* access_mask */
1766 FILE_SHARE_DELETE), /* share_access */
1767 base_create_disposition, /* create_disposition*/
1768 0, /* create_options */
1769 file_attributes, /* file_attributes */
1770 NO_OPLOCK, /* oplock_request */
1771 0, /* allocation_size */
1774 &base_fsp, /* result */
1776 NULL); /* fsp_data */
1778 TALLOC_FREE(smb_fname_base);
1780 if (!NT_STATUS_IS_OK(status)) {
1781 DEBUG(10, ("onefs_create_file_unixpath for base %s "
1782 "failed: %s\n", smb_fname->base_name,
1783 nt_errstr(status)));
1788 * Testing against windows xp/2003/vista shows that oplocks
1789 * can actually be requested and granted on streams (see the
1790 * RAW-OPLOCK-STREAM1 smbtorture test).
1792 if ((oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK) !=
1794 DEBUG(5, ("Oplock(%d) being requested on a stream! "
1795 "Ignoring oplock request: fname=%s\n",
1796 oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK,
1797 smb_fname_str_dbg(smb_fname)));
1798 /* Request NO_OPLOCK instead. */
1799 oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
1803 /* Covert generic bits in the security descriptor. */
1805 security_acl_map_generic(sd->dacl, &file_generic_mapping);
1806 security_acl_map_generic(sd->sacl, &file_generic_mapping);
1810 * If it's a request for a directory open, deal with it separately.
1813 if (create_options & FILE_DIRECTORY_FILE) {
1815 if (create_options & FILE_NON_DIRECTORY_FILE) {
1816 status = NT_STATUS_INVALID_PARAMETER;
1820 /* Can't open a temp directory. IFS kit test. */
1821 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
1822 (file_attributes & FILE_ATTRIBUTE_TEMPORARY)) {
1823 status = NT_STATUS_INVALID_PARAMETER;
1828 * We will get a create directory here if the Win32
1829 * app specified a security descriptor in the
1830 * CreateDirectory() call.
1833 status = onefs_open_directory(
1836 smb_fname, /* fname */
1837 access_mask, /* access_mask */
1838 share_access, /* share_access */
1839 create_disposition, /* create_disposition*/
1840 create_options, /* create_options */
1841 file_attributes, /* file_attributes */
1848 * Ordinary file case.
1851 status = file_new(req, conn, &fsp);
1852 if(!NT_STATUS_IS_OK(status)) {
1857 * We're opening the stream element of a base_fsp
1858 * we already opened. Set up the base_fsp pointer.
1861 fsp->base_fsp = base_fsp;
1864 status = onefs_open_file_ntcreate(
1867 smb_fname, /* fname */
1868 access_mask, /* access_mask */
1869 share_access, /* share_access */
1870 create_disposition, /* create_disposition*/
1871 create_options, /* create_options */
1872 file_attributes, /* file_attributes */
1873 oplock_request, /* oplock_request */
1877 fsp_data); /* fsp_data */
1879 if(!NT_STATUS_IS_OK(status)) {
1880 file_free(req, fsp);
1884 if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
1886 /* A stream open never opens a directory */
1889 status = NT_STATUS_FILE_IS_A_DIRECTORY;
1894 * Fail the open if it was explicitly a non-directory
1898 if (create_options & FILE_NON_DIRECTORY_FILE) {
1899 status = NT_STATUS_FILE_IS_A_DIRECTORY;
1903 create_options |= FILE_DIRECTORY_FILE;
1905 status = onefs_open_directory(
1908 smb_fname, /* fname */
1909 access_mask, /* access_mask */
1910 share_access, /* share_access */
1911 create_disposition, /* create_disposition*/
1912 create_options, /* create_options */
1913 file_attributes, /* file_attributes */
1920 if (!NT_STATUS_IS_OK(status)) {
1924 fsp->base_fsp = base_fsp;
1928 if ((ea_list != NULL) && (info == FILE_WAS_CREATED)) {
1929 status = set_ea(conn, fsp, smb_fname, ea_list);
1930 if (!NT_STATUS_IS_OK(status)) {
1935 if (!fsp->is_directory && S_ISDIR(smb_fname->st.st_ex_mode)) {
1936 status = NT_STATUS_ACCESS_DENIED;
1940 /* Save the requested allocation size. */
1941 if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
1943 && (allocation_size > smb_fname->st.st_ex_size)) {
1944 fsp->initial_allocation_size = smb_roundup(
1945 fsp->conn, allocation_size);
1946 if (fsp->is_directory) {
1947 /* Can't set allocation size on a directory. */
1948 status = NT_STATUS_ACCESS_DENIED;
1951 if (vfs_allocate_file_space(
1952 fsp, fsp->initial_allocation_size) == -1) {
1953 status = NT_STATUS_DISK_FULL;
1957 fsp->initial_allocation_size = smb_roundup(
1958 fsp->conn, (uint64_t)smb_fname->st.st_ex_size);
1962 DEBUG(10, ("onefs_create_file_unixpath: info=%d\n", info));
1965 if (pinfo != NULL) {
1968 if ((fsp->fh != NULL) && (fsp->fh->fd != -1)) {
1969 SMB_VFS_FSTAT(fsp, &smb_fname->st);
1971 return NT_STATUS_OK;
1974 DEBUG(10, ("onefs_create_file_unixpath: %s\n", nt_errstr(status)));
1977 if (base_fsp && fsp->base_fsp == base_fsp) {
1979 * The close_file below will close
1984 close_file(req, fsp, ERROR_CLOSE);
1987 if (base_fsp != NULL) {
1988 close_file(req, base_fsp, ERROR_CLOSE);
1994 static void destroy_onefs_fsp_data(void *p_data)
1996 struct onefs_fsp_data *fsp_data = (struct onefs_fsp_data *)p_data;
1998 destroy_onefs_callback_record(fsp_data->oplock_callback_id);
2002 * SMB_VFS_CREATE_FILE interface to onefs.
2004 NTSTATUS onefs_create_file(vfs_handle_struct *handle,
2005 struct smb_request *req,
2006 uint16_t root_dir_fid,
2007 struct smb_filename *smb_fname,
2008 uint32_t access_mask,
2009 uint32_t share_access,
2010 uint32_t create_disposition,
2011 uint32_t create_options,
2012 uint32_t file_attributes,
2013 uint32_t oplock_request,
2014 uint64_t allocation_size,
2015 struct security_descriptor *sd,
2016 struct ea_list *ea_list,
2017 files_struct **result,
2020 connection_struct *conn = handle->conn;
2021 struct onefs_fsp_data fsp_data = {};
2022 int info = FILE_WAS_OPENED;
2023 files_struct *fsp = NULL;
2026 DEBUG(10,("onefs_create_file: access_mask = 0x%x "
2027 "file_attributes = 0x%x, share_access = 0x%x, "
2028 "create_disposition = 0x%x create_options = 0x%x "
2029 "oplock_request = 0x%x "
2030 "root_dir_fid = 0x%x, ea_list = 0x%p, sd = 0x%p, "
2032 (unsigned int)access_mask,
2033 (unsigned int)file_attributes,
2034 (unsigned int)share_access,
2035 (unsigned int)create_disposition,
2036 (unsigned int)create_options,
2037 (unsigned int)oplock_request,
2038 (unsigned int)root_dir_fid,
2039 ea_list, sd, smb_fname_str_dbg(smb_fname)));
2041 /* Get the file name if root_dir_fid was specified. */
2042 if (root_dir_fid != 0) {
2043 status = get_relative_fid_filename(conn, req, root_dir_fid,
2045 if (!NT_STATUS_IS_OK(status)) {
2050 /* All file access must go through check_name() */
2051 status = check_name(conn, smb_fname->base_name);
2052 if (!NT_STATUS_IS_OK(status)) {
2056 status = onefs_create_file_unixpath(
2059 smb_fname, /* fname */
2060 access_mask, /* access_mask */
2061 share_access, /* share_access */
2062 create_disposition, /* create_disposition*/
2063 create_options, /* create_options */
2064 file_attributes, /* file_attributes */
2065 oplock_request, /* oplock_request */
2066 allocation_size, /* allocation_size */
2068 ea_list, /* ea_list */
2071 &fsp_data); /* psbuf */
2073 if (!NT_STATUS_IS_OK(status)) {
2077 DEBUG(10, ("onefs_create_file: info=%d\n", info));
2080 * Setup private onefs_fsp_data. Currently the private data struct is
2081 * only used to store the oplock_callback_id so that when the file is
2082 * closed, the onefs_callback_record can be properly cleaned up in the
2083 * oplock_onefs sub-system.
2086 struct onefs_fsp_data *fsp_data_tmp = NULL;
2087 fsp_data_tmp = (struct onefs_fsp_data *)
2088 VFS_ADD_FSP_EXTENSION(handle, fsp, struct onefs_fsp_data,
2089 &destroy_onefs_fsp_data);
2091 if (fsp_data_tmp == NULL) {
2092 status = NT_STATUS_NO_MEMORY;
2096 *fsp_data_tmp = fsp_data;
2100 if (pinfo != NULL) {
2103 return NT_STATUS_OK;
2106 DEBUG(10, ("onefs_create_file: %s\n", nt_errstr(status)));
2109 close_file(req, fsp, ERROR_CLOSE);