LPRng-HOWTO: Authentication and Encryption

Next Previous Contents

## 12. Authentication and Encryption

One of the major problems in a print spooler system is providing privacy and authentication services for users. One method is to construct a specific set of protocols which will be used for providing the privacy or authentication; another is to provide a simple interface to a set of tools that will do the authentication and/or encryption. The LPRng system adopts this latter approach.

## 12.1 Authentication

A careful study of the authentication problem shows that it should be done during reception of commands and/or jobs from a remote user and/or spooler. At this time the following must be done:

1. The received command must be checked for consistency, and the remote user and host must be determined.
2. The remote user and host must be authenticated.
3. The command and/or spooling operation must be carried out.
4. The results must be returned to the remote system.

## 12.2 Identifiers

When a user logs into a system, they are assigned a user name and a corresponding UserID. This user name is used by the LPRng software when transferring jobs to identify the user.

When we look into the problem of authentication, we will possibly have a more global user identification to deal with, the authentication identifier (AuthID). One way to deal with this problem is to give LPRng intimate knowledge of the UserID and AuthID relationship. While this is possible, it may be difficult to deal with in a simple and extensible manner. An alternate solution is to provide a mapping service, where the authentication procedure provides a map between the UserID and AuthID.

## 12.3 RFC1179 Protocol Extensions

The RFC1179 protocol specifies that a LPD server command sent on a connection has the form:

    \nnn[additional fields]\n

`\nnn` is a one octet (byte) value with the following meaning:

    REQ_START   1    start printer
    REQ_RECV    2    transfer a printer job
    REQ_DSHORT  3    print short form of queue status
    REQ_DLONG   4    print long form of queue status
    REQ_REMOVE  5    remove jobs

The LPRng system extends the protocol with the following additional types:

    REQ_CONTROL 6    do control operation
    REQ_BLOCK   7    transfer a block format print job
    REQ_SECURE  8    do operation with authentication

The REQ_CONTROL allows a remote user to send LPC commands to the server. The REQ_BLOCK provides an alternate method to transfer a job. Rather than transferring the control and data files individually, this format transfers one file. The REQ_AUTH provides a mechanism for providing an authentication mechanism and is described in this document.

## 12.4 Client Operations for Client To lpd Server Authentication

Options used:

- `use_auth=`Authentication type
- `default_auth=`Default authentication type
- `remote_user=`Remote server identification
- `server_user=`Server identification
- `user_auth_command=`User to server authentication program

1. First, the `use_auth` option is checked to see if it specifies an authentication type. If it does, then the `use_auth` value is used to identify the type of authentication to be done.
2. If, by using a command line flag to the `lpr`, `lpq`, etc program, the user specifies that an authenticated transfer is to be done and the `use_auth` value is not set, then `use_auth` is set to the `default_auth` value.
3. If after the above actions `use_auth` has a value, then an authenticated transfer will be done.
4. Some sort of identifier specific to the remote system must be provided to the authentication facility. For client to server operations, the remote system is identified by the `remote_user` and `server_user` printcap option values. If the `remote_user` value is not specified, then it will be set to `server_user` (default `daemon`). As discussed below, the `server_user` is usually used to identify the `lpd` server on an originating host, but a general form of identification can be used.
5. The `userid` is the value obtained by using the current UID of the program as the search value for `getpwuid()`.
6. The client will open a connection to the server and sends a command with the following format:

       \008printer C userid use_auth\n          - for commands
       \008printer C userid use_auth controlfilename\n - for print jobs

   Note that \008 is a one byte code indicating an authenticated transfer. Printer is the spool queue name, C in the character 'C' indicating a client request, userid is the login id of the user, use_auth is a keyword identifying the authentication type, and controlfile name is the name of a controlfile to be transferred.

