s3:smbd: add a smbd_server_connection pointer to connection_struct
[sfrench/samba-autobuild/.git] / source3 / smbd / reply.c
index 98ee83ea83222a788ea0926fbe6edcdfb453ea62..750915b1cb4576b2c59f67beba4e8ad5ad421174 100644 (file)
@@ -466,7 +466,7 @@ static bool netbios_session_retarget(const char *name, int name_type)
                sscanf(p, "%x", &retarget_type);
        }
 
-       ret = resolve_name(retarget, &retarget_addr, retarget_type);
+       ret = resolve_name(retarget, &retarget_addr, retarget_type, false);
        if (!ret) {
                DEBUG(10, ("could not resolve %s\n", retarget));
                goto fail;
@@ -703,7 +703,7 @@ void reply_tcon_and_X(struct smb_request *req)
 
        /* we might have to close an old one */
        if ((tcon_flags & 0x1) && conn) {
-               close_cnum(sconn, conn,req->vuid);
+               close_cnum(conn,req->vuid);
                req->conn = NULL;
                conn = NULL;
        }
@@ -856,6 +856,7 @@ void reply_tcon_and_X(struct smb_request *req)
 
        END_PROFILE(SMBtconX);
 
+       req->tid = conn->cnum;
        chain_reply(req);
        return;
 }
@@ -993,8 +994,9 @@ void reply_checkpath(struct smb_request *req)
                                conn,
                                req->flags2 & FLAGS2_DFS_PATHNAMES,
                                name,
-                               &smb_fname,
-                               NULL);
+                               0,
+                               NULL,
+                               &smb_fname);
 
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
@@ -1090,8 +1092,9 @@ void reply_getatr(struct smb_request *req)
                                conn,
                                req->flags2 & FLAGS2_DFS_PATHNAMES,
                                fname,
-                               &smb_fname,
-                               NULL);
+                               0,
+                               NULL,
+                               &smb_fname);
                if (!NT_STATUS_IS_OK(status)) {
                        if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
                                reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
@@ -1106,7 +1109,7 @@ void reply_getatr(struct smb_request *req)
                        DEBUG(3,("reply_getatr: stat of %s failed (%s)\n",
                                 smb_fname_str_dbg(smb_fname),
                                 strerror(errno)));
-                       reply_unixerror(req, ERRDOS,ERRbadfile);
+                       reply_nterror(req,  map_nt_error_from_unix(errno));
                        goto out;
                }
 
@@ -1192,8 +1195,9 @@ void reply_setatr(struct smb_request *req)
                                conn,
                                req->flags2 & FLAGS2_DFS_PATHNAMES,
                                fname,
-                               &smb_fname,
-                               NULL);
+                               0,
+                               NULL,
+                               &smb_fname);
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
                        reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
@@ -1220,7 +1224,7 @@ void reply_setatr(struct smb_request *req)
        ft.mtime = convert_time_t_to_timespec(mtime);
        status = smb_set_file_time(conn, NULL, smb_fname, &ft, true);
        if (!NT_STATUS_IS_OK(status)) {
-               reply_unixerror(req, ERRDOS, ERRnoaccess);
+               reply_nterror(req, status);
                goto out;
        }
 
@@ -1232,7 +1236,7 @@ void reply_setatr(struct smb_request *req)
 
                if (file_set_dosmode(conn, smb_fname, mode, NULL,
                                     false) != 0) {
-                       reply_unixerror(req, ERRDOS, ERRnoaccess);
+                       reply_nterror(req, map_nt_error_from_unix(errno));
                        goto out;
                }
        }
@@ -1258,7 +1262,7 @@ void reply_dskattr(struct smb_request *req)
        START_PROFILE(SMBdskattr);
 
        if (get_dfree_info(conn,".",True,&bsize,&dfree,&dsize) == (uint64_t)-1) {
-               reply_unixerror(req, ERRHRD, ERRgeneral);
+               reply_nterror(req, map_nt_error_from_unix(errno));
                END_PROFILE(SMBdskattr);
                return;
        }
@@ -1342,6 +1346,7 @@ void reply_search(struct smb_request *req)
        char *path = NULL;
        const char *mask = NULL;
        char *directory = NULL;
+       struct smb_filename *smb_fname = NULL;
        char *fname = NULL;
        SMB_OFF_T size;
        uint32 mode;
@@ -1366,14 +1371,12 @@ void reply_search(struct smb_request *req)
 
        if (req->wct < 2) {
                reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
-               END_PROFILE(SMBsearch);
-               return;
+               goto out;
        }
 
        if (lp_posix_pathnames()) {
                reply_unknown_new(req, req->cmd);
-               END_PROFILE(SMBsearch);
-               return;
+               goto out;
        }
 
        /* If we were called as SMBffirst then we must expect close. */
@@ -1389,8 +1392,7 @@ void reply_search(struct smb_request *req)
                                       &nt_status, &mask_contains_wcard);
        if (!NT_STATUS_IS_OK(nt_status)) {
                reply_nterror(req, nt_status);
-               END_PROFILE(SMBsearch);
-               return;
+               goto out;
        }
 
        p++;
@@ -1400,47 +1402,23 @@ void reply_search(struct smb_request *req)
        /* dirtype &= ~aDIR; */
 
        if (status_len == 0) {
-               struct smb_filename *smb_fname = NULL;
-
-               nt_status = resolve_dfspath_wcard(ctx, conn,
-                                         req->flags2 & FLAGS2_DFS_PATHNAMES,
-                                         path,
-                                         &path,
-                                         &mask_contains_wcard);
+               nt_status = filename_convert(ctx, conn,
+                                            req->flags2 & FLAGS2_DFS_PATHNAMES,
+                                            path,
+                                            UCF_ALWAYS_ALLOW_WCARD_LCOMP,
+                                            &mask_contains_wcard,
+                                            &smb_fname);
                if (!NT_STATUS_IS_OK(nt_status)) {
                        if (NT_STATUS_EQUAL(nt_status,NT_STATUS_PATH_NOT_COVERED)) {
                                reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
                                                ERRSRV, ERRbadpath);
-                               END_PROFILE(SMBsearch);
-                               return;
+                               goto out;
                        }
                        reply_nterror(req, nt_status);
-                       END_PROFILE(SMBsearch);
-                       return;
-               }
-
-               nt_status = unix_convert(ctx, conn, path, &smb_fname,
-                                        UCF_ALLOW_WCARD_LCOMP);
-               if (!NT_STATUS_IS_OK(nt_status)) {
-                       reply_nterror(req, nt_status);
-                       END_PROFILE(SMBsearch);
-                       return;
+                       goto out;
                }
 
