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 */
021package com.unboundid.ldap.sdk;
022
023
024
025import com.unboundid.asn1.ASN1OctetString;
026import com.unboundid.util.NotMutable;
027import com.unboundid.util.ThreadSafety;
028import com.unboundid.util.ThreadSafetyLevel;
029
030
031
032/**
033 * This class provides a SASL ANONYMOUS bind request implementation as described
034 * in <A HREF="http://www.ietf.org/rfc/rfc4505.txt">RFC 4505</A>.  Binding with
035 * The ANONYMOUS SASL mechanism is essentially equivalent to using an anonymous
036 * simple bind (i.e., a simple bind with an empty password), although the SASL
037 * ANONYMOUS mechanism does provide the ability to include additional trace
038 * information with the request that may be logged or otherwise handled by
039 * the server.
040 * <BR><BR>
041 * <H2>Example</H2>
042 * The following example demonstrates the process for performing an ANONYMOUS
043 * bind, including a trace string of "Demo Application" against a directory
044 * server:
045 * <PRE>
046 * ANONYMOUSBindRequest bindRequest =
047 *      new ANONYMOUSBindRequest("Demo Application");
048 * BindResult bindResult;
049 * try
050 * {
051 *   bindResult = connection.bind(bindRequest);
052 *   // If we get here, then the bind was successful.
053 * }
054 * catch (LDAPException le)
055 * {
056 *   // The bind failed for some reason.
057 *   bindResult = new BindResult(le.toLDAPResult());
058 *   ResultCode resultCode = le.getResultCode();
059 *   String errorMessageFromServer = le.getDiagnosticMessage();
060 * }
061 * </PRE>
062 */
063@NotMutable()
064@ThreadSafety(level=ThreadSafetyLevel.NOT_THREADSAFE)
065public final class ANONYMOUSBindRequest
066       extends SASLBindRequest
067{
068  /**
069   * The name for the ANONYMOUS SASL mechanism.
070   */
071  public static final String ANONYMOUS_MECHANISM_NAME = "ANONYMOUS";
072
073
074
075  /**
076   * The serial version UID for this serializable class.
077   */
078  private static final long serialVersionUID = 4259102841471750866L;
079
080
081
082  // The trace string that should be included in the bind request, if available.
083  private final String traceString;
084
085
086
087  /**
088   * Creates a new SASL ANONYMOUS bind request with no trace string and no
089   * controls.
090   */
091  public ANONYMOUSBindRequest()
092  {
093    this(null, NO_CONTROLS);
094  }
095
096
097
098  /**
099   * Creates a new SASL ANONYMOUS bind request with the provided trace string
100   * and no controls.
101   *
102   * @param  traceString  The trace string to include in the bind request, or
103   *                      {@code null} if no trace string is to be provided.
104   */
105  public ANONYMOUSBindRequest(final String traceString)
106  {
107    this(traceString, NO_CONTROLS);
108  }
109
110
111
112  /**
113   * Creates a new SASL ANONYMOUS bind request with the provided set of controls
114   * and no trace string.
115   *
116   * @param  controls     The set of controls to include in the request.
117   */
118  public ANONYMOUSBindRequest(final Control... controls)
119  {
120    this(null, controls);
121  }
122
123
124
125  /**
126   * Creates a new SASL ANONYMOUS bind request with the provided trace string
127   * and controls.
128   *
129   * @param  traceString  The trace string to include in the bind request, or
130   *                      {@code null} if no trace string is to be provided.
131   * @param  controls     The set of controls to include in the request.
132   */
133  public ANONYMOUSBindRequest(final String traceString,
134                              final Control... controls)
135  {
136    super(controls);
137
138    this.traceString = traceString;
139  }
140
141
142
143  /**
144   * {@inheritDoc}
145   */
146  @Override()
147  public String getSASLMechanismName()
148  {
149    return ANONYMOUS_MECHANISM_NAME;
150  }
151
152
153
154  /**
155   * Retrieves the trace string that will be included with the bind request.
156   *
157   * @return  The trace string that will be included with the bind request, or
158   *          {@code null} if there is to be no trace string.
159   */
160  public String getTraceString()
161  {
162    return traceString;
163  }
164
165
166
167  /**
168   * Sends this bind request to the target server over the provided connection
169   * and returns the corresponding response.
170   *
171   * @param  connection  The connection to use to send this bind request to the
172   *                     server and read the associated response.
173   * @param  depth       The current referral depth for this request.  It should
174   *                     always be one for the initial request, and should only
175   *                     be incremented when following referrals.
176   *
177   * @return  The bind response read from the server.
178   *
179   * @throws  LDAPException  If a problem occurs while sending the request or
180   *                         reading the response.
181   */
182  @Override()
183  protected BindResult process(final LDAPConnection connection, final int depth)
184            throws LDAPException
185  {
186    ASN1OctetString credentials = null;
187    if ((traceString == null) || (traceString.length() == 0))
188    {
189      credentials = new ASN1OctetString(traceString);
190    }
191
192    return sendBindRequest(connection, null, credentials, getControls(),
193                           getResponseTimeoutMillis(connection));
194  }
195
196
197
198  /**
199   * {@inheritDoc}
200   */
201  @Override()
202  public ANONYMOUSBindRequest getRebindRequest(final String host,
203                                               final int port)
204  {
205    return new ANONYMOUSBindRequest(traceString, getControls());
206  }
207
208
209
210  /**
211   * {@inheritDoc}
212   */
213  @Override()
214  public ANONYMOUSBindRequest duplicate()
215  {
216    return duplicate(getControls());
217  }
218
219
220
221  /**
222   * {@inheritDoc}
223   */
224  @Override()
225  public ANONYMOUSBindRequest duplicate(final Control[] controls)
226  {
227    final ANONYMOUSBindRequest bindRequest =
228         new ANONYMOUSBindRequest(traceString, controls);
229    bindRequest.setResponseTimeoutMillis(getResponseTimeoutMillis(null));
230    return bindRequest;
231  }
232
233
234
235  /**
236   * {@inheritDoc}
237   */
238  @Override()
239  public void toString(final StringBuilder buffer)
240  {
241    buffer.append("ANONYMOUSBindRequest(");
242    if (traceString != null)
243    {
244      buffer.append(", trace='");
245      buffer.append(traceString);
246      buffer.append('\'');
247    }
248
249    final Control[] controls = getControls();
250    if (controls.length > 0)
251    {
252      buffer.append(", controls={");
253      for (int i=0; i < controls.length; i++)
254      {
255        if (i > 0)
256        {
257          buffer.append(", ");
258        }
259
260        buffer.append(controls[i]);
261      }
262      buffer.append('}');
263    }
264
265    buffer.append(')');
266  }
267}