DACL 만들기

적절한 DACL(임의 액세스 제어 목록 )을 만드는 것은 애플리케이션 개발에서 필요하고 중요한 부분입니다. NULL DACL은 모든 사용자에 대한 모든 유형의 액세스를 허용하므로 NULL DACL을 사용하지 마세요.

다음 예제에서는 DACL을 올바르게 만드는 방법을 보여줍니다. 이 예제에는 SDDL( 보안 설명자 정의 언어 )을 사용하여 DACL에서 부여되고 거부된 액세스 제어를 정의하는 함수 CreateMyDACL이 포함되어 있습니다. 애플리케이션의 개체에 대한 다른 액세스를 제공하려면 필요에 따라 CreateMyDACL 함수를 수정합니다.

예제:

  1. main 함수는 SECURITY_ATTRIBUTES 구조체의 주소를 CreateMyDACL 함수에 전달합니다.

  2. CreateMyDACL 함수는 SDDL 문자열을 사용하여 다음을 수행합니다.

    • 게스트 및 익명 로그온 사용자에 대한 액세스를 거부합니다.
    • 인증된 사용자에 대한 읽기/쓰기/실행 액세스를 허용합니다.
    • 관리자에게 모든 권한을 허용합니다.

    SDDL 문자열 형식에 대한 자세한 내용은 보안 설명자 문자열 형식을 참조하세요.

  3. CreateMyDACL 함수는 ConvertStringSecurityDescriptorToSecurityDescriptor 함수를 호출하여 SDDL 문자열을 보안 설명자로 변환합니다. 보안 설명자는 SECURITY_ATTRIBUTES 구조체의 lpSecurityDescriptor 멤버가 가리켰습니다. CreateMyDACL은 ConvertStringSecurityDescriptorToSecurityDescriptor 에서 기본 함수로 반환 값을 보냅니다.

  4. main 함수는 업데이트된 SECURITY_ATTRIBUTES 구조를 사용하여 CreateDirectory 함수에서 만든 새 폴더에 대한 DACL을 지정합니다.

  5. main 함수가 SECURITY_ATTRIBUTES 구조체를 사용하여 완료되면 main 함수는 LocalFree 함수를 호출하여 lpSecurityDescriptor 멤버에 할당된 메모리를 해제합니다.

참고

ConvertStringSecurityDescriptorToSecurityDescriptor와 같은 SDDL 함수를 성공적으로 컴파일하려면 _WIN32_WINNT 상수는 0x0500 이상으로 정의해야 합니다.

 

#define _WIN32_WINNT 0x0500

#include <windows.h>
#include <sddl.h>
#include <stdio.h>

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

BOOL CreateMyDACL(SECURITY_ATTRIBUTES *);

void main()
{
     SECURITY_ATTRIBUTES  sa;
      
     sa.nLength = sizeof(SECURITY_ATTRIBUTES);
     sa.bInheritHandle = FALSE;  

     // Call function to set the DACL. The DACL
     // is set in the SECURITY_ATTRIBUTES 
     // lpSecurityDescriptor member.
     if (!CreateMyDACL(&sa))
     {
         // Error encountered; generate message and exit.
         printf("Failed CreateMyDACL\n");
         exit(1);
     }

     // Use the updated SECURITY_ATTRIBUTES to specify
     // security attributes for securable objects.
     // This example uses security attributes during
     // creation of a new directory.
     if (0 == CreateDirectory(TEXT("C:\\MyFolder"), &sa))
     {
         // Error encountered; generate message and exit.
         printf("Failed CreateDirectory\n");
         exit(1);
     }

     // Free the memory allocated for the SECURITY_DESCRIPTOR.
     if (NULL != LocalFree(sa.lpSecurityDescriptor))
     {
         // Error encountered; generate message and exit.
         printf("Failed LocalFree\n");
         exit(1);
     }
}


// CreateMyDACL.
//    Create a security descriptor that contains the DACL 
//    you want.
//    This function uses SDDL to make Deny and Allow ACEs.
//
// Parameter:
//    SECURITY_ATTRIBUTES * pSA
//    Pointer to a SECURITY_ATTRIBUTES structure. It is your
//    responsibility to properly initialize the 
//    structure and to free the structure's 
//    lpSecurityDescriptor member when you have
//    finished using it. To free the structure's 
//    lpSecurityDescriptor member, call the 
//    LocalFree function.
// 
// Return value:
//    FALSE if the address to the structure is NULL. 
//    Otherwise, this function returns the value from the
//    ConvertStringSecurityDescriptorToSecurityDescriptor 
//    function.
BOOL CreateMyDACL(SECURITY_ATTRIBUTES * pSA)
{
     // Define the SDDL for the DACL. This example sets 
     // the following access:
     //     Built-in guests are denied all access.
     //     Anonymous logon is denied all access.
     //     Authenticated users are allowed 
     //     read/write/execute access.
     //     Administrators are allowed full control.
     // Modify these values as needed to generate the proper
     // DACL for your application. 
     TCHAR * szSD = TEXT("D:")       // Discretionary ACL
        TEXT("(D;OICI;GA;;;BG)")     // Deny access to 
                                     // built-in guests
        TEXT("(D;OICI;GA;;;AN)")     // Deny access to 
                                     // anonymous logon
        TEXT("(A;OICI;GRGWGX;;;AU)") // Allow 
                                     // read/write/execute 
                                     // to authenticated 
                                     // users
        TEXT("(A;OICI;GA;;;BA)");    // Allow full control 
                                     // to administrators

    if (NULL == pSA)
        return FALSE;

     return ConvertStringSecurityDescriptorToSecurityDescriptor(
                szSD,
                SDDL_REVISION_1,
                &(pSA->lpSecurityDescriptor),
                NULL);
}