-               nt_status = get_full_smb_filename(ctx, smb_fname, &directory);
-               TALLOC_FREE(smb_fname);
-               if (!NT_STATUS_IS_OK(nt_status)) {
-                       reply_nterror(req, nt_status);
-                       END_PROFILE(SMBsearch);
-                       return;
-               }
-
-               nt_status = check_name(conn, directory);
-               if (!NT_STATUS_IS_OK(nt_status)) {
-                       reply_nterror(req, nt_status);
-                       END_PROFILE(SMBsearch);
-                       return;
-               }
+               directory = smb_fname->base_name;
 
                p = strrchr_m(directory,'/');
                if ((p != NULL) && (*directory != '/')) {
@@ -1454,8 +1432,7 @@ void reply_search(struct smb_request *req)
 
                if (!directory) {
                        reply_nterror(req, NT_STATUS_NO_MEMORY);
-                       END_PROFILE(SMBsearch);
-                       return;
+                       goto out;
                }
 
                memset((char *)status,'\0',21);
@@ -1472,8 +1449,7 @@ void reply_search(struct smb_request *req)
                                        &conn->dirptr);
                if (!NT_STATUS_IS_OK(nt_status)) {
                        reply_nterror(req, nt_status);
-                       END_PROFILE(SMBsearch);
-                       return;
+                       goto out;
                }
                dptr_num = dptr_dnum(conn->dirptr);
        } else {
@@ -1513,8 +1489,7 @@ void reply_search(struct smb_request *req)
                if (!make_dir_struct(ctx,buf,"???????????",volume_label(SNUM(conn)),
                                0,aVOLID,0,!allow_long_path_components)) {
                        reply_nterror(req, NT_STATUS_NO_MEMORY);
-                       END_PROFILE(SMBsearch);
-                       return;
+                       goto out;
                }
                dptr_fill(buf+12,dptr_num);
                if (dptr_zero(buf+12) && (status_len==0)) {
@@ -1526,8 +1501,7 @@ void reply_search(struct smb_request *req)
                                      data_blob_const(buf, sizeof(buf)))
                    == -1) {
                        reply_nterror(req, NT_STATUS_NO_MEMORY);
-                       END_PROFILE(SMBsearch);
-                       return;
+                       goto out;
                }
        } else {
                unsigned int i;
@@ -1566,8 +1540,7 @@ void reply_search(struct smb_request *req)
                                                convert_timespec_to_time_t(date),
                                                !allow_long_path_components)) {
                                        reply_nterror(req, NT_STATUS_NO_MEMORY);
-                                       END_PROFILE(SMBsearch);
-                                       return;
+                                       goto out;
                                }
                                if (!dptr_fill(buf+12,dptr_num)) {
                                        break;
@@ -1576,8 +1549,7 @@ void reply_search(struct smb_request *req)
                                                      data_blob_const(buf, sizeof(buf)))
                                    == -1) {
                                        reply_nterror(req, NT_STATUS_NO_MEMORY);
-                                       END_PROFILE(SMBsearch);
-                                       return;
+                                       goto out;
                                }
                                numentries++;
                        }
@@ -1604,8 +1576,7 @@ void reply_search(struct smb_request *req)
 
        if ((numentries == 0) && !mask_contains_wcard) {
                reply_botherror(req, STATUS_NO_MORE_FILES, ERRDOS, ERRnofiles);
-               END_PROFILE(SMBsearch);
-               return;
+               goto out;
        }
 
        SSVAL(req->outbuf,smb_vwv0,numentries);
@@ -1637,7 +1608,8 @@ void reply_search(struct smb_request *req)
                dirtype,
                numentries,
                maxentries ));
-
+ out:
+       TALLOC_FREE(smb_fname);
        END_PROFILE(SMBsearch);
        return;
 }
@@ -1746,8 +1718,9 @@ void reply_open(struct smb_request *req)
                                conn,
                                req->flags2 & FLAGS2_DFS_PATHNAMES,
                                fname,
-                               &smb_fname,
-                               NULL);
+                               0,
+                               NULL,
+                               &smb_fname);
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
                        reply_botherror(req,
@@ -1759,10 +1732,10 @@ void reply_open(struct smb_request *req)
                goto out;
        }
 
-       if (!map_open_params_to_ntcreate(
-                   smb_fname->base_name, deny_mode, OPENX_FILE_EXISTS_OPEN,
-                   &access_mask, &share_mode, &create_disposition,
-                   &create_options)) {
+       if (!map_open_params_to_ntcreate(smb_fname, deny_mode,
+                                        OPENX_FILE_EXISTS_OPEN, &access_mask,
+                                        &share_mode, &create_disposition,
+                                        &create_options)) {
                reply_nterror(req, NT_STATUS_DOS(ERRDOS, ERRbadaccess));
                goto out;
        }
@@ -1811,7 +1784,8 @@ void reply_open(struct smb_request *req)
        mtime = convert_timespec_to_time_t(smb_fname->st.st_ex_mtime);
 
        if (fattr & aDIR) {
-               DEBUG(3,("attempt to open a directory %s\n",fsp->fsp_name));
+               DEBUG(3,("attempt to open a directory %s\n",
+                        fsp_str_dbg(fsp)));
                close_file(req, fsp, ERROR_CLOSE);
                reply_doserror(req, ERRDOS,ERRnoaccess);
                goto out;
@@ -1916,8 +1890,9 @@ void reply_open_and_X(struct smb_request *req)
                                conn,
                                req->flags2 & FLAGS2_DFS_PATHNAMES,
                                fname,
-                               &smb_fname,
-                               NULL);
+                               0,
+                               NULL,
+                               &smb_fname);
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
                        reply_botherror(req,
@@ -1929,9 +1904,10 @@ void reply_open_and_X(struct smb_request *req)
                goto out;
        }
 
-       if (!map_open_params_to_ntcreate(
-                   smb_fname->base_name, deny_mode, smb_ofun, &access_mask,
-                   &share_mode, &create_disposition, &create_options)) {
+       if (!map_open_params_to_ntcreate(smb_fname, deny_mode, smb_ofun,
+                                        &access_mask, &share_mode,
+                                        &create_disposition,
+                                        &create_options)) {
                reply_nterror(req, NT_STATUS_DOS(ERRDOS, ERRbadaccess));
                goto out;
        }
@@ -2076,6 +2052,7 @@ void reply_ulogoffX(struct smb_request *req)
        DEBUG( 3, ( "ulogoffX vuid=%d\n", req->vuid ) );
 
        END_PROFILE(SMBulogoffX);
+       req->vuid = UID_FIELD_INVALID;
        chain_reply(req);
 }
 
@@ -2124,8 +2101,9 @@ void reply_mknew(struct smb_request *req)
                                conn,
                                req->flags2 & FLAGS2_DFS_PATHNAMES,
                                fname,
-                               &smb_fname,
-                               NULL);
+                               0,
+                               NULL,
+                               &smb_fname);
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
                        reply_botherror(req,
@@ -2257,8 +2235,9 @@ void reply_ctemp(struct smb_request *req)
        status = filename_convert(ctx, conn,
                                req->flags2 & FLAGS2_DFS_PATHNAMES,
                                fname,
-                               &smb_fname,
-                               NULL);
+                               0,
+                               NULL,
+                               &smb_fname);
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
                        reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
@@ -2271,7 +2250,7 @@ void reply_ctemp(struct smb_request *req)
 
        tmpfd = mkstemp(smb_fname->base_name);
        if (tmpfd == -1) {
-               reply_unixerror(req, ERRDOS, ERRnoaccess);
+               reply_nterror(req, map_nt_error_from_unix(errno));
                goto out;
        }
 
