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

* Merge of zebra privileges
This commit is contained in:
paul 2003-06-04 13:59:38 +00:00
parent a159ed935b
commit edd7c245d3
37 changed files with 682 additions and 73 deletions

View file

@ -24,7 +24,7 @@ noinst_HEADERS = \
bgpd_SOURCES = \ bgpd_SOURCES = \
bgp_main.c $(libbgp_a_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 sysconf_DATA = bgpd.conf.sample bgpd.conf.sample2

View file

@ -29,6 +29,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "memory.h" #include "memory.h"
#include "prefix.h" #include "prefix.h"
#include "log.h" #include "log.h"
#include "privs.h"
#include "bgpd/bgpd.h" #include "bgpd/bgpd.h"
#include "bgpd/bgp_attr.h" #include "bgpd/bgp_attr.h"
@ -45,6 +46,7 @@ struct option longopts[] =
{ "vty_port", required_argument, NULL, 'P'}, { "vty_port", required_argument, NULL, 'P'},
{ "retain", no_argument, NULL, 'r'}, { "retain", no_argument, NULL, 'r'},
{ "no_kernel", no_argument, NULL, 'n'}, { "no_kernel", no_argument, NULL, 'n'},
{ "user", required_argument, NULL, 'u'},
{ "version", no_argument, NULL, 'v'}, { "version", no_argument, NULL, 'v'},
{ "help", no_argument, NULL, 'h'}, { "help", no_argument, NULL, 'h'},
{ 0 } { 0 }
@ -70,6 +72,23 @@ char *pid_file = PATH_BGPD_PID;
int vty_port = BGP_VTY_PORT; int vty_port = BGP_VTY_PORT;
char *vty_addr = NULL; 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. */ /* Help information display. */
static void static void
usage (char *progname, int status) 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\ -P, --vty_port Set vty's port number\n\
-r, --retain When program terminates, retain added route by bgpd.\n\ -r, --retain When program terminates, retain added route by bgpd.\n\
-n, --no_kernel Do not install route to kernel.\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\ -v, --version Print program version\n\
-h, --help Display this help and exit\n\ -h, --help Display this help and exit\n\
\n\ \n\
@ -197,7 +217,7 @@ main (int argc, char **argv)
/* Command line argument treatment. */ /* Command line argument treatment. */
while (1) 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) if (opt == EOF)
break; break;
@ -238,6 +258,9 @@ main (int argc, char **argv)
case 'n': case 'n':
bgp_option_set (BGP_OPT_NO_FIB); bgp_option_set (BGP_OPT_NO_FIB);
break; break;
case 'u':
bgpd_privs.user = bgpd_privs.group = optarg;
break;
case 'v': case 'v':
print_version (progname); print_version (progname);
exit (0); exit (0);
@ -257,6 +280,7 @@ main (int argc, char **argv)
/* Initializations. */ /* Initializations. */
srand (time (NULL)); srand (time (NULL));
signal_init (); signal_init ();
zprivs_init (&bgpd_privs);
cmd_init (1); cmd_init (1);
vty_init (); vty_init ();
memory_init (); memory_init ();

View file

@ -27,12 +27,16 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "if.h" #include "if.h"
#include "prefix.h" #include "prefix.h"
#include "command.h" #include "command.h"
#include "privs.h"
#include "bgpd/bgpd.h" #include "bgpd/bgpd.h"
#include "bgpd/bgp_fsm.h" #include "bgpd/bgp_fsm.h"
#include "bgpd/bgp_attr.h" #include "bgpd/bgp_attr.h"
#include "bgpd/bgp_debug.h" #include "bgpd/bgp_debug.h"
#include "bgpd/bgp_network.h" #include "bgpd/bgp_network.h"
extern struct zebra_privs_t bgpd_privs;
/* Accept bgp connection. */ /* Accept bgp connection. */
static int static int
@ -153,9 +157,16 @@ bgp_bind_address (int sock, struct in_addr *addr)
#endif /* HAVE_SIN_LEN */ #endif /* HAVE_SIN_LEN */
memcpy (&local.sin_addr, addr, sizeof (struct in_addr)); 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)); ret = bind (sock, (struct sockaddr *)&local, sizeof (struct sockaddr_in));
if (ret < 0) if (ret < 0)
; ;
if (bgpd_privs.change (ZPRIVS_LOWER) )
zlog_err ("bgp_bind_address: could not lower privs");
return 0; return 0;
} }
@ -307,6 +318,9 @@ bgp_socket (struct bgp *bgp, unsigned short port)
sockopt_reuseaddr (sock); sockopt_reuseaddr (sock);
sockopt_reuseport (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); ret = bind (sock, ainfo->ai_addr, ainfo->ai_addrlen);
if (ret < 0) if (ret < 0)
{ {
@ -314,6 +328,10 @@ bgp_socket (struct bgp *bgp, unsigned short port)
close (sock); close (sock);
continue; continue;
} }
if (bgpd_privs.change (ZPRIVS_LOWER) )
zlog_err ("bgp_bind_address: could not lower privs");
ret = listen (sock, 3); ret = listen (sock, 3);
if (ret < 0) if (ret < 0)
{ {
@ -359,6 +377,9 @@ bgp_socket (struct bgp *bgp, unsigned short port)
sin.sin_len = socklen; sin.sin_len = socklen;
#endif /* HAVE_SIN_LEN */ #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); ret = bind (sock, (struct sockaddr *) &sin, socklen);
if (ret < 0) if (ret < 0)
{ {
@ -366,6 +387,10 @@ bgp_socket (struct bgp *bgp, unsigned short port)
close (sock); close (sock);
return ret; return ret;
} }
if (bgpd_privs.change (ZPRIVS_LOWER) )
zlog_err ("bgp_socket: could not lower privs");
ret = listen (sock, 3); ret = listen (sock, 3);
if (ret < 0) if (ret < 0)
{ {

View file

@ -98,8 +98,15 @@ AC_ARG_ENABLE(ospf-te,
[ --enable-ospf-te enable Traffic Engineering Extension to OSPF]) [ --enable-ospf-te enable Traffic Engineering Extension to OSPF])
AC_ARG_ENABLE(multipath, AC_ARG_ENABLE(multipath,
[ --enable-multipath=ARG enable multipath function, ARG must be digit]) [ --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, 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_broken_aliases}" = "yes"; then
if test "${enable_netlink}" = "yes" if test "${enable_netlink}" = "yes"
@ -136,6 +143,32 @@ else
AC_MSG_RESULT(no) AC_MSG_RESULT(no)
fi 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 changequote(, )dnl
MULTIPATH_NUM=1 MULTIPATH_NUM=1
@ -864,6 +897,28 @@ AC_TRY_COMPILE([#include <sys/resource.h>
AC_DEFINE(HAVE_RUSAGE,,rusage)], AC_DEFINE(HAVE_RUSAGE,,rusage)],
AC_MSG_RESULT(no)) 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 ---------------------------
dnl check for glibc 'backtrace' dnl check for glibc 'backtrace'
dnl --------------------------- dnl ---------------------------
@ -968,5 +1023,4 @@ compiler : ${CC}
compiler flags : ${CFLAGS} compiler flags : ${CFLAGS}
linker flags : ${LDFLAGS} ${LIBS} linker flags : ${LDFLAGS} ${LIBS}
state file directory : ${zebra_statedir} state file directory : ${zebra_statedir}
linker flags : ${LDFLAGS} ${LIBS}
" "

View file

@ -10,9 +10,9 @@ libzebra_a_SOURCES = \
print_version.c checksum.c vector.c linklist.c vty.c command.c \ 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 \ 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 \ 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@ 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 \ 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 \ 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 \ 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 EXTRA_DIST = regex.c regex-gnu.h

View file

@ -190,6 +190,8 @@ enum
MTYPE_VRF, MTYPE_VRF,
MTYPE_VRF_NAME, MTYPE_VRF_NAME,
MTYPE_PRIVS,
MTYPE_MAX MTYPE_MAX
}; };

View file

@ -33,6 +33,7 @@
#include "log.h" #include "log.h"
#include "prefix.h" #include "prefix.h"
#include "filter.h" #include "filter.h"
#include "privs.h"
/* Vty events */ /* Vty events */
enum event enum event
@ -1851,6 +1852,7 @@ vty_serv_un (char *path)
int sock, len; int sock, len;
struct sockaddr_un serv; struct sockaddr_un serv;
mode_t old_mask; mode_t old_mask;
struct zprivs_ids_t ids;
/* First of all, unlink existing socket */ /* First of all, unlink existing socket */
unlink (path); unlink (path);
@ -1894,6 +1896,18 @@ vty_serv_un (char *path)
umask (old_mask); 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); vty_event (VTYSH_SERV, sock, NULL);
} }

