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