]> git.sur5r.net Git - openldap/commitdiff
Relevant drafts...
authorKurt Zeilenga <kurt@openldap.org>
Tue, 4 May 1999 04:25:18 +0000 (04:25 +0000)
committerKurt Zeilenga <kurt@openldap.org>
Tue, 4 May 1999 04:25:18 +0000 (04:25 +0000)
doc/drafts/draft-ietf-ldapext-acl-model-02.txt [new file with mode: 0644]
doc/drafts/draft-ietf-ldapext-ldap-c-api-02.txt [new file with mode: 0644]

diff --git a/doc/drafts/draft-ietf-ldapext-acl-model-02.txt b/doc/drafts/draft-ietf-ldapext-acl-model-02.txt
new file mode 100644 (file)
index 0000000..f390148
--- /dev/null
@@ -0,0 +1,2440 @@
+
+
+
+
+
+
+
+          Internet-Draft                                     E. Stokes
+          LDAP Extensions WG                                  D. Byrne
+          Intended Category: Standards Track                B. Blakley
+          Expires: 15 October 1999                                 IBM
+                                                         15 April 1999
+
+                         Access Control Model for LDAP
+                     <draft-ietf-ldapext-acl-model-02.txt>
+
+          STATUS OF THIS MEMO
+
+             This document is an Internet-Draft and is in full
+             conformance with all provisions of Section 10 of RFC2026.
+
+             Internet-Drafts are working documents of the Internet
+             Engineering Task Force (IETF), its areas, and its working
+             groups. Note that other groups may also distribute
+             working documents as Internet-Drafts. Internet-Drafts are
+             draft documents valid for a maximum of six months and may
+             be updated, replaced, or obsoleted by other documents at
+             any time. It is inappropriate to use Internet- Drafts as
+             reference material or to cite them other than as "work in
+             progress."
+
+             The list of current Internet-Drafts can be accessed at
+             http://www.ietf.org/ietf/1id-abstracts.txt
+
+             The list of Internet-Draft Shadow Directories can be
+             accessed at http://www.ietf.org/shadow.html.
+
+             Comments and suggestions on this document are encouraged.
+             Comments on this document should be sent to the  LDAPEXT
+             working group discussion list:
+
+                    ietf-ldapext@netscape.com
+
+          ABSTRACT
+
+             This document describes the access control model for the
+             Lightweight Directory Application Protocol (LDAP)
+             directory service. It includes a description of the
+             model, the LDAP controls, and the extended operations to
+             the LDAP protocol.  A separate document defines the
+             corresponding application programming interfaces (APIs).
+             RFC2219 [Bradner97] terminology is used.
+
+
+
+          Stokes, Byrne, Blakley  Expires 15 October 1999         [Page 1]
+\f
+
+
+
+
+          Internet-Draft      Access Control Model       15 April 1999
+
+
+
+          1.  Introduction
+
+             The ability to securely access (replicate and distribute)
+             directory information throughout the network is necessary
+             for successful deployment.  LDAP's acceptance as an
+             access protocol for directory information is driving the
+             need to provide an access control model definition for
+             LDAP directory content among servers within an enterprise
+             and the Internet.  Currently LDAP does not define an
+             access control model, but is needed to ensure consistent
+             secure access across heterogeneous LDAP implementations.
+             The major objective is to provide a simple, but secure,
+             highly efficient access control model for LDAP while also
+             providing the appropriate flexibility to meet the needs
+             of both the Internet and enterprise environments and
+             policies.  This document defines the model and the
+             protocol extensions (controls and extended operations).
+             A separate document defines the corresponding application
+             programming interfaces (APIs).
+
+
+          2.  Overview
+
+             Access Control mechanisms evaluate requests for access to
+             protected resources and make decisions about whether
+             those requests should be granted or denied.  In order to
+             make a grant/deny decision about a request for access to
+             a protected resource, an access control mechanism needs
+             to evaluate policy data.  This policy data describes
+             security-relevant characteristics of the requesting
+             subject and the rules which govern the use of the target
+             object.
+
+             This proposal defines the protocol elements for
+             transmission of this access control policy data in an
+             LDAP environment and an attribute that defines the access
+             control mechanism in effect for a given part of the LDAP
+             namespace.  The instantiation of an access control model
+             at the directory server is not defined in this document.
+             By defining only what flows on the wire allows existing
+             access control mechanisms to be used at the directory
+             server.
+
+             No mechanisms are defined in this document to control
+             access to access control information or for storage of
+
+
+
+          Stokes, Byrne, Blakley  Expires 15 October 1999         [Page 2]
+\f
+
+
+
+
+          Internet-Draft      Access Control Model       15 April 1999
+
+
+
+             access control information at the server; this is vendor
+             dependent.
+
+             A separate requirements document for access control
+             exists.  The access control model used the requirements
+             documents as a guideline for the development of this
+             specification and are reflected in this specification to
+             the extent that the working group could agree on an
+             access control model.
+
+             The access control model defines
+
+                - A wire protocol for interoperability:  The existing
+                  LDAP protocol flows for add, delete, modify, etc are
+                  used to manipulate access control information.
+                  There are additional LDAP controls and extended
+                  protocol operations defined to further help
+                  management of access control information:
+                  getEffectiveRights, listSubjectRights, and
+                  specifyCredentials.
+
+                - LDAP Directory Interchange Format (LDIF) for
+                  application portability:  The LDIF is defined for
+                  access control information (ACI).  This LDIF is also
+                  used as input to the LDAP APIs so access control
+                  information can be addressed uniformly independent
+                  of how that information is stored and addressed at
+                  the server.
+
+                - A set of attributes to identity the access control
+                  mechanisms supported by a server.
+
+             Encoding of access control information on the wire is per
+             the LDAPv3 specifications.
+
+
+          3.  Terminology
+
+             An "access control list" contains the access control
+             policy information controlling access to an object or
+             collection of objects.  An access control list consists
+             of a set of access control list entries.
+
+             An "access control list entry" defines a single subject
+             security attribute's granted rights for the objects
+
+
+
+          Stokes, Byrne, Blakley  Expires 15 October 1999         [Page 3]
+\f
+
+
+
+
+          Internet-Draft      Access Control Model       15 April 1999
+
+
+
+             governed by the access control list to which it belongs.
+
+             The "access control policy information" (acpi) for an
+             object or a collection of objects defines which subject
+             security attributes entitle a subject to which granted
+             rights.  The access control policy information for an
+             object is stored in an access control list.
+
+             An "access decision" is a boolean-valued function which
+             answers the question: "can the subject with these subject
+             security attributes perform this operation on this
+             object?"
+
+             An "access decision function" is an algorithm which makes
+             an access decision based on subject security attributes,
+             access control policy information, an object identifier,
+             and an operation name (possibly augmented by additional
+             contextual information).
+
+             An "access decision function interface" is a programmatic
+             interface through which applications can request an
+             access decision.
+
+             An "access identity" is an identity which is used by an
+             access decision function to make an access decision.
+
+             An "audit identity" is an identity which does not, in the
+             absence of additional information, enable a party
+             receiving and examining it to determine which subject it
+             belongs to.
+
+             A "credential" is a collection of subject security
+             attributes.
+
+             "effective rights" are the complete set of rights a
+             subject is entitled to based on all access control lists
+             which apply to a specific object and based on all of the
+             subject's security attributes.
+
+             "granted rights" are the complete set of rights an access
+             control list entitles a subject to based on a specific
+             subject security attribute.
+
+             A "group" is a privilege attribute asserting a subject's
+             membership in the collection of subjects whose name is
+
+
+
+          Stokes, Byrne, Blakley  Expires 15 October 1999         [Page 4]
+\f
+
+
+
+
+          Internet-Draft      Access Control Model       15 April 1999
+
+
+
+             that of the group.
+
+             An "identity" is a subject security attribute which is
+             unique to a single subject.
+
+             An "object" is the target of operations in an information
+             system.
+
+             An "operation" is the result of executing the code
+             accessed through a named entry point in an information
+             system.
+
+             An "operation name" is the name of the entry point
+             through which an operation is invoked in an information
+             system.
+
+             A "privilege attribute" is a subject security attribute
+             which may be shared by several subjects.
+
+             "required rights" are the complete set of rights needed
+             to authorize a requester to perform a specific operation
+             on an object of a specific type.
+
+             A "right" is the basic unit of access control policy
+             administration.  For each object type in an information
+             system, a security administrator defines a set of
+             required rights for each operation.  For each object in
+             the system, a security administrator defines a set of
+             granted rights for each subject security attribute.  When
+             an access decision is required, an access decision
+             function checks to make sure that the requester's subject
+             security attributes have been granted all required rights
+             needed to perform the requested operation on the
+             specified target object.
+
+             A "role" is a privilege attribute asserting a subject's
+             organizational position and entitlement to perform the
+             operations appropriate to that organizational position.
+
+             A "subject" is an entity which intiates actions in an
+             information system.
+
+             A "subject security attribute" is a defined property
+             which is used by a security policy evaluation system to
+             make policy decisions.
+
+
+
+          Stokes, Byrne, Blakley  Expires 15 October 1999         [Page 5]
+\f
+
+
+
+
+          Internet-Draft      Access Control Model       15 April 1999
+
+
+
+          4.  The Model
+
+
+          4.1  Access Control Activity Lifecycle
+
+             The access control proposal described in this draft
+             addresses four activities:
+
+                - Creation of subject security attribute information
+                  and access control policy information
+
+                - Retrieval of subject security attribute information
+                  at the time an access request is made
+
+                - Evaluation of access requests against policy,
+                  resulting in an access decision
+
+                - Replication of access control policy information
+                  from one server to another
+
+          4.2  Access Control Information Model
+
+             This document does not define formats for storage of
+             access control information; it does define the
+             operational semantics of access control operations.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+          Stokes, Byrne, Blakley  Expires 15 October 1999         [Page 6]
+\f
+
+
+
+
+          Internet-Draft      Access Control Model       15 April 1999
+
+
+
+             The diagram below illustrates the componentry of an LDAP
+             system and the placement of the function specified in
+             this draft.
+
+                         +-------------+
+                         | Application |
+                         +-------------+
+                           +--------+
+                           | LDAP   |
+                           | Client |
+                           +--------+
+                               |
+                               |
+                               | <-- LDAP Extended Access Control
+             Controls
+                               |     or Extended Access Control
+             Operations
+                               v
+                    +-----------------------------+
+                    |   LDAP Server (e.g. SLAPD)  |
+                    +-----------------------------+
+                          .                 |
+                          .                 |
+                          .                 |
+                          .                 |
+                          v                 v
+                    +----------+      +-----------+
+                    | Access   |      |           |
+                    | Control  |<.....| Datastore |
+                    | Manager  |      |           |
+                    +----------+      +-----------+
+
+             LDAP clients use the controls and extended operations
+             specified in this document to administer access control
+             policy enforced by LDAP servers.  Servers may store
+             access control information in any way they choose. In
+             particular, servers may use the access control mechanisms
+             of their datastores to store and enforce LDAP access
+             control, or they may implement access control managers
+             external to their datastores.  Datastores and external
+             access control managers may implement  any access control
+             rule syntax and semantics they choose, as long as the
+             semantics is compatible with that defined in the section
+             titled "Operational Semantics of Access Control
+             Operations" (found after the control and extended
+
+
+
+          Stokes, Byrne, Blakley  Expires 15 October 1999         [Page 7]
+\f
+
+
+
+
+          Internet-Draft      Access Control Model       15 April 1999
+
+
+
+             operation definition).
+
+             The access control administration mechanisms specified in
+             this document are neutral with respect to policy
+             inheritance mechanisms, explicit vs.  implicit denial,
+             and group nesting.
+
+          4.3  Bind and Credentials
+
+             A bind authenticates a principal to the directory.  A
+             principal is represented by a DN.  A principal has a set
+             of credentials that are used for determining whether
+             access to resources specified in ldap operations.  These
+             credentials may be pushed to the server by the client or
+             may be pulled by the server from the directory data.
+             Credentials may be local with respect to the server.  If
+             not local (owned by another server or administrative
+             scope), then the server may decide to define a trust
+             model that states how to evaluate the trust of a
+             credential at bind time.  The definition of such a trust
+             model is outside the scope of this document.
+
+
+          5.  Access Control Information Schema
+
+
+          5.1  Attributes
+
+
+          5.1.1  Root DSE Attribute for Access Control Mechanism
+
+             The following attribute may be included in the Root DSE.
+
+              (<OID to be assigned>
+                 NAME      'supportedACIMechanisms'
+                 DESC      list of access control mechanisms supported
+                             by this directory server
+                 SYNTAX    LDAPOID
+              )
+
+             Two access control mechanisms are defined by this
+             document:
+                  LDAPv3     <OID to be assigned>
+                  X500       <OID to be assigned>
+
+
+
+
+          Stokes, Byrne, Blakley  Expires 15 October 1999         [Page 8]
+\f
+
+
+
+
+          Internet-Draft      Access Control Model       15 April 1999
+
+
+
+             Other vendor access control mechanisms can be defined (by
+             OID) and are the responsibility of those vendors to
+             provide the definition and OID.
+
+          5.1.2  Subschema Attribute for Access Control Mechanism
+
+             A given naming context must provide information about
+             which access control mechanism is in effect for that
+             portion of the namespace.  The following attribute must
+             be in each subschema entry associated with a naming
+             context whose access control mechanism is different from
+             adjacent naming contexts supported by that directory
+             server.
+
+                - aCIMechanism lists the value (an OID) that defines
+                  the access control mechanism in effect for the scope
+                  of that subschema entry
+
+          5.2  Other Defined Parameters/OIDs
+
+
+          5.2.1  Rights Families and Rights
+
+             The following rights families are defined:
+                  LDAPv3     <OID to be assigned>
+                  X500       <OID to be assigned>
+
+             Other parties can (and will) define other rights
+             families.  It is the responsibility of those parties to
+             provide the definition and OID.
+
+          5.2.1.1  LDAPv3 Rights Family
+
+             Access rights can apply to an entire object or to
+             attributes of the object.  Each of the LDAP access rights
+             are discrete. One permission does not imply another
+             permission.  The rights may be ORed together to provide
+             the desired rights list.
+
+             Rights which apply to attributes are:
+
+                1   Read     Read attribute values
+                2   Write    Write attribute values
+                4   Search   Search entries with specified attributes
+                8   Compare  Compare attributes
+
+
+
+          Stokes, Byrne, Blakley  Expires 15 October 1999         [Page 9]
+\f
+
+
+
+
+          Internet-Draft      Access Control Model       15 April 1999
+
+
+
+             Rights that apply to an entire object are:
+
+               16   Add      Add an object below this object
+               32   Delete   Delete this object
+
+             Rights that apply to the object to which the directory
+             object points are:
+
+               64   Manage   Perform a privileged operation; used to
+                              restrict access to operations which
+                              read or write especially sensitive data
+              128   Use      Execute; useful in controlling access to
+                              the objects referred to by directory
+                              entries than in controlling access to
+                              the directory entries themselves
+              256   Get      Get retrieves the attribute values
+              512   Set      Set writes the attribute values
+
+          5.2.1.2  The X.500 Rights Family
+
+             <define the rights for X.500>
+
+          5.2.2  DN Types
+
+             The following DN Types are defined:
+
+                - access-id, OID=<OID to be assigned>
+
+                - group, OID=<OID to be assigned>
+
+                - role, OID=<OID to be assigned>
+
+             access-id, group, and role MUST be supported.  An acess-
+             id is a non-collection (non-group and non-role objects)
+             DN that can be authenticated.
+
+             Other parties can (and will) define other DN Types.  It
+             is the responsibility of those parties to provide the
+             definition and OID.
+
+
+          6.  Access Control Parameters for LDAP Controls & Extended
+          Operations
+
+             This section defines the parameters used in the access
+
+
+
+          Stokes, Byrne, Blakley  Expires 15 October 1999        [Page 10]
+\f
+
+
+
+
+          Internet-Draft      Access Control Model       15 April 1999
+
+
+
+             control LDAP controls and extended operations in this
+             document.
+
+             targetDN specifies the initial directory entry in DN
+             syntax on which the control or extended operation is
+             performed.
+
+             whichObject specifies whether the access control
+             information which is get/set is for the target directory
+             entry (ENTRY) or the target directory entry and its
+             subtree (SUBTREE).
+
+             rightsFamily specifies the family of rights that will be
+             get/set for the control or extended operation performed.
+             A rights family has a defined set of rights.
+
+             rightsList in the SearchResultEntry is of the form
+             specified in the LDIF BNF for <right>.
+
+             dnType speficies the type of subject security attribute.
+             Defined types are access-id, group, and role.
+
+             subjectDN is a LDAP string that defines the subject or
+             value of the dnType.  The subjectDN may be a DN or
+             another string such as IPAddress (dotted-decimal string
+             representation) on which access control is get/set.  If
+             the subject is an entry in the directory, then the syntax
+             of the LDAP string is DN.  We define two well-known
+             subjectDNs, the strings
+
+                - public - meaning public access for all users
+
+                - this - meaning the user whose name matches the entry
+                  being accessed
+
+             Four operations are defined:
+
+                - ACI_GRANT grants the rights specified in the
+                  rightsList for the given subject. If an access
+                  control list does not exist for the specified
+                  entry/attribute, then the access control list is
+                  created with the granted rights for the given
+                  subject.  If the access control list already exists
+                  for the specified entry/attribute, then the access
+                  control list is modified to grant the rights for the
+
+
+
+          Stokes, Byrne, Blakley  Expires 15 October 1999        [Page 11]
+\f
+
+
+
+
+          Internet-Draft      Access Control Model       15 April 1999
+
+
+
+                  given subject.
+
+                - ACI_DENY denies the rights specified in the
+                  rightsList for the given subject.  No implementation
+                  is implied for this operation.  For example, denial
+                  of rights may be implemented as explicit denial
+                  (negative rights) on the access control list or
+                  removal of rights from the access control list.
+
+                - ACI_REPLACE replaces the entire access control list
+                  for the specified entry/attribute.  If an access
+                  control list does not exist for the specified
+                  entry/attribute, then the access control list is
+                  created with the granted rights for the given
+                  subject.
+
+                - ACI_DELETE deletes the entire access control list
+                  for the specified entry/attribute.
+
+             attrs specifies the list of attributes against which the
+             operation is performed.  attrs can be defined using a
+             LDAP filter expression.
+
+
+          7.  Access Control Information (ACI) Controls
+
+             The access control information controls provide a way to
+             manipulate access control information in conjunction with
+             an LDAP operation such as ldap_add, ldap_modify, or
+             ldap_search.  Three LDAP controls are defined for
+             transmission of access control information.  These
+             controls allow access control information to be get/set
+             while manipulating other directory information.  The
+             controls are:
+
+                - getEffectiveRights to obtain the effective rights
+                  for a given directory entry(s) for a given subject
+                  during a ldap_search operation
+
+                - listSubjectRights to get the access control
+                  information for a given directory entry(s) during a
+                  ldap_search operation
+
+                - specifyCredentials to specify a set of credentials
+                  for the bind identity (DN) during a ldap_bind
+
+
+
+          Stokes, Byrne, Blakley  Expires 15 October 1999        [Page 12]
+\f
+
+
+
+
+          Internet-Draft      Access Control Model       15 April 1999
+
+
+
+                  operation
+
+          7.1  getEffectiveRights Control
+
+
+          7.1.1  Request Control
+
+             This control is  included in  the ldap_search  message as
+             part of the controls  field  of the  LDAPMessage, as
+             defined in  Section  4.1.12 of [LDAPv3].
+
+             The controlType is set to <OID to be assigned>. The
+             criticality MAY be either TRUE or FALSE (where absent is
+             also equivalent to FALSE) at the client's option.  The
+             controlValue is an OCTET STRING, whose value is the BER
+             encoding of a value of the following SEQUENCE:
+
+              getEffectiveRightsRequest ::= SEQUENCE {
+                   targetDN  LDAPDN,
+                   effectiveRightsRequest   SEQUENCE OF SEQUENCE {
+                               rightsFamily  LDAPOID | "*",
+                               whichObject   ENUMERATED {
+                                               LDAP_ENTRY (1),
+                                               LDAP_SUBTREE (2)
+                                               },
+                               dnType        LDAPOID | "*",
+                               subjectDN     LDAPString,
+                               }
+              }
+
+             The targetDN specifies the initial directory entry in DN
+             syntax on which the getEffectiveRights control is
+             performed.  request is a set of sequences that state the
+             whichObject (entry or entry plus subtree) and specifics
+             of the control request to be performed.  One or more
+             rightsFamily can be be obtained for a given subjectDN ad
+             dnType.  A "*" in the rightsFamily field indicates that
+             the rights for all rights families defined for the
+             subjectDN / dnType are to be returned.  This control is
+             applied to the scope set by the ldap_search operation,
+             i.e.  base, one-level, subtree.
+
+          7.1.2  Response Control
+
+             This control is included in the ldap_search_response
+
+
+
+          Stokes, Byrne, Blakley  Expires 15 October 1999        [Page 13]
+\f
+
+
+
+
+          Internet-Draft      Access Control Model       15 April 1999
+
+
+
+             message as part of the controls field of the LDAPMessage,
+             as defined in Section 4.1.12 of [LDAPv3].
+
+             The controlType is set to <OID to be assigned>. The
+             criticality MAY be either TRUE or FALSE (where absent is
+             also equivalent to FALSE).  The controlValue is an OCTET
+             STRING, whose value is the BER encoding of a value of the
+             following SEQUENCE:
+
+              getEffectiveRightsResponse ::= {
+                result  ENUMERATED {
+                   success                       (0),
+                   operationsError               (1),
+                   unavailableCriticalExtension (12),
+                   noSuchAttribute              (16),
+                   undefinedAttributeType       (17),
+                   invalidAttributeSyntax       (21),
+                   unavailable                  (52),
+                   unwillingToPerform           (53),
+                   other                        (80)
+                   }
+              }
+
+             The effective rights returned are returned with each
+             attribute returned by the search result.  So, the result
+             for ldap_search is:
+
+              SearchResultEntry ::= [APPLICATION 4] SEQUENCE {
+                 objectName    LDAPDN,
+                 rightsAttributes    PartialEffectiveRightsList }
+
+              PartialEffectiveRightsList ::= SEQUENCE OF SEQUENCE {
+                 rightFamily   LDAPOID,
+                 rightsList    ENUMERATED,
+                 whichObject   ENUMERATED {
+                                   LDAP_ENTRY (1),
+                                   LDAP_SUBTREE (2)
+                                   }
+              }
+
+             Although this extends the search operation, there are no
+             incompatibilities between versions.  LDAPv2 cannot send a
+             control, hence the above structure cannot be returned to
+             a LDAPv2 client.  A LDAPv3 client cannot send this
+             request to a LDAPv2 server.  A LDAPv3 server not
+
+
+
+          Stokes, Byrne, Blakley  Expires 15 October 1999        [Page 14]
+\f
+
+
+
+
+          Internet-Draft      Access Control Model       15 April 1999
+
+
+
+             supporting this control cannot return the additional
+             data.
+
+          7.1.3  Client-Server Interaction
+
+             The getEffectiveRightsRequest control requests the rights
+             that MUST be in effect for requested directory
+             entry/attribute based on the subject DN.  The server that
+             consumes the search operation looks up the rights for the
+             returned directory information based on the subject DN
+             and returns that rights information.
+
+             There are six possible scenarios that may occur as a
+             result of the getEffectiveRights control being included
+             on the search request:
+
+
+               1.  If the server does not support this control and the
+                   client specified TRUE for the control's criticality
+                   field, then the server MUST return
+                   unavailableCriticalExtension as a return code in
+                   the searchResponse message and not send back any
+                   other results.  This behavior is specified in
+                   section 4.1.12 of [LDAPv3].
+
+               2.  If the server does not support this control and the
+                   client specified FALSE for the control's
+                   criticality field, then the server MUST ignore the
+                   control and process the request as if it were not
+                   present.  This behavior is specified in section
+                   4.1.12 of [LDAPv3].
+
+               3.  If the server supports this control but for some
+                   reason such as cannot process specified
+                   rightsFamily and the client specified TRUE for the
+                   control's criticality field, then the server SHOULD
+                   do the following: return
+                   unavailableCriticalExtension as a return code in
+                   the searchResult message.
+
+               4.  If the server supports this control but for some
+                   reason such as cannot process specified
+                   rightsFamily and the client specified FALSE for the
+                   control's criticality field, then the server should
+                   process as 'no rights returned for that family' and
+
+
+
+          Stokes, Byrne, Blakley  Expires 15 October 1999        [Page 15]
+\f
+
+
+
+
+          Internet-Draft      Access Control Model       15 April 1999
+
+
+
+                   include the result Unavailable in the
+                   getEffectiveRightsResponse control in the
+                   searchResult message.
+
+               5.  If the server supports this control and can return
+                   the rights per the rightsFamily information, then
+                   it should include the getEffectiveRightsResponse
+                   control in the searchResult message with a result
+                   of success.
+
+               6.  If the search request failed for any other reason,
+                   then the server SHOULD omit the
+                   getEffectiveRightsResponse control from the
+                   searchResult message.
+
+             The client application is assured that the correct rights
+             are returned for scope of the search operation if and
+             only if the getEffectiveRightsResponse control returns
+             the rights.  If the server omits the
+             getEffectiveRightsResponse control from the searchResult
+             message, the client SHOULD assume that the control was
+             ignored by the server.
+
+             The getEffectiveRightsResponse control, if included by
+             the server in the searchResponse message, should have the
+             getEffectiveRightsResult set to either success if the
+             rights are returned or set to the appropriate error code
+             as to why the rights could not be returned.
+
+             The server may not be able to return a right because it
+             may not exist in that directory object's attribute; in
+             this case, the rights request is ignored with success.
+
+          7.2  listSubjectRights Control
+
+
+          7.2.1  Request Control
+
+             This control is included in  the ldap_search  message as
+             part of the controls  field  of the  LDAPMessage, as
+             defined in  Section  4.1.12 of [LDAPv3].
+
+             The controlType is set to <OID to be assigned>. The
+             criticality MAY be either TRUE or FALSE (where absent is
+             also equivalent to FALSE) at the client's option.  The
+
+
+
+          Stokes, Byrne, Blakley  Expires 15 October 1999        [Page 16]
+\f
+
+
+
+
+          Internet-Draft      Access Control Model       15 April 1999
+
+
+
+             controlValue is an OCTET STRING, whose value is the BER
+             encoding of a value of the following SEQUENCE:
+
+              listSubjectRightsRequest ::= SEQUENCE {
+                   targetDN  LDAPDN,
+                   listRightsRequest   SEQUENCE OF SEQUENCE {
+                               rightsFamily  LDAPOID | "*",
+                               whichObject   ENUMERATED {
+                                               LDAP_ENTRY (1),
+                                               LDAP_SUBTREE (2)
+                                               },
+                               dnType        LDAPOID | "*",
+                               listSubjectDN     LDAPString | "*",
+                               }
+              }
+
+             The targetDN specifies the initial directory entry in DN
+             syntax on which the listSubjectRights control is
+             performed.  request is a set of sequences that state the
+             whichObject (entry or entry plus subtree) and specifics
+             of the control request to be performed.  One or more
+             rightsFamily can be be obtained for a given subjectDN ad
+             dnType.  A "*" in the rightsFamily field indicates that
+             the rights for all rights families defined for the
+             subjectDN / dnType are to be returned.  A "*" in the
+             dnType field indicates that all dnTypes are processed by
+             this request.  A "*" in the subjectDN field indicates
+             that all subjectDNs are processed by this request. The
+             scope of the operation is controlled by the scope set in
+             the ldap_search operation.
+
+          7.2.2  Response Control
+
+             This control is included in the ldap_search message as
+             part of the controls field of the LDAPMessage, as defined
+             in Section 4.1.12 of [LDAPv3].
+
+             The controlType is set to <OID to be assigned>. The
+             criticality MAY be either TRUE or FALSE (where absent is
+             also equivalent to FALSE).  The controlValue is an OCTET
+             STRING, whose value is the BER encoding of a value of the
+             following SEQUENCE:
+
+              listSubjectRightsResponse ::= {
+                result  ENUMERATED {
+
+
+
+          Stokes, Byrne, Blakley  Expires 15 October 1999        [Page 17]
+\f
+
+
+
+
+          Internet-Draft      Access Control Model       15 April 1999
+
+
+
+                   success                       (0),
+                   operationsError               (1),
+                   unavailableCriticalExtension (12),
+                   noSuchAttribute              (16),
+                   undefinedAttributeType       (17),
+                   invalidAttributeSyntax       (21),
+                   unavailable                  (52),
+                   unwillingToPerform           (53),
+                   other                        (80)
+                   }
+              }
+
+             The subjects' rights returned are returned with each
+             attribute returned by the search result.  So, the result
+             for ldap_search is:
+
+              SearchResultEntry ::= [APPLICATION 4] SEQUENCE {
+                 objectName    LDAPDN,
+                 attributes    PartialSubjRightsAttributeList }
+
+              PartialSubjRightsAttributeList ::= SEQUENCE OF SEQUENCE
+             {
+                 rightFamily   LDAPOID,
+                 whichObject   ENUMERATED {
+                                 LDAP_ENTRY (1),
+                                 LDAP_SUBTREE (2)
+                                 },
+                 subjectDnType LDAPOID,
+                 subjectDN     LDAPString,
+                 rightsList    ENUMERATED
+                 }
+
+             Although this extends the search operation, there are no
+             incompatibilities between versions.  LDAPv2 cannot send a
+             control, hence the above structure cannot be returned to
+             a LDAPv2 client.  A LDAPv3 client cannot send this
+             request to a LDAPv2 server.  A LDAPv3 server not
+             supporting this control cannot return the additional
+             data.
+
+          7.2.3  Client-Server Interaction
+
+             The listSubjectRightsRequest control specifies the rights
+             that MUST be returned for the scope of the search.  The
+             server that consumes the search operation looks up the
+
+
+
+          Stokes, Byrne, Blakley  Expires 15 October 1999        [Page 18]
+\f
+
+
+
+
+          Internet-Draft      Access Control Model       15 April 1999
+
+
+
+             rights for the returned directory information and returns
+             the result as search information associated with the
+             scope of that search.
+
+             There are six possible scenarios that may occur as a
+             result of the listSubjectRights control being included on
+             the search request:
+
+
+               1.  If the server does not support this control and the
+                   client specified TRUE for the control's criticality
+                   field, then the server MUST return
+                   unavailableCriticalExtension as a return code in
+                   the searchResponse message and not send back any
+                   other results.  This behavior is specified in
+                   section 4.1.12 of [LDAPv3].
+
+               2.  If the server does not support this control and the
+                   client specified FALSE for the control's
+                   criticality field, then the server MUST ignore the
+                   control and process the request as if it were not
+                   present.  This behavior is specified in section
+                   4.1.12 of [LDAPv3].
+
+               3.  If the server supports this control but for some
+                   reason such as cannot process specified
+                   rightsFamily and the client specified TRUE for the
+                   control's criticality field, then the server SHOULD
+                   do the following: return
+                   unavailableCriticalExtension as a return code in
+                   the searchResult message and omit the
+                   listSubjectRightsResponse control in the
+                   searchResult message.
+
+               4.  If the server supports this control but for some
+                   reason such as cannot process specified
+                   rightsFamily and the client specified FALSE for the
+                   control's criticality field, then the server should
+                   process as 'no rights returned for that family' and
+                   include the result Unavailable in the
+                   listSubjectRightsResponse control in the
+                   searchResult message.
+
+               5.  If the server supports this control and can return
+                   the rights per the rightsFamily information, then
+
+
+
+          Stokes, Byrne, Blakley  Expires 15 October 1999        [Page 19]
+\f
+
+
+
+
+          Internet-Draft      Access Control Model       15 April 1999
+
+
+
+                   it should include the listSubjectRightsResponse
+                   control in the searchResult message with a result
+                   of success.
+
+               6.  If the search request failed for any other reason,
+                   then the server SHOULD omit the
+                   listSubjectRightsResponse control from the
+                   searchResult message.
+
+             The client application is assured that the correct rights
+             are returned for the scope of the search operation if and
+             only if the listSubjectRightsResponse control returns the
+             rights.  If the server omits the
+             listSubjectRightsResponse control from the searchResponse
+             message, the client SHOULD assume that the control was
+             ignored by the server.
+
+             The listSubjectRightsResponse control, if included by the
+             server in the searchResponse message, should have the
+             searchResult set to either success if the rights were
+             returned or set to the appropriate error code as to why
+             the rights could not be returned.
+
+             The server may not be able to return a right because it
+             may not exist in that directory object's attribute; in
+             this case, the rights request is ignored with success.
+
+          7.3  specifyCredentials Control
+
+
+          7.3.1  Request Control
+
+             This control is included in  the ldap_bind  message as
+             part of the controls  field  of the  LDAPMessage, as
+             defined in  Section  4.1.12 of [LDAPv3].
+
+             The controlType is set to <OID to be assigned>. The
+             criticality MAY be either TRUE or FALSE (where absent is
+             also equivalent to FALSE) at the client's option.  The
+             controlValue is an OCTET STRING, whose value is the BER
+             encoding of a value of the following SEQUENCE:
+
+              specifyCredentialRequest ::= SEQUENCE {
+                   credential  LDAPString
+                               }
+
+
+
+          Stokes, Byrne, Blakley  Expires 15 October 1999        [Page 20]
+\f
+
+
+
+
+          Internet-Draft      Access Control Model       15 April 1999
+
+
+
+              }
+
+             The credential specifies the credential (e.g. groups,
+             roles, etc) that the client is requesting be associated
+             with the bind DN for access control determination in
+             subsequent ldap operations.  This provides a 'push' model
+             for credentials where the client attempts to 'push' the
+             credential to the server.  The server may process at bind
+             time as follows:
+
+                - server may unconditionally ignore
+
+                - server may unconditionally accept
+
+                - server may define trust model and evaluate of the
+                  trust of each credential
+
+             If this control is not used, it is assumed that the
+             server determines (pulls) the credentials associated with
+             the bind DN when needed in subsequent ldap operations to
+             provide access control.
+
+          7.3.2  Response Control
+
+             This control is included in the ldap_search message as
+             part of the controls field of the LDAPMessage, as defined
+             in Section 4.1.12 of [LDAPv3].
+
+             The controlType is set to <OID to be assigned>. The
+             criticality MAY be either TRUE or FALSE (where absent is
+             also equivalent to FALSE).  The controlValue is an OCTET
+             STRING, whose value is the BER encoding of a value of the
+             following SEQUENCE:
+
+              specifyCredentialsResponse ::= {
+                result  ENUMERATED {
+                   success                       (0),
+                   operationsError               (1),
+                   unavailableCriticalExtension (12),
+                   unavailable                  (52),
+                   unwillingToPerform           (53),
+                   other                        (80)
+                   }
+              }
+
+
+
+
+          Stokes, Byrne, Blakley  Expires 15 October 1999        [Page 21]
+\f
+
+
+
+
+          Internet-Draft      Access Control Model       15 April 1999
+
+
+
+             No data is returned; just the result is returned.
+
+             Although this extends the bind operation, there are no
+             incompatibilities between versions.  LDAPv2 cannot send a
+             control.  A LDAPv3 client cannot send this request to a
+             LDAPv2 server.  A LDAPv3 server not supporting this
+             control cannot return the additional data.
+
+          7.3.3  Client-Server Interaction
+
+             The specifyCredentialsRequest control specifies the
+             credentials that the client was the server to use for
+             access control in subsequent ldap operations.  The server
+             that consumes the bind operation may unconditionally
+             accept, ignore, or evaluate the trust of the specified
+             credentials at bind time and returns only a success or
+             failure response (no data returned).
+
+             There are six possible scenarios that may occur as a
+             result of the specifyCredential control being included on
+             the bind request:
+
+
+               1.  If the server does not support this control and the
+                   client specified TRUE for the control's criticality
+                   field, then the server MUST return
+                   unavailableCriticalExtension as a return code in
+                   the bindResponse message.  This behavior is
+                   specified in section 4.1.12 of [LDAPv3].
+
+               2.  If the server does not support this control and the
+                   client specified FALSE for the control's
+                   criticality field, then the server MUST ignore the
+                   control and process the request as if it were not
+                   present.  This behavior is specified in section
+                   4.1.12 of [LDAPv3].
+
+               3.  If the server supports this control but for some
+                   reason such as cannot process specified credential
+                   (e.g. server decided to evaluate the trust of that
+                   credential and the result is the server not
+                   trusting all the credentials or unconditionally
+                   ignores the credential) and the client specified
+                   TRUE for the control's criticality field, then the
+                   server SHOULD do the following: return
+
+
+
+          Stokes, Byrne, Blakley  Expires 15 October 1999        [Page 22]
+\f
+
+
+
+
+          Internet-Draft      Access Control Model       15 April 1999
+
+
+
+                   unavailableCriticalExtension as a return code in
+                   the bindResult message and omit the
+                   specifyCredentialResponse control in the bindResult
+                   message.
+
+               4.  If the server supports this control but for some
+                   reason such as cannot process specified credential
+                   (e.g. server decided to evaluate the trust of that
+                   credential and the result is the server not
+                   trusting all the credentials or unconditionally
+                   ignores the credential) and the client specified
+                   FALSE for the control's criticality field, then the
+                   server should process as 'credential ignored' and
+                   include the result Unavailable in the
+                   specifyCredentialResponse control in the bindResult
+                   message.
+
+               5.  If the server supports this control and evaulates
+                   the trust of that credential and the result is the
+                   server trusting all the credentials, then it should
+                   include the specifyCredentialResponse control in
+                   the bindResult message with a result of success.
+
+               6.  If the bind request failed for any other reason,
+                   then the server SHOULD omit the
+                   specifyCredentialResponse control from the
+                   bindResult message.
+
+             The client application is assured that the correct
+             credentials are used by the server when specified by the
+             client for subsequent ldap operations if and only if the
+             specifyCredentialResponse is successful.  If the server
+             omits the specifyCredentialResponse control from the
+             searchResponse message, the client SHOULD assume that the
+             control was ignored by the server.
+
+             The specifyCredentialResponse control, if included by the
+             server in the bindResponse message, should have the
+             bindResult set to either success if the credentials were
+             accepted by the server or set to the appropriate error
+             code as to why the credentials were not accepted.
+
+
+
+
+
+
+
+          Stokes, Byrne, Blakley  Expires 15 October 1999        [Page 23]
+\f
+
+
+
+
+          Internet-Draft      Access Control Model       15 April 1999
+
+
+
+          8.  Access Control Extended Operations
+
+             Two extended operations (analogous to the controls) are
+             defined for transmission of access control information.
+             These operations help with the management of access
+             control information independent of manipulating other
+             directory information.  The extended operations are:
+
+                - LDAP Get Effective Rights to obtain the effective
+                  rights for a given directory entry for a given
+                  subject
+
+                - LDAP List Subject Rights to get the access control
+                  information for a given directory entry
+
+          8.1  LDAP Get Effective Rights Operation
+
+             ldapGetEffectiveRightsRequest ::= [APPLICATION 23]
+             SEQUENCE {
+                requestName      [0] <OID to be assigned>,
+                requestValue     [1] OCTET STRING OPTIONAL }
+
+                where
+
+                requestValue ::= SEQUENCE {
+                   targetDN  LDAPDN,
+                   updates   SEQUENCE OF SEQUENCE {
+                               rightsFamily  LDAPOID | "*",
+                               whichObject   ENUMERATED {
+                                               LDAP_ENTRY (1),
+                                               LDAP_SUBTREE (2)
+                                               },
+                               dnType        LDAPOID | "*",
+                               subjectDN     LDAPString,
+                               }
+                   }
+
+
+             The requestName is a dotted-decimal representation of the
+             OBJECT IDENTIFIER corresponding to the request. The
+             requestValue is information in a form defined by that
+             request, encapsulated inside an OCTET STRING.
+
+             The server will respond to this with an LDAPMessage
+             containing the ExtendedResponse which is a rights list.
+
+
+
+          Stokes, Byrne, Blakley  Expires 15 October 1999        [Page 24]
+\f
+
+
+
+
+          Internet-Draft      Access Control Model       15 April 1999
+
+
+
+             ldpGetEffectiveRightsResponse ::= [APPLICATION 24]
+             SEQUENCE {
+                COMPONENTS OF LDAPResult,
+                responseName     [10] <OID to be assigned> OPTIONAL,
+                effectiveRights  [11] OCTET STRING OPTIONAL }
+
+                where
+
+                effectiveRights ::= SEQUENCE OF SEQUENCE {
+                   rightFamily   LDAPOID,
+                   rightsList    ENUMERATED,
+                   whichObject   ENUMERATED {
+                                    LDAP_ENTRY (1),
+                                    LDAP_SUBTREE (2)
+                                    },
+                   subjectDnType LDAPOID,
+                   subjectDN     LDAPSTRING
+                }
+
+             If the server does not recognize the request name, it
+             MUST return only the response fields from LDAPResult,
+             containing the protocolError result code.
+
+          8.2  LDAP List Subject Rights
+
+             ldapListSubjectRightsRequest ::= [APPLICATION 23]
+             SEQUENCE {
+                requestName      [0] <OID to be assigned>,
+                requestValue     [1] OCTET STRING }
+
+                where
+
+                requestValue ::= SEQUENCE {
+                   targetDN  LDAPDN,
+                   updates   SEQUENCE OF SEQUENCE {
+                               rightsFamily  LDAPOID | "*",
+                               whichObject   ENUMERATED {
+                                               LDAP_ENTRY (1),
+                                               LDAP_SUBTREE (2)
+                                               },
+                               dnType        LDAPOID | "*",
+                               listSubjectDN     LDAPString | "*",
+                               }
+                   }
+
+
+
+
+          Stokes, Byrne, Blakley  Expires 15 October 1999        [Page 25]
+\f
+
+
+
+
+          Internet-Draft      Access Control Model       15 April 1999
+
+
+
+             The requestName is a dotted-decimal representation of the
+             OBJECT IDENTIFIER corresponding to the request. The
+             requestValue is information in a form defined by that
+             request, encapsulated inside an OCTET STRING.
+
+             The server will respond to this with an LDAPMessage
+             containing the ExtendedResponse which is a result code.
+
+             ldapListSubjectRightsResponse ::= [APPLICATION 24]
+             SEQUENCE {
+                COMPONENTS OF LDAPResult,
+                responseName      [10] <OID to be assigned> OPTIONAL,
+                subjectRightsList [11] OCTET STRING OPTIONAL }
+
+                where
+
+                subjectRightsList ::= SEQUENCE OF SEQUENCE {
+                               rightFamily   LDAPOID,
+                               whichObject   ENUMERATED {
+                                               LDAP_ENTRY (1),
+                                               LDAP_SUBTREE (2)
+                                               },
+                               subjectDnType        LDAPOID,
+                               subjectDN     LDAPString,
+                               perms         SEQUENCE OF SEQUENCE {
+                                               rightsList ENUMERATED,
+                                               attrs  LDAPSTRING
+                                               }
+                               }
+                }
+
+             If the server does not recognize the request name, it
+             MUST return only the response fields from LDAPResult,
+             containing the protocolError result code.
+
+
+
+          9.  Operational Semantics of Access Control Operations
+
+             The semantics of access control operations described in
+             this document are defined operationally in terms of
+             "histories".  A history is a sequence of actions (x1, x2,
+             ..., xN).
+
+
+
+
+
+          Stokes, Byrne, Blakley  Expires 15 October 1999        [Page 26]
+\f
+
+
+
+
+          Internet-Draft      Access Control Model       15 April 1999
+
+
+
+             We consider five types of actions:
+
+                - LDAP Access Control Policy Update actions:
+                  invocations of the LDAP Update Access Extended
+                  Operation or LDAP Update Access Control.
+
+                - LDAP Access Control Policy Query operations:
+                  invocations of the LDAP Get Effective Access
+                  Extended Operation, LDAP Get Effective Access
+                  Control, LDAP List Subject Rights Extended
+                  Operation, or LDAP List Subject Rights Control.
+
+                - Datastore Access Control Policy Update Actions: any
+                  operation implemented by the server which LDAP is
+                  using as its datastore which changes the access
+                  policy enforced with respect to attempts to access
+                  LDAP directory entries and their attributes.
+
+                - LDAP Access Request operations: invocations of LDAP
+                  entry or attribute access operations (Read, Update,
+                  Search, Compare, etc...).
+
+                - Other operations: anything else, including Datastore
+                  operations which do not change the access policy
+                  enforced by the server.
+
+
+             The semantics of histories are defined as follows:
+
+                - LDAP Update (Replace), LDAP Query
+
+                  The Query will show that the subject has all rights
+                  granted by the Update operation, and no rights not
+                  granted by the Update operation.
+
+                - LDAP Update (Grant), LDAP Query
+
+                  The Query will show that the subject has all rights
+                  granted by the Update operation.  The Query may show
+                  that the subject also has other rights not granted
+                  by the Update operation, depending on the policy in
+                  force before the Update operation.
+
+                - LDAP Update (Deny), LDAP Query
+
+
+
+
+          Stokes, Byrne, Blakley  Expires 15 October 1999        [Page 27]
+\f
+
+
+
+
+          Internet-Draft      Access Control Model       15 April 1999
+
+
+
+                  The Query will show that the subject does not have
+                  any right denied by the Update operation.  The Query
+                  may show that the subject has rights not denied by
+                  the Update operation, depending on the policy in
+                  force before the Update operation.
+
+                - LDAP Update (Replace), LDAP Access Request
+
+                  The Request will succeed if it requires only rights
+                  granted to the requesting subject by the Update
+                  operation.  The Request will fail with an access-
+                  denied exception if it requires any right not
+                  granted by the Update operation.
+
+                - LDAP Update (Grant), LDAP Access Request
+
+                  The Request will succeed if it requires only rights
+                  granted to the requesting subject by the Update
+                  operation.  The Request may succeed if it requires
+                  rights not granted by the Update operation,
+                  depending on the policy in force before the Update
+                  operation.
+
+                - LDAP Update (Deny), LDAP Access Request
+
+                  The Request will fail with an access-denied
+                  exception if it requires any right denied to the
+                  requesting subject by the Update operation.  If the
+                  Request requires only rights which were not denied
+                  by the Update operation, it may succeed, depending
+                  on the policy in force before the Update operation.
+
+                - LDAP Update (Replace), Other, LDAP Query
+
+                  The Query will show that the subject has all rights
+                  granted by the Update operation, and no rights not
+                  granted by the Update operation.
+
+                - LDAP Update (Grant), Other, LDAP Query
+
+                  The Query will show that the subject has all rights
+                  granted by the Update operation.  The Query may show
+                  that the subject also has other rights not granted
+                  by the Update operation, depending on the policy in
+                  force before the Update operation.
+
+
+
+          Stokes, Byrne, Blakley  Expires 15 October 1999        [Page 28]
+\f
+
+
+
+
+          Internet-Draft      Access Control Model       15 April 1999
+
+
+
+                - LDAP Update (Deny), Other, LDAP Query
+
+                  The Query will show that the subject does not have
+                  any right denied by the Update operation.  The Query
+                  may show that the subject has rights not denied by
+                  the Update operation, depending on the policy in
+                  force before the Update operation.
+
+                - LDAP Update (Replace), Other, LDAP Access Request
+
+                  The Request will succeed if it requires only rights
+                  granted to the requesting subject by the Update
+                  operation.  The Request will fail with an access-
+                  denied exception if it requires any right not
+                  granted by the Update operation.
+
+                - LDAP Update (Grant), Other, LDAP Access Request
+
+                  The Request will succeed if it requires only rights
+                  granted to the requesting subject by the Update
+                  operation.  The Request may succeed if it requires
+                  rights not granted by the Update operation,
+                  depending on the policy in force before the Update
+                  operation.
+
+                - LDAP Update (Deny), Other, LDAP Access Request
+
+                  The Request will fail with an access-denied
+                  exception if it requires any right denied to the
+                  requesting subject by the Update operation.  If the
+                  Request requires only rights which were not denied
+                  by the Update operation, it may succeed, depending
+                  on the policy in force before the Update operation.
+
+                - LDAP Update (Replace), Datastore Update, LDAP Query
+
+                  The result of the Query is not defined.
+
+                - LDAP Update (Grant), Datastore Update, LDAP Query
+
+                  The result of the Query is not defined.
+
+                - LDAP Update (Deny), Datastore Update, LDAP Query
+
+                  The result of the Query is not defined.
+
+
+
+          Stokes, Byrne, Blakley  Expires 15 October 1999        [Page 29]
+\f
+
+
+
+
+          Internet-Draft      Access Control Model       15 April 1999
+
+
+
+                - LDAP Update (Replace), Datastore Update, LDAP Access
+                  Request
+
+                  The result of the Access Request is not defined.
+
+                - LDAP Update (Grant), Datastore Update, LDAP Access
+                  Request
+
+                  The result of the Access Request is not defined.
+
+                - LDAP Update (Deny), Datastore Update, LDAP Access
+                  Request
+
+                  The result of the Access Request is not defined.
+
+
+
+          10.  LDIF Syntax for Access Control Information
+
+
+          10.1  LDIF Purpose
+
+             The intent of the LDIF is to design a common interchange
+             format. Any given LDAP server should be able to translate
+             the below defined LDIF into a meaningful request. Each
+             server should be able to understand each part of the
+             LDIF; there should not be any ambiguity into what any
+             part of the syntax means.
+
+             While the end goal is to have a common behavior model
+             between different LDAP server implementations, the LDIF
+             alone will not ensure identical ACL processing behavior
+             between servers.  The semantics of how a server
+             interprets the aci syntax are not defined here. What
+             'deny' means on server1 might be different than on
+             server2.
+
+             The LDIF maintains an assumption that the receiving
+             server supports inheritance within the security model. If
+             the server does not support inheritance, the receiving
+             server must expand any inherited information based on the
+             scope flag.
+
+
+
+
+
+
+          Stokes, Byrne, Blakley  Expires 15 October 1999        [Page 30]
+\f
+
+
+
+
+          Internet-Draft      Access Control Model       15 April 1999
+
+
+
+          10.2  ACL Attributes
+
+             There are three attributes which are allowed on all
+             directory objects:  aci, vendorAci and policyOwner. The
+             syntax of these attributes is defined below. The aci,
+             vendorAci and policyOwner attribute are all multivalued.
+             In determining the order of the syntax, the DN was left
+             until the end for parsing reasons.   Examples follow the
+             BNF
+
+
+          10.2.1  VendorACI_
+
+             The Vendor specific ACI information is listed in its own
+             attribute. The assumption here is that if the vendor's
+             need to provide information in an additional attribute,
+             then the vendor specific information would not
+             necessarily be of the same syntax as the ACI attribute
+             which would have < acl syntax> .
+
+
+          10.2.2  Policy Owner_
+
+             The intent behind policy ownership is that it controls
+             administrative subdomains. It can also control who has
+             permission to set / change acls for implementations that
+             do not have an acl controlling access to itself.   If
+             there are multiple policy owners it is implementation
+             specific as to the behavior of whether policy owner #1
+             can override policy owner # 2.
+
+             The syntax for policyOwner includes the 'scope' flag.
+             Servers which do not support inheritance must expand the
+             policyOwner inheritance similar to the expansion of the
+             ACI.   If the policy owner is not specified for any
+             object in the tree, behavior is implementation defined.
+             For instance, if no object anywhere in the tree has a
+             policy owner, then the server could simply assert that
+             the 'root DN' is considered the policy owner for all
+             objects. An alternate approach might be that the
+             implementation defines the entryDN to be the policy
+             owner.
+
+             The policyOwner and ACI are left as distinct  attributes
+             for several reasons. They syntax of the policy owner is
+
+
+
+          Stokes, Byrne, Blakley  Expires 15 October 1999        [Page 31]
+\f
+
+
+
+
+          Internet-Draft      Access Control Model       15 April 1999
+
+
+
+             very similar to the syntax of the ACI. In parsing, it
+             would be difficult to tell when one stops and the other
+             begins (especially since there are no reserved characters
+             in LDAP Dns ). Additionally, the inheritance models of
+             the administrative subdomains may be different then the
+             models guiding the ACI inheritance. Since there is no
+             flag to tell if a given ACI is explicit vs inherited,
+             combining the two sets of information ties the
+             policyOwner inheritance to ACI inheritance. Additionally,
+             keeping the information separate makes it easier for the
+             applications to construct views of various models by only
+             requesting the information they need.
+
+
+          10.2.3  ACI
+
+             The aci attribute is defined using < acl syntax>. Within
+             the acl syntax, the family OID describes the permissions,
+             dnType, subhectDn and scope that will be found in the
+             following string.  The permissions for the IETF family
+             are found below.  The family OID is listed first in the
+             syntax to be consistent with other LDAP LDIF definitions
+             which list OIDs first.  If the OID within the ACI
+             attribute is listed as other than the IETF family oid,
+             the syntax is the same as l isted below, but one or more
+             of the scope, dnType, subjectDn or permissions may vary
+             from the IETF defined syntax.
+
+             Within the acl syntax, there is a string which describes
+             the rights. This is a composite of the permissions and
+             resources to which the user is being granted or denied
+             access. The set of permissions is fixed. Either of the
+             actions "grant" | "deny"  may be used when creating or
+             updating an aci.
+
+             Using the BNF defined below, it is possible for the
+             permission string to be empty. The aci
+
+              aci:
+             1.2.3.4#subtree#grant;;attribute1$grant;r,s;[all]#group#cn=Dept
+             XYZ, c=US
+
+             mean that this group is granted permission to read and
+             search all attributes except  attribute1.
+
+
+
+
+          Stokes, Byrne, Blakley  Expires 15 October 1999        [Page 32]
+\f
+
+
+
+
+          Internet-Draft      Access Control Model       15 April 1999
+
+
+
+             Similarly, the aci
+
+              aci:  1.2.3.4#subtree#group#cn=Dept XYZ, c=US simply
+             means that no permissions have been defined for this
+             group. It is up to the server implementation as to
+             whether the group does or does not receive permission to
+             attributes on an entry with an empty rights list.
+
+             The attributeString is an attribute Name (defined to be a
+             printable string).  If the string refers to an attribute
+             not defined in the given server's schema, the server
+             SHOULD report an error.   Another option for the
+             attributeString is "[entry]". This is provided to
+             describe permissions which apply to an entire object.
+             This could mean actions such as delete the object, or add
+             a child object. The third option for attributeString is
+             "[all]" which means the permission set should apply to
+             all attributes.
+
+             If the keyword "[all]"  and another attribute are both
+             specified within an aci, the more specific permission set
+             for the attribute overrides the less specific permission
+             set for "[all]".   If two acis contain identical
+             familyOID, scope, DnTypes and DNs, the permission given
+             DN is specified in two distinct acis on any given entry,
+             the rights lists can be combined into one list. For
+             example:
+
+              aci: 1.2.3.4#subtree#group#grant;r,w;[all]#cn=Dept XYZ
+              aci: 1.2.3.4#subtree#group#grant;r;attribute1#cn=Dept
+             XYZ
+
+             is the equivalent of
+
+              aci:
+             1.2.3.4#subtree#group#grant;r,w;[all];r,attribute1#cn=Dept
+             XYZ
+
+             Multiple attributeStrings can be listed after any given
+             permission set; for instance, "r,w ; attribute1,
+             attribute2". This means that if the server supports a
+             attribute aggregation mechanism, attribute1 and
+             attribute2 should be considered to be part of the same
+             group. If the server does not support a grouping
+             mechanism, the permission set applies independently to
+
+
+
+          Stokes, Byrne, Blakley  Expires 15 October 1999        [Page 33]
+\f
+
+
+
+
+          Internet-Draft      Access Control Model       15 April 1999
+
+
+
+             attribute1 and attribute2. For servers that do not
+             support attribute grouping, "r,w ; attribute1,
+             attribute2" results in the same operations as " r,w;
+             attribute1; r,w; attribute2 "
+
+             Within the vendorACI, the oid determines the format or
+             the printable string to follow.
+
+
+          10.3  Modifying the ACI Values
+
+             The attribute: value pairs listed below would be possible
+             inputs for normal LDAP operations such as ldapadd and
+             ldapmodify.  Within the ldapmodify command there are
+             three changetypes: add, delete, replace.
+
+             Replace works similarly to all other attributes. If the
+             attribute value does not exist, create the value. If the
+             attribute does exist, replace the value.  If the aci
+             value is replaced, all aci values are replaced.  Given an
+             aci for an entry:
+
+              aci:
+             1.2.3.4#subtree#deny;r,w;[all];grant;rsc;attirbute2#group#cn=Dept
+             ABC
+              aci:
+             1.2.3.4#subtree#grant;r,;[all];grant;rsc;attirbute1#group#cn=Dept
+             XYZ
+
+             perform the following change:
+
+              dn: cn=someEntry
+              changetype: replace
+              add: aci
+              aci: 1.2.3.4#subtree#grant;r,w;[all];#group#cn=Dept LMN
+
+             The resulting acl is:
+
+              aci: 1.2.3.4#subtree#grant;r,w;[all];#group#cn=Dept LMN
+
+             (aci values for Dept XYZ and ABC are lost through the
+             replace)
+
+             During an ldapmodify-add, if the aci does not exist, the
+             create the aci with the specific aci value(s).  If the
+
+
+
+          Stokes, Byrne, Blakley  Expires 15 October 1999        [Page 34]
+\f
+
+
+
+
+          Internet-Draft      Access Control Model       15 April 1999
+
+
+
+             aci does exist, then add the specified values to the
+             given aci.  For example a given aci:
+
+               aci: 1.2.3.4#subtree#group#grant;r,w;[all]#cn=Dept XYZ
+
+              with a modification:
+               dn: cn=someEntry
+               changetype: add
+               add: aci
+               aci: 1.2.3.4#subtree#group#grant;r;attribute1#cn=Dept
+             XYZ
+
+             would yield an aci value of:
+
+              aci:
+             1.2.3.4#subtree#group#grant;r,w;[all];r,attribute1#cn=Dept
+             XYZ
+
+             To delete an entire acl, use ldapmodify - delete without
+             specifying a value for the aci. The entry would then
+             inherit its aci from some other node in the tree
+             depending on the server inheritance model.
+
+              dn: cn = some Entry
+              changetype: delete
+              delete: aci
+
+             During an ldapmodify-delete, there are two possible
+             interpretations of the delete.
+
+              dn: cn = some Entry
+              changetype: delete
+              delete: aci
+              aci: < >  (see below)
+
+             Interpretation 1.
+
+                aci: 1.2.3.4#subtree#group#cn=Dept XYZ
+              would delete the entire aci for the group cn=Dept XYZ
+
+             Interpretation 2.
+
+                aci:
+             1.2.3.4#subtree#grant;rsc;attribute1#group#cn=Dept XYZ
+              would delete the 'grant;rsc;attribute1' portion of the
+
+
+
+          Stokes, Byrne, Blakley  Expires 15 October 1999        [Page 35]
+\f
+
+
+
+
+          Internet-Draft      Access Control Model       15 April 1999
+
+
+
+             aci
+              for the group cn=Dept XYZ
+
+              before ldapmodify - delete:
+                aci:
+             1.2.3.4#subtree#group#grant;r,w;[all];grant;rsc;attribute1#cn=Dept
+             XYZ
+
+              after ldapmodify - delete of attribute1
+                aci: 1.2.3.4#subtree#group#grant;r,w;[all];#cn=Dept
+             XYZ
+
+              if the delete is for an attribute not existing within
+             the aci, nothing
+              is changed in the expected outcome. For example, if now
+             attribute2
+              is deleted,
+
+                aci: 1.2.3.4#subtree#grant;[attribute2]#group#cn=Dept
+             XYZ
+
+              the resulting aci would still be
+
+                aci: 1.2.3.4#subtree#group#grant;r,w;[all];#cn=Dept
+             XYZ
+
+
+          10.4  BNF
+
+              <aci> ::= <acl syntax>
+              <vendorAci > ::=  <oid> + '#' + <printable string>
+
+              <acl syntax> ::= <familyOID> + '#' + <scope> + '#' +
+                       <rights> + '#' + <dnType> + '#' + <subjectDn>
+
+              <policyOwner> ::= <familyOid> + '#' + <scope> + '#' +
+                                  <dnType> + '#' + <subjectDn>
+
+              <subjectDn> ::= <printable string>
+              <familyOid> ::= < oid >
+
+              <scope> ::     "entry"  | "subtree"
+
+              <dnType> :: "access-id" | "role" | "group"
+              <rights> ::= [  ] | [ < right > + [ '$' + <right> ] * ]
+
+
+
+          Stokes, Byrne, Blakley  Expires 15 October 1999        [Page 36]
+\f
+
+
+
+
+          Internet-Draft      Access Control Model       15 April 1999
+
+
+
+              <right> ::= <action> + ';' + <permissions> +
+                            ';' +  <attrs>
+
+              <action> ::= "grant" | "deny"
+
+              <permissions> ::= [  ] | [ < permission > +
+                                  [ ',' + <permission> ] *  ]
+              <attrs > ::= [ <attributeString> +
+                            [  ',' + <attributeString > ] * ]
+
+              <attributeString>  ::= "[all]" | "[entry]" |
+                                       <printableString>
+
+              <permission> : "a" | "d" | "r" | "s" | "w" | "c"
+                                 | "g" | "s" | "m" | "u"
+                             These are the permissions defined for
+                         the IETF family OID.
+
+
+          10.5  Examples
+
+             Suppose IETFFamilyOID = 1.2.3.4
+
+             The following two examples show an administrative
+             subdomain being established. The first example shows a
+             single user being assigned the policyOwner for the entire
+             domain. The second example shows a group of ids assigned
+             to the policy Owner.
+
+              policyOwner:  1.2.3.4#subtree#access-id#cn=Hoyt
+
+              policyOwner:  1.2.3.4#subtree#group#cn=System Owners,
+             o=Company
+
+             The next example shows an aci attribute where a group
+             "cn=Dept XYZ, c=US"  is being given permissions to read,
+             search and compare attribute1. The permission should
+             apply to the entire subtree below the node containing
+             this aci.
+
+             aci: 1.2.3.4#subtree#group#grant;r,s,c;attribute1#cn=Dept
+             XYZ, c=US
+
+             The next example shows an ACI attribute where a role
+             "cn=SysAdmins,o=Company"  is being given permissions to
+
+
+
+          Stokes, Byrne, Blakley  Expires 15 October 1999        [Page 37]
+\f
+
+
+
+
+          Internet-Draft      Access Control Model       15 April 1999
+
+
+
+             add objects below this node, and read, search and compare
+             attributes2 and 3. The permission should apply to the
+             entire subtree below the node containing this ACI.
+
+             aci:
+             1.2.3.4#subtree#role#grant;a;[entry]$grant;r,s,c;attribute2,attribute3#cn=SysAdmins,o=Company
+
+
+
+          11.  Security Considerations
+
+             This draft proposes protocol elements for transmission of
+             security policy information.  Security considerations are
+             discussed throughout this draft.  Because subject
+             security attribute information is used to evaluate
+             decision requests, it is security-sensitive information
+             and must be protected against unauthorized modification
+             whenever it is stored or transmitted.
+
+
+
+          12.  References
+
+             [LDAPv3] M. Wahl, T. Howes, S. Kille, "Lightweight
+             Directory Access Protocol (v3)", RFC 2251, December 1997.
+
+             [ECMA] ECMA, "Security in Open Systems: A Security
+             Framework" ECMA TR/46, July 1988
+
+             [REQTS] Stokes, Byrne, Blakley, "Access Control
+             Requirements for LDAP, INTERNET-DRAFT <draft-ietf-
+             ldapext-acl-reqts-01.txt>, August 1998.
+
+             [ATTR] M.Wahl, A, Coulbeck, T. Howes, S. Kille,
+             "Lightweight Directory Access Protocol (v3)": Attribute
+             Syntax Definitions, RFC 2252, December 1997.
+
+             [UTF] M. Wahl, S. Kille, "Lightweight Directory Access
+             Protocol (v3)": A UTF-8 String Representation of
+             Distinguished Names", RFC 2253, December 1997.
+
+             [Bradner97] Bradner, Scott, "Key Words for use in RFCs to
+             Indicate Requirement Levels", RFC 2119.
+
+
+
+
+
+          Stokes, Byrne, Blakley  Expires 15 October 1999        [Page 38]
+\f
+
+
+
+
+          Internet-Draft      Access Control Model       15 April 1999
+
+
+
+          AUTHOR(S) ADDRESS
+
+              Ellen Stokes                       Bob Blakley
+              IBM                                Dascom
+              11400 Burnet Rd
+              Austin, TX 78758                   Austin, TX
+              USA                                USA
+              mail-to: stokes@austin.ibm.com     mail-to: blakley@dascom.com
+              phone: +1 512 838 3725
+              fax:   +1 512 838 8597
+
+
+              Debbie Byrne
+              IBM
+              11400 Burnet Rd
+              Austin, TX 78758
+              USA
+              mail-to: djbyrne@us.ibm.com
+              phone: +1 512 838 1960
+              fax:   +1 512 838 0156
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+          Stokes, Byrne, Blakley  Expires 15 October 1999        [Page 39]
+\f
+
+
+
+
+          Internet-Draft      Access Control Model       15 April 1999
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+          Stokes, Byrne, Blakley  Expires 15 October 1999        [Page 40]
+\f
+
+
+
+
+
+
+
+
+                                    CONTENTS
+
+
+           1.  Introduction.......................................   2
+
+           2.  Overview...........................................   2
+
+           3.  Terminology........................................   3
+
+           4.  The Model..........................................   6
+               4.1   Access Control Activity Lifecycle............   6
+               4.2   Access Control Information Model.............   6
+               4.3   Bind and Credentials.........................   8
+
+           5.  Access Control Information Schema..................   8
+               5.1   Attributes...................................   8
+                     5.1.1   Root DSE Attribute for Access
+                             Control Mechanism   8
+                     5.1.2   Subschema Attribute for Access
+                             Control Mechanism   9
+               5.2   Other Defined Parameters/OIDs................   9
+                     5.2.1   Rights Families and Rights   9
+                     5.2.2   DN Types  10
+
+           6.  Access Control Parameters for LDAP Controls &
+               Extended Operations................................  10
+
+           7.  Access Control Information (ACI) Controls..........  12
+               7.1   getEffectiveRights Control...................  13
+                     7.1.1   Request Control  13
+                     7.1.2   Response Control  13
+                     7.1.3   Client-Server Interaction  15
+               7.2   listSubjectRights Control....................  16
+                     7.2.1   Request Control  16
+                     7.2.2   Response Control  17
+                     7.2.3   Client-Server Interaction  18
+               7.3   specifyCredentials Control...................  20
+                     7.3.1   Request Control  20
+                     7.3.2   Response Control  21
+                     7.3.3   Client-Server Interaction  22
+
+           8.  Access Control Extended Operations.................  24
+               8.1   LDAP Get Effective Rights Operation..........  24
+               8.2   LDAP List Subject Rights.....................  25
+
+
+
+
+                                     - i -
+
+
+
+
+
+
+
+
+
+
+
+           9.  Operational Semantics of Access Control
+               Operations.........................................  26
+
+          10.  LDIF Syntax for Access Control Information.........  30
+               10.1  LDIF Purpose.................................  30
+               10.2  ACL Attributes...............................  31
+                     10.2.1  VendorACI   31
+                     10.2.2  Policy Owner   31
+                     10.2.3  ACI  32
+               10.3  Modifying the ACI Values.....................  34
+               10.4  BNF..........................................  36
+               10.5  Examples.....................................  37
+
+          11.  Security Considerations............................  38
+
+          12.  References.........................................  38
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+                                     - ii -
+
+
+
+
diff --git a/doc/drafts/draft-ietf-ldapext-ldap-c-api-02.txt b/doc/drafts/draft-ietf-ldapext-ldap-c-api-02.txt
new file mode 100644 (file)
index 0000000..0ed82cf
--- /dev/null
@@ -0,0 +1,4315 @@
+
+
+
+
+
+
+Network Working Group                                   M. Smith, Editor
+INTERNET-DRAFT                             Netscape Communications Corp.
+Intended Category: Standards Track                              T. Howes
+Obsoletes: RFC 1823                        Netscape Communications Corp.
+Expires: 23 August 1999                                        A. Herron
+                                                         Microsoft Corp.
+                                                                 M. Wahl
+                                            Innosoft International, Inc.
+                                                              A. Anantha
+                                                         Microsoft Corp.
+
+
+                                                        23 February 1999
+
+                The C LDAP Application Program Interface
+                 <draft-ietf-ldapext-ldap-c-api-02.txt>
+
+
+1.  Status of this Memo
+
+This document is an Internet-Draft and is in full conformance with all
+provisions of Section 10 of RFC2026.  Internet-Drafts are working docu-
+ments of the Internet Engineering Task Force (IETF), its areas, and its
+working groups.  Note that other groups may also distribute working
+documents as Internet-Drafts.
+
+Internet-Drafts are draft documents valid for a maximum of six months
+and may be updated, replaced, or obsoleted by other documents at any
+time.  It is inappropriate to use Internet-Drafts as reference material
+or to cite them other than as "work in progress."
+
+The list of current Internet-Drafts can be accessed at
+http://www.ietf.org/ietf/1id-abstracts.txt.
+
+The list of Internet-Draft Shadow Directories can be accessed at
+http://www.ietf.org/shadow.html.
+
+This draft document will be submitted to the RFC Editor as a Standards
+Track document. Distribution of this memo is unlimited.  Technical dis-
+cussion of this document will take place on the IETF LDAP Extension
+Working Group mailing list <ietf-ldapext@netscape.com>.  Please send
+editorial comments directly to the authors.
+
+Copyright (C) The Internet Society (1997-1999). All Rights Reserved.
+
+Please see the Copyright section near the end of this document for more
+information.
+
+
+
+
+Expires: 23 August 1999                                         [Page 1]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+2.  Introduction
+
+This document defines a C language application program interface (API)
+to the Lightweight Directory Access Protocol (LDAP). This document
+replaces the previous definition of this API, defined in RFC 1823,
+updating it to include support for features found in version 3 of the
+LDAP protocol.  New extended operation functions were added to support
+LDAPv3 features such as controls.  In addition, other LDAP API changes
+were made to support information hiding and thread safety.
+
+The C 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 applica-
+tion program to obtain LDAP information.  The API calls are described in
+detail, followed by appendices that provide example code demonstrating
+use of the API, the namespace consumed by the API, a summary of require-
+ments for API extensions, known incompatibilities with RFC 1823, and a
+list of changes made since the last revision of this document.
+
+
+3.  Table of Contents
+
+1.     Status of this Memo............................................1
+2.     Introduction...................................................2
+3.     Table of Contents..............................................2
+4.     Overview of the LDAP Model.....................................4
+5.     Overview of LDAP API Use.......................................4
+6.     Header File Requirements.......................................6
+7.     Common Data Structures.........................................7
+8.     Retrieving Information About the API Implementation............8
+8.1.      Retrieving Information at Compile Time......................8
+8.2.      Retrieving Information During Execution.....................10
+9.     LDAP Error Codes...............................................13
+10.    Performing LDAP Operations.....................................14
+10.1.     Initializing an LDAP Session................................14
+10.2.     LDAP Session Handle Options.................................15
+10.3.     Working With Controls.......................................21
+10.3.1.      A Client Control That Governs Referral Processing........22
+10.4.     Authenticating to the directory.............................22
+10.5.     Closing the session.........................................25
+10.6.     Searching...................................................26
+10.7.     Reading an Entry............................................30
+10.8.     Listing the Children of an Entry............................30
+10.9.     Comparing a Value Against an Entry..........................30
+10.10.    Modifying an entry..........................................32
+10.11.    Modifying the Name of an Entry..............................34
+10.12.    Adding an entry.............................................36
+
+
+
+Expires: 23 August 1999                                         [Page 2]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+10.13.    Deleting an entry...........................................38
+10.14.    Extended Operations.........................................40
+11.    Abandoning An Operation........................................41
+12.    Obtaining Results and Peeking Inside LDAP Messages.............42
+13.    Handling Errors and Parsing Results............................44
+14.    Stepping Through a List of Results.............................47
+15.    Parsing Search Results.........................................48
+15.1.     Stepping Through a List of Entries or References............48
+15.2.     Stepping Through the Attributes of an Entry.................49
+15.3.     Retrieving the Values of an Attribute.......................50
+15.4.     Retrieving the name of an entry.............................51
+15.5.     Retrieving controls from an entry...........................52
+15.6.     Parsing References..........................................53
+16.    Encoded ASN.1 Value Manipulation...............................54
+16.1.     General.....................................................54
+16.2.     Encoding....................................................55
+16.3.     Encoding Example............................................58
+16.4.     Decoding....................................................59
+16.5.     Decoding Example............................................61
+17.    Security Considerations........................................64
+18.    Acknowledgements...............................................64
+19.    Copyright......................................................64
+20.    Bibliography...................................................65
+21.    Authors' Addresses.............................................66
+22.    Appendix A - Sample C LDAP API Code............................67
+23.    Appendix B - Namespace Consumed By This Specification..........68
+24.    Appendix C - Summary of Requirements for API Extensions........69
+24.1.     Compatibility...............................................69
+24.2.     Style.......................................................69
+24.3.     Dependence on Externally Defined Types......................69
+24.4.     Compile Time Information....................................69
+24.5.     Runtime Information.........................................70
+24.6.     Values Used for Session Handle Options......................70
+25.    Appendix D - Known Incompatibilities with RFC 1823.............70
+25.1.     Opaque LDAP Structure.......................................70
+25.2.     Additional Error Codes......................................70
+25.3.     Freeing of String Data with ldap_memfree()..................71
+25.4.     Changes to ldap_result()....................................71
+25.5.     Changes to ldap_first_attribute() and ldap_next_attribute...71
+25.6.     Changes to ldap_modrdn() and ldap_modrdn_s() Functions......71
+25.7.     API Specification Clarified.................................72
+25.8.     Deprecated Functions........................................72
+26.    Appendix E - Changes Made Since Last Document Revision.........72
+26.1.     API Changes.................................................73
+26.2.     Editorial changes...........................................74
+
+
+
+
+
+
+Expires: 23 August 1999                                         [Page 3]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+4.  Overview of the LDAP Model
+
+LDAP is the lightweight directory access protocol, described in [2] and
+[6]. 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.
+
+The LDAP information model is based on the entry, which contains infor-
+mation 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 attri-
+bute (e.g., ASCII characters, a jpeg photograph, etc.) and how those
+values behave during directory operations (e.g., is case significant
+during comparisons).
+
+Entries may be organized in a tree structure, usually based on politi-
+cal, 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 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 entry up
+to the root of the tree. 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].
+
+Operations are provided to authenticate, search for and retrieve infor-
+mation, 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 func-
+tions.
+
+
+5.  Overview of LDAP API Use
+
+An application generally uses the C LDAP API in four simple steps.
+
+   1.   Initialize an LDAP session with a primary LDAP server. The
+        ldap_init() function returns a handle to the session, allowing
+        multiple connections to be open at once.
+
+   2.   Authenticate to the LDAP server. The ldap_sasl_bind() function
+        and friends support a variety of authentication methods.
+
+
+
+Expires: 23 August 1999                                         [Page 4]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+   3.   Perform some LDAP operations and obtain some results.
+        ldap_search() and friends return results which can be parsed by
+        ldap_parse_result(), ldap_first_entry(), ldap_next_entry(), etc.
+
+   4.   Close the session. The ldap_unbind() function closes the connec-
+        tion.
+
+Operations can be performed either synchronously or asynchronously.  The
+names of the synchronous functions 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 rou-
+tines return an indication of the outcome of the operation (e.g, the
+constant LDAP_SUCCESS or some other error code).  The asynchronous rou-
+tines make available to the caller the message id of the operation ini-
+tiated. 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() or ldap_abandon_ext().
+
+Results and errors are returned in an opaque structure called LDAPMes-
+sage.  Routines are provided to parse this structure, step through
+entries and attributes returned, etc. Routines are also provided to
+interpret errors. Later sections of this document describe these rou-
+tines in more detail.
+
+LDAP version 3 servers may return referrals and references to other
+servers.  By default, implementations of this API will attempt to follow
+referrals automatically for the application.  This behavior can be dis-
+abled globally (using the ldap_set_option() call) or on a per-request
+basis through the use of a client control.
+
+All DN and string attribute values passed into or produced by this C
+LDAP API are represented using the character set of the underlying LDAP
+protocol version in use.  When this API is used with LDAPv3, DN and
+string values are represented as UTF-8[10] characters.  When this API is
+used with LDAPv2, the US-ASCII[12] or T.61[12] character set are used.
+Future documents may specific additional APIs supporting other character
+sets.
+
+For compatibility with existing applications, implementations of this
+API will by default use version 2 of the LDAP protocol.  Applications
+that intend to take advantage of LDAP version 3 features will need to
+use the ldap_set_option() call with a LDAP_OPT_PROTOCOL_VERSION to
+switch to version 3.
+
+Note that this API is designed for use in environments where the 'int'
+type is at least 32 bits in size.
+
+
+
+
+
+Expires: 23 August 1999                                         [Page 5]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+6.  Header File Requirements
+
+To promote portability of applications, implementations of this C LDAP
+API must conform to the following requirements of the header files used
+by applications to access the services of this API:
+
+Name and Inclusion
+        Applications are only required to include a single header file
+        named ldap.h to access all of the API services described in this
+        document.  Therefore, the following C source program must com-
+        pile without errors:
+
+           #include <ldap.h>
+
+           int
+           main()
+           {
+               return 0;
+           }
+
+        Note that it is permissible for the ldap.h header file to
+        include other implementation-specific header files.
+
+Implementations SHOULD also provide a header file named lber.h to faci-
+late development of applications desiring compatibility with older LDAP
+implementations.  The lber.h header file may be empty.
+
+
+Idempotence
+        All header files should be idempotent; that is, if they are
+        included more than once the effect is as if they had only been
+        included once.
+
+Must Be Included Before API Is Used
+        An application must include the ldap.h header file before
+        referencing any of the function or type definitions described in
+        this API specification.
+
+Mutual Independence
+        If possible, header files should be mutually independent with
+        minimal dependence on system or any other header files.
+
+Use of the 'const' Keyword
+        This API specification is defined in terms of ISO C[13].  It
+        makes use of function prototypes and the 'const' keyword.  The
+        use of 'const' in this specification is limited to simple, non-
+        array function parameters to avoid forcing applications to
+        declare parameters and variables that accept return values from
+
+
+
+Expires: 23 August 1999                                         [Page 6]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+        LDAP API functions as 'const.'  Implementations specifically
+        designed to be used with non-ISO C translators may provide func-
+        tion declarations without prototypes or function prototypes
+        without specification of 'const' arguments.
+
+Definition of 'struct timeval'
+        This API specification uses the 'struct timeval' type.  Imple-
+        mentations of this API should ensure that the struct timeval
+        type is by default defined as a consequence of including the
+        ldap.h header file.  Because struct timeval is usually defined
+        in one or more system header files, it is possible for header
+        file conflicts to occur if ldap.h also defines it or arranges
+        for it to be defined by including another header file.  There-
+        fore, applications may want to arrange for struct timeval to be
+        defined before they include ldap.h.  To support this, the ldap.h
+        header file must not itself define struct timeval if the prepro-
+        cessor symbol LDAP_TYPE_TIMEVAL_DEFINED is defined before ldap.h
+        is included.
+
+
+7.  Common Data Structures
+
+Some data structures that are common to several LDAP API functions are
+defined here:
+
+           typedef struct ldap LDAP;
+
+           typedef struct ldapmsg LDAPMessage;
+
+           typedef struct berelement BerElement;
+
+           struct berval {
+                   unsigned long   bv_len;
+                   char            *bv_val;
+           };
+
+           struct timeval {
+                   long            tv_sec;
+                   long            tv_usec;
+           };
+
+The LDAP structure is an opaque data type that represents an LDAP ses-
+sion Typically this corresponds to a connection to a single server, but
+it may encompass several server connections in the face of LDAPv3 refer-
+rals.
+
+The LDAPMessage structure is an opaque data type that is used to return
+entry, reference, result, and error information.  An LDAPMessage
+
+
+
+Expires: 23 August 1999                                         [Page 7]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+structure may represent the beginning of a list, or chain of messages
+that consists of a series of entries, references, and result messages as
+returned by LDAP operations such as search.  LDAP API functions such as
+ldap_parse_result() that operate on message chains that may contain more
+than one result message always operate on the first result message in
+the chain.  See the "Obtaining Results and Peeking Inside LDAP Messages"
+section of this document for more information.
+
+The BerElement structure is an opaque data type that is used to hold
+data and state information about encoded data.  It is described in more
+detail in the section "Encoded ASN.1 Value Manipulation" later in this
+document.
+
+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.
+
+See the earlier section "Header File Requirements" for more information
+on struct timeval.
+
+
+8.  Retrieving Information About the API Implementation
+
+Applications developed to this specification need to be able to deter-
+mine information about the particular API implementation they are using
+both at compile time and during execution.
+
+
+8.1.  Retrieving Information at Compile Time
+
+All conformant implementations MUST include the following five defini-
+tions in a header file so compile time tests can be done by LDAP
+software developers:
+
+   #define LDAP_API_VERSION     level
+   #define LDAP_VERSION_MIN     min-version
+   #define LDAP_VERSION_MAX     max-version
+
+
+
+Expires: 23 August 1999                                         [Page 8]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+   #define LDAP_VENDOR_NAME     "vend-name"
+   #define LDAP_VENDOR_VERSION  vend-version
+
+where:
+
+     "level" is replaced with the RFC number given to this C LDAP API
+     specification when it is published as a standards track RFC.
+
+     min-version is replaced with the lowest LDAP protocol version sup-
+     ported by the implementation.
+
+     max-version is replaced with the highest LDAP protocol version sup-
+     ported by the implementation.  This should be 3.
+
+     "vend-name" is replaced with a text string that identifies the
+     party that supplies the API implementation.
+
+     "vend-version" is a supplier-specific version number multiplied
+     times 100.
+
+Note that the LDAP_VENDOR_NAME macro may be defined as "" if no vendor
+name is available and the LDAP_VENDOR_VERSION macro may be defined as 0
+if no vendor-specific version information is available.
+
+For example, if this specification is published as RFC 88888, Netscape
+Communication's version 4.0 implementation that supports LDAPv2 and v3
+might include macro definitions like these:
+
+   #define LDAP_API_VERSION     88888      /* RFC 88888 compliant */
+   #define LDAP_VERSION_MIN     2
+   #define LDAP_VERSION_MAX     3
+   #define LDAP_VENDOR_NAME     "Netscape Communications Corp."
+   #define LDAP_VENDOR_VERSION  400        /* version 4.0 */
+
+and application code can test the C LDAP API version level using a
+construct such as this one:
+
+   #if (LDAP_API_VERSION >= 88888)
+           /* use features supported in RFC 88888 or later */
+   #endif
+
+Until such time as this document is published as an RFC, implementations
+should use the value 2000 plus the revision number of this draft for
+LDAP_API_VERSION.  For example, the correct value for LDAP_API_VERSION
+for revision 03 of this draft is 2003.
+
+Documents that extend this specification SHOULD define a macro of the
+form:
+
+
+
+Expires: 23 August 1999                                         [Page 9]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+   #define LDAP_API_FEATURE_x level
+
+where "x" is replaced with a name (textual identifier) for the feature
+and "level" is replaced with the number of the RFC that specifies the
+API extension.  The name SHOULD NOT begin with the string "X_".
+
+For example, if C LDAP API extensions for Transport Layer Security [9]
+were published in RFC 99999, that RFC might require conformant implemen-
+tations to define a macro like this:
+
+   #define LDAP_API_FEATURE_TLS 99999
+
+
+Private or experimental API extensions may be indicated by defining a
+macro of this same form where "x" (the extension's name) begins with the
+string "X_" and "level" is replaced with a integer number that is
+specific to the extension.
+
+
+8.2.  Retrieving Information During Execution
+
+The ldap_get_option() call (described in greater detail later in this
+document) can be used during execution in conjunction with an option
+parameter value of LDAP_OPT_API_INFO (0x00) to retrieve some basic
+information about the API and about the specific implementation being
+used.  The ld parameter to ldap_get_option() can be either NULL or a
+valid LDAP session handle which was obtained by calling ldap_init().
+The optdata parameter to ldap_get_option() MUST be the address of an
+LDAPAPIInfo structure which is defined as follows:
+
+   typedef struct ldapapiinfo {
+       int  ldapai_info_version;     /* version of this struct (1) */
+       int  ldapai_api_version;      /* revision of API supported */
+       int  ldapai_protocol_version; /* highest LDAP version supported */
+       char **ldapai_extensions;     /* names of API extensions */
+       char *ldapai_vendor_name;     /* name of supplier */
+       int  ldapai_vendor_version;   /* supplier-specific version times 100 */
+   } LDAPAPIInfo;
+
+In addition, API implementations MUST include the following macro defin-
+ition:
+
+   #define LDAP_API_INFO_VERSION    1
+
+Note that the ldapai_info_version field of the LDAPAPIInfo structure
+should be set to the value LDAP_API_INFO_VERSION (1) before calling
+ldap_get_option() so that it can be checked for consistency.  All other
+fields are set by the ldap_get_option() function.
+
+
+
+Expires: 23 August 1999                                        [Page 10]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+The members of the LDAPAPIInfo structure are:
+
+ldapai_info_version
+          A number that identifies the version of the LDAPAPIInfo struc-
+          ture.  This should be set to the value LDAP_API_INFO_VERSION
+          (1) before calling ldap_get_option().  If the value received
+          is not recognized by the API implementation, the
+          ldap_get_option() function sets ldapai_info_version to a valid
+          value that would be recognized, sets the ldapai_api_version to
+          the correct value, and returns an error without filling in any
+          of the other fields in the LDAPAPIInfo structure.
+
+ldapai_api_version
+          A number that matches that assigned to the C LDAP API RFC sup-
+          ported by the API implementation.  This should match the value
+          of the LDAP_API_VERSION macro defined earlier.
+
+ldapai_protocol_version
+          The highest LDAP protocol version supported by the implementa-
+          tion.  For example, if LDAPv3 is the highest version supported
+          then this field will be set to 3.
+
+ldapai_extensions
+          A NULL-terminated array of character strings that lists the
+          names of the API extensions supported by the LDAP API imple-
+          mentation.  These names will typically match the textual iden-
+          tifiers that appear in the "x" portion of the
+          LDAP_API_FEATURE_x macros described above, although the pre-
+          cise value MUST be defined by documents that specify C LDAP
+          API extensions.  If no API extensions are supported, this
+          field will be set to NULL.  The caller is responsible for
+          disposing of the memory occupied by this array by passing it
+          to ldap_value_free() which is described later in this docu-
+          ment.  To retrieve more information about a particular exten-
+          sion, the ldap_get_option() call can be used with an option
+          parameter value of LDAP_OPT_API_FEATURE_INFO (0x15).  The opt-
+          data parameter to the ldap_get_option() MUST be the address of
+          an LDAPAPIFeatureInfo structure which is defined as follows:
+
+             typedef struct ldap_apifeature_info {
+                 int   ldapaif_info_version; /* version of this struct (1) */
+                 char  *ldapaif_name;        /* name of supported feature */
+                 int   ldapaif_version;      /* revision of supported feature */
+             } LDAPAPIFeatureInfo;
+
+          In addition, API implementations MUST include the following
+          macro definition:
+
+
+
+
+Expires: 23 August 1999                                        [Page 11]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+             #define LDAP_FEATURE_INFO_VERSION    1
+
+          Note that the ldapaif_info_version field of the LDAPAPI-
+          FeatureInfo structure should be set to the value
+          LDAP_FEATURE_INFO_VERSION (1) and the ldapaif_name field
+          should be set to the extension name string as described below
+          before ldap_get_option() is called.  The call will fill in the
+          ldapaif_version field of the LDAPAPIFeatureInfo structure.
+
+   The members of the LDAPAPIFeatureInfo structure are:
+
+   ldapaif_info_version
+             A number that identifies the version of the LDAPAPI-
+             FeatureInfo structure.  This should be set to the value
+             LDAP_FEATURE_INFO_VERSION (1) before calling
+             ldap_get_option().  If the value received is not recognized
+             by the API implementation, the ldap_get_option() function
+             sets ldapaif_info_version to a valid value that would be
+             recognized and returns an error without filling in the
+             ldapaif_version field in the LDAPAPIFeatureInfo structure.
+
+   ldapaif_name
+             The name of an extension, as returned in the
+             ldapai_extensions array of the LDAPAPIInfo structure and as
+             specified in the document that describes the extension.
+
+   ldapaif_version
+             This field will be set as a result of calling
+             ldap_get_option().  It is a number that matches that
+             assigned to the C LDAP API extension RFC supported for this
+             extension.  For private or experimental API extensions, the
+             value is extension-specific.  In either case, the value of
+             ldapaxi_ext_version should be identical to the value of the
+             LDAP_API_FEATURE_x macro defined for the extension
+             (described above).
+
+ldapai_vendor_name
+          A zero-terminated string that contains the name of the party
+          that produced the LDAP API implementation.  This field may be
+          set to NULL if no name is available.  If non-NULL, the caller
+          is responsible for disposing of the memory occupied by passing
+          this pointer to ldap_memfree() which is described later in
+          this document.  This value SHOULD match the value of the
+          LDAP_VENDOR_NAME macro described earlier in this document.
+
+ldapai_vendor_version
+          An implementation-specific version number multiplied by 100.
+          For example, if the implementation version is 4.0 then this
+
+
+
+Expires: 23 August 1999                                        [Page 12]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+          field will be set to 400.  If no version information is avail-
+          able, this field will be set to 0.  This value SHOULD match
+          the value of the LDAP_VENDOR_VERSION macro described earlier
+          in this document.
+
+
+9.  LDAP Error Codes
+
+Many of the LDAP API routines 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.  Supported
+error codes are (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)
+
+
+
+Expires: 23 August 1999                                        [Page 13]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+           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 CLDAP
+           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)
+
+
+10.  Performing LDAP Operations
+
+This section describes each LDAP operation API call in detail. All func-
+tions take a "session handle," a pointer to an LDAP structure containing
+per-connection information.  Many routines return results in an LDAPMes-
+sage structure. These structures and others are described as needed
+below.
+
+
+10.1.  Initializing an LDAP Session
+
+ldap_init() 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 routine is deprecated:
+
+
+
+
+Expires: 23 August 1999                                        [Page 14]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+        LDAP *ldap_open(
+                const char      *hostname,
+                int             portno
+        );
+Unlike ldap_init(), ldap_open() attempts to make a server connection
+before returning to the caller.
+
+Parameters are:
+
+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 will be tried in the order
+         listed, stopping with the first one to which a successful con-
+         nection is made.
+
+   Note: A suitable representation for including a literal IPv6[11]
+   address in the hostname parameter is desired, but has not yet been
+   determined or implemented in practice.
+
+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 parame-
+         ter is ignored.
+
+ldap_init() and ldap_open() both return a "session handle," a pointer to
+an opaque structure that should be passed to subsequent calls pertaining
+to the session. These routines return NULL if the session cannot be ini-
+tialized 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 LDAPv2 server, one of the LDAP bind calls
+described below must be completed before other operations can be per-
+formed 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 routines described in the next section.
+
+
+10.2.  LDAP Session Handle Options
+
+The LDAP session handle returned by ldap_init() is a pointer to an
+opaque data type representing an LDAP session. In RFC 1823 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.
+
+
+
+Expires: 23 August 1999                                        [Page 15]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+In the interest of insulating callers from inevitable changes to this
+structure, these aspects of the session are now accessed through a pair
+of accessor functions, described below.
+
+ldap_get_option() is used to access the current value of various
+session-wide parameters. ldap_set_option() 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.
+
+Note that if automatic referral following is enabled (the default), any
+connections created during the course of following referrals will
+inherit the options associated with the session that sent the original
+request that caused the referrals to be returned.
+
+           int ldap_get_option(
+                   LDAP            *ld,
+                   int             option,
+                   void            *outvalue
+           );
+
+           int ldap_set_option(
+                   LDAP            *ld,
+                   int             option,
+                   const void      *invalue
+           );
+
+   #define LDAP_OPT_ON     ((void *)1)
+   #define LDAP_OPT_OFF    ((void *)0)
+
+
+Parameters are:
+
+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 indi-
+       cated meanings.  After the constant the actual hexadecimal value
+       of the constant is listed in parentheses.
+
+
+   LDAP_OPT_API_INFO (0x00)
+      Type for invalue parameter: not applicable (option is READ-ONLY)
+
+      Type for outvalue parameter: LDAPAPIInfo *
+
+
+
+Expires: 23 August 1999                                        [Page 16]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+      Description:
+           Used to retrieve some basic information about the LDAP API
+           implementation at execution time.  See the section "Retriev-
+           ing Information About the API Implementation" above for more
+           information.  This option is READ-ONLY and cannot be set.
+
+      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 pri-
+              mary 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 derefer-
+              enced 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:
+
+
+
+Expires: 23 August 1999                                        [Page 17]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+              A limit on the number of seconds to spend on a search. A
+              value of LDAP_NO_LIMIT (0) means no limit.  This value is
+              passed to the server in the search request only; it does
+              not affect how long the C LDAP API implementation itself
+              will wait locally for search results.  The timeout parame-
+              ter passed to ldap_search_ext_s() or ldap_result() -- both
+              of which are described later in this document -- can be
+              used to specify both a local and server side time limit.
+
+      LDAP_OPT_REFERRALS (0x08)
+         Type for invalue parameter: void * (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 or not. It can be set
+              to one of the constants LDAP_OPT_ON or LDAP_OPT_OFF; any
+              non-NULL pointer value passed to ldap_set_option() enables
+              this option.  When reading the current setting using
+              ldap_get_option(), a zero value means off and any non-zero
+              value means on.
+
+      LDAP_OPT_RESTART (0x09)
+         Type for invalue parameter: void * (LDAP_OPT_ON or
+         LDAP_OPT_OFF)
+
+         Type for outvalue parameter: int *
+
+         Description:
+              Determines whether LDAP I/O operations should automati-
+              cally be restarted if they abort prematurely. It should be
+              set to one of the constants LDAP_OPT_ON or LDAP_OPT_OFF;
+              any non-NULL pointer value passed to ldap_set_option()
+              enables this option.  When reading the current setting
+              using ldap_get_option(), a zero value means off and any
+              non-zero value means on. This option is useful if an LDAP
+              I/O operation may be 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
+
+
+
+Expires: 23 August 1999                                        [Page 18]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+              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 the Working With Controls section
+              below.
+
+      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 the Working With Controls section below.
+
+      LDAP_OPT_API_FEATURE_INFO (0x15)
+         Type for invalue parameter: not applicable (option is READ-
+         ONLY)
+
+         Type for outvalue parameter: LDAPAPIFeatureInfo *
+
+         Description:
+              Used to retrieve version information about LDAP API
+              extended features at execution time.  See the section
+              "Retrieving Information About the API Implementation"
+              above for more information.  This option is READ-ONLY and
+              cannot be set.
+
+      LDAP_OPT_HOST_NAME (0x30)
+         Type for invalue parameter: char *
+
+         Type for outvalue parameter: char **
+
+         Description:
+              The host name (or list of hosts) for the primary LDAP
+              server.  See the definition of the hostname parameter to
+              ldap_init() for the allowed syntax.
+
+      LDAP_OPT_ERROR_NUMBER (0x31)
+
+
+
+Expires: 23 August 1999                                        [Page 19]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+         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 LDAP-
+            Control **, a copy of the 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 data associated with invalue is copied by the
+            API implementation to allow callers of the API to dispose of
+            or otherwise change their copy of the data after a success-
+            ful call to ldap_set_option().  If a value passed for
+            invalue is invalid or cannot be accepted by the implementa-
+            tion, ldap_set_option() should return -1 to indicate an
+            error.
+
+Both ldap_get_option() and ldap_set_option() return 0 if successful and
+-1 if an error occurs.
+
+Standards track documents that extend this specification and specify new
+options MUST use values for option macros that are between 0x1000 and
+0x3FFF inclusive.  Private and experimental extensions MUST use values
+for the option macros that are between 0x4000 and 0x7FFF inclusive.  All
+values below 0x1000 and above 0x7FFF that are not defined in this docu-
+ment are reserved and MUST NOT be used.
+
+
+
+
+
+
+
+Expires: 23 August 1999                                        [Page 20]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+10.3.  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 con-
+                 trol, set ldctl_value.bv_val to NULL.
+
+ldctl_iscritical Indicates whether the control is critical of not. If
+                 this field is non-zero, the operation will only be car-
+                 ried out if the control is recognized by the server
+                 and/or client.  Note that the LDAP unbind and abandon
+                 operations have no server response, so clients SHOULD
+                 NOT mark server controls critical when used with these
+                 two operations.
+
+Some LDAP API calls allocate an ldapcontrol structure or a NULL-
+terminated array of ldapcontrol structures.  The following routines 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 (see above).  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.
+
+
+
+Expires: 23 August 1999                                        [Page 21]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+Server controls are defined by LDAPv3 protocol extension documents; for
+example, a control has been proposed to support server-side sorting of
+search results [7].
+
+One client control is defined in this document (described in the follow-
+ing section).  Other client controls may be defined in future revisions
+of this document or in documents that extend this API.
+
+
+10.3.1.  A Client Control That Governs Referral Processing
+
+As described previously in the section "LDAP Session Handle Options,"
+applications can enable and disable automatic chasing of referrals on a
+session-wide basic by using the ldap_set_option() function with the
+LDAP_OPT_REFERRALS option.  It is also useful to govern automatic refer-
+ral chasing on per-request basis.  A client control with an OID of
+1.2.840.113556.1.4.616 exists to provide this functionality.
+
+   /* OID for referrals client control */
+   #define LDAP_CONTROL_REFERRALS              "1.2.840.113556.1.4.616"
+
+   /* Flags for referrals client control value */
+   #define LDAP_CHASE_SUBORDINATE_REFERRALS    0x00000020
+   #define LDAP_CHASE_EXTERNAL_REFERRALS       0x00000040
+
+To create a referrals client control, the ldctl_oid field of an LDAPCon-
+trol structure should be set to LDAP_CONTROL_REFERRALS
+("1.2.840.113556.1.4.616") and the ldctl_value field should be set to a
+4-octet value that contains a set of flags.  The ldctl_value.bv_len
+field should always be set to 4.  The ldctl_value.bv_val field should
+point to a 4-octet integer flags value.  This flags value can be set to
+zero to disable automatic chasing of referrals and LDAPv3 references
+altogether.  Alternatively, the flags value can be set to the value
+LDAP_CHASE_SUBORDINATE_REFERRALS (0x00000020) to indicate that only
+LDAPv3 search continuation references should be automatically chased by
+the API implementation, to the value LDAP_CHASE_EXTERNAL_REFERRALS
+(0x00000040) to indicate that only LDAPv3 referrals should be automati-
+cally chased, or the logical OR of the two flag values (0x00000060) to
+indicate that both referrals and references should be automatically
+chased.
+
+
+10.4.  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
+
+
+
+Expires: 23 August 1999                                        [Page 22]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+general and extensible authentication over LDAP through the use of the
+Simple Authentication Security Layer [8].  The routines 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 routines
+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 routines is deprecated:
+
+           int ldap_bind( LDAP *ld, const char *dn, const char *cred,
+                   int method );
+
+           int ldap_bind_s( LDAP *ld, const char *dn, const char *cred,
+                   int method );
+
+
+
+
+Expires: 23 August 1999                                        [Page 23]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+           int ldap_kerberos_bind( LDAP *ld, const char *dn );
+
+           int ldap_kerberos_bind_s( LDAP *ld, const char *dn );
+
+Parameters are:
+
+ld           The session handle.
+
+dn           The name of the entry to bind as.
+
+mechanism    Either LDAP_SASL_SIMPLE (NULL) to get simple authentica-
+             tion, 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 creden-
+             tials 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 routines are not described.
+Interested readers are referred to RFC 1823.
+
+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 the section below on error
+handling 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(), described below,
+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 sub-
+sequent call to ldap_result(), described below, can be used to obtain
+
+
+
+Expires: 23 August 1999                                        [Page 24]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+the result of the bind. In case of error, ldap_simple_bind() will return
+-1, setting the session error parameters in the LDAP structure appropri-
+ately.
+
+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 the section below on error handling for more informa-
+tion about possible errors and how to interpret them.
+
+Note that if an LDAPv2 server is contacted, no other operations over the
+connection should be attempted before a bind call has successfully com-
+pleted.
+
+Subsequent bind calls can be used to re-authenticate over the same con-
+nection, and multistep SASL sequences can be accomplished through a
+sequence of calls to ldap_sasl_bind() or ldap_sasl_bind_s().
+
+
+10.5.  Closing the session
+
+The following functions are used to unbind from the directory, close
+open connections, and dispose of the session handle.
+
+           int ldap_unbind_ext( LDAP *ld, LDAPControl **serverctrls,
+               LDAPControl **clientctrls );
+
+           int ldap_unbind( LDAP *ld );
+
+           int ldap_unbind_s( LDAP *ld );
+
+Parameters are:
+
+ld           The session handle.
+
+serverctrls  List of LDAP server controls.
+
+clientctrls  List of client controls.
+
+The ldap_unbind_ext(), ldap_unbind() and ldap_unbind_s() all work syn-
+chronously in the sense that they send an unbind request to the server,
+close all open connections associated with the LDAP session handle, and
+dispose of all resources associated with the session handle before
+returning.  Note, however, that there is no server response to an LDAP
+unbind operation.  All three of the unbind functions return LDAP_SUCCESS
+(or another LDAP error code if the request cannot be sent to the LDAP
+server).  After a call to one of the unbind functions, the session han-
+dle ld is invalid and it is illegal to make any further LDAP API calls
+
+
+
+Expires: 23 August 1999                                        [Page 25]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+using ld.
+
+The ldap_unbind() and ldap_unbind_s() functions behave identically.  The
+ldap_unbind_ext() function allows server and client controls to be
+included explicitly, but note that since there is no server response to
+an unbind request there is no way to receive a response to a server con-
+trol sent with an unbind request.
+
+
+
+10.6.  Searching
+
+The following functions are used to search the LDAP directory, returning
+a requested set of attributes for each entry matched.  There are five
+variations.
+
+           int ldap_search_ext(
+                   LDAP            *ld,
+                   const char      *base,
+                   int             scope,
+                   const char      *filter,
+                   char            **attrs,
+                   int             attrsonly,
+                   LDAPControl     **serverctrls,
+                   LDAPControl     **clientctrls,
+                   struct timeval  *timeout,
+                   int             sizelimit,
+                   int             *msgidp
+           );
+
+           int ldap_search_ext_s(
+                   LDAP            *ld,
+                   const char      *base,
+                   int             scope,
+                   const char      *filter,
+                   char            **attrs,
+                   int             attrsonly,
+                   LDAPControl     **serverctrls,
+                   LDAPControl     **clientctrls,
+                   struct timeval  *timeout,
+                   int             sizelimit,
+                   LDAPMessage     **res
+           );
+
+           int ldap_search(
+                   LDAP            *ld,
+                   const char      *base,
+                   int             scope,
+
+
+
+Expires: 23 August 1999                                        [Page 26]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+                   const char      *filter,
+                   char            **attrs,
+                   int             attrsonly
+           );
+
+           int ldap_search_s(
+                   LDAP            *ld,
+                   const char      *base,
+                   int             scope,
+                   const char      *filter,
+                   char            **attrs,
+                   int             attrsonly,
+                   LDAPMessage     **res
+           );
+
+           int ldap_search_st(
+                   LDAP            *ld,
+                   const char      *base,
+                   int             scope,
+                   const char      *filter,
+                   char            **attrs,
+                   int             attrsonly,
+                   struct timeval  *timeout,
+                   LDAPMessage     **res
+           );
+
+Parameters are:
+
+ld           The session handle.
+
+base         The dn of the entry at which to start the search.
+
+scope        One of LDAP_SCOPE_BASE (0x00), LDAP_SCOPE_ONELEVEL (0x01),
+             or LDAP_SCOPE_SUBTREE (0x02), indicating the scope of the
+             search.
+
+filter       A character string as described in [3], representing the
+             search filter.  The value NULL can be passed to indicate
+             that the filter "(objectclass=*)" which matches all entries
+             should be used.  Note that if the caller of the API is
+             using LDAPv2, only a subset of the filter functionality
+             described in [3] can be successfully used.
+
+attrs        A NULL-terminated array of strings indicating which attri-
+             butes to return for each matching entry. Passing NULL for
+             this parameter causes all available user attributes to be
+             retrieved.  The special constant string LDAP_NO_ATTRS
+             ("1.1") can be used as the only string in the array to
+
+
+
+Expires: 23 August 1999                                        [Page 27]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+             indicate that no attribute types should be returned by the
+             server.  The special constant string LDAP_ALL_USER_ATTRS
+             ("*") can be used in the attrs array along with the names
+             of some operational attributes to indicate that all user
+             attributes plus the listed operational attributes should be
+             returned.
+
+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.
+
+timeout      For the ldap_search_st() function, this specifies the local
+             search timeout value (if it is NULL, the timeout is infin-
+             ite).  For the ldap_search_ext() and ldap_search_ext_s()
+             functions, this specifies both the local search timeout
+             value and the operation time limit that is sent to the
+             server within the search request.  For the
+             ldap_search_ext() and ldap_search_ext_s() functions, pass-
+             ing a NULL value for timeout causes the global default
+             timeout stored in the LDAP session handle (set by using
+             ldap_set_option() with the LDAP_OPT_TIMELIMIT parameter) to
+             be sent to the server with the request but an infinite
+             local search timeout to be used.
+
+sizelimit    For the ldap_search_ext() and ldap_search_ext_s() calls,
+             this is a limit on the number of entries to return from the
+             search.  A value of LDAP_NO_LIMIT (0) means no limit.
+
+res          For the synchronous calls, this is a result parameter which
+             will contain the results of the search upon completion of
+             the call.  If no results are returned, *res is set to NULL.
+
+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_search_ext() call succeeds.
+
+There are three options in the session handle ld which potentially
+affect how the search is performed. They are:
+
+LDAP_OPT_SIZELIMIT
+             A limit on the number of entries to return from the search.
+             A value of LDAP_NO_LIMIT (0) means no limit.  Note that the
+             value from the session handle is ignored when using the
+             ldap_search_ext() or ldap_search_ext_s() functions.
+
+
+
+
+Expires: 23 August 1999                                        [Page 28]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+LDAP_OPT_TIMELIMIT
+             A limit on the number of seconds to spend on the search. A
+             value of LDAP_NO_LIMIT (0) means no limit.  Note that the
+             value from the session handle is ignored when using the
+             ldap_search_ext() or ldap_search_ext_s() functions.
+
+LDAP_OPT_DEREF
+             One of LDAP_DEREF_NEVER (0x00), LDAP_DEREF_SEARCHING
+             (0x01), LDAP_DEREF_FINDING (0x02), or LDAP_DEREF_ALWAYS
+             (0x03), 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.
+
+The ldap_search_ext() function initiates an asynchronous search opera-
+tion and returns the constant LDAP_SUCCESS if the request was success-
+fully sent, or another LDAP error code if not.  See the section below on
+error handling for more information about possible errors and how to
+interpret them.  If successful, ldap_search_ext() places the message id
+of the request in *msgidp. A subsequent call to ldap_result(), described
+below, can be used to obtain the results from the search.  These results
+can be parsed using the result parsing routines described in detail
+later.
+
+Similar to ldap_search_ext(), the ldap_search() function initiates an
+asynchronous search operation and returns the message id of the opera-
+tion initiated.  As for ldap_search_ext(), a subsequent call to
+ldap_result(), described below, can be used to obtain the result of the
+bind. In case of error, ldap_search() will return -1, setting the ses-
+sion error parameters in the LDAP structure appropriately.
+
+The synchronous ldap_search_ext_s(), ldap_search_s(), and
+ldap_search_st() functions all 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 the section below on error
+handling for more information about possible errors and how to interpret
+them.  Entries returned from the search (if any) are contained in the
+res parameter. This parameter is opaque to the caller.  Entries, attri-
+butes, 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.
+
+The ldap_search_ext() and ldap_search_ext_s() functions support LDAPv3
+server controls, client controls, and allow varying size and time limits
+to be easily specified for each search operation.  The ldap_search_st()
+function is identical to ldap_search_s() except that it takes an
+
+
+
+Expires: 23 August 1999                                        [Page 29]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+additional parameter specifying a local timeout for the search.  The
+local search timeout is used to limit the amount of time the API imple-
+mentation will wait for a search to complete.  After the local search
+timeout expires, the API implementation will send an abandon operation
+to abort the search operation.
+
+10.7.  Reading an Entry
+
+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=*)" or
+NULL. attrs contains the list of attributes to return.
+
+
+10.8.  Listing the Children of an Entry
+
+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=*)" or
+NULL. attrs contains the list of attributes to return for each child
+entry.
+
+10.9.  Comparing a Value Against an Entry
+
+The following routines are used to compare a given attribute value
+assertion against an LDAP entry.  There are four variations:
+
+           int ldap_compare_ext(
+                   LDAP            *ld,
+                   const char      *dn,
+                   const char      *attr,
+                   struct berval   *bvalue
+                   LDAPControl     **serverctrls,
+                   LDAPControl     **clientctrls,
+                   int             *msgidp
+           );
+
+           int ldap_compare_ext_s(
+                   LDAP            *ld,
+                   const char      *dn,
+                   const char      *attr,
+                   struct berval   *bvalue,
+                   LDAPControl     **serverctrls,
+                   LDAPControl     **clientctrls
+           );
+
+           int ldap_compare(
+                   LDAP            *ld,
+
+
+
+Expires: 23 August 1999                                        [Page 30]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+                   const char      *dn,
+                   const char      *attr,
+                   const char      *value
+           );
+
+           int ldap_compare_s(
+                   LDAP            *ld,
+                   const char      *dn,
+                   const char      *attr,
+                   const char      *value
+           );
+
+Parameters are:
+
+ld           The session handle.
+
+dn           The name of the entry to compare against.
+
+attr         The attribute to compare against.
+
+bvalue       The attribute value to compare against those found in the
+             given entry. This parameter is used in the extended rou-
+             tines and is a pointer to a struct berval so it is possible
+             to compare binary values.
+
+value        A string attribute value to compare against, used by the
+             ldap_compare() and ldap_compare_s() functions.  Use
+             ldap_compare_ext() or ldap_compare_ext_s() if you need to
+             compare binary values.
+
+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_compare_ext() call succeeds.
+
+The ldap_compare_ext() function initiates an asynchronous compare opera-
+tion and returns the constant LDAP_SUCCESS if the request was success-
+fully sent, or another LDAP error code if not.  See the section below on
+error handling for more information about possible errors and how to
+interpret them.  If successful, ldap_compare_ext() places the message id
+of the request in *msgidp. A subsequent call to ldap_result(), described
+below, can be used to obtain the result of the compare.
+
+Similar to ldap_compare_ext(), the ldap_compare() function initiates an
+asynchronous compare operation and returns the message id of the opera-
+tion initiated.  As for ldap_compare_ext(), a subsequent call to
+
+
+
+Expires: 23 August 1999                                        [Page 31]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+ldap_result(), described below, can be used to obtain the result of the
+bind. In case of error, ldap_compare() will return -1, setting the ses-
+sion error parameters in the LDAP structure appropriately.
+
+The synchronous ldap_compare_ext_s() and ldap_compare_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 the section below on error handling for more information about pos-
+sible errors and how to interpret them.
+
+The ldap_compare_ext() and ldap_compare_ext_s() functions support LDAPv3
+server controls and client controls.
+
+
+10.10.  Modifying an entry
+
+The following routines are used to modify an existing LDAP entry.  There
+are four variations:
+
+           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
+
+           int ldap_modify_ext(
+                   LDAP            *ld,
+                   const char      *dn,
+                   LDAPMod         **mods,
+                   LDAPControl     **serverctrls,
+                   LDAPControl     **clientctrls,
+                   int             *msgidp
+           );
+
+           int ldap_modify_ext_s(
+                   LDAP            *ld,
+                   const char      *dn,
+                   LDAPMod         **mods,
+                   LDAPControl     **serverctrls,
+                   LDAPControl     **clientctrls
+           );
+
+           int ldap_modify(
+
+
+
+Expires: 23 August 1999                                        [Page 32]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+                   LDAP            *ld,
+                   const char      *dn,
+                   LDAPMod         **mods
+           );
+
+           int ldap_modify_s(
+                   LDAP            *ld,
+                   const char      *dn,
+                   LDAPMod         **mods
+           );
+
+Parameters are:
+
+ld           The session handle.
+
+dn           The name of the entry to modify.
+
+mods         A NULL-terminated array of modifications to make to the
+             entry.
+
+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_modify_ext() call succeeds.
+
+The fields in the LDAPMod structure have the following meanings:
+
+mod_op       The modification operation to perform. It should be one of
+             LDAP_MOD_ADD (0x00), LDAP_MOD_DELETE (0x01), or
+             LDAP_MOD_REPLACE (0x02).  This field also indicates the
+             type of values included in the mod_vals union. It is logi-
+             cally ORed with LDAP_MOD_BVALUES (0x80) to select the
+             mod_bvalues form. Otherwise, the mod_values form is used.
+
+mod_type     The type of the attribute to modify.
+
+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.
+
+For LDAP_MOD_ADD modifications, the given values are added to  the
+entry, creating the attribute if necessary.
+
+
+
+Expires: 23 August 1999                                        [Page 33]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+For LDAP_MOD_DELETE modifications, the given values are deleted from the
+entry, removing the attribute if no values remain. If the entire attri-
+bute 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, or
+removed if the mod_vals field is NULL. All modifications are performed
+in the order in which they are listed.
+
+The ldap_modify_ext() function initiates an asynchronous modify opera-
+tion and returns the constant LDAP_SUCCESS if the request was success-
+fully sent, or another LDAP error code if not.  See the section below on
+error handling for more information about possible errors and how to
+interpret them.  If successful, ldap_modify_ext() places the message id
+of the request in *msgidp. A subsequent call to ldap_result(), described
+below, can be used to obtain the result of the modify.
+
+Similar to ldap_modify_ext(), the ldap_modify() function initiates an
+asynchronous modify operation and returns the message id of the opera-
+tion initiated.  As for ldap_modify_ext(), a subsequent call to
+ldap_result(), described below, can be used to obtain the result of the
+modify. In case of error, ldap_modify() will return -1, setting the ses-
+sion error parameters in the LDAP structure appropriately.
+
+The synchronous ldap_modify_ext_s() and ldap_modify_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 the section below on error handling for more information about pos-
+sible errors and how to interpret them.
+
+The ldap_modify_ext() and ldap_modify_ext_s() functions support LDAPv3
+server controls and client controls.
+
+
+10.11.  Modifying the Name of an Entry
+
+In LDAPv2, the ldap_modrdn(), ldap_modrdn_s(), ldap_modrdn2(), and
+ldap_modrdn2_s() routines were used to change the name of an LDAP entry.
+They could only be used to change the least significant component of a
+name (the RDN or relative distinguished name). LDAPv3 provides the
+Modify DN protocol operation that allows more general name change
+access. The ldap_rename() and ldap_rename_s() routines are used to
+change the name of an entry, and the use of the ldap_modrdn(),
+ldap_modrdn_s(), ldap_modrdn2(), and ldap_modrdn2_s() routines is depre-
+cated.
+
+           int ldap_rename(
+                   LDAP            *ld,
+
+
+
+Expires: 23 August 1999                                        [Page 34]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+                   const char      *dn,
+                   const char      *newrdn,
+                   const char      *newparent,
+                   int             deleteoldrdn,
+                   LDAPControl     **serverctrls,
+                   LDAPControl     **clientctrls,
+                   int             *msgidp
+
+           );
+           int ldap_rename_s(
+                   LDAP            *ld,
+                   const char      *dn,
+                   const char      *newrdn,
+                   const char      *newparent,
+                   int             deleteoldrdn,
+                   LDAPControl     **serverctrls,
+                   LDAPControl     **clientctrls
+           );
+
+   Use of the following routines is deprecated.
+
+           int ldap_modrdn(
+                   LDAP            *ld,
+                   const char      *dn,
+                   const char      *newrdn
+           );
+           int ldap_modrdn_s(
+                   LDAP            *ld,
+                   const char      *dn,
+                   const char      *newrdn
+           );
+           int ldap_modrdn2(
+                   LDAP            *ld,
+                   const char      *dn,
+                   const char      *newrdn,
+                   int             deleteoldrdn
+           );
+           int ldap_modrdn2_s(
+                   LDAP            *ld,
+                   const char      *dn,
+                   const char      *newrdn,
+                   int             deleteoldrdn
+           );
+
+Parameters are:
+
+ld           The session handle.
+
+
+
+
+Expires: 23 August 1999                                        [Page 35]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+dn           The name of the entry whose DN is to be changed.
+
+newrdn       The new RDN to give the entry.
+
+newparent    The new parent, or superior entry.  If this parameter is
+             NULL, only the RDN of the entry is changed.  The root DN
+             may be specified by passing a zero length string, "".  The
+             newparent parameter should always be NULL when using ver-
+             sion 2 of the LDAP protocol; otherwise the server's
+             behavior is undefined.
+
+deleteoldrdn This parameter only has meaning on the rename routines if
+             newrdn is different than the old RDN. It is 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.
+
+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_rename() call succeeds.
+
+The ldap_rename() function initiates an asynchronous modify DN operation
+and returns the constant LDAP_SUCCESS if the request was successfully
+sent, or another LDAP error code if not.  See the section below on error
+handling for more information about possible errors and how to interpret
+them.  If successful, ldap_rename() places the DN message id of the
+request in *msgidp. A subsequent call to ldap_result(), described below,
+can be used to obtain the result of the rename.
+
+The synchronous ldap_rename_s() returns 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 the section below on error
+handling for more information about possible errors and how to interpret
+them.
+
+The ldap_rename() and ldap_rename_s() functions both support LDAPv3
+server controls and client controls.
+
+
+10.12.  Adding an entry
+
+The following functions are used to add entries to the LDAP directory.
+There are four variations:
+
+
+
+
+Expires: 23 August 1999                                        [Page 36]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+           int ldap_add_ext(
+                   LDAP            *ld,
+                   const char      *dn,
+                   LDAPMod         **attrs,
+                   LDAPControl     **serverctrls,
+                   LDAPControl     **clientctrls,
+                   int             *msgidp
+           );
+
+           int ldap_add_ext_s(
+                   LDAP            *ld,
+                   const char      *dn,
+                   LDAPMod         **attrs,
+                   LDAPControl     **serverctrls,
+                   LDAPControl     **clientctrls
+           );
+
+           int ldap_add(
+                   LDAP            *ld,
+                   const char      *dn,
+                   LDAPMod         **attrs
+           );
+
+           int ldap_add_s(
+                   LDAP            *ld,
+                   const char      *dn,
+                   LDAPMod         **attrs
+           );
+
+Parameters are:
+
+ld           The session handle.
+
+dn           The name of the entry to add.
+
+attrs        The entry's attributes, specified using the LDAPMod struc-
+             ture 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.
+
+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_add_ext() call succeeds.
+
+
+
+
+Expires: 23 August 1999                                        [Page 37]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+Note that the parent of the entry being added must already exist or the
+parent must be empty (i.e., equal to the root DN) for an add to succeed.
+
+The ldap_add_ext() function initiates an asynchronous add operation and
+returns the constant LDAP_SUCCESS if the request was successfully sent,
+or another LDAP error code if not.  See the section below on error han-
+dling for more information about possible errors and how to interpret
+them.  If successful, ldap_add_ext() places the message id of the
+request in *msgidp. A subsequent call to ldap_result(), described below,
+can be used to obtain the result of the add.
+
+Similar to ldap_add_ext(), the ldap_add() function initiates an asyn-
+chronous add operation and returns the message id of the operation ini-
+tiated.  As for ldap_add_ext(), a subsequent call to ldap_result(),
+described below, can be used to obtain the result of the add. In case of
+error, ldap_add() will return -1, setting the session error parameters
+in the LDAP structure appropriately.
+
+The synchronous ldap_add_ext_s() and ldap_add_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
+the section below on error handling for more information about possible
+errors and how to interpret them.
+
+The ldap_add_ext() and ldap_add_ext_s() functions support LDAPv3 server
+controls and client controls.
+
+
+
+10.13.  Deleting an entry
+
+The following functions are used to delete a leaf entry from the LDAP
+directory.  There are four variations:
+
+           int ldap_delete_ext(
+                   LDAP            *ld,
+                   const char      *dn,
+                   LDAPControl     **serverctrls,
+                   LDAPControl     **clientctrls,
+                   int             *msgidp
+           );
+
+           int ldap_delete_ext_s(
+                   LDAP            *ld,
+                   const char      *dn,
+                   LDAPControl     **serverctrls,
+                   LDAPControl     **clientctrls
+           );
+
+
+
+Expires: 23 August 1999                                        [Page 38]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+
+           int ldap_delete(
+                   LDAP            *ld,
+                   const char      *dn
+           );
+
+           int ldap_delete_s(
+                   LDAP            *ld,
+                   const char      *dn
+           );
+
+Parameters are:
+
+ld           The session handle.
+
+dn           The name of the entry to delete.
+
+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_delete_ext() call succeeds.
+
+Note that the entry to delete must be a leaf entry (i.e., it must have
+no children). Deletion of entire subtrees in a single operation is not
+supported by LDAP.
+
+The ldap_delete_ext() function initiates an asynchronous delete opera-
+tion and returns the constant LDAP_SUCCESS if the request was success-
+fully sent, or another LDAP error code if not.  See the section below on
+error handling for more information about possible errors and how to
+interpret them.  If successful, ldap_delete_ext() places the message id
+of the request in *msgidp. A subsequent call to ldap_result(), described
+below, can be used to obtain the result of the delete.
+
+Similar to ldap_delete_ext(), the ldap_delete() function initiates an
+asynchronous delete operation and returns the message id of the opera-
+tion initiated.  As for ldap_delete_ext(), a subsequent call to
+ldap_result(), described below, can be used to obtain the result of the
+delete. In case of error, ldap_delete() will return -1, setting the ses-
+sion error parameters in the LDAP structure appropriately.
+
+The synchronous ldap_delete_ext_s() and ldap_delete_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 the section below on error handling for more information about pos-
+sible errors and how to interpret them.
+
+
+
+Expires: 23 August 1999                                        [Page 39]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+The ldap_delete_ext() and ldap_delete_ext_s() functions support LDAPv3
+server controls and client controls.
+
+
+10.14.  Extended Operations
+
+The ldap_extended_operation() and ldap_extended_operation_s() routines
+allow extended LDAP operations to be passed to the server, providing a
+general protocol extensibility mechanism.
+
+           int ldap_extended_operation(
+                   LDAP            *ld,
+                   const char      *exoid,
+                   struct berval   *exdata,
+                   LDAPControl     **serverctrls,
+                   LDAPControl     **clientctrls,
+                   int             *msgidp
+           );
+
+           int ldap_extended_operation_s(
+                   LDAP            *ld,
+                   const char      *exoid,
+                   struct berval   *exdata,
+                   LDAPControl     **serverctrls,
+                   LDAPControl     **clientctrls,
+                   char            **retoidp,
+                   struct berval   **retdatap
+           );
+
+Parameters are:
+
+ld           The session handle.
+
+requestoid   The dotted-OID text string naming the request.
+
+requestdata  The arbitrary data required by the operation (if NULL, no
+             data is sent to the server).
+
+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_extended_operation() call succeeds.
+
+retoidp      Pointer to a character string that will be set to an allo-
+             cated, dotted-OID text string returned by the server.  This
+             string should be disposed of using the ldap_memfree()
+
+
+
+Expires: 23 August 1999                                        [Page 40]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+             function.  If no OID was returned, *retoidp is set to NULL.
+
+retdatap     Pointer to a berval structure pointer that will be set an
+             allocated copy of the data returned by the server.  This
+             struct berval should be disposed of using ber_bvfree().  If
+             no data is returned, *retdatap is set to NULL.
+
+The ldap_extended_operation() function initiates an asynchronous
+extended operation and returns the constant LDAP_SUCCESS if the request
+was successfully sent, or another LDAP error code if not.  See the sec-
+tion below on error handling for more information about possible errors
+and how to interpret them.  If successful, ldap_extended_operation()
+places the message id of the request in *msgidp. A subsequent call to
+ldap_result(), described below, can be used to obtain the result of the
+extended operation which can be passed to ldap_parse_extended_result()
+to obtain the OID and data contained in the response.
+
+The synchronous ldap_extended_operation_s() function returns 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 the section
+below on error handling for more information about possible errors and
+how to interpret them.  The retoid and retdata parameters are filled in
+with the OID and data from the response.  If no OID or data was
+returned, these parameters are set to NULL.
+
+The ldap_extended_operation() and ldap_extended_operation_s() functions
+both support LDAPv3 server controls and client controls.
+
+
+11.  Abandoning An Operation
+
+The following calls are used to abandon an operation in progress:
+
+           int ldap_abandon_ext(
+                   LDAP            *ld,
+                   int             msgid,
+                   LDAPControl     **serverctrls,
+                   LDAPControl     **clientctrls
+           );
+
+           int ldap_abandon(
+                   LDAP            *ld,
+                   int             msgid
+           );
+
+
+ld           The session handle.
+
+
+
+
+Expires: 23 August 1999                                        [Page 41]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+msgid        The message id of the request to be abandoned.
+
+serverctrls  List of LDAP server controls.
+
+clientctrls  List of client controls.
+
+ldap_abandon_ext() abandons the operation with message id msgid and
+returns the constant LDAP_SUCCESS if the abandon was successful or
+another LDAP error code if not.  See the section below on error handling
+for more information about possible errors and how to interpret them.
+
+ldap_abandon() is identical to ldap_abandon_ext() except that it does
+not accept client or server controls and it returns zero if the abandon
+was successful, -1 otherwise.
+
+After a successful call to ldap_abandon() or ldap_abandon_ext(), results
+with the given message id are never returned from a subsequent call to
+ldap_result().  There is no server response to LDAP abandon operations.
+
+
+12.  Obtaining Results and Peeking Inside LDAP Messages
+
+ldap_result() is used to obtain the result of a previous asynchronously
+initiated operation. Note that depending on how it is called,
+ldap_result() may actually return a list or "chain" of result messages.
+The ldap_result() function only returns messages for a single request,
+so for all LDAP operations other than search only one result message is
+expected; that is, the only time the "result chain" may contain more
+than one message is if results from a search operation are returned.
+Once a chain of messages has been returned to the caller, it is no
+longer tied in any caller-visible way to the LDAP request that produced
+it.  Therefore, a chain of messages returned by calling ldap_result() or
+by calling a synchronous search routine will never be affected by subse-
+quent LDAP API calls (except for ldap_msgfree() which is used to dispose
+of a chain of messages).
+
+ldap_msgfree() frees the result messages (possibly an entire chain of
+messages) obtained from a previous call to ldap_result() or from a call
+to a synchronous search routine.
+
+ldap_msgtype() returns the type of an LDAP message.  ldap_msgid()
+returns the message ID of an LDAP message.
+
+           int ldap_result(
+                   LDAP            *ld,
+                   int             msgid,
+                   int             all,
+                   struct timeval  *timeout,
+
+
+
+Expires: 23 August 1999                                        [Page 42]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+                   LDAPMessage     **res
+           );
+
+           int ldap_msgfree( LDAPMessage *res );
+
+           int ldap_msgtype( LDAPMessage *res );
+
+           int ldap_msgid( LDAPMessage *res );
+
+Parameters are:
+
+ld       The session handle.
+
+msgid    The message id of the operation whose results are to be
+         returned, or the constant LDAP_RES_ANY (-1) if any result is
+         desired.
+
+all      Specifies how many messages will be retrieved in a single call
+         to ldap_result().  This parameter only has meaning for search
+         results.  Pass the constant LDAP_MSG_ONE (0x00) to retrieve one
+         message at a time.  Pass LDAP_MSG_ALL (0x01) to request that
+         all results of a search be received before returning all
+         results in a single chain.  Pass LDAP_MSG_RECEIVED (0x02) to
+         indicate that all messages retrieved so far should be returned
+         in the result chain.
+
+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 seconds speci-
+         fies a polling behavior.
+
+res      For ldap_result(), a result parameter that will contain the
+         result(s) of the operation. If no results are returned, *res is
+         set to NULL.  For ldap_msgfree(), the result chain to be freed,
+         obtained from a previous call to ldap_result(),
+         ldap_search_s(), or ldap_search_st().  If res is NULL, nothing
+         is done and ldap_msgfree() returns zero.
+
+Upon successful completion, ldap_result() returns the type of the first
+result returned in the res parameter. This will be one of the following
+constants.
+
+             LDAP_RES_BIND (0x61)
+             LDAP_RES_SEARCH_ENTRY (0x64)
+             LDAP_RES_SEARCH_REFERENCE (0x73)      -- new in LDAPv3
+             LDAP_RES_SEARCH_RESULT (0x65)
+             LDAP_RES_MODIFY (0x67)
+             LDAP_RES_ADD (0x69)
+
+
+
+Expires: 23 August 1999                                        [Page 43]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+             LDAP_RES_DELETE (0x6B)
+             LDAP_RES_MODDN (0x6D)
+             LDAP_RES_COMPARE (0x6F)
+             LDAP_RES_EXTENDED (0x78)              -- new in LDAPv3
+
+ldap_result() returns 0 if the timeout expired and -1 if an error
+occurs, in which case the error parameters of the LDAP session handle
+will be set accordingly.
+
+ldap_msgfree() frees the result structure pointed to by res and returns
+the type of the message it freed.  If res is NULL, nothing is done and
+the value zero is returned.
+
+ldap_msgtype() returns the type of the LDAP message it is passed as a
+parameter. The type will be one of the types listed above, or -1 on
+error.
+
+ldap_msgid() returns the message ID associated with the LDAP message
+passed as a parameter.
+
+
+13.  Handling Errors and Parsing Results
+
+The following calls are used to extract information from results and
+handle errors returned by other LDAP API routines.  Note that
+ldap_parse_sasl_bind_result() and ldap_parse_extended_result() must typ-
+ically be used in addition to ldap_parse_result() to retrieve all the
+result information from SASL Bind and Extended Operations respectively.
+
+           int ldap_parse_result(
+                   LDAP            *ld,
+                   LDAPMessage     *res,
+                   int             *errcodep,
+                   char            **matcheddnp,
+                   char            **errmsgp,
+                   char            ***referralsp,
+                   LDAPControl     ***serverctrlsp,
+                   int             freeit
+           );
+
+           int ldap_parse_sasl_bind_result(
+                   LDAP            *ld,
+                   LDAPMessage     *res,
+                   struct berval   **servercredp,
+                   int             freeit
+           );
+
+           int ldap_parse_extended_result(
+
+
+
+Expires: 23 August 1999                                        [Page 44]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+                   LDAP            *ld,
+                   LDAPMessage     *res,
+                   char            **retoidp,
+                   struct berval   **retdatap,
+                   int             freeit
+           );
+
+           char *ldap_err2string( int err );
+
+   The use of the following routines is deprecated.
+
+           int ldap_result2error(
+                   LDAP            *ld,
+                   LDAPMessage     *res,
+                   int             freeit
+           );
+
+           void ldap_perror( LDAP *ld, const char *msg );
+
+Parameters are:
+
+ld           The session handle.
+
+res          The result of an LDAP operation as returned by
+             ldap_result() or one of the synchronous API operation
+             calls.
+
+errcodep     This result parameter will be filled in with the LDAP error
+             code field from the LDAPMessage message.  This is the indi-
+             cation from the server of the outcome of the operation.
+             NULL may be passed to ignore this field.
+
+matcheddnp   In the case of a return of LDAP_NO_SUCH_OBJECT, this result
+             parameter will be filled in with a DN indicating how much
+             of the name in the request was recognized. NULL may be
+             passed to ignore this field.  The matched DN string should
+             be freed by calling ldap_memfree() which is described later
+             in this document.
+
+errmsgp      This result parameter will be filled in with the contents
+             of the error message field from the LDAPMessage message.
+             The error message string should be freed by calling
+             ldap_memfree() which is described later in this document.
+             NULL may be passed to ignore this field.
+
+referralsp   This result parameter will be filled in with the contents
+             of the referrals field from the LDAPMessage message, indi-
+             cating zero or more alternate LDAP servers where the
+
+
+
+Expires: 23 August 1999                                        [Page 45]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+             request should be retried.  The referrals array should be
+             freed by calling ldap_value_free() which is described later
+             in this document.  NULL may be passed to ignore this field.
+
+serverctrlsp This result parameter will be filled in with an allocated
+             array of controls copied out of the LDAPMessage message.
+             The control array should be freed by calling
+             ldap_controls_free() which was described earlier.
+
+freeit       A boolean that determines whether the res parameter is
+             disposed of or not.  Pass any non-zero value to have these
+             routines free res after extracting the requested informa-
+             tion.  This is provided as a convenience; you can also use
+             ldap_msgfree() to free the result later.  If freeit is
+             non-zero, the entire chain of messages represented by res
+             is disposed of.
+
+servercredp  For SASL bind results, this result parameter will be filled
+             in with the credentials passed back by the server for
+             mutual authentication, if given. An allocated berval struc-
+             ture is returned that should be disposed of by calling
+             ber_bvfree().  NULL may be passed to ignore this field.
+
+retoidp      For extended results, this result parameter will be filled
+             in with the dotted-OID text representation of the name of
+             the extended operation response.  This string should be
+             disposed of by calling ldap_memfree().  NULL may be passed
+             to ignore this field.
+
+retdatap     For extended results, this result parameter will be filled
+             in with a pointer to a struct berval containing the data in
+             the extended operation response.  It should be disposed of
+             by calling ber_bvfree(). NULL may be passed to ignore this
+             field.
+
+err          For ldap_err2string(), an LDAP error code, as returned by
+             ldap_parse_result() or another LDAP API call.
+
+Additional parameters for the deprecated routines are not described.
+Interested readers are referred to RFC 1823.
+
+All three of the ldap_parse_*_result() routines skip over messages of
+type LDAP_RES_SEARCH_ENTRY and LDAP_RES_SEARCH_REFERENCE when looking
+for a result message to parse.  They return the constant LDAP_SUCCESS if
+the result was successfully parsed and another LDAP error code if not.
+Note that the LDAP error code that indicates the outcome of the opera-
+tion performed by the server is placed in the errcodep
+ldap_parse_result() parameter.  If a chain of messages that contains
+
+
+
+Expires: 23 August 1999                                        [Page 46]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+more than one result message is passed to these routines they always
+operate on the first result in the chain.
+
+ldap_err2string() is used to convert a numeric LDAP error code, as
+returned by one of the three ldap_parse_*_result() routines, or one of
+the synchronous API operation calls, into an informative zero-terminated
+character string message describing the error.  It returns a pointer to
+static data.
+
+
+14.  Stepping Through a List of Results
+
+The ldap_first_message() and ldap_next_message() routines are used to
+step through the list of messages in a result chain returned by
+ldap_result().  For search operations, the result chain may actually
+include referral messages, entry messages, and result messages.
+ldap_count_messages() is used to count the number of messages returned.
+The ldap_msgtype() function, described above, can be used to distinguish
+between the different message types.
+
+           LDAPMessage *ldap_first_message( LDAP *ld, LDAPMessage *res );
+
+           LDAPMessage *ldap_next_message( LDAP *ld, LDAPMessage *msg );
+
+           int ldap_count_messages( LDAP *ld, LDAPMessage *res );
+
+Parameters are:
+
+ld     The session handle.
+
+res    The result chain, as obtained by a call to one of the synchronous
+       search routines or ldap_result().
+
+msg    The message returned by a previous call to ldap_first_message()
+       or ldap_next_message().
+
+ldap_first_message() and ldap_next_message() will return NULL when no
+more messages exist in the result set to be returned.  NULL is also
+returned if an error occurs while stepping through the entries, in which
+case the error parameters in the session handle ld will be set to indi-
+cate the error.
+
+ldap_count_messages() returns the number of messages contained in a
+chain of results. It can also be used to count the number of messages
+that remain in a chain if called with a message, entry, or reference
+returned by ldap_first_message(), ldap_next_message(),
+ldap_first_entry(), ldap_next_entry(), ldap_first_reference(),
+ldap_next_reference().
+
+
+
+Expires: 23 August 1999                                        [Page 47]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+15.  Parsing Search Results
+
+The following calls are used to parse the entries and references
+returned by ldap_search() and friends. These results 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 and
+references 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.
+
+
+15.1.  Stepping Through a List of Entries or References
+
+The ldap_first_entry() and ldap_next_entry() routines are used to step
+through and retrieve the list of entries from a search result chain.
+The ldap_first_reference() and ldap_next_reference() routines are used
+to step through and retrieve the list of continuation references from a
+search result chain.  ldap_count_entries() is used to count the number
+of entries returned. ldap_count_references() is used to count the number
+of references returned.
+
+           LDAPMessage *ldap_first_entry( LDAP *ld, LDAPMessage *res );
+
+           LDAPMessage *ldap_next_entry( LDAP *ld, LDAPMessage *entry );
+
+           LDAPMessage *ldap_first_reference( LDAP *ld, LDAPMessage *res );
+
+           LDAPMessage *ldap_next_reference( LDAP *ld, LDAPMessage *ref );
+
+           int ldap_count_entries( LDAP *ld, LDAPMessage *res );
+
+           int ldap_count_references( LDAP *ld, LDAPMessage *res );
+
+Parameters are:
+
+ld     The session handle.
+
+res    The search result, as obtained by a call to one of the synchro-
+       nous search routines or ldap_result().
+
+entry  The entry returned by a previous call to ldap_first_entry() or
+       ldap_next_entry().
+
+ref    The reference returned by a previous call to
+       ldap_first_reference() or ldap_next_reference().
+
+ldap_first_entry(), ldap_next_entry(), ldap_first_reference() and
+ldap_next_reference() all return NULL when no more entries or references
+
+
+
+Expires: 23 August 1999                                        [Page 48]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+exist in the result set to be returned.  NULL is also returned if an
+error occurs while stepping through the entries or references, in which
+case the error parameters in the session handle ld will be set to indi-
+cate the error.
+
+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 that
+remain in a chain if called with a message, entry or reference returned
+by ldap_first_message(), ldap_next_message(), ldap_first_entry(),
+ldap_next_entry(), ldap_first_reference(), ldap_next_reference().
+
+ldap_count_references() returns the number of references contained in a
+chain of search results. It can also be used to count the number of
+references that remain in a chain.
+
+
+15.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:
+
+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 inter-
+       nally 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().  The BerElement type itself is an opaque
+       structure that is described in more detail later in this document
+       in the section "Encoded ASN.1 Value Manipulation".
+
+
+
+Expires: 23 August 1999                                        [Page 49]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+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().  If mem
+       is NULL, nothing is done.
+
+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 error parameters in the session handle ld will be set to indi-
+cate the error.
+
+Both routines 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().
+
+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. 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() and friends to retrieve the associated values.
+
+
+15.3.  Retrieving the Values of an Attribute
+
+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.
+
+           char **ldap_get_values(
+                   LDAP            *ld,
+                   LDAPMessage     *entry,
+                   const char      *attr
+           );
+
+           struct berval **ldap_get_values_len(
+                   LDAP            *ld,
+                   LDAPMessage     *entry,
+                   const char      *attr
+           );
+
+           int ldap_count_values( char **vals );
+
+
+
+Expires: 23 August 1999                                        [Page 50]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+           int ldap_count_values_len( struct berval **vals );
+
+           void ldap_value_free( char **vals );
+
+           void ldap_value_free_len( struct berval **vals );
+
+Parameters are:
+
+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 (e.g., "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.
+
+ldap_get_values() and ldap_get_values_len() return NULL if no values are
+found for attr or if an error occurs.
+
+ldap_count_values() and ldap_count_values_len() 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.
+
+
+15.4.  Retrieving the name of an entry
+
+ldap_get_dn() is used to retrieve the name of an entry.
+ldap_explode_dn() and ldap_explode_rdn() are used to break up a name
+into its component parts. ldap_dn2ufn() 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 );
+
+
+
+
+Expires: 23 August 1999                                        [Page 51]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+           char *ldap_dn2ufn( const char *dn );
+
+Parameters are:
+
+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").
+
+ldap_get_dn() 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.  Note the
+format of the DNs returned is given by [4].
+
+ldap_explode_dn() 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().
+
+ldap_explode_rdn() 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().
+
+ldap_dn2ufn() converts the DN into the user friendly format described in
+[5]. The UFN returned is newly allocated space that should be freed by a
+call to ldap_memfree() when no longer in use.
+
+
+15.5.  Retrieving controls from an entry
+
+ldap_get_entry_controls() is used to extract LDAP controls from an
+entry.
+
+
+           int ldap_get_entry_controls(
+
+
+
+Expires: 23 August 1999                                        [Page 52]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+                   LDAP            *ld,
+                   LDAPMessage     *entry,
+                   LDAPControl     ***serverctrlsp
+           );
+
+Parameters are:
+
+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 ser-
+             verctrlsp is NULL, no controls are returned.
+
+ldap_get_entry_controls() returns an LDAP error code that indicates
+whether the reference could be successfully parsed (LDAP_SUCCESS if all
+goes well).
+
+
+
+15.6.  Parsing References
+
+ldap_parse_reference() 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:
+
+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
+
+
+
+Expires: 23 August 1999                                        [Page 53]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+             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 ser-
+             verctrlsp is NULL, no controls are returned.
+
+freeit       A boolean that determines whether the ref parameter is
+             disposed of or not.  Pass any non-zero value to have this
+             routine free ref after extracting the requested informa-
+             tion.  This is provided as a convenience; you can also use
+             ldap_msgfree() to free the result later.
+
+ldap_parse_reference() returns an LDAP error code that indicates whether
+the reference could be successfully parsed (LDAP_SUCCESS if all goes
+well).
+
+
+16.  Encoded ASN.1 Value Manipulation
+
+This section describes routines which may be used to encode and decode
+BER-encoded ASN.1 values, which are often used inside of control and
+extension values.
+
+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.
+
+
+16.1.  General
+
+           struct berval {
+                   unsigned long   bv_len;
+                   char            *bv_val;
+           };
+
+A struct berval contains a sequence of bytes and an indication of its
+length.  The bv_val is not necessarily zero-terminated.  bv_len must
+always be a nonnegative number.  Applications may allocate their own
+berval structures.
+
+As defined earlier, the BerElement  structure is an opaque structure:
+
+           typedef struct berelement BerElement;
+
+It contains not only a copy of the encoded value, but also state infor-
+mation used in encoding or decoding.  Applications cannot allocate their
+
+
+
+Expires: 23 August 1999                                        [Page 54]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+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 );
+
+ber_bvfree() 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 );
+
+ber_bvecfree() 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( const struct berval *bv );
+
+ber_bvdup() returns a copy of a berval.  The bv_val field in the
+returned berval points to a different area of memory than the bv_val
+field in the argument berval.  The NULL pointer is returned on error
+(e.g. out of memory).
+
+           void ber_free( BerElement *ber, int fbuf );
+
+ber_free() 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.
+
+
+16.2.  Encoding
+
+           BerElement *ber_alloc_t( int options );
+
+ber_alloc_t() 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 to be rearranged in tag and byte order or default values to be
+
+
+
+Expires: 23 August 1999                                        [Page 55]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+removed, 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 correctly and removing default values, DER out-
+put 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 ber_alloc_t().
+
+           int ber_printf( BerElement *ber, const char *fmt, ... )
+
+The ber_printf() routine 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 ele-
+ment. ber must be a pointer to a BerElement returned by ber_alloc_t().
+ber_printf() interprets and formats its arguments according to the for-
+mat string fmt.  ber_printf() 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 an int specifying the tag to override
+        the next element to be written to the ber.  This works across
+        calls.  The int value must contain the tag class, constructed
+        bit, and tag value.  For example, a tag of "[3]" for a con-
+        structed type is 0xA3.  All implementations must support tags
+        that fit in a single octet (i.e., where the tag value is less
+        than 32) and they may support larger tags.
+
+'b'     Boolean.  The next argument is an int, 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.
+
+'i'     Integer.  The next argument is an int, 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.
+
+'X'     Bitstring.  The next two arguments are a char * pointer to the
+        start of the bitstring, followed by an int 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.
+
+
+
+
+Expires: 23 August 1999                                        [Page 56]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+'n'     Null.  No argument is required.  An ASN.1 NULL element is out-
+        put.  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
+        an int with the length of the string.  The string may contain
+        null bytes and need not be 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' (null)
+        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 trailing '\0' (null) byte.  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 for-
+        mat character.
+
+'V'     Several octet strings.  A NULL-terminated array of 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 char-
+        acter 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 can-
+        not 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 subse-
+quent call to ber_printf() for that BerElement.  The same applies to the
+'[' and ']' format characters.
+
+
+
+Expires: 23 August 1999                                        [Page 57]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+Sequences and sets nest, and implementations of this API must maintain
+internal state to be able to properly calculate the lengths.
+
+           int ber_flatten( const BerElement *ber, struct berval **bvPtr );
+
+The ber_flatten routine 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 rou-
+tine 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 (i.e., -1 will be
+returned by ber_flatten() if this situation is exists).
+
+
+16.3.  Encoding Example
+
+The following is an example of encoding the following ASN.1 data type:
+
+      Example1Request ::= SEQUENCE {
+           s     OCTET STRING, -- must be printable
+           val1  INTEGER,
+           val2  [0] INTEGER DEFAULT 0
+      }
+
+
+      int encode_example1(const char *s,int val1,int val2,struct berval **bvPtr)
+      {
+           BerElement *ber;
+           int rc = -1;
+
+           ber = ber_alloc_t(LBER_USE_DER);
+
+           if (ber == NULL) return -1;
+
+           if (ber_printf(ber,"{si",s,val1) == -1) {
+                   goto done;
+           }
+
+           if (val2 != 0) {
+                   if (ber_printf(ber,"ti",0x80,val2) == -1) {
+                           goto done;
+                   }
+           }
+
+           if (ber_printf(ber,"}") == -1) {
+
+
+
+Expires: 23 August 1999                                        [Page 58]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+                   goto done;
+           }
+
+           rc = ber_flatten(ber,bvPtr);
+
+   done:
+           ber_free(ber,1);
+           return rc;
+      }
+
+
+16.4.  Decoding
+
+The following two symbols are available to applications.
+
+           #define LBER_ERROR   0xffffffffUL
+           #define LBER_DEFAULT 0xffffffffUL
+
+           BerElement *ber_init( const struct berval *bv );
+
+The ber_init function constructs a BerElement and returns a new BerEle-
+ment containing a copy of the data in the bv argument.  ber_init returns
+the NULL pointer on error.
+
+           unsigned long ber_scanf( BerElement *ber, const char *fmt, ... );
+
+The ber_scanf() routine 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().  ber_scanf interprets the bytes according to the format
+string fmt, and stores the results in its additional arguments.
+ber_scanf() returns LBER_ERROR on error, and a different value on suc-
+cess.
+
+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, zero-
+        terminated, and the pointer to the string is stored in the argu-
+        ment.  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 dis-
+        carded during the decoding.  This format cannot be used with
+        octet strings which could contain null bytes.
+
+
+
+Expires: 23 August 1999                                        [Page 59]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+'O'     Octet string.  A struct berval ** argument should be supplied,
+        which upon return points to an allocated struct berval contain-
+        ing the octet string and its length.  ber_bvfree() 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 an int should be supplied. The int 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.
+
+'i'     Integer.  A pointer to an int should be supplied. The int 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.  ber_scanf() will return an error if the integer can-
+        not be stored in an int.
+
+'B'     Bitstring.  A char ** argument should be supplied which will
+        point to the allocated bits, followed by an unsigned long *
+        argument, which will point to the length (in bits) of the bit-
+        string returned.  ldap_memfree 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 verified to have
+        a zero-length value and is skipped.  The tag is ignored.
+
+'v'     Several octet strings.  A char *** argument should be supplied,
+        which upon return points to an allocated NULL-terminated array
+        of char *'s containing the octet strings.  NULL is stored if the
+        sequence is empty.  ldap_memfree 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 con-
+        taining the octet strings and their lengths.  NULL is stored if
+        the sequence is empty. ber_bvecfree() 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
+
+
+
+Expires: 23 August 1999                                        [Page 60]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+        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.
+
+           unsigned long ber_peek_tag( BerElement *ber, unsigned long *lenPtr );
+
+ber_peek_tag() 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.
+
+           unsigned long ber_skip_tag( BerElement *ber, unsigned long *lenPtr );
+
+ber_skip_tag() 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 rou-
+tine 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.
+
+           unsigned long ber_first_element( BerElement *ber,
+                   unsigned long *lenPtr, char **opaquePtr );
+
+           unsigned long ber_next_element( BerElement *ber,
+                   unsigned long *lenPtr, char *opaque );
+
+ber_first_element() and ber_next_element() are used to traverse a SET,
+SET OF, SEQUENCE or SEQUENCE OF data value. ber_first_element() 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.
+ber_next_element() 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(), as shown in the example below.
+
+
+16.5.  Decoding Example
+
+The following is an example of decoding an ASN.1 data type:
+
+
+
+
+Expires: 23 August 1999                                        [Page 61]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+      Example2Request ::= SEQUENCE {
+           dn    OCTET STRING, -- must be printable
+           scope ENUMERATED { b (0), s (1), w (2) },
+           ali   ENUMERATED { n (0), s (1), f (2), a (3) },
+           size  INTEGER,
+           time  INTEGER,
+           tonly BOOLEAN,
+           attrs SEQUENCE OF OCTET STRING, -- must be printable
+           [0] SEQUENCE OF SEQUENCE {
+              type  OCTET STRING -- must be printable,
+              crit  BOOLEAN DEFAULT FALSE,
+              value OCTET STRING
+           } OPTIONAL }
+
+      #define TAG_CONTROL_LIST 0xA0L /* context specific cons 0 */
+
+      int decode_example2(struct berval *bv)
+      {
+           BerElement *ber;
+           unsigned long len, res;
+           int scope, ali, size, time, tonly;
+           char *dn = NULL, **attrs = NULL;
+           int i,rc = 0;
+
+           ber = ber_init(bv);
+           if (ber == NULL) {
+                   fputs("ERROR ber_init failed\n", stderr);
+                   return -1;
+           }
+
+           res = ber_scanf(ber,"{aiiiib{v}",&dn,&scope,&ali,
+                           &size,&time,&tonly,&attrs);
+
+           if (res == LBER_ERROR) {
+                   fputs("ERROR ber_scanf failed\n", stderr);
+                   ber_free(ber,1);
+                   return -1;
+           }
+
+           /* *** use dn */
+           ldap_memfree(dn);
+
+           for (i = 0; attrs != NULL && attrs[i] != NULL; i++) {
+                   /* *** use attrs[i] */
+                   ldap_memfree(attrs[i]);
+           }
+           ldap_memfree(attrs);
+
+
+
+
+Expires: 23 August 1999                                        [Page 62]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+           if (ber_peek_tag(ber,&len) == TAG_CONTROL_LIST) {
+                   char *opaque;
+                   unsigned long tag;
+
+                   for (tag = ber_first_element(ber,&len,&opaque);
+                        tag != LBER_DEFAULT;
+                        tag = ber_next_element (ber,&len,opaque)) {
+
+                           unsigned long ttag, tlen;
+                           char *type;
+                           int crit;
+                           struct berval *value;
+
+                           if (ber_scanf(ber,"{a",&type) == LBER_ERROR) {
+                                   fputs("ERROR cannot parse type\n", stderr);
+                                   break;
+                           }
+                           /* *** use type */
+                           ldap_memfree(type);
+
+                           ttag = ber_peek_tag(ber,&tlen);
+                           if (ttag == 0x01) {  /* boolean */
+                                   if (ber_scanf(ber,"b",
+                                                 &crit) == LBER_ERROR) {
+                                           fputs("ERROR cannot parse crit\n",
+                                               stderr);
+                                           rc = -1;
+                                           break;
+                                   }
+                           } else if (ttag == 0x04) { /* octet string */
+                                   crit = 0;
+                           } else {
+                                   fputs("ERROR extra field in controls\n",
+                                       stderr );
+                                   break;
+                           }
+
+                           if (ber_scanf(ber,"O}",&value) == LBER_ERROR) {
+                                   fputs("ERROR cannot parse value\n", stderr);
+                                   rc = -1;
+                                   break;
+                           }
+                           /* *** use value */
+                           ber_bvfree(value);
+                   }
+           }
+
+           ber_scanf(ber,"}");
+
+
+
+Expires: 23 August 1999                                        [Page 63]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+
+           ber_free(ber,1);
+
+           return rc;
+       }
+
+
+
+17.  Security Considerations
+
+LDAPv2 supports security through protocol-level authentication using
+clear-text passwords.  LDAPv3 adds support for SASL [8] (Simple Authen-
+tication Security Layer) methods.  LDAPv3 also supports operation over a
+secure transport layer using Transport Layer Security TLS [9].  Readers
+are referred to the protocol documents for discussion of related secu-
+rity considerations.
+
+Implementations of this API should be cautious when handling authentica-
+tion credentials.  In particular, keeping long-lived copies of creden-
+tials without the application's knowledge is discouraged.
+
+
+18.  Acknowledgements
+
+Many members of the IETF ASID and LDAPEXT working groups as well as
+members of the Internet at large have provided useful comments and
+suggestions that have been incorporated into this document.  Chris
+Weider deserves special mention for his contributions as co-author of
+earlier revisions of this document.
+
+The original material upon which this specification is based was sup-
+ported by the National Science Foundation under Grant No.  NCR-9416667.
+
+
+19.  Copyright
+
+Copyright (C) The Internet Society (1997-1999). All Rights Reserved.
+
+This document and translations of it may be copied and furnished to oth-
+ers, and derivative works that comment on or otherwise explain it or
+assist in its implementation may be prepared, copied, published and dis-
+tributed, in whole or in part, without restriction of any kind, provided
+that the above copyright notice and this paragraph are included on all
+such copies and derivative works.  However, this document itself may not
+be modified in any way, such as by removing the copyright notice or
+references to the Internet Society or other Internet organizations,
+except as needed for the  purpose of developing Internet standards in
+which case the procedures for copyrights defined in the Internet
+
+
+
+Expires: 23 August 1999                                        [Page 64]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+Standards process must be followed, or as required to translate it into
+languages other than English.
+
+The limited permissions granted above are perpetual and will not be
+revoked by the Internet Society or its successors or assigns.
+
+This document and the information contained herein is provided on an "AS
+IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK
+FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT
+LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT
+INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FIT-
+NESS FOR A PARTICULAR PURPOSE.
+
+
+20.  Bibliography
+
+[1]  The Directory: Selected Attribute Syntaxes.  CCITT, Recommendation
+     X.520.
+
+[2]  M. Wahl, A. Coulbeck, T. Howes, S. Kille, W. Yeong, C. Robbins,
+     "Lightweight Directory Access Protocol (v3): Attribute Syntax
+     Definitions", RFC 2252, December 1997.
+
+[3]  T. Howes, "The String Representation of LDAP Search Filters," RFC
+     2254, December 1997.
+
+[4]  M. Wahl, S. Kille, T. Howes, "Lightweight Directory Access Protocol
+     (v3): A UTF-8 String Representation of Distinguished Names", RFC
+     2253, December 1997.
+
+[5]  S. Kille, "Using the OSI Directory to Achieve User Friendly Nam-
+     ing," RFC 1781, March 1995.
+
+[6]  M. Wahl, T. Howes, S. Kille, "Lightweight Directory Access Protocol
+     (v3)", RFC 2251, December 1997.
+
+[7]  A. Herron, T. Howes, M. Wahl, C. Weider, A. Anantha, "LDAP Control
+     Extension for Server Side Sorting of Search Results", INTERNET-
+     DRAFT <draft-ietf-ldapext-sorting-01.txt>, 7 August 1998.
+
+[8]  J. Meyers, "Simple Authentication and Security Layer (SASL)", RFC
+     2222, October 1997.
+
+[9]  "Lightweight Directory Access Protocol (v3): Extension for Tran-
+     sport Layer Security", INTERNET-DRAFT <draft-ietf-ldapext-ldapv3-
+     tls-04.txt>, November 1998.
+
+[10] "UTF-8, a transformation format of Unicode and ISO 10646", RFC
+
+
+
+Expires: 23 August 1999                                        [Page 65]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+     2044, October 1996.
+
+[11] "IP Version 6 Addressing Architecture,", RFC 1884, December 1995.
+
+[12] "Character Mnemonics and Character Sets," RFC 1345, June 1992.
+
+[13] "Programming Languages - C", ANSI/ISO Standard 9899, revised 1997.
+
+
+21.  Authors' Addresses
+
+   Mark Smith (document editor)
+   Netscape Communications Corp.
+   501 E. Middlefield Rd., Mailstop MV068
+   Mountain View, CA 94043
+   USA
+   +1 650 937-3477
+   mcs@netscape.com
+
+   Tim Howes
+   Netscape Communications Corp.
+   501 E. Middlefield Rd., Mailstop MV068
+   Mountain View, CA 94043
+   USA
+   +1 650 937-3419
+   howes@netscape.com
+
+   Andy Herron
+   Microsoft Corp.
+   1 Microsoft Way
+   Redmond, WA 98052
+   USA
+   +1 425 882-8080
+   andyhe@microsoft.com
+
+   Mark Wahl
+   Innosoft International, Inc.
+   8911 Capital of Texas Hwy, Suite 4140
+   Austin, TX 78759
+   USA
+   +1 626 919 3600
+   Mark.Wahl@innosoft.com
+
+   Anoop Anantha
+   Microsoft Corp.
+   1 Microsoft Way
+   Redmond, WA 98052
+   USA
+
+
+
+Expires: 23 August 1999                                        [Page 66]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+   +1 425 882-8080
+   anoopa@microsoft.com
+
+
+22.  Appendix A - Sample C LDAP API Code
+
+   #include <stdio.h>
+   #include <ldap.h>
+
+   main()
+   {
+           LDAP            *ld;
+           LDAPMessage     *res, *e;
+           int             i, rc;
+           char            *a, *dn;
+           BerElement      *ptr;
+           char            **vals;
+
+           /* open an LDAP session */
+           if ( (ld = ldap_init( "dotted.host.name", LDAP_PORT )) == NULL )
+                   return 1;
+
+           /* authenticate as nobody */
+           if (( rc = ldap_simple_bind_s( ld, NULL, NULL )) != LDAP_SUCCESS ) {
+                   fprintf( stderr, "ldap_simple_bind_s: %s\n",
+                       ldap_err2string( rc ));
+                   ldap_unbind( ld );
+                   return 1;
+           }
+
+           /* search for entries with cn of "Babs Jensen", return all attrs  */
+           if (( rc = ldap_search_s( ld, "o=University of Michigan, c=US",
+               LDAP_SCOPE_SUBTREE, "(cn=Babs Jensen)", NULL, 0, &res ))
+               != LDAP_SUCCESS ) {
+                   fprintf( stderr, "ldap_search_s: %s\n",
+                       ldap_err2string( rc ));
+                   if ( res == NULL ) {
+                           ldap_unbind( ld );
+                           return 1;
+                   }
+           }
+
+           /* 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: %s\n", dn );
+
+
+
+Expires: 23 August 1999                                        [Page 67]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+                   ldap_memfree( dn );
+
+                   /* print each attribute */
+                   for ( a = ldap_first_attribute( ld, e, &ptr ); a != NULL;
+                       a = ldap_next_attribute( ld, e, ptr ) ) {
+                           printf( "\tattribute: %s\n", a );
+
+                           /* print each value */
+                           vals = ldap_get_values( ld, e, a );
+                           for ( i = 0; vals[i] != NULL; i++ ) {
+                                   printf( "\t\tvalue: %s\n", vals[i] );
+                           }
+                           ldap_value_free( vals );
+                           ldap_memfree( a );
+                   }
+                   if ( ptr != NULL ) {
+                           ber_free( ptr, 0 );
+                   }
+           }
+           /* free the search results */
+           ldap_msgfree( res );
+
+           /* close and free connection resources */
+           ldap_unbind( ld );
+
+           return 0;
+   }
+
+
+23.  Appendix B - Namespace Consumed By This Specification
+
+The following 2 prefixes are used in this specification to name func-
+tions:
+   ldap_
+   ber_
+
+The following 6 prefixes are used in this specification to name struc-
+tures, unions, and typedefs:
+   ldap
+   LDAP
+   PLDAP
+   ber
+   Ber
+   timeval
+
+The following 3 prefixes are used in this specification to name #defined
+macros:
+   LDAP
+
+
+
+Expires: 23 August 1999                                        [Page 68]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+   LBER_
+   mod_
+
+
+24.  Appendix C - Summary of Requirements for API Extensions
+
+As the LDAP protocol is extended, this C LDAP API will need to be
+extended as well.  For example, an LDAPv3 control extension has already
+been defined for server-side sorting of search results [7].  This appen-
+dix summarizes the requirements for extending this API.
+
+24.1.  Compatibility
+
+Extensions to this document should not, by default, alter the behavior
+of any of the APIs specified in this document.  If an extension option-
+ally changes the behavior of any existing C LDAP API function calls, the
+behavior change must be well documented.
+
+24.2.  Style
+
+Extensions to this API should follow the general style and naming con-
+ventions used in this document.  For example, function names should
+start with "ldap_" or "ber_" and consist entirely of lowercase letters,
+digits, and underscore ('_') characters.  More information can be found
+in the preceding appendix called "Namespace Consumed By This Specifica-
+tion."
+
+24.3.  Dependence on Externally Defined Types
+
+Extensions to this API should minimize dependencies on types and macros
+that are defined in system header files and generally use only intrinsic
+types that are part of the C language, types defined in this specifica-
+tion, or types defined in the extension document itself.
+
+24.4.  Compile Time Information
+
+Extensions to this API should conform to the requirements contained in
+the "Retrieving Information at Compile Time" section of this document.
+That is, extensions should define a macro of the form:
+
+   #define LDAP_API_FEATURE_x level
+
+so that applications can detect the presence or absense of the extension
+at compile time and also test the version or level of the extension pro-
+vided by an API implementation.
+
+
+
+
+
+
+Expires: 23 August 1999                                        [Page 69]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+24.5.  Runtime Information
+
+Extensions to this API should conform to the requirements contained in
+the "Retrieving Information During Execution" section of this document.
+That is, each extension should be given a character string name and that
+name should appear in the ldapai_extensions array field of the LDAPAPI-
+Info structure following a successful call to ldap_get_option() with an
+option parameter value of LDAP_OPT_API_INFO.  In addition, information
+about the extension should be available via a call to ldap_get_option()
+with an option parameter value of LDAP_OPT_API_FEATURE_INFO.
+
+24.6.  Values Used for Session Handle Options
+
+Extensions to this API that add new session options (for use with the
+ldap_get_option() and ldap_set_option() functions) should meet the
+requirements contained in the last paragraph of the "LDAP Session Handle
+Options" section of this document.  Specifically, standards track docu-
+ments MUST use values for option macros that are between 0x1000 and
+0x3FFF inclusive and private and experimental extensions MUST use values
+for the option macros that are between 0x4000 and 0x7FFF inclusive.
+
+
+25.  Appendix D - Known Incompatibilities with RFC 1823
+
+This appendix lists known incompatibilities between this API specifica-
+tion and the one contained in RFC 1823, beyond the additional API func-
+tions added in support of LDAPv3.
+
+
+25.1.  Opaque LDAP Structure
+
+In RFC 1823, some fields in the LDAP structure were exposed to applica-
+tion programmers.  To provide a cleaner interface and to make it easier
+for implementations to evolve over time without sacrificing binary com-
+patibility with older applications, the LDAP structure is now entirely
+opaque.  The new ldap_set_option() and ldap_get_option() calls can be
+used to manipulate per-session and global options.
+
+
+25.2.  Additional Error Codes
+
+The following new error code macros were introduced to support LDAPv3:
+   LDAP_REFERRAL
+   LDAP_ADMINLIMIT_EXCEEDED
+   LDAP_UNAVAILABLE_CRITICAL_EXTENSION
+   LDAP_CONFIDENTIALITY_REQUIRED
+   LDAP_SASL_BIND_IN_PROGRESS
+   LDAP_AFFECTS_MULTIPLE_DSAS
+
+
+
+Expires: 23 August 1999                                        [Page 70]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+   LDAP_CONNECT_ERROR
+   LDAP_NOT_SUPPORTED
+   LDAP_CONTROL_NOT_FOUND
+   LDAP_NO_RESULTS_RETURNED
+   LDAP_MORE_RESULTS_TO_RETURN
+   LDAP_CLIENT_LOOP
+   LDAP_REFERRAL_LIMIT_EXCEEDED
+
+
+25.3.  Freeing of String Data with ldap_memfree()
+
+All strings received from the API (e.g., those returned by the
+ldap_get_dn() or ldap_dn2ufn() functions) should be freed by calling
+ldap_memfree() not free().  RFC 1823 did not define an ldap_memfree()
+function.
+
+
+25.4.  Changes to ldap_result()
+
+The meaning of the all parameter to ldap_result has changed slightly.
+Nonzero values from RFC 1823 correspond to LDAP_MSG_ALL (0x01).  There
+is also a new possible value, LDAP_MSG_RECEIVED (0x02).
+
+The result type LDAP_RES_MODDN is now returned where RFC 1823 returned
+LDAP_RES_MODRDN.  The actual value for these two macros is the same
+(0x6D).
+
+
+25.5.  Changes to ldap_first_attribute() and ldap_next_attribute
+
+Each non-NULL return value should be freed by calling ldap_memfree()
+after use.  In RFC 1823, these two functions returned a pointer to a
+per-session buffer, which was not very thread-friendly.
+
+After the last call to ldap_first_attribute() or ldap_next_attribute(),
+the value set in the ptr parameter should be freed by calling ber_free(
+ptr, 0 ).  RFC 1823 did not mention that the ptr value should be freed.
+
+The type of the ptr parameter was changed from void * to BerElement *.
+
+
+25.6.  Changes to ldap_modrdn() and ldap_modrdn_s() Functions
+
+In RFC 1823, the ldap_modrdn() and ldap_modrdn_s() functions include a
+parameter called deleteoldrdn.  This does not match the great majority
+of implementations, so in this specification the deleteoldrdn parameter
+was removed from ldap_modrdn() and ldap_modrdn_s().  Two additional
+functions that support deleteoldrdn and are widely implemented as well
+
+
+
+Expires: 23 August 1999                                        [Page 71]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+were added to this specification: ldap_modrdn2() and ldap_modrdn2_s().
+
+
+25.7.  API Specification Clarified
+
+RFC 1823 left many things unspecified, including behavior of various
+memory disposal functions when a NULL pointer is presented, requirements
+for header files, values of many macros, and so on.  This specification
+is more complete and generally tighter than the one in RFC 1823.
+
+
+25.8.  Deprecated Functions
+
+A number of functions that are in RFC 1823 are labeled as "deprecated"
+in this specification.  In most cases, a replacement that provides
+equivalent functionality has been defined.  The deprecated functions
+are:
+
+   ldap_bind()
+           Use ldap_simple_bind() or ldap_sasl_bind() instead.
+
+   ldap_bind_s()
+           Use ldap_simple_bind_s() or ldap_sasl_bind_s() instead.
+
+   ldap_kerberos_bind() and ldap_kerberos_bind_s()
+           No equivalent functions are provided.
+
+   ldap_modrdn() and ldap_modrdn2()
+           Use ldap_rename() instead.
+
+   ldap_modrdn_s() and ldap_modrdn2_s()
+           Use ldap_rename_s() instead.
+
+   ldap_open()
+           Use ldap_init() instead.
+
+   ldap_perror()
+           Use ldap_err2string() instead.
+
+   ldap_result2error()
+           Use ldap_parse_result() instead.
+
+
+26.  Appendix E - Changes Made Since Last Document Revision
+
+The previous version of this document was draft-ietf-ldapext-ldap-c-
+api-01.txt, dated 7 August 1998.  This appendix lists all of the changes
+made to that document to produce the one you are reading now.
+
+
+
+Expires: 23 August 1999                                        [Page 72]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+26.1.  API Changes
+
+   General: added the 'const' keyword to function prototypes where
+   appropriate.
+
+   Added two new sections that specify additional features and require-
+   ments for API implementors:
+      "Header File Requirements"
+      "A Client Control That Governs Referral Processing"
+
+   "Retrieving Information at Compile Time" section: added
+   LDAP_VERSION_MIN, LDAP_VERSION_MAX, LDAP_VENDOR_NAME, and
+   LDAP_VENDOR_VERSION macros.  Corrected LDAP_API_VERSION example code
+   to use >= instead of >.  Added note about what value to use for
+   LDAP_API_VERSION prior to publication of this draft as an RFC (2000 +
+   draft revision number).
+
+   "Retrieving Information During Execution" section: added
+   LDAP_API_INFO_VERSION macro and clarified the text to explain the
+   behavior when there is a mismatch between LDAPAPIInfo structure ver-
+   sions.  Added LDAP_OPT_API_FEATURE_INFO to allow applications to
+   retrieve version information about API extended features.
+
+   "LDAP Session Handle Options" section:  Added macro definitions for
+   LDAP_OPT_ON and LDAP_OPT_OFF and changed the "invalue" type for
+   Boolean options from "int" to "void *".  For consistency, we now
+   require that applications dispose of "char *" and "LDAPControl *"
+   values that are returned.  Added note about which option value ranges
+   are to be used for various purposes.
+
+   "Closing the session" section: added new function ldap_unbind_ext()
+   to allow controls to be used with unbind operations.
+
+   "Searching" section: added requirement that *res be set to NULL by
+   synchronous calls that fail to return any results.
+
+   "Modifying the Name of an Entry" section: added function prototypes
+   for ldap_modrdn2() and ldap_modrdn2_s() and corrected the ones for
+   ldap_modrdn() and ldap_modrdn_s() to match the most widely imple-
+   mented APIs.
+
+   "Obtaining Results and Peeking Inside LDAP Messages" section: added
+   requirement that "*res" be set to NULL when ldap_result() fails to
+   return any results.  Added requirement that ldap_msgfree() accept a
+   NULL "res" parameter.
+
+   "Stepping Through the Attributes of an Entry" section:  added
+   requirement that ldap_memfree() accept a NULL "mem" parameter.
+
+
+
+Expires: 23 August 1999                                        [Page 73]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+   "Encoded ASN.1 Value Manipulation - Encoding" section: added note
+   that implementations may support tags with a value larger than 32
+   (but this is not required).
+
+   "Encoded ASN.1 Value Manipulation - Decoding" section: changed the
+   LBER_ERROR and LBER_DEFAULT macros to end in "UL" instead of "L"
+   since all the functions that return these two values return an
+   "unsigned long" value.
+
+
+26.2.  Editorial changes
+
+
+   Removed section: "Appendix - Outstanding Issues."
+
+   Added two new editorial sections:
+      "Appendix - Summary of Requirements for API Extensions"
+      "Appendix - Known Incompatibilities with RFC 1823".
+
+   General: replaced all occurrences of "LDAP C API" with "C LDAP API"
+   for consistency.
+
+   "Status of Memo" section: added a statement that this document is in
+   full conformance with all provisions of Section 10 of RFC2026.  Also
+   revised the text about the Internet Draft current and shadow direc-
+   tories to match the latest I-D guidelines.
+
+   Document authors: removed Chris Weider from the list of authors (at
+   his own request) and added an explicit mention of him in the "Ack-
+   nowledgements" section.  Updated Mark Wahl's company affiliation in
+   document preface.  Added "(document editor)" after Mark Smith's name
+   in the "Authors' Addresses" section.
+
+   Copyright: updated the year to 1999.
+
+   "Introduction" section: expanded the sentence that mentioned the sam-
+   ple code appendix to mention all of the appendices.
+
+   "Overview of LDAP API Use" section: numbered the four simple steps
+   for using the API. Added mention of the referrals client control.
+   Clarified the text on character sets.  Replaced mention of
+   ldap_bind() with ldap_sasl_bind() because the former is deprecated.
+   Added note that this API is designed for use in environments where
+   the 'int' type is at least 32 bits in size.
+
+   "Common Data Structures" section: added definition of BerElement so
+   it is defined before it is used.  Added reference back to "Header
+   File Requirements" for "struct timeval" related considerations.
+
+
+
+Expires: 23 August 1999                                        [Page 74]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+   "Initializing an LDAP Session" section: moved note about ldap_open()
+   attempting to make a server connection closer to the ldap_open()
+   function prototype.  Added note that using literal IPv6 addresses in
+   the "hostname" parameter is not yet supported.
+
+   "LDAP Session Handle Options" section: replaced one instance of
+   "Formerly" with "In RFC 1823."  Added note about inheritance of
+   options when automatic referral following is enabled.  Added
+   LDAP_OPT_API_INFO and LDAP_OPT_API_FEATURE_INFO for completeness (not
+   previously included in this section).  Replaced erroneous references
+   to the "Using Controls" section with references to the "Working With
+   Controls" section.  In the text describing the LDAP_OPT_HOST_NAME
+   option, added a reference to the "hostname" parameter of ldap_init()
+   for the syntax of the option value.  Clarified that ldap_set_option()
+   makes a copy of the "invalue" data.
+
+   "Working With Controls" section: added a note to remind the reader
+   that server controls that are marked critical should not be used with
+   unbind and abandon operations since those two operations have no
+   server response.
+
+   "Closing the session" section: made it clear that all open connec-
+   tions associated with a session handle are closed when any of the
+   unbind API functions are called.
+
+   "Searching" section: added note that only a subset of the filter
+   functionality is available when communicating with an LDAPv2 server.
+   Clarified text to explain when a local timeout is used and when it is
+   not.
+
+   "Abandoning An Operation" section: removed some redundant text from
+   the paragraph that explains the differences between ldap_abandon()
+   and ldap_abandon_ext().
+
+   "Obtaining Results and Peeking Inside LDAP Messages" section: clari-
+   fied that ldap_result() only returns messages for one request at a
+   time.
+
+   "Handling Errors and Parsing Results" section: replace a few
+   occurrences of LDAPResult with LDAPMessage (there is no type called
+   LDAPResult).  Changed the names of the "resultoidp" and "resultdatap"
+   parameters to "retoidp" and "retdatap" to avoid confusion with LDAP
+   result messages.
+
+   "Stepping Through a List of Entries or References" section: added "or
+   References" to the section name to better reflect its contents.
+   Added missing description of "ref" parameter.  Added mention of
+   ldap_first_reference() and ldap_next_reference() in sentence about
+
+
+
+Expires: 23 August 1999                                        [Page 75]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+   function return values.
+
+   "Stepping Through the Attributes of an Entry" section:  added forward
+   reference for BerElement type.
+
+   "Parsing References" section: in the description of the "ref" parame-
+   ter, changed the phrase "these routines" to the more accurate "this
+   routine."
+
+   "Encoded ASN.1 Value Manipulation - General" section: changed text to
+   make sense given that the definition of BerElement now appears first
+   in the "Common Data Structures" section.
+
+   "Encoded ASN.1 Value Manipulation - Encoding" section: Changed the
+   style of function prototypes to better match the rest of the docu-
+   ment.  Corrected a typo in the ber_bvdup() description ("as the"
+   replaced with "than the").  Changed "null" to "NULL" where appropri-
+   ate to be consistent with use elsewhere in the document.  Removed
+   mention of sequences from the discussion of the LBER_USE_DER option.
+   Fixed some truncated sentences (by adding some missing '\' characters
+   to the nroff document source).
+
+   "Encoded ASN.1 Value Manipulation - Encoding Example" section:  sim-
+   plified the error handling in the example code through the use of a
+   'goto' statement.
+
+   "Encoded ASN.1 Value Manipulation - Decoding" section: Changed the
+   style of function prototypes to better match the rest of the docu-
+   ment.  Changed "null" to "NULL" and "null-terminated" to "zero-
+   terminated" where appropriate to be consistent with use elsewhere in
+   the document.  Fixed a typo (the text now says "an allocated" instead
+   of "a allocated.").  Clarified the description of the 'n' format
+   character for ber_scanf().
+
+   "Encoded ASN.1 Value Manipulation - Decoding Example" section:
+   changed code to not define a macro that begins with "LDAP" since that
+   prefix is reserved for the API.  Removed an extra 'i' from the format
+   string used in the first call to ber_scanf().  Changed error report-
+   ing code to send messages to stderr instead of stdout.  Changed
+   declaration of "res" local variable from "int" to "unsigned long" and
+   corrected one test of the ber_scanf() return value to test against
+   LBER_ERROR instead of -1.  Fixed improperly rendered strings (by
+   adding '\' characters to the nroff source for this document so that
+   '\t' and '\n' are correctly rendered).
+
+   "Acknowledgements" section: added the mention of Chris Weider.
+   Rephrased the text that gives credit to the National Science Founda-
+   tion (it now says "The original material upon which this
+
+
+
+Expires: 23 August 1999                                        [Page 76]
+\f
+C LDAP API        C LDAP Application Program Interface  23 February 1999
+
+
+   specification is based was supported by ..." instead of "This origi-
+   nal material upon which this revision is based was based upon work
+   supported by ..."
+
+   In the "Bibliography" section:  Added a reference to RFC 1345 and
+   ANSI/ISO C.  Updated the LDAPv3 TLS and Sorting references to point
+   to the latest revisions of those documents.
+
+   "Appendix - Sample C LDAP API Code": added #include <stdio.h> to the
+   sample code.  Changed the code to demonstrate good error handling by
+   freeing all memory and calling ldap_unbind() before returning.
+   Replaced calls to exit() with return statements.  Fixed improperly
+   rendered strings (by adding '\' characters to the nroff source for
+   this document so that '\t' and '\n' are correctly rendered).
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+Expires: 23 August 1999                                        [Page 77]
+\f