Example Code for Creating a Control Access Right

The following Visual Basic example creates a controlAccessRight object in the Extended-Rights container.

Dim ExContainer As IADsContainer
Dim rootdse As IADs
Dim ExRight As IADs

On Error GoTo CleanUp
 
Set rootdse = GetObject("LDAP://rootDSE")
configpath = rootdse.Get("configurationNamingContext")
Set ExContainer = GetObject("LDAP://cn=extended-rights," & configpath)
 
' Create the object, specifying the object class and the cn.
Set ExRight = ExContainer.Create("controlAccessRight", "cn=MyExRight")
 
' Set the classes that the right applies to.
' Specify the schemaIDGUID of the user and computer classes.
ExRight.PutEx ADS_PROPERTY_UPDATE, "appliesTo", _
         Array("bf967aba-0de6-11d0-a285-00aa003049e2", _
               "bf967a86-0de6-11d0-a285-00aa003049e2")
 
' Set the display name used in Security property pages and other UI.
ExRight.PutEx ADS_PROPERTY_UPDATE, 
              "displayName", 
              Array("My-Extended-Right")
 
' Set rightsGUID to a GUID generated by Uuidgen.exe.
ExRight.PutEx ADS_PROPERTY_UPDATE, "rightsGUID", _
               Array("64ad33ac-ea09-4ded-b798-a0585c50fd5a")

' Set validAccesses to indicate a control access right.
ExRight.PutEx ADS_PROPERTY_UPDATE, "validAccesses", &H100

ExRight.SetInfo

Exit Sub

CleanUp:
    MsgBox ("An error has occurred.")
    ExContainer = Nothing
    rootdse = Nothing
    ExRight = Nothing

The following C++ code example is a function that creates a controlAccessRight object in the Extended-Rights container. When you call this function, use the following format to specify the GUID string for the pszRightsGUID parameter.

L"b7b13123-b82e-11d0-afee-0000f80367c1"

The ADSVALUE array for the appliesTo property uses the same GUID format and sets the dwType member to ADSTYPE_CASE_IGNORE_STRING.

#define _WIN32_WINNT 0x0500
 
#include <windows.h>
#include <stdio.h>
#include <activeds.h>
 
