summaryrefslogtreecommitdiff
path: root/zebra
diff options
context:
space:
mode:
authorpaul <paul>2003-06-04 13:59:38 +0000
committerpaul <paul>2003-06-04 13:59:38 +0000
commitedd7c245d3a77012abf801da00d5664ebaa5f749 (patch)
treed4fada229d7980fb751f28c9a979aa88de1a0af0 /zebra
parenta159ed935b580ed99111a185734ddd9c973e7691 (diff)
2003-06-04 Paul Jakma <paul@dishone.st>
* Merge of zebra privileges
Diffstat (limited to 'zebra')
-rw-r--r--zebra/Makefile.am7
-rw-r--r--zebra/ioctl.c17
-rw-r--r--zebra/ipforward_proc.c32
-rw-r--r--zebra/ipforward_solaris.c58
-rw-r--r--zebra/ipforward_sysctl.c43
-rw-r--r--zebra/kernel_socket.c10
-rw-r--r--zebra/main.c35
-rw-r--r--zebra/rt_netlink.c41
-rw-r--r--zebra/rt_socket.c53
-rw-r--r--zebra/rtadv.c13
-rw-r--r--zebra/zserv.c9
11 files changed, 280 insertions, 38 deletions
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 <zebra.h>
+#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 <zebra.h>
#include "log.h"
+#include "prefix.h"
/*
** Solaris should define IP_DEV_NAME in <inet/ip.h>, 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 <zebra.h>
+#include "privs.h"
#ifdef NRL
#include <netinet6/in6.h>
@@ -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)