]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - backend/ipp.c
Import CUPS v1.7.1
[thirdparty/cups.git] / backend / ipp.c
index ff06a4badc2c32b2bd09ef81bfaa934a83b8f0bb..22a350c9cf425819ea9245e0abe3297c034dc662 100644 (file)
@@ -1,36 +1,18 @@
 /*
- * "$Id: ipp.c 9759 2011-05-11 03:24:33Z mike $"
+ * "$Id: ipp.c 11495 2013-12-22 05:29:16Z msweet $"
  *
- *   IPP backend for CUPS.
+ * IPP backend for CUPS.
  *
- *   Copyright 2007-2013 by Apple Inc.
- *   Copyright 1997-2007 by Easy Software Products, all rights reserved.
+ * Copyright 2007-2013 by Apple Inc.
+ * Copyright 1997-2007 by Easy Software Products, all rights reserved.
  *
- *   These coded instructions, statements, and computer programs are the
- *   property of Apple Inc. and are protected by Federal copyright
- *   law.  Distribution and use rights are outlined in the file "LICENSE.txt"
- *   "LICENSE" which should have been included with this file.  If this
- *   file is missing or damaged, see the license at "http://www.cups.org/".
+ * These coded instructions, statements, and computer programs are the
+ * property of Apple Inc. and are protected by Federal copyright
+ * law.  Distribution and use rights are outlined in the file "LICENSE.txt"
+ * "LICENSE" which should have been included with this file.  If this
+ * file is missing or damaged, see the license at "http://www.cups.org/".
  *
- *   This file is subject to the Apple OS-Developed Software exception.
- *
- * Contents:
- *
- *   main()                - Send a file to the printer or server.
- *   cancel_job()          - Cancel a print job.
- *   check_printer_state()  - Check the printer state.
- *   monitor_printer()     - Monitor the printer state.
- *   new_request()         - Create a new print creation or validation
- *                           request.
- *   password_cb()         - Disable the password prompt for
- *                           cupsDoFileRequest().
- *   quote_string()        - Quote a string value.
- *   report_attr()         - Report an IPP attribute value.
- *   report_printer_state() - Report the printer state.
- *   run_as_user()         - Run the IPP backend as the printing user.
- *   sigterm_handler()     - Handle 'terminate' signals that stop the backend.
- *   timeout_cb()          - Handle HTTP timeouts.
- *   update_reasons()      - Update the printer-state-reasons values.
+ * This file is subject to the Apple OS-Developed Software exception.
  */
 
 /*
@@ -115,8 +97,6 @@ static char          username[256] = "",
                                        /* Username for device URI */
                        *password = NULL;
                                        /* Password for device URI */
-static int             password_tries = 0;
-                                       /* Password tries */
 static const char * const pattrs[] =   /* Printer attributes we want */
 {
 #ifdef HAVE_LIBZ
@@ -135,6 +115,7 @@ static const char * const pattrs[] =        /* Printer attributes we want */
   "media-col-supported",
   "multiple-document-handling-supported",
   "operations-supported",
+  "print-color-mode-supported",
   "printer-alert",
   "printer-alert-description",
   "printer-is-accepting-jobs",
@@ -182,10 +163,10 @@ static ipp_t              *new_request(ipp_op_t op, int version, const char *uri,
                                     ppd_file_t *ppd,
                                     ipp_attribute_t *media_col_sup,
                                     ipp_attribute_t *doc_handling_sup,
-                                    int print_color_mode);
+                                    ipp_attribute_t *print_color_mode_sup);
 static const char      *password_cb(const char *prompt, http_t *http,
                                     const char *method, const char *resource,
-                                    void *user_data);
+                                    int *user_data);
 static const char      *quote_string(const char *s, char *q, size_t qsize);
 static void            report_attr(ipp_attribute_t *attr);
 static void            report_printer_state(ipp_t *ipp);
