s3 onefs: Plumb smb_filename through onefs createfile path
[ira/wip.git] / source3 / modules / onefs_open.c
index e335dc7e281ee32b4b1cb4934e150b6f407b3537..5aade2c56289e009497be5588276a99c5171171f 100644 (file)
  * along with this program; if not, see <http://www.gnu.org/licenses/>.
  */
 
+#include "includes.h"
 #include "onefs.h"
+#include "onefs_config.h"
+#include "oplock_onefs.h"
 #include "smbd/globals.h"
 
 extern const struct generic_mapping file_generic_mapping;
@@ -43,7 +46,7 @@ struct onefs_fsp_data {
 
 static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
                              struct smb_request *req,
-                             const char *fname,
+                             struct smb_filename *smb_fname,
                              uint32_t access_mask,
                              uint32_t share_access,
                              uint32_t create_disposition,
@@ -55,8 +58,7 @@ static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
                              struct ea_list *ea_list,
                              files_struct **result,
                              int *pinfo,
-                             struct onefs_fsp_data *fsp_data,
-                             SMB_STRUCT_STAT *psbuf);
+                             struct onefs_fsp_data *fsp_data);
 
 /****************************************************************************
  Open a file.
@@ -66,9 +68,7 @@ static NTSTATUS onefs_open_file(files_struct *fsp,
                                connection_struct *conn,
                                struct smb_request *req,
                                const char *parent_dir,
-                               const char *name,
-                               const char *path,
-                               SMB_STRUCT_STAT *psbuf,
+                               struct smb_filename *smb_fname,
                                int flags,
                                mode_t unx_mode,
                                uint32 access_mask,
@@ -81,18 +81,24 @@ static NTSTATUS onefs_open_file(files_struct *fsp,
                                struct security_descriptor *sd,
                                int *granted_oplock)
 {
+       char *path = NULL;
+       struct smb_filename *smb_fname_onefs = NULL;
        NTSTATUS status = NT_STATUS_OK;
        int accmode = (flags & O_ACCMODE);
        int local_flags = flags;
-       bool file_existed = VALID_STAT(*psbuf);
+       bool file_existed = VALID_STAT(smb_fname->st);
        const char *wild;
-       char *base = NULL;
-       char *stream = NULL;
        int base_fd = -1;
 
        fsp->fh->fd = -1;
        errno = EPERM;
 
+       status = get_full_smb_filename(talloc_tos(), smb_fname,
+                                      &path);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
        /* Check permissions */
 
        /*
@@ -108,7 +114,8 @@ static NTSTATUS onefs_open_file(files_struct *fsp,
        if (!CAN_WRITE(conn)) {
                /* It's a read-only share - fail if we wanted to write. */
                if(accmode != O_RDONLY) {
-                       DEBUG(3,("Permission denied opening %s\n", path));
+                       DEBUG(3, ("Permission denied opening %s\n",
+                                 smb_fname_str_dbg(smb_fname)));
                        return NT_STATUS_ACCESS_DENIED;
                } else if(flags & O_CREAT) {
                        /* We don't want to write - but we must make sure that
@@ -134,7 +141,7 @@ static NTSTATUS onefs_open_file(files_struct *fsp,
 
        if ((accmode == O_RDONLY) && ((flags & O_TRUNC) == O_TRUNC)) {
                DEBUG(10,("onefs_open_file: truncate requested on read-only "
-                         "open for file %s\n", path));
+                         "open for file %s\n", smb_fname_str_dbg(smb_fname)));
                local_flags = (flags & ~O_ACCMODE)|O_RDWR;
        }
 
@@ -145,7 +152,7 @@ static NTSTATUS onefs_open_file(files_struct *fsp,
         * open flags. JRA.
         */
 
-       if (file_existed && S_ISFIFO(psbuf->st_mode)) {
+       if (file_existed && S_ISFIFO(smb_fname->st.st_ex_mode)) {
                local_flags |= O_NONBLOCK;
        }
 #endif
@@ -171,7 +178,7 @@ static NTSTATUS onefs_open_file(files_struct *fsp,
                 * then was copied via Samba.
                 */
                DEBUG(1, ("onefs_open_file: creating file with wildcard: %s\n",
-                         path));
+                         smb_fname_str_dbg(smb_fname)));
                return NT_STATUS_OBJECT_NAME_INVALID;
        }
 
@@ -187,41 +194,30 @@ static NTSTATUS onefs_open_file(files_struct *fsp,
                flags |= O_NOFOLLOW;
        }
 #endif
-       /* Stream handling */
-       if (is_ntfs_stream_name(path)) {
-               status = onefs_split_ntfs_stream_name(talloc_tos(), path,
-                                                     &base, &stream);
+       /* Setup a onefs-style smb_fname struct. */
+       status = onefs_stream_prep_smb_fname(talloc_tos(), smb_fname,
+                                            &smb_fname_onefs);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
        }
