Document revision date: 30 March 2001
[Compaq] [Go to the documentation home page] [How to order documentation] [Help on this site] [How to contact us]
[OpenVMS documentation]

OpenVMS Utility Routines Manual


Previous Contents Index

12.1.4.3 Mixing Pointer Sizes

Two modules that include LDAP.H can be compiled with different pointer sizes and linked together. While each module may use the LDAP API on its own, it may not be possible for both modules to share LDAP-related data.

None of the public LDAP data structures is directly compatible between 32- and 64-bit modules. For example, a BerValue that has been allocated by a 32-bit module does not have the same layout as a BerValue which a 64-bit module expects to see, and consequently cannot be exchanged between two such modules without some sort of data conversion taking place.

Opaque data structures (such as LDAP *) have only a single structure definition inside the library, and so pointers to such structures may be exchanged between 32- and 64-bit callers. Note that these structures are allocated only by the library itself, and, in the case of a 64-bit caller, these structures may be allocated in 64-bit space. So while the LDAP handle returned to a 32-bit caller of ldap_init() could safely be used by a 64-bit module, the reverse may not be true.

12.1.5 Multithreading Support

The OpenVMS LDAP API may be used by a multi-threaded application. Two of the functions in the library, ldap_perror() and ldap_result2error() , are not thread-safe.

12.2 Common Data Structures and Memory Handling

The following are definitions of some data structures that are common to several LDAP API functions.


        
typedef struct ldap LDAP; 
        
typedef struct berelement BerElement; 
        
typedef struct ldapmsg LDAPMessage; 
        
typedef struct berval { 
    ber_len_t       bv_len;                
    char            *bv_val;        
} BerValue; 
 
        
struct timeval; 
 

The LDAP structure is an opaque data type that represents an LDAP session. Typically, this corresponds to a connection to a single server, but it may encompass several server connections in LDAPv3 referrals.

The LDAPMessage structure is an opaque data type that is used to return entry, reference, result, and error information. An LDAPMessage structure may represent the beginning of a list or a chain of messages that contain a series of entries, references, and result messages that are returned by LDAP operations, such as search. LDAP API functions, such as ldap_parse_result() , that operate on message chains which may contain more than one result message, always operate on the first result message in the chain. See Section 12.17 for more information.

The BerElement structure is an opaque data type that is used to hold data and state information about encoded data.

The berval structure is used to represent arbitrary binary data, and its fields have the following meanings:
bv_len Length of data in bytes.
bv_val A pointer to the data itself.

The timeval structure is used to represent an interval of time, and its fields have the following meanings:
tv_sec Seconds component of time interval.
tv_usec Microseconds component of time interval.

All memory that is allocated by a function in this C LDAP API and returned to the caller should be disposed of by calling the appropriate free function provided by this API. The correct free function to call is documented in each section of this chapter where a function that allocates memory is described.

Memory that is allocated outside of the C LDAP API must not be disposed of using a function provided by this API.

The following is a complete list of free functions that are used to dispose of allocated memory:


   ber_bvecfree() 
 
   ber_bvfree() 
 
   ber_free() 
 
   ldap_control_free() 
 
   ldap_controls_free() 
 
   ldap_memfree() 
 
   ldap_msgfree() 
 
   ldap_value_free() 
 
   ldap_value_free_len() 
 

12.3 LDAP Error Codes

