SUMMARY II - lp, filters and user names

From: Harry Wilson (
Date: Mon Sep 23 1996 - 10:34:04 CDT

Hello all,

        Several people have asked for this information, so I have joined the suggestions to this note.

If you did not want it, sorry ...

If you did then here it is.




Here's my solution, which I use as part of my automatic
ghostscript-based postscript colour print queue. It's a bit of a hack
to say the least, but it does get the user info. I'm not absolutely
sure from your description whether you actually have the user info (ie.
if it is ever being passed to the print system), but I think that if
the info is there at all, this should do it.

1. in /usr/lib/lp/bin, apply the following diff:

*** slow.filter.fcs Sat Jul 16 04:30:20 1994
--- slow.filter Wed Feb 22 11:46:06 1995
*** 71,76 ****
--- 71,77 ----
+ export cf
  for file in "$@"
*** 81,86 ****
--- 82,94 ----
                        "See if it still exists and is readable, or
                consult your system administrator."
+ cf=`basename ${prefix} | tail +2c`
+ host=`dirname ${file}`
+ host=`basename $host`
+ if [ ! -d "/var/spool/lp/requests/${host}" ]; then
+ host=`uname -n`
+ fi
+ cf="/var/spool/lp/requests/${host}/${cf}-0"
                0<${file} 1>${prefix}-${k} eval "2>&5 ${FILTER}" || {
                        while [ 127 -lt "${exit_code}" ]

2. Somewhere in your print filter use something like:

params=`cat ${cf}`
job=`echo $params | cut -d" " -f1`
queue=`echo $job | cut -d"-" -f1`
user=`echo $params | cut -d" " -f3 | cut -d"!" -f2`
host=`echo $params | cut -d" " -f7 | cut -d"." -f1`

Hope it helps,


 George Cameron
 Dept. BioMedical Physics
 Aberdeen University
 Foresterhill Fax: +44 (0)1224-685645
 Aberdeen AB9 2ZD Telephone: +44 (0)1224-663123 ext 53210
 Scotland, UK


The reason you always got "lp" as the username was the filter
was always run by lp. What you wanted was the username that
submitted the job - a different thing entirely.

Here is an unfinished stab at the filter - I will return to
it when I have the time.

It shows the args, CWD and files stating "df" - this is where
it is going to have to look. (SunOS 4 anyway...)
For SunOS 5.5 the files are different - called for example 29-0
for print job number 29.
Do you think you could capture me a pair of files
out of your spool directory - do an "lp /etc/vfstab" for example
followed by a quick cp - and send me what you get.

Finally it will have to chuck all the stdin out again to the
right filter, if I understand your scheme right.

(Incidentally, a prog like this would be the ideal place
to control a printer access policy - usernames, size of job,
time of day .......

A really smart filter could replace all references to the
sysadmin with appropriately complimentary ones!


#include <ctype.h>
#include <dirent.h>
#include <errno.h>
#include <fcntl.h>
#include <memory.h>
#include <pwd.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <syslog.h>
#include <unistd.h>
#include <string.h>

int main(int argc, char **argv)

        char *command, *cwd;
        FILE *stre;
        int x;
        DIR *dirp;
        struct dirent *dp;
        struct stat *buf;
        struct stat statbuf;
        char *filterin,*newfilterin;

** This is a filter: we want to read all stdin here, to EOF
** ideally using malloc(3) to get the space as we don't know the
** size in advance.

*** Now report by mail the arguments, current directory
*** and FILEs present whose names begin "df".
*** (The point is that one of these files will match what
*** we have as stdin. Then the matching "cf" file will
*** hold the username.)
        command = strdup("/usr/lib/sendmail root");
        stre = popen(command, "w");
        if (NULL == stre) {
                fprintf(stderr, "Error - no pipe...\n");

        fprintf(stre, "Subject: Parameter Details\n\n");

        for (x = 0; x < argc; x++) {
                fprintf(stre, "Arg[%d]=%s\n", x, argv[x]);

        cwd = getcwd(NULL, 1024);
        fprintf(stre, "CWD=%s\n", cwd);

        dirp = opendir(".");

        for (dp = readdir(dirp);
             dp != NULL;
             dp = readdir(dirp)) {

                buf = &statbuf;
                stat(dp->d_name, buf);

                if ((S_ISREG(buf->st_mode)) && (0 == strncmp(dp->d_name, "df", 2))) {
                        fprintf(stre, "File %s\n", dp->d_name);

/*** check whether this "df" file matches stdin ***/
/*** need to check here for a matching CF file ***/
/*** and read the contents ***/





 Your dilemma reminds me of a problem I had using NFS between VMS and UNIX. If
I remember correctly VMS could only act as the NFS server and when VMS
"exported" the VMS filesystem (container filesystem?), they had the option of
using UNIX type UID authentication or a aliasing security technique.
Essentially, the VMS side didn't want to open up their system manager user
access to the root user on the NFS client (UNIX) side. So they aliased root to
some other ID under VMS.

Your situation reminds me of a ACL/alias file used in VMS that maps all NFS
requests to one generic user so that the VMS side can manage access summarily
instead of having to manage an ACL for each VMS user that might want to use NFS.

I wonder if the same sort of ACL/aliasing is being used in your LPD example and
for simplicity, no matter which VMS user generates the print request, the LPD
software under VMS just sticks "LP" in there?

I also worked on a similar problem between UNIX and MVS using Interlinks LPD
product and Interlinks Enterprise Print Server(EPS). Without the extra-cost
EPS product, the standard LPD protocol would stick "LP" in as the print user.
After installing the EPS product though, the LPD protocol worked as defined in
the standard RFC definition. You might want to speak to the vendor where you
acquired the VMS LPD product to see if this is a "feature".

Good Luck!
Brian Puchalski

Hello Harry,

you can extract those informations from the controlfile of the printjob
(the 'cf...' files). The actual controlfile can be `grep'ed` from the lock

Ciao, Dieter Gobbers



Harry Wilson
UNIX System Administrator
2 Kensington Terrace
Newcastle Upon Tyne

Tel: 0191 222 5023
Fax: 0191 222 8703

This archive was generated by hypermail 2.1.2 : Fri Sep 28 2001 - 23:11:10 CDT