NAME
lpd - line printer daemon
SYNOPSIS
/usr/local/bin/lpd [-Llogfile] [-F] [-V] [-Ddebugopt]
DESCRIPTION
The lpd program is the printer server program of the LPRng
software suite. This software is an enhanced and modified
version of the Berkeley LPD software.
OPTIONS
-L logfile
specifies an alternate file to be used for logging
error and debugging messages. The syslog(8) facility
is used to log critical messages as well.
-F Under normal operation, the LPD server will run in
background mode. The -F flag forces it to run in
forground mode, where it is more easily debugged.
-V Print program version information.
-D debugopt
Debugging is controlled using the - D option. This
accepts a comma-separated list of debugging settings.
These settings take one of two forms: facility=value ,
or value to set an overall default value. The
available facilities can be determined by invoking LPD
with the -D= parameter.
OPERATION
Lpd is the line printer daemon (spool queue handler) and is
normally invoked at boot time from the rc(8) file; it can
also be started by a user. Note that the lpd server needs
only run on systems where actual printing or spooling is
taking place. lpr(1) and other related programs transfer
files using network facilities to the lpd .
When started, lpd reads a configuration file to obtain basic
operational parameters and then reads the printcap(5)
database information to determine the which printers have
spool queues and to start spool queue server processes. If
running as a background server, it will disconnect from its
control terminal and run in the background. It uses the
system calls listen(2) and accept(2) to receive requests to
print files in the queue, transfer files to the spooling
area, display the queue, remove jobs from the queue, or
perform a spool queue control function. In each case it
creates one or more server processes to handle the request
and the lpd process will listen for more requests.
Sending the server a SIGHUP signal causes the server to
reread the various configuration and inititialization files.
This action is similar to that of the INETD and other
servers. The same action is taken when sent a reread
command by the lpc(1) program. At an interveral specified
by the poll_time configuration variable, lpd will check for
spool queues with jobs and no printing activity, and start
printing.
LPD access control is provided by two means: the pathnames
or programs specified by the perms_path configuration
information and the printcap XU (check user) entry. These
entries consist of a list of files separated by colons
and/or a set of filters. For example:
/etc/lpd.perms:|/usr/local/lib/perms
would specify a file and a filter. The filter program is
invoked with the filter_options specified in the
configuration information, and is sent the name of the
printer on the filter standard input. The filter should
respond by writing a list of permissions entries on its
standard output.
Each LPD service request is check against the entries in the
permissions file and/or filter response. The following is a
typical permissions file:
# Set default permissions
DEFAULT ACCEPT
# Reject any connections from outside our subnet
REJECT SERVICE=X NOT IP=130.191.0.0/255.255.0.0
# Only accept Printing (P) and spooling (LPR) from
# Engineering Lab or the Dean's office
REJECT SERVICE=P,R NOT REMOTEHOST=*.eng.astart.com,dean.astart.com
# Do not accept forwarded jobs for printing
REJECT SERVICE=P FORWARD
# Allow only the administrators control access
ACCEPT SERVICE=C,M REMOTEHOST=spooler.eng.astart.com USER=root,papowell
ACCEPT SERVICE=C,M SERVER REMOTEUSER=root,papowell
# Allow only the user on the same host who spooled job to remove it
ACCEPT SERVICE=M SAMEUSER SAMEHOST
REJECT SERVICE=M,C
Permission checking is done by using a set of keys (or
fields) with associated values to check for permission. The
SERVICE key has value P for printing (i.e.- unspooling), R
for spooling (i.e.- LPR request), C and S for printer
control and status respectively (i.e.- LPC request), M for
removal (i.e.- LPRM request), Q for queue information (i.e.-
LPRM request), and so forth. The key indicates the initial
connection to the LPD spooler, and can be used to control
connections from remote systems. The values of the USER,
HOST, and IP keys taken from the control file which is being
received or checked for permissions. The REMOTEUSER,
REMOTEHOST and REMOTEIP keys are those either sent as part
of a command, or derived from information about the current
network connection. Each line of the permissions file is
scanned for key names and values, and these are matched
against the request keys information. When all matches on a
line are made, then search terminates with the specified
action (ACCEPT/REJECT). If no match is found the default
permission value is used. The DEFAULT key is used to
specify the current default permission to be used for
successful matches or if there is no match after scanning
the entire permissions database.
The GROUP entry is used to check that the USER name appears
in a group entry in the system user group database. For
example, GROUP=student*,staff* would check to see if any of
the group name matching student* or staff* have the
specified user name in them. If a system has the netgroups
capability, a group name starting with a @ will be treated
as a netgroup name, and current user name from the job file
will bechecked to see if it is in the group. Similarly, the
REMOTEGROUP entry will check a remote user name. The PORT
entry can be used to ensure that a connection to the server
orignates from a specified range of ports. For more
details, see the lpd.perm(5) man page.
The permissions database is scanned in order of the fixed
file entries and then by invoking the specified filters for
each of the permissions lists. It is recommended that the
filters be placed at the end of the permissions lists. The
user name is one of the parameters passed to the filter, and
can be used to determine if a user has permissions to print
a file.
Key Match Connect Job Job LPQ LPRM LPC
Spool Print
SERVICE S 'X' 'R' 'P' 'Q' 'M' 'C,S'
USER S - JUSR JUSR JUSR JUSR JUSR
HOST S RH JH JH JH JH JH
GROUP S - JUSR JUSR JUSR JUSR JUSR
IP IP RIP JIP JIP RIP JIP JIP
PORT N PORT PORT - PORT PORT PORT
REMOTEUSER S - JUSR JUSR JUSR CUSR CUSR
REMOTEHOST S RH RH JH RH RH RH
REMOTEGROUP S - JUSR JUSR JUSR CUSR CUSR
REMOTEIP IP RIP RIP JIP RIP RIP RIP
CONTROLLINE S - CL CL CL CL CL
PRINTER S - PR PR PR PR PR
FORWARD V - SA - - SA SA SA
SAMEHOST V - SA - SA SA SA
SAMEUSER V - - - SU SU SU
SERVER V - SV - SV SV SV
AUTH V - AU - AU AU AU
AUTHTYPE S - AU - AU AU AU
AUTHUSER S - AU - AU AU AU
FWDUSER S - AU - AU AU AU
KEY:
JH = HOST host in control file
RH = REMOTEHOST connecting host name
JUSR = USER user in control file
CUSR = REMOTEUSER user from control request
JIP= IP IP address of host in control file
RIP= REMOTEIP IP address of requesting host
PORT= connecting host origination port
CONTROLLINE= pattern match of control line in control file
FW= IP of source of request = IP of host in control file
SA= IP of source of request = IP of host in control file
SU= user from request = user in control file
SA= IP of source of request = IP of server host
SV= matches if remote host is the server
AU= authentication information
IFIP= IP address of remote end of connection
Match: S = string with wild card, IP = IPaddress[/netmask],
N = low[-high] number range, V = exact value match
SERVICE: 'X' - Connection request; 'R' - lpr request from remote host;
'P' - print job in queue; 'Q' - lpq request, 'M' - lprm request;
'C' - lpc spool control request; 'S' - lpc spool status request
NOTE: when printing (P action), the remote and job check values
(i.e. - RUSR, JUSR) are identical.
The special key letter=patterns searches the control file
line starting with the (upper case) letter, and is usually
used with printing and spooling checks. For example,
C=A*,B* would check that the class information (i.e.- line
in the control file starting with C) had a value starting
with A or B.
PERMISSIONS, MULTIHOMED HOSTS, IPV6
There is a subtle problem with names and IP addresses which
are obtained for 'multi-homed hosts', i.e. - those with
multiple ethernet interfaces, and for IPV6 (IP Version 6),
in which a host can have multiple addresses, and for the
normal host which can have both a short name and a fully
qualified domain name. In addition, a host can have
multiple IP addresses, depending on the complexity of its
configuration.
The IFIP (interface IP) field can be used to check the IP
address of the origination of the request, as reported by
the information returned by the accept() system call. Note
that this information may be IPV4 or IPV6 information,
depending on the origination of the system. This
information is used by gethostbyaddr() to obtain the
orginating host fully qualified domain name (FQDN) and set
of IP addresses. Note that this FQDN will be for the
originating interface, and may not be the cannonical host
name. Some systems which use the Domain Name Server (DNS)
system may add the cannonical system name as an alias.
When performing an IP address match, the entire list of IP
addresses for a system will now be checked. If one of these
matches, then success is reported. Similarly, the entire
list of host names and aliases will be checked. If one of
these matches, then success will be reported.
In addition, when checking for printing, if the name lookup
for the host reported in the control file fails, then we
assume that the host is unknown and all match checks for
names or IP addresses will fail. You can determine if a
host has an entry by using the following check, which will
reject all requests from a remotehost which does not have a
DNS entry.
REJECT NOT REMOTEHOST=*
PRINTCAP DATABASE
Individual printer operations are controlled by values in
the printcap database. See printcap(5) for details of the
format and content of the various entries. The following
are typical printer entries for a local and remote printer.
# main or shared printcap file - usually /etc/printcap
# remote postscript printer
fullpage
|postscript
:lp=postscript@farside.astart.com
# give access to (remote) hosts
t1|postscript2
:cm=Test Printer 1
:lp=postscript2@nearside.astart.com
# local printcap file
# specification for local printer on nearside
t1|postscript2
:oh=nearside.astart.com
:cd=/usr/spool/LPD/safe
:sd=/usr/spool/LPD/t1
#
# /usr/spool/LPD/t1/printcap file -
t1:
:lp=/dev/pr
:if=/usr/lib/pr/if
:of=/usr/lib/pr/if
Printcap information can be distributed by individual files
or shared using NSF, YP, or other methods; see lpd.conf(5)
for the exact details of the location of printcap files and
programs, given by the printcap_path and lpd_printcap_path
configuration information. The a common printcap
configuration is to have a main (shared) printcap database
which is used by all hosts. The printcap information is
usually extremely simple, consisting only of the printer
name and host (i.e. - fullpage printer entry).
On hosts which have printers attached or which are to
provide spooling queue directories, more extensive printcap
information is needed. In the shared database, oh (options
for specified host only) field restricts use of this entry
to the specified host. This entry can contain host specific
information, such as the location of the spool queue and/or
actual device to be used for output.
In the above example, the main printcap file, usually
/etc/printcap, has entries for all printers. Note that
these entries do not specify the spool directories (sd and
cd fields), but this could be provided. On a host with a
printer specific information can be provided in serveral
ways. The simplest is to simply put an additional entry in
the shared printcap file, with the oh field set to the
support host name. An alternative would be to specify the
spool directories (sd and cd fields) in the shared
information, and to put the printer specific information in
a printcap file.
In addition to the oh flag, the server flag indicates that
this entry is for a the LPD server only. This can be used
to simplify the management of client and server entries.
The printcap information is obtained in the following order.
All programs use the contents of the configuration
printcap_path variable to get a list of locations of
printcap files. In addition, the lpd program appends the
contents of the lpd_printcap_path configuration information.
Next, each of these entries is processed, and the printcap
information is extracted. Entries which have oh fields are
only used by the specified host. The files and information
is processed in linear order, later entries overriding
preceeding ones.
When processing jobs or performing spool queue specific
requests, the LPD server will check to see if there is a
printcap file in the control directory for the spool queue
and the contents will be processed. Since only the LPD
server has access to the spool and control queues, this
information is processed only by the server.
In addition to files, printcap information can be obtained
from programs or filters. For example, the printcap_path of
the form /etc/printcap:|/usr/lib/getpr will use the contents
of the /etc/printcap file, and then use the /usr/lib/getpr
program to get information about a specific printer. When
information about a particular spool queue is needed and one
or more filters are specified as the source of printcap
information, then the filter will be started and the printer
name written on its standard input. The filter must provide
a printcap entry for the requested printer on its standard
output.
The filter can be used to interface to databases or
nonstandard information sources which do not produce
printcap information in an acceptible form.
SPOOL DIRECTORY CONTENTS
Each spool queue has a spool directory (sd) and optional
control directory (cd) where job and control information is
kept. Under normal operation the spool and control
directories are identical, but if the spool directory is NFS
exported for use by other printer spoolers which write files
directly into the spool queue, then it is recommended that
the control directory be a separate directory and not NFS
mounted. The following files are used for printer
operations. Per job entries are marked with an asterisk
(*).
File Name Dir Purpose
printer CD lock file and server process PID
unspooler.printer CD subserver process PID
control.printer CD queue control information
*hfAnnn SD job hold file
*cfAnnnHOST SD job control file
*dfAnnnHOST SD job data file
*bfAnnn.* SD tempory files
The nnn in the file names stands for the job number.
RFC1179 requires this to be a 3 digit number, but the
longnumber printcap flag or a nonzero longnumber
configuration variable will enable 6 digit numbers.
The lock file is used to prevent multiple job queue servers
from becoming active simultaneously, and to store the server
process id. The lock file name is the name as the printer
name; all other control files have the printer name appended
as indicated above.
The printer spool control file contains information
controlling the queue operations. It consists of a series
of lines with keywords and values to control printing,
spooling, and automatic job holding operations. The
following is an example of a typical spool control file.
spooling_disabled 0
printing_disabled 1
holdall 0
redirect p1@host2
debug 10,log=/tmp/log
class A
The spooling_disabled and printing_disabled entries control
spooling and printing; the lpc enable, disable, start, and
stop command alter these values. The holdall entry will
prevent jobs from being processed until released with the
lpc hold or release comands; the lpc holdall and noholdall
commands alter these values.
The redirect entry causes the lpd server to forward jobs to
the specified remote printer; the lpc redirect command
alters this field. The class field controls the class of
jobs being printed. By default, the class value is a
pattern that matches the class entry in a job file; however
a entry of the form letter=patterns will print jobs whose
control file line starting with letter matches one of the
patterns. The debug line provides a set of debugging
parameters for diagnostic information for the particular
spool queue.
Each print job consists of a control file and one or more
data files. Lines in the control file file specify the job
data files or parameters for the job and the general format
of the file is specified by RFC1179. Each line consists of
a flag character and a parameter; upper case and digit
characters specify options and lower case letters specify
the printing format and names of data files. The following
is a list of the control file flag characters.
A Identifier A job identifier to be used when displaying
job information and/or status. The insertion of this
line is controlled by the use_identifier
printcap/configuration variable.
C Class String to be used for the class line on the burst
page.
H Host Name. Name of the machine where lpr was invoked.
I Indent. The number of characters to indent the output
by (in ascii).
J Job Name. String to be used for the job name on the
burst page.
L Banner user name. Information for banner page.
P Person. Login name of the person who invoked lpr.
This is used to verify ownership by lprm.
M Send mail to the specified user when the current print
job completes.
N File name. The original name of a data file which is
in the job.
T Title. String to be used as the title for pr(1) when
the LPR -p option was specified.
U Unlink. Job file to remove when printing completed.
W Width. The page width (in characters) to used for
printing.
Z zoptions. Options passed by lpr -Zzoptions. These are
passed to output filters to aid in printing.
f Formatted File. Name of a file to print which is
already formatted.
l Like ``f'' but passes control characters and does not
make page breaks.
p Name of a file to print using pr(1) as a filter.
t Troff File. The file contains troff(1) output (cat
phototypesetter commands).
d DVI File. The file contains Tex(l) output (DVI format
from Stanford).
g Graph File. The file contains data produced by
plot(3X).
c Cifplot File. The file contains data produced by
cifplot.
v The file contains a raster image.
r The file contains text data with FORTRAN carriage
control characters.
1 Troff Font R. Name of the font file to use instead of
the default. (Obsolete)
2 Troff Font I. Name of the font file to use instead of
the default. (Obsolete)
3 Troff Font B. Name of the font file to use instead of
the default. (Obsolete)
4 Troff Font S. Name of the font file to use instead of
the default. (Obsolete)
Each job in the spool queue can have an associated job hold
file which is used by the server process to control the
printing of the job. The status file contains information
controlling the job hold status and error status. The spool
server will attempt to print a job a limited number of times
before abandoning it or setting an error status in the job
status file. The following is a typical job hold file.
hold 0 priority 0 active 2135 redirect
remove 0 error
A nonzero hold entry will prevent the job from being
processed; the lpc hold and release commands update this
field. The priority field overrides the normal first-in
first-out printing priority; jobs with non-zero priority
fields are printed first. The lpc topq command updates this
field. If the active field is non-zero, the job is being
printed by the server with the specified process id. The
redirect field allows individual jobs to be forwarded to a
different printer; the lpc move command updates this field.
Finally, the remove and error fields are used to control
printing of problem jobs. The remove field is set when a
job should be removed; the error field records information
that would prevent a job from being printed.
JOB SUBMISSION
The LPR program is used to submit a job to the LPRng system.
The LPR program opens a connection to the LPD server and
then transfer the job control file and data files. The LPD
server checks to see if the remote host and user has
permissions to spool to the requested printer, and then
checks to see if the printer is accepting jobs. If both
conditions are met, the job is accepted and the control and
data files are placed int the spool directory. The LPRng
software sends the control file first, followed by the data
files.
If the LPR program is acting as a filter, it is not
necessary to temporarily store the print job on the local
machine. The input data can be sent directly to the LPD
server for spooling using an implicit job size of 0 and
sending data until the connection is terminated to the
server. However, some LPD servers do not accept 0 size
jobs, even though it is specified by the RFC1179, so by
default LPR will create a temporary file. The LPR -k
(seKure) option specifies this direct transmission mode be
used.
JOB TRANSMISSION
When LPR is to send a job to the server, it must determine
the location of the server. It does this by examining the
values of the specified printer and host.
If the printer and host are explicitly specified in the form
pr@host then the LPR program will send the job to the
specified spool queue pr and to the server running on host.
This can be explicitly specified by the PRINTER environment
variable or by the LPR -P option.
If the printer is specified only by a name, then the
information in the printcap database is used. The printcap
entry for the printer is searched for and the remote host
and printer information extracted. The job is sent to the
server running on the specified host.
This action can be modified by the following printcap or
configuration tags.
1. (Configuration) If there is no printcap entry for the
printer, the job is sent to the LPD server running on
host.
2. (Configuration or printcap) If this flag is specified,
then LPR and other client programs will send the job to
the server running on the localhost. This overrides
the default_host information.
FORWARDING OPERATIONS
The LPD system can forward jobs from one spool directory to
another. This is controlled by the following options.
1. The forward field in the spool control file has a value
rp@rm. This can be set using the LPC forward command.
2. The lp (line printer) printcap entry has the form
rp@rm. There is a rm (remote machine) and optional rp
(remote printer) printcap entry.
The first of the above conditions to be met will determine
the destination. If printing is enabled, then jobs will be
forwarded to the remote destination. Example:
# using lp=rp@host
test:sd=/usr/spool/test
:lp=test@host
test:sd=/usr/spool/test
:lp=test@host%port
# using :rp:rm:
test:sd=/usr/spool/test
:rp=test:rm=host
3.
The LPD server uses the same algorithm for sending jobs as the
LPR program.
A connection is made to the remote server and the files are copied
to the server.
A set of timeouts is used to control error recover and retry operations.
The printcap and configuration variables
connect_timeout,
connect_interval,
connect_grace,
and
send_try
control connecting to the remote host.
A connection is attempted to the remote server from a
random port in the range of ports specified by the
originate_port
variable.
If a connection is not completed within
connect_timeout
seconds,
the connection is aborted,
and then after the
connect_interval
seconds it is retried.
The procedure repeated
indefinately for printing,
but only once for status or control operations.
A
connect_timeout value of 0 indicates no timeout;
a value of 0 specifies infinite timeout
After a job has been successfully printed,
the connection is closed and the server waits for
connect_grace
seconds before trying to reconnect.
BOUNCE QUEUES
A bounce queue is a special queue that allows jobs to be
passed through various filters before being sent to an final
destination. The lp entry must specify the bounce queue
name on the server. This will force all jobs to be passed
to the bounce queue for processing. The bq field must
specify the final destination for jobs after filtering.
Data files are passed through the appropriate format filter
before transfer to the destination. If there is no format
filter, then no processing is done and the original file is
transferred. See PRINTING OPERATIONS for details about
filters. For example, the following printcap entry will
filter format f files.
testbq:sd=/usr/spool/testbq:
:lp=testbq@host:bq=final@host
:if=/usr/lib/filter_for_f
:mf=/usr/lib/filter_for_m
:pf=/usr/lib/filter_for_pr
:translate_format=mfpf
When using a bounce queue, it is usually desirable to have
the filters actually change the format types of the job as
well as processing the data. This conversion can be forced
using the printcap translate_format entry. This entry
consists of pairs of lower case characters of the form
SdSd...; S is the original and d is the translated format.
In the example above, the m format is processed by a filter,
and then its format type is changed to f; the p format is
processed similarly. Note that the lpr -p option specifies
that the job will be processed by the /bin/pr command - the
filter must do both the pr processing and any necessary
format conversions.
LPR FILTER PROCESSING
The :lpr_bounce: printcap flag will cause LPR to do bounce
queue filtering before sending the job to the remote queue.
This can have unexpected effects if the filters are not
available on the local host.
A typical entry which will cause LPR to do filtering is
shown below.
testbq:lpr_bounce
:lp=printer@host
:if=/usr/lib/filter_for_f
:vf=/usr/lib/filter_for_v
:mf=/usr/lib/filter_for_m
:translate_format=mfvf
This entry will force LPR to run jobs with formats f, m, and v
through the appropriate filter.
It will also rename the formats to the f format.
ROUTING JOBS TO PRINTERS
When a job is submitted for printing, sometimes it is
desirable to have it dynamically rerouted to another spool
queue, or multiple copies send to various destination. This
can be done by using a routing_filter.
When a job is accepted by the LPD server, part of the
processing includes passing it to a program specified by the
printcap router entry. This filter is invoked with the
original control file as STDIN, and the default set of
filter options. The output of the routing filter will be a
set of directives used by LPD when forwarding the job to
another printer or in processing the job. The environment
and options flags are set as for a standard filter. (See
"FILTERS" for details.) Here is a sample printcap entry:
t2|Test Printer 2:sd=/var/spool/LPD/t2
:lf=log
:lp=t2@printserver
:bq=t1@localhost
:destinations=t1@localhost,t2@localhost
:router=/usr/local/LPD/router
The routing filter exit status is used as follows:
0 (JSUCC) - normal processing
37 (JHOLD) - job is held
any other value - job is deleted from queue
The router filter returns one or more routing entries with
the following format. Note that entry order is not
important, but each entry will end with the 'end' tag. dest
<destination queue> copies <number of copies to be made>
X<controlfile modifications> end
Example of router output:
dest t1@localhost
copies 2
CA
end
dest t2@localhost
CZ
end
The above routing information will have copies of the job sent to
the t1 and t2 spool queue servers. If no valid routing information
is returned by the router filter the job will be sent to the default
bounce queue destination.
REFORMATING CONTROL FILES
Sometimes it is desirable to reformat a control file before
sending to a remote destination. If the control_filter
printcap entry is present, then the control file is passed
through the filter. If the filter exits with status JSUCC,
then the job is process normally; status JABORT causes the
job processing to be aborted, status JREMOVE causes the job
processing to be removed, and any other status is treated as
JFAIL.
After passing the control file through the control_filter,
the LPD server will reread it, and transfer only the data
files specified in the new control file to the destination.
SPOOL QUEUE NAME OPTION
The qq printcap entry and the use_queuename configuration
entry causes the name of the spool queue to be placed in the
job control file. This value can be used by the filter to
determine how to process a job. When combined with the use
of the Bounce Queue, this can be used to reformat jobs
before sending to another printer spooler system.
PRINTING OPERATIONS
When printing is enabled, the LPD server will create a spool
server process to carry out printing operations. For each
job in the queue, the spool server process will create a
subserver process to carry out the actual printing
operations. If the subserver process fails, the server
process will initiate recovery operations. Job will be
attempted to be printed until all are done or a subserver
returns an ABORT indication; the server will then terminate
operations.
The server process normally scans the queue once, at
initiation; if the spool control file is modified, usually
by using the lpc command, the spool queue is rescanned. The
overall algorithm for job printing is:
open the print device;
send some initialization strings;
send a banner to the device;
send the job data files to the device;
send some termination strings;
close the print device;
In order to handle the various device requirements, the
subserver process in turn uses 'filter' programs specified
in the printcap entry to carry out the individual steps.
OF Filter
The 'of' filter is used for initialization, banner
printing and the termination strings. It has the
peculiar property of suspending itself when sent a
special escape string, allowing other filters to be
used to print the individual job files.
Data Filters
Each data file in a job has format specified by a lower
case character and an associated filter specified in
the printcap file. For example, the 'g' format is
printed by the 'gf' filter, and so forth. By
convention, the 'if' filter is used to print 'f'
(ordinary text) and 'l' (binary) format jobs.
lp-pipe Filters
If the printcap device specification has the form
|program then the output device is accessed by the
specified program. This allows the program to take
care of any required initialization or communication
requirements.
The following is a concise summary of the actual algorithm
used to print files. Note that LP stands for the printer
device or filter specified by the 'lp' printcap entry; OF
stands for the 'of' printcap filter; IF is the default 'if'
filter; BP is the banner printing filter; and ?F stands for
the filter for data file. The '??' values stand for entries
from the printcap file.
LP = open( 'lp' ); // open device, filter, or network connection
OF = IF = LP; // set defaults
set up accounting according to 'af' entry;
if( 'of' ) OF = filter( 'of' ) -> LP;// make OF filter
if 'as' then record start of job accounting information.
if 'achk' then check for accounting limits.
if( leader on open 'ld' ) `ld` -> OF// send leader
if( FF on open 'fo' ) `fo` -> OF // send leader
// print a banner
// first check to see if required
// and then to see if not suppressed by printcap
// or by user
do_banner =
(always banner 'ab'
|| (!suppress banner 'sb' && job has banner ));
if( ! header last 'hl' && do_banner ){
if( banner program 'bp' ){
fork and exec bp to generate banner, but into temp file.
cat temp file -> OF;
} else {
short banner info -> OF;
}
}
// now we suspend the OF filter, use other filters
if( OF != LP ) suspend OF filter;
for each data file df in job do
// send FF between files of job
if( !first job && ! no FF separator 'sf' ){
if( OF != LP ) wake up OF filter;
'ff' -> OF;
if( OF != LP ) suspend OF filter;
}
// get filter for job
format = jobformat;
if( jobformat == 'f' or jobformat = 'l' ){
format = 'f';
}
filter = check pc for filter for format;
?F = LP; // default - no filter
if( filter ){
?F = filter( filter ) -> LP;
}
data file -> ?F;
// note: if :direct_read: flag set, filter input
// is directly from the file, otherwise the
// file contents are written to the filter input.
if( ?F != LP ) close( ?F )
endfor
// finish printing
if( OF != LP ) wake up OF filter;
if( header last 'hl' && do_banner ){
if( ! no FF separator 'sf' ){
'ff' -> OF;
}
if( banner program 'bp' ){
fork and exec bp to generate banner, but into temp file.
cat temp file -> OF;
} else {
short banner info -> OF;
}
}
if( ff on close 'fq' ){
'ff' -> OF;
}
if( trailer on close 'tr' ){
tr -> OF;
}
if 'ae' then record end of job accounting information.
if( OF != LP ) close( OF );
close( LP );
When printing or transferring a job to a spool queue fails,
it is retried the number of times specified by the rt (or
send_try ) printcap variable. A 0 value specifies an
infinite number or retries. When the retry count is
exceeded, then the send_failure_action printcap variable
determines the action to be taken. The variable can be the
values succ , fail , abort , remove , ignore , or hold ,
which will cause the job to be treated as normally
completed, retried, aborted, removed, or ignored and retried
at a later time respectively. These names correspond to the
JSUCC , JFAIL , etc. error codes returned by filters. If
the variable has the form |/filter , then the filter is run
and passed the number of attempts on the standard input.
The filter must exits with a JSUCC, JFAIL, etc., error code
and the server will take the appropriate action as listed
above.
The print filters normally have their input provided by a
process via a pipe. However, if the direct_read printcap
flag is set, then the filter input is taken directly from
the job file. This is compatible with the vintage BSD
method, but loses the ability to track the job progress.
After the job print or transfer attempt, if the job is to be
removed and the printcap variable save_on_error is true, the
job will not be removed from the spool queue but only
flagged with an error. The job can then be retried at a
later time. If the job is successfully printed it is
usually removed from the spool queue. However, if the
printcap variable save_when_done is true the job will merely
be marked as completed and not removed from the queue.
FILTERS
As described in the previous section, filters are created to
handle output to devices or other filters. The command line
to invoke a filter is generated in the following manner.
1. The printcap entry or configuration value defining the
filter command is obtained.
2. The file to be printed or the banner line/file
generated by the banner printer will be written to
STDIN (file descriptor 0) of the filter. The output
device (or /dev/null if this is not a printing filter)
will be be STDOUT (file descriptor 1) and STDERR (file
descriptor 2) will be connected to the error logging
file. If this is a printing filter, the error log will
be determined by the :af: printcap field. If
accounting is enabled, file descriptor 3 will be
connected to be the accounting file or filter as
specified by the printcap :af: entry.
3. If the ROOT_PERMS_TO_FILTER_SECURITY_LOOPHOLE compile
time option is enabled, then filter specifications
starting with ROOT filtername will be run as root (EUID
= 0). This can be a serious security loophole, and
should only be used as a last resort for specific
problems.
4. The options for the filter command line will be
replaced by appropriate values. Option specifications
have the form $[0| ][-][']X. The default option
expansion has the form $X -> -X'value'; the form $0X or
$(space)X adds a space after the -X, i.e.- $0X -> -X
'value'; the form $-X suppresses the -X, i.e. - $-X ->
'value'; and the form $'X' suppresses the quotes around
the value. Note that the 0,-, and ' can be combined.
For example, $-'X -> value. The options will be
exanded as follows:
Key Value
a Accounting file (printcap 'af')
b Job size, i.e.- total data file size, in bytes
c if binary (format 'l') expands to -c
d Control directory
e job data file
f original print file name (control file N field)
h Control file hostname
i Control file indent (I) field
j job number from control file name
k Control file name
l printcap Page length (pl) value
m printcap Cost factor (co) value
n Control file user logname (P) field
p Remote Printer name for forwarded jobs
r Remote Host name for forwarded jobs
s printer Status file (ps) value
t current time in simple format
w printcap Page width (pw) value
x printcap x dimension (px) value
y printcap y dimension (py) value
F data file format character
P Printer name
S printcap Comment tag (cm) value
Upper Case control file line starting with letter
Digit control file line starting with digit
5. The options specified by the filter_options (for none
OF filters) or of_filter_options (for the OF filter)
will be appended to the command line and expanded. To
suppress adding options, you can use the form '-$
filter', i.e. - of=-$/bin/cat. If the 'bkf' (backwards
compatible filter options) printcap flag is set, the of
filter is given the options specified by
bk_of_filter_options and other filters those by
bk_filter_options. The following shows the various
combinations possible, and typical values for the
options.
Options
filter_options $C $F $H $J $L $P $Q $R $Z $a $c $d $e $f $h $i \
$j $k $l $n $s $w $x $y $-a
bk_filter_options $P $w $l $x $y $F $c $L $i $J $C $0n $0h $-a
bk_of_filter_options $w $l $x $y
6. A printing filter which executes correctly and completely should
exit with a 0 error status.
A nonzero error status will be interpreted as follows:
JFAIL 32 failed - retry later
JABORT 33 aborted - do not try again, but keep job
JREMOVE 34 failed - remove job
The JFAIL will cause the job to be retried at a later time.
A limit can be placed on the number of retries using the
:rt: or :send_try: printcap entry. A retry value of 0 will
cause infinite retries. The JABORT indicates serious
problems and will cause printing operations on the job to
stop until restarted by operator intervention. The JREMOVE
status indicates problems, and the job should be removed
from the spool queue.
The environment variables for filters are highly restricted,
due to the possibility for abuse by users. The following
variables are set:
USER and LOGNAME
user name or daemon name.
LOGDIR
home directory of user or daemon.
PATH from the filter_path configuration variable.
LD_LIBRARY_PATH
from the filter_ld_path configuration variable.
SHELL
set to /bin/sh
IFS set to blank and tab.
TZ the TZ environment variable.
SPOOL_DIR
the spool directory for the printer
CONTROL_DIR
the control directory for the printer
PRINTCAP_ENTRY
the printcap entry for the printer
CONTROL
the control file for the print job
pass_env environment variables
Values of environment variables listed in the pass_env
configuration variable.
ACCOUNTING
The LPRng software provides several methods of performing
accounting. The printcap af (accounting field), as and ae
(accounting start and end), and achk (accounting check)
provide a basic set of facilities. The af field specifies a
file, filter, or TCP network connection to an accounting
server. If af has the form |filter or |-$ filter then a
filter will be started and all accounting information will
be sent to the filter. The first form passes the filter the
command line options specified by the filter_options
configuration variable and the second suppresses option
passing. If af has the form host%port then a TCP connection
will be opened to the port on the specified host and
accounting information sent there. All other forms will be
treated as a pathname relative to the queue spool directory.
If af specifies a file, then the accounting information is
appended to an existing file; the accounting file will not
be created.
When af specifies a filter or network connection and the
achk flag is set, then after writting the initial accounting
information (see as printcap field below) the server will
wait for a reply of the form ACCEPT from the filter or
server. If not received, the job will not be printed.
The as (accounting start) and ae (accounting end) fields can
specify a string to be printed or a filter. Options in the
string will be expanded as for filters, and the strings
printed to either the accounting information destination.
If the as field specifies a filter, then the print server
will wait for the filter to exit before printing the job.
If the exit status is 0 (successful), the job will be
printed. A non-zero JREMOVE status will remove the job,
while any other status will terminate queue printing
operations. After printing the job, the ae filter will be
started and the server will wait for it to complete before
printing the next job.
The as and ae filters will have STDOUT set to the printing
device and or filter, and the STDERR set to the error log
file for the print queue, and fild descriptor 3 set to the
destination specified by the af field.
As a convenience, all format filters for printing will be
started with file descriptor 3 set to the destination (file
or filter) specified by the printcap af field. This allows
special filters which can query devices for page counts to
pass their information directly to an accounting program.
The descriptor will READ/WRITE, allowing filters to query
the accounting program and/or update the information
directly.
LOGGING INFORMATION
In order to provide a centrallized method to track job
status and information, the printcap/configurtion variable
logger_destination enable the send of status and other
information to a remote destination. The logger_destination
value has the form
host[%port][,protocol]
Examples:
taco%451,UDP
dickory%2001,TCP
where host is the host name or IP address, port is an
optional port number, and protocol is an optional protocol
type such as UDP or TCP. The configuration variables
default_logger_port and default_logger_protocol can be used
to override the default port number (2001) and protocol
(UDP) to be used if none is specified. Logging information
has the format below.
IDENTIFIER jobid [PRINTER name] at timestamp \
STATUS | TRACE | FILTER_STATUS PID nnn
[ status information]
The status information format consists of an identifier
line, followed by a specifier of the status type. The
logging information entry is terminated by a line with a
single period on it. Lines with a starting period have the
period duplicated.
AUTHENTICATION
Rather than building authentication facilties into LPRng, an
interface to authentication programs is defined, and will be
used as follows. The printcap and configuration entries
use_auth, default_auth, forward_auth, user_auth_command,
server_auth_command, server_user, and remote_user entries
control authentication. The use_auth value specifies the
type of authentication to be used for client to server
authentication. The default_auth is the use_auth value to
be used if explicitly requested by a user, i.e. - the lpr,
lpc, lprm, and lpq -A (use authentication) option. Typical
values would be pgp, kerberos, etc. The client programs use
the user_auth_command executable to perform authentication.
When a server gets and an authentication request, it will
use the server_auth_command to do authentication. The
server_user is the remote server name used when a client is
sending jobs to the server or when the server is originating
a request. When a server forwards a request, it uses the
forward_auth value to determine if authentication is to be
done, and the remote_user as the destination server
identification.
Client To Server Authentication
1. The client will open a connection to the server and
sends a command with the following format. The
REQ_SECURE field in the command corresponds to the one-
byte command type used by the LPR protocol.
Commands:
\REQ_SECUREprinter C user\n
Print job transfers:
\REQ_SECUREprinter C user controfilename\n
2. On reception of this command, the server will send a
one byte success code as below. An error code may be
followed by additional error information. The values
used by LPRng include:
ACK_SUCCESS 0 success, no error
ACK_STOP_Q 1 failed; no spooling to the remote queue
ACK_RETRY 2 failed; retry later
ACK_FAIL 3 failed; job rejected, no retry
3. If there is an error the connection will be terminated.
The server will then start an authentication process,
and provide the following open file descriptors for it.
The authenticator process will run as the UID of the
server (i.e.- usually daemon).
FD Options Purpose
0 R/W socket connection to remote host (R/W)
1 W pipe or file descriptor
for information for server
2 W error log
3 R pipe or file descriptor
for responses to client
The command line arguments will have the form:
program -S -Pprinter -nuser -Rserver_user -Ttempfile
The printer and user information will be obtained from
the command line sent to the server. The authenticator
can create additional temporary or working files with
the pathnames tempfile.ext; these should be deleted
after the authentication process has been completed.
4. After receiving \ACK_SUCCESS, the client starts an
authenticator process, and provides the following open
file descriptors for it. The authenticator process will
run UID user.
FD Options Purpose
0 R/W socket connection to remote host (R/W)
1 W pipe or file descriptor
for responses to client
2 W error log
The command line arguments will have the form:
program -C -Pprinter -nuser -Rserver_user -Ttempfile
5. The authenticator can create additional temporary or
working files with the pathnames tempfile.ext; these
will be deleted after the authentication process has
been completed. The client authenticator will be
running as the client user.
6. After exchanging authentication information, the client
authenticator will transfer the contents of the
temporary file to the server authenticator, using FD 0.
It will then wait for reply status on FD 0. If the
transfer step fails, or there is no reply status of the
correct format, the client authenticator will print any
recieved information on FD 1, error information on FD 2,
and then exit with error code JFAIL.
7. After receiving the files on FD 0, the server
authenticator will perform the required authentication
procedures and leave the results in tempfile. The
server authentictor will write the following to FD 1,
for use by the server:
authentication_info\n
If the transfer step or authentication fails, then the
server will write an error message to FD 2 and exit with
error code JFAIL. The server will use this
authentication information to determine if the remote
user has permission to access the system.
8. The server authentication process will read input from
FD 3 until and end of file, and then proceed to transfer
the input to the client authenticator. If the data
transfer fails, then the process will exit with error
code JFAIL, otherwise it will exit with error code
JSUCC.
9. The client authenticator will read the status
information from FD 0, and after performing
authentication will write it to FD 1. If data transfer
or authentication fails, the authenticator will write
an error message to FD 2 and exit with error code JFAIL,
otherwise it will exit with error code JSUCC.
Server to Server Authentication
The Server to Server authentication procedure is used by one
server to forward jobs or commands to another server. It
should be noted that this forwarding operation puts an
implicit trust in the security of the client to server to
server chain. In the description below, src and dst are the
userid of the source and destination servers respectively.
1. The originating host takes the part of the client, and
will transfer a job acting like the client. The initial
information transfer from the originating (src) server
will have the format:
Commands:
\REQ_SECUREprinter F user\n
Print job transfers:
\REQ_SECUREprinter F user controfilename\n
After receiving a 0 acknowlegement byte, the src server
will invoke its authenticator with the arguments below.
The forward_user value will default to the server_user
value if not explicitly provided.
program -C -Pprinter -nserver_user \
-Rforward_user -Ttempfile
2. On the destintation server the authenticator is invoked
with the arguments:
program -S -Pprinter -nserver_user \
-Rforward_user -Ttempfile
The authentication is performed to determine that the
transfer was between the two servers, rather than the
user to server.
KERBEROS AUTHENTICATION
As a convenience, Kerberos 5 authentication has been built
into the LPD clients and servers. If you are not familiar
with Kerberos, then you should obtain other documentation
and/or assistance before attempting to use this. The
following facilities/configuration values are used to
support Kerberos.
A Kerberos principal is the name used for authentication
purposes by Kerberos. For example, user principals have the
form user@REALM; for example, papowell@ASTART.COM. Services
and/or servers have the form service/host@REALM; for
example, the lpd server on dickory would have the form:
lpr/astart2.astart.com@ASTART.COM
User to server authenticaiton process will use the user's
principal name, and generate a service name for the server.
The name generation is controlled by the following
configuration and/or printcap values.
service
The name of the service to be used to identify the
service. This is usually "lpr".
kerberos_keytab
The location of the server keytab file. The keytab
file corresponds to the user password, and must be
considered a security risk. It should be owned by the
LPD server user, and readable/writable only by the
server.
kerberos_life
The lifetime of the authentication ticket used by the
server. This usually defaults to 10 hours.
kerberos_renew
The renewal time of the ticket.
In addition to the default values, an explicit server
principal can be specified in the printcap file using the
kerberos_server_principal This allows cross domain
authentication to be done.
When setting up Kerberos authentication, you will need to
establish principals for each server, and to distribute and
install the keytab files on each server.
AUTHENTICATION PERMISSIONS
The following permissions tags are available to check on
authentication procedures.
AUTH=[NONE,USER,FWD] - authentication
AUTH=NONE - no authentication
AUTH=USER - authentication from a client
AUTH=FWD - forwarded authentication from a lpd server
AUTHTYPE=globmatch
AUTHUSER=globmatch
FWDUSER=globmatch
1. The AUTH tag can be used to determine the type of
authentication being done. The AUTHTYPE tag can be used
to match the authentication type being used or requested
by the client or remote server. The authentication
process returns an authentication identifier for the
user; this information can be matched by the AUTHUSER
tag.
2. For a command sent from a client or forwarded from a
server, AUTHUSER matches the auth_user_id provided for
the user when sent to a server. (This information will
be forwared by a remote server). For a forwarded
command, FWDUSER refers to the authentication
information for the server doing the forwarding.
3. For example, to reject non-authenticated operations,
the following line could be put in the permissions file.
REJECT AUTH=NONE
4. To reject server forwarded authentication as well, we
use REJECT AUTH=NONE,FWD. If a remote server with name
serverhost has id information FFEDBEEFDEAF, then the
following will accept only forwarded jobs from this
server.
ACCEPT FWDUSER=FFEDBEEFDEAF REMOTEHOST=serverhost
REJECT AUTH=FWD
FILES
The files used by LPRng are set by values in the printer
configuration file. The following are a commonly used set
of default values.
/etc/lpd.conf LPRng configuration file
/etc/printcap printer description file
/etc/lpd.perms printer permissions
/var/spool/printer* spool directories
/var/spool/printer*/printcap printer specific printcap information
/var/spool/printer*/printer lock file for queue control
/var/spool/printer*/control.printer queue control
/var/spool/printer*/active.printer active job
/var/spool/printer*/log.printer log file
SEE ALSO
lpd.conf(5), lpc(8), lpd(8), lpr(1), lpq(1), lprm(1),
printcap(5), lpd.perms(5), pr(1).
DIAGNOSTICS
Most of the diagnostics are self explanatory.
If you are puzzled over the exact cause of failure,
set the debugging level on (-D5) and run again.
The debugging information will
help you to pinpoint the exact cause of failure.
HISTORY
LPRng is a enhanced printer spooler system with
functionality similar to the Berkeley LPR software. In 1988
Patrick Powell released the PLP (Public Line Printer)
software, which went through several evolutions. Justin
Mason (jmason@iona.ie) generated PLP4.0 from several older
releases of PLP. In 1992 Patrick Powell release LPRng, a
completely redesigned and newly written version of the
software.
The LPRng mailing list is plp@iona.ie; subscribe by sending
mail to plp-request@iona.ie with the word subscribe in the
body. The software is available from
ftp://iona.ie/pub/LPRng.
LPRng is distributed under the GNU software license for
non-commercial use, the Artistic License for limited
commercial use. Commerical support and licensing is
available through Patrick Powell <papowell@astart.com>.