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,
492 req->vuid, fsp, &smb_fname->st);
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_VETO_OPLOCK_PATH(conn, smb_fname->base_name)) {
607 /* Mask off everything except the private Samba bits. */
608 oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
611 /* this is for OS/2 long file names - say we don't support them */
612 if (!lp_posix_pathnames() && strstr(smb_fname->base_name,".+,;=[].")) {
613 /* OS/2 Workplace shell fix may be main code stream in a later
615 DEBUG(5,("onefs_open_file_ntcreate: OS/2 long filenames are "
616 "not supported.\n"));
617 if (use_nt_status()) {
618 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
620 return NT_STATUS_DOS(ERRDOS, ERRcannotopen);
623 switch( create_disposition ) {
625 * Currently we're using FILE_SUPERSEDE as the same as
626 * FILE_OVERWRITE_IF but they really are
627 * different. FILE_SUPERSEDE deletes an existing file
628 * (requiring delete access) then recreates it.
632 * @todo: Clear all file attributes?
633 * http://www.osronline.com/article.cfm?article=302
634 * create if not exist, trunc if exist
636 * If file exists replace/overwrite. If file doesn't
639 flags2 |= (O_CREAT | O_TRUNC);
643 case FILE_OVERWRITE_IF:
644 /* If file exists replace/overwrite. If file doesn't
646 flags2 |= (O_CREAT | O_TRUNC);
651 /* If file exists open. If file doesn't exist error. */
653 DEBUG(5,("onefs_open_file_ntcreate: FILE_OPEN "
654 "requested for file %s and file "
656 smb_fname_str_dbg(smb_fname)));
658 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
663 /* If file exists overwrite. If file doesn't exist
666 DEBUG(5, ("onefs_open_file_ntcreate: "
667 "FILE_OVERWRITE requested for file "
668 "%s and file doesn't exist.\n",
669 smb_fname_str_dbg(smb_fname)));
671 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
678 /* If file exists error. If file doesn't exist
681 DEBUG(5, ("onefs_open_file_ntcreate: "
682 "FILE_CREATE requested for file %s "
683 "and file already exists.\n",
684 smb_fname_str_dbg(smb_fname)));
685 if (S_ISDIR(smb_fname->st.st_ex_mode)) {
690 return map_nt_error_from_unix(errno);
692 flags2 |= (O_CREAT|O_EXCL);
696 /* If file exists open. If file doesn't exist
702 return NT_STATUS_INVALID_PARAMETER;
705 /* Match attributes on file exists and overwrite. */
706 if (!posix_open && file_existed &&
707 ((create_disposition == FILE_OVERWRITE) ||
708 (create_disposition == FILE_OVERWRITE_IF))) {
709 if (!open_match_attributes(conn, existing_dos_attributes,
711 smb_fname->st.st_ex_mode,
712 unx_mode, &new_unx_mode)) {
713 DEBUG(5, ("onefs_open_file_ntcreate: attributes "
714 "missmatch for file %s (%x %x) (0%o, 0%o)\n",
715 smb_fname_str_dbg(smb_fname),
716 existing_dos_attributes,
718 (unsigned int)smb_fname->st.st_ex_mode,
719 (unsigned int)unx_mode ));
721 return NT_STATUS_ACCESS_DENIED;
726 * OneFS understands MAXIMUM_ALLOWED_ACCESS, so only hack the
727 * access_mask, but leave the MAA for the actual open in
730 open_access_mask = access_mask;
731 if (open_access_mask & MAXIMUM_ALLOWED_ACCESS) {
732 access_mask |= FILE_GENERIC_ALL;
735 /* Convert GENERIC bits to specific bits. */
736 se_map_generic(&access_mask, &file_generic_mapping);
737 se_map_generic(&open_access_mask, &file_generic_mapping);
739 if ((flags2 & O_TRUNC) || (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE)) {
740 /* This will cause oplock breaks. */
741 open_access_mask |= FILE_WRITE_DATA;
744 DEBUG(10, ("onefs_open_file_ntcreate: fname=%s, after mapping "
745 "open_access_mask=%#x, access_mask=0x%x\n",
746 smb_fname_str_dbg(smb_fname), open_access_mask,
750 * Note that we ignore the append flag as append does not
751 * mean the same thing under DOS and Unix.
754 if ((access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ||
755 (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE)) {
758 * DENY_DOS opens are always underlying read-write on the
759 * file handle, no matter what the requested access mask
760 * says. Stock samba just sets the flags, but since
761 * ifs_createfile uses the access_mask, it must be updated as
762 * well. This allows BASE-DENY* to pass.
764 if (create_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) {
766 DEBUG(10,("onefs_open_file_ntcreate: deny_dos: "
767 "Adding O_RDWR to flags "
768 "(0x%x) and some READ bits to "
769 "open_access_mask (0x%x)\n",
770 flags, open_access_mask));
773 open_access_mask |= (FILE_READ_ATTRIBUTES |
774 FILE_READ_DATA | FILE_READ_EA | FILE_EXECUTE);
776 } else if (access_mask & (FILE_READ_ATTRIBUTES |
788 /* Currently we only look at FILE_WRITE_THROUGH for create options. */
790 if ((create_options & FILE_WRITE_THROUGH) &&
791 lp_strict_sync(SNUM(conn))) {
796 if (posix_open && (access_mask & FILE_APPEND_DATA)) {
800 if (!posix_open && !CAN_WRITE(conn)) {
802 * We should really return a permission denied error if either
803 * O_CREAT or O_TRUNC are set, but for compatibility with
804 * older versions of Samba we just AND them out.
806 flags2 &= ~(O_CREAT|O_TRUNC);
808 /* Deny DELETE_ACCESS explicitly if the share is read only. */
809 if (access_mask & DELETE_ACCESS) {
810 return map_nt_error_from_unix(EACCES);
814 /* Ensure we can't write on a read-only share or file. */
815 if (flags != O_RDONLY && file_existed &&
816 (!CAN_WRITE(conn) || IS_DOS_READONLY(existing_dos_attributes))) {
817 DEBUG(5, ("onefs_open_file_ntcreate: write access requested "
818 "for file %s on read only %s\n",
819 smb_fname_str_dbg(smb_fname),
820 !CAN_WRITE(conn) ? "share" : "file" ));
822 return NT_STATUS_ACCESS_DENIED;
825 DEBUG(10, ("fsp = %p\n", fsp));
827 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
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 struct timespec old_write_time;
935 old_write_time = smb_fname->st.st_ex_mtime;
937 DEBUG(3, ("Someone created file %s with an "
938 "oplock after we looked: Retrying\n",
939 smb_fname_str_dbg(smb_fname)));
941 * We hit the race that when we did the stat
942 * on the file it did not exist, and someone
943 * has created it in between the stat and the
944 * open_file() call. Just retry immediately.
946 id = vfs_file_id_from_sbuf(conn,
948 if (!(lck = get_share_mode_lock(talloc_tos(),
949 id, conn->connectpath, smb_fname,
954 DEBUG(0, ("onefs_open_file_ntcreate: "
955 "Could not get share mode "
957 smb_fname_str_dbg(smb_fname)));
958 status = NT_STATUS_SHARING_VIOLATION;
960 /* XXXZLK: This will cause us to get a
961 * semlock event when we aren't
963 goto cleanup_destroy;
966 schedule_defer_open(lck, request_time, req);
969 /* Waiting for an oplock */
970 DEBUG(5,("Async createfile because a client has an "
972 smb_fname_str_dbg(smb_fname)));
975 schedule_defer_open(lck, request_time, req);
979 /* Check for a sharing violation */
980 if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
981 uint32 can_access_mask;
982 bool can_access = True;
984 /* Check if this can be done with the deny_dos and fcb
987 /* Try to find dup fsp if possible. */
989 (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS|
990 NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) {
993 DEBUG(0, ("DOS open without an SMB "
995 status = NT_STATUS_INTERNAL_ERROR;
996 goto cleanup_destroy;
999 /* Use the client requested access mask here,
1000 * not the one we open with. */
1001 status = fcb_or_dos_open(req,
1012 if (NT_STATUS_IS_OK(status)) {
1014 *pinfo = FILE_WAS_OPENED;
1016 status = NT_STATUS_OK;
1022 * This next line is a subtlety we need for
1023 * MS-Access. If a file open will fail due to share
1024 * permissions and also for security (access) reasons,
1025 * we need to return the access failed error, not the
1026 * share error. We can't open the file due to kernel
1027 * oplock deadlock (it's possible we failed above on
1028 * the open_mode_check()) so use a userspace check.
1031 if (flags & O_RDWR) {
1032 can_access_mask = FILE_READ_DATA|FILE_WRITE_DATA;
1033 } else if (flags & O_WRONLY) {
1034 can_access_mask = FILE_WRITE_DATA;
1036 can_access_mask = FILE_READ_DATA;
1039 if (((can_access_mask & FILE_WRITE_DATA) &&
1040 !CAN_WRITE(conn)) ||
1041 !can_access_file_data(conn, smb_fname,
1047 * If we're returning a share violation, ensure we
1048 * cope with the braindead 1 second delay.
1050 if (!(oplock_request & INTERNAL_OPEN_ONLY) &&
1051 lp_defer_sharing_violations()) {
1052 struct timeval timeout;
1053 struct deferred_open_record state;
1056 /* this is a hack to speed up torture tests
1058 timeout_usecs = lp_parm_int(SNUM(conn),
1059 "smbd","sharedelay",
1060 SHARING_VIOLATION_USEC_WAIT);
1062 /* This is a relative time, added to the
1063 absolute request_time value to get the
1064 absolute timeout time. Note that if this
1065 is the second or greater time we enter this
1066 codepath for this particular request mid
1067 then request_time is left as the absolute
1068 time of the *first* time this request mid
1069 was processed. This is what allows the
1070 request to eventually time out. */
1072 timeout = timeval_set(0, timeout_usecs);
1074 /* Nothing actually uses
1075 state.delayed_for_oplocks but it's handy to
1076 differentiate in debug messages between a
1077 30 second delay due to oplock break, and a
1078 1 second delay for share mode conflicts. */
1080 state.delayed_for_oplocks = False;
1082 state.failed = false;
1085 && !request_timed_out(request_time,
1087 defer_open(lck, request_time, timeout,
1094 * We have detected a sharing violation here
1095 * so return the correct error code
1097 status = NT_STATUS_SHARING_VIOLATION;
1099 status = NT_STATUS_ACCESS_DENIED;
1102 goto cleanup_destroy;
1106 * Normal error, for example EACCES
1109 if (oplock_callback_id != 0) {
1110 destroy_onefs_callback_record(oplock_callback_id);
1117 fsp->oplock_type = granted_oplock;
1119 if (oplock_callback_id != 0) {
1120 onefs_set_oplock_callback(oplock_callback_id, fsp);
1121 fsp_data->oplock_callback_id = oplock_callback_id;
1123 SMB_ASSERT(fsp->oplock_type == NO_OPLOCK);
1126 if (!file_existed) {
1127 struct timespec old_write_time = smb_fname->st.st_ex_mtime;
1129 * Deal with the race condition where two smbd's detect the
1130 * file doesn't exist and do the create at the same time. One
1131 * of them will win and set a share mode, the other (ie. this
1132 * one) should check if the requested share mode for this
1133 * create is allowed.
1137 * Now the file exists and fsp is successfully opened,
1138 * fsp->dev and fsp->inode are valid and should replace the
1139 * dev=0,inode=0 from a non existent file. Spotted by
1140 * Nadav Danieli <nadavd@exanet.com>. JRA.
1145 lck = get_share_mode_lock(talloc_tos(), id,
1147 smb_fname, &old_write_time);
1150 DEBUG(0, ("onefs_open_file_ntcreate: Could not get "
1151 "share mode lock for %s\n",
1152 smb_fname_str_dbg(smb_fname)));
1154 return NT_STATUS_SHARING_VIOLATION;
1157 if (lck->delete_on_close) {
1158 status = NT_STATUS_DELETE_PENDING;
1161 if (!NT_STATUS_IS_OK(status)) {
1162 struct deferred_open_record state;
1166 state.delayed_for_oplocks = False;
1169 /* Do it all over again immediately. In the second
1170 * round we will find that the file existed and handle
1171 * the DELETE_PENDING and FCB cases correctly. No need
1172 * to duplicate the code here. Essentially this is a
1173 * "goto top of this function", but don't tell
1177 defer_open(lck, request_time, timeval_zero(),
1185 * We exit this block with the share entry *locked*.....
1190 SMB_ASSERT(lck != NULL);
1192 /* Delete streams if create_disposition requires it */
1193 if (file_existed && clear_ads &&
1194 !is_ntfs_stream_smb_fname(smb_fname)) {
1195 status = delete_all_streams(conn, smb_fname->base_name);
1196 if (!NT_STATUS_IS_OK(status)) {
1203 /* note that we ignore failure for the following. It is
1204 basically a hack for NFS, and NFS will never set one of
1205 these only read them. Nobody but Samba can ever set a deny
1206 mode and we have already checked our more authoritative
1207 locking database for permission to set this deny mode. If
1208 the kernel refuses the operations then the kernel is wrong.
1209 note that GPFS supports it as well - jmcd */
1211 if (fsp->fh->fd != -1) {
1212 ret_flock = SMB_VFS_KERNEL_FLOCK(fsp, share_access);
1213 if(ret_flock == -1 ){
1217 return NT_STATUS_SHARING_VIOLATION;
1222 * At this point onwards, we can guarentee that the share entry
1223 * is locked, whether we created the file or not, and that the
1224 * deny mode is compatible with all current opens.
1227 /* Record the options we were opened with. */
1228 fsp->share_access = share_access;
1229 fsp->fh->private_options = create_options;
1231 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
1233 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
1236 /* stat opens on existing files don't get oplocks. */
1237 if (is_stat_open(open_access_mask)) {
1238 fsp->oplock_type = NO_OPLOCK;
1241 if (!(flags2 & O_TRUNC)) {
1242 info = FILE_WAS_OPENED;
1244 info = FILE_WAS_OVERWRITTEN;
1247 info = FILE_WAS_CREATED;
1255 * Setup the oplock info in both the shared memory and
1259 if ((fsp->oplock_type != NO_OPLOCK) &&
1260 (fsp->oplock_type != FAKE_LEVEL_II_OPLOCK)) {
1261 if (!set_file_oplock(fsp, fsp->oplock_type)) {
1262 /* Could not get the kernel oplock */
1263 fsp->oplock_type = NO_OPLOCK;
1267 if (fsp->oplock_type == LEVEL_II_OPLOCK &&
1268 (!lp_level2_oplocks(SNUM(conn)) ||
1269 !(global_client_caps & CAP_LEVEL_II_OPLOCKS))) {
1271 DEBUG(5, ("Downgrading level2 oplock on open "
1272 "because level2 oplocks = off\n"));
1274 release_file_oplock(fsp);
1277 if (info == FILE_WAS_OVERWRITTEN || info == FILE_WAS_CREATED ||
1278 info == FILE_WAS_SUPERSEDED) {
1279 new_file_created = True;
1282 set_share_mode(lck, fsp, conn->server_info->utok.uid, 0,
1285 /* Handle strange delete on close create semantics. */
1286 if (create_options & FILE_DELETE_ON_CLOSE) {
1287 status = can_set_delete_on_close(fsp, True, new_dos_attributes);
1289 if (!NT_STATUS_IS_OK(status)) {
1290 /* Remember to delete the mode we just added. */
1291 del_share_mode(lck, fsp);
1296 /* Note that here we set the *inital* delete on close flag,
1297 not the regular one. The magic gets handled in close. */
1298 fsp->initial_delete_on_close = True;
1302 * Take care of inherited ACLs on created files - if default ACL not
1304 * May be necessary depending on acl policies.
1306 if (!posix_open && !file_existed && !def_acl &&
1307 !(VALID_STAT(smb_fname->st) &&
1308 (smb_fname->st.st_ex_flags & SF_HASNTFSACL))) {
1310 int saved_errno = errno; /* We might get ENOSYS in the next
1313 if (SMB_VFS_FCHMOD_ACL(fsp, unx_mode) == -1 &&
1315 errno = saved_errno; /* Ignore ENOSYS */
1318 } else if (new_unx_mode) {
1322 /* Attributes need changing. File already existed. */
1325 int saved_errno = errno; /* We might get ENOSYS in the
1327 ret = SMB_VFS_FCHMOD_ACL(fsp, new_unx_mode);
1329 if (ret == -1 && errno == ENOSYS) {
1330 errno = saved_errno; /* Ignore ENOSYS */
1332 DEBUG(5, ("onefs_open_file_ntcreate: reset "
1333 "attributes of file %s to 0%o\n",
1334 smb_fname_str_dbg(smb_fname),
1335 (unsigned int)new_unx_mode));
1336 ret = 0; /* Don't do the fchmod below. */
1341 (SMB_VFS_FCHMOD(fsp, new_unx_mode) == -1))
1342 DEBUG(5, ("onefs_open_file_ntcreate: failed to reset "
1343 "attributes of file %s to 0%o\n",
1344 smb_fname_str_dbg(smb_fname),
1345 (unsigned int)new_unx_mode));
1348 /* If this is a successful open, we must remove any deferred open
1351 del_deferred_open_entry(lck, req->mid);
1355 return NT_STATUS_OK;
1359 /****************************************************************************
1360 Open a directory from an NT SMB call.
1361 ****************************************************************************/
1362 static NTSTATUS onefs_open_directory(connection_struct *conn,
1363 struct smb_request *req,
1364 struct smb_filename *smb_dname,
1366 uint32 share_access,
1367 uint32 create_disposition,
1368 uint32 create_options,
1369 uint32 file_attributes,
1370 struct security_descriptor *sd,
1371 files_struct **result,
1374 files_struct *fsp = NULL;
1375 struct share_mode_lock *lck = NULL;
1377 struct timespec mtimespec;
1380 bool posix_open = false;
1381 uint32 create_flags = 0;
1382 uint32 mode = lp_dir_mask(SNUM(conn));
1384 DEBUG(5, ("onefs_open_directory: opening directory %s, "
1385 "access_mask = 0x%x, "
1386 "share_access = 0x%x create_options = 0x%x, "
1387 "create_disposition = 0x%x, file_attributes = 0x%x\n",
1388 smb_fname_str_dbg(smb_dname), (unsigned int)access_mask,
1389 (unsigned int)share_access, (unsigned int)create_options,
1390 (unsigned int)create_disposition,
1391 (unsigned int)file_attributes));
1393 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
1394 (conn->fs_capabilities & FILE_NAMED_STREAMS) &&
1395 is_ntfs_stream_smb_fname(smb_dname)) {
1396 DEBUG(2, ("onefs_open_directory: %s is a stream name!\n",
1397 smb_fname_str_dbg(smb_dname)));
1398 return NT_STATUS_NOT_A_DIRECTORY;
1401 switch (create_disposition) {
1403 /* If directory exists open. If directory doesn't
1406 info = FILE_WAS_OPENED;
1409 /* If directory exists error. If directory doesn't
1411 create_flags = O_CREAT | O_EXCL;
1412 info = FILE_WAS_CREATED;
1415 /* If directory exists open. If directory doesn't
1418 /* Note: in order to return whether the directory was
1419 * opened or created, we first try to open and then try
1422 info = FILE_WAS_OPENED;
1424 case FILE_SUPERSEDE:
1425 case FILE_OVERWRITE:
1426 case FILE_OVERWRITE_IF:
1428 DEBUG(5, ("onefs_open_directory: invalid "
1429 "create_disposition 0x%x for directory %s\n",
1430 (unsigned int)create_disposition,
1431 smb_fname_str_dbg(smb_dname)));
1432 return NT_STATUS_INVALID_PARAMETER;
1436 * Check for write access to the share. Done in mkdir_internal() in
1439 if (!CAN_WRITE(conn) && (create_flags & O_CREAT)) {
1440 return NT_STATUS_ACCESS_DENIED;
1443 /* Get parent dirname */
1444 if (!parent_dirname(talloc_tos(), smb_dname->base_name, &parent_dir,
1446 return NT_STATUS_NO_MEMORY;
1449 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
1451 mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
1452 file_attributes = 0;
1454 mode = unix_mode(conn, aDIR, smb_dname, parent_dir);
1458 * The NONINDEXED and COMPRESSED bits seem to always be cleared on
1459 * directories, no matter if you specify that they should be set.
1462 ~(FILE_ATTRIBUTE_NONINDEXED | FILE_ATTRIBUTE_COMPRESSED);
1464 status = file_new(req, conn, &fsp);
1465 if(!NT_STATUS_IS_OK(status)) {
1470 * Actual open with retry magic to handle FILE_OPEN_IF which is
1471 * unique because the kernel won't tell us if the file was opened or
1475 fsp->fh->fd = onefs_sys_create_file(conn,
1477 smb_dname->base_name,
1482 create_flags | O_DIRECTORY,
1490 if (fsp->fh->fd == -1) {
1491 DEBUG(3, ("Error opening %s. Errno=%d (%s).\n",
1492 smb_fname_str_dbg(smb_dname), errno,
1494 SMB_ASSERT(errno != EINPROGRESS);
1496 if (create_disposition == FILE_OPEN_IF) {
1497 if (errno == ENOENT) {
1498 /* Try again, creating it this time. */
1499 create_flags = O_CREAT | O_EXCL;
1500 info = FILE_WAS_CREATED;
1502 } else if (errno == EEXIST) {
1503 /* Uggh. Try again again. */
1505 info = FILE_WAS_OPENED;
1510 /* Error cases below: */
1511 file_free(req, fsp);
1513 if ((errno == ENOENT) && (create_disposition == FILE_OPEN)) {
1514 DEBUG(5, ("onefs_open_directory: FILE_OPEN requested "
1515 "for directory %s and it doesn't "
1516 "exist.\n", smb_fname_str_dbg(smb_dname)));
1517 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1518 } else if ((errno == EEXIST) &&
1519 (create_disposition == FILE_CREATE)) {
1520 DEBUG(5, ("onefs_open_directory: FILE_CREATE "
1521 "requested for directory %s and it "
1522 "already exists.\n",
1523 smb_fname_str_dbg(smb_dname)));
1524 return NT_STATUS_OBJECT_NAME_COLLISION;
1525 } else if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
1526 /* Catch sharing violations. */
1527 return NT_STATUS_SHARING_VIOLATION;
1530 return map_nt_error_from_unix(errno);
1533 if (info == FILE_WAS_CREATED) {
1535 /* Pulled from mkdir_internal() */
1536 if (SMB_VFS_LSTAT(conn, smb_dname) == -1) {
1537 DEBUG(2, ("Could not stat directory '%s' just "
1539 smb_fname_str_dbg(smb_dname),
1541 return map_nt_error_from_unix(errno);
1544 if (!S_ISDIR(smb_dname->st.st_ex_mode)) {
1545 DEBUG(0, ("Directory just '%s' created is not a "
1547 smb_fname_str_dbg(smb_dname)));
1548 return NT_STATUS_ACCESS_DENIED;
1553 * Check if high bits should have been set, then (if
1554 * bits are missing): add them. Consider bits
1555 * automagically set by UNIX, i.e. SGID bit from
1558 if (mode & ~(S_IRWXU|S_IRWXG|S_IRWXO) &&
1559 (mode & ~smb_dname->st.st_ex_mode)) {
1560 SMB_VFS_CHMOD(conn, smb_dname->base_name,
1561 (smb_dname->st.st_ex_mode |
1562 (mode & ~smb_dname->st.st_ex_mode)));
1566 /* Change the owner if required. */
1567 if (lp_inherit_owner(SNUM(conn))) {
1568 change_dir_owner_to_parent(conn, parent_dir,
1569 smb_dname->base_name,
1573 notify_fname(conn, NOTIFY_ACTION_ADDED,
1574 FILE_NOTIFY_CHANGE_DIR_NAME,
1575 smb_dname->base_name);
1578 /* Stat the fd for Samba bookkeeping. */
1579 if(SMB_VFS_FSTAT(fsp, &smb_dname->st) != 0) {
1581 file_free(req, fsp);
1582 return map_nt_error_from_unix(errno);
1585 /* Setup the files_struct for it. */
1586 fsp->mode = smb_dname->st.st_ex_mode;
1587 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_dname->st);
1588 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
1589 fsp->file_pid = req ? req->smbpid : 0;
1590 fsp->can_lock = False;
1591 fsp->can_read = False;
1592 fsp->can_write = False;
1594 fsp->share_access = share_access;
1595 fsp->fh->private_options = create_options;
1597 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
1599 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
1600 fsp->print_file = False;
1601 fsp->modified = False;
1602 fsp->oplock_type = NO_OPLOCK;
1603 fsp->sent_oplock_break = NO_BREAK_SENT;
1604 fsp->is_directory = True;
1605 fsp->posix_open = posix_open;
1607 status = fsp_set_smb_fname(fsp, smb_dname);
1608 if (!NT_STATUS_IS_OK(status)) {
1610 file_free(req, fsp);
1614 mtimespec = smb_dname->st.st_ex_mtime;
1617 * Still set the samba share mode lock for correct delete-on-close
1618 * semantics and to make smbstatus more useful.
1620 lck = get_share_mode_lock(talloc_tos(), fsp->file_id,
1621 conn->connectpath, smb_dname, &mtimespec);
1624 DEBUG(0, ("onefs_open_directory: Could not get share mode "
1625 "lock for %s\n", smb_fname_str_dbg(smb_dname)));
1627 file_free(req, fsp);
1628 return NT_STATUS_SHARING_VIOLATION;
1631 if (lck->delete_on_close) {
1634 file_free(req, fsp);
1635 return NT_STATUS_DELETE_PENDING;
1638 set_share_mode(lck, fsp, conn->server_info->utok.uid, 0, NO_OPLOCK);
1641 * For directories the delete on close bit at open time seems
1642 * always to be honored on close... See test 19 in Samba4 BASE-DELETE.
1644 if (create_options & FILE_DELETE_ON_CLOSE) {
1645 status = can_set_delete_on_close(fsp, True, 0);
1646 if (!NT_STATUS_IS_OK(status) &&
1647 !NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
1650 file_free(req, fsp);
1654 if (NT_STATUS_IS_OK(status)) {
1655 /* Note that here we set the *inital* delete on close flag,
1656 not the regular one. The magic gets handled in close. */
1657 fsp->initial_delete_on_close = True;
1668 return NT_STATUS_OK;
1672 * Wrapper around onefs_open_file_ntcreate and onefs_open_directory.
1674 static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
1675 struct smb_request *req,
1676 struct smb_filename *smb_fname,
1677 uint32_t access_mask,
1678 uint32_t share_access,
1679 uint32_t create_disposition,
1680 uint32_t create_options,
1681 uint32_t file_attributes,
1682 uint32_t oplock_request,
1683 uint64_t allocation_size,
1684 struct security_descriptor *sd,
1685 struct ea_list *ea_list,
1686 files_struct **result,
1688 struct onefs_fsp_data *fsp_data)
1690 int info = FILE_WAS_OPENED;
1691 files_struct *base_fsp = NULL;
1692 files_struct *fsp = NULL;
1695 DEBUG(10,("onefs_create_file_unixpath: access_mask = 0x%x "
1696 "file_attributes = 0x%x, share_access = 0x%x, "
1697 "create_disposition = 0x%x create_options = 0x%x "
1698 "oplock_request = 0x%x ea_list = 0x%p, sd = 0x%p, "
1700 (unsigned int)access_mask,
1701 (unsigned int)file_attributes,
1702 (unsigned int)share_access,
1703 (unsigned int)create_disposition,
1704 (unsigned int)create_options,
1705 (unsigned int)oplock_request,
1706 ea_list, sd, smb_fname_str_dbg(smb_fname)));
1708 if (create_options & FILE_OPEN_BY_FILE_ID) {
1709 status = NT_STATUS_NOT_SUPPORTED;
1713 if (create_options & NTCREATEX_OPTIONS_INVALID_PARAM_MASK) {
1714 status = NT_STATUS_INVALID_PARAMETER;
1719 SMB_ASSERT((oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK) ==
1721 oplock_request |= INTERNAL_OPEN_ONLY;
1724 if (lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE,
1725 PARM_IGNORE_SACLS, PARM_IGNORE_SACLS_DEFAULT)) {
1726 access_mask &= ~SYSTEM_SECURITY_ACCESS;
1729 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
1730 && (access_mask & DELETE_ACCESS)
1731 && !is_ntfs_stream_smb_fname(smb_fname)) {
1733 * We can't open a file with DELETE access if any of the
1734 * streams is open without FILE_SHARE_DELETE
1736 status = open_streams_for_delete(conn, smb_fname->base_name);
1738 if (!NT_STATUS_IS_OK(status)) {
1743 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
1744 && is_ntfs_stream_smb_fname(smb_fname)) {
1745 uint32 base_create_disposition;
1746 struct smb_filename *smb_fname_base = NULL;
1748 if (create_options & FILE_DIRECTORY_FILE) {
1749 status = NT_STATUS_NOT_A_DIRECTORY;
1753 switch (create_disposition) {
1755 base_create_disposition = FILE_OPEN;
1758 base_create_disposition = FILE_OPEN_IF;
1762 /* Create an smb_filename with stream_name == NULL. */
1763 status = create_synthetic_smb_fname(talloc_tos(),
1764 smb_fname->base_name,
1767 if (!NT_STATUS_IS_OK(status)) {
1771 if (SMB_VFS_STAT(conn, smb_fname_base) == -1) {
1772 DEBUG(10, ("Unable to stat stream: %s\n",
1773 smb_fname_str_dbg(smb_fname_base)));
1776 status = onefs_create_file_unixpath(
1779 smb_fname_base, /* fname */
1780 SYNCHRONIZE_ACCESS, /* access_mask */
1783 FILE_SHARE_DELETE), /* share_access */
1784 base_create_disposition, /* create_disposition*/
1785 0, /* create_options */
1786 file_attributes, /* file_attributes */
1787 NO_OPLOCK, /* oplock_request */
1788 0, /* allocation_size */
1791 &base_fsp, /* result */
1793 NULL); /* fsp_data */
1795 TALLOC_FREE(smb_fname_base);
1797 if (!NT_STATUS_IS_OK(status)) {
1798 DEBUG(10, ("onefs_create_file_unixpath for base %s "
1799 "failed: %s\n", smb_fname->base_name,
1800 nt_errstr(status)));
1805 * Testing against windows xp/2003/vista shows that oplocks
1806 * can actually be requested and granted on streams (see the
1807 * RAW-OPLOCK-STREAM1 smbtorture test).
1809 if ((oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK) !=
1811 DEBUG(5, ("Oplock(%d) being requested on a stream! "
1812 "Ignoring oplock request: fname=%s\n",
1813 oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK,
1814 smb_fname_str_dbg(smb_fname)));
1815 /* Request NO_OPLOCK instead. */
1816 oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
1820 /* Covert generic bits in the security descriptor. */
1822 security_acl_map_generic(sd->dacl, &file_generic_mapping);
1823 security_acl_map_generic(sd->sacl, &file_generic_mapping);
1827 * If it's a request for a directory open, deal with it separately.
1830 if (create_options & FILE_DIRECTORY_FILE) {
1832 if (create_options & FILE_NON_DIRECTORY_FILE) {
1833 status = NT_STATUS_INVALID_PARAMETER;
1837 /* Can't open a temp directory. IFS kit test. */
1838 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
1839 (file_attributes & FILE_ATTRIBUTE_TEMPORARY)) {
1840 status = NT_STATUS_INVALID_PARAMETER;
1845 * We will get a create directory here if the Win32
1846 * app specified a security descriptor in the
1847 * CreateDirectory() call.
1850 status = onefs_open_directory(
1853 smb_fname, /* fname */
1854 access_mask, /* access_mask */
1855 share_access, /* share_access */
1856 create_disposition, /* create_disposition*/
1857 create_options, /* create_options */
1858 file_attributes, /* file_attributes */
1865 * Ordinary file case.
1868 status = file_new(req, conn, &fsp);
1869 if(!NT_STATUS_IS_OK(status)) {
1874 * We're opening the stream element of a base_fsp
1875 * we already opened. Set up the base_fsp pointer.
1878 fsp->base_fsp = base_fsp;
1881 status = onefs_open_file_ntcreate(
1884 smb_fname, /* fname */
1885 access_mask, /* access_mask */
1886 share_access, /* share_access */
1887 create_disposition, /* create_disposition*/
1888 create_options, /* create_options */
1889 file_attributes, /* file_attributes */
1890 oplock_request, /* oplock_request */
1894 fsp_data); /* fsp_data */
1896 if(!NT_STATUS_IS_OK(status)) {
1897 file_free(req, fsp);
1901 if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
1903 /* A stream open never opens a directory */
1906 status = NT_STATUS_FILE_IS_A_DIRECTORY;
1911 * Fail the open if it was explicitly a non-directory
1915 if (create_options & FILE_NON_DIRECTORY_FILE) {
1916 status = NT_STATUS_FILE_IS_A_DIRECTORY;
1920 create_options |= FILE_DIRECTORY_FILE;
1922 status = onefs_open_directory(
1925 smb_fname, /* fname */
1926 access_mask, /* access_mask */
1927 share_access, /* share_access */
1928 create_disposition, /* create_disposition*/
1929 create_options, /* create_options */
1930 file_attributes, /* file_attributes */
1937 if (!NT_STATUS_IS_OK(status)) {
1941 fsp->base_fsp = base_fsp;
1945 if ((ea_list != NULL) && (info == FILE_WAS_CREATED)) {
1946 status = set_ea(conn, fsp, smb_fname, ea_list);
1947 if (!NT_STATUS_IS_OK(status)) {
1952 if (!fsp->is_directory && S_ISDIR(smb_fname->st.st_ex_mode)) {
1953 status = NT_STATUS_ACCESS_DENIED;
1957 /* Save the requested allocation size. */
1958 if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
1960 && (allocation_size > smb_fname->st.st_ex_size)) {
1961 fsp->initial_allocation_size = smb_roundup(
1962 fsp->conn, allocation_size);
1963 if (fsp->is_directory) {
1964 /* Can't set allocation size on a directory. */
1965 status = NT_STATUS_ACCESS_DENIED;
1968 if (vfs_allocate_file_space(
1969 fsp, fsp->initial_allocation_size) == -1) {
1970 status = NT_STATUS_DISK_FULL;
1974 fsp->initial_allocation_size = smb_roundup(
1975 fsp->conn, (uint64_t)smb_fname->st.st_ex_size);
1979 DEBUG(10, ("onefs_create_file_unixpath: info=%d\n", info));
1982 if (pinfo != NULL) {
1985 if ((fsp->fh != NULL) && (fsp->fh->fd != -1)) {
1986 SMB_VFS_FSTAT(fsp, &smb_fname->st);
1988 return NT_STATUS_OK;
1991 DEBUG(10, ("onefs_create_file_unixpath: %s\n", nt_errstr(status)));
1994 if (base_fsp && fsp->base_fsp == base_fsp) {
1996 * The close_file below will close
2001 close_file(req, fsp, ERROR_CLOSE);
2004 if (base_fsp != NULL) {
2005 close_file(req, base_fsp, ERROR_CLOSE);
2011 static void destroy_onefs_fsp_data(void *p_data)
2013 struct onefs_fsp_data *fsp_data = (struct onefs_fsp_data *)p_data;
2015 destroy_onefs_callback_record(fsp_data->oplock_callback_id);
2019 * SMB_VFS_CREATE_FILE interface to onefs.
2021 NTSTATUS onefs_create_file(vfs_handle_struct *handle,
2022 struct smb_request *req,
2023 uint16_t root_dir_fid,
2024 struct smb_filename *smb_fname,
2025 uint32_t access_mask,
2026 uint32_t share_access,
2027 uint32_t create_disposition,
2028 uint32_t create_options,
2029 uint32_t file_attributes,
2030 uint32_t oplock_request,
2031 uint64_t allocation_size,
2032 struct security_descriptor *sd,
2033 struct ea_list *ea_list,
2034 files_struct **result,
2037 connection_struct *conn = handle->conn;
2038 struct onefs_fsp_data fsp_data = {};
2039 int info = FILE_WAS_OPENED;
2040 files_struct *fsp = NULL;
2043 DEBUG(10,("onefs_create_file: access_mask = 0x%x "
2044 "file_attributes = 0x%x, share_access = 0x%x, "
2045 "create_disposition = 0x%x create_options = 0x%x "
2046 "oplock_request = 0x%x "
2047 "root_dir_fid = 0x%x, ea_list = 0x%p, sd = 0x%p, "
2049 (unsigned int)access_mask,
2050 (unsigned int)file_attributes,
2051 (unsigned int)share_access,
2052 (unsigned int)create_disposition,
2053 (unsigned int)create_options,
2054 (unsigned int)oplock_request,
2055 (unsigned int)root_dir_fid,
2056 ea_list, sd, smb_fname_str_dbg(smb_fname)));
2058 /* Get the file name if root_dir_fid was specified. */
2059 if (root_dir_fid != 0) {
2060 status = get_relative_fid_filename(conn, req, root_dir_fid,
2062 if (!NT_STATUS_IS_OK(status)) {
2067 /* All file access must go through check_name() */
2068 status = check_name(conn, smb_fname->base_name);
2069 if (!NT_STATUS_IS_OK(status)) {
2073 status = onefs_create_file_unixpath(
2076 smb_fname, /* fname */
2077 access_mask, /* access_mask */
2078 share_access, /* share_access */
2079 create_disposition, /* create_disposition*/
2080 create_options, /* create_options */
2081 file_attributes, /* file_attributes */
2082 oplock_request, /* oplock_request */
2083 allocation_size, /* allocation_size */
2085 ea_list, /* ea_list */
2088 &fsp_data); /* psbuf */
2090 if (!NT_STATUS_IS_OK(status)) {
2094 DEBUG(10, ("onefs_create_file: info=%d\n", info));
2097 * Setup private onefs_fsp_data. Currently the private data struct is
2098 * only used to store the oplock_callback_id so that when the file is
2099 * closed, the onefs_callback_record can be properly cleaned up in the
2100 * oplock_onefs sub-system.
2103 struct onefs_fsp_data *fsp_data_tmp = NULL;
2104 fsp_data_tmp = (struct onefs_fsp_data *)
2105 VFS_ADD_FSP_EXTENSION(handle, fsp, struct onefs_fsp_data,
2106 &destroy_onefs_fsp_data);
2108 if (fsp_data_tmp == NULL) {
2109 status = NT_STATUS_NO_MEMORY;
2113 *fsp_data_tmp = fsp_data;
2117 if (pinfo != NULL) {
2120 return NT_STATUS_OK;
2123 DEBUG(10, ("onefs_create_file: %s\n", nt_errstr(status)));
2126 close_file(req, fsp, ERROR_CLOSE);