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