]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - scheduler/ipp.c
Merge CUPS 1.4svn-r7319.
[thirdparty/cups.git] / scheduler / ipp.c
index 9f50ef812475e8aa2f31830c9a14351a19bfdf8a..6b964d8455b2a203701882bae5892e7f767ab9fc 100644 (file)
@@ -3,7 +3,7 @@
  *
  *   IPP routines for the Common UNIX Printing System (CUPS) scheduler.
  *
- *   Copyright 2007 by Apple Inc.
+ *   Copyright 2007-2008 by Apple Inc.
  *   Copyright 1997-2007 by Easy Software Products, all rights reserved.
  *
  *   This file contains Kerberos support code, copyright 2006 by
@@ -664,7 +664,7 @@ cupsdProcessIPPRequest(
                     con->http.fd, con->response->request.status.status_code,
                    ippErrorString(con->response->request.status.status_code));
 
-    if (cupsdSendHeader(con, HTTP_OK, "application/ipp", AUTH_NONE))
+    if (cupsdSendHeader(con, HTTP_OK, "application/ipp", CUPSD_AUTH_NONE))
     {
 #ifdef CUPSD_USE_CHUNKING
      /*
@@ -752,7 +752,7 @@ cupsdProcessIPPRequest(
  * 'cupsdTimeoutJob()' - Timeout a job waiting on job files.
  */
 
-void
+int                                    /* O - 0 on success, -1 on error */
 cupsdTimeoutJob(cupsd_job_t *job)      /* I - Job to timeout */
 {
   cupsd_printer_t      *printer;       /* Destination printer or class */
@@ -780,10 +780,13 @@ cupsdTimeoutJob(cupsd_job_t *job) /* I - Job to timeout */
     cupsdLogMessage(CUPSD_LOG_INFO, "[Job %d] Adding end banner page \"%s\".",
                     job->id, attr->values[1].string.text);
 
-    kbytes = copy_banner(NULL, job, attr->values[1].string.text);
+    if ((kbytes = copy_banner(NULL, job, attr->values[1].string.text)) < 0)
+      return (-1);
 
     cupsdUpdateQuota(printer, job->username, 0, kbytes);
   }
+
+  return (0);
 }
 
 
@@ -1274,7 +1277,8 @@ add_job(cupsd_client_t  *con,             /* I - Client connection */
 
   cupsdLogMessage(CUPSD_LOG_DEBUG2, "add_job(%p[%d], %p(%s), %p(%s/%s))",
                   con, con->http.fd, printer, printer->name,
-                 filetype, filetype->super, filetype->type);
+                 filetype, filetype ? filetype->super : "none",
+                 filetype ? filetype->type : "none");
 
  /*
   * Check remote printing to non-shared printer...
@@ -1511,17 +1515,7 @@ add_job(cupsd_client_t  *con,            /* I - Client connection */
     */
 
     if (auth_info)
