LDAP_SERVER_INFORMATION IN DNS

Use the LDAP_SERVER_INFORMATION IN DNS API to run various LDAP operations for LDAP server information.

  • ldap_server_locate
  • ldap_server_free_list
  • ldap_server_conf_save
These LDAP APIs are provided to run the following operations:
  • Use LDAP server information that is published in the Domain Name System (DNS) to locate one or more LDAP servers, and associated information. Server information is returned as a linked list of server information structures.
  • Free all storage that is associated with a linked list of server information structures.
  • Store information about one or more LDAP servers in a local configuration repository. The local configuration can be used to mimic information that can also be published in DNS.

Synopsis

#include ldap.h


int ldap_server_locate (
       LDAPServerRequest *server_request,
       LDAPServerInfo    **server_info_listpp);

int  ldap_server_free_list(
        LDAPServerInfo *server_info_listp);

int ldap_server_conf_save(
       char            *filename,
       unsigned long   ttl, 
       LDAPServerInfo  *server_info_listp));

typedef struct LDAP_Server_Request {
    int     search_source;      /* Source for server info     */
#define LDAP_LSI_CONF_DNS  0    /* Config first, then DNS (def)*/
#define LDAP_LSI_CONF_ONLY 1    /* Local Config file only     */
#define LDAP_LSI_DNS_ONLY  2    /* DNS only                   */
    char    *conf_filename      /* pathname of config file    */
    int     reserved;           /* Reserved, set to zero      */
    char    *service_key;       /* Service string             */
    char    *enetwork_domain;   /* eNetwork domain (eDomain)  */
    char    **name_servers;     /* Array of name server addrs */
    char    **dns_domains;      /* Array of DNS domains       */
    int     connection_type;    /* Connection type            */
#define LDAP_LSI_UDP_TCP 0      /* Use UDP, then TCP (default)*/
#define LDAP_LSI_UDP 1          /* Use UDP only               */
#define LDAP_LSI_TCP 2          /* Use TCP only               */
    int     connection_timeout; /* connect timeout (seconds)  */
    char    *DN_filter;         /* DN suffix filter           */
    char    *proto_key          /* Symbolic protocol name     */
    unsigned char reserved2[60]; /* reserved fields, set to 0 */   
} LDAPServerRequest;


typedef struct LDAP_Server_Info {
    char    *lsi_host;        /* LDAP server's hostname */
    unsigned short lsi_port;  /* LDAP port              */
    char    *lsi_suffix;      /* Server's LDAP suffix   */
    char    *lsi_query_key;   /* service_key[.edomain]  */
    char    *lsi_dns_domain;  /* Publishing DNS domain  */
    int      lsi_replica_type;/* master or replica      */
#define LDAP_LSI_MASTER  1    /* LDAP Master            */
#define LDAP_LSI_REPLICA 2    /* LDAP Replica           */
    int      lsi_sec_type;    /* SSL or non-SSL         */ 
#define LDAP_LSI_NOSSL   1    /* Non-SSL                */
#define LDAP_LSI_SSL     2    /* Secure Server          */
    unsigned short lsi_priority; /* Server priority     */
    unsigned short lsi_weight; /* load balancing weight */
    char    *lsi_vendor_info;  /* vendor information    */
    char    *lsi_info;        /* LDAP Info string       */
    struct LDAP_Server_Info *prev; /* linked list previous ptr */
    struct LDAP_Server_Info *next; /* linked list next ptr     */
} LDAPServerInfo;

Input parameters

server_request
Specifies a pointer to an LDAPServerRequest structure, which must be initialized to zero before you set specific parameters. This setting ensures that defaults are used when a parameter is not explicitly set. If the default behavior is wanted for all possible input parameters, set server_request to NULL. This setting is equivalent to setting the LDAPServerRequest structure to zero. Otherwise, supply the address of the LDAPServerRequest structure, containing the following fields:
search_source
Specifies where to find the server information. search_source can be one of the following information:
  • Access the local LDAP DNS configuration file. If the file is not found, or the file does not contain information for a combination of the service_key, enetwork_domain, and any of the DNS domains as specified by the application, then access DNS.
  • Search the local LDAP DNS configuration file only.
  • Search DNS only.
conf_filename
Specifies an alternative configuration file name. Specify NULL to get the default file name and location.
reserved
Represents a reserved area for future function, which must be initialized to zero.
service_key
Specifies the search key. For example, use the service name string when you obtain a list of Service records (SRV), pseudo-SRV Text records (TXT), or CNAME alias records from DNS. If not specified, the default is ldap.
Note: Standards are moving towards the use of an underscore (_) as a prefix for service name strings. Over time, it is expected that _ldap is the preferred service name string for publishing LDAP services in DNS. If the application does not specify service_key, and no entries are returned by using the default ldap. service name, the search is automatically rerun by using _ldap as the service name. As an alternative, the application can explicitly specify _ldap as the service name. The search is directed specifically at DNS SRV records that use _ldap as the service name.
enetwork_domain
Indicates that LDAP servers grouped within the specified eNetwork domain are to be located. An eNetwork domain is a naming construct. It is implemented by the LDAP administrator, to further subdivide a set of LDAP servers (as published in DNS) into logical groupings. By specifying an eNetwork domain, only the LDAP servers that are grouped within the specified eNetwork domain are returned by the ldap_server_locate() API. This grouping can be useful when applications require access to a particular set of LDAP servers. For example, the research division within a company might use a dedicated set of LDAP directories, for example, masters and replicas. Applications that require access to information published in research LDAP servers can selectively obtain the host names and ports of research LDAP servers. You can obtain them by publishing this set of LDAP servers in DNS with an eNetwork domain of research. Other LDAP servers that are also published in DNS are not returned.
The criterion for searching DNS to locate the appropriate LDAP servers is constructed by concatenating the following information:
  • service_key (defaults to ldap)
  • enetwork_domain
  • tcp
  • DNS domain
