]> git.ipfire.org Git - thirdparty/cups.git/commitdiff
Merge changes from r6781 to r6792 (CUPS 1.3.0)
authormsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>
Mon, 13 Aug 2007 21:04:11 +0000 (21:04 +0000)
committermsweet <msweet@a1ca3aef-8c08-0410-bb20-df032aa958be>
Mon, 13 Aug 2007 21:04:11 +0000 (21:04 +0000)
git-svn-id: svn+ssh://src.apple.com/svn/cups/easysw/current@405 a1ca3aef-8c08-0410-bb20-df032aa958be

18 files changed:
CHANGES.txt
INSTALL.txt
README.txt
backend/ipp.c
backend/socket.c
backend/usb-darwin.c
config-scripts/cups-common.m4
doc/help/kerberos.html
scheduler/auth.c
scheduler/client.c
scheduler/client.h
scheduler/conf.c
scheduler/ipp.c
scheduler/job.c
scheduler/listen.c
scheduler/main.c
scheduler/process.c
scheduler/testlpd.c

index 9d71580cd46b77edc4b8ca893aba49e8ff789eb6..68404a28a9137171466d8c154ea9e52262d73870 100644 (file)
@@ -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.
index 92416a1828b4b34ce84daafc6e932a07fc443f31..5732830f39d8ad67cef918a6f48e0e8a9e34e8fb 100644 (file)
@@ -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
index 37fc684513252bca44f5b93a2a5f02b962aca5b4..48fee5a99a5afe9a2e7c26fb8cda7b6f7cde199c 100644 (file)
@@ -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"
index df55c5cbb1c645c853cdc9303296d01413bbb603..ed82f4d33d916b73fe9540340a6d655c2f4814eb 100644 (file)
@@ -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
   {
    /*
index 68f9a29c551a9f3f2c8faff8ddf1cbad6ea24129..06790d96cb3b3271435debd7c4a53723f494fa21 100644 (file)
@@ -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;
index e71965d8ccceb8f55cbc270b6bbf6ef0fac7cf81..dc628fea316d9d7dc7e8ed78af26b3f40e5de79c 100644 (file)
@@ -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=<serial> or ?location=<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);
index 88c1532007e817fc1ecd97d31d439b8191fecfa6..27835e87c61fbb349e34f8a2f5e20cdea5d63946 100644 (file)
@@ -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'`"
index a7b0e5ed06ae572d9da280330c5a28c5add48f2e..83c5fe8f08ac02813d026e24e87f4d4799314165 100644 (file)
@@ -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.</P>
 
+<BLOCKQUOTE><B>Note:</B>
+
+<P>In order to use Kerberos-authenticated shared printers, you <EM>must</EM> be
+running a version of MIT Kerberos with the <TT>krb5_cc_new_unique()</TT>
+function or Heimdal Kerberos. Otherwise, only local Kerberos authentication
+is supported.</P>
+
+</BLOCKQUOTE>
+
 
 <H2 CLASS="title"><A NAME="KRB5">Configuring Kerberos on Your System</A></H2>
 
@@ -126,8 +135,9 @@ lines to the policies you want to protect with authentication, for example:</P>
 <H2 CLASS="title"><A NAME="IMPLEMENT">Implementation Information</A></H2>
 
 <P>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.</P>
+"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.</P>
 
 <P>After getting a user's Kerberos credentials, CUPS strips the "@KDC"
 portion of the username so that it can check the group membership locally,
index 12ea711c07f4c37e8f4fa0c11dfc71ae7d2d12a3..03f875be6d625123e2f2b9d7b49dfd891009ca85 100644 (file)
@@ -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)
index dfe1546deefe8e3e97b36732412789815f4e0c19..f8316a79e696c4c8bd436f7d02ab9c746b4877d6 100644 (file)
@@ -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;
   }
 
index d439276db9fd6d0825c9ccfab625466902af8179..f3c0f3a326d55425f9f95ee3327a6aed141e66a4 100644 (file)
@@ -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);
index 9a2188b62c26d3a5c312c53db2416d50df49f5d2..26d6037bfac872dad9e3a2a1774e2e672847df7d 100644 (file)
@@ -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;
index 04bb9d0fead82fa3b6e8c2ea6254481eed21f3ca..fd8c797dbce25d1bf37ee4894fc242a537e94300 100644 (file)
@@ -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;
   }
 
index 407e752aaf5c22dd2db50b7170086a28cdfb542e..ed1982c9c4e5ec1b0089776b62b825f203c72295 100644 (file)
@@ -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)
index 6e938a65c0f3b734c50c64d6f37ff2a5944a2da9..0a3158db40fc88ee946419424e610c6b116439ca 100644 (file)
@@ -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;
 }
 
 
index aee1b111189800ce036ab6f715ee6f601efd32da..f9f1ba9b143e044906a6c1ddfd166f8b9e12268a 100644 (file)
@@ -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...
   */
index 6ea6e150aa1c79fba8bfeafd48f64a8367ccc8e2..5e0933f15f6ce92917c259ade8042415de6722c9 100644 (file)
@@ -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)
   {
index 7cf094f4b27aff2498ec08489141c453ca853785..fbc99e10c49eb1e0a73cde12b7f958e00fd93264 100644 (file)
@@ -32,6 +32,7 @@
 #include <cups/string.h>
 #include <stdlib.h>
 #include <sys/stat.h>
+#include <sys/wait.h>
 #include <errno.h>
 #include <signal.h>
 #include <unistd.h>