Module Name:    src
Committed By:   roy
Date:           Tue Jul  9 09:34:59 UTC 2013

Modified Files:
        src/etc: group master.passwd
        src/etc/mtree: special
        src/etc/rc.d: rtadvd
        src/usr.sbin/rtadvd: dump.c rtadvd.c rtadvd.h

Log Message:
Add _rtadvd user and group.
Add a chroot dir for the _rtadvd user.
Drop privs to the user _rtadvd after acquiring our socket.
When rc.d/rtadvd starts or reloads, the rtadvd config file is copied
into the chroot before starting or reloading rtadvd itself.
Create a symlink from /var/run/rtadvd.dump to the chroot

Inital idea from OpenBSD patch rtadvd.c r1.36


To generate a diff of this commit:
cvs rdiff -u -r1.31 -r1.32 src/etc/group
cvs rdiff -u -r1.46 -r1.47 src/etc/master.passwd
cvs rdiff -u -r1.145 -r1.146 src/etc/mtree/special
cvs rdiff -u -r1.7 -r1.8 src/etc/rc.d/rtadvd
cvs rdiff -u -r1.10 -r1.11 src/usr.sbin/rtadvd/dump.c
cvs rdiff -u -r1.43 -r1.44 src/usr.sbin/rtadvd/rtadvd.c
cvs rdiff -u -r1.12 -r1.13 src/usr.sbin/rtadvd/rtadvd.h

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/etc/group
diff -u src/etc/group:1.31 src/etc/group:1.32
--- src/etc/group:1.31	Fri Jun  7 06:35:11 2013
+++ src/etc/group	Tue Jul  9 09:34:58 2013
@@ -25,6 +25,7 @@ _tests:*:26:
 _tcpdump:*:27:
 _tss:*:28:
 _gpio:*:29:
+_rtadvd:*:30:
 guest:*:31:root
 nobody:*:39:
 utmp:*:45:

Index: src/etc/master.passwd
diff -u src/etc/master.passwd:1.46 src/etc/master.passwd:1.47
--- src/etc/master.passwd:1.46	Wed Apr 25 16:11:26 2012
+++ src/etc/master.passwd	Tue Jul  9 09:34:58 2013
@@ -18,5 +18,6 @@ _mdnsd:*:25:25::0:0:& pseudo-user:/nonex
 _tests:*:26:26::0:0:& pseudo-user:/nonexistent:/sbin/nologin
 _tcpdump:*:27:27::0:0:& pseudo-user:/var/chroot/tcpdump:/sbin/nologin
 _tss:*:28:28::0:0:& pseudo-user:/var/tpm:/sbin/nologin
+_rtadvd:*:30:30::0:0:& pseudo-user:/var/chroot/rtadvd:/sbin/nologin
 uucp:*:66:1::0:0:UNIX-to-UNIX Copy:/nonexistent:/sbin/nologin
 nobody:*:32767:39::0:0:Unprivileged user:/nonexistent:/sbin/nologin

Index: src/etc/mtree/special
diff -u src/etc/mtree/special:1.145 src/etc/mtree/special:1.146
--- src/etc/mtree/special:1.145	Thu May 16 07:37:05 2013
+++ src/etc/mtree/special	Tue Jul  9 09:34:58 2013
@@ -1,4 +1,4 @@
-#	$NetBSD: special,v 1.145 2013/05/16 07:37:05 yamt Exp $
+#	$NetBSD: special,v 1.146 2013/07/09 09:34:58 roy Exp $
 #	@(#)special	8.2 (Berkeley) 1/23/94
 #
 # This file may be overwritten on upgrades.
@@ -395,6 +395,10 @@
 ./var/chroot/ntpd/var/db	type=dir  mode=0775 gname=ntpd
 ./var/chroot/ntpd/var/run	type=dir  mode=0775 gname=ntpd
 ./var/chroot/pflogd		type=dir  mode=0755
