2003-06-04 Paul Jakma <paul@dishone.st>

	* Merge of zebra privileges
diff --git a/ripd/Makefile.am b/ripd/Makefile.am
index df9a0af..2c187e8 100644
--- a/ripd/Makefile.am
+++ b/ripd/Makefile.am
@@ -17,7 +17,7 @@
 ripd_SOURCES = \
 	rip_main.c $(librip_a_SOURCES)
 
-ripd_LDADD = -L../lib -lzebra
+ripd_LDADD = -L../lib -lzebra @LIBCAP@
 
 sysconf_DATA = ripd.conf.sample
 
diff --git a/ripd/rip_interface.c b/ripd/rip_interface.c
index 8ec96ae..c388929 100644
--- a/ripd/rip_interface.c
+++ b/ripd/rip_interface.c
@@ -34,6 +34,7 @@
 #include "zclient.h"
 #include "filter.h"
 #include "sockopt.h"
+#include "privs.h"
 
 #include "zebra/connected.h"
 
@@ -56,6 +57,8 @@
   {0,                      NULL}
 };
 
+extern struct zebra_privs_t ripd_privs;
+
 /* RIP enabled network vector. */
 vector rip_enable_interface;
 
@@ -177,6 +180,9 @@
 	  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 @@
 	      return;
 	    }
 
+    if (ripd_privs.change (ZPRIVS_LOWER))
+        zlog_err ("rip_interface_multicast_set: could not lower privs");
+
 	  return;
 
 	}
diff --git a/ripd/rip_main.c b/ripd/rip_main.c
index 5e56052..9526d7a 100644
--- a/ripd/rip_main.c
+++ b/ripd/rip_main.c
@@ -30,6 +30,7 @@
 #include "filter.h"
 #include "keychain.h"
 #include "log.h"
+#include "privs.h"
 
 #include "ripd/ripd.h"
 
@@ -43,10 +44,31 @@
   { "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 @@
 -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 @@
     {
       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 @@
 	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 @@
   master = thread_master_create ();
 
   /* Library initialization. */
+  zprivs_init (&ripd_privs);
   signal_init ();
   cmd_init (1);
   vty_init ();
diff --git a/ripd/ripd.c b/ripd/ripd.c
index c5d4553..a58406b 100644
--- a/ripd/ripd.c
+++ b/ripd/ripd.c
@@ -37,10 +37,13 @@
 #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 @@
   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;
 }