Replace the boilerplate calls to :
authorJeremy Allison <jra@samba.org>
Thu, 18 Jun 2009 20:13:38 +0000 (13:13 -0700)
committerJeremy Allison <jra@samba.org>
Thu, 18 Jun 2009 20:13:38 +0000 (13:13 -0700)
resolve_dfspath() -> unix_convert() -> get_full_smb_filename() -> check_name()
with a new function filename_convert().
This restores the check_name() calls that had gone missing
since the default create_file was changed. All "standard"
pathname processing now goes through filename_convert().
I'll take a look at the non-standard pathname processing
next. As a benefit, fixed a missing resolve_dfspath()
in the trans2 mkdir call.
Jeremy.

source3/include/proto.h
source3/smbd/filename.c
source3/smbd/nttrans.c
source3/smbd/reply.c
source3/smbd/smb2_create.c
source3/smbd/trans2.c

index 4ae141e89d5d2628d006a18ebde662a32fb1356a..6fc28259d69430db4764c3c8911c525b997f8e06 100644 (file)
@@ -6384,6 +6384,12 @@ NTSTATUS check_name(connection_struct *conn, const char *name);
 int get_real_filename(connection_struct *conn, const char *path,
                      const char *name, TALLOC_CTX *mem_ctx,
                      char **found_name);
+NTSTATUS filename_convert(TALLOC_CTX *mem_ctx,
+                       connection_struct *conn,
+                       bool dfs_path,
+                       const char *name_in,
+                       struct smb_filename **pp_smb_fname,
+                       char **pp_name);
 
 /* The following definitions come from smbd/files.c  */
 
@@ -7078,8 +7084,8 @@ void send_trans2_replies(connection_struct *conn,
 unsigned char *create_volume_objectid(connection_struct *conn, unsigned char objid[16]);
 NTSTATUS hardlink_internals(TALLOC_CTX *ctx,
                connection_struct *conn,
-               const char *oldname_in,
-               const char *newname_in);
+               const struct smb_filename *smb_fname_old,
+               const struct smb_filename *smb_fname_new);
 NTSTATUS smb_set_file_time(connection_struct *conn,
                           files_struct *fsp,
                           const char *fname,
index 456caf590bc2f2c2728d7aa5537f8d5c05e227fb..e1e54549f787f86a22cfab1184fdadc689c650d6 100644 (file)
@@ -1150,3 +1150,55 @@ static NTSTATUS build_stream_path(TALLOC_CTX *mem_ctx,
        TALLOC_FREE(streams);
        return status;
 }
+
+/****************************************************************************
+ Go through all the steps to validate a filename.
+****************************************************************************/
+
+NTSTATUS filename_convert(TALLOC_CTX *ctx,
+                               connection_struct *conn,
+                               bool dfs_path,
+                               const char *name_in,
+                               struct smb_filename **pp_smb_fname,
+                               char **pp_name)
+{
+       NTSTATUS status;
+
+       *pp_smb_fname = NULL;
+       *pp_name = NULL;
+
+       status = resolve_dfspath(ctx, conn,
+                               dfs_path,
+                               name_in,
+                               pp_name);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(10,("filename_convert: resolve_dfspath failed "
+                       "for name %s with %s\n",
+                       name_in,
+                       nt_errstr(status) ));
+               return status;
+       }
+       status = unix_convert(ctx, conn, *pp_name, pp_smb_fname, 0);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(10,("filename_convert: unix_convert failed "
+                       "for name %s with %s\n",
+                       *pp_name,
+                       nt_errstr(status) ));
+               return status;
+       }
+
+       status = get_full_smb_filename(ctx, *pp_smb_fname, pp_name);
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       }
+
+       status = check_name(conn, *pp_name);
+       if (!NT_STATUS_IS_OK(status)) {
+               DEBUG(3,("filename_convert: check_name failed "
+                       "for name %s with %s\n",
+                       *pp_name,
+                       nt_errstr(status) ));
+               return status;
+       }
+       return status;
+}
index c4d0374e9998e2e36350fb9a1a62c1dd506e7242..73c062e69feffbc2f51e8ab39f069d365d726807 100644 (file)
@@ -535,10 +535,11 @@ void reply_ntcreate_and_X(struct smb_request *req)
                        ? BATCH_OPLOCK : 0;
        }
 
