diff --git a/Ldap-Asn1-FromAsn1.html b/Ldap-Asn1-FromAsn1.html
new file mode 100644
index 0000000..1375283
--- /dev/null
+++ b/Ldap-Asn1-FromAsn1.html
@@ -0,0 +1,93 @@
+
Ldap.Asn1.FromAsn1 Documentation class FromAsn1 a where Source
Instances
FromAsn1 LdapOid Source LDAPOID ::= OCTET STRING -- Constrained to <numericoid>
+ FromAsn1 LdapString Source LDAPString ::= OCTET STRING -- UTF-8 encoded,
+ FromAsn1 Uri Source URI ::= LDAPString
+ FromAsn1 ReferralUris Source Referral ::= SEQUENCE SIZE (1..MAX) OF uri URI
+ FromAsn1 LdapDn Source LDAPDN ::= LDAPString
+ FromAsn1 PartialAttribute Source PartialAttribute ::= SEQUENCE {
+ type AttributeDescription,
+ vals SET OF value AttributeValue }
+ FromAsn1 AttributeValue Source AttributeValue ::= OCTET STRING
+ FromAsn1 AttributeDescription Source AttributeDescription ::= LDAPString
+ FromAsn1 LdapResult Source LDAPResult ::= SEQUENCE {
+ resultCode ENUMERATED {
+ success (0),
+ operationsError (1),
+ protocolError (2),
+ timeLimitExceeded (3),
+ sizeLimitExceeded (4),
+ compareFalse (5),
+ compareTrue (6),
+ authMethodNotSupported (7),
+ strongerAuthRequired (8),
+ -- 9 reserved --
+ referral (10),
+ adminLimitExceeded (11),
+ unavailableCriticalExtension (12),
+ confidentialityRequired (13),
+ saslBindInProgress (14),
+ noSuchAttribute (16),
+ undefinedAttributeType (17),
+ inappropriateMatching (18),
+ constraintViolation (19),
+ attributeOrValueExists (20),
+ invalidAttributeSyntax (21),
+ -- 22-31 unused --
+ noSuchObject (32),
+ aliasProblem (33),
+ invalidDNSyntax (34),
+ -- 35 reserved for undefined isLeaf --
+ aliasDereferencingProblem (36),
+ -- 37-47 unused --
+ inappropriateAuthentication (48),
+ invalidCredentials (49),
+ insufficientAccessRights (50),
+ busy (51),
+ unavailable (52),
+ unwillingToPerform (53),
+ loopDetect (54),
+ -- 55-63 unused --
+ namingViolation (64),
+ objectClassViolation (65),
+ notAllowedOnNonLeaf (66),
+ notAllowedOnRDN (67),
+ entryAlreadyExists (68),
+ objectClassModsProhibited (69),
+ -- 70 reserved for CLDAP --
+ affectsMultipleDSAs (71),
+ -- 72-79 unused --
+ other (80),
+ ... },
+ matchedDN LDAPDN,
+ diagnosticMessage LDAPString,
+ referral [3] Referral OPTIONAL }
+ FromAsn1 PartialAttributeList Source PartialAttributeList ::= SEQUENCE OF partialAttribute PartialAttribute
+ FromAsn1 ProtocolServerOp Source BindResponse ::= [APPLICATION 1] SEQUENCE {
+ COMPONENTS OF LDAPResult,
+ serverSaslCreds [7] OCTET STRING OPTIONAL }
+ SearchResultEntry ::= [APPLICATION 4] SEQUENCE {
+ objectName LDAPDN,
+ attributes PartialAttributeList }
+ SearchResultDone ::= [APPLICATION 5] LDAPResult
+ ModifyResponse ::= [APPLICATION 7] LDAPResult
+ AddResponse ::= [APPLICATION 9] LDAPResult
+ DelResponse ::= [APPLICATION 11] LDAPResult
+ CompareResponse ::= [APPLICATION 15] LDAPResult
+ FromAsn1 Id Source MessageID ::= INTEGER (0 .. maxInt)
+ FromAsn1 op => FromAsn1 (LdapMessage op) Source LDAPMessage ::= SEQUENCE {
+ messageID MessageID,
+ protocolOp CHOICE {
+ bindRequest BindRequest,
+ bindResponse BindResponse,
+ unbindRequest UnbindRequest,
+ searchRequest SearchRequest,
+ searchResEntry SearchResultEntry,
+ searchResDone SearchResultDone,
+ searchResRef SearchResultReference,
+ addRequest AddRequest,
+ addResponse AddResponse,
+ ... },
+ controls [0] Controls OPTIONAL }
+ (FromAsn1 a, FromAsn1 b) => FromAsn1 (a, b) Source
\ No newline at end of file
diff --git a/Ldap-Asn1-ToAsn1.html b/Ldap-Asn1-ToAsn1.html
new file mode 100644
index 0000000..a5742e0
--- /dev/null
+++ b/Ldap-Asn1-ToAsn1.html
@@ -0,0 +1,116 @@
+Ldap.Asn1.ToAsn1 Documentation class ToAsn1 a where Source
Instances
ToAsn1 LdapOid Source LDAPOID ::= OCTET STRING -- Constrained to <numericoid>
+ ToAsn1 LdapString Source LDAPString ::= OCTET STRING -- UTF-8 encoded
+ ToAsn1 RelativeLdapDn Source RelativeLDAPDN ::= LDAPString -- Constrained to <name-component>
+ ToAsn1 LdapDn Source LDAPDN ::= LDAPString -- Constrained to <distinguishedName>
+ ToAsn1 PartialAttribute Source PartialAttribute ::= SEQUENCE {
+ type AttributeDescription,
+ vals SET OF value AttributeValue }
+ ToAsn1 Attribute Source Attribute ::= PartialAttribute(WITH COMPONENTS {
+ ...,
+ vals (SIZE(1..MAX))})
+ ToAsn1 AssertionValue Source AssertionValue ::= OCTET STRING
+ ToAsn1 AttributeValueAssertion Source AttributeValueAssertion ::= SEQUENCE {
+ attributeDesc AttributeDescription,
+ assertionValue AssertionValue }
+ ToAsn1 AttributeValue Source AttributeValue ::= OCTET STRING
+ ToAsn1 AttributeDescription Source AttributeDescription ::= LDAPString
+ ToAsn1 Control Source Control ::= SEQUENCE {
+ controlType LDAPOID,
+ criticality BOOLEAN DEFAULT FALSE,
+ controlValue OCTET STRING OPTIONAL }
+ ToAsn1 Controls Source Controls ::= SEQUENCE OF control Control
+ ToAsn1 AttributeList Source AttributeList ::= SEQUENCE OF attribute Attribute
+ ToAsn1 AttributeSelection Source AttributeSelection ::= SEQUENCE OF selector LDAPString
+ ToAsn1 MatchingRuleId Source MatchingRuleId ::= LDAPString
+ ToAsn1 MatchingRuleAssertion Source MatchingRuleAssertion ::= SEQUENCE {
+ matchingRule [1] MatchingRuleId OPTIONAL,
+ type [2] AttributeDescription OPTIONAL,
+ matchValue [3] AssertionValue,
+ dnAttributes [4] BOOLEAN DEFAULT FALSE }
+ ToAsn1 SubstringFilter Source SubstringFilter ::= SEQUENCE {
+ type AttributeDescription,
+ substrings SEQUENCE SIZE (1..MAX) OF substring CHOICE {
+ initial [0] AssertionValue, -- can occur at most once
+ any [1] AssertionValue,
+ final [2] AssertionValue } -- can occur at most once
+ }
+ ToAsn1 Filter Source Filter ::= CHOICE {
+ and [0] SET SIZE (1..MAX) OF filter Filter,
+ or [1] SET SIZE (1..MAX) OF filter Filter,
+ not [2] Filter,
+ equalityMatch [3] AttributeValueAssertion,
+ substrings [4] SubstringFilter,
+ greaterOrEqual [5] AttributeValueAssertion,
+ lessOrEqual [6] AttributeValueAssertion,
+ present [7] AttributeDescription,
+ approxMatch [8] AttributeValueAssertion,
+ extensibleMatch [9] MatchingRuleAssertion,
+ ... }
+ ToAsn1 AuthenticationChoice Source AuthenticationChoice ::= CHOICE {
+ simple [0] OCTET STRING,
+ ... }
+ ToAsn1 ProtocolClientOp Source BindRequest ::= [APPLICATION 0] SEQUENCE {
+ version INTEGER (1 .. 127),
+ name LDAPDN,
+ authentication AuthenticationChoice }
+ UnbindRequest ::= [APPLICATION 2] NULL
+ SearchRequest ::= [APPLICATION 3] SEQUENCE {
+ baseObject LDAPDN,
+ scope ENUMERATED {
+ baseObject (0),
+ singleLevel (1),
+ wholeSubtree (2),
+ ... },
+ derefAliases ENUMERATED {
+ neverDerefAliases (0),
+ derefInSearching (1),
+ derefFindingBaseObj (2),
+ derefAlways (3) },
+ sizeLimit INTEGER (0 .. maxInt),
+ timeLimit INTEGER (0 .. maxInt),
+ typesOnly BOOLEAN,
+ filter Filter,
+ attributes AttributeSelection }
+ ModifyRequest ::= [APPLICATION 6] SEQUENCE {
+ object LDAPDN,
+ changes SEQUENCE OF change SEQUENCE {
+ operation ENUMERATED {
+ add (0),
+ delete (1),
+ replace (2),
+ ... },
+ modification PartialAttribute } }
+ AddRequest ::= [APPLICATION 8] SEQUENCE {
+ entry LDAPDN,
+ attributes AttributeList }
+ DelRequest ::= [APPLICATION 10] LDAPDN
+ ModifyDNRequest ::= [APPLICATION 12] SEQUENCE {
+ entry LDAPDN,
+ newrdn RelativeLDAPDN,
+ deleteoldrdn BOOLEAN,
+ newSuperior [0] LDAPDN OPTIONAL }
+ CompareRequest ::= [APPLICATION 14] SEQUENCE {
+ entry LDAPDN,
+ ava AttributeValueAssertion }
+ ExtendedRequest ::= [APPLICATION 23] SEQUENCE {
+ requestName [0] LDAPOID,
+ requestValue [1] OCTET STRING OPTIONAL }
+ ToAsn1 Id Source MessageID ::= INTEGER (0 .. maxInt)
+ ToAsn1 a => ToAsn1 [a] Source ToAsn1 a => ToAsn1 (NonEmpty a) Source ToAsn1 op => ToAsn1 (LdapMessage op) Source LDAPMessage ::= SEQUENCE {
+ messageID MessageID,
+ protocolOp CHOICE {
+ bindRequest BindRequest,
+ bindResponse BindResponse,
+ unbindRequest UnbindRequest,
+ searchRequest SearchRequest,
+ searchResEntry SearchResultEntry,
+ searchResDone SearchResultDone,
+ searchResRef SearchResultReference,
+ addRequest AddRequest,
+ addResponse AddResponse,
+ ... },
+ controls [0] Controls OPTIONAL }
+
\ No newline at end of file
diff --git a/Ldap-Asn1-Type.html b/Ldap-Asn1-Type.html
new file mode 100644
index 0000000..00408d8
--- /dev/null
+++ b/Ldap-Asn1-Type.html
@@ -0,0 +1,208 @@
+Ldap.Asn1.Type Documentation data LdapMessage op Source
Instances
Eq op => Eq (LdapMessage op) Source Ord op => Ord (LdapMessage op) Source Show op => Show (LdapMessage op) Source ToAsn1 op => ToAsn1 (LdapMessage op) Source LDAPMessage ::= SEQUENCE {
+ messageID MessageID,
+ protocolOp CHOICE {
+ bindRequest BindRequest,
+ bindResponse BindResponse,
+ unbindRequest UnbindRequest,
+ searchRequest SearchRequest,
+ searchResEntry SearchResultEntry,
+ searchResDone SearchResultDone,
+ searchResRef SearchResultReference,
+ addRequest AddRequest,
+ addResponse AddResponse,
+ ... },
+ controls [0] Controls OPTIONAL }
+ FromAsn1 op => FromAsn1 (LdapMessage op) Source LDAPMessage ::= SEQUENCE {
+ messageID MessageID,
+ protocolOp CHOICE {
+ bindRequest BindRequest,
+ bindResponse BindResponse,
+ unbindRequest UnbindRequest,
+ searchRequest SearchRequest,
+ searchResEntry SearchResultEntry,
+ searchResDone SearchResultDone,
+ searchResRef SearchResultReference,
+ addRequest AddRequest,
+ addResponse AddResponse,
+ ... },
+ controls [0] Controls OPTIONAL }
+
data ProtocolClientOp Source
Instances
Eq ProtocolClientOp Source Ord ProtocolClientOp Source Show ProtocolClientOp Source ToAsn1 ProtocolClientOp Source BindRequest ::= [APPLICATION 0] SEQUENCE {
+ version INTEGER (1 .. 127),
+ name LDAPDN,
+ authentication AuthenticationChoice }
+ UnbindRequest ::= [APPLICATION 2] NULL
+ SearchRequest ::= [APPLICATION 3] SEQUENCE {
+ baseObject LDAPDN,
+ scope ENUMERATED {
+ baseObject (0),
+ singleLevel (1),
+ wholeSubtree (2),
+ ... },
+ derefAliases ENUMERATED {
+ neverDerefAliases (0),
+ derefInSearching (1),
+ derefFindingBaseObj (2),
+ derefAlways (3) },
+ sizeLimit INTEGER (0 .. maxInt),
+ timeLimit INTEGER (0 .. maxInt),
+ typesOnly BOOLEAN,
+ filter Filter,
+ attributes AttributeSelection }
+ ModifyRequest ::= [APPLICATION 6] SEQUENCE {
+ object LDAPDN,
+ changes SEQUENCE OF change SEQUENCE {
+ operation ENUMERATED {
+ add (0),
+ delete (1),
+ replace (2),
+ ... },
+ modification PartialAttribute } }
+ AddRequest ::= [APPLICATION 8] SEQUENCE {
+ entry LDAPDN,
+ attributes AttributeList }
+ DelRequest ::= [APPLICATION 10] LDAPDN
+ ModifyDNRequest ::= [APPLICATION 12] SEQUENCE {
+ entry LDAPDN,
+ newrdn RelativeLDAPDN,
+ deleteoldrdn BOOLEAN,
+ newSuperior [0] LDAPDN OPTIONAL }
+ CompareRequest ::= [APPLICATION 14] SEQUENCE {
+ entry LDAPDN,
+ ava AttributeValueAssertion }
+ ExtendedRequest ::= [APPLICATION 23] SEQUENCE {
+ requestName [0] LDAPOID,
+ requestValue [1] OCTET STRING OPTIONAL }
+
data Filter Source
Instances
Eq Filter Source Ord Filter Source Show Filter Source ToAsn1 Filter Source Filter ::= CHOICE {
+ and [0] SET SIZE (1..MAX) OF filter Filter,
+ or [1] SET SIZE (1..MAX) OF filter Filter,
+ not [2] Filter,
+ equalityMatch [3] AttributeValueAssertion,
+ substrings [4] SubstringFilter,
+ greaterOrEqual [5] AttributeValueAssertion,
+ lessOrEqual [6] AttributeValueAssertion,
+ present [7] AttributeDescription,
+ approxMatch [8] AttributeValueAssertion,
+ extensibleMatch [9] MatchingRuleAssertion,
+ ... }
+
data LdapResult Source
Instances
Eq LdapResult Source Ord LdapResult Source Show LdapResult Source FromAsn1 LdapResult Source LDAPResult ::= SEQUENCE {
+ resultCode ENUMERATED {
+ success (0),
+ operationsError (1),
+ protocolError (2),
+ timeLimitExceeded (3),
+ sizeLimitExceeded (4),
+ compareFalse (5),
+ compareTrue (6),
+ authMethodNotSupported (7),
+ strongerAuthRequired (8),
+ -- 9 reserved --
+ referral (10),
+ adminLimitExceeded (11),
+ unavailableCriticalExtension (12),
+ confidentialityRequired (13),
+ saslBindInProgress (14),
+ noSuchAttribute (16),
+ undefinedAttributeType (17),
+ inappropriateMatching (18),
+ constraintViolation (19),
+ attributeOrValueExists (20),
+ invalidAttributeSyntax (21),
+ -- 22-31 unused --
+ noSuchObject (32),
+ aliasProblem (33),
+ invalidDNSyntax (34),
+ -- 35 reserved for undefined isLeaf --
+ aliasDereferencingProblem (36),
+ -- 37-47 unused --
+ inappropriateAuthentication (48),
+ invalidCredentials (49),
+ insufficientAccessRights (50),
+ busy (51),
+ unavailable (52),
+ unwillingToPerform (53),
+ loopDetect (54),
+ -- 55-63 unused --
+ namingViolation (64),
+ objectClassViolation (65),
+ notAllowedOnNonLeaf (66),
+ notAllowedOnRDN (67),
+ entryAlreadyExists (68),
+ objectClassModsProhibited (69),
+ -- 70 reserved for CLDAP --
+ affectsMultipleDSAs (71),
+ -- 72-79 unused --
+ other (80),
+ ... },
+ matchedDN LDAPDN,
+ diagnosticMessage LDAPString,
+ referral [3] Referral OPTIONAL }
+
newtype LdapString Source
The LDAPString is a notational convenience to indicate that, although
+ strings of LDAPString type encode as ASN.1 OCTET STRING types, the
+ [ISO10646] character set (a superset of [Unicode]) is used, encoded
+ following the UTF-8 [RFC3629] algorithm.
\ No newline at end of file
diff --git a/Ldap-Client-Add.html b/Ldap-Client-Add.html
new file mode 100644
index 0000000..ad51456
--- /dev/null
+++ b/Ldap-Client-Add.html
@@ -0,0 +1,4 @@
+Ldap.Client.Add
\ No newline at end of file
diff --git a/Ldap-Client-Bind.html b/Ldap-Client-Bind.html
new file mode 100644
index 0000000..df16968
--- /dev/null
+++ b/Ldap-Client-Bind.html
@@ -0,0 +1,10 @@
+Ldap.Client.Bind
\ No newline at end of file
diff --git a/Ldap-Client-Compare.html b/Ldap-Client-Compare.html
new file mode 100644
index 0000000..b20272c
--- /dev/null
+++ b/Ldap-Client-Compare.html
@@ -0,0 +1,4 @@
+Ldap.Client.Compare
\ No newline at end of file
diff --git a/Ldap-Client-Delete.html b/Ldap-Client-Delete.html
new file mode 100644
index 0000000..375d5b8
--- /dev/null
+++ b/Ldap-Client-Delete.html
@@ -0,0 +1,4 @@
+Ldap.Client.Delete
\ No newline at end of file
diff --git a/Ldap-Client-Extended.html b/Ldap-Client-Extended.html
new file mode 100644
index 0000000..a44b004
--- /dev/null
+++ b/Ldap-Client-Extended.html
@@ -0,0 +1,4 @@
+Ldap.Client.Extended
\ No newline at end of file
diff --git a/Ldap-Client-Internal.html b/Ldap-Client-Internal.html
new file mode 100644
index 0000000..7418adb
--- /dev/null
+++ b/Ldap-Client-Internal.html
@@ -0,0 +1,4 @@
+Ldap.Client.Internal Documentation Waiting for Request Completion Misc
\ No newline at end of file
diff --git a/Ldap-Client-Modify.html b/Ldap-Client-Modify.html
new file mode 100644
index 0000000..82abc30
--- /dev/null
+++ b/Ldap-Client-Modify.html
@@ -0,0 +1,4 @@
+Ldap.Client.Modify
\ No newline at end of file
diff --git a/Ldap-Client-Search.html b/Ldap-Client-Search.html
new file mode 100644
index 0000000..8fd4ef9
--- /dev/null
+++ b/Ldap-Client-Search.html
@@ -0,0 +1,4 @@
+Ldap.Client.Search
\ No newline at end of file
diff --git a/Ldap-Client.html b/Ldap-Client.html
new file mode 100644
index 0000000..f7035dd
--- /dev/null
+++ b/Ldap-Client.html
@@ -0,0 +1,4 @@
+Ldap.Client Documentation Bind Search Search modifiers Modify Add Delete ModifyDn Compare Extended Waiting for completion Miscellanous Re-exports
\ No newline at end of file
diff --git a/doc-index-58.html b/doc-index-58.html
new file mode 100644
index 0000000..eb8a855
--- /dev/null
+++ b/doc-index-58.html
@@ -0,0 +1,4 @@
+ldap-client-0.1.0: Pure Haskell LDAP Client Library (Index - :)
\ No newline at end of file
diff --git a/doc-index-A.html b/doc-index-A.html
new file mode 100644
index 0000000..83b816b
--- /dev/null
+++ b/doc-index-A.html
@@ -0,0 +1,4 @@
+ldap-client-0.1.0: Pure Haskell LDAP Client Library (Index - A) Index - A
Add 1 (Data Constructor) Ldap.Asn1.Type 2 (Data Constructor) Ldap.Client.Modify , Ldap.Client add Ldap.Client.Add , Ldap.Client addAsync Ldap.Client.Add addAsyncSTM Ldap.Client.Add addEither Ldap.Client.Add AddRequest Ldap.Asn1.Type AddResponse Ldap.Asn1.Type AdminLimitExceeded Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client AffectsMultipleDSAs Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client AliasDereferencingProblem Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client AliasProblem Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client And 1 (Data Constructor) Ldap.Asn1.Type 2 (Data Constructor) Ldap.Client.Search , Ldap.Client Any Ldap.Asn1.Type ApproxMatch Ldap.Asn1.Type AssertionValue 1 (Type/Class) Ldap.Asn1.Type 2 (Data Constructor) Ldap.Asn1.Type Async Ldap.Client.Internal , Ldap.Client Attr 1 (Type/Class) Ldap.Client.Internal , Ldap.Client 2 (Data Constructor) Ldap.Client.Internal , Ldap.Client Attribute 1 (Type/Class) Ldap.Asn1.Type 2 (Data Constructor) Ldap.Asn1.Type AttributeDescription 1 (Type/Class) Ldap.Asn1.Type 2 (Data Constructor) Ldap.Asn1.Type AttributeList 1 (Type/Class) Ldap.Asn1.Type 2 (Data Constructor) Ldap.Asn1.Type AttributeOrValueExists Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client AttributeSelection 1 (Type/Class) Ldap.Asn1.Type 2 (Data Constructor) Ldap.Asn1.Type AttributeValue 1 (Type/Class) Ldap.Asn1.Type 2 (Data Constructor) Ldap.Asn1.Type AttributeValueAssertion 1 (Type/Class) Ldap.Asn1.Type 2 (Data Constructor) Ldap.Asn1.Type AttrList Ldap.Client.Internal , Ldap.Client AuthenticationChoice Ldap.Asn1.Type AuthMethodNotSupported Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client
\ No newline at end of file
diff --git a/doc-index-All.html b/doc-index-All.html
new file mode 100644
index 0000000..200d2cc
--- /dev/null
+++ b/doc-index-All.html
@@ -0,0 +1,4 @@
+ldap-client-0.1.0: Pure Haskell LDAP Client Library (Index) Index
::= Ldap.Client.Search , Ldap.Client :<= Ldap.Client.Search , Ldap.Client := Ldap.Client.Search , Ldap.Client :=* Ldap.Client.Search , Ldap.Client :>= Ldap.Client.Search , Ldap.Client :~= Ldap.Client.Search , Ldap.Client Add 1 (Data Constructor) Ldap.Asn1.Type 2 (Data Constructor) Ldap.Client.Modify , Ldap.Client add Ldap.Client.Add , Ldap.Client addAsync Ldap.Client.Add addAsyncSTM Ldap.Client.Add addEither Ldap.Client.Add AddRequest Ldap.Asn1.Type AddResponse Ldap.Asn1.Type AdminLimitExceeded Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client AffectsMultipleDSAs Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client AliasDereferencingProblem Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client AliasProblem Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client And 1 (Data Constructor) Ldap.Asn1.Type 2 (Data Constructor) Ldap.Client.Search , Ldap.Client Any Ldap.Asn1.Type ApproxMatch Ldap.Asn1.Type AssertionValue 1 (Type/Class) Ldap.Asn1.Type 2 (Data Constructor) Ldap.Asn1.Type Async Ldap.Client.Internal , Ldap.Client Attr 1 (Type/Class) Ldap.Client.Internal , Ldap.Client 2 (Data Constructor) Ldap.Client.Internal , Ldap.Client Attribute 1 (Type/Class) Ldap.Asn1.Type 2 (Data Constructor) Ldap.Asn1.Type AttributeDescription 1 (Type/Class) Ldap.Asn1.Type 2 (Data Constructor) Ldap.Asn1.Type AttributeList 1 (Type/Class) Ldap.Asn1.Type 2 (Data Constructor) Ldap.Asn1.Type AttributeOrValueExists Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client AttributeSelection 1 (Type/Class) Ldap.Asn1.Type 2 (Data Constructor) Ldap.Asn1.Type AttributeValue 1 (Type/Class) Ldap.Asn1.Type 2 (Data Constructor) Ldap.Asn1.Type AttributeValueAssertion 1 (Type/Class) Ldap.Asn1.Type 2 (Data Constructor) Ldap.Asn1.Type AttrList Ldap.Client.Internal , Ldap.Client AuthenticationChoice Ldap.Asn1.Type AuthMethodNotSupported Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client BaseObject Ldap.Asn1.Type , Ldap.Client.Search , Ldap.Client bind Ldap.Client.Bind , Ldap.Client bindAsync Ldap.Client.Bind bindAsyncSTM Ldap.Client.Bind bindEither Ldap.Client.Bind BindRequest Ldap.Asn1.Type BindResponse Ldap.Asn1.Type Busy Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client client Ldap.Client.Internal ClientMessage Ldap.Client.Internal compare Ldap.Client.Compare , Ldap.Client compareAsync Ldap.Client.Compare compareAsyncSTM Ldap.Client.Compare compareEither Ldap.Client.Compare CompareFalse Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client CompareRequest Ldap.Asn1.Type CompareResponse Ldap.Asn1.Type CompareTrue Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client ConfidentialityRequired Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client ConstraintViolation Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client Control 1 (Type/Class) Ldap.Asn1.Type 2 (Data Constructor) Ldap.Asn1.Type Controls 1 (Type/Class) Ldap.Asn1.Type 2 (Data Constructor) Ldap.Asn1.Type Delete 1 (Data Constructor) Ldap.Asn1.Type 2 (Data Constructor) Ldap.Client.Modify , Ldap.Client delete Ldap.Client.Delete , Ldap.Client deleteAsync Ldap.Client.Delete deleteAsyncSTM Ldap.Client.Delete deleteEither Ldap.Client.Delete DeleteRequest Ldap.Asn1.Type DeleteResponse Ldap.Asn1.Type DerefAliases Ldap.Asn1.Type derefAliases Ldap.Client.Search , Ldap.Client DerefAlways Ldap.Asn1.Type DerefFindingBaseObject Ldap.Asn1.Type DerefInSearching Ldap.Asn1.Type Dn 1 (Type/Class) Ldap.Client.Internal , Ldap.Client 2 (Data Constructor) Ldap.Client.Internal , Ldap.Client EntryAlreadyExists Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client EqualityMatch Ldap.Asn1.Type extended Ldap.Client.Extended , Ldap.Client extendedAsync Ldap.Client.Extended extendedAsyncSTM Ldap.Client.Extended extendedEither Ldap.Client.Extended ExtendedRequest Ldap.Asn1.Type ExtendedResponse Ldap.Asn1.Type ExtensibleMatch Ldap.Asn1.Type Filter 1 (Type/Class) Ldap.Asn1.Type 2 (Type/Class) Ldap.Client.Search , Ldap.Client Final Ldap.Asn1.Type FromAsn1 Ldap.Asn1.FromAsn1 fromAsn1 Ldap.Asn1.FromAsn1 GreaterOrEqual Ldap.Asn1.Type Host Ldap.Client.Internal , Ldap.Client Id 1 (Type/Class) Ldap.Asn1.Type 2 (Data Constructor) Ldap.Asn1.Type InappropriateAuthentication Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client InappropriateMatching Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client Initial Ldap.Asn1.Type Insecure Ldap.Client.Internal , Ldap.Client InsufficientAccessRights Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client InvalidAttributeSyntax Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client InvalidCredentials Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client InvalidDNSyntax Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client IOError Ldap.Client Ldap 1 (Type/Class) Ldap.Client.Internal , Ldap.Client 2 (Data Constructor) Ldap.Client.Internal LdapDn 1 (Type/Class) Ldap.Asn1.Type 2 (Data Constructor) Ldap.Asn1.Type LdapError Ldap.Client LdapMessage 1 (Type/Class) Ldap.Asn1.Type 2 (Data Constructor) Ldap.Asn1.Type ldapMessageControls Ldap.Asn1.Type ldapMessageId Ldap.Asn1.Type ldapMessageOp Ldap.Asn1.Type LdapOid 1 (Type/Class) Ldap.Asn1.Type 2 (Data Constructor) Ldap.Asn1.Type LdapResult 1 (Type/Class) Ldap.Asn1.Type 2 (Data Constructor) Ldap.Asn1.Type LdapString 1 (Type/Class) Ldap.Asn1.Type 2 (Data Constructor) Ldap.Asn1.Type LessOrEqual Ldap.Asn1.Type LoopDetect Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client MatchingRuleAssertion 1 (Type/Class) Ldap.Asn1.Type 2 (Data Constructor) Ldap.Asn1.Type MatchingRuleId 1 (Type/Class) Ldap.Asn1.Type 2 (Data Constructor) Ldap.Asn1.Type Mod Ldap.Client.Search , Ldap.Client modify Ldap.Client.Modify , Ldap.Client modifyAsync Ldap.Client.Modify modifyAsyncSTM Ldap.Client.Modify modifyDn Ldap.Client.Modify , Ldap.Client modifyDnAsync Ldap.Client.Modify modifyDnAsyncSTM Ldap.Client.Modify modifyDnEither Ldap.Client.Modify ModifyDnRequest Ldap.Asn1.Type ModifyDnResponse Ldap.Asn1.Type modifyEither Ldap.Client.Modify ModifyRequest Ldap.Asn1.Type ModifyResponse Ldap.Asn1.Type NamingViolation Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client NeverDerefAliases Ldap.Asn1.Type New Ldap.Client.Internal next Ldap.Asn1.FromAsn1 NonEmpty Ldap.Client NoSuchAttribute Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client NoSuchObject Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client Not 1 (Data Constructor) Ldap.Asn1.Type 2 (Data Constructor) Ldap.Client.Search , Ldap.Client NotAllowedOnNonLeaf Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client NotAllowedOnRDN Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client ObjectClassModsProhibited Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client ObjectClassViolation Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client Oid 1 (Type/Class) Ldap.Client.Internal , Ldap.Client 2 (Data Constructor) Ldap.Client.Internal , Ldap.Client Operation 1 (Type/Class) Ldap.Asn1.Type 2 (Type/Class) Ldap.Client.Modify , Ldap.Client OperationError Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client Or 1 (Data Constructor) Ldap.Asn1.Type 2 (Data Constructor) Ldap.Client.Search , Ldap.Client Other Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client parse Ldap.Asn1.FromAsn1 parseAsn1 Ldap.Asn1.FromAsn1 ParseError Ldap.Client Parser Ldap.Asn1.FromAsn1 PartialAttribute 1 (Type/Class) Ldap.Asn1.Type 2 (Data Constructor) Ldap.Asn1.Type PartialAttributeList 1 (Type/Class) Ldap.Asn1.Type 2 (Data Constructor) Ldap.Asn1.Type Password 1 (Type/Class) Ldap.Client.Internal , Ldap.Client 2 (Data Constructor) Ldap.Client.Internal , Ldap.Client Plain Ldap.Client.Internal , Ldap.Client PortNumber Ldap.Client.Internal , Ldap.Client Present 1 (Data Constructor) Ldap.Asn1.Type 2 (Data Constructor) Ldap.Client.Search , Ldap.Client ProtocolClientOp Ldap.Asn1.Type ProtocolError Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client ProtocolServerOp Ldap.Asn1.Type raise Ldap.Client.Internal Referral Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client ReferralUris 1 (Type/Class) Ldap.Asn1.Type 2 (Data Constructor) Ldap.Asn1.Type RelativeDn 1 (Type/Class) Ldap.Client.Internal , Ldap.Client 2 (Data Constructor) Ldap.Client.Internal , Ldap.Client RelativeLdapDn 1 (Type/Class) Ldap.Asn1.Type 2 (Data Constructor) Ldap.Asn1.Type Replace 1 (Data Constructor) Ldap.Asn1.Type 2 (Data Constructor) Ldap.Client.Modify , Ldap.Client Request Ldap.Client.Internal Response Ldap.Client.Internal ResponseError 1 (Type/Class) Ldap.Client.Internal , Ldap.Client 2 (Data Constructor) Ldap.Client ResponseErrorCode Ldap.Client.Internal , Ldap.Client ResponseInvalid Ldap.Client.Internal , Ldap.Client ResultCode Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client SaslBindInProgress Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client Scope Ldap.Asn1.Type , Ldap.Client.Search , Ldap.Client scope Ldap.Client.Search , Ldap.Client Search Ldap.Client.Search , Ldap.Client search Ldap.Client.Search , Ldap.Client searchAsync Ldap.Client.Search searchAsyncSTM Ldap.Client.Search searchEither Ldap.Client.Search SearchEntry 1 (Type/Class) Ldap.Client.Search , Ldap.Client 2 (Data Constructor) Ldap.Client.Search , Ldap.Client SearchRequest Ldap.Asn1.Type SearchResultDone Ldap.Asn1.Type SearchResultEntry Ldap.Asn1.Type SearchResultReference Ldap.Asn1.Type Secure Ldap.Client.Internal , Ldap.Client sendRequest Ldap.Client.Internal Simple Ldap.Asn1.Type SingleLevel Ldap.Asn1.Type , Ldap.Client.Search , Ldap.Client size Ldap.Client.Search , Ldap.Client SizeLimitExceeded Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client startTls Ldap.Client.Extended startTlsAsync Ldap.Client.Extended startTlsAsyncSTM Ldap.Client.Extended startTlsEither Ldap.Client.Extended StrongerAuthRequired Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client Substring Ldap.Asn1.Type SubstringFilter 1 (Type/Class) Ldap.Asn1.Type 2 (Data Constructor) Ldap.Asn1.Type Substrings Ldap.Asn1.Type Success Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client time Ldap.Client.Search , Ldap.Client TimeLimitExceeded Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client ToAsn1 Ldap.Asn1.ToAsn1 toAsn1 Ldap.Asn1.ToAsn1 typesOnly Ldap.Client.Search , Ldap.Client unAttr Ldap.Client.Internal Unavailable Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client UnavailableCriticalExtension Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client unbindAsync Ldap.Client.Bind unbindAsyncSTM Ldap.Client.Bind UnbindRequest Ldap.Asn1.Type UndefinedAttributeType Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client unId Ldap.Asn1.Type UnwillingToPerform Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client Uri 1 (Type/Class) Ldap.Asn1.Type 2 (Data Constructor) Ldap.Asn1.Type wait Ldap.Client.Internal , Ldap.Client waitSTM Ldap.Client.Internal WholeSubtree Ldap.Asn1.Type , Ldap.Client.Search , Ldap.Client with Ldap.Client
\ No newline at end of file
diff --git a/doc-index-B.html b/doc-index-B.html
new file mode 100644
index 0000000..e0f2bac
--- /dev/null
+++ b/doc-index-B.html
@@ -0,0 +1,4 @@
+ldap-client-0.1.0: Pure Haskell LDAP Client Library (Index - B)
\ No newline at end of file
diff --git a/doc-index-C.html b/doc-index-C.html
new file mode 100644
index 0000000..2130975
--- /dev/null
+++ b/doc-index-C.html
@@ -0,0 +1,4 @@
+ldap-client-0.1.0: Pure Haskell LDAP Client Library (Index - C)
\ No newline at end of file
diff --git a/doc-index-D.html b/doc-index-D.html
new file mode 100644
index 0000000..47b33ad
--- /dev/null
+++ b/doc-index-D.html
@@ -0,0 +1,4 @@
+ldap-client-0.1.0: Pure Haskell LDAP Client Library (Index - D)
\ No newline at end of file
diff --git a/doc-index-E.html b/doc-index-E.html
new file mode 100644
index 0000000..e86ffd9
--- /dev/null
+++ b/doc-index-E.html
@@ -0,0 +1,4 @@
+ldap-client-0.1.0: Pure Haskell LDAP Client Library (Index - E)
\ No newline at end of file
diff --git a/doc-index-F.html b/doc-index-F.html
new file mode 100644
index 0000000..c2364f2
--- /dev/null
+++ b/doc-index-F.html
@@ -0,0 +1,4 @@
+ldap-client-0.1.0: Pure Haskell LDAP Client Library (Index - F)
\ No newline at end of file
diff --git a/doc-index-G.html b/doc-index-G.html
new file mode 100644
index 0000000..4cd5007
--- /dev/null
+++ b/doc-index-G.html
@@ -0,0 +1,4 @@
+ldap-client-0.1.0: Pure Haskell LDAP Client Library (Index - G)
\ No newline at end of file
diff --git a/doc-index-H.html b/doc-index-H.html
new file mode 100644
index 0000000..1fe8663
--- /dev/null
+++ b/doc-index-H.html
@@ -0,0 +1,4 @@
+ldap-client-0.1.0: Pure Haskell LDAP Client Library (Index - H)
\ No newline at end of file
diff --git a/doc-index-I.html b/doc-index-I.html
new file mode 100644
index 0000000..4ca0f6e
--- /dev/null
+++ b/doc-index-I.html
@@ -0,0 +1,4 @@
+ldap-client-0.1.0: Pure Haskell LDAP Client Library (Index - I) Index - I
Id 1 (Type/Class) Ldap.Asn1.Type 2 (Data Constructor) Ldap.Asn1.Type InappropriateAuthentication Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client InappropriateMatching Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client Initial Ldap.Asn1.Type Insecure Ldap.Client.Internal , Ldap.Client InsufficientAccessRights Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client InvalidAttributeSyntax Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client InvalidCredentials Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client InvalidDNSyntax Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client IOError Ldap.Client
\ No newline at end of file
diff --git a/doc-index-L.html b/doc-index-L.html
new file mode 100644
index 0000000..2731ae8
--- /dev/null
+++ b/doc-index-L.html
@@ -0,0 +1,4 @@
+ldap-client-0.1.0: Pure Haskell LDAP Client Library (Index - L)
\ No newline at end of file
diff --git a/doc-index-M.html b/doc-index-M.html
new file mode 100644
index 0000000..14377b0
--- /dev/null
+++ b/doc-index-M.html
@@ -0,0 +1,4 @@
+ldap-client-0.1.0: Pure Haskell LDAP Client Library (Index - M)
\ No newline at end of file
diff --git a/doc-index-N.html b/doc-index-N.html
new file mode 100644
index 0000000..95f5559
--- /dev/null
+++ b/doc-index-N.html
@@ -0,0 +1,4 @@
+ldap-client-0.1.0: Pure Haskell LDAP Client Library (Index - N) Index - N
NamingViolation Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client NeverDerefAliases Ldap.Asn1.Type New Ldap.Client.Internal next Ldap.Asn1.FromAsn1 NonEmpty Ldap.Client NoSuchAttribute Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client NoSuchObject Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client Not 1 (Data Constructor) Ldap.Asn1.Type 2 (Data Constructor) Ldap.Client.Search , Ldap.Client NotAllowedOnNonLeaf Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client NotAllowedOnRDN Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client
\ No newline at end of file
diff --git a/doc-index-O.html b/doc-index-O.html
new file mode 100644
index 0000000..1ee8e79
--- /dev/null
+++ b/doc-index-O.html
@@ -0,0 +1,4 @@
+ldap-client-0.1.0: Pure Haskell LDAP Client Library (Index - O) Index - O
ObjectClassModsProhibited Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client ObjectClassViolation Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client Oid 1 (Type/Class) Ldap.Client.Internal , Ldap.Client 2 (Data Constructor) Ldap.Client.Internal , Ldap.Client Operation 1 (Type/Class) Ldap.Asn1.Type 2 (Type/Class) Ldap.Client.Modify , Ldap.Client OperationError Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client Or 1 (Data Constructor) Ldap.Asn1.Type 2 (Data Constructor) Ldap.Client.Search , Ldap.Client Other Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client
\ No newline at end of file
diff --git a/doc-index-P.html b/doc-index-P.html
new file mode 100644
index 0000000..09bd77b
--- /dev/null
+++ b/doc-index-P.html
@@ -0,0 +1,4 @@
+ldap-client-0.1.0: Pure Haskell LDAP Client Library (Index - P)
\ No newline at end of file
diff --git a/doc-index-R.html b/doc-index-R.html
new file mode 100644
index 0000000..80f5829
--- /dev/null
+++ b/doc-index-R.html
@@ -0,0 +1,4 @@
+ldap-client-0.1.0: Pure Haskell LDAP Client Library (Index - R) Index - R
raise Ldap.Client.Internal Referral Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client ReferralUris 1 (Type/Class) Ldap.Asn1.Type 2 (Data Constructor) Ldap.Asn1.Type RelativeDn 1 (Type/Class) Ldap.Client.Internal , Ldap.Client 2 (Data Constructor) Ldap.Client.Internal , Ldap.Client RelativeLdapDn 1 (Type/Class) Ldap.Asn1.Type 2 (Data Constructor) Ldap.Asn1.Type Replace 1 (Data Constructor) Ldap.Asn1.Type 2 (Data Constructor) Ldap.Client.Modify , Ldap.Client Request Ldap.Client.Internal Response Ldap.Client.Internal ResponseError 1 (Type/Class) Ldap.Client.Internal , Ldap.Client 2 (Data Constructor) Ldap.Client ResponseErrorCode Ldap.Client.Internal , Ldap.Client ResponseInvalid Ldap.Client.Internal , Ldap.Client ResultCode Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client
\ No newline at end of file
diff --git a/doc-index-S.html b/doc-index-S.html
new file mode 100644
index 0000000..603b37f
--- /dev/null
+++ b/doc-index-S.html
@@ -0,0 +1,4 @@
+ldap-client-0.1.0: Pure Haskell LDAP Client Library (Index - S) Index - S
SaslBindInProgress Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client Scope Ldap.Asn1.Type , Ldap.Client.Search , Ldap.Client scope Ldap.Client.Search , Ldap.Client Search Ldap.Client.Search , Ldap.Client search Ldap.Client.Search , Ldap.Client searchAsync Ldap.Client.Search searchAsyncSTM Ldap.Client.Search searchEither Ldap.Client.Search SearchEntry 1 (Type/Class) Ldap.Client.Search , Ldap.Client 2 (Data Constructor) Ldap.Client.Search , Ldap.Client SearchRequest Ldap.Asn1.Type SearchResultDone Ldap.Asn1.Type SearchResultEntry Ldap.Asn1.Type SearchResultReference Ldap.Asn1.Type Secure Ldap.Client.Internal , Ldap.Client sendRequest Ldap.Client.Internal Simple Ldap.Asn1.Type SingleLevel Ldap.Asn1.Type , Ldap.Client.Search , Ldap.Client size Ldap.Client.Search , Ldap.Client SizeLimitExceeded Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client startTls Ldap.Client.Extended startTlsAsync Ldap.Client.Extended startTlsAsyncSTM Ldap.Client.Extended startTlsEither Ldap.Client.Extended StrongerAuthRequired Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client Substring Ldap.Asn1.Type SubstringFilter 1 (Type/Class) Ldap.Asn1.Type 2 (Data Constructor) Ldap.Asn1.Type Substrings Ldap.Asn1.Type Success Ldap.Asn1.Type , Ldap.Client.Internal , Ldap.Client
\ No newline at end of file
diff --git a/doc-index-T.html b/doc-index-T.html
new file mode 100644
index 0000000..2c86a6f
--- /dev/null
+++ b/doc-index-T.html
@@ -0,0 +1,4 @@
+ldap-client-0.1.0: Pure Haskell LDAP Client Library (Index - T)
\ No newline at end of file
diff --git a/doc-index-U.html b/doc-index-U.html
new file mode 100644
index 0000000..0961a58
--- /dev/null
+++ b/doc-index-U.html
@@ -0,0 +1,4 @@
+ldap-client-0.1.0: Pure Haskell LDAP Client Library (Index - U)
\ No newline at end of file
diff --git a/doc-index-W.html b/doc-index-W.html
new file mode 100644
index 0000000..686aea4
--- /dev/null
+++ b/doc-index-W.html
@@ -0,0 +1,4 @@
+ldap-client-0.1.0: Pure Haskell LDAP Client Library (Index - W)
\ No newline at end of file
diff --git a/doc-index.html b/doc-index.html
new file mode 100644
index 0000000..48a73ea
--- /dev/null
+++ b/doc-index.html
@@ -0,0 +1,4 @@
+ldap-client-0.1.0: Pure Haskell LDAP Client Library (Index)
\ No newline at end of file
diff --git a/frames.html b/frames.html
new file mode 100644
index 0000000..1b4e38d
--- /dev/null
+++ b/frames.html
@@ -0,0 +1,30 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/haddock-util.js b/haddock-util.js
new file mode 100644
index 0000000..9a6fccf
--- /dev/null
+++ b/haddock-util.js
@@ -0,0 +1,344 @@
+// Haddock JavaScript utilities
+
+var rspace = /\s\s+/g,
+ rtrim = /^\s+|\s+$/g;
+
+function spaced(s) { return (" " + s + " ").replace(rspace, " "); }
+function trim(s) { return s.replace(rtrim, ""); }
+
+function hasClass(elem, value) {
+ var className = spaced(elem.className || "");
+ return className.indexOf( " " + value + " " ) >= 0;
+}
+
+function addClass(elem, value) {
+ var className = spaced(elem.className || "");
+ if ( className.indexOf( " " + value + " " ) < 0 ) {
+ elem.className = trim(className + " " + value);
+ }
+}
+
+function removeClass(elem, value) {
+ var className = spaced(elem.className || "");
+ className = className.replace(" " + value + " ", " ");
+ elem.className = trim(className);
+}
+
+function toggleClass(elem, valueOn, valueOff, bool) {
+ if (bool == null) { bool = ! hasClass(elem, valueOn); }
+ if (bool) {
+ removeClass(elem, valueOff);
+ addClass(elem, valueOn);
+ }
+ else {
+ removeClass(elem, valueOn);
+ addClass(elem, valueOff);
+ }
+ return bool;
+}
+
+
+function makeClassToggle(valueOn, valueOff)
+{
+ return function(elem, bool) {
+ return toggleClass(elem, valueOn, valueOff, bool);
+ }
+}
+
+toggleShow = makeClassToggle("show", "hide");
+toggleCollapser = makeClassToggle("collapser", "expander");
+
+function toggleSection(id)
+{
+ var b = toggleShow(document.getElementById("section." + id));
+ toggleCollapser(document.getElementById("control." + id), b);
+ rememberCollapsed(id, b);
+ return b;
+}
+
+var collapsed = {};
+function rememberCollapsed(id, b)
+{
+ if(b)
+ delete collapsed[id]
+ else
+ collapsed[id] = null;
+
+ var sections = [];
+ for(var i in collapsed)
+ {
+ if(collapsed.hasOwnProperty(i))
+ sections.push(i);
+ }
+ // cookie specific to this page; don't use setCookie which sets path=/
+ document.cookie = "collapsed=" + escape(sections.join('+'));
+}
+
+function restoreCollapsed()
+{
+ var cookie = getCookie("collapsed");
+ if(!cookie)
+ return;
+
+ var ids = cookie.split('+');
+ for(var i in ids)
+ {
+ if(document.getElementById("section." + ids[i]))
+ toggleSection(ids[i]);
+ }
+}
+
+function setCookie(name, value) {
+ document.cookie = name + "=" + escape(value) + ";path=/;";
+}
+
+function clearCookie(name) {
+ document.cookie = name + "=;path=/;expires=Thu, 01-Jan-1970 00:00:01 GMT;";
+}
+
+function getCookie(name) {
+ var nameEQ = name + "=";
+ var ca = document.cookie.split(';');
+ for(var i=0;i < ca.length;i++) {
+ var c = ca[i];
+ while (c.charAt(0)==' ') c = c.substring(1,c.length);
+ if (c.indexOf(nameEQ) == 0) {
+ return unescape(c.substring(nameEQ.length,c.length));
+ }
+ }
+ return null;
+}
+
+
+
+var max_results = 75; // 50 is not enough to search for map in the base libraries
+var shown_range = null;
+var last_search = null;
+
+function quick_search()
+{
+ perform_search(false);
+}
+
+function full_search()
+{
+ perform_search(true);
+}
+
+
+function perform_search(full)
+{
+ var text = document.getElementById("searchbox").value.toLowerCase();
+ if (text == last_search && !full) return;
+ last_search = text;
+
+ var table = document.getElementById("indexlist");
+ var status = document.getElementById("searchmsg");
+ var children = table.firstChild.childNodes;
+
+ // first figure out the first node with the prefix
+ var first = bisect(-1);
+ var last = (first == -1 ? -1 : bisect(1));
+
+ if (first == -1)
+ {
+ table.className = "";
+ status.innerHTML = "No results found, displaying all";
+ }
+ else if (first == 0 && last == children.length - 1)
+ {
+ table.className = "";
+ status.innerHTML = "";
+ }
+ else if (last - first >= max_results && !full)
+ {
+ table.className = "";
+ status.innerHTML = "More than " + max_results + ", press Search to display";
+ }
+ else
+ {
+ // decide what you need to clear/show
+ if (shown_range)
+ setclass(shown_range[0], shown_range[1], "indexrow");
+ setclass(first, last, "indexshow");
+ shown_range = [first, last];
+ table.className = "indexsearch";
+ status.innerHTML = "";
+ }
+
+
+ function setclass(first, last, status)
+ {
+ for (var i = first; i <= last; i++)
+ {
+ children[i].className = status;
+ }
+ }
+
+
+ // do a binary search, treating 0 as ...
+ // return either -1 (no 0's found) or location of most far match
+ function bisect(dir)
+ {
+ var first = 0, finish = children.length - 1;
+ var mid, success = false;
+
+ while (finish - first > 3)
+ {
+ mid = Math.floor((finish + first) / 2);
+
+ var i = checkitem(mid);
+ if (i == 0) i = dir;
+ if (i == -1)
+ finish = mid;
+ else
+ first = mid;
+ }
+ var a = (dir == 1 ? first : finish);
+ var b = (dir == 1 ? finish : first);
+ for (var i = b; i != a - dir; i -= dir)
+ {
+ if (checkitem(i) == 0) return i;
+ }
+ return -1;
+ }
+
+
+ // from an index, decide what the result is
+ // 0 = match, -1 is lower, 1 is higher
+ function checkitem(i)
+ {
+ var s = getitem(i).toLowerCase().substr(0, text.length);
+ if (s == text) return 0;
+ else return (s > text ? -1 : 1);
+ }
+
+
+ // from an index, get its string
+ // this abstracts over alternates
+ function getitem(i)
+ {
+ for ( ; i >= 0; i--)
+ {
+ var s = children[i].firstChild.firstChild.data;
+ if (s.indexOf(' ') == -1)
+ return s;
+ }
+ return ""; // should never be reached
+ }
+}
+
+function setSynopsis(filename) {
+ if (parent.window.synopsis) {
+ if (parent.window.synopsis.location.replace) {
+ // In Firefox this avoids adding the change to the history.
+ parent.window.synopsis.location.replace(filename);
+ } else {
+ parent.window.synopsis.location = filename;
+ }
+ }
+}
+
+function addMenuItem(html) {
+ var menu = document.getElementById("page-menu");
+ if (menu) {
+ var btn = menu.firstChild.cloneNode(false);
+ btn.innerHTML = html;
+ menu.appendChild(btn);
+ }
+}
+
+function adjustForFrames() {
+ var bodyCls;
+
+ if (parent.location.href == window.location.href) {
+ // not in frames, so add Frames button
+ addMenuItem("Frames ");
+ bodyCls = "no-frame";
+ }
+ else {
+ bodyCls = "in-frame";
+ }
+ addClass(document.body, bodyCls);
+}
+
+function reframe() {
+ setCookie("haddock-reframe", document.URL);
+ window.location = "frames.html";
+}
+
+function postReframe() {
+ var s = getCookie("haddock-reframe");
+ if (s) {
+ parent.window.main.location = s;
+ clearCookie("haddock-reframe");
+ }
+}
+
+function styles() {
+ var i, a, es = document.getElementsByTagName("link"), rs = [];
+ for (i = 0; a = es[i]; i++) {
+ if(a.rel.indexOf("style") != -1 && a.title) {
+ rs.push(a);
+ }
+ }
+ return rs;
+}
+
+function addStyleMenu() {
+ var as = styles();
+ var i, a, btns = "";
+ for(i=0; a = as[i]; i++) {
+ btns += ""
+ + a.title + " "
+ }
+ if (as.length > 1) {
+ var h = "";
+ addMenuItem(h);
+ }
+}
+
+function setActiveStyleSheet(title) {
+ var as = styles();
+ var i, a, found;
+ for(i=0; a = as[i]; i++) {
+ a.disabled = true;
+ // need to do this always, some browsers are edge triggered
+ if(a.title == title) {
+ found = a;
+ }
+ }
+ if (found) {
+ found.disabled = false;
+ setCookie("haddock-style", title);
+ }
+ else {
+ as[0].disabled = false;
+ clearCookie("haddock-style");
+ }
+ styleMenu(false);
+}
+
+function resetStyle() {
+ var s = getCookie("haddock-style");
+ if (s) setActiveStyleSheet(s);
+}
+
+
+function styleMenu(show) {
+ var m = document.getElementById('style-menu');
+ if (m) toggleShow(m, show);
+}
+
+
+function pageLoad() {
+ addStyleMenu();
+ adjustForFrames();
+ resetStyle();
+ restoreCollapsed();
+}
+
diff --git a/hslogo-16.png b/hslogo-16.png
new file mode 100644
index 0000000..0ff8579
Binary files /dev/null and b/hslogo-16.png differ
diff --git a/index-frames.html b/index-frames.html
new file mode 100644
index 0000000..c95cef5
--- /dev/null
+++ b/index-frames.html
@@ -0,0 +1,4 @@
+ldap-client-0.1.0: Pure Haskell LDAP Client Library
\ No newline at end of file
diff --git a/index.html b/index.html
new file mode 100644
index 0000000..edcd5a8
--- /dev/null
+++ b/index.html
@@ -0,0 +1,4 @@
+ldap-client-0.1.0: Pure Haskell LDAP Client Library ldap-client-0.1.0: Pure Haskell LDAP Client Library Pure Haskell LDAP client library implementing (the parts of) RFC 4511.
\ No newline at end of file
diff --git a/ldap-client.haddock b/ldap-client.haddock
new file mode 100644
index 0000000..df2ff38
Binary files /dev/null and b/ldap-client.haddock differ
diff --git a/mini_Ldap-Asn1-FromAsn1.html b/mini_Ldap-Asn1-FromAsn1.html
new file mode 100644
index 0000000..5a1b897
--- /dev/null
+++ b/mini_Ldap-Asn1-FromAsn1.html
@@ -0,0 +1,4 @@
+Ldap.Asn1.FromAsn1
\ No newline at end of file
diff --git a/mini_Ldap-Asn1-ToAsn1.html b/mini_Ldap-Asn1-ToAsn1.html
new file mode 100644
index 0000000..4f67251
--- /dev/null
+++ b/mini_Ldap-Asn1-ToAsn1.html
@@ -0,0 +1,4 @@
+Ldap.Asn1.ToAsn1
\ No newline at end of file
diff --git a/mini_Ldap-Asn1-Type.html b/mini_Ldap-Asn1-Type.html
new file mode 100644
index 0000000..8868af8
--- /dev/null
+++ b/mini_Ldap-Asn1-Type.html
@@ -0,0 +1,4 @@
+Ldap.Asn1.Type
\ No newline at end of file
diff --git a/mini_Ldap-Client-Add.html b/mini_Ldap-Client-Add.html
new file mode 100644
index 0000000..3e317aa
--- /dev/null
+++ b/mini_Ldap-Client-Add.html
@@ -0,0 +1,4 @@
+Ldap.Client.Add
\ No newline at end of file
diff --git a/mini_Ldap-Client-Bind.html b/mini_Ldap-Client-Bind.html
new file mode 100644
index 0000000..7ed621a
--- /dev/null
+++ b/mini_Ldap-Client-Bind.html
@@ -0,0 +1,4 @@
+Ldap.Client.Bind
\ No newline at end of file
diff --git a/mini_Ldap-Client-Compare.html b/mini_Ldap-Client-Compare.html
new file mode 100644
index 0000000..432a0ba
--- /dev/null
+++ b/mini_Ldap-Client-Compare.html
@@ -0,0 +1,4 @@
+Ldap.Client.Compare
\ No newline at end of file
diff --git a/mini_Ldap-Client-Delete.html b/mini_Ldap-Client-Delete.html
new file mode 100644
index 0000000..f046436
--- /dev/null
+++ b/mini_Ldap-Client-Delete.html
@@ -0,0 +1,4 @@
+Ldap.Client.Delete
\ No newline at end of file
diff --git a/mini_Ldap-Client-Extended.html b/mini_Ldap-Client-Extended.html
new file mode 100644
index 0000000..ebf2d85
--- /dev/null
+++ b/mini_Ldap-Client-Extended.html
@@ -0,0 +1,4 @@
+Ldap.Client.Extended
\ No newline at end of file
diff --git a/mini_Ldap-Client-Internal.html b/mini_Ldap-Client-Internal.html
new file mode 100644
index 0000000..9229263
--- /dev/null
+++ b/mini_Ldap-Client-Internal.html
@@ -0,0 +1,4 @@
+Ldap.Client.Internal Waiting for Request Completion Misc
\ No newline at end of file
diff --git a/mini_Ldap-Client-Modify.html b/mini_Ldap-Client-Modify.html
new file mode 100644
index 0000000..06ccf0f
--- /dev/null
+++ b/mini_Ldap-Client-Modify.html
@@ -0,0 +1,4 @@
+Ldap.Client.Modify
\ No newline at end of file
diff --git a/mini_Ldap-Client-Search.html b/mini_Ldap-Client-Search.html
new file mode 100644
index 0000000..9d4bb03
--- /dev/null
+++ b/mini_Ldap-Client-Search.html
@@ -0,0 +1,4 @@
+Ldap.Client.Search
\ No newline at end of file
diff --git a/mini_Ldap-Client.html b/mini_Ldap-Client.html
new file mode 100644
index 0000000..7165334
--- /dev/null
+++ b/mini_Ldap-Client.html
@@ -0,0 +1,4 @@
+Ldap.Client Bind Search Search modifiers Modify Add Delete ModifyDn Compare Extended Waiting for completion Miscellanous Re-exports
\ No newline at end of file
diff --git a/minus.gif b/minus.gif
new file mode 100644
index 0000000..1deac2f
Binary files /dev/null and b/minus.gif differ
diff --git a/ocean.css b/ocean.css
new file mode 100644
index 0000000..ef652a2
--- /dev/null
+++ b/ocean.css
@@ -0,0 +1,587 @@
+/* @group Fundamentals */
+
+* { margin: 0; padding: 0 }
+
+/* Is this portable? */
+html {
+ background-color: white;
+ width: 100%;
+ height: 100%;
+}
+
+body {
+ background: white;
+ color: black;
+ text-align: left;
+ min-height: 100%;
+ position: relative;
+}
+
+p {
+ margin: 0.8em 0;
+}
+
+ul, ol {
+ margin: 0.8em 0 0.8em 2em;
+}
+
+dl {
+ margin: 0.8em 0;
+}
+
+dt {
+ font-weight: bold;
+}
+dd {
+ margin-left: 2em;
+}
+
+a { text-decoration: none; }
+a[href]:link { color: rgb(196,69,29); }
+a[href]:visited { color: rgb(171,105,84); }
+a[href]:hover { text-decoration:underline; }
+
+/* @end */
+
+/* @group Fonts & Sizes */
+
+/* Basic technique & IE workarounds from YUI 3
+ For reasons, see:
+ http://yui.yahooapis.com/3.1.1/build/cssfonts/fonts.css
+ */
+
+body {
+ font:13px/1.4 sans-serif;
+ *font-size:small; /* for IE */
+ *font:x-small; /* for IE in quirks mode */
+}
+
+h1 { font-size: 146.5%; /* 19pt */ }
+h2 { font-size: 131%; /* 17pt */ }
+h3 { font-size: 116%; /* 15pt */ }
+h4 { font-size: 100%; /* 13pt */ }
+h5 { font-size: 100%; /* 13pt */ }
+
+select, input, button, textarea {
+ font:99% sans-serif;
+}
+
+table {
+ font-size:inherit;
+ font:100%;
+}
+
+pre, code, kbd, samp, tt, .src {
+ font-family:monospace;
+ *font-size:108%;
+ line-height: 124%;
+}
+
+.links, .link {
+ font-size: 85%; /* 11pt */
+}
+
+#module-header .caption {
+ font-size: 182%; /* 24pt */
+}
+
+.info {
+ font-size: 85%; /* 11pt */
+}
+
+#table-of-contents, #synopsis {
+ /* font-size: 85%; /* 11pt */
+}
+
+
+/* @end */
+
+/* @group Common */
+
+.caption, h1, h2, h3, h4, h5, h6 {
+ font-weight: bold;
+ color: rgb(78,98,114);
+ margin: 0.8em 0 0.4em;
+}
+
+* + h1, * + h2, * + h3, * + h4, * + h5, * + h6 {
+ margin-top: 2em;
+}
+
+h1 + h2, h2 + h3, h3 + h4, h4 + h5, h5 + h6 {
+ margin-top: inherit;
+}
+
+ul.links {
+ list-style: none;
+ text-align: left;
+ float: right;
+ display: inline-table;
+ margin: 0 0 0 1em;
+}
+
+ul.links li {
+ display: inline;
+ border-left: 1px solid #d5d5d5;
+ white-space: nowrap;
+ padding: 0;
+}
+
+ul.links li a {
+ padding: 0.2em 0.5em;
+}
+
+.hide { display: none; }
+.show { display: inherit; }
+.clear { clear: both; }
+
+.collapser {
+ background-image: url(minus.gif);
+ background-repeat: no-repeat;
+}
+.expander {
+ background-image: url(plus.gif);
+ background-repeat: no-repeat;
+}
+p.caption.collapser,
+p.caption.expander {
+ background-position: 0 0.4em;
+}
+.collapser, .expander {
+ padding-left: 14px;
+ margin-left: -14px;
+ cursor: pointer;
+}
+
+pre {
+ padding: 0.25em;
+ margin: 0.8em 0;
+ background: rgb(229,237,244);
+ overflow: auto;
+ border-bottom: 0.25em solid white;
+ /* white border adds some space below the box to compensate
+ for visual extra space that paragraphs have between baseline
+ and the bounding box */
+}
+
+.src {
+ background: #f0f0f0;
+ padding: 0.2em 0.5em;
+}
+
+.keyword { font-weight: normal; }
+.def { font-weight: bold; }
+
+
+/* @end */
+
+/* @group Page Structure */
+
+#content {
+ margin: 0 auto;
+ padding: 0 2em 6em;
+}
+
+#package-header {
+ background: rgb(41,56,69);
+ border-top: 5px solid rgb(78,98,114);
+ color: #ddd;
+ padding: 0.2em;
+ position: relative;
+ text-align: left;
+}
+
+#package-header .caption {
+ background: url(hslogo-16.png) no-repeat 0em;
+ color: white;
+ margin: 0 2em;
+ font-weight: normal;
+ font-style: normal;
+ padding-left: 2em;
+}
+
+#package-header a:link, #package-header a:visited { color: white; }
+#package-header a:hover { background: rgb(78,98,114); }
+
+#module-header .caption {
+ color: rgb(78,98,114);
+ font-weight: bold;
+ border-bottom: 1px solid #ddd;
+}
+
+table.info {
+ float: right;
+ padding: 0.5em 1em;
+ border: 1px solid #ddd;
+ color: rgb(78,98,114);
+ background-color: #fff;
+ max-width: 40%;
+ border-spacing: 0;
+ position: relative;
+ top: -0.5em;
+ margin: 0 0 0 2em;
+}
+
+.info th {
+ padding: 0 1em 0 0;
+}
+
+div#style-menu-holder {
+ position: relative;
+ z-index: 2;
+ display: inline;
+}
+
+#style-menu {
+ position: absolute;
+ z-index: 1;
+ overflow: visible;
+ background: #374c5e;
+ margin: 0;
+ text-align: center;
+ right: 0;
+ padding: 0;
+ top: 1.25em;
+}
+
+#style-menu li {
+ display: list-item;
+ border-style: none;
+ margin: 0;
+ padding: 0;
+ color: #000;
+ list-style-type: none;
+}
+
+#style-menu li + li {
+ border-top: 1px solid #919191;
+}
+
+#style-menu a {
+ width: 6em;
+ padding: 3px;
+ display: block;
+}
+
+#footer {
+ background: #ddd;
+ border-top: 1px solid #aaa;
+ padding: 0.5em 0;
+ color: #666;
+ text-align: center;
+ position: absolute;
+ bottom: 0;
+ width: 100%;
+ height: 3em;
+}
+
+/* @end */
+
+/* @group Front Matter */
+
+#table-of-contents {
+ float: right;
+ clear: right;
+ background: #faf9dc;
+ border: 1px solid #d8d7ad;
+ padding: 0.5em 1em;
+ max-width: 20em;
+ margin: 0.5em 0 1em 1em;
+}
+
+#table-of-contents .caption {
+ text-align: center;
+ margin: 0;
+}
+
+#table-of-contents ul {
+ list-style: none;
+ margin: 0;
+}
+
+#table-of-contents ul ul {
+ margin-left: 2em;
+}
+
+#description .caption {
+ display: none;
+}
+
+#synopsis {
+ display: none;
+}
+
+.no-frame #synopsis {
+ display: block;
+ position: fixed;
+ right: 0;
+ height: 80%;
+ top: 10%;
+ padding: 0;
+ max-width: 75%;
+}
+
+#synopsis .caption {
+ float: left;
+ width: 29px;
+ color: rgba(255,255,255,0);
+ height: 110px;
+ margin: 0;
+ font-size: 1px;
+ padding: 0;
+}
+
+#synopsis p.caption.collapser {
+ background: url(synopsis.png) no-repeat -64px -8px;
+}
+
+#synopsis p.caption.expander {
+ background: url(synopsis.png) no-repeat 0px -8px;
+}
+
+#synopsis ul {
+ height: 100%;
+ overflow: auto;
+ padding: 0.5em;
+ margin: 0;
+}
+
+#synopsis ul ul {
+ overflow: hidden;
+}
+
+#synopsis ul,
+#synopsis ul li.src {
+ background-color: #faf9dc;
+ white-space: nowrap;
+ list-style: none;
+ margin-left: 0;
+}
+
+/* @end */
+
+/* @group Main Content */
+
+#interface div.top { margin: 2em 0; }
+#interface h1 + div.top,
+#interface h2 + div.top,
+#interface h3 + div.top,
+#interface h4 + div.top,
+#interface h5 + div.top {
+ margin-top: 1em;
+}
+#interface p.src .link {
+ float: right;
+ color: #919191;
+ border-left: 1px solid #919191;
+ background: #f0f0f0;
+ padding: 0 0.5em 0.2em;
+ margin: 0 -0.5em 0 0.5em;
+}
+
+#interface td.src .link {
+ float: right;
+ color: #919191;
+ border-left: 1px solid #919191;
+ background: #f0f0f0;
+ padding: 0 0.5em 0.2em;
+ margin: 0 -0.5em 0 0.5em;
+}
+
+#interface span.fixity {
+ color: #919191;
+ border-left: 1px solid #919191;
+ padding: 0.2em 0.5em 0.2em 0.5em;
+ margin: 0 -1em 0 1em;
+}
+
+#interface span.rightedge {
+ border-left: 1px solid #919191;
+ padding: 0.2em 0 0.2em 0;
+ margin: 0 0 0 1em;
+}
+
+#interface table { border-spacing: 2px; }
+#interface td {
+ vertical-align: top;
+ padding-left: 0.5em;
+}
+#interface td.src {
+ white-space: nowrap;
+}
+#interface td.doc p {
+ margin: 0;
+}
+#interface td.doc p + p {
+ margin-top: 0.8em;
+}
+
+.subs dl {
+ margin: 0;
+}
+
+.subs dt {
+ float: left;
+ clear: left;
+ display: block;
+ margin: 1px 0;
+}
+
+.subs dd {
+ float: right;
+ width: 90%;
+ display: block;
+ padding-left: 0.5em;
+ margin-bottom: 0.5em;
+}
+
+.subs dd.empty {
+ display: none;
+}
+
+.subs dd p {
+ margin: 0;
+}
+
+/* Render short-style data instances */
+.inst ul {
+ height: 100%;
+ padding: 0.5em;
+ margin: 0;
+}
+
+.inst, .inst li {
+ list-style: none;
+ margin-left: 1em;
+}
+
+.top p.src {
+ border-top: 1px solid #ccc;
+}
+
+.subs, .doc {
+ /* use this selector for one level of indent */
+ padding-left: 2em;
+}
+
+.warning {
+ color: red;
+}
+
+.arguments {
+ margin-top: -0.4em;
+}
+.arguments .caption {
+ display: none;
+}
+
+.fields { padding-left: 1em; }
+
+.fields .caption { display: none; }
+
+.fields p { margin: 0 0; }
+
+/* this seems bulky to me
+.methods, .constructors {
+ background: #f8f8f8;
+ border: 1px solid #eee;
+}
+*/
+
+/* @end */
+
+/* @group Auxillary Pages */
+
+
+.extension-list {
+ list-style-type: none;
+ margin-left: 0;
+}
+
+#mini {
+ margin: 0 auto;
+ padding: 0 1em 1em;
+}
+
+#mini > * {
+ font-size: 93%; /* 12pt */
+}
+
+#mini #module-list .caption,
+#mini #module-header .caption {
+ font-size: 125%; /* 15pt */
+}
+
+#mini #interface h1,
+#mini #interface h2,
+#mini #interface h3,
+#mini #interface h4 {
+ font-size: 109%; /* 13pt */
+ margin: 1em 0 0;
+}
+
+#mini #interface .top,
+#mini #interface .src {
+ margin: 0;
+}
+
+#mini #module-list ul {
+ list-style: none;
+ margin: 0;
+}
+
+#alphabet ul {
+ list-style: none;
+ padding: 0;
+ margin: 0.5em 0 0;
+ text-align: center;
+}
+
+#alphabet li {
+ display: inline;
+ margin: 0 0.25em;
+}
+
+#alphabet a {
+ font-weight: bold;
+}
+
+#index .caption,
+#module-list .caption { font-size: 131%; /* 17pt */ }
+
+#index table {
+ margin-left: 2em;
+}
+
+#index .src {
+ font-weight: bold;
+}
+#index .alt {
+ font-size: 77%; /* 10pt */
+ font-style: italic;
+ padding-left: 2em;
+}
+
+#index td + td {
+ padding-left: 1em;
+}
+
+#module-list ul {
+ list-style: none;
+ margin: 0 0 0 2em;
+}
+
+#module-list li {
+ clear: right;
+}
+
+#module-list span.collapser,
+#module-list span.expander {
+ background-position: 0 0.3em;
+}
+
+#module-list .package {
+ float: right;
+}
+
+/* @end */
diff --git a/plus.gif b/plus.gif
new file mode 100644
index 0000000..2d15c14
Binary files /dev/null and b/plus.gif differ
diff --git a/src/Ldap-Asn1-FromAsn1.html b/src/Ldap-Asn1-FromAsn1.html
new file mode 100644
index 0000000..b526d8a
--- /dev/null
+++ b/src/Ldap-Asn1-FromAsn1.html
@@ -0,0 +1,389 @@
+
+
+
+
+
+src/Ldap/Asn1/FromAsn1.hs
+
+
+
+
+module Ldap . Asn1 . FromAsn1
+ ( FromAsn1 ( .. )
+ , Parser
+ , parseAsn1
+ , parse
+ , next
+ ) where
+
+#if __GLASGOW_HASKELL__ >= 710
+import Control . Applicative ( Alternative ( .. ) , liftA2 , optional )
+#else
+import Control . Applicative ( Applicative ( .. ) , Alternative ( .. ) , liftA2 , optional )
+#endif
+import Control . Monad ( MonadPlus ( .. ) , ( >=> ) , guard )
+import Data . ASN1 . Types ( ASN1 )
+import qualified Data . ASN1 . Types as Asn1
+import Data . Foldable ( asum )
+import Data . List . NonEmpty ( some1 )
+import qualified Data . Text . Encoding as Text
+
+import Ldap . Asn1 . Type
+
+
+
+
+
+class FromAsn1 a where
+ fromAsn1 :: Parser [ ASN1 ] a
+
+
+instance FromAsn1 op => FromAsn1 ( LdapMessage op ) where
+ fromAsn1 = do
+ Asn1 . Start Asn1 . Sequence <- next
+ i <- fromAsn1
+ op <- fromAsn1
+ Asn1 . End Asn1 . Sequence <- next
+ return ( LdapMessage i op Nothing )
+
+
+instance FromAsn1 Id where
+ fromAsn1 = do
+ Asn1 . IntVal i <- next
+ return ( Id ( fromIntegral i ) )
+
+
+instance FromAsn1 LdapString where
+ fromAsn1 = do
+ Asn1 . OctetString s <- next
+ case Text . decodeUtf8' s of
+ Right t -> return ( LdapString t )
+ Left _ -> empty
+
+
+instance FromAsn1 LdapOid where
+ fromAsn1 = do
+ Asn1 . OctetString s <- next
+ return ( LdapOid s )
+
+
+instance FromAsn1 LdapDn where
+ fromAsn1 = fmap LdapDn fromAsn1
+
+
+instance FromAsn1 AttributeDescription where
+ fromAsn1 = fmap AttributeDescription fromAsn1
+
+
+instance FromAsn1 AttributeValue where
+ fromAsn1 = do
+ Asn1 . OctetString s <- next
+ return ( AttributeValue s )
+
+
+instance FromAsn1 PartialAttribute where
+ fromAsn1 = do
+ Asn1 . Start Asn1 . Sequence <- next
+ d <- fromAsn1
+ Asn1 . Start Asn1 . Set <- next
+ vs <- many fromAsn1
+ Asn1 . End Asn1 . Set <- next
+ Asn1 . End Asn1 . Sequence <- next
+ return ( PartialAttribute d vs )
+
+
+instance FromAsn1 LdapResult where
+ fromAsn1 = do
+ resultCode <- do
+ Asn1 . Enumerated x <- next
+ case x of
+ 0 -> pure Success
+ 1 -> pure OperationError
+ 2 -> pure ProtocolError
+ 3 -> pure TimeLimitExceeded
+ 4 -> pure SizeLimitExceeded
+ 5 -> pure CompareFalse
+ 6 -> pure CompareTrue
+ 7 -> pure AuthMethodNotSupported
+ 8 -> pure StrongerAuthRequired
+ 10 -> pure Referral
+ 11 -> pure AdminLimitExceeded
+ 12 -> pure UnavailableCriticalExtension
+ 13 -> pure ConfidentialityRequired
+ 14 -> pure SaslBindInProgress
+ 16 -> pure NoSuchAttribute
+ 17 -> pure UndefinedAttributeType
+ 18 -> pure InappropriateMatching
+ 19 -> pure ConstraintViolation
+ 20 -> pure AttributeOrValueExists
+ 21 -> pure InvalidAttributeSyntax
+ 32 -> pure NoSuchObject
+ 33 -> pure AliasProblem
+ 34 -> pure InvalidDNSyntax
+ 36 -> pure AliasDereferencingProblem
+ 48 -> pure InappropriateAuthentication
+ 49 -> pure InvalidCredentials
+ 50 -> pure InsufficientAccessRights
+ 51 -> pure Busy
+ 52 -> pure Unavailable
+ 53 -> pure UnwillingToPerform
+ 54 -> pure LoopDetect
+ 64 -> pure NamingViolation
+ 65 -> pure ObjectClassViolation
+ 66 -> pure NotAllowedOnNonLeaf
+ 67 -> pure NotAllowedOnRDN
+ 68 -> pure EntryAlreadyExists
+ 69 -> pure ObjectClassModsProhibited
+ 71 -> pure AffectsMultipleDSAs
+ 80 -> pure Other
+ _ -> empty
+ matchedDn <- fromAsn1
+ diagnosticMessage
+ <- fromAsn1
+ referral <- optional $ do
+ Asn1 . Start ( Asn1 . Container Asn1 . Context 0 ) <- next
+ x <- fromAsn1
+ Asn1 . End ( Asn1 . Container Asn1 . Context 0 ) <- next
+ return x
+ return ( LdapResult resultCode matchedDn diagnosticMessage referral )
+
+
+instance FromAsn1 ReferralUris where
+ fromAsn1 = do
+ Asn1 . Start Asn1 . Sequence <- next
+ xs <- some1 fromAsn1
+ Asn1 . End Asn1 . Sequence <- next
+ return ( ReferralUris xs )
+
+
+instance FromAsn1 Uri where
+ fromAsn1 = fmap Uri fromAsn1
+
+
+instance FromAsn1 ProtocolServerOp where
+ fromAsn1 = asum
+ [ fmap ( \ res -> BindResponse res Nothing ) ( app 1 )
+ , fmap ( uncurry SearchResultEntry ) ( app 4 )
+ , fmap SearchResultDone ( app 5 )
+ , fmap ModifyResponse ( app 7 )
+ , fmap AddResponse ( app 9 )
+ , fmap DeleteResponse ( app 11 )
+ , fmap ModifyDnResponse ( app 13 )
+ , fmap CompareResponse ( app 15 )
+ , do
+ Asn1 . Start ( Asn1 . Container Asn1 . Application 24 ) <- next
+ res <- fromAsn1
+ name <- optional $ do
+ Asn1 . Other Asn1 . Context 0 s <- next
+ return s
+ value <- optional $ do
+ Asn1 . Other Asn1 . Context 1 s <- next
+ return s
+ Asn1 . End ( Asn1 . Container Asn1 . Application 24 ) <- next
+ return ( ExtendedResponse res ( fmap LdapOid name ) value )
+ ]
+ where
+ app l = do
+ Asn1 . Start ( Asn1 . Container Asn1 . Application x ) <- next
+ guard ( x == l )
+ res <- fromAsn1
+ Asn1 . End ( Asn1 . Container Asn1 . Application y ) <- next
+ guard ( y == l )
+ return res
+
+
+instance FromAsn1 PartialAttributeList where
+ fromAsn1 = do
+ Asn1 . Start Asn1 . Sequence <- next
+ xs <- many fromAsn1
+ Asn1 . End Asn1 . Sequence <- next
+ return ( PartialAttributeList xs )
+
+instance ( FromAsn1 a , FromAsn1 b ) => FromAsn1 ( a , b ) where
+ fromAsn1 = liftA2 (,) fromAsn1 fromAsn1
+
+
+newtype Parser s a = Parser { unParser :: s -> Maybe ( s , a ) }
+
+instance Functor ( Parser s ) where
+ fmap f ( Parser g ) = Parser ( fmap ( fmap f ) . g )
+
+instance Applicative ( Parser s ) where
+ pure x = Parser ( \ s -> pure ( s , x ) )
+ Parser mf <*> Parser mx = Parser $ \ s -> do
+ ( s' , f ) <- mf s
+ ( s'' , x ) <- mx s'
+ pure ( s'' , f x )
+
+instance Alternative ( Parser s ) where
+ empty = Parser ( \ _ -> empty )
+ Parser ma <|> Parser mb =
+ Parser ( \ s -> ma s <|> mb s )
+
+instance Monad ( Parser s ) where
+ return x = Parser ( \ s -> return ( s , x ) )
+ Parser mx >>= k =
+ Parser ( mx >=> \ ( s' , x ) -> unParser ( k x ) s' )
+ fail _ = empty
+
+instance MonadPlus ( Parser s ) where
+ mzero = Parser ( \ _ -> mzero )
+ Parser ma `mplus` Parser mb =
+ Parser ( \ s -> ma s `mplus` mb s )
+
+parseAsn1 :: FromAsn1 a => [ ASN1 ] -> Maybe ( [ ASN1 ] , a )
+parseAsn1 = parse fromAsn1
+
+parse :: Parser s a -> s -> Maybe ( s , a )
+parse = unParser
+
+next :: Parser [ s ] s
+next = Parser ( \ s -> case s of [] -> Nothing ; x : xs -> Just ( xs , x ) )
+
+
diff --git a/src/Ldap-Asn1-ToAsn1.html b/src/Ldap-Asn1-ToAsn1.html
new file mode 100644
index 0000000..90e7770
--- /dev/null
+++ b/src/Ldap-Asn1-ToAsn1.html
@@ -0,0 +1,432 @@
+
+
+
+
+
+src/Ldap/Asn1/ToAsn1.hs
+
+
+
+module Ldap . Asn1 . ToAsn1
+ ( ToAsn1 ( toAsn1 )
+ ) where
+
+import Data . ASN1 . Types ( ASN1 , ASN1Class , ASN1Tag , ASN1ConstructionType )
+import qualified Data . ASN1 . Types as Asn1
+import Data . ByteString ( ByteString )
+import Data . Foldable ( fold , foldMap )
+import Data . List . NonEmpty ( NonEmpty )
+import Data . Maybe ( Maybe , maybe )
+import Data . Monoid ( Endo ( Endo ) , ( <> ) , mempty )
+import qualified Data . Text . Encoding as Text
+import Prelude ( Integer , ( . ) , fromIntegral )
+
+import Ldap . Asn1 . Type
+
+
+class ToAsn1 a where
+ toAsn1 :: a -> Endo [ ASN1 ]
+
+
+instance ToAsn1 op => ToAsn1 ( LdapMessage op ) where
+ toAsn1 ( LdapMessage i op mc ) =
+ sequence ( toAsn1 i <> toAsn1 op <> maybe mempty ( context 0 . toAsn1 ) mc )
+
+
+instance ToAsn1 Id where
+ toAsn1 ( Id i ) = single ( Asn1 . IntVal ( fromIntegral i ) )
+
+
+instance ToAsn1 LdapString where
+ toAsn1 ( LdapString s ) = single ( Asn1 . OctetString ( Text . encodeUtf8 s ) )
+
+
+instance ToAsn1 LdapOid where
+ toAsn1 ( LdapOid s ) = single ( Asn1 . OctetString s )
+
+
+instance ToAsn1 LdapDn where
+ toAsn1 ( LdapDn s ) = toAsn1 s
+
+
+instance ToAsn1 RelativeLdapDn where
+ toAsn1 ( RelativeLdapDn s ) = toAsn1 s
+
+
+instance ToAsn1 AttributeDescription where
+ toAsn1 ( AttributeDescription s ) = toAsn1 s
+
+
+instance ToAsn1 AttributeValue where
+ toAsn1 ( AttributeValue s ) = single ( Asn1 . OctetString s )
+
+
+instance ToAsn1 AttributeValueAssertion where
+ toAsn1 ( AttributeValueAssertion d v ) = toAsn1 d <> toAsn1 v
+
+
+instance ToAsn1 AssertionValue where
+ toAsn1 ( AssertionValue s ) = single ( Asn1 . OctetString s )
+
+
+
+instance ToAsn1 PartialAttribute where
+ toAsn1 ( PartialAttribute d xs ) = sequence ( toAsn1 d <> set ( toAsn1 xs ) )
+
+
+instance ToAsn1 Attribute where
+ toAsn1 ( Attribute d xs ) = sequence ( toAsn1 d <> set ( toAsn1 xs ) )
+
+
+instance ToAsn1 MatchingRuleId where
+ toAsn1 ( MatchingRuleId s ) = toAsn1 s
+
+
+instance ToAsn1 Controls where
+ toAsn1 ( Controls cs ) = sequence ( toAsn1 cs )
+
+
+instance ToAsn1 Control where
+ toAsn1 ( Control t c v ) =
+ sequence ( fold
+ [ toAsn1 t
+ , single ( Asn1 . Boolean c )
+ , maybe mempty ( single . Asn1 . OctetString ) v
+ ] )
+
+
+instance ToAsn1 ProtocolClientOp where
+ toAsn1 ( BindRequest v n a ) =
+ application 0 ( single ( Asn1 . IntVal ( fromIntegral v ) ) <> toAsn1 n <> toAsn1 a )
+ toAsn1 UnbindRequest =
+ other Asn1 . Application 2 mempty
+ toAsn1 ( SearchRequest bo s da sl tl to f a ) =
+ application 3 ( fold
+ [ toAsn1 bo
+ , enum s'
+ , enum da'
+ , single ( Asn1 . IntVal ( fromIntegral sl ) )
+ , single ( Asn1 . IntVal ( fromIntegral tl ) )
+ , single ( Asn1 . Boolean to )
+ , toAsn1 f
+ , toAsn1 a
+ ] )
+ where
+ s' = case s of
+ BaseObject -> 0
+ SingleLevel -> 1
+ WholeSubtree -> 2
+ da' = case da of
+ NeverDerefAliases -> 0
+ DerefInSearching -> 1
+ DerefFindingBaseObject -> 2
+ DerefAlways -> 3
+ toAsn1 ( ModifyRequest dn xs ) =
+ application 6 ( fold
+ [ toAsn1 dn
+ , sequence ( foldMap ( \ ( op , pa ) -> sequence ( enum ( case op of
+ Add -> 0
+ Delete -> 1
+ Replace -> 2 ) <> toAsn1 pa ) ) xs )
+ ] )
+ toAsn1 ( AddRequest dn as ) =
+ application 8 ( toAsn1 dn <> toAsn1 as )
+ toAsn1 ( DeleteRequest ( LdapDn ( LdapString dn ) ) ) =
+ other Asn1 . Application 10 ( Text . encodeUtf8 dn )
+ toAsn1 ( ModifyDnRequest dn rdn del new ) =
+ application 12 ( fold
+ [ toAsn1 dn
+ , toAsn1 rdn
+ , single ( Asn1 . Boolean del )
+ , maybe mempty
+ ( \ ( LdapDn ( LdapString dn' ) ) -> other Asn1 . Context 0 ( Text . encodeUtf8 dn' ) )
+ new
+ ] )
+ toAsn1 ( CompareRequest dn av ) =
+ application 14 ( toAsn1 dn <> sequence ( toAsn1 av ) )
+ toAsn1 ( ExtendedRequest ( LdapOid oid ) mv ) =
+ application 23 ( fold
+ [ other Asn1 . Context 0 oid
+ , maybe mempty ( other Asn1 . Context 1 ) mv
+ ] )
+
+
+instance ToAsn1 AuthenticationChoice where
+ toAsn1 ( Simple s ) = other Asn1 . Context 0 s
+
+
+instance ToAsn1 AttributeSelection where
+ toAsn1 ( AttributeSelection as ) = sequence ( toAsn1 as )
+
+
+instance ToAsn1 Filter where
+ toAsn1 f = case f of
+ And xs -> context 0 ( toAsn1 xs )
+ Or xs -> context 1 ( toAsn1 xs )
+ Not x -> context 2 ( toAsn1 x )
+ EqualityMatch x -> context 3 ( toAsn1 x )
+ Substrings x -> context 4 ( toAsn1 x )
+ GreaterOrEqual x -> context 5 ( toAsn1 x )
+ LessOrEqual x -> context 6 ( toAsn1 x )
+ Present ( AttributeDescription ( LdapString x ) )
+ -> other Asn1 . Context 7 ( Text . encodeUtf8 x )
+ ApproxMatch x -> context 8 ( toAsn1 x )
+ ExtensibleMatch x -> context 9 ( toAsn1 x )
+
+
+instance ToAsn1 SubstringFilter where
+ toAsn1 ( SubstringFilter ad ss ) =
+ toAsn1 ad <> sequence ( foldMap ( \ s -> case s of
+ Initial ( AssertionValue v ) -> other Asn1 . Context 0 v
+ Any ( AssertionValue v ) -> other Asn1 . Context 1 v
+ Final ( AssertionValue v ) -> other Asn1 . Context 2 v ) ss )
+
+
+instance ToAsn1 MatchingRuleAssertion where
+ toAsn1 ( MatchingRuleAssertion mmr mad av b ) = sequence ( fold
+ [ context 1 ( optional mmr )
+ , context 2 ( optional mad )
+ , context 3 ( toAsn1 av )
+ , context 4 ( single ( Asn1 . Boolean b ) )
+ ] )
+
+
+instance ToAsn1 AttributeList where
+ toAsn1 ( AttributeList xs ) = sequence ( toAsn1 xs )
+
+instance ToAsn1 a => ToAsn1 [ a ] where
+ toAsn1 = foldMap toAsn1
+
+instance ToAsn1 a => ToAsn1 ( NonEmpty a ) where
+ toAsn1 = foldMap toAsn1
+
+sequence :: Endo [ ASN1 ] -> Endo [ ASN1 ]
+sequence = construction Asn1 . Sequence
+
+set :: Endo [ ASN1 ] -> Endo [ ASN1 ]
+set = construction Asn1 . Set
+
+application :: ASN1Tag -> Endo [ ASN1 ] -> Endo [ ASN1 ]
+application = construction . Asn1 . Container Asn1 . Application
+
+context :: ASN1Tag -> Endo [ ASN1 ] -> Endo [ ASN1 ]
+context = construction . Asn1 . Container Asn1 . Context
+
+construction :: ASN1ConstructionType -> Endo [ ASN1 ] -> Endo [ ASN1 ]
+construction t x = single ( Asn1 . Start t ) <> x <> single ( Asn1 . End t )
+
+other :: ASN1Class -> ASN1Tag -> ByteString -> Endo [ ASN1 ]
+other c t = single . Asn1 . Other c t
+
+optional :: ToAsn1 a => Maybe a -> Endo [ ASN1 ]
+optional = maybe mempty toAsn1
+
+enum :: Integer -> Endo [ ASN1 ]
+enum = single . Asn1 . Enumerated
+
+single :: a -> Endo [ a ]
+single x = Endo ( x : )
+
+
diff --git a/src/Ldap-Asn1-Type.html b/src/Ldap-Asn1-Type.html
new file mode 100644
index 0000000..26e7fb2
--- /dev/null
+++ b/src/Ldap-Asn1-Type.html
@@ -0,0 +1,202 @@
+
+
+
+
+
+src/Ldap/Asn1/Type.hs
+
+
+
+module Ldap . Asn1 . Type where
+
+import Data . ByteString ( ByteString )
+import Data . Int ( Int8 , Int32 )
+import Data . List . NonEmpty ( NonEmpty )
+import Data . Text ( Text )
+
+
+data LdapMessage op = LdapMessage
+ { ldapMessageId :: ! Id
+ , ldapMessageOp :: ! op
+ , ldapMessageControls :: ! ( Maybe Controls )
+ } deriving ( Show , Eq , Ord )
+
+newtype Id = Id { unId :: Int32 }
+ deriving ( Show , Eq , Ord )
+
+data ProtocolClientOp =
+ BindRequest Int8 LdapDn AuthenticationChoice
+ | UnbindRequest
+ | SearchRequest LdapDn Scope DerefAliases Int32 Int32 Bool Filter AttributeSelection
+ | ModifyRequest LdapDn [ ( Operation , PartialAttribute ) ]
+ | AddRequest LdapDn AttributeList
+ | DeleteRequest LdapDn
+ | ModifyDnRequest LdapDn RelativeLdapDn Bool ( Maybe LdapDn )
+ | CompareRequest LdapDn AttributeValueAssertion
+ | ExtendedRequest LdapOid ( Maybe ByteString )
+ deriving ( Show , Eq , Ord )
+
+data ProtocolServerOp =
+ BindResponse LdapResult ( Maybe ByteString )
+ | SearchResultEntry LdapDn PartialAttributeList
+ | SearchResultReference ( NonEmpty Uri )
+ | SearchResultDone ( LdapResult )
+ | ModifyResponse LdapResult
+ | AddResponse LdapResult
+ | DeleteResponse LdapResult
+ | ModifyDnResponse LdapResult
+ | CompareResponse LdapResult
+ | ExtendedResponse LdapResult ( Maybe LdapOid ) ( Maybe ByteString )
+ deriving ( Show , Eq , Ord )
+
+data AuthenticationChoice = Simple ByteString
+ deriving ( Show , Eq , Ord )
+
+data Scope =
+ BaseObject
+ | SingleLevel
+ | WholeSubtree
+ deriving ( Show , Eq , Ord )
+
+data DerefAliases =
+ NeverDerefAliases
+ | DerefInSearching
+ | DerefFindingBaseObject
+ | DerefAlways
+ deriving ( Show , Eq , Ord )
+
+data Filter =
+ And ( NonEmpty Filter )
+ | Or ( NonEmpty Filter )
+ | Not Filter
+ | EqualityMatch AttributeValueAssertion
+ | Substrings SubstringFilter
+ | GreaterOrEqual AttributeValueAssertion
+ | LessOrEqual AttributeValueAssertion
+ | Present AttributeDescription
+ | ApproxMatch AttributeValueAssertion
+ | ExtensibleMatch MatchingRuleAssertion
+ deriving ( Show , Eq , Ord )
+
+data SubstringFilter = SubstringFilter AttributeDescription ( NonEmpty Substring )
+ deriving ( Show , Eq , Ord )
+
+data Substring =
+ Initial AssertionValue
+ | Any AssertionValue
+ | Final AssertionValue
+ deriving ( Show , Eq , Ord )
+
+data MatchingRuleAssertion = MatchingRuleAssertion ( Maybe MatchingRuleId ) ( Maybe AttributeDescription ) AssertionValue Bool
+ deriving ( Show , Eq , Ord )
+
+newtype MatchingRuleId = MatchingRuleId LdapString
+ deriving ( Show , Eq , Ord )
+
+newtype AttributeSelection = AttributeSelection [ LdapString ]
+ deriving ( Show , Eq , Ord )
+
+newtype AttributeList = AttributeList [ Attribute ]
+ deriving ( Show , Eq , Ord )
+
+newtype PartialAttributeList = PartialAttributeList [ PartialAttribute ]
+ deriving ( Show , Eq , Ord )
+
+newtype Controls = Controls [ Control ]
+ deriving ( Show , Eq , Ord )
+
+data Control = Control LdapOid Bool ( Maybe ByteString )
+ deriving ( Show , Eq , Ord )
+
+data LdapResult = LdapResult ResultCode LdapDn LdapString ( Maybe ReferralUris )
+ deriving ( Show , Eq , Ord )
+
+data ResultCode =
+ Success
+ | OperationError
+ | ProtocolError
+ | TimeLimitExceeded
+ | SizeLimitExceeded
+ | CompareFalse
+ | CompareTrue
+ | AuthMethodNotSupported
+ | StrongerAuthRequired
+ | Referral
+ | AdminLimitExceeded
+ | UnavailableCriticalExtension
+ | ConfidentialityRequired
+ | SaslBindInProgress
+ | NoSuchAttribute
+ | UndefinedAttributeType
+ | InappropriateMatching
+ | ConstraintViolation
+ | AttributeOrValueExists
+ | InvalidAttributeSyntax
+ | NoSuchObject
+ | AliasProblem
+ | InvalidDNSyntax
+ | AliasDereferencingProblem
+ | InappropriateAuthentication
+ | InvalidCredentials
+ | InsufficientAccessRights
+ | Busy
+ | Unavailable
+ | UnwillingToPerform
+ | LoopDetect
+ | NamingViolation
+ | ObjectClassViolation
+ | NotAllowedOnNonLeaf
+ | NotAllowedOnRDN
+ | EntryAlreadyExists
+ | ObjectClassModsProhibited
+ | AffectsMultipleDSAs
+ | Other
+ deriving ( Show , Eq , Ord )
+
+newtype AttributeDescription = AttributeDescription LdapString
+ deriving ( Show , Eq , Ord )
+
+newtype AttributeValue = AttributeValue ByteString
+ deriving ( Show , Eq , Ord )
+
+data AttributeValueAssertion = AttributeValueAssertion AttributeDescription AssertionValue
+ deriving ( Show , Eq , Ord )
+
+newtype AssertionValue = AssertionValue ByteString
+ deriving ( Show , Eq , Ord )
+
+data Attribute = Attribute AttributeDescription ( NonEmpty AttributeValue )
+ deriving ( Show , Eq , Ord )
+
+data PartialAttribute = PartialAttribute AttributeDescription [ AttributeValue ]
+ deriving ( Show , Eq , Ord )
+
+newtype LdapDn = LdapDn LdapString
+ deriving ( Show , Eq , Ord )
+
+newtype RelativeLdapDn = RelativeLdapDn LdapString
+ deriving ( Show , Eq , Ord )
+
+newtype ReferralUris = ReferralUris ( NonEmpty Uri )
+ deriving ( Show , Eq , Ord )
+
+newtype Uri = Uri LdapString
+ deriving ( Show , Eq , Ord )
+
+data Operation =
+ Add
+ | Delete
+ | Replace
+ deriving ( Show , Eq , Ord )
+
+
+
+
+
+newtype LdapString = LdapString Text
+ deriving ( Show , Eq , Ord )
+
+newtype LdapOid = LdapOid ByteString
+ deriving ( Show , Eq , Ord )
+
+
diff --git a/src/Ldap-Client-Add.html b/src/Ldap-Client-Add.html
new file mode 100644
index 0000000..4337346
--- /dev/null
+++ b/src/Ldap-Client-Add.html
@@ -0,0 +1,55 @@
+
+
+
+
+
+src/Ldap/Client/Add.hs
+
+
+
+module Ldap . Client . Add
+ ( add
+ , addEither
+ , addAsync
+ , addAsyncSTM
+ ) where
+
+import Control . Monad . STM ( STM , atomically )
+import Data . List . NonEmpty ( NonEmpty ( ( :| ) ) )
+
+import qualified Ldap . Asn1 . Type as Type
+import Ldap . Client . Internal
+
+
+add :: Ldap -> Dn -> AttrList NonEmpty -> IO ()
+add l dn as =
+ raise =<< addEither l dn as
+
+addEither :: Ldap -> Dn -> AttrList NonEmpty -> IO ( Either ResponseError () )
+addEither l dn as =
+ wait =<< addAsync l dn as
+
+addAsync :: Ldap -> Dn -> AttrList NonEmpty -> IO ( Async () )
+addAsync l dn as =
+ atomically ( addAsyncSTM l dn as )
+
+addAsyncSTM :: Ldap -> Dn -> AttrList NonEmpty -> STM ( Async () )
+addAsyncSTM l dn as =
+ let req = addRequest dn as in sendRequest l ( addResult req ) req
+
+addRequest :: Dn -> AttrList NonEmpty -> Request
+addRequest ( Dn dn ) as =
+ Type . AddRequest ( Type . LdapDn ( Type . LdapString dn ) )
+ ( Type . AttributeList ( map f as ) )
+ where
+ f ( Attr x , xs ) = Type . Attribute ( Type . AttributeDescription ( Type . LdapString x ) )
+ ( fmap Type . AttributeValue xs )
+
+addResult :: Request -> Response -> Either ResponseError ()
+addResult req ( Type . AddResponse ( Type . LdapResult code ( Type . LdapDn ( Type . LdapString dn ) )
+ ( Type . LdapString msg ) _ ) :| [] )
+ | Type . Success <- code = Right ()
+ | otherwise = Left ( ResponseErrorCode req code ( Dn dn ) msg )
+addResult req res = Left ( ResponseInvalid req res )
+
+
diff --git a/src/Ldap-Client-Bind.html b/src/Ldap-Client-Bind.html
new file mode 100644
index 0000000..af963cd
--- /dev/null
+++ b/src/Ldap-Client-Bind.html
@@ -0,0 +1,77 @@
+
+
+
+
+
+src/Ldap/Client/Bind.hs
+
+
+
+module Ldap . Client . Bind
+ ( bind
+ , bindEither
+ , bindAsync
+ , bindAsyncSTM
+ , unbindAsync
+ , unbindAsyncSTM
+ ) where
+
+import Control . Monad ( void )
+import Control . Monad . STM ( STM , atomically )
+import Data . List . NonEmpty ( NonEmpty ( ( :| ) ) )
+
+import qualified Ldap . Asn1 . Type as Type
+import Ldap . Client . Internal
+
+
+bind :: Ldap -> Dn -> Password -> IO ()
+bind l username password =
+ raise =<< bindEither l username password
+
+bindEither :: Ldap -> Dn -> Password -> IO ( Either ResponseError () )
+bindEither l username password =
+ wait =<< bindAsync l username password
+
+bindAsync :: Ldap -> Dn -> Password -> IO ( Async () )
+bindAsync l username password =
+ atomically ( bindAsyncSTM l username password )
+
+bindAsyncSTM :: Ldap -> Dn -> Password -> STM ( Async () )
+bindAsyncSTM l username password =
+ let req = bindRequest username password in sendRequest l ( bindResult req ) req
+
+bindRequest :: Dn -> Password -> Request
+bindRequest ( Dn username ) ( Password password ) =
+ Type . BindRequest ldapVersion
+ ( Type . LdapDn ( Type . LdapString username ) )
+ ( Type . Simple password )
+ where
+ ldapVersion = 3
+
+bindResult :: Request -> Response -> Either ResponseError ()
+bindResult req ( Type . BindResponse ( Type . LdapResult code ( Type . LdapDn ( Type . LdapString dn ) )
+ ( Type . LdapString msg ) _ ) _ :| [] )
+ | Type . Success <- code = Right ()
+ | otherwise = Left ( ResponseErrorCode req code ( Dn dn ) msg )
+bindResult req res = Left ( ResponseInvalid req res )
+
+
+
+
+
+
+unbindAsync :: Ldap -> IO ()
+unbindAsync =
+ atomically . unbindAsyncSTM
+
+
+
+
+
+unbindAsyncSTM :: Ldap -> STM ()
+unbindAsyncSTM l =
+ void ( sendRequest l die Type . UnbindRequest )
+ where
+ die = error "Ldap.Client: do not wait for the response to UnbindRequest"
+
+
diff --git a/src/Ldap-Client-Compare.html b/src/Ldap-Client-Compare.html
new file mode 100644
index 0000000..a883caf
--- /dev/null
+++ b/src/Ldap-Client-Compare.html
@@ -0,0 +1,57 @@
+
+
+
+
+
+src/Ldap/Client/Compare.hs
+
+
+
+module Ldap . Client . Compare
+ ( compare
+ , compareEither
+ , compareAsync
+ , compareAsyncSTM
+ ) where
+
+import Control . Monad . STM ( STM , atomically )
+import Data . ByteString ( ByteString )
+import Data . List . NonEmpty ( NonEmpty ( ( :| ) ) )
+import Prelude hiding ( compare )
+
+import Ldap . Client . Internal
+import qualified Ldap . Asn1 . Type as Type
+
+
+compare :: Ldap -> Dn -> Attr -> ByteString -> IO Bool
+compare l dn k v =
+ raise =<< compareEither l dn k v
+
+compareEither :: Ldap -> Dn -> Attr -> ByteString -> IO ( Either ResponseError Bool )
+compareEither l dn k v =
+ wait =<< compareAsync l dn k v
+
+compareAsync :: Ldap -> Dn -> Attr -> ByteString -> IO ( Async Bool )
+compareAsync l dn k v =
+ atomically ( compareAsyncSTM l dn k v )
+
+compareAsyncSTM :: Ldap -> Dn -> Attr -> ByteString -> STM ( Async Bool )
+compareAsyncSTM l dn k v =
+ let req = compareRequest dn k v in sendRequest l ( compareResult req ) req
+
+compareRequest :: Dn -> Attr -> ByteString -> Request
+compareRequest ( Dn dn ) ( Attr k ) v =
+ Type . CompareRequest ( Type . LdapDn ( Type . LdapString dn ) )
+ ( Type . AttributeValueAssertion
+ ( Type . AttributeDescription ( Type . LdapString k ) )
+ ( Type . AssertionValue v ) )
+
+compareResult :: Request -> Response -> Either ResponseError Bool
+compareResult req ( Type . CompareResponse ( Type . LdapResult code ( Type . LdapDn ( Type . LdapString dn ) )
+ ( Type . LdapString msg ) _ ) :| [] )
+ | Type . CompareTrue <- code = Right True
+ | Type . CompareFalse <- code = Right False
+ | otherwise = Left ( ResponseErrorCode req code ( Dn dn ) msg )
+compareResult req res = Left ( ResponseInvalid req res )
+
+
diff --git a/src/Ldap-Client-Delete.html b/src/Ldap-Client-Delete.html
new file mode 100644
index 0000000..c10197e
--- /dev/null
+++ b/src/Ldap-Client-Delete.html
@@ -0,0 +1,51 @@
+
+
+
+
+
+src/Ldap/Client/Delete.hs
+
+
+
+module Ldap . Client . Delete
+ ( delete
+ , deleteEither
+ , deleteAsync
+ , deleteAsyncSTM
+ ) where
+
+import Control . Concurrent . STM ( STM , atomically )
+import Data . List . NonEmpty ( NonEmpty ( ( :| ) ) )
+
+import qualified Ldap . Asn1 . Type as Type
+import Ldap . Client . Internal
+
+
+delete :: Ldap -> Dn -> IO ()
+delete l dn =
+ raise =<< deleteEither l dn
+
+deleteEither :: Ldap -> Dn -> IO ( Either ResponseError () )
+deleteEither l dn =
+ wait =<< deleteAsync l dn
+
+deleteAsync :: Ldap -> Dn -> IO ( Async () )
+deleteAsync l dn =
+ atomically ( deleteAsyncSTM l dn )
+
+deleteAsyncSTM :: Ldap -> Dn -> STM ( Async () )
+deleteAsyncSTM l dn =
+ let req = deleteRequest dn in sendRequest l ( deleteResult req ) req
+
+deleteRequest :: Dn -> Request
+deleteRequest ( Dn dn ) =
+ Type . DeleteRequest ( Type . LdapDn ( Type . LdapString dn ) )
+
+deleteResult :: Request -> Response -> Either ResponseError ()
+deleteResult req ( Type . DeleteResponse ( Type . LdapResult code ( Type . LdapDn ( Type . LdapString dn ) )
+ ( Type . LdapString msg ) _ ) :| [] )
+ | Type . Success <- code = Right ()
+ | otherwise = Left ( ResponseErrorCode req code ( Dn dn ) msg )
+deleteResult req res = Left ( ResponseInvalid req res )
+
+
diff --git a/src/Ldap-Client-Extended.html b/src/Ldap-Client-Extended.html
new file mode 100644
index 0000000..ca12d31
--- /dev/null
+++ b/src/Ldap-Client-Extended.html
@@ -0,0 +1,75 @@
+
+
+
+
+
+src/Ldap/Client/Extended.hs
+
+
+
+
+module Ldap . Client . Extended
+ ( extended
+ , extendedEither
+ , extendedAsync
+ , extendedAsyncSTM
+ , startTls
+ , startTlsEither
+ , startTlsAsync
+ , startTlsAsyncSTM
+ ) where
+
+import Control . Monad ( ( <=< ) )
+import Control . Monad . STM ( STM , atomically )
+import Data . ByteString ( ByteString )
+import Data . List . NonEmpty ( NonEmpty ( ( :| ) ) )
+
+import qualified Ldap . Asn1 . Type as Type
+import Ldap . Client . Internal
+
+
+extended :: Ldap -> Oid -> Maybe ByteString -> IO ()
+extended l oid mv =
+ raise =<< extendedEither l oid mv
+
+extendedEither :: Ldap -> Oid -> Maybe ByteString -> IO ( Either ResponseError () )
+extendedEither l oid mv =
+ wait =<< extendedAsync l oid mv
+
+extendedAsync :: Ldap -> Oid -> Maybe ByteString -> IO ( Async () )
+extendedAsync l oid mv =
+ atomically ( extendedAsyncSTM l oid mv )
+
+extendedAsyncSTM :: Ldap -> Oid -> Maybe ByteString -> STM ( Async () )
+extendedAsyncSTM l oid mv =
+ let req = extendedRequest oid mv in sendRequest l ( extendedResult req ) req
+
+extendedRequest :: Oid -> Maybe ByteString -> Request
+extendedRequest ( Oid oid ) =
+ Type . ExtendedRequest ( Type . LdapOid oid )
+
+extendedResult :: Request -> Response -> Either ResponseError ()
+extendedResult req ( Type . ExtendedResponse ( Type . LdapResult code ( Type . LdapDn ( Type . LdapString dn ) )
+ ( Type . LdapString msg ) _ ) _ _ :| [] )
+ | Type . Success <- code = Right ()
+ | otherwise = Left ( ResponseErrorCode req code ( Dn dn ) msg )
+extendedResult req res = Left ( ResponseInvalid req res )
+
+
+startTls :: Ldap -> IO ()
+startTls =
+ raise <=< startTlsEither
+
+startTlsEither :: Ldap -> IO ( Either ResponseError () )
+startTlsEither =
+ wait <=< startTlsAsync
+
+startTlsAsync :: Ldap -> IO ( Async () )
+startTlsAsync =
+ atomically . startTlsAsyncSTM
+
+startTlsAsyncSTM :: Ldap -> STM ( Async () )
+startTlsAsyncSTM l =
+ extendedAsyncSTM l ( Oid "1.3.6.1.4.1.1466.20037" ) Nothing
+
+
diff --git a/src/Ldap-Client-Internal.html b/src/Ldap-Client-Internal.html
new file mode 100644
index 0000000..733dde5
--- /dev/null
+++ b/src/Ldap-Client-Internal.html
@@ -0,0 +1,123 @@
+
+
+
+
+
+src/Ldap/Client/Internal.hs
+
+
+
+
+
+module Ldap . Client . Internal
+ ( Host ( .. )
+ , PortNumber
+ , Ldap ( .. )
+ , ClientMessage ( .. )
+ , Type . ResultCode ( .. )
+ , Async
+ , Oid ( .. )
+ , AttrList
+
+ , wait
+ , waitSTM
+
+ , Response
+ , ResponseError ( .. )
+ , Request
+ , raise
+ , sendRequest
+ , Dn ( .. )
+ , RelativeDn ( .. )
+ , Password ( .. )
+ , Attr ( .. )
+ , unAttr
+ ) where
+
+import Control . Concurrent . STM ( STM , atomically )
+import Control . Concurrent . STM . TMVar ( TMVar , newEmptyTMVar , readTMVar )
+import Control . Concurrent . STM . TQueue ( TQueue , writeTQueue )
+import Control . Exception ( Exception , throwIO )
+import Data . ByteString ( ByteString )
+import Data . List . NonEmpty ( NonEmpty )
+import Data . Text ( Text )
+import Data . Typeable ( Typeable )
+import Network ( PortNumber )
+
+import qualified Ldap . Asn1 . Type as Type
+
+
+data Host =
+ Plain String
+ | Secure String
+ | Insecure String
+ deriving ( Show , Eq , Ord )
+
+data Ldap = Ldap
+ { client :: TQueue ClientMessage
+ } deriving ( Eq )
+
+data ClientMessage = New Request ( TMVar ( NonEmpty Type . ProtocolServerOp ) )
+type Request = Type . ProtocolClientOp
+type InMessage = Type . ProtocolServerOp
+type Response = NonEmpty InMessage
+
+data Async a = Async ( STM ( Either ResponseError a ) )
+
+instance Functor Async where
+ fmap f ( Async stm ) = Async ( fmap ( fmap f ) stm )
+
+
+newtype Dn = Dn Text
+ deriving ( Show , Eq )
+
+newtype RelativeDn = RelativeDn Text
+ deriving ( Show , Eq )
+
+newtype Oid = Oid ByteString
+ deriving ( Show , Eq )
+
+newtype Password = Password ByteString
+ deriving ( Show , Eq )
+
+
+data ResponseError =
+ ResponseInvalid Request Response
+ | ResponseErrorCode Request Type . ResultCode Dn Text
+ deriving ( Show , Eq , Typeable )
+
+instance Exception ResponseError
+
+
+
+newtype Attr = Attr Text
+ deriving ( Show , Eq )
+
+type AttrList f = [ ( Attr , f ByteString ) ]
+
+
+
+unAttr :: Attr -> Text
+unAttr ( Attr a ) = a
+
+
+wait :: Async a -> IO ( Either ResponseError a )
+wait = atomically . waitSTM
+
+waitSTM :: Async a -> STM ( Either ResponseError a )
+waitSTM ( Async stm ) = stm
+
+
+sendRequest :: Ldap -> ( Response -> Either ResponseError a ) -> Request -> STM ( Async a )
+sendRequest l p msg =
+ do var <- newEmptyTMVar
+ writeRequest l var msg
+ return ( Async ( fmap p ( readTMVar var ) ) )
+
+writeRequest :: Ldap -> TMVar Response -> Request -> STM ()
+writeRequest Ldap { client } var msg = writeTQueue client ( New msg var )
+
+raise :: Exception e => Either e a -> IO a
+raise = either throwIO return
+
+
diff --git a/src/Ldap-Client-Modify.html b/src/Ldap-Client-Modify.html
new file mode 100644
index 0000000..9c4e286
--- /dev/null
+++ b/src/Ldap-Client-Modify.html
@@ -0,0 +1,102 @@
+
+
+
+
+
+src/Ldap/Client/Modify.hs
+
+
+
+module Ldap . Client . Modify
+ ( Operation ( .. )
+ , modify
+ , modifyEither
+ , modifyAsync
+ , modifyAsyncSTM
+ , modifyDn
+ , modifyDnEither
+ , modifyDnAsync
+ , modifyDnAsyncSTM
+ ) where
+
+import Control . Monad . STM ( STM , atomically )
+import Data . ByteString ( ByteString )
+import Data . List . NonEmpty ( NonEmpty ( ( :| ) ) )
+
+import qualified Ldap . Asn1 . Type as Type
+import Ldap . Client . Internal
+
+
+data Operation =
+ Delete Attr [ ByteString ]
+ | Add Attr [ ByteString ]
+ | Replace Attr [ ByteString ]
+ deriving ( Show , Eq )
+
+modify :: Ldap -> Dn -> [ Operation ] -> IO ()
+modify l dn as =
+ raise =<< modifyEither l dn as
+
+modifyEither :: Ldap -> Dn -> [ Operation ] -> IO ( Either ResponseError () )
+modifyEither l dn as =
+ wait =<< modifyAsync l dn as
+
+modifyAsync :: Ldap -> Dn -> [ Operation ] -> IO ( Async () )
+modifyAsync l dn as =
+ atomically ( modifyAsyncSTM l dn as )
+
+modifyAsyncSTM :: Ldap -> Dn -> [ Operation ] -> STM ( Async () )
+modifyAsyncSTM l dn xs =
+ let req = modifyRequest dn xs in sendRequest l ( modifyResult req ) req
+
+modifyRequest :: Dn -> [ Operation ] -> Request
+modifyRequest ( Dn dn ) xs =
+ Type . ModifyRequest ( Type . LdapDn ( Type . LdapString dn ) ) ( map f xs )
+ where
+ f ( Delete ( Attr k ) vs ) =
+ ( Type . Delete , Type . PartialAttribute ( Type . AttributeDescription ( Type . LdapString k ) )
+ ( map Type . AttributeValue vs ) )
+ f ( Add ( Attr k ) vs ) =
+ ( Type . Add , Type . PartialAttribute ( Type . AttributeDescription ( Type . LdapString k ) )
+ ( map Type . AttributeValue vs ) )
+ f ( Replace ( Attr k ) vs ) =
+ ( Type . Replace , Type . PartialAttribute ( Type . AttributeDescription ( Type . LdapString k ) )
+ ( map Type . AttributeValue vs ) )
+
+modifyResult :: Request -> Response -> Either ResponseError ()
+modifyResult req ( Type . ModifyResponse ( Type . LdapResult code ( Type . LdapDn ( Type . LdapString dn ) ) ( Type . LdapString msg ) _ ) :| [] )
+ | Type . Success <- code = Right ()
+ | otherwise = Left ( ResponseErrorCode req code ( Dn dn ) msg )
+modifyResult req res = Left ( ResponseInvalid req res )
+
+
+modifyDn :: Ldap -> Dn -> RelativeDn -> Bool -> Maybe Dn -> IO ()
+modifyDn l dn rdn del new =
+ raise =<< modifyDnEither l dn rdn del new
+
+modifyDnEither :: Ldap -> Dn -> RelativeDn -> Bool -> Maybe Dn -> IO ( Either ResponseError () )
+modifyDnEither l dn rdn del new =
+ wait =<< modifyDnAsync l dn rdn del new
+
+modifyDnAsync :: Ldap -> Dn -> RelativeDn -> Bool -> Maybe Dn -> IO ( Async () )
+modifyDnAsync l dn rdn del new =
+ atomically ( modifyDnAsyncSTM l dn rdn del new )
+
+modifyDnAsyncSTM :: Ldap -> Dn -> RelativeDn -> Bool -> Maybe Dn -> STM ( Async () )
+modifyDnAsyncSTM l dn rdn del new =
+ let req = modifyDnRequest dn rdn del new in sendRequest l ( modifyDnResult req ) req
+
+modifyDnRequest :: Dn -> RelativeDn -> Bool -> Maybe Dn -> Request
+modifyDnRequest ( Dn dn ) ( RelativeDn rdn ) del new =
+ Type . ModifyDnRequest ( Type . LdapDn ( Type . LdapString dn ) )
+ ( Type . RelativeLdapDn ( Type . LdapString rdn ) )
+ del
+ ( fmap ( \ ( Dn dn' ) -> Type . LdapDn ( Type . LdapString dn' ) ) new )
+
+modifyDnResult :: Request -> Response -> Either ResponseError ()
+modifyDnResult req ( Type . ModifyDnResponse ( Type . LdapResult code ( Type . LdapDn ( Type . LdapString dn ) ) ( Type . LdapString msg ) _ ) :| [] )
+ | Type . Success <- code = Right ()
+ | otherwise = Left ( ResponseErrorCode req code ( Dn dn ) msg )
+modifyDnResult req res = Left ( ResponseInvalid req res )
+
+
diff --git a/src/Ldap-Client-Search.html b/src/Ldap-Client-Search.html
new file mode 100644
index 0000000..adced5e
--- /dev/null
+++ b/src/Ldap-Client-Search.html
@@ -0,0 +1,189 @@
+
+
+
+
+
+src/Ldap/Client/Search.hs
+
+
+
+
+
+module Ldap . Client . Search
+ ( search
+ , searchEither
+ , searchAsync
+ , searchAsyncSTM
+ , Search
+ , Mod
+ , Type . Scope ( .. )
+ , scope
+ , size
+ , time
+ , typesOnly
+ , derefAliases
+ , Filter ( .. )
+ , SearchEntry ( .. )
+ ) where
+
+import Control . Monad . STM ( STM , atomically )
+import Data . ByteString ( ByteString )
+import Data . Int ( Int32 )
+import Data . List . NonEmpty ( NonEmpty ( ( :| ) ) )
+import qualified Data . List . NonEmpty as NonEmpty
+import Data . Maybe ( mapMaybe )
+#if __GLASGOW_HASKELL__ >= 710
+import Data . Semigroup ( Semigroup ( .. ) )
+#else
+import Data . Semigroup ( Semigroup ( .. ) , Monoid ( .. ) )
+#endif
+
+import qualified Ldap . Asn1 . Type as Type
+import Ldap . Client . Internal
+
+
+search :: Ldap -> Dn -> Mod Search -> Filter -> [ Attr ] -> IO [ SearchEntry ]
+search l base opts flt attributes =
+ raise =<< searchEither l base opts flt attributes
+
+searchEither
+ :: Ldap
+ -> Dn
+ -> Mod Search
+ -> Filter
+ -> [ Attr ]
+ -> IO ( Either ResponseError [ SearchEntry ] )
+searchEither l base opts flt attributes =
+ wait =<< searchAsync l base opts flt attributes
+
+searchAsync :: Ldap -> Dn -> Mod Search -> Filter -> [ Attr ] -> IO ( Async [ SearchEntry ] )
+searchAsync l base opts flt attributes =
+ atomically ( searchAsyncSTM l base opts flt attributes )
+
+searchAsyncSTM :: Ldap -> Dn -> Mod Search -> Filter -> [ Attr ] -> STM ( Async [ SearchEntry ] )
+searchAsyncSTM l base opts flt attributes =
+ let req = searchRequest base opts flt attributes in sendRequest l ( searchResult req ) req
+
+searchRequest :: Dn -> Mod Search -> Filter -> [ Attr ] -> Request
+searchRequest ( Dn base ) ( Mod m ) flt attributes =
+ Type . SearchRequest ( Type . LdapDn ( Type . LdapString base ) )
+ _scope
+ _derefAliases
+ _size
+ _time
+ _typesOnly
+ ( fromFilter flt )
+ ( Type . AttributeSelection ( map ( Type . LdapString . unAttr ) attributes ) )
+ where
+ Search { _scope , _derefAliases , _size , _time , _typesOnly } =
+ m defaultSearch
+ fromFilter ( Not x ) = Type . Not ( fromFilter x )
+ fromFilter ( And xs ) = Type . And ( fmap fromFilter xs )
+ fromFilter ( Or xs ) = Type . Or ( fmap fromFilter xs )
+ fromFilter ( Present ( Attr x ) ) =
+ Type . Present ( Type . AttributeDescription ( Type . LdapString x ) )
+ fromFilter ( Attr x := y ) =
+ Type . EqualityMatch
+ ( Type . AttributeValueAssertion ( Type . AttributeDescription ( Type . LdapString x ) )
+ ( Type . AssertionValue y ) )
+ fromFilter ( Attr x :>= y ) =
+ Type . GreaterOrEqual
+ ( Type . AttributeValueAssertion ( Type . AttributeDescription ( Type . LdapString x ) )
+ ( Type . AssertionValue y ) )
+ fromFilter ( Attr x :<= y ) =
+ Type . LessOrEqual
+ ( Type . AttributeValueAssertion ( Type . AttributeDescription ( Type . LdapString x ) )
+ ( Type . AssertionValue y ) )
+ fromFilter ( Attr x :~= y ) =
+ Type . ApproxMatch
+ ( Type . AttributeValueAssertion ( Type . AttributeDescription ( Type . LdapString x ) )
+ ( Type . AssertionValue y ) )
+ fromFilter ( Attr x :=* ( mi , xs , mf ) ) =
+ Type . Substrings
+ ( Type . SubstringFilter ( Type . AttributeDescription ( Type . LdapString x ) )
+ ( NonEmpty . fromList ( concat
+ [ maybe [] ( \ i -> [ Type . Initial ( Type . AssertionValue i ) ] ) mi
+ , fmap ( Type . Any . Type . AssertionValue ) xs
+ , maybe [] ( \ f -> [ Type . Final ( Type . AssertionValue f ) ] ) mf
+ ] ) ) )
+ fromFilter ( ( mx , mr , b ) ::= y ) =
+ Type . ExtensibleMatch
+ ( Type . MatchingRuleAssertion ( fmap ( \ ( Attr r ) -> Type . MatchingRuleId ( Type . LdapString r ) ) mr )
+ ( fmap ( \ ( Attr x ) -> Type . AttributeDescription ( Type . LdapString x ) ) mx )
+ ( Type . AssertionValue y )
+ b )
+
+searchResult :: Request -> Response -> Either ResponseError [ SearchEntry ]
+searchResult req ( Type . SearchResultDone ( Type . LdapResult code ( Type . LdapDn ( Type . LdapString dn' ) )
+ ( Type . LdapString msg ) _ ) :| xs )
+ | Type . Success <- code = Right ( mapMaybe g xs )
+ | Type . AdminLimitExceeded <- code = Right ( mapMaybe g xs )
+ | Type . SizeLimitExceeded <- code = Right ( mapMaybe g xs )
+ | otherwise = Left ( ResponseErrorCode req code ( Dn dn' ) msg )
+ where
+ g ( Type . SearchResultEntry ( Type . LdapDn ( Type . LdapString dn ) )
+ ( Type . PartialAttributeList ys ) ) =
+ Just ( SearchEntry ( Dn dn ) ( map h ys ) )
+ g _ = Nothing
+ h ( Type . PartialAttribute ( Type . AttributeDescription ( Type . LdapString x ) )
+ y ) = ( Attr x , fmap j y )
+ j ( Type . AttributeValue x ) = x
+searchResult req res = Left ( ResponseInvalid req res )
+
+data Search = Search
+ { _scope :: Type . Scope
+ , _derefAliases :: Type . DerefAliases
+ , _size :: Int32
+ , _time :: Int32
+ , _typesOnly :: Bool
+ } deriving ( Show , Eq )
+
+defaultSearch :: Search
+defaultSearch = Search
+ { _scope = Type . BaseObject
+ , _size = 0
+ , _time = 0
+ , _typesOnly = False
+ , _derefAliases = Type . NeverDerefAliases
+ }
+
+scope :: Type . Scope -> Mod Search
+scope x = Mod ( \ y -> y { _scope = x } )
+
+size :: Int32 -> Mod Search
+size x = Mod ( \ y -> y { _size = x } )
+
+time :: Int32 -> Mod Search
+time x = Mod ( \ y -> y { _time = x } )
+
+typesOnly :: Bool -> Mod Search
+typesOnly x = Mod ( \ y -> y { _typesOnly = x } )
+
+derefAliases :: Type . DerefAliases -> Mod Search
+derefAliases x = Mod ( \ y -> y { _derefAliases = x } )
+
+newtype Mod a = Mod ( a -> a )
+
+instance Semigroup ( Mod a ) where
+ Mod f <> Mod g = Mod ( g . f )
+
+instance Monoid ( Mod a ) where
+ mempty = Mod id
+ mappend = ( <> )
+
+data Filter =
+ Not Filter
+ | And ( NonEmpty Filter )
+ | Or ( NonEmpty Filter )
+ | Present Attr
+ | Attr := ByteString
+ | Attr :>= ByteString
+ | Attr :<= ByteString
+ | Attr :~= ByteString
+ | Attr :=* ( Maybe ByteString , [ ByteString ] , Maybe ByteString )
+ | ( Maybe Attr , Maybe Attr , Bool ) ::= ByteString
+
+data SearchEntry = SearchEntry Dn ( AttrList [] )
+ deriving ( Show , Eq )
+
+
diff --git a/src/Ldap-Client.html b/src/Ldap-Client.html
new file mode 100644
index 0000000..af6edfb
--- /dev/null
+++ b/src/Ldap-Client.html
@@ -0,0 +1,216 @@
+
+
+
+
+
+src/Ldap/Client.hs
+
+
+
+
+
+
+module Ldap . Client
+ ( Host ( .. )
+ , Ldap
+ , LdapError ( .. )
+ , ResponseError ( .. )
+ , Type . ResultCode ( .. )
+ , Async
+ , with
+
+ , bind
+
+ , search
+ , SearchEntry ( .. )
+
+ , Search
+ , Mod
+ , scope
+ , Type . Scope ( .. )
+ , size
+ , time
+ , typesOnly
+ , derefAliases
+ , Filter ( .. )
+
+ , modify
+ , Operation ( .. )
+
+ , add
+
+ , delete
+
+ , modifyDn
+
+ , compare
+
+ , extended
+
+ , wait
+
+ , Dn ( .. )
+ , RelativeDn ( .. )
+ , Oid ( .. )
+ , Password ( .. )
+ , AttrList
+ , Attr ( .. )
+
+ , NonEmpty
+ , PortNumber
+ ) where
+
+#if __GLASGOW_HASKELL__ < 710
+import Control . Applicative ( ( <$> ) )
+#endif
+import qualified Control . Concurrent . Async as Async
+import Control . Concurrent . STM ( atomically )
+import Control . Concurrent . STM . TMVar ( putTMVar )
+import Control . Concurrent . STM . TQueue ( TQueue , newTQueueIO , writeTQueue , readTQueue )
+import Control . Exception ( Handler ( .. ) , bracket , throwIO , catches )
+import Control . Monad ( forever )
+import qualified Data . ASN1 . BinaryEncoding as Asn1
+import qualified Data . ASN1 . Encoding as Asn1
+import qualified Data . ASN1 . Error as Asn1
+import qualified Data . ByteString as ByteString
+import qualified Data . ByteString . Lazy as ByteString . Lazy
+import Data . Foldable ( traverse_ , asum )
+import Data . Function ( fix )
+import Data . List . NonEmpty ( NonEmpty ( ( :| ) ) )
+import qualified Data . Map . Strict as Map
+import Data . Monoid ( Endo ( appEndo ) )
+import Network . Connection ( Connection )
+import qualified Network . Connection as Conn
+import qualified System . IO . Error as IO
+import Prelude hiding ( compare )
+
+import Ldap . Asn1 . ToAsn1 ( ToAsn1 ( toAsn1 ) )
+import Ldap . Asn1 . FromAsn1 ( FromAsn1 , parseAsn1 )
+import qualified Ldap . Asn1 . Type as Type
+import Ldap . Client . Internal
+import Ldap . Client . Bind ( bind , unbindAsync )
+import Ldap . Client . Search
+ ( search
+ , Search
+ , Mod
+ , scope
+ , size
+ , time
+ , typesOnly
+ , derefAliases
+ , Filter ( .. )
+ , SearchEntry ( .. )
+ )
+import Ldap . Client . Modify ( Operation ( .. ) , modify , modifyDn )
+import Ldap . Client . Add ( add )
+import Ldap . Client . Delete ( delete )
+import Ldap . Client . Compare ( compare )
+import Ldap . Client . Extended ( extended )
+
+
+newLdap :: IO Ldap
+newLdap = Ldap
+ <$> newTQueueIO
+
+data LdapError =
+ IOError IOError
+ | ParseError Asn1 . ASN1Error
+ | ResponseError ResponseError
+ deriving ( Show , Eq )
+
+
+with :: Host -> PortNumber -> ( Ldap -> IO a ) -> IO ( Either LdapError a )
+with host port f = do
+ context <- Conn . initConnectionContext
+ bracket ( Conn . connectTo context params ) Conn . connectionClose ( \ conn ->
+ bracket newLdap unbindAsync ( \ l -> do
+ inq <- newTQueueIO
+ outq <- newTQueueIO
+ Async . withAsync ( input inq conn ) $ \ i ->
+ Async . withAsync ( output outq conn ) $ \ o ->
+ Async . withAsync ( dispatch l inq outq ) $ \ d ->
+ Async . withAsync ( f l ) $ \ u ->
+ fmap ( Right . snd ) ( Async . waitAnyCancel [ i , o , d , u ] ) ) )
+ `catches`
+ [ Handler ( return . Left . IOError )
+ , Handler ( return . Left . ParseError )
+ , Handler ( return . Left . ResponseError )
+ ]
+ where
+ params = Conn . ConnectionParams
+ { Conn . connectionHostname =
+ case host of
+ Plain h -> h
+ Secure h -> h
+ Insecure h -> h
+ , Conn . connectionPort = port
+ , Conn . connectionUseSecure =
+ case host of
+ Plain _ -> Nothing
+ Secure _ -> Just Conn . TLSSettingsSimple
+ { Conn . settingDisableCertificateValidation = False
+ , Conn . settingDisableSession = False
+ , Conn . settingUseServerName = False
+ }
+ Insecure _ -> Just Conn . TLSSettingsSimple
+ { Conn . settingDisableCertificateValidation = True
+ , Conn . settingDisableSession = False
+ , Conn . settingUseServerName = False
+ }
+ , Conn . connectionUseSocks = Nothing
+ }
+
+input :: FromAsn1 a => TQueue a -> Connection -> IO b
+input inq conn = flip fix [] $ \ loop chunks -> do
+ chunk <- Conn . connectionGet conn 8192
+ case ByteString . length chunk of
+ 0 -> throwIO ( IO . mkIOError IO . eofErrorType "Ldap.Client.input" Nothing Nothing )
+ _ -> do
+ let chunks' = chunk : chunks
+ case Asn1 . decodeASN1 Asn1 . DER ( ByteString . Lazy . fromChunks ( reverse chunks' ) ) of
+ Left Asn1 . ParsingPartial
+ -> loop chunks'
+ Left e -> throwIO e
+ Right asn1 -> do
+ flip fix asn1 $ \ loop' asn1' ->
+ case parseAsn1 asn1' of
+ Nothing -> return ()
+ Just ( asn1'' , a ) -> do
+ atomically ( writeTQueue inq a )
+ loop' asn1''
+ loop []
+
+output :: ToAsn1 a => TQueue a -> Connection -> IO b
+output out conn = forever $ do
+ msg <- atomically ( readTQueue out )
+ Conn . connectionPut conn ( encode ( toAsn1 msg ) )
+ where
+ encode x = Asn1 . encodeASN1' Asn1 . DER ( appEndo x [] )
+
+dispatch
+ :: Ldap
+ -> TQueue ( Type . LdapMessage Type . ProtocolServerOp )
+ -> TQueue ( Type . LdapMessage Request )
+ -> IO a
+dispatch Ldap { client } inq outq =
+ flip fix ( Map . empty , Map . empty , 1 ) $ \ loop ( ! got , ! results , ! counter ) ->
+ loop =<< atomically ( asum
+ [ do New new var <- readTQueue client
+ writeTQueue outq ( Type . LdapMessage ( Type . Id counter ) new Nothing )
+ return ( got , Map . insert ( Type . Id counter ) var results , counter + 1 )
+ , do Type . LdapMessage mid op _ <- readTQueue inq
+ case op of
+ Type . SearchResultEntry { } ->
+ return ( Map . insertWith ( ++ ) mid [ op ] got , results , counter )
+ Type . SearchResultReference { } ->
+ return ( got , results , counter )
+ Type . SearchResultDone { } -> do
+ let stack = Map . findWithDefault [] mid got
+ traverse_ ( \ var -> putTMVar var ( op :| stack ) ) ( Map . lookup mid results )
+ return ( Map . delete mid got , Map . delete mid results , counter )
+ _ -> do
+ traverse_ ( \ var -> putTMVar var ( op :| [] ) ) ( Map . lookup mid results )
+ return ( Map . delete mid got , Map . delete mid results , counter )
+ ] )
+
+
diff --git a/src/hscolour.css b/src/hscolour.css
new file mode 100644
index 0000000..c15919e
--- /dev/null
+++ b/src/hscolour.css
@@ -0,0 +1,5 @@
+.hs-keyglyph, .hs-layout {color: red;}
+.hs-keyword {color: blue;}
+.hs-comment, .hs-comment a {color: green;}
+.hs-str, .hs-chr {color: teal;}
+.hs-keyword, .hs-conid, .hs-varid, .hs-conop, .hs-varop, .hs-num, .hs-cpp, .hs-sel, .hs-definition {}
diff --git a/synopsis.png b/synopsis.png
new file mode 100644
index 0000000..85fb86e
Binary files /dev/null and b/synopsis.png differ