SDB:CUPS in a Nutshell
This article addresses experienced Linux users.
It does not provide detailed explanations. All important issues in connection with CUPS are presented in a concise form.
Some details here and there could be a bit outdated (depending on the CUPS version) but in general things are still valid.
This article describes CUPS up to version 2.x under Linux with the traditional filtering system and backends there.
The nowadays driverless printing workflow is rather different.
Overview of the CUPS Printing System
Concepts printing explains the basics about printing.
For a general overview see the "Overview of CUPS" page at the CUPS web interface running on your local machine or see the documentation for your actually used CUPS version at CUPS.org
CUPS home page: http://www.cups.org/
Processing stages of a print job:
The following first step takes place both on client and on server systems. This is the only step on client systems. No queues exist on client systems. A single host with a locally connected printer works as a CUPS server with a print queue for that printer.
(I) Generating a print job
An application program or a command-line tool generates a print job and passes it to the spooler.
A print job consists of information for the spooler, the print data (see PostScript and Concepts printing), and optional information for the filter.
Example for a command-line tool:
lp -d queue -t title -o option1=value1 -o option2=value2 file1 file2
- "queue" and "title" is information for the spooler.
- "option1=value1" and "option2=value2" is information for the filter.
- "file1" and "file2" are the print data.
The following subsequent steps only take place on a CUPS server. A host on which the following steps take place is a server. A host on which a print queue actually exists is a server (in contrast to clients where only references to the actual print queues exist).
The spooler (cupsd) does:
(II) Saving the print job in the spool directory
- Saving the information for the spooler and the filter in the control file /var/spool/cups/c<job-number>
- Saving the data from the files to print in the data file /var/spool/cups/d<job-number>-<file-number>
(III) Filtering the print data and sending printer-specific data to the printer
- Starting the filter system:
- Determining which filters are needed for generating the printer-specific data and establishment of the so called "filter chain" or "filter pipe".
- Starting the programs of the filter chain/pipe with suitable parameters.
- Starting the backend for sending the printer-specific data from the filter pipe to the printer.
(IV) Completing the print job
- Waiting until the backend is finished.
- Deleting the respective files from the spool directory.
The Spooler
Function of the spooler
The main purpose of the spooler system is to move data from the sender to the recipient.
- Accepting data (only from authorized senders).
- Buffering data (until the recipient is ready to accept them).
- Sending data to authorized recipients (after implementing suitable filters, if necessary).
- Providing information about the status of the data (e.g., for "lpstat -W completed -o").
Details:
/usr/sbin/cupsd
- cupsd is the server for the IPP protocol
- cupsd listens on TCP port 631 for IPP tasks for example via commands like "lp -d queue_name file_name" or "lpstat -t"
- cupsd listens on TCP port 631 for HTTP tasks like managing printers via http://localhost:631/printers/
- cupsd uses UDP port 631 for sending and receiving "CUPS Browsing" information (see "Intrinsic design of CUPS for printing in the network" below). Use commands like "netcat -u -l -p 631" to pick up such information (provided UDP port 631 is not yet occupied by cupsd)
- Configuration file for cupsd: /etc/cups/cupsd.conf (since CUPS 1.6 also /etc/cups/cups-files.conf)
- systemd unit files /usr/lib/systemd/system/cups.*
/usr/lib/cups/daemon/cups-lpd
- cups-lpd is the server for the LPD protocol (RFC 1179)
- cups-lpd accepts print jobs that come in on TCP port 515 via the LPD protocol
- Either xinetd or inetd or systemd is used as wrapper for cups-lpd
- Configuration files:
- Either /etc/xinetd.d/cups-lpd
- or the cups-lpd line in /etc/inetd.conf
- or systemd /usr/lib/systemd/system/cups-lpd* unit files
PPD Files
What is a PPD file and how does it work?
See "PPD files: Printer-specific options" at Concepts printing.
For PostScript printers, the PPD file contains the printer-specific options (and nothing else) together with the corresponding PostScript code snippets that must be sent to the PostScript interpreter in order to activate a certain option.
For non-PostScript printers, the PPD file contains additionally information which printer driver program must be used and the options that are available for the particular driver. If several drivers can be used for a given printer, several PPD files are available.
Depending on the printer-specific options set for a certain print job (e.g., "-o PageSize=A4"), the filter system reads the suitable PostScript code snippets (the so called "PostScript invocation values") from the PPD file and inserts them in the PostScript data stream.
The syntax for an option entry in the PPD file with two example entries is as follows:
* Main keyword | Option keyword/translation string | " PostScript invocation value " |
---|---|---|
*PageSize | Letter/letter paper: | "<</PageSize[612 792]/ImagingBBox null>>setpagedevice" |
*PageSize | A4/A4 paper: | "<</PageSize[595 842]/ImagingBBox null>>setpagedevice" |
More information is available in the "Adobe PostScript Printer Description File Format Specification, Version 4.3".
Details:
/etc/cups/ppd/
- This directory contains the PPD files that cupsd actually makes use of.
- The entries (especially the "*Default..." entries) in a PPD file in /etc/cups/ppd/ can vary from the entries in the original PPD file that was specified when the queue was configured.
- This directory contains the original PPD files which are used to set up new print queues. See "openSUSE printer driver software packages" at Concepts printing which packages provide what kind of PPD files.
- Additional PPD files (e.g., PPD files from printer manufacturers) can be copied to this directory in order to make them available for the printer configuration tools.
The OpenPrinting/LinuxPrinting.org printer database
- The OpenPrinting/LinuxPrinting.org printer database consists of XML files from which the Foomatic PPD files are generated.
- The OpenPrinting/LinuxPrinting.org printer database is available at https://wiki.linuxfoundation.org/openprinting/database/databaseintro
The Filter (includes the Driver)
In general "filter" means a program that converts input data into output data and "driver" means device-model-specific software and data.
What does the filter system do and how does it work?
The main purpose of the filter system is to convert the original data of the print job (ASCII, PostScript, PDF) into printer-specific data (PostScript, PCL, ESC/P) via several steps.
Usually the last step is a program which is the printer driver which outputs the final printer-specific data, see "Printer drivers: Make the printer print" at Concepts printing.
Each step is done by a separated filtering program where the filtering programs are run one after the other as a traditional Unix pipe: The original print job data is the input of the first filtering program where its output is sent via the pipe as input to the second filtering program and so on until the output of last filtering program is sent via the pipe as input to the CUPS backend that finally sends the printer-specific data to the printer (see the subsequent section about "The Backends").
The actual filtering of a particular print job for a particular printer model on a particular Linux system depends on various conditions, see "Background Information" at SDB:How to Report a Printing Issue.
In particular the filtering is different for the traditional printing data format PostScript and for the recent printing data format PDF, see "Common printing data formats" at Concepts printing.
Furthermore the actual filtering depends on which kind of printer driver is used.
The following is one particular example how the filtering works for the traditional printing data format PostScript when a printer driver is used that is included in Ghostscript (see Concepts printing). In this case the filtering takes place by means of the following steps:
1) Converting the original data to PostScript.
1a) Determination of the MIME type of the original data:
This happens according to /usr/share/cups/mime/mime.types or /etc/cups/mime.types.
1b) Conversion to PostScript (if it is not yet PostScript):
If the MIME type of the original data is not "application/postscript", then conversion to PostScript according to /usr/share/cups/mime/mime.convs or /etc/cups/mime.convs.
In particular original data of MIME type "text/plain" is converted to PostScript with /usr/lib/cups/filter/texttops.
Since CUPS 1.3.4 only UTF-8 text is supported (which includes 7-bit ASCII text). Text in the ISO-8859 encodings is no longer supported. The reason is that it is not possible to autodetect the encoding so that CUPS cannot process "plain text" files in arbitrary encodings in a reliable way, see SDB:Plain Text versus Locale. To print non-UTF-8 text, you must convert it from its encoding to UTF-8 before sending it to the CUPS server. To print an ISO-8859-1 text file, you may use:
iconv -f ISO-8859-1 -t UTF-8 filename | lp -d queue
See "iconv --help" for some information about iconv.
Printing of PDF or graphics files (JPEG, PNG, etc.) works as before.
2) Inserting the PostScript invocation values in the PostScript data stream.
This happens according to the following line in /usr/share/cups/mime/mime.convs or /etc/cups/mime.convs:
Input MIME type | Output MIME type | Costs | Filter |
---|---|---|---|
application/postscript | application/vnd.cups-postscript | 66 | pstops |
3) Convert PostScript data to printer-specific data.
If a non-PostScript printer is used with a Foomatic PPD file, the PostScript data are converted to printer-specific data according to the following line in every Foomatic (version 3.x) PPD file:
Main keyword | Input MIME type | Costs | Filter |
---|---|---|---|
*cupsFilter: | "application/vnd.cups-postscript | foomatic-rip" |
If a non-PostScript printer is used with a Foomatic PPD file, then foomatic-rip together with Ghostscript serve as the PostScript interpreter.
foomatic-rip proceeds as follows to convert the PostScript data to printer-specific data:
3a) Build a Ghostscript command:
foomatic-rip builds a Ghostscript command with the needed Ghostscript printer driver and additional parameters according to the printer-specific options set for the respective print job.
In some cases, a postfilter is introduced after the Ghostscript command (via pipe). For example for some PCL printers certain options are realized by means of changes in the PCL data stream (e.g., paper tray selection via "perl -e").
3b) Run the Ghostscript command (or pipe):
foomatic-rip executes the Ghostscript command.
If a non-Foomatic PPD file (e.g., a Gutenprint/Gimp-Print PPD file from /usr/share/cups/model/gutenprint or /usr/share/cups/model/stp) is used for a non-PostScript printer, the "*cupsFilter" entries in the PPD file may look as follows:
*cupsFilter: "application/vnd.cups-raster 100 rastertogutenprint"
or
*cupsFilter: "application/vnd.cups-raster 100 rastertoprinter"
With the matching entries in /usr/share/cups/mime/mime.convs or /etc/cups/mime.convs the result is a different filtering procedure. In this particular case /usr/lib/cups/filter/rastertogutenprint or /usr/lib/cups/filter/rastertoprinter is the printer driver program.
For more general information on filters see the man page "man 7 filter". More specific information on filtering is available in the Support Database article SDB:Using Your Own Filters to Print with CUPS.
Details:
/usr/lib/cups/filter/
This directory contains the various filter programs used by the CUPS filter system if a PPD file was specified when the respective queue was configured.
- /usr/lib/cups/filter/*tops (e.g., /usr/lib/cups/filter/texttops) for converting the original data (e.g., "text/plain") to PostScript.
- /usr/lib/cups/filter/pstops for inserting the PostScript invocation values and, if necessary, for reformatting the PostScript data (e.g., to downsize and print two pages on one sheet).
- /usr/lib/cups/filter/foomatic-rip for converting PostScript data to printer-specific data (e.g., PCL or ESC/P).
/etc/cups/interfaces/
Backward incompatible change since CUPS 2.2.0: There is no longer the directory /etc/cups/interfaces because since CUPS 2.2.0 so called "System V style Interface Scripts" are no longer supported for security reasons (cf. the "CHANGES" files in CUPS).
Up to CUPS < 2.2.0 the /etc/cups/interfaces directory contains the filter used by CUPS if a "System V style Interface Script" was specified instead of a PPD file when the respective queue was configured. A "System V style Interface Script" is a single filter program or filter script that produces the printer-specific data for all data formats in which the original print data may be sent. More information about the "System V style Interface Script" is available in the Support Database article "Using Your Own Filters to Print with CUPS": SDB:Using Your Own Filters to Print with CUPS.
"raw"
If neither a PPD file nor a "System V style Interface Script" was specified when the respective queue was configured, no filtering will take place. The original print data will be sent directly from the backend to the recipient (normally the printer) as they are (in "raw" form). It is not possible to convert the line break (e.g., LF -> CR+LF) or append a form feed. Up to CUPS < 2.2.0 a "System V style Interface Script" can be used for this purpose.
The Backends
What is a CUPS backend and how does it work?
Normally, the backend receives the printer-specific data from the filter and forwards them to the printer or another recipient.
The differences between the backend and the filter are as follows:
- One backend but usually several filters (called "filter chain" or "filter pipe") are activated to process a print job. Exceptions: "System V style Interface Script" (one filter) and "raw" printing (no filter).
- In the processing chain/pipe, the backend is always the last program executed for processing a print job.
The print system considers the print job as completed when the backend is finished. The backend is finished when the transmission to the recipient is completed. If the further processing at the recipient fails (e.g., if the printer is not able to print the printer-specific data), this will go unnoticed by the print system.
If the data transmission to the recipient fails (usually after several attempts by the backend), the backend will report an error to the print system (more precisely, to cupsd). The backend decides if and how many attempts make sense before it reports that the data transmission has failed. As further attempts would be futile, cupsd disables printing on the affected queue. After eliminating the cause of the problem, the system administrator must reenable printing with /usr/bin/enable (for CUPS 1.1 - i.e. up to Suse Linux 10.1) or with cupsenable (since CUPS 1.2 - i.e. since openSUSE 10.2).
For more information on backends see the man pages "man 7 backend" for what is specific for backends and "man 7 filter" for general information regarding filters (backends are a special type of filter). More specific information on backends is available in the Support Database article SDB:Using Your Own Backends to Print with CUPS.
Details:
/usr/lib/cups/backend/
This directory contains the various backends.
A suitable backend must be employed under consideration of how the printer can be accessed from the host running the CUPS system and the type of recipient.
The destination to which a backend can send the data can be any URI (Uniform Resource Identifier) for which a suitable backend is available. The first part of the "DeviceURI" entry in /etc/cups/printers.conf determines the backend, the other entries serve as parameters for the backend.
Backend | URI syntax | Example URI |
---|---|---|
parallel | parallel:/dev/lp* | parallel:/dev/lp0 |
usb (traditional) | usb:/dev/usb/lp* | usb:/dev/usb/lp0 |
usb (new) | usb://<make>/<model>?serial=<number> | usb://ACME/FunPrinter%201000?serial=A1B2C3 |
ipp | ipp://<ipp-server.domain>/printers/<queue> | ipp://cups-server.domain/printers/funprinter1000 |
lpd | lpd://<lpd-server.domain>/<queue> | lpd://192.168.101.202/lpt1 |
socket | socket://<host.domain>:<port> | socket://192.168.101.202:9100 |
smb | see the man page smbspool(8) | smb://user:password@workgroup/smb-server/share |
If "user" and "password" are needed for the smb backend, the owner, group, and access permissions for the file /etc/cups/printers.conf must be sufficiently restrictive. The specifications "user" and "password" are not displayed with the command "lpstat -v".
Every backend can also be addressed directly. For example, the "parallel" and "usb" backends return the IEEE-1284 identification of connected printers.
root@host# /usr/lib/cups/backend/parallel direct parallel:/dev/lp0 "ACME FunPrinter 1000" "Parallel Port #1"
root@host# /usr/lib/cups/backend/usb direct usb://ACME/USB%20Printer?serial=1234 "ACME USB Printer" "USB Printer #1" direct usb:/dev/usb/lp1 "Unknown" "USB Printer #2" ...
For older CUPS versions upon start-up, cupsd successively executes all backends in /usr/lib/cups/backend/ in order to determine which of the backends are available on the respective system. Only the available backends can be used for the configuration of queues. The available backends are displayed with "lpinfo -v". For nowadays CUPS versions not the cupsd itself but the separated cups-deviced is run that also executes all backends in /usr/lib/cups/backend/ when a "lpinfo -v" command is run (and cups-driverd is run when a "lpinfo -m" command is run, see "man cups-deviced" and "man cups-driverd").
Command-line Tools
General information on the command-line tools
Do not edit configuration files in /etc/cups/ manually if suitable command-line tools are available for this purpose.
Exception: /etc/cups/cupsd.conf (and since CUPS 1.6 also /etc/cups/cups-files.conf)
After modifications in /etc/cups/cupsd.conf (and since CUPS 1.6 also in /etc/cups/cups-files.conf), cupsd must be restarted in order to make it use the modified configuration.
Do not change CUPS spool files (in /var/spool/cups/) manually. Use CUPS command-line tools.
Never ever change CUPS files manually while the cupsd is running.
In contrast CUPS command-line tools only submit a task what to do to the cupsd and then the cupsd can do it properly.
Reason:
CUPS files are neither re-read nor instantly updated in any case. Rather, cupsd keeps much information in memory and writes it back to the files at more or less arbitrary time (see the "DirtyCleanInterval" cupsd configuration directive).
For example, to clean up all print queues run "cancel -a" (or since CUPS 1.7 "cancel -a -x") which completely removes all existing (old) print jobs (including job history) in all print queues.
Never copy configuration files from other systems into your system unless you know exactly what you are doing. Use command-line tools instead.
For example, to set up the same queues on several machines (e.g., for a backup server), do not copy /etc/cups/printers.conf and /etc/cups/ppd/*, but write the respective commands in a script (usually a sequence of lpadmin commands) and run the script on the various machines. In this way, any error messages will be displayed on the respective machines (e.g., if a PPD file is not available on a machine or if a backend is not available or not ready to use). Furthermore with such a script you have something like a backup plus log-file of your settings, enabling you to restore those settings by running the script at any time.
If you are not sure which graphical tool is best suited for certain special configurations or print queue maintenance actions, use command-line tools instead.
In many cases, the sequence of the options is significant. Read the man pages. For example, the following commands are all different:
lpadmin -E -p queue, lpadmin -p queue -E lpadmin -E -p queue -E
Details:
Command-line tools for creating or editing queues
How to set up a print queue in full compliance with CUPS:
- Retrieve autodetected printers and their correct matching DeviceURIs from the cupsd: Run (as root) "lpinfo -l -v"
- Retrieve available printer driver descriptions from the cupsd: Run (as root) "lpinfo -l -m"
- Select a printer/DeviceURI from the first list and a printer driver from the second list and devise an appropriate queue name.
- Set up the queue: Run (as root) "lpadmin -p queue_name -v DeviceURI -m printer_driver -E" or "lpadmin -p queue_name -v DeviceURI -P /usr/share/cups/model/printer_driver -E"
There is no re-start of the cupsd needed to add, modify, or delete print queues (only a config change of the cupsd itself requires it to be re-started).
Example for creating a usual queue with a PPD file:
root@host# lpadmin -h localhost -p funprinter1000 -v parallel:/dev/lp0 -P /usr/share/cups/model/Postscript.ppd.gz -E
Example for creating a local "raw" queue that only forwards print job data to a queue on a remote cups server (see the sections "raw" and "/usr/lib/cups/backend/" above):
root@host# lpadmin -h localhost -p funprinter1000forwarding -v ipp://cups-server.domain/printers/funprinter1000 -E
Use the following command to check what was created:
user@host$ lpstat -h localhost -a funprinter1000 -p funprinter1000 -v funprinter1000 funprinter1000 accepting requests since Jan 01 00:00 printer funprinter1000 is idle. enabled since Jan 01 00:00 device for funprinter1000: parallel:/dev/lp0
Alternatively, take a look at /etc/cups/printers.conf:
<Printer funprinter1000> Info funprinter1000 DeviceURI parallel:/dev/lp0 State Idle Accepting Yes JobSheets none none QuotaPeriod 0 PageLimit 0 KLimit 0 </Printer>
Or query the system via the web frontend: http://localhost:631/printers/funprinter1000
Editing the queue (e.g., changing the description and location):
root@host# lpadmin -h localhost -p funprinter1000 -D "ACME FunPrinter 1000" -L "2. floor: room 3"
Displaying the printer-specific options and their default settings in /etc/cups/ppd/funprinter1000.ppd (provided the queue was set up with a PPD file):
user@host$ lpoptions -h localhost -p funprinter1000 -l Resolution/Output Resolution: 150dpi *300dpi 600dpi 1200dpi 2400dpi PageSize/Media Size: Letter Legal Executive *A4 A5 ...
The output has the following syntax:
main-keyword/translation-string: option-keyword option-keyword option-keyword ...
The default setting is marked with an * preceding the "option-keyword".
Changing the printer-specific default settings in /etc/cups/ppd/funprinter1000.ppd (provided the queue was set up with a PPD file):
root@host# lpadmin -h localhost -p funprinter1000 -o Resolution=600dpi -o PageSize=Letter
The syntax is as follows:
lpadmin -h localhost -p queue -o main-keyword1=option-keyword1 -o main-keyword2=option-keyword2 ...
Do not use lpoptions for this purpose. Refer to the Support Database article Print Settings with CUPS. Normal users can use lpoptions to save their personal default settings in ~/.cups/lpoptions (since CUPS 1.2 / openSUSE 10.2, it was ~/.lpoptions in CUPS 1.1). More information on this is presented in the same Support Database article.
Use "accept" and "reject" to accept and reject print jobs for a queue.
Use /usr/bin/enable ("enable" is a bash built-in) or /usr/sbin/cupsenable and "disable" or /usr/sbin/cupsdisable to enable and disable printing in a queue (e.g., to avoid print jobs from being lost while doing maintenance work on the printer).
Deleting the queue:
root@host# lpadmin -h localhost -x funprinter1000
Command-line tools for daily use
Avoid BSD-type commands (lpr, lpq, lprm), as these only support a limited number of generic options. Use System V-type commands (lp, lpstat, cancel) instead.
Use lpoptions to save personal printer-specific option settings in ~/.cups/lpoptions (since CUPS 1.2 / openSUSE 10.2, it was ~/.lpoptions in CUPS 1.1). Example:
user@host$ lpoptions -o Resolution=1200dpi -p funprinter1000
The generally available printing options are described on the "Command-Line Printing and Options" page in the "Getting Started" section under "Documentation/Help" at the CUPS web interface running on your local machine or see the "Documentation" for your actually used CUPS version at CUPS.org
cupsd Web Frontend
Every cupsd in the network has an HTTP web frontend. The URL for the local running cupsd is http://localhost:631 and the URL for a remote cupsd on "host.domain" is http://host.domain:631 provided that the remote cupsd which runs on the remote host permits the access.
Details:
In daily operations, the web frontend is usually the best source of information about queues and print jobs. For example, http://localhost:631/printers/ provides an overview of all queues of a local cupsd.
The web frontend is the best way to get documentation on the respective cupsd (cupsd version). For example, the documentation for the locally installed CUPS version is available at http://localhost:631 and the documentation for CUPS installed on a remote server is is available at http://host.domain:631 provided that the remote server permit the access.
Even the PPD files in /etc/cups/ppd/ can be accessed by way of the web frontend. For example, the PPD file of the queue "funprinter1000" on the local host (/etc/cups/ppd/funprinter1000.ppd) can be accessed with the URL http://localhost:631/printers/funprinter1000.ppd and accordingly the PPD file of "queue" on "host.domain" can be accessed with a URL in the form http://host.domain:631/printers/queue.ppd provided that the remote host permit the access.
Configuring CUPS <= 1.5 in the Network
CUPS >= 1.6 has major incompatible changes
After a version upgrade to CUPS >= 1.6 printing in the network would no longer work as it did up to CUPS 1.5.
For an overview about what is new since CUPS 1.6 see https://www.cups.org/blog.html
For details regarding incompatible changes since CUPS 1.6 see https://bugzilla.opensuse.org/show_bug.cgi?id=735404 and follow the links therein.
Since Mac OS X version 10.8 "Mountain Lion" it uses CUPS 1.6 (but not OS X 10.7 "Lion" that has CUPS 1.5). It seems OS X 10.8 clients need a CUPS 1.6 server that supports how OS X 10.8 clients print by default via network. Therefore networks with newest Mac OS X 10.8 clients may require a CUPS 1.6 server.
Users who need backward compatibility would run CUPS up to 1.5 on one server and those who need the new features in CUPS >= 1.6 could additionally run CUPS >= 1.6 on another server.
In particular note that CUPS >= 1.6 usually requires the filters of the cups-filters software that is provided by OpenPrinting.org.
Intrinsic design of CUPS <= 1.5 for printing in the network
CUPS network servers (hosts on which spooling and filtering is done):
- The cupsd of a CUPS network server sends information about its queues to a list of IP addresses (host addresses and/or broadcast addresses). The default setting is an empty list.
- The transmission is repeated after preset intervals. The default setting is 30 seconds.
Clients (hosts that only send print jobs to servers):
- By default, cupsd listens to information from servers. Therefore, a local cupsd should run on every client. There is a list of servers from which information is accepted. By default, information is accepted from all servers.
- The information about a specific queue is deleted on a client if no new information about the queue comes in within a set interval. The default setting is 300 seconds.
In this way, the queues of the server are available directly on the client. Users on the clients can browse the queues on various servers. Therefore the whole stuff is called "Browsing".
Browsing is activated by default. All incoming browsing information is accepted, but no browsing information is sent (see above).
Configuration of a CUPS <= 1.5 server
- Configure print queues for the printers associated with the server.
- Allow the clients to access the queues.
- Activate sending of browsing information to the clients.
Subnetworks should be used to facilitate the configuration. If subnets are used, it is sufficient to send the browsing information to a fixed broadcast address instead of continuously maintaining a list of individual host addresses.
The access to the queues of a server is handled independently, regardless to which hosts the server sends browsing information. A server can grant all clients in the network access to its queues, while sending browsing information to only some of the clients. However, a server should not send any browsing information to clients that do not have access to its queues.
In a large company, it is not possible to have only one large server that sends browsing information for some of the queues to the clients in one department or one building and browsing information for other queues to other clients.
Several servers (one for every department or building) are needed for this.
Details:
Configuration of the print queues on a CUPS <= 1.5 server
The printers belonging to a server are the ones for which the filtering takes place on the server.
I) Configure the printers so that printing works on the server.
Set up print queues for the printers associated with the server.
Verify that printing works correctly when a normal user prints directly from the server. In case of problems inspect the CUPS debug messages on the server, see below.
II) Allow the clients to access the queues.
Either change /etc/cups/cupsd.conf manually or use YaST. Since openSUSE 11.1 use in YaST the "Share Printers" dialog, see YaST Printer.
First let the cupsd listen on the network:
By default the cupsd since CUPS 1.2 (since openSUSE 10.2) listens only on internal ("localhost") network interfaces (and a Unix domain socket) in /etc/cups/cupsd.conf for CUPS 1.2 and later:
Listen localhost:631 Listen /var/run/cups/cups.sock
For a CUPS 1.2 (and later) network server you must change it to listen on the outer network too. Add an entry of the form "Listen IP.of.your.server".
If the CUPS server is accessible from any untrusted network, make sure that you use a firewall to protect your server.
Then allow the clients to access the server:
The default setting in /etc/cups/cupsd.conf is as follows:
<Location /> Order allow,deny Allow 127.0.0.2 </Location>
Access from "localhost" 127.0.0.1 is allowed in any case without an explicite entry and 127.0.0.2 could be assignd to the hostname of the server so that access via the hostname of the server is also allowed.
To allow access from all hosts in the whole local network insert the line
Allow @LOCAL
This setting allows all LOCAL hosts to access cupsd. LOCAL hosts are those whose IP addresses are associated with non-PPP interfaces (more precisely, interfaces whose IFF_POINTOPOINT flag is not set) and whose IP address belongs to the same network as the CUPS server. This means that usually the "Internet" network interface which is connected to an usual modem is excluded. But if it is connected to a cable modem it is not a point-to-point interface so that @LOCAL cannot be used in this case.
To allow access from specific hosts or networks insert lines like
Allow 192.168.100.1 Allow 192.168.200.0/255.255.255.0
We recommend the use of IP addresses instead of names.
Differences regarding older SUSE LINUX versions:
From SUSE LINUX 9.0 up to SUSE LINUX 10.1, the default setting in /etc/cups/cupsd.conf was:
BrowseAllow @LOCAL . . . <Location /> ... Allow @LOCAL </Location>
This setting allowed all LOCAL hosts to access cupsd and furthermore packets from all other hosts have been rejected immediately.
Up to SUSE LINUX 10.1 we provided CUPS 1.1 and since openSUSE 10.2 we provide CUPS 1.2 which is not fully backward compatible with CUPS 1.1.
Therefore in case of an update it is recommended not to use an outdated cupsd.conf from a CUPS 1.1 installation before but to start from scratch with the original cupsd.conf from our CUPS 1.2 (or later) RPM.
For example RunAsUser is no longer supported so that since openSUSE 10.2 / CUPS 1.2 the cupsd runs as root and therefore we are back to its default "basic authentication" via system users and system passwords (in /etc/shadow) so that it works again to authenticate as "root" and use the usual root system password.
III) Activate the sending of browsing information to the clients.
In /etc/cups/cupsd.conf, set the entry "BrowseAddress @LOCAL" in order to send browsing information to all LOCAL hosts, or insert entries in the form "BrowseAddress client.host.IP.address" or "BrowseAddress network.broadcast.IP.address".
The sending of browsing information to the clients is somewhat optional:
- If it is omitted, the clients will not automatically receive information about the queues on the server.
- Nevertheless, due to the previous step the clients are able to address the queues of the server.
Especially in large networks it may make sense to grant access to all clients, but to send browsing information only to some of the clients (e.g., only to the clients located in the same department or building as the server).
IV) Restart the cupsd.
Get CUPS debug messages if it does not work
The CUPS log file /var/log/cups/error_log contains log messages that could be useful for troubleshooting - but it does not contain debug messages by default.
To get CUPS debug messages, see the section "Usually provide CUPS debug messages" in SDB:How to Report a Printing Issue.
Provided you have CUPS debug messages but those messages do not help you to find the root cause why it does not work, you may ask for help as described in SDB:How to Report a Printing Issue.
Configuration of CUPS <= 1.5 clients
Recommended:
- Activate /etc/init.d/cups so that cupsd is started when the client is booted.
- Start cupsd.
From SUSE LINUX 9.1, this takes place by default. If necessary, this can be done with the YaST Runlevel Editor or with insserv. Under normal circumstances, you should not configure anything else, especially
- no local queues on clients and
- no changes in the default settings for cupsd on clients.
Special cases for configuration of CUPS <= 1.5 clients
Optional:
Insert entries in the form "BrowseAllow IP.of.desired.server" and "BrowseDeny IP.of.unwanted.server" in /etc/cups/cupsd.conf in order to reject all kinds of packets (including browsing information) from undesired servers. We recommend the use of IP addresses instead of names. In certain cases, it may be useful to adapt the "BrowseOrder" entry.
If there are servers that do not send any browsing information but whose queues can be accessed (e.g., servers in other departments or buildings), you may want to poll the server's browsing information. To do this, insert an entry in the form "BrowsePoll IP.of.the.server:631" for every server in /etc/cups/cupsd.conf. We recommend the use of IP addresses instead of names. By default, the port on the server is 631. After cupsd is restarted, a cups-polld will be started for every "BrowsePoll" entry.
Either change /etc/cups/cupsd.conf manually or use YaST. Since openSUSE 11.3 use in YaST the "Print via Network" dialog, see YaST Printer.
If browsing is generally undesired:
Set "Browsing Off" in /etc/cups/cupsd.conf. This does not mean that the queues on the server can no longer be accessed. Utilities like the command-line tools can still be used; however, the server must be specified explicitly (normally with the option "-h", see the man pages).
Client-only configuration:
If browsing is generally undesired, there is no reason for running a cupsd on the client. In this case, a client-only configuration should be used. Either set it up manually as described below or use YaST. Since openSUSE 11.1 use in YaST the "Print via Network" dialog, see YaST Printer.
- Stop and deactivate cupsd (using the YaST Runlevel Editor or insserv).
- In /etc/cups/client.conf, insert an entry in the form "ServerName IP.of.the.server".
Such an entry in /etc/cups/client.conf should not exist together with a running local cupsd. As only one entry is possible, the preferred server should be entered. To access a different server, the server must be specified explicitly (option "-h") when using the command-line tools, or the environment variable CUPS_SERVER must be set accordingly. Some applications ignore the "ServerName" entry. In this case, it may be useful to set CUPS_SERVER, or the server can be specified explicitly in the application (e.g., with the option "-h" in the print command).
Minimal client installations:
The standard minimum requirement for addressing CUPS servers is to install the "cups-libs" and "cups-client" packages. In this case, servers can be addressed with the command-line tools.
The absolute minimum requirement for addressing a CUPS server is to install only the "cups-libs" package. In this case, only application programs that use the CUPS libraries directly can print.
Regarding firewall
If the CUPS server and the client systems are in an internal network and when you trust all what there is in your internal network, your network interface must be set to be in the "internal zone".
It doesn't make sense to have a network setup in a trusted internal network with a network interface which belongs to the untrusted "external zone" (which is the default to be safe).
In particular do not disable firewall protection for CUPS (i.e. for IPP which uses TCP port 631 and UDP port 631) for the untrusted "external zone".
See the Support Database article CUPS and SANE Firewall settings.
Allow printer admin tasks for a normal user
Since openSUSE 10.2 / CUPS 1.2 with an original CUPS 1.2 (or later) cupsd.conf file (which supports CUPS operation policies) you could allow printer admin tasks for a normal user as follows:
<Policy default> ... <Limit ... CUPS-Add-Modify-Printer ...> Require user @SYSTEM normal-user
Replace "normal-user" with the system user name (i.e. the user name in /etc/passwd) of the normal user who should be allowed to do printer admin tasks and restart the cupsd.
For details regarding "Operation Policies" see https://www.cups.org/doc/policies.html
Have in mind that a user who is allowed to do printer admin tasks can change the print queues as he likes. For example he could let (possibly confidential) print jobs print as usual (so that the betrayal is not easily noticed) but additionally send a copy of what is printed to any external destination.
In this context a general security advice:
When root allows normal users to do system administration tasks, in particular when root allows normal users to administer system processes (i.e. processes that run as root like the cupsd), then this or that kind of privilege escalation will be possible.
Only trustworthy users who do not misuse their privileges may get allowed to do specific system administration tasks.
See also
SDB:Purchasing a Printer and Compatibility
SDB:Printing via TCP/IP network