From d4d9d1941bdac9993968c34cf928c645e4152fd3 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sat, 21 Oct 2017 00:08:08 +0000 Subject: [PATCH] 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 Reviewed-by: Andreas Schneider --- source3/client/client.c | 31 +++++++++++++++++++++++++++++++ source3/client/client_proto.h | 1 + 2 files changed, 32 insertions(+) diff --git a/source3/client/client.c b/source3/client/client.c index df16496ff86..8cc511983cb 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -345,6 +345,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 *,