C++에서 개체의 ACL 수정

다음 예제에서는 개체의 DACL(임의 액세스 제어 목록)에 ACE(액세스 제어 항목)를 추가합니다.

AccessMode 매개 변수는 새 ACE의 유형과 지정된 트러스티에 대한 기존 ACE와 새 ACE를 결합하는 방법을 결정합니다. AccessMode 매개 변수에서 GRANT_ACCESS, SET_ACCESS, DENY_ACCESS 또는 REVOKE_ACCESS 플래그를 사용합니다. 이러한 플래그에 대한 자세한 내용은 ACCESS_MODE 참조하세요.

유사한 코드를 사용하여 SACL( 시스템 액세스 제어 목록 )을 사용할 수 있습니다. GetNamedSecurityInfoSetNamedSecurityInfo 함수에서 SACL_SECURITY_INFORMATION 지정하여 개체에 대한 SACL을 가져와 설정합니다. AccessMode 매개 변수에서 SET_AUDIT_SUCCESS, SET_AUDIT_FAILURE 및 REVOKE_ACCESS 플래그를 사용합니다. 이러한 플래그에 대한 자세한 내용은 ACCESS_MODE 참조하세요.

이 코드를 사용하여 디렉터리 서비스 개체의 DACL에 개체별 ACE 를 추가합니다. 개체별 ACE에서 GUID를 지정하려면 TrusteeForm 매개 변수를 TRUSTEE_IS_OBJECTS_AND_NAME 또는 TRUSTEE_IS_OBJECTS_AND_SID 설정하고 pszTrustee 매개 변수를 OBJECTS_AND_NAME 또는 OBJECTS_AND_SID 구조체에 대한 포인터로 설정합니다.

이 예제에서는 GetNamedSecurityInfo 함수를 사용하여 기존 DACL을 가져옵니다. 그런 다음 EXPLICIT_ACCESS 구조체를 ACE에 대한 정보로 채우고 SetEntriesInAcl 함수를 사용하여 새 ACE를 DACL의 기존 ACE와 병합합니다. 마지막으로 SetNamedSecurityInfo 함수를 호출하여 새 DACL을 개체의 보안 설명자에 연결합니다.

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

DWORD AddAceToObjectsSecurityDescriptor (
    LPTSTR pszObjName,          // name of object
    SE_OBJECT_TYPE ObjectType,  // type of object
    LPTSTR pszTrustee,          // trustee for new ACE
    TRUSTEE_FORM TrusteeForm,   // format of trustee structure
    DWORD dwAccessRights,       // access mask for new ACE
    ACCESS_MODE AccessMode,     // type of ACE
    DWORD dwInheritance         // inheritance flags for new ACE
) 
{
    DWORD dwRes = 0;
    PACL pOldDACL = NULL, pNewDACL = NULL;
    PSECURITY_DESCRIPTOR pSD = NULL;
    EXPLICIT_ACCESS ea;

    if (NULL == pszObjName) 
        return ERROR_INVALID_PARAMETER;

    // Get a pointer to the existing DACL.

    dwRes = GetNamedSecurityInfo(pszObjName, ObjectType, 
          DACL_SECURITY_INFORMATION,
          NULL, NULL, &pOldDACL, NULL, &pSD);
    if (ERROR_SUCCESS != dwRes) {
        printf( "GetNamedSecurityInfo Error %u\n", dwRes );
        goto Cleanup; 
    }  

    // Initialize an EXPLICIT_ACCESS structure for the new ACE. 

    ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
    ea.grfAccessPermissions = dwAccessRights;
    ea.grfAccessMode = AccessMode;
    ea.grfInheritance= dwInheritance;
    ea.Trustee.TrusteeForm = TrusteeForm;
    ea.Trustee.ptstrName = pszTrustee;

    // Create a new ACL that merges the new ACE
    // into the existing DACL.

    dwRes = SetEntriesInAcl(1, &ea, pOldDACL, &pNewDACL);
    if (ERROR_SUCCESS != dwRes)  {
        printf( "SetEntriesInAcl Error %u\n", dwRes );
        goto Cleanup; 
    }  

    // Attach the new ACL as the object's DACL.

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

    Cleanup:

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

        return dwRes;
}