]> git.ipfire.org Git - thirdparty/cups.git/blobdiff - scheduler/ipp.c
Merge changes from r6758 to r6781.
[thirdparty/cups.git] / scheduler / ipp.c
index 49a1b55e1eb342d5f8d51a7a5a03079dfc3f5593..04bb9d0fead82fa3b6e8c2ea6254481eed21f3ca 100644 (file)
@@ -8255,14 +8255,19 @@ static void
 save_krb5_creds(cupsd_client_t *con,   /* I - Client connection */
                 cupsd_job_t    *job)   /* I - Job */
 {
-#  ifndef HAVE_KRB5_CC_NEW_UNIQUE
-  char         cachename[1024];        /* Name of resolved cache */
-#  endif /* !HAVE_KRB5_CC_NEW_UNIQUE */
+#  if !defined(HAVE_KRB5_CC_NEW_UNIQUE) && !defined(HAVE_HEIMDAL)
+  cupsdLogMessage(CUPSD_LOG_INFO,
+                  "Sorry, your version of Kerberos does not support delegated "
+                 "credentials!");
+  return;
+
+#  else
+  krb5_error_code error;               /* Kerberos error code */
   OM_uint32    major_status,           /* Major status code */
                minor_status;           /* Minor status code */
 
 
-#  ifdef __APPLE__
+#   ifdef __APPLE__
  /*
   * If the weak-linked GSSAPI/Kerberos library is not present, don't try
   * to use it...
@@ -8270,25 +8275,37 @@ save_krb5_creds(cupsd_client_t *con,    /* I - Client connection */
 
   if (krb5_init_context == NULL)
     return;
-#  endif /* __APPLE__ */
+#    endif /* __APPLE__ */
 
  /*
   * We MUST create a file-based cache because memory-based caches are
   * only valid for the current process/address space.
-  */
-
-#  ifdef HAVE_KRB5_CC_NEW_UNIQUE
-  if (krb5_cc_new_unique(KerberosContext, "FILE", NULL, &(job->ccache)))
-#  else
-  snprintf(cachename, sizeof(cachename), "FILE:%s/k%05d", RequestRoot, job->id);
-
-  if (krb5_cc_resolve(KerberosContext, cachename, &(job->ccache)))
-#  endif /* HAVE_KRB5_CC_NEW_UNIQUE */
-  {
-    cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to create new credentials");
+  *
+  * Due to various bugs/features in different versions of Kerberos, we
+  * need either the krb5_cc_new_unique() function or Heimdal's version
+  * of krb5_cc_gen_new() to create a new FILE: credential cache that
+  * can be passed to the backend.  These functions create a temporary
+  * file (typically in /tmp) containing the cached credentials, which
+  * are removed when we have successfully printed a job.
+  */
+
+#    ifdef HAVE_KRB5_CC_NEW_UNIQUE
+  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,
+                               &(job->ccache))) != 0)
+#    endif /* HAVE_KRB5_CC_NEW_UNIQUE */
+  {
+    cupsdLogMessage(CUPSD_LOG_ERROR, "Unable to create new credentials (%d/%s)",
+                    error, strerror(errno));
     return;
   }
 
+ /*
+  * Copy the user's credentials to the new cache file...
+  */
+
   major_status = gss_krb5_copy_ccache(&minor_status, con->gss_delegated_cred,
                                      job->ccache);
 
@@ -8300,11 +8317,17 @@ save_krb5_creds(cupsd_client_t *con,    /* I - Client connection */
     return;
   }
 
-  cupsdSetStringf(&(job->ccname), "KRB5CCNAME=%s",
+ /*
+  * Add the KRB5CCNAME environment variable to the job so that the
+  * backend can use the credentials when printing.
+  */
+
+  cupsdSetStringf(&(job->ccname), "KRB5CCNAME=FILE:%s",
                   krb5_cc_get_name(KerberosContext, job->ccache));
 
   cupsdLogMessage(CUPSD_LOG_DEBUG2, "[Job %d] save_krb5_creds: %s", job->id,
                   job->ccname);
+#  endif /* HAVE_KRB5_CC_NEW_UNIQUE || HAVE_HEIMDAL */
 }
 #endif /* HAVE_GSSAPI && HAVE_KRB5_H */