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