Código de ejemplo para establecer una ACE en un objeto de directorio
Definición de la función SetRight
En el ejemplo de código siguiente se define una función que agrega un Access Control Entry (ACE) a la lista de Access Control discrecionales (DACL) del descriptor de seguridad de un objeto especificado en Servicios de dominio de Active Directory. La subrutina le permite:
- Conceda o deniegue el acceso a todo el objeto.
- Conceda o deniegue el acceso a una propiedad específica en el objeto .
- Conceda o deniegue el acceso a un conjunto de propiedades en el objeto .
- Conceda o deniegue el derecho de crear un tipo específico de objeto secundario.
- Establezca una ACE que todos los objetos secundarios o los objetos secundarios de una clase de objeto especificada puedan heredar.
A continuación de este ejemplo de código de Visual Basic se muestran varios ejemplos de código que muestran cómo usar la función SetRight para establecer diferentes tipos de ACE.
Const ACL_REVISION_DS = &H4
Public Function SetRight(objectDN As String, _
accessrights As Long, _
accesstype As Long, _
aceinheritflags As Long, _
objectGUID As String, _
inheritedObjectGUID As String, _
trustee As String) As Boolean
Dim dsobject As IADs
Dim sd As IADsSecurityDescriptor
Dim dacl As IADsAccessControlList
Dim newace As New AccessControlEntry
Dim lflags As Long
On Error GoTo Cleanup
' Bind to the specified object.
Set dsobject = GetObject(objectDN)
' Read the security descriptor on the object.
Set sd = dsobject.Get("ntSecurityDescriptor")
' Get the DACL from the security descriptor.
Set dacl = sd.DiscretionaryAcl
' Set the properties of the new ACE.
newace.AccessMask = accessrights
newace.AceType = accesstype
newace.AceFlags = aceinheritflags
newace.trustee = trustee
' Set the GUID for the object type or inherited object type.
lflags = 0
If Not objectGUID = vbNullString Then
newace.ObjectType = objectGUID
lflags = lflags Or &H1 'ADS_FLAG_OBJECT_TYPE_PRESENT
End If
If Not inheritedObjectGUID = vbNullString Then
newace.InheritedObjectType = inheritedObjectGUID
lflags = lflags Or &H2 'ADS_FLAG_INHERITED_OBJECT_TYPE_PRESENT
End If
If Not (lflags = 0) Then newace.Flags = lflags
' Set the ACL Revision.
dacl.AclRevision = ACL_REVISION_DS
' Add the ACE to the DACL and to the security descriptor.
dacl.AddAce newace
sd.DiscretionaryAcl = dacl
' Apply it to the object.
dsobject.Put "ntSecurityDescriptor", sd
dsobject.SetInfo
SetRight = True
Exit Function
Cleanup:
Set dsobject = Nothing
Set sd = Nothing
Set dacl = Nothing
Set newace = Nothing
SetRight = False
End Function
HRESULT SetRight(
IADs *pObject,
long lAccessMask,
long lAccessType,
long lAccessInheritFlags,
LPOLESTR szObjectGUID,
LPOLESTR szInheritedObjectGUID,
LPOLESTR szTrustee)
{
VARIANT varSD;
HRESULT hr = E_FAIL;
IADsAccessControlList *pACL = NULL;
IADsSecurityDescriptor *pSD = NULL;
IDispatch *pDispDACL = NULL;
IADsAccessControlEntry *pACE = NULL;
IDispatch *pDispACE = NULL;
long lFlags = 0L;
// The following code example takes the szTrustee in an expected naming format
// and assumes it is the name for the correct trustee.
// The application should validate the specified trustee.
if (!szTrustee || !pObject)
return E_INVALIDARG;
VariantInit(&varSD);
// Get the nTSecurityDescriptor.
// Type should be VT_DISPATCH - an IDispatch pointer to the security descriptor object.
hr = pObject->Get(_bstr_t("nTSecurityDescriptor"), &varSD);
if ( FAILED(hr) || varSD.vt != VT_DISPATCH ) {
wprintf(L"get nTSecurityDescriptor failed: 0x%x\n", hr);
return hr;
}
hr = V_DISPATCH( &varSD )->QueryInterface(IID_IADsSecurityDescriptor,(void**)&pSD);
if ( FAILED(hr) ) {
wprintf(L"QueryInterface for IADsSecurityDescriptor failed: 0x%x\n", hr);
goto cleanup;
}
// Get the DACL.
hr = pSD->get_DiscretionaryAcl(&pDispDACL);
if (SUCCEEDED(hr))
hr = pDispDACL->QueryInterface(IID_IADsAccessControlList,(void**)&pACL);
if ( FAILED(hr) ) {
wprintf(L"Could not get DACL: 0x%x\n", hr);
goto cleanup;
}
// Create the COM object for the new ACE.
hr = CoCreateInstance(
CLSID_AccessControlEntry,
NULL,
CLSCTX_INPROC_SERVER,
IID_IADsAccessControlEntry,
(void **)&pACE
);
if ( FAILED(hr) ) {
wprintf(L"Could not create ACE object: 0x%x\n", hr);
goto cleanup;
}
// Set the properties for the new ACE.
// Set the mask that specifies the access right.
hr = pACE->put_AccessMask( lAccessMask );
// Set the trustee.
hr = pACE->put_Trustee( szTrustee );
// Set AceType.
hr = pACE->put_AceType( lAccessType );
// Set AceFlags to specify whether other objects can inherit the ACE from the specified object.
hr = pACE->put_AceFlags( lAccessInheritFlags );
// If an szObjectGUID is specified, add ADS_FLAG_OBJECT_TYPE_PRESENT
// to the lFlags mask and set the ObjectType.
if (szObjectGUID)
{
lFlags |= ADS_FLAG_OBJECT_TYPE_PRESENT;
hr = pACE->put_ObjectType( szObjectGUID );
}
// If an szInheritedObjectGUID is specified, add ADS_FLAG_INHERITED_OBJECT_TYPE_PRESENT
// to the lFlags mask and set the InheritedObjectType.
if (szInheritedObjectGUID)
{
lFlags |= ADS_FLAG_INHERITED_OBJECT_TYPE_PRESENT;
hr = pACE->put_InheritedObjectType( szInheritedObjectGUID );
}
// Set flags if ObjectType or InheritedObjectType were set.
if (lFlags)
hr = pACE->put_Flags(lFlags);
// Add the ACE to the ACL to the SD to the cache to the object.
// Call the QueryInterface method for the IDispatch pointer to pass to the AddAce method.
hr = pACE->QueryInterface(IID_IDispatch, (void**)&pDispACE);
if (SUCCEEDED(hr))
{
// Set the ACL revision.
hr = pACL->put_AclRevision(ACL_REVISION_DS);
// Add the ACE.
hr = pACL->AddAce(pDispACE);
if (SUCCEEDED(hr))
{
// Write the DACL.
hr = pSD->put_DiscretionaryAcl(pDispDACL);
if (SUCCEEDED(hr))
{
// Write the ntSecurityDescriptor property to the property cache.
hr = pObject->Put(CComBSTR("nTSecurityDescriptor"), varSD);
if (SUCCEEDED(hr))
{
// Call SetInfo to update the property on the object in the directory.
hr = pObject->SetInfo();
}
}
}
}
cleanup:
if (pDispACE)
pDispACE->Release();
if (pACE)
pACE->Release();
if (pACL)
pACL->Release();
if (pDispDACL)
pDispDACL->Release();
if (pSD)
pSD->Release();
VariantClear(&varSD);
return hr;
}
Conceder o denegar el acceso a todo el objeto
En el siguiente ejemplo de código de Visual Basic se compila una cadena de enlace para el contenedor Users y, a continuación, se llama a la función SetRight para establecer una ACE en el contenedor Users. En este ejemplo se establece una ACE que concede al administrador el derecho de leer o escribir cualquier propiedad en el objeto.
Dim rootDSE As IADs
Dim objectDN As String
Dim bResult As Boolean
Const ADS_RIGHT_READ_PROP = &H10
Const ADS_RIGHT_WRITE_PROP = &H20
' Bind to the Users container in the local domain.
Set rootDSE = GetObject("LDAP://rootDSE")
objectDN = "LDAP://cn=users," & rootDSE.Get("defaultNamingContext")
' Grant trustee the right to read/write any property.
bResult = SetRight objectDN, _
ADS_RIGHT_READ_PROP Or ADS_RIGHT_WRITE_PROP, _
ADS_ACETYPE_ACCESS_ALLOWED, _
0, _
vbNullString, _
vbNullString, _
"someone@fabrikam.com" ' Trustee
If bResult = True Then
MsgBox ("The trustee can read or write any property.")
Else
MsgBox ("An error occurred.")
End If
En el siguiente ejemplo de código de C++ se establece una ACE que concede al administrador permiso para leer o escribir cualquier propiedad en el objeto. En el ejemplo de código se supone que pObject y szTrustee se establecen en valores válidos. Para obtener más información, vea Establecer derechos de acceso en un objeto.
HRESULT hr;
IADs *pObject;
LPWSTR szTrustee;
hr = SetRight(
pObject, // IADs pointer to the object
ADS_RIGHT_READ_PROP | ADS_RIGHT_WRITE_PROP,
ADS_ACETYPE_ACCESS_ALLOWED,
0, // Not inheritable
NULL, // No object type GUID
NULL, // No inherited object type GUID
szTrustee
);
Conceder o denegar el acceso a una propiedad específica en el objeto
En este ejemplo de código se llama a la función SetRight para conceder al administrador el derecho de leer o escribir una propiedad específica en el objeto. Tenga en cuenta que debe especificar schemaIDGUID de la propiedad y debe especificar ADS_ACETYPE_ACCESS_ALLOWED_OBJECT para indicar que se trata de una ACE específica del objeto. En este ejemplo de código también se especifica la marca ADS_ACEFLAG_INHERIT_ACE que indica que los objetos secundarios pueden heredar la ACE.
' Grant trustee the right to read the Telephone-Number property
' of all child objects in the Users container.
' {bf967a49-0de6-11d0-a285-00aa003049e2} is the schemaIDGUID of
' the Telephone-Number property.
bResult = SetRight objectDN, _
ADS_RIGHT_WRITE_PROP Or ADS_RIGHT_READ_PROP, _
ADS_ACETYPE_ACCESS_ALLOWED_OBJECT, _
ADS_ACEFLAG_INHERIT_ACE, _
"{bf967a49-0de6-11d0-a285-00aa003049e2}", _
vbNullString, _
"someone@fabrikam.com" ' Trustee
If bResult = True Then
MsgBox ("The trustee can read the telephone number property.")
Else
MsgBox ("An error occurred.")
End If
// Grant trustee the right to read the Telephone-Number property
// of all child objects in the Users container.
// {bf967a49-0de6-11d0-a285-00aa003049e2} is the schemaIDGUID of
// the Telephone-Number property.
hr = SetRight(
pObject, // IADs pointer to the object.
ADS_RIGHT_READ_PROP | ADS_RIGHT_WRITE_PROP,
ADS_ACETYPE_ACCESS_ALLOWED_OBJECT,
ADS_ACEFLAG_INHERIT_ACE,
L"{bf967a49-0de6-11d0-a285-00aa003049e2}",
NULL, // No inherited object type GUID.
szTrustee
);
Conceder o denegar el acceso a un conjunto de propiedades en el objeto
En este ejemplo de código se llama a la función SetRight para conceder al administrador el derecho de leer o escribir un conjunto específico de propiedades en el objeto. Especifique ADS_ACETYPE_ACCESS_ALLOWED_OBJECT para indicar que se trata de una ACE específica del objeto.
Un conjunto de propiedades se define mediante un objeto controlAccessRight en el contenedor De derechos extendidos de la partición Configuration. Para identificar la propiedad establecida en la ACE, especifique la propiedad rightsGUID de un objeto controlAccessRight . Tenga en cuenta que este GUID del conjunto de propiedades también se establece en la propiedad attributeSecurityGUID de cada objeto attributeSchema incluido en el conjunto de propiedades. Para obtener más información, consulte Control de derechos de acceso.
En este ejemplo de código también se especifican marcas de herencia que establecen la ACE como heredable por los objetos secundarios, pero que no son eficaces en el objeto inmediato. Además, el ejemplo especifica el GUID de la clase User, que indica que los objetos de esa clase solo pueden heredar la ACE.
' Grant trustee permission to read or write a set of properties.
' {77B5B886-944A-11d1-AEBD-0000F80367C1} is a GUID that identifies
' a property set.
' {bf967aba-0de6-11d0-a285-00aa003049e2} is a GUID that identifies the
' User class, so this ACE is inherited only by objects of that class.
bResult = SetRight objectDN, _
ADS_RIGHT_READ_PROP Or ADS_RIGHT_WRITE_PROP, _
ADS_ACETYPE_ACCESS_ALLOWED_OBJECT, _
ADS_ACEFLAG_INHERIT_ACE Or ADS_ACEFLAG_INHERIT_ONLY_ACE, _
"{77B5B886-944A-11d1-AEBD-0000F80367C1}", _
"{bf967aba-0de6-11d0-a285-00aa003049e2}", _
"someone@fabrikam.com" ' Trustee
If bResult = True Then
MsgBox ("The trustee can read or write a set of properties.")
Else
MsgBox ("An error occurred.")
End If
// Grant trustee the right to read or write a set of properties.
// {77B5B886-944A-11d1-AEBD-0000F80367C1} is a GUID that identifies
// a property set (rightsGUID of a controlAccessRight object).
// {bf967aba-0de6-11d0-a285-00aa003049e2} is the schemaIDGUID of the
// User class, so this ACE is inherited only by objects of that class.
hr = SetRight(
pObject, // IADs pointer to the object.
ADS_RIGHT_READ_PROP | ADS_RIGHT_WRITE_PROP,
ADS_ACETYPE_ACCESS_ALLOWED_OBJECT,
ADS_ACEFLAG_INHERIT_ACE | ADS_ACEFLAG_INHERIT_ONLY_ACE,
L"{77B5B886-944A-11d1-AEBD-0000F80367C1}",
L"{bf967aba-0de6-11d0-a285-00aa003049e2}",
szTrustee
);
Concesión o denegación de permiso para crear un tipo específico de objeto secundario
En el ejemplo de código siguiente se llama a la función SetRight para conceder a un administrador especificado el derecho a crear y eliminar objetos User en el subárbol bajo el objeto especificado. Tenga en cuenta que el ejemplo especifica el GUID de la clase User, lo que significa que la ACE solo permite al administrador crear objetos User, no objetos de otras clases. Especifique ADS_ACETYPE_ACCESS_ALLOWED_OBJECT para indicar que se trata de una ACE específica del objeto.
' Grant trustee the right to create or delete User objects
' in the specified object.
' {bf967aba-0de6-11d0-a285-00aa003049e2} is a GUID that identifies the
' User class.
bResult = SetRight objectDN, _
ADS_RIGHT_DS_CREATE_CHILD Or ADS_RIGHT_DS_DELETE_CHILD, _
ADS_ACETYPE_ACCESS_ALLOWED_OBJECT, _
0, _
"{bf967aba-0de6-11d0-a285-00aa003049e2}", _
vbNullString, _
"jeffsmith@fabrikam.com" 'trustee
If bResult = True Then
MsgBox ("The trustee can create or delete User objects.")
Else
MsgBox ("An error occurred.")
End If
// Grant trustee the right to create or delete User objects
// in the specified object.
// {bf967aba-0de6-11d0-a285-00aa003049e2} is the schemaIDGUID of the
// User class.
hr = SetRight(
pObject, // IADs pointer to the object.
ADS_RIGHT_DS_CREATE_CHILD | ADS_RIGHT_DS_DELETE_CHILD,
ADS_ACETYPE_ACCESS_ALLOWED_OBJECT,
0, // Not inheritable.
L"{bf967aba-0de6-11d0-a285-00aa003049e2}",
NULL, // No inherited object type GUID.
szTrustee
);
Para obtener más información y schemaIDGUID de un atributo o clase predefinidos, vea la página de referencia de atributos o clases en la referencia del esquema de Active Directory . Para obtener más información y un ejemplo de código que se puede usar para obtener un schemaIDGUID mediante programación, vea Lectura de atributosSchema y classSchema Objects.