prqd(1) - Linux man page

Name

prqd - Print quota enforcement daemon

Synopsys

prqd

Description

Prqd can be used in conjunction with LPRng to enforce print quota by limiting the number of pages users can print on a queue.

Limits can be set in general (for all users), based on UNIX group membership and individually. Additionally users can have a personal print account.

This is useful in public computer labs in schools and universities. All students are allowed to print a limited number of pages per semester as required in the courses. The limit expires at the end of each semester. Additionally users can have a personal print account for private purposes. Print accounts do not expire.

Printing is allowed if at least one of the following conditions is true:

The user has not yet reached the limit or
there is a positive number of pages in the personal print account.

Options

The program does not use any options.

Return Value

The program returns 0 on success, positive values on errors.

Diagnostics

The program writes log messages to ${prefix}/var/log/prqd/prqd.log, typically /usr/local/var/log/prqd/prqd.log.

Files

Configuration file structure

When entering service mode the program reads the configuration file ${prefix}/etc/prqd/prqd.conf, typically /usr/local/etc/prqd/prqd.conf.

The configuration file consists of a list of sections, typically there is one options section and a number of class and printer sections. Each section is introduced by the section header in square brackets. The section contents is a number of lines, each line contains one key/value pair. Key and value are separated by ''=''.

The options section sets general options for the daemon itself.

A class section contains limit information for a class of printers (a group of printers).

The printer sections assign a class to each printers. Optionally each printer can be given a number of aliases. Aliases must match the aliases specified in the printcap file.

The options section

The options section is started by the [options] section header. The following lines are allowed:
database = type:name
specifies the type (''ndbm'', ''gdbm'' or ''bdb'') of the database backend and the name of the database file.
socket = name
specifies the file name for the UNIX domain socket used for communication between prqd and the clients (prqdcl, prqdadm and prqdinfo).
socket timeout = timeout
specifies the timeout for socket operations in seconds.
user information directory = name
specifies the directory name for user information files.
run as user = uname
specifies the user name used to run prqd in service mode.
run as group = gname
specifies the group name used to run prqd in service mode.

Class sections

Class sections are started by [class name] section headers.

The following lines can occur in class sections:

limit = limit-value
specifies a limit. The limit-value can have the following structure:
default:limit
specifies the general limit.
group:gname:limit
specifies the limit for a UNIX user group.
user:user:limit
specifies the limit for one user.
The limit can be either a number, or ''deny'' or ''unlimited''.
deny action = action
specifies the action to take when printing is denied. The action can be either ''remove'' or ''hold''.
write user information = boolean
specifies whether or not to write user information files for this printer class.

Printer section

A printer section is started by the [printer name] section header. It can contain the following lines:
class = name
assigns a printer class to that printer.
alias = name
assigns an alias to the printer.

Examples

Example situation

A university faculty has two PC labs equipped with networked printers lp1 and lp2. Students can print up to 200 pages per semesters on both printers in summary. Faculty stuff is allowed to print unlimited.

In a centralized equipment root there is a color laser printer and a copier. Faculty staff has unlimited access to both printers, students are not allowed to use these printers.

The print server host running LPRng is named ps. We decide to run prqd on the same host, so we can use the pipe mechanism for communication between LPRng and prqdcl (this is more secure than using network connections).

Here is an excerpt from /etc/hosts:

192.168.101.33        lp1
192.168.101.34        lp2
192.168.101.35        lpcolor
192.168.101.36        copier
192.168.101.65        ps
The copier can be used both manually and as a networked printer. So we can not do reliable accounting (a user can start a copy job manually on the machine before fsnmp succeeded to retrieve the page count). But we want to use prqd to allow access to copier for staff members and to deny access for students.

Example printcap file

lp1
      :client
      :force_localhost@
      :lp=lp1@ps.my-domain.com
lp2
      :client
      :force_localhost@
      :lp=lp2@ps.my-domain.com
lpcolor
      :client
      :force_localhost@
      :lp=lpcolor@ps.my-domain.com
copier
      :client
      :force_localhost@
      :lp=copier@ps.my-domain.com
lp1
      :server:oh=ps.my-domain.com
      :sd=/var/spool/lprng/lp1
      :sh
      :mx#0
      :lp=/dev/null
      :af=|/usr/local/bin/prqdcl
      :achk
      :filter=/usr/local/libexec/filters/fsnmp
lp2
      :server:oh=ps.my-domain.com
      :sd=/var/spool/lprng/lp2
      :sh
      :mx#0
      :lp=/dev/null
      :af=|/usr/local/bin/prqdcl
      :achk
      :filter=/usr/local/libexec/filters/fsnmp