View file

@ -42,6 +42,8 @@ typedef int socklen_t;
#include <fcntl.h> #include <fcntl.h>
#include <signal.h> #include <signal.h>
#include <string.h> #include <string.h>
#include <pwd.h>
#include <grp.h>
#ifdef HAVE_STROPTS_H #ifdef HAVE_STROPTS_H
#include <stropts.h> #include <stropts.h>
#endif /* HAVE_STROPTS_H */ #endif /* HAVE_STROPTS_H */
@ -70,6 +72,10 @@ typedef int socklen_t;
#ifdef HAVE_RUSAGE #ifdef HAVE_RUSAGE
#include <sys/resource.h> #include <sys/resource.h>
#endif /* HAVE_RUSAGE */ #endif /* HAVE_RUSAGE */
#ifdef HAVE_LCAPS
#include <sys/capability.h>
#include <sys/prctl.h>
#endif /* HAVE_LCAPS */
/* machine dependent includes */ /* machine dependent includes */
#ifdef SUNOS_5 #ifdef SUNOS_5

View file

@ -28,7 +28,7 @@ noinst_HEADERS = \
ospf6d_SOURCES = \ ospf6d_SOURCES = \
ospf6_main.c $(libospf6_a_SOURCES) ospf6_main.c $(libospf6_a_SOURCES)
ospf6d_LDADD = -L../lib -lzebra ospf6d_LDADD = -L../lib -lzebra @LIBCAP@
sysconf_DATA = ospf6d.conf.sample sysconf_DATA = ospf6d.conf.sample

View file

@ -27,6 +27,7 @@
#include "command.h" #include "command.h"
#include "vty.h" #include "vty.h"
#include "memory.h" #include "memory.h"
#include "privs.h"
#include "ospf6d.h" #include "ospf6d.h"
#include "ospf6_network.h" #include "ospf6_network.h"
@ -43,6 +44,26 @@ extern int ospf6_sock;
/* Default port values. */ /* Default port values. */
#define OSPF6_VTY_PORT 2606 #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. */ /* ospf6d options, we use GNU getopt library. */
struct option longopts[] = struct option longopts[] =
{ {
@ -51,6 +72,7 @@ struct option longopts[] =
{ "pid_file", required_argument, NULL, 'i'}, { "pid_file", required_argument, NULL, 'i'},
{ "vty_addr", required_argument, NULL, 'A'}, { "vty_addr", required_argument, NULL, 'A'},
{ "vty_port", required_argument, NULL, 'P'}, { "vty_port", required_argument, NULL, 'P'},
{ "user", required_argument, NULL, 'u'},
{ "version", no_argument, NULL, 'v'}, { "version", no_argument, NULL, 'v'},
{ "help", no_argument, NULL, 'h'}, { "help", no_argument, NULL, 'h'},
{ 0 } { 0 }
@ -93,6 +115,7 @@ Daemon which manages OSPF version 3.\n\n\
-i, --pid_file Set process identifier file name\n\ -i, --pid_file Set process identifier file name\n\
-A, --vty_addr Set vty's bind address\n\ -A, --vty_addr Set vty's bind address\n\
-P, --vty_port Set vty's port number\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\ -v, --version Print program version\n\
-h, --help Display this help and exit\n\ -h, --help Display this help and exit\n\
\n\ \n\
@ -231,7 +254,7 @@ main (int argc, char *argv[], char *envp[])
/* Command line argument treatment. */ /* Command line argument treatment. */
while (1) 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) if (opt == EOF)
break; break;
@ -263,6 +286,9 @@ main (int argc, char *argv[], char *envp[])
vty_port = atoi (optarg); vty_port = atoi (optarg);
vty_port = (vty_port ? vty_port : OSPF6_VTY_PORT); vty_port = (vty_port ? vty_port : OSPF6_VTY_PORT);
break; break;
case 'u':
ospf6d_privs.user = ospf6d_privs.group = optarg;
break;
case 'v': case 'v':
print_version (progname); print_version (progname);
exit (0); exit (0);
@ -288,6 +314,7 @@ main (int argc, char *argv[], char *envp[])
zlog_default = openzlog (progname, flag, ZLOG_OSPF6, zlog_default = openzlog (progname, flag, ZLOG_OSPF6,
LOG_CONS|LOG_NDELAY|LOG_PID, LOG_CONS|LOG_NDELAY|LOG_PID,
LOG_DAEMON); LOG_DAEMON);
zprivs_init (&ospf6d_privs);
signal_init (); signal_init ();
cmd_init (1); cmd_init (1);
vty_init (); vty_init ();

View file

@ -23,6 +23,7 @@
#include "memory.h" #include "memory.h"
#include "log.h" #include "log.h"
#include "sockunion.h" #include "sockunion.h"
#include "privs.h"
#include "ospf6d.h" #include "ospf6d.h"
#include "ospf6_proto.h" #include "ospf6_proto.h"
@ -32,6 +33,7 @@ extern struct sockaddr_in6 allspfrouters6;
extern struct sockaddr_in6 alldrouters6; extern struct sockaddr_in6 alldrouters6;
extern int ospf6_sock; extern int ospf6_sock;
extern struct thread_master *master; extern struct thread_master *master;
extern struct zebra_privs_t ospf6d_privs;
/* iovec functions */ /* iovec functions */
void void
@ -194,6 +196,10 @@ iov_copy_all (struct iovec *dst, struct iovec *src, size_t size)
int int
ospf6_serv_sock () 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); ospf6_sock = socket (AF_INET6, SOCK_RAW, IPPROTO_OSPFIGP);
if (ospf6_sock < 0) if (ospf6_sock < 0)
{ {
@ -202,6 +208,9 @@ ospf6_serv_sock ()
} }
sockopt_reuseaddr (ospf6_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 */ /* setup global sockaddr_in6, allspf6 & alldr6 for later use */
allspfrouters6.sin6_family = AF_INET6; allspfrouters6.sin6_family = AF_INET6;
alldrouters6.sin6_family = AF_INET6; alldrouters6.sin6_family = AF_INET6;

View file

@ -16,6 +16,6 @@ ospfapiheader_HEADERS = \
ospfclient_SOURCES = \ ospfclient_SOURCES = \
ospfclient.c $(libospfapiclient_a_SOURCES) ospfclient.c $(libospfapiclient_a_SOURCES)
ospfclient_LDADD = ../ospfd/libospf.a ../lib/libzebra.a ospfclient_LDADD = ../ospfd/libospf.a ../lib/libzebra.a @LIBCAP@

View file

@ -11,6 +11,8 @@
#include <zebra.h> #include <zebra.h>
#include "prefix.h" /* needed by ospf_asbr.h */ #include "prefix.h" /* needed by ospf_asbr.h */
#include "privs.h"
#include "ospfd/ospfd.h" #include "ospfd/ospfd.h"
#include "ospfd/ospf_asbr.h" #include "ospfd/ospf_asbr.h"
#include "ospfd/ospf_lsa.h" #include "ospfd/ospf_lsa.h"
@ -18,6 +20,18 @@
#include "ospfd/ospf_api.h" #include "ospfd/ospf_api.h"
#include "ospf_apiclient.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 /* The following includes are specific to this application. For
example it uses threads from libzebra, however your application is example it uses threads from libzebra, however your application is
free to use any thread library (like pthreads). */ free to use any thread library (like pthreads). */
@ -274,6 +288,7 @@ main (int argc, char *argv[])
} }
/* Initialization */ /* Initialization */
zprivs_init (&ospfd_privs);
master = thread_master_create (); master = thread_master_create ();
/* Open connection to OSPF daemon */ /* Open connection to OSPF daemon */

