Path: utzoo!utgpu!cs.utexas.edu!wuarchive!uunet!stanford.edu!rutgers!cmcl2!kramden.acf.nyu.edu!brnstnd From: brnstnd@kramden.acf.nyu.edu (Dan Bernstein) Newsgroups: alt.sources Subject: kstuff 0.18 (part 3/6) Message-ID: <6015:May704:41:5491@kramden.acf.nyu.edu> Date: 7 May 91 04:41:54 GMT Followup-To: alt.sources.d Organization: IR Lines: 2531 #! /bin/sh # This is a shell archive. Remove anything before this line, then unpack # it by saving it into a file and typing "sh file". To overwrite existing # files, type "sh file -c". You can also feed this as standard input via # unshar, or by typing "sh 'BLURB.authd' <<'END_OF_FILE' XIf host X supports RFC 931, and if joe@X and sally@Y are connected Xthrough TCP, then sally can find out the name of joe. This package Xincludes authd, an RFC 931 server---the program that X runs to tell Xsally who joe is. Once you've installed it, your users can't escape the Xauthentication: if they telnet or rlogin or send mail or do whatever to Xanother host, that host can find out the username. X XThis package also includes a library that acts as an RFC 931 client--- Xthe routines that sally uses to ask X's server who joe is. You don't Xneed privileges to use the library, which should compile and run without Xtrouble on any BSD-derived system. (authd is not so portable; although Xit works without changes under SunOS and Ultrix, it might not work on Xother systems. The package includes testauthd to make sure it works.) X XThe previous version of authd was reported to work on the following Xsystems: X X Sun 2/170, SunOS 4.0 X Sun 4/280, SunOS 4.0.3 X Sun 3/80, SunOS 4.1 X Sun 3/160, SunOS 4.1 X Sun 3/180, SunOS 4.1 X Sun 4/60, SunOS 4.1 X Sun 4/330, SunOS 4.1 X DECsystem-5820, Ultrix 4.0 X DECsystem-5820, Ultrix 4.1 X DECStation-5400, Ultrix 4.1 X VAX 8650, Ultrix 4.1 X MicroVAX III, BSD 4.3+NFS X HP9000 Series 300, HP-UX 7.0 X HP9000 Series 400, HP-UX 7.0 X HP9000 Series 800, HP-UX 7.0 X Convex C210, Convex UNIX 8.0 X XI've placed this code into the public domain because I think that Xeveryone should support at least this level of security. I'm sick of Xseeing people forge mail and spoof NNTP and attack systems anonymously Xthrough the network. Now they won't be able to, because every connection Xwill be tagged with the username with at least as much security as the XTCP host address in each packet. I hope that every site will do its part Xto contribute to network security (and to help CERT trace intruders). X XIt should take approximately 10 minutes to read the instructions and Xcompile, install, and test authd on a new machine. It should take Xapproximately 2 minutes on each new machine once you're familiar with Xthe instructions. Send comments on these estimates to brnstnd@nyu.edu, Xcc the Office of Management and Budget, Paperwork Reduction Division. X X---Dan Bernstein, brnstnd@nyu.edu END_OF_FILE if test 2201 -ne `wc -c <'BLURB.authd'`; then echo shar: \"'BLURB.authd'\" unpacked with wrong size! fi # end of 'BLURB.authd' fi if test -f 'FILES' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'FILES'\" else echo shar: Extracting \"'FILES'\" \(2483 characters\) sed "s/^X//" >'FILES' <<'END_OF_FILE' XBLURB XREADME XCHANGES XFORMLETTER XFILES XMakefile XINSTALL XBLURB.authd XREADME.authd Xload.1 Xauthuser.3 Xauthd.8 Xtcpuid.8 Xtcpuname.8 Xpff.doc XOFILES.hist Xrfc931 Xauread.h Xauthuser.h Xavenrun.h Xboottime.h Xconfclonedev.h Xconfconvexfilegarbage.h Xconfconvexrpcnfs.h Xconfconvexsysfile.h Xconfdevt.h Xconfdomain.h Xconfetcconfhfileh.h Xconffcredptr.h Xconffree.h Xconfgetuserconvex.h Xconfgetuserdynix.h Xconfgetusermips.h Xconfgetusersupport.h Xconfgnode.h Xconfhavepflag.h Xconfhaveppid.h Xconfhavepsuid.h Xconfhaveucred.h Xconfhaveusigintr.h Xconfhavevmseg.h Xconfitype.h Xconfkvm.h Xconfloadavglong.h Xconfmajorminor.h Xconfmalloc.h Xconfmntent.h Xconfmntult.h Xconfneedartospte.h Xconfneedmachparam.h Xconfneedmntinfo.h Xconfnfs.h Xconfnlistknlist.h Xconfnlistmeaning.h Xconfnlistunder.h Xconfnlname.h Xconfnonsfinet.h Xconfnounpaddr.h Xconfodofe.h Xconfopalf.h Xconfpcredinproc.h Xconfpcredunderproc.h Xconfpsess.h Xconfregion.h Xconfrtype.h Xconfslowstat.h Xconfsocketneedsxnode.h Xconfsyncsema.h Xconfsysucred.h Xconftcpnlist.h Xconftext.h Xconftextneedsvmparam.h Xconfttyvp.h Xconfultrixrpcnfs.h Xconfundefstdcbeforedir.h Xconfuofile.h Xconfusrptnlist.h Xconfvmunix.h Xconfvtype.h Xfiletable.h Xgetdevicename.h Xgetfcred.h Xgetnode.h Xgetopt.h Xgetpcred.h Xgetsocket.h Xgetuser.h Xgetvmseg.h Xgroupname.h Xinpcblist.h Xkmem.h Xmallocfree.h Xmmem.h Xmntops.h Xnetinp.h Xnlistlist.h Xnumeric.h Xportname.h Xprintfamily.h Xprintfflag.h Xprintftype.h Xprintprotoinet.h Xprintpstat.h Xprintrlimits.h Xprintrusage.h Xprintsocktype.h Xprintucred.h Xproctable.h Xrevnamei.h Xrpcnfs.h Xsmem.h Xstattimeout.h Xstrerr.h Xstructfile.h Xstructinpcb.h Xstructmbuf.h Xstructmtab.h Xstructproc.h Xstructprotosw.h Xstructpte.h Xstructsockaddrin.h Xstructsocket.h Xstructtcp.h Xstructtext.h Xstructucred.h Xstructunpcb.h Xstructuser.h Xstructxnode.h Xusername.h Xvirtype.h Xvmstuff.h Xauread.c Xauthd.c Xauthuser.c Xavenrun.c Xboottime.c Xfiletable.c Xgetdevicename.c Xgetfcred.c Xgetnode.c Xgetpcred.c Xgetsocket.c Xgetuser.c Xgetvmseg.c Xgroupname.c Xinpcblist.c Xkmem.c Xload.c Xmmem.c Xmntops.c Xnetinp.c Xnetstatuids.c Xnlistlist.c Xnumeric.c Xpff.c Xportname.c Xprintfamily.c Xprintfflag.c Xprintftype.c Xprintprotoinet.c Xprintpstat.c Xprintrlimits.c Xprintrusage.c Xprintsocktype.c Xprintucred.c Xproctable.c Xrevnamei.c Xsmem.c Xstattimeout.c Xstrerr.c Xtestauthd.c Xusername.c Xvirtype.c Xfindinode Xfindinode/README Xfindinode/FILES Xfindinode/Makefile Xfindinode/FIDDIR Xfindinode/INSTALL Xfindinode/fsupdatefid Xfindinode/fid.h Xfindinode/fid.c Xfindinode/updatefid.c Xfindinode/findinode.c Xfindinode/updatefid.8 Xfindinode/findinode.1 Xfindinode/getopt.h END_OF_FILE if test 2483 -ne `wc -c <'FILES'`; then echo shar: \"'FILES'\" unpacked with wrong size! fi # end of 'FILES' fi if test -f 'authuser.3' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'authuser.3'\" else echo shar: Extracting \"'authuser.3'\" \(3350 characters\) sed "s/^X//" >'authuser.3' <<'END_OF_FILE' X.TH authuser 3 X.SH NAME Xauthuser \- library to get information from a remote Authentication Server X.SH SYNTAX X.B #include X.PP X.B unsigned short auth_tcpport; X.PP X.B char *auth_xline(user,fd,&in); X.PP X.B int auth_fd(fd,&in,&local,&remote); X.PP X.B char *auth_tcpuser(in,local,remote); X.PP X.B char *user; X.br X.B int fd; X.br X.B unsigned long in; X.br X.B unsigned short local; X.br X.B unsigned short remote; X.SH DESCRIPTION XThe X.I authuser Xlibrary provides a simple interface for Xfinding out the remote identity Xof a connection through the XAuthentication Server Xas specified by RFC 931. XUse the -lauthuser loader option Xto compile a program with this library. X.PP X.B auth_xline(user,fd,&in) Xreturns a line of the form X-Auth-User: user or X-Forgery-By: username, Xdepending upon what the host on the other side of X.B fd Xthinks of the user. XThis is particularly appropriate for Xmail and news headers. X.PP XIf the remote host reports that X.B user Xowns the connection on that side, X.B auth_xline Xwill return X-Auth-User: user. XIf the remote host reports that a different X.B username Xowns the connection, X.B auth_xline Xwill return X-Forgery-By: username. XIf user is NULL, Xit returns X-Auth-User: username Xwith the username reported by the remote host. XIf X.B fd Xis not a TCP connection Xor authentication is impossible, X.B auth_xline Xreturns NULL, setting errno appropriately. X.PP XThe line is not cr-lf terminated. XIt is stored in a static area Xwhich is overwritten on each call to X.B auth_xline. X.B auth_xline Xplaces the Internet address of the other host into in. X.PP X.B auth_fd(fd,&in,&local,&remote) Xretrieves address information from the connection in socket X.B fd. XIt places the XInternet address of the host on other side into X.B in Xand the local and remote XTCP ports into X.B local Xand X.B remote. X.B auth_fd Xreturns -1 upon error, setting errno appropriately. X.PP X.B auth_tcpuser(in,local,remote) Xreturns the name of the user on the other end of the TCP connection Xbetween X.B remote@in Xand X.B local. XIf authentication is impossible, X.B auth_tcpuser Xreturns XNULL, setting errno appropriately. XThe user name is stored in a static area Xwhich is overwritten on each call to X.B auth_tcpuser Xand X.B auth_xline. X.PP XThe authentication routines check with the Xremote Authentication Server on port X.B auth_tcpport, Xwhich defaults to 113 Xas specified by RFC 931. XYou can set X.B auth_tcpport Xto other values Xfor nonstandard implementations. X.PP X.SH RESTRICTIONS X.I authuser Xdoes no backslash interpretation Xupon the remote user name. XHopefully the next revision of RFC 931 Xwill make clear exactly what backslash Xinterpretation should be going on. X.PP X.I authuser Xdoes not use the operating system type Xinformation provided by the Authentication Server. X.SH VERSION Xauthuser version 3.1, May 6, 1991. X.SH AUTHOR XPlaced into the public domain by Daniel J. Bernstein. X.SH REFERENCES XThe authentication server is more secure than passwords Xin some ways, but less secure than passwords in many ways. X(It's certainly better than no password at all---e.g., for Xmail or news.) XIt is not the final solution. XFor an excellent discussion of security problems within Xthe TCP/IP protocol suite, see XSteve Bellovin's article X``Security Problems in the TCP/IP Protocol Suite.'' X.SH "SEE ALSO" Xauthtcp(1), Xattachport(1), Xgetpeername(3), Xgetsockname(3), Xtcp(4), Xauthd(8) END_OF_FILE if test 3350 -ne `wc -c <'authuser.3'`; then echo shar: \"'authuser.3'\" unpacked with wrong size! fi # end of 'authuser.3' fi if test -f 'authuser.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'authuser.c'\" else echo shar: Extracting \"'authuser.c'\" \(3622 characters\) sed "s/^X//" >'authuser.c' <<'END_OF_FILE' X/* X5/6/91 DJB baseline authuser 3.1. Public domain. X*/ X X#include X#include X#include X#include X#include X#include X#include X#include Xextern int errno; X#include "authuser.h" X Xunsigned short auth_tcpport = 113; X X#define SIZ 500 /* various buffers */ X Xstatic int usercmp(u,v) Xregister char *u; Xregister char *v; X{ X /* is it correct to consider Foo and fOo the same user? yes */ X /* but the function of this routine may change later */ X while (*u && *v) X if (tolower(*u) != tolower(*v)) X return tolower(*u) - tolower(*v); X else X ++u,++v; X return *u || *v; X} X Xstatic char authline[SIZ]; X Xchar *auth_xline(user,fd,in) Xregister char *user; /* the supposed name of the user, NULL if unknown */ Xregister int fd; /* the file descriptor of the connection */ Xregister unsigned long *in; X{ X unsigned short local; X unsigned short remote; X register char *ruser; X X if (auth_fd(fd,in,&local,&remote) == -1) X return 0; X ruser = auth_tcpuser(*in,local,remote); X if (!ruser) X return 0; X if (!user) X user = ruser; /* forces X-Auth-User */ X (void) sprintf(authline, X (usercmp(ruser,user) ? "X-Forgery-By: %s" : "X-Auth-User: %s"), X ruser); X return authline; X} X Xint auth_fd(fd,in,local,remote) Xregister int fd; Xregister unsigned long *in; Xregister unsigned short *local; Xregister unsigned short *remote; X{ X struct sockaddr_in sa; X int dummy; X X dummy = sizeof(sa); X if (getsockname(fd,&sa,&dummy) == -1) X return -1; X if (sa.sin_family != AF_INET) X { X errno = EAFNOSUPPORT; X return -1; X } X *local = ntohs(sa.sin_port); X dummy = sizeof(sa); X if (getpeername(fd,&sa,&dummy) == -1) X return -1; X *remote = ntohs(sa.sin_port); X *in = sa.sin_addr.s_addr; X return 0; X} X Xstatic char ruser[SIZ]; Xstatic char realbuf[SIZ]; Xstatic char *buf; X Xchar *auth_tcpuser(in,local,remote) Xregister unsigned long in; Xregister unsigned short local; Xregister unsigned short remote; X{ X struct sockaddr_in sa; X register int s; X register int buflen; X register int w; X register int saveerrno; X char ch; X unsigned short rlocal; X unsigned short rremote; X X if ((s = socket(AF_INET,SOCK_STREAM,0)) == -1) X return 0; X sa.sin_family = AF_INET; X sa.sin_port = htons(auth_tcpport); X sa.sin_addr.s_addr = in; X if (connect(s,&sa,sizeof(sa)) == -1) X { X saveerrno = errno; X (void) close(s); X errno = saveerrno; X return 0; X } X X buf = realbuf; X (void) sprintf(buf,"%u , %u\r\n",(unsigned int) remote,(unsigned int) local); X /* note the reversed order---the example in the RFC is misleading */ X buflen = strlen(buf); X while ((w = write(s,buf,buflen)) < buflen) X if (w == -1) /* should we worry about 0 as well? */ X { X saveerrno = errno; X (void) close(s); X errno = saveerrno; X return 0; X } X else X { X buf += w; X buflen -= w; X } X buf = realbuf; X while ((w = read(s,&ch,1)) == 1) X { X *buf = ch; X if ((ch != ' ') && (ch != '\t') && (ch != '\r')) X ++buf; X if ((buf - realbuf == sizeof(realbuf) - 1) || (ch == '\n')) X break; X } X if (w == -1) X { X saveerrno = errno; X (void) close(s); X errno = saveerrno; X return 0; X } X *buf = '\0'; X X if (sscanf(realbuf,"%hd,%hd: USERID :%*[^:]:%s",&rremote,&rlocal,ruser) < 3) X { X (void) close(s); X errno = EIO; X /* makes sense, right? well, not when USERID failed to match ERROR */ X /* but there's no good error to return in that case */ X return 0; X } X if ((remote != rremote) || (local != rlocal)) X { X (void) close(s); X errno = EIO; X return 0; X } X /* XXX: we're not going to do any backslash processing */ X (void) close(s); X return ruser; X} END_OF_FILE if test 3622 -ne `wc -c <'authuser.c'`; then echo shar: \"'authuser.c'\" unpacked with wrong size! fi # end of 'authuser.c' fi if test -f 'avenrun.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'avenrun.c'\" else echo shar: Extracting \"'avenrun.c'\" \(2091 characters\) sed "s/^X//" >'avenrun.c' <<'END_OF_FILE' X/* History: X5/1/91 DJB baseline public domain X*/ X X/* getavenrun() returns a pointer into an array of 3 doubles giving the */ X/* current load average (i.e., AVErage Number of RUNning jobs). The first */ X/* is typically the 1-minute average, the second is the 5-minute average, */ X/* and the third is the 15-minute average. getavenrun returns 0 on error. */ X X/* avenruninit() does optional initialization to cooperate with other */ X/* libraries that use nlistlist. avenruninit returns -1 on error. */ X X/* avenrunstrerr is a strerrfun for use with the strerr library. */ X X#include "avenrun.h" X#include "kmem.h" X#include "nlistlist.h" X#include "strerr.h" X#include "confloadavglong.h" X X#define AVENRUNNLIST "_avenrun" X Xstatic int avinit = 0; X Xstatic double av[3]; Xstatic short avtype; Xstatic unsigned long avvalue; Xstatic int avenrunerrno = 0; X Xstatic struct strerrtab e[] = { X { 0, "avenrun error 0", 0 } X#define AV_INIT 1 X, { AV_INIT, "cannot init avenrun: ", nliststrerr } X#define AV_NLIST 2 X, { AV_NLIST, "cannot nlist: ", nliststrerr } X#define AV_NLISTFOUND 3 X, { AV_NLISTFOUND, AVENRUNNLIST, nlistnotin } X#define AV_KMEM 4 X, { AV_KMEM, "cannot read avenrun: ", kmemstrerr } X}; X Xchar *avenrunstrerr(ke) Xstrerrfun *ke; X{ X return strerrtaberr(ke,avenrunerrno,e,sizeof(e)/sizeof(*e),"unknown avenrun error"); X} X Xint avenruninit() X{ X if (nlistadd(AVENRUNNLIST,&avtype,&avvalue) == -1) X RETERN(-1,avenrunerrno,AV_INIT) X avinit = 1; X return 0; X} X X#ifdef LOADAVGISLONG Xstatic long avd[3]; X#endif X Xdouble *getavenrun() X{ X if (!avinit) X if (avenruninit() == -1) X return 0; X if (avtype == -1) X if (nlistdo() == -1) X RETERN(0,avenrunerrno,AV_NLIST) X if (!avtype) X RETERN(0,avenrunerrno,AV_NLISTFOUND) X#ifdef LOADAVGISLONG X if (kmemcpy((char *) &(avd[0]),(char *) avvalue,sizeof(avd)) == -1) X RETERN(0,avenrunerrno,AV_KMEM) X av[0] = ((double) avd[0]) / LOADAVGISLONG; X av[1] = ((double) avd[1]) / LOADAVGISLONG; X av[2] = ((double) avd[2]) / LOADAVGISLONG; X#else X if (kmemcpy((char *) &(av[0]),(char *) avvalue,sizeof(av)) == -1) X RETERN(0,avenrunerrno,AV_KMEM) X#endif X return av; X} END_OF_FILE if test 2091 -ne `wc -c <'avenrun.c'`; then echo shar: \"'avenrun.c'\" unpacked with wrong size! fi # end of 'avenrun.c' fi if test -f 'filetable.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'filetable.c'\" else echo shar: Extracting \"'filetable.c'\" \(2666 characters\) sed "s/^X//" >'filetable.c' <<'END_OF_FILE' X/* History: X5/1/91 DJB baseline public domain X*/ X X/* X Xstruct file *getfiletable() returns a pointer to a not necessarily Xatomic copy of the file table. myfile is the base of the file table in Xreal kernel memory, i.e., _file. mynfile is the number of entries in the Xfile table, i.e., _nfile. X Xfiletableinit() does optional initialization to cooperate with other Xlibraries. X Xfiletablestrerr is a strerrfun for filetableinit() and getfiletable(). X X*/ X X#include "mallocfree.h" X#include "structfile.h" X#include "filetable.h" X#include "kmem.h" X#include "nlistlist.h" X#include "strerr.h" X X#define FILENLIST "_file" X#define NFILENLIST "_nfile" X Xstatic int finit = 0; Xstatic struct file *filetable = 0; Xstatic short ftype; Xstatic short nftype; Xstatic unsigned long fvalue; Xstatic unsigned long nfvalue; Xstruct file *myfile; Xint mynfile; Xstatic int filetableerrno = 0; X Xstatic struct strerrtab e[] = { X { 0, "filetable error 0", 0 } X#define FT_INIT 1 X, { FT_INIT, "cannot init filetable: ", nliststrerr } X#define FT_NLIST 2 X, { FT_NLIST, "cannot nlist: ", nliststrerr } X#define FT_NLFFOUND 3 X, { FT_NLFFOUND, FILENLIST, nlistnotin } X#define FT_NLNFFOUND 4 X, { FT_NLNFFOUND, NFILENLIST, nlistnotin } X#define FT_NLFREAD 5 X, { FT_NLFREAD, "cannot read file table pointer: ", kmemstrerr } X#define FT_NLNFREAD 6 X, { FT_NLNFREAD, "cannot read nfile: ", kmemstrerr } X#define FT_FTREAD 7 X, { FT_FTREAD, "cannot read file table: ", kmemstrerr } X#define FT_ALLOC 8 X, { FT_ALLOC, "out of memory", 0 } X} ; X Xchar *filetablestrerr(ke) Xstrerrfun *ke; X{ X return strerrtaberr(ke,filetableerrno,e,sizeof(e)/sizeof(*e),"unknown filetable error"); X} X Xint filetableinit() X{ X if (nlistadd(FILENLIST,&ftype,&fvalue) == -1) X RETERN(-1,filetableerrno,FT_INIT) X if (nlistadd(NFILENLIST,&nftype,&nfvalue) == -1) X RETERN(-1,filetableerrno,FT_INIT) X finit = 1; X return 0; X} X Xstruct file *getfiletable() X{ X if (!finit) X if (filetableinit() == -1) X return 0; X if (ftype == -1) X if (nlistdo() == -1) X RETERN(0,filetableerrno,FT_NLIST) X if (!ftype) X RETERN(0,filetableerrno,FT_NLFFOUND) X if (!nftype) X RETERN(0,filetableerrno,FT_NLNFFOUND) X if (kmemcpy((char *) &mynfile,(char *) nfvalue,sizeof(mynfile)) == -1) X RETERN(0,filetableerrno,FT_NLFREAD) X if (kmemcpy((char *) &myfile,(char *) fvalue,sizeof(myfile)) == -1) X RETERN(0,filetableerrno,FT_NLNFREAD) X X if (filetable) X free((char *) filetable); X filetable = (struct file *) malloc((unsigned) (sizeof(struct file) * mynfile)); X if (!filetable) X RETERN(0,filetableerrno,FT_ALLOC) X X if (kmemcpy((char *) filetable,(char *) myfile,sizeof(struct file) * mynfile) == -1) X RETERN(0,filetableerrno,FT_FTREAD) X X return filetable; X} END_OF_FILE if test 2666 -ne `wc -c <'filetable.c'`; then echo shar: \"'filetable.c'\" unpacked with wrong size! fi # end of 'filetable.c' fi if test -f 'findinode/findinode.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'findinode/findinode.c'\" else echo shar: Extracting \"'findinode/findinode.c'\" \(3687 characters\) sed "s/^X//" >'findinode/findinode.c' <<'END_OF_FILE' X#include X#include X#include X#include X#include X#include "getopt.h" X#include "fid.h" X X/* XXX: This has really shoddy error checking. */ X Xint nonl(s) Xchar *s; X{ X while (*s) X { X if (*s == '\n') X return 0; X ++s; X } X return 1; X} X Xmain(argc,argv) Xint argc; Xchar *argv[]; X{ X struct node f; X struct nodenum fn; X struct dnodenum dn; X struct stat st; X int i; X int j; X static struct dnodenum dnarr[100]; X struct stat stroot; X DIR *dirp; X struct direct *dp; X static char line[1000]; X int flagjustone; X int opt; X int uid; X X uid = getuid(); X X if (fidinit() == -1) X { X fprintf(stderr,"findinode: fatal: cannot open fid database\n"); X exit(1); X } X X if (lstat("/",&stroot) == -1) X { X fprintf(stderr,"findinode: fatal: cannot lstat /\n"); X exit(1); X } X X flagjustone = 0; X X while ((opt = getopt(argc,argv,"aA")) != EOF) X switch(opt) X { X case 'a': flagjustone = 0; break; X case 'A': flagjustone = 1; break; X case '?': ; /*XXX*/ X } X X while (fgets(line,sizeof(line),stdin)) /* XXX: truncation */ X { X line[strlen(line) - 1] = 0; X if (sscanf(line,"%lu %lx",&f.i,&f.d) < 2) X if (lstat(line,&st) == -1) X { X printf(": %s\n",line); X fflush(stdout); X continue; X } X else X { X f.i = st.st_ino; X f.d = st.st_dev; X } X f.i = (unsigned long) (ino_t) f.i; X f.d = (unsigned long) (dev_t) f.d; X i = fidfilesget(f); X /* XXX: put all this searching stuff into a function returning a string? */ X#ifdef notdef X printf("file %s (%lu %lx) links %u\n",argv[1],f.i,f.d,i); X#endif X if (!i) X if (f.i == stroot.st_ino && f.d == stroot.st_dev) X printf("%lu %lx: /\n",f.i,f.d); X else X printf("%lu %lx: \n",f.i,f.d); X if (i > 1 && flagjustone) X i = 1; X for (;i;--i) X { X /* Get the directories. */ X fidlock(); X if (i > fidfilesget(f)) X { X fidunlock(); X continue; /* just in case database changed */ X } X fn.x = f; fn.n = i; X dnarr[0].x.i = fn.x.i; dnarr[0].x.d = fn.x.d; X dnarr[j = 1] = dn = fidf2dget(fn); X printf("%lu %lx: ",f.i,f.d); X while (fn.x.i = dn.x.i, fn.x.d = dn.x.d, fidfilesget(fn.x) > 0) X { X /* XXX: could report an error if fidfilesget() > 1 */ X fn.n = 1; X dn = dnarr[++j] = fidf2dget(fn); X if (j == 99) X break; /*XXX*/ X } X fidunlock(); X X if (dnarr[j].x.i == stroot.st_ino && dnarr[j].x.d == stroot.st_dev) X { X chdir("/"); X do X { X printf("/"); X dirp = opendir("."); X --j; X while (dp = readdir(dirp)) X { X if (dp->d_name[0] == 0) X continue; X if (dp->d_name[0] == '.' && dp->d_name[1] == 0) X continue; X if (dp->d_name[0] == '.' && dp->d_name[1] == '.' && dp->d_name[2] == 0) X continue; X if (lstat(dp->d_name,&st) != -1) X if (dnarr[j].x.i == st.st_ino && dnarr[j].x.d == st.st_dev) X if (!j || (chdir(dp->d_name) != -1)) X { X if (nonl(dp->d_name)) X printf("%s",dp->d_name); X else X printf("/"); /* XXX: should have -0 option */ X if (j) X { X /* XXX: maybe access(".",R_OK) would work ok here. */ X /* and X_OK---this is too blunt but easier than */ X /* doing it right */ X if (uid && (st.st_uid != uid) && !(st.st_mode & 0005)) X { X j = 0; X printf("//"); X } X } X break; X } X } X closedir(dirp); X if (!dp) /* XXX: gee, is this valid under ANSI? :-) */ X { X printf("/"); X break; X } X } X while (j); X } X else X printf(""); /*XXX*/ X putchar('\n'); X /*XXX: -0?*/ X } X fflush(stdout); X } X} END_OF_FILE if test 3687 -ne `wc -c <'findinode/findinode.c'`; then echo shar: \"'findinode/findinode.c'\" unpacked with wrong size! fi # end of 'findinode/findinode.c' fi if test -f 'findinode/updatefid.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'findinode/updatefid.c'\" else echo shar: Extracting \"'findinode/updatefid.c'\" \(2654 characters\) sed "s/^X//" >'findinode/updatefid.c' <<'END_OF_FILE' X#include X#include X#include X#include X#include "fid.h" X X/* XXX: error checks? */ X X/* XXX: should we periodically seek out and destroy files/dirs with 0 links? */ X Xremove(f,linknum,d,entnum) Xstruct node f; Xint linknum; Xstruct dnode d; Xint entnum; X{ X int linkmax; X int entmax; X struct nodenum fn; X struct dnodenum dn; X X fn.x = f; fn.n = linknum; fidf2ddel(fn); X dn.x = d; dn.n = entnum; fidd2fdel(dn); X linkmax = fidfilesget(f); X if (linknum < linkmax) X { X fn.x = f; fn.n = linkmax; X dn = fidf2dget(fn); fidf2ddel(fn); fidd2fdel(dn); X fn.n = linknum; fidf2dput(fn,dn); fidd2fput(dn,fn); X } X entmax = fiddirsget(d); X if (entnum < entmax) X { X dn.x = d; dn.n = entmax; X fn = fidd2fget(dn); fidd2fdel(dn); fidf2ddel(fn); X dn.n = entnum; fidd2fput(dn,fn); fidf2dput(fn,dn); X } X if (--linkmax) fidfilesput(f,linkmax); else fidfilesdel(f); X if (--entmax) fiddirsput(d,entmax); else fiddirsdel(d); X} X Xadd(f,d) Xstruct node f; Xstruct dnode d; X{ X int linkmax; X int entmax; X struct nodenum fn; X struct dnodenum dn; X X linkmax = fidfilesget(f); ++linkmax; fidfilesput(f,linkmax); X entmax = fiddirsget(d); ++entmax; fiddirsput(d,entmax); X fn.x = f; fn.n = linkmax; X dn.x = d; dn.n = entmax; X fidf2dput(fn,dn); X fidd2fput(dn,fn); X} X Xint dodir() X{ X struct node f; X struct dnode d; X struct nodenum fn; X struct dnodenum dn; X DIR *dirp; X struct direct *dp; X struct stat st; X int i; X long t; X long modt; X X if (lstat(".",&st) == -1) X return -1; X dirp = opendir("."); X if (!dirp) X return -1; X fidlock(); X d.i = st.st_ino; d.d = st.st_dev; X modt = st.st_mtime; if (modt < st.st_ctime) modt = st.st_ctime; X t = fiddirtimesget(d); /* XXX: should have flag to skip this test */ X if (t == modt) X { X fidunlock(); X return 0; X } X fiddirtimesput(d,0); /* marking dir for update */ X i = fiddirsget(d); X dn.x = d; X while (i) /* wipe out old entries */ X { X dn.n = i; X fn = fidd2fget(dn); X#ifdef notdef X printf("[- %u %u %u %u] ",fn.x.i,fn.x.d,dn.x.i,dn.x.d); X#endif X remove(fn.x,fn.n,dn.x,dn.n); X --i; X } X while (dp = readdir(dirp)) /* put in new entries */ X { X if (dp->d_name[0] == 0) X continue; X if (dp->d_name[0] == '.' && dp->d_name[1] == 0) X continue; X if (dp->d_name[0] == '.' && dp->d_name[1] == '.' && dp->d_name[2] == 0) X continue; X if (lstat(dp->d_name,&st) != -1) X { X f.i = st.st_ino; f.d = st.st_dev; X#ifdef notdef X printf("[+ %u %u %u %u] ",f.i,f.d,d.i,d.d); X#endif X add(f,d); X } X } X fidunlock(); X fiddirtimesput(d,modt); X return 0; X} X Xmain(argc,argv) Xint argc; Xchar *argv[]; X{ X fidinit(); X X while (*++argv) X if (chdir(*argv) == 0) X dodir(); X} END_OF_FILE if test 2654 -ne `wc -c <'findinode/updatefid.c'`; then echo shar: \"'findinode/updatefid.c'\" unpacked with wrong size! fi # end of 'findinode/updatefid.c' fi if test -f 'getdevicename.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'getdevicename.c'\" else echo shar: Extracting \"'getdevicename.c'\" \(3848 characters\) sed "s/^X//" >'getdevicename.c' <<'END_OF_FILE' X/* History: X5/1/91 DJB baseline. todo: hash device names. X3/15/91 DJB separated into library function XOriginally stolen from printdevice() in Dupuy ofiles. X*/ X X/* X Xchar *getdevicename(node) struct Xnode *node; returns the name of a Xdevice in /dev (e.g., /dev/kmem) with the same remote device as node, or X0 if no such device exists. X Xchar *getttydevname(dev) dev_t dev; returns the name of a character Xdevice with the given remote device, or 0 if no such device exists. XXX Xfor the name and modularization: this is used to find the ctty of a Xprocess given u_ttyd, but that doesn't make it logical. X X*/ X X#include X#include X#include X#include "confnfs.h" X#include "confundefstdcbeforedir.h" X#ifdef UNDEFSTDCBEFOREDIR /* stupid features don't deserve short names */ X#undef __stdc__ /* dorks */ X#endif X#include X#include Xextern int errno; X#include "mallocfree.h" X#include "structxnode.h" X#include "confgnode.h" X#include "confclonedev.h" X#include "confmajorminor.h" X Xstatic char dev[] = "/dev/"; X Xstatic int scanned = 0; X Xstruct devname X { X struct devname *next; X char *name; X unsigned mode; X dev_t rdev; X#ifdef CLONEDEV X short clonedev; X#endif X#ifndef NFS X unsigned ino; X#endif X } X; X Xstatic struct devname *devnamelist = 0; X Xstatic int scandev() X{ X struct stat status; X register struct direct *entry; X register DIR *devdir; X register struct devname *dvent; X X scanned = 1; X X errno = 0; X if (!(devdir = opendir(dev))) X return -1; /*XXX*/ X X if (dvent = (struct devname *) malloc(sizeof(struct devname))) X { X while (entry = readdir(devdir)) X { X if (!(dvent->name = malloc(sizeof(dev) + strlen(entry->d_name)))) X break; X (void) strcpy(dvent->name,dev); X (void) strcat(dvent->name,entry->d_name); X if (stat(dvent->name, &status) < 0 X || ((status.st_mode & S_IFMT) != S_IFBLK X && (status.st_mode & S_IFMT) != S_IFCHR)) X { X free((char *) dvent->name); X continue; X } X X dvent->mode = status.st_mode & S_IFMT; X dvent->rdev = status.st_rdev; X#ifdef CLONEDEV X if (dvent->mode == S_IFCHR && major(dvent->rdev) == CLONEDEV) X dvent->clonedev = minor(dvent->rdev); X else X dvent->clonedev = -1; X#endif X#ifndef NFS X dvent->ino = status.st_ino; X#endif X dvent->next = devnamelist; X devnamelist = dvent; X if (!(dvent = (struct devname *) malloc(sizeof(struct devname)))) X break; X } X free ((char *) dvent); X } X closedir(devdir); X return 0; X} X Xchar *getdevicename(node) Xstruct Xnode *node; X{ X register struct devname *dvent; X X if (!scanned) X if (scandev() == -1) X return 0; /*XXX*/ X X for (dvent = devnamelist;dvent;dvent = dvent->next) X { X#ifdef NFS X if (dvent->rdev == node->v_rdev X && (dvent->mode == ((node->v_type == VBLK) ? S_IFBLK : S_IFCHR))) X#else X#ifdef GNODE X if (dvent->rdev == node->g_rdev && dvent->ino == node->g_number X && (dvent->mode == (((node->g_mode & GFMT) == GFBLK) ? S_IFBLK : S_IFCHR))) X#else X if (dvent->rdev == node->i_rdev && dvent->ino == node->i_number X && (dvent->mode == (((node->i_mode & IFMT) == IFBLK) ? S_IFBLK : S_IFCHR))) X#endif X#endif X return dvent->name; X#ifdef CLONEDEV X if (node->v_type == VCHR && dvent->clonedev > 0 X && major(node->v_rdev) == dvent->clonedev) X return dvent->name; X#endif X } X return 0; /*XXX*/ X} X Xchar *getttydevname(dev) Xdev_t dev; X{ X register struct devname *dvent; X X if (!scanned) X if (scandev() == -1) X return 0; /*XXX*/ X X for (dvent = devnamelist;dvent;dvent = dvent->next) X { X /*XXX: is this right normally? */ X if (dvent->rdev == dev X && (dvent->mode == S_IFCHR)) X return dvent->name; X#ifdef notdef /* XXX: CLONEDEV */ X if (node->v_type == VCHR && dvent->clonedev > 0 X && major(node->v_rdev) == dvent->clonedev) X return dvent->name; X#endif X } X return 0; /*XXX*/ X} END_OF_FILE if test 3848 -ne `wc -c <'getdevicename.c'`; then echo shar: \"'getdevicename.c'\" unpacked with wrong size! fi # end of 'getdevicename.c' fi if test -f 'kmem.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'kmem.c'\" else echo shar: Extracting \"'kmem.c'\" \(1753 characters\) sed "s/^X//" >'kmem.c' <<'END_OF_FILE' X/* History: X5/1/91 DJB baseline public domain X*/ X X/* X Xint kmemcpy(buf,pos,n) char *buf; char *pos; int n; copies n bytes from Xposition pos in kernel memory into buffer buf (in user memory). It Xreturns 0 on success, -1 on error. X Xkmeminit() is an optional initialization routine to cooperate with other Xlibraries. X Xkmemstrerr is a strerrfun for kmeminit() and kmemcpy(). X X*/ X X#include X#include X#include "kmem.h" X#include "strerr.h" X X#define KMEM "/dev/kmem" X X#define LSEEKFROMSTART 0 X Xstatic int kmemfd = -1; Xstatic int kmemerrno = 0; X Xstatic char *kmemerrprk(ke) strerrfun *ke; { *ke = strerrsys; return KMEM; } X Xchar *kmemstrerr(ke) Xstrerrfun *ke; X{ X *ke = 0; X switch(kmemerrno) X { X case 0: X return "kmem error 0"; X#define KMEM_OPEN 1 X case KMEM_OPEN: X *ke = kmemerrprk; X return "cannot open "; X#define KMEM_LSEEK 2 X case KMEM_LSEEK: X *ke = strerrsys; X return "cannot lseek kmem"; X#define KMEM_READ 3 X case KMEM_READ: X *ke = strerrsys; X return "cannot read kmem"; X#define KMEM_READZERO 4 X case KMEM_READZERO: X return "kmem read 0 bytes"; X default: X return "unknown kmem error"; X } X} X Xint kmeminit() X{ X kmemfd = open(KMEM,O_RDONLY); X if (kmemfd == -1) X RETERN(-1,kmemerrno,KMEM_OPEN) X return 0; X} X Xint kmemcpy(buf,pos,n) Xchar *buf; Xchar *pos; Xint n; X{ X int r; X X if (!n) X return 0; X if (kmemfd == -1) X if (kmeminit() == -1) X return -1; X if (lseek(kmemfd,(long) pos,LSEEKFROMSTART) == -1) X RETERN(-1,kmemerrno,KMEM_LSEEK) X while ((r = read(kmemfd,buf,n)) < n) X if (r == -1) X RETERN(-1,kmemerrno,KMEM_READ) X else if (r == 0) /* XXX: this can never happen */ X RETERN(-1,kmemerrno,KMEM_READZERO) X else X { X buf += r; X n -= r; X } X return 0; X} END_OF_FILE if test 1753 -ne `wc -c <'kmem.c'`; then echo shar: \"'kmem.c'\" unpacked with wrong size! fi # end of 'kmem.c' fi if test -f 'netinp.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'netinp.c'\" else echo shar: Extracting \"'netinp.c'\" \(2170 characters\) sed "s/^X//" >'netinp.c' <<'END_OF_FILE' X/* History: X5/1/91 DJB baseline public domain. todo: eliminate this file. XDerived from authd 3.01, DJB. X*/ X X#ifdef USENETSTAT X X#include "confnonsfinet.h" X#ifdef NONSFINET X#define NETSTAT "/usr/bin/netstat -n -A" X#endif X X/* End of machine define-mod section. */ X X#ifndef NETSTAT X#define NETSTAT "/usr/ucb/netstat -n -A -f inet" X#endif X#ifndef NETSTATBUF X#define NETSTATBUF 200 /* 80 would suffice */ X#endif X#ifndef NETSTATREMOTE X#define NETSTATREMOTE 49 /* has to be 53 for SunOS 4.1.1, I think */ X#endif X#ifndef NETSTATWIDTH X#define NETSTATWIDTH 17 X#endif X#ifndef REMOTESIZE X#define REMOTESIZE 100 /* guaranteed to be enough */ X#endif X X#endif X X#include XFILE *popen(); /* grrrr */ X#include "kmem.h" X#include "structinpcb.h" X#ifdef USENETSTAT X#include "structtcp.h" X#else X#include "inpcblist.h" X#endif X#include "netinp.h" X X#ifdef USENETSTAT Xstatic FILE *fi; Xstatic char remote[REMOTESIZE]; Xstatic char s[NETSTATBUF]; Xstatic int header; Xstatic int pcb; Xstatic struct tcpcb tcp; Xstatic struct inpcb inp; X Xchar *inploc; X Xint netinpinit(r1,r2,r3,r4,rp) Xint r1; Xint r2; Xint r3; Xint r4; Xint rp; X{ X fi = popen(NETSTAT,"r"); X if (!fi) X return -1; X (void) sprintf(remote,"%d.%d.%d.%d.%d ",r1,r2,r3,r4,rp); X header = 0; X return 0; X} X Xstruct inpcb *nextnetinp() X{ X if (!header) X { X header = 1; X if (!fgets(s,sizeof(s),fi)) X return 0; X if (!fgets(s,sizeof(s),fi)) X return 0; X } X do X { X if (!fgets(s,sizeof(s),fi)) X return 0; /* XXX: cannot distinguish from error */ X if (sscanf(s,"%8x",&pcb) != 1) X return 0; X } X while (strncmp(s + NETSTATREMOTE,remote,NETSTATWIDTH)); X if (kmemcpy((char *) &tcp,(char *) pcb,sizeof(tcp)) == -1) X return 0; X if (!tcp.t_inpcb) X return 0; X if (kmemcpy((char *) &inp,(char *) tcp.t_inpcb,sizeof(inp)) == -1) X return 0; X if (inp.inp_ppcb != (char *) pcb) X return 0; X inploc = tcp.t_inpcb; X return &inp; X} X X#else X Xchar *inploc; Xstatic struct inpcb *inp; X Xint netinpinit(r1,r2,r3,r4,rp) Xint r1; Xint r2; Xint r3; Xint r4; Xint rp; X{ X if (inpcblistinit() == -1) X return -1; X inp = 0; X} X Xstruct inpcb *nextnetinp() X{ X inp = nextinpcb(inp); X inploc = (char *) inpcbloc; X return inp; X} X X#endif END_OF_FILE if test 2170 -ne `wc -c <'netinp.c'`; then echo shar: \"'netinp.c'\" unpacked with wrong size! fi # end of 'netinp.c' fi if test -f 'netstatuids.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'netstatuids.c'\" else echo shar: Extracting \"'netstatuids.c'\" \(2453 characters\) sed "s/^X//" >'netstatuids.c' <<'END_OF_FILE' X/* History: X5/3/91 DJB modified to not compile without HAVE_UCRED X5/1/91 DJB baseline public domain X*/ X X#include "confhaveucred.h" X#ifndef HAVE_UCRED Xerror! error! error! XXX Xnetstatuids will not work on a system without struct ucred. X#endif X X#include X#include "structfile.h" X#include "structucred.h" X#include "structinpcb.h" X#include "inpcblist.h" X#include "filetable.h" X#include "getfcred.h" X#include "strerr.h" X#include "authuser.h" X#include X#include "mallocfree.h" X Xchar *pw(u) Xint u; X{ X struct passwd *pw; X char buf[20]; X X pw = getpwuid(u); X if (pw) X return pw->pw_name; X sprintf(buf,"%d",u); X return buf; X} X Xmain() X{ X struct inpcb *inp; X struct file *ft; X struct file *fp; X struct ucred *uc; X int *sfs; X int numsfs; X int i; X unsigned char *fa; X unsigned char *la; X char *user; X X if (filetableinit() == -1) X { X fprintf(stderr,"ns5: %s\n",strerr(filetablestrerr)); X exit(1); X } X if (inpcblistinit() == -1) X { X fprintf(stderr,"ns5: %s\n",strerr(inpcbliststrerr)); X exit(1); X } X X ft = getfiletable(); X if (!ft) X { X fprintf(stderr,"ns5: %s\n",strerr(filetablestrerr)); X exit(1); X } X sfs = (int *) malloc((unsigned) (sizeof(int) * mynfile)); X if (!sfs) X { X fprintf(stderr,"ns5: out of memory\n"); X exit(1); X } X numsfs = 0; X X for (fp = ft;fp < ft + mynfile;++fp) X if (fp->f_count && fp->f_type == DTYPE_SOCKET) X sfs[numsfs++] = fp - ft; X X inp = 0; X while (inp = nextinpcb(inp)) X for (i = 0;i < numsfs;++i) X if ((fp = ft + sfs[i])->f_data == (char *) inp->inp_socket) X { X sfs[i] = sfs[--numsfs]; X uc = getfcred(fp); X if (!uc) X { X fprintf(stderr,"ns5: warning: %s\n",strerr(getfcredstrerr)); X break; X } X fa = (unsigned char *) &(inp->inp_faddr); X la = (unsigned char *) &(inp->inp_laddr); X user = 0; X if (inp->inp_fport) X user = auth_tcpuser(inp->inp_faddr.s_addr X ,ntohs(inp->inp_lport) X ,ntohs(inp->inp_fport)); X else X break; /*XXX: unconnected server*/ X if (!user) X user = "?"; X printf("%s@%d.%d.%d.%d:%d\t%s@%d.%d.%d.%d:%d\n" X ,user X ,(unsigned) fa[0],(unsigned) fa[1],(unsigned) fa[2],(unsigned) fa[3] X ,ntohs(inp->inp_fport) X ,pw(uc->cr_ruid) X ,(unsigned) la[0],(unsigned) la[1],(unsigned) la[2],(unsigned) la[3] X ,ntohs(inp->inp_lport) X ); X fflush(stdout); /*XXX*/ X break; X } X X if (inperrno) X { X fprintf(stderr,"ns5: %s\n",strerr(inpcbliststrerr)); X exit(1); X } X exit(0); X} END_OF_FILE if test 2453 -ne `wc -c <'netstatuids.c'`; then echo shar: \"'netstatuids.c'\" unpacked with wrong size! fi # end of 'netstatuids.c' fi if test -f 'nlistlist.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'nlistlist.c'\" else echo shar: Extracting \"'nlistlist.c'\" \(3961 characters\) sed "s/^X//" >'nlistlist.c' <<'END_OF_FILE' X/* History: X5/1/91 DJB baseline public domain X*/ X X/* X XThe problem: Independent libraries want to access a shared resource, Xthe kernel name list. Normally, if those libraries were written Xindependently, they would each do a separate nlist(). This is Xunacceptably inefficient. X XThe solution: nlistlist. Other libraries can call nlistadd() in their Xinitialization routines, then nlistdo() before they need the data. Xnlistlist buffers all nlistadd()ed names and only looks them up on an Xnlistdo(). So independent libraries can cooperate merely by providing Xinitialization routines. X Xint nlistadd(name,type,value) char *name; short *type; unsigned long *value; Xsets *type to -1 and returns 0. Upon the next call to nlistdo(), name X(which should always begin with an underscore) will be looked up in the Xkernel's name list (typically /vmunix). The type of the returned address Xwill be stored in *type, and the value will be stored in *value. If Xthere is some problem, nlistadd returns -1, and the above operations Xwill not occur. The meaning of *type on a successful lookup varies from Xsystem to system, but a zero *type indicates that name is not in the Xname list. X Xnlistdo() handles all previous nlistadd()s as mentioned above. It Xreturns 0 on success, -1 on error. X Xnliststrerr is a strerrfun for nlistadd() and nlistdo(). X Xnlistnotin is a strerrfun for use by libraries using nlistlist. It Xprints a message like " not in nlist", and is appropriate after a type Xis returned as 0. X X*/ X X#include X#include "mallocfree.h" X#include "nlistlist.h" X#include "strerr.h" X#include "confnlistknlist.h" X#include "confnlistunder.h" X#include "confnlistmeaning.h" X#include "confvmunix.h" X#include "confnlname.h" X Xchar *nlistnotin(ke) Xstrerrfun *ke; X{ X return strerrstr(ke," not in nlist"); X} X Xstatic int nlisterrno = 0; X Xstatic struct strerrtab e[] = { X { 0, "nlist error 0", 0 } X#define NLIST_ALLOC 1 X, { NLIST_ALLOC, "cannot malloc for nlist", 0 } X#define NLIST_NLIST 2 X, { NLIST_NLIST, "nlist() failed", 0 } X} ; X Xchar *nliststrerr(ke) Xstrerrfun *ke; X{ X return strerrtaberr(ke,nlisterrno,e,sizeof(e)/sizeof(*e),"unknown nlist error"); X} X Xstatic struct nlistlist X { X char *name; X short *type; X unsigned long *value; X struct nlistlist *next; X } Xhead = { 0 , 0 }; X Xstatic int nlistnum = 0; X Xint nlistadd(name,type,value) Xchar *name; Xshort *type; Xunsigned long *value; X{ X struct nlistlist *t; X X t = head.next; X head.next = (struct nlistlist *) malloc(sizeof(struct nlistlist)); X if (!head.next) X { X head.next = t; X nlisterrno = NLIST_ALLOC; X return -1; X } X head.next->next = t; X head.next->name = name; X head.next->type = type; X head.next->value = value; X *type = -1; X ++nlistnum; X return 0; X} X Xint nlistdo() X{ X struct nlist *nl; X struct nlistlist *t; X struct nlistlist *tnext; X int i; X X if (!nlistnum) X return 0; X nl = (struct nlist *) malloc((unsigned) (sizeof(struct nlist) * (nlistnum + 1))); X if (!nl) X RETERN(-1,nlisterrno,NLIST_ALLOC) X i = 0; X for (t = head.next;t;t = t->next) X { X#ifdef FORGET_UNDERSCORES X NLNAME(nl[i]) = t->name + 1; X#else X NLNAME(nl[i]) = t->name; X#endif X ++i; X } X NLNAME(nl[i]) = ""; X#ifdef KNLIST X knlist(nl); X /* XXX: This appears to fail in some cases. So... */ X for (i = 0;i < nlistnum;++i) X if (!nl[i].n_value) X { X nlist(VMUNIX,nl); /*XXX*/ X break; X } X#else X#ifdef MEANINGLESS_NLIST X nlist(VMUNIX,nl); X#else X if (nlist(VMUNIX,nl) == -1) X { X free((char *) nl); X nlisterrno = NLIST_NLIST; X return -1; X } X#endif X#endif X#ifdef notdef /*XXX: debugging */ X printf("[nlist"); X while (i) { --i; printf(" %s:%x",NLNAME(nl[i]),nl[i].n_value); } X printf("]"); X#endif X i = 0; X for (t = head.next;t;t = tnext) X { X *(t->type) = nl[i].n_type; X /* XXX: force some uniformity on the types? */ X *(t->value) = nl[i].n_value; X /* XXX: let user give us a function to free t->name? */ X tnext = t->next; X free((char *) t); X ++i; X } X nlistnum = 0; X free((char *) nl); X head.next = 0; X return 0; X} END_OF_FILE if test 3961 -ne `wc -c <'nlistlist.c'`; then echo shar: \"'nlistlist.c'\" unpacked with wrong size! fi # end of 'nlistlist.c' fi if test -f 'printpstat.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'printpstat.c'\" else echo shar: Extracting \"'printpstat.c'\" \(1996 characters\) sed "s/^X//" >'printpstat.c' <<'END_OF_FILE' X/* History: X5/1/91 DJB baseline public domain X*/ X X/* X Xchar *printpstat(p) struct proc *p; returns a string representing Xvarious basic information about p's status (with p in user memory). XNot well defined. X X*/ X X#include X#include X#include "printpstat.h" X#include "structproc.h" X#include "confhavepflag.h" X Xstatic char result[300]; X/* XXX: 300 is guaranteed safe for the current code, but if you add */ X/* more printing flags, you may have to bring the number up. */ X Xchar *printpstat(p) Xstruct proc *p; X{ X int pstat; X int pflag; X char *t; X X pstat = p->p_stat; X#ifndef HAVE_PFLAG X pflag = p->p_select | p->p_sched | p->p_vm; /*XXX: annoying*/ X#else X pflag = p->p_flag; X#endif X X switch(pstat) X { X#ifdef SSLEEP X case SSLEEP: strcpy(result,"S "); break; X#endif X#ifdef SWAIT X case SWAIT: strcpy(result,"D "); break; X#endif X#ifdef SRUN X case SRUN: strcpy(result,"R "); break; X#endif X#ifdef SIDL X case SIDL: strcpy(result,"X "); break; X#endif X#ifdef SZOMB X case SZOMB: strcpy(result,"Z "); break; X#endif X#ifdef SSTOP X case SSTOP: strcpy(result,"T "); break; X#endif X default: strcpy(result,"? "); X } X t = result + 2; X X#define PFLAG(S,X) if (pflag & S) { strcpy(t,X); t += strlen(t); pflag &= ~S; } X X#ifdef SLOAD X PFLAG(SLOAD,"load ") X#endif X#ifdef SSYS X PFLAG(SSYS,"sys ") X#endif X#ifdef SLOCK X PFLAG(SLOCK,"lock ") X#endif X#ifdef SSWAP X PFLAG(SSWAP,"swap ") X#endif X#ifdef SOMASK X PFLAG(SOMASK,"omask ") X#endif X#ifdef SWEXIT X PFLAG(SWEXIT,"wexit ") X#endif X#ifdef SWTED X PFLAG(SWTED,"wted ") X#endif X#ifdef SULOCK X PFLAG(SULOCK,"ulock ") X#endif X#ifdef STRC X PFLAG(STRC,"traced ") X#endif X#ifdef SPAGI X PFLAG(SPAGI,"ipage ") X#endif X#ifdef SSEL X PFLAG(SSEL,"sel! ") X#endif X#ifdef SPTECHG X PFLAG(SPTECHG,"ptechg ") X#endif X#ifdef SEXECDN X PFLAG(SEXECDN,"execdn ") X#endif X#ifdef SVFORK X PFLAG(SVFORK,"vfork ") X#endif X#ifdef SVFDONE X PFLAG(SVFDONE,"vfdone ") X#endif X#ifdef SNOVM X PFLAG(SNOVM,"novm ") X#endif X if (pflag) X { X sprintf(t,"flag %x ",pflag); X } X return result; X} END_OF_FILE if test 1996 -ne `wc -c <'printpstat.c'`; then echo shar: \"'printpstat.c'\" unpacked with wrong size! fi # end of 'printpstat.c' fi if test -f 'printucred.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'printucred.c'\" else echo shar: Extracting \"'printucred.c'\" \(3161 characters\) sed "s/^X//" >'printucred.c' <<'END_OF_FILE' X/* History: X5/3/91 DJB modified to print something sensible under !HAVE_UCRED X5/1/91 DJB baseline public domain X*/ X X/* X Xchar *printucred(uc,style,ruids,tags,uns) struct ucred *uc; int style; Xint ruids; int tags; int uns; prints uc in a variety of styles. X Xstyle is not yet officially defined. XXX this whole interface X XIf ruids is 0, the effective uid is printed, and the real uid is printed Xif different. If ruids is 1, only the effective uid is printed. If ruids Xis 2, only the real uid is printed. X XIf tags is 1, information is tagged with inline labels. If tags is 0, it Xis assumed that labels are placed at the top of columns. X XIf uns is 1, uids are printed as usernames if possible. If uns is 0, Xuids are always printed as uids. X X*/ X X#include X#include X#include "structucred.h" X#include "printucred.h" X#include "username.h" X#include "groupname.h" X#include "confhaveucred.h" X/* XXX: should provide for string group names! */ X Xstatic char result[50 + NGROUPS * 8]; X/* XXX: assumes uids and gids are at most 8 (really 5) characters */ X/* XXX: assumes uids and gids are short */ X/* XXX: string representation? */ X/* XXX: under newer Suns, auid? audit? label? */ X Xchar *printucred(uc,style,ruids,tags,uns) Xstruct ucred *uc; Xint style; Xint ruids; Xint tags; Xint uns; X{ X int i; X char *t; X unsigned gid; X unsigned rgid; X unsigned uid; X unsigned ruid; X unsigned puid; X X#ifdef HAVE_UCRED X uid = uc->cr_uid; X ruid = uc->cr_ruid; X#else X uid = uc->uid; X ruid = uc->uid; X#endif X puid = (ruids == 2) ? ruid : uid; X if (uns) X { X char *pun; X uid2username(puid,&pun); /* XXX: care about return value? */ X if (style == 1) X sprintf(result,"%s%8s",tags ? "uid " : "",pun); X else X sprintf(result,"%s%s",tags ? "uid " : "",pun); X } X else X if (style == 1) X sprintf(result,"%s%5u",tags ? "uid " : "",puid); X else X sprintf(result,"%s%u",tags ? "uid " : "",puid); X t = result + strlen(result); X if (!ruids && (uid != ruid)) X { X if (uns) X { X char *pun; X uid2username(ruid,&pun); /* XXX: care about return value? */ X if (style == 1) X sprintf(t,"/%8u",ruid); X else X sprintf(t,"/%u",ruid); X } X else X if (style == 1) X sprintf(t,"/%5u",ruid); X else X sprintf(t,"/%u",ruid); X t += strlen(t); X } X if (style == 1 && !ruids && (uid == ruid)) X { X if (uns) { sprintf(t," "); t += 9; } X else { sprintf(t," "); t += 6; } X } X if (style == 2) X { X sprintf(t," "); X t = result + (tags ? 4 : 0) + (!ruids ? 6 : 0) + 5 + (uns ? 6 : 0); X *t = 0; X } X#ifdef HAVE_UCRED /*XXX*/ X if (style == 3) X { X gid = (unsigned short) uc->cr_gid; X rgid = (unsigned short) uc->cr_rgid; X sprintf(t," %s%u",tags ? "gid " : "",gid); t += strlen(t); X if (gid != rgid) X { X sprintf(t,"/%u",rgid); t += strlen(t); X } X for (i = 0;i < NGROUPS;++i) X { X register short g; X g = uc->cr_groups[i]; X if (g == -1) X break; /* XXX: is this right? */ X if (g != gid && g != rgid) X sprintf(t," %u",(unsigned) (unsigned short) g); X t += strlen(t); X if (!g) X break; /* XXX: is this right? */ X } X } X#endif X return result; X} END_OF_FILE if test 3161 -ne `wc -c <'printucred.c'`; then echo shar: \"'printucred.c'\" unpacked with wrong size! fi # end of 'printucred.c' fi if test -f 'proctable.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'proctable.c'\" else echo shar: Extracting \"'proctable.c'\" \(2453 characters\) sed "s/^X//" >'proctable.c' <<'END_OF_FILE' X/* History: X5/1/91 DJB baseline public domain X*/ X X#include "mallocfree.h" X#include "proctable.h" X#include "structproc.h" X#include "kmem.h" X#include "nlistlist.h" X#include "strerr.h" X X#define PROCNLIST "_proc" X#define NPROCNLIST "_nproc" X Xstatic int pinit = 0; Xstatic struct proc *proctable = 0; Xstatic short ptype; Xstatic short nptype; Xstatic unsigned long pvalue; Xstatic unsigned long npvalue; Xstruct proc *myproc; Xint mynproc; Xstatic int proctableerrno = 0; X Xchar *proctablestrerr(ke) Xstrerrfun *ke; X{ X *ke = 0; X switch(proctableerrno) X { X case 0: X return "proctable error 0"; X#define PT_INIT 1 X case PT_INIT: X *ke = nliststrerr; X return "cannot init proctable: "; X#define PT_NLIST 2 X case PT_NLIST: X *ke = nliststrerr; X return "cannot nlist: "; X#define PT_NLPFOUND 3 X case PT_NLPFOUND: X *ke = nlistnotin; X return PROCNLIST; X#define PT_NLNPFOUND 4 X case PT_NLNPFOUND: X *ke = nlistnotin; X return NPROCNLIST; X#define PT_NLPREAD 5 X case PT_NLPREAD: X *ke = kmemstrerr; X return "cannot read proc table pointer: "; X#define PT_NLNPREAD 6 X case PT_NLNPREAD: X *ke = kmemstrerr; X return "cannot read nproc: "; X#define PT_FTREAD 7 X case PT_FTREAD: X *ke = kmemstrerr; X return "cannot read proc table: "; X#define PT_ALLOC 8 X case PT_ALLOC: X *ke = 0; X return "out of memory"; X default: X return "unknown proctable error"; X } X} X Xint proctableinit() X{ X if (nlistadd(PROCNLIST,&ptype,&pvalue) == -1) X RETERN(-1,proctableerrno,PT_INIT) X if (nlistadd(NPROCNLIST,&nptype,&npvalue) == -1) X RETERN(-1,proctableerrno,PT_INIT) X pinit = 1; X return 0; X} X Xstruct proc *getproctable() X{ X if (!pinit) X if (proctableinit() == -1) X return 0; X if (ptype == -1) X if (nlistdo() == -1) X RETERN(0,proctableerrno,PT_NLIST) X if (!ptype) X RETERN(0,proctableerrno,PT_NLPFOUND) X if (!nptype) X RETERN(0,proctableerrno,PT_NLNPFOUND) X if (kmemcpy((char *) &mynproc,(char *) npvalue,sizeof(mynproc)) == -1) X RETERN(0,proctableerrno,PT_NLPREAD) X if (kmemcpy((char *) &myproc,(char *) pvalue,sizeof(myproc)) == -1) X RETERN(0,proctableerrno,PT_NLNPREAD) X X if (proctable) X free((char *) proctable); X proctable = (struct proc *) malloc((unsigned) (sizeof(struct proc) * mynproc)); X if (!proctable) X RETERN(0,proctableerrno,PT_ALLOC) X X if (kmemcpy((char *) proctable,(char *) myproc,sizeof(struct proc) * mynproc) == -1) X RETERN(0,proctableerrno,PT_FTREAD) X X return proctable; X} END_OF_FILE if test 2453 -ne `wc -c <'proctable.c'`; then echo shar: \"'proctable.c'\" unpacked with wrong size! fi # end of 'proctable.c' fi if test -f 'strerr.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'strerr.c'\" else echo shar: Extracting \"'strerr.c'\" \(2183 characters\) sed "s/^X//" >'strerr.c' <<'END_OF_FILE' X/* History: X5/1/91 DJB baseline public domain X*/ X X#include X#include Xextern int errno; Xextern int sys_nerr; Xextern char *sys_errlist[]; X#include X#include "mallocfree.h" X#include "strerr.h" X Xchar *strerrtaberr(ke,err,tab,n,dfl) Xstrerrfun *ke; Xint err; /* error number */ Xstruct strerrtab *tab; /* error table */ Xint n; /* size of tab */ Xchar *dfl; /* what to say if err isn't in tab */ X{ X int i; X if ((err < 0) || (err >= n)) X { X *ke = 0; X return dfl; X } X if (tab[err].err != err) X { X for (i = 0;i < n;++i) X if (tab[i].err == err) X break; X if (i == n) X { X *ke = 0; X return dfl; X } X } X else X i = err; /* fastest this way */ X /* So now tab[i].err == err. */ X *ke = tab[i].next; X return tab[i].s; X} X Xchar *strerrstr(ke,s) Xstrerrfun *ke; Xchar *s; X{ X *ke = 0; X return s; X} X Xchar *strerrsys(ke) Xstrerrfun *ke; X{ X *ke = strerrno; X return ": "; X} X Xstatic char unk[30]; X Xchar *strerrno(ke) Xstrerrfun *ke; X{ X *ke = 0; X if ((errno < 0) || (errno > sys_nerr)) X { X (void) sprintf(unk,"unknown error %d",errno); X return unk; X } X return sys_errlist[errno]; X} X Xstruct sel { struct sel *next; char *s; unsigned len; } ; X Xchar *strerr(ke) Xstrerrfun ke; X{ X char *s; X char *t; X struct sel head; X struct sel *sel; X struct sel *temp; X int saveerrno; /*XXX: what if malloc messes up other errors? */ X unsigned len; X X head.next = 0; X sel = &head; X X /* Note that *sel is always allocated. We do this so that we can */ X /* better handle malloc errors. */ X X while (ke) X { X s = ke(&ke); X saveerrno = errno; X temp = (struct sel *) malloc(sizeof(struct sel)); X if (!temp) X { X sel->s = "aack! malloc error"; X sel->len = strlen(sel->s); X break; X } X errno = saveerrno; X sel->next = temp; X temp->next = 0; X sel->s = s; X sel->len = strlen(s); X sel = temp; X } X X len = 1; X for (sel = &head;temp = sel->next;sel = temp) X len += sel->len; X X s = malloc(len); X if (!s) X return "aack! malloc error"; /*XXX*/ X X t = s; X for (sel = &head;temp = sel->next;sel = temp) X { X (void) strcpy(t,sel->s); X t += sel->len; X if (sel != &head) /*XXX*/ X free((char *) sel); X } X free((char *) sel); X X return s; X} END_OF_FILE if test 2183 -ne `wc -c <'strerr.c'`; then echo shar: \"'strerr.c'\" unpacked with wrong size! fi # end of 'strerr.c' fi if test -f 'testauthd.c' -a "${1}" != "-c" ; then echo shar: Will not clobber existing file \"'testauthd.c'\" else echo shar: Extracting \"'testauthd.c'\" \(2704 characters\) sed "s/^X//" >'testauthd.c' <<'END_OF_FILE' X#include X#include X#include X#ifdef sun X#include X#endif X#include X#include X#include X#include X#include Xextern int errno; X#include "authuser.h" X Xmain() X{ X int s; X int t; X int u; X struct sockaddr_in sa; X int salen; X int localport; X unsigned long in; X unsigned short local; X unsigned short remote; X char *user; X struct passwd *pw; X int ok; X X ok = 1; X X#define ZOT(x) { fprintf(stderr,"test: fatal: %s\n",x); exit(37); } X X printf("connecting to myself through loopback (127.1)...\n"); X X s = socket(AF_INET,SOCK_STREAM,0); X if (s == -1) X ZOT("cannot create server socket") X X localport = 0; /* meaning pick a port, we don't care which */ X X sa.sin_family = AF_INET; X sa.sin_port = htons(localport); X sa.sin_addr.s_addr = INADDR_ANY; X X if (bind(s,&sa,sizeof(sa)) == -1) X ZOT("cannot bind server socket") X X salen = sizeof(sa); X if (getsockname(s,&sa,&salen) == -1) X ZOT("cannot get name of server socket") X X if (listen(s,5) == -1) X ZOT("cannot listen for connections") /* XXX: impossible */ X X u = socket(AF_INET,SOCK_STREAM,0); X if (u == -1) X ZOT("cannot create client socket") X X /* we could bind now if we wanted to pick a local port, or to know */ X /* our local port before connection */ X X /* if connect() blocked then we'd never get a chance to accept() */ X if (fcntl(u,F_SETFL,O_NDELAY) == -1) /* XXX: FNDELAY? */ X ZOT("cannot set client socket to non-blocking mode") X X /* sa is already initialized above to the address we want to connect to */ X if (connect(u,&sa,sizeof(sa)) != -1) X ; /* XXX: this is slightly screwy, though common, behavior */ X else X if (errno != EINPROGRESS) X ZOT("connect failed") /* XXX: should retry if EINTR */ X X salen = sizeof(sa); X if ((t = accept(s,&sa,&salen)) == -1) X ZOT("cannot accept connection") X X printf("system says host is %s\n",inet_ntoa(sa.sin_addr)); X X /* now let's see what the server can figure out about the client */ X X if (auth_fd(t,&in,&local,&remote) == -1) X ZOT("authuser cannot figure out connection information") X X if (sa.sin_addr.s_addr != in) X { X ok = 0; X sa.sin_addr.s_addr = in; X } X printf("authuser says host is %s\n",inet_ntoa(sa.sin_addr)); X X pw = getpwuid(getuid()); X if (pw) X printf("system says username is %s\n",pw->pw_name); X else X { X ok = 0; X printf("system cannot figure out your username\n"); X } X X user = auth_tcpuser(in,local,remote); X if (user) X printf("authd says username is %s\n",user); X else X { X ok = 0; X printf("authd cannot figure out your username\n"); X } X X if (ok) X if (!strcmp(user,pw->pw_name)) X printf("Everything looks okay to me.\n"); X else X ok = 1; X X exit(!ok); X} END_OF_FILE if test 2704 -ne `wc -c <'testauthd.c'`; then echo shar: \"'testauthd.c'\" unpacked with wrong size! fi # end of 'testauthd.c' fi echo shar: End of archive 3 \(of 6\). cp /dev/null ark3isdone MISSING="" for I in 1 2 3 4 5 6 ; do if test ! -f ark${I}isdone ; then MISSING="${MISSING} ${I}" fi done if test "${MISSING}" = "" ; then echo You have unpacked all 6 archives. rm -f ark[1-9]isdone else echo You still need to unpack the following archives: echo " " ${MISSING} fi ## End of shell archive. exit 0