최신목록

2016년 2월 4일 목요일

[WIN32]Security Descriptor 생성(Users 그룹 권한 변경)

service에서 파일을 생성했는데 user 계정으로 로그인해서 파일 write를 하려니 access denied가 떴다. 이유는 파일의 보안 권한 때문! 파일 속성의 보안탭에서 권한을 추가해주면 잘 동작한다. 하지만 내가 만든 파일인데...권한을 상속받지 않고 내가 마음대로 주려면..어찌해야하는가....SD(Security Descriptor)를 만들어서 적용해주면 된다.

1. 원하는 계정의 SID(Security Identifier) 생성(AllocateAndInitializeSid)
2. SID마다 부여한 권한정보를 담고 있는 EXPLICIT_ACCESS를 각각 만듬.
3. EXPLICIT_ACCESS 를 적용한 ACL(access control list)을 생성한다.(SetEntriesInAcl)
4. 새로운 Security Descriptor를 생성한다.(InitializeSecurityDescriptor)
5. 생성한 ACL을 SD에 적용한다.(SetSecurityDescriptorDacl)
6. 생성한 SD를 가지고 CreateFile등에 사용한다.

SD가 NULL인 상태로 CreateFile을 이용해서 파일생성시 Users에게 부여된 권한은 아래와 같았다.


Users 권한에 대한 쓰기 권한이 제한되어 있음을 볼 수 있다.

아래는 EveryOne과 Users 그룹 Administrators 그룹에 대한 권한 설정한 샘플 소스이다.


#include 
#include 
#pragma comment(lib, "advapi32.lib")

BOOL makepSD(PSECURITY_DESCRIPTOR pSD)
{
    DWORD dwRes;
    PSID pEveryoneSID = NULL, pAdminSID = NULL, pUserSID;
    EXPLICIT_ACCESS ea[3];
    SID_IDENTIFIER_AUTHORITY SIDAuthWorld = SECURITY_WORLD_SID_AUTHORITY;
    SID_IDENTIFIER_AUTHORITY SIDAuthNT = SECURITY_NT_AUTHORITY;
 
    PACL pACL = NULL;

    if(!AllocateAndInitializeSid(&SIDAuthWorld, 1,
        SECURITY_WORLD_RID,
        0,0,0,0,0,0,0,
        &pEveryoneSID))
       {
           _tprintf(_T("AllocateAndInitializeSid Error %u\n"), GetLastError());
           goto CleanUp;
       }

    ea[0].grfAccessPermissions = GENERIC_READ;
    ea[0].grfAccessMode = SET_ACCESS;
    ea[0].grfInheritance = NO_INHERITANCE;
    ea[0].Trustee.TrusteeForm = TRUSTEE_IS_SID;
    ea[0].Trustee.TrusteeType = TRUSTEE_IS_USER;
    ea[0].Trustee.ptstrName = (LPTSTR)pEveryoneSID;

    if(!AllocateAndInitializeSid(&SIDAuthNT, 2,
        SECURITY_BUILTIN_DOMAIN_RID,
        DOMAIN_ALIAS_RID_ADMINS,
        0,0,0,0,0,0,
        &pAdminSID))
       {
           _tprintf(_T("AllocateAndInitializeSid Error %u\n"), GetLastError());
           goto CleanUp;
       }

    ea[1].grfAccessPermissions = GENERIC_ALL;
    ea[1].grfAccessMode = SET_ACCESS;
    ea[1].grfInheritance = NO_INHERITANCE;
    ea[1].Trustee.TrusteeForm = TRUSTEE_IS_SID;
    ea[1].Trustee.TrusteeType = TRUSTEE_IS_GROUP;
    ea[1].Trustee.ptstrName = (LPTSTR)pAdminSID;

    if(!AllocateAndInitializeSid(&SIDAuthNT, 2,
        SECURITY_BUILTIN_DOMAIN_RID,
        DOMAIN_ALIAS_RID_USERS,
        0,0,0,0,0,0,
        &pUserSID))
       {
           _tprintf(_T("AllocateAndInitializeSid Error %u\n"), GetLastError());
           goto CleanUp;
       }

    ea[2].grfAccessPermissions = GENERIC_READ | GENERIC_WRITE;
    ea[2].grfAccessMode = SET_ACCESS;
    ea[2].grfInheritance = NO_INHERITANCE;
    ea[2].Trustee.TrusteeForm = TRUSTEE_IS_SID;
    ea[2].Trustee.TrusteeType = TRUSTEE_IS_GROUP;
    ea[2].Trustee.ptstrName = (LPTSTR)pUserSID;

    dwRes = SetEntriesInAcl(3, ea, NULL, &pACL);
    if(dwRes != ERROR_SUCCESS)
    {
        _tprintf(_T("SetEntriesInAcl Error %u\n"), GetLastError());
        goto CleanUp;
    }

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

    if(!SetSecurityDescriptorDacl(pSD, TRUE, pACL, FALSE))
    {
        _tprintf(_T("SetSecurityDescriptorDacl Error %u\n"), GetLastError());
        goto CleanUp;
    }
    return TRUE;

CleanUp:
    if(pAdminSID)
        FreeSid(pAdminSID);
    if(pEveryoneSID)
        FreeSid(pEveryoneSID);
    if(pUserSID)
        FreeSid(pUserSID);
    return FALSE;
}


위와 같이 생성된 SD를 적용하여 파일을 생성하였을때 부여된 권한은 아래와 같습니다.


쓰기 읽기 권한이 모두 주어진것을 볼 수 있습니다.

댓글 없음:

댓글 쓰기