lpcolor
      :server:oh=ps.my-domain.com
      :sd=/var/spool/lprng/lpcolor
      :sh
      :mx#0
      :lp=/dev/null
      :af=|/usr/local/bin/prqdcl
      :achk
      :filter=/usr/local/libexec/filters/fsnmp
copier
      :server:oh=ps.my-domain.com
      :sd=/var/spool/lprng/copier
      :sh
      :mx#0
      :lp=192.168.101.36%9100
      :af=|/usr/local/bin/prqdcl
      :achk

Example fsnmp.conf file

[lp1]
lp                            =       192.168.101.33%9100
snmp version                  =       1
snmp community                =       public
ctrl-d at end                 =       yes
shutdown data socket          =       no
minimum pagecount time        =       30
data transfer port range      =       9100 9110
accounting destination        =       |/usr/local/bin/prqdcl

[lp2]
lp                            =       192.168.101.34%9100
snmp version                  =       1
snmp community                =       public
ctrl-d at end                 =       yes
shutdown data socket          =       no
minimum pagecount time        =       30
data transfer port range      =       9100 9110
accounting destination        =       |/usr/local/bin/prqdcl

[lpcolor]
lp                            =       192.168.101.35%9100
snmp version                  =       1
snmp community                =       public
ctrl-d at end                 =       yes
shutdown data socket          =       no
minimum pagecount time        =       30
data transfer port range      =       9100 9110
accounting destination        =       |/usr/local/bin/prqdcl

Example prqd.conf file

[options]
database                      =       ndbm:/var/prqd/prqd
socket                        =       /var/run/prqd/prqd.sock
socket timeout                =       1.5
user information directory    =       /opt/printing
run as group                  =       daemon
run as user                   =       prqdu

[class staff-pr]
limit                         =       default:deny
limit                         =       group:staff:unlimited
limit                         =       user:root:unlimited

[class stud-pr]
limit                         =       default:200
limit                         =       group:staff:unlimited
limit                         =       user:root:unlimited

[printer lp1]
class                         =       stud-pr

[printer lp2]
class                         =       stud-pr

[printer lpcolor]
class                         =       staff-pr

[printer copier]
class                         =       staff-pr

Example explaination

In the printcap file we tell LPRng not to send print job data directly to the printers, instead data is passed to the fsnmp print filter. LPRng must not open a network connection to the printer, for some printers this would cause problems when attempting to retrieve the printer status (Some printers change the status to ''busy'' immediately after a network connection is established. Fsnmp waits for the printer to become ''ready'' before asking for the page count.). So LPRng opens the /dev/null device, not a network connection to the printer.

Both LPRng and fsnmp pass accounting information to the prqdcl program. When LPRng starts a print job it sends a ''jobstart'' request to prqdcl and waits for a response. The response '' ACCEPT '', '' HOLD '' or '' REMOVE '' decides whether or not the print job data is transferred to the printer, kept in the queue or removed.

The printers have built-in support for SNMP version 1. The SNMP community is ''public''. The filter ensures that the last byte sent to the printer is a CTRL-D.

Fsnmp connects to port 9100 on the printers. The source port must be in the range from 9100 to 9110. Our printers do not support a clean shutdown of TCP/IP connections.

If the page count did not change during a print job, fsnmp checks for 30 seconds whether or not the printer changes the state from ''ready'' to ''busy'' again.

Prqd uses an NDBM database stored in /var/prqd. The file name prqd will result in a prqd.dir and a prqd.pag file in that directory for NDBM databases.

User information files are crated in /opt/printing. This directory must be writable for users prqdu from group daemon because prqd changes the current user and group before entering service mode.

We have two printer classes:

staff-pr
The printers usable by staff members only. Access to printers in this class is denied generally, but members of the UNIX user group ''staff'' are allowed to print unlimited, user root too.
stud-pr
The printers for use by students in the PC labs. The general limit is 200 pages. Members of the ''staff'' group and the user ''root'' can print unlimited.

See Also

fsnmp(1), LPRng, http://dktools.sourceforge.net/prqd.html

Author

Dipl.-Ing. Dirk Krause

Copyright And License

Copyright © 2007-2008, Dirk Krause All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above
  copyright notice, this list of conditions and the
  following disclaimer.

* Redistributions in binary form must reproduce the above
  copyright notice, this list of conditions and the following
  disclaimer in the documentation and/or other materials
  provided with the distribution.

* Neither the name of the Dirk Krause nor the names of
  contributors may be used to endorse or promote products
  derived from this software without specific prior written
  permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS " AS IS " AND ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED . IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT , INDIRECT , INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE , DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .

Referenced By

prqdcl(1)