7. On reception of this command, the server will send a one byte success code. If an error is indicated by a non-zero response, additional error status may follow the non-zero success code byte. At the end of this information the connection will be terminated. The values used by LPRng are:

          ACK_SUCCESS 0   success
          ACK_STOP_Q  1   failed; no spooling to the remote queue
          ACK_RETRY   2   failed; retry later
          ACK_FAIL    3   failed; job rejected, no retry

   If the success code is zero, the sender or client will start the client side authentication program specified by the `user_auth_command` option. This program will be passed the same options as normal filter program. See Filters for details. The authentication program will have the following IO assignments:

       FD  Options Purpose
       0  R/W     socket connection to remote host (R/W)
       1  W       pipe or file descriptor,  for responses to client
       2  W       error log

   Command line arguments:

       program -C -Pprinter -nuser -asend_auth -Rremote_user -Ttempfile

   The authenticator program can create additional temporary or working files with the pathnames `tempfile.ext`; these will be deleted after the authentication process has been completed.

   The command line arguments will undergo replacement of %H and %R values. This means that when authenticating to host nowhere.com, a `remote_user=lpr@%R` will be expanded to `remote_user=lpr@`nowhere.com.

8. If the authentication type is for a built-in type, then the built-in facilities will be used. Commonly built-in facilities are `kerberos` authentication. The same actions are carried out.
9. The `tempfile` will contain either a command line as would be transferred using the standard RFC1179 protocol, or a print job in block format. See RFC1179 Protocol for details. The client authenticator program will open and transfer the contents of `tempfile` to the server authenticator, using FD 0 and a format compatible with the underlying authentication mechanism.

   If the transfer fails the client authenticator will log error information on FD 2 and then exit with error code JFAIL.

10. The server will send the client authentication program any error or logging information over the FD 0 connection, in a form appropriate to the authentication operation. The client authenticator will write this information to FD 1. If data transfer or authentication fails, the authenticator will write an error message to FD 2 and exit with error code JFAIL
11. If no error has occured the client authenticator will then exit with error code JSUCC.

## 12.5 Server Operations for Client To lpd Server Authentication

Options used:

- `server_auth_command=`Server (lpd) authentication program

1. When an authentication command arrives at the server, it has the following form:

       \008printer C userid use_auth\n          - for commands
       \008printer C userid use_auth controlfilename\n - for print jobs

   The server will decode the various fields, and set the following permission keys:
   PRINTER=`printer`
   USER=`user`
   AUTHTYPE=`use_auth`
   AUTH=`USER`

2. The server will attempt to find the printcap for the specified printer. For some operations this printer will be a dummy entry; this will simply cause the following operations to use the default information in the `lpd` configuration.
3. If a print job is being performed and the spool queue does not exist, then the job will be rejected. A non-zero error code will be written to the connection and the operation will terminate.
4. If the AUTHTYPE is not built in, and the `server_auth_command` value is not specified, then authentication will fail.

   An error message will be logged to the server log file, and a non-zero error code and message will be written to the connection to the remote client program.

5. If the authentication program exists, a 0 success code is written to the connection and authentication proceeds. (Note that the client side of the authentication will use this as an indication to start the client side authentication program).
6. Many authentication programs require that the users provide some form of key or identification. The `server_user` option is used for this purpose. If there is no value specified, `server_user` is set to the `user` (default `daemon`) option value.
7. The server will start the server authenticator program and provide the following open file descriptors for it. The program will run as the same UID as the `lpd` server. If this is a print job transfer, the current directory will be the spool directory of the print queue.

       FD  Options Purpose
       0  R/W     socket connection to remote host (R/W)
       1  W       pipe or file descriptor,  for information for server
       2  W       error log
       3  R       pipe or file descriptor,  for responses to client

   Command line arguments:

       program -S -PPRINTER -nUSER -aAUTHTYPE -Rserver_user -Ttempfile

   The authenticator can create additional temporary or working files with the pathnames tempfile.ext; these will be deleted after the authentication process has been completed.