For example, if:
  • The default service_key of ldap is used
  • The eNetwork domain is sales5
  • The default DNS domain of the client is midwest.acme.com
Then, the DNS value that is used to search DNS for the set of LDAP servers that belong to the sales5 eNetwork domain is ldap.sales5.tcp.midwest.acme.com.
If enetwork_domain is set to zero, the following steps are taken to determine the enetwork_domain:
  • The locally configured default, if set, is used.
  • If a locally configured default is not set, then a platform-specific value is used. On a Windows NT™ operating system, the user logon domain is used.
  • If a platform-specific eNetwork domain is not defined, then the eNetwork domain component in the DNS value is omitted. In the preceding example, this results in the following string that is used: ldap.midwest.tcp.acme.com.
If enetwork_domain is set to a NULL string, then the eNetwork domain component in the DNS value is omitted. This setting might be useful for finding a default eNetwork domain when a specific eNetwork domain is not known.
Note: If the search is run with a non-NULL value for enetwork_domain, and the search fails, the search is issued again with a NULL enetwork_domain, by using the specified service_key, which defaults to ldap. The second search with NULL enetwork_domain is attempted after a complete search is concluded without results. For example, if search_source is set to the default LDAP_LSI_CONF_DNS, then the first search is not considered to be complete until both the local configuration and DNS are queried. If both of these searches fail, then both the local configuration and DNS are queried again with a NULL enetwork_domain. The intent is to find a set of LDAP servers that are published under the default service key, that is, ldap, when nothing can be found published under ldap.enetwork_domain. The application can determine whether the located servers are published in an enetwork_domain by examining the lsi_query_key field, as returned in the server_info_list structures that are returned on the ldap_server_locate() API. If the returned lsi_query_key consists solely of the specified service_key, then the located servers were not published in DNS with the specified enetwork_domain.
.
name_servers
Specifies a NULL-terminated array of DNS name server IP address in dotted decimal format. For example, 122.122.33.49. If not specified, the locally configured DNS name servers are used.
dns_domains
Specifies a NULL-terminated array of one or more DNS domain names. If not specified, the local DNS domain configuration is used.
Note: The domain names supplied here can take the following forms:
  • austin.ibm.com (standard DNS format)
  • cn=fred, ou=accounting, dc=austin, dc=ibm, dc=com
Regarding providing a domain name, these specifications are equivalent. Both result in a domain name of austin.ibm.com. This approach makes it easier for an application to locate LDAP servers for binding based on a user name space. This space is mapped into the DNS name space. For more information, see the section DNS domains and configuration file.
connection_type
Specifies the type of connection to use when it communicates with the DNS name server. The following options are supported:
  • Use UDP first. If no response is received, or data truncation occurs, then use TCP.
  • Use only UDP.
  • Use only TCP.
If set to zero, the default is to use UDP first (then TCP).
UDP is the preferred connection type, and typically runs well. You might want to consider by using TCP/IP if:
  • The amount of data that is returned does not fit in the 512-byte UDP packet.
  • The transmission and receipt of UDP packets turns out to be unreliable. This action might depend on network characteristics.
connection_timeout
Specifies a timeout value when querying DNS (for both TCP and UDP). If LDAP_LSI_UDP_TCP is specified for connection_type and a response is not received in the specified time period for UDP, TCP is attempted. A value of zero results in an innumerable timeout. When the LDAPServerRequest parameter is set to NULL, the default is 10 seconds. When you pass the LDAPServerRequest parameter, this parameter must be set to a nonzero value if an indefinite timeout is not wanted.
DN_filter
Specifies a Distinguished Name to be used as a filter, for selecting candidate LDAP servers that are based on the server suffixes. If the most significant portion of the DN is an exact match with a server suffix (after it normalizes), an LDAPServerInfo structure is returned for the server or suffix combination. If it does not match, an LDAPServerInfo structure is not returned for the server or suffix combination.
proto_key
Specifies the protocol key. For example, tcp or _tcp, to be used when you obtain a list of SRV, pseudo-SRV TXT, or CNAME alias records from DNS. If not specified, the default is tcp.
Note: Standards are moving towards the use of an underscore ( _ ) as a prefix for the protocol. Over time, it is expected that _tcp will become the preferred protocol string for publishing LDAP and other services in DNS. If the application does not specify protocol_key and no entries are returned by using the default tcp protocol key, the search is automatically rerun by using the _tcp protocol. As an alternative, the application explicitly specifies _tcp as the protocol, and the search is directed specifically at DNS SRV records that use the _tcp protocol.
reserved2
Represents a reserved area for future function, which must be initialized to zero.
server_info_listpp
Specifies the address that is set to point to a linked list of LDAPServerInfo structures. Each LDAPServerInfo structure that is defined in the list contains server information that is obtained from either of the following items:
  • DNS
  • Local configuration