+./var/chroot/rtadvd		type=dir  mode=0755
+./var/chroot/rtadvd/etc		type=dir  mode=0755
+./var/chroot/rtadvd/var		type=dir  mode=0755
+./var/chroot/rtadvd/var/run	type=dir  mode=0775 gname=_rtadvd
 ./var/chroot/sshd		type=dir  mode=0755
 ./var/chroot/tcpdump		type=dir  mode=0755
 ./var/chroot/tftp-proxy		type=dir  mode=0755

Index: src/etc/rc.d/rtadvd
diff -u src/etc/rc.d/rtadvd:1.7 src/etc/rc.d/rtadvd:1.8
--- src/etc/rc.d/rtadvd:1.7	Thu Dec 13 15:51:17 2012
+++ src/etc/rc.d/rtadvd	Tue Jul  9 09:34:58 2013
@@ -1,6 +1,6 @@
 #!/bin/sh
 #
-# $NetBSD: rtadvd,v 1.7 2012/12/13 15:51:17 roy Exp $
+# $NetBSD: rtadvd,v 1.8 2013/07/09 09:34:58 roy Exp $
 #
 
 # PROVIDE: rtadvd
@@ -9,20 +9,51 @@
 
 $_rc_subr_loaded . /etc/rc.subr
 
-name="rtadvd"
+name=rtadvd
 rcvar=$name
-command="/usr/sbin/${name}"
+command="/usr/sbin/$name"
 pidfile="/var/run/$name.pid"
-extra_commands="reload"
-start_precmd="rtadvd_precmd"
+extra_commands=reload
+start_precmd=rtadvd_prestart
+reload_precmd=rtadvd_prereload
 
-rtadvd_precmd()
+rtadvd_prereload()
 {
-	if [ "$ip6mode" != "router" ]; then
+	local chdir="$(getent passwd _rtadvd | cut -d: -f6)"
+	local conf=/etc/rtadvd.conf myflags o confdir
+	
+	[ -z "$chdir" -o "$chdir" = / ] && return 0
+
+	if [ -n "$flags" ]; then
+		myflags=$flags
+	else
+		eval myflags=\$${name}_flags
+	fi
+	set -- ${myflags}
+	while getopts c:dDfM:Rs o; do
+		case "$1" in
+		-c)	conf="$OPTARG";;
+		esac
+		shift
+	done
+	confdir=$(dirname "$conf")
+	
+	echo "$name: copying $conf to $chdir$conf"
+	cp "$conf" "$chdir$conf"
+
+	# Provide a link to the chrooted dump file
+	ln -snf "$chdir/var/run/$name.dump" /var/run
+}
+
+rtadvd_prestart()
+{
+	if [ "$ip6mode" != router ]; then
 		warn \
 	"${name} cannot be used on IPv6 host, only on an IPv6 router."
 		return 1
 	fi
+
+	rtadvd_prereload
 }
 
 load_rc_config $name