-       /* It's a stream, so pass in the base_fd */
-       if (stream != NULL) {
-               SMB_ASSERT(fsp->base_fsp);
 
-               /*
-                * We have never seen an oplock taken on a stream, and our
-                * current implementation doesn't support it.  If a request is
-                * seen, log a loud error message and ignore the requested
-                * oplock.
-                */
-               if ((oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK) !=
-                    NO_OPLOCK) {
-                       DEBUG(0,("Oplock(%d) being requested on a stream! "
-                               "Ignoring oplock request: base=%s, stream=%s",
-                               oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK,
-                               base, stream));
-                       /* Recover by requesting NO_OPLOCK instead. */
-                       oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
-               }
+       /* If it's a stream pass in the base_fd */
+       if ((conn->fs_capabilities & FILE_NAMED_STREAMS) &&
+           is_ntfs_stream_smb_fname(smb_fname_onefs)) {
+               SMB_ASSERT(fsp->base_fsp);
 
-               DEBUG(10,("Opening a stream: base=%s(%d), stream=%s",
-                         base, fsp->base_fsp->fh->fd, stream));
+               DEBUG(10, ("Opening a stream: base=%s(%d), stream=%s\n",
+                          smb_fname_onefs->base_name, fsp->base_fsp->fh->fd,
+                          smb_fname_onefs->stream_name));
 
                base_fd = fsp->base_fsp->fh->fd;
        }
 
        fsp->fh->fd = onefs_sys_create_file(conn,
                                            base_fd,
-                                           stream != NULL ? stream :
-                                           (base != NULL ? base : path),
+                                           smb_fname_onefs->stream_name != NULL ?
+                                           smb_fname_onefs->stream_name :
+                                           smb_fname_onefs->base_name,
                                            access_mask,
                                            open_access_mask,
                                            share_access,
@@ -233,6 +229,7 @@ static NTSTATUS onefs_open_file(files_struct *fsp,
                                            sd,
                                            new_dos_attributes,
                                            granted_oplock);
+       TALLOC_FREE(smb_fname_onefs);
 
        if (fsp->fh->fd == -1) {
                if (errno == EMFILE) {
@@ -250,9 +247,9 @@ static NTSTATUS onefs_open_file(files_struct *fsp,
                }
 
                status = map_nt_error_from_unix(errno);
-               DEBUG(3,("Error opening file %s (%s) (local_flags=%d) "
-                       "(flags=%d)\n",
-                       path, strerror(errno), local_flags, flags));
+               DEBUG(3, ("Error opening file %s (%s) (local_flags=%d) "
+                         "(flags=%d)\n", smb_fname_str_dbg(smb_fname),
+                         strerror(errno), local_flags, flags));
                return status;
        }
 
@@ -278,13 +275,15 @@ static NTSTATUS onefs_open_file(files_struct *fsp,
                int ret;
 
                if (fsp->fh->fd == -1) {
-                       ret = SMB_VFS_STAT(conn, path, psbuf);
+                       ret = SMB_VFS_STAT(conn, smb_fname);
                } else {
-                       ret = SMB_VFS_FSTAT(fsp, psbuf);
+                       ret = SMB_VFS_FSTAT(fsp, &smb_fname->st);
                        /* If we have an fd, this stat should succeed. */
                        if (ret == -1) {
-                               DEBUG(0,("Error doing fstat on open file %s "
-                                        "(%s)\n", path,strerror(errno) ));
+                               DEBUG(0, ("Error doing fstat on open file %s "
+                                         "(%s)\n",
+                                         smb_fname_str_dbg(smb_fname),
+                                         strerror(errno) ));
                        }
                }
 
@@ -302,14 +301,14 @@ static NTSTATUS onefs_open_file(files_struct *fsp,
         * so catch a directory open and return an EISDIR. JRA.
         */
 
-       if(S_ISDIR(psbuf->st_mode)) {
+       if(S_ISDIR(smb_fname->st.st_ex_mode)) {
                fd_close(fsp);
                errno = EISDIR;
                return NT_STATUS_FILE_IS_A_DIRECTORY;
        }
 
-       fsp->mode = psbuf->st_mode;
-       fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf);
+       fsp->mode = smb_fname->st.st_ex_mode;
+       fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
        fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
        fsp->file_pid = req ? req->smbpid : 0;
        fsp->can_lock = True;
@@ -383,15 +382,6 @@ static void defer_open(struct share_mode_lock *lck,
                exit_server("push_deferred_smb_message failed");
        }
        add_deferred_open(lck, req->mid, request_time, state->id);
-
-       /*
-        * Push the MID of this packet on the signing queue.
-        * We only do this once, the first time we push the packet
-        * onto the deferred open queue, as this has a side effect
-        * of incrementing the response sequence number.
-        */
-
-       srv_defer_sign_response(req->mid);
 }
 
 static void schedule_defer_open(struct share_mode_lock *lck,
@@ -441,7 +431,7 @@ static void schedule_defer_open(struct share_mode_lock *lck,
 ****************************************************************************/
 NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
                                  struct smb_request *req,
-                                 const char *fname,
+                                 struct smb_filename *smb_fname,
                                  uint32 access_mask,
                                  uint32 share_access,
                                  uint32 create_disposition,
@@ -451,12 +441,11 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
                                  struct security_descriptor *sd,
                                  files_struct *fsp,
                                  int *pinfo,
-                                 struct onefs_fsp_data *fsp_data,
-                                 SMB_STRUCT_STAT *psbuf)
+                                 struct onefs_fsp_data *fsp_data)
 {
        int flags=0;
        int flags2=0;
-       bool file_existed = VALID_STAT(*psbuf);
+       bool file_existed = VALID_STAT(smb_fname->st);
        bool def_acl = False;
        bool posix_open = False;
        bool new_file_created = False;
@@ -473,13 +462,19 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
        NTSTATUS status;
        int ret_flock;
        char *parent_dir;
-       const char *newname;
        int granted_oplock;
        uint64_t oplock_callback_id = 0;
        uint32 createfile_attributes = 0;
+       char *fname = NULL;
 
        ZERO_STRUCT(id);
 
+       status = get_full_smb_filename(talloc_tos(), smb_fname,
+                                      &fname);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
        if (conn->printer) {
                /*
                 * Printers are handled completely differently.
@@ -491,12 +486,14 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
                }
 
                DEBUG(10, ("onefs_open_file_ntcreate: printer open fname=%s\n",
-                         fname));
+                          smb_fname_str_dbg(smb_fname)));
 
-               return print_fsp_open(req, conn, fname, req->vuid, fsp, psbuf);
+               return print_fsp_open(req, conn, fname, req->vuid, fsp,
+                                     &smb_fname->st);
        }
 
-       if (!parent_dirname(talloc_tos(), fname, &parent_dir, &newname)) {
+       if (!parent_dirname(talloc_tos(), smb_fname->base_name, &parent_dir,
+                           NULL)) {
                return NT_STATUS_NO_MEMORY;
        }
 
@@ -515,9 +512,9 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
                  "access_mask=0x%x share_access=0x%x "
                  "create_disposition = 0x%x create_options=0x%x "
                  "unix mode=0%o oplock_request=0x%x\n",
-                 fname, new_dos_attributes, access_mask, share_access,
-                 create_disposition, create_options, unx_mode,
-                 oplock_request));
+                 smb_fname_str_dbg(smb_fname), new_dos_attributes,
+                 access_mask, share_access, create_disposition,
+                 create_options, unx_mode, oplock_request));
 
        /*
         * Any non-stat-only open has the potential to contend oplocks, which
@@ -527,10 +524,7 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
         *
         *   1. Open the base file of a stream: Always done stat-only
         *
-        *   2. Open the stream: Oplocks are disallowed on streams, so an
-        *      oplock will never be contended.
-        *
-        *   3. open_file_fchmod(), which is called from 3 places:
+        *   2. open_file_fchmod(), which is called from 3 places:
         *      A. try_chown: Posix acls only. Never called on onefs.
         *      B. set_ea_dos_attributes: Can't be called from onefs, because
         *         SMB_VFS_SETXATTR return ENOSYS.
@@ -539,7 +533,8 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
         *         it off, but if a customer were to turn it on it would be
         *         bad.
         */
-       if (req == NULL && !is_stat_open(access_mask) && !is_ntfs_stream_name(fname)) {
+       if (req == NULL && !is_stat_open(access_mask) &&
+           !is_ntfs_stream_smb_fname(smb_fname)) {
                smb_panic("NULL req on a non-stat-open!");
        }
 
@@ -588,7 +583,7 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
                }
        }
 
-       status = check_name(conn, fname);
+       status = check_name(conn, smb_fname->base_name);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
@@ -596,7 +591,8 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
        if (!posix_open) {
                new_dos_attributes &= SAMBA_ATTRIBUTES_MASK;
                if (file_existed) {
-                       existing_dos_attributes = dos_mode(conn, fname, psbuf);
+                       existing_dos_attributes = dos_mode(conn, fname,
+                                                          &smb_fname->st);
                }
        }
 
@@ -608,13 +604,13 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
 
        /* Ignore oplock requests if oplocks are disabled. */
        if (!lp_oplocks(SNUM(conn)) || global_client_failed_oplock_break ||
-           IS_VETO_OPLOCK_PATH(conn, fname)) {
+           IS_VETO_OPLOCK_PATH(conn, smb_fname->base_name)) {
                /* Mask off everything except the private Samba bits. */
                oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
        }
 
        /* this is for OS/2 long file names - say we don't support them */
-       if (!lp_posix_pathnames() && strstr(fname,".+,;=[].")) {
+       if (!lp_posix_pathnames() && strstr(smb_fname->base_name,".+,;=[].")) {
                /* OS/2 Workplace shell fix may be main code stream in a later
                 * release. */
                DEBUG(5,("onefs_open_file_ntcreate: OS/2 long filenames are "
@@ -657,7 +653,8 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
                        if (!file_existed) {
                                DEBUG(5,("onefs_open_file_ntcreate: FILE_OPEN "
                                         "requested for file %s and file "
-                                        "doesn't exist.\n", fname ));
+                                        "doesn't exist.\n",
+                                        smb_fname_str_dbg(smb_fname)));
                                errno = ENOENT;
                                return NT_STATUS_OBJECT_NAME_NOT_FOUND;
                        }
@@ -670,7 +667,7 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
                                DEBUG(5, ("onefs_open_file_ntcreate: "
                                          "FILE_OVERWRITE requested for file "
                                          "%s and file doesn't exist.\n",
-                                         fname));
+                                         smb_fname_str_dbg(smb_fname)));
                                errno = ENOENT;
                                return NT_STATUS_OBJECT_NAME_NOT_FOUND;
                        }
@@ -685,8 +682,8 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
                                DEBUG(5, ("onefs_open_file_ntcreate: "
                                          "FILE_CREATE requested for file %s "
                                          "and file already exists.\n",
-                                         fname));
-                               if (S_ISDIR(psbuf->st_mode)) {
+                                         smb_fname_str_dbg(smb_fname)));
+                               if (S_ISDIR(smb_fname->st.st_ex_mode)) {
                                        errno = EISDIR;
                                } else {
                                        errno = EEXIST;
@@ -710,15 +707,16 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
        if (!posix_open && file_existed &&
            ((create_disposition == FILE_OVERWRITE) ||
                (create_disposition == FILE_OVERWRITE_IF))) {
-               if (!open_match_attributes(conn, fname,
-                                          existing_dos_attributes,
-                                          new_dos_attributes, psbuf->st_mode,
+               if (!open_match_attributes(conn, existing_dos_attributes,
+                                          new_dos_attributes,
+                                          smb_fname->st.st_ex_mode,
                                           unx_mode, &new_unx_mode)) {
                        DEBUG(5, ("onefs_open_file_ntcreate: attributes "
                                  "missmatch for file %s (%x %x) (0%o, 0%o)\n",
-                                 fname, existing_dos_attributes,
+                                 smb_fname_str_dbg(smb_fname),
+                                 existing_dos_attributes,
                                  new_dos_attributes,
-                                 (unsigned int)psbuf->st_mode,
+                                 (unsigned int)smb_fname->st.st_ex_mode,
                                  (unsigned int)unx_mode ));
                        errno = EACCES;
                        return NT_STATUS_ACCESS_DENIED;
@@ -744,14 +742,10 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
                open_access_mask |= FILE_WRITE_DATA;
        }
 
-       if (lp_parm_bool(SNUM(fsp->conn), PARM_ONEFS_TYPE,
-               PARM_IGNORE_SACL, PARM_IGNORE_SACL_DEFAULT)) {
-               access_mask &= ~SYSTEM_SECURITY_ACCESS;
-       }
-
        DEBUG(10, ("onefs_open_file_ntcreate: fname=%s, after mapping "
                   "open_access_mask=%#x, access_mask=0x%x\n",
-                  fname, open_access_mask, access_mask));
+                  smb_fname_str_dbg(smb_fname), open_access_mask,
+                  access_mask));
 
        /*
         * Note that we ignore the append flag as append does not
@@ -823,14 +817,15 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
            (!CAN_WRITE(conn) || IS_DOS_READONLY(existing_dos_attributes))) {
                DEBUG(5, ("onefs_open_file_ntcreate: write access requested "
                          "for file %s on read only %s\n",
-                         fname, !CAN_WRITE(conn) ? "share" : "file" ));
+                         smb_fname_str_dbg(smb_fname),
+                         !CAN_WRITE(conn) ? "share" : "file" ));
                errno = EACCES;
                return NT_STATUS_ACCESS_DENIED;
        }
 
        DEBUG(10, ("fsp = %p\n", fsp));
 
-       fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf);
+       fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
        fsp->share_access = share_access;
        fsp->fh->private_options = create_options;
        fsp->access_mask = open_access_mask; /* We change this to the
@@ -846,8 +841,8 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
        }
 
        if (file_existed) {
-               struct timespec old_write_time = get_mtimespec(psbuf);
-               id = vfs_file_id_from_sbuf(conn, psbuf);
+               struct timespec old_write_time = smb_fname->st.st_ex_mtime;
+               id = vfs_file_id_from_sbuf(conn, &smb_fname->st);
 
                lck = get_share_mode_lock(talloc_tos(), id,
                                          conn->connectpath,
@@ -905,9 +900,7 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
                                 conn,
                                 req,
                                 parent_dir,
-                                newname,
-                                fname,
-                                psbuf,
+                                smb_fname,
                                 flags|flags2,
                                 unx_mode,
                                 access_mask,
@@ -930,18 +923,19 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
                                struct deferred_open_record state;
                                struct timespec old_write_time;
 
-                               old_write_time = get_mtimespec(psbuf);
+                               old_write_time = smb_fname->st.st_ex_mtime;
 
                                DEBUG(3, ("Someone created file %s with an "
                                          "oplock after we looked: Retrying\n",
-                                         fname));
+                                         smb_fname_str_dbg(smb_fname)));
                                /*
                                 * We hit the race that when we did the stat
                                 * on the file it did not exist, and someone
                                 * has created it in between the stat and the
                                 * open_file() call. Just retry immediately.
                                 */
-                               id = vfs_file_id_from_sbuf(conn, psbuf);
+                               id = vfs_file_id_from_sbuf(conn,
+                                                          &smb_fname->st);
                                if (!(lck = get_share_mode_lock(talloc_tos(),
                                          id, conn->connectpath, fname,
                                          &old_write_time))) {
@@ -950,7 +944,8 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
                                         */
                                        DEBUG(0, ("onefs_open_file_ntcreate: "
                                                  "Could not get share mode "
-                                                 "lock for %s\n", fname));
+                                                 "lock for %s\n",
+                                               smb_fname_str_dbg(smb_fname)));
                                        status = NT_STATUS_SHARING_VIOLATION;
                                        goto cleanup_destroy;
                                }
@@ -966,7 +961,8 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
                        }
                        /* Waiting for an oplock */
                        DEBUG(5,("Async createfile because a client has an "
-                                "oplock on %s\n", fname));
+                                "oplock on %s\n",
+                                smb_fname_str_dbg(smb_fname)));
 
                        SMB_ASSERT(req);
                        schedule_defer_open(lck, request_time, req);
