summaryrefslogtreecommitdiffstats
path: root/source3/client/smbspool.c
diff options
context:
space:
mode:
authorSimo Sorce <idra@samba.org>2007-06-16 18:54:13 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:23:25 -0500
commit59c450635773210bb8fca79a6cfc74d23a097bd5 (patch)
tree60fbc77b9f60ca1f96c8415bc93448b4b1315b3e /source3/client/smbspool.c
parentc1a2e8f6da82b80a9d47bef633c17a8591c0cb3d (diff)
downloadsamba-59c450635773210bb8fca79a6cfc74d23a097bd5.tar.gz
samba-59c450635773210bb8fca79a6cfc74d23a097bd5.tar.xz
samba-59c450635773210bb8fca79a6cfc74d23a097bd5.zip
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)
Diffstat (limited to 'source3/client/smbspool.c')
-rw-r--r--source3/client/smbspool.c73
1 files changed, 60 insertions, 13 deletions
diff --git a/source3/client/smbspool.c b/source3/client/smbspool.c
index 5783cbe1381..89863cc0ff2 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;
+}