C++ での子オブジェクトの作成の制御

コンテナー オブジェクトの DACL を使用して、コンテナー内で子オブジェクトを作成できるユーザーを制御できます。 これは、オブジェクトの作成者が通常、オブジェクトの所有者として割り当てられ、オブジェクトの所有者がオブジェクトへのアクセスを制御できるため、重要な場合があります。

さまざまな種類のコンテナー オブジェクトには、子オブジェクトを作成する機能を制御する特定のアクセス権があります。 たとえば、キーの下にサブキーを作成するには、スレッドがレジストリ キーにKEY_CREATE_SUB_KEYアクセスできる必要があります。 レジストリ キーの DACL には、このアクセス権を許可または拒否する ACE を含めることができます。 同様に、NTFS では、ディレクトリ内にファイルまたはディレクトリを作成する機能を制御するためのFILE_ADD_FILEおよびFILE_ADD_SUBDIRECTORYアクセス権がサポートされます。

ADS_RIGHT_DS_CREATE_CHILDアクセス権は、ディレクトリ サービス (DS) オブジェクトでの子オブジェクトの作成を制御します。 ただし、DS オブジェクトにはさまざまな種類のオブジェクトを含めることができるため、システムではより細かい細分性の制御がサポートされます。 オブジェクト固有の ACE を使用して、指定した種類の子オブジェクトを作成する権限を許可または拒否できます。 ユーザーが他の種類の子オブジェクトを作成できないようにしながら、ユーザーが 1 種類の子オブジェクトを作成できるようにすることができます。

次の例では 、SetEntriesInAcl 関数を使用して、オブジェクト固有の ACE を ACL に追加します。 ACE は、指定した種類の子オブジェクトを作成するためのアクセス許可を付与します。 ACE が子オブジェクトの作成を制御することを示すために、EXPLICIT_ACCESS構造体の grfAccessPermissions メンバーは ADS_RIGHT_DS_CREATE_CHILD に設定されます。 ObjectTypeGuid メンバーに有効な GUID が含まれていることを示すために、OBJECTS_AND_SID構造体の ObjectsPresent メンバーは ACE_OBJECT_TYPE_PRESENT に設定されます。 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);