Till Kamppeter, linuxprinting.org, Mandriva
till.kamppeter at gmx.net

1. Setting up a Print Queue with CUPS

1. 1. Connecting your printer

Connect your printer to the parallel port or USB. then restart the CUPS daemon with

killall -HUP cupsd

and check with

lpinfo -v

whether CUPS gas recognized your printer. You should get something like

...
direct parallel:/dev/lp0
...
direct usb://hp/dj450?serial=SG31K210C23S
...

If this is not the case check whether the printer is correctly recognized. On USB use the "lsusb" command:

[[email protected] root]# lsusb
Bus 001 Device 016: ID 0924:3d53 Xerox
Bus 001 Device 014: ID 03f0:0512 Hewlett-Packard
Bus 001 Device 007: ID 03f0:1e11 Hewlett-Packard PSC-950
Bus 001 Device 005: ID 04b8:0112 Seiko Epson Corp. Perfection 2450
Bus 001 Device 003: ID 0451:2077 Texas Instruments, Inc. TUSB2077 Hub
Bus 001 Device 001: ID 0000:0000 [[email protected] root]#

Your printer should lead to an entry here, also in the /proc/bus/usb/devices file it should appear. Check with "lsmod" whether the correct kernel modules (kernel 2.4.x: " printer", kernel 2.6.x: "usblp") are loaded and load them with "modprobe <module>" if needed.

For parallel printers check with "/proc/sys/dev/parport/parport?/autoprobe*":

[[email protected] till]$ cat /proc/sys/dev/parport/parport*/autoprobe*
CLASS:PRINTER;
MODEL:dj450;
MANUFACTURER:hp;
DESCRIPTION:hp dj450;
COMMAND SET:MLC,PCL,PML,BIDI-ECP,ECP18,DW-PCL,DYN,DESKJET;
[[email protected] till]$

If nothing is listed, reload the relevant kernel modules

modprobe -r lp parport_pc parport
modprobe lp

For USB printers the /dev/ file system should contain

crw-rw---- 1 lp sys 180, 0 Jan 4 19:34 /dev/usb/lp0
crw-rw---- 1 lp sys 180, 1 Jan 4 19:34 /dev/usb/lp1 ...

for parallel

crw-rw---- 1 lp sys 6, 0 Jan 13 16:34 /dev/lp0
...

1. 2. Your distribution's printer setup tool

First, try to go the way your distribution does. Most printers can simply be set up by the tools coming with the distributions: "printerdrake" (or "mcc") on Mandriva Linux, "yast2" on SuSE, or "printconf-gui" on Red Hat or Fedora. They lead you step-by-step to the configuration of your printers, they auto-detect new printers, suggest the best driver, and they are even sometimes able to fully automatically set up all locally connected printers without any user interaction.

1. 3. General printer setup with CUPS

CUPS itself has two possibilities to add new print queues. The easier way is the built-in web interface of the CUPS system. You reach it with any web browser accessing the address:

http://localhost:631/

Choose "Do Administration Tasks", enter "root" and the root password in the login/password window, and then choose "Add Printer". Now you will be led step-by-step through the set up of the printer.

The name of the print queue should not contain other characters than letters, numbers, or underscores and not more than 12 characters. This assures compatibility with non-CUPS clients, especially Windows, and makes it easier to access the printer via the command line. "Location" and "Description" need not to be filled in, they are only comments, but filling them in makes it easier for users to find the most suitable printer in a network.

After clicking "Continue" you are asked for the "Device" for your queue. Choose the appropruate parallel or USB port. The entry should contain the model name of your printer.

On the next two pages choose manufacturer and model. If your model is not listed, follow the steps in the next sections.

If you come to the step "Printer ... has been added successfully" your queue is set up, click on the printer's name to get to the printer's administration page. Now click on "Configure Printer" and choose the default settings for it. Make sure that the default paper size is A4 when you are outside the US or Canada. Click on "Print Test Page" to check whether the printer really works.

Alternatively, you can set up a printer by the command line with the "lpadmin" command. See "man lpadmin" for more info.

