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 }