1
2package Net::LDAP::ASN;
3
4our $VERSION = '0.13';
5
6use Convert::ASN1;
7
8my $asn = Convert::ASN1->new;
9
10sub import {
11  my $pkg    = shift;
12  my $caller = caller;
13
14  foreach my $macro (@_) {
15    my $obj = $asn->find($macro)
16      or require Carp and Carp::croak("Unknown macro '$macro'");
17
18    *{"$caller\::$macro"} = \$obj;
19  }
20}
21
22$asn->prepare(<<LDAP_ASN) or die $asn->error;
23
24    -- We have split LDAPMessage into LDAPResponse and LDAPRequest
25    -- The purpose of this is two fold
26    -- 1) for encode we don't want the protocolOp
27    --    in the hierarchy as it is not really needed
28    -- 2) For decode we do want it, this allows Net::LDAP::Message::decode
29    --    to be much simpler. Decode will also be faster due to
30    --    less elements in the CHOICE
31
32    LDAPRequest ::= SEQUENCE {
33	messageID       MessageID,
34	-- protocolOp
35	CHOICE {
36	    bindRequest     BindRequest,
37	    unbindRequest   UnbindRequest,
38	    searchRequest   SearchRequest,
39	    modifyRequest   ModifyRequest,
40	    addRequest      AddRequest,
41	    delRequest      DelRequest,
42	    modDNRequest    ModifyDNRequest,
43	    compareRequest  CompareRequest,
44	    abandonRequest  AbandonRequest,
45	    extendedReq     ExtendedRequest }
46	controls        [0] Controls OPTIONAL }
47
48    LDAPResponse ::= SEQUENCE {
49	messageID       MessageID,
50	protocolOp      CHOICE {
51	    bindResponse    BindResponse,
52	    searchResEntry  SearchResultEntry,
53	    searchResDone   SearchResultDone,
54	    searchResRef    SearchResultReference,
55	    modifyResponse  ModifyResponse,
56	    addResponse     AddResponse,
57	    delResponse     DelResponse,
58	    modDNResponse   ModifyDNResponse,
59	    compareResponse CompareResponse,
60	    extendedResp    ExtendedResponse,
61	    intermediateResponse IntermediateResponse }
62	controls        [0] Controls OPTIONAL }
63
64    MessageID ::= INTEGER -- (0 .. maxInt)
65
66    -- maxInt INTEGER ::= 2147483647 -- (2^^31 - 1) --
67
68    LDAPString ::= OCTET STRING -- UTF-8 encoded, [ISO10646] characters
69
70    LDAPOID ::= OCTET STRING -- Constrained to <numericoid> [RFC4512]
71
72    LDAPDN ::= LDAPString -- Constrained to <distinguishedName> [RFC4514]
73
74    RelativeLDAPDN ::= LDAPString -- Constrained to <name-component> [RFC4514]
75
76    AttributeDescription ::= LDAPString -- Constrained to <attributedescription> [RFC4512]
77
78    AttributeValue ::= OCTET STRING
79
80    AttributeValueAssertion ::= SEQUENCE {
81	attributeDesc   AttributeDescription,
82	assertionValue  AssertionValue }
83
84    AssertionValue ::= OCTET STRING
85
86    PartialAttribute ::= SEQUENCE {
87	type    AttributeDescription,
88	vals    SET OF AttributeValue }
89
90    Attribute ::= PartialAttribute -- (WITH COMPONENTS { ..., vals (SIZE(1..MAX))})
91
92    MatchingRuleId ::= LDAPString
93
94    LDAPResult ::= SEQUENCE {
95	resultCode      ENUMERATED {
96	    success                      (0),
97	    operationsError              (1),
98	    protocolError                (2),
99	    timeLimitExceeded            (3),
100	    sizeLimitExceeded            (4),
101	    compareFalse                 (5),
102	    compareTrue                  (6),
103	    authMethodNotSupported       (7),
104	    strongAuthRequired           (8),
105		-- 9 reserved --
106	    referral                     (10),
107	    adminLimitExceeded           (11),
108	    unavailableCriticalExtension (12),
109	    confidentialityRequired      (13),
110	    saslBindInProgress           (14),
111	    noSuchAttribute              (16),
112	    undefinedAttributeType       (17),
113	    inappropriateMatching        (18),
114	    constraintViolation          (19),
115	    attributeOrValueExists       (20),
116	    invalidAttributeSyntax       (21),
117		-- 22-31 unused --
118	    noSuchObject                 (32),
119	    aliasProblem                 (33),
120	    invalidDNSyntax              (34),
121		-- 35 reserved for undefined isLeaf --
122	    aliasDereferencingProblem    (36),
123		-- 37-47 unused --
124	    inappropriateAuthentication  (48),
125	    invalidCredentials           (49),
126	    insufficientAccessRights     (50),
127	    busy                         (51),
128	    unavailable                  (52),
129	    unwillingToPerform           (53),
130	    loopDetect                   (54),
131		-- 55-63 unused --
132	    namingViolation              (64),
133	    objectClassViolation         (65),
134	    notAllowedOnNonLeaf          (66),
135	    notAllowedOnRDN              (67),
136	    entryAlreadyExists           (68),
137	    objectClassModsProhibited    (69),
138		-- 70 reserved for CLDAP --
139	    affectsMultipleDSAs          (71),
140		-- 72-79 unused --
141	    other                        (80)}
142		-- 81-90 reserved for APIs --
143	matchedDN       LDAPDN,
144	errorMessage    LDAPString,
145	referral        [3] Referral OPTIONAL }
146
147    Referral ::= SEQUENCE OF URI
148
149    URI ::= LDAPString -- limited to characters permitted in URIs
150
151    Controls ::= SEQUENCE OF Control
152
153    -- Names changed here for backwards compat with previous
154    -- Net::LDAP    --GMB
155    Control ::= SEQUENCE {
156	type            LDAPOID,                       -- controlType
157	critical        BOOLEAN OPTIONAL, -- DEFAULT FALSE,    -- criticality
158	value           OCTET STRING OPTIONAL }        -- controlValue
159
160    BindRequest ::= [APPLICATION 0] SEQUENCE {
161	version         INTEGER, -- (1 .. 127),
162	name            LDAPDN,
163	authentication  AuthenticationChoice }
164
165    AuthenticationChoice ::= CHOICE {
166	simple          [0] OCTET STRING,
167			-- 1 and 2 reserved
168	sasl            [3] SaslCredentials }
169
170    SaslCredentials ::= SEQUENCE {
171	mechanism       LDAPString,
172	credentials     OCTET STRING OPTIONAL }
173
174    BindResponse ::= [APPLICATION 1] SEQUENCE {
175	COMPONENTS OF LDAPResult,
176	serverSaslCreds    [7] OCTET STRING OPTIONAL }
177
178    UnbindRequest ::= [APPLICATION 2] NULL
179
180    SearchRequest ::= [APPLICATION 3] SEQUENCE {
181	baseObject      LDAPDN,
182	scope           ENUMERATED {
183	    baseObject              (0),
184	    singleLevel             (1),
185	    wholeSubtree            (2),
186	    subOrdinates            (3) } -- OpenLDAP extension
187	derefAliases    ENUMERATED {
188	    neverDerefAliases       (0),
189	    derefInSearching        (1),
190	    derefFindingBaseObj     (2),
191	    derefAlways             (3) }
192	sizeLimit       INTEGER, -- (0 .. maxInt),
193	timeLimit       INTEGER, -- (0 .. maxInt),
194	typesOnly       BOOLEAN,
195	filter          Filter,
196	attributes      AttributeSelection }
197
198    AttributeSelection ::= SEQUENCE OF LDAPString
199		-- The LDAPString is constrained to <attributeSelector> [RFC 4511]
200
201    Filter ::= CHOICE {
202	and             [0] SET OF Filter,
203	or              [1] SET OF Filter,
204	not             [2] Filter,
205	equalityMatch   [3] AttributeValueAssertion,
206	substrings      [4] SubstringFilter,
207	greaterOrEqual  [5] AttributeValueAssertion,
208	lessOrEqual     [6] AttributeValueAssertion,
209	present         [7] AttributeDescription,
210	approxMatch     [8] AttributeValueAssertion,
211	extensibleMatch [9] MatchingRuleAssertion }
212
213    SubstringFilter ::= SEQUENCE {
214	type            AttributeDescription,
215	-- at least one must be present
216	substrings      SEQUENCE OF CHOICE {
217	    initial [0] AssertionValue,    -- can occur at most once
218	    any     [1] AssertionValue,
219	    final   [2] AssertionValue } } -- can occur at most once
220
221    MatchingRuleAssertion ::= SEQUENCE {
222	matchingRule    [1] MatchingRuleId OPTIONAL,
223	type            [2] AttributeDescription OPTIONAL,
224	matchValue      [3] AssertionValue,
225	dnAttributes    [4] BOOLEAN OPTIONAL } -- DEFAULT FALSE }
226
227    SearchResultEntry ::= [APPLICATION 4] SEQUENCE {
228	objectName      LDAPDN,
229	attributes      PartialAttributeList }
230
231    PartialAttributeList ::= SEQUENCE OF PartialAttribute
232
233    SearchResultReference ::= [APPLICATION 19] SEQUENCE OF URI
234
235    SearchResultDone ::= [APPLICATION 5] LDAPResult
236
237    ModifyRequest ::= [APPLICATION 6] SEQUENCE {
238	object          LDAPDN,
239	modification    SEQUENCE OF SEQUENCE {
240	    operation       ENUMERATED {
241			add     (0),
242			delete  (1),
243			replace (2),
244			increment (3) } -- increment from RFC 4525
245	    modification    PartialAttribute } }
246
247    ModifyResponse ::= [APPLICATION 7] LDAPResult
248
249    AddRequest ::= [APPLICATION 8] SEQUENCE {
250	objectName      LDAPDN,
251	attributes      AttributeList }
252
253    AttributeList ::= SEQUENCE OF Attribute
254
255    AddResponse ::= [APPLICATION 9] LDAPResult
256
257    DelRequest ::= [APPLICATION 10] LDAPDN
258
259    DelResponse ::= [APPLICATION 11] LDAPResult
260
261    ModifyDNRequest ::= [APPLICATION 12] SEQUENCE {
262	entry           LDAPDN,
263	newrdn          RelativeLDAPDN,
264	deleteoldrdn    BOOLEAN,
265	newSuperior     [0] LDAPDN OPTIONAL }
266
267    ModifyDNResponse ::= [APPLICATION 13] LDAPResult
268
269    CompareRequest ::= [APPLICATION 14] SEQUENCE {
270	entry           LDAPDN,
271	ava             AttributeValueAssertion }
272
273    CompareResponse ::= [APPLICATION 15] LDAPResult
274
275    AbandonRequest ::= [APPLICATION 16] MessageID
276
277    ExtendedRequest ::= [APPLICATION 23] SEQUENCE {
278	requestName     [0] LDAPOID,
279	requestValue    [1] OCTET STRING OPTIONAL }
280
281    ExtendedResponse ::= [APPLICATION 24] SEQUENCE {
282	COMPONENTS OF LDAPResult,
283	responseName    [10] LDAPOID OPTIONAL,
284	responseValue   [11] OCTET STRING OPTIONAL }
285
286    IntermediateResponse ::= [APPLICATION 25] SEQUENCE {
287	responseName    [0] LDAPOID OPTIONAL,
288	responseValue   [1] OCTET STRING OPTIONAL }
289
290
291    -- Virtual List View Control
292    VirtualListViewRequest ::= SEQUENCE {
293	beforeCount     INTEGER, --(0 .. maxInt),
294	afterCount      INTEGER, --(0 .. maxInt),
295	CHOICE {
296	    byoffset [0] SEQUENCE {
297	    offset          INTEGER,  --(0 .. maxInt),
298	    contentCount    INTEGER } --(0 .. maxInt) }
299	    byValue [1] AssertionValue }
300	    -- byValue [1] greaterThanOrEqual assertionValue }
301	contextID     OCTET STRING OPTIONAL }
302
303    VirtualListViewResponse ::= SEQUENCE {
304	targetPosition    INTEGER, --(0 .. maxInt),
305	contentCount      INTEGER, --(0 .. maxInt),
306	virtualListViewResult ENUMERATED {
307	    success                   (0),
308	    operatonsError            (1),
309	    unwillingToPerform       (53),
310	    insufficientAccessRights (50),
311	    busy                     (51),
312	    timeLimitExceeded         (3),
313	    adminLimitExceeded       (11),
314	    sortControlMissing       (60),
315	    indexRangeError          (61),
316	    other                    (80) }
317	contextID     OCTET STRING OPTIONAL     }
318
319
320    LDAPEntry ::= COMPONENTS OF AddRequest
321
322    -- RFC-2891 Server Side Sorting Control
323    -- Current parser does not allow a named entity following the ::=
324    -- so we use a COMPONENTS OF hack
325    SortRequestDummy ::= SEQUENCE {
326	order SEQUENCE OF SEQUENCE {
327	    type         OCTET STRING,
328	    orderingRule [0] OCTET STRING OPTIONAL,
329	    reverseOrder [1] BOOLEAN OPTIONAL } }
330
331    SortRequest ::= COMPONENTS OF SortRequestDummy
332
333    SortResult ::= SEQUENCE {
334	sortResult  ENUMERATED {
335	    success                   (0), -- results are sorted
336	    operationsError           (1), -- server internal failure
337	    timeLimitExceeded         (3), -- timelimit reached before
338					   -- sorting was completed
339	    strongAuthRequired        (8), -- refused to return sorted
340					   -- results via insecure
341					   -- protocol
342	    adminLimitExceeded       (11), -- too many matching entries
343					   -- for the server to sort
344	    noSuchAttribute          (16), -- unrecognized attribute
345					   -- type in sort key
346	    inappropriateMatching    (18), -- unrecognized or inappro-
347					   -- priate matching rule in
348					   -- sort key
349	    insufficientAccessRights (50), -- refused to return sorted
350					   -- results to this client
351	    busy                     (51), -- too busy to process
352	    unwillingToPerform       (53), -- unable to sort
353	    other                    (80) }
354    attributeType [0] AttributeDescription OPTIONAL }
355
356    -- RFC-2696 Paged Results Control
357    realSearchControlValue ::= SEQUENCE {
358	size            INTEGER, --  (0..maxInt),
359			-- requested page size from client
360			-- result set size estimate from server
361	cookie          OCTET STRING }
362
363    -- draft-behera-ldap-password-policy-09
364    ppControlResponse ::= SEQUENCE {
365	warning [0] PPWarning OPTIONAL,
366	error   [1] PPError OPTIONAL
367    }
368	PPWarning ::= CHOICE {
369	    timeBeforeExpiration [0] INTEGER, -- (0..maxInt),
370	    graceAuthNsRemaining [1] INTEGER -- (0..maxInt)
371	}
372	PPError ::= ENUMERATED {
373	    passwordExpired             (0),
374	    accountLocked               (1),
375	    changeAfterReset            (2),
376	    passwordModNotAllowed       (3),
377	    mustSupplyOldPassword       (4),
378	    insufficientPasswordQuality (5),
379	    passwordTooShort            (6),
380	    passwordTooYoung            (7),
381	    passwordInHistory           (8)
382	}
383
384    -- RFC-4370 Proxied Authorization Control
385    proxyAuthValue ::= SEQUENCE {
386	proxyDN LDAPDN
387    }
388
389    -- RFC-3296 ManageDsaIT Control
390    ManageDsaIT ::= SEQUENCE {
391	dummy INTEGER OPTIONAL   -- it really is unused
392    }
393
394    -- Persistent Search Control
395    PersistentSearch ::= SEQUENCE {
396	changeTypes INTEGER,
397	changesOnly BOOLEAN,
398	returnECs   BOOLEAN
399    }
400
401    -- Entry Change Notification Control
402    EntryChangeNotification ::= SEQUENCE {
403	changeType ENUMERATED {
404	    add         (1),
405	    delete      (2),
406	    modify      (4),
407	    modDN       (8)
408	}
409	previousDN   LDAPDN OPTIONAL,     -- modifyDN ops. only
410	changeNumber INTEGER OPTIONAL     -- if supported
411    }
412
413    -- RFC-3876 Matched Values Control
414    ValuesReturnFilter ::= SEQUENCE OF SimpleFilterItem
415
416    SimpleFilterItem ::= CHOICE {
417	equalityMatch   [3] AttributeValueAssertion,
418	substrings      [4] SubstringFilter,
419	greaterOrEqual  [5] AttributeValueAssertion,
420	lessOrEqual     [6] AttributeValueAssertion,
421	present         [7] AttributeDescription,
422	approxMatch     [8] AttributeValueAssertion,
423	extensibleMatch [9] SimpleMatchingAssertion }
424
425    SimpleMatchingAssertion ::= SEQUENCE {
426	matchingRule    [1] MatchingRuleId OPTIONAL,
427	type            [2] AttributeDescription OPTIONAL,
428	--- at least one of the above must be present
429	matchValue      [3] AssertionValue }
430
431    -- RFC-4533 LDAP Content Synchronization Operation
432
433    syncUUID ::= OCTET STRING -- (SIZE(16))
434
435    syncCookie ::= OCTET STRING
436
437    syncRequestValue ::= SEQUENCE {
438	mode ENUMERATED {
439	    -- 0 unused
440	    refreshOnly       (1),
441	    -- 2 reserved
442	    refreshAndPersist (3)
443	}
444	cookie     syncCookie OPTIONAL,
445	reloadHint BOOLEAN OPTIONAL -- DEFAULT FALSE
446    }
447
448    syncStateValue ::= SEQUENCE {
449	state ENUMERATED {
450	    present (0),
451	    add     (1),
452	    modify  (2),
453	    delete  (3)
454	}
455	entryUUID syncUUID,
456	cookie    syncCookie OPTIONAL
457    }
458
459    syncDoneValue ::= SEQUENCE {
460	cookie          syncCookie OPTIONAL,
461	refreshDeletes  BOOLEAN OPTIONAL -- DEFAULT FALSE
462    }
463
464    syncInfoValue ::= CHOICE {
465	newcookie      [0] syncCookie,
466	refreshDelete  [1] SEQUENCE {
467	    cookie         syncCookie OPTIONAL,
468	    refreshDone    BOOLEAN OPTIONAL -- DEFAULT TRUE
469	}
470	refreshPresent [2] SEQUENCE {
471	    cookie         syncCookie OPTIONAL,
472	    refreshDone    BOOLEAN OPTIONAL -- DEFAULT TRUE
473	}
474	syncIdSet      [3] SEQUENCE {
475	    cookie         syncCookie OPTIONAL,
476	    refreshDeletes BOOLEAN OPTIONAL, -- DEFAULT FALSE
477	    syncUUIDs      SET OF syncUUID
478	}
479    }
480
481    -- RFC-3672 Subentries Control
482    -- Current parser does not allow a named entity following the ::=
483    -- so we use a COMPONENTS OF hack
484    SubentriesValueDummy ::= SEQUENCE {
485	visibility BOOLEAN
486    }
487    SubentriesValue ::= COMPONENTS OF SubentriesValueDummy
488
489LDAP_ASN
490
4911;
492
493