001    /*
002     * Copyright 2007-2013 UnboundID Corp.
003     * All Rights Reserved.
004     */
005    /*
006     * Copyright (C) 2008-2013 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 "Hello, world!" against a directory server:
044     * <PRE>
045     *   ANONYMOUSBindRequest bindRequest =
046     *        new ANONYMOUSBindRequest("Hello, world!");
047     *   try
048     *   {
049     *     BindResult bindResult = connection.bind(bindRequest);
050     *     // If we get here, then the bind was successful.
051     *   }
052     *   catch (LDAPException le)
053     *   {
054     *     // The bind failed for some reason.
055     *   }
056     * </PRE>
057     */
058    @NotMutable()
059    @ThreadSafety(level=ThreadSafetyLevel.NOT_THREADSAFE)
060    public final class ANONYMOUSBindRequest
061           extends SASLBindRequest
062    {
063      /**
064       * The name for the ANONYMOUS SASL mechanism.
065       */
066      public static final String ANONYMOUS_MECHANISM_NAME = "ANONYMOUS";
067    
068    
069    
070      /**
071       * The serial version UID for this serializable class.
072       */
073      private static final long serialVersionUID = 4259102841471750866L;
074    
075    
076    
077      // The trace string that should be included in the bind request, if available.
078      private final String traceString;
079    
080    
081    
082      /**
083       * Creates a new SASL ANONYMOUS bind request with no trace string and no
084       * controls.
085       */
086      public ANONYMOUSBindRequest()
087      {
088        this(null, NO_CONTROLS);
089      }
090    
091    
092    
093      /**
094       * Creates a new SASL ANONYMOUS bind request with the provided trace string
095       * and no controls.
096       *
097       * @param  traceString  The trace string to include in the bind request, or
098       *                      {@code null} if no trace string is to be provided.
099       */
100      public ANONYMOUSBindRequest(final String traceString)
101      {
102        this(traceString, NO_CONTROLS);
103      }
104    
105    
106    
107      /**
108       * Creates a new SASL ANONYMOUS bind request with the provided set of controls
109       * and no trace string.
110       *
111       * @param  controls     The set of controls to include in the request.
112       */
113      public ANONYMOUSBindRequest(final Control... controls)
114      {
115        this(null, controls);
116      }
117    
118    
119    
120      /**
121       * Creates a new SASL ANONYMOUS bind request with the provided trace string
122       * and controls.
123       *
124       * @param  traceString  The trace string to include in the bind request, or
125       *                      {@code null} if no trace string is to be provided.
126       * @param  controls     The set of controls to include in the request.
127       */
128      public ANONYMOUSBindRequest(final String traceString,
129                                  final Control... controls)
130      {
131        super(controls);
132    
133        this.traceString = traceString;
134      }
135    
136    
137    
138      /**
139       * {@inheritDoc}
140       */
141      @Override()
142      public String getSASLMechanismName()
143      {
144        return ANONYMOUS_MECHANISM_NAME;
145      }
146    
147    
148    
149      /**
150       * Retrieves the trace string that will be included with the bind request.
151       *
152       * @return  The trace string that will be included with the bind request, or
153       *          {@code null} if there is to be no trace string.
154       */
155      public String getTraceString()
156      {
157        return traceString;
158      }
159    
160    
161    
162      /**
163       * Sends this bind request to the target server over the provided connection
164       * and returns the corresponding response.
165       *
166       * @param  connection  The connection to use to send this bind request to the
167       *                     server and read the associated response.
168       * @param  depth       The current referral depth for this request.  It should
169       *                     always be one for the initial request, and should only
170       *                     be incremented when following referrals.
171       *
172       * @return  The bind response read from the server.
173       *
174       * @throws  LDAPException  If a problem occurs while sending the request or
175       *                         reading the response.
176       */
177      @Override()
178      protected BindResult process(final LDAPConnection connection, final int depth)
179                throws LDAPException
180      {
181        ASN1OctetString credentials = null;
182        if ((traceString == null) || (traceString.length() == 0))
183        {
184          credentials = new ASN1OctetString(traceString);
185        }
186    
187        return sendBindRequest(connection, null, credentials, getControls(),
188                               getResponseTimeoutMillis(connection));
189      }
190    
191    
192    
193      /**
194       * {@inheritDoc}
195       */
196      @Override()
197      public ANONYMOUSBindRequest getRebindRequest(final String host,
198                                                   final int port)
199      {
200        return new ANONYMOUSBindRequest(traceString, getControls());
201      }
202    
203    
204    
205      /**
206       * {@inheritDoc}
207       */
208      @Override()
209      public ANONYMOUSBindRequest duplicate()
210      {
211        return duplicate(getControls());
212      }
213    
214    
215    
216      /**
217       * {@inheritDoc}
218       */
219      @Override()
220      public ANONYMOUSBindRequest duplicate(final Control[] controls)
221      {
222        final ANONYMOUSBindRequest bindRequest =
223             new ANONYMOUSBindRequest(traceString, controls);
224        bindRequest.setResponseTimeoutMillis(getResponseTimeoutMillis(null));
225        return bindRequest;
226      }
227    
228    
229    
230      /**
231       * {@inheritDoc}
232       */
233      @Override()
234      public void toString(final StringBuilder buffer)
235      {
236        buffer.append("ANONYMOUSBindRequest(");
237        if (traceString != null)
238        {
239          buffer.append(", trace='");
240          buffer.append(traceString);
241          buffer.append('\'');
242        }
243    
244        final Control[] controls = getControls();
245        if (controls.length > 0)
246        {
247          buffer.append(", controls={");
248          for (int i=0; i < controls.length; i++)
249          {
250            if (i > 0)
251            {
252              buffer.append(", ");
253            }
254    
255            buffer.append(controls[i]);
256          }
257          buffer.append('}');
258        }
259    
260        buffer.append(')');
261      }
262    }