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