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

Source Code for Module ldaptor.protocols.pureldap

   1  # Copyright (C) 2001 Tommi Virtanen 
   2  # 
   3  # This library is free software; you can redistribute it and/or 
   4  # modify it under the terms of version 2.1 of the GNU Lesser General Public 
   5  # License as published by the Free Software Foundation. 
   6  # 
   7  # This library is distributed in the hope that it will be useful, 
   8  # but WITHOUT ANY WARRANTY; without even the implied warranty of 
   9  # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
  10  # Lesser General Public License for more details. 
  11  # 
  12  # You should have received a copy of the GNU Lesser General Public 
  13  # License along with this library; if not, write to the Free Software 
  14  # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
  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 
29 -def alloc_ldap_message_id():
30 global next_ldap_message_id 31 r=next_ldap_message_id 32 next_ldap_message_id=next_ldap_message_id+1 33 return r
34
35 -def escape(s):
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
43 -class LDAPInteger(BERInteger):
44 pass
45
46 -class LDAPString(BEROctetString):
47 pass
48
49 -class LDAPAttributeValue(BEROctetString):
50 pass
51
52 -class LDAPMessage(BERSequence):
53 id = None 54 value = None 55
56 - def fromBER(klass, tag, content, berdecoder=None):
57 l = berDecodeMultiple(content, berdecoder) 58 59 id_=l[0].value 60 value=l[1] 61 if l[2:]: 62 controls = [] 63 for c in l[2]: 64 controls.append(( 65 c.controlType, 66 c.criticality, 67 c.controlValue, 68 )) 69 else: 70 controls = None 71 assert not l[3:] 72 73 r = klass(id=id_, 74 value=value, 75 controls=controls, 76 tag=tag) 77 return r
78 fromBER = classmethod(fromBER) 79
80 - def __init__(self, value=None, controls=None, id=None, tag=None):
81 BERSequence.__init__(self, value=[], tag=tag) 82 assert value is not None 83 self.id=id 84 if self.id is None: 85 self.id=alloc_ldap_message_id() 86 self.value=value 87 self.controls = controls
88
89 - def __str__(self):
90 l = [BERInteger(self.id), self.value] 91 if self.controls is not None: 92 l.append(LDAPControls([LDAPControl(*a) for a in self.controls])) 93 return str(BERSequence(l))
94
95 - def __repr__(self):
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
103 -class LDAPProtocolOp:
104 - def __init__(self):
105 pass
106
107 - def __str__(self):
108 raise NotImplementedError
109
110 -class LDAPProtocolRequest(LDAPProtocolOp):
111 needs_answer=1 112 pass
113
114 -class LDAPProtocolResponse(LDAPProtocolOp):
115 pass
116
117 -class LDAPBERDecoderContext_LDAPBindRequest(BERDecoderContext):
118 Identities = { 119 CLASS_CONTEXT|0x00: BEROctetString, 120 CLASS_CONTEXT|0x03: BERSequence, 121 }
122
123 -class LDAPBindRequest(LDAPProtocolRequest, BERSequence):
124 tag=CLASS_APPLICATION|0x00 125
126 - def fromBER(klass, tag, content, berdecoder=None):
127 l = berDecodeMultiple(content, 128 LDAPBERDecoderContext_LDAPBindRequest( 129 fallback=berdecoder)) 130 131 sasl = False 132 auth = None 133 if isinstance(l[2], BEROctetString): 134 auth = l[2].value 135 elif isinstance(l[2], BERSequence): 136 auth = (l[2][0].value, l[2][1].value) 137 sasl = True 138 139 r = klass(version=l[0].value, 140 dn=l[1].value, 141 auth=auth, 142 tag=tag, 143 sasl=sasl) 144 return r
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
167 - def __str__(self):
168 if not self.sasl: 169 auth_ber = BEROctetString(self.auth, tag=CLASS_CONTEXT|0) 170 else: 171 auth_ber = BERSequence([BEROctetString(self.auth[0]), BEROctetString(self.auth[1])], tag=CLASS_CONTEXT|3) 172 return str(BERSequence([ 173 BERInteger(self.version), 174 BEROctetString(self.dn), 175 auth_ber, 176 ], tag=self.tag))
177
178 - def __repr__(self):
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
188 -class LDAPReferral(BERSequence):
189 tag = CLASS_CONTEXT | 0x03
190 191 192 # This is currently just a stub and implements no real functionality.
193 -class LDAPSearchResultReference(LDAPProtocolResponse):
194 tag = CLASS_APPLICATION | 0x13 195
196 - def __init__(self):
198
199 - def fromBER(cls, tag, content, berdecoder=None):
200 r = cls() 201 return r
202 fromBER = classmethod(fromBER) 203
204 - def __str__(self):
205 return object.__str__(self)
206
207 - def __repr__(self):
208 return object.__repr__(self)
209 210
211 -class LDAPResult(LDAPProtocolResponse, BERSequence):
212 - def fromBER(klass, tag, content, berdecoder=None):
213 l = berDecodeMultiple(content, LDAPBERDecoderContext_LDAPBindRequest( 214 fallback=berdecoder)) 215 216 assert 3<=len(l)<=4 217 218 referral = None 219 #if (l[3:] and isinstance(l[3], LDAPReferral)): 220 #TODO support referrals 221 #self.referral=self.data[0] 222 223 r = klass(resultCode=l[0].value, 224 matchedDN=l[1].value, 225 errorMessage=l[2].value, 226 referral=referral, 227 tag=tag) 228 return r
229 fromBER = classmethod(fromBER) 230
231 - def __init__(self, resultCode=None, matchedDN=None, errorMessage=None, referral=None, serverSaslCreds=None, tag=None):
232 LDAPProtocolResponse.__init__(self) 233 BERSequence.__init__(self, value=[], tag=tag) 234 assert resultCode is not None 235 self.resultCode=resultCode 236 if matchedDN is None: 237 matchedDN='' 238 self.matchedDN=matchedDN 239 if errorMessage is None: 240 errorMessage='' 241 self.errorMessage=errorMessage 242 self.referral=referral 243 self.serverSaslCreds=serverSaslCreds
244
245 - def __str__(self):
246 assert self.referral is None #TODO 247 return str(BERSequence([ 248 BEREnumerated(self.resultCode), 249 BEROctetString(self.matchedDN), 250 BEROctetString(self.errorMessage), 251 #TODO referral [3] Referral OPTIONAL 252 ], tag=self.tag))
253
254 - def __repr__(self):
255 l=[] 256 l.append('resultCode=%r' % self.resultCode) 257 if self.matchedDN: 258 l.append('matchedDN=%r' % str(self.matchedDN)) 259 if self.errorMessage: 260 l.append('errorMessage=%r' % str(self.errorMessage)) 261 if self.referral: 262 l.append('referral=%r' % self.referral) 263 if self.tag!=self.__class__.tag: 264 l.append('tag=%d' % self.tag) 265 return self.__class__.__name__+'('+', '.join(l)+')'
266
267 -class LDAPBindResponse_serverSaslCreds(BEROctetString):
268 tag = CLASS_CONTEXT|0x07 269 270 pass
271
272 -class LDAPBERDecoderContext_BindResponse(BERDecoderContext):
273 Identities = { 274 LDAPBindResponse_serverSaslCreds.tag: LDAPBindResponse_serverSaslCreds, 275 }
276
277 -class LDAPBindResponse(LDAPResult):
278 tag=CLASS_APPLICATION|0x01 279 280 resultCode = None 281 matchedDN = None 282 errorMessage = None 283 referral = None 284 serverSaslCreds = None 285
286 - def fromBER(klass, tag, content, berdecoder=None):
287 l = berDecodeMultiple(content, LDAPBERDecoderContext_BindResponse( 288 fallback=berdecoder)) 289 290 assert 3<=len(l)<=4 291 292 try: 293 if isinstance(l[3], LDAPBindResponse_serverSaslCreds): 294 serverSaslCreds=l[3] 295 else: 296 serverSaslCreds=None 297 except IndexError: 298 serverSaslCreds=None 299 300 referral = None 301 #if (l[3:] and isinstance(l[3], LDAPReferral)): 302 #TODO support referrals 303 #self.referral=self.data[0] 304 305 r = klass(resultCode=l[0].value, 306 matchedDN=l[1].value, 307 errorMessage=l[2].value, 308 referral=referral, 309 serverSaslCreds=serverSaslCreds, 310 tag=tag) 311 return r
312 fromBER = classmethod(fromBER) 313
314 - def __init__(self, resultCode=None, matchedDN=None, errorMessage=None, referral=None, serverSaslCreds=None, tag=None):
317
318 - def __str__(self):
319 return LDAPResult.__str__(self)
320
321 - def __repr__(self):
322 return LDAPResult.__repr__(self)
323
324 -class LDAPUnbindRequest(LDAPProtocolRequest, BERNull):
325 tag=CLASS_APPLICATION|0x02 326 needs_answer=0 327
328 - def __init__(self, *args, **kwargs):
329 LDAPProtocolRequest.__init__(self) 330 BERNull.__init__(self, *args, **kwargs)
331
332 - def __str__(self):
333 return BERNull.__str__(self)
334
335 -class LDAPAttributeDescription(BEROctetString):
336 pass
337
338 -class LDAPAttributeValueAssertion(BERSequence):
339 - def fromBER(klass, tag, content, berdecoder=None):
340 l = berDecodeMultiple(content, berdecoder) 341 assert len(l) == 2 342 343 r = klass(attributeDesc=l[0], 344 assertionValue=l[1], 345 tag=tag) 346 return r
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
355 - def __str__(self):
356 return str(BERSequence([self.attributeDesc, 357 self.assertionValue], 358 tag=self.tag))
359
360 - def __repr__(self):
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
369 -class LDAPFilter(BERStructured):
370 - def __init__(self, tag=None):
372
373 -class LDAPFilterSet(BERSet):
374 - def fromBER(klass, tag, content, berdecoder=None):
375 l = berDecodeMultiple(content, LDAPBERDecoderContext_Filter(fallback=berdecoder)) 376 r = klass(l, tag=tag) 377 return r
378 fromBER = classmethod(fromBER)
379
380 -class LDAPFilter_and(LDAPFilterSet):
381 tag = CLASS_CONTEXT|0x00 382
383 - def asText(self):
384 return '(&'+''.join([x.asText() for x in self])+')'
385
386 -class LDAPFilter_or(LDAPFilterSet):
387 tag = CLASS_CONTEXT|0x01 388
389 - def asText(self):
390 return '(|'+''.join([x.asText() for x in self])+')'
391
392 -class LDAPFilter_not(LDAPFilter):
393 tag = CLASS_CONTEXT|0x02 394
395 - def fromBER(klass, tag, content, berdecoder=None):
396 value, bytes = berDecodeObject(LDAPBERDecoderContext_Filter(fallback=berdecoder, inherit=berdecoder), content) 397 assert bytes == len(content) 398 399 r = klass(value=value, 400 tag=tag) 401 return r
402 fromBER = classmethod(fromBER) 403
404 - def __init__(self, value, tag=tag):
405 LDAPFilter.__init__(self, tag=tag) 406 assert value is not None 407 self.value=value
408
409 - def __repr__(self):
410 if self.tag==self.__class__.tag: 411 return self.__class__.__name__\ 412 +"(value=%s)"\ 413 %repr(self.value) 414 else: 415 return self.__class__.__name__\ 416 +"(value=%s, tag=%d)"\ 417 %(repr(self.value), self.tag)
418
419 - def __str__(self):
420 r=str(self.value) 421 return chr(self.identification())+int2berlen(len(r))+r
422
423 - def asText(self):
424 return '(!'+self.value.asText()+')'
425
426 -class LDAPFilter_equalityMatch(LDAPAttributeValueAssertion):
427 tag = CLASS_CONTEXT|0x03 428
429 - def asText(self):
430 return '('+self.attributeDesc.value+'=' \ 431 +escape(self.assertionValue.value)+')'
432
433 -class LDAPFilter_substrings_initial(LDAPString):
434 tag = CLASS_CONTEXT|0x00 435
436 - def asText(self):
437 return escape(self.value)
438 439
440 -class LDAPFilter_substrings_any(LDAPString):
441 tag = CLASS_CONTEXT|0x01 442
443 - def asText(self):
444 return escape(self.value)
445
446 -class LDAPFilter_substrings_final(LDAPString):
447 tag = CLASS_CONTEXT|0x02 448
449 - def asText(self):
450 return escape(self.value)
451
452 -class LDAPBERDecoderContext_Filter_substrings(BERDecoderContext):
453 Identities = { 454 LDAPFilter_substrings_initial.tag: LDAPFilter_substrings_initial, 455 LDAPFilter_substrings_any.tag: LDAPFilter_substrings_any, 456 LDAPFilter_substrings_final.tag: LDAPFilter_substrings_final, 457 }
458
459 -class LDAPFilter_substrings(BERSequence):
460 tag = CLASS_CONTEXT|0x04 461
462 - def fromBER(klass, tag, content, berdecoder=None):
463 l = berDecodeMultiple(content, LDAPBERDecoderContext_Filter_substrings(fallback=berdecoder)) 464 assert len(l) == 2 465 assert len(l[1])>=1 466 467 r = klass(type=l[0].value, 468 substrings=list(l[1]), 469 tag=tag) 470 return r
471 fromBER = classmethod(fromBER) 472
473 - def __init__(self, type=None, substrings=None, tag=None):
474 BERSequence.__init__(self, value=[], tag=tag) 475 assert type is not None 476 assert substrings is not None 477 self.type=type 478 self.substrings=substrings
479
480 - def __str__(self):
481 return str(BERSequence([ 482 LDAPString(self.type), 483 BERSequence(self.substrings)], tag=self.tag))
484
485 - def __repr__(self):
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
495 - def asText(self):
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
525 -class LDAPFilter_greaterOrEqual(LDAPAttributeValueAssertion):
526 tag = CLASS_CONTEXT|0x05 527
528 - def asText(self):
529 return '('+self.attributeDesc.value+'>=' \ 530 +escape(self.assertionValue.value)+')'
531
532 -class LDAPFilter_lessOrEqual(LDAPAttributeValueAssertion):
533 tag = CLASS_CONTEXT|0x06 534
535 - def asText(self):
536 return '('+self.attributeDesc.value+'<=' \ 537 +escape(self.assertionValue.value)+')'
538
539 -class LDAPFilter_present(LDAPAttributeDescription):
540 tag = CLASS_CONTEXT|0x07 541
542 - def asText(self):
543 return '(%s=*)' % self.value
544
545 -class LDAPFilter_approxMatch(LDAPAttributeValueAssertion):
546 tag = CLASS_CONTEXT|0x08 547 548
549 - def asText(self):
550 return '('+self.attributeDesc.value+'~=' \ 551 +escape(self.assertionValue.value)+')'
552
553 -class LDAPMatchingRuleId(LDAPString):
554 pass
555
556 -class LDAPAssertionValue(BEROctetString):
557 pass
558
559 -class LDAPMatchingRuleAssertion_matchingRule(LDAPMatchingRuleId):
560 tag = CLASS_CONTEXT|0x01 561 pass
562
563 -class LDAPMatchingRuleAssertion_type(LDAPAttributeDescription):
564 tag = CLASS_CONTEXT|0x02 565 pass
566
567 -class LDAPMatchingRuleAssertion_matchValue(LDAPAssertionValue):
568 tag = CLASS_CONTEXT|0x03 569 pass
570
571 -class LDAPMatchingRuleAssertion_dnAttributes(BERBoolean):
572 tag = CLASS_CONTEXT|0x04 573 pass
574
575 -class LDAPBERDecoderContext_MatchingRuleAssertion(BERDecoderContext):
576 Identities = { 577 LDAPMatchingRuleAssertion_matchingRule.tag: LDAPMatchingRuleAssertion_matchingRule, 578 LDAPMatchingRuleAssertion_type.tag: LDAPMatchingRuleAssertion_type, 579 LDAPMatchingRuleAssertion_matchValue.tag: LDAPMatchingRuleAssertion_matchValue, 580 LDAPMatchingRuleAssertion_dnAttributes.tag: LDAPMatchingRuleAssertion_dnAttributes, 581 }
582
583 -class LDAPMatchingRuleAssertion(BERSequence):
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):
624 BERSequence.__init__(self, value=[], tag=tag) 625 assert matchValue is not None 626 self.matchingRule=matchingRule 627 self.type=type 628 self.matchValue=matchValue 629 self.dnAttributes=dnAttributes 630 if not self.dnAttributes: 631 self.dnAttributes=None
632
633 - def __str__(self):
634 return str(BERSequence( 635 filter(lambda x: x is not None, [self.matchingRule, self.type, self.matchValue, self.dnAttributes]), tag=self.tag))
636
637 - def __repr__(self):
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
647 -class LDAPFilter_extensibleMatch(LDAPMatchingRuleAssertion):
648 tag = CLASS_CONTEXT|0x09 649 pass
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
677 -class LDAPSearchRequest(LDAPProtocolRequest, BERSequence):
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=[] #TODO AttributeDescriptionList 688 689 #TODO decode 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):
717 LDAPProtocolRequest.__init__(self) 718 BERSequence.__init__(self, [], tag=tag) 719 720 if baseObject is not None: 721 self.baseObject=baseObject 722 if scope is not None: 723 self.scope=scope 724 if derefAliases is not None: 725 self.derefAliases=derefAliases 726 if sizeLimit is not None: 727 self.sizeLimit=sizeLimit 728 if timeLimit is not None: 729 self.timeLimit=timeLimit 730 if typesOnly is not None: 731 self.typesOnly=typesOnly 732 if filter is not None: 733 self.filter=filter 734 if attributes is not None: 735 self.attributes=attributes
736
737 - def __str__(self):
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
749 - def __repr__(self):
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
794 - def __str__(self):
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
824 -class LDAPSearchResultDone(LDAPResult):
825 tag=CLASS_APPLICATION|0x05 826 827 pass
828
829 -class LDAPControls(BERSequence):
830 tag = CLASS_CONTEXT|0x00 831
832 - def fromBER(klass, tag, content, berdecoder=None):
833 l = berDecodeMultiple(content, LDAPBERDecoderContext_LDAPControls( 834 inherit=berdecoder)) 835 836 r = klass(l, tag=tag) 837 return r
838 fromBER = classmethod(fromBER)
839
840 -class LDAPControl(BERSequence):
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 # TODO is controlType, controlValue allowed without criticality? 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):
864 BERSequence.__init__(self, value=[], tag=tag) 865 assert controlType is not None 866 self.controlType = controlType 867 self.criticality = criticality 868 self.controlValue = controlValue
869
870 - def __str__(self):
871 self.data=[LDAPOID(self.controlType)] 872 if self.criticality is not None: 873 self.data.append(BERBoolean(self.criticality)) 874 if self.controlValue is not None: 875 self.data.append(BEROctetString(self.controlValue)) 876 return BERSequence.__str__(self)
877
878 -class LDAPBERDecoderContext_LDAPControls(BERDecoderContext):
879 Identities = { 880 LDAPControl.tag: LDAPControl, 881 }
882
883 -class LDAPBERDecoderContext_LDAPMessage(BERDecoderContext):
884 Identities = { 885 LDAPControls.tag: LDAPControls, 886 LDAPSearchResultReference.tag: LDAPSearchResultReference, 887 }
888
889 -class LDAPBERDecoderContext_TopLevel(BERDecoderContext):
890 Identities = { 891 BERSequence.tag: LDAPMessage, 892 }
893
894 -class LDAPModifyRequest(LDAPProtocolRequest, BERSequence):
895 tag=CLASS_APPLICATION|0x06 896 object = None 897 modification = None 898
899 - def fromBER(klass, tag, content, berdecoder=None):
900 l = berDecodeMultiple(content, berdecoder) 901 902 assert len(l) == 2 903 904 r = klass(object=l[0].value, 905 modification=l[1].data, 906 tag=tag) 907 return r
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
953 - def __str__(self):
954 l=[LDAPString(self.object)] 955 if self.modification is not None: 956 l.append(BERSequence(self.modification)) 957 return str(BERSequence(l, tag=self.tag))
958
959 - def __repr__(self):
960 if self.tag==self.__class__.tag: 961 return self.__class__.__name__+"(object=%s, modification=%s)"\ 962 %(repr(self.object), repr(self.modification)) 963 else: 964 return self.__class__.__name__+"(object=%s, modification=%s, tag=%d)" \ 965 %(repr(self.object), repr(self.modification), self.tag)
966 967
968 -class LDAPModifyResponse(LDAPResult):
969 tag = CLASS_APPLICATION|0x07
970
971 -class LDAPAddRequest(LDAPProtocolRequest, BERSequence):
972 tag = CLASS_APPLICATION|0x08 973
974 - def fromBER(klass, tag, content, berdecoder=None):
975 l = berDecodeMultiple(content, berdecoder) 976 977 r = klass(entry=l[0].value, 978 attributes=l[1], 979 tag=tag) 980 return r
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
1008 - def __str__(self):
1009 return str(BERSequence([ 1010 LDAPString(self.entry), 1011 BERSequence(map(BERSequence, self.attributes)), 1012 ], tag=self.tag))
1013
1014 - def __repr__(self):
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
1024 -class LDAPAddResponse(LDAPResult):
1025 tag = CLASS_APPLICATION|0x09
1026
1027 -class LDAPDelRequest(LDAPProtocolRequest, LDAPString):
1028 tag = CLASS_APPLICATION|0x0a 1029
1030 - def __init__(self, value=None, entry=None, tag=None):
1031 """ 1032 Initialize the object 1033 1034 l=LDAPDelRequest(entry='cn=foo,dc=example,dc=com') 1035 """ 1036 if entry is None and value is not None: 1037 entry = value 1038 LDAPProtocolRequest.__init__(self) 1039 LDAPString.__init__(self, value=entry, tag=tag)
1040
1041 - def __str__(self):
1042 return LDAPString.__str__(self)
1043
1044 - def __repr__(self):
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
1054 -class LDAPDelResponse(LDAPResult):
1055 tag = CLASS_APPLICATION|0x0b 1056 pass
1057 1058
1059 -class LDAPModifyDNResponse_newSuperior(LDAPString):
1060 tag = CLASS_CONTEXT|0x00 1061 1062 pass
1063
1064 -class LDAPBERDecoderContext_ModifyDNRequest(BERDecoderContext):
1065 Identities = { 1066 LDAPModifyDNResponse_newSuperior.tag: LDAPModifyDNResponse_newSuperior, 1067 }
1068
1069 -class LDAPModifyDNRequest(LDAPProtocolRequest, BERSequence):
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):
1078 l = berDecodeMultiple(content, LDAPBERDecoderContext_ModifyDNRequest(fallback=berdecoder)) 1079 1080 kw = {} 1081 try: 1082 kw['newSuperior'] = str(l[3].value) 1083 except IndexError: 1084 pass 1085 1086 r = klass(entry=str(l[0].value), 1087 newrdn=str(l[1].value), 1088 deleteoldrdn=l[2].value, 1089 tag=tag, 1090 **kw) 1091 return r
1092 fromBER = classmethod(fromBER) 1093
1094 - def __init__(self, entry, newrdn, deleteoldrdn, newSuperior=None, 1095 tag=None):
1096 """ 1097 Initialize the object 1098 1099 Example usage:: 1100 1101 l=LDAPModifyDNRequest(entry='cn=foo,dc=example,dc=com', 1102 newrdn='someAttr=value', 1103 deleteoldrdn=0) 1104 """ 1105 1106 LDAPProtocolRequest.__init__(self) 1107 BERSequence.__init__(self, [], tag=tag) 1108 assert entry is not None 1109 assert newrdn is not None 1110 assert deleteoldrdn is not None 1111 self.entry=entry 1112 self.newrdn=newrdn 1113 self.deleteoldrdn=deleteoldrdn 1114 self.newSuperior=newSuperior
1115
1116 - def __str__(self):
1117 l=[ 1118 LDAPString(self.entry), 1119 LDAPString(self.newrdn), 1120 BERBoolean(self.deleteoldrdn), 1121 ] 1122 if self.newSuperior is not None: 1123 l.append(LDAPString(self.newSuperior, tag=CLASS_CONTEXT|0)) 1124 return str(BERSequence(l, tag=self.tag))
1125
1126 - def __repr__(self):
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
1138 -class LDAPModifyDNResponse(LDAPResult):
1139 tag=CLASS_APPLICATION|13
1140 1141 #class LDAPCompareResponse(LDAPProtocolResponse): 1142 #class LDAPCompareRequest(LDAPProtocolRequest): 1143
1144 -class LDAPAbandonRequest(LDAPProtocolRequest, LDAPInteger):
1145 tag = CLASS_APPLICATION|0x10 1146 needs_answer=0 1147
1148 - def __init__(self, value=None, id=None, tag=None):
1149 """ 1150 Initialize the object 1151 1152 l=LDAPAbandonRequest(id=1) 1153 """ 1154 if id is None and value is not None: 1155 id = value 1156 LDAPProtocolRequest.__init__(self) 1157 LDAPInteger.__init__(self, value=id, tag=tag)
1158
1159 - def __str__(self):
1160 return LDAPInteger.__str__(self)
1161
1162 - def __repr__(self):
1163 if self.tag==self.__class__.tag: 1164 return self.__class__.__name__+"(id=%s)" \ 1165 %repr(self.value) 1166 else: 1167 return self.__class__.__name__ \ 1168 +"(id=%s, tag=%d)" \ 1169 %(repr(self.value), self.tag)
1170
1171 -class LDAPOID(BEROctetString):
1172 pass
1173
1174 -class LDAPResponseName(LDAPOID):
1175 tag = CLASS_CONTEXT|10
1176
1177 -class LDAPResponse(BEROctetString):
1178 tag = CLASS_CONTEXT|11
1179
1180 -class LDAPBERDecoderContext_LDAPExtendedRequest(BERDecoderContext):
1181 Identities = { 1182 CLASS_CONTEXT|0x00: BEROctetString, 1183 CLASS_CONTEXT|0x01: BEROctetString, 1184 }
1185
1186 -class LDAPExtendedRequest(LDAPProtocolRequest, BERSequence):
1187 tag = CLASS_APPLICATION|23 1188 1189 requestName = None 1190 requestValue = None 1191
1192 - def fromBER(klass, tag, content, berdecoder=None):
1193 l = berDecodeMultiple(content, 1194 LDAPBERDecoderContext_LDAPExtendedRequest( 1195 fallback=berdecoder)) 1196 1197 kw = {} 1198 try: 1199 kw['requestValue'] = l[1].value 1200 except IndexError: 1201 pass 1202 1203 r = klass(requestName=l[0].value, 1204 tag=tag, 1205 **kw) 1206 return r
1207 fromBER = classmethod(fromBER) 1208
1209 - def __init__(self, requestName=None, requestValue=None, 1210 tag=None):
1211 LDAPProtocolRequest.__init__(self) 1212 BERSequence.__init__(self, [], tag=tag) 1213 assert requestName is not None 1214 assert isinstance(requestName, basestring) 1215 assert requestValue is None or isinstance(requestValue, basestring) 1216 self.requestName=requestName 1217 self.requestValue=requestValue
1218
1219 - def __str__(self):
1220 l=[LDAPOID(self.requestName, tag=CLASS_CONTEXT|0)] 1221 if self.requestValue is not None: 1222 l.append(BEROctetString(str(self.requestValue), tag=CLASS_CONTEXT|1)) 1223 return str(BERSequence(l, tag=self.tag))
1224
1225 -class LDAPPasswordModifyRequest_userIdentity(BEROctetString):
1226 tag=CLASS_CONTEXT|0
1227 -class LDAPPasswordModifyRequest_oldPasswd(BEROctetString):
1228 tag=CLASS_CONTEXT|1
1229 -class LDAPPasswordModifyRequest_newPasswd(BEROctetString):
1230 tag=CLASS_CONTEXT|2
1231
1232 -class LDAPBERDecoderContext_LDAPPasswordModifyRequest(BERDecoderContext):
1233 Identities = { 1234 LDAPPasswordModifyRequest_userIdentity.tag: 1235 LDAPPasswordModifyRequest_userIdentity, 1236 1237 LDAPPasswordModifyRequest_oldPasswd.tag: 1238 LDAPPasswordModifyRequest_oldPasswd, 1239 1240 LDAPPasswordModifyRequest_newPasswd.tag: 1241 LDAPPasswordModifyRequest_newPasswd, 1242 }
1243
1244 -class LDAPPasswordModifyRequest(LDAPExtendedRequest):
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):
1250 assert (requestName is None 1251 or requestName == self.oid), \ 1252 '%s requestName was %s instead of %s' \ 1253 % (self.__class__.__name__, requestName, self.oid) 1254 #TODO genPasswd 1255 1256 l=[] 1257 if userIdentity is not None: 1258 l.append(LDAPPasswordModifyRequest_userIdentity(userIdentity)) 1259 if oldPasswd is not None: 1260 l.append(LDAPPasswordModifyRequest_oldPasswd(oldPasswd)) 1261 if newPasswd is not None: 1262 l.append(LDAPPasswordModifyRequest_newPasswd(newPasswd)) 1263 LDAPExtendedRequest.__init__( 1264 self, 1265 requestName=self.oid, 1266 requestValue=str(BERSequence(l)), 1267 tag=tag)
1268
1269 - def __repr__(self):
1270 l=[] 1271 # TODO userIdentity, oldPasswd, newPasswd 1272 if self.tag!=self.__class__.tag: 1273 l.append('tag=%d' % self.tag) 1274 return self.__class__.__name__+'('+', '.join(l)+')'
1275
1276 -class LDAPBERDecoderContext_LDAPExtendedResponse(BERDecoderContext):
1277 Identities = { 1278 LDAPResponseName.tag: LDAPResponseName, 1279 LDAPResponse.tag: LDAPResponse, 1280 }
1281
1282 -class LDAPExtendedResponse(LDAPResult):
1283 tag = CLASS_APPLICATION|0x18 1284 1285 responseName = None 1286 response = None 1287
1288 - def fromBER(klass, tag, content, berdecoder=None):
1289 l = berDecodeMultiple(content, LDAPBERDecoderContext_LDAPExtendedResponse( 1290 fallback=berdecoder)) 1291 1292 assert 3<=len(l)<=4 1293 1294 referral = None 1295 #if (l[3:] and isinstance(l[3], LDAPReferral)): 1296 #TODO support referrals 1297 #self.referral=self.data[0] 1298 1299 r = klass(resultCode=l[0].value, 1300 matchedDN=l[1].value, 1301 errorMessage=l[2].value, 1302 referral=referral, 1303 tag=tag) 1304 return r
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
1320 - def __str__(self):
1321 assert self.referral is None #TODO 1322 l=[BEREnumerated(self.resultCode), 1323 BEROctetString(self.matchedDN), 1324 BEROctetString(self.errorMessage), 1325 #TODO referral [3] Referral OPTIONAL 1326 ] 1327 if self.responseName is not None: 1328 l.append(LDAPOID(self.responseName, tag=CLASS_CONTEXT|0x0a)) 1329 if self.response is not None: 1330 l.append(BEROctetString(self.response, tag=CLASS_CONTEXT|0x0b)) 1331 return str(BERSequence(l, tag=self.tag))
1332
1333 -class LDAPStartTLSRequest(LDAPExtendedRequest):
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):
1342 assert (requestName is None 1343 or requestName == self.oid), \ 1344 '%s requestName was %s instead of %s' \ 1345 % (self.__class__.__name__, requestName, self.oid) 1346 1347 LDAPExtendedRequest.__init__( 1348 self, 1349 requestName=self.oid, 1350 tag=tag)
1351
1352 - def __repr__(self):
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