[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

new libc5 (5.4.33-4) for unstable - READ THIS BEFORE INSTALLING IT



Hi All!

Finally I think the library including the utmp wrappers is fit for
distribution in unstable. There are several points I have to make,
though. There still are programs out there tht will write to utmp
using their own functions, nto the libc5 functions. This was bad in
the first place and will end in corrupting utmp now. 

Of all programs I checked, screen and ssh (when linked with libc5) are
the only ones writing to utmp using an own function. There probably
will be more, so don't be too sure about it. The list below tells
about the programs I checked in the source. 

A lot of programs will stop functioning correctly when this library is
installed (namely those reading utmp using a utmp interface of their
own). Again some of them are listed below.

lastlog and wtmp _will_ be corrupted when libc5 and libc6 programs
write to them, as libc5 does not provide library functions to do so. I
am working on a program testing these files for new data and fixing it
every now and then, but it will be some time until I finish this.
I have done some testing on wtmp, and noticed that it will be _very_
hard to do this correctly. As much less programs use wtmp, it should
not be hard to make all of them use libc6.

Please read this file carefully before installing this library.
Probably there will be problems, but I hope it won't be too bad.

Have fun,
        Helmut

-------------- utmp-wrapper.README ---------------------------

This release of libc 5.4.33 for Debian contains wrapping functions to
the main UTMP writing and reading functions. This means that this C
library will (differing from the standard release made by H.J. Lu)
write UTMP entries in the new format that is used by glibc 2.x .
It will not, however, make the advanced features of this UTMP format
available to programs compiled and linked with libc5. 


WARNING:

There are still programs out there that may thrash the utmp file.

lastlog and wtmp are not at all touched by these wrapper functions.
As there will be (at least for a time) both libc5 and libc6 programs
writing to these files (and there is no clean way to do so in libc5)
these files will be corrupt. I'm working on a deamon fixing these files
on a regular basis.

glibc 2.1.4 will include a utmp_daemon program that will handle all these
problems. It will even be capable of catching programs that do not use the
libc functions to interact with the utmp file. It uses, however, features 
that are not part of 2.0.4, so for now this libc5 wrapper for utmp will
be used on Debian. Note that utmp corruptions may happen through direct
utmp access. THIS IS HIGHLY EXPERIMENTAL SOFTWARE FOR NOW.

I tested it a lot on my system and didn't have any utmp corruption for
two weeks. So I hope it won't bite too many people. The only program I found
writing to utmp that does not work correctly in hamm is screen.

These wrapper functions provide the following functions:
 
  void setutent(void);
  void utmpname(const char *name);
  struct utmp *getutent(void);
  struct utmp *getutid(struct utmp *ut);
  struct utmp *getutline(struct utmp *ut);
  static struct utmp *_pututline(struct utmp *ut);
  void pututline(struct utmp *ut);
  void endutent(void);

The following files have been modified to achieve this (all relative
to the libc source directory):

  login/utmp2.c     this module is no longer used in the C library, 
                    the libc6 routines from utmp_file.c are used instead 
  login/getlogin.c  use new_utmp indstead of utmp.
  inet/ruserpass.c  use new_utmp indstead of utmp, convert to old_utmp.
 
these files have been added:

  login/utmp-wrap.h  these two are new, based on the utmp.h files from
  login/utmp-wrap.c  libc5 and glibc 2. 

  login/utmp_file.c (from glibc 2.0.4) this file has been modified to 
                    use new_utmp as standard type and to export the functions.
                    see below for exact changes to the glibc 2.0.4 version

PROBLEMS and BUGS:

    Note that the functions in libbsd were not replaced. The only critical
    of them is logout which does not use the libc function. If there are
    programs using this, please tell me.

    Furthermore the lastlog structs are incompatible as well. As there are
    no lastlog functions in libc5 (only the struct definition) this 
    cannot be solved using this wrapper. The only way to solve this is 
    to modify all programs using lastlog.
    Something similar hold for all wtmp handling.

As there is no clean way to convert utmp on a running system, I recommend
rebooting to make all prgrams use the utmp-wrapping functions.

The C library run-time package contains a UTMP converter program.
You will find this wrapper program at /usr/sbin/utmp-conv.
A manpage is available from section 8.

-------------- Programs tested ------------------------------
This is a list of programs known to interact with /var run/utmp. I
checked the sources of these programs to detect whether they will work
with the wrapper functions or not. Programs reading utmp may not work
correctly, but will cause no corruption. Luckily nearly all programs 
writing to utmp (that I tested) do The Right Thing[TM].

!! The notable exception is screen, which uses the libc functions only !!
!! when compiled with libc6.                                           !!

Some remarks on wtmp:
All programs writing/reading to wtmp should use the function
logwtmp supplied by libc6 when compiled against it.

Programs using utmp in the wrong way:

 - syslogd: read-only, so not too bad. However, the
      messaging won't work. Fix: use the fixes below  

 - wall (bsdutils):  as above.

 - write (bsdmainutils): as above. the fix is not optimal. Using
     getutline and getutid would be better, but I was too lazy to add
     these changes.

 - shellutils (who, users) use an own way to access the complete utmp
     file at once. This is _NOT_ recommended, even for reading. The
     current version in hamm uses libc6, so there are no problems with
     compatibility, but it should be fixed nevertheless.

 - zsh : watch will not work when linked to libc5. the same as above
     aplies

 - tcsh: watch and who will not work when linked to libc5. Again the
     same as above aplies

 - netstd : all programs I checked use the wrong way. All programs are
        read-only, though.

| - screen does not the Right Thing when compiled with libc5, but it |
|    does so when compiled with libc6.                               |
|   !!!  SCREEN DOES WRITE TO UTMP AND DOES NOT THE RIGHT THING !!!  |

| - ssh does not the Right Thing when compiled with libc5.           |
|   !!!  SSH DOES WRITE TO UTMP AND DOES NOT THE RIGHT THING !!!     |

Programs using utmp in the right way, but need some attention still
or will only work correctly when compiled against libc6 for wtmp
and/or lastlog:

 - sysvinit (uses wtmp as well)
 - shadow    (       -"-       ) the md5 routines are not included in
    the libc6 version (as it provides libcrypt). As the routine that
    is responsible for generating the salt is based on the specific
    md5 implementation used in this package, it won't compile.
    As libc6 supports shadow passwd and md5 passwd, this suite should
    be heaviliy modified to make use of this. 
    A fix to make it compile (and work) with libc6 is to define 
    CRYPTOBJS="md5.o md5crypt.o"
    regardless of finding a libcrypt.
 - login (poeigl) (uses wtmp as well)
 - rxvt (uses wtmp as well)
 - xterm, sessreg (use wtmp as well)
 - pppd (uses wtmp as well)

Programs completely without problems:

 - agetty (poeigl) 

-------------- FIXES -------------------
diff -ur sysklogd-1.3.orig/syslogd.c sysklogd-1.3/syslogd.c
--- sysklogd-1.3.orig/syslogd.c	Mon Jun  9 19:33:19 1997
+++ sysklogd-1.3/syslogd.c	Mon Jun  9 19:39:15 1997
@@ -408,7 +408,6 @@
 static int nlogs = -1;
 static int restart = 0;
 
-#define UNAMESZ		8	/* length of a login name */
 #define MAXUNAMES	20	/* maximum number of user names */
 #define MAXFNAME	200	/* max file pathname length */
 
@@ -453,7 +452,7 @@
 	time_t	f_time;			/* time this was last written */
 	u_char	f_pmask[LOG_NFACILITIES+1];	/* priority mask */
 	union {
-		char	f_uname[MAXUNAMES][UNAMESZ+1];
+		char	f_uname[MAXUNAMES][UT_NAMESIZE+1];
 		struct {
 			char	f_hname[MAXHOSTNAMELEN+1];
 			struct sockaddr_in	f_addr;
@@ -1628,24 +1627,18 @@
 	register struct filed *f;
 	struct iovec *iov;
 {
-	char p[6 + UNAMESZ];
+	char p[6 + UT_LINESIZE];
 	register int i;
 	int ttyf, len;
-	FILE *uf;
 	static int reenter = 0;
-	struct utmp ut;
+	struct utmp *ut;
 	char greetings[200];
 
 	if (reenter++)
 		return;
 
 	/* open the user login file */
-	if ((uf = fopen(UTMP_FILE, "r")) == NULL) {
-		logerror(UTMP_FILE);
-		reenter = 0;
-		return;
-	}
-
+        setutent();
 	/*
 	 * Might as well fork instead of using nonblocking I/O
 	 * and doing notty().
@@ -1664,13 +1657,13 @@
 		len = strlen(greetings);
 
 		/* scan the user login file */
-		while (fread((char *) &ut, sizeof(ut), 1, uf) == 1) {
+		while ((ut=getutent())!=NULL) {
 			/* is this slot used? */
-			if (ut.ut_name[0] == '\0')
+			if (ut->ut_name[0] == '\0')
 				continue;
-			if (ut.ut_type == LOGIN_PROCESS)
+			if (ut->ut_type == LOGIN_PROCESS)
 			        continue;
-			if (!(strcmp (ut.ut_name,"LOGIN"))) /* paranoia */
+			if (!(strcmp (ut->ut_name,"LOGIN"))) /* paranoia */
 			        continue;
 
 			/* should we send the message to this user? */
@@ -1681,7 +1674,7 @@
 						break;
 					}
 					if (strncmp(f->f_un.f_uname[i],
-					    ut.ut_name, UNAMESZ) == 0)
+					    ut->ut_name, UT_NAMESIZE) == 0)
 						break;
 				}
 				if (i >= MAXUNAMES)
@@ -1690,7 +1683,7 @@
 
 			/* compute the device name */
 			strcpy(p, _PATH_DEV);
-			strncat(p, ut.ut_line, UNAMESZ);
+			strncat(p, ut->ut_line, UT_LINESIZE);
 
 			if (f->f_type == F_WALL) {
 				iov[0].iov_base = greetings;
@@ -1716,7 +1709,7 @@
 		exit(0);
 	}
 	/* close the user login file */
-	(void) fclose(uf);
+	endutent();
 	reenter = 0;
 }
 
@@ -2286,9 +2279,9 @@
 		for (i = 0; i < MAXUNAMES && *p; i++) {
 			for (q = p; *q && *q != ','; )
 				q++;
-			(void) strncpy(f->f_un.f_uname[i], p, UNAMESZ);
-			if ((q - p) > UNAMESZ)
-				f->f_un.f_uname[i][UNAMESZ] = '\0';
+			(void) strncpy(f->f_un.f_uname[i], p, UT_NAMESIZE);
+			if ((q - p) > UT_NAMESIZE)
+				f->f_un.f_uname[i][UT_NAMESIZE] = '\0';
 			else
 				f->f_un.f_uname[i][q - p] = '\0';
 			while (*q == ',' || *q == ' ')
diff -ur bsdmainutils-3.3.orig/write.c bsdmainutils-3.3/write.c
--- bsdmainutils-3.3.orig/write.c	Wed Mar 12 00:33:57 1997
+++ bsdmainutils-3.3/write.c	Mon Jun  9 20:35:49 1997
@@ -141,21 +141,18 @@
 utmp_chk(user, tty)
 	char *user, *tty;
 {
-	struct utmp u;
-	int ufd;
+	struct utmp *u;
 
-	if ((ufd = open(_PATH_UTMP, O_RDONLY)) < 0)
-		return(0);	/* ignore error, shouldn't happen anyway */
-
-	while (read(ufd, (char *) &u, sizeof(u)) == sizeof(u))
-		if (u.ut_type == USER_PROCESS &&
-		    strncmp(user, u.ut_name, sizeof(u.ut_name)) == 0 &&
-		    strncmp(tty, u.ut_line, sizeof(u.ut_line)) == 0) {
-			(void)close(ufd);
+	setutent();
+	while ((u=getutent())!=NULL)
+		if (u->ut_type == USER_PROCESS &&
+		    strncmp(user, u->ut_name, sizeof(u->ut_name)) == 0 &&
+		    strncmp(tty, u->ut_line, sizeof(u->ut_line)) == 0) {
+			endutent();
 			return(0);
 		}
 
-	(void)close(ufd);
+	endutent();
 	return(1);
 }
 
@@ -174,24 +171,21 @@
 	char *user, *tty, *mytty;
 	uid_t myuid;
 {
-	struct utmp u;
+	struct utmp *u;
 	time_t bestatime, atime;
 	int ufd, nloggedttys, nttys, msgsok, user_is_me;
 	char atty[UT_LINESIZE + 1];
 
-	if ((ufd = open(_PATH_UTMP, O_RDONLY)) < 0) {
-		perror("utmp");
-		exit(1);
-	}
+	setutent();
 
 	nloggedttys = nttys = 0;
 	bestatime = 0;
 	user_is_me = 0;
-	while (read(ufd, (char *) &u, sizeof(u)) == sizeof(u))
-		if (u.ut_type == USER_PROCESS &&
-		    strncmp(user, u.ut_name, sizeof(u.ut_name)) == 0) {
+	while ((u=getutent())!=NULL)
+		if (u->ut_type == USER_PROCESS &&
+		    strncmp(user, u->ut_name, sizeof(u->ut_name)) == 0) {
 			++nloggedttys;
-			(void)strncpy(atty, u.ut_line, UT_LINESIZE);
+			(void)strncpy(atty, u->ut_line, UT_LINESIZE);
 			atty[UT_LINESIZE] = '\0';
 			if (term_chk(atty, &msgsok, &atime, 0))
 				continue;	/* bad term? skip */
@@ -207,15 +201,15 @@
 			 * it, and the atime will be way in the
 			 * past. So, if the atime is < utmp creation
 			 * time, use the utmp time. */
-			if (atime < u.ut_time)
-			    atime = u.ut_time;
+			if (atime < u->ut_time)
+			    atime = u->ut_time;
 			if (atime > bestatime) {
 				bestatime = atime;
 				(void)strcpy(tty, atty);
 			}
 		}
 
-	(void)close(ufd);
+	endutent();
 	if (nloggedttys == 0) {
 		(void)fprintf(stderr, "write: %s is not logged in\n", user);
 		exit(1);
diff -ur bsdutils-3.2/wall.c bsdutils-3.2.new/wall.c
--- bsdutils-3.2/wall.c	Sun Jun  1 17:44:40 1997
+++ bsdutils-3.2.new/wall.c	Mon Jun  9 19:53:11 1997
@@ -76,10 +76,10 @@
 	extern int optind;
 	int ch;
 	struct iovec iov;
-	struct utmp utmp;
+	struct utmp *utmp;
 	FILE *fp;
 	char *p, *ttymsg();
-	char line[sizeof(utmp.ut_line) + 1];
+	char line[sizeof(utmp->ut_line) + 1];
 
 	while ((ch = getopt(argc, argv, "n")) != EOF)
 		switch (ch) {
@@ -101,26 +101,24 @@
 
 	makemsg(*argv);
 
-	if (!(fp = fopen(_PATH_UTMP, "r"))) {
-		(void)fprintf(stderr, "wall: cannot read %s.\n", _PATH_UTMP);
-		exit(1);
-	}
+	setutent();
 	iov.iov_base = mbuf;
 	iov.iov_len = mbufsize;
 	/* NOSTRICT */
-	while (fread((char *)&utmp, sizeof(utmp), 1, fp) == 1) {
-		if (!utmp.ut_name[0] ||
+	while ((utmp=getutent())!=NULL) {
+		if (!utmp->ut_name[0] ||
v #ifdef DEBIAN
-		    utmp.ut_type != USER_PROCESS ||
-		    !strncmp(utmp.ut_id, ":0", 2) ||
+		    utmp->ut_type != USER_PROCESS ||
+		    !strncmp(utmp->ut_id, ":0", 2) ||
 #endif /* DEBIAN */
-		    !strncmp(utmp.ut_name, IGNOREUSER, sizeof(utmp.ut_name)))
+		    !strncmp(utmp->ut_name, IGNOREUSER, sizeof(utmp->ut_name)))
 			continue;
-		strncpy(line, utmp.ut_line, sizeof(utmp.ut_line));
-		line[sizeof(utmp.ut_line)] = '\0';
+		strncpy(line, utmp->ut_line, sizeof(utmp->ut_line));
+		line[sizeof(utmp->ut_line)] = '\0';
 		if ((p = ttymsg(&iov, 1, line, 60*5)) != NULL)
 			(void)fprintf(stderr, "wall: %s\n", p);
 	}
+	endutent();
 	exit(0);
 }
 
-- 
Helmut Geyer                                Helmut.Geyer@iwr.uni-heidelberg.de
public PGP key available :           finger geyer@saturn.iwr.uni-heidelberg.de

Attachment: pgpTvioryOm0x.pgp
Description: PGP signature


Reply to: