From 4a315a9af3155acaacc8749c5fe8d3d589401733 Mon Sep 17 00:00:00 2001 From: Ruslan Ermilov Date: Wed, 5 Sep 2001 15:37:01 +0000 Subject: [PATCH] SECURITY. Notify operators using wall(1)'s -g option. Drop ``setgid tty'' privilege. Obtained from: OpenBSD MFC after: 1 month --- sbin/dump/Makefile | 2 - sbin/dump/dump.h | 2 - sbin/dump/main.c | 1 - sbin/dump/optr.c | 126 +++++------------------------------------- sbin/dump/pathnames.h | 1 + 5 files changed, 15 insertions(+), 117 deletions(-) diff --git a/sbin/dump/Makefile b/sbin/dump/Makefile index 95e2b9a7ea73..2df9111f8967 100644 --- a/sbin/dump/Makefile +++ b/sbin/dump/Makefile @@ -18,8 +18,6 @@ LINKS= ${BINDIR}/dump ${BINDIR}/rdump CFLAGS+=-DRDUMP CFLAGS+=-I${.CURDIR}/../../libexec/rlogind SRCS= itime.c main.c optr.c dumprmt.c tape.c traverse.c unctime.c -BINGRP= tty -BINMODE=2555 MAN= dump.8 MLINKS+=dump.8 rdump.8 diff --git a/sbin/dump/dump.h b/sbin/dump/dump.h index c1b1302ebf0a..cbca3f231d20 100644 --- a/sbin/dump/dump.h +++ b/sbin/dump/dump.h @@ -100,7 +100,6 @@ void msg __P((const char *fmt, ...)) __printflike(1, 2); void msgtail __P((const char *fmt, ...)) __printflike(1, 2); int query __P((char *question)); void quit __P((const char *fmt, ...)) __printflike(1, 2); -void set_operators __P((void)); void timeest __P((void)); time_t unctime __P((char *str)); @@ -151,7 +150,6 @@ void interrupt __P((int signo)); /* in case operator bangs on console */ #define X_ABORT 3 /* abort dump; don't attempt checkpointing */ #define OPGRENT "operator" /* group entry to notify */ -#define DIALUP "ttyd" /* prefix for dialups */ struct fstab *fstabsearch __P((char *key)); /* search fs_file and fs_spec */ diff --git a/sbin/dump/main.c b/sbin/dump/main.c index cc19b42c3fbb..be639b7b881b 100644 --- a/sbin/dump/main.c +++ b/sbin/dump/main.c @@ -287,7 +287,6 @@ main(argc, argv) if (signal(SIGINT, interrupt) == SIG_IGN) signal(SIGINT, SIG_IGN); - set_operators(); /* /etc/group snarfed */ getfstab(); /* /etc/fstab snarfed */ /* * disk can be either the full special file name, diff --git a/sbin/dump/optr.c b/sbin/dump/optr.c index 47c5792cccff..0fdc74571dc3 100644 --- a/sbin/dump/optr.c +++ b/sbin/dump/optr.c @@ -59,7 +59,6 @@ static const char rcsid[] = void alarmcatch __P((/* int, int */)); int datesort __P((const void *, const void *)); -static void sendmes __P((char *, char *)); /* * Query the operator; This previously-fascist piece of code @@ -117,7 +116,7 @@ query(question) return(back); } -char lastmsg[100]; +char lastmsg[BUFSIZ]; /* * Alert the console operator, and enable the alarm clock to @@ -159,130 +158,33 @@ interrupt(signo) } /* - * The following variables and routines manage alerting - * operators to the status of dump. - * This works much like wall(1) does. - */ -struct group *gp; - -/* - * Get the names from the group entry "operator" to notify. - */ -void -set_operators() -{ - if (!notify) /*not going to notify*/ - return; - gp = getgrnam(OPGRENT); - (void) endgrent(); - if (gp == NULL) { - msg("No group entry for %s.\n", OPGRENT); - notify = 0; - return; - } -} - -struct tm *localclock; - -/* - * We fork a child to do the actual broadcasting, so - * that the process control groups are not messed up + * We now use wall(1) to do the actual broadcasting. */ void broadcast(message) char *message; { - time_t clock; - FILE *f_utmp; - struct utmp utmp; - char **np; - int pid, s; + FILE *fp; + char buf[sizeof(_PATH_WALL) + sizeof(OPGRENT) + 3]; - if (!notify || gp == NULL) + if (!notify) return; - switch (pid = fork()) { - case -1: + snprintf(buf, sizeof(buf), "%s -g %s", _PATH_WALL, OPGRENT); + if ((fp = popen(buf, "w")) == NULL) return; - case 0: - break; - default: - while (wait(&s) != pid) - continue; - return; - } - clock = time((time_t *)0); - localclock = localtime(&clock); + (void) fputs("\a\a\aMessage from the dump program to all operators\n\nDUMP: NEEDS ATTENTION: ", fp); + if (lastmsg[0]) + (void) fputs(lastmsg, fp); + if (message[0]) + (void) fputs(message, fp); - if ((f_utmp = fopen(_PATH_UTMP, "r")) == NULL) { - msg("Cannot open %s: %s\n", _PATH_UTMP, strerror(errno)); - return; - } - - while (!feof(f_utmp)) { - if (fread((char *) &utmp, sizeof (struct utmp), 1, f_utmp) != 1) - break; - if (utmp.ut_name[0] == 0) - continue; - for (np = gp->gr_mem; *np; np++) { - if (strncmp(*np, utmp.ut_name, sizeof(utmp.ut_name)) != 0) - continue; - /* - * Do not send messages to operators on dialups - */ - if (strncmp(utmp.ut_line, DIALUP, strlen(DIALUP)) == 0) - continue; -#ifdef DEBUG - msg("Message to %s at %s\n", *np, utmp.ut_line); -#endif - sendmes(utmp.ut_line, message); - } - } - (void) fclose(f_utmp); - Exit(0); /* the wait in this same routine will catch this */ - /* NOTREACHED */ -} - -static void -sendmes(tty, message) - char *tty, *message; -{ - char t[MAXPATHLEN], buf[BUFSIZ]; - register char *cp; - int lmsg = 1; - FILE *f_tty; - - (void) strcpy(t, _PATH_DEV); - (void) strncat(t, tty, sizeof t - strlen(_PATH_DEV) - 1); - - if ((f_tty = fopen(t, "w")) != NULL) { - setbuf(f_tty, buf); - (void) fprintf(f_tty, - "\n\ -\a\a\aMessage from the dump program to all operators at %d:%02d ...\r\n\n\ -DUMP: NEEDS ATTENTION: ", - localclock->tm_hour, localclock->tm_min); - for (cp = lastmsg; ; cp++) { - if (*cp == '\0') { - if (lmsg) { - cp = message; - if (*cp == '\0') - break; - lmsg = 0; - } else - break; - } - if (*cp == '\n') - (void) putc('\r', f_tty); - (void) putc(*cp, f_tty); - } - (void) fclose(f_tty); - } + (void) pclose(fp); } /* - * print out an estimate of the amount of time left to do the dump + * Print out an estimate of the amount of time left to do the dump */ time_t tschedule = 0; diff --git a/sbin/dump/pathnames.h b/sbin/dump/pathnames.h index 10defb2a213c..1e466f40aee6 100644 --- a/sbin/dump/pathnames.h +++ b/sbin/dump/pathnames.h @@ -41,3 +41,4 @@ #define _PATH_DUMPDATES "/etc/dumpdates" #define _PATH_LOCK "/tmp/dumplockXXXXXX" #define _PATH_RMT "/etc/rmt" /* path on remote host */ +#define _PATH_WALL "/usr/bin/wall"