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