]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - scheduler/ipp.c
Merge changes from CUPS 1.6svn-r9968.
[thirdparty/cups.git] / scheduler / ipp.c
index 5200964c363a172e896dc64f117e61681f9fa7cb..ac5f8c2b9d5fb9015b81f4a9b3b26967d1df265a 100644 (file)
@@ -88,7 +88,6 @@
  *   renew_subscription()        - Renew an existing subscription...
  *   restart_job()               - Restart an old print job.
  *   save_auth_info()            - Save authentication information for a job.
- *   save_krb5_creds()           - Save Kerberos credentials for the job.
  *   send_document()             - Send a file to a printer or class.
  *   send_http_error()           - Send a HTTP error back to the IPP client.
  *   send_ipp_status()           - Send a status back to the IPP client.
@@ -145,7 +144,7 @@ static cupsd_job_t *add_job(cupsd_client_t *con, cupsd_printer_t *printer,
                            mime_type_t *filetype);
 static void    add_job_state_reasons(cupsd_client_t *con, cupsd_job_t *job);
 static void    add_job_subscriptions(cupsd_client_t *con, cupsd_job_t *job);
-static void    add_job_uuid(cupsd_client_t *con, cupsd_job_t *job);
+static void    add_job_uuid(cupsd_job_t *job);
 static void    add_printer(cupsd_client_t *con, ipp_attribute_t *uri);
 static void    add_printer_state_reasons(cupsd_client_t *con,
                                          cupsd_printer_t *p);
@@ -224,18 +223,12 @@ static void       renew_subscription(cupsd_client_t *con, int sub_id);
 static void    restart_job(cupsd_client_t *con, ipp_attribute_t *uri);
 static void    save_auth_info(cupsd_client_t *con, cupsd_job_t *job,
                               ipp_attribute_t *auth_info);
-#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5_H)
-static void    save_krb5_creds(cupsd_client_t *con, cupsd_job_t *job);
-#endif /* HAVE_GSSAPI && HAVE_KRB5_H */
 static void    send_document(cupsd_client_t *con, ipp_attribute_t *uri);
 static void    send_http_error(cupsd_client_t *con, http_status_t status,
                                cupsd_printer_t *printer);
 static void    send_ipp_status(cupsd_client_t *con, ipp_status_t status,
                                const char *message, ...)
-#    ifdef __GNUC__
-__attribute__ ((__format__ (__printf__, 3, 4)))
-#    endif /* __GNUC__ */
-;
+               __attribute__((__format__(__printf__, 3, 4)));
 static void    set_default(cupsd_client_t *con, ipp_attribute_t *uri);
 static void    set_job_attrs(cupsd_client_t *con, ipp_attribute_t *uri);
 static void    set_printer_attrs(cupsd_client_t *con, ipp_attribute_t *uri);
@@ -306,7 +299,7 @@ cupsdProcessIPPRequest(
                  con->request->request.any.version[1]);
 
     send_ipp_status(con, IPP_VERSION_NOT_SUPPORTED,
-                    _("Bad request version number %d.%d"),
+                    _("Bad request version number %d.%d."),
                    con->request->request.any.version[0],
                    con->request->request.any.version[1]);
   }
@@ -321,7 +314,7 @@ cupsdProcessIPPRequest(
                  IPP_BAD_REQUEST, con->http.hostname,
                   con->request->request.any.request_id);
 
-    send_ipp_status(con, IPP_BAD_REQUEST, _("Bad request ID %d"),
+    send_ipp_status(con, IPP_BAD_REQUEST, _("Bad request ID %d."),
                    con->request->request.any.request_id);
   }
   else if (!con->request->attrs)
@@ -330,7 +323,7 @@ cupsdProcessIPPRequest(
                   "%04X %s No attributes in request",
                  IPP_BAD_REQUEST, con->http.hostname);
 
-    send_ipp_status(con, IPP_BAD_REQUEST, _("No attributes in request"));
+    send_ipp_status(con, IPP_BAD_REQUEST, _("No attributes in request."));
   }
   else
   {
@@ -353,7 +346,7 @@ cupsdProcessIPPRequest(
                      IPP_BAD_REQUEST, con->http.hostname);
 
        send_ipp_status(con, IPP_BAD_REQUEST,
-                       _("Attribute groups are out of order (%x < %x)"),
+                       _("Attribute groups are out of order (%x < %x)."),
                        attr->group_tag, group);
        break;
       }
@@ -416,8 +409,8 @@ cupsdProcessIPPRequest(
                      "attributes-natural-language", NULL, DefaultLanguage);
 
       if (charset &&
-          strcasecmp(charset->values[0].string.text, "us-ascii") &&
-          strcasecmp(charset->values[0].string.text, "utf-8"))
+          _cups_strcasecmp(charset->values[0].string.text, "us-ascii") &&
+          _cups_strcasecmp(charset->values[0].string.text, "utf-8"))
       {
        /*
         * Bad character set...
@@ -430,7 +423,7 @@ cupsdProcessIPPRequest(
                      IPP_CHARSET, con->http.hostname,
                      charset->values[0].string.text);
        send_ipp_status(con, IPP_BAD_REQUEST,
-                       _("Unsupported character set \"%s\""),
+                       _("Unsupported character set \"%s\"."),
                        charset->values[0].string.text);
       }
       else if (!charset || !language ||
@@ -489,7 +482,7 @@ cupsdProcessIPPRequest(
        cupsdLogMessage(CUPSD_LOG_DEBUG, "End of attributes...");
 
        send_ipp_status(con, IPP_BAD_REQUEST,
-                       _("Missing required attributes"));
+                       _("Missing required attributes."));
       }
       else
       {
@@ -506,7 +499,7 @@ cupsdProcessIPPRequest(
          */
 
          if (!strcmp(username->values[0].string.text, "root") &&
-             strcasecmp(con->http.hostname, "localhost") &&
+             _cups_strcasecmp(con->http.hostname, "localhost") &&
              strcmp(con->username, "root"))
          {
           /*
@@ -719,7 +712,7 @@ cupsdProcessIPPRequest(
                            ippOpString(con->request->request.op.operation_id));
 
               send_ipp_status(con, IPP_OPERATION_NOT_SUPPORTED,
-                             _("%s not supported"),
+                             _("%s not supported."),
                              ippOpString(
                                  con->request->request.op.operation_id));
              break;
@@ -905,7 +898,7 @@ accept_jobs(cupsd_client_t  *con,   /* I - Client connection */
     */
 
     send_ipp_status(con, IPP_NOT_FOUND,
-                    _("The printer or class was not found."));
+                    _("The printer or class does not exist."));
     return;
   }
 
@@ -926,8 +919,6 @@ accept_jobs(cupsd_client_t  *con,   /* I - Client connection */
   printer->accepting        = 1;
   printer->state_message[0] = '\0';
 
-  cupsdAddPrinterHistory(printer);
-
   cupsdAddEvent(CUPSD_EVENT_PRINTER_STATE, printer, NULL,
                 "Now accepting jobs.");
 
@@ -1037,7 +1028,7 @@ add_class(cupsd_client_t  *con,           /* I - Client connection */
       */
 
       send_ipp_status(con, IPP_NOT_POSSIBLE,
-                      _("A printer named \"%s\" already exists"),
+                      _("A printer named \"%s\" already exists."),
                      resource + 9);
       return;
     }
@@ -1137,7 +1128,6 @@ add_class(cupsd_client_t  *con,           /* I - Client connection */
                     pclass->name, attr->values[0].boolean, pclass->accepting);
 
     pclass->accepting = attr->values[0].boolean;
-    cupsdAddPrinterHistory(pclass);
 
     cupsdAddEvent(CUPSD_EVENT_PRINTER_STATE, pclass, NULL, "%s accepting jobs.",
                  pclass->accepting ? "Now" : "No longer");
@@ -1163,7 +1153,7 @@ add_class(cupsd_client_t  *con,           /* I - Client connection */
         attr->values[0].integer != IPP_PRINTER_STOPPED)
     {
       send_ipp_status(con, IPP_BAD_REQUEST,
-                      _("Attempt to set %s printer-state to bad value %d"),
+                      _("Attempt to set %s printer-state to bad value %d."),
                       pclass->name, attr->values[0].integer);
       return;
     }
@@ -1184,7 +1174,6 @@ add_class(cupsd_client_t  *con,           /* I - Client connection */
   {
     strlcpy(pclass->state_message, attr->values[0].string.text,
             sizeof(pclass->state_message));
-    cupsdAddPrinterHistory(pclass);
 
     cupsdAddEvent(CUPSD_EVENT_PRINTER_STATE, pclass, NULL, "%s",
                   pclass->state_message);
@@ -1221,13 +1210,13 @@ add_class(cupsd_client_t  *con,         /* I - Client connection */
        */
 
        send_ipp_status(con, IPP_NOT_FOUND,
-                       _("The printer or class was not found."));
+                       _("The printer or class does not exist."));
        return;
       }
       else if (dtype & CUPS_PRINTER_CLASS)
       {
         send_ipp_status(con, IPP_BAD_REQUEST,
-                       _("Nested classes are not allowed"));
+                       _("Nested classes are not allowed."));
         return;
       }
 
@@ -1275,8 +1264,6 @@ add_class(cupsd_client_t  *con,           /* I - Client connection */
   }
   else
   {
-    cupsdAddPrinterHistory(pclass);
-
     cupsdAddEvent(CUPSD_EVENT_PRINTER_ADDED,
                  pclass, NULL, "New class \"%s\" added by \"%s\".",
                  pclass->name, get_username(con));
@@ -1333,7 +1320,7 @@ add_file(cupsd_client_t *con,             /* I - Connection to client */
 
     if (con)
       send_ipp_status(con, IPP_INTERNAL_ERROR,
-                     _("Unable to allocate memory for file types"));
+                     _("Unable to allocate memory for file types."));
 
     return (-1);
   }
@@ -1387,11 +1374,11 @@ add_job(cupsd_client_t  *con,           /* I - Client connection */
   */
 
   if (!printer->shared &&
-      strcasecmp(con->http.hostname, "localhost") &&
-      strcasecmp(con->http.hostname, ServerName))
+      _cups_strcasecmp(con->http.hostname, "localhost") &&
+      _cups_strcasecmp(con->http.hostname, ServerName))
   {
     send_ipp_status(con, IPP_NOT_AUTHORIZED,
-                    _("The printer or class is not shared"));
+                    _("The printer or class is not shared."));
     return (NULL);
   }
 
@@ -1454,7 +1441,7 @@ add_job(cupsd_client_t  *con,             /* I - Client connection */
              filetype->type);
 
     send_ipp_status(con, IPP_DOCUMENT_FORMAT,
-                    _("Unsupported format \'%s\'"), mimetype);
+                    _("Unsupported format \"%s\"."), mimetype);
 
     ippAddString(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_MIMETYPE,
                  "document-format", NULL, mimetype);