8. After performing the necessary authentication operations, the client side authenticator will transfer a file containing either commands or a print job to the server side authenticator. The server authenticator will put this file in the specified `tempfile`.

   In order for the LPRng software to perform permissions checking, it needs an authenticated identifier for the user. The server authenticator will write such an identifier to FD 1. This should be a single line, of a maximum of 127 characters (LPRng LINEBUFFER maximum size), i.e.:

       authentication_info\n

   If the transfer step or authentication fails, then the server authenticator will write an error message to FD 2 and exit with error code JFAIL.

9. The `lpd` server will record the authentication information returned by the server in the AUTHUSER permissions key.

   If a print job is being transferred, it will also be stored in the control file. This allows job forwarding as is discussed below.

10. The `lpd` server will perform the usual permissions checks, with the addition of the indicated permission keys and associated values. During this process, any error messages or logging information normally returned to client programs will be written to the authentication program FD 3.
11. The `lpd` server will carry out either the commands or print job specified in the temporary file. During this process, any error messages or logging information normally returned to client programs will be written to the authentication program FD 3.
12. At the end of the remote servers operations, the FD 3 file descriptor will be closed and the `lpd` server will wait for the authentication process to exit.
13. The server authentication process will read input from FD 3 until the end of input, and then transfer the received information to the client side authenticator. It may use the tempfile to hold the information during the reading and transfer process.

    If the transfer of the logging information fails, then the authenticator process will exit with error code JFAIL, otherwise it will exit with error code JSUCC.

## 12.6 lpd Server to Server Authentication

Options used:

- `forward_auth=`Server forwarding authentication type

The Server to Server authentication procedure is used by one server to forward jobs or commands to another server. It should be noted that this forwarding operation puts an implicit trust in the security of the client to server to server chain.

1. The `lpd` server will perform an authenticated transfer to another server when it either needs to transfer a job to a remote printer or when it needs to propagate a `lpq`, `lprm`, or `lprc` operation. The <tt>remote_support</tt> command can be used to control this forwarding operation.
2. When propagating a command, the server uses the authentication information provided for the remote user by the client to server authentication program. When propagating or forwarding a job, the server will use the authentication information stored in the job control or hold file. This information will be represented as AUTHUSER in the following discussion.
3. The identification for the sending server and receiving server for the authentication programs is generated. For the sending server, the `server_user` value is used. If it is not specified, the `server_user` value is set to the `user` (default `daemon`) value. For the remote server, the `remote_user` value is used. If it is not specified, the `remote_user` value is set to the `user` (default `daemon`) value.
4. If there is no user authentication information, then a normal, non-authenticated transfer will be done.
5. The `server_auth_command` will be used for the forwarding operation. If it does not have a value, then a normal, non-authenticated transfer will be done.
6. The sending server takes the part of the client, and will transfer a job acting similar to a client. The initial information transfer from the sending server will have the format:

       \008printer F server_user authtype \n          - for commands
       \008printer F server_user authtype controlfilename\n - for print jobs

7. The sending server will invoke its authenticator with the arguments:

       server_auth_command -F -Pprinter -nserver_user -aauthtype \
           -Rremote_user -Ttempfile

8. The tempfile containing the job or command information to be sent will have the form:

       user_authentication\n
       <normal file contents>

   That is, the user authentication information is place in the tempfile.
9. The tempfile will be transferred to the remote server in the same fashion as for a user job. Any error or logging information returned will either be written to the `lpd` log file or to the previous `lpd` process in the transfer chain.
10. On the destination server the same operations for receiving an authentication request from a client is performed. The USER and AUTHTYPE values will be the derived from the authentication request `server_user` and `authtype` fields in the command sent to the server. The `server_user` value is obtained as for client to server transfers. The server side authenticator is invoked with the arguments:

        server_auth_command -S -Pprinter -nUSER -aAUTHTYPE \
           -Rremote_user -Ttempfile

11. As for client to server operations, the authenticator will write the authenticated user name on FD 1, and the FWDUSER is set to this value.
12. The `lpd` server will remove the first line of the transferred file, which contains the user authentication information, and set AUTHUSER to this value.
13. Authentication is performed using the indicated values.
14. If authentication succeeds, then the command line or print job control file is processed in the normal manner. This might now add more permissions values to tags, but the authentication information will not be changed.