@@ -1007,7 +1003,6 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
                                                        create_options);
 
                                if (NT_STATUS_IS_OK(status)) {
-                                       TALLOC_FREE(lck);
                                        if (pinfo) {
                                                *pinfo = FILE_WAS_OPENED;
                                        }
@@ -1034,8 +1029,10 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
                                can_access_mask = FILE_READ_DATA;
                        }
 
-                       if (((can_access_mask & FILE_WRITE_DATA) && !CAN_WRITE(conn)) ||
-                           !can_access_file_data(conn,fname,psbuf,can_access_mask)) {
+                       if (((can_access_mask & FILE_WRITE_DATA) &&
+                               !CAN_WRITE(conn)) ||
+                           !can_access_file_data(conn, smb_fname,
+                                                 can_access_mask)) {
                                can_access = False;
                        }
 
@@ -1120,7 +1117,7 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
        }
 
        if (!file_existed) {
-               struct timespec old_write_time = get_mtimespec(psbuf);
+               struct timespec old_write_time = smb_fname->st.st_ex_mtime;
                /*
                 * Deal with the race condition where two smbd's detect the
                 * file doesn't exist and do the create at the same time. One
@@ -1144,7 +1141,8 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
 
                if (lck == NULL) {
                        DEBUG(0, ("onefs_open_file_ntcreate: Could not get "
-                                 "share mode lock for %s\n", fname));
+                                 "share mode lock for %s\n",
+                                 smb_fname_str_dbg(smb_fname)));
                        fd_close(fsp);
                        return NT_STATUS_SHARING_VIOLATION;
                }
@@ -1185,8 +1183,9 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
        SMB_ASSERT(lck != NULL);
 
        /* Delete streams if create_disposition requires it */
-       if (file_existed && clear_ads) {
-               status = delete_all_streams(conn, fname);
+       if (file_existed && clear_ads &&
+           !is_ntfs_stream_smb_fname(smb_fname)) {
+               status = delete_all_streams(conn, smb_fname->base_name);
                if (!NT_STATUS_IS_OK(status)) {
                        TALLOC_FREE(lck);
                        fd_close(fsp);
@@ -1297,8 +1296,9 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
         * selected.
         * May be necessary depending on acl policies.
         */
-       if (!posix_open && !file_existed && !def_acl && !(VALID_STAT(*psbuf)
-                 && (psbuf->st_flags & SF_HASNTFSACL))) {
+       if (!posix_open && !file_existed && !def_acl &&
+           !(VALID_STAT(smb_fname->st) &&
+               (smb_fname->st.st_ex_flags & SF_HASNTFSACL))) {
 
                int saved_errno = errno; /* We might get ENOSYS in the next
                                          * call.. */
@@ -1324,7 +1324,8 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
                        } else {
                                DEBUG(5, ("onefs_open_file_ntcreate: reset "
                                          "attributes of file %s to 0%o\n",
-                                         fname, (unsigned int)new_unx_mode));
+                                         smb_fname_str_dbg(smb_fname),
+                                         (unsigned int)new_unx_mode));
                                ret = 0; /* Don't do the fchmod below. */
                        }
                }
@@ -1333,7 +1334,8 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
                    (SMB_VFS_FCHMOD(fsp, new_unx_mode) == -1))
                        DEBUG(5, ("onefs_open_file_ntcreate: failed to reset "
                                  "attributes of file %s to 0%o\n",
-                                 fname, (unsigned int)new_unx_mode));
+                                 smb_fname_str_dbg(smb_fname),
+                                 (unsigned int)new_unx_mode));
        }
 
        /* If this is a successful open, we must remove any deferred open
@@ -1352,7 +1354,7 @@ NTSTATUS onefs_open_file_ntcreate(connection_struct *conn,
 ****************************************************************************/
 static NTSTATUS onefs_open_directory(connection_struct *conn,
                                     struct smb_request *req,
-                                    const char *fname,
+                                    struct smb_filename *smb_dname,
                                     uint32 access_mask,
                                     uint32 share_access,
                                     uint32 create_disposition,
@@ -1360,8 +1362,7 @@ static NTSTATUS onefs_open_directory(connection_struct *conn,
                                     uint32 file_attributes,
                                     struct security_descriptor *sd,
                                     files_struct **result,
-                                    int *pinfo,
-                                    SMB_STRUCT_STAT *psbuf)
+                                    int *pinfo)
 {
        files_struct *fsp = NULL;
        struct share_mode_lock *lck = NULL;
@@ -1378,14 +1379,16 @@ static NTSTATUS onefs_open_directory(connection_struct *conn,
                  "access_mask = 0x%x, "
                  "share_access = 0x%x create_options = 0x%x, "
                  "create_disposition = 0x%x, file_attributes = 0x%x\n",
-                 fname, (unsigned int)access_mask, (unsigned int)share_access,
-                 (unsigned int)create_options, (unsigned int)create_disposition,
+                 smb_fname_str_dbg(smb_dname), (unsigned int)access_mask,
+                 (unsigned int)share_access, (unsigned int)create_options,
+                 (unsigned int)create_disposition,
                  (unsigned int)file_attributes));
 
        if (!(file_attributes & FILE_FLAG_POSIX_SEMANTICS) &&
            (conn->fs_capabilities & FILE_NAMED_STREAMS) &&
-           is_ntfs_stream_name(fname)) {
-               DEBUG(2, ("onefs_open_directory: %s is a stream name!\n", fname));
+           is_ntfs_stream_smb_fname(smb_dname)) {
+               DEBUG(2, ("onefs_open_directory: %s is a stream name!\n",
+                         smb_fname_str_dbg(smb_dname)));
                return NT_STATUS_NOT_A_DIRECTORY;
        }
 
