changeset 505:78959fd970b0

Add is_admin and implement it for windows
author Andre Heinecke <aheinecke@intevation.de>
date Mon, 28 Apr 2014 09:19:53 +0000
parents 3cf72c5282e8
children bfcfbae151ab
files common/util.c common/util.h
diffstat 2 files changed, 98 insertions(+), 0 deletions(-) [+]
line wrap: on
line diff
--- a/common/util.c	Mon Apr 28 09:19:29 2014 +0000
+++ b/common/util.c	Mon Apr 28 09:19:53 2014 +0000
@@ -6,6 +6,8 @@
  * See LICENSE.txt for details.
  */
 #include "util.h"
+#include "logging.h"
+
 #ifndef _WIN32
 #include <unistd.h>
 #include <sys/types.h>
@@ -36,3 +38,82 @@
 #endif
   return ret;
 }
+
+bool is_admin()
+{
+#ifndef _WIN32
+  /* TODO implement */
+  return false;
+#else
+  bool retval = false;
+  BOOL in_admin_group = FALSE;
+  HANDLE hToken = NULL;
+  HANDLE hTokenToCheck = NULL;
+  DWORD cbSize = 0;
+  TOKEN_ELEVATION_TYPE elevation;
+  BYTE admin_id[SECURITY_MAX_SID_SIZE];
+
+  if (!OpenProcessToken(GetCurrentProcess(),
+                        TOKEN_QUERY | TOKEN_DUPLICATE, &hToken))
+    {
+      PRINTLASTERROR ("Failed to duplicate process token.\n");
+      return false;
+    }
+
+  if (!GetTokenInformation(hToken, TokenElevationType, &elevation,
+                           sizeof(elevation), &cbSize))
+    {
+      PRINTLASTERROR ("Failed to get token information.\n");
+      goto done;
+    }
+
+  /* If limited check the the linked token instead */
+  if (TokenElevationTypeLimited == elevation)
+    {
+      if (!GetTokenInformation(hToken, TokenLinkedToken, &hTokenToCheck,
+                               sizeof(hTokenToCheck), &cbSize))
+        {
+          PRINTLASTERROR ("Failed to get the linked token.\n");
+          goto done;
+        }
+    }
+
+  if (!hTokenToCheck) /* The linked token is already of the correct type */
+    {
+      if (!DuplicateToken(hToken, SecurityIdentification, &hTokenToCheck))
+        {
+          PRINTLASTERROR ("Failed to duplicate token for identification.\n");
+          goto done;
+        }
+    }
+
+  /* Do the sid dance for the adminSID */
+  cbSize = sizeof(admin_id);
+  if (!CreateWellKnownSid(WinBuiltinAdministratorsSid, NULL, &admin_id,
+                          &cbSize))
+    {
+      PRINTLASTERROR ("Failed to get admin sid.\n");
+      goto done;
+    }
+
+  /* The actual check */
+  if (!CheckTokenMembership(hTokenToCheck, &admin_id, &in_admin_group))
+    {
+      PRINTLASTERROR ("Failed to check token membership.\n");
+      goto done;
+    }
+
+  if (in_admin_group)
+    {
+      /* Winbool to standard bool */
+      retval = true;
+    }
+
+done:
+  if (hToken) CloseHandle(hToken);
+  if (hTokenToCheck) CloseHandle(hTokenToCheck);
+
+  return retval;
+#endif
+}
+
--- a/common/util.h	Mon Apr 28 09:19:29 2014 +0000
+++ b/common/util.h	Mon Apr 28 09:19:53 2014 +0000
@@ -12,6 +12,10 @@
  */
 #include <stdbool.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 /**@brief Check if the current process is running with elevated privileges.
  *
  * Elevates the current process token to check if it is marked as elevated.
@@ -20,4 +24,17 @@
  * @returns true if the current process is elevated.*/
 bool is_elevated();
 
+/**@brief Check if the user is in the administrators group.
+ *
+ * The function checks if the account that startet this process
+ * belongs to a user that is a member of the Administrators group.
+ *
+ * @returns True if the user is in the admin group. False otherwise or on error.
+ */
+bool is_admin();
+
+#ifdef __cplusplus
+}
+#endif
+
 #endif // COMMON_UTIL_H

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