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,
84 struct smb_filename *smb_fname_onefs = NULL;
85 NTSTATUS status = NT_STATUS_OK;
86 int accmode = (flags & O_ACCMODE);
87 int local_flags = flags;
88 bool file_existed = VALID_STAT(smb_fname->st);
95 /* Check permissions */
98 * This code was changed after seeing a client open request
99 * containing the open mode of (DENY_WRITE/read-only) with
100 * the 'create if not exist' bit set. The previous code
101 * would fail to open the file read only on a read-only share
102 * as it was checking the flags parameter directly against O_RDONLY,
103 * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
107 if (!CAN_WRITE(conn)) {
108 /* It's a read-only share - fail if we wanted to write. */
109 if(accmode != O_RDONLY) {
110 DEBUG(3, ("Permission denied opening %s\n",
111 smb_fname_str_dbg(smb_fname)));
112 return NT_STATUS_ACCESS_DENIED;
113 } else if(flags & O_CREAT) {
114 /* We don't want to write - but we must make sure that
115 O_CREAT doesn't create the file if we have write
116 access into the directory.
119 local_flags &= ~O_CREAT;
124 * This little piece of insanity is inspired by the
125 * fact that an NT client can open a file for O_RDONLY,
126 * but set the create disposition to FILE_EXISTS_TRUNCATE.
127 * If the client *can* write to the file, then it expects to
128 * truncate the file, even though it is opening for readonly.
129 * Quicken uses this stupid trick in backup file creation...
130 * Thanks *greatly* to "David W. Chapman Jr." <dwcjr@inethouston.net>
131 * for helping track this one down. It didn't bite us in 2.0.x
132 * as we always opened files read-write in that release. JRA.
135 if ((accmode == O_RDONLY) && ((flags & O_TRUNC) == O_TRUNC)) {
136 DEBUG(10,("onefs_open_file: truncate requested on read-only "
137 "open for file %s\n", smb_fname_str_dbg(smb_fname)));
138 local_flags = (flags & ~O_ACCMODE)|O_RDWR;
141 #if defined(O_NONBLOCK) && defined(S_ISFIFO)
143 * We would block on opening a FIFO with no one else on the
144 * other end. Do what we used to do and add O_NONBLOCK to the
148 if (file_existed && S_ISFIFO(smb_fname->st.st_ex_mode)) {
149 local_flags |= O_NONBLOCK;
153 /* Don't create files with Microsoft wildcard characters. */
156 * wildcard characters are allowed in stream names
157 * only test the basefilename
159 wild = fsp->base_fsp->fsp_name->base_name;
161 wild = smb_fname->base_name;
163 if ((local_flags & O_CREAT) && !file_existed &&
166 * XXX: may need to remvoe this return...
168 * We dont think this check needs to exist. All it does is
169 * block creating files with Microsoft wildcards, which is
170 * fine if the creation originated from NFS or locally and
171 * then was copied via Samba.
173 DEBUG(1, ("onefs_open_file: creating file with wildcard: %s\n",
174 smb_fname_str_dbg(smb_fname)));
175 return NT_STATUS_OBJECT_NAME_INVALID;
178 /* Actually do the open */
182 * Never follow symlinks on a POSIX client. The
183 * client should be doing this.
186 if (fsp->posix_open || !lp_symlinks(SNUM(conn))) {
190 /* Setup a onefs-style smb_fname struct. */
191 status = onefs_stream_prep_smb_fname(talloc_tos(), smb_fname,
193 if (!NT_STATUS_IS_OK(status)) {
197 /* If it's a stream pass in the base_fd */
198 if ((conn->fs_capabilities & FILE_NAMED_STREAMS) &&
199 is_ntfs_stream_smb_fname(smb_fname_onefs)) {
200 SMB_ASSERT(fsp->base_fsp);
202 DEBUG(10, ("Opening a stream: base=%s(%d), stream=%s\n",
203 smb_fname_onefs->base_name, fsp->base_fsp->fh->fd,
204 smb_fname_onefs->stream_name));
206 base_fd = fsp->base_fsp->fh->fd;
209 fsp->fh->fd = onefs_sys_create_file(conn,
211 smb_fname_onefs->stream_name != NULL ?
212 smb_fname_onefs->stream_name :
213 smb_fname_onefs->base_name,
225 TALLOC_FREE(smb_fname_onefs);
227 if (fsp->fh->fd == -1) {
228 if (errno == EMFILE) {
229 static time_t last_warned = 0L;
231 if (time((time_t *) NULL) > last_warned) {
232 DEBUG(0, ("Too many open files, unable "
233 "to open more! smbd's max "
234 "open files = %d, also check "
235 "sysctl kern.maxfiles and "
236 "sysctl kern.maxfilesperproc\n",
237 lp_max_open_files()));
238 last_warned = time((time_t *) NULL);
242 status = map_nt_error_from_unix(errno);
243 DEBUG(3, ("Error opening file %s (%s) (local_flags=%d) "
244 "(flags=%d)\n", smb_fname_str_dbg(smb_fname),
245 strerror(errno), local_flags, flags));
249 if ((local_flags & O_CREAT) && !file_existed) {
251 /* Inherit the ACL if required */
252 if (lp_inherit_perms(SNUM(conn))) {
253 inherit_access_posix_acl(conn, parent_dir,
254 smb_fname->base_name, unx_mode);
257 /* Change the owner if required. */
258 if (lp_inherit_owner(SNUM(conn))) {
259 change_file_owner_to_parent(conn, parent_dir,
263 notify_fname(conn, NOTIFY_ACTION_ADDED,
264 FILE_NOTIFY_CHANGE_FILE_NAME, smb_fname->base_name);
270 if (fsp->fh->fd == -1) {
271 ret = SMB_VFS_STAT(conn, smb_fname);
273 ret = SMB_VFS_FSTAT(fsp, &smb_fname->st);
274 /* If we have an fd, this stat should succeed. */
276 DEBUG(0, ("Error doing fstat on open file %s "
278 smb_fname_str_dbg(smb_fname),
283 /* For a non-io open, this stat failing means file not found. JRA */
285 status = map_nt_error_from_unix(errno);
292 * POSIX allows read-only opens of directories. We don't
293 * want to do this (we use a different code path for this)
294 * so catch a directory open and return an EISDIR. JRA.
297 if(S_ISDIR(smb_fname->st.st_ex_mode)) {
300 return NT_STATUS_FILE_IS_A_DIRECTORY;
303 fsp->mode = smb_fname->st.st_ex_mode;
304 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
305 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
306 fsp->file_pid = req ? req->smbpid : 0;
307 fsp->can_lock = True;
308 fsp->can_read = (access_mask & (FILE_READ_DATA)) ? True : False;
309 if (!CAN_WRITE(conn)) {
310 fsp->can_write = False;
312 fsp->can_write = (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ?
315 fsp->print_file = False;
316 fsp->modified = False;
317 fsp->sent_oplock_break = NO_BREAK_SENT;
318 fsp->is_directory = False;
319 if (conn->aio_write_behind_list &&
320 is_in_path(smb_fname->base_name, conn->aio_write_behind_list,
321 conn->case_sensitive)) {
322 fsp->aio_write_behind = True;
325 status = fsp_set_smb_fname(fsp, smb_fname);
326 if (!NT_STATUS_IS_OK(status)) {
328 errno = map_errno_from_nt_status(status);
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,
336 smb_fname_str_dbg(smb_fname),
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);
427 /* A delayed-for-oplocks deferred open timing out should only
428 * happen if there is a bug or extreme load, since we set the
429 * timeout to 300 seconds. */
430 DEBUG(0, ("Deferred open timeout! request_time=%d.%d, "
431 "mid=%d\n", request_time.tv_sec, request_time.tv_usec,
436 /****************************************************************************
437 Open a file with a share mode. Passed in an already created files_struct.
438 ****************************************************************************/
439 NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
440 struct smb_request *req,
441 struct smb_filename *smb_fname,
444 uint32 create_disposition,
445 uint32 create_options,
446 uint32 new_dos_attributes,
448 struct security_descriptor *sd,
451 struct onefs_fsp_data *fsp_data)
455 bool file_existed = VALID_STAT(smb_fname->st);
456 bool def_acl = False;
457 bool posix_open = False;
458 bool new_file_created = False;
459 bool clear_ads = False;
461 mode_t new_unx_mode = (mode_t)0;
462 mode_t unx_mode = (mode_t)0;
464 uint32 existing_dos_attributes = 0;
465 struct pending_message_list *pml = NULL;
466 struct timeval request_time = timeval_zero();
467 struct share_mode_lock *lck = NULL;
468 uint32 open_access_mask = access_mask;
473 uint64_t oplock_callback_id = 0;
474 uint32 createfile_attributes = 0;
480 * Printers are handled completely differently.
481 * Most of the passed parameters are ignored.
485 *pinfo = FILE_WAS_CREATED;
488 DEBUG(10, ("onefs_open_file_ntcreate: printer open fname=%s\n",
489 smb_fname_str_dbg(smb_fname)));
491 return print_fsp_open(req, conn, smb_fname->base_name,
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,
508 smb_fname, parent_dir);
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, smb_fname);
598 /* Setup dos_attributes to be set by ifs_createfile */
599 if (lp_store_dos_attributes(SNUM(conn))) {
600 createfile_attributes = (new_dos_attributes | aARCH) &
601 ~(FILE_ATTRIBUTE_NONINDEXED | FILE_ATTRIBUTE_COMPRESSED);
604 /* Ignore oplock requests if oplocks are disabled. */
605 if (!lp_oplocks(SNUM(conn)) || global_client_failed_oplock_break ||
606 is_in_path(smb_fname->base_name, conn->veto_oplock_list,
607 get_Protocol(), conn->case_sensitive)) {
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->share_access = share_access;
829 fsp->fh->private_options = create_options;
830 fsp->access_mask = open_access_mask; /* We change this to the
831 * requested access_mask after
832 * the open is done. */
833 fsp->posix_open = posix_open;
835 /* Ensure no SAMBA_PRIVATE bits can be set. */
836 fsp->oplock_type = (oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK);
838 if (timeval_is_zero(&request_time)) {
839 request_time = fsp->open_time;
843 struct timespec old_write_time = smb_fname->st.st_ex_mtime;
844 id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
846 lck = get_share_mode_lock(talloc_tos(), id,
848 smb_fname, &old_write_time);
851 DEBUG(0, ("Could not get share mode lock\n"));
852 return NT_STATUS_SHARING_VIOLATION;
855 if (lck->delete_on_close) {
856 /* DELETE_PENDING is not deferred for a second */
858 return NT_STATUS_DELETE_PENDING;
862 SMB_ASSERT(!file_existed || (lck != NULL));
865 * Ensure we pay attention to default ACLs on directories. May be
866 * neccessary depending on ACL policies.
868 if ((flags2 & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
869 (def_acl = directory_has_default_acl(conn, parent_dir))) {
873 DEBUG(4,("calling onefs_open_file with flags=0x%X flags2=0x%X "
874 "mode=0%o, access_mask = 0x%x, open_access_mask = 0x%x\n",
875 (unsigned int)flags, (unsigned int)flags2,
876 (unsigned int)unx_mode, (unsigned int)access_mask,
877 (unsigned int)open_access_mask));
880 * Since the open is guaranteed to be stat only if req == NULL, a
881 * callback record is only needed if req != NULL.
884 SMB_ASSERT(fsp_data);
885 oplock_callback_id = onefs_oplock_wait_record(req->mid);
886 if (oplock_callback_id == 0) {
887 return NT_STATUS_NO_MEMORY;
891 * It is also already asserted it's either a stream or a
892 * stat-only open at this point.
894 SMB_ASSERT(fsp->oplock_type == NO_OPLOCK);
896 /* The kernel and Samba's version of stat-only differs
897 * slightly: The kernel doesn't think its stat-only if we're
898 * truncating. We'd better have a req in order to defer the
900 SMB_ASSERT(!((flags|flags2) & O_TRUNC));
904 status = onefs_open_file(fsp,
917 createfile_attributes,
921 if (!NT_STATUS_IS_OK(status)) {
923 /* OneFS Oplock Handling */
924 if (errno == EINPROGRESS) {
926 /* If we get EINPROGRESS, the kernel will send us an
927 * asynchronous semlock event back. Ensure we can defer
928 * the open, by asserting req. */
933 * We hit the race that when we did the stat
934 * on the file it did not exist, and someone
935 * has created it in between the stat and the
936 * open_file() call. Defer our open waiting,
937 * to break the oplock of the first opener.
940 struct timespec old_write_time;
942 DEBUG(3, ("Someone created file %s with an "
943 "oplock after we looked: Retrying\n",
944 smb_fname_str_dbg(smb_fname)));
946 * We hit the race that when we did the stat
947 * on the file it did not exist, and someone
948 * has created it in between the stat and the
949 * open_file() call. Just retry immediately.
951 id = vfs_file_id_from_sbuf(conn,
953 if (!(lck = get_share_mode_lock(talloc_tos(),
954 id, conn->connectpath, smb_fname,
959 DEBUG(0, ("onefs_open_file_ntcreate: "
960 "Could not get share mode "
962 smb_fname_str_dbg(smb_fname)));
963 status = NT_STATUS_SHARING_VIOLATION;
965 /* XXXZLK: This will cause us to get a
966 * semlock event when we aren't
968 goto cleanup_destroy;
971 schedule_defer_open(lck, request_time, req);
974 /* Waiting for an oplock */
975 DEBUG(5,("Async createfile because a client has an "
977 smb_fname_str_dbg(smb_fname)));
980 schedule_defer_open(lck, request_time, req);
984 /* Check for a sharing violation */
985 if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
986 uint32 can_access_mask;
987 bool can_access = True;
989 /* If we raced on open we may not have a valid file_id
990 * or stat buf. Get them again. */
991 if (SMB_VFS_STAT(conn, fname, psbuf) == -1) {
992 DEBUG(0,("Error doing stat on file %s "
993 "(%s)\n", fname, strerror(errno)));
994 status = NT_STATUS_SHARING_VIOLATION;
995 goto cleanup_destroy;
997 id = vfs_file_id_from_sbuf(conn, psbuf);
999 /* Check if this can be done with the deny_dos and fcb
1002 /* Try to find dup fsp if possible. */
1003 if (create_options &
1004 (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS|
1005 NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) {
1008 DEBUG(0, ("DOS open without an SMB "
1010 status = NT_STATUS_INTERNAL_ERROR;
1011 goto cleanup_destroy;
1014 /* Use the client requested access mask here,
1015 * not the one we open with. */
1016 status = fcb_or_dos_open(req,
1027 if (NT_STATUS_IS_OK(status)) {
1029 *pinfo = FILE_WAS_OPENED;
1031 status = NT_STATUS_OK;
1037 * This next line is a subtlety we need for
1038 * MS-Access. If a file open will fail due to share
1039 * permissions and also for security (access) reasons,
1040 * we need to return the access failed error, not the
1041 * share error. We can't open the file due to kernel
1042 * oplock deadlock (it's possible we failed above on
1043 * the open_mode_check()) so use a userspace check.
1046 if (flags & O_RDWR) {
1047 can_access_mask = FILE_READ_DATA|FILE_WRITE_DATA;
1048 } else if (flags & O_WRONLY) {
1049 can_access_mask = FILE_WRITE_DATA;
1051 can_access_mask = FILE_READ_DATA;
1054 if (((can_access_mask & FILE_WRITE_DATA) &&
1055 !CAN_WRITE(conn)) ||
1056 !can_access_file_data(conn, smb_fname,
1062 * If we're returning a share violation, ensure we
1063 * cope with the braindead 1 second delay.
1065 if (!(oplock_request & INTERNAL_OPEN_ONLY) &&
1066 lp_defer_sharing_violations()) {
1067 struct timeval timeout;
1068 struct deferred_open_record state;
1071 /* this is a hack to speed up torture tests
1073 timeout_usecs = lp_parm_int(SNUM(conn),
1074 "smbd","sharedelay",
1075 SHARING_VIOLATION_USEC_WAIT);
1077 /* This is a relative time, added to the
1078 absolute request_time value to get the
1079 absolute timeout time. Note that if this
1080 is the second or greater time we enter this
1081 codepath for this particular request mid
1082 then request_time is left as the absolute
1083 time of the *first* time this request mid
1084 was processed. This is what allows the
1085 request to eventually time out. */
1087 timeout = timeval_set(0, timeout_usecs);
1089 /* Nothing actually uses
1090 state.delayed_for_oplocks but it's handy to
1091 differentiate in debug messages between a
1092 30 second delay due to oplock break, and a
1093 1 second delay for share mode conflicts. */
1095 state.delayed_for_oplocks = False;
1097 state.failed = false;
1100 * We hit the race that when we did the stat
1101 * on the file it did not exist, and someone
1102 * has created it in between the stat and the
1103 * open_file() call. Retrieve the share_mode
1104 * lock on the newly opened file so we can
1105 * defer our request.
1108 struct timespec old_write_time;
1109 old_write_time = get_mtimespec(psbuf);
1111 lck = get_share_mode_lock(talloc_tos(),
1112 id, conn->connectpath, fname,
1116 ("onefs_open_file_ntcreate:"
1117 " Could not get share "
1118 "mode lock for %s\n",
1120 /* This will cause us to return
1121 * immediately skipping the
1122 * the 1 second delay, which
1123 * isn't a big deal */
1124 status = NT_STATUS_SHARING_VIOLATION;
1125 goto cleanup_destroy;
1129 if ((req != NULL) &&
1130 !request_timed_out(request_time, timeout))
1132 defer_open(lck, request_time, timeout,
1139 * We have detected a sharing violation here
1140 * so return the correct error code
1142 status = NT_STATUS_SHARING_VIOLATION;
1144 status = NT_STATUS_ACCESS_DENIED;
1147 goto cleanup_destroy;
1151 * Normal error, for example EACCES
1154 if (oplock_callback_id != 0) {
1155 destroy_onefs_callback_record(oplock_callback_id);
1162 fsp->oplock_type = granted_oplock;
1164 if (oplock_callback_id != 0) {
1165 onefs_set_oplock_callback(oplock_callback_id, fsp);
1166 fsp_data->oplock_callback_id = oplock_callback_id;
1168 SMB_ASSERT(fsp->oplock_type == NO_OPLOCK);
1171 if (!file_existed) {
1172 struct timespec old_write_time = smb_fname->st.st_ex_mtime;
1174 * Deal with the race condition where two smbd's detect the
1175 * file doesn't exist and do the create at the same time. One
1176 * of them will win and set a share mode, the other (ie. this
1177 * one) should check if the requested share mode for this
1178 * create is allowed.
1182 * Now the file exists and fsp is successfully opened,
1183 * fsp->file_id is valid and should replace the
1184 * dev=0, inode=0 from a non existent file. Spotted by
1185 * Nadav Danieli <nadavd@exanet.com>. JRA.
1190 lck = get_share_mode_lock(talloc_tos(), id,
1192 smb_fname, &old_write_time);
1195 DEBUG(0, ("onefs_open_file_ntcreate: Could not get "
1196 "share mode lock for %s\n",
1197 smb_fname_str_dbg(smb_fname)));
1199 return NT_STATUS_SHARING_VIOLATION;
1202 if (lck->delete_on_close) {
1203 status = NT_STATUS_DELETE_PENDING;
1206 if (!NT_STATUS_IS_OK(status)) {
1207 struct deferred_open_record state;
1211 state.delayed_for_oplocks = False;
1214 /* Do it all over again immediately. In the second
1215 * round we will find that the file existed and handle
1216 * the DELETE_PENDING and FCB cases correctly. No need
1217 * to duplicate the code here. Essentially this is a
1218 * "goto top of this function", but don't tell
1222 defer_open(lck, request_time, timeval_zero(),
1230 * We exit this block with the share entry *locked*.....
1235 SMB_ASSERT(lck != NULL);
1237 /* Delete streams if create_disposition requires it */
1238 if (file_existed && clear_ads &&
1239 !is_ntfs_stream_smb_fname(smb_fname)) {
1240 status = delete_all_streams(conn, smb_fname->base_name);
1241 if (!NT_STATUS_IS_OK(status)) {
1248 /* note that we ignore failure for the following. It is
1249 basically a hack for NFS, and NFS will never set one of
1250 these only read them. Nobody but Samba can ever set a deny
1251 mode and we have already checked our more authoritative
1252 locking database for permission to set this deny mode. If
1253 the kernel refuses the operations then the kernel is wrong.
1254 note that GPFS supports it as well - jmcd */
1256 if (fsp->fh->fd != -1) {
1257 ret_flock = SMB_VFS_KERNEL_FLOCK(fsp, share_access, access_mask);
1258 if(ret_flock == -1 ){
1262 return NT_STATUS_SHARING_VIOLATION;
1267 * At this point onwards, we can guarentee that the share entry
1268 * is locked, whether we created the file or not, and that the
1269 * deny mode is compatible with all current opens.
1272 /* Record the options we were opened with. */
1273 fsp->share_access = share_access;
1274 fsp->fh->private_options = create_options;
1276 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
1278 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
1281 /* stat opens on existing files don't get oplocks. */
1282 if (is_stat_open(open_access_mask)) {
1283 fsp->oplock_type = NO_OPLOCK;
1286 if (!(flags2 & O_TRUNC)) {
1287 info = FILE_WAS_OPENED;
1289 info = FILE_WAS_OVERWRITTEN;
1292 info = FILE_WAS_CREATED;
1300 * Setup the oplock info in both the shared memory and
1304 if ((fsp->oplock_type != NO_OPLOCK) &&
1305 (fsp->oplock_type != FAKE_LEVEL_II_OPLOCK)) {
1306 if (!set_file_oplock(fsp, fsp->oplock_type)) {
1307 /* Could not get the kernel oplock */
1308 fsp->oplock_type = NO_OPLOCK;
1312 if (fsp->oplock_type == LEVEL_II_OPLOCK &&
1313 (!lp_level2_oplocks(SNUM(conn)) ||
1314 !(global_client_caps & CAP_LEVEL_II_OPLOCKS))) {
1316 DEBUG(5, ("Downgrading level2 oplock on open "
1317 "because level2 oplocks = off\n"));
1319 release_file_oplock(fsp);
1322 if (info == FILE_WAS_OVERWRITTEN || info == FILE_WAS_CREATED ||
1323 info == FILE_WAS_SUPERSEDED) {
1324 new_file_created = True;
1327 set_share_mode(lck, fsp, conn->server_info->utok.uid, 0,
1330 /* Handle strange delete on close create semantics. */
1331 if (create_options & FILE_DELETE_ON_CLOSE) {
1332 status = can_set_delete_on_close(fsp, True, new_dos_attributes);
1334 if (!NT_STATUS_IS_OK(status)) {
1335 /* Remember to delete the mode we just added. */
1336 del_share_mode(lck, fsp);
1341 /* Note that here we set the *inital* delete on close flag,
1342 not the regular one. The magic gets handled in close. */
1343 fsp->initial_delete_on_close = True;
1347 * Take care of inherited ACLs on created files - if default ACL not
1349 * May be necessary depending on acl policies.
1351 if (!posix_open && !file_existed && !def_acl &&
1352 !(VALID_STAT(smb_fname->st) &&
1353 (smb_fname->st.st_ex_flags & SF_HASNTFSACL))) {
1355 int saved_errno = errno; /* We might get ENOSYS in the next
1358 if (SMB_VFS_FCHMOD_ACL(fsp, unx_mode) == -1 &&
1360 errno = saved_errno; /* Ignore ENOSYS */
1363 } else if (new_unx_mode) {
1367 /* Attributes need changing. File already existed. */
1370 int saved_errno = errno; /* We might get ENOSYS in the
1372 ret = SMB_VFS_FCHMOD_ACL(fsp, new_unx_mode);
1374 if (ret == -1 && errno == ENOSYS) {
1375 errno = saved_errno; /* Ignore ENOSYS */
1377 DEBUG(5, ("onefs_open_file_ntcreate: reset "
1378 "attributes of file %s to 0%o\n",
1379 smb_fname_str_dbg(smb_fname),
1380 (unsigned int)new_unx_mode));
1381 ret = 0; /* Don't do the fchmod below. */
1386 (SMB_VFS_FCHMOD(fsp, new_unx_mode) == -1))
1387 DEBUG(5, ("onefs_open_file_ntcreate: failed to reset "
1388 "attributes of file %s to 0%o\n",
1389 smb_fname_str_dbg(smb_fname),
1390 (unsigned int)new_unx_mode));
1393 /* If this is a successful open, we must remove any deferred open
1396 del_deferred_open_entry(lck, req->mid);
1400 return NT_STATUS_OK;
1404 /****************************************************************************
1405 Open a directory from an NT SMB call.
1406 ****************************************************************************/
1407 static NTSTATUS onefs_open_directory(connection_struct *conn,
1408 struct smb_request *req,
1409 struct smb_filename *smb_dname,
1411 uint32 share_access,
1412 uint32 create_disposition,
1413 uint32 create_options,
1414 uint32 file_attributes,
1415 struct security_descriptor *sd,
1416 files_struct **result,
1419 files_struct *fsp = NULL;
1420 struct share_mode_lock *lck = NULL;
1422 struct timespec mtimespec;
1425 bool posix_open = false;
1426 uint32 create_flags = 0;
1427 uint32 mode = lp_dir_mask(SNUM(conn));
1429 DEBUG(5, ("onefs_open_directory: opening directory %s, "
1430 "access_mask = 0x%x, "
1431 "share_access = 0x%x create_options = 0x%x, "
1432 "create_disposition = 0x%x, file_attributes = 0x%x\n",
1433 smb_fname_str_dbg(smb_dname), (unsigned int)access_mask,
1434 (unsigned int)share_access, (unsigned int)create_options,
1435 (unsigned int)create_disposition,
1436 (unsigned int)file_attributes));
1438 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
1439 (conn->fs_capabilities & FILE_NAMED_STREAMS) &&
1440 is_ntfs_stream_smb_fname(smb_dname)) {
1441 DEBUG(2, ("onefs_open_directory: %s is a stream name!\n",
1442 smb_fname_str_dbg(smb_dname)));
1443 return NT_STATUS_NOT_A_DIRECTORY;
1446 switch (create_disposition) {
1448 /* If directory exists open. If directory doesn't
1451 info = FILE_WAS_OPENED;
1454 /* If directory exists error. If directory doesn't
1456 create_flags = O_CREAT | O_EXCL;
1457 info = FILE_WAS_CREATED;
1460 /* If directory exists open. If directory doesn't
1463 /* Note: in order to return whether the directory was
1464 * opened or created, we first try to open and then try
1467 info = FILE_WAS_OPENED;
1469 case FILE_SUPERSEDE:
1470 case FILE_OVERWRITE:
1471 case FILE_OVERWRITE_IF:
1473 DEBUG(5, ("onefs_open_directory: invalid "
1474 "create_disposition 0x%x for directory %s\n",
1475 (unsigned int)create_disposition,
1476 smb_fname_str_dbg(smb_dname)));
1477 return NT_STATUS_INVALID_PARAMETER;
1481 * Check for write access to the share. Done in mkdir_internal() in
1484 if (!CAN_WRITE(conn) && (create_flags & O_CREAT)) {
1485 return NT_STATUS_ACCESS_DENIED;
1488 /* Get parent dirname */
1489 if (!parent_dirname(talloc_tos(), smb_dname->base_name, &parent_dir,
1491 return NT_STATUS_NO_MEMORY;
1494 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
1496 mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
1497 file_attributes = 0;
1499 mode = unix_mode(conn, aDIR, smb_dname, parent_dir);
1503 * The NONINDEXED and COMPRESSED bits seem to always be cleared on
1504 * directories, no matter if you specify that they should be set.
1507 ~(FILE_ATTRIBUTE_NONINDEXED | FILE_ATTRIBUTE_COMPRESSED);
1509 status = file_new(req, conn, &fsp);
1510 if(!NT_STATUS_IS_OK(status)) {
1515 * Actual open with retry magic to handle FILE_OPEN_IF which is
1516 * unique because the kernel won't tell us if the file was opened or
1520 fsp->fh->fd = onefs_sys_create_file(conn,
1522 smb_dname->base_name,
1527 create_flags | O_DIRECTORY,
1535 if (fsp->fh->fd == -1) {
1536 DEBUG(3, ("Error opening %s. Errno=%d (%s).\n",
1537 smb_fname_str_dbg(smb_dname), errno,
1539 SMB_ASSERT(errno != EINPROGRESS);
1541 if (create_disposition == FILE_OPEN_IF) {
1542 if (errno == ENOENT) {
1543 /* Try again, creating it this time. */
1544 create_flags = O_CREAT | O_EXCL;
1545 info = FILE_WAS_CREATED;
1547 } else if (errno == EEXIST) {
1548 /* Uggh. Try again again. */
1550 info = FILE_WAS_OPENED;
1555 /* Error cases below: */
1556 file_free(req, fsp);
1558 if ((errno == ENOENT) && (create_disposition == FILE_OPEN)) {
1559 DEBUG(5, ("onefs_open_directory: FILE_OPEN requested "
1560 "for directory %s and it doesn't "
1561 "exist.\n", smb_fname_str_dbg(smb_dname)));
1562 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1563 } else if ((errno == EEXIST) &&
1564 (create_disposition == FILE_CREATE)) {
1565 DEBUG(5, ("onefs_open_directory: FILE_CREATE "
1566 "requested for directory %s and it "
1567 "already exists.\n",
1568 smb_fname_str_dbg(smb_dname)));
1569 return NT_STATUS_OBJECT_NAME_COLLISION;
1570 } else if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
1571 /* Catch sharing violations. */
1572 return NT_STATUS_SHARING_VIOLATION;
1575 return map_nt_error_from_unix(errno);
1578 if (info == FILE_WAS_CREATED) {
1580 /* Pulled from mkdir_internal() */
1581 if (SMB_VFS_LSTAT(conn, smb_dname) == -1) {
1582 DEBUG(2, ("Could not stat directory '%s' just "
1584 smb_fname_str_dbg(smb_dname),
1586 return map_nt_error_from_unix(errno);
1589 if (!S_ISDIR(smb_dname->st.st_ex_mode)) {
1590 DEBUG(0, ("Directory just '%s' created is not a "
1592 smb_fname_str_dbg(smb_dname)));
1593 return NT_STATUS_ACCESS_DENIED;
1598 * Check if high bits should have been set, then (if
1599 * bits are missing): add them. Consider bits
1600 * automagically set by UNIX, i.e. SGID bit from
1603 if (mode & ~(S_IRWXU|S_IRWXG|S_IRWXO) &&
1604 (mode & ~smb_dname->st.st_ex_mode)) {
1605 SMB_VFS_CHMOD(conn, smb_dname->base_name,
1606 (smb_dname->st.st_ex_mode |
1607 (mode & ~smb_dname->st.st_ex_mode)));
1611 /* Change the owner if required. */
1612 if (lp_inherit_owner(SNUM(conn))) {
1613 change_dir_owner_to_parent(conn, parent_dir,
1614 smb_dname->base_name,
1618 notify_fname(conn, NOTIFY_ACTION_ADDED,
1619 FILE_NOTIFY_CHANGE_DIR_NAME,
1620 smb_dname->base_name);
1623 /* Stat the fd for Samba bookkeeping. */
1624 if(SMB_VFS_FSTAT(fsp, &smb_dname->st) != 0) {
1626 file_free(req, fsp);
1627 return map_nt_error_from_unix(errno);
1630 /* Setup the files_struct for it. */
1631 fsp->mode = smb_dname->st.st_ex_mode;
1632 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_dname->st);
1633 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
1634 fsp->file_pid = req ? req->smbpid : 0;
1635 fsp->can_lock = False;
1636 fsp->can_read = False;
1637 fsp->can_write = False;
1639 fsp->share_access = share_access;
1640 fsp->fh->private_options = create_options;
1642 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
1644 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
1645 fsp->print_file = False;
1646 fsp->modified = False;
1647 fsp->oplock_type = NO_OPLOCK;
1648 fsp->sent_oplock_break = NO_BREAK_SENT;
1649 fsp->is_directory = True;
1650 fsp->posix_open = posix_open;
1652 status = fsp_set_smb_fname(fsp, smb_dname);
1653 if (!NT_STATUS_IS_OK(status)) {
1655 file_free(req, fsp);
1659 mtimespec = smb_dname->st.st_ex_mtime;
1662 * Still set the samba share mode lock for correct delete-on-close
1663 * semantics and to make smbstatus more useful.
1665 lck = get_share_mode_lock(talloc_tos(), fsp->file_id,
1666 conn->connectpath, smb_dname, &mtimespec);
1669 DEBUG(0, ("onefs_open_directory: Could not get share mode "
1670 "lock for %s\n", smb_fname_str_dbg(smb_dname)));
1672 file_free(req, fsp);
1673 return NT_STATUS_SHARING_VIOLATION;
1676 if (lck->delete_on_close) {
1679 file_free(req, fsp);
1680 return NT_STATUS_DELETE_PENDING;
1683 set_share_mode(lck, fsp, conn->server_info->utok.uid, 0, NO_OPLOCK);
1686 * For directories the delete on close bit at open time seems
1687 * always to be honored on close... See test 19 in Samba4 BASE-DELETE.
1689 if (create_options & FILE_DELETE_ON_CLOSE) {
1690 status = can_set_delete_on_close(fsp, True, 0);
1691 if (!NT_STATUS_IS_OK(status) &&
1692 !NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
1695 file_free(req, fsp);
1699 if (NT_STATUS_IS_OK(status)) {
1700 /* Note that here we set the *inital* delete on close flag,
1701 not the regular one. The magic gets handled in close. */
1702 fsp->initial_delete_on_close = True;
1713 return NT_STATUS_OK;
1717 * Wrapper around onefs_open_file_ntcreate and onefs_open_directory.
1719 static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
1720 struct smb_request *req,
1721 struct smb_filename *smb_fname,
1722 uint32_t access_mask,
1723 uint32_t share_access,
1724 uint32_t create_disposition,
1725 uint32_t create_options,
1726 uint32_t file_attributes,
1727 uint32_t oplock_request,
1728 uint64_t allocation_size,
1729 struct security_descriptor *sd,
1730 struct ea_list *ea_list,
1731 files_struct **result,
1733 struct onefs_fsp_data *fsp_data)
1735 int info = FILE_WAS_OPENED;
1736 files_struct *base_fsp = NULL;
1737 files_struct *fsp = NULL;
1740 DEBUG(10,("onefs_create_file_unixpath: access_mask = 0x%x "
1741 "file_attributes = 0x%x, share_access = 0x%x, "
1742 "create_disposition = 0x%x create_options = 0x%x "
1743 "oplock_request = 0x%x ea_list = 0x%p, sd = 0x%p, "
1745 (unsigned int)access_mask,
1746 (unsigned int)file_attributes,
1747 (unsigned int)share_access,
1748 (unsigned int)create_disposition,
1749 (unsigned int)create_options,
1750 (unsigned int)oplock_request,
1751 ea_list, sd, smb_fname_str_dbg(smb_fname)));
1753 if (create_options & FILE_OPEN_BY_FILE_ID) {
1754 status = NT_STATUS_NOT_SUPPORTED;
1758 if (create_options & NTCREATEX_OPTIONS_INVALID_PARAM_MASK) {
1759 status = NT_STATUS_INVALID_PARAMETER;
1764 SMB_ASSERT((oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK) ==
1766 oplock_request |= INTERNAL_OPEN_ONLY;
1769 if (lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE,
1770 PARM_IGNORE_SACLS, PARM_IGNORE_SACLS_DEFAULT)) {
1771 access_mask &= ~SYSTEM_SECURITY_ACCESS;
1774 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
1775 && (access_mask & DELETE_ACCESS)
1776 && !is_ntfs_stream_smb_fname(smb_fname)) {
1778 * We can't open a file with DELETE access if any of the
1779 * streams is open without FILE_SHARE_DELETE
1781 status = open_streams_for_delete(conn, smb_fname->base_name);
1783 if (!NT_STATUS_IS_OK(status)) {
1788 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
1789 && is_ntfs_stream_smb_fname(smb_fname)) {
1790 uint32 base_create_disposition;
1791 struct smb_filename *smb_fname_base = NULL;
1793 if (create_options & FILE_DIRECTORY_FILE) {
1794 status = NT_STATUS_NOT_A_DIRECTORY;
1798 switch (create_disposition) {
1800 base_create_disposition = FILE_OPEN;
1803 base_create_disposition = FILE_OPEN_IF;
1807 /* Create an smb_filename with stream_name == NULL. */
1808 status = create_synthetic_smb_fname(talloc_tos(),
1809 smb_fname->base_name,
1812 if (!NT_STATUS_IS_OK(status)) {
1816 if (SMB_VFS_STAT(conn, smb_fname_base) == -1) {
1817 DEBUG(10, ("Unable to stat stream: %s\n",
1818 smb_fname_str_dbg(smb_fname_base)));
1821 status = onefs_create_file_unixpath(
1824 smb_fname_base, /* fname */
1825 SYNCHRONIZE_ACCESS, /* access_mask */
1828 FILE_SHARE_DELETE), /* share_access */
1829 base_create_disposition, /* create_disposition*/
1830 0, /* create_options */
1831 file_attributes, /* file_attributes */
1832 NO_OPLOCK, /* oplock_request */
1833 0, /* allocation_size */
1836 &base_fsp, /* result */
1838 NULL); /* fsp_data */
1840 TALLOC_FREE(smb_fname_base);
1842 if (!NT_STATUS_IS_OK(status)) {
1843 DEBUG(10, ("onefs_create_file_unixpath for base %s "
1844 "failed: %s\n", smb_fname->base_name,
1845 nt_errstr(status)));
1850 * Testing against windows xp/2003/vista shows that oplocks
1851 * can actually be requested and granted on streams (see the
1852 * RAW-OPLOCK-STREAM1 smbtorture test).
1854 if ((oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK) !=
1856 DEBUG(5, ("Oplock(%d) being requested on a stream! "
1857 "Ignoring oplock request: fname=%s\n",
1858 oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK,
1859 smb_fname_str_dbg(smb_fname)));
1860 /* Request NO_OPLOCK instead. */
1861 oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
1865 /* Covert generic bits in the security descriptor. */
1867 security_acl_map_generic(sd->dacl, &file_generic_mapping);
1868 security_acl_map_generic(sd->sacl, &file_generic_mapping);
1872 * If it's a request for a directory open, deal with it separately.
1875 if (create_options & FILE_DIRECTORY_FILE) {
1877 if (create_options & FILE_NON_DIRECTORY_FILE) {
1878 status = NT_STATUS_INVALID_PARAMETER;
1882 /* Can't open a temp directory. IFS kit test. */
1883 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
1884 (file_attributes & FILE_ATTRIBUTE_TEMPORARY)) {
1885 status = NT_STATUS_INVALID_PARAMETER;
1890 * We will get a create directory here if the Win32
1891 * app specified a security descriptor in the
1892 * CreateDirectory() call.
1895 status = onefs_open_directory(
1898 smb_fname, /* fname */
1899 access_mask, /* access_mask */
1900 share_access, /* share_access */
1901 create_disposition, /* create_disposition*/
1902 create_options, /* create_options */
1903 file_attributes, /* file_attributes */
1910 * Ordinary file case.
1913 status = file_new(req, conn, &fsp);
1914 if(!NT_STATUS_IS_OK(status)) {
1919 * We're opening the stream element of a base_fsp
1920 * we already opened. Set up the base_fsp pointer.
1923 fsp->base_fsp = base_fsp;
1926 status = onefs_open_file_ntcreate(
1929 smb_fname, /* fname */
1930 access_mask, /* access_mask */
1931 share_access, /* share_access */
1932 create_disposition, /* create_disposition*/
1933 create_options, /* create_options */
1934 file_attributes, /* file_attributes */
1935 oplock_request, /* oplock_request */
1939 fsp_data); /* fsp_data */
1941 if(!NT_STATUS_IS_OK(status)) {
1942 file_free(req, fsp);
1946 if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
1948 /* A stream open never opens a directory */
1951 status = NT_STATUS_FILE_IS_A_DIRECTORY;
1956 * Fail the open if it was explicitly a non-directory
1960 if (create_options & FILE_NON_DIRECTORY_FILE) {
1961 status = NT_STATUS_FILE_IS_A_DIRECTORY;
1965 create_options |= FILE_DIRECTORY_FILE;
1967 status = onefs_open_directory(
1970 smb_fname, /* fname */
1971 access_mask, /* access_mask */
1972 share_access, /* share_access */
1973 create_disposition, /* create_disposition*/
1974 create_options, /* create_options */
1975 file_attributes, /* file_attributes */
1982 if (!NT_STATUS_IS_OK(status)) {
1986 fsp->base_fsp = base_fsp;
1990 if ((ea_list != NULL) && (info == FILE_WAS_CREATED)) {
1991 status = set_ea(conn, fsp, smb_fname, ea_list);
1992 if (!NT_STATUS_IS_OK(status)) {
1997 if (!fsp->is_directory && S_ISDIR(smb_fname->st.st_ex_mode)) {
1998 status = NT_STATUS_ACCESS_DENIED;
2002 /* Save the requested allocation size. */
2003 if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
2005 && (allocation_size > smb_fname->st.st_ex_size)) {
2006 fsp->initial_allocation_size = smb_roundup(
2007 fsp->conn, allocation_size);
2008 if (fsp->is_directory) {
2009 /* Can't set allocation size on a directory. */
2010 status = NT_STATUS_ACCESS_DENIED;
2013 if (vfs_allocate_file_space(
2014 fsp, fsp->initial_allocation_size) == -1) {
2015 status = NT_STATUS_DISK_FULL;
2019 fsp->initial_allocation_size = smb_roundup(
2020 fsp->conn, (uint64_t)smb_fname->st.st_ex_size);
2024 DEBUG(10, ("onefs_create_file_unixpath: info=%d\n", info));
2027 if (pinfo != NULL) {
2030 if ((fsp->fh != NULL) && (fsp->fh->fd != -1)) {
2031 SMB_VFS_FSTAT(fsp, &smb_fname->st);
2033 return NT_STATUS_OK;
2036 DEBUG(10, ("onefs_create_file_unixpath: %s\n", nt_errstr(status)));
2039 if (base_fsp && fsp->base_fsp == base_fsp) {
2041 * The close_file below will close
2046 close_file(req, fsp, ERROR_CLOSE);
2049 if (base_fsp != NULL) {
2050 close_file(req, base_fsp, ERROR_CLOSE);
2056 static void destroy_onefs_fsp_data(void *p_data)
2058 struct onefs_fsp_data *fsp_data = (struct onefs_fsp_data *)p_data;
2060 destroy_onefs_callback_record(fsp_data->oplock_callback_id);
2064 * SMB_VFS_CREATE_FILE interface to onefs.
2066 NTSTATUS onefs_create_file(vfs_handle_struct *handle,
2067 struct smb_request *req,
2068 uint16_t root_dir_fid,
2069 struct smb_filename *smb_fname,
2070 uint32_t access_mask,
2071 uint32_t share_access,
2072 uint32_t create_disposition,
2073 uint32_t create_options,
2074 uint32_t file_attributes,
2075 uint32_t oplock_request,
2076 uint64_t allocation_size,
2077 struct security_descriptor *sd,
2078 struct ea_list *ea_list,
2079 files_struct **result,
2082 connection_struct *conn = handle->conn;
2083 struct onefs_fsp_data fsp_data = {};
2084 int info = FILE_WAS_OPENED;
2085 files_struct *fsp = NULL;
2088 DEBUG(10,("onefs_create_file: access_mask = 0x%x "
2089 "file_attributes = 0x%x, share_access = 0x%x, "
2090 "create_disposition = 0x%x create_options = 0x%x "
2091 "oplock_request = 0x%x "
2092 "root_dir_fid = 0x%x, ea_list = 0x%p, sd = 0x%p, "
2094 (unsigned int)access_mask,
2095 (unsigned int)file_attributes,
2096 (unsigned int)share_access,
2097 (unsigned int)create_disposition,
2098 (unsigned int)create_options,
2099 (unsigned int)oplock_request,
2100 (unsigned int)root_dir_fid,
2101 ea_list, sd, smb_fname_str_dbg(smb_fname)));
2103 /* Get the file name if root_dir_fid was specified. */
2104 if (root_dir_fid != 0) {
2105 status = get_relative_fid_filename(conn, req, root_dir_fid,
2107 if (!NT_STATUS_IS_OK(status)) {
2112 /* All file access must go through check_name() */
2113 status = check_name(conn, smb_fname->base_name);
2114 if (!NT_STATUS_IS_OK(status)) {
2118 status = onefs_create_file_unixpath(
2121 smb_fname, /* fname */
2122 access_mask, /* access_mask */
2123 share_access, /* share_access */
2124 create_disposition, /* create_disposition*/
2125 create_options, /* create_options */
2126 file_attributes, /* file_attributes */
2127 oplock_request, /* oplock_request */
2128 allocation_size, /* allocation_size */
2130 ea_list, /* ea_list */
2133 &fsp_data); /* psbuf */
2135 if (!NT_STATUS_IS_OK(status)) {
2139 DEBUG(10, ("onefs_create_file: info=%d\n", info));
2142 * Setup private onefs_fsp_data. Currently the private data struct is
2143 * only used to store the oplock_callback_id so that when the file is
2144 * closed, the onefs_callback_record can be properly cleaned up in the
2145 * oplock_onefs sub-system.
2148 struct onefs_fsp_data *fsp_data_tmp = NULL;
2149 fsp_data_tmp = (struct onefs_fsp_data *)
2150 VFS_ADD_FSP_EXTENSION(handle, fsp, struct onefs_fsp_data,
2151 &destroy_onefs_fsp_data);
2153 if (fsp_data_tmp == NULL) {
2154 status = NT_STATUS_NO_MEMORY;
2158 *fsp_data_tmp = fsp_data;
2162 if (pinfo != NULL) {
2165 return NT_STATUS_OK;
2168 DEBUG(10, ("onefs_create_file: %s\n", nt_errstr(status)));
2171 close_file(req, fsp, ERROR_CLOSE);