-       status = resolve_dfspath(ctx,
+       status = filename_convert(ctx,
                                conn,
                                req->flags2 & FLAGS2_DFS_PATHNAMES,
                                fname,
+                               &smb_fname,
                                &fname);
 
        if (!NT_STATUS_IS_OK(status)) {
@@ -552,12 +553,6 @@ void reply_ntcreate_and_X(struct smb_request *req)
                goto out;
        }
 
-       status = unix_convert(ctx, conn, fname, &smb_fname, 0);
-       if (!NT_STATUS_IS_OK(status)) {
-               reply_nterror(req, status);
-               goto out;
-       }
-
        status = SMB_VFS_CREATE_FILE(
                conn,                                   /* conn */
                req,                                    /* req */
@@ -1021,10 +1016,11 @@ static void call_nt_transact_create(connection_struct *conn,
                goto out;
        }
 
-       status = resolve_dfspath(ctx,
+       status = filename_convert(ctx,
                                conn,
                                req->flags2 & FLAGS2_DFS_PATHNAMES,
                                fname,
+                               &smb_fname,
                                &fname);
 
        if (!NT_STATUS_IS_OK(status)) {
@@ -1038,12 +1034,6 @@ static void call_nt_transact_create(connection_struct *conn,
                goto out;
        }
 
-       status = unix_convert(ctx, conn, fname, &smb_fname, 0);
-       if (!NT_STATUS_IS_OK(status)) {
-               reply_nterror(req, status);
-               goto out;
-       }
-
        oplock_request = (flags & REQUEST_OPLOCK) ? EXCLUSIVE_OPLOCK : 0;
        if (oplock_request) {
                oplock_request |= (flags & REQUEST_BATCH_OPLOCK)
@@ -1399,6 +1389,8 @@ static NTSTATUS copy_internals(TALLOC_CTX *ctx,
 void reply_ntrename(struct smb_request *req)
 {
        connection_struct *conn = req->conn;
+       struct smb_filename *smb_fname_old = NULL;
+       struct smb_filename *smb_fname_new = NULL;
        char *oldname = NULL;
        char *newname = NULL;
        const char *p;
@@ -1444,9 +1436,10 @@ void reply_ntrename(struct smb_request *req)
                return;
        }
 
-       status = resolve_dfspath(ctx, conn,
+       status = filename_convert(ctx, conn,
                                req->flags2 & FLAGS2_DFS_PATHNAMES,
                                oldname,
+                               &smb_fname_old,
                                &oldname);
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
@@ -1460,9 +1453,10 @@ void reply_ntrename(struct smb_request *req)
                return;
        }
 
-       status = resolve_dfspath(ctx, conn,
+       status = filename_convert(ctx, conn,
                                req->flags2 & FLAGS2_DFS_PATHNAMES,
                                newname,
+                               &smb_fname_new,
                                &newname);
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
@@ -1498,8 +1492,8 @@ void reply_ntrename(struct smb_request *req)
                        } else {
                                status = hardlink_internals(ctx,
                                                conn,
-                                               oldname,
-                                               newname);
+                                               smb_fname_old,
+                                               smb_fname_new);
                        }
                        break;
                case RENAME_FLAG_COPY:
index 996cba208b9c032ea7d36eee8d5231079d8f667b..f11f3bfed7d62863de8c35b8c793c545c02f3471 100644 (file)
@@ -987,10 +987,15 @@ void reply_checkpath(struct smb_request *req)
                return;
        }
 
-       status = resolve_dfspath(ctx, conn,
-                       req->flags2 & FLAGS2_DFS_PATHNAMES,
-                       name,
-                       &name);
+       DEBUG(3,("reply_checkpath %s mode=%d\n", name, (int)SVAL(req->vwv+0, 0)));
+
+       status = filename_convert(ctx,
+                               conn,
+                               req->flags2 & FLAGS2_DFS_PATHNAMES,
+                               name,
+                               &smb_fname,
+                               &name);
+
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
                        reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
@@ -1001,24 +1006,6 @@ void reply_checkpath(struct smb_request *req)
                goto path_err;
        }
 
-       DEBUG(3,("reply_checkpath %s mode=%d\n", name, (int)SVAL(req->vwv+0, 0)));
-
-       status = unix_convert(ctx, conn, name, &smb_fname, 0);
-       if (!NT_STATUS_IS_OK(status)) {
-               goto path_err;
-       }
-
-       status = get_full_smb_filename(ctx, smb_fname, &name);
-       if (!NT_STATUS_IS_OK(status)) {
-               goto path_err;
-       }
-
-       status = check_name(conn, name);
-       if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(3,("reply_checkpath: check_name of %s failed (%s)\n",name,nt_errstr(status)));
-               goto path_err;
-       }
-
        if (!VALID_STAT(smb_fname->st) &&
            (SMB_VFS_STAT(conn, name, &smb_fname->st) != 0)) {
                DEBUG(3,("reply_checkpath: stat of %s failed (%s)\n",name,strerror(errno)));
@@ -1091,20 +1078,6 @@ void reply_getatr(struct smb_request *req)
                goto out;
        }
 
-       status = resolve_dfspath(ctx, conn,
-                               req->flags2 & FLAGS2_DFS_PATHNAMES,
-                               fname,
-                               &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);
-                       goto out;
-               }
-               reply_nterror(req, status);
-               goto out;
-       }
-
        /* dos smetimes asks for a stat of "" - it returns a "hidden directory"
                under WfWg - weird! */
        if (*fname == '\0') {
@@ -1115,19 +1088,18 @@ void reply_getatr(struct smb_request *req)
                size = 0;
                mtime = 0;
        } else {
-               status = unix_convert(ctx, conn, fname, &smb_fname, 0);
-               if (!NT_STATUS_IS_OK(status)) {
-                       reply_nterror(req, status);
-                       goto out;
-               }
-               status = get_full_smb_filename(ctx, smb_fname, &fname);
-               if (!NT_STATUS_IS_OK(status)) {
-                       reply_nterror(req, status);
-                       goto out;
-               }
-               status = check_name(conn, fname);
+               status = filename_convert(ctx,
+                               conn,
+                               req->flags2 & FLAGS2_DFS_PATHNAMES,
+                               fname,
+                               &smb_fname,
+                               &fname);
                if (!NT_STATUS_IS_OK(status)) {
-                       DEBUG(3,("reply_getatr: check_name of %s failed (%s)\n",fname,nt_errstr(status)));
+                       if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
+                               reply_botherror(req, NT_STATUS_PATH_NOT_COVERED,
+                                               ERRSRV, ERRbadpath);
+                               goto out;
+                       }
                        reply_nterror(req, status);
                        goto out;
                }
