]> git.puffer.fish Git - matthieu/frr.git/commitdiff
privs: fix privilege dropping to use system defined groups
authorTimo Teräs <timo.teras@iki.fi>
Fri, 22 May 2015 10:40:56 +0000 (13:40 +0300)
committerDonald Sharp <sharpd@cumulusnetworks.com>
Sat, 9 Apr 2016 00:32:02 +0000 (20:32 -0400)
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>
lib/privs.c

index 8cfd8dfd5e401154a1125858c14fb7e8712964ad..ff0be2fe128bc044fa1f91d721410c63ed5e13ab 100644 (file)
@@ -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) )
         {