]> git.proxmox.com Git - mirror_frr.git/commitdiff
2003-06-04 Paul Jakma <paul@dishone.st>
authorpaul <paul>
Wed, 4 Jun 2003 13:59:38 +0000 (13:59 +0000)
committerpaul <paul>
Wed, 4 Jun 2003 13:59:38 +0000 (13:59 +0000)
* Merge of zebra privileges

37 files changed:
bgpd/Makefile.am
bgpd/bgp_main.c
bgpd/bgp_network.c
configure.ac
lib/Makefile.am
lib/memory.h
lib/vty.c
lib/zebra.h
ospf6d/Makefile.am
ospf6d/ospf6_main.c
ospf6d/ospf6_network.c
ospfclient/Makefile.am
ospfclient/ospfclient.c
ospfd/Makefile.am
ospfd/ospf_main.c
ospfd/ospf_network.c
ospfd/ospfd.c
redhat/zebra.pam
redhat/zebra.spec.in
ripd/Makefile.am
ripd/rip_interface.c
ripd/rip_main.c
ripd/ripd.c
ripngd/Makefile.am
ripngd/ripng_main.c
vtysh/Makefile.am
zebra/Makefile.am
zebra/ioctl.c
zebra/ipforward_proc.c
zebra/ipforward_solaris.c
zebra/ipforward_sysctl.c
zebra/kernel_socket.c
zebra/main.c
zebra/rt_netlink.c
zebra/rt_socket.c
zebra/rtadv.c
zebra/zserv.c

index 7f739f6e3f558c0a8f5db2d8fdd052b2f53ee19a..0e549cc06953fed24d3b2e9ab53e7ed0e297aa97 100644 (file)
@@ -24,7 +24,7 @@ noinst_HEADERS = \
 bgpd_SOURCES = \
        bgp_main.c $(libbgp_a_SOURCES)
 
-bgpd_LDADD = ../lib/libzebra.a
+bgpd_LDADD = ../lib/libzebra.a @LIBCAP@
 
 sysconf_DATA = bgpd.conf.sample bgpd.conf.sample2
 
index 703779147024831cec7e445c2f8cf7e13539351e..3e1d80f69bf6347ea94a7eb026fd9f35260d1ff1 100644 (file)
@@ -29,6 +29,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 #include "memory.h"
 #include "prefix.h"
 #include "log.h"
+#include "privs.h"
 
 #include "bgpd/bgpd.h"
 #include "bgpd/bgp_attr.h"
@@ -45,6 +46,7 @@ struct option longopts[] =
   { "vty_port",    required_argument, NULL, 'P'},
   { "retain",      no_argument,       NULL, 'r'},
   { "no_kernel",   no_argument,       NULL, 'n'},
+  { "user",        required_argument, NULL, 'u'},
   { "version",     no_argument,       NULL, 'v'},
   { "help",        no_argument,       NULL, 'h'},
   { 0 }
@@ -70,6 +72,23 @@ char *pid_file = PATH_BGPD_PID;
 int vty_port = BGP_VTY_PORT;
 char *vty_addr = NULL;
 
+/* privileges */
+zebra_capabilities_t _caps_p [] =  
+{
+    ZCAP_BIND,
+};
+
+struct zebra_privs_t bgpd_privs =
+{
+#if defined(ZEBRA_USER) && defined(ZEBRA_GROUP)
+  .user = ZEBRA_USER,
+  .group = ZEBRA_GROUP,
+#endif
+  .caps_p = _caps_p,
+  .cap_num_p = sizeof(_caps_p)/sizeof(_caps_p[0]),
+  .cap_num_i = 0,
+};
+
 /* Help information display. */
 static void
 usage (char *progname, int status)
@@ -89,6 +108,7 @@ redistribution between different routing protocols.\n\n\
 -P, --vty_port     Set vty's port number\n\
 -r, --retain       When program terminates, retain added route by bgpd.\n\
 -n, --no_kernel    Do not install route to kernel.\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\
@@ -197,7 +217,7 @@ main (int argc, char **argv)
   /* Command line argument treatment. */
   while (1) 
     {
-      opt = getopt_long (argc, argv, "df:hp:A:P:rnv", longopts, 0);
+      opt = getopt_long (argc, argv, "df:hp:A:P:rnu:v", longopts, 0);
     
       if (opt == EOF)
        break;
@@ -238,6 +258,9 @@ main (int argc, char **argv)
        case 'n':
          bgp_option_set (BGP_OPT_NO_FIB);
          break;
+  case 'u':
+    bgpd_privs.user = bgpd_privs.group = optarg;
+    break;
        case 'v':
          print_version (progname);
          exit (0);
@@ -257,6 +280,7 @@ main (int argc, char **argv)
   /* Initializations. */
   srand (time (NULL));
   signal_init ();
+  zprivs_init (&bgpd_privs);
   cmd_init (1);
   vty_init ();
   memory_init ();
index 40e9cdb34bd810312e9dfeebe2cc34f3b2ab7bee..019b78b7c3103c00e77953d9c4cd302ffed95e99 100644 (file)
@@ -27,12 +27,16 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 #include "if.h"
 #include "prefix.h"
 #include "command.h"
+#include "privs.h"
 
 #include "bgpd/bgpd.h"
 #include "bgpd/bgp_fsm.h"
 #include "bgpd/bgp_attr.h"
 #include "bgpd/bgp_debug.h"
 #include "bgpd/bgp_network.h"
+
+extern struct zebra_privs_t bgpd_privs;
+
 \f
 /* Accept bgp connection. */
 static int
@@ -153,9 +157,16 @@ bgp_bind_address (int sock, struct in_addr *addr)
 #endif /* HAVE_SIN_LEN */
   memcpy (&local.sin_addr, addr, sizeof (struct in_addr));
 
+  if ( bgpd_privs.change (ZPRIVS_RAISE) )
+    zlog_err ("bgp_bind_address: could not raise privs");
+    
   ret = bind (sock, (struct sockaddr *)&local, sizeof (struct sockaddr_in));
   if (ret < 0)
     ;
+    
+  if (bgpd_privs.change (ZPRIVS_LOWER) )
+    zlog_err ("bgp_bind_address: could not lower privs");
+    
   return 0;
 }
 
@@ -306,6 +317,9 @@ bgp_socket (struct bgp *bgp, unsigned short port)
 
       sockopt_reuseaddr (sock);
       sockopt_reuseport (sock);
+      
+      if (bgpd_privs.change (ZPRIVS_RAISE) )
+        zlog_err ("bgp_socket: could not raise privs");
 
       ret = bind (sock, ainfo->ai_addr, ainfo->ai_addrlen);
       if (ret < 0)
@@ -314,6 +328,10 @@ bgp_socket (struct bgp *bgp, unsigned short port)
          close (sock);
          continue;
        }
+      
+      if (bgpd_privs.change (ZPRIVS_LOWER) )
+        zlog_err ("bgp_bind_address: could not lower privs");
+        
       ret = listen (sock, 3);
       if (ret < 0) 
        {
@@ -359,6 +377,9 @@ bgp_socket (struct bgp *bgp, unsigned short port)
   sin.sin_len = socklen;
 #endif /* HAVE_SIN_LEN */
 
+  if ( bgpd_privs.change (ZPRIVS_RAISE) )
+    zlog_err ("bgp_socket: could not raise privs");
+
   ret = bind (sock, (struct sockaddr *) &sin, socklen);
   if (ret < 0)
     {
@@ -366,6 +387,10 @@ bgp_socket (struct bgp *bgp, unsigned short port)
       close (sock);
       return ret;
     }
+  
+  if (bgpd_privs.change (ZPRIVS_LOWER) )
+    zlog_err ("bgp_socket: could not lower privs");
+    
   ret = listen (sock, 3);
   if (ret < 0) 
     {
index ad58c3a81973c5b1f147934321f09781df544e3c..290d8331961eba537aaee99c7c5997a33b63ad41 100755 (executable)
@@ -98,8 +98,15 @@ AC_ARG_ENABLE(ospf-te,
 [  --enable-ospf-te        enable Traffic Engineering Extension to OSPF])
 AC_ARG_ENABLE(multipath,
 [  --enable-multipath=ARG  enable multipath function, ARG must be digit])
+AC_ARG_ENABLE(zebra_user,
+[  --enable-user=ARG       user to run zebra suite as (default zebra)])
+AC_ARG_ENABLE(zebra_group,
+[  --enable-group=ARG      group to run zebra suite as (default zebra)])
+AC_ARG_ENABLE(vty_group,
+[  --enable-vty-group=ARG      set vty sockets to have specified group as owner])
+
 AC_ARG_ENABLE(rtadv,
-[  --enable-rtadv         enable IPV6 router advertisment feature])
+[  --enable-rtadv         enable IPV6 router advertisement feature])
 
 if test "${enable_broken_aliases}" = "yes"; then
   if test "${enable_netlink}" = "yes"
@@ -136,6 +143,32 @@ else
   AC_MSG_RESULT(no)
 fi
 
+if test "${enable_user}" = "yes" ; then
+  enable_user="zebra"
+elif test "${enable_user}" = "no"; then
+  enable_user="root"
+fi
+AC_DEFINE_UNQUOTED(ZEBRA_USER, "${enable_user}", Zebra User)
+
+if test "${enable_group}" = "yes" ; then
+  enable_group="zebra"
+elif test "${enable_group}" = "no"; then
+  enable_group="root"
+fi
+AC_DEFINE_UNQUOTED(ZEBRA_GROUP, "${enable_group}", Zebra Group)
+
+if test x"${enable_vty_group}" = x"yes" ; then
+  AC_MSG_ERROR([--enable-vty-group requires a group as argument])
+fi
+if test "${enable_vty_group}" = ""; then
+  AC_MSG_ERROR([--enable-vty-group requires a group as argument])
+fi
+if test x"${enable_vty_group}" != x"no"; then
+  if test "${enable_vty_group}" != ""; then
+    AC_DEFINE_UNQUOTED(VTY_GROUP, "${enable_vty_group}", VTY Sockets Group)
+  fi
+fi
+
 changequote(, )dnl
 
 MULTIPATH_NUM=1
@@ -864,6 +897,28 @@ AC_TRY_COMPILE([#include <sys/resource.h>
  AC_DEFINE(HAVE_RUSAGE,,rusage)],
  AC_MSG_RESULT(no))
 
+dnl -------------------
+dnl capabilities checks
+dnl -------------------
+AC_MSG_CHECKING(whether prctl PR_SET_KEEPCAPS is available)
+AC_TRY_COMPILE([#include <sys/prctl.h>],[prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0);],
+  [AC_MSG_RESULT(yes)
+   AC_DEFINE(HAVE_PR_SET_KEEPCAPS,,prctl)
+   zebra_ac_keepcaps="yes"],
+   AC_MSG_RESULT(no)
+)
+if test x"${zebra_ac_keepcaps}" = x"yes"; then
+  AC_CHECK_HEADERS(sys/capability.h)
+fi
+if test x"${ac_cv_header_sys_capability_h}" = x"yes"; then
+  AC_CHECK_LIB(cap, cap_init, 
+    [AC_DEFINE(HAVE_LCAPS,1,Capabilities)
+     LIBCAP="-lcap"
+    ]
+  )
+fi
+AC_SUBST(LIBCAP)
+
 dnl ---------------------------
 dnl check for glibc 'backtrace'
 dnl --------------------------- 
@@ -968,5 +1023,4 @@ compiler                : ${CC}
 compiler flags          : ${CFLAGS}
 linker flags            : ${LDFLAGS} ${LIBS}
 state file directory    : ${zebra_statedir}
-linker flags            : ${LDFLAGS} ${LIBS}
 "
index 026806035b69800e5218f903baf29829f590d61d..d041770d89bad0795b5c281dd83f5b6717bda6ee 100644 (file)
@@ -10,9 +10,9 @@ libzebra_a_SOURCES = \
        print_version.c checksum.c vector.c linklist.c vty.c command.c \
        sockunion.c prefix.c thread.c if.c memory.c buffer.c table.c hash.c \
        filter.c routemap.c distribute.c stream.c str.c log.c plist.c \
-       zclient.c sockopt.c smux.c md5.c if_rmap.c keychain.c
+       zclient.c sockopt.c smux.c md5.c if_rmap.c keychain.c privs.c debug.c
 
-libzebra_a_DEPENDENCIES = @LIB_REGEX@
+libzebra_a_DEPENDENCIES = @LIB_REGEX@ @LIBCAP@
 
 libzebra_a_LIBADD = @LIB_REGEX@
 
@@ -20,7 +20,8 @@ noinst_HEADERS = \
        buffer.h command.h filter.h getopt.h hash.h if.h linklist.h log.h \
        memory.h network.h prefix.h routemap.h distribute.h sockunion.h \
        str.h stream.h table.h thread.h vector.h version.h vty.h zebra.h \
-       plist.h zclient.h sockopt.h smux.h md5-gnu.h if_rmap.h keychain.h
+       plist.h zclient.h sockopt.h smux.h md5-gnu.h if_rmap.h keychain.h \
+       privs.h debug.h
 
 EXTRA_DIST = regex.c regex-gnu.h
 
index a38cda3f3d3f487066335813b352f51212f24c4d..925f6b655c5dd71ea4376877e4360c4d5d1b284c 100644 (file)
@@ -189,6 +189,8 @@ enum
 
   MTYPE_VRF,
   MTYPE_VRF_NAME,
+  
+  MTYPE_PRIVS,
 
   MTYPE_MAX
 };
index 5ef364a08097f8d5d4d845f1ae88db1ac8acbbab..4d6eb3048e1fdea732a7328ab3d4fd0a3fe56455 100644 (file)
--- a/lib/vty.c
+++ b/lib/vty.c
@@ -33,6 +33,7 @@
 #include "log.h"
 #include "prefix.h"
 #include "filter.h"
+#include "privs.h"
 
 /* Vty events */
 enum event 
@@ -1851,7 +1852,8 @@ vty_serv_un (char *path)
   int sock, len;
   struct sockaddr_un serv;
   mode_t old_mask;
-
+  struct zprivs_ids_t ids;
+  
   /* First of all, unlink existing socket */
   unlink (path);
 
@@ -1894,6 +1896,18 @@ vty_serv_un (char *path)
 
   umask (old_mask);
 
+  zprivs_get_ids(&ids);
+  
+  if (ids.gid_vty > 0)
+    {
+      /* set group of socket */
+      if ( chown (path, -1, ids.gid_vty) )
+        {
+          zlog_err ("vty_serv_un: could chown socket, %s",
+                     strerror (errno) );
+        }
+    }
+
   vty_event (VTYSH_SERV, sock, NULL);
 }
 
