The Samba-Bugzilla – Attachment 13711 Details for
Bug 13093
smbclient doesn't correctly canonicalize all local names before use.
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Updated git-am fix for master.
bug-13093 (text/plain), 17.87 KB, created by
Jeremy Allison
on 2017-10-21 00:16:19 UTC
(
hide
)
Description:
Updated git-am fix for master.
Filename:
MIME Type:
Creator:
Jeremy Allison
Created:
2017-10-21 00:16:19 UTC
Size:
17.87 KB
patch
obsolete
>From db9e4150ff5c29ee67cef5649149835df2593d00 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Sat, 21 Oct 2017 00:08:08 +0000 >Subject: [PATCH 1/2] 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> >--- > 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 *, >-- >2.15.0.rc0.271.g36b669edcc-goog > > >From 4c3476e091620046af0a5fd275decdc876b807d0 Mon Sep 17 00:00:00 2001 >From: Jeremy Allison <jra@samba.org> >Date: Fri, 20 Oct 2017 15:09:38 -0700 >Subject: [PATCH 2/2] s3: smbclient: Ensure we call client_clean_name() before > all operations on remote pathnames. > >This allows names containing .. components to be resolved on the client side >before being sent to the server. Relative names work in SMB1 but not in SMB2. >Fix both client.c and clitar.c > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=13093 > >Signed-off-by: Jeremy Allison <jra@samba.org> >--- > source3/client/client.c | 204 ++++++++++++++++++++++++++++++++++++++++++++++-- > source3/client/clitar.c | 31 ++++++++ > 2 files changed, 227 insertions(+), 8 deletions(-) > >diff --git a/source3/client/client.c b/source3/client/client.c >index 8cc511983cb..8f449e81311 100644 >--- a/source3/client/client.c >+++ b/source3/client/client.c >@@ -430,7 +430,7 @@ static int do_cd(const char *new_dir) > } > client_set_cur_dir(new_cd); > >- new_cd = clean_name(ctx, new_cd); >+ new_cd = client_clean_name(ctx, new_cd); > client_set_cur_dir(new_cd); > > status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(), >@@ -474,7 +474,7 @@ static int do_cd(const char *new_dir) > client_set_cur_dir(saved_dir); > goto out; > } >- targetpath = clean_name(ctx, targetpath); >+ targetpath = client_clean_name(ctx, targetpath); > if (!targetpath) { > client_set_cur_dir(saved_dir); > goto out; >@@ -984,6 +984,11 @@ static int cmd_dir(void) > return 1; > } > >+ mask = client_clean_name(ctx, mask); >+ if (mask == NULL) { >+ return 1; >+ } >+ > if (showacls) { > /* cwd is only used if showacls is on */ > client_set_cwd(client_get_cur_dir()); >@@ -1036,6 +1041,14 @@ static int cmd_du(void) > } else { > mask = talloc_strdup(ctx, "*"); > } >+ if (!mask) { >+ return 1; >+ } >+ >+ mask = client_clean_name(ctx, mask); >+ if (mask == NULL) { >+ return 1; >+ } > > status = do_list(mask, attribute, do_du, recurse, true); > if (!NT_STATUS_IS_OK(status)) { >@@ -1232,7 +1245,7 @@ static int cmd_get(void) > if (!rname) { > return 1; > } >- rname = clean_name(ctx, rname); >+ rname = client_clean_name(ctx, rname); > if (!rname) { > return 1; > } >@@ -1298,6 +1311,10 @@ static NTSTATUS do_mget(struct cli_state *cli_state, struct file_info *finfo, > if (!rname) { > return NT_STATUS_NO_MEMORY; > } >+ rname = client_clean_name(ctx, rname); >+ if (rname == NULL) { >+ return NT_STATUS_NO_MEMORY; >+ } > do_get(rname, finfo->name, false); > TALLOC_FREE(rname); > return NT_STATUS_OK; >@@ -1317,6 +1334,10 @@ static NTSTATUS do_mget(struct cli_state *cli_state, struct file_info *finfo, > if (!new_cd) { > return NT_STATUS_NO_MEMORY; > } >+ new_cd = client_clean_name(ctx, new_cd); >+ if (new_cd == NULL) { >+ return NT_STATUS_NO_MEMORY; >+ } > client_set_cur_dir(new_cd); > > string_replace(finfo->name,'\\','/'); >@@ -1347,6 +1368,10 @@ static NTSTATUS do_mget(struct cli_state *cli_state, struct file_info *finfo, > return NT_STATUS_NO_MEMORY; > } > >+ mget_mask = client_clean_name(ctx, mget_mask); >+ if (mget_mask == NULL) { >+ return NT_STATUS_NO_MEMORY; >+ } > status = do_list(mget_mask, > (FILE_ATTRIBUTE_SYSTEM > | FILE_ATTRIBUTE_HIDDEN >@@ -1416,7 +1441,7 @@ static int cmd_more(void) > if (!rname) { > return 1; > } >- rname = clean_name(ctx,rname); >+ rname = client_clean_name(ctx,rname); > if (!rname) { > return 1; > } >@@ -1474,6 +1499,10 @@ static int cmd_mget(void) > if (!mget_mask) { > return 1; > } >+ mget_mask = client_clean_name(ctx, mget_mask); >+ if (mget_mask == NULL) { >+ return 1; >+ } > status = do_list(mget_mask, attribute, do_mget, false, true); > if (!NT_STATUS_IS_OK(status)) { > return 1; >@@ -1492,6 +1521,10 @@ static int cmd_mget(void) > if (!mget_mask) { > return 1; > } >+ mget_mask = client_clean_name(ctx, mget_mask); >+ if (mget_mask == NULL) { >+ return 1; >+ } > status = do_list(mget_mask, attribute, do_mget, false, true); > if (!NT_STATUS_IS_OK(status)) { > return 1; >@@ -1588,6 +1621,10 @@ static int cmd_mkdir(void) > if (!mask) { > return 1; > } >+ mask = client_clean_name(ctx, mask); >+ if (mask == NULL) { >+ return 1; >+ } > > if (recurse) { > char *ddir = NULL; >@@ -1659,6 +1696,10 @@ static int cmd_altname(void) > if (!name) { > return 1; > } >+ name = client_clean_name(ctx, name); >+ if (name == NULL) { >+ return 1; >+ } > do_altname(name); > return 0; > } >@@ -1889,7 +1930,10 @@ static int cmd_allinfo(void) > if (!name) { > return 1; > } >- >+ name = client_clean_name(ctx, name); >+ if (name == NULL) { >+ return 1; >+ } > do_allinfo(name); > > return 0; >@@ -2052,7 +2096,7 @@ static int cmd_put(void) > return 1; > } > >- rname = clean_name(ctx, rname); >+ rname = client_clean_name(ctx, rname); > if (!rname) { > return 1; > } >@@ -2261,6 +2305,19 @@ static int cmd_mput(void) > break; > } > normalize_name(rname); >+ { >+ char *tmp_rname = >+ client_clean_name(ctx, rname); >+ if (tmp_rname == NULL) { >+ break; >+ } >+ SAFE_FREE(rname); >+ rname = smb_xstrdup(tmp_rname); >+ TALLOC_FREE(tmp_rname); >+ if (rname == NULL) { >+ break; >+ } >+ } > if (!NT_STATUS_IS_OK(cli_chkpath(cli, rname)) && > !do_mkdir(rname)) { > DEBUG (0, ("Unable to make dir, skipping...")); >@@ -2291,6 +2348,18 @@ static int cmd_mput(void) > > normalize_name(rname); > >+ { >+ char *tmp_rname = client_clean_name(ctx, rname); >+ if (tmp_rname == NULL) { >+ break; >+ } >+ SAFE_FREE(rname); >+ rname = smb_xstrdup(tmp_rname); >+ TALLOC_FREE(tmp_rname); >+ if (rname == NULL) { >+ break; >+ } >+ } > do_put(rname, lname, false); > } > free_file_list(file_list); >@@ -2461,6 +2530,10 @@ static int cmd_del(void) > if (!mask) { > return 1; > } >+ mask = client_clean_name(ctx, mask); >+ if (mask == NULL) { >+ return 1; >+ } > > status = do_list(mask,attribute,do_del,false,false); > if (!NT_STATUS_IS_OK(status)) { >@@ -2577,6 +2650,10 @@ static int cmd_deltree(void) > if (mask == NULL) { > return 1; > } >+ mask = client_clean_name(ctx, mask); >+ if (mask == NULL) { >+ return 1; >+ } > > deltree_list_head = NULL; > >@@ -2678,6 +2755,10 @@ static int cmd_wdel(void) > if (!mask) { > return 1; > } >+ mask = client_clean_name(ctx, mask); >+ if (mask == NULL) { >+ return 1; >+ } > > status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(), > cli, mask, &targetcli, &targetname); >@@ -2719,6 +2800,11 @@ static int cmd_open(void) > return 1; > } > >+ mask = client_clean_name(ctx, mask); >+ if (mask == NULL) { >+ return 1; >+ } >+ > status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(), > cli, mask, &targetcli, &targetname); > if (!NT_STATUS_IS_OK(status)) { >@@ -2834,6 +2920,10 @@ static int cmd_posix_open(void) > if (!mask) { > return 1; > } >+ mask = client_clean_name(ctx, mask); >+ if (mask == NULL) { >+ return 1; >+ } > > if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) { > d_printf("posix_open <filename> 0<mode>\n"); >@@ -2889,6 +2979,10 @@ static int cmd_posix_mkdir(void) > if (!mask) { > return 1; > } >+ mask = client_clean_name(ctx, mask); >+ if (mask == NULL) { >+ return 1; >+ } > > if (!next_token_talloc(ctx, &cmd_ptr,&buf,NULL)) { > d_printf("posix_mkdir <filename> 0<mode>\n"); >@@ -2933,6 +3027,10 @@ static int cmd_posix_unlink(void) > if (!mask) { > return 1; > } >+ mask = client_clean_name(ctx, mask); >+ if (mask == NULL) { >+ return 1; >+ } > > status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(), > cli, mask, &targetcli, &targetname); >@@ -2972,6 +3070,10 @@ static int cmd_posix_rmdir(void) > if (!mask) { > return 1; > } >+ mask = client_clean_name(ctx, mask); >+ if (mask == NULL) { >+ return 1; >+ } > > status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(), > cli, mask, &targetcli, &targetname); >@@ -3274,6 +3376,10 @@ static int cmd_rmdir(void) > if (!mask) { > return 1; > } >+ mask = client_clean_name(ctx, mask); >+ if (mask == NULL) { >+ return 1; >+ } > > status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(), > cli, mask, &targetcli, &targetname); >@@ -3318,6 +3424,10 @@ static int cmd_link(void) > if (!oldname) { > return 1; > } >+ oldname = client_clean_name(ctx, oldname); >+ if (oldname == NULL) { >+ return 1; >+ } > newname = talloc_asprintf(ctx, > "%s%s", > client_get_cur_dir(), >@@ -3325,6 +3435,10 @@ static int cmd_link(void) > if (!newname) { > return 1; > } >+ newname = client_clean_name(ctx, newname); >+ if (newname == NULL) { >+ return 1; >+ } > > status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(), > cli, oldname, &targetcli, &targetname); >@@ -3372,6 +3486,10 @@ static int cmd_readlink(void) > if (!name) { > return 1; > } >+ name = client_clean_name(ctx, name); >+ if (name == NULL) { >+ return 1; >+ } > > status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(), > cli, name, &targetcli, &targetname); >@@ -3426,6 +3544,10 @@ static int cmd_symlink(void) > if (!newname) { > return 1; > } >+ newname = client_clean_name(ctx, newname); >+ if (newname == NULL) { >+ return 1; >+ } > /* New name must be present in share namespace. */ > status = cli_resolve_path(ctx, "", > popt_get_cmdline_auth_info(), cli, newname, >@@ -3477,6 +3599,10 @@ static int cmd_chmod(void) > if (!src) { > return 1; > } >+ src = client_clean_name(ctx, src); >+ if (src == NULL) { >+ return 1; >+ } > > mode = (mode_t)strtol(buf, NULL, 8); > >@@ -3636,6 +3762,10 @@ static int cmd_getfacl(void) > if (!src) { > return 1; > } >+ src = client_clean_name(ctx, src); >+ if (src == NULL) { >+ return 1; >+ } > > status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(), > cli, src, &targetcli, &targetname); >@@ -3804,6 +3934,10 @@ static int cmd_geteas(void) > if (!src) { > return 1; > } >+ src = client_clean_name(ctx, src); >+ if (src == NULL) { >+ return 1; >+ } > > status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(), > cli, src, &targetcli, &targetname); >@@ -3861,6 +3995,10 @@ static int cmd_setea(void) > if (!src) { > return 1; > } >+ src = client_clean_name(ctx, src); >+ if (src == NULL) { >+ return 1; >+ } > > status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(), > cli, src, &targetcli, &targetname); >@@ -3907,6 +4045,10 @@ static int cmd_stat(void) > if (!src) { > return 1; > } >+ src = client_clean_name(ctx, src); >+ if (src == NULL) { >+ return 1; >+ } > > status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(), > cli, src, &targetcli, &targetname); >@@ -4016,6 +4158,10 @@ static int cmd_chown(void) > if (!src) { > return 1; > } >+ src = client_clean_name(ctx, src); >+ if (src == NULL) { >+ return 1; >+ } > status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(), > cli, src, &targetcli, &targetname); > if (!NT_STATUS_IS_OK(status)) { >@@ -4066,6 +4212,10 @@ static int cmd_rename(void) > if (!src) { > return 1; > } >+ src = client_clean_name(ctx, src); >+ if (src == NULL) { >+ return 1; >+ } > > dest = talloc_asprintf(ctx, > "%s%s", >@@ -4074,6 +4224,10 @@ static int cmd_rename(void) > if (!dest) { > return 1; > } >+ dest = client_clean_name(ctx, dest); >+ if (dest == NULL) { >+ return 1; >+ } > > if (next_token_talloc(ctx, &cmd_ptr, &buf, NULL) && > strcsequal(buf, "-f")) { >@@ -4159,6 +4313,10 @@ static int cmd_scopy(void) > if (!src) { > return 1; > } >+ src = client_clean_name(ctx, src); >+ if (src == NULL) { >+ return 1; >+ } > > dest = talloc_asprintf(ctx, > "%s%s", >@@ -4167,6 +4325,10 @@ static int cmd_scopy(void) > if (!dest) { > return 1; > } >+ dest = client_clean_name(ctx, dest); >+ if (dest == NULL) { >+ return 1; >+ } > > status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(), > cli, src, &targetcli, &targetsrc); >@@ -4289,6 +4451,10 @@ static int cmd_hardlink(void) > if (!src) { > return 1; > } >+ src = client_clean_name(ctx, src); >+ if (src == NULL) { >+ return 1; >+ } > > dest = talloc_asprintf(ctx, > "%s%s", >@@ -4297,6 +4463,10 @@ static int cmd_hardlink(void) > if (!dest) { > return 1; > } >+ dest = client_clean_name(ctx, dest); >+ if (dest == NULL) { >+ return 1; >+ } > > status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(), > cli, src, &targetcli, &targetname); >@@ -4376,6 +4546,10 @@ static int cmd_notify(void) > if (name == NULL) { > goto fail; > } >+ name = client_clean_name(talloc_tos(), name); >+ if (name == NULL) { >+ return 1; >+ } > status = cli_ntcreate( > cli, name, 0, FILE_READ_DATA, 0, > FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, >@@ -4550,7 +4724,7 @@ static int cmd_reget(void) > if (!remote_name) { > return 1; > } >- remote_name = clean_name(ctx,remote_name); >+ remote_name = client_clean_name(ctx,remote_name); > if (!remote_name) { > return 1; > } >@@ -4602,7 +4776,7 @@ static int cmd_reput(void) > return 1; > } > >- remote_name = clean_name(ctx, remote_name); >+ remote_name = client_clean_name(ctx, remote_name); > if (!remote_name) { > return 1; > } >@@ -5038,6 +5212,11 @@ static int cmd_utimes(void) > err = 1; > goto out; > } >+ fname = client_clean_name(ctx, fname); >+ if (fname == NULL) { >+ err = 1; >+ goto out; >+ } > > while (next_token_talloc(ctx, &cmd_ptr, &buf, NULL) && > time_count < 4) { >@@ -5161,6 +5340,11 @@ int cmd_setmode(void) > err = 1; > goto out; > } >+ fname = client_clean_name(ctx, fname); >+ if (fname == NULL) { >+ err = 1; >+ goto out; >+ } > > while (next_token_talloc(ctx, &cmd_ptr, &buf, NULL)) { > const char *s = buf; >@@ -5671,6 +5855,10 @@ static char **remote_completion(const char *text, int len) > if (!dirmask) { > goto cleanup; > } >+ dirmask = client_clean_name(ctx, dirmask); >+ if (dirmask == NULL) { >+ goto cleanup; >+ } > > status = cli_resolve_path(ctx, "", popt_get_cmdline_auth_info(), > cli, dirmask, &targetcli, &targetpath); >diff --git a/source3/client/clitar.c b/source3/client/clitar.c >index eff79698315..b8009c92cb6 100644 >--- a/source3/client/clitar.c >+++ b/source3/client/clitar.c >@@ -699,6 +699,11 @@ static int tar_create(struct tar* t) > err = 1; > goto out_close; > } >+ mask = client_clean_name(ctx, mask); >+ if (mask == NULL) { >+ err = 1; >+ goto out_close; >+ } > DBG(5, ("tar_process do_list with mask: %s\n", mask)); > status = do_list(mask, TAR_DO_LIST_ATTR, get_file_callback, false, true); > if (!NT_STATUS_IS_OK(status)) { >@@ -764,6 +769,11 @@ static int tar_create_from_list(struct tar *t) > err = 1; > goto out; > } >+ mask = client_clean_name(ctx, mask); >+ if (mask == NULL) { >+ err = 1; >+ goto out; >+ } > > DBG(5, ("incl. path='%s', base='%s', mask='%s'\n", > path, base ? base : "NULL", mask)); >@@ -775,6 +785,12 @@ static int tar_create_from_list(struct tar *t) > err = 1; > goto out; > } >+ base = client_clean_name(ctx, base); >+ if (base == NULL) { >+ err = 1; >+ goto out; >+ } >+ > DBG(5, ("cd '%s' before do_list\n", base)); > client_set_cur_dir(base); > } >@@ -820,6 +836,11 @@ static NTSTATUS get_file_callback(struct cli_state *cli, > status = NT_STATUS_NO_MEMORY; > goto out; > } >+ remote_name = client_clean_name(ctx, remote_name); >+ if (remote_name == NULL) { >+ status = NT_STATUS_NO_MEMORY; >+ goto out; >+ } > > if (strequal(finfo->name, "..") || strequal(finfo->name, ".")) { > goto out; >@@ -853,6 +874,11 @@ static NTSTATUS get_file_callback(struct cli_state *cli, > status = NT_STATUS_NO_MEMORY; > goto out; > } >+ mask = client_clean_name(ctx, mask); >+ if (mask == NULL) { >+ status = NT_STATUS_NO_MEMORY; >+ goto out; >+ } > > rc = tar_get_file(&tar_ctx, remote_name, finfo); > if (rc != 0) { >@@ -1112,6 +1138,11 @@ static int tar_send_file(struct tar *t, struct archive_entry *entry) > err = 1; > goto out; > } >+ full_path = client_clean_name(ctx, full_path); >+ if (full_path == NULL) { >+ err = 1; >+ goto out; >+ } > > if (mode != AE_IFREG && mode != AE_IFDIR) { > DBG(0, ("Skipping non-dir & non-regular file %s\n", full_path)); >-- >2.15.0.rc0.271.g36b669edcc-goog >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 13093
:
13709
|
13710
|
13711
|
13718
|
13719
|
13720