NOTE:

  • On SuSE systems another authentication method is used ("Digest"). To use the web interface, you must give a digest password to root at first, using the command "lppasswd":

    lppasswd -a -g sys root

    and enter a password (not necessarily the normal root password. This password has to be used for the web interface (or any other CUPS frontend) then.

  • On Ubuntu Linux the administrative tasks of the CUPS web interface are disabled by default. They say that this is for security reasons. To re-enable them, add the user "cupsys" to the "shadow" group in /etc/group.

  • On Debian (and therefore also Ubuntu) the CUPS packages have names with "cupsys" instead of "cups" and the CUPS daemon is restarted with "/etc/init.d/cupsys restart" instead of "/etc/init.d/cups restart".

  • In certain error cases a print queue can get disabled and jobs stay waiting in the queue. To enable it, you need to run the command "enable" of CUPS:

    /usr/bin/enable <queue name>

    to re-enable the printer or click the green "Start Printer" button on the printer's page in the web interface.

    To avoid auto-disabling in CUPS 1.1.x you can use beh (the Backend Error Handler) from:

    http://www.linuxprinting.org/beh.html

    In CUPS 1.2 the error handling can be configured to repeat or discard the job instead of disabling the queue without any extra software.

  • If you cannot print from KDE applications, or cannot access all printer settings, click the "Options >>" button at the lower left of the printing dialog to expand it and check whether the printing system is set to CUPS.

  • A very good graphical CUPS administration interface is the KDE Printing Manager. On every machine with installed KDE you find it in the KDE Control Center under "Peripherals" -> "Printers". Take care that at the bottom of the window CUPS is chosen as your printing system. The "Administrator Mode" gives you the possibility to do several administration tasks without entering the root login and password again and again. Operation should be intuitive, right-click on the printer queue entries and on the free area around them to get menues with all functions.

    On the web you will find information on

    http://printing.kde.org

  • If printing from KDE (and also the KDE Printing Manager) does not work for you with CUPS 1.2, start "kprinter" (or choose "File" -> "Print" in the menu of a KDE application). In the dialog click on "System Options" at the bottom. A new dialog pops up where you choose "CUPS Server" on the left, at the top in the section "Server information" set the "Host" to "localhost" and the "Port" to "631" then. After clicking OK the printing functionality of KDE should start to work immediately.

Further info you get in the CUPS documentation on

http://localhost:631/documentation.html

especially:

http://localhost:631/sam.html

1. 4. PPDs for PostScript printers

PostScript is a platform-independent page description language which is used by many mid-range and high-end laser printers and even by some high-end inkjets. Adobe has not only created PostScript, but also a way how to describe the properties and special commands of the different PostScript printers: The PPD (Postscript Printer Description) files, which also CUPS uses to describe printers. All this is well documented by Adobe:

http://partners.adobe.com/public/developer/ps/index_specs.html

PostScript printers are always shipped with appropriate PPD files. And these files describe their properties exactly. The files are also used by the drivers for Windows and Mac OS. Using these files with CUPS makes the full functionality of the printer (trays, resolutions, staplers, ...) available and therefore this is highly recommended.

To use a PPD simply copy it to /usr/share/cups/model, make it readable for everyone, let CUPS register it doing "killall -HUP cupsd" or "/etc/init.d/cups restart", and it will appear as a printer model in the web interface of CUPS (or in other printer administration programs). Set up your print queue as shown above then.

You find the PPDs either on the driver CDs which come with printer (but unfortunately often compressed in a way that one cannot uncompress them with free software, at some manufacturers, like for example Brother the PPDs on the driver CDs are not compressed), on installed Windows boxes, on the manufacturer's web site, at Adobe (mainly older models)

http://www.adobe.com/products/printerdrivers/winppd.html

on linuxprinting.org (these files are released as free software by the manufacturers)

http://www.linuxprinting.org/download/PPD/

or on www.cups.org (most files contributed by printer manufacturers):

http://www.cups.org/ppd.php

If there are PPDs for different Windows and Mac OS systems, the NT4 or Mac OS X versions should work best.

More info about PPDs you can find on:

http://www.linuxprinting.org/ppd-doc.html

Check the integrity of the PPD files with the "cupstestppd" utility. Often the output helps you fixing small flaws by editing the PPD file. CUPS only accepts PPD files which pass the test. The references in the messages are to the following document:

http://partners.adobe.com/public/developer/en/ps/5003.PPD_Spec_v4.3.pdf

1. 5. Non-PostScript printers, GhostScript, and Foomatic

Under Unix and Linux applications usually produce PostScript when one sends a document to a printer and all printers are treated as PostScript printers. If a printer does not understand PostScript by itself the software PostScript interpreter GhostScript is used to translate the incoming PostScript into the printer's own language (PCL, ESC/P 2, ... or something proprietary).

The code which generates the printer's native language is the so-called printer driver. There are more or less sophisticated drivers for many printers and languages.

There are different types of drivers:

  • GhostScript built-in

    This driver concept is the oldest one. Drivers are pieces of code compiled into the GhostScript executable. One has to rebuild GhostScript to add a driver and so adding drivers for new printers is not trivial for most users. It is not recommended to create new drivers of this type. To determine which drivers are available, do "gs -h"and see the "Devices" section of the output. The current Subversion repository of ESP GhostScript contains all known free drivers of this type.

  • Filter

    Filters are separate executables which convert a printer-independent graphics format produced by GhostScript (PNM, PPM, ...) into the printer's native language. They appeared because some people wanted to create a printer driver quickly without needing to study the internals of GhostScript. The advantage is that you do not need to patch and compile GhostScript to install them. So they are very easy to install. To find out whether the driver you need is already installed, check whether the driver's executable is in the execution path (Use "which <driver name>").

  • CUPS Raster

    CUPS raster drivers are a special form of filter type drivers. The concept is developed as a part of CUPS to make driver installation easy. CUPS calls GhostScript to translate the PostScript input into the CUPS raster format and an additional CUPS filter to translate the CUPS raster format into the printer's language. These drivers come always with PPDs which do not only contain options and printer properties but also instruct CUPS to call the correct CUPS filter. Which of these drivers are installed you see by the PPD files in /usr/share/cups/model (and its subdirectories) and by the printer models showing up in the lists when setting up a print queue with the web interface of CUPS (entries contain "CUPS").

  • IJS plug-in

    Like filters IJS plug-ins are also separate executables and so they also do not require GhostScript to be patched and recompiled to add support for a new printer. But in contrary to filters IJS plug-ins communicate bi-directionally with GhostScript and so GhostScript can ask them for certain printer properties and adapt its rendering appropriately. The executables have to be in the execution path, like filters. They usually contain "ijs" somewhere in their names and some of them can be called with the "-h" command line option to get version information.

  • Uniprint

    This method is not common any more. GhostScript has a built-in driver named "uniprint" which is a universal raster driver. One can supply all comands which have to be sent to a printer to do raster printing on the GhostScript command line or by a file. For some printers there are several such files with the extension ".upp" in the /usr/share/ghostscript/<version>/lib/ directory.

As the drivers come from many different sources (often students who simply needed their printers for their work) they are of so many different types and are also invoked by very different and cumbersome command lines. There are also usually no PPD files supplied with them to easily use them with CUPS.

Foomatic is a layer between the GhostScript/driver combo and the printing system. It provides a PPD file for every valid printer/driver pair and a universal filter, which can be easily integrated into the well-known printing systems (CUPS, LPRng, LPD, PPR, PDQ) or be used stand-alone for direct, spooler-less printing.

The filter, "foomatic-rip", is then called by the printing system to convert the job data from PostScript to the printer's language. It reads in the PPD file which contains all information about the driver and how it is used, the command line prototype, all user-settable options and whet has to be inserted into the command line or into the job data to execute the users's choices. With this information and the user-supplied settings "foomatic-rip" builds the correct GhostScript command line and inserts PostScript or PJL commands into the job data stream. It finally executes GhostScript using the command line and pipes the PostScript data through it.

Using Foomatic with CUPS is easy. You look up your printer in the database on linuxprinting.org, choose a driver and then doenload the appropriate PPD fiile. Put the PPD file into /usr/share/cups/model and make it readable for everyone.

If your printer is not listed on linuxprinting.org, you could either try a driver for one of its predecessor models or you can check in the manual whether it uses a standard language (PostScript, PCL,ESC/P, ...) and use one of the "Generic" printer entries in the database.

Verify that the appropriate driver is installed. See the driver type descriptions above to learn how to determine whether a driver is installed. Install the driver if needed.

Download also "foomatic-rip" and "foomatic-gswrapper", put them into /usr/bin and make them readable and executable for everyone. Create a link to make "foomatic-rip" visible for CUPS:

ln -s /usr/bin/foomatic-rip /usr/lib/cups/filter/

Restart CUPS with "killall -HUP cupsd" or "/etc/init.d/cups restart".

Now set up a print queue with CUPS as described above. In the web interface choose an entry which contains your printer's model name and "Foomatic".

NOTE:

  • Do not use Foomatic PPDs for PostScript printers when you have a manufacturer-supplied PPD. The Foomatic PPDs for PostScript printers are generic and support only a few options, the manufacturer-supplied PPDs give access to the full functionality of your printer.

Some links:

linuxprinting.org printer database:

http://www.linuxprinting.org/printer_list.cgi

Instructions for setting up printers with CUPS and handling PPDs:

http://www.linuxprinting.org/cups-doc.html
http://www.linuxprinting.org/ppd-doc.html

More driver sources (non-free for otherwise unsupported printers):

Canon inkjets:

http://www.turboprint.de/
ftp://download.canon.jp/pub/driver/bj/linux/
http://forum.kanotix.net/viewtopic.php?t=7784
http://mambo.kuhp.kyoto-u.ac.jp/~takushi/

Canon laser printers:

ftp://download.canon.jp/pub/driver/lasershot/linux/

Brother printers and multi-function devices:

http://solutions.brother.com/linux/en_us/index.html

Epson printers, scanners, and multi-function devices:

http://www.avasys.jp/english/linux_e/index.html

1. 6. Multi-function devices

On multi-function devices you probably want to use not only the printer but also the scanner, fax, and memory card reader.

On Epson devices printer, scanner, and card reader behave as independent USB devices. The card reader appears as a USB mass-storage device. The scanner is usually automatically discovered by SANE, mostly via the "epson" backend, but sometimes also via "plustek" or "snapscan". Please note that for "snapscan" the firmware of the scanner must be installed on your computer, so that the driver can upload it onto the device (see the SnapScan web site). Epson provides also the IScan driver package, but it contains closed-source components and therefore it is not included in most Linux distributions.

Links related to scanning with Epson's multi-function devices:

http://www.sane-project.org/
http://snapscan.sourceforge.net/
http://www.avasys.jp/english/linux_e/index.html

With newer kernels (2.6.13 and newer) there are often problems with the components put together in one device. In such a case update to SANE 1.0.17.

HP offers the most complete support with their completely free HPLIP (HP Linux Printing and Imaging, http://hpinkjet.sourceforge.net/). You cannot only scan via SANE and access memory cards (also on devices connected via parallel port or ethernet), but you can also read out ink/toner levels, clean and check the nozzles, do simple color calibrations, and since HPLIP 0.9.8 you can even send faxes from your PC.

With its ink level and maintenance facilities HPLIP is also useful for pure printers from HP

In some distributions HP printers and multi-function devices are automatically set up with HPLIP. If not, with HPLIP 0.9.8 and later the setup is easy. It comes with a tool named "hp-setup" which auto-detects locally connected HP devices and sets up appropriate print and fax queues automatically. Make also sure that your /etc/sane.d/dll.conf contains a line with only "hpaio" in it and you will be able to print and fax via CUPS, to scan via SANE, to access memory cards via USB storage (only newer devices, USB connection required), and do all the rest with the graphical tool "hp-toolbox".

For card readers it is highly recommended to use them via USB storage whenever possible. They work via "hp-toolbox" on all models, but they are so extremely slow that buying a USB-2.0 card reader for around 10 EUR is the much better solution.

On Ubuntu it is possible that the HPLIP daemons are already installed but not the "hp-toolbox". Get it installed with "apt-get install hplip". Note also that all PPD files from HPLIP (PostScript and HPIJS) are listed under the manufacturer name "HP (HPLIP)" in the CUPS web interface

.

Note thet HPOJ is not maintainmed any more. So switch to HPLIP in case of problems.

For Brother's multi-function devices there are proprietary drivers from Brother available for download:

http://solutions.brother.com/linux/en_us/index.html

Some Samsung devices come with closed-source drivers on CD-Rom. For some Lexmark devices (X7x, X11xx) there are SANE drivers, so that you can at least scan with them.

On network-connected high-end multi-function devices you can scan via the front panel buttons and then transfer the scanned images via e-mail, FTP, or WWW to your computer.

SANE does also excellent network scanning via "saned" on the server and the "net" backend on the clients. And SANE-TWAIN on Windows clients.

2. Ethernet-Connected Printers

2. 1. General

Ethernet-connected printers (or conventional printers connected to print boxes like HP JetDirect or so) are very convenient in networks, as they do not rely on a single server. In small, especially home networks every PC has its own queue to the printer and so no PC needs to keep running day and night to have the printer accessible. In big networks several redundant servers have queues to the printer. If all are running they form a cluster and share the workload, if one fails, the jobs are simply done by the others.

2. 2. Assigning an IP address to a printer

On some more sophisticated devices you can enter the IP via the front panel, on others it has to be done by software running on a computer and accessing the printer or printbox through the network.

If you look into the manual of your printer or ethernet printing adapter, in many cases they simply tell you to install a Windows program from the supplied CDs to configure the ethernet interface. Do not think you have bought a very expensive paperweight then, you can usually configure the IP of such a device with different standard methods.

 

One possibility is using the "arp" (Address Resolution Protocol) utility, giving the command

arp -s <ip-address> <ethernet-address>

for example

arp -s 192.0.2.2 08:00:69:00:12:34

The ethernet address (also called MAC address) you find on the sticker on the device or its network card or by printing a self-test/configuration page with the device (there is a special button for it, you must hold down a button for some seconds, or hold down a button while turning the device on). Some devices can also display their MAC address on the front panel. It is a sequence of 6 2-digit hexadecimal numbers like for example 00:60:4C:4A:55:9D. After accessing your printer (web interface, ping, ...) you can also find the MAC address in the /proc/net/arp file.

Alternatively, you can install and run "rarpd" on your machine and enter all IP assignments in the /etc/ethers file like:

08:00:69:00:17:e3 myprinter.mydomain.com
08:00:69:00:12:34 192.0.2.2

Then the IP will be assigned whenever any device listed in the file is turned on. This way one has a central management for the IPs, there are no problems with devices not remembering their IPs when power-cycling, and if you have temporarily used a device at another place, it gets its IP back automatically.

Also bootp can be used to assign IP addresses to printers.

Check whether the printer accepted the IP address with

ping <ip-address>

If these methods do not work, you need to access one of the device's administration interfaces while it still has an IP address not compatible to your network. To do so, get the printer's current IP address and netmask by printing the self-test/configuration page. If the IP address and netmask are compatible to your network, you can skip the next step (for example if the printer has polled them from a DHCP server). If in doubt, try "ping <printer's IP address>" to see whether your printer answers.

If the address is not compatible to your network, enter the following command (as root):

ifconfig eth0 inet www.xxx.yyy.zzz netmask 255.255.255.0 up

www, xxx, yyy are the first three numbers of the printer's IP and zzz a number other than the forth number of the printer's IP (not 0 and not 255). After "netmask" the printer's netmask has to be given, it is 255.255.255.0 in most cases, as shown here. Note that after giving this command your computer is not reachable on the network. So do not use an important server for this.

Now you should be able to access the printer's administration interfaces, for example a web interface by pointing a browser to "http://<printer's IP address>/" or do "telnet <printer's IP address>". Set the printer's IP so that the printer can be accessed from your network. Some printers need to be turned off and on again after changing the IP address.

If you needed to enter the above-mentioned "ifconfig eth0 ..." command to get access to your printer's administration interface, enter the two commands "ifdown eth0; ifup eth0" or the command "/etc/init.d/network restart" to get back to your normal network configuration. Check whether you are able to access the printer under its new IP address via ping, your browser, or telnet.

You can also do the assignment of the IP address to the printer on your DHCP server. This way you can configure all your network devices at a central place and so you can avoid having to configure the individual devices when you move them between different subnets.

 

If you want to do so, configure your printer to get its IP via DHCP (often also called automatic IP in the printers web or telnet interface). Many manufacturers preconfigure their printers already for using DHCP to get an IP address. Then assign the desired IP address to the printers MAC address on the DHCP server. If the DHCP server is on a router, use the router's web administration interface for that, if it is on a Linux or Unix box, add the following to /etc/dhcpd.conf:

host <host name for printer> {
  hardware ethernet <printer's mac address>;
  fixed-address <IP address for printer>;
}

 

So the entry on the DHCP server could be:

 

host SagemMF3625 {
  hardware ethernet 00:60:4C:4A:55:9D;
  fixed-address 192.168.1.193;
}

 

Now restart the DHCP server (for example with "/etc/init.d/dhcpd restart") and then turn off and turn on the printer, so that it polls its IP from your DHCP server.

2. 3. Discovering the printer's network protocols

To find out which protocols a printer supports, simply look which ports are open on it. This is done with the "nmap" command. Do

nmap <ip-address>

for example

[[email protected] root]# nmap 192.168.100.20

Starting nmap 3.78 ( http://www.insecure.org/nmap/ ) at 2005-01-13 20:56 EST
Interesting ports on printer.mandrakesoft.com (192.168.100.20):
(The 1657 ports scanned but not shown below are in state: closed)
PORT     STATE SERVICE
21/tcp   open ftp
23/tcp   open telnet
80/tcp   open http
280/tcp  open http-mgmt
515/tcp  open printer
631/tcp  open ipp
9100/tcp open jetdirect
MAC Address: 00:10:83:BB:B1:29 (Hewlett-packard Company)

Nmap run completed -- 1 IP address (1 host up) scanned in 12.671 seconds
[[email protected] root]#

Now you can see by the ports which protocols are supported:

port protocol
  23 printer admin via telnet
  80 printer admin via web
 139 printing via SMB
 515 printing via LPD
 631 printing via IPP
9100 printing via TCP/Socket (can be also other ports > 1023)

your printer has an admin interface via telnet (do "telnet <printer IP>") or web (use URL "http:/<printer IP>/" in your browser) you can probably activate or deactivate the possible communication protocols of your printer. So open the desired protocol and close the others for example to avoid that a print quota system on your server will be surrounded.

See

http://localhost:631/sam.html#COMMON_NETWORK

for more information about setting up network printing devices.

2. 4. Setting up a print queue

In principle, the print queues are set up the same way as for local printers, via the printer setup tool of your distribution, the CUPS web interface or the "lpadmin" command. The only difference is what has to be entered for the device to which the jobs should go.

CUPS does not auto-detect the presence of network-connected printers. You have to know its IP and its protocol, in some cases even more information. In the web interface you choose on the "Device" page which protocol should be used to access your printer, on the next page you have to enter the so-called device URI (Unified Resource Identifier) then. If you use "lpadmin" you have to supply the device URI on the command line ("-v" option). The choice of printer model and driver is exactly the same as for a USB or parallel printer.

Easiest to set up is the access through the TCP/Socket protocol (also known as AppSocket or JetDirect). One only needs the IP of the printer and the port number. The IP you have assigned to your device and the port number you get from the "nmap" output. Most common is 9100, for multi-port print boxes 9101, 9102, and 9103, but other port numbers greater than 1023 are possible. So use TCP/Socket whenever it is possible.

The device URI is

socket://<printer IP>:<port number>

Example for a printer with IP 192.158.100.20 and port 9100:

socket://192.158.100.20:9100

Alternatively, you can use the LPD protocol (Line Printer Daemon, the former standard printing system on Linux machines, still widely used on commercial Unix systems). For this port 515 must be open on your device. Often it is enough to supply only the IP address of your printer, but sometimes you need to know also the name of the internal print queue of the device, which cannot be easily auto-detected by software running on your computer. So simply try at first only with the IP address if you do not have a queue name. If you need a queue name, you can either find it in the manual (if you are lucky), guess common names as "LPD", "LPR", "ps", "PORT", "LPT", ... or these name with an added number (on Brother printers it is "binary_p1"), or find it on

http://localhost:631/sam.html#COMMON_NETWORK

The device URI without queue name is then

lpd://<printer-ip>

and with queue name

lpd://<printer-ip>/<queue-name>

where "queue-name" is the name of the LPD queue on your printer or print box.

A third possibility is to try SMB (Windows NT protocol). This will work if the printer's port 139 is listed as open by "nmap". SMB is not supported by the CUPS software itself, but by Samba. It is enough to install the Samba client software coming with your distribution. You will not need running Samba daemons. Restart the CUPS daemon with

killall -HUP cupsd

or

/etc/init.d/cups restart

after installing Samba. "lpinfo -v" should list "network smb" then.

The information which you need to supply is the printer's IP and the printer share name. The share name varies between the different printer models and can be determined with the "smbclient" command:

smbclient -N -L <printer IP>

You should have at least one share of the type "Printer". The device URI looks as follows then:

smb://<printer-ip>/<share>

More information you can find on

http://localhost:631/sam.html#PRINTING_OTHER
http://localhost:631/sam.html#COMMON_NETWORK

3. Networked Printing with CUPS

3. 1. Basic CUPS configuration for remote printer auto-discovery

Sharing printers between computers running CUPS (Linux, Unix, Mac OS X) is very easy, when the correct CUPS configuration is used. Once having the correct configuration, you set up a print queue on the machine where the printer is attached to and the other machines will have the printer vailable automatically within the next 30 seconds. And if you move the printer to another box, no change has to be done on the other machines, they will discover the move by themselves.

For the automatic discovery of remote printers every machine with locally defined print queues (CUPS server) broadcasts its host name and the names of the queues into the network every 30 seconds. Every machine running a CUPS daemon listens to such broadcasts, collects this information, and treats these queues like its own local queues (CUPS client).

 

So a CUPS client lists all remote CUPS queues it gets knowledge of with "lpstat -p" command. Jobs sent to these remote queues the CUPS client passes automatically to the CUPS server so that the server can print them. Also the user-settable options of remote CUPS queues can be accessed on the CUPS client. "lpoptions" and the graphical printing frontends like "kprinter" or "xpp" show all the options as defined in the PPD file on the CUPS server and the user can set them. The processing of the jobs is done always on the server, so neither drivers nor PPD files need to be installed on the CUPS clients. And nothing needs to be removed from the clients when a printer is removed from a server. A machine with a running CUPS daemon can be both a CUPS server and a CUPS client.

Do not think the broadcasts apply a high load to your networks. Only a few bytes are broadcasted every 30 seconds, not more than the host name and the queue names. All other info which you see about remote printers on a CUPS client is polled from the server on demand, only when an application requests it. You can still change the length of the interval, for example in networs with extremely many printers.

To get this working as easy as possible and with a basic security for small office or home networks edit the /etc/cups/cupsd.conf file as follows:

LogLevel info
TempDir /var/spool/cups/tmp
Port 631

BrowseAddress @LOCAL
BrowseDeny All
BrowseAllow 127.0.0.1
BrowseAllow @LOCAL
BrowseOrder deny,allow

<Location />
Order Deny,Allow
Deny From All
Allow From 127.0.0.1
Allow From @LOCAL
</Location>

<Location /admin>
AuthType Basic
AuthClass System
Order Deny,Allow
Deny From All
Allow From 127.0.0.1
</Location>

Comment lines and most blank lines are not shown here. All other lines not shown here can be (or stay) commented out ("#" added at the beginning of the line).

NOTE:

  • Do not forget to restart the CUPS daemon with "killall -HUP cupsd" whenever you edit anything in /etc/cups/cupsd.conf or in any file in /etc/cups or its subdirectories.

  • On some distributions (like Ubuntu) the /etc/cups/cupsd.conf file is split into several files. /etc/cups/cupsd.conf contains "Include <filename>" directives, telling which file have to be inserted at that place.

The "LogLevel" setting tells how much should be logged in /var/log/cups/error_log by default. Leave it on "info" as long as you do not try to troubleshoot some problem. The "TempDir" can be different on your system. Do not modify or delete this line. 631 is the default port of CUPS (and IPP, the Internet Printing Protocol, the communication protocol CUPS is using), so do not change it.

The "Browse..." settings control the broadcasting of printer information between CUPS daemons.

"BrowseAdress" tells to which CUPS clients information about the queues on your machine is broadcasted. "@LOCAL" means all local networks, but not PPP, or dialed connections, so you printers will not get broadcasted into the internet and no costly dial-on-demand connections will be triggered. Yo can also specify an address range ("192.168.100.*") or several "BrowseAddress" lines with address ranges or even the IP addresses of single machines.

"BrowseDeny", "BrowseAllow", and "BrowseOrder" define from which CUPS servers broadcasted printers will be accepted and from where not. In our case we have a "BrowseOrder deny,allow" so the "BrowseDeny" are treated first and then the "BrowseAllow". Without any such line all broadcasted printers are accepted, the "BrowseDeny all" leads to no printer being accepted, but after that line the "BrowseAllow" lines are treated so the broadcasts from the IP 127.0.0.1 (the local machine) and from the local networks ("@LOCAL") are accepted again. The configuration of the example prevents queues appearing from faulty sites which broadcast into the internet. Using a more restrictive configuration you can get rid of long printer lists in your printing frontends so that you only see the printers you really need.

The "<Location ...> ... </Location>" blocks control the access to your machine by CUPS clients. Possible locations are:

Location Purpose
/ The overall CUPS server
/admin Adding/modifying/removing print queues
/printers Printing on all queues
/printers/<queue name> Printing on a particular queue
/jobs Modifying/removing jobs

The locations behave like a directory hierarchy, if a sublocation does not exist, the access rules of the parent location apply. For example if there are the queues "bwlaser", "colorlaser", and "inkjet" and the locations "/printers" and "/printers/inkjet", the rules of "/printers" are valid only for "bwlaser" and "colorlaser", for "inkjet" the rules of "/printers/inkjet" apply.

The "Deny From", "Allow From", and "Order" rules work the same way for client access permission as "BrowseDeny", "BrowseAllow", and "BrowseOrder" for accepting broadcasted printers. So in the example general access (Location "/") is allowed for the local machine and all clients on the local networks. This applies especially for printing on all print queues as there is no "/printers" location. Print queue manipulation is even only allowed from the local machine.

If only selected client machines are allowed to print on a certain CUPS server/printer, a user who is root on such a client can export the printer to clients who are not allowed by creating a queue which uses the ipp backend to point to the restricted printer on the server and sharing this queue to everyone else. So the admin must trust the users at the machines to which he exports printers or not allow them to be root on the client. Replacing a client by a machine with faked MAC address is still possible. The "ipp" backend cannot be simply removed, as it is needed for a CUPS client to talk to a CUPS server when printing through a queue broadcasted by the server.

Access cannot only be restricted per-network or per-machine but also per-user. For user-wise access restrictions the "AuthType" and "AuthClass" rules are used.

"AuthType" can be "None" (no per-user access restriction, no login/password required), "Basic" (permitted users can access with their usual Unix login/password on the server), or "Digest" (CUPS has its own user accounts defined with the "lppasswd" command).

NOTE:

  • "AuthType Basic" cannot be used if CUPS is configured so that it drops its root privileges directly after being started ("RunAsUser Yes" in /etc/cups/cupsd.conf, default setting in SuSE). Then CUPS does not have access to /etc/shadow any more and a user-based authentication is only possible if CUPS has its own passwords. This means that in this case "AuthType Digest" has to be used and passwords have to be defined with "lppasswd".

"AuthClass" can be "System", then only users of the system group (usually "sys", users can be added in /etc/group) and root can access. It can also be "User", to give all Unix or Digest users on the server access or "Group" to give access to the users in the group specified by the "AuthGroupName" rule.

In our example everyone can print, as there are no per-user restrictions in the "/" location. But queue manipulation can only be done by the members of the Unix System group, usually this is only "root". Therefore you need to log in as "root" in the web interface to set up queues.

3. 2. High availability

In CUPS it is also easy to set up high availability by having redundant printers or servers.

For example you can connect three (preferrably equal) printers via USB to one CUPS server. You define a queue with the same configuration to each of these printers, for example with the names "laser1", "laser2", and "laser3". Now you set up a so-called printer class. This is a queue which does not point to a printer, but to a set of other queues. In this case you let it point to outr three queues "laser1", "laser2", and "laser3". Let us call the class "laser". To define the class one uses again the web interface of CUPS, simply clicking the "Add Class" button on the Administration page. "lpadmin" also allows to define classes.

If a user would send a job to "laser2" the job has to wait until all other jobs on "laser2" are ready and "laser2" must be ready to print (turned on, paper and toner loaded). Otherwise the user's job waits in the queue, even if "laser1" and "laser3" are doing nothing.

If the user sends the job to the class "laser". The first printer which gets free will take the job. So if "laser1" is printing a 100-page job and "laser2" is out of paper, the user's one-page letter goes to "laser3" and so it comes out quickly.

The problem would be if the server fails. Then none of the printers is available and the users cannot print. So we connect each printer to another computer, which means that if one of the computers fails, the other two printers are still available. But there is one problem: On which server do we define the class "laser"? If this server fails, the printers are all not available again.

The solution is a so called "implicit class", a class automatically defined by CUPS. Therefore we do not call the three queues on the three servers "laser1", "laser2", and "laser3". It is much simpler, we call them all "laser" and let them get broadcasted into our network. Now the clients receive broadcasts of three equally-named queues. For the users of the clients only one queue named "laser" appears. And this queue behaves as a class: the first of the three printers which gets free takes the job. So independent which of the three server/printer combos are working, if at least one is working the jobs sent to "laser" get printed. Also there is no single point of failure which defines the class "laser". "laser" is defined on every client and only if at least one of the three servers is working.

If you have an ethernet-connected printer you could define a queue for it on every client, so the clients are their own CUPS servers and do not depend on a single server. But imagine the number of print queues you see in graphical printing frontends when every queue has another name, and that in a network with only one printer. And imagine also the administration nightmare when the IP of the printer has to be changed.

So here you better choose three machines and define equally-named queues pointing to this one printer. You get an implicit class which will be the only one visible queue on the CUPS clients. And you do not need to rely on one server, you can print if at least one of the three is running.

Also combinations of this are possible: For example two servers and three ethernet printers, where on each of the two servers is exactly the same CUPS configuration: Three queues pointing to the three printers and a class putting together the three queues. The two classes on the two servers form an implicit class and so printing into this implicit class works with any arbitrary pair of server and printer.

3. 3. Print quotas and accounting

CUPS has also basic page accounting and quota capabilities.

Every printed page is logged in the file /var/log/cups/page_log So one can everytime read out this file and determine who printed how many pages. The system is based on the CUPS filters. They simply analyse the PostScript data stream to determine the number of pages. And there fore it depends on the quality of the PostScript generated by the applications whether the pages get correctly counted. And if there is a paper jam, pages are already counted and do not get printed. Also Jobs which get rendered printer-ready on the client (Windows) will not get accounted correctly, as CUPS does not understand the proprietary language of the printer.

In addition, one can restrict the amount of pages (or kBytes) which a user is allowed to print in a certain time frame. Such restrictions can be applied to the print queues with the "lpadmin" command.

lpadmin -p printer1 -o job-quota-period=604800 -o job-k-limit=1024
lpadmin -p printer2 -o job-quota-period=604800 -o job-page-limit=100

The first command means that within the "job-quota-period" (time always given in seconds, in this example we have one week) users can only print a maximum of 1024 kBytes (= 1 MByte) of data on the printer "printer1". The second command restricts printing on "printer2" to 100 pages per week. One can also give both "job-k-limit" and "job-page-limit" to one queue. Then both limits apply so the printer rejects jobs when the user already reaches one of the limits, either the 1 MByte or the 100 pages.

This is a very simple quota system: Quotas cannot be given per-user, so a certain user's quota cannot be raised independent of the other users, for example if the user pays his pages or gets a more printing-intensive job. Also counting of the pages is not very sophisticated as it was already shown above.

So for more sophisticated accounting it is recommended to use add-on software which is specialized for this job. This software can limit printing per-user, can create bills for the users, use hardware page counting methods of laser printers, and even estimate the actual amount of toner or ink needed for a page sent to the printer by counting the pixels.

The most well-known and complete free software package for print accounting and quotas id PyKota:

http://www.librelogiciel.com/software/PyKota/

A simple system based on reading out the hardware counter of network printers via SNMP is accsnmp:

http://fritz.potsdam.edu/projects/cupsapps/

3. 4. LPD clients

If you have some older boxes, or machines with commercial Unix systems, you have probably LPD on them and not CUPS. Also Windows clients which print via Microsoft's print services for Unix print via the LPD protocol. You do not need to install LPD or LPRng on your print servers to get print jobs from these boxes printed. CUPS has an interface to LPD clients, the so-called CUPS-LPD mini-daemon.

The CUPS-LPD mini-daemon maps the CUPS queues known to your server's CUPS daemon to the LPD protocol. The queues will have the same name for LPD as they have for CUPS.

To activate the CUPS-LPD mini-daemon, you have to get it invoked on demand by inetd or xinetd. For inetd add the line

printer stream tcp nowait lp /usr/lib/cups/daemon/cups-lpd cups-lpd

to /etc/inetd.conf and give a kick to the inetd with "killall -HUP inetd". For xinetd create a file named /etc/xinetd.d/cups-lpd containing

service printer
{
    socket_type = stream
    protocol = tcp
    wait = no
    user = lp
    group = sys
    server = /usr/lib/cups/daemon/cups-lpd
    server_args = -o document-format=application/octet-stream
    passenv =
    env = TMPDIR=/var/spool/cups/tmp
    disable = no
}

and kick the xinetd daemon with "killall -HUP xinetd". From now on LPD clients can print on your queues the classical LPD way. Note that any access restrictions in /etc/cups/cupsd.conf, in /etc/hosts.allow and in /etc/hosts.deny are ignored. So every user and every machine can print via LPD on your server.

4. Accessing Printers from Windows Clients via Samba

4. 1. Sharing the CUPS queues to Windows clients

At first check whether the needed Samba server packages are installed and that your Samba version is linked against the CUPS library (should be the case in most modern Linux distributions). To check whether Samba is linked against the CUPS library, use the "ldd" command:

root# ldd `which smbd`
libssl.so.0.9.6 => /usr/lib/libssl.so.0.9.6 (0x4002d000)
libcrypto.so.0.9.6 => /usr/lib/libcrypto.so.0.9.6 (0x4005a000)
libcups.so.2 => /usr/lib/libcups.so.2 (0x40123000)
[...]

If "libcups" is listed as shown in this example, your Samba is OK. If not, try to get CUPS-enabled packages of Samba for your distro or compile Samba from source. If you compile Samba from source, you need to have the header/development package of the CUPS library ("libcups-devel", "cupsys-dev", or similar) installed.

You also need to take care that the names of all your printers are not longer than 12 characters. If a queue name is longer, edit /etc/cups/printers.conf to modify the queue name and then activate the change with the usual "killall -HUP cupsd". CUPS has no on-board tool to rename print queues, but some other printer setup tools, like "printerdrake" in Mandriva Linux, have.

Now do the following modifications on /etc/samba/smb.conf:

[global]
load printers = yes
printing = cups
printcap name = cups

printer admin = @ntadmins

[printers]
comment = All Printers
path = /var/spool/samba
browseable = no
public = yes
guest ok = yes
writable = no
printable = yes
printer admin = root, @ntadmins

[print$]
comment = Printer Driver Download Area
path = /etc/samba/drivers
browseable = yes
guest ok = yes
read only = yes
write list = @ntadmins, root

All lines not supposed to be modified are not shown. Do not touch that lines, otherwise you could loose other Samba services, like file sharing or so.

Restart Samba (usually "/etc/init.d/smb restart") to get your changes active.

Create the "ntadmins" group in /etc/group and add users which should be allowed to to Samba printer administration. "root" is always allowed to do so and does not need to be added to this group.

If some of the directories referred to in the lines shown above does not exist, create it. Let the ownerships of these directories be root and the ntadmins group. Set permissions for everyone to read and execute and for user and group to write into the directories.

Create Samba accounts for "root" and every user in the "ntadmins" group with "smbpasswd":

root# smbpasswd -a root
New SMB password: secret
Retype new SMB password: secret

Samba has no access to the Unix passwords in /etc/shadow. Therefore Samba needs its own passwords. Use always the Samba passwords for authentication against Samba.

Most important in the smb.conf is "printing = cups". This makes Samba use the functions of the CUPS library to access printers, instead of shell command lines defined in /etc/samba/smb.conf So if your smb.conf contains lines like "print command", "lpq command", ... in the "[global]" or "[printers]" sections, they get ignored.

The "[print$]" section defines a file share where Windows printer drivers can be supplied so that Windows clients can download them automatically ("Point'n'Print").

The shown configuration makes all printers known to the local CUPS daemon being shared via Samba. This means they will all be detected in the network Neighborhood or in the Add Printer Wizard under Windows.

To really print with these printers under Windows one can use the Windows drivers which came with the printers and set up queues with them on each client. Or one uploads the drivers into the print$ share on the Samba server (can be done with the Add Printer Wizard under Windows). This requires also uncommenting the "octet-stream" lines in the end of the /etc/cups/mime.types and /etc/cups/mime.convs files and then restarting CUPS, so that CUPS accepts already completely processed print data on regular print queues and does not try to filter it. For more about this, see the printing sections of the Samba HOWTO collection:

http://de.samba.org/samba/docs/man/Samba-HOWTO-Collection/printing.html
http://de.samba.org/samba/docs/man/Samba-HOWTO-Collection/CUPS-printing.html

This approach of printing has the disadvantage that once many different printer drivers are on each Windows client and this can compromise the stability of Windows. Another problem is that CUPS does not understand the job data which passes through it and so it cannot count the printed pages. This prevents print accounting from working correctly.

The better way is to let our server emulate PostScript printers, as it does for Unix applications. For that a PostScript driver for Windows and the PPD file of the CUPS queue is put up in the print$ share and so Windows will use the PostScript driver for all printers and send PostScript, as a Unix client. This way every Windows client has only one printer driver installed and CUPS gets data on which it can do accounting and other types of processing.