[comp.sources.bugs] Problem in Dan Heller's "dots" game

billw@oberon.lcs.mit.edu (Bill Wisner) (12/30/87)

Due to a problem with the format of /etc/utmp, dots can't handle 2-player
games against someone with an eight-letter username. The following replacement
for findem.c alleviates the problem.
-- (cut here)
/* findem.c   find the login of the person we wanna play */

#include "dots.h"
#include <sys/stat.h>
#include <sgtty.h>
#include <utmp.h>

#define UTMP  		"/etc/utmp"

struct utmp utmp_buf;
struct stat stat_buf;
struct sgttyb sgtty_buf;

int fd;

findem(argc, argv)
char **argv;
{
    char *ttyname(), to_tty[13], *tmp_name;
    register char *login = argv[2], *where = "", *ourtty = ttyname(0) + 5;
    register FILE *recipient;

    if (argc > 3)
	where = argv[3];
    if (!strcmp(where, ourtty)) {
	fprintf(stderr, "You can't play yourself.\n");
	return 0;
    }
    if ((fd = open(UTMP, 0)) == -1) {
	perror(UTMP);
	return 0;
    }

    while (read(fd, (char *) &utmp_buf, sizeof(utmp_buf)))
	if (!strncmp(utmp_buf.ut_name, login, 8) &&
	   (*where && !strcmp(utmp_buf.ut_line, where) ||
	   (!*where && strcmp(where, ourtty))))
		break;

    (void) close(fd);
    if (strncmp(login, utmp_buf.ut_name, 8)) {
	fprintf(stderr, "%s is not logged in.", login);
	return 0;
    }
    if (*where && strcmp(where, utmp_buf.ut_line)) {
	fprintf(stderr, "%s is not logged in on %s.\n", login, where);
	return 0;
    }

    (void) sprintf(to_tty, "/dev/%s", utmp_buf.ut_line);
    if (!(recipient = fopen(to_tty, "w"))) {
	perror(to_tty);
	fprintf(stderr, "%s: Can't ask %s to play.\n", argv[0], argv[2]);
	return 0;
    }
    setuid(getuid());	/* turns off set-uid attribute once tty is opened */
    setgid(getgid());	/* probably isn't necessary most of the time */

    return invite(recipient);
}

chris@mimsy.UUCP (Chris Torek) (12/31/87)

In article <7765@eddie.MIT.EDU>, billw@oberon.lcs.mit.edu (Bill Wisner) writes:
>Due to a problem with the format of /etc/utmp, dots can't handle 2-player
>games against someone with an eight-letter username. The following replacement
>for findem.c alleviates the problem.

As it says in <utmp.h>, `Assuming the number 8 is unwise.'  There are
several other potential bugs in this routine (I spotted three offhand).
I would change it to something more like this:

/* findem.c   find the login of the person we wanna play */

#include "dots.h"
#include <sys/stat.h>
#include <sgtty.h>
#include <utmp.h>

#define UTMP  		"/etc/utmp"

struct utmp utmp_buf;
struct stat stat_buf;
struct sgttyb sgtty_buf;

int fd;

#define	NMAX	sizeof(utmp_buf.ut_name)
#define	LMAX	sizeof(utmp_buf.ut_line)
#define	DEVPART	"/dev/"
#define	DEVLEN	5		/* strlen(DEVPART) */

char	*ttyname();

findem(argc, argv)
	int argc;
	char **argv;
{
	register char *login = argv[2], *where = 0, *ourtty = ttyname(0);
	register FILE *recipient;
	int found;
	char *to_tty[DEVLEN + LMAX + 1];

	if (ourtty == 0) {
		fprintf(stderr, "%s: can't find your tty\n");
		return 0;
	}
	ourtty += DEVLEN;
	if (argc > 3) {
		where = argv[3];
		if (strcmp(where, ourtty) == 0) {
			fprintf(stderr, "You can't play yourself.\n");
			return 0;
		}
	}
	if ((fd = open(UTMP, 0)) == -1) {
		perror(UTMP);
		return 0;
	}
	found = 0;
	while (read(fd, (char *)&utmp_buf, sizeof(utmp_buf)) > 0) {
		if (strncmp(utmp_buf.ut_name, login, NMAX) != 0)
			continue;
		found = -1;
		if (where == 0 ||
		    strncmp(utmp_buf.ut_line, where, LMAX) == 0)) {
			found = 1;
			break;
		}
	}
	(void) close(fd);
	if (found < 1) {
		fprintf(stderr, "%s is not logged in%s%s.\n", login,
			found ? " on " : "", found ? where : "");
		return 0;
	}
	/* N.B.: %.*s may be dubious under dpANS */
	(void) sprintf(to_tty, "%s%.*s", DEVPART, LMAX, utmp_buf.ut_line);
	if ((recipient = fopen(to_tty, "w")) == 0) {
		perror(to_tty);
		fprintf(stderr, "%s: Can't ask %s to play.\n", argv[0],
			argv[2]);
		return 0;
	}
	setgid(getgid());/* probably isn't necessary most of the time */
	setuid(getuid());/* turns off set-uid attribute once tty is opened */

	return invite(recipient);
}
-- 
In-Real-Life: Chris Torek, Univ of MD Comp Sci Dept (+1 301 454 7690)
Domain:	chris@mimsy.umd.edu	Path:	uunet!mimsy!chris