## 12.7 Permission Checking

The following patterns and values can be used to check that a particular type of authentication has been used, and what the authenticated user information is.

- AUTH=[NONE,USER,FWD] - authentication
  Values can be:

      AUTH=NONE     - no authentication
      AUTH=USER     - authentication from a client
      AUTH=FWD      - forwarded authentication from a lpd server

- AUTHUSER=globmatch

  For a command received from a client, the value is auth_user information returned by the authenticator

  For a command received from a server (i.e.- forwarded by a server), the value is the original auth_user_id determined by the remote server.

- FWDUSER=globmatch

  For a command received from a server (i.e.- forwarded by a server), the value is the the forwarding servers authentication information.

For example, to reject non-authenticated operations, the following line could be put in the permissions file.

    REJECT AUTH=NONE

To reject server forwarded authentication as well, we use:

    REJECT AUTH=NONE,FWD

If a remote server has id information FFEDBEEFDEAF, then the following will accept only forwarded jobs from this server. Note that AUTHUSER will only match on authenticated transfers; FWDUSER will only match on forwarded transfers.

    ACCEPT FWDUSER=FFEDBEEFDEAF
    REJECT AUTH=FWD

## 12.8 Using PGP for Authentication

PGP is a well known encryption and authentication program. For more details see the web site http://www.pgp.net or the ftp site ftp://ftp.pgp.net.

### authenticate_pgp

The `LPRng/src/AUTHENTICATOR/authenticate_pgp.sh` program uses the standard `pgp` program and facilities to do authentication. It uses the following `pgp` key organization.

1. Each user should have a private keyring in their home directory, in the /.pgp directory, i.e. - the default used by PGP. The users public key identification should have the format:

       User Name <userid@host> <userid1@host> ...

   `userid` must be the userid used for submitting jobs. Note that that different userids can be put into the key string as long as there is one entry for each userid that the user has.

   For example, suppose that user John Smith has several accounts on different hosts: john, jsmith, jsmith1. Then his key should have in it:

          John Smith <john@whereever> <jsmith@nowhere> <jsmith1@whatever> ...

   If the user is daring, then the pass phrase can be put in the file: `~/.pgp/clientkey` . This file will be read by the `authenticate_pgp` script and the contents passed to PGP as the key.

   This file MUST have 0400 permissions (read only by user) and MUST owned by the user. This is very dangerous; but so is setting the PGPPASS environment variable.

2. Each server must have a private keyring for user daemon, or whatever you run the LPD server as. This must be in the in the `~daemon/.pgp` directory, i.e. - the default used by PGP. The daemon public key identification should have the format:

       daemon_hostname daemon <daemon_hostname@hostname>

   In addition, the pass phrase for the daemon user must be put in the file `~daemon/.pgp/serverkey`.

   Note: you may have one daemon user with the same key for ALL servers, or you may have different ones for different servers.

3. Each user who wants to send jobs to the server must have the daemons public key on their public keyring. The server must have their public key on its public keyring.
4. When a job is submitted, the server will search for the users public key using the username submitted by the LPRng client. This will be the same as their login name.
5. The LPRng software searches the printcap database for the tag to be used for the server key lookup. The :server_user: value is checked for first; if it is not found the configuration user value (default 'daemon') is used.

### Installing authenticate_pgp

By default, the `authenticate_pgp` script and several helper programs, `readfilecount` and `removeoneline`, will be installed in the standard executable locations.

### Printcap/Configuration Modifications

You must set the following printcap and/or configuration variable to on. Note that the printcap keys override the configuration keys.

    user_auth_command=/usr/local/.../authenticate_pgp
    use_auth=pgp
    server_auth=pgp
    server_user=daemon_id_for_server
    pass_env=PGPPASS,PGPPATH

Example printcap entry:

    pr:
        :lp=pr@wayoff
        :use_auth=pgp
        :server_auth=pgp
        :server_user=daemon_wayoff

### Permissions Modifications:

If you wish to enforce the use of authentication, then you should modify the lpd.perms file. Here are some examples.

       # force authentication
       REJECT AUTH=NONE
       # in addition to above,
       # do not accept forwarded authentication
       REJECT AUTH=FWD
       # if the above is too strong,  you can
       # reject forwarded authentication unless from specified server
       # note: U1, U2, etc. are the userids of the remote server
       REJECT AUTH=FWD NOT FWDUSER=U1@*,U2@*,U3@*
       # you can be paranoid and also check to see that that host
       # agrees with the userid reported.
       REJECT AUTH=FWD FWDUSER=U1@host1

### Client/User Configuration

The user should either have the PGPPASS environment variable defined, or have in his home directory the file /.pgp/clientkey. This file will be read by the script and used for the value of the PGPPASS environment variable. If neither of these is available, then the pgp program will interactively request this information.

### Checking authenticate_pgp Operation

1. In order to use the script in debug mode, you must first create the user 'daemon' private keys on your private keyring for testing purposes.

       pgp -kg
           User ID: daemon_test <daemon_test@host>
           Pass phrase: daemon_test
       pgp -kg
           User ID: user_test <user_test@host>
           Pass phrase: user_test

2. Put the pass phrases for daemon_test in /.pgp/serverkey and the pass phrases for user_test in /.pgp/clientkey

       echo user_test >~/.pgp/serverkey
       echo user_test >~/.pgp/clientkey

3. The first test will ensure that you have the pgp software installed in an accessible manner. Execute the script as a user:

       sh authenticate_pgp -D -nuser_test -Rdaemon_test

   The output should resemble:

       server PGPPASS daemon_test
       ORIGKEY PRaTACFJGcQV92TE6bX72W2JHNNGPRIR7
       SERVER AUTH TRANSFERFILE temp.str
       398
       -----BEGIN PGP MESSAGE-----
       Version: 2.6.3i
       ...
       -----END PGP MESSAGE-----
       client PGPPASS user_test

   If there is an error, an error message will be printed.

### Setting up and Testing Daemon Keys

The next test will make sure that the daemon user can access its public and secret keyring when running as user daemon.

1. As a user, extract your user public key. As the user do:

       pgp -kxa userid userid_public_key

2. You should have a user `deamon` with a home directory that is owned and readable only by `daemon`. You do not need a password (logon) capabilities for `daemon`.

   Create the daemon/.pgp directory, and make sure that it has 0700 permissions.

3. Use the SU command to run as `daemon`. The SU command does not update the $HOME environment variable. Do the following to set $HOME:

       export HOME=`eval echo ~daemon`

4. Create a pgp key for the daemon. As user daemon do: the following to create the permanent daemon PGP key (`host` should be the host name for this server). Set the pass phrase to a suitable value. Make a note of these values - you will need them later.

       pgp -kg
          User ID: daemon_host <daemon_host@host>
          Pass phrase: ....

5. Extract the public key for daemon_host into a file. As user daemon do:

       pgp -kxa daemon_host daemon_public_key

6. Add the user's public key to the user daemon public key ring. The `userid_public_key` was created previously. As daemon do:

       pgp -ka userid_public_key

7. Add the daemon's public key to the user public key ring. As user do:

       pgp -ka daemon_public_key  (from step 4.5 above).

8. As user, encrypt a message check to see if it can be decoded by daemon. As user:

       echo hi >/tmp/msg
       pgp -seat msg daemon_host -u userid -o /tmp/msg.pgp
       chmod 777 /tmp/msg.pgp

   As daemon, check to see if you can decode this message.

       pgp /tmp/msg.pgp -o /tmp/msg.dec
       diff /tmp/msg /tmp/msg.dec

9. As user daemon, encode a message for user and see if it can be decoded by user. As daemon:

       pgp -seat /tmp/msg.dec userid -o /tmp/msg.pgp -u daemon_host
       chmod 777 /tmp/msg.pgp

   As user, decode the message for user.

       pgp /tmp/msg.pgp -o /tmp/msg.dec2
       diff /tmp/msg.dec2 /tmp/msg

