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