home *** CD-ROM | disk | FTP | other *** search
/ Handbook of Infosec Terms 2.0 / Handbook_of_Infosec_Terms_Version_2.0_ISSO.iso / text / rfcs / rfc1823.txt < prev    next >
Text File  |  1996-05-07  |  42KB  |  692 lines

  1.  
  2.  
  3.  
  4.  
  5.  
  6.  
  7. Network Working Group                                           T. Howes Request for Comments: 1823                                      M. Smith Category: Informational                          University of  Michigan                                                              August 1995 
  8.  
  9.                   The LDAP Application Program Interface 
  10.  
  11. Status of this Memo 
  12.  
  13.    This memo provides information for the Internet community.  This memo    does not specify an Internet standard of any kind.  Distribution of    this memo is unlimited. 
  14.  
  15. 1.  Introduction 
  16.  
  17.    This document defines a C language application program interface to    the lightweight directory access protocol (LDAP). The LDAP API is    designed to be powerful, yet simple to use. It defines compatible    synchronous and asynchronous interfaces to LDAP to suit a wide    variety of applications.  This document gives a brief overview of the    LDAP model, then an overview of how the API is used by an application    program to obtain LDAP information.  The API calls are described in    detail, followed by an appendix that provides some example code    demonstrating the use of the API. 
  18.  
  19. 2.  Overview of the LDAP Model 
  20.  
  21.    LDAP is the lightweight directory access protocol, described in [2]    and [7]. It can provide a lightweight frontend to the X.500 directory    [1], or a stand-alone service. In either mode, LDAP is based on a    client-server model in which a client makes a TCP connection to an    LDAP server, over which it sends requests and receives responses. 
  22.  
  23.    The LDAP information model is based on the entry, which contains    information about some object (e.g., a person).  Entries are composed    of attributes, which have a type and one or more values. Each    attribute has a syntax that determines what kinds of values are    allowed in the attribute (e.g., ASCII characters, a jpeg photograph,    etc.) and how those values behave during directory operations (e.g.,    is case significant during comparisons). 
  24.  
  25.    Entries are organized in a tree structure, usually based on    political, geographical, and organizational boundaries. Each entry is    uniquely named relative to its sibling entries by its relative    distinguished name (RDN) consisting of one or more distinguished    attribute values from the entry.  At most one value from each    attribute may be used in the RDN.  For example, the entry for the 
  26.  
  27.  
  28.  
  29. Howes & Smith                Informational                      [Page 1] 
  30.  RFC 1823                        LDAP API                     August 1995 
  31.  
  32.     person Babs Jensen might be named with the "Barbara Jensen" value    from the commonName attribute. A globally unique name for an entry,    called a distinguished name or DN, is constructed by concatenating    the sequence of RDNs from the root of the tree down to the entry. For    example, if Babs worked for the University of Michigan, the DN of her    U-M entry might be "cn=Barbara Jensen, o=University of Michigan,    c=US". The DN format used by LDAP is defined in [4]. 
  33.  
  34.    Operations are provided to authenticate, search for and retrieve    information, modify information, and add and delete entries from the    tree.  The next sections give an overview of how the API is used and    detailed descriptions of the LDAP API calls that implement all of    these functions. 
  35.  
  36. 3.  Overview of LDAP API Use 
  37.  
  38.    An application generally uses the LDAP API in four simple steps. 
  39.  
  40.    o    Open a connection to an LDAP server. The ldap_open() call         returns a handle to the connection, allowing multiple         connections to be open at once. 
  41.  
  42.    o    Authenticate to the LDAP server and/or the X.500 DSA. The         ldap_bind() call and friends support a variety of         authentication methods. 
  43.  
  44.    o    Perform some LDAP operations and obtain some results.         ldap_search() and friends return results which can be parsed         by ldap_result2error(), ldap_first_entry(), ldap_next_entry(),         etc. 
  45.  
  46.    o    Close the connection. The ldap_unbind() call closes the         connection. 
  47.  
  48.    Operations can be performed either synchronously or asynchronously.    Synchronous calls end in _s. For example, a synchronous search can be    completed by calling ldap_search_s(). An asynchronous search can be    initiated by calling ldap_search(). All synchronous routines return    an indication of the outcome of the operation (e.g, the constant    LDAP_SUCCESS or some other error code).  The asynchronous routines    return the message id of the operation initiated. This id can be used    in subsequent calls to ldap_result() to obtain the result(s) of the    operation.  An asynchronous operation can be abandoned by calling    ldap_abandon(). 
  49.  
  50.  
  51.  
  52.  
  53.  
  54.  
  55.  
  56. Howes & Smith                Informational                      [Page 2] 
  57.  RFC 1823                        LDAP API                     August 1995 
  58.  
  59.     Results and errors are returned in an opaque structure called    LDAPMessage.  Routines are provided to parse this structure, step    through entries and attributes returned, etc. Routines are also    provided to interpret errors. The next sections describe these    routines in more detail. 
  60.  
  61. 4.  Calls for performing LDAP operations 
  62.  
  63.    This section describes each LDAP operation API call in detail. All    calls take a "connection handle", a pointer to an LDAP structure    containing per-connection information.  Many routines return results    in an LDAPMessage structure. These structures and others are    described as needed below. 
  64.  
  65. 4.1.  Opening a connection 
  66.  
  67.    ldap_open() opens a connection to the LDAP server. 
  68.  
  69.               typedef struct ldap {                       /* ... opaque parameters ... */                       int     ld_deref;                       int     ld_timelimit;                       int     ld_sizelimit;                       int     ld_errno;                       char    *ld_matched;                       char    *ld_error;                       /* ... opaque parameters ... */               } LDAP; 
  70.  
  71.               LDAP *ldap_open( char *hostname, int portno ); 
  72.  
  73.       Parameters are: 
  74.  
  75.       hostname Contains a space-separated list of hostnames or dotted                strings representing the IP address of hosts running an                LDAP server to connect to. The hosts are tried in the                order listed, stopping with the first one to which a                successful connection is made; 
  76.  
  77.       portno   contains the TCP port number to which to connect. The                default LDAP port can be obtained by supplying the                constant LDAP_PORT. 
  78.  
  79.    ldap_open() returns a "connection handle", a pointer to an LDAP    structure that should be passed to subsequent calls pertaining to the    connection. It returns NULL if the connection cannot be opened. One    of the ldap_bind calls described below must be completed before other    operations can be performed on the connection. 
  80.  
  81.  
  82.  
  83. Howes & Smith                Informational                      [Page 3] 
  84.  RFC 1823                        LDAP API                     August 1995 
  85.  
  86.     The calling program should assume nothing about the order of the    fields in the LDAP structure. There may be other fields in the    structure for internal library use. The fields shown above are    described as needed in the description of other calls below. 
  87.  
  88. 4.2.  Authenticating to the directory 
  89.  
  90.    ldap_bind() and friends are used to authenticate to the directory. 
  91.  
  92.            int ldap_bind( LDAP *ld, char *dn, char *cred, int method ); 
  93.  
  94.            int ldap_bind_s( LDAP *ld, char *dn, char *cred, int method ); 
  95.  
  96.            int ldap_simple_bind( LDAP *ld, char *dn, char *passwd ); 
  97.  
  98.            int ldap_simple_bind_s( LDAP *ld, char *dn, char *passwd ); 
  99.  
  100.            int ldap_kerberos_bind( LDAP *ld, char *dn ); 
  101.  
  102.            int ldap_kerberos_bind_s( LDAP *ld, char *dn ); 
  103.  
  104.    Parameters are: 
  105.  
  106.    ld     The connection handle; 
  107.  
  108.    dn     The name of the entry to bind as; 
  109.  
  110.    cred   The credentials with which to authenticate; 
  111.  
  112.    method One of LDAP_AUTH_SIMPLE, LDAP_AUTH_KRBV41, or           LDAP_AUTH_KRBV42, indicating the authentication method to use; 
  113.  
  114.    passwd For ldap_simple_bind(), the password to compare to the entry's           userPassword attribute; 
  115.  
  116.    There are three types of bind calls, providing simple authentication,    kerberos authentication, and general routines to do either one. In    the case of Kerberos version 4 authentication using the general    ldap_bind() routines, the credentials are ignored, as the routines    assume a valid ticket granting ticket already exists which can be    used to retrieve the appropriate service tickets. 
  117.  
  118.    Synchronous versions of the routines have names that end in _s.    These routines return the result of the bind operation, either the    constant LDAP_SUCCESS if the operation was successful, or another    LDAP error code if it was not. See the section below on error    handling for more information about possible errors and how to    interpret them. 
  119.  
  120.  
  121.  
  122. Howes & Smith                Informational                      [Page 4] 
  123.  RFC 1823                        LDAP API                     August 1995 
  124.  
  125.     Asynchronous versions of these routines return the message id of the    bind operation initiated. A subsequent call to ldap_result(),    described below, can be used to obtain the result of the bind. In    case of error, these routines will return -1, setting the ld_errno    field in the LDAP structure appropriately. 
  126.  
  127.    Note that no other operations over the connection should be attempted    before a bind call has successfully completed. Subsequent bind calls    can be used to re-authenticate over the same connection. 
  128.  
  129. 4.3.  Closing the connection 
  130.  
  131.    ldap_unbind() is used to unbind from the directory and close the    connection. 
  132.  
  133.            int ldap_unbind( LDAP *ld ); 
  134.  
  135.    Parameters are: 
  136.  
  137.       ld   The connection handle. 
  138.  
  139.    ldap_unbind() works synchronously, unbinding from the directory,    closing the connection, and freeing up the ld structure before    returning. ldap_unbind() returns LDAP_SUCCESS (or another LDAP error    code if the request cannot be sent to the LDAP server).  After a call    to ldap_unbind(), the ld connection handle is invalid. 
  140.  
  141. 4.4.  Searching 
  142.  
  143.    ldap_search() and friends are used to search the LDAP directory,    returning a requested set of attributes for each entry matched.    There are three variations. 
  144.  
  145.            struct timeval {                    long    tv_sec;                    long    tv_usec;            };            int ldap_search(                    LDAP    *ld,                    char    *base,                    int     scope,                    char    *filter,                    char    *attrs[],                    int     attrsonly            );            int ldap_search_s(                    LDAP            *ld,                    char            *base, 
  146.  
  147.  
  148.  
  149. Howes & Smith                Informational                      [Page 5] 
  150.  RFC 1823                        LDAP API                     August 1995 
  151.  
  152.                     int             scope,                    char            *filter,                    char            *attrs[],                    int             attrsonly,                    LDAPMessage     **res            );            int ldap_search_st(                    LDAP            *ld,                    char            *base,                    int             scope,                    char            *filter,                    char            *attrs[],                    int             attrsonly,                    struct timeval  *timeout,                    LDAPMessage     **res            ); 
  153.  
  154.    Parameters are: 
  155.  
  156.    ld        The connection handle; 
  157.  
  158.    base      The dn of the entry at which to start the search; 
  159.  
  160.    scope     One of LDAP_SCOPE_BASE, LDAP_SCOPE_ONELEVEL, or              LDAP_SCOPE_SUBTREE, indicating the scope of the search; 
  161.  
  162.    filter    A character string as described in RFC 1558 [3],              representing the search filter; 
  163.  
  164.    attrs     A NULL-terminated array of strings indicating which              attributes to return for each matching entry. Passing              NULL for this parameter causes all available attributes              to be retrieved; 
  165.  
  166.    attrsonly A boolean value that should be zero if both attribute              types and values are to be returned, non-zero if only              types are wanted; 
  167.  
  168.    timeout   For the ldap_search_st() call, this specifies the local              search timeout value; 
  169.  
  170.    res       For the synchronous calls, this is a result parameter              which will contain the results of the search upon              completion of the call. 
  171.  
  172.    There are three fields in the ld connection handle which control how    the search is performed. They are: 
  173.  
  174.  
  175.  
  176.  Howes & Smith                Informational                      [Page 6] 
  177.  RFC 1823                        LDAP API                     August 1995 
  178.  
  179.     ld_sizelimit A limit on the number of entries to return from the                 search. A value of zero means no limit; 
  180.  
  181.    ld_timelimit A limit on the number of seconds to spend on the search.                 A value of zero means no limit; 
  182.  
  183.    ld_deref     One of LDAP_DEREF_NEVER, LDAP_DEREF_SEARCHING,                 LDAP_DEREF_FINDING, or LDAP_DEREF_ALWAYS, specifying                 how aliases should be handled during the search. 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. 
  184.  
  185.    An asynchronous search is initiated by calling ldap_search(). It    returns the message id of the initiated search. The results of the    search can be obtained by a subsequent call to ldap_result().  The    results can be parsed by the result parsing routines described in    detail later.  In case of error, -1 is returned and the ld_errno    field in the LDAP structure is set appropriately. 
  186.  
  187.    A synchronous search is performed by calling ldap_search_s() or    ldap_search_st(). The routines are identical, except that    ldap_search_st() takes an additional parameter specifying a timeout    for the search.  Both routines return an indication of the result of    the search, either LDAP_SUCCESS or some error indication (see Error    Handling below).  The entries returned from the search (if any) are    contained in the res parameter. This parameter is opaque to the    caller.  Entries, attributes, values, etc., should be extracted by    calling the parsing routines described below. The results contained    in res should be freed when no longer in use by calling    ldap_msgfree(), described later. 
  188.  
  189. 4.5.  Reading an entry 
  190.  
  191.    LDAP does not support a read operation directly. Instead, this    operation is emulated by a search with base set to the DN of the    entry to read, scope set to LDAP_SCOPE_BASE, and filter set to    "(objectclass=*)". attrs contains the list of attributes to return. 
  192.  
  193. 4.6.  Listing the children of an entry 
  194.  
  195.    LDAP does not support a list operation directly. Instead, this    operation is emulated by a search with base set to the DN of the    entry to list, scope set to LDAP_SCOPE_ONELEVEL, and filter set to    "(objectclass=*)". attrs contains the list of attributes to return    for each child entry. 
  196.  
  197.  
  198.  
  199. Howes & Smith                Informational                      [Page 7] 
  200.  RFC 1823                        LDAP API                     August 1995 
  201.  
  202.  4.7.  Modifying an entry 
  203.  
  204.    The ldap_modify() and ldap_modify_s() routines are used to modify an    existing LDAP entry. 
  205.  
  206.            typedef struct ldapmod {                    int             mod_op;                    char            *mod_type;                    union {                            char            **modv_strvals;                            struct berval   **modv_bvals;                    } mod_vals;            } LDAPMod;            #define mod_values      mod_vals.modv_strvals            #define mod_bvalues     mod_vals.modv_bvals 
  207.  
  208.            int ldap_modify( LDAP *ld, char *dn, LDAPMod *mods[] ); 
  209.  
  210.            int ldap_modify_s( LDAP *ld, char *dn, LDAPMod *mods[] ); 
  211.  
  212.    Parameters are: 
  213.  
  214.    ld       The connection handle; 
  215.  
  216.    dn       The name of the entry to modify; 
  217.  
  218.    mods     A NULL-terminated array of modifications to make to the             entry. 
  219.  
  220.    The fields in the LDAPMod structure have the following meanings: 
  221.  
  222.    mod_op   The modification operation to perform. It should be one of             LDAP_MOD_ADD, LDAP_MOD_DELETE, or LDAP_MOD_REPLACE. This             field also indicates the type of values included in the             mod_vals union. It is ORed with LDAP_MOD_BVALUES to select             the mod_bvalues form. Otherwise, the mod_values form is             used; 
  223.  
  224.    mod_type The type of the attribute to modify; 
  225.  
  226.    mod_vals The values (if any) to add, delete, or replace. Only one of             the mod_values or mod_bvalues variants should be used,             selected by ORing the mod_op field with the constant             LDAP_MOD_BVALUES. mod_values is a NULL-terminated array of             zero-terminated strings and mod_bvalues is a NULL-terminated             array of berval structures that can be used to pass binary             values such as images. 
  227.  
  228.  
  229.  
  230.  Howes & Smith                Informational                      [Page 8] 
  231.  RFC 1823                        LDAP API                     August 1995 
  232.  
  233.     For LDAP_MOD_ADD modifications, the given values are added to the    entry, creating the attribute if necessary.  For LDAP_MOD_DELETE    modifications, the given values are deleted from the entry, removing    the attribute if no values remain.  If the entire attribute is to be    deleted, the mod_vals field should be set to NULL.  For    LDAP_MOD_REPLACE modifications, the attribute will have the listed    values after the modification, having been created if necessary.  All    modifications are performed in the order in which they are listed. 
  234.  
  235.    ldap_modify_s() returns the LDAP error code  resulting  from the    modify  operation.   This  code  can  be interpreted by ldap_perror()    and friends. 
  236.  
  237.    ldap_modify() returns the message id of the request it initiates, or    -1 on error.  The result of the operation can be obtained by calling    ldap_result(). 
  238.  
  239. 4.8.  Modifying the RDN of an entry 
  240.  
  241.    The ldap_modrdn() and ldap_modrdn_s() routines are used to change the    name of an LDAP entry. 
  242.  
  243.            int ldap_modrdn(                    LDAP    *ld,                    char    *dn,                    char    *newrdn,                    int     deleteoldrdn            );            int ldap_modrdn_s(                    LDAP    *ld,                    char    *dn,                    char    *newrdn,                    int     deleteoldrdn            ); 
  244.  
  245.    Parameters are: 
  246.  
  247.    ld            The connection handle; 
  248.  
  249.    dn            The name of the entry whose RDN is to be changed; 
  250.  
  251.    newrdn        The new RDN to give the entry; 
  252.  
  253.    deleteoldrdn  A boolean value, if non-zero indicating that the old                  RDN value(s) should be removed, if zero indicating that                  the old RDN value(s) should be retained as non-                  distinguished values of the entry. 
  254.  
  255.  
  256.  
  257.  Howes & Smith                Informational                      [Page 9] 
  258.  RFC 1823                        LDAP API                     August 1995 
  259.  
  260.     The ldap_modrdn_s() routine is synchronous, returning the LDAP error    code indicating the outcome of the operation. 
  261.  
  262.    The ldap_modrdn() routine is asynchronous, returning the message id    of the operation it initiates, or -1 in case of trouble. The result    of the operation can be obtained by calling ldap_result(). 
  263.  
  264. 4.9.  Adding an entry 
  265.  
  266.    ldap_add() and ldap_add_s() are used to add entries to the LDAP    directory. 
  267.  
  268.            int ldap_add( LDAP *ld, char *dn, LDAPMod *attrs[] ); 
  269.  
  270.            int ldap_add_s( LDAP *ld, char *dn, LDAPMod *attrs[] ); 
  271.  
  272.    Parameters are: 
  273.  
  274.    ld    The connection handle; 
  275.  
  276.    dn    The name of the entry to add; 
  277.  
  278.    attrs The entry's attributes, specified using the LDAPMod structure          defined for ldap_modify(). The mod_type and mod_vals fields          should be filled in.  The mod_op field is ignored unless ORed          with the constant LDAP_MOD_BVALUES, used to select the          mod_bvalues case of the mod_vals union. 
  279.  
  280.    Note that the parent of the entry must already exist. 
  281.  
  282.    ldap_add_s() is synchronous, returning the LDAP error code indicating    the outcome of the operation. 
  283.  
  284.    ldap_add() is asynchronous, returning the message id of the operation    it initiates, or -1 in case of trouble. The result of the operation    can be obtained by calling ldap_result(). 
  285.  
  286. 4.10.  Deleting an entry 
  287.  
  288.    ldap_delete() and ldap_delete_s() are used to delete entries from the    LDAP directory. 
  289.  
  290.            int ldap_delete( LDAP *ld, char *dn ); 
  291.  
  292.            int ldap_delete_s( LDAP *ld, char *dn ); 
  293.  
  294.  
  295.  
  296.  
  297.  
  298.  Howes & Smith                Informational                     [Page 10] 
  299.  RFC 1823                        LDAP API                     August 1995 
  300.  
  301.     Parameters are: 
  302.  
  303.    ld       The connection handle; 
  304.  
  305.    dn       The name of the entry to delete. 
  306.  
  307.    Note that the entry to delete must be a leaf entry (i.e., it must    have no children). Deletion of entire subtrees is not supported by    LDAP. 
  308.  
  309.    ldap_delete_s() is synchronous, returning the LDAP error code    indicating the outcome of the operation. 
  310.  
  311.    ldap_delete() is asynchronous, returning the message id of the    operation it initiates, or -1 in case of trouble. The result of the    operation can be obtained by calling ldap_result(). 
  312.  
  313. 5.  Calls for abandoning an operation 
  314.  
  315.    ldap_abandon() is used to abandon an operation in progress. 
  316.  
  317.            int ldap_abandon( LDAP *ld, int msgid ); 
  318.  
  319.    ldap_abandon() abandons the operation with message id msgid. It    returns zero if the abandon was successful, -1 otherwise. After a    successful call to ldap_abandon(), results with the given message id    are never returned from a call to ldap_result(). 
  320.  
  321. 6.  Calls for obtaining results 
  322.  
  323.    ldap_result() is used to obtain the result of a previous    asynchronously initiated operation. ldap_msgfree() frees the results    obtained from a previous call to ldap_result(), or a synchronous    search routine. 
  324.  
  325.            int ldap_result(                    LDAP            *ld,                    int             msgid,                    int             all,                    struct timeval  *timeout,                    LDAPMessage     **res            ); 
  326.  
  327.            int ldap_msgfree( LDAPMessage *res ); 
  328.  
  329.  
  330.  
  331.  
  332.  
  333.  
  334.  
  335. Howes & Smith                Informational                     [Page 11] 
  336.  RFC 1823                        LDAP API                     August 1995 
  337.  
  338.     Parameters are: 
  339.  
  340.    ld       The connection handle; 
  341.  
  342.    msgid    The message id of the operation whose results are to be             returned, or the constant LDAP_RES_ANY if any result is             desired; 
  343.  
  344.    all      A boolean parameter that only has meaning for search             results. If non-zero it indicates that all results of a             search should be retrieved before any are returned. If zero,             search results (entries) will be returned one at a time as             they arrive; 
  345.  
  346.    timeout  A timeout specifying how long to wait for results to be             returned.  A NULL value causes ldap_result() to block until             results are available.  A timeout value of zero second             specifies a polling behavior; 
  347.  
  348.    res      For ldap_result(), a result parameter that will contain the             result(s) of the operation. For ldap_msgfree(), the result             chain to be freed, obtained from a previous call to             ldap_result() or ldap_search_s() or ldap_search_st(). 
  349.  
  350.    Upon successful completion, ldap_result() returns the type of the    result returned in the res parameter. This will be one of the    following constants. 
  351.  
  352.              LDAP_RES_BIND              LDAP_RES_SEARCH_ENTRY              LDAP_RES_SEARCH_RESULT              LDAP_RES_MODIFY              LDAP_RES_ADD              LDAP_RES_DELETE              LDAP_RES_MODRDN              LDAP_RES_COMPARE 
  353.  
  354.    ldap_result() returns 0 if the timeout expired and -1 if an error    occurs, in which case the ld_errno field of the ld structure will be    set accordingly. 
  355.  
  356.    ldap_msgfree() frees the result structure pointed to be res and    returns the type of the message it freed. 
  357.  
  358.  
  359.  
  360.  
  361.  
  362.  
  363.  
  364.  Howes & Smith                Informational                     [Page 12] 
  365.  RFC 1823                        LDAP API                     August 1995 
  366.  
  367.  7.  Calls for error handling 
  368.  
  369.    The following calls are used to interpret errors returned by other    LDAP API routines. 
  370.  
  371.            int ldap_result2error(                    LDAP            *ld,                    LDAPMessage     *res,                    int             freeit            ); 
  372.  
  373.            char *ldap_err2string( int err ); 
  374.  
  375.            void ldap_perror( LDAP *ld, char *msg ); 
  376.  
  377.    Parameters are: 
  378.  
  379.    ld       The connection handle; 
  380.  
  381.    res      The result of an LDAP operation as returned by ldap_result()             or one of the synchronous API operation calls; 
  382.  
  383.    freeit   A boolean parameter indicating whether the res parameter             should be freed (non-zero) or not (zero); 
  384.  
  385.    err      An LDAP error code, as returned by ldap_result2error() or             one of the synchronous API operation calls; 
  386.  
  387.    msg      A message to be displayed before the LDAP error message. 
  388.  
  389.    ldap_result2error() is used to convert the LDAP result message    obtained from ldap_result(), or the res parameter returned by one of    the synchronous API operation calls, into a numeric LDAP error code.    It also parses the ld_matched and ld_error portions of the result    message and puts them into the connection handle information. All the    synchronous operation routines call ldap_result2error() before    returning, ensuring that these fields are set correctly. The relevant    fields in the connection structue are: 
  390.  
  391.    ld_matched In the event of an LDAP_NO_SUCH_OBJECT error return, this               parameter contains the extent of the DN matched; 
  392.  
  393.    ld_error   This parameter contains the error message sent in the               result by the LDAP server. 
  394.  
  395.    ld_errno   The LDAP error code indicating the outcome of the               operation. It is one of the following constants: 
  396.  
  397.  
  398.  
  399.  Howes & Smith                Informational                     [Page 13] 
  400.  RFC 1823                        LDAP API                     August 1995 
  401.  
  402.             LDAP_SUCCESS            LDAP_OPERATIONS_ERROR            LDAP_PROTOCOL_ERROR            LDAP_TIMELIMIT_EXCEEDED            LDAP_SIZELIMIT_EXCEEDED            LDAP_COMPARE_FALSE            LDAP_COMPARE_TRUE            LDAP_STRONG_AUTH_NOT_SUPPORTED            LDAP_STRONG_AUTH_REQUIRED            LDAP_NO_SUCH_ATTRIBUTE            LDAP_UNDEFINED_TYPE            LDAP_INAPPROPRIATE_MATCHING            LDAP_CONSTRAINT_VIOLATION            LDAP_TYPE_OR_VALUE_EXISTS            LDAP_INVALID_SYNTAX            LDAP_NO_SUCH_OBJECT            LDAP_ALIAS_PROBLEM            LDAP_INVALID_DN_SYNTAX            LDAP_IS_LEAF            LDAP_ALIAS_DEREF_PROBLEM            LDAP_INAPPROPRIATE_AUTH            LDAP_INVALID_CREDENTIALS            LDAP_INSUFFICIENT_ACCESS            LDAP_BUSY            LDAP_UNAVAILABLE            LDAP_UNWILLING_TO_PERFORM            LDAP_LOOP_DETECT            LDAP_NAMING_VIOLATION            LDAP_OBJECT_CLASS_VIOLATION            LDAP_NOT_ALLOWED_ON_NONLEAF            LDAP_NOT_ALLOWED_ON_RDN            LDAP_ALREADY_EXISTS            LDAP_NO_OBJECT_CLASS_MODS            LDAP_RESULTS_TOO_LARGE            LDAP_OTHER            LDAP_SERVER_DOWN            LDAP_LOCAL_ERROR            LDAP_ENCODING_ERROR            LDAP_DECODING_ERROR            LDAP_TIMEOUT            LDAP_AUTH_UNKNOWN            LDAP_FILTER_ERROR            LDAP_USER_CANCELLED            LDAP_PARAM_ERROR            LDAP_NO_MEMORY 
  403.  
  404.  
  405.  
  406.  
  407.  
  408.  Howes & Smith                Informational                     [Page 14] 
  409.  RFC 1823                        LDAP API                     August 1995 
  410.  
  411.     ldap_err2string() is used to convert a numeric LDAP error code, as    returned by ldap_result2error() or one of the synchronous API    operation calls, into an informative NULL-terminated character string    message describing the error.  It returns a pointer to static data. 
  412.  
  413.    ldap_perror() is used to print the message supplied in msg, followed    by an indication of the error contained in the ld_errno field of the    ld connection handle, to standard error. 
  414.  
  415. 8.  Calls for parsing search entries 
  416.  
  417.    The following calls are used to parse the entries returned by    ldap_search() and friends. These entries are returned in an opaque    structure that should only be accessed by calling the routines    described below. Routines are provided to step through the entries    returned, step through the attributes of an entry, retrieve the name    of an entry, and retrieve the values associated with a given    attribute in an entry. 
  418.  
  419. 8.1.  Stepping through a set of entries 
  420.  
  421.    The ldap_first_entry() and ldap_next_entry() routines are used to    step through a set of entries in a search result.    ldap_count_entries() is used to count the number of entries returned. 
  422.  
  423.            LDAPMesage *ldap_first_entry( LDAP *ld, LDAPMessage *res ); 
  424.  
  425.            LDAPMesage *ldap_next_entry( LDAP *ld, LDAPMessage *entry ); 
  426.  
  427.            int ldap_count_entries( LDAP *ld, LDAPMessage *res ); 
  428.  
  429.    Parameters are: 
  430.  
  431.    ld     The connection handle; 
  432.  
  433.    res    The search result, as obtained by a call to one of the syn-           chronous search routines or ldap_result(); 
  434.  
  435.    entry  The entry returned by a previous call to ldap_first_entry() or           ldap_next_entry(). 
  436.  
  437.    ldap_first_entry() and ldap_next_entry() will return NULL when no    more entries exist to be returned. NULL is also returned if an error    occurs while stepping through the entries, in which case the ld_errno    field of the ld connection handle will be set to indicate the error. 
  438.  
  439.    ldap_count_entries() returns the number of entries contained in a    chain of entries. It can also be used to count the number of entries 
  440.  
  441.  
  442.  
  443. Howes & Smith                Informational                     [Page 15] 
  444.  RFC 1823                        LDAP API                     August 1995 
  445.  
  446.     that remain in a chain if called with an entry returned by    ldap_first_entry() or ldap_next_entry(). 
  447.  
  448. 8.2.  Stepping through the attributes of an entry 
  449.  
  450.    The ldap_first_attribute() and ldap_next_attribute() calls are used    to step through the list of attribute types returned with an entry. 
  451.  
  452.            char *ldap_first_attribute(                    LDAP            *ld,                    LDAPMessage     *entry,                    void            **ptr            );            char *ldap_next_attribute(                    LDAP            *ld,                    LDAPMessage     *entry,                    void            *ptr            ); 
  453.  
  454.    Parameters are: 
  455.  
  456.    ld     The connection handle; 
  457.  
  458.    entry  The entry whose attributes are to be stepped through, as           returned by ldap_first_entry() or ldap_next_entry(); 
  459.  
  460.    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(). 
  461.  
  462.    ldap_first_attribute() and ldap_next_attribute() will return NULL    when the end of the attributes is reached, or if there is an error,    in which case the ld_errno field in the ld connection handle will be    set to indicate the error. 
  463.  
  464.    Both routines return a pointer to a per-connection buffer containing    the current attribute name. This should be treated like static data.    ldap_first_attribute() 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. 
  465.  
  466.    The attribute names returned are suitable for passing in a call to    ldap_get_values() and friends to retrieve the associated values. 
  467.  
  468.  
  469.  
  470.  
  471.  
  472.  Howes & Smith                Informational                     [Page 16] 
  473.  RFC 1823                        LDAP API                     August 1995 
  474.  
  475.  8.3.  Retrieving the values of an attribute 
  476.  
  477.    ldap_get_values() and ldap_get_values_len() are used to retrieve the    values of a given attribute from an entry. ldap_count_values() and    ldap_count_values_len() are used to count the returned values.    ldap_value_free() and ldap_value_free_len() are used to free the    values. 
  478.  
  479.            typedef struct berval {                    unsigned long   bv_len;                    char            *bv_val;            }; 
  480.  
  481.            char **ldap_get_values(                    LDAP            *ld,                    LDAPMessage     *entry,                    char            *attr            ); 
  482.  
  483.            struct berval **ldap_get_values_len(                    LDAP            *ld,                    LDAPMessage     *entry,                    char            *attr            ); 
  484.  
  485.            int ldap_count_values( char **vals ); 
  486.  
  487.            int ldap_count_values_len( struct berval **vals ); 
  488.  
  489.            int ldap_value_free( char **vals ); 
  490.  
  491.            int ldap_value_free_len( struct berval **vals ); 
  492.  
  493.    Parameters are: 
  494.  
  495.    ld     The connection handle; 
  496.  
  497.    entry  The entry from which to retrieve values, as returned by           ldap_first_entry() or ldap_next_entry(); 
  498.  
  499.    attr   The attribute whose values are to be retrieved, as returned by           ldap_first_attribute() or ldap_next_attribute(), or a caller-           supplied string (e.g., "mail"); 
  500.  
  501.    vals   The values returned by a previous call to ldap_get_values() or           ldap_get_values_len(). 
  502.  
  503.  
  504.  
  505.  
  506.  
  507. Howes & Smith                Informational                     [Page 17] 
  508.  RFC 1823                        LDAP API                     August 1995 
  509.  
  510.     Two forms of the various calls are provided. The first form is only    suitable for use with non-binary character string data only. The    second _len form is used with any kind of data. 
  511.  
  512.    Note that the values returned are malloc'ed and should be freed by    calling either ldap_value_free() or ldap_value_free_len() when no    longer in use. 
  513.  
  514. 8.4.  Retrieving the name of an entry 
  515.  
  516.    ldap_get_dn() is used to retrieve the name of an entry.    ldap_explode_dn() is used to break up the name into its component    parts. ldap_dn2ufn() is used to convert the name into a more "user    friendly" format. 
  517.  
  518.            char *ldap_get_dn( LDAP *ld, LDAPMessage *entry ); 
  519.  
  520.            char **ldap_explode_dn( char *dn, int notypes ); 
  521.  
  522.            char *ldap_dn2ufn( char *dn ); 
  523.  
  524.    Parameters are: 
  525.  
  526.    ld      The connection handle; 
  527.  
  528.    entry   The entry whose name is to be retrieved, as returned by            ldap_first_entry() or ldap_next_entry(); 
  529.  
  530.    dn      The dn to explode, as returned by ldap_get_dn(); 
  531.  
  532.    notypes A boolean parameter, if non-zero indicating that the dn com-            ponents should have their type information stripped off            (i.e., "cn=Babs" would become "Babs"). 
  533.  
  534.    ldap_get_dn() will return NULL if there is some error parsing the dn,    setting ld_errno in the ld connection handle to indicate the error.    It returns a pointer to malloc'ed space that the caller should free    by calling free() when it is no longer in use.  Note the format of    the DNs returned is given by [4]. 
  535.  
  536.    ldap_explode_dn() returns a char * array containing the RDN    components of the DN supplied, with or without types as indicated by    the notypes parameter. The array returned should be freed when it is    no longer in use by calling ldap_value_free(). 
  537.  
  538.    ldap_dn2ufn() converts the DN into the user friendly format described    in [5]. The UFN returned is malloc'ed space that should be freed by a    call to free() when no longer in use. 
  539.  
  540.  
  541.  
  542. Howes & Smith                Informational                     [Page 18] 
  543.  RFC 1823                        LDAP API                     August 1995 
  544.  
  545.  9.  Security Considerations 
  546.  
  547.    LDAP supports minimal security during connection authentication. 
  548.  
  549. 10.  Acknowledgements 
  550.  
  551.    This material is based upon work supported by the National Science    Foundation under Grant No. NCR-9416667. 
  552.  
  553. 11.  Bibliography 
  554.  
  555.    [1] The Directory: Selected Attribute Syntaxes.  CCITT,        Recommendation X.520. 
  556.  
  557.    [2] Howes, T., Kille, S., Yeong, W., and C. Robbins, "The String        Representation of Standard Attribute Syntaxes", University of        Michigan, ISODE Consortium, Performance Systems International,        NeXor Ltd., RFC 1778, March 1995. 
  558.  
  559.    [3] Howes, T., "A String Representation of LDAP Search Filters", RFC        1558, University of Michigan, December 1993. 
  560.  
  561.    [4] Kille, S., "A String Representation of Distinguished Names", RFC        1779, ISODE Consortium, March 1995. 
  562.  
  563.    [5] Kille, S., "Using the OSI Directory to Achieve User Friendly        Naming",  RFC 1781, ISODE Consortium, March 1995. 
  564.  
  565.    [6] S.P. Miller, B.C. Neuman, J.I. Schiller, J.H. Saltzer, "Kerberos        Authentication and Authorization System", MIT Project Athena        Documentation Section  E.2.1, December 1987 
  566.  
  567.    [7] Yeong, W., Howes, T., and S. Kille, "Lightweight Directory Access        Protocol," RFC 1777, Performance Systems International,        University of Michigan, ISODE Consortium, March 1995. 
  568.  
  569.  
  570.  
  571.  
  572.  
  573.  
  574.  
  575.  
  576.  
  577.  
  578.  
  579.  
  580.  
  581.  
  582.  
  583.  Howes & Smith                Informational                     [Page 19] 
  584.  RFC 1823                        LDAP API                     August 1995 
  585.  
  586.  12.  Authors' Addresses 
  587.  
  588.        Tim Howes        University of Michigan        ITD Research Systems        535 W William St.        Ann Arbor, MI 48103-4943        USA 
  589.  
  590.        Phone: +1 313 747-4454        EMail: tim@umich.edu 
  591.  
  592.         Mark Smith        University of Michigan        ITD Research Systems        535 W William St.        Ann Arbor, MI 48103-4943        USA 
  593.  
  594.        Phone: +1 313 764-2277        EMail: mcs@umich.edu 
  595.  
  596.  
  597.  
  598.  
  599.  
  600.  
  601.  
  602.  
  603.  
  604.  
  605.  
  606.  
  607.  
  608.  
  609.  
  610.  
  611.  
  612.  
  613.  
  614.  
  615.  
  616.  
  617.  
  618.  
  619.  
  620.  
  621.  
  622.  
  623.  
  624. Howes & Smith                Informational                     [Page 20] 
  625.  RFC 1823                        LDAP API                     August 1995 
  626.  
  627.  13.  Appendix A - Sample LDAP API Code 
  628.  
  629.    #include <ldap.h> 
  630.  
  631.    main()    {            LDAP            *ld;            LDAPMessage     *res, *e;            int             i;            char            *a, *dn;            void            *ptr;            char            **vals; 
  632.  
  633.            /* open a connection */            if ( (ld = ldap_open( "dotted.host.name", LDAP_PORT ))                    == NULL )                    exit( 1 ); 
  634.  
  635.            /* authenticate as nobody */            if ( ldap_simple_bind_s( ld, NULL, NULL ) != LDAP_SUCCESS ) {                    ldap_perror( ld, "ldap_simple_bind_s" );                    exit( 1 );            } 
  636.  
  637.            /* search for entries with cn of "Babs Jensen",                    return all attrs  */            if ( ldap_search_s( ld, "o=University of Michigan, c=US",                LDAP_SCOPE_SUBTREE, "(cn=Babs Jensen)", NULL, 0, &res )                != LDAP_SUCCESS ) {                    ldap_perror( ld, "ldap_search_s" );                    exit( 1 );            } 
  638.  
  639.            /* step through each entry returned */            for ( e = ldap_first_entry( ld, res ); e != NULL;                e = ldap_next_entry( ld, e ) ) {                    /* print its name */                    dn = ldap_get_dn( ld, e );                    printf( "dn: %s0, dn );                    free( dn ); 
  640.  
  641.                    /* print each attribute */                    for ( a = ldap_first_attribute( ld, e, &ptr );                            a != NULL;                        a = ldap_next_attribute( ld, e, ptr ) ) {                            printf( "attribute: %s0, a ); 
  642.  
  643.                            /* print each value */ 
  644.  
  645.  
  646.  
  647. Howes & Smith                Informational                     [Page 21] 
  648.  RFC 1823                        LDAP API                     August 1995 
  649.  
  650.                             vals = ldap_get_values( ld, e, a );                            for ( i = 0; vals[i] != NULL; i++ ) {                                    printf( "value: %s0, vals[i] );                            }                            ldap_value_free( vals );                    }            }            /* free the search results */            ldap_msgfree( res ); 
  651.  
  652.            /* close and free connection resources */            ldap_unbind( ld );    } 
  653.  
  654.  
  655.  
  656.  
  657.  
  658.  
  659.  
  660.  
  661.  
  662.  
  663.  
  664.  
  665.  
  666.  
  667.  
  668.  
  669.  
  670.  
  671.  
  672.  
  673.  
  674.  
  675.  
  676.  
  677.  
  678.  
  679.  
  680.  
  681.  
  682.  
  683.  
  684.  
  685.  
  686.  
  687.  
  688.  
  689.  
  690.  Howes & Smith                Informational                     [Page 22] 
  691.  
  692.