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 uint32_t private_flags,
58 struct security_descriptor *sd,
59 struct ea_list *ea_list,
60 files_struct **result,
62 struct onefs_fsp_data *fsp_data);
64 /****************************************************************************
66 ****************************************************************************/
68 static NTSTATUS onefs_open_file(files_struct *fsp,
69 connection_struct *conn,
70 struct smb_request *req,
71 const char *parent_dir,
72 struct smb_filename *smb_fname,
76 uint32 open_access_mask,
80 uint32 create_options,
81 uint32_t new_dos_attributes,
82 struct security_descriptor *sd,
85 struct smb_filename *smb_fname_onefs = NULL;
86 NTSTATUS status = NT_STATUS_OK;
87 int accmode = (flags & O_ACCMODE);
88 int local_flags = flags;
89 bool file_existed = VALID_STAT(smb_fname->st);
96 /* Check permissions */
99 * This code was changed after seeing a client open request
100 * containing the open mode of (DENY_WRITE/read-only) with
101 * the 'create if not exist' bit set. The previous code
102 * would fail to open the file read only on a read-only share
103 * as it was checking the flags parameter directly against O_RDONLY,
104 * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
108 if (!CAN_WRITE(conn)) {
109 /* It's a read-only share - fail if we wanted to write. */
110 if(accmode != O_RDONLY) {
111 DEBUG(3, ("Permission denied opening %s\n",
112 smb_fname_str_dbg(smb_fname)));
113 return NT_STATUS_ACCESS_DENIED;
114 } else if(flags & O_CREAT) {
115 /* We don't want to write - but we must make sure that
116 O_CREAT doesn't create the file if we have write
117 access into the directory.
120 local_flags &= ~O_CREAT;
125 * This little piece of insanity is inspired by the
126 * fact that an NT client can open a file for O_RDONLY,
127 * but set the create disposition to FILE_EXISTS_TRUNCATE.
128 * If the client *can* write to the file, then it expects to
129 * truncate the file, even though it is opening for readonly.
130 * Quicken uses this stupid trick in backup file creation...
131 * Thanks *greatly* to "David W. Chapman Jr." <dwcjr@inethouston.net>
132 * for helping track this one down. It didn't bite us in 2.0.x
133 * as we always opened files read-write in that release. JRA.
136 if ((accmode == O_RDONLY) && ((flags & O_TRUNC) == O_TRUNC)) {
137 DEBUG(10,("onefs_open_file: truncate requested on read-only "
138 "open for file %s\n", smb_fname_str_dbg(smb_fname)));
139 local_flags = (flags & ~O_ACCMODE)|O_RDWR;
142 #if defined(O_NONBLOCK) && defined(S_ISFIFO)
144 * We would block on opening a FIFO with no one else on the
145 * other end. Do what we used to do and add O_NONBLOCK to the
149 if (file_existed && S_ISFIFO(smb_fname->st.st_ex_mode)) {
150 local_flags |= O_NONBLOCK;
154 /* Don't create files with Microsoft wildcard characters. */
157 * wildcard characters are allowed in stream names
158 * only test the basefilename
160 wild = fsp->base_fsp->fsp_name->base_name;
162 wild = smb_fname->base_name;
164 if ((local_flags & O_CREAT) && !file_existed &&
167 * XXX: may need to remvoe this return...
169 * We dont think this check needs to exist. All it does is
170 * block creating files with Microsoft wildcards, which is
171 * fine if the creation originated from NFS or locally and
172 * then was copied via Samba.
174 DEBUG(1, ("onefs_open_file: creating file with wildcard: %s\n",
175 smb_fname_str_dbg(smb_fname)));
176 return NT_STATUS_OBJECT_NAME_INVALID;
179 /* Actually do the open */
183 * Never follow symlinks on a POSIX client. The
184 * client should be doing this.
187 if (fsp->posix_open || !lp_symlinks(SNUM(conn))) {
191 /* Setup a onefs-style smb_fname struct. */
192 status = onefs_stream_prep_smb_fname(talloc_tos(), smb_fname,
194 if (!NT_STATUS_IS_OK(status)) {
198 /* If it's a stream pass in the base_fd */
199 if ((conn->fs_capabilities & FILE_NAMED_STREAMS) &&
200 is_ntfs_stream_smb_fname(smb_fname_onefs)) {
201 SMB_ASSERT(fsp->base_fsp);
203 DEBUG(10, ("Opening a stream: base=%s(%d), stream=%s\n",
204 smb_fname_onefs->base_name, fsp->base_fsp->fh->fd,
205 smb_fname_onefs->stream_name));
207 base_fd = fsp->base_fsp->fh->fd;
210 fsp->fh->fd = onefs_sys_create_file(conn,
212 smb_fname_onefs->stream_name != NULL ?
213 smb_fname_onefs->stream_name :
214 smb_fname_onefs->base_name,
226 TALLOC_FREE(smb_fname_onefs);
228 if (fsp->fh->fd == -1) {
229 if (errno == EMFILE) {
230 static time_t last_warned = 0L;
232 if (time((time_t *) NULL) > last_warned) {
233 DEBUG(0, ("Too many open files, unable "
234 "to open more! smbd's max "
235 "open files = %d, also check "
236 "sysctl kern.maxfiles and "
237 "sysctl kern.maxfilesperproc\n",
238 lp_max_open_files()));
239 last_warned = time((time_t *) NULL);
243 status = map_nt_error_from_unix(errno);
244 DEBUG(3, ("Error opening file %s (%s) (local_flags=%d) "
245 "(flags=%d)\n", smb_fname_str_dbg(smb_fname),
246 strerror(errno), local_flags, flags));
250 if ((local_flags & O_CREAT) && !file_existed) {
252 /* Inherit the ACL if required */
253 if (lp_inherit_perms(SNUM(conn))) {
254 inherit_access_posix_acl(conn, parent_dir,
255 smb_fname->base_name, unx_mode);
258 /* Change the owner if required. */
259 if (lp_inherit_owner(SNUM(conn))) {
260 change_file_owner_to_parent(conn, parent_dir,
264 notify_fname(conn, NOTIFY_ACTION_ADDED,
265 FILE_NOTIFY_CHANGE_FILE_NAME, smb_fname->base_name);
271 if (fsp->fh->fd == -1) {
272 ret = SMB_VFS_STAT(conn, smb_fname);
274 ret = SMB_VFS_FSTAT(fsp, &smb_fname->st);
275 /* If we have an fd, this stat should succeed. */
277 DEBUG(0, ("Error doing fstat on open file %s "
279 smb_fname_str_dbg(smb_fname),
284 /* For a non-io open, this stat failing means file not found. JRA */
286 status = map_nt_error_from_unix(errno);
293 * POSIX allows read-only opens of directories. We don't
294 * want to do this (we use a different code path for this)
295 * so catch a directory open and return an EISDIR. JRA.
298 if(S_ISDIR(smb_fname->st.st_ex_mode)) {
301 return NT_STATUS_FILE_IS_A_DIRECTORY;
304 fsp->mode = smb_fname->st.st_ex_mode;
305 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
306 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
307 fsp->file_pid = req ? req->smbpid : 0;
308 fsp->can_lock = True;
309 fsp->can_read = (access_mask & (FILE_READ_DATA)) ? True : False;
310 if (!CAN_WRITE(conn)) {
311 fsp->can_write = False;
313 fsp->can_write = (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ?
316 fsp->print_file = False;
317 fsp->modified = False;
318 fsp->sent_oplock_break = NO_BREAK_SENT;
319 fsp->is_directory = False;
320 if (conn->aio_write_behind_list &&
321 is_in_path(smb_fname->base_name, conn->aio_write_behind_list,
322 conn->case_sensitive)) {
323 fsp->aio_write_behind = True;
326 fsp->wcp = NULL; /* Write cache pointer. */
328 DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
329 conn->server_info->unix_name,
330 smb_fname_str_dbg(smb_fname),
331 BOOLSTR(fsp->can_read), BOOLSTR(fsp->can_write),
332 conn->num_files_open));
338 /****************************************************************************
339 Handle the 1 second delay in returning a SHARING_VIOLATION error.
340 ****************************************************************************/
342 static void defer_open(struct share_mode_lock *lck,
343 struct timeval request_time,
344 struct timeval timeout,
345 struct smb_request *req,
346 struct deferred_open_record *state)
352 for (i=0; i<lck->num_share_modes; i++) {
353 struct share_mode_entry *e = &lck->share_modes[i];
355 if (!is_deferred_open_entry(e)) {
359 if (procid_is_me(&e->pid) && (e->op_mid == req->mid)) {
360 DEBUG(0, ("Trying to defer an already deferred "
361 "request: mid=%llu, exiting\n",
362 (unsigned long long)req->mid));
363 exit_server("attempt to defer a deferred request");
367 /* End paranoia check */
369 DEBUG(10,("defer_open_sharing_error: time [%u.%06u] adding deferred "
370 "open entry for mid %llu\n",
371 (unsigned int)request_time.tv_sec,
372 (unsigned int)request_time.tv_usec,
373 (unsigned long long)req->mid));
375 if (!push_deferred_open_message_smb(req, request_time, timeout,
376 (char *)state, sizeof(*state))) {
377 exit_server("push_deferred_open_message_smb failed");
379 add_deferred_open(lck, req->mid, request_time, state->id);
382 static void schedule_defer_open(struct share_mode_lock *lck,
383 struct timeval request_time,
384 struct smb_request *req)
386 struct deferred_open_record state;
388 /* This is a relative time, added to the absolute
389 request_time value to get the absolute timeout time.
390 Note that if this is the second or greater time we enter
391 this codepath for this particular request mid then
392 request_time is left as the absolute time of the *first*
393 time this request mid was processed. This is what allows
394 the request to eventually time out. */
396 struct timeval timeout;
398 /* Normally the smbd we asked should respond within
399 * OPLOCK_BREAK_TIMEOUT seconds regardless of whether
400 * the client did, give twice the timeout as a safety
401 * measure here in case the other smbd is stuck
405 * On OneFS, the kernel will always send an oplock_revoked message
406 * before this timeout is hit.
408 timeout = timeval_set(OPLOCK_BREAK_TIMEOUT*10, 0);
410 /* Nothing actually uses state.delayed_for_oplocks
411 but it's handy to differentiate in debug messages
412 between a 30 second delay due to oplock break, and
413 a 1 second delay for share mode conflicts. */
415 state.delayed_for_oplocks = True;
416 state.failed = false;
419 if (!request_timed_out(request_time, timeout)) {
420 defer_open(lck, request_time, timeout, req, &state);
422 /* A delayed-for-oplocks deferred open timing out should only
423 * happen if there is a bug or extreme load, since we set the
424 * timeout to 300 seconds. */
425 DEBUG(0, ("Deferred open timeout! request_time=%d.%d, "
426 "mid=%d\n", request_time.tv_sec, request_time.tv_usec,
431 /****************************************************************************
432 Open a file with a share mode. Passed in an already created files_struct.
433 ****************************************************************************/
434 NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
435 struct smb_request *req,
436 struct smb_filename *smb_fname,
439 uint32 create_disposition,
440 uint32 create_options,
441 uint32 new_dos_attributes,
443 uint32_t private_flags,
444 struct security_descriptor *sd,
447 struct onefs_fsp_data *fsp_data)
451 bool file_existed = VALID_STAT(smb_fname->st);
452 bool def_acl = False;
453 bool posix_open = False;
454 bool new_file_created = False;
455 bool clear_ads = False;
457 mode_t new_unx_mode = (mode_t)0;
458 mode_t unx_mode = (mode_t)0;
460 uint32 existing_dos_attributes = 0;
461 struct timeval request_time = timeval_zero();
462 struct share_mode_lock *lck = NULL;
463 uint32 open_access_mask = access_mask;
468 uint64_t oplock_callback_id = 0;
469 uint32 createfile_attributes = 0;
475 * Printers are handled completely differently.
476 * Most of the passed parameters are ignored.
480 *pinfo = FILE_WAS_CREATED;
483 DEBUG(10, ("onefs_open_file_ntcreate: printer open fname=%s\n",
484 smb_fname_str_dbg(smb_fname)));
486 return print_fsp_open(req, conn, smb_fname->base_name,
490 if (!parent_dirname(talloc_tos(), smb_fname->base_name, &parent_dir,
492 return NT_STATUS_NO_MEMORY;
495 if (new_dos_attributes & FILE_FLAG_POSIX_SEMANTICS) {
497 unx_mode = (mode_t)(new_dos_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
498 new_dos_attributes = 0;
500 /* We add aARCH to this as this mode is only used if the file is
502 unx_mode = unix_mode(conn, new_dos_attributes | aARCH,
503 smb_fname, parent_dir);
506 DEBUG(10,("onefs_open_file_ntcreate: fname=%s, dos_attrs=0x%x "
507 "access_mask=0x%x share_access=0x%x "
508 "create_disposition = 0x%x create_options=0x%x "
509 "unix mode=0%o oplock_request=0x%x\n",
510 smb_fname_str_dbg(smb_fname), new_dos_attributes,
511 access_mask, share_access, create_disposition,
512 create_options, unx_mode, oplock_request));
515 * Any non-stat-only open has the potential to contend oplocks, which
516 * means to avoid blocking in the kernel (which is unacceptable), the
517 * open must be deferred. In order to defer opens, req must not be
518 * NULL. The known cases of calling with a NULL req:
520 * 1. Open the base file of a stream: Always done stat-only
522 * 2. open_file_fchmod(), which is called from 3 places:
523 * A. try_chown: Posix acls only. Never called on onefs.
524 * B. set_ea_dos_attributes: Can't be called from onefs, because
525 * SMB_VFS_SETXATTR return ENOSYS.
526 * C. file_set_dos_mode: This would only happen if the "dos
527 * filemode" smb.conf parameter is set to yes. We ship with
528 * it off, but if a customer were to turn it on it would be
531 if (req == NULL && !is_stat_open(access_mask) &&
532 !is_ntfs_stream_smb_fname(smb_fname)) {
533 smb_panic("NULL req on a non-stat-open!");
536 if ((req == NULL) && ((oplock_request & INTERNAL_OPEN_ONLY) == 0)) {
537 DEBUG(0, ("No smb request but not an internal only open!\n"));
538 return NT_STATUS_INTERNAL_ERROR;
542 * Only non-internal opens can be deferred at all
547 if (get_deferred_open_message_state(req->mid,
550 struct deferred_open_record *state = (struct deferred_open_record *)ptr;
552 /* Remember the absolute time of the original
553 request with this mid. We'll use it later to
554 see if this has timed out. */
556 /* Remove the deferred open entry under lock. */
557 lck = get_share_mode_lock(talloc_tos(), state->id,
560 DEBUG(0, ("could not get share mode lock\n"));
562 del_deferred_open_entry(lck, req->mid);
566 /* Ensure we don't reprocess this message. */
567 remove_deferred_open_message_smb(req->mid);
570 * When receiving a semlock_async_failure message, the
571 * deferred open will be marked as "failed". Returning
575 DEBUG(0, ("onefs_open_file_ntcreate: "
576 "semlock_async_failure detected!\n"));
577 return NT_STATUS_INTERNAL_ERROR;
582 status = check_name(conn, smb_fname->base_name);
583 if (!NT_STATUS_IS_OK(status)) {
588 new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
590 existing_dos_attributes = dos_mode(conn, smb_fname);
594 /* Setup dos_attributes to be set by ifs_createfile */
595 if (lp_store_dos_attributes(SNUM(conn))) {
596 createfile_attributes = (new_dos_attributes | aARCH) &
597 ~(FILE_ATTRIBUTE_NONINDEXED | FILE_ATTRIBUTE_COMPRESSED);
600 /* Ignore oplock requests if oplocks are disabled. */
601 if (!lp_oplocks(SNUM(conn)) || global_client_failed_oplock_break ||
602 IS_VETO_OPLOCK_PATH(conn, smb_fname->base_name)) {
603 /* Mask off everything except the private Samba bits. */
604 oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
607 /* this is for OS/2 long file names - say we don't support them */
608 if (!lp_posix_pathnames() && strstr(smb_fname->base_name,".+,;=[].")) {
609 /* OS/2 Workplace shell fix may be main code stream in a later
611 DEBUG(5,("onefs_open_file_ntcreate: OS/2 long filenames are "
612 "not supported.\n"));
613 if (use_nt_status()) {
614 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
616 return NT_STATUS_DOS(ERRDOS, ERRcannotopen);
619 switch( create_disposition ) {
621 * Currently we're using FILE_SUPERSEDE as the same as
622 * FILE_OVERWRITE_IF but they really are
623 * different. FILE_SUPERSEDE deletes an existing file
624 * (requiring delete access) then recreates it.
628 * @todo: Clear all file attributes?
629 * http://www.osronline.com/article.cfm?article=302
630 * create if not exist, trunc if exist
632 * If file exists replace/overwrite. If file doesn't
635 flags2 |= (O_CREAT | O_TRUNC);
639 case FILE_OVERWRITE_IF:
640 /* If file exists replace/overwrite. If file doesn't
642 flags2 |= (O_CREAT | O_TRUNC);
647 /* If file exists open. If file doesn't exist error. */
649 DEBUG(5,("onefs_open_file_ntcreate: FILE_OPEN "
650 "requested for file %s and file "
652 smb_fname_str_dbg(smb_fname)));
654 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
659 /* If file exists overwrite. If file doesn't exist
662 DEBUG(5, ("onefs_open_file_ntcreate: "
663 "FILE_OVERWRITE requested for file "
664 "%s and file doesn't exist.\n",
665 smb_fname_str_dbg(smb_fname)));
667 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
674 /* If file exists error. If file doesn't exist
677 DEBUG(5, ("onefs_open_file_ntcreate: "
678 "FILE_CREATE requested for file %s "
679 "and file already exists.\n",
680 smb_fname_str_dbg(smb_fname)));
681 if (S_ISDIR(smb_fname->st.st_ex_mode)) {
686 return map_nt_error_from_unix(errno);
688 flags2 |= (O_CREAT|O_EXCL);
692 /* If file exists open. If file doesn't exist
698 return NT_STATUS_INVALID_PARAMETER;
701 /* Match attributes on file exists and overwrite. */
702 if (!posix_open && file_existed &&
703 ((create_disposition == FILE_OVERWRITE) ||
704 (create_disposition == FILE_OVERWRITE_IF))) {
705 if (!open_match_attributes(conn, existing_dos_attributes,
707 smb_fname->st.st_ex_mode,
708 unx_mode, &new_unx_mode)) {
709 DEBUG(5, ("onefs_open_file_ntcreate: attributes "
710 "missmatch for file %s (%x %x) (0%o, 0%o)\n",
711 smb_fname_str_dbg(smb_fname),
712 existing_dos_attributes,
714 (unsigned int)smb_fname->st.st_ex_mode,
715 (unsigned int)unx_mode ));
717 return NT_STATUS_ACCESS_DENIED;
722 * OneFS understands MAXIMUM_ALLOWED_ACCESS, so only hack the
723 * access_mask, but leave the MAA for the actual open in
726 open_access_mask = access_mask;
727 if (open_access_mask & MAXIMUM_ALLOWED_ACCESS) {
728 access_mask |= FILE_GENERIC_ALL;
731 /* Convert GENERIC bits to specific bits. */
732 se_map_generic(&access_mask, &file_generic_mapping);
733 se_map_generic(&open_access_mask, &file_generic_mapping);
735 if ((flags2 & O_TRUNC) || (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE)) {
736 /* This will cause oplock breaks. */
737 open_access_mask |= FILE_WRITE_DATA;
740 DEBUG(10, ("onefs_open_file_ntcreate: fname=%s, after mapping "
741 "open_access_mask=%#x, access_mask=0x%x\n",
742 smb_fname_str_dbg(smb_fname), open_access_mask,
746 * Note that we ignore the append flag as append does not
747 * mean the same thing under DOS and Unix.
750 if ((access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ||
751 (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE)) {
754 * DENY_DOS opens are always underlying read-write on the
755 * file handle, no matter what the requested access mask
756 * says. Stock samba just sets the flags, but since
757 * ifs_createfile uses the access_mask, it must be updated as
758 * well. This allows BASE-DENY* to pass.
760 if (create_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) {
762 DEBUG(10,("onefs_open_file_ntcreate: deny_dos: "
763 "Adding O_RDWR to flags "
764 "(0x%x) and some READ bits to "
765 "open_access_mask (0x%x)\n",
766 flags, open_access_mask));
769 open_access_mask |= (FILE_READ_ATTRIBUTES |
770 FILE_READ_DATA | FILE_READ_EA | FILE_EXECUTE);
772 } else if (access_mask & (FILE_READ_ATTRIBUTES |
784 /* Currently we only look at FILE_WRITE_THROUGH for create options. */
786 if ((create_options & FILE_WRITE_THROUGH) &&
787 lp_strict_sync(SNUM(conn))) {
792 if (posix_open && (access_mask & FILE_APPEND_DATA)) {
796 if (!posix_open && !CAN_WRITE(conn)) {
798 * We should really return a permission denied error if either
799 * O_CREAT or O_TRUNC are set, but for compatibility with
800 * older versions of Samba we just AND them out.
802 flags2 &= ~(O_CREAT|O_TRUNC);
804 /* Deny DELETE_ACCESS explicitly if the share is read only. */
805 if (access_mask & DELETE_ACCESS) {
806 return map_nt_error_from_unix(EACCES);
810 /* Ensure we can't write on a read-only share or file. */
811 if (flags != O_RDONLY && file_existed &&
812 (!CAN_WRITE(conn) || IS_DOS_READONLY(existing_dos_attributes))) {
813 DEBUG(5, ("onefs_open_file_ntcreate: write access requested "
814 "for file %s on read only %s\n",
815 smb_fname_str_dbg(smb_fname),
816 !CAN_WRITE(conn) ? "share" : "file" ));
818 return NT_STATUS_ACCESS_DENIED;
821 DEBUG(10, ("fsp = %p\n", fsp));
823 fsp->share_access = share_access;
824 fsp->fh->private_options = private_flags;
825 fsp->access_mask = open_access_mask; /* We change this to the
826 * requested access_mask after
827 * the open is done. */
828 fsp->posix_open = posix_open;
830 /* Ensure no SAMBA_PRIVATE bits can be set. */
831 fsp->oplock_type = (oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK);
833 if (timeval_is_zero(&request_time)) {
834 request_time = fsp->open_time;
838 struct timespec old_write_time = smb_fname->st.st_ex_mtime;
839 id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
841 lck = get_share_mode_lock(talloc_tos(), id,
843 smb_fname, &old_write_time);
846 DEBUG(0, ("Could not get share mode lock\n"));
847 return NT_STATUS_SHARING_VIOLATION;
850 if (lck->delete_on_close) {
851 /* DELETE_PENDING is not deferred for a second */
853 return NT_STATUS_DELETE_PENDING;
857 SMB_ASSERT(!file_existed || (lck != NULL));
860 * Ensure we pay attention to default ACLs on directories. May be
861 * neccessary depending on ACL policies.
863 if ((flags2 & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
864 (def_acl = directory_has_default_acl(conn, parent_dir))) {
868 DEBUG(4,("calling onefs_open_file with flags=0x%X flags2=0x%X "
869 "mode=0%o, access_mask = 0x%x, open_access_mask = 0x%x\n",
870 (unsigned int)flags, (unsigned int)flags2,
871 (unsigned int)unx_mode, (unsigned int)access_mask,
872 (unsigned int)open_access_mask));
875 * Since the open is guaranteed to be stat only if req == NULL, a
876 * callback record is only needed if req != NULL.
879 SMB_ASSERT(fsp_data);
880 oplock_callback_id = onefs_oplock_wait_record(req->mid);
881 if (oplock_callback_id == 0) {
882 return NT_STATUS_NO_MEMORY;
886 * It is also already asserted it's either a stream or a
887 * stat-only open at this point.
889 SMB_ASSERT(fsp->oplock_type == NO_OPLOCK);
891 /* The kernel and Samba's version of stat-only differs
892 * slightly: The kernel doesn't think its stat-only if we're
893 * truncating. We'd better have a req in order to defer the
895 SMB_ASSERT(!((flags|flags2) & O_TRUNC));
899 status = onefs_open_file(fsp,
912 createfile_attributes,
916 if (!NT_STATUS_IS_OK(status)) {
918 /* OneFS Oplock Handling */
919 if (errno == EINPROGRESS) {
921 /* If we get EINPROGRESS, the kernel will send us an
922 * asynchronous semlock event back. Ensure we can defer
923 * the open, by asserting req. */
928 * We hit the race that when we did the stat
929 * on the file it did not exist, and someone
930 * has created it in between the stat and the
931 * open_file() call. Defer our open waiting,
932 * to break the oplock of the first opener.
935 struct timespec old_write_time;
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 /* If we raced on open we may not have a valid file_id
985 * or stat buf. Get them again. */
986 if (SMB_VFS_STAT(conn, fname, psbuf) == -1) {
987 DEBUG(0,("Error doing stat on file %s "
988 "(%s)\n", fname, strerror(errno)));
989 status = NT_STATUS_SHARING_VIOLATION;
990 goto cleanup_destroy;
992 id = vfs_file_id_from_sbuf(conn, psbuf);
994 /* Check if this can be done with the deny_dos and fcb
997 /* Try to find dup fsp if possible. */
999 (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS|
1000 NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) {
1003 DEBUG(0, ("DOS open without an SMB "
1005 status = NT_STATUS_INTERNAL_ERROR;
1006 goto cleanup_destroy;
1009 /* Use the client requested access mask here,
1010 * not the one we open with. */
1011 status = fcb_or_dos_open(req,
1022 if (NT_STATUS_IS_OK(status)) {
1024 *pinfo = FILE_WAS_OPENED;
1026 status = NT_STATUS_OK;
1032 * This next line is a subtlety we need for
1033 * MS-Access. If a file open will fail due to share
1034 * permissions and also for security (access) reasons,
1035 * we need to return the access failed error, not the
1036 * share error. We can't open the file due to kernel
1037 * oplock deadlock (it's possible we failed above on
1038 * the open_mode_check()) so use a userspace check.
1041 if (flags & O_RDWR) {
1042 can_access_mask = FILE_READ_DATA|FILE_WRITE_DATA;
1043 } else if (flags & O_WRONLY) {
1044 can_access_mask = FILE_WRITE_DATA;
1046 can_access_mask = FILE_READ_DATA;
1049 if (((can_access_mask & FILE_WRITE_DATA) &&
1050 !CAN_WRITE(conn)) ||
1051 !can_access_file_data(conn, smb_fname,
1057 * If we're returning a share violation, ensure we
1058 * cope with the braindead 1 second delay.
1060 if (!(oplock_request & INTERNAL_OPEN_ONLY) &&
1061 lp_defer_sharing_violations()) {
1062 struct timeval timeout;
1063 struct deferred_open_record state;
1066 /* this is a hack to speed up torture tests
1068 timeout_usecs = lp_parm_int(SNUM(conn),
1069 "smbd","sharedelay",
1070 SHARING_VIOLATION_USEC_WAIT);
1072 /* This is a relative time, added to the
1073 absolute request_time value to get the
1074 absolute timeout time. Note that if this
1075 is the second or greater time we enter this
1076 codepath for this particular request mid
1077 then request_time is left as the absolute
1078 time of the *first* time this request mid
1079 was processed. This is what allows the
1080 request to eventually time out. */
1082 timeout = timeval_set(0, timeout_usecs);
1084 /* Nothing actually uses
1085 state.delayed_for_oplocks but it's handy to
1086 differentiate in debug messages between a
1087 30 second delay due to oplock break, and a
1088 1 second delay for share mode conflicts. */
1090 state.delayed_for_oplocks = False;
1092 state.failed = false;
1095 * We hit the race that when we did the stat
1096 * on the file it did not exist, and someone
1097 * has created it in between the stat and the
1098 * open_file() call. Retrieve the share_mode
1099 * lock on the newly opened file so we can
1100 * defer our request.
1103 struct timespec old_write_time;
1104 old_write_time = get_mtimespec(psbuf);
1106 lck = get_share_mode_lock(talloc_tos(),
1107 id, conn->connectpath, fname,
1111 ("onefs_open_file_ntcreate:"
1112 " Could not get share "
1113 "mode lock for %s\n",
1115 /* This will cause us to return
1116 * immediately skipping the
1117 * the 1 second delay, which
1118 * isn't a big deal */
1119 status = NT_STATUS_SHARING_VIOLATION;
1120 goto cleanup_destroy;
1124 if ((req != NULL) &&
1125 !request_timed_out(request_time, timeout))
1127 defer_open(lck, request_time, timeout,
1134 * We have detected a sharing violation here
1135 * so return the correct error code
1137 status = NT_STATUS_SHARING_VIOLATION;
1139 status = NT_STATUS_ACCESS_DENIED;
1142 goto cleanup_destroy;
1146 * Normal error, for example EACCES
1149 if (oplock_callback_id != 0) {
1150 destroy_onefs_callback_record(oplock_callback_id);
1157 fsp->oplock_type = granted_oplock;
1159 if (oplock_callback_id != 0) {
1160 onefs_set_oplock_callback(oplock_callback_id, fsp);
1161 fsp_data->oplock_callback_id = oplock_callback_id;
1163 SMB_ASSERT(fsp->oplock_type == NO_OPLOCK);
1166 if (!file_existed) {
1167 struct timespec old_write_time = smb_fname->st.st_ex_mtime;
1169 * Deal with the race condition where two smbd's detect the
1170 * file doesn't exist and do the create at the same time. One
1171 * of them will win and set a share mode, the other (ie. this
1172 * one) should check if the requested share mode for this
1173 * create is allowed.
1177 * Now the file exists and fsp is successfully opened,
1178 * fsp->file_id is valid and should replace the
1179 * dev=0, inode=0 from a non existent file. Spotted by
1180 * Nadav Danieli <nadavd@exanet.com>. JRA.
1185 lck = get_share_mode_lock(talloc_tos(), id,
1187 smb_fname, &old_write_time);
1190 DEBUG(0, ("onefs_open_file_ntcreate: Could not get "
1191 "share mode lock for %s\n",
1192 smb_fname_str_dbg(smb_fname)));
1194 return NT_STATUS_SHARING_VIOLATION;
1197 if (lck->delete_on_close) {
1198 status = NT_STATUS_DELETE_PENDING;
1201 if (!NT_STATUS_IS_OK(status)) {
1202 struct deferred_open_record state;
1206 state.delayed_for_oplocks = False;
1209 /* Do it all over again immediately. In the second
1210 * round we will find that the file existed and handle
1211 * the DELETE_PENDING and FCB cases correctly. No need
1212 * to duplicate the code here. Essentially this is a
1213 * "goto top of this function", but don't tell
1217 defer_open(lck, request_time, timeval_zero(),
1225 * We exit this block with the share entry *locked*.....
1230 SMB_ASSERT(lck != NULL);
1232 /* Delete streams if create_disposition requires it */
1233 if (file_existed && clear_ads &&
1234 !is_ntfs_stream_smb_fname(smb_fname)) {
1235 status = delete_all_streams(conn, smb_fname->base_name);
1236 if (!NT_STATUS_IS_OK(status)) {
1243 /* note that we ignore failure for the following. It is
1244 basically a hack for NFS, and NFS will never set one of
1245 these only read them. Nobody but Samba can ever set a deny
1246 mode and we have already checked our more authoritative
1247 locking database for permission to set this deny mode. If
1248 the kernel refuses the operations then the kernel is wrong.
1249 note that GPFS supports it as well - jmcd */
1251 if (fsp->fh->fd != -1) {
1252 ret_flock = SMB_VFS_KERNEL_FLOCK(fsp, share_access, access_mask);
1253 if(ret_flock == -1 ){
1257 return NT_STATUS_SHARING_VIOLATION;
1262 * At this point onwards, we can guarentee that the share entry
1263 * is locked, whether we created the file or not, and that the
1264 * deny mode is compatible with all current opens.
1268 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
1270 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
1273 /* stat opens on existing files don't get oplocks. */
1274 if (is_stat_open(open_access_mask)) {
1275 fsp->oplock_type = NO_OPLOCK;
1278 if (!(flags2 & O_TRUNC)) {
1279 info = FILE_WAS_OPENED;
1281 info = FILE_WAS_OVERWRITTEN;
1284 info = FILE_WAS_CREATED;
1292 * Setup the oplock info in both the shared memory and
1296 if ((fsp->oplock_type != NO_OPLOCK) &&
1297 (fsp->oplock_type != FAKE_LEVEL_II_OPLOCK)) {
1298 if (!set_file_oplock(fsp, fsp->oplock_type)) {
1299 /* Could not get the kernel oplock */
1300 fsp->oplock_type = NO_OPLOCK;
1304 if (fsp->oplock_type == LEVEL_II_OPLOCK &&
1305 (!lp_level2_oplocks(SNUM(conn)) ||
1306 !(global_client_caps & CAP_LEVEL_II_OPLOCKS))) {
1308 DEBUG(5, ("Downgrading level2 oplock on open "
1309 "because level2 oplocks = off\n"));
1311 release_file_oplock(fsp);
1314 if (info == FILE_WAS_OVERWRITTEN || info == FILE_WAS_CREATED ||
1315 info == FILE_WAS_SUPERSEDED) {
1316 new_file_created = True;
1319 set_share_mode(lck, fsp, conn->server_info->utok.uid, 0,
1322 /* Handle strange delete on close create semantics. */
1323 if (create_options & FILE_DELETE_ON_CLOSE) {
1324 status = can_set_delete_on_close(fsp, new_dos_attributes);
1326 if (!NT_STATUS_IS_OK(status)) {
1327 /* Remember to delete the mode we just added. */
1328 del_share_mode(lck, fsp);
1333 /* Note that here we set the *inital* delete on close flag,
1334 not the regular one. The magic gets handled in close. */
1335 fsp->initial_delete_on_close = True;
1339 * Take care of inherited ACLs on created files - if default ACL not
1341 * May be necessary depending on acl policies.
1343 if (!posix_open && !file_existed && !def_acl &&
1344 !(VALID_STAT(smb_fname->st) &&
1345 (smb_fname->st.st_ex_flags & SF_HASNTFSACL))) {
1347 int saved_errno = errno; /* We might get ENOSYS in the next
1350 if (SMB_VFS_FCHMOD_ACL(fsp, unx_mode) == -1 &&
1352 errno = saved_errno; /* Ignore ENOSYS */
1355 } else if (new_unx_mode) {
1359 /* Attributes need changing. File already existed. */
1362 int saved_errno = errno; /* We might get ENOSYS in the
1364 ret = SMB_VFS_FCHMOD_ACL(fsp, new_unx_mode);
1366 if (ret == -1 && errno == ENOSYS) {
1367 errno = saved_errno; /* Ignore ENOSYS */
1369 DEBUG(5, ("onefs_open_file_ntcreate: reset "
1370 "attributes of file %s to 0%o\n",
1371 smb_fname_str_dbg(smb_fname),
1372 (unsigned int)new_unx_mode));
1373 ret = 0; /* Don't do the fchmod below. */
1378 (SMB_VFS_FCHMOD(fsp, new_unx_mode) == -1))
1379 DEBUG(5, ("onefs_open_file_ntcreate: failed to reset "
1380 "attributes of file %s to 0%o\n",
1381 smb_fname_str_dbg(smb_fname),
1382 (unsigned int)new_unx_mode));
1385 /* If this is a successful open, we must remove any deferred open
1388 del_deferred_open_entry(lck, req->mid);
1392 return NT_STATUS_OK;
1396 /****************************************************************************
1397 Open a directory from an NT SMB call.
1398 ****************************************************************************/
1399 static NTSTATUS onefs_open_directory(connection_struct *conn,
1400 struct smb_request *req,
1401 struct smb_filename *smb_dname,
1403 uint32 share_access,
1404 uint32 create_disposition,
1405 uint32 create_options,
1406 uint32 file_attributes,
1407 struct security_descriptor *sd,
1408 files_struct **result,
1411 files_struct *fsp = NULL;
1412 struct share_mode_lock *lck = NULL;
1414 struct timespec mtimespec;
1417 bool posix_open = false;
1418 uint32 create_flags = 0;
1419 uint32 mode = lp_dir_mask(SNUM(conn));
1421 DEBUG(5, ("onefs_open_directory: opening directory %s, "
1422 "access_mask = 0x%x, "
1423 "share_access = 0x%x create_options = 0x%x, "
1424 "create_disposition = 0x%x, file_attributes = 0x%x\n",
1425 smb_fname_str_dbg(smb_dname), (unsigned int)access_mask,
1426 (unsigned int)share_access, (unsigned int)create_options,
1427 (unsigned int)create_disposition,
1428 (unsigned int)file_attributes));
1430 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
1431 (conn->fs_capabilities & FILE_NAMED_STREAMS) &&
1432 is_ntfs_stream_smb_fname(smb_dname)) {
1433 DEBUG(2, ("onefs_open_directory: %s is a stream name!\n",
1434 smb_fname_str_dbg(smb_dname)));
1435 return NT_STATUS_NOT_A_DIRECTORY;
1438 switch (create_disposition) {
1440 /* If directory exists open. If directory doesn't
1443 info = FILE_WAS_OPENED;
1446 /* If directory exists error. If directory doesn't
1448 create_flags = O_CREAT | O_EXCL;
1449 info = FILE_WAS_CREATED;
1452 /* If directory exists open. If directory doesn't
1455 /* Note: in order to return whether the directory was
1456 * opened or created, we first try to open and then try
1459 info = FILE_WAS_OPENED;
1461 case FILE_SUPERSEDE:
1462 case FILE_OVERWRITE:
1463 case FILE_OVERWRITE_IF:
1465 DEBUG(5, ("onefs_open_directory: invalid "
1466 "create_disposition 0x%x for directory %s\n",
1467 (unsigned int)create_disposition,
1468 smb_fname_str_dbg(smb_dname)));
1469 return NT_STATUS_INVALID_PARAMETER;
1473 * Check for write access to the share. Done in mkdir_internal() in
1476 if (!CAN_WRITE(conn) && (create_flags & O_CREAT)) {
1477 return NT_STATUS_ACCESS_DENIED;
1480 /* Get parent dirname */
1481 if (!parent_dirname(talloc_tos(), smb_dname->base_name, &parent_dir,
1483 return NT_STATUS_NO_MEMORY;
1486 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
1488 mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
1489 file_attributes = 0;
1491 mode = unix_mode(conn, aDIR, smb_dname, parent_dir);
1495 * The NONINDEXED and COMPRESSED bits seem to always be cleared on
1496 * directories, no matter if you specify that they should be set.
1499 ~(FILE_ATTRIBUTE_NONINDEXED | FILE_ATTRIBUTE_COMPRESSED);
1501 status = file_new(req, conn, &fsp);
1502 if(!NT_STATUS_IS_OK(status)) {
1507 * Actual open with retry magic to handle FILE_OPEN_IF which is
1508 * unique because the kernel won't tell us if the file was opened or
1512 fsp->fh->fd = onefs_sys_create_file(conn,
1514 smb_dname->base_name,
1519 create_flags | O_DIRECTORY,
1527 if (fsp->fh->fd == -1) {
1528 DEBUG(3, ("Error opening %s. Errno=%d (%s).\n",
1529 smb_fname_str_dbg(smb_dname), errno,
1531 SMB_ASSERT(errno != EINPROGRESS);
1533 if (create_disposition == FILE_OPEN_IF) {
1534 if (errno == ENOENT) {
1535 /* Try again, creating it this time. */
1536 create_flags = O_CREAT | O_EXCL;
1537 info = FILE_WAS_CREATED;
1539 } else if (errno == EEXIST) {
1540 /* Uggh. Try again again. */
1542 info = FILE_WAS_OPENED;
1547 /* Error cases below: */
1548 file_free(req, fsp);
1550 if ((errno == ENOENT) && (create_disposition == FILE_OPEN)) {
1551 DEBUG(5, ("onefs_open_directory: FILE_OPEN requested "
1552 "for directory %s and it doesn't "
1553 "exist.\n", smb_fname_str_dbg(smb_dname)));
1554 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1555 } else if ((errno == EEXIST) &&
1556 (create_disposition == FILE_CREATE)) {
1557 DEBUG(5, ("onefs_open_directory: FILE_CREATE "
1558 "requested for directory %s and it "
1559 "already exists.\n",
1560 smb_fname_str_dbg(smb_dname)));
1561 return NT_STATUS_OBJECT_NAME_COLLISION;
1562 } else if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
1563 /* Catch sharing violations. */
1564 return NT_STATUS_SHARING_VIOLATION;
1567 return map_nt_error_from_unix(errno);
1570 if (info == FILE_WAS_CREATED) {
1572 /* Pulled from mkdir_internal() */
1573 if (SMB_VFS_LSTAT(conn, smb_dname) == -1) {
1574 DEBUG(2, ("Could not stat directory '%s' just "
1576 smb_fname_str_dbg(smb_dname),
1578 return map_nt_error_from_unix(errno);
1581 if (!S_ISDIR(smb_dname->st.st_ex_mode)) {
1582 DEBUG(0, ("Directory just '%s' created is not a "
1584 smb_fname_str_dbg(smb_dname)));
1585 return NT_STATUS_ACCESS_DENIED;
1590 * Check if high bits should have been set, then (if
1591 * bits are missing): add them. Consider bits
1592 * automagically set by UNIX, i.e. SGID bit from
1595 if (mode & ~(S_IRWXU|S_IRWXG|S_IRWXO) &&
1596 (mode & ~smb_dname->st.st_ex_mode)) {
1597 SMB_VFS_CHMOD(conn, smb_dname->base_name,
1598 (smb_dname->st.st_ex_mode |
1599 (mode & ~smb_dname->st.st_ex_mode)));
1603 /* Change the owner if required. */
1604 if (lp_inherit_owner(SNUM(conn))) {
1605 change_dir_owner_to_parent(conn, parent_dir,
1606 smb_dname->base_name,
1610 notify_fname(conn, NOTIFY_ACTION_ADDED,
1611 FILE_NOTIFY_CHANGE_DIR_NAME,
1612 smb_dname->base_name);
1615 /* Stat the fd for Samba bookkeeping. */
1616 if(SMB_VFS_FSTAT(fsp, &smb_dname->st) != 0) {
1618 file_free(req, fsp);
1619 return map_nt_error_from_unix(errno);
1622 /* Setup the files_struct for it. */
1623 fsp->mode = smb_dname->st.st_ex_mode;
1624 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_dname->st);
1625 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
1626 fsp->file_pid = req ? req->smbpid : 0;
1627 fsp->can_lock = False;
1628 fsp->can_read = False;
1629 fsp->can_write = False;
1631 fsp->share_access = share_access;
1632 fsp->fh->private_options = 0;
1634 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
1636 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
1637 fsp->print_file = False;
1638 fsp->modified = False;
1639 fsp->oplock_type = NO_OPLOCK;
1640 fsp->sent_oplock_break = NO_BREAK_SENT;
1641 fsp->is_directory = True;
1642 fsp->posix_open = posix_open;
1644 status = fsp_set_smb_fname(fsp, smb_dname);
1645 if (!NT_STATUS_IS_OK(status)) {
1647 file_free(req, fsp);
1651 mtimespec = smb_dname->st.st_ex_mtime;
1654 * Still set the samba share mode lock for correct delete-on-close
1655 * semantics and to make smbstatus more useful.
1657 lck = get_share_mode_lock(talloc_tos(), fsp->file_id,
1658 conn->connectpath, smb_dname, &mtimespec);
1661 DEBUG(0, ("onefs_open_directory: Could not get share mode "
1662 "lock for %s\n", smb_fname_str_dbg(smb_dname)));
1664 file_free(req, fsp);
1665 return NT_STATUS_SHARING_VIOLATION;
1668 if (lck->delete_on_close) {
1671 file_free(req, fsp);
1672 return NT_STATUS_DELETE_PENDING;
1675 set_share_mode(lck, fsp, conn->server_info->utok.uid, 0, NO_OPLOCK);
1678 * For directories the delete on close bit at open time seems
1679 * always to be honored on close... See test 19 in Samba4 BASE-DELETE.
1681 if (create_options & FILE_DELETE_ON_CLOSE) {
1682 status = can_set_delete_on_close(fsp, 0);
1683 if (!NT_STATUS_IS_OK(status) &&
1684 !NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
1687 file_free(req, fsp);
1691 if (NT_STATUS_IS_OK(status)) {
1692 /* Note that here we set the *inital* delete on close flag,
1693 not the regular one. The magic gets handled in close. */
1694 fsp->initial_delete_on_close = True;
1705 return NT_STATUS_OK;
1709 * Wrapper around onefs_open_file_ntcreate and onefs_open_directory.
1711 static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
1712 struct smb_request *req,
1713 struct smb_filename *smb_fname,
1714 uint32_t access_mask,
1715 uint32_t share_access,
1716 uint32_t create_disposition,
1717 uint32_t create_options,
1718 uint32_t file_attributes,
1719 uint32_t oplock_request,
1720 uint64_t allocation_size,
1721 uint32_t private_flags,
1722 struct security_descriptor *sd,
1723 struct ea_list *ea_list,
1724 files_struct **result,
1726 struct onefs_fsp_data *fsp_data)
1728 int info = FILE_WAS_OPENED;
1729 files_struct *base_fsp = NULL;
1730 files_struct *fsp = NULL;
1733 DEBUG(10,("onefs_create_file_unixpath: access_mask = 0x%x "
1734 "file_attributes = 0x%x, share_access = 0x%x, "
1735 "create_disposition = 0x%x create_options = 0x%x "
1736 "oplock_request = 0x%x private_flags = 0x%x "
1737 "ea_list = 0x%p, sd = 0x%p, "
1739 (unsigned int)access_mask,
1740 (unsigned int)file_attributes,
1741 (unsigned int)share_access,
1742 (unsigned int)create_disposition,
1743 (unsigned int)create_options,
1744 (unsigned int)oplock_request,
1745 (unsigned int)private_flags,
1746 ea_list, sd, smb_fname_str_dbg(smb_fname)));
1748 if (create_options & FILE_OPEN_BY_FILE_ID) {
1749 status = NT_STATUS_NOT_SUPPORTED;
1753 if (create_options & NTCREATEX_OPTIONS_INVALID_PARAM_MASK) {
1754 status = NT_STATUS_INVALID_PARAMETER;
1759 SMB_ASSERT((oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK) ==
1761 oplock_request |= INTERNAL_OPEN_ONLY;
1764 if (lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE,
1765 PARM_IGNORE_SACLS, PARM_IGNORE_SACLS_DEFAULT)) {
1766 access_mask &= ~SYSTEM_SECURITY_ACCESS;
1769 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
1770 && (access_mask & DELETE_ACCESS)
1771 && !is_ntfs_stream_smb_fname(smb_fname)) {
1773 * We can't open a file with DELETE access if any of the
1774 * streams is open without FILE_SHARE_DELETE
1776 status = open_streams_for_delete(conn, smb_fname->base_name);
1778 if (!NT_STATUS_IS_OK(status)) {
1783 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
1784 && is_ntfs_stream_smb_fname(smb_fname)) {
1785 uint32 base_create_disposition;
1786 struct smb_filename *smb_fname_base = NULL;
1788 if (create_options & FILE_DIRECTORY_FILE) {
1789 status = NT_STATUS_NOT_A_DIRECTORY;
1793 switch (create_disposition) {
1795 base_create_disposition = FILE_OPEN;
1798 base_create_disposition = FILE_OPEN_IF;
1802 /* Create an smb_filename with stream_name == NULL. */
1803 status = create_synthetic_smb_fname(talloc_tos(),
1804 smb_fname->base_name,
1807 if (!NT_STATUS_IS_OK(status)) {
1811 if (SMB_VFS_STAT(conn, smb_fname_base) == -1) {
1812 DEBUG(10, ("Unable to stat stream: %s\n",
1813 smb_fname_str_dbg(smb_fname_base)));
1816 status = onefs_create_file_unixpath(
1819 smb_fname_base, /* fname */
1820 SYNCHRONIZE_ACCESS, /* access_mask */
1823 FILE_SHARE_DELETE), /* share_access */
1824 base_create_disposition, /* create_disposition*/
1825 0, /* create_options */
1826 file_attributes, /* file_attributes */
1827 NO_OPLOCK, /* oplock_request */
1828 0, /* allocation_size */
1829 0, /* private_flags */
1832 &base_fsp, /* result */
1834 NULL); /* fsp_data */
1836 TALLOC_FREE(smb_fname_base);
1838 if (!NT_STATUS_IS_OK(status)) {
1839 DEBUG(10, ("onefs_create_file_unixpath for base %s "
1840 "failed: %s\n", smb_fname->base_name,
1841 nt_errstr(status)));
1846 * Testing against windows xp/2003/vista shows that oplocks
1847 * can actually be requested and granted on streams (see the
1848 * RAW-OPLOCK-STREAM1 smbtorture test).
1850 if ((oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK) !=
1852 DEBUG(5, ("Oplock(%d) being requested on a stream! "
1853 "Ignoring oplock request: fname=%s\n",
1854 oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK,
1855 smb_fname_str_dbg(smb_fname)));
1856 /* Request NO_OPLOCK instead. */
1857 oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
1861 /* Covert generic bits in the security descriptor. */
1863 security_acl_map_generic(sd->dacl, &file_generic_mapping);
1864 security_acl_map_generic(sd->sacl, &file_generic_mapping);
1868 * If it's a request for a directory open, deal with it separately.
1871 if (create_options & FILE_DIRECTORY_FILE) {
1873 if (create_options & FILE_NON_DIRECTORY_FILE) {
1874 status = NT_STATUS_INVALID_PARAMETER;
1878 /* Can't open a temp directory. IFS kit test. */
1879 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
1880 (file_attributes & FILE_ATTRIBUTE_TEMPORARY)) {
1881 status = NT_STATUS_INVALID_PARAMETER;
1886 * We will get a create directory here if the Win32
1887 * app specified a security descriptor in the
1888 * CreateDirectory() call.
1891 status = onefs_open_directory(
1894 smb_fname, /* fname */
1895 access_mask, /* access_mask */
1896 share_access, /* share_access */
1897 create_disposition, /* create_disposition*/
1898 create_options, /* create_options */
1899 file_attributes, /* file_attributes */
1906 * Ordinary file case.
1909 status = file_new(req, conn, &fsp);
1910 if(!NT_STATUS_IS_OK(status)) {
1915 * We're opening the stream element of a base_fsp
1916 * we already opened. Set up the base_fsp pointer.
1919 fsp->base_fsp = base_fsp;
1922 status = onefs_open_file_ntcreate(
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 */
1931 oplock_request, /* oplock_request */
1935 fsp_data); /* fsp_data */
1937 if(!NT_STATUS_IS_OK(status)) {
1938 file_free(req, fsp);
1942 if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
1944 /* A stream open never opens a directory */
1947 status = NT_STATUS_FILE_IS_A_DIRECTORY;
1952 * Fail the open if it was explicitly a non-directory
1956 if (create_options & FILE_NON_DIRECTORY_FILE) {
1957 status = NT_STATUS_FILE_IS_A_DIRECTORY;
1961 create_options |= FILE_DIRECTORY_FILE;
1963 status = onefs_open_directory(
1966 smb_fname, /* fname */
1967 access_mask, /* access_mask */
1968 share_access, /* share_access */
1969 create_disposition, /* create_disposition*/
1970 create_options, /* create_options */
1971 file_attributes, /* file_attributes */
1978 if (!NT_STATUS_IS_OK(status)) {
1982 fsp->base_fsp = base_fsp;
1986 if ((ea_list != NULL) && (info == FILE_WAS_CREATED)) {
1987 status = set_ea(conn, fsp, smb_fname, ea_list);
1988 if (!NT_STATUS_IS_OK(status)) {
1993 if (!fsp->is_directory && S_ISDIR(smb_fname->st.st_ex_mode)) {
1994 status = NT_STATUS_ACCESS_DENIED;
1998 /* Save the requested allocation size. */
1999 if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
2001 && (allocation_size > smb_fname->st.st_ex_size)) {
2002 fsp->initial_allocation_size = smb_roundup(
2003 fsp->conn, allocation_size);
2004 if (fsp->is_directory) {
2005 /* Can't set allocation size on a directory. */
2006 status = NT_STATUS_ACCESS_DENIED;
2009 if (vfs_allocate_file_space(
2010 fsp, fsp->initial_allocation_size) == -1) {
2011 status = NT_STATUS_DISK_FULL;
2015 fsp->initial_allocation_size = smb_roundup(
2016 fsp->conn, (uint64_t)smb_fname->st.st_ex_size);
2020 DEBUG(10, ("onefs_create_file_unixpath: info=%d\n", info));
2023 if (pinfo != NULL) {
2026 if ((fsp->fh != NULL) && (fsp->fh->fd != -1)) {
2027 SMB_VFS_FSTAT(fsp, &smb_fname->st);
2029 return NT_STATUS_OK;
2032 DEBUG(10, ("onefs_create_file_unixpath: %s\n", nt_errstr(status)));
2035 if (base_fsp && fsp->base_fsp == base_fsp) {
2037 * The close_file below will close
2042 close_file(req, fsp, ERROR_CLOSE);
2045 if (base_fsp != NULL) {
2046 close_file(req, base_fsp, ERROR_CLOSE);
2052 static void destroy_onefs_fsp_data(void *p_data)
2054 struct onefs_fsp_data *fsp_data = (struct onefs_fsp_data *)p_data;
2056 destroy_onefs_callback_record(fsp_data->oplock_callback_id);
2060 * SMB_VFS_CREATE_FILE interface to onefs.
2062 NTSTATUS onefs_create_file(vfs_handle_struct *handle,
2063 struct smb_request *req,
2064 uint16_t root_dir_fid,
2065 struct smb_filename *smb_fname,
2066 uint32_t access_mask,
2067 uint32_t share_access,
2068 uint32_t create_disposition,
2069 uint32_t create_options,
2070 uint32_t file_attributes,
2071 uint32_t oplock_request,
2072 uint64_t allocation_size,
2073 uint32_t private_flags,
2074 struct security_descriptor *sd,
2075 struct ea_list *ea_list,
2076 files_struct **result,
2079 connection_struct *conn = handle->conn;
2080 struct onefs_fsp_data fsp_data = {};
2081 int info = FILE_WAS_OPENED;
2082 files_struct *fsp = NULL;
2085 DEBUG(10,("onefs_create_file: access_mask = 0x%x "
2086 "file_attributes = 0x%x, share_access = 0x%x, "
2087 "create_disposition = 0x%x create_options = 0x%x "
2088 "oplock_request = 0x%x private_flags = 0x%x"
2089 "root_dir_fid = 0x%x, ea_list = 0x%p, sd = 0x%p, "
2091 (unsigned int)access_mask,
2092 (unsigned int)file_attributes,
2093 (unsigned int)share_access,
2094 (unsigned int)create_disposition,
2095 (unsigned int)create_options,
2096 (unsigned int)oplock_request,
2097 (unsigned int)private_flags,
2098 (unsigned int)root_dir_fid,
2099 ea_list, sd, smb_fname_str_dbg(smb_fname)));
2101 /* Get the file name if root_dir_fid was specified. */
2102 if (root_dir_fid != 0) {
2103 status = get_relative_fid_filename(conn, req, root_dir_fid,
2105 if (!NT_STATUS_IS_OK(status)) {
2110 /* All file access must go through check_name() */
2111 status = check_name(conn, smb_fname->base_name);
2112 if (!NT_STATUS_IS_OK(status)) {
2116 status = onefs_create_file_unixpath(
2119 smb_fname, /* fname */
2120 access_mask, /* access_mask */
2121 share_access, /* share_access */
2122 create_disposition, /* create_disposition*/
2123 create_options, /* create_options */
2124 file_attributes, /* file_attributes */
2125 oplock_request, /* oplock_request */
2126 allocation_size, /* allocation_size */
2129 ea_list, /* ea_list */
2132 &fsp_data); /* psbuf */
2134 if (!NT_STATUS_IS_OK(status)) {
2138 DEBUG(10, ("onefs_create_file: info=%d\n", info));
2141 * Setup private onefs_fsp_data. Currently the private data struct is
2142 * only used to store the oplock_callback_id so that when the file is
2143 * closed, the onefs_callback_record can be properly cleaned up in the
2144 * oplock_onefs sub-system.
2147 struct onefs_fsp_data *fsp_data_tmp = NULL;
2148 fsp_data_tmp = (struct onefs_fsp_data *)
2149 VFS_ADD_FSP_EXTENSION(handle, fsp, struct onefs_fsp_data,
2150 &destroy_onefs_fsp_data);
2152 if (fsp_data_tmp == NULL) {
2153 status = NT_STATUS_NO_MEMORY;
2157 *fsp_data_tmp = fsp_data;
2161 if (pinfo != NULL) {
2164 return NT_STATUS_OK;
2167 DEBUG(10, ("onefs_create_file: %s\n", nt_errstr(status)));
2170 close_file(req, fsp, ERROR_CLOSE);