s3-smbd: group print relate data in own structure
[Samba/ekacnet.git] / source3 / modules / onefs_open.c
blobdd4c24555f65422efe7b4e72c4d1256bce2b9807
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 uint32_t private_flags,
58 struct security_descriptor *sd,
59 struct ea_list *ea_list,
60 files_struct **result,
61 int *pinfo,
62 struct onefs_fsp_data *fsp_data);
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 struct smb_filename *smb_fname,
73 int flags,
74 mode_t unx_mode,
75 uint32 access_mask,
76 uint32 open_access_mask,
77 int oplock_request,
78 uint64 id,
79 uint32 share_access,
80 uint32 create_options,
81 uint32_t new_dos_attributes,
82 struct security_descriptor *sd,
83 int *granted_oplock)
85 struct smb_filename *smb_fname_onefs = NULL;
86 NTSTATUS status = NT_STATUS_OK;
87 int accmode = (flags & O_ACCMODE);
88 int local_flags = flags;
89 bool file_existed = VALID_STAT(smb_fname->st);
90 const char *wild;
91 int base_fd = -1;
93 fsp->fh->fd = -1;
94 errno = EPERM;
96 /* Check permissions */
99 * This code was changed after seeing a client open request
100 * containing the open mode of (DENY_WRITE/read-only) with
101 * the 'create if not exist' bit set. The previous code
102 * would fail to open the file read only on a read-only share
103 * as it was checking the flags parameter directly against O_RDONLY,
104 * this was failing as the flags parameter was set to O_RDONLY|O_CREAT.
105 * JRA.
108 if (!CAN_WRITE(conn)) {
109 /* It's a read-only share - fail if we wanted to write. */
110 if(accmode != O_RDONLY) {
111 DEBUG(3, ("Permission denied opening %s\n",
112 smb_fname_str_dbg(smb_fname)));
113 return NT_STATUS_ACCESS_DENIED;
114 } else if(flags & O_CREAT) {
115 /* We don't want to write - but we must make sure that
116 O_CREAT doesn't create the file if we have write
117 access into the directory.
119 flags &= ~O_CREAT;
120 local_flags &= ~O_CREAT;
125 * This little piece of insanity is inspired by the
126 * fact that an NT client can open a file for O_RDONLY,
127 * but set the create disposition to FILE_EXISTS_TRUNCATE.
128 * If the client *can* write to the file, then it expects to
129 * truncate the file, even though it is opening for readonly.
130 * Quicken uses this stupid trick in backup file creation...
131 * Thanks *greatly* to "David W. Chapman Jr." <dwcjr@inethouston.net>
132 * for helping track this one down. It didn't bite us in 2.0.x
133 * as we always opened files read-write in that release. JRA.
136 if ((accmode == O_RDONLY) && ((flags & O_TRUNC) == O_TRUNC)) {
137 DEBUG(10,("onefs_open_file: truncate requested on read-only "
138 "open for file %s\n", smb_fname_str_dbg(smb_fname)));
139 local_flags = (flags & ~O_ACCMODE)|O_RDWR;
142 #if defined(O_NONBLOCK) && defined(S_ISFIFO)
144 * We would block on opening a FIFO with no one else on the
145 * other end. Do what we used to do and add O_NONBLOCK to the
146 * open flags. JRA.
149 if (file_existed && S_ISFIFO(smb_fname->st.st_ex_mode)) {
150 local_flags |= O_NONBLOCK;
152 #endif
154 /* Don't create files with Microsoft wildcard characters. */
155 if (fsp->base_fsp) {
157 * wildcard characters are allowed in stream names
158 * only test the basefilename
160 wild = fsp->base_fsp->fsp_name->base_name;
161 } else {
162 wild = smb_fname->base_name;
164 if ((local_flags & O_CREAT) && !file_existed &&
165 ms_has_wild(wild)) {
167 * XXX: may need to remvoe this return...
169 * We dont think this check needs to exist. All it does is
170 * block creating files with Microsoft wildcards, which is
171 * fine if the creation originated from NFS or locally and
172 * then was copied via Samba.
174 DEBUG(1, ("onefs_open_file: creating file with wildcard: %s\n",
175 smb_fname_str_dbg(smb_fname)));
176 return NT_STATUS_OBJECT_NAME_INVALID;
179 /* Actually do the open */
181 #ifdef O_NOFOLLOW
183 * Never follow symlinks on a POSIX client. The
184 * client should be doing this.
187 if (fsp->posix_open || !lp_symlinks(SNUM(conn))) {
188 flags |= O_NOFOLLOW;
190 #endif
191 /* Setup a onefs-style smb_fname struct. */
192 status = onefs_stream_prep_smb_fname(talloc_tos(), smb_fname,
193 &smb_fname_onefs);
194 if (!NT_STATUS_IS_OK(status)) {
195 return status;
198 /* If it's a stream pass in the base_fd */
199 if ((conn->fs_capabilities & FILE_NAMED_STREAMS) &&
200 is_ntfs_stream_smb_fname(smb_fname_onefs)) {
201 SMB_ASSERT(fsp->base_fsp);
203 DEBUG(10, ("Opening a stream: base=%s(%d), stream=%s\n",
204 smb_fname_onefs->base_name, fsp->base_fsp->fh->fd,
205 smb_fname_onefs->stream_name));
207 base_fd = fsp->base_fsp->fh->fd;
210 fsp->fh->fd = onefs_sys_create_file(conn,
211 base_fd,
212 smb_fname_onefs->stream_name != NULL ?
213 smb_fname_onefs->stream_name :
214 smb_fname_onefs->base_name,
215 access_mask,
216 open_access_mask,
217 share_access,
218 create_options,
219 flags,
220 unx_mode,
221 oplock_request,
224 new_dos_attributes,
225 granted_oplock);
226 TALLOC_FREE(smb_fname_onefs);
228 if (fsp->fh->fd == -1) {
229 if (errno == EMFILE) {
230 static time_t last_warned = 0L;
232 if (time((time_t *) NULL) > last_warned) {
233 DEBUG(0, ("Too many open files, unable "
234 "to open more! smbd's max "
235 "open files = %d, also check "
236 "sysctl kern.maxfiles and "
237 "sysctl kern.maxfilesperproc\n",
238 lp_max_open_files()));
239 last_warned = time((time_t *) NULL);
243 status = map_nt_error_from_unix(errno);
244 DEBUG(3, ("Error opening file %s (%s) (local_flags=%d) "
245 "(flags=%d)\n", smb_fname_str_dbg(smb_fname),
246 strerror(errno), local_flags, flags));
247 return status;
250 if ((local_flags & O_CREAT) && !file_existed) {
252 /* Inherit the ACL if required */
253 if (lp_inherit_perms(SNUM(conn))) {
254 inherit_access_posix_acl(conn, parent_dir,
255 smb_fname->base_name, unx_mode);
258 /* Change the owner if required. */
259 if (lp_inherit_owner(SNUM(conn))) {
260 change_file_owner_to_parent(conn, parent_dir,
261 fsp);
264 notify_fname(conn, NOTIFY_ACTION_ADDED,
265 FILE_NOTIFY_CHANGE_FILE_NAME, smb_fname->base_name);
268 if (!file_existed) {
269 int ret;
271 if (fsp->fh->fd == -1) {
272 ret = SMB_VFS_STAT(conn, smb_fname);
273 } else {
274 ret = SMB_VFS_FSTAT(fsp, &smb_fname->st);
275 /* If we have an fd, this stat should succeed. */
276 if (ret == -1) {
277 DEBUG(0, ("Error doing fstat on open file %s "
278 "(%s)\n",
279 smb_fname_str_dbg(smb_fname),
280 strerror(errno) ));
284 /* For a non-io open, this stat failing means file not found. JRA */
285 if (ret == -1) {
286 status = map_nt_error_from_unix(errno);
287 fd_close(fsp);
288 return status;
293 * POSIX allows read-only opens of directories. We don't
294 * want to do this (we use a different code path for this)
295 * so catch a directory open and return an EISDIR. JRA.
298 if(S_ISDIR(smb_fname->st.st_ex_mode)) {
299 fd_close(fsp);
300 errno = EISDIR;
301 return NT_STATUS_FILE_IS_A_DIRECTORY;
304 fsp->mode = smb_fname->st.st_ex_mode;
305 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
306 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
307 fsp->file_pid = req ? req->smbpid : 0;
308 fsp->can_lock = True;
309 fsp->can_read = (access_mask & (FILE_READ_DATA)) ? True : False;
310 if (!CAN_WRITE(conn)) {
311 fsp->can_write = False;
312 } else {
313 fsp->can_write = (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ?
314 True : False;
316 fsp->print_file = NULL;
317 fsp->modified = False;
318 fsp->sent_oplock_break = NO_BREAK_SENT;
319 fsp->is_directory = False;
320 if (conn->aio_write_behind_list &&
321 is_in_path(smb_fname->base_name, conn->aio_write_behind_list,
322 conn->case_sensitive)) {
323 fsp->aio_write_behind = True;
326 fsp->wcp = NULL; /* Write cache pointer. */
328 DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
329 conn->server_info->unix_name,
330 smb_fname_str_dbg(smb_fname),
331 BOOLSTR(fsp->can_read), BOOLSTR(fsp->can_write),
332 conn->num_files_open));
334 errno = 0;
335 return NT_STATUS_OK;
338 /****************************************************************************
339 Handle the 1 second delay in returning a SHARING_VIOLATION error.
340 ****************************************************************************/
342 static void defer_open(struct share_mode_lock *lck,
343 struct timeval request_time,
344 struct timeval timeout,
345 struct smb_request *req,
346 struct deferred_open_record *state)
348 int i;
350 /* Paranoia check */
352 for (i=0; i<lck->num_share_modes; i++) {
353 struct share_mode_entry *e = &lck->share_modes[i];
355 if (!is_deferred_open_entry(e)) {
356 continue;
359 if (procid_is_me(&e->pid) && (e->op_mid == req->mid)) {
360 DEBUG(0, ("Trying to defer an already deferred "
361 "request: mid=%llu, exiting\n",
362 (unsigned long long)req->mid));
363 exit_server("attempt to defer a deferred request");
367 /* End paranoia check */
369 DEBUG(10,("defer_open_sharing_error: time [%u.%06u] adding deferred "
370 "open entry for mid %llu\n",
371 (unsigned int)request_time.tv_sec,
372 (unsigned int)request_time.tv_usec,
373 (unsigned long long)req->mid));
375 if (!push_deferred_open_message_smb(req, request_time, timeout,
376 state->id, (char *)state, sizeof(*state))) {
377 exit_server("push_deferred_open_message_smb failed");
379 add_deferred_open(lck, req->mid, request_time, state->id);
382 static void schedule_defer_open(struct share_mode_lock *lck,
383 struct timeval request_time,
384 struct smb_request *req)
386 struct deferred_open_record state;
388 /* This is a relative time, added to the absolute
389 request_time value to get the absolute timeout time.
390 Note that if this is the second or greater time we enter
391 this codepath for this particular request mid then
392 request_time is left as the absolute time of the *first*
393 time this request mid was processed. This is what allows
394 the request to eventually time out. */
396 struct timeval timeout;
398 /* Normally the smbd we asked should respond within
399 * OPLOCK_BREAK_TIMEOUT seconds regardless of whether
400 * the client did, give twice the timeout as a safety
401 * measure here in case the other smbd is stuck
402 * somewhere else. */
405 * On OneFS, the kernel will always send an oplock_revoked message
406 * before this timeout is hit.
408 timeout = timeval_set(OPLOCK_BREAK_TIMEOUT*10, 0);
410 /* Nothing actually uses state.delayed_for_oplocks
411 but it's handy to differentiate in debug messages
412 between a 30 second delay due to oplock break, and
413 a 1 second delay for share mode conflicts. */
415 state.delayed_for_oplocks = True;
416 state.failed = false;
417 state.id = lck->id;
419 if (!request_timed_out(request_time, timeout)) {
420 defer_open(lck, request_time, timeout, req, &state);
421 } else {
422 /* A delayed-for-oplocks deferred open timing out should only
423 * happen if there is a bug or extreme load, since we set the
424 * timeout to 300 seconds. */
425 DEBUG(0, ("Deferred open timeout! request_time=%d.%d, "
426 "mid=%d\n", request_time.tv_sec, request_time.tv_usec,
427 req->mid));
431 /****************************************************************************
432 Open a file with a share mode. Passed in an already created files_struct.
433 ****************************************************************************/
434 NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
435 struct smb_request *req,
436 struct smb_filename *smb_fname,
437 uint32 access_mask,
438 uint32 share_access,
439 uint32 create_disposition,
440 uint32 create_options,
441 uint32 new_dos_attributes,
442 int oplock_request,
443 uint32_t private_flags,
444 struct security_descriptor *sd,
445 files_struct *fsp,
446 int *pinfo,
447 struct onefs_fsp_data *fsp_data)
449 int flags=0;
450 int flags2=0;
451 bool file_existed = VALID_STAT(smb_fname->st);
452 bool def_acl = False;
453 bool posix_open = False;
454 bool new_file_created = False;
455 bool clear_ads = False;
456 struct file_id id;
457 mode_t new_unx_mode = (mode_t)0;
458 mode_t unx_mode = (mode_t)0;
459 int info;
460 uint32 existing_dos_attributes = 0;
461 struct timeval request_time = timeval_zero();
462 struct share_mode_lock *lck = NULL;
463 uint32 open_access_mask = access_mask;
464 NTSTATUS status;
465 int ret_flock;
466 char *parent_dir;
467 int granted_oplock;
468 uint64_t oplock_callback_id = 0;
469 uint32 createfile_attributes = 0;
471 ZERO_STRUCT(id);
473 if (conn->printer) {
475 * Printers are handled completely differently.
476 * Most of the passed parameters are ignored.
479 if (pinfo) {
480 *pinfo = FILE_WAS_CREATED;
483 DEBUG(10, ("onefs_open_file_ntcreate: printer open fname=%s\n",
484 smb_fname_str_dbg(smb_fname)));
486 return print_fsp_open(req, conn, smb_fname->base_name,
487 req->vuid, fsp);
490 if (!parent_dirname(talloc_tos(), smb_fname->base_name, &parent_dir,
491 NULL)) {
492 return NT_STATUS_NO_MEMORY;
495 if (new_dos_attributes & FILE_FLAG_POSIX_SEMANTICS) {
496 posix_open = True;
497 unx_mode = (mode_t)(new_dos_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
498 new_dos_attributes = 0;
499 } else {
500 /* We add aARCH to this as this mode is only used if the file is
501 * created new. */
502 unx_mode = unix_mode(conn, new_dos_attributes | aARCH,
503 smb_fname, parent_dir);
506 DEBUG(10,("onefs_open_file_ntcreate: fname=%s, dos_attrs=0x%x "
507 "access_mask=0x%x share_access=0x%x "
508 "create_disposition = 0x%x create_options=0x%x "
509 "unix mode=0%o oplock_request=0x%x\n",
510 smb_fname_str_dbg(smb_fname), new_dos_attributes,
511 access_mask, share_access, create_disposition,
512 create_options, unx_mode, oplock_request));
515 * Any non-stat-only open has the potential to contend oplocks, which
516 * means to avoid blocking in the kernel (which is unacceptable), the
517 * open must be deferred. In order to defer opens, req must not be
518 * NULL. The known cases of calling with a NULL req:
520 * 1. Open the base file of a stream: Always done stat-only
522 * 2. open_file_fchmod(), which is called from 3 places:
523 * A. try_chown: Posix acls only. Never called on onefs.
524 * B. set_ea_dos_attributes: Can't be called from onefs, because
525 * SMB_VFS_SETXATTR return ENOSYS.
526 * C. file_set_dos_mode: This would only happen if the "dos
527 * filemode" smb.conf parameter is set to yes. We ship with
528 * it off, but if a customer were to turn it on it would be
529 * bad.
531 if (req == NULL && !is_stat_open(access_mask) &&
532 !is_ntfs_stream_smb_fname(smb_fname)) {
533 smb_panic("NULL req on a non-stat-open!");
536 if ((req == NULL) && ((oplock_request & INTERNAL_OPEN_ONLY) == 0)) {
537 DEBUG(0, ("No smb request but not an internal only open!\n"));
538 return NT_STATUS_INTERNAL_ERROR;
542 * Only non-internal opens can be deferred at all
545 if (req) {
546 void *ptr;
547 if (get_deferred_open_message_state(req,
548 &request_time,
549 &ptr)) {
550 struct deferred_open_record *state = (struct deferred_open_record *)ptr;
552 /* Remember the absolute time of the original
553 request with this mid. We'll use it later to
554 see if this has timed out. */
556 /* Remove the deferred open entry under lock. */
557 remove_deferred_open_entry(state->id, req->mid);
559 /* Ensure we don't reprocess this message. */
560 remove_deferred_open_message_smb(req->mid);
563 * When receiving a semlock_async_failure message, the
564 * deferred open will be marked as "failed". Returning
565 * INTERNAL_ERROR.
567 if (state->failed) {
568 DEBUG(0, ("onefs_open_file_ntcreate: "
569 "semlock_async_failure detected!\n"));
570 return NT_STATUS_INTERNAL_ERROR;
575 status = check_name(conn, smb_fname->base_name);
576 if (!NT_STATUS_IS_OK(status)) {
577 return status;
580 if (!posix_open) {
581 new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
582 if (file_existed) {
583 existing_dos_attributes = dos_mode(conn, smb_fname);
587 /* Setup dos_attributes to be set by ifs_createfile */
588 if (lp_store_dos_attributes(SNUM(conn))) {
589 createfile_attributes = (new_dos_attributes | aARCH) &
590 ~(FILE_ATTRIBUTE_NONINDEXED | FILE_ATTRIBUTE_COMPRESSED);
593 /* Ignore oplock requests if oplocks are disabled. */
594 if (!lp_oplocks(SNUM(conn)) || global_client_failed_oplock_break ||
595 IS_VETO_OPLOCK_PATH(conn, smb_fname->base_name)) {
596 /* Mask off everything except the private Samba bits. */
597 oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
600 /* this is for OS/2 long file names - say we don't support them */
601 if (!lp_posix_pathnames() && strstr(smb_fname->base_name,".+,;=[].")) {
602 /* OS/2 Workplace shell fix may be main code stream in a later
603 * release. */
604 DEBUG(5,("onefs_open_file_ntcreate: OS/2 long filenames are "
605 "not supported.\n"));
606 if (use_nt_status()) {
607 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
609 return NT_STATUS_DOS(ERRDOS, ERRcannotopen);
612 switch( create_disposition ) {
614 * Currently we're using FILE_SUPERSEDE as the same as
615 * FILE_OVERWRITE_IF but they really are
616 * different. FILE_SUPERSEDE deletes an existing file
617 * (requiring delete access) then recreates it.
619 case FILE_SUPERSEDE:
621 * @todo: Clear all file attributes?
622 * http://www.osronline.com/article.cfm?article=302
623 * create if not exist, trunc if exist
625 * If file exists replace/overwrite. If file doesn't
626 * exist create.
628 flags2 |= (O_CREAT | O_TRUNC);
629 clear_ads = true;
630 break;
632 case FILE_OVERWRITE_IF:
633 /* If file exists replace/overwrite. If file doesn't
634 * exist create. */
635 flags2 |= (O_CREAT | O_TRUNC);
636 clear_ads = true;
637 break;
639 case FILE_OPEN:
640 /* If file exists open. If file doesn't exist error. */
641 if (!file_existed) {
642 DEBUG(5,("onefs_open_file_ntcreate: FILE_OPEN "
643 "requested for file %s and file "
644 "doesn't exist.\n",
645 smb_fname_str_dbg(smb_fname)));
646 errno = ENOENT;
647 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
649 break;
651 case FILE_OVERWRITE:
652 /* If file exists overwrite. If file doesn't exist
653 * error. */
654 if (!file_existed) {
655 DEBUG(5, ("onefs_open_file_ntcreate: "
656 "FILE_OVERWRITE requested for file "
657 "%s and file doesn't exist.\n",
658 smb_fname_str_dbg(smb_fname)));
659 errno = ENOENT;
660 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
662 flags2 |= O_TRUNC;
663 clear_ads = true;
664 break;
666 case FILE_CREATE:
667 /* If file exists error. If file doesn't exist
668 * create. */
669 if (file_existed) {
670 DEBUG(5, ("onefs_open_file_ntcreate: "
671 "FILE_CREATE requested for file %s "
672 "and file already exists.\n",
673 smb_fname_str_dbg(smb_fname)));
674 if (S_ISDIR(smb_fname->st.st_ex_mode)) {
675 errno = EISDIR;
676 } else {
677 errno = EEXIST;
679 return map_nt_error_from_unix(errno);
681 flags2 |= (O_CREAT|O_EXCL);
682 break;
684 case FILE_OPEN_IF:
685 /* If file exists open. If file doesn't exist
686 * create. */
687 flags2 |= O_CREAT;
688 break;
690 default:
691 return NT_STATUS_INVALID_PARAMETER;
694 /* Match attributes on file exists and overwrite. */
695 if (!posix_open && file_existed &&
696 ((create_disposition == FILE_OVERWRITE) ||
697 (create_disposition == FILE_OVERWRITE_IF))) {
698 if (!open_match_attributes(conn, existing_dos_attributes,
699 new_dos_attributes,
700 smb_fname->st.st_ex_mode,
701 unx_mode, &new_unx_mode)) {
702 DEBUG(5, ("onefs_open_file_ntcreate: attributes "
703 "missmatch for file %s (%x %x) (0%o, 0%o)\n",
704 smb_fname_str_dbg(smb_fname),
705 existing_dos_attributes,
706 new_dos_attributes,
707 (unsigned int)smb_fname->st.st_ex_mode,
708 (unsigned int)unx_mode ));
709 errno = EACCES;
710 return NT_STATUS_ACCESS_DENIED;
715 * OneFS understands MAXIMUM_ALLOWED_ACCESS, so only hack the
716 * access_mask, but leave the MAA for the actual open in
717 * open_access_mask.
719 open_access_mask = access_mask;
720 if (open_access_mask & MAXIMUM_ALLOWED_ACCESS) {
721 access_mask |= FILE_GENERIC_ALL;
724 /* Convert GENERIC bits to specific bits. */
725 se_map_generic(&access_mask, &file_generic_mapping);
726 se_map_generic(&open_access_mask, &file_generic_mapping);
728 if ((flags2 & O_TRUNC) || (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE)) {
729 /* This will cause oplock breaks. */
730 open_access_mask |= FILE_WRITE_DATA;
733 DEBUG(10, ("onefs_open_file_ntcreate: fname=%s, after mapping "
734 "open_access_mask=%#x, access_mask=0x%x\n",
735 smb_fname_str_dbg(smb_fname), open_access_mask,
736 access_mask));
739 * Note that we ignore the append flag as append does not
740 * mean the same thing under DOS and Unix.
743 if ((access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ||
744 (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE)) {
747 * DENY_DOS opens are always underlying read-write on the
748 * file handle, no matter what the requested access mask
749 * says. Stock samba just sets the flags, but since
750 * ifs_createfile uses the access_mask, it must be updated as
751 * well. This allows BASE-DENY* to pass.
753 if (create_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) {
755 DEBUG(10,("onefs_open_file_ntcreate: deny_dos: "
756 "Adding O_RDWR to flags "
757 "(0x%x) and some READ bits to "
758 "open_access_mask (0x%x)\n",
759 flags, open_access_mask));
761 flags = O_RDWR;
762 open_access_mask |= (FILE_READ_ATTRIBUTES |
763 FILE_READ_DATA | FILE_READ_EA | FILE_EXECUTE);
765 } else if (access_mask & (FILE_READ_ATTRIBUTES |
766 FILE_READ_DATA |
767 FILE_READ_EA |
768 FILE_EXECUTE)) {
769 flags = O_RDWR;
770 } else {
771 flags = O_WRONLY;
773 } else {
774 flags = O_RDONLY;
777 /* Currently we only look at FILE_WRITE_THROUGH for create options. */
778 #if defined(O_SYNC)
779 if ((create_options & FILE_WRITE_THROUGH) &&
780 lp_strict_sync(SNUM(conn))) {
781 flags2 |= O_SYNC;
783 #endif /* O_SYNC */
785 if (posix_open && (access_mask & FILE_APPEND_DATA)) {
786 flags2 |= O_APPEND;
789 if (!posix_open && !CAN_WRITE(conn)) {
791 * We should really return a permission denied error if either
792 * O_CREAT or O_TRUNC are set, but for compatibility with
793 * older versions of Samba we just AND them out.
795 flags2 &= ~(O_CREAT|O_TRUNC);
797 /* Deny DELETE_ACCESS explicitly if the share is read only. */
798 if (access_mask & DELETE_ACCESS) {
799 return map_nt_error_from_unix(EACCES);
803 /* Ensure we can't write on a read-only share or file. */
804 if (flags != O_RDONLY && file_existed &&
805 (!CAN_WRITE(conn) || IS_DOS_READONLY(existing_dos_attributes))) {
806 DEBUG(5, ("onefs_open_file_ntcreate: write access requested "
807 "for file %s on read only %s\n",
808 smb_fname_str_dbg(smb_fname),
809 !CAN_WRITE(conn) ? "share" : "file" ));
810 errno = EACCES;
811 return NT_STATUS_ACCESS_DENIED;
814 DEBUG(10, ("fsp = %p\n", fsp));
816 fsp->share_access = share_access;
817 fsp->fh->private_options = private_flags;
818 fsp->access_mask = open_access_mask; /* We change this to the
819 * requested access_mask after
820 * the open is done. */
821 fsp->posix_open = posix_open;
823 /* Ensure no SAMBA_PRIVATE bits can be set. */
824 fsp->oplock_type = (oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK);
826 if (timeval_is_zero(&request_time)) {
827 request_time = fsp->open_time;
830 if (file_existed) {
831 struct timespec old_write_time = smb_fname->st.st_ex_mtime;
832 id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
834 lck = get_share_mode_lock(talloc_tos(), id,
835 conn->connectpath,
836 smb_fname, &old_write_time);
838 if (lck == NULL) {
839 DEBUG(0, ("Could not get share mode lock\n"));
840 return NT_STATUS_SHARING_VIOLATION;
843 if (lck->delete_on_close) {
844 /* DELETE_PENDING is not deferred for a second */
845 TALLOC_FREE(lck);
846 return NT_STATUS_DELETE_PENDING;
850 SMB_ASSERT(!file_existed || (lck != NULL));
853 * Ensure we pay attention to default ACLs on directories. May be
854 * neccessary depending on ACL policies.
856 if ((flags2 & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
857 (def_acl = directory_has_default_acl(conn, parent_dir))) {
858 unx_mode = 0777;
861 DEBUG(4,("calling onefs_open_file with flags=0x%X flags2=0x%X "
862 "mode=0%o, access_mask = 0x%x, open_access_mask = 0x%x\n",
863 (unsigned int)flags, (unsigned int)flags2,
864 (unsigned int)unx_mode, (unsigned int)access_mask,
865 (unsigned int)open_access_mask));
868 * Since the open is guaranteed to be stat only if req == NULL, a
869 * callback record is only needed if req != NULL.
871 if (req) {
872 SMB_ASSERT(fsp_data);
873 oplock_callback_id = onefs_oplock_wait_record(req->mid);
874 if (oplock_callback_id == 0) {
875 return NT_STATUS_NO_MEMORY;
877 } else {
879 * It is also already asserted it's either a stream or a
880 * stat-only open at this point.
882 SMB_ASSERT(fsp->oplock_type == NO_OPLOCK);
884 /* The kernel and Samba's version of stat-only differs
885 * slightly: The kernel doesn't think its stat-only if we're
886 * truncating. We'd better have a req in order to defer the
887 * open. */
888 SMB_ASSERT(!((flags|flags2) & O_TRUNC));
891 /* Do the open. */
892 status = onefs_open_file(fsp,
893 conn,
894 req,
895 parent_dir,
896 smb_fname,
897 flags|flags2,
898 unx_mode,
899 access_mask,
900 open_access_mask,
901 fsp->oplock_type,
902 oplock_callback_id,
903 share_access,
904 create_options,
905 createfile_attributes,
907 &granted_oplock);
909 if (!NT_STATUS_IS_OK(status)) {
911 /* OneFS Oplock Handling */
912 if (errno == EINPROGRESS) {
914 /* If we get EINPROGRESS, the kernel will send us an
915 * asynchronous semlock event back. Ensure we can defer
916 * the open, by asserting req. */
917 SMB_ASSERT(req);
919 if (lck == NULL) {
921 * We hit the race that when we did the stat
922 * on the file it did not exist, and someone
923 * has created it in between the stat and the
924 * open_file() call. Defer our open waiting,
925 * to break the oplock of the first opener.
928 struct timespec old_write_time;
930 DEBUG(3, ("Someone created file %s with an "
931 "oplock after we looked: Retrying\n",
932 smb_fname_str_dbg(smb_fname)));
934 * We hit the race that when we did the stat
935 * on the file it did not exist, and someone
936 * has created it in between the stat and the
937 * open_file() call. Just retry immediately.
939 id = vfs_file_id_from_sbuf(conn,
940 &smb_fname->st);
941 if (!(lck = get_share_mode_lock(talloc_tos(),
942 id, conn->connectpath, smb_fname,
943 &old_write_time))) {
945 * Emergency exit
947 DEBUG(0, ("onefs_open_file_ntcreate: "
948 "Could not get share mode "
949 "lock for %s\n",
950 smb_fname_str_dbg(smb_fname)));
951 status = NT_STATUS_SHARING_VIOLATION;
953 /* XXXZLK: This will cause us to get a
954 * semlock event when we aren't
955 * expecting one. */
956 goto cleanup_destroy;
959 schedule_defer_open(lck, request_time, req);
960 goto cleanup;
962 /* Waiting for an oplock */
963 DEBUG(5,("Async createfile because a client has an "
964 "oplock on %s\n",
965 smb_fname_str_dbg(smb_fname)));
967 SMB_ASSERT(req);
968 schedule_defer_open(lck, request_time, req);
969 goto cleanup;
972 /* Check for a sharing violation */
973 if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
974 uint32 can_access_mask;
975 bool can_access = True;
977 /* If we raced on open we may not have a valid file_id
978 * or stat buf. Get them again. */
979 if (SMB_VFS_STAT(conn, fname, psbuf) == -1) {
980 DEBUG(0,("Error doing stat on file %s "
981 "(%s)\n", fname, strerror(errno)));
982 status = NT_STATUS_SHARING_VIOLATION;
983 goto cleanup_destroy;
985 id = vfs_file_id_from_sbuf(conn, psbuf);
987 /* Check if this can be done with the deny_dos and fcb
988 * calls. */
990 /* Try to find dup fsp if possible. */
991 if (private_flags &
992 (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS|
993 NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) {
995 if (req == NULL) {
996 DEBUG(0, ("DOS open without an SMB "
997 "request!\n"));
998 status = NT_STATUS_INTERNAL_ERROR;
999 goto cleanup_destroy;
1002 /* Use the client requested access mask here,
1003 * not the one we open with. */
1004 status = fcb_or_dos_open(req,
1005 conn,
1006 fsp,
1007 smb_fname,
1009 req->smbpid,
1010 req->vuid,
1011 access_mask,
1012 share_access,
1013 create_options);
1015 if (NT_STATUS_IS_OK(status)) {
1016 if (pinfo) {
1017 *pinfo = FILE_WAS_OPENED;
1019 status = NT_STATUS_OK;
1020 goto cleanup;
1025 * This next line is a subtlety we need for
1026 * MS-Access. If a file open will fail due to share
1027 * permissions and also for security (access) reasons,
1028 * we need to return the access failed error, not the
1029 * share error. We can't open the file due to kernel
1030 * oplock deadlock (it's possible we failed above on
1031 * the open_mode_check()) so use a userspace check.
1034 if (flags & O_RDWR) {
1035 can_access_mask = FILE_READ_DATA|FILE_WRITE_DATA;
1036 } else if (flags & O_WRONLY) {
1037 can_access_mask = FILE_WRITE_DATA;
1038 } else {
1039 can_access_mask = FILE_READ_DATA;
1042 if (((can_access_mask & FILE_WRITE_DATA) &&
1043 !CAN_WRITE(conn)) ||
1044 !can_access_file_data(conn, smb_fname,
1045 can_access_mask)) {
1046 can_access = False;
1050 * If we're returning a share violation, ensure we
1051 * cope with the braindead 1 second delay.
1053 if (!(oplock_request & INTERNAL_OPEN_ONLY) &&
1054 lp_defer_sharing_violations()) {
1055 struct timeval timeout;
1056 struct deferred_open_record state;
1057 int timeout_usecs;
1059 /* this is a hack to speed up torture tests
1060 in 'make test' */
1061 timeout_usecs = lp_parm_int(SNUM(conn),
1062 "smbd","sharedelay",
1063 SHARING_VIOLATION_USEC_WAIT);
1065 /* This is a relative time, added to the
1066 absolute request_time value to get the
1067 absolute timeout time. Note that if this
1068 is the second or greater time we enter this
1069 codepath for this particular request mid
1070 then request_time is left as the absolute
1071 time of the *first* time this request mid
1072 was processed. This is what allows the
1073 request to eventually time out. */
1075 timeout = timeval_set(0, timeout_usecs);
1077 /* Nothing actually uses
1078 state.delayed_for_oplocks but it's handy to
1079 differentiate in debug messages between a
1080 30 second delay due to oplock break, and a
1081 1 second delay for share mode conflicts. */
1083 state.delayed_for_oplocks = False;
1084 state.id = id;
1085 state.failed = false;
1088 * We hit the race that when we did the stat
1089 * on the file it did not exist, and someone
1090 * has created it in between the stat and the
1091 * open_file() call. Retrieve the share_mode
1092 * lock on the newly opened file so we can
1093 * defer our request.
1095 if (lck == NULL) {
1096 struct timespec old_write_time;
1097 old_write_time = get_mtimespec(psbuf);
1099 lck = get_share_mode_lock(talloc_tos(),
1100 id, conn->connectpath, fname,
1101 &old_write_time);
1102 if (lck == NULL) {
1103 DEBUG(0,
1104 ("onefs_open_file_ntcreate:"
1105 " Could not get share "
1106 "mode lock for %s\n",
1107 fname));
1108 /* This will cause us to return
1109 * immediately skipping the
1110 * the 1 second delay, which
1111 * isn't a big deal */
1112 status = NT_STATUS_SHARING_VIOLATION;
1113 goto cleanup_destroy;
1117 if ((req != NULL) &&
1118 !request_timed_out(request_time, timeout))
1120 defer_open(lck, request_time, timeout,
1121 req, &state);
1125 if (can_access) {
1127 * We have detected a sharing violation here
1128 * so return the correct error code
1130 status = NT_STATUS_SHARING_VIOLATION;
1131 } else {
1132 status = NT_STATUS_ACCESS_DENIED;
1135 goto cleanup_destroy;
1139 * Normal error, for example EACCES
1141 cleanup_destroy:
1142 if (oplock_callback_id != 0) {
1143 destroy_onefs_callback_record(oplock_callback_id);
1145 cleanup:
1146 TALLOC_FREE(lck);
1147 return status;
1150 fsp->oplock_type = granted_oplock;
1152 if (oplock_callback_id != 0) {
1153 onefs_set_oplock_callback(oplock_callback_id, fsp);
1154 fsp_data->oplock_callback_id = oplock_callback_id;
1155 } else {
1156 SMB_ASSERT(fsp->oplock_type == NO_OPLOCK);
1159 if (!file_existed) {
1160 struct timespec old_write_time = smb_fname->st.st_ex_mtime;
1162 * Deal with the race condition where two smbd's detect the
1163 * file doesn't exist and do the create at the same time. One
1164 * of them will win and set a share mode, the other (ie. this
1165 * one) should check if the requested share mode for this
1166 * create is allowed.
1170 * Now the file exists and fsp is successfully opened,
1171 * fsp->file_id is valid and should replace the
1172 * dev=0, inode=0 from a non existent file. Spotted by
1173 * Nadav Danieli <nadavd@exanet.com>. JRA.
1176 id = fsp->file_id;
1178 lck = get_share_mode_lock(talloc_tos(), id,
1179 conn->connectpath,
1180 smb_fname, &old_write_time);
1182 if (lck == NULL) {
1183 DEBUG(0, ("onefs_open_file_ntcreate: Could not get "
1184 "share mode lock for %s\n",
1185 smb_fname_str_dbg(smb_fname)));
1186 fd_close(fsp);
1187 return NT_STATUS_SHARING_VIOLATION;
1190 if (lck->delete_on_close) {
1191 status = NT_STATUS_DELETE_PENDING;
1194 if (!NT_STATUS_IS_OK(status)) {
1195 struct deferred_open_record state;
1197 fd_close(fsp);
1199 state.delayed_for_oplocks = False;
1200 state.id = id;
1202 /* Do it all over again immediately. In the second
1203 * round we will find that the file existed and handle
1204 * the DELETE_PENDING and FCB cases correctly. No need
1205 * to duplicate the code here. Essentially this is a
1206 * "goto top of this function", but don't tell
1207 * anybody... */
1209 if (req != NULL) {
1210 defer_open(lck, request_time, timeval_zero(),
1211 req, &state);
1213 TALLOC_FREE(lck);
1214 return status;
1218 * We exit this block with the share entry *locked*.....
1223 SMB_ASSERT(lck != NULL);
1225 /* Delete streams if create_disposition requires it */
1226 if (file_existed && clear_ads &&
1227 !is_ntfs_stream_smb_fname(smb_fname)) {
1228 status = delete_all_streams(conn, smb_fname->base_name);
1229 if (!NT_STATUS_IS_OK(status)) {
1230 TALLOC_FREE(lck);
1231 fd_close(fsp);
1232 return status;
1236 /* note that we ignore failure for the following. It is
1237 basically a hack for NFS, and NFS will never set one of
1238 these only read them. Nobody but Samba can ever set a deny
1239 mode and we have already checked our more authoritative
1240 locking database for permission to set this deny mode. If
1241 the kernel refuses the operations then the kernel is wrong.
1242 note that GPFS supports it as well - jmcd */
1244 if (fsp->fh->fd != -1) {
1245 ret_flock = SMB_VFS_KERNEL_FLOCK(fsp, share_access, access_mask);
1246 if(ret_flock == -1 ){
1248 TALLOC_FREE(lck);
1249 fd_close(fsp);
1250 return NT_STATUS_SHARING_VIOLATION;
1255 * At this point onwards, we can guarentee that the share entry
1256 * is locked, whether we created the file or not, and that the
1257 * deny mode is compatible with all current opens.
1261 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
1263 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
1265 if (file_existed) {
1266 /* stat opens on existing files don't get oplocks. */
1267 if (is_stat_open(open_access_mask)) {
1268 fsp->oplock_type = NO_OPLOCK;
1271 if (!(flags2 & O_TRUNC)) {
1272 info = FILE_WAS_OPENED;
1273 } else {
1274 info = FILE_WAS_OVERWRITTEN;
1276 } else {
1277 info = FILE_WAS_CREATED;
1280 if (pinfo) {
1281 *pinfo = info;
1285 * Setup the oplock info in both the shared memory and
1286 * file structs.
1289 if ((fsp->oplock_type != NO_OPLOCK) &&
1290 (fsp->oplock_type != FAKE_LEVEL_II_OPLOCK)) {
1291 if (!set_file_oplock(fsp, fsp->oplock_type)) {
1292 /* Could not get the kernel oplock */
1293 fsp->oplock_type = NO_OPLOCK;
1297 if (fsp->oplock_type == LEVEL_II_OPLOCK &&
1298 (!lp_level2_oplocks(SNUM(conn)) ||
1299 !(global_client_caps & CAP_LEVEL_II_OPLOCKS))) {
1301 DEBUG(5, ("Downgrading level2 oplock on open "
1302 "because level2 oplocks = off\n"));
1304 release_file_oplock(fsp);
1307 if (info == FILE_WAS_OVERWRITTEN || info == FILE_WAS_CREATED ||
1308 info == FILE_WAS_SUPERSEDED) {
1309 new_file_created = True;
1312 set_share_mode(lck, fsp, conn->server_info->utok.uid, 0,
1313 fsp->oplock_type);
1315 /* Handle strange delete on close create semantics. */
1316 if (create_options & FILE_DELETE_ON_CLOSE) {
1317 status = can_set_delete_on_close(fsp, new_dos_attributes);
1319 if (!NT_STATUS_IS_OK(status)) {
1320 /* Remember to delete the mode we just added. */
1321 del_share_mode(lck, fsp);
1322 TALLOC_FREE(lck);
1323 fd_close(fsp);
1324 return status;
1326 /* Note that here we set the *inital* delete on close flag,
1327 not the regular one. The magic gets handled in close. */
1328 fsp->initial_delete_on_close = True;
1332 * Take care of inherited ACLs on created files - if default ACL not
1333 * selected.
1334 * May be necessary depending on acl policies.
1336 if (!posix_open && !file_existed && !def_acl &&
1337 !(VALID_STAT(smb_fname->st) &&
1338 (smb_fname->st.st_ex_flags & SF_HASNTFSACL))) {
1340 int saved_errno = errno; /* We might get ENOSYS in the next
1341 * call.. */
1343 if (SMB_VFS_FCHMOD_ACL(fsp, unx_mode) == -1 &&
1344 errno == ENOSYS) {
1345 errno = saved_errno; /* Ignore ENOSYS */
1348 } else if (new_unx_mode) {
1350 int ret = -1;
1352 /* Attributes need changing. File already existed. */
1355 int saved_errno = errno; /* We might get ENOSYS in the
1356 * next call.. */
1357 ret = SMB_VFS_FCHMOD_ACL(fsp, new_unx_mode);
1359 if (ret == -1 && errno == ENOSYS) {
1360 errno = saved_errno; /* Ignore ENOSYS */
1361 } else {
1362 DEBUG(5, ("onefs_open_file_ntcreate: reset "
1363 "attributes of file %s to 0%o\n",
1364 smb_fname_str_dbg(smb_fname),
1365 (unsigned int)new_unx_mode));
1366 ret = 0; /* Don't do the fchmod below. */
1370 if ((ret == -1) &&
1371 (SMB_VFS_FCHMOD(fsp, new_unx_mode) == -1))
1372 DEBUG(5, ("onefs_open_file_ntcreate: failed to reset "
1373 "attributes of file %s to 0%o\n",
1374 smb_fname_str_dbg(smb_fname),
1375 (unsigned int)new_unx_mode));
1378 /* If this is a successful open, we must remove any deferred open
1379 * records. */
1380 if (req != NULL) {
1381 del_deferred_open_entry(lck, req->mid);
1383 TALLOC_FREE(lck);
1385 return NT_STATUS_OK;
1389 /****************************************************************************
1390 Open a directory from an NT SMB call.
1391 ****************************************************************************/
1392 static NTSTATUS onefs_open_directory(connection_struct *conn,
1393 struct smb_request *req,
1394 struct smb_filename *smb_dname,
1395 uint32 access_mask,
1396 uint32 share_access,
1397 uint32 create_disposition,
1398 uint32 create_options,
1399 uint32 file_attributes,
1400 struct security_descriptor *sd,
1401 files_struct **result,
1402 int *pinfo)
1404 files_struct *fsp = NULL;
1405 struct share_mode_lock *lck = NULL;
1406 NTSTATUS status;
1407 struct timespec mtimespec;
1408 int info = 0;
1409 char *parent_dir;
1410 bool posix_open = false;
1411 uint32 create_flags = 0;
1412 uint32 mode = lp_dir_mask(SNUM(conn));
1414 DEBUG(5, ("onefs_open_directory: opening directory %s, "
1415 "access_mask = 0x%x, "
1416 "share_access = 0x%x create_options = 0x%x, "
1417 "create_disposition = 0x%x, file_attributes = 0x%x\n",
1418 smb_fname_str_dbg(smb_dname), (unsigned int)access_mask,
1419 (unsigned int)share_access, (unsigned int)create_options,
1420 (unsigned int)create_disposition,
1421 (unsigned int)file_attributes));
1423 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
1424 (conn->fs_capabilities & FILE_NAMED_STREAMS) &&
1425 is_ntfs_stream_smb_fname(smb_dname)) {
1426 DEBUG(2, ("onefs_open_directory: %s is a stream name!\n",
1427 smb_fname_str_dbg(smb_dname)));
1428 return NT_STATUS_NOT_A_DIRECTORY;
1431 switch (create_disposition) {
1432 case FILE_OPEN:
1433 /* If directory exists open. If directory doesn't
1434 * exist error. */
1435 create_flags = 0;
1436 info = FILE_WAS_OPENED;
1437 break;
1438 case FILE_CREATE:
1439 /* If directory exists error. If directory doesn't
1440 * exist create. */
1441 create_flags = O_CREAT | O_EXCL;
1442 info = FILE_WAS_CREATED;
1443 break;
1444 case FILE_OPEN_IF:
1445 /* If directory exists open. If directory doesn't
1446 * exist create. */
1448 /* Note: in order to return whether the directory was
1449 * opened or created, we first try to open and then try
1450 * to create. */
1451 create_flags = 0;
1452 info = FILE_WAS_OPENED;
1453 break;
1454 case FILE_SUPERSEDE:
1455 case FILE_OVERWRITE:
1456 case FILE_OVERWRITE_IF:
1457 default:
1458 DEBUG(5, ("onefs_open_directory: invalid "
1459 "create_disposition 0x%x for directory %s\n",
1460 (unsigned int)create_disposition,
1461 smb_fname_str_dbg(smb_dname)));
1462 return NT_STATUS_INVALID_PARAMETER;
1466 * Check for write access to the share. Done in mkdir_internal() in
1467 * mainline samba.
1469 if (!CAN_WRITE(conn) && (create_flags & O_CREAT)) {
1470 return NT_STATUS_ACCESS_DENIED;
1473 /* Get parent dirname */
1474 if (!parent_dirname(talloc_tos(), smb_dname->base_name, &parent_dir,
1475 NULL)) {
1476 return NT_STATUS_NO_MEMORY;
1479 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
1480 posix_open = true;
1481 mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
1482 file_attributes = 0;
1483 } else {
1484 mode = unix_mode(conn, aDIR, smb_dname, parent_dir);
1488 * The NONINDEXED and COMPRESSED bits seem to always be cleared on
1489 * directories, no matter if you specify that they should be set.
1491 file_attributes &=
1492 ~(FILE_ATTRIBUTE_NONINDEXED | FILE_ATTRIBUTE_COMPRESSED);
1494 status = file_new(req, conn, &fsp);
1495 if(!NT_STATUS_IS_OK(status)) {
1496 return status;
1500 * Actual open with retry magic to handle FILE_OPEN_IF which is
1501 * unique because the kernel won't tell us if the file was opened or
1502 * created.
1504 retry_open:
1505 fsp->fh->fd = onefs_sys_create_file(conn,
1507 smb_dname->base_name,
1508 access_mask,
1509 access_mask,
1510 share_access,
1511 create_options,
1512 create_flags | O_DIRECTORY,
1513 mode,
1517 file_attributes,
1518 NULL);
1520 if (fsp->fh->fd == -1) {
1521 DEBUG(3, ("Error opening %s. Errno=%d (%s).\n",
1522 smb_fname_str_dbg(smb_dname), errno,
1523 strerror(errno)));
1524 SMB_ASSERT(errno != EINPROGRESS);
1526 if (create_disposition == FILE_OPEN_IF) {
1527 if (errno == ENOENT) {
1528 /* Try again, creating it this time. */
1529 create_flags = O_CREAT | O_EXCL;
1530 info = FILE_WAS_CREATED;
1531 goto retry_open;
1532 } else if (errno == EEXIST) {
1533 /* Uggh. Try again again. */
1534 create_flags = 0;
1535 info = FILE_WAS_OPENED;
1536 goto retry_open;
1540 /* Error cases below: */
1541 file_free(req, fsp);
1543 if ((errno == ENOENT) && (create_disposition == FILE_OPEN)) {
1544 DEBUG(5, ("onefs_open_directory: FILE_OPEN requested "
1545 "for directory %s and it doesn't "
1546 "exist.\n", smb_fname_str_dbg(smb_dname)));
1547 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1548 } else if ((errno == EEXIST) &&
1549 (create_disposition == FILE_CREATE)) {
1550 DEBUG(5, ("onefs_open_directory: FILE_CREATE "
1551 "requested for directory %s and it "
1552 "already exists.\n",
1553 smb_fname_str_dbg(smb_dname)));
1554 return NT_STATUS_OBJECT_NAME_COLLISION;
1555 } else if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
1556 /* Catch sharing violations. */
1557 return NT_STATUS_SHARING_VIOLATION;
1560 return map_nt_error_from_unix(errno);
1563 if (info == FILE_WAS_CREATED) {
1565 /* Pulled from mkdir_internal() */
1566 if (SMB_VFS_LSTAT(conn, smb_dname) == -1) {
1567 DEBUG(2, ("Could not stat directory '%s' just "
1568 "created: %s\n",
1569 smb_fname_str_dbg(smb_dname),
1570 strerror(errno)));
1571 return map_nt_error_from_unix(errno);
1574 if (!S_ISDIR(smb_dname->st.st_ex_mode)) {
1575 DEBUG(0, ("Directory just '%s' created is not a "
1576 "directory\n",
1577 smb_fname_str_dbg(smb_dname)));
1578 return NT_STATUS_ACCESS_DENIED;
1581 if (!posix_open) {
1583 * Check if high bits should have been set, then (if
1584 * bits are missing): add them. Consider bits
1585 * automagically set by UNIX, i.e. SGID bit from
1586 * parent dir.
1588 if (mode & ~(S_IRWXU|S_IRWXG|S_IRWXO) &&
1589 (mode & ~smb_dname->st.st_ex_mode)) {
1590 SMB_VFS_CHMOD(conn, smb_dname->base_name,
1591 (smb_dname->st.st_ex_mode |
1592 (mode & ~smb_dname->st.st_ex_mode)));
1596 /* Change the owner if required. */
1597 if (lp_inherit_owner(SNUM(conn))) {
1598 change_dir_owner_to_parent(conn, parent_dir,
1599 smb_dname->base_name,
1600 &smb_dname->st);
1603 notify_fname(conn, NOTIFY_ACTION_ADDED,
1604 FILE_NOTIFY_CHANGE_DIR_NAME,
1605 smb_dname->base_name);
1608 /* Stat the fd for Samba bookkeeping. */
1609 if(SMB_VFS_FSTAT(fsp, &smb_dname->st) != 0) {
1610 fd_close(fsp);
1611 file_free(req, fsp);
1612 return map_nt_error_from_unix(errno);
1615 /* Setup the files_struct for it. */
1616 fsp->mode = smb_dname->st.st_ex_mode;
1617 fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_dname->st);
1618 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
1619 fsp->file_pid = req ? req->smbpid : 0;
1620 fsp->can_lock = False;
1621 fsp->can_read = False;
1622 fsp->can_write = False;
1624 fsp->share_access = share_access;
1625 fsp->fh->private_options = 0;
1627 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
1629 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
1630 fsp->print_file = NULL;
1631 fsp->modified = False;
1632 fsp->oplock_type = NO_OPLOCK;
1633 fsp->sent_oplock_break = NO_BREAK_SENT;
1634 fsp->is_directory = True;
1635 fsp->posix_open = posix_open;
1637 status = fsp_set_smb_fname(fsp, smb_dname);
1638 if (!NT_STATUS_IS_OK(status)) {
1639 fd_close(fsp);
1640 file_free(req, fsp);
1641 return status;
1644 mtimespec = smb_dname->st.st_ex_mtime;
1647 * Still set the samba share mode lock for correct delete-on-close
1648 * semantics and to make smbstatus more useful.
1650 lck = get_share_mode_lock(talloc_tos(), fsp->file_id,
1651 conn->connectpath, smb_dname, &mtimespec);
1653 if (lck == NULL) {
1654 DEBUG(0, ("onefs_open_directory: Could not get share mode "
1655 "lock for %s\n", smb_fname_str_dbg(smb_dname)));
1656 fd_close(fsp);
1657 file_free(req, fsp);
1658 return NT_STATUS_SHARING_VIOLATION;
1661 if (lck->delete_on_close) {
1662 TALLOC_FREE(lck);
1663 fd_close(fsp);
1664 file_free(req, fsp);
1665 return NT_STATUS_DELETE_PENDING;
1668 set_share_mode(lck, fsp, conn->server_info->utok.uid, 0, NO_OPLOCK);
1671 * For directories the delete on close bit at open time seems
1672 * always to be honored on close... See test 19 in Samba4 BASE-DELETE.
1674 if (create_options & FILE_DELETE_ON_CLOSE) {
1675 status = can_set_delete_on_close(fsp, 0);
1676 if (!NT_STATUS_IS_OK(status) &&
1677 !NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
1678 TALLOC_FREE(lck);
1679 fd_close(fsp);
1680 file_free(req, fsp);
1681 return status;
1684 if (NT_STATUS_IS_OK(status)) {
1685 /* Note that here we set the *inital* delete on close flag,
1686 not the regular one. The magic gets handled in close. */
1687 fsp->initial_delete_on_close = True;
1691 TALLOC_FREE(lck);
1693 if (pinfo) {
1694 *pinfo = info;
1697 *result = fsp;
1698 return NT_STATUS_OK;
1702 * Wrapper around onefs_open_file_ntcreate and onefs_open_directory.
1704 static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
1705 struct smb_request *req,
1706 struct smb_filename *smb_fname,
1707 uint32_t access_mask,
1708 uint32_t share_access,
1709 uint32_t create_disposition,
1710 uint32_t create_options,
1711 uint32_t file_attributes,
1712 uint32_t oplock_request,
1713 uint64_t allocation_size,
1714 uint32_t private_flags,
1715 struct security_descriptor *sd,
1716 struct ea_list *ea_list,
1717 files_struct **result,
1718 int *pinfo,
1719 struct onefs_fsp_data *fsp_data)
1721 int info = FILE_WAS_OPENED;
1722 files_struct *base_fsp = NULL;
1723 files_struct *fsp = NULL;
1724 NTSTATUS status;
1726 DEBUG(10,("onefs_create_file_unixpath: access_mask = 0x%x "
1727 "file_attributes = 0x%x, share_access = 0x%x, "
1728 "create_disposition = 0x%x create_options = 0x%x "
1729 "oplock_request = 0x%x private_flags = 0x%x "
1730 "ea_list = 0x%p, sd = 0x%p, "
1731 "fname = %s\n",
1732 (unsigned int)access_mask,
1733 (unsigned int)file_attributes,
1734 (unsigned int)share_access,
1735 (unsigned int)create_disposition,
1736 (unsigned int)create_options,
1737 (unsigned int)oplock_request,
1738 (unsigned int)private_flags,
1739 ea_list, sd, smb_fname_str_dbg(smb_fname)));
1741 if (create_options & FILE_OPEN_BY_FILE_ID) {
1742 status = NT_STATUS_NOT_SUPPORTED;
1743 goto fail;
1746 if (create_options & NTCREATEX_OPTIONS_INVALID_PARAM_MASK) {
1747 status = NT_STATUS_INVALID_PARAMETER;
1748 goto fail;
1751 if (req == NULL) {
1752 SMB_ASSERT((oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK) ==
1753 NO_OPLOCK);
1754 oplock_request |= INTERNAL_OPEN_ONLY;
1757 if (lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE,
1758 PARM_IGNORE_SACLS, PARM_IGNORE_SACLS_DEFAULT)) {
1759 access_mask &= ~SYSTEM_SECURITY_ACCESS;
1762 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
1763 && (access_mask & DELETE_ACCESS)
1764 && !is_ntfs_stream_smb_fname(smb_fname)) {
1766 * We can't open a file with DELETE access if any of the
1767 * streams is open without FILE_SHARE_DELETE
1769 status = open_streams_for_delete(conn, smb_fname->base_name);
1771 if (!NT_STATUS_IS_OK(status)) {
1772 goto fail;
1776 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
1777 && is_ntfs_stream_smb_fname(smb_fname)) {
1778 uint32 base_create_disposition;
1779 struct smb_filename *smb_fname_base = NULL;
1781 if (create_options & FILE_DIRECTORY_FILE) {
1782 status = NT_STATUS_NOT_A_DIRECTORY;
1783 goto fail;
1786 switch (create_disposition) {
1787 case FILE_OPEN:
1788 base_create_disposition = FILE_OPEN;
1789 break;
1790 default:
1791 base_create_disposition = FILE_OPEN_IF;
1792 break;
1795 /* Create an smb_filename with stream_name == NULL. */
1796 status = create_synthetic_smb_fname(talloc_tos(),
1797 smb_fname->base_name,
1798 NULL, NULL,
1799 &smb_fname_base);
1800 if (!NT_STATUS_IS_OK(status)) {
1801 goto fail;
1804 if (SMB_VFS_STAT(conn, smb_fname_base) == -1) {
1805 DEBUG(10, ("Unable to stat stream: %s\n",
1806 smb_fname_str_dbg(smb_fname_base)));
1809 status = onefs_create_file_unixpath(
1810 conn, /* conn */
1811 NULL, /* req */
1812 smb_fname_base, /* fname */
1813 SYNCHRONIZE_ACCESS, /* access_mask */
1814 (FILE_SHARE_READ |
1815 FILE_SHARE_WRITE |
1816 FILE_SHARE_DELETE), /* share_access */
1817 base_create_disposition, /* create_disposition*/
1818 0, /* create_options */
1819 file_attributes, /* file_attributes */
1820 NO_OPLOCK, /* oplock_request */
1821 0, /* allocation_size */
1822 0, /* private_flags */
1823 NULL, /* sd */
1824 NULL, /* ea_list */
1825 &base_fsp, /* result */
1826 NULL, /* pinfo */
1827 NULL); /* fsp_data */
1829 TALLOC_FREE(smb_fname_base);
1831 if (!NT_STATUS_IS_OK(status)) {
1832 DEBUG(10, ("onefs_create_file_unixpath for base %s "
1833 "failed: %s\n", smb_fname->base_name,
1834 nt_errstr(status)));
1835 goto fail;
1839 * Testing against windows xp/2003/vista shows that oplocks
1840 * can actually be requested and granted on streams (see the
1841 * RAW-OPLOCK-STREAM1 smbtorture test).
1843 if ((oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK) !=
1844 NO_OPLOCK) {
1845 DEBUG(5, ("Oplock(%d) being requested on a stream! "
1846 "Ignoring oplock request: fname=%s\n",
1847 oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK,
1848 smb_fname_str_dbg(smb_fname)));
1849 /* Request NO_OPLOCK instead. */
1850 oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
1854 /* Covert generic bits in the security descriptor. */
1855 if (sd != NULL) {
1856 security_acl_map_generic(sd->dacl, &file_generic_mapping);
1857 security_acl_map_generic(sd->sacl, &file_generic_mapping);
1861 * If it's a request for a directory open, deal with it separately.
1864 if (create_options & FILE_DIRECTORY_FILE) {
1866 if (create_options & FILE_NON_DIRECTORY_FILE) {
1867 status = NT_STATUS_INVALID_PARAMETER;
1868 goto fail;
1871 /* Can't open a temp directory. IFS kit test. */
1872 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
1873 (file_attributes & FILE_ATTRIBUTE_TEMPORARY)) {
1874 status = NT_STATUS_INVALID_PARAMETER;
1875 goto fail;
1879 * We will get a create directory here if the Win32
1880 * app specified a security descriptor in the
1881 * CreateDirectory() call.
1884 status = onefs_open_directory(
1885 conn, /* conn */
1886 req, /* req */
1887 smb_fname, /* fname */
1888 access_mask, /* access_mask */
1889 share_access, /* share_access */
1890 create_disposition, /* create_disposition*/
1891 create_options, /* create_options */
1892 file_attributes, /* file_attributes */
1893 sd, /* sd */
1894 &fsp, /* result */
1895 &info); /* pinfo */
1896 } else {
1899 * Ordinary file case.
1902 status = file_new(req, conn, &fsp);
1903 if(!NT_STATUS_IS_OK(status)) {
1904 goto fail;
1908 * We're opening the stream element of a base_fsp
1909 * we already opened. Set up the base_fsp pointer.
1911 if (base_fsp) {
1912 fsp->base_fsp = base_fsp;
1915 status = onefs_open_file_ntcreate(
1916 conn, /* conn */
1917 req, /* req */
1918 smb_fname, /* fname */
1919 access_mask, /* access_mask */
1920 share_access, /* share_access */
1921 create_disposition, /* create_disposition*/
1922 create_options, /* create_options */
1923 file_attributes, /* file_attributes */
1924 oplock_request, /* oplock_request */
1925 sd, /* sd */
1926 fsp, /* result */
1927 &info, /* pinfo */
1928 fsp_data); /* fsp_data */
1930 if(!NT_STATUS_IS_OK(status)) {
1931 file_free(req, fsp);
1932 fsp = NULL;
1935 if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
1937 /* A stream open never opens a directory */
1939 if (base_fsp) {
1940 status = NT_STATUS_FILE_IS_A_DIRECTORY;
1941 goto fail;
1945 * Fail the open if it was explicitly a non-directory
1946 * file.
1949 if (create_options & FILE_NON_DIRECTORY_FILE) {
1950 status = NT_STATUS_FILE_IS_A_DIRECTORY;
1951 goto fail;
1954 create_options |= FILE_DIRECTORY_FILE;
1956 status = onefs_open_directory(
1957 conn, /* conn */
1958 req, /* req */
1959 smb_fname, /* fname */
1960 access_mask, /* access_mask */
1961 share_access, /* share_access */
1962 create_disposition, /* create_disposition*/
1963 create_options, /* create_options */
1964 file_attributes, /* file_attributes */
1965 sd, /* sd */
1966 &fsp, /* result */
1967 &info); /* pinfo */
1971 if (!NT_STATUS_IS_OK(status)) {
1972 goto fail;
1975 fsp->base_fsp = base_fsp;
1977 SMB_ASSERT(fsp);
1979 if ((ea_list != NULL) && (info == FILE_WAS_CREATED)) {
1980 status = set_ea(conn, fsp, smb_fname, ea_list);
1981 if (!NT_STATUS_IS_OK(status)) {
1982 goto fail;
1986 if (!fsp->is_directory && S_ISDIR(smb_fname->st.st_ex_mode)) {
1987 status = NT_STATUS_ACCESS_DENIED;
1988 goto fail;
1991 /* Save the requested allocation size. */
1992 if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
1993 if (allocation_size
1994 && (allocation_size > smb_fname->st.st_ex_size)) {
1995 fsp->initial_allocation_size = smb_roundup(
1996 fsp->conn, allocation_size);
1997 if (fsp->is_directory) {
1998 /* Can't set allocation size on a directory. */
1999 status = NT_STATUS_ACCESS_DENIED;
2000 goto fail;
2002 if (vfs_allocate_file_space(
2003 fsp, fsp->initial_allocation_size) == -1) {
2004 status = NT_STATUS_DISK_FULL;
2005 goto fail;
2007 } else {
2008 fsp->initial_allocation_size = smb_roundup(
2009 fsp->conn, (uint64_t)smb_fname->st.st_ex_size);
2013 DEBUG(10, ("onefs_create_file_unixpath: info=%d\n", info));
2015 *result = fsp;
2016 if (pinfo != NULL) {
2017 *pinfo = info;
2019 if ((fsp->fh != NULL) && (fsp->fh->fd != -1)) {
2020 SMB_VFS_FSTAT(fsp, &smb_fname->st);
2022 return NT_STATUS_OK;
2024 fail:
2025 DEBUG(10, ("onefs_create_file_unixpath: %s\n", nt_errstr(status)));
2027 if (fsp != NULL) {
2028 if (base_fsp && fsp->base_fsp == base_fsp) {
2030 * The close_file below will close
2031 * fsp->base_fsp.
2033 base_fsp = NULL;
2035 close_file(req, fsp, ERROR_CLOSE);
2036 fsp = NULL;
2038 if (base_fsp != NULL) {
2039 close_file(req, base_fsp, ERROR_CLOSE);
2040 base_fsp = NULL;
2042 return status;
2045 static void destroy_onefs_fsp_data(void *p_data)
2047 struct onefs_fsp_data *fsp_data = (struct onefs_fsp_data *)p_data;
2049 destroy_onefs_callback_record(fsp_data->oplock_callback_id);
2053 * SMB_VFS_CREATE_FILE interface to onefs.
2055 NTSTATUS onefs_create_file(vfs_handle_struct *handle,
2056 struct smb_request *req,
2057 uint16_t root_dir_fid,
2058 struct smb_filename *smb_fname,
2059 uint32_t access_mask,
2060 uint32_t share_access,
2061 uint32_t create_disposition,
2062 uint32_t create_options,
2063 uint32_t file_attributes,
2064 uint32_t oplock_request,
2065 uint64_t allocation_size,
2066 uint32_t private_flags,
2067 struct security_descriptor *sd,
2068 struct ea_list *ea_list,
2069 files_struct **result,
2070 int *pinfo)
2072 connection_struct *conn = handle->conn;
2073 struct onefs_fsp_data fsp_data = {};
2074 int info = FILE_WAS_OPENED;
2075 files_struct *fsp = NULL;
2076 NTSTATUS status;
2078 DEBUG(10,("onefs_create_file: access_mask = 0x%x "
2079 "file_attributes = 0x%x, share_access = 0x%x, "
2080 "create_disposition = 0x%x create_options = 0x%x "
2081 "oplock_request = 0x%x private_flags = 0x%x"
2082 "root_dir_fid = 0x%x, ea_list = 0x%p, sd = 0x%p, "
2083 "fname = %s\n",
2084 (unsigned int)access_mask,
2085 (unsigned int)file_attributes,
2086 (unsigned int)share_access,
2087 (unsigned int)create_disposition,
2088 (unsigned int)create_options,
2089 (unsigned int)oplock_request,
2090 (unsigned int)private_flags,
2091 (unsigned int)root_dir_fid,
2092 ea_list, sd, smb_fname_str_dbg(smb_fname)));
2094 /* Get the file name if root_dir_fid was specified. */
2095 if (root_dir_fid != 0) {
2096 status = get_relative_fid_filename(conn, req, root_dir_fid,
2097 smb_fname);
2098 if (!NT_STATUS_IS_OK(status)) {
2099 goto fail;
2103 /* All file access must go through check_name() */
2104 status = check_name(conn, smb_fname->base_name);
2105 if (!NT_STATUS_IS_OK(status)) {
2106 goto fail;
2109 status = onefs_create_file_unixpath(
2110 conn, /* conn */
2111 req, /* req */
2112 smb_fname, /* fname */
2113 access_mask, /* access_mask */
2114 share_access, /* share_access */
2115 create_disposition, /* create_disposition*/
2116 create_options, /* create_options */
2117 file_attributes, /* file_attributes */
2118 oplock_request, /* oplock_request */
2119 allocation_size, /* allocation_size */
2120 private_flags,
2121 sd, /* sd */
2122 ea_list, /* ea_list */
2123 &fsp, /* result */
2124 &info, /* pinfo */
2125 &fsp_data); /* psbuf */
2127 if (!NT_STATUS_IS_OK(status)) {
2128 goto fail;
2131 DEBUG(10, ("onefs_create_file: info=%d\n", info));
2134 * Setup private onefs_fsp_data. Currently the private data struct is
2135 * only used to store the oplock_callback_id so that when the file is
2136 * closed, the onefs_callback_record can be properly cleaned up in the
2137 * oplock_onefs sub-system.
2139 if (fsp) {
2140 struct onefs_fsp_data *fsp_data_tmp = NULL;
2141 fsp_data_tmp = (struct onefs_fsp_data *)
2142 VFS_ADD_FSP_EXTENSION(handle, fsp, struct onefs_fsp_data,
2143 &destroy_onefs_fsp_data);
2145 if (fsp_data_tmp == NULL) {
2146 status = NT_STATUS_NO_MEMORY;
2147 goto fail;
2150 *fsp_data_tmp = fsp_data;
2153 *result = fsp;
2154 if (pinfo != NULL) {
2155 *pinfo = info;
2157 return NT_STATUS_OK;
2159 fail:
2160 DEBUG(10, ("onefs_create_file: %s\n", nt_errstr(status)));
2162 if (fsp != NULL) {
2163 close_file(req, fsp, ERROR_CLOSE);
2164 fsp = NULL;
2166 return status;