Mercurial > trustbridge
view common/util.c @ 677:85c5aa9aba2b
Improve error handling and use unicode function for unload
author | Andre Heinecke <andre.heinecke@intevation.de> |
---|---|
date | Mon, 30 Jun 2014 11:26:05 +0200 |
parents | 4ad764bfb39c |
children | 216a65d7fc4b |
line wrap: on
line source
/* Copyright (C) 2014 by Bundesamt für Sicherheit in der Informationstechnik * Software engineering by Intevation GmbH * * This file is Free Software under the GNU GPL (v>=2) * and comes with ABSOLUTELY NO WARRANTY! * See LICENSE.txt for details. */ #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 #ifdef WIN32 char * get_install_dir() { wchar_t wPath[MAX_PATH]; char *utf8path = NULL; char *dirsep = NULL; if (!GetModuleFileNameW (NULL, wPath, MAX_PATH - 1)) { PRINTLASTERROR ("Failed to obtain module file name. Path too long?"); return NULL; } /* wPath might not be 0 terminated */ wPath[MAX_PATH - 1] = '\0'; utf8path = wchar_to_utf8 (wPath, wcsnlen(wPath, MAX_PATH)); if (utf8path == NULL) { ERRORPRINTF ("Failed to convert module path to utf-8"); return NULL; } /* Cut away the executable name */ dirsep = strrchr(utf8path, '\\'); if (dirsep == NULL) { ERRORPRINTF ("Failed to find directory seperator."); return NULL; } *dirsep = '\0'; return utf8path; } static PSID copy_sid(PSID from) { if (!from) { return 0; } DWORD sidLength = GetLengthSid(from); PSID to = (PSID) xmalloc(sidLength); CopySid(sidLength, to, from); return to; } PSID get_process_owner(HANDLE hProcess) { HANDLE hToken = NULL; PSID sid; if (hProcess == NULL) { ERRORPRINTF ("invalid call to get_process_owner"); return NULL; } OpenProcessToken(hProcess, TOKEN_READ, &hToken); if (hToken) { DWORD size = 0; PTOKEN_USER userStruct; // check how much space is needed GetTokenInformation(hToken, TokenUser, NULL, 0, &size); if (ERROR_INSUFFICIENT_BUFFER == GetLastError()) { userStruct = (PTOKEN_USER) xmalloc (size); GetTokenInformation(hToken, TokenUser, userStruct, size, &size); sid = copy_sid(userStruct->User.Sid); CloseHandle(hToken); xfree (userStruct); return sid; } } return NULL; } #endif bool is_elevated() { bool ret = false; #ifndef _WIN32 ret = (geteuid() == 0); #else HANDLE hToken = NULL; if (OpenProcessToken (GetCurrentProcess(), TOKEN_QUERY, &hToken)) { DWORD elevation; DWORD cbSize = sizeof (DWORD); if (GetTokenInformation (hToken, TokenElevation, &elevation, sizeof (TokenElevation), &cbSize)) { ret = elevation; } } if (hToken) CloseHandle (hToken); #endif return ret; } bool is_admin() { #ifndef _WIN32 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; 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 }