### Testing authenticate_pgp

This test will check the actual authentication process carried out by `authenticate_pgp`.

1. Compile the `setupauth` program and install it in a temporary location. Note that `setupauth` is not an installed part of the LPRng distribution, but is a accessory.

       cd LPRng/src
       make setupauth
       mv setupauth /tmp/setupauth

2. `setupauth` has the command line:

       setupauth clientid 'client command' serverid 'servercommand'

   For example:

       /tmp/setupauth \
          papowell "/bin/ksh -c 'echo CLIENT; printenv ;'" \
          papowell "/bin/ksh -c 'echo SERVER; printenv ;'"

   This would display the environment variables set up by the setupauth program. This are similar to those used by LPRng.

3. The LPRng/src/AUTHENTICATE/testauth script has some simple tests you might want to run. Uncomment out the appropriate ones and substitute the appropriate user name for papowell and daemon.

       #!/bin/sh
       user=${USER:-`whoami`}
       # show environment variables
       #/tmp/setupauth \
       #   "${user}" "/bin/ksh -c 'echo CLIENT; printenv ;'" \
       #   "${user}" "/bin/ksh -c 'echo SERVER; printenv ;'"
       #
       #exit 0;
       #
       # check bidirectionality of data transfer
       #  /tmp/setupauth \
       #   "${user}" "/bin/ksh -c 'echo CLIENT STARTING SENDING 1>&2; echo hi 1>&0;'" \
       #   "${user}" "/bin/ksh -c 'echo SERVER READING; cat ;'" \
       # sleep 3;
       #  /tmp/setupauth \
       #   "${user}" "/bin/ksh -c 'echo CLIENT STARTING READING; cat '" \
       #   "${user}" "/bin/ksh -c 'echo SERVER SENDING 1>&2; echo hi 1>&0'"
       #
       # check the authenticate pgp operation
       #  Note: you can also use
       #  'sh -x ./authenticate_pcp ...' to see the detailed actions.
       #  Note: you must be root to run the next test.
       #
       rm /tmp/tempc /tmp/temps
       echo Hi $$ >/tmp/tempc
       chmod 777 /tmp/tempc
       /tmp/setupauth \
           "${user}" './authenticate_pgp -C -n"${user}" -R"${user}" -T/tmp/tempc' \
           "${user}" './authenticate_pgp -S -n"${user}" -R"${user}" -T/tmp/temps'
       rm /tmp/tempc /tmp/temps
       echo Hi $$ >/tmp/tempc
       chmod 777 /tmp/tempc
       /tmp/setupauth \
           "${user}" './authenticate_pgp -C -n"${user}" -Rdaemon -T/tmp/tempc' \
           daemon './authenticate_pgp -S -n"${user}" -Rdaemon -T/tmp/temps'

4. You must now SU to ROOT, as `testauth` needs to run as root to change userids. As `root`, Set the USER environment variable to the user you desire to simulate and execute the testauth script.

       USER=myself
       /tmp/testauth

### Testing authentication

1. Add the following lines to one of the printcap entries:

       :user_auth=pgp
       :user_authentication_command=/usr/local/lib/authenticate_pgp
       :server_auth=pgp
       :server_authentication_command=/usr/local/lib/authenticate_pgp

2. restart the server, using lpc lpd, to force it to read the new printcap information.
3. test the authentication facilities by using lpr to send a job to the appropriate spool queue.

### Key distribution

You can distribute the daemon PGP public key fairly easily - see the PGP documentation for key server information.

Each daemon must have the user's PGP key installed, or must in some way get the key from a trusted server. This is very site dependent and needs to be done by each site administrator.

## 12.9 Using Kerberos for Authentication

The LPRng use of Kerberos authentication was based on the Kerberos5-1.0 release as of December 20, 1996. This was obtained from MIT:

1. ftp to ATHENA-DIST.MIT.EDU (18.159.0.42), login anonymous, password your_email_address
2. Change into the directory '/pub/kerberos/
3. Get the README files and look at the details of using FTP to get the distribution. Note that there are also patches available which you might want to use.

