root/source3/modules/onefs_open.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. onefs_open_file
  2. defer_open
  3. schedule_defer_open
  4. onefs_open_file_ntcreate
  5. onefs_open_directory
  6. onefs_create_file_unixpath
  7. destroy_onefs_fsp_data
  8. onefs_create_file

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

/* [<][>][^][v][top][bottom][index][help] */