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 BERBoolean, BERDecoderContext, BEREnumerated, BERInteger, BERNull,
22 BEROctetString, BERSequence, BERSequenceOf, BERSet, BERStructured,
23
24 CLASS_APPLICATION, CLASS_CONTEXT,
25
26 berDecodeMultiple, berDecodeObject, int2berlen,
27 )
28
29 next_ldap_message_id=1
35
37 s = s.replace('\\', r'\5c')
38 s = s.replace('*', r'\2a')
39 s = s.replace('(', r'\28')
40 s = s.replace(')', r'\29')
41 s = s.replace('\0', r'\00')
42 return s
43
46
49
52
54 id = None
55 value = None
56
57 - def fromBER(klass, tag, content, berdecoder=None):
79 fromBER = classmethod(fromBER)
80
81 - def __init__(self, value=None, controls=None, id=None, tag=None):
89
95
97 l=[]
98 l.append('id=%r' % self.id)
99 l.append('value=%r' % self.value)
100 if self.tag!=self.__class__.tag:
101 l.append('tag=%d' % self.tag)
102 return self.__class__.__name__+'('+', '.join(l)+')'
103
107
109 raise NotImplementedError
110
114
117
123
125 tag=CLASS_APPLICATION|0x00
126
127 - def fromBER(klass, tag, content, berdecoder=None):
146 fromBER = classmethod(fromBER)
147
148 - def __init__(self, version=None, dn=None, auth=None, tag=None, sasl=False):
149 """Constructor for LDAP Bind Request
150
151 For sasl=False, pass a string password for 'auth'
152 For sasl=True, pass a tuple of (mechanism, credentials) for 'auth'"""
153
154 LDAPProtocolRequest.__init__(self)
155 BERSequence.__init__(self, [], tag=tag)
156 self.version=version
157 if self.version is None:
158 self.version=3
159 self.dn=dn
160 if self.dn is None:
161 self.dn=''
162 self.auth=auth
163 if self.auth is None:
164 self.auth=''
165 assert(not sasl)
166 self.sasl=sasl
167
178
180 l=[]
181 l.append('version=%d' % self.version)
182 l.append('dn=%s' % repr(self.dn))
183 l.append('auth=%s' % repr(self.auth))
184 if self.tag!=self.__class__.tag:
185 l.append('tag=%d' % self.tag)
186 l.append('sasl=%s' % repr(self.sasl))
187 return self.__class__.__name__+'('+', '.join(l)+')'
188
191
192
193
210
211
212 -class LDAPResult(LDAPProtocolResponse, BERSequence):
213 - def fromBER(klass, tag, content, berdecoder=None):
230 fromBER = classmethod(fromBER)
231
232 - def __init__(self, resultCode=None, matchedDN=None, errorMessage=None, referral=None, serverSaslCreds=None, tag=None):
245
254
267
272
277
324
335
338
340 - def fromBER(klass, tag, content, berdecoder=None):
348 fromBER = classmethod(fromBER)
349
350 - def __init__(self, attributeDesc=None, assertionValue=None, tag=None):
351 BERSequence.__init__(self, value=[], tag=tag)
352 assert attributeDesc is not None
353 self.attributeDesc=attributeDesc
354 self.assertionValue=assertionValue
355
357 return str(BERSequence([self.attributeDesc,
358 self.assertionValue],
359 tag=self.tag))
360
362 if self.tag==self.__class__.tag:
363 return self.__class__.__name__+"(attributeDesc=%s, assertionValue=%s)"\
364 %(repr(self.attributeDesc), repr(self.assertionValue))
365 else:
366 return self.__class__.__name__+"(attributeDesc=%s, assertionValue=%s, tag=%d)"\
367 %(repr(self.attributeDesc), repr(self.assertionValue), self.tag)
368
369
373
380
386
392
426
433
439
440
446
452
459
461 tag = CLASS_CONTEXT|0x04
462
463 - def fromBER(klass, tag, content, berdecoder=None):
472 fromBER = classmethod(fromBER)
473
474 - def __init__(self, type=None, substrings=None, tag=None):
480
485
487 if self.tag==self.__class__.tag:
488 return self.__class__.__name__\
489 +"(type=%s, substrings=%s)"\
490 %(repr(self.type), repr(self.substrings))
491 else:
492 return self.__class__.__name__\
493 +"(type=%s, substrings=%s, tag=%d)"\
494 %(repr(self.type), repr(self.substrings), self.tag)
495
497 initial=None
498 final=None
499 any=[]
500
501 for s in self.substrings:
502 assert s is not None
503 if isinstance(s, LDAPFilter_substrings_initial):
504 assert initial is None
505 assert not any
506 assert final is None
507 initial=s.asText()
508 elif isinstance(s, LDAPFilter_substrings_final):
509 assert final is None
510 final=s.asText()
511 elif isinstance(s, LDAPFilter_substrings_any):
512 assert final is None
513 any.append(s.asText())
514 else:
515 raise 'TODO'
516
517 if initial is None:
518 initial=''
519 if final is None:
520 final=''
521
522
523 return '('+self.type+'=' \
524 +'*'.join([initial]+any+[final])+')'
525
532
539
545
553
556
559
563
567
571
575
583
585 matchingRule=None
586 type=None
587 matchValue=None
588 dnAttributes=None
589
590 - def fromBER(klass, tag, content, berdecoder=None):
591 l = berDecodeMultiple(content, LDAPBERDecoderContext_MatchingRuleAssertion(fallback=berdecoder, inherit=berdecoder))
592
593 assert 1<=len(l)<=4
594 if isinstance(l[0], LDAPMatchingRuleAssertion_matchingRule):
595 matchingRule=l[0]
596 del l[0]
597 if len(l)>1 \
598 and isinstance(l[0], LDAPMatchingRuleAssertion_type):
599 type=l[0]
600 del l[0]
601 if len(l)>1 \
602 and isinstance(l[0], LDAPMatchingRuleAssertion_matchValue):
603 matchValue=l[0]
604 del l[0]
605 if len(l)>1 \
606 and isinstance(l[0], LDAPMatchingRuleAssertion_dnAttributes):
607 dnAttributes=l[0]
608 del l[0]
609 assert matchValue
610 if not dnAttributes:
611 dnAttributes=None
612
613 assert 8<=len(l)<=8
614 r = klass(matchingRule=matchingRule,
615 type=type,
616 matchValue=matchValue,
617 dnAttributes=dnAttributes,
618 tag=tag)
619 return r
620 fromBER = classmethod(fromBER)
621
622 - def __init__(self, matchingRule=None, type=None,
623 matchValue=None, dnAttributes=None,
624 tag=None):
633
637
639 l=[]
640 l.append('matchingRule=%s' % repr(self.matchingRule))
641 l.append('type=%s' % repr(self.type))
642 l.append('matchValue=%s' % repr(self.matchValue))
643 l.append('dnAttributes=%s' % repr(self.dnAttributes))
644 if self.tag!=self.__class__.tag:
645 l.append('tag=%d' % self.tag)
646 return self.__class__.__name__+'('+', '.join(l)+')'
647
651
652
653 -class LDAPBERDecoderContext_Filter(BERDecoderContext):
654 Identities = {
655 LDAPFilter_and.tag: LDAPFilter_and,
656 LDAPFilter_or.tag: LDAPFilter_or,
657 LDAPFilter_not.tag: LDAPFilter_not,
658 LDAPFilter_equalityMatch.tag: LDAPFilter_equalityMatch,
659 LDAPFilter_substrings.tag: LDAPFilter_substrings,
660 LDAPFilter_greaterOrEqual.tag: LDAPFilter_greaterOrEqual,
661 LDAPFilter_lessOrEqual.tag: LDAPFilter_lessOrEqual,
662 LDAPFilter_present.tag: LDAPFilter_present,
663 LDAPFilter_approxMatch.tag: LDAPFilter_approxMatch,
664 LDAPFilter_extensibleMatch.tag: LDAPFilter_extensibleMatch,
665 }
666
667 LDAP_SCOPE_baseObject=0
668 LDAP_SCOPE_singleLevel=1
669 LDAP_SCOPE_wholeSubtree=2
670
671 LDAP_DEREF_neverDerefAliases=0
672 LDAP_DEREF_derefInSearching=1
673 LDAP_DEREF_derefFindingBaseObj=2
674 LDAP_DEREF_derefAlways=3
675
676 LDAPFilterMatchAll = LDAPFilter_present('objectClass')
677
679 tag=CLASS_APPLICATION|0x03
680
681 baseObject=''
682 scope=LDAP_SCOPE_wholeSubtree
683 derefAliases=LDAP_DEREF_neverDerefAliases
684 sizeLimit=0
685 timeLimit=0
686 typesOnly=0
687 filter=LDAPFilterMatchAll
688 attributes=[]
689
690
691
692 - def fromBER(klass, tag, content, berdecoder=None):
693 l = berDecodeMultiple(content, LDAPBERDecoderContext_Filter(fallback=berdecoder, inherit=berdecoder))
694
695 assert 8<=len(l)<=8
696 r = klass(baseObject=l[0].value,
697 scope=l[1].value,
698 derefAliases=l[2].value,
699 sizeLimit=l[3].value,
700 timeLimit=l[4].value,
701 typesOnly=l[5].value,
702 filter=l[6],
703 attributes=[x.value for x in l[7]],
704 tag=tag)
705 return r
706 fromBER = classmethod(fromBER)
707
708 - def __init__(self,
709 baseObject=None,
710 scope=None,
711 derefAliases=None,
712 sizeLimit=None,
713 timeLimit=None,
714 typesOnly=None,
715 filter=None,
716 attributes=None,
717 tag=None):
737
739 return str(BERSequence([
740 BEROctetString(self.baseObject),
741 BEREnumerated(self.scope),
742 BEREnumerated(self.derefAliases),
743 BERInteger(self.sizeLimit),
744 BERInteger(self.timeLimit),
745 BERBoolean(self.typesOnly),
746 self.filter,
747 BERSequenceOf(map(BEROctetString, self.attributes)),
748 ], tag=self.tag))
749
751 if self.tag==self.__class__.tag:
752 return self.__class__.__name__\
753 +("(baseObject=%s, scope=%s, derefAliases=%s, " \
754 +"sizeLimit=%s, timeLimit=%s, typesOnly=%s, " \
755 "filter=%s, attributes=%s)") \
756 %(repr(self.baseObject), self.scope,
757 self.derefAliases, self.sizeLimit,
758 self.timeLimit, self.typesOnly,
759 repr(self.filter), self.attributes)
760
761 else:
762 return self.__class__.__name__\
763 +("(baseObject=%s, scope=%s, derefAliases=%s, " \
764 +"sizeLimit=%s, timeLimit=%s, typesOnly=%s, " \
765 "filter=%s, attributes=%s, tag=%d)") \
766 %(repr(self.baseObject), self.scope,
767 self.derefAliases, self.sizeLimit,
768 self.timeLimit, self.typesOnly,
769 self.filter, self.attributes, self.tag)
770
771 -class LDAPSearchResultEntry(LDAPProtocolResponse, BERSequence):
772 tag=CLASS_APPLICATION|0x04
773
774 - def fromBER(klass, tag, content, berdecoder=None):
775 l = berDecodeMultiple(content, LDAPBERDecoderContext_Filter(fallback=berdecoder, inherit=berdecoder))
776
777 objectName=l[0].value
778 attributes=[]
779 for attr, li in l[1].data:
780 attributes.append((attr.value, map(lambda x: x.value, li)))
781 r = klass(objectName=objectName,
782 attributes=attributes,
783 tag=tag)
784 return r
785 fromBER = classmethod(fromBER)
786
787 - def __init__(self, objectName, attributes, tag=None):
788 LDAPProtocolResponse.__init__(self)
789 BERSequence.__init__(self, [], tag=tag)
790 assert objectName is not None
791 assert attributes is not None
792 self.objectName=objectName
793 self.attributes=attributes
794
796 return str(BERSequence([
797 BEROctetString(self.objectName),
798 BERSequence(map(lambda (attr,li):
799 BERSequence([BEROctetString(attr),
800 BERSet(map(BEROctetString,
801 li))]),
802 self.attributes)),
803 ], tag=self.tag))
804
805 - def __repr__(self):
806 if self.tag==self.__class__.tag:
807 return self.__class__.__name__\
808 +"(objectName=%s, attributes=%s"\
809 %(repr(str(self.objectName)),
810 repr(map(lambda (a,l):
811 (str(a),
812 map(lambda i, l=l: str(i), l)),
813 self.attributes)))
814 else:
815 return self.__class__.__name__\
816 +"(objectName=%s, attributes=%s, tag=%d"\
817 %(repr(str(self.objectName)),
818 repr(map(lambda (a,l):
819 (str(a),
820 map(lambda i, l=l: str(i), l)),
821 self.attributes)),
822 self.tag)
823
824
829
840
842 criticality = None
843 controlValue = None
844
845 - def fromBER(klass, tag, content, berdecoder=None):
846 l = berDecodeMultiple(content, berdecoder)
847
848 kw = {}
849 if l[1:]:
850 kw['criticality'] = l[1].value
851 if l[2:]:
852 kw['controlValue'] = l[2].value
853
854 assert not l[3:]
855
856 r = klass(controlType=l[0].value,
857 tag=tag,
858 **kw)
859 return r
860 fromBER = classmethod(fromBER)
861
862 - def __init__(self,
863 controlType, criticality=None, controlValue=None,
864 id=None, tag=None):
870
878
883
889
894
896 tag=CLASS_APPLICATION|0x06
897 object = None
898 modification = None
899
900 - def fromBER(klass, tag, content, berdecoder=None):
909 fromBER = classmethod(fromBER)
910
911 - def __init__(self, object=None, modification=None, tag=None):
912 """
913 Initialize the object
914
915 Example usage::
916
917 l = LDAPModifyRequest(
918 object='cn=foo,dc=example,dc=com',
919 modification=[
920
921 BERSequence([
922 BEREnumerated(0),
923 BERSequence([
924 LDAPAttributeDescription('attr1'),
925 BERSet([
926 LDAPString('value1'),
927 LDAPString('value2'),
928 ]),
929 ]),
930 ]),
931
932 BERSequence([
933 BEREnumerated(1),
934 BERSequence([
935 LDAPAttributeDescription('attr2'),
936 ]),
937 ]),
938
939 ])
940
941 But more likely you just want to say::
942
943 mod = delta.ModifyOp('cn=foo,dc=example,dc=com',
944 [delta.Add('attr1', ['value1', 'value2']),
945 delta.Delete('attr1', ['value1', 'value2'])])
946 l = mod.asLDAP()
947 """
948
949 LDAPProtocolRequest.__init__(self)
950 BERSequence.__init__(self, [], tag=tag)
951 self.object=object
952 self.modification=modification
953
959
967
968
971
973 tag = CLASS_APPLICATION|0x08
974
975 - def fromBER(klass, tag, content, berdecoder=None):
982 fromBER = classmethod(fromBER)
983
984 - def __init__(self, entry=None, attributes=None, tag=None):
985 """
986 Initialize the object
987
988 Example usage::
989
990 l=LDAPAddRequest(entry='cn=foo,dc=example,dc=com',
991 attributes=[(LDAPAttributeDescription("attrFoo"),
992 BERSet(value=(
993 LDAPAttributeValue("value1"),
994 LDAPAttributeValue("value2"),
995 ))),
996 (LDAPAttributeDescription("attrBar"),
997 BERSet(value=(
998 LDAPAttributeValue("value1"),
999 LDAPAttributeValue("value2"),
1000 ))),
1001 ])
1002 """
1003
1004 LDAPProtocolRequest.__init__(self)
1005 BERSequence.__init__(self, [], tag=tag)
1006 self.entry=entry
1007 self.attributes=attributes
1008
1014
1016 if self.tag==self.__class__.tag:
1017 return self.__class__.__name__+"(entry=%s, attributes=%s)"\
1018 %(repr(self.entry), repr(self.attributes))
1019 else:
1020 return self.__class__.__name__+"(entry=%s, attributes=%s, tag=%d)" \
1021 %(repr(self.entry), repr(self.attributes), self.tag)
1022
1023
1024
1027
1029 tag = CLASS_APPLICATION|0x0a
1030
1031 - def __init__(self, value=None, entry=None, tag=None):
1041
1044
1046 if self.tag==self.__class__.tag:
1047 return self.__class__.__name__+"(entry=%s)" \
1048 %repr(self.value)
1049 else:
1050 return self.__class__.__name__ \
1051 +"(entry=%s, tag=%d)" \
1052 %(repr(self.value), self.tag)
1053
1054
1058
1059
1064
1069
1071 tag=CLASS_APPLICATION|12
1072
1073 entry=None
1074 newrdn=None
1075 deleteoldrdn=None
1076 newSuperior=None
1077
1078 - def fromBER(klass, tag, content, berdecoder=None):
1093 fromBER = classmethod(fromBER)
1094
1095 - def __init__(self, entry, newrdn, deleteoldrdn, newSuperior=None,
1096 tag=None):
1116
1126
1128 l = [
1129 "entry=%s" % repr(self.entry),
1130 "newrdn=%s" % repr(self.newrdn),
1131 "deleteoldrdn=%s" % repr(self.deleteoldrdn),
1132 ]
1133 if self.newSuperior is not None:
1134 l.append("newSuperior=%s" % repr(self.newSuperior))
1135 if self.tag!=self.__class__.tag:
1136 l.append("tag=%d" % self.tag)
1137 return self.__class__.__name__ + "(" + ', '.join(l) + ")"
1138
1141
1142
1143
1144
1149
1176
1179
1182
1185
1191
1230
1237
1249
1251 oid = '1.3.6.1.4.1.4203.1.11.1'
1252
1253 - def __init__(self, requestName=None,
1254 userIdentity=None, oldPasswd=None, newPasswd=None,
1255 tag=None):
1274
1276 l=[]
1277
1278 if self.tag!=self.__class__.tag:
1279 l.append('tag=%d' % self.tag)
1280 return self.__class__.__name__+'('+', '.join(l)+')'
1281
1287
1289 tag = CLASS_APPLICATION|0x18
1290
1291 responseName = None
1292 response = None
1293
1294 - def fromBER(klass, tag, content, berdecoder=None):
1311 fromBER = classmethod(fromBER)
1312
1313 - def __init__(self, resultCode=None, matchedDN=None, errorMessage=None,
1314 referral=None, serverSaslCreds=None,
1315 responseName=None, response=None,
1316 tag=None):
1325
1338
1340 """
1341 Request to start Transport Layer Security.
1342
1343 See RFC 2830 for details.
1344 """
1345 oid = '1.3.6.1.4.1.1466.20037'
1346
1347 - def __init__(self, requestName=None, tag=None):
1357
1359 l=[]
1360 if self.tag!=self.__class__.tag:
1361 l.append('tag=%d' % self.tag)
1362 return self.__class__.__name__+'('+', '.join(l)+')'
1363
1364 -class LDAPBERDecoderContext(BERDecoderContext):
1365 Identities = {
1366 LDAPBindResponse.tag: LDAPBindResponse,
1367 LDAPBindRequest.tag: LDAPBindRequest,
1368 LDAPUnbindRequest.tag: LDAPUnbindRequest,
1369 LDAPSearchRequest.tag: LDAPSearchRequest,
1370 LDAPSearchResultEntry.tag: LDAPSearchResultEntry,
1371 LDAPSearchResultDone.tag: LDAPSearchResultDone,
1372 LDAPReferral.tag: LDAPReferral,
1373 LDAPModifyRequest.tag: LDAPModifyRequest,
1374 LDAPModifyResponse.tag: LDAPModifyResponse,
1375 LDAPAddRequest.tag: LDAPAddRequest,
1376 LDAPAddResponse.tag: LDAPAddResponse,
1377 LDAPDelRequest.tag: LDAPDelRequest,
1378 LDAPDelResponse.tag: LDAPDelResponse,
1379 LDAPExtendedRequest.tag: LDAPExtendedRequest,
1380 LDAPExtendedResponse.tag: LDAPExtendedResponse,
1381 LDAPModifyDNRequest.tag: LDAPModifyDNRequest,
1382 LDAPModifyDNResponse.tag: LDAPModifyDNResponse,
1383 LDAPAbandonRequest.tag: LDAPAbandonRequest,
1384 }
1385