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