index 62566cf86c4a3c5d5bdff531825bf0dc61a1bea1..15608dbcd87ff1a9caf5626284ab90606451b89c 100644 (file)
@@ -42,6 +42,8 @@ typedef int socklen_t;
 #include <fcntl.h>
 #include <signal.h>
 #include <string.h>
+#include <pwd.h>
+#include <grp.h>
 #ifdef HAVE_STROPTS_H
 #include <stropts.h>
 #endif /* HAVE_STROPTS_H */
@@ -70,6 +72,10 @@ typedef int socklen_t;
 #ifdef HAVE_RUSAGE
 #include <sys/resource.h>
 #endif /* HAVE_RUSAGE */
+#ifdef HAVE_LCAPS
+#include <sys/capability.h>
+#include <sys/prctl.h>
+#endif /* HAVE_LCAPS */
 
 /* machine dependent includes */
 #ifdef SUNOS_5
index 680e89b8f729ee558938be2c6dc4a3f9e0e443c3..e42814affbc3d26d665f824f9e870c4a12584d79 100644 (file)
@@ -28,7 +28,7 @@ noinst_HEADERS = \
 ospf6d_SOURCES = \
        ospf6_main.c $(libospf6_a_SOURCES)
 
-ospf6d_LDADD = -L../lib -lzebra
+ospf6d_LDADD = -L../lib -lzebra @LIBCAP@
 
 sysconf_DATA = ospf6d.conf.sample
 
index 10203bf854d02d0d32702c0450f08f175c0d3f5d..e6cd6aaae62dc1dddcb63ff774696b09921775ed 100644 (file)
@@ -27,6 +27,7 @@
 #include "command.h"
 #include "vty.h"
 #include "memory.h"
+#include "privs.h"
 
 #include "ospf6d.h"
 #include "ospf6_network.h"
@@ -43,6 +44,26 @@ extern int ospf6_sock;
 /* Default port values. */
 #define OSPF6_VTY_PORT             2606
 
