s3/ldbtools: don't neddlessly link against wbinbind libs
[Samba/gebeck_regimport.git] / source3 / modules / onefs_open.c
blobc23c176b79a8336feec25611971fe04d92055cee
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\n",
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\n",
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 static void schedule_defer_open(struct share_mode_lock *lck,
392 struct timeval request_time,
393 struct smb_request *req)
395 struct deferred_open_record state;
397 /* This is a relative time, added to the absolute
398 request_time value to get the absolute timeout time.
399 Note that if this is the second or greater time we enter
400 this codepath for this particular request mid then
401 request_time is left as the absolute time of the *first*
402 time this request mid was processed. This is what allows
403 the request to eventually time out. */
405 struct timeval timeout;
407 /* Normally the smbd we asked should respond within
408 * OPLOCK_BREAK_TIMEOUT seconds regardless of whether
409 * the client did, give twice the timeout as a safety
410 * measure here in case the other smbd is stuck
411 * somewhere else. */
414 * On OneFS, the kernel will always send an oplock_revoked message
415 * before this timeout is hit.
417 timeout = timeval_set(OPLOCK_BREAK_TIMEOUT*10, 0);
419 /* Nothing actually uses state.delayed_for_oplocks
420 but it's handy to differentiate in debug messages
421 between a 30 second delay due to oplock break, and
422 a 1 second delay for share mode conflicts. */
424 state.delayed_for_oplocks = True;
425 state.failed = false;
426 state.id = lck->id;
428 if (!request_timed_out(request_time, timeout)) {
429 defer_open(lck, request_time, timeout, req, &state);
433 /****************************************************************************
434 Open a file with a share mode. Passed in an already created files_struct.
435 ****************************************************************************/
436 NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
437 struct smb_request *req,
438 const char *fname,
439 uint32 access_mask,
440 uint32 share_access,
441 uint32 create_disposition,
442 uint32 create_options,
443 uint32 new_dos_attributes,
444 int oplock_request,
445 struct security_descriptor *sd,
446 files_struct *fsp,
447 int *pinfo,
448 struct onefs_fsp_data *fsp_data,
449 SMB_STRUCT_STAT *psbuf)
451 int flags=0;
452 int flags2=0;
453 bool file_existed = VALID_STAT(*psbuf);
454 bool def_acl = False;
455 bool posix_open = False;
456 bool new_file_created = False;
457 bool clear_ads = False;
458 struct file_id id;
459 mode_t new_unx_mode = (mode_t)0;
460 mode_t unx_mode = (mode_t)0;
461 int info;
462 uint32 existing_dos_attributes = 0;
463 struct pending_message_list *pml = NULL;
464 struct timeval request_time = timeval_zero();
465 struct share_mode_lock *lck = NULL;
466 uint32 open_access_mask = access_mask;
467 NTSTATUS status;
468 int ret_flock;
469 char *parent_dir;
470 const char *newname;
471 int granted_oplock;
472 uint64_t oplock_callback_id = 0;
473 uint32 createfile_attributes = 0;
475 ZERO_STRUCT(id);
477 if (conn->printer) {
479 * Printers are handled completely differently.
480 * Most of the passed parameters are ignored.
483 if (pinfo) {
484 *pinfo = FILE_WAS_CREATED;
487 DEBUG(10, ("onefs_open_file_ntcreate: printer open fname=%s\n",
488 fname));
490 return print_fsp_open(req, conn, fname, req->vuid, fsp, psbuf);
493 if (!parent_dirname(talloc_tos(), fname, &parent_dir, &newname)) {
494 return NT_STATUS_NO_MEMORY;
497 if (new_dos_attributes & FILE_FLAG_POSIX_SEMANTICS) {
498 posix_open = True;
499 unx_mode = (mode_t)(new_dos_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
500 new_dos_attributes = 0;
501 } else {
502 /* We add aARCH to this as this mode is only used if the file is
503 * created new. */
504 unx_mode = unix_mode(conn, new_dos_attributes | aARCH, fname,
505 parent_dir);
508 DEBUG(10,("onefs_open_file_ntcreate: fname=%s, dos_attrs=0x%x "
509 "access_mask=0x%x share_access=0x%x "
510 "create_disposition = 0x%x create_options=0x%x "
511 "unix mode=0%o oplock_request=0x%x\n",
512 fname, new_dos_attributes, access_mask, share_access,
513 create_disposition, create_options, unx_mode,
514 oplock_request));
517 * Any non-stat-only open has the potential to contend oplocks, which
518 * means to avoid blocking in the kernel (which is unacceptable), the
519 * open must be deferred. In order to defer opens, req must not be
520 * NULL. The known cases of calling with a NULL req:
522 * 1. Open the base file of a stream: Always done stat-only
524 * 2. Open the stream: Oplocks are disallowed on streams, so an
525 * oplock will never be contended.
527 * 3. open_file_fchmod(), which is called from 3 places:
528 * A. try_chown: Posix acls only. Never called on onefs.
529 * B. set_ea_dos_attributes: Can't be called from onefs, because
530 * SMB_VFS_SETXATTR return ENOSYS.
531 * C. file_set_dos_mode: This would only happen if the "dos
532 * filemode" smb.conf parameter is set to yes. We ship with
533 * it off, but if a customer were to turn it on it would be
534 * bad.
536 if (req == NULL && !is_stat_open(access_mask) && !is_ntfs_stream_name(fname)) {
537 smb_panic("NULL req on a non-stat-open!");
540 if ((req == NULL) && ((oplock_request & INTERNAL_OPEN_ONLY) == 0)) {
541 DEBUG(0, ("No smb request but not an internal only open!\n"));
542 return NT_STATUS_INTERNAL_ERROR;
546 * Only non-internal opens can be deferred at all
549 if ((req != NULL)
550 && ((pml = get_open_deferred_message(req->mid)) != NULL)) {
551 struct deferred_open_record *state =
552 (struct deferred_open_record *)pml->private_data.data;
554 /* Remember the absolute time of the original
555 request with this mid. We'll use it later to
556 see if this has timed out. */
558 request_time = pml->request_time;
560 /* Remove the deferred open entry under lock. */
561 lck = get_share_mode_lock(talloc_tos(), state->id, NULL, NULL,
562 NULL);
563 if (lck == NULL) {
564 DEBUG(0, ("could not get share mode lock\n"));
565 } else {
566 del_deferred_open_entry(lck, req->mid);
567 TALLOC_FREE(lck);
570 /* Ensure we don't reprocess this message. */
571 remove_deferred_open_smb_message(req->mid);
574 * When receiving a semlock_async_failure message, the
575 * deferred open will be marked as "failed". Returning
576 * INTERNAL_ERROR.
578 if (state->failed) {
579 DEBUG(0, ("onefs_open_file_ntcreate: "
580 "semlock_async_failure detected!\n"));
581 return NT_STATUS_INTERNAL_ERROR;
585 status = check_name(conn, fname);
586 if (!NT_STATUS_IS_OK(status)) {
587 return status;
590 if (!posix_open) {
591 new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
592 if (file_existed) {
593 existing_dos_attributes = dos_mode(conn, fname, psbuf);
597 /* Setup dos_attributes to be set by ifs_createfile */
598 if (lp_store_dos_attributes(SNUM(conn))) {
599 createfile_attributes = (new_dos_attributes | aARCH) &
600 ~(FILE_ATTRIBUTE_NONINDEXED | FILE_ATTRIBUTE_COMPRESSED);
603 /* Ignore oplock requests if oplocks are disabled. */
604 if (!lp_oplocks(SNUM(conn)) || global_client_failed_oplock_break ||
605 IS_VETO_OPLOCK_PATH(conn, fname)) {
606 /* Mask off everything except the private Samba bits. */
607 oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
610 /* this is for OS/2 long file names - say we don't support them */
611 if (!lp_posix_pathnames() && strstr(fname,".+,;=[].")) {
612 /* OS/2 Workplace shell fix may be main code stream in a later
613 * release. */
614 DEBUG(5,("onefs_open_file_ntcreate: OS/2 long filenames are "
615 "not supported.\n"));
616 if (use_nt_status()) {
617 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
619 return NT_STATUS_DOS(ERRDOS, ERRcannotopen);
622 switch( create_disposition ) {
624 * Currently we're using FILE_SUPERSEDE as the same as
625 * FILE_OVERWRITE_IF but they really are
626 * different. FILE_SUPERSEDE deletes an existing file
627 * (requiring delete access) then recreates it.
629 case FILE_SUPERSEDE:
631 * @todo: Clear all file attributes?
632 * http://www.osronline.com/article.cfm?article=302
633 * create if not exist, trunc if exist
635 * If file exists replace/overwrite. If file doesn't
636 * exist create.
638 flags2 |= (O_CREAT | O_TRUNC);
639 clear_ads = true;
640 break;
642 case FILE_OVERWRITE_IF:
643 /* If file exists replace/overwrite. If file doesn't
644 * exist create. */
645 flags2 |= (O_CREAT | O_TRUNC);
646 clear_ads = true;
647 break;
649 case FILE_OPEN:
650 /* If file exists open. If file doesn't exist error. */
651 if (!file_existed) {
652 DEBUG(5,("onefs_open_file_ntcreate: FILE_OPEN "
653 "requested for file %s and file "
654 "doesn't exist.\n", fname ));
655 errno = ENOENT;
656 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
658 break;
660 case FILE_OVERWRITE:
661 /* If file exists overwrite. If file doesn't exist
662 * error. */
663 if (!file_existed) {
664 DEBUG(5, ("onefs_open_file_ntcreate: "
665 "FILE_OVERWRITE requested for file "
666 "%s and file doesn't exist.\n",
667 fname));
668 errno = ENOENT;
669 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
671 flags2 |= O_TRUNC;
672 clear_ads = true;
673 break;
675 case FILE_CREATE:
676 /* If file exists error. If file doesn't exist
677 * create. */
678 if (file_existed) {
679 DEBUG(5, ("onefs_open_file_ntcreate: "
680 "FILE_CREATE requested for file %s "
681 "and file already exists.\n",
682 fname));
683 if (S_ISDIR(psbuf->st_mode)) {
684 errno = EISDIR;
685 } else {
686 errno = EEXIST;
688 return map_nt_error_from_unix(errno);
690 flags2 |= (O_CREAT|O_EXCL);
691 break;
693 case FILE_OPEN_IF:
694 /* If file exists open. If file doesn't exist
695 * create. */
696 flags2 |= O_CREAT;
697 break;
699 default:
700 return NT_STATUS_INVALID_PARAMETER;
703 /* Match attributes on file exists and overwrite. */
704 if (!posix_open && file_existed &&
705 ((create_disposition == FILE_OVERWRITE) ||
706 (create_disposition == FILE_OVERWRITE_IF))) {
707 if (!open_match_attributes(conn, fname,
708 existing_dos_attributes,
709 new_dos_attributes, psbuf->st_mode,
710 unx_mode, &new_unx_mode)) {
711 DEBUG(5, ("onefs_open_file_ntcreate: attributes "
712 "missmatch for file %s (%x %x) (0%o, 0%o)\n",
713 fname, existing_dos_attributes,
714 new_dos_attributes,
715 (unsigned int)psbuf->st_mode,
716 (unsigned int)unx_mode ));
717 errno = EACCES;
718 return NT_STATUS_ACCESS_DENIED;
723 * OneFS understands MAXIMUM_ALLOWED_ACCESS, so only hack the
724 * access_mask, but leave the MAA for the actual open in
725 * open_access_mask.
727 open_access_mask = access_mask;
728 if (open_access_mask & MAXIMUM_ALLOWED_ACCESS) {
729 access_mask |= FILE_GENERIC_ALL;
732 /* Convert GENERIC bits to specific bits. */
733 se_map_generic(&access_mask, &file_generic_mapping);
734 se_map_generic(&open_access_mask, &file_generic_mapping);
736 if ((flags2 & O_TRUNC) || (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE)) {
737 /* This will cause oplock breaks. */
738 open_access_mask |= FILE_WRITE_DATA;
741 if (lp_parm_bool(SNUM(fsp->conn), PARM_ONEFS_TYPE,
742 PARM_IGNORE_SACLS, PARM_IGNORE_SACLS_DEFAULT)) {
743 access_mask &= ~SYSTEM_SECURITY_ACCESS;
746 DEBUG(10, ("onefs_open_file_ntcreate: fname=%s, after mapping "
747 "open_access_mask=%#x, access_mask=0x%x\n",
748 fname, open_access_mask, access_mask));
751 * Note that we ignore the append flag as append does not
752 * mean the same thing under DOS and Unix.
755 if ((access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ||
756 (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE)) {
759 * DENY_DOS opens are always underlying read-write on the
760 * file handle, no matter what the requested access mask
761 * says. Stock samba just sets the flags, but since
762 * ifs_createfile uses the access_mask, it must be updated as
763 * well. This allows BASE-DENY* to pass.
765 if (create_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) {
767 DEBUG(10,("onefs_open_file_ntcreate: deny_dos: "
768 "Adding O_RDWR to flags "
769 "(0x%x) and some READ bits to "
770 "open_access_mask (0x%x)\n",
771 flags, open_access_mask));
773 flags = O_RDWR;
774 open_access_mask |= (FILE_READ_ATTRIBUTES |
775 FILE_READ_DATA | FILE_READ_EA | FILE_EXECUTE);
777 } else if (access_mask & (FILE_READ_ATTRIBUTES |
778 FILE_READ_DATA |
779 FILE_READ_EA |
780 FILE_EXECUTE)) {
781 flags = O_RDWR;
782 } else {
783 flags = O_WRONLY;
785 } else {
786 flags = O_RDONLY;
789 /* Currently we only look at FILE_WRITE_THROUGH for create options. */
790 #if defined(O_SYNC)
791 if ((create_options & FILE_WRITE_THROUGH) &&
792 lp_strict_sync(SNUM(conn))) {
793 flags2 |= O_SYNC;
795 #endif /* O_SYNC */
797 if (posix_open && (access_mask & FILE_APPEND_DATA)) {
798 flags2 |= O_APPEND;
801 if (!posix_open && !CAN_WRITE(conn)) {
803 * We should really return a permission denied error if either
804 * O_CREAT or O_TRUNC are set, but for compatibility with
805 * older versions of Samba we just AND them out.
807 flags2 &= ~(O_CREAT|O_TRUNC);
809 /* Deny DELETE_ACCESS explicitly if the share is read only. */
810 if (access_mask & DELETE_ACCESS) {
811 return map_nt_error_from_unix(EACCES);
815 /* Ensure we can't write on a read-only share or file. */
816 if (flags != O_RDONLY && file_existed &&
817 (!CAN_WRITE(conn) || IS_DOS_READONLY(existing_dos_attributes))) {
818 DEBUG(5, ("onefs_open_file_ntcreate: write access requested "
819 "for file %s on read only %s\n",
820 fname, !CAN_WRITE(conn) ? "share" : "file" ));
821 errno = EACCES;
822 return NT_STATUS_ACCESS_DENIED;
825 DEBUG(10, ("fsp = %p\n", fsp));
827 fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf);
828 fsp->share_access = share_access;
829 fsp->fh->private_options = create_options;
830 fsp->access_mask = open_access_mask; /* We change this to the
831 * requested access_mask after
832 * the open is done. */
833 fsp->posix_open = posix_open;
835 /* Ensure no SAMBA_PRIVATE bits can be set. */
836 fsp->oplock_type = (oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK);
838 if (timeval_is_zero(&request_time)) {
839 request_time = fsp->open_time;
842 if (file_existed) {
843 struct timespec old_write_time = get_mtimespec(psbuf);
844 id = vfs_file_id_from_sbuf(conn, psbuf);
846 lck = get_share_mode_lock(talloc_tos(), id,
847 conn->connectpath,
848 fname, &old_write_time);
850 if (lck == NULL) {
851 DEBUG(0, ("Could not get share mode lock\n"));
852 return NT_STATUS_SHARING_VIOLATION;
855 if (lck->delete_on_close) {
856 /* DELETE_PENDING is not deferred for a second */
857 TALLOC_FREE(lck);
858 return NT_STATUS_DELETE_PENDING;
862 SMB_ASSERT(!file_existed || (lck != NULL));
865 * Ensure we pay attention to default ACLs on directories. May be
866 * neccessary depending on ACL policies.
868 if ((flags2 & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
869 (def_acl = directory_has_default_acl(conn, parent_dir))) {
870 unx_mode = 0777;
873 DEBUG(4,("calling onefs_open_file with flags=0x%X flags2=0x%X "
874 "mode=0%o, access_mask = 0x%x, open_access_mask = 0x%x\n",
875 (unsigned int)flags, (unsigned int)flags2,
876 (unsigned int)unx_mode, (unsigned int)access_mask,
877 (unsigned int)open_access_mask));
880 * Since the open is guaranteed to be stat only if req == NULL, a
881 * callback record is only needed if req != NULL.
883 if (req) {
884 SMB_ASSERT(fsp_data);
885 oplock_callback_id = onefs_oplock_wait_record(req->mid);
886 if (oplock_callback_id == 0) {
887 return NT_STATUS_NO_MEMORY;
889 } else {
891 * It is also already asserted it's either a stream or a
892 * stat-only open at this point.
894 SMB_ASSERT(fsp->oplock_type == NO_OPLOCK);
897 /* Do the open. */
898 status = onefs_open_file(fsp,
899 conn,
900 req,
901 parent_dir,
902 newname,
903 fname,
904 psbuf,
905 flags|flags2,
906 unx_mode,
907 access_mask,
908 open_access_mask,
909 fsp->oplock_type,
910 oplock_callback_id,
911 share_access,
912 create_options,
913 createfile_attributes,
915 &granted_oplock);
917 if (!NT_STATUS_IS_OK(status)) {
919 /* OneFS Oplock Handling */
920 if (errno == EINPROGRESS) {
922 if (lck == NULL) {
924 struct deferred_open_record state;
925 struct timespec old_write_time;
927 old_write_time = get_mtimespec(psbuf);
929 DEBUG(3, ("Someone created file %s with an "
930 "oplock after we looked: Retrying\n",
931 fname));
933 * We hit the race that when we did the stat
934 * on the file it did not exist, and someone
935 * has created it in between the stat and the
936 * open_file() call. Just retry immediately.
938 id = vfs_file_id_from_sbuf(conn, psbuf);
939 if (!(lck = get_share_mode_lock(talloc_tos(),
940 id, conn->connectpath, fname,
941 &old_write_time))) {
943 * Emergency exit
945 DEBUG(0, ("onefs_open_file_ntcreate: "
946 "Could not get share mode "
947 "lock for %s\n", fname));
948 status = NT_STATUS_SHARING_VIOLATION;
949 goto cleanup_destroy;
952 state.delayed_for_oplocks = False;
953 state.id = id;
955 if (req != NULL) {
956 defer_open(lck, request_time,
957 timeval_zero(), req, &state);
959 goto cleanup_destroy;
961 /* Waiting for an oplock */
962 DEBUG(5,("Async createfile because a client has an "
963 "oplock on %s\n", fname));
965 SMB_ASSERT(req);
966 schedule_defer_open(lck, request_time, req);
967 goto cleanup;
970 /* Check for a sharing violation */
971 if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
972 uint32 can_access_mask;
973 bool can_access = True;
975 /* Check if this can be done with the deny_dos and fcb
976 * calls. */
978 /* Try to find dup fsp if possible. */
979 if (create_options &
980 (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS|
981 NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) {
983 if (req == NULL) {
984 DEBUG(0, ("DOS open without an SMB "
985 "request!\n"));
986 status = NT_STATUS_INTERNAL_ERROR;
987 goto cleanup_destroy;
990 /* Use the client requested access mask here,
991 * not the one we open with. */
992 status = fcb_or_dos_open(req,
993 conn,
994 fsp,
995 fname,
997 req->smbpid,
998 req->vuid,
999 access_mask,
1000 share_access,
1001 create_options);
1003 if (NT_STATUS_IS_OK(status)) {
1004 TALLOC_FREE(lck);
1005 if (pinfo) {
1006 *pinfo = FILE_WAS_OPENED;
1008 status = NT_STATUS_OK;
1009 goto cleanup;
1014 * This next line is a subtlety we need for
1015 * MS-Access. If a file open will fail due to share
1016 * permissions and also for security (access) reasons,
1017 * we need to return the access failed error, not the
1018 * share error. We can't open the file due to kernel
1019 * oplock deadlock (it's possible we failed above on
1020 * the open_mode_check()) so use a userspace check.
1023 if (flags & O_RDWR) {
1024 can_access_mask = FILE_READ_DATA|FILE_WRITE_DATA;
1025 } else if (flags & O_WRONLY) {
1026 can_access_mask = FILE_WRITE_DATA;
1027 } else {
1028 can_access_mask = FILE_READ_DATA;
1031 if (((can_access_mask & FILE_WRITE_DATA) && !CAN_WRITE(conn)) ||
1032 !can_access_file_data(conn,fname,psbuf,can_access_mask)) {
1033 can_access = False;
1037 * If we're returning a share violation, ensure we
1038 * cope with the braindead 1 second delay.
1040 if (!(oplock_request & INTERNAL_OPEN_ONLY) &&
1041 lp_defer_sharing_violations()) {
1042 struct timeval timeout;
1043 struct deferred_open_record state;
1044 int timeout_usecs;
1046 /* this is a hack to speed up torture tests
1047 in 'make test' */
1048 timeout_usecs = lp_parm_int(SNUM(conn),
1049 "smbd","sharedelay",
1050 SHARING_VIOLATION_USEC_WAIT);
1052 /* This is a relative time, added to the
1053 absolute request_time value to get the
1054 absolute timeout time. Note that if this
1055 is the second or greater time we enter this
1056 codepath for this particular request mid
1057 then request_time is left as the absolute
1058 time of the *first* time this request mid
1059 was processed. This is what allows the
1060 request to eventually time out. */
1062 timeout = timeval_set(0, timeout_usecs);
1064 /* Nothing actually uses
1065 state.delayed_for_oplocks but it's handy to
1066 differentiate in debug messages between a
1067 30 second delay due to oplock break, and a
1068 1 second delay for share mode conflicts. */
1070 state.delayed_for_oplocks = False;
1071 state.id = id;
1072 state.failed = false;
1074 if ((req != NULL)
1075 && !request_timed_out(request_time,
1076 timeout)) {
1077 defer_open(lck, request_time, timeout,
1078 req, &state);
1082 if (can_access) {
1084 * We have detected a sharing violation here
1085 * so return the correct error code
1087 status = NT_STATUS_SHARING_VIOLATION;
1088 } else {
1089 status = NT_STATUS_ACCESS_DENIED;
1092 goto cleanup_destroy;
1096 * Normal error, for example EACCES
1098 cleanup_destroy:
1099 if (oplock_callback_id != 0) {
1100 destroy_onefs_callback_record(oplock_callback_id);
1102 cleanup:
1103 TALLOC_FREE(lck);
1104 return status;
1107 fsp->oplock_type = granted_oplock;
1109 if (oplock_callback_id != 0) {
1110 onefs_set_oplock_callback(oplock_callback_id, fsp);
1111 fsp_data->oplock_callback_id = oplock_callback_id;
1112 } else {
1113 SMB_ASSERT(fsp->oplock_type == NO_OPLOCK);
1116 if (!file_existed) {
1117 struct timespec old_write_time = get_mtimespec(psbuf);
1119 * Deal with the race condition where two smbd's detect the
1120 * file doesn't exist and do the create at the same time. One
1121 * of them will win and set a share mode, the other (ie. this
1122 * one) should check if the requested share mode for this
1123 * create is allowed.
1127 * Now the file exists and fsp is successfully opened,
1128 * fsp->dev and fsp->inode are valid and should replace the
1129 * dev=0,inode=0 from a non existent file. Spotted by
1130 * Nadav Danieli <nadavd@exanet.com>. JRA.
1133 id = fsp->file_id;
1135 lck = get_share_mode_lock(talloc_tos(), id,
1136 conn->connectpath,
1137 fname, &old_write_time);
1139 if (lck == NULL) {
1140 DEBUG(0, ("onefs_open_file_ntcreate: Could not get "
1141 "share mode lock for %s\n", fname));
1142 fd_close(fsp);
1143 return NT_STATUS_SHARING_VIOLATION;
1146 if (lck->delete_on_close) {
1147 status = NT_STATUS_DELETE_PENDING;
1150 if (!NT_STATUS_IS_OK(status)) {
1151 struct deferred_open_record state;
1153 fd_close(fsp);
1155 state.delayed_for_oplocks = False;
1156 state.id = id;
1158 /* Do it all over again immediately. In the second
1159 * round we will find that the file existed and handle
1160 * the DELETE_PENDING and FCB cases correctly. No need
1161 * to duplicate the code here. Essentially this is a
1162 * "goto top of this function", but don't tell
1163 * anybody... */
1165 if (req != NULL) {
1166 defer_open(lck, request_time, timeval_zero(),
1167 req, &state);
1169 TALLOC_FREE(lck);
1170 return status;
1174 * We exit this block with the share entry *locked*.....
1179 SMB_ASSERT(lck != NULL);
1181 /* Delete streams if create_disposition requires it */
1182 if (file_existed && clear_ads && !is_ntfs_stream_name(fname)) {
1183 status = delete_all_streams(conn, fname);
1184 if (!NT_STATUS_IS_OK(status)) {
1185 TALLOC_FREE(lck);
1186 fd_close(fsp);
1187 return status;
1191 /* note that we ignore failure for the following. It is
1192 basically a hack for NFS, and NFS will never set one of
1193 these only read them. Nobody but Samba can ever set a deny
1194 mode and we have already checked our more authoritative
1195 locking database for permission to set this deny mode. If
1196 the kernel refuses the operations then the kernel is wrong.
1197 note that GPFS supports it as well - jmcd */
1199 if (fsp->fh->fd != -1) {
1200 ret_flock = SMB_VFS_KERNEL_FLOCK(fsp, share_access);
1201 if(ret_flock == -1 ){
1203 TALLOC_FREE(lck);
1204 fd_close(fsp);
1205 return NT_STATUS_SHARING_VIOLATION;
1210 * At this point onwards, we can guarentee that the share entry
1211 * is locked, whether we created the file or not, and that the
1212 * deny mode is compatible with all current opens.
1215 /* Record the options we were opened with. */
1216 fsp->share_access = share_access;
1217 fsp->fh->private_options = create_options;
1219 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
1221 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
1223 if (file_existed) {
1224 /* stat opens on existing files don't get oplocks. */
1225 if (is_stat_open(open_access_mask)) {
1226 fsp->oplock_type = NO_OPLOCK;
1229 if (!(flags2 & O_TRUNC)) {
1230 info = FILE_WAS_OPENED;
1231 } else {
1232 info = FILE_WAS_OVERWRITTEN;
1234 } else {
1235 info = FILE_WAS_CREATED;
1238 if (pinfo) {
1239 *pinfo = info;
1243 * Setup the oplock info in both the shared memory and
1244 * file structs.
1247 if ((fsp->oplock_type != NO_OPLOCK) &&
1248 (fsp->oplock_type != FAKE_LEVEL_II_OPLOCK)) {
1249 if (!set_file_oplock(fsp, fsp->oplock_type)) {
1250 /* Could not get the kernel oplock */
1251 fsp->oplock_type = NO_OPLOCK;
1255 if (fsp->oplock_type == LEVEL_II_OPLOCK &&
1256 (!lp_level2_oplocks(SNUM(conn)) ||
1257 !(global_client_caps & CAP_LEVEL_II_OPLOCKS))) {
1259 DEBUG(5, ("Downgrading level2 oplock on open "
1260 "because level2 oplocks = off\n"));
1262 release_file_oplock(fsp);
1265 if (info == FILE_WAS_OVERWRITTEN || info == FILE_WAS_CREATED ||
1266 info == FILE_WAS_SUPERSEDED) {
1267 new_file_created = True;
1270 set_share_mode(lck, fsp, conn->server_info->utok.uid, 0,
1271 fsp->oplock_type);
1273 /* Handle strange delete on close create semantics. */
1274 if (create_options & FILE_DELETE_ON_CLOSE) {
1275 status = can_set_delete_on_close(fsp, True, new_dos_attributes);
1277 if (!NT_STATUS_IS_OK(status)) {
1278 /* Remember to delete the mode we just added. */
1279 del_share_mode(lck, fsp);
1280 TALLOC_FREE(lck);
1281 fd_close(fsp);
1282 return status;
1284 /* Note that here we set the *inital* delete on close flag,
1285 not the regular one. The magic gets handled in close. */
1286 fsp->initial_delete_on_close = True;
1290 * Take care of inherited ACLs on created files - if default ACL not
1291 * selected.
1292 * May be necessary depending on acl policies.
1294 if (!posix_open && !file_existed && !def_acl && !(VALID_STAT(*psbuf)
1295 && (psbuf->st_flags & SF_HASNTFSACL))) {
1297 int saved_errno = errno; /* We might get ENOSYS in the next
1298 * call.. */
1300 if (SMB_VFS_FCHMOD_ACL(fsp, unx_mode) == -1 &&
1301 errno == ENOSYS) {
1302 errno = saved_errno; /* Ignore ENOSYS */
1305 } else if (new_unx_mode) {
1307 int ret = -1;
1309 /* Attributes need changing. File already existed. */
1312 int saved_errno = errno; /* We might get ENOSYS in the
1313 * next call.. */
1314 ret = SMB_VFS_FCHMOD_ACL(fsp, new_unx_mode);
1316 if (ret == -1 && errno == ENOSYS) {
1317 errno = saved_errno; /* Ignore ENOSYS */
1318 } else {
1319 DEBUG(5, ("onefs_open_file_ntcreate: reset "
1320 "attributes of file %s to 0%o\n",
1321 fname, (unsigned int)new_unx_mode));
1322 ret = 0; /* Don't do the fchmod below. */
1326 if ((ret == -1) &&
1327 (SMB_VFS_FCHMOD(fsp, new_unx_mode) == -1))
1328 DEBUG(5, ("onefs_open_file_ntcreate: failed to reset "
1329 "attributes of file %s to 0%o\n",
1330 fname, (unsigned int)new_unx_mode));
1333 /* If this is a successful open, we must remove any deferred open
1334 * records. */
1335 if (req != NULL) {
1336 del_deferred_open_entry(lck, req->mid);
1338 TALLOC_FREE(lck);
1340 return NT_STATUS_OK;
1344 /****************************************************************************
1345 Open a directory from an NT SMB call.
1346 ****************************************************************************/
1347 static NTSTATUS onefs_open_directory(connection_struct *conn,
1348 struct smb_request *req,
1349 const char *fname,
1350 uint32 access_mask,
1351 uint32 share_access,
1352 uint32 create_disposition,
1353 uint32 create_options,
1354 uint32 file_attributes,
1355 struct security_descriptor *sd,
1356 files_struct **result,
1357 int *pinfo,
1358 SMB_STRUCT_STAT *psbuf)
1360 files_struct *fsp = NULL;
1361 struct share_mode_lock *lck = NULL;
1362 NTSTATUS status;
1363 struct timespec mtimespec;
1364 int info = 0;
1365 char *parent_dir;
1366 const char *dirname;
1367 bool posix_open = false;
1368 uint32 create_flags = 0;
1369 uint32 mode = lp_dir_mask(SNUM(conn));
1371 DEBUG(5, ("onefs_open_directory: opening directory %s, "
1372 "access_mask = 0x%x, "
1373 "share_access = 0x%x create_options = 0x%x, "
1374 "create_disposition = 0x%x, file_attributes = 0x%x\n",
1375 fname, (unsigned int)access_mask, (unsigned int)share_access,
1376 (unsigned int)create_options, (unsigned int)create_disposition,
1377 (unsigned int)file_attributes));
1379 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
1380 (conn->fs_capabilities & FILE_NAMED_STREAMS) &&
1381 is_ntfs_stream_name(fname)) {
1382 DEBUG(2, ("onefs_open_directory: %s is a stream name!\n", fname));
1383 return NT_STATUS_NOT_A_DIRECTORY;
1386 switch (create_disposition) {
1387 case FILE_OPEN:
1388 /* If directory exists open. If directory doesn't
1389 * exist error. */
1390 create_flags = 0;
1391 info = FILE_WAS_OPENED;
1392 break;
1393 case FILE_CREATE:
1394 /* If directory exists error. If directory doesn't
1395 * exist create. */
1396 create_flags = O_CREAT | O_EXCL;
1397 info = FILE_WAS_CREATED;
1398 break;
1399 case FILE_OPEN_IF:
1400 /* If directory exists open. If directory doesn't
1401 * exist create. */
1403 /* Note: in order to return whether the directory was
1404 * opened or created, we first try to open and then try
1405 * to create. */
1406 create_flags = 0;
1407 info = FILE_WAS_OPENED;
1408 break;
1409 case FILE_SUPERSEDE:
1410 case FILE_OVERWRITE:
1411 case FILE_OVERWRITE_IF:
1412 default:
1413 DEBUG(5, ("onefs_open_directory: invalid "
1414 "create_disposition 0x%x for directory %s\n",
1415 (unsigned int)create_disposition, fname));
1416 return NT_STATUS_INVALID_PARAMETER;
1420 * Check for write access to the share. Done in mkdir_internal() in
1421 * mainline samba.
1423 if (!CAN_WRITE(conn) && (create_flags & O_CREAT)) {
1424 return NT_STATUS_ACCESS_DENIED;
1427 /* Get parent dirname */
1428 if (!parent_dirname(talloc_tos(), fname, &parent_dir, &dirname)) {
1429 return NT_STATUS_NO_MEMORY;
1432 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
1433 posix_open = true;
1434 mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
1435 file_attributes = 0;
1436 } else {
1437 mode = unix_mode(conn, aDIR, fname, parent_dir);
1441 * The NONINDEXED and COMPRESSED bits seem to always be cleared on
1442 * directories, no matter if you specify that they should be set.
1444 file_attributes &=
1445 ~(FILE_ATTRIBUTE_NONINDEXED | FILE_ATTRIBUTE_COMPRESSED);
1447 status = file_new(req, conn, &fsp);
1448 if(!NT_STATUS_IS_OK(status)) {
1449 return status;
1453 * Actual open with retry magic to handle FILE_OPEN_IF which is
1454 * unique because the kernel won't tell us if the file was opened or
1455 * created.
1457 retry_open:
1458 fsp->fh->fd = onefs_sys_create_file(conn,
1460 fname,
1461 access_mask,
1462 access_mask,
1463 share_access,
1464 create_options,
1465 create_flags | O_DIRECTORY,
1466 mode,
1470 file_attributes,
1471 NULL);
1473 if (fsp->fh->fd == -1) {
1474 DEBUG(3, ("Error opening %s. Errno=%d (%s).\n", fname, errno,
1475 strerror(errno)));
1476 SMB_ASSERT(errno != EINPROGRESS);
1478 if (create_disposition == FILE_OPEN_IF) {
1479 if (errno == ENOENT) {
1480 /* Try again, creating it this time. */
1481 create_flags = O_CREAT | O_EXCL;
1482 info = FILE_WAS_CREATED;
1483 goto retry_open;
1484 } else if (errno == EEXIST) {
1485 /* Uggh. Try again again. */
1486 create_flags = 0;
1487 info = FILE_WAS_OPENED;
1488 goto retry_open;
1492 /* Error cases below: */
1493 file_free(req, fsp);
1495 if ((errno == ENOENT) && (create_disposition == FILE_OPEN)) {
1496 DEBUG(5,("onefs_open_directory: FILE_OPEN requested "
1497 "for directory %s and it doesn't "
1498 "exist.\n", fname ));
1499 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1500 } else if ((errno == EEXIST) &&
1501 (create_disposition == FILE_CREATE)) {
1502 DEBUG(5,("onefs_open_directory: FILE_CREATE "
1503 "requested for directory %s and it "
1504 "already exists.\n", fname ));
1505 return NT_STATUS_OBJECT_NAME_COLLISION;
1506 } else if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
1507 /* Catch sharing violations. */
1508 return NT_STATUS_SHARING_VIOLATION;
1511 return map_nt_error_from_unix(errno);
1514 if (info == FILE_WAS_CREATED) {
1516 /* Pulled from mkdir_internal() */
1517 if (SMB_VFS_LSTAT(conn, fname, psbuf) == -1) {
1518 DEBUG(2, ("Could not stat directory '%s' just "
1519 "created: %s\n",fname, strerror(errno)));
1520 return map_nt_error_from_unix(errno);
1523 if (!S_ISDIR(psbuf->st_mode)) {
1524 DEBUG(0, ("Directory just '%s' created is not a "
1525 "directory\n", fname));
1526 return NT_STATUS_ACCESS_DENIED;
1529 if (!posix_open) {
1531 * Check if high bits should have been set, then (if
1532 * bits are missing): add them. Consider bits
1533 * automagically set by UNIX, i.e. SGID bit from
1534 * parent dir.
1536 if (mode & ~(S_IRWXU|S_IRWXG|S_IRWXO) &&
1537 (mode & ~psbuf->st_mode)) {
1538 SMB_VFS_CHMOD(conn, fname, (psbuf->st_mode |
1539 (mode & ~psbuf->st_mode)));
1543 /* Change the owner if required. */
1544 if (lp_inherit_owner(SNUM(conn))) {
1545 change_dir_owner_to_parent(conn, parent_dir, fname,
1546 psbuf);
1549 notify_fname(conn, NOTIFY_ACTION_ADDED,
1550 FILE_NOTIFY_CHANGE_DIR_NAME, fname);
1553 /* Stat the fd for Samba bookkeeping. */
1554 if(SMB_VFS_FSTAT(fsp, psbuf) != 0) {
1555 fd_close(fsp);
1556 file_free(req, fsp);
1557 return map_nt_error_from_unix(errno);
1560 /* Setup the files_struct for it. */
1561 fsp->mode = psbuf->st_mode;
1562 fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf);
1563 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
1564 fsp->file_pid = req ? req->smbpid : 0;
1565 fsp->can_lock = False;
1566 fsp->can_read = False;
1567 fsp->can_write = False;
1569 fsp->share_access = share_access;
1570 fsp->fh->private_options = create_options;
1572 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
1574 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
1575 fsp->print_file = False;
1576 fsp->modified = False;
1577 fsp->oplock_type = NO_OPLOCK;
1578 fsp->sent_oplock_break = NO_BREAK_SENT;
1579 fsp->is_directory = True;
1580 fsp->posix_open = posix_open;
1582 string_set(&fsp->fsp_name,fname);
1584 mtimespec = get_mtimespec(psbuf);
1587 * Still set the samba share mode lock for correct delete-on-close
1588 * semantics and to make smbstatus more useful.
1590 lck = get_share_mode_lock(talloc_tos(), fsp->file_id,
1591 conn->connectpath,
1592 fname, &mtimespec);
1594 if (lck == NULL) {
1595 DEBUG(0, ("onefs_open_directory: Could not get share mode "
1596 "lock for %s\n", fname));
1597 fd_close(fsp);
1598 file_free(req, fsp);
1599 return NT_STATUS_SHARING_VIOLATION;
1602 if (lck->delete_on_close) {
1603 TALLOC_FREE(lck);
1604 fd_close(fsp);
1605 file_free(req, fsp);
1606 return NT_STATUS_DELETE_PENDING;
1609 set_share_mode(lck, fsp, conn->server_info->utok.uid, 0, NO_OPLOCK);
1612 * For directories the delete on close bit at open time seems
1613 * always to be honored on close... See test 19 in Samba4 BASE-DELETE.
1615 if (create_options & FILE_DELETE_ON_CLOSE) {
1616 status = can_set_delete_on_close(fsp, True, 0);
1617 if (!NT_STATUS_IS_OK(status) &&
1618 !NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
1619 TALLOC_FREE(lck);
1620 fd_close(fsp);
1621 file_free(req, fsp);
1622 return status;
1625 if (NT_STATUS_IS_OK(status)) {
1626 /* Note that here we set the *inital* delete on close flag,
1627 not the regular one. The magic gets handled in close. */
1628 fsp->initial_delete_on_close = True;
1632 TALLOC_FREE(lck);
1634 if (pinfo) {
1635 *pinfo = info;
1638 *result = fsp;
1639 return NT_STATUS_OK;
1643 * Wrapper around onefs_open_file_ntcreate and onefs_open_directory.
1645 static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
1646 struct smb_request *req,
1647 const char *fname,
1648 uint32_t access_mask,
1649 uint32_t share_access,
1650 uint32_t create_disposition,
1651 uint32_t create_options,
1652 uint32_t file_attributes,
1653 uint32_t oplock_request,
1654 uint64_t allocation_size,
1655 struct security_descriptor *sd,
1656 struct ea_list *ea_list,
1657 files_struct **result,
1658 int *pinfo,
1659 struct onefs_fsp_data *fsp_data,
1660 SMB_STRUCT_STAT *psbuf)
1662 SMB_STRUCT_STAT sbuf;
1663 int info = FILE_WAS_OPENED;
1664 files_struct *base_fsp = NULL;
1665 files_struct *fsp = NULL;
1666 NTSTATUS status;
1668 DEBUG(10,("onefs_create_file_unixpath: access_mask = 0x%x "
1669 "file_attributes = 0x%x, share_access = 0x%x, "
1670 "create_disposition = 0x%x create_options = 0x%x "
1671 "oplock_request = 0x%x ea_list = 0x%p, sd = 0x%p, "
1672 "fname = %s\n",
1673 (unsigned int)access_mask,
1674 (unsigned int)file_attributes,
1675 (unsigned int)share_access,
1676 (unsigned int)create_disposition,
1677 (unsigned int)create_options,
1678 (unsigned int)oplock_request,
1679 ea_list, sd, fname));
1681 if (create_options & FILE_OPEN_BY_FILE_ID) {
1682 status = NT_STATUS_NOT_SUPPORTED;
1683 goto fail;
1686 if (create_options & NTCREATEX_OPTIONS_INVALID_PARAM_MASK) {
1687 status = NT_STATUS_INVALID_PARAMETER;
1688 goto fail;
1691 if (req == NULL) {
1692 SMB_ASSERT((oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK) ==
1693 NO_OPLOCK);
1694 oplock_request |= INTERNAL_OPEN_ONLY;
1697 if (psbuf != NULL) {
1698 sbuf = *psbuf;
1700 else {
1701 if (SMB_VFS_STAT(conn, fname, &sbuf) == -1) {
1702 SET_STAT_INVALID(sbuf);
1706 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
1707 && (access_mask & DELETE_ACCESS)
1708 && !is_ntfs_stream_name(fname)) {
1710 * We can't open a file with DELETE access if any of the
1711 * streams is open without FILE_SHARE_DELETE
1713 status = open_streams_for_delete(conn, fname);
1715 if (!NT_STATUS_IS_OK(status)) {
1716 goto fail;
1720 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
1721 && is_ntfs_stream_name(fname)) {
1722 char *base;
1723 uint32 base_create_disposition;
1725 if (create_options & FILE_DIRECTORY_FILE) {
1726 status = NT_STATUS_NOT_A_DIRECTORY;
1727 goto fail;
1730 status = onefs_split_ntfs_stream_name(talloc_tos(), fname,
1731 &base, NULL);
1732 if (!NT_STATUS_IS_OK(status)) {
1733 DEBUG(10, ("onefs_create_file_unixpath: "
1734 "split_ntfs_stream_name failed: %s\n",
1735 nt_errstr(status)));
1736 goto fail;
1739 SMB_ASSERT(!is_ntfs_stream_name(base)); /* paranoia.. */
1741 switch (create_disposition) {
1742 case FILE_OPEN:
1743 base_create_disposition = FILE_OPEN;
1744 break;
1745 default:
1746 base_create_disposition = FILE_OPEN_IF;
1747 break;
1750 status = onefs_create_file_unixpath(
1751 conn, /* conn */
1752 NULL, /* req */
1753 base, /* fname */
1754 SYNCHRONIZE_ACCESS, /* access_mask */
1755 (FILE_SHARE_READ |
1756 FILE_SHARE_WRITE |
1757 FILE_SHARE_DELETE), /* share_access */
1758 base_create_disposition, /* create_disposition*/
1759 0, /* create_options */
1760 file_attributes, /* file_attributes */
1761 NO_OPLOCK, /* oplock_request */
1762 0, /* allocation_size */
1763 NULL, /* sd */
1764 NULL, /* ea_list */
1765 &base_fsp, /* result */
1766 NULL, /* pinfo */
1767 NULL, /* fsp_data */
1768 NULL); /* psbuf */
1770 if (!NT_STATUS_IS_OK(status)) {
1771 DEBUG(10, ("onefs_create_file_unixpath for base %s "
1772 "failed: %s\n", base, nt_errstr(status)));
1773 goto fail;
1777 /* Covert generic bits in the security descriptor. */
1778 if (sd != NULL) {
1779 security_acl_map_generic(sd->dacl, &file_generic_mapping);
1780 security_acl_map_generic(sd->sacl, &file_generic_mapping);
1784 * If it's a request for a directory open, deal with it separately.
1787 if (create_options & FILE_DIRECTORY_FILE) {
1789 if (create_options & FILE_NON_DIRECTORY_FILE) {
1790 status = NT_STATUS_INVALID_PARAMETER;
1791 goto fail;
1794 /* Can't open a temp directory. IFS kit test. */
1795 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
1796 (file_attributes & FILE_ATTRIBUTE_TEMPORARY)) {
1797 status = NT_STATUS_INVALID_PARAMETER;
1798 goto fail;
1802 * We will get a create directory here if the Win32
1803 * app specified a security descriptor in the
1804 * CreateDirectory() call.
1807 status = onefs_open_directory(
1808 conn, /* conn */
1809 req, /* req */
1810 fname, /* fname */
1811 access_mask, /* access_mask */
1812 share_access, /* share_access */
1813 create_disposition, /* create_disposition*/
1814 create_options, /* create_options */
1815 file_attributes, /* file_attributes */
1816 sd, /* sd */
1817 &fsp, /* result */
1818 &info, /* pinfo */
1819 &sbuf); /* psbuf */
1820 } else {
1823 * Ordinary file case.
1826 status = file_new(req, conn, &fsp);
1827 if(!NT_STATUS_IS_OK(status)) {
1828 goto fail;
1832 * We're opening the stream element of a base_fsp
1833 * we already opened. Set up the base_fsp pointer.
1835 if (base_fsp) {
1836 fsp->base_fsp = base_fsp;
1839 status = onefs_open_file_ntcreate(
1840 conn, /* conn */
1841 req, /* req */
1842 fname, /* fname */
1843 access_mask, /* access_mask */
1844 share_access, /* share_access */
1845 create_disposition, /* create_disposition*/
1846 create_options, /* create_options */
1847 file_attributes, /* file_attributes */
1848 oplock_request, /* oplock_request */
1849 sd, /* sd */
1850 fsp, /* result */
1851 &info, /* pinfo */
1852 fsp_data, /* fsp_data */
1853 &sbuf); /* psbuf */
1855 if(!NT_STATUS_IS_OK(status)) {
1856 file_free(req, fsp);
1857 fsp = NULL;
1860 if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
1862 /* A stream open never opens a directory */
1864 if (base_fsp) {
1865 status = NT_STATUS_FILE_IS_A_DIRECTORY;
1866 goto fail;
1870 * Fail the open if it was explicitly a non-directory
1871 * file.
1874 if (create_options & FILE_NON_DIRECTORY_FILE) {
1875 status = NT_STATUS_FILE_IS_A_DIRECTORY;
1876 goto fail;
1879 create_options |= FILE_DIRECTORY_FILE;
1881 status = onefs_open_directory(
1882 conn, /* conn */
1883 req, /* req */
1884 fname, /* fname */
1885 access_mask, /* access_mask */
1886 share_access, /* share_access */
1887 create_disposition, /* create_disposition*/
1888 create_options, /* create_options */
1889 file_attributes, /* file_attributes */
1890 sd, /* sd */
1891 &fsp, /* result */
1892 &info, /* pinfo */
1893 &sbuf); /* psbuf */
1897 if (!NT_STATUS_IS_OK(status)) {
1898 goto fail;
1901 fsp->base_fsp = base_fsp;
1903 SMB_ASSERT(fsp);
1905 if ((ea_list != NULL) && (info == FILE_WAS_CREATED)) {
1906 status = set_ea(conn, fsp, fname, ea_list);
1907 if (!NT_STATUS_IS_OK(status)) {
1908 goto fail;
1912 if (!fsp->is_directory && S_ISDIR(sbuf.st_mode)) {
1913 status = NT_STATUS_ACCESS_DENIED;
1914 goto fail;
1917 /* Save the requested allocation size. */
1918 if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
1919 if (allocation_size
1920 && (allocation_size > sbuf.st_size)) {
1921 fsp->initial_allocation_size = smb_roundup(
1922 fsp->conn, allocation_size);
1923 if (fsp->is_directory) {
1924 /* Can't set allocation size on a directory. */
1925 status = NT_STATUS_ACCESS_DENIED;
1926 goto fail;
1928 if (vfs_allocate_file_space(
1929 fsp, fsp->initial_allocation_size) == -1) {
1930 status = NT_STATUS_DISK_FULL;
1931 goto fail;
1933 } else {
1934 fsp->initial_allocation_size = smb_roundup(
1935 fsp->conn, (uint64_t)sbuf.st_size);
1939 DEBUG(10, ("onefs_create_file_unixpath: info=%d\n", info));
1941 *result = fsp;
1942 if (pinfo != NULL) {
1943 *pinfo = info;
1945 if (psbuf != NULL) {
1946 if ((fsp->fh == NULL) || (fsp->fh->fd == -1)) {
1947 *psbuf = sbuf;
1949 else {
1950 SMB_VFS_FSTAT(fsp, psbuf);
1953 return NT_STATUS_OK;
1955 fail:
1956 DEBUG(10, ("onefs_create_file_unixpath: %s\n", nt_errstr(status)));
1958 if (fsp != NULL) {
1959 if (base_fsp && fsp->base_fsp == base_fsp) {
1961 * The close_file below will close
1962 * fsp->base_fsp.
1964 base_fsp = NULL;
1966 close_file(req, fsp, ERROR_CLOSE);
1967 fsp = NULL;
1969 if (base_fsp != NULL) {
1970 close_file(req, base_fsp, ERROR_CLOSE);
1971 base_fsp = NULL;
1973 return status;
1976 static void destroy_onefs_fsp_data(void *p_data)
1978 struct onefs_fsp_data *fsp_data = (struct onefs_fsp_data *)p_data;
1980 destroy_onefs_callback_record(fsp_data->oplock_callback_id);
1984 * SMB_VFS_CREATE_FILE interface to onefs.
1986 NTSTATUS onefs_create_file(vfs_handle_struct *handle,
1987 struct smb_request *req,
1988 uint16_t root_dir_fid,
1989 const char *fname,
1990 uint32_t create_file_flags,
1991 uint32_t access_mask,
1992 uint32_t share_access,
1993 uint32_t create_disposition,
1994 uint32_t create_options,
1995 uint32_t file_attributes,
1996 uint32_t oplock_request,
1997 uint64_t allocation_size,
1998 struct security_descriptor *sd,
1999 struct ea_list *ea_list,
2000 files_struct **result,
2001 int *pinfo,
2002 SMB_STRUCT_STAT *psbuf)
2004 connection_struct *conn = handle->conn;
2005 struct case_semantics_state *case_state = NULL;
2006 struct onefs_fsp_data fsp_data = {};
2007 SMB_STRUCT_STAT sbuf;
2008 int info = FILE_WAS_OPENED;
2009 files_struct *fsp = NULL;
2010 NTSTATUS status;
2012 DEBUG(10,("onefs_create_file: access_mask = 0x%x "
2013 "file_attributes = 0x%x, share_access = 0x%x, "
2014 "create_disposition = 0x%x create_options = 0x%x "
2015 "oplock_request = 0x%x "
2016 "root_dir_fid = 0x%x, ea_list = 0x%p, sd = 0x%p, "
2017 "create_file_flags = 0x%x, fname = %s\n",
2018 (unsigned int)access_mask,
2019 (unsigned int)file_attributes,
2020 (unsigned int)share_access,
2021 (unsigned int)create_disposition,
2022 (unsigned int)create_options,
2023 (unsigned int)oplock_request,
2024 (unsigned int)root_dir_fid,
2025 ea_list, sd, create_file_flags, fname));
2027 /* Get the file name if root_dir_fid was specified. */
2028 if (root_dir_fid != 0) {
2029 char *new_fname;
2031 status = get_relative_fid_filename(conn, req, root_dir_fid,
2032 fname, &new_fname);
2033 if (!NT_STATUS_IS_OK(status)) {
2034 goto fail;
2037 fname = new_fname;
2040 /* Resolve the file name if this was a DFS pathname. */
2041 if ((req != NULL) && (req->flags2 & FLAGS2_DFS_PATHNAMES)) {
2042 char *resolved_fname;
2044 status = resolve_dfspath(talloc_tos(), conn, true, fname,
2045 &resolved_fname);
2047 if (!NT_STATUS_IS_OK(status)) {
2049 * For PATH_NOT_COVERED we had
2050 * reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
2051 * ERRSRV, ERRbadpath);
2052 * Need to fix in callers
2054 goto fail;
2056 fname = resolved_fname;
2059 /* Check if POSIX semantics are wanted. */
2060 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
2061 case_state = set_posix_case_semantics(talloc_tos(), conn);
2064 /* Convert dos path to unix path if it hasn't already been done. */
2065 if (create_file_flags & CFF_DOS_PATH) {
2066 char *converted_fname;
2068 SET_STAT_INVALID(sbuf);
2070 status = unix_convert(talloc_tos(), conn, fname, False,
2071 &converted_fname, NULL, &sbuf);
2072 if (!NT_STATUS_IS_OK(status)) {
2073 goto fail;
2075 fname = converted_fname;
2076 } else {
2077 if (psbuf != NULL) {
2078 sbuf = *psbuf;
2079 } else {
2080 if (SMB_VFS_STAT(conn, fname, &sbuf) == -1) {
2081 SET_STAT_INVALID(sbuf);
2087 TALLOC_FREE(case_state);
2089 /* All file access must go through check_name() */
2090 status = check_name(conn, fname);
2091 if (!NT_STATUS_IS_OK(status)) {
2092 goto fail;
2095 status = onefs_create_file_unixpath(
2096 conn, /* conn */
2097 req, /* req */
2098 fname, /* fname */
2099 access_mask, /* access_mask */
2100 share_access, /* share_access */
2101 create_disposition, /* create_disposition*/
2102 create_options, /* create_options */
2103 file_attributes, /* file_attributes */
2104 oplock_request, /* oplock_request */
2105 allocation_size, /* allocation_size */
2106 sd, /* sd */
2107 ea_list, /* ea_list */
2108 &fsp, /* result */
2109 &info, /* pinfo */
2110 &fsp_data, /* fsp_data */
2111 &sbuf); /* psbuf */
2113 if (!NT_STATUS_IS_OK(status)) {
2114 goto fail;
2117 DEBUG(10, ("onefs_create_file: info=%d\n", info));
2120 * Setup private onefs_fsp_data. Currently the private data struct is
2121 * only used to store the oplock_callback_id so that when the file is
2122 * closed, the onefs_callback_record can be properly cleaned up in the
2123 * oplock_onefs sub-system.
2125 if (fsp) {
2126 struct onefs_fsp_data *fsp_data_tmp = NULL;
2127 fsp_data_tmp = (struct onefs_fsp_data *)
2128 VFS_ADD_FSP_EXTENSION(handle, fsp, struct onefs_fsp_data,
2129 &destroy_onefs_fsp_data);
2131 if (fsp_data_tmp == NULL) {
2132 status = NT_STATUS_NO_MEMORY;
2133 goto fail;
2136 *fsp_data_tmp = fsp_data;
2139 *result = fsp;
2140 if (pinfo != NULL) {
2141 *pinfo = info;
2143 if (psbuf != NULL) {
2144 *psbuf = sbuf;
2146 return NT_STATUS_OK;
2148 fail:
2149 DEBUG(10, ("onefs_create_file: %s\n", nt_errstr(status)));
2151 if (fsp != NULL) {
2152 close_file(req, fsp, ERROR_CLOSE);
2153 fsp = NULL;
2155 return status;