From 59c450635773210bb8fca79a6cfc74d23a097bd5 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Sat, 16 Jun 2007 18:54:13 +0000 Subject: r23524: Fix bug 2319. Got report this is all ok form a tester. Close a loong standing bug preventing people to freely use any character in their password when printing via cups were involved. (This used to be commit 54ca011212982cf1d94a76ca9d39c391783da04f) --- source3/client/smbspool.c | 73 ++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 60 insertions(+), 13 deletions(-) (limited to 'source3/client/smbspool.c') diff --git a/source3/client/smbspool.c b/source3/client/smbspool.c index 5783cbe138..89863cc0ff 100644 --- a/source3/client/smbspool.c +++ b/source3/client/smbspool.c @@ -47,6 +47,7 @@ static void list_devices(void); static struct cli_state *smb_complete_connection(const char *, const char *,int , const char *, const char *, const char *, const char *, int); static struct cli_state *smb_connect(const char *, const char *, int, const char *, const char *, const char *, const char *); static int smb_print(struct cli_state *, char *, FILE *); +static char * uri_unescape_alloc(const char *); /* @@ -62,8 +63,9 @@ static int smb_print(struct cli_state *, char *, FILE *); int port; /* Port number */ char uri[1024], /* URI */ *sep, /* Pointer to separator */ + *tmp, *tmp2, /* Temp pointers to do escaping */ *password; /* Password */ - const char *username, /* Username */ + char *username, /* Username */ *server, /* Server name */ *printer; /* Printer name */ const char *workgroup; /* Workgroup */ @@ -152,19 +154,24 @@ static int smb_print(struct cli_state *, char *, FILE *); if ((sep = strrchr_m(uri, '@')) != NULL) { - username = uri + 6; + tmp = uri + 6; *sep++ = '\0'; + /* username is in tmp */ + server = sep; /* * Extract password as needed... */ - if ((password = strchr_m(username, ':')) != NULL) - *password++ = '\0'; - else + if ((tmp2 = strchr_m(tmp, ':')) != NULL) { + *tmp2++ = '\0'; + password = uri_unescape_alloc(tmp2); + } else { password = null_str; + } + username = uri_unescape_alloc(tmp); } else { @@ -173,16 +180,18 @@ static int smb_print(struct cli_state *, char *, FILE *); server = uri + 6; } - if ((sep = strchr_m(server, '/')) == NULL) + tmp = server; + + if ((sep = strchr_m(tmp, '/')) == NULL) { fputs("ERROR: Bad URI - need printer name!\n", stderr); return (1); } *sep++ = '\0'; - printer = sep; + tmp2 = sep; - if ((sep = strchr_m(printer, '/')) != NULL) + if ((sep = strchr_m(tmp2, '/')) != NULL) { /* * Convert to smb://[username:password@]workgroup/server/printer... @@ -190,12 +199,15 @@ static int smb_print(struct cli_state *, char *, FILE *); *sep++ = '\0'; - workgroup = server; - server = printer; - printer = sep; + workgroup = uri_unescape_alloc(tmp); + server = uri_unescape_alloc(tmp2); + printer = uri_unescape_alloc(sep); } - else + else { workgroup = NULL; + server = uri_unescape_alloc(tmp); + printer = uri_unescape_alloc(tmp2); + } if ((sep = strrchr_m(server, ':')) != NULL) { @@ -203,7 +215,7 @@ static int smb_print(struct cli_state *, char *, FILE *); port=atoi(sep); } - else + else port=0; @@ -588,3 +600,38 @@ smb_print(struct cli_state *cli, /* I - SMB connection */ else return (0); } + +static char *uri_unescape_alloc(const char *uritok) +{ + char *t, *ret; + const char *p; + long int val; + char eval[3]; + + ret = (char *)SMB_MALLOC(strlen(uritok)+1); + + if (!ret) return NULL; + + eval[2] = '\0'; + + for (p = uritok, t = ret; *p; p++, t++) { + if (*p == '%') { /* unescape hex */ + p++; + eval[0] = *p; + p++; + eval[1] = *p; + val = strtol(eval, NULL, 16); + if ((val == LONG_MIN || val == LONG_MAX) && errno == ERANGE) { + SAFE_FREE(ret); + return NULL; + } + *t = (char)val; + } else { + *t = *p; + } + } + + *t = '\0'; /*terminate*/ + + return ret; +} -- cgit