View file

@ -28,7 +28,7 @@ noinst_HEADERS = \
ospfd_SOURCES = \ ospfd_SOURCES = \
ospf_main.c $(libospf_a_SOURCES) ospf_main.c $(libospf_a_SOURCES)
ospfd_LDADD = -L../lib -lzebra ospfd_LDADD = -L../lib -lzebra @LIBCAP@
sysconf_DATA = ospfd.conf.sample sysconf_DATA = ospfd.conf.sample

View file

@ -36,6 +36,8 @@
#include "stream.h" #include "stream.h"
#include "log.h" #include "log.h"
#include "memory.h" #include "memory.h"
#include "privs.h"
#include "debug.h"
#include "ospfd/ospfd.h" #include "ospfd/ospfd.h"
#include "ospfd/ospf_interface.h" #include "ospfd/ospf_interface.h"
@ -47,6 +49,29 @@
#include "ospfd/ospf_zebra.h" #include "ospfd/ospf_zebra.h"
#include "ospfd/ospf_vty.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. */ /* Configuration filename and directory. */
char config_current[] = OSPF_DEFAULT_CONFIG; char config_current[] = OSPF_DEFAULT_CONFIG;
char config_default[] = SYSCONFDIR OSPF_DEFAULT_CONFIG; char config_default[] = SYSCONFDIR OSPF_DEFAULT_CONFIG;
@ -61,6 +86,7 @@ struct option longopts[] =
{ "help", no_argument, NULL, 'h'}, { "help", no_argument, NULL, 'h'},
{ "vty_addr", required_argument, NULL, 'A'}, { "vty_addr", required_argument, NULL, 'A'},
{ "vty_port", required_argument, NULL, 'P'}, { "vty_port", required_argument, NULL, 'P'},
{ "user", required_argument, NULL, 'u'},
{ "version", no_argument, NULL, 'v'}, { "version", no_argument, NULL, 'v'},
{ 0 } { 0 }
}; };
@ -88,6 +114,7 @@ Daemon which manages OSPF.\n\n\
-i, --pid_file Set process identifier file name\n\ -i, --pid_file Set process identifier file name\n\
-A, --vty_addr Set vty's bind address\n\ -A, --vty_addr Set vty's bind address\n\
-P, --vty_port Set vty's port number\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\ -v, --version Print program version\n\
-h, --help Display this help and exit\n\ -h, --help Display this help and exit\n\
\n\ \n\
@ -162,6 +189,11 @@ signal_init ()
signal_set (SIGTTOU, SIG_IGN); signal_set (SIGTTOU, SIG_IGN);
#endif #endif
signal_set (SIGUSR1, sigusr1); 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 */
} }
/* OSPFd main routine. */ /* OSPFd main routine. */
@ -200,7 +232,7 @@ main (int argc, char **argv)
{ {
int opt; 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) if (opt == EOF)
break; break;
@ -232,6 +264,9 @@ main (int argc, char **argv)
vty_port = atoi (optarg); vty_port = atoi (optarg);
vty_port = (vty_port ? vty_port : OSPF_VTY_PORT); vty_port = (vty_port ? vty_port : OSPF_VTY_PORT);
break; break;
case 'u':
ospfd_privs.group = ospfd_privs.user = optarg;
break;
case 'v': case 'v':
print_version (progname); print_version (progname);
exit (0); exit (0);
@ -249,6 +284,7 @@ main (int argc, char **argv)
master = om->master; master = om->master;
/* Library inits. */ /* Library inits. */
zprivs_init (&ospfd_privs);
signal_init (); signal_init ();
cmd_init (1); cmd_init (1);
debug_init (); debug_init ();

View file

@ -29,6 +29,9 @@
#include "sockunion.h" #include "sockunion.h"
#include "log.h" #include "log.h"
#include "sockopt.h" #include "sockopt.h"
#include "privs.h"
extern struct zebra_privs_t ospfd_privs;
#include "ospfd/ospfd.h" #include "ospfd/ospfd.h"
#include "ospfd/ospf_network.h" #include "ospfd/ospf_network.h"
@ -39,6 +42,8 @@
#include "ospfd/ospf_neighbor.h" #include "ospfd/ospf_neighbor.h"
#include "ospfd/ospf_packet.h" #include "ospfd/ospf_packet.h"
/* Join to the OSPF ALL SPF ROUTERS multicast group. */ /* Join to the OSPF ALL SPF ROUTERS multicast group. */
int int
ospf_if_add_allspfrouters (struct ospf *top, struct prefix *p, ospf_if_add_allspfrouters (struct ospf *top, struct prefix *p,
@ -151,13 +156,21 @@ ospf_sock_init (void)
int ospf_sock; int ospf_sock;
int ret, tos, hincl = 1; 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); ospf_sock = socket (AF_INET, SOCK_RAW, IPPROTO_OSPFIGP);
if (ospf_sock < 0) 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)); zlog_warn ("ospf_read_sock_init: socket: %s", strerror (errno));
return -1; return -1;
} }
/* Set precedence field. */ /* Set precedence field. */
#ifdef IPTOS_PREC_INTERNETCONTROL #ifdef IPTOS_PREC_INTERNETCONTROL
tos = IPTOS_PREC_INTERNETCONTROL; tos = IPTOS_PREC_INTERNETCONTROL;
@ -165,6 +178,9 @@ ospf_sock_init (void)
(char *) &tos, sizeof (int)); (char *) &tos, sizeof (int));
if (ret < 0) 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); zlog_warn ("can't set sockopt IP_TOS %d to socket %d", tos, ospf_sock);
close (ospf_sock); /* Prevent sd leak. */ close (ospf_sock); /* Prevent sd leak. */
return ret; return ret;
@ -174,19 +190,40 @@ ospf_sock_init (void)
/* we will include IP header with packet */ /* we will include IP header with packet */
ret = setsockopt (ospf_sock, IPPROTO_IP, IP_HDRINCL, &hincl, sizeof (hincl)); ret = setsockopt (ospf_sock, IPPROTO_IP, IP_HDRINCL, &hincl, sizeof (hincl));
if (ret < 0) 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) #if defined (IP_PKTINFO)
ret = setsockopt (ospf_sock, IPPROTO_IP, IP_PKTINFO, &hincl, sizeof (hincl)); ret = setsockopt (ospf_sock, IPPROTO_IP, IP_PKTINFO, &hincl, sizeof (hincl));
if (ret < 0) 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) #elif defined (IP_RECVIF)
ret = setsockopt (ospf_sock, IPPROTO_IP, IP_RECVIF, &hincl, sizeof (hincl)); ret = setsockopt (ospf_sock, IPPROTO_IP, IP_RECVIF, &hincl, sizeof (hincl));
if (ret < 0) 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 #else
#warning "cannot be able to receive link information on this OS" #warning "cannot be able to receive link information on this OS"
#endif #endif
if (ospfd_privs.change (ZPRIVS_LOWER))
{
zlog_err ("ospf_sock_init: could not lower privs, %s",
strerror (errno) );
}
return ospf_sock; return ospf_sock;
} }

