CUPS and PyKota

From Wiki

Revision as of 01:18, 23 June 2008 by SYNACK (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to:navigation, search

Installing the base system

  • Install base system of Debian Etch (Sarge does not use a new enough version of CUPS, etc. to provide full functionality)

Installing and configuring Samba/Winbind

  • Install Samba and Winbind, then configure /etc/samba/smb.conf to be similar to below:
        idmap gid = 10000-40000
        obey pam restrictions = yes
        dns proxy = no
        netbios name = <hostname here>
        printing = cups
        invalid users = root
        idmap uid = 10000-20000
        workgroup = <domain here>
        os level = 20
        printcap name = cups
        security = ads
        max log size = 1000
        winbind separator = \
        log file = /var/log/samba/log.%m
        load printers = yes
        socket options = TCP_NODELAY
        wins server = <IP Address of WINS Server>
        encrypt passwords = true
        public = yes
        realm = <FQDN IN CAPS>
        winbind use default domain = yes
        wins proxy = no
        server string = Cups Server
        winbind enum users = yes
        password server = *
        winbind gid = 10000-20000
        winbind enum groups = yes
        syslog = 0
        preferred master = no
        panic action = /usr/share/samba/panic-action %d

        printable = yes
        writable = no
        path = /var/spool/samba
        comment = All Printers
        public = yes
        create mode = 0700
        printer admin = @"domain admins"

	  comment = Printer Drivers
	  path = /etc/samba/drivers
	  browseable = yes
	  read only = no
	  guest ok = yes
	  write list = administrator, @"domain admins"
  • Install krb5-config and krb5-user then configure /etc/krb5.conf similar to below:
       <FQDN IN CAPS> = {
                kdc = <PDC IN CAPS>
                kdc = <BDC IN CAPS>
                admin_server = <PDC IN CAPS>

  • The /etc/nsswitch.conf file should contain the following lines:
passwd:         files winbind
group:          files winbind
shadow:         files winbind
  • Join server to the domain with:

# net ads join -U administrator

  • NB: It may be necessary to restart the winbind service at this point
  • At this point, the configuration can be tested using the command:

# wbinfo -u

  • If Samba and Winbind are working correctly at this point, a list of domain users should be displayed

Installing/configuring CUPS

  • Install the CUPS packages (including the Foomatic printer drivers for CUPS – the full package makes life easier when using the web interface)

# aptitude install cupsys foomatic-db foomatic-filters-ppds

  • Edit the /etc/cups/cupsd.conf file to allow remote access to the necessary users. The following should be sufficient:
# Log general information in error_log - change "info" to "debug" for
# troubleshooting...
LogLevel warning

# Administrator user group...
SystemGroup lpadmin

# Allow remote access
Port 631
Listen /var/run/cups/cups.sock

# Show shared printers on the local network.
Browsing On
BrowseOrder allow,deny
BrowseAllow @LOCAL

# Default authentication type, when authentication is required...
DefaultAuthType Basic

# Restrict access to the server...
<Location />
  Order allow,deny
  Allow @LOCAL

# Restrict access to the admin pages...
<Location /admin>
  Encryption Required
  Order allow,deny
  Allow @LOCAL

# Restrict access to configuration files...
<Location /admin/conf>
  AuthType Basic
  Require user @SYSTEM
  Order allow,deny
  Allow @LOCAL
# Set the default printer/job policies...
<Policy default>
  # Job-related operations must be done by the owner or an adminstrator...
  <Limit Send-Document Send-URI Hold-Job Release-Job Restart-Job Purge-Jobs Set-Job-Attributes Create-Job-Subscription Renew-Subscription Cancel-Subscription Get-Notifications Reprocess-Job Cancel-Current-Job Suspend-Current-Job Resume-Job CUPS-Move-Job>
    Require user @OWNER @SYSTEM
    Order deny,allow

  # All administration operations require an adminstrator to authenticate...
  <Limit Pause-Printer Resume-Printer Set-Printer-Attributes Enable-Printer Disable-Printer Pause-Printer-After-Current-Job Hold-New-Jobs Release-Held-New-Jobs Deactivate-Printer Activate-Printer Restart-Printer Shutdown-Printer Startup-Printer Promote-Job Schedule-Job-After CUPS-Add-Printer CUPS-Delete-Printer CUPS-Add-Class CUPS-Delete-Class CUPS-Accept-Jobs CUPS-Reject-Jobs CUPS-Set-Default>
    AuthType Basic
    Require user @SYSTEM
    Order deny,allow

  # Only the owner or an administrator can cancel or authenticate a job...
  <Limit Cancel-Job CUPS-Authenticate-Job>
    Require user @OWNER @SYSTEM
    Order deny,allow

  <Limit All>
    Order deny,allow

Printcap /var/run/cups/printcap
  • It should now be possible to add printers to CUPS using the web interface at https://<cups server>:631
  • It is advisable to use the Postscript drivers where possible so that printing is as quick as possible
  • Older and more basic JetDirect interfaces also seem to print quicker using the socket 9100 connection method
  • Extract the following files from the CUPS Driver package to /usr/share/cups/drivers:
    • cups6.inf
    • cups6.ini
    • cups6.ppd
    • cupsps6.dll
    • cupsui6.dll
  • Copy the following files from a Windows installation to /usr/share/cups/drivers:
    • ps5ui.dll
    • pscript.hlp
    • pscript.ntf
    • pscript5.dll
  • Ensure all the files within the directory /usr/share/cups/drivers have lower case filenames
  • Change the ownership of /etc/samba/drivers using the following command:

# chown -R administrator:”domain admins” /etc/samba/drivers/

  • Run the following command to export the drivers for all the existing printers in CUPS:

# cupsaddsmb -H servername -U administrator -a

  • To test that this has worked (assuming that there are no error messages), browse to the CUPS server in Windows and try to connect to a printer

Installing/Configuring Pykota

  • Download the Debian Etch package for Pykota
  • Install the package using the following command:

# dpkg -i <filename>

  • After resolving any dependency issues, it may be necessary to run the command again
  • Run the following command:

# pksetup debian

  • Follow the on-screen instructions to configure Pykota
  • At this point, it may be necessary to edit the /etc/pykota/pykota.conf file so that Pykota looks for instead of localhost for the SQL server:
storageserver :
  • Check that BOTH the symlink in /usr/lib/cups/backend AND the origional file /usr/share/pykota/cupspykopta have the execute bit set and restart the cupsysd service
  • Also check the permissions on the cupspykota file

# chown root.root /usr/share/pykota/cupspykota # chmod 700 /usr/share/pykota/cupspykota

  • Check that the Debian package 'pysnmp2' is NOT installed as this is known not to work with Pykota. A working version should have been installed by pksetup
  • Add a printer via the web interface in CUPS – the device type should be of type 'PyKota managed....'
  • Add the following lines to /etc/pykota/pykota.conf (software accounting is used because the hardware accounting increases the time taken to print the first page)

preaccounter : software()

accounter : software()
  • Add accounting options to the printer using pkprinters – e.g. A cost of 1p per page

# pkprinters -a -c 0.01 CupsPrinterName

  • Add a user to PyKota using the pkusers command – for example Joey who will be charged for printing and given an initial allowance of £2

# pkusers -a -l balance -b 2 joey

  • Print to the published printer (either via Samba or through Linux) as Joey and the job should successfully flow through CUPS
  • To check that the accounting is working, first check in the CUPS web interface that the job has logged the number of pages correctly, then run the following commands to display the user's balance and the printer's accounting details

# pkusers -L joey # repykota -P CupsPrinterName

  • To use automatic addition of users, edit /etc/pykota/pykota.conf so that the 'policy:' line reads the following (the default does not work correctly due to the description not having quotes around it!)
policy : external(pkusers --add --skipexisting --limitby noquota $PYKOTAUSERNAME && edpykota --add --skipexisting --printer $PYKOTAPRINTERNAME $PYKOTAUSERNAME)
  • Due to the way that I want to charge, a script is needed to handle the creation of new users. I have placed the script in /usr/share/pykota and it is called


  1. !/bin/bash
  1. Script to create new users for PyKota and assign initial
  2. balance.
  3. Script should be specified in the 'policy' section of
  4. pykota.conf
  1. Variable assignment


  1. If a pupil username limit by balance and assign inital quota

if echo "$PYKOTAUSERNAME" | grep -q ^[0-9]

       then pkusers -a -s -l balance -b $INITIALBALANCE $PYKOTAUSERNAME && edpykota -a -s -P $PYKOTAPRINTERNAME $PYKOTAUSERNAME
  1. If not a pupil, must be a staff member or test account so do
  2. not limit printing
       else pkusers -a -s -l noquota $PYKOTAUSERNAME && edpykota -a -s -P $PYKOTAPRINTERNAME $PYKOTAUSERNAME




  • To run the script, alter the policy line in pykota.conf so that it reads:
policy : external(/usr/share/pykota/ $PYKOTAUSERNAME $PYKOTAPRINTERNAME)
  • To allow use of the CGI web pages, a new website configuration file named pykota was made and added to /etc/apache2/sites-enabled/ :

<apache> NameVirtualHost *

<VirtualHost *>

       ServerAdmin webmaster@localhost
       DocumentRoot /usr/share/pykota/
       <Directory />
               Options FollowSymLinks
               AllowOverride None
       <Directory /usr/share/pykota/>
               Options Indexes FollowSymLinks MultiViews
               AllowOverride None
               Order allow,deny
               allow from all
               # This directive allows us to have pretty PyKota CGIs
               RedirectMatch ^/$ /usr/share/pykota/
       ScriptAlias /cgi-bin/ /usr/share/pykota/cgi-bin/
       <Directory "/usr/share/pykota/cgi-bin">
               AllowOverride None
               Options ExecCGI -MultiViews +SymLinksIfOwnerMatch
               Order allow,deny
               Allow from all
       ErrorLog /var/log/apache2/error.log
       # Possible values include: debug, info, notice, warn, error, crit,
       # alert, emerg.
       LogLevel warn
       CustomLog /var/log/apache2/access.log combined
       ServerSignature On



  • Ideally, the CGIs will require authentication so that users can only see their own print quota account details... this has proved difficult so far.
  • Change the 'poor man threshold' in pykota.conf so that the users get a warning at a time
  • Change the enforcement to 'laxist' in pykota.conf so that users can go into debt on their last job (i.e. A job may cost 20p but a user only has 10p so their balance will be allowed to go to -10p but they will not be able to print again until a value greater than 10p has been added)
  • Change the settings to prevent duplicates
  • Above changes can be seen in pykota.conf below:
## pykota.conf
# IMPORTANT : many more directives can be used, and some of the directives
# below accept different and/or more complex parameters. Please read
# /usr/share/pykota/conf/pykota.conf.sample for more details about the
# numerous possibilities allowed.

# Database settings
storagebackend : pgstorage
storageserver :
storagename : pykota
storageuser : pykotauser
storageuserpw : readonlypw
storagecaching : No
disablehistory : No

# Logging method
logger : system

# Set debug to Yes during installation and testing
debug : Yes

# Who should receive automatic bug reports ?
crashrecipient :

# Should we keep temporary files on disk ?
# Set this to yes for debugging software accounting problems
keepfiles : no

# Logos for banners and CGI scripts
logourl :
logolink :

maildomain : MAIL DOMAIN HERE

# Print Administrator
admin : Administrator

# Use usernames as-is or convert them to lowercase ?
utolower : Yes

# Should we hide some fields in the history (title, filename) ?
privacy : no

# Should we strip some characters off the job titles?
striptitle : smbprn.????????

# Should we charge end users when an error occurs ?
onbackenderror : nocharge

# Default accounting methods :
preaccounter : software()
accounter : software()
onaccountererror : stop

# Who will receive warning messages ?
# both means admin and user.
mailto : both

# Grace delay for pages based quotas, works the same
# as for disk quotas
gracedelay : 7

# Configurable zero, to give free credits
balancezero : 0.0

# Warning limit for credit based quotas
poorman : 0.20

# Warning messages to use
poorwarn : Your Print Quota account balance is low - you have less than 20p of c
redit left. You will soon be unable to print unless you top up your account.

softwarn : Your Print Quota Soft Limit is reached.
 This means that you may still be allowed to print for some
 time, but you must contact your administrator to purchase
 more print quota.

hardwarn : Your Print Quota Hard Limit is reached.
 This means that you are not allowed to print anymore.
 Please contact the network manager
 as soon as possible to solve the problem.

# Number of banners allowed to be printed by users
# who are over quota
maxdenybanners : 0

# Should we allow users to ever be over quota on their last job ?
# strict means no.
enforcement : laxist

# Should we trust printers' internal page counter ?
trustjobsize : yes

# How to handle duplicate jobs
denyduplicates : no
duplicatesdelay : 0

# What should we do when an unknown user prints ?
# The policy below will automatically create a printing account
# for unknown users, allowing them to print with no limit on the
# current printer.
policy : external(/usr/share/pykota/ $PYKOTAUSERNAME $PYKOTAPRINTERNAME)

# Here are some lines that we suggest you add at the end
# of the pykota.conf file. These lines gives possible
# values for the way print jobs' size will be computed.
# NB : it is possible that a manual configuration gives
# better results for you. As always, your mileage may vary.

preaccounter : software()
accounter : software()

preaccounter : software()
Accounter : software()


Invoicing Users

  • In order to charge the staff users for their print outs, a method is needed to calculate their spend. PyKota includes the pkinvoice command for this.
  • pkinvoice produces a PDF containing an invoice for all the users or a given user. Unfortunately, it does not have the ability to filter users using regular expresions... therefore the following script is needed.


  1. !/bin/sh
  1. Script to create invoices for staff users
  1. Read start date from command line – use YYYYMMDD as format


  1. Create temporary directory to store invoices – must be writable by all

DATE=$(date +%y%m%d) DIRECTORY="/tmp/INVOICES_$DATE" mkdir $DIRECTORY chmod a+rwx $DIRECTORY

  1. Create list of staff users

wbinfo -u | grep ^[^0-9] > userlist.txt FILE=userlist.txt

  1. Read the list of users one line at a time

while read UNAME; do

       # If the username is from the admin domain, strip the first part
       if [ ${UNAME:0:5} == "ADMIN" ]
       # Run the pkinvoice command on the username
       pkinvoice -u £ -o $DIRECTORY/$UNAME.pdf start=$STARTDATE end=yesterday username=$UNAME

done <$FILE </bash>