Enable total anonymization in vfs_smb_traffic_analyzer, by mapping any user names...
[Samba/ekacnet.git] / source3 / modules / onefs_open.c
blob1f5f8551ffb0e1196c70841d4a9e4aaad6417f59
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 "onefs.h"
36 #include "smbd/globals.h"
38 extern const struct generic_mapping file_generic_mapping;
40 struct onefs_fsp_data {
41 uint64_t oplock_callback_id;
44 static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
45 struct smb_request *req,
46 const char *fname,
47 uint32_t access_mask,
48 uint32_t share_access,
49 uint32_t create_disposition,
50 uint32_t create_options,
51 uint32_t file_attributes,
52 uint32_t oplock_request,
53 uint64_t allocation_size,
54 struct security_descriptor *sd,
55 struct ea_list *ea_list,
56 files_struct **result,
57 int *pinfo,
58 struct onefs_fsp_data *fsp_data,
59 SMB_STRUCT_STAT *psbuf);
61 /****************************************************************************
62 Open a file.
63 ****************************************************************************/
65 static NTSTATUS onefs_open_file(files_struct *fsp,
66 connection_struct *conn,
67 struct smb_request *req,
68 const char *parent_dir,
69 const char *name,
70 const char *path,
71 SMB_STRUCT_STAT *psbuf,
72 int flags,
73 mode_t unx_mode,
74 uint32 access_mask,
75 uint32 open_access_mask,
76 int oplock_request,
77 uint64 id,
78 uint32 share_access,
79 uint32 create_options,
80 uint32_t new_dos_attributes,
81 struct security_descriptor *sd,
82 int *granted_oplock)
84 NTSTATUS status = NT_STATUS_OK;
85 int accmode = (flags & O_ACCMODE);
86 int local_flags = flags;
87 bool file_existed = VALID_STAT(*psbuf);
88 const char *wild;
89 char *base = NULL;
90 char *stream = NULL;
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", path));
112 return NT_STATUS_ACCESS_DENIED;
113 } else if(flags & O_CREAT) {
114 /* We don't want to write - but we must make sure that
115 O_CREAT doesn't create the file if we have write
116 access into the directory.
118 flags &= ~O_CREAT;
119 local_flags &= ~O_CREAT;
124 * This little piece of insanity is inspired by the
125 * fact that an NT client can open a file for O_RDONLY,
126 * but set the create disposition to FILE_EXISTS_TRUNCATE.
127 * If the client *can* write to the file, then it expects to
128 * truncate the file, even though it is opening for readonly.
129 * Quicken uses this stupid trick in backup file creation...
130 * Thanks *greatly* to "David W. Chapman Jr." <dwcjr@inethouston.net>
131 * for helping track this one down. It didn't bite us in 2.0.x
132 * as we always opened files read-write in that release. JRA.
135 if ((accmode == O_RDONLY) && ((flags & O_TRUNC) == O_TRUNC)) {
136 DEBUG(10,("onefs_open_file: truncate requested on read-only "
137 "open for file %s\n", path));
138 local_flags = (flags & ~O_ACCMODE)|O_RDWR;
141 #if defined(O_NONBLOCK) && defined(S_ISFIFO)
143 * We would block on opening a FIFO with no one else on the
144 * other end. Do what we used to do and add O_NONBLOCK to the
145 * open flags. JRA.
148 if (file_existed && S_ISFIFO(psbuf->st_mode)) {
149 local_flags |= O_NONBLOCK;
151 #endif
153 /* Don't create files with Microsoft wildcard characters. */
154 if (fsp->base_fsp) {
156 * wildcard characters are allowed in stream names
157 * only test the basefilename
159 wild = fsp->base_fsp->fsp_name;
160 } else {
161 wild = path;
163 if ((local_flags & O_CREAT) && !file_existed &&
164 ms_has_wild(wild)) {
166 * XXX: may need to remvoe this return...
168 * We dont think this check needs to exist. All it does is
169 * block creating files with Microsoft wildcards, which is
170 * fine if the creation originated from NFS or locally and
171 * then was copied via Samba.
173 DEBUG(1, ("onefs_open_file: creating file with wildcard: %s\n",
174 path));
175 return NT_STATUS_OBJECT_NAME_INVALID;
178 /* Actually do the open */
180 #ifdef O_NOFOLLOW
182 * Never follow symlinks on a POSIX client. The
183 * client should be doing this.
186 if (fsp->posix_open || !lp_symlinks(SNUM(conn))) {
187 flags |= O_NOFOLLOW;
189 #endif
190 /* Stream handling */
191 if (is_ntfs_stream_name(path)) {
192 status = onefs_split_ntfs_stream_name(talloc_tos(), path,
193 &base, &stream);
195 /* It's a stream, so pass in the base_fd */
196 if (stream != NULL) {
197 SMB_ASSERT(fsp->base_fsp);
200 * We have never seen an oplock taken on a stream, and our
201 * current implementation doesn't support it. If a request is
202 * seen, log a loud error message and ignore the requested
203 * oplock.
205 if ((oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK) !=
206 NO_OPLOCK) {
207 DEBUG(0,("Oplock(%d) being requested on a stream! "
208 "Ignoring oplock request: base=%s, stream=%s",
209 oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK,
210 base, stream));
211 /* Recover by requesting NO_OPLOCK instead. */
212 oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
215 DEBUG(10,("Opening a stream: base=%s(%d), stream=%s",
216 base, fsp->base_fsp->fh->fd, stream));
218 base_fd = fsp->base_fsp->fh->fd;
221 fsp->fh->fd = onefs_sys_create_file(conn,
222 base_fd,
223 stream != NULL ? stream :
224 (base != NULL ? base : path),
225 access_mask,
226 open_access_mask,
227 share_access,
228 create_options,
229 flags,
230 unx_mode,
231 oplock_request,
234 new_dos_attributes,
235 granted_oplock);
237 if (fsp->fh->fd == -1) {
238 if (errno == EMFILE) {
239 static time_t last_warned = 0L;
241 if (time((time_t *) NULL) > last_warned) {
242 DEBUG(0, ("Too many open files, unable "
243 "to open more! smbd's max "
244 "open files = %d, also check "
245 "sysctl kern.maxfiles and "
246 "sysctl kern.maxfilesperproc\n",
247 lp_max_open_files()));
248 last_warned = time((time_t *) NULL);
252 status = map_nt_error_from_unix(errno);
253 DEBUG(3,("Error opening file %s (%s) (local_flags=%d) "
254 "(flags=%d)\n",
255 path, strerror(errno), local_flags, flags));
256 return status;
259 if ((local_flags & O_CREAT) && !file_existed) {
261 /* Inherit the ACL if required */
262 if (lp_inherit_perms(SNUM(conn))) {
263 inherit_access_posix_acl(conn, parent_dir, path,
264 unx_mode);
267 /* Change the owner if required. */
268 if (lp_inherit_owner(SNUM(conn))) {
269 change_file_owner_to_parent(conn, parent_dir,
270 fsp);
273 notify_fname(conn, NOTIFY_ACTION_ADDED,
274 FILE_NOTIFY_CHANGE_FILE_NAME, path);
277 if (!file_existed) {
278 int ret;
280 if (fsp->fh->fd == -1) {
281 ret = SMB_VFS_STAT(conn, path, psbuf);
282 } else {
283 ret = SMB_VFS_FSTAT(fsp, psbuf);
284 /* If we have an fd, this stat should succeed. */
285 if (ret == -1) {
286 DEBUG(0,("Error doing fstat on open file %s "
287 "(%s)\n", path,strerror(errno) ));
291 /* For a non-io open, this stat failing means file not found. JRA */
292 if (ret == -1) {
293 status = map_nt_error_from_unix(errno);
294 fd_close(fsp);
295 return status;
300 * POSIX allows read-only opens of directories. We don't
301 * want to do this (we use a different code path for this)
302 * so catch a directory open and return an EISDIR. JRA.
305 if(S_ISDIR(psbuf->st_mode)) {
306 fd_close(fsp);
307 errno = EISDIR;
308 return NT_STATUS_FILE_IS_A_DIRECTORY;
311 fsp->mode = psbuf->st_mode;
312 fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf);
313 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
314 fsp->file_pid = req ? req->smbpid : 0;
315 fsp->can_lock = True;
316 fsp->can_read = (access_mask & (FILE_READ_DATA)) ? True : False;
317 if (!CAN_WRITE(conn)) {
318 fsp->can_write = False;
319 } else {
320 fsp->can_write = (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ?
321 True : False;
323 fsp->print_file = False;
324 fsp->modified = False;
325 fsp->sent_oplock_break = NO_BREAK_SENT;
326 fsp->is_directory = False;
327 if (conn->aio_write_behind_list &&
328 is_in_path(path, conn->aio_write_behind_list, conn->case_sensitive)) {
329 fsp->aio_write_behind = True;
332 string_set(&fsp->fsp_name, path);
333 fsp->wcp = NULL; /* Write cache pointer. */
335 DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
336 conn->server_info->unix_name,
337 fsp->fsp_name,
338 BOOLSTR(fsp->can_read), BOOLSTR(fsp->can_write),
339 conn->num_files_open));
341 errno = 0;
342 return NT_STATUS_OK;
345 /****************************************************************************
346 Handle the 1 second delay in returning a SHARING_VIOLATION error.
347 ****************************************************************************/
349 static void defer_open(struct share_mode_lock *lck,
350 struct timeval request_time,
351 struct timeval timeout,
352 struct smb_request *req,
353 struct deferred_open_record *state)
355 int i;
357 /* Paranoia check */
359 for (i=0; i<lck->num_share_modes; i++) {
360 struct share_mode_entry *e = &lck->share_modes[i];
362 if (!is_deferred_open_entry(e)) {
363 continue;
366 if (procid_is_me(&e->pid) && (e->op_mid == req->mid)) {
367 DEBUG(0, ("Trying to defer an already deferred "
368 "request: mid=%d, exiting\n", req->mid));
369 exit_server("attempt to defer a deferred request");
373 /* End paranoia check */
375 DEBUG(10,("defer_open_sharing_error: time [%u.%06u] adding deferred "
376 "open entry for mid %u\n",
377 (unsigned int)request_time.tv_sec,
378 (unsigned int)request_time.tv_usec,
379 (unsigned int)req->mid));
381 if (!push_deferred_smb_message(req, request_time, timeout,
382 (char *)state, sizeof(*state))) {
383 exit_server("push_deferred_smb_message failed");
385 add_deferred_open(lck, req->mid, request_time, state->id);
388 * Push the MID of this packet on the signing queue.
389 * We only do this once, the first time we push the packet
390 * onto the deferred open queue, as this has a side effect
391 * of incrementing the response sequence number.
394 srv_defer_sign_response(req->mid);
397 static void schedule_defer_open(struct share_mode_lock *lck,
398 struct timeval request_time,
399 struct smb_request *req)
401 struct deferred_open_record state;
403 /* This is a relative time, added to the absolute
404 request_time value to get the absolute timeout time.
405 Note that if this is the second or greater time we enter
406 this codepath for this particular request mid then
407 request_time is left as the absolute time of the *first*
408 time this request mid was processed. This is what allows
409 the request to eventually time out. */
411 struct timeval timeout;
413 /* Normally the smbd we asked should respond within
414 * OPLOCK_BREAK_TIMEOUT seconds regardless of whether
415 * the client did, give twice the timeout as a safety
416 * measure here in case the other smbd is stuck
417 * somewhere else. */
420 * On OneFS, the kernel will always send an oplock_revoked message
421 * before this timeout is hit.
423 timeout = timeval_set(OPLOCK_BREAK_TIMEOUT*10, 0);
425 /* Nothing actually uses state.delayed_for_oplocks
426 but it's handy to differentiate in debug messages
427 between a 30 second delay due to oplock break, and
428 a 1 second delay for share mode conflicts. */
430 state.delayed_for_oplocks = True;
431 state.failed = false;
432 state.id = lck->id;
434 if (!request_timed_out(request_time, timeout)) {
435 defer_open(lck, request_time, timeout, req, &state);
439 /****************************************************************************
440 Open a file with a share mode. Passed in an already created files_struct.
441 ****************************************************************************/
442 NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
443 struct smb_request *req,
444 const char *fname,
445 uint32 access_mask,
446 uint32 share_access,
447 uint32 create_disposition,
448 uint32 create_options,
449 uint32 new_dos_attributes,
450 int oplock_request,
451 struct security_descriptor *sd,
452 files_struct *fsp,
453 int *pinfo,
454 struct onefs_fsp_data *fsp_data,
455 SMB_STRUCT_STAT *psbuf)
457 int flags=0;
458 int flags2=0;
459 bool file_existed = VALID_STAT(*psbuf);
460 bool def_acl = False;
461 bool posix_open = False;
462 bool new_file_created = False;
463 bool clear_ads = False;
464 struct file_id id;
465 mode_t new_unx_mode = (mode_t)0;
466 mode_t unx_mode = (mode_t)0;
467 int info;
468 uint32 existing_dos_attributes = 0;
469 struct pending_message_list *pml = NULL;
470 struct timeval request_time = timeval_zero();
471 struct share_mode_lock *lck = NULL;
472 uint32 open_access_mask = access_mask;
473 NTSTATUS status;
474 int ret_flock;
475 char *parent_dir;
476 const char *newname;
477 int granted_oplock;
478 uint64_t oplock_callback_id = 0;
479 uint32 createfile_attributes = 0;
481 ZERO_STRUCT(id);
483 if (conn->printer) {
485 * Printers are handled completely differently.
486 * Most of the passed parameters are ignored.
489 if (pinfo) {
490 *pinfo = FILE_WAS_CREATED;
493 DEBUG(10, ("onefs_open_file_ntcreate: printer open fname=%s\n",
494 fname));
496 return print_fsp_open(req, conn, fname, req->vuid, fsp, psbuf);
499 if (!parent_dirname(talloc_tos(), fname, &parent_dir, &newname)) {
500 return NT_STATUS_NO_MEMORY;
503 if (new_dos_attributes & FILE_FLAG_POSIX_SEMANTICS) {
504 posix_open = True;
505 unx_mode = (mode_t)(new_dos_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
506 new_dos_attributes = 0;
507 } else {
508 /* We add aARCH to this as this mode is only used if the file is
509 * created new. */
510 unx_mode = unix_mode(conn, new_dos_attributes | aARCH, fname,
511 parent_dir);
514 DEBUG(10,("onefs_open_file_ntcreate: fname=%s, dos_attrs=0x%x "
515 "access_mask=0x%x share_access=0x%x "
516 "create_disposition = 0x%x create_options=0x%x "
517 "unix mode=0%o oplock_request=0x%x\n",
518 fname, new_dos_attributes, access_mask, share_access,
519 create_disposition, create_options, unx_mode,
520 oplock_request));
523 * Any non-stat-only open has the potential to contend oplocks, which
524 * means to avoid blocking in the kernel (which is unacceptable), the
525 * open must be deferred. In order to defer opens, req must not be
526 * NULL. The known cases of calling with a NULL req:
528 * 1. Open the base file of a stream: Always done stat-only
530 * 2. Open the stream: Oplocks are disallowed on streams, so an
531 * oplock will never be contended.
533 * 3. open_file_fchmod(), which is called from 3 places:
534 * A. try_chown: Posix acls only. Never called on onefs.
535 * B. set_ea_dos_attributes: Can't be called from onefs, because
536 * SMB_VFS_SETXATTR return ENOSYS.
537 * C. file_set_dos_mode: This would only happen if the "dos
538 * filemode" smb.conf parameter is set to yes. We ship with
539 * it off, but if a customer were to turn it on it would be
540 * bad.
542 if (req == NULL && !is_stat_open(access_mask) && !is_ntfs_stream_name(fname)) {
543 smb_panic("NULL req on a non-stat-open!");
546 if ((req == NULL) && ((oplock_request & INTERNAL_OPEN_ONLY) == 0)) {
547 DEBUG(0, ("No smb request but not an internal only open!\n"));
548 return NT_STATUS_INTERNAL_ERROR;
552 * Only non-internal opens can be deferred at all
555 if ((req != NULL)
556 && ((pml = get_open_deferred_message(req->mid)) != NULL)) {
557 struct deferred_open_record *state =
558 (struct deferred_open_record *)pml->private_data.data;
560 /* Remember the absolute time of the original
561 request with this mid. We'll use it later to
562 see if this has timed out. */
564 request_time = pml->request_time;
566 /* Remove the deferred open entry under lock. */
567 lck = get_share_mode_lock(talloc_tos(), state->id, NULL, NULL,
568 NULL);
569 if (lck == NULL) {
570 DEBUG(0, ("could not get share mode lock\n"));
571 } else {
572 del_deferred_open_entry(lck, req->mid);
573 TALLOC_FREE(lck);
576 /* Ensure we don't reprocess this message. */
577 remove_deferred_open_smb_message(req->mid);
580 * When receiving a semlock_async_failure message, the
581 * deferred open will be marked as "failed". Returning
582 * INTERNAL_ERROR.
584 if (state->failed) {
585 DEBUG(0, ("onefs_open_file_ntcreate: "
586 "semlock_async_failure detected!\n"));
587 return NT_STATUS_INTERNAL_ERROR;
591 status = check_name(conn, fname);
592 if (!NT_STATUS_IS_OK(status)) {
593 return status;
596 if (!posix_open) {
597 new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
598 if (file_existed) {
599 existing_dos_attributes = dos_mode(conn, fname, psbuf);
603 /* Setup dos_attributes to be set by ifs_createfile */
604 if (lp_store_dos_attributes(SNUM(conn))) {
605 createfile_attributes = (new_dos_attributes | aARCH) &
606 ~(FILE_ATTRIBUTE_NONINDEXED | FILE_ATTRIBUTE_COMPRESSED);
609 /* Ignore oplock requests if oplocks are disabled. */
610 if (!lp_oplocks(SNUM(conn)) || global_client_failed_oplock_break ||
611 IS_VETO_OPLOCK_PATH(conn, fname)) {
612 /* Mask off everything except the private Samba bits. */
613 oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
616 /* this is for OS/2 long file names - say we don't support them */
617 if (!lp_posix_pathnames() && strstr(fname,".+,;=[].")) {
618 /* OS/2 Workplace shell fix may be main code stream in a later
619 * release. */
620 DEBUG(5,("onefs_open_file_ntcreate: OS/2 long filenames are "
621 "not supported.\n"));
622 if (use_nt_status()) {
623 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
625 return NT_STATUS_DOS(ERRDOS, ERRcannotopen);
628 switch( create_disposition ) {
630 * Currently we're using FILE_SUPERSEDE as the same as
631 * FILE_OVERWRITE_IF but they really are
632 * different. FILE_SUPERSEDE deletes an existing file
633 * (requiring delete access) then recreates it.
635 case FILE_SUPERSEDE:
637 * @todo: Clear all file attributes?
638 * http://www.osronline.com/article.cfm?article=302
639 * create if not exist, trunc if exist
641 * If file exists replace/overwrite. If file doesn't
642 * exist create.
644 flags2 |= (O_CREAT | O_TRUNC);
645 clear_ads = true;
646 break;
648 case FILE_OVERWRITE_IF:
649 /* If file exists replace/overwrite. If file doesn't
650 * exist create. */
651 flags2 |= (O_CREAT | O_TRUNC);
652 clear_ads = true;
653 break;
655 case FILE_OPEN:
656 /* If file exists open. If file doesn't exist error. */
657 if (!file_existed) {
658 DEBUG(5,("onefs_open_file_ntcreate: FILE_OPEN "
659 "requested for file %s and file "
660 "doesn't exist.\n", fname ));
661 errno = ENOENT;
662 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
664 break;
666 case FILE_OVERWRITE:
667 /* If file exists overwrite. If file doesn't exist
668 * error. */
669 if (!file_existed) {
670 DEBUG(5, ("onefs_open_file_ntcreate: "
671 "FILE_OVERWRITE requested for file "
672 "%s and file doesn't exist.\n",
673 fname));
674 errno = ENOENT;
675 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
677 flags2 |= O_TRUNC;
678 clear_ads = true;
679 break;
681 case FILE_CREATE:
682 /* If file exists error. If file doesn't exist
683 * create. */
684 if (file_existed) {
685 DEBUG(5, ("onefs_open_file_ntcreate: "
686 "FILE_CREATE requested for file %s "
687 "and file already exists.\n",
688 fname));
689 if (S_ISDIR(psbuf->st_mode)) {
690 errno = EISDIR;
691 } else {
692 errno = EEXIST;
694 return map_nt_error_from_unix(errno);
696 flags2 |= (O_CREAT|O_EXCL);
697 break;
699 case FILE_OPEN_IF:
700 /* If file exists open. If file doesn't exist
701 * create. */
702 flags2 |= O_CREAT;
703 break;
705 default:
706 return NT_STATUS_INVALID_PARAMETER;
709 /* Match attributes on file exists and overwrite. */
710 if (!posix_open && file_existed &&
711 ((create_disposition == FILE_OVERWRITE) ||
712 (create_disposition == FILE_OVERWRITE_IF))) {
713 if (!open_match_attributes(conn, fname,
714 existing_dos_attributes,
715 new_dos_attributes, psbuf->st_mode,
716 unx_mode, &new_unx_mode)) {
717 DEBUG(5, ("onefs_open_file_ntcreate: attributes "
718 "missmatch for file %s (%x %x) (0%o, 0%o)\n",
719 fname, existing_dos_attributes,
720 new_dos_attributes,
721 (unsigned int)psbuf->st_mode,
722 (unsigned int)unx_mode ));
723 errno = EACCES;
724 return NT_STATUS_ACCESS_DENIED;
729 * OneFS understands MAXIMUM_ALLOWED_ACCESS, so only hack the
730 * access_mask, but leave the MAA for the actual open in
731 * open_access_mask.
733 open_access_mask = access_mask;
734 if (open_access_mask & MAXIMUM_ALLOWED_ACCESS) {
735 access_mask |= FILE_GENERIC_ALL;
738 /* Convert GENERIC bits to specific bits. */
739 se_map_generic(&access_mask, &file_generic_mapping);
740 se_map_generic(&open_access_mask, &file_generic_mapping);
742 if ((flags2 & O_TRUNC) || (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE)) {
743 /* This will cause oplock breaks. */
744 open_access_mask |= FILE_WRITE_DATA;
747 if (lp_parm_bool(SNUM(fsp->conn), PARM_ONEFS_TYPE,
748 PARM_IGNORE_SACLS, PARM_IGNORE_SACLS_DEFAULT)) {
749 access_mask &= ~SYSTEM_SECURITY_ACCESS;
752 DEBUG(10, ("onefs_open_file_ntcreate: fname=%s, after mapping "
753 "open_access_mask=%#x, access_mask=0x%x\n",
754 fname, open_access_mask, access_mask));
757 * Note that we ignore the append flag as append does not
758 * mean the same thing under DOS and Unix.
761 if ((access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ||
762 (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE)) {
765 * DENY_DOS opens are always underlying read-write on the
766 * file handle, no matter what the requested access mask
767 * says. Stock samba just sets the flags, but since
768 * ifs_createfile uses the access_mask, it must be updated as
769 * well. This allows BASE-DENY* to pass.
771 if (create_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) {
773 DEBUG(10,("onefs_open_file_ntcreate: deny_dos: "
774 "Adding O_RDWR to flags "
775 "(0x%x) and some READ bits to "
776 "open_access_mask (0x%x)\n",
777 flags, open_access_mask));
779 flags = O_RDWR;
780 open_access_mask |= (FILE_READ_ATTRIBUTES |
781 FILE_READ_DATA | FILE_READ_EA | FILE_EXECUTE);
783 } else if (access_mask & (FILE_READ_ATTRIBUTES |
784 FILE_READ_DATA |
785 FILE_READ_EA |
786 FILE_EXECUTE)) {
787 flags = O_RDWR;
788 } else {
789 flags = O_WRONLY;
791 } else {
792 flags = O_RDONLY;
795 /* Currently we only look at FILE_WRITE_THROUGH for create options. */
796 #if defined(O_SYNC)
797 if ((create_options & FILE_WRITE_THROUGH) &&
798 lp_strict_sync(SNUM(conn))) {
799 flags2 |= O_SYNC;
801 #endif /* O_SYNC */
803 if (posix_open && (access_mask & FILE_APPEND_DATA)) {
804 flags2 |= O_APPEND;
807 if (!posix_open && !CAN_WRITE(conn)) {
809 * We should really return a permission denied error if either
810 * O_CREAT or O_TRUNC are set, but for compatibility with
811 * older versions of Samba we just AND them out.
813 flags2 &= ~(O_CREAT|O_TRUNC);
815 /* Deny DELETE_ACCESS explicitly if the share is read only. */
816 if (access_mask & DELETE_ACCESS) {
817 return map_nt_error_from_unix(EACCES);
821 /* Ensure we can't write on a read-only share or file. */
822 if (flags != O_RDONLY && file_existed &&
823 (!CAN_WRITE(conn) || IS_DOS_READONLY(existing_dos_attributes))) {
824 DEBUG(5, ("onefs_open_file_ntcreate: write access requested "
825 "for file %s on read only %s\n",
826 fname, !CAN_WRITE(conn) ? "share" : "file" ));
827 errno = EACCES;
828 return NT_STATUS_ACCESS_DENIED;
831 DEBUG(10, ("fsp = %p\n", fsp));
833 fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf);
834 fsp->share_access = share_access;
835 fsp->fh->private_options = create_options;
836 fsp->access_mask = open_access_mask; /* We change this to the
837 * requested access_mask after
838 * the open is done. */
839 fsp->posix_open = posix_open;
841 /* Ensure no SAMBA_PRIVATE bits can be set. */
842 fsp->oplock_type = (oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK);
844 if (timeval_is_zero(&request_time)) {
845 request_time = fsp->open_time;
848 if (file_existed) {
849 struct timespec old_write_time = get_mtimespec(psbuf);
850 id = vfs_file_id_from_sbuf(conn, psbuf);
852 lck = get_share_mode_lock(talloc_tos(), id,
853 conn->connectpath,
854 fname, &old_write_time);
856 if (lck == NULL) {
857 DEBUG(0, ("Could not get share mode lock\n"));
858 return NT_STATUS_SHARING_VIOLATION;
861 if (lck->delete_on_close) {
862 /* DELETE_PENDING is not deferred for a second */
863 TALLOC_FREE(lck);
864 return NT_STATUS_DELETE_PENDING;
868 SMB_ASSERT(!file_existed || (lck != NULL));
871 * Ensure we pay attention to default ACLs on directories. May be
872 * neccessary depending on ACL policies.
874 if ((flags2 & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
875 (def_acl = directory_has_default_acl(conn, parent_dir))) {
876 unx_mode = 0777;
879 DEBUG(4,("calling onefs_open_file with flags=0x%X flags2=0x%X "
880 "mode=0%o, access_mask = 0x%x, open_access_mask = 0x%x\n",
881 (unsigned int)flags, (unsigned int)flags2,
882 (unsigned int)unx_mode, (unsigned int)access_mask,
883 (unsigned int)open_access_mask));
886 * Since the open is guaranteed to be stat only if req == NULL, a
887 * callback record is only needed if req != NULL.
889 if (req) {
890 SMB_ASSERT(fsp_data);
891 oplock_callback_id = onefs_oplock_wait_record(req->mid);
892 if (oplock_callback_id == 0) {
893 return NT_STATUS_NO_MEMORY;
895 } else {
897 * It is also already asserted it's either a stream or a
898 * stat-only open at this point.
900 SMB_ASSERT(fsp->oplock_type == NO_OPLOCK);
903 /* Do the open. */
904 status = onefs_open_file(fsp,
905 conn,
906 req,
907 parent_dir,
908 newname,
909 fname,
910 psbuf,
911 flags|flags2,
912 unx_mode,
913 access_mask,
914 open_access_mask,
915 fsp->oplock_type,
916 oplock_callback_id,
917 share_access,
918 create_options,
919 createfile_attributes,
921 &granted_oplock);
923 if (!NT_STATUS_IS_OK(status)) {
925 /* OneFS Oplock Handling */
926 if (errno == EINPROGRESS) {
928 if (lck == NULL) {
930 struct deferred_open_record state;
931 struct timespec old_write_time;
933 old_write_time = get_mtimespec(psbuf);
935 DEBUG(3, ("Someone created file %s with an "
936 "oplock after we looked: Retrying\n",
937 fname));
939 * We hit the race that when we did the stat
940 * on the file it did not exist, and someone
941 * has created it in between the stat and the
942 * open_file() call. Just retry immediately.
944 id = vfs_file_id_from_sbuf(conn, psbuf);
945 if (!(lck = get_share_mode_lock(talloc_tos(),
946 id, conn->connectpath, fname,
947 &old_write_time))) {
949 * Emergency exit
951 DEBUG(0, ("onefs_open_file_ntcreate: "
952 "Could not get share mode "
953 "lock for %s\n", fname));
954 status = NT_STATUS_SHARING_VIOLATION;
955 goto cleanup_destroy;
958 state.delayed_for_oplocks = False;
959 state.id = id;
961 if (req != NULL) {
962 defer_open(lck, request_time,
963 timeval_zero(), req, &state);
965 goto cleanup_destroy;
967 /* Waiting for an oplock */
968 DEBUG(5,("Async createfile because a client has an "
969 "oplock on %s\n", fname));
971 SMB_ASSERT(req);
972 schedule_defer_open(lck, request_time, req);
973 goto cleanup;
976 /* Check for a sharing violation */
977 if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
978 uint32 can_access_mask;
979 bool can_access = True;
981 /* Check if this can be done with the deny_dos and fcb
982 * calls. */
984 /* Try to find dup fsp if possible. */
985 if (create_options &
986 (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS|
987 NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) {
989 if (req == NULL) {
990 DEBUG(0, ("DOS open without an SMB "
991 "request!\n"));
992 status = NT_STATUS_INTERNAL_ERROR;
993 goto cleanup_destroy;
996 /* Use the client requested access mask here,
997 * not the one we open with. */
998 status = fcb_or_dos_open(req,
999 conn,
1000 fsp,
1001 fname,
1003 req->smbpid,
1004 req->vuid,
1005 access_mask,
1006 share_access,
1007 create_options);
1009 if (NT_STATUS_IS_OK(status)) {
1010 TALLOC_FREE(lck);
1011 if (pinfo) {
1012 *pinfo = FILE_WAS_OPENED;
1014 status = NT_STATUS_OK;
1015 goto cleanup;
1020 * This next line is a subtlety we need for
1021 * MS-Access. If a file open will fail due to share
1022 * permissions and also for security (access) reasons,
1023 * we need to return the access failed error, not the
1024 * share error. We can't open the file due to kernel
1025 * oplock deadlock (it's possible we failed above on
1026 * the open_mode_check()) so use a userspace check.
1029 if (flags & O_RDWR) {
1030 can_access_mask = FILE_READ_DATA|FILE_WRITE_DATA;
1031 } else if (flags & O_WRONLY) {
1032 can_access_mask = FILE_WRITE_DATA;
1033 } else {
1034 can_access_mask = FILE_READ_DATA;
1037 if (((can_access_mask & FILE_WRITE_DATA) && !CAN_WRITE(conn)) ||
1038 !can_access_file_data(conn,fname,psbuf,can_access_mask)) {
1039 can_access = False;
1043 * If we're returning a share violation, ensure we
1044 * cope with the braindead 1 second delay.
1046 if (!(oplock_request & INTERNAL_OPEN_ONLY) &&
1047 lp_defer_sharing_violations()) {
1048 struct timeval timeout;
1049 struct deferred_open_record state;
1050 int timeout_usecs;
1052 /* this is a hack to speed up torture tests
1053 in 'make test' */
1054 timeout_usecs = lp_parm_int(SNUM(conn),
1055 "smbd","sharedelay",
1056 SHARING_VIOLATION_USEC_WAIT);
1058 /* This is a relative time, added to the
1059 absolute request_time value to get the
1060 absolute timeout time. Note that if this
1061 is the second or greater time we enter this
1062 codepath for this particular request mid
1063 then request_time is left as the absolute
1064 time of the *first* time this request mid
1065 was processed. This is what allows the
1066 request to eventually time out. */
1068 timeout = timeval_set(0, timeout_usecs);
1070 /* Nothing actually uses
1071 state.delayed_for_oplocks but it's handy to
1072 differentiate in debug messages between a
1073 30 second delay due to oplock break, and a
1074 1 second delay for share mode conflicts. */
1076 state.delayed_for_oplocks = False;
1077 state.id = id;
1078 state.failed = false;
1080 if ((req != NULL)
1081 && !request_timed_out(request_time,
1082 timeout)) {
1083 defer_open(lck, request_time, timeout,
1084 req, &state);
1088 if (can_access) {
1090 * We have detected a sharing violation here
1091 * so return the correct error code
1093 status = NT_STATUS_SHARING_VIOLATION;
1094 } else {
1095 status = NT_STATUS_ACCESS_DENIED;
1098 goto cleanup_destroy;
1102 * Normal error, for example EACCES
1104 cleanup_destroy:
1105 if (oplock_callback_id != 0) {
1106 destroy_onefs_callback_record(oplock_callback_id);
1108 cleanup:
1109 TALLOC_FREE(lck);
1110 return status;
1113 fsp->oplock_type = granted_oplock;
1115 if (oplock_callback_id != 0) {
1116 onefs_set_oplock_callback(oplock_callback_id, fsp);
1117 fsp_data->oplock_callback_id = oplock_callback_id;
1118 } else {
1119 SMB_ASSERT(fsp->oplock_type == NO_OPLOCK);
1122 if (!file_existed) {
1123 struct timespec old_write_time = get_mtimespec(psbuf);
1125 * Deal with the race condition where two smbd's detect the
1126 * file doesn't exist and do the create at the same time. One
1127 * of them will win and set a share mode, the other (ie. this
1128 * one) should check if the requested share mode for this
1129 * create is allowed.
1133 * Now the file exists and fsp is successfully opened,
1134 * fsp->dev and fsp->inode are valid and should replace the
1135 * dev=0,inode=0 from a non existent file. Spotted by
1136 * Nadav Danieli <nadavd@exanet.com>. JRA.
1139 id = fsp->file_id;
1141 lck = get_share_mode_lock(talloc_tos(), id,
1142 conn->connectpath,
1143 fname, &old_write_time);
1145 if (lck == NULL) {
1146 DEBUG(0, ("onefs_open_file_ntcreate: Could not get "
1147 "share mode lock for %s\n", fname));
1148 fd_close(fsp);
1149 return NT_STATUS_SHARING_VIOLATION;
1152 if (lck->delete_on_close) {
1153 status = NT_STATUS_DELETE_PENDING;
1156 if (!NT_STATUS_IS_OK(status)) {
1157 struct deferred_open_record state;
1159 fd_close(fsp);
1161 state.delayed_for_oplocks = False;
1162 state.id = id;
1164 /* Do it all over again immediately. In the second
1165 * round we will find that the file existed and handle
1166 * the DELETE_PENDING and FCB cases correctly. No need
1167 * to duplicate the code here. Essentially this is a
1168 * "goto top of this function", but don't tell
1169 * anybody... */
1171 if (req != NULL) {
1172 defer_open(lck, request_time, timeval_zero(),
1173 req, &state);
1175 TALLOC_FREE(lck);
1176 return status;
1180 * We exit this block with the share entry *locked*.....
1185 SMB_ASSERT(lck != NULL);
1187 /* Delete streams if create_disposition requires it */
1188 if (file_existed && clear_ads) {
1189 status = delete_all_streams(conn, fname);
1190 if (!NT_STATUS_IS_OK(status)) {
1191 TALLOC_FREE(lck);
1192 fd_close(fsp);
1193 return status;
1197 /* note that we ignore failure for the following. It is
1198 basically a hack for NFS, and NFS will never set one of
1199 these only read them. Nobody but Samba can ever set a deny
1200 mode and we have already checked our more authoritative
1201 locking database for permission to set this deny mode. If
1202 the kernel refuses the operations then the kernel is wrong.
1203 note that GPFS supports it as well - jmcd */
1205 if (fsp->fh->fd != -1) {
1206 ret_flock = SMB_VFS_KERNEL_FLOCK(fsp, share_access);
1207 if(ret_flock == -1 ){
1209 TALLOC_FREE(lck);
1210 fd_close(fsp);
1211 return NT_STATUS_SHARING_VIOLATION;
1216 * At this point onwards, we can guarentee that the share entry
1217 * is locked, whether we created the file or not, and that the
1218 * deny mode is compatible with all current opens.
1221 /* Record the options we were opened with. */
1222 fsp->share_access = share_access;
1223 fsp->fh->private_options = create_options;
1225 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
1227 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
1229 if (file_existed) {
1230 /* stat opens on existing files don't get oplocks. */
1231 if (is_stat_open(open_access_mask)) {
1232 fsp->oplock_type = NO_OPLOCK;
1235 if (!(flags2 & O_TRUNC)) {
1236 info = FILE_WAS_OPENED;
1237 } else {
1238 info = FILE_WAS_OVERWRITTEN;
1240 } else {
1241 info = FILE_WAS_CREATED;
1244 if (pinfo) {
1245 *pinfo = info;
1249 * Setup the oplock info in both the shared memory and
1250 * file structs.
1253 if ((fsp->oplock_type != NO_OPLOCK) &&
1254 (fsp->oplock_type != FAKE_LEVEL_II_OPLOCK)) {
1255 if (!set_file_oplock(fsp, fsp->oplock_type)) {
1256 /* Could not get the kernel oplock */
1257 fsp->oplock_type = NO_OPLOCK;
1261 if (fsp->oplock_type == LEVEL_II_OPLOCK &&
1262 (!lp_level2_oplocks(SNUM(conn)) ||
1263 !(global_client_caps & CAP_LEVEL_II_OPLOCKS))) {
1265 DEBUG(5, ("Downgrading level2 oplock on open "
1266 "because level2 oplocks = off\n"));
1268 release_file_oplock(fsp);
1271 if (info == FILE_WAS_OVERWRITTEN || info == FILE_WAS_CREATED ||
1272 info == FILE_WAS_SUPERSEDED) {
1273 new_file_created = True;
1276 set_share_mode(lck, fsp, conn->server_info->utok.uid, 0,
1277 fsp->oplock_type);
1279 /* Handle strange delete on close create semantics. */
1280 if (create_options & FILE_DELETE_ON_CLOSE) {
1281 status = can_set_delete_on_close(fsp, True, new_dos_attributes);
1283 if (!NT_STATUS_IS_OK(status)) {
1284 /* Remember to delete the mode we just added. */
1285 del_share_mode(lck, fsp);
1286 TALLOC_FREE(lck);
1287 fd_close(fsp);
1288 return status;
1290 /* Note that here we set the *inital* delete on close flag,
1291 not the regular one. The magic gets handled in close. */
1292 fsp->initial_delete_on_close = True;
1296 * Take care of inherited ACLs on created files - if default ACL not
1297 * selected.
1298 * May be necessary depending on acl policies.
1300 if (!posix_open && !file_existed && !def_acl && !(VALID_STAT(*psbuf)
1301 && (psbuf->st_flags & SF_HASNTFSACL))) {
1303 int saved_errno = errno; /* We might get ENOSYS in the next
1304 * call.. */
1306 if (SMB_VFS_FCHMOD_ACL(fsp, unx_mode) == -1 &&
1307 errno == ENOSYS) {
1308 errno = saved_errno; /* Ignore ENOSYS */
1311 } else if (new_unx_mode) {
1313 int ret = -1;
1315 /* Attributes need changing. File already existed. */
1318 int saved_errno = errno; /* We might get ENOSYS in the
1319 * next call.. */
1320 ret = SMB_VFS_FCHMOD_ACL(fsp, new_unx_mode);
1322 if (ret == -1 && errno == ENOSYS) {
1323 errno = saved_errno; /* Ignore ENOSYS */
1324 } else {
1325 DEBUG(5, ("onefs_open_file_ntcreate: reset "
1326 "attributes of file %s to 0%o\n",
1327 fname, (unsigned int)new_unx_mode));
1328 ret = 0; /* Don't do the fchmod below. */
1332 if ((ret == -1) &&
1333 (SMB_VFS_FCHMOD(fsp, new_unx_mode) == -1))
1334 DEBUG(5, ("onefs_open_file_ntcreate: failed to reset "
1335 "attributes of file %s to 0%o\n",
1336 fname, (unsigned int)new_unx_mode));
1339 /* If this is a successful open, we must remove any deferred open
1340 * records. */
1341 if (req != NULL) {
1342 del_deferred_open_entry(lck, req->mid);
1344 TALLOC_FREE(lck);
1346 return NT_STATUS_OK;
1350 /****************************************************************************
1351 Open a directory from an NT SMB call.
1352 ****************************************************************************/
1353 static NTSTATUS onefs_open_directory(connection_struct *conn,
1354 struct smb_request *req,
1355 const char *fname,
1356 uint32 access_mask,
1357 uint32 share_access,
1358 uint32 create_disposition,
1359 uint32 create_options,
1360 uint32 file_attributes,
1361 struct security_descriptor *sd,
1362 files_struct **result,
1363 int *pinfo,
1364 SMB_STRUCT_STAT *psbuf)
1366 files_struct *fsp = NULL;
1367 struct share_mode_lock *lck = NULL;
1368 NTSTATUS status;
1369 struct timespec mtimespec;
1370 int info = 0;
1371 char *parent_dir;
1372 const char *dirname;
1373 bool posix_open = false;
1374 uint32 create_flags = 0;
1375 uint32 mode = lp_dir_mask(SNUM(conn));
1377 DEBUG(5, ("onefs_open_directory: opening directory %s, "
1378 "access_mask = 0x%x, "
1379 "share_access = 0x%x create_options = 0x%x, "
1380 "create_disposition = 0x%x, file_attributes = 0x%x\n",
1381 fname, (unsigned int)access_mask, (unsigned int)share_access,
1382 (unsigned int)create_options, (unsigned int)create_disposition,
1383 (unsigned int)file_attributes));
1385 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
1386 (conn->fs_capabilities & FILE_NAMED_STREAMS) &&
1387 is_ntfs_stream_name(fname)) {
1388 DEBUG(2, ("onefs_open_directory: %s is a stream name!\n", fname));
1389 return NT_STATUS_NOT_A_DIRECTORY;
1392 switch (create_disposition) {
1393 case FILE_OPEN:
1394 /* If directory exists open. If directory doesn't
1395 * exist error. */
1396 create_flags = 0;
1397 info = FILE_WAS_OPENED;
1398 break;
1399 case FILE_CREATE:
1400 /* If directory exists error. If directory doesn't
1401 * exist create. */
1402 create_flags = O_CREAT | O_EXCL;
1403 info = FILE_WAS_CREATED;
1404 break;
1405 case FILE_OPEN_IF:
1406 /* If directory exists open. If directory doesn't
1407 * exist create. */
1409 /* Note: in order to return whether the directory was
1410 * opened or created, we first try to open and then try
1411 * to create. */
1412 create_flags = 0;
1413 info = FILE_WAS_OPENED;
1414 break;
1415 case FILE_SUPERSEDE:
1416 case FILE_OVERWRITE:
1417 case FILE_OVERWRITE_IF:
1418 default:
1419 DEBUG(5, ("onefs_open_directory: invalid "
1420 "create_disposition 0x%x for directory %s\n",
1421 (unsigned int)create_disposition, fname));
1422 return NT_STATUS_INVALID_PARAMETER;
1426 * Check for write access to the share. Done in mkdir_internal() in
1427 * mainline samba.
1429 if (!CAN_WRITE(conn) && (create_flags & O_CREAT)) {
1430 return NT_STATUS_ACCESS_DENIED;
1433 /* Get parent dirname */
1434 if (!parent_dirname(talloc_tos(), fname, &parent_dir, &dirname)) {
1435 return NT_STATUS_NO_MEMORY;
1438 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
1439 posix_open = true;
1440 mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
1441 file_attributes = 0;
1442 } else {
1443 mode = unix_mode(conn, aDIR, fname, parent_dir);
1447 * The NONINDEXED and COMPRESSED bits seem to always be cleared on
1448 * directories, no matter if you specify that they should be set.
1450 file_attributes &=
1451 ~(FILE_ATTRIBUTE_NONINDEXED | FILE_ATTRIBUTE_COMPRESSED);
1453 status = file_new(req, conn, &fsp);
1454 if(!NT_STATUS_IS_OK(status)) {
1455 return status;
1459 * Actual open with retry magic to handle FILE_OPEN_IF which is
1460 * unique because the kernel won't tell us if the file was opened or
1461 * created.
1463 retry_open:
1464 fsp->fh->fd = onefs_sys_create_file(conn,
1466 fname,
1467 access_mask,
1468 access_mask,
1469 share_access,
1470 create_options,
1471 create_flags | O_DIRECTORY,
1472 mode,
1476 file_attributes,
1477 NULL);
1479 if (fsp->fh->fd == -1) {
1480 DEBUG(3, ("Error opening %s. Errno=%d (%s).\n", fname, errno,
1481 strerror(errno)));
1482 SMB_ASSERT(errno != EINPROGRESS);
1484 if (create_disposition == FILE_OPEN_IF) {
1485 if (errno == ENOENT) {
1486 /* Try again, creating it this time. */
1487 create_flags = O_CREAT | O_EXCL;
1488 info = FILE_WAS_CREATED;
1489 goto retry_open;
1490 } else if (errno == EEXIST) {
1491 /* Uggh. Try again again. */
1492 create_flags = 0;
1493 info = FILE_WAS_OPENED;
1494 goto retry_open;
1498 /* Error cases below: */
1499 file_free(req, fsp);
1501 if ((errno == ENOENT) && (create_disposition == FILE_OPEN)) {
1502 DEBUG(5,("onefs_open_directory: FILE_OPEN requested "
1503 "for directory %s and it doesn't "
1504 "exist.\n", fname ));
1505 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1506 } else if ((errno == EEXIST) &&
1507 (create_disposition == FILE_CREATE)) {
1508 DEBUG(5,("onefs_open_directory: FILE_CREATE "
1509 "requested for directory %s and it "
1510 "already exists.\n", fname ));
1511 return NT_STATUS_OBJECT_NAME_COLLISION;
1512 } else if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
1513 /* Catch sharing violations. */
1514 return NT_STATUS_SHARING_VIOLATION;
1517 return map_nt_error_from_unix(errno);
1520 if (info == FILE_WAS_CREATED) {
1522 /* Pulled from mkdir_internal() */
1523 if (SMB_VFS_LSTAT(conn, fname, psbuf) == -1) {
1524 DEBUG(2, ("Could not stat directory '%s' just "
1525 "created: %s\n",fname, strerror(errno)));
1526 return map_nt_error_from_unix(errno);
1529 if (!S_ISDIR(psbuf->st_mode)) {
1530 DEBUG(0, ("Directory just '%s' created is not a "
1531 "directory\n", fname));
1532 return NT_STATUS_ACCESS_DENIED;
1535 if (!posix_open) {
1537 * Check if high bits should have been set, then (if
1538 * bits are missing): add them. Consider bits
1539 * automagically set by UNIX, i.e. SGID bit from
1540 * parent dir.
1542 if (mode & ~(S_IRWXU|S_IRWXG|S_IRWXO) &&
1543 (mode & ~psbuf->st_mode)) {
1544 SMB_VFS_CHMOD(conn, fname, (psbuf->st_mode |
1545 (mode & ~psbuf->st_mode)));
1549 /* Change the owner if required. */
1550 if (lp_inherit_owner(SNUM(conn))) {
1551 change_dir_owner_to_parent(conn, parent_dir, fname,
1552 psbuf);
1555 notify_fname(conn, NOTIFY_ACTION_ADDED,
1556 FILE_NOTIFY_CHANGE_DIR_NAME, fname);
1559 /* Stat the fd for Samba bookkeeping. */
1560 if(SMB_VFS_FSTAT(fsp, psbuf) != 0) {
1561 fd_close(fsp);
1562 file_free(req, fsp);
1563 return map_nt_error_from_unix(errno);
1566 /* Setup the files_struct for it. */
1567 fsp->mode = psbuf->st_mode;
1568 fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf);
1569 fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
1570 fsp->file_pid = req ? req->smbpid : 0;
1571 fsp->can_lock = False;
1572 fsp->can_read = False;
1573 fsp->can_write = False;
1575 fsp->share_access = share_access;
1576 fsp->fh->private_options = create_options;
1578 * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
1580 fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
1581 fsp->print_file = False;
1582 fsp->modified = False;
1583 fsp->oplock_type = NO_OPLOCK;
1584 fsp->sent_oplock_break = NO_BREAK_SENT;
1585 fsp->is_directory = True;
1586 fsp->posix_open = posix_open;
1588 string_set(&fsp->fsp_name,fname);
1590 mtimespec = get_mtimespec(psbuf);
1593 * Still set the samba share mode lock for correct delete-on-close
1594 * semantics and to make smbstatus more useful.
1596 lck = get_share_mode_lock(talloc_tos(), fsp->file_id,
1597 conn->connectpath,
1598 fname, &mtimespec);
1600 if (lck == NULL) {
1601 DEBUG(0, ("onefs_open_directory: Could not get share mode "
1602 "lock for %s\n", fname));
1603 fd_close(fsp);
1604 file_free(req, fsp);
1605 return NT_STATUS_SHARING_VIOLATION;
1608 if (lck->delete_on_close) {
1609 TALLOC_FREE(lck);
1610 fd_close(fsp);
1611 file_free(req, fsp);
1612 return NT_STATUS_DELETE_PENDING;
1615 set_share_mode(lck, fsp, conn->server_info->utok.uid, 0, NO_OPLOCK);
1618 * For directories the delete on close bit at open time seems
1619 * always to be honored on close... See test 19 in Samba4 BASE-DELETE.
1621 if (create_options & FILE_DELETE_ON_CLOSE) {
1622 status = can_set_delete_on_close(fsp, True, 0);
1623 if (!NT_STATUS_IS_OK(status) &&
1624 !NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
1625 TALLOC_FREE(lck);
1626 fd_close(fsp);
1627 file_free(req, fsp);
1628 return status;
1631 if (NT_STATUS_IS_OK(status)) {
1632 /* Note that here we set the *inital* delete on close flag,
1633 not the regular one. The magic gets handled in close. */
1634 fsp->initial_delete_on_close = True;
1638 TALLOC_FREE(lck);
1640 if (pinfo) {
1641 *pinfo = info;
1644 *result = fsp;
1645 return NT_STATUS_OK;
1649 * If a main file is opened for delete, all streams need to be checked for
1650 * !FILE_SHARE_DELETE. Do this by opening with DELETE_ACCESS.
1651 * If that works, delete them all by setting the delete on close and close.
1654 static NTSTATUS open_streams_for_delete(connection_struct *conn,
1655 const char *fname)
1657 struct stream_struct *stream_info;
1658 files_struct **streams;
1659 int i;
1660 unsigned int num_streams;
1661 TALLOC_CTX *frame = talloc_stackframe();
1662 NTSTATUS status;
1664 status = SMB_VFS_STREAMINFO(conn, NULL, fname, talloc_tos(),
1665 &num_streams, &stream_info);
1667 if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
1668 || NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
1669 DEBUG(10, ("no streams around\n"));
1670 TALLOC_FREE(frame);
1671 return NT_STATUS_OK;
1674 if (!NT_STATUS_IS_OK(status)) {
1675 DEBUG(10, ("SMB_VFS_STREAMINFO failed: %s\n",
1676 nt_errstr(status)));
1677 goto fail;
1680 DEBUG(10, ("open_streams_for_delete found %d streams\n",
1681 num_streams));
1683 if (num_streams == 0) {
1684 TALLOC_FREE(frame);
1685 return NT_STATUS_OK;
1688 streams = TALLOC_ARRAY(talloc_tos(), files_struct *, num_streams);
1689 if (streams == NULL) {
1690 DEBUG(0, ("talloc failed\n"));
1691 status = NT_STATUS_NO_MEMORY;
1692 goto fail;
1695 /* Open the base file */
1697 for (i=0; i<num_streams; i++) {
1698 char *streamname;
1700 if (strequal(stream_info[i].name, "::$DATA")) {
1701 streams[i] = NULL;
1702 continue;
1705 streamname = talloc_asprintf(talloc_tos(), "%s%s", fname,
1706 stream_info[i].name);
1708 if (streamname == NULL) {
1709 DEBUG(0, ("talloc_aprintf failed\n"));
1710 status = NT_STATUS_NO_MEMORY;
1711 goto fail;
1714 status = onefs_create_file_unixpath
1715 (conn, /* conn */
1716 NULL, /* req */
1717 streamname, /* fname */
1718 DELETE_ACCESS, /* access_mask */
1719 FILE_SHARE_READ | FILE_SHARE_WRITE
1720 | FILE_SHARE_DELETE, /* share_access */
1721 FILE_OPEN, /* create_disposition*/
1722 NTCREATEX_OPTIONS_PRIVATE_STREAM_DELETE, /* create_options */
1723 FILE_ATTRIBUTE_NORMAL, /* file_attributes */
1724 0, /* oplock_request */
1725 0, /* allocation_size */
1726 NULL, /* sd */
1727 NULL, /* ea_list */
1728 &streams[i], /* result */
1729 NULL, /* pinfo */
1730 NULL, /* fsp_data */
1731 NULL); /* psbuf */
1733 TALLOC_FREE(streamname);
1735 if (!NT_STATUS_IS_OK(status)) {
1736 DEBUG(10, ("Could not open stream %s: %s\n",
1737 streamname, nt_errstr(status)));
1738 break;
1743 * don't touch the variable "status" beyond this point :-)
1746 for (i -= 1 ; i >= 0; i--) {
1747 if (streams[i] == NULL) {
1748 continue;
1751 DEBUG(10, ("Closing stream # %d, %s\n", i,
1752 streams[i]->fsp_name));
1753 close_file(NULL, streams[i], NORMAL_CLOSE);
1756 fail:
1757 TALLOC_FREE(frame);
1758 return status;
1762 * Wrapper around onefs_open_file_ntcreate and onefs_open_directory.
1764 static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
1765 struct smb_request *req,
1766 const char *fname,
1767 uint32_t access_mask,
1768 uint32_t share_access,
1769 uint32_t create_disposition,
1770 uint32_t create_options,
1771 uint32_t file_attributes,
1772 uint32_t oplock_request,
1773 uint64_t allocation_size,
1774 struct security_descriptor *sd,
1775 struct ea_list *ea_list,
1776 files_struct **result,
1777 int *pinfo,
1778 struct onefs_fsp_data *fsp_data,
1779 SMB_STRUCT_STAT *psbuf)
1781 SMB_STRUCT_STAT sbuf;
1782 int info = FILE_WAS_OPENED;
1783 files_struct *base_fsp = NULL;
1784 files_struct *fsp = NULL;
1785 NTSTATUS status;
1787 DEBUG(10,("onefs_create_file_unixpath: access_mask = 0x%x "
1788 "file_attributes = 0x%x, share_access = 0x%x, "
1789 "create_disposition = 0x%x create_options = 0x%x "
1790 "oplock_request = 0x%x ea_list = 0x%p, sd = 0x%p, "
1791 "fname = %s\n",
1792 (unsigned int)access_mask,
1793 (unsigned int)file_attributes,
1794 (unsigned int)share_access,
1795 (unsigned int)create_disposition,
1796 (unsigned int)create_options,
1797 (unsigned int)oplock_request,
1798 ea_list, sd, fname));
1800 if (create_options & FILE_OPEN_BY_FILE_ID) {
1801 status = NT_STATUS_NOT_SUPPORTED;
1802 goto fail;
1805 if (create_options & NTCREATEX_OPTIONS_INVALID_PARAM_MASK) {
1806 status = NT_STATUS_INVALID_PARAMETER;
1807 goto fail;
1810 if (req == NULL) {
1811 SMB_ASSERT((oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK) ==
1812 NO_OPLOCK);
1813 oplock_request |= INTERNAL_OPEN_ONLY;
1816 if (psbuf != NULL) {
1817 sbuf = *psbuf;
1819 else {
1820 if (SMB_VFS_STAT(conn, fname, &sbuf) == -1) {
1821 SET_STAT_INVALID(sbuf);
1825 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
1826 && (access_mask & DELETE_ACCESS)
1827 && !is_ntfs_stream_name(fname)) {
1829 * We can't open a file with DELETE access if any of the
1830 * streams is open without FILE_SHARE_DELETE
1832 status = open_streams_for_delete(conn, fname);
1834 if (!NT_STATUS_IS_OK(status)) {
1835 goto fail;
1839 if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
1840 && is_ntfs_stream_name(fname)) {
1841 char *base;
1842 uint32 base_create_disposition;
1844 if (create_options & FILE_DIRECTORY_FILE) {
1845 status = NT_STATUS_NOT_A_DIRECTORY;
1846 goto fail;
1849 status = onefs_split_ntfs_stream_name(talloc_tos(), fname,
1850 &base, NULL);
1851 if (!NT_STATUS_IS_OK(status)) {
1852 DEBUG(10, ("onefs_create_file_unixpath: "
1853 "split_ntfs_stream_name failed: %s\n",
1854 nt_errstr(status)));
1855 goto fail;
1858 SMB_ASSERT(!is_ntfs_stream_name(base)); /* paranoia.. */
1860 switch (create_disposition) {
1861 case FILE_OPEN:
1862 base_create_disposition = FILE_OPEN;
1863 break;
1864 default:
1865 base_create_disposition = FILE_OPEN_IF;
1866 break;
1869 status = onefs_create_file_unixpath(
1870 conn, /* conn */
1871 NULL, /* req */
1872 base, /* fname */
1873 SYNCHRONIZE_ACCESS, /* access_mask */
1874 (FILE_SHARE_READ |
1875 FILE_SHARE_WRITE |
1876 FILE_SHARE_DELETE), /* share_access */
1877 base_create_disposition, /* create_disposition*/
1878 0, /* create_options */
1879 file_attributes, /* file_attributes */
1880 NO_OPLOCK, /* oplock_request */
1881 0, /* allocation_size */
1882 NULL, /* sd */
1883 NULL, /* ea_list */
1884 &base_fsp, /* result */
1885 NULL, /* pinfo */
1886 NULL, /* fsp_data */
1887 NULL); /* psbuf */
1889 if (!NT_STATUS_IS_OK(status)) {
1890 DEBUG(10, ("onefs_create_file_unixpath for base %s "
1891 "failed: %s\n", base, nt_errstr(status)));
1892 goto fail;
1896 /* Covert generic bits in the security descriptor. */
1897 if (sd != NULL) {
1898 security_acl_map_generic(sd->dacl, &file_generic_mapping);
1899 security_acl_map_generic(sd->sacl, &file_generic_mapping);
1903 * If it's a request for a directory open, deal with it separately.
1906 if (create_options & FILE_DIRECTORY_FILE) {
1908 if (create_options & FILE_NON_DIRECTORY_FILE) {
1909 status = NT_STATUS_INVALID_PARAMETER;
1910 goto fail;
1913 /* Can't open a temp directory. IFS kit test. */
1914 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
1915 (file_attributes & FILE_ATTRIBUTE_TEMPORARY)) {
1916 status = NT_STATUS_INVALID_PARAMETER;
1917 goto fail;
1921 * We will get a create directory here if the Win32
1922 * app specified a security descriptor in the
1923 * CreateDirectory() call.
1926 status = onefs_open_directory(
1927 conn, /* conn */
1928 req, /* req */
1929 fname, /* fname */
1930 access_mask, /* access_mask */
1931 share_access, /* share_access */
1932 create_disposition, /* create_disposition*/
1933 create_options, /* create_options */
1934 file_attributes, /* file_attributes */
1935 sd, /* sd */
1936 &fsp, /* result */
1937 &info, /* pinfo */
1938 &sbuf); /* psbuf */
1939 } else {
1942 * Ordinary file case.
1945 status = file_new(req, conn, &fsp);
1946 if(!NT_STATUS_IS_OK(status)) {
1947 goto fail;
1951 * We're opening the stream element of a base_fsp
1952 * we already opened. Set up the base_fsp pointer.
1954 if (base_fsp) {
1955 fsp->base_fsp = base_fsp;
1958 status = onefs_open_file_ntcreate(
1959 conn, /* conn */
1960 req, /* req */
1961 fname, /* fname */
1962 access_mask, /* access_mask */
1963 share_access, /* share_access */
1964 create_disposition, /* create_disposition*/
1965 create_options, /* create_options */
1966 file_attributes, /* file_attributes */
1967 oplock_request, /* oplock_request */
1968 sd, /* sd */
1969 fsp, /* result */
1970 &info, /* pinfo */
1971 fsp_data, /* fsp_data */
1972 &sbuf); /* psbuf */
1974 if(!NT_STATUS_IS_OK(status)) {
1975 file_free(req, fsp);
1976 fsp = NULL;
1979 if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
1981 /* A stream open never opens a directory */
1983 if (base_fsp) {
1984 status = NT_STATUS_FILE_IS_A_DIRECTORY;
1985 goto fail;
1989 * Fail the open if it was explicitly a non-directory
1990 * file.
1993 if (create_options & FILE_NON_DIRECTORY_FILE) {
1994 status = NT_STATUS_FILE_IS_A_DIRECTORY;
1995 goto fail;
1998 create_options |= FILE_DIRECTORY_FILE;
2000 status = onefs_open_directory(
2001 conn, /* conn */
2002 req, /* req */
2003 fname, /* fname */
2004 access_mask, /* access_mask */
2005 share_access, /* share_access */
2006 create_disposition, /* create_disposition*/
2007 create_options, /* create_options */
2008 file_attributes, /* file_attributes */
2009 sd, /* sd */
2010 &fsp, /* result */
2011 &info, /* pinfo */
2012 &sbuf); /* psbuf */
2016 if (!NT_STATUS_IS_OK(status)) {
2017 goto fail;
2020 fsp->base_fsp = base_fsp;
2022 SMB_ASSERT(fsp);
2024 if ((ea_list != NULL) && (info == FILE_WAS_CREATED)) {
2025 status = set_ea(conn, fsp, fname, ea_list);
2026 if (!NT_STATUS_IS_OK(status)) {
2027 goto fail;
2031 if (!fsp->is_directory && S_ISDIR(sbuf.st_mode)) {
2032 status = NT_STATUS_ACCESS_DENIED;
2033 goto fail;
2036 /* Save the requested allocation size. */
2037 if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
2038 if (allocation_size
2039 && (allocation_size > sbuf.st_size)) {
2040 fsp->initial_allocation_size = smb_roundup(
2041 fsp->conn, allocation_size);
2042 if (fsp->is_directory) {
2043 /* Can't set allocation size on a directory. */
2044 status = NT_STATUS_ACCESS_DENIED;
2045 goto fail;
2047 if (vfs_allocate_file_space(
2048 fsp, fsp->initial_allocation_size) == -1) {
2049 status = NT_STATUS_DISK_FULL;
2050 goto fail;
2052 } else {
2053 fsp->initial_allocation_size = smb_roundup(
2054 fsp->conn, (uint64_t)sbuf.st_size);
2058 DEBUG(10, ("onefs_create_file_unixpath: info=%d\n", info));
2060 *result = fsp;
2061 if (pinfo != NULL) {
2062 *pinfo = info;
2064 if (psbuf != NULL) {
2065 if ((fsp->fh == NULL) || (fsp->fh->fd == -1)) {
2066 *psbuf = sbuf;
2068 else {
2069 SMB_VFS_FSTAT(fsp, psbuf);
2072 return NT_STATUS_OK;
2074 fail:
2075 DEBUG(10, ("onefs_create_file_unixpath: %s\n", nt_errstr(status)));
2077 if (fsp != NULL) {
2078 if (base_fsp && fsp->base_fsp == base_fsp) {
2080 * The close_file below will close
2081 * fsp->base_fsp.
2083 base_fsp = NULL;
2085 close_file(req, fsp, ERROR_CLOSE);
2086 fsp = NULL;
2088 if (base_fsp != NULL) {
2089 close_file(req, base_fsp, ERROR_CLOSE);
2090 base_fsp = NULL;
2092 return status;
2095 static void destroy_onefs_fsp_data(void *p_data)
2097 struct onefs_fsp_data *fsp_data = (struct onefs_fsp_data *)p_data;
2099 destroy_onefs_callback_record(fsp_data->oplock_callback_id);
2103 * SMB_VFS_CREATE_FILE interface to onefs.
2105 NTSTATUS onefs_create_file(vfs_handle_struct *handle,
2106 struct smb_request *req,
2107 uint16_t root_dir_fid,
2108 const char *fname,
2109 uint32_t create_file_flags,
2110 uint32_t access_mask,
2111 uint32_t share_access,
2112 uint32_t create_disposition,
2113 uint32_t create_options,
2114 uint32_t file_attributes,
2115 uint32_t oplock_request,
2116 uint64_t allocation_size,
2117 struct security_descriptor *sd,
2118 struct ea_list *ea_list,
2119 files_struct **result,
2120 int *pinfo,
2121 SMB_STRUCT_STAT *psbuf)
2123 connection_struct *conn = handle->conn;
2124 struct case_semantics_state *case_state = NULL;
2125 struct onefs_fsp_data fsp_data = {};
2126 SMB_STRUCT_STAT sbuf;
2127 int info = FILE_WAS_OPENED;
2128 files_struct *fsp = NULL;
2129 NTSTATUS status;
2131 DEBUG(10,("onefs_create_file: access_mask = 0x%x "
2132 "file_attributes = 0x%x, share_access = 0x%x, "
2133 "create_disposition = 0x%x create_options = 0x%x "
2134 "oplock_request = 0x%x "
2135 "root_dir_fid = 0x%x, ea_list = 0x%p, sd = 0x%p, "
2136 "create_file_flags = 0x%x, fname = %s\n",
2137 (unsigned int)access_mask,
2138 (unsigned int)file_attributes,
2139 (unsigned int)share_access,
2140 (unsigned int)create_disposition,
2141 (unsigned int)create_options,
2142 (unsigned int)oplock_request,
2143 (unsigned int)root_dir_fid,
2144 ea_list, sd, create_file_flags, fname));
2146 /* Get the file name if root_dir_fid was specified. */
2147 if (root_dir_fid != 0) {
2148 char *new_fname;
2150 status = get_relative_fid_filename(conn, req, root_dir_fid,
2151 fname, &new_fname);
2152 if (!NT_STATUS_IS_OK(status)) {
2153 goto fail;
2156 fname = new_fname;
2159 /* Resolve the file name if this was a DFS pathname. */
2160 if ((req != NULL) && (req->flags2 & FLAGS2_DFS_PATHNAMES)) {
2161 char *resolved_fname;
2163 status = resolve_dfspath(talloc_tos(), conn, true, fname,
2164 &resolved_fname);
2166 if (!NT_STATUS_IS_OK(status)) {
2168 * For PATH_NOT_COVERED we had
2169 * reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
2170 * ERRSRV, ERRbadpath);
2171 * Need to fix in callers
2173 goto fail;
2175 fname = resolved_fname;
2178 /* Check if POSIX semantics are wanted. */
2179 if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
2180 case_state = set_posix_case_semantics(talloc_tos(), conn);
2183 /* Convert dos path to unix path if it hasn't already been done. */
2184 if (create_file_flags & CFF_DOS_PATH) {
2185 char *converted_fname;
2187 SET_STAT_INVALID(sbuf);
2189 status = unix_convert(talloc_tos(), conn, fname, False,
2190 &converted_fname, NULL, &sbuf);
2191 if (!NT_STATUS_IS_OK(status)) {
2192 goto fail;
2194 fname = converted_fname;
2195 } else {
2196 if (psbuf != NULL) {
2197 sbuf = *psbuf;
2198 } else {
2199 if (SMB_VFS_STAT(conn, fname, &sbuf) == -1) {
2200 SET_STAT_INVALID(sbuf);
2206 TALLOC_FREE(case_state);
2208 /* All file access must go through check_name() */
2209 status = check_name(conn, fname);
2210 if (!NT_STATUS_IS_OK(status)) {
2211 goto fail;
2214 status = onefs_create_file_unixpath(
2215 conn, /* conn */
2216 req, /* req */
2217 fname, /* fname */
2218 access_mask, /* access_mask */
2219 share_access, /* share_access */
2220 create_disposition, /* create_disposition*/
2221 create_options, /* create_options */
2222 file_attributes, /* file_attributes */
2223 oplock_request, /* oplock_request */
2224 allocation_size, /* allocation_size */
2225 sd, /* sd */
2226 ea_list, /* ea_list */
2227 &fsp, /* result */
2228 &info, /* pinfo */
2229 &fsp_data, /* fsp_data */
2230 &sbuf); /* psbuf */
2232 if (!NT_STATUS_IS_OK(status)) {
2233 goto fail;
2236 DEBUG(10, ("onefs_create_file: info=%d\n", info));
2239 * Setup private onefs_fsp_data. Currently the private data struct is
2240 * only used to store the oplock_callback_id so that when the file is
2241 * closed, the onefs_callback_record can be properly cleaned up in the
2242 * oplock_onefs sub-system.
2244 if (fsp) {
2245 struct onefs_fsp_data *fsp_data_tmp = NULL;
2246 fsp_data_tmp = (struct onefs_fsp_data *)
2247 VFS_ADD_FSP_EXTENSION(handle, fsp, struct onefs_fsp_data,
2248 &destroy_onefs_fsp_data);
2250 if (fsp_data_tmp == NULL) {
2251 status = NT_STATUS_NO_MEMORY;
2252 goto fail;
2255 *fsp_data_tmp = fsp_data;
2258 *result = fsp;
2259 if (pinfo != NULL) {
2260 *pinfo = info;
2262 if (psbuf != NULL) {
2263 *psbuf = sbuf;
2265 return NT_STATUS_OK;
2267 fail:
2268 DEBUG(10, ("onefs_create_file: %s\n", nt_errstr(status)));
2270 if (fsp != NULL) {
2271 close_file(req, fsp, ERROR_CLOSE);
2272 fsp = NULL;
2274 return status;