The branch, master has been updated via 3bfb53caa86ece1d7ff1bf3c7759f003203d4247 (commit) from ea85ceefa945f1fee2bb10441a3cc8e35216733b (commit)
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master - Log ----------------------------------------------------------------- commit 3bfb53caa86ece1d7ff1bf3c7759f003203d4247 Author: Jeremy Allison <[EMAIL PROTECTED]> Date: Wed Oct 1 16:40:41 2008 -0700 Fix bug #5080. Access to cups-printers via samba broken with cups 1.3.4, Unsupported character set. Cups 1.3.4 expects utf8 to be used in all messages to/from the server. We may be using a different character set so we need to use talloc utf8 push/pull functions in all communication. Needs more testing. Don't release until I've done a thorough test. I also have a version for 3.2.x. Jeremy. ----------------------------------------------------------------------- Summary of changes: source3/printing/print_cups.c | 341 ++++++++++++++++++++++++++++++----------- 1 files changed, 251 insertions(+), 90 deletions(-) Changeset truncated at 500 lines: diff --git a/source3/printing/print_cups.c b/source3/printing/print_cups.c index 97584cb..b46d83b 100644 --- a/source3/printing/print_cups.c +++ b/source3/printing/print_cups.c @@ -2,6 +2,7 @@ * Support code for the Common UNIX Printing System ("CUPS") * * Copyright 1999-2003 by Michael R Sweet. + * Copyright 2008 Jeremy Allison. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -17,6 +18,10 @@ * along with this program; if not, see <http://www.gnu.org/licenses/>. */ +/* + * JRA. Converted to utf8 pull/push. + */ + #include "includes.h" #include "printing.h" @@ -51,24 +56,23 @@ cups_passwd_cb(const char *prompt) /* I - Prompt */ return (NULL); } -static http_t *cups_connect(void) +static http_t *cups_connect(TALLOC_CTX *frame) { - http_t *http; - char *server, *p; + http_t *http = NULL; + char *server = NULL, *p = NULL; int port; int timeout = lp_cups_connection_timeout(); - - gotalarm = 0; - - if (timeout) { - CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig); - alarm(timeout); - } + size_t size; if (lp_cups_server() != NULL && strlen(lp_cups_server()) > 0) { - server = smb_xstrdup(lp_cups_server()); + if (!push_utf8_talloc(frame, &server, lp_cups_server(), &size)) { + return NULL; + } } else { - server = smb_xstrdup(cupsServer()); + server = talloc_strdup(frame,cupsServer()); + } + if (server) { + return NULL; } p = strchr(server, ':'); @@ -82,6 +86,13 @@ static http_t *cups_connect(void) DEBUG(10, ("connecting to cups server %s:%d\n", server, port)); + gotalarm = 0; + + if (timeout) { + CatchSignal(SIGALRM, SIGNAL_CAST gotalarm_sig); + alarm(timeout); + } + http = httpConnect(server, port); CatchSignal(SIGALRM, SIGNAL_CAST SIG_IGN); @@ -92,12 +103,12 @@ static http_t *cups_connect(void) server, port, strerror(errno))); } - SAFE_FREE(server); return http; } bool cups_cache_reload(void) { + TALLOC_CTX *frame = talloc_stackframe(); http_t *http = NULL; /* HTTP connection to server */ ipp_t *request = NULL, /* IPP Request */ *response = NULL; /* IPP Response */ @@ -111,6 +122,7 @@ bool cups_cache_reload(void) "printer-info" }; bool ret = False; + size_t size; DEBUG(5, ("reloading cups printcap cache\n")); @@ -124,7 +136,7 @@ bool cups_cache_reload(void) * Try to connect to the server... */ - if ((http = cups_connect()) == NULL) { + if ((http = cups_connect(frame)) == NULL) { goto out; } @@ -145,7 +157,7 @@ bool cups_cache_reload(void) language = cupsLangDefault(); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, - "attributes-charset", NULL, cupsLangEncoding(language)); + "attributes-charset", NULL, "utf-8"); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, language->language); @@ -185,12 +197,24 @@ bool cups_cache_reload(void) while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER) { if (strcmp(attr->name, "printer-name") == 0 && - attr->value_tag == IPP_TAG_NAME) - name = attr->values[0].string.text; + attr->value_tag == IPP_TAG_NAME) { + if (!pull_utf8_talloc(frame, + &name, + attr->values[0].string.text, + &size)) { + goto out; + } + } if (strcmp(attr->name, "printer-info") == 0 && - attr->value_tag == IPP_TAG_TEXT) - info = attr->values[0].string.text; + attr->value_tag == IPP_TAG_TEXT) { + if (!pull_utf8_talloc(frame, + &info, + attr->values[0].string.text, + &size)) { + goto out; + } + } attr = attr->next; } @@ -225,7 +249,7 @@ bool cups_cache_reload(void) request->request.op.request_id = 1; ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, - "attributes-charset", NULL, cupsLangEncoding(language)); + "attributes-charset", NULL, "utf-8"); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, language->language); @@ -265,12 +289,24 @@ bool cups_cache_reload(void) while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER) { if (strcmp(attr->name, "printer-name") == 0 && - attr->value_tag == IPP_TAG_NAME) - name = attr->values[0].string.text; + attr->value_tag == IPP_TAG_NAME) { + if (!pull_utf8_talloc(frame, + &name, + attr->values[0].string.text, + &size)) { + goto out; + } + } if (strcmp(attr->name, "printer-info") == 0 && - attr->value_tag == IPP_TAG_TEXT) - info = attr->values[0].string.text; + attr->value_tag == IPP_TAG_TEXT) { + if (!pull_utf8_talloc(frame, + &info, + attr->values[0].string.text, + &size)) { + goto out; + } + } attr = attr->next; } @@ -299,6 +335,7 @@ bool cups_cache_reload(void) if (http) httpClose(http); + TALLOC_FREE(frame); return ret; } @@ -309,13 +346,15 @@ bool cups_cache_reload(void) static int cups_job_delete(const char *sharename, const char *lprm_command, struct printjob *pjob) { + TALLOC_CTX *frame = talloc_stackframe(); int ret = 1; /* Return value */ http_t *http = NULL; /* HTTP connection to server */ ipp_t *request = NULL, /* IPP Request */ *response = NULL; /* IPP Response */ cups_lang_t *language = NULL; /* Default language */ + char *user = NULL; char uri[HTTP_MAX_URI]; /* printer-uri attribute */ - + size_t size; DEBUG(5,("cups_job_delete(%s, %p (%d))\n", sharename, pjob, pjob->sysjob)); @@ -329,7 +368,7 @@ static int cups_job_delete(const char *sharename, const char *lprm_command, stru * Try to connect to the server... */ - if ((http = cups_connect()) == NULL) { + if ((http = cups_connect(frame)) == NULL) { goto out; } @@ -351,7 +390,7 @@ static int cups_job_delete(const char *sharename, const char *lprm_command, stru language = cupsLangDefault(); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, - "attributes-charset", NULL, cupsLangEncoding(language)); + "attributes-charset", NULL, "utf-8"); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, language->language); @@ -360,8 +399,12 @@ static int cups_job_delete(const char *sharename, const char *lprm_command, stru ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri); + if (!push_utf8_talloc(frame, &user, pjob->user, &size)) { + goto out; + } + ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", - NULL, pjob->user); + NULL, user); /* * Do the request and get back a response... @@ -389,6 +432,7 @@ static int cups_job_delete(const char *sharename, const char *lprm_command, stru if (http) httpClose(http); + TALLOC_FREE(frame); return ret; } @@ -399,13 +443,15 @@ static int cups_job_delete(const char *sharename, const char *lprm_command, stru static int cups_job_pause(int snum, struct printjob *pjob) { + TALLOC_CTX *frame = talloc_stackframe(); int ret = 1; /* Return value */ http_t *http = NULL; /* HTTP connection to server */ ipp_t *request = NULL, /* IPP Request */ *response = NULL; /* IPP Response */ cups_lang_t *language = NULL; /* Default language */ + char *user = NULL; char uri[HTTP_MAX_URI]; /* printer-uri attribute */ - + size_t size; DEBUG(5,("cups_job_pause(%d, %p (%d))\n", snum, pjob, pjob->sysjob)); @@ -419,7 +465,7 @@ static int cups_job_pause(int snum, struct printjob *pjob) * Try to connect to the server... */ - if ((http = cups_connect()) == NULL) { + if ((http = cups_connect(frame)) == NULL) { goto out; } @@ -441,7 +487,7 @@ static int cups_job_pause(int snum, struct printjob *pjob) language = cupsLangDefault(); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, - "attributes-charset", NULL, cupsLangEncoding(language)); + "attributes-charset", NULL, "utf-8"); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, language->language); @@ -450,8 +496,11 @@ static int cups_job_pause(int snum, struct printjob *pjob) ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri); + if (!push_utf8_talloc(frame, &user, pjob->user, &size)) { + goto out; + } ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", - NULL, pjob->user); + NULL, user); /* * Do the request and get back a response... @@ -479,6 +528,7 @@ static int cups_job_pause(int snum, struct printjob *pjob) if (http) httpClose(http); + TALLOC_FREE(frame); return ret; } @@ -489,13 +539,15 @@ static int cups_job_pause(int snum, struct printjob *pjob) static int cups_job_resume(int snum, struct printjob *pjob) { + TALLOC_CTX *frame = talloc_stackframe(); int ret = 1; /* Return value */ http_t *http = NULL; /* HTTP connection to server */ ipp_t *request = NULL, /* IPP Request */ *response = NULL; /* IPP Response */ cups_lang_t *language = NULL; /* Default language */ + char *user = NULL; char uri[HTTP_MAX_URI]; /* printer-uri attribute */ - + size_t size; DEBUG(5,("cups_job_resume(%d, %p (%d))\n", snum, pjob, pjob->sysjob)); @@ -509,7 +561,7 @@ static int cups_job_resume(int snum, struct printjob *pjob) * Try to connect to the server... */ - if ((http = cups_connect()) == NULL) { + if ((http = cups_connect(frame)) == NULL) { goto out; } @@ -531,7 +583,7 @@ static int cups_job_resume(int snum, struct printjob *pjob) language = cupsLangDefault(); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, - "attributes-charset", NULL, cupsLangEncoding(language)); + "attributes-charset", NULL, "utf-8"); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, language->language); @@ -540,8 +592,11 @@ static int cups_job_resume(int snum, struct printjob *pjob) ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "job-uri", NULL, uri); + if (!push_utf8_talloc(frame, &user, pjob->user, &size)) { + goto out; + } ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", - NULL, pjob->user); + NULL, user); /* * Do the request and get back a response... @@ -569,6 +624,7 @@ static int cups_job_resume(int snum, struct printjob *pjob) if (http) httpClose(http); + TALLOC_FREE(frame); return ret; } @@ -579,6 +635,7 @@ static int cups_job_resume(int snum, struct printjob *pjob) static int cups_job_submit(int snum, struct printjob *pjob) { + TALLOC_CTX *frame = talloc_stackframe(); int ret = 1; /* Return value */ http_t *http = NULL; /* HTTP connection to server */ ipp_t *request = NULL, /* IPP Request */ @@ -589,6 +646,12 @@ static int cups_job_submit(int snum, struct printjob *pjob) char *new_jobname = NULL; int num_options = 0; cups_option_t *options = NULL; + char *printername = NULL; + char *user = NULL; + char *jobname = NULL; + char *cupsoptions = NULL; + char *filename = NULL; + size_t size; char addr[INET6_ADDRSTRLEN]; DEBUG(5,("cups_job_submit(%d, %p (%d))\n", snum, pjob, pjob->sysjob)); @@ -603,7 +666,7 @@ static int cups_job_submit(int snum, struct printjob *pjob) * Try to connect to the server... */ - if ((http = cups_connect()) == NULL) { + if ((http = cups_connect(frame)) == NULL) { goto out; } @@ -626,19 +689,25 @@ static int cups_job_submit(int snum, struct printjob *pjob) language = cupsLangDefault(); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_CHARSET, - "attributes-charset", NULL, cupsLangEncoding(language)); + "attributes-charset", NULL, "utf-8"); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_LANGUAGE, "attributes-natural-language", NULL, language->language); + if (!push_utf8_talloc(frame, &printername, PRINTERNAME(snum), &size)) { + goto out; + } slprintf(uri, sizeof(uri) - 1, "ipp://localhost/printers/%s", - PRINTERNAME(snum)); + printername); ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri", NULL, uri); + if (!push_utf8_talloc(frame, &user, pjob->user, &size)) { + goto out; + } ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME, "requesting-user-name", - NULL, pjob->user); + NULL, user); clientname = client_name(get_client_fd()); if (strcmp(clientname, "UNKNOWN") == 0) { @@ -649,8 +718,14 @@ static int cups_job_submit(int snum, struct printjob *pjob) "job-originating-host-name", NULL, clientname); - if (asprintf(&new_jobname,"%s%.8u %s", PRINT_SPOOL_PREFIX, - (unsigned int)pjob->smbjob, pjob->jobname) < 0) { + if (!push_utf8_talloc(frame, &jobname, pjob->jobname, &size)) { + goto out; + } + new_jobname = talloc_asprintf(frame, + "%s%.8u %s", PRINT_SPOOL_PREFIX, + (unsigned int)pjob->smbjob, + jobname); + if (new_jobname == NULL) { goto out; } @@ -661,9 +736,12 @@ static int cups_job_submit(int snum, struct printjob *pjob) * add any options defined in smb.conf */ + if (!push_utf8_talloc(frame, &cupsoptions, lp_cups_options(snum), &size)) { + goto out; + } num_options = 0; options = NULL; - num_options = cupsParseOptions(lp_cups_options(snum), num_options, &options); + num_options = cupsParseOptions(cupsoptions, num_options, &options); if ( num_options ) cupsEncodeOptions(request, num_options, options); @@ -672,8 +750,11 @@ static int cups_job_submit(int snum, struct printjob *pjob) * Do the request and get back a response... */ - slprintf(uri, sizeof(uri) - 1, "/printers/%s", PRINTERNAME(snum)); + slprintf(uri, sizeof(uri) - 1, "/printers/%s", printername); + if (!push_utf8_talloc(frame, &filename, pjob->filename, &size)) { + goto out; + } if ((response = cupsDoFileRequest(http, request, uri, pjob->filename)) != NULL) { if (response->request.status.status_code >= IPP_OK_CONFLICT) { DEBUG(0,("Unable to print file to %s - %s\n", PRINTERNAME(snum), @@ -700,7 +781,7 @@ static int cups_job_submit(int snum, struct printjob *pjob) if (http) httpClose(http); - SAFE_FREE(new_jobname); + TALLOC_FREE(frame); return ret; } @@ -715,7 +796,8 @@ static int cups_queue_get(const char *sharename, print_queue_struct **q, print_status_struct *status) { - fstring printername; + TALLOC_CTX *frame = talloc_stackframe(); + char *printername = NULL; http_t *http = NULL; /* HTTP connection to server */ ipp_t *request = NULL, /* IPP Request */ *response = NULL; /* IPP Response */ @@ -726,13 +808,14 @@ static int cups_queue_get(const char *sharename, qalloc = 0; /* Number of queue entries allocated */ print_queue_struct *queue = NULL, /* Queue entries */ *temp; /* Temporary pointer for queue */ - const char *user_name, /* job-originating-user-name attribute */ - *job_name; /* job-name attribute */ + char *user_name = NULL, /* job-originating-user-name attribute */ + *job_name = NULL; /* job-name attribute */ int job_id; /* job-id attribute */ int job_k_octets; /* job-k-octets attribute */ time_t job_time; /* time-at-creation attribute */ ipp_jstate_t job_status; /* job-status attribute */ int job_priority; /* job-priority attribute */ + size_t size; static const char *jattrs[] = /* Requested job attributes */ { "job-id", @@ -757,9 +840,10 @@ static int cups_queue_get(const char *sharename, (which is basically what we do for non-cups printers ... using the lpq_command to get the queue listing). */ -- Samba Shared Repository