Note that the distribution has only the most superficial documentation. There are no man pages for any of the support libraries, etc. etc.

### Kerberos Installation Procedure

1. Get the Kerberos 5 distribution.
2. Compile and install the distribution.
3. Create the /etc/krb5.conf, /usr/local/var/krb5kdc/kdc.conf files using templates from the src/conf-files subdirectory. See the Installation notes and the System Administrators Guide.
4. Don't forget to create the /usr/local/var/krb5kdc/kdc.acl file; I did and it took me HOURS to figure out what was wrong...
5. Start up the KDC and KADMIN servers - you might want to put the following in your rc.local or equivalent file:

       if [ -f /etc/krb5.conf -a -f /usr/local/var/krb5kdc/kdc.conf  ]; then
           echo -n ' krb5kdc ';    /usr/local/sbin/krb5kdc;
           echo -n ' kadmind ';    /usr/local/sbin/kadmind;
       fi

6. use kadmin (or kadmin.local) to create principals for your users.
7. Now you need to create principals for the lprng servers. I have been using: lpr/hostname.REALM as a template- i.e. lpr/astart1.astart.com@astart.com for an example

   Do this for all the servers. You should use fully qualified domain names for the principals.

8. Now you need to extract the keytab for each of the servers:

       kadmin ...
       ktadd -k file_for_host  lpr/hostname.REALM

   The 'file_for_host' contains the keytab information, which is the equivalent information for the server.

9. Copy the 'file_for_host' to the server (you might want to encrypt or use a secure transfer for this). You need to put this in `/etc/lpd.keytab`. Make sure that this file is readable only by user `daemon`, as it will try to read the file to get its server key.

       #> ls -l /etc/lpd.keytab
       -rw-------  1 daemon  wheel  128 Jan 16 11:06 /etc/lpd.keytab

10. Add the following entries to lpd.conf:

        use_auth=kerberos
        default_auth=kerberos
        kerberos_keytab=/etc/lpd.keytab
        kerberos_service=lpr
        kerberos_life=
        kerberos_renew=

    The kerberos_keytab entry is the location of the keytab file; kerberos_service is the service that will be used to generate a server principal name. This is the "lpr" that appears in the above operations.

    kerberos_life and kerberos_renew determine the lifetime and renewability of Kerberos tickets. The lifetime defaults to 10 hours, and the ticket will be refreshed when it expires if necessary.

11. You might like to check out the authentication using the sclient and sserver test programs. These link in the kerberos authentication and allow you to test it without all of LPD being involved.

        cd LPRng/src; make sserver sclient
        usage: sserver [-D] [-p port] [-s service] [-S keytab] file
           -D turns debugging on
           1. opens TCP   port 'port' (default 1234)
           2. waits for a connection
           3. when a connection comes in,  uses 'service' to get the principal
               name of the server,  and looks up the key in keytab file.
           4. Goes through the kerberos authentication.
           5. Copies the input from remote server to 'file'
           6. exits.
         usage: sclient [-D] [-p port] [-s service] host file
           -D turns debugging on
           1. opens a connection to port on host (i.e. - host%port)
           2. does the authentication.  You must have done kinit to get
               for your ticket to be valid.
           3. sends the file to remote host.

    To test this, start up sserver on one host/window, then run sclient. The error messages are pretty straight forward, and when in doubt, look at the source code which has more than sufficient information.

### Testing Transfers

Restart the server, and then try getting information using LPQ.

You can turn on tracing at LPQ to see if authentication is being used and is working:

    lpq -Dnetwork,database

If the lpq works, then try send a job and see if the transfer is successful.

### Explicit Server Principal Name

If you are using printers in different domains, then you can put the explicit principal name of the server in the printcap file, using the server_principal entry. For example:

    lp_offsite
        :lp=printer@erehwon.org
        :use_auth=kerberos
        :kerberos_server_principal=lpr/erehwon.org@BLUESKY.ORG

Next Previous Contents