@@ -2311,9 +2290,9 @@ void reply_ctemp(struct smb_request *req)
        SSVAL(req->outbuf,smb_vwv0,fsp->fnum);
 
        /* the returned filename is relative to the directory */
-       s = strrchr_m(fsp->fsp_name, '/');
+       s = strrchr_m(fsp->fsp_name->base_name, '/');
        if (!s) {
-               s = fsp->fsp_name;
+               s = fsp->fsp_name->base_name;
        } else {
                s++;
        }
@@ -2339,8 +2318,8 @@ void reply_ctemp(struct smb_request *req)
                      CVAL(req->outbuf,smb_flg)|CORE_OPLOCK_GRANTED);
        }
 
-       DEBUG( 2, ( "reply_ctemp: created temp file %s\n", fsp->fsp_name ) );
-       DEBUG( 3, ( "reply_ctemp %s fd=%d umode=0%o\n", fsp->fsp_name,
+       DEBUG(2, ("reply_ctemp: created temp file %s\n", fsp_str_dbg(fsp)));
+       DEBUG(3, ("reply_ctemp %s fd=%d umode=0%o\n", fsp_str_dbg(fsp),
                    fsp->fh->fd, (unsigned int)smb_fname->st.st_ex_mode));
  out:
        TALLOC_FREE(smb_fname);
@@ -2355,22 +2334,13 @@ void reply_ctemp(struct smb_request *req)
 static NTSTATUS can_rename(connection_struct *conn, files_struct *fsp,
                           uint16 dirtype, SMB_STRUCT_STAT *pst)
 {
-       struct smb_filename *smb_fname = NULL;
-       NTSTATUS status;
        uint32 fmode;
 
        if (!CAN_WRITE(conn)) {
                return NT_STATUS_MEDIA_WRITE_PROTECTED;
        }
 
-       status = create_synthetic_smb_fname_split(talloc_tos(), fsp->fsp_name,
-                                                 pst, &smb_fname);
-       if (!NT_STATUS_IS_OK(status)) {
-               return status;
-       }
-
-       fmode = dos_mode(conn, smb_fname);
-       TALLOC_FREE(smb_fname);
+       fmode = dos_mode(conn, fsp->fsp_name);
        if ((fmode & ~dirtype) & (aHIDDEN | aSYSTEM)) {
                return NT_STATUS_NO_SUCH_FILE;
        }
@@ -2534,21 +2504,15 @@ static NTSTATUS do_unlink(connection_struct *conn,
 ****************************************************************************/
 
 NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req,
-                         uint32 dirtype, const char *name_in, bool has_wild)
+                         uint32 dirtype, struct smb_filename *smb_fname,
+                         bool has_wild)
 {
-       struct smb_filename *smb_fname = NULL;
        char *fname_dir = NULL;
        char *fname_mask = NULL;
        int count=0;
        NTSTATUS status = NT_STATUS_OK;
        TALLOC_CTX *ctx = talloc_tos();
 
-       status = unix_convert(ctx, conn, name_in, &smb_fname,
-                             has_wild ? UCF_ALLOW_WCARD_LCOMP : 0);
-       if (!NT_STATUS_IS_OK(status)) {
-               goto out;
-       }
-
        /* Split up the directory from the filename/mask. */
        status = split_fname_dir_mask(ctx, smb_fname->base_name,
                                      &fname_dir, &fname_mask);
@@ -2646,18 +2610,23 @@ NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req,
 
                while ((dname = ReadDirName(dir_hnd, &offset,
                                            &smb_fname->st))) {
+                       TALLOC_CTX *frame = talloc_stackframe();
+
                        if (!is_visible_file(conn, fname_dir, dname,
                                             &smb_fname->st, true)) {
+                               TALLOC_FREE(frame);
                                continue;
                        }
 
                        /* Quick check for "." and ".." */
                        if (ISDOT(dname) || ISDOTDOT(dname)) {
+                               TALLOC_FREE(frame);
                                continue;
                        }
 
                        if(!mask_match(dname, fname_mask,
                                       conn->case_sensitive)) {
+                               TALLOC_FREE(frame);
                                continue;
                        }
 
@@ -2669,23 +2638,28 @@ NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req,
                        if (!smb_fname->base_name) {
                                TALLOC_FREE(dir_hnd);
                                status = NT_STATUS_NO_MEMORY;
+                               TALLOC_FREE(frame);
                                goto out;
                        }
 
                        status = check_name(conn, smb_fname->base_name);
                        if (!NT_STATUS_IS_OK(status)) {
                                TALLOC_FREE(dir_hnd);
+                               TALLOC_FREE(frame);
                                goto out;
                        }
 
                        status = do_unlink(conn, req, smb_fname, dirtype);
                        if (!NT_STATUS_IS_OK(status)) {
+                               TALLOC_FREE(frame);
                                continue;
                        }
 
                        count++;
                        DEBUG(3,("unlink_internals: successful unlink [%s]\n",
                                 smb_fname->base_name));
+
+                       TALLOC_FREE(frame);
                }
                TALLOC_FREE(dir_hnd);
        }
@@ -2695,7 +2669,6 @@ NTSTATUS unlink_internals(connection_struct *conn, struct smb_request *req,
        }
 
  out:
-       TALLOC_FREE(smb_fname);
        TALLOC_FREE(fname_dir);
        TALLOC_FREE(fname_mask);
        return status;
@@ -2709,6 +2682,7 @@ void reply_unlink(struct smb_request *req)
 {
        connection_struct *conn = req->conn;
        char *name = NULL;
+       struct smb_filename *smb_fname = NULL;
        uint32 dirtype;
        NTSTATUS status;
        bool path_contains_wcard = False;
@@ -2718,8 +2692,7 @@ void reply_unlink(struct smb_request *req)
 
        if (req->wct < 1) {
                reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
-               END_PROFILE(SMBunlink);
-               return;
+               goto out;
        }
 
        dirtype = SVAL(req->vwv+0, 0);
@@ -2729,45 +2702,42 @@ void reply_unlink(struct smb_request *req)
                                  &path_contains_wcard);
        if (!NT_STATUS_IS_OK(status)) {
                reply_nterror(req, status);
-               END_PROFILE(SMBunlink);
-               return;
+               goto out;
        }
 
-       status = resolve_dfspath_wcard(ctx, conn,
-                                      req->flags2 & FLAGS2_DFS_PATHNAMES,
-                                      name,
-                                      &name,
-                                      &path_contains_wcard);
+       status = filename_convert(ctx, conn,
+                                 req->flags2 & FLAGS2_DFS_PATHNAMES,
+                                 name,
+                                 UCF_COND_ALLOW_WCARD_LCOMP,
+                                 &path_contains_wcard,
+                                 &smb_fname);
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
                        reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
                                        ERRSRV, ERRbadpath);
-                       END_PROFILE(SMBunlink);
-                       return;
+                       goto out;
                }
                reply_nterror(req, status);
-               END_PROFILE(SMBunlink);
-               return;
+               goto out;
        }
 
-       DEBUG(3,("reply_unlink : %s\n",name));
+       DEBUG(3,("reply_unlink : %s\n", smb_fname_str_dbg(smb_fname)));
 