+/* ospf6d privileges */
+zebra_capabilities_t _caps_p [] = 
+{
+  ZCAP_RAW,
+  ZCAP_BIND
+};
+
+struct zebra_privs_t ospf6d_privs =
+{
+#if defined(ZEBRA_USER)
+  .user = ZEBRA_USER,
+#endif
+#if defined ZEBRA_GROUP
+  .group = ZEBRA_GROUP,
+#endif
+  .caps_p = _caps_p,
+  .cap_num_p = 2,
+  .cap_num_i = 0
+};
+
 /* ospf6d options, we use GNU getopt library. */
 struct option longopts[] = 
 {
@@ -51,6 +72,7 @@ struct option longopts[] =
   { "pid_file",    required_argument, NULL, 'i'},
   { "vty_addr",    required_argument, NULL, 'A'},
   { "vty_port",    required_argument, NULL, 'P'},
+  { "user",        required_argument, NULL, 'u'},
   { "version",     no_argument,       NULL, 'v'},
   { "help",        no_argument,       NULL, 'h'},
   { 0 }
@@ -93,6 +115,7 @@ Daemon which manages OSPF version 3.\n\n\
 -i, --pid_file     Set process identifier file name\n\
 -A, --vty_addr     Set vty's bind address\n\
 -P, --vty_port     Set vty's port number\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\
@@ -231,7 +254,7 @@ main (int argc, char *argv[], char *envp[])
   /* Command line argument treatment. */
   while (1) 
     {
-      opt = getopt_long (argc, argv, "df:hp:A:P:v", longopts, 0);
+      opt = getopt_long (argc, argv, "df:hp:A:P:u:v", longopts, 0);
     
       if (opt == EOF)
         break;
@@ -263,6 +286,9 @@ main (int argc, char *argv[], char *envp[])
           vty_port = atoi (optarg);
           vty_port = (vty_port ? vty_port : OSPF6_VTY_PORT);
          break;
+        case 'u':
+          ospf6d_privs.user = ospf6d_privs.group = optarg;
+          break;
         case 'v':
           print_version (progname);
           exit (0);
@@ -288,6 +314,7 @@ main (int argc, char *argv[], char *envp[])
   zlog_default = openzlog (progname, flag, ZLOG_OSPF6,
                           LOG_CONS|LOG_NDELAY|LOG_PID,
                           LOG_DAEMON);
+       zprivs_init (&ospf6d_privs);
   signal_init ();
   cmd_init (1);
   vty_init ();
index e90614e59c825d3dba07f86b208e096102da3b3a..ece34135a0fa296fa813e19b6e9d06a168782809 100644 (file)
@@ -23,6 +23,7 @@
 #include "memory.h"
 #include "log.h"
 #include "sockunion.h"
+#include "privs.h"
 
 #include "ospf6d.h"
 #include "ospf6_proto.h"
@@ -32,6 +33,7 @@ extern struct sockaddr_in6 allspfrouters6;
 extern struct sockaddr_in6 alldrouters6;
 extern int ospf6_sock;
 extern struct thread_master *master;
+extern struct zebra_privs_t ospf6d_privs;
 
 /* iovec functions */
 void
@@ -194,6 +196,10 @@ iov_copy_all (struct iovec *dst, struct iovec *src, size_t size)
 int
 ospf6_serv_sock ()
 {
+
+  if (ospf6d_privs.change (ZPRIVS_RAISE))
+      zlog_err ("ospf6_serv_sock: could not raise privs");
+      
   ospf6_sock = socket (AF_INET6, SOCK_RAW, IPPROTO_OSPFIGP);
   if (ospf6_sock < 0)
     {
@@ -202,6 +208,9 @@ ospf6_serv_sock ()
     }
   sockopt_reuseaddr (ospf6_sock);
 
+  if (ospf6d_privs.change (ZPRIVS_LOWER))
+      zlog_err ("ospf_sock_init: could not lower privs");
+  
   /* setup global sockaddr_in6, allspf6 & alldr6 for later use */
   allspfrouters6.sin6_family = AF_INET6;
   alldrouters6.sin6_family = AF_INET6;
index 95a74eec385d2906b36b9d227a83f578fd9bf92f..fb041af92553cdc625db94aaf95cbd88c031a9f5 100644 (file)
@@ -16,6 +16,6 @@ ospfapiheader_HEADERS = \
 ospfclient_SOURCES = \
        ospfclient.c $(libospfapiclient_a_SOURCES)
 
-ospfclient_LDADD = ../ospfd/libospf.a ../lib/libzebra.a
+ospfclient_LDADD = ../ospfd/libospf.a ../lib/libzebra.a @LIBCAP@
 
 
index ec1aabcbff29958c1609f4d33065af282824a833..2801087217eccaeea57483dd6ed97e5c9ddffce9 100644 (file)
@@ -11,6 +11,8 @@
 
 #include <zebra.h>
 #include "prefix.h" /* needed by ospf_asbr.h */
+#include "privs.h"
+
 #include "ospfd/ospfd.h"
 #include "ospfd/ospf_asbr.h"
 #include "ospfd/ospf_lsa.h"
 #include "ospfd/ospf_api.h"
 #include "ospf_apiclient.h"
 
+/* privileges struct. 
+ * set cap_num_* and uid/gid to nothing to use NULL privs
+ * as ospfapiclient links in libospf.a which uses privs.
+ */
+struct zebra_privs_t ospfd_privs =
+{
+  .user = NULL,
+  .group = NULL,
+  .cap_num_p = 0,
+  .cap_num_i = 0
+};
+
 /* The following includes are specific to this application. For
    example it uses threads from libzebra, however your application is
    free to use any thread library (like pthreads). */
@@ -274,6 +288,7 @@ main (int argc, char *argv[])
     }
 
   /* Initialization */
+  zprivs_init (&ospfd_privs);
   master = thread_master_create ();
 
   /* Open connection to OSPF daemon */
index 81315daed675446e54b28c9a720c93f52e9ae181..81f212c46d3eb09379a5d1815cad76796f1197b9 100644 (file)
@@ -28,7 +28,7 @@ noinst_HEADERS = \
 ospfd_SOURCES = \
        ospf_main.c $(libospf_a_SOURCES)
 
-ospfd_LDADD = -L../lib -lzebra
+ospfd_LDADD = -L../lib -lzebra @LIBCAP@
 
 sysconf_DATA = ospfd.conf.sample
 
index 0ac82a68463c9fd53bd25b3f7400516b90e0afa7..b1d1fd4caa4b400862b11b782ac8b161cca18e04 100644 (file)
@@ -36,6 +36,8 @@
 #include "stream.h"
 #include "log.h"
 #include "memory.h"
+#include "privs.h"
+#include "debug.h"
 
 #include "ospfd/ospfd.h"
 #include "ospfd/ospf_interface.h"
 #include "ospfd/ospf_zebra.h"
 #include "ospfd/ospf_vty.h"
 
+/* ospfd privileges */
+zebra_capabilities_t _caps_p [] = 
+{
+  ZCAP_RAW,
+  ZCAP_BIND,
+  ZCAP_BROADCAST,
+  ZCAP_ADMIN,
+};
+
+struct zebra_privs_t ospfd_privs =
+{
+#if defined(ZEBRA_USER) && defined(ZEBRA_GROUP)
+  .user = ZEBRA_USER,
+  .group = ZEBRA_GROUP,
+#endif
+#if defined(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
+};
+
 /* Configuration filename and directory. */
 char config_current[] = OSPF_DEFAULT_CONFIG;
 char config_default[] = SYSCONFDIR OSPF_DEFAULT_CONFIG;
@@ -61,6 +86,7 @@ struct option longopts[] =
   { "help",        no_argument,       NULL, 'h'},
   { "vty_addr",    required_argument, NULL, 'A'},
   { "vty_port",    required_argument, NULL, 'P'},
+  { "user",        required_argument, NULL, 'u'},
   { "version",     no_argument,       NULL, 'v'},
   { 0 }
 };
@@ -88,6 +114,7 @@ Daemon which manages OSPF.\n\n\
 -i, --pid_file     Set process identifier file name\n\
 -A, --vty_addr     Set vty's bind address\n\
 -P, --vty_port     Set vty's port number\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\
@@ -162,6 +189,11 @@ signal_init ()
   signal_set (SIGTTOU, SIG_IGN);
 #endif
   signal_set (SIGUSR1, sigusr1);
+#ifdef HAVE_GLIBC_BACKTRACE
+  signal_set (SIGBUS, debug_print_trace);
+  signal_set (SIGSEGV, debug_print_trace);
+  signal_set (SIGILL, debug_print_trace); 
+#endif /* HAVE_GLIBC_BACKTRACE */
 }
 \f
 /* OSPFd main routine. */