@@ -1418,7 +1421,8 @@ static NTSTATUS onefs_open_directory(connection_struct *conn,
                default:
                        DEBUG(5, ("onefs_open_directory: invalid "
                                  "create_disposition 0x%x for directory %s\n",
-                                 (unsigned int)create_disposition, fname));
+                                 (unsigned int)create_disposition,
+                                 smb_fname_str_dbg(smb_dname)));
                        return NT_STATUS_INVALID_PARAMETER;
        }
 
@@ -1431,7 +1435,8 @@ static NTSTATUS onefs_open_directory(connection_struct *conn,
        }
 
        /* Get parent dirname */
-       if (!parent_dirname(talloc_tos(), fname, &parent_dir, &dirname)) {
+       if (!parent_dirname(talloc_tos(), smb_dname->base_name, &parent_dir,
+                           &dirname)) {
                return NT_STATUS_NO_MEMORY;
        }
 
@@ -1440,7 +1445,7 @@ static NTSTATUS onefs_open_directory(connection_struct *conn,
                mode = (mode_t)(file_attributes & ~FILE_FLAG_POSIX_SEMANTICS);
                file_attributes = 0;
        } else {
-               mode = unix_mode(conn, aDIR, fname, parent_dir);
+               mode = unix_mode(conn, aDIR, smb_dname->base_name, parent_dir);
        }
 
        /*
@@ -1463,7 +1468,7 @@ static NTSTATUS onefs_open_directory(connection_struct *conn,
  retry_open:
        fsp->fh->fd = onefs_sys_create_file(conn,
                                            -1,
-                                           fname,
+                                           smb_dname->base_name,
                                            access_mask,
                                            access_mask,
                                            share_access,
@@ -1477,7 +1482,8 @@ static NTSTATUS onefs_open_directory(connection_struct *conn,
                                            NULL);
 
        if (fsp->fh->fd == -1) {
-               DEBUG(3, ("Error opening %s. Errno=%d (%s).\n", fname, errno,
+               DEBUG(3, ("Error opening %s. Errno=%d (%s).\n",
+                         smb_fname_str_dbg(smb_dname), errno,
                          strerror(errno)));
                SMB_ASSERT(errno != EINPROGRESS);
 
@@ -1499,15 +1505,16 @@ static NTSTATUS onefs_open_directory(connection_struct *conn,
                file_free(req, fsp);
 
                if ((errno == ENOENT) && (create_disposition == FILE_OPEN)) {
-                       DEBUG(5,("onefs_open_directory: FILE_OPEN requested "
+                       DEBUG(5, ("onefs_open_directory: FILE_OPEN requested "
                                  "for directory %s and it doesn't "
-                                 "exist.\n", fname ));
+                                 "exist.\n", smb_fname_str_dbg(smb_dname)));
                        return NT_STATUS_OBJECT_NAME_NOT_FOUND;
                } else if ((errno == EEXIST) &&
                    (create_disposition == FILE_CREATE)) {
-                       DEBUG(5,("onefs_open_directory: FILE_CREATE "
+                       DEBUG(5, ("onefs_open_directory: FILE_CREATE "
                                  "requested for directory %s and it "
-                                 "already exists.\n", fname ));
+                                 "already exists.\n",
+                                 smb_fname_str_dbg(smb_dname)));
                        return NT_STATUS_OBJECT_NAME_COLLISION;
                } else if ((errno == EAGAIN) || (errno == EWOULDBLOCK)) {
                        /* Catch sharing violations. */
@@ -1520,15 +1527,18 @@ static NTSTATUS onefs_open_directory(connection_struct *conn,
        if (info == FILE_WAS_CREATED) {
 
                /* Pulled from mkdir_internal() */
-               if (SMB_VFS_LSTAT(conn, fname, psbuf) == -1) {
+               if (SMB_VFS_LSTAT(conn, smb_dname) == -1) {
                        DEBUG(2, ("Could not stat directory '%s' just "
-                                 "created: %s\n",fname, strerror(errno)));
+                                 "created: %s\n",
+                                 smb_fname_str_dbg(smb_dname),
+                                 strerror(errno)));
                        return map_nt_error_from_unix(errno);
                }
 
-               if (!S_ISDIR(psbuf->st_mode)) {
+               if (!S_ISDIR(smb_dname->st.st_ex_mode)) {
                        DEBUG(0, ("Directory just '%s' created is not a "
-                                 "directory\n", fname));
+                                 "directory\n",
+                                 smb_fname_str_dbg(smb_dname)));
                        return NT_STATUS_ACCESS_DENIED;
                }
 
@@ -1540,32 +1550,35 @@ static NTSTATUS onefs_open_directory(connection_struct *conn,
                         * parent dir.
                         */
                        if (mode & ~(S_IRWXU|S_IRWXG|S_IRWXO) &&
-                           (mode & ~psbuf->st_mode)) {
-                               SMB_VFS_CHMOD(conn, fname, (psbuf->st_mode |
-                                                 (mode & ~psbuf->st_mode)));
+                           (mode & ~smb_dname->st.st_ex_mode)) {
+                               SMB_VFS_CHMOD(conn, smb_dname->base_name,
+                                   (smb_dname->st.st_ex_mode |
+                                       (mode & ~smb_dname->st.st_ex_mode)));
                        }
                }
 
                /* Change the owner if required. */
                if (lp_inherit_owner(SNUM(conn))) {
-                       change_dir_owner_to_parent(conn, parent_dir, fname,
-                                                  psbuf);
+                       change_dir_owner_to_parent(conn, parent_dir,
+                                                  smb_dname->base_name,
+                                                  &smb_dname->st);
                }
 
                notify_fname(conn, NOTIFY_ACTION_ADDED,
-                            FILE_NOTIFY_CHANGE_DIR_NAME, fname);
+                            FILE_NOTIFY_CHANGE_DIR_NAME,
+                            smb_dname->base_name);
        }
 
        /* Stat the fd for Samba bookkeeping. */