View file

@ -53,6 +53,7 @@ Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
#include "ospfd/ospf_ase.h" #include "ospfd/ospf_ase.h"
/* OSPF process wide configuration. */ /* OSPF process wide configuration. */
static struct ospf_master ospf_master; static struct ospf_master ospf_master;

View file

@ -1,10 +1,26 @@
#%PAM-1.0 #%PAM-1.0
# #
##### if running zebra as root:
# Only allow root (and possibly wheel) to use this because enable access # Only allow root (and possibly wheel) to use this because enable access
# is unrestricted. # 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. # Uncomment the following line to implicitly trust users in the "wheel" group.
#auth sufficient /lib/security/pam_wheel.so trust use_uid #auth sufficient /lib/security/pam_wheel.so trust use_uid
# Uncomment the following line to require a user to be in the "wheel" group. # Uncomment the following line to require a user to be in the "wheel" group.
#auth required /lib/security/pam_wheel.so use_uid #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

View file

@ -1,4 +1,4 @@
# conditionals # configure options
%define with_snmp 0 %define with_snmp 0
%define with_vtysh 1 %define with_vtysh 1
%define with_ospf_te 1 %define with_ospf_te 1
@ -11,6 +11,8 @@
%define with_ospfclient 1 %define with_ospfclient 1
%define with_ospfapi 1 %define with_ospfapi 1
%define with_multipath 64 %define with_multipath 64
%define zebra_user zebra
%define vty_group zebravty
# path defines # path defines
%define _sysconfdir /etc/zebra %define _sysconfdir /etc/zebra
@ -22,12 +24,12 @@
%define _libexecdir %{_exec_prefix}/libexec/zebra %define _libexecdir %{_exec_prefix}/libexec/zebra
%define _includedir %{_prefix}/include/zebra %define _includedir %{_prefix}/include/zebra
%define _libdir %{_exec_prefix}/%{_lib}/zebra %define _libdir %{_exec_prefix}/%{_lib}/zebra
%define _localstatedir %{_prefix}/var/run %define _localstatedir /var/run/zebra
Summary: Routing daemon Summary: Routing daemon
Name: zebra Name: zebra
Version: @VERSION@ Version: @VERSION@
Release: @CONFDATE@ Release: @CONFDATE@01
License: GPL License: GPL
Group: System Environment/Daemons Group: System Environment/Daemons
Source0: ftp://ftp.zebra.org/pub/zebra/%{name}-%{version}.tar.gz Source0: ftp://ftp.zebra.org/pub/zebra/%{name}-%{version}.tar.gz
@ -80,10 +82,7 @@ developing OSPF-API and zebra applications.
%setup -q %setup -q
%build %build
./update-autotools
%configure \ %configure \
--with-cflags="-O2" \
--enable-netlink \
%if %with_ipv6 %if %with_ipv6
--enable-ipv6 \ --enable-ipv6 \
%endif %endif
@ -119,12 +118,17 @@ developing OSPF-API and zebra applications.
--enable-ospfapi=no \ --enable-ospfapi=no \
%endif %endif
%if %with_pam %if %with_pam
--with-libpam --with-libpam \
%endif %endif
%if %zebra_user
pushd vtysh --enable-user=%zebra_user \
make %{?_smp_mflags} rebuild --enable-group=%zebra_user \
popd %endif
%if %vty_group
--enable-vty-group=%vty_group \
%endif
--with-cflags="-O2" \
--enable-netlink
make %{?_smp_mflags} MAKEINFO="makeinfo --no-split" 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 %{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.pam $RPM_BUILD_ROOT/etc/pam.d/zebra
install -m644 %{zeb_rh_src}/zebra.logrotate $RPM_BUILD_ROOT/etc/logrotate.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 %post
# zebra_spec_add_service <service name> <port/proto> <comment> # zebra_spec_add_service <service name> <port/proto> <comment>
@ -235,9 +251,19 @@ fi
%doc doc/zebra.html %doc doc/zebra.html
%doc doc/mpls %doc doc/mpls
%doc ChangeLog INSTALL NEWS README REPORTING-BUGS SERVICES TODO %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) %{_sysconfdir}
%dir %attr(750,root,root) /var/log/zebra %dir %attr(750,root,root) /var/log/zebra
%dir %attr(755,root,root) /usr/share/info %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* %{_infodir}/*info*
%{_mandir}/man*/* %{_mandir}/man*/*
%{_sbindir}/* %{_sbindir}/*
@ -262,6 +288,9 @@ fi
%endif %endif
%changelog %changelog
* Tue Mar 20 2003 Paul Jakma <paul@dishone.st>
- zebra privileges support
* Mon Mar 18 2003 Paul Jakma <paul@dishone.st> * Mon Mar 18 2003 Paul Jakma <paul@dishone.st>
- Fix mem leak in 'show thread cpu' - Fix mem leak in 'show thread cpu'
- Ralph Keller's OSPF-API - Ralph Keller's OSPF-API

View file

@ -17,7 +17,7 @@ noinst_HEADERS = \
ripd_SOURCES = \ ripd_SOURCES = \
rip_main.c $(librip_a_SOURCES) rip_main.c $(librip_a_SOURCES)
ripd_LDADD = -L../lib -lzebra ripd_LDADD = -L../lib -lzebra @LIBCAP@
sysconf_DATA = ripd.conf.sample sysconf_DATA = ripd.conf.sample

View file

@ -34,6 +34,7 @@
#include "zclient.h" #include "zclient.h"
#include "filter.h" #include "filter.h"
#include "sockopt.h" #include "sockopt.h"
#include "privs.h"
#include "zebra/connected.h" #include "zebra/connected.h"
@ -56,6 +57,8 @@ struct message ri_version_msg[] =
{0, NULL} {0, NULL}
}; };
extern struct zebra_privs_t ripd_privs;
/* RIP enabled network vector. */ /* RIP enabled network vector. */
vector rip_enable_interface; vector rip_enable_interface;
@ -177,6 +180,9 @@ rip_interface_multicast_set (int sock, struct interface *ifp)
from.sin_len = sizeof (struct sockaddr_in); from.sin_len = sizeof (struct sockaddr_in);
#endif /* HAVE_SIN_LEN */ #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, ret = bind (sock, (struct sockaddr *) & from,
sizeof (struct sockaddr_in)); sizeof (struct sockaddr_in));
if (ret < 0) if (ret < 0)
@ -185,6 +191,9 @@ rip_interface_multicast_set (int sock, struct interface *ifp)
return; return;
} }
if (ripd_privs.change (ZPRIVS_LOWER))
zlog_err ("rip_interface_multicast_set: could not lower privs");
return; return;
} }

View file

