Subject: Re: [netatalk-admins] papd and RedHat 5.0 (fwd)

From: andrew morgan <[email-masked]>
Date: Sat, 4 Mar 2000 08:34:41 -0800 (PST)

---------- Forwarded message ----------
Date: Fri, 10 Dec 1999 18:18:33 -0500
From: John Dalbec <[email-masked]>
To: [email-masked]
Subject: Re: [netatalk-admins] papd and RedHat 5.0

Environment:
Red Hat Linux 5.2
lpr-0.46-0.5.2
HP LaserJet 6L
netatalk-1.4b2+asun2.1.4(pre-asun2.1.4-35.tar.gz)
ipfwadm-2.3.0-6
10Base2 Ethernet
Performa 5200CD
Mac OS 8.6
OT 2.03
AppleTalk and TCP/IP over local ethernet

Description:
When I print a file from the Mac to the LaserJet, lpd sends an email saying

Your printer job (<name>)
was not printed because it was not linked to the original file

What happens is that papd creates the control and data files with uid/gid root,
and for security reasons lpd tries to open the data file as the user listed in
the control file.  The "lpr" command fchown()s the data file to the correct uid
so files printed with "lpr" print OK.  

Repeat-By:
Install lpr-0.46 on the same machine as netatalk.  Try to print a file.

Fix:
I have adapted the fchown() code from the "lpr" command (which AFAICT does not
incur any additional licenses) to create a patch for papd.  Specifically, the
patch modifies the lp_open() routine in lp.c to give away the data file to the
user named in the control file.

*** netatalk-1.4b2+asun2.1.4/etc/papd/lp.c      Sat Nov  6 10:53:30 1999
--- lp.c        Sat Nov  6 11:05:55 1999
***************
*** 65,70 ****
--- 65,71 ----
  #include <string.h>
  #include <netdb.h>
  #include <fcntl.h>
+ #include <pwd.h>

  #include "printer.h"
  #include "file.h"
***************
*** 268,273 ****
--- 269,275 ----
  {
      char      name[ MAXPATHLEN ];
      int               fd;
+     struct passwd *pw;

      if (( lp.lp_flags & LP_INIT ) == 0 && lp_init( out ) != 0 ) {
        return( -1 );
***************
*** 292,297 ****
--- 294,322 ----
            spoolerror( out, NULL );
            return( -1 );
        }
+
+       if ( lp.lp_person ) {
+           if (( pw = getpwnam( lp.lp_person )) == NULL) {
+               syslog( LOG_ERR, "lp_open getpwnam %s: no such user",
+                       lp.lp_person );
+               spoolerror( out, NULL );
+               return( -1 );
+           }
+       } else {
+           if (( pw = getpwnam( printer->p_operator )) == NULL) {
+               syslog( LOG_ERR, "lp_open getpwnam %s: no such user",
+                       printer->p_operator );
+               spoolerror( out, NULL );
+               return( -1 );
+           }
+       }
+
+       if ( fchown( fd, pw->pw_uid, -1 ) < 0 ) {
+           syslog( LOG_ERR, "lp_open chown %s %s: %m", pw->pw_name, name );
+           spoolerror( out, NULL );
+           return( -1 );
+       }
+
        if (( lp.lp_stream = fdopen( fd, "w" )) == NULL ) {
            syslog( LOG_ERR, "lp_open fdopen: %m" );
            spoolerror( out, NULL );