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