s3:registry: create regdb_store_keys_internal() with db_context argument
[kai/samba.git] / source3 / modules / onefs_open.c
1 /*
2  * Unix SMB/CIFS implementation.
3  *
4  * This file began with some code from source3/smbd/open.c and has been
5  * modified it work with ifs_createfile.
6  *
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
15  *
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
20  *
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.
25  *
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.
30  *
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/>.
33  */
34
35 #include "includes.h"
36 #include "onefs.h"
37 #include "onefs_config.h"
38 #include "oplock_onefs.h"
39 #include "smbd/globals.h"
40
41 extern const struct generic_mapping file_generic_mapping;
42
43 struct onefs_fsp_data {
44         uint64_t oplock_callback_id;
45 };
46
47 static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
48                               struct smb_request *req,
49                               struct smb_filename *smb_fname,
50                               uint32_t access_mask,
51                               uint32_t share_access,
52                               uint32_t create_disposition,
53                               uint32_t create_options,
54                               uint32_t file_attributes,
55                               uint32_t oplock_request,
56                               uint64_t allocation_size,
57                               struct security_descriptor *sd,
58                               struct ea_list *ea_list,
59                               files_struct **result,
60                               int *pinfo,
61                               struct onefs_fsp_data *fsp_data);
62
63 /****************************************************************************
64  Open a file.
65 ****************************************************************************/
66
67 static NTSTATUS onefs_open_file(files_struct *fsp,
68                                 connection_struct *conn,
69                                 struct smb_request *req,
70                                 const char *parent_dir,
71                                 struct smb_filename *smb_fname,
72                                 int flags,
73                                 mode_t unx_mode,
74                                 uint32 access_mask,
75                                 uint32 open_access_mask,
76                                 int oplock_request,
77                                 uint64 id,
78                                 uint32 share_access,
79                                 uint32 create_options,
80                                 uint32_t new_dos_attributes,
81                                 struct security_descriptor *sd,
82                                 int *granted_oplock)
83 {
84         char *path = NULL;
85         struct smb_filename *smb_fname_onefs = NULL;
86         NTSTATUS status = NT_STATUS_OK;
87         int accmode = (flags & O_ACCMODE);
88         int local_flags = flags;
89         bool file_existed = VALID_STAT(smb_fname->st);
90         const char *wild;
91         int base_fd = -1;
92
93         fsp->fh->fd = -1;
94         errno = EPERM;
95
96         /* Check permissions */
97
98         /*
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.
106          */
107
108         if (!CAN_WRITE(conn)) {
109                 /* It's a read-only share - fail if we wanted to write. */
110                 if(accmode != O_RDONLY) {
111                         DEBUG(3, ("Permission denied opening %s\n",
112                                   smb_fname_str_dbg(smb_fname)));
113                         return NT_STATUS_ACCESS_DENIED;
114                 } else if(flags & O_CREAT) {
115                         /* We don't want to write - but we must make sure that
116                            O_CREAT doesn't create the file if we have write
117                            access into the directory.
118                         */
119                         flags &= ~O_CREAT;
120                         local_flags &= ~O_CREAT;
121                 }
122         }
123
124         /*
125          * This little piece of insanity is inspired by the
126          * fact that an NT client can open a file for O_RDONLY,
127          * but set the create disposition to FILE_EXISTS_TRUNCATE.
128          * If the client *can* write to the file, then it expects to
129          * truncate the file, even though it is opening for readonly.
130          * Quicken uses this stupid trick in backup file creation...
131          * Thanks *greatly* to "David W. Chapman Jr." <dwcjr@inethouston.net>
132          * for helping track this one down. It didn't bite us in 2.0.x
133          * as we always opened files read-write in that release. JRA.
134          */
135
136         if ((accmode == O_RDONLY) && ((flags & O_TRUNC) == O_TRUNC)) {
137                 DEBUG(10,("onefs_open_file: truncate requested on read-only "
138                           "open for file %s\n", smb_fname_str_dbg(smb_fname)));
139                 local_flags = (flags & ~O_ACCMODE)|O_RDWR;
140         }
141
142 #if defined(O_NONBLOCK) && defined(S_ISFIFO)
143         /*
144          * We would block on opening a FIFO with no one else on the
145          * other end. Do what we used to do and add O_NONBLOCK to the
146          * open flags. JRA.
147          */
148
149         if (file_existed && S_ISFIFO(smb_fname->st.st_ex_mode)) {
150                 local_flags |= O_NONBLOCK;
151         }
152 #endif
153
154         /* Don't create files with Microsoft wildcard characters. */
155         if (fsp->base_fsp) {
156                 /*
157                  * wildcard characters are allowed in stream names
158                  * only test the basefilename
159                  */
160                 wild = fsp->base_fsp->fsp_name;
161         } else {
162                 wild = smb_fname->base_name;
163         }
164         if ((local_flags & O_CREAT) && !file_existed &&
165             ms_has_wild(wild))  {
166                 /*
167                  * XXX: may need to remvoe this return...
168                  *
169                  * We dont think this check needs to exist. All it does is
170                  * block creating files with Microsoft wildcards, which is
171                  * fine if the creation originated from NFS or locally and
172                  * then was copied via Samba.
173                  */
174                 DEBUG(1, ("onefs_open_file: creating file with wildcard: %s\n",
175                           smb_fname_str_dbg(smb_fname)));
176                 return NT_STATUS_OBJECT_NAME_INVALID;
177         }
178
179         /* Actually do the open */
180
181 #ifdef O_NOFOLLOW
182         /*
183          * Never follow symlinks on a POSIX client. The
184          * client should be doing this.
185          */
186
187         if (fsp->posix_open || !lp_symlinks(SNUM(conn))) {
188                 flags |= O_NOFOLLOW;
189         }
190 #endif
191         /* Setup a onefs-style smb_fname struct. */
192         status = onefs_stream_prep_smb_fname(talloc_tos(), smb_fname,
193                                              &smb_fname_onefs);
194         if (!NT_STATUS_IS_OK(status)) {
195                 return status;
196         }
197
198         /* If it's a stream pass in the base_fd */
199         if ((conn->fs_capabilities & FILE_NAMED_STREAMS) &&
200             is_ntfs_stream_smb_fname(smb_fname_onefs)) {
201                 SMB_ASSERT(fsp->base_fsp);
202
203                 DEBUG(10, ("Opening a stream: base=%s(%d), stream=%s\n",
204                            smb_fname_onefs->base_name, fsp->base_fsp->fh->fd,
205                            smb_fname_onefs->stream_name));
206
207                 base_fd = fsp->base_fsp->fh->fd;
208         }
209
210         fsp->fh->fd = onefs_sys_create_file(conn,
211                                             base_fd,
212                                             smb_fname_onefs->stream_name != NULL ?
213                                             smb_fname_onefs->stream_name :
214                                             smb_fname_onefs->base_name,
215                                             access_mask,
216                                             open_access_mask,
217                                             share_access,
218                                             create_options,
219                                             flags,
220                                             unx_mode,
221                                             oplock_request,
222                                             id,
223                                             sd,
224                                             new_dos_attributes,
225                                             granted_oplock);
226         TALLOC_FREE(smb_fname_onefs);
227
228         if (fsp->fh->fd == -1) {
229                 if (errno == EMFILE) {
230                         static time_t last_warned = 0L;
231
232                         if (time((time_t *) NULL) > last_warned) {
233                                 DEBUG(0, ("Too many open files, unable "
234                                           "to open more!  smbd's max "
235                                           "open files = %d, also check "
236                                           "sysctl kern.maxfiles and "
237                                           "sysctl kern.maxfilesperproc\n",
238                                           lp_max_open_files()));
239                                 last_warned = time((time_t *) NULL);
240                         }
241                 }
242
243                 status = map_nt_error_from_unix(errno);
244                 DEBUG(3, ("Error opening file %s (%s) (local_flags=%d) "
245                           "(flags=%d)\n", smb_fname_str_dbg(smb_fname),
246                           strerror(errno), local_flags, flags));
247                 return status;
248         }
249
250         if ((local_flags & O_CREAT) && !file_existed) {
251
252                 /* Inherit the ACL if required */
253                 if (lp_inherit_perms(SNUM(conn))) {
254                         inherit_access_posix_acl(conn, parent_dir,
255                             smb_fname->base_name, unx_mode);
256                 }
257
258                 /* Change the owner if required. */
259                 if (lp_inherit_owner(SNUM(conn))) {
260                         change_file_owner_to_parent(conn, parent_dir,
261                             fsp);
262                 }
263
264                 notify_fname(conn, NOTIFY_ACTION_ADDED,
265                     FILE_NOTIFY_CHANGE_FILE_NAME, smb_fname->base_name);
266         }
267
268         if (!file_existed) {
269                 int ret;
270
271                 if (fsp->fh->fd == -1) {
272                         ret = SMB_VFS_STAT(conn, smb_fname);
273                 } else {
274                         ret = SMB_VFS_FSTAT(fsp, &smb_fname->st);
275                         /* If we have an fd, this stat should succeed. */
276                         if (ret == -1) {
277                                 DEBUG(0, ("Error doing fstat on open file %s "
278                                           "(%s)\n",
279                                           smb_fname_str_dbg(smb_fname),
280                                           strerror(errno) ));
281                         }
282                 }
283
284                 /* For a non-io open, this stat failing means file not found. JRA */
285                 if (ret == -1) {
286                         status = map_nt_error_from_unix(errno);
287                         fd_close(fsp);
288                         return status;
289                 }
290         }
291
292         /*
293          * POSIX allows read-only opens of directories. We don't
294          * want to do this (we use a different code path for this)
295          * so catch a directory open and return an EISDIR. JRA.
296          */
297
298         if(S_ISDIR(smb_fname->st.st_ex_mode)) {
299                 fd_close(fsp);
300                 errno = EISDIR;
301                 return NT_STATUS_FILE_IS_A_DIRECTORY;
302         }
303
304         fsp->mode = smb_fname->st.st_ex_mode;
305         fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
306         fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
307         fsp->file_pid = req ? req->smbpid : 0;
308         fsp->can_lock = True;
309         fsp->can_read = (access_mask & (FILE_READ_DATA)) ? True : False;
310         if (!CAN_WRITE(conn)) {
311                 fsp->can_write = False;
312         } else {
313                 fsp->can_write = (access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ?
314                         True : False;
315         }
316         fsp->print_file = False;
317         fsp->modified = False;
318         fsp->sent_oplock_break = NO_BREAK_SENT;
319         fsp->is_directory = False;
320         if (conn->aio_write_behind_list &&
321             is_in_path(smb_fname->base_name, conn->aio_write_behind_list,
322                        conn->case_sensitive)) {
323                 fsp->aio_write_behind = True;
324         }
325
326         status = get_full_smb_filename(talloc_tos(), smb_fname,
327                                        &path);
328         if (!NT_STATUS_IS_OK(status)) {
329                 return status;
330         }
331
332         string_set(&fsp->fsp_name, path);
333         TALLOC_FREE(path);
334
335         fsp->wcp = NULL; /* Write cache pointer. */
336
337         DEBUG(2,("%s opened file %s read=%s write=%s (numopen=%d)\n",
338                  conn->server_info->unix_name,
339                  smb_fname_str_dbg(smb_fname),
340                  BOOLSTR(fsp->can_read), BOOLSTR(fsp->can_write),
341                  conn->num_files_open));
342
343         errno = 0;
344         return NT_STATUS_OK;
345 }
346
347 /****************************************************************************
348  Handle the 1 second delay in returning a SHARING_VIOLATION error.
349 ****************************************************************************/
350
351 static void defer_open(struct share_mode_lock *lck,
352                        struct timeval request_time,
353                        struct timeval timeout,
354                        struct smb_request *req,
355                        struct deferred_open_record *state)
356 {
357         int i;
358
359         /* Paranoia check */
360
361         for (i=0; i<lck->num_share_modes; i++) {
362                 struct share_mode_entry *e = &lck->share_modes[i];
363
364                 if (!is_deferred_open_entry(e)) {
365                         continue;
366                 }
367
368                 if (procid_is_me(&e->pid) && (e->op_mid == req->mid)) {
369                         DEBUG(0, ("Trying to defer an already deferred "
370                                   "request: mid=%d, exiting\n", req->mid));
371                         exit_server("attempt to defer a deferred request");
372                 }
373         }
374
375         /* End paranoia check */
376
377         DEBUG(10,("defer_open_sharing_error: time [%u.%06u] adding deferred "
378                   "open entry for mid %u\n",
379                   (unsigned int)request_time.tv_sec,
380                   (unsigned int)request_time.tv_usec,
381                   (unsigned int)req->mid));
382
383         if (!push_deferred_smb_message(req, request_time, timeout,
384                                        (char *)state, sizeof(*state))) {
385                 exit_server("push_deferred_smb_message failed");
386         }
387         add_deferred_open(lck, req->mid, request_time, state->id);
388 }
389
390 static void schedule_defer_open(struct share_mode_lock *lck,
391                                 struct timeval request_time,
392                                 struct smb_request *req)
393 {
394         struct deferred_open_record state;
395
396         /* This is a relative time, added to the absolute
397            request_time value to get the absolute timeout time.
398            Note that if this is the second or greater time we enter
399            this codepath for this particular request mid then
400            request_time is left as the absolute time of the *first*
401            time this request mid was processed. This is what allows
402            the request to eventually time out. */
403
404         struct timeval timeout;
405
406         /* Normally the smbd we asked should respond within
407          * OPLOCK_BREAK_TIMEOUT seconds regardless of whether
408          * the client did, give twice the timeout as a safety
409          * measure here in case the other smbd is stuck
410          * somewhere else. */
411
412         /*
413          * On OneFS, the kernel will always send an oplock_revoked message
414          * before this timeout is hit.
415          */
416         timeout = timeval_set(OPLOCK_BREAK_TIMEOUT*10, 0);
417
418         /* Nothing actually uses state.delayed_for_oplocks
419            but it's handy to differentiate in debug messages
420            between a 30 second delay due to oplock break, and
421            a 1 second delay for share mode conflicts. */
422
423         state.delayed_for_oplocks = True;
424         state.failed = false;
425         state.id = lck->id;
426
427         if (!request_timed_out(request_time, timeout)) {
428                 defer_open(lck, request_time, timeout, req, &state);
429         }
430 }
431
432 /****************************************************************************
433  Open a file with a share mode.  Passed in an already created files_struct.
434 ****************************************************************************/
435 NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
436                                   struct smb_request *req,
437                                   struct smb_filename *smb_fname,
438                                   uint32 access_mask,
439                                   uint32 share_access,
440                                   uint32 create_disposition,
441                                   uint32 create_options,
442                                   uint32 new_dos_attributes,
443                                   int oplock_request,
444                                   struct security_descriptor *sd,
445                                   files_struct *fsp,
446                                   int *pinfo,
447                                   struct onefs_fsp_data *fsp_data)
448 {
449         int flags=0;
450         int flags2=0;
451         bool file_existed = VALID_STAT(smb_fname->st);
452         bool def_acl = False;
453         bool posix_open = False;
454         bool new_file_created = False;
455         bool clear_ads = False;
456         struct file_id id;
457         mode_t new_unx_mode = (mode_t)0;
458         mode_t unx_mode = (mode_t)0;
459         int info;
460         uint32 existing_dos_attributes = 0;
461         struct pending_message_list *pml = NULL;
462         struct timeval request_time = timeval_zero();
463         struct share_mode_lock *lck = NULL;
464         uint32 open_access_mask = access_mask;
465         NTSTATUS status;
466         int ret_flock;
467         char *parent_dir;
468         int granted_oplock;
469         uint64_t oplock_callback_id = 0;
470         uint32 createfile_attributes = 0;
471
472         ZERO_STRUCT(id);
473
474         if (conn->printer) {
475                 /*
476                  * Printers are handled completely differently.
477                  * Most of the passed parameters are ignored.
478                  */
479
480                 if (pinfo) {
481                         *pinfo = FILE_WAS_CREATED;
482                 }
483
484                 DEBUG(10, ("onefs_open_file_ntcreate: printer open fname=%s\n",
485                            smb_fname_str_dbg(smb_fname)));
486
487                 return print_fsp_open(req, conn, smb_fname->base_name,
488                                       req->vuid, fsp, &smb_fname->st);
489         }
490
491         if (!parent_dirname(talloc_tos(), smb_fname->base_name, &parent_dir,
492                             NULL)) {
493                 return NT_STATUS_NO_MEMORY;
494         }
495
496         if (new_dos_attributes & FILE_FLAG_POSIX_SEMANTICS) {
497                 posix_open = True;
498                 unx_mode = (mode_t)(new_dos_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
499                 new_dos_attributes = 0;
500         } else {
501                 /* We add aARCH to this as this mode is only used if the file is
502                  * created new. */
503                 unx_mode = unix_mode(conn, new_dos_attributes | aARCH,
504                                      smb_fname, parent_dir);
505         }
506
507         DEBUG(10,("onefs_open_file_ntcreate: fname=%s, dos_attrs=0x%x "
508                   "access_mask=0x%x share_access=0x%x "
509                   "create_disposition = 0x%x create_options=0x%x "
510                   "unix mode=0%o oplock_request=0x%x\n",
511                   smb_fname_str_dbg(smb_fname), new_dos_attributes,
512                   access_mask, share_access, create_disposition,
513                   create_options, unx_mode, oplock_request));
514
515         /*
516          * Any non-stat-only open has the potential to contend oplocks, which
517          * means to avoid blocking in the kernel (which is unacceptable), the
518          * open must be deferred.  In order to defer opens, req must not be
519          * NULL.  The known cases of calling with a NULL req:
520          *
521          *   1. Open the base file of a stream: Always done stat-only
522          *
523          *   2. open_file_fchmod(), which is called from 3 places:
524          *      A. try_chown: Posix acls only. Never called on onefs.
525          *      B. set_ea_dos_attributes: Can't be called from onefs, because
526          *         SMB_VFS_SETXATTR return ENOSYS.
527          *      C. file_set_dos_mode: This would only happen if the "dos
528          *         filemode" smb.conf parameter is set to yes.  We ship with
529          *         it off, but if a customer were to turn it on it would be
530          *         bad.
531          */
532         if (req == NULL && !is_stat_open(access_mask) &&
533             !is_ntfs_stream_smb_fname(smb_fname)) {
534                 smb_panic("NULL req on a non-stat-open!");
535         }
536
537         if ((req == NULL) && ((oplock_request & INTERNAL_OPEN_ONLY) == 0)) {
538                 DEBUG(0, ("No smb request but not an internal only open!\n"));
539                 return NT_STATUS_INTERNAL_ERROR;
540         }
541
542         /*
543          * Only non-internal opens can be deferred at all
544          */
545
546         if ((req != NULL)
547             && ((pml = get_open_deferred_message(req->mid)) != NULL)) {
548                 struct deferred_open_record *state =
549                         (struct deferred_open_record *)pml->private_data.data;
550
551                 /* Remember the absolute time of the original
552                    request with this mid. We'll use it later to
553                    see if this has timed out. */
554
555                 request_time = pml->request_time;
556
557                 /* Remove the deferred open entry under lock. */
558                 lck = get_share_mode_lock(talloc_tos(), state->id, NULL, NULL,
559                                           NULL);
560                 if (lck == NULL) {
561                         DEBUG(0, ("could not get share mode lock\n"));
562                 } else {
563                         del_deferred_open_entry(lck, req->mid);
564                         TALLOC_FREE(lck);
565                 }
566
567                 /* Ensure we don't reprocess this message. */
568                 remove_deferred_open_smb_message(req->mid);
569
570                 /*
571                  * When receiving a semlock_async_failure message, the
572                  * deferred open will be marked as "failed". Returning
573                  * INTERNAL_ERROR.
574                  */
575                 if (state->failed) {
576                         DEBUG(0, ("onefs_open_file_ntcreate: "
577                                   "semlock_async_failure detected!\n"));
578                         return NT_STATUS_INTERNAL_ERROR;
579                 }
580         }
581
582         status = check_name(conn, smb_fname->base_name);
583         if (!NT_STATUS_IS_OK(status)) {
584                 return status;
585         }
586
587         if (!posix_open) {
588                 new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
589                 if (file_existed) {
590                         existing_dos_attributes = dos_mode(conn, smb_fname);
591                 }
592         }
593
594         /* Setup dos_attributes to be set by ifs_createfile */
595         if (lp_store_dos_attributes(SNUM(conn))) {
596                 createfile_attributes = (new_dos_attributes | aARCH) &
597                     ~(FILE_ATTRIBUTE_NONINDEXED | FILE_ATTRIBUTE_COMPRESSED);
598         }
599
600         /* Ignore oplock requests if oplocks are disabled. */
601         if (!lp_oplocks(SNUM(conn)) || global_client_failed_oplock_break ||
602             IS_VETO_OPLOCK_PATH(conn, smb_fname->base_name)) {
603                 /* Mask off everything except the private Samba bits. */
604                 oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
605         }
606
607         /* this is for OS/2 long file names - say we don't support them */
608         if (!lp_posix_pathnames() && strstr(smb_fname->base_name,".+,;=[].")) {
609                 /* OS/2 Workplace shell fix may be main code stream in a later
610                  * release. */
611                 DEBUG(5,("onefs_open_file_ntcreate: OS/2 long filenames are "
612                           "not supported.\n"));
613                 if (use_nt_status()) {
614                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
615                 }
616                 return NT_STATUS_DOS(ERRDOS, ERRcannotopen);
617         }
618
619         switch( create_disposition ) {
620                 /*
621                  * Currently we're using FILE_SUPERSEDE as the same as
622                  * FILE_OVERWRITE_IF but they really are
623                  * different. FILE_SUPERSEDE deletes an existing file
624                  * (requiring delete access) then recreates it.
625                  */
626                 case FILE_SUPERSEDE:
627                         /**
628                          * @todo: Clear all file attributes?
629                          * http://www.osronline.com/article.cfm?article=302
630                          * create if not exist, trunc if exist
631                          *
632                          * If file exists replace/overwrite. If file doesn't
633                          * exist create.
634                          */
635                         flags2 |= (O_CREAT | O_TRUNC);
636                         clear_ads = true;
637                         break;
638
639                 case FILE_OVERWRITE_IF:
640                         /* If file exists replace/overwrite. If file doesn't
641                          * exist create. */
642                         flags2 |= (O_CREAT | O_TRUNC);
643                         clear_ads = true;
644                         break;
645
646                 case FILE_OPEN:
647                         /* If file exists open. If file doesn't exist error. */
648                         if (!file_existed) {
649                                 DEBUG(5,("onefs_open_file_ntcreate: FILE_OPEN "
650                                          "requested for file %s and file "
651                                          "doesn't exist.\n",
652                                          smb_fname_str_dbg(smb_fname)));
653                                 errno = ENOENT;
654                                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
655                         }
656                         break;
657
658                 case FILE_OVERWRITE:
659                         /* If file exists overwrite. If file doesn't exist
660                          * error. */
661                         if (!file_existed) {
662                                 DEBUG(5, ("onefs_open_file_ntcreate: "
663                                           "FILE_OVERWRITE requested for file "
664                                           "%s and file doesn't exist.\n",
665                                           smb_fname_str_dbg(smb_fname)));
666                                 errno = ENOENT;
667                                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
668                         }
669                         flags2 |= O_TRUNC;
670                         clear_ads = true;
671                         break;
672
673                 case FILE_CREATE:
674                         /* If file exists error. If file doesn't exist
675                          * create. */
676                         if (file_existed) {
677                                 DEBUG(5, ("onefs_open_file_ntcreate: "
678                                           "FILE_CREATE requested for file %s "
679                                           "and file already exists.\n",
680                                           smb_fname_str_dbg(smb_fname)));
681                                 if (S_ISDIR(smb_fname->st.st_ex_mode)) {
682                                         errno = EISDIR;
683                                 } else {
684                                         errno = EEXIST;
685                                 }
686                                 return map_nt_error_from_unix(errno);
687                         }
688                         flags2 |= (O_CREAT|O_EXCL);
689                         break;
690
691                 case FILE_OPEN_IF:
692                         /* If file exists open. If file doesn't exist
693                          * create. */
694                         flags2 |= O_CREAT;
695                         break;
696
697                 default:
698                         return NT_STATUS_INVALID_PARAMETER;
699         }
700
701         /* Match attributes on file exists and overwrite. */
702         if (!posix_open && file_existed &&
703             ((create_disposition == FILE_OVERWRITE) ||
704                 (create_disposition == FILE_OVERWRITE_IF))) {
705                 if (!open_match_attributes(conn, existing_dos_attributes,
706                                            new_dos_attributes,
707                                            smb_fname->st.st_ex_mode,
708                                            unx_mode, &new_unx_mode)) {
709                         DEBUG(5, ("onefs_open_file_ntcreate: attributes "
710                                   "missmatch for file %s (%x %x) (0%o, 0%o)\n",
711                                   smb_fname_str_dbg(smb_fname),
712                                   existing_dos_attributes,
713                                   new_dos_attributes,
714                                   (unsigned int)smb_fname->st.st_ex_mode,
715                                   (unsigned int)unx_mode ));
716                         errno = EACCES;
717                         return NT_STATUS_ACCESS_DENIED;
718                 }
719         }
720
721         /*
722          * OneFS understands MAXIMUM_ALLOWED_ACCESS, so only hack the
723          * access_mask, but leave the MAA for the actual open in
724          * open_access_mask.
725          */
726         open_access_mask = access_mask;
727         if (open_access_mask & MAXIMUM_ALLOWED_ACCESS) {
728                 access_mask |= FILE_GENERIC_ALL;
729         }
730
731         /* Convert GENERIC bits to specific bits. */
732         se_map_generic(&access_mask, &file_generic_mapping);
733         se_map_generic(&open_access_mask, &file_generic_mapping);
734
735         if ((flags2 & O_TRUNC) || (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE)) {
736                 /* This will cause oplock breaks. */
737                 open_access_mask |= FILE_WRITE_DATA;
738         }
739
740         DEBUG(10, ("onefs_open_file_ntcreate: fname=%s, after mapping "
741                    "open_access_mask=%#x, access_mask=0x%x\n",
742                    smb_fname_str_dbg(smb_fname), open_access_mask,
743                    access_mask));
744
745         /*
746          * Note that we ignore the append flag as append does not
747          * mean the same thing under DOS and Unix.
748          */
749
750         if ((access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ||
751             (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE)) {
752
753                 /*
754                  * DENY_DOS opens are always underlying read-write on the
755                  * file handle, no matter what the requested access mask
756                  * says. Stock samba just sets the flags, but since
757                  * ifs_createfile uses the access_mask, it must be updated as
758                  * well.  This allows BASE-DENY* to pass.
759                  */
760                 if (create_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) {
761
762                         DEBUG(10,("onefs_open_file_ntcreate: deny_dos: "
763                                   "Adding O_RDWR to flags "
764                                   "(0x%x) and some READ bits to "
765                                   "open_access_mask (0x%x)\n",
766                                   flags, open_access_mask));
767
768                         flags = O_RDWR;
769                         open_access_mask |= (FILE_READ_ATTRIBUTES |
770                             FILE_READ_DATA | FILE_READ_EA | FILE_EXECUTE);
771
772                 } else if (access_mask & (FILE_READ_ATTRIBUTES |
773                                FILE_READ_DATA |
774                                FILE_READ_EA |
775                                FILE_EXECUTE)) {
776                         flags = O_RDWR;
777                 } else {
778                         flags = O_WRONLY;
779                 }
780         } else {
781                 flags = O_RDONLY;
782         }
783
784         /* Currently we only look at FILE_WRITE_THROUGH for create options. */
785 #if defined(O_SYNC)
786         if ((create_options & FILE_WRITE_THROUGH) &&
787             lp_strict_sync(SNUM(conn))) {
788                 flags2 |= O_SYNC;
789         }
790 #endif /* O_SYNC */
791
792         if (posix_open && (access_mask & FILE_APPEND_DATA)) {
793                 flags2 |= O_APPEND;
794         }
795
796         if (!posix_open && !CAN_WRITE(conn)) {
797                 /*
798                  * We should really return a permission denied error if either
799                  * O_CREAT or O_TRUNC are set, but for compatibility with
800                  * older versions of Samba we just AND them out.
801                  */
802                 flags2 &= ~(O_CREAT|O_TRUNC);
803
804                 /* Deny DELETE_ACCESS explicitly if the share is read only. */
805                 if (access_mask & DELETE_ACCESS) {
806                         return map_nt_error_from_unix(EACCES);
807                 }
808         }
809
810         /* Ensure we can't write on a read-only share or file. */
811         if (flags != O_RDONLY && file_existed &&
812             (!CAN_WRITE(conn) || IS_DOS_READONLY(existing_dos_attributes))) {
813                 DEBUG(5, ("onefs_open_file_ntcreate: write access requested "
814                           "for file %s on read only %s\n",
815                           smb_fname_str_dbg(smb_fname),
816                           !CAN_WRITE(conn) ? "share" : "file" ));
817                 errno = EACCES;
818                 return NT_STATUS_ACCESS_DENIED;
819         }
820
821         DEBUG(10, ("fsp = %p\n", fsp));
822
823         fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
824         fsp->share_access = share_access;
825         fsp->fh->private_options = create_options;
826         fsp->access_mask = open_access_mask; /* We change this to the
827                                               * requested access_mask after
828                                               * the open is done. */
829         fsp->posix_open = posix_open;
830
831         /* Ensure no SAMBA_PRIVATE bits can be set. */
832         fsp->oplock_type = (oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK);
833
834         if (timeval_is_zero(&request_time)) {
835                 request_time = fsp->open_time;
836         }
837
838         if (file_existed) {
839                 struct timespec old_write_time = smb_fname->st.st_ex_mtime;
840                 id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
841
842                 lck = get_share_mode_lock(talloc_tos(), id,
843                                           conn->connectpath,
844                                           smb_fname, &old_write_time);
845
846                 if (lck == NULL) {
847                         DEBUG(0, ("Could not get share mode lock\n"));
848                         return NT_STATUS_SHARING_VIOLATION;
849                 }
850
851                 if (lck->delete_on_close) {
852                         /* DELETE_PENDING is not deferred for a second */
853                         TALLOC_FREE(lck);
854                         return NT_STATUS_DELETE_PENDING;
855                 }
856         }
857
858         SMB_ASSERT(!file_existed || (lck != NULL));
859
860         /*
861          * Ensure we pay attention to default ACLs on directories.  May be
862          * neccessary depending on ACL policies.
863          */
864         if ((flags2 & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
865             (def_acl = directory_has_default_acl(conn, parent_dir))) {
866                 unx_mode = 0777;
867         }
868
869         DEBUG(4,("calling onefs_open_file with flags=0x%X flags2=0x%X "
870                  "mode=0%o, access_mask = 0x%x, open_access_mask = 0x%x\n",
871                  (unsigned int)flags, (unsigned int)flags2,
872                  (unsigned int)unx_mode, (unsigned int)access_mask,
873                  (unsigned int)open_access_mask));
874
875         /*
876          * Since the open is guaranteed to be stat only if req == NULL, a
877          * callback record is only needed if req != NULL.
878          */
879         if (req) {
880                 SMB_ASSERT(fsp_data);
881                 oplock_callback_id = onefs_oplock_wait_record(req->mid);
882                 if (oplock_callback_id == 0) {
883                         return NT_STATUS_NO_MEMORY;
884                 }
885         } else {
886                 /*
887                  * It is also already asserted it's either a stream or a
888                  * stat-only open at this point.
889                  */
890                 SMB_ASSERT(fsp->oplock_type == NO_OPLOCK);
891         }
892
893         /* Do the open. */
894         status = onefs_open_file(fsp,
895                                  conn,
896                                  req,
897                                  parent_dir,
898                                  smb_fname,
899                                  flags|flags2,
900                                  unx_mode,
901                                  access_mask,
902                                  open_access_mask,
903                                  fsp->oplock_type,
904                                  oplock_callback_id,
905                                  share_access,
906                                  create_options,
907                                  createfile_attributes,
908                                  sd,
909                                  &granted_oplock);
910
911         if (!NT_STATUS_IS_OK(status)) {
912
913                 /* OneFS Oplock Handling */
914                 if (errno == EINPROGRESS) {
915
916                         if (lck == NULL) {
917
918                                 struct deferred_open_record state;
919                                 struct timespec old_write_time;
920
921                                 old_write_time = smb_fname->st.st_ex_mtime;
922
923                                 DEBUG(3, ("Someone created file %s with an "
924                                           "oplock after we looked: Retrying\n",
925                                           smb_fname_str_dbg(smb_fname)));
926                                 /*
927                                  * We hit the race that when we did the stat
928                                  * on the file it did not exist, and someone
929                                  * has created it in between the stat and the
930                                  * open_file() call. Just retry immediately.
931                                  */
932                                 id = vfs_file_id_from_sbuf(conn,
933                                                            &smb_fname->st);
934                                 if (!(lck = get_share_mode_lock(talloc_tos(),
935                                           id, conn->connectpath, smb_fname,
936                                           &old_write_time))) {
937                                         /*
938                                          * Emergency exit
939                                          */
940                                         DEBUG(0, ("onefs_open_file_ntcreate: "
941                                                   "Could not get share mode "
942                                                   "lock for %s\n",
943                                                 smb_fname_str_dbg(smb_fname)));
944                                         status = NT_STATUS_SHARING_VIOLATION;
945                                         goto cleanup_destroy;
946                                 }
947
948                                 state.delayed_for_oplocks = False;
949                                 state.id = id;
950
951                                 if (req != NULL) {
952                                         defer_open(lck, request_time,
953                                             timeval_zero(), req, &state);
954                                 }
955                                 goto cleanup_destroy;
956                         }
957                         /* Waiting for an oplock */
958                         DEBUG(5,("Async createfile because a client has an "
959                                  "oplock on %s\n",
960                                  smb_fname_str_dbg(smb_fname)));
961
962                         SMB_ASSERT(req);
963                         schedule_defer_open(lck, request_time, req);
964                         goto cleanup;
965                 }
966
967                 /* Check for a sharing violation */
968                 if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
969                         uint32 can_access_mask;
970                         bool can_access = True;
971
972                         /* Check if this can be done with the deny_dos and fcb
973                          * calls. */
974
975                         /* Try to find dup fsp if possible. */
976                         if (create_options &
977                             (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS|
978                              NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) {
979
980                                 if (req == NULL) {
981                                         DEBUG(0, ("DOS open without an SMB "
982                                                   "request!\n"));
983                                         status = NT_STATUS_INTERNAL_ERROR;
984                                         goto cleanup_destroy;
985                                 }
986
987                                 /* Use the client requested access mask here,
988                                  * not the one we open with. */
989                                 status = fcb_or_dos_open(req,
990                                                         conn,
991                                                         fsp,
992                                                         smb_fname,
993                                                         id,
994                                                         req->smbpid,
995                                                         req->vuid,
996                                                         access_mask,
997                                                         share_access,
998                                                         create_options);
999
1000                                 if (NT_STATUS_IS_OK(status)) {
1001                                         if (pinfo) {
1002                                                 *pinfo = FILE_WAS_OPENED;
1003                                         }
1004                                         status =  NT_STATUS_OK;
1005                                         goto cleanup;
1006                                 }
1007                         }
1008
1009                         /*
1010                          * This next line is a subtlety we need for
1011                          * MS-Access. If a file open will fail due to share
1012                          * permissions and also for security (access) reasons,
1013                          * we need to return the access failed error, not the
1014                          * share error. We can't open the file due to kernel
1015                          * oplock deadlock (it's possible we failed above on
1016                          * the open_mode_check()) so use a userspace check.
1017                          */
1018
1019                         if (flags & O_RDWR) {
1020                                 can_access_mask = FILE_READ_DATA|FILE_WRITE_DATA;
1021                         } else if (flags & O_WRONLY) {
1022                                 can_access_mask = FILE_WRITE_DATA;
1023                         } else {
1024                                 can_access_mask = FILE_READ_DATA;
1025                         }
1026
1027                         if (((can_access_mask & FILE_WRITE_DATA) &&
1028                                 !CAN_WRITE(conn)) ||
1029                             !can_access_file_data(conn, smb_fname,
1030                                                   can_access_mask)) {
1031                                 can_access = False;
1032                         }
1033
1034                         /*
1035                          * If we're returning a share violation, ensure we
1036                          * cope with the braindead 1 second delay.
1037                          */
1038                         if (!(oplock_request & INTERNAL_OPEN_ONLY) &&
1039                             lp_defer_sharing_violations()) {
1040                                 struct timeval timeout;
1041                                 struct deferred_open_record state;
1042                                 int timeout_usecs;
1043
1044                                 /* this is a hack to speed up torture tests
1045                                    in 'make test' */
1046                                 timeout_usecs = lp_parm_int(SNUM(conn),
1047                                     "smbd","sharedelay",
1048                                     SHARING_VIOLATION_USEC_WAIT);
1049
1050                                 /* This is a relative time, added to the
1051                                    absolute request_time value to get the
1052                                    absolute timeout time.  Note that if this
1053                                    is the second or greater time we enter this
1054                                    codepath for this particular request mid
1055                                    then request_time is left as the absolute
1056                                    time of the *first* time this request mid
1057                                    was processed. This is what allows the
1058                                    request to eventually time out. */
1059
1060                                 timeout = timeval_set(0, timeout_usecs);
1061
1062                                 /* Nothing actually uses
1063                                    state.delayed_for_oplocks but it's handy to
1064                                    differentiate in debug messages between a
1065                                    30 second delay due to oplock break, and a
1066                                    1 second delay for share mode conflicts. */
1067
1068                                 state.delayed_for_oplocks = False;
1069                                 state.id = id;
1070                                 state.failed = false;
1071
1072                                 if ((req != NULL)
1073                                     && !request_timed_out(request_time,
1074                                                           timeout)) {
1075                                         defer_open(lck, request_time, timeout,
1076                                                    req, &state);
1077                                 }
1078                         }
1079
1080                         if (can_access) {
1081                                 /*
1082                                  * We have detected a sharing violation here
1083                                  * so return the correct error code
1084                                  */
1085                                 status = NT_STATUS_SHARING_VIOLATION;
1086                         } else {
1087                                 status = NT_STATUS_ACCESS_DENIED;
1088                         }
1089
1090                         goto cleanup_destroy;
1091                 }
1092
1093                 /*
1094                  * Normal error, for example EACCES
1095                  */
1096          cleanup_destroy:
1097                 if (oplock_callback_id != 0) {
1098                         destroy_onefs_callback_record(oplock_callback_id);
1099                 }
1100          cleanup:
1101                 TALLOC_FREE(lck);
1102                 return status;
1103         }
1104
1105         fsp->oplock_type = granted_oplock;
1106
1107         if (oplock_callback_id != 0) {
1108                 onefs_set_oplock_callback(oplock_callback_id, fsp);
1109                 fsp_data->oplock_callback_id = oplock_callback_id;
1110         } else {
1111                 SMB_ASSERT(fsp->oplock_type == NO_OPLOCK);
1112         }
1113
1114         if (!file_existed) {
1115                 struct timespec old_write_time = smb_fname->st.st_ex_mtime;
1116                 /*
1117                  * Deal with the race condition where two smbd's detect the
1118                  * file doesn't exist and do the create at the same time. One
1119                  * of them will win and set a share mode, the other (ie. this
1120                  * one) should check if the requested share mode for this
1121                  * create is allowed.
1122                  */
1123
1124                 /*
1125                  * Now the file exists and fsp is successfully opened,
1126                  * fsp->dev and fsp->inode are valid and should replace the
1127                  * dev=0,inode=0 from a non existent file. Spotted by
1128                  * Nadav Danieli <nadavd@exanet.com>. JRA.
1129                  */
1130
1131                 id = fsp->file_id;
1132
1133                 lck = get_share_mode_lock(talloc_tos(), id,
1134                                           conn->connectpath,
1135                                           smb_fname, &old_write_time);
1136
1137                 if (lck == NULL) {
1138                         DEBUG(0, ("onefs_open_file_ntcreate: Could not get "
1139                                   "share mode lock for %s\n",
1140                                   smb_fname_str_dbg(smb_fname)));
1141                         fd_close(fsp);
1142                         return NT_STATUS_SHARING_VIOLATION;
1143                 }
1144
1145                 if (lck->delete_on_close) {
1146                         status = NT_STATUS_DELETE_PENDING;
1147                 }
1148
1149                 if (!NT_STATUS_IS_OK(status)) {
1150                         struct deferred_open_record state;
1151
1152                         fd_close(fsp);
1153
1154                         state.delayed_for_oplocks = False;
1155                         state.id = id;
1156
1157                         /* Do it all over again immediately. In the second
1158                          * round we will find that the file existed and handle
1159                          * the DELETE_PENDING and FCB cases correctly. No need
1160                          * to duplicate the code here. Essentially this is a
1161                          * "goto top of this function", but don't tell
1162                          * anybody... */
1163
1164                         if (req != NULL) {
1165                                 defer_open(lck, request_time, timeval_zero(),
1166                                            req, &state);
1167                         }
1168                         TALLOC_FREE(lck);
1169                         return status;
1170                 }
1171
1172                 /*
1173                  * We exit this block with the share entry *locked*.....
1174                  */
1175
1176         }
1177
1178         SMB_ASSERT(lck != NULL);
1179
1180         /* Delete streams if create_disposition requires it */
1181         if (file_existed && clear_ads &&
1182             !is_ntfs_stream_smb_fname(smb_fname)) {
1183                 status = delete_all_streams(conn, smb_fname->base_name);
1184                 if (!NT_STATUS_IS_OK(status)) {
1185                         TALLOC_FREE(lck);
1186                         fd_close(fsp);
1187                         return status;
1188                 }
1189         }
1190
1191         /* note that we ignore failure for the following. It is
1192            basically a hack for NFS, and NFS will never set one of
1193            these only read them. Nobody but Samba can ever set a deny
1194            mode and we have already checked our more authoritative
1195            locking database for permission to set this deny mode. If
1196            the kernel refuses the operations then the kernel is wrong.
1197            note that GPFS supports it as well - jmcd */
1198
1199         if (fsp->fh->fd != -1) {
1200                 ret_flock = SMB_VFS_KERNEL_FLOCK(fsp, share_access);
1201                 if(ret_flock == -1 ){
1202
1203                         TALLOC_FREE(lck);
1204                         fd_close(fsp);
1205                         return NT_STATUS_SHARING_VIOLATION;
1206                 }
1207         }
1208
1209         /*
1210          * At this point onwards, we can guarentee that the share entry
1211          * is locked, whether we created the file or not, and that the
1212          * deny mode is compatible with all current opens.
1213          */
1214
1215         /* Record the options we were opened with. */
1216         fsp->share_access = share_access;
1217         fsp->fh->private_options = create_options;
1218         /*
1219          * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
1220          */
1221         fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
1222
1223         if (file_existed) {
1224                 /* stat opens on existing files don't get oplocks. */
1225                 if (is_stat_open(open_access_mask)) {
1226                         fsp->oplock_type = NO_OPLOCK;
1227                 }
1228
1229                 if (!(flags2 & O_TRUNC)) {
1230                         info = FILE_WAS_OPENED;
1231                 } else {
1232                         info = FILE_WAS_OVERWRITTEN;
1233                 }
1234         } else {
1235                 info = FILE_WAS_CREATED;
1236         }
1237
1238         if (pinfo) {
1239                 *pinfo = info;
1240         }
1241
1242         /*
1243          * Setup the oplock info in both the shared memory and
1244          * file structs.
1245          */
1246
1247         if ((fsp->oplock_type != NO_OPLOCK) &&
1248             (fsp->oplock_type != FAKE_LEVEL_II_OPLOCK)) {
1249                 if (!set_file_oplock(fsp, fsp->oplock_type)) {
1250                         /* Could not get the kernel oplock */
1251                         fsp->oplock_type = NO_OPLOCK;
1252                 }
1253         }
1254
1255         if (fsp->oplock_type == LEVEL_II_OPLOCK &&
1256             (!lp_level2_oplocks(SNUM(conn)) ||
1257                 !(global_client_caps & CAP_LEVEL_II_OPLOCKS))) {
1258
1259                 DEBUG(5, ("Downgrading level2 oplock on open "
1260                           "because level2 oplocks = off\n"));
1261
1262                 release_file_oplock(fsp);
1263         }
1264
1265         if (info == FILE_WAS_OVERWRITTEN || info == FILE_WAS_CREATED ||
1266             info == FILE_WAS_SUPERSEDED) {
1267                 new_file_created = True;
1268         }
1269
1270         set_share_mode(lck, fsp, conn->server_info->utok.uid, 0,
1271                        fsp->oplock_type);
1272
1273         /* Handle strange delete on close create semantics. */
1274         if (create_options & FILE_DELETE_ON_CLOSE) {
1275                 status = can_set_delete_on_close(fsp, True, new_dos_attributes);
1276
1277                 if (!NT_STATUS_IS_OK(status)) {
1278                         /* Remember to delete the mode we just added. */
1279                         del_share_mode(lck, fsp);
1280                         TALLOC_FREE(lck);
1281                         fd_close(fsp);
1282                         return status;
1283                 }
1284                 /* Note that here we set the *inital* delete on close flag,
1285                    not the regular one. The magic gets handled in close. */
1286                 fsp->initial_delete_on_close = True;
1287         }
1288
1289         /*
1290          * Take care of inherited ACLs on created files - if default ACL not
1291          * selected.
1292          * May be necessary depending on acl policies.
1293          */
1294         if (!posix_open && !file_existed && !def_acl &&
1295             !(VALID_STAT(smb_fname->st) &&
1296                 (smb_fname->st.st_ex_flags & SF_HASNTFSACL))) {
1297
1298                 int saved_errno = errno; /* We might get ENOSYS in the next
1299                                           * call.. */
1300
1301                 if (SMB_VFS_FCHMOD_ACL(fsp, unx_mode) == -1 &&
1302                     errno == ENOSYS) {
1303                         errno = saved_errno; /* Ignore ENOSYS */
1304                 }
1305
1306         } else if (new_unx_mode) {
1307
1308                 int ret = -1;
1309
1310                 /* Attributes need changing. File already existed. */
1311
1312                 {
1313                         int saved_errno = errno; /* We might get ENOSYS in the
1314                                                   * next call.. */
1315                         ret = SMB_VFS_FCHMOD_ACL(fsp, new_unx_mode);
1316
1317                         if (ret == -1 && errno == ENOSYS) {
1318                                 errno = saved_errno; /* Ignore ENOSYS */
1319                         } else {
1320                                 DEBUG(5, ("onefs_open_file_ntcreate: reset "
1321                                           "attributes of file %s to 0%o\n",
1322                                           smb_fname_str_dbg(smb_fname),
1323                                           (unsigned int)new_unx_mode));
1324                                 ret = 0; /* Don't do the fchmod below. */
1325                         }
1326                 }
1327
1328                 if ((ret == -1) &&
1329                     (SMB_VFS_FCHMOD(fsp, new_unx_mode) == -1))
1330                         DEBUG(5, ("onefs_open_file_ntcreate: failed to reset "
1331                                   "attributes of file %s to 0%o\n",
1332                                   smb_fname_str_dbg(smb_fname),
1333                                   (unsigned int)new_unx_mode));
1334         }
1335
1336         /* If this is a successful open, we must remove any deferred open
1337          * records. */
1338         if (req != NULL) {
1339                 del_deferred_open_entry(lck, req->mid);
1340         }
1341         TALLOC_FREE(lck);
1342
1343         return NT_STATUS_OK;
1344 }
1345
1346
1347 /****************************************************************************
1348  Open a directory from an NT SMB call.
1349 ****************************************************************************/
1350 static NTSTATUS onefs_open_directory(connection_struct *conn,
1351                                      struct smb_request *req,
1352                                      struct smb_filename *smb_dname,
1353                                      uint32 access_mask,
1354                                      uint32 share_access,
1355                                      uint32 create_disposition,
1356                                      uint32 create_options,
1357                                      uint32 file_attributes,
1358                                      struct security_descriptor *sd,
1359                                      files_struct **result,
1360                                      int *pinfo)
1361 {
1362         files_struct *fsp = NULL;
1363         struct share_mode_lock *lck = NULL;
1364         NTSTATUS status;
1365         struct timespec mtimespec;
1366         int info = 0;
1367         char *parent_dir;
1368         bool posix_open = false;
1369         uint32 create_flags = 0;
1370         uint32 mode = lp_dir_mask(SNUM(conn));
1371
1372         DEBUG(5, ("onefs_open_directory: opening directory %s, "
1373                   "access_mask = 0x%x, "
1374                   "share_access = 0x%x create_options = 0x%x, "
1375                   "create_disposition = 0x%x, file_attributes = 0x%x\n",
1376                   smb_fname_str_dbg(smb_dname), (unsigned int)access_mask,
1377                   (unsigned int)share_access, (unsigned int)create_options,
1378                   (unsigned int)create_disposition,
1379                   (unsigned int)file_attributes));
1380
1381         if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
1382             (conn->fs_capabilities & FILE_NAMED_STREAMS) &&
1383             is_ntfs_stream_smb_fname(smb_dname)) {
1384                 DEBUG(2, ("onefs_open_directory: %s is a stream name!\n",
1385                           smb_fname_str_dbg(smb_dname)));
1386                 return NT_STATUS_NOT_A_DIRECTORY;
1387         }
1388
1389         switch (create_disposition) {
1390                 case FILE_OPEN:
1391                         /* If directory exists open. If directory doesn't
1392                          * exist error. */
1393                         create_flags = 0;
1394                         info = FILE_WAS_OPENED;
1395                         break;
1396                 case FILE_CREATE:
1397                         /* If directory exists error. If directory doesn't
1398                          * exist create. */
1399                         create_flags = O_CREAT | O_EXCL;
1400                         info = FILE_WAS_CREATED;
1401                         break;
1402                 case FILE_OPEN_IF:
1403                         /* If directory exists open. If directory doesn't
1404                          * exist create. */
1405
1406                         /* Note: in order to return whether the directory was
1407                          * opened or created, we first try to open and then try
1408                          * to create. */
1409                         create_flags = 0;
1410                         info = FILE_WAS_OPENED;
1411                         break;
1412                 case FILE_SUPERSEDE:
1413                 case FILE_OVERWRITE:
1414                 case FILE_OVERWRITE_IF:
1415                 default:
1416                         DEBUG(5, ("onefs_open_directory: invalid "
1417                                   "create_disposition 0x%x for directory %s\n",
1418                                   (unsigned int)create_disposition,
1419                                   smb_fname_str_dbg(smb_dname)));
1420                         return NT_STATUS_INVALID_PARAMETER;
1421         }
1422
1423         /*
1424          * Check for write access to the share. Done in mkdir_internal() in
1425          * mainline samba.
1426          */
1427         if (!CAN_WRITE(conn) && (create_flags & O_CREAT)) {
1428                 return NT_STATUS_ACCESS_DENIED;
1429         }
1430
1431         /* Get parent dirname */
1432         if (!parent_dirname(talloc_tos(), smb_dname->base_name, &parent_dir,
1433                             NULL)) {
1434                 return NT_STATUS_NO_MEMORY;
1435         }
1436
1437         if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
1438                 posix_open = true;
1439                 mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
1440                 file_attributes = 0;
1441         } else {
1442                 mode = unix_mode(conn, aDIR, smb_dname, parent_dir);
1443         }
1444
1445         /*
1446          * The NONINDEXED and COMPRESSED bits seem to always be cleared on
1447          * directories, no matter if you specify that they should be set.
1448          */
1449         file_attributes &=
1450             ~(FILE_ATTRIBUTE_NONINDEXED | FILE_ATTRIBUTE_COMPRESSED);
1451
1452         status = file_new(req, conn, &fsp);
1453         if(!NT_STATUS_IS_OK(status)) {
1454                 return status;
1455         }
1456
1457         /*
1458          * Actual open with retry magic to handle FILE_OPEN_IF which is
1459          * unique because the kernel won't tell us if the file was opened or
1460          * created.
1461          */
1462  retry_open:
1463         fsp->fh->fd = onefs_sys_create_file(conn,
1464                                             -1,
1465                                             smb_dname->base_name,
1466                                             access_mask,
1467                                             access_mask,
1468                                             share_access,
1469                                             create_options,
1470                                             create_flags | O_DIRECTORY,
1471                                             mode,
1472                                             0,
1473                                             0,
1474                                             sd,
1475                                             file_attributes,
1476                                             NULL);
1477
1478         if (fsp->fh->fd == -1) {
1479                 DEBUG(3, ("Error opening %s. Errno=%d (%s).\n",
1480                           smb_fname_str_dbg(smb_dname), errno,
1481                           strerror(errno)));
1482                 SMB_ASSERT(errno != EINPROGRESS);
1483
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;
1495                         }
1496                 }
1497
1498                 /* Error cases below: */
1499                 file_free(req, fsp);
1500
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", smb_fname_str_dbg(smb_dname)));
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",
1511                                   smb_fname_str_dbg(smb_dname)));
1512                         return NT_STATUS_OBJECT_NAME_COLLISION;
1513                 } else if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
1514                         /* Catch sharing violations. */
1515                         return NT_STATUS_SHARING_VIOLATION;
1516                 }
1517
1518                 return map_nt_error_from_unix(errno);
1519         }
1520
1521         if (info == FILE_WAS_CREATED) {
1522
1523                 /* Pulled from mkdir_internal() */
1524                 if (SMB_VFS_LSTAT(conn, smb_dname) == -1) {
1525                         DEBUG(2, ("Could not stat directory '%s' just "
1526                                   "created: %s\n",
1527                                   smb_fname_str_dbg(smb_dname),
1528                                   strerror(errno)));
1529                         return map_nt_error_from_unix(errno);
1530                 }
1531
1532                 if (!S_ISDIR(smb_dname->st.st_ex_mode)) {
1533                         DEBUG(0, ("Directory just '%s' created is not a "
1534                                   "directory\n",
1535                                   smb_fname_str_dbg(smb_dname)));
1536                         return NT_STATUS_ACCESS_DENIED;
1537                 }
1538
1539                 if (!posix_open) {
1540                         /*
1541                          * Check if high bits should have been set, then (if
1542                          * bits are missing): add them.  Consider bits
1543                          * automagically set by UNIX, i.e. SGID bit from
1544                          * parent dir.
1545                          */
1546                         if (mode & ~(S_IRWXU|S_IRWXG|S_IRWXO) &&
1547                             (mode & ~smb_dname->st.st_ex_mode)) {
1548                                 SMB_VFS_CHMOD(conn, smb_dname->base_name,
1549                                     (smb_dname->st.st_ex_mode |
1550                                         (mode & ~smb_dname->st.st_ex_mode)));
1551                         }
1552                 }
1553
1554                 /* Change the owner if required. */
1555                 if (lp_inherit_owner(SNUM(conn))) {
1556                         change_dir_owner_to_parent(conn, parent_dir,
1557                                                    smb_dname->base_name,
1558                                                    &smb_dname->st);
1559                 }
1560
1561                 notify_fname(conn, NOTIFY_ACTION_ADDED,
1562                              FILE_NOTIFY_CHANGE_DIR_NAME,
1563                              smb_dname->base_name);
1564         }
1565
1566         /* Stat the fd for Samba bookkeeping. */
1567         if(SMB_VFS_FSTAT(fsp, &smb_dname->st) != 0) {
1568                 fd_close(fsp);
1569                 file_free(req, fsp);
1570                 return map_nt_error_from_unix(errno);
1571         }
1572
1573         /* Setup the files_struct for it. */
1574         fsp->mode = smb_dname->st.st_ex_mode;
1575         fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_dname->st);
1576         fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
1577         fsp->file_pid = req ? req->smbpid : 0;
1578         fsp->can_lock = False;
1579         fsp->can_read = False;
1580         fsp->can_write = False;
1581
1582         fsp->share_access = share_access;
1583         fsp->fh->private_options = create_options;
1584         /*
1585          * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
1586          */
1587         fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
1588         fsp->print_file = False;
1589         fsp->modified = False;
1590         fsp->oplock_type = NO_OPLOCK;
1591         fsp->sent_oplock_break = NO_BREAK_SENT;
1592         fsp->is_directory = True;
1593         fsp->posix_open = posix_open;
1594
1595         string_set(&fsp->fsp_name, smb_dname->base_name);
1596
1597         mtimespec = smb_dname->st.st_ex_mtime;
1598
1599         /*
1600          * Still set the samba share mode lock for correct delete-on-close
1601          * semantics and to make smbstatus more useful.
1602          */
1603         lck = get_share_mode_lock(talloc_tos(), fsp->file_id,
1604                                   conn->connectpath, smb_dname, &mtimespec);
1605
1606         if (lck == NULL) {
1607                 DEBUG(0, ("onefs_open_directory: Could not get share mode "
1608                           "lock for %s\n", smb_fname_str_dbg(smb_dname)));
1609                 fd_close(fsp);
1610                 file_free(req, fsp);
1611                 return NT_STATUS_SHARING_VIOLATION;
1612         }
1613
1614         if (lck->delete_on_close) {
1615                 TALLOC_FREE(lck);
1616                 fd_close(fsp);
1617                 file_free(req, fsp);
1618                 return NT_STATUS_DELETE_PENDING;
1619         }
1620
1621         set_share_mode(lck, fsp, conn->server_info->utok.uid, 0, NO_OPLOCK);
1622
1623         /*
1624          * For directories the delete on close bit at open time seems
1625          * always to be honored on close... See test 19 in Samba4 BASE-DELETE.
1626          */
1627         if (create_options & FILE_DELETE_ON_CLOSE) {
1628                 status = can_set_delete_on_close(fsp, True, 0);
1629                 if (!NT_STATUS_IS_OK(status) &&
1630                     !NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
1631                         TALLOC_FREE(lck);
1632                         fd_close(fsp);
1633                         file_free(req, fsp);
1634                         return status;
1635                 }
1636
1637                 if (NT_STATUS_IS_OK(status)) {
1638                         /* Note that here we set the *inital* delete on close flag,
1639                            not the regular one. The magic gets handled in close. */
1640                         fsp->initial_delete_on_close = True;
1641                 }
1642         }
1643
1644         TALLOC_FREE(lck);
1645
1646         if (pinfo) {
1647                 *pinfo = info;
1648         }
1649
1650         *result = fsp;
1651         return NT_STATUS_OK;
1652 }
1653
1654 /*
1655  * Wrapper around onefs_open_file_ntcreate and onefs_open_directory.
1656  */
1657 static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
1658                                            struct smb_request *req,
1659                                            struct smb_filename *smb_fname,
1660                                            uint32_t access_mask,
1661                                            uint32_t share_access,
1662                                            uint32_t create_disposition,
1663                                            uint32_t create_options,
1664                                            uint32_t file_attributes,
1665                                            uint32_t oplock_request,
1666                                            uint64_t allocation_size,
1667                                            struct security_descriptor *sd,
1668                                            struct ea_list *ea_list,
1669                                            files_struct **result,
1670                                            int *pinfo,
1671                                            struct onefs_fsp_data *fsp_data)
1672 {
1673         int info = FILE_WAS_OPENED;
1674         files_struct *base_fsp = NULL;
1675         files_struct *fsp = NULL;
1676         NTSTATUS status;
1677
1678         DEBUG(10,("onefs_create_file_unixpath: access_mask = 0x%x "
1679                   "file_attributes = 0x%x, share_access = 0x%x, "
1680                   "create_disposition = 0x%x create_options = 0x%x "
1681                   "oplock_request = 0x%x ea_list = 0x%p, sd = 0x%p, "
1682                   "fname = %s\n",
1683                   (unsigned int)access_mask,
1684                   (unsigned int)file_attributes,
1685                   (unsigned int)share_access,
1686                   (unsigned int)create_disposition,
1687                   (unsigned int)create_options,
1688                   (unsigned int)oplock_request,
1689                   ea_list, sd, smb_fname_str_dbg(smb_fname)));
1690
1691         if (create_options & FILE_OPEN_BY_FILE_ID) {
1692                 status = NT_STATUS_NOT_SUPPORTED;
1693                 goto fail;
1694         }
1695
1696         if (create_options & NTCREATEX_OPTIONS_INVALID_PARAM_MASK) {
1697                 status = NT_STATUS_INVALID_PARAMETER;
1698                 goto fail;
1699         }
1700
1701         if (req == NULL) {
1702                 SMB_ASSERT((oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK) ==
1703                             NO_OPLOCK);
1704                 oplock_request |= INTERNAL_OPEN_ONLY;
1705         }
1706
1707         if (lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE,
1708                 PARM_IGNORE_SACLS, PARM_IGNORE_SACLS_DEFAULT)) {
1709                 access_mask &= ~SYSTEM_SECURITY_ACCESS;
1710         }
1711
1712         if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
1713             && (access_mask & DELETE_ACCESS)
1714             && !is_ntfs_stream_smb_fname(smb_fname)) {
1715                 /*
1716                  * We can't open a file with DELETE access if any of the
1717                  * streams is open without FILE_SHARE_DELETE
1718                  */
1719                 status = open_streams_for_delete(conn, smb_fname->base_name);
1720
1721                 if (!NT_STATUS_IS_OK(status)) {
1722                         goto fail;
1723                 }
1724         }
1725
1726         if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
1727             && is_ntfs_stream_smb_fname(smb_fname)) {
1728                 uint32 base_create_disposition;
1729                 struct smb_filename *smb_fname_base = NULL;
1730
1731                 if (create_options & FILE_DIRECTORY_FILE) {
1732                         status = NT_STATUS_NOT_A_DIRECTORY;
1733                         goto fail;
1734                 }
1735
1736                 switch (create_disposition) {
1737                 case FILE_OPEN:
1738                         base_create_disposition = FILE_OPEN;
1739                         break;
1740                 default:
1741                         base_create_disposition = FILE_OPEN_IF;
1742                         break;
1743                 }
1744
1745                 /* Create an smb_filename with stream_name == NULL. */
1746                 status = create_synthetic_smb_fname(talloc_tos(),
1747                                                     smb_fname->base_name,
1748                                                     NULL, NULL,
1749                                                     &smb_fname_base);
1750                 if (!NT_STATUS_IS_OK(status)) {
1751                         goto fail;
1752                 }
1753
1754                 if (SMB_VFS_STAT(conn, smb_fname_base) == -1) {
1755                         DEBUG(10, ("Unable to stat stream: %s\n",
1756                                    smb_fname_str_dbg(smb_fname_base)));
1757                 }
1758
1759                 status = onefs_create_file_unixpath(
1760                         conn,                           /* conn */
1761                         NULL,                           /* req */
1762                         smb_fname_base,                 /* fname */
1763                         SYNCHRONIZE_ACCESS,             /* access_mask */
1764                         (FILE_SHARE_READ |
1765                             FILE_SHARE_WRITE |
1766                             FILE_SHARE_DELETE),         /* share_access */
1767                         base_create_disposition,        /* create_disposition*/
1768                         0,                              /* create_options */
1769                         file_attributes,                /* file_attributes */
1770                         NO_OPLOCK,                      /* oplock_request */
1771                         0,                              /* allocation_size */
1772                         NULL,                           /* sd */
1773                         NULL,                           /* ea_list */
1774                         &base_fsp,                      /* result */
1775                         NULL,                           /* pinfo */
1776                         NULL);                          /* fsp_data */
1777
1778                 TALLOC_FREE(smb_fname_base);
1779
1780                 if (!NT_STATUS_IS_OK(status)) {
1781                         DEBUG(10, ("onefs_create_file_unixpath for base %s "
1782                                    "failed: %s\n", smb_fname->base_name,
1783                                    nt_errstr(status)));
1784                         goto fail;
1785                 }
1786
1787                 /*
1788                  * Testing against windows xp/2003/vista shows that oplocks
1789                  * can actually be requested and granted on streams (see the
1790                  * RAW-OPLOCK-STREAM1 smbtorture test).
1791                  */
1792                 if ((oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK) !=
1793                      NO_OPLOCK) {
1794                         DEBUG(5, ("Oplock(%d) being requested on a stream! "
1795                                   "Ignoring oplock request: fname=%s\n",
1796                                   oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK,
1797                                 smb_fname_str_dbg(smb_fname)));
1798                         /* Request NO_OPLOCK instead. */
1799                         oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
1800                 }
1801         }
1802
1803         /* Covert generic bits in the security descriptor. */
1804         if (sd != NULL) {
1805                 security_acl_map_generic(sd->dacl, &file_generic_mapping);
1806                 security_acl_map_generic(sd->sacl, &file_generic_mapping);
1807         }
1808
1809         /*
1810          * If it's a request for a directory open, deal with it separately.
1811          */
1812
1813         if (create_options & FILE_DIRECTORY_FILE) {
1814
1815                 if (create_options & FILE_NON_DIRECTORY_FILE) {
1816                         status = NT_STATUS_INVALID_PARAMETER;
1817                         goto fail;
1818                 }
1819
1820                 /* Can't open a temp directory. IFS kit test. */
1821                 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
1822                      (file_attributes & FILE_ATTRIBUTE_TEMPORARY)) {
1823                         status = NT_STATUS_INVALID_PARAMETER;
1824                         goto fail;
1825                 }
1826
1827                 /*
1828                  * We will get a create directory here if the Win32
1829                  * app specified a security descriptor in the
1830                  * CreateDirectory() call.
1831                  */
1832
1833                 status = onefs_open_directory(
1834                         conn,                           /* conn */
1835                         req,                            /* req */
1836                         smb_fname,                      /* fname */
1837                         access_mask,                    /* access_mask */
1838                         share_access,                   /* share_access */
1839                         create_disposition,             /* create_disposition*/
1840                         create_options,                 /* create_options */
1841                         file_attributes,                /* file_attributes */
1842                         sd,                             /* sd */
1843                         &fsp,                           /* result */
1844                         &info);                         /* pinfo */
1845         } else {
1846
1847                 /*
1848                  * Ordinary file case.
1849                  */
1850
1851                 status = file_new(req, conn, &fsp);
1852                 if(!NT_STATUS_IS_OK(status)) {
1853                         goto fail;
1854                 }
1855
1856                 /*
1857                  * We're opening the stream element of a base_fsp
1858                  * we already opened. Set up the base_fsp pointer.
1859                  */
1860                 if (base_fsp) {
1861                         fsp->base_fsp = base_fsp;
1862                 }
1863
1864                 status = onefs_open_file_ntcreate(
1865                         conn,                           /* conn */
1866                         req,                            /* req */
1867                         smb_fname,                      /* fname */
1868                         access_mask,                    /* access_mask */
1869                         share_access,                   /* share_access */
1870                         create_disposition,             /* create_disposition*/
1871                         create_options,                 /* create_options */
1872                         file_attributes,                /* file_attributes */
1873                         oplock_request,                 /* oplock_request */
1874                         sd,                             /* sd */
1875                         fsp,                            /* result */
1876                         &info,                          /* pinfo */
1877                         fsp_data);                      /* fsp_data */
1878
1879                 if(!NT_STATUS_IS_OK(status)) {
1880                         file_free(req, fsp);
1881                         fsp = NULL;
1882                 }
1883
1884                 if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
1885
1886                         /* A stream open never opens a directory */
1887
1888                         if (base_fsp) {
1889                                 status = NT_STATUS_FILE_IS_A_DIRECTORY;
1890                                 goto fail;
1891                         }
1892
1893                         /*
1894                          * Fail the open if it was explicitly a non-directory
1895                          * file.
1896                          */
1897
1898                         if (create_options & FILE_NON_DIRECTORY_FILE) {
1899                                 status = NT_STATUS_FILE_IS_A_DIRECTORY;
1900                                 goto fail;
1901                         }
1902
1903                         create_options |= FILE_DIRECTORY_FILE;
1904
1905                         status = onefs_open_directory(
1906                                 conn,                   /* conn */
1907                                 req,                    /* req */
1908                                 smb_fname,              /* fname */
1909                                 access_mask,            /* access_mask */
1910                                 share_access,           /* share_access */
1911                                 create_disposition,     /* create_disposition*/
1912                                 create_options,         /* create_options */
1913                                 file_attributes,        /* file_attributes */
1914                                 sd,                     /* sd */
1915                                 &fsp,                   /* result */
1916                                 &info);                 /* pinfo */
1917                 }
1918         }
1919
1920         if (!NT_STATUS_IS_OK(status)) {
1921                 goto fail;
1922         }
1923
1924         fsp->base_fsp = base_fsp;
1925
1926         SMB_ASSERT(fsp);
1927
1928         if ((ea_list != NULL) && (info == FILE_WAS_CREATED)) {
1929                 status = set_ea(conn, fsp, smb_fname, ea_list);
1930                 if (!NT_STATUS_IS_OK(status)) {
1931                         goto fail;
1932                 }
1933         }
1934
1935         if (!fsp->is_directory && S_ISDIR(smb_fname->st.st_ex_mode)) {
1936                 status = NT_STATUS_ACCESS_DENIED;
1937                 goto fail;
1938         }
1939
1940         /* Save the requested allocation size. */
1941         if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
1942                 if (allocation_size
1943                     && (allocation_size > smb_fname->st.st_ex_size)) {
1944                         fsp->initial_allocation_size = smb_roundup(
1945                                 fsp->conn, allocation_size);
1946                         if (fsp->is_directory) {
1947                                 /* Can't set allocation size on a directory. */
1948                                 status = NT_STATUS_ACCESS_DENIED;
1949                                 goto fail;
1950                         }
1951                         if (vfs_allocate_file_space(
1952                                     fsp, fsp->initial_allocation_size) == -1) {
1953                                 status = NT_STATUS_DISK_FULL;
1954                                 goto fail;
1955                         }
1956                 } else {
1957                         fsp->initial_allocation_size = smb_roundup(
1958                                 fsp->conn, (uint64_t)smb_fname->st.st_ex_size);
1959                 }
1960         }
1961
1962         DEBUG(10, ("onefs_create_file_unixpath: info=%d\n", info));
1963
1964         *result = fsp;
1965         if (pinfo != NULL) {
1966                 *pinfo = info;
1967         }
1968         if ((fsp->fh != NULL) && (fsp->fh->fd != -1)) {
1969                 SMB_VFS_FSTAT(fsp, &smb_fname->st);
1970         }
1971         return NT_STATUS_OK;
1972
1973  fail:
1974         DEBUG(10, ("onefs_create_file_unixpath: %s\n", nt_errstr(status)));
1975
1976         if (fsp != NULL) {
1977                 if (base_fsp && fsp->base_fsp == base_fsp) {
1978                         /*
1979                          * The close_file below will close
1980                          * fsp->base_fsp.
1981                          */
1982                         base_fsp = NULL;
1983                 }
1984                 close_file(req, fsp, ERROR_CLOSE);
1985                 fsp = NULL;
1986         }
1987         if (base_fsp != NULL) {
1988                 close_file(req, base_fsp, ERROR_CLOSE);
1989                 base_fsp = NULL;
1990         }
1991         return status;
1992 }
1993
1994 static void destroy_onefs_fsp_data(void *p_data)
1995 {
1996         struct onefs_fsp_data *fsp_data = (struct onefs_fsp_data *)p_data;
1997
1998         destroy_onefs_callback_record(fsp_data->oplock_callback_id);
1999 }
2000
2001 /**
2002  * SMB_VFS_CREATE_FILE interface to onefs.
2003  */
2004 NTSTATUS onefs_create_file(vfs_handle_struct *handle,
2005                            struct smb_request *req,
2006                            uint16_t root_dir_fid,
2007                            struct smb_filename *smb_fname,
2008                            uint32_t access_mask,
2009                            uint32_t share_access,
2010                            uint32_t create_disposition,
2011                            uint32_t create_options,
2012                            uint32_t file_attributes,
2013                            uint32_t oplock_request,
2014                            uint64_t allocation_size,
2015                            struct security_descriptor *sd,
2016                            struct ea_list *ea_list,
2017                            files_struct **result,
2018                            int *pinfo)
2019 {
2020         connection_struct *conn = handle->conn;
2021         struct onefs_fsp_data fsp_data = {};
2022         int info = FILE_WAS_OPENED;
2023         files_struct *fsp = NULL;
2024         NTSTATUS status;
2025
2026         DEBUG(10,("onefs_create_file: access_mask = 0x%x "
2027                   "file_attributes = 0x%x, share_access = 0x%x, "
2028                   "create_disposition = 0x%x create_options = 0x%x "
2029                   "oplock_request = 0x%x "
2030                   "root_dir_fid = 0x%x, ea_list = 0x%p, sd = 0x%p, "
2031                   "fname = %s\n",
2032                   (unsigned int)access_mask,
2033                   (unsigned int)file_attributes,
2034                   (unsigned int)share_access,
2035                   (unsigned int)create_disposition,
2036                   (unsigned int)create_options,
2037                   (unsigned int)oplock_request,
2038                   (unsigned int)root_dir_fid,
2039                   ea_list, sd, smb_fname_str_dbg(smb_fname)));
2040
2041         /* Get the file name if root_dir_fid was specified. */
2042         if (root_dir_fid != 0) {
2043                 status = get_relative_fid_filename(conn, req, root_dir_fid,
2044                                                    smb_fname);
2045                 if (!NT_STATUS_IS_OK(status)) {
2046                         goto fail;
2047                 }
2048         }
2049
2050         /* All file access must go through check_name() */
2051         status = check_name(conn, smb_fname->base_name);
2052         if (!NT_STATUS_IS_OK(status)) {
2053                 goto fail;
2054         }
2055
2056         status = onefs_create_file_unixpath(
2057                 conn,                                   /* conn */
2058                 req,                                    /* req */
2059                 smb_fname,                              /* fname */
2060                 access_mask,                            /* access_mask */
2061                 share_access,                           /* share_access */
2062                 create_disposition,                     /* create_disposition*/
2063                 create_options,                         /* create_options */
2064                 file_attributes,                        /* file_attributes */
2065                 oplock_request,                         /* oplock_request */
2066                 allocation_size,                        /* allocation_size */
2067                 sd,                                     /* sd */
2068                 ea_list,                                /* ea_list */
2069                 &fsp,                                   /* result */
2070                 &info,                                  /* pinfo */
2071                 &fsp_data);                             /* psbuf */
2072
2073         if (!NT_STATUS_IS_OK(status)) {
2074                 goto fail;
2075         }
2076
2077         DEBUG(10, ("onefs_create_file: info=%d\n", info));
2078
2079         /*
2080          * Setup private onefs_fsp_data.  Currently the private data struct is
2081          * only used to store the oplock_callback_id so that when the file is
2082          * closed, the onefs_callback_record can be properly cleaned up in the
2083          * oplock_onefs sub-system.
2084          */
2085         if (fsp) {
2086                 struct onefs_fsp_data *fsp_data_tmp = NULL;
2087                 fsp_data_tmp = (struct onefs_fsp_data *)
2088                     VFS_ADD_FSP_EXTENSION(handle, fsp, struct onefs_fsp_data,
2089                         &destroy_onefs_fsp_data);
2090
2091                 if (fsp_data_tmp == NULL) {
2092                         status = NT_STATUS_NO_MEMORY;
2093                         goto fail;
2094                 }
2095
2096                 *fsp_data_tmp = fsp_data;
2097         }
2098
2099         *result = fsp;
2100         if (pinfo != NULL) {
2101                 *pinfo = info;
2102         }
2103         return NT_STATUS_OK;
2104
2105  fail:
2106         DEBUG(10, ("onefs_create_file: %s\n", nt_errstr(status)));
2107
2108         if (fsp != NULL) {
2109                 close_file(req, fsp, ERROR_CLOSE);
2110                 fsp = NULL;
2111         }
2112         return status;
2113 }