@ -30,6 +30,7 @@
#include "filter.h" #include "filter.h"
#include "keychain.h" #include "keychain.h"
#include "log.h" #include "log.h"
#include "privs.h"
#include "ripd/ripd.h" #include "ripd/ripd.h"
@ -43,10 +44,31 @@ static struct option longopts[] =
{ "vty_addr", required_argument, NULL, 'A'}, { "vty_addr", required_argument, NULL, 'A'},
{ "vty_port", required_argument, NULL, 'P'}, { "vty_port", required_argument, NULL, 'P'},
{ "retain", no_argument, NULL, 'r'}, { "retain", no_argument, NULL, 'r'},
{ "user", required_argument, NULL, 'u'},
{ "version", no_argument, NULL, 'v'}, { "version", no_argument, NULL, 'v'},
{ 0 } { 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. */ /* Configuration file and directory. */
char config_current[] = RIPD_DEFAULT_CONFIG; char config_current[] = RIPD_DEFAULT_CONFIG;
char config_default[] = SYSCONFDIR 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\ -A, --vty_addr Set vty's bind address\n\
-P, --vty_port Set vty's port number\n\ -P, --vty_port Set vty's port number\n\
-r, --retain When program terminates, retain added route by ripd.\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\ -v, --version Print program version\n\
-h, --help Display this help and exit\n\ -h, --help Display this help and exit\n\
\n\ \n\
@ -189,7 +212,7 @@ main (int argc, char **argv)
{ {
int opt; 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) if (opt == EOF)
break; break;
@ -224,6 +247,9 @@ main (int argc, char **argv)
case 'r': case 'r':
retain_mode = 1; retain_mode = 1;
break; break;
case 'u':
ripd_privs.group = ripd_privs.user = optarg;
break;
case 'v': case 'v':
print_version (progname); print_version (progname);
exit (0); exit (0);
@ -241,6 +267,7 @@ main (int argc, char **argv)
master = thread_master_create (); master = thread_master_create ();
/* Library initialization. */ /* Library initialization. */
zprivs_init (&ripd_privs);
signal_init (); signal_init ();
cmd_init (1); cmd_init (1);
vty_init (); vty_init ();

View file

@ -37,10 +37,13 @@
#include "distribute.h" #include "distribute.h"
#include "md5-gnu.h" #include "md5-gnu.h"
#include "keychain.h" #include "keychain.h"
#include "privs.h"
#include "ripd/ripd.h" #include "ripd/ripd.h"
#include "ripd/rip_debug.h" #include "ripd/rip_debug.h"
extern struct zebra_privs_t ripd_privs;
/* RIP Structure. */ /* RIP Structure. */
struct rip *rip = NULL; struct rip *rip = NULL;
@ -1884,12 +1887,16 @@ rip_create_socket ()
setsockopt_pktinfo (sock); setsockopt_pktinfo (sock);
#endif /* RIP_RECVMSG */ #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)); ret = bind (sock, (struct sockaddr *) & addr, sizeof (addr));
if (ret < 0) if (ret < 0)
{ {
perror ("bind"); perror ("bind");
return ret; return ret;
} }
if (ripd_privs.change (ZPRIVS_LOWER))
zlog_err ("rip_create_socket: could not lower privs");
return sock; return sock;
} }

View file

@ -17,7 +17,7 @@ noinst_HEADERS = \
ripngd_SOURCES = \ ripngd_SOURCES = \
ripng_main.c $(libripng_a_SOURCES) ripng_main.c $(libripng_a_SOURCES)
ripngd_LDADD = -L../lib -lzebra ripngd_LDADD = -L../lib -lzebra @LIBCAP@
sysconf_DATA = ripngd.conf.sample sysconf_DATA = ripngd.conf.sample

View file

