codekingpro/portable-devtools
114k
1"""
2"""
3
4# Created on 2013.05.15
5#
6# Author: Giovanni Cannata
7#
8# Copyright 2014 - 2020 Giovanni Cannata
9#
10# This file is part of ldap3.
11#
12# ldap3 is free software: you can redistribute it and/or modify
13# it under the terms of the GNU Lesser General Public License as published
14# by the Free Software Foundation, either version 3 of the License, or
15# (at your option) any later version.
16#
17# ldap3 is distributed in the hope that it will be useful,
18# but WITHOUT ANY WARRANTY; without even the implied warranty of
19# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20# GNU Lesser General Public License for more details.
21#
22# You should have received a copy of the GNU Lesser General Public License
23# along with ldap3 in the COPYING and COPYING.LESSER files.
24# If not, see <http://www.gnu.org/licenses/>.
25
26#######################
27# ldap ASN.1 Definition
28# from RFC4511 - Appendix B
29# extended with result codes from IANA ldap-parameters as of 2013.08.21
30# extended with modify_increment from RFC4525
31
32#########################################################
33# Lightweight-Directory-Access-Protocol-V3 {1 3 6 1 1 18}
34# -- Copyright (C) The Internet Society (2006). This version of
35# -- this ASN.1 module is part of RFC 4511; see the RFC itself
36# -- for full legal notices.
37# DEFINITIONS
38# IMPLICIT TAGS
39# EXTENSIBILITY IMPLIED
40
41from pyasn1.type.univ import OctetString, Integer, Sequence, Choice, SequenceOf, Boolean, Null, Enumerated, SetOf
42from pyasn1.type.namedtype import NamedTypes, NamedType, OptionalNamedType, DefaultedNamedType
43from pyasn1.type.constraint import ValueRangeConstraint, SingleValueConstraint, ValueSizeConstraint
44from pyasn1.type.namedval import NamedValues
45from pyasn1.type.tag import tagClassApplication, tagFormatConstructed, Tag, tagClassContext, tagFormatSimple
46
47
48# constants
49# maxInt INTEGER ::= 2147483647 -- (2^^31 - 1) --
50LDAP_MAX_INT = 2147483647
51MAXINT = Integer(LDAP_MAX_INT)
52
53# constraints
54rangeInt0ToMaxConstraint = ValueRangeConstraint(0, MAXINT)
55rangeInt1To127Constraint = ValueRangeConstraint(1, 127)
56size1ToMaxConstraint = ValueSizeConstraint(1, MAXINT)
57responseValueConstraint = SingleValueConstraint(0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 11, 12, 13, 14, 16, 17, 18, 19, 20, 21, 32, 33, 34, 36, 48, 49, 50, 51, 52, 53, 54, 64, 65, 66, 67, 68, 69, 71, 80, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123,
58 4096)
59
60# custom constraints
61numericOIDConstraint = None # TODO
62distinguishedNameConstraint = None # TODO
63nameComponentConstraint = None # TODO
64attributeDescriptionConstraint = None # TODO
65uriConstraint = None # TODO
66attributeSelectorConstraint = None # TODO
67
68
69class Integer0ToMax(Integer):
70 subtypeSpec = Integer.subtypeSpec + rangeInt0ToMaxConstraint
71
72
73class LDAPString(OctetString):
74 # LDAPString ::= OCTET STRING -- UTF-8 encoded, -- [ISO10646] characters
75 encoding = 'utf-8'
76
77
78class MessageID(Integer0ToMax):
79 # MessageID ::= INTEGER (0 .. maxInt)
80 pass
81
82
83class LDAPOID(OctetString):
84 # LDAPOID ::= OCTET STRING -- Constrained to <numericoid>
85 # -- [RFC4512]
86
87 # subtypeSpec = numericOIDConstraint
88 pass
89
90
91class LDAPDN(LDAPString):
92 # LDAPDN ::= LDAPString -- Constrained to <distinguishedName>
93 # -- [RFC4514]
94
95 # subtypeSpec = distinguishedName
96 pass
97
98
99class RelativeLDAPDN(LDAPString):
100 # RelativeLDAPDN ::= LDAPString -- Constrained to <name-component>
101 # -- [RFC4514]
102
103 # subtypeSpec = LDAPString.subtypeSpec + nameComponentConstraint
104 pass
105
106
107class AttributeDescription(LDAPString):
108 # AttributeDescription ::= LDAPString -- Constrained to <attributedescription>
109 # -- [RFC4512]
110
111 # subtypeSpec = LDAPString.subtypeSpec + attributeDescriptionConstraint
112 pass
113
114
115class AttributeValue(OctetString):
116 # AttributeValue ::= OCTET STRING
117 encoding = 'utf-8'
118
119
120class AssertionValue(OctetString):
121 # AssertionValue ::= OCTET STRING
122 encoding = 'utf-8'
123
124
125class AttributeValueAssertion(Sequence):
126 # AttributeValueAssertion ::= SEQUENCE {
127 # attributeDesc AttributeDescription,
128 # assertionValue AssertionValue }
129 componentType = NamedTypes(NamedType('attributeDesc', AttributeDescription()),
130 NamedType('assertionValue', AssertionValue()))
131
132
133class MatchingRuleId(LDAPString):
134 # MatchingRuleId ::= LDAPString
135 pass
136
137
138class Vals(SetOf):
139 # vals SET OF value AttributeValue }
140 componentType = AttributeValue()
141
142
143class ValsAtLeast1(SetOf):
144 # vals SET OF value AttributeValue }
145 componentType = AttributeValue()
146 subtypeSpec = SetOf.subtypeSpec + size1ToMaxConstraint
147
148
149class PartialAttribute(Sequence):
150 # PartialAttribute ::= SEQUENCE {
151 # type AttributeDescription,
152 # vals SET OF value AttributeValue }
153 componentType = NamedTypes(NamedType('type', AttributeDescription()),
154 NamedType('vals', Vals()))
155
156
157class Attribute(Sequence):
158 # Attribute ::= PartialAttribute(WITH COMPONENTS {
159 # ...,
160 # vals (SIZE(1..MAX))})
161 componentType = NamedTypes(NamedType('type', AttributeDescription()),
162 # NamedType('vals', ValsAtLeast1()))
163 NamedType('vals', Vals())) # changed from ValsAtLeast1() to allow empty member values in groups - this should not be as per rfc4511 4.1.7, but openldap accept it
164
165
166class AttributeList(SequenceOf):
167 # AttributeList ::= SEQUENCE OF attribute Attribute
168 componentType = Attribute()
169
170
171class Simple(OctetString):
172 # simple [0] OCTET STRING,
173 tagSet = OctetString.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatSimple, 0))
174 encoding = 'utf-8'
175
176
177class Credentials(OctetString):
178 # credentials OCTET STRING
179 encoding = 'utf-8'
180
181
182class SaslCredentials(Sequence):
183 # SaslCredentials ::= SEQUENCE {
184 # mechanism LDAPString,
185 # credentials OCTET STRING OPTIONAL }
186 tagSet = Sequence.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatConstructed, 3))
187 componentType = NamedTypes(NamedType('mechanism', LDAPString()),
188 OptionalNamedType('credentials', Credentials()))
189
190
191# not in RFC4511 but used by Microsoft to embed the NTLM protocol in the BindRequest (Sicily Protocol)
192class SicilyPackageDiscovery(OctetString):
193 # sicilyPackageDiscovery [9] OCTET STRING,
194 tagSet = OctetString.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatSimple, 9))
195 encoding = 'utf-8'
196
197
198# not in RFC4511 but used by Microsoft to embed the NTLM protocol in the BindRequest (Sicily Protocol)
199class SicilyNegotiate(OctetString):
200 # sicilyNegotiate [10] OCTET STRING,
201 tagSet = OctetString.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatSimple, 10))
202 encoding = 'utf-8'
203
204
205# not in RFC4511 but used by Microsoft to embed the NTLM protocol in the BindRequest (Sicily Protocol)
206class SicilyResponse(OctetString):
207 # sicilyResponse [11] OCTET STRING,
208 tagSet = OctetString.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatSimple, 11))
209 encoding = 'utf-8'
210
211
212class AuthenticationChoice(Choice):
213 # AuthenticationChoice ::= CHOICE {
214 # simple [0] OCTET STRING,
215 # -- 1 and 2 reserved
216 # sasl [3] SaslCredentials,
217 # ... }
218
219 # from https://msdn.microsoft.com/en-us/library/cc223498.aspx # legacy NTLM authentication for Windows Active Directory
220 # sicilyPackageDiscovery [9] OCTET STRING
221 # sicilyNegotiate [10] OCTET STRING
222 # sicilyResponse [11] OCTET STRING }
223
224 componentType = NamedTypes(NamedType('simple', Simple()),
225 NamedType('sasl', SaslCredentials()),
226 NamedType('sicilyPackageDiscovery', SicilyPackageDiscovery()),
227 NamedType('sicilyNegotiate', SicilyNegotiate()),
228 NamedType('sicilyResponse', SicilyResponse()),
229 )
230
231
232class Version(Integer):
233 # version INTEGER (1 .. 127),
234 subtypeSpec = Integer.subtypeSpec + rangeInt1To127Constraint
235
236
237class ResultCode(Enumerated):
238 # resultCode ENUMERATED {
239 # success (0),
240 # operationsError (1),
241 # protocolError (2),
242 # timeLimitExceeded (3),
243 # sizeLimitExceeded (4),
244 # compareFalse (5),
245 # compareTrue (6),
246 # authMethodNotSupported (7),
247 # strongerAuthRequired (8),
248 # -- 9 reserved --
249 # referral (10),
250 # adminLimitExceeded (11),
251 # unavailableCriticalExtension (12),
252 # confidentialityRequired (13),
253 # saslBindInProgress (14),
254 # noSuchAttribute (16),
255 # undefinedAttributeType (17),
256 # inappropriateMatching (18),
257 # constraintViolation (19),
258 # attributeOrValueExists (20),
259 # invalidAttributeSyntax (21),
260 # -- 22-31 unused --
261 # noSuchObject (32),
262 # aliasProblem (33),
263 # invalidDNSyntax (34),
264 # -- 35 reserved for undefined isLeaf --
265 # aliasDereferencingProblem (36),
266 # -- 37-47 unused --
267 # inappropriateAuthentication (48),
268 # invalidCredentials (49),
269 # insufficientAccessRights (50),
270 # busy (51),
271 # unavailable (52),
272 # unwillingToPerform (53),
273 # loopDetect (54),
274 # -- 55-63 unused --
275 # namingViolation (64),
276 # objectClassViolation (65),
277 # notAllowedOnNonLeaf (66),
278 # notAllowedOnRDN (67),
279 # entryAlreadyExists (68),
280 # objectClassModsProhibited (69),
281 # -- 70 reserved for CLDAP --
282 # affectsMultipleDSAs (71),
283 # -- 72-79 unused --
284 # other (80),
285 # ... }
286 #
287 # from IANA ldap-parameters:
288 # lcupResourcesExhausted 113 IESG [RFC3928]
289 # lcupSecurityViolation 114 IESG [RFC3928]
290 # lcupInvalidData 115 IESG [RFC3928]
291 # lcupUnsupportedScheme 116 IESG [RFC3928]
292 # lcupReloadRequired 117 IESG [RFC3928]
293 # canceled 118 IESG [RFC3909]
294 # noSuchOperation 119 IESG [RFC3909]
295 # tooLate 120 IESG [RFC3909]
296 # cannotCancel 121 IESG [RFC3909]
297 # assertionFailed 122 IESG [RFC4528]
298 # authorizationDenied 123 WELTMAN [RFC4370]
299 # e-syncRefreshRequired 4096 [Kurt_Zeilenga] [Jong_Hyuk_Choi] [RFC4533]
300 namedValues = NamedValues(('success', 0),
301 ('operationsError', 1),
302 ('protocolError', 2),
303 ('timeLimitExceeded', 3),
304 ('sizeLimitExceeded', 4),
305 ('compareFalse', 5),
306 ('compareTrue', 6),
307 ('authMethodNotSupported', 7),
308 ('strongerAuthRequired', 8),
309 ('referral', 10),
310 ('adminLimitExceeded', 11),
311 ('unavailableCriticalExtension', 12),
312 ('confidentialityRequired', 13),
313 ('saslBindInProgress', 14),
314 ('noSuchAttribute', 16),
315 ('undefinedAttributeType', 17),
316 ('inappropriateMatching', 18),
317 ('constraintViolation', 19),
318 ('attributeOrValueExists', 20),
319 ('invalidAttributeSyntax', 21),
320 ('noSuchObject', 32),
321 ('aliasProblem', 33),
322 ('invalidDNSyntax', 34),
323 ('aliasDereferencingProblem', 36),
324 ('inappropriateAuthentication', 48),
325 ('invalidCredentials', 49),
326 ('insufficientAccessRights', 50),
327 ('busy', 51),
328 ('unavailable', 52),
329 ('unwillingToPerform', 53),
330 ('loopDetected', 54),
331 ('namingViolation', 64),
332 ('objectClassViolation', 65),
333 ('notAllowedOnNonLeaf', 66),
334 ('notAllowedOnRDN', 67),
335 ('entryAlreadyExists', 68),
336 ('objectClassModsProhibited', 69),
337 ('affectMultipleDSAs', 71),
338 ('other', 80),
339 ('lcupResourcesExhausted', 113),
340 ('lcupSecurityViolation', 114),
341 ('lcupInvalidData', 115),
342 ('lcupUnsupportedScheme', 116),
343 ('lcupReloadRequired', 117),
344 ('canceled', 118),
345 ('noSuchOperation', 119),
346 ('tooLate', 120),
347 ('cannotCancel', 121),
348 ('assertionFailed', 122),
349 ('authorizationDenied', 123),
350 ('e-syncRefreshRequired', 4096))
351
352 subTypeSpec = Enumerated.subtypeSpec + responseValueConstraint
353
354
355class URI(LDAPString):
356 # URI ::= LDAPString -- limited to characters permitted in
357 # -- URIs
358
359 # subtypeSpec = LDAPString.subTypeSpec + uriConstrain
360 pass
361
362
363class Referral(SequenceOf):
364 # Referral ::= SEQUENCE SIZE (1..MAX) OF uri URI
365 tagSet = SequenceOf.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatConstructed, 3))
366 componentType = URI()
367
368
369class ServerSaslCreds(OctetString):
370 # serverSaslCreds [7] OCTET STRING OPTIONAL
371 tagSet = OctetString.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatSimple, 7))
372 encoding = 'utf-8'
373
374
375class LDAPResult(Sequence):
376 # LDAPResult ::= SEQUENCE {
377 # resultCode ENUMERATED {
378 # success (0),
379 # operationsError (1),
380 # protocolError (2),
381 # timeLimitExceeded (3),
382 # sizeLimitExceeded (4),
383 # compareFalse (5),
384 # compareTrue (6),
385 # authMethodNotSupported (7),
386 # strongerAuthRequired (8),
387 # -- 9 reserved --
388 # referral (10),
389 # adminLimitExceeded (11),
390 # unavailableCriticalExtension (12),
391 # confidentialityRequired (13),
392 # saslBindInProgress (14),
393 # noSuchAttribute (16),
394 # undefinedAttributeType (17),
395 # inappropriateMatching (18),
396 # constraintViolation (19),
397 # attributeOrValueExists (20),
398 # invalidAttributeSyntax (21),
399 # -- 22-31 unused --
400 # noSuchObject (32),
401 # aliasProblem (33),
402 # invalidDNSyntax (34),
403 # -- 35 reserved for undefined isLeaf --
404 # aliasDereferencingProblem (36),
405 # -- 37-47 unused --
406 # inappropriateAuthentication (48),
407 # invalidCredentials (49),
408 # insufficientAccessRights (50),
409 # busy (51),
410 # unavailable (52),
411 # unwillingToPerform (53),
412 # loopDetect (54),
413 # -- 55-63 unused --
414 # namingViolation (64),
415 # objectClassViolation (65),
416 # notAllowedOnNonLeaf (66),
417 # notAllowedOnRDN (67),
418 # entryAlreadyExists (68),
419 # objectClassModsProhibited (69),
420 # -- 70 reserved for CLDAP --
421 # affectsMultipleDSAs (71),
422 # -- 72-79 unused --
423 # other (80),
424 # ... },
425 # matchedDN LDAPDN,
426 # diagnosticMessage LDAPString,
427 # referral [3] Referral OPTIONAL }
428 componentType = NamedTypes(NamedType('resultCode', ResultCode()),
429 NamedType('matchedDN', LDAPDN()),
430 NamedType('diagnosticMessage', LDAPString()),
431 OptionalNamedType('referral', Referral()))
432
433
434class Criticality(Boolean):
435 # criticality BOOLEAN DEFAULT FALSE
436 defaultValue = False
437
438
439class ControlValue(OctetString):
440 # controlValue OCTET STRING
441 encoding = 'utf-8'
442
443
444class Control(Sequence):
445 # Control ::= SEQUENCE {
446 # controlType LDAPOID,
447 # criticality BOOLEAN DEFAULT FALSE,
448 # controlValue OCTET STRING OPTIONAL }
449 componentType = NamedTypes(NamedType('controlType', LDAPOID()),
450 DefaultedNamedType('criticality', Criticality()),
451 OptionalNamedType('controlValue', ControlValue()))
452
453
454class Controls(SequenceOf):
455 # Controls ::= SEQUENCE OF control Control
456 tagSet = SequenceOf.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatConstructed, 0))
457 componentType = Control()
458
459
460class Scope(Enumerated):
461 # scope ENUMERATED {
462 # baseObject (0),
463 # singleLevel (1),
464 # wholeSubtree (2),
465 namedValues = NamedValues(('baseObject', 0),
466 ('singleLevel', 1),
467 ('wholeSubtree', 2))
468
469
470class DerefAliases(Enumerated):
471 # derefAliases ENUMERATED {
472 # neverDerefAliases (0),
473 # derefInSearching (1),
474 # derefFindingBaseObj (2),
475 # derefAlways (3) },
476 namedValues = NamedValues(('neverDerefAliases', 0),
477 ('derefInSearching', 1),
478 ('derefFindingBaseObj', 2),
479 ('derefAlways', 3))
480
481
482class TypesOnly(Boolean):
483 # typesOnly BOOLEAN
484 pass
485
486
487class Selector(LDAPString):
488 # -- The LDAPString is constrained to
489 # -- <attributeSelector> in Section 4.5.1.8
490
491 # subtypeSpec = LDAPString.subtypeSpec + attributeSelectorConstraint
492 pass
493
494
495class AttributeSelection(SequenceOf):
496 # AttributeSelection ::= SEQUENCE OF selector LDAPString
497 # -- The LDAPString is constrained to
498 # -- <attributeSelector> in Section 4.5.1.8
499 componentType = Selector()
500
501
502class MatchingRule(MatchingRuleId):
503 # matchingRule [1] MatchingRuleId
504 tagSet = MatchingRuleId.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatSimple, 1))
505
506
507class Type(AttributeDescription):
508 # type [2] AttributeDescription
509 tagSet = AttributeDescription.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatSimple, 2))
510
511
512class MatchValue(AssertionValue):
513 # matchValue [3] AssertionValue,
514 tagSet = AssertionValue.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatSimple, 3))
515
516
517class DnAttributes(Boolean):
518 # dnAttributes [4] BOOLEAN DEFAULT FALSE }
519 tagSet = Boolean.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatSimple, 4))
520 defaultValue = Boolean(False)
521
522
523class MatchingRuleAssertion(Sequence):
524 # MatchingRuleAssertion ::= SEQUENCE {
525 # matchingRule [1] MatchingRuleId OPTIONAL,
526 # type [2] AttributeDescription OPTIONAL,
527 # matchValue [3] AssertionValue,
528 # dnAttributes [4] BOOLEAN DEFAULT FALSE }
529 componentType = NamedTypes(OptionalNamedType('matchingRule', MatchingRule()),
530 OptionalNamedType('type', Type()),
531 NamedType('matchValue', MatchValue()),
532 DefaultedNamedType('dnAttributes', DnAttributes()))
533
534
535class Initial(AssertionValue):
536 # initial [0] AssertionValue, -- can occur at most once
537 tagSet = AssertionValue.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatSimple, 0))
538
539
540class Any(AssertionValue):
541 # any [1] AssertionValue,
542 tagSet = AssertionValue.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatSimple, 1))
543
544
545class Final(AssertionValue):
546 # final [1] AssertionValue, -- can occur at most once
547 tagSet = AssertionValue.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatSimple, 2))
548
549
550class Substring(Choice):
551 # substring CHOICE {
552 # initial [0] AssertionValue, -- can occur at most once
553 # any [1] AssertionValue,
554 # final [2] AssertionValue } -- can occur at most once
555 # }
556 componentType = NamedTypes(NamedType('initial', Initial()),
557 NamedType('any', Any()),
558 NamedType('final', Final()))
559
560
561class Substrings(SequenceOf):
562 # substrings SEQUENCE SIZE (1..MAX) OF substring CHOICE {
563 # ...
564 # }
565 subtypeSpec = SequenceOf.subtypeSpec + size1ToMaxConstraint
566 componentType = Substring()
567
568
569class SubstringFilter(Sequence):
570 # SubstringFilter ::= SEQUENCE {
571 # type AttributeDescription,
572 # substrings SEQUENCE SIZE (1..MAX) OF substring CHOICE {
573 # initial [0] AssertionValue, -- can occur at most once
574 # any [1] AssertionValue,
575 # final [2] AssertionValue } -- can occur at most once
576 # }
577 tagSet = Sequence.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatConstructed, 4))
578 componentType = NamedTypes(NamedType('type', AttributeDescription()),
579 NamedType('substrings', Substrings()))
580
581
582class And(SetOf):
583 # and [0] SET SIZE (1..MAX) OF filter Filter
584 tagSet = SetOf.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatConstructed, 0))
585 subtypeSpec = SetOf.subtypeSpec + size1ToMaxConstraint
586
587
588class Or(SetOf):
589 # or [1] SET SIZE (1..MAX) OF filter Filter
590 tagSet = SetOf.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatConstructed, 1))
591 subtypeSpec = SetOf.subtypeSpec + size1ToMaxConstraint
592
593
594class Not(Choice):
595 # not [2] Filter
596 pass # defined after Filter definition to allow recursion
597
598
599class EqualityMatch(AttributeValueAssertion):
600 # equalityMatch [3] AttributeValueAssertion
601 tagSet = AttributeValueAssertion.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatConstructed, 3))
602
603
604class GreaterOrEqual(AttributeValueAssertion):
605 # greaterOrEqual [5] AttributeValueAssertion
606 tagSet = AttributeValueAssertion.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatConstructed, 5))
607
608
609class LessOrEqual(AttributeValueAssertion):
610 # lessOrEqual [6] AttributeValueAssertion
611 tagSet = AttributeValueAssertion.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatConstructed, 6))
612
613
614class Present(AttributeDescription):
615 # present [7] AttributeDescription
616 tagSet = AttributeDescription.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatConstructed, 7))
617
618
619class ApproxMatch(AttributeValueAssertion):
620 # approxMatch [8] AttributeValueAssertion
621 tagSet = AttributeValueAssertion.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatConstructed, 8))
622
623
624class ExtensibleMatch(MatchingRuleAssertion):
625 # extensibleMatch [9] MatchingRuleAssertion
626 tagSet = MatchingRuleAssertion.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatConstructed, 9))
627
628
629class Filter(Choice):
630 # Filter ::= CHOICE {
631 # and [0] SET SIZE (1..MAX) OF filter Filter,
632 # or [1] SET SIZE (1..MAX) OF filter Filter,
633 # not [2] Filter,
634 # equalityMatch [3] AttributeValueAssertion,
635 # substrings [4] SubstringFilter,
636 # greaterOrEqual [5] AttributeValueAssertion,
637 # lessOrEqual [6] AttributeValueAssertion,
638 # present [7] AttributeDescription,
639 # approxMatch [8] AttributeValueAssertion,
640 # extensibleMatch [9] MatchingRuleAssertion,
641 # ... }
642 componentType = NamedTypes(NamedType('and', And()),
643 NamedType('or', Or()),
644 NamedType('notFilter', Not()),
645 NamedType('equalityMatch', EqualityMatch()),
646 NamedType('substringFilter', SubstringFilter()),
647 NamedType('greaterOrEqual', GreaterOrEqual()),
648 NamedType('lessOrEqual', LessOrEqual()),
649 NamedType('present', Present()),
650 NamedType('approxMatch', ApproxMatch()),
651 NamedType('extensibleMatch', ExtensibleMatch()))
652
653
654And.componentType = Filter()
655Or.componentType = Filter()
656Not.componentType = NamedTypes(NamedType('innerNotFilter', Filter()))
657Not.tagSet = Filter.tagSet.tagExplicitly(Tag(tagClassContext, tagFormatConstructed, 2)) # as per RFC4511 page 23
658
659
660class PartialAttributeList(SequenceOf):
661 # PartialAttributeList ::= SEQUENCE OF
662 # partialAttribute PartialAttribute
663 componentType = PartialAttribute()
664
665
666class Operation(Enumerated):
667 # operation ENUMERATED {
668 # add (0),
669 # delete (1),
670 # replace (2),
671 # ... }
672 namedValues = NamedValues(('add', 0),
673 ('delete', 1),
674 ('replace', 2),
675 ('increment', 3))
676
677
678class Change(Sequence):
679 # change SEQUENCE {
680 # operation ENUMERATED {
681 # add (0),
682 # delete (1),
683 # replace (2),
684 # ... },
685 # modification PartialAttribute } }
686 componentType = NamedTypes(NamedType('operation', Operation()),
687 NamedType('modification', PartialAttribute()))
688
689
690class Changes(SequenceOf):
691 # changes SEQUENCE OF change SEQUENCE
692 componentType = Change()
693
694
695class DeleteOldRDN(Boolean):
696 # deleteoldrdn BOOLEAN
697 pass
698
699
700class NewSuperior(LDAPDN):
701 # newSuperior [0] LDAPDN
702 tagSet = LDAPDN.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatSimple, 0))
703
704
705class RequestName(LDAPOID):
706 # requestName [0] LDAPOID
707 tagSet = LDAPOID.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatSimple, 0))
708
709
710class RequestValue(OctetString):
711 # requestValue [1] OCTET STRING
712 tagSet = OctetString.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatSimple, 1))
713 encoding = 'utf-8'
714
715
716class ResponseName(LDAPOID):
717 # responseName [10] LDAPOID
718 tagSet = LDAPOID.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatSimple, 10))
719
720
721class ResponseValue(OctetString):
722 # responseValue [11] OCTET STRING
723 tagSet = OctetString.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatSimple, 11))
724 encoding = 'utf-8'
725
726
727class IntermediateResponseName(LDAPOID):
728 # responseName [0] LDAPOID
729 tagSet = LDAPOID.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatSimple, 0))
730
731
732class IntermediateResponseValue(OctetString):
733 # responseValue [1] OCTET STRING
734 tagSet = OctetString.tagSet.tagImplicitly(Tag(tagClassContext, tagFormatSimple, 1))
735 encoding = 'utf-8'
736
737
738# operations
739class BindRequest(Sequence):
740 # BindRequest ::= [APPLICATION 0] SEQUENCE {
741 # version INTEGER (1 .. 127),
742 # name LDAPDN,
743 # authentication AuthenticationChoice }
744 tagSet = Sequence.tagSet.tagImplicitly(Tag(tagClassApplication, tagFormatConstructed, 0))
745 componentType = NamedTypes(NamedType('version', Version()),
746 NamedType('name', LDAPDN()),
747 NamedType('authentication', AuthenticationChoice()))
748
749
750class BindResponse(Sequence):
751 # BindResponse ::= [APPLICATION 1] SEQUENCE {
752 # COMPONENTS OF LDAPResult,
753 # serverSaslCreds [7] OCTET STRING OPTIONAL }
754 tagSet = Sequence.tagSet.tagImplicitly(Tag(tagClassApplication, tagFormatConstructed, 1))
755 componentType = NamedTypes(NamedType('resultCode', ResultCode()),
756 NamedType('matchedDN', LDAPDN()),
757 NamedType('diagnosticMessage', LDAPString()),
758 OptionalNamedType('referral', Referral()),
759 OptionalNamedType('serverSaslCreds', ServerSaslCreds()))
760
761
762class UnbindRequest(Null):
763 # UnbindRequest ::= [APPLICATION 2] NULL
764 tagSet = Null.tagSet.tagImplicitly(Tag(tagClassApplication, tagFormatSimple, 2))
765
766
767class SearchRequest(Sequence):
768 # SearchRequest ::= [APPLICATION 3] SEQUENCE {
769 # baseObject LDAPDN,
770 # scope ENUMERATED {
771 # baseObject (0),
772 # singleLevel (1),
773 # wholeSubtree (2),
774 # ... },
775 # derefAliases ENUMERATED {
776 # neverDerefAliases (0),
777 # derefInSearching (1),
778 # derefFindingBaseObj (2),
779 # derefAlways (3) },
780 # sizeLimit INTEGER (0 .. maxInt),
781 # timeLimit INTEGER (0 .. maxInt),
782 # typesOnly BOOLEAN,
783 # filter Filter,
784 # attributes AttributeSelection }
785 tagSet = Sequence.tagSet.tagImplicitly(Tag(tagClassApplication, tagFormatConstructed, 3))
786 componentType = NamedTypes(NamedType('baseObject', LDAPDN()),
787 NamedType('scope', Scope()),
788 NamedType('derefAliases', DerefAliases()),
789 NamedType('sizeLimit', Integer0ToMax()),
790 NamedType('timeLimit', Integer0ToMax()),
791 NamedType('typesOnly', TypesOnly()),
792 NamedType('filter', Filter()),
793 NamedType('attributes', AttributeSelection()))
794
795
796class SearchResultReference(SequenceOf):
797 # SearchResultReference ::= [APPLICATION 19] SEQUENCE
798 # SIZE (1..MAX) OF uri URI
799 tagSet = SequenceOf.tagSet.tagImplicitly(Tag(tagClassApplication, tagFormatConstructed, 19))
800 subtypeSpec = SequenceOf.subtypeSpec + size1ToMaxConstraint
801 componentType = URI()
802
803
804class SearchResultEntry(Sequence):
805 # SearchResultEntry ::= [APPLICATION 4] SEQUENCE {
806 # objectName LDAPDN,
807 # attributes PartialAttributeList }
808 tagSet = Sequence.tagSet.tagImplicitly(Tag(tagClassApplication, tagFormatConstructed, 4))
809 componentType = NamedTypes(NamedType('object', LDAPDN()),
810 NamedType('attributes', PartialAttributeList()))
811
812
813class SearchResultDone(LDAPResult):
814 # SearchResultDone ::= [APPLICATION 5] LDAPResult
815 tagSet = LDAPResult.tagSet.tagImplicitly(Tag(tagClassApplication, tagFormatConstructed, 5))
816
817
818class ModifyRequest(Sequence):
819 # ModifyRequest ::= [APPLICATION 6] SEQUENCE {
820 # object LDAPDN,
821 # changes SEQUENCE OF change SEQUENCE {
822 # operation ENUMERATED {
823 # add (0),
824 # delete (1),
825 # replace (2),
826 # ... },
827 # modification PartialAttribute } }
828 tagSet = Sequence.tagSet.tagImplicitly(Tag(tagClassApplication, tagFormatConstructed, 6))
829 componentType = NamedTypes(NamedType('object', LDAPDN()),
830 NamedType('changes', Changes()))
831
832
833class ModifyResponse(LDAPResult):
834 # ModifyResponse ::= [APPLICATION 7] LDAPResult
835 tagSet = LDAPResult.tagSet.tagImplicitly(Tag(tagClassApplication, tagFormatConstructed, 7))
836
837
838class AddRequest(Sequence):
839 # AddRequest ::= [APPLICATION 8] SEQUENCE {
840 # entry LDAPDN,
841 # attributes AttributeList }
842 tagSet = Sequence.tagSet.tagImplicitly(Tag(tagClassApplication, tagFormatConstructed, 8))
843 componentType = NamedTypes(NamedType('entry', LDAPDN()),
844 NamedType('attributes', AttributeList()))
845
846
847class AddResponse(LDAPResult):
848 # AddResponse ::= [APPLICATION 9] LDAPResult
849 tagSet = LDAPResult.tagSet.tagImplicitly(Tag(tagClassApplication, tagFormatConstructed, 9))
850
851
852class DelRequest(LDAPDN):
853 # DelRequest ::= [APPLICATION 10] LDAPDN
854 tagSet = LDAPDN.tagSet.tagImplicitly(Tag(tagClassApplication, tagFormatSimple, 10))
855
856
857class DelResponse(LDAPResult):
858 # DelResponse ::= [APPLICATION 11] LDAPResult
859 tagSet = LDAPResult.tagSet.tagImplicitly(Tag(tagClassApplication, tagFormatConstructed, 11))
860
861
862class ModifyDNRequest(Sequence):
863 # ModifyDNRequest ::= [APPLICATION 12] SEQUENCE {
864 # entry LDAPDN,
865 # newrdn RelativeLDAPDN,
866 # deleteoldrdn BOOLEAN,
867 # newSuperior [0] LDAPDN OPTIONAL }
868 tagSet = Sequence.tagSet.tagImplicitly(Tag(tagClassApplication, tagFormatConstructed, 12))
869 componentType = NamedTypes(NamedType('entry', LDAPDN()),
870 NamedType('newrdn', RelativeLDAPDN()),
871 NamedType('deleteoldrdn', DeleteOldRDN()),
872 OptionalNamedType('newSuperior', NewSuperior()))
873
874
875class ModifyDNResponse(LDAPResult):
876 # ModifyDNResponse ::= [APPLICATION 13] LDAPResult
877 tagSet = LDAPResult.tagSet.tagImplicitly(Tag(tagClassApplication, tagFormatConstructed, 13))
878
879
880class CompareRequest(Sequence):
881 # CompareRequest ::= [APPLICATION 14] SEQUENCE {
882 # entry LDAPDN,
883 # ava AttributeValueAssertion }
884 tagSet = Sequence.tagSet.tagImplicitly(Tag(tagClassApplication, tagFormatConstructed, 14))
885 componentType = NamedTypes(NamedType('entry', LDAPDN()),
886 NamedType('ava', AttributeValueAssertion()))
887
888
889class CompareResponse(LDAPResult):
890 # CompareResponse ::= [APPLICATION 15] LDAPResult
891 tagSet = LDAPResult.tagSet.tagImplicitly(Tag(tagClassApplication, tagFormatConstructed, 15))
892
893
894class AbandonRequest(MessageID):
895 # AbandonRequest ::= [APPLICATION 16] MessageID
896 tagSet = MessageID.tagSet.tagImplicitly(Tag(tagClassApplication, tagFormatSimple, 16))
897
898
899class ExtendedRequest(Sequence):
900 # ExtendedRequest ::= [APPLICATION 23] SEQUENCE {
901 # requestName [0] LDAPOID,
902 # requestValue [1] OCTET STRING OPTIONAL }
903 tagSet = Sequence.tagSet.tagImplicitly(Tag(tagClassApplication, tagFormatConstructed, 23))
904 componentType = NamedTypes(NamedType('requestName', RequestName()),
905 OptionalNamedType('requestValue', RequestValue()))
906
907
908class ExtendedResponse(Sequence):
909 # ExtendedResponse ::= [APPLICATION 24] SEQUENCE {
910 # COMPONENTS OF LDAPResult,
911 # responseName [10] LDAPOID OPTIONAL,
912 # responseValue [11] OCTET STRING OPTIONAL }
913 tagSet = Sequence.tagSet.tagImplicitly(Tag(tagClassApplication, tagFormatConstructed, 24))
914 componentType = NamedTypes(NamedType('resultCode', ResultCode()),
915 NamedType('matchedDN', LDAPDN()),
916 NamedType('diagnosticMessage', LDAPString()),
917 OptionalNamedType('referral', Referral()),
918 OptionalNamedType('responseName', ResponseName()),
919 OptionalNamedType('responseValue', ResponseValue()))
920
921
922class IntermediateResponse(Sequence):
923 # IntermediateResponse ::= [APPLICATION 25] SEQUENCE {
924 # responseName [0] LDAPOID OPTIONAL,
925 # responseValue [1] OCTET STRING OPTIONAL }
926 tagSet = Sequence.tagSet.tagImplicitly(Tag(tagClassApplication, tagFormatConstructed, 25))
927 componentType = NamedTypes(OptionalNamedType('responseName', IntermediateResponseName()),
928 OptionalNamedType('responseValue', IntermediateResponseValue()))
929
930
931class ProtocolOp(Choice):
932 # protocolOp CHOICE {
933 # bindRequest BindRequest,
934 # bindResponse BindResponse,
935 # unbindRequest UnbindRequest,
936 # searchRequest SearchRequest,
937 # searchResEntry SearchResultEntry,
938 # searchResDone SearchResultDone,
939 # searchResRef SearchResultReference,
940 # modifyRequest ModifyRequest,
941 # modifyResponse ModifyResponse,
942 # addRequest AddRequest,
943 # addResponse AddResponse,
944 # delRequest DelRequest,
945 # delResponse DelResponse,
946 # modDNRequest ModifyDNRequest,
947 # modDNResponse ModifyDNResponse,
948 # compareRequest CompareRequest,
949 # compareResponse CompareResponse,
950 # abandonRequest AbandonRequest,
951 # extendedReq ExtendedRequest,
952 # extendedResp ExtendedResponse,
953 # ...,
954 # intermediateResponse IntermediateResponse }
955 componentType = NamedTypes(NamedType('bindRequest', BindRequest()),
956 NamedType('bindResponse', BindResponse()),
957 NamedType('unbindRequest', UnbindRequest()),
958 NamedType('searchRequest', SearchRequest()),
959 NamedType('searchResEntry', SearchResultEntry()),
960 NamedType('searchResDone', SearchResultDone()),
961 NamedType('searchResRef', SearchResultReference()),
962 NamedType('modifyRequest', ModifyRequest()),
963 NamedType('modifyResponse', ModifyResponse()),
964 NamedType('addRequest', AddRequest()),
965 NamedType('addResponse', AddResponse()),
966 NamedType('delRequest', DelRequest()),
967 NamedType('delResponse', DelResponse()),
968 NamedType('modDNRequest', ModifyDNRequest()),
969 NamedType('modDNResponse', ModifyDNResponse()),
970 NamedType('compareRequest', CompareRequest()),
971 NamedType('compareResponse', CompareResponse()),
972 NamedType('abandonRequest', AbandonRequest()),
973 NamedType('extendedReq', ExtendedRequest()),
974 NamedType('extendedResp', ExtendedResponse()),
975 NamedType('intermediateResponse', IntermediateResponse()))
976
977
978class LDAPMessage(Sequence):
979 # LDAPMessage ::= SEQUENCE {
980 # messageID MessageID,
981 # protocolOp CHOICE {
982 # bindRequest BindRequest,
983 # bindResponse BindResponse,
984 # unbindRequest UnbindRequest,
985 # searchRequest SearchRequest,
986 # searchResEntry SearchResultEntry,
987 # searchResDone SearchResultDone,
988 # searchResRef SearchResultReference,
989 # modifyRequest ModifyRequest,
990 # modifyResponse ModifyResponse,
991 # addRequest AddRequest,
992 # addResponse AddResponse,
993 # delRequest DelRequest,
994 # delResponse DelResponse,
995 # modDNRequest ModifyDNRequest,
996 # modDNResponse ModifyDNResponse,
997 # compareRequest CompareRequest,
998 # compareResponse CompareResponse,
999 # abandonRequest AbandonRequest,
1000 # extendedReq ExtendedRequest,
1001 # extendedResp ExtendedResponse,
1002 # ...,
1003 # intermediateResponse IntermediateResponse },
1004 # controls [0] Controls OPTIONAL }
1005 componentType = NamedTypes(NamedType('messageID', MessageID()),
1006 NamedType('protocolOp', ProtocolOp()),
1007 OptionalNamedType('controls', Controls()))
1008 