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
 }

Reply via email to