@ -32,6 +32,7 @@
#include "log.h" #include "log.h"
#include "prefix.h" #include "prefix.h"
#include "if.h" #include "if.h"
#include "privs.h"
#include "ripngd/ripngd.h" #include "ripngd/ripngd.h"
@ -51,10 +52,32 @@ struct option longopts[] =
{ "vty_addr", required_argument, NULL, 'A'}, { "vty_addr", required_argument, NULL, 'A'},
{ "vty_port", required_argument, NULL, 'P'}, { "vty_port", required_argument, NULL, 'P'},
{ "retain", no_argument, NULL, 'r'}, { "retain", no_argument, NULL, 'r'},
{ "user", required_argument, NULL, 'u'},
{ "version", no_argument, NULL, 'v'}, { "version", no_argument, NULL, 'v'},
{ 0 } { 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 */ /* RIPngd program name */
/* Route retain mode flag. */ /* Route retain mode flag. */
@ -89,6 +112,7 @@ Daemon which manages RIPng.\n\n\
-A, --vty_addr Set vty's bind address\n\ -A, --vty_addr Set vty's bind address\n\
-P, --vty_port Set vty's port number\n\ -P, --vty_port Set vty's port number\n\
-r, --retain When program terminates, retain added route by ripngd.\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\ -v, --version Print program version\n\
-h, --help Display this help and exit\n\ -h, --help Display this help and exit\n\
\n\ \n\
@ -190,7 +214,7 @@ main (int argc, char **argv)
{ {
int opt; 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) if (opt == EOF)
break; break;
@ -228,6 +252,9 @@ main (int argc, char **argv)
case 'r': case 'r':
retain_mode = 1; retain_mode = 1;
break; break;
case 'u':
ripngd_privs.group = ripngd_privs.user = optarg;
break;
case 'v': case 'v':
print_version (progname); print_version (progname);
exit (0); exit (0);
@ -244,6 +271,7 @@ main (int argc, char **argv)
master = thread_master_create (); master = thread_master_create ();
/* Library inits. */ /* Library inits. */
zprivs_init (&ripngd_privs);
signal_init (); signal_init ();
cmd_init (1); cmd_init (1);
vty_init (); vty_init ();

View file

@ -9,7 +9,7 @@ bin_PROGRAMS = vtysh
vtysh_SOURCES = vtysh_main.c vtysh.c vtysh_cmd.c vtysh_user.c vtysh_config.c vtysh_SOURCES = vtysh_main.c vtysh.c vtysh_cmd.c vtysh_user.c vtysh_config.c
noinst_HEADERS = vtysh.h vtysh_user.h noinst_HEADERS = vtysh.h vtysh_user.h
vtysh_LDADD = ../lib/libzebra.a vtysh_LDADD = ../lib/libzebra.a @LIBCAP@
sysconf_DATA = vtysh.conf.sample sysconf_DATA = vtysh.conf.sample

View file

@ -13,9 +13,10 @@ rt_method = @RT_METHOD@
rtread_method = @RTREAD_METHOD@ rtread_method = @RTREAD_METHOD@
kernel_method = @KERNEL_METHOD@ kernel_method = @KERNEL_METHOD@
other_method = @OTHER_METHOD@ other_method = @OTHER_METHOD@
libcap = @LIBCAP@
otherobj = $(ipforward) $(if_method) $(if_proc) $(rt_method) \ otherobj = $(ipforward) $(if_method) $(if_proc) $(rt_method) \
$(rtread_method) $(kernel_method) $(other_method) $(rtread_method) $(kernel_method) $(other_method) $(libcap)
sbin_PROGRAMS = zebra sbin_PROGRAMS = zebra
@ -25,7 +26,7 @@ zebra_SOURCES = \
noinst_HEADERS = \ noinst_HEADERS = \
connected.h ioctl.h rib.h rt.h zserv.h redistribute.h debug.h rtadv.h \ 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) 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 \ ipforward_solaris.c ipforward_sysctl.c rt_ioctl.c rt_netlink.c \
rt_socket.c rtread_netlink.c rtread_proc.c rtread_sysctl.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 \ 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 #client : client_main.o ../lib/libzebra.a
# $(CC) -g -o client client_main.o ../lib/libzebra.a $(LIBS) $(LIB_IPV6) # $(CC) -g -o client client_main.o ../lib/libzebra.a $(LIBS) $(LIB_IPV6)

View file

@ -27,10 +27,13 @@
#include "prefix.h" #include "prefix.h"
#include "ioctl.h" #include "ioctl.h"
#include "log.h" #include "log.h"
#include "privs.h"
#include "zebra/rib.h" #include "zebra/rib.h"
#include "zebra/rt.h" #include "zebra/rt.h"
extern struct zebra_privs_t zserv_privs;
/* clear and set interface name string */ /* clear and set interface name string */
void void
ifreq_set_name (struct ifreq *ifreq, struct interface *ifp) 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 ret = 0;
int err = 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); sock = socket (AF_INET, SOCK_DGRAM, 0);
if (sock < 0) if (sock < 0)
{ {
if (zserv_privs.change(ZPRIVS_LOWER))
zlog (NULL, LOG_ERR, "Can't lower privileges");
perror ("socket"); perror ("socket");
exit (1); exit (1);
} }
ret = ioctl (sock, request, buffer); ret = ioctl (sock, request, buffer);
if (zserv_privs.change(ZPRIVS_LOWER))
zlog (NULL, LOG_ERR, "Can't lower privileges");
if (ret < 0) if (ret < 0)
{ {
err = errno; err = errno;
@ -76,14 +84,21 @@ if_ioctl_ipv6 (u_long request, caddr_t buffer)
int ret = 0; int ret = 0;
int err = 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); sock = socket (AF_INET6, SOCK_DGRAM, 0);
if (sock < 0) if (sock < 0)
{ {
if (zserv_privs.change(ZPRIVS_LOWER))
zlog (NULL, LOG_ERR, "Can't lower privileges");
perror ("socket"); perror ("socket");
exit (1); exit (1);
} }
ret = ioctl (sock, request, buffer); ret = ioctl (sock, request, buffer);
if (zserv_privs.change(ZPRIVS_LOWER))
zlog (NULL, LOG_ERR, "Can't lower privileges");
if (ret < 0) if (ret < 0)
{ {
err = errno; err = errno;

View file

@ -22,6 +22,11 @@
#include <zebra.h> #include <zebra.h>
#include "log.h"
#include "privs.h"
extern struct zebra_privs_t zserv_privs;
char proc_net_snmp[] = "/proc/net/snmp"; char proc_net_snmp[] = "/proc/net/snmp";
static void static void
@ -69,8 +74,14 @@ ipforward_on ()
{ {
FILE *fp; FILE *fp;
if ( zserv_privs.change(ZPRIVS_RAISE) )
zlog_err ("Can't raise privileges, %s", strerror (errno) );
fp = fopen (proc_ipv4_forwarding, "w"); fp = fopen (proc_ipv4_forwarding, "w");
if ( zserv_privs.change(ZPRIVS_LOWER) )
zlog_err ("Can't lower privileges, %s", strerror (errno));
if (fp == NULL) if (fp == NULL)
return -1; return -1;
@ -86,8 +97,15 @@ ipforward_off ()
{ {
FILE *fp; FILE *fp;
if ( zserv_privs.change(ZPRIVS_RAISE) )
zlog_err ("Can't raise privileges, %s", strerror (errno));
fp = fopen (proc_ipv4_forwarding, "w"); fp = fopen (proc_ipv4_forwarding, "w");
if ( zserv_privs.change(ZPRIVS_LOWER) )
zlog_err ("Can't lower privileges, %s", strerror (errno));
if (fp == NULL) if (fp == NULL)
return -1; return -1;
@ -124,8 +142,14 @@ ipforward_ipv6_on ()
{ {
FILE *fp; FILE *fp;
if ( zserv_privs.change(ZPRIVS_RAISE) )
zlog_err ("Can't raise privileges, %s", strerror (errno));
fp = fopen (proc_ipv6_forwarding, "w"); fp = fopen (proc_ipv6_forwarding, "w");
if ( zserv_privs.change(ZPRIVS_LOWER) )
zlog_err ("Can't lower privileges, %s", strerror (errno));
if (fp == NULL) if (fp == NULL)
return -1; return -1;
@ -141,8 +165,14 @@ ipforward_ipv6_off ()
{ {
FILE *fp; FILE *fp;
if ( zserv_privs.change(ZPRIVS_RAISE) )
zlog_err ("Can't raise privileges, %s", strerror (errno));
fp = fopen (proc_ipv6_forwarding, "w"); fp = fopen (proc_ipv6_forwarding, "w");
if ( zserv_privs.change(ZPRIVS_LOWER) )
zlog_err ("Can't lower privileges, %s", strerror (errno));
if (fp == NULL) if (fp == NULL)
return -1; return -1;

View file

@ -22,6 +22,7 @@
#include <zebra.h> #include <zebra.h>
#include "log.h" #include "log.h"
#include "prefix.h"
/* /*
** Solaris should define IP_DEV_NAME in <inet/ip.h>, but we'll save ** Solaris should define IP_DEV_NAME in <inet/ip.h>, but we'll save
@ -33,6 +34,9 @@
#define IP_DEV_NAME "/dev/ip" #define IP_DEV_NAME "/dev/ip"
#endif #endif
/* /*
extern struct zebra_privs_t zserv_privs;
** This is a limited ndd style function that operates one integer ** This is a limited ndd style function that operates one integer
** value only. Errors return -1. ND_SET commands return 0 on ** value only. Errors return -1. ND_SET commands return 0 on
** success. ND_GET commands return the value on success (which could ** 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__); zlog_err("internal error - inappropriate command given to solaris_nd()%s:%d", __FILE__, __LINE__);
return -1; return -1;
} }
strioctl.ic_cmd = cmd; strioctl.ic_cmd = cmd;
strioctl.ic_timout = 0; strioctl.ic_timout = 0;
strioctl.ic_len = ND_BUFFER_SIZE; strioctl.ic_len = ND_BUFFER_SIZE;
strioctl.ic_dp = nd_buf; strioctl.ic_dp = nd_buf;
if ((fd = open (device, O_RDWR)) < 0) {
zlog_warn("failed to open device %s - %s", device, strerror(errno)); if ( zserv_privs.change (ZPRIVS_RAISE) )
return -1; zlog_err ("solaris_nd: Can't raise privileges");
} if ((fd = open (device, O_RDWR)) < 0)
if (ioctl (fd, I_STR, &strioctl) < 0) { {
close (fd); zlog_warn("failed to open device %s - %s", device, strerror(errno));
zlog_warn("ioctl I_STR failed on device %s - %s", device,strerror(errno)); if ( zserv_privs.change (ZPRIVS_LOWER) )
return -1; zlog_err ("solaris_nd: Can't lower privileges");
} return -1;
close(fd); }
if (cmd == ND_GET) { if (ioctl (fd, I_STR, &strioctl) < 0)
errno = 0; {
retval = atoi(nd_buf); if ( zserv_privs.change (ZPRIVS_LOWER) )
if (errno) { zlog_err ("solaris_nd: Can't lower privileges");
zlog_warn("failed to convert returned value to integer - %s",strerror(errno)); close (fd);
retval = -1; zlog_warn("ioctl I_STR failed on device %s - %s", device,strerror(errno));
return -1;
}
close(fd);
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; return retval;
} }

View file

@ -20,6 +20,7 @@
*/ */
#include <zebra.h> #include <zebra.h>
#include "privs.h"
#ifdef NRL #ifdef NRL
#include <netinet6/in6.h> #include <netinet6/in6.h>
@ -29,6 +30,8 @@
#define MIB_SIZ 4 #define MIB_SIZ 4
extern struct zebra_privs_t zserv_privs;
/* IPv4 forwarding control MIB. */ /* IPv4 forwarding control MIB. */
int mib[MIB_SIZ] = int mib[MIB_SIZ] =
{ {
@ -60,11 +63,17 @@ ipforward_on ()
int ipforwarding = 1; int ipforwarding = 1;
len = sizeof ipforwarding; len = sizeof ipforwarding;
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 (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"); zlog_warn ("Can't set ipforwarding on");
return -1; return -1;
} }
if (zserv_privs.change(ZPRIVS_LOWER))
zlog (NULL, LOG_ERR, "Can't lower privileges");
return ipforwarding; return ipforwarding;
} }
@ -75,11 +84,17 @@ ipforward_off ()
int ipforwarding = 0; int ipforwarding = 0;
len = sizeof ipforwarding; len = sizeof ipforwarding;
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 (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"); zlog_warn ("Can't set ipforwarding on");
return -1; return -1;
} }
if (zserv_privs.change(ZPRIVS_LOWER))
zlog (NULL, LOG_ERR, "Can't lower privileges");
return ipforwarding; return ipforwarding;
} }
@ -106,11 +121,17 @@ ipforward_ipv6 ()
int ip6forwarding = 0; int ip6forwarding = 0;
len = sizeof ip6forwarding; len = sizeof ip6forwarding;
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 (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"); zlog_warn ("can't get ip6forwarding value");
return -1; return -1;
} }
if (zserv_privs.change(ZPRIVS_LOWER))
zlog (NULL, LOG_ERR, "Can't lower privileges");
return ip6forwarding; return ip6forwarding;
} }
@ -121,11 +142,17 @@ ipforward_ipv6_on ()
int ip6forwarding = 1; int ip6forwarding = 1;
len = sizeof ip6forwarding; len = sizeof ip6forwarding;
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 (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"); zlog_warn ("can't get ip6forwarding value");
return -1; return -1;
} }
if (zserv_privs.change(ZPRIVS_LOWER))
zlog (NULL, LOG_ERR, "Can't lower privileges");
return ip6forwarding; return ip6forwarding;
} }
@ -136,11 +163,17 @@ ipforward_ipv6_off ()
int ip6forwarding = 0; int ip6forwarding = 0;
len = sizeof ip6forwarding; len = sizeof ip6forwarding;
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 (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"); zlog_warn ("can't get ip6forwarding value");
return -1; return -1;
} }
if (zserv_privs.change(ZPRIVS_LOWER))
zlog (NULL, LOG_ERR, "Can't lower privileges");
return ip6forwarding; return ip6forwarding;
} }
#endif /* HAVE_IPV6 */ #endif /* HAVE_IPV6 */