@@ -200,7 +232,7 @@ main (int argc, char **argv)
     {
       int opt;
 
-      opt = getopt_long (argc, argv, "dlf:hA:P:v", longopts, 0);
+      opt = getopt_long (argc, argv, "dlf:hA:P:u:v", longopts, 0);
     
       if (opt == EOF)
        break;
@@ -232,6 +264,9 @@ main (int argc, char **argv)
           vty_port = atoi (optarg);
           vty_port = (vty_port ? vty_port : OSPF_VTY_PORT);
          break;
+  case 'u':
+    ospfd_privs.group = ospfd_privs.user = optarg;
+    break;
        case 'v':
          print_version (progname);
          exit (0);
@@ -249,6 +284,7 @@ main (int argc, char **argv)
   master = om->master;
 
   /* Library inits. */
+  zprivs_init (&ospfd_privs);
   signal_init ();
   cmd_init (1);
   debug_init ();
index 56ec8647836d0c4196a39d09bf6caef244c95e68..87aec1e5c98f61e42a99c7b8e53291f6df9dc85c 100644 (file)
@@ -29,6 +29,9 @@
 #include "sockunion.h"
 #include "log.h"
 #include "sockopt.h"
+#include "privs.h"
+
+extern struct zebra_privs_t ospfd_privs;
 
 #include "ospfd/ospfd.h"
 #include "ospfd/ospf_network.h"
@@ -39,6 +42,8 @@
 #include "ospfd/ospf_neighbor.h"
 #include "ospfd/ospf_packet.h"
 
+
+
 /* Join to the OSPF ALL SPF ROUTERS multicast group. */
 int
 ospf_if_add_allspfrouters (struct ospf *top, struct prefix *p,
@@ -151,12 +156,20 @@ ospf_sock_init (void)
   int ospf_sock;
   int ret, tos, hincl = 1;
 
+  if ( ospfd_privs.change (ZPRIVS_RAISE) )
+    zlog_err ("ospf_sock_init: could not raise privs, %s",
+               strerror (errno) );
+    
   ospf_sock = socket (AF_INET, SOCK_RAW, IPPROTO_OSPFIGP);
   if (ospf_sock < 0)
     {
+      if ( ospfd_privs.change (ZPRIVS_LOWER) )
+        zlog_err ("ospf_sock_init: could not lower privs, %s",
+                   strerror (errno) );
       zlog_warn ("ospf_read_sock_init: socket: %s", strerror (errno));
       return -1;
     }
+    
 
   /* Set precedence field. */
 #ifdef IPTOS_PREC_INTERNETCONTROL
@@ -165,6 +178,9 @@ ospf_sock_init (void)
                    (char *) &tos, sizeof (int));
   if (ret < 0)
     {
+      if ( ospfd_privs.change (ZPRIVS_LOWER) )
+        zlog_err ("ospf_sock_init: could not lower privs, %s",
+                   strerror (errno) );
       zlog_warn ("can't set sockopt IP_TOS %d to socket %d", tos, ospf_sock);
       close (ospf_sock);       /* Prevent sd leak. */
       return ret;
@@ -174,19 +190,40 @@ ospf_sock_init (void)
   /* we will include IP header with packet */
   ret = setsockopt (ospf_sock, IPPROTO_IP, IP_HDRINCL, &hincl, sizeof (hincl));
   if (ret < 0)
-    zlog_warn ("Can't set IP_HDRINCL option");
+    {
+      if ( ospfd_privs.change (ZPRIVS_LOWER) )
+        zlog_err ("ospf_sock_init: could not lower privs, %s",
+                   strerror (errno) );
+      zlog_warn ("Can't set IP_HDRINCL option");
+    }
 
 #if defined (IP_PKTINFO)
   ret = setsockopt (ospf_sock, IPPROTO_IP, IP_PKTINFO, &hincl, sizeof (hincl));
    if (ret < 0)
-    zlog_warn ("Can't set IP_PKTINFO option");
+     {
+       if ( ospfd_privs.change (ZPRIVS_LOWER) )
+         zlog_err ("ospf_sock_init: could not lower privs, %s",
+                   strerror (errno) );
+       zlog_warn ("Can't set IP_PKTINFO option");
+     }
 #elif defined (IP_RECVIF)
   ret = setsockopt (ospf_sock, IPPROTO_IP, IP_RECVIF, &hincl, sizeof (hincl));
    if (ret < 0)
-    zlog_warn ("Can't set IP_RECVIF option");
+     {
+       if ( ospfd_privs.change (ZPRIVS_LOWER) )
+         zlog_err ("ospf_sock_init: could not lower privs, %s",
+                   strerror (errno) );
+       zlog_warn ("Can't set IP_RECVIF option");
+     }
 #else
 #warning "cannot be able to receive link information on this OS"
 #endif
+
+  if (ospfd_privs.change (ZPRIVS_LOWER))
+    {
+      zlog_err ("ospf_sock_init: could not lower privs, %s",
+               strerror (errno) );
+    }
  
   return ospf_sock;
 }
index d8646f07b445fc402b786bd21eb301cfb668db63..a12a011527514c2e83279166e7ed27af0f57d91c 100644 (file)
@@ -53,6 +53,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
 #include "ospfd/ospf_ase.h"
 
 \f
+
 /* OSPF process wide configuration. */
 static struct ospf_master ospf_master;
 
index fb17f59e0e439b26609008b1e12fc16009a0d5c6..1390edf4a327d9032bb032dcf9584dd3bed16bde 100644 (file)
@@ -1,10 +1,26 @@
 #%PAM-1.0
 #
+
+##### if running zebra as root:
 # Only allow root (and possibly wheel) to use this because enable access
 # is unrestricted.
+# auth       sufficient   /lib/security/pam_rootok.so
 
-auth       sufficient   /lib/security/pam_rootok.so
 # Uncomment the following line to implicitly trust users in the "wheel" group.
 #auth       sufficient   /lib/security/pam_wheel.so trust use_uid
 # Uncomment the following line to require a user to be in the "wheel" group.
 #auth       required     /lib/security/pam_wheel.so use_uid
+###########################################################
+
+# If using zebra privileges and with a seperate group for vty access, then
+# access can be controlled via the vty access group, and pam can simply
+# check for valid user/password
+#
+# only allow local users.
+auth       required     /lib/security/pam_securetty.so
+auth       required     /lib/security/pam_stack.so service=system-auth
+auth       required     /lib/security/pam_nologin.so
+account    required     /lib/security/pam_stack.so service=system-auth
+password   required     /lib/security/pam_stack.so service=system-auth
+session    required     /lib/security/pam_stack.so service=system-auth
+session    optional     /lib/security/pam_console.so
index ce3a6fb43ad30b40f99e6cc9d622c41e133735c1..85b3b318d58756716135bdb2c5c6a42507bf50b5 100644 (file)
@@ -1,4 +1,4 @@
-# conditionals
+# configure options
 %define        with_snmp       0
 %define                with_vtysh      1
 %define                with_ospf_te    1
@@ -11,6 +11,8 @@
 %define                with_ospfclient 1
 %define                with_ospfapi    1
 %define                with_multipath  64
+%define                zebra_user      zebra
+%define                vty_group       zebravty
 
 # path defines
 %define                _sysconfdir     /etc/zebra
 %define                _libexecdir     %{_exec_prefix}/libexec/zebra
 %define                _includedir     %{_prefix}/include/zebra
 %define                _libdir         %{_exec_prefix}/%{_lib}/zebra
-%define                _localstatedir  %{_prefix}/var/run
+%define                _localstatedir  /var/run/zebra
 
 Summary: Routing daemon
 Name:          zebra
 Version:       @VERSION@
-Release:       @CONFDATE@
+Release:       @CONFDATE@01
 License:       GPL
 Group: System Environment/Daemons
 Source0:       ftp://ftp.zebra.org/pub/zebra/%{name}-%{version}.tar.gz
@@ -80,10 +82,7 @@ developing OSPF-API and zebra applications.
 %setup  -q
 
 %build
-./update-autotools
 %configure \
-       --with-cflags="-O2" \
-       --enable-netlink \
 %if %with_ipv6
        --enable-ipv6 \
 %endif
@@ -119,12 +118,17 @@ developing OSPF-API and zebra applications.
        --enable-ospfapi=no \
 %endif
 %if %with_pam
-       --with-libpam
+       --with-libpam \
 %endif
-
-pushd vtysh
-make %{?_smp_mflags} rebuild
-popd
+%if %zebra_user
+       --enable-user=%zebra_user \
+       --enable-group=%zebra_user \
+%endif
+%if %vty_group
+       --enable-vty-group=%vty_group \
+%endif
+--with-cflags="-O2" \
+--enable-netlink
 
 make %{?_smp_mflags} MAKEINFO="makeinfo --no-split"
 
@@ -151,6 +155,18 @@ install %{zeb_rh_src}/ospfd.init $RPM_BUILD_ROOT/etc/rc.d/init.d/ospfd
 install %{zeb_rh_src}/ripd.init $RPM_BUILD_ROOT/etc/rc.d/init.d/ripd
 install -m644 %{zeb_rh_src}/zebra.pam $RPM_BUILD_ROOT/etc/pam.d/zebra
 install -m644 %{zeb_rh_src}/zebra.logrotate $RPM_BUILD_ROOT/etc/logrotate.d/zebra
+install -d -m750  $RPM_BUILD_ROOT/var/run/zebra
+
+%pre
+# add vty_group
+%if %vty_group
+groupadd -r %vty_group 2> /dev/null || :
+%endif
+# add zebra user and group
+%if %zebra_user
+/usr/sbin/useradd -M -r -s /bin/false -c "Zebra routing suite" \
+ -d %_localstatedir %zebra_user 2> /dev/null || :
+%endif
 
 %post
 # zebra_spec_add_service <service name> <port/proto> <comment>
@@ -235,9 +251,19 @@ fi
 %doc doc/zebra.html
 %doc doc/mpls
 %doc ChangeLog INSTALL NEWS README REPORTING-BUGS SERVICES TODO
+%if %zebra_user
+%dir %attr(751,%zebra_user,%zebra_user) %{_sysconfdir}
+%dir %attr(750,%zebra_user,%zebra_user) /var/log/zebra 
+%dir %attr(751,%zebra_user,%zebra_user) /var/run/zebra
+%else
 %dir %attr(750,root,root) %{_sysconfdir}
 %dir %attr(750,root,root) /var/log/zebra
 %dir %attr(755,root,root) /usr/share/info
+%dir %attr(750,root,root) /var/run/zebra
+%endif
+%if %vty_group
+%attr(750,%zebra_user,%vty_group) %{_sysconfdir}/vtysh.conf.sample
+%endif
 %{_infodir}/*info*
 %{_mandir}/man*/*
 %{_sbindir}/*
@@ -262,6 +288,9 @@ fi
 %endif
 
 %changelog
+* Tue Mar 20 2003 Paul Jakma <paul@dishone.st>
+- zebra privileges support
+
 * Mon Mar 18 2003 Paul Jakma <paul@dishone.st>
 - Fix mem leak in 'show thread cpu'
 - Ralph Keller's OSPF-API
index df9a0af5906ecb06b59d0eac4a691f103e9a40f1..2c187e84a7a30f9934e4a359fa95ff6616c1878c 100644 (file)
@@ -17,7 +17,7 @@ noinst_HEADERS = \
 ripd_SOURCES = \
        rip_main.c $(librip_a_SOURCES)
 
-ripd_LDADD = -L../lib -lzebra
+ripd_LDADD = -L../lib -lzebra @LIBCAP@
 
 sysconf_DATA = ripd.conf.sample
 
index 8ec96ae16cc9d9d12ce0d5dcd8ccb3805e2cd250..c38892955233cf341c25d1d4ee007210a7e2b219 100644 (file)
@@ -34,6 +34,7 @@
 #include "zclient.h"
 #include "filter.h"
 #include "sockopt.h"
+#include "privs.h"
 
 #include "zebra/connected.h"
 
@@ -56,6 +57,8 @@ struct message ri_version_msg[] =
   {0,                      NULL}
 };
 
+extern struct zebra_privs_t ripd_privs;
+
 /* RIP enabled network vector. */
 vector rip_enable_interface;
 
@@ -177,6 +180,9 @@ rip_interface_multicast_set (int sock, struct interface *ifp)
          from.sin_len = sizeof (struct sockaddr_in);
 #endif /* HAVE_SIN_LEN */
 
+    if (ripd_privs.change (ZPRIVS_RAISE))
+      zlog_err ("rip_interface_multicast_set: could not raise privs");
+      
          ret = bind (sock, (struct sockaddr *) & from, 
                      sizeof (struct sockaddr_in));
          if (ret < 0)
@@ -185,6 +191,9 @@ rip_interface_multicast_set (int sock, struct interface *ifp)
              return;
            }
 
