sms@wlv.imsd.contel.com (Steven M. Schultz) (06/16/90)
Subject: lastcomm uid->name mapping bug +FIX Index: ucb/lastcomm.c 2.10BSD Description: 'lastcomm' does not handle uid values which are greater than 32767 or greater than NUID correctly. Also a LARGE quantity of memory is wasted by statically "char [NUID][sizeof (utmp.ut_name)]" where NUID is currently 2048. Repeat-By: run 'lastcomm'. if you see "(null)" in place of a user name for commands run with uid that is greater than 32767 or NUID, the bug is present. Fix: Rather than fix the grotesque method "lastcomm" was using, the uid->name mapping function getname() was taken from "ls" and installed. Apply the following patch to lastcomm.c and recompile. If you have not installed the shadow password file, the call to setpassent(1) will have to be changed to setpwent(). *** lastcomm.c.old Thu Mar 12 01:25:27 1987 --- lastcomm.c Fri Jun 15 15:10:27 1990 *************** *** 137,196 **** /* should be done with nameserver or database */ struct utmp utmp; - - #define NUID 2048 #define NMAX (sizeof (utmp.ut_name)) ! char names[NUID][NMAX+1]; ! char outrangename[NMAX+1]; ! int outrangeuid = -1; char * getname(uid) { register struct passwd *pw; ! static init; ! struct passwd *getpwent(); ! if (uid >= 0 && uid < NUID && names[uid][0]) ! return (&names[uid][0]); ! if (uid >= 0 && uid == outrangeuid) ! return (outrangename); ! if (init == 2) { ! if (uid < NUID) ! return (0); ! setpwent(); ! while (pw = getpwent()) { ! if (pw->pw_uid != uid) ! continue; ! outrangeuid = pw->pw_uid; ! strncpy(outrangename, pw->pw_name, NMAX); ! endpwent(); ! return (outrangename); ! } ! endpwent(); ! return (0); ! } ! if (init == 0) ! setpwent(), init = 1; ! while (pw = getpwent()) { ! if (pw->pw_uid < 0 || pw->pw_uid >= NUID) { ! if (pw->pw_uid == uid) { ! outrangeuid = pw->pw_uid; ! strncpy(outrangename, pw->pw_name, NMAX); ! return (outrangename); ! } ! continue; ! } ! if (names[pw->pw_uid][0]) ! continue; ! strncpy(names[pw->pw_uid], pw->pw_name, NMAX); ! if (pw->pw_uid == uid) ! return (&names[uid][0]); ! } ! init = 2; ! endpwent(); ! return (0); } #include <sys/dir.h> --- 137,168 ---- /* should be done with nameserver or database */ struct utmp utmp; #define NMAX (sizeof (utmp.ut_name)) + #define SCPYN(a, b) strncpy(a, b, NMAX) ! #define NCACHE 64 /* power of 2 */ ! #define CAMASK NCACHE - 1 char * getname(uid) + uid_t uid; { + static struct ncache { + uid_t uid; + char name[NMAX+1]; + } c_uid[NCACHE]; register struct passwd *pw; ! register struct ncache *cp; ! setpassent(1); ! cp = c_uid + (uid & CAMASK); ! if (cp->uid == uid && *cp->name) ! return(cp->name); ! if (!(pw = getpwuid(uid))) ! return((char *)0); ! cp->uid = uid; ! SCPYN(cp->name, pw->pw_name); ! return(cp->name); } #include <sys/dir.h>