-       status = unlink_internals(conn, req, dirtype, name,
+       status = unlink_internals(conn, req, dirtype, smb_fname,
                                  path_contains_wcard);
        if (!NT_STATUS_IS_OK(status)) {
                if (open_was_deferred(req->mid)) {
                        /* We have re-scheduled this call. */
-                       END_PROFILE(SMBunlink);
-                       return;
+                       goto out;
                }
                reply_nterror(req, status);
-               END_PROFILE(SMBunlink);
-               return;
+               goto out;
        }
 
        reply_outbuf(req, 0, 0);
+ out:
+       TALLOC_FREE(smb_fname);
        END_PROFILE(SMBunlink);
-
        return;
 }
 
@@ -2854,7 +2824,7 @@ static void sendfile_short_send(files_struct *fsp,
        if (nread < headersize) {
                DEBUG(0,("sendfile_short_send: sendfile failed to send "
                        "header for file %s (%s). Terminating\n",
-                       fsp->fsp_name, strerror(errno) ));
+                       fsp_str_dbg(fsp), strerror(errno)));
                exit_server_cleanly("sendfile_short_send failed");
        }
 
@@ -2868,7 +2838,7 @@ static void sendfile_short_send(files_struct *fsp,
                }
 
                DEBUG(0,("sendfile_short_send: filling truncated file %s "
-                       "with zeros !\n", fsp->fsp_name));
+                       "with zeros !\n", fsp_str_dbg(fsp)));
 
                while (nread < smb_maxcnt) {
                        /*
@@ -2963,15 +2933,19 @@ static void send_file_readbraw(connection_struct *conn,
                                DEBUG(0,("send_file_readbraw: sendfile not available. Faking..\n"));
 
                                if (fake_sendfile(fsp, startpos, nread) == -1) {
-                                       DEBUG(0,("send_file_readbraw: fake_sendfile failed for file %s (%s).\n",
-                                               fsp->fsp_name, strerror(errno) ));
+                                       DEBUG(0,("send_file_readbraw: "
+                                                "fake_sendfile failed for "
+                                                "file %s (%s).\n",
+                                                fsp_str_dbg(fsp),
+                                                strerror(errno)));
                                        exit_server_cleanly("send_file_readbraw fake_sendfile failed");
                                }
                                return;
                        }
 
-                       DEBUG(0,("send_file_readbraw: sendfile failed for file %s (%s). Terminating\n",
-                               fsp->fsp_name, strerror(errno) ));
+                       DEBUG(0,("send_file_readbraw: sendfile failed for "
+                                "file %s (%s). Terminating\n",
+                                fsp_str_dbg(fsp), strerror(errno)));
                        exit_server_cleanly("send_file_readbraw sendfile failed");
                } else if (sendfile_read == 0) {
                        /*
@@ -2983,7 +2957,7 @@ static void send_file_readbraw(connection_struct *conn,
                         */
                        DEBUG(3, ("send_file_readbraw: sendfile sent zero "
                                  "bytes falling back to the normal read: "
-                                 "%s\n", fsp->fsp_name));
+                                 "%s\n", fsp_str_dbg(fsp)));
                        goto normal_readbraw;
                }
 
@@ -3269,7 +3243,7 @@ Returning short read of maximum allowed for compatibility with Windows 2000.\n",
        nread = read_file(fsp,data,startpos,numtoread);
 
        if (nread < 0) {
-               reply_unixerror(req, ERRDOS, ERRnoaccess);
+               reply_nterror(req, map_nt_error_from_unix(errno));
                END_PROFILE(SMBlockread);
                return;
        }
@@ -3363,7 +3337,7 @@ Returning short read of maximum allowed for compatibility with Windows 2000.\n",
                nread = read_file(fsp,data,startpos,numtoread);
 
        if (nread < 0) {
-               reply_unixerror(req, ERRDOS,ERRnoaccess);
+               reply_nterror(req, map_nt_error_from_unix(errno));
                goto strict_unlock;
        }
 
@@ -3425,9 +3399,10 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req,
        SMB_STRUCT_STAT sbuf;
        ssize_t nread = -1;
        struct lock_struct lock;
+       int saved_errno = 0;
 
        if(SMB_VFS_FSTAT(fsp, &sbuf) == -1) {
-               reply_unixerror(req, ERRDOS, ERRnoaccess);
+               reply_nterror(req, map_nt_error_from_unix(errno));
                return;
        }
 
@@ -3494,8 +3469,11 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req,
                                nread = fake_sendfile(fsp, startpos,
                                                      smb_maxcnt);
                                if (nread == -1) {
-                                       DEBUG(0,("send_file_readX: fake_sendfile failed for file %s (%s).\n",
-                                               fsp->fsp_name, strerror(errno) ));
+                                       DEBUG(0,("send_file_readX: "
+                                                "fake_sendfile failed for "
+                                                "file %s (%s).\n",
+                                                fsp_str_dbg(fsp),
+                                                strerror(errno)));
                                        exit_server_cleanly("send_file_readX: fake_sendfile failed");
                                }
                                DEBUG( 3, ( "send_file_readX: fake_sendfile fnum=%d max=%d nread=%d\n",
@@ -3504,8 +3482,9 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req,
                                goto strict_unlock;
                        }
 
-                       DEBUG(0,("send_file_readX: sendfile failed for file %s (%s). Terminating\n",
-                               fsp->fsp_name, strerror(errno) ));
+                       DEBUG(0,("send_file_readX: sendfile failed for file "
+                                "%s (%s). Terminating\n", fsp_str_dbg(fsp),
+                                strerror(errno)));
                        exit_server_cleanly("send_file_readX sendfile failed");
                } else if (nread == 0) {
                        /*
@@ -3517,7 +3496,7 @@ static void send_file_readX(connection_struct *conn, struct smb_request *req,
                         */
                        DEBUG(3, ("send_file_readX: sendfile sent zero bytes "
                                  "falling back to the normal read: %s\n",
-                                 fsp->fsp_name));
+                                 fsp_str_dbg(fsp)));
                        goto normal_read;
                }
 
@@ -3547,14 +3526,16 @@ normal_read:
                /* Send out the header. */
                if (write_data(smbd_server_fd(), (char *)headerbuf,
                               sizeof(headerbuf)) != sizeof(headerbuf)) {
-                       DEBUG(0,("send_file_readX: write_data failed for file %s (%s). Terminating\n",
-                               fsp->fsp_name, strerror(errno) ));
+                       DEBUG(0,("send_file_readX: write_data failed for file "
+                                "%s (%s). Terminating\n", fsp_str_dbg(fsp),
+                                strerror(errno)));
                        exit_server_cleanly("send_file_readX sendfile failed");
                }
                nread = fake_sendfile(fsp, startpos, smb_maxcnt);
                if (nread == -1) {
-                       DEBUG(0,("send_file_readX: fake_sendfile failed for file %s (%s).\n",
-                               fsp->fsp_name, strerror(errno) ));
+                       DEBUG(0,("send_file_readX: fake_sendfile failed for "
+                                "file %s (%s).\n", fsp_str_dbg(fsp),
+                                strerror(errno)));
                        exit_server_cleanly("send_file_readX: fake_sendfile failed");
                }
                goto strict_unlock;
