M
Ich hab meinen Code jetzt nochmal überarbeitet und eine Funktion für das Auslesen der Gruppenzugehörigkeit erstellt. Die Angelegenheit mit der ACCESS_MASK-Struktur ist wirklich nicht sehr verlässlich, da es zum Einen unter FAT32 natürlich nicht funktioniert und auch nicht die absolut effektiven Rechte ermittelt sondern die impliziten Rechte, die ein Administrator besitzt oder geerbt hat, auch außer Acht lässt(wie zum Beispiel WRITE_OWNER oder DELETE). Wenn du die zu überprüfende Gruppe ändern willst, dass sie zum Beispiel auf "Hauptbenutzer" überprüft, ändere einfach DOMAIN_ALIAS_RID_[...] in die entsprechende Konstante.
#include <iostream>
#include <windows.h>
#include <conio.h>
#include <Accctrl.h>
#include <Aclapi.h>
BOOL IsAdmin(PBOOL pbresult) {
DWORD dwbufsize = 0;
BOOL bSuccess = FALSE;
PTOKEN_GROUPS grouplist = NULL;
HANDLE hAccessToken = NULL;
PSID pSID = NULL;
*pbresult = FALSE;
SID_IDENTIFIER_AUTHORITY auth = SECURITY_NT_AUTHORITY;
//Prozesstoken öffnen
if(!OpenProcessToken(GetCurrentProcess(),TOKEN_QUERY,&hAccessToken)) {
goto exit;
}
//Gruppenliste des Tokens abrufen
if (!GetTokenInformation(hAccessToken,TokenGroups,grouplist,0,&dwbufsize)) {
if (GetLastError()!=ERROR_INSUFFICIENT_BUFFER) {
goto exit;
}
grouplist = (PTOKEN_GROUPS) new CHAR[dwbufsize];
if (!GetTokenInformation(hAccessToken,TokenGroups,grouplist,dwbufsize,&dwbufsize)) {
goto exit;
}
} else {
goto exit;
}
//SID erzeugen, die die gewünschte Gruppe repräsentiert
if (!AllocateAndInitializeSid(&auth,2,SECURITY_BUILTIN_DOMAIN_RID,DOMAIN_ALIAS_RID_ADMINS,0,0,0,0,0,0,&pSID)) {
goto exit;
}
//Prüfen, ob die gewünschte Gruppe in der Gruppenliste des Tokens enthalten ist
for (UINT i=0;i<grouplist->GroupCount;i++) {
if (EqualSid(grouplist->Groups[i].Sid,pSID)) {
*pbresult = TRUE;
bSuccess = TRUE;
goto exit;
}
}
exit:
if (grouplist) {delete[] grouplist;}
if (hAccessToken) {CloseHandle(hAccessToken);}
if (pSID) {FreeSid(pSID);}
#if defined(_DEBUG) && defined(_CONSOLE)
if (!bSuccess) {std::cout << "Fehler beim Aufruf von " __FUNCTION__ " - Fehlercode:" << GetLastError();}
#endif
return bSuccess;
}
BOOL GetEffectiveFileAccessMask(LPCTSTR file,PACCESS_MASK pmask) {
DWORD dwRet = 0;
DWORD dwbufsize = 0;
BOOL bSuccess = FALSE;
PCHAR secdesc = NULL;
TRUSTEE tr;
PACL acl = NULL;
HANDLE hAccessToken;
BOOL isdefaultedacl = FALSE;
BOOL isdaclpresent = FALSE;
PTOKEN_USER pTu = NULL;
ZeroMemory(&tr,sizeof(TRUSTEE));
ZeroMemory(pmask,sizeof(ACCESS_MASK));
//Security Descriptor abfragen
if (!GetFileSecurity(file,DACL_SECURITY_INFORMATION,secdesc,0,&dwbufsize)) {
if (GetLastError()!=ERROR_INSUFFICIENT_BUFFER) {
goto exit;
}
secdesc = new CHAR[dwbufsize];
if (!GetFileSecurity(file,DACL_SECURITY_INFORMATION,secdesc,dwbufsize,&dwbufsize)) {
goto exit;
}
} else {
goto exit;
}
//DACL aus dem Security Descriptor erhalten
if (!GetSecurityDescriptorDacl(secdesc,&isdaclpresent,&acl,&isdefaultedacl)) {
goto exit;
}
if (!isdaclpresent) {
//Wo ist sie hin? :-)
goto exit;
}
//Prozesstoken öffnen
if(!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY,&hAccessToken)) {
goto exit;
}
//TokenUser abfragen
if (!GetTokenInformation(hAccessToken, TokenUser, pTu, 0, &dwbufsize)) {
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
goto exit;
}
pTu = (PTOKEN_USER) new CHAR[dwbufsize];
if (!GetTokenInformation(hAccessToken, TokenUser, pTu,dwbufsize, &dwbufsize)) {
goto exit;
}
}
//Trustee initialisieren
tr.TrusteeForm = TRUSTEE_IS_SID;
tr.TrusteeType = TRUSTEE_IS_USER;
tr.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
tr.pMultipleTrustee = NULL;
tr.ptstrName = (LPSTR)(pTu->User.Sid);
//Effektive Rechte des Trustees gemäß ACL erhalten
if (GetEffectiveRightsFromAcl(acl ,&tr, pmask) != ERROR_SUCCESS) {
goto exit;
}
bSuccess = TRUE;
exit:
if (hAccessToken) {CloseHandle(hAccessToken);}
if (secdesc) {delete[] secdesc;}
if (pTu) {delete[] pTu;}
#if defined(_DEBUG) && defined(_CONSOLE)
if (!bSuccess) {std::cout << "Fehler beim Aufruf von " __FUNCTION__ " - Fehlercode:" << GetLastError();}
#endif
return bSuccess;
}
int main() {
BOOL isadmin = FALSE;
if(IsAdmin(&isadmin)) {
std::cout << "Aktueller Benutzer ist ein Administrator: " << (isadmin ? "ja" : "nein");
}
getch();
return 0;
}