Team BBL
Previous Page Next Page

21.4. Printer Spooling

The programs that we develop in this chapter form the basis of a simple printer spooler. A simple user command sends a file to the printer spooler; the spooler saves it to disk, queues the request, and ultimately sends the file to the printer.

All UNIX Systems provide at least one print spooling system. FreeBSD ships LPD, the BSD print spooling system (see lpd(8) and Chapter 13 of Stevens [1990]). Linux and Mac OS X include CUPS, the Common UNIX Printing System (see cupsd(8)). Solaris ships with the standard System V printer spooler (see lp(1) and lpsched(1M)). In this chapter, our interest is not in these spooling systems per se, but in communicating with a network printer. We need to develop a spooling system to solve the problem of multiuser access to a single resource (the printer).

We use a simple command that reads a file and sends it to the printer spooler daemon. The command has one option to force the file to be treated as plaintext (the default assumes that the file is PostScript). We call this command print.

In our printer spooler daemon, printd, we use multiple threads to divide up the work that the daemon needs to accomplish.

  • One thread listens on a socket for new print requests arriving from clients running the print command.

  • A separate thread is spawned for each client to copy the file to be printed to a spooling area.

  • One thread communicates with the printer, sending it queued jobs one at a time.

  • One thread handles signals.

Figure 21.6 shows how these components fit together.

Figure 21.6. Printer spooling components


The print configuration file is /etc/printer.conf. It identifies the host name of the server running the printer spooling daemon and the host name of the network printer. The spooling daemon is identified by a line starting with the printserver keyword, followed by white space and the host name of the server. The printer is identified by a line starting with the printer keyword, followed by white space and the host name of the printer.

A sample printer configuration file might contain the following lines:

         printserver  blade
         printer      phaser860

where blade is the host name of the computer system running the printer spooling daemon, and phaser860 is the host name of the network printer.

Security

Programs that run with superuser privileges have the potential to open a computer system up to attack. Such programs usually aren't more vulnerable than any other program, but when compromised can lead to attackers obtaining full access to your system.

The printer spooling daemon in this chapter starts out with superuser privileges in this example to be able to bind a socket to a privileged TCP port number. To make the daemon less vulnerable to attack, we can

  • Design the daemon to conform to the principles of least privilege (Section 8.11). After we obtain a socket bound to a privileged port address, we can change the user and group IDs of the daemon to something other that root (lp, for example). All the files and directories used to store queued print jobs should be owned by this nonprivileged user. This way, the daemon, if compromised, will provide the attacker with access only to the printing subsystem. This is still a concern, but it is far less serious than an attacker getting full access to your system.

  • Audit the daemon's source code for all known potential vulnerabilities, such as buffer overruns.

  • Log unexpected or suspicious behavior so that an administrator can take note and investigate further.

    Team BBL
    Previous Page Next Page