2016-10-17 3 views
4

현재 사용자는 액세스 할 수 있지만 액세스 할 수는없는 새 파일을 만들려는 Win32 API를 사용하여 C에서 다음 코드를 테스트하고 있습니다. 다른 사람들에게.Win32 API : 현재 사용자는 공개하지만 다른 사용자는 비공개 파일을 만듭니다.

모든 사용자의 SID에 대한 모든 사용 권한을 거부하고 현재 사용자의 SID에 대해 사용 권한을 설정합니다.

파일이 성공적으로 만들어졌으며 사용 권한이 분명하게 성공적으로 설정되었습니다 (아래 스크린 샷 참조). 그러나 메모장에서 파일을 열려고하면 "액세스가 거부되었습니다"라고 표시됩니다 (내 파일 탐색기가 동일한 파일로 실행 중임). 세션), 또한 내가 명령 프롬프트를 열고 "file_created.txt"를 입력하면 "액세스가 거부되었습니다"와 같은 메시지가 나타납니다.

저는 관리자이기 때문에 수동으로 권한을 복원 할 수 있지만 아이디어는 프로그래밍 방식으로 작동하도록 만드는 것입니다. 모든 권한을 가진

이미지 : 현재 사용자 권한이있는 enter image description here

이미지 : enter image description here

코드 :

#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; 
} 

참고 : 나는 코드가 메모리 누수 등의 문제가 실현 나는 그 아이디어를 테스트하기 위해 해킹하고 있었다.

답변

6

Windows OS에서 명시 적 거부 권한은 명시 적 허용 권한보다 우선합니다. 따라서 "Everyone"그룹에는 귀하의 계정이 포함되어 있으므로 직접 사용하도록 설정 한 경우에도 파일에 대한 액세스가 거부됩니다. 실제로 규칙을 모두 거부 할 필요가없는 경우 일부 사용자의 액세스 권한이 객체 ACL에 설정되어 있지 않으면 액세스가 기본적으로 거부됩니다.

+0

당신은 Sr이 완전히 옳았습니다. 코드의 모든 사람들을위한 설정을 제거했으며, 예상대로 작동합니다. 감사합니다! –