-       if(SMB_VFS_FSTAT(fsp, psbuf) != 0) {
+       if(SMB_VFS_FSTAT(fsp, &smb_dname->st) != 0) {
                fd_close(fsp);
                file_free(req, fsp);
                return map_nt_error_from_unix(errno);
        }
 
        /* Setup the files_struct for it. */
-       fsp->mode = psbuf->st_mode;
-       fsp->file_id = vfs_file_id_from_sbuf(conn, psbuf);
+       fsp->mode = smb_dname->st.st_ex_mode;
+       fsp->file_id = vfs_file_id_from_sbuf(conn, &smb_dname->st);
        fsp->vuid = req ? req->vuid : UID_FIELD_INVALID;
        fsp->file_pid = req ? req->smbpid : 0;
        fsp->can_lock = False;
@@ -1585,21 +1598,21 @@ static NTSTATUS onefs_open_directory(connection_struct *conn,
        fsp->is_directory = True;
        fsp->posix_open = posix_open;
 
-       string_set(&fsp->fsp_name,fname);
+       string_set(&fsp->fsp_name, smb_dname->base_name);
 
-       mtimespec = get_mtimespec(psbuf);
+       mtimespec = smb_dname->st.st_ex_mtime;
 
        /*
         * Still set the samba share mode lock for correct delete-on-close
         * semantics and to make smbstatus more useful.
         */
        lck = get_share_mode_lock(talloc_tos(), fsp->file_id,
-                                 conn->connectpath,
-                                 fname, &mtimespec);
+                                 conn->connectpath, smb_dname->base_name,
+                                 &mtimespec);
 
        if (lck == NULL) {
                DEBUG(0, ("onefs_open_directory: Could not get share mode "
-                         "lock for %s\n", fname));
+                         "lock for %s\n", smb_fname_str_dbg(smb_dname)));
                fd_close(fsp);
                file_free(req, fsp);
                return NT_STATUS_SHARING_VIOLATION;