@@ -1481,14 +1468,14 @@ add_job(cupsd_client_t  *con,           /* I - Client connection */
     if (attr->value_tag != IPP_TAG_KEYWORD &&
         attr->value_tag != IPP_TAG_NAME)
     {
-      send_ipp_status(con, IPP_BAD_REQUEST, _("Bad job-sheets value type"));
+      send_ipp_status(con, IPP_BAD_REQUEST, _("Bad job-sheets value type."));
       return (NULL);
     }
 
     if (attr->num_values > 2)
     {
       send_ipp_status(con, IPP_BAD_REQUEST,
-                      _("Too many job-sheets values (%d > 2)"),
+                      _("Too many job-sheets values (%d > 2)."),
                      attr->num_values);
       return (NULL);
     }
@@ -1497,7 +1484,7 @@ add_job(cupsd_client_t  *con,             /* I - Client connection */
       if (strcmp(attr->values[i].string.text, "none") &&
           !cupsdFindBanner(attr->values[i].string.text))
       {
-       send_ipp_status(con, IPP_BAD_REQUEST, _("Bad job-sheets value \"%s\""),
+       send_ipp_status(con, IPP_BAD_REQUEST, _("Bad job-sheets value \"%s\"."),
                        attr->values[i].string.text);
        return (NULL);
       }
@@ -1546,7 +1533,7 @@ add_job(cupsd_client_t  *con,             /* I - Client connection */
 
   if (!ippFindAttribute(con->request, "PageRegion", IPP_TAG_ZERO) &&
       !ippFindAttribute(con->request, "PageSize", IPP_TAG_ZERO) &&
-      _pwgGetPageSize(printer->pwg, con->request, NULL, &exact))
+      _ppdCacheGetPageSize(printer->pc, con->request, NULL, &exact))
   {
     if (!exact &&
         (media_col = ippFindAttribute(con->request, "media-col",
@@ -1594,8 +1581,7 @@ add_job(cupsd_client_t  *con,             /* I - Client connection */
 
   if (MaxJobs && cupsArrayCount(Jobs) >= MaxJobs)
   {
-    send_ipp_status(con, IPP_NOT_POSSIBLE,
-                    _("Too many active jobs."));
+    send_ipp_status(con, IPP_NOT_POSSIBLE, _("Too many active jobs."));
     return (NULL);
   }
 
@@ -1636,7 +1622,7 @@ add_job(cupsd_client_t  *con,             /* I - Client connection */
   if ((job = cupsdAddJob(priority, printer->name)) == NULL)
   {
     send_ipp_status(con, IPP_INTERNAL_ERROR,
-                    _("Unable to add job for destination \"%s\""),
+                    _("Unable to add job for destination \"%s\"."),
                    printer->name);
     return (NULL);
   }
@@ -1649,7 +1635,7 @@ add_job(cupsd_client_t  *con,             /* I - Client connection */
 
   cupsdMarkDirty(CUPSD_DIRTY_JOBS);
 
-  add_job_uuid(con, job);
+  add_job_uuid(job);
   apply_printer_defaults(printer, job);
 
   attr = ippFindAttribute(job->attrs, "requesting-user-name", IPP_TAG_NAME);
@@ -1979,7 +1965,7 @@ add_job(cupsd_client_t  *con,             /* I - Client connection */
   }
   else if ((attr = ippFindAttribute(job->attrs, "job-sheets",
                                     IPP_TAG_ZERO)) != NULL)
-    job->sheets = attr;
+    job->job_sheets = attr;
 
  /*
   * Fill in the response info...
@@ -2166,7 +2152,7 @@ add_job_subscriptions(
                            resource, sizeof(resource)) < HTTP_URI_OK)
         {
           send_ipp_status(con, IPP_NOT_POSSIBLE,
-                         _("Bad notify-recipient-uri URI \"%s\""), recipient);
+                         _("Bad notify-recipient-uri \"%s\"."), recipient);
          ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_ENUM,
                        "notify-status-code", IPP_URI_SCHEME);
          return;
@@ -2178,7 +2164,7 @@ add_job_subscriptions(
        {
           send_ipp_status(con, IPP_NOT_POSSIBLE,
                          _("notify-recipient-uri URI \"%s\" uses unknown "
-                           "scheme"), recipient);
+                           "scheme."), recipient);
          ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_ENUM,
                        "notify-status-code", IPP_URI_SCHEME);
          return;
@@ -2187,7 +2173,7 @@ add_job_subscriptions(
         if (!strcmp(scheme, "rss") && !check_rss_recipient(recipient))
        {
           send_ipp_status(con, IPP_NOT_POSSIBLE,
-                         _("notify-recipient-uri URI \"%s\" is already used"),
+                         _("notify-recipient-uri URI \"%s\" is already used."),
                          recipient);
          ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_ENUM,
                        "notify-status-code", IPP_ATTRIBUTES);
@@ -2202,7 +2188,7 @@ add_job_subscriptions(
         if (strcmp(pullmethod, "ippget"))
        {
           send_ipp_status(con, IPP_NOT_POSSIBLE,
-                         _("Bad notify-pull-method \"%s\""), pullmethod);
+                         _("Bad notify-pull-method \"%s\"."), pullmethod);
          ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_ENUM,
                        "notify-status-code", IPP_ATTRIBUTES);
          return;
@@ -2214,7 +2200,7 @@ add_job_subscriptions(
               strcmp(attr->values[0].string.text, "utf-8"))
       {
         send_ipp_status(con, IPP_CHARSET,
-                       _("Character set \"%s\" not supported"),
+                       _("Character set \"%s\" not supported."),
                        attr->values[0].string.text);
        return;
       }
@@ -2223,7 +2209,7 @@ add_job_subscriptions(
                strcmp(attr->values[0].string.text, DefaultLanguage)))
       {
         send_ipp_status(con, IPP_CHARSET,
-                       _("Language \"%s\" not supported"),
+                       _("Language \"%s\" not supported."),
                        attr->values[0].string.text);
        return;
       }
@@ -2234,7 +2220,7 @@ add_job_subscriptions(
        {
           send_ipp_status(con, IPP_REQUEST_VALUE,
                          _("The notify-user-data value is too large "
-                           "(%d > 63 octets)"),
+                           "(%d > 63 octets)."),
                          attr->values[0].unknown.length);
          return;
        }
@@ -2336,48 +2322,19 @@ add_job_subscriptions(
  */
 
 static void
-add_job_uuid(cupsd_client_t *con,      /* I - Client connection */
-             cupsd_job_t    *job)      /* I - Job */
+add_job_uuid(cupsd_job_t *job)         /* I - Job */
 {
-  char                 uuid[1024];     /* job-uuid string */
-  _cups_md5_state_t    md5state;       /* MD5 state */
-  unsigned char                md5sum[16];     /* MD5 digest/sum */
-
-
- /*
-  * First see if the job already has a job-uuid attribute; if so, return...
-  */
-
-  if (ippFindAttribute(job->attrs, "job-uuid", IPP_TAG_URI))
-    return;
+  char                 uuid[64];       /* job-uuid string */
 
- /*
-  * No job-uuid attribute, so build a version 3 UUID with the local job
-  * ID at the end; see RFC 4122 for details.  Start with the MD5 sum of
-  * the ServerName, server name and port that the client connected to,
-  * and local job ID...
-  */
-
-  snprintf(uuid, sizeof(uuid), "%s:%s:%d:%d", ServerName, con->servername,
-          con->serverport, job->id);
-
-  _cupsMD5Init(&md5state);
-  _cupsMD5Append(&md5state, (unsigned char *)uuid, strlen(uuid));
-  _cupsMD5Finish(&md5state, md5sum);
 
  /*
-  * Format the UUID URI using the MD5 sum and job ID.
+  * Add a job-uuid attribute if none exists...
   */
 
-  snprintf(uuid, sizeof(uuid),
-           "urn:uuid:%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-"
-          "%02x%02x%02x%02x%02x%02x",
-          md5sum[0], md5sum[1], md5sum[2], md5sum[3], md5sum[4], md5sum[5],
-          (md5sum[6] & 15) | 0x30, md5sum[7], (md5sum[8] & 0x3f) | 0x40,
-          md5sum[9], md5sum[10], md5sum[11], md5sum[12], md5sum[13],
-          md5sum[14], md5sum[15]);
-
-  ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_URI, "job-uuid", NULL, uuid);
+  if (!ippFindAttribute(job->attrs, "job-uuid", IPP_TAG_URI))
+    ippAddString(job->attrs, IPP_TAG_JOB, IPP_TAG_URI, "job-uuid", NULL,
+                _httpAssembleUUID(ServerName, RemotePort, job->dest, job->id,
+                                  uuid, sizeof(uuid)));
 }
 
 
@@ -2467,7 +2424,7 @@ add_printer(cupsd_client_t  *con, /* I - Client connection */
       */
 
       send_ipp_status(con, IPP_NOT_POSSIBLE,
-                      _("A class named \"%s\" already exists"),
+                      _("A class named \"%s\" already exists."),
                      resource + 10);
       return;
     }
@@ -2586,7 +2543,7 @@ add_printer(cupsd_client_t  *con, /* I - Client connection */
 
     if (uri_status < HTTP_URI_OK)
     {
-      send_ipp_status(con, IPP_NOT_POSSIBLE, _("Bad device-uri \"%s\""),
+      send_ipp_status(con, IPP_NOT_POSSIBLE, _("Bad device-uri \"%s\"."),
                      attr->values[0].string.text);
       cupsdLogMessage(CUPSD_LOG_DEBUG,
                       "add_printer: httpSeparateURI returned %d", uri_status);
@@ -2606,7 +2563,7 @@ add_printer(cupsd_client_t  *con, /* I - Client connection */
        */
 
        send_ipp_status(con, IPP_NOT_POSSIBLE,
-                       _("File device URIs have been disabled! "
+                       _("File device URIs have been disabled. "
                          "To enable, see the FileDevice directive in "
                          "\"%s/cupsd.conf\"."),
                        ServerRoot);
@@ -2626,8 +2583,8 @@ add_printer(cupsd_client_t  *con, /* I - Client connection */
         * Could not find device in list!
        */
 
-       send_ipp_status(con, IPP_NOT_POSSIBLE, _("Bad device-uri scheme \"%s\""),
-                       scheme);
+       send_ipp_status(con, IPP_NOT_POSSIBLE,
+                        _("Bad device-uri scheme \"%s\"."), scheme);
        return;
       }
     }
@@ -2670,7 +2627,7 @@ add_printer(cupsd_client_t  *con, /* I - Client connection */
 
     if (!supported || i >= supported->num_values)
     {
-      send_ipp_status(con, IPP_NOT_POSSIBLE, _("Bad port-monitor \"%s\""),
+      send_ipp_status(con, IPP_NOT_POSSIBLE, _("Bad port-monitor \"%s\"."),
                      attr->values[0].string.text);
       return;
     }
@@ -2697,7 +2654,6 @@ add_printer(cupsd_client_t  *con, /* I - Client connection */
                     printer->name, attr->values[0].boolean, printer->accepting);
 
     printer->accepting = attr->values[0].boolean;
-    cupsdAddPrinterHistory(printer);
 
     cupsdAddEvent(CUPSD_EVENT_PRINTER_STATE, printer, NULL,
                   "%s accepting jobs.",
@@ -2707,6 +2663,15 @@ add_printer(cupsd_client_t  *con,        /* I - Client connection */
   if ((attr = ippFindAttribute(con->request, "printer-is-shared",
                                IPP_TAG_BOOLEAN)) != NULL)
   {
+    if (attr->values[0].boolean &&
+        printer->num_auth_info_required == 1 &&
+       !strcmp(printer->auth_info_required[0], "negotiate"))
+    {
+      send_ipp_status(con, IPP_BAD_REQUEST,
+                      _("Cannot share a remote Kerberized printer."));
+      return;
+    }
+
     if (printer->shared && !attr->values[0].boolean)
       cupsdDeregisterPrinter(printer, 1);
 
@@ -2723,7 +2688,7 @@ add_printer(cupsd_client_t  *con, /* I - Client connection */
     if (attr->values[0].integer != IPP_PRINTER_IDLE &&
         attr->values[0].integer != IPP_PRINTER_STOPPED)
     {
-      send_ipp_status(con, IPP_BAD_REQUEST, _("Bad printer-state value %d"),
+      send_ipp_status(con, IPP_BAD_REQUEST, _("Bad printer-state value %d."),
                       attr->values[0].integer);
       return;
     }
@@ -2745,7 +2710,6 @@ add_printer(cupsd_client_t  *con, /* I - Client connection */
   {
     strlcpy(printer->state_message, attr->values[0].string.text,
             sizeof(printer->state_message));
-    cupsdAddPrinterHistory(printer);
 
     cupsdAddEvent(CUPSD_EVENT_PRINTER_STATE, printer, NULL, "%s",
                   printer->state_message);
@@ -2758,7 +2722,7 @@ add_printer(cupsd_client_t  *con, /* I - Client connection */
             (int)(sizeof(printer->reasons) / sizeof(printer->reasons[0])))
     {
       send_ipp_status(con, IPP_NOT_POSSIBLE,
-                      _("Too many printer-state-reasons values (%d > %d)"),
+                      _("Too many printer-state-reasons values (%d > %d)."),
                      attr->num_values,
                      (int)(sizeof(printer->reasons) /
                            sizeof(printer->reasons[0])));
@@ -2933,7 +2897,7 @@ add_printer(cupsd_client_t  *con, /* I - Client connection */
 
       if (copy_model(con, attr->values[0].string.text, dstfile))
       {
-        send_ipp_status(con, IPP_INTERNAL_ERROR, _("Unable to copy PPD file"));
+        send_ipp_status(con, IPP_INTERNAL_ERROR, _("Unable to copy PPD file."));
        return;
       }
 
@@ -2952,11 +2916,7 @@ add_printer(cupsd_client_t  *con,        /* I - Client connection */
 
     char cache_name[1024];             /* Cache filename for printer attrs */
 
-    snprintf(cache_name, sizeof(cache_name), "%s/%s.ipp4", CacheDir,
-             printer->name);
-    unlink(cache_name);
-
-    snprintf(cache_name, sizeof(cache_name), "%s/%s.pwg3", CacheDir,
+    snprintf(cache_name, sizeof(cache_name), "%s/%s.data", CacheDir,
              printer->name);
     unlink(cache_name);
 
@@ -3047,8 +3007,6 @@ add_printer(cupsd_client_t  *con, /* I - Client connection */
   }
   else
   {
-    cupsdAddPrinterHistory(printer);
-
     cupsdAddEvent(CUPSD_EVENT_PRINTER_ADDED,
                   printer, NULL, "New printer \"%s\" added by \"%s\".",
                  printer->name, get_username(con));
@@ -3137,6 +3095,8 @@ apple_init_profile(
                        cftext;         /* Localized text */
 
 
+  (void)id;
+
  /*
   * Build the profile name dictionary...
   */
@@ -3144,6 +3104,12 @@ apple_init_profile(
   dict = CFDictionaryCreateMutable(kCFAllocatorDefault, 0,
                                   &kCFTypeDictionaryKeyCallBacks,
                                   &kCFTypeDictionaryValueCallBacks);
+  if (!dict)
+  {
+    cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to initialize profile \"%s\".",
+                    iccfile);
+    return;
+  }
 
   cftext = CFStringCreateWithCString(kCFAllocatorDefault, text,
                                     kCFStringEncodingUTF8);
@@ -3203,7 +3169,7 @@ apple_init_profile(
 #  ifdef HAVE_COLORSYNCREGISTERDEVICE
  if (iccfile)
  {
-    url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, 
+    url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault,
                                                  (const UInt8 *)iccfile,
                                                   strlen(iccfile), false);
 
@@ -3258,9 +3224,9 @@ apple_register_profiles(
   ppd_option_t         *cm_option;     /* Color model option */
   ppd_choice_t         *cm_choice;     /* Color model choice */
   int                  num_profiles;   /* Number of profiles */
-  CMError              error = 0;      /* Last error */
+  OSStatus             error = 0;      /* Last error */
   unsigned             device_id,      /* Printer device ID */
-                       profile_id,     /* Profile ID */
+                       profile_id = 0, /* Profile ID */
                        default_profile_id = 0;
                                        /* Default profile ID */
   CFMutableDictionaryRef device_name;  /* Printer device name dictionary */
@@ -3324,7 +3290,12 @@ apple_register_profiles(
        strlcpy(iccfile, attr->value, sizeof(iccfile));
 
       if (access(iccfile, 0))
+      {
+        cupsdLogMessage(CUPSD_LOG_ERROR,
+                        "%s: ICC Profile \"%s\" does not exist.", p->name,
+                        iccfile);
        continue;
+      }
 
       num_profiles ++;
     }
@@ -3454,7 +3425,8 @@ apple_register_profiles(
         else
          strlcpy(iccfile, attr->value, sizeof(iccfile));
 
-        if (access(iccfile, 0))
+        if (_cupsFileCheck(iccfile, _CUPS_FILE_CHECK_FILE, !RunUser,
+                          cupsdLogFCMessage, p))
          continue;
 
         if (profile_key[0] == 'c')
@@ -3510,41 +3482,54 @@ apple_register_profiles(
         * See if this is the default profile...
        */
 
-        if (!default_profile_id)
+        if (!default_profile_id && q1_choice && q2_choice && q3_choice)
        {
-         if (q2_choice)
-         {
-           if (q3_choice)
-           {
-             snprintf(selector, sizeof(selector), "%s.%s.%s",
-                      q1_choice, q2_choice, q3_choice);
-              if (!strcmp(selector, attr->spec))
-               default_profile_id = profile_id;
-            }
+         snprintf(selector, sizeof(selector), "%s.%s.%s", q1_choice, q2_choice,
+                  q3_choice);
+         if (!strcmp(selector, attr->spec))
+           default_profile_id = profile_id;
+       }
 
-            if (!default_profile_id)
-           {
-             snprintf(selector, sizeof(selector), "%s.%s.", q1_choice,
-                      q2_choice);
-              if (!strcmp(selector, attr->spec))
-               default_profile_id = profile_id;
-           }
-          }
+        if (!default_profile_id && q1_choice && q2_choice)
+       {
+         snprintf(selector, sizeof(selector), "%s.%s.", q1_choice, q2_choice);
+         if (!strcmp(selector, attr->spec))
+           default_profile_id = profile_id;
+       }
 
-          if (!default_profile_id && q3_choice)
-         {
-           snprintf(selector, sizeof(selector), "%s..%s", q1_choice,
-                    q3_choice);
-           if (!strcmp(selector, attr->spec))
-             default_profile_id = profile_id;
-         }
+        if (!default_profile_id && q1_choice && q3_choice)
+       {
+         snprintf(selector, sizeof(selector), "%s..%s", q1_choice, q3_choice);
+         if (!strcmp(selector, attr->spec))
+           default_profile_id = profile_id;
+       }
 
-          if (!default_profile_id)
-         {
-           snprintf(selector, sizeof(selector), "%s..", q1_choice);
-           if (!strcmp(selector, attr->spec))
-             default_profile_id = profile_id;
-         }
+        if (!default_profile_id && q1_choice)
+       {
+         snprintf(selector, sizeof(selector), "%s..", q1_choice);
+         if (!strcmp(selector, attr->spec))
+           default_profile_id = profile_id;
+       }
+
+        if (!default_profile_id && q2_choice && q3_choice)
+       {
+         snprintf(selector, sizeof(selector), ".%s.%s", q2_choice, q3_choice);
+         if (!strcmp(selector, attr->spec))
+           default_profile_id = profile_id;
+       }
+
+        if (!default_profile_id && q2_choice)
+       {
+         snprintf(selector, sizeof(selector), ".%s.", q2_choice);
+         if (!strcmp(selector, attr->spec))
+           default_profile_id = profile_id;
+       }
+
+        if (!default_profile_id && q3_choice)
+       {
+         snprintf(selector, sizeof(selector), "..%s", q3_choice);
+         if (!strcmp(selector, attr->spec))
+           default_profile_id = profile_id;
        }
       }
 
@@ -3693,12 +3678,14 @@ apple_register_profiles(
 
     switch (ppd->colorspace)
     {
+      default :
       case PPD_CS_RGB :
       case PPD_CS_CMY :
           profile_id = _ppdHashName("RGB..");
           apple_init_profile(ppd, NULL, profile, profile_id, "RGB", "RGB",
                             NULL);
           break;
+
       case PPD_CS_RGBK :
       case PPD_CS_CMYK :
           profile_id = _ppdHashName("CMYK..");
@@ -3759,6 +3746,7 @@ apple_register_profiles(
 
     switch (ppd->colorspace)
     {
+      default :
       case PPD_CS_RGB :
       case PPD_CS_CMY :
           profile_id = _ppdHashName("RGB..");
@@ -3843,7 +3831,7 @@ apple_register_profiles(
        kCFPreferencesCurrentHost
       };
       CFDictionaryRef  deviceDict;     /* Device dictionary */
-      CFUUIDRef                deviceUUID;     /* Device UUID (TODO: use printer-uuid value) */
+      CFUUIDRef                deviceUUID;     /* Device UUID */
 
       deviceDict = CFDictionaryCreate(kCFAllocatorDefault,
                                      (const void **)deviceDictKeys,
@@ -3853,8 +3841,9 @@ apple_register_profiles(
                                      &kCFTypeDictionaryKeyCallBacks,
                                      &kCFTypeDictionaryValueCallBacks);
       deviceUUID = ColorSyncCreateUUIDFromUInt32(device_id);
-      if (deviceDict && deviceUUID &&
-          !ColorSyncRegisterDevice(kColorSyncPrinterDeviceClass, deviceUUID,
+
+      if (!deviceDict || !deviceUUID ||
+         !ColorSyncRegisterDevice(kColorSyncPrinterDeviceClass, deviceUUID,
                                   deviceDict))
        error = 1001;
 
@@ -3935,11 +3924,15 @@ apple_unregister_profiles(
 #  ifdef HAVE_COLORSYNCREGISTERDEVICE
   if (ColorSyncUnregisterDevice != NULL)
   {
-    CFUUIDRef deviceUUID;              /* Printer UUID */
+   /*
+    * Because we may have registered the printer profiles using a prior device
+    * ID-based UUID, remove both the old style UUID and current UUID for the
+    * printer.
+    */
 
-    deviceUUID = ColorSyncCreateUUIDFromUInt32(_ppdHashName(p->name));
-                                       /* TODO: Use printer-uuid value */
+    CFUUIDRef deviceUUID;              /* Device UUID */
 
+    deviceUUID = ColorSyncCreateUUIDFromUInt32(_ppdHashName(p->name));
     if (deviceUUID)
     {
       ColorSyncUnregisterDevice(kColorSyncPrinterDeviceClass, deviceUUID);
@@ -3954,6 +3947,7 @@ apple_unregister_profiles(
 }
 #endif /* __APPLE__ */
 
+
 /*
  * 'apply_printer_defaults()' - Apply printer default options to a job.
  */
@@ -4039,7 +4033,7 @@ authenticate_job(cupsd_client_t  *con,    /* I - Client connection */
                                  IPP_TAG_INTEGER)) == NULL)
     {
       send_ipp_status(con, IPP_BAD_REQUEST,
-                      _("Got a printer-uri attribute but no job-id"));
+                      _("Got a printer-uri attribute but no job-id."));
       return;
     }
 
@@ -4061,7 +4055,7 @@ authenticate_job(cupsd_client_t  *con,    /* I - Client connection */
       * Not a valid URI!
       */
 
-      send_ipp_status(con, IPP_BAD_REQUEST, _("Bad job-uri attribute \"%s\""),
+      send_ipp_status(con, IPP_BAD_REQUEST, _("Bad job-uri \"%s\"."),
                       uri->values[0].string.text);
       return;
     }
@@ -4079,8 +4073,7 @@ authenticate_job(cupsd_client_t  *con,    /* I - Client connection */
     * Nope - return a "not found" error...
     */
 
-    send_ipp_status(con, IPP_NOT_FOUND,
-                    _("Job #%d does not exist"), jobid);
+    send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist."), jobid);
     return;
   }
 
@@ -4095,7 +4088,7 @@ authenticate_job(cupsd_client_t  *con,    /* I - Client connection */
     */
 
     send_ipp_status(con, IPP_NOT_POSSIBLE,
-                    _("Job #%d is not held for authentication"),
+                    _("Job #%d is not held for authentication."),
                    jobid);
     return;
   }
@@ -4123,7 +4116,7 @@ authenticate_job(cupsd_client_t  *con,    /* I - Client connection */
       send_http_error(con, HTTP_UNAUTHORIZED, printer);
     else
       send_ipp_status(con, IPP_NOT_AUTHORIZED,
-                     _("No authentication information provided"));
+                     _("No authentication information provided."));
     return;
   }
 
@@ -4164,7 +4157,11 @@ authenticate_job(cupsd_client_t  *con,   /* I - Client connection */
 
   cupsdReleaseJob(job);
 
+  cupsdAddEvent(CUPSD_EVENT_JOB_STATE, NULL, job, "Job authenticated by user");
+
   cupsdLogJob(job, CUPSD_LOG_INFO, "Authenticated by \"%s\".", con->username);
+
+  cupsdCheckJobs();
 }
 
 
@@ -4218,7 +4215,7 @@ cancel_all_jobs(cupsd_client_t  *con,     /* I - Client connection */
          else
          {
            send_ipp_status(con, IPP_BAD_REQUEST,
-                           _("Missing requesting-user-name attribute"));
+                           _("Missing requesting-user-name attribute."));
            return;
          }
        }
@@ -4243,7 +4240,7 @@ cancel_all_jobs(cupsd_client_t  *con,     /* I - Client connection */
         else
         {
          send_ipp_status(con, IPP_BAD_REQUEST,
-                         _("Missing requesting-user-name attribute"));
+                         _("Missing requesting-user-name attribute."));
          return;
         }
 
@@ -4260,7 +4257,7 @@ cancel_all_jobs(cupsd_client_t  *con,     /* I - Client connection */
   if (strcmp(uri->name, "printer-uri"))
   {
     send_ipp_status(con, IPP_BAD_REQUEST,
-                    _("The printer-uri attribute is required"));
+                    _("The printer-uri attribute is required."));
     return;
   }
 
@@ -4283,7 +4280,7 @@ cancel_all_jobs(cupsd_client_t  *con,     /* I - Client connection */
         (!strncmp(resource, "/classes/", 9) && resource[9]))
     {
       send_ipp_status(con, IPP_NOT_FOUND,
-                      _("The printer or class was not found."));
+                      _("The printer or class does not exist."));
       return;
     }
 
@@ -4307,7 +4304,7 @@ cancel_all_jobs(cupsd_client_t  *con,     /* I - Client connection */
 
       if (i < job_ids->num_values)
       {
-       send_ipp_status(con, IPP_NOT_FOUND, _("job-id %d not found."),
+       send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist."),
                        job_ids->values[i].integer);
        return;
       }
@@ -4356,13 +4353,13 @@ cancel_all_jobs(cupsd_client_t  *con,   /* I - Client connection */
       for (i = 0; i < job_ids->num_values; i ++)
       {
        if ((job = cupsdFindJob(job_ids->values[i].integer)) == NULL ||
-           strcasecmp(job->dest, printer->name))
+           _cups_strcasecmp(job->dest, printer->name))
          break;
       }
 
       if (i < job_ids->num_values)
       {
-       send_ipp_status(con, IPP_NOT_FOUND, _("job-id %d not found."),
+       send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist."),
                        job_ids->values[i].integer);
        return;
       }
@@ -4437,7 +4434,7 @@ cancel_job(cupsd_client_t  *con,  /* I - Client connection */
                                  IPP_TAG_INTEGER)) == NULL)
     {
       send_ipp_status(con, IPP_BAD_REQUEST,
-                      _("Got a printer-uri attribute but no job-id"));
+                      _("Got a printer-uri attribute but no job-id."));
       return;
     }
 
@@ -4454,7 +4451,7 @@ cancel_job(cupsd_client_t  *con,  /* I - Client connection */
        */
 
        send_ipp_status(con, IPP_NOT_FOUND,
-                       _("The printer or class was not found."));
+                       _("The printer or class does not exist."));
        return;
       }
 
@@ -4466,7 +4463,7 @@ cancel_job(cupsd_client_t  *con,  /* I - Client connection */
           job;
           job = (cupsd_job_t *)cupsArrayNext(ActiveJobs))
        if (job->state_value <= IPP_JOB_PROCESSING &&
-           !strcasecmp(job->dest, printer->name))
+           !_cups_strcasecmp(job->dest, printer->name))
          break;
 
       if (job)
@@ -4481,14 +4478,14 @@ cancel_job(cupsd_client_t  *con,        /* I - Client connection */
             job;
             job = (cupsd_job_t *)cupsArrayNext(ActiveJobs))
          if (job->state_value == IPP_JOB_STOPPED &&
-             !strcasecmp(job->dest, printer->name))
+             !_cups_strcasecmp(job->dest, printer->name))
            break;
 
        if (job)
          jobid = job->id;
        else
        {
-         send_ipp_status(con, IPP_NOT_POSSIBLE, _("No active jobs on %s"),
+         send_ipp_status(con, IPP_NOT_POSSIBLE, _("No active jobs on %s."),
                          printer->name);
          return;
        }
@@ -4511,8 +4508,7 @@ cancel_job(cupsd_client_t  *con,  /* I - Client connection */
       * Not a valid URI!
       */
 
-      send_ipp_status(con, IPP_BAD_REQUEST,
-                      _("Bad job-uri attribute \"%s\""),
+      send_ipp_status(con, IPP_BAD_REQUEST, _("Bad job-uri \"%s\"."),
                       uri->values[0].string.text);
       return;
     }
@@ -4540,7 +4536,7 @@ cancel_job(cupsd_client_t  *con,  /* I - Client connection */
     * Nope - return a "not found" error...
     */
 
-    send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist"), jobid);
+    send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist."), jobid);
     return;
   }
 
@@ -4635,7 +4631,7 @@ cancel_subscription(
     */
 
     send_ipp_status(con, IPP_NOT_FOUND,
-                    _("notify-subscription-id %d no good"), sub_id);
+                    _("Subscription #%d does not exist."), sub_id);
     return;
   }
 
@@ -4888,7 +4884,7 @@ check_quotas(cupsd_client_t  *con,        /* I - Client connection */
          break;
       }
 #else
-      else if (!strcasecmp(username, name))
+      else if (!_cups_strcasecmp(username, name))
        break;
 #endif /* HAVE_MBR_UID_TO_UUID */
 
@@ -4973,7 +4969,7 @@ close_job(cupsd_client_t  *con,           /* I - Client connection */
                               IPP_TAG_INTEGER)) == NULL)
   {
     send_ipp_status(con, IPP_BAD_REQUEST,
-                   _("Got a printer-uri attribute but no job-id"));
+                   _("Got a printer-uri attribute but no job-id."));
     return;
   }
 
@@ -4983,7 +4979,7 @@ close_job(cupsd_client_t  *con,           /* I - Client connection */
     * Nope - return a "not found" error...
     */
 
-    send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist"),
+    send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist."),
                     attr->values[0].integer);
     return;
   }
@@ -5271,20 +5267,24 @@ copy_attrs(ipp_t        *to,            /* I - Destination request */
          fromattr->group_tag != IPP_TAG_ZERO) || !fromattr->name)
       continue;
 
-    if (exclude && 
+    if (!strcmp(fromattr->name, "job-printer-uri"))
+      continue;
+
+    if (exclude &&
         (cupsArrayFind(exclude, fromattr->name) ||
         cupsArrayFind(exclude, "all")))
     {
      /*
       * We need to exclude this attribute for security reasons; we require the
-      * job-id and job-printer-uri attributes regardless of the security
-      * settings for IPP conformance.
+      * job-id attribute regardless of the security settings for IPP
+      * conformance.
+      *
+      * The job-printer-uri attribute is handled by copy_job_attrs().
       *
       * Subscription attribute security is handled by copy_subscription_attrs().
       */
 
-      if (strcmp(fromattr->name, "job-id") &&
-         strcmp(fromattr->name, "job-printer-uri"))
+      if (strcmp(fromattr->name, "job-id"))
         continue;
     }
 
@@ -5533,7 +5533,7 @@ copy_banner(cupsd_client_t *con,  /* I - Client connection */
          case IPP_TAG_KEYWORD :
          case IPP_TAG_CHARSET :
          case IPP_TAG_LANGUAGE :
-             if (!strcasecmp(banner->filetype->type, "postscript"))
+             if (!_cups_strcasecmp(banner->filetype->type, "postscript"))
              {
               /*
                * Need to quote strings for PS banners...
@@ -5693,11 +5693,9 @@ copy_model(cupsd_client_t *con,          /* I - Client connection */
   snprintf(buffer, sizeof(buffer), "%s/daemon/cups-driverd", ServerBin);
   snprintf(tempfile, sizeof(tempfile), "%s/%d.ppd", TempDir, con->http.fd);
   tempfd = open(tempfile, O_WRONLY | O_CREAT | O_TRUNC, 0600);
-  if (tempfd < 0)
+  if (tempfd < 0 || cupsdOpenPipe(temppipe))
     return (-1);
 
-  cupsdOpenPipe(temppipe);
-
   cupsdLogMessage(CUPSD_LOG_DEBUG,
                   "copy_model: Running \"cups-driverd cat %s\"...", from);
 
@@ -5948,10 +5946,6 @@ copy_job_attrs(cupsd_client_t *con,      /* I - Client connection */
   * Send the requested attributes for each job...
   */
 
-  httpAssembleURIf(HTTP_URI_CODING_ALL, job_uri, sizeof(job_uri), "ipp", NULL,
-                   con->servername, con->serverport, "/jobs/%d",
-                  job->id);
-
   if (!cupsArrayFind(exclude, "all"))
   {
     if ((!exclude || !cupsArrayFind(exclude, "document-count")) &&
@@ -5966,8 +5960,13 @@ copy_job_attrs(cupsd_client_t *con,      /* I - Client connection */
 
     if ((!exclude || !cupsArrayFind(exclude, "job-more-info")) &&
         (!ra || cupsArrayFind(ra, "job-more-info")))
+    {
+      httpAssembleURIf(HTTP_URI_CODING_ALL, job_uri, sizeof(job_uri), "http",
+                       NULL, con->servername, con->serverport, "/jobs/%d",
+                      job->id);
       ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_URI,
                   "job-more-info", NULL, job_uri);
+    }
 
     if (job->state_value > IPP_JOB_PROCESSING &&
        (!exclude || !cupsArrayFind(exclude, "job-preserved")) &&
@@ -5981,12 +5980,28 @@ copy_job_attrs(cupsd_client_t *con,     /* I - Client connection */
                    "job-printer-up-time", time(NULL));
   }
 
+  if (!ra || cupsArrayFind(ra, "job-printer-uri"))
+  {
+    httpAssembleURIf(HTTP_URI_CODING_ALL, job_uri, sizeof(job_uri), "ipp", NULL,
+                    con->servername, con->serverport,
+                    job->dtype & (CUPS_PRINTER_IMPLICIT | CUPS_PRINTER_CLASS) ?
+                        "/classes/%s" : "/printers/%s",
+                    job->dest);
+    ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_URI,
+                "job-printer-uri", NULL, job_uri);
+  }
+
   if (!ra || cupsArrayFind(ra, "job-state-reasons"))
     add_job_state_reasons(con, job);
 
   if (!ra || cupsArrayFind(ra, "job-uri"))
+  {
+    httpAssembleURIf(HTTP_URI_CODING_ALL, job_uri, sizeof(job_uri), "ipp", NULL,
+                    con->servername, con->serverport, "/jobs/%d",
+                    job->id);
     ippAddString(con->response, IPP_TAG_JOB, IPP_TAG_URI,
                 "job-uri", NULL, job_uri);
+  }
 
   copy_attrs(con->response, job->attrs, ra, IPP_TAG_JOB, 0, exclude);
 }
@@ -6008,7 +6023,6 @@ copy_printer_attrs(
                                        /* Printer icons */
   time_t               curtime;        /* Current time */
   int                  i;              /* Looping var */
-  ipp_attribute_t      *history;       /* History collection */
 
 
  /*
@@ -6146,23 +6160,6 @@ copy_printer_attrs(
     ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
                   "printer-state-change-time", printer->state_time);
 
-  if (MaxPrinterHistory > 0 && printer->num_history > 0 &&
-      cupsArrayFind(ra, "printer-state-history"))
-  {
-   /*
-    * Printer history is only sent if specifically requested, so that
-    * older CUPS/IPP clients won't barf on the collection attributes.
-    */
-
-    history = ippAddCollections(con->response, IPP_TAG_PRINTER,
-                                "printer-state-history",
-                                printer->num_history, NULL);
-
-    for (i = 0; i < printer->num_history; i ++)
-      copy_attrs(history->values[i].collection = ippNew(), printer->history[i],
-                 NULL, IPP_TAG_ZERO, 0, NULL);
-  }
-
   if (!ra || cupsArrayFind(ra, "printer-state-message"))
     ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_TEXT,
                 "printer-state-message", NULL, printer->state_message);
@@ -6174,7 +6171,6 @@ copy_printer_attrs(
   {
     int type;                          /* printer-type value */
 
-
    /*
     * Add the CUPS-specific printer-type attribute...
     */
@@ -6367,7 +6363,7 @@ create_job(cupsd_client_t  *con,  /* I - Client connection */
     */
 
     send_ipp_status(con, IPP_NOT_FOUND,
-                    _("The printer or class was not found."));
+                    _("The printer or class does not exist."));
     return;
   }
 
@@ -6670,7 +6666,7 @@ create_subscription(
     */
 
     send_ipp_status(con, IPP_NOT_FOUND,
-                    _("The printer or class was not found."));
+                    _("The printer or class does not exist."));
     return;
   }
 
@@ -6711,7 +6707,7 @@ create_subscription(
   if (!attr)
   {
     send_ipp_status(con, IPP_BAD_REQUEST,
-                    _("No subscription attributes in request"));
+                    _("No subscription attributes in request."));
     return;
   }
 
@@ -6769,7 +6765,7 @@ create_subscription(
                            resource, sizeof(resource)) < HTTP_URI_OK)
         {
           send_ipp_status(con, IPP_NOT_POSSIBLE,
-                         _("Bad notify-recipient-uri URI \"%s\""), recipient);
+                         _("Bad notify-recipient-uri \"%s\"."), recipient);
          ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_ENUM,
                        "notify-status-code", IPP_URI_SCHEME);
          return;
@@ -6781,7 +6777,7 @@ create_subscription(
        {
           send_ipp_status(con, IPP_NOT_POSSIBLE,
                          _("notify-recipient-uri URI \"%s\" uses unknown "
-                           "scheme"), recipient);
+                           "scheme."), recipient);
          ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_ENUM,
                        "notify-status-code", IPP_URI_SCHEME);
          return;
@@ -6790,7 +6786,7 @@ create_subscription(
         if (!strcmp(scheme, "rss") && !check_rss_recipient(recipient))
        {
           send_ipp_status(con, IPP_NOT_POSSIBLE,
-                         _("notify-recipient-uri URI \"%s\" is already used"),
+                         _("notify-recipient-uri URI \"%s\" is already used."),
                          recipient);
          ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_ENUM,
                        "notify-status-code", IPP_ATTRIBUTES);
@@ -6805,7 +6801,7 @@ create_subscription(
         if (strcmp(pullmethod, "ippget"))
        {
           send_ipp_status(con, IPP_NOT_POSSIBLE,
-                         _("Bad notify-pull-method \"%s\""), pullmethod);
+                         _("Bad notify-pull-method \"%s\"."), pullmethod);
          ippAddInteger(con->response, IPP_TAG_SUBSCRIPTION, IPP_TAG_ENUM,
                        "notify-status-code", IPP_ATTRIBUTES);
          return;
@@ -6817,7 +6813,7 @@ create_subscription(
               strcmp(attr->values[0].string.text, "utf-8"))
       {
         send_ipp_status(con, IPP_CHARSET,
-                       _("Character set \"%s\" not supported"),
+                       _("Character set \"%s\" not supported."),
                        attr->values[0].string.text);
        return;
       }
@@ -6826,7 +6822,7 @@ create_subscription(
                strcmp(attr->values[0].string.text, DefaultLanguage)))
       {
         send_ipp_status(con, IPP_CHARSET,
-                       _("Language \"%s\" not supported"),
+                       _("Language \"%s\" not supported."),
                        attr->values[0].string.text);
        return;
       }
@@ -6837,7 +6833,7 @@ create_subscription(
        {
           send_ipp_status(con, IPP_REQUEST_VALUE,
                          _("The notify-user-data value is too large "
-                           "(%d > 63 octets)"),
+                           "(%d > 63 octets)."),
                          attr->values[0].unknown.length);
          return;
        }
@@ -6885,7 +6881,7 @@ create_subscription(
       else
       {
         send_ipp_status(con, IPP_BAD_REQUEST,
-                       _("notify-events not specified"));
+                       _("notify-events not specified."));
        return;
       }
     }
@@ -6903,7 +6899,8 @@ create_subscription(
     {
       if ((job = cupsdFindJob(jobid)) == NULL)
       {
-       send_ipp_status(con, IPP_NOT_FOUND, _("Job %d not found"), jobid);
+       send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist."),
+                       jobid);
        return;
       }
     }
@@ -6918,14 +6915,14 @@ create_subscription(
     }
 
     if (job)
-      cupsdLogMessage(CUPSD_LOG_DEBUG, "Added subscription %d for job %d",
+      cupsdLogMessage(CUPSD_LOG_DEBUG, "Added subscription #%d for job %d.",
                      sub->id, job->id);
     else if (printer)
       cupsdLogMessage(CUPSD_LOG_DEBUG,
-                      "Added subscription %d for printer \"%s\"",
+                      "Added subscription #%d for printer \"%s\".",
                      sub->id, printer->name);
     else
-      cupsdLogMessage(CUPSD_LOG_DEBUG, "Added subscription %d for server",
+      cupsdLogMessage(CUPSD_LOG_DEBUG, "Added subscription #%d for server.",
                      sub->id);
 
     sub->interval = interval;
@@ -6983,7 +6980,7 @@ delete_printer(cupsd_client_t  *con,      /* I - Client connection */
     */
 
     send_ipp_status(con, IPP_NOT_FOUND,
-                    _("The printer or class was not found."));
+                    _("The printer or class does not exist."));
     return;
   }
 
@@ -7026,13 +7023,10 @@ delete_printer(cupsd_client_t  *con,    /* I - Client connection */
            printer->name);
   unlink(filename);
 
-  snprintf(filename, sizeof(filename), "%s/%s.ipp4", CacheDir, printer->name);
-  unlink(filename);
-
   snprintf(filename, sizeof(filename), "%s/%s.png", CacheDir, printer->name);
   unlink(filename);
 
-  snprintf(filename, sizeof(filename), "%s/%s.pwg3", CacheDir, printer->name);
+  snprintf(filename, sizeof(filename), "%s/%s.data", CacheDir, printer->name);
   unlink(filename);
 
 #ifdef __APPLE__
@@ -7106,7 +7100,7 @@ get_default(cupsd_client_t *con)  /* I - Client connection */
     con->response->request.status.status_code = IPP_OK;
   }
   else
-    send_ipp_status(con, IPP_NOT_FOUND, _("No default printer"));
+    send_ipp_status(con, IPP_NOT_FOUND, _("No default printer."));
 }
 
 
@@ -7243,7 +7237,7 @@ get_document(cupsd_client_t  *con,        /* I - Client connection */
                                  IPP_TAG_INTEGER)) == NULL)
     {
       send_ipp_status(con, IPP_BAD_REQUEST,
-                      _("Got a printer-uri attribute but no job-id"));
+                      _("Got a printer-uri attribute but no job-id."));
       return;
     }
 
@@ -7265,8 +7259,7 @@ get_document(cupsd_client_t  *con,        /* I - Client connection */
       * Not a valid URI!
       */
 
-      send_ipp_status(con, IPP_BAD_REQUEST,
-                      _("Bad job-uri attribute \"%s\""),
+      send_ipp_status(con, IPP_BAD_REQUEST, _("Bad job-uri \"%s\"."),
                       uri->values[0].string.text);
       return;
     }
@@ -7284,7 +7277,7 @@ get_document(cupsd_client_t  *con,        /* I - Client connection */
     * Nope - return a "not found" error...
     */
 
-    send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist"), jobid);
+    send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist."), jobid);
     return;
   }
 
@@ -7292,7 +7285,8 @@ get_document(cupsd_client_t  *con,        /* I - Client connection */
   * Check policy...
   */
 
-  if ((status = cupsdCheckPolicy(DefaultPolicyPtr, con, NULL)) != HTTP_OK)
+  if ((status = cupsdCheckPolicy(DefaultPolicyPtr, con,
+                                 job->username)) != HTTP_OK)
   {
     send_http_error(con, status, NULL);
     return;
@@ -7306,15 +7300,16 @@ get_document(cupsd_client_t  *con,      /* I - Client connection */
                                IPP_TAG_INTEGER)) == NULL)
   {
     send_ipp_status(con, IPP_BAD_REQUEST,
-                    _("Missing document-number attribute"));
+                    _("Missing document-number attribute."));
     return;
   }
 
   if ((docnum = attr->values[0].integer) < 1 || docnum > job->num_files ||
       attr->num_values > 1)
   {
-    send_ipp_status(con, IPP_NOT_FOUND, _("Document %d not found in job %d."),
-                    docnum, jobid);
+    send_ipp_status(con, IPP_NOT_FOUND,
+                    _("Document #%d does not exist in job #%d."), docnum,
+                   jobid);
     return;
   }
 
@@ -7326,7 +7321,8 @@ get_document(cupsd_client_t  *con,        /* I - Client connection */
                     "Unable to open document %d in job %d - %s", docnum, jobid,
                    strerror(errno));
     send_ipp_status(con, IPP_NOT_FOUND,
-                    _("Unable to open document %d in job %d"), docnum, jobid);
+                    _("Unable to open document #%d in job #%d."), docnum,
+                   jobid);
     return;
   }
 
@@ -7388,7 +7384,7 @@ get_job_attrs(cupsd_client_t  *con,       /* I - Client connection */
                                  IPP_TAG_INTEGER)) == NULL)
     {
       send_ipp_status(con, IPP_BAD_REQUEST,
-                      _("Got a printer-uri attribute but no job-id"));
+                      _("Got a printer-uri attribute but no job-id."));
       return;
     }
 
@@ -7410,8 +7406,7 @@ get_job_attrs(cupsd_client_t  *con,       /* I - Client connection */
       * Not a valid URI!
       */
 
-      send_ipp_status(con, IPP_BAD_REQUEST,
-                      _("Bad job-uri attribute \"%s\""),
+      send_ipp_status(con, IPP_BAD_REQUEST, _("Bad job-uri \"%s\"."),
                       uri->values[0].string.text);
       return;
     }
@@ -7429,7 +7424,7 @@ get_job_attrs(cupsd_client_t  *con,       /* I - Client connection */
     * Nope - return a "not found" error...
     */
 
-    send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist"), jobid);
+    send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist."), jobid);
     return;
   }
 
@@ -7508,7 +7503,7 @@ get_jobs(cupsd_client_t  *con,            /* I - Client connection */
 
   if (strcmp(uri->name, "printer-uri"))
   {
-    send_ipp_status(con, IPP_BAD_REQUEST, _("No printer-uri in request"));
+    send_ipp_status(con, IPP_BAD_REQUEST, _("No printer-uri in request."));
     return;
   }
 
@@ -7545,7 +7540,7 @@ get_jobs(cupsd_client_t  *con,            /* I - Client connection */
     */
 
     send_ipp_status(con, IPP_NOT_FOUND,
-                    _("The printer or class was not found."));
+                    _("The printer or class does not exist."));
     return;
   }
   else
@@ -7729,7 +7724,7 @@ get_jobs(cupsd_client_t  *con,            /* I - Client connection */
 
     if (i < job_ids->num_values)
     {
-      send_ipp_status(con, IPP_NOT_FOUND, _("job-id %d not found."),
+      send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist."),
                       job_ids->values[i].integer);
       return;
     }
@@ -7803,7 +7798,7 @@ get_jobs(cupsd_client_t  *con,            /* I - Client connection */
        continue;
       }
 
-      if (username[0] && strcasecmp(username, job->username))
+      if (username[0] && _cups_strcasecmp(username, job->username))
        continue;
 
       if (count > 0)
@@ -7859,7 +7854,7 @@ get_notifications(cupsd_client_t *con)    /* I - Client connection */
   if (!ids)
   {
     send_ipp_status(con, IPP_BAD_REQUEST,
-                    _("Missing notify-subscription-ids attribute"));
+                    _("Missing notify-subscription-ids attribute."));
     return;
   }
 
@@ -7875,8 +7870,7 @@ get_notifications(cupsd_client_t *con)    /* I - Client connection */
       * Bad subscription ID...
       */
 
-      send_ipp_status(con, IPP_NOT_FOUND,
-                      _("notify-subscription-id %d no good"),
+      send_ipp_status(con, IPP_NOT_FOUND, _("Subscription #%d does not exist."),
                      ids->values[i].integer);
       return;
     }
@@ -8312,7 +8306,7 @@ get_printer_attrs(cupsd_client_t  *con,   /* I - Client connection */
     */
 
     send_ipp_status(con, IPP_NOT_FOUND,
-                    _("The printer or class was not found."));
+                    _("The printer or class does not exist."));
     return;
   }
 
@@ -8368,7 +8362,7 @@ get_printer_supported(
     */
 
     send_ipp_status(con, IPP_NOT_FOUND,
-                    _("The printer or class was not found."));
+                    _("The printer or class does not exist."));
     return;
   }
 
@@ -8512,7 +8506,7 @@ get_printers(cupsd_client_t *con, /* I - Client connection */
     if ((!type || (printer->type & CUPS_PRINTER_CLASS) == type) &&
         (printer->type & printer_mask) == printer_type &&
        (!location ||
-        (printer->location && !strcasecmp(printer->location, location))))
+        (printer->location && !_cups_strcasecmp(printer->location, location))))
     {
      /*
       * If HideImplicitMembers is enabled, see if this printer or class
@@ -8585,8 +8579,8 @@ get_subscription_attrs(
     * Bad subscription ID...
     */
 
-    send_ipp_status(con, IPP_NOT_FOUND,
-                    _("notify-subscription-id %d no good"), sub_id);
+    send_ipp_status(con, IPP_NOT_FOUND, _("Subscription #%d does not exist."),
+                    sub_id);
     return;
   }
 
@@ -8679,8 +8673,8 @@ get_subscriptions(cupsd_client_t  *con,   /* I - Client connection */
 
     if (!job)
     {
-      send_ipp_status(con, IPP_NOT_FOUND, _("Job #%s does not exist"),
-                      resource + 6);
+      send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist."),
+                      atoi(resource + 6));
       return;
     }
   }
@@ -8691,7 +8685,7 @@ get_subscriptions(cupsd_client_t  *con,   /* I - Client connection */
     */
 
     send_ipp_status(con, IPP_NOT_FOUND,
-                    _("The printer or class was not found."));
+                    _("The printer or class does not exist."));
     return;
   }
   else if ((attr = ippFindAttribute(con->request, "notify-job-id",
@@ -8701,7 +8695,7 @@ get_subscriptions(cupsd_client_t  *con,   /* I - Client connection */
 
     if (!job)
     {
-      send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist"),
+      send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist."),
                       attr->values[0].integer);
       return;
     }
@@ -8752,7 +8746,7 @@ get_subscriptions(cupsd_client_t  *con,   /* I - Client connection */
        sub;
        sub = (cupsd_subscription_t *)cupsArrayNext(Subscriptions))
     if ((!printer || sub->dest == printer) && (!job || sub->job == job) &&
-        (!username[0] || !strcasecmp(username, sub->owner)))
+        (!username[0] || !_cups_strcasecmp(username, sub->owner)))
     {
       ippAddSeparator(con->response);
 
@@ -8832,7 +8826,7 @@ hold_job(cupsd_client_t  *con,            /* I - Client connection */
                                  IPP_TAG_INTEGER)) == NULL)
     {
       send_ipp_status(con, IPP_BAD_REQUEST,
-                      _("Got a printer-uri attribute but no job-id"));
+                      _("Got a printer-uri attribute but no job-id."));
       return;
     }
 
@@ -8855,7 +8849,7 @@ hold_job(cupsd_client_t  *con,            /* I - Client connection */
       */
 
       send_ipp_status(con, IPP_BAD_REQUEST,
-                      _("Bad job-uri attribute \"%s\""),
+                      _("Bad job-uri \"%s\"."),
                       uri->values[0].string.text);
       return;
     }
@@ -8873,7 +8867,7 @@ hold_job(cupsd_client_t  *con,            /* I - Client connection */
     * Nope - return a "not found" error...
     */
 
-    send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist"), jobid);
+    send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist."), jobid);
     return;
   }
 
@@ -8888,6 +8882,22 @@ hold_job(cupsd_client_t  *con,           /* I - Client connection */
     return;
   }
 
+ /*
+  * See if the job is in a state that allows holding...
+  */
+
+  if (job->state_value > IPP_JOB_STOPPED)
+  {
+   /*
+    * Return a "not-possible" error...
+    */
+
+    send_ipp_status(con, IPP_NOT_POSSIBLE,
+                   _("Job #%d is finished and cannot be altered."),
+                   job->id);
+    return;
+  }
+
  /*
   * Hold the job and return...
   */
@@ -8941,7 +8951,7 @@ hold_new_jobs(cupsd_client_t  *con,       /* I - Connection */
     */
 
     send_ipp_status(con, IPP_NOT_FOUND,
-                    _("The printer or class was not found."));
+                    _("The printer or class does not exist."));
     return;
   }
 
@@ -8962,7 +8972,6 @@ hold_new_jobs(cupsd_client_t  *con,       /* I - Connection */
   printer->holding_new_jobs = 1;
 
   cupsdSetPrinterReasons(printer, "+hold-new-jobs");
-  cupsdAddPrinterHistory(printer);
 
   if (dtype & CUPS_PRINTER_CLASS)
     cupsdLogMessage(CUPSD_LOG_INFO,
@@ -9020,7 +9029,7 @@ move_job(cupsd_client_t  *con,            /* I - Client connection */
     */
 
     send_ipp_status(con, IPP_BAD_REQUEST,
-                    _("job-printer-uri attribute missing"));
+                    _("job-printer-uri attribute missing."));
     return;
   }
 
@@ -9031,7 +9040,7 @@ move_job(cupsd_client_t  *con,            /* I - Client connection */
     */
 
     send_ipp_status(con, IPP_NOT_FOUND,
-                    _("The printer or class was not found."));
+                    _("The printer or class does not exist."));
     return;
   }
 
@@ -9064,7 +9073,7 @@ move_job(cupsd_client_t  *con,            /* I - Client connection */
        */
 
        send_ipp_status(con, IPP_NOT_FOUND,
-                       _("The printer or class was not found."));
+                       _("The printer or class does not exist."));
        return;
       }
 
@@ -9083,7 +9092,7 @@ move_job(cupsd_client_t  *con,            /* I - Client connection */
        */
 
        send_ipp_status(con, IPP_NOT_FOUND,
-                       _("Job #%d does not exist"), attr->values[0].integer);
+                       _("Job #%d does not exist."), attr->values[0].integer);
        return;
       }
       else
@@ -9109,8 +9118,7 @@ move_job(cupsd_client_t  *con,            /* I - Client connection */
       * Not a valid URI!
       */
 
-      send_ipp_status(con, IPP_BAD_REQUEST,
-                      _("Bad job-uri attribute \"%s\""),
+      send_ipp_status(con, IPP_BAD_REQUEST, _("Bad job-uri \"%s\"."),
                       uri->values[0].string.text);
       return;
     }
@@ -9127,8 +9135,7 @@ move_job(cupsd_client_t  *con,            /* I - Client connection */
       * Nope - return a "not found" error...
       */
 
-      send_ipp_status(con, IPP_NOT_FOUND,
-                      _("Job #%d does not exist"), jobid);
+      send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist."), jobid);
       return;
     }
     else
@@ -9170,7 +9177,7 @@ move_job(cupsd_client_t  *con,            /* I - Client connection */
       */
 
       send_ipp_status(con, IPP_NOT_POSSIBLE,
-                      _("Job #%d is finished and cannot be altered"),
+                      _("Job #%d is finished and cannot be altered."),
                      job->id);
       return;
     }
@@ -9207,7 +9214,7 @@ move_job(cupsd_client_t  *con,            /* I - Client connection */
       * completed...
       */
 
-      if (strcasecmp(job->dest, src) ||
+      if (_cups_strcasecmp(job->dest, src) ||
           job->state_value > IPP_JOB_STOPPED)
        continue;
 
@@ -9355,7 +9362,7 @@ print_job(cupsd_client_t  *con,           /* I - Client connection */
       )
     {
       send_ipp_status(con, IPP_ATTRIBUTES,
-                      _("Unsupported compression \"%s\""),
+                      _("Unsupported compression \"%s\"."),
                      attr->values[0].string.text);
       ippAddString(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_KEYWORD,
                   "compression", NULL, attr->values[0].string.text);
@@ -9374,7 +9381,7 @@ print_job(cupsd_client_t  *con,           /* I - Client connection */
 
   if (!con->filename)
   {
-    send_ipp_status(con, IPP_BAD_REQUEST, _("No file!?"));
+    send_ipp_status(con, IPP_BAD_REQUEST, _("No file in print request."));
     return;
   }
 
@@ -9389,7 +9396,7 @@ print_job(cupsd_client_t  *con,           /* I - Client connection */
     */
 
     send_ipp_status(con, IPP_NOT_FOUND,
-                    _("The printer or class was not found."));
+                    _("The printer or class does not exist."));
     return;
   }
 
@@ -9408,7 +9415,7 @@ print_job(cupsd_client_t  *con,           /* I - Client connection */
                type) != 2)
     {
       send_ipp_status(con, IPP_BAD_REQUEST,
-                      _("Bad document-format \"%s\""),
+                      _("Bad document-format \"%s\"."),
                      format->values[0].string.text);
       return;
     }
@@ -9424,7 +9431,7 @@ print_job(cupsd_client_t  *con,           /* I - Client connection */
     if (sscanf(default_format, "%15[^/]/%31[^;]", super, type) != 2)
     {
       send_ipp_status(con, IPP_BAD_REQUEST,
-                      _("Bad document-format \"%s\""),
+                      _("Bad document-format \"%s\"."),
                      default_format);
       return;
     }
@@ -9489,7 +9496,7 @@ print_job(cupsd_client_t  *con,           /* I - Client connection */
   else if (!filetype)
   {
     send_ipp_status(con, IPP_DOCUMENT_FORMAT,
-                    _("Unsupported document-format \"%s\""),
+                    _("Unsupported document-format \"%s\"."),
                    format ? format->values[0].string.text :
                             "application/octet-stream");
     cupsdLogMessage(CUPSD_LOG_INFO,
@@ -9506,9 +9513,9 @@ print_job(cupsd_client_t  *con,           /* I - Client connection */
   * Read any embedded job ticket info from PS files...
   */
 
-  if (!strcasecmp(filetype->super, "application") &&
-      (!strcasecmp(filetype->type, "postscript") ||
-       !strcasecmp(filetype->type, "pdf")))
+  if (!_cups_strcasecmp(filetype->super, "application") &&
+      (!_cups_strcasecmp(filetype->type, "postscript") ||
+       !_cups_strcasecmp(filetype->type, "pdf")))
     read_job_ticket(con);
 
  /*
@@ -9782,7 +9789,7 @@ reject_jobs(cupsd_client_t  *con, /* I - Client connection */
     */
 
     send_ipp_status(con, IPP_NOT_FOUND,
-                    _("The printer or class was not found."));
+                    _("The printer or class does not exist."));
     return;
   }
 
@@ -9809,8 +9816,6 @@ reject_jobs(cupsd_client_t  *con, /* I - Client connection */
     strlcpy(printer->state_message, attr->values[0].string.text,
             sizeof(printer->state_message));
 
-  cupsdAddPrinterHistory(printer);
-
   cupsdAddEvent(CUPSD_EVENT_PRINTER_STATE, printer, NULL,
                 "No longer accepting jobs.");
 
@@ -9865,7 +9870,7 @@ release_held_new_jobs(
     */
 
     send_ipp_status(con, IPP_NOT_FOUND,
-                    _("The printer or class was not found."));
+                    _("The printer or class does not exist."));
     return;
   }
 
@@ -9886,7 +9891,6 @@ release_held_new_jobs(
   printer->holding_new_jobs = 0;
 
   cupsdSetPrinterReasons(printer, "-hold-new-jobs");
-  cupsdAddPrinterHistory(printer);
 
   if (dtype & CUPS_PRINTER_CLASS)
     cupsdLogMessage(CUPSD_LOG_INFO,
@@ -9940,7 +9944,7 @@ release_job(cupsd_client_t  *con, /* I - Client connection */
                                  IPP_TAG_INTEGER)) == NULL)
     {
       send_ipp_status(con, IPP_BAD_REQUEST,
-                      _("Got a printer-uri attribute but no job-id"));
+                      _("Got a printer-uri attribute but no job-id."));
       return;
     }
 
@@ -9962,8 +9966,7 @@ release_job(cupsd_client_t  *con, /* I - Client connection */
       * Not a valid URI!
       */
 
-      send_ipp_status(con, IPP_BAD_REQUEST,
-                      _("Bad job-uri attribute \"%s\""),
+      send_ipp_status(con, IPP_BAD_REQUEST, _("Bad job-uri \"%s\"."),
                       uri->values[0].string.text);
       return;
     }
@@ -9981,7 +9984,7 @@ release_job(cupsd_client_t  *con, /* I - Client connection */
     * Nope - return a "not found" error...
     */
 
-    send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist"), jobid);
+    send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist."), jobid);
     return;
   }
 
@@ -9995,7 +9998,7 @@ release_job(cupsd_client_t  *con, /* I - Client connection */
     * Nope - return a "not possible" error...
     */
 
-    send_ipp_status(con, IPP_NOT_POSSIBLE, _("Job #%d is not held"), jobid);
+    send_ipp_status(con, IPP_NOT_POSSIBLE, _("Job #%d is not held."), jobid);
     return;
   }
 
@@ -10074,8 +10077,8 @@ renew_subscription(
     * Bad subscription ID...
     */
 
-    send_ipp_status(con, IPP_NOT_FOUND,
-                    _("notify-subscription-id %d no good"), sub_id);
+    send_ipp_status(con, IPP_NOT_FOUND, _("Subscription #%d does not exist."),
+                    sub_id);
     return;
   }
 
@@ -10086,7 +10089,7 @@ renew_subscription(
     */
 
     send_ipp_status(con, IPP_NOT_POSSIBLE,
-                    _("Job subscriptions cannot be renewed"));
+                    _("Job subscriptions cannot be renewed."));
     return;
   }
 
@@ -10166,7 +10169,7 @@ restart_job(cupsd_client_t  *con,       /* I - Client connection */
                                  IPP_TAG_INTEGER)) == NULL)
     {
       send_ipp_status(con, IPP_BAD_REQUEST,
-                      _("Got a printer-uri attribute but no job-id"));
+                      _("Got a printer-uri attribute but no job-id."));
       return;
     }
 
@@ -10188,8 +10191,7 @@ restart_job(cupsd_client_t  *con,       /* I - Client connection */
       * Not a valid URI!
       */
 
-      send_ipp_status(con, IPP_BAD_REQUEST,
-                      _("Bad job-uri attribute \"%s\""),
+      send_ipp_status(con, IPP_BAD_REQUEST, _("Bad job-uri \"%s\"."),
                       uri->values[0].string.text);
       return;
     }
@@ -10207,7 +10209,7 @@ restart_job(cupsd_client_t  *con,       /* I - Client connection */
     * Nope - return a "not found" error...
     */
 
-    send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist"), jobid);
+    send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist."), jobid);
     return;
   }
 
@@ -10221,7 +10223,7 @@ restart_job(cupsd_client_t  *con,       /* I - Client connection */
     * Nope - return a "not possible" error...
     */
 
-    send_ipp_status(con, IPP_NOT_POSSIBLE, _("Job #%d is not complete"),
+    send_ipp_status(con, IPP_NOT_POSSIBLE, _("Job #%d is not complete."),
                     jobid);
     return;
   }
@@ -10239,7 +10241,7 @@ restart_job(cupsd_client_t  *con,       /* I - Client connection */
     */
 
     send_ipp_status(con, IPP_NOT_POSSIBLE,
-                    _("Job #%d cannot be restarted - no files"), jobid);
+                    _("Job #%d cannot be restarted - no files."), jobid);
     return;
   }
 
@@ -10306,7 +10308,7 @@ save_auth_info(
   int                  i;              /* Looping var */
   char                 filename[1024]; /* Job authentication filename */
   cups_file_t          *fp;            /* Job authentication file */
-  char                 line[2048];     /* Line for file */
+  char                 line[65536];    /* Line for file */
   cupsd_printer_t      *dest;          /* Destination printer/class */
 
 
@@ -10355,30 +10357,41 @@ save_auth_info(
   fchown(cupsFileNumber(fp), 0, 0);
   fchmod(cupsFileNumber(fp), 0400);
 
+  for (i = 0;
+       i < (int)(sizeof(job->auth_env) / sizeof(job->auth_env[0]));
+       i ++)
+    cupsdClearString(job->auth_env + i);
+
   if (auth_info && auth_info->num_values == dest->num_auth_info_required)
   {
    /*
     * Write 1 to 3 auth values...
     */
 
-    cupsdClearString(&job->auth_username);
-    cupsdClearString(&job->auth_domain);
-    cupsdClearString(&job->auth_password);
-
-    for (i = 0; i < auth_info->num_values; i ++)
+    for (i = 0;
+         i < auth_info->num_values &&
+            i < (int)(sizeof(job->auth_env) / sizeof(job->auth_env[0]));
+        i ++)
     {
       httpEncode64_2(line, sizeof(line), auth_info->values[i].string.text,
                      strlen(auth_info->values[i].string.text));
       cupsFilePrintf(fp, "%s\n", line);
 
       if (!strcmp(dest->auth_info_required[i], "username"))
-        cupsdSetStringf(&job->auth_username, "AUTH_USERNAME=%s",
+        cupsdSetStringf(job->auth_env + i, "AUTH_USERNAME=%s",
                        auth_info->values[i].string.text);
       else if (!strcmp(dest->auth_info_required[i], "domain"))
-        cupsdSetStringf(&job->auth_domain, "AUTH_DOMAIN=%s",
+        cupsdSetStringf(job->auth_env + i, "AUTH_DOMAIN=%s",
                        auth_info->values[i].string.text);
       else if (!strcmp(dest->auth_info_required[i], "password"))
-        cupsdSetStringf(&job->auth_password, "AUTH_PASSWORD=%s",
+        cupsdSetStringf(job->auth_env + i, "AUTH_PASSWORD=%s",
+                       auth_info->values[i].string.text);
+      else if (!strcmp(dest->auth_info_required[i], "negotiate"))
+        cupsdSetStringf(job->auth_env + i, "AUTH_NEGOTIATE=%s",
+                       auth_info->values[i].string.text);
+      else
+        cupsdSetStringf(job->auth_env + i, "AUTH_%s=%s",
+                       dest->auth_info_required[i],
                        auth_info->values[i].string.text);
     }
   }
@@ -10391,8 +10404,7 @@ save_auth_info(
     httpEncode64_2(line, sizeof(line), con->username, strlen(con->username));
     cupsFilePrintf(fp, "%s\n", line);
 
-    cupsdSetStringf(&job->auth_username, "AUTH_USERNAME=%s", con->username);
-    cupsdClearString(&job->auth_domain);
+    cupsdSetStringf(job->auth_env + 0, "AUTH_USERNAME=%s", con->username);
 
    /*
     * Write the authenticated password...
@@ -10401,9 +10413,17 @@ save_auth_info(
     httpEncode64_2(line, sizeof(line), con->password, strlen(con->password));
     cupsFilePrintf(fp, "%s\n", line);
 
-    cupsdSetStringf(&job->auth_password, "AUTH_PASSWORD=%s", con->password);
+    cupsdSetStringf(job->auth_env + 1, "AUTH_PASSWORD=%s", con->password);
   }
 
+#ifdef HAVE_GSSAPI
+  if (con->gss_uid > 0)
+  {
+    cupsFilePrintf(fp, "%d\n", (int)con->gss_uid);
+    cupsdSetStringf(&job->auth_uid, "AUTH_UID=%d", (int)con->gss_uid);
+  }
+#endif /* HAVE_GSSAPI */
+
  /*
   * Write a random number of newlines to the end of the file...
   */
@@ -10416,52 +10436,7 @@ save_auth_info(
   */
 
   cupsFileClose(fp);
-
-#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5_H)
-#  ifdef HAVE_KRB5_IPC_CLIENT_SET_TARGET_UID
-  if (con->have_gss &&
-      (con->http.hostaddr->addr.sa_family == AF_LOCAL || con->gss_creds))
-#  else
-  if (con->have_gss && con->gss_creds)
-#  endif /* HAVE_KRB5_IPC_CLIENT_SET_TARGET_UID */
-    save_krb5_creds(con, job);
-  else if (job->ccname)
-    cupsdClearString(&(job->ccname));
-#endif /* HAVE_GSSAPI && HAVE_KRB5_H */
-}
-
-
-#if defined(HAVE_GSSAPI) && defined(HAVE_KRB5_H)
-/*
- * 'save_krb5_creds()' - Save Kerberos credentials for the job.
- */
-
-static void
-save_krb5_creds(cupsd_client_t *con,   /* I - Client connection */
-                cupsd_job_t    *job)   /* I - Job */
-{
- /*
-  * Get the credentials...
-  */
-
-  job->ccache = cupsdCopyKrb5Creds(con);
-
- /*
-  * Add the KRB5CCNAME environment variable to the job so that the
-  * backend can use the credentials when printing.
-  */
-
-  if (job->ccache)
-  {
-    cupsdSetStringf(&(job->ccname), "KRB5CCNAME=FILE:%s",
-                   krb5_cc_get_name(KerberosContext, job->ccache));
-
-    cupsdLogJob(job, CUPSD_LOG_DEBUG2, "save_krb5_creds: %s", job->ccname);
-  }
-  else
-    cupsdClearString(&(job->ccname));
 }
-#endif /* HAVE_GSSAPI && HAVE_KRB5_H */
 
 
 /*
@@ -10521,7 +10496,7 @@ send_document(cupsd_client_t  *con,     /* I - Client connection */
                                  IPP_TAG_INTEGER)) == NULL)
     {
       send_ipp_status(con, IPP_BAD_REQUEST,
-                      _("Got a printer-uri attribute but no job-id"));
+                      _("Got a printer-uri attribute but no job-id."));
       return;
     }
 
@@ -10543,8 +10518,7 @@ send_document(cupsd_client_t  *con,     /* I - Client connection */
       * Not a valid URI!
       */
 
-      send_ipp_status(con, IPP_BAD_REQUEST,
-                      _("Bad job-uri attribute \"%s\""),
+      send_ipp_status(con, IPP_BAD_REQUEST, _("Bad job-uri \"%s\"."),
                       uri->values[0].string.text);
       return;
     }
@@ -10562,7 +10536,7 @@ send_document(cupsd_client_t  *con,     /* I - Client connection */
     * Nope - return a "not found" error...
     */
 
-    send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist"), jobid);
+    send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist."), jobid);
     return;
   }
 
@@ -10595,7 +10569,7 @@ send_document(cupsd_client_t  *con,     /* I - Client connection */
 #endif /* HAVE_LIBZ */
       )
     {
-      send_ipp_status(con, IPP_ATTRIBUTES, _("Unsupported compression \"%s\""),
+      send_ipp_status(con, IPP_ATTRIBUTES, _("Unsupported compression \"%s\"."),
                      attr->values[0].string.text);
       ippAddString(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_KEYWORD,
                   "compression", NULL, attr->values[0].string.text);
@@ -10625,7 +10599,7 @@ send_document(cupsd_client_t  *con,     /* I - Client connection */
         attr->values[0].boolean)
       goto last_document;
 
-    send_ipp_status(con, IPP_BAD_REQUEST, _("No file!?"));
+    send_ipp_status(con, IPP_BAD_REQUEST, _("No file in print request."));
     return;
   }
 
@@ -10643,7 +10617,7 @@ send_document(cupsd_client_t  *con,     /* I - Client connection */
     if (sscanf(format->values[0].string.text, "%15[^/]/%31[^;]",
                super, type) != 2)
     {
-      send_ipp_status(con, IPP_BAD_REQUEST, _("Bad document-format \"%s\""),
+      send_ipp_status(con, IPP_BAD_REQUEST, _("Bad document-format \"%s\"."),
                      format->values[0].string.text);
       return;
     }
@@ -10659,8 +10633,7 @@ send_document(cupsd_client_t  *con,     /* I - Client connection */
     if (sscanf(default_format, "%15[^/]/%31[^;]", super, type) != 2)
     {
       send_ipp_status(con, IPP_BAD_REQUEST,
-                      _("Could not scan type \"%s\""),
-                     default_format);
+                      _("Bad document-format-default \"%s\"."), default_format);
       return;
     }
   }
@@ -10724,7 +10697,7 @@ send_document(cupsd_client_t  *con,     /* I - Client connection */
   else if (!filetype)
   {
     send_ipp_status(con, IPP_DOCUMENT_FORMAT,
-                    _("Unsupported format \'%s/%s\'"), super, type);
+                    _("Unsupported document-format \"%s/%s\"."), super, type);
     cupsdLogMessage(CUPSD_LOG_INFO,
                     "Hint: Do you have the raw file printing rules enabled?");
 
@@ -10741,7 +10714,7 @@ send_document(cupsd_client_t  *con,     /* I - Client connection */
              filetype->type);
 
     send_ipp_status(con, IPP_DOCUMENT_FORMAT,
-                    _("Unsupported format \'%s\'"), mimetype);
+                    _("Unsupported document-format \"%s\"."), mimetype);
 
     ippAddString(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_MIMETYPE,
                  "document-format", NULL, mimetype);
@@ -10884,7 +10857,9 @@ send_http_error(
   cupsdLogMessage(status == HTTP_FORBIDDEN ? CUPSD_LOG_ERROR : CUPSD_LOG_DEBUG,
                   "Returning HTTP %s for %s (%s) from %s",
                   httpStatus(status),
-                 ippOpString(con->request->request.op.operation_id),
+                 con->request ?
+                     ippOpString(con->request->request.op.operation_id) :
+                     "no operation-id",
                  uri ? uri->values[0].string.text : "no URI",
                  con->http.hostname);
 
@@ -11020,7 +10995,7 @@ set_default(cupsd_client_t  *con,       /* I - Client connection */
     */
 
     send_ipp_status(con, IPP_NOT_FOUND,
-                    _("The printer or class was not found."));
+                    _("The printer or class does not exist."));
     return;
   }
 
@@ -11111,7 +11086,7 @@ set_job_attrs(cupsd_client_t  *con,     /* I - Client connection */
                                  IPP_TAG_INTEGER)) == NULL)
     {
       send_ipp_status(con, IPP_BAD_REQUEST,
-                      _("Got a printer-uri attribute but no job-id"));
+                      _("Got a printer-uri attribute but no job-id."));
       return;
     }
 
@@ -11133,8 +11108,7 @@ set_job_attrs(cupsd_client_t  *con,     /* I - Client connection */
       * Not a valid URI!
       */
 
-      send_ipp_status(con, IPP_BAD_REQUEST,
-                      _("Bad job-uri attribute \"%s\""),
+      send_ipp_status(con, IPP_BAD_REQUEST, _("Bad job-uri \"%s\"."),
                       uri->values[0].string.text);
       return;
     }
@@ -11152,7 +11126,7 @@ set_job_attrs(cupsd_client_t  *con,     /* I - Client connection */
     * Nope - return a "not found" error...
     */
 
-    send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist"), jobid);
+    send_ipp_status(con, IPP_NOT_FOUND, _("Job #%d does not exist."), jobid);
     return;
   }
 
@@ -11167,7 +11141,7 @@ set_job_attrs(cupsd_client_t  *con,     /* I - Client connection */
     */
 
     send_ipp_status(con, IPP_NOT_POSSIBLE,
-                    _("Job #%d is finished and cannot be altered"), jobid);
+                    _("Job #%d is finished and cannot be altered."), jobid);
     return;
   }
 
@@ -11242,7 +11216,7 @@ set_job_attrs(cupsd_client_t  *con,     /* I - Client connection */
 
       if (attr->value_tag != IPP_TAG_INTEGER)
       {
-       send_ipp_status(con, IPP_REQUEST_VALUE, _("Bad job-priority value"));
+       send_ipp_status(con, IPP_REQUEST_VALUE, _("Bad job-priority value."));
 
        if ((attr2 = copy_attribute(con->response, attr, 0)) != NULL)
           attr2->group_tag = IPP_TAG_UNSUPPORTED_GROUP;
@@ -11272,7 +11246,7 @@ set_job_attrs(cupsd_client_t  *con,     /* I - Client connection */
 
       if (attr->value_tag != IPP_TAG_ENUM)
       {
-       send_ipp_status(con, IPP_REQUEST_VALUE, _("Bad job-state value"));
+       send_ipp_status(con, IPP_REQUEST_VALUE, _("Bad job-state value."));
 
        if ((attr2 = copy_attribute(con->response, attr, 0)) != NULL)
           attr2->group_tag = IPP_TAG_UNSUPPORTED_GROUP;
@@ -11476,7 +11450,7 @@ set_printer_attrs(cupsd_client_t  *con, /* I - Client connection */
     */
 
     send_ipp_status(con, IPP_NOT_FOUND,
-                    _("The printer or class was not found."));
+                    _("The printer or class does not exist."));
     return;
   }
 
@@ -11806,7 +11780,7 @@ start_printer(cupsd_client_t  *con,     /* I - Client connection */
     */
 
     send_ipp_status(con, IPP_NOT_FOUND,
-                    _("The printer or class was not found."));
+                    _("The printer or class does not exist."));
     return;
   }
 
@@ -11888,7 +11862,7 @@ stop_printer(cupsd_client_t  *con,      /* I - Client connection */
     */
 
     send_ipp_status(con, IPP_NOT_FOUND,
-                    _("The printer or class was not found."));
+                    _("The printer or class does not exist."));
     return;
   }
 
@@ -12086,7 +12060,7 @@ user_allowed(cupsd_printer_t *p,        /* I - Printer or class */
       if (cupsdCheckGroup(username, pw, name))
         break;
     }
-    else if (!strcasecmp(username, name))
+    else if (!_cups_strcasecmp(username, name))
       break;
   }
 
@@ -12132,7 +12106,7 @@ validate_job(cupsd_client_t  *con,      /* I - Client connection */
       )
     {
       send_ipp_status(con, IPP_ATTRIBUTES,
-                      _("Unsupported compression \"%s\""),
+                      _("Unsupported compression \"%s\"."),
                      attr->values[0].string.text);
       ippAddString(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_KEYWORD,
                   "compression", NULL, attr->values[0].string.text);
@@ -12150,7 +12124,7 @@ validate_job(cupsd_client_t  *con,      /* I - Client connection */
     if (sscanf(format->values[0].string.text, "%15[^/]/%31[^;]",
                super, type) != 2)
     {
-      send_ipp_status(con, IPP_BAD_REQUEST, _("Bad document-format \"%s\""),
+      send_ipp_status(con, IPP_BAD_REQUEST, _("Bad document-format \"%s\"."),
                      format->values[0].string.text);
       return;
     }
@@ -12161,7 +12135,7 @@ validate_job(cupsd_client_t  *con,      /* I - Client connection */
       cupsdLogMessage(CUPSD_LOG_INFO,
                       "Hint: Do you have the raw file printing rules enabled?");
       send_ipp_status(con, IPP_DOCUMENT_FORMAT,
-                      _("Unsupported document-format \"%s\""),
+                      _("Unsupported document-format \"%s\"."),
                      format->values[0].string.text);
       ippAddString(con->response, IPP_TAG_UNSUPPORTED_GROUP, IPP_TAG_MIMETYPE,
                    "document-format", NULL, format->values[0].string.text);
@@ -12180,7 +12154,7 @@ validate_job(cupsd_client_t  *con,      /* I - Client connection */
     */
 
     send_ipp_status(con, IPP_NOT_FOUND,
-                    _("The printer or class was not found."));
+                    _("The printer or class does not exist."));
     return;
   }