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