@@ -1645,125 +1658,12 @@ static NTSTATUS onefs_open_directory(connection_struct *conn,
        return NT_STATUS_OK;
 }
 
-/*
- * If a main file is opened for delete, all streams need to be checked for
- * !FILE_SHARE_DELETE. Do this by opening with DELETE_ACCESS.
- * If that works, delete them all by setting the delete on close and close.
- */
-
-static NTSTATUS open_streams_for_delete(connection_struct *conn,
-                                       const char *fname)
-{
-       struct stream_struct *stream_info;
-       files_struct **streams;
-       int i;
-       unsigned int num_streams;
-       TALLOC_CTX *frame = talloc_stackframe();
-       NTSTATUS status;
-
-       status = SMB_VFS_STREAMINFO(conn, NULL, fname, talloc_tos(),
-                                   &num_streams, &stream_info);
-
-       if (NT_STATUS_EQUAL(status, NT_STATUS_NOT_IMPLEMENTED)
-           || NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
-               DEBUG(10, ("no streams around\n"));
-               TALLOC_FREE(frame);
-               return NT_STATUS_OK;
-       }
-
-       if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(10, ("SMB_VFS_STREAMINFO failed: %s\n",
-                          nt_errstr(status)));
-               goto fail;
-       }
-
-       DEBUG(10, ("open_streams_for_delete found %d streams\n",
-                  num_streams));
-
-       if (num_streams == 0) {
-               TALLOC_FREE(frame);
-               return NT_STATUS_OK;
-       }
-
-       streams = TALLOC_ARRAY(talloc_tos(), files_struct *, num_streams);
-       if (streams == NULL) {
-               DEBUG(0, ("talloc failed\n"));
-               status = NT_STATUS_NO_MEMORY;
-               goto fail;
-       }
-
-       /* Open the base file */
-
-       for (i=0; i<num_streams; i++) {
-               char *streamname;
-
-               if (strequal(stream_info[i].name, "::$DATA")) {
-                       streams[i] = NULL;
-                       continue;
-               }
-
-               streamname = talloc_asprintf(talloc_tos(), "%s%s", fname,
-                                            stream_info[i].name);
-
-               if (streamname == NULL) {
-                       DEBUG(0, ("talloc_aprintf failed\n"));
-                       status = NT_STATUS_NO_MEMORY;
-                       goto fail;
-               }
-
-               status = onefs_create_file_unixpath
-                       (conn,                  /* conn */
-                        NULL,                  /* req */
-                        streamname,            /* fname */
-                        DELETE_ACCESS,         /* access_mask */
-                        FILE_SHARE_READ | FILE_SHARE_WRITE
-                        | FILE_SHARE_DELETE,   /* share_access */
-                        FILE_OPEN,             /* create_disposition*/
-                        NTCREATEX_OPTIONS_PRIVATE_STREAM_DELETE, /* create_options */
-                        FILE_ATTRIBUTE_NORMAL, /* file_attributes */
-                        0,                     /* oplock_request */
-                        0,                     /* allocation_size */
-                        NULL,                  /* sd */
-                        NULL,                  /* ea_list */
-                        &streams[i],           /* result */
-                        NULL,                  /* pinfo */
-                        NULL,                  /* fsp_data */
-                        NULL);                 /* psbuf */
-
-               TALLOC_FREE(streamname);
-
-               if (!NT_STATUS_IS_OK(status)) {
-                       DEBUG(10, ("Could not open stream %s: %s\n",
-                                  streamname, nt_errstr(status)));
-                       break;
-               }
-       }
-
-       /*
-        * don't touch the variable "status" beyond this point :-)
-        */
-
-       for (i -= 1 ; i >= 0; i--) {
-               if (streams[i] == NULL) {
-                       continue;
-               }
-
-               DEBUG(10, ("Closing stream # %d, %s\n", i,
-                          streams[i]->fsp_name));
-               close_file(NULL, streams[i], NORMAL_CLOSE);
-       }
-
- fail:
-       TALLOC_FREE(frame);
-       return status;
-}
-
 /*
  * Wrapper around onefs_open_file_ntcreate and onefs_open_directory.
  */
 static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
                                           struct smb_request *req,
-                                          const char *fname,
+                                          struct smb_filename *smb_fname,
                                           uint32_t access_mask,
                                           uint32_t share_access,
                                           uint32_t create_disposition,
@@ -1775,10 +1675,8 @@ static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
                                           struct ea_list *ea_list,
                                           files_struct **result,
                                           int *pinfo,
-                                          struct onefs_fsp_data *fsp_data,
-                                          SMB_STRUCT_STAT *psbuf)
+                                          struct onefs_fsp_data *fsp_data)
 {
-       SMB_STRUCT_STAT sbuf;
        int info = FILE_WAS_OPENED;
        files_struct *base_fsp = NULL;
        files_struct *fsp = NULL;
@@ -1795,7 +1693,7 @@ static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
                  (unsigned int)create_disposition,
                  (unsigned int)create_options,
                  (unsigned int)oplock_request,
-                 ea_list, sd, fname));
+                 ea_list, sd, smb_fname_str_dbg(smb_fname)));
 
        if (create_options & FILE_OPEN_BY_FILE_ID) {
                status = NT_STATUS_NOT_SUPPORTED;
@@ -1813,23 +1711,19 @@ static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
                oplock_request |= INTERNAL_OPEN_ONLY;
        }
 
