001 /* 002 * Copyright 2007-2014 UnboundID Corp. 003 * All Rights Reserved. 004 */ 005 /* 006 * Copyright (C) 2008-2014 UnboundID Corp. 007 * 008 * This program is free software; you can redistribute it and/or modify 009 * it under the terms of the GNU General Public License (GPLv2 only) 010 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only) 011 * as published by the Free Software Foundation. 012 * 013 * This program is distributed in the hope that it will be useful, 014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 016 * GNU General Public License for more details. 017 * 018 * You should have received a copy of the GNU General Public License 019 * along with this program; if not, see <http://www.gnu.org/licenses>. 020 */ 021 package com.unboundid.ldap.sdk; 022 023 024 025 import java.util.ArrayList; 026 027 import com.unboundid.asn1.ASN1OctetString; 028 import com.unboundid.asn1.ASN1StreamReader; 029 import com.unboundid.asn1.ASN1StreamReaderSequence; 030 031 import static com.unboundid.ldap.sdk.LDAPMessages.*; 032 import static com.unboundid.util.Debug.*; 033 import static com.unboundid.util.StaticUtils.*; 034 035 036 037 /** 038 * This class provides a data structure for holding information about the result 039 * of processing a bind operation. It provides generic bind response elements 040 * as described in the {@code LDAPResult} class, but may be overridden to 041 * provide more detailed information for specific types of bind requests. 042 */ 043 public class BindResult 044 extends LDAPResult 045 { 046 /** 047 * The BER type for the server SASL credentials element in the bind result. 048 */ 049 private static final byte TYPE_SERVER_SASL_CREDENTIALS = (byte) 0x87; 050 051 052 053 /** 054 * The serial version UID for this serializable class. 055 */ 056 private static final long serialVersionUID = 2211625049303605730L; 057 058 059 060 // The server SASL credentials from the response, if available. 061 private final ASN1OctetString serverSASLCredentials; 062 063 064 065 /** 066 * Creates a new bind result with the provided information. 067 * 068 * @param messageID The message ID for the LDAP message that is 069 * associated with this bind result. 070 * @param resultCode The result code from the response. 071 * @param diagnosticMessage The diagnostic message from the response, if 072 * available. 073 * @param matchedDN The matched DN from the response, if available. 074 * @param referralURLs The set of referral URLs from the response, if 075 * available. 076 * @param responseControls The set of controls from the response, if 077 * available. 078 */ 079 public BindResult(final int messageID, final ResultCode resultCode, 080 final String diagnosticMessage, final String matchedDN, 081 final String[] referralURLs, 082 final Control[] responseControls) 083 { 084 this(messageID, resultCode, diagnosticMessage, matchedDN, referralURLs, 085 responseControls, null); 086 } 087 088 089 090 /** 091 * Creates a new bind result with the provided information. 092 * 093 * @param messageID The message ID for the LDAP message that is 094 * associated with this bind result. 095 * @param resultCode The result code from the response. 096 * @param diagnosticMessage The diagnostic message from the response, if 097 * available. 098 * @param matchedDN The matched DN from the response, if 099 * available. 100 * @param referralURLs The set of referral URLs from the response, 101 * if available. 102 * @param responseControls The set of controls from the response, if 103 * available. 104 * @param serverSASLCredentials The server SASL credentials from the 105 * response, if available. 106 */ 107 public BindResult(final int messageID, final ResultCode resultCode, 108 final String diagnosticMessage, final String matchedDN, 109 final String[] referralURLs, 110 final Control[] responseControls, 111 final ASN1OctetString serverSASLCredentials) 112 { 113 super(messageID, resultCode, diagnosticMessage, matchedDN, referralURLs, 114 responseControls); 115 116 this.serverSASLCredentials = serverSASLCredentials; 117 } 118 119 120 121 /** 122 * Creates a new bind result from the provided generic LDAP result. 123 * 124 * @param ldapResult The LDAP result to use to create this bind result. 125 */ 126 public BindResult(final LDAPResult ldapResult) 127 { 128 super(ldapResult); 129 130 serverSASLCredentials = null; 131 } 132 133 134 135 /** 136 * Creates a new bind result from the provided {@code LDAPException}. 137 * 138 * @param exception The {@code LDAPException} to use to create this bind 139 * result. 140 */ 141 public BindResult(final LDAPException exception) 142 { 143 super(exception.toLDAPResult()); 144 145 serverSASLCredentials = null; 146 } 147 148 149 150 /** 151 * Creates a new bind result from the provided bind result. This constructor 152 * may be used in creating custom subclasses. 153 * 154 * @param bindResult The bind result to use to create this bind result. 155 */ 156 protected BindResult(final BindResult bindResult) 157 { 158 super(bindResult); 159 160 serverSASLCredentials = bindResult.serverSASLCredentials; 161 } 162 163 164 165 /** 166 * Creates a new bind result object with the provided message ID and with the 167 * protocol op and controls read from the given ASN.1 stream reader. 168 * 169 * @param messageID The LDAP message ID for the LDAP message that is 170 * associated with this bind result. 171 * @param messageSequence The ASN.1 stream reader sequence used in the 172 * course of reading the LDAP message elements. 173 * @param reader The ASN.1 stream reader from which to read the 174 * protocol op and controls. 175 * 176 * @return The decoded bind result. 177 * 178 * @throws LDAPException If a problem occurs while reading or decoding data 179 * from the ASN.1 stream reader. 180 */ 181 static BindResult readBindResultFrom(final int messageID, 182 final ASN1StreamReaderSequence messageSequence, 183 final ASN1StreamReader reader) 184 throws LDAPException 185 { 186 try 187 { 188 final ASN1StreamReaderSequence protocolOpSequence = 189 reader.beginSequence(); 190 final ResultCode resultCode = ResultCode.valueOf(reader.readEnumerated()); 191 192 String matchedDN = reader.readString(); 193 if (matchedDN.length() == 0) 194 { 195 matchedDN = null; 196 } 197 198 String diagnosticMessage = reader.readString(); 199 if (diagnosticMessage.length() == 0) 200 { 201 diagnosticMessage = null; 202 } 203 204 String[] referralURLs = null; 205 ASN1OctetString serverSASLCredentials = null; 206 while (protocolOpSequence.hasMoreElements()) 207 { 208 final byte type = (byte) reader.peek(); 209 switch (type) 210 { 211 case TYPE_REFERRAL_URLS: 212 final ArrayList<String> refList = new ArrayList<String>(1); 213 final ASN1StreamReaderSequence refSequence = reader.beginSequence(); 214 while (refSequence.hasMoreElements()) 215 { 216 refList.add(reader.readString()); 217 } 218 referralURLs = new String[refList.size()]; 219 refList.toArray(referralURLs); 220 break; 221 222 case TYPE_SERVER_SASL_CREDENTIALS: 223 serverSASLCredentials = 224 new ASN1OctetString(type, reader.readBytes()); 225 break; 226 227 default: 228 throw new LDAPException(ResultCode.DECODING_ERROR, 229 ERR_BIND_RESULT_INVALID_ELEMENT.get(toHex(type))); 230 } 231 } 232 233 Control[] controls = NO_CONTROLS; 234 if (messageSequence.hasMoreElements()) 235 { 236 final ArrayList<Control> controlList = new ArrayList<Control>(1); 237 final ASN1StreamReaderSequence controlSequence = reader.beginSequence(); 238 while (controlSequence.hasMoreElements()) 239 { 240 controlList.add(Control.readFrom(reader)); 241 } 242 243 controls = new Control[controlList.size()]; 244 controlList.toArray(controls); 245 } 246 247 return new BindResult(messageID, resultCode, diagnosticMessage, matchedDN, 248 referralURLs, controls, serverSASLCredentials); 249 } 250 catch (LDAPException le) 251 { 252 debugException(le); 253 throw le; 254 } 255 catch (Exception e) 256 { 257 debugException(e); 258 throw new LDAPException(ResultCode.DECODING_ERROR, 259 ERR_BIND_RESULT_CANNOT_DECODE.get(getExceptionMessage(e)), e); 260 } 261 } 262 263 264 265 /** 266 * Retrieves the server SASL credentials from the bind result, if available. 267 * 268 * @return The server SASL credentials from the bind response, or 269 * {@code null} if none were provided. 270 */ 271 public ASN1OctetString getServerSASLCredentials() 272 { 273 return serverSASLCredentials; 274 } 275 }