On Fri, 14 Jan 2000, S.Barbaresi wrote: > we would like to integrate our Mac's with the printer accounting system by > using "papd". We've installed and configured atalkd, afpd and papd on our > Solaris boxes, but all print jobs are created by the same user, > consequently, the printer accounting system cant distinguish each job. > > The Question: is it possible to pass the user-id to papd, and hence to > lpd? I had exactly the same problem and ended up patching netatalk-1.4b2+asun2.1.3 so that it did the same sort of thing as CAP. In other words your users have to mount an AppleTalk share from the UNIX box before they can print. When they mount it, a file is written out that contains their node address. When they try to print through the UNIX box, only nodes that have mounted OK are allowed in. Seems to work for us anyway[1]. For what its worth, I've attached the patches for the various bits of netatalk to this email (this is something I've been meaning to do for months but not had enough round tuits until now). Tatty bye, Jim'll [1] Other than the fact that I advertise 37 printers into the same AppleTalk zone. Whilst other netatalk boxes see the NBP advertisments fine, Macs and CAP boxes only see a variable number of LaserWriters from the total. However I don't think this is related to this patch - looks more like a limitation with Macs being about to distinguish devices of the same AppleTalk type that are on the same node.
*** /home/jon/netatalk-1.4b2+asun2.1.3/etc/afpd/afp_asp.c Thu Oct 14 17:54:00 1999 --- /home/martin/netatalk-1.4b2+asun2.1.3/etc/afpd/afp_asp.c Sun Feb 7 20:35:35 1999 *************** *** 19,33 **** #include <atalk/atp.h> #include <atalk/asp.h> #include <atalk/compat.h> - #include <atalk/paths.h> #include "globals.h" #include "switch.h" #include "auth.h" - #ifdef SECURE_PRINTING - char secure_path[MAXPATHLEN + 1]; - #endif SECURE_PRINTING - extern struct oforks *writtenfork; static AFPObj *child; --- 19,28 ---- *************** *** 35,48 **** static void afp_asp_die(int sig) { ASP asp = child->handle; - #ifdef SECURE_PRINTING - char path[MAXPATHLEN + 1]; - - sprintf(path, "%s/%u.%u", _PATH_AFPCONNDIR, - ntohs( asp->asp_sat.sat_addr.s_net ), - asp->asp_sat.sat_addr.s_node); - unlink(path); - #endif /* SECURE_PRINTING */ asp_attention(asp, AFPATTN_SHUTDOWN); if ( asp_shutdown( asp ) < 0 ) { --- 30,35 ---- *************** *** 98,108 **** struct sigaction action; int func, ccnt = 0, reply = 0; - #ifdef SECURE_PRINTING - char path[MAXPATHLEN + 1]; - FILE *fd; - #endif /* SECURE_PRINTING */ - obj->exit = afp_asp_die; obj->reply = (int (*)()) asp_cmdreply; obj->attention = (int (*)(void *, AFPUserBytes)) asp_attention; --- 85,90 ---- *************** *** 133,155 **** atp_sockaddr( asp->asp_atp )->sat_addr.s_node, atp_sockaddr( asp->asp_atp )->sat_port ); - #ifdef SECURE_PRINTING - sprintf(secure_path, "%s/%u.%u", _PATH_AFPCONNDIR, - ntohs( asp->asp_sat.sat_addr.s_net ), - asp->asp_sat.sat_addr.s_node); - #endif SECURE_PRINTING - while (reply = asp_getrequest(asp)) { switch (reply) { case ASPFUNC_CLOSE : - - #ifdef SECURE_PRINTING - sprintf(path, "%s/%u.%u", _PATH_AFPCONNDIR, - ntohs( asp->asp_sat.sat_addr.s_net ), - asp->asp_sat.sat_addr.s_node); - syslog( LOG_INFO, "Unlinking %s",path ); - unlink(path); - #endif SECURE_PRINTING asp_close( asp ); #ifdef USE_PAM if (pamh) { --- 115,123 ---- *** /home/jon/netatalk-1.4b2+asun2.1.3/etc/afpd/auth.c Wed Oct 13 23:27:19 1999 --- /home/martin/netatalk-1.4b2+asun2.1.3/etc/afpd/auth.c Wed Oct 6 16:48:11 1999 *************** *** 44,53 **** #include "status.h" #include "switch.h" - #ifdef SECURE_PRINTING - extern char secure_path[MAXPATHLEN + 1]; - #endif SECURE_PRINTING - #define PASSWDLEN 8 #ifdef USE_PAM --- 44,49 ---- *************** *** 438,466 **** return( AFP_OK ); } ! login( name, uid, gid ) char *name; uid_t uid; gid_t gid; { - #ifdef SECURE_PRINTING - FILE *fd; - #endif SECURE_PRINTING - if ( uid == 0 ) { /* don't allow root login */ syslog( LOG_ERR, "login: root login denied!" ); return AFPERR_NOTAUTH; } - #ifdef SECURE_PRINTING - if ( (fd = fopen(secure_path, "w")) < 0 ) { - syslog( LOG_ERR, "Failed to open %s", secure_path); - } else { - fprintf(fd, "%s\n", name); - fclose(fd); - } - #endif SECURE_PRINTING - syslog( LOG_INFO, "login %s (uid %d, gid %d)", name, uid, gid ); if (initgroups( name, gid ) < 0) { #ifdef RUN_AS_USER --- 434,450 ---- return( AFP_OK ); } ! login( obj, name, uid, gid ) ! AFPObj *obj; char *name; uid_t uid; gid_t gid; { if ( uid == 0 ) { /* don't allow root login */ syslog( LOG_ERR, "login: root login denied!" ); return AFPERR_NOTAUTH; } syslog( LOG_INFO, "login %s (uid %d, gid %d)", name, uid, gid ); if (initgroups( name, gid ) < 0) { #ifdef RUN_AS_USER *************** *** 629,635 **** if (( pwd = getpwnam( ad.pname )) == NULL ) { return( AFPERR_NOTAUTH ); } ! return( login( pwd->pw_name, pwd->pw_uid, pwd->pw_gid )); #else AFS /* get principals */ *p++ = KRB4RPL_PRINC; --- 613,619 ---- if (( pwd = getpwnam( ad.pname )) == NULL ) { return( AFPERR_NOTAUTH ); } ! return( login( &obj, pwd->pw_name, pwd->pw_uid, pwd->pw_gid )); #else AFS /* get principals */ *p++ = KRB4RPL_PRINC; *************** *** 697,703 **** if (( pwd = getpwnam( ad.pname )) == NULL ) { return( AFPERR_NOTAUTH ); } ! return( login( pwd->pw_name, pwd->pw_uid, pwd->pw_gid )); #endif AFS default : --- 681,687 ---- if (( pwd = getpwnam( ad.pname )) == NULL ) { return( AFPERR_NOTAUTH ); } ! return( login( &obj, pwd->pw_name, pwd->pw_uid, pwd->pw_gid )); #endif AFS default : *************** *** 785,796 **** if ( pwd->pw_passwd != NULL ) { #ifdef AFS if ( kcheckuser( pwd, ibuf ) == 0 ) { ! return( login( pwd->pw_name, pwd->pw_uid, pwd->pw_gid )); } #endif AFS p = crypt( ibuf, pwd->pw_passwd ); if ( strcmp( p, pwd->pw_passwd ) == 0 ) { ! return( login( pwd->pw_name, pwd->pw_uid, pwd->pw_gid )); } } return AFPERR_NOTAUTH; --- 769,780 ---- if ( pwd->pw_passwd != NULL ) { #ifdef AFS if ( kcheckuser( pwd, ibuf ) == 0 ) { ! return( login( &obj, pwd->pw_name, pwd->pw_uid, pwd->pw_gid )); } #endif AFS p = crypt( ibuf, pwd->pw_passwd ); if ( strcmp( p, pwd->pw_passwd ) == 0 ) { ! return( login( &obj, pwd->pw_name, pwd->pw_uid, pwd->pw_gid )); } } return AFPERR_NOTAUTH; *** /home/jon/netatalk-1.4b2+asun2.1.3/etc/papd/main.c Thu Oct 14 19:39:22 1999 --- /home/martin/netatalk-1.4b2+asun2.1.3/etc/papd/main.c Wed Feb 3 20:07:01 1999 *************** *** 43,54 **** struct printer *printers = NULL; int debug = 0; - #ifdef SECURE_PRINTING - char secureprint = 0; - char secpath[MAXPATHLEN + 1]; - char *username; - FILE *fd; - #endif /* SECURE_PRINTING */ char *conffile = _PATH_PAPDCONF; char *printcap = _PATH_PAPDPRINTCAP; unsigned char connid, quantum, sock, oquantum = PAP_MAXQUANTUM; --- 43,48 ---- *************** *** 167,173 **** defprinter.p_pagecost_msg = NULL; defprinter.p_lock = "lock"; ! while (( c = getopt( ac, av, "adf:p:P:s" )) != EOF ) { switch ( c ) { case 'a' : /* for compatibility with old papd */ break; --- 161,167 ---- defprinter.p_pagecost_msg = NULL; defprinter.p_lock = "lock"; ! while (( c = getopt( ac, av, "adf:p:P:" )) != EOF ) { switch ( c ) { case 'a' : /* for compatibility with old papd */ break; *************** *** 188,205 **** pidfile = optarg; break; - case 's' : - #ifdef SECURE_PRINTING - secureprint++; - break; - #else SECURE_PRINTING - fprintf(stderr,"Secure printing not configured in binary\n"); - exit( 1 ); - #endif SECURE_PRINTING - default : fprintf( stderr, ! "Usage:\t%s [ -d ] [ -f conffile ] [ -p printcap ] [-s]\n", *av ); exit( 1 ); } --- 182,190 ---- pidfile = optarg; break; default : fprintf( stderr, ! "Usage:\t%s [ -d ] [ -f conffile ] [ -p printcap ]\n", *av ); exit( 1 ); } *************** *** 358,400 **** if ( err ) { continue; } - - #ifdef SECURE_PRINTING - syslog( LOG_INFO, "About to check security file"); - sprintf(secpath,"%s/%u.%u", - _PATH_AFPCONNDIR, - ntohs( sat.sat_addr.s_net ), - sat.sat_addr.s_node ); - syslog (LOG_INFO, "Opening file %s",secpath); - if ( (fd = fopen(secpath, "r")) == NULL ) { - syslog( LOG_ERR, - "Rejected printing from %u.%u:%u when unauthenticated\n", - ntohs( sat.sat_addr.s_net ), - sat.sat_addr.s_node, - sat.sat_port - ); - syslog(LOG_ERR, "Couldn't open file: %s", - strerror(errno)); - continue; - } else { - username = (char *)malloc(25 * sizeof(char)); - syslog(LOG_INFO, "About to read username"); - fgets(username,25,fd); - syslog( LOG_INFO, "Got a username, closing file"); - username[strlen(username)-1]='\0'; - fclose(fd); - syslog( LOG_INFO, "Setting username in lp_person"); - lp_person(username); - syslog( LOG_ERR, - "Accepted job from user %s from %u.%u:%u\n", - username, - ntohs( sat.sat_addr.s_net ), - sat.sat_addr.s_node, - sat.sat_port - ); - } - - #endif SECURE_PRINTING switch ( c = fork()) { case -1 : --- 343,348 ---- *** /home/jon/netatalk-1.4b2+asun2.1.3/etc/papd/lp.c Thu Oct 14 19:44:11 1999 --- /home/martin/netatalk-1.4b2+asun2.1.3/etc/papd/lp.c Thu Jun 26 21:48:43 1997 *************** *** 66,80 **** #include <netdb.h> #include <fcntl.h> - #ifdef LPRNG - #include <sys/wait.h> - #include <signal.h> - - #ifndef LPR - #define LPR "/usr/local/bin/lpr" - #endif - #endif LPRNG - #include "printer.h" #include "file.h" --- 66,71 ---- *************** *** 178,188 **** lp_init( out ) struct papfile *out; { - #ifndef LPRNG int fd, n, len; char *cp, buf[ BUFSIZ ]; struct stat st; - #endif /* LPRNG */ #ifdef ABS_PRINT char cost[ 22 ]; char balance[ 22 ]; --- 169,177 ---- *************** *** 220,226 **** lp.lp_letter = 'A'; if ( printer->p_flags & P_SPOOLED ) { - #ifndef LPRNG /* check if queuing is enabled: mode & 010 on lock file */ if ( stat( printer->p_lock, &st ) < 0 ) { syslog( LOG_ERR, "lp_init: %s: %m", printer->p_lock ); --- 209,214 ---- *************** *** 266,272 **** lseek( fd, 0L, 0 ); write( fd, buf, strlen( buf )); close( fd ); - #endif /* LPRNG */ } else { lp.lp_flags |= LP_PIPE; lp.lp_seq = getpid(); --- 254,259 ---- *************** *** 298,315 **** return( -1 ); } } else { ! #ifdef LPRNG ! sprintf( name, "%s/papd.%d%c", _PATH_VARTMP, getpid(), lp.lp_letter++ ); ! #else ! sprintf( name, "df%c%03d%s", lp.lp_letter++, lp.lp_seq, hostname ); ! #endif ! if (( fd = open( name, O_WRONLY|O_CREAT|O_EXCL, ! #ifdef LPRNG ! 0600 ! #else ! 0660 ! #endif ! )) < 0 ) { syslog( LOG_ERR, "lp_open %s: %m", name ); spoolerror( out, NULL ); return( -1 ); --- 285,293 ---- return( -1 ); } } else { ! sprintf( name, "df%c%03d%s", lp.lp_letter++, lp.lp_seq, hostname ); ! ! if (( fd = open( name, O_WRONLY|O_CREAT|O_EXCL, 0660 )) < 0 ) { syslog( LOG_ERR, "lp_open %s: %m", name ); spoolerror( out, NULL ); return( -1 ); *************** *** 365,375 **** } for ( letter = 'A'; letter < lp.lp_letter; letter++ ) { - #ifdef LPRNG - sprintf( name, "%s/papd.%d%c", _PATH_VARTMP, getpid(), letter ); - #else sprintf( name, "df%c%03d%s", letter, lp.lp_seq, hostname ); - #endif if ( unlink( name ) < 0 ) { syslog( LOG_ERR, "lp_cancel unlink %s: %m", name ); } --- 343,349 ---- *************** *** 399,472 **** lp_close(); if ( printer->p_flags & P_SPOOLED ) { - char *job, *person; - #ifdef LPRNG - char **argv, **ptr, **fileptr; - pid_t pid; - #endif - - job = (lp.lp_job && *lp.lp_job) ? lp.lp_job : "Mac Job"; - person = lp.lp_person ? lp.lp_person : printer->p_operator; - - #ifdef LPRNG - if (! ((ptr = argv = (char **) malloc(sizeof(*argv) * - (6 + (lp.lp_letter - 'A')))) && - (*ptr++ = (char *) malloc(sizeof("lpr"))) && - (*ptr++ = (char *) malloc(strlen(printer->p_printer) + 3)) &&/* -P */ - (*ptr++ = (char *) malloc(strlen(job) + 3)) && /* -J */ - (*ptr++ = (char *) malloc(strlen(job) + 3)) && /* -T */ - (*ptr++ = (char *) malloc(strlen(person) + 3)))) { /* -U */ - syslog( LOG_ERR, "malloc: %m" ); - exit( 1 ); - } - - for ( letter = 'A'; letter < lp.lp_letter; letter++ ) { - if (! (*ptr++ = (char *) malloc( strlen(_PATH_VARTMP) + 20 ))) { - syslog( LOG_ERR, "malloc: %m" ); - exit( 1 ); - } - } - - ptr = argv; - - (void) sprintf( *ptr++, "lpr" ); - (void) sprintf( *ptr++, "-P%s", printer->p_printer ); - (void) sprintf( *ptr++, "-J%s", job ); - (void) sprintf( *ptr++, "-T%s", job ); - (void) sprintf( *ptr++, "-U%s", person ); - - fileptr = ptr; - - for ( letter = 'A'; letter < lp.lp_letter; letter++ ) - (void) sprintf( *ptr++, "%s/papd.%d%c", _PATH_VARTMP, getpid(), letter ); - - *ptr = NULL; - syslog(LOG_INFO, "lp_print: About to run %s %s %s %s %s %s", - argv[0], argv[1], argv[2], argv[3], argv[4], argv[5]); - signal( SIGCHLD, SIG_DFL ); - - switch (( pid = fork() )) { - case 0: - (void) execv( LPR, argv ); - syslog( LOG_ERR, "execvp(%s): %m", LPR ); - exit( 1 ); - case -1: - syslog( LOG_ERR, "fork: %m" ); - exit( 1 ); - default: { - int status; - - pid = waitpid( pid, &status, 0 ); - if ( WIFEXITED(status) && WEXITSTATUS(status) ) - syslog( LOG_ERR, "lp_print: child exited with status %d", - WEXITSTATUS(status) ); - while ( *fileptr ) - (void) unlink( *fileptr++ ); - for ( ptr = argv; *ptr; ptr++ ) - (void) free( *ptr ); - } - } - #else sprintf( tfname, "tfA%03d%s", lp.lp_seq, hostname ); if (( fd = open( tfname, O_WRONLY|O_EXCL|O_CREAT, 0660 )) < 0 ) { syslog( LOG_ERR, "lp_print %s: %m", tfname ); --- 373,378 ---- *************** *** 478,496 **** } fprintf( cfile, "H%s\n", hostname ); /* XXX lp_host? */ ! printf( cfile, "P%s\n", person ); - fprintf( cfile, "J%s\n", job ); - fprintf( cfile, "T%s\n", job ); fprintf( cfile, "C%s\n", hostname ); /* XXX lp_host? */ ! fprintf( cfile, "L%s\n", person ); for ( letter = 'A'; letter < lp.lp_letter; letter++ ) { fprintf( cfile, "fdf%c%03d%s\n", letter, lp.lp_seq, hostname ); fprintf( cfile, "Udf%c%03d%s\n", letter, lp.lp_seq, hostname ); } ! fprintf( cfile, "N%s\n", job ); fclose( cfile ); sprintf( cfname, "cfA%03d%s", lp.lp_seq, hostname ); --- 384,421 ---- } fprintf( cfile, "H%s\n", hostname ); /* XXX lp_host? */ ! if ( lp.lp_person ) { ! fprintf( cfile, "P%s\n", lp.lp_person ); ! } else { ! fprintf( cfile, "P%s\n", printer->p_operator ); ! } ! ! if ( lp.lp_job && *lp.lp_job ) { ! fprintf( cfile, "J%s\n", lp.lp_job ); ! fprintf( cfile, "T%s\n", lp.lp_job ); ! } else { ! fprintf( cfile, "JMac Job\n" ); ! fprintf( cfile, "TMac Job\n" ); ! } fprintf( cfile, "C%s\n", hostname ); /* XXX lp_host? */ ! ! if ( lp.lp_person ) { ! fprintf( cfile, "L%s\n", lp.lp_person ); ! } else { ! fprintf( cfile, "L%s\n", printer->p_operator ); ! } for ( letter = 'A'; letter < lp.lp_letter; letter++ ) { fprintf( cfile, "fdf%c%03d%s\n", letter, lp.lp_seq, hostname ); fprintf( cfile, "Udf%c%03d%s\n", letter, lp.lp_seq, hostname ); } ! if ( lp.lp_job && *lp.lp_job ) { ! fprintf( cfile, "N%s\n", lp.lp_job ); ! } else { ! fprintf( cfile, "NMac Job\n" ); ! } fclose( cfile ); sprintf( cfname, "cfA%03d%s", lp.lp_seq, hostname ); *************** *** 523,535 **** syslog( LOG_ERR, "lp_print lpd said %c: %m", buf[ 0 ] ); return; } - #endif } syslog( LOG_INFO, "lp_print queued" ); return; } - lp_disconn_unix( fd ) { return( close( fd )); --- 448,458 ---- *************** *** 609,617 **** lp_rmjob( job ) int job; { - #ifdef LPRNG - return( -1 ); - #else char buf[ 1024 ]; int n, s; --- 532,537 ---- *************** *** 637,643 **** lp_disconn_inet( s ); return( 0 ); - #endif } char *kw_rank = "Rank"; --- 557,562 ---- *************** *** 653,661 **** lp_queue( out ) struct papfile *out; { - #ifdef LPRNG - return( -1 ); - #else char buf[ 1024 ], *start, *stop, *p, *q; static struct papfile pf; int n, len, s; --- 572,577 ---- *************** *** 800,804 **** return( 0 ); } } - #endif /* LPRNG */ } --- 716,719 ---- *** /home/jon/netatalk-1.4b2+asun2.1.3/etc/papd/session.c Thu Oct 14 18:00:42 1999 --- /home/martin/netatalk-1.4b2+asun2.1.3/etc/papd/session.c Sat Feb 6 06:42:47 1999 *************** *** 300,306 **** } } } - - - - --- 300,302 ---- *** /home/jon/netatalk-1.4b2+asun2.1.3/etc/papd/Makefile Thu Oct 14 18:00:30 1999 --- /home/martin/netatalk-1.4b2+asun2.1.3/etc/papd/Makefile Tue May 20 18:35:42 1997 *************** *** 4,10 **** bprint.o magics.o headers.o queries.o INCPATH = -I../../include ${KRBINCPATH} ${ABSINCPATH} ! CFLAGS= ${DEFS} ${KRBDEFS} ${ABSDEFS} ${OPTOPTS} ${INCPATH} -DLPRNG TAGSFILE= tags LIBDIRS= -L../../libatalk ${KRBLIBDIRS} ${ABSLIBDIRS} LIBS= -latalk ${ABSLIBS} ${KRBLIBS} ${ADDLIBS} --- 4,10 ---- bprint.o magics.o headers.o queries.o INCPATH = -I../../include ${KRBINCPATH} ${ABSINCPATH} ! CFLAGS= ${DEFS} ${KRBDEFS} ${ABSDEFS} ${OPTOPTS} ${INCPATH} TAGSFILE= tags LIBDIRS= -L../../libatalk ${KRBLIBDIRS} ${ABSLIBDIRS} LIBS= -latalk ${ABSLIBS} ${KRBLIBS} ${ADDLIBS} *** /home/jon/netatalk-1.4b2+asun2.1.3/sys/linux/Makefile Wed Oct 13 20:35:23 1999 --- /home/martin/netatalk-1.4b2+asun2.1.3/sys/linux/Makefile Sat Feb 27 21:10:59 1999 *************** *** 1,14 **** # Linux specific defines, passed to subdirectories. #DEFS= -DNEED_QUOTACTL_WRAPPER -DSENDFILE_FLAVOR_LINUX ! DEFS= -DNEED_QUOTACTL_WRAPPER -DSECURE_PRINTING OPTOPTS= -O2 -fomit-frame-pointer -fsigned-char -Wunused -Wuninitialized #OPTOPTS= -g -fsigned-char CC= gcc INSTALL= install # if you aren't using pam and are using glibc, you'll need to add -lcrypt # if you're using libc5, you'll need to take out the -lrpcsvc ! AFPLIBS= ! ADDLIBS= -lrpcsvc ALL= ../../libatalk ../../include ../../bin ../../etc ../../man --- 1,14 ---- # Linux specific defines, passed to subdirectories. #DEFS= -DNEED_QUOTACTL_WRAPPER -DSENDFILE_FLAVOR_LINUX ! DEFS= -DNEED_QUOTACTL_WRAPPER OPTOPTS= -O2 -fomit-frame-pointer -fsigned-char -Wunused -Wuninitialized #OPTOPTS= -g -fsigned-char CC= gcc INSTALL= install # if you aren't using pam and are using glibc, you'll need to add -lcrypt # if you're using libc5, you'll need to take out the -lrpcsvc ! AFPLIBS=-lrpcsvc ! ADDLIBS= ALL= ../../libatalk ../../include ../../bin ../../etc ../../man