14.15 LDAP拡張DNコントロール

eDirectoryにはLDAP拡張DNコントロールが備わっています。このコントロールは、識別名オブジェクトの拡張フォームを要求するために、拡張LDAP検索で使用しjます。この拡張フォームには、オブジェクトGUIDの文字列表現と、オブジェクトの識別名が含まれます。

eDirectoryサーバでLDAP拡張DNコントロール機能を使用するには、管理者は拡張LDAP検索要求でLDAP拡張DNコントロールのOID1.2.840.113556.1.4.529を指定する必要があります。

拡張DNコントロールによって、クライアントは、このコントロールを使用するLDAP検索によって返される結果に、オブジェクトのGUIDデータと、distinguishedNameオブジェクトが含まれるように要求できます。次のように返されます。

<GUID=xxxxxxxx>;distinguishedName

xxxxxxxxGUIDが含まれる文字列、distinguishedNameDN(例: cn=users,dc=fabrikam,dc=com)です。

LDAP拡張DNコントロールは、整数のフラグ値も渡すことができます。渡されるフラグ値によって、返されるGUID値の文字列形式が決まり、次のBERエンコードシーケンスに設定されます。

Sequence {
  Flag    INTEGER
}

フラグ値0の場合、GUID値は16進数文字列形式で返されます。例: <GUID=3BC72D2DEC5A704BBDC21F4EF97B7870>

フラグ値1の場合、標準文字列形式でGUID値が返されます。例: <GUID=098f2470-bae0-11cd-b579-08002b30bfeb>

一部としてDNが含まれるeDirectoryのデータタイプには複雑なものもいくつかあります。eDirectoryがLDAP拡張DNコントロールで処理する複雑なデータタイプは以下のみです。

  • SYN_PATH (volumeDNのGUIDが返されます)

  • SYN_DN

  • SYN_TYPED_NAME

    メモ:前述の複雑なデータタイプが含まれる拡張DNコントロールを使用する場合、LDAP検索のパフォーマンスが影響を受けます。

例:

次のC++コード例は、シーケンスデータを手動でフォーマットする方法を示しています。ber_printf関数を使用してシーケンスデータを作成します。フラグ部分には、GUID文字列の書式指定子が含まれます。

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;
}

次のC++コード例は、拡張DNコントロールとldap_search_ext_s関数を併用する方法について示しています。

        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 );
}