[net.bugs.4bsd] minor flaw in 4.2 login/ac/wtmp

jpl@allegra.UUCP (John P. Linderman) (04/23/84)

Both /etc/ac and /usr/ucb/last assume that /usr/adm/wtmp is an array
of utmp structures.  So does /bin/login, but if the assumption becomes
invalid, /bin/login preserves rather than corrects the error.

Repeat by:
   cd /usr/adm
   mv wtmp oldwtmp
   echo "Garbage" > wtmp
   # You can also invalidate the assumption by running the /usr file system
   # out of space, although some users might take a dim view of this.
   # Both `last' and `ac' now report garbage, and will continue reporting
   # garbage until wtmp is reinitialized.

Fix:
   If /bin/login insists on writing at offsets that are multiples of
   sizeof(struct utmp), improper initialization of /usr/adm/wtmp or
   write errors on that file will not spoil all future login accounting.
   There follows a diff of a simple and not outrageously inefficient fix
   to /usr/src/bin/login.c that will correct "alignment" errors.

*** login.c
--- nlogin.c
***************
*** 93,96
  	char *ttyn;
  	int ldisc = 0, zero = 0;
  
  	signal(SIGALRM, timedout);

--- 93,97 -----
  	char *ttyn;
  	int ldisc = 0, zero = 0;
+ 	struct stat wtstat;
  
  	signal(SIGALRM, timedout);
***************
*** 251,255
  	}
  	if (t > 0 && (f = open("/usr/adm/wtmp", 1)) >= 0) {
! 		lseek(f, 0L, 2);
  		write(f, (char *)&utmp, sizeof(utmp));
  		close(f);

--- 252,257 -----
  	}
  	if (t > 0 && (f = open("/usr/adm/wtmp", 1)) >= 0) {
! 		fstat(f, &wtstat);
! 		lseek(f, wtstat.st_size - (wtstat.st_size % sizeof(utmp)), 0);
  		write(f, (char *)&utmp, sizeof(utmp));
  		close(f);

John P. Linderman  Department of Brokeley 4.2 Studies  allegra!jpl