1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 """LDAP protocol message conversion; no application logic here."""
18
19 from pureber import *
20
21 next_ldap_message_id=1
27
29 s = s.replace('\\', r'\5c')
30 s = s.replace('*', r'\2a')
31 s = s.replace('(', r'\28')
32 s = s.replace(')', r'\29')
33 s = s.replace('\0', r'\00')
34 return s
35
38
41
43 id = None
44 value = None
45
46 - def fromBER(klass, tag, content, berdecoder=None):
68 fromBER = classmethod(fromBER)
69
70 - def __init__(self, value=None, controls=None, id=None, tag=None):
78
84
86 l=[]
87 l.append('id=%r' % self.id)
88 l.append('value=%r' % self.value)
89 if self.tag!=self.__class__.tag:
90 l.append('tag=%d' % self.tag)
91 return self.__class__.__name__+'('+', '.join(l)+')'
92
96
98 raise NotImplementedError
99
103
106
111
113 tag=CLASS_APPLICATION|0x00
114
115 - def fromBER(klass, tag, content, berdecoder=None):
125 fromBER = classmethod(fromBER)
126
127 - def __init__(self, version=None, dn=None, auth=None, tag=None):
139
146
148 l=[]
149 l.append('version=%d' % self.version)
150 l.append('dn=%s' % repr(self.dn))
151 l.append('auth=%s' % repr(self.auth))
152 if self.tag!=self.__class__.tag:
153 l.append('tag=%d' % self.tag)
154 return self.__class__.__name__+'('+', '.join(l)+')'
155
156
157
160
161 -class LDAPResult(LDAPProtocolResponse, BERSequence):
162 - def fromBER(klass, tag, content, berdecoder=None):
179 fromBER = classmethod(fromBER)
180
181 - def __init__(self, resultCode=None, matchedDN=None, errorMessage=None, referral=None, serverSaslCreds=None, tag=None):
194
203
216
221
226
276
287
290
292 - def fromBER(klass, tag, content, berdecoder=None):
300 fromBER = classmethod(fromBER)
301
302 - def __init__(self, attributeDesc=None, assertionValue=None, tag=None):
303 BERSequence.__init__(self, value=[], tag=tag)
304 assert attributeDesc is not None
305 self.attributeDesc=attributeDesc
306 self.assertionValue=assertionValue
307
309 return str(BERSequence([self.attributeDesc,
310 self.assertionValue],
311 tag=self.tag))
312
314 if self.tag==self.__class__.tag:
315 return self.__class__.__name__+"(attributeDesc=%s, assertionValue=%s)"\
316 %(repr(self.attributeDesc), repr(self.assertionValue))
317 else:
318 return self.__class__.__name__+"(attributeDesc=%s, assertionValue=%s, tag=%d)"\
319 %(repr(self.attributeDesc), repr(self.assertionValue), self.tag)
320
321
325
332
338
344
378
385
391
392
398
404
411
413 tag = CLASS_CONTEXT|0x04
414
415 - def fromBER(klass, tag, content, berdecoder=None):
424 fromBER = classmethod(fromBER)
425
426 - def __init__(self, type=None, substrings=None, tag=None):
432
437
439 if self.tag==self.__class__.tag:
440 return self.__class__.__name__\
441 +"(type=%s, substrings=%s)"\
442 %(repr(self.type), repr(self.substrings))
443 else:
444 return self.__class__.__name__\
445 +"(type=%s, substrings=%s, tag=%d)"\
446 %(repr(self.type), repr(self.substrings), self.tag)
447
449 initial=None
450 final=None
451 any=[]
452
453 for s in self.substrings:
454 assert s is not None
455 if isinstance(s, LDAPFilter_substrings_initial):
456 assert initial is None
457 assert not any
458 assert final is None
459 initial=s.asText()
460 elif isinstance(s, LDAPFilter_substrings_final):
461 assert final is None
462 final=s.asText()
463 elif isinstance(s, LDAPFilter_substrings_any):
464 assert final is None
465 any.append(s.asText())
466 else:
467 raise NotImplementedError('TODO: Filter type not supported %r' % s)
468
469 if initial is None:
470 initial=''
471 if final is None:
472 final=''
473
474
475 return '('+self.type+'=' \
476 +'*'.join([initial]+any+[final])+')'
477
484
491
497
505
508
511
515
519
523
527
535
537 matchingRule=None
538 type=None
539 matchValue=None
540 dnAttributes=None
541
542 - def fromBER(klass, tag, content, berdecoder=None):
543 l = berDecodeMultiple(content, LDAPBERDecoderContext_MatchingRuleAssertion(fallback=berdecoder, inherit=berdecoder))
544
545 assert 1<=len(l)<=4
546 if isinstance(l[0], LDAPMatchingRuleAssertion_matchingRule):
547 matchingRule=l[0]
548 del l[0]
549 if len(l)>1 \
550 and isinstance(l[0], LDAPMatchingRuleAssertion_type):
551 type=l[0]
552 del l[0]
553 if len(l)>1 \
554 and isinstance(l[0], LDAPMatchingRuleAssertion_matchValue):
555 matchValue=l[0]
556 del l[0]
557 if len(l)>1 \
558 and isinstance(l[0], LDAPMatchingRuleAssertion_dnAttributes):
559 dnAttributes=l[0]
560 del l[0]
561 assert matchValue
562 if not dnAttributes:
563 dnAttributes=None
564
565 assert 8<=len(l)<=8
566 r = klass(matchingRule=matchingRule,
567 type=type,
568 matchValue=matchValue,
569 dnAttributes=dnAttributes,
570 tag=tag)
571 return r
572 fromBER = classmethod(fromBER)
573
574 - def __init__(self, matchingRule=None, type=None,
575 matchValue=None, dnAttributes=None,
576 tag=None):
585
589
591 l=[]
592 l.append('matchingRule=%s' % repr(self.matchingRule))
593 l.append('type=%s' % repr(self.type))
594 l.append('matchValue=%s' % repr(self.matchValue))
595 l.append('dnAttributes=%s' % repr(self.dnAttributes))
596 if self.tag!=self.__class__.tag:
597 l.append('tag=%d' % self.tag)
598 return self.__class__.__name__+'('+', '.join(l)+')'
599
603
604
605 -class LDAPBERDecoderContext_Filter(BERDecoderContext):
606 Identities = {
607 LDAPFilter_and.tag: LDAPFilter_and,
608 LDAPFilter_or.tag: LDAPFilter_or,
609 LDAPFilter_not.tag: LDAPFilter_not,
610 LDAPFilter_equalityMatch.tag: LDAPFilter_equalityMatch,
611 LDAPFilter_substrings.tag: LDAPFilter_substrings,
612 LDAPFilter_greaterOrEqual.tag: LDAPFilter_greaterOrEqual,
613 LDAPFilter_lessOrEqual.tag: LDAPFilter_lessOrEqual,
614 LDAPFilter_present.tag: LDAPFilter_present,
615 LDAPFilter_approxMatch.tag: LDAPFilter_approxMatch,
616 LDAPFilter_extensibleMatch.tag: LDAPFilter_extensibleMatch,
617 }
618
619 LDAP_SCOPE_baseObject=0
620 LDAP_SCOPE_singleLevel=1
621 LDAP_SCOPE_wholeSubtree=2
622
623 LDAP_DEREF_neverDerefAliases=0
624 LDAP_DEREF_derefInSearching=1
625 LDAP_DEREF_derefFindingBaseObj=2
626 LDAP_DEREF_derefAlways=3
627
628 LDAPFilterMatchAll = LDAPFilter_present('objectClass')
629
631 tag=CLASS_APPLICATION|0x03
632
633 baseObject=''
634 scope=LDAP_SCOPE_wholeSubtree
635 derefAliases=LDAP_DEREF_neverDerefAliases
636 sizeLimit=0
637 timeLimit=0
638 typesOnly=0
639 filter=LDAPFilterMatchAll
640 attributes=[]
641
642
643
644 - def fromBER(klass, tag, content, berdecoder=None):
645 l = berDecodeMultiple(content, LDAPBERDecoderContext_Filter(fallback=berdecoder, inherit=berdecoder))
646
647 assert 8<=len(l)<=8
648 r = klass(baseObject=l[0].value,
649 scope=l[1].value,
650 derefAliases=l[2].value,
651 sizeLimit=l[3].value,
652 timeLimit=l[4].value,
653 typesOnly=l[5].value,
654 filter=l[6],
655 attributes=[x.value for x in l[7]],
656 tag=tag)
657 return r
658 fromBER = classmethod(fromBER)
659
660 - def __init__(self,
661 baseObject=None,
662 scope=None,
663 derefAliases=None,
664 sizeLimit=None,
665 timeLimit=None,
666 typesOnly=None,
667 filter=None,
668 attributes=None,
669 tag=None):
689
691 return str(BERSequence([
692 BEROctetString(self.baseObject),
693 BEREnumerated(self.scope),
694 BEREnumerated(self.derefAliases),
695 BERInteger(self.sizeLimit),
696 BERInteger(self.timeLimit),
697 BERBoolean(self.typesOnly),
698 self.filter,
699 BERSequenceOf(map(BEROctetString, self.attributes)),
700 ], tag=self.tag))
701
703 if self.tag==self.__class__.tag:
704 return self.__class__.__name__\
705 +("(baseObject=%s, scope=%s, derefAliases=%s, " \
706 +"sizeLimit=%s, timeLimit=%s, typesOnly=%s, " \
707 "filter=%s, attributes=%s)") \
708 %(repr(self.baseObject), self.scope,
709 self.derefAliases, self.sizeLimit,
710 self.timeLimit, self.typesOnly,
711 repr(self.filter), self.attributes)
712
713 else:
714 return self.__class__.__name__\
715 +("(baseObject=%s, scope=%s, derefAliases=%s, " \
716 +"sizeLimit=%s, timeLimit=%s, typesOnly=%s, " \
717 "filter=%s, attributes=%s, tag=%d)") \
718 %(repr(self.baseObject), self.scope,
719 self.derefAliases, self.sizeLimit,
720 self.timeLimit, self.typesOnly,
721 self.filter, self.attributes, self.tag)
722
723 -class LDAPSearchResultEntry(LDAPProtocolResponse, BERSequence):
724 tag=CLASS_APPLICATION|0x04
725
726 - def fromBER(klass, tag, content, berdecoder=None):
727 l = berDecodeMultiple(content, LDAPBERDecoderContext_Filter(fallback=berdecoder, inherit=berdecoder))
728
729 objectName=l[0].value
730 attributes=[]
731 for attr, li in l[1].data:
732 attributes.append((attr.value, map(lambda x: x.value, li)))
733 r = klass(objectName=objectName,
734 attributes=attributes,
735 tag=tag)
736 return r
737 fromBER = classmethod(fromBER)
738
739 - def __init__(self, objectName, attributes, tag=None):
740 LDAPProtocolResponse.__init__(self)
741 BERSequence.__init__(self, [], tag=tag)
742 assert objectName is not None
743 assert attributes is not None
744 self.objectName=objectName
745 self.attributes=attributes
746
748 return str(BERSequence([
749 BEROctetString(self.objectName),
750 BERSequence(map(lambda (attr,li):
751 BERSequence([BEROctetString(attr),
752 BERSet(map(BEROctetString,
753 li))]),
754 self.attributes)),
755 ], tag=self.tag))
756
757 - def __repr__(self):
758 if self.tag==self.__class__.tag:
759 return self.__class__.__name__\
760 +"(objectName=%s, attributes=%s"\
761 %(repr(str(self.objectName)),
762 repr(map(lambda (a,l):
763 (str(a),
764 map(lambda i, l=l: str(i), l)),
765 self.attributes)))
766 else:
767 return self.__class__.__name__\
768 +"(objectName=%s, attributes=%s, tag=%d"\
769 %(repr(str(self.objectName)),
770 repr(map(lambda (a,l):
771 (str(a),
772 map(lambda i, l=l: str(i), l)),
773 self.attributes)),
774 self.tag)
775
776
781
792
830
835
840
845
847 tag=CLASS_APPLICATION|0x06
848 object = None
849 modification = None
850
851 - def fromBER(klass, tag, content, berdecoder=None):
860 fromBER = classmethod(fromBER)
861
862 - def __init__(self, object=None, modification=None, tag=None):
863 """
864 Initialize the object
865
866 Example usage::
867
868 l = LDAPModifyRequest(
869 object='cn=foo,dc=example,dc=com',
870 modification=[
871
872 BERSequence([
873 BEREnumerated(0),
874 BERSequence([
875 LDAPAttributeDescription('attr1'),
876 BERSet([
877 LDAPString('value1'),
878 LDAPString('value2'),
879 ]),
880 ]),
881 ]),
882
883 BERSequence([
884 BEREnumerated(1),
885 BERSequence([
886 LDAPAttributeDescription('attr2'),
887 ]),
888 ]),
889
890 ])
891
892 But more likely you just want to say::
893
894 mod = delta.ModifyOp('cn=foo,dc=example,dc=com',
895 [delta.Add('attr1', ['value1', 'value2']),
896 delta.Delete('attr1', ['value1', 'value2'])])
897 l = mod.asLDAP()
898 """
899
900 LDAPProtocolRequest.__init__(self)
901 BERSequence.__init__(self, [], tag=tag)
902 self.object=object
903 self.modification=modification
904
910
918
919
922
924 tag = CLASS_APPLICATION|0x08
925
926 - def fromBER(klass, tag, content, berdecoder=None):
933 fromBER = classmethod(fromBER)
934
935 - def __init__(self, entry=None, attributes=None, tag=None):
936 """
937 Initialize the object
938
939 Example usage::
940
941 l=LDAPAddRequest(entry='cn=foo,dc=example,dc=com',
942 attributes=[(LDAPAttributeDescription("attrFoo"),
943 BERSet(value=(
944 LDAPAttributeValue("value1"),
945 LDAPAttributeValue("value2"),
946 ))),
947 (LDAPAttributeDescription("attrBar"),
948 BERSet(value=(
949 LDAPAttributeValue("value1"),
950 LDAPAttributeValue("value2"),
951 ))),
952 ])
953 """
954
955 LDAPProtocolRequest.__init__(self)
956 BERSequence.__init__(self, [], tag=tag)
957 self.entry=entry
958 self.attributes=attributes
959
965
967 if self.tag==self.__class__.tag:
968 return self.__class__.__name__+"(entry=%s, attributes=%s)"\
969 %(repr(self.entry), repr(self.attributes))
970 else:
971 return self.__class__.__name__+"(entry=%s, attributes=%s, tag=%d)" \
972 %(repr(self.entry), repr(self.attributes), self.tag)
973
974
975
978
980 tag = CLASS_APPLICATION|0x0a
981
982 - def __init__(self, value=None, entry=None, tag=None):
992
995
997 if self.tag==self.__class__.tag:
998 return self.__class__.__name__+"(entry=%s)" \
999 %repr(self.value)
1000 else:
1001 return self.__class__.__name__ \
1002 +"(entry=%s, tag=%d)" \
1003 %(repr(self.value), self.tag)
1004
1005
1009
1010
1015
1020
1022 tag=CLASS_APPLICATION|12
1023
1024 entry=None
1025 newrdn=None
1026 deleteoldrdn=None
1027 newSuperior=None
1028
1029 - def fromBER(klass, tag, content, berdecoder=None):
1044 fromBER = classmethod(fromBER)
1045
1046 - def __init__(self, entry, newrdn, deleteoldrdn, newSuperior=None,
1047 tag=None):
1067
1077
1079 l = [
1080 "entry=%s" % repr(self.entry),
1081 "newrdn=%s" % repr(self.newrdn),
1082 "deleteoldrdn=%s" % repr(self.deleteoldrdn),
1083 ]
1084 if self.newSuperior is not None:
1085 l.append("newSuperior=%s" % repr(self.newSuperior))
1086 if self.tag!=self.__class__.tag:
1087 l.append("tag=%d" % self.tag)
1088 return self.__class__.__name__ + "(" + ', '.join(l) + ")"
1089
1092
1093
1094
1095
1096
1097
1098
1101
1104
1107
1113
1152
1159
1171
1173 oid = '1.3.6.1.4.1.4203.1.11.1'
1174
1175 - def __init__(self, requestName=None,
1176 userIdentity=None, oldPasswd=None, newPasswd=None,
1177 tag=None):
1196
1198 l=[]
1199
1200 if self.tag!=self.__class__.tag:
1201 l.append('tag=%d' % self.tag)
1202 return self.__class__.__name__+'('+', '.join(l)+')'
1203
1209
1211 tag = CLASS_APPLICATION|0x18
1212
1213 responseName = None
1214 response = None
1215
1216 - def fromBER(klass, tag, content, berdecoder=None):
1233 fromBER = classmethod(fromBER)
1234
1235 - def __init__(self, resultCode=None, matchedDN=None, errorMessage=None,
1236 referral=None, serverSaslCreds=None,
1237 responseName=None, response=None,
1238 tag=None):
1247
1260
1262 """
1263 Request to start Transport Layer Security.
1264
1265 See RFC 2830 for details.
1266 """
1267 oid = '1.3.6.1.4.1.1466.20037'
1268
1269 - def __init__(self, requestName=None, tag=None):
1279
1281 l=[]
1282 if self.tag!=self.__class__.tag:
1283 l.append('tag=%d' % self.tag)
1284 return self.__class__.__name__+'('+', '.join(l)+')'
1285
1286 -class LDAPBERDecoderContext(BERDecoderContext):
1287 Identities = {
1288 LDAPBindResponse.tag: LDAPBindResponse,
1289 LDAPBindRequest.tag: LDAPBindRequest,
1290 LDAPUnbindRequest.tag: LDAPUnbindRequest,
1291 LDAPSearchRequest.tag: LDAPSearchRequest,
1292 LDAPSearchResultEntry.tag: LDAPSearchResultEntry,
1293 LDAPSearchResultDone.tag: LDAPSearchResultDone,
1294 LDAPReferral.tag: LDAPReferral,
1295 LDAPModifyRequest.tag: LDAPModifyRequest,
1296 LDAPModifyResponse.tag: LDAPModifyResponse,
1297 LDAPAddRequest.tag: LDAPAddRequest,
1298 LDAPAddResponse.tag: LDAPAddResponse,
1299 LDAPDelRequest.tag: LDAPDelRequest,
1300 LDAPDelResponse.tag: LDAPDelResponse,
1301 LDAPExtendedRequest.tag: LDAPExtendedRequest,
1302 LDAPExtendedResponse.tag: LDAPExtendedResponse,
1303 LDAPModifyDNRequest.tag: LDAPModifyDNRequest,
1304 LDAPModifyDNResponse.tag: LDAPModifyDNResponse,
1305 }
1306