-    {
-      if (job->attrs->prev)
-        job->attrs->prev->next = auth_info->next;
-      else
-        job->attrs->attrs = auth_info->next;
-
-      if (job->attrs->last == auth_info)
-        job->attrs->last = job->attrs->prev;
-
-      _ippFreeAttr(auth_info);
-    }
+      ippDeleteAttribute(job->attrs, auth_info);
   }
 
   if ((attr = ippFindAttribute(job->attrs, "job-originating-host-name",
@@ -1801,7 +1795,8 @@ add_job(cupsd_client_t  *con,             /* I - Client connection */
                       "[Job %d] Adding start banner page \"%s\".",
                       job->id, attr->values[0].string.text);
 
-      kbytes = copy_banner(con, job, attr->values[0].string.text);
+      if ((kbytes = copy_banner(con, job, attr->values[0].string.text)) < 0)
+        return (NULL);
 
       cupsdUpdateQuota(printer, job->username, 0, kbytes);
     }
@@ -2415,13 +2410,16 @@ add_printer(cupsd_client_t  *con,       /* I - Client connection */
     need_restart_job = 1;
 
     supported = ippFindAttribute(printer->attrs, "port-monitor-supported",
-                                 IPP_TAG_KEYWORD);
-    for (i = 0; i < supported->num_values; i ++)
-      if (!strcmp(supported->values[i].string.text,
-                  attr->values[0].string.text))
-        break;
+                                 IPP_TAG_NAME);
+    if (supported)
+    {
+      for (i = 0; i < supported->num_values; i ++)
+        if (!strcmp(supported->values[i].string.text,
+                    attr->values[0].string.text))
+          break;
+    }
 
-    if (i >= supported->num_values)
+    if (!supported || i >= supported->num_values)
     {
       send_ipp_status(con, IPP_NOT_POSSIBLE, _("Bad port-monitor \"%s\"!"),
                      attr->values[0].string.text);
@@ -3158,6 +3156,7 @@ cancel_job(cupsd_client_t  *con,  /* I - Client connection */
   cupsd_job_t  *job;                   /* Job information */
   cups_ptype_t dtype;                  /* Destination type (printer/class) */
   cupsd_printer_t *printer;            /* Printer data */
+  int          purge;                  /* Purge the job? */
 
 
   cupsdLogMessage(CUPSD_LOG_DEBUG2, "cancel_job(%p[%d], %s)", con,
@@ -3265,6 +3264,16 @@ cancel_job(cupsd_client_t  *con, /* I - Client connection */
     jobid = atoi(resource + 6);
   }
 
+ /*
+  * Look for the "purge-job" attribute...
+  */
+
+  if ((attr = ippFindAttribute(con->request, "purge-job",
+                               IPP_TAG_BOOLEAN)) != NULL)
+    purge = attr->values[0].boolean;
+  else
+    purge = 0;
+
  /*
   * See if the job exists...
   */
@@ -3294,7 +3303,7 @@ cancel_job(cupsd_client_t  *con,  /* I - Client connection */
   * we can't cancel...
   */
 
-  if (job->state_value >= IPP_JOB_CANCELED)
+  if (job->state_value >= IPP_JOB_CANCELED && !purge)
   {
     switch (job->state_value)
     {
@@ -3324,11 +3333,15 @@ cancel_job(cupsd_client_t  *con,        /* I - Client connection */
   * Cancel the job and return...
   */
 
-  cupsdCancelJob(job, 0, IPP_JOB_CANCELED);
+  cupsdCancelJob(job, purge, IPP_JOB_CANCELED);
   cupsdCheckJobs();
 
-  cupsdLogMessage(CUPSD_LOG_INFO, "[Job %d] Canceled by \"%s\".", jobid,
-                  username);
+  if (purge)
+    cupsdLogMessage(CUPSD_LOG_INFO, "[Job %d] Purged by \"%s\".", jobid,
+                    username);
+  else
+    cupsdLogMessage(CUPSD_LOG_INFO, "[Job %d] Canceled by \"%s\".", jobid,
+                    username);
 
   con->response->request.status.status_code = IPP_OK;
 }
@@ -3422,13 +3435,6 @@ check_quotas(cupsd_client_t  *con,       /* I - Client connection */
   cupsdLogMessage(CUPSD_LOG_DEBUG2, "check_quotas(%p[%d], %p[%s])",
                   con, con->http.fd, p, p->name);
 
- /*
-  * Check input...
-  */
-
-  if (!con || !p)
-    return (0);
-
  /*
   * Figure out who is printing...
   */
@@ -3935,7 +3941,7 @@ copy_banner(cupsd_client_t *con,  /* I - Client connection */
   */
 
   if (add_file(con, job, banner->filetype, 0))
-    return (0);
+    return (-1);
 
   snprintf(filename, sizeof(filename), "%s/d%05d-%03d", RequestRoot, job->id,
            job->num_files);
@@ -4287,10 +4293,11 @@ copy_model(cupsd_client_t *con,         /* I - Client connection */
                   "copy_model: Running \"cups-driverd cat %s\"...", from);
 
   if (!cupsdStartProcess(buffer, argv, envp, -1, temppipe[1], CGIPipes[1],
-                         -1, -1, 0, &temppid))
+                         -1, -1, 0, DefaultProfile, &temppid))
   {
     close(tempfd);
     unlink(tempfile);
+
     return (-1);
   }
 
@@ -4661,6 +4668,10 @@ copy_printer_attrs(
                 printer->recoverable);
 #endif /* __APPLE__ */
 
+  if (!ra || cupsArrayFind(ra, "marker-change-time"))
+    ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_INTEGER,
+                  "marker-change-time", printer->marker_time);
+
   if (printer->alert && (!ra || cupsArrayFind(ra, "printer-alert")))
     ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_STRING,
                  "printer-alert", NULL, printer->alert);
@@ -4675,6 +4686,18 @@ copy_printer_attrs(
     ippAddDate(con->response, IPP_TAG_PRINTER, "printer-current-time",
                ippTimeToDate(curtime));
 
+#ifdef HAVE_DNSSD
+  if (!ra || cupsArrayFind(ra, "printer-dns-sd-name"))
+  {
+    if (printer->reg_name)
+      ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_NAME,
+                   "printer-dns-sd-name", NULL, printer->reg_name);
+    else
+      ippAddInteger(con->response, IPP_TAG_PRINTER, IPP_TAG_NOVALUE,
+                   "printer-dns-sd-name", 0);
+  }
+#endif /* HAVE_DNSSD */
+
   if (!ra || cupsArrayFind(ra, "printer-error-policy"))
     ippAddString(con->response, IPP_TAG_PRINTER, IPP_TAG_NAME,
                 "printer-error-policy", NULL, printer->error_policy);
@@ -6089,6 +6112,12 @@ get_jobs(cupsd_client_t  *con,           /* I - Client connection */
 
     cupsdLogMessage(CUPSD_LOG_DEBUG2, "get_jobs: job->id = %d", job->id);
 
+    if (!job->dest || !job->username)
+      cupsdLoadJob(job);
+
+    if (!job->dest || !job->username)
+      continue;
+
     if ((dest && strcmp(job->dest, dest)) &&
         (!job->printer || !dest || strcmp(job->printer->name, dest)))
       continue;
@@ -7190,17 +7219,6 @@ move_job(cupsd_client_t  *con,           /* I - Client connection */
     return;
   }
 
- /*
-  * Check policy...
-  */
-
-  if ((status = cupsdCheckPolicy(dprinter->op_policy_ptr, con,
-                                 NULL)) != HTTP_OK)
-  {
-    send_http_error(con, status, dprinter);
-    return;
-  }
-
  /*
   * See if we have a job URI or a printer URI...
   */
@@ -7308,6 +7326,17 @@ move_job(cupsd_client_t  *con,           /* I - Client connection */
     }
   }
 
+ /*
+  * Check the policy of the destination printer...
+  */
+
+  if ((status = cupsdCheckPolicy(dprinter->op_policy_ptr, con,
+                                 job ? job->username : NULL)) != HTTP_OK)
+  {
+    send_http_error(con, status, dprinter);
+    return;
+  }
+
  /*
   * Now move the job or jobs...
   */
@@ -7696,7 +7725,8 @@ print_job(cupsd_client_t  *con,           /* I - Client connection */
   * See if we need to add the ending sheet...
   */
 
-  cupsdTimeoutJob(job);
+  if (cupsdTimeoutJob(job))
+    return;
 
  /*
   * Log and save the job...
@@ -8420,13 +8450,13 @@ save_auth_info(
       cupsFilePrintf(fp, "%s\n", line);
 
       if (!strcmp(dest->auth_info_required[i], "username"))
-        cupsdSetStringf(&job->auth_username, "AUTH_USERNAME=%s",
+        cupsdSetStringf(&job->auth_username, "CUPSD_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_domain, "CUPSD_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_password, "CUPSD_AUTH_PASSWORD=%s",
                        auth_info->values[i].string.text);
     }
   }
@@ -8439,7 +8469,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);
+    cupsdSetStringf(&job->auth_username, "CUPSD_AUTH_USERNAME=%s", con->username);
     cupsdClearString(&job->auth_domain);
 
    /*
@@ -8449,7 +8479,7 @@ 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_password, "CUPSD_AUTH_PASSWORD=%s", con->password);
   }
 
  /*
@@ -8493,9 +8523,7 @@ save_krb5_creds(cupsd_client_t *con,      /* I - Client connection */
   krb5_error_code      error;          /* Kerberos error code */
   OM_uint32            major_status,   /* Major status code */
                        minor_status;   /* Minor status code */
-#    ifdef HAVE_KRB5_CC_NEW_UNIQUE
   krb5_principal       principal;      /* Kerberos principal */
-#    endif /* HAVE_KRB5_CC_NEW_UNIQUE */
 
 
 #   ifdef __APPLE__
@@ -8524,7 +8552,7 @@ save_krb5_creds(cupsd_client_t *con,      /* I - Client connection */
   if ((error = krb5_cc_new_unique(KerberosContext, "FILE", NULL,
                                   &(job->ccache))) != 0)
 #    else /* HAVE_HEIMDAL */
-  if ((error = krb5_cc_gen_new(krb_context, &krb5_fcc_ops,
+  if ((error = krb5_cc_gen_new(KerberosContext, &krb5_fcc_ops,
                                &(job->ccache))) != 0)
 #    endif /* HAVE_KRB5_CC_NEW_UNIQUE */
   {
@@ -8902,7 +8930,8 @@ send_document(cupsd_client_t  *con,       /* I - Client connection */
     * See if we need to add the ending sheet...
     */
 
-    cupsdTimeoutJob(job);
+    if (cupsdTimeoutJob(job))
+      return;
 
     if (job->state_value == IPP_JOB_STOPPED)
     {
@@ -8987,7 +9016,7 @@ send_http_error(
   if (status == HTTP_UNAUTHORIZED &&
       printer && printer->num_auth_info_required > 0 &&
       !strcmp(printer->auth_info_required[0], "negotiate"))
-    cupsdSendError(con, status, AUTH_NEGOTIATE);
+    cupsdSendError(con, status, CUPSD_AUTH_NEGOTIATE);
   else if (printer)
   {
     char       resource[HTTP_MAX_URI]; /* Resource portion of URI */
@@ -9000,13 +9029,13 @@ send_http_error(
       snprintf(resource, sizeof(resource), "/printers/%s", printer->name);
 
     if ((auth = cupsdFindBest(resource, HTTP_POST)) == NULL ||
-        auth->type == AUTH_NONE)
+        auth->type == CUPSD_AUTH_NONE)
       auth = cupsdFindPolicyOp(printer->op_policy_ptr, IPP_PRINT_JOB);
 
-    cupsdSendError(con, status, auth ? auth->type : AUTH_NONE);
+    cupsdSendError(con, status, auth ? auth->type : CUPSD_AUTH_NONE);
   }
   else
-    cupsdSendError(con, status, AUTH_NONE);
+    cupsdSendError(con, status, CUPSD_AUTH_NONE);
 
   ippDelete(con->response);
   con->response = NULL;
@@ -9309,7 +9338,8 @@ set_job_attrs(cupsd_client_t  *con,       /* I - Client connection */
       else if (con->response->request.status.status_code == IPP_OK)
       {
         cupsdSetJobPriority(job, attr->values[0].integer);
-        event |= CUPSD_EVENT_JOB_CONFIG_CHANGED;
+        event |= CUPSD_EVENT_JOB_CONFIG_CHANGED |
+                CUPSD_EVENT_PRINTER_QUEUE_ORDER_CHANGED;
       }
     }
     else if (!strcmp(attr->name, "job-state"))
@@ -9456,6 +9486,10 @@ set_job_attrs(cupsd_client_t  *con,      /* I - Client connection */
   * Send events as needed...
   */
 
+  if (event & CUPSD_EVENT_PRINTER_QUEUE_ORDER_CHANGED)
+    cupsdAddEvent(CUPSD_EVENT_PRINTER_QUEUE_ORDER_CHANGED, job->printer, job,
+                  "Job priority changed by user.");
+
   if (event & CUPSD_EVENT_JOB_STATE)
     cupsdAddEvent(CUPSD_EVENT_JOB_STATE, job->printer, job,
                   job->state_value == IPP_JOB_HELD ?
@@ -9962,6 +9996,8 @@ user_allowed(cupsd_printer_t *p,  /* I - Printer or class */
 {
   int          i;                      /* Looping var */
   struct passwd        *pw;                    /* User password data */
+  char         baseuser[256],          /* Base username */
+               *baseptr;               /* Pointer to "@" in base username */
 
 
   if (p->num_users == 0)
@@ -9970,6 +10006,20 @@ user_allowed(cupsd_printer_t *p,        /* I - Printer or class */
   if (!strcmp(username, "root"))
     return (1);
 
+  if (strchr(username, '@'))
+  {
+   /*
+    * Strip @REALM for username check...
+    */
+
+    strlcpy(baseuser, username, sizeof(baseuser));
+
+    if ((baseptr = strchr(baseuser, '@')) != NULL)
+      *baseptr = '\0';
+
+    username = baseuser;
+  }
+
   pw = getpwnam(username);
   endpwent();
 
@@ -10136,8 +10186,8 @@ validate_user(cupsd_job_t    *job,      /* I - Job */
   cupsdLogMessage(CUPSD_LOG_DEBUG2,
                   "validate_user(job=%d, con=%d, owner=\"%s\", username=%p, "
                  "userlen=%d)",
-                 job ? job->id : 0, con->http.fd, owner ? owner : "(null)",
-                 username, userlen);
+                 job->id, con ? con->http.fd : 0,
+                 owner ? owner : "(null)", username, userlen);
 
  /*
   * Validate input...