filename
Specifies an alternative configuration file name. Specify NULL to get the default file name and location.
ttl
Specifies the time-to-live, in minutes, for server information that is saved in the configuration file. Set ttl to zero if it is intended to be a permanent repository of information.

When the ldap_server_locate() API accesses the configuration file with search_source set to LDAP_LSI_CONF_ONLY, and the configuration file is not refreshed in ttl minutes, the LDAP_TIMEOUT error code is returned.

When the ldap_server_locate() API is accesses the configuration file with search_source set to LDAP_LSI_CONF_DNS, and the configuration file is not refreshed in ttl minutes, then network DNS is accessed to obtain server information.

server_info_listp
Specifies the address of a linked list of LDAPServerInfo structures. This linked list might be returned from the ldap_server_locate() API, or might be constructed by the application.

Output parameters

Returns 0 if successful. If an error is encountered, an appropriate return code as defined in the ldap.h file is returned. If successful, the address of a linked list of LDAPServerInfo structures is returned.

server_info_listpp
Upon successful return from ldap_server_locate(), server_info_listpp points to a linked list of LDAPServerInfo structures. The LDAPServerInfo structure contains the following fields:
lsi_host
Fully qualified host name of the target server (NULL-terminated string).
lsi_port
Integer representation of the LDAP server port.
lsi_suffix
String that specifies a supported suffix for the LDAP server (NULL-terminated string).
lsi_query_key
Specifies the eNetwork domain to which the LDAP server belongs, prefixed by the service key. For example, if service key is ldap and eNetwork domain is sales, then lsi_query_key is set to ldap.sales. If the server is not associated with an eNetwork domain (as published in DNS), then lsi_query_key consists solely of the service key value. Also, for example, if the service key is _ldap and the eNetwork domain is marketing, then lsi_query_key is set to _ldap.marketing.
lsi_dns_domain
DNS domain in which the LDAP server was published. For example, the DNS search might be for ldap.sales.tcp.austin.ibm.com, but the resulting servers have a fully qualified DNS host name of ldap2.raleigh.ibm.com. In this example, lsi_host is set to ldap2.raleigh.ibm.com while lsi_dns_domain is set to austin.ibm.com. The actual domain in which the server was published might be of interest, particularly when multiple DNS domains are configured or supplied as input.
lsi_replica_type
Specifies the type of server, LDAP_LSI_MASTER or LDAP_LSI_REPLICA. If set to zero, the type is unknown.
lsi_sec_type
Specifies the port security type, LDAP_LSI_NOSSL or LDAP_LSI_SSL. This value is derived from the ldap or ldaps prefix in the LDAP URL. If the LDAP URL is not defined, the security type is unknown and lsi_sectype is set to zero.
lsi_priority
The priority value that is obtained from the SRV RR (or the pseudo-SRV TXT RR). Set to zero if unknown or not available.
lsi_weight
The weight value that is obtained from the SRV RR or the pseudo-SRV TXT RR. Set to zero if unknown or not available.
lsi_vendor_info
NULL-terminated string that is obtained from the ldapvendor TXT RR, if defined. It might be used to identify the LDAP server vendor or version information.
lsi_info
NULL-terminated information string that is obtained from the ldapinfo TXT RR, if defined. If not defined, lsi_info is set to NULL. This information string can be used by the LDAP or network administrator to publish more information about the target LDAP server.
prev
Points to the previous LDAP_Server_Info element in the linked list. This value is NULL if at the top of the list.
next
Points to the next LDAP_Server_Info element in the linked list. This value is NULL if at the end of the list.

Usage

DNS domains and configuration file
The local configuration file can contain server information for combinations of the following information:
  • Service key (typically set to ldap or _ldap)
  • eNetwork domain
  • DNS domains
When the application sets search_source to the default LDAP_LSI_CONFIG_DNS, the ldap_server_locate() API attempts to find server information in the configuration file for the designated service key, eNetwork domain, and DNS domains.
If the configuration file does not contain information that matches this criteria, the locator API searches the DNS. It searches by using the specified service key, eNetwork domain, and DNS domains. For example:
  • The application supplies the following three DNS domains:
    • austin.ibm.com
    • raleigh.ibm.com
    • miami.ibm.com
    Also, the application uses the default service key, that is, ldap, and specifies sales for the eNetwork domain.
  • The configuration file contains server information for austin.ibm.com and miami.ibm.com, with the default service key and eNetwork domain of sales.
  • Information is also published in DNS for raleigh.ibm.com, with the default service key and eNetwork domain of sales.
  • The search_source parameter is set to LDAP_LSI_CONFIG_DNS, which indicates that both the configuration file and DNS are to be used if necessary.
  • The locator API builds a single ordered list of server entries, with the following entries:
    • Server entries for the austin.ibm.com DNS domain, as extracted from the configuration file.
    • Server entries for the raleigh.ibm.com DNS domain, as obtained from DNS over the network.
    • Server entries for the miami.ibm.com DNS domain, as extracted from the configuration file.

