001    /*
002     * Copyright 2007-2015 UnboundID Corp.
003     * All Rights Reserved.
004     */
005    /*
006     * Copyright (C) 2008-2015 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 com.unboundid.asn1.ASN1OctetString;
026    import com.unboundid.util.NotMutable;
027    import com.unboundid.util.ThreadSafety;
028    import 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)
065    public 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    }