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 extern const struct generic_mapping file_generic_mapping;
38 extern bool global_client_failed_oplock_break;
40 struct deferred_open_record {
41 bool delayed_for_oplocks;
42 bool failed; /* added for onefs_oplocks */
46 static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
47 struct smb_request *req,
50 uint32_t share_access,
51 uint32_t create_disposition,
52 uint32_t create_options,
53 uint32_t file_attributes,
54 uint32_t oplock_request,
55 uint64_t allocation_size,
56 struct security_descriptor *sd,
57 struct ea_list *ea_list,
59 files_struct **result,
61 SMB_STRUCT_STAT *psbuf);
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,
73 SMB_STRUCT_STAT *psbuf,
77 uint32 open_access_mask,
81 uint32 create_options,
82 uint32_t new_dos_attributes,
83 struct security_descriptor *sd,
86 NTSTATUS status = NT_STATUS_OK;
87 int accmode = (flags & O_ACCMODE);
88 int local_flags = flags;
89 bool file_existed = VALID_STAT(*psbuf);
98 /* Check permissions */
101 * This code was changed after seeing a client open request
102 * containing the open mode of (DENY_WRITE/read-only) with
103 * the 'create if not exist' bit set. The previous code
104 * would fail to open the file read only on a read-only share
105 * as it was checking the flags parameter directly against O_RDONLY,
106 * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
110 if (!CAN_WRITE(conn)) {
111 /* It's a read-only share - fail if we wanted to write. */
112 if(accmode != O_RDONLY) {
113 DEBUG(3,("Permission denied opening %s\n", path));
114 return NT_STATUS_ACCESS_DENIED;
115 } else if(flags & O_CREAT) {
116 /* We don't want to write - but we must make sure that
117 O_CREAT doesn't create the file if we have write
118 access into the directory.
121 local_flags &= ~O_CREAT;
126 * This little piece of insanity is inspired by the
127 * fact that an NT client can open a file for O_RDONLY,
128 * but set the create disposition to FILE_EXISTS_TRUNCATE.
129 * If the client *can* write to the file, then it expects to
130 * truncate the file, even though it is opening for readonly.
131 * Quicken uses this stupid trick in backup file creation...
132 * Thanks *greatly* to "David W. Chapman Jr." <dwcjr@inethouston.net>
133 * for helping track this one down. It didn't bite us in 2.0.x
134 * as we always opened files read-write in that release. JRA.
137 if ((accmode == O_RDONLY) && ((flags & O_TRUNC) == O_TRUNC)) {
138 DEBUG(10,("onefs_open_file: truncate requested on read-only "
139 "open for file %s\n", path));
140 local_flags = (flags & ~O_ACCMODE)|O_RDWR;
143 #if defined(O_NONBLOCK) && defined(S_ISFIFO)
145 * We would block on opening a FIFO with no one else on the
146 * other end. Do what we used to do and add O_NONBLOCK to the
150 if (file_existed && S_ISFIFO(psbuf->st_mode)) {
151 local_flags |= O_NONBLOCK;
155 /* Don't create files with Microsoft wildcard characters. */
158 * wildcard characters are allowed in stream names
159 * only test the basefilename
161 wild = fsp->base_fsp->fsp_name;
165 if ((local_flags & O_CREAT) && !file_existed &&
168 * XXX: may need to remvoe this return...
170 * We dont think this check needs to exist. All it does is
171 * block creating files with Microsoft wildcards, which is
172 * fine if the creation originated from NFS or locally and
173 * then was copied via Samba.
175 DEBUG(1, ("onefs_open_file: creating file with wildcard: %s\n",
177 return NT_STATUS_OBJECT_NAME_INVALID;
180 /* Actually do the open */
184 * Never follow symlinks on a POSIX client. The
185 * client should be doing this.
188 if (fsp->posix_open || !lp_symlinks(SNUM(conn))) {
192 /* Don't request an oplock if oplocks are turned off for the
194 if (!lp_oplocks(SNUM(conn)))
197 /* Stream handling */
198 if (is_ntfs_stream_name(path)) {
199 status = onefs_split_ntfs_stream_name(talloc_tos(), path,
202 /* It's a stream, so pass in the base_fd */
203 if (stream != NULL) {
204 SMB_ASSERT(fsp->base_fsp);
206 DEBUG(10,("Opening a stream: base=%s(%d), stream=%s",
207 base, fsp->base_fsp->fh->fd, stream));
209 base_fd = fsp->base_fsp->fh->fd;
212 fsp->fh->fd = onefs_sys_create_file(conn,
214 stream != NULL ? stream :
215 (base != NULL ? base : path),
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) "
246 path,nt_errstr(status),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, path,
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, path);
271 if (fsp->fh->fd == -1) {
272 ret = SMB_VFS_STAT(conn, path, psbuf);
274 ret = SMB_VFS_FSTAT(fsp, psbuf);
275 /* If we have an fd, this stat should succeed. */
277 DEBUG(0,("Error doing fstat on open file %s "
278 "(%s)\n", path,strerror(errno) ));
282 /* For a non-io open, this stat failing means file not found. JRA */
284 status = map_nt_error_from_unix(errno);
291 * POSIX allows read-only opens of directories. We don't
292 * want to do this (we use a different code path for this)
293 * so catch a directory open and return an EISDIR. JRA.
296 if(S_ISDIR(psbuf->st_mode)) {
299 return NT_STATUS_FILE_IS_A_DIRECTORY;
302 fsp->mode = psbuf->st_mode;
303 fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf);
304 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
305 fsp->file_pid = req ? req->smbpid : 0;
306 fsp->can_lock = True;
307 fsp->can_read = (access_mask & (FILE_READ_DATA)) ? True : False;
308 if (!CAN_WRITE(conn)) {
309 fsp->can_write = False;
311 fsp->can_write = (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ?
314 fsp->print_file = False;
315 fsp->modified = False;
316 fsp->sent_oplock_break = NO_BREAK_SENT;
317 fsp->is_directory = False;
318 if (conn->aio_write_behind_list &&
319 is_in_path(path, conn->aio_write_behind_list, conn->case_sensitive)) {
320 fsp->aio_write_behind = True;
323 string_set(&fsp->fsp_name, path);
324 fsp->wcp = NULL; /* Write cache pointer. */
326 DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
327 conn->server_info->unix_name,
329 BOOLSTR(fsp->can_read), BOOLSTR(fsp->can_write),
330 conn->num_files_open));
336 /****************************************************************************
337 Handle the 1 second delay in returning a SHARING_VIOLATION error.
338 ****************************************************************************/
340 static void defer_open(struct share_mode_lock *lck,
341 struct timeval request_time,
342 struct timeval timeout,
343 struct smb_request *req,
344 struct deferred_open_record *state)
350 for (i=0; i<lck->num_share_modes; i++) {
351 struct share_mode_entry *e = &lck->share_modes[i];
353 if (!is_deferred_open_entry(e)) {
357 if (procid_is_me(&e->pid) && (e->op_mid == req->mid)) {
358 DEBUG(0, ("Trying to defer an already deferred "
359 "request: mid=%d, exiting\n", req->mid));
360 exit_server("attempt to defer a deferred request");
364 /* End paranoia check */
366 DEBUG(10,("defer_open_sharing_error: time [%u.%06u] adding deferred "
367 "open entry for mid %u\n",
368 (unsigned int)request_time.tv_sec,
369 (unsigned int)request_time.tv_usec,
370 (unsigned int)req->mid));
372 if (!push_deferred_smb_message(req, request_time, timeout,
373 (char *)state, sizeof(*state))) {
374 exit_server("push_deferred_smb_message failed");
376 add_deferred_open(lck, req->mid, request_time, state->id);
379 * Push the MID of this packet on the signing queue.
380 * We only do this once, the first time we push the packet
381 * onto the deferred open queue, as this has a side effect
382 * of incrementing the response sequence number.
385 srv_defer_sign_response(req->mid);
388 static void schedule_defer_open(struct share_mode_lock *lck,
389 struct timeval request_time,
390 struct smb_request *req)
392 struct deferred_open_record state;
394 /* This is a relative time, added to the absolute
395 request_time value to get the absolute timeout time.
396 Note that if this is the second or greater time we enter
397 this codepath for this particular request mid then
398 request_time is left as the absolute time of the *first*
399 time this request mid was processed. This is what allows
400 the request to eventually time out. */
402 struct timeval timeout;
404 /* Normally the smbd we asked should respond within
405 * OPLOCK_BREAK_TIMEOUT seconds regardless of whether
406 * the client did, give twice the timeout as a safety
407 * measure here in case the other smbd is stuck
410 timeout = timeval_set(OPLOCK_BREAK_TIMEOUT*2, 0);
412 /* Nothing actually uses state.delayed_for_oplocks
413 but it's handy to differentiate in debug messages
414 between a 30 second delay due to oplock break, and
415 a 1 second delay for share mode conflicts. */
417 state.delayed_for_oplocks = True;
418 state.failed = False;
421 if (!request_timed_out(request_time, timeout)) {
422 defer_open(lck, request_time, timeout, req, &state);
426 /****************************************************************************
427 Open a file with a share mode. Passed in an already created files_struct.
428 ****************************************************************************/
429 NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
430 struct smb_request *req,
434 uint32 create_disposition,
435 uint32 create_options,
436 uint32 new_dos_attributes,
438 struct security_descriptor *sd,
441 SMB_STRUCT_STAT *psbuf)
445 bool file_existed = VALID_STAT(*psbuf);
446 bool def_acl = False;
447 bool posix_open = False;
448 bool new_file_created = False;
449 bool clear_ads = False;
451 mode_t new_unx_mode = (mode_t)0;
452 mode_t unx_mode = (mode_t)0;
454 uint32 existing_dos_attributes = 0;
455 struct pending_message_list *pml = NULL;
456 struct timeval request_time = timeval_zero();
457 struct share_mode_lock *lck = NULL;
458 uint32 open_access_mask = access_mask;
464 uint64 oplock_waiter;
465 uint32 createfile_attributes = 0;
471 * Printers are handled completely differently.
472 * Most of the passed parameters are ignored.
476 *pinfo = FILE_WAS_CREATED;
479 DEBUG(10, ("onefs_open_file_ntcreate: printer open fname=%s\n",
482 return print_fsp_open(req, conn, fname, req->vuid, fsp, psbuf);
485 if (!parent_dirname(talloc_tos(), fname, &parent_dir, &newname)) {
486 return NT_STATUS_NO_MEMORY;
489 if (new_dos_attributes & FILE_FLAG_POSIX_SEMANTICS) {
491 unx_mode = (mode_t)(new_dos_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
492 new_dos_attributes = 0;
494 /* We add aARCH to this as this mode is only used if the file is
496 unx_mode = unix_mode(conn, new_dos_attributes | aARCH, fname,
500 DEBUG(10,("onefs_open_file_ntcreate: fname=%s, dos_attrs=0x%x "
501 "access_mask=0x%x share_access=0x%x "
502 "create_disposition = 0x%x create_options=0x%x "
503 "unix mode=0%o oplock_request=0x%x\n",
504 fname, new_dos_attributes, access_mask, share_access,
505 create_disposition, create_options, unx_mode,
508 if ((req == NULL) && ((oplock_request & INTERNAL_OPEN_ONLY) == 0)) {
509 DEBUG(0, ("No smb request but not an internal only open!\n"));
510 return NT_STATUS_INTERNAL_ERROR;
514 * Only non-internal opens can be deferred at all
518 && ((pml = get_open_deferred_message(req->mid)) != NULL)) {
519 struct deferred_open_record *state =
520 (struct deferred_open_record *)pml->private_data.data;
522 /* Remember the absolute time of the original
523 request with this mid. We'll use it later to
524 see if this has timed out. */
526 request_time = pml->request_time;
528 /* Remove the deferred open entry under lock. */
529 lck = get_share_mode_lock(talloc_tos(), state->id, NULL, NULL,
532 DEBUG(0, ("could not get share mode lock\n"));
534 del_deferred_open_entry(lck, req->mid);
538 /* Ensure we don't reprocess this message. */
539 remove_deferred_open_smb_message(req->mid);
542 * When receiving a semlock_async_failure message, the
543 * deferred open will be marked as "failed". Returning
547 DEBUG(0, ("onefs_open_file_ntcreate: "
548 "semlock_async_failure detected!\n"));
549 return NT_STATUS_INTERNAL_ERROR;
553 status = check_name(conn, fname);
554 if (!NT_STATUS_IS_OK(status)) {
559 new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
561 existing_dos_attributes = dos_mode(conn, fname, psbuf);
565 /* Setup dos_attributes to be set by ifs_createfile */
566 if (lp_store_dos_attributes(SNUM(conn))) {
567 createfile_attributes = (new_dos_attributes | aARCH) &
568 ~(FILE_ATTRIBUTE_NONINDEXED | FILE_ATTRIBUTE_COMPRESSED);
571 /* Ignore oplock requests if oplocks are disabled. */
572 if (!lp_oplocks(SNUM(conn)) || global_client_failed_oplock_break ||
573 IS_VETO_OPLOCK_PATH(conn, fname)) {
574 /* Mask off everything except the private Samba bits. */
575 oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
578 /* this is for OS/2 long file names - say we don't support them */
579 if (!lp_posix_pathnames() && strstr(fname,".+,;=[].")) {
580 /* OS/2 Workplace shell fix may be main code stream in a later
582 DEBUG(5,("onefs_open_file_ntcreate: OS/2 long filenames are "
583 "not supported.\n"));
584 if (use_nt_status()) {
585 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
587 return NT_STATUS_DOS(ERRDOS, ERRcannotopen);
590 switch( create_disposition ) {
592 * Currently we're using FILE_SUPERSEDE as the same as
593 * FILE_OVERWRITE_IF but they really are
594 * different. FILE_SUPERSEDE deletes an existing file
595 * (requiring delete access) then recreates it.
599 * @todo: Clear all file attributes?
600 * http://www.osronline.com/article.cfm?article=302
601 * create if not exist, trunc if exist
603 * If file exists replace/overwrite. If file doesn't
606 flags2 |= (O_CREAT | O_TRUNC);
610 case FILE_OVERWRITE_IF:
611 /* If file exists replace/overwrite. If file doesn't
613 flags2 |= (O_CREAT | O_TRUNC);
618 /* If file exists open. If file doesn't exist error. */
620 DEBUG(5,("onefs_open_file_ntcreate: FILE_OPEN "
621 "requested for file %s and file "
622 "doesn't exist.\n", fname ));
624 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
629 /* If file exists overwrite. If file doesn't exist
632 DEBUG(5, ("onefs_open_file_ntcreate: "
633 "FILE_OVERWRITE requested for file "
634 "%s and file doesn't exist.\n",
637 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
644 /* If file exists error. If file doesn't exist
647 DEBUG(5, ("onefs_open_file_ntcreate: "
648 "FILE_CREATE requested for file %s "
649 "and file already exists.\n",
651 if (S_ISDIR(psbuf->st_mode)) {
656 return map_nt_error_from_unix(errno);
658 flags2 |= (O_CREAT|O_EXCL);
662 /* If file exists open. If file doesn't exist
668 return NT_STATUS_INVALID_PARAMETER;
671 /* Match attributes on file exists and overwrite. */
672 if (!posix_open && file_existed &&
673 ((create_disposition == FILE_OVERWRITE) ||
674 (create_disposition == FILE_OVERWRITE_IF))) {
675 if (!open_match_attributes(conn, fname,
676 existing_dos_attributes,
677 new_dos_attributes, psbuf->st_mode,
678 unx_mode, &new_unx_mode)) {
679 DEBUG(5, ("onefs_open_file_ntcreate: attributes "
680 "missmatch for file %s (%x %x) (0%o, 0%o)\n",
681 fname, existing_dos_attributes,
683 (unsigned int)psbuf->st_mode,
684 (unsigned int)unx_mode ));
686 return NT_STATUS_ACCESS_DENIED;
691 * OneFS understands MAXIMUM_ALLOWED_ACCESS, so only hack the
692 * access_mask, but leave the MAA for the actual open in
695 open_access_mask = access_mask;
696 if (open_access_mask & MAXIMUM_ALLOWED_ACCESS) {
697 access_mask |= FILE_GENERIC_ALL;
700 /* Convert GENERIC bits to specific bits. */
701 se_map_generic(&access_mask, &file_generic_mapping);
702 se_map_generic(&open_access_mask, &file_generic_mapping);
704 if ((flags2 & O_TRUNC) || (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE)) {
705 /* This will cause oplock breaks. */
706 open_access_mask |= FILE_WRITE_DATA;
709 DEBUG(10, ("onefs_open_file_ntcreate: fname=%s, after mapping "
710 "open_access_mask=%#x, access_mask=0x%x\n",
711 fname, open_access_mask, access_mask));
714 * Note that we ignore the append flag as append does not
715 * mean the same thing under DOS and Unix.
718 if ((access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ||
719 (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE)) {
722 * DENY_DOS opens are always underlying read-write on the
723 * file handle, no matter what the requested access mask
724 * says. Stock samba just sets the flags, but since
725 * ifs_createfile uses the access_mask, it must be updated as
726 * well. This allows BASE-DENY* to pass.
728 if (create_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) {
730 DEBUG(10,("onefs_open_file_ntcreate: deny_dos: "
731 "Adding O_RDWR to flags "
732 "(0x%x) and some READ bits to "
733 "open_access_mask (0x%x)\n",
734 flags, open_access_mask));
737 open_access_mask |= (FILE_READ_ATTRIBUTES |
738 FILE_READ_DATA | FILE_READ_EA | FILE_EXECUTE);
740 } else if (access_mask & (FILE_READ_ATTRIBUTES |
752 /* Currently we only look at FILE_WRITE_THROUGH for create options. */
754 if ((create_options & FILE_WRITE_THROUGH) &&
755 lp_strict_sync(SNUM(conn))) {
760 if (posix_open && (access_mask & FILE_APPEND_DATA)) {
764 if (!posix_open && !CAN_WRITE(conn)) {
766 * We should really return a permission denied error if either
767 * O_CREAT or O_TRUNC are set, but for compatibility with
768 * older versions of Samba we just AND them out.
770 flags2 &= ~(O_CREAT|O_TRUNC);
772 /* Deny DELETE_ACCESS explicitly if the share is read only. */
773 if (access_mask & DELETE_ACCESS) {
774 return map_nt_error_from_unix(EACCES);
778 /* Ensure we can't write on a read-only share or file. */
779 if (flags != O_RDONLY && file_existed &&
780 (!CAN_WRITE(conn) || IS_DOS_READONLY(existing_dos_attributes))) {
781 DEBUG(5, ("onefs_open_file_ntcreate: write access requested "
782 "for file %s on read only %s\n",
783 fname, !CAN_WRITE(conn) ? "share" : "file" ));
785 return NT_STATUS_ACCESS_DENIED;
788 DEBUG(10, ("fsp = %p\n", fsp));
790 fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf);
791 fsp->share_access = share_access;
792 fsp->fh->private_options = create_options;
793 fsp->access_mask = open_access_mask; /* We change this to the
794 * requested access_mask after
795 * the open is done. */
796 fsp->posix_open = posix_open;
798 /* Ensure no SAMBA_PRIVATE bits can be set. */
799 fsp->oplock_type = (oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK);
801 if (timeval_is_zero(&request_time)) {
802 request_time = fsp->open_time;
806 struct timespec old_write_time = get_mtimespec(psbuf);
807 id = vfs_file_id_from_sbuf(conn, psbuf);
809 lck = get_share_mode_lock(talloc_tos(), id,
811 fname, &old_write_time);
814 DEBUG(0, ("Could not get share mode lock\n"));
815 return NT_STATUS_SHARING_VIOLATION;
818 if (lck->delete_on_close) {
819 /* DELETE_PENDING is not deferred for a second */
821 return NT_STATUS_DELETE_PENDING;
825 SMB_ASSERT(!file_existed || (lck != NULL));
828 * Ensure we pay attention to default ACLs on directories. May be
829 * neccessary depending on ACL policies.
831 if ((flags2 & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
832 (def_acl = directory_has_default_acl(conn, parent_dir))) {
836 DEBUG(4,("calling onefs_open_file with flags=0x%X flags2=0x%X "
837 "mode=0%o, access_mask = 0x%x, open_access_mask = 0x%x\n",
838 (unsigned int)flags, (unsigned int)flags2,
839 (unsigned int)unx_mode, (unsigned int)access_mask,
840 (unsigned int)open_access_mask));
842 oplock_waiter = 1; //ifs_oplock_wait_record(mid);
844 if (oplock_waiter == 0) {
845 return NT_STATUS_NO_MEMORY;
849 status = onefs_open_file(fsp,
864 createfile_attributes,
868 if (!NT_STATUS_IS_OK(status)) {
870 /* OneFS Oplock Handling */
871 if (errno == EINPROGRESS) {
875 struct deferred_open_record state;
876 struct timespec old_write_time;
878 old_write_time = get_mtimespec(psbuf);
880 DEBUG(3, ("Someone created file %s with an "
881 "oplock after we looked: Retrying\n",
884 * We hit the race that when we did the stat
885 * on the file it did not exist, and someone
886 * has created it in between the stat and the
887 * open_file() call. Just retry immediately.
889 id = vfs_file_id_from_sbuf(conn, psbuf);
890 if (!(lck = get_share_mode_lock(talloc_tos(),
891 id, conn->connectpath, fname,
896 DEBUG(0, ("onefs_open_file_ntcreate: "
897 "Could not get share mode "
898 "lock for %s\n", fname));
899 status = NT_STATUS_SHARING_VIOLATION;
900 goto cleanup_destroy;
903 state.delayed_for_oplocks = False;
907 defer_open(lck, request_time,
908 timeval_zero(), req, &state);
910 goto cleanup_destroy;
912 /* Waiting for an oplock */
914 schedule_defer_open(lck, request_time, req);
918 /* Check for a sharing violation */
919 if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
920 uint32 can_access_mask;
921 bool can_access = True;
923 /* Check if this can be done with the deny_dos and fcb
926 /* Try to find dup fsp if possible. */
928 (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS|
929 NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) {
932 DEBUG(0, ("DOS open without an SMB "
934 status = NT_STATUS_INTERNAL_ERROR;
935 goto cleanup_destroy;
938 /* Use the client requested access mask here,
939 * not the one we open with. */
940 status = fcb_or_dos_open(req,
951 if (NT_STATUS_IS_OK(status)) {
954 *pinfo = FILE_WAS_OPENED;
956 status = NT_STATUS_OK;
962 * This next line is a subtlety we need for
963 * MS-Access. If a file open will fail due to share
964 * permissions and also for security (access) reasons,
965 * we need to return the access failed error, not the
966 * share error. We can't open the file due to kernel
967 * oplock deadlock (it's possible we failed above on
968 * the open_mode_check()) so use a userspace check.
971 if (flags & O_RDWR) {
972 can_access_mask = FILE_READ_DATA|FILE_WRITE_DATA;
973 } else if (flags & O_WRONLY) {
974 can_access_mask = FILE_WRITE_DATA;
976 can_access_mask = FILE_READ_DATA;
979 if (((can_access_mask & FILE_WRITE_DATA) && !CAN_WRITE(conn)) ||
980 !can_access_file_data(conn,fname,psbuf,can_access_mask)) {
985 * If we're returning a share violation, ensure we
986 * cope with the braindead 1 second delay.
988 if (!(oplock_request & INTERNAL_OPEN_ONLY) &&
989 lp_defer_sharing_violations()) {
990 struct timeval timeout;
991 struct deferred_open_record state;
994 /* this is a hack to speed up torture tests
996 timeout_usecs = lp_parm_int(SNUM(conn),
998 SHARING_VIOLATION_USEC_WAIT);
1000 /* This is a relative time, added to the
1001 absolute request_time value to get the
1002 absolute timeout time. Note that if this
1003 is the second or greater time we enter this
1004 codepath for this particular request mid
1005 then request_time is left as the absolute
1006 time of the *first* time this request mid
1007 was processed. This is what allows the
1008 request to eventually time out. */
1010 timeout = timeval_set(0, timeout_usecs);
1012 /* Nothing actually uses
1013 state.delayed_for_oplocks but it's handy to
1014 differentiate in debug messages between a
1015 30 second delay due to oplock break, and a
1016 1 second delay for share mode conflicts. */
1018 state.delayed_for_oplocks = False;
1020 state.failed = false;
1023 && !request_timed_out(request_time,
1025 defer_open(lck, request_time, timeout,
1032 * We have detected a sharing violation here
1033 * so return the correct error code
1035 status = NT_STATUS_SHARING_VIOLATION;
1037 status = NT_STATUS_ACCESS_DENIED;
1040 goto cleanup_destroy;
1044 * Normal error, for example EACCES
1047 //destroy_ifs_callback_record(oplock_waiter);
1053 fsp->oplock_type = granted_oplock;
1055 /* XXX uncomment for oplocks */
1056 //ifs_set_oplock_callback(oplock_waiter, fsp);
1057 //fsp->oplock_callback_id = oplock_waiter;
1059 if (!file_existed) {
1060 struct timespec old_write_time = get_mtimespec(psbuf);
1062 * Deal with the race condition where two smbd's detect the
1063 * file doesn't exist and do the create at the same time. One
1064 * of them will win and set a share mode, the other (ie. this
1065 * one) should check if the requested share mode for this
1066 * create is allowed.
1070 * Now the file exists and fsp is successfully opened,
1071 * fsp->dev and fsp->inode are valid and should replace the
1072 * dev=0,inode=0 from a non existent file. Spotted by
1073 * Nadav Danieli <nadavd@exanet.com>. JRA.
1078 lck = get_share_mode_lock(talloc_tos(), id,
1080 fname, &old_write_time);
1083 DEBUG(0, ("onefs_open_file_ntcreate: Could not get "
1084 "share mode lock for %s\n", fname));
1086 return NT_STATUS_SHARING_VIOLATION;
1089 if (lck->delete_on_close) {
1090 status = NT_STATUS_DELETE_PENDING;
1093 if (!NT_STATUS_IS_OK(status)) {
1094 struct deferred_open_record state;
1098 state.delayed_for_oplocks = False;
1101 /* Do it all over again immediately. In the second
1102 * round we will find that the file existed and handle
1103 * the DELETE_PENDING and FCB cases correctly. No need
1104 * to duplicate the code here. Essentially this is a
1105 * "goto top of this function", but don't tell
1109 defer_open(lck, request_time, timeval_zero(),
1117 * We exit this block with the share entry *locked*.....
1122 SMB_ASSERT(lck != NULL);
1124 /* Delete streams if create_disposition requires it */
1125 if (file_existed && clear_ads) {
1126 status = delete_all_streams(conn, fname);
1127 if (!NT_STATUS_IS_OK(status)) {
1134 /* note that we ignore failure for the following. It is
1135 basically a hack for NFS, and NFS will never set one of
1136 these only read them. Nobody but Samba can ever set a deny
1137 mode and we have already checked our more authoritative
1138 locking database for permission to set this deny mode. If
1139 the kernel refuses the operations then the kernel is wrong.
1140 note that GPFS supports it as well - jmcd */
1142 if (fsp->fh->fd != -1) {
1143 ret_flock = SMB_VFS_KERNEL_FLOCK(fsp, share_access);
1144 if(ret_flock == -1 ){
1148 return NT_STATUS_SHARING_VIOLATION;
1153 * At this point onwards, we can guarentee that the share entry
1154 * is locked, whether we created the file or not, and that the
1155 * deny mode is compatible with all current opens.
1158 /* Record the options we were opened with. */
1159 fsp->share_access = share_access;
1160 fsp->fh->private_options = create_options;
1162 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
1164 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
1167 /* stat opens on existing files don't get oplocks. */
1168 if (is_stat_open(open_access_mask)) {
1169 fsp->oplock_type = NO_OPLOCK;
1172 if (!(flags2 & O_TRUNC)) {
1173 info = FILE_WAS_OPENED;
1175 info = FILE_WAS_OVERWRITTEN;
1178 info = FILE_WAS_CREATED;
1186 * Setup the oplock info in both the shared memory and
1190 if ((fsp->oplock_type != NO_OPLOCK) &&
1191 (fsp->oplock_type != FAKE_LEVEL_II_OPLOCK)) {
1192 if (!set_file_oplock(fsp, fsp->oplock_type)) {
1193 /* Could not get the kernel oplock */
1194 fsp->oplock_type = NO_OPLOCK;
1198 if (info == FILE_WAS_OVERWRITTEN || info == FILE_WAS_CREATED ||
1199 info == FILE_WAS_SUPERSEDED) {
1200 new_file_created = True;
1203 set_share_mode(lck, fsp, conn->server_info->utok.uid, 0,
1206 /* Handle strange delete on close create semantics. */
1207 if (create_options & FILE_DELETE_ON_CLOSE) {
1208 status = can_set_delete_on_close(fsp, True, new_dos_attributes);
1210 if (!NT_STATUS_IS_OK(status)) {
1211 /* Remember to delete the mode we just added. */
1212 del_share_mode(lck, fsp);
1217 /* Note that here we set the *inital* delete on close flag,
1218 not the regular one. The magic gets handled in close. */
1219 fsp->initial_delete_on_close = True;
1223 * Take care of inherited ACLs on created files - if default ACL not
1225 * May be necessary depending on acl policies.
1227 if (!posix_open && !file_existed && !def_acl && !(VALID_STAT(*psbuf)
1228 && (psbuf->st_flags & SF_HASNTFSACL))) {
1230 int saved_errno = errno; /* We might get ENOSYS in the next
1233 if (SMB_VFS_FCHMOD_ACL(fsp, unx_mode) == -1 &&
1235 errno = saved_errno; /* Ignore ENOSYS */
1238 } else if (new_unx_mode) {
1242 /* Attributes need changing. File already existed. */
1245 int saved_errno = errno; /* We might get ENOSYS in the
1247 ret = SMB_VFS_FCHMOD_ACL(fsp, new_unx_mode);
1249 if (ret == -1 && errno == ENOSYS) {
1250 errno = saved_errno; /* Ignore ENOSYS */
1252 DEBUG(5, ("onefs_open_file_ntcreate: reset "
1253 "attributes of file %s to 0%o\n",
1254 fname, (unsigned int)new_unx_mode));
1255 ret = 0; /* Don't do the fchmod below. */
1260 (SMB_VFS_FCHMOD(fsp, new_unx_mode) == -1))
1261 DEBUG(5, ("onefs_open_file_ntcreate: failed to reset "
1262 "attributes of file %s to 0%o\n",
1263 fname, (unsigned int)new_unx_mode));
1266 /* If this is a successful open, we must remove any deferred open
1269 del_deferred_open_entry(lck, req->mid);
1273 return NT_STATUS_OK;
1277 /****************************************************************************
1278 Open a directory from an NT SMB call.
1279 ****************************************************************************/
1280 static NTSTATUS onefs_open_directory(connection_struct *conn,
1281 struct smb_request *req,
1284 uint32 share_access,
1285 uint32 create_disposition,
1286 uint32 create_options,
1287 uint32 file_attributes,
1288 struct security_descriptor *sd,
1289 files_struct **result,
1291 SMB_STRUCT_STAT *psbuf)
1293 files_struct *fsp = NULL;
1294 struct share_mode_lock *lck = NULL;
1296 struct timespec mtimespec;
1299 const char *dirname;
1300 bool posix_open = false;
1301 uint32 create_flags = 0;
1302 uint32 mode = lp_dir_mask(SNUM(conn));
1304 DEBUG(5, ("onefs_open_directory: opening directory %s, "
1305 "access_mask = 0x%x, "
1306 "share_access = 0x%x create_options = 0x%x, "
1307 "create_disposition = 0x%x, file_attributes = 0x%x\n",
1308 fname, (unsigned int)access_mask, (unsigned int)share_access,
1309 (unsigned int)create_options, (unsigned int)create_disposition,
1310 (unsigned int)file_attributes));
1312 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
1313 (conn->fs_capabilities & FILE_NAMED_STREAMS) &&
1314 is_ntfs_stream_name(fname)) {
1315 DEBUG(2, ("onefs_open_directory: %s is a stream name!\n", fname));
1316 return NT_STATUS_NOT_A_DIRECTORY;
1319 switch (create_disposition) {
1321 /* If directory exists open. If directory doesn't
1324 info = FILE_WAS_OPENED;
1327 /* If directory exists error. If directory doesn't
1329 create_flags = O_CREAT | O_EXCL;
1330 info = FILE_WAS_CREATED;
1333 /* If directory exists open. If directory doesn't
1336 /* Note: in order to return whether the directory was
1337 * opened or created, we first try to open and then try
1340 info = FILE_WAS_OPENED;
1342 case FILE_SUPERSEDE:
1343 case FILE_OVERWRITE:
1344 case FILE_OVERWRITE_IF:
1346 DEBUG(5, ("onefs_open_directory: invalid "
1347 "create_disposition 0x%x for directory %s\n",
1348 (unsigned int)create_disposition, fname));
1349 return NT_STATUS_INVALID_PARAMETER;
1353 * Check for write access to the share. Done in mkdir_internal() in
1356 if (!CAN_WRITE(conn) && (create_flags & O_CREAT)) {
1357 return NT_STATUS_ACCESS_DENIED;
1360 /* Get parent dirname */
1361 if (!parent_dirname(talloc_tos(), fname, &parent_dir, &dirname)) {
1362 return NT_STATUS_NO_MEMORY;
1365 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
1367 mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
1368 file_attributes = 0;
1370 mode = unix_mode(conn, aDIR, fname, parent_dir);
1374 * The NONINDEXED and COMPRESSED bits seem to always be cleared on
1375 * directories, no matter if you specify that they should be set.
1378 ~(FILE_ATTRIBUTE_NONINDEXED | FILE_ATTRIBUTE_COMPRESSED);
1380 status = file_new(req, conn, &fsp);
1381 if(!NT_STATUS_IS_OK(status)) {
1386 * Actual open with retry magic to handle FILE_OPEN_IF which is
1387 * unique because the kernel won't tell us if the file was opened or
1391 fsp->fh->fd = onefs_sys_create_file(conn,
1398 create_flags | O_DIRECTORY,
1406 if (fsp->fh->fd == -1) {
1407 DEBUG(3, ("Error opening %s. Errno=%d (%s).\n", fname, errno,
1409 SMB_ASSERT(errno != EINPROGRESS);
1411 if (create_disposition == FILE_OPEN_IF) {
1412 if (errno == ENOENT) {
1413 /* Try again, creating it this time. */
1414 create_flags = O_CREAT | O_EXCL;
1415 info = FILE_WAS_CREATED;
1417 } else if (errno == EEXIST) {
1418 /* Uggh. Try again again. */
1420 info = FILE_WAS_OPENED;
1425 /* Error cases below: */
1426 file_free(req, fsp);
1428 if ((errno == ENOENT) && (create_disposition == FILE_OPEN)) {
1429 DEBUG(5,("onefs_open_directory: FILE_OPEN requested "
1430 "for directory %s and it doesn't "
1431 "exist.\n", fname ));
1432 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1433 } else if ((errno == EEXIST) &&
1434 (create_disposition == FILE_CREATE)) {
1435 DEBUG(5,("onefs_open_directory: FILE_CREATE "
1436 "requested for directory %s and it "
1437 "already exists.\n", fname ));
1438 return NT_STATUS_OBJECT_NAME_COLLISION;
1439 } else if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
1440 /* Catch sharing violations. */
1441 return NT_STATUS_SHARING_VIOLATION;
1444 return map_nt_error_from_unix(errno);
1447 if (info == FILE_WAS_CREATED) {
1449 /* Pulled from mkdir_internal() */
1450 if (SMB_VFS_LSTAT(conn, fname, psbuf) == -1) {
1451 DEBUG(2, ("Could not stat directory '%s' just "
1452 "created: %s\n",fname, strerror(errno)));
1453 return map_nt_error_from_unix(errno);
1456 if (!S_ISDIR(psbuf->st_mode)) {
1457 DEBUG(0, ("Directory just '%s' created is not a "
1458 "directory\n", fname));
1459 return NT_STATUS_ACCESS_DENIED;
1464 * Check if high bits should have been set, then (if
1465 * bits are missing): add them. Consider bits
1466 * automagically set by UNIX, i.e. SGID bit from
1469 if (mode & ~(S_IRWXU|S_IRWXG|S_IRWXO) &&
1470 (mode & ~psbuf->st_mode)) {
1471 SMB_VFS_CHMOD(conn, fname, (psbuf->st_mode |
1472 (mode & ~psbuf->st_mode)));
1476 /* Change the owner if required. */
1477 if (lp_inherit_owner(SNUM(conn))) {
1478 change_dir_owner_to_parent(conn, parent_dir, fname,
1482 notify_fname(conn, NOTIFY_ACTION_ADDED,
1483 FILE_NOTIFY_CHANGE_DIR_NAME, fname);
1486 /* Stat the fd for Samba bookkeeping. */
1487 if(SMB_VFS_FSTAT(fsp, psbuf) != 0) {
1489 file_free(req, fsp);
1490 return map_nt_error_from_unix(errno);
1493 /* Setup the files_struct for it. */
1494 fsp->mode = psbuf->st_mode;
1495 fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf);
1496 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
1497 fsp->file_pid = req ? req->smbpid : 0;
1498 fsp->can_lock = False;
1499 fsp->can_read = False;
1500 fsp->can_write = False;
1502 fsp->share_access = share_access;
1503 fsp->fh->private_options = create_options;
1505 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
1507 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
1508 fsp->print_file = False;
1509 fsp->modified = False;
1510 fsp->oplock_type = NO_OPLOCK;
1511 fsp->sent_oplock_break = NO_BREAK_SENT;
1512 fsp->is_directory = True;
1513 fsp->posix_open = posix_open;
1515 string_set(&fsp->fsp_name,fname);
1517 mtimespec = get_mtimespec(psbuf);
1520 * Still set the samba share mode lock for correct delete-on-close
1521 * semantics and to make smbstatus more useful.
1523 lck = get_share_mode_lock(talloc_tos(), fsp->file_id,
1528 DEBUG(0, ("onefs_open_directory: Could not get share mode "
1529 "lock for %s\n", fname));
1531 file_free(req, fsp);
1532 return NT_STATUS_SHARING_VIOLATION;
1535 if (lck->delete_on_close) {
1538 file_free(req, fsp);
1539 return NT_STATUS_DELETE_PENDING;
1542 set_share_mode(lck, fsp, conn->server_info->utok.uid, 0, NO_OPLOCK);
1545 * For directories the delete on close bit at open time seems
1546 * always to be honored on close... See test 19 in Samba4 BASE-DELETE.
1548 if (create_options & FILE_DELETE_ON_CLOSE) {
1549 status = can_set_delete_on_close(fsp, True, 0);
1550 if (!NT_STATUS_IS_OK(status) &&
1551 !NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
1554 file_free(req, fsp);
1558 if (NT_STATUS_IS_OK(status)) {
1559 /* Note that here we set the *inital* delete on close flag,
1560 not the regular one. The magic gets handled in close. */
1561 fsp->initial_delete_on_close = True;
1572 return NT_STATUS_OK;
1576 * If a main file is opened for delete, all streams need to be checked for
1577 * !FILE_SHARE_DELETE. Do this by opening with DELETE_ACCESS.
1578 * If that works, delete them all by setting the delete on close and close.
1581 static NTSTATUS open_streams_for_delete(connection_struct *conn,
1584 struct stream_struct *stream_info;
1585 files_struct **streams;
1587 unsigned int num_streams;
1588 TALLOC_CTX *frame = talloc_stackframe();
1591 status = SMB_VFS_STREAMINFO(conn, NULL, fname, talloc_tos(),
1592 &num_streams, &stream_info);
1594 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
1595 || NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
1596 DEBUG(10, ("no streams around\n"));
1598 return NT_STATUS_OK;
1601 if (!NT_STATUS_IS_OK(status)) {
1602 DEBUG(10, ("SMB_VFS_STREAMINFO failed: %s\n",
1603 nt_errstr(status)));
1607 DEBUG(10, ("open_streams_for_delete found %d streams\n",
1610 if (num_streams == 0) {
1612 return NT_STATUS_OK;
1615 streams = TALLOC_ARRAY(talloc_tos(), files_struct *, num_streams);
1616 if (streams == NULL) {
1617 DEBUG(0, ("talloc failed\n"));
1618 status = NT_STATUS_NO_MEMORY;
1622 /* Open the base file */
1624 for (i=0; i<num_streams; i++) {
1627 if (strequal(stream_info[i].name, "::$DATA")) {
1632 streamname = talloc_asprintf(talloc_tos(), "%s%s", fname,
1633 stream_info[i].name);
1635 if (streamname == NULL) {
1636 DEBUG(0, ("talloc_aprintf failed\n"));
1637 status = NT_STATUS_NO_MEMORY;
1641 status = onefs_create_file_unixpath
1644 streamname, /* fname */
1645 DELETE_ACCESS, /* access_mask */
1646 FILE_SHARE_READ | FILE_SHARE_WRITE
1647 | FILE_SHARE_DELETE, /* share_access */
1648 FILE_OPEN, /* create_disposition*/
1649 NTCREATEX_OPTIONS_PRIVATE_STREAM_DELETE, /* create_options */
1650 FILE_ATTRIBUTE_NORMAL, /* file_attributes */
1651 0, /* oplock_request */
1652 0, /* allocation_size */
1655 &streams[i], /* result */
1659 TALLOC_FREE(streamname);
1661 if (!NT_STATUS_IS_OK(status)) {
1662 DEBUG(10, ("Could not open stream %s: %s\n",
1663 streamname, nt_errstr(status)));
1669 * don't touch the variable "status" beyond this point :-)
1672 for (i -= 1 ; i >= 0; i--) {
1673 if (streams[i] == NULL) {
1677 DEBUG(10, ("Closing stream # %d, %s\n", i,
1678 streams[i]->fsp_name));
1679 close_file(NULL, streams[i], NORMAL_CLOSE);
1688 * Wrapper around onefs_open_file_ntcreate and onefs_open_directory.
1690 static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
1691 struct smb_request *req,
1693 uint32_t access_mask,
1694 uint32_t share_access,
1695 uint32_t create_disposition,
1696 uint32_t create_options,
1697 uint32_t file_attributes,
1698 uint32_t oplock_request,
1699 uint64_t allocation_size,
1700 struct security_descriptor *sd,
1701 struct ea_list *ea_list,
1702 files_struct **result,
1704 SMB_STRUCT_STAT *psbuf)
1706 SMB_STRUCT_STAT sbuf;
1707 int info = FILE_WAS_OPENED;
1708 files_struct *base_fsp = NULL;
1709 files_struct *fsp = NULL;
1712 DEBUG(10,("onefs_create_file_unixpath: access_mask = 0x%x "
1713 "file_attributes = 0x%x, share_access = 0x%x, "
1714 "create_disposition = 0x%x create_options = 0x%x "
1715 "oplock_request = 0x%x ea_list = 0x%p, sd = 0x%p, "
1717 (unsigned int)access_mask,
1718 (unsigned int)file_attributes,
1719 (unsigned int)share_access,
1720 (unsigned int)create_disposition,
1721 (unsigned int)create_options,
1722 (unsigned int)oplock_request,
1723 ea_list, sd, fname));
1725 if (create_options & FILE_OPEN_BY_FILE_ID) {
1726 status = NT_STATUS_NOT_SUPPORTED;
1730 if (create_options & NTCREATEX_OPTIONS_INVALID_PARAM_MASK) {
1731 status = NT_STATUS_INVALID_PARAMETER;
1736 oplock_request |= INTERNAL_OPEN_ONLY;
1739 if (psbuf != NULL) {
1743 if (SMB_VFS_STAT(conn, fname, &sbuf) == -1) {
1744 SET_STAT_INVALID(sbuf);
1748 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
1749 && (access_mask & DELETE_ACCESS)
1750 && !is_ntfs_stream_name(fname)) {
1752 * We can't open a file with DELETE access if any of the
1753 * streams is open without FILE_SHARE_DELETE
1755 status = open_streams_for_delete(conn, fname);
1757 if (!NT_STATUS_IS_OK(status)) {
1762 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
1763 && is_ntfs_stream_name(fname)) {
1765 uint32 base_create_disposition;
1767 if (create_options & FILE_DIRECTORY_FILE) {
1768 status = NT_STATUS_NOT_A_DIRECTORY;
1772 status = onefs_split_ntfs_stream_name(talloc_tos(), fname,
1774 if (!NT_STATUS_IS_OK(status)) {
1775 DEBUG(10, ("onefs_create_file_unixpath: "
1776 "split_ntfs_stream_name failed: %s\n",
1777 nt_errstr(status)));
1781 SMB_ASSERT(!is_ntfs_stream_name(base)); /* paranoia.. */
1783 switch (create_disposition) {
1785 base_create_disposition = FILE_OPEN;
1788 base_create_disposition = FILE_OPEN_IF;
1792 status = onefs_create_file_unixpath(
1796 0, /* access_mask */
1799 FILE_SHARE_DELETE), /* share_access */
1800 base_create_disposition, /* create_disposition*/
1801 0, /* create_options */
1802 file_attributes, /* file_attributes */
1803 NO_OPLOCK, /* oplock_request */
1804 0, /* allocation_size */
1807 &base_fsp, /* result */
1811 if (!NT_STATUS_IS_OK(status)) {
1812 DEBUG(10, ("onefs_create_file_unixpath for base %s "
1813 "failed: %s\n", base, nt_errstr(status)));
1818 /* Covert generic bits in the security descriptor. */
1820 security_acl_map_generic(sd->dacl, &file_generic_mapping);
1821 security_acl_map_generic(sd->sacl, &file_generic_mapping);
1825 * If it's a request for a directory open, deal with it separately.
1828 if (create_options & FILE_DIRECTORY_FILE) {
1830 if (create_options & FILE_NON_DIRECTORY_FILE) {
1831 status = NT_STATUS_INVALID_PARAMETER;
1835 /* Can't open a temp directory. IFS kit test. */
1836 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
1837 (file_attributes & FILE_ATTRIBUTE_TEMPORARY)) {
1838 status = NT_STATUS_INVALID_PARAMETER;
1843 * We will get a create directory here if the Win32
1844 * app specified a security descriptor in the
1845 * CreateDirectory() call.
1848 status = onefs_open_directory(
1852 access_mask, /* access_mask */
1853 share_access, /* share_access */
1854 create_disposition, /* create_disposition*/
1855 create_options, /* create_options */
1856 file_attributes, /* file_attributes */
1864 * Ordinary file case.
1867 status = file_new(req, conn, &fsp);
1868 if(!NT_STATUS_IS_OK(status)) {
1873 * We're opening the stream element of a base_fsp
1874 * we already opened. Set up the base_fsp pointer.
1877 fsp->base_fsp = base_fsp;
1880 status = onefs_open_file_ntcreate(
1884 access_mask, /* access_mask */
1885 share_access, /* share_access */
1886 create_disposition, /* create_disposition*/
1887 create_options, /* create_options */
1888 file_attributes, /* file_attributes */
1889 oplock_request, /* oplock_request */
1895 if(!NT_STATUS_IS_OK(status)) {
1896 file_free(req, fsp);
1900 if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
1902 /* A stream open never opens a directory */
1905 status = NT_STATUS_FILE_IS_A_DIRECTORY;
1910 * Fail the open if it was explicitly a non-directory
1914 if (create_options & FILE_NON_DIRECTORY_FILE) {
1915 status = NT_STATUS_FILE_IS_A_DIRECTORY;
1919 create_options |= FILE_DIRECTORY_FILE;
1921 status = onefs_open_directory(
1925 access_mask, /* access_mask */
1926 share_access, /* share_access */
1927 create_disposition, /* create_disposition*/
1928 create_options, /* create_options */
1929 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, fname, ea_list);
1947 if (!NT_STATUS_IS_OK(status)) {
1952 if (!fsp->is_directory && S_ISDIR(sbuf.st_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 > sbuf.st_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)sbuf.st_size);
1979 DEBUG(10, ("onefs_create_file_unixpath: info=%d\n", info));
1982 if (pinfo != NULL) {
1985 if (psbuf != NULL) {
1986 if ((fsp->fh == NULL) || (fsp->fh->fd == -1)) {
1990 SMB_VFS_FSTAT(fsp, psbuf);
1993 return NT_STATUS_OK;
1996 DEBUG(10, ("onefs_create_file_unixpath: %s\n", nt_errstr(status)));
1999 if (base_fsp && fsp->base_fsp == base_fsp) {
2001 * The close_file below will close
2006 close_file(req, fsp, ERROR_CLOSE);
2009 if (base_fsp != NULL) {
2010 close_file(req, base_fsp, ERROR_CLOSE);
2017 * SMB_VFS_CREATE_FILE interface to onefs.
2019 NTSTATUS onefs_create_file(vfs_handle_struct *handle,
2020 struct smb_request *req,
2021 uint16_t root_dir_fid,
2023 uint32_t create_file_flags,
2024 uint32_t access_mask,
2025 uint32_t share_access,
2026 uint32_t create_disposition,
2027 uint32_t create_options,
2028 uint32_t file_attributes,
2029 uint32_t oplock_request,
2030 uint64_t allocation_size,
2031 struct security_descriptor *sd,
2032 struct ea_list *ea_list,
2033 files_struct **result,
2035 SMB_STRUCT_STAT *psbuf)
2037 connection_struct *conn = handle->conn;
2038 struct case_semantics_state *case_state = NULL;
2039 SMB_STRUCT_STAT sbuf;
2040 int info = FILE_WAS_OPENED;
2041 files_struct *fsp = NULL;
2044 DEBUG(10,("onefs_create_file: access_mask = 0x%x "
2045 "file_attributes = 0x%x, share_access = 0x%x, "
2046 "create_disposition = 0x%x create_options = 0x%x "
2047 "oplock_request = 0x%x "
2048 "root_dir_fid = 0x%x, ea_list = 0x%p, sd = 0x%p, "
2049 "create_file_flags = 0x%x, fname = %s\n",
2050 (unsigned int)access_mask,
2051 (unsigned int)file_attributes,
2052 (unsigned int)share_access,
2053 (unsigned int)create_disposition,
2054 (unsigned int)create_options,
2055 (unsigned int)oplock_request,
2056 (unsigned int)root_dir_fid,
2057 ea_list, sd, create_file_flags, fname));
2059 /* Get the file name if root_dir_fid was specified. */
2060 if (root_dir_fid != 0) {
2063 status = get_relative_fid_filename(conn, req, root_dir_fid,
2065 if (!NT_STATUS_IS_OK(status)) {
2072 /* Resolve the file name if this was a DFS pathname. */
2073 if ((req != NULL) && (req->flags2 & FLAGS2_DFS_PATHNAMES)) {
2074 char *resolved_fname;
2076 status = resolve_dfspath(talloc_tos(), conn, true, fname,
2079 if (!NT_STATUS_IS_OK(status)) {
2081 * For PATH_NOT_COVERED we had
2082 * reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
2083 * ERRSRV, ERRbadpath);
2084 * Need to fix in callers
2088 fname = resolved_fname;
2091 /* Check if POSIX semantics are wanted. */
2092 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
2093 case_state = set_posix_case_semantics(talloc_tos(), conn);
2096 /* Convert dos path to unix path if it hasn't already been done. */
2097 if (create_file_flags & CFF_DOS_PATH) {
2098 char *converted_fname;
2100 SET_STAT_INVALID(sbuf);
2102 status = unix_convert(talloc_tos(), conn, fname, False,
2103 &converted_fname, NULL, &sbuf);
2104 if (!NT_STATUS_IS_OK(status)) {
2107 fname = converted_fname;
2109 if (psbuf != NULL) {
2112 if (SMB_VFS_STAT(conn, fname, &sbuf) == -1) {
2113 SET_STAT_INVALID(sbuf);
2119 TALLOC_FREE(case_state);
2121 /* All file access must go through check_name() */
2122 status = check_name(conn, fname);
2123 if (!NT_STATUS_IS_OK(status)) {
2127 status = onefs_create_file_unixpath(
2131 access_mask, /* access_mask */
2132 share_access, /* share_access */
2133 create_disposition, /* create_disposition*/
2134 create_options, /* create_options */
2135 file_attributes, /* file_attributes */
2136 oplock_request, /* oplock_request */
2137 allocation_size, /* allocation_size */
2139 ea_list, /* ea_list */
2144 if (!NT_STATUS_IS_OK(status)) {
2148 DEBUG(10, ("onefs_create_file: info=%d\n", info));
2151 if (pinfo != NULL) {
2154 if (psbuf != NULL) {
2157 return NT_STATUS_OK;
2160 DEBUG(10, ("onefs_create_file: %s\n", nt_errstr(status)));
2163 close_file(req, fsp, ERROR_CLOSE);