VMS Help  —  LDAP
value_free_len() when no longer in use.

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.

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).

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).

20  –  Encoded ASN.1

    LDAP contains 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.

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).

20.2  –  Decoding

    The following two symbols are available to applications.

            #define LBER_ERROR   0xffffffffL
            #define LBER_DEFAULT 0xffffffffL

            BerElement *ber_init (struct berval *bv);

    The ber_init() function constructs a BerElement and returns a new
    BerElement containing a copy of the data in the bv argument. The
    ber_init() function returns the null pointer on error.

            ber_tag_t ber_scanf (BerElement *ber, char *fmt, ... );

    The ber_scanf() function is used to decode a BER element in much
    the same way that sscanf() works. One important difference,
    though, is that some state information is kept with the ber
    argument so that multiple calls can be made to ber_scanf() to
    sequentially read from the BER element. The ber argument must
    be a pointer to a BerElement returned by ber_init(). The ber_
    scanf() function interprets function the bytes according to
    the format string fmt, and stores the results in its additional
    arguments. The ber_scanf() function returns LBER_ERROR on error,
    and a different value on success.

    The format string contains conversion specifications which are
    used to direct the interpretation of the BER element. The format
    string can contain the following characters:

    a     Octet string. A char ** argument should be supplied. Memory
          is allocated, filled with the contents of the octet string,
          null- terminated, and the pointer to the string is stored
          in the argument. The returned value must be freed using
          ldap_memfree().  The tag of the element must indicate the
          primitive form (constructed strings are not supported) but
          is otherwise ignored and discarded during the decoding.
          This format cannot be used with octet strings which could
          contain null bytes.
    O     Octet string. A struct berval ** argument should be
          supplied, which upon return points to a allocated struct
          berval containing the octet string and its length. The
          ber_bvfree()  function must be called to free the allocated
          memory. The tag of the element must indicate the primitive
          form (constructed strings are not supported) but is
          otherwise ignored during the decoding.
    b     Boolean. A pointer to a ber_int_t should be supplied. The
          value stored will be 0 for FALSE or nonzero for TRUE. The
          tag of the element must indicate the primitive form but is
          otherwise ignored during the decoding.
    e     Enumerated value stored will be in host byte order. The
          tag of the element must indicate the primitive form but is
          otherwise ignored during the decoding. The ber_scanf()
          function will return an error if the enumerated value
          cannot be stored in a ber_int_t.
    i     Integer. A pointer to a ber_int_t should be supplied. The
          value stored will be in host byte order. The tag of the
          element must indicate the primitive form but is otherwise
          ignored during the decoding. The ber_scanf()  function will
          return an error if the integer cannot be stored in a ber_
          int_t.
    B     Bitstring. A char ** argument should be supplied which
          will point to the allocated bits, followed by a ber_len_t *
          argument, which will point to the length (in bits) of the
          bit-string returned. The ldap_memfree()  function must be
          called to free the bit-string. The tag of the element must
          indicate the primitive form (constructed bitstrings are not
          supported) but is otherwise ignored during the decoding.
    n     Null. No argument is required. The element is simply
          skipped if it is recognized as a zero-length element. The
          tag is ignored.
    v     Several octet strings. A char *** argument should be
          supplied, which upon return points to a allocated null-
          terminated array of char *'s containing the octet strings.
          NULL is stored if the sequence is empty. The ldap_
          memfree()  function must be called to free each element
          of the array and the array itself. The tag of the sequence
          and of the octet strings are ignored.
    V     Several octet strings (which could contain null bytes).
          A struct berval *** should be supplied, which upon
          return points to a allocated null-terminated array of
          struct berval *'s containing the octet strings and their
          lengths. NULL is stored if the sequence is empty. The ber_
          bvecfree()  function can be called to free the allocated
          memory. The tag of the sequence and of the octet strings
          are ignored.
    x     Skip element. The next element is skipped. No argument is
          required.
    {     Begin sequence. No argument is required. The initial
          sequence tag and length are skipped.
    }     End sequence. No argument is required.
    [     Begin set. No argument is required. The initial set tag and
          length are skipped.
    ]     End set. No argument is required.

      ber_tag_t ber_peek_tag (BerElement *ber, ber_len_t *lenPtr);

    The ber_peek_tag() function returns the tag of the next element
    to be parsed in the BerElement argument. The length of this
    element is stored in the *lenPtr argument. LBER_DEFAULT is
    returned if there is no further data to be read. The ber argument
    is not modified.

      ber_tag_t ber_skip_tag (BerElement *ber, ber_len_t *lenPtr);

    The ber_skip_tag() function is similar to ber_peek_tag(),  except
    that the state pointer in the BerElement argument is advanced
    past the first tag and length, and is pointed to the value part
    of the next element. This function should only be used with
    constructed types and situations when a BER encoding is used as
    the value of an OCTET STRING. The length of the value is stored
    in *lenPtr.

            ber_tag_t ber_first_element(BerElement *ber,
                    ber_len_t *lenPtr, char **opaquePtr);

            ber_tag_t ber_next_element  (BerElement *ber,
                    ber_len_t *lenPtr, char *opaque);

    The ber_first_element() and ber_next_element()  functions are
    used to traverse a SET, SET OF, SEQUENCE or SEQUENCE OF data
    value. The ber_first_element() function calls ber_skip_tag(),
    stores internal information in *lenPtr and *opaquePtr, and calls
    ber_peek_tag() for the first element inside the constructed
    value. LBER_DEFAULT is returned if the constructed value is
    empty. The ber_next_element() function positions the state at the
    start of the next element in the constructed type. LBER_DEFAULT
    is returned if there are no further values.

    The len and opaque values should not be used by applications
    other than as arguments to ber_next_element(). (Refer to the VSI
    OpenVMS Utility Routines Manual for an example of this usage.)

21  –  Using SSL

    Secure Sockets Layer (SSL) is the open standard security protocol
    for the secure transfer of sensitive information over the
    Internet.

    You can establish SSL on an LDAP session if the server supports
    such sessions. SSL uses X.509 public key technology to provide
    the following security functions:

    o  Integrity and confidentiality of the LDAP dialog

       This is the most common use of SSL. The bytes sent over the
       wire are encrypted.

    o  Authentication of the client

       Some servers use SSL to authenticate the client and make
       access control decisions based on the client identity. In
       this case, the client must have access to its private key and
       its certificate. The client certificate subject is a DN.

    o  Authentication of the server

       It might be important for the client to verify the identity
       of the server to which it is talking. In this case, the client
       must have access to the appropriate certification authority
       (CA) public keys.

    There are several versions of SSL: SSLv2 (2.0), SSLv3 (3.0), and
    TLSv1 (3.1). TLS is the latest Internet standard. It does not
    require the use of RSA algorithms. Usually the client specifies
    the highest version it supports, and the server negotiates
    downward, if necessary. The client library supports all the
    versions listed here.

    You can establish SSL over LDAP two different ways:

    o  LDAPS

       This older, de facto standard uses a separate TCP/IP port
       (usually 636) specifically for SSL over LDAP. In this case,
       the second parameter to the ldap_tls_start() function must be
       set to zero.

    o  StartTLS

       This proposed Internet standard uses a regular LDAP port
       (usually 389) and requires the client to request the use
       of SSL. In this case, the second parameter to the ldap_tls_
       start() function must be set to 1.

21.1  –  SSL Certificate Options

    The following session-handle options are specific to SSL and can
    be set by the ldap_set_option() function:

    o  LDAP_OPT_TLS_CERT_REQUIRED (0x7001) void *

       Set to LDAP_OPT_ON if the client library requires a server
       certificate to be present the next time the ldap_tls_start()
       function is called. The default value is LDAP_OPT_OFF; a
       server certificate is not required.

    o  LDAP_OPT_TLS_VERIFY_REQUIRED (0x7002) void *

       Set to LDAP_OPT_ON if the client library requires that a
       server certificate path be validated the next time the ldap_
       tls_start() function is called. The default value is LDAP_OPT_
       OFF; the server certificate, if any, is not verified.

    o  LDAP_OPT_TLS_CERT_FILE (0x7003) char *

       Set to the name of a file containing the client's certificate
       for use by the ldap_tls_start() function.

    o  LDAP_OPT_TLS_PKEY_FILE (0x7004) char *

       Set to the name of a file containing the client's private key
       for use by the ldap_tls_start() function.

    o  LDAP_OPT_TLS_CA_FILE (0x7005) char *

       Set to the name of a file containing CA public keys used for
       validation of the server by the ldap_tls_start() function.

    o  LDAP_OPT_TLS_CA_PATH (0x7006) char *

       Set to the name of a directory on disk containing CA public
       key files used for validation of the server by the ldap_tls_
       start() function.

    o  LDAP_OPT_TLS_VERSION (0x7007) int *

       Set to the desired SSL protocol version. This option takes one
       of the following values:

           1: TLSv1 only
          20: SSLv2 only
          23: SSLv2 or SSLv3
          30: SSLv3 only (default)
          31: TLSv1 only

    If LDAP_OPT_TLS_VERIFY_REQUIRED is set to ON, either the LDAP_
    OPT_TLS_CA_FILE or the LDAP_OPT_TLS_CA_PATH option must be set.

    If client authentication is required, both LDAP_OPT_TLS_CERT_FILE
    and LDAP_OPT_TLS_PKEY_FILE must be set.

21.2  –  Obtaining a Key Pair

    In order for TLS to authenticate a client, the client must have
    a private key and a certificate. Obtain these from either a
    Certification Authority or a self-sign program. A self-sign
    program is included in the Open Source Security for OpenVMS
    product.
Close Help