Project 153 - Implement print quotas via Pcounter


1. Introduction

The School of Engineering and Electronics (SEE) uses a system based on Pcounter to implement accounting - and charging - for printing in their Linux student labs. The purpose of this project is to investigate exactly how SEE's system works, and whether it's feasible to copy the solution in order to provide printer accounting and/or charging in all Informatics student labs.

2. How SEE's Linux printing works

2.1 CUPS background

  1. When a CUPS print server receives a job for an smb:// queue, it processes the job via its /usr/lib/cups/backend/smb backend filter, having first set the environment variable DEVICE_URI to the full name of the queue.

    In a default CUPS installation, /usr/lib/cups/backend/smb is just a symlink to the SAMBA-supplied /usr/bin/smbspool binary.

  2. CUPS backends without world execute permissions are run as the root user. Otherwise, the backend runs as the unprivileged user lp. (man -s7 backend)

  3. Content filters (e.g. text to Postscript) are applied by the CUPS server to the print job as specified by the PPD file associated with the queue.

  4. smbspool (man -s8 smbspool) takes the same six parameters as any other CUPS filter; the second parameter is the user name. If the Kerberos credentials cache specified by KRB5CCNAME contains valid credentials, then smbspool can use Kerberos authentication.

2.2 SEE configuration

  1. SEE use the krb5 module in the PAM stack. Their users log in with their EASE password, so they get a TGT for EASE.ED.AC.UK on login.

  2. Each of SEE's lab machines is individually configured as a CUPS server with two queues, the associated URI's of which are:


    Each queue is associated with the Kyocera-FS-1030D Postscript printer PPD file: that corresponds to the printer physically installed in SEE's lab.

    As specified by the URI's, each CUPS queue points to a queue on the IS print server; those IS queues then target SEE's Kyocera-FS-1030D Postscript lab printer. The first queue is configured to charge for printing at 5p/sheet via the IS Pcounter service; the second offers free printing. (For our purposes, we're only interested in the charged queue.)

    The IS server is a Windows2003 server, in the Active Directory (i.e. the ED.AC.UK Kerberos domain.)

  3. SEE use the CUPS /etc/cups/mime.convs and /etc/cups/local.convs files exactly as supplied by the CUPS RPMs; they don't modify these files in any way.

  4. On each SEE lab machine, the default SMB filter on /usr/lib/cups/backend/smb is replaced by the following script (owner: root; permissions: 0700):

       CUPSUID=`id -u $2`
       KRB5PATH=`find /tmp -mtime -1 -name krb5cc_${CUPSUID}* | head -n 1`
       KRB5CCNAME=${KRB5PATH} /usr/bin/smbspool ${DEVICE_URI} $1 $2 "$3" "$4" "$5" $6

    (Comment: this script doesn't appear to deal with the six allowed parameters to smbspool correctly - but, reportedly, it works ...)

2.3 SEE print sequence

  1. SEE users get a TGT for EASE.ED.AC.UK on login; it's stored in their credentials cache /tmp/krb5cc_<UID>.

  2. When a SEE user prints via CUPS to the local queue smb://, the /usr/lib/cups/backend/smb script is invoked. Owing to the permissions on the script, it will be running as the root user. The script locates the user's credentials cache, then uses that in the smbspool call to the IS print server. That is, the smbspool call uses Kerberos authentication to the remote IS print server on behalf of the calling user. Cross-realm authentication results in the user getting a krbtgt/ED.AC.UK@EASE.ED.AC.UK cross-realm TGT, then a scieng1$@ED.AC.UK service ticket. smbspool then sends the print job to the IS server.

    (Comment: this explains why each machine involved has to be running as a full CUPS server. The CUPS server talking to the IS printer server needs access to the sending user's credentials cache on the machine from which the print job is being sent.)

  3. All print job formatting and filtering is performed at the SEE end by the CUPS server(s), using the specified PPD files. The IS queue merely routes the job to the target SEE printer. It also talks to the IS Pcounter system to decrement the user's account.

  4. Users can inspect their Pcounter balance by going to

This all reportedly works fine.

3. Attempt to replicate SEE's Linux printing

  1. IS have created a queue - smb:// - which targets our if113m0 printer. The IS server is a Windows2008 server, in the Active Directory (i.e. the ED.AC.UK Kerberos domain.) A test print from IS successfully emerges from this printer.

    The creation of that queue was requested in CMS ticket 1066695, which is where this entire issue continues to be tracked.

    Comment: To allow ( to access if113m0 (a.k.a. via the HP JetDirect protocal requires suitable adjustments to the Informatics firewall. These has been enabled - as strictly as possible - by the following additions to our configuration:


       /*  pantone                       */
       /*  HP LaserJet P4015x in IF1.13  */
       #include <dice/options/ipfilter.h> 
       ipfilter.export         jetdirect-sciengprintserver


       ipfilter.exportrestrict      edlan resnet calton cstr divpc034 gdmr \
                                    sciengprintserver ...[snip]...
       ipfilter.allowToWireN \

    Should other IS print servers similarly need to be allowed through the firewall in the course of this work, they will need similar treatment.

  2. The desktop machine ancona has been set up as a CUPS server with a single queue defined as follows:

       !cups.queues            mSET(if113m0samba)
       cups.uri_if113m0samba   smb://
       cups.ppd_if113m0samba   /usr/local/share/ppd/HP/hp-laserjet_p4015x-ps.ppd.gz

  3. ancona has been added to the ipfilter.notOffSiteTrusted list in live/ipfilter.h so that it can send SMB requests to the IS server on TCP/UDP ports 135-139 and 445.

  4. Helper binaries have been defined on ancona as follows:


       /usr/kerberos/bin/kinit -c /tmp/krb5cc_${UID}_cups_smb $USER@ED.AC.UK


       CUPSUID=`/usr/bin/id -u $2`
       export KRB5CCNAME=/tmp/krb5cc_${CUPSUID}_cups_smb
       /usr/bin/smbspool "$1" "$2" "$3" "$4" "$5" $6

4. Current situation and problems

  1. Cross-realm authentication from INF.ED.AC.UK to does not work. Exactly why isn't clear, but there are visible differences on the wire (*) in the protocol negotiations between INF.ED.AC.UK and (i.e. the Win2008 IS print server allocated to Informatics), and INF.ED.AC.UK and (the Win2003 IS print server allocated to SEE. (†))

    (* Specifically: smbspool negotiates authentication options with the remote server using GSSAPI and its SPNEGO pseudo-protocol. For the Win2003 print server, SPNEGO eventually returns the full name of Kerberos service principal for the remote service, namely scieng1$@ED.AC.UK. Such a full principal name is not returned by the Win2008 print server; the consequence is that the client then incorrectly assumes that the service principal exists in its (i.e. the client's) local domain, i.e. INF.ED.AC.UK.)

    The proposed workaround is to abandon single-signon for this purpose, and to have students run a plogin (or similar) command to get the necessary initial krbtgt/ED.AC.UK@ED.AC.UK ticket at the start of any working session, and to store this ticket in a specific credentials cache. This seems reasonable.

    († In principle, we could ask IS to give us exactly the same server as they use for SEE - but that doesn't sound like a good permanent solution since, if the differences are to do with differences between Win2003 and Win2008, the problems will presumably recur. In this respect, SEE might suddenly find that their current setup stops working sometime.)

  2. Ignoring CUPS, it's possible to target the IS print server manually by kinit'ing to ED.AC.UK, and then running smbspool by hand. Doing so, I currently see the following behaviour:

    1. If the IS print server is sent a raw text file, a print does emerge from the printer - but it's stair-stepped -, and the user's printer account balance is correspondingly decremented.

    2. If the IS print server is sent a raw PDF file, a print does emerge from the printer, but the user's printer account balance is not correspondingly decremented.

    3. If the IS print server is sent a raw Postscript file, I neither get a print, nor do I see my printer account balance decremented.

    The same behaviour can be replicated via CUPS (if suitable changes are made to ancona:/etc/cups/local.convs, so that jobs are sent by CUPS to the IS server in raw format.) So, conversely, if manual printing using smbspool can be made to work reliably, the expectation is that printing via CUPS will also work.

    SEE don't see, and never have seen, any similar problems. The problems seem to me to indicate that we have a mismatch in expectations of either acceptable input, or job filtering, between us and IS. I have posed this question in the CMS ticket (on 23.11.2010) but have not yet had a response.

    Assuming print job filtering can be made to work as we need, then we still need an explanation - and a solution - for the differences in account balance handling between i and ii above: the entire point of this exercise is reliably to implement charging for printing.

  3. In a fully-working system, there are circumstances where a user could subvert the set-up and have his/her printing charged to another person.

  4. For unknown reasons, I find that my kerberos-authenticated access to the IS queue (bootstrapped by the plogin command) stops working after a random period (this is very hard to test for, but it seems to be between 15 minutes and 1 hour), after which I have to plogin again. I do not know why this happens; one initial guess is imperfect time synchronisation. The crudest fix would be to have the plogin script fork a job which periodically reauthenticated the user.

-- IanDurkacz - 03 Dec 2010

Topic revision: r9 - 02 Feb 2011 - 15:23:06 - IanDurkacz
This site is powered by the TWiki collaboration platformCopyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback
This Wiki uses Cookies