Many of the LDAP API functions return LDAP error codes, some of which indicate local errors and some of which may be returned by servers. All of the LDAP error codes returned will be positive integers; those between 0x00 and 0x50 are returned from the LDAP server, those above 0x50 are generated by the API itself. Supported error codes are as follows (hexadecimal values are given in parentheses after the constant):


     LDAP_SUCCESS (0x00) 
     
     LDAP_OPERATIONS_ERROR (0x01) 
 
     LDAP_PROTOCOL_ERROR (0x02) 
 
     LDAP_TIMELIMIT_EXCEEDED (0x03) 
 
     LDAP_SIZELIMIT_EXCEEDED (0x04) 
 
     LDAP_COMPARE_FALSE (0x05) 
 
     LDAP_COMPARE_TRUE (0x06) 
 
     LDAP_STRONG_AUTH_NOT_SUPPORTED (0x07) 
 
     LDAP_STRONG_AUTH_REQUIRED (0x08) 
 
     LDAP_REFERRAL (0x0a)                            -- new in LDAPv3 
 
     LDAP_ADMINLIMIT_EXCEEDED (0x0b)                 -- new in LDAPv3 
 
     LDAP_UNAVAILABLE_CRITICAL_EXTENSION (0x0c)      -- new in LDAPv3 
 
     LDAP_CONFIDENTIALITY_REQUIRED (0x0d)            -- new in LDAPv3 
 
     LDAP_SASL_BIND_IN_PROGRESS (0x0e)               -- new in LDAPv3 
 
     LDAP_NO_SUCH_ATTRIBUTE (0x10) 
 
     LDAP_UNDEFINED_TYPE (0x11) 
 
     LDAP_INAPPROPRIATE_MATCHING (0x12) 
 
     LDAP_CONSTRAINT_VIOLATION (0x13) 
 
     LDAP_TYPE_OR_VALUE_EXISTS (0x14) 
 
     LDAP_INVALID_SYNTAX (0x15) 
 
     LDAP_NO_SUCH_OBJECT (0x20) 
 
     LDAP_ALIAS_PROBLEM (0x21) 
 
     LDAP_INVALID_DN_SYNTAX (0x22) 
 
     LDAP_IS_LEAF (0x23)                        -- not used in LDAPv3 
 
     LDAP_ALIAS_DEREF_PROBLEM (0x24) 
 
     LDAP_INAPPROPRIATE_AUTH (0x30) 
 
     LDAP_INVALID_CREDENTIALS (0x31) 
 
     LDAP_INSUFFICIENT_ACCESS (0x32) 
 
     LDAP_BUSY (0x33) 
 
     LDAP_UNAVAILABLE (0x34) 
 
     LDAP_UNWILLING_TO_PERFORM (0x35) 
 
     LDAP_LOOP_DETECT (0x36) 
 
     LDAP_NAMING_VIOLATION (0x40) 
 
     LDAP_OBJECT_CLASS_VIOLATION (0x41) 
 
     LDAP_NOT_ALLOWED_ON_NONLEAF (0x42) 
 
     LDAP_NOT_ALLOWED_ON_RDN (0x43) 
 
     LDAP_ALREADY_EXISTS (0x44) 
 
     LDAP_NO_OBJECT_CLASS_MODS (0x45) 
 
     LDAP_RESULTS_TOO_LARGE (0x46)                -- reserved for CLDA 
 
     LDAP_AFFECTS_MULTIPLE_DSAS (0x47)            -- new in LDAPv3 
 
     LDAP_OTHER (0x50) 
 
     LDAP_SERVER_DOWN (0x51) 
 
     LDAP_LOCAL_ERROR (0x52) 
 
     LDAP_ENCODING_ERROR (0x53) 
 
     LDAP_DECODING_ERROR (0x54) 
 
     LDAP_TIMEOUT (0x55) 
 
     LDAP_AUTH_UNKNOWN (0x56) 
 
     LDAP_FILTER_ERROR (0x57) 
  
     LDAP_USER_CANCELLED (0x58) 
 
     LDAP_PARAM_ERROR (0x59) 
 
     LDAP_NO_MEMORY (0x5a) 
 
     LDAP_CONNECT_ERROR (0x5b) 
 
     LDAP_NOT_SUPPORTED (0x5c) 
 
     LDAP_CONTROL_NOT_FOUND (0x5d) 
 
     LDAP_NO_RESULTS_RETURNED (0x5e) 
 
     LDAP_MORE_RESULTS_TO_RETURN (0x5f) 
 
     LDAP_CLIENT_LOOP (0x60) 
 
     LDAP_REFERRAL_LIMIT_EXCEEDED (0x61) 
 

12.4 Initializing an LDAP Session

The ldap_init() function initializes a session with an LDAP server. The server is not actually contacted until an operation is performed that requires it, allowing various options to be set after initialization.


        LDAP *ldap_init( 
              const char    *hostname, 
              int           portno); 