The resulting list of servers contains all the austin.ibm.com servers first, followed by the raleigh.ibm.com servers, followed by the miami.ibm.com servers. Within each group of servers, the entries are sorted by priority and weight.

API usage
These routines are used to run operations that are related to finding and saving LDAP server information.
ldap_server_locate()
The ldap_server_locate() API is used to locate one or more suitable LDAP servers. In general, an application uses the ldap_server_locate() API as follows:
  • Before you connect to an LDAP server in the enterprise, use ldap_server_locate() to obtain a list of one or more LDAP servers. The servers are published in DNS or in the local configuration file. Typically, an application can use the default request settings by passing a NULL for the LDAPServerRequest parameter. By default, the API looks for server information in the local configuration file first. Then, it moves on to DNS if the local configuration file does not exist or expired.
    Note: If no server entries are found, and the application does not specify the service key, which defaults to ldap, then the ldap_server_locate() function runs the complete search again, by using the alternative _ldap for the service key. The results of this second search, if any, are returned to the application.
  • After the application obtains the list of servers, it must walk the list, by using the first server that meets its requirements. This action maximizes the advantage that can be derived from using the priority and weighting scheme that is implemented by the administrator. The application might not want to use the first server in the list for several reasons:
    • The client requires to specifically connect by using SSL or non-SSL. For each server in the list, the application can query the rootDSE to determine whether the server supports a secure SSL port. This query is the preferred approach. Alternatively, the application can walk the list until it finds a server entry with the appropriate security type. An LDAP server might be listening on both an SSL and non-SSL port. In this case, the server has two entries in the server list:
    • The client specifically requires to connect to a Master or Replica.
    • The client requires to connect to a server that supports a particular suffix.
      Note: Specify DN_filter to filter out servers that do not have a suffix. The DN is under this suffix. To confirm that a server actually supports the suffix, query the server rootDSE.
    • Some other characteristic that is associated with the wanted server exists, defined in the ldapinfo string.
  • After the client selects a server, it then issues the ldap_init or ldap_ssl_init API. If the selected server is unavailable, the application is free to move down the list of servers. It moves the server list until either it finds a suitable server it can connect to, or the list is exhausted.
ldap_server_free_list()
To free the list of servers and associated LDAPServerInfo structures, the application must use the ldap_server_free_list() API. The ldap_server_free_list() API frees the linked list of LDAPServerInfo structures and all associated storage as returned from the ldap_server_locate() API.
ldap_server_conf_save()
The ldap_server_conf_save() API is used to store server information into local configuration. The format for specifying the server information about the ldap_server_conf_save() API is identical to the format returned from the ldap_server_locate() API.
The application that writes information into the configuration file can specify an optional time-to-live for the information that is stored in the file. When an application uses the locator API to access DNS server information, the configuration file is considered to be stale if:
date/time_file_last_updated + ttl > current_date/time

If the application uses the default behavior for using the configuration file, it bypasses a stale configuration file. It attempts to find all required information from DNS. Otherwise, the ttl must be set to zero (indefinite ttl), in which case the information is considered to be good indefinitely.

Setting a nonzero ttl is most useful when an application or other mechanism exists for refreshing the local configuration file on a periodic basis.

