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 status = get_full_smb_filename(talloc_tos(), smb_fname,
98 if (!NT_STATUS_IS_OK(status)) {
102 /* Check permissions */
105 * This code was changed after seeing a client open request
106 * containing the open mode of (DENY_WRITE/read-only) with
107 * the 'create if not exist' bit set. The previous code
108 * would fail to open the file read only on a read-only share
109 * as it was checking the flags parameter directly against O_RDONLY,
110 * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
114 if (!CAN_WRITE(conn)) {
115 /* It's a read-only share - fail if we wanted to write. */
116 if(accmode != O_RDONLY) {
117 DEBUG(3, ("Permission denied opening %s\n",
118 smb_fname_str_dbg(smb_fname)));
119 return NT_STATUS_ACCESS_DENIED;
120 } else if(flags & O_CREAT) {
121 /* We don't want to write - but we must make sure that
122 O_CREAT doesn't create the file if we have write
123 access into the directory.
126 local_flags &= ~O_CREAT;
131 * This little piece of insanity is inspired by the
132 * fact that an NT client can open a file for O_RDONLY,
133 * but set the create disposition to FILE_EXISTS_TRUNCATE.
134 * If the client *can* write to the file, then it expects to
135 * truncate the file, even though it is opening for readonly.
136 * Quicken uses this stupid trick in backup file creation...
137 * Thanks *greatly* to "David W. Chapman Jr." <dwcjr@inethouston.net>
138 * for helping track this one down. It didn't bite us in 2.0.x
139 * as we always opened files read-write in that release. JRA.
142 if ((accmode == O_RDONLY) && ((flags & O_TRUNC) == O_TRUNC)) {
143 DEBUG(10,("onefs_open_file: truncate requested on read-only "
144 "open for file %s\n", smb_fname_str_dbg(smb_fname)));
145 local_flags = (flags & ~O_ACCMODE)|O_RDWR;
148 #if defined(O_NONBLOCK) && defined(S_ISFIFO)
150 * We would block on opening a FIFO with no one else on the
151 * other end. Do what we used to do and add O_NONBLOCK to the
155 if (file_existed && S_ISFIFO(smb_fname->st.st_ex_mode)) {
156 local_flags |= O_NONBLOCK;
160 /* Don't create files with Microsoft wildcard characters. */
163 * wildcard characters are allowed in stream names
164 * only test the basefilename
166 wild = fsp->base_fsp->fsp_name;
170 if ((local_flags & O_CREAT) && !file_existed &&
173 * XXX: may need to remvoe this return...
175 * We dont think this check needs to exist. All it does is
176 * block creating files with Microsoft wildcards, which is
177 * fine if the creation originated from NFS or locally and
178 * then was copied via Samba.
180 DEBUG(1, ("onefs_open_file: creating file with wildcard: %s\n",
181 smb_fname_str_dbg(smb_fname)));
182 return NT_STATUS_OBJECT_NAME_INVALID;
185 /* Actually do the open */
189 * Never follow symlinks on a POSIX client. The
190 * client should be doing this.
193 if (fsp->posix_open || !lp_symlinks(SNUM(conn))) {
197 /* Setup a onefs-style smb_fname struct. */
198 status = onefs_stream_prep_smb_fname(talloc_tos(), smb_fname,
200 if (!NT_STATUS_IS_OK(status)) {
204 /* If it's a stream pass in the base_fd */
205 if ((conn->fs_capabilities & FILE_NAMED_STREAMS) &&
206 is_ntfs_stream_smb_fname(smb_fname_onefs)) {
207 SMB_ASSERT(fsp->base_fsp);
209 DEBUG(10, ("Opening a stream: base=%s(%d), stream=%s\n",
210 smb_fname_onefs->base_name, fsp->base_fsp->fh->fd,
211 smb_fname_onefs->stream_name));
213 base_fd = fsp->base_fsp->fh->fd;
216 fsp->fh->fd = onefs_sys_create_file(conn,
218 smb_fname_onefs->stream_name != NULL ?
219 smb_fname_onefs->stream_name :
220 smb_fname_onefs->base_name,
232 TALLOC_FREE(smb_fname_onefs);
234 if (fsp->fh->fd == -1) {
235 if (errno == EMFILE) {
236 static time_t last_warned = 0L;
238 if (time((time_t *) NULL) > last_warned) {
239 DEBUG(0, ("Too many open files, unable "
240 "to open more! smbd's max "
241 "open files = %d, also check "
242 "sysctl kern.maxfiles and "
243 "sysctl kern.maxfilesperproc\n",
244 lp_max_open_files()));
245 last_warned = time((time_t *) NULL);
249 status = map_nt_error_from_unix(errno);
250 DEBUG(3, ("Error opening file %s (%s) (local_flags=%d) "
251 "(flags=%d)\n", smb_fname_str_dbg(smb_fname),
252 strerror(errno), local_flags, flags));
256 if ((local_flags & O_CREAT) && !file_existed) {
258 /* Inherit the ACL if required */
259 if (lp_inherit_perms(SNUM(conn))) {
260 inherit_access_posix_acl(conn, parent_dir, path,
264 /* Change the owner if required. */
265 if (lp_inherit_owner(SNUM(conn))) {
266 change_file_owner_to_parent(conn, parent_dir,
270 notify_fname(conn, NOTIFY_ACTION_ADDED,
271 FILE_NOTIFY_CHANGE_FILE_NAME, path);
277 if (fsp->fh->fd == -1) {
278 ret = SMB_VFS_STAT(conn, smb_fname);
280 ret = SMB_VFS_FSTAT(fsp, &smb_fname->st);
281 /* If we have an fd, this stat should succeed. */
283 DEBUG(0, ("Error doing fstat on open file %s "
285 smb_fname_str_dbg(smb_fname),
290 /* For a non-io open, this stat failing means file not found. JRA */
292 status = map_nt_error_from_unix(errno);
299 * POSIX allows read-only opens of directories. We don't
300 * want to do this (we use a different code path for this)
301 * so catch a directory open and return an EISDIR. JRA.
304 if(S_ISDIR(smb_fname->st.st_ex_mode)) {
307 return NT_STATUS_FILE_IS_A_DIRECTORY;
310 fsp->mode = smb_fname->st.st_ex_mode;
311 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
312 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
313 fsp->file_pid = req ? req->smbpid : 0;
314 fsp->can_lock = True;
315 fsp->can_read = (access_mask & (FILE_READ_DATA)) ? True : False;
316 if (!CAN_WRITE(conn)) {
317 fsp->can_write = False;
319 fsp->can_write = (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ?
322 fsp->print_file = False;
323 fsp->modified = False;
324 fsp->sent_oplock_break = NO_BREAK_SENT;
325 fsp->is_directory = False;
326 if (conn->aio_write_behind_list &&
327 is_in_path(path, conn->aio_write_behind_list, conn->case_sensitive)) {
328 fsp->aio_write_behind = True;
331 string_set(&fsp->fsp_name, path);
332 fsp->wcp = NULL; /* Write cache pointer. */
334 DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
335 conn->server_info->unix_name,
337 BOOLSTR(fsp->can_read), BOOLSTR(fsp->can_write),
338 conn->num_files_open));
344 /****************************************************************************
345 Handle the 1 second delay in returning a SHARING_VIOLATION error.
346 ****************************************************************************/
348 static void defer_open(struct share_mode_lock *lck,
349 struct timeval request_time,
350 struct timeval timeout,
351 struct smb_request *req,
352 struct deferred_open_record *state)
358 for (i=0; i<lck->num_share_modes; i++) {
359 struct share_mode_entry *e = &lck->share_modes[i];
361 if (!is_deferred_open_entry(e)) {
365 if (procid_is_me(&e->pid) && (e->op_mid == req->mid)) {
366 DEBUG(0, ("Trying to defer an already deferred "
367 "request: mid=%d, exiting\n", req->mid));
368 exit_server("attempt to defer a deferred request");
372 /* End paranoia check */
374 DEBUG(10,("defer_open_sharing_error: time [%u.%06u] adding deferred "
375 "open entry for mid %u\n",
376 (unsigned int)request_time.tv_sec,
377 (unsigned int)request_time.tv_usec,
378 (unsigned int)req->mid));
380 if (!push_deferred_smb_message(req, request_time, timeout,
381 (char *)state, sizeof(*state))) {
382 exit_server("push_deferred_smb_message failed");
384 add_deferred_open(lck, req->mid, request_time, state->id);
387 static void schedule_defer_open(struct share_mode_lock *lck,
388 struct timeval request_time,
389 struct smb_request *req)
391 struct deferred_open_record state;
393 /* This is a relative time, added to the absolute
394 request_time value to get the absolute timeout time.
395 Note that if this is the second or greater time we enter
396 this codepath for this particular request mid then
397 request_time is left as the absolute time of the *first*
398 time this request mid was processed. This is what allows
399 the request to eventually time out. */
401 struct timeval timeout;
403 /* Normally the smbd we asked should respond within
404 * OPLOCK_BREAK_TIMEOUT seconds regardless of whether
405 * the client did, give twice the timeout as a safety
406 * measure here in case the other smbd is stuck
410 * On OneFS, the kernel will always send an oplock_revoked message
411 * before this timeout is hit.
413 timeout = timeval_set(OPLOCK_BREAK_TIMEOUT*10, 0);
415 /* Nothing actually uses state.delayed_for_oplocks
416 but it's handy to differentiate in debug messages
417 between a 30 second delay due to oplock break, and
418 a 1 second delay for share mode conflicts. */
420 state.delayed_for_oplocks = True;
421 state.failed = false;
424 if (!request_timed_out(request_time, timeout)) {
425 defer_open(lck, request_time, timeout, req, &state);
429 /****************************************************************************
430 Open a file with a share mode. Passed in an already created files_struct.
431 ****************************************************************************/
432 NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
433 struct smb_request *req,
434 struct smb_filename *smb_fname,
437 uint32 create_disposition,
438 uint32 create_options,
439 uint32 new_dos_attributes,
441 struct security_descriptor *sd,
444 struct onefs_fsp_data *fsp_data)
448 bool file_existed = VALID_STAT(smb_fname->st);
449 bool def_acl = False;
450 bool posix_open = False;
451 bool new_file_created = False;
452 bool clear_ads = False;
454 mode_t new_unx_mode = (mode_t)0;
455 mode_t unx_mode = (mode_t)0;
457 uint32 existing_dos_attributes = 0;
458 struct pending_message_list *pml = NULL;
459 struct timeval request_time = timeval_zero();
460 struct share_mode_lock *lck = NULL;
461 uint32 open_access_mask = access_mask;
466 uint64_t oplock_callback_id = 0;
467 uint32 createfile_attributes = 0;
472 status = get_full_smb_filename(talloc_tos(), smb_fname,
474 if (!NT_STATUS_IS_OK(status)) {
480 * Printers are handled completely differently.
481 * Most of the passed parameters are ignored.
485 *pinfo = FILE_WAS_CREATED;
488 DEBUG(10, ("onefs_open_file_ntcreate: printer open fname=%s\n",
489 smb_fname_str_dbg(smb_fname)));
491 return print_fsp_open(req, conn, fname, req->vuid, fsp,
495 if (!parent_dirname(talloc_tos(), smb_fname->base_name, &parent_dir,
497 return NT_STATUS_NO_MEMORY;
500 if (new_dos_attributes & FILE_FLAG_POSIX_SEMANTICS) {
502 unx_mode = (mode_t)(new_dos_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
503 new_dos_attributes = 0;
505 /* We add aARCH to this as this mode is only used if the file is
507 unx_mode = unix_mode(conn, new_dos_attributes | aARCH, fname,
511 DEBUG(10,("onefs_open_file_ntcreate: fname=%s, dos_attrs=0x%x "
512 "access_mask=0x%x share_access=0x%x "
513 "create_disposition = 0x%x create_options=0x%x "
514 "unix mode=0%o oplock_request=0x%x\n",
515 smb_fname_str_dbg(smb_fname), new_dos_attributes,
516 access_mask, share_access, create_disposition,
517 create_options, unx_mode, oplock_request));
520 * Any non-stat-only open has the potential to contend oplocks, which
521 * means to avoid blocking in the kernel (which is unacceptable), the
522 * open must be deferred. In order to defer opens, req must not be
523 * NULL. The known cases of calling with a NULL req:
525 * 1. Open the base file of a stream: Always done stat-only
527 * 2. open_file_fchmod(), which is called from 3 places:
528 * A. try_chown: Posix acls only. Never called on onefs.
529 * B. set_ea_dos_attributes: Can't be called from onefs, because
530 * SMB_VFS_SETXATTR return ENOSYS.
531 * C. file_set_dos_mode: This would only happen if the "dos
532 * filemode" smb.conf parameter is set to yes. We ship with
533 * it off, but if a customer were to turn it on it would be
536 if (req == NULL && !is_stat_open(access_mask) &&
537 !is_ntfs_stream_smb_fname(smb_fname)) {
538 smb_panic("NULL req on a non-stat-open!");
541 if ((req == NULL) && ((oplock_request & INTERNAL_OPEN_ONLY) == 0)) {
542 DEBUG(0, ("No smb request but not an internal only open!\n"));
543 return NT_STATUS_INTERNAL_ERROR;
547 * Only non-internal opens can be deferred at all
551 && ((pml = get_open_deferred_message(req->mid)) != NULL)) {
552 struct deferred_open_record *state =
553 (struct deferred_open_record *)pml->private_data.data;
555 /* Remember the absolute time of the original
556 request with this mid. We'll use it later to
557 see if this has timed out. */
559 request_time = pml->request_time;
561 /* Remove the deferred open entry under lock. */
562 lck = get_share_mode_lock(talloc_tos(), state->id, NULL, NULL,
565 DEBUG(0, ("could not get share mode lock\n"));
567 del_deferred_open_entry(lck, req->mid);
571 /* Ensure we don't reprocess this message. */
572 remove_deferred_open_smb_message(req->mid);
575 * When receiving a semlock_async_failure message, the
576 * deferred open will be marked as "failed". Returning
580 DEBUG(0, ("onefs_open_file_ntcreate: "
581 "semlock_async_failure detected!\n"));
582 return NT_STATUS_INTERNAL_ERROR;
586 status = check_name(conn, smb_fname->base_name);
587 if (!NT_STATUS_IS_OK(status)) {
592 new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
594 existing_dos_attributes = dos_mode(conn, fname,
599 /* Setup dos_attributes to be set by ifs_createfile */
600 if (lp_store_dos_attributes(SNUM(conn))) {
601 createfile_attributes = (new_dos_attributes | aARCH) &
602 ~(FILE_ATTRIBUTE_NONINDEXED | FILE_ATTRIBUTE_COMPRESSED);
605 /* Ignore oplock requests if oplocks are disabled. */
606 if (!lp_oplocks(SNUM(conn)) || global_client_failed_oplock_break ||
607 IS_VETO_OPLOCK_PATH(conn, smb_fname->base_name)) {
608 /* Mask off everything except the private Samba bits. */
609 oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
612 /* this is for OS/2 long file names - say we don't support them */
613 if (!lp_posix_pathnames() && strstr(smb_fname->base_name,".+,;=[].")) {
614 /* OS/2 Workplace shell fix may be main code stream in a later
616 DEBUG(5,("onefs_open_file_ntcreate: OS/2 long filenames are "
617 "not supported.\n"));
618 if (use_nt_status()) {
619 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
621 return NT_STATUS_DOS(ERRDOS, ERRcannotopen);
624 switch( create_disposition ) {
626 * Currently we're using FILE_SUPERSEDE as the same as
627 * FILE_OVERWRITE_IF but they really are
628 * different. FILE_SUPERSEDE deletes an existing file
629 * (requiring delete access) then recreates it.
633 * @todo: Clear all file attributes?
634 * http://www.osronline.com/article.cfm?article=302
635 * create if not exist, trunc if exist
637 * If file exists replace/overwrite. If file doesn't
640 flags2 |= (O_CREAT | O_TRUNC);
644 case FILE_OVERWRITE_IF:
645 /* If file exists replace/overwrite. If file doesn't
647 flags2 |= (O_CREAT | O_TRUNC);
652 /* If file exists open. If file doesn't exist error. */
654 DEBUG(5,("onefs_open_file_ntcreate: FILE_OPEN "
655 "requested for file %s and file "
657 smb_fname_str_dbg(smb_fname)));
659 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
664 /* If file exists overwrite. If file doesn't exist
667 DEBUG(5, ("onefs_open_file_ntcreate: "
668 "FILE_OVERWRITE requested for file "
669 "%s and file doesn't exist.\n",
670 smb_fname_str_dbg(smb_fname)));
672 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
679 /* If file exists error. If file doesn't exist
682 DEBUG(5, ("onefs_open_file_ntcreate: "
683 "FILE_CREATE requested for file %s "
684 "and file already exists.\n",
685 smb_fname_str_dbg(smb_fname)));
686 if (S_ISDIR(smb_fname->st.st_ex_mode)) {
691 return map_nt_error_from_unix(errno);
693 flags2 |= (O_CREAT|O_EXCL);
697 /* If file exists open. If file doesn't exist
703 return NT_STATUS_INVALID_PARAMETER;
706 /* Match attributes on file exists and overwrite. */
707 if (!posix_open && file_existed &&
708 ((create_disposition == FILE_OVERWRITE) ||
709 (create_disposition == FILE_OVERWRITE_IF))) {
710 if (!open_match_attributes(conn, existing_dos_attributes,
712 smb_fname->st.st_ex_mode,
713 unx_mode, &new_unx_mode)) {
714 DEBUG(5, ("onefs_open_file_ntcreate: attributes "
715 "missmatch for file %s (%x %x) (0%o, 0%o)\n",
716 smb_fname_str_dbg(smb_fname),
717 existing_dos_attributes,
719 (unsigned int)smb_fname->st.st_ex_mode,
720 (unsigned int)unx_mode ));
722 return NT_STATUS_ACCESS_DENIED;
727 * OneFS understands MAXIMUM_ALLOWED_ACCESS, so only hack the
728 * access_mask, but leave the MAA for the actual open in
731 open_access_mask = access_mask;
732 if (open_access_mask & MAXIMUM_ALLOWED_ACCESS) {
733 access_mask |= FILE_GENERIC_ALL;
736 /* Convert GENERIC bits to specific bits. */
737 se_map_generic(&access_mask, &file_generic_mapping);
738 se_map_generic(&open_access_mask, &file_generic_mapping);
740 if ((flags2 & O_TRUNC) || (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE)) {
741 /* This will cause oplock breaks. */
742 open_access_mask |= FILE_WRITE_DATA;
745 DEBUG(10, ("onefs_open_file_ntcreate: fname=%s, after mapping "
746 "open_access_mask=%#x, access_mask=0x%x\n",
747 smb_fname_str_dbg(smb_fname), open_access_mask,
751 * Note that we ignore the append flag as append does not
752 * mean the same thing under DOS and Unix.
755 if ((access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ||
756 (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE)) {
759 * DENY_DOS opens are always underlying read-write on the
760 * file handle, no matter what the requested access mask
761 * says. Stock samba just sets the flags, but since
762 * ifs_createfile uses the access_mask, it must be updated as
763 * well. This allows BASE-DENY* to pass.
765 if (create_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) {
767 DEBUG(10,("onefs_open_file_ntcreate: deny_dos: "
768 "Adding O_RDWR to flags "
769 "(0x%x) and some READ bits to "
770 "open_access_mask (0x%x)\n",
771 flags, open_access_mask));
774 open_access_mask |= (FILE_READ_ATTRIBUTES |
775 FILE_READ_DATA | FILE_READ_EA | FILE_EXECUTE);
777 } else if (access_mask & (FILE_READ_ATTRIBUTES |
789 /* Currently we only look at FILE_WRITE_THROUGH for create options. */
791 if ((create_options & FILE_WRITE_THROUGH) &&
792 lp_strict_sync(SNUM(conn))) {
797 if (posix_open && (access_mask & FILE_APPEND_DATA)) {
801 if (!posix_open && !CAN_WRITE(conn)) {
803 * We should really return a permission denied error if either
804 * O_CREAT or O_TRUNC are set, but for compatibility with
805 * older versions of Samba we just AND them out.
807 flags2 &= ~(O_CREAT|O_TRUNC);
809 /* Deny DELETE_ACCESS explicitly if the share is read only. */
810 if (access_mask & DELETE_ACCESS) {
811 return map_nt_error_from_unix(EACCES);
815 /* Ensure we can't write on a read-only share or file. */
816 if (flags != O_RDONLY && file_existed &&
817 (!CAN_WRITE(conn) || IS_DOS_READONLY(existing_dos_attributes))) {
818 DEBUG(5, ("onefs_open_file_ntcreate: write access requested "
819 "for file %s on read only %s\n",
820 smb_fname_str_dbg(smb_fname),
821 !CAN_WRITE(conn) ? "share" : "file" ));
823 return NT_STATUS_ACCESS_DENIED;
826 DEBUG(10, ("fsp = %p\n", fsp));
828 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
829 fsp->share_access = share_access;
830 fsp->fh->private_options = create_options;
831 fsp->access_mask = open_access_mask; /* We change this to the
832 * requested access_mask after
833 * the open is done. */
834 fsp->posix_open = posix_open;
836 /* Ensure no SAMBA_PRIVATE bits can be set. */
837 fsp->oplock_type = (oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK);
839 if (timeval_is_zero(&request_time)) {
840 request_time = fsp->open_time;
844 struct timespec old_write_time = smb_fname->st.st_ex_mtime;
845 id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
847 lck = get_share_mode_lock(talloc_tos(), id,
849 fname, &old_write_time);
852 DEBUG(0, ("Could not get share mode lock\n"));
853 return NT_STATUS_SHARING_VIOLATION;
856 if (lck->delete_on_close) {
857 /* DELETE_PENDING is not deferred for a second */
859 return NT_STATUS_DELETE_PENDING;
863 SMB_ASSERT(!file_existed || (lck != NULL));
866 * Ensure we pay attention to default ACLs on directories. May be
867 * neccessary depending on ACL policies.
869 if ((flags2 & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
870 (def_acl = directory_has_default_acl(conn, parent_dir))) {
874 DEBUG(4,("calling onefs_open_file with flags=0x%X flags2=0x%X "
875 "mode=0%o, access_mask = 0x%x, open_access_mask = 0x%x\n",
876 (unsigned int)flags, (unsigned int)flags2,
877 (unsigned int)unx_mode, (unsigned int)access_mask,
878 (unsigned int)open_access_mask));
881 * Since the open is guaranteed to be stat only if req == NULL, a
882 * callback record is only needed if req != NULL.
885 SMB_ASSERT(fsp_data);
886 oplock_callback_id = onefs_oplock_wait_record(req->mid);
887 if (oplock_callback_id == 0) {
888 return NT_STATUS_NO_MEMORY;
892 * It is also already asserted it's either a stream or a
893 * stat-only open at this point.
895 SMB_ASSERT(fsp->oplock_type == NO_OPLOCK);
899 status = onefs_open_file(fsp,
912 createfile_attributes,
916 if (!NT_STATUS_IS_OK(status)) {
918 /* OneFS Oplock Handling */
919 if (errno == EINPROGRESS) {
923 struct deferred_open_record state;
924 struct timespec old_write_time;
926 old_write_time = smb_fname->st.st_ex_mtime;
928 DEBUG(3, ("Someone created file %s with an "
929 "oplock after we looked: Retrying\n",
930 smb_fname_str_dbg(smb_fname)));
932 * We hit the race that when we did the stat
933 * on the file it did not exist, and someone
934 * has created it in between the stat and the
935 * open_file() call. Just retry immediately.
937 id = vfs_file_id_from_sbuf(conn,
939 if (!(lck = get_share_mode_lock(talloc_tos(),
940 id, conn->connectpath, fname,
945 DEBUG(0, ("onefs_open_file_ntcreate: "
946 "Could not get share mode "
948 smb_fname_str_dbg(smb_fname)));
949 status = NT_STATUS_SHARING_VIOLATION;
950 goto cleanup_destroy;
953 state.delayed_for_oplocks = False;
957 defer_open(lck, request_time,
958 timeval_zero(), req, &state);
960 goto cleanup_destroy;
962 /* Waiting for an oplock */
963 DEBUG(5,("Async createfile because a client has an "
965 smb_fname_str_dbg(smb_fname)));
968 schedule_defer_open(lck, request_time, req);
972 /* Check for a sharing violation */
973 if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
974 uint32 can_access_mask;
975 bool can_access = True;
977 /* Check if this can be done with the deny_dos and fcb
980 /* Try to find dup fsp if possible. */
982 (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS|
983 NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) {
986 DEBUG(0, ("DOS open without an SMB "
988 status = NT_STATUS_INTERNAL_ERROR;
989 goto cleanup_destroy;
992 /* Use the client requested access mask here,
993 * not the one we open with. */
994 status = fcb_or_dos_open(req,
1005 if (NT_STATUS_IS_OK(status)) {
1007 *pinfo = FILE_WAS_OPENED;
1009 status = NT_STATUS_OK;
1015 * This next line is a subtlety we need for
1016 * MS-Access. If a file open will fail due to share
1017 * permissions and also for security (access) reasons,
1018 * we need to return the access failed error, not the
1019 * share error. We can't open the file due to kernel
1020 * oplock deadlock (it's possible we failed above on
1021 * the open_mode_check()) so use a userspace check.
1024 if (flags & O_RDWR) {
1025 can_access_mask = FILE_READ_DATA|FILE_WRITE_DATA;
1026 } else if (flags & O_WRONLY) {
1027 can_access_mask = FILE_WRITE_DATA;
1029 can_access_mask = FILE_READ_DATA;
1032 if (((can_access_mask & FILE_WRITE_DATA) &&
1033 !CAN_WRITE(conn)) ||
1034 !can_access_file_data(conn, smb_fname,
1040 * If we're returning a share violation, ensure we
1041 * cope with the braindead 1 second delay.
1043 if (!(oplock_request & INTERNAL_OPEN_ONLY) &&
1044 lp_defer_sharing_violations()) {
1045 struct timeval timeout;
1046 struct deferred_open_record state;
1049 /* this is a hack to speed up torture tests
1051 timeout_usecs = lp_parm_int(SNUM(conn),
1052 "smbd","sharedelay",
1053 SHARING_VIOLATION_USEC_WAIT);
1055 /* This is a relative time, added to the
1056 absolute request_time value to get the
1057 absolute timeout time. Note that if this
1058 is the second or greater time we enter this
1059 codepath for this particular request mid
1060 then request_time is left as the absolute
1061 time of the *first* time this request mid
1062 was processed. This is what allows the
1063 request to eventually time out. */
1065 timeout = timeval_set(0, timeout_usecs);
1067 /* Nothing actually uses
1068 state.delayed_for_oplocks but it's handy to
1069 differentiate in debug messages between a
1070 30 second delay due to oplock break, and a
1071 1 second delay for share mode conflicts. */
1073 state.delayed_for_oplocks = False;
1075 state.failed = false;
1078 && !request_timed_out(request_time,
1080 defer_open(lck, request_time, timeout,
1087 * We have detected a sharing violation here
1088 * so return the correct error code
1090 status = NT_STATUS_SHARING_VIOLATION;
1092 status = NT_STATUS_ACCESS_DENIED;
1095 goto cleanup_destroy;
1099 * Normal error, for example EACCES
1102 if (oplock_callback_id != 0) {
1103 destroy_onefs_callback_record(oplock_callback_id);
1110 fsp->oplock_type = granted_oplock;
1112 if (oplock_callback_id != 0) {
1113 onefs_set_oplock_callback(oplock_callback_id, fsp);
1114 fsp_data->oplock_callback_id = oplock_callback_id;
1116 SMB_ASSERT(fsp->oplock_type == NO_OPLOCK);
1119 if (!file_existed) {
1120 struct timespec old_write_time = smb_fname->st.st_ex_mtime;
1122 * Deal with the race condition where two smbd's detect the
1123 * file doesn't exist and do the create at the same time. One
1124 * of them will win and set a share mode, the other (ie. this
1125 * one) should check if the requested share mode for this
1126 * create is allowed.
1130 * Now the file exists and fsp is successfully opened,
1131 * fsp->dev and fsp->inode are valid and should replace the
1132 * dev=0,inode=0 from a non existent file. Spotted by
1133 * Nadav Danieli <nadavd@exanet.com>. JRA.
1138 lck = get_share_mode_lock(talloc_tos(), id,
1140 fname, &old_write_time);
1143 DEBUG(0, ("onefs_open_file_ntcreate: Could not get "
1144 "share mode lock for %s\n",
1145 smb_fname_str_dbg(smb_fname)));
1147 return NT_STATUS_SHARING_VIOLATION;
1150 if (lck->delete_on_close) {
1151 status = NT_STATUS_DELETE_PENDING;
1154 if (!NT_STATUS_IS_OK(status)) {
1155 struct deferred_open_record state;
1159 state.delayed_for_oplocks = False;
1162 /* Do it all over again immediately. In the second
1163 * round we will find that the file existed and handle
1164 * the DELETE_PENDING and FCB cases correctly. No need
1165 * to duplicate the code here. Essentially this is a
1166 * "goto top of this function", but don't tell
1170 defer_open(lck, request_time, timeval_zero(),
1178 * We exit this block with the share entry *locked*.....
1183 SMB_ASSERT(lck != NULL);
1185 /* Delete streams if create_disposition requires it */
1186 if (file_existed && clear_ads &&
1187 !is_ntfs_stream_smb_fname(smb_fname)) {
1188 status = delete_all_streams(conn, smb_fname->base_name);
1189 if (!NT_STATUS_IS_OK(status)) {
1196 /* note that we ignore failure for the following. It is
1197 basically a hack for NFS, and NFS will never set one of
1198 these only read them. Nobody but Samba can ever set a deny
1199 mode and we have already checked our more authoritative
1200 locking database for permission to set this deny mode. If
1201 the kernel refuses the operations then the kernel is wrong.
1202 note that GPFS supports it as well - jmcd */
1204 if (fsp->fh->fd != -1) {
1205 ret_flock = SMB_VFS_KERNEL_FLOCK(fsp, share_access);
1206 if(ret_flock == -1 ){
1210 return NT_STATUS_SHARING_VIOLATION;
1215 * At this point onwards, we can guarentee that the share entry
1216 * is locked, whether we created the file or not, and that the
1217 * deny mode is compatible with all current opens.
1220 /* Record the options we were opened with. */
1221 fsp->share_access = share_access;
1222 fsp->fh->private_options = create_options;
1224 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
1226 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
1229 /* stat opens on existing files don't get oplocks. */
1230 if (is_stat_open(open_access_mask)) {
1231 fsp->oplock_type = NO_OPLOCK;
1234 if (!(flags2 & O_TRUNC)) {
1235 info = FILE_WAS_OPENED;
1237 info = FILE_WAS_OVERWRITTEN;
1240 info = FILE_WAS_CREATED;
1248 * Setup the oplock info in both the shared memory and
1252 if ((fsp->oplock_type != NO_OPLOCK) &&
1253 (fsp->oplock_type != FAKE_LEVEL_II_OPLOCK)) {
1254 if (!set_file_oplock(fsp, fsp->oplock_type)) {
1255 /* Could not get the kernel oplock */
1256 fsp->oplock_type = NO_OPLOCK;
1260 if (fsp->oplock_type == LEVEL_II_OPLOCK &&
1261 (!lp_level2_oplocks(SNUM(conn)) ||
1262 !(global_client_caps & CAP_LEVEL_II_OPLOCKS))) {
1264 DEBUG(5, ("Downgrading level2 oplock on open "
1265 "because level2 oplocks = off\n"));
1267 release_file_oplock(fsp);
1270 if (info == FILE_WAS_OVERWRITTEN || info == FILE_WAS_CREATED ||
1271 info == FILE_WAS_SUPERSEDED) {
1272 new_file_created = True;
1275 set_share_mode(lck, fsp, conn->server_info->utok.uid, 0,
1278 /* Handle strange delete on close create semantics. */
1279 if (create_options & FILE_DELETE_ON_CLOSE) {
1280 status = can_set_delete_on_close(fsp, True, new_dos_attributes);
1282 if (!NT_STATUS_IS_OK(status)) {
1283 /* Remember to delete the mode we just added. */
1284 del_share_mode(lck, fsp);
1289 /* Note that here we set the *inital* delete on close flag,
1290 not the regular one. The magic gets handled in close. */
1291 fsp->initial_delete_on_close = True;
1295 * Take care of inherited ACLs on created files - if default ACL not
1297 * May be necessary depending on acl policies.
1299 if (!posix_open && !file_existed && !def_acl &&
1300 !(VALID_STAT(smb_fname->st) &&
1301 (smb_fname->st.st_ex_flags & SF_HASNTFSACL))) {
1303 int saved_errno = errno; /* We might get ENOSYS in the next
1306 if (SMB_VFS_FCHMOD_ACL(fsp, unx_mode) == -1 &&
1308 errno = saved_errno; /* Ignore ENOSYS */
1311 } else if (new_unx_mode) {
1315 /* Attributes need changing. File already existed. */
1318 int saved_errno = errno; /* We might get ENOSYS in the
1320 ret = SMB_VFS_FCHMOD_ACL(fsp, new_unx_mode);
1322 if (ret == -1 && errno == ENOSYS) {
1323 errno = saved_errno; /* Ignore ENOSYS */
1325 DEBUG(5, ("onefs_open_file_ntcreate: reset "
1326 "attributes of file %s to 0%o\n",
1327 smb_fname_str_dbg(smb_fname),
1328 (unsigned int)new_unx_mode));
1329 ret = 0; /* Don't do the fchmod below. */
1334 (SMB_VFS_FCHMOD(fsp, new_unx_mode) == -1))
1335 DEBUG(5, ("onefs_open_file_ntcreate: failed to reset "
1336 "attributes of file %s to 0%o\n",
1337 smb_fname_str_dbg(smb_fname),
1338 (unsigned int)new_unx_mode));
1341 /* If this is a successful open, we must remove any deferred open
1344 del_deferred_open_entry(lck, req->mid);
1348 return NT_STATUS_OK;
1352 /****************************************************************************
1353 Open a directory from an NT SMB call.
1354 ****************************************************************************/
1355 static NTSTATUS onefs_open_directory(connection_struct *conn,
1356 struct smb_request *req,
1357 struct smb_filename *smb_dname,
1359 uint32 share_access,
1360 uint32 create_disposition,
1361 uint32 create_options,
1362 uint32 file_attributes,
1363 struct security_descriptor *sd,
1364 files_struct **result,
1367 files_struct *fsp = NULL;
1368 struct share_mode_lock *lck = NULL;
1370 struct timespec mtimespec;
1373 bool posix_open = false;
1374 uint32 create_flags = 0;
1375 uint32 mode = lp_dir_mask(SNUM(conn));
1377 DEBUG(5, ("onefs_open_directory: opening directory %s, "
1378 "access_mask = 0x%x, "
1379 "share_access = 0x%x create_options = 0x%x, "
1380 "create_disposition = 0x%x, file_attributes = 0x%x\n",
1381 smb_fname_str_dbg(smb_dname), (unsigned int)access_mask,
1382 (unsigned int)share_access, (unsigned int)create_options,
1383 (unsigned int)create_disposition,
1384 (unsigned int)file_attributes));
1386 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
1387 (conn->fs_capabilities & FILE_NAMED_STREAMS) &&
1388 is_ntfs_stream_smb_fname(smb_dname)) {
1389 DEBUG(2, ("onefs_open_directory: %s is a stream name!\n",
1390 smb_fname_str_dbg(smb_dname)));
1391 return NT_STATUS_NOT_A_DIRECTORY;
1394 switch (create_disposition) {
1396 /* If directory exists open. If directory doesn't
1399 info = FILE_WAS_OPENED;
1402 /* If directory exists error. If directory doesn't
1404 create_flags = O_CREAT | O_EXCL;
1405 info = FILE_WAS_CREATED;
1408 /* If directory exists open. If directory doesn't
1411 /* Note: in order to return whether the directory was
1412 * opened or created, we first try to open and then try
1415 info = FILE_WAS_OPENED;
1417 case FILE_SUPERSEDE:
1418 case FILE_OVERWRITE:
1419 case FILE_OVERWRITE_IF:
1421 DEBUG(5, ("onefs_open_directory: invalid "
1422 "create_disposition 0x%x for directory %s\n",
1423 (unsigned int)create_disposition,
1424 smb_fname_str_dbg(smb_dname)));
1425 return NT_STATUS_INVALID_PARAMETER;
1429 * Check for write access to the share. Done in mkdir_internal() in
1432 if (!CAN_WRITE(conn) && (create_flags & O_CREAT)) {
1433 return NT_STATUS_ACCESS_DENIED;
1436 /* Get parent dirname */
1437 if (!parent_dirname(talloc_tos(), smb_dname->base_name, &parent_dir,
1439 return NT_STATUS_NO_MEMORY;
1442 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
1444 mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
1445 file_attributes = 0;
1447 mode = unix_mode(conn, aDIR, smb_dname->base_name, parent_dir);
1451 * The NONINDEXED and COMPRESSED bits seem to always be cleared on
1452 * directories, no matter if you specify that they should be set.
1455 ~(FILE_ATTRIBUTE_NONINDEXED | FILE_ATTRIBUTE_COMPRESSED);
1457 status = file_new(req, conn, &fsp);
1458 if(!NT_STATUS_IS_OK(status)) {
1463 * Actual open with retry magic to handle FILE_OPEN_IF which is
1464 * unique because the kernel won't tell us if the file was opened or
1468 fsp->fh->fd = onefs_sys_create_file(conn,
1470 smb_dname->base_name,
1475 create_flags | O_DIRECTORY,
1483 if (fsp->fh->fd == -1) {
1484 DEBUG(3, ("Error opening %s. Errno=%d (%s).\n",
1485 smb_fname_str_dbg(smb_dname), errno,
1487 SMB_ASSERT(errno != EINPROGRESS);
1489 if (create_disposition == FILE_OPEN_IF) {
1490 if (errno == ENOENT) {
1491 /* Try again, creating it this time. */
1492 create_flags = O_CREAT | O_EXCL;
1493 info = FILE_WAS_CREATED;
1495 } else if (errno == EEXIST) {
1496 /* Uggh. Try again again. */
1498 info = FILE_WAS_OPENED;
1503 /* Error cases below: */
1504 file_free(req, fsp);
1506 if ((errno == ENOENT) && (create_disposition == FILE_OPEN)) {
1507 DEBUG(5, ("onefs_open_directory: FILE_OPEN requested "
1508 "for directory %s and it doesn't "
1509 "exist.\n", smb_fname_str_dbg(smb_dname)));
1510 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1511 } else if ((errno == EEXIST) &&
1512 (create_disposition == FILE_CREATE)) {
1513 DEBUG(5, ("onefs_open_directory: FILE_CREATE "
1514 "requested for directory %s and it "
1515 "already exists.\n",
1516 smb_fname_str_dbg(smb_dname)));
1517 return NT_STATUS_OBJECT_NAME_COLLISION;
1518 } else if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
1519 /* Catch sharing violations. */
1520 return NT_STATUS_SHARING_VIOLATION;
1523 return map_nt_error_from_unix(errno);
1526 if (info == FILE_WAS_CREATED) {
1528 /* Pulled from mkdir_internal() */
1529 if (SMB_VFS_LSTAT(conn, smb_dname) == -1) {
1530 DEBUG(2, ("Could not stat directory '%s' just "
1532 smb_fname_str_dbg(smb_dname),
1534 return map_nt_error_from_unix(errno);
1537 if (!S_ISDIR(smb_dname->st.st_ex_mode)) {
1538 DEBUG(0, ("Directory just '%s' created is not a "
1540 smb_fname_str_dbg(smb_dname)));
1541 return NT_STATUS_ACCESS_DENIED;
1546 * Check if high bits should have been set, then (if
1547 * bits are missing): add them. Consider bits
1548 * automagically set by UNIX, i.e. SGID bit from
1551 if (mode & ~(S_IRWXU|S_IRWXG|S_IRWXO) &&
1552 (mode & ~smb_dname->st.st_ex_mode)) {
1553 SMB_VFS_CHMOD(conn, smb_dname->base_name,
1554 (smb_dname->st.st_ex_mode |
1555 (mode & ~smb_dname->st.st_ex_mode)));
1559 /* Change the owner if required. */
1560 if (lp_inherit_owner(SNUM(conn))) {
1561 change_dir_owner_to_parent(conn, parent_dir,
1562 smb_dname->base_name,
1566 notify_fname(conn, NOTIFY_ACTION_ADDED,
1567 FILE_NOTIFY_CHANGE_DIR_NAME,
1568 smb_dname->base_name);
1571 /* Stat the fd for Samba bookkeeping. */
1572 if(SMB_VFS_FSTAT(fsp, &smb_dname->st) != 0) {
1574 file_free(req, fsp);
1575 return map_nt_error_from_unix(errno);
1578 /* Setup the files_struct for it. */
1579 fsp->mode = smb_dname->st.st_ex_mode;
1580 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_dname->st);
1581 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
1582 fsp->file_pid = req ? req->smbpid : 0;
1583 fsp->can_lock = False;
1584 fsp->can_read = False;
1585 fsp->can_write = False;
1587 fsp->share_access = share_access;
1588 fsp->fh->private_options = create_options;
1590 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
1592 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
1593 fsp->print_file = False;
1594 fsp->modified = False;
1595 fsp->oplock_type = NO_OPLOCK;
1596 fsp->sent_oplock_break = NO_BREAK_SENT;
1597 fsp->is_directory = True;
1598 fsp->posix_open = posix_open;
1600 string_set(&fsp->fsp_name, smb_dname->base_name);
1602 mtimespec = smb_dname->st.st_ex_mtime;
1605 * Still set the samba share mode lock for correct delete-on-close
1606 * semantics and to make smbstatus more useful.
1608 lck = get_share_mode_lock(talloc_tos(), fsp->file_id,
1609 conn->connectpath, smb_dname->base_name,
1613 DEBUG(0, ("onefs_open_directory: Could not get share mode "
1614 "lock for %s\n", smb_fname_str_dbg(smb_dname)));
1616 file_free(req, fsp);
1617 return NT_STATUS_SHARING_VIOLATION;
1620 if (lck->delete_on_close) {
1623 file_free(req, fsp);
1624 return NT_STATUS_DELETE_PENDING;
1627 set_share_mode(lck, fsp, conn->server_info->utok.uid, 0, NO_OPLOCK);
1630 * For directories the delete on close bit at open time seems
1631 * always to be honored on close... See test 19 in Samba4 BASE-DELETE.
1633 if (create_options & FILE_DELETE_ON_CLOSE) {
1634 status = can_set_delete_on_close(fsp, True, 0);
1635 if (!NT_STATUS_IS_OK(status) &&
1636 !NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
1639 file_free(req, fsp);
1643 if (NT_STATUS_IS_OK(status)) {
1644 /* Note that here we set the *inital* delete on close flag,
1645 not the regular one. The magic gets handled in close. */
1646 fsp->initial_delete_on_close = True;
1657 return NT_STATUS_OK;
1661 * Wrapper around onefs_open_file_ntcreate and onefs_open_directory.
1663 static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
1664 struct smb_request *req,
1665 struct smb_filename *smb_fname,
1666 uint32_t access_mask,
1667 uint32_t share_access,
1668 uint32_t create_disposition,
1669 uint32_t create_options,
1670 uint32_t file_attributes,
1671 uint32_t oplock_request,
1672 uint64_t allocation_size,
1673 struct security_descriptor *sd,
1674 struct ea_list *ea_list,
1675 files_struct **result,
1677 struct onefs_fsp_data *fsp_data)
1679 int info = FILE_WAS_OPENED;
1680 files_struct *base_fsp = NULL;
1681 files_struct *fsp = NULL;
1684 DEBUG(10,("onefs_create_file_unixpath: access_mask = 0x%x "
1685 "file_attributes = 0x%x, share_access = 0x%x, "
1686 "create_disposition = 0x%x create_options = 0x%x "
1687 "oplock_request = 0x%x ea_list = 0x%p, sd = 0x%p, "
1689 (unsigned int)access_mask,
1690 (unsigned int)file_attributes,
1691 (unsigned int)share_access,
1692 (unsigned int)create_disposition,
1693 (unsigned int)create_options,
1694 (unsigned int)oplock_request,
1695 ea_list, sd, smb_fname_str_dbg(smb_fname)));
1697 if (create_options & FILE_OPEN_BY_FILE_ID) {
1698 status = NT_STATUS_NOT_SUPPORTED;
1702 if (create_options & NTCREATEX_OPTIONS_INVALID_PARAM_MASK) {
1703 status = NT_STATUS_INVALID_PARAMETER;
1708 SMB_ASSERT((oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK) ==
1710 oplock_request |= INTERNAL_OPEN_ONLY;
1713 if (lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE,
1714 PARM_IGNORE_SACLS, PARM_IGNORE_SACLS_DEFAULT)) {
1715 access_mask &= ~SYSTEM_SECURITY_ACCESS;
1718 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
1719 && (access_mask & DELETE_ACCESS)
1720 && !is_ntfs_stream_smb_fname(smb_fname)) {
1722 * We can't open a file with DELETE access if any of the
1723 * streams is open without FILE_SHARE_DELETE
1725 status = open_streams_for_delete(conn, smb_fname->base_name);
1727 if (!NT_STATUS_IS_OK(status)) {
1732 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
1733 && is_ntfs_stream_smb_fname(smb_fname)) {
1734 uint32 base_create_disposition;
1735 struct smb_filename *smb_fname_base = NULL;
1737 if (create_options & FILE_DIRECTORY_FILE) {
1738 status = NT_STATUS_NOT_A_DIRECTORY;
1742 switch (create_disposition) {
1744 base_create_disposition = FILE_OPEN;
1747 base_create_disposition = FILE_OPEN_IF;
1751 /* Create an smb_filename with stream_name == NULL. */
1752 status = create_synthetic_smb_fname(talloc_tos(),
1753 smb_fname->base_name,
1756 if (!NT_STATUS_IS_OK(status)) {
1760 if (SMB_VFS_STAT(conn, smb_fname_base) == -1) {
1761 DEBUG(10, ("Unable to stat stream: %s\n",
1762 smb_fname_str_dbg(smb_fname_base)));
1765 status = onefs_create_file_unixpath(
1768 smb_fname_base, /* fname */
1769 SYNCHRONIZE_ACCESS, /* access_mask */
1772 FILE_SHARE_DELETE), /* share_access */
1773 base_create_disposition, /* create_disposition*/
1774 0, /* create_options */
1775 file_attributes, /* file_attributes */
1776 NO_OPLOCK, /* oplock_request */
1777 0, /* allocation_size */
1780 &base_fsp, /* result */
1782 NULL); /* fsp_data */
1784 TALLOC_FREE(smb_fname_base);
1786 if (!NT_STATUS_IS_OK(status)) {
1787 DEBUG(10, ("onefs_create_file_unixpath for base %s "
1788 "failed: %s\n", smb_fname->base_name,
1789 nt_errstr(status)));
1794 * Testing against windows xp/2003/vista shows that oplocks
1795 * can actually be requested and granted on streams (see the
1796 * RAW-OPLOCK-STREAM1 smbtorture test).
1798 if ((oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK) !=
1800 DEBUG(5, ("Oplock(%d) being requested on a stream! "
1801 "Ignoring oplock request: fname=%s\n",
1802 oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK,
1803 smb_fname_str_dbg(smb_fname)));
1804 /* Request NO_OPLOCK instead. */
1805 oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
1809 /* Covert generic bits in the security descriptor. */
1811 security_acl_map_generic(sd->dacl, &file_generic_mapping);
1812 security_acl_map_generic(sd->sacl, &file_generic_mapping);
1816 * If it's a request for a directory open, deal with it separately.
1819 if (create_options & FILE_DIRECTORY_FILE) {
1821 if (create_options & FILE_NON_DIRECTORY_FILE) {
1822 status = NT_STATUS_INVALID_PARAMETER;
1826 /* Can't open a temp directory. IFS kit test. */
1827 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
1828 (file_attributes & FILE_ATTRIBUTE_TEMPORARY)) {
1829 status = NT_STATUS_INVALID_PARAMETER;
1834 * We will get a create directory here if the Win32
1835 * app specified a security descriptor in the
1836 * CreateDirectory() call.
1839 status = onefs_open_directory(
1842 smb_fname, /* fname */
1843 access_mask, /* access_mask */
1844 share_access, /* share_access */
1845 create_disposition, /* create_disposition*/
1846 create_options, /* create_options */
1847 file_attributes, /* file_attributes */
1854 * Ordinary file case.
1857 status = file_new(req, conn, &fsp);
1858 if(!NT_STATUS_IS_OK(status)) {
1863 * We're opening the stream element of a base_fsp
1864 * we already opened. Set up the base_fsp pointer.
1867 fsp->base_fsp = base_fsp;
1870 status = onefs_open_file_ntcreate(
1873 smb_fname, /* fname */
1874 access_mask, /* access_mask */
1875 share_access, /* share_access */
1876 create_disposition, /* create_disposition*/
1877 create_options, /* create_options */
1878 file_attributes, /* file_attributes */
1879 oplock_request, /* oplock_request */
1883 fsp_data); /* fsp_data */
1885 if(!NT_STATUS_IS_OK(status)) {
1886 file_free(req, fsp);
1890 if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
1892 /* A stream open never opens a directory */
1895 status = NT_STATUS_FILE_IS_A_DIRECTORY;
1900 * Fail the open if it was explicitly a non-directory
1904 if (create_options & FILE_NON_DIRECTORY_FILE) {
1905 status = NT_STATUS_FILE_IS_A_DIRECTORY;
1909 create_options |= FILE_DIRECTORY_FILE;
1911 status = onefs_open_directory(
1914 smb_fname, /* fname */
1915 access_mask, /* access_mask */
1916 share_access, /* share_access */
1917 create_disposition, /* create_disposition*/
1918 create_options, /* create_options */
1919 file_attributes, /* file_attributes */
1926 if (!NT_STATUS_IS_OK(status)) {
1930 fsp->base_fsp = base_fsp;
1934 if ((ea_list != NULL) && (info == FILE_WAS_CREATED)) {
1935 status = set_ea(conn, fsp, smb_fname, ea_list);
1936 if (!NT_STATUS_IS_OK(status)) {
1941 if (!fsp->is_directory && S_ISDIR(smb_fname->st.st_ex_mode)) {
1942 status = NT_STATUS_ACCESS_DENIED;
1946 /* Save the requested allocation size. */
1947 if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
1949 && (allocation_size > smb_fname->st.st_ex_size)) {
1950 fsp->initial_allocation_size = smb_roundup(
1951 fsp->conn, allocation_size);
1952 if (fsp->is_directory) {
1953 /* Can't set allocation size on a directory. */
1954 status = NT_STATUS_ACCESS_DENIED;
1957 if (vfs_allocate_file_space(
1958 fsp, fsp->initial_allocation_size) == -1) {
1959 status = NT_STATUS_DISK_FULL;
1963 fsp->initial_allocation_size = smb_roundup(
1964 fsp->conn, (uint64_t)smb_fname->st.st_ex_size);
1968 DEBUG(10, ("onefs_create_file_unixpath: info=%d\n", info));
1971 if (pinfo != NULL) {
1974 if ((fsp->fh != NULL) && (fsp->fh->fd != -1)) {
1975 SMB_VFS_FSTAT(fsp, &smb_fname->st);
1977 return NT_STATUS_OK;
1980 DEBUG(10, ("onefs_create_file_unixpath: %s\n", nt_errstr(status)));
1983 if (base_fsp && fsp->base_fsp == base_fsp) {
1985 * The close_file below will close
1990 close_file(req, fsp, ERROR_CLOSE);
1993 if (base_fsp != NULL) {
1994 close_file(req, base_fsp, ERROR_CLOSE);
2000 static void destroy_onefs_fsp_data(void *p_data)
2002 struct onefs_fsp_data *fsp_data = (struct onefs_fsp_data *)p_data;
2004 destroy_onefs_callback_record(fsp_data->oplock_callback_id);
2008 * SMB_VFS_CREATE_FILE interface to onefs.
2010 NTSTATUS onefs_create_file(vfs_handle_struct *handle,
2011 struct smb_request *req,
2012 uint16_t root_dir_fid,
2013 struct smb_filename *smb_fname,
2014 uint32_t access_mask,
2015 uint32_t share_access,
2016 uint32_t create_disposition,
2017 uint32_t create_options,
2018 uint32_t file_attributes,
2019 uint32_t oplock_request,
2020 uint64_t allocation_size,
2021 struct security_descriptor *sd,
2022 struct ea_list *ea_list,
2023 files_struct **result,
2026 connection_struct *conn = handle->conn;
2027 struct onefs_fsp_data fsp_data = {};
2028 int info = FILE_WAS_OPENED;
2029 files_struct *fsp = NULL;
2032 DEBUG(10,("onefs_create_file: access_mask = 0x%x "
2033 "file_attributes = 0x%x, share_access = 0x%x, "
2034 "create_disposition = 0x%x create_options = 0x%x "
2035 "oplock_request = 0x%x "
2036 "root_dir_fid = 0x%x, ea_list = 0x%p, sd = 0x%p, "
2038 (unsigned int)access_mask,
2039 (unsigned int)file_attributes,
2040 (unsigned int)share_access,
2041 (unsigned int)create_disposition,
2042 (unsigned int)create_options,
2043 (unsigned int)oplock_request,
2044 (unsigned int)root_dir_fid,
2045 ea_list, sd, smb_fname_str_dbg(smb_fname)));
2047 /* Get the file name if root_dir_fid was specified. */
2048 if (root_dir_fid != 0) {
2049 status = get_relative_fid_filename(conn, req, root_dir_fid,
2051 if (!NT_STATUS_IS_OK(status)) {
2056 /* All file access must go through check_name() */
2057 status = check_name(conn, smb_fname->base_name);
2058 if (!NT_STATUS_IS_OK(status)) {
2062 status = onefs_create_file_unixpath(
2065 smb_fname, /* fname */
2066 access_mask, /* access_mask */
2067 share_access, /* share_access */
2068 create_disposition, /* create_disposition*/
2069 create_options, /* create_options */
2070 file_attributes, /* file_attributes */
2071 oplock_request, /* oplock_request */
2072 allocation_size, /* allocation_size */
2074 ea_list, /* ea_list */
2077 &fsp_data); /* psbuf */
2079 if (!NT_STATUS_IS_OK(status)) {
2083 DEBUG(10, ("onefs_create_file: info=%d\n", info));
2086 * Setup private onefs_fsp_data. Currently the private data struct is
2087 * only used to store the oplock_callback_id so that when the file is
2088 * closed, the onefs_callback_record can be properly cleaned up in the
2089 * oplock_onefs sub-system.
2092 struct onefs_fsp_data *fsp_data_tmp = NULL;
2093 fsp_data_tmp = (struct onefs_fsp_data *)
2094 VFS_ADD_FSP_EXTENSION(handle, fsp, struct onefs_fsp_data,
2095 &destroy_onefs_fsp_data);
2097 if (fsp_data_tmp == NULL) {
2098 status = NT_STATUS_NO_MEMORY;
2102 *fsp_data_tmp = fsp_data;
2106 if (pinfo != NULL) {
2109 return NT_STATUS_OK;
2112 DEBUG(10, ("onefs_create_file: %s\n", nt_errstr(status)));
2115 close_file(req, fsp, ERROR_CLOSE);