diff common/util.c @ 644:c7a35fa302ec

Check sudo group membership if user to determine if he can elevate privileges
author Andre Heinecke <andre.heinecke@intevation.de>
date Tue, 24 Jun 2014 18:10:10 +0200
parents 78959fd970b0
children 175370634226
line wrap: on
line diff
--- a/common/util.c	Tue Jun 24 15:24:09 2014 +0200
+++ b/common/util.c	Tue Jun 24 18:10:10 2014 +0200
@@ -7,10 +7,14 @@
  */
 #include "util.h"
 #include "logging.h"
+#include "strhelp.h"
 
 #ifndef _WIN32
 #include <unistd.h>
 #include <sys/types.h>
+#include <pwd.h>
+#include <grp.h>
+#include <string.h>
 #else
 #include <windows.h>
 #endif
@@ -42,7 +46,58 @@
 bool is_admin()
 {
 #ifndef _WIN32
-  /* TODO implement */
+  struct passwd *current_user = getpwuid (geteuid());
+  int ngroups = 0,
+      ret = 0,
+      i = 0;
+  gid_t * groups = NULL;
+
+  if (current_user == NULL)
+    {
+      ERRORPRINTF ("Failed to obtain user information.");
+      return false;
+    }
+
+  ret = getgrouplist (current_user->pw_name, current_user->pw_gid, NULL,
+                      &ngroups);
+
+  if (ret != -1 || ngroups <= 0)
+    {
+      ERRORPRINTF ("Unknown error in getgrouplist call");
+      return false;
+    }
+
+  groups = xmalloc (((unsigned int)ngroups) * sizeof (gid_t));
+
+  ret = getgrouplist (current_user->pw_name, current_user->pw_gid, groups,
+                      &ngroups);
+
+  if (ret != ngroups)
+    {
+      ERRORPRINTF ("Group length mismatch.");
+      xfree (groups);
+      return false;
+    }
+
+  for (i = 0; i < ngroups; i++)
+    {
+      struct group *gr = getgrgid (groups[i]);
+      if (gr == NULL)
+        {
+          ERRORPRINTF ("Error in group enumeration");
+          xfree (groups);
+          return false;
+        }
+      if (strcmp("sudo", gr->gr_name) == 0)
+        {
+          DEBUGPRINTF ("User is in sudo group \n");
+          xfree (groups);
+          return true;
+        }
+    }
+
+  DEBUGPRINTF ("User is not in sudo group");
+
   return false;
 #else
   bool retval = false;

http://wald.intevation.org/projects/trustbridge/