Use of the following function is deprecated.


        LDAP *ldap_open( 
              const char    *hostname, 
              int           portno); 

Unlike ldap_init() , the ldap_open() function attempts to make a server connection before returning to the caller. A more complete description can be found in RFC 1823.

Parameters are as follows:
hostname Contains a space-separated list of hostnames or dotted strings representing the IP address of hosts running an LDAP server to connect to. Each hostname in the list can include an optional port number which is separated from the host itself with a colon (:) character. The hosts are tried in the order listed, stopping with the first one to which a successful connection is made. Note that only ldap_open() attempts to make the connection before returning to the caller. ldap_init() does not connect to the LDAP server.
portno Contains the TCP port number to connect to. The default LDAP port of 389 can be obtained by supplying the constant LDAP_PORT. If a host includes a port number, then this parameter is ignored.

The ldap_init() and ldap_open() functions both return a session handle, a pointer to an opaque structure that should be passed to subsequent calls pertaining to the session. These functions return NULL if the session cannot be initialized, in which case the operating system error reporting mechanism can be checked to see why the call failed.

Note that if you connect to an LDAP Version 2 server, one of the ldap_bind() calls must be completed before other operations can be performed on the session. LDAPv3 does not require that a bind operation be completed before other operations can be performed.

The calling program can set various attributes of the session by calling the functions described in the next section.

12.5 LDAP Session Handle Options

The LDAP session handle returned by ldap_init() is a pointer to an opaque data type representing an LDAP session. Formerly, this data type was a structure exposed to the caller, and various fields in the structure could be set to control aspects of the session, such as size and time limits on searches.

To insulate callers from inevitable changes to this structure, these aspects of the session are now accessed through a pair of accessor functions.

The ldap_get_option() function is used to access the current value of various session-wide parameters. The ldap_set_option() function is used to set the value of these parameters. Note that some options are READ-ONLY and cannot be set; it is an error to call ldap_set_option() and attempt to set a READ-ONLY option.


        int ldap_get_option( 
                LDAP            *ld, 
                int             option, 
                void            *outvalue 
        ); 
 
        int ldap_set_option( 
                LDAP            *ld, 
                int             option, 
                const void      *invalue 
        ); 

Parameters are as follows:
ld The session handle. If this is NULL, a set of global defaults is accessed. New LDAP session handles created with ldap_init() or ldap_open() inherit their characteristics from these global defaults.
option The name of the option being accessed or set. This parameter should be one of the following constants, which have the indicated meanings. After the constant, the actual hexadecimal value of the constant is listed in parentheses.
  LDAP_OPT_DESC (0x01) Type for invalue parameter: not applicable (option is read-only).
Type for outvalue parameter: int *

Description: The underlying socket descriptor corresponding to the primary LDAP connection. This option is read-only and cannot be set.

  LDAP_OPT_DEREF (0x02) Type for invalue parameter: int *
Type for outvalue parameter: int *

Description: Determines how aliases are handled during search. It can have one of the following values: LDAP_DEREF_NEVER (0x00), LDAP_DEREF_SEARCHING (0x01), LDAP_DEREF_FINDING (0x02), or LDAP_DEREF_ALWAYS (0x03). The LDAP_DEREF_SEARCHING value means aliases should be dereferenced during the search but not when locating the base object of the search.The LDAP_DEREF_FINDING value means aliases should be dereferenced when locating the base object but not during the search.

  LDAP_OPT_SIZELIMIT (0x03) Type for invalue parameter: int *
Type for outvalue parameter: int *

Description: A limit on the number of entries to return from a search. A value of LDAP_NO_LIMIT (0) means no limit.

  LDAP_OPT_TIMELIMIT (0x04) Type for invalue parameter: int *
Type for outvalue parameter: int *

Description: A limit on the number of seconds to spend on a search. A value of LDAP_NO_LIMIT (0) means no limit.

  LDAP_OPT_REFERRALS (0x08) Type for invalue parameter: int (LDAP_OPT_ON or LDAP_OPT_OFF)
Type for outvalue parameter: int *

