在 C++ 中控制子物件建立

您可以使用容器物件的 DACL 來控制允許在容器內建立子物件的人員。 這很重要,因為物件的建立者通常會指派為物件的擁有者,而物件的擁有者可以控制物件的存取權。

不同類型的容器物件具有特定的存取權限,可控制建立子物件的能力。 例如,執行緒必須具有登錄機碼的KEY_CREATE_SUB_KEY存取權,才能在機碼下建立子機碼。 登錄機碼的 DACL 可以包含允許或拒絕此存取權的 ACE。 同樣地,NTFS 支援FILE_ADD_FILE和FILE_ADD_SUBDIRECTORY存取權限,以控制在目錄中建立檔案或目錄的能力。

ADS_RIGHT_DS_CREATE_CHILD存取權限可控制在目錄服務中建立子物件, (DS) 物件。 不過,DS 物件可以包含不同類型的物件,因此系統支援更精細的控制細微性。 您可以使用 特定物件 ACE 來允許或拒絕許可權來建立指定的子物件類型。 您可以允許使用者建立一種類型的子物件,同時防止使用者建立其他類型的子物件。

下列範例會使用 SetEntriesInAcl 函式,將物件特定的 ACE 新增至 ACL。 ACE 會授與建立指定型別子物件的許可權。 EXPLICIT_ACCESS結構的grfAccessPermissions成員會設定為 ADS_RIGHT_DS_CREATE_CHILD,表示 ACE 會控制子物件的建立。 OBJECTS_AND_SID結構的ObjectsPresent成員會設定為 ACE_OBJECT_TYPE_PRESENT,表示ObjectTypeGuid成員包含有效的 GUID。 GUID 會識別正在控制其建立的子物件類型。

在下列範例中,pOldDACL 必須是現有 ACL 結構的有效指標。 如需如何為物件建立 ACL 結構的詳細資訊,請參閱 在 C++ 中建立新物件的安全性描述元

DWORD dwRes;
PACL pOldDACL = NULL;
PACL pNewDACL = NULL;
GUID guidChildObjectType = GUID_NULL;   // GUID of object to control creation of
PSID pTrusteeSID = NULL;           // trustee for new ACE
EXPLICIT_ACCESS ea;
OBJECTS_AND_SID ObjectsAndSID;

// pOldDACL must be a valid pointer to an existing ACL structure.

// guidChildObjectType must be the GUID of an object type 
// that is a possible child of the object associated with pOldDACL.
 
// Initialize an OBJECTS_AND_SID structure with object type GUIDs and 
// the SID of the trustee for the new ACE. 

ZeroMemory(&ObjectsAndSID, sizeof(OBJECTS_AND_SID));
ObjectsAndSID.ObjectsPresent = ACE_OBJECT_TYPE_PRESENT;
ObjectsAndSID.ObjectTypeGuid = guidChildObjectType;
ObjectsAndSID.InheritedObjectTypeGuid  = GUID_NULL;
ObjectsAndSID.pSid = (SID *)pTrusteeSID;

// Initialize an EXPLICIT_ACCESS structure for the new ACE. 

ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
ea.grfAccessPermissions = ADS_RIGHT_DS_CREATE_CHILD;
ea.grfAccessMode = GRANT_ACCESS;
ea.grfInheritance= NO_INHERITANCE;
ea.Trustee.TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
ea.Trustee.ptstrName = (LPTSTR) &ObjectsAndSID;

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

dwRes = SetEntriesInAcl(1, &ea, pOldDACL, &pNewDACL);