View file

@ -31,11 +31,14 @@
#include "str.h" #include "str.h"
#include "table.h" #include "table.h"
#include "rib.h" #include "rib.h"
#include "privs.h"
#include "zebra/interface.h" #include "zebra/interface.h"
#include "zebra/zserv.h" #include "zebra/zserv.h"
#include "zebra/debug.h" #include "zebra/debug.h"
extern struct zebra_privs_t zserv_privs;
/* Socket length roundup function. */ /* Socket length roundup function. */
#define ROUNDUP(a) \ #define ROUNDUP(a) \
((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long)) ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
@ -798,16 +801,23 @@ kernel_read (struct thread *thread)
void void
routing_socket () routing_socket ()
{ {
if ( zserv_privs.change (ZPRIVS_RAISE) )
zlog_err ("routing_socket: Can't raise privileges");
routing_sock = socket (AF_ROUTE, SOCK_RAW, 0); routing_sock = socket (AF_ROUTE, SOCK_RAW, 0);
if (routing_sock < 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"); zlog_warn ("Can't init kernel routing socket");
return; return;
} }
if (fcntl (routing_sock, F_SETFL, O_NONBLOCK) < 0) if (fcntl (routing_sock, F_SETFL, O_NONBLOCK) < 0)
zlog_warn ("Can't set O_NONBLOCK to routing socket"); 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. */ /* kernel_read needs rewrite. */
thread_add_read (master, kernel_read, NULL, routing_sock); thread_add_read (master, kernel_read, NULL, routing_sock);

View file

@ -1,5 +1,4 @@
/* /* zebra daemon main routine.
* zebra daemon main routine.
* Copyright (C) 1997, 98 Kunihiro Ishiguro * Copyright (C) 1997, 98 Kunihiro Ishiguro
* *
* This file is part of GNU Zebra. * This file is part of GNU Zebra.
@ -30,6 +29,7 @@
#include "memory.h" #include "memory.h"
#include "prefix.h" #include "prefix.h"
#include "log.h" #include "log.h"
#include "privs.h"
#include "zebra/rib.h" #include "zebra/rib.h"
#include "zebra/zserv.h" #include "zebra/zserv.h"
@ -62,10 +62,32 @@ struct option longopts[] =
{ "vty_addr", required_argument, NULL, 'A'}, { "vty_addr", required_argument, NULL, 'A'},
{ "vty_port", required_argument, NULL, 'P'}, { "vty_port", required_argument, NULL, 'P'},
{ "retain", no_argument, NULL, 'r'}, { "retain", no_argument, NULL, 'r'},
{ "user", required_argument, NULL, 'u'},
{ "version", no_argument, NULL, 'v'}, { "version", no_argument, NULL, 'v'},
{ 0 } { 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. */ /* Default configuration file path. */
char config_current[] = DEFAULT_CONFIG_FILE; char config_current[] = DEFAULT_CONFIG_FILE;
char config_default[] = SYSCONFDIR 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\ -A, --vty_addr Set vty's bind address\n\
-P, --vty_port Set vty's port number\n\ -P, --vty_port Set vty's port number\n\
-r, --retain When program terminates, retain added route by zebra.\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\ -v, --version Print program version\n\
-h, --help Display this help and exit\n\ -h, --help Display this help and exit\n\
\n\ \n\
@ -196,7 +219,7 @@ main (int argc, char **argv)
{ {
int opt; 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) if (opt == EOF)
break; break;
@ -239,6 +262,9 @@ main (int argc, char **argv)
case 'r': case 'r':
retain_mode = 1; retain_mode = 1;
break; break;
case 'u':
zserv_privs.user = zserv_privs.group = optarg;
break;
case 'v': case 'v':
print_version (progname); print_version (progname);
exit (0); exit (0);
@ -255,6 +281,9 @@ main (int argc, char **argv)
/* Make master thread emulator. */ /* Make master thread emulator. */
master = thread_master_create (); master = thread_master_create ();
/* privs initialise */
zprivs_init (&zserv_privs);
/* Vty related initialize. */ /* Vty related initialize. */
signal_init (); signal_init ();
cmd_init (1); cmd_init (1);

View file

@ -34,6 +34,7 @@
#include "table.h" #include "table.h"
#include "rib.h" #include "rib.h"
#include "thread.h" #include "thread.h"
#include "privs.h"
#include "zebra/zserv.h" #include "zebra/zserv.h"
#include "zebra/redistribute.h" #include "zebra/redistribute.h"
@ -67,6 +68,8 @@ struct message nlmsg_str[] =
extern int rtm_table_default; extern int rtm_table_default;
extern struct zebra_privs_t zserv_privs;
/* Make socket for Linux netlink interface. */ /* Make socket for Linux netlink interface. */
static int static int
netlink_socket (struct nlsock *nl, unsigned long groups) netlink_socket (struct nlsock *nl, unsigned long groups)
@ -98,15 +101,26 @@ netlink_socket (struct nlsock *nl, unsigned long groups)
snl.nl_groups = groups; snl.nl_groups = groups;
/* Bind the socket to the netlink structure for anything. */ /* 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); ret = bind (sock, (struct sockaddr *) &snl, sizeof snl);
if (ret < 0) 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", zlog (NULL, LOG_ERR, "Can't bind %s socket to group 0x%x: %s",
nl->name, snl.nl_groups, strerror (errno)); nl->name, snl.nl_groups, strerror (errno));
close (sock); close (sock);
return -1; return -1;
} }
if ( zserv_privs.change(ZPRIVS_LOWER) )
zlog (NULL, LOG_ERR, "Can't lower privileges");
/* multiple netlink sockets will have different nl_pid */ /* multiple netlink sockets will have different nl_pid */
namelen = sizeof snl; namelen = sizeof snl;
ret = getsockname (sock, (struct sockaddr *) &snl, &namelen); ret = getsockname (sock, (struct sockaddr *) &snl, &namelen);
@ -187,13 +201,27 @@ netlink_request (int family, int type, struct nlsock *nl)
req.nlh.nlmsg_seq = ++nl->seq; req.nlh.nlmsg_seq = ++nl->seq;
req.g.rtgen_family = family; 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, ret = sendto (nl->sock, (void*) &req, sizeof req, 0,
(struct sockaddr*) &snl, sizeof snl); (struct sockaddr*) &snl, sizeof snl);
if ( zserv_privs.change(ZPRIVS_LOWER) )
zlog (NULL, LOG_ERR, "Can't lower privileges");
if (ret < 0) if (ret < 0)
{ {
zlog (NULL, LOG_ERR, "%s sendto failed: %s", nl->name, strerror (errno)); zlog (NULL, LOG_ERR, "%s sendto failed: %s", nl->name, strerror (errno));
return -1; return -1;
} }
return 0; return 0;
} }
@ -215,8 +243,14 @@ netlink_parse_info (int (*filter) (struct sockaddr_nl *, struct nlmsghdr *),
struct msghdr msg = { (void*)&snl, sizeof snl, &iov, 1, NULL, 0, 0}; struct msghdr msg = { (void*)&snl, sizeof snl, &iov, 1, NULL, 0, 0};
struct nlmsghdr *h; struct nlmsghdr *h;
if ( zserv_privs.change(ZPRIVS_RAISE) )
zlog (NULL, LOG_ERR, "Can't raise privileges");
status = recvmsg (nl->sock, &msg, 0); status = recvmsg (nl->sock, &msg, 0);
if ( zserv_privs.change(ZPRIVS_LOWER) )
zlog (NULL, LOG_ERR, "Can't lower privileges");
if (status < 0) if (status < 0)
{ {
if (errno == EINTR) if (errno == EINTR)
@ -1104,7 +1138,12 @@ netlink_talk (struct nlmsghdr *n, struct nlsock *nl)
n->nlmsg_seq); n->nlmsg_seq);
/* Send message to netlink interface. */ /* 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); status = sendmsg (nl->sock, &msg, 0);
if ( zserv_privs.change(ZPRIVS_LOWER) )
zlog (NULL, LOG_ERR, "Can't lower privileges");
if (status < 0) if (status < 0)
{ {
zlog (NULL, LOG_ERR, "netlink_talk sendmsg() error: %s", zlog (NULL, LOG_ERR, "netlink_talk sendmsg() error: %s",

View file

@ -27,10 +27,13 @@
#include "sockunion.h" #include "sockunion.h"
#include "log.h" #include "log.h"
#include "str.h" #include "str.h"
#include "privs.h"
#include "zebra/debug.h" #include "zebra/debug.h"
#include "zebra/rib.h" #include "zebra/rib.h"
extern struct zebra_privs_t zserv_privs;
int int
rtm_write (int message, rtm_write (int message,
union sockunion *dest, union sockunion *dest,
@ -187,13 +190,29 @@ kernel_rtm_ipv4 (int cmd, struct prefix *p, struct rib *rib, int family)
int int
kernel_add_ipv4 (struct prefix *p, struct rib *rib) 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 int
kernel_delete_ipv4 (struct prefix *p, struct rib *rib) 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 #ifdef HAVE_IPV6
@ -421,13 +440,29 @@ kernel_rtm_ipv6_multipath (int cmd, struct prefix *p, struct rib *rib,
int int
kernel_add_ipv6 (struct prefix *p, struct rib *rib) 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 int
kernel_delete_ipv6 (struct prefix *p, struct rib *rib) 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. */ /* Delete IPv6 route from the kernel. */
@ -435,6 +470,14 @@ int
kernel_delete_ipv6_old (struct prefix_ipv6 *dest, struct in6_addr *gate, kernel_delete_ipv6_old (struct prefix_ipv6 *dest, struct in6_addr *gate,
int index, int flags, int table) 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 */ #endif /* HAVE_IPV6 */

View file

@ -29,11 +29,14 @@
#include "prefix.h" #include "prefix.h"
#include "linklist.h" #include "linklist.h"
#include "command.h" #include "command.h"
#include "privs.h"
#include "zebra/interface.h" #include "zebra/interface.h"
#include "zebra/rtadv.h" #include "zebra/rtadv.h"
#include "zebra/debug.h" #include "zebra/debug.h"
extern struct zebra_privs_t zserv_privs;
#if defined (HAVE_IPV6) && defined (RTADV) #if defined (HAVE_IPV6) && defined (RTADV)
/* If RFC2133 definition is used. */ /* If RFC2133 definition is used. */
@ -143,7 +146,7 @@ rtadv_send_packet (int sock, struct interface *ifp)
struct cmsghdr *cmsgptr; struct cmsghdr *cmsgptr;
struct in6_pktinfo *pkt; struct in6_pktinfo *pkt;
struct sockaddr_in6 addr; struct sockaddr_in6 addr;
#if HAVE_SOCKADDR_DL #ifdef HAVE_SOCKADDR_DL
struct sockaddr_dl *sdl; struct sockaddr_dl *sdl;
#endif /* HAVE_SOCKADDR_DL */ #endif /* HAVE_SOCKADDR_DL */
char adata [sizeof (struct cmsghdr) + sizeof (struct in6_pktinfo)]; char adata [sizeof (struct cmsghdr) + sizeof (struct in6_pktinfo)];
@ -409,8 +412,16 @@ rtadv_make_socket (void)
int ret; int ret;
struct icmp6_filter filter; 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); 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 /* When we can't make ICMPV6 socket simply back. Router
advertisement feature will not be supported. */ advertisement feature will not be supported. */
if (sock < 0) if (sock < 0)

View file

@ -33,6 +33,7 @@
#include "sockunion.h" #include "sockunion.h"
#include "log.h" #include "log.h"
#include "zclient.h" #include "zclient.h"
#include "privs.h"
#include "zebra/zserv.h" #include "zebra/zserv.h"
#include "zebra/redistribute.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); void zebra_event (enum event event, int sock, struct zserv *client);
extern struct zebra_privs_t zserv_privs;
extern struct thread_master *master; extern struct thread_master *master;
/* For logging of zebra meesages. */ /* For logging of zebra meesages. */
@ -1638,6 +1641,9 @@ zebra_serv ()
sockopt_reuseaddr (accept_sock); sockopt_reuseaddr (accept_sock);
sockopt_reuseport (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, ret = bind (accept_sock, (struct sockaddr *)&addr,
sizeof (struct sockaddr_in)); sizeof (struct sockaddr_in));
if (ret < 0) if (ret < 0)
@ -1648,6 +1654,9 @@ zebra_serv ()
return; return;
} }
if ( zserv_privs.change(ZPRIVS_LOWER) )
zlog (NULL, LOG_ERR, "Can't lower privileges");
ret = listen (accept_sock, 1); ret = listen (accept_sock, 1);
if (ret < 0) if (ret < 0)
{ {