@@ -3565,11 +3546,12 @@ nosendfile_read:
        reply_outbuf(req, 12, smb_maxcnt);
 
        nread = read_file(fsp, smb_buf(req->outbuf), startpos, smb_maxcnt);
+       saved_errno = errno;
 
        SMB_VFS_STRICT_UNLOCK(conn, fsp, &lock);
 
        if (nread < 0) {
-               reply_unixerror(req, ERRDOS, ERRnoaccess);
+               reply_nterror(req, map_nt_error_from_unix(saved_errno));
                return;
        }
 
@@ -3810,7 +3792,7 @@ void reply_writebraw(struct smb_request *req)
                (int)nwritten, (int)write_through));
 
        if (nwritten < (ssize_t)numtowrite)  {
-               reply_unixerror(req, ERRHRD, ERRdiskfull);
+               reply_doserror(req, ERRHRD, ERRdiskfull);
                error_to_writebrawerr(req);
                goto strict_unlock;
        }
@@ -3879,7 +3861,7 @@ void reply_writebraw(struct smb_request *req)
                nwritten = write_file(req,fsp,buf+4,startpos+nwritten,numtowrite);
                if (nwritten == -1) {
                        TALLOC_FREE(buf);
-                       reply_unixerror(req, ERRHRD, ERRdiskfull);
+                       reply_nterror(req, map_nt_error_from_unix(errno));
                        error_to_writebrawerr(req);
                        goto strict_unlock;
                }
@@ -3900,7 +3882,7 @@ void reply_writebraw(struct smb_request *req)
        status = sync_file(conn, fsp, write_through);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(5,("reply_writebraw: sync_file for %s returned %s\n",
-                       fsp->fsp_name, nt_errstr(status) ));
+                        fsp_str_dbg(fsp), nt_errstr(status)));
                reply_nterror(req, status);
                error_to_writebrawerr(req);
                goto strict_unlock;
@@ -3958,6 +3940,7 @@ void reply_writeunlock(struct smb_request *req)
        NTSTATUS status = NT_STATUS_OK;
        files_struct *fsp;
        struct lock_struct lock;
+       int saved_errno = 0;
 
        START_PROFILE(SMBwriteunlock);
 
@@ -4003,18 +3986,24 @@ void reply_writeunlock(struct smb_request *req)
                nwritten = 0;
        } else {
                nwritten = write_file(req,fsp,data,startpos,numtowrite);
+               saved_errno = errno;
        }
 
        status = sync_file(conn, fsp, False /* write through */);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(5,("reply_writeunlock: sync_file for %s returned %s\n",
-                       fsp->fsp_name, nt_errstr(status) ));
+                        fsp_str_dbg(fsp), nt_errstr(status)));
                reply_nterror(req, status);
                goto strict_unlock;
        }
 
-       if(((nwritten < numtowrite) && (numtowrite != 0))||(nwritten < 0)) {
-               reply_unixerror(req, ERRHRD, ERRdiskfull);
+       if(nwritten < 0) {
+               reply_nterror(req, map_nt_error_from_unix(saved_errno));
+               goto strict_unlock;
+       }
+
+       if((nwritten < numtowrite) && (numtowrite != 0)) {
+               reply_doserror(req, ERRHRD, ERRdiskfull);
                goto strict_unlock;
        }
 
@@ -4065,6 +4054,7 @@ void reply_write(struct smb_request *req)
        files_struct *fsp;
        struct lock_struct lock;
        NTSTATUS status;
+       int saved_errno = 0;
 
        START_PROFILE(SMBwrite);
 
@@ -4136,13 +4126,18 @@ void reply_write(struct smb_request *req)
        status = sync_file(conn, fsp, False);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(5,("reply_write: sync_file for %s returned %s\n",
-                       fsp->fsp_name, nt_errstr(status) ));
+                        fsp_str_dbg(fsp), nt_errstr(status)));
                reply_nterror(req, status);
                goto strict_unlock;
        }
 
-       if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
-               reply_unixerror(req, ERRHRD, ERRdiskfull);
+       if(nwritten < 0) {
+               reply_nterror(req, map_nt_error_from_unix(saved_errno));
+               goto strict_unlock;
+       }
+
+       if((nwritten == 0) && (numtowrite != 0)) {
+               reply_doserror(req, ERRHRD, ERRdiskfull);
                goto strict_unlock;
        }
 
@@ -4389,8 +4384,13 @@ void reply_write_and_X(struct smb_request *req)
                nwritten = write_file(req,fsp,data,startpos,numtowrite);
        }
 
-       if(((nwritten == 0) && (numtowrite != 0))||(nwritten < 0)) {
-               reply_unixerror(req, ERRHRD, ERRdiskfull);
+       if(nwritten < 0) {
+               reply_nterror(req, map_nt_error_from_unix(errno));
+               goto strict_unlock;
+       }
+
+       if((nwritten == 0) && (numtowrite != 0)) {
+               reply_doserror(req, ERRHRD, ERRdiskfull);
                goto strict_unlock;
        }
 
@@ -4409,7 +4409,7 @@ void reply_write_and_X(struct smb_request *req)
        status = sync_file(conn, fsp, write_through);
        if (!NT_STATUS_IS_OK(status)) {
                DEBUG(5,("reply_write_and_X: sync_file for %s returned %s\n",
-                       fsp->fsp_name, nt_errstr(status) ));
+                        fsp_str_dbg(fsp), nt_errstr(status)));
                reply_nterror(req, status);
                goto strict_unlock;
        }
@@ -4484,8 +4484,8 @@ void reply_lseek(struct smb_request *req)
                                SMB_STRUCT_STAT sbuf;
 
                                if(SMB_VFS_FSTAT(fsp, &sbuf) == -1) {
-                                       reply_unixerror(req, ERRDOS,
-                                                       ERRnoaccess);
+                                       reply_nterror(req,
+                                               map_nt_error_from_unix(errno));
                                        END_PROFILE(SMBlseek);
                                        return;
                                }
@@ -4497,7 +4497,7 @@ void reply_lseek(struct smb_request *req)
                }
 
                if(res == -1) {
-                       reply_unixerror(req, ERRDOS, ERRnoaccess);
+                       reply_nterror(req, map_nt_error_from_unix(errno));
                        END_PROFILE(SMBlseek);
                        return;
                }
@@ -4545,7 +4545,7 @@ void reply_flush(struct smb_request *req)
                NTSTATUS status = sync_file(conn, fsp, True);
                if (!NT_STATUS_IS_OK(status)) {
                        DEBUG(5,("reply_flush: sync_file for %s returned %s\n",
-                               fsp->fsp_name, nt_errstr(status) ));
+                               fsp_str_dbg(fsp), nt_errstr(status)));
                        reply_nterror(req, status);
                        END_PROFILE(SMBflush);
                        return;
@@ -4713,8 +4713,8 @@ void reply_writeclose(struct smb_request *req)
         */
 
        if (numtowrite) {
-               DEBUG(3,("reply_writeclose: zero length write doesn't close file %s\n",
-                       fsp->fsp_name ));
+               DEBUG(3,("reply_writeclose: zero length write doesn't close "
+                        "file %s\n", fsp_str_dbg(fsp)));
                close_status = close_file(req, fsp, NORMAL_CLOSE);
        }
 
