s4: Better way to call "dom_sid_to_rid" from ldap.py
[Samba/aatanasov.git] / source3 / modules / onefs_open.c
blob31f27e907ac5d37d355b8b7996d98274c089bf99
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 struct smb_filename *smb_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);
63 /****************************************************************************
64 Open a file.
65 ****************************************************************************/
67 static NTSTATUS onefs_open_file(files_struct *fsp,
68 connection_struct *conn,
69 struct smb_request *req,
70 const char *parent_dir,
71 struct smb_filename *smb_fname,
72 int flags,
73 mode_t unx_mode,
74 uint32 access_mask,
75 uint32 open_access_mask,
76 int oplock_request,
77 uint64 id,
78 uint32 share_access,
79 uint32 create_options,
80 uint32_t new_dos_attributes,
81 struct security_descriptor *sd,
82 int *granted_oplock)
84 struct smb_filename *smb_fname_onefs = NULL;
85 NTSTATUS status = NT_STATUS_OK;
86 int accmode = (flags & O_ACCMODE);
87 int local_flags = flags;
88 bool file_existed = VALID_STAT(smb_fname->st);
89 const char *wild;
90 int base_fd = -1;
92 fsp->fh->fd = -1;
93 errno = EPERM;
95 /* Check permissions */
98 * This code was changed after seeing a client open request
99 * containing the open mode of (DENY_WRITE/read-only) with
100 * the 'create if not exist' bit set. The previous code
101 * would fail to open the file read only on a read-only share
102 * as it was checking the flags parameter directly against O_RDONLY,
103 * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
104 * JRA.
107 if (!CAN_WRITE(conn)) {
108 /* It's a read-only share - fail if we wanted to write. */
109 if(accmode != O_RDONLY) {
110 DEBUG(3, ("Permission denied opening %s\n",
111 smb_fname_str_dbg(smb_fname)));
112 return NT_STATUS_ACCESS_DENIED;
113 } else if(flags & O_CREAT) {
114 /* We don't want to write - but we must make sure that
115 O_CREAT doesn't create the file if we have write
116 access into the directory.
118 flags &= ~O_CREAT;
119 local_flags &= ~O_CREAT;
124 * This little piece of insanity is inspired by the
125 * fact that an NT client can open a file for O_RDONLY,
126 * but set the create disposition to FILE_EXISTS_TRUNCATE.
127 * If the client *can* write to the file, then it expects to
128 * truncate the file, even though it is opening for readonly.
129 * Quicken uses this stupid trick in backup file creation...
130 * Thanks *greatly* to "David W. Chapman Jr." <dwcjr@inethouston.net>
131 * for helping track this one down. It didn't bite us in 2.0.x
132 * as we always opened files read-write in that release. JRA.
135 if ((accmode == O_RDONLY) && ((flags & O_TRUNC) == O_TRUNC)) {
136 DEBUG(10,("onefs_open_file: truncate requested on read-only "
137 "open for file %s\n", smb_fname_str_dbg(smb_fname)));
138 local_flags = (flags & ~O_ACCMODE)|O_RDWR;
141 #if defined(O_NONBLOCK) && defined(S_ISFIFO)
143 * We would block on opening a FIFO with no one else on the
144 * other end. Do what we used to do and add O_NONBLOCK to the
145 * open flags. JRA.
148 if (file_existed && S_ISFIFO(smb_fname->st.st_ex_mode)) {
149 local_flags |= O_NONBLOCK;
151 #endif
153 /* Don't create files with Microsoft wildcard characters. */
154 if (fsp->base_fsp) {
156 * wildcard characters are allowed in stream names
157 * only test the basefilename
159 wild = fsp->base_fsp->fsp_name->base_name;
160 } else {
161 wild = smb_fname->base_name;
163 if ((local_flags & O_CREAT) && !file_existed &&
164 ms_has_wild(wild)) {
166 * XXX: may need to remvoe this return...
168 * We dont think this check needs to exist. All it does is
169 * block creating files with Microsoft wildcards, which is
170 * fine if the creation originated from NFS or locally and
171 * then was copied via Samba.
173 DEBUG(1, ("onefs_open_file: creating file with wildcard: %s\n",
174 smb_fname_str_dbg(smb_fname)));
175 return NT_STATUS_OBJECT_NAME_INVALID;
178 /* Actually do the open */
180 #ifdef O_NOFOLLOW
182 * Never follow symlinks on a POSIX client. The
183 * client should be doing this.
186 if (fsp->posix_open || !lp_symlinks(SNUM(conn))) {
187 flags |= O_NOFOLLOW;
189 #endif
190 /* Setup a onefs-style smb_fname struct. */
191 status = onefs_stream_prep_smb_fname(talloc_tos(), smb_fname,
192 &smb_fname_onefs);
193 if (!NT_STATUS_IS_OK(status)) {
194 return status;
197 /* If it's a stream pass in the base_fd */
198 if ((conn->fs_capabilities & FILE_NAMED_STREAMS) &&
199 is_ntfs_stream_smb_fname(smb_fname_onefs)) {
200 SMB_ASSERT(fsp->base_fsp);
202 DEBUG(10, ("Opening a stream: base=%s(%d), stream=%s\n",
203 smb_fname_onefs->base_name, fsp->base_fsp->fh->fd,
204 smb_fname_onefs->stream_name));
206 base_fd = fsp->base_fsp->fh->fd;
209 fsp->fh->fd = onefs_sys_create_file(conn,
210 base_fd,
211 smb_fname_onefs->stream_name != NULL ?
212 smb_fname_onefs->stream_name :
213 smb_fname_onefs->base_name,
214 access_mask,
215 open_access_mask,
216 share_access,
217 create_options,
218 flags,
219 unx_mode,
220 oplock_request,
223 new_dos_attributes,
224 granted_oplock);
225 TALLOC_FREE(smb_fname_onefs);
227 if (fsp->fh->fd == -1) {
228 if (errno == EMFILE) {
229 static time_t last_warned = 0L;
231 if (time((time_t *) NULL) > last_warned) {
232 DEBUG(0, ("Too many open files, unable "
233 "to open more! smbd's max "
234 "open files = %d, also check "
235 "sysctl kern.maxfiles and "
236 "sysctl kern.maxfilesperproc\n",
237 lp_max_open_files()));
238 last_warned = time((time_t *) NULL);
242 status = map_nt_error_from_unix(errno);
243 DEBUG(3, ("Error opening file %s (%s) (local_flags=%d) "
244 "(flags=%d)\n", smb_fname_str_dbg(smb_fname),
245 strerror(errno), local_flags, flags));
246 return status;
249 if ((local_flags & O_CREAT) && !file_existed) {
251 /* Inherit the ACL if required */
252 if (lp_inherit_perms(SNUM(conn))) {
253 inherit_access_posix_acl(conn, parent_dir,
254 smb_fname->base_name, unx_mode);
257 /* Change the owner if required. */
258 if (lp_inherit_owner(SNUM(conn))) {
259 change_file_owner_to_parent(conn, parent_dir,
260 fsp);
263 notify_fname(conn, NOTIFY_ACTION_ADDED,
264 FILE_NOTIFY_CHANGE_FILE_NAME, smb_fname->base_name);
267 if (!file_existed) {
268 int ret;
270 if (fsp->fh->fd == -1) {
271 ret = SMB_VFS_STAT(conn, smb_fname);
272 } else {
273 ret = SMB_VFS_FSTAT(fsp, &smb_fname->st);
274 /* If we have an fd, this stat should succeed. */
275 if (ret == -1) {
276 DEBUG(0, ("Error doing fstat on open file %s "
277 "(%s)\n",
278 smb_fname_str_dbg(smb_fname),
279 strerror(errno) ));
283 /* For a non-io open, this stat failing means file not found. JRA */
284 if (ret == -1) {
285 status = map_nt_error_from_unix(errno);
286 fd_close(fsp);
287 return status;
292 * POSIX allows read-only opens of directories. We don't
293 * want to do this (we use a different code path for this)
294 * so catch a directory open and return an EISDIR. JRA.
297 if(S_ISDIR(smb_fname->st.st_ex_mode)) {
298 fd_close(fsp);
299 errno = EISDIR;
300 return NT_STATUS_FILE_IS_A_DIRECTORY;
303 fsp->mode = smb_fname->st.st_ex_mode;
304 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
305 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
306 fsp->file_pid = req ? req->smbpid : 0;
307 fsp->can_lock = True;
308 fsp->can_read = (access_mask & (FILE_READ_DATA)) ? True : False;
309 if (!CAN_WRITE(conn)) {
310 fsp->can_write = False;
311 } else {
312 fsp->can_write = (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ?
313 True : False;
315 fsp->print_file = False;
316 fsp->modified = False;
317 fsp->sent_oplock_break = NO_BREAK_SENT;
318 fsp->is_directory = False;
319 if (conn->aio_write_behind_list &&
320 is_in_path(smb_fname->base_name, conn->aio_write_behind_list,
321 conn->case_sensitive)) {
322 fsp->aio_write_behind = True;
325 status = fsp_set_smb_fname(fsp, smb_fname);
326 if (!NT_STATUS_IS_OK(status)) {
327 fd_close(fsp);
328 errno = map_errno_from_nt_status(status);
329 return status;
332 fsp->wcp = NULL; /* Write cache pointer. */
334 DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
335 conn->server_info->unix_name,
336 smb_fname_str_dbg(smb_fname),
337 BOOLSTR(fsp->can_read), BOOLSTR(fsp->can_write),
338 conn->num_files_open));
340 errno = 0;
341 return NT_STATUS_OK;
344 /****************************************************************************
345 Handle the 1 second delay in returning a SHARING_VIOLATION error.
346 ****************************************************************************/
348 static void defer_open(struct share_mode_lock *lck,
349 struct timeval request_time,
350 struct timeval timeout,
351 struct smb_request *req,
352 struct deferred_open_record *state)
354 int i;
356 /* Paranoia check */
358 for (i=0; i<lck->num_share_modes; i++) {
359 struct share_mode_entry *e = &lck->share_modes[i];
361 if (!is_deferred_open_entry(e)) {
362 continue;
365 if (procid_is_me(&e->pid) && (e->op_mid == req->mid)) {
366 DEBUG(0, ("Trying to defer an already deferred "
367 "request: mid=%d, exiting\n", req->mid));
368 exit_server("attempt to defer a deferred request");
372 /* End paranoia check */
374 DEBUG(10,("defer_open_sharing_error: time [%u.%06u] adding deferred "
375 "open entry for mid %u\n",
376 (unsigned int)request_time.tv_sec,
377 (unsigned int)request_time.tv_usec,
378 (unsigned int)req->mid));
380 if (!push_deferred_smb_message(req, request_time, timeout,
381 (char *)state, sizeof(*state))) {
382 exit_server("push_deferred_smb_message failed");
384 add_deferred_open(lck, req->mid, request_time, state->id);
387 static void schedule_defer_open(struct share_mode_lock *lck,
388 struct timeval request_time,
389 struct smb_request *req)
391 struct deferred_open_record state;
393 /* This is a relative time, added to the absolute
394 request_time value to get the absolute timeout time.
395 Note that if this is the second or greater time we enter
396 this codepath for this particular request mid then
397 request_time is left as the absolute time of the *first*
398 time this request mid was processed. This is what allows
399 the request to eventually time out. */
401 struct timeval timeout;
403 /* Normally the smbd we asked should respond within
404 * OPLOCK_BREAK_TIMEOUT seconds regardless of whether
405 * the client did, give twice the timeout as a safety
406 * measure here in case the other smbd is stuck
407 * somewhere else. */
410 * On OneFS, the kernel will always send an oplock_revoked message
411 * before this timeout is hit.
413 timeout = timeval_set(OPLOCK_BREAK_TIMEOUT*10, 0);
415 /* Nothing actually uses state.delayed_for_oplocks
416 but it's handy to differentiate in debug messages
417 between a 30 second delay due to oplock break, and
418 a 1 second delay for share mode conflicts. */
420 state.delayed_for_oplocks = True;
421 state.failed = false;
422 state.id = lck->id;
424 if (!request_timed_out(request_time, timeout)) {
425 defer_open(lck, request_time, timeout, req, &state);
429 /****************************************************************************
430 Open a file with a share mode. Passed in an already created files_struct.
431 ****************************************************************************/
432 NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
433 struct smb_request *req,
434 struct smb_filename *smb_fname,
435 uint32 access_mask,
436 uint32 share_access,
437 uint32 create_disposition,
438 uint32 create_options,
439 uint32 new_dos_attributes,
440 int oplock_request,
441 struct security_descriptor *sd,
442 files_struct *fsp,
443 int *pinfo,
444 struct onefs_fsp_data *fsp_data)
446 int flags=0;
447 int flags2=0;
448 bool file_existed = VALID_STAT(smb_fname->st);
449 bool def_acl = False;
450 bool posix_open = False;
451 bool new_file_created = False;
452 bool clear_ads = False;
453 struct file_id id;
454 mode_t new_unx_mode = (mode_t)0;
455 mode_t unx_mode = (mode_t)0;
456 int info;
457 uint32 existing_dos_attributes = 0;
458 struct pending_message_list *pml = NULL;
459 struct timeval request_time = timeval_zero();
460 struct share_mode_lock *lck = NULL;
461 uint32 open_access_mask = access_mask;
462 NTSTATUS status;
463 int ret_flock;
464 char *parent_dir;
465 int granted_oplock;
466 uint64_t oplock_callback_id = 0;
467 uint32 createfile_attributes = 0;
469 ZERO_STRUCT(id);
471 if (conn->printer) {
473 * Printers are handled completely differently.
474 * Most of the passed parameters are ignored.
477 if (pinfo) {
478 *pinfo = FILE_WAS_CREATED;
481 DEBUG(10, ("onefs_open_file_ntcreate: printer open fname=%s\n",
482 smb_fname_str_dbg(smb_fname)));
484 return print_fsp_open(req, conn, smb_fname->base_name,
485 req->vuid, fsp, &smb_fname->st);
488 if (!parent_dirname(talloc_tos(), smb_fname->base_name, &parent_dir,
489 NULL)) {
490 return NT_STATUS_NO_MEMORY;
493 if (new_dos_attributes & FILE_FLAG_POSIX_SEMANTICS) {
494 posix_open = True;
495 unx_mode = (mode_t)(new_dos_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
496 new_dos_attributes = 0;
497 } else {
498 /* We add aARCH to this as this mode is only used if the file is
499 * created new. */
500 unx_mode = unix_mode(conn, new_dos_attributes | aARCH,
501 smb_fname, parent_dir);
504 DEBUG(10,("onefs_open_file_ntcreate: fname=%s, dos_attrs=0x%x "
505 "access_mask=0x%x share_access=0x%x "
506 "create_disposition = 0x%x create_options=0x%x "
507 "unix mode=0%o oplock_request=0x%x\n",
508 smb_fname_str_dbg(smb_fname), new_dos_attributes,
509 access_mask, share_access, create_disposition,
510 create_options, unx_mode, oplock_request));
513 * Any non-stat-only open has the potential to contend oplocks, which
514 * means to avoid blocking in the kernel (which is unacceptable), the
515 * open must be deferred. In order to defer opens, req must not be
516 * NULL. The known cases of calling with a NULL req:
518 * 1. Open the base file of a stream: Always done stat-only
520 * 2. open_file_fchmod(), which is called from 3 places:
521 * A. try_chown: Posix acls only. Never called on onefs.
522 * B. set_ea_dos_attributes: Can't be called from onefs, because
523 * SMB_VFS_SETXATTR return ENOSYS.
524 * C. file_set_dos_mode: This would only happen if the "dos
525 * filemode" smb.conf parameter is set to yes. We ship with
526 * it off, but if a customer were to turn it on it would be
527 * bad.
529 if (req == NULL && !is_stat_open(access_mask) &&
530 !is_ntfs_stream_smb_fname(smb_fname)) {
531 smb_panic("NULL req on a non-stat-open!");
534 if ((req == NULL) && ((oplock_request & INTERNAL_OPEN_ONLY) == 0)) {
535 DEBUG(0, ("No smb request but not an internal only open!\n"));
536 return NT_STATUS_INTERNAL_ERROR;
540 * Only non-internal opens can be deferred at all
543 if ((req != NULL)
544 && ((pml = get_open_deferred_message(req->mid)) != NULL)) {
545 struct deferred_open_record *state =
546 (struct deferred_open_record *)pml->private_data.data;
548 /* Remember the absolute time of the original
549 request with this mid. We'll use it later to
550 see if this has timed out. */
552 request_time = pml->request_time;
554 /* Remove the deferred open entry under lock. */
555 lck = get_share_mode_lock(talloc_tos(), state->id, NULL, NULL,
556 NULL);
557 if (lck == NULL) {
558 DEBUG(0, ("could not get share mode lock\n"));
559 } else {
560 del_deferred_open_entry(lck, req->mid);
561 TALLOC_FREE(lck);
564 /* Ensure we don't reprocess this message. */
565 remove_deferred_open_smb_message(req->mid);
568 * When receiving a semlock_async_failure message, the
569 * deferred open will be marked as "failed". Returning
570 * INTERNAL_ERROR.
572 if (state->failed) {
573 DEBUG(0, ("onefs_open_file_ntcreate: "
574 "semlock_async_failure detected!\n"));
575 return NT_STATUS_INTERNAL_ERROR;
579 status = check_name(conn, smb_fname->base_name);
580 if (!NT_STATUS_IS_OK(status)) {
581 return status;
584 if (!posix_open) {
585 new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
586 if (file_existed) {
587 existing_dos_attributes = dos_mode(conn, smb_fname);
591 /* Setup dos_attributes to be set by ifs_createfile */
592 if (lp_store_dos_attributes(SNUM(conn))) {
593 createfile_attributes = (new_dos_attributes | aARCH) &
594 ~(FILE_ATTRIBUTE_NONINDEXED | FILE_ATTRIBUTE_COMPRESSED);
597 /* Ignore oplock requests if oplocks are disabled. */
598 if (!lp_oplocks(SNUM(conn)) || global_client_failed_oplock_break ||
599 IS_VETO_OPLOCK_PATH(conn, smb_fname->base_name)) {
600 /* Mask off everything except the private Samba bits. */
601 oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
604 /* this is for OS/2 long file names - say we don't support them */
605 if (!lp_posix_pathnames() && strstr(smb_fname->base_name,".+,;=[].")) {
606 /* OS/2 Workplace shell fix may be main code stream in a later
607 * release. */
608 DEBUG(5,("onefs_open_file_ntcreate: OS/2 long filenames are "
609 "not supported.\n"));
610 if (use_nt_status()) {
611 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
613 return NT_STATUS_DOS(ERRDOS, ERRcannotopen);
616 switch( create_disposition ) {
618 * Currently we're using FILE_SUPERSEDE as the same as
619 * FILE_OVERWRITE_IF but they really are
620 * different. FILE_SUPERSEDE deletes an existing file
621 * (requiring delete access) then recreates it.
623 case FILE_SUPERSEDE:
625 * @todo: Clear all file attributes?
626 * http://www.osronline.com/article.cfm?article=302
627 * create if not exist, trunc if exist
629 * If file exists replace/overwrite. If file doesn't
630 * exist create.
632 flags2 |= (O_CREAT | O_TRUNC);
633 clear_ads = true;
634 break;
636 case FILE_OVERWRITE_IF:
637 /* If file exists replace/overwrite. If file doesn't
638 * exist create. */
639 flags2 |= (O_CREAT | O_TRUNC);
640 clear_ads = true;
641 break;
643 case FILE_OPEN:
644 /* If file exists open. If file doesn't exist error. */
645 if (!file_existed) {
646 DEBUG(5,("onefs_open_file_ntcreate: FILE_OPEN "
647 "requested for file %s and file "
648 "doesn't exist.\n",
649 smb_fname_str_dbg(smb_fname)));
650 errno = ENOENT;
651 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
653 break;
655 case FILE_OVERWRITE:
656 /* If file exists overwrite. If file doesn't exist
657 * error. */
658 if (!file_existed) {
659 DEBUG(5, ("onefs_open_file_ntcreate: "
660 "FILE_OVERWRITE requested for file "
661 "%s and file doesn't exist.\n",
662 smb_fname_str_dbg(smb_fname)));
663 errno = ENOENT;
664 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
666 flags2 |= O_TRUNC;
667 clear_ads = true;
668 break;
670 case FILE_CREATE:
671 /* If file exists error. If file doesn't exist
672 * create. */
673 if (file_existed) {
674 DEBUG(5, ("onefs_open_file_ntcreate: "
675 "FILE_CREATE requested for file %s "
676 "and file already exists.\n",
677 smb_fname_str_dbg(smb_fname)));
678 if (S_ISDIR(smb_fname->st.st_ex_mode)) {
679 errno = EISDIR;
680 } else {
681 errno = EEXIST;
683 return map_nt_error_from_unix(errno);
685 flags2 |= (O_CREAT|O_EXCL);
686 break;
688 case FILE_OPEN_IF:
689 /* If file exists open. If file doesn't exist
690 * create. */
691 flags2 |= O_CREAT;
692 break;
694 default:
695 return NT_STATUS_INVALID_PARAMETER;
698 /* Match attributes on file exists and overwrite. */
699 if (!posix_open && file_existed &&
700 ((create_disposition == FILE_OVERWRITE) ||
701 (create_disposition == FILE_OVERWRITE_IF))) {
702 if (!open_match_attributes(conn, existing_dos_attributes,
703 new_dos_attributes,
704 smb_fname->st.st_ex_mode,
705 unx_mode, &new_unx_mode)) {
706 DEBUG(5, ("onefs_open_file_ntcreate: attributes "
707 "missmatch for file %s (%x %x) (0%o, 0%o)\n",
708 smb_fname_str_dbg(smb_fname),
709 existing_dos_attributes,
710 new_dos_attributes,
711 (unsigned int)smb_fname->st.st_ex_mode,
712 (unsigned int)unx_mode ));
713 errno = EACCES;
714 return NT_STATUS_ACCESS_DENIED;
719 * OneFS understands MAXIMUM_ALLOWED_ACCESS, so only hack the
720 * access_mask, but leave the MAA for the actual open in
721 * open_access_mask.
723 open_access_mask = access_mask;
724 if (open_access_mask & MAXIMUM_ALLOWED_ACCESS) {
725 access_mask |= FILE_GENERIC_ALL;
728 /* Convert GENERIC bits to specific bits. */
729 se_map_generic(&access_mask, &file_generic_mapping);
730 se_map_generic(&open_access_mask, &file_generic_mapping);
732 if ((flags2 & O_TRUNC) || (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE)) {
733 /* This will cause oplock breaks. */
734 open_access_mask |= FILE_WRITE_DATA;
737 DEBUG(10, ("onefs_open_file_ntcreate: fname=%s, after mapping "
738 "open_access_mask=%#x, access_mask=0x%x\n",
739 smb_fname_str_dbg(smb_fname), open_access_mask,
740 access_mask));
743 * Note that we ignore the append flag as append does not
744 * mean the same thing under DOS and Unix.
747 if ((access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ||
748 (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE)) {
751 * DENY_DOS opens are always underlying read-write on the
752 * file handle, no matter what the requested access mask
753 * says. Stock samba just sets the flags, but since
754 * ifs_createfile uses the access_mask, it must be updated as
755 * well. This allows BASE-DENY* to pass.
757 if (create_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) {
759 DEBUG(10,("onefs_open_file_ntcreate: deny_dos: "
760 "Adding O_RDWR to flags "
761 "(0x%x) and some READ bits to "
762 "open_access_mask (0x%x)\n",
763 flags, open_access_mask));
765 flags = O_RDWR;
766 open_access_mask |= (FILE_READ_ATTRIBUTES |
767 FILE_READ_DATA | FILE_READ_EA | FILE_EXECUTE);
769 } else if (access_mask & (FILE_READ_ATTRIBUTES |
770 FILE_READ_DATA |
771 FILE_READ_EA |
772 FILE_EXECUTE)) {
773 flags = O_RDWR;
774 } else {
775 flags = O_WRONLY;
777 } else {
778 flags = O_RDONLY;
781 /* Currently we only look at FILE_WRITE_THROUGH for create options. */
782 #if defined(O_SYNC)
783 if ((create_options & FILE_WRITE_THROUGH) &&
784 lp_strict_sync(SNUM(conn))) {
785 flags2 |= O_SYNC;
787 #endif /* O_SYNC */
789 if (posix_open && (access_mask & FILE_APPEND_DATA)) {
790 flags2 |= O_APPEND;
793 if (!posix_open && !CAN_WRITE(conn)) {
795 * We should really return a permission denied error if either
796 * O_CREAT or O_TRUNC are set, but for compatibility with
797 * older versions of Samba we just AND them out.
799 flags2 &= ~(O_CREAT|O_TRUNC);
801 /* Deny DELETE_ACCESS explicitly if the share is read only. */
802 if (access_mask & DELETE_ACCESS) {
803 return map_nt_error_from_unix(EACCES);
807 /* Ensure we can't write on a read-only share or file. */
808 if (flags != O_RDONLY && file_existed &&
809 (!CAN_WRITE(conn) || IS_DOS_READONLY(existing_dos_attributes))) {
810 DEBUG(5, ("onefs_open_file_ntcreate: write access requested "
811 "for file %s on read only %s\n",
812 smb_fname_str_dbg(smb_fname),
813 !CAN_WRITE(conn) ? "share" : "file" ));
814 errno = EACCES;
815 return NT_STATUS_ACCESS_DENIED;
818 DEBUG(10, ("fsp = %p\n", fsp));
820 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
821 fsp->share_access = share_access;
822 fsp->fh->private_options = create_options;
823 fsp->access_mask = open_access_mask; /* We change this to the
824 * requested access_mask after
825 * the open is done. */
826 fsp->posix_open = posix_open;
828 /* Ensure no SAMBA_PRIVATE bits can be set. */
829 fsp->oplock_type = (oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK);
831 if (timeval_is_zero(&request_time)) {
832 request_time = fsp->open_time;
835 if (file_existed) {
836 struct timespec old_write_time = smb_fname->st.st_ex_mtime;
837 id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
839 lck = get_share_mode_lock(talloc_tos(), id,
840 conn->connectpath,
841 smb_fname, &old_write_time);
843 if (lck == NULL) {
844 DEBUG(0, ("Could not get share mode lock\n"));
845 return NT_STATUS_SHARING_VIOLATION;
848 if (lck->delete_on_close) {
849 /* DELETE_PENDING is not deferred for a second */
850 TALLOC_FREE(lck);
851 return NT_STATUS_DELETE_PENDING;
855 SMB_ASSERT(!file_existed || (lck != NULL));
858 * Ensure we pay attention to default ACLs on directories. May be
859 * neccessary depending on ACL policies.
861 if ((flags2 & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
862 (def_acl = directory_has_default_acl(conn, parent_dir))) {
863 unx_mode = 0777;
866 DEBUG(4,("calling onefs_open_file with flags=0x%X flags2=0x%X "
867 "mode=0%o, access_mask = 0x%x, open_access_mask = 0x%x\n",
868 (unsigned int)flags, (unsigned int)flags2,
869 (unsigned int)unx_mode, (unsigned int)access_mask,
870 (unsigned int)open_access_mask));
873 * Since the open is guaranteed to be stat only if req == NULL, a
874 * callback record is only needed if req != NULL.
876 if (req) {
877 SMB_ASSERT(fsp_data);
878 oplock_callback_id = onefs_oplock_wait_record(req->mid);
879 if (oplock_callback_id == 0) {
880 return NT_STATUS_NO_MEMORY;
882 } else {
884 * It is also already asserted it's either a stream or a
885 * stat-only open at this point.
887 SMB_ASSERT(fsp->oplock_type == NO_OPLOCK);
890 /* Do the open. */
891 status = onefs_open_file(fsp,
892 conn,
893 req,
894 parent_dir,
895 smb_fname,
896 flags|flags2,
897 unx_mode,
898 access_mask,
899 open_access_mask,
900 fsp->oplock_type,
901 oplock_callback_id,
902 share_access,
903 create_options,
904 createfile_attributes,
906 &granted_oplock);
908 if (!NT_STATUS_IS_OK(status)) {
910 /* OneFS Oplock Handling */
911 if (errno == EINPROGRESS) {
913 if (lck == NULL) {
915 struct deferred_open_record state;
916 struct timespec old_write_time;
918 old_write_time = smb_fname->st.st_ex_mtime;
920 DEBUG(3, ("Someone created file %s with an "
921 "oplock after we looked: Retrying\n",
922 smb_fname_str_dbg(smb_fname)));
924 * We hit the race that when we did the stat
925 * on the file it did not exist, and someone
926 * has created it in between the stat and the
927 * open_file() call. Just retry immediately.
929 id = vfs_file_id_from_sbuf(conn,
930 &smb_fname->st);
931 if (!(lck = get_share_mode_lock(talloc_tos(),
932 id, conn->connectpath, smb_fname,
933 &old_write_time))) {
935 * Emergency exit
937 DEBUG(0, ("onefs_open_file_ntcreate: "
938 "Could not get share mode "
939 "lock for %s\n",
940 smb_fname_str_dbg(smb_fname)));
941 status = NT_STATUS_SHARING_VIOLATION;
942 goto cleanup_destroy;
945 state.delayed_for_oplocks = False;
946 state.id = id;
948 if (req != NULL) {
949 defer_open(lck, request_time,
950 timeval_zero(), req, &state);
952 goto cleanup_destroy;
954 /* Waiting for an oplock */
955 DEBUG(5,("Async createfile because a client has an "
956 "oplock on %s\n",
957 smb_fname_str_dbg(smb_fname)));
959 SMB_ASSERT(req);
960 schedule_defer_open(lck, request_time, req);
961 goto cleanup;
964 /* Check for a sharing violation */
965 if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
966 uint32 can_access_mask;
967 bool can_access = True;
969 /* Check if this can be done with the deny_dos and fcb
970 * calls. */
972 /* Try to find dup fsp if possible. */
973 if (create_options &
974 (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS|
975 NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) {
977 if (req == NULL) {
978 DEBUG(0, ("DOS open without an SMB "
979 "request!\n"));
980 status = NT_STATUS_INTERNAL_ERROR;
981 goto cleanup_destroy;
984 /* Use the client requested access mask here,
985 * not the one we open with. */
986 status = fcb_or_dos_open(req,
987 conn,
988 fsp,
989 smb_fname,
991 req->smbpid,
992 req->vuid,
993 access_mask,
994 share_access,
995 create_options);
997 if (NT_STATUS_IS_OK(status)) {
998 if (pinfo) {
999 *pinfo = FILE_WAS_OPENED;
1001 status = NT_STATUS_OK;
1002 goto cleanup;
1007 * This next line is a subtlety we need for
1008 * MS-Access. If a file open will fail due to share
1009 * permissions and also for security (access) reasons,
1010 * we need to return the access failed error, not the
1011 * share error. We can't open the file due to kernel
1012 * oplock deadlock (it's possible we failed above on
1013 * the open_mode_check()) so use a userspace check.
1016 if (flags & O_RDWR) {
1017 can_access_mask = FILE_READ_DATA|FILE_WRITE_DATA;
1018 } else if (flags & O_WRONLY) {
1019 can_access_mask = FILE_WRITE_DATA;
1020 } else {
1021 can_access_mask = FILE_READ_DATA;
1024 if (((can_access_mask & FILE_WRITE_DATA) &&
1025 !CAN_WRITE(conn)) ||
1026 !can_access_file_data(conn, smb_fname,
1027 can_access_mask)) {
1028 can_access = False;
1032 * If we're returning a share violation, ensure we
1033 * cope with the braindead 1 second delay.
1035 if (!(oplock_request & INTERNAL_OPEN_ONLY) &&
1036 lp_defer_sharing_violations()) {
1037 struct timeval timeout;
1038 struct deferred_open_record state;
1039 int timeout_usecs;
1041 /* this is a hack to speed up torture tests
1042 in 'make test' */
1043 timeout_usecs = lp_parm_int(SNUM(conn),
1044 "smbd","sharedelay",
1045 SHARING_VIOLATION_USEC_WAIT);
1047 /* This is a relative time, added to the
1048 absolute request_time value to get the
1049 absolute timeout time. Note that if this
1050 is the second or greater time we enter this
1051 codepath for this particular request mid
1052 then request_time is left as the absolute
1053 time of the *first* time this request mid
1054 was processed. This is what allows the
1055 request to eventually time out. */
1057 timeout = timeval_set(0, timeout_usecs);
1059 /* Nothing actually uses
1060 state.delayed_for_oplocks but it's handy to
1061 differentiate in debug messages between a
1062 30 second delay due to oplock break, and a
1063 1 second delay for share mode conflicts. */
1065 state.delayed_for_oplocks = False;
1066 state.id = id;
1067 state.failed = false;
1069 if ((req != NULL)
1070 && !request_timed_out(request_time,
1071 timeout)) {
1072 defer_open(lck, request_time, timeout,
1073 req, &state);
1077 if (can_access) {
1079 * We have detected a sharing violation here
1080 * so return the correct error code
1082 status = NT_STATUS_SHARING_VIOLATION;
1083 } else {
1084 status = NT_STATUS_ACCESS_DENIED;
1087 goto cleanup_destroy;
1091 * Normal error, for example EACCES
1093 cleanup_destroy:
1094 if (oplock_callback_id != 0) {
1095 destroy_onefs_callback_record(oplock_callback_id);
1097 cleanup:
1098 TALLOC_FREE(lck);
1099 return status;
1102 fsp->oplock_type = granted_oplock;
1104 if (oplock_callback_id != 0) {
1105 onefs_set_oplock_callback(oplock_callback_id, fsp);
1106 fsp_data->oplock_callback_id = oplock_callback_id;
1107 } else {
1108 SMB_ASSERT(fsp->oplock_type == NO_OPLOCK);
1111 if (!file_existed) {
1112 struct timespec old_write_time = smb_fname->st.st_ex_mtime;
1114 * Deal with the race condition where two smbd's detect the
1115 * file doesn't exist and do the create at the same time. One
1116 * of them will win and set a share mode, the other (ie. this
1117 * one) should check if the requested share mode for this
1118 * create is allowed.
1122 * Now the file exists and fsp is successfully opened,
1123 * fsp->dev and fsp->inode are valid and should replace the
1124 * dev=0,inode=0 from a non existent file. Spotted by
1125 * Nadav Danieli <nadavd@exanet.com>. JRA.
1128 id = fsp->file_id;
1130 lck = get_share_mode_lock(talloc_tos(), id,
1131 conn->connectpath,
1132 smb_fname, &old_write_time);
1134 if (lck == NULL) {
1135 DEBUG(0, ("onefs_open_file_ntcreate: Could not get "
1136 "share mode lock for %s\n",
1137 smb_fname_str_dbg(smb_fname)));
1138 fd_close(fsp);
1139 return NT_STATUS_SHARING_VIOLATION;
1142 if (lck->delete_on_close) {
1143 status = NT_STATUS_DELETE_PENDING;
1146 if (!NT_STATUS_IS_OK(status)) {
1147 struct deferred_open_record state;
1149 fd_close(fsp);
1151 state.delayed_for_oplocks = False;
1152 state.id = id;
1154 /* Do it all over again immediately. In the second
1155 * round we will find that the file existed and handle
1156 * the DELETE_PENDING and FCB cases correctly. No need
1157 * to duplicate the code here. Essentially this is a
1158 * "goto top of this function", but don't tell
1159 * anybody... */
1161 if (req != NULL) {
1162 defer_open(lck, request_time, timeval_zero(),
1163 req, &state);
1165 TALLOC_FREE(lck);
1166 return status;
1170 * We exit this block with the share entry *locked*.....
1175 SMB_ASSERT(lck != NULL);
1177 /* Delete streams if create_disposition requires it */
1178 if (file_existed && clear_ads &&
1179 !is_ntfs_stream_smb_fname(smb_fname)) {
1180 status = delete_all_streams(conn, smb_fname->base_name);
1181 if (!NT_STATUS_IS_OK(status)) {
1182 TALLOC_FREE(lck);
1183 fd_close(fsp);
1184 return status;
1188 /* note that we ignore failure for the following. It is
1189 basically a hack for NFS, and NFS will never set one of
1190 these only read them. Nobody but Samba can ever set a deny
1191 mode and we have already checked our more authoritative
1192 locking database for permission to set this deny mode. If
1193 the kernel refuses the operations then the kernel is wrong.
1194 note that GPFS supports it as well - jmcd */
1196 if (fsp->fh->fd != -1) {
1197 ret_flock = SMB_VFS_KERNEL_FLOCK(fsp, share_access);
1198 if(ret_flock == -1 ){
1200 TALLOC_FREE(lck);
1201 fd_close(fsp);
1202 return NT_STATUS_SHARING_VIOLATION;
1207 * At this point onwards, we can guarentee that the share entry
1208 * is locked, whether we created the file or not, and that the
1209 * deny mode is compatible with all current opens.
1212 /* Record the options we were opened with. */
1213 fsp->share_access = share_access;
1214 fsp->fh->private_options = create_options;
1216 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
1218 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
1220 if (file_existed) {
1221 /* stat opens on existing files don't get oplocks. */
1222 if (is_stat_open(open_access_mask)) {
1223 fsp->oplock_type = NO_OPLOCK;
1226 if (!(flags2 & O_TRUNC)) {
1227 info = FILE_WAS_OPENED;
1228 } else {
1229 info = FILE_WAS_OVERWRITTEN;
1231 } else {
1232 info = FILE_WAS_CREATED;
1235 if (pinfo) {
1236 *pinfo = info;
1240 * Setup the oplock info in both the shared memory and
1241 * file structs.
1244 if ((fsp->oplock_type != NO_OPLOCK) &&
1245 (fsp->oplock_type != FAKE_LEVEL_II_OPLOCK)) {
1246 if (!set_file_oplock(fsp, fsp->oplock_type)) {
1247 /* Could not get the kernel oplock */
1248 fsp->oplock_type = NO_OPLOCK;
1252 if (fsp->oplock_type == LEVEL_II_OPLOCK &&
1253 (!lp_level2_oplocks(SNUM(conn)) ||
1254 !(global_client_caps & CAP_LEVEL_II_OPLOCKS))) {
1256 DEBUG(5, ("Downgrading level2 oplock on open "
1257 "because level2 oplocks = off\n"));
1259 release_file_oplock(fsp);
1262 if (info == FILE_WAS_OVERWRITTEN || info == FILE_WAS_CREATED ||
1263 info == FILE_WAS_SUPERSEDED) {
1264 new_file_created = True;
1267 set_share_mode(lck, fsp, conn->server_info->utok.uid, 0,
1268 fsp->oplock_type);
1270 /* Handle strange delete on close create semantics. */
1271 if (create_options & FILE_DELETE_ON_CLOSE) {
1272 status = can_set_delete_on_close(fsp, True, new_dos_attributes);
1274 if (!NT_STATUS_IS_OK(status)) {
1275 /* Remember to delete the mode we just added. */
1276 del_share_mode(lck, fsp);
1277 TALLOC_FREE(lck);
1278 fd_close(fsp);
1279 return status;
1281 /* Note that here we set the *inital* delete on close flag,
1282 not the regular one. The magic gets handled in close. */
1283 fsp->initial_delete_on_close = True;
1287 * Take care of inherited ACLs on created files - if default ACL not
1288 * selected.
1289 * May be necessary depending on acl policies.
1291 if (!posix_open && !file_existed && !def_acl &&
1292 !(VALID_STAT(smb_fname->st) &&
1293 (smb_fname->st.st_ex_flags & SF_HASNTFSACL))) {
1295 int saved_errno = errno; /* We might get ENOSYS in the next
1296 * call.. */
1298 if (SMB_VFS_FCHMOD_ACL(fsp, unx_mode) == -1 &&
1299 errno == ENOSYS) {
1300 errno = saved_errno; /* Ignore ENOSYS */
1303 } else if (new_unx_mode) {
1305 int ret = -1;
1307 /* Attributes need changing. File already existed. */
1310 int saved_errno = errno; /* We might get ENOSYS in the
1311 * next call.. */
1312 ret = SMB_VFS_FCHMOD_ACL(fsp, new_unx_mode);
1314 if (ret == -1 && errno == ENOSYS) {
1315 errno = saved_errno; /* Ignore ENOSYS */
1316 } else {
1317 DEBUG(5, ("onefs_open_file_ntcreate: reset "
1318 "attributes of file %s to 0%o\n",
1319 smb_fname_str_dbg(smb_fname),
1320 (unsigned int)new_unx_mode));
1321 ret = 0; /* Don't do the fchmod below. */
1325 if ((ret == -1) &&
1326 (SMB_VFS_FCHMOD(fsp, new_unx_mode) == -1))
1327 DEBUG(5, ("onefs_open_file_ntcreate: failed to reset "
1328 "attributes of file %s to 0%o\n",
1329 smb_fname_str_dbg(smb_fname),
1330 (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 struct smb_filename *smb_dname,
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)
1359 files_struct *fsp = NULL;
1360 struct share_mode_lock *lck = NULL;
1361 NTSTATUS status;
1362 struct timespec mtimespec;
1363 int info = 0;
1364 char *parent_dir;
1365 bool posix_open = false;
1366 uint32 create_flags = 0;
1367 uint32 mode = lp_dir_mask(SNUM(conn));
1369 DEBUG(5, ("onefs_open_directory: opening directory %s, "
1370 "access_mask = 0x%x, "
1371 "share_access = 0x%x create_options = 0x%x, "
1372 "create_disposition = 0x%x, file_attributes = 0x%x\n",
1373 smb_fname_str_dbg(smb_dname), (unsigned int)access_mask,
1374 (unsigned int)share_access, (unsigned int)create_options,
1375 (unsigned int)create_disposition,
1376 (unsigned int)file_attributes));
1378 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
1379 (conn->fs_capabilities & FILE_NAMED_STREAMS) &&
1380 is_ntfs_stream_smb_fname(smb_dname)) {
1381 DEBUG(2, ("onefs_open_directory: %s is a stream name!\n",
1382 smb_fname_str_dbg(smb_dname)));
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,
1416 smb_fname_str_dbg(smb_dname)));
1417 return NT_STATUS_INVALID_PARAMETER;
1421 * Check for write access to the share. Done in mkdir_internal() in
1422 * mainline samba.
1424 if (!CAN_WRITE(conn) && (create_flags & O_CREAT)) {
1425 return NT_STATUS_ACCESS_DENIED;
1428 /* Get parent dirname */
1429 if (!parent_dirname(talloc_tos(), smb_dname->base_name, &parent_dir,
1430 NULL)) {
1431 return NT_STATUS_NO_MEMORY;
1434 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
1435 posix_open = true;
1436 mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
1437 file_attributes = 0;
1438 } else {
1439 mode = unix_mode(conn, aDIR, smb_dname, parent_dir);
1443 * The NONINDEXED and COMPRESSED bits seem to always be cleared on
1444 * directories, no matter if you specify that they should be set.
1446 file_attributes &=
1447 ~(FILE_ATTRIBUTE_NONINDEXED | FILE_ATTRIBUTE_COMPRESSED);
1449 status = file_new(req, conn, &fsp);
1450 if(!NT_STATUS_IS_OK(status)) {
1451 return status;
1455 * Actual open with retry magic to handle FILE_OPEN_IF which is
1456 * unique because the kernel won't tell us if the file was opened or
1457 * created.
1459 retry_open:
1460 fsp->fh->fd = onefs_sys_create_file(conn,
1462 smb_dname->base_name,
1463 access_mask,
1464 access_mask,
1465 share_access,
1466 create_options,
1467 create_flags | O_DIRECTORY,
1468 mode,
1472 file_attributes,
1473 NULL);
1475 if (fsp->fh->fd == -1) {
1476 DEBUG(3, ("Error opening %s. Errno=%d (%s).\n",
1477 smb_fname_str_dbg(smb_dname), errno,
1478 strerror(errno)));
1479 SMB_ASSERT(errno != EINPROGRESS);
1481 if (create_disposition == FILE_OPEN_IF) {
1482 if (errno == ENOENT) {
1483 /* Try again, creating it this time. */
1484 create_flags = O_CREAT | O_EXCL;
1485 info = FILE_WAS_CREATED;
1486 goto retry_open;
1487 } else if (errno == EEXIST) {
1488 /* Uggh. Try again again. */
1489 create_flags = 0;
1490 info = FILE_WAS_OPENED;
1491 goto retry_open;
1495 /* Error cases below: */
1496 file_free(req, fsp);
1498 if ((errno == ENOENT) && (create_disposition == FILE_OPEN)) {
1499 DEBUG(5, ("onefs_open_directory: FILE_OPEN requested "
1500 "for directory %s and it doesn't "
1501 "exist.\n", smb_fname_str_dbg(smb_dname)));
1502 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1503 } else if ((errno == EEXIST) &&
1504 (create_disposition == FILE_CREATE)) {
1505 DEBUG(5, ("onefs_open_directory: FILE_CREATE "
1506 "requested for directory %s and it "
1507 "already exists.\n",
1508 smb_fname_str_dbg(smb_dname)));
1509 return NT_STATUS_OBJECT_NAME_COLLISION;
1510 } else if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
1511 /* Catch sharing violations. */
1512 return NT_STATUS_SHARING_VIOLATION;
1515 return map_nt_error_from_unix(errno);
1518 if (info == FILE_WAS_CREATED) {
1520 /* Pulled from mkdir_internal() */
1521 if (SMB_VFS_LSTAT(conn, smb_dname) == -1) {
1522 DEBUG(2, ("Could not stat directory '%s' just "
1523 "created: %s\n",
1524 smb_fname_str_dbg(smb_dname),
1525 strerror(errno)));
1526 return map_nt_error_from_unix(errno);
1529 if (!S_ISDIR(smb_dname->st.st_ex_mode)) {
1530 DEBUG(0, ("Directory just '%s' created is not a "
1531 "directory\n",
1532 smb_fname_str_dbg(smb_dname)));
1533 return NT_STATUS_ACCESS_DENIED;
1536 if (!posix_open) {
1538 * Check if high bits should have been set, then (if
1539 * bits are missing): add them. Consider bits
1540 * automagically set by UNIX, i.e. SGID bit from
1541 * parent dir.
1543 if (mode & ~(S_IRWXU|S_IRWXG|S_IRWXO) &&
1544 (mode & ~smb_dname->st.st_ex_mode)) {
1545 SMB_VFS_CHMOD(conn, smb_dname->base_name,
1546 (smb_dname->st.st_ex_mode |
1547 (mode & ~smb_dname->st.st_ex_mode)));
1551 /* Change the owner if required. */
1552 if (lp_inherit_owner(SNUM(conn))) {
1553 change_dir_owner_to_parent(conn, parent_dir,
1554 smb_dname->base_name,
1555 &smb_dname->st);
1558 notify_fname(conn, NOTIFY_ACTION_ADDED,
1559 FILE_NOTIFY_CHANGE_DIR_NAME,
1560 smb_dname->base_name);
1563 /* Stat the fd for Samba bookkeeping. */
1564 if(SMB_VFS_FSTAT(fsp, &smb_dname->st) != 0) {
1565 fd_close(fsp);
1566 file_free(req, fsp);
1567 return map_nt_error_from_unix(errno);
1570 /* Setup the files_struct for it. */
1571 fsp->mode = smb_dname->st.st_ex_mode;
1572 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_dname->st);
1573 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
1574 fsp->file_pid = req ? req->smbpid : 0;
1575 fsp->can_lock = False;
1576 fsp->can_read = False;
1577 fsp->can_write = False;
1579 fsp->share_access = share_access;
1580 fsp->fh->private_options = create_options;
1582 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
1584 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
1585 fsp->print_file = False;
1586 fsp->modified = False;
1587 fsp->oplock_type = NO_OPLOCK;
1588 fsp->sent_oplock_break = NO_BREAK_SENT;
1589 fsp->is_directory = True;
1590 fsp->posix_open = posix_open;
1592 status = fsp_set_smb_fname(fsp, smb_dname);
1593 if (!NT_STATUS_IS_OK(status)) {
1594 fd_close(fsp);
1595 file_free(req, fsp);
1596 return status;
1599 mtimespec = smb_dname->st.st_ex_mtime;
1602 * Still set the samba share mode lock for correct delete-on-close
1603 * semantics and to make smbstatus more useful.
1605 lck = get_share_mode_lock(talloc_tos(), fsp->file_id,
1606 conn->connectpath, smb_dname, &mtimespec);
1608 if (lck == NULL) {
1609 DEBUG(0, ("onefs_open_directory: Could not get share mode "
1610 "lock for %s\n", smb_fname_str_dbg(smb_dname)));
1611 fd_close(fsp);
1612 file_free(req, fsp);
1613 return NT_STATUS_SHARING_VIOLATION;
1616 if (lck->delete_on_close) {
1617 TALLOC_FREE(lck);
1618 fd_close(fsp);
1619 file_free(req, fsp);
1620 return NT_STATUS_DELETE_PENDING;
1623 set_share_mode(lck, fsp, conn->server_info->utok.uid, 0, NO_OPLOCK);
1626 * For directories the delete on close bit at open time seems
1627 * always to be honored on close... See test 19 in Samba4 BASE-DELETE.
1629 if (create_options & FILE_DELETE_ON_CLOSE) {
1630 status = can_set_delete_on_close(fsp, True, 0);
1631 if (!NT_STATUS_IS_OK(status) &&
1632 !NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
1633 TALLOC_FREE(lck);
1634 fd_close(fsp);
1635 file_free(req, fsp);
1636 return status;
1639 if (NT_STATUS_IS_OK(status)) {
1640 /* Note that here we set the *inital* delete on close flag,
1641 not the regular one. The magic gets handled in close. */
1642 fsp->initial_delete_on_close = True;
1646 TALLOC_FREE(lck);
1648 if (pinfo) {
1649 *pinfo = info;
1652 *result = fsp;
1653 return NT_STATUS_OK;
1657 * Wrapper around onefs_open_file_ntcreate and onefs_open_directory.
1659 static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
1660 struct smb_request *req,
1661 struct smb_filename *smb_fname,
1662 uint32_t access_mask,
1663 uint32_t share_access,
1664 uint32_t create_disposition,
1665 uint32_t create_options,
1666 uint32_t file_attributes,
1667 uint32_t oplock_request,
1668 uint64_t allocation_size,
1669 struct security_descriptor *sd,
1670 struct ea_list *ea_list,
1671 files_struct **result,
1672 int *pinfo,
1673 struct onefs_fsp_data *fsp_data)
1675 int info = FILE_WAS_OPENED;
1676 files_struct *base_fsp = NULL;
1677 files_struct *fsp = NULL;
1678 NTSTATUS status;
1680 DEBUG(10,("onefs_create_file_unixpath: access_mask = 0x%x "
1681 "file_attributes = 0x%x, share_access = 0x%x, "
1682 "create_disposition = 0x%x create_options = 0x%x "
1683 "oplock_request = 0x%x ea_list = 0x%p, sd = 0x%p, "
1684 "fname = %s\n",
1685 (unsigned int)access_mask,
1686 (unsigned int)file_attributes,
1687 (unsigned int)share_access,
1688 (unsigned int)create_disposition,
1689 (unsigned int)create_options,
1690 (unsigned int)oplock_request,
1691 ea_list, sd, smb_fname_str_dbg(smb_fname)));
1693 if (create_options & FILE_OPEN_BY_FILE_ID) {
1694 status = NT_STATUS_NOT_SUPPORTED;
1695 goto fail;
1698 if (create_options & NTCREATEX_OPTIONS_INVALID_PARAM_MASK) {
1699 status = NT_STATUS_INVALID_PARAMETER;
1700 goto fail;
1703 if (req == NULL) {
1704 SMB_ASSERT((oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK) ==
1705 NO_OPLOCK);
1706 oplock_request |= INTERNAL_OPEN_ONLY;
1709 if (lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE,
1710 PARM_IGNORE_SACLS, PARM_IGNORE_SACLS_DEFAULT)) {
1711 access_mask &= ~SYSTEM_SECURITY_ACCESS;
1714 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
1715 && (access_mask & DELETE_ACCESS)
1716 && !is_ntfs_stream_smb_fname(smb_fname)) {
1718 * We can't open a file with DELETE access if any of the
1719 * streams is open without FILE_SHARE_DELETE
1721 status = open_streams_for_delete(conn, smb_fname->base_name);
1723 if (!NT_STATUS_IS_OK(status)) {
1724 goto fail;
1728 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
1729 && is_ntfs_stream_smb_fname(smb_fname)) {
1730 uint32 base_create_disposition;
1731 struct smb_filename *smb_fname_base = NULL;
1733 if (create_options & FILE_DIRECTORY_FILE) {
1734 status = NT_STATUS_NOT_A_DIRECTORY;
1735 goto fail;
1738 switch (create_disposition) {
1739 case FILE_OPEN:
1740 base_create_disposition = FILE_OPEN;
1741 break;
1742 default:
1743 base_create_disposition = FILE_OPEN_IF;
1744 break;
1747 /* Create an smb_filename with stream_name == NULL. */
1748 status = create_synthetic_smb_fname(talloc_tos(),
1749 smb_fname->base_name,
1750 NULL, NULL,
1751 &smb_fname_base);
1752 if (!NT_STATUS_IS_OK(status)) {
1753 goto fail;
1756 if (SMB_VFS_STAT(conn, smb_fname_base) == -1) {
1757 DEBUG(10, ("Unable to stat stream: %s\n",
1758 smb_fname_str_dbg(smb_fname_base)));
1761 status = onefs_create_file_unixpath(
1762 conn, /* conn */
1763 NULL, /* req */
1764 smb_fname_base, /* fname */
1765 SYNCHRONIZE_ACCESS, /* access_mask */
1766 (FILE_SHARE_READ |
1767 FILE_SHARE_WRITE |
1768 FILE_SHARE_DELETE), /* share_access */
1769 base_create_disposition, /* create_disposition*/
1770 0, /* create_options */
1771 file_attributes, /* file_attributes */
1772 NO_OPLOCK, /* oplock_request */
1773 0, /* allocation_size */
1774 NULL, /* sd */
1775 NULL, /* ea_list */
1776 &base_fsp, /* result */
1777 NULL, /* pinfo */
1778 NULL); /* fsp_data */
1780 TALLOC_FREE(smb_fname_base);
1782 if (!NT_STATUS_IS_OK(status)) {
1783 DEBUG(10, ("onefs_create_file_unixpath for base %s "
1784 "failed: %s\n", smb_fname->base_name,
1785 nt_errstr(status)));
1786 goto fail;
1790 * Testing against windows xp/2003/vista shows that oplocks
1791 * can actually be requested and granted on streams (see the
1792 * RAW-OPLOCK-STREAM1 smbtorture test).
1794 if ((oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK) !=
1795 NO_OPLOCK) {
1796 DEBUG(5, ("Oplock(%d) being requested on a stream! "
1797 "Ignoring oplock request: fname=%s\n",
1798 oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK,
1799 smb_fname_str_dbg(smb_fname)));
1800 /* Request NO_OPLOCK instead. */
1801 oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
1805 /* Covert generic bits in the security descriptor. */
1806 if (sd != NULL) {
1807 security_acl_map_generic(sd->dacl, &file_generic_mapping);
1808 security_acl_map_generic(sd->sacl, &file_generic_mapping);
1812 * If it's a request for a directory open, deal with it separately.
1815 if (create_options & FILE_DIRECTORY_FILE) {
1817 if (create_options & FILE_NON_DIRECTORY_FILE) {
1818 status = NT_STATUS_INVALID_PARAMETER;
1819 goto fail;
1822 /* Can't open a temp directory. IFS kit test. */
1823 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
1824 (file_attributes & FILE_ATTRIBUTE_TEMPORARY)) {
1825 status = NT_STATUS_INVALID_PARAMETER;
1826 goto fail;
1830 * We will get a create directory here if the Win32
1831 * app specified a security descriptor in the
1832 * CreateDirectory() call.
1835 status = onefs_open_directory(
1836 conn, /* conn */
1837 req, /* req */
1838 smb_fname, /* fname */
1839 access_mask, /* access_mask */
1840 share_access, /* share_access */
1841 create_disposition, /* create_disposition*/
1842 create_options, /* create_options */
1843 file_attributes, /* file_attributes */
1844 sd, /* sd */
1845 &fsp, /* result */
1846 &info); /* pinfo */
1847 } else {
1850 * Ordinary file case.
1853 status = file_new(req, conn, &fsp);
1854 if(!NT_STATUS_IS_OK(status)) {
1855 goto fail;
1859 * We're opening the stream element of a base_fsp
1860 * we already opened. Set up the base_fsp pointer.
1862 if (base_fsp) {
1863 fsp->base_fsp = base_fsp;
1866 status = onefs_open_file_ntcreate(
1867 conn, /* conn */
1868 req, /* req */
1869 smb_fname, /* fname */
1870 access_mask, /* access_mask */
1871 share_access, /* share_access */
1872 create_disposition, /* create_disposition*/
1873 create_options, /* create_options */
1874 file_attributes, /* file_attributes */
1875 oplock_request, /* oplock_request */
1876 sd, /* sd */
1877 fsp, /* result */
1878 &info, /* pinfo */
1879 fsp_data); /* fsp_data */
1881 if(!NT_STATUS_IS_OK(status)) {
1882 file_free(req, fsp);
1883 fsp = NULL;
1886 if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
1888 /* A stream open never opens a directory */
1890 if (base_fsp) {
1891 status = NT_STATUS_FILE_IS_A_DIRECTORY;
1892 goto fail;
1896 * Fail the open if it was explicitly a non-directory
1897 * file.
1900 if (create_options & FILE_NON_DIRECTORY_FILE) {
1901 status = NT_STATUS_FILE_IS_A_DIRECTORY;
1902 goto fail;
1905 create_options |= FILE_DIRECTORY_FILE;
1907 status = onefs_open_directory(
1908 conn, /* conn */
1909 req, /* req */
1910 smb_fname, /* fname */
1911 access_mask, /* access_mask */
1912 share_access, /* share_access */
1913 create_disposition, /* create_disposition*/
1914 create_options, /* create_options */
1915 file_attributes, /* file_attributes */
1916 sd, /* sd */
1917 &fsp, /* result */
1918 &info); /* pinfo */
1922 if (!NT_STATUS_IS_OK(status)) {
1923 goto fail;
1926 fsp->base_fsp = base_fsp;
1928 SMB_ASSERT(fsp);
1930 if ((ea_list != NULL) && (info == FILE_WAS_CREATED)) {
1931 status = set_ea(conn, fsp, smb_fname, ea_list);
1932 if (!NT_STATUS_IS_OK(status)) {
1933 goto fail;
1937 if (!fsp->is_directory && S_ISDIR(smb_fname->st.st_ex_mode)) {
1938 status = NT_STATUS_ACCESS_DENIED;
1939 goto fail;
1942 /* Save the requested allocation size. */
1943 if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
1944 if (allocation_size
1945 && (allocation_size > smb_fname->st.st_ex_size)) {
1946 fsp->initial_allocation_size = smb_roundup(
1947 fsp->conn, allocation_size);
1948 if (fsp->is_directory) {
1949 /* Can't set allocation size on a directory. */
1950 status = NT_STATUS_ACCESS_DENIED;
1951 goto fail;
1953 if (vfs_allocate_file_space(
1954 fsp, fsp->initial_allocation_size) == -1) {
1955 status = NT_STATUS_DISK_FULL;
1956 goto fail;
1958 } else {
1959 fsp->initial_allocation_size = smb_roundup(
1960 fsp->conn, (uint64_t)smb_fname->st.st_ex_size);
1964 DEBUG(10, ("onefs_create_file_unixpath: info=%d\n", info));
1966 *result = fsp;
1967 if (pinfo != NULL) {
1968 *pinfo = info;
1970 if ((fsp->fh != NULL) && (fsp->fh->fd != -1)) {
1971 SMB_VFS_FSTAT(fsp, &smb_fname->st);
1973 return NT_STATUS_OK;
1975 fail:
1976 DEBUG(10, ("onefs_create_file_unixpath: %s\n", nt_errstr(status)));
1978 if (fsp != NULL) {
1979 if (base_fsp && fsp->base_fsp == base_fsp) {
1981 * The close_file below will close
1982 * fsp->base_fsp.
1984 base_fsp = NULL;
1986 close_file(req, fsp, ERROR_CLOSE);
1987 fsp = NULL;
1989 if (base_fsp != NULL) {
1990 close_file(req, base_fsp, ERROR_CLOSE);
1991 base_fsp = NULL;
1993 return status;
1996 static void destroy_onefs_fsp_data(void *p_data)
1998 struct onefs_fsp_data *fsp_data = (struct onefs_fsp_data *)p_data;
2000 destroy_onefs_callback_record(fsp_data->oplock_callback_id);
2004 * SMB_VFS_CREATE_FILE interface to onefs.
2006 NTSTATUS onefs_create_file(vfs_handle_struct *handle,
2007 struct smb_request *req,
2008 uint16_t root_dir_fid,
2009 struct smb_filename *smb_fname,
2010 uint32_t access_mask,
2011 uint32_t share_access,
2012 uint32_t create_disposition,
2013 uint32_t create_options,
2014 uint32_t file_attributes,
2015 uint32_t oplock_request,
2016 uint64_t allocation_size,
2017 struct security_descriptor *sd,
2018 struct ea_list *ea_list,
2019 files_struct **result,
2020 int *pinfo)
2022 connection_struct *conn = handle->conn;
2023 struct onefs_fsp_data fsp_data = {};
2024 int info = FILE_WAS_OPENED;
2025 files_struct *fsp = NULL;
2026 NTSTATUS status;
2028 DEBUG(10,("onefs_create_file: access_mask = 0x%x "
2029 "file_attributes = 0x%x, share_access = 0x%x, "
2030 "create_disposition = 0x%x create_options = 0x%x "
2031 "oplock_request = 0x%x "
2032 "root_dir_fid = 0x%x, ea_list = 0x%p, sd = 0x%p, "
2033 "fname = %s\n",
2034 (unsigned int)access_mask,
2035 (unsigned int)file_attributes,
2036 (unsigned int)share_access,
2037 (unsigned int)create_disposition,
2038 (unsigned int)create_options,
2039 (unsigned int)oplock_request,
2040 (unsigned int)root_dir_fid,
2041 ea_list, sd, smb_fname_str_dbg(smb_fname)));
2043 /* Get the file name if root_dir_fid was specified. */
2044 if (root_dir_fid != 0) {
2045 status = get_relative_fid_filename(conn, req, root_dir_fid,
2046 smb_fname);
2047 if (!NT_STATUS_IS_OK(status)) {
2048 goto fail;
2052 /* All file access must go through check_name() */
2053 status = check_name(conn, smb_fname->base_name);
2054 if (!NT_STATUS_IS_OK(status)) {
2055 goto fail;
2058 status = onefs_create_file_unixpath(
2059 conn, /* conn */
2060 req, /* req */
2061 smb_fname, /* fname */
2062 access_mask, /* access_mask */
2063 share_access, /* share_access */
2064 create_disposition, /* create_disposition*/
2065 create_options, /* create_options */
2066 file_attributes, /* file_attributes */
2067 oplock_request, /* oplock_request */
2068 allocation_size, /* allocation_size */
2069 sd, /* sd */
2070 ea_list, /* ea_list */
2071 &fsp, /* result */
2072 &info, /* pinfo */
2073 &fsp_data); /* psbuf */
2075 if (!NT_STATUS_IS_OK(status)) {
2076 goto fail;
2079 DEBUG(10, ("onefs_create_file: info=%d\n", info));
2082 * Setup private onefs_fsp_data. Currently the private data struct is
2083 * only used to store the oplock_callback_id so that when the file is
2084 * closed, the onefs_callback_record can be properly cleaned up in the
2085 * oplock_onefs sub-system.
2087 if (fsp) {
2088 struct onefs_fsp_data *fsp_data_tmp = NULL;
2089 fsp_data_tmp = (struct onefs_fsp_data *)
2090 VFS_ADD_FSP_EXTENSION(handle, fsp, struct onefs_fsp_data,
2091 &destroy_onefs_fsp_data);
2093 if (fsp_data_tmp == NULL) {
2094 status = NT_STATUS_NO_MEMORY;
2095 goto fail;
2098 *fsp_data_tmp = fsp_data;
2101 *result = fsp;
2102 if (pinfo != NULL) {
2103 *pinfo = info;
2105 return NT_STATUS_OK;
2107 fail:
2108 DEBUG(10, ("onefs_create_file: %s\n", nt_errstr(status)));
2110 if (fsp != NULL) {
2111 close_file(req, fsp, ERROR_CLOSE);
2112 fsp = NULL;
2114 return status;