@@ -223,6 +204,7 @@ main(int  argc,                             /* I - Number of command-line args */
                *name,                  /* Name of option */
                *value,                 /* Value of option */
                sep;                    /* Separator character */
+  int          password_tries = 0;     /* Password tries */
   http_addrlist_t *addrlist;           /* Address of printer */
   int          snmp_enabled = 1;       /* Is SNMP enabled? */
   int          snmp_fd,                /* SNMP socket */
@@ -262,17 +244,18 @@ main(int  argc,                           /* I - Number of command-line args */
   ipp_attribute_t *copies_sup;         /* copies-supported */
   ipp_attribute_t *cups_version;       /* cups-version */
   ipp_attribute_t *format_sup;         /* document-format-supported */
+  ipp_attribute_t *job_auth;           /* job-authorization-uri */
   ipp_attribute_t *media_col_sup;      /* media-col-supported */
   ipp_attribute_t *operations_sup;     /* operations-supported */
   ipp_attribute_t *doc_handling_sup;   /* multiple-document-handling-supported */
   ipp_attribute_t *printer_state;      /* printer-state attribute */
   ipp_attribute_t *printer_accepting;  /* printer-is-accepting-jobs */
+  ipp_attribute_t *print_color_mode_sup;/* Does printer support print-color-mode? */
   int          create_job = 0,         /* Does printer support Create-Job? */
                get_job_attrs = 0,      /* Does printer support Get-Job-Attributes? */
                send_document = 0,      /* Does printer support Send-Document? */
                validate_job = 0,       /* Does printer support Validate-Job? */
-               print_color_mode = 0;   /* Does printer support print-color-mode? */
-  int          copies,                 /* Number of copies for job */
+               copies,                 /* Number of copies for job */
                copies_remaining;       /* Number of copies remaining */
   const char   *content_type,          /* CONTENT_TYPE environment variable */
                *final_content_type,    /* FINAL_CONTENT_TYPE environment var */
@@ -366,7 +349,8 @@ main(int  argc,                             /* I - Number of command-line args */
   * that way.
   */
 
-  if (!getuid() && (value = getenv("AUTH_UID")) != NULL)
+  if (!getuid() && (value = getenv("AUTH_UID")) != NULL &&
+      !getenv("AUTH_PASSWORD"))
   {
     uid_t      uid = (uid_t)atoi(value);
                                        /* User ID */
@@ -431,7 +415,7 @@ main(int  argc,                             /* I - Number of command-line args */
   if (!port)
     port = IPP_PORT;                   /* Default to port 631 */
 
-  if (!strcmp(scheme, "https"))
+  if (!strcmp(scheme, "https") || !strcmp(scheme, "ipps"))
     cupsSetEncryption(HTTP_ENCRYPT_ALWAYS);
   else
     cupsSetEncryption(HTTP_ENCRYPT_IF_REQUESTED);
@@ -634,7 +618,7 @@ main(int  argc,                             /* I - Number of command-line args */
   * Set the authentication info, if any...
   */
 
-  cupsSetPasswordCB2(password_cb, NULL);
+  cupsSetPasswordCB2((cups_password_cb2_t)password_cb, &password_tries);
 
   if (username[0])
   {
@@ -1040,7 +1024,8 @@ main(int  argc,                           /* I - Number of command-line args */
        delay = _cupsNextDelay(delay, &prev_delay);
 
        ippDelete(supported);
-       supported = NULL;
+       supported  = NULL;
+       ipp_status = IPP_STATUS_ERROR_BUSY;
        continue;
       }
     }
@@ -1116,9 +1101,7 @@ main(int  argc,                           /* I - Number of command-line args */
                media_col_sup->values[i].string.text);
     }
 
-    print_color_mode = ippFindAttribute(supported,
-                                       "print-color-mode-supported",
-                                       IPP_TAG_KEYWORD) != NULL;
+    print_color_mode_sup = ippFindAttribute(supported, "print-color-mode-supported", IPP_TAG_KEYWORD);
 
     if ((operations_sup = ippFindAttribute(supported, "operations-supported",
                                           IPP_TAG_ENUM)) != NULL)
@@ -1400,15 +1383,23 @@ main(int  argc,                         /* I - Number of command-line args */
     request = new_request(IPP_VALIDATE_JOB, version, uri, argv[2],
                           monitor.job_name, num_options, options, compression,
                          copies_sup ? copies : 1, document_format, pc, ppd,
-                         media_col_sup, doc_handling_sup, print_color_mode);
+                         media_col_sup, doc_handling_sup, print_color_mode_sup);
 
-    ippDelete(cupsDoRequest(http, request, resource));
+    response = cupsDoRequest(http, request, resource);
 
     ipp_status = cupsLastError();
 
     fprintf(stderr, "DEBUG: Validate-Job: %s (%s)\n",
             ippErrorString(ipp_status), cupsLastErrorString());
 
+    if ((job_auth = ippFindAttribute(response, "job-authorization-uri",
+                                    IPP_TAG_URI)) != NULL)
+      num_options = cupsAddOption("job-authorization-uri",
+                                  ippGetString(job_auth, 0, NULL), num_options,
+                                  &options);
+
+    ippDelete(response);
+
     if (job_canceled)
       break;
 
@@ -1478,7 +1469,7 @@ main(int  argc,                           /* I - Number of command-line args */
                          version, uri, argv[2], monitor.job_name, num_options,
                          options, compression, copies_sup ? copies : 1,
                          document_format, pc, ppd, media_col_sup,
-                         doc_handling_sup, print_color_mode);
+                         doc_handling_sup, print_color_mode_sup);
 
    /*
     * Do the request...
@@ -1594,6 +1585,7 @@ main(int  argc,                           /* I - Number of command-line args */
       }
       else if (ipp_status == IPP_STATUS_ERROR_JOB_CANCELED ||
                ipp_status == IPP_STATUS_ERROR_NOT_AUTHORIZED ||
+               ipp_status == IPP_STATUS_ERROR_ATTRIBUTES_OR_VALUES ||
               ipp_status == IPP_STATUS_ERROR_CUPS_ACCOUNT_INFO_NEEDED ||
               ipp_status == IPP_STATUS_ERROR_CUPS_ACCOUNT_CLOSED ||
               ipp_status == IPP_STATUS_ERROR_CUPS_ACCOUNT_LIMIT_REACHED ||
@@ -1689,8 +1681,8 @@ main(int  argc,                           /* I - Number of command-line args */
          ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_NAME,
                        "requesting-user-name", NULL, argv[2]);
 
-        if ((i + 1) >= num_files)
-         ippAddBoolean(request, IPP_TAG_OPERATION, "last-document", 1);
+       ippAddBoolean(request, IPP_TAG_OPERATION, "last-document",
+                     (i + 1) >= num_files);
 
        if (document_format)
          ippAddString(request, IPP_TAG_OPERATION, IPP_TAG_MIMETYPE,
@@ -1878,6 +1870,9 @@ main(int  argc,                           /* I - Number of command-line args */
 
       check_printer_state(http, uri, resource, argv[2], version);
 
+      if (cupsLastError() <= IPP_OK_CONFLICT)
+        password_tries = 0;
+
      /*
       * Build an IPP_GET_JOB_ATTRIBUTES request...
       */
@@ -2028,12 +2023,16 @@ main(int  argc,                         /* I - Number of command-line args */
 
   check_printer_state(http, uri, resource, argv[2], version);
 
+  if (cupsLastError() <= IPP_OK_CONFLICT)
+    password_tries = 0;
+
  /*
   * Collect the final page count as needed...
   */
 
   if (have_supplies &&
-      !backendSNMPSupplies(snmp_fd, http->hostaddr, &page_count, NULL) &&
+      !backendSNMPSupplies(snmp_fd, &(http->addrlist->addr), &page_count,
+                           NULL) &&
       page_count > start_count)
     fprintf(stderr, "PAGE: total %d\n", page_count - start_count);
 
@@ -2086,17 +2085,19 @@ main(int  argc,                         /* I - Number of command-line args */
     fputs("JOBSTATE: account-authorization-failed\n", stderr);
 
   if (ipp_status == IPP_NOT_AUTHORIZED || ipp_status == IPP_FORBIDDEN ||
-      ipp_status == IPP_AUTHENTICATION_CANCELED ||
-      ipp_status == IPP_STATUS_ERROR_CUPS_ACCOUNT_INFO_NEEDED ||
-      ipp_status == IPP_STATUS_ERROR_CUPS_ACCOUNT_CLOSED ||
-      ipp_status == IPP_STATUS_ERROR_CUPS_ACCOUNT_LIMIT_REACHED ||
-      ipp_status == IPP_STATUS_ERROR_CUPS_ACCOUNT_AUTHORIZATION_FAILED)
+      ipp_status == IPP_AUTHENTICATION_CANCELED)
     return (CUPS_BACKEND_AUTH_REQUIRED);
+  else if (ipp_status == IPP_STATUS_ERROR_CUPS_ACCOUNT_LIMIT_REACHED ||
+          ipp_status == IPP_STATUS_ERROR_CUPS_ACCOUNT_INFO_NEEDED ||
+          ipp_status == IPP_STATUS_ERROR_CUPS_ACCOUNT_CLOSED ||
+          ipp_status == IPP_STATUS_ERROR_CUPS_ACCOUNT_AUTHORIZATION_FAILED)
+    return (CUPS_BACKEND_HOLD);
   else if (ipp_status == IPP_INTERNAL_ERROR)
     return (CUPS_BACKEND_STOP);
   else if (ipp_status == IPP_CONFLICT)
     return (CUPS_BACKEND_FAILED);
   else if (ipp_status == IPP_REQUEST_VALUE ||
+          ipp_status == IPP_STATUS_ERROR_ATTRIBUTES_OR_VALUES ||
            ipp_status == IPP_DOCUMENT_FORMAT || job_canceled < 0)
   {
     if (ipp_status == IPP_REQUEST_VALUE)
@@ -2104,6 +2105,9 @@ main(int  argc,                           /* I - Number of command-line args */
     else if (ipp_status == IPP_DOCUMENT_FORMAT)
       _cupsLangPrintFilter(stderr, "ERROR",
                            _("Printer cannot print supplied content."));
+    else if (ipp_status == IPP_STATUS_ERROR_ATTRIBUTES_OR_VALUES)
+      _cupsLangPrintFilter(stderr, "ERROR",
+                           _("Printer cannot print with supplied options."));
     else
       _cupsLangPrintFilter(stderr, "ERROR", _("Print job canceled at printer."));
 
@@ -2208,9 +2212,6 @@ check_printer_state(
   fprintf(stderr, "DEBUG: Get-Printer-Attributes: %s (%s)\n",
          ippErrorString(cupsLastError()), cupsLastErrorString());
 
-  if (cupsLastError() <= IPP_OK_CONFLICT)
-    password_tries = 0;
-
  /*
   * Return the printer-state value...
   */
@@ -2238,6 +2239,7 @@ monitor_printer(
   const char   *job_name;              /* Job name */
   ipp_jstate_t job_state;              /* Job state */
   const char   *job_user;              /* Job originating user name */
+  int          password_tries = 0;     /* Password tries */
 
 
  /*
@@ -2249,7 +2251,8 @@ monitor_printer(
   httpSetTimeout(http, 30.0, timeout_cb, NULL);
   if (username[0])
     cupsSetUser(username);
-  cupsSetPasswordCB2(password_cb, NULL);
+
+  cupsSetPasswordCB2((cups_password_cb2_t)password_cb, &password_tries);
 
  /*
   * Loop until the job is canceled, aborted, or completed.
@@ -2275,6 +2278,8 @@ monitor_printer(
                                                    monitor->resource,
                                                   monitor->user,
                                                   monitor->version);
+      if (cupsLastError() <= IPP_OK_CONFLICT)
+        password_tries = 0;
 
      /*
       * Check the status of the job itself...
@@ -2477,7 +2482,8 @@ new_request(
     ppd_file_t      *ppd,              /* I - PPD file data */
     ipp_attribute_t *media_col_sup,    /* I - media-col-supported values */
     ipp_attribute_t *doc_handling_sup,  /* I - multiple-document-handling-supported values */
-    int             print_color_mode)  /* I - Printer supports print-color-mode */
+    ipp_attribute_t *print_color_mode_sup)
+                                       /* I - Printer supports print-color-mode */
 {
   int          i;                      /* Looping var */
   ipp_t                *request;               /* Request data */
@@ -2579,17 +2585,27 @@ new_request(
                      "job-password-encryption", NULL, keyword);
       }
 
-      if (pc->account_id &&
-          (keyword = cupsGetOption("job-account-id", num_options,
-                                   options)) != NULL)
-        ippAddString(request, IPP_TAG_JOB, IPP_TAG_NAME, "job-account-id",
-                     NULL, keyword);
+      if (pc->account_id)
+      {
+        if ((keyword = cupsGetOption("job-account-id", num_options,
+                                    options)) == NULL)
+         keyword = cupsGetOption("job-billing", num_options, options);
 
-      if (pc->account_id &&
-          (keyword = cupsGetOption("job-accounting-user-id", num_options,
-                                   options)) != NULL)
-        ippAddString(request, IPP_TAG_JOB, IPP_TAG_NAME,
-                     "job-accounting-user-id", NULL, keyword);
+        if (keyword)
+         ippAddString(request, IPP_TAG_JOB, IPP_TAG_NAME, "job-account-id",
+                      NULL, keyword);
+      }
+
+      if (pc->accounting_user_id)
+      {
+        if ((keyword = cupsGetOption("job-accounting-user-id", num_options,
+                                    options)) == NULL)
+         keyword = user;
+
+        if (keyword)
+         ippAddString(request, IPP_TAG_JOB, IPP_TAG_NAME,
+                      "job-accounting-user-id", NULL, keyword);
+      }
 
       for (mandatory = (char *)cupsArrayFirst(pc->mandatory);
            mandatory;
@@ -2642,6 +2658,14 @@ new_request(
                                   strlen(keyword));
                 break;
             default :
+                if (!strcmp(mandatory, "print-color-mode") && !strcmp(keyword, "monochrome"))
+                {
+                  if (ippContainsString(print_color_mode_sup, "auto-monochrome"))
+                    keyword = "auto-monochrome";
+                  else if (ippContainsString(print_color_mode_sup, "process-monochrome") && !ippContainsString(print_color_mode_sup, "monochrome"))
+                    keyword = "process-monochrome";
+                }
+
                 ippAddString(request, IPP_TAG_JOB, value_tag, mandatory,
                              NULL, keyword);
                 break;
@@ -2716,22 +2740,32 @@ new_request(
        ippAddString(request, IPP_TAG_JOB, IPP_TAG_KEYWORD, "output-bin",
                     NULL, keyword);
 
-      color_attr_name = print_color_mode ? "print-color-mode" : "output-mode";
+      color_attr_name = print_color_mode_sup ? "print-color-mode" : "output-mode";
 
       if ((keyword = cupsGetOption("print-color-mode", num_options,
-                                  options)) != NULL)
-       ippAddString(request, IPP_TAG_JOB, IPP_TAG_KEYWORD, color_attr_name,
-                    NULL, keyword);
-      else if ((choice = ppdFindMarkedChoice(ppd, "ColorModel")) != NULL)
+                                  options)) == NULL)
       {
-       if (!_cups_strcasecmp(choice->choice, "Gray"))
-         ippAddString(request, IPP_TAG_JOB, IPP_TAG_KEYWORD,
-                      color_attr_name, NULL, "monochrome");
-       else
-         ippAddString(request, IPP_TAG_JOB, IPP_TAG_KEYWORD,
-                      color_attr_name, NULL, "color");
+       if ((choice = ppdFindMarkedChoice(ppd, "ColorModel")) != NULL)
+       {
+         if (!_cups_strcasecmp(choice->choice, "Gray"))
+           keyword = "monochrome";
+         else
+           keyword = "color";
+       }
+      }
+
+      if (keyword && !strcmp(keyword, "monochrome"))
+      {
+       if (ippContainsString(print_color_mode_sup, "auto-monochrome"))
+         keyword = "auto-monochrome";
+       else if (ippContainsString(print_color_mode_sup, "process-monochrome") && !ippContainsString(print_color_mode_sup, "monochrome"))
+         keyword = "process-monochrome";
       }
 
+      if (keyword)
+       ippAddString(request, IPP_TAG_JOB, IPP_TAG_KEYWORD, color_attr_name,
+                    NULL, keyword);
+
       if ((keyword = cupsGetOption("print-quality", num_options,
                                   options)) != NULL)
        ippAddInteger(request, IPP_TAG_JOB, IPP_TAG_ENUM, "print-quality",
@@ -2917,18 +2951,19 @@ password_cb(const char *prompt,         /* I - Prompt (not used) */
             http_t     *http,          /* I - Connection */
             const char *method,                /* I - Request method (not used) */
             const char *resource,      /* I - Resource path (not used) */
-            void       *user_data)     /* I - User data (not used) */
+            int        *password_tries)        /* I - Password tries */
 {
   char def_username[HTTP_MAX_VALUE];   /* Default username */
 
 
-  fprintf(stderr, "DEBUG: password_cb(prompt=\"%s\"), password=%p, "
-          "password_tries=%d\n", prompt, password, password_tries);
+  fprintf(stderr, "DEBUG: password_cb(prompt=\"%s\", http=%p, method=\"%s\", "
+                  "resource=\"%s\", password_tries=%p(%d)), password=%p\n",
+          prompt, http, method, resource, password_tries, *password_tries,
+          password);
 
   (void)prompt;
   (void)method;
   (void)resource;
-  (void)user_data;
 
  /*
   * Remember that we need to authenticate...
@@ -2946,9 +2981,9 @@ password_cb(const char *prompt,           /* I - Prompt (not used) */
             quote_string(def_username, quoted, sizeof(quoted)));
   }
 
-  if (password && *password && password_tries < 3)
+  if (password && *password && *password_tries < 3)
   {
-    password_tries ++;
+    (*password_tries) ++;
 
     return (password);
   }
@@ -2992,7 +3027,7 @@ quote_string(const char *s,               /* I - String */
   {
     if (*s == '\\' || *s == '\"' || *s == '\'')
     {
-      if (q < (qend - 3))
+      if (qptr < (qend - 4))
       {
        *qptr++ = '\\';
        *qptr++ = '\\';
@@ -3380,7 +3415,6 @@ run_as_user(char       *argv[],           /* I - Command-line arguments */
 
   if (conn)
   {
-    xpc_connection_suspend(conn);
     xpc_connection_cancel(conn);
     xpc_release(conn);
   }
@@ -3646,5 +3680,5 @@ update_reasons(ipp_attribute_t *attr,     /* I - printer-state-reasons or NULL */
 }
 
 /*
- * End of "$Id: ipp.c 9759 2011-05-11 03:24:33Z mike $".
+ * End of "$Id: ipp.c 11495 2013-12-22 05:29:16Z msweet $".
  */