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