-       if (psbuf != NULL) {
-               sbuf = *psbuf;
-       }
-       else {
-               if (SMB_VFS_STAT(conn, fname, &sbuf) == -1) {
-                       SET_STAT_INVALID(sbuf);
-               }
+       if (lp_parm_bool(SNUM(conn), PARM_ONEFS_TYPE,
+               PARM_IGNORE_SACLS, PARM_IGNORE_SACLS_DEFAULT)) {
+               access_mask &= ~SYSTEM_SECURITY_ACCESS;
        }
 
        if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
            && (access_mask & DELETE_ACCESS)
-           && !is_ntfs_stream_name(fname)) {
+           && !is_ntfs_stream_smb_fname(smb_fname)) {
                /*
                 * We can't open a file with DELETE access if any of the
                 * streams is open without FILE_SHARE_DELETE
                 */
-               status = open_streams_for_delete(conn, fname);
+               status = open_streams_for_delete(conn, smb_fname->base_name);
 
                if (!NT_STATUS_IS_OK(status)) {
                        goto fail;
@@ -1837,26 +1731,15 @@ static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
        }
 
        if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
-           && is_ntfs_stream_name(fname)) {
-               char *base;
+           && is_ntfs_stream_smb_fname(smb_fname)) {
                uint32 base_create_disposition;
+               struct smb_filename *smb_fname_base = NULL;
 
                if (create_options & FILE_DIRECTORY_FILE) {
                        status = NT_STATUS_NOT_A_DIRECTORY;
                        goto fail;
                }
 
-               status = onefs_split_ntfs_stream_name(talloc_tos(), fname,
-                                                     &base, NULL);
-               if (!NT_STATUS_IS_OK(status)) {
-                       DEBUG(10, ("onefs_create_file_unixpath: "
-                                 "split_ntfs_stream_name failed: %s\n",
-                                 nt_errstr(status)));
-                       goto fail;
-               }
-
-               SMB_ASSERT(!is_ntfs_stream_name(base)); /* paranoia.. */
-
                switch (create_disposition) {
                case FILE_OPEN:
                        base_create_disposition = FILE_OPEN;
@@ -1866,10 +1749,24 @@ static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
                        break;
                }
 
+               /* Create an smb_filename with stream_name == NULL. */
+               status = create_synthetic_smb_fname(talloc_tos(),
+                                                   smb_fname->base_name,
+                                                   NULL, NULL,
+                                                   &smb_fname_base);
+               if (!NT_STATUS_IS_OK(status)) {
+                       goto fail;
+               }
+
+               if (SMB_VFS_STAT(conn, smb_fname_base) == -1) {
+                       DEBUG(10, ("Unable to stat stream: %s\n",
+                                  smb_fname_str_dbg(smb_fname_base)));
+               }
+
                status = onefs_create_file_unixpath(
                        conn,                           /* conn */
                        NULL,                           /* req */
-                       base,                           /* fname */
+                       smb_fname_base,                 /* fname */
                        SYNCHRONIZE_ACCESS,             /* access_mask */
                        (FILE_SHARE_READ |
                            FILE_SHARE_WRITE |
@@ -1883,14 +1780,31 @@ static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
                        NULL,                           /* ea_list */
                        &base_fsp,                      /* result */
                        NULL,                           /* pinfo */
-                       NULL,                           /* fsp_data */
-                       NULL);                          /* psbuf */
+                       NULL);                          /* fsp_data */
+
+               TALLOC_FREE(smb_fname_base);
 
                if (!NT_STATUS_IS_OK(status)) {
                        DEBUG(10, ("onefs_create_file_unixpath for base %s "
-                                 "failed: %s\n", base, nt_errstr(status)));
+                                  "failed: %s\n", smb_fname->base_name,
+                                  nt_errstr(status)));
                        goto fail;
                }
+
+               /*
+                * Testing against windows xp/2003/vista shows that oplocks
+                * can actually be requested and granted on streams (see the
+                * RAW-OPLOCK-STREAM1 smbtorture test).
+                */
+               if ((oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK) !=
+                    NO_OPLOCK) {
+                       DEBUG(5, ("Oplock(%d) being requested on a stream! "
+                                 "Ignoring oplock request: fname=%s\n",
+                                 oplock_request & ~SAMBA_PRIVATE_OPLOCK_MASK,
+                               smb_fname_str_dbg(smb_fname)));
+                       /* Request NO_OPLOCK instead. */
+                       oplock_request &= SAMBA_PRIVATE_OPLOCK_MASK;
+               }
        }
 
        /* Covert generic bits in the security descriptor. */
@@ -1926,7 +1840,7 @@ static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
                status = onefs_open_directory(
                        conn,                           /* conn */
                        req,                            /* req */
-                       fname,                          /* fname */
+                       smb_fname,                      /* fname */
                        access_mask,                    /* access_mask */
                        share_access,                   /* share_access */
                        create_disposition,             /* create_disposition*/
@@ -1934,8 +1848,7 @@ static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
                        file_attributes,                /* file_attributes */
                        sd,                             /* sd */
                        &fsp,                           /* result */
-                       &info,                          /* pinfo */
-                       &sbuf);                         /* psbuf */
+                       &info);                         /* pinfo */
        } else {
 
                /*
@@ -1958,7 +1871,7 @@ static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
                status = onefs_open_file_ntcreate(
                        conn,                           /* conn */
                        req,                            /* req */
-                       fname,                          /* fname */
+                       smb_fname,                      /* fname */
                        access_mask,                    /* access_mask */
                        share_access,                   /* share_access */
                        create_disposition,             /* create_disposition*/
@@ -1968,8 +1881,7 @@ static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
                        sd,                             /* sd */
                        fsp,                            /* result */
                        &info,                          /* pinfo */
-                       fsp_data,                       /* fsp_data */
-                       &sbuf);                         /* psbuf */
+                       fsp_data);                      /* fsp_data */
 
                if(!NT_STATUS_IS_OK(status)) {
                        file_free(req, fsp);
@@ -2000,7 +1912,7 @@ static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
                        status = onefs_open_directory(
                                conn,                   /* conn */
                                req,                    /* req */
-                               fname,                  /* fname */
+                               smb_fname,              /* fname */
                                access_mask,            /* access_mask */
                                share_access,           /* share_access */
                                create_disposition,     /* create_disposition*/
@@ -2008,8 +1920,7 @@ static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
                                file_attributes,        /* file_attributes */
                                sd,                     /* sd */
                                &fsp,                   /* result */
-                               &info,                  /* pinfo */
-                               &sbuf);                 /* psbuf */
+                               &info);                 /* pinfo */
                }
        }
 
@@ -2022,13 +1933,13 @@ static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
        SMB_ASSERT(fsp);
 
        if ((ea_list != NULL) && (info == FILE_WAS_CREATED)) {
-               status = set_ea(conn, fsp, fname, ea_list);
+               status = set_ea(conn, fsp, smb_fname, ea_list);
                if (!NT_STATUS_IS_OK(status)) {
                        goto fail;
                }
        }
 
