001 /* 002 * CDDL HEADER START 003 * 004 * The contents of this file are subject to the terms of the 005 * Common Development and Distribution License, Version 1.0 only 006 * (the "License"). You may not use this file except in compliance 007 * with the License. 008 * 009 * You can obtain a copy of the license at 010 * trunk/opends/resource/legal-notices/OpenDS.LICENSE 011 * or https://OpenDS.dev.java.net/OpenDS.LICENSE. 012 * See the License for the specific language governing permissions 013 * and limitations under the License. 014 * 015 * When distributing Covered Code, include this CDDL HEADER in each 016 * file and include the License file at 017 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, 018 * add the following below this CDDL HEADER, with the fields enclosed 019 * by brackets "[]" replaced with your own identifying information: 020 * Portions Copyright [yyyy] [name of copyright owner] 021 * 022 * CDDL HEADER END 023 * 024 * 025 * Copyright 2006-2008 Sun Microsystems, Inc. 026 */ 027 package org.opends.server.protocols.ldap; 028 import org.opends.messages.Message; 029 030 031 032 import java.util.ArrayList; 033 import java.util.Iterator; 034 import java.util.List; 035 036 import org.opends.server.protocols.asn1.ASN1Element; 037 import org.opends.server.protocols.asn1.ASN1Enumerated; 038 import org.opends.server.protocols.asn1.ASN1OctetString; 039 import org.opends.server.protocols.asn1.ASN1Sequence; 040 import org.opends.server.types.DN; 041 import org.opends.server.types.DebugLogLevel; 042 import org.opends.server.types.LDAPException; 043 044 import static org.opends.server.loggers.debug.DebugLogger.*; 045 import org.opends.server.loggers.debug.DebugTracer; 046 import static org.opends.messages.ProtocolMessages.*; 047 import static org.opends.server.protocols.ldap.LDAPConstants.*; 048 import static org.opends.server.protocols.ldap.LDAPResultCode.*; 049 import static org.opends.server.util.ServerConstants.*; 050 051 052 053 /** 054 * This class defines the structures and methods for an LDAP delete response 055 * protocol op, which is used to provide information about the result of 056 * processing a delete request. 057 */ 058 public class BindResponseProtocolOp 059 extends ProtocolOp 060 { 061 /** 062 * The tracer object for the debug logger. 063 */ 064 private static final DebugTracer TRACER = getTracer(); 065 066 // The server SASL credentials for this response. 067 private ASN1OctetString serverSASLCredentials; 068 069 // The matched DN for this response. 070 private DN matchedDN; 071 072 // The result code for this response. 073 private int resultCode; 074 075 // The set of referral URLs for this response. 076 private List<String> referralURLs; 077 078 // The error message for this response. 079 private Message errorMessage; 080 081 082 083 /** 084 * Creates a new bind response protocol op with the provided result code. 085 * 086 * @param resultCode The result code for this response. 087 */ 088 public BindResponseProtocolOp(int resultCode) 089 { 090 this.resultCode = resultCode; 091 092 errorMessage = null; 093 matchedDN = null; 094 referralURLs = null; 095 serverSASLCredentials = null; 096 } 097 098 099 100 /** 101 * Creates a new bind response protocol op with the provided result code and 102 * error message. 103 * 104 * @param resultCode The result code for this response. 105 * @param errorMessage The error message for this response. 106 */ 107 public BindResponseProtocolOp(int resultCode, Message errorMessage) 108 { 109 this.resultCode = resultCode; 110 this.errorMessage = errorMessage; 111 112 matchedDN = null; 113 referralURLs = null; 114 serverSASLCredentials = null; 115 } 116 117 118 119 /** 120 * Creates a new bind response protocol op with the provided information. 121 * 122 * @param resultCode The result code for this response. 123 * @param errorMessage The error message for this response. 124 * @param matchedDN The matched DN for this response. 125 * @param referralURLs The referral URLs for this response. 126 */ 127 public BindResponseProtocolOp(int resultCode, Message errorMessage, 128 DN matchedDN, List<String> referralURLs) 129 { 130 this.resultCode = resultCode; 131 this.errorMessage = errorMessage; 132 this.matchedDN = matchedDN; 133 this.referralURLs = referralURLs; 134 135 serverSASLCredentials = null; 136 } 137 138 139 140 /** 141 * Creates a new bind response protocol op with the provided information. 142 * 143 * @param resultCode The result code for this response. 144 * @param errorMessage The error message for this response. 145 * @param matchedDN The matched DN for this response. 146 * @param referralURLs The referral URLs for this response. 147 * @param serverSASLCredentials The server SASL credentials for this 148 */ 149 public BindResponseProtocolOp(int resultCode, Message errorMessage, 150 DN matchedDN, List<String> referralURLs, 151 ASN1OctetString serverSASLCredentials) 152 { 153 this.resultCode = resultCode; 154 this.errorMessage = errorMessage; 155 this.matchedDN = matchedDN; 156 this.referralURLs = referralURLs; 157 this.serverSASLCredentials = serverSASLCredentials; 158 } 159 160 161 162 /** 163 * Retrieves the result code for this response. 164 * 165 * @return The result code for this response. 166 */ 167 public int getResultCode() 168 { 169 return resultCode; 170 } 171 172 173 174 /** 175 * Specifies the result code for this response. 176 * 177 * @param resultCode The result code for this response. 178 */ 179 public void setResultCode(int resultCode) 180 { 181 this.resultCode = resultCode; 182 } 183 184 185 186 /** 187 * Retrieves the error message for this response. 188 * 189 * @return The error message for this response, or <CODE>null</CODE> if none 190 * is available. 191 */ 192 public Message getErrorMessage() 193 { 194 return errorMessage; 195 } 196 197 198 199 /** 200 * Specifies the error message for this response. 201 * 202 * @param errorMessage The error message for this response. 203 */ 204 public void setErrorMessage(Message errorMessage) 205 { 206 this.errorMessage = errorMessage; 207 } 208 209 210 211 /** 212 * Retrieves the matched DN for this response. 213 * 214 * @return The matched DN for this response, or <CODE>null</CODE> if none is 215 * available. 216 */ 217 public DN getMatchedDN() 218 { 219 return matchedDN; 220 } 221 222 223 224 /** 225 * Specifies the matched DN for this response. 226 * 227 * @param matchedDN The matched DN for this response. 228 */ 229 public void setMatchedDN(DN matchedDN) 230 { 231 this.matchedDN = matchedDN; 232 } 233 234 235 236 /** 237 * Retrieves the set of referral URLs for this response. 238 * 239 * @return The set of referral URLs for this response, or <CODE>null</CODE> 240 * if none are available. 241 */ 242 public List<String> getReferralURLs() 243 { 244 return referralURLs; 245 } 246 247 248 249 /** 250 * Specifies the set of referral URLs for this response. 251 * 252 * @param referralURLs The set of referral URLs for this response. 253 */ 254 public void setReferralURLs(List<String> referralURLs) 255 { 256 this.referralURLs = referralURLs; 257 } 258 259 260 261 /** 262 * Retrieves the server SASL credentials for this response. 263 * 264 * @return The server SASL credentials for this response, or 265 * <CODE>null</CODE> if there are none. 266 */ 267 public ASN1OctetString getServerSASLCredentials() 268 { 269 return serverSASLCredentials; 270 } 271 272 273 274 /** 275 * Specifies the server SASL credentials for this response. 276 * 277 * @param serverSASLCredentials The server SASL credentials for this 278 * response. 279 */ 280 public void setServerSASLCredentials(ASN1OctetString serverSASLCredentials) 281 { 282 this.serverSASLCredentials = serverSASLCredentials; 283 } 284 285 286 287 /** 288 * Retrieves the BER type for this protocol op. 289 * 290 * @return The BER type for this protocol op. 291 */ 292 public byte getType() 293 { 294 return OP_TYPE_BIND_RESPONSE; 295 } 296 297 298 299 /** 300 * Retrieves the name for this protocol op type. 301 * 302 * @return The name for this protocol op type. 303 */ 304 public String getProtocolOpName() 305 { 306 return "Bind Response"; 307 } 308 309 310 311 /** 312 * Encodes this protocol op to an ASN.1 element suitable for including in an 313 * LDAP message. 314 * 315 * @return The ASN.1 element containing the encoded protocol op. 316 */ 317 public ASN1Element encode() 318 { 319 ArrayList<ASN1Element> elements = new ArrayList<ASN1Element>(5); 320 elements.add(new ASN1Enumerated(resultCode)); 321 322 if (matchedDN == null) 323 { 324 elements.add(new ASN1OctetString()); 325 } 326 else 327 { 328 elements.add(new ASN1OctetString(matchedDN.toString())); 329 } 330 331 elements.add(new ASN1OctetString(errorMessage)); 332 333 if ((referralURLs != null) && (! referralURLs.isEmpty())) 334 { 335 ArrayList<ASN1Element> referralElements = 336 new ArrayList<ASN1Element>(referralURLs.size()); 337 338 for (String s : referralURLs) 339 { 340 referralElements.add(new ASN1OctetString(s)); 341 } 342 343 elements.add(new ASN1Sequence(TYPE_REFERRAL_SEQUENCE, referralElements)); 344 } 345 346 if (serverSASLCredentials != null) 347 { 348 serverSASLCredentials.setType(TYPE_SERVER_SASL_CREDENTIALS); 349 elements.add(serverSASLCredentials); 350 } 351 352 return new ASN1Sequence(OP_TYPE_BIND_RESPONSE, elements); 353 } 354 355 356 357 /** 358 * Decodes the provided ASN.1 element as a bind response protocol op. 359 * 360 * @param element The ASN.1 element to decode. 361 * 362 * @return The decoded bind response protocol op. 363 * 364 * @throws LDAPException If a problem occurs while attempting to decode the 365 * ASN.1 element to a protocol op. 366 */ 367 public static BindResponseProtocolOp decodeBindResponse(ASN1Element element) 368 throws LDAPException 369 { 370 ArrayList<ASN1Element> elements; 371 try 372 { 373 elements = element.decodeAsSequence().elements(); 374 } 375 catch (Exception e) 376 { 377 if (debugEnabled()) 378 { 379 TRACER.debugCaught(DebugLogLevel.ERROR, e); 380 } 381 382 Message message = ERR_LDAP_RESULT_DECODE_SEQUENCE.get(String.valueOf(e)); 383 throw new LDAPException(PROTOCOL_ERROR, message, e); 384 } 385 386 387 int numElements = elements.size(); 388 if ((numElements < 3) || (numElements > 5)) 389 { 390 Message message = 391 ERR_LDAP_BIND_RESULT_DECODE_INVALID_ELEMENT_COUNT.get(numElements); 392 throw new LDAPException(PROTOCOL_ERROR, message); 393 } 394 395 396 int resultCode; 397 try 398 { 399 resultCode = elements.get(0).decodeAsInteger().intValue(); 400 } 401 catch (Exception e) 402 { 403 if (debugEnabled()) 404 { 405 TRACER.debugCaught(DebugLogLevel.ERROR, e); 406 } 407 408 Message message = 409 ERR_LDAP_RESULT_DECODE_RESULT_CODE.get(String.valueOf(e)); 410 throw new LDAPException(PROTOCOL_ERROR, message, e); 411 } 412 413 414 DN matchedDN; 415 try 416 { 417 String dnString = elements.get(1).decodeAsOctetString().stringValue(); 418 if (dnString.length() == 0) 419 { 420 matchedDN = null; 421 } 422 else 423 { 424 matchedDN = DN.decode(dnString); 425 } 426 } 427 catch (Exception e) 428 { 429 if (debugEnabled()) 430 { 431 TRACER.debugCaught(DebugLogLevel.ERROR, e); 432 } 433 434 Message message = 435 ERR_LDAP_RESULT_DECODE_MATCHED_DN.get(String.valueOf(e)); 436 throw new LDAPException(PROTOCOL_ERROR, message, e); 437 } 438 439 440 Message errorMessage; 441 try 442 { 443 errorMessage = 444 Message.raw(elements.get(2).decodeAsOctetString().stringValue()); 445 if (errorMessage.length() == 0) 446 { 447 errorMessage = null; 448 } 449 } 450 catch (Exception e) 451 { 452 if (debugEnabled()) 453 { 454 TRACER.debugCaught(DebugLogLevel.ERROR, e); 455 } 456 457 Message message = 458 ERR_LDAP_RESULT_DECODE_ERROR_MESSAGE.get(String.valueOf(e)); 459 throw new LDAPException(PROTOCOL_ERROR, message, e); 460 } 461 462 463 ArrayList<String> referralURLs; 464 ASN1OctetString serverSASLCredentials; 465 switch (numElements) 466 { 467 case 4: 468 element = elements.get(3); 469 switch (element.getType()) 470 { 471 case TYPE_REFERRAL_SEQUENCE: 472 serverSASLCredentials = null; 473 474 try 475 { 476 ArrayList<ASN1Element> referralElements = 477 element.decodeAsSequence().elements(); 478 referralURLs = new ArrayList<String>(referralElements.size()); 479 480 for (ASN1Element e : referralElements) 481 { 482 referralURLs.add(e.decodeAsOctetString().stringValue()); 483 } 484 } 485 catch (Exception e) 486 { 487 if (debugEnabled()) 488 { 489 TRACER.debugCaught(DebugLogLevel.ERROR, e); 490 } 491 492 Message message = 493 ERR_LDAP_RESULT_DECODE_REFERRALS.get(String.valueOf(e)); 494 throw new LDAPException(PROTOCOL_ERROR, message, e); 495 } 496 497 break; 498 case TYPE_SERVER_SASL_CREDENTIALS: 499 referralURLs = null; 500 501 try 502 { 503 serverSASLCredentials = element.decodeAsOctetString(); 504 } 505 catch (Exception e) 506 { 507 if (debugEnabled()) 508 { 509 TRACER.debugCaught(DebugLogLevel.ERROR, e); 510 } 511 512 Message message = 513 ERR_LDAP_BIND_RESULT_DECODE_SERVER_SASL_CREDENTIALS. 514 get(String.valueOf(e)); 515 throw new LDAPException(PROTOCOL_ERROR, message, e); 516 } 517 518 break; 519 default: 520 Message message = 521 ERR_LDAP_BIND_RESULT_DECODE_INVALID_TYPE.get(element.getType()); 522 throw new LDAPException(PROTOCOL_ERROR, message); 523 } 524 break; 525 case 5: 526 try 527 { 528 ArrayList<ASN1Element> referralElements = 529 elements.get(3).decodeAsSequence().elements(); 530 referralURLs = new ArrayList<String>(referralElements.size()); 531 532 for (ASN1Element e : referralElements) 533 { 534 referralURLs.add(e.decodeAsOctetString().stringValue()); 535 } 536 } 537 catch (Exception e) 538 { 539 if (debugEnabled()) 540 { 541 TRACER.debugCaught(DebugLogLevel.ERROR, e); 542 } 543 544 Message message = 545 ERR_LDAP_RESULT_DECODE_REFERRALS.get(String.valueOf(e)); 546 throw new LDAPException(PROTOCOL_ERROR, message, e); 547 } 548 549 try 550 { 551 serverSASLCredentials = elements.get(4).decodeAsOctetString(); 552 } 553 catch (Exception e) 554 { 555 if (debugEnabled()) 556 { 557 TRACER.debugCaught(DebugLogLevel.ERROR, e); 558 } 559 560 Message message = ERR_LDAP_BIND_RESULT_DECODE_SERVER_SASL_CREDENTIALS. 561 get(String.valueOf(e)); 562 throw new LDAPException(PROTOCOL_ERROR, message, e); 563 } 564 565 break; 566 default: 567 referralURLs = null; 568 serverSASLCredentials = null; 569 break; 570 } 571 572 573 return new BindResponseProtocolOp(resultCode, errorMessage, matchedDN, 574 referralURLs, serverSASLCredentials); 575 } 576 577 578 579 /** 580 * Appends a string representation of this LDAP protocol op to the provided 581 * buffer. 582 * 583 * @param buffer The buffer to which the string should be appended. 584 */ 585 public void toString(StringBuilder buffer) 586 { 587 buffer.append("BindResponse(resultCode="); 588 buffer.append(resultCode); 589 590 if ((errorMessage != null) && (errorMessage.length() > 0)) 591 { 592 buffer.append(", errorMessage="); 593 buffer.append(errorMessage); 594 } 595 596 if (matchedDN != null) 597 { 598 buffer.append(", matchedDN="); 599 buffer.append(matchedDN.toString()); 600 } 601 602 if ((referralURLs != null) && (! referralURLs.isEmpty())) 603 { 604 buffer.append(", referralURLs={"); 605 606 Iterator<String> iterator = referralURLs.iterator(); 607 buffer.append(iterator.next()); 608 609 while (iterator.hasNext()) 610 { 611 buffer.append(", "); 612 buffer.append(iterator.next()); 613 } 614 615 buffer.append("}"); 616 } 617 618 if (serverSASLCredentials != null) 619 { 620 buffer.append(", serverSASLCredentials="); 621 serverSASLCredentials.toString(buffer); 622 } 623 624 buffer.append(")"); 625 } 626 627 628 629 /** 630 * Appends a multi-line string representation of this LDAP protocol op to the 631 * provided buffer. 632 * 633 * @param buffer The buffer to which the information should be appended. 634 * @param indent The number of spaces from the margin that the lines should 635 * be indented. 636 */ 637 public void toString(StringBuilder buffer, int indent) 638 { 639 StringBuilder indentBuf = new StringBuilder(indent); 640 for (int i=0 ; i < indent; i++) 641 { 642 indentBuf.append(' '); 643 } 644 645 buffer.append(indentBuf); 646 buffer.append("Bind Response"); 647 buffer.append(EOL); 648 649 buffer.append(indentBuf); 650 buffer.append(" Result Code: "); 651 buffer.append(resultCode); 652 buffer.append(EOL); 653 654 if (errorMessage != null) 655 { 656 buffer.append(indentBuf); 657 buffer.append(" Error Message: "); 658 buffer.append(errorMessage); 659 buffer.append(EOL); 660 } 661 662 if (matchedDN != null) 663 { 664 buffer.append(indentBuf); 665 buffer.append(" Matched DN: "); 666 matchedDN.toString(buffer); 667 buffer.append(EOL); 668 } 669 670 if ((referralURLs != null) && (! referralURLs.isEmpty())) 671 { 672 buffer.append(indentBuf); 673 buffer.append(" Referral URLs: "); 674 buffer.append(EOL); 675 676 for (String s : referralURLs) 677 { 678 buffer.append(indentBuf); 679 buffer.append(" "); 680 buffer.append(s); 681 buffer.append(EOL); 682 } 683 } 684 685 if (serverSASLCredentials != null) 686 { 687 buffer.append(indentBuf); 688 buffer.append(" Server SASL Credentials:"); 689 buffer.append(EOL); 690 691 serverSASLCredentials.toString(buffer, indent+4); 692 } 693 } 694 } 695