14.15 LDAP Extended DN Control

eDirectory provides the LDAP Extended DN Control which is used with an extended LDAP search to request an extended form of object Distinguished Name. The extended form includes a string representation of Object GUID along with Distinguished Name of the object.

To use the LDAP Extended DN Control feature with the eDirectory server, an administrator must provide the LDAP Extended DN Control OID 1.2.840.113556.1.4.529 in the extended LDAP search request.

The Extended DN Control enables the client to request that the results returned by an LDAP search that uses this control return the GUID data of an object along with the object distinguishedName, which is returned as follows:

<GUID=xxxxxxxx>;distinguishedName

Where xxxxxxxx is a string that contains the GUID, and distinguishedName is the DN, as in cn=users,dc=fabrikam,dc=com.

LDAP extended DN control can be passed along with an integer flag value. The flag value passed in specifies the string format of the returned GUID value, and is set to the following Ber-encoded sequence:

Sequence {
  Flag    INTEGER
}

A flag value 0 specifies that the GUID value be returned in hexadecimal string format such as <GUID=3BC72D2DEC5A704BBDC21F4EF97B7870>.

A flag value of 1 will return the GUID value in standard string format such as <GUID=098f2470-bae0-11cd-b579-08002b30bfeb>.

There are several complex data types of eDirectory that include DN as a part of it. eDirectory handles only the following complex data types with LDAP Extended DN Control:

  • SYN_PATH (GUID is returned for volumeDN)

  • SYN_DN

  • SYN_TYPED_NAME

    NOTE:LDAP search performance will be impacted while using the Extended DN Control with the above mentioned complex data types.

Examples:

The following C++ example code shows how to manually format the sequence data. The ber_printf function is used to create the sequence data. The flags portion contains the GUID string format specifier:

LDAPControl *FormatExtDNFlags(int iFlagValue)
{
  BerElement *pber = NULL;
  LDAPControl *pLControl = NULL;
  berval *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 formatted LDAPControl data.
  return pLControl;
}

The following C++ example code shows how to use the extended DN control with the ldap_search_ext_s function:

        int err;
        LDAP *ldapConnection = NULL;
        LDAPControl *pExtDNControl;
        LDAPControl *controlArray[2];
        LDAPMessage *results = NULL;
        LDAPMessage *message = NULL;
        char *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_simple_bind_s( ldapConnection, NULL, NULL);
        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,
                        "cn=users,dc=Fabrikam,dc=com",
                        LDAP_SCOPE_SUBTREE,
                        "objectClass=*",
                        NULL,          // Retrieve all attributes.
                        0,             // Retrieve attributes and values.
                        (LDAPControl **) &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;
                printf( "  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 );
}