Note: Subsecond response time can be expected in many cases, when you use UDP to query DNS. Since most applications get the server information during initialization, repetitive invocation of the locator API is usually unnecessary.
By default, the configuration file is stored in the following platform-specific location:
UNIX™
/etc/ldap_server_info.conf
Windows NT and Windows™ 2000
\drivers\etc\ldap_server_info.conf
Format of local configuration file
The following sample shows the definition for a local configuration file that is created with the ldap_server_conf_save() API. You must create the file by using the ldap_server_conf_save() API. However, with careful editing, it can also be created and maintained manually. Some basic rules for managing this file manually:
  • Comment fields must begin with a number sign ( # ). Comment fields are ignored.
  • All parameters are positional.
  • The first non-comment line must contain the time-to-live value for the file.
#################################################################
# Local LDAP DNS configuration file.
#
# The following line holds the file's expiration time, which is
# a UNIX time_t value (time in seconds since January 1, 1970 UTC).
# A value of 0 indicates that the file will not expire.
#907979782
0
# Each of the following lines in this file represents a known
# LDAP server. The lines have the following format:
#
# service domain host priority weight port replica sec "suffix" 
        "vendor info" "general info"
#
# where:
#
#  service= service_key[.eNetwork_domain]
#
#  domain=  DNS domain
#
#  host=    fully qualified DNS name of the LDAP Server host
#
#  priority= target host with the lowest priority tried first
#
#  weight=  load balancing method.  When multiple hosts have the
#           same priority, the host to be contacted first is 
#           determined by the weight value.  
#           Set to 0 if load balancing is not needed.
#
#  port=    The port to use to contact the LDAP Server.
#
#  replica= Use "1" to indicate Master.
#           "2" to indicate Replica.
#
#  sec=     Use "1" to indicate Non-SSL
#           "2" to indicate SSL.
#
#  suffix=  A suffix on the server.
#
#  vendor info= a string that identifies the LDAP server vendor
#
#  general info=    Any informational text you wish to include.
#
ldap     austin.ibm.com ldapserver1.austin.ibm.com 1 1 389 1 1 
        "ou=users,o=sample" "IBM SecureWay" "phoneinfo"
ldap     austin.ibm.com ldapserver2.austin.ibm.com 1 1 389 2 1 
        "ou=users,o=sample" "IBM SecureWay" "phoneinfo replica"
ldap.gso austin.ibm.com gso3.austin.ibm.com 1 1 636 1 2 "" ""
ldap.gso austin.ibm.com gso3.austin.ibm.com 1 1 636 1 2 
        "cn=GSO,o=sample"
ldap.gso austin.ibm.com gso3.austin.ibm.com 1 1 636 1 2 
        "ou=Austin,o=sample" "IBM" "GSO ePersonbase"
ldap.gso austin.ibm.com gso3.austin.ibm.com 1 1 389 1 1 "" ""
ldap.gso austin.ibm.com gso3.austin.ibm.com 1 1 389 1 1 
        "cn=GSO,o=sample"
ldap.gso austin.ibm.com gso3.austin.ibm.com 1 1 389 1 1 
        "ou=Austin,o=sample" "IBM" "GSO ePersonbase"
ldap.sales raleigh.ibm.com saleshost1.raleigh.ibm.com 1 1 389 1 1 
        "dc=raleigh,dc=ibm, dc=com" "IBM" "Sales Marketing"
ldap.sales raleigh.ibm.com saleshost2.raleigh.ibm.com 2 1 389 2 1 
        "dc=raleigh,dc=ibm, dc=com" "IBM" "Sales Marketing Replica"
#
###################################################################
The newer form of service keys can also be used in the configuration file. For example, the following code is an excerpt that uses _ldap as the service key:
_ldap     austin.ibm.com ldapserver1.austin.ibm.com 1 1 389 1 1 
        "ou=users,o=sample" "IBM SecureWay" "phoneinfo"
_ldap     austin.ibm.com ldapserver2.austin.ibm.com 1 1 389 2 1 
        "ou=users,o=sample" "IBM SecureWay" "phoneinfo replica"
_ldap.gso austin.ibm.com gso3.austin.ibm.com 1 1 636 1 2 "" ""
_ldap.gso austin.ibm.com gso3.austin.ibm.com 1 1 636 1 2 
        "cn=GSO,o=sample"
_ldap.gso austin.ibm.com gso3.austin.ibm.com 1 1 636 1 2 
        "ou=Austin,o=sample" "IBM" "GSO ePersonbase"
_ldap.gso austin.ibm.com gso3.austin.ibm.com 1 1 389 1 1 "" ""
_ldap.gso austin.ibm.com gso3.austin.ibm.com 1 1 389 1 1 
        "cn=GSO,o=sample"
_ldap.gso austin.ibm.com gso3.austin.ibm.com 1 1 389 1 1 
        "ou=Austin,o=sample" "IBM" "GSO ePersonbase"
_ldap.sales raleigh.ibm.com saleshost1.raleigh.ibm.com 1 1 389 1 1 
        "dc=raleigh,dc=ibm,dc=com" "IBM" "Sales Marketing"
_ldap.sales raleigh.ibm.com saleshost2.raleigh.ibm.com 2 1 389 2 1 
        "dc=raleigh,dc=ibm,dc=com" "IBM" "Sales Marketing Replica"
Publishing LDAP server information in DNS
If DNS is used to publish LDAP server information, the LDAP administrator must configure the relevant DNS name servers with the appropriate SRV and TXT records. The records reflect the LDAP servers available in the enterprise.
  • If SRV records are supported by the DNS servers in the enterprise, SRV records can be created that identify the LDAP servers. They identify with appropriate weighting and priority settings. For more information about SRV records and how they are used, see A. Gulbrandsen, P. Vixie, "A DNS RR for Specifying the Location of Services (DNS SRV)", Internet RFC 2782, Troll Technologies, Vixie Enterprises, February, 2000, which obsoletes RFC 2052.
  • TXT records must be associated with the A record of each LDAP server. The TXT records include the LDAP URL records which specify host name, port, base DN, and port type. For example, ldap for non-SSL, and ldaps for SSL.
  • If SRV records are not used, the list of available servers must be specified with a set of TXT records which emulate the SRV RR format.
The LDAP server locator API:
  • Provides access to a list of LDAP servers. By default, the locator API queries a local configuration file for the required information. If the file was updated with a nonzero time-to-live, and the file is stale, or the file does not contain the required information, the locator API then accesses DNS. By default, the local configuration file has no time-to-live, and is considered to be good indefinitely.
    Note: The configuration file is designed to hold the same level of information per server that can be obtained from DNS.
  • Gathers data relevant to each of the LDAP servers from DNS, by using three sequenced algorithms:
    1. SRV records
    2. Pseudo-SRV records (by using TXT records)
    3. A CNAME alias that references a single host A record
    The algorithms are attempted in sequence until results are returned for one of the algorithms. For example, if no SRV records are found, but pseudo-SRV records are found, the list of servers is built from the pseudo-SRV records.
  • Builds a list of LDAP servers, with the first server in the list that is classified as the preferred or default server. Depending on how DNS publishes LDAP servers, the preferred LDAP server can be a reflection of how the administrator organizes the LDAP information in DNS. The application has access to the additional data that was retrieved from DNS. The additional information for each LDAP server information structure can consist of the following information:
    • Host name and port
    • eNetwork domain of the server
    • Fully qualified DNS domain where the host name is published
    • Suffix
    • Replication type (master or replica)
    • Security type (SSL or non-SSL)
    • Vendor ID
    • Administrator-defined data

The application can use ldap_server_locate() to obtain a list of one or more LDAP servers that exist in the enterprise. It is published in either DNS or the local configuration file. The additional data might be used by the application to select the appropriate server. For example, the application might require a server that supports a specific suffix, or might require to specifically access the master for update operations.

As input to the API, the application can supply:
  • A list of one or more DNS name server IP addresses. The default is to use the locally configured list of name server addresses. When an active name server is located, it is used for all subsequent processing.
  • The service key. The default is ldap. The service key is used to query DNS for information specific to the LDAP protocol. For example, when you search for SRV records in the austin.ibm.com DNS domain, the search is for ldap.tcp.austin.ibm.com with type=SRV. This example assumes that the search does not include an eNetwork domain component. The application can also specify _ldap as the service key and _tcp for the protocol, in which case the search is for _ldap._tcp.austin.ibm.com with type=SRV.
  • The name of the eNetwork domain. The eNetwork domain is typically the name that is used to identify the LDAP user authentication domain. It further qualifies the search for relevant LDAP servers, as published in the user DNS domain. For example, when you search for SRV records in the austin.ibm.com DNS domain, with an eNetwork domain of marketing the search is for ldap.marketing.tcp.austin.ibm.com with type=SRV.
  • A list of one or more fully qualified DNS domain names. The default is to use the locally configured domains.
    If multiple domains are supplied, either in the default configuration or explicitly supplied by the application, information is gathered from each DNS domain. The server information that is returned from the locator API is grouped by DNS domain. If two domains are supplied, for example, austin.ibm.com and raleigh.ibm.com, the entries for LDAP servers that are published in the austin.ibm.com domain is first in the list, with the austin.ibm.com servers that are sorted by priority and weight. Entries for LDAP servers that are published in the raleigh.ibm.com domain follows the entire set of austin.ibm.com servers (with the raleigh.ibm.com servers that are sorted by priority and weight).
    Note: All entries that are returned by the locator API are associated with a single service_key.edomain combination.
    DNS domain names that are supplied here can take two forms:
    • austin.ibm.com (standard DNS format)
    • cn=fred, ou=accounting, dc=austin, dc=ibm, dc=com
    About providing a fully qualified DNS domain name, these provisions are equivalent. Both result in a DNS domain name of austin.ibm.com. This approach makes it easier for an application to locate LDAP servers it requires to bind with, based on a user name space. This space is mapped into the DNS name space.
  • The connection type (UDP or TCP).
  • A DN for comparison against the suffix that are defined for each LDAP server entry. This string, if supplied, is used as a filter. Only server entries that define a suffix that compares with the DN are returned by the locator API. For example, a DN of "cn=fred, ou=accounting, o=sample" matches the first of the following DN, but not the second:
    • o=sample
    • o=tivoli, c=us
    The ability to filter based upon each LDAP server suffix is supplied as a convenience. Therefore, the application does not require to step through the list of servers, comparing a DN with each entry suffix.
  • The application can specify how information in the local configuration file is used. The default is to look in the local, configuration file for the wanted information. If the information is not found, then DNS servers on the network are accessed. The application can specify the following information:
    • Look in the configuration file first, then access the network (default).
    • Look in the configuration file only.
    • Access DNS only.
    When you use the default configuration file, the application is not required to specify the location. Alternatively, the application can provide a path name to a configuration file.
    Note: Information that is stored in the configuration file takes the same form as information obtained from DNS. The difference is that it is saved in the file by an application. The file can also be constructed and distributed to users by the administrator.
    Maximum benefit is obtained when applications can use the defaults for all the parameters. This benefit minimizes application knowledge of the specifics that is related to locating LDAP servers.
Using SRV and TXT records

The DNS-lookup routine looks for SRV records first. If one or more servers are found, then the server information is returned. The second algorithm, which is based on TXT records that emulate SRV records, is not called.

Use the SRV records for finding the address of servers and for a specific protocol and domain. This use is described in RFC 2052, "A DNS RR for Specifying the Location of Services (DNS SRV)". Correct use of the SRV RR grants the administrator the following actions:
  • Distribute a service across multiple hosts within a domain
  • Move the service from host to host without disruption
  • Designate certain hosts as primary and others as alternates, or backups, by using a priority and weighting scheme
TXT stands for text. TXT records are strings. BIND versions before 4.8.3 do not support TXT records. To fully implement the technique that is described in RFC 2052, the DNS name servers must use a version of BIND. This version supports SRV records and TXT records. An SRV resource record (RR) has the following components, as described in RFC 2052:
service.proto.name ttl class SRV priority weight port target
where:
service
Symbolic name of the wanted service. By default, the service name or service key is ldap. When used to publish servers that are associated with an eNetwork domain, the service value is derived by concatenating the service key, for example, ldap. With the eNetwork domain name, for example, marketing. In this example, the resulting service is ldap.marketing.
proto
Protocol, typically tcp or udp, or _tcp or _udp.
name
Domain name that is associated with the RR.
ttl
Time-to-live, standard DNS meaning.
class
Standard DNS meaning. For example, IN.
Priority
Target host with lowest number priority must be attempted first.
weight
Load balancing mechanism. When multiple target hosts have the same priority, the chance of contacting one of the hosts first must be proportional to its weight. Set to 0 if load balancing is not necessary.
port
Port on the target host for the service.
target
Target host name must have one or more A records that are associated with it.
The approach is to use SRV records to define a list of candidate LDAP servers. Then, use TXT records that are associated with the A record of each host to get more information about each LDAP server. Three forms of TXT records are understood by the LDAP client DNS lookup routines:
  • The service TXT record provides a standard LDAP URL, that is, provides host, port and base DN.
  • The ldaptype TXT record identifies whether the LDAP server is a master or replica.
  • The ldapvendor TXT record identifies the vendor.
ldap         A       199.23.45.296
             TXT     "service:ldap://ldap.ibm.com:389/o=foo,c=us"
             TXT     "ldaptype: master"
             TXT     "ldapvendor: IBMeNetwork"
             TXT     "ldapinfo: ldapver=3, keyx=fastserver"   
The ldapinfo freeform TXT record provides more information, as defined by the LDAP or network administrator. As in the example above, the information can be keyword-based. The ldapinfo record is available to the application.
In combination, the name server might contain the following information, which effectively publishes the set of LDAP servers that are in the marketing eNetwork domain:
ldap.marketing.tcp    SRV     0  0  0    ldapm
                      SRV     0  0  0    ldapmsec
                      SRV     0  0  0    ldapmsuffix
                      SRV     1  1  0    ldapr1
                      SRV     1  2  0    ldapr2
                      SRV     1  2  0    ldapr2sec
                      SRV     2  1  2222 ldapr3.raleigh.ibm.com.
                               
ldapm        A       199.23.45.296
             TXT     "service:ldap://ldapm.austin.ibm.com:389/o=foo,c=us"
             TXT     "ldaptype: master"

ldapmsec     A       199.23.45.296
             TXT     "service:ldaps://ldapm.austin.ibm.com:686/o=foo,c=us"
             TXT     "ldaptype: master"

ldapmsuffix  A       199.23.45.296
             TXT     "service:ldaps://ldapm.austin.ibm.com:389/o=moo,c=us"
             TXT     "ldaptype: master"

ldapr1       A       199.23.45.297
             TXT     "service:ldap://ldapr1:389/o=foo,c=us"
             TXT     "ldaptype: replica"

ldapr2       A       199.23.45.298
             TXT     "service:ldap://ldapr2:389/o=foo,c=us"
             TXT     "ldaptype: replica"

ldapr2sec    A       199.23.45.298
             TXT     "service:ldaps://ldapr2/o=foo,c=us"         
             TXT     "ldaptype: replica"     
             TXT     "ldapinfo: ca=verisign, authtype=server"   

ldapr3.raleigh.ibm.com.   A   199.23.45.299
In this example, a DNS search for ibmldap.marketing.tcp.austin.ibm.com with type=SRV returns seven SRV records, which represent entries for four hosts. An SRV record is required for each port or suffix combination that is supported by a server. For example, a server that supports an SSL and non-SSL port might have at least two SRV records and two corresponding A records. These records point to the same IP address. In this example, the A RR combinations for ldapm/ldapmsec/ldapmsuffix and ldapr2/ldapr2sec map to the same host address.
Note: ldapmsuffix provides an alternative suffix for the 199.23.45.296 host.

The port that is specified on the SRV record is ignored if the target host has a TXT record that contains an LDAP URL. If the URL is specified without a port, the default port is used (389 for non-SSL, 686 for SSL).

Some rules for constructing strings that are associated with the TXT records:
  • If the string contains white space, the entire string that follows TXT must be enclosed in double quotation marks.
  • If the string contains characters that are not supported by DNS. For example, the suffix might contain characters that are not supported by DNS, an escape is supported, based on the technique that is described in "Uniform Resource Locators (URL)", Internet RFC 1738, December 1994. For example:
    TXT     "service:ldaps://ldapr2/o=foo%f0,c=us"
    grants the x'f0' character to be included in the LDAP URL.

The algorithm for the use of LDAP servers is outlined as follows. The LDAP servers are ordered in the list that is based on this algorithm. The application has the freedom of using the first server in the list that is based on priority and weight. It also has the freedom to select a different server, which is based upon its requirements.

Using pseudo-SRV TXT records

If the SRV algorithm does not return any servers, the secondary algorithm is called. Instead of looking for SRV records, the lookup routine runs a TXT query. It uses the service name string that is supplied on ldap_server_locate(), which defaults to ldap.tcp.

The intent is to emulate the scheme that is provided with SRV records, but by using a search for TXT records instead. To duplicate the previous example by using TXT records instead of SRV records, the following definition is used:
ldap.marketing.tcp    TXT     0  0  0    ldapm
                      TXT     0  0  0    ldapmsec
                      TXT     0  0  0    ldapmsuffix
                      TXT     1  1  0    ldapr1
                      TXT     1  2  0    ldapr2
                      TXT     1  2  0    ldapr2sec
                      TXT     2  1  2222 ldapr3.raleigh.ibm.com.
                               
ldapm        A       199.23.45.296
             TXT     "service:ldap://ldapm.austin.ibm.com:389/o=foo,c=us"       
             TXT     "ldaptype: master"        

ldapmsec     A       199.23.45.296
             TXT     "service:ldaps://ldapm.austin.ibm.com:686/o=foo,c=us"
             TXT     "ldaptype: master"    

ldapmsuffix  A       199.23.45.296    
             TXT     "service:ldaps://ldapm.austin.ibm.com:389/o=moo,c=us"
             TXT     "ldaptype: master" 

ldapr1       A       199.23.45.297
             TXT     "service:ldap://ldapr1:389/o=foo,c=us"         
             TXT     "ldaptype: replica"        

ldapr2       A       199.23.45.298
             TXT     "service:ldap://ldapr2:389/o=foo,c=us"         
             TXT     "ldaptype: replica"        

ldapr2sec    A       199.23.45.298
             TXT     "service:ldaps://ldapr2/o=foo,c=us"         
             TXT     "ldaptype: replica"     
             TXT     "ldapinfo: ca=verisign, authtype=server"   

ldapr3.raleigh.ibm.com.   A   199.23.45.299
The LDAP resolver routine assumes that the default domain is in effect when the SRV-type TXT records do not contain fully qualified domain names.
Note: The pseudo-SRV TXT records, in many cases, can exactly replicate the syntax of SRV records, with the exception that SRV is replaced by TXT. This replication makes for consistent parsing of the records by the resolver routines. It also makes it simple to switch between the two mechanisms when you insert this information into the DNS database. However, some versions of DNS require data that is associated with the TXT records to be enclosed in double quotation marks, as follows:
ldap.marketing.tcp    TXT     "0  0  0    ldapm"
                      TXT     "0  0  0    ldapmsec"
The ldap_server_locate() API handles either format.
Using a CNAME alias record
If the pseudo-SRV algorithm does not return any servers, the third algorithm is called. Instead of looking for TXT records, the lookup routine runs a standard query by using the service name string that is supplied on ldap_server_locate(), which defaults to ldap.
ldap.marketing.tcp    CNAME   ldapm
                              
ldapm        A       199.23.45.296
             TXT     "service:ldap://ldapm.austin.ibm.com:389/o=foo,c=us"       
             TXT     "ldaptype: master"     
If TXT records are not associated with the A record, defaults are assumed for port and ldaptype.
Alternative scheme for publishing LDAP server information in DNS

A more recent Internet Engineering Task Force (IETF) draft describes a scheme where service keys and the protocol are prefixed with an underscore ( _ ). For more information about this new scheme, see the following internet draft: A. Gulbrandsen, P. Vixie, "A DNS RR for Specifying the Location of Services (DNS SRV)", Internet RFC 2052, Troll Technologies, Vixie Enterprises. January 1999

When services are published in DNS by using the approach that is proposed in this IETF draft, service names and protocol are prefixed with an underscore ( _ ).

For instance, a previous example might be defined as follows:
_ldap.marketing._tcp    SRV     0  0  0    ldapm
                        SRV     0  0  0    ldapmsec
                        SRV     0  0  0    ldapmsuffix
                        SRV     1  1  0    ldapr1
                        SRV     1  2  0    ldapr2
                        SRV     1  2  0    ldapr2sec
                        SRV     2  1  2222 ldapr3.raleigh.ibm.com.
If all LDAP service information is published within your enterprise this way, the application can choose to not specify service key or protocol, and the ldap_server_locate() API first runs its search by using ldap and tcp. The search does not find any entries, and the API automatically runs the search again by using _ldap and _tcp for service key and protocol. The search returns the information that is published with the alternative scheme.

If information is published with both schemes, the application must explicitly define the service key and protocol, to ensure that the wanted information is returned.

Errors

ldap_server_locate(), ldap_server_free_list and ldap_server_conf_save() return the LDAP error code that results from the operation.

For more information, see LDAP_ERROR.

See also

ldap_error