(Message inbox:633) Received: from SAFE.Stanford.EDU by jessica.Stanford.EDU with TCP; Tue, 9 Aug 88 23:15:58 PDT Received: from po2.andrew.cmu.edu ([128.2.249.105]) by safe.stanford.edu with Sendmail; Tue, 9 Aug 88 23:07:21 pdt Received: by po2.andrew.cmu.edu (5.54/3.15) id ; Wed, 10 Aug 88 01:03:35 EDT Received: via switchmail for info-appletalk+@andrew.cmu.edu; Wed, 10 Aug 88 01:03:28 -0400 (EDT) Received: from po3.andrew.cmu.edu via qmail ID ; Wed, 10 Aug 88 01:00:34 -0400 (EDT) Received: by po3.andrew.cmu.edu (5.54/3.15) id for info-appletalk; Wed, 10 Aug 88 00:59:20 EDT Received: by ucbvax.Berkeley.EDU (5.59/1.30) id AA15747; Tue, 9 Aug 88 20:32:17 PDT Received: from USENET by ucbvax.Berkeley.EDU with netnews for info-appletalk@andrew.cmu.edu (info-appletalk@andrew.cmu.edu) (contact usenet@ucbvax.Berkeley.EDU if you have questions) Date: 10 Aug 88 03:09:34 GMT From: budd@bu-cs.bu.edu (Philip Budne) Organization: Boston U. Comp. Sci. Subject: lwsrv accounting/access control for CAP 5.0 Message-Id: <24353@bu-cs.BU.EDU> Sender: info-appletalk-request@andrew.cmu.edu To: info-appletalk@andrew.cmu.edu A while back someone asked if lwserv had been adapted to do accounting. Here is a solution I did a while back. Our CS student machines has a pair of TI2115 OmniLoser printers, and I wanted to make them available to Mac users ONLY IF they had accounts on the Unix system. I've modified aufs to write a small file based on net/node of origin in a special directory when a user logs in via aufs and remove it when they logout. (the files do get left when a mac crashes, but it usually comes back with a different node number. lwsrv checks if the incomming request comes from a node for which we have data, then setuid()s to that user before running lpr so that accounting is done properly. If the user is not logged in the request is rejected. Both lwsrv and aufs now take "-X directory" arguments. Phil Budne, Boston University Diffs: ================================================================ *** aufs.c.1 Thu May 19 15:20:19 1988 --- aufs.c Tue Aug 9 20:34:54 1988 *************** *** 75,80 **** --- 75,81 ---- private char *passwdlookaside = NULL; /* local password file??? */ private char *guestid = NULL; /* any guest ids? */ private char *coredir = NULL; /* place to put coredumps */ + export char *userlogindir = NULL; /* budd -- name of userlogin file */ export int mcs, qs; /* maxcmdsize and quantum size */ export int sqs = atpMaxNum; /* maximum send quantum */ export int n_rrpkts = atpMaxNum; /* maximum send quantum to allow remote */ *************** *** 151,157 **** char *DBLevelOpts(); fprintf(stderr,"usage: %s [-d cap-flags] [-a afp-levels] ",name); ! fprintf(stderr,"[-n name] [-t packets] [-s] [-V afpvols]\n"); fprintf(stderr,"\t-d for CAP debugging flags:\n"); fprintf(stderr,"\t l = lap, d = ddp, a = atp, n = nbp, p = pap,"); fprintf(stderr,"i = ini, s = asp\n"); --- 152,158 ---- char *DBLevelOpts(); fprintf(stderr,"usage: %s [-d cap-flags] [-a afp-levels] ",name); ! fprintf(stderr,"[-n name] [-t packets] [-s] [-V afpvols] [-X usrfile]\n"); /* budd */ fprintf(stderr,"\t-d for CAP debugging flags:\n"); fprintf(stderr,"\t l = lap, d = ddp, a = atp, n = nbp, p = pap,"); fprintf(stderr,"i = ini, s = asp\n"); *************** *** 171,176 **** --- 172,178 ---- fprintf(stderr,"\t-l file to send logfile to other than .log\n"); fprintf(stderr,"\t-S limit responses to packets\n"); fprintf(stderr,"\t-R limit remote to sending packets\n"); + fprintf(stderr,"\t-X datafile of logged in users\n"); /* budd */ fprintf(stderr,"\nExample: %s -t 'bdelete irename' -a 'file fork dir' -s\n", name); exit(1); *************** *** 202,208 **** extern char *optarg; extern int optind; ! while ((c = getopt(argc,argv,"a:d:D:n:N:t:sV:U:G:P:c:l:z:S:R:")) != EOF) { switch (c) { case 'z': strncpy(zonetorun, optarg, 32); --- 204,210 ---- extern char *optarg; extern int optind; ! while ((c = getopt(argc,argv,"a:d:D:n:N:t:sV:U:G:P:c:l:z:S:R:X:")) != EOF) { switch (c) { case 'z': strncpy(zonetorun, optarg, 32); *************** *** 272,277 **** --- 274,282 ---- n_rrpkts = atpMaxNum; } break; + case 'X': /* budd... */ + userlogindir = optarg; + break; /* ...budd */ default: usage(argv[0]); break; *************** *** 280,285 **** --- 285,292 ---- } + export AddrBlock addr; /* budd */ + main(argc,argv) int argc; char **argv; *************** *** 289,295 **** int killnow(), killin5(), diein5(); #endif int err,atpskt,slsref; - AddrBlock addr; int comp,comp2; byte *srvinfo; int srvinfolen; --- 296,301 ---- *************** *** 382,387 **** --- 389,398 ---- if ((ctp_stack = (int *)malloc(sizeof(int)*maxsess)) == NULL) { log("couldn't malloc stack for pid recording, fatal!"); } + if( userlogindir != NULL ) { /* budd... */ + log("Aufs: user login database in %s", userlogindir ); + } /* ...budd */ + ctp_stack_cnt = 0; { int i; for (i = 0 ; i < maxsess; i++) { *************** *** 579,584 **** --- 590,596 ---- while (comp > 0) { abSleep(sectotick(60),TRUE); } if (comp == SessClosed || comp == ParamErr) { log("Session (%d) closed",cno); + clearuserlogin(); /* budd */ return; } if (comp < 0) { *************** *** 995,997 **** --- 1007,1035 ---- } + /**************** budd... ****************/ + clearuserlogin() { + if( userlogindir != NULL ) { + char fname[ 100 ]; + int fd; + + make_userlogin( fname, userlogindir, addr ); + if( unlink( fname ) < 0 ) { + if( (fd = open( fname, O_WRONLY|O_TRUNC )) != -1 ) + close( fd ); + } /* unlink failed */ + } /* have userlogindir */ + } /* clearuserlogin */ + + /* duplicated in aufs.c and lwsrv.c sigh */ + make_userlogin( buf, dir, addrb ) + char *buf, *dir; + AddrBlock addrb; + { + sprintf( buf, "%s/net%d.%dnode%d", + dir, + nkipnetnumber(addrb.net), nkipsubnetnumber(addrb.net), + addrb.node + ); + } /* make_userlogin */ + /**************** ...budd ****************/ ============================================= *** afpos.c.1 Thu May 19 15:19:51 1988 --- afpos.c Tue Aug 9 21:53:37 1988 *************** *** 2427,2432 **** --- 2439,2465 ---- strcpy(usrnam,p->pw_name); usrdir = (char *) malloc(strlen(p->pw_dir)+1); strcpy(usrdir,p->pw_dir); + + /* budd... */ + if( userlogindir != NULL ) { /* need to save user logins? */ + extern AddrBlock addr; /* is this valid now?? seems to be! */ + char fname[ 100 ]; + FILE *f; + + /* create file before setuid call so we can write in directory. */ + make_userlogin( fname, userlogindir, addr ); + if( (f = fopen( fname, "w" )) != NULL ) { /* sigh. leaves race. */ + fprintf( f, "%s\n", usrnam ); /* perhaps write temp */ + fclose( f ); /* and rename? */ + /* sigh. fchown and fchmod are BSDisms */ + chmod( fname, 0644 ); /* make owned by user so they */ + chown( fname, usruid, -1 ); /* can truncate it on exit!! */ + } /* fopen ok */ + else + log("Login: could not create %s: %s", fname, syserr() ); + } /* userlogindir and not guest */ + /* ...budd */ + break; } ================================================================ *** lwsrv.c.1 Thu May 19 15:19:01 1988 --- lwsrv.c Mon Jul 25 14:45:41 1988 *************** *** 50,55 **** --- 50,56 ---- # include #endif #include "papstream.h" + #include /* budd */ private char *tracefile = NULL; private char *fontfile = NULL; *************** *** 64,71 **** export PAPStatusRec statbuff; /* status buffer */ private char username[80],jobname[80]; - #ifndef TEMPFILE # define TEMPFILE "/tmp/lwsrvXXXXXX" /* temporary file holds job */ #endif --- 65,73 ---- export PAPStatusRec statbuff; /* status buffer */ private char username[80],jobname[80]; + private char *aufsdb = NULL; /* budd */ + private int requid; #ifndef TEMPFILE # define TEMPFILE "/tmp/lwsrvXXXXXX" /* temporary file holds job */ #endif *************** *** 82,88 **** fprintf(stderr,"usage: %s -n -p \n",s); fprintf(stderr,"usage:\t\t-a -f \n"); fprintf(stderr,"usage:\t\t[-l ] [-t ] [-r] [-h]\n"); ! fprintf(stderr,"usage:\t\t[-T crtolf] [-T quote8bit]\n\n"); fprintf(stderr,"\t-p* is the unix printer to print to\n"); fprintf(stderr,"\t-n* specifies the name lwsrv registers.\n"); fprintf(stderr,"\t-a* is the ProcSet directory.\n"); --- 84,91 ---- fprintf(stderr,"usage: %s -n -p \n",s); fprintf(stderr,"usage:\t\t-a -f \n"); fprintf(stderr,"usage:\t\t[-l ] [-t ] [-r] [-h]\n"); ! fprintf(stderr,"usage:\t\t[-T crtolf] [-T quote8bit] [-X userlogindb]\n\n"); ! /* budd.........^^*/ fprintf(stderr,"\t-p* is the unix printer to print to\n"); fprintf(stderr,"\t-n* specifies the name lwsrv registers.\n"); fprintf(stderr,"\t-a* is the ProcSet directory.\n"); *************** *** 106,111 **** --- 109,115 ---- fprintf(stderr,"\t-T quote8bit: quote 8 bit chars for Transcript\n"); fprintf(stderr,"\t-T makenondscconformant: make non DSC conformant: use\n"); fprintf(stderr,"\t if psrv only works with DSC 1.0 conventions\n"); + fprintf(stderr,"\t-X use aufs for validation\n");/*budd*/ fprintf(stderr,"\nexample: %s -n Laser -p ps -a/usr/lib/ADicts\n",s); fprintf(stderr,"\t\t-f /usr/lib/LW+Fonts\n"); fprintf(stderr,"\t(note the starred items above are required)\n"); *************** *** 121,127 **** extern char *optarg; extern int optind; ! while ((c = getopt(argc,argv,"a:f:l:p:P:t:d:n:rehT:A:S")) != EOF) { switch (c) { case 'a': if (index(optarg, '/') == NULL) { --- 125,131 ---- extern char *optarg; extern int optind; ! while ((c = getopt(argc,argv,"a:f:l:p:P:t:d:n:rehT:A:SX:")) != EOF) { switch (c) { case 'a': if (index(optarg, '/') == NULL) { *************** *** 171,176 **** --- 175,185 ---- singlefork = TRUE; fprintf(stderr, "lwsrv: single fork\n"); break; + case 'X': /* budd... */ + aufsdb = optarg; + fprintf(stderr, "lwsrv: aufs db directory in %s\n", aufsdb ); + break; /* ...budd */ + case '?': /* illegal character */ usage(argv[0],NULL); /* usage and exit */ break; *************** *** 212,217 **** --- 221,227 ---- doargs(argc,argv); /* handle args */ + requid = getuid(); /* budd */ if (!dbug.db_flgs) { /* disassociate */ if (fork()) *************** *** 274,279 **** --- 284,291 ---- if (!singlefork) signal(SIGCHLD, childdone); while (TRUE) { + AddrBlock addr; /* budd */ + NewStatus("idle"); err = GetNextJob(srefnum, &cno, &rcomp); if (err != noErr) { *************** *** 283,288 **** --- 295,346 ---- while (rcomp > 0) abSleep(20,TRUE); fprintf(stderr,"lwsrv: Starting print job for %s\n",prtname); + + /*** budd.... */ + if ((err = PAPGetNetworkInfo(cno, &addr)) != noErr) + fprintf(stderr, "Get Network info failed with error %d", err); + else + fprintf(stderr,"Connection %d from [Network %d.%d, node %d, socket %d]\n", + cno, + nkipnetnumber(addr.net), nkipsubnetnumber(addr.net), + addr.node, addr.skt); + + if( aufsdb != NULL ) { + char fname[ 256 ]; + int f, cc, ok; + struct passwd *pw; + ok = 0; /* false */ + make_userlogin( fname, aufsdb, addr ); + if( (f = open( fname, 0)) >= 0 && + (cc = read( f, fname, sizeof( fname )-1 )) > 0 ) { + if( fname[cc-1] == '\n' ) + fname[cc-1] = '\0'; + fprintf( stderr, "Found username in aufsdb (%s): %s\n", + aufsdb, fname ); + if( (pw = getpwnam( fname )) != NULL ) { + requid = pw->pw_uid; + ok = 1; /* true */ + } /* pwnam ok */ + } /* open and read OK */ + if( !ok ) { /* dump connection with error message */ + char message[ 512 ]; + fprintf( stderr, "No username (or invalid) confirmation.\n"); + gethostname( fname, sizeof( fname )-1 ); /* ick */ + + /* THIS DOES NOT WORK! */ + sprintf(message, "error: please login to host %s via appleshare", + fname ); + NewStatus( message ); + sleep( 3 ); /* bleh!! */ + /* PAPShutdown( cno ); /* */ + PAPClose( cno, TRUE ); /* arg2 is ignored!! */ + /* what does it mean? */ + + continue; + } /* not ok */ + } /* have aufsdb */ + /* ....budd ***/ + if (!singlefork) { if (fork() != 0) { PAPShutdown(cno); /* kill off connection */ *************** *** 347,355 **** fprintf(stderr,"lwsrv: Preserving file in %s\n",tname); fprintf(stderr,"lwsrv: Printing job: %s; user %s; on %s\n", jobname,username,ctime(&t)); ! sprintf(buf,"/usr/ucb/lpr -P%s %s %s -J 'MacUser: %s' %s\n", ! unixpname,rflag ? "" : "-r",hflag ? "" : "-h", username,tname); ! system(buf); } p_cls(pf); /* close out the pap connection */ } --- 405,449 ---- fprintf(stderr,"lwsrv: Preserving file in %s\n",tname); fprintf(stderr,"lwsrv: Printing job: %s; user %s; on %s\n", jobname,username,ctime(&t)); ! if( aufsdb ) { ! char *av[20], **ap, printer[50]; ! int pid2, pid, f; ! ! sprintf( printer, "-P%s", unixpname ); ! ap = av; ! *ap++ = "lpr"; ! *ap++ = printer; ! if( !hflag ) ! *ap++ = "-h"; ! *ap++ = "-J"; ! *ap++ = "lwsrv output"; ! *ap = NULL; ! ! if( (pid = fork()) == 0 ) { ! close( 0 ); ! open( tname, 0 ); /* open temp file */ ! ! close( 1 ); /* remove any connection to any tty */ ! close( 2 ); /* so that lpr will use uid */ ! open( "/", 0 ); /* not getlogin(). */ ! dup( 1 ); ! ! setuid( requid ); ! execv( "/usr/ucb/lpr", av ); ! exit( 1 ); ! } ! else if( pid > 0 ) { ! while( (pid2 = wait(0)) != -1 && pid2 != pid ) ! ; ! } ! if( !rflag ) ! unlink( tname ); ! } ! else { ! sprintf(buf,"/usr/ucb/lpr -P%s %s %s -J 'MacUser: %s' %s\n", ! unixpname,rflag ? "" : "-r",hflag ? "" : "-h", username,tname); ! system(buf); ! } } p_cls(pf); /* close out the pap connection */ } *************** *** 380,383 **** --- 474,490 ---- sprintf(tmp,"status: %s",status); cpyc2pstr(statbuff.StatusStr, tmp); abSleep(0,TRUE); /* make sure protocol runs */ + } + + /**************** budd... ****************/ + /* duplicated in aufs.c and lwsrv.c sigh */ + make_userlogin( buf, dir, addrb ) + char *buf, *dir; + AddrBlock addrb; + { + sprintf( buf, "%s/net%d.%dnode%d", + dir, + nkipnetnumber(addrb.net), nkipsubnetnumber(addrb.net), + addrb.node + ); }