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