ACLMGMT.CPP
/*++ 
 
DCOM Permission Configuration Sample 
Copyright (c) 1996, Microsoft Corporation. All rights reserved. 
 
Module Name: 
 
    aclmgmt.cpp 
 
Abstract: 
 
    Routines to manage access control lists 
 
Author: 
 
    Michael Nelson 
 
Environment: 
 
    Windows NT 
 
--*/ 
 
#include <windows.h> 
#include <stdio.h> 
#include <conio.h> 
#include <tchar.h> 
#include "ntsecapi.h" 
#include "dcomperm.h" 
 
DWORD 
CopyACL ( 
    PACL OldACL, 
    PACL NewACL 
    ) 
{ 
    ACL_SIZE_INFORMATION  aclSizeInfo; 
    LPVOID                ace; 
    ACE_HEADER            *aceHeader; 
    ULONG                 i; 
 
    GetAclInformation (OldACL, (LPVOID) &aclSizeInfo, (DWORD) sizeof (aclSizeInfo), AclSizeInformation); 
 
    // 
    // Copy all of the ACEs to the new ACL 
    // 
 
    for (i = 0; i < aclSizeInfo.AceCount; i++) 
    { 
        // 
        // Get the ACE and header info 
        // 
 
        if (!GetAce (OldACL, i, &ace)) 
            return GetLastError(); 
 
        aceHeader = (ACE_HEADER *) ace; 
 
        // 
        // Add the ACE to the new list 
        // 
 
        if (!AddAce (NewACL, ACL_REVISION, 0xffffffff, ace, aceHeader->AceSize)) 
            return GetLastError(); 
    } 
 
    return ERROR_SUCCESS; 
} 
 
DWORD 
AddAccessDeniedACEToACL ( 
    PACL *Acl, 
    DWORD PermissionMask, 
    LPTSTR Principal 
    ) 
{ 
    ACL_SIZE_INFORMATION  aclSizeInfo; 
    int                   aclSize; 
    DWORD                 returnValue; 
    PSID                  principalSID; 
    PACL                  oldACL, newACL; 
 
    oldACL = *Acl; 
 
    returnValue = GetPrincipalSID (Principal, &principalSID); 
    if (returnValue != ERROR_SUCCESS) 
        return returnValue; 
 
    GetAclInformation (oldACL, (LPVOID) &aclSizeInfo, (DWORD) sizeof (ACL_SIZE_INFORMATION), AclSizeInformation); 
 
    aclSize = aclSizeInfo.AclBytesInUse + 
              sizeof (ACL) + sizeof (ACCESS_DENIED_ACE) + 
              GetLengthSid (principalSID) - sizeof (DWORD); 
 
    newACL = (PACL) new BYTE [aclSize]; 
 
    if (!InitializeAcl (newACL, aclSize, ACL_REVISION)) 
    { 
        free (principalSID); 
        return GetLastError(); 
    } 
 
    if (!AddAccessDeniedAce (newACL, ACL_REVISION2, PermissionMask, principalSID)) 
    { 
        free (principalSID); 
        return GetLastError(); 
    } 
 
    returnValue = CopyACL (oldACL, newACL); 
    if (returnValue != ERROR_SUCCESS) 
    { 
        free (principalSID); 
        return returnValue; 
    } 
 
    *Acl = newACL; 
 
    free (principalSID); 
    return ERROR_SUCCESS; 
} 
 
DWORD 
AddAccessAllowedACEToACL ( 
    PACL *Acl, 
    DWORD PermissionMask, 
    LPTSTR Principal 
    ) 
{ 
    ACL_SIZE_INFORMATION  aclSizeInfo; 
    int                   aclSize; 
    DWORD                 returnValue; 
    PSID                  principalSID; 
    PACL                  oldACL, newACL; 
 
    oldACL = *Acl; 
 
    returnValue = GetPrincipalSID (Principal, &principalSID); 
    if (returnValue != ERROR_SUCCESS) 
        return returnValue; 
 
    GetAclInformation (oldACL, (LPVOID) &aclSizeInfo, (DWORD) sizeof (ACL_SIZE_INFORMATION), AclSizeInformation); 
 
    aclSize = aclSizeInfo.AclBytesInUse + 
              sizeof (ACL) + sizeof (ACCESS_ALLOWED_ACE) + 
              GetLengthSid (principalSID) - sizeof (DWORD); 
 
    newACL = (PACL) new BYTE [aclSize]; 
 
    if (!InitializeAcl (newACL, aclSize, ACL_REVISION)) 
    { 
        free (principalSID); 
        return GetLastError(); 
    } 
 
    returnValue = CopyACL (oldACL, newACL); 
    if (returnValue != ERROR_SUCCESS) 
    { 
        free (principalSID); 
        return returnValue; 
    } 
 
    if (!AddAccessAllowedAce (newACL, ACL_REVISION2, PermissionMask, principalSID)) 
    { 
        free (principalSID); 
        return GetLastError(); 
    } 
 
    *Acl = newACL; 
 
    free (principalSID); 
    return ERROR_SUCCESS; 
} 
 
DWORD 
RemovePrincipalFromACL ( 
    PACL Acl, 
    LPTSTR Principal 
    ) 
{ 
    ACL_SIZE_INFORMATION    aclSizeInfo; 
    ULONG                   i; 
    LPVOID                  ace; 
    ACCESS_ALLOWED_ACE      *accessAllowedAce; 
    ACCESS_DENIED_ACE       *accessDeniedAce; 
    SYSTEM_AUDIT_ACE        *systemAuditAce; 
    PSID                    principalSID; 
    DWORD                   returnValue; 
    ACE_HEADER              *aceHeader; 
 
    returnValue = GetPrincipalSID (Principal, &principalSID); 
    if (returnValue != ERROR_SUCCESS) 
        return returnValue; 
 
    GetAclInformation (Acl, (LPVOID) &aclSizeInfo, (DWORD) sizeof (ACL_SIZE_INFORMATION), AclSizeInformation); 
 
    for (i = 0; i < aclSizeInfo.AceCount; i++) 
    { 
        if (!GetAce (Acl, i, &ace)) 
        { 
            free (principalSID); 
            return GetLastError(); 
        } 
 
        aceHeader = (ACE_HEADER *) ace; 
 
        if (aceHeader->AceType == ACCESS_ALLOWED_ACE_TYPE) 
        { 
            accessAllowedAce = (ACCESS_ALLOWED_ACE *) ace; 
 
            if (EqualSid (principalSID, (PSID) &accessAllowedAce->SidStart)) 
            { 
                DeleteAce (Acl, i); 
                free (principalSID); 
                return ERROR_SUCCESS; 
            } 
        } else 
 
        if (aceHeader->AceType == ACCESS_DENIED_ACE_TYPE) 
        { 
            accessDeniedAce = (ACCESS_DENIED_ACE *) ace; 
 
            if (EqualSid (principalSID, (PSID) &accessDeniedAce->SidStart)) 
            { 
                DeleteAce (Acl, i); 
                free (principalSID); 
                return ERROR_SUCCESS; 
            } 
        } else 
 
        if (aceHeader->AceType == SYSTEM_AUDIT_ACE_TYPE) 
        { 
            systemAuditAce = (SYSTEM_AUDIT_ACE *) ace; 
 
            if (EqualSid (principalSID, (PSID) &systemAuditAce->SidStart)) 
            { 
                DeleteAce (Acl, i); 
                free (principalSID); 
                return ERROR_SUCCESS; 
            } 
        } 
    } 
 
    free (principalSID); 
    return ERROR_SUCCESS; 
}