@@ -4868,7 +4868,6 @@ void reply_unlock(struct smb_request *req)
 
 void reply_tdis(struct smb_request *req)
 {
-       struct smbd_server_connection *sconn = smbd_server_conn;
        connection_struct *conn = req->conn;
        START_PROFILE(SMBtdis);
 
@@ -4881,7 +4880,7 @@ void reply_tdis(struct smb_request *req)
 
        conn->used = False;
 
-       close_cnum(sconn, conn,req->vuid);
+       close_cnum(conn,req->vuid);
        req->conn = NULL;
 
        reply_outbuf(req, 0, 0);
@@ -5197,7 +5196,7 @@ void reply_printwrite(struct smb_request *req)
        data = (const char *)req->buf + 3;
 
        if (write_file(req,fsp,data,-1,numtowrite) != numtowrite) {
-               reply_unixerror(req, ERRHRD, ERRdiskfull);
+               reply_nterror(req, map_nt_error_from_unix(errno));
                END_PROFILE(SMBsplwr);
                return;
        }
@@ -5232,8 +5231,9 @@ void reply_mkdir(struct smb_request *req)
        status = filename_convert(ctx, conn,
                                 req->flags2 & FLAGS2_DFS_PATHNAMES,
                                 directory,
-                                &smb_dname,
-                                NULL);
+                                0,
+                                NULL,
+                                &smb_dname);
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
                        reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
@@ -5540,8 +5540,9 @@ void reply_rmdir(struct smb_request *req)
        status = filename_convert(ctx, conn,
                                 req->flags2 & FLAGS2_DFS_PATHNAMES,
                                 directory,
-                                &smb_dname,
-                                NULL);
+                                0,
+                                NULL,
+                                &smb_dname);
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
                        reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
