001 /*
002 * Copyright 2007-2016 UnboundID Corp.
003 * All Rights Reserved.
004 */
005 /*
006 * Copyright (C) 2008-2016 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 import java.util.List;
027
028 import com.unboundid.asn1.ASN1OctetString;
029 import com.unboundid.util.NotMutable;
030 import com.unboundid.util.ThreadSafety;
031 import com.unboundid.util.ThreadSafetyLevel;
032
033
034
035 /**
036 * This class provides a SASL ANONYMOUS bind request implementation as described
037 * in <A HREF="http://www.ietf.org/rfc/rfc4505.txt">RFC 4505</A>. Binding with
038 * The ANONYMOUS SASL mechanism is essentially equivalent to using an anonymous
039 * simple bind (i.e., a simple bind with an empty password), although the SASL
040 * ANONYMOUS mechanism does provide the ability to include additional trace
041 * information with the request that may be logged or otherwise handled by
042 * the server.
043 * <BR><BR>
044 * <H2>Example</H2>
045 * The following example demonstrates the process for performing an ANONYMOUS
046 * bind, including a trace string of "Demo Application" against a directory
047 * server:
048 * <PRE>
049 * ANONYMOUSBindRequest bindRequest =
050 * new ANONYMOUSBindRequest("Demo Application");
051 * BindResult bindResult;
052 * try
053 * {
054 * bindResult = connection.bind(bindRequest);
055 * // If we get here, then the bind was successful.
056 * }
057 * catch (LDAPException le)
058 * {
059 * // The bind failed for some reason.
060 * bindResult = new BindResult(le.toLDAPResult());
061 * ResultCode resultCode = le.getResultCode();
062 * String errorMessageFromServer = le.getDiagnosticMessage();
063 * }
064 * </PRE>
065 */
066 @NotMutable()
067 @ThreadSafety(level=ThreadSafetyLevel.NOT_THREADSAFE)
068 public final class ANONYMOUSBindRequest
069 extends SASLBindRequest
070 {
071 /**
072 * The name for the ANONYMOUS SASL mechanism.
073 */
074 public static final String ANONYMOUS_MECHANISM_NAME = "ANONYMOUS";
075
076
077
078 /**
079 * The serial version UID for this serializable class.
080 */
081 private static final long serialVersionUID = 4259102841471750866L;
082
083
084
085 // The trace string that should be included in the bind request, if available.
086 private final String traceString;
087
088
089
090 /**
091 * Creates a new SASL ANONYMOUS bind request with no trace string and no
092 * controls.
093 */
094 public ANONYMOUSBindRequest()
095 {
096 this(null, NO_CONTROLS);
097 }
098
099
100
101 /**
102 * Creates a new SASL ANONYMOUS bind request with the provided trace string
103 * and no controls.
104 *
105 * @param traceString The trace string to include in the bind request, or
106 * {@code null} if no trace string is to be provided.
107 */
108 public ANONYMOUSBindRequest(final String traceString)
109 {
110 this(traceString, NO_CONTROLS);
111 }
112
113
114
115 /**
116 * Creates a new SASL ANONYMOUS bind request with the provided set of controls
117 * and no trace string.
118 *
119 * @param controls The set of controls to include in the request.
120 */
121 public ANONYMOUSBindRequest(final Control... controls)
122 {
123 this(null, controls);
124 }
125
126
127
128 /**
129 * Creates a new SASL ANONYMOUS bind request with the provided trace string
130 * and controls.
131 *
132 * @param traceString The trace string to include in the bind request, or
133 * {@code null} if no trace string is to be provided.
134 * @param controls The set of controls to include in the request.
135 */
136 public ANONYMOUSBindRequest(final String traceString,
137 final Control... controls)
138 {
139 super(controls);
140
141 this.traceString = traceString;
142 }
143
144
145
146 /**
147 * {@inheritDoc}
148 */
149 @Override()
150 public String getSASLMechanismName()
151 {
152 return ANONYMOUS_MECHANISM_NAME;
153 }
154
155
156
157 /**
158 * Retrieves the trace string that will be included with the bind request.
159 *
160 * @return The trace string that will be included with the bind request, or
161 * {@code null} if there is to be no trace string.
162 */
163 public String getTraceString()
164 {
165 return traceString;
166 }
167
168
169
170 /**
171 * Sends this bind request to the target server over the provided connection
172 * and returns the corresponding response.
173 *
174 * @param connection The connection to use to send this bind request to the
175 * server and read the associated response.
176 * @param depth The current referral depth for this request. It should
177 * always be one for the initial request, and should only
178 * be incremented when following referrals.
179 *
180 * @return The bind response read from the server.
181 *
182 * @throws LDAPException If a problem occurs while sending the request or
183 * reading the response.
184 */
185 @Override()
186 protected BindResult process(final LDAPConnection connection, final int depth)
187 throws LDAPException
188 {
189 ASN1OctetString credentials = null;
190 if ((traceString == null) || (traceString.length() == 0))
191 {
192 credentials = new ASN1OctetString(traceString);
193 }
194
195 return sendBindRequest(connection, null, credentials, getControls(),
196 getResponseTimeoutMillis(connection));
197 }
198
199
200
201 /**
202 * {@inheritDoc}
203 */
204 @Override()
205 public ANONYMOUSBindRequest getRebindRequest(final String host,
206 final int port)
207 {
208 return new ANONYMOUSBindRequest(traceString, getControls());
209 }
210
211
212
213 /**
214 * {@inheritDoc}
215 */
216 @Override()
217 public ANONYMOUSBindRequest duplicate()
218 {
219 return duplicate(getControls());
220 }
221
222
223
224 /**
225 * {@inheritDoc}
226 */
227 @Override()
228 public ANONYMOUSBindRequest duplicate(final Control[] controls)
229 {
230 final ANONYMOUSBindRequest bindRequest =
231 new ANONYMOUSBindRequest(traceString, controls);
232 bindRequest.setResponseTimeoutMillis(getResponseTimeoutMillis(null));
233 return bindRequest;
234 }
235
236
237
238 /**
239 * {@inheritDoc}
240 */
241 @Override()
242 public void toString(final StringBuilder buffer)
243 {
244 buffer.append("ANONYMOUSBindRequest(");
245 if (traceString != null)
246 {
247 buffer.append(", trace='");
248 buffer.append(traceString);
249 buffer.append('\'');
250 }
251
252 final Control[] controls = getControls();
253 if (controls.length > 0)
254 {
255 buffer.append(", controls={");
256 for (int i=0; i < controls.length; i++)
257 {
258 if (i > 0)
259 {
260 buffer.append(", ");
261 }
262
263 buffer.append(controls[i]);
264 }
265 buffer.append('}');
266 }
267
268 buffer.append(')');
269 }
270
271
272
273 /**
274 * {@inheritDoc}
275 */
276 @Override()
277 public void toCode(final List<String> lineList, final String requestID,
278 final int indentSpaces, final boolean includeProcessing)
279 {
280 // Create the request variable.
281 final ArrayList<ToCodeArgHelper> constructorArgs =
282 new ArrayList<ToCodeArgHelper>(2);
283 constructorArgs.add(ToCodeArgHelper.createString(traceString,
284 "Trace String"));
285
286 final Control[] controls = getControls();
287 if (controls.length > 0)
288 {
289 constructorArgs.add(ToCodeArgHelper.createControlArray(controls,
290 "Bind Controls"));
291 }
292
293 ToCodeHelper.generateMethodCall(lineList, indentSpaces,
294 "ANONYMOUSBindRequest", requestID + "Request",
295 "new ANONYMOUSBindRequest", constructorArgs);
296
297
298 // Add lines for processing the request and obtaining the result.
299 if (includeProcessing)
300 {
301 // Generate a string with the appropriate indent.
302 final StringBuilder buffer = new StringBuilder();
303 for (int i=0; i < indentSpaces; i++)
304 {
305 buffer.append(' ');
306 }
307 final String indent = buffer.toString();
308
309 lineList.add("");
310 lineList.add(indent + "try");
311 lineList.add(indent + '{');
312 lineList.add(indent + " BindResult " + requestID +
313 "Result = connection.bind(" + requestID + "Request);");
314 lineList.add(indent + " // The bind was processed successfully.");
315 lineList.add(indent + '}');
316 lineList.add(indent + "catch (LDAPException e)");
317 lineList.add(indent + '{');
318 lineList.add(indent + " // The bind failed. Maybe the following will " +
319 "help explain why.");
320 lineList.add(indent + " // Note that the connection is now likely in " +
321 "an unauthenticated state.");
322 lineList.add(indent + " ResultCode resultCode = e.getResultCode();");
323 lineList.add(indent + " String message = e.getMessage();");
324 lineList.add(indent + " String matchedDN = e.getMatchedDN();");
325 lineList.add(indent + " String[] referralURLs = e.getReferralURLs();");
326 lineList.add(indent + " Control[] responseControls = " +
327 "e.getResponseControls();");
328 lineList.add(indent + '}');
329 }
330 }
331 }