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