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