summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2017-10-21 00:08:08 +0000
committerKarolin Seeger <kseeger@samba.org>2017-11-01 10:49:25 +0100
commitf3f306c672eaeccb0d3b61b5c5f1f34fd7c542c8 (patch)
treec5501c6f43f77988a46eb81a74b43d57f0ca3945
parent5e1abab6af20f71334018164ba21307c439bbef2 (diff)
downloadsamba-f3f306c672eaeccb0d3b61b5c5f1f34fd7c542c8.tar.gz
s3: client: Add new utility function client_clean_name().
Correctly canonicalizes a remote pathname removing '..' elements before sending to a remote server. '..' elements work in SMB1 pathnames, but not in SMB2. Not yet used. BUG: https://bugzilla.samba.org/show_bug.cgi?id=13093 Signed-off-by: Jeremy Allison <jra@samba.org> Reviewed-by: Andreas Schneider <asn@samba.org> (cherry picked from commit d4d9d1941bdac9993968c34cf928c645e4152fd3)
-rw-r--r--source3/client/client.c31
-rw-r--r--source3/client/client_proto.h1
2 files changed, 32 insertions, 0 deletions
diff --git a/source3/client/client.c b/source3/client/client.c
index 5ef9ad52151..dd008081df9 100644
--- a/source3/client/client.c
+++ b/source3/client/client.c
@@ -346,6 +346,37 @@ static void normalize_name(char *newdir)
}
/****************************************************************************
+ Local name cleanup before sending to server. SMB1 allows relative pathnames,
+ but SMB2 does not, so we need to resolve them locally.
+****************************************************************************/
+
+char *client_clean_name(TALLOC_CTX *ctx, const char *name)
+{
+ char *newname = NULL;
+ if (name == NULL) {
+ return NULL;
+ }
+
+ /* First ensure any path separators are correct. */
+ newname = talloc_strdup(ctx, name);
+ if (newname == NULL) {
+ return NULL;
+ }
+ normalize_name(newname);
+
+ /* Now remove any relative (..) path components. */
+ if (cli->requested_posix_capabilities & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
+ newname = unix_clean_name(ctx, newname);
+ } else {
+ newname = clean_name(ctx, newname);
+ }
+ if (newname == NULL) {
+ return NULL;
+ }
+ return newname;
+}
+
+/****************************************************************************
Change directory - inner section.
****************************************************************************/
diff --git a/source3/client/client_proto.h b/source3/client/client_proto.h
index d3d40363f20..38f13aa0adc 100644
--- a/source3/client/client_proto.h
+++ b/source3/client/client_proto.h
@@ -35,6 +35,7 @@ enum {
const char *client_get_cur_dir(void);
const char *client_set_cur_dir(const char *newdir);
+char *client_clean_name(TALLOC_CTX *ctx, const char *name);
NTSTATUS do_list(const char *mask,
uint16_t attribute,
NTSTATUS (*fn)(struct cli_state *cli_state, struct file_info *,