diff options
author | ume <ume@FreeBSD.org> | 2003-08-08 16:42:37 +0000 |
---|---|---|
committer | ume <ume@FreeBSD.org> | 2003-08-08 16:42:37 +0000 |
commit | 02ba92cc973152efd707c7e8e1c3b17091ddb26e (patch) | |
tree | 099a5ddb0139b1572c5cc2a9d1f4dc52af700a65 /usr.sbin/rtsold/rtsol.c | |
parent | 52b4a696e076a7e2fb7dd05bd2f6feec997189cd (diff) | |
download | FreeBSD-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.c | 127 |
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); +} |