Directory Services |
The LDAP_SERVER_EXTENDED_DN_OID control is used with an extended LDAP search function to request an extended form of an Active Directory object's distinguished name. The extended form includes a string representation of the object's objectGUID property. For security principal objects such as users, groups, and computers, the extended form also includes a string representation of the object's objectSID property.
To use this control, set the members of the LDAPControl structure as follows.
PWCHAR ldctl_oid = LDAP_SERVER_EXTENDED_DN_OID; struct berval ldctl_value; BOOLEAN ldctl_iscritical;
The Extended DN Control enables the client to request that the results returned by an LDAP search that uses this control return the GUID and SID data of an object along with the object's distinguishedName, which is returned as follows.
<GUID=xxxxxxxx>;<SID=yyyyyyyyy>;distinguishedName
where xxxxxxxx is a string that contains the GUID, yyyyyyyy is a string that contains the SID, and distinguishedName is the DN, as in "cn=users,dc=fabrikam,dc=com". The GUID and DN are always present; the SID is present only for security principals.
The flag value passed in the ldctl_value field specifies the string format of the returned GUID and SID values, and is set to the following Ber-encoded sequence:
Sequence { Flag INTEGER }
A flag value of 0 specifies that the GUID and SID values be returned in hexadecimal string format such as <GUID=3BC72D2DEC5A704BBDC21F4EF97B7870> and <SID=0105000000000005150000005951B81766725D2564633B0B9B602C00>.
A flag value of 1 will return the GUID and SID values in standard string format such as <GUID=098f2470-bae0-11cd-b579-08002b30bfeb> and <SID=S-1-5-21-397955417-626881126-188441444-2908315>.
The ber_printf routine is used to create the sequence data. The flags portion contains the GUID/SID string format specifier. The following code example shows how to manually format the sequence data.
LDAPControl *FormatExtDNFlags(int iFlagValue) { BerElement *pber = NULL; PLDAPControl pLControl = NULL; PBERVAL pldctrl_value = NULL; int success = -1; // Ensure that iFlagValue is either 0 or 1. Convert TRUE (-1) to a legal value. if(iFlagValue != 0) iFlagValue = 1; // Format and encode the SEQUENCE data in a BerElement. pber = ber_alloc_t(LBER_USE_DER); if(pber==NULL) return NULL; pLControl = new LDAPControl; if(pLControl==NULL) { ber_free(pber,1); return NULL; } ber_printf(pber,"{i}",iFlagValue); // Transfer encoded data into a BERVAL. success = ber_flatten(pber,&pldctrl_value); ber_free(pber,1); if(success != 0) {return NULL;} // Copy the BERVAL data to the LDAPControl structure. pLControl.ldctl_oid = LDAP_SERVER_EXTENDED_DN_OID; pLControl.ldctl_iscritical = TRUE; pLControl.ldctl_value.bv_val = new char[pldctrl_value->bv_len]; memcpy(pLControl.ldctl_value.bv_val, pldctrl_value->bv_val, pldctrl_value->bv_len); pLControl.ldctl_value.bv_len = pldctrl_value->bv_len; // Cleanup temporary berval. ber_bvfree(pldctrl_value); // Return the formatted LDAPControl data. return pLControl; }
The following code example shows how to use the extended DN control with the ldap_search_ext_s function.
[C++]
INT err;
LDAP *ldapConnection = NULL;
PLDAPControl pExtDNcontrol;
PLDAPControl controlArray[2];
LDAPMessage *results = NULL;
LDAPMessage *message = NULL;
PWCHAR dn = NULL;
// Connect to the default LDAP server.
ldapConnection = ldap_open( NULL, 0 );
if ( ldapConnection == NULL ) goto FatalExit0;
// Bind to the server using default credentials.
err = ldap_bind_s( ldapConnection, NULL, NULL, LDAP_AUTH_NEGOTIATE );
if (LDAP_SUCCESS != err) goto FatalExit0;
// Setup the extended DN control, requesting 'standard string' format.
pExtDNControl = FormatExtDNFlags(1);
if (pExtDNControl == NULL) goto FatalExit0;
controlArray[0] = pExtDNcontrol;
controlArray[1] = NULL;
// Perform a synchronous search.
err = ldap_search_ext_s( ldapConnection,
L"cn=users,dc=Fabrikam,dc=com",
LDAP_SCOPE_SUBTREE,
L"objectClass=*",
NULL, // Retrieve all attributes
0, // Retrieve attributes and values
(PLDAPControl *) &controlArray,
NULL, // Client controls
0, // Timeout
0, // Sizelimit
&results // Receives identifier for results
);
if (LDAP_SUCCESS != err) goto FatalExit0;
// Process the search results.
message = ldap_first_entry( ldapConnection, results );
while (message != NULL)
{
// Print the distinguished name of the object.
dn = ldap_get_dn( ldapConnection, message );
if (!dn) goto FatalExit0;
wprintf( L" Distinguished Name is : %s\n", dn );
ldap_memfree(dn);
message = ldap_next_entry( ldapConnection, message );
}
FatalExit0:
if (ldapConnection)
ldap_unbind( ldapConnection );
if (results)
ldap_msgfree( results );
Client: Included in Windows XP and
Windows 2000 Professional.
Server: Included in Windows Server 2003 and
Windows 2000 Server.
Redistributable: Requires Active Directory Client Extension
on Windows NT 4.0 SP6a and Windows 95/98/Me.
Header: Declared in Ntldap.h.