+    if (ripd_privs.change (ZPRIVS_LOWER))
+        zlog_err ("rip_interface_multicast_set: could not lower privs");
+
          return;
 
        }
index 5e560524ae11cd0ea92f1f9aaea11d90790a28fd..9526d7ae9776f721f4a756d5af80c9c0b8a67f0e 100644 (file)
@@ -30,6 +30,7 @@
 #include "filter.h"
 #include "keychain.h"
 #include "log.h"
+#include "privs.h"
 
 #include "ripd/ripd.h"
 
@@ -43,10 +44,31 @@ static 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 }
 };
 
+/* ripd privileges */
+zebra_capabilities_t _caps_p [] = 
+{
+  ZCAP_RAW,
+  ZCAP_BIND
+};
+
+struct zebra_privs_t ripd_privs =
+{
+#if defined(ZEBRA_USER)
+  .user = ZEBRA_USER,
+#endif
+#if defined ZEBRA_GROUP
+  .group = ZEBRA_GROUP,
+#endif
+  .caps_p = _caps_p,
+  .cap_num_p = 2,
+  .cap_num_i = 0
+};
+
 /* Configuration file and directory. */
 char config_current[] = RIPD_DEFAULT_CONFIG;
 char config_default[] = SYSCONFDIR RIPD_DEFAULT_CONFIG;
