Package ldaptor :: Package protocols :: Module pureldap
[hide private]
[frames] | no frames]

Source Code for Module ldaptor.protocols.pureldap

   1  # Twisted, the Framework of Your Internet 
   2  # Copyright (C) 2001 Matthew W. Lefkowitz 
   3  # 
   4  # This library is free software; you can redistribute it and/or 
   5  # modify it under the terms of version 2.1 of the GNU Lesser General Public 
   6  # License as published by the Free Software Foundation. 
   7  # 
   8  # This library is distributed in the hope that it will be useful, 
   9  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
  10  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
  11  # Lesser General Public License for more details. 
  12  # 
  13  # You should have received a copy of the GNU Lesser General Public 
  14  # License along with this library; if not, write to the Free Software 
  15  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
  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 
30 -def alloc_ldap_message_id():
31 global next_ldap_message_id 32 r=next_ldap_message_id 33 next_ldap_message_id=next_ldap_message_id+1 34 return r
35
36 -def escape(s):
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
44 -class LDAPString(BEROctetString):
45 pass
46
47 -class LDAPAttributeValue(BEROctetString):
48 pass
49
50 -class LDAPMessage(BERSequence):
51 id = None 52 value = None 53
54 - def fromBER(klass, tag, content, berdecoder=None):
55 l = berDecodeMultiple(content, berdecoder) 56 57 id_=l[0].value 58 value=l[1] 59 if l[2:]: 60 controls = [] 61 for c in l[2]: 62 controls.append(( 63 c.controlType, 64 c.criticality, 65 c.controlValue, 66 )) 67 else: 68 controls = None 69 assert not l[3:] 70 71 r = klass(id=id_, 72 value=value, 73 controls=controls, 74 tag=tag) 75 return r
76 fromBER = classmethod(fromBER) 77
78 - def __init__(self, value=None, controls=None, id=None, tag=None):
79 BERSequence.__init__(self, value=[], tag=tag) 80 assert value is not None 81 self.id=id 82 if self.id is None: 83 self.id=alloc_ldap_message_id() 84 self.value=value 85 self.controls = controls
86
87 - def __str__(self):
88 l = [BERInteger(self.id), self.value] 89 if self.controls is not None: 90 l.append(LDAPControls([LDAPControl(*a) for a in self.controls])) 91 return str(BERSequence(l))
92
93 - def __repr__(self):
94 l=[] 95 l.append('id=%r' % self.id) 96 l.append('value=%r' % self.value) 97 if self.tag!=self.__class__.tag: 98 l.append('tag=%d' % self.tag) 99 return self.__class__.__name__+'('+', '.join(l)+')'
100
101 -class LDAPProtocolOp:
102 - def __init__(self):
103 pass
104
105 - def __str__(self):
106 raise NotImplementedError
107
108 -class LDAPProtocolRequest(LDAPProtocolOp):
109 needs_answer=1 110 pass
111
112 -class LDAPProtocolResponse(LDAPProtocolOp):
113 pass
114
115 -class LDAPBERDecoderContext_LDAPBindRequest(BERDecoderContext):
116 Identities = { 117 CLASS_CONTEXT|0x00: BEROctetString, 118 }
119
120 -class LDAPBindRequest(LDAPProtocolRequest, BERSequence):
121 tag=CLASS_APPLICATION|0x00 122
123 - def fromBER(klass, tag, content, berdecoder=None):
124 l = berDecodeMultiple(content, 125 LDAPBERDecoderContext_LDAPBindRequest( 126 fallback=berdecoder)) 127 128 r = klass(version=l[0].value, 129 dn=l[1].value, 130 auth=l[2].value, 131 tag=tag) 132 return r
133 fromBER = classmethod(fromBER) 134
135 - def __init__(self, version=None, dn=None, auth=None, tag=None):
136 LDAPProtocolRequest.__init__(self) 137 BERSequence.__init__(self, [], tag=tag) 138 self.version=version 139 if self.version is None: 140 self.version=3 141 self.dn=dn 142 if self.dn is None: 143 self.dn='' 144 self.auth=auth 145 if self.auth is None: 146 self.auth=''
147
148 - def __str__(self):
149 return str(BERSequence([ 150 BERInteger(self.version), 151 BEROctetString(self.dn), 152 BEROctetString(self.auth, tag=CLASS_CONTEXT|0), 153 ], tag=self.tag))
154
155 - def __repr__(self):
156 l=[] 157 l.append('version=%d' % self.version) 158 l.append('dn=%s' % repr(self.dn)) 159 l.append('auth=%s' % repr(self.auth)) 160 if self.tag!=self.__class__.tag: 161 l.append('tag=%d' % self.tag) 162 return self.__class__.__name__+'('+', '.join(l)+')'
163 164 165
166 -class LDAPReferral(BERSequence):
167 tag = CLASS_CONTEXT | 0x03
168 169 170 # This is currently just a stub and implements no real functionality.
171 -class LDAPSearchResultReference(LDAPProtocolResponse):
172 tag = CLASS_APPLICATION | 0x13 173
174 - def __init__(self):
176
177 - def fromBER(cls, tag, content, berdecoder=None):
178 r = cls() 179 return r
180 fromBER = classmethod(fromBER) 181
182 - def __str__(self):
183 return object.__str__(self)
184
185 - def __repr__(self):
186 return object.__repr__(self)
187 188
189 -class LDAPResult(LDAPProtocolResponse, BERSequence):
190 - def fromBER(klass, tag, content, berdecoder=None):
191 l = berDecodeMultiple(content, LDAPBERDecoderContext_LDAPBindRequest( 192 fallback=berdecoder)) 193 194 assert 3<=len(l)<=4 195 196 referral = None 197 #if (l[3:] and isinstance(l[3], LDAPReferral)): 198 #TODO support referrals 199 #self.referral=self.data[0] 200 201 r = klass(resultCode=l[0].value, 202 matchedDN=l[1].value, 203 errorMessage=l[2].value, 204 referral=referral, 205 tag=tag) 206 return r
207 fromBER = classmethod(fromBER) 208
209 - def __init__(self, resultCode=None, matchedDN=None, errorMessage=None, referral=None, serverSaslCreds=None, tag=None):
210 LDAPProtocolResponse.__init__(self) 211 BERSequence.__init__(self, value=[], tag=tag) 212 assert resultCode is not None 213 self.resultCode=resultCode 214 if matchedDN is None: 215 matchedDN='' 216 self.matchedDN=matchedDN 217 if errorMessage is None: 218 errorMessage='' 219 self.errorMessage=errorMessage 220 self.referral=referral 221 self.serverSaslCreds=serverSaslCreds
222
223 - def __str__(self):
224 assert self.referral is None #TODO 225 return str(BERSequence([ 226 BEREnumerated(self.resultCode), 227 BEROctetString(self.matchedDN), 228 BEROctetString(self.errorMessage), 229 #TODO referral [3] Referral OPTIONAL 230 ], tag=self.tag))
231
232 - def __repr__(self):
233 l=[] 234 l.append('resultCode=%r' % self.resultCode) 235 if self.matchedDN: 236 l.append('matchedDN=%r' % str(self.matchedDN)) 237 if self.errorMessage: 238 l.append('errorMessage=%r' % str(self.errorMessage)) 239 if self.referral: 240 l.append('referral=%r' % self.referral) 241 if self.tag!=self.__class__.tag: 242 l.append('tag=%d' % self.tag) 243 return self.__class__.__name__+'('+', '.join(l)+')'
244
245 -class LDAPBindResponse_serverSaslCreds(BERSequence):
246 tag = CLASS_CONTEXT|0x03 247 248 pass
249
250 -class LDAPBERDecoderContext_BindResponse(BERDecoderContext):
251 Identities = { 252 LDAPBindResponse_serverSaslCreds.tag: LDAPBindResponse_serverSaslCreds, 253 }
254
255 -class LDAPBindResponse(LDAPResult):
256 tag=CLASS_APPLICATION|0x01 257 258 resultCode = None 259 matchedDN = None 260 errorMessage = None 261 referral = None 262 serverSaslCreds = None 263
264 - def fromBER(klass, tag, content, berdecoder=None):
265 l = berDecodeMultiple(content, LDAPBERDecoderContext_BindResponse( 266 fallback=berdecoder)) 267 268 assert 3<=len(l)<=4 269 270 try: 271 if isinstance(l[0], LDAPBindResponse_serverSaslCreds): 272 serverSaslCreds=l[0] 273 del l[0] 274 else: 275 serverSaslCreds=None 276 except IndexError: 277 serverSaslCreds=None 278 279 referral = None 280 #if (l[3:] and isinstance(l[3], LDAPReferral)): 281 #TODO support referrals 282 #self.referral=self.data[0] 283 284 r = klass(resultCode=l[0].value, 285 matchedDN=l[1].value, 286 errorMessage=l[2].value, 287 referral=referral, 288 serverSaslCreds=serverSaslCreds, 289 tag=tag) 290 return r
291 fromBER = classmethod(fromBER) 292
293 - def __init__(self, resultCode=None, matchedDN=None, errorMessage=None, referral=None, serverSaslCreds=None, tag=None):
296
297 - def __str__(self):
298 assert self.serverSaslCreds is None #TODO 299 return LDAPResult.__str__(self)
300
301 - def __repr__(self):
302 assert self.serverSaslCreds is None #TODO 303 return LDAPResult.__repr__(self)
304
305 -class LDAPUnbindRequest(LDAPProtocolRequest, BERNull):
306 tag=CLASS_APPLICATION|0x02 307 needs_answer=0 308
309 - def __init__(self, *args, **kwargs):
310 LDAPProtocolRequest.__init__(self) 311 BERNull.__init__(self, *args, **kwargs)
312
313 - def __str__(self):
314 return BERNull.__str__(self)
315
316 -class LDAPAttributeDescription(BEROctetString):
317 pass
318
319 -class LDAPAttributeValueAssertion(BERSequence):
320 - def fromBER(klass, tag, content, berdecoder=None):
321 l = berDecodeMultiple(content, berdecoder) 322 assert len(l) == 2 323 324 r = klass(attributeDesc=l[0], 325 assertionValue=l[1], 326 tag=tag) 327 return r
328 fromBER = classmethod(fromBER) 329
330 - def __init__(self, attributeDesc=None, assertionValue=None, tag=None):
331 BERSequence.__init__(self, value=[], tag=tag) 332 assert attributeDesc is not None 333 self.attributeDesc=attributeDesc 334 self.assertionValue=assertionValue
335
336 - def __str__(self):
337 return str(BERSequence([self.attributeDesc, 338 self.assertionValue], 339 tag=self.tag))
340
341 - def __repr__(self):
342 if self.tag==self.__class__.tag: 343 return self.__class__.__name__+"(attributeDesc=%s, assertionValue=%s)"\ 344 %(repr(self.attributeDesc), repr(self.assertionValue)) 345 else: 346 return self.__class__.__name__+"(attributeDesc=%s, assertionValue=%s, tag=%d)"\ 347 %(repr(self.attributeDesc), repr(self.assertionValue), self.tag)
348 349
350 -class LDAPFilter(BERStructured):
351 - def __init__(self, tag=None):
353
354 -class LDAPFilterSet(BERSet):
355 - def fromBER(klass, tag, content, berdecoder=None):
356 l = berDecodeMultiple(content, LDAPBERDecoderContext_Filter(fallback=berdecoder)) 357 r = klass(l, tag=tag) 358 return r
359 fromBER = classmethod(fromBER)
360
361 -class LDAPFilter_and(LDAPFilterSet):
362 tag = CLASS_CONTEXT|0x00 363
364 - def asText(self):
365 return '(&'+''.join([x.asText() for x in self])+')'
366
367 -class LDAPFilter_or(LDAPFilterSet):
368 tag = CLASS_CONTEXT|0x01 369
370 - def asText(self):
371 return '(|'+''.join([x.asText() for x in self])+')'
372
373 -class LDAPFilter_not(LDAPFilter):
374 tag = CLASS_CONTEXT|0x02 375
376 - def fromBER(klass, tag, content, berdecoder=None):
377 value, bytes = berDecodeObject(LDAPBERDecoderContext_Filter(fallback=berdecoder, inherit=berdecoder), content) 378 assert bytes == len(content) 379 380 r = klass(value=value, 381 tag=tag) 382 return r
383 fromBER = classmethod(fromBER) 384
385 - def __init__(self, value, tag=tag):
386 LDAPFilter.__init__(self, tag=tag) 387 assert value is not None 388 self.value=value
389
390 - def __repr__(self):
391 if self.tag==self.__class__.tag: 392 return self.__class__.__name__\ 393 +"(value=%s)"\ 394 %repr(self.value) 395 else: 396 return self.__class__.__name__\ 397 +"(value=%s, tag=%d)"\ 398 %(repr(self.value), self.tag)
399
400 - def __str__(self):
401 r=str(self.value) 402 return chr(self.identification())+int2berlen(len(r))+r
403
404 - def asText(self):
405 return '(!'+self.value.asText()+')'
406
407 -class LDAPFilter_equalityMatch(LDAPAttributeValueAssertion):
408 tag = CLASS_CONTEXT|0x03 409
410 - def asText(self):
411 return '('+self.attributeDesc.value+'=' \ 412 +escape(self.assertionValue.value)+')'
413
414 -class LDAPFilter_substrings_initial(LDAPString):
415 tag = CLASS_CONTEXT|0x00 416
417 - def asText(self):
418 return escape(self.value)
419 420
421 -class LDAPFilter_substrings_any(LDAPString):
422 tag = CLASS_CONTEXT|0x01 423
424 - def asText(self):
425 return escape(self.value)
426
427 -class LDAPFilter_substrings_final(LDAPString):
428 tag = CLASS_CONTEXT|0x02 429
430 - def asText(self):
431 return escape(self.value)
432
433 -class LDAPBERDecoderContext_Filter_substrings(BERDecoderContext):
434 Identities = { 435 LDAPFilter_substrings_initial.tag: LDAPFilter_substrings_initial, 436 LDAPFilter_substrings_any.tag: LDAPFilter_substrings_any, 437 LDAPFilter_substrings_final.tag: LDAPFilter_substrings_final, 438 }
439
440 -class LDAPFilter_substrings(BERSequence):
441 tag = CLASS_CONTEXT|0x04 442
443 - def fromBER(klass, tag, content, berdecoder=None):
444 l = berDecodeMultiple(content, LDAPBERDecoderContext_Filter_substrings(fallback=berdecoder)) 445 assert len(l) == 2 446 assert len(l[1])>=1 447 448 r = klass(type=l[0].value, 449 substrings=list(l[1]), 450 tag=tag) 451 return r
452 fromBER = classmethod(fromBER) 453
454 - def __init__(self, type=None, substrings=None, tag=None):
455 BERSequence.__init__(self, value=[], tag=tag) 456 assert type is not None 457 assert substrings is not None 458 self.type=type 459 self.substrings=substrings
460
461 - def __str__(self):
462 return str(BERSequence([ 463 LDAPString(self.type), 464 BERSequence(self.substrings)], tag=self.tag))
465
466 - def __repr__(self):
467 if self.tag==self.__class__.tag: 468 return self.__class__.__name__\ 469 +"(type=%s, substrings=%s)"\ 470 %(repr(self.type), repr(self.substrings)) 471 else: 472 return self.__class__.__name__\ 473 +"(type=%s, substrings=%s, tag=%d)"\ 474 %(repr(self.type), repr(self.substrings), self.tag)
475
476 - def asText(self):
477 initial=None 478 final=None 479 any=[] 480 481 for s in self.substrings: 482 assert s is not None 483 if isinstance(s, LDAPFilter_substrings_initial): 484 assert initial is None 485 assert not any 486 assert final is None 487 initial=s.asText() 488 elif isinstance(s, LDAPFilter_substrings_final): 489 assert final is None 490 final=s.asText() 491 elif isinstance(s, LDAPFilter_substrings_any): 492 assert final is None 493 any.append(s.asText()) 494 else: 495 raise 'TODO' 496 497 if initial is None: 498 initial='' 499 if final is None: 500 final='' 501 502 503 return '('+self.type+'=' \ 504 +'*'.join([initial]+any+[final])+')'
505
506 -class LDAPFilter_greaterOrEqual(LDAPAttributeValueAssertion):
507 tag = CLASS_CONTEXT|0x05 508
509 - def asText(self):
510 return '('+self.attributeDesc.value+'>=' \ 511 +escape(self.assertionValue.value)+')'
512
513 -class LDAPFilter_lessOrEqual(LDAPAttributeValueAssertion):
514 tag = CLASS_CONTEXT|0x06 515
516 - def asText(self):
517 return '('+self.attributeDesc.value+'<=' \ 518 +escape(self.assertionValue.value)+')'
519
520 -class LDAPFilter_present(LDAPAttributeDescription):
521 tag = CLASS_CONTEXT|0x07 522
523 - def asText(self):
524 return '(%s=*)' % self.value
525
526 -class LDAPFilter_approxMatch(LDAPAttributeValueAssertion):
527 tag = CLASS_CONTEXT|0x08 528 529
530 - def asText(self):
531 return '('+self.attributeDesc.value+'~=' \ 532 +escape(self.assertionValue.value)+')'
533
534 -class LDAPMatchingRuleId(LDAPString):
535 pass
536
537 -class LDAPAssertionValue(BEROctetString):
538 pass
539
540 -class LDAPMatchingRuleAssertion_matchingRule(LDAPMatchingRuleId):
541 tag = CLASS_CONTEXT|0x01 542 pass
543
544 -class LDAPMatchingRuleAssertion_type(LDAPAttributeDescription):
545 tag = CLASS_CONTEXT|0x02 546 pass
547
548 -class LDAPMatchingRuleAssertion_matchValue(LDAPAssertionValue):
549 tag = CLASS_CONTEXT|0x03 550 pass
551
552 -class LDAPMatchingRuleAssertion_dnAttributes(BERBoolean):
553 tag = CLASS_CONTEXT|0x04 554 pass
555
556 -class LDAPBERDecoderContext_MatchingRuleAssertion(BERDecoderContext):
557 Identities = { 558 LDAPMatchingRuleAssertion_matchingRule.tag: LDAPMatchingRuleAssertion_matchingRule, 559 LDAPMatchingRuleAssertion_type.tag: LDAPMatchingRuleAssertion_type, 560 LDAPMatchingRuleAssertion_matchValue.tag: LDAPMatchingRuleAssertion_matchValue, 561 LDAPMatchingRuleAssertion_dnAttributes.tag: LDAPMatchingRuleAssertion_dnAttributes, 562 }
563
564 -class LDAPMatchingRuleAssertion(BERSequence):
565 matchingRule=None 566 type=None 567 matchValue=None 568 dnAttributes=None 569
570 - def fromBER(klass, tag, content, berdecoder=None):
571 l = berDecodeMultiple(content, LDAPBERDecoderContext_MatchingRuleAssertion(fallback=berdecoder, inherit=berdecoder)) 572 573 assert 1<=len(l)<=4 574 if isinstance(l[0], LDAPMatchingRuleAssertion_matchingRule): 575 matchingRule=l[0] 576 del l[0] 577 if len(l)>1 \ 578 and isinstance(l[0], LDAPMatchingRuleAssertion_type): 579 type=l[0] 580 del l[0] 581 if len(l)>1 \ 582 and isinstance(l[0], LDAPMatchingRuleAssertion_matchValue): 583 matchValue=l[0] 584 del l[0] 585 if len(l)>1 \ 586 and isinstance(l[0], LDAPMatchingRuleAssertion_dnAttributes): 587 dnAttributes=l[0] 588 del l[0] 589 assert matchValue 590 if not dnAttributes: 591 dnAttributes=None 592 593 assert 8<=len(l)<=8 594 r = klass(matchingRule=matchingRule, 595 type=type, 596 matchValue=matchValue, 597 dnAttributes=dnAttributes, 598 tag=tag) 599 return r
600 fromBER = classmethod(fromBER) 601
602 - def __init__(self, matchingRule=None, type=None, 603 matchValue=None, dnAttributes=None, 604 tag=None):
605 BERSequence.__init__(self, value=[], tag=tag) 606 assert matchValue is not None 607 self.matchingRule=matchingRule 608 self.type=type 609 self.matchValue=matchValue 610 self.dnAttributes=dnAttributes 611 if not self.dnAttributes: 612 self.dnAttributes=None
613
614 - def __str__(self):
615 return str(BERSequence( 616 filter(lambda x: x is not None, [self.matchingRule, self.type, self.matchValue, self.dnAttributes]), tag=self.tag))
617
618 - def __repr__(self):
619 l=[] 620 l.append('matchingRule=%s' % repr(self.matchingRule)) 621 l.append('type=%s' % repr(self.type)) 622 l.append('matchValue=%s' % repr(self.matchValue)) 623 l.append('dnAttributes=%s' % repr(self.dnAttributes)) 624 if self.tag!=self.__class__.tag: 625 l.append('tag=%d' % self.tag) 626 return self.__class__.__name__+'('+', '.join(l)+')'
627
628 -class LDAPFilter_extensibleMatch(LDAPMatchingRuleAssertion):
629 tag = CLASS_CONTEXT|0x09 630 pass
631 632
633 -class LDAPBERDecoderContext_Filter(BERDecoderContext):
634 Identities = { 635 LDAPFilter_and.tag: LDAPFilter_and, 636 LDAPFilter_or.tag: LDAPFilter_or, 637 LDAPFilter_not.tag: LDAPFilter_not, 638 LDAPFilter_equalityMatch.tag: LDAPFilter_equalityMatch, 639 LDAPFilter_substrings.tag: LDAPFilter_substrings, 640 LDAPFilter_greaterOrEqual.tag: LDAPFilter_greaterOrEqual, 641 LDAPFilter_lessOrEqual.tag: LDAPFilter_lessOrEqual, 642 LDAPFilter_present.tag: LDAPFilter_present, 643 LDAPFilter_approxMatch.tag: LDAPFilter_approxMatch, 644 LDAPFilter_extensibleMatch.tag: LDAPFilter_extensibleMatch, 645 }
646 647 LDAP_SCOPE_baseObject=0 648 LDAP_SCOPE_singleLevel=1 649 LDAP_SCOPE_wholeSubtree=2 650 651 LDAP_DEREF_neverDerefAliases=0 652 LDAP_DEREF_derefInSearching=1 653 LDAP_DEREF_derefFindingBaseObj=2 654 LDAP_DEREF_derefAlways=3 655 656 LDAPFilterMatchAll = LDAPFilter_present('objectClass') 657
658 -class LDAPSearchRequest(LDAPProtocolRequest, BERSequence):
659 tag=CLASS_APPLICATION|0x03 660 661 baseObject='' 662 scope=LDAP_SCOPE_wholeSubtree 663 derefAliases=LDAP_DEREF_neverDerefAliases 664 sizeLimit=0 665 timeLimit=0 666 typesOnly=0 667 filter=LDAPFilterMatchAll 668 attributes=[] #TODO AttributeDescriptionList 669 670 #TODO decode 671
672 - def fromBER(klass, tag, content, berdecoder=None):
673 l = berDecodeMultiple(content, LDAPBERDecoderContext_Filter(fallback=berdecoder, inherit=berdecoder)) 674 675 assert 8<=len(l)<=8 676 r = klass(baseObject=l[0].value, 677 scope=l[1].value, 678 derefAliases=l[2].value, 679 sizeLimit=l[3].value, 680 timeLimit=l[4].value, 681 typesOnly=l[5].value, 682 filter=l[6], 683 attributes=[x.value for x in l[7]], 684 tag=tag) 685 return r
686 fromBER = classmethod(fromBER) 687
688 - def __init__(self, 689 baseObject=None, 690 scope=None, 691 derefAliases=None, 692 sizeLimit=None, 693 timeLimit=None, 694 typesOnly=None, 695 filter=None, 696 attributes=None, 697 tag=None):
698 LDAPProtocolRequest.__init__(self) 699 BERSequence.__init__(self, [], tag=tag) 700 701 if baseObject is not None: 702 self.baseObject=baseObject 703 if scope is not None: 704 self.scope=scope 705 if derefAliases is not None: 706 self.derefAliases=derefAliases 707 if sizeLimit is not None: 708 self.sizeLimit=sizeLimit 709 if timeLimit is not None: 710 self.timeLimit=timeLimit 711 if typesOnly is not None: 712 self.typesOnly=typesOnly 713 if filter is not None: 714 self.filter=filter 715 if attributes is not None: 716 self.attributes=attributes
717
718 - def __str__(self):
719 return str(BERSequence([ 720 BEROctetString(self.baseObject), 721 BEREnumerated(self.scope), 722 BEREnumerated(self.derefAliases), 723 BERInteger(self.sizeLimit), 724 BERInteger(self.timeLimit), 725 BERBoolean(self.typesOnly), 726 self.filter, 727 BERSequenceOf(map(BEROctetString, self.attributes)), 728 ], tag=self.tag))
729
730 - def __repr__(self):
731 if self.tag==self.__class__.tag: 732 return self.__class__.__name__\ 733 +("(baseObject=%s, scope=%s, derefAliases=%s, " \ 734 +"sizeLimit=%s, timeLimit=%s, typesOnly=%s, " \ 735 "filter=%s, attributes=%s)") \ 736 %(repr(self.baseObject), self.scope, 737 self.derefAliases, self.sizeLimit, 738 self.timeLimit, self.typesOnly, 739 repr(self.filter), self.attributes) 740 741 else: 742 return self.__class__.__name__\ 743 +("(baseObject=%s, scope=%s, derefAliases=%s, " \ 744 +"sizeLimit=%s, timeLimit=%s, typesOnly=%s, " \ 745 "filter=%s, attributes=%s, tag=%d)") \ 746 %(repr(self.baseObject), self.scope, 747 self.derefAliases, self.sizeLimit, 748 self.timeLimit, self.typesOnly, 749 self.filter, self.attributes, self.tag)
750
751 -class LDAPSearchResultEntry(LDAPProtocolResponse, BERSequence):
752 tag=CLASS_APPLICATION|0x04 753
754 - def fromBER(klass, tag, content, berdecoder=None):
755 l = berDecodeMultiple(content, LDAPBERDecoderContext_Filter(fallback=berdecoder, inherit=berdecoder)) 756 757 objectName=l[0].value 758 attributes=[] 759 for attr, li in l[1].data: 760 attributes.append((attr.value, map(lambda x: x.value, li))) 761 r = klass(objectName=objectName, 762 attributes=attributes, 763 tag=tag) 764 return r
765 fromBER = classmethod(fromBER) 766
767 - def __init__(self, objectName, attributes, tag=None):
768 LDAPProtocolResponse.__init__(self) 769 BERSequence.__init__(self, [], tag=tag) 770 assert objectName is not None 771 assert attributes is not None 772 self.objectName=objectName 773 self.attributes=attributes
774
775 - def __str__(self):
776 return str(BERSequence([ 777 BEROctetString(self.objectName), 778 BERSequence(map(lambda (attr,li): 779 BERSequence([BEROctetString(attr), 780 BERSet(map(BEROctetString, 781 li))]), 782 self.attributes)), 783 ], tag=self.tag))
784
785 - def __repr__(self):
786 if self.tag==self.__class__.tag: 787 return self.__class__.__name__\ 788 +"(objectName=%s, attributes=%s"\ 789 %(repr(str(self.objectName)), 790 repr(map(lambda (a,l): 791 (str(a), 792 map(lambda i, l=l: str(i), l)), 793 self.attributes))) 794 else: 795 return self.__class__.__name__\ 796 +"(objectName=%s, attributes=%s, tag=%d"\ 797 %(repr(str(self.objectName)), 798 repr(map(lambda (a,l): 799 (str(a), 800 map(lambda i, l=l: str(i), l)), 801 self.attributes)), 802 self.tag)
803 804
805 -class LDAPSearchResultDone(LDAPResult):
806 tag=CLASS_APPLICATION|0x05 807 808 pass
809
810 -class LDAPControls(BERSequence):
811 tag = CLASS_CONTEXT|0x00 812
813 - def fromBER(klass, tag, content, berdecoder=None):
814 l = berDecodeMultiple(content, LDAPBERDecoderContext_LDAPControls( 815 inherit=berdecoder)) 816 817 r = klass(l, tag=tag) 818 return r
819 fromBER = classmethod(fromBER)
820
821 -class LDAPControl(BERSequence):
822 criticality = None 823 controlValue = None 824
825 - def fromBER(klass, tag, content, berdecoder=None):
826 l = berDecodeMultiple(content, berdecoder) 827 828 kw = {} 829 if l[1:]: 830 kw['criticality'] = l[1].value 831 if l[2:]: 832 kw['controlValue'] = l[2].value 833 # TODO is controlType, controlValue allowed without criticality? 834 assert not l[3:] 835 836 r = klass(controlType=l[0].value, 837 tag=tag, 838 **kw) 839 return r
840 fromBER = classmethod(fromBER) 841
842 - def __init__(self, 843 controlType, criticality=None, controlValue=None, 844 id=None, tag=None):
845 BERSequence.__init__(self, value=[], tag=tag) 846 assert controlType is not None 847 self.controlType = controlType 848 self.criticality = criticality 849 self.controlValue = controlValue
850
851 - def __str__(self):
852 self.data=[LDAPOID(self.controlType)] 853 if self.criticality is not None: 854 self.data.append(BERBoolean(self.criticality)) 855 if self.controlValue is not None: 856 self.data.append(BEROctetString(self.controlValue)) 857 return BERSequence.__str__(self)
858
859 -class LDAPBERDecoderContext_LDAPControls(BERDecoderContext):
860 Identities = { 861 LDAPControl.tag: LDAPControl, 862 }
863
864 -class LDAPBERDecoderContext_LDAPMessage(BERDecoderContext):
865 Identities = { 866 LDAPControls.tag: LDAPControls, 867 LDAPSearchResultReference.tag: LDAPSearchResultReference, 868 }
869
870 -class LDAPBERDecoderContext_TopLevel(BERDecoderContext):
871 Identities = { 872 BERSequence.tag: LDAPMessage, 873 }
874
875 -class LDAPModifyRequest(LDAPProtocolRequest, BERSequence):
876 tag=CLASS_APPLICATION|0x06 877 object = None 878 modification = None 879
880 - def fromBER(klass, tag, content, berdecoder=None):
881 l = berDecodeMultiple(content, berdecoder) 882 883 assert len(l) == 2 884 885 r = klass(object=l[0].value, 886 modification=l[1].data, 887 tag=tag) 888 return r
889 fromBER = classmethod(fromBER) 890
891 - def __init__(self, object=None, modification=None, tag=None):
892 """ 893 Initialize the object 894 895 Example usage:: 896 897 l = LDAPModifyRequest( 898 object='cn=foo,dc=example,dc=com', 899 modification=[ 900 901 BERSequence([ 902 BEREnumerated(0), 903 BERSequence([ 904 LDAPAttributeDescription('attr1'), 905 BERSet([ 906 LDAPString('value1'), 907 LDAPString('value2'), 908 ]), 909 ]), 910 ]), 911 912 BERSequence([ 913 BEREnumerated(1), 914 BERSequence([ 915 LDAPAttributeDescription('attr2'), 916 ]), 917 ]), 918 919 ]) 920 921 But more likely you just want to say:: 922 923 mod = delta.ModifyOp('cn=foo,dc=example,dc=com', 924 [delta.Add('attr1', ['value1', 'value2']), 925 delta.Delete('attr1', ['value1', 'value2'])]) 926 l = mod.asLDAP() 927 """ 928 929 LDAPProtocolRequest.__init__(self) 930 BERSequence.__init__(self, [], tag=tag) 931 self.object=object 932 self.modification=modification
933
934 - def __str__(self):
935 l=[LDAPString(self.object)] 936 if self.modification is not None: 937 l.append(BERSequence(self.modification)) 938 return str(BERSequence(l, tag=self.tag))
939
940 - def __repr__(self):
941 if self.tag==self.__class__.tag: 942 return self.__class__.__name__+"(object=%s, modification=%s)"\ 943 %(repr(self.object), repr(self.modification)) 944 else: 945 return self.__class__.__name__+"(object=%s, modification=%s, tag=%d)" \ 946 %(repr(self.object), repr(self.modification), self.tag)
947 948
949 -class LDAPModifyResponse(LDAPResult):
950 tag = CLASS_APPLICATION|0x07
951
952 -class LDAPAddRequest(LDAPProtocolRequest, BERSequence):
953 tag = CLASS_APPLICATION|0x08 954
955 - def fromBER(klass, tag, content, berdecoder=None):
956 l = berDecodeMultiple(content, berdecoder) 957 958 r = klass(entry=l[0].value, 959 attributes=l[1], 960 tag=tag) 961 return r
962 fromBER = classmethod(fromBER) 963
964 - def __init__(self, entry=None, attributes=None, tag=None):
965 """ 966 Initialize the object 967 968 Example usage:: 969 970 l=LDAPAddRequest(entry='cn=foo,dc=example,dc=com', 971 attributes=[(LDAPAttributeDescription("attrFoo"), 972 BERSet(value=( 973 LDAPAttributeValue("value1"), 974 LDAPAttributeValue("value2"), 975 ))), 976 (LDAPAttributeDescription("attrBar"), 977 BERSet(value=( 978 LDAPAttributeValue("value1"), 979 LDAPAttributeValue("value2"), 980 ))), 981 ]) 982 """ 983 984 LDAPProtocolRequest.__init__(self) 985 BERSequence.__init__(self, [], tag=tag) 986 self.entry=entry 987 self.attributes=attributes
988
989 - def __str__(self):
990 return str(BERSequence([ 991 LDAPString(self.entry), 992 BERSequence(map(BERSequence, self.attributes)), 993 ], tag=self.tag))
994
995 - def __repr__(self):
996 if self.tag==self.__class__.tag: 997 return self.__class__.__name__+"(entry=%s, attributes=%s)"\ 998 %(repr(self.entry), repr(self.attributes)) 999 else: 1000 return self.__class__.__name__+"(entry=%s, attributes=%s, tag=%d)" \ 1001 %(repr(self.entry), repr(self.attributes), self.tag)
1002 1003 1004
1005 -class LDAPAddResponse(LDAPResult):
1006 tag = CLASS_APPLICATION|0x09
1007
1008 -class LDAPDelRequest(LDAPProtocolRequest, LDAPString):
1009 tag = CLASS_APPLICATION|0x0a 1010
1011 - def __init__(self, value=None, entry=None, tag=None):
1012 """ 1013 Initialize the object 1014 1015 l=LDAPDelRequest(entry='cn=foo,dc=example,dc=com') 1016 """ 1017 if entry is None and value is not None: 1018 entry = value 1019 LDAPProtocolRequest.__init__(self) 1020 LDAPString.__init__(self, value=entry, tag=tag)
1021
1022 - def __str__(self):
1023 return LDAPString.__str__(self)
1024
1025 - def __repr__(self):
1026 if self.tag==self.__class__.tag: 1027 return self.__class__.__name__+"(entry=%s)" \ 1028 %repr(self.value) 1029 else: 1030 return self.__class__.__name__ \ 1031 +"(entry=%s, tag=%d)" \ 1032 %(repr(self.value), self.tag)
1033 1034
1035 -class LDAPDelResponse(LDAPResult):
1036 tag = CLASS_APPLICATION|0x0b 1037 pass
1038 1039
1040 -class LDAPModifyDNResponse_newSuperior(LDAPString):
1041 tag = CLASS_CONTEXT|0x00 1042 1043 pass
1044
1045 -class LDAPBERDecoderContext_ModifyDNRequest(BERDecoderContext):
1046 Identities = { 1047 LDAPModifyDNResponse_newSuperior.tag: LDAPModifyDNResponse_newSuperior, 1048 }
1049
1050 -class LDAPModifyDNRequest(LDAPProtocolRequest, BERSequence):
1051 tag=CLASS_APPLICATION|12 1052 1053 entry=None 1054 newrdn=None 1055 deleteoldrdn=None 1056 newSuperior=None 1057
1058 - def fromBER(klass, tag, content, berdecoder=None):
1059 l = berDecodeMultiple(content, LDAPBERDecoderContext_ModifyDNRequest(fallback=berdecoder)) 1060 1061 kw = {} 1062 try: 1063 kw['newSuperior'] = str(l[3].value) 1064 except IndexError: 1065 pass 1066 1067 r = klass(entry=str(l[0].value), 1068 newrdn=str(l[1].value), 1069 deleteoldrdn=l[2].value, 1070 tag=tag, 1071 **kw) 1072 return r
1073 fromBER = classmethod(fromBER) 1074
1075 - def __init__(self, entry, newrdn, deleteoldrdn, newSuperior=None, 1076 tag=None):
1077 """ 1078 Initialize the object 1079 1080 Example usage:: 1081 1082 l=LDAPModifyDNRequest(entry='cn=foo,dc=example,dc=com', 1083 newrdn='someAttr=value', 1084 deleteoldrdn=0) 1085 """ 1086 1087 LDAPProtocolRequest.__init__(self) 1088 BERSequence.__init__(self, [], tag=tag) 1089 assert entry is not None 1090 assert newrdn is not None 1091 assert deleteoldrdn is not None 1092 self.entry=entry 1093 self.newrdn=newrdn 1094 self.deleteoldrdn=deleteoldrdn 1095 self.newSuperior=newSuperior
1096
1097 - def __str__(self):
1098 l=[ 1099 LDAPString(self.entry), 1100 LDAPString(self.newrdn), 1101 BERBoolean(self.deleteoldrdn), 1102 ] 1103 if self.newSuperior is not None: 1104 l.append(LDAPString(self.newSuperior, tag=CLASS_CONTEXT|0)) 1105 return str(BERSequence(l, tag=self.tag))
1106
1107 - def __repr__(self):
1108 l = [ 1109 "entry=%s" % repr(self.entry), 1110 "newrdn=%s" % repr(self.newrdn), 1111 "deleteoldrdn=%s" % repr(self.deleteoldrdn), 1112 ] 1113 if self.newSuperior is not None: 1114 l.append("newSuperior=%s" % repr(self.newSuperior)) 1115 if self.tag!=self.__class__.tag: 1116 l.append("tag=%d" % self.tag) 1117 return self.__class__.__name__ + "(" + ', '.join(l) + ")"
1118
1119 -class LDAPModifyDNResponse(LDAPResult):
1120 tag=CLASS_APPLICATION|13
1121 1122 #class LDAPCompareResponse(LDAPProtocolResponse): 1123 #class LDAPCompareRequest(LDAPProtocolRequest): 1124 #class LDAPAbandonRequest(LDAPProtocolRequest): 1125 # needs_answer=0 1126 1127
1128 -class LDAPOID(BEROctetString):
1129 pass
1130
1131 -class LDAPResponseName(LDAPOID):
1132 tag = CLASS_CONTEXT|10
1133
1134 -class LDAPResponse(BEROctetString):
1135 tag = CLASS_CONTEXT|11
1136
1137 -class LDAPBERDecoderContext_LDAPExtendedRequest(BERDecoderContext):
1138 Identities = { 1139 CLASS_CONTEXT|0x00: BEROctetString, 1140 CLASS_CONTEXT|0x01: BEROctetString, 1141 }
1142
1143 -class LDAPExtendedRequest(LDAPProtocolRequest, BERSequence):
1144 tag = CLASS_APPLICATION|23 1145 1146 requestName = None 1147 requestValue = None 1148
1149 - def fromBER(klass, tag, content, berdecoder=None):
1150 l = berDecodeMultiple(content, 1151 LDAPBERDecoderContext_LDAPExtendedRequest( 1152 fallback=berdecoder)) 1153 1154 kw = {} 1155 try: 1156 kw['requestValue'] = l[1].value 1157 except IndexError: 1158 pass 1159 1160 r = klass(requestName=l[0].value, 1161 tag=tag, 1162 **kw) 1163 return r
1164 fromBER = classmethod(fromBER) 1165
1166 - def __init__(self, requestName, requestValue=None, 1167 tag=None):
1168 LDAPProtocolRequest.__init__(self) 1169 BERSequence.__init__(self, [], tag=tag) 1170 assert requestName is not None 1171 assert isinstance(requestName, basestring) 1172 self.requestName=requestName 1173 self.requestValue=requestValue
1174
1175 - def __str__(self):
1176 l=[LDAPOID(self.requestName, tag=CLASS_CONTEXT|0)] 1177 if self.requestValue is not None: 1178 l.append(BEROctetString(str(self.requestValue), tag=CLASS_CONTEXT|1)) 1179 return str(BERSequence(l, tag=self.tag))
1180
1181 -class LDAPPasswordModifyRequest_userIdentity(BEROctetString):
1182 tag=CLASS_CONTEXT|0
1183 -class LDAPPasswordModifyRequest_oldPasswd(BEROctetString):
1184 tag=CLASS_CONTEXT|1
1185 -class LDAPPasswordModifyRequest_newPasswd(BEROctetString):
1186 tag=CLASS_CONTEXT|2
1187
1188 -class LDAPBERDecoderContext_LDAPPasswordModifyRequest(BERDecoderContext):
1189 Identities = { 1190 LDAPPasswordModifyRequest_userIdentity.tag: 1191 LDAPPasswordModifyRequest_userIdentity, 1192 1193 LDAPPasswordModifyRequest_oldPasswd.tag: 1194 LDAPPasswordModifyRequest_oldPasswd, 1195 1196 LDAPPasswordModifyRequest_newPasswd.tag: 1197 LDAPPasswordModifyRequest_newPasswd, 1198 }
1199
1200 -class LDAPPasswordModifyRequest(LDAPExtendedRequest):
1201 oid = '1.3.6.1.4.1.4203.1.11.1' 1202
1203 - def __init__(self, requestName=None, 1204 userIdentity=None, oldPasswd=None, newPasswd=None, 1205 tag=None):
1206 assert (requestName is None 1207 or requestName == self.oid), \ 1208 '%s requestName was %s instead of %s' \ 1209 % (self.__class__.__name__, requestName, self.oid) 1210 #TODO genPasswd 1211 1212 l=[] 1213 if userIdentity is not None: 1214 l.append(LDAPPasswordModifyRequest_userIdentity(userIdentity)) 1215 if oldPasswd is not None: 1216 l.append(LDAPPasswordModifyRequest_oldPasswd(oldPasswd)) 1217 if newPasswd is not None: 1218 l.append(LDAPPasswordModifyRequest_newPasswd(newPasswd)) 1219 LDAPExtendedRequest.__init__( 1220 self, 1221 requestName=self.oid, 1222 requestValue=str(BERSequence(l)), 1223 tag=tag)
1224
1225 - def __repr__(self):
1226 l=[] 1227 # TODO userIdentity, oldPasswd, newPasswd 1228 if self.tag!=self.__class__.tag: 1229 l.append('tag=%d' % self.tag) 1230 return self.__class__.__name__+'('+', '.join(l)+')'
1231
1232 -class LDAPBERDecoderContext_LDAPExtendedResponse(BERDecoderContext):
1233 Identities = { 1234 LDAPResponseName.tag: LDAPResponseName, 1235 LDAPResponse.tag: LDAPResponse, 1236 }
1237
1238 -class LDAPExtendedResponse(LDAPResult):
1239 tag = CLASS_APPLICATION|0x18 1240 1241 responseName = None 1242 response = None 1243
1244 - def fromBER(klass, tag, content, berdecoder=None):
1245 l = berDecodeMultiple(content, LDAPBERDecoderContext_LDAPExtendedResponse( 1246 fallback=berdecoder)) 1247 1248 assert 3<=len(l)<=4 1249 1250 referral = None 1251 #if (l[3:] and isinstance(l[3], LDAPReferral)): 1252 #TODO support referrals 1253 #self.referral=self.data[0] 1254 1255 r = klass(resultCode=l[0].value, 1256 matchedDN=l[1].value, 1257 errorMessage=l[2].value, 1258 referral=referral, 1259 tag=tag) 1260 return r
1261 fromBER = classmethod(fromBER) 1262
1263 - def __init__(self, resultCode=None, matchedDN=None, errorMessage=None, 1264 referral=None, serverSaslCreds=None, 1265 responseName=None, response=None, 1266 tag=None):
1275
1276 - def __str__(self):
1277 assert self.referral is None #TODO 1278 l=[BEREnumerated(self.resultCode), 1279 BEROctetString(self.matchedDN), 1280 BEROctetString(self.errorMessage), 1281 #TODO referral [3] Referral OPTIONAL 1282 ] 1283 if self.responseName is not None: 1284 l.append(LDAPOID(self.responseName, tag=CLASS_CONTEXT|0x0a)) 1285 if self.response is not None: 1286 l.append(BEROctetString(self.response, tag=CLASS_CONTEXT|0x0b)) 1287 return str(BERSequence(l, tag=self.tag))
1288
1289 -class LDAPStartTLSRequest(LDAPExtendedRequest):
1290 """ 1291 Request to start Transport Layer Security. 1292 1293 See RFC 2830 for details. 1294 """ 1295 oid = '1.3.6.1.4.1.1466.20037' 1296
1297 - def __init__(self, requestName=None, tag=None):
1298 assert (requestName is None 1299 or requestName == self.oid), \ 1300 '%s requestName was %s instead of %s' \ 1301 % (self.__class__.__name__, requestName, self.oid) 1302 1303 LDAPExtendedRequest.__init__( 1304 self, 1305 requestName=self.oid, 1306 tag=tag)
1307
1308 - def __repr__(self):
1309 l=[] 1310 if self.tag!=self.__class__.tag: 1311 l.append('tag=%d' % self.tag) 1312 return self.__class__.__name__+'('+', '.join(l)+')'
1313
1314 -class LDAPBERDecoderContext(BERDecoderContext):
1315 Identities = { 1316 LDAPBindResponse.tag: LDAPBindResponse, 1317 LDAPBindRequest.tag: LDAPBindRequest, 1318 LDAPUnbindRequest.tag: LDAPUnbindRequest, 1319 LDAPSearchRequest.tag: LDAPSearchRequest, 1320 LDAPSearchResultEntry.tag: LDAPSearchResultEntry, 1321 LDAPSearchResultDone.tag: LDAPSearchResultDone, 1322 LDAPReferral.tag: LDAPReferral, 1323 LDAPModifyRequest.tag: LDAPModifyRequest, 1324 LDAPModifyResponse.tag: LDAPModifyResponse, 1325 LDAPAddRequest.tag: LDAPAddRequest, 1326 LDAPAddResponse.tag: LDAPAddResponse, 1327 LDAPDelRequest.tag: LDAPDelRequest, 1328 LDAPDelResponse.tag: LDAPDelResponse, 1329 LDAPExtendedRequest.tag: LDAPExtendedRequest, 1330 LDAPExtendedResponse.tag: LDAPExtendedResponse, 1331 LDAPModifyDNRequest.tag: LDAPModifyDNRequest, 1332 LDAPModifyDNResponse.tag: LDAPModifyDNResponse, 1333 }
1334