vBulletin Search Engine Optimization
| |||||||
| Register | FAQ | Members List | Calendar | Search | Today's Posts | Mark Forums Read |
| ||||
| Hi all, since rtadvd listens on the network for some ICMPv6 messages and works with them, running as root is a little bit dangerous. Droping its privileges is easy, since it opens its network and routing socket in the beginning and does not even reloads it config on SIGHUP. The only problem is, that it dumped debug output to a file in /var/run on SIGUSR1, but rtadvd should be changerooted to /var/empty. With this diff, the output will be written to syslog. It is not much (10 lines + 1 line for each prefix) and it is only used for debugging. Diff is attached. Have fun, Rainer Index: usr.sbin/rtadvd/Makefile ================================================== ================= RCS file: /cvs/src/usr.sbin/rtadvd/Makefile,v retrieving revision 1.5 diff -u -p -r1.5 Makefile --- usr.sbin/rtadvd/Makefile 19 Dec 2006 14:50:29 -0000 1.5 +++ usr.sbin/rtadvd/Makefile 5 Apr 2008 21:22:25 -0000 @@ -3,6 +3,7 @@ PROG= rtadvd SRCS= rtadvd.c rrenum.c advcap.c if.c config.c timer.c dump.c +CFLAGS=-Wall LDADD+= -lutil DPADD+= ${LIBUTIL} MAN= rtadvd.8 rtadvd.conf.5 Index: usr.sbin/rtadvd/dump.c ================================================== ================= RCS file: /cvs/src/usr.sbin/rtadvd/dump.c,v retrieving revision 1.6 diff -u -p -r1.6 dump.c --- usr.sbin/rtadvd/dump.c 10 Jun 2002 19:57:35 -0000 1.6 +++ usr.sbin/rtadvd/dump.c 5 Apr 2008 21:22:25 -0000 @@ -47,6 +47,7 @@ #include <time.h> #include <stdio.h> #include <stdarg.h> +#include <stdlib.h> #include <syslog.h> #include <string.h> #include <errno.h> @@ -57,12 +58,9 @@ #include "if.h" #include "dump.h" -static FILE *fp; - extern struct rainfo *ralist; static char *ether_str(struct sockaddr_dl *); -static void if_dump(void); static char *rtpref_str[] = { "medium", /* 00 */ @@ -88,131 +86,128 @@ ether_str(sdl) return(hbuf); } -static void -if_dump() +char* +lifetime(int lt) +{ + char *str; + + if (lt == ND6_INFINITE_LIFETIME) + asprintf(&str, "infinity"); + else + asprintf(&str, "%ld", (long)lt); + return str; +} + +void +rtadvd_dump() { struct rainfo *rai; struct prefix *pfx; char prefixbuf[INET6_ADDRSTRLEN]; int first; struct timeval now; + char *origin, *vltime, *pltime, *flags; + char *vltimexpire=NULL, *pltimexpire=NULL; gettimeofday(&now, NULL); /* XXX: unused in most cases */ for (rai = ralist; rai; rai = rai->next) { - fprintf(fp, "%s:\n", rai->ifname); + syslog(LOG_INFO, "%s:\n", rai->ifname); - fprintf(fp, " Status: %s\n", - (iflist[rai->ifindex]->ifm_flags & IFF_UP) ? "UP" : - "DOWN"); + syslog(LOG_INFO, " Status: %s\n", + (iflist[rai->ifindex]->ifm_flags & IFF_UP) ? "UP" : "DOWN"); /* control information */ if (rai->lastsent.tv_sec) { /* note that ctime() appends CR by itself */ - fprintf(fp, " Last RA sent: %s", - ctime((time_t *)&rai->lastsent.tv_sec)); + syslog(LOG_INFO, " Last RA sent: %s", + ctime((time_t *)&rai->lastsent.tv_sec)); } if (rai->timer) { - fprintf(fp, " Next RA will be sent: %s", - ctime((time_t *)&rai->timer->tm.tv_sec)); + syslog(LOG_INFO, " Next RA will be sent: %s\n", + ctime((time_t *)&rai->timer->tm.tv_sec)); } else - fprintf(fp, " RA timer is stopped"); - fprintf(fp, " waits: %d, initcount: %d\n", + syslog(LOG_INFO, " RA timer is stopped\n"); + syslog(LOG_INFO, " waits: %d, initcount: %d\n", rai->waiting, rai->initcounter); /* statistics */ - fprintf(fp, " statistics: RA(out/in/inconsistent): " - "%llu/%llu/%llu, ", + syslog(LOG_INFO, " statistics: RA(out/in/inconsistent): " + "%llu/%llu/%llu, RS(input): %llu\n", (unsigned long long)rai->raoutput, (unsigned long long)rai->rainput, - (unsigned long long)rai->rainconsistent); - fprintf(fp, "RS(input): %llu\n", + (unsigned long long)rai->rainconsistent, (unsigned long long)rai->rsinput); /* interface information */ if (rai->advlinkopt) - fprintf(fp, " Link-layer address: %s\n", + syslog(LOG_INFO, " Link-layer address: %s\n", ether_str(rai->sdl)); - fprintf(fp, " MTU: %d\n", rai->phymtu); + syslog(LOG_INFO, " MTU: %d\n", rai->phymtu); /* Router configuration variables */ - fprintf(fp, " DefaultLifetime: %d, MaxAdvInterval: %d, " - "MinAdvInterval: %d\n", rai->lifetime, rai->maxinterval, - rai->mininterval); - fprintf(fp, " Flags: %s%s%s, ", + syslog(LOG_INFO, " DefaultLifetime: %d, MaxAdvInterval: %d, " + "MinAdvInterval: %d\n" + "Flags: %s%s, Preference: %s, MTU: %d\n", + rai->lifetime, rai->maxinterval, rai->mininterval, rai->managedflg ? "M" : "", rai->otherflg ? "O" : "", - ""); - fprintf(fp, "Preference: %s, ", - rtpref_str[(rai->rtpref >> 3) & 0xff]); - fprintf(fp, "MTU: %d\n", rai->linkmtu); - fprintf(fp, " ReachableTime: %d, RetransTimer: %d, " - "CurHopLimit: %d\n", rai->reachabletime, - rai->retranstimer, rai->hoplimit); + rtpref_str[(rai->rtpref >> 3) & 0xff], rai->linkmtu); + syslog(LOG_INFO, " ReachableTime: %d, RetransTimer: %d, " + "CurHopLimit: %d\n", rai->reachabletime, + rai->retranstimer, rai->hoplimit); if (rai->clockskew) - fprintf(fp, " Clock skew: %ldsec\n", + syslog(LOG_INFO, " Clock skew: %ldsec\n", rai->clockskew); for (first = 1, pfx = rai->prefix.next; pfx != &rai->prefix; pfx = pfx->next) { if (first) { - fprintf(fp, " Prefixes:\n"); + syslog(LOG_INFO, " Prefixes:\n"); first = 0; } - fprintf(fp, " %s/%d(", - inet_ntop(AF_INET6, &pfx->prefix, prefixbuf, - sizeof(prefixbuf)), pfx->prefixlen); switch (pfx->origin) { case PREFIX_FROM_KERNEL: - fprintf(fp, "KERNEL, "); + origin = "KERNEL"; break; case PREFIX_FROM_CONFIG: - fprintf(fp, "CONFIG, "); + origin = "CONFIG"; break; case PREFIX_FROM_DYNAMIC: - fprintf(fp, "DYNAMIC, "); + origin = "DYNAMIC"; break; } - if (pfx->validlifetime == ND6_INFINITE_LIFETIME) - fprintf(fp, "vltime: infinity"); - else - fprintf(fp, "vltime: %ld", - (long)pfx->validlifetime); + if (pfx->vltimeexpire != 0) - fprintf(fp, "(decr,expire %ld), ", (long) + asprintf(&vltimexpire, "(decr,expire %ld)", (long) pfx->vltimeexpire > now.tv_sec ? pfx->vltimeexpire - now.tv_sec : 0); - else - fprintf(fp, ", "); - if (pfx->preflifetime == ND6_INFINITE_LIFETIME) - fprintf(fp, "pltime: infinity"); - else - fprintf(fp, "pltime: %ld", - (long)pfx->preflifetime); if (pfx->pltimeexpire != 0) - fprintf(fp, "(decr,expire %ld), ", (long) + asprintf(&pltimexpire, "(decr,expire %ld)", (long) pfx->pltimeexpire > now.tv_sec ? pfx->pltimeexpire - now.tv_sec : 0); - else - fprintf(fp, ", "); - fprintf(fp, "flags: %s%s%s", + + vltime = lifetime(pfx->validlifetime); + pltime = lifetime(pfx->preflifetime); + asprintf(&flags, "%s%s", pfx->onlinkflg ? "L" : "", - pfx->autoconfflg ? "A" : "", - ""); - fprintf(fp, ")\n"); + pfx->autoconfflg ? "A" : ""); + syslog(LOG_INFO, " %s/%d(%s, vltime: %s%s, " + "pltime: %s%s, flags: %s)\n", + inet_ntop(AF_INET6, &pfx->prefix, prefixbuf, + sizeof(prefixbuf)), pfx->prefixlen, origin, + vltime, (vltimexpire)? vltimexpire : "", + pltime, (pltimexpire)? pltimexpire : "", flags); + + if (vltimexpire) { + free(vltimexpire); + vltimexpire = NULL; + } + if (pltimexpire) { + free(pltimexpire); + pltimexpire = NULL; + } + free(vltime); + free(pltime); + free(flags); } } -} - -void -rtadvd_dump_file(dumpfile) - char *dumpfile; -{ - if ((fp = fopen(dumpfile, "w")) == NULL) { - syslog(LOG_WARNING, "<%s> open a dump file(%s)", - __func__, dumpfile); - return; - } - - if_dump(); - - fclose(fp); } Index: usr.sbin/rtadvd/dump.h ================================================== ================= RCS file: /cvs/src/usr.sbin/rtadvd/dump.h,v retrieving revision 1.2 diff -u -p -r1.2 dump.h --- usr.sbin/rtadvd/dump.h 16 Feb 2002 21:28:08 -0000 1.2 +++ usr.sbin/rtadvd/dump.h 5 Apr 2008 21:22:25 -0000 @@ -30,4 +30,4 @@ * SUCH DAMAGE. */ -extern void rtadvd_dump_file(char *); +void rtadvd_dump(); Index: usr.sbin/rtadvd/rtadvd.8 ================================================== ================= RCS file: /cvs/src/usr.sbin/rtadvd/rtadvd.8,v retrieving revision 1.23 diff -u -p -r1.23 rtadvd.8 --- usr.sbin/rtadvd/rtadvd.8 31 May 2007 19:20:29 -0000 1.23 +++ usr.sbin/rtadvd/rtadvd.8 5 Apr 2008 21:22:25 -0000 @@ -136,8 +136,7 @@ Only statically configured prefixes, if Upon receipt of signal .Dv SIGUSR1 , .Nm -will dump the current internal state into -.Pa /var/run/rtadvd.dump . +will dump the current internal state into syslog. .Pp Use .Dv SIGTERM @@ -152,16 +151,12 @@ to all the interfaces .Pp .Ex -std rtadvd .Sh FILES -.Bl -tag -width "/var/run/rtadvd.dumpXX" -compact +.Bl -tag -width "/var/run/rtadvd.pidXX" -compact .It Pa /etc/rtadvd.conf The default configuration file. .It Pa /var/run/rtadvd.pid Contains the PID of the currently running .Nm . -.It Pa /var/run/rtadvd.dump -The file in which -.Nm -dumps its internal state. .El .Sh SEE ALSO .Xr rtadvd.conf 5 , Index: usr.sbin/rtadvd/rtadvd.c ================================================== ================= RCS file: /cvs/src/usr.sbin/rtadvd/rtadvd.c,v retrieving revision 1.30 diff -u -p -r1.30 rtadvd.c --- usr.sbin/rtadvd/rtadvd.c 24 Mar 2008 16:11:05 -0000 1.30 +++ usr.sbin/rtadvd/rtadvd.c 5 Apr 2008 21:22:26 -0000 @@ -56,6 +56,8 @@ #include <stdlib.h> #include <syslog.h> #include <util.h> +#include <pwd.h> +#include <paths.h> #include "rtadvd.h" #include "rrenum.h" @@ -78,7 +80,6 @@ struct iovec sndiov[2]; struct sockaddr_in6 from; struct sockaddr_in6 sin6_allnodes = {sizeof(sin6_allnodes), AF_INET6}; struct in6_addr in6a_site_allrouters; -static char *dumpfilename = "/var/run/rtadvd.dump"; /* XXX: should be configurable */ static char *mcastif; int sock; int rtsock = -1; @@ -152,6 +153,7 @@ main(argc, argv) struct timeval *timeout; int i, ch; int fflag = 0, logopt; + struct passwd *pw; /* get command line options and arguments */ #define OPTIONS "c:dDfM:Rs" @@ -237,6 +239,22 @@ main(argc, argv) maxfd = rtsock; } else rtsock = -1; + if ((pw = getpwnam("_rtadvd")) == NULL) + if ((pw = getpwnam("nobody")) == NULL) + errx(1, "neither user _rtadvd nor nobody found"); + + if (chroot(_PATH_VAREMPTY) == -1) + err(1, "chroot"); + if (chdir("/") == -1) + err(1, "chdir \"/\""); + if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) == -1) + err(1, "setresgid"); + if (setgroups(1, &pw->pw_gid) == -1) + err(1, "setgroups"); + if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) == -1) + err(1, "setresuid"); + + endpwent(); fdmasks = howmany(maxfd + 1, NFDBITS) * sizeof(fd_mask); if ((fdsetp = malloc(fdmasks)) == NULL) { @@ -260,7 +278,7 @@ main(argc, argv) if (do_dump) { /* SIGUSR1 */ do_dump = 0; - rtadvd_dump_file(dumpfilename); + rtadvd_dump(); } if (do_die) { |