@@ -85,6 +107,7 @@ Daemon which manages RIP version 1 and 2.\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 ripd.\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\
@@ -189,7 +212,7 @@ main (int argc, char **argv)
     {
       int opt;
 
-      opt = getopt_long (argc, argv, "df:hA:P:rv", longopts, 0);
+      opt = getopt_long (argc, argv, "df:hA:P:u:rv", longopts, 0);
     
       if (opt == EOF)
        break;
@@ -224,6 +247,9 @@ main (int argc, char **argv)
        case 'r':
          retain_mode = 1;
          break;
+    case 'u':
+        ripd_privs.group = ripd_privs.user = optarg;
+        break;
        case 'v':
          print_version (progname);
          exit (0);
@@ -241,6 +267,7 @@ main (int argc, char **argv)
   master = thread_master_create ();
 
   /* Library initialization. */
+  zprivs_init (&ripd_privs);
   signal_init ();
   cmd_init (1);
   vty_init ();
index c5d45536b264e7d56f47553686927dcb2542dc3b..a58406b478aa69aa7a690e5257463fd281898ce1 100644 (file)
 #include "distribute.h"
 #include "md5-gnu.h"
 #include "keychain.h"
+#include "privs.h"
 
 #include "ripd/ripd.h"
 #include "ripd/rip_debug.h"
 
+extern struct zebra_privs_t ripd_privs;
+
 /* RIP Structure. */
 struct rip *rip = NULL;
 
@@ -1884,13 +1887,17 @@ rip_create_socket ()
   setsockopt_pktinfo (sock);
 #endif /* RIP_RECVMSG */
 
+  if (ripd_privs.change (ZPRIVS_RAISE))
+      zlog_err ("rip_create_socket: could not raise privs");
   ret = bind (sock, (struct sockaddr *) & addr, sizeof (addr));
   if (ret < 0)
     {
       perror ("bind");
       return ret;
     }
-  
+  if (ripd_privs.change (ZPRIVS_LOWER))
+      zlog_err ("rip_create_socket: could not lower privs");
+      
   return sock;
 }
 
