One Solution To Kerberized Printing with CUPS under MacOS
X 10.2 Only
Note: This software will not work with 10.3! The command line klprng may still work.
Updated October 2003
Get the parts from ftp://ftp.ncsu.edu/pub/unity/lockers/project/netatalk/public/klprng.dmg.tar.gz
See details on the CUPS backend script at http://www.ncsu.edu/mac/klprng/klpr.html
1) This solution will only work for users logged in at the console
(iHook has to run and it is a GUI app). Terminal users can use /usr/bin/klprng
-P firstname.lastname@example.org instead of the cups lpr.
2) Printing will fail with no good error message if the user does not have
kerberos tickets before they print.
3) The lprng print servers seem to reject print request with no error message
if the local username requesting the print does not match the kerberos principal
name. This means you can't just kinit from any local user id and then
print. We do not intend to fix this as we use a kerberized login and
don't care. If anyone wants to work on the project we will share everything
we know with them and help test as best we can.
4) This software has only been tested on 10.2.3 and 10.2.4 and WILL NOT WORK
on 10.1.x because CUPS is required. It will not work with 10.3 because the security hole used to run iHook is closed.
5) If this does not work for you we are sorry. We might make some suggestions
but we did not write most of the software and do not have the resources to
fix your problems. I wish we did.
6) We did not write lprng, Patrick Powell did. See http://www.lprng.org/
7) We did not kerberize lprng for the new kerberos model in MacOS X, Sam
Hartman wrote the lprng.diff. It was a one shot deal based on a lprng
snap shot around May 2002(v3.8.12) so don't bother him about it. We
have the patch available with this distribution (lprng.diff).
7) We did not write CUPS, Michael Sweet did most of it. See http://cups.org/.
8) The perl script for our lpr backend is based loosely on the pap
script at http://www.srz-berlin.de/~bla/cups/backend/pap/pap and we are not
sure who wrote it.
1) klprng - This is the lpr client tool from the LPRNG distribution version
3.8.12 with a patch to make it compile with kerberos under MacOS X 10.2.
We put this in /usr/bin because that is were kinit is stored on a default
MacOS X install.
2) lpd.conf - the configuration file that lprng uses to get info about printers
and their configuration. We have the most simple case where all printers
are kerberized and there is one server. Most sites will need to change
this to reflect their information. We put it in /usr/local/etc to avoid conflicts
any other lpr/lpd software.
3) klpr - the cups backend script written in perl that makes everything work.
If you want to change the application you use to print (klprng) or launch
(iHook.app) make sure to change these two lines at the top of this file:
my $cmd = "/usr/bin/klprng";
my $ihook = "/Applications/iHook.app";
See a commented version of the perl klpr backend here.
4) iHook - the software we choose to act as our script launcher. If
you have not already, get it from http://rsug.itd.umich.edu/software/ihook/.
Great job by the UMich team! Runs any script you give it.
5) open - the command line tool Apple provides to run applications or files
by their paths.
How we got here:
We needed to print to kerberized lprng servers from MacOS X 10.2 as I suspect
you do if you are reading this file. We spent a lot of time talking
to a lot of developers on kerberos and at Apple about the problems associated
with kerberos, cups and lprng. We tested lots of theories about ticket
caches, cups configuration, lprng configuration and other things. Several
folks have kerberized command line printing tools on MacOS X (CMU, Reed,
etc) but no one to our knowledge has worked out printing with Print
Center and GUI apps on MacOS X 10.2+. Really the issues all boil down to
two things a) kerberos in MacOS X is cached in memory only and b) the CUPS
printing system is running as root. Since root is not the user that
is requesting to print and has no kerberos tickets then a simple script CUPS
backend that calls a kerberized lpr does not work. Getting to the tickets
in memory won't work because of the way the MacOS partitions off users from
each other (MachO chain issues). Apple suggested and we looked at doing
something like what Cornel's Side Car does with 2 daemons one root and one
that starts on user login that pass tickets to each other. On our way to
testing the suggestions from all the folks we talked to we found a simple
So a rough analogy of what happens when a user prints is that the print job
is thrown over a fence from the user to cupsd running as root. Many
folks thought we should throw the user's kerberos creds over the fence as
well but we found a way to throw the processed print job back over the fence
to klprng running as the user. It seems that any GUI bundle application
which is started using Apple's "open" tool will run as the current console
user regardless of who calls it.
Knowing how the open tool worked made the difference. So now we wrote
a CUPS lpr backend in perl which spools the processed print file in tmp,
writes a shell script into tmp to run klprng, uses open to run that shell
script with iHook, and cleans up both the spool file and the temp script
at finish. Get all that? Ok so it just works for us.
These are some things we think should be done or tried but really do not
have time to work on.
a) Maybe recompile CUPS so that the RunAsUser directive would take $USER
from the user that asked to print and run at least the backend in that users
space. Still not sure this would solve the MachO Chain problems.
b) It would be nice if users using Print Center could not delete every printer
on the box. We thought about building Xpp for MacOS X, making it Aqua
and then adding authorization api checks for creating and destroying printers
but no time.
c) klprng should really be built from the latest versions and have some checks
to match calling user names and kerberos principals.
d) Would be really cool to add new directives to iHook like %GETKRBCRED and
%DESTROYKRBCRED so we would not have the problem with print jobs not going
thru due to lack of kinit before printing.
So Apple did close the open -a path we were using to get back into the user space and at the ticket
cache. We are now working on a Printing Plug-in that will use a Printer Dialog Extension to get a service granting ticket
for lprng and file cache it in /private/tmp on a per user per job basis (this is as secure as we can get).
The new backend will pick up the tickets, destroy the file cache and print the job. No date has been set for release.