s3: Add the OneFS SMB_VFS_CREATE_FILE implementation
[kai/samba.git] / source3 / modules / onefs_open.c
1 /*
2  * Unix SMB/CIFS implementation.
3  *
4  * This file began with some code from source3/smbd/open.c and modified it to
5  * 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);
463         }
464
465         if (!parent_dirname_talloc(talloc_tos(), fname, &parent_dir,
466                                    &newname)) {
467                 return NT_STATUS_NO_MEMORY;
468         }
469
470         if (new_dos_attributes & FILE_FLAG_POSIX_SEMANTICS) {
471                 posix_open = True;
472                 unx_mode = (mode_t)(new_dos_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
473                 new_dos_attributes = 0;
474         } else {
475                 /* We add aARCH to this as this mode is only used if the file is
476                  * created new. */
477                 unx_mode = unix_mode(conn, new_dos_attributes | aARCH, fname,
478                                      parent_dir);
479         }
480
481         DEBUG(10,("onefs_open_file_ntcreate: fname=%s, dos_attrs=0x%x "
482                   "access_mask=0x%x share_access=0x%x "
483                   "create_disposition = 0x%x create_options=0x%x "
484                   "unix mode=0%o oplock_request=0x%x\n",
485                   fname, new_dos_attributes, access_mask, share_access,
486                   create_disposition, create_options, unx_mode,
487                   oplock_request));
488
489         if ((req == NULL) && ((oplock_request & INTERNAL_OPEN_ONLY) == 0)) {
490                 DEBUG(0, ("No smb request but not an internal only open!\n"));
491                 return NT_STATUS_INTERNAL_ERROR;
492         }
493
494         /*
495          * Only non-internal opens can be deferred at all
496          */
497
498         if ((req != NULL)
499             && ((pml = get_open_deferred_message(req->mid)) != NULL)) {
500                 struct deferred_open_record *state =
501                         (struct deferred_open_record *)pml->private_data.data;
502
503                 /* Remember the absolute time of the original
504                    request with this mid. We'll use it later to
505                    see if this has timed out. */
506
507                 request_time = pml->request_time;
508
509                 /* Remove the deferred open entry under lock. */
510                 lck = get_share_mode_lock(talloc_tos(), state->id, NULL, NULL,
511                                           NULL);
512                 if (lck == NULL) {
513                         DEBUG(0, ("could not get share mode lock\n"));
514                 } else {
515                         del_deferred_open_entry(lck, req->mid);
516                         TALLOC_FREE(lck);
517                 }
518
519                 /* Ensure we don't reprocess this message. */
520                 remove_deferred_open_smb_message(req->mid);
521
522                 /*
523                  * When receiving a semlock_async_failure message, the
524                  * deferred open will be marked as "failed". Returning
525                  * INTERNAL_ERROR.
526                  */
527                 if (state->failed) {
528                         DEBUG(0, ("onefs_open_file_ntcreate: "
529                                   "semlock_async_failure detected!\n"));
530                         return NT_STATUS_INTERNAL_ERROR;
531                 }
532         }
533
534         status = check_name(conn, fname);
535         if (!NT_STATUS_IS_OK(status)) {
536                 return status;
537         }
538
539         if (!posix_open) {
540                 new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
541                 if (file_existed) {
542                         existing_dos_attributes = dos_mode(conn, fname, psbuf);
543                 }
544         }
545
546         /* Setup dos_attributes to be set by ifs_createfile */
547         if (lp_store_dos_attributes(SNUM(conn))) {
548                 createfile_attributes = (new_dos_attributes | aARCH) &
549                     ~(FILE_ATTRIBUTE_NONINDEXED | FILE_ATTRIBUTE_COMPRESSED);
550         }
551
552         /* Ignore oplock requests if oplocks are disabled. */
553         if (!lp_oplocks(SNUM(conn)) || global_client_failed_oplock_break ||
554             IS_VETO_OPLOCK_PATH(conn, fname)) {
555                 /* Mask off everything except the private Samba bits. */
556                 oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
557         }
558
559         /* this is for OS/2 long file names - say we don't support them */
560         if (!lp_posix_pathnames() && strstr(fname,".+,;=[].")) {
561                 /* OS/2 Workplace shell fix may be main code stream in a later
562                  * release. */
563                 DEBUG(5,("onefs_open_file_ntcreate: OS/2 long filenames are "
564                           "not supported.\n"));
565                 if (use_nt_status()) {
566                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
567                 }
568                 return NT_STATUS_DOS(ERRDOS, ERRcannotopen);
569         }
570
571         switch( create_disposition ) {
572                 /*
573                  * Currently we're using FILE_SUPERSEDE as the same as
574                  * FILE_OVERWRITE_IF but they really are
575                  * different. FILE_SUPERSEDE deletes an existing file
576                  * (requiring delete access) then recreates it.
577                  */
578                 case FILE_SUPERSEDE:
579                         /* If file exists replace/overwrite. If file doesn't
580                          * exist create. */
581                         /**
582                          * @todo: Clear all file attributes?
583                          * http://www.osronline.com/article.cfm?article=302
584                          * create if not exist, trunc if exist
585                          *
586                          * If file exists replace/overwrite. If file doesn't
587                          * exist create.
588                          */
589                         flags2 |= (O_CREAT | O_TRUNC);
590                         break;
591
592                 case FILE_OVERWRITE_IF:
593                         /* If file exists replace/overwrite. If file doesn't
594                          * exist create. */
595                         flags2 |= (O_CREAT | O_TRUNC);
596                         break;
597
598                 case FILE_OPEN:
599                         /* If file exists open. If file doesn't exist error. */
600                         if (!file_existed) {
601                                 DEBUG(5,("onefs_open_file_ntcreate: FILE_OPEN "
602                                          "requested for file %s and file "
603                                          "doesn't exist.\n", fname ));
604                                 errno = ENOENT;
605                                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
606                         }
607                         break;
608
609                 case FILE_OVERWRITE:
610                         /* If file exists overwrite. If file doesn't exist
611                          * error. */
612                         if (!file_existed) {
613                                 DEBUG(5, ("onefs_open_file_ntcreate: "
614                                           "FILE_OVERWRITE requested for file "
615                                           "%s and file doesn't exist.\n",
616                                           fname));
617                                 errno = ENOENT;
618                                 return NT_STATUS_OBJECT_NAME_NOT_FOUND;
619                         }
620                         flags2 |= O_TRUNC;
621                         break;
622
623                 case FILE_CREATE:
624                         /* If file exists error. If file doesn't exist
625                          * create. */
626                         if (file_existed) {
627                                 DEBUG(5, ("onefs_open_file_ntcreate: "
628                                           "FILE_CREATE requested for file %s "
629                                           "and file already exists.\n",
630                                           fname));
631                                 if (S_ISDIR(psbuf->st_mode)) {
632                                         errno = EISDIR;
633                                 } else {
634                                         errno = EEXIST;
635                                 }
636                                 return map_nt_error_from_unix(errno);
637                         }
638                         flags2 |= (O_CREAT|O_EXCL);
639                         break;
640
641                 case FILE_OPEN_IF:
642                         /* If file exists open. If file doesn't exist
643                          * create. */
644                         flags2 |= O_CREAT;
645                         break;
646
647                 default:
648                         return NT_STATUS_INVALID_PARAMETER;
649         }
650
651         /* Match attributes on file exists and overwrite. */
652         if (!posix_open && file_existed &&
653             ((create_disposition == FILE_OVERWRITE) ||
654                 (create_disposition == FILE_OVERWRITE_IF))) {
655                 if (!open_match_attributes(conn, fname,
656                                            existing_dos_attributes,
657                                            new_dos_attributes, psbuf->st_mode,
658                                            unx_mode, &new_unx_mode)) {
659                         DEBUG(5, ("onefs_open_file_ntcreate: attributes "
660                                   "missmatch for file %s (%x %x) (0%o, 0%o)\n",
661                                   fname, existing_dos_attributes,
662                                   new_dos_attributes,
663                                   (unsigned int)psbuf->st_mode,
664                                   (unsigned int)unx_mode ));
665                         errno = EACCES;
666                         return NT_STATUS_ACCESS_DENIED;
667                 }
668         }
669
670         /*
671          * OneFS understands MAXIMUM_ALLOWED_ACCESS, so only hack the
672          * access_mask, but leave the MAA for the actual open in
673          * open_access_mask.
674          */
675         open_access_mask = access_mask;
676         if (open_access_mask & MAXIMUM_ALLOWED_ACCESS) {
677                 access_mask |= FILE_GENERIC_ALL;
678         }
679
680         /* Convert GENERIC bits to specific bits. */
681         se_map_generic(&access_mask, &file_generic_mapping);
682         se_map_generic(&open_access_mask, &file_generic_mapping);
683
684         if ((flags2 & O_TRUNC) || (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE)) {
685                 /* This will cause oplock breaks. */
686                 open_access_mask |= FILE_WRITE_DATA;
687         }
688
689         DEBUG(10, ("onefs_open_file_ntcreate: fname=%s, after mapping "
690                    "open_access_mask=%#x, access_mask=0x%x\n",
691                    fname, open_access_mask, access_mask));
692
693         /*
694          * Note that we ignore the append flag as append does not
695          * mean the same thing under DOS and Unix.
696          */
697
698         if ((access_mask & (FILE_WRITE_DATA | FILE_APPEND_DATA)) ||
699             (oplock_request & FORCE_OPLOCK_BREAK_TO_NONE)) {
700
701                 /*
702                  * DENY_DOS opens are always underlying read-write on the
703                  * file handle, no matter what the requested access mask
704                  * says. Stock samba just sets the flags, but since
705                  * ifs_createfile uses the access_mask, it must be updated as
706                  * well.  This allows BASE-DENY* to pass.
707                  */
708                 if (create_options & NTCREATEX_OPTIONS_PRIVATE_DENY_DOS) {
709
710                         DEBUG(10,("onefs_open_file_ntcreate: deny_dos: "
711                                   "Adding O_RDWR to flags "
712                                   "(0x%x) and some READ bits to "
713                                   "open_access_mask (0x%x)\n",
714                                   flags, open_access_mask));
715
716                         flags = O_RDWR;
717                         open_access_mask |= (FILE_READ_ATTRIBUTES |
718                             FILE_READ_DATA | FILE_READ_EA | FILE_EXECUTE);
719
720                 } else if (access_mask & (FILE_READ_ATTRIBUTES |
721                                FILE_READ_DATA |
722                                FILE_READ_EA |
723                                FILE_EXECUTE)) {
724                         flags = O_RDWR;
725                 } else {
726                         flags = O_WRONLY;
727                 }
728         } else {
729                 flags = O_RDONLY;
730         }
731
732         /* Currently we only look at FILE_WRITE_THROUGH for create options. */
733 #if defined(O_SYNC)
734         if ((create_options & FILE_WRITE_THROUGH) &&
735             lp_strict_sync(SNUM(conn))) {
736                 flags2 |= O_SYNC;
737         }
738 #endif /* O_SYNC */
739
740         if (posix_open && (access_mask & FILE_APPEND_DATA)) {
741                 flags2 |= O_APPEND;
742         }
743
744         if (!posix_open && !CAN_WRITE(conn)) {
745                 /*
746                  * We should really return a permission denied error if either
747                  * O_CREAT or O_TRUNC are set, but for compatibility with
748                  * older versions of Samba we just AND them out.
749                  */
750                 flags2 &= ~(O_CREAT|O_TRUNC);
751
752                 /**
753                  * XXX: TODO
754                  * Apparently this is necessary because we ship with
755                  * lp_acl_check_permissions = no.  It is set to no because our
756                  * ifs_createfile does the access check correctly.  This check
757                  * was added in the last merge, and the question is why is it
758                  * necessary?  Check out Bug 25547 and Bug 14596.  The key is
759                  * to figure out what case this is covering, and do some
760                  * testing to see if it's actually necessary.  If it is, maybe
761                  * it should go upstream in open.c.
762                  */
763                 if (!lp_acl_check_permissions(SNUM(conn)) &&
764                     (access_mask & DELETE_ACCESS)) {
765                         return map_nt_error_from_unix(EACCES);
766                 }
767         }
768
769         /* Ensure we can't write on a read-only share or file. */
770         if (flags != O_RDONLY && file_existed &&
771             (!CAN_WRITE(conn) || IS_DOS_READONLY(existing_dos_attributes))) {
772                 DEBUG(5, ("onefs_open_file_ntcreate: write access requested "
773                           "for file %s on read only %s\n",
774                           fname, !CAN_WRITE(conn) ? "share" : "file" ));
775                 errno = EACCES;
776                 return NT_STATUS_ACCESS_DENIED;
777         }
778
779         DEBUG(10, ("fsp = %p\n", fsp));
780
781         fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf);
782         fsp->share_access = share_access;
783         fsp->fh->private_options = create_options;
784         fsp->access_mask = open_access_mask; /* We change this to the
785                                               * requested access_mask after
786                                               * the open is done. */
787         fsp->posix_open = posix_open;
788
789         /* Ensure no SAMBA_PRIVATE bits can be set. */
790         fsp->oplock_type = (oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK);
791
792         if (timeval_is_zero(&request_time)) {
793                 request_time = fsp->open_time;
794         }
795
796         if (file_existed) {
797                 struct timespec old_write_time = get_mtimespec(psbuf);
798                 id = vfs_file_id_from_sbuf(conn, psbuf);
799
800                 lck = get_share_mode_lock(talloc_tos(), id,
801                                           conn->connectpath,
802                                           fname, &old_write_time);
803
804                 if (lck == NULL) {
805                         DEBUG(0, ("Could not get share mode lock\n"));
806                         return NT_STATUS_SHARING_VIOLATION;
807                 }
808
809                 if (lck->delete_on_close) {
810                         /* DELETE_PENDING is not deferred for a second */
811                         TALLOC_FREE(lck);
812                         return NT_STATUS_DELETE_PENDING;
813                 }
814         }
815
816         SMB_ASSERT(!file_existed || (lck != NULL));
817
818         /*
819          * Ensure we pay attention to default ACLs on directories.  May be
820          * neccessary depending on ACL policies.
821          */
822         if ((flags2 & O_CREAT) && lp_inherit_acls(SNUM(conn)) &&
823             (def_acl = directory_has_default_acl(conn, parent_dir))) {
824                 unx_mode = 0777;
825         }
826
827         DEBUG(4,("calling onefs_open_file with flags=0x%X flags2=0x%X "
828                  "mode=0%o, access_mask = 0x%x, open_access_mask = 0x%x\n",
829                  (unsigned int)flags, (unsigned int)flags2,
830                  (unsigned int)unx_mode, (unsigned int)access_mask,
831                  (unsigned int)open_access_mask));
832
833         oplock_waiter = 1; //ifs_oplock_wait_record(mid);
834
835         if (oplock_waiter == 0) {
836                 return NT_STATUS_NO_MEMORY;
837         }
838
839         /* Do the open. */
840         status = onefs_open_file(fsp,
841                                  conn,
842                                  req,
843                                  parent_dir,
844                                  newname,
845                                  fname,
846                                  psbuf,
847                                  flags|flags2,
848                                  unx_mode,
849                                  access_mask,
850                                  open_access_mask,
851                                  fsp->oplock_type,
852                                  oplock_waiter,
853                                  share_access,
854                                  create_options,
855                                  createfile_attributes,
856                                  sd,
857                                  &granted_oplock);
858
859         if (!NT_STATUS_IS_OK(status)) {
860
861                 /* OneFS Oplock Handling */
862                 if (errno == EINPROGRESS) {
863
864                         if (lck == NULL) {
865
866                                 struct deferred_open_record state;
867                                 struct timespec old_write_time;
868
869                                 old_write_time = get_mtimespec(psbuf);
870
871                                 DEBUG(3, ("Someone created file %s with an "
872                                           "oplock after we looked: Retrying\n",
873                                           fname));
874                                 /*
875                                  * We hit the race that when we did the stat
876                                  * on the file it did not exist, and someone
877                                  * has created it in between the stat and the
878                                  * open_file() call. Just retry immediately.
879                                  */
880                                 id = vfs_file_id_from_sbuf(conn, psbuf);
881                                 if (!(lck = get_share_mode_lock(talloc_tos(),
882                                           id, conn->connectpath, fname,
883                                           &old_write_time))) {
884                                         /*
885                                          * Emergency exit
886                                          */
887                                         DEBUG(0, ("onefs_open_file_ntcreate: "
888                                                   "Could not get share mode "
889                                                   "lock for %s\n", fname));
890                                         status = NT_STATUS_SHARING_VIOLATION;
891                                         goto cleanup_destroy;
892                                 }
893
894                                 state.delayed_for_oplocks = False;
895                                 state.id = id;
896
897                                 if (req != NULL) {
898                                         defer_open(lck, request_time,
899                                             timeval_zero(), req, &state);
900                                 }
901                                 goto cleanup_destroy;
902                         }
903                         /* Waiting for an oplock */
904                         SMB_ASSERT(req);
905                         schedule_defer_open(lck, request_time, req);
906                         goto cleanup;
907                 }
908
909                 /* Check for a sharing violation */
910                 if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
911                         uint32 can_access_mask;
912                         bool can_access = True;
913
914                         /* Check if this can be done with the deny_dos and fcb
915                          * calls. */
916
917                         /* Try to find dup fsp if possible. */
918                         if (create_options &
919                             (NTCREATEX_OPTIONS_PRIVATE_DENY_DOS|
920                              NTCREATEX_OPTIONS_PRIVATE_DENY_FCB)) {
921
922                                 if (req == NULL) {
923                                         DEBUG(0, ("DOS open without an SMB "
924                                                   "request!\n"));
925                                         status = NT_STATUS_INTERNAL_ERROR;
926                                         goto cleanup_destroy;
927                                 }
928
929                                 /* Use the client requested access mask here,
930                                  * not the one we open with. */
931                                 status = fcb_or_dos_open(req,
932                                                         conn,
933                                                         fsp,
934                                                         fname,
935                                                         id,
936                                                         req->smbpid,
937                                                         req->vuid,
938                                                         access_mask,
939                                                         share_access,
940                                                         create_options);
941
942                                 if (NT_STATUS_IS_OK(status)) {
943                                         TALLOC_FREE(lck);
944                                         if (pinfo) {
945                                                 *pinfo = FILE_WAS_OPENED;
946                                         }
947                                         status =  NT_STATUS_OK;
948                                         goto cleanup;
949                                 }
950                         }
951
952                         /*
953                          * This next line is a subtlety we need for
954                          * MS-Access. If a file open will fail due to share
955                          * permissions and also for security (access) reasons,
956                          * we need to return the access failed error, not the
957                          * share error. We can't open the file due to kernel
958                          * oplock deadlock (it's possible we failed above on
959                          * the open_mode_check()) so use a userspace check.
960                          */
961
962                         if (flags & O_RDWR) {
963                                 can_access_mask = FILE_READ_DATA|FILE_WRITE_DATA;
964                         } else if (flags & O_WRONLY) {
965                                 can_access_mask = FILE_WRITE_DATA;
966                         } else {
967                                 can_access_mask = FILE_READ_DATA;
968                         }
969
970                         if (((can_access_mask & FILE_WRITE_DATA) && !CAN_WRITE(conn)) ||
971                             !can_access_file_data(conn,fname,psbuf,can_access_mask)) {
972                                 can_access = False;
973                         }
974
975                         /*
976                          * If we're returning a share violation, ensure we
977                          * cope with the braindead 1 second delay.
978                          */
979                         if (!(oplock_request & INTERNAL_OPEN_ONLY) &&
980                             lp_defer_sharing_violations()) {
981                                 struct timeval timeout;
982                                 struct deferred_open_record state;
983                                 int timeout_usecs;
984
985                                 /* this is a hack to speed up torture tests
986                                    in 'make test' */
987                                 timeout_usecs = lp_parm_int(SNUM(conn),
988                                     "smbd","sharedelay",
989                                     SHARING_VIOLATION_USEC_WAIT);
990
991                                 /* This is a relative time, added to the
992                                    absolute request_time value to get the
993                                    absolute timeout time.  Note that if this
994                                    is the second or greater time we enter this
995                                    codepath for this particular request mid
996                                    then request_time is left as the absolute
997                                    time of the *first* time this request mid
998                                    was processed. This is what allows the
999                                    request to eventually time out. */
1000
1001                                 timeout = timeval_set(0, timeout_usecs);
1002
1003                                 /* Nothing actually uses
1004                                    state.delayed_for_oplocks but it's handy to
1005                                    differentiate in debug messages between a
1006                                    30 second delay due to oplock break, and a
1007                                    1 second delay for share mode conflicts. */
1008
1009                                 state.delayed_for_oplocks = False;
1010                                 state.id = id;
1011                                 state.failed = false;
1012
1013                                 if ((req != NULL)
1014                                     && !request_timed_out(request_time,
1015                                                           timeout)) {
1016                                         defer_open(lck, request_time, timeout,
1017                                                    req, &state);
1018                                 }
1019                         }
1020
1021                         if (can_access) {
1022                                 /*
1023                                  * We have detected a sharing violation here
1024                                  * so return the correct error code
1025                                  */
1026                                 status = NT_STATUS_SHARING_VIOLATION;
1027                         } else {
1028                                 status = NT_STATUS_ACCESS_DENIED;
1029                         }
1030
1031                         goto cleanup_destroy;
1032                 }
1033
1034                 /*
1035                  * Normal error, for example EACCES
1036                  */
1037          cleanup_destroy:
1038                 //destroy_ifs_callback_record(oplock_waiter);
1039          cleanup:
1040                 TALLOC_FREE(lck);
1041                 return status;
1042         }
1043
1044         fsp->oplock_type = granted_oplock;
1045
1046         /* XXX uncomment for oplocks */
1047         //ifs_set_oplock_callback(oplock_waiter, fsp);
1048         //fsp->oplock_callback_id = oplock_waiter;
1049
1050         if (!file_existed) {
1051                 struct timespec old_write_time = get_mtimespec(psbuf);
1052                 /*
1053                  * Deal with the race condition where two smbd's detect the
1054                  * file doesn't exist and do the create at the same time. One
1055                  * of them will win and set a share mode, the other (ie. this
1056                  * one) should check if the requested share mode for this
1057                  * create is allowed.
1058                  */
1059
1060                 /*
1061                  * Now the file exists and fsp is successfully opened,
1062                  * fsp->dev and fsp->inode are valid and should replace the
1063                  * dev=0,inode=0 from a non existent file. Spotted by
1064                  * Nadav Danieli <nadavd@exanet.com>. JRA.
1065                  */
1066
1067                 id = fsp->file_id;
1068
1069                 lck = get_share_mode_lock(talloc_tos(), id,
1070                                           conn->connectpath,
1071                                           fname, &old_write_time);
1072
1073                 if (lck == NULL) {
1074                         DEBUG(0, ("onefs_open_file_ntcreate: Could not get "
1075                                   "share mode lock for %s\n", fname));
1076                         fd_close(fsp);
1077                         return NT_STATUS_SHARING_VIOLATION;
1078                 }
1079
1080                 if (lck->delete_on_close) {
1081                         status = NT_STATUS_DELETE_PENDING;
1082                 }
1083
1084                 if (!NT_STATUS_IS_OK(status)) {
1085                         struct deferred_open_record state;
1086
1087                         fd_close(fsp);
1088
1089                         state.delayed_for_oplocks = False;
1090                         state.id = id;
1091
1092                         /* Do it all over again immediately. In the second
1093                          * round we will find that the file existed and handle
1094                          * the DELETE_PENDING and FCB cases correctly. No need
1095                          * to duplicate the code here. Essentially this is a
1096                          * "goto top of this function", but don't tell
1097                          * anybody... */
1098
1099                         if (req != NULL) {
1100                                 defer_open(lck, request_time, timeval_zero(),
1101                                            req, &state);
1102                         }
1103                         TALLOC_FREE(lck);
1104                         return status;
1105                 }
1106
1107                 /*
1108                  * We exit this block with the share entry *locked*.....
1109                  */
1110
1111         }
1112
1113         SMB_ASSERT(lck != NULL);
1114
1115         /* note that we ignore failure for the following. It is
1116            basically a hack for NFS, and NFS will never set one of
1117            these only read them. Nobody but Samba can ever set a deny
1118            mode and we have already checked our more authoritative
1119            locking database for permission to set this deny mode. If
1120            the kernel refuses the operations then the kernel is wrong.
1121            note that GPFS supports it as well - jmcd */
1122
1123         if (fsp->fh->fd != -1) {
1124                 ret_flock = SMB_VFS_KERNEL_FLOCK(fsp, share_access);
1125                 if(ret_flock == -1 ){
1126
1127                         TALLOC_FREE(lck);
1128                         fd_close(fsp);
1129                         return NT_STATUS_SHARING_VIOLATION;
1130                 }
1131         }
1132
1133         /*
1134          * At this point onwards, we can guarentee that the share entry
1135          * is locked, whether we created the file or not, and that the
1136          * deny mode is compatible with all current opens.
1137          */
1138
1139         /* Record the options we were opened with. */
1140         fsp->share_access = share_access;
1141         fsp->fh->private_options = create_options;
1142         /*
1143          * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
1144          */
1145         fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
1146
1147         if (file_existed) {
1148                 /* stat opens on existing files don't get oplocks. */
1149                 if (is_stat_open(open_access_mask)) {
1150                         fsp->oplock_type = NO_OPLOCK;
1151                 }
1152
1153                 if (!(flags2 & O_TRUNC)) {
1154                         info = FILE_WAS_OPENED;
1155                 } else {
1156                         info = FILE_WAS_OVERWRITTEN;
1157                 }
1158         } else {
1159                 info = FILE_WAS_CREATED;
1160         }
1161
1162         if (pinfo) {
1163                 *pinfo = info;
1164         }
1165
1166         /*
1167          * Setup the oplock info in both the shared memory and
1168          * file structs.
1169          */
1170
1171         if ((fsp->oplock_type != NO_OPLOCK) &&
1172             (fsp->oplock_type != FAKE_LEVEL_II_OPLOCK)) {
1173                 if (!set_file_oplock(fsp, fsp->oplock_type)) {
1174                         /* Could not get the kernel oplock */
1175                         fsp->oplock_type = NO_OPLOCK;
1176                 }
1177         }
1178
1179         if (info == FILE_WAS_OVERWRITTEN || info == FILE_WAS_CREATED ||
1180             info == FILE_WAS_SUPERSEDED) {
1181                 new_file_created = True;
1182         }
1183
1184         set_share_mode(lck, fsp, conn->server_info->utok.uid, 0,
1185                        fsp->oplock_type, true);
1186
1187         /* Handle strange delete on close create semantics. */
1188         if (create_options & FILE_DELETE_ON_CLOSE) {
1189                 status = can_set_delete_on_close(fsp, True, new_dos_attributes);
1190
1191                 if (!NT_STATUS_IS_OK(status)) {
1192                         /* Remember to delete the mode we just added. */
1193                         del_share_mode(lck, fsp);
1194                         TALLOC_FREE(lck);
1195                         fd_close(fsp);
1196                         return status;
1197                 }
1198                 /* Note that here we set the *inital* delete on close flag,
1199                    not the regular one. The magic gets handled in close. */
1200                 fsp->initial_delete_on_close = True;
1201         }
1202
1203         /*
1204          * Take care of inherited ACLs on created files - if default ACL not
1205          * selected.
1206          * May be necessary depending on acl policies.
1207          */
1208         if (!posix_open && !file_existed && !def_acl && !(VALID_STAT(*psbuf)
1209                   && (psbuf->st_flags & SF_HASNTFSACL))) {
1210
1211                 int saved_errno = errno; /* We might get ENOSYS in the next
1212                                           * call.. */
1213
1214                 if (SMB_VFS_FCHMOD_ACL(fsp, unx_mode) == -1 &&
1215                     errno == ENOSYS) {
1216                         errno = saved_errno; /* Ignore ENOSYS */
1217                 }
1218
1219         } else if (new_unx_mode) {
1220
1221                 int ret = -1;
1222
1223                 /* Attributes need changing. File already existed. */
1224
1225                 {
1226                         int saved_errno = errno; /* We might get ENOSYS in the
1227                                                   * next call.. */
1228                         ret = SMB_VFS_FCHMOD_ACL(fsp, new_unx_mode);
1229
1230                         if (ret == -1 && errno == ENOSYS) {
1231                                 errno = saved_errno; /* Ignore ENOSYS */
1232                         } else {
1233                                 DEBUG(5, ("onefs_open_file_ntcreate: reset "
1234                                           "attributes of file %s to 0%o\n",
1235                                           fname, (unsigned int)new_unx_mode));
1236                                 ret = 0; /* Don't do the fchmod below. */
1237                         }
1238                 }
1239
1240                 if ((ret == -1) &&
1241                     (SMB_VFS_FCHMOD(fsp, new_unx_mode) == -1))
1242                         DEBUG(5, ("onefs_open_file_ntcreate: failed to reset "
1243                                   "attributes of file %s to 0%o\n",
1244                                   fname, (unsigned int)new_unx_mode));
1245         }
1246
1247         /* If this is a successful open, we must remove any deferred open
1248          * records. */
1249         if (req != NULL) {
1250                 del_deferred_open_entry(lck, req->mid);
1251         }
1252         TALLOC_FREE(lck);
1253
1254         return NT_STATUS_OK;
1255 }
1256
1257
1258 /****************************************************************************
1259  Open a directory from an NT SMB call.
1260 ****************************************************************************/
1261 static NTSTATUS onefs_open_directory(connection_struct *conn,
1262                                      struct smb_request *req,
1263                                      const char *fname,
1264                                      uint32 access_mask,
1265                                      uint32 share_access,
1266                                      uint32 create_disposition,
1267                                      uint32 create_options,
1268                                      uint32 file_attributes,
1269                                      struct security_descriptor *sd,
1270                                      files_struct **result,
1271                                      int *pinfo,
1272                                      SMB_STRUCT_STAT *psbuf)
1273 {
1274         files_struct *fsp = NULL;
1275         struct share_mode_lock *lck = NULL;
1276         NTSTATUS status;
1277         struct timespec mtimespec;
1278         int info = 0;
1279         char *parent_dir;
1280         const char *dirname;
1281         bool posix_open = false;
1282         uint32 create_flags = 0;
1283         uint32 mode = lp_dir_mask(SNUM(conn));
1284
1285         DEBUG(5, ("onefs_open_directory: opening directory %s, "
1286                   "access_mask = 0x%x, "
1287                   "share_access = 0x%x create_options = 0x%x, "
1288                   "create_disposition = 0x%x, file_attributes = 0x%x\n",
1289                   fname, (unsigned int)access_mask, (unsigned int)share_access,
1290                   (unsigned int)create_options, (unsigned int)create_disposition,
1291                   (unsigned int)file_attributes));
1292
1293         if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
1294             (conn->fs_capabilities & FILE_NAMED_STREAMS) &&
1295             is_ntfs_stream_name(fname)) {
1296                 DEBUG(2, ("onefs_open_directory: %s is a stream name!\n", fname));
1297                 return NT_STATUS_NOT_A_DIRECTORY;
1298         }
1299
1300         switch (create_disposition) {
1301                 case FILE_OPEN:
1302                         /* If directory exists open. If directory doesn't
1303                          * exist error. */
1304                         create_flags = 0;
1305                         info = FILE_WAS_OPENED;
1306                         break;
1307                 case FILE_CREATE:
1308                         /* If directory exists error. If directory doesn't
1309                          * exist create. */
1310                         create_flags = O_CREAT | O_EXCL;
1311                         info = FILE_WAS_CREATED;
1312                         break;
1313                 case FILE_OPEN_IF:
1314                         /* If directory exists open. If directory doesn't
1315                          * exist create. */
1316
1317                         /* Note: in order to return whether the directory was
1318                          * opened or created, we first try to open and then try
1319                          * to create. */
1320                         create_flags = 0;
1321                         info = FILE_WAS_OPENED;
1322                         break;
1323                 case FILE_SUPERSEDE:
1324                 case FILE_OVERWRITE:
1325                 case FILE_OVERWRITE_IF:
1326                 default:
1327                         DEBUG(5, ("onefs_open_directory: invalid "
1328                                   "create_disposition 0x%x for directory %s\n",
1329                                   (unsigned int)create_disposition, fname));
1330                         return NT_STATUS_INVALID_PARAMETER;
1331         }
1332
1333         /*
1334          * Check for write access to the share. Done in mkdir_internal() in
1335          * mainline samba.
1336          */
1337         if (!CAN_WRITE(conn) && (create_flags & O_CREAT)) {
1338                 return NT_STATUS_ACCESS_DENIED;
1339         }
1340
1341         /* Get parent dirname */
1342         if (!parent_dirname_talloc(talloc_tos(), fname, &parent_dir,
1343                                    &dirname)) {
1344                 return NT_STATUS_NO_MEMORY;
1345         }
1346
1347         if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
1348                 posix_open = true;
1349                 mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
1350                 file_attributes = 0;
1351         } else {
1352                 mode = unix_mode(conn, aDIR, fname, parent_dir);
1353         }
1354
1355         /*
1356          * The NONINDEXED and COMPRESSED bits seem to always be cleared on
1357          * directories, no matter if you specify that they should be set.
1358          */
1359         file_attributes &=
1360             ~(FILE_ATTRIBUTE_NONINDEXED | FILE_ATTRIBUTE_COMPRESSED);
1361
1362         status = file_new(req, conn, &fsp);
1363         if(!NT_STATUS_IS_OK(status)) {
1364                 return status;
1365         }
1366
1367         /*
1368          * Actual open with retry magic to handle FILE_OPEN_IF which is
1369          * unique because the kernel won't tell us if the file was opened or
1370          * created.
1371          */
1372  retry_open:
1373         fsp->fh->fd = onefs_sys_create_file(conn,
1374                                             -1,
1375                                             fname,
1376                                             access_mask,
1377                                             access_mask,
1378                                             share_access,
1379                                             create_options,
1380                                             create_flags | O_DIRECTORY,
1381                                             mode,
1382                                             0,
1383                                             0,
1384                                             sd,
1385                                             file_attributes,
1386                                             NULL);
1387
1388         if (fsp->fh->fd == -1) {
1389                 DEBUG(3, ("Error opening %s. Errno=%d (%s).\n", fname, errno,
1390                           strerror(errno)));
1391                 SMB_ASSERT(errno != EINPROGRESS);
1392
1393                 if (create_disposition == FILE_OPEN_IF) {
1394                         if (errno == ENOENT) {
1395                                 /* Try again, creating it this time. */
1396                                 create_flags = O_CREAT | O_EXCL;
1397                                 info = FILE_WAS_CREATED;
1398                                 goto retry_open;
1399                         } else if (errno == EEXIST) {
1400                                 /* Uggh. Try again again. */
1401                                 create_flags = 0;
1402                                 info = FILE_WAS_OPENED;
1403                                 goto retry_open;
1404                         }
1405                 }
1406
1407                 /* Error cases below: */
1408                 file_free(req, fsp);
1409
1410                 if ((errno == ENOENT) && (create_disposition == FILE_OPEN)) {
1411                         DEBUG(5,("onefs_open_directory: FILE_OPEN requested "
1412                                   "for directory %s and it doesn't "
1413                                   "exist.\n", fname ));
1414                         return NT_STATUS_OBJECT_NAME_NOT_FOUND;
1415                 } else if ((errno == EEXIST) &&
1416                     (create_disposition == FILE_CREATE)) {
1417                         DEBUG(5,("onefs_open_directory: FILE_CREATE "
1418                                   "requested for directory %s and it "
1419                                   "already exists.\n", fname ));
1420                         return NT_STATUS_OBJECT_NAME_COLLISION;
1421                 } else if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
1422                         /* Catch sharing violations. */
1423                         return NT_STATUS_SHARING_VIOLATION;
1424                 }
1425
1426                 return map_nt_error_from_unix(errno);
1427         }
1428
1429         if (info == FILE_WAS_CREATED) {
1430
1431                 /* Pulled from mkdir_internal() */
1432                 if (SMB_VFS_LSTAT(conn, fname, psbuf) == -1) {
1433                         DEBUG(2, ("Could not stat directory '%s' just "
1434                                   "created: %s\n",fname, strerror(errno)));
1435                         return map_nt_error_from_unix(errno);
1436                 }
1437
1438                 if (!S_ISDIR(psbuf->st_mode)) {
1439                         DEBUG(0, ("Directory just '%s' created is not a "
1440                                   "directory\n", fname));
1441                         return NT_STATUS_ACCESS_DENIED;
1442                 }
1443
1444                 if (!posix_open) {
1445                         /*
1446                          * Check if high bits should have been set, then (if
1447                          * bits are missing): add them.  Consider bits
1448                          * automagically set by UNIX, i.e. SGID bit from
1449                          * parent dir.
1450                          */
1451                         if (mode & ~(S_IRWXU|S_IRWXG|S_IRWXO) &&
1452                             (mode & ~psbuf->st_mode)) {
1453                                 SMB_VFS_CHMOD(conn, fname, (psbuf->st_mode |
1454                                                   (mode & ~psbuf->st_mode)));
1455                         }
1456                 }
1457
1458                 /* Change the owner if required. */
1459                 if (lp_inherit_owner(SNUM(conn))) {
1460                         change_dir_owner_to_parent(conn, parent_dir, fname,
1461                                                    psbuf);
1462                 }
1463
1464                 notify_fname(conn, NOTIFY_ACTION_ADDED,
1465                              FILE_NOTIFY_CHANGE_DIR_NAME, fname);
1466         }
1467
1468         /* Stat the fd for Samba bookkeeping. */
1469         if(SMB_VFS_FSTAT(fsp, psbuf) != 0) {
1470                 fd_close(fsp);
1471                 file_free(req, fsp);
1472                 return map_nt_error_from_unix(errno);
1473         }
1474
1475         /* Setup the files_struct for it. */
1476         fsp->mode = psbuf->st_mode;
1477         fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf);
1478         fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
1479         fsp->file_pid = req ? req->smbpid : 0;
1480         fsp->can_lock = False;
1481         fsp->can_read = False;
1482         fsp->can_write = False;
1483
1484         fsp->share_access = share_access;
1485         fsp->fh->private_options = create_options;
1486         /*
1487          * According to Samba4, SEC_FILE_READ_ATTRIBUTE is always granted,
1488          */
1489         fsp->access_mask = access_mask | FILE_READ_ATTRIBUTES;
1490         fsp->print_file = False;
1491         fsp->modified = False;
1492         fsp->oplock_type = NO_OPLOCK;
1493         fsp->sent_oplock_break = NO_BREAK_SENT;
1494         fsp->is_directory = True;
1495         fsp->posix_open = posix_open;
1496
1497         string_set(&fsp->fsp_name,fname);
1498
1499         mtimespec = get_mtimespec(psbuf);
1500
1501         /*
1502          * Still set the samba share mode lock for correct delete-on-close
1503          * semantics and to make smbstatus more useful.
1504          */
1505         lck = get_share_mode_lock(talloc_tos(), fsp->file_id,
1506                                   conn->connectpath,
1507                                   fname, &mtimespec);
1508
1509         if (lck == NULL) {
1510                 DEBUG(0, ("onefs_open_directory: Could not get share mode "
1511                           "lock for %s\n", fname));
1512                 fd_close(fsp);
1513                 file_free(req, fsp);
1514                 return NT_STATUS_SHARING_VIOLATION;
1515         }
1516
1517         if (lck->delete_on_close) {
1518                 TALLOC_FREE(lck);
1519                 fd_close(fsp);
1520                 file_free(req, fsp);
1521                 return NT_STATUS_DELETE_PENDING;
1522         }
1523
1524         set_share_mode(lck, fsp, conn->server_info->utok.uid, 0, NO_OPLOCK,
1525                        true);
1526
1527         /*
1528          * For directories the delete on close bit at open time seems
1529          * always to be honored on close... See test 19 in Samba4 BASE-DELETE.
1530          */
1531         if (create_options & FILE_DELETE_ON_CLOSE) {
1532                 status = can_set_delete_on_close(fsp, True, 0);
1533                 if (!NT_STATUS_IS_OK(status) &&
1534                     !NT_STATUS_EQUAL(status, NT_STATUS_DIRECTORY_NOT_EMPTY)) {
1535                         TALLOC_FREE(lck);
1536                         fd_close(fsp);
1537                         file_free(req, fsp);
1538                         return status;
1539                 }
1540
1541                 if (NT_STATUS_IS_OK(status)) {
1542                         /* Note that here we set the *inital* delete on close flag,
1543                            not the regular one. The magic gets handled in close. */
1544                         fsp->initial_delete_on_close = True;
1545                 }
1546         }
1547
1548         TALLOC_FREE(lck);
1549
1550         if (pinfo) {
1551                 *pinfo = info;
1552         }
1553
1554         *result = fsp;
1555         return NT_STATUS_OK;
1556 }
1557
1558 /*
1559  * If a main file is opened for delete, all streams need to be checked for
1560  * !FILE_SHARE_DELETE. Do this by opening with DELETE_ACCESS.
1561  * If that works, delete them all by setting the delete on close and close.
1562  */
1563
1564 static NTSTATUS open_streams_for_delete(connection_struct *conn,
1565                                         const char *fname)
1566 {
1567         struct stream_struct *stream_info;
1568         files_struct **streams;
1569         int i;
1570         unsigned int num_streams;
1571         TALLOC_CTX *frame = talloc_stackframe();
1572         NTSTATUS status;
1573
1574         status = SMB_VFS_STREAMINFO(conn, NULL, fname, talloc_tos(),
1575                                     &num_streams, &stream_info);
1576
1577         if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
1578             || NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
1579                 DEBUG(10, ("no streams around\n"));
1580                 TALLOC_FREE(frame);
1581                 return NT_STATUS_OK;
1582         }
1583
1584         if (!NT_STATUS_IS_OK(status)) {
1585                 DEBUG(10, ("SMB_VFS_STREAMINFO failed: %s\n",
1586                            nt_errstr(status)));
1587                 goto fail;
1588         }
1589
1590         DEBUG(10, ("open_streams_for_delete found %d streams\n",
1591                    num_streams));
1592
1593         if (num_streams == 0) {
1594                 TALLOC_FREE(frame);
1595                 return NT_STATUS_OK;
1596         }
1597
1598         streams = TALLOC_ARRAY(talloc_tos(), files_struct *, num_streams);
1599         if (streams == NULL) {
1600                 DEBUG(0, ("talloc failed\n"));
1601                 status = NT_STATUS_NO_MEMORY;
1602                 goto fail;
1603         }
1604
1605         for (i=0; i<num_streams; i++) {
1606                 char *streamname;
1607
1608                 if (strequal(stream_info[i].name, "::$DATA")) {
1609                         streams[i] = NULL;
1610                         continue;
1611                 }
1612
1613                 streamname = talloc_asprintf(talloc_tos(), "%s%s", fname,
1614                                              stream_info[i].name);
1615
1616                 if (streamname == NULL) {
1617                         DEBUG(0, ("talloc_aprintf failed\n"));
1618                         status = NT_STATUS_NO_MEMORY;
1619                         goto fail;
1620                 }
1621
1622                 status = onefs_create_file_unixpath
1623                         (conn,                  /* conn */
1624                          NULL,                  /* req */
1625                          streamname,            /* fname */
1626                          DELETE_ACCESS,         /* access_mask */
1627                          FILE_SHARE_READ | FILE_SHARE_WRITE
1628                          | FILE_SHARE_DELETE,   /* share_access */
1629                          FILE_OPEN,             /* create_disposition*/
1630                          NTCREATEX_OPTIONS_PRIVATE_STREAM_DELETE, /* create_options */
1631                          FILE_ATTRIBUTE_NORMAL, /* file_attributes */
1632                          0,                     /* oplock_request */
1633                          0,                     /* allocation_size */
1634                          NULL,                  /* sd */
1635                          NULL,                  /* ea_list */
1636                          &streams[i],           /* result */
1637                          NULL,                  /* pinfo */
1638                          NULL);                 /* psbuf */
1639
1640                 TALLOC_FREE(streamname);
1641
1642                 if (!NT_STATUS_IS_OK(status)) {
1643                         DEBUG(10, ("Could not open stream %s: %s\n",
1644                                    streamname, nt_errstr(status)));
1645                         break;
1646                 }
1647         }
1648
1649         /*
1650          * don't touch the variable "status" beyond this point :-)
1651          */
1652
1653         for (i -= 1 ; i >= 0; i--) {
1654                 if (streams[i] == NULL) {
1655                         continue;
1656                 }
1657
1658                 DEBUG(10, ("Closing stream # %d, %s\n", i,
1659                            streams[i]->fsp_name));
1660                 close_file(NULL, streams[i], NORMAL_CLOSE);
1661         }
1662
1663  fail:
1664         TALLOC_FREE(frame);
1665         return status;
1666 }
1667
1668 /*
1669  * Wrapper around onefs_open_file_ntcreate and onefs_open_directory.
1670  */
1671 static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
1672                                            struct smb_request *req,
1673                                            const char *fname,
1674                                            uint32_t access_mask,
1675                                            uint32_t share_access,
1676                                            uint32_t create_disposition,
1677                                            uint32_t create_options,
1678                                            uint32_t file_attributes,
1679                                            uint32_t oplock_request,
1680                                            uint64_t allocation_size,
1681                                            struct security_descriptor *sd,
1682                                            struct ea_list *ea_list,
1683                                            files_struct **result,
1684                                            int *pinfo,
1685                                            SMB_STRUCT_STAT *psbuf)
1686 {
1687         SMB_STRUCT_STAT sbuf;
1688         int info = FILE_WAS_OPENED;
1689         files_struct *base_fsp = NULL;
1690         files_struct *fsp = NULL;
1691         NTSTATUS status;
1692
1693         DEBUG(10,("onefs_create_file_unixpath: access_mask = 0x%x "
1694                   "file_attributes = 0x%x, share_access = 0x%x, "
1695                   "create_disposition = 0x%x create_options = 0x%x "
1696                   "oplock_request = 0x%x ea_list = 0x%p, sd = 0x%p, "
1697                   "fname = %s\n",
1698                   (unsigned int)access_mask,
1699                   (unsigned int)file_attributes,
1700                   (unsigned int)share_access,
1701                   (unsigned int)create_disposition,
1702                   (unsigned int)create_options,
1703                   (unsigned int)oplock_request,
1704                   ea_list, sd, fname));
1705
1706         if (create_options & FILE_OPEN_BY_FILE_ID) {
1707                 status = NT_STATUS_NOT_SUPPORTED;
1708                 goto fail;
1709         }
1710
1711         if (create_options & NTCREATEX_OPTIONS_INVALID_PARAM_MASK) {
1712                 status = NT_STATUS_INVALID_PARAMETER;
1713                 goto fail;
1714         }
1715
1716         if (req == NULL) {
1717                 oplock_request |= INTERNAL_OPEN_ONLY;
1718         }
1719
1720         if (psbuf != NULL) {
1721                 sbuf = *psbuf;
1722         }
1723         else {
1724                 if (SMB_VFS_STAT(conn, fname, &sbuf) == -1) {
1725                         SET_STAT_INVALID(sbuf);
1726                 }
1727         }
1728
1729         if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
1730             && (access_mask & DELETE_ACCESS)
1731             && !is_ntfs_stream_name(fname)) {
1732                 /*
1733                  * We can't open a file with DELETE access if any of the
1734                  * streams is open without FILE_SHARE_DELETE
1735                  */
1736                 status = open_streams_for_delete(conn, fname);
1737
1738                 if (!NT_STATUS_IS_OK(status)) {
1739                         goto fail;
1740                 }
1741         }
1742
1743         if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
1744             && is_ntfs_stream_name(fname)
1745             && (!(create_options & NTCREATEX_OPTIONS_PRIVATE_STREAM_DELETE))) {
1746                 char *base;
1747                 uint32 base_create_disposition;
1748
1749                 if (create_options & FILE_DIRECTORY_FILE) {
1750                         status = NT_STATUS_NOT_A_DIRECTORY;
1751                         goto fail;
1752                 }
1753
1754                 status = split_ntfs_stream_name(talloc_tos(), fname,
1755                                                 &base, NULL);
1756                 if (!NT_STATUS_IS_OK(status)) {
1757                         DEBUG(10, ("onefs_create_file_unixpath: "
1758                                   "split_ntfs_stream_name failed: %s\n",
1759                                   nt_errstr(status)));
1760                         goto fail;
1761                 }
1762
1763                 SMB_ASSERT(!is_ntfs_stream_name(base)); /* paranoia.. */
1764
1765                 switch (create_disposition) {
1766                 case FILE_OPEN:
1767                         base_create_disposition = FILE_OPEN;
1768                         break;
1769                 default:
1770                         base_create_disposition = FILE_OPEN_IF;
1771                         break;
1772                 }
1773
1774                 status = onefs_create_file_unixpath(
1775                         conn,                           /* conn */
1776                         NULL,                           /* req */
1777                         base,                           /* fname */
1778                         0,                              /* access_mask */
1779                         (FILE_SHARE_READ |
1780                             FILE_SHARE_WRITE |
1781                             FILE_SHARE_DELETE),         /* share_access */
1782                         base_create_disposition,        /* create_disposition*/
1783                         0,                              /* create_options */
1784                         0,                              /* file_attributes */
1785                         NO_OPLOCK,                      /* oplock_request */
1786                         0,                              /* allocation_size */
1787                         NULL,                           /* sd */
1788                         NULL,                           /* ea_list */
1789                         &base_fsp,                      /* result */
1790                         NULL,                           /* pinfo */
1791                         NULL);                          /* psbuf */
1792
1793                 if (!NT_STATUS_IS_OK(status)) {
1794                         DEBUG(10, ("onefs_create_file_unixpath for base %s "
1795                                   "failed: %s\n", base, nt_errstr(status)));
1796                         goto fail;
1797                 }
1798                 /*
1799                  * we don't need to low level fd: This might conflict with
1800                  * OneFS streams.
1801                  */
1802                 fd_close(base_fsp);
1803         }
1804
1805         /* Covert generic bits in the security descriptor. */
1806         if (sd != NULL) {
1807                 security_acl_map_generic(sd->dacl, &file_generic_mapping);
1808                 security_acl_map_generic(sd->sacl, &file_generic_mapping);
1809         }
1810
1811         /*
1812          * If it's a request for a directory open, deal with it separately.
1813          */
1814
1815         if (create_options & FILE_DIRECTORY_FILE) {
1816
1817                 if (create_options & FILE_NON_DIRECTORY_FILE) {
1818                         status = NT_STATUS_INVALID_PARAMETER;
1819                         goto fail;
1820                 }
1821
1822                 /* Can't open a temp directory. IFS kit test. */
1823                 if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
1824                      (file_attributes & FILE_ATTRIBUTE_TEMPORARY)) {
1825                         status = NT_STATUS_INVALID_PARAMETER;
1826                         goto fail;
1827                 }
1828
1829                 /*
1830                  * We will get a create directory here if the Win32
1831                  * app specified a security descriptor in the
1832                  * CreateDirectory() call.
1833                  */
1834
1835                 status = onefs_open_directory(
1836                         conn,                           /* conn */
1837                         req,                            /* req */
1838                         fname,                          /* fname */
1839                         access_mask,                    /* access_mask */
1840                         share_access,                   /* share_access */
1841                         create_disposition,             /* create_disposition*/
1842                         create_options,                 /* create_options */
1843                         file_attributes,                /* file_attributes */
1844                         sd,                             /* sd */
1845                         &fsp,                           /* result */
1846                         &info,                          /* pinfo */
1847                         &sbuf);                         /* psbuf */
1848         } else {
1849
1850                 /*
1851                  * Ordinary file case.
1852                  */
1853
1854                 status = file_new(req, conn, &fsp);
1855                 if(!NT_STATUS_IS_OK(status)) {
1856                         goto fail;
1857                 }
1858
1859                 /*
1860                  * We're opening the stream element of a base_fsp
1861                  * we already opened. Set up the base_fsp pointer.
1862                  */
1863                 if (base_fsp) {
1864                         fsp->base_fsp = base_fsp;
1865                 }
1866
1867                 status = onefs_open_file_ntcreate(
1868                         conn,                           /* conn */
1869                         req,                            /* req */
1870                         fname,                          /* fname */
1871                         access_mask,                    /* access_mask */
1872                         share_access,                   /* share_access */
1873                         create_disposition,             /* create_disposition*/
1874                         create_options,                 /* create_options */
1875                         file_attributes,                /* file_attributes */
1876                         oplock_request,                 /* oplock_request */
1877                         sd,                             /* sd */
1878                         fsp,                            /* result */
1879                         &info,                          /* pinfo */
1880                         &sbuf);                         /* psbuf */
1881
1882                 if(!NT_STATUS_IS_OK(status)) {
1883                         file_free(req, fsp);
1884                         fsp = NULL;
1885                 }
1886
1887                 if (NT_STATUS_EQUAL(status, NT_STATUS_FILE_IS_A_DIRECTORY)) {
1888
1889                         /* A stream open never opens a directory */
1890
1891                         if (base_fsp) {
1892                                 status = NT_STATUS_FILE_IS_A_DIRECTORY;
1893                                 goto fail;
1894                         }
1895
1896                         /*
1897                          * Fail the open if it was explicitly a non-directory
1898                          * file.
1899                          */
1900
1901                         if (create_options & FILE_NON_DIRECTORY_FILE) {
1902                                 status = NT_STATUS_FILE_IS_A_DIRECTORY;
1903                                 goto fail;
1904                         }
1905
1906                         create_options |= FILE_DIRECTORY_FILE;
1907
1908                         status = onefs_open_directory(
1909                                 conn,                   /* conn */
1910                                 req,                    /* req */
1911                                 fname,                  /* fname */
1912                                 access_mask,            /* access_mask */
1913                                 share_access,           /* share_access */
1914                                 create_disposition,     /* create_disposition*/
1915                                 create_options,         /* create_options */
1916                                 file_attributes,        /* file_attributes */
1917                                 sd,                     /* sd */
1918                                 &fsp,                   /* result */
1919                                 &info,                  /* pinfo */
1920                                 &sbuf);                 /* psbuf */
1921                 }
1922         }
1923
1924         if (!NT_STATUS_IS_OK(status)) {
1925                 goto fail;
1926         }
1927
1928         fsp->base_fsp = base_fsp;
1929
1930         SMB_ASSERT(fsp);
1931
1932         if ((ea_list != NULL) && (info == FILE_WAS_CREATED)) {
1933                 status = set_ea(conn, fsp, fname, ea_list);
1934                 if (!NT_STATUS_IS_OK(status)) {
1935                         goto fail;
1936                 }
1937         }
1938
1939         if (!fsp->is_directory && S_ISDIR(sbuf.st_mode)) {
1940                 status = NT_STATUS_ACCESS_DENIED;
1941                 goto fail;
1942         }
1943
1944         /* Save the requested allocation size. */
1945         if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
1946                 if (allocation_size
1947                     && (allocation_size > sbuf.st_size)) {
1948                         fsp->initial_allocation_size = smb_roundup(
1949                                 fsp->conn, allocation_size);
1950                         if (fsp->is_directory) {
1951                                 /* Can't set allocation size on a directory. */
1952                                 status = NT_STATUS_ACCESS_DENIED;
1953                                 goto fail;
1954                         }
1955                         if (vfs_allocate_file_space(
1956                                     fsp, fsp->initial_allocation_size) == -1) {
1957                                 status = NT_STATUS_DISK_FULL;
1958                                 goto fail;
1959                         }
1960                 } else {
1961                         fsp->initial_allocation_size = smb_roundup(
1962                                 fsp->conn, (uint64_t)sbuf.st_size);
1963                 }
1964         }
1965
1966         DEBUG(10, ("onefs_create_file_unixpath: info=%d\n", info));
1967
1968         *result = fsp;
1969         if (pinfo != NULL) {
1970                 *pinfo = info;
1971         }
1972         if (psbuf != NULL) {
1973                 if ((fsp->fh == NULL) || (fsp->fh->fd == -1)) {
1974                         *psbuf = sbuf;
1975                 }
1976                 else {
1977                         SMB_VFS_FSTAT(fsp, psbuf);
1978                 }
1979         }
1980         return NT_STATUS_OK;
1981
1982  fail:
1983         DEBUG(10, ("onefs_create_file_unixpath: %s\n", nt_errstr(status)));
1984
1985         if (fsp != NULL) {
1986                 if (base_fsp && fsp->base_fsp == base_fsp) {
1987                         /*
1988                          * The close_file below will close
1989                          * fsp->base_fsp.
1990                          */
1991                         base_fsp = NULL;
1992                 }
1993                 close_file(req, fsp, ERROR_CLOSE);
1994                 fsp = NULL;
1995         }
1996         if (base_fsp != NULL) {
1997                 close_file(req, base_fsp, ERROR_CLOSE);
1998                 base_fsp = NULL;
1999         }
2000         return status;
2001 }
2002
2003 /**
2004  * SMB_VFS_CREATE_FILE interface to onefs.
2005  */
2006 NTSTATUS onefs_create_file(vfs_handle_struct *handle,
2007                            struct smb_request *req,
2008                            uint16_t root_dir_fid,
2009                            const char *fname,
2010                            uint32_t create_file_flags,
2011                            uint32_t access_mask,
2012                            uint32_t share_access,
2013                            uint32_t create_disposition,
2014                            uint32_t create_options,
2015                            uint32_t file_attributes,
2016                            uint32_t oplock_request,
2017                            uint64_t allocation_size,
2018                            struct security_descriptor *sd,
2019                            struct ea_list *ea_list,
2020                            files_struct **result,
2021                            int *pinfo,
2022                            SMB_STRUCT_STAT *psbuf)
2023 {
2024         connection_struct *conn = handle->conn;
2025         struct case_semantics_state *case_state = NULL;
2026         SMB_STRUCT_STAT sbuf;
2027         int info = FILE_WAS_OPENED;
2028         files_struct *fsp = NULL;
2029         NTSTATUS status;
2030
2031         DEBUG(10,("onefs_create_file: access_mask = 0x%x "
2032                   "file_attributes = 0x%x, share_access = 0x%x, "
2033                   "create_disposition = 0x%x create_options = 0x%x "
2034                   "oplock_request = 0x%x "
2035                   "root_dir_fid = 0x%x, ea_list = 0x%p, sd = 0x%p, "
2036                   "create_file_flags = 0x%x, fname = %s\n",
2037                   (unsigned int)access_mask,
2038                   (unsigned int)file_attributes,
2039                   (unsigned int)share_access,
2040                   (unsigned int)create_disposition,
2041                   (unsigned int)create_options,
2042                   (unsigned int)oplock_request,
2043                   (unsigned int)root_dir_fid,
2044                   ea_list, sd, create_file_flags, fname));
2045
2046         /* Get the file name if root_dir_fid was specified. */
2047         if (root_dir_fid != 0) {
2048                 char *new_fname;
2049
2050                 status = get_relative_fid_filename(conn, req, root_dir_fid,
2051                                                    fname, &new_fname);
2052                 if (!NT_STATUS_IS_OK(status)) {
2053                         goto fail;
2054                 }
2055
2056                 fname = new_fname;
2057         }
2058
2059         /* Resolve the file name if this was a DFS pathname. */
2060         if ((req != NULL) && (req->flags2 & FLAGS2_DFS_PATHNAMES)) {
2061                 char *resolved_fname;
2062
2063                 status = resolve_dfspath(talloc_tos(), conn, true, fname,
2064                                          &resolved_fname);
2065
2066                 if (!NT_STATUS_IS_OK(status)) {
2067                         /*
2068                          * For PATH_NOT_COVERED we had
2069                          * reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
2070                          *                 ERRSRV, ERRbadpath);
2071                          * Need to fix in callers
2072                          */
2073                         goto fail;
2074                 }
2075                 fname = resolved_fname;
2076         }
2077
2078         /* Check if POSIX semantics are wanted. */
2079         if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
2080                 case_state = set_posix_case_semantics(talloc_tos(), conn);
2081         }
2082
2083         /* Convert dos path to unix path if it hasn't already been done. */
2084         if (create_file_flags & CFF_DOS_PATH) {
2085                 char *converted_fname;
2086
2087                 SET_STAT_INVALID(sbuf);
2088
2089                 status = unix_convert(talloc_tos(), conn, fname, False,
2090                                       &converted_fname, NULL, &sbuf);
2091                 if (!NT_STATUS_IS_OK(status)) {
2092                         goto fail;
2093                 }
2094                 fname = converted_fname;
2095         } else {
2096                 if (psbuf != NULL) {
2097                         sbuf = *psbuf;
2098                 } else {
2099                         if (SMB_VFS_STAT(conn, fname, &sbuf) == -1) {
2100                                 SET_STAT_INVALID(sbuf);
2101                         }
2102                 }
2103
2104         }
2105
2106         TALLOC_FREE(case_state);
2107
2108         /* All file access must go through check_name() */
2109         status = check_name(conn, fname);
2110         if (!NT_STATUS_IS_OK(status)) {
2111                 goto fail;
2112         }
2113
2114         status = onefs_create_file_unixpath(
2115                 conn,                                   /* conn */
2116                 req,                                    /* req */
2117                 fname,                                  /* fname */
2118                 access_mask,                            /* access_mask */
2119                 share_access,                           /* share_access */
2120                 create_disposition,                     /* create_disposition*/
2121                 create_options,                         /* create_options */
2122                 file_attributes,                        /* file_attributes */
2123                 oplock_request,                         /* oplock_request */
2124                 allocation_size,                        /* allocation_size */
2125                 sd,                                     /* sd */
2126                 ea_list,                                /* ea_list */
2127                 &fsp,                                   /* result */
2128                 &info,                                  /* pinfo */
2129                 &sbuf);                                 /* psbuf */
2130
2131         if (!NT_STATUS_IS_OK(status)) {
2132                 goto fail;
2133         }
2134
2135         DEBUG(10, ("onefs_create_file: info=%d\n", info));
2136
2137         *result = fsp;
2138         if (pinfo != NULL) {
2139                 *pinfo = info;
2140         }
2141         if (psbuf != NULL) {
2142                 *psbuf = sbuf;
2143         }
2144         return NT_STATUS_OK;
2145
2146  fail:
2147         DEBUG(10, ("onefs_create_file: %s\n", nt_errstr(status)));
2148
2149         if (fsp != NULL) {
2150                 close_file(req, fsp, ERROR_CLOSE);
2151                 fsp = NULL;
2152         }
2153         return status;
2154 }