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