                         LPRng - An Enhanced Printer Spooler
                          Introduction and Reference Manual
                              Version 3.1, Jan. 1, 1997
                         Patrick Powell <papowell@sdsu.edu>

                                      ABSTRACT
                  The  LPRng  software  is an enhanced, extended, and
               portable version of the Berkeley LPR software.   While
               providing  the  same general functionality, the imple-
               mentation is completely new and provides  support  for
               the  following  features:  lightweight  (no  databases
               needed) lpr, lpc, and lprm programs; dynamic  redirec-
               tion  of  print  queues; automatic job holding; highly
               verbose diagnostics; multiple printers serving a  sin-
               gle  queue;  client  programs  do not need to run SUID
               root; greatly enhanced security checks; and a  greatly
               improved permission and authorization mechanism.

                                    Introduction
             Print  spooler  software is one of the most common and heavily
          used system application programs.  While printing may  appear  to
          be  simple  on  the surface, in practice it is complicated by the
          following problems.  Each model of printer has a peculiar set  of
          interface  and  format  requirements; this means that the printer
          software must be highly  configurable  at  the  device  interface
          level.   Next, multiple users may want to share the same printer;
          this leads to the need for a spooling system with the  associated
          problems  of  priority  and fair use.  Printers are notorious for
          failing at the most  inopportune  times;  the  spooling  software
          needs  to report failures and to reconfigure or repair the system
          in a simple manner.  Finally, the software should be portable  so
          that  the  same  software  can be used on different systems; in a
          network based system this introduces the problems of security and
          authentication.
             The  LPRng Printer Spooling[Pow95] software is a descendant of
          the 4.3 BSD Line Printer Spooler Software (LPR),[Cam94]  but  has
          totally  redesigned  and reimplemented.  The evolution started in
          1986 at the University of Waterloo, where the original 4.3  soft-
          ware  was  modified to support a variety of new printers.  Due to
          restrictions with the original AT&T and Berkeley software license
          these  modifications  could  not  be  distributed.   The problems
          encountered during this process led to the development of the PLP
          (Public  Line  Printer)  software[Pow95a]  and  PLP  Version  3.0
          (PLP3.0) was released in 1988.  The PLP software architecture was
          based on the the original LPR code, but with highly verbose diag-
          nostics and a much more elaborate  set  of  administration  func-
          tions.
             From  1988  to  1994 various sites and administrators modified
          and extended the PLP3.0 software.  The plp@iona.ie  mailing  list
          was  formed  to  distribute  and coordinate these changes, and in
          1994 a major programming effort by Justin Mason  <jmason@iona.ie>
          restructured  the  PLP3.0 code, integrated the majority of exten-
          sions, and PLP4.0 was released in 1995.
             Problems  with  the  PLP  software  were  discussed   in   the
          plp@iona.ie  mailing  list  as well as various USENIX newsgroups.
          Given the current network security  issues,  client/server  based
          applications,  and  growing  administration  problems, the PLP4.0
          software needed extensive revisions.  There was general agreement
          on the following design goals.


          LPRng - Introduction                                            1









             First,  run time diagnostics and detailed error reporting were
          essential and should be  the  highest  priority.   When  problems
          occur  users and administrators must quickly diagnose the causes,
          and obtaining information is essential.  Next, the user interface
          to  the  printing facilities should change as little as possible.
          This would allow a gradual evolution from LPR and PLP to the  new
          software  with as least surprises to the users as possible.  How-
          ever,  the  administrative  interface  could  change,  and   many
          improvements  and  changes were suggested.  It was essential that
          the new software be compatible at  the  network  interface  level
          with  other  implementations of the LPR spooling software.  While
          in 1990 the RFC1179 - Line Printer Daemon  Protocol[McL90]  docu-
          menting  the  network  protocol to be used to transfer print jobs
          and status information between line printer spooling programs was
          published, many of the existing implementations do not conform to
          RFC1179 or have made extensions to the RFC.  The existing LPR and
          PLP  software uses a set of filter programs to interface to vari-
          ous printers.  A major concern of administrators was  that  these
          vintage  filter  programs should be usable with the new software.
          Finally, the long list of security, administration, and  network-
          ing problems should be eliminated if at all possible.
             These  considerations led to the design and development of the
          LPRng software.  While it is a totally new design and implementa-
          tion of spooling software, it uses routines and support code from
          the Free Software Foundation  GNU  Project,  and  is  distributed
          under  the  GNU  Copyleft  License.[GNU91] The LPRng software was
          intentionally designed to use as few non-portable or non-standard
          Operating  System  facilities  as  possible,  or to use them in a
          highly controlled and portable manner.  The use of the GNU utili-
          ties  such  as autoconf and Gnumake allow operating system depen-
          dent versions of various support routines to be selected at  com-
          pile time in an automatic manner.
             Since  the  original  release of LPRng in 1994, there has been
          growing use of it for commercial and other business applications.
          The  Artisitic  license meets the needs of most end users; a com-
          mercial license and support is available for users  and  institu-
          tions  that  require it.  In addition to the original goals, Ver-
          sion 3.1 of LPRng now provide the following capabilities:
          o  Unique identification of user jobs.
          o  Long job numbers (up to 6 digits long), which avoids  problems
             when  spooling a large number of jobs to a single spool queue.
          o  Dynamic redirection and routing of jobs.  A  spool  queue  can
             now  duplication  and  redirect  a  job  to  one or more spool
             queues.  This allows dynamic routing of  jobs  based  on  load
             conditions and other considerations.
          o  Authenticated  job  and  command  transfers  between users and
             servers.  The original LPR protocol as defined in RFC1179  has
             been  extended  to  provide  for  authentication.   The actual
             authentication is  separate  from  LPRng,  which  provides  an
             interface  and  specification for its use.  Currently, PGP and
             Kerberos authentication is supported.
             The following sections discuss the overall architecture of the
          LPRng  software,  and  then  deal with the major components.  The
          emphasis of  this  discussion  are  the  added  functionality  or


          2                                            LPRng - Introduction









          differences  of  LPRng.   The  LPRng  configuration  information,
          extensions to the printcap database, and changes to the  lpr  and
          other  client  programs  is  discussed.  The operation of the job
          spool queues and the new algorithm used for job printing is  then
          covered,  together  with  a  description  of the filter interface
          mechanism.  Security and associated  problems  with  SETUID  ROOT
          programs  is  briefly discussed, and the summary at the end lists
          some outstanding issues.

                             LPRng Software Architecture
             The LPRng software architecture is shown in Figure 1.
















          ------------------------------------------------------------------
                    LPRM    LPQ       LPC               t2 server
                                                          (LPD)   Filters
                      +++    +       +++++                      ++
                         +++++  +++++     +++++                  ++
                                                                  +
                  LPR  +++  LPD  +++++++++++++  LPD               +of
                                                                  +
                             |                   |                +
                             |                   |                +bp
                                                                  +
                                                                  +
               file        t1@h1               t2@h2              +
                                                                  +if
                    /usr/export/LPD/t1     /usr/spool/t2          +
            Databases                       control.t2            +
            +++++++++++                                           +
            + config  +  cfA003h1            cfA001h1             +
            +++++++++++     dfA003h1            dfA001h1           lp
            +++++++++++                         hfA001h1        (/dev/lp)
            +printcap++     dfB003h1
            +++++++++++
            permissions                    cfA006h2.com
                         cfA004h1             dfA006h2.com
                            dfA004h1

                   Figure 1:  LPRng Spooling Software Architecture


          LPRng - Introduction                                            3









          While LPRng is similar in structure to the Berkeley LPR software,
          it differs in many important details.  The dashed lines indicated
          TCP/IP based communication between two programs; solid lines rep-
          resent access to files or directories.  Boxes  with  dotted  out-
          lines  represent  databases that may be accessed by all programs,
          either as files or by using network facilities.   The  user  pro-
          grams such as the print spooler lpr, the status reporter lpq, the
          job remover lprm, and the control program lpc are client programs
          which  connect  to one or more lpd server processes using TCP/IP.
          After  validation  and  authentication  the  servers  carry   out
          requested  activities on files and/or provide status information.
          The configuration and printcap databases provide the  information
          needed  by both server and client programs.  While clients do not
          need access to the  printcap  database,  in  many  cases  a  runt
          database  is  useful for providing printer configuration informa-
          tion.
             As in the LPR software, the lpd server  manages  one  or  more
          spool  queues  where print jobs are stored.  These are are imple-
          mented as directories in a file system.  A print job consists  of
          a  control  file,  which  contains  user information and printing
          options, and data files which contain the actual  information  to
          be  printed.   A spool queue can be a bounce or forwarding queue,
          which temporarily stores print jobs before they  are  transferred
          to  another  queue,  or  a  print  queue  which has an associated
          printer.
             Operation of a spool queues is controlled  by  information  in






























          4                                            LPRng - Introduction









          the  spool  queue  printcap entry and the printer control file in
          the spool directory; individual print job may  also  have  a  job
          control file as well.


























          -#-ENG-LPRng-Test-Configuration-----------------------------------
           # compile time only:
           #client_configuration_file /etc/lpd.conf:/etc/lpd_client.conf
           #server_configuration_file /etc/lpd.conf
           default_printer          t1
           default_host             %H
           default_banner_printer   /usr/local/bin/lpbanner
           lockfile                 /usr/spool/LPD/lpd.lock
           logfile                  /usr/adm/lpd.log
           #lpd_port                printer
           lpd_port                 4000
           originate_port           721 731
           user                     daemon
           group                    daemon
           #printcap_path           /etc/printcap:/usr/etc/printcap
           printcap_path            /tmp/LPD/printcap.%H
           #printcap_path           |/tmp/LPD/pcserver
           #printer_perms_path      /tmp/LPD/printer_perms.%H
           #printer_perms_path      /etc/printperm:/usr/etc/printperm
           printer_perms_path       /tmp/LPD/printer_perms.%H
           #print_perms_path        |/tmp/LPD/permserver
           use_info_cache           yes
           # include facility
           include                  /tmp/LPD/common.conf
                      Figure 2:  Configuration Database Format


          LPRng - Introduction                                            5









             Jobs are submitted to the lpd server by the lpr program  which
          transfers  the job over a TCP/IP connection.  The lpd server then
          forwards the job to another server or print it.  The lpq  program
          requests  and prints job status information, and the lprm program
          removes jobs from the spool queue.  The  LPRng  software  uses  a
          permissions database and the printcap information to determine if
          a user is authorized to use  a  facility;  authorization  can  be
          based  on  originating  host,  user  name, and a variety of other
          attributes.
             After a job is placed in a print queue, lpd creates  a  server
          process  to  manage the printing operations.  This server process
          then creates one or more filter processes which interface to  the
          printer  hardware.  The data files are passed through the filters
          to the actual printer.

                              Configuration Information
             Configuration information is used by both  the  LPRng  clients
          and  the  lpd server.  The configuration information controls the
          network behavior of the programs, and provides a set  of  default
          for commonly specified system information.  Compile time defaults
          can be overridden by values read from a configuration file, whose
          format  is shown in Figure 2.  The configuration file can also be
          used to specify default values for printcap variables.
             In all LPRng database files leading whitespace,  blank  lines,
          and lines whose first non-whitespace character is a # are treated
          as comments and ignored; a \ as the last character of a  non-com-
          ment  line  will  logically  continue this line to the next line,
          replacing the \ with one or more spaces.




























          6                                            LPRng - Introduction









             Each line of the configuration file has a configuration  vari-
          able   and   its   value.    The   client_configuration_file  and
          server_configuration_file values are used  only  at  startup  and
          initialization, and specify the configuration files for the LPRng
          client and lpd server programs.  Each of the configuration  files
          is  read in sequence and variable values are updated as the files
          are read.
             Much of the configuration information provides site  dependent
          information   or   allows   configuration   for   testing.    The
          default_printer and  default_  host  variables  set  the  default
          printer  and  host  to  be used by client software; the %h and %H
          strings are replaced with the short  or  fully  qualified  domain
          name  of the host on which the software is running.  The default_
          banner_printer sets the default banner  printing  program  to  be
          used  by the lpd server; the lockfile and logfile are used by the
          lpd server to prevent multiple servers from running and to record
          lpd logging information.
             The  lpd_port  variable specifies the TCP/IP port on which the
          lpd server listens for client requests.  In  production  versions
          this  is  usually  515  (the printer alias in the network service
          database); by setting it to some other port a test version can be
          run in parallel with production software.
             The originate_port value specifies a range of TCP/IP port num-
          bers for originating connections.  RFC1179 specifies  that  these
          connections  should  originate from port 721 to 731 inclusive; in
          most UNIX environments these are privileged ports and  cannot  be
          used  unless  the program's effective UID is ROOT (0).  On a UNIX
          system, if the client software is not SETUID ROOT, then only  the
          ROOT  user can successfully bind to a privileged port.  See Secu-
          rity Considerations for details on problems this may expose.  The
          user  and  group entries specify the effective user and group IDs
          to be used by the lpd server.  For this to be effective, the  lpd
          server  must  be  SUID  root or be started by a root process; see
          Security Considerations for details.
             The printcap_path, lpd_printcap_path, and  printer_perms  con-
          figuration  information specifies where database information will
          be found.  All programs use the printcap_path, and  printer_perms
          information; the lpd server will use the lpd_printcap_path infor-
          mation after the printcap_path informaiton.   The  use_info_cache
          option  allows  the  lpd  server  to read the information once at
          startup and then use a cached copy of this information,  as  does
          the  inet.d  server.   If lpd receives a SIGHUP signal it rereads
          the database information.  This can be  done  by  using  the  lpc
          reread  command.   Finally,  it  is  possible  to use the include
          facility to read additional configuration files.   This  facility
          may be removed in later releases of the LPRng software.

                                Printcap Information
             Entries in the printcap database define spool queues and their
          configuration available to the LPRng software.  Figures 3a and 3b
          show a set of client and server printcap database entries.  Lead-
          ing whitespace, blank lines, and lines whose first  character  is
          `#'  are  ignored.  Default values for printcap variables are set
          in the configuration file, using the same tags  as  the  printcap


          LPRng - Introduction                                            7









          file.  For compatibility with the historical LPR printcap format,
          \ at the end of a line appends the next line to the current line.
          -#-Client-Printcap-Database---------------------------------------
           # printer p1@'local host'
           p1
           # remote printer
           p2
             |full|double|rotate
             |twosided|XDR Line Printer
             :lp=p2@host
           # remote printer alternative
           p3:rp=p3:rm=host
           # connect to port 2000
           p4:2000%host
           # all entry (lpq -a)
           all:all=p1,p2,p3
                        Figure 3a:  Client Printcap Examples
          ------------------------------------------------------------------
             A  printcap  entry  consists  of a primary name followed by an
          optional set of aliases, followed by an optional set of  variable
          tag  names and values.  The primary name is the name by which the
          printer is referred to in error messages and status  information.
          The  | separator starts an alias entry and the : separator starts
          an variable entry; entries extend to the end of line or the  next
          separator  character;  leading and trailing in each entry whites-
          pace is ignored.
             The LPRng client programs need only the lpd server  host  name
          and  target  printer on the server.  This can be specified on the
          command line using the `-Pprinter' or `-Pprinter@host' option; if
          no  default  is  specified  in  the configuration information the
          local host is the default server host.  In Figure 3a, the  simple
          printcap  entry p1 means printer p1 on the default host; entry p2
          has has two aliases, the last of which is really  a  comment  and
          will be used when displaying status information.
             The  lp  (line  printer)  tag  specifies the printer device or
          host.  The form lp=printer@host is  printer  on  host;  the  form
          lp=printer@host%2000  indicates  the  lpd  server is available on
          port 2000.  This last form is extremely useful when running  mul-
          tiple versions of spooler software, and for connecting to network
          based printers with specialized needs.  A file pathname  such  as
          lp  =/dev/ttya  specifies  a  printer  device  to  be used by the
          server; the form lp=host%2000 indicates port 2000 on host is net-
          work based printing device.
             More  printcap information is needed for the lpd server, as is
          shown in Figure 3b.  Spool queues have printcap entries with a sd
          (spool directory) tag.  The tc tag (recursively) appends a print-
          cap entry to the end of the referencing entry.  Multiple tc  tags
          may  appear  in a printcap entry.  Printcap entries whose primary
          (first) name starts with a non-alphabetic character  are  consid-
          ered to be dummy entries and can only be referenced by tc tags.
          ------------------------------------------------------------------
           # Server/Client Printcap Database
           # file: /etc/printcap
           # clients see p1 as remote pr


          8                                            LPRng - Introduction









           # server use sd tag to get
           #  /usr/spool/LPD/p1/printcap
           p1
             :cm=Test Printer 1
             :sd=/usr/spool/LPD/p1
             :lp=p1@host
           # second printer,
           p2
             :sd=/usr/spool/LPD/p2
             :tc=@common
           # common information
           @common:
             :lf=log
             :rw
             :of=/tmp/LPD/psof
             :if=/tmp/LPD/psif
           p3:sd=/usr/spool/%P:tc=@common

           # Printer specific information
           #   used by server,
           # file: /usr/spool/LPD/\
           #        p1/printcap
           # Alternately, this information
           # could be part of the
           #   /etc/lpd_printcap file
           p1
             # override previous value
             :lp=/dev/ttya
             :lf=log
             :rw
             :of=/tmp/LPD/psof
             :if=/tmp/LPD/psif
           # debug
           #   :db=9,remote=10
           # autohold - hold all jobs on submission
           #   :ah
                     Figure 3b:  Server/Client Printcap Examples
          ------------------------------------------------------------------
             The  lpd  server  checks  to  see if a printcap file is in the
          spool directory, and will read the printcap information from this
          file,  overridding  existing  information.   This allows a single
          master printcap database to be used by both clients and  servers;
          the  clients  ignore the sd tags and the server gets printer spe-
          cific information from the printcap file in the spool  directory.
             The  oh  (options  for host) entry can be used to specify that
          the printcap entry is used  only  by  a  host  whose  IP  address
          matches  the  IP  address of the entry.  For example, if oh=dick-
          ory.sdsu.edu, then only hosts with the same IP address  as  dick-
          ory.sdsu.edu would use the printcap entry.  By using the oh entry
          in the server printcap entry a single printcap database file  can
          be used.
             A major administration problem is the distribution of printcap
          information.  One solution is to use a network database  such  as
          Sun  Microsystems NIS, HESIOD, Sybase, etc.  Rather than build in


          LPRng - Introduction                                            9









          a specific database access method the  LPRng  software  uses  the
          concept of database filters to access the information.  In Figure
          2, the configuration printcap_path value |/tmp/LPD/dbserver spec-
          ifies using a filter program to get printcap information.
             The  filter program is started by the client or server process
          and a string containing the name of the desired printcap entry is
          sent  to  the filter's stdin port; the returned printcap informa-
          tion is read from the filter's stdout port.  By convention, a all
          request  returns either all the available printcap entries, or an
          all printcap entry whose all tag contains  a  list  of  available
          printers.








          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
          SAMEHOST    V     -       SA    -      SA   SA    SA
          SAMEUSER    V     -       -     -      SU   SU    SU
          SERVER      V     -       SV    -      SV   SV    SV
          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= N           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
          Match: S = string with glob wild card, IP = IPaddress[/netmask],
            i.e.- x.y.z.w/a.b.c.d or x.y.z.w/N where N is length of mask
            N = low[-high] number range; NOT negates the test status
                          Figure 4:  Permission Attributes


          10                                           LPRng - Introduction









             The Sun NIS database can be access by  using  a  simple  shell
          script  and  the ypmatch program; HESIOD, DBII, Sybase, and other
          databases can be supported in the same manner.
             The actual printcap expansion algorithm is  as  follows.   The
          list  of  printcap  files specified by the configuration database
          values  printcap_path  and  on  the  LPD  server  the  additional
          lpd_printcap_path are searched.  These values should be semicolon
          or comma separated lists of files, or the command for  a  filter.
          The  files  are read, and any include files are read at the indi-
          cated points.  (This is similar to the manner in which the C lan-
          guage  preprocessor  operates.)   Next,  the input is parsed into
          printcap fields, and organized into raw  printcap  entries.   The
          raw entries are then sorted and joined together to form the final
          printcap entries.  As each entry is added, it is checked for a tc
          field and the specified entry is recursively processed.
             Strings  with %X in them will be processed and the string sub-
          stitions will be  made.   Currently,  %P,  %H,  %h,  %R,  %M  are
          replaced  by  the  printer name, fully qualified host name, short






































          LPRng - Introduction                                           11









          host name, remote printer, and  remote  host  respectively.   The
          result  of  this  process will be a set of printcap entries whose
          values are organized in sorted  order.   The  resulting  printcap
          entry can be examined using the lpc program printcap command.
             The  printcap  database is consulted only when actual informa-
          tion about a printer is needed.  When an actual printcap entry is
          needed,  the  database is checked to see if a printcap entry with
          the printer name is present.  If it is not and a filter has  been
          specified  in  the  printcap_path configuration information, then
          the filter started and the required printer name is  made  avail-
          able  on  the  filter stdin (file descriptor 0).  The filter will
          write information to its stdout (file descriptor 1), which is  in
          turn  read  by the LPRng software.  The result is then parsed and
          checked as for the printcap entries obtained from files.
             When the tc entry to  be  expanded  is  not  in  the  printcap
          database  and  a  filter  is  available,  then the filter will be
          invoked to obtain the entry.  If the first printer  name  in  the
          printcaps  entry  is non-alphabetic character, then the entry can
          only be used as a reference for tc.

                                   Job Submission
             The lpr client program submits jobs to the lpd server by  sim-
          ply  using  a  TCP/IP  connection  and  sending  the files to the
          server.  The only information the client needs is the printer and
          hostname, and can run as a user application.
             If the printer output is piped to the lpr client, then RFC1179
          allows the output to be directly copied from the  client  to  the
          server by using the lpr -k (for seKure) option.  While LPRng sup-
          ports this option, many  other  LPR  server  implementations  are
          defective or do not support this capability.  This is useful when
          creating large jobs, or there is are  security  related  problems
          with creating a temporary file on the client host.
             The  LPRng  clients can run as ordinary user processes; elimi-
          nates any problems with unauthorized  access  to  files,  as  the
          client has no permission except those of the user.
             However,  for the lpr client to be compatible with vintage LPR
          spooling software (i.e.- SUN Microsystems), it must  originate  a
          connection  from a privileged port.  For this reason, when run as
          a SETUID ROOT program, after  making  a  connection  to  the  the
          server,  the  lpr  client uses setuid(2) to drop the root permis-
          sions, and operates as an ordinary user program.
             Several of the vintage lpr options such as the `-s' (use  sym-
          bolic  links)  and `-r' options (remove on printing) are not sup-
          ported; the symbolic link option  has  no  effect  as  files  are
          transferred  directly  to  the  server, and the remove option has
          caused more than one user to accidentaly delete the files that he
          wanted printed!

                       Permissions and Authorization Checking
             One  of  the requirements of any printer spooling system is to
          deny access to unauthorized users and to record accounting infor-
          mation  for  authorized  users.  The LPRng software uses a rather
          elaborate permissions and authorization mechanism, similar to the
          ones used by computer network firewalls.


          12                                           LPRng - Introduction









             Since  all  spooling  operations  are  carried  out by the lpd
          server, it is the only process that needs to perform  permissions
          checks.  Permissions are checked when a connection is made to the
          server, and before the server performs  and  action  or  provides
          information  requested  by the various client programs.  In addi-
          tion, the server checks job permissions before it prints a job as
          well as when the job is submitted.  This allows NFS based printer
          spooler software, which copies control and data files directly to
          a  spool  directory, to be used with the LPRng software.  See the
          Security Considerations section  for  a  discussion  of  problems
          related to allowing this type of activity.
























          -#-Permissions-Database-------------------------------------------
           # Reject connections not in our subnet
           REJECT SERVICE=X NOT IP=130.191.0.0/255.255.0.0
           # Allow root on trusted hosts or server
           # to have control and removal capability
           # and users on the same host to remove their jobs
           ACCEPT SERVICE=C,M HOST=hop.sdsu.edu,skip.sdsu.edu \
               PORT=721-731 USER=root
           ACCEPT SERVICE=C,M SERVER USER=root
           ACCEPT SERVICE=M SAMEUSER SAMEHOST
           REJECT SERVICE=C,M
           # do not allow forwarded jobs from anybody but dickory
           ALLOW SERVICE=R NOT SAMEHOST HOST=dickory.sdsu.edu
           REJECT SERVICE=R NOT SAMEHOST
           # Allow PC lab to spool to laserwriter
           ACCEPT SERVICE=R,P,Q PRINTER=lw4 HOST=*.eng.sdsu.edu
           # if no match in other database then you fail
           DEFAULT REJECT
                       Figure 5:  Sample Permissions Database


          LPRng - Introduction                                           13









             Each request for service has a set of attributes and values; a
          list  of these attributes is shown in Figure 4.  Figure 5 shows a
          sample permissions database.  Each line in the database  consists
          of  a  match  result and a list of attribute names and match pat-
          terns.  Permissions checking is done by scanning the database  in
          order,  checking  each  line  for a match.  If all the entries on
          line match, then the result is the match result for the  line  or
          the  current  default.   Note  that  each  entry can have several
          alternate patterns; these patterns are tried  in  order  until  a
          match is found.
             The  default_permission  configuration  variable  specifies an
          initial (default) permission database entry;  additional  permis-
          sion databases are specified by the printer_perms_path configura-
          tion variable.  When checking permissions for a spool queue  with
          printcap entry, the xu printcap tag provides an additional set of
          databases to be searched as well.  One of  the  database  entries
          can  be a filter, which is invoked with the filter_options speci-
          fied in the configuration database,  and  has  the  name  of  the
          printer  written  to  its  standard  input.   The  filter options
          include the print job user name, which can be used  to  search  a
          database  to  determine  if  the  user has permission to access a
          file.  The filter output is used as an additional permission file
          for permissions checking.
             For  a complete list of keys and tags, see the manual page for
          details.  If no match is  found  after  searching  all  specified
          databases  then  the  last  specified  default permission will be
          used.
             Permission attributes are treated as string,  integer,  or  IP
          address values.  The string patterns are based on the simple glob
          patterns of the Bourne and C shells,  and  use  case  insensitive
          matching with only the * metacharacter.  For example, the pattern
          A*b will match Ab,  and  AthisB.   IP  address  patterns  are  an
          address  (ADDR)  followed  by  an  optional  netmask  (NM)  which
          defaults to 255.255.255.255;  the  match  succeeds  if  (using  C






















          14                                           LPRng - Introduction









          language  notation)  (IP^ADDR)&NM is zero.  For example, the pat-
          tern 130.191.163.0 / 255.255.255.0 matches all of  the  addresses
          in the 130.191.163.0 subnet range.  The netmask can also be spec-
          ified by the number of most significant non-zero bits.  For exam-
          ple,  130.191.163.0/255.255.255.0  and  130.191.163.0/24  are the
          same address/mask pair.  Number patters are a low  to  (optional)
          high integer range.
             The special pattern char= pattern matches the char line in the
          job control file against pattern.  For example,  C=A*,B*,C*  will
          check  the  C (class) information line for a string starting with
          A, B, or C.  The special  pattern  NULL  matches  missing  or  no
          information;  for example the permissions entry ALLOW SERVICE=R,P
          USER=NULL,* allows anonymous job spooling and printing.

                             Spool Queues and Job Files
             The main activity of the lpd server is  centered  on  managing
          print  jobs  in the spool queues.  A print job consists of a con-
          trol file, containing user and other information, and data  files
          containing  the information to be printed.  The control file for-
          mat is specified by RFC1179; a sample job control file  is  shown
          in  Figure  6.   Control  file  names have the format cfXnnnHOST,
          where X is a letter, nnn is a 3 digit job number, and HOST  is  a
          host  identifier.   Data  files names have the format dfXnnnHOST,
          where X is a letter, and nnn and HOST are identical to the corre-
          sponding control file.
          -Htaco.sdsu.edu---------------------------------------------------
           Ppapowell
           J(stdin)
           CA
           Lpapowell
           Qt1
           fdfA917taco.sdsu.edu
           N(stdin)
           UdfA917taco.sdsu.edu
                             Figure 6:  Job Control File
          ------------------------------------------------------------------
             Control  file lines starting with an upper case letter provide
          information and those starting with lower case letters specify  a
          format  and a data file to be printed with the format.  For exam-
          ple, the P (person) and H (host) lines give the originating  user
          and  host  name; the I (indent) and L (banner name) are used when
          printing the job.
             The LPRng software extends  the  basic  RFC1179  control  file
          entries by adding Z (output filters options), Q (original queue),
          and A (identification) options.  The value of these  options  are
          passed  to the filters that format and print the data files.  For
          example, Figure 3a shows an example of a printcap entry (p2) with
          several  aliases.   The lpr command lpr -Q -Pdouble -Zheavy_paper
          will create a control file  with  the  Qdouble  and  Zheavy_paper
          entries  and sends it to the p2 printer.  The output printing can
          use the Q and Z  entries  to  select  various  paper  and  format
          options.




          LPRng - Introduction                                           15









                                LPD Server Operations
             The  lpd  server  creates  queue server process for each spool
          queue, and then waits for connections from clients.  Each time  a
          request  arrives  the  server will create a new process to handle
          the requests.  The max_servers_active configuration variable  can
          be  used to limit the number of active servers.  The queue server
          process uses the printcap entry information and a set of  control
          files in the spool directory to control its activities and report
          its actions (Figure 1).  In  the  discussion  below,  printer  is
          stands  for  the primary printer name; all files are in the spool
          directory unless otherwise indicated.
             The Server lock file (printer) is used to ensure that only one
          server process is active at a time.  The spool control file (con-
          trol.printer) has the format shown in Figure 7a, and controls one
          or  more  of the spool queue related activities.  Entries in this
          file override defaults  and  values  in  the  printcap  database.
          Note:  the  information  shown in this file may not be present at
          all times.
             The control  file  spooling_disabled  and  printing_  disabled
          entries disable spooling to the queue and printing from the queue
          respectively.  The redirect entry causes the server  to  transfer
          all  spool jobs to the specified remote printer.  When holdall is
          enabled, the server will not process a jobs until it is  released
          by  a  request  from the lpc program.  The printcap ah (automati-
          cally hold) flag can be used to set job holding on by default, or
          it  can be enabled/disabled by using the lpc holdall or noholdall
          commands.  If the ah flag is on, it cannot be  overriden  by  the
          lpc holdall/noholdall commands.
          -printing_disabled-0----------------------------------------------
           spooling_disabled 1
           debug 10,remote=5,log=/tmp/log
           redirect  p3@mentor
           holdall  off
           class     A,B
                           Figure 7a:  Spool Control File
          ------------------------------------------------------------------
             The  class entry restricts the printable jobs to the specified
          class.  This facility allows special forms to  be  mounted  on  a
          printer and only jobs which need them to be printed.  The special
          pattern char=patterns restricts printing to jobs with  a  control
          file line starting with char which matches pattern.  For example,
          P=accounting could be used to restrict printing to jobs from  the
          accounting user.
             The  debug  entry is a diagnostic and testing aid.  The set of
          options are used used by the server to enable or disable specific
          testing functions.  For example, 10,remote=5,log= /tmp/log speci-
          fies a general debugging level of 10, setting the remote flag  to
          5, and logging to the /tmp/log file.
             The  lpc (line printer control) program is used to request the
          lpd server to change the spool control file values and take other
          actions,  such as starting or stopping server processes.  The lpc
          program can also request (brutal) spool server  process  termina-
          tion,  and  (gentle)  restarting of spooling activities.  The lpc
          stop and start commands are used to enable and disable  printing;


          16                                           LPRng - Introduction









          enable  and  disable is used to enable and disable spooling.  The
          abort command will attempt to brutally stop printing of the  cur-
          rent  job  and remove it; the kill command will stop printing and
          then attempt to restart the last job.  There are similar commands
          to modify the various fields in the control file; see the lpc man
          page for details.
             The spool server process scans the spool queue, ordering  jobs
          to  be  serviced  in  a first-in, first-out order within priority
          classes.  Class A is the lowest (default) priority, and Z is  the
          highest.   When  a  job  is selected for for servicing, the spool
          server forks a subserver process to carry out the actual work..
             The reason for using a subserver process for per job servicing
          is  based  on experiences with a variety of UNIX implementations.
          Some of these implementations have memory leaks or file  descrip-
          tor  leaks  associated  with various database and networking rou-
          tines; each time a process uses these routines they  open  a  new
          file  descriptor  or  allocate  some temporary storage.  Unfortu-
          nately, these descriptors are never  closed  the  descriptors  or
          reclaim the storage.  These defective functions are firewalled in
          a subserver process, which only exists while a particular job  is
          processed.   Note that the same problems exist in the lpd server,
          which also takes care to isolate these  actions  in  a  subserver
          process.
          -active-----2743--------------------------------------------------
           hold       1
           priority   0x873486
           remove     1
           redirect   p4@mentor
           error      Printer timed out
                              Figure 7b:  Job Hold File
          ------------------------------------------------------------------
             When a job is selected for service, the subserver process cre-
          ates a job hold file to record information; job cfA001mentor will
          have  hold file hfA001mentor.  The hold file has the format shown
          in Figure 7b.
             The active entry records the process ID of the subserver  pro-
          cess,  and  indicates  that  the  job is active.  A non-zero hold
          entry indicates that the job  is  being  held  by  administrative
          actions;  a  hold value of 0 allows a job to be printed.  The lpc
          hold and release commands can be used to hold and release jobs.
             The priority field specifies an additional level of job prior-
          ity;  jobs with non-zero priority fields are serviced before jobs
          with 0 fields; the lpc topq command updates the priority value.
             The redirect entry supplements the spool queue redirect infor-
          mation.  This entry allows individual jobs to be moved to another
          spool queue.  The lpc move command updates the redirect value.
             The remove and error entries are used to solve a problem  with
          defective  or  misconfigured  printing  software.  After a job is
          serviced its files are removed from the  spool  directory.   How-
          ever,  sometimes  due  to accident or intent, the files cannot be
          deleted, resulting in the job being endlessly  printed  and  pre-
          venting  normal operations.  When a job is serviced, the job hold
          file is created and written in the spool directory; if  the  hold
          file  cannot  be modified the job is not serviced.  After the job


          LPRng - Introduction                                           17









          has been serviced the remove field is set to  a  non-zero  value;
          this  prevents  the job from being reprinted, and the error field
          records any error conditions that might inhibit retrying  servic-
          ing  the  job.   This  information  is displayed by the lpq (line
          printer queue) program.  After the job files have been successful
          removed, the server then removes the job hold file.
             A bounce queue is used to temporarily hold jobs until they can
          be forwarded to a remote printer.  This is  useful  when  sending
          jobs  to  a network printer.  The LPRng software lpr and lpd pro-
          grams use the same algorithm to check file permissions and acces-
          sibility  when  sending jobs to a remote printer.  Normally, data
          files are not modified  when  forwarding,  but  if  the  printcap
          bq=destsystem flag is set and there is an appropriate format fil-
          ter, the data files will be processed by the filter before trans-
          fering  to  the destination system.  Note that for correct opera-
          tion, the printcap lp flag should be set to the name/host  combi-
          nation of the bounce queue, i.e.-









          -LP-=-open(-'lp'-);--//-open-device-------------------------------
           OF = IF = LP;     // set defaults
           if( 'of' ) OF = filter( 'of' ) -> LP;
                              // make OF filter
           if( accounting at start 'as')
              do accounting;
           if( leader on open 'ld' ) `ld` -> OF;
                             // send leader
           if( FF on open 'fo' ) `fo` -> OF;
                             // send FF
           // check to see if banner required
           do_banner =
              (always banner 'ab'
                 || (!suppress banner 'sb'
                    && control file 'L' ));
           if( ! header last 'hl' && do_banner ){
              BP = OF; bnr = null;
              if( banner start 'bs' ) bnr = 'bs'
              else if( banner program 'bp' ) bnr = 'bp'
              if( bnr ){
                 BP = filter( bnr ) -> OF;
              }
              short banner info -> BP;
              if( BP != OF ) close( BP );
           }
           // suspend the OF filter
           if( OF != LP ) suspend OF filter;
                    Figure 8a:  Printing algorithm used by LPRng


          18                                           LPRng - Introduction









          bqname:lp=bqname@host
            :bq=destq@host
            :sd=/var/...
            :if=/if_filter
             The :lpr_bounce: printcap flag will cause the LPR  program  to
          perform  filtering before sending the jobs to a server.  This can
          have unexpected results if the filters are not available  on  the
          local host.

                                 Printing Algorithm
             On  the  surface,  dealing with the printer hardware should be
          quite simple: the printer device is opened, the  job  data  files
          are  sent  to the device, and the printing device is then closed.
          The actual algorithm used by the lpd server for printing a job is
          rather complex, in order to deal with the following problems.
          1.  Each printer usually has specific requirements for connection
              and initialization, not to mention the actual transmission of
              data.
          2.  If  the  connection  to the printer is a serial line, stty(1)
              (or a similar function) must set the speed, format, and other
              characteristics.   When  a serial line is closed and reopened
              the line characteristics may be reset to some default  value,
              requiring  the  line  to be held open throughout the printing
              process.
          3  The effects of the  failure  printing  a  job  job  should  be































          LPRng - Introduction                                           19









             localized to that job.




























          -for-each-data-file-df-in-job-do----------------------------------
              // send FF between files of job
              if( !first job && ! suppress FF 'sf' ){
                 if( OF != LP ) wake up OF filter;
                 'ff' -> OF;
                 if( OF != LP ) suspend OF filter;
              }
              // get filter for job
              ?F = LP; // default - no filter
              format = jobformat;
              if( jobformat == 'f' or
                 jobformat = 'l' ){
                    format = 'f';
              }
              filter = format filter from printcap;
              if( filter ){
                 ?F = filter( filter ) -> LP;
              }
              // send data file to printer
              // through filter
              data file -> ?F;
              // kill filter
              if( ?F != LP ) close( ?F )
           endfor
                    Figure 8b:  Printing algorithm used by LPRng


          20                                           LPRng - Introduction









          4  Different types of output such  as  raster  plots,  PostScript
             files,  text  files, etc., may require different handling when
             printing.  This can be very device specific.
          5  Multiple users may use the same printer; jobs need to be care-
             fully  separated, banner pages provided, and other administra-
             tive functions performed.
          6  Administrators have a strong  desire  to  record  the  printer
             usage so that users can be billed appropriately.
          7  Some  serial line devices must be opened in a nonblocking mode
             so that configuration operations can be performed.
             In order to handle printer specific problems, each printer has
          a  set  of  filters or support programs which provide support for
          specific operations.  For example the of filter will  print  ban-
          ners,  page  separators, and other high level queue control func-
          tions.  Files whose print format is the (lower case) character  ?
          will  be printed using a ?f filter; the programs corresponding to
          each format are found in the printcap file.
          The algorithm used by LPRng is shown in Figure 8.  It is  similar
          to  the  original  Berkeley  algorithm, but not identical.  Names
          such as `of' refer to entries in the printcap database and OF  is
          a  filter  process  created  from the `of' information; OF = fil-
          ter('of') -> LP means create the OF filter from the  of  informa-
          tion in the printcap file, and send it output to the LP filter or
          device.
             While the algorithm used by LPRng is similar to  the  original
          Berkeley  LPR  algorithm,  there  are  some  subtle  differences.
          Before the job is printed, it is checked for the formats it uses.
          If  there  is  no filter available for a data file the job is not




























          LPRng - Introduction                                           21









          printed and only an error message is generated.

































          -//-finish-printing-----------------------------------------------
           if( OF != LP ) wake up OF filter;
           if( header last 'hl' && do_banner ){
              if( ! no FF separator 'sf' )
                 'ff' -> OF;
              BP = OF; bnr = null;
              if( banner end program 'be' ) bnr = 'be'
              else if( banner program 'bp' ) bnr = 'bp'
              if( bnr ){
                 BP = filter( bnr ) -> OF;
              }
              short banner info -> BP;
              if( BP != OF ) close( BP );
           }
           if( ff on close 'fq' ) 'ff' -> OF;
           if( trailer on close 'tr' ) tr -> OF;
           if( accounting at end 'ae') do accounting;
           if( OF != LP ) close( OF );
           close( LP );
                    Figure 8c:  Printing algorithm used by LPRng


          22                                           LPRng - Introduction









             The  printing  device is opened and closed for each print job.
          This eliminates a set of problems of printer failure; when  vari-
          ous  network  and  other printers will fail printing a file, they
          will not work correctly until reset by a network reconnection  or
          a  device  open.   In  addition, the 'nb' printcap entry forces a
          nonblocking open to be done on a device.
             The as and ae printcap entries specify a filter or  format  to
          be  used to record accounting information at the beginning or end
          of a job respectively, and the af printcap  entry  specifies  the
          accounting file where accounting information should be sent.  For
          example, for a 230 byte long job spooled to printer p1 by john on
          pc1  the  entry as=start $P $u $H $b will write start p1 john pc1
          230 in the accounting  file.   The  entry  as=|/usr/local/psaccnt
          start  will  run the psaccnt program, with the additional options
          specified by the filter_options configuration variable and  waits
          for  it  to terminate.  If the program terminates with a non-zero
          error status then the job will not be printed.  Any error message
          printed by the program on its stderr output will be placed in the
          log file.  The program stdout will be connected directly  to  the
          printer  device or filter specified by the lp field.  This allows
          any specialized probing of the printer to be done by the account-
          ing  program.   The ae field specifies the string or filter to be
          used at the end of a job.  Similar action is taken at the end  of
          a job using the ae printcap entry.
             In addition to the accounting done by the lpd program, filters
          can also do accounting and write their results to the  accounting
          file.  By convention, the name of this file will be passed to the
          filter, and FD 3 will be connected to the file.
             In addition to these file and program based facilities, if the
          accounting  file has the form af =host%port then it is assumed to
          specify a host and port for a remote accounting server.  The  lpd
          program  will  make  a connection to the specified host and port,
          and then send the  as  string  (with  expanded  options)  to  the























          LPRng - Introduction                                           23









          server.   If  the  accounting_check flag is TRUE, the server will
          check for a ACCEPT reply from the server, and will reject the job
          if  it is not received.  The connection will be passed to filters
          as FD 3, and they can also send  accounting  information  to  the
          server.
             Each  site  usually  has  a  different set of needs for banner
          printing.  LPRng has removed fancy bannner printing from the  lpd
          server  to  a  separate program.  The bp (banner printer) program
          generates a banner for a job; users can modify the banner without
          modify  the  LPRng software.  Note that banners can be printed at
          the beginning and end of  jobs.   All  banner  output  is  passed
          through the of filter if it is present.
             LPRng  can  use  vintage  filters  available for LPR and other
          spooling systems with a minimum of changes.  The section on  Fil-
          ters discusses how they are accommodated.
























          -Filter-specification:--------------------------------------------
             path arg1 arg2 $P $w $l $x $y
               $K $L $c $i \
               $Z $C $J $R \
               $0n $0h $F $-a
           Expanded Specification
           path arg1 arg2  \
              -PPrinter -wpw -lpl -xpx -ypy \
              -Kcontrolfilename -LLogname -iIndent \
              -ZZoptions -CClass -JJobinfo -RRaccountname \
              -n Person -h Host -Fformat af
           Note: pw, pw, etc. are from printcap entries,
             Printer, Logname, etc. are from control file lines,
             other information generated by server.
                    Figure 9:  Filter Specification and Expansion


          24                                           LPRng - Introduction









             LPRng supports multiple printers serving a single print queue.
          The  master  print  queue has a sv=server1,server2,...  (servers)
          printcap entry listing the server printer names; server  printers
          have a corresponding ss=master (serves) printcap entry.  The mas-
          ter spool queue server process creates a  subserver  process  for
          each slave printer; the subserver processes print all of the jobs
          in the server spool queue and then terminate.   As  each  of  the
          subservers processes terminates, the master select a job from the
          master spool queue and then create a new subserver process.  This
          subserver process will copy the job to the server spool queue and
          then process the job.  Note  that  print  jobs  can  be  directly
          spooled  to  slave spool queues, allowing users to send jobs to a
          server printer as well as to the master spool queue.

                                       Filters
             The LPRng software makes heavy use  of  filter  processes  for
          printing  and  other  operations.  A filter specification has the
          form
           | [-$] path optionsP
          Printcap printer filter entries usually drop the `|' filter indi-
          cation.   Filters run with EUID and RUID daemon; the ROOT keyword
          runs EUID ROOT.  See Security Considerations for details.
             The path entry specifies the  absolute  pathname  of  an  exe-
          cutable  file  and the options are a set of options to invoke the
          filter with.  In addition to  the  user  specified  options,  the
          LPRng  software  will  append  the  configuration  variable  fil-
          ter_options unless suppressed by the -$ flag.
             The options are scanned for variable  substitutions  indicated
          by  $  characters, followed by zero or more of the format indica-
          tion characters ' (single quote), - (minus), or 0 (zero).  If key
          has  a  non-zero  length  string  value  X,  then $key expands to
          -key'X'; the 0 format key add as space between the key letter and
          the value, ' suppresses quotation marks, and - suppresses the key
          flag.
               $0key expands to -key 'X'
               $-key expands to 'X'
               $'key expands to -key X
               $-'key expands to X


















          LPRng - Introduction                                           25









          The $c key should be used only for printing filters.  If the data
          file format is l (i.e.- binary) $c expands -c otherwise it is the
          empty string and does not appear in the output.  The following is
          a  list  of  keys and their corresponding values (:x: indicates a
          printcap value, control file is  a  line  from  the  job  control
          file).
               Key   Source              Value
               a     :af:                accounting file
               b     data file           data file size
               c     control file        data file format (see above).
               d     LPD                 control directory
               e     LPD                 pathname of data file in spool queue
               f     control file        data file original file name
               h     control file        short form of originating host name
               i     control file        indent specified to LPR
               j     control file        job number
               l     :pl:                page length
               m     :cf:                page cost factor for accounting
               n     control file        user name
               s     :ps:                printer status file
               t     LPD                 current time
               w     :pw:                page width
               x     :px:                page x dimension
               F     data file           format
               P     LPD                 printer name
               S     :cm:                comment tag
               Upper Case Character
                     control file        Corresponding control file field
          If  there  is  no  corresponding value for any of these keys, the
          result is a null (empty) string.  The substitution formats  allow
          the  user  to create interfaces to vintage printer filters with a
          minimum of effort; see below for an example.  As a  further  aid,
          The  printcap  bkf  (backwards  filter)  flag  appends  a list of
          options which are compatible with most vintage printer filters.
             In addition to the  command  line  options  filters  have  the
          PRINTCAP,  CONTROL_FILE,  and DATA_FILE environment variables set
          to the printcap information, control file contents, and data file
          name  being  printed.   This allows filters to use information in
          the control file or printcap entries with  a  minimum  amount  of
          effort.
             By  convention filters read input from stdin, write to stdout,
          and write errors to stderr.  The error output is usually directed
          to  the  error  logging file for the printer.  Print filters have
          their current directory set to the printer spool directory.

                               Security Considerations
             Security considerations were a major factor in the  design  of
          the LPRng software.  Many of the problems center on the following
          issues.
          1.  Users trying to use the printer spooler software  to  exploit
              bugs in the operating system and gain root access.
          2.  Users  trying  to  use  the  printer spooler software to gain
              unauthorized access to other users files,
          3.  Users trying to gain illegal access to printing facilities.


          26                                           LPRng - Introduction









          4.  Users trying to avoid accounting procedures.
          5.  Denial of service attacks.
             The first issue to be dealt with is the problem of  ROOT  per-
          missions.   All  of the client LPRng programs can run as ordinary
          users; this eliminates a large number of attacks on system  secu-
          rity  by trying to exploit various defects in the system based on
          SUID root programs.  The LPD server  is  the  only  program  that
          absolutely  needs  to  run with real UID (RUID) ROOT as it uses a
          privileged TCP/IP port to listen for incoming connections, and in
          most  UNIX systems bind(2) requires EUID ROOT permissions to bind
          to a privileged port.  (It is not recommended that  a  non-privi-
          leged  port be used as a trojan horse user program can bind to it
          and impersonate the LPRng software.)  According to RFC1179 a con-
          nection  to  a  server must originate from a (privileged) port in
          the range 721-731.
             Given this need for ROOT permissions, the LPRng code  goes  to
          extreme  lengths  to  ensure that only the bind(2) calls are made
          with EUID root, and that all other operations are done either  as
          daemon (server) or as user (clients).  It is strongly recommended
          that the lpd program not be SUID root, but should started  up  by
          the system initialization rc(4) scripts or a root user.
             It is recommended that all client programs be run as user (non
          privileged) jobs.  Only files accessible to the user will be read
          or  transferred  to  the  server.   If  a  user wants to access a
          printer that requires privileged ports, it is a simple matter  to
          create  a bounce queue on a server that will forward a job to the
          remote system.
             The checkpc (check printcap) program scans  the  printcap  and
          permissions  databases,  spool  queues, and checks permissions of
          files and directories.  If run by ROOT with  the  -f  (fix)  flag
          set, it will try to change ownerships, create files and/or direc-
          tories, and remove junk or old job files from spool queues.  This
          program also has some portability tests built into it, and can be
          used to check that the target system can  safely  run  the  LPRng
          software.
             Most  efforts  to circumvent accounting and permissions checks
          are based on forging or impersonation of another user or  network
          host.   The  current version of the LPRng software depends on the
          various system configuration and database  utilities  to  provide
          user  authentication  and system authentication.  This is clearly
          inadequate, and LPRng support  encryption  based  authentication;
          support  for using Kerberos (version 5) is built into the system.
          PGP and other forms of authentication are supported by using  the
          filter  mechanism  to  invoke  a  set  of authentication programs
          rather than directly incorporating the code into the LPRng  soft-
          ware.   Details  of the exact interface for authentication can be
          found in the lpd(8) man page documentation.
             One of the arguments for running client programs SUID ROOT  is
          that  it  allows  them to connect to the server from a privileged
          port, and the information provided will be authenticated in  some
          manner by use of the operating system facilities.  Unfortunately,
          the LPRng software uses various network databases to obtain  con-
          necting host information; by attacking the the system by spoofing
          database  (DNS)  server  activities,  it  is  possible  to  forge


          LPRng - Introduction                                           27









          authentication.
             The  use of NFS exported and mounted spool directories exposes
          the LPRng software to extreme attack.   One  of  the  assumptions
          made  by  most spooling systems is that only the trusted spooling
          software or trusted application programs will have  write  access
          to  the  spool  directory;  when  the directory is NFS mounted or
          exported this may no longer be true.   Several  spooling  systems
          operate by writing job control and data files into an NFS mounted
          spool directory.  By appropriately  forging  network  identifica-
          tion, credentials, and various RPC calls, attackers can create or
          modify unprotected files in the spooling directory.  The  ability
          to  read information in job or other files may also give them the
          ability to launch other forms of attack.  One of the  more  mali-
          cious  denial  of service attacks is to create a file that cannot
          be removed or modified; the spooler software may end  up  repeat-
          edly  attempting  to  print  the  file, blocking other users from
          using the spool queue and consuming printer resources.
             In order to protect the LPRng software from NFS spoofing based
          attacks,  the   printcap  cd=directory entry specifies a separate
          control file directory to be used by  lpd  for  all  spool  queue
          files  except  the job and data files.  This directory should not
          be NFS mounted or exported, and should reside on the  local  host
          file system.  This directory should be carefully created so as to
          be accessible only by user daemon.  Printcap and  other  informa-
          tion can be safely placed in this directory as it cannot be modi-
          fied by NFS operations.
             Avoiding printing accounting procedures has long been a tradi-
          tion  at  educational institutions; while minor infringements are
          usually ignored, persistent and blatant offenses  are  worrisome.
          In addition, once an individual discovers a method then it appar-
          ently is rapidly copied by others, leading to  widespread  abuse.
          One   difficulty  faced  by  administrators  is  determining  the
          resources used by a job.  As part of the printing algorithm,  the
          LPRng software provides a set of hooks to allow the invocation of
          accounting programs before and after the actual job  is  printed.
          For  example, most PostScript printers have a page count register
          whose value can be easily read by a  simple  Postscript  Program.
          By  reading  this  before  and after a job the total usage can be
          calculated.
             However, some students have discovered that by aborting a  job
          in  the middle of its printing or by printing a job that contains
          information that causes the printer to hang and  not  report  the
          total  pages  used  at the end of a job they can avoid the normal
          accounting procedures.  By recording information before  as  well
          as after a job completes such incomplete jobs can be found.
             Filters  are  a  major  security loophole, as most filters are
          shell scripts and inherit shell script vulnerabilities.  To  com-
          bat  this,  the  LPRng  software  defaults to running all filters
          either as the user or as daemon, and provides  a  predefined  and
          limited  set of environment variables.  Some network printer fil-
          ters need to open a privileged port and must  have  root  permis-
          sions.   This  is  a  serious vulnerability, and the lp=host%port
          printer specification has been provided to ameliorate this  prob-
          lem.   It  has  been recommended that filters run as user nobody,


          28                                           LPRng - Introduction









          restricting capabilities to an even greater exent, and this  con-
          sideration is under study.
             If  it is absolutely necessary that a filter execute with ROOT
          permissions, then the adminstrator should install the filter SUID
          root, but only allowing execution by group daemon.  For example:
           chown root $filter
           chgrp daemon $filter
           chmod 4010 $filter
             Filters  which  are  actually  shell scripts are vulnerable to
          attacks using metacharacters in option strings.  To combat  this,
          the  LPRng  software  ruthlessly  purges  all  non-alphanumberic,
          whitespace and simple punctuation (minus, equal,  period,  slash,
          and comma) characters from filter options.  The raw option infor-
          mation is available in the PRINTCAP and CONTROL_FILE  environment
          variables.   Administrators  would be wise to examine shell based
          printer filters for similar security loopholes.
             Deliberate denial of service attacks are almost impossible  to
          avoid.   However,  heavy  usage of the printer system can produce
          almost the same symptoms.  For example, when a  large  number  of
          print  jobs  are queued it is possible to exhaust the spool queue
          file space.  The printcap mx (maximum job size)  entry  specifies
          the maximum job size (in Kbytes) to be queued and the mi (minimum
          free space) entry specifies the minimum free  space  (in  Kbytes)
          needed.

                               Example Printcap Files
          The following is a typical set of LPRng printcap files that could
          be used With the psfilter programs.  We assume we are talking  to
          a  HP  IV  printer,  ecepr3,  it  us using a Jetdirect card which
          allows a  direct  printer  connection  on  port  9100.   We  have
          installed the filter software as follows:
          /usr/local/lib/ - directory
            psif - IF filter
            psof - OF filter
            bannerx -  banner printer
          Version 1:
          by default, the psof filter will print a banner using information
          on the short banner line and/or parameters passed by LPRng.
           # LPRng printcap files
           # HP LaserJet 4m+
           lw4|lp|HP LaserJet 4M
           # job size information
             :mx#0
           # spool directory
             :sd=/usr/spool/cca_4mp:
           # device network address
             :lp=ecepr3%9100
             :rw
           # set up status and
           #  accounting files
             :sf=status
             :af=acct
             :lf=log
           # page information size


          LPRng - Introduction                                           29









             :pl#60:pw#80:
           # you need SHORT BANNER
           # specify the SHORT BANNER
           #  line format
             :sb
             :bl=Seq\: $-'j \
               Class\: \ $-'C \
               User\: $-'n Job\: $-'J \
               Date\: $-'t
           # turn FF off
             :sf
           # filters
             :if=/usr/local/lib/psif
             :of=/usr/local/lib/psof
          Version 2:
          You want to have a special banner, so you  specify  a  BP  banner
          printers   explicitly  and  turn  of  the psof banner generation.
          Make the following changes to Version 1.
           REMOVE:
             :sb (you want full banners)
           ADD:
             # use new banner printer
             :bp=/usr/local/lib/bannerx
           CHANGE
             # pass option to filter to
             # turn of banner generation and
             # pass through text
             :of=/usr/local/lib/psof      -Tbanner=off
          Version 3:
          Printer is on /dev/ttya serial line. Note: the stty  options  are
          taken  from  an  actual functioning printer connection and should
          work for HP printer  on  a  serial  line).   Make  the  following
          changes to Version 1.
           CHANGE:
             :lp=/dev/ttya
           ADD:
             :sy=38400 -echo -crmod \
               -raw -oddp -evenp \
                pass8 cbreak ixon
          Version 4: you do not want banner pages at all.  Make the follow-
          ing changes to Version 1.
           # LPRng printcap files
              ADD:
              # suppress all header info
              :sh

                             Summary and Acknowledgments
             The LPRng software continues to evolve as users find  problems
          and  develop  new  printing requirements.  One of the areas to be
          pursued is the use of encryption for end to end authentication of
          users and print jobs.  Another is adding interfaces to other net-
          work based spooling systems.  Finally,  documentation  and  auto-
          mated management continues to be pursued.
             The  network  based  interfaces for client programs makes user


          30                                           LPRng - Introduction









          developed GUI systems almost trivial to  develop.   PERL  scripts
          and  Tkl/Tk  based  front  ends can be developed rapidly and with
          little effort.
             The development of the PLP and LPRng software would  not  have
          been  possible  without  the aid and assistance of literally hun-
          dreds of users.  The main developer of the software  was  Patrick
          Powell  <papowell@  sdsu.edu>, and Justin Mason <jmason@ iona.ie>
          generated the PLP4.0 distribution, contributed much of the porta-
          bility  code,  and  organized the plp@iona.ie mailing list.  Sub-
          scribe by sending email to plp-request@  iona.ie  with  the  word
          subscribe    in    the    body.     Marty    Leisner    <leisner@
          sdsp.mc.xerox.com>,  Ken  Lalonde  <ken@   cs.toronto.edu>,   and
          Michael   Joosten  <joost@  ori.cadlab.de>  performed  invaluable
          portability testing  and  debugging  of  the  LPRng  Alpha  Minus
          release;  they  discovered  and provided fixes for literally hun-
          dreds of bugs.
             LPRng was based on PLP Release 4.0,  to  which  the  following
          people (in alphabetical order) contributed:
          Alan F Lundin                                <aflundi@sandia.gov>
          Alan Shutko                                 <ats@shep1.wustl.edu>
          Andrew Leahy                      <A.Leahy@st.nepean.uws.edu.au>,
          Andrew Richards                   <physajr@phys.canterbury.ac.nz>
          Angus Duggan                              <angus@harlequin.co.uk>
          Avery Earle                                <ae@play.psych.mun.ca>
          Baba Z Buehler                            <baba@beckman.uiuc.edu>
          Bertrand Decouty-INRIA Rennes-France  <Bertrand.Decouty@irisa.fr>
          Bertrand Wallrich                    <Bertrand.Wallrich@loria.fr>
          Bjarne Steinsbo                                   <bjarne@hsr.no>
          Brad Greer                              <brad@cac.washington.edu>
          Carl Hilton                     <chilton@dns2.sac.usace.army.mil>
          Chao-Wen Young                            <kiki@eng.dowjones.com>
          Corey Minyard                           <minyard@wf-rch.cirr.com>
          Dave Alden                            <alden@math.ohio-state.edu>
          David M Clarke                         <dmc900@durras.anu.edu.au>
          Desmond Macauley                      <desmondm@eng.dowjones.com>
          Dirk Wrocklage                           <dirkw@uni-paderborn.de>
          Dorab Patel                                   <dorab@twinsun.com>
          Doug White                              <dwhite@gdi.uoregon.edu>,
          Dwaine C. Gonyier                 <virtual@panthra.catt.ncsu.edu>
          Ed Santiago                                        <esm@lanl.gov>
          Elliot Lee                                      <sopwith@cuc.edu>
          Eric C Hagberg                     <hagberg@mail.med.cornell.edu>
          Geoff Ballinger                          <geoff@chemeng.ed.ac.uk>
          George Harrach               <ghharrac@ouray.Denver.Colorado.EDU>
          George Lindholm                             <lindholm@ucs.ubc.ca>
          Greg Wohletz                                   <greg@cs.unlv.edu>
          Harlan Stenn                              <Harlan.Stenn@pfcs.com>
          Helmut Jarausch               <jarausch@igpm.igpm.rwth-aachen.de>
          Hendrik Klompmaker         <Hendrik.Klompmaker@Beheer.zod.wau.nl>
          Jan Barte                                 <yann@uni-paderborn.de>
          Jarrod Douglas                          <jarrod@cs.curtin.edu.au>
          Jens Thiel                 <thielj@athene.informatik.uni-bonn.de>
          Jon E. Ferguson                               <jon@media.mit.edu>
          Jos Backus                                           <jos@oce.nl>


          LPRng - Introduction                                           31









          Julian Anderson                            <jules@comp.vuw.ac.nz>
          Julian Turnbull                         <jst@dcs.edinburgh.ac.uk>
          Klaus Steinberger      <Klaus.Steinberger@Physik.Uni-Muenchen.DE>
          Lothar Butsch                              <but@unibw-hamburg.de>
          Marc Baudoin                            <Marc.Baudoin@hsc.fr.net>
          Martin Forssen                             <maf@math.chalmers.se>
          Marty Leisner                         <leisner@sdsp.mc.xerox.com>
          Michael Haardt           <u31b3hs@POOL.Informatik.RWTH-Aachen.DE>
          Michael Joosten                             <joost@ori.cadlab.de>
          Michel Robitaille                     <robitail@IRO.UMontreal.CA>
          Ole Benner                                       <olb@kom.auc.dk>
          Panos Dimakopoulos                               <dimakop@cti.gr>
          Paul Burry                                     <rpburry@magi.com>
          Paul Eggert                                  <eggert@twinsun.com>
          Paul Haldane                       <Paul.Haldane@edinburgh.ac.uk>
          Per Foreby                                      <perf@efd.lth.se>
          QingLong                                <qinglong@Bolizm.ihep.su>
          Rick Martin                                    <rickm@cs.umb.edu>
          Ron Roskens                                  <roskens@cs.umn.edu>
          Scott Sutherland                          <scott@math.sunysb.edu>
          Sherwood Botsford                    <sherwood@space.ualberta.ca>
          Stefan Monnier                    <stefan.monnier@lia.di.epfl.ch>
          Stefano Ianigro                         <w_stef@unibw-hamburg.de>
          Stuart Kemp                                <stuart@cs.jcu.edu.au>
          Sven Rudolph                              <sr1@inf.tu-dresden.de>
          Todd C. Miller                      <Todd.Miller@cs.colorado.edu>
          Zygo Blaxell                                 <zblaxell@myrus.com>

                                 Author Information
             Patrick  Powell  <papowell@sdsu.edu> is faculty in the Depart-
          ment of Computer and Electrical Engineering at  San  Diego  State
          University,  San  Diego  CA 92182, where he teaches Computer Net-
          works, Real Time Systems, and Distributed Computing.

                                     References
          Pow96. Patrick A. Powell, LPRng Version  3.1  -  README  and  MAN
             Pages, Dept. of Electrical and Computer Engineering, San Diego
             State    University,    San    Diego,    CA    92182,    1997.
             FTP://ftp.iona.ie    /pub/LPRng/,    FTP://   dickory.sdsu.edu
             /pub/LPRng/
          Pow95. Patrick A. Powell, LPRng - Introduction and Reference Man-
             ual,  Dept.  of Electrical and Computer Engineering, San Diego
             State    University,    San    Diego,    CA    92182,    1995.
             FTP://ftp.iona.ie    /pub/LPRng/,    FTP://   dickory.sdsu.edu
             /pub/LPRng/
          Cam94. Ralph Campbell, ``4.3BSD Line  Printer  Spooler  Manual,''
             4.4  Berkeley Software Distribution, Computer Systems Research
             Group, U.C. Berkeley, Berkeley CA, 1994.   USENIX  Association
             and O'Reilly & Associates, Inc.
          Pow95a. Patrick  A.  Powell,  ``PLP  -  The  Public  Line Printer
             Spooler Reference Manual,''  PLP  4.0  Software  Distribution,
             1995.  FTP://ftp. iona.ie/pub/plp-4.0
          McL90. Leo  J. McLaughlin III, RFC1179 Line Printer Daemon Proto-
             col, Internet Advisory Board, 1990.


          32                                           LPRng - Introduction









          GNU91. GNU, GNU General Public License, Free Software Foundation,
             Inc., 675 Mass. Ave. Cambridge, MA 02139, 1991.






















































          LPRng - Introduction                                           33




