2016-10-17 3 views
4

Ich teste den folgenden Code in C mit Win32 API, die eine neue Datei erstellen soll, die für den aktuellen Benutzer zugänglich ist, aber privat (nicht zugänglich) für alle anderen.Win32-API: Erstellen einer öffentlichen Datei für den aktuellen Benutzer, aber privat für alle anderen

Dazu eine Berechtigung alle Berechtigungen für alle SID verweigern, dann für aktuelle Benutzer SID ich die Berechtigungen einrichten.

Die Datei wurde erfolgreich erstellt und die Berechtigungen sind scheinbar erfolgreich eingerichtet (siehe Screenshots unten), aber wenn ich versuche, die Datei mit Notepad zu öffnen, heißt es "Zugriff verweigert" (Meine Datei Explorer läuft unter dem gleichen Sitzung), auch wenn ich eine Eingabeaufforderung öffnen und "file_created.txt" eingeben, wird der gleiche "Zugriff verweigert" angezeigt.

Ich kann natürlich die Berechtigungen manuell wiederherstellen, da ich Administrator bin, aber die Idee ist, es programmatisch arbeiten zu lassen.

Bild mit allen Berechtigungen: enter image description here

Bild mit aktuellen Benutzerberechtigungen: enter image description here

Der Code:

#include <windows.h> 
#include <AccCtrl.h> 
#include <aclapi.h> 

#include <stdio.h> 
#include <stdexcept> 
#include <string> 

#undef UNICODE 

int GetCurrentUserSid(PSID* pSID) 
{ 
    const int MAX_NAME = 256; 
    DWORD i, dwSize = 0; 
    HANDLE hToken; 
    PTOKEN_USER user; 
    TOKEN_INFORMATION_CLASS TokenClass = TokenUser; 

    if (!OpenProcessToken(GetCurrentProcess(), TOKEN_READ | TOKEN_QUERY, &hToken)) 
    return GetLastError(); 
    else 
    wprintf(L"OpenProcessToken() - got the handle to the access token!\n"); 

    if (!GetTokenInformation(hToken, TokenClass, NULL, 0, &dwSize)) 
    { 
    DWORD dwResult = GetLastError(); 
    if (dwResult != ERROR_INSUFFICIENT_BUFFER) 
    { 
     wprintf(L"GetTokenInformation() failed, error %u\n", dwResult); 
     return FALSE; 
    } 
    else 
     wprintf(L"GetTokenInformation() - have an ample buffer...\n"); 
    } 
    else 
    wprintf(L"GetTokenInformation() - buffer for Token group is OK\n"); 

    user = (PTOKEN_USER)LocalAlloc(GPTR, dwSize); 
    if (!GetTokenInformation(hToken, TokenClass, user, dwSize, &dwSize)) 
    { 
    wprintf(L"GetTokenInformation() failed, error %u\n", GetLastError()); 
    return FALSE; 
    } 
    else 
    wprintf(L"GetTokenInformation() for getting the TokenGroups is OK\n"); 

    DWORD dw_sid_len = GetLengthSid(user->User.Sid); 
    *pSID = (SID*)LocalAlloc(GPTR, dw_sid_len); 
    CopySid(dw_sid_len, *pSID, user->User.Sid); 
    return 0; 
} 

