# HG changeset patch # User Andre Heinecke # Date 1398676793 0 # Node ID 78959fd970b06fcb275013f4f1931b7f9f1550d5 # Parent 3cf72c5282e8011f9edb268a6b27ad3061a4f10f Add is_admin and implement it for windows diff -r 3cf72c5282e8 -r 78959fd970b0 common/util.c --- 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 #include @@ -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 +} + diff -r 3cf72c5282e8 -r 78959fd970b0 common/util.h --- 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 +#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