summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2009-06-18 13:13:38 -0700
committerJeremy Allison <jra@samba.org>2009-06-18 13:13:38 -0700
commit34267482d53cb559cc40c4ec2bee929c21b7886b (patch)
treedae973a4b11a0a7f3dd51e07a30f7a1065d7c6a6
parente7e98ba4807f3c4e0538b24ae0092f69383ae2d7 (diff)
downloadsamba-34267482d53cb559cc40c4ec2bee929c21b7886b.tar.gz
samba-34267482d53cb559cc40c4ec2bee929c21b7886b.tar.bz2
samba-34267482d53cb559cc40c4ec2bee929c21b7886b.zip
Replace the boilerplate calls to :
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.
-rw-r--r--source3/include/proto.h10
-rw-r--r--source3/smbd/filename.c52
-rw-r--r--source3/smbd/nttrans.c30
-rw-r--r--source3/smbd/reply.c168
-rw-r--r--source3/smbd/smb2_create.c10
-rw-r--r--source3/smbd/trans2.c154
6 files changed, 154 insertions, 270 deletions
diff --git a/source3/include/proto.h b/source3/include/proto.h
index 4ae141e89d..6fc28259d6 100644
--- a/source3/include/proto.h
+++ b/source3/include/proto.h
@@ -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,
diff --git a/source3/smbd/filename.c b/source3/smbd/filename.c
index 456caf590b..e1e54549f7 100644
--- a/source3/smbd/filename.c
+++ b/source3/smbd/filename.c
@@ -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;
+}
diff --git a/source3/smbd/nttrans.c b/source3/smbd/nttrans.c
index c4d0374e99..73c062e69f 100644
--- a/source3/smbd/nttrans.c
+++ b/source3/smbd/nttrans.c
@@ -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:
diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c
index 996cba208b..f11f3bfed7 100644
--- a/source3/smbd/reply.c
+++ b/source3/smbd/reply.c
@@ -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)) {
diff --git a/source3/smbd/smb2_create.c b/source3/smbd/smb2_create.c
index 81879f1725..0e3cd164cd 100644
--- a/source3/smbd/smb2_create.c
+++ b/source3/smbd/smb2_create.c
@@ -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 */
diff --git a/source3/smbd/trans2.c b/source3/smbd/trans2.c
index f275b94772..ca90c5ae69 100644
--- a/source3/smbd/trans2.c
+++ b/source3/smbd/trans2.c
@@ -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))) {