@@ -5711,7 +5712,6 @@ static void rename_open_files(connection_struct *conn,
 {
        files_struct *fsp;
        bool did_rename = False;
-       char *fname_dst = NULL;
        NTSTATUS status;
 
        for(fsp = file_find_di_first(lck->id); fsp;
@@ -5725,17 +5725,13 @@ static void rename_open_files(connection_struct *conn,
                }
                DEBUG(10, ("rename_open_files: renaming file fnum %d "
                           "(file_id %s) from %s -> %s\n", fsp->fnum,
-                          file_id_string_tos(&fsp->file_id), fsp->fsp_name,
+                          file_id_string_tos(&fsp->file_id), fsp_str_dbg(fsp),
                           smb_fname_str_dbg(smb_fname_dst)));
 
-               status = get_full_smb_filename(talloc_tos(), smb_fname_dst,
-                                              &fname_dst);
-               if (!NT_STATUS_IS_OK(status)) {
-                       return;
+               status = fsp_set_smb_fname(fsp, smb_fname_dst);
+               if (NT_STATUS_IS_OK(status)) {
+                       did_rename = True;
                }
-               string_set(&fsp->fsp_name, fname_dst);
-               did_rename = True;
-               TALLOC_FREE(fname_dst);
        }
 
        if (!did_rename) {
@@ -5790,9 +5786,6 @@ static void notify_rename(connection_struct *conn, bool is_dir,
 {
        char *parent_dir_src = NULL;
        char *parent_dir_dst = NULL;
-       char *fname_src = NULL;
-       char *fname_dst = NULL;
-       NTSTATUS status;
        uint32 mask;
 
        mask = is_dir ? FILE_NOTIFY_CHANGE_DIR_NAME
@@ -5805,24 +5798,17 @@ static void notify_rename(connection_struct *conn, bool is_dir,
                goto out;
        }
 
-       status = get_full_smb_filename(talloc_tos(), smb_fname_src,
-                                      &fname_src);
-       if (!NT_STATUS_IS_OK(status)) {
-               goto out;
-       }
-       status = get_full_smb_filename(talloc_tos(), smb_fname_dst,
-                                      &fname_dst);
-       if (!NT_STATUS_IS_OK(status)) {
-               goto out;
-       }
-
        if (strcmp(parent_dir_src, parent_dir_dst) == 0) {
-               notify_fname(conn, NOTIFY_ACTION_OLD_NAME, mask, fname_src);
-               notify_fname(conn, NOTIFY_ACTION_NEW_NAME, mask, fname_dst);
+               notify_fname(conn, NOTIFY_ACTION_OLD_NAME, mask,
+                            smb_fname_src->base_name);
+               notify_fname(conn, NOTIFY_ACTION_NEW_NAME, mask,
+                            smb_fname_dst->base_name);
        }
        else {
-               notify_fname(conn, NOTIFY_ACTION_REMOVED, mask, fname_src);
-               notify_fname(conn, NOTIFY_ACTION_ADDED, mask, fname_dst);
+               notify_fname(conn, NOTIFY_ACTION_REMOVED, mask,
+                            smb_fname_src->base_name);
+               notify_fname(conn, NOTIFY_ACTION_ADDED, mask,
+                            smb_fname_dst->base_name);
        }
 
        /* this is a strange one. w2k3 gives an additional event for
@@ -5832,13 +5818,11 @@ static void notify_rename(connection_struct *conn, bool is_dir,
                notify_fname(conn, NOTIFY_ACTION_MODIFIED,
                             FILE_NOTIFY_CHANGE_ATTRIBUTES
                             |FILE_NOTIFY_CHANGE_CREATION,
-                            fname_dst);
+                            smb_fname_dst->base_name);
        }
  out:
        TALLOC_FREE(parent_dir_src);
        TALLOC_FREE(parent_dir_dst);
-       TALLOC_FREE(fname_src);
-       TALLOC_FREE(fname_dst);
 }
 
 /****************************************************************************
@@ -5867,17 +5851,12 @@ NTSTATUS rename_internals_fsp(connection_struct *conn,
        }
 
        /* Make a copy of the src and dst smb_fname structs */
-       status = copy_smb_filename(ctx, smb_fname_dst_in, &smb_fname_dst);
+       status = copy_smb_filename(ctx, fsp->fsp_name, &smb_fname_src);
        if (!NT_STATUS_IS_OK(status)) {
                goto out;
        }
 
-       /*
-        * This will be replaced with copy_smb_filename() when fsp->fsp_name
-        * is converted to store an smb_filename struct.
-        */
-       status = create_synthetic_smb_fname_split(ctx, fsp->fsp_name, NULL,
-                                                 &smb_fname_src);
+       status = copy_smb_filename(ctx, smb_fname_dst_in, &smb_fname_dst);
        if (!NT_STATUS_IS_OK(status)) {
                goto out;
        }
@@ -6135,16 +6114,14 @@ NTSTATUS rename_internals_fsp(connection_struct *conn,
 NTSTATUS rename_internals(TALLOC_CTX *ctx,
                        connection_struct *conn,
                        struct smb_request *req,
-                       const char *name_in,
-                       const char *newname_in,
+                       struct smb_filename *smb_fname_src,
+                       struct smb_filename *smb_fname_dst,
                        uint32 attrs,
                        bool replace_if_exists,
                        bool src_has_wild,
                        bool dest_has_wild,
                        uint32_t access_mask)
 {
-       struct smb_filename *smb_fname_src = NULL;
-       struct smb_filename *smb_fname_dst = NULL;
        char *fname_src_dir = NULL;
        char *fname_src_mask = NULL;
        int count=0;
@@ -6155,19 +6132,6 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx,
        int create_options = 0;
        bool posix_pathnames = lp_posix_pathnames();
 
-       status = unix_convert(ctx, conn, name_in, &smb_fname_src,
-                             src_has_wild ? UCF_ALLOW_WCARD_LCOMP : 0);
-       if (!NT_STATUS_IS_OK(status)) {
-               goto out;
-       }
-
-       status = unix_convert(ctx, conn, newname_in, &smb_fname_dst,
-                             (UCF_SAVE_LCOMP |
-                              (dest_has_wild ? UCF_ALLOW_WCARD_LCOMP : 0)));
-       if (!NT_STATUS_IS_OK(status)) {
-               goto out;
-       }
-
        /*
         * Split the old name into directory and last component
         * strings. Note that unix_convert may have stripped off a
@@ -6468,8 +6432,6 @@ NTSTATUS rename_internals(TALLOC_CTX *ctx,
        }
 
  out:
-       TALLOC_FREE(smb_fname_src);
-       TALLOC_FREE(smb_fname_dst);
        TALLOC_FREE(fname_src_dir);
        TALLOC_FREE(fname_src_mask);
        return status;
@@ -6490,13 +6452,14 @@ void reply_mv(struct smb_request *req)
        bool src_has_wcard = False;
        bool dest_has_wcard = False;
        TALLOC_CTX *ctx = talloc_tos();
+       struct smb_filename *smb_fname_src = NULL;
+       struct smb_filename *smb_fname_dst = NULL;
 
        START_PROFILE(SMBmv);
 
        if (req->wct < 1) {
                reply_nterror(req, NT_STATUS_INVALID_PARAMETER);
-               END_PROFILE(SMBmv);
-               return;
+               goto out;
        }
 
        attrs = SVAL(req->vwv+0, 0);
@@ -6506,69 +6469,71 @@ void reply_mv(struct smb_request *req)
                                       &status, &src_has_wcard);
        if (!NT_STATUS_IS_OK(status)) {
                reply_nterror(req, status);
-               END_PROFILE(SMBmv);
-               return;
+               goto out;
        }
        p++;
        p += srvstr_get_path_req_wcard(ctx, req, &newname, p, STR_TERMINATE,
                                       &status, &dest_has_wcard);
        if (!NT_STATUS_IS_OK(status)) {
                reply_nterror(req, status);
-               END_PROFILE(SMBmv);
-               return;
+               goto out;
        }
 
-       status = resolve_dfspath_wcard(ctx, conn,
-                                      req->flags2 & FLAGS2_DFS_PATHNAMES,
-                                      name,
-                                      &name,
-                                      &src_has_wcard);
+       status = filename_convert(ctx,
+                                 conn,
+                                 req->flags2 & FLAGS2_DFS_PATHNAMES,
+                                 name,
+                                 UCF_COND_ALLOW_WCARD_LCOMP,
+                                 &src_has_wcard,
+                                 &smb_fname_src);
+
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
                        reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
                                        ERRSRV, ERRbadpath);
-                       END_PROFILE(SMBmv);
-                       return;
+                       goto out;
                }
                reply_nterror(req, status);
-               END_PROFILE(SMBmv);
-               return;
+               goto out;
        }
 
-       status = resolve_dfspath_wcard(ctx, conn,
-                                      req->flags2 & FLAGS2_DFS_PATHNAMES,
-                                      newname,
-                                      &newname,
-                                      &dest_has_wcard);
+       status = filename_convert(ctx,
+                                 conn,
+                                 req->flags2 & FLAGS2_DFS_PATHNAMES,
+                                 newname,
+                                 UCF_COND_ALLOW_WCARD_LCOMP | UCF_SAVE_LCOMP,
+                                 &dest_has_wcard,
+                                 &smb_fname_dst);
+
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
                        reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
                                        ERRSRV, ERRbadpath);
-                       END_PROFILE(SMBmv);
-                       return;
+                       goto out;
                }
                reply_nterror(req, status);
-               END_PROFILE(SMBmv);
-               return;
+               goto out;
        }
 
-       DEBUG(3,("reply_mv : %s -> %s\n",name,newname));
+       DEBUG(3,("reply_mv : %s -> %s\n", smb_fname_str_dbg(smb_fname_src),
+                smb_fname_str_dbg(smb_fname_dst)));
 
-       status = rename_internals(ctx, conn, req, name, newname, attrs, False,
-                                 src_has_wcard, dest_has_wcard, DELETE_ACCESS);
+       status = rename_internals(ctx, conn, req, smb_fname_src, smb_fname_dst,
+                                 attrs, False, src_has_wcard, dest_has_wcard,
+                                 DELETE_ACCESS);
        if (!NT_STATUS_IS_OK(status)) {
                if (open_was_deferred(req->mid)) {
                        /* We have re-scheduled this call. */
-                       END_PROFILE(SMBmv);
-                       return;
+                       goto out;
                }
                reply_nterror(req, status);
-               END_PROFILE(SMBmv);
-               return;
+               goto out;
        }
 
        reply_outbuf(req, 0, 0);
-
+ out:
+       TALLOC_FREE(smb_fname_src);
+       TALLOC_FREE(smb_fname_dst);
        END_PROFILE(SMBmv);
        return;
 }
@@ -6635,8 +6600,8 @@ NTSTATUS copy_file(TALLOC_CTX *ctx,
        if (!target_is_directory && count) {
                new_create_disposition = FILE_OPEN;
        } else {
-               if (!map_open_params_to_ntcreate(smb_fname_dst_tmp->base_name,
-                                                0, ofun, NULL, NULL,
+               if (!map_open_params_to_ntcreate(smb_fname_dst_tmp, 0, ofun,
+                                                NULL, NULL,
                                                 &new_create_disposition,
                                                 NULL)) {
                        status = NT_STATUS_INVALID_PARAMETER;
@@ -6756,7 +6721,6 @@ void reply_copy(struct smb_request *req)
        const char *p;
        int count=0;
        int error = ERRnoaccess;
-       int err = 0;
        int tid2;
        int ofun;
        int flags;
@@ -6800,11 +6764,12 @@ void reply_copy(struct smb_request *req)
                goto out;
        }
 
-       status = resolve_dfspath_wcard(ctx, conn,
-                                      req->flags2 & FLAGS2_DFS_PATHNAMES,
-                                      fname_src,
-                                      &fname_src,
-                                      &source_has_wild);
+       status = filename_convert(ctx, conn,
+                                 req->flags2 & FLAGS2_DFS_PATHNAMES,
+                                 fname_src,
+                                 UCF_COND_ALLOW_WCARD_LCOMP,
+                                 &source_has_wild,
+                                 &smb_fname_src);
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
                        reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
@@ -6815,11 +6780,12 @@ void reply_copy(struct smb_request *req)
                goto out;
        }
 
-       status = resolve_dfspath_wcard(ctx, conn,
-                                      req->flags2 & FLAGS2_DFS_PATHNAMES,
-                                      fname_dst,
-                                      &fname_dst,
-                                      &dest_has_wild);
+       status = filename_convert(ctx, conn,
+                                 req->flags2 & FLAGS2_DFS_PATHNAMES,
+                                 fname_dst,
+                                 UCF_COND_ALLOW_WCARD_LCOMP,
+                                 &dest_has_wild,
+                                 &smb_fname_dst);
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
                        reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
@@ -6830,20 +6796,6 @@ void reply_copy(struct smb_request *req)
                goto out;
        }
 
-       status = unix_convert(ctx, conn, fname_src, &smb_fname_src,
-                             source_has_wild ? UCF_ALLOW_WCARD_LCOMP : 0);
-       if (!NT_STATUS_IS_OK(status)) {
-               reply_nterror(req, status);
-               goto out;
-       }
-
-       status = unix_convert(ctx, conn, fname_dst, &smb_fname_dst,
-                             dest_has_wild ? UCF_ALLOW_WCARD_LCOMP : 0);
-       if (!NT_STATUS_IS_OK(status)) {
-               reply_nterror(req, status);
-               goto out;
-       }
-
        target_is_directory = VALID_STAT_OF_DIR(smb_fname_dst->st);
 
        if ((flags&1) && target_is_directory) {
@@ -7059,13 +7011,6 @@ void reply_copy(struct smb_request *req)
        }
 
        if (count == 0) {
-               if(err) {
-                       /* Error on close... */
-                       errno = err;
-                       reply_unixerror(req, ERRHRD, ERRgeneral);
-                       goto out;
-               }
-
                reply_doserror(req, ERRDOS, error);
                goto out;
        }
@@ -7249,7 +7194,7 @@ NTSTATUS smbd_do_locking(struct smb_request *req,
                          (double)e->offset,
                          (double)e->count,
                          (unsigned int)e->smbpid,
-                         fsp->fsp_name));
+                         fsp_str_dbg(fsp)));
 
                if (e->brltype != UNLOCK_LOCK) {
                        /* this can only happen with SMB2 */
@@ -7288,7 +7233,7 @@ NTSTATUS smbd_do_locking(struct smb_request *req,
                          (double)e->offset,
                          (double)e->count,
                          (unsigned int)e->smbpid,
-                         fsp->fsp_name,
+                         fsp_str_dbg(fsp),
                          (int)timeout));
 
                if (type & LOCKING_ANDX_CANCEL_LOCK) {
@@ -7504,7 +7449,8 @@ void reply_lockingX(struct smb_request *req)
                        DEBUG(5,("reply_lockingX: Error : oplock break from "
                                 "client for fnum = %d (oplock=%d) and no "
                                 "oplock granted on this file (%s).\n",
-                                fsp->fnum, fsp->oplock_type, fsp->fsp_name));
+                                fsp->fnum, fsp->oplock_type,
+                                fsp_str_dbg(fsp)));
 
                        /* if this is a pure oplock break request then don't
                         * send a reply */
@@ -7527,7 +7473,7 @@ void reply_lockingX(struct smb_request *req)
 
                if (!result) {
                        DEBUG(0, ("reply_lockingX: error in removing "
-                                 "oplock on file %s\n", fsp->fsp_name));
+                                 "oplock on file %s\n", fsp_str_dbg(fsp)));
                        /* Hmmm. Is this panic justified? */
                        smb_panic("internal tdb error");
                }
@@ -7684,7 +7630,6 @@ void reply_readbs(struct smb_request *req)
 void reply_setattrE(struct smb_request *req)
 {
        connection_struct *conn = req->conn;
-       struct smb_filename *smb_fname = NULL;
        struct smb_file_time ft;
        files_struct *fsp;
        NTSTATUS status;
@@ -7704,14 +7649,6 @@ void reply_setattrE(struct smb_request *req)
                goto out;
        }
 
-       /* XXX: Remove when fsp->fsp_name is converted to smb_filename. */
-       status = create_synthetic_smb_fname_split(talloc_tos(), fsp->fsp_name,
-                                                 NULL, &smb_fname);
-       if (!NT_STATUS_IS_OK(status)) {
-               reply_nterror(req, status);
-               goto out;
-       }
-
        /*
         * Convert the DOS times into unix times.
         */
@@ -7732,7 +7669,7 @@ void reply_setattrE(struct smb_request *req)
 
        /* Ensure we have a valid stat struct for the source. */
        if (fsp->fh->fd != -1) {
-               if (SMB_VFS_FSTAT(fsp, &smb_fname->st) == -1) {
+               if (SMB_VFS_FSTAT(fsp, &fsp->fsp_name->st) == -1) {
                        status = map_nt_error_from_unix(errno);
                        reply_nterror(req, status);
                        goto out;
@@ -7741,9 +7678,9 @@ void reply_setattrE(struct smb_request *req)
                int ret = -1;
 
                if (fsp->posix_open) {
-                       ret = SMB_VFS_LSTAT(conn, smb_fname);
+                       ret = SMB_VFS_LSTAT(conn, fsp->fsp_name);
                } else {
-                       ret = SMB_VFS_STAT(conn, smb_fname);
+                       ret = SMB_VFS_STAT(conn, fsp->fsp_name);
                }
                if (ret == -1) {
                        status = map_nt_error_from_unix(errno);
@@ -7752,7 +7689,7 @@ void reply_setattrE(struct smb_request *req)
                }
        }
 
-       status = smb_set_file_time(conn, fsp, smb_fname, &ft, true);
+       status = smb_set_file_time(conn, fsp, fsp->fsp_name, &ft, true);
        if (!NT_STATUS_IS_OK(status)) {
                reply_doserror(req, ERRDOS, ERRnoaccess);
                goto out;
@@ -7812,8 +7749,6 @@ void reply_getattrE(struct smb_request *req)
        int mode;
        files_struct *fsp;
        struct timespec create_ts;
-       struct smb_filename *smb_fname = NULL;
-       NTSTATUS status;
 
        START_PROFILE(SMBgetattrE);
 
@@ -7833,21 +7768,14 @@ void reply_getattrE(struct smb_request *req)
 
        /* Do an fstat on this file */
        if(fsp_stat(fsp, &sbuf)) {
-               reply_unixerror(req, ERRDOS, ERRnoaccess);
+               reply_nterror(req, map_nt_error_from_unix(errno));
                END_PROFILE(SMBgetattrE);
                return;
        }
 
-       status = create_synthetic_smb_fname_split(talloc_tos(), fsp->fsp_name,
-                                                 &sbuf, &smb_fname);
-       if (!NT_STATUS_IS_OK(status)) {
-               reply_nterror(req, status);
-               END_PROFILE(SMBgetattrE);
-               return;
-       }
+       fsp->fsp_name->st = sbuf;
 
-       mode = dos_mode(conn, smb_fname);
-       TALLOC_FREE(smb_fname);
+       mode = dos_mode(conn, fsp->fsp_name);
 
        /*
         * Convert the times into dos times. Set create