index a6810649679230cc506a6e36d0a3e60ce6f53611..d9db576e5f62cfa692ee93326a6837d5dcf37aee 100644 (file)
@@ -17,7 +17,7 @@ noinst_HEADERS = \
 ripngd_SOURCES = \
        ripng_main.c $(libripng_a_SOURCES)
 
-ripngd_LDADD = -L../lib -lzebra
+ripngd_LDADD = -L../lib -lzebra @LIBCAP@
 
 sysconf_DATA = ripngd.conf.sample
 
index 44c387623647808ce5025704ea0f8cea1ef7401a..bd1972a11676b1bde887757a85ab19fc398f5165 100644 (file)
@@ -32,6 +32,7 @@
 #include "log.h"
 #include "prefix.h"
 #include "if.h"
+#include "privs.h"
 
 #include "ripngd/ripngd.h"
 
@@ -51,10 +52,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 }
 };
 
+/* ripngd privileges */
+zebra_capabilities_t _caps_p [] = 
+{
+  ZCAP_RAW,
+  ZCAP_BIND
+};
+
+struct zebra_privs_t ripngd_privs =
+{
+#if defined(ZEBRA_USER)
+  .user = ZEBRA_USER,
+#endif
+#if defined ZEBRA_GROUP
+  .group = ZEBRA_GROUP,
+#endif
+  .caps_p = _caps_p,
+  .cap_num_p = 2,
+  .cap_num_i = 0
+};
+
+
 /* RIPngd program name */
 
 /* Route retain mode flag. */
@@ -89,6 +112,7 @@ Daemon which manages RIPng.\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 ripngd.\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\
@@ -190,7 +214,7 @@ main (int argc, char **argv)
     {
       int opt;
 
-      opt = getopt_long (argc, argv, "dlf:hA:P:v", longopts, 0);
+      opt = getopt_long (argc, argv, "dlf:hA:P:u:v", longopts, 0);
     
       if (opt == EOF)
        break;
@@ -228,6 +252,9 @@ main (int argc, char **argv)
        case 'r':
          retain_mode = 1;
          break;
+  case 'u':
+    ripngd_privs.group = ripngd_privs.user = optarg;
+    break;
        case 'v':
          print_version (progname);
          exit (0);
@@ -244,6 +271,7 @@ main (int argc, char **argv)
   master = thread_master_create ();
 
   /* Library inits. */
+  zprivs_init (&ripngd_privs);
   signal_init ();
   cmd_init (1);
   vty_init ();
index 89156f90e354951ce3667aeabcbfaed03001f972..7a21409fa0c39386fbe9bc07ee68e2968398af00 100644 (file)
@@ -9,7 +9,7 @@ bin_PROGRAMS = vtysh
 
 vtysh_SOURCES = vtysh_main.c vtysh.c vtysh_cmd.c vtysh_user.c vtysh_config.c
 noinst_HEADERS = vtysh.h vtysh_user.h
-vtysh_LDADD = ../lib/libzebra.a
+vtysh_LDADD = ../lib/libzebra.a @LIBCAP@
 
 sysconf_DATA = vtysh.conf.sample
 
index 6214767de96eb715afa96ae4ef2e28a2c772e408..ce5646727910aaf22eba358ba2efaaed0292f7a4 100644 (file)
@@ -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)
index 3e5d1d2fbb75fbc02e8090f5671419f013cb3475..f8e7f22b650352ec38b0142acf98d6a8314b5ab9 100644 (file)
 #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;
index eb8cef01f167b675c6462169432c69bda95544af..a31ec84b67081bed85495e9598aaf303878a5aba 100644 (file)
 
 #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;
index 63d1110cbcf864b2fe184998996ee4c5b7b5b916..fe06e74da3724ed4e0d97b4f6d9ec620919f5c5e 100644 (file)
@@ -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;
 }
 
index 828eb8655762977b68576b56ae8b4a9afbc4b34b..53b6c6f0b9b4128263ea408b375471633acb3e63 100644 (file)
@@ -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 */
index 17893a87b719a465c28c9e491bf3be11d3655946..30e0fb1dfc80a6dfe7fd6f511c169fe7ad882673 100644 (file)
 #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);
index 66469a2f0d6bd255893e98cfd5a51d2da3a6ae02..72b1fc4ea83921b23b724bf73fa468516d9a1e19 100644 (file)
@@ -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);
index 87062dc5d1031516ce27a081515e63ec053f689e..e151462350a748bc27fffd1374c9f5e14f5abc24 100644 (file)
@@ -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",
index 19b2fc2f75d79aa3cba8112b64b036d9b389066c..d603c60da3a5c533a8e774f282247d9e368e436c 100644 (file)
 #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 */
index 8f4b37780a6dd22dc196e11ab5edee8316469082..9dcee8ea9df6dafe8ce0a3df497f562b1b903669 100644 (file)
 #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)
index 70e7672df84361945998d83a11176dd10433879c..975574af0c148fecf620e943e85febc57764cc75 100644 (file)
@@ -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;
 \f
 /* 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)