summaryrefslogtreecommitdiffstats
path: root/usr.sbin/rtsold/rtsol.c
diff options
context:
space:
mode:
authorume <ume@FreeBSD.org>2003-08-08 16:42:37 +0000
committerume <ume@FreeBSD.org>2003-08-08 16:42:37 +0000
commit02ba92cc973152efd707c7e8e1c3b17091ddb26e (patch)
tree099a5ddb0139b1572c5cc2a9d1f4dc52af700a65 /usr.sbin/rtsold/rtsol.c
parent52b4a696e076a7e2fb7dd05bd2f6feec997189cd (diff)
downloadFreeBSD-src-02ba92cc973152efd707c7e8e1c3b17091ddb26e.zip
FreeBSD-src-02ba92cc973152efd707c7e8e1c3b17091ddb26e.tar.gz
Process the "O bit."
If the value of OtherConfigFlag changes from FALSE to TRUE, the host should invoke the stateful autoconfiguration protocol, requesting information. [RFC 2462 Section 5.5.3] Obtained from: KAME MFC after: 1 week
Diffstat (limited to 'usr.sbin/rtsold/rtsol.c')
-rw-r--r--usr.sbin/rtsold/rtsol.c127
1 files changed, 127 insertions, 0 deletions
diff --git a/usr.sbin/rtsold/rtsol.c b/usr.sbin/rtsold/rtsol.c
index 0543bca..923628d 100644
--- a/usr.sbin/rtsold/rtsol.c
+++ b/usr.sbin/rtsold/rtsol.c
@@ -35,7 +35,10 @@
#include <sys/socket.h>
#include <sys/uio.h>
#include <sys/time.h>
+#include <fcntl.h>
#include <sys/queue.h>
+#include <sys/wait.h>
+#include <sys/stat.h>
#include <net/if.h>
#include <net/route.h>
@@ -70,6 +73,9 @@ int rssock;
static struct sockaddr_in6 sin6_allrouters = {sizeof(sin6_allrouters), AF_INET6};
+static void call_script __P((char *, char *));
+static int safefile __P((const char *));
+
int
sockopen()
{
@@ -233,6 +239,7 @@ rtsol_input(int s)
struct cmsghdr *cm;
struct in6_pktinfo *pi = NULL;
struct ifinfo *ifi = NULL;
+ struct nd_router_advert *nd_ra;
u_char ntopbuf[INET6_ADDRSTRLEN], ifnamebuf[IFNAMSIZ];
/* get message */
@@ -330,6 +337,23 @@ rtsol_input(int s)
INET6_ADDRSTRLEN),
ifi->ifname, ifi->state);
+ nd_ra = (struct nd_router_advert *)icp;
+
+ /*
+ * Process the "O bit."
+ * If the value of OtherConfigFlag changes from FALSE to TRUE, the
+ * host should invoke the stateful autoconfiguration protocol,
+ * requesting information.
+ * [RFC 2462 Section 5.5.3]
+ */
+ if (((nd_ra->nd_ra_flags_reserved) & ND_RA_FLAG_OTHER) &&
+ !ifi->otherconfig) {
+ warnmsg(LOG_DEBUG, __func__,
+ "OtherConfigFlag on %s is turned on", ifi->ifname);
+ ifi->otherconfig = 1;
+ call_script(otherconf_script, ifi->ifname);
+ }
+
ifi->racnt++;
switch(ifi->state) {
@@ -343,3 +367,106 @@ rtsol_input(int s)
break;
}
}
+
+static void
+call_script(scriptpath, ifname)
+ char *scriptpath, *ifname;
+{
+ pid_t pid, wpid;
+
+ if (scriptpath == NULL)
+ return;
+
+ /* launch the script */
+ pid = fork();
+ if (pid < 0) {
+ warnmsg(LOG_ERR, __func__,
+ "failed to fork: %s", strerror(errno));
+ return;
+ } else if (pid) {
+ int wstatus;
+
+ do {
+ wpid = wait(&wstatus);
+ } while (wpid != pid && wpid > 0);
+
+ if (wpid < 0)
+ warnmsg(LOG_ERR, __func__,
+ "wait: %s", strerror(errno));
+ else {
+ warnmsg(LOG_DEBUG, __func__,
+ "script \"%s\" terminated", scriptpath);
+ }
+ } else {
+ char *argv[3];
+ int fd;
+
+ argv[0] = scriptpath;
+ argv[1] = ifname;
+ argv[2] = NULL;
+
+ if (safefile(scriptpath)) {
+ warnmsg(LOG_ERR, __func__,
+ "script \"%s\" cannot be executed safely",
+ scriptpath);
+ exit(1);
+ }
+
+ if ((fd = open("/dev/null", O_RDWR)) != -1) {
+ dup2(fd, STDIN_FILENO);
+ dup2(fd, STDOUT_FILENO);
+ dup2(fd, STDERR_FILENO);
+ if (fd > STDERR_FILENO)
+ close(fd);
+ }
+
+ execv(scriptpath, argv);
+
+ warnmsg(LOG_ERR, __func__, "child: exec failed: %s",
+ strerror(errno));
+ exit(0);
+ }
+
+ return;
+}
+
+static int
+safefile(path)
+ const char *path;
+{
+ struct stat s;
+ uid_t myuid;
+
+ /* no setuid */
+ if (getuid() != geteuid()) {
+ warnmsg(LOG_NOTICE, __func__,
+ "setuid'ed execution not allowed\n");
+ return (-1);
+ }
+
+ if (lstat(path, &s) != 0) {
+ warnmsg(LOG_NOTICE, __func__, "lstat failed: %s",
+ strerror(errno));
+ return (-1);
+ }
+
+ /* the file must be owned by the running uid */
+ myuid = getuid();
+ if (s.st_uid != myuid) {
+ warnmsg(LOG_NOTICE, __func__,
+ "%s has invalid owner uid\n", path);
+ return (-1);
+ }
+
+ switch (s.st_mode & S_IFMT) {
+ case S_IFREG:
+ break;
+ default:
+ warnmsg(LOG_NOTICE, __func__,
+ "%s is an invalid file type 0x%o\n",
+ path, (s.st_mode & S_IFMT));
+ return (-1);
+ }
+
+ return (0);
+}
OpenPOWER on IntegriCloud