Description: Determines whether the LDAP library automatically follows referrals returned by LDAP servers. It can be set to one of the constants LDAP_OPT_ON (1) or LDAP_OPT_OFF (0).

  LDAP_OPT_RESTART (0x09) Type for invalue parameter: int (LDAP_OPT_ON or LDAP_OPT_OFF)
Type for outvalue parameter: int *

Description: Determines whether LDAP I/O operations should automatically be restarted if they abort prematurely. It should be set to one of the constants LDAP_OPT_ON or LDAP_OPT_OFF. This option is useful if an LDAP I/O operation is interrupted prematurely, (for example, by a timer going off) or other interrupt.

  LDAP_OPT_PROTOCOL_VERSION (0x11) Type for invalue parameter: int *
Type for outvalue parameter: int *

Description: This option indicates the version of the LDAP protocol used when communicating with the primary LDAP server. It must be one of the constants LDAP_VERSION2 (2) or LDAP_VERSION3 (3). If no version is set, the default is LDAP_VERSION2 (2).

  LDAP_OPT_SERVER_CONTROLS (0x12) Type for invalue parameter: LDAPControl **
Type for outvalue parameter: LDAPControl ***

Description: A default list of LDAP server controls to be sent with each request. See Section 12.6 for more information.

  LDAP_OPT_CLIENT_CONTROLS (0x13) Type for invalue parameter: LDAPControl **
Type for outvalue parameter: LDAPControl ***

Description: A default list of client controls that affect the LDAP session. See Section 12.6 for more information.

  LDAP_OPT_HOST_NAME (0x30) Type for invalue parameter: char *
Type for outvalue parameter: char **

Description: The host name (or list of host) for the primary LDAP server.

  LDAP_OPT_ERROR_NUMBER (0x31) Type for invalue parameter: int *
Type for outvalue parameter: int *

Description: The code of the most recent LDAP error that occurred for this session.

  LDAP_OPT_ERROR_STRING (0x32) Type for invalue parameter: char *
Type for outvalue parameter: char **

Description: The message returned with the most recent LDAP error that occurred for this session.

outvalue The address of a place to put the value of the option. The actual type of this parameter depends on the setting of the option parameter. For outvalues of type char ** and LDAPControl **, a pointer to data that is associated with the LDAP session ld is returned; callers should dispose of the memory by calling ldap_memfree() or ldap_controls_free() .
invalue A pointer to the value the option is to be given. The actual type of this parameter depends on the setting of the option parameter. The constants LDAP_OPT_ON and LDAP_OPT_OFF can be given for options that have on or off settings.

Both ldap_get_option() and ldap_set_option() return 0 if successful and -1 if an error occurs.

12.6 Working with Controls

LDAPv3 operations can be extended through the use of controls. Controls may be sent to a server or returned to the client with any LDAP message. These controls are referred to as server controls.

The LDAP API also supports a client-side extension mechanism through the use of client controls. These controls affect the behavior of the LDAP API only and are never sent to a server. A common data structure is used to represent both types of controls:


        typedef struct ldapcontrol { 
                char                            *ldctl_oid; 
                struct berval                   ldctl_value; 
                char                            ldctl_iscritical; 
        } LDAPControl, *PLDAPControl; 

The fields in the ldapcontrol structure have the following meanings:
ldctl_oid The control type, represented as a string.
ldctl_value The data associated with the control (if any). To specify a zero-length value, set ldctl_value.bv_len to zero and ldctl_value.bv_val to a zero-length string. To indicate that no data is associated with the control, set ldctl_value.bv_val to NULL.
ldctl_iscritical Indicates whether the control is critical or not. If this field is non-zero, the operation will only be carried out if the control is recognized by the server and/or client.

Some LDAP API calls allocate an ldapcontrol structure or a NULL-terminated array of ldapcontrol structures. The following functions can be used to dispose of a single control or an array of controls:


     void ldap_control_free( LDAPControl *ctrl ); 
 
     void ldap_controls_free( LDAPControl **ctrls ); 

A set of controls that affect the entire session can be set using the ldap_set_option() function. A list of controls can also be passed directly to some LDAP API calls, such as ldap_search_ext() , in which case any controls set for the session through the use of ldap_set_option() are ignored. Control lists are represented as a NULL-terminated array of pointers to ldapcontrol structures.

