From edd7c245d3a77012abf801da00d5664ebaa5f749 Mon Sep 17 00:00:00 2001 From: paul Date: Wed, 4 Jun 2003 13:59:38 +0000 Subject: 2003-06-04 Paul Jakma * Merge of zebra privileges --- zebra/Makefile.am | 7 +++--- zebra/ioctl.c | 17 +++++++++++++- zebra/ipforward_proc.c | 32 +++++++++++++++++++++++++- zebra/ipforward_solaris.c | 58 ++++++++++++++++++++++++++++++++--------------- zebra/ipforward_sysctl.c | 43 +++++++++++++++++++++++++++++++---- zebra/kernel_socket.c | 10 ++++++++ zebra/main.c | 35 +++++++++++++++++++++++++--- zebra/rt_netlink.c | 41 ++++++++++++++++++++++++++++++++- zebra/rt_socket.c | 53 +++++++++++++++++++++++++++++++++++++++---- zebra/rtadv.c | 13 ++++++++++- zebra/zserv.c | 9 ++++++++ 11 files changed, 280 insertions(+), 38 deletions(-) (limited to 'zebra') diff --git a/zebra/Makefile.am b/zebra/Makefile.am index 6214767d..ce564672 100644 --- a/zebra/Makefile.am +++ b/zebra/Makefile.am @@ -13,9 +13,10 @@ rt_method = @RT_METHOD@ rtread_method = @RTREAD_METHOD@ kernel_method = @KERNEL_METHOD@ other_method = @OTHER_METHOD@ +libcap = @LIBCAP@ otherobj = $(ipforward) $(if_method) $(if_proc) $(rt_method) \ - $(rtread_method) $(kernel_method) $(other_method) + $(rtread_method) $(kernel_method) $(other_method) $(libcap) sbin_PROGRAMS = zebra @@ -25,7 +26,7 @@ zebra_SOURCES = \ noinst_HEADERS = \ connected.h ioctl.h rib.h rt.h zserv.h redistribute.h debug.h rtadv.h \ - interface.h ipforward.h irdp.h + interface.h ipforward.h zebra_LDADD = ../lib/libzebra.a $(otherobj) $(LIB_IPV6) @@ -38,7 +39,7 @@ EXTRA_DIST = $(sysconf_DATA) if_ioctl.c if_netlink.c if_proc.c if_sysctl.c \ ipforward_solaris.c ipforward_sysctl.c rt_ioctl.c rt_netlink.c \ rt_socket.c rtread_netlink.c rtread_proc.c rtread_sysctl.c \ rtread_getmsg.c kernel_socket.c kernel_netlink.c mtu_kvm.c \ - GNOME-SMI GNOME-PRODUCT-ZEBRA-MIB irdp.c + GNOME-SMI GNOME-PRODUCT-ZEBRA-MIB #client : client_main.o ../lib/libzebra.a # $(CC) -g -o client client_main.o ../lib/libzebra.a $(LIBS) $(LIB_IPV6) diff --git a/zebra/ioctl.c b/zebra/ioctl.c index 3e5d1d2f..f8e7f22b 100644 --- a/zebra/ioctl.c +++ b/zebra/ioctl.c @@ -27,10 +27,13 @@ #include "prefix.h" #include "ioctl.h" #include "log.h" +#include "privs.h" #include "zebra/rib.h" #include "zebra/rt.h" +extern struct zebra_privs_t zserv_privs; + /* clear and set interface name string */ void ifreq_set_name (struct ifreq *ifreq, struct interface *ifp) @@ -46,14 +49,19 @@ if_ioctl (u_long request, caddr_t buffer) int ret = 0; int err = 0; + if (zserv_privs.change(ZPRIVS_RAISE)) + zlog (NULL, LOG_ERR, "Can't raise privileges"); sock = socket (AF_INET, SOCK_DGRAM, 0); if (sock < 0) { + if (zserv_privs.change(ZPRIVS_LOWER)) + zlog (NULL, LOG_ERR, "Can't lower privileges"); perror ("socket"); exit (1); } - ret = ioctl (sock, request, buffer); + if (zserv_privs.change(ZPRIVS_LOWER)) + zlog (NULL, LOG_ERR, "Can't lower privileges"); if (ret < 0) { err = errno; @@ -76,14 +84,21 @@ if_ioctl_ipv6 (u_long request, caddr_t buffer) int ret = 0; int err = 0; + if (zserv_privs.change(ZPRIVS_RAISE)) + zlog (NULL, LOG_ERR, "Can't raise privileges"); sock = socket (AF_INET6, SOCK_DGRAM, 0); if (sock < 0) { + if (zserv_privs.change(ZPRIVS_LOWER)) + zlog (NULL, LOG_ERR, "Can't lower privileges"); perror ("socket"); exit (1); } ret = ioctl (sock, request, buffer); + if (zserv_privs.change(ZPRIVS_LOWER)) + zlog (NULL, LOG_ERR, "Can't lower privileges"); + if (ret < 0) { err = errno; diff --git a/zebra/ipforward_proc.c b/zebra/ipforward_proc.c index eb8cef01..a31ec84b 100644 --- a/zebra/ipforward_proc.c +++ b/zebra/ipforward_proc.c @@ -22,6 +22,11 @@ #include +#include "log.h" +#include "privs.h" + +extern struct zebra_privs_t zserv_privs; + char proc_net_snmp[] = "/proc/net/snmp"; static void @@ -68,9 +73,15 @@ int ipforward_on () { FILE *fp; + + if ( zserv_privs.change(ZPRIVS_RAISE) ) + zlog_err ("Can't raise privileges, %s", strerror (errno) ); fp = fopen (proc_ipv4_forwarding, "w"); - + + if ( zserv_privs.change(ZPRIVS_LOWER) ) + zlog_err ("Can't lower privileges, %s", strerror (errno)); + if (fp == NULL) return -1; @@ -86,7 +97,14 @@ ipforward_off () { FILE *fp; + if ( zserv_privs.change(ZPRIVS_RAISE) ) + zlog_err ("Can't raise privileges, %s", strerror (errno)); + fp = fopen (proc_ipv4_forwarding, "w"); + + if ( zserv_privs.change(ZPRIVS_LOWER) ) + zlog_err ("Can't lower privileges, %s", strerror (errno)); + if (fp == NULL) return -1; @@ -124,7 +142,13 @@ ipforward_ipv6_on () { FILE *fp; + if ( zserv_privs.change(ZPRIVS_RAISE) ) + zlog_err ("Can't raise privileges, %s", strerror (errno)); + fp = fopen (proc_ipv6_forwarding, "w"); + + if ( zserv_privs.change(ZPRIVS_LOWER) ) + zlog_err ("Can't lower privileges, %s", strerror (errno)); if (fp == NULL) return -1; @@ -141,7 +165,13 @@ ipforward_ipv6_off () { FILE *fp; + if ( zserv_privs.change(ZPRIVS_RAISE) ) + zlog_err ("Can't raise privileges, %s", strerror (errno)); + fp = fopen (proc_ipv6_forwarding, "w"); + + if ( zserv_privs.change(ZPRIVS_LOWER) ) + zlog_err ("Can't lower privileges, %s", strerror (errno)); if (fp == NULL) return -1; diff --git a/zebra/ipforward_solaris.c b/zebra/ipforward_solaris.c index 63d1110c..fe06e74d 100644 --- a/zebra/ipforward_solaris.c +++ b/zebra/ipforward_solaris.c @@ -22,6 +22,7 @@ #include #include "log.h" +#include "prefix.h" /* ** Solaris should define IP_DEV_NAME in , but we'll save @@ -33,6 +34,9 @@ #define IP_DEV_NAME "/dev/ip" #endif /* + +extern struct zebra_privs_t zserv_privs; + ** This is a limited ndd style function that operates one integer ** value only. Errors return -1. ND_SET commands return 0 on ** success. ND_GET commands return the value on success (which could @@ -63,30 +67,48 @@ solaris_nd(const int cmd, const char* parameter, const int value) zlog_err("internal error - inappropriate command given to solaris_nd()%s:%d", __FILE__, __LINE__); return -1; } + strioctl.ic_cmd = cmd; strioctl.ic_timout = 0; strioctl.ic_len = ND_BUFFER_SIZE; strioctl.ic_dp = nd_buf; - if ((fd = open (device, O_RDWR)) < 0) { - zlog_warn("failed to open device %s - %s", device, strerror(errno)); - return -1; - } - if (ioctl (fd, I_STR, &strioctl) < 0) { - close (fd); - zlog_warn("ioctl I_STR failed on device %s - %s", device,strerror(errno)); - return -1; - } + + if ( zserv_privs.change (ZPRIVS_RAISE) ) + zlog_err ("solaris_nd: Can't raise privileges"); + if ((fd = open (device, O_RDWR)) < 0) + { + zlog_warn("failed to open device %s - %s", device, strerror(errno)); + if ( zserv_privs.change (ZPRIVS_LOWER) ) + zlog_err ("solaris_nd: Can't lower privileges"); + return -1; + } + if (ioctl (fd, I_STR, &strioctl) < 0) + { + if ( zserv_privs.change (ZPRIVS_LOWER) ) + zlog_err ("solaris_nd: Can't lower privileges"); + close (fd); + zlog_warn("ioctl I_STR failed on device %s - %s", device,strerror(errno)); + return -1; + } close(fd); - if (cmd == ND_GET) { - errno = 0; - retval = atoi(nd_buf); - if (errno) { - zlog_warn("failed to convert returned value to integer - %s",strerror(errno)); - retval = -1; + if ( zserv_privs.change (ZPRIVS_LOWER) ) + zlog_err ("solaris_nd: Can't lower privileges"); + + if (cmd == ND_GET) + { + errno = 0; + retval = atoi(nd_buf); + if (errno) + { + zlog_warn("failed to convert returned value to integer - %s", + strerror(errno)); + retval = -1; + } + } + else + { + retval = 0; } - } else { - retval = 0; - } return retval; } diff --git a/zebra/ipforward_sysctl.c b/zebra/ipforward_sysctl.c index 828eb865..53b6c6f0 100644 --- a/zebra/ipforward_sysctl.c +++ b/zebra/ipforward_sysctl.c @@ -20,6 +20,7 @@ */ #include +#include "privs.h" #ifdef NRL #include @@ -29,6 +30,8 @@ #define MIB_SIZ 4 +extern struct zebra_privs_t zserv_privs; + /* IPv4 forwarding control MIB. */ int mib[MIB_SIZ] = { @@ -60,11 +63,17 @@ ipforward_on () int ipforwarding = 1; len = sizeof ipforwarding; - if (sysctl (mib, MIB_SIZ, NULL, NULL, &ipforwarding, len) < 0) + if (zserv_privs.change(ZPRIVS_RAISE)) + zlog (NULL, LOG_ERR, "Can't raise privileges"); + if (sysctl (mib, MIB_SIZ, NULL, NULL, &ipforwarding, len) < 0) { + if (zserv_privs.change(ZPRIVS_LOWER)) + zlog (NULL, LOG_ERR, "Can't lower privileges"); zlog_warn ("Can't set ipforwarding on"); return -1; } + if (zserv_privs.change(ZPRIVS_LOWER)) + zlog (NULL, LOG_ERR, "Can't lower privileges"); return ipforwarding; } @@ -75,11 +84,17 @@ ipforward_off () int ipforwarding = 0; len = sizeof ipforwarding; - if (sysctl (mib, MIB_SIZ, NULL, NULL, &ipforwarding, len) < 0) + if (zserv_privs.change(ZPRIVS_RAISE)) + zlog (NULL, LOG_ERR, "Can't raise privileges"); + if (sysctl (mib, MIB_SIZ, NULL, NULL, &ipforwarding, len) < 0) { + if (zserv_privs.change(ZPRIVS_LOWER)) + zlog (NULL, LOG_ERR, "Can't lower privileges"); zlog_warn ("Can't set ipforwarding on"); return -1; } + if (zserv_privs.change(ZPRIVS_LOWER)) + zlog (NULL, LOG_ERR, "Can't lower privileges"); return ipforwarding; } @@ -106,11 +121,17 @@ ipforward_ipv6 () int ip6forwarding = 0; len = sizeof ip6forwarding; - if (sysctl (mib_ipv6, MIB_SIZ, &ip6forwarding, &len, 0, 0) < 0) + if (zserv_privs.change(ZPRIVS_RAISE)) + zlog (NULL, LOG_ERR, "Can't raise privileges"); + if (sysctl (mib_ipv6, MIB_SIZ, &ip6forwarding, &len, 0, 0) < 0) { + if (zserv_privs.change(ZPRIVS_LOWER)) + zlog (NULL, LOG_ERR, "Can't lower privileges"); zlog_warn ("can't get ip6forwarding value"); return -1; } + if (zserv_privs.change(ZPRIVS_LOWER)) + zlog (NULL, LOG_ERR, "Can't lower privileges"); return ip6forwarding; } @@ -121,11 +142,17 @@ ipforward_ipv6_on () int ip6forwarding = 1; len = sizeof ip6forwarding; - if (sysctl (mib_ipv6, MIB_SIZ, NULL, NULL, &ip6forwarding, len) < 0) + if (zserv_privs.change(ZPRIVS_RAISE)) + zlog (NULL, LOG_ERR, "Can't raise privileges"); + if (sysctl (mib_ipv6, MIB_SIZ, NULL, NULL, &ip6forwarding, len) < 0) { + if (zserv_privs.change(ZPRIVS_LOWER)) + zlog (NULL, LOG_ERR, "Can't lower privileges"); zlog_warn ("can't get ip6forwarding value"); return -1; } + if (zserv_privs.change(ZPRIVS_LOWER)) + zlog (NULL, LOG_ERR, "Can't lower privileges"); return ip6forwarding; } @@ -136,11 +163,17 @@ ipforward_ipv6_off () int ip6forwarding = 0; len = sizeof ip6forwarding; - if (sysctl (mib_ipv6, MIB_SIZ, NULL, NULL, &ip6forwarding, len) < 0) + if (zserv_privs.change(ZPRIVS_RAISE)) + zlog (NULL, LOG_ERR, "Can't raise privileges"); + if (sysctl (mib_ipv6, MIB_SIZ, NULL, NULL, &ip6forwarding, len) < 0) { + if (zserv_privs.change(ZPRIVS_LOWER)) + zlog (NULL, LOG_ERR, "Can't lower privileges"); zlog_warn ("can't get ip6forwarding value"); return -1; } + if (zserv_privs.change(ZPRIVS_LOWER)) + zlog (NULL, LOG_ERR, "Can't lower privileges"); return ip6forwarding; } #endif /* HAVE_IPV6 */ diff --git a/zebra/kernel_socket.c b/zebra/kernel_socket.c index 17893a87..30e0fb1d 100644 --- a/zebra/kernel_socket.c +++ b/zebra/kernel_socket.c @@ -31,11 +31,14 @@ #include "str.h" #include "table.h" #include "rib.h" +#include "privs.h" #include "zebra/interface.h" #include "zebra/zserv.h" #include "zebra/debug.h" +extern struct zebra_privs_t zserv_privs; + /* Socket length roundup function. */ #define ROUNDUP(a) \ ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) @@ -798,16 +801,23 @@ kernel_read (struct thread *thread) void routing_socket () { + if ( zserv_privs.change (ZPRIVS_RAISE) ) + zlog_err ("routing_socket: Can't raise privileges"); + routing_sock = socket (AF_ROUTE, SOCK_RAW, 0); if (routing_sock < 0) { + if ( zserv_privs.change (ZPRIVS_LOWER) ) + zlog_err ("routing_socket: Can't lower privileges"); zlog_warn ("Can't init kernel routing socket"); return; } if (fcntl (routing_sock, F_SETFL, O_NONBLOCK) < 0) zlog_warn ("Can't set O_NONBLOCK to routing socket"); + if ( zserv_privs.change (ZPRIVS_LOWER) ) + zlog_err ("routing_socket: Can't lower privileges"); /* kernel_read needs rewrite. */ thread_add_read (master, kernel_read, NULL, routing_sock); diff --git a/zebra/main.c b/zebra/main.c index 66469a2f..72b1fc4e 100644 --- a/zebra/main.c +++ b/zebra/main.c @@ -1,5 +1,4 @@ -/* - * zebra daemon main routine. +/* zebra daemon main routine. * Copyright (C) 1997, 98 Kunihiro Ishiguro * * This file is part of GNU Zebra. @@ -30,6 +29,7 @@ #include "memory.h" #include "prefix.h" #include "log.h" +#include "privs.h" #include "zebra/rib.h" #include "zebra/zserv.h" @@ -62,10 +62,32 @@ struct option longopts[] = { "vty_addr", required_argument, NULL, 'A'}, { "vty_port", required_argument, NULL, 'P'}, { "retain", no_argument, NULL, 'r'}, + { "user", required_argument, NULL, 'u'}, { "version", no_argument, NULL, 'v'}, { 0 } }; +zebra_capabilities_t _caps_p [] = +{ + ZCAP_ADMIN, + ZCAP_SYS_ADMIN, +}; + +/* zebra privileges to run with */ +struct zebra_privs_t zserv_privs = +{ +#if defined(ZEBRA_USER) && defined(ZEBRA_GROUP) + .user = ZEBRA_USER, + .group = ZEBRA_GROUP, +#endif +#ifdef VTY_GROUP + .vty_group = VTY_GROUP, +#endif + .caps_p = _caps_p, + .cap_num_p = sizeof(_caps_p)/sizeof(_caps_p[0]), + .cap_num_i = 0 +}; + /* Default configuration file path. */ char config_current[] = DEFAULT_CONFIG_FILE; char config_default[] = SYSCONFDIR DEFAULT_CONFIG_FILE; @@ -93,6 +115,7 @@ redistribution between different routing protocols.\n\n\ -A, --vty_addr Set vty's bind address\n\ -P, --vty_port Set vty's port number\n\ -r, --retain When program terminates, retain added route by zebra.\n\ +-u, --user User and group to run as\n\ -v, --version Print program version\n\ -h, --help Display this help and exit\n\ \n\ @@ -196,7 +219,7 @@ main (int argc, char **argv) { int opt; - opt = getopt_long (argc, argv, "bdklf:hA:P:rv", longopts, 0); + opt = getopt_long (argc, argv, "bdklf:hA:P:ru:v", longopts, 0); if (opt == EOF) break; @@ -239,6 +262,9 @@ main (int argc, char **argv) case 'r': retain_mode = 1; break; + case 'u': + zserv_privs.user = zserv_privs.group = optarg; + break; case 'v': print_version (progname); exit (0); @@ -255,6 +281,9 @@ main (int argc, char **argv) /* Make master thread emulator. */ master = thread_master_create (); + /* privs initialise */ + zprivs_init (&zserv_privs); + /* Vty related initialize. */ signal_init (); cmd_init (1); diff --git a/zebra/rt_netlink.c b/zebra/rt_netlink.c index 87062dc5..e1514623 100644 --- a/zebra/rt_netlink.c +++ b/zebra/rt_netlink.c @@ -34,6 +34,7 @@ #include "table.h" #include "rib.h" #include "thread.h" +#include "privs.h" #include "zebra/zserv.h" #include "zebra/redistribute.h" @@ -67,6 +68,8 @@ struct message nlmsg_str[] = extern int rtm_table_default; +extern struct zebra_privs_t zserv_privs; + /* Make socket for Linux netlink interface. */ static int netlink_socket (struct nlsock *nl, unsigned long groups) @@ -98,14 +101,25 @@ netlink_socket (struct nlsock *nl, unsigned long groups) snl.nl_groups = groups; /* Bind the socket to the netlink structure for anything. */ + if ( zserv_privs.change(ZPRIVS_RAISE) ) + { + zlog (NULL, LOG_ERR, "Can't raise privileges"); + return -1; + } + ret = bind (sock, (struct sockaddr *) &snl, sizeof snl); if (ret < 0) { + if ( zserv_privs.change(ZPRIVS_LOWER) ) + zlog (NULL, LOG_ERR, "Can't lower privileges"); zlog (NULL, LOG_ERR, "Can't bind %s socket to group 0x%x: %s", nl->name, snl.nl_groups, strerror (errno)); close (sock); return -1; } + + if ( zserv_privs.change(ZPRIVS_LOWER) ) + zlog (NULL, LOG_ERR, "Can't lower privileges"); /* multiple netlink sockets will have different nl_pid */ namelen = sizeof snl; @@ -186,14 +200,28 @@ netlink_request (int family, int type, struct nlsock *nl) req.nlh.nlmsg_pid = 0; req.nlh.nlmsg_seq = ++nl->seq; req.g.rtgen_family = family; + + /* linux appears to check capabilities on every message + * have to raise caps for every message sent + */ + if ( zserv_privs.change(ZPRIVS_RAISE) ) + { + zlog (NULL, LOG_ERR, "Can't raise privileges"); + return -1; + } ret = sendto (nl->sock, (void*) &req, sizeof req, 0, (struct sockaddr*) &snl, sizeof snl); + + if ( zserv_privs.change(ZPRIVS_LOWER) ) + zlog (NULL, LOG_ERR, "Can't lower privileges"); + if (ret < 0) - { + { zlog (NULL, LOG_ERR, "%s sendto failed: %s", nl->name, strerror (errno)); return -1; } + return 0; } @@ -215,7 +243,13 @@ netlink_parse_info (int (*filter) (struct sockaddr_nl *, struct nlmsghdr *), struct msghdr msg = { (void*)&snl, sizeof snl, &iov, 1, NULL, 0, 0}; struct nlmsghdr *h; + if ( zserv_privs.change(ZPRIVS_RAISE) ) + zlog (NULL, LOG_ERR, "Can't raise privileges"); + status = recvmsg (nl->sock, &msg, 0); + + if ( zserv_privs.change(ZPRIVS_LOWER) ) + zlog (NULL, LOG_ERR, "Can't lower privileges"); if (status < 0) { @@ -1104,7 +1138,12 @@ netlink_talk (struct nlmsghdr *n, struct nlsock *nl) n->nlmsg_seq); /* Send message to netlink interface. */ + if ( zserv_privs.change(ZPRIVS_RAISE) ) + zlog (NULL, LOG_ERR, "Can't raise privileges"); status = sendmsg (nl->sock, &msg, 0); + if ( zserv_privs.change(ZPRIVS_LOWER) ) + zlog (NULL, LOG_ERR, "Can't lower privileges"); + if (status < 0) { zlog (NULL, LOG_ERR, "netlink_talk sendmsg() error: %s", diff --git a/zebra/rt_socket.c b/zebra/rt_socket.c index 19b2fc2f..d603c60d 100644 --- a/zebra/rt_socket.c +++ b/zebra/rt_socket.c @@ -27,10 +27,13 @@ #include "sockunion.h" #include "log.h" #include "str.h" +#include "privs.h" #include "zebra/debug.h" #include "zebra/rib.h" +extern struct zebra_privs_t zserv_privs; + int rtm_write (int message, union sockunion *dest, @@ -187,13 +190,29 @@ kernel_rtm_ipv4 (int cmd, struct prefix *p, struct rib *rib, int family) int kernel_add_ipv4 (struct prefix *p, struct rib *rib) { - return kernel_rtm_ipv4 (RTM_ADD, p, rib, AF_INET); + int route; + + if (zserv_privs.change(ZPRIVS_RAISE)) + zlog (NULL, LOG_ERR, "Can't raise privileges"); + route = kernel_rtm_ipv4 (RTM_ADD, p, rib, AF_INET); + if (zserv_privs.change(ZPRIVS_LOWER)) + zlog (NULL, LOG_ERR, "Can't lower privileges"); + + return route; } int kernel_delete_ipv4 (struct prefix *p, struct rib *rib) { - return kernel_rtm_ipv4 (RTM_DELETE, p, rib, AF_INET); + int route; + + if (zserv_privs.change(ZPRIVS_RAISE)) + zlog (NULL, LOG_ERR, "Can't raise privileges"); + route = kernel_rtm_ipv4 (RTM_DELETE, p, rib, AF_INET); + if (zserv_privs.change(ZPRIVS_LOWER)) + zlog (NULL, LOG_ERR, "Can't lower privileges"); + + return route; } #ifdef HAVE_IPV6 @@ -421,13 +440,29 @@ kernel_rtm_ipv6_multipath (int cmd, struct prefix *p, struct rib *rib, int kernel_add_ipv6 (struct prefix *p, struct rib *rib) { - return kernel_rtm_ipv6_multipath (RTM_ADD, p, rib, AF_INET6); + int route; + + if (zserv_privs.change(ZPRIVS_RAISE)) + zlog (NULL, LOG_ERR, "Can't raise privileges"); + route = kernel_rtm_ipv6_multipath (RTM_ADD, p, rib, AF_INET6); + if (zserv_privs.change(ZPRIVS_LOWER)) + zlog (NULL, LOG_ERR, "Can't lower privileges"); + + return route; } int kernel_delete_ipv6 (struct prefix *p, struct rib *rib) { - return kernel_rtm_ipv6_multipath (RTM_DELETE, p, rib, AF_INET6); + int route; + + if (zserv_privs.change(ZPRIVS_RAISE)) + zlog (NULL, LOG_ERR, "Can't raise privileges"); + route = kernel_rtm_ipv6_multipath (RTM_DELETE, p, rib, AF_INET6); + if (zserv_privs.change(ZPRIVS_LOWER)) + zlog (NULL, LOG_ERR, "Can't lower privileges"); + + return route; } /* Delete IPv6 route from the kernel. */ @@ -435,6 +470,14 @@ int kernel_delete_ipv6_old (struct prefix_ipv6 *dest, struct in6_addr *gate, int index, int flags, int table) { - return kernel_rtm_ipv6 (RTM_DELETE, dest, gate, index, flags); + int route; + + if (zserv_privs.change(ZPRIVS_RAISE)) + zlog (NULL, LOG_ERR, "Can't raise privileges"); + route = kernel_rtm_ipv6 (RTM_DELETE, dest, gate, index, flags); + if (zserv_privs.change(ZPRIVS_LOWER)) + zlog (NULL, LOG_ERR, "Can't lower privileges"); + + return route; } #endif /* HAVE_IPV6 */ diff --git a/zebra/rtadv.c b/zebra/rtadv.c index 8f4b3778..9dcee8ea 100644 --- a/zebra/rtadv.c +++ b/zebra/rtadv.c @@ -29,11 +29,14 @@ #include "prefix.h" #include "linklist.h" #include "command.h" +#include "privs.h" #include "zebra/interface.h" #include "zebra/rtadv.h" #include "zebra/debug.h" +extern struct zebra_privs_t zserv_privs; + #if defined (HAVE_IPV6) && defined (RTADV) /* If RFC2133 definition is used. */ @@ -143,7 +146,7 @@ rtadv_send_packet (int sock, struct interface *ifp) struct cmsghdr *cmsgptr; struct in6_pktinfo *pkt; struct sockaddr_in6 addr; -#if HAVE_SOCKADDR_DL +#ifdef HAVE_SOCKADDR_DL struct sockaddr_dl *sdl; #endif /* HAVE_SOCKADDR_DL */ char adata [sizeof (struct cmsghdr) + sizeof (struct in6_pktinfo)]; @@ -409,8 +412,16 @@ rtadv_make_socket (void) int ret; struct icmp6_filter filter; + if ( zserv_privs.change (ZPRIVS_RAISE) ) + zlog_err ("rtadv_make_socket: could not raise privs, %s", + strerror (errno) ); + sock = socket (AF_INET6, SOCK_RAW, IPPROTO_ICMPV6); + if ( zserv_privs.change (ZPRIVS_LOWER) ) + zlog_err ("rtadv_make_socket: could not lower privs, %s", + strerror (errno) ); + /* When we can't make ICMPV6 socket simply back. Router advertisement feature will not be supported. */ if (sock < 0) diff --git a/zebra/zserv.c b/zebra/zserv.c index 70e7672d..975574af 100644 --- a/zebra/zserv.c +++ b/zebra/zserv.c @@ -33,6 +33,7 @@ #include "sockunion.h" #include "log.h" #include "zclient.h" +#include "privs.h" #include "zebra/zserv.h" #include "zebra/redistribute.h" @@ -50,6 +51,8 @@ int rtm_table_default = 0; void zebra_event (enum event event, int sock, struct zserv *client); +extern struct zebra_privs_t zserv_privs; + extern struct thread_master *master; /* For logging of zebra meesages. */ @@ -1638,6 +1641,9 @@ zebra_serv () sockopt_reuseaddr (accept_sock); sockopt_reuseport (accept_sock); + if ( zserv_privs.change(ZPRIVS_RAISE) ) + zlog (NULL, LOG_ERR, "Can't raise privileges"); + ret = bind (accept_sock, (struct sockaddr *)&addr, sizeof (struct sockaddr_in)); if (ret < 0) @@ -1647,6 +1653,9 @@ zebra_serv () close (accept_sock); /* Avoid sd leak. */ return; } + + if ( zserv_privs.change(ZPRIVS_LOWER) ) + zlog (NULL, LOG_ERR, "Can't lower privileges"); ret = listen (accept_sock, 1); if (ret < 0) -- cgit v1.2.1