1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 """LDAP protocol message conversion; no application logic here."""
17
18 from pureber import (
19
20 BERBoolean, BERDecoderContext, BEREnumerated, BERInteger, BERNull,
21 BEROctetString, BERSequence, BERSequenceOf, BERSet, BERStructured,
22
23 CLASS_APPLICATION, CLASS_CONTEXT,
24
25 berDecodeMultiple, berDecodeObject, int2berlen,
26 )
27
28 next_ldap_message_id=1
34
36 s = s.replace('\\', r'\5c')
37 s = s.replace('*', r'\2a')
38 s = s.replace('(', r'\28')
39 s = s.replace(')', r'\29')
40 s = s.replace('\0', r'\00')
41 return s
42
45
48
51
53 id = None
54 value = None
55
56 - def fromBER(klass, tag, content, berdecoder=None):
78 fromBER = classmethod(fromBER)
79
80 - def __init__(self, value=None, controls=None, id=None, tag=None):
88
94
96 l=[]
97 l.append('id=%r' % self.id)
98 l.append('value=%r' % self.value)
99 if self.tag!=self.__class__.tag:
100 l.append('tag=%d' % self.tag)
101 return self.__class__.__name__+'('+', '.join(l)+')'
102
106
108 raise NotImplementedError
109
113
116
122
124 tag=CLASS_APPLICATION|0x00
125
126 - def fromBER(klass, tag, content, berdecoder=None):
145 fromBER = classmethod(fromBER)
146
147 - def __init__(self, version=None, dn=None, auth=None, tag=None, sasl=False):
148 """Constructor for LDAP Bind Request
149
150 For sasl=False, pass a string password for 'auth'
151 For sasl=True, pass a tuple of (mechanism, credentials) for 'auth'"""
152
153 LDAPProtocolRequest.__init__(self)
154 BERSequence.__init__(self, [], tag=tag)
155 self.version=version
156 if self.version is None:
157 self.version=3
158 self.dn=dn
159 if self.dn is None:
160 self.dn=''
161 self.auth=auth
162 if self.auth is None:
163 self.auth=''
164 assert(not sasl)
165 self.sasl=sasl
166
177
179 l=[]
180 l.append('version=%d' % self.version)
181 l.append('dn=%s' % repr(self.dn))
182 l.append('auth=%s' % repr(self.auth))
183 if self.tag!=self.__class__.tag:
184 l.append('tag=%d' % self.tag)
185 l.append('sasl=%s' % repr(self.sasl))
186 return self.__class__.__name__+'('+', '.join(l)+')'
187
190
191
192
209
210
211 -class LDAPResult(LDAPProtocolResponse, BERSequence):
212 - def fromBER(klass, tag, content, berdecoder=None):
229 fromBER = classmethod(fromBER)
230
231 - def __init__(self, resultCode=None, matchedDN=None, errorMessage=None, referral=None, serverSaslCreds=None, tag=None):
244
253
266
271
276
323
334
337
339 - def fromBER(klass, tag, content, berdecoder=None):
347 fromBER = classmethod(fromBER)
348
349 - def __init__(self, attributeDesc=None, assertionValue=None, tag=None):
350 BERSequence.__init__(self, value=[], tag=tag)
351 assert attributeDesc is not None
352 self.attributeDesc=attributeDesc
353 self.assertionValue=assertionValue
354
359
361 if self.tag==self.__class__.tag:
362 return self.__class__.__name__+"(attributeDesc=%s, assertionValue=%s)"\
363 %(repr(self.attributeDesc), repr(self.assertionValue))
364 else:
365 return self.__class__.__name__+"(attributeDesc=%s, assertionValue=%s, tag=%d)"\
366 %(repr(self.attributeDesc), repr(self.assertionValue), self.tag)
367
368
372
379
385
391
425
432
438
439
445
451
458
460 tag = CLASS_CONTEXT|0x04
461
462 - def fromBER(klass, tag, content, berdecoder=None):
471 fromBER = classmethod(fromBER)
472
473 - def __init__(self, type=None, substrings=None, tag=None):
479
484
486 if self.tag==self.__class__.tag:
487 return self.__class__.__name__\
488 +"(type=%s, substrings=%s)"\
489 %(repr(self.type), repr(self.substrings))
490 else:
491 return self.__class__.__name__\
492 +"(type=%s, substrings=%s, tag=%d)"\
493 %(repr(self.type), repr(self.substrings), self.tag)
494
496 initial=None
497 final=None
498 any=[]
499
500 for s in self.substrings:
501 assert s is not None
502 if isinstance(s, LDAPFilter_substrings_initial):
503 assert initial is None
504 assert not any
505 assert final is None
506 initial=s.asText()
507 elif isinstance(s, LDAPFilter_substrings_final):
508 assert final is None
509 final=s.asText()
510 elif isinstance(s, LDAPFilter_substrings_any):
511 assert final is None
512 any.append(s.asText())
513 else:
514 raise NotImplementedError('TODO: Filter type not supported %r' % s)
515
516 if initial is None:
517 initial=''
518 if final is None:
519 final=''
520
521
522 return '('+self.type+'=' \
523 +'*'.join([initial]+any+[final])+')'
524
531
538
544
552
555
558
562
566
570
574
582
584 matchingRule=None
585 type=None
586 matchValue=None
587 dnAttributes=None
588
589 - def fromBER(klass, tag, content, berdecoder=None):
590 l = berDecodeMultiple(content, LDAPBERDecoderContext_MatchingRuleAssertion(fallback=berdecoder, inherit=berdecoder))
591
592 assert 1<=len(l)<=4
593 if isinstance(l[0], LDAPMatchingRuleAssertion_matchingRule):
594 matchingRule=l[0]
595 del l[0]
596 if len(l)>1 \
597 and isinstance(l[0], LDAPMatchingRuleAssertion_type):
598 type=l[0]
599 del l[0]
600 if len(l)>1 \
601 and isinstance(l[0], LDAPMatchingRuleAssertion_matchValue):
602 matchValue=l[0]
603 del l[0]
604 if len(l)>1 \
605 and isinstance(l[0], LDAPMatchingRuleAssertion_dnAttributes):
606 dnAttributes=l[0]
607 del l[0]
608 assert matchValue
609 if not dnAttributes:
610 dnAttributes=None
611
612 assert 8<=len(l)<=8
613 r = klass(matchingRule=matchingRule,
614 type=type,
615 matchValue=matchValue,
616 dnAttributes=dnAttributes,
617 tag=tag)
618 return r
619 fromBER = classmethod(fromBER)
620
621 - def __init__(self, matchingRule=None, type=None,
622 matchValue=None, dnAttributes=None,
623 tag=None):
632
636
638 l=[]
639 l.append('matchingRule=%s' % repr(self.matchingRule))
640 l.append('type=%s' % repr(self.type))
641 l.append('matchValue=%s' % repr(self.matchValue))
642 l.append('dnAttributes=%s' % repr(self.dnAttributes))
643 if self.tag!=self.__class__.tag:
644 l.append('tag=%d' % self.tag)
645 return self.__class__.__name__+'('+', '.join(l)+')'
646
650
651
652 -class LDAPBERDecoderContext_Filter(BERDecoderContext):
653 Identities = {
654 LDAPFilter_and.tag: LDAPFilter_and,
655 LDAPFilter_or.tag: LDAPFilter_or,
656 LDAPFilter_not.tag: LDAPFilter_not,
657 LDAPFilter_equalityMatch.tag: LDAPFilter_equalityMatch,
658 LDAPFilter_substrings.tag: LDAPFilter_substrings,
659 LDAPFilter_greaterOrEqual.tag: LDAPFilter_greaterOrEqual,
660 LDAPFilter_lessOrEqual.tag: LDAPFilter_lessOrEqual,
661 LDAPFilter_present.tag: LDAPFilter_present,
662 LDAPFilter_approxMatch.tag: LDAPFilter_approxMatch,
663 LDAPFilter_extensibleMatch.tag: LDAPFilter_extensibleMatch,
664 }
665
666 LDAP_SCOPE_baseObject=0
667 LDAP_SCOPE_singleLevel=1
668 LDAP_SCOPE_wholeSubtree=2
669
670 LDAP_DEREF_neverDerefAliases=0
671 LDAP_DEREF_derefInSearching=1
672 LDAP_DEREF_derefFindingBaseObj=2
673 LDAP_DEREF_derefAlways=3
674
675 LDAPFilterMatchAll = LDAPFilter_present('objectClass')
676
678 tag=CLASS_APPLICATION|0x03
679
680 baseObject=''
681 scope=LDAP_SCOPE_wholeSubtree
682 derefAliases=LDAP_DEREF_neverDerefAliases
683 sizeLimit=0
684 timeLimit=0
685 typesOnly=0
686 filter=LDAPFilterMatchAll
687 attributes=[]
688
689
690
691 - def fromBER(klass, tag, content, berdecoder=None):
692 l = berDecodeMultiple(content, LDAPBERDecoderContext_Filter(fallback=berdecoder, inherit=berdecoder))
693
694 assert 8<=len(l)<=8
695 r = klass(baseObject=l[0].value,
696 scope=l[1].value,
697 derefAliases=l[2].value,
698 sizeLimit=l[3].value,
699 timeLimit=l[4].value,
700 typesOnly=l[5].value,
701 filter=l[6],
702 attributes=[x.value for x in l[7]],
703 tag=tag)
704 return r
705 fromBER = classmethod(fromBER)
706
707 - def __init__(self,
708 baseObject=None,
709 scope=None,
710 derefAliases=None,
711 sizeLimit=None,
712 timeLimit=None,
713 typesOnly=None,
714 filter=None,
715 attributes=None,
716 tag=None):
736
738 return str(BERSequence([
739 BEROctetString(self.baseObject),
740 BEREnumerated(self.scope),
741 BEREnumerated(self.derefAliases),
742 BERInteger(self.sizeLimit),
743 BERInteger(self.timeLimit),
744 BERBoolean(self.typesOnly),
745 self.filter,
746 BERSequenceOf(map(BEROctetString, self.attributes)),
747 ], tag=self.tag))
748
750 if self.tag==self.__class__.tag:
751 return self.__class__.__name__\
752 +("(baseObject=%s, scope=%s, derefAliases=%s, " \
753 +"sizeLimit=%s, timeLimit=%s, typesOnly=%s, " \
754 "filter=%s, attributes=%s)") \
755 %(repr(self.baseObject), self.scope,
756 self.derefAliases, self.sizeLimit,
757 self.timeLimit, self.typesOnly,
758 repr(self.filter), self.attributes)
759
760 else:
761 return self.__class__.__name__\
762 +("(baseObject=%s, scope=%s, derefAliases=%s, " \
763 +"sizeLimit=%s, timeLimit=%s, typesOnly=%s, " \
764 "filter=%s, attributes=%s, tag=%d)") \
765 %(repr(self.baseObject), self.scope,
766 self.derefAliases, self.sizeLimit,
767 self.timeLimit, self.typesOnly,
768 self.filter, self.attributes, self.tag)
769
770 -class LDAPSearchResultEntry(LDAPProtocolResponse, BERSequence):
771 tag=CLASS_APPLICATION|0x04
772
773 - def fromBER(klass, tag, content, berdecoder=None):
774 l = berDecodeMultiple(content, LDAPBERDecoderContext_Filter(fallback=berdecoder, inherit=berdecoder))
775
776 objectName=l[0].value
777 attributes=[]
778 for attr, li in l[1].data:
779 attributes.append((attr.value, map(lambda x: x.value, li)))
780 r = klass(objectName=objectName,
781 attributes=attributes,
782 tag=tag)
783 return r
784 fromBER = classmethod(fromBER)
785
786 - def __init__(self, objectName, attributes, tag=None):
787 LDAPProtocolResponse.__init__(self)
788 BERSequence.__init__(self, [], tag=tag)
789 assert objectName is not None
790 assert attributes is not None
791 self.objectName=objectName
792 self.attributes=attributes
793
795 return str(BERSequence([
796 BEROctetString(self.objectName),
797 BERSequence(map(lambda (attr,li):
798 BERSequence([BEROctetString(attr),
799 BERSet(map(BEROctetString,
800 li))]),
801 self.attributes)),
802 ], tag=self.tag))
803
804 - def __repr__(self):
805 if self.tag==self.__class__.tag:
806 return self.__class__.__name__\
807 +"(objectName=%s, attributes=%s"\
808 %(repr(str(self.objectName)),
809 repr(map(lambda (a,l):
810 (str(a),
811 map(lambda i, l=l: str(i), l)),
812 self.attributes)))
813 else:
814 return self.__class__.__name__\
815 +"(objectName=%s, attributes=%s, tag=%d"\
816 %(repr(str(self.objectName)),
817 repr(map(lambda (a,l):
818 (str(a),
819 map(lambda i, l=l: str(i), l)),
820 self.attributes)),
821 self.tag)
822
823
828
839
841 criticality = None
842 controlValue = None
843
844 - def fromBER(klass, tag, content, berdecoder=None):
845 l = berDecodeMultiple(content, berdecoder)
846
847 kw = {}
848 if l[1:]:
849 kw['criticality'] = l[1].value
850 if l[2:]:
851 kw['controlValue'] = l[2].value
852
853 assert not l[3:]
854
855 r = klass(controlType=l[0].value,
856 tag=tag,
857 **kw)
858 return r
859 fromBER = classmethod(fromBER)
860
861 - def __init__(self,
862 controlType, criticality=None, controlValue=None,
863 id=None, tag=None):
869
877
882
888
893
895 tag=CLASS_APPLICATION|0x06
896 object = None
897 modification = None
898
899 - def fromBER(klass, tag, content, berdecoder=None):
908 fromBER = classmethod(fromBER)
909
910 - def __init__(self, object=None, modification=None, tag=None):
911 """
912 Initialize the object
913
914 Example usage::
915
916 l = LDAPModifyRequest(
917 object='cn=foo,dc=example,dc=com',
918 modification=[
919
920 BERSequence([
921 BEREnumerated(0),
922 BERSequence([
923 LDAPAttributeDescription('attr1'),
924 BERSet([
925 LDAPString('value1'),
926 LDAPString('value2'),
927 ]),
928 ]),
929 ]),
930
931 BERSequence([
932 BEREnumerated(1),
933 BERSequence([
934 LDAPAttributeDescription('attr2'),
935 ]),
936 ]),
937
938 ])
939
940 But more likely you just want to say::
941
942 mod = delta.ModifyOp('cn=foo,dc=example,dc=com',
943 [delta.Add('attr1', ['value1', 'value2']),
944 delta.Delete('attr1', ['value1', 'value2'])])
945 l = mod.asLDAP()
946 """
947
948 LDAPProtocolRequest.__init__(self)
949 BERSequence.__init__(self, [], tag=tag)
950 self.object=object
951 self.modification=modification
952
958
966
967
970
972 tag = CLASS_APPLICATION|0x08
973
974 - def fromBER(klass, tag, content, berdecoder=None):
981 fromBER = classmethod(fromBER)
982
983 - def __init__(self, entry=None, attributes=None, tag=None):
984 """
985 Initialize the object
986
987 Example usage::
988
989 l=LDAPAddRequest(entry='cn=foo,dc=example,dc=com',
990 attributes=[(LDAPAttributeDescription("attrFoo"),
991 BERSet(value=(
992 LDAPAttributeValue("value1"),
993 LDAPAttributeValue("value2"),
994 ))),
995 (LDAPAttributeDescription("attrBar"),
996 BERSet(value=(
997 LDAPAttributeValue("value1"),
998 LDAPAttributeValue("value2"),
999 ))),
1000 ])
1001 """
1002
1003 LDAPProtocolRequest.__init__(self)
1004 BERSequence.__init__(self, [], tag=tag)
1005 self.entry=entry
1006 self.attributes=attributes
1007
1013
1015 if self.tag==self.__class__.tag:
1016 return self.__class__.__name__+"(entry=%s, attributes=%s)"\
1017 %(repr(self.entry), repr(self.attributes))
1018 else:
1019 return self.__class__.__name__+"(entry=%s, attributes=%s, tag=%d)" \
1020 %(repr(self.entry), repr(self.attributes), self.tag)
1021
1022
1023
1026
1028 tag = CLASS_APPLICATION|0x0a
1029
1030 - def __init__(self, value=None, entry=None, tag=None):
1040
1043
1045 if self.tag==self.__class__.tag:
1046 return self.__class__.__name__+"(entry=%s)" \
1047 %repr(self.value)
1048 else:
1049 return self.__class__.__name__ \
1050 +"(entry=%s, tag=%d)" \
1051 %(repr(self.value), self.tag)
1052
1053
1057
1058
1063
1068
1070 tag=CLASS_APPLICATION|12
1071
1072 entry=None
1073 newrdn=None
1074 deleteoldrdn=None
1075 newSuperior=None
1076
1077 - def fromBER(klass, tag, content, berdecoder=None):
1092 fromBER = classmethod(fromBER)
1093
1094 - def __init__(self, entry, newrdn, deleteoldrdn, newSuperior=None,
1095 tag=None):
1115
1125
1127 l = [
1128 "entry=%s" % repr(self.entry),
1129 "newrdn=%s" % repr(self.newrdn),
1130 "deleteoldrdn=%s" % repr(self.deleteoldrdn),
1131 ]
1132 if self.newSuperior is not None:
1133 l.append("newSuperior=%s" % repr(self.newSuperior))
1134 if self.tag!=self.__class__.tag:
1135 l.append("tag=%d" % self.tag)
1136 return self.__class__.__name__ + "(" + ', '.join(l) + ")"
1137
1140
1141
1142
1143
1170
1173
1176
1179
1185
1224
1231
1243
1245 oid = '1.3.6.1.4.1.4203.1.11.1'
1246
1247 - def __init__(self, requestName=None,
1248 userIdentity=None, oldPasswd=None, newPasswd=None,
1249 tag=None):
1268
1270 l=[]
1271
1272 if self.tag!=self.__class__.tag:
1273 l.append('tag=%d' % self.tag)
1274 return self.__class__.__name__+'('+', '.join(l)+')'
1275
1281
1283 tag = CLASS_APPLICATION|0x18
1284
1285 responseName = None
1286 response = None
1287
1288 - def fromBER(klass, tag, content, berdecoder=None):
1305 fromBER = classmethod(fromBER)
1306
1307 - def __init__(self, resultCode=None, matchedDN=None, errorMessage=None,
1308 referral=None, serverSaslCreds=None,
1309 responseName=None, response=None,
1310 tag=None):
1319
1332
1334 """
1335 Request to start Transport Layer Security.
1336
1337 See RFC 2830 for details.
1338 """
1339 oid = '1.3.6.1.4.1.1466.20037'
1340
1341 - def __init__(self, requestName=None, tag=None):
1351
1353 l=[]
1354 if self.tag!=self.__class__.tag:
1355 l.append('tag=%d' % self.tag)
1356 return self.__class__.__name__+'('+', '.join(l)+')'
1357
1358 -class LDAPBERDecoderContext(BERDecoderContext):
1359 Identities = {
1360 LDAPBindResponse.tag: LDAPBindResponse,
1361 LDAPBindRequest.tag: LDAPBindRequest,
1362 LDAPUnbindRequest.tag: LDAPUnbindRequest,
1363 LDAPSearchRequest.tag: LDAPSearchRequest,
1364 LDAPSearchResultEntry.tag: LDAPSearchResultEntry,
1365 LDAPSearchResultDone.tag: LDAPSearchResultDone,
1366 LDAPReferral.tag: LDAPReferral,
1367 LDAPModifyRequest.tag: LDAPModifyRequest,
1368 LDAPModifyResponse.tag: LDAPModifyResponse,
1369 LDAPAddRequest.tag: LDAPAddRequest,
1370 LDAPAddResponse.tag: LDAPAddResponse,
1371 LDAPDelRequest.tag: LDAPDelRequest,
1372 LDAPDelResponse.tag: LDAPDelResponse,
1373 LDAPExtendedRequest.tag: LDAPExtendedRequest,
1374 LDAPExtendedResponse.tag: LDAPExtendedResponse,
1375 LDAPModifyDNRequest.tag: LDAPModifyDNRequest,
1376 LDAPModifyDNResponse.tag: LDAPModifyDNResponse,
1377 LDAPAbandonRequest.tag: LDAPAbandonRequest,
1378 }
1379