Server controls are defined by LDAPv3 protocol extension documents; for example, a control has been proposed to support paging of search results. No client controls are currently implemented in this version of the API.

12.7 Authenticating to the Directory

The following functions are used to authenticate an LDAP client to an LDAP directory server.

The ldap_sasl_bind() and ldap_sasl_bind_s() functions can be used to do general and extensible authentication over LDAP through the use of the Simple Authentication Security Layer. The functions both take the DN to bind as, the method to use, as a dotted-string representation of an OID identifying the method, and a struct berval holding the credentials. The special constant value LDAP_SASL_SIMPLE (NULL) can be passed to request simple authentication, or the simplified functions ldap_simple_bind() or ldap_simple_bind_s() can be used.


        int ldap_sasl_bind( 
                LDAP                                    *ld, 
                const char                              *dn, 
                const char                              *mechanism, 
                const struct berval                     *cred, 
                LDAPControl                             **serverctrls, 
                LDAPControl                             **clientctrls, 
                int                                     *msgidp 
        ); 
 
        int ldap_sasl_bind_s( 
                LDAP                                    *ld, 
                const char                              *dn, 
                const char                              *mechanism, 
                const struct berval                     *cred, 
                LDAPControl                             **serverctrls, 
                LDAPControl                             **clientctrls, 
                struct berval                           **servercredp 
        ); 
 
        int ldap_simple_bind( 
                LDAP                                    *ld, 
                const char                              *dn, 
                const char                              *passwd 
        ); 
 
        int ldap_simple_bind_s( 
                LDAP                                    *ld, 
                const char                              *dn, 
                const char                              *passwd 
        ); 

The use of the following functions is deprecated:


     int ldap_bind( LDAP *ld, char *dn, char *cred, int method ); 
 
     int ldap_bind_s( LDAP *ld, char *dn, char *cred, int method ); 

Parameters are as follows:
ld The session handle.
dn The name of the entry to bind as.
mechanism Either LDAP_SASL_SIMPLE (NULL) to get simple authentication, or a text string identifying the SASL method.
cred The credentials with which to authenticate. Arbitrary credentials can be passed using this parameter. The format and content of the credentials depends on the setting of the mechanism parameter.
passwd For ldap_simple_bind() , the password to compare to the entry's userPassword attribute.
serverctrls List of LDAP server controls.
clientctrls List of client controls.
msgidp This result parameter will be set to the message id of the request if the ldap_sasl_bind() call succeeds.
servercredp This result parameter will be filled in with the credentials passed back by the server for mutual authentication, if given. An allocated berval structure is returned that should be disposed of by calling ber_bvfree(). NULL may be passed to ignore this field.

Additional parameters for the deprecated functions are not described. See the RFC 1823 documentation for more information.

The ldap_sasl_bind() function initiates an asynchronous bind operation and returns the constant LDAP_SUCCESS if the request was successfully sent or another LDAP error code if not. See Section 12.18 for more information about possible errors and how to interpret them. If successful, ldap_sasl_bind() places the message id of the request in *msgidp. A subsequent call to ldap_result() can be used to obtain the result of the bind.

The ldap_simple_bind() function initiates a simple asynchronous bind operation and returns the message id of the operation initiated. A subsequent call to ldap_result() can be used to obtain the result of the bind. In case of error, ldap_simple_bind() will return -1, setting the session error parameters in the LDAP structure appropriately.

The synchronous ldap_sasl_bind_s() and ldap_simple_bind_s() functions both return the result of the operation, either the constant LDAP_SUCCESS if the operation was successful, or another LDAP error code if it was not. See Section 12.18 for more information about possible errors and how to interpret them.

Note that if an LDAP Version 2 server is contacted, no other operations over the connection should be attempted before a bind call has successfully completed.

Subsequent bind calls can be used to reauthenticate over the same connection, and multistep SASL sequences can be accomplished through a sequence of calls to ldap_sasl_bind() or ldap_sasl_bind_s() .


Previous Next Contents Index

  [Go to the documentation home page] [How to order documentation] [Help on this site] [How to contact us]  
  privacy and legal statement  
4493PRO_027.HTML