LPD.PERMS(5)

πŸ‘‘ LPD.PERMS(5) πŸ’… β€” the lpd.perms file, section 5 of the manual

okay bestie come closer because this one is a whole thing and she's important πŸ’–


πŸ’– NAME πŸ’–

lpd.perms β€” the permissions control file for the LPRng line printer spooler system. yes. the file that decides who gets to print and who gets told no. main character energy fr πŸ‘‘


✨ DESCRIPTION ✨

okay so. the file lpd.perms is literally where you hand the LPRng Printer spooler system its permission information. that's her whole job. 🫢

Blank lines? ignored. everything from a hash sign (#) to the end of the line? also ignored. and if you actually want a hash sign to mean something in your permission info, you gotta escape it with a backslash (\). she's picky like that, no cap. πŸ™ˆ

every other line is a permissions entry, and it has to look like this:

ACCEPT [[not] key = value[,value]* ]*
REJECT [[not] key = value[,value]* ]*
DEFAULT ACCEPT
DEFAULT REJECT

Every single LPD service request gets checked against the entries in the permissions database or file. like, every one. nobody sneaks past. πŸ•΅οΈ

here's a typical permissions file, so you can see the vibe:

# Set default permissions
DEFAULT ACCEPT
# Reject any connections from outside our subnet
REJECT SERVICE=X NOT REMOTEIP=130.191.0.0/255.255.0.0
# Only accept spooling (LPR) from
# Engineering Lab or the Dean's office
REJECT SERVICE=R NOT REMOTEHOST=*.eng.sdsu.edu,dean.sdsu.edu
# Do not accept forwarded jobs for printing
REJECT SERVICE=R FORWARD
# Allow only the administrators control access
ACCEPT SERVICE=C,M REMOTEHOST=spooler.eng.sdsu.edu REMOTEUSER=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
# Allow users to check status
ACCEPT SERVICE=C LPC=status
# Require connection for other operations over UNIX socket
# not TCP/IP port.  Effectively requiring them to be made from the
# localhost
ACCEPT SERVICE=C UNIXSOCKET
REJECT SERVICE=C

# Variation - accept all spooled jobs,  but then apply
#  permissions checking when job is printed.  Allows
#  prevents remote spoolers from locking up trying resend
#  same request
ACCEPT SERVICE=R
REJECT SERVICE=P NOT REMOTEHOST=*.eng.sdsu.edu,dean.sdsu.edu

πŸ¦‹ how the checking actually works πŸ¦‹

Permission checking happens by using a set of keys (or fields) with associated values, and matching those against stuff to decide if you're allowed. πŸ’…

the SERVICE key takes these values:

  • P β€” printing (i.e.- unspooling)
  • R β€” spooling (i.e.- LPR request)
  • P β€” printing (i.e., after job has been spooled)
  • C β€” printer control (i.e. - LPC)
  • M β€” removal (i.e.- LPRM request)
  • Q β€” queue information (i.e.- LPQ request)
yes she lists P twice up there. that's literally what the page says. we don't make the rules, we just report them πŸ’€

and the X key is what gets used when checking for connection information. iykyk.


🌸 the lifecycle of a check 🌸

So at the very start, all of the keys have undefined or NULL values β€” they're empty, they're nothing, they're a blank canvas ✨ β€” and they get assigned values during the permissions checking process.

when a connection is made to the server, it assigns the REMOTEHOST key (alias REMOTEIP) the list of IP addresses and hostnames determined by doing a reverse Domain Name Service (DNS) lookup on the remote host's IP address. and if the reverse DNS fails? then only the IP address gets used. periodt. πŸ’€

the REMOTEPORT key (PORT is an alias for REMOTEPORT, bestie, don't forget) gets assigned the port number of the connection origination.

the UNIXSOCKET key will match (be true) if the connection is over a UNIX socket. by convention, this is from the localhost. 🏠

and finally the SERVICE value is assigned X, and the lpd server checks the database to see if the connection is accepted or rejected. vibe check complete. βœ…


then the server reads the request information from the connection. πŸ‘€

if the request is for an authenticated data transfer, the server invokes the appropriate authentication mechanism, which assigns:

  • AUTH a true (or matching) value
  • AUTHTYPE the type of authentication
  • AUTHUSER the authenticated user id value, which may differ from the actual user name
  • AUTHFROM the authenticated identification of the originator of the request, which may be a server if the request is forwarded

next, the SERVICE value gets set to R, C, M, or Q depending on whether it's an LPR, LPC, LPRM, or LPQ request β€” and the LPC value gets set to the requested LPC command if it was an LPC request. πŸ“

  • if the request contained a user name, then REMOTEUSER is set to this name
  • if the request contained a printer name, then PRINTER is set to the printer name
  • if the request is a print request, then the HOST value is set to the list of host names and IP addresses given by a DNS lookup of the value in the H field of the job

the database gets scanned again to determine if the operation can be performed on the requested queue. and to simplify rule writing (thank u for that 🫢), if the operation requires modification or checking of individual jobs β€” like the LPC, LPQ, or LPRM commands β€” then the various checks that depend on jobs will succeed in this step.


finally πŸ’« if the operation requires modification or checking of individual jobs (yes, again the LPC, LPQ, or LPRM commands), then the specified print queue is scanned, and for each job in the print queue, the HOST and USER values are set to the host and user values in the control file for the job.


πŸŽ€ how the database is checked πŸŽ€

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 the search terminates with the specified action (ACCEPT/REJECT). 🏁

if no match is found, the default permission value is used. the DEFAULT key is what specifies the current default permission β€” used for successful matches, or if there's no match at all after scanning the entire permissions database. so she always has an answer, bestie. always. πŸ’…


🧚 a few extra keys that go hard 🧚

The following keys provide some additional checking capabilities:

  • REMOTEGROUP β€” checks that the REMOTEUSER value appears in a group or netgroup entry in the system database
  • GROUP β€” same deal but for the USER value

like, for example, GROUP=student*,staff* would check to see if any of the group names matching student* or staff* have the specified user name in them. 🌈

and if a system has the netgroups capability, a printer, group, or remotegroup name starting with a @ will be treated as a netgroup name, and the specified user name or printer will be checked to see if it is in the group. cute. ✨


πŸ”₯ the boolean besties πŸ”₯

  • SERVER β€” true (match) if the request originated from the print server
  • SAMEHOST β€” true (matches) if the REMOTEHOST and HOST values have a common entry, i.e. - are the same host
  • SAMEUSER β€” true (matches) if the REMOTEUSER and USER values are identical
  • AUTHSAMEUSER β€” true (matches) if the AUTHUSER value that originated the request and the AUTHUSER which was used to transfer a job are identical
  • AUTHJOB β€” true (matches) if the job was transferred using authentication
  • FORWARD β€” an alias for NOT SAMEHOST

πŸ“ the CONTROLLINE moment πŸ“

the CONTROLLINE value can be used to determine if there's a matching line in the control file. this facility has been used to ensure that jobs contain various information fields in order to be printed. very "check her receipts" of it. πŸ’…


πŸ‘‘ THE BIG TABLE πŸ‘‘

here she is. the whole grid. all of it. no skips, no summarizing, we are not playing about this one:

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
REMOTEPORT   N     PORT    PORT  -      PORT PORT  PORT
REMOTEUSER   S     -       JUSR  JUSR   JUSR CUSR  CUSR
REMOTEHOST   S     RH      RH    JH     RH   RH    RH
UNIXSOCKET   V     SK      SK    SK     SK   SK    SK
REMOTEGROUP  S     -       JUSR  JUSR   JUSR CUSR  CUSR
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
AUTH         V     -       AU    -      AU   AU    AU
AUTHTYPE     S     -       AU    -      AU   AU    AU
AUTHUSER     S     -       AU    -      AU   AU    AU
AUTHSAMEUSER S     -       AU    -      AU   AU    AU
AUTHFROM     S     -       AU    -      AU   AU    AU
AUTHJOB      V     -       AU    -      AU   AU    AU
  PORT is alias for REMOTEPORT
  REMOTEIP is alias for REMOTEHOST
  IP is alias for HOST

okay and now the legend, because those abbreviations are not self-explanatory and she knows it 🌸

KEY:
   JH = HOST          host in control file
   RH = REMOTEHOST    connecting host name/IP
   JUSR = USER        user in control file
   CUSR = REMOTEUSER  user from control request
   JIP= IP            host/IP addr of host in control file
   RIP= REMOTEIP      host/IP addr of requesting host
   PORT=              connecting host origination port
    SK=  match if connection over a UNIX socket
   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 from same address as server
   AU= value determined by server authentication operation
                      AUTH is true if authenticated transfer,
                      TYPE is set to the type of authentication (kerberos, etc)
                      AUTHUSER is user authentication id
                      AUTHFROM is sender authentication id (can be remote server)
                      AUTHSAMEUSER matches if remote user authentication id matches original
                      user authentication id
                      AUTHJOB it true if print job has authentication

and the match-type / service legend too, obviously πŸ’…

Match: S = string with wild card, IP = IP address[/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
   'U' - administratively allowed user operation
NOTE: when printing (P action), the remote and job check values
   (i.e. - RUSR, JUSR) are identical.

🌈 the special letter=patterns move 🌈

so there's this special key form, letter=patterns, and what it does is search the control file line starting with the (upper case) letter. it's 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. see? iconic. πŸŽ€


πŸ’œ how a permission line is built πŸ’œ

A permission line consists of a list of tests and a result value. if all of the tests succeed, then a match has been found and the permission testing completes with the result value. πŸ†

you use the DEFAULT reserved word to set the default ACCEPT/DENY result.

and the NOT keyword? it reverses the sense of a test. so NOT really said "flip that for me bestie" πŸ”„

Each test can have one or more optional values separated by commas. for example USER=john,paul,mark has 3 test values. three of them! and the Match value is what specifies how the matching is done. ⭐


okay and we are not done yet β€” there is literally more of this page coming, so hold that thought πŸ’–

  • S β€” string type match, aka a string match with glob energy ✨ Format: a string with wildcards (*), and that lil * matches 0 or more chars. Character comparison is case insensitive, bestie. For example β€” USER=th*s matches uTHS, This, This, Theses. yes the same example twice, that's what it says, don't come for me πŸ’…
  • IP β€” IP address and submask. The IP address must be in dotted form, no shortcuts. Format: x.x.x.x[/y.y.y.y or /z]
    • x.x.x.x is the IP address
    • y.y.y.y is an optional submask, default is 255.255.255.255
    • z is a netmask with the most significant z bits set The match is done by turning the IP address into a 32 bit value and using:
success = ((x ^ IP ) & y) == 0   (C language notation)

i.e. β€” only the bits where the mask is non-zero are used in the comparison, periodt. For example β€” IP=130.191.0.0/255.255.0.0 matches all address 130.191.X.X, and IP=130.191.0.0/16 has the same value 🫢

  • N β€” numerical range, a low-high integer range. simple as that. Format: low[-high] Example: PORT=0-1023 matches a port in range 0 - 1023 (that's the privileged zone, iconic) πŸ”₯

The authentication entries AUTH, AUTHTYPE, AUTHUSER, AUTHSAMEUSER and AUTHFROM can be used to check permissions for authenticated operations. AUTH is set (true) if authentication was done. We can use this to reject non-authenticated transfers:

REJECT NOT AUTH

The AUTHTYPE will match the authentication type being used or requested by the remote client or server. The AUTHUSER matches the original client authentication information used by the client to make a request to the server, and the AUTHFROM matches the sender authentication information. The AUTHSAMEUSER will match if the remote client or user authentication id is the same as that used for the job generation. πŸ’œ

πŸŽ€ LPC=OP πŸŽ€

The LPC=op entry is useful to allow various users to perform administration operations. The following permissions entry would allows users to hold or release their own jobs:

ACCEPT SERVICE=C SAMEUSER SAMEHOST LPC=release

🌈 DNS, IPV6, AND MULTIHOMED HOSTS 🌈

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. lowkey a whole identity crisis fr fr 😭

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. so generous of it honestly πŸ‘‘


πŸ’– 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/lprng/lpd.conf β€” LPRng configuration file
  • ${HOME}/.printcap β€” user printer description file
  • /etc/printcap β€” printer description file
  • /etc/lprng/lpd.perms β€” permissions
  • /var/run/lprng/lpd β€” lock file for queue control
  • /var/spool/lpd β€” spool directories
  • /var/spool/lpd/QUEUE/control β€” queue control
  • /var/spool/lpd/QUEUE/log β€” trace or debug log file
  • /var/spool/lpd/QUEUE/acct β€” accounting file
  • /var/spool/lpd/QUEUE/status β€” status file

✨ SEE ALSO ✨

lpd.conf(5), lpc(8), lpd(8), checkpc(8), lpr(1), lpq(1), lprm(1), printcap(5), pr(1), lprng_certs(1), lprng_index_certs(1).

πŸ‘‘ AUTHOR πŸ‘‘

Patrick Powell <papowell@lprng.com>.

🌸 HISTORY 🌸

LPRng is a enhanced printer spooler system with functionality similar to the Berkeley LPR software. The LPRng developer mailing list is lprng-devel@lists.sourceforge.net; subscribe by visiting https://lists.sourceforge.net/lists/listinfo/lprng-devel or sending mail to lprng-request@lists.sourceforge.net with the word subscribe in the body.

The software is available via http://lprng.sourceforge.net πŸ¦‹


okay bestie that's the whole thing, we ate and left absolutely no crumbs πŸ’… This was the LPRng version of LPD.PERMS(5), dated 2006-12-09 β€” go forth and configure your permissions, you main character 🫢✨

πŸ“¦ where this page comes from