HP OpenVMS Utility Routines Manual


Previous Contents Index

14.19.2 Stepping Through the Attributes of an Entry

The ldap_first_attribute() and ldap_next_attribute() calls are used to step through the list of attribute types returned with an entry.


        char *ldap_first_attribute( 
                LDAP                                    *ld, 
                LDAPMessage                             *entry, 
                BerElement                              **ptr 
        ); 
 
        char *ldap_next_attribute( 
                LDAP                                    *ld, 
                LDAPMessage                             *entry, 
                BerElement                              *ptr 
        ); 
 
        void ldap_memfree( char *mem ); 

Parameters are as follows:
ld The session handle.
entry The entry whose attributes are to be stepped through, as returned by ldap_first_entry() or ldap_next_entry() .
ptr In ldap_first_attribute() , the address of a pointer used internally to keep track of the current position in the entry. In ldap_next_attribute() , the pointer returned by a previous call to ldap_first_attribute() .
mem A pointer to memory allocated by the LDAP library, such as the attribute type names returned by ldap_first_attribute() and ldap_next_attribute() , or the DN returned by ldap_get_dn() .

The ldap_first_attribute() and ldap_next_attribute() functions will return NULL when the end of the attributes is reached, or if there is an error, in which case the error parameters in the session handle ld will be set to indicate the error.

Both functions return a pointer to an allocated buffer containing the current attribute name. This should be freed when no longer in use by calling ldap_memfree() .

The ldap_first_attribute() function will allocate and return in ptr a pointer to a BerElement used to keep track of the current position. This pointer should be passed in subsequent calls to ldap_next_attribute() to step through the entry's attributes. After a set of calls to ldap_first_attribute() and ldap_next_attribute() , if ptr is non-NULL, it should be freed by calling ber_free(ptr, 0) . Note that it is very important to pass the second parameter as 0 (zero) in this call, since the buffer associated with the BerElement does not point to separately allocated memory.

The attribute type names returned are suitable for passing in a call to ldap_get_values() to retrieve the associated values.

14.19.3 Retrieving the Values of an Attribute

The ldap_get_values() and ldap_get_values_len() functions are used to retrieve the values of a given attribute from an entry. The ldap_count_values() and ldap_count_values_len() functions are used to count the returned values. The ldap_value_free() and ldap_value_free_len() functions are used to free the values.


        char **ldap_get_values( 
                LDAP            *ld, 
                LDAPMessage     *entry, 
                char            *attr 
        ); 
 
        struct berval **ldap_get_values_len( 
                LDAP            *ld, 
                LDAPMessage     *entry, 
                char            *attr 
        ); 
 
        int ldap_count_values( char **vals ) 
 
        int ldap_count_values_len( struct berval **vals ); 
 
        void ldap_value_free( char **vals ); 
 
        void ldap_value_free_len( struct berval **vals ); 

Parameters are as follows:
ld The session handle.
entry The entry from which to retrieve values, as returned by ldap_first_entry() or ldap_next_entry() .
attr The attribute whose values are to be retrieved, as returned by ldap_first_attribute() or ldap_next_attribute() , or a caller- supplied string (for example, "mail").
vals The values returned by a previous call to ldap_get_values() or ldap_get_values_len() .

Two forms of the various calls are provided. The first form is only suitable for use with non-binary character string data. The second _len form is used with any kind of data.

The ldap_get_values() and ldap_get_values_len() functions return NULL if no values are found for attr or if an error occurs.

The ldap_count_values() and ldap_count_values_len() functions return -1 if an error occurs such as the vals parameter being invalid.

Note that the values returned are dynamically allocated and should be freed by calling either ldap_value_free() or ldap_value_free_len() when no longer in use.

14.19.4 Retrieving the Name of an Entry

The ldap_get_dn() function is used to retrieve the name of an entry. The ldap_explode_dn() and ldap_explode_rdn() functions are used to break up a name into its component parts. The ldap_dn2ufn() function is used to convert the name into a more user-friendly format.


        char *ldap_get_dn( LDAP *ld, LDAPMessage *entry ); 
  
        char **ldap_explode_dn( const char *dn, int notypes ); 
 
        char **ldap_explode_rdn( const char *rdn, int notypes ); 
 
        char *ldap_dn2ufn( const char *dn ); 

Parameters are as follows:
ld The session handle.
entry The entry whose name is to be retrieved, as returned by ldap_first_entry() or ldap_next_entry() .
dn The dn to explode, such as returned by ldap_get_dn() .
rdn The rdn to explode, such as returned in the components of the array returned by ldap_explode_dn() .
notypes A boolean parameter, if non-zero indicating that the DN or RDN components should have their type information stripped off (i.e., "cn=Babs" would become "Babs").

The ldap_get_dn() function will return NULL if there is some error parsing the dn, setting error parameters in the session handle ld to indicate the error. It returns a pointer to newly allocated space that the caller should free by calling ldap_memfree() when it is no longer in use.