DWORD set_file_security(LPSTR filename) 
{ 
    PACL pNewDACL = NULL; 
    PSID current_user = NULL; 
    DWORD sid_size = SECURITY_MAX_SID_SIZE; 
    SID everyone_sid; 
    DWORD dwRes; 
    if (CreateWellKnownSid(WinWorldSid, NULL, &everyone_sid, &sid_size) == 
    FALSE) { 
    throw std::runtime_error("CreateWellKnownSid() failed: " + 
     std::to_string(GetLastError())); 
    } 

    GetCurrentUserSid(&current_user); 

    EXPLICIT_ACCESSA ea[2]; 
    ZeroMemory(&ea, 2 * sizeof(EXPLICIT_ACCESSA)); 

    ea[0].grfAccessPermissions = ACCESS_SYSTEM_SECURITY | READ_CONTROL | WRITE_DAC | GENERIC_ALL; 
    ea[0].grfAccessMode = GRANT_ACCESS; 
    ea[0].grfInheritance = NO_INHERITANCE; 
    ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID; 
    ea[0].Trustee.ptstrName = reinterpret_cast<char*>(current_user); 

    ea[1].grfAccessPermissions = ACCESS_SYSTEM_SECURITY | READ_CONTROL | WRITE_DAC | GENERIC_ALL; 
    ea[1].grfAccessMode = DENY_ACCESS; 
    ea[1].grfInheritance = NO_INHERITANCE; 
    ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID; 
    ea[1].Trustee.ptstrName = reinterpret_cast<char*>(&everyone_sid); 

    dwRes = SetEntriesInAclA(2, ea, NULL, &pNewDACL); 
    if (ERROR_SUCCESS != dwRes) { 
    printf("SetEntriesInAcl Error %u\n", dwRes); 
    //TODO: goto Cleanup; 
    } 

    PSECURITY_DESCRIPTOR pSD = NULL; 

    // Initialize a security descriptor. 
    pSD = (PSECURITY_DESCRIPTOR)LocalAlloc(LPTR, 
    SECURITY_DESCRIPTOR_MIN_LENGTH); 
    if (NULL == pSD) 
    { 
    _tprintf(_T("LocalAlloc Error %u\n"), GetLastError()); 
    goto Cleanup; 
    } 

    if (!InitializeSecurityDescriptor(pSD, 
    SECURITY_DESCRIPTOR_REVISION)) 
    { 
    _tprintf(_T("InitializeSecurityDescriptor Error %u\n"), 
     GetLastError()); 
    goto Cleanup; 
    } 

    // Add the ACL to the security descriptor. 
    if (!SetSecurityDescriptorDacl(pSD, 
    TRUE,  // bDaclPresent flag 
    pNewDACL, 
    FALSE)) // not a default DACL 
    { 
    _tprintf(_T("SetSecurityDescriptorDacl Error %u\n"), 
     GetLastError()); 
    goto Cleanup; 
    } 
    SECURITY_ATTRIBUTES sa; 
    // Initialize a security attributes structure. 
    sa.nLength = sizeof(SECURITY_ATTRIBUTES); 
    sa.lpSecurityDescriptor = pSD; 
    sa.bInheritHandle = FALSE; 

    HANDLE hFile = CreateFileA(filename, GENERIC_ALL, 0, &sa, CREATE_NEW, FILE_ATTRIBUTE_NORMAL, NULL); 
    CloseHandle(hFile); 

    //dwRes = SetNamedSecurityInfoA(filename, SE_FILE_OBJECT, 
    // DACL_SECURITY_INFORMATION, NULL, NULL, pNewDACL, NULL); 
    //if (ERROR_SUCCESS != dwRes) { 
    // printf("SetNamedSecurityInfo Error %u\n", dwRes); 
    // //goto Cleanup; 
    //} 

Cleanup: 

    if (pNewDACL != NULL) 
    LocalFree((HLOCAL)pNewDACL); 

    return dwRes; 
} 

int main() 
{ 
    //return 0; 

    // Create Everyone SID. 
    DWORD sid_size = SECURITY_MAX_SID_SIZE; 
    SID everyone_sid; 
    if (CreateWellKnownSid(WinWorldSid, NULL, &everyone_sid, &sid_size) == 
    FALSE) { 
    throw std::runtime_error("CreateWellKnownSid() failed: " + 
     std::to_string(GetLastError())); 
    } 

    LPSTR filename = "created_file.txt"; 

    set_file_security(filename); 

    return 0; 
} 

HINWEIS: erkannte ich die Codespeicherlecks und andere Fragen hat, Ich hackte nur schnell, um die Idee zu testen.

Antwort

6

Im Windows-Betriebssystem haben explizite Verweigerungsrechte Vorrang vor expliziten Erlauben-Berechtigungen. Da die Gruppe "Jeder" Ihr Konto enthält, wird der Zugriff auf die Datei verweigert, selbst wenn Sie sie selbst aktiviert haben. In der Tat brauchen Sie die Deny-Regel überhaupt nicht, wenn Zugriffsrechte für einen Benutzer in der Objekt-ACL nicht gesetzt sind, wird der Zugriff standardmäßig verweigert.

+0

Sie Sr waren völlig richtig, ich entfernte die Einstellungen für alle im Code und funktioniert jetzt wie erwartet, danke! –

Verwandte Themen