@@ -1201,9 +1173,11 @@ void reply_setatr(struct smb_request *req)
                goto out;
        }
 
-       status = resolve_dfspath(ctx, conn,
+       status = filename_convert(ctx,
+                               conn,
                                req->flags2 & FLAGS2_DFS_PATHNAMES,
                                fname,
+                               &smb_fname,
                                &fname);
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
@@ -1215,24 +1189,6 @@ void reply_setatr(struct smb_request *req)
                goto out;
        }
 
-       status = unix_convert(ctx, conn, fname, &smb_fname, 0);
-       if (!NT_STATUS_IS_OK(status)) {
-               reply_nterror(req, status);
-               goto out;
-       }
-
-       status = get_full_smb_filename(ctx, smb_fname, &fname);
-       if (!NT_STATUS_IS_OK(status)) {
-               reply_nterror(req, status);
-               goto out;
-       }
-
-       status = check_name(conn, fname);
-       if (!NT_STATUS_IS_OK(status)) {
-               reply_nterror(req, status);
-               goto out;
-       }
-
        if (fname[0] == '.' && fname[1] == '\0') {
                /*
                 * Not sure here is the right place to catch this
@@ -1769,10 +1725,11 @@ void reply_open(struct smb_request *req)
                goto out;
        }
 
-       status = resolve_dfspath(ctx,
+       status = filename_convert(ctx,
                                conn,
                                req->flags2 & FLAGS2_DFS_PATHNAMES,
                                fname,
+                               &smb_fname,
                                &fname);
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
@@ -1785,12 +1742,6 @@ void reply_open(struct smb_request *req)
                goto out;
        }
 
-       status = unix_convert(ctx, conn, fname, &smb_fname, 0);
-       if (!NT_STATUS_IS_OK(status)) {
-               reply_nterror(req, status);
-               goto out;
-       }
-
        if (!map_open_params_to_ntcreate(
                    fname, deny_mode, OPENX_FILE_EXISTS_OPEN, &access_mask,
                    &share_mode, &create_disposition, &create_options)) {
@@ -1930,10 +1881,11 @@ void reply_open_and_X(struct smb_request *req)
                goto out;
        }
 
-       status = resolve_dfspath(ctx,
+       status = filename_convert(ctx,
                                conn,
                                req->flags2 & FLAGS2_DFS_PATHNAMES,
                                fname,
+                               &smb_fname,
                                &fname);
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
@@ -1946,12 +1898,6 @@ void reply_open_and_X(struct smb_request *req)
                goto out;
        }
 
-       status = unix_convert(ctx, conn, fname, &smb_fname, 0);
-       if (!NT_STATUS_IS_OK(status)) {
-               reply_nterror(req, status);
-               goto out;
-       }
-
        if (!map_open_params_to_ntcreate(
                    fname, deny_mode, smb_ofun, &access_mask,
                    &share_mode, &create_disposition, &create_options)) {
@@ -2143,10 +2089,11 @@ void reply_mknew(struct smb_request *req)
                goto out;
        }
 
-       status = resolve_dfspath(ctx,
+       status = filename_convert(ctx,
                                conn,
                                req->flags2 & FLAGS2_DFS_PATHNAMES,
                                fname,
+                               &smb_fname,
                                &fname);
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
@@ -2159,12 +2106,6 @@ void reply_mknew(struct smb_request *req)
                goto out;
        }
 
-       status = unix_convert(ctx, conn, fname, &smb_fname, 0);
-       if (!NT_STATUS_IS_OK(status)) {
-               reply_nterror(req, status);
-               goto out;
-       }
-
        if (fattr & aVOLID) {
                DEBUG(0,("Attempt to create file (%s) with volid set - "
                        "please report this\n", fname));
@@ -2281,9 +2222,10 @@ void reply_ctemp(struct smb_request *req)
                goto out;
        }
 
-       status = resolve_dfspath(ctx, conn,
+       status = filename_convert(ctx, conn,
                                req->flags2 & FLAGS2_DFS_PATHNAMES,
                                fname,
+                               &smb_fname,
                                &fname);
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
@@ -2295,18 +2237,6 @@ void reply_ctemp(struct smb_request *req)
                goto out;
        }
 
-       status = unix_convert(ctx, conn, fname, &smb_fname, 0);
-       if (!NT_STATUS_IS_OK(status)) {
-               reply_nterror(req, status);
-               goto out;
-       }
-
-       status = check_name(conn, smb_fname->base_name);
-       if (!NT_STATUS_IS_OK(status)) {
-               reply_nterror(req, status);
-               goto out;
-       }
-
        tmpfd = mkstemp(smb_fname->base_name);
        if (tmpfd == -1) {
                reply_unixerror(req, ERRDOS, ERRnoaccess);
@@ -5263,9 +5193,10 @@ void reply_mkdir(struct smb_request *req)
                goto out;
        }
 
-       status = resolve_dfspath(ctx, conn,
+       status = filename_convert(ctx, conn,
                                 req->flags2 & FLAGS2_DFS_PATHNAMES,
                                 directory,
+                                &smb_dname,
                                 &directory);
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
@@ -5277,18 +5208,6 @@ void reply_mkdir(struct smb_request *req)
                goto out;
        }
 
-       status = unix_convert(ctx, conn, directory, &smb_dname, 0);
-       if (!NT_STATUS_IS_OK(status)) {
-               reply_nterror(req, status);
-               goto out;
-       }
-
-       status = check_name(conn, smb_dname->base_name);
-       if (!NT_STATUS_IS_OK(status)) {
-               reply_nterror(req, status);
-               goto out;
-       }
-
        status = create_directory(conn, req, smb_dname);
 
        DEBUG(5, ("create_directory returned %s\n", nt_errstr(status)));
@@ -5535,9 +5454,10 @@ void reply_rmdir(struct smb_request *req)
                goto out;
        }
 
-       status = resolve_dfspath(ctx, conn,
+       status = filename_convert(ctx, conn,
                                 req->flags2 & FLAGS2_DFS_PATHNAMES,
                                 directory,
+                                &smb_dname,
                                 &directory);
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
@@ -5549,24 +5469,6 @@ void reply_rmdir(struct smb_request *req)
                goto out;
        }
 
-       status = unix_convert(ctx, conn, directory, &smb_dname, 0);
-       if (!NT_STATUS_IS_OK(status)) {
-               reply_nterror(req, status);
-               goto out;
-       }
-
-       status = get_full_smb_filename(ctx, smb_dname, &directory);
-       if (!NT_STATUS_IS_OK(status)) {
-               reply_nterror(req, status);
-               goto out;
-       }
-
-       status = check_name(conn, directory);
-       if (!NT_STATUS_IS_OK(status)) {
-               reply_nterror(req, status);
-               goto out;
-       }
-
        dptr_closepath(directory, req->smbpid);
        status = rmdir_internals(ctx, conn, directory);
        if (!NT_STATUS_IS_OK(status)) {
index 81879f1725a4028e31dcafd2a5242e88cada0031..0e3cd164cd9216cf3caf6335e097def32c579e1e 100644 (file)
@@ -315,23 +315,17 @@ static struct tevent_req *smbd_smb2_create_send(TALLOC_CTX *mem_ctx,
                in_create_options &= ~(0x10);/* NTCREATEX_OPTIONS_SYNC_ALERT */
                in_create_options &= ~(0x20);/* NTCREATEX_OPTIONS_ASYNC_ALERT */
 
-               status = resolve_dfspath(talloc_tos(),
+               status = filename_convert(talloc_tos(),
                                        smbreq->conn,
                                        smbreq->flags2 & FLAGS2_DFS_PATHNAMES,
                                        in_name,
+                                       &smb_fname,
                                        &fname);
                if (!NT_STATUS_IS_OK(status)) {
                        tevent_req_nterror(req, status);
                        goto out;
                }
 
-               status = unix_convert(talloc_tos(), smbreq->conn, fname,
-                                     &smb_fname, 0);
-               if (!NT_STATUS_IS_OK(status)) {
-                       tevent_req_nterror(req, status);
-                       goto out;
-               }
-
                status = SMB_VFS_CREATE_FILE(smbreq->conn,
                                             smbreq,
                                             0, /* root_dir_fid */
index f275b94772f3e0b910316c5651eaf1a3e0d6cd12..ca90c5ae699218a44c85f882a78c069444915ebd 100644 (file)
@@ -941,10 +941,11 @@ static void call_trans2open(connection_struct *conn,
                fname, (unsigned int)deny_mode, (unsigned int)open_attr,
                (unsigned int)open_ofun, open_size));
 
-       status = resolve_dfspath(ctx,
+       status = filename_convert(ctx,
                                conn,
                                req->flags2 & FLAGS2_DFS_PATHNAMES,
                                fname,
+                               &smb_fname,
                                &fname);
        if (!NT_STATUS_IS_OK(status)) {
                if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
@@ -957,12 +958,6 @@ static void call_trans2open(connection_struct *conn,
                goto out;
        }
 
-       status = unix_convert(ctx, conn, fname, &smb_fname, 0);
-       if (!NT_STATUS_IS_OK(status)) {
-               reply_nterror(req, status);
-               goto out;
-       }
-
        if (open_ofun == 0) {
                reply_nterror(req, NT_STATUS_OBJECT_NAME_COLLISION);
                goto out;
@@ -3993,10 +3988,11 @@ static void call_trans2qfilepathinfo(connection_struct *conn,
                        return;
                }
 
-               status = resolve_dfspath(ctx,
+               status = filename_convert(ctx,
                                        conn,
                                        req->flags2 & FLAGS2_DFS_PATHNAMES,
                                        fname,
+                                       &smb_fname,
                                        &fname);
                if (!NT_STATUS_IS_OK(status)) {
                        if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
@@ -4009,27 +4005,8 @@ static void call_trans2qfilepathinfo(connection_struct *conn,
                        return;
                }
 
-               status = unix_convert(ctx, conn, fname, &smb_fname, 0);
-               if (!NT_STATUS_IS_OK(status)) {
-                       reply_nterror(req, status);
-                       return;
-               }
                sbuf = smb_fname->st;
 
-               status = get_full_smb_filename(ctx, smb_fname, &fname);
-               TALLOC_FREE(smb_fname);
-               if (!NT_STATUS_IS_OK(status)) {
-                       reply_nterror(req, status);
-                       return;
-               }
-
-               status = check_name(conn, fname);
-               if (!NT_STATUS_IS_OK(status)) {
-                       DEBUG(3,("call_trans2qfilepathinfo: fileinfo of %s failed (%s)\n",fname,nt_errstr(status)));
-                       reply_nterror(req, status);
-                       return;
-               }
-
                if ((conn->fs_capabilities & FILE_NAMED_STREAMS)
                    && is_ntfs_stream_name(fname)) {
                        char *base;
@@ -4855,65 +4832,33 @@ total_data=%u (should be %u)\n", (unsigned int)total_data, (unsigned int)IVAL(pd
 
 NTSTATUS hardlink_internals(TALLOC_CTX *ctx,
                connection_struct *conn,
-               const char *oldname_in,
-               const char *newname_in)
+               const struct smb_filename *smb_fname_old,
+               const struct smb_filename *smb_fname_new)
 {
-       struct smb_filename *smb_fname = NULL;
-       struct smb_filename *smb_fname_new = NULL;
        char *oldname = NULL;
        char *newname = NULL;
        NTSTATUS status = NT_STATUS_OK;
 
-       status = unix_convert(ctx, conn, oldname_in, &smb_fname, 0);
-       if (!NT_STATUS_IS_OK(status)) {
-               goto out;
-       }
-
-       status = get_full_smb_filename(ctx, smb_fname, &oldname);
-       if (!NT_STATUS_IS_OK(status)) {
-               goto out;
-       }
-
-       status = check_name(conn, oldname);
-       if (!NT_STATUS_IS_OK(status)) {
-               goto out;
-       }
-
        /* source must already exist. */
-       if (!VALID_STAT(smb_fname->st)) {
-               status = NT_STATUS_OBJECT_NAME_NOT_FOUND;
-               goto out;
-       }
-
-       status = unix_convert(ctx, conn, newname_in, &smb_fname_new, 0);
-       if (!NT_STATUS_IS_OK(status)) {
-               goto out;
-       }
-
-       status = get_full_smb_filename(ctx, smb_fname_new, &newname);
-       if (!NT_STATUS_IS_OK(status)) {
-               goto out;
-       }
-
-       status = check_name(conn, newname);
-       if (!NT_STATUS_IS_OK(status)) {
-               goto out;
+       if (!VALID_STAT(smb_fname_old->st)) {
+               return NT_STATUS_OBJECT_NAME_NOT_FOUND;
        }
 
        /* Disallow if newname already exists. */
        if (VALID_STAT(smb_fname_new->st)) {
-               status = NT_STATUS_OBJECT_NAME_COLLISION;
-               goto out;
+               return NT_STATUS_OBJECT_NAME_COLLISION;
        }
 
        /* No links from a directory. */
-       if (S_ISDIR(smb_fname->st.st_ex_mode)) {
-               status = NT_STATUS_FILE_IS_A_DIRECTORY;
-               goto out;
+       if (S_ISDIR(smb_fname_old->st.st_ex_mode)) {
+               return NT_STATUS_FILE_IS_A_DIRECTORY;
        }
 
-       /* Ensure this is within the share. */
-       status = check_reduced_name(conn, oldname);
+       status = get_full_smb_filename(ctx, smb_fname_new, &newname);
+       if (!NT_STATUS_IS_OK(status)) {
+               goto out;
+       }
+       status = get_full_smb_filename(ctx, smb_fname_old, &oldname);
        if (!NT_STATUS_IS_OK(status)) {
                goto out;
        }
@@ -4926,8 +4871,8 @@ NTSTATUS hardlink_internals(TALLOC_CTX *ctx,
                                 nt_errstr(status), newname, oldname));
        }
  out:
-       TALLOC_FREE(smb_fname);
-       TALLOC_FREE(smb_fname_new);
+       TALLOC_FREE(newname);
+       TALLOC_FREE(oldname);
        return status;
 }
 
@@ -5389,9 +5334,10 @@ static NTSTATUS smb_set_file_unix_link(connection_struct *conn,
 static NTSTATUS smb_set_file_unix_hlink(connection_struct *conn,
                                        struct smb_request *req,
                                        const char *pdata, int total_data,
-                                       const char *fname)
+                                       const struct smb_filename *smb_fname_new)
 {
        char *oldname = NULL;
+       struct smb_filename *smb_fname_old = NULL;
        TALLOC_CTX *ctx = talloc_tos();
        NTSTATUS status = NT_STATUS_OK;
 
@@ -5406,18 +5352,20 @@ static NTSTATUS smb_set_file_unix_hlink(connection_struct *conn,
                return status;
        }
 
-       status = resolve_dfspath(ctx, conn,
+       DEBUG(10,("smb_set_file_unix_hlink: SMB_SET_FILE_UNIX_LINK doing hard link %s -> %s\n",
+               smb_fname_str_dbg(smb_fname_new), oldname));
+
+       status = filename_convert(ctx,
+                               conn,
                                req->flags2 & FLAGS2_DFS_PATHNAMES,
                                oldname,
+                               &smb_fname_old,
                                &oldname);
        if (!NT_STATUS_IS_OK(status)) {
                return status;
        }
 
-       DEBUG(10,("smb_set_file_unix_hlink: SMB_SET_FILE_UNIX_LINK doing hard link %s -> %s\n",
-               fname, oldname));
-
-       return hardlink_internals(ctx, conn, oldname, fname);
+       return hardlink_internals(ctx, conn, smb_fname_old, smb_fname_new);
 }
 
 /****************************************************************************
@@ -6883,9 +6831,10 @@ static void call_trans2setfilepathinfo(connection_struct *conn,
                        return;
                }
 
-               status = resolve_dfspath(ctx, conn,
+               status = filename_convert(ctx, conn,
                                         req->flags2 & FLAGS2_DFS_PATHNAMES,
                                         fname,
+                                        &smb_fname,
                                         &fname);
                if (!NT_STATUS_IS_OK(status)) {
                        if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
@@ -6898,26 +6847,8 @@ static void call_trans2setfilepathinfo(connection_struct *conn,
                        return;
                }
 
-               status = unix_convert(ctx, conn, fname, &smb_fname, 0);
-               if (!NT_STATUS_IS_OK(status)) {
-                       reply_nterror(req, status);
-                       return;
-               }
                sbuf = smb_fname->st;
 
-               status = get_full_smb_filename(ctx, smb_fname, &fname);
-               TALLOC_FREE(smb_fname);
-               if (!NT_STATUS_IS_OK(status)) {
-                       reply_nterror(req, status);
-                       return;
-               }
-
-               status = check_name(conn, fname);
-               if (!NT_STATUS_IS_OK(status)) {
-                       reply_nterror(req, status);
-                       return;
-               }
-
                if (INFO_LEVEL_IS_UNIX(info_level)) {
                        /*
                         * For CIFS UNIX extensions the target name may not exist.
@@ -7103,14 +7034,14 @@ static void call_trans2setfilepathinfo(connection_struct *conn,
 
                case SMB_SET_FILE_UNIX_HLINK:
                {
-                       if (tran_call != TRANSACT2_SETPATHINFO) {
+                       if (tran_call != TRANSACT2_SETPATHINFO || smb_fname == NULL) {
                                /* We must have a pathname for this. */
                                reply_nterror(req, NT_STATUS_INVALID_LEVEL);
                                return;
                        }
                        status = smb_set_file_unix_hlink(conn, req,
                                                         pdata, total_data,
-                                                        fname);
+                                                        smb_fname);
                        break;
                }
 
@@ -7251,18 +7182,23 @@ static void call_trans2mkdir(connection_struct *conn, struct smb_request *req,
 
        DEBUG(3,("call_trans2mkdir : name = %s\n", directory));
 
-       status = unix_convert(ctx, conn, directory, &smb_dname, 0);
-       if (!NT_STATUS_IS_OK(status)) {
-               reply_nterror(req, status);
-               return;
-       }
+       status = filename_convert(ctx,
+                               conn,
+                               req->flags2 & FLAGS2_DFS_PATHNAMES,
+                               directory,
+                               &smb_dname,
+                               &directory);
 
-       status = check_name(conn, smb_dname->base_name);
        if (!NT_STATUS_IS_OK(status)) {
-               DEBUG(5,("call_trans2mkdir error (%s)\n", nt_errstr(status)));
+               if (NT_STATUS_EQUAL(status,NT_STATUS_PATH_NOT_COVERED)) {
+                       reply_botherror(req,
+                               NT_STATUS_PATH_NOT_COVERED,
+                               ERRSRV, ERRbadpath);
+                       return;
+               }
                reply_nterror(req, status);
-               goto out;
-       }
+               return;
+        }
 
        /* Any data in this call is an EA list. */
        if (total_data && (total_data != 4) && !lp_ea_support(SNUM(conn))) {