-       if (!fsp->is_directory && S_ISDIR(sbuf.st_mode)) {
+       if (!fsp->is_directory && S_ISDIR(smb_fname->st.st_ex_mode)) {
                status = NT_STATUS_ACCESS_DENIED;
                goto fail;
        }
@@ -2036,7 +1947,7 @@ static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
        /* Save the requested allocation size. */
        if ((info == FILE_WAS_CREATED) || (info == FILE_WAS_OVERWRITTEN)) {
                if (allocation_size
-                   && (allocation_size > sbuf.st_size)) {
+                   && (allocation_size > smb_fname->st.st_ex_size)) {
                        fsp->initial_allocation_size = smb_roundup(
                                fsp->conn, allocation_size);
                        if (fsp->is_directory) {
@@ -2051,7 +1962,7 @@ static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
                        }
                } else {
                        fsp->initial_allocation_size = smb_roundup(
-                               fsp->conn, (uint64_t)sbuf.st_size);
+                               fsp->conn, (uint64_t)smb_fname->st.st_ex_size);
                }
        }
 
@@ -2061,13 +1972,8 @@ static NTSTATUS onefs_create_file_unixpath(connection_struct *conn,
        if (pinfo != NULL) {
                *pinfo = info;
        }
-       if (psbuf != NULL) {
-               if ((fsp->fh == NULL) || (fsp->fh->fd == -1)) {
-                       *psbuf = sbuf;
-               }
-               else {
-                       SMB_VFS_FSTAT(fsp, psbuf);
-               }
+       if ((fsp->fh != NULL) && (fsp->fh->fd != -1)) {
+               SMB_VFS_FSTAT(fsp, &smb_fname->st);
        }
        return NT_STATUS_OK;
 
@@ -2105,8 +2011,7 @@ static void destroy_onefs_fsp_data(void *p_data)
 NTSTATUS onefs_create_file(vfs_handle_struct *handle,
                           struct smb_request *req,
                           uint16_t root_dir_fid,
-                          const char *fname,
-                          uint32_t create_file_flags,
+                          struct smb_filename *smb_fname,
                           uint32_t access_mask,
                           uint32_t share_access,
                           uint32_t create_disposition,
@@ -2117,13 +2022,10 @@ NTSTATUS onefs_create_file(vfs_handle_struct *handle,
                           struct security_descriptor *sd,
                           struct ea_list *ea_list,
                           files_struct **result,
-                          int *pinfo,
-                          SMB_STRUCT_STAT *psbuf)
+                          int *pinfo)
 {
        connection_struct *conn = handle->conn;
-       struct case_semantics_state *case_state = NULL;
        struct onefs_fsp_data fsp_data = {};
-       SMB_STRUCT_STAT sbuf;
        int info = FILE_WAS_OPENED;
        files_struct *fsp = NULL;
        NTSTATUS status;
@@ -2133,7 +2035,7 @@ NTSTATUS onefs_create_file(vfs_handle_struct *handle,
                  "create_disposition = 0x%x create_options = 0x%x "
                  "oplock_request = 0x%x "
                  "root_dir_fid = 0x%x, ea_list = 0x%p, sd = 0x%p, "
-                 "create_file_flags = 0x%x, fname = %s\n",
+                 "fname = %s\n",
                  (unsigned int)access_mask,
                  (unsigned int)file_attributes,
                  (unsigned int)share_access,
@@ -2141,72 +2043,19 @@ NTSTATUS onefs_create_file(vfs_handle_struct *handle,
                  (unsigned int)create_options,
                  (unsigned int)oplock_request,
                  (unsigned int)root_dir_fid,
-                 ea_list, sd, create_file_flags, fname));
+                 ea_list, sd, smb_fname_str_dbg(smb_fname)));
 
        /* Get the file name if root_dir_fid was specified. */
        if (root_dir_fid != 0) {
-               char *new_fname;
-
                status = get_relative_fid_filename(conn, req, root_dir_fid,
-                                                  fname, &new_fname);
-               if (!NT_STATUS_IS_OK(status)) {
-                       goto fail;
-               }
-
-               fname = new_fname;
-       }
-
-       /* Resolve the file name if this was a DFS pathname. */
-       if ((req != NULL) && (req->flags2 & FLAGS2_DFS_PATHNAMES)) {
-               char *resolved_fname;
-
-               status = resolve_dfspath(talloc_tos(), conn, true, fname,
-                                        &resolved_fname);
-
-               if (!NT_STATUS_IS_OK(status)) {
-                       /*
-                        * For PATH_NOT_COVERED we had
-                        * reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
-                        *                 ERRSRV, ERRbadpath);
-                        * Need to fix in callers
-                        */
-                       goto fail;
-               }
-               fname = resolved_fname;
-       }
-
-       /* Check if POSIX semantics are wanted. */
-       if (file_attributes & FILE_FLAG_POSIX_SEMANTICS) {
-               case_state = set_posix_case_semantics(talloc_tos(), conn);
-       }
-
-       /* Convert dos path to unix path if it hasn't already been done. */
-       if (create_file_flags & CFF_DOS_PATH) {
-               char *converted_fname;
-
-               SET_STAT_INVALID(sbuf);
-
-               status = unix_convert(talloc_tos(), conn, fname, False,
-                                     &converted_fname, NULL, &sbuf);
+                                                  smb_fname);
                if (!NT_STATUS_IS_OK(status)) {
                        goto fail;
                }
-               fname = converted_fname;
-       } else {
-               if (psbuf != NULL) {
-                       sbuf = *psbuf;
-               } else {
-                       if (SMB_VFS_STAT(conn, fname, &sbuf) == -1) {
-                               SET_STAT_INVALID(sbuf);
-                       }
-               }
-
        }
 
-       TALLOC_FREE(case_state);
-
        /* All file access must go through check_name() */
-       status = check_name(conn, fname);
+       status = check_name(conn, smb_fname->base_name);
        if (!NT_STATUS_IS_OK(status)) {
                goto fail;
        }
@@ -2214,7 +2063,7 @@ NTSTATUS onefs_create_file(vfs_handle_struct *handle,
        status = onefs_create_file_unixpath(
                conn,                                   /* conn */
                req,                                    /* req */
-               fname,                                  /* fname */
+               smb_fname,                              /* fname */
                access_mask,                            /* access_mask */
                share_access,                           /* share_access */
                create_disposition,                     /* create_disposition*/
@@ -2226,8 +2075,7 @@ NTSTATUS onefs_create_file(vfs_handle_struct *handle,
                ea_list,                                /* ea_list */
                &fsp,                                   /* result */
                &info,                                  /* pinfo */
-               &fsp_data,                              /* fsp_data */
-               &sbuf);                                 /* psbuf */
+               &fsp_data);                             /* psbuf */
 
        if (!NT_STATUS_IS_OK(status)) {
                goto fail;
@@ -2259,9 +2107,6 @@ NTSTATUS onefs_create_file(vfs_handle_struct *handle,
        if (pinfo != NULL) {
                *pinfo = info;
        }
-       if (psbuf != NULL) {
-               *psbuf = sbuf;
-       }
        return NT_STATUS_OK;
 
  fail: