# Module Ldap_ooclient

    module Ldap_ooclient: sig .. end

an object oriented ldap client interface

## Basic Data Types

    type op = string * string list

the type of an operation, eg. `("cn", ["foo";"bar"])`

    type op_lst = op list

    type referral_policy = [ `FOLLOW | `RETURN ]

The policy the client should take when it encounteres a referral. This is currently not used

    type changetype = [ `ADD | `DELETE | `MODDN | `MODIFY | `MODRDN ]

The change type of an ldapentry. This controls some aspects of it's behavior

## Local Representation of LDAP Objects

    class type ldapentry_t = object .. end

The base type of an ldap entry represented in memory.

    class ldapentry : object .. end

this object represents a remote object within local memory.

## Miscallaneous

    val format_entry : < attributes : string list; dn : string; get_value : string -> string list;
             .. > ->
           unit

toplevel formatter for ldapentry, prints the whole entry with a nice structure. Each attribute is in the correct syntax to be copied and pasted into a modify operation.

    val format_entries : < attributes : string list; dn : string; get_value : string -> string list;
             .. >
           list -> unit

format lists of entries, in this case only print the dn

    type changerec = [ `Addition of ldapentry
           | `Delete of string
           | `Modification of
               string * (Ldap_types.modify_optype * string * string list) list
           | `Modrdn of string * int * string ]

The type of an ldap change record, used by extended LDIF

## Communication with Ldap_funclient

See `Ldap_funclient`

    val to_entry : [< `Entry of Ldap_types.search_result_entry | `Referral of string list ] ->
           ldapentry

given a search_result_entry as returned by ldap_funclient, produce an ldapentry containing either the entry, or the referral object

    val of_entry : ldapentry -> Ldap_types.search_result_entry

given an ldapentry as returned by ldapcon, or constructed manually, produce a search_result_entry suitable for ldap_funclient, or ldap_funserver.

## Interacting with LDAP Servers

    class ldapcon : ?connect_timeout:int -> ?referral_policy:[> `RETURN ] -> ?version:int -> string list -> object .. end

This class abstracts a connection to an LDAP server (or servers), an instance will be connected to the server you specify and can be used to perform operations on that server.

## Iterators Over Streams of ldapentry Objects

    val iter : (ldapentry -> unit) ->
           (?abandon:bool -> unit -> ldapentry) -> unit

given a source of ldapentry objects (unit -> ldapentry), such as the return value of ldapcon#search_a, apply f (first arg) to each entry See List.iter

    val rev_map : (ldapentry -> 'a) ->
           (?abandon:bool -> unit -> ldapentry) -> 'a list

given a source of ldapentry objects (unit -> ldapentry), such as the return value of ldapcon#search_a apply f (first arg) to each entry in reverse, and return a list containing the result of each application. See List.map

    val map : (ldapentry -> 'a) ->
           (?abandon:bool -> unit -> ldapentry) -> 'a list

same as rev_map, but does it in order

    val fold : (ldapentry -> 'a -> 'a) ->
           'a -> (?abandon:bool -> unit -> ldapentry) -> 'a

given a source of ldapentry objects (unit -> ldapentry), such as the return value of ldapcon#search_a compute (f eN ... (f e2 (f e1 intial))) see List.fold_right.

## Schema Aware ldapentry Derivatives

### General Schema Aware Entry

`Ldap_ooclient.scldapentry`, A schema aware derivative of `Ldap_ooclient.ldapentry`. It contains an rfc2252 schema checker, and given the database schema, it can be used to garentee that operations performed in memory are valid against a standards compliant database. It has numerious uses, translation between two databases with different schemas an example of where it finds natural usage. For an example application

    module OrdOid: sig .. end

an ordered oid type, for placing oids in sets

    module Setstr: sig .. end

A set of Oids

    type scflavor =

`|` | `Optimistic` | `(*` | Add missing attributes to make the object consistant, or add objectclasses in order to make illegal attribues legal | `*)`
`|` | `Pessimistic` | `(*` | Delete objectclasses which must attributes which are missing, and delete illegal attributes. | `*)`

The type of schema checking to perform in `Ldap_ooclient.scldapentry`. Normally this is picked automatically, however it can be overridden in some cases.

    val attrToOid : Ldap_schemaparser.schema ->
           Ldap_schemaparser.Lcstring.t -> Ldap_schemaparser.Oid.t

given a name of an attribute name (canonical or otherwise), return its oid

- Raises `Invalid_attribute` If the attribute is not found in the schema.

    val oidToAttr : Ldap_schemaparser.schema -> Ldap_schemaparser.Oid.t -> string

given the oid of an attribute, return its canonical name

- Raises `Invalid_attribute` If the attribute is not found in the schema.

    val ocToOid : Ldap_schemaparser.schema ->
           Ldap_schemaparser.Lcstring.t -> Ldap_schemaparser.Oid.t

given a name of an objectclass (canonical or otherwise), return its oid.

- Raises `Invalid_objectclass` If the objectclass is not found in the schema.

    val oidToOc : Ldap_schemaparser.schema -> Ldap_schemaparser.Oid.t -> string

given the oid of an objectclass, return its canonical name

- Raises `Invalid_objectclass` If the objectclass is not found in the schema.

    val getOc : Ldap_schemaparser.schema ->
           Ldap_schemaparser.Lcstring.t -> Ldap_schemaparser.objectclass

get an objectclass structure by one of its names (canonical or otherwise, however getting it by canonical name is currently much faster)

- Raises `Invalid_objectclass` If the objectclass is not found in the schema.

    val getAttr : Ldap_schemaparser.schema ->
           Ldap_schemaparser.Lcstring.t -> Ldap_schemaparser.attribute

get an attr structure by one of its names (canonical or otherwise, however getting it by canonical name is currently much faster)

- Raises `Invalid_attribute` If the attribute is not found in the schema.

    val equateAttrs : Ldap_schemaparser.schema ->
           Ldap_schemaparser.Lcstring.t -> Ldap_schemaparser.Lcstring.t -> bool

equate attributes by oid. This allows non canonical names to be handled correctly, for example "uid" and "userID" are actually the same attribute.

- Raises `Invalid_attribute` If either attribute is not found in the schema.

    exception Invalid_objectclass of string

    exception Invalid_attribute of string

    exception Single_value of string

    exception Objectclass_is_required

    class scldapentry : Ldap_schemaparser.schema -> object .. end

## Schema Aware Entry for Account Managment

A derivative of `Ldap_ooclient.scldapentry` which includes abstractions for managing user accounts in the directory. This class is experimantal, and may be drastically changed in the next version. As with all experimental code, use with caution. A few of its features.

- Loosely dependant attributes: Many attributes are derived from others via a function. ldapaccount allows you to codify that relationship by providing an attribute generator (`Ldap_ooclient.generator`) for the attribute, which will be used to derive it's value except in the case that it is specified explicitly
- Attribute and Generator Grouping: via the service abstraction. Allows you to group attributes together with generators and default values in interesting ways. You can then assign the whole grouping a name, and refer to it by that name. See `Ldap_ooclient.service`
- Difference Based: Service operations are difference based, all applications of service operations compute the delta between the current object, and what the service requires. The minumum set of changes necessary to satisfy the service are applied to the object.
- Idempotentcy: As a result of being difference based, Service operations are itempotent. For example, adding a service twice has no effect on the object. It will not queue changes for modification to the directory, and it will not change the object in memory. Deleting a service twice has no effect...etc

    type generator = {

`` | `gen_name : `string`;` | `(*` | The name of the generator, this should also be its key in the hashtbl | `*)`
`` | `required : `string list`;` | `(*` | A list of names of attributes which are required by this generator. The names need not be canonical. | `*)`
`` | `genfun : `ldapentry_t -> string list`;` | `(*` | A function which returns a list of values for the attribute, given the entire object. | `*)`

`}`

The structure of a generator

    type service = {

`` | `svc_name : `string`;` | `(*` | The name of the service, should also be its key in the hashtbl. | `*)`
`` | `static_attrs : `(string * string list) list`;` | `(*` | A list of attributes and values which must be present for the service to be satisfied. | `*)`
`` | `generate_attrs : `string list`;` | `(*` | A list of attributes to generate. | `*)`
`` | `depends : `string list`;` | `(*` | A list of services on which this service depends. | `*)`

`}`

The structure of a service

    type generation_error =

`|` | `Missing_required of `string list``
`|` | `Generator_error of `string``

The type of error raised by attribute generators

    exception No_generator of string

You've asked it to generate an attribute (in a service) which doesn't have a generator

    exception Generation_failed of generation_error

Generator has failed because of some kind of error

    exception No_service of string

The service you're talking about doesn't exist

    exception Service_dep_unsatisfiable of string

A service which the one you tried to add depends on doesn't exists

    exception Generator_dep_unsatisfiable of string * string

Your generator depends on an attribute which isn't in the schema

    exception Cannot_sort_dependancies of string list

You have detached cycles in your generator dependancy lists

    class ldapaccount : Ldap_schemaparser.schema -> (string, generator) Stdlib.Hashtbl.t -> (string, service) Stdlib.Hashtbl.t -> object .. end