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