// ****************************************************************
//  CreateExtendedRight
// ****************************************************************
HRESULT CreateExtendedRight(
             LPWSTR pszCommonName,     // cn property
             LPWSTR pszDisplayName,    // displayName property
             LPWSTR pszRightsGUID,     // rightsGUID property
             ADSVALUE *pAdsvAppliesTo, // array of GUIDs for appliesTo property
             int cAppliesTo )          // number of GUIDs in array
{
HRESULT hr = E_FAIL;
VARIANT var;
LPOLESTR szADsPath = NULL;
IADs *pRootDSE = NULL;
IDirectoryObject *pExRights = NULL;
UINT nSize = 0;
WCHAR *lpszExtRights = L"LDAP://cn=Extended-Rights," 

const int cAttributes = 6;   // Count of attributes that must be set to create a control access right.
PADS_ATTR_INFO pAttributeEntries = new ADS_ATTR_INFO[cAttributes];  // array of attributes
ADSVALUE adsvCN,
         adsvObjectClass,
         adsvDisplayName,
         adsvRightsGUID,
         adsvValidAccesses;
 
LPOLESTR pszRightRelPath = new WCHAR[MAX_PATH];
IDispatch *pNewObject = NULL;
 
hr = ADsOpenObject(L"LDAP://rootDSE",
                   NULL,
                   NULL,
                   ADS_SECURE_AUTHENTICATION, // Use Secure Authentication.
                   IID_IADs,
                   (void**)&pRootDSE);
if (FAILED(hr)) {
    wprintf(L"Bind to rootDSE failed: 0x%x\n", hr);
    return hr;
}
 
// Get the DN to the config container.
hr = pRootDSE->Get(CComBSTR("configurationNamingContext"), &var);
if (SUCCEEDED(hr))
{
    // Determine the buffer size required to store the ADsPath string
    // and allocate the buffer.
    nSize = wcslen(lpszExtRights) + wcslen(var.bstrVal) + 1;
    szADsPath = new OLECHAR[nSize];

    if (szADsPath == NULL)
    {
        wprintf(L"Buffer allocation failed.");
        goto cleanup;
    }

    // Build ADsPath string to Extended-Rights container
    wcsncpy_s(szADsPath,lpszExtRights,nSize);
    wcsncat_s(szADsPath,var.bstrVal,wcslen(var.bstrVal));
 
    // Get an IDirectory Object pointer to the Extended Rights Container.
    hr = ADsOpenObject(szADsPath,
               NULL,
               NULL,
               ADS_SECURE_AUTHENTICATION, // Use Secure Authentication.
               IID_IDirectoryObject,
               (void**)&pExRights);
}
if (FAILED (hr) ) {
    wprintf(L"Bind to Extended Rights Container failed: 0x%x\n", hr);
    goto cleanup;
}
 
// Set first attribute: CN
pAttributeEntries[0].pszAttrName = L"CN";                    // Attribute name: CN
pAttributeEntries[0].dwControlCode = ADS_ATTR_APPEND;        // Add the attribute.
pAttributeEntries[0].dwADsType = ADSTYPE_CASE_IGNORE_STRING; // Attribute syntax is string.
// Fill in the ADSVALUE structure for the CN property
adsvCN.CaseIgnoreString = pszCommonName;
adsvCN.dwType = ADSTYPE_CASE_IGNORE_STRING;
pAttributeEntries[0].pADsValues = &adsvCN;
pAttributeEntries[0].dwNumValues = 1;
 
// Set second attribute: objectClass
pAttributeEntries[1].pszAttrName = L"objectClass";           // Attribute name: objectClass
pAttributeEntries[1].dwControlCode = ADS_ATTR_APPEND;        // Add the attribute.
pAttributeEntries[1].dwADsType = ADSTYPE_CASE_IGNORE_STRING; // Attribute syntax is string.
// Fill in the ADSVALUE structure for the objectClass property
adsvObjectClass.CaseIgnoreString = L"controlAccessRight";    // objectClass is controlAccessRight
adsvObjectClass.dwType = ADSTYPE_CASE_IGNORE_STRING;
pAttributeEntries[1].pADsValues = &adsvObjectClass;
pAttributeEntries[1].dwNumValues = 1;
 
// Set third attribute: appliesTo
// Each value for this property is a schemaIDGUID of a class to which the right can be applied.
pAttributeEntries[2].pszAttrName = L"appliesTo";             // Attribute name: appliesTo
pAttributeEntries[2].dwControlCode = ADS_ATTR_APPEND;        // Add the attribute.
pAttributeEntries[2].dwADsType = ADSTYPE_CASE_IGNORE_STRING; // Attribute syntax is string.
// The ADSVALUE array for this property is passed in as a parameter to this function.
pAttributeEntries[2].pADsValues = pAdsvAppliesTo;
pAttributeEntries[2].dwNumValues = cAppliesTo;
 
// Set fourth attribute: displayName
pAttributeEntries[3].pszAttrName = L"displayName";           // Attribute name: CNpAttributeEntries[3].dwControlCode = ADS_ATTR_APPEND;        // Add the attribute.
pAttributeEntries[3].dwADsType = ADSTYPE_CASE_IGNORE_STRING; // Attribute syntax is string.
// Fill in the ADSVALUE structure for the displayName property.
adsvDisplayName.CaseIgnoreString = pszDisplayName;
adsvDisplayName.dwType = ADSTYPE_CASE_IGNORE_STRING;
pAttributeEntries[3].pADsValues = &adsvDisplayName;
pAttributeEntries[3].dwNumValues = 1;
 
// Set fifth attribute: rightsGUID
pAttributeEntries[4].pszAttrName = L"rightsGUID";            // Attribute name
pAttributeEntries[4].dwControlCode = ADS_ATTR_APPEND;        // Add the attribute.
pAttributeEntries[4].dwADsType = ADSTYPE_CASE_IGNORE_STRING; // Attribute syntax is string.
// Fill in the ADSVALUE structure for the rightsGUID property.
adsvRightsGUID.dwType = ADSTYPE_CASE_IGNORE_STRING;
adsvRightsGUID.CaseIgnoreString = pszRightsGUID;
pAttributeEntries[4].pADsValues = &adsvRightsGUID;
pAttributeEntries[4].dwNumValues = 1;
 
// Set sixth attribute: validAccesses
pAttributeEntries[5].pszAttrName = L"validAccesses";         // Attribute name
pAttributeEntries[5].dwControlCode = ADS_ATTR_APPEND;        // Add the attribute.
pAttributeEntries[5].dwADsType = ADSTYPE_CASE_IGNORE_STRING; // Attribute syntax is string.
// Fill in the ADSVALUE structure for the rightsGUID property.
adsvValidAccesses.dwType = ADSTYPE_INTEGER;
adsvValidAccesses.Integer = ADS_RIGHT_DS_CONTROL_ACCESS;
pAttributeEntries[5].pADsValues = &adsvValidAccesses;
pAttributeEntries[5].dwNumValues = 1;
 
// Set up the relative distinguished name for the new object.
wcscpy_s(pszRightRelPath, L"cn=");
wcscat_s(pszRightRelPath, pszCommonName);
 
// Create the controlAccessRight
hr = pExRights->CreateDSObject(
                     pszRightRelPath,   // Relative path of new object
                     pAttributeEntries, // Attributes to be set
                     cAttributes,       // Number of attributes being set
                     &pNewObject        // receives IDispatch pointer to the new object
                     );
 
cleanup:
 
if (pRootDSE)
    pRootDSE->Release();
if (pExRights)
    pExRights->Release();
if (pNewObject)
    pNewObject->Release();
if (szADsPath)
    delete [] szADsPath;
 
VariantClear(&var);
return hr;
}

This CreateExtendedRight sample function can be called with the following code example.

ADSVALUE adsvAppliesTo;
 
adsvAppliesTo.dwType = ADSTYPE_CASE_IGNORE_STRING;
adsvAppliesTo.CaseIgnoreString = L"bf967aba-0de6-11d0-a285-00aa003049e2";

hr = CreateExtendedRight(L"myexright", L"My Extended Right",
                     L"7587d479-441a-480b-9d5d-807b4d067db4",
                     &adsvAppliesTo,
                     1);