The ldap_explode_dn() function returns a NULL-terminated char * array containing the RDN components of the DN supplied, with or without types as indicated by the notypes parameter. The components are returned in the order they appear in the dn. The array returned should be freed when it is no longer in use by calling ldap_value_free() .

The ldap_explode_rdn() function returns a NULL-terminated char * array containing the components of the RDN supplied, with or without types as indicated by the notypes parameter. The components are returned in the order they appear in the rdn. The array returned should be freed when it is no longer in use by calling ldap_value_free() .

The ldap_dn2ufn() function converts the DN into the user friendly format. The UFN returned is newly allocated space that should be freed by a call to ldap_memfree() when no longer in use.

14.19.5 Retrieving Controls from an Entry

The ldap_get_entry_controls() function is used to extract LDAP controls from an entry.


  int ldap_get_entry_controls( 
          LDAP                                    *ld, 
          LDAPMessage                             *entry, 
          LDAPControl                             ***serverctrlsp 
  ); 

Parameters are as follows:
ld The session handle.
entry The entry to extract controls from, as returned by ldap_first_entry() or ldap_next_entry() .
serverctrlsp This result parameter will be filled in with an allocated array of controls copied out of entry. The control array should be freed by calling ldap_controls_free() . If serverctrlsp is NULL, no controls are returned.

The ldap_get_entry_controls() function returns an LDAP error code that indicates whether the reference could be successfully parsed (LDAP_SUCCESS if all goes well).

14.19.6 Parsing References

The ldap_parse_reference() function is used to extract referrals and controls from a SearchResultReference message.


        int ldap_parse_reference( 
                LDAP                            *ld, 
                LDAPMessage                     *ref, 
                char                            ***referralsp, 
                LDAPControl                     ***serverctrlsp, 
                int                             freeit 
        ); 

Parameters are as follows:
ld The session handle.
ref The reference to parse, as returned by ldap_result() , ldap_first_reference() , or ldap_next_reference() .
referralsp This result parameter will be filled in with an allocated array of character strings. The elements of the array are the referrals (typically LDAP URLs) contained in ref. The array should be freed when no longer in used by calling ldap_value_free() . If referralsp is NULL, the referral URLs are not returned.
serverctrlsp This result parameter will be filled in with an allocated array of controls copied out of ref. The control array should be freed by calling ldap_controls_free() . If serverctrlsp is NULL, no controls are returned.
freeit A boolean that determines whether or not the ref parameter is disposed of. Pass any non-zero value to have these functions free ref after extracting the requested information. This option is provided as a convenience; you can also use ldap_msgfree() to free the result later.

The ldap_parse_reference() function returns an LDAP error code that indicates whether the reference could be successfully parsed (LDAP_SUCCESS if all goes well).

14.20 Encoded ASN.1 Value Manipulation

This section describes functions that may be used to encode and decode BER-encoded ASN.1 values, which are often used inside of control and extension values.

The following additional integral types are defined for use in manipulation of BER encoded ASN.1 values:


typedef unsigned long ber_tag_t; /* for BER tags */ 
 
typedef long     ber_int_t; /* for BER ints, enums, and Booleans */ 

With the exceptions of two new functions, ber_flatten() and ber_init() , these functions are compatible with the University of Michigan LDAP 3.3 implementation of BER.


        typedef struct berval { 
                ber_len_t            bv_len; 
                char                 *bv_val; 
        } BerValue; 

A struct berval contains a sequence of bytes and an indication of its length. The bv_val is not null terminated. A bv_len must always be a nonnegative number. Applications may allocate their own berval structures.


        typedef struct berelement { 
             /* opaque */ 
        } BerElement; 

The BerElement structure contains not only a copy of the encoded value, but also state information used in encoding or decoding. Applications cannot allocate their own BerElement structures. The internal state is neither thread-specific nor locked, so two threads should not manipulate the same BerElement value simultaneously.

A single BerElement value cannot be used for both encoding and decoding.


        void ber_bvfree( struct berval *bv ); 

The ber_bvfree() function frees a berval returned from this API. Both the bv->bv_val string and the berval itself are freed. Applications should not use ber_bvfree() with bervals which the application has allocated.


        void ber_bvecfree ( struct berval **bv ); 

The ber_bvecfree() function frees an array of bervals returned from this API. Each of the bervals in the array are freed using ber_bvfree() , then the array itself is freed.


        struct berval *ber_bvdup (struct berval *bv ); 

The ber_bvdup() function returns a copy of a berval. The bv_val field in the returned berval points to a different area of memory as the bv_val field in the argument berval. The null pointer is returned on error (for example, out of memory).


        void ber_free ( BerElement *ber, int fbuf ); 

The ber_free() function frees a BerElement which is returned from the API calls ber_alloc_t() or ber_init() . Each BerElement must be freed by the caller. The second argument fbuf should always be set to 1 to ensure that the internal buffer used by the BER functions is freed as well as the BerElement container itself.

14.20.1 Encoding

The following is an example of encoding:


        BerElement *ber_alloc_t(int options); 

The ber_alloc_t() function constructs and returns BerElement. The null pointer is returned on error. The options field contains a bitwise-or of options which are to be used when generating the encoding of this BerElement. One option is defined and must always be supplied:


        #define LBER_USE_DER 0x01 

When this option is present, lengths will always be encoded in the minimum number of octets. Note that this option does not cause values of sets and sequences to be rearranged in tag and byte order, so these functions are not sufficient for generating DER output as defined in X.509 and X.680. If the caller takes responsibility for ordering values of sets and sequences correctly, DER output as defined in X.509 and X.680 can be produced.

Unrecognized option bits are ignored.

The BerElement returned by ber_alloc_t() is initially empty. Calls to ber_printf() will append bytes to the end of the BerElement.


        int ber_printf(BerElement *ber, char *fmt, ... ) 

The ber_printf() function is used to encode a BER element in much the same way that sprintf() works. One important difference, though, is that state information is kept in the BER argument so that multiple calls can be made to ber_printf() to append to the end of the BER element. BER must be a pointer to a BerElement returned by ber_alloc_t() . The ber_printf() function interprets and formats its arguments according to the format string fmt . The ber_printf() function returns -1 if there is an error during encoding and a positive number if successful. As with sprintf() , each character in fmt refers to an argument to ber_printf() .

The format string can contain the following format characters:
t Tag. The next argument is a ber_tag_t specifying the tag to override the next element to be written to the ber. This works across calls. The value must contain the tag class, constructed bit, and tag value. The tag value must fit in a single octet (tag value is less than 32). For example, a tag of "[3]" for a constructed type is 0xA3.
b Boolean. The next argument is a ber_int_t , containing either 0 for FALSE or 0xff for TRUE. A boolean element is output. If this format character is not preceded by the 't' format modifier, the tag 0x01 is used for the element.
e Enumerated. The next argument is a ber_int_t , containing the enumerated value in the host's byte order. An enumerated element is output. If this format character is not preceded by the 't' format modifier, the tag 0x0A is used for the element.
i Integer. The next argument is a ber_int_t , containing the integer in the host's byte order. An integer element is output. If this format character is not preceded by the 't' format modifier, the tag 0x02 is used for the element.
B Bitstring. The next two arguments are a char * pointer to the start of the bitstring, followed by a ber_len_t containing the number of bits in the bitstring. A bitstring element is output, in primitive form. If this format character is not preceded by the 't' format modifier, the tag 0x03 is used for the element.
n Null. No argument is required. An ASN.1 NULL element is output. If this format character is not preceded by the 't' format modifier, the tag 0x05 is used for the element.
o Octet string. The next two arguments are a char *, followed by a ber_len_t with the length of the string. The string may contain null bytes and need not by zero-terminated. An octet string element is output, in primitive form. If this format character is not preceded by the 't' format modifier, the tag 0x04 is used for the element.
s Octet string. The next argument is a char * pointing to a zero-terminated string. An octet string element in primitive form is output, which does not include the trailing '\0' byte. If this format character is not preceded by the 't' format modifier, the tag 0x04 is used for the element.
v Several octet strings. The next argument is a char **, an array of char * pointers to zero-terminated strings. The last element in the array must be a null pointer. The octet strings do not include the leading SEQUENCE OF octet strings. The 't' format modifier cannot be used with this format character.
V Several octet strings. A NULL-terminated array of struct berval *'s is supplied. Note that a construct like '{V}' is required to get an actual SEQUENCE OF octet strings. The 't' format modifier cannot be used with this format character.
{ Begin sequence. No argument is required. If this format character is not preceded by the 't' format modifier, the tag 0x30 is used.
} End sequence. No argument is required. The 't' format modifier cannot be used with this format character.
[ Begin set. No argument is required. If this format character is not preceded by the 't' format modifier, the tag 0x31 is used.
] End set. No argument is required. The 't' format modifier cannot be used with this format character.

Each use of a '{' format character must be matched by a '}' character, either later in the format string, or in the format string of a subsequent call to ber_printf() for that BerElement. The same applies to the '[' and ']'.

Sequences and sets nest, and implementations of this API must maintain internal state to be able to properly calculate the lengths.


        int ber_flatten (BerElement *ber, struct berval **bvPtr); 

The ber_flatten() function allocates a struct berval whose contents are a BER encoding taken from the ber argument. The bvPtr pointer points to the returned berval, which must be freed using ber_bvfree() . This function returns 0 on success and -1 on error.

The ber_flatten() API call is not present in U-M LDAP 3.3.

The use of ber_flatten() on a BerElement in which all '{' and '}' format modifiers have not been properly matched is an error (that is, -1 will be returned by ber_flatten() if this situation is exists).


Previous Next Contents Index