diff --git a/libexec/utmp_update/Makefile b/libexec/utmp_update/Makefile index 2fa90268fd28..e1bb4830782c 100644 --- a/libexec/utmp_update/Makefile +++ b/libexec/utmp_update/Makefile @@ -1,8 +1,10 @@ -# $NetBSD: Makefile,v 1.3 2002/12/16 22:45:15 wiz Exp $ +# $NetBSD: Makefile,v 1.4 2011/09/17 01:50:54 christos Exp $ PROG= utmp_update MAN= utmp_update.8 BINOWN= root BINMODE=4555 +COPTS.utmp_update.c += -Wno-format-nonliteral + .include diff --git a/libexec/utmp_update/utmp_update.c b/libexec/utmp_update/utmp_update.c index b2dba0673ed4..6a01de00953c 100644 --- a/libexec/utmp_update/utmp_update.c +++ b/libexec/utmp_update/utmp_update.c @@ -1,4 +1,4 @@ -/* $NetBSD: utmp_update.c,v 1.9 2009/04/13 03:38:15 christos Exp $ */ +/* $NetBSD: utmp_update.c,v 1.10 2011/09/17 01:50:54 christos Exp $ */ /*- * Copyright (c) 2002 The NetBSD Foundation, Inc. @@ -30,7 +30,7 @@ */ #include -__RCSID("$NetBSD: utmp_update.c,v 1.9 2009/04/13 03:38:15 christos Exp $"); +__RCSID("$NetBSD: utmp_update.c,v 1.10 2011/09/17 01:50:54 christos Exp $"); #include #include @@ -46,8 +46,28 @@ __RCSID("$NetBSD: utmp_update.c,v 1.9 2009/04/13 03:38:15 christos Exp $"); #include #include #include +#include +#include +#include -int main(int, char *[]); +static __dead void +logerr(int e, const char *fmt, ...) +{ + va_list sap, eap; + char *s = NULL; + + if (e) + (void)asprintf(&s, "%s (%s)", fmt, strerror(e)); + if (s) + fmt = s; + + va_start(sap, fmt); + va_copy(eap, sap); + vsyslog(LOG_ERR, fmt, sap); + va_end(sap); + errx(1, fmt, eap); + va_end(eap); +} int main(int argc, char *argv[]) @@ -63,42 +83,45 @@ main(int argc, char *argv[]) euid = geteuid(); ruid = getuid(); - if (seteuid(ruid) == -1) - err(1, "seteuid"); if (argc != 2) { (void)fprintf(stderr, "Usage: %s \n", - getprogname()); - exit(1); + getprogname()); + return 1; } + openlog(getprogname(), LOG_PID | LOG_NDELAY, LOG_AUTH); + if (seteuid(ruid) == -1) + logerr(errno, "Can't setuid %ld", (long)ruid); + len = strlen(argv[1]); if (len > sizeof(*utx) * 4 + 1 || len < sizeof(*utx)) - errx(1, "Bad argument"); + logerr(0, "Bad argument size %zu", len); if ((utx = malloc(len)) == NULL) - err(1, NULL); + logerr(errno, "Can't allocate %zu", len); res = strunvis((char *)utx, argv[1]); if (res != (int)sizeof(*utx)) - errx(1, "Decoding error %s %d != %zu", argv[1], res, sizeof(*utx)); + logerr(0, "Decoding error %s %d != %zu", argv[1], res, + sizeof(*utx)); switch (utx->ut_type) { case USER_PROCESS: case DEAD_PROCESS: break; default: - errx(1, "Invalid utmpx type %d", (int)utx->ut_type); + logerr(0, "Invalid utmpx type %d", (int)utx->ut_type); } if (ruid != 0) { if ((pwd = getpwuid(ruid)) == NULL) - errx(1, "User %lu does not exist in password database", - (long)ruid); + logerr(0, "User %ld does not exist in password" + " database", (long)ruid); if (strcmp(pwd->pw_name, utx->ut_name) != 0) - errx(1, "Current user `%s' does not match " + logerr(0, "Current user `%s' does not match " "`%s' in utmpx entry", pwd->pw_name, utx->ut_name); } @@ -106,34 +129,39 @@ main(int argc, char *argv[]) fd = open(tty, O_RDONLY|O_NONBLOCK, 0); if (fd != -1) { if (fstat(fd, &st) == -1) - err(1, "Cannot stat `%s'", tty); + logerr(errno, "Cannot stat `%s'", tty); if (ruid != 0 && st.st_uid != ruid) - errx(1, "%s: Is not owned by you", tty); + logerr(0, "%s: Is not owned by you", tty); if (!isatty(fd)) - errx(1, "%s: Not a tty device", tty); + logerr(0, "%s: Not a tty device", tty); (void)close(fd); if (access(tty, W_OK|R_OK) == -1) - err(1, "%s", tty); + logerr(errno, "Can't access `%s'", tty); } else { struct utmpx utold, *utoldp; + pid_t ppid; + /* * A daemon like ftpd that does not use a tty line? * We only allow it to kill its own existing entries */ if (utx->ut_type != DEAD_PROCESS) - err(1, "Cannot open `%s'", tty); + logerr(errno, "Cannot open `%s'", tty); (void)memcpy(utold.ut_line, utx->ut_line, sizeof(utx->ut_line)); if ((utoldp = getutxline(&utold)) == NULL) - err(1, "Cannot find existing entry for `%s'", + logerr(0, "Cannot find existing entry for `%s'", utx->ut_line); - if (utoldp->ut_pid != getppid()) - err(1, "Cannot modify entry for `%s'", tty); + if (utoldp->ut_pid != (ppid = getppid())) + logerr(0, "Cannot modify entry for `%s' " + "utmp pid %ld != parent %ld", tty, + (long)utoldp->ut_pid, (long)ppid); } - (void)seteuid(euid); + if (seteuid(euid) == 1) + logerr(errno, "Can't setuid %ld", (long)euid); if (pututxline(utx) == NULL) - err(1, "Cannot update utmp entry"); + logerr(errno, "Cannot update utmp entry"); return 0; }