Try to fix the build by fixing some typos in the vfs code
[Samba.git] / source3 / modules / onefs_open.c
blobd0310d017486c8982919ce2348146d93326621f2
1 /*
2 * Unix SMB/CIFS implementation.
4 * This file began with some code from source3/smbd/open.c and modified it to
5 * 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 "onefs.h"
37 extern const struct generic_mapping file_generic_mapping;
38 extern bool global_client_failed_oplock_break;
40 struct deferred_open_record {
41 bool delayed_for_oplocks;
42 bool failed; /* added for onefs_oplocks */
43 struct file_id id;
46 static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
47 struct smb_request *req,
48 const char *fname,
49 uint32_t access_mask,
50 uint32_t share_access,
51 uint32_t create_disposition,
52 uint32_t create_options,
53 uint32_t file_attributes,
54 uint32_t oplock_request,
55 uint64_t allocation_size,
56 struct security_descriptor *sd,
57 struct ea_list *ea_list,
59 files_struct **result,
60 int *pinfo,
61 SMB_STRUCT_STAT *psbuf);
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 const char *name,
72 const char *path,
73 SMB_STRUCT_STAT *psbuf,
74 int flags,
75 mode_t unx_mode,
76 uint32 access_mask,
77 uint32 open_access_mask,
78 int oplock_request,
79 uint64 id,
80 uint32 share_access,
81 uint32 create_options,
82 uint32_t new_dos_attributes,
83 struct security_descriptor *sd,
84 int *granted_oplock)
86 NTSTATUS status = NT_STATUS_OK;
87 int accmode = (flags & O_ACCMODE);
88 int local_flags = flags;
89 bool file_existed = VALID_STAT(*psbuf);
90 const char *wild;
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", path));
111 return NT_STATUS_ACCESS_DENIED;
112 } else if(flags & O_CREAT) {
113 /* We don't want to write - but we must make sure that
114 O_CREAT doesn't create the file if we have write
115 access into the directory.
117 flags &= ~O_CREAT;
118 local_flags &= ~O_CREAT;
123 * This little piece of insanity is inspired by the
124 * fact that an NT client can open a file for O_RDONLY,
125 * but set the create disposition to FILE_EXISTS_TRUNCATE.
126 * If the client *can* write to the file, then it expects to
127 * truncate the file, even though it is opening for readonly.
128 * Quicken uses this stupid trick in backup file creation...
129 * Thanks *greatly* to "David W. Chapman Jr." <dwcjr@inethouston.net>
130 * for helping track this one down. It didn't bite us in 2.0.x
131 * as we always opened files read-write in that release. JRA.
134 if ((accmode == O_RDONLY) && ((flags & O_TRUNC) == O_TRUNC)) {
135 DEBUG(10,("onefs_open_file: truncate requested on read-only "
136 "open for file %s\n", path));
137 local_flags = (flags & ~O_ACCMODE)|O_RDWR;
140 #if defined(O_NONBLOCK) && defined(S_ISFIFO)
142 * We would block on opening a FIFO with no one else on the
143 * other end. Do what we used to do and add O_NONBLOCK to the
144 * open flags. JRA.
147 if (file_existed && S_ISFIFO(psbuf->st_mode)) {
148 local_flags |= O_NONBLOCK;
150 #endif
152 /* Don't create files with Microsoft wildcard characters. */
153 if (fsp->base_fsp) {
155 * wildcard characters are allowed in stream names
156 * only test the basefilename
158 wild = fsp->base_fsp->fsp_name;
159 } else {
160 wild = path;
162 if ((local_flags & O_CREAT) && !file_existed &&
163 ms_has_wild(wild)) {
165 * XXX: may need to remvoe this return...
167 * We dont think this check needs to exist. All it does is
168 * block creating files with Microsoft wildcards, which is
169 * fine if the creation originated from NFS or locally and
170 * then was copied via Samba.
172 DEBUG(1, ("onefs_open_file: creating file with wildcard: %s\n",
173 path));
174 return NT_STATUS_OBJECT_NAME_INVALID;
177 /* Actually do the open */
179 #ifdef O_NOFOLLOW
181 * Never follow symlinks on a POSIX client. The
182 * client should be doing this.
185 if (fsp->posix_open || !lp_symlinks(SNUM(conn))) {
186 flags |= O_NOFOLLOW;
188 #endif
189 /* Don't request an oplock if oplocks are turned off for the
190 * share. */
191 if (!lp_oplocks(SNUM(conn)))
192 oplock_request = 0;
194 fsp->fh->fd = onefs_sys_create_file(conn,
196 path,
197 access_mask,
198 open_access_mask,
199 share_access,
200 create_options,
201 flags,
202 unx_mode,
203 oplock_request,
206 new_dos_attributes,
207 granted_oplock);
209 if (fsp->fh->fd == -1) {
210 if (errno == EMFILE) {
211 static time_t last_warned = 0L;
213 if (time((time_t *) NULL) > last_warned) {
214 DEBUG(0, ("Too many open files, unable "
215 "to open more! smbd's max "
216 "open files = %d, also check "
217 "sysctl kern.maxfiles and "
218 "sysctl kern.maxfilesperproc\n",
219 lp_max_open_files()));
220 last_warned = time((time_t *) NULL);
224 status = map_nt_error_from_unix(errno);
225 DEBUG(3,("Error opening file %s (%s) (local_flags=%d) "
226 "(flags=%d)\n",
227 path,nt_errstr(status),local_flags,flags));
228 return status;
231 if ((local_flags & O_CREAT) && !file_existed) {
233 /* Inherit the ACL if required */
234 if (lp_inherit_perms(SNUM(conn))) {
235 inherit_access_posix_acl(conn, parent_dir, path,
236 unx_mode);
239 /* Change the owner if required. */
240 if (lp_inherit_owner(SNUM(conn))) {
241 change_file_owner_to_parent(conn, parent_dir,
242 fsp);
245 notify_fname(conn, NOTIFY_ACTION_ADDED,
246 FILE_NOTIFY_CHANGE_FILE_NAME, path);
249 if (!file_existed) {
250 int ret;
252 if (fsp->fh->fd == -1) {
253 ret = SMB_VFS_STAT(conn, path, psbuf);
254 } else {
255 ret = SMB_VFS_FSTAT(fsp, psbuf);
256 /* If we have an fd, this stat should succeed. */
257 if (ret == -1) {
258 DEBUG(0,("Error doing fstat on open file %s "
259 "(%s)\n", path,strerror(errno) ));
263 /* For a non-io open, this stat failing means file not found. JRA */
264 if (ret == -1) {
265 status = map_nt_error_from_unix(errno);
266 fd_close(fsp);
267 return status;
272 * POSIX allows read-only opens of directories. We don't
273 * want to do this (we use a different code path for this)
274 * so catch a directory open and return an EISDIR. JRA.
277 if(S_ISDIR(psbuf->st_mode)) {
278 fd_close(fsp);
279 errno = EISDIR;
280 return NT_STATUS_FILE_IS_A_DIRECTORY;
283 fsp->mode = psbuf->st_mode;
284 fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf);
285 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
286 fsp->file_pid = req ? req->smbpid : 0;
287 fsp->can_lock = True;
288 fsp->can_read = (access_mask & (FILE_READ_DATA)) ? True : False;
289 if (!CAN_WRITE(conn)) {
290 fsp->can_write = False;
291 } else {
292 fsp->can_write = (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ?
293 True : False;
295 fsp->print_file = False;
296 fsp->modified = False;
297 fsp->sent_oplock_break = NO_BREAK_SENT;
298 fsp->is_directory = False;
299 if (conn->aio_write_behind_list &&
300 is_in_path(path, conn->aio_write_behind_list, conn->case_sensitive)) {
301 fsp->aio_write_behind = True;
304 string_set(&fsp->fsp_name, path);
305 fsp->wcp = NULL; /* Write cache pointer. */
307 DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
308 conn->server_info->unix_name,
309 fsp->fsp_name,
310 BOOLSTR(fsp->can_read), BOOLSTR(fsp->can_write),
311 conn->num_files_open));
313 errno = 0;
314 return NT_STATUS_OK;
317 /****************************************************************************
318 Handle the 1 second delay in returning a SHARING_VIOLATION error.
319 ****************************************************************************/
321 static void defer_open(struct share_mode_lock *lck,
322 struct timeval request_time,
323 struct timeval timeout,
324 struct smb_request *req,
325 struct deferred_open_record *state)
327 int i;
329 /* Paranoia check */
331 for (i=0; i<lck->num_share_modes; i++) {
332 struct share_mode_entry *e = &lck->share_modes[i];
334 if (!is_deferred_open_entry(e)) {
335 continue;
338 if (procid_is_me(&e->pid) && (e->op_mid == req->mid)) {
339 DEBUG(0, ("Trying to defer an already deferred "
340 "request: mid=%d, exiting\n", req->mid));
341 exit_server("attempt to defer a deferred request");
345 /* End paranoia check */
347 DEBUG(10,("defer_open_sharing_error: time [%u.%06u] adding deferred "
348 "open entry for mid %u\n",
349 (unsigned int)request_time.tv_sec,
350 (unsigned int)request_time.tv_usec,
351 (unsigned int)req->mid));
353 if (!push_deferred_smb_message(req, request_time, timeout,
354 (char *)state, sizeof(*state))) {
355 exit_server("push_deferred_smb_message failed");
357 add_deferred_open(lck, req->mid, request_time, state->id);
360 * Push the MID of this packet on the signing queue.
361 * We only do this once, the first time we push the packet
362 * onto the deferred open queue, as this has a side effect
363 * of incrementing the response sequence number.
366 srv_defer_sign_response(req->mid);
369 static void schedule_defer_open(struct share_mode_lock *lck,
370 struct timeval request_time,
371 struct smb_request *req)
373 struct deferred_open_record state;
375 /* This is a relative time, added to the absolute
376 request_time value to get the absolute timeout time.
377 Note that if this is the second or greater time we enter
378 this codepath for this particular request mid then
379 request_time is left as the absolute time of the *first*
380 time this request mid was processed. This is what allows
381 the request to eventually time out. */
383 struct timeval timeout;
385 /* Normally the smbd we asked should respond within
386 * OPLOCK_BREAK_TIMEOUT seconds regardless of whether
387 * the client did, give twice the timeout as a safety
388 * measure here in case the other smbd is stuck
389 * somewhere else. */
391 timeout = timeval_set(OPLOCK_BREAK_TIMEOUT*2, 0);
393 /* Nothing actually uses state.delayed_for_oplocks
394 but it's handy to differentiate in debug messages
395 between a 30 second delay due to oplock break, and
396 a 1 second delay for share mode conflicts. */
398 state.delayed_for_oplocks = True;
399 state.failed = False;
400 state.id = lck->id;
402 if (!request_timed_out(request_time, timeout)) {
403 defer_open(lck, request_time, timeout, req, &state);
407 /****************************************************************************
408 Open a file with a share mode. Passed in an already created files_struct.
409 ****************************************************************************/
410 NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
411 struct smb_request *req,
412 const char *fname,
413 uint32 access_mask,
414 uint32 share_access,
415 uint32 create_disposition,
416 uint32 create_options,
417 uint32 new_dos_attributes,
418 int oplock_request,
419 struct security_descriptor *sd,
420 files_struct *fsp,
421 int *pinfo,
422 SMB_STRUCT_STAT *psbuf)
424 int flags=0;
425 int flags2=0;
426 bool file_existed = VALID_STAT(*psbuf);
427 bool def_acl = False;
428 bool posix_open = False;
429 bool new_file_created = False;
430 struct file_id id;
431 mode_t new_unx_mode = (mode_t)0;
432 mode_t unx_mode = (mode_t)0;
433 int info;
434 uint32 existing_dos_attributes = 0;
435 struct pending_message_list *pml = NULL;
436 struct timeval request_time = timeval_zero();
437 struct share_mode_lock *lck = NULL;
438 uint32 open_access_mask = access_mask;
439 NTSTATUS status;
440 int ret_flock;
441 char *parent_dir;
442 const char *newname;
443 int granted_oplock;
444 uint64 oplock_waiter;
445 uint32 createfile_attributes = 0;
447 ZERO_STRUCT(id);
449 if (conn->printer) {
451 * Printers are handled completely differently.
452 * Most of the passed parameters are ignored.
455 if (pinfo) {
456 *pinfo = FILE_WAS_CREATED;
459 DEBUG(10, ("onefs_open_file_ntcreate: printer open fname=%s\n",
460 fname));
462 return print_fsp_open(req, conn, fname, req->vuid, fsp);
465 if (!parent_dirname_talloc(talloc_tos(), fname, &parent_dir,
466 &newname)) {
467 return NT_STATUS_NO_MEMORY;
470 if (new_dos_attributes & FILE_FLAG_POSIX_SEMANTICS) {
471 posix_open = True;
472 unx_mode = (mode_t)(new_dos_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
473 new_dos_attributes = 0;
474 } else {
475 /* We add aARCH to this as this mode is only used if the file is
476 * created new. */
477 unx_mode = unix_mode(conn, new_dos_attributes | aARCH, fname,
478 parent_dir);
481 DEBUG(10,("onefs_open_file_ntcreate: fname=%s, dos_attrs=0x%x "
482 "access_mask=0x%x share_access=0x%x "
483 "create_disposition = 0x%x create_options=0x%x "
484 "unix mode=0%o oplock_request=0x%x\n",
485 fname, new_dos_attributes, access_mask, share_access,
486 create_disposition, create_options, unx_mode,
487 oplock_request));
489 if ((req == NULL) && ((oplock_request & INTERNAL_OPEN_ONLY) == 0)) {
490 DEBUG(0, ("No smb request but not an internal only open!\n"));
491 return NT_STATUS_INTERNAL_ERROR;
495 * Only non-internal opens can be deferred at all
498 if ((req != NULL)
499 && ((pml = get_open_deferred_message(req->mid)) != NULL)) {
500 struct deferred_open_record *state =
501 (struct deferred_open_record *)pml->private_data.data;
503 /* Remember the absolute time of the original
504 request with this mid. We'll use it later to
505 see if this has timed out. */
507 request_time = pml->request_time;
509 /* Remove the deferred open entry under lock. */
510 lck = get_share_mode_lock(talloc_tos(), state->id, NULL, NULL,
511 NULL);
512 if (lck == NULL) {
513 DEBUG(0, ("could not get share mode lock\n"));
514 } else {
515 del_deferred_open_entry(lck, req->mid);
516 TALLOC_FREE(lck);
519 /* Ensure we don't reprocess this message. */
520 remove_deferred_open_smb_message(req->mid);
523 * When receiving a semlock_async_failure message, the
524 * deferred open will be marked as "failed". Returning
525 * INTERNAL_ERROR.
527 if (state->failed) {
528 DEBUG(0, ("onefs_open_file_ntcreate: "
529 "semlock_async_failure detected!\n"));
530 return NT_STATUS_INTERNAL_ERROR;
534 status = check_name(conn, fname);
535 if (!NT_STATUS_IS_OK(status)) {
536 return status;
539 if (!posix_open) {
540 new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
541 if (file_existed) {
542 existing_dos_attributes = dos_mode(conn, fname, psbuf);
546 /* Setup dos_attributes to be set by ifs_createfile */
547 if (lp_store_dos_attributes(SNUM(conn))) {
548 createfile_attributes = (new_dos_attributes | aARCH) &
549 ~(FILE_ATTRIBUTE_NONINDEXED | FILE_ATTRIBUTE_COMPRESSED);
552 /* Ignore oplock requests if oplocks are disabled. */
553 if (!lp_oplocks(SNUM(conn)) || global_client_failed_oplock_break ||
554 IS_VETO_OPLOCK_PATH(conn, fname)) {
555 /* Mask off everything except the private Samba bits. */
556 oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
559 /* this is for OS/2 long file names - say we don't support them */
560 if (!lp_posix_pathnames() && strstr(fname,".+,;=[].")) {
561 /* OS/2 Workplace shell fix may be main code stream in a later
562 * release. */
563 DEBUG(5,("onefs_open_file_ntcreate: OS/2 long filenames are "
564 "not supported.\n"));
565 if (use_nt_status()) {
566 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
568 return NT_STATUS_DOS(ERRDOS, ERRcannotopen);
571 switch( create_disposition ) {
573 * Currently we're using FILE_SUPERSEDE as the same as
574 * FILE_OVERWRITE_IF but they really are
575 * different. FILE_SUPERSEDE deletes an existing file
576 * (requiring delete access) then recreates it.
578 case FILE_SUPERSEDE:
579 /* If file exists replace/overwrite. If file doesn't
580 * exist create. */
582 * @todo: Clear all file attributes?
583 * http://www.osronline.com/article.cfm?article=302
584 * create if not exist, trunc if exist
586 * If file exists replace/overwrite. If file doesn't
587 * exist create.
589 flags2 |= (O_CREAT | O_TRUNC);
590 break;
592 case FILE_OVERWRITE_IF:
593 /* If file exists replace/overwrite. If file doesn't
594 * exist create. */
595 flags2 |= (O_CREAT | O_TRUNC);
596 break;
598 case FILE_OPEN:
599 /* If file exists open. If file doesn't exist error. */
600 if (!file_existed) {
601 DEBUG(5,("onefs_open_file_ntcreate: FILE_OPEN "
602 "requested for file %s and file "
603 "doesn't exist.\n", fname ));
604 errno = ENOENT;
605 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
607 break;
609 case FILE_OVERWRITE:
610 /* If file exists overwrite. If file doesn't exist
611 * error. */
612 if (!file_existed) {
613 DEBUG(5, ("onefs_open_file_ntcreate: "
614 "FILE_OVERWRITE requested for file "
615 "%s and file doesn't exist.\n",
616 fname));
617 errno = ENOENT;
618 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
620 flags2 |= O_TRUNC;
621 break;
623 case FILE_CREATE:
624 /* If file exists error. If file doesn't exist
625 * create. */
626 if (file_existed) {
627 DEBUG(5, ("onefs_open_file_ntcreate: "
628 "FILE_CREATE requested for file %s "
629 "and file already exists.\n",
630 fname));
631 if (S_ISDIR(psbuf->st_mode)) {
632 errno = EISDIR;
633 } else {
634 errno = EEXIST;
636 return map_nt_error_from_unix(errno);
638 flags2 |= (O_CREAT|O_EXCL);
639 break;
641 case FILE_OPEN_IF:
642 /* If file exists open. If file doesn't exist
643 * create. */
644 flags2 |= O_CREAT;
645 break;
647 default:
648 return NT_STATUS_INVALID_PARAMETER;
651 /* Match attributes on file exists and overwrite. */
652 if (!posix_open && file_existed &&
653 ((create_disposition == FILE_OVERWRITE) ||
654 (create_disposition == FILE_OVERWRITE_IF))) {
655 if (!open_match_attributes(conn, fname,
656 existing_dos_attributes,
657 new_dos_attributes, psbuf->st_mode,
658 unx_mode, &new_unx_mode)) {
659 DEBUG(5, ("onefs_open_file_ntcreate: attributes "
660 "missmatch for file %s (%x %x) (0%o, 0%o)\n",
661 fname, existing_dos_attributes,
662 new_dos_attributes,
663 (unsigned int)psbuf->st_mode,
664 (unsigned int)unx_mode ));
665 errno = EACCES;
666 return NT_STATUS_ACCESS_DENIED;
671 * OneFS understands MAXIMUM_ALLOWED_ACCESS, so only hack the
672 * access_mask, but leave the MAA for the actual open in
673 * open_access_mask.
675 open_access_mask = access_mask;
676 if (open_access_mask & MAXIMUM_ALLOWED_ACCESS) {
677 access_mask |= FILE_GENERIC_ALL;
680 /* Convert GENERIC bits to specific bits. */
681 se_map_generic(&access_mask, &file_generic_mapping);
682 se_map_generic(&open_access_mask, &file_generic_mapping);
684 if ((flags2 & O_TRUNC) || (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE)) {
685 /* This will cause oplock breaks. */
686 open_access_mask |= FILE_WRITE_DATA;
689 DEBUG(10, ("onefs_open_file_ntcreate: fname=%s, after mapping "
690 "open_access_mask=%#x, access_mask=0x%x\n",
691 fname, open_access_mask, access_mask));
694 * Note that we ignore the append flag as append does not
695 * mean the same thing under DOS and Unix.
698 if ((access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ||
699 (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE)) {
702 * DENY_DOS opens are always underlying read-write on the
703 * file handle, no matter what the requested access mask
704 * says. Stock samba just sets the flags, but since
705 * ifs_createfile uses the access_mask, it must be updated as
706 * well. This allows BASE-DENY* to pass.
708 if (create_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) {
710 DEBUG(10,("onefs_open_file_ntcreate: deny_dos: "
711 "Adding O_RDWR to flags "
712 "(0x%x) and some READ bits to "
713 "open_access_mask (0x%x)\n",
714 flags, open_access_mask));
716 flags = O_RDWR;
717 open_access_mask |= (FILE_READ_ATTRIBUTES |
718 FILE_READ_DATA | FILE_READ_EA | FILE_EXECUTE);
720 } else if (access_mask & (FILE_READ_ATTRIBUTES |
721 FILE_READ_DATA |
722 FILE_READ_EA |
723 FILE_EXECUTE)) {
724 flags = O_RDWR;
725 } else {
726 flags = O_WRONLY;
728 } else {
729 flags = O_RDONLY;
732 /* Currently we only look at FILE_WRITE_THROUGH for create options. */
733 #if defined(O_SYNC)
734 if ((create_options & FILE_WRITE_THROUGH) &&
735 lp_strict_sync(SNUM(conn))) {
736 flags2 |= O_SYNC;
738 #endif /* O_SYNC */
740 if (posix_open && (access_mask & FILE_APPEND_DATA)) {
741 flags2 |= O_APPEND;
744 if (!posix_open && !CAN_WRITE(conn)) {
746 * We should really return a permission denied error if either
747 * O_CREAT or O_TRUNC are set, but for compatibility with
748 * older versions of Samba we just AND them out.
750 flags2 &= ~(O_CREAT|O_TRUNC);
753 * XXX: TODO
754 * Apparently this is necessary because we ship with
755 * lp_acl_check_permissions = no. It is set to no because our
756 * ifs_createfile does the access check correctly. This check
757 * was added in the last merge, and the question is why is it
758 * necessary? Check out Bug 25547 and Bug 14596. The key is
759 * to figure out what case this is covering, and do some
760 * testing to see if it's actually necessary. If it is, maybe
761 * it should go upstream in open.c.
763 if (!lp_acl_check_permissions(SNUM(conn)) &&
764 (access_mask & DELETE_ACCESS)) {
765 return map_nt_error_from_unix(EACCES);
769 /* Ensure we can't write on a read-only share or file. */
770 if (flags != O_RDONLY && file_existed &&
771 (!CAN_WRITE(conn) || IS_DOS_READONLY(existing_dos_attributes))) {
772 DEBUG(5, ("onefs_open_file_ntcreate: write access requested "
773 "for file %s on read only %s\n",
774 fname, !CAN_WRITE(conn) ? "share" : "file" ));
775 errno = EACCES;
776 return NT_STATUS_ACCESS_DENIED;
779 DEBUG(10, ("fsp = %p\n", fsp));
781 fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf);
782 fsp->share_access = share_access;
783 fsp->fh->private_options = create_options;
784 fsp->access_mask = open_access_mask; /* We change this to the
785 * requested access_mask after
786 * the open is done. */
787 fsp->posix_open = posix_open;
789 /* Ensure no SAMBA_PRIVATE bits can be set. */
790 fsp->oplock_type = (oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK);
792 if (timeval_is_zero(&request_time)) {
793 request_time = fsp->open_time;
796 if (file_existed) {
797 struct timespec old_write_time = get_mtimespec(psbuf);
798 id = vfs_file_id_from_sbuf(conn, psbuf);
800 lck = get_share_mode_lock(talloc_tos(), id,
801 conn->connectpath,
802 fname, &old_write_time);
804 if (lck == NULL) {
805 DEBUG(0, ("Could not get share mode lock\n"));
806 return NT_STATUS_SHARING_VIOLATION;
809 if (lck->delete_on_close) {
810 /* DELETE_PENDING is not deferred for a second */
811 TALLOC_FREE(lck);
812 return NT_STATUS_DELETE_PENDING;
816 SMB_ASSERT(!file_existed || (lck != NULL));
819 * Ensure we pay attention to default ACLs on directories. May be
820 * neccessary depending on ACL policies.
822 if ((flags2 & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
823 (def_acl = directory_has_default_acl(conn, parent_dir))) {
824 unx_mode = 0777;
827 DEBUG(4,("calling onefs_open_file with flags=0x%X flags2=0x%X "
828 "mode=0%o, access_mask = 0x%x, open_access_mask = 0x%x\n",
829 (unsigned int)flags, (unsigned int)flags2,
830 (unsigned int)unx_mode, (unsigned int)access_mask,
831 (unsigned int)open_access_mask));
833 oplock_waiter = 1; //ifs_oplock_wait_record(mid);
835 if (oplock_waiter == 0) {
836 return NT_STATUS_NO_MEMORY;
839 /* Do the open. */
840 status = onefs_open_file(fsp,
841 conn,
842 req,
843 parent_dir,
844 newname,
845 fname,
846 psbuf,
847 flags|flags2,
848 unx_mode,
849 access_mask,
850 open_access_mask,
851 fsp->oplock_type,
852 oplock_waiter,
853 share_access,
854 create_options,
855 createfile_attributes,
857 &granted_oplock);
859 if (!NT_STATUS_IS_OK(status)) {
861 /* OneFS Oplock Handling */
862 if (errno == EINPROGRESS) {
864 if (lck == NULL) {
866 struct deferred_open_record state;
867 struct timespec old_write_time;
869 old_write_time = get_mtimespec(psbuf);
871 DEBUG(3, ("Someone created file %s with an "
872 "oplock after we looked: Retrying\n",
873 fname));
875 * We hit the race that when we did the stat
876 * on the file it did not exist, and someone
877 * has created it in between the stat and the
878 * open_file() call. Just retry immediately.
880 id = vfs_file_id_from_sbuf(conn, psbuf);
881 if (!(lck = get_share_mode_lock(talloc_tos(),
882 id, conn->connectpath, fname,
883 &old_write_time))) {
885 * Emergency exit
887 DEBUG(0, ("onefs_open_file_ntcreate: "
888 "Could not get share mode "
889 "lock for %s\n", fname));
890 status = NT_STATUS_SHARING_VIOLATION;
891 goto cleanup_destroy;
894 state.delayed_for_oplocks = False;
895 state.id = id;
897 if (req != NULL) {
898 defer_open(lck, request_time,
899 timeval_zero(), req, &state);
901 goto cleanup_destroy;
903 /* Waiting for an oplock */
904 SMB_ASSERT(req);
905 schedule_defer_open(lck, request_time, req);
906 goto cleanup;
909 /* Check for a sharing violation */
910 if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
911 uint32 can_access_mask;
912 bool can_access = True;
914 /* Check if this can be done with the deny_dos and fcb
915 * calls. */
917 /* Try to find dup fsp if possible. */
918 if (create_options &
919 (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS|
920 NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) {
922 if (req == NULL) {
923 DEBUG(0, ("DOS open without an SMB "
924 "request!\n"));
925 status = NT_STATUS_INTERNAL_ERROR;
926 goto cleanup_destroy;
929 /* Use the client requested access mask here,
930 * not the one we open with. */
931 status = fcb_or_dos_open(req,
932 conn,
933 fsp,
934 fname,
936 req->smbpid,
937 req->vuid,
938 access_mask,
939 share_access,
940 create_options);
942 if (NT_STATUS_IS_OK(status)) {
943 TALLOC_FREE(lck);
944 if (pinfo) {
945 *pinfo = FILE_WAS_OPENED;
947 status = NT_STATUS_OK;
948 goto cleanup;
953 * This next line is a subtlety we need for
954 * MS-Access. If a file open will fail due to share
955 * permissions and also for security (access) reasons,
956 * we need to return the access failed error, not the
957 * share error. We can't open the file due to kernel
958 * oplock deadlock (it's possible we failed above on
959 * the open_mode_check()) so use a userspace check.
962 if (flags & O_RDWR) {
963 can_access_mask = FILE_READ_DATA|FILE_WRITE_DATA;
964 } else if (flags & O_WRONLY) {
965 can_access_mask = FILE_WRITE_DATA;
966 } else {
967 can_access_mask = FILE_READ_DATA;
970 if (((can_access_mask & FILE_WRITE_DATA) && !CAN_WRITE(conn)) ||
971 !can_access_file_data(conn,fname,psbuf,can_access_mask)) {
972 can_access = False;
976 * If we're returning a share violation, ensure we
977 * cope with the braindead 1 second delay.
979 if (!(oplock_request & INTERNAL_OPEN_ONLY) &&
980 lp_defer_sharing_violations()) {
981 struct timeval timeout;
982 struct deferred_open_record state;
983 int timeout_usecs;
985 /* this is a hack to speed up torture tests
986 in 'make test' */
987 timeout_usecs = lp_parm_int(SNUM(conn),
988 "smbd","sharedelay",
989 SHARING_VIOLATION_USEC_WAIT);
991 /* This is a relative time, added to the
992 absolute request_time value to get the
993 absolute timeout time. Note that if this
994 is the second or greater time we enter this
995 codepath for this particular request mid
996 then request_time is left as the absolute
997 time of the *first* time this request mid
998 was processed. This is what allows the
999 request to eventually time out. */
1001 timeout = timeval_set(0, timeout_usecs);
1003 /* Nothing actually uses
1004 state.delayed_for_oplocks but it's handy to
1005 differentiate in debug messages between a
1006 30 second delay due to oplock break, and a
1007 1 second delay for share mode conflicts. */
1009 state.delayed_for_oplocks = False;
1010 state.id = id;
1011 state.failed = false;
1013 if ((req != NULL)
1014 && !request_timed_out(request_time,
1015 timeout)) {
1016 defer_open(lck, request_time, timeout,
1017 req, &state);
1021 if (can_access) {
1023 * We have detected a sharing violation here
1024 * so return the correct error code
1026 status = NT_STATUS_SHARING_VIOLATION;
1027 } else {
1028 status = NT_STATUS_ACCESS_DENIED;
1031 goto cleanup_destroy;
1035 * Normal error, for example EACCES
1037 cleanup_destroy:
1038 //destroy_ifs_callback_record(oplock_waiter);
1039 cleanup:
1040 TALLOC_FREE(lck);
1041 return status;
1044 fsp->oplock_type = granted_oplock;
1046 /* XXX uncomment for oplocks */
1047 //ifs_set_oplock_callback(oplock_waiter, fsp);
1048 //fsp->oplock_callback_id = oplock_waiter;
1050 if (!file_existed) {
1051 struct timespec old_write_time = get_mtimespec(psbuf);
1053 * Deal with the race condition where two smbd's detect the
1054 * file doesn't exist and do the create at the same time. One
1055 * of them will win and set a share mode, the other (ie. this
1056 * one) should check if the requested share mode for this
1057 * create is allowed.
1061 * Now the file exists and fsp is successfully opened,
1062 * fsp->dev and fsp->inode are valid and should replace the
1063 * dev=0,inode=0 from a non existent file. Spotted by
1064 * Nadav Danieli <nadavd@exanet.com>. JRA.
1067 id = fsp->file_id;
1069 lck = get_share_mode_lock(talloc_tos(), id,
1070 conn->connectpath,
1071 fname, &old_write_time);
1073 if (lck == NULL) {
1074 DEBUG(0, ("onefs_open_file_ntcreate: Could not get "
1075 "share mode lock for %s\n", fname));
1076 fd_close(fsp);
1077 return NT_STATUS_SHARING_VIOLATION;
1080 if (lck->delete_on_close) {
1081 status = NT_STATUS_DELETE_PENDING;
1084 if (!NT_STATUS_IS_OK(status)) {
1085 struct deferred_open_record state;
1087 fd_close(fsp);
1089 state.delayed_for_oplocks = False;
1090 state.id = id;
1092 /* Do it all over again immediately. In the second
1093 * round we will find that the file existed and handle
1094 * the DELETE_PENDING and FCB cases correctly. No need
1095 * to duplicate the code here. Essentially this is a
1096 * "goto top of this function", but don't tell
1097 * anybody... */
1099 if (req != NULL) {
1100 defer_open(lck, request_time, timeval_zero(),
1101 req, &state);
1103 TALLOC_FREE(lck);
1104 return status;
1108 * We exit this block with the share entry *locked*.....
1113 SMB_ASSERT(lck != NULL);
1115 /* note that we ignore failure for the following. It is
1116 basically a hack for NFS, and NFS will never set one of
1117 these only read them. Nobody but Samba can ever set a deny
1118 mode and we have already checked our more authoritative
1119 locking database for permission to set this deny mode. If
1120 the kernel refuses the operations then the kernel is wrong.
1121 note that GPFS supports it as well - jmcd */
1123 if (fsp->fh->fd != -1) {
1124 ret_flock = SMB_VFS_KERNEL_FLOCK(fsp, share_access);
1125 if(ret_flock == -1 ){
1127 TALLOC_FREE(lck);
1128 fd_close(fsp);
1129 return NT_STATUS_SHARING_VIOLATION;
1134 * At this point onwards, we can guarentee that the share entry
1135 * is locked, whether we created the file or not, and that the
1136 * deny mode is compatible with all current opens.
1139 /* Record the options we were opened with. */
1140 fsp->share_access = share_access;
1141 fsp->fh->private_options = create_options;
1143 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
1145 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
1147 if (file_existed) {
1148 /* stat opens on existing files don't get oplocks. */
1149 if (is_stat_open(open_access_mask)) {
1150 fsp->oplock_type = NO_OPLOCK;
1153 if (!(flags2 & O_TRUNC)) {
1154 info = FILE_WAS_OPENED;
1155 } else {
1156 info = FILE_WAS_OVERWRITTEN;
1158 } else {
1159 info = FILE_WAS_CREATED;
1162 if (pinfo) {
1163 *pinfo = info;
1167 * Setup the oplock info in both the shared memory and
1168 * file structs.
1171 if ((fsp->oplock_type != NO_OPLOCK) &&
1172 (fsp->oplock_type != FAKE_LEVEL_II_OPLOCK)) {
1173 if (!set_file_oplock(fsp, fsp->oplock_type)) {
1174 /* Could not get the kernel oplock */
1175 fsp->oplock_type = NO_OPLOCK;
1179 if (info == FILE_WAS_OVERWRITTEN || info == FILE_WAS_CREATED ||
1180 info == FILE_WAS_SUPERSEDED) {
1181 new_file_created = True;
1184 set_share_mode(lck, fsp, conn->server_info->utok.uid, 0,
1185 fsp->oplock_type);
1187 /* Handle strange delete on close create semantics. */
1188 if (create_options & FILE_DELETE_ON_CLOSE) {
1189 status = can_set_delete_on_close(fsp, True, new_dos_attributes);
1191 if (!NT_STATUS_IS_OK(status)) {
1192 /* Remember to delete the mode we just added. */
1193 del_share_mode(lck, fsp);
1194 TALLOC_FREE(lck);
1195 fd_close(fsp);
1196 return status;
1198 /* Note that here we set the *inital* delete on close flag,
1199 not the regular one. The magic gets handled in close. */
1200 fsp->initial_delete_on_close = True;
1204 * Take care of inherited ACLs on created files - if default ACL not
1205 * selected.
1206 * May be necessary depending on acl policies.
1208 if (!posix_open && !file_existed && !def_acl && !(VALID_STAT(*psbuf)
1209 && (psbuf->st_flags & SF_HASNTFSACL))) {
1211 int saved_errno = errno; /* We might get ENOSYS in the next
1212 * call.. */
1214 if (SMB_VFS_FCHMOD_ACL(fsp, unx_mode) == -1 &&
1215 errno == ENOSYS) {
1216 errno = saved_errno; /* Ignore ENOSYS */
1219 } else if (new_unx_mode) {
1221 int ret = -1;
1223 /* Attributes need changing. File already existed. */
1226 int saved_errno = errno; /* We might get ENOSYS in the
1227 * next call.. */
1228 ret = SMB_VFS_FCHMOD_ACL(fsp, new_unx_mode);
1230 if (ret == -1 && errno == ENOSYS) {
1231 errno = saved_errno; /* Ignore ENOSYS */
1232 } else {
1233 DEBUG(5, ("onefs_open_file_ntcreate: reset "
1234 "attributes of file %s to 0%o\n",
1235 fname, (unsigned int)new_unx_mode));
1236 ret = 0; /* Don't do the fchmod below. */
1240 if ((ret == -1) &&
1241 (SMB_VFS_FCHMOD(fsp, new_unx_mode) == -1))
1242 DEBUG(5, ("onefs_open_file_ntcreate: failed to reset "
1243 "attributes of file %s to 0%o\n",
1244 fname, (unsigned int)new_unx_mode));
1247 /* If this is a successful open, we must remove any deferred open
1248 * records. */
1249 if (req != NULL) {
1250 del_deferred_open_entry(lck, req->mid);
1252 TALLOC_FREE(lck);
1254 return NT_STATUS_OK;
1258 /****************************************************************************
1259 Open a directory from an NT SMB call.
1260 ****************************************************************************/
1261 static NTSTATUS onefs_open_directory(connection_struct *conn,
1262 struct smb_request *req,
1263 const char *fname,
1264 uint32 access_mask,
1265 uint32 share_access,
1266 uint32 create_disposition,
1267 uint32 create_options,
1268 uint32 file_attributes,
1269 struct security_descriptor *sd,
1270 files_struct **result,
1271 int *pinfo,
1272 SMB_STRUCT_STAT *psbuf)
1274 files_struct *fsp = NULL;
1275 struct share_mode_lock *lck = NULL;
1276 NTSTATUS status;
1277 struct timespec mtimespec;
1278 int info = 0;
1279 char *parent_dir;
1280 const char *dirname;
1281 bool posix_open = false;
1282 uint32 create_flags = 0;
1283 uint32 mode = lp_dir_mask(SNUM(conn));
1285 DEBUG(5, ("onefs_open_directory: opening directory %s, "
1286 "access_mask = 0x%x, "
1287 "share_access = 0x%x create_options = 0x%x, "
1288 "create_disposition = 0x%x, file_attributes = 0x%x\n",
1289 fname, (unsigned int)access_mask, (unsigned int)share_access,
1290 (unsigned int)create_options, (unsigned int)create_disposition,
1291 (unsigned int)file_attributes));
1293 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
1294 (conn->fs_capabilities & FILE_NAMED_STREAMS) &&
1295 is_ntfs_stream_name(fname)) {
1296 DEBUG(2, ("onefs_open_directory: %s is a stream name!\n", fname));
1297 return NT_STATUS_NOT_A_DIRECTORY;
1300 switch (create_disposition) {
1301 case FILE_OPEN:
1302 /* If directory exists open. If directory doesn't
1303 * exist error. */
1304 create_flags = 0;
1305 info = FILE_WAS_OPENED;
1306 break;
1307 case FILE_CREATE:
1308 /* If directory exists error. If directory doesn't
1309 * exist create. */
1310 create_flags = O_CREAT | O_EXCL;
1311 info = FILE_WAS_CREATED;
1312 break;
1313 case FILE_OPEN_IF:
1314 /* If directory exists open. If directory doesn't
1315 * exist create. */
1317 /* Note: in order to return whether the directory was
1318 * opened or created, we first try to open and then try
1319 * to create. */
1320 create_flags = 0;
1321 info = FILE_WAS_OPENED;
1322 break;
1323 case FILE_SUPERSEDE:
1324 case FILE_OVERWRITE:
1325 case FILE_OVERWRITE_IF:
1326 default:
1327 DEBUG(5, ("onefs_open_directory: invalid "
1328 "create_disposition 0x%x for directory %s\n",
1329 (unsigned int)create_disposition, fname));
1330 return NT_STATUS_INVALID_PARAMETER;
1334 * Check for write access to the share. Done in mkdir_internal() in
1335 * mainline samba.
1337 if (!CAN_WRITE(conn) && (create_flags & O_CREAT)) {
1338 return NT_STATUS_ACCESS_DENIED;
1341 /* Get parent dirname */
1342 if (!parent_dirname_talloc(talloc_tos(), fname, &parent_dir,
1343 &dirname)) {
1344 return NT_STATUS_NO_MEMORY;
1347 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
1348 posix_open = true;
1349 mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
1350 file_attributes = 0;
1351 } else {
1352 mode = unix_mode(conn, aDIR, fname, parent_dir);
1356 * The NONINDEXED and COMPRESSED bits seem to always be cleared on
1357 * directories, no matter if you specify that they should be set.
1359 file_attributes &=
1360 ~(FILE_ATTRIBUTE_NONINDEXED | FILE_ATTRIBUTE_COMPRESSED);
1362 status = file_new(req, conn, &fsp);
1363 if(!NT_STATUS_IS_OK(status)) {
1364 return status;
1368 * Actual open with retry magic to handle FILE_OPEN_IF which is
1369 * unique because the kernel won't tell us if the file was opened or
1370 * created.
1372 retry_open:
1373 fsp->fh->fd = onefs_sys_create_file(conn,
1375 fname,
1376 access_mask,
1377 access_mask,
1378 share_access,
1379 create_options,
1380 create_flags | O_DIRECTORY,
1381 mode,
1385 file_attributes,
1386 NULL);
1388 if (fsp->fh->fd == -1) {
1389 DEBUG(3, ("Error opening %s. Errno=%d (%s).\n", fname, errno,
1390 strerror(errno)));
1391 SMB_ASSERT(errno != EINPROGRESS);
1393 if (create_disposition == FILE_OPEN_IF) {
1394 if (errno == ENOENT) {
1395 /* Try again, creating it this time. */
1396 create_flags = O_CREAT | O_EXCL;
1397 info = FILE_WAS_CREATED;
1398 goto retry_open;
1399 } else if (errno == EEXIST) {
1400 /* Uggh. Try again again. */
1401 create_flags = 0;
1402 info = FILE_WAS_OPENED;
1403 goto retry_open;
1407 /* Error cases below: */
1408 file_free(req, fsp);
1410 if ((errno == ENOENT) && (create_disposition == FILE_OPEN)) {
1411 DEBUG(5,("onefs_open_directory: FILE_OPEN requested "
1412 "for directory %s and it doesn't "
1413 "exist.\n", fname ));
1414 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1415 } else if ((errno == EEXIST) &&
1416 (create_disposition == FILE_CREATE)) {
1417 DEBUG(5,("onefs_open_directory: FILE_CREATE "
1418 "requested for directory %s and it "
1419 "already exists.\n", fname ));
1420 return NT_STATUS_OBJECT_NAME_COLLISION;
1421 } else if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
1422 /* Catch sharing violations. */
1423 return NT_STATUS_SHARING_VIOLATION;
1426 return map_nt_error_from_unix(errno);
1429 if (info == FILE_WAS_CREATED) {
1431 /* Pulled from mkdir_internal() */
1432 if (SMB_VFS_LSTAT(conn, fname, psbuf) == -1) {
1433 DEBUG(2, ("Could not stat directory '%s' just "
1434 "created: %s\n",fname, strerror(errno)));
1435 return map_nt_error_from_unix(errno);
1438 if (!S_ISDIR(psbuf->st_mode)) {
1439 DEBUG(0, ("Directory just '%s' created is not a "
1440 "directory\n", fname));
1441 return NT_STATUS_ACCESS_DENIED;
1444 if (!posix_open) {
1446 * Check if high bits should have been set, then (if
1447 * bits are missing): add them. Consider bits
1448 * automagically set by UNIX, i.e. SGID bit from
1449 * parent dir.
1451 if (mode & ~(S_IRWXU|S_IRWXG|S_IRWXO) &&
1452 (mode & ~psbuf->st_mode)) {
1453 SMB_VFS_CHMOD(conn, fname, (psbuf->st_mode |
1454 (mode & ~psbuf->st_mode)));
1458 /* Change the owner if required. */
1459 if (lp_inherit_owner(SNUM(conn))) {
1460 change_dir_owner_to_parent(conn, parent_dir, fname,
1461 psbuf);
1464 notify_fname(conn, NOTIFY_ACTION_ADDED,
1465 FILE_NOTIFY_CHANGE_DIR_NAME, fname);
1468 /* Stat the fd for Samba bookkeeping. */
1469 if(SMB_VFS_FSTAT(fsp, psbuf) != 0) {
1470 fd_close(fsp);
1471 file_free(req, fsp);
1472 return map_nt_error_from_unix(errno);
1475 /* Setup the files_struct for it. */
1476 fsp->mode = psbuf->st_mode;
1477 fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf);
1478 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
1479 fsp->file_pid = req ? req->smbpid : 0;
1480 fsp->can_lock = False;
1481 fsp->can_read = False;
1482 fsp->can_write = False;
1484 fsp->share_access = share_access;
1485 fsp->fh->private_options = create_options;
1487 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
1489 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
1490 fsp->print_file = False;
1491 fsp->modified = False;
1492 fsp->oplock_type = NO_OPLOCK;
1493 fsp->sent_oplock_break = NO_BREAK_SENT;
1494 fsp->is_directory = True;
1495 fsp->posix_open = posix_open;
1497 string_set(&fsp->fsp_name,fname);
1499 mtimespec = get_mtimespec(psbuf);
1502 * Still set the samba share mode lock for correct delete-on-close
1503 * semantics and to make smbstatus more useful.
1505 lck = get_share_mode_lock(talloc_tos(), fsp->file_id,
1506 conn->connectpath,
1507 fname, &mtimespec);
1509 if (lck == NULL) {
1510 DEBUG(0, ("onefs_open_directory: Could not get share mode "
1511 "lock for %s\n", fname));
1512 fd_close(fsp);
1513 file_free(req, fsp);
1514 return NT_STATUS_SHARING_VIOLATION;
1517 if (lck->delete_on_close) {
1518 TALLOC_FREE(lck);
1519 fd_close(fsp);
1520 file_free(req, fsp);
1521 return NT_STATUS_DELETE_PENDING;
1524 set_share_mode(lck, fsp, conn->server_info->utok.uid, 0, NO_OPLOCK);
1527 * For directories the delete on close bit at open time seems
1528 * always to be honored on close... See test 19 in Samba4 BASE-DELETE.
1530 if (create_options & FILE_DELETE_ON_CLOSE) {
1531 status = can_set_delete_on_close(fsp, True, 0);
1532 if (!NT_STATUS_IS_OK(status) &&
1533 !NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
1534 TALLOC_FREE(lck);
1535 fd_close(fsp);
1536 file_free(req, fsp);
1537 return status;
1540 if (NT_STATUS_IS_OK(status)) {
1541 /* Note that here we set the *inital* delete on close flag,
1542 not the regular one. The magic gets handled in close. */
1543 fsp->initial_delete_on_close = True;
1547 TALLOC_FREE(lck);
1549 if (pinfo) {
1550 *pinfo = info;
1553 *result = fsp;
1554 return NT_STATUS_OK;
1558 * If a main file is opened for delete, all streams need to be checked for
1559 * !FILE_SHARE_DELETE. Do this by opening with DELETE_ACCESS.
1560 * If that works, delete them all by setting the delete on close and close.
1563 static NTSTATUS open_streams_for_delete(connection_struct *conn,
1564 const char *fname)
1566 struct stream_struct *stream_info;
1567 files_struct **streams;
1568 int i;
1569 unsigned int num_streams;
1570 TALLOC_CTX *frame = talloc_stackframe();
1571 NTSTATUS status;
1573 status = SMB_VFS_STREAMINFO(conn, NULL, fname, talloc_tos(),
1574 &num_streams, &stream_info);
1576 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
1577 || NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
1578 DEBUG(10, ("no streams around\n"));
1579 TALLOC_FREE(frame);
1580 return NT_STATUS_OK;
1583 if (!NT_STATUS_IS_OK(status)) {
1584 DEBUG(10, ("SMB_VFS_STREAMINFO failed: %s\n",
1585 nt_errstr(status)));
1586 goto fail;
1589 DEBUG(10, ("open_streams_for_delete found %d streams\n",
1590 num_streams));
1592 if (num_streams == 0) {
1593 TALLOC_FREE(frame);
1594 return NT_STATUS_OK;
1597 streams = TALLOC_ARRAY(talloc_tos(), files_struct *, num_streams);
1598 if (streams == NULL) {
1599 DEBUG(0, ("talloc failed\n"));
1600 status = NT_STATUS_NO_MEMORY;
1601 goto fail;
1604 for (i=0; i<num_streams; i++) {
1605 char *streamname;
1607 if (strequal(stream_info[i].name, "::$DATA")) {
1608 streams[i] = NULL;
1609 continue;
1612 streamname = talloc_asprintf(talloc_tos(), "%s%s", fname,
1613 stream_info[i].name);
1615 if (streamname == NULL) {
1616 DEBUG(0, ("talloc_aprintf failed\n"));
1617 status = NT_STATUS_NO_MEMORY;
1618 goto fail;
1621 status = onefs_create_file_unixpath
1622 (conn, /* conn */
1623 NULL, /* req */
1624 streamname, /* fname */
1625 DELETE_ACCESS, /* access_mask */
1626 FILE_SHARE_READ | FILE_SHARE_WRITE
1627 | FILE_SHARE_DELETE, /* share_access */
1628 FILE_OPEN, /* create_disposition*/
1629 NTCREATEX_OPTIONS_PRIVATE_STREAM_DELETE, /* create_options */
1630 FILE_ATTRIBUTE_NORMAL, /* file_attributes */
1631 0, /* oplock_request */
1632 0, /* allocation_size */
1633 NULL, /* sd */
1634 NULL, /* ea_list */
1635 &streams[i], /* result */
1636 NULL, /* pinfo */
1637 NULL); /* psbuf */
1639 TALLOC_FREE(streamname);
1641 if (!NT_STATUS_IS_OK(status)) {
1642 DEBUG(10, ("Could not open stream %s: %s\n",
1643 streamname, nt_errstr(status)));
1644 break;
1649 * don't touch the variable "status" beyond this point :-)
1652 for (i -= 1 ; i >= 0; i--) {
1653 if (streams[i] == NULL) {
1654 continue;
1657 DEBUG(10, ("Closing stream # %d, %s\n", i,
1658 streams[i]->fsp_name));
1659 close_file(NULL, streams[i], NORMAL_CLOSE);
1662 fail:
1663 TALLOC_FREE(frame);
1664 return status;
1668 * Wrapper around onefs_open_file_ntcreate and onefs_open_directory.
1670 static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
1671 struct smb_request *req,
1672 const char *fname,
1673 uint32_t access_mask,
1674 uint32_t share_access,
1675 uint32_t create_disposition,
1676 uint32_t create_options,
1677 uint32_t file_attributes,
1678 uint32_t oplock_request,
1679 uint64_t allocation_size,
1680 struct security_descriptor *sd,
1681 struct ea_list *ea_list,
1682 files_struct **result,
1683 int *pinfo,
1684 SMB_STRUCT_STAT *psbuf)
1686 SMB_STRUCT_STAT sbuf;
1687 int info = FILE_WAS_OPENED;
1688 files_struct *base_fsp = NULL;
1689 files_struct *fsp = NULL;
1690 NTSTATUS status;
1692 DEBUG(10,("onefs_create_file_unixpath: access_mask = 0x%x "
1693 "file_attributes = 0x%x, share_access = 0x%x, "
1694 "create_disposition = 0x%x create_options = 0x%x "
1695 "oplock_request = 0x%x ea_list = 0x%p, sd = 0x%p, "
1696 "fname = %s\n",
1697 (unsigned int)access_mask,
1698 (unsigned int)file_attributes,
1699 (unsigned int)share_access,
1700 (unsigned int)create_disposition,
1701 (unsigned int)create_options,
1702 (unsigned int)oplock_request,
1703 ea_list, sd, fname));
1705 if (create_options & FILE_OPEN_BY_FILE_ID) {
1706 status = NT_STATUS_NOT_SUPPORTED;
1707 goto fail;
1710 if (create_options & NTCREATEX_OPTIONS_INVALID_PARAM_MASK) {
1711 status = NT_STATUS_INVALID_PARAMETER;
1712 goto fail;
1715 if (req == NULL) {
1716 oplock_request |= INTERNAL_OPEN_ONLY;
1719 if (psbuf != NULL) {
1720 sbuf = *psbuf;
1722 else {
1723 if (SMB_VFS_STAT(conn, fname, &sbuf) == -1) {
1724 SET_STAT_INVALID(sbuf);
1728 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
1729 && (access_mask & DELETE_ACCESS)
1730 && !is_ntfs_stream_name(fname)) {
1732 * We can't open a file with DELETE access if any of the
1733 * streams is open without FILE_SHARE_DELETE
1735 status = open_streams_for_delete(conn, fname);
1737 if (!NT_STATUS_IS_OK(status)) {
1738 goto fail;
1742 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
1743 && is_ntfs_stream_name(fname)
1744 && (!(create_options & NTCREATEX_OPTIONS_PRIVATE_STREAM_DELETE))) {
1745 char *base;
1746 uint32 base_create_disposition;
1748 if (create_options & FILE_DIRECTORY_FILE) {
1749 status = NT_STATUS_NOT_A_DIRECTORY;
1750 goto fail;
1753 status = split_ntfs_stream_name(talloc_tos(), fname,
1754 &base, NULL);
1755 if (!NT_STATUS_IS_OK(status)) {
1756 DEBUG(10, ("onefs_create_file_unixpath: "
1757 "split_ntfs_stream_name failed: %s\n",
1758 nt_errstr(status)));
1759 goto fail;
1762 SMB_ASSERT(!is_ntfs_stream_name(base)); /* paranoia.. */
1764 switch (create_disposition) {
1765 case FILE_OPEN:
1766 base_create_disposition = FILE_OPEN;
1767 break;
1768 default:
1769 base_create_disposition = FILE_OPEN_IF;
1770 break;
1773 status = onefs_create_file_unixpath(
1774 conn, /* conn */
1775 NULL, /* req */
1776 base, /* fname */
1777 0, /* access_mask */
1778 (FILE_SHARE_READ |
1779 FILE_SHARE_WRITE |
1780 FILE_SHARE_DELETE), /* share_access */
1781 base_create_disposition, /* create_disposition*/
1782 0, /* create_options */
1783 0, /* file_attributes */
1784 NO_OPLOCK, /* oplock_request */
1785 0, /* allocation_size */
1786 NULL, /* sd */
1787 NULL, /* ea_list */
1788 &base_fsp, /* result */
1789 NULL, /* pinfo */
1790 NULL); /* psbuf */
1792 if (!NT_STATUS_IS_OK(status)) {
1793 DEBUG(10, ("onefs_create_file_unixpath for base %s "
1794 "failed: %s\n", base, nt_errstr(status)));
1795 goto fail;
1798 * we don't need to low level fd: This might conflict with
1799 * OneFS streams.
1801 fd_close(base_fsp);
1804 /* Covert generic bits in the security descriptor. */
1805 if (sd != NULL) {
1806 security_acl_map_generic(sd->dacl, &file_generic_mapping);
1807 security_acl_map_generic(sd->sacl, &file_generic_mapping);
1811 * If it's a request for a directory open, deal with it separately.
1814 if (create_options & FILE_DIRECTORY_FILE) {
1816 if (create_options & FILE_NON_DIRECTORY_FILE) {
1817 status = NT_STATUS_INVALID_PARAMETER;
1818 goto fail;
1821 /* Can't open a temp directory. IFS kit test. */
1822 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
1823 (file_attributes & FILE_ATTRIBUTE_TEMPORARY)) {
1824 status = NT_STATUS_INVALID_PARAMETER;
1825 goto fail;
1829 * We will get a create directory here if the Win32
1830 * app specified a security descriptor in the
1831 * CreateDirectory() call.
1834 status = onefs_open_directory(
1835 conn, /* conn */
1836 req, /* req */
1837 fname, /* fname */
1838 access_mask, /* access_mask */
1839 share_access, /* share_access */
1840 create_disposition, /* create_disposition*/
1841 create_options, /* create_options */
1842 file_attributes, /* file_attributes */
1843 sd, /* sd */
1844 &fsp, /* result */
1845 &info, /* pinfo */
1846 &sbuf); /* psbuf */
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 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 &sbuf); /* psbuf */
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 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 */
1919 &sbuf); /* psbuf */
1923 if (!NT_STATUS_IS_OK(status)) {
1924 goto fail;
1927 fsp->base_fsp = base_fsp;
1929 SMB_ASSERT(fsp);
1931 if ((ea_list != NULL) && (info == FILE_WAS_CREATED)) {
1932 status = set_ea(conn, fsp, fname, ea_list);
1933 if (!NT_STATUS_IS_OK(status)) {
1934 goto fail;
1938 if (!fsp->is_directory && S_ISDIR(sbuf.st_mode)) {
1939 status = NT_STATUS_ACCESS_DENIED;
1940 goto fail;
1943 /* Save the requested allocation size. */
1944 if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
1945 if (allocation_size
1946 && (allocation_size > sbuf.st_size)) {
1947 fsp->initial_allocation_size = smb_roundup(
1948 fsp->conn, allocation_size);
1949 if (fsp->is_directory) {
1950 /* Can't set allocation size on a directory. */
1951 status = NT_STATUS_ACCESS_DENIED;
1952 goto fail;
1954 if (vfs_allocate_file_space(
1955 fsp, fsp->initial_allocation_size) == -1) {
1956 status = NT_STATUS_DISK_FULL;
1957 goto fail;
1959 } else {
1960 fsp->initial_allocation_size = smb_roundup(
1961 fsp->conn, (uint64_t)sbuf.st_size);
1965 DEBUG(10, ("onefs_create_file_unixpath: info=%d\n", info));
1967 *result = fsp;
1968 if (pinfo != NULL) {
1969 *pinfo = info;
1971 if (psbuf != NULL) {
1972 if ((fsp->fh == NULL) || (fsp->fh->fd == -1)) {
1973 *psbuf = sbuf;
1975 else {
1976 SMB_VFS_FSTAT(fsp, psbuf);
1979 return NT_STATUS_OK;
1981 fail:
1982 DEBUG(10, ("onefs_create_file_unixpath: %s\n", nt_errstr(status)));
1984 if (fsp != NULL) {
1985 if (base_fsp && fsp->base_fsp == base_fsp) {
1987 * The close_file below will close
1988 * fsp->base_fsp.
1990 base_fsp = NULL;
1992 close_file(req, fsp, ERROR_CLOSE);
1993 fsp = NULL;
1995 if (base_fsp != NULL) {
1996 close_file(req, base_fsp, ERROR_CLOSE);
1997 base_fsp = NULL;
1999 return status;
2003 * SMB_VFS_CREATE_FILE interface to onefs.
2005 NTSTATUS onefs_create_file(vfs_handle_struct *handle,
2006 struct smb_request *req,
2007 uint16_t root_dir_fid,
2008 const char *fname,
2009 uint32_t create_file_flags,
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,
2021 SMB_STRUCT_STAT *psbuf)
2023 connection_struct *conn = handle->conn;
2024 struct case_semantics_state *case_state = NULL;
2025 SMB_STRUCT_STAT sbuf;
2026 int info = FILE_WAS_OPENED;
2027 files_struct *fsp = NULL;
2028 NTSTATUS status;
2030 DEBUG(10,("onefs_create_file: access_mask = 0x%x "
2031 "file_attributes = 0x%x, share_access = 0x%x, "
2032 "create_disposition = 0x%x create_options = 0x%x "
2033 "oplock_request = 0x%x "
2034 "root_dir_fid = 0x%x, ea_list = 0x%p, sd = 0x%p, "
2035 "create_file_flags = 0x%x, fname = %s\n",
2036 (unsigned int)access_mask,
2037 (unsigned int)file_attributes,
2038 (unsigned int)share_access,
2039 (unsigned int)create_disposition,
2040 (unsigned int)create_options,
2041 (unsigned int)oplock_request,
2042 (unsigned int)root_dir_fid,
2043 ea_list, sd, create_file_flags, fname));
2045 /* Get the file name if root_dir_fid was specified. */
2046 if (root_dir_fid != 0) {
2047 char *new_fname;
2049 status = get_relative_fid_filename(conn, req, root_dir_fid,
2050 fname, &new_fname);
2051 if (!NT_STATUS_IS_OK(status)) {
2052 goto fail;
2055 fname = new_fname;
2058 /* Resolve the file name if this was a DFS pathname. */
2059 if ((req != NULL) && (req->flags2 & FLAGS2_DFS_PATHNAMES)) {
2060 char *resolved_fname;
2062 status = resolve_dfspath(talloc_tos(), conn, true, fname,
2063 &resolved_fname);
2065 if (!NT_STATUS_IS_OK(status)) {
2067 * For PATH_NOT_COVERED we had
2068 * reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
2069 * ERRSRV, ERRbadpath);
2070 * Need to fix in callers
2072 goto fail;
2074 fname = resolved_fname;
2077 /* Check if POSIX semantics are wanted. */
2078 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
2079 case_state = set_posix_case_semantics(talloc_tos(), conn);
2082 /* Convert dos path to unix path if it hasn't already been done. */
2083 if (create_file_flags & CFF_DOS_PATH) {
2084 char *converted_fname;
2086 SET_STAT_INVALID(sbuf);
2088 status = unix_convert(talloc_tos(), conn, fname, False,
2089 &converted_fname, NULL, &sbuf);
2090 if (!NT_STATUS_IS_OK(status)) {
2091 goto fail;
2093 fname = converted_fname;
2094 } else {
2095 if (psbuf != NULL) {
2096 sbuf = *psbuf;
2097 } else {
2098 if (SMB_VFS_STAT(conn, fname, &sbuf) == -1) {
2099 SET_STAT_INVALID(sbuf);
2105 TALLOC_FREE(case_state);
2107 /* All file access must go through check_name() */
2108 status = check_name(conn, fname);
2109 if (!NT_STATUS_IS_OK(status)) {
2110 goto fail;
2113 status = onefs_create_file_unixpath(
2114 conn, /* conn */
2115 req, /* req */
2116 fname, /* fname */
2117 access_mask, /* access_mask */
2118 share_access, /* share_access */
2119 create_disposition, /* create_disposition*/
2120 create_options, /* create_options */
2121 file_attributes, /* file_attributes */
2122 oplock_request, /* oplock_request */
2123 allocation_size, /* allocation_size */
2124 sd, /* sd */
2125 ea_list, /* ea_list */
2126 &fsp, /* result */
2127 &info, /* pinfo */
2128 &sbuf); /* psbuf */
2130 if (!NT_STATUS_IS_OK(status)) {
2131 goto fail;
2134 DEBUG(10, ("onefs_create_file: info=%d\n", info));
2136 *result = fsp;
2137 if (pinfo != NULL) {
2138 *pinfo = info;
2140 if (psbuf != NULL) {
2141 *psbuf = sbuf;
2143 return NT_STATUS_OK;
2145 fail:
2146 DEBUG(10, ("onefs_create_file: %s\n", nt_errstr(status)));
2148 if (fsp != NULL) {
2149 close_file(req, fsp, ERROR_CLOSE);
2150 fsp = NULL;
2152 return status;