summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorTimo Teräs <timo.teras@iki.fi>2015-05-22 12:40:56 +0200
committerDonald Sharp <sharpd@cumulusnetworks.com>2016-04-09 02:32:02 +0200
commit6d7578168127542e0cb9e17020bf9983dec18108 (patch)
tree001690bb751c71417ce538dfb2e1910ae07f8fe8 /lib
parentlib/privs: Don't use CAP_NET_BROADCAST (diff)
downloadfrr-6d7578168127542e0cb9e17020bf9983dec18108.tar.xz
frr-6d7578168127542e0cb9e17020bf9983dec18108.zip
privs: fix privilege dropping to use system defined groups
It may be requred for quagga process to belong to additional groups. E.g. nhrp module will need to talk to strongSwan using vici and may require additional permissions. Initialize groups from the system group database. Signed-off-by: Timo Teräs <timo.teras@iki.fi> Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
Diffstat (limited to 'lib')
-rw-r--r--lib/privs.c66
1 files changed, 47 insertions, 19 deletions
diff --git a/lib/privs.c b/lib/privs.c
index 8cfd8dfd5..ff0be2fe1 100644
--- a/lib/privs.c
+++ b/lib/privs.c
@@ -627,6 +627,8 @@ zprivs_init(struct zebra_privs_t *zprivs)
{
struct passwd *pwentry = NULL;
struct group *grentry = NULL;
+ gid_t groups[NGROUPS_MAX];
+ int i, ngroups = 0;
if (!zprivs)
{
@@ -645,33 +647,59 @@ zprivs_init(struct zebra_privs_t *zprivs)
if (zprivs->user)
{
- if ( (pwentry = getpwnam (zprivs->user)) )
- {
- zprivs_state.zuid = pwentry->pw_uid;
- }
- else
+ if ( (pwentry = getpwnam (zprivs->user)) == NULL )
{
/* cant use log.h here as it depends on vty */
fprintf (stderr, "privs_init: could not lookup user %s\n",
zprivs->user);
exit (1);
}
+
+ zprivs_state.zuid = pwentry->pw_uid;
+ zprivs_state.zgid = pwentry->pw_gid;
}
grentry = NULL;
+ if (zprivs->group)
+ {
+ if ( (grentry = getgrnam (zprivs->group)) == NULL )
+ {
+ fprintf (stderr, "privs_init: could not lookup group %s\n",
+ zprivs->group);
+ exit (1);
+ }
+
+ zprivs_state.zgid = grentry->gr_gid;
+ }
+
+ if (zprivs->user)
+ {
+ ngroups = sizeof(groups);
+ if ( (ngroups = getgrouplist (zprivs->user, zprivs_state.zgid, groups, &ngroups )) < 0 )
+ {
+ /* cant use log.h here as it depends on vty */
+ fprintf (stderr, "privs_init: could not getgrouplist for user %s\n",
+ zprivs->user);
+ exit (1);
+ }
+ }
+
if (zprivs->vty_group)
/* Add the vty_group to the supplementary groups so it can be chowned to */
{
if ( (grentry = getgrnam (zprivs->vty_group)) )
{
zprivs_state.vtygrp = grentry->gr_gid;
- if ( setgroups (1, &zprivs_state.vtygrp) )
+
+ for ( i = 0; i < ngroups; i++ )
+ if ( groups[i] == zprivs_state.vtygrp )
+ break;
+
+ if ( i >= ngroups && ngroups < (int) ZEBRA_NUM_OF(groups) )
{
- fprintf (stderr, "privs_init: could not setgroups, %s\n",
- safe_strerror (errno) );
- exit (1);
- }
+ groups[i] = zprivs_state.vtygrp;
+ }
}
else
{
@@ -680,19 +708,19 @@ zprivs_init(struct zebra_privs_t *zprivs)
exit (1);
}
}
-
- if (zprivs->group)
+
+ if (ngroups)
{
- if ( (grentry = getgrnam (zprivs->group)) )
+ if ( setgroups (ngroups, groups) )
{
- zprivs_state.zgid = grentry->gr_gid;
- }
- else
- {
- fprintf (stderr, "privs_init: could not lookup group %s\n",
- zprivs->group);
+ fprintf (stderr, "privs_init: could not setgroups, %s\n",
+ safe_strerror (errno) );
exit (1);
}
+ }
+
+ if (zprivs_state.zgid)
+ {
/* change group now, forever. uid we do later */
if ( setregid (zprivs_state.zgid, zprivs_state.zgid) )
{