Index: src/usr.sbin/rtadvd/dump.c
diff -u src/usr.sbin/rtadvd/dump.c:1.10 src/usr.sbin/rtadvd/dump.c:1.11
--- src/usr.sbin/rtadvd/dump.c:1.10	Thu Dec 13 15:36:36 2012
+++ src/usr.sbin/rtadvd/dump.c	Tue Jul  9 09:34:59 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: dump.c,v 1.10 2012/12/13 15:36:36 roy Exp $	*/
+/*	$NetBSD: dump.c,v 1.11 2013/07/09 09:34:59 roy Exp $	*/
 /*	$KAME: dump.c,v 1.34 2004/06/14 05:35:59 itojun Exp $	*/
 
 /*
@@ -269,7 +269,7 @@ rtadvd_dump_file(const char *dumpfile)
 	    dumpfile);
 
 	if ((fp = fopen(dumpfile, "w")) == NULL) {
-		syslog(LOG_WARNING, "<%s> open a dump file(%s)",
+		syslog(LOG_WARNING, "<%s> open a dump file(%s): %m",
 		       __func__, dumpfile);
 		return;
 	}

Index: src/usr.sbin/rtadvd/rtadvd.c
diff -u src/usr.sbin/rtadvd/rtadvd.c:1.43 src/usr.sbin/rtadvd/rtadvd.c:1.44
--- src/usr.sbin/rtadvd/rtadvd.c:1.43	Fri Jun 28 07:59:32 2013
+++ src/usr.sbin/rtadvd/rtadvd.c	Tue Jul  9 09:34:59 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: rtadvd.c,v 1.43 2013/06/28 07:59:32 roy Exp $	*/
+/*	$NetBSD: rtadvd.c,v 1.44 2013/07/09 09:34:59 roy Exp $	*/
 /*	$KAME: rtadvd.c,v 1.92 2005/10/17 14:40:02 suz Exp $	*/
 
 /*
@@ -58,6 +58,7 @@
 #include <util.h>
 #endif
 #include <poll.h>
+#include <pwd.h>
 
 #include "rtadvd.h"
 #include "rrenum.h"
@@ -177,6 +178,7 @@ main(int argc, char *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"
@@ -229,6 +231,17 @@ main(int argc, char *argv[])
 	if (dflag == 1)
 		(void)setlogmask(LOG_UPTO(LOG_INFO));
 
+	errno = 0; /* Ensure errno is 0 so we know if getpwnam errors or not */
+	if ((pw = getpwnam(RTADVD_USER)) == NULL) {
+		if (errno == 0)
+			syslog(LOG_ERR,
+			    "user %s does not exist, aborting",
+			    RTADVD_USER);
+		else
+			syslog(LOG_ERR, "getpwnam: %s: %m", RTADVD_USER);
+		exit(1);
+	}
+
 	/* timer initialization */
 	rtadvd_timer_init();
 
@@ -260,6 +273,23 @@ main(int argc, char *argv[])
 	} else
 		set[1].fd = -1;
 
+	syslog(LOG_INFO, "dropping privileges to %s", RTADVD_USER);
+	if (chroot(pw->pw_dir) == -1) {
+		syslog(LOG_ERR, "chroot: %s: %m", pw->pw_dir);
+		exit(1);
+	}
+	if (chdir("/") == -1) {
+		syslog(LOG_ERR, "chdir: /: %m");
+		exit(1);
+	}
+	if (setgroups(1, &pw->pw_gid) == -1 ||
+	    setgid(pw->pw_gid) == -1 || 
+	    setuid(pw->pw_uid) == -1)
+	{
+		syslog(LOG_ERR, "failed to drop privileges: %m");
+		exit(1);
+	}
+
 	signal(SIGINT, set_die);
 	signal(SIGTERM, set_die);
 	signal(SIGHUP, set_reconf);

Index: src/usr.sbin/rtadvd/rtadvd.h
diff -u src/usr.sbin/rtadvd/rtadvd.h:1.12 src/usr.sbin/rtadvd/rtadvd.h:1.13
--- src/usr.sbin/rtadvd/rtadvd.h:1.12	Thu Dec 13 15:36:36 2012
+++ src/usr.sbin/rtadvd/rtadvd.h	Tue Jul  9 09:34:59 2013
@@ -1,4 +1,4 @@
-/*	$NetBSD: rtadvd.h,v 1.12 2012/12/13 15:36:36 roy Exp $	*/
+/*	$NetBSD: rtadvd.h,v 1.13 2013/07/09 09:34:59 roy Exp $	*/
 /*	$KAME: rtadvd.h,v 1.30 2005/10/17 14:40:02 suz Exp $	*/
 
 /*
@@ -30,6 +30,8 @@
  * SUCH DAMAGE.
  */
 
+#define RTADVD_USER	"_rtadvd"
+
 #define ALLNODES "ff02::1"
 #define ALLROUTERS_LINK "ff02::2"
 #define ALLROUTERS_SITE "ff05::2"

Reply via email to