lastcomm uid->name mapping bug +FIX
Steven M. Schultz
sms at wlv.imsd.contel.com
Sat Jun 16 08:41:19 AEST 1990
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>
More information about the Comp.bugs.2bsd
mailing list