Hello,
Patch 8
# HG changeset patch
# User MJP
# Date 1452862954 -3600
# Fri Jan 15 14:02:34 2016 +0100
# Node ID 55eeedfb0cb54ed0d91c7de080b507fc79f64c30
# Parent 8d76f9f8cc873602c8593b896133648cdedb6afd
Add: Introduce priv_get_if_rdomain() to get the rdomain of a device.
diff -r 8d76f9f8cc87 -r 55eeedfb0cb5 usr.sbin/npppd/npppd/privsep.c
--- usr.sbin/npppd/npppd/privsep.c Fri Jan 15 14:02:34 2016 +0100
+++ usr.sbin/npppd/npppd/privsep.c Fri Jan 15 14:02:34 2016 +0100
@@ -54,7 +54,8 @@
PRIVSEP_SET_IF_ADDR,
PRIVSEP_DEL_IF_ADDR,
PRIVSEP_GET_IF_FLAGS,
- PRIVSEP_SET_IF_FLAGS
+ PRIVSEP_SET_IF_FLAGS,
+ PRIVSEP_GET_IF_RDOMAIN
};
struct PRIVSEP_OPEN_ARG {
@@ -126,6 +127,17 @@
int flags;
};
+struct PRIVSEP_GET_IF_RDOMAIN_ARG {
+ char ifname[IFNAMSIZ];
+ u_int rdomain;
+};
+
+struct PRIVSEP_GET_IF_RDOMAIN_RESP {
+ int retval;
+ int rerrno;
+ u_int rdomain;
+};
+
struct PRIVSEP_COMMON_RESP {
int retval;
int rerrno;
@@ -164,6 +176,8 @@
struct PRIVSEP_GET_IF_FLAGS_ARG *);
static int privsep_npppd_check_set_if_flags (
struct PRIVSEP_SET_IF_FLAGS_ARG *);
+static int privsep_npppd_check_get_if_rdomain (
+ struct PRIVSEP_GET_IF_RDOMAIN_ARG *);
static int privsep_sock = -1;
static struct imsgbuf privsep_ibuf;
@@ -512,6 +526,37 @@
return (privsep_common_resp());
}
+int
+priv_get_if_rdomain(const char *ifname, int *prdomain)
+{
+ struct PRIVSEP_GET_IF_RDOMAIN_ARG a;
+ struct PRIVSEP_GET_IF_RDOMAIN_RESP *r;
+ struct imsg imsg;
+ int retval = -1;
+
+ strlcpy(a.ifname, ifname, sizeof(a.ifname));
+ a.rdomain = 0;
+
+ (void)imsg_compose(&privsep_ibuf, PRIVSEP_GET_IF_RDOMAIN, 0, 0, -1,
+ &a, sizeof(a));
+ imsg_flush(&privsep_ibuf);
+
+ if (imsg_read_and_get(&privsep_ibuf, &imsg) == -1)
+ return (-1);
+ if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(*r))
+ errno = EACCES;
+ else {
+ r = imsg.data;
+ *prdomain = r->rdomain;
+ if (r->retval != 0)
+ errno = r->rerrno;
+ retval = r->retval;
+ }
+ imsg_free(&imsg);
+
+ return (retval);
+}
+
static int
privsep_recvfd(void)
{
@@ -946,6 +991,41 @@
imsg_flush(ibuf);
}
break;
+ case PRIVSEP_GET_IF_RDOMAIN: {
+ int s;
+ struct ifreq ifr;
+ struct PRIVSEP_GET_IF_RDOMAIN_ARG *a = imsg.data;
+ struct PRIVSEP_GET_IF_RDOMAIN_RESP r;
+
+ memset(&r, 0, sizeof(r));
+ r.retval = -1;
+
+ if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(*a))
+ r.rerrno = EINVAL;
+ else if (privsep_npppd_check_get_if_rdomain(a)) {
+ r.rerrno = EACCES;
+ } else {
+ memset(&ifr, 0, sizeof(ifr));
+ strlcpy(ifr.ifr_name, a->ifname,
+ sizeof(ifr.ifr_name));
+ if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
+ r.retval = -1;
+ r.rerrno = errno;
+ } else {
+ r.retval = 0;
+ if (ioctl(s, SIOCGIFRDOMAIN, &ifr) ==
-1)
+ r.rdomain = 0;
+ else
+ r.rdomain = ifr.ifr_rdomainid;
+ }
+ if (s >= 0)
+ close(s);
+ }
+ (void)imsg_compose(ibuf, PRIVSEP_OK, 0, 0, -1,
+ &r, sizeof(r));
+ imsg_flush(ibuf);
+ }
+ break;
}
imsg_free(&imsg);
}
@@ -1114,3 +1194,12 @@
return (1);
}
+
+static int
+privsep_npppd_check_get_if_rdomain(struct PRIVSEP_GET_IF_RDOMAIN_ARG *arg)
+{
+ if (startswith(arg->ifname, "tun") || startswith(arg->ifname, "pppx")
|| startswith(arg->ifname, "lo"))
+ return (0);
+
+ return (1);
+}
diff -r 8d76f9f8cc87 -r 55eeedfb0cb5 usr.sbin/npppd/npppd/privsep.h
--- usr.sbin/npppd/npppd/privsep.h Fri Jan 15 14:02:34 2016 +0100
+++ usr.sbin/npppd/npppd/privsep.h Fri Jan 15 14:02:34 2016 +0100
@@ -45,6 +45,7 @@
int priv_delete_if_addr(const char *);
int priv_set_if_flags(const char *, int);
int priv_get_if_flags(const char *, int *);
+int priv_get_if_rdomain(const char *, int *);
#ifdef __cplusplus
}