From: msweet Date: Mon, 13 Aug 2007 21:04:11 +0000 (+0000) Subject: Merge changes from r6781 to r6792 (CUPS 1.3.0) X-Git-Tag: release-1.6.3~207 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=76cd9e37aaf496aab887d499f4917b60e91d6d25;p=thirdparty%2Fcups.git Merge changes from r6781 to r6792 (CUPS 1.3.0) git-svn-id: svn+ssh://src.apple.com/svn/cups/easysw/current@405 a1ca3aef-8c08-0410-bb20-df032aa958be --- diff --git a/CHANGES.txt b/CHANGES.txt index 9d71580cd4..68404a28a9 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,9 +1,14 @@ -CHANGES.txt - 2007-08-08 +CHANGES.txt - 2007-08-13 ------------------------ CHANGES IN CUPS V1.3.0 + - The scheduler did not handle out-of-file conditions + gracefully when accepting new connections, leading to + heavy CPU usage. + - The scheduler did not detect ServerBin misconfigurations + (STR #2470) - "AuthType Default" did not work as expected when the "DefaultAuthType foo" line appeared after it in the cupsd.conf file. diff --git a/INSTALL.txt b/INSTALL.txt index 92416a1828..5732830f39 100644 --- a/INSTALL.txt +++ b/INSTALL.txt @@ -1,4 +1,4 @@ -INSTALL - CUPS v1.3.0 - 2007-08-03 +INSTALL - CUPS v1.3.0 - 2007-08-13 ---------------------------------- This file describes how to compile and install CUPS from source diff --git a/README.txt b/README.txt index 37fc684513..48fee5a99a 100644 --- a/README.txt +++ b/README.txt @@ -1,4 +1,4 @@ -README - CUPS v1.3.0 - 2007-08-03 +README - CUPS v1.3.0 - 2007-08-13 --------------------------------- Looking for compile instructions? Read the file "INSTALL.txt" diff --git a/backend/ipp.c b/backend/ipp.c index df55c5cbb1..ed82f4d33d 100644 --- a/backend/ipp.c +++ b/backend/ipp.c @@ -51,6 +51,7 @@ */ static char *password = NULL; /* Password for device URI */ +static int password_tries = 0; /* Password tries */ #ifdef __APPLE__ static char pstmpname[1024] = ""; /* Temporary PostScript file name */ #endif /* __APPLE__ */ @@ -1372,8 +1373,12 @@ password_cb(const char *prompt) /* I - Prompt (not used) */ { (void)prompt; - if (password) + if (password && password_tries < 3) + { + password_tries ++; + return (password); + } else { /* diff --git a/backend/socket.c b/backend/socket.c index 68f9a29c55..06790d96cb 100644 --- a/backend/socket.c +++ b/backend/socket.c @@ -432,6 +432,7 @@ side_cb(int print_fd, /* I - Print file */ cups_sc_status_t status; /* Request/response status */ char data[2048]; /* Request/response data */ int datalen; /* Request/response data size */ + const char *device_id; /* 1284DEVICEID env var */ datalen = sizeof(data); @@ -462,6 +463,14 @@ side_cb(int print_fd, /* I - Print file */ datalen = 1; break; + case CUPS_SC_CMD_GET_DEVICE_ID : + if ((device_id = getenv("1284DEVICEID")) != NULL) + { + strlcpy(data, device_id, sizeof(data)); + datalen = (int)strlen(data); + break; + } + default : status = CUPS_SC_STATUS_NOT_IMPLEMENTED; datalen = 0; diff --git a/backend/usb-darwin.c b/backend/usb-darwin.c index e71965d8cc..dc628fea31 100644 --- a/backend/usb-darwin.c +++ b/backend/usb-darwin.c @@ -267,7 +267,7 @@ static void copy_devicestring(io_service_t usbInterface, CFStringRef *deviceID, static void device_added(void *userdata, io_iterator_t iterator); static void get_device_id(cups_sc_status_t *status, char *data, int *datalen); static void iterate_printers(iterator_callback_t callBack, void *userdata); -static void parse_options(const char *options, char *serial, UInt32 *location, Boolean *wait_eof); +static void parse_options(const char *options, char *serial, int serial_size, UInt32 *location, Boolean *wait_eof); static void release_deviceinfo(CFStringRef *make, CFStringRef *model, CFStringRef *serial); static void setup_cfLanguage(void); static void soft_reset(); @@ -329,7 +329,7 @@ print_device(const char *uri, /* I - Device URI */ setup_cfLanguage(); - parse_options(options, serial, &location, &g.wait_eof); + parse_options(options, serial, sizeof(serial), &location, &g.wait_eof); if (resource[0] == '/') resource++; @@ -1546,10 +1546,10 @@ CFStringRef cfstr_create_trim(const char *cstr) static void parse_options(const char *options, char *serial, + int serial_size, UInt32 *location, Boolean *wait_eof) { - char *serialnumber; /* ?serial= or ?location= */ char optionName[255], /* Name of option */ value[255], /* Value of option */ *ptr; /* Pointer into name or value */ @@ -1562,8 +1562,6 @@ static void parse_options(const char *options, if (!options) return; - serialnumber = NULL; - while (*options != '\0') { /* Get the name... */ @@ -1607,8 +1605,7 @@ static void parse_options(const char *options, } else if (strcasecmp(optionName, "serial") == 0) { - strcpy(serial, value); - serialnumber = serial; + strlcpy(serial, value, serial_size); } else if (strcasecmp(optionName, "location") == 0 && location) *location = strtol(value, NULL, 16); diff --git a/config-scripts/cups-common.m4 b/config-scripts/cups-common.m4 index 88c1532007..27835e87c6 100644 --- a/config-scripts/cups-common.m4 +++ b/config-scripts/cups-common.m4 @@ -20,7 +20,7 @@ dnl Set the name of the config header file... AC_CONFIG_HEADER(config.h) dnl Versio number information... -CUPS_VERSION="1.3rc2" +CUPS_VERSION="1.3.0" CUPS_REVISION="" #if test -z "$CUPS_REVISION" -a -d .svn; then # CUPS_REVISION="-r`svnversion . | awk -F: '{print $NF}' | sed -e '1,$s/[[a-zA-Z]]*//g'`" diff --git a/doc/help/kerberos.html b/doc/help/kerberos.html index a7b0e5ed06..83c5fe8f08 100644 --- a/doc/help/kerberos.html +++ b/doc/help/kerberos.html @@ -11,6 +11,15 @@ to a remote authenticated queue. This document describes how to configure CUPS to use Kerberos authentication and provides helpful links to the MIT help pages for configuring Kerberos on your systems and network.

+
Note: + +

In order to use Kerberos-authenticated shared printers, you must be +running a version of MIT Kerberos with the krb5_cc_new_unique() +function or Heimdal Kerberos. Otherwise, only local Kerberos authentication +is supported.

+ +
+

Configuring Kerberos on Your System

@@ -126,8 +135,9 @@ lines to the policies you want to protect with authentication, for example:

Implementation Information

CUPS implements Kerberos over HTTP using GSS API and the service name -"ipp". Delegation of credentials (needed for remote printers with -authentication) is only supported when using a single KDC on your network.

+"ipp". Delegation of credentials, which is needed when printing to a +remote/shared printer with Kerberos authentication, is currently only supported +when using a single KDC on your network.

After getting a user's Kerberos credentials, CUPS strips the "@KDC" portion of the username so that it can check the group membership locally, diff --git a/scheduler/auth.c b/scheduler/auth.c index 12ea711c07..03f875be6d 100644 --- a/scheduler/auth.c +++ b/scheduler/auth.c @@ -1026,11 +1026,19 @@ cupsdAuthorize(cupsd_client_t *con) /* I - Client connection */ if (context != GSS_C_NO_CONTEXT) gss_delete_sec_context(&minor_status, &context, GSS_C_NO_BUFFER); + + gss_release_cred(&minor_status, &server_creds); return; } /* - * Get the username associated with the credentials... + * Release our credentials... + */ + + gss_release_cred(&minor_status, &server_creds); + + /* + * Get the username associated with the client's credentials... */ if (!con->gss_delegated_cred) diff --git a/scheduler/client.c b/scheduler/client.c index dfe1546dee..f8316a79e6 100644 --- a/scheduler/client.c +++ b/scheduler/client.c @@ -161,9 +161,13 @@ cupsdAcceptClient(cupsd_listener_t *lis)/* I - Listener socket */ if ((con->http.fd = accept(lis->fd, (struct sockaddr *)con->http.hostaddr, &addrlen)) < 0) { + if (errno == ENFILE || errno == EMFILE) + cupsdPauseListening(); + cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to accept client connection - %s.", strerror(errno)); free(con); + return; } diff --git a/scheduler/client.h b/scheduler/client.h index d439276db9..f3c0f3a326 100644 --- a/scheduler/client.h +++ b/scheduler/client.h @@ -90,6 +90,8 @@ VAR http_encryption_t LocalEncryption VALUE(HTTP_ENCRYPT_IF_REQUESTED); /* Local port encryption to use */ VAR cups_array_t *Listeners VALUE(NULL); /* Listening sockets */ +VAR time_t ListeningPaused VALUE(0); + /* Time when listening was paused */ VAR cups_array_t *Clients VALUE(NULL); /* HTTP clients */ VAR http_addrlist_t *ServerAddrs VALUE(NULL); diff --git a/scheduler/conf.c b/scheduler/conf.c index 9a2188b62c..26d6037bfa 100644 --- a/scheduler/conf.c +++ b/scheduler/conf.c @@ -56,7 +56,8 @@ typedef enum { CUPSD_VARTYPE_INTEGER, /* Integer option */ CUPSD_VARTYPE_STRING, /* String option */ - CUPSD_VARTYPE_BOOLEAN /* Boolean option */ + CUPSD_VARTYPE_BOOLEAN, /* Boolean option */ + CUPSD_VARTYPE_PATHNAME /* File/directory name option */ } cupsd_vartype_t; typedef struct @@ -81,7 +82,7 @@ static cupsd_var_t variables[] = { "BrowseInterval", &BrowseInterval, CUPSD_VARTYPE_INTEGER }, #ifdef HAVE_LDAP { "BrowseLDAPBindDN", &BrowseLDAPBindDN, CUPSD_VARTYPE_STRING }, - { "BrowseLDAPCACertFile", &BrowseLDAPCACertFile, CUPSD_VARTYPE_STRING }, + { "BrowseLDAPCACertFile", &BrowseLDAPCACertFile, CUPSD_VARTYPE_PATHNAME }, { "BrowseLDAPDN", &BrowseLDAPDN, CUPSD_VARTYPE_STRING }, { "BrowseLDAPPassword", &BrowseLDAPPassword, CUPSD_VARTYPE_STRING }, { "BrowseLDAPServer", &BrowseLDAPServer, CUPSD_VARTYPE_STRING }, @@ -152,20 +153,20 @@ static cupsd_var_t variables[] = { "RIPCache", &RIPCache, CUPSD_VARTYPE_STRING }, { "RootCertDuration", &RootCertDuration, CUPSD_VARTYPE_INTEGER }, { "ServerAdmin", &ServerAdmin, CUPSD_VARTYPE_STRING }, - { "ServerBin", &ServerBin, CUPSD_VARTYPE_STRING }, + { "ServerBin", &ServerBin, CUPSD_VARTYPE_PATHNAME }, #ifdef HAVE_SSL - { "ServerCertificate", &ServerCertificate, CUPSD_VARTYPE_STRING }, + { "ServerCertificate", &ServerCertificate, CUPSD_VARTYPE_PATHNAME }, # if defined(HAVE_LIBSSL) || defined(HAVE_GNUTLS) - { "ServerKey", &ServerKey, CUPSD_VARTYPE_STRING }, + { "ServerKey", &ServerKey, CUPSD_VARTYPE_PATHNAME }, # endif /* HAVE_LIBSSL || HAVE_GNUTLS */ #endif /* HAVE_SSL */ { "ServerName", &ServerName, CUPSD_VARTYPE_STRING }, - { "ServerRoot", &ServerRoot, CUPSD_VARTYPE_STRING }, + { "ServerRoot", &ServerRoot, CUPSD_VARTYPE_PATHNAME }, { "StateDir", &StateDir, CUPSD_VARTYPE_STRING }, #ifdef HAVE_AUTHORIZATION_H { "SystemGroupAuthKey", &SystemGroupAuthKey, CUPSD_VARTYPE_STRING }, #endif /* HAVE_AUTHORIZATION_H */ - { "TempDir", &TempDir, CUPSD_VARTYPE_STRING }, + { "TempDir", &TempDir, CUPSD_VARTYPE_PATHNAME }, { "Timeout", &Timeout, CUPSD_VARTYPE_INTEGER }, { "UseNetworkDefault", &UseNetworkDefault, CUPSD_VARTYPE_BOOLEAN } }; @@ -3076,6 +3077,20 @@ read_configuration(cups_file_t *fp) /* I - File to read from */ value, linenum); break; + case CUPSD_VARTYPE_PATHNAME : + if (value[0] == '/') + strlcpy(temp, value, sizeof(temp)); + else + snprintf(temp, sizeof(temp), "%s/%s", ServerRoot, value); + + if (access(temp, 0)) + { + cupsdLogMessage(CUPSD_LOG_ERROR, + "File or directory for \"%s %s\" on line %d " + "does not exist!", line, value, linenum); + break; + } + case CUPSD_VARTYPE_STRING : cupsdSetString((char **)var->ptr, value); break; diff --git a/scheduler/ipp.c b/scheduler/ipp.c index 04bb9d0fea..fd8c797dbc 100644 --- a/scheduler/ipp.c +++ b/scheduler/ipp.c @@ -8299,6 +8299,7 @@ save_krb5_creds(cupsd_client_t *con, /* I - Client connection */ { cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to create new credentials (%d/%s)", error, strerror(errno)); + job->ccache = NULL; return; } @@ -8314,6 +8315,7 @@ save_krb5_creds(cupsd_client_t *con, /* I - Client connection */ cupsdLogGSSMessage(CUPSD_LOG_ERROR, major_status, minor_status, "Unable to import client credentials cache"); krb5_cc_destroy(KerberosContext, job->ccache); + job->ccache = NULL; return; } diff --git a/scheduler/job.c b/scheduler/job.c index 407e752aaf..ed1982c9c4 100644 --- a/scheduler/job.c +++ b/scheduler/job.c @@ -230,16 +230,17 @@ cupsdCancelJob(cupsd_job_t *job, /* I - Job to cancel */ cupsdClearString(&job->auth_password); #ifdef HAVE_GSSAPI - if (job->ccname) - { - /* - * Destroy the credential cache and clear the KRB5CCNAME env var string. - */ + /* + * Destroy the credential cache and clear the KRB5CCNAME env var string. + */ + if (job->ccache) + { krb5_cc_destroy(KerberosContext, job->ccache); - - cupsdClearString(&job->ccname); + job->ccache = NULL; } + + cupsdClearString(&job->ccname); #endif /* HAVE_GSSAPI */ /* @@ -1803,16 +1804,17 @@ free_job(cupsd_job_t *job) /* I - Job */ cupsdClearString(&job->auth_domain); cupsdClearString(&job->auth_password); #ifdef HAVE_GSSAPI - if (job->ccname) - { - /* - * Destroy the credential cache and clear the KRB5CCNAME env var string. - */ + /* + * Destroy the credential cache and clear the KRB5CCNAME env var string. + */ + if (job->ccache) + { krb5_cc_destroy(KerberosContext, job->ccache); - - cupsdClearString(&job->ccname); + job->ccache = NULL; } + + cupsdClearString(&job->ccname); #endif /* HAVE_GSSAPI */ if (job->num_files > 0) diff --git a/scheduler/listen.c b/scheduler/listen.c index 6e938a65c0..0a3158db40 100644 --- a/scheduler/listen.c +++ b/scheduler/listen.c @@ -75,6 +75,10 @@ cupsdPauseListening(void) if (cupsArrayCount(Clients) == MaxClients) cupsdLogMessage(CUPSD_LOG_WARN, "Max clients reached, holding new connections..."); + else if (errno == ENFILE || errno == EMFILE) + cupsdLogMessage(CUPSD_LOG_WARN, + "Too many open files, holding new connections for " + "30 seconds..."); cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdPauseListening: Clearing input bits..."); @@ -82,6 +86,8 @@ cupsdPauseListening(void) lis; lis = (cupsd_listener_t *)cupsArrayNext(Listeners)) cupsdRemoveSelect(lis->fd); + + ListeningPaused = time(NULL) + 30; } @@ -98,9 +104,7 @@ cupsdResumeListening(void) if (cupsArrayCount(Listeners) < 1) return; - if (cupsArrayCount(Clients) >= (MaxClients - 1)) - cupsdLogMessage(CUPSD_LOG_WARN, "Resuming new connection processing..."); - + cupsdLogMessage(CUPSD_LOG_INFO, "Resuming new connection processing..."); cupsdLogMessage(CUPSD_LOG_DEBUG2, "cupsdResumeListening: Setting input bits..."); @@ -108,6 +112,8 @@ cupsdResumeListening(void) lis; lis = (cupsd_listener_t *)cupsArrayNext(Listeners)) cupsdAddSelect(lis->fd, (cupsd_selfunc_t)cupsdAcceptClient, NULL, lis); + + ListeningPaused = 0; } diff --git a/scheduler/main.c b/scheduler/main.c index aee1b11118..f9f1ba9b14 100644 --- a/scheduler/main.c +++ b/scheduler/main.c @@ -801,6 +801,14 @@ main(int argc, /* I - Number of command-line args */ } #endif /* HAVE_LAUNCHD */ + /* + * Resume listening for new connections as needed... + */ + + if (ListeningPaused && ListeningPaused <= current_time && + cupsArrayCount(Clients) < MaxClients) + cupsdResumeListening(); + /* * Expire subscriptions and unload completed jobs as needed... */ @@ -1707,6 +1715,21 @@ select_timeout(int fds) /* I - Number of descriptors returned */ timeout = now + 86400; /* 86400 == 1 day */ why = "do nothing"; + /* + * Check whether we are accepting new connections... + */ + + if (ListeningPaused > 0 && cupsArrayCount(Clients) < MaxClients && + ListeningPaused < timeout) + { + if (ListeningPaused <= now) + timeout = now; + else + timeout = ListeningPaused; + + why = "resume listening"; + } + /* * Check the activity and close old clients... */ diff --git a/scheduler/process.c b/scheduler/process.c index 6ea6e150aa..5e0933f15f 100644 --- a/scheduler/process.c +++ b/scheduler/process.c @@ -131,6 +131,13 @@ cupsdStartProcess( "cupsdStartProcess(\"%s\", %p, %p, %d, %d, %d)", command, argv, envp, infd, outfd, errfd); + if (access(command, X_OK)) + { + cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to execute %s: %s", command, + strerror(errno)); + return (0); + } + #if defined(__APPLE__) if (envp) { diff --git a/scheduler/testlpd.c b/scheduler/testlpd.c index 7cf094f4b2..fbc99e10c4 100644 --- a/scheduler/testlpd.c +++ b/scheduler/testlpd.c @@ -32,6 +32,7 @@ #include #include #include +#include #include #include #include