在 C++ 中修改物件的 ACL

下列範例會將 存取控制專案 (ACE) 新增至物件的 任意存取控制清單 (DACL) 。

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

使用此程式碼可將 物件特定的 ACE 新增至目錄服務物件的 DACL。 若要在物件特定的 ACE 中指定 GUID,請將 TrustForm 參數設定為 TRUSTEE_IS_OBJECTS_AND_NAME 或 TRUSTEE_IS_OBJECTS_AND_SID,並將 pszTrustee 參數設定為 OBJECTS_AND_NAMEOBJECTS_AND_SID 結構的指標。

此範例會使用 GetNamedSecurityInfo 函式來取得現有的 DACL。 然後它會以 ACE 的相關資訊填入 EXPLICIT_ACCESS 結構,並使用 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;
}