summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorreyk <reyk@openbsd.org>2009-12-01 16:21:46 +0000
committerreyk <reyk@openbsd.org>2009-12-01 16:21:46 +0000
commit5329634ebd49324f9ff26ee73bd5f8dbd76dd4ff (patch)
tree7a701bb0eacb9add7de416c964e38021a99153da
parentadd "exec" keyword (diff)
downloadwireguard-openbsd-5329634ebd49324f9ff26ee73bd5f8dbd76dd4ff.tar.xz
wireguard-openbsd-5329634ebd49324f9ff26ee73bd5f8dbd76dd4ff.zip
Add the new exec command to run a process and its children in a
non-default rdomain/rtable. route will change the default rdomain using the new setrdomain() syscall and execute the supplied command, eg. "route -T1 exec /usr/sbin/named". Tested by many including michele@, phessler@ ok claudio@, deraadt@
-rw-r--r--sbin/route/keywords.h4
-rw-r--r--sbin/route/route.824
-rw-r--r--sbin/route/route.c54
3 files changed, 65 insertions, 17 deletions
diff --git a/sbin/route/keywords.h b/sbin/route/keywords.h
index cdc548ced82..722ff225f08 100644
--- a/sbin/route/keywords.h
+++ b/sbin/route/keywords.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: keywords.h,v 1.25 2009/10/30 17:32:34 jsg Exp $ */
+/* $OpenBSD: keywords.h,v 1.26 2009/12/01 16:21:46 reyk Exp $ */
/* WARNING! This file was generated by keywords.sh */
@@ -16,6 +16,7 @@ enum {
K_DELETE,
K_DST,
K_ENCAP,
+ K_EXEC,
K_EXPIRE,
K_FLUSH,
K_GATEWAY,
@@ -73,6 +74,7 @@ struct keytab keywords[] = {
{ "delete", K_DELETE },
{ "dst", K_DST },
{ "encap", K_ENCAP },
+ { "exec", K_EXEC },
{ "expire", K_EXPIRE },
{ "flush", K_FLUSH },
{ "gateway", K_GATEWAY },
diff --git a/sbin/route/route.8 b/sbin/route/route.8
index e2836a1b5ee..54a5018b95c 100644
--- a/sbin/route/route.8
+++ b/sbin/route/route.8
@@ -1,4 +1,4 @@
-.\" $OpenBSD: route.8,v 1.61 2009/11/04 08:27:21 jmc Exp $
+.\" $OpenBSD: route.8,v 1.62 2009/12/01 16:21:46 reyk Exp $
.\" $NetBSD: route.8,v 1.6 1995/03/18 15:00:13 cgd Exp $
.\"
.\" Copyright (c) 1983, 1991, 1993
@@ -30,7 +30,7 @@
.\"
.\" @(#)route.8 8.3 (Berkeley) 3/19/94
.\"
-.Dd $Mdocdate: November 4 2009 $
+.Dd $Mdocdate: December 1 2009 $
.Dt ROUTE 8
.Os
.Sh NAME
@@ -106,6 +106,8 @@ Add a route.
Change aspects of a route (such as its gateway).
.It Cm delete
Delete a specific route.
+.It Cm exec
+Execute a command in the specified routing domain.
.It Cm flush
Remove all routes.
.It Cm get
@@ -156,6 +158,24 @@ or
modifiers.
.Pp
The
+.Cm exec
+command has the syntax:
+.Bd -filled -offset indent
+.Nm route Op Fl T Ar tableid
+.Cm exec
+.Op Ar command ...
+.Ed
+.Pp
+If the
+.Cm exec
+command is specified,
+.Nm
+will execute a command forcing the process and its children into the
+routing domain as specified with the
+.Fl T Ar tableid
+option.
+.Pp
+The
.Cm monitor
command has the syntax:
.Bd -filled -offset indent
diff --git a/sbin/route/route.c b/sbin/route/route.c
index 2d7952b95a7..58b78246346 100644
--- a/sbin/route/route.c
+++ b/sbin/route/route.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: route.c,v 1.140 2009/11/02 21:08:44 claudio Exp $ */
+/* $OpenBSD: route.c,v 1.141 2009/12/01 16:21:46 reyk Exp $ */
/* $NetBSD: route.c,v 1.16 1996/04/15 18:27:05 cgd Exp $ */
/*
@@ -109,7 +109,8 @@ void set_metric(char *, int);
void inet_makenetandmask(u_int32_t, struct sockaddr_in *, int);
void interfaces(void);
void getlabel(char *);
-void gettable(const char *);
+int gettable(const char *);
+int rdomain(int, int, char **);
__dead void
usage(char *cp)
@@ -122,7 +123,7 @@ usage(char *cp)
"usage: %s [-dnqtv] [-T tableid] command [[modifiers] args]\n",
__progname);
fprintf(stderr,
- "commands: add, change, delete, flush, get, monitor, show\n");
+ "commands: add, change, delete, exec, flush, get, monitor, show\n");
exit(1);
}
@@ -135,6 +136,8 @@ main(int argc, char **argv)
{
int ch;
int rval = 0;
+ int rtableid = 1;
+ int kw;
if (argc < 2)
usage(NULL);
@@ -154,7 +157,7 @@ main(int argc, char **argv)
tflag = 1;
break;
case 'T':
- gettable(optarg);
+ rtableid = gettable(optarg);
break;
case 'd':
debugonly = 1;
@@ -170,16 +173,27 @@ main(int argc, char **argv)
uid = geteuid();
if (*argv == NULL)
usage(NULL);
- if (keyword(*argv) == K_MONITOR)
- monitor(argc, argv);
- if (tflag)
- s = open(_PATH_DEVNULL, O_WRONLY);
- else
- s = socket(PF_ROUTE, SOCK_RAW, 0);
- if (s == -1)
- err(1, "socket");
- switch (keyword(*argv)) {
+ kw = keyword(*argv);
+ switch (kw) {
+ case K_EXEC:
+ break;
+ case K_MONITOR:
+ monitor(argc, argv);
+ break;
+ default:
+ if (tflag)
+ s = open(_PATH_DEVNULL, O_WRONLY);
+ else
+ s = socket(PF_ROUTE, SOCK_RAW, 0);
+ if (s == -1)
+ err(1, "socket");
+ break;
+ }
+ switch (kw) {
+ case K_EXEC:
+ rval = rdomain(rtableid, argc - 1, argv + 1);
+ break;
case K_GET:
uid = 0;
/* FALLTHROUGH */
@@ -1579,7 +1593,7 @@ getlabel(char *name)
rtm_addrs |= RTA_LABEL;
}
-void
+int
gettable(const char *s)
{
const char *errstr;
@@ -1587,4 +1601,16 @@ gettable(const char *s)
tableid = strtonum(s, 0, RT_TABLEID_MAX, &errstr);
if (errstr)
errx(1, "invalid table id: %s", errstr);
+ return (tableid);
+}
+
+int
+rdomain(int rtableid, int argc, char **argv)
+{
+ if (!argc)
+ usage(NULL);
+ if (setrdomain(rtableid) == -1)
+ err(1, "setrdomain");
+ execvp(*argv, argv);
+ return (errno == ENOENT ? 127 : 126);
}