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