Hello, Patch 9
# HG changeset patch # User MJP # Date 1452862954 -3600 # Fri Jan 15 14:02:34 2016 +0100 # Node ID 97146d7e9ebbb07f93d734dbdd7afe942f5cc557 # Parent 55eeedfb0cb54ed0d91c7de080b507fc79f64c30 Add: Introduce priv_set_if_rdomain() to set the rdomain of a device. diff -r 55eeedfb0cb5 -r 97146d7e9ebb 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 @@ -55,7 +55,8 @@ PRIVSEP_DEL_IF_ADDR, PRIVSEP_GET_IF_FLAGS, PRIVSEP_SET_IF_FLAGS, - PRIVSEP_GET_IF_RDOMAIN + PRIVSEP_GET_IF_RDOMAIN, + PRIVSEP_SET_IF_RDOMAIN }; struct PRIVSEP_OPEN_ARG { @@ -138,6 +139,11 @@ u_int rdomain; }; +struct PRIVSEP_SET_IF_RDOMAIN_ARG { + char ifname[IFNAMSIZ]; + u_int rdomain; +}; + struct PRIVSEP_COMMON_RESP { int retval; int rerrno; @@ -178,6 +184,8 @@ struct PRIVSEP_SET_IF_FLAGS_ARG *); static int privsep_npppd_check_get_if_rdomain ( struct PRIVSEP_GET_IF_RDOMAIN_ARG *); +static int privsep_npppd_check_set_if_rdomain ( + struct PRIVSEP_SET_IF_RDOMAIN_ARG *); static int privsep_sock = -1; static struct imsgbuf privsep_ibuf; @@ -557,6 +565,21 @@ return (retval); } +int +priv_set_if_rdomain(const char *ifname, int rdomain) +{ + struct PRIVSEP_SET_IF_RDOMAIN_ARG a; + + strlcpy(a.ifname, ifname, sizeof(a.ifname)); + a.rdomain = rdomain; + + (void)imsg_compose(&privsep_ibuf, PRIVSEP_SET_IF_RDOMAIN, 0, 0, -1, + &a, sizeof(a)); + imsg_flush(&privsep_ibuf); + + return (privsep_common_resp()); +} + static int privsep_recvfd(void) { @@ -1026,6 +1049,35 @@ imsg_flush(ibuf); } break; + case PRIVSEP_SET_IF_RDOMAIN: { + int s; + struct ifreq ifr; + struct PRIVSEP_SET_IF_RDOMAIN_ARG *a = imsg.data; + struct PRIVSEP_COMMON_RESP r = { -1, 0 }; + + if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(*a)) + r.rerrno = EINVAL; + else if (privsep_npppd_check_set_if_rdomain(a)) + r.rerrno = EACCES; + else { + memset(&ifr, 0, sizeof(ifr)); + strlcpy(ifr.ifr_name, a->ifname, + sizeof(ifr.ifr_name)); + ifr.ifr_rdomainid = a->rdomain; + if ((s = socket(AF_INET, SOCK_DGRAM, 0)) < 0 || + ioctl(s, SIOCSIFRDOMAIN, &ifr) != 0) { + r.retval = -1; + r.rerrno = errno; + } else + r.retval = 0; + if (s >= 0) + close(s); + } + (void)imsg_compose(ibuf, PRIVSEP_OK, 0, 0, -1, + &r, sizeof(r)); + imsg_flush(ibuf); + } + break; } imsg_free(&imsg); } @@ -1203,3 +1255,12 @@ return (1); } + +static int +privsep_npppd_check_set_if_rdomain(struct PRIVSEP_SET_IF_RDOMAIN_ARG *arg) +{ + if (startswith(arg->ifname, "tun") || startswith(arg->ifname, "pppx")) + return (0); + + return (1); +} diff -r 55eeedfb0cb5 -r 97146d7e9ebb 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_set_if_rdomain(const char *, int); int priv_get_if_rdomain(const char *, int *); #ifdef __cplusplus