s3: re-run make samba3-idl.
[Samba/gbeck.git] / source3 / modules / onefs_open.c
blobc5030f4ab85dddc067fe2d1ba3f616246e812ed9
1 /*
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
12 * - Streams
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/>.
35 #include "includes.h"
36 #include "onefs.h"
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 const char *fname,
50 uint32_t access_mask,
51 uint32_t share_access,
52 uint32_t create_disposition,
53 uint32_t create_options,
54 uint32_t file_attributes,
55 uint32_t oplock_request,
56 uint64_t allocation_size,
57 struct security_descriptor *sd,
58 struct ea_list *ea_list,
59 files_struct **result,
60 int *pinfo,
61 struct onefs_fsp_data *fsp_data,
62 SMB_STRUCT_STAT *psbuf);
64 /****************************************************************************
65 Open a file.
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 const char *name,
73 const char *path,
74 SMB_STRUCT_STAT *psbuf,
75 int flags,
76 mode_t unx_mode,
77 uint32 access_mask,
78 uint32 open_access_mask,
79 int oplock_request,
80 uint64 id,
81 uint32 share_access,
82 uint32 create_options,
83 uint32_t new_dos_attributes,
84 struct security_descriptor *sd,
85 int *granted_oplock)
87 NTSTATUS status = NT_STATUS_OK;
88 int accmode = (flags & O_ACCMODE);
89 int local_flags = flags;
90 bool file_existed = VALID_STAT(*psbuf);
91 const char *wild;
92 char *base = NULL;
93 char *stream = NULL;
94 int base_fd = -1;
96 fsp->fh->fd = -1;
97 errno = EPERM;
99 /* Check permissions */
102 * This code was changed after seeing a client open request
103 * containing the open mode of (DENY_WRITE/read-only) with
104 * the 'create if not exist' bit set. The previous code
105 * would fail to open the file read only on a read-only share
106 * as it was checking the flags parameter directly against O_RDONLY,
107 * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
108 * JRA.
111 if (!CAN_WRITE(conn)) {
112 /* It's a read-only share - fail if we wanted to write. */
113 if(accmode != O_RDONLY) {
114 DEBUG(3,("Permission denied opening %s\n", path));
115 return NT_STATUS_ACCESS_DENIED;
116 } else if(flags & O_CREAT) {
117 /* We don't want to write - but we must make sure that
118 O_CREAT doesn't create the file if we have write
119 access into the directory.
121 flags &= ~O_CREAT;
122 local_flags &= ~O_CREAT;
127 * This little piece of insanity is inspired by the
128 * fact that an NT client can open a file for O_RDONLY,
129 * but set the create disposition to FILE_EXISTS_TRUNCATE.
130 * If the client *can* write to the file, then it expects to
131 * truncate the file, even though it is opening for readonly.
132 * Quicken uses this stupid trick in backup file creation...
133 * Thanks *greatly* to "David W. Chapman Jr." <dwcjr@inethouston.net>
134 * for helping track this one down. It didn't bite us in 2.0.x
135 * as we always opened files read-write in that release. JRA.
138 if ((accmode == O_RDONLY) && ((flags & O_TRUNC) == O_TRUNC)) {
139 DEBUG(10,("onefs_open_file: truncate requested on read-only "
140 "open for file %s\n", path));
141 local_flags = (flags & ~O_ACCMODE)|O_RDWR;
144 #if defined(O_NONBLOCK) && defined(S_ISFIFO)
146 * We would block on opening a FIFO with no one else on the
147 * other end. Do what we used to do and add O_NONBLOCK to the
148 * open flags. JRA.
151 if (file_existed && S_ISFIFO(psbuf->st_mode)) {
152 local_flags |= O_NONBLOCK;
154 #endif
156 /* Don't create files with Microsoft wildcard characters. */
157 if (fsp->base_fsp) {
159 * wildcard characters are allowed in stream names
160 * only test the basefilename
162 wild = fsp->base_fsp->fsp_name;
163 } else {
164 wild = path;
166 if ((local_flags & O_CREAT) && !file_existed &&
167 ms_has_wild(wild)) {
169 * XXX: may need to remvoe this return...
171 * We dont think this check needs to exist. All it does is
172 * block creating files with Microsoft wildcards, which is
173 * fine if the creation originated from NFS or locally and
174 * then was copied via Samba.
176 DEBUG(1, ("onefs_open_file: creating file with wildcard: %s\n",
177 path));
178 return NT_STATUS_OBJECT_NAME_INVALID;
181 /* Actually do the open */
183 #ifdef O_NOFOLLOW
185 * Never follow symlinks on a POSIX client. The
186 * client should be doing this.
189 if (fsp->posix_open || !lp_symlinks(SNUM(conn))) {
190 flags |= O_NOFOLLOW;
192 #endif
193 /* Stream handling */
194 if (is_ntfs_stream_name(path)) {
195 status = onefs_split_ntfs_stream_name(talloc_tos(), path,
196 &base, &stream);
198 /* It's a stream, so pass in the base_fd */
199 if ((conn->fs_capabilities & FILE_NAMED_STREAMS) && stream != NULL) {
200 SMB_ASSERT(fsp->base_fsp);
203 * We have never seen an oplock taken on a stream, and our
204 * current implementation doesn't support it. If a request is
205 * seen, log a loud error message and ignore the requested
206 * oplock.
208 if ((oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK) !=
209 NO_OPLOCK) {
210 DEBUG(0,("Oplock(%d) being requested on a stream! "
211 "Ignoring oplock request: base=%s, stream=%s",
212 oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK,
213 base, stream));
214 /* Recover by requesting NO_OPLOCK instead. */
215 oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
218 DEBUG(10,("Opening a stream: base=%s(%d), stream=%s",
219 base, fsp->base_fsp->fh->fd, stream));
221 base_fd = fsp->base_fsp->fh->fd;
224 fsp->fh->fd = onefs_sys_create_file(conn,
225 base_fd,
226 stream != NULL ? stream :
227 (base != NULL ? base : path),
228 access_mask,
229 open_access_mask,
230 share_access,
231 create_options,
232 flags,
233 unx_mode,
234 oplock_request,
237 new_dos_attributes,
238 granted_oplock);
240 if (fsp->fh->fd == -1) {
241 if (errno == EMFILE) {
242 static time_t last_warned = 0L;
244 if (time((time_t *) NULL) > last_warned) {
245 DEBUG(0, ("Too many open files, unable "
246 "to open more! smbd's max "
247 "open files = %d, also check "
248 "sysctl kern.maxfiles and "
249 "sysctl kern.maxfilesperproc\n",
250 lp_max_open_files()));
251 last_warned = time((time_t *) NULL);
255 status = map_nt_error_from_unix(errno);
256 DEBUG(3,("Error opening file %s (%s) (local_flags=%d) "
257 "(flags=%d)\n",
258 path, strerror(errno), local_flags, flags));
259 return status;
262 if ((local_flags & O_CREAT) && !file_existed) {
264 /* Inherit the ACL if required */
265 if (lp_inherit_perms(SNUM(conn))) {
266 inherit_access_posix_acl(conn, parent_dir, path,
267 unx_mode);
270 /* Change the owner if required. */
271 if (lp_inherit_owner(SNUM(conn))) {
272 change_file_owner_to_parent(conn, parent_dir,
273 fsp);
276 notify_fname(conn, NOTIFY_ACTION_ADDED,
277 FILE_NOTIFY_CHANGE_FILE_NAME, path);
280 if (!file_existed) {
281 int ret;
283 if (fsp->fh->fd == -1) {
284 ret = SMB_VFS_STAT(conn, path, psbuf);
285 } else {
286 ret = SMB_VFS_FSTAT(fsp, psbuf);
287 /* If we have an fd, this stat should succeed. */
288 if (ret == -1) {
289 DEBUG(0,("Error doing fstat on open file %s "
290 "(%s)\n", path,strerror(errno) ));
294 /* For a non-io open, this stat failing means file not found. JRA */
295 if (ret == -1) {
296 status = map_nt_error_from_unix(errno);
297 fd_close(fsp);
298 return status;
303 * POSIX allows read-only opens of directories. We don't
304 * want to do this (we use a different code path for this)
305 * so catch a directory open and return an EISDIR. JRA.
308 if(S_ISDIR(psbuf->st_mode)) {
309 fd_close(fsp);
310 errno = EISDIR;
311 return NT_STATUS_FILE_IS_A_DIRECTORY;
314 fsp->mode = psbuf->st_mode;
315 fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf);
316 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
317 fsp->file_pid = req ? req->smbpid : 0;
318 fsp->can_lock = True;
319 fsp->can_read = (access_mask & (FILE_READ_DATA)) ? True : False;
320 if (!CAN_WRITE(conn)) {
321 fsp->can_write = False;
322 } else {
323 fsp->can_write = (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ?
324 True : False;
326 fsp->print_file = False;
327 fsp->modified = False;
328 fsp->sent_oplock_break = NO_BREAK_SENT;
329 fsp->is_directory = False;
330 if (conn->aio_write_behind_list &&
331 is_in_path(path, conn->aio_write_behind_list, conn->case_sensitive)) {
332 fsp->aio_write_behind = True;
335 string_set(&fsp->fsp_name, path);
336 fsp->wcp = NULL; /* Write cache pointer. */
338 DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
339 conn->server_info->unix_name,
340 fsp->fsp_name,
341 BOOLSTR(fsp->can_read), BOOLSTR(fsp->can_write),
342 conn->num_files_open));
344 errno = 0;
345 return NT_STATUS_OK;
348 /****************************************************************************
349 Handle the 1 second delay in returning a SHARING_VIOLATION error.
350 ****************************************************************************/
352 static void defer_open(struct share_mode_lock *lck,
353 struct timeval request_time,
354 struct timeval timeout,
355 struct smb_request *req,
356 struct deferred_open_record *state)
358 int i;
360 /* Paranoia check */
362 for (i=0; i<lck->num_share_modes; i++) {
363 struct share_mode_entry *e = &lck->share_modes[i];
365 if (!is_deferred_open_entry(e)) {
366 continue;
369 if (procid_is_me(&e->pid) && (e->op_mid == req->mid)) {
370 DEBUG(0, ("Trying to defer an already deferred "
371 "request: mid=%d, exiting\n", req->mid));
372 exit_server("attempt to defer a deferred request");
376 /* End paranoia check */
378 DEBUG(10,("defer_open_sharing_error: time [%u.%06u] adding deferred "
379 "open entry for mid %u\n",
380 (unsigned int)request_time.tv_sec,
381 (unsigned int)request_time.tv_usec,
382 (unsigned int)req->mid));
384 if (!push_deferred_smb_message(req, request_time, timeout,
385 (char *)state, sizeof(*state))) {
386 exit_server("push_deferred_smb_message failed");
388 add_deferred_open(lck, req->mid, request_time, state->id);
391 * Push the MID of this packet on the signing queue.
392 * We only do this once, the first time we push the packet
393 * onto the deferred open queue, as this has a side effect
394 * of incrementing the response sequence number.
397 srv_defer_sign_response(req->mid);
400 static void schedule_defer_open(struct share_mode_lock *lck,
401 struct timeval request_time,
402 struct smb_request *req)
404 struct deferred_open_record state;
406 /* This is a relative time, added to the absolute
407 request_time value to get the absolute timeout time.
408 Note that if this is the second or greater time we enter
409 this codepath for this particular request mid then
410 request_time is left as the absolute time of the *first*
411 time this request mid was processed. This is what allows
412 the request to eventually time out. */
414 struct timeval timeout;
416 /* Normally the smbd we asked should respond within
417 * OPLOCK_BREAK_TIMEOUT seconds regardless of whether
418 * the client did, give twice the timeout as a safety
419 * measure here in case the other smbd is stuck
420 * somewhere else. */
423 * On OneFS, the kernel will always send an oplock_revoked message
424 * before this timeout is hit.
426 timeout = timeval_set(OPLOCK_BREAK_TIMEOUT*10, 0);
428 /* Nothing actually uses state.delayed_for_oplocks
429 but it's handy to differentiate in debug messages
430 between a 30 second delay due to oplock break, and
431 a 1 second delay for share mode conflicts. */
433 state.delayed_for_oplocks = True;
434 state.failed = false;
435 state.id = lck->id;
437 if (!request_timed_out(request_time, timeout)) {
438 defer_open(lck, request_time, timeout, req, &state);
442 /****************************************************************************
443 Open a file with a share mode. Passed in an already created files_struct.
444 ****************************************************************************/
445 NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
446 struct smb_request *req,
447 const char *fname,
448 uint32 access_mask,
449 uint32 share_access,
450 uint32 create_disposition,
451 uint32 create_options,
452 uint32 new_dos_attributes,
453 int oplock_request,
454 struct security_descriptor *sd,
455 files_struct *fsp,
456 int *pinfo,
457 struct onefs_fsp_data *fsp_data,
458 SMB_STRUCT_STAT *psbuf)
460 int flags=0;
461 int flags2=0;
462 bool file_existed = VALID_STAT(*psbuf);
463 bool def_acl = False;
464 bool posix_open = False;
465 bool new_file_created = False;
466 bool clear_ads = False;
467 struct file_id id;
468 mode_t new_unx_mode = (mode_t)0;
469 mode_t unx_mode = (mode_t)0;
470 int info;
471 uint32 existing_dos_attributes = 0;
472 struct pending_message_list *pml = NULL;
473 struct timeval request_time = timeval_zero();
474 struct share_mode_lock *lck = NULL;
475 uint32 open_access_mask = access_mask;
476 NTSTATUS status;
477 int ret_flock;
478 char *parent_dir;
479 const char *newname;
480 int granted_oplock;
481 uint64_t oplock_callback_id = 0;
482 uint32 createfile_attributes = 0;
484 ZERO_STRUCT(id);
486 if (conn->printer) {
488 * Printers are handled completely differently.
489 * Most of the passed parameters are ignored.
492 if (pinfo) {
493 *pinfo = FILE_WAS_CREATED;
496 DEBUG(10, ("onefs_open_file_ntcreate: printer open fname=%s\n",
497 fname));
499 return print_fsp_open(req, conn, fname, req->vuid, fsp, psbuf);
502 if (!parent_dirname(talloc_tos(), fname, &parent_dir, &newname)) {
503 return NT_STATUS_NO_MEMORY;
506 if (new_dos_attributes & FILE_FLAG_POSIX_SEMANTICS) {
507 posix_open = True;
508 unx_mode = (mode_t)(new_dos_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
509 new_dos_attributes = 0;
510 } else {
511 /* We add aARCH to this as this mode is only used if the file is
512 * created new. */
513 unx_mode = unix_mode(conn, new_dos_attributes | aARCH, fname,
514 parent_dir);
517 DEBUG(10,("onefs_open_file_ntcreate: fname=%s, dos_attrs=0x%x "
518 "access_mask=0x%x share_access=0x%x "
519 "create_disposition = 0x%x create_options=0x%x "
520 "unix mode=0%o oplock_request=0x%x\n",
521 fname, new_dos_attributes, access_mask, share_access,
522 create_disposition, create_options, unx_mode,
523 oplock_request));
526 * Any non-stat-only open has the potential to contend oplocks, which
527 * means to avoid blocking in the kernel (which is unacceptable), the
528 * open must be deferred. In order to defer opens, req must not be
529 * NULL. The known cases of calling with a NULL req:
531 * 1. Open the base file of a stream: Always done stat-only
533 * 2. Open the stream: Oplocks are disallowed on streams, so an
534 * oplock will never be contended.
536 * 3. open_file_fchmod(), which is called from 3 places:
537 * A. try_chown: Posix acls only. Never called on onefs.
538 * B. set_ea_dos_attributes: Can't be called from onefs, because
539 * SMB_VFS_SETXATTR return ENOSYS.
540 * C. file_set_dos_mode: This would only happen if the "dos
541 * filemode" smb.conf parameter is set to yes. We ship with
542 * it off, but if a customer were to turn it on it would be
543 * bad.
545 if (req == NULL && !is_stat_open(access_mask) && !is_ntfs_stream_name(fname)) {
546 smb_panic("NULL req on a non-stat-open!");
549 if ((req == NULL) && ((oplock_request & INTERNAL_OPEN_ONLY) == 0)) {
550 DEBUG(0, ("No smb request but not an internal only open!\n"));
551 return NT_STATUS_INTERNAL_ERROR;
555 * Only non-internal opens can be deferred at all
558 if ((req != NULL)
559 && ((pml = get_open_deferred_message(req->mid)) != NULL)) {
560 struct deferred_open_record *state =
561 (struct deferred_open_record *)pml->private_data.data;
563 /* Remember the absolute time of the original
564 request with this mid. We'll use it later to
565 see if this has timed out. */
567 request_time = pml->request_time;
569 /* Remove the deferred open entry under lock. */
570 lck = get_share_mode_lock(talloc_tos(), state->id, NULL, NULL,
571 NULL);
572 if (lck == NULL) {
573 DEBUG(0, ("could not get share mode lock\n"));
574 } else {
575 del_deferred_open_entry(lck, req->mid);
576 TALLOC_FREE(lck);
579 /* Ensure we don't reprocess this message. */
580 remove_deferred_open_smb_message(req->mid);
583 * When receiving a semlock_async_failure message, the
584 * deferred open will be marked as "failed". Returning
585 * INTERNAL_ERROR.
587 if (state->failed) {
588 DEBUG(0, ("onefs_open_file_ntcreate: "
589 "semlock_async_failure detected!\n"));
590 return NT_STATUS_INTERNAL_ERROR;
594 status = check_name(conn, fname);
595 if (!NT_STATUS_IS_OK(status)) {
596 return status;
599 if (!posix_open) {
600 new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
601 if (file_existed) {
602 existing_dos_attributes = dos_mode(conn, fname, psbuf);
606 /* Setup dos_attributes to be set by ifs_createfile */
607 if (lp_store_dos_attributes(SNUM(conn))) {
608 createfile_attributes = (new_dos_attributes | aARCH) &
609 ~(FILE_ATTRIBUTE_NONINDEXED | FILE_ATTRIBUTE_COMPRESSED);
612 /* Ignore oplock requests if oplocks are disabled. */
613 if (!lp_oplocks(SNUM(conn)) || global_client_failed_oplock_break ||
614 IS_VETO_OPLOCK_PATH(conn, fname)) {
615 /* Mask off everything except the private Samba bits. */
616 oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
619 /* this is for OS/2 long file names - say we don't support them */
620 if (!lp_posix_pathnames() && strstr(fname,".+,;=[].")) {
621 /* OS/2 Workplace shell fix may be main code stream in a later
622 * release. */
623 DEBUG(5,("onefs_open_file_ntcreate: OS/2 long filenames are "
624 "not supported.\n"));
625 if (use_nt_status()) {
626 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
628 return NT_STATUS_DOS(ERRDOS, ERRcannotopen);
631 switch( create_disposition ) {
633 * Currently we're using FILE_SUPERSEDE as the same as
634 * FILE_OVERWRITE_IF but they really are
635 * different. FILE_SUPERSEDE deletes an existing file
636 * (requiring delete access) then recreates it.
638 case FILE_SUPERSEDE:
640 * @todo: Clear all file attributes?
641 * http://www.osronline.com/article.cfm?article=302
642 * create if not exist, trunc if exist
644 * If file exists replace/overwrite. If file doesn't
645 * exist create.
647 flags2 |= (O_CREAT | O_TRUNC);
648 clear_ads = true;
649 break;
651 case FILE_OVERWRITE_IF:
652 /* If file exists replace/overwrite. If file doesn't
653 * exist create. */
654 flags2 |= (O_CREAT | O_TRUNC);
655 clear_ads = true;
656 break;
658 case FILE_OPEN:
659 /* If file exists open. If file doesn't exist error. */
660 if (!file_existed) {
661 DEBUG(5,("onefs_open_file_ntcreate: FILE_OPEN "
662 "requested for file %s and file "
663 "doesn't exist.\n", fname ));
664 errno = ENOENT;
665 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
667 break;
669 case FILE_OVERWRITE:
670 /* If file exists overwrite. If file doesn't exist
671 * error. */
672 if (!file_existed) {
673 DEBUG(5, ("onefs_open_file_ntcreate: "
674 "FILE_OVERWRITE requested for file "
675 "%s and file doesn't exist.\n",
676 fname));
677 errno = ENOENT;
678 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
680 flags2 |= O_TRUNC;
681 clear_ads = true;
682 break;
684 case FILE_CREATE:
685 /* If file exists error. If file doesn't exist
686 * create. */
687 if (file_existed) {
688 DEBUG(5, ("onefs_open_file_ntcreate: "
689 "FILE_CREATE requested for file %s "
690 "and file already exists.\n",
691 fname));
692 if (S_ISDIR(psbuf->st_mode)) {
693 errno = EISDIR;
694 } else {
695 errno = EEXIST;
697 return map_nt_error_from_unix(errno);
699 flags2 |= (O_CREAT|O_EXCL);
700 break;
702 case FILE_OPEN_IF:
703 /* If file exists open. If file doesn't exist
704 * create. */
705 flags2 |= O_CREAT;
706 break;
708 default:
709 return NT_STATUS_INVALID_PARAMETER;
712 /* Match attributes on file exists and overwrite. */
713 if (!posix_open && file_existed &&
714 ((create_disposition == FILE_OVERWRITE) ||
715 (create_disposition == FILE_OVERWRITE_IF))) {
716 if (!open_match_attributes(conn, fname,
717 existing_dos_attributes,
718 new_dos_attributes, psbuf->st_mode,
719 unx_mode, &new_unx_mode)) {
720 DEBUG(5, ("onefs_open_file_ntcreate: attributes "
721 "missmatch for file %s (%x %x) (0%o, 0%o)\n",
722 fname, existing_dos_attributes,
723 new_dos_attributes,
724 (unsigned int)psbuf->st_mode,
725 (unsigned int)unx_mode ));
726 errno = EACCES;
727 return NT_STATUS_ACCESS_DENIED;
732 * OneFS understands MAXIMUM_ALLOWED_ACCESS, so only hack the
733 * access_mask, but leave the MAA for the actual open in
734 * open_access_mask.
736 open_access_mask = access_mask;
737 if (open_access_mask & MAXIMUM_ALLOWED_ACCESS) {
738 access_mask |= FILE_GENERIC_ALL;
741 /* Convert GENERIC bits to specific bits. */
742 se_map_generic(&access_mask, &file_generic_mapping);
743 se_map_generic(&open_access_mask, &file_generic_mapping);
745 if ((flags2 & O_TRUNC) || (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE)) {
746 /* This will cause oplock breaks. */
747 open_access_mask |= FILE_WRITE_DATA;
750 if (lp_parm_bool(SNUM(fsp->conn), PARM_ONEFS_TYPE,
751 PARM_IGNORE_SACLS, PARM_IGNORE_SACLS_DEFAULT)) {
752 access_mask &= ~SYSTEM_SECURITY_ACCESS;
755 DEBUG(10, ("onefs_open_file_ntcreate: fname=%s, after mapping "
756 "open_access_mask=%#x, access_mask=0x%x\n",
757 fname, open_access_mask, access_mask));
760 * Note that we ignore the append flag as append does not
761 * mean the same thing under DOS and Unix.
764 if ((access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ||
765 (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE)) {
768 * DENY_DOS opens are always underlying read-write on the
769 * file handle, no matter what the requested access mask
770 * says. Stock samba just sets the flags, but since
771 * ifs_createfile uses the access_mask, it must be updated as
772 * well. This allows BASE-DENY* to pass.
774 if (create_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) {
776 DEBUG(10,("onefs_open_file_ntcreate: deny_dos: "
777 "Adding O_RDWR to flags "
778 "(0x%x) and some READ bits to "
779 "open_access_mask (0x%x)\n",
780 flags, open_access_mask));
782 flags = O_RDWR;
783 open_access_mask |= (FILE_READ_ATTRIBUTES |
784 FILE_READ_DATA | FILE_READ_EA | FILE_EXECUTE);
786 } else if (access_mask & (FILE_READ_ATTRIBUTES |
787 FILE_READ_DATA |
788 FILE_READ_EA |
789 FILE_EXECUTE)) {
790 flags = O_RDWR;
791 } else {
792 flags = O_WRONLY;
794 } else {
795 flags = O_RDONLY;
798 /* Currently we only look at FILE_WRITE_THROUGH for create options. */
799 #if defined(O_SYNC)
800 if ((create_options & FILE_WRITE_THROUGH) &&
801 lp_strict_sync(SNUM(conn))) {
802 flags2 |= O_SYNC;
804 #endif /* O_SYNC */
806 if (posix_open && (access_mask & FILE_APPEND_DATA)) {
807 flags2 |= O_APPEND;
810 if (!posix_open && !CAN_WRITE(conn)) {
812 * We should really return a permission denied error if either
813 * O_CREAT or O_TRUNC are set, but for compatibility with
814 * older versions of Samba we just AND them out.
816 flags2 &= ~(O_CREAT|O_TRUNC);
818 /* Deny DELETE_ACCESS explicitly if the share is read only. */
819 if (access_mask & DELETE_ACCESS) {
820 return map_nt_error_from_unix(EACCES);
824 /* Ensure we can't write on a read-only share or file. */
825 if (flags != O_RDONLY && file_existed &&
826 (!CAN_WRITE(conn) || IS_DOS_READONLY(existing_dos_attributes))) {
827 DEBUG(5, ("onefs_open_file_ntcreate: write access requested "
828 "for file %s on read only %s\n",
829 fname, !CAN_WRITE(conn) ? "share" : "file" ));
830 errno = EACCES;
831 return NT_STATUS_ACCESS_DENIED;
834 DEBUG(10, ("fsp = %p\n", fsp));
836 fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf);
837 fsp->share_access = share_access;
838 fsp->fh->private_options = create_options;
839 fsp->access_mask = open_access_mask; /* We change this to the
840 * requested access_mask after
841 * the open is done. */
842 fsp->posix_open = posix_open;
844 /* Ensure no SAMBA_PRIVATE bits can be set. */
845 fsp->oplock_type = (oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK);
847 if (timeval_is_zero(&request_time)) {
848 request_time = fsp->open_time;
851 if (file_existed) {
852 struct timespec old_write_time = get_mtimespec(psbuf);
853 id = vfs_file_id_from_sbuf(conn, psbuf);
855 lck = get_share_mode_lock(talloc_tos(), id,
856 conn->connectpath,
857 fname, &old_write_time);
859 if (lck == NULL) {
860 DEBUG(0, ("Could not get share mode lock\n"));
861 return NT_STATUS_SHARING_VIOLATION;
864 if (lck->delete_on_close) {
865 /* DELETE_PENDING is not deferred for a second */
866 TALLOC_FREE(lck);
867 return NT_STATUS_DELETE_PENDING;
871 SMB_ASSERT(!file_existed || (lck != NULL));
874 * Ensure we pay attention to default ACLs on directories. May be
875 * neccessary depending on ACL policies.
877 if ((flags2 & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
878 (def_acl = directory_has_default_acl(conn, parent_dir))) {
879 unx_mode = 0777;
882 DEBUG(4,("calling onefs_open_file with flags=0x%X flags2=0x%X "
883 "mode=0%o, access_mask = 0x%x, open_access_mask = 0x%x\n",
884 (unsigned int)flags, (unsigned int)flags2,
885 (unsigned int)unx_mode, (unsigned int)access_mask,
886 (unsigned int)open_access_mask));
889 * Since the open is guaranteed to be stat only if req == NULL, a
890 * callback record is only needed if req != NULL.
892 if (req) {
893 SMB_ASSERT(fsp_data);
894 oplock_callback_id = onefs_oplock_wait_record(req->mid);
895 if (oplock_callback_id == 0) {
896 return NT_STATUS_NO_MEMORY;
898 } else {
900 * It is also already asserted it's either a stream or a
901 * stat-only open at this point.
903 SMB_ASSERT(fsp->oplock_type == NO_OPLOCK);
906 /* Do the open. */
907 status = onefs_open_file(fsp,
908 conn,
909 req,
910 parent_dir,
911 newname,
912 fname,
913 psbuf,
914 flags|flags2,
915 unx_mode,
916 access_mask,
917 open_access_mask,
918 fsp->oplock_type,
919 oplock_callback_id,
920 share_access,
921 create_options,
922 createfile_attributes,
924 &granted_oplock);
926 if (!NT_STATUS_IS_OK(status)) {
928 /* OneFS Oplock Handling */
929 if (errno == EINPROGRESS) {
931 if (lck == NULL) {
933 struct deferred_open_record state;
934 struct timespec old_write_time;
936 old_write_time = get_mtimespec(psbuf);
938 DEBUG(3, ("Someone created file %s with an "
939 "oplock after we looked: Retrying\n",
940 fname));
942 * We hit the race that when we did the stat
943 * on the file it did not exist, and someone
944 * has created it in between the stat and the
945 * open_file() call. Just retry immediately.
947 id = vfs_file_id_from_sbuf(conn, psbuf);
948 if (!(lck = get_share_mode_lock(talloc_tos(),
949 id, conn->connectpath, fname,
950 &old_write_time))) {
952 * Emergency exit
954 DEBUG(0, ("onefs_open_file_ntcreate: "
955 "Could not get share mode "
956 "lock for %s\n", fname));
957 status = NT_STATUS_SHARING_VIOLATION;
958 goto cleanup_destroy;
961 state.delayed_for_oplocks = False;
962 state.id = id;
964 if (req != NULL) {
965 defer_open(lck, request_time,
966 timeval_zero(), req, &state);
968 goto cleanup_destroy;
970 /* Waiting for an oplock */
971 DEBUG(5,("Async createfile because a client has an "
972 "oplock on %s\n", fname));
974 SMB_ASSERT(req);
975 schedule_defer_open(lck, request_time, req);
976 goto cleanup;
979 /* Check for a sharing violation */
980 if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
981 uint32 can_access_mask;
982 bool can_access = True;
984 /* Check if this can be done with the deny_dos and fcb
985 * calls. */
987 /* Try to find dup fsp if possible. */
988 if (create_options &
989 (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS|
990 NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) {
992 if (req == NULL) {
993 DEBUG(0, ("DOS open without an SMB "
994 "request!\n"));
995 status = NT_STATUS_INTERNAL_ERROR;
996 goto cleanup_destroy;
999 /* Use the client requested access mask here,
1000 * not the one we open with. */
1001 status = fcb_or_dos_open(req,
1002 conn,
1003 fsp,
1004 fname,
1006 req->smbpid,
1007 req->vuid,
1008 access_mask,
1009 share_access,
1010 create_options);
1012 if (NT_STATUS_IS_OK(status)) {
1013 TALLOC_FREE(lck);
1014 if (pinfo) {
1015 *pinfo = FILE_WAS_OPENED;
1017 status = NT_STATUS_OK;
1018 goto cleanup;
1023 * This next line is a subtlety we need for
1024 * MS-Access. If a file open will fail due to share
1025 * permissions and also for security (access) reasons,
1026 * we need to return the access failed error, not the
1027 * share error. We can't open the file due to kernel
1028 * oplock deadlock (it's possible we failed above on
1029 * the open_mode_check()) so use a userspace check.
1032 if (flags & O_RDWR) {
1033 can_access_mask = FILE_READ_DATA|FILE_WRITE_DATA;
1034 } else if (flags & O_WRONLY) {
1035 can_access_mask = FILE_WRITE_DATA;
1036 } else {
1037 can_access_mask = FILE_READ_DATA;
1040 if (((can_access_mask & FILE_WRITE_DATA) && !CAN_WRITE(conn)) ||
1041 !can_access_file_data(conn,fname,psbuf,can_access_mask)) {
1042 can_access = False;
1046 * If we're returning a share violation, ensure we
1047 * cope with the braindead 1 second delay.
1049 if (!(oplock_request & INTERNAL_OPEN_ONLY) &&
1050 lp_defer_sharing_violations()) {
1051 struct timeval timeout;
1052 struct deferred_open_record state;
1053 int timeout_usecs;
1055 /* this is a hack to speed up torture tests
1056 in 'make test' */
1057 timeout_usecs = lp_parm_int(SNUM(conn),
1058 "smbd","sharedelay",
1059 SHARING_VIOLATION_USEC_WAIT);
1061 /* This is a relative time, added to the
1062 absolute request_time value to get the
1063 absolute timeout time. Note that if this
1064 is the second or greater time we enter this
1065 codepath for this particular request mid
1066 then request_time is left as the absolute
1067 time of the *first* time this request mid
1068 was processed. This is what allows the
1069 request to eventually time out. */
1071 timeout = timeval_set(0, timeout_usecs);
1073 /* Nothing actually uses
1074 state.delayed_for_oplocks but it's handy to
1075 differentiate in debug messages between a
1076 30 second delay due to oplock break, and a
1077 1 second delay for share mode conflicts. */
1079 state.delayed_for_oplocks = False;
1080 state.id = id;
1081 state.failed = false;
1083 if ((req != NULL)
1084 && !request_timed_out(request_time,
1085 timeout)) {
1086 defer_open(lck, request_time, timeout,
1087 req, &state);
1091 if (can_access) {
1093 * We have detected a sharing violation here
1094 * so return the correct error code
1096 status = NT_STATUS_SHARING_VIOLATION;
1097 } else {
1098 status = NT_STATUS_ACCESS_DENIED;
1101 goto cleanup_destroy;
1105 * Normal error, for example EACCES
1107 cleanup_destroy:
1108 if (oplock_callback_id != 0) {
1109 destroy_onefs_callback_record(oplock_callback_id);
1111 cleanup:
1112 TALLOC_FREE(lck);
1113 return status;
1116 fsp->oplock_type = granted_oplock;
1118 if (oplock_callback_id != 0) {
1119 onefs_set_oplock_callback(oplock_callback_id, fsp);
1120 fsp_data->oplock_callback_id = oplock_callback_id;
1121 } else {
1122 SMB_ASSERT(fsp->oplock_type == NO_OPLOCK);
1125 if (!file_existed) {
1126 struct timespec old_write_time = get_mtimespec(psbuf);
1128 * Deal with the race condition where two smbd's detect the
1129 * file doesn't exist and do the create at the same time. One
1130 * of them will win and set a share mode, the other (ie. this
1131 * one) should check if the requested share mode for this
1132 * create is allowed.
1136 * Now the file exists and fsp is successfully opened,
1137 * fsp->dev and fsp->inode are valid and should replace the
1138 * dev=0,inode=0 from a non existent file. Spotted by
1139 * Nadav Danieli <nadavd@exanet.com>. JRA.
1142 id = fsp->file_id;
1144 lck = get_share_mode_lock(talloc_tos(), id,
1145 conn->connectpath,
1146 fname, &old_write_time);
1148 if (lck == NULL) {
1149 DEBUG(0, ("onefs_open_file_ntcreate: Could not get "
1150 "share mode lock for %s\n", fname));
1151 fd_close(fsp);
1152 return NT_STATUS_SHARING_VIOLATION;
1155 if (lck->delete_on_close) {
1156 status = NT_STATUS_DELETE_PENDING;
1159 if (!NT_STATUS_IS_OK(status)) {
1160 struct deferred_open_record state;
1162 fd_close(fsp);
1164 state.delayed_for_oplocks = False;
1165 state.id = id;
1167 /* Do it all over again immediately. In the second
1168 * round we will find that the file existed and handle
1169 * the DELETE_PENDING and FCB cases correctly. No need
1170 * to duplicate the code here. Essentially this is a
1171 * "goto top of this function", but don't tell
1172 * anybody... */
1174 if (req != NULL) {
1175 defer_open(lck, request_time, timeval_zero(),
1176 req, &state);
1178 TALLOC_FREE(lck);
1179 return status;
1183 * We exit this block with the share entry *locked*.....
1188 SMB_ASSERT(lck != NULL);
1190 /* Delete streams if create_disposition requires it */
1191 if (file_existed && clear_ads && !is_ntfs_stream_name(fname)) {
1192 status = delete_all_streams(conn, fname);
1193 if (!NT_STATUS_IS_OK(status)) {
1194 TALLOC_FREE(lck);
1195 fd_close(fsp);
1196 return status;
1200 /* note that we ignore failure for the following. It is
1201 basically a hack for NFS, and NFS will never set one of
1202 these only read them. Nobody but Samba can ever set a deny
1203 mode and we have already checked our more authoritative
1204 locking database for permission to set this deny mode. If
1205 the kernel refuses the operations then the kernel is wrong.
1206 note that GPFS supports it as well - jmcd */
1208 if (fsp->fh->fd != -1) {
1209 ret_flock = SMB_VFS_KERNEL_FLOCK(fsp, share_access);
1210 if(ret_flock == -1 ){
1212 TALLOC_FREE(lck);
1213 fd_close(fsp);
1214 return NT_STATUS_SHARING_VIOLATION;
1219 * At this point onwards, we can guarentee that the share entry
1220 * is locked, whether we created the file or not, and that the
1221 * deny mode is compatible with all current opens.
1224 /* Record the options we were opened with. */
1225 fsp->share_access = share_access;
1226 fsp->fh->private_options = create_options;
1228 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
1230 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
1232 if (file_existed) {
1233 /* stat opens on existing files don't get oplocks. */
1234 if (is_stat_open(open_access_mask)) {
1235 fsp->oplock_type = NO_OPLOCK;
1238 if (!(flags2 & O_TRUNC)) {
1239 info = FILE_WAS_OPENED;
1240 } else {
1241 info = FILE_WAS_OVERWRITTEN;
1243 } else {
1244 info = FILE_WAS_CREATED;
1247 if (pinfo) {
1248 *pinfo = info;
1252 * Setup the oplock info in both the shared memory and
1253 * file structs.
1256 if ((fsp->oplock_type != NO_OPLOCK) &&
1257 (fsp->oplock_type != FAKE_LEVEL_II_OPLOCK)) {
1258 if (!set_file_oplock(fsp, fsp->oplock_type)) {
1259 /* Could not get the kernel oplock */
1260 fsp->oplock_type = NO_OPLOCK;
1264 if (fsp->oplock_type == LEVEL_II_OPLOCK &&
1265 (!lp_level2_oplocks(SNUM(conn)) ||
1266 !(global_client_caps & CAP_LEVEL_II_OPLOCKS))) {
1268 DEBUG(5, ("Downgrading level2 oplock on open "
1269 "because level2 oplocks = off\n"));
1271 release_file_oplock(fsp);
1274 if (info == FILE_WAS_OVERWRITTEN || info == FILE_WAS_CREATED ||
1275 info == FILE_WAS_SUPERSEDED) {
1276 new_file_created = True;
1279 set_share_mode(lck, fsp, conn->server_info->utok.uid, 0,
1280 fsp->oplock_type);
1282 /* Handle strange delete on close create semantics. */
1283 if (create_options & FILE_DELETE_ON_CLOSE) {
1284 status = can_set_delete_on_close(fsp, True, new_dos_attributes);
1286 if (!NT_STATUS_IS_OK(status)) {
1287 /* Remember to delete the mode we just added. */
1288 del_share_mode(lck, fsp);
1289 TALLOC_FREE(lck);
1290 fd_close(fsp);
1291 return status;
1293 /* Note that here we set the *inital* delete on close flag,
1294 not the regular one. The magic gets handled in close. */
1295 fsp->initial_delete_on_close = True;
1299 * Take care of inherited ACLs on created files - if default ACL not
1300 * selected.
1301 * May be necessary depending on acl policies.
1303 if (!posix_open && !file_existed && !def_acl && !(VALID_STAT(*psbuf)
1304 && (psbuf->st_flags & SF_HASNTFSACL))) {
1306 int saved_errno = errno; /* We might get ENOSYS in the next
1307 * call.. */
1309 if (SMB_VFS_FCHMOD_ACL(fsp, unx_mode) == -1 &&
1310 errno == ENOSYS) {
1311 errno = saved_errno; /* Ignore ENOSYS */
1314 } else if (new_unx_mode) {
1316 int ret = -1;
1318 /* Attributes need changing. File already existed. */
1321 int saved_errno = errno; /* We might get ENOSYS in the
1322 * next call.. */
1323 ret = SMB_VFS_FCHMOD_ACL(fsp, new_unx_mode);
1325 if (ret == -1 && errno == ENOSYS) {
1326 errno = saved_errno; /* Ignore ENOSYS */
1327 } else {
1328 DEBUG(5, ("onefs_open_file_ntcreate: reset "
1329 "attributes of file %s to 0%o\n",
1330 fname, (unsigned int)new_unx_mode));
1331 ret = 0; /* Don't do the fchmod below. */
1335 if ((ret == -1) &&
1336 (SMB_VFS_FCHMOD(fsp, new_unx_mode) == -1))
1337 DEBUG(5, ("onefs_open_file_ntcreate: failed to reset "
1338 "attributes of file %s to 0%o\n",
1339 fname, (unsigned int)new_unx_mode));
1342 /* If this is a successful open, we must remove any deferred open
1343 * records. */
1344 if (req != NULL) {
1345 del_deferred_open_entry(lck, req->mid);
1347 TALLOC_FREE(lck);
1349 return NT_STATUS_OK;
1353 /****************************************************************************
1354 Open a directory from an NT SMB call.
1355 ****************************************************************************/
1356 static NTSTATUS onefs_open_directory(connection_struct *conn,
1357 struct smb_request *req,
1358 const char *fname,
1359 uint32 access_mask,
1360 uint32 share_access,
1361 uint32 create_disposition,
1362 uint32 create_options,
1363 uint32 file_attributes,
1364 struct security_descriptor *sd,
1365 files_struct **result,
1366 int *pinfo,
1367 SMB_STRUCT_STAT *psbuf)
1369 files_struct *fsp = NULL;
1370 struct share_mode_lock *lck = NULL;
1371 NTSTATUS status;
1372 struct timespec mtimespec;
1373 int info = 0;
1374 char *parent_dir;
1375 const char *dirname;
1376 bool posix_open = false;
1377 uint32 create_flags = 0;
1378 uint32 mode = lp_dir_mask(SNUM(conn));
1380 DEBUG(5, ("onefs_open_directory: opening directory %s, "
1381 "access_mask = 0x%x, "
1382 "share_access = 0x%x create_options = 0x%x, "
1383 "create_disposition = 0x%x, file_attributes = 0x%x\n",
1384 fname, (unsigned int)access_mask, (unsigned int)share_access,
1385 (unsigned int)create_options, (unsigned int)create_disposition,
1386 (unsigned int)file_attributes));
1388 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
1389 (conn->fs_capabilities & FILE_NAMED_STREAMS) &&
1390 is_ntfs_stream_name(fname)) {
1391 DEBUG(2, ("onefs_open_directory: %s is a stream name!\n", fname));
1392 return NT_STATUS_NOT_A_DIRECTORY;
1395 switch (create_disposition) {
1396 case FILE_OPEN:
1397 /* If directory exists open. If directory doesn't
1398 * exist error. */
1399 create_flags = 0;
1400 info = FILE_WAS_OPENED;
1401 break;
1402 case FILE_CREATE:
1403 /* If directory exists error. If directory doesn't
1404 * exist create. */
1405 create_flags = O_CREAT | O_EXCL;
1406 info = FILE_WAS_CREATED;
1407 break;
1408 case FILE_OPEN_IF:
1409 /* If directory exists open. If directory doesn't
1410 * exist create. */
1412 /* Note: in order to return whether the directory was
1413 * opened or created, we first try to open and then try
1414 * to create. */
1415 create_flags = 0;
1416 info = FILE_WAS_OPENED;
1417 break;
1418 case FILE_SUPERSEDE:
1419 case FILE_OVERWRITE:
1420 case FILE_OVERWRITE_IF:
1421 default:
1422 DEBUG(5, ("onefs_open_directory: invalid "
1423 "create_disposition 0x%x for directory %s\n",
1424 (unsigned int)create_disposition, fname));
1425 return NT_STATUS_INVALID_PARAMETER;
1429 * Check for write access to the share. Done in mkdir_internal() in
1430 * mainline samba.
1432 if (!CAN_WRITE(conn) && (create_flags & O_CREAT)) {
1433 return NT_STATUS_ACCESS_DENIED;
1436 /* Get parent dirname */
1437 if (!parent_dirname(talloc_tos(), fname, &parent_dir, &dirname)) {
1438 return NT_STATUS_NO_MEMORY;
1441 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
1442 posix_open = true;
1443 mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
1444 file_attributes = 0;
1445 } else {
1446 mode = unix_mode(conn, aDIR, fname, parent_dir);
1450 * The NONINDEXED and COMPRESSED bits seem to always be cleared on
1451 * directories, no matter if you specify that they should be set.
1453 file_attributes &=
1454 ~(FILE_ATTRIBUTE_NONINDEXED | FILE_ATTRIBUTE_COMPRESSED);
1456 status = file_new(req, conn, &fsp);
1457 if(!NT_STATUS_IS_OK(status)) {
1458 return status;
1462 * Actual open with retry magic to handle FILE_OPEN_IF which is
1463 * unique because the kernel won't tell us if the file was opened or
1464 * created.
1466 retry_open:
1467 fsp->fh->fd = onefs_sys_create_file(conn,
1469 fname,
1470 access_mask,
1471 access_mask,
1472 share_access,
1473 create_options,
1474 create_flags | O_DIRECTORY,
1475 mode,
1479 file_attributes,
1480 NULL);
1482 if (fsp->fh->fd == -1) {
1483 DEBUG(3, ("Error opening %s. Errno=%d (%s).\n", fname, errno,
1484 strerror(errno)));
1485 SMB_ASSERT(errno != EINPROGRESS);
1487 if (create_disposition == FILE_OPEN_IF) {
1488 if (errno == ENOENT) {
1489 /* Try again, creating it this time. */
1490 create_flags = O_CREAT | O_EXCL;
1491 info = FILE_WAS_CREATED;
1492 goto retry_open;
1493 } else if (errno == EEXIST) {
1494 /* Uggh. Try again again. */
1495 create_flags = 0;
1496 info = FILE_WAS_OPENED;
1497 goto retry_open;
1501 /* Error cases below: */
1502 file_free(req, fsp);
1504 if ((errno == ENOENT) && (create_disposition == FILE_OPEN)) {
1505 DEBUG(5,("onefs_open_directory: FILE_OPEN requested "
1506 "for directory %s and it doesn't "
1507 "exist.\n", fname ));
1508 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1509 } else if ((errno == EEXIST) &&
1510 (create_disposition == FILE_CREATE)) {
1511 DEBUG(5,("onefs_open_directory: FILE_CREATE "
1512 "requested for directory %s and it "
1513 "already exists.\n", fname ));
1514 return NT_STATUS_OBJECT_NAME_COLLISION;
1515 } else if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
1516 /* Catch sharing violations. */
1517 return NT_STATUS_SHARING_VIOLATION;
1520 return map_nt_error_from_unix(errno);
1523 if (info == FILE_WAS_CREATED) {
1525 /* Pulled from mkdir_internal() */
1526 if (SMB_VFS_LSTAT(conn, fname, psbuf) == -1) {
1527 DEBUG(2, ("Could not stat directory '%s' just "
1528 "created: %s\n",fname, strerror(errno)));
1529 return map_nt_error_from_unix(errno);
1532 if (!S_ISDIR(psbuf->st_mode)) {
1533 DEBUG(0, ("Directory just '%s' created is not a "
1534 "directory\n", fname));
1535 return NT_STATUS_ACCESS_DENIED;
1538 if (!posix_open) {
1540 * Check if high bits should have been set, then (if
1541 * bits are missing): add them. Consider bits
1542 * automagically set by UNIX, i.e. SGID bit from
1543 * parent dir.
1545 if (mode & ~(S_IRWXU|S_IRWXG|S_IRWXO) &&
1546 (mode & ~psbuf->st_mode)) {
1547 SMB_VFS_CHMOD(conn, fname, (psbuf->st_mode |
1548 (mode & ~psbuf->st_mode)));
1552 /* Change the owner if required. */
1553 if (lp_inherit_owner(SNUM(conn))) {
1554 change_dir_owner_to_parent(conn, parent_dir, fname,
1555 psbuf);
1558 notify_fname(conn, NOTIFY_ACTION_ADDED,
1559 FILE_NOTIFY_CHANGE_DIR_NAME, fname);
1562 /* Stat the fd for Samba bookkeeping. */
1563 if(SMB_VFS_FSTAT(fsp, psbuf) != 0) {
1564 fd_close(fsp);
1565 file_free(req, fsp);
1566 return map_nt_error_from_unix(errno);
1569 /* Setup the files_struct for it. */
1570 fsp->mode = psbuf->st_mode;
1571 fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf);
1572 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
1573 fsp->file_pid = req ? req->smbpid : 0;
1574 fsp->can_lock = False;
1575 fsp->can_read = False;
1576 fsp->can_write = False;
1578 fsp->share_access = share_access;
1579 fsp->fh->private_options = create_options;
1581 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
1583 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
1584 fsp->print_file = False;
1585 fsp->modified = False;
1586 fsp->oplock_type = NO_OPLOCK;
1587 fsp->sent_oplock_break = NO_BREAK_SENT;
1588 fsp->is_directory = True;
1589 fsp->posix_open = posix_open;
1591 string_set(&fsp->fsp_name,fname);
1593 mtimespec = get_mtimespec(psbuf);
1596 * Still set the samba share mode lock for correct delete-on-close
1597 * semantics and to make smbstatus more useful.
1599 lck = get_share_mode_lock(talloc_tos(), fsp->file_id,
1600 conn->connectpath,
1601 fname, &mtimespec);
1603 if (lck == NULL) {
1604 DEBUG(0, ("onefs_open_directory: Could not get share mode "
1605 "lock for %s\n", fname));
1606 fd_close(fsp);
1607 file_free(req, fsp);
1608 return NT_STATUS_SHARING_VIOLATION;
1611 if (lck->delete_on_close) {
1612 TALLOC_FREE(lck);
1613 fd_close(fsp);
1614 file_free(req, fsp);
1615 return NT_STATUS_DELETE_PENDING;
1618 set_share_mode(lck, fsp, conn->server_info->utok.uid, 0, NO_OPLOCK);
1621 * For directories the delete on close bit at open time seems
1622 * always to be honored on close... See test 19 in Samba4 BASE-DELETE.
1624 if (create_options & FILE_DELETE_ON_CLOSE) {
1625 status = can_set_delete_on_close(fsp, True, 0);
1626 if (!NT_STATUS_IS_OK(status) &&
1627 !NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
1628 TALLOC_FREE(lck);
1629 fd_close(fsp);
1630 file_free(req, fsp);
1631 return status;
1634 if (NT_STATUS_IS_OK(status)) {
1635 /* Note that here we set the *inital* delete on close flag,
1636 not the regular one. The magic gets handled in close. */
1637 fsp->initial_delete_on_close = True;
1641 TALLOC_FREE(lck);
1643 if (pinfo) {
1644 *pinfo = info;
1647 *result = fsp;
1648 return NT_STATUS_OK;
1652 * Wrapper around onefs_open_file_ntcreate and onefs_open_directory.
1654 static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
1655 struct smb_request *req,
1656 const char *fname,
1657 uint32_t access_mask,
1658 uint32_t share_access,
1659 uint32_t create_disposition,
1660 uint32_t create_options,
1661 uint32_t file_attributes,
1662 uint32_t oplock_request,
1663 uint64_t allocation_size,
1664 struct security_descriptor *sd,
1665 struct ea_list *ea_list,
1666 files_struct **result,
1667 int *pinfo,
1668 struct onefs_fsp_data *fsp_data,
1669 SMB_STRUCT_STAT *psbuf)
1671 SMB_STRUCT_STAT sbuf;
1672 int info = FILE_WAS_OPENED;
1673 files_struct *base_fsp = NULL;
1674 files_struct *fsp = NULL;
1675 NTSTATUS status;
1677 DEBUG(10,("onefs_create_file_unixpath: access_mask = 0x%x "
1678 "file_attributes = 0x%x, share_access = 0x%x, "
1679 "create_disposition = 0x%x create_options = 0x%x "
1680 "oplock_request = 0x%x ea_list = 0x%p, sd = 0x%p, "
1681 "fname = %s\n",
1682 (unsigned int)access_mask,
1683 (unsigned int)file_attributes,
1684 (unsigned int)share_access,
1685 (unsigned int)create_disposition,
1686 (unsigned int)create_options,
1687 (unsigned int)oplock_request,
1688 ea_list, sd, fname));
1690 if (create_options & FILE_OPEN_BY_FILE_ID) {
1691 status = NT_STATUS_NOT_SUPPORTED;
1692 goto fail;
1695 if (create_options & NTCREATEX_OPTIONS_INVALID_PARAM_MASK) {
1696 status = NT_STATUS_INVALID_PARAMETER;
1697 goto fail;
1700 if (req == NULL) {
1701 SMB_ASSERT((oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK) ==
1702 NO_OPLOCK);
1703 oplock_request |= INTERNAL_OPEN_ONLY;
1706 if (psbuf != NULL) {
1707 sbuf = *psbuf;
1709 else {
1710 if (SMB_VFS_STAT(conn, fname, &sbuf) == -1) {
1711 SET_STAT_INVALID(sbuf);
1715 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
1716 && (access_mask & DELETE_ACCESS)
1717 && !is_ntfs_stream_name(fname)) {
1719 * We can't open a file with DELETE access if any of the
1720 * streams is open without FILE_SHARE_DELETE
1722 status = open_streams_for_delete(conn, fname);
1724 if (!NT_STATUS_IS_OK(status)) {
1725 goto fail;
1729 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
1730 && is_ntfs_stream_name(fname)) {
1731 char *base;
1732 uint32 base_create_disposition;
1734 if (create_options & FILE_DIRECTORY_FILE) {
1735 status = NT_STATUS_NOT_A_DIRECTORY;
1736 goto fail;
1739 status = onefs_split_ntfs_stream_name(talloc_tos(), fname,
1740 &base, NULL);
1741 if (!NT_STATUS_IS_OK(status)) {
1742 DEBUG(10, ("onefs_create_file_unixpath: "
1743 "split_ntfs_stream_name failed: %s\n",
1744 nt_errstr(status)));
1745 goto fail;
1748 SMB_ASSERT(!is_ntfs_stream_name(base)); /* paranoia.. */
1750 switch (create_disposition) {
1751 case FILE_OPEN:
1752 base_create_disposition = FILE_OPEN;
1753 break;
1754 default:
1755 base_create_disposition = FILE_OPEN_IF;
1756 break;
1759 status = onefs_create_file_unixpath(
1760 conn, /* conn */
1761 NULL, /* req */
1762 base, /* fname */
1763 SYNCHRONIZE_ACCESS, /* access_mask */
1764 (FILE_SHARE_READ |
1765 FILE_SHARE_WRITE |
1766 FILE_SHARE_DELETE), /* share_access */
1767 base_create_disposition, /* create_disposition*/
1768 0, /* create_options */
1769 file_attributes, /* file_attributes */
1770 NO_OPLOCK, /* oplock_request */
1771 0, /* allocation_size */
1772 NULL, /* sd */
1773 NULL, /* ea_list */
1774 &base_fsp, /* result */
1775 NULL, /* pinfo */
1776 NULL, /* fsp_data */
1777 NULL); /* psbuf */
1779 if (!NT_STATUS_IS_OK(status)) {
1780 DEBUG(10, ("onefs_create_file_unixpath for base %s "
1781 "failed: %s\n", base, nt_errstr(status)));
1782 goto fail;
1786 /* Covert generic bits in the security descriptor. */
1787 if (sd != NULL) {
1788 security_acl_map_generic(sd->dacl, &file_generic_mapping);
1789 security_acl_map_generic(sd->sacl, &file_generic_mapping);
1793 * If it's a request for a directory open, deal with it separately.
1796 if (create_options & FILE_DIRECTORY_FILE) {
1798 if (create_options & FILE_NON_DIRECTORY_FILE) {
1799 status = NT_STATUS_INVALID_PARAMETER;
1800 goto fail;
1803 /* Can't open a temp directory. IFS kit test. */
1804 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
1805 (file_attributes & FILE_ATTRIBUTE_TEMPORARY)) {
1806 status = NT_STATUS_INVALID_PARAMETER;
1807 goto fail;
1811 * We will get a create directory here if the Win32
1812 * app specified a security descriptor in the
1813 * CreateDirectory() call.
1816 status = onefs_open_directory(
1817 conn, /* conn */
1818 req, /* req */
1819 fname, /* fname */
1820 access_mask, /* access_mask */
1821 share_access, /* share_access */
1822 create_disposition, /* create_disposition*/
1823 create_options, /* create_options */
1824 file_attributes, /* file_attributes */
1825 sd, /* sd */
1826 &fsp, /* result */
1827 &info, /* pinfo */
1828 &sbuf); /* psbuf */
1829 } else {
1832 * Ordinary file case.
1835 status = file_new(req, conn, &fsp);
1836 if(!NT_STATUS_IS_OK(status)) {
1837 goto fail;
1841 * We're opening the stream element of a base_fsp
1842 * we already opened. Set up the base_fsp pointer.
1844 if (base_fsp) {
1845 fsp->base_fsp = base_fsp;
1848 status = onefs_open_file_ntcreate(
1849 conn, /* conn */
1850 req, /* req */
1851 fname, /* fname */
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 */
1857 oplock_request, /* oplock_request */
1858 sd, /* sd */
1859 fsp, /* result */
1860 &info, /* pinfo */
1861 fsp_data, /* fsp_data */
1862 &sbuf); /* psbuf */
1864 if(!NT_STATUS_IS_OK(status)) {
1865 file_free(req, fsp);
1866 fsp = NULL;
1869 if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
1871 /* A stream open never opens a directory */
1873 if (base_fsp) {
1874 status = NT_STATUS_FILE_IS_A_DIRECTORY;
1875 goto fail;
1879 * Fail the open if it was explicitly a non-directory
1880 * file.
1883 if (create_options & FILE_NON_DIRECTORY_FILE) {
1884 status = NT_STATUS_FILE_IS_A_DIRECTORY;
1885 goto fail;
1888 create_options |= FILE_DIRECTORY_FILE;
1890 status = onefs_open_directory(
1891 conn, /* conn */
1892 req, /* req */
1893 fname, /* fname */
1894 access_mask, /* access_mask */
1895 share_access, /* share_access */
1896 create_disposition, /* create_disposition*/
1897 create_options, /* create_options */
1898 file_attributes, /* file_attributes */
1899 sd, /* sd */
1900 &fsp, /* result */
1901 &info, /* pinfo */
1902 &sbuf); /* psbuf */
1906 if (!NT_STATUS_IS_OK(status)) {
1907 goto fail;
1910 fsp->base_fsp = base_fsp;
1912 SMB_ASSERT(fsp);
1914 if ((ea_list != NULL) && (info == FILE_WAS_CREATED)) {
1915 status = set_ea(conn, fsp, fname, ea_list);
1916 if (!NT_STATUS_IS_OK(status)) {
1917 goto fail;
1921 if (!fsp->is_directory && S_ISDIR(sbuf.st_mode)) {
1922 status = NT_STATUS_ACCESS_DENIED;
1923 goto fail;
1926 /* Save the requested allocation size. */
1927 if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
1928 if (allocation_size
1929 && (allocation_size > sbuf.st_size)) {
1930 fsp->initial_allocation_size = smb_roundup(
1931 fsp->conn, allocation_size);
1932 if (fsp->is_directory) {
1933 /* Can't set allocation size on a directory. */
1934 status = NT_STATUS_ACCESS_DENIED;
1935 goto fail;
1937 if (vfs_allocate_file_space(
1938 fsp, fsp->initial_allocation_size) == -1) {
1939 status = NT_STATUS_DISK_FULL;
1940 goto fail;
1942 } else {
1943 fsp->initial_allocation_size = smb_roundup(
1944 fsp->conn, (uint64_t)sbuf.st_size);
1948 DEBUG(10, ("onefs_create_file_unixpath: info=%d\n", info));
1950 *result = fsp;
1951 if (pinfo != NULL) {
1952 *pinfo = info;
1954 if (psbuf != NULL) {
1955 if ((fsp->fh == NULL) || (fsp->fh->fd == -1)) {
1956 *psbuf = sbuf;
1958 else {
1959 SMB_VFS_FSTAT(fsp, psbuf);
1962 return NT_STATUS_OK;
1964 fail:
1965 DEBUG(10, ("onefs_create_file_unixpath: %s\n", nt_errstr(status)));
1967 if (fsp != NULL) {
1968 if (base_fsp && fsp->base_fsp == base_fsp) {
1970 * The close_file below will close
1971 * fsp->base_fsp.
1973 base_fsp = NULL;
1975 close_file(req, fsp, ERROR_CLOSE);
1976 fsp = NULL;
1978 if (base_fsp != NULL) {
1979 close_file(req, base_fsp, ERROR_CLOSE);
1980 base_fsp = NULL;
1982 return status;
1985 static void destroy_onefs_fsp_data(void *p_data)
1987 struct onefs_fsp_data *fsp_data = (struct onefs_fsp_data *)p_data;
1989 destroy_onefs_callback_record(fsp_data->oplock_callback_id);
1993 * SMB_VFS_CREATE_FILE interface to onefs.
1995 NTSTATUS onefs_create_file(vfs_handle_struct *handle,
1996 struct smb_request *req,
1997 uint16_t root_dir_fid,
1998 const char *fname,
1999 uint32_t create_file_flags,
2000 uint32_t access_mask,
2001 uint32_t share_access,
2002 uint32_t create_disposition,
2003 uint32_t create_options,
2004 uint32_t file_attributes,
2005 uint32_t oplock_request,
2006 uint64_t allocation_size,
2007 struct security_descriptor *sd,
2008 struct ea_list *ea_list,
2009 files_struct **result,
2010 int *pinfo,
2011 SMB_STRUCT_STAT *psbuf)
2013 connection_struct *conn = handle->conn;
2014 struct case_semantics_state *case_state = NULL;
2015 struct onefs_fsp_data fsp_data = {};
2016 SMB_STRUCT_STAT sbuf;
2017 int info = FILE_WAS_OPENED;
2018 files_struct *fsp = NULL;
2019 NTSTATUS status;
2021 DEBUG(10,("onefs_create_file: access_mask = 0x%x "
2022 "file_attributes = 0x%x, share_access = 0x%x, "
2023 "create_disposition = 0x%x create_options = 0x%x "
2024 "oplock_request = 0x%x "
2025 "root_dir_fid = 0x%x, ea_list = 0x%p, sd = 0x%p, "
2026 "create_file_flags = 0x%x, fname = %s\n",
2027 (unsigned int)access_mask,
2028 (unsigned int)file_attributes,
2029 (unsigned int)share_access,
2030 (unsigned int)create_disposition,
2031 (unsigned int)create_options,
2032 (unsigned int)oplock_request,
2033 (unsigned int)root_dir_fid,
2034 ea_list, sd, create_file_flags, fname));
2036 /* Get the file name if root_dir_fid was specified. */
2037 if (root_dir_fid != 0) {
2038 char *new_fname;
2040 status = get_relative_fid_filename(conn, req, root_dir_fid,
2041 fname, &new_fname);
2042 if (!NT_STATUS_IS_OK(status)) {
2043 goto fail;
2046 fname = new_fname;
2049 /* Resolve the file name if this was a DFS pathname. */
2050 if ((req != NULL) && (req->flags2 & FLAGS2_DFS_PATHNAMES)) {
2051 char *resolved_fname;
2053 status = resolve_dfspath(talloc_tos(), conn, true, fname,
2054 &resolved_fname);
2056 if (!NT_STATUS_IS_OK(status)) {
2058 * For PATH_NOT_COVERED we had
2059 * reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
2060 * ERRSRV, ERRbadpath);
2061 * Need to fix in callers
2063 goto fail;
2065 fname = resolved_fname;
2068 /* Check if POSIX semantics are wanted. */
2069 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
2070 case_state = set_posix_case_semantics(talloc_tos(), conn);
2073 /* Convert dos path to unix path if it hasn't already been done. */
2074 if (create_file_flags & CFF_DOS_PATH) {
2075 char *converted_fname;
2077 SET_STAT_INVALID(sbuf);
2079 status = unix_convert(talloc_tos(), conn, fname, False,
2080 &converted_fname, NULL, &sbuf);
2081 if (!NT_STATUS_IS_OK(status)) {
2082 goto fail;
2084 fname = converted_fname;
2085 } else {
2086 if (psbuf != NULL) {
2087 sbuf = *psbuf;
2088 } else {
2089 if (SMB_VFS_STAT(conn, fname, &sbuf) == -1) {
2090 SET_STAT_INVALID(sbuf);
2096 TALLOC_FREE(case_state);
2098 /* All file access must go through check_name() */
2099 status = check_name(conn, fname);
2100 if (!NT_STATUS_IS_OK(status)) {
2101 goto fail;
2104 status = onefs_create_file_unixpath(
2105 conn, /* conn */
2106 req, /* req */
2107 fname, /* fname */
2108 access_mask, /* access_mask */
2109 share_access, /* share_access */
2110 create_disposition, /* create_disposition*/
2111 create_options, /* create_options */
2112 file_attributes, /* file_attributes */
2113 oplock_request, /* oplock_request */
2114 allocation_size, /* allocation_size */
2115 sd, /* sd */
2116 ea_list, /* ea_list */
2117 &fsp, /* result */
2118 &info, /* pinfo */
2119 &fsp_data, /* fsp_data */
2120 &sbuf); /* psbuf */
2122 if (!NT_STATUS_IS_OK(status)) {
2123 goto fail;
2126 DEBUG(10, ("onefs_create_file: info=%d\n", info));
2129 * Setup private onefs_fsp_data. Currently the private data struct is
2130 * only used to store the oplock_callback_id so that when the file is
2131 * closed, the onefs_callback_record can be properly cleaned up in the
2132 * oplock_onefs sub-system.
2134 if (fsp) {
2135 struct onefs_fsp_data *fsp_data_tmp = NULL;
2136 fsp_data_tmp = (struct onefs_fsp_data *)
2137 VFS_ADD_FSP_EXTENSION(handle, fsp, struct onefs_fsp_data,
2138 &destroy_onefs_fsp_data);
2140 if (fsp_data_tmp == NULL) {
2141 status = NT_STATUS_NO_MEMORY;
2142 goto fail;
2145 *fsp_data_tmp = fsp_data;
2148 *result = fsp;
2149 if (pinfo != NULL) {
2150 *pinfo = info;
2152 if (psbuf != NULL) {
2153 *psbuf = sbuf;
2155 return NT_STATUS_OK;
2157 fail:
2158 DEBUG(10, ("onefs_create_file: %s\n", nt_errstr(status)));
2160 if (fsp != NULL) {
2161 close_file(req, fsp, ERROR_CLOSE);
2162 fsp = NULL;
2164 return status;