001/* 002 * Copyright 2015-2018 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright (C) 2015-2018 Ping Identity Corporation 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.unboundidds.controls; 022 023 024 025import java.io.Serializable; 026import java.util.StringTokenizer; 027 028import com.unboundid.ldap.sdk.LDAPException; 029import com.unboundid.ldap.sdk.ResultCode; 030import com.unboundid.util.Debug; 031import com.unboundid.util.NotMutable; 032import com.unboundid.util.StaticUtils; 033import com.unboundid.util.ThreadSafety; 034import com.unboundid.util.ThreadSafetyLevel; 035import com.unboundid.util.Validator; 036 037import static com.unboundid.ldap.sdk.unboundidds.controls.ControlMessages.*; 038 039 040 041/** 042 * This class defines a data structure that will provide information about 043 * errors that could cause an authentication attempt to fail. It includes a 044 * number of predefined failure types, but but also allows for the possibility 045 * of additional failure types that have not been defined. 046 * <BR> 047 * <BLOCKQUOTE> 048 * <B>NOTE:</B> This class, and other classes within the 049 * {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only 050 * supported for use against Ping Identity, UnboundID, and Alcatel-Lucent 8661 051 * server products. These classes provide support for proprietary 052 * functionality or for external specifications that are not considered stable 053 * or mature enough to be guaranteed to work in an interoperable way with 054 * other types of LDAP servers. 055 * </BLOCKQUOTE> 056 */ 057@NotMutable() 058@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 059public final class AuthenticationFailureReason 060 implements Serializable 061{ 062 /** 063 * The numeric value for the failure type that indicates the user's account 064 * is not in a usable state. Examining the set of account usability errors 065 * should provide more specific information about the nature of the error. 066 */ 067 public static final int FAILURE_TYPE_ACCOUNT_NOT_USABLE = 1; 068 069 070 071 /** 072 * The name for the failure type that indicates the user's account is not in a 073 * usable state. Examining the set of account usability errors should provide 074 * more specific information about the nature of the error. 075 */ 076 public static final String FAILURE_NAME_ACCOUNT_NOT_USABLE = 077 "account-not-usable"; 078 079 080 081 /** 082 * The numeric value for the failure type that indicates that the server was 083 * unable to assign a client connection policy for the user. 084 */ 085 public static final int FAILURE_TYPE_CANNOT_ASSIGN_CLIENT_CONNECTION_POLICY = 086 3; 087 088 089 090 /** 091 * The name for the failure type that indicates that the server was unable to 092 * assign a client connection policy for the user. 093 */ 094 public static final String 095 FAILURE_NAME_CANNOT_ASSIGN_CLIENT_CONNECTION_POLICY = 096 "cannot-assign-client-connection-policy"; 097 098 099 100 /** 101 * The numeric value for the failure type that indicates that the server was 102 * unable to identify the user specified as the authentication or 103 * authorization identity. 104 */ 105 public static final int FAILURE_TYPE_CANNOT_IDENTIFY_USER = 4; 106 107 108 109 /** 110 * The numeric value for the failure type that indicates that the server was 111 * unable to identify the user specified as the authentication or 112 * authorization identity. 113 */ 114 public static final String FAILURE_NAME_CANNOT_IDENTIFY_USER = 115 "cannot-identify-user"; 116 117 118 119 /** 120 * The numeric value for the failure type that indicates that bind was not 121 * permitted by some constraint defined in the server (password policy, 122 * client connection policy, operational attributes in the user entry, etc.). 123 */ 124 public static final int FAILURE_TYPE_CONSTRAINT_VIOLATION = 5; 125 126 127 128 /** 129 * The name for the failure type that indicates that bind was not permitted by 130 * some constraint defined in the server (password policy, client connection 131 * policy, operational attributes in the user entry, etc.). 132 */ 133 public static final String FAILURE_NAME_CONSTRAINT_VIOLATION = 134 "constraint-violation"; 135 136 137 138 /** 139 * The numeric value for the failure type that indicates that there was a 140 * problem with a control included in the bind request. 141 */ 142 public static final int FAILURE_TYPE_CONTROL_PROBLEM = 6; 143 144 145 146 /** 147 * The name for the failure type that indicates that there was a problem with 148 * a control included in the bind request. 149 */ 150 public static final String FAILURE_NAME_CONTROL_PROBLEM = "control-problem"; 151 152 153 154 /** 155 * The numeric value for the failure type that indicates that there was a 156 * problem with the SASL credentials provided to the server (e.g., they were 157 * malformed, out of sequence, or otherwise invalid). 158 */ 159 public static final int FAILURE_TYPE_IMPROPER_SASL_CREDENTIALS = 7; 160 161 162 163 /** 164 * The name for the failure type that indicates that there was a problem with 165 * the SASL credentials provided to the server (e.g., they were malformed, out 166 * of sequence, or otherwise invalid). 167 */ 168 public static final String FAILURE_NAME_IMPROPER_SASL_CREDENTIALS = 169 "improper-sasl-credentials"; 170 171 172 173 /** 174 * The numeric value for the failure type that indicates that the bind was 175 * not permitted by the server's access control configuration. 176 */ 177 public static final int FAILURE_TYPE_INSUFFICIENT_ACCESS_RIGHTS = 8; 178 179 180 181 /** 182 * The name for the failure type that indicates that the bind was not 183 * permitted by the server's access control configuration. 184 */ 185 public static final String FAILURE_NAME_INSUFFICIENT_ACCESS_RIGHTS = 186 "insufficient-access-rights"; 187 188 189 190 /** 191 * The numeric value for the failure type that indicates that the user 192 * provided an incorrect password or other form of invalid credentials. 193 */ 194 public static final int FAILURE_TYPE_INVALID_CREDENTIALS = 9; 195 196 197 198 /** 199 * The name for the failure type that indicates that the user provided an 200 * incorrect password or other form of invalid credentials. 201 */ 202 public static final String FAILURE_NAME_INVALID_CREDENTIALS = 203 "invalid-credentials"; 204 205 206 207 /** 208 * The numeric value for the failure type that indicates that the server is in 209 * lockdown mode and will only permit authentication for a limited set of 210 * administrators. 211 */ 212 public static final int FAILURE_TYPE_LOCKDOWN_MODE = 10; 213 214 215 216 /** 217 * The name for the failure type that indicates that the server is in lockdown 218 * mode and will only permit authentication for a limited set of 219 * administrators. 220 */ 221 public static final String FAILURE_NAME_LOCKDOWN_MODE = "lockdown-mode"; 222 223 224 225 /** 226 * The numeric value for the failure type that indicates that the user will 227 * only be permitted to authenticate in a secure manner. 228 */ 229 public static final int FAILURE_TYPE_SECURE_AUTHENTICATION_REQUIRED = 11; 230 231 232 233 /** 234 * The name for the failure type that indicates that the user will only be 235 * permitted to authenticate in a secure manner. 236 */ 237 public static final String FAILURE_NAME_SECURE_AUTHENTICATION_REQUIRED = 238 "secure-authentication-required"; 239 240 241 242 /** 243 * The numeric value for the failure type that indicates that a server error 244 * occurred while processing the bind operation. 245 */ 246 public static final int FAILURE_TYPE_SERVER_ERROR = 12; 247 248 249 250 /** 251 * The name for the failure type that indicates that a server error occurred 252 * while processing the bind operation. 253 */ 254 public static final String FAILURE_NAME_SERVER_ERROR = "server-error"; 255 256 257 258 /** 259 * The numeric value for the failure type that indicates that a third-party 260 * SASL mechanism handler failed to authenticate the user. 261 */ 262 public static final int FAILURE_TYPE_THIRD_PARTY_SASL_AUTHENTICATION_FAILURE = 263 13; 264 265 266 267 /** 268 * The name for the failure type that indicates that a third-party SASL 269 * mechanism handler failed to authenticate the user. 270 */ 271 public static final String 272 FAILURE_NAME_THIRD_PARTY_SASL_AUTHENTICATION_FAILURE = 273 "third-party-sasl-authentication-failure"; 274 275 276 277 /** 278 * The numeric value for the failure type that indicates that attempted 279 * authentication type is not available for the target user. 280 */ 281 public static final int FAILURE_TYPE_UNAVAILABLE_AUTHENTICATION_TYPE = 14; 282 283 284 285 /** 286 * The name for the failure type that indicates that attempted authentication 287 * type is not available for the target user. 288 */ 289 public static final String FAILURE_NAME_UNAVAILABLE_AUTHENTICATION_TYPE = 290 "unavailable-authentication-type"; 291 292 293 294 /** 295 * The numeric value for a failure type that does not fit into any other of 296 * the defined failure types. 297 */ 298 public static final int FAILURE_TYPE_OTHER = 15; 299 300 301 302 /** 303 * The name for a failure type that does not fit into any other of the defined 304 * failure types. 305 */ 306 public static final String FAILURE_NAME_OTHER = "other"; 307 308 309 310 /** 311 * The serial version UID for this serializable class. 312 */ 313 private static final long serialVersionUID = -5752716527356924347L; 314 315 316 317 // The integer value for this account usability error. 318 private final int intValue; 319 320 // A human-readable message that provides specific details about this account 321 // usability error. 322 private final String message; 323 324 // The name for this account usability error. 325 private final String name; 326 327 // The encoded string representation for this account usability error. 328 private final String stringRepresentation; 329 330 331 332 /** 333 * Creates a new authentication failure reason with the provided information. 334 * 335 * @param intValue The integer value for this authentication failure reason. 336 * @param name The name for this authentication failure reason. It must 337 * not be {@code null}. 338 * @param message A human-readable message that provides specific details 339 * about this account usability error. It may be 340 * {@code null} if no message is available. 341 */ 342 public AuthenticationFailureReason(final int intValue, final String name, 343 final String message) 344 { 345 Validator.ensureNotNull(name); 346 347 this.intValue = intValue; 348 this.name = name; 349 this.message = message; 350 351 final StringBuilder buffer = new StringBuilder(); 352 buffer.append("code="); 353 buffer.append(intValue); 354 buffer.append("\tname="); 355 buffer.append(name); 356 357 if (message != null) 358 { 359 buffer.append("\tmessage="); 360 buffer.append(message); 361 } 362 363 stringRepresentation = buffer.toString(); 364 } 365 366 367 368 /** 369 * Creates a new authentication failure reason that is decoded from the 370 * provided string representation. 371 * 372 * @param stringRepresentation The string representation of the 373 * authentication failure reason to decode. It 374 * must not be {@code null}. 375 * 376 * @throws LDAPException If the provided string cannot be decoded as a valid 377 * authentication failure reason. 378 */ 379 public AuthenticationFailureReason(final String stringRepresentation) 380 throws LDAPException 381 { 382 this.stringRepresentation = stringRepresentation; 383 384 try 385 { 386 Integer i = null; 387 String n = null; 388 String m = null; 389 390 final StringTokenizer tokenizer = 391 new StringTokenizer(stringRepresentation, "\t"); 392 while (tokenizer.hasMoreTokens()) 393 { 394 final String token = tokenizer.nextToken(); 395 final int equalPos = token.indexOf('='); 396 final String fieldName = token.substring(0, equalPos); 397 final String fieldValue = token.substring(equalPos+1); 398 if (fieldName.equals("code")) 399 { 400 i = Integer.valueOf(fieldValue); 401 } 402 else if (fieldName.equals("name")) 403 { 404 n = fieldValue; 405 } 406 else if (fieldName.equals("message")) 407 { 408 m = fieldValue; 409 } 410 } 411 412 if (i == null) 413 { 414 throw new LDAPException(ResultCode.DECODING_ERROR, 415 ERR_AUTH_FAILURE_REASON_CANNOT_DECODE.get(stringRepresentation, 416 ERR_AUTH_FAILURE_REASON_NO_CODE.get())); 417 } 418 419 if (n == null) 420 { 421 throw new LDAPException(ResultCode.DECODING_ERROR, 422 ERR_AUTH_FAILURE_REASON_CANNOT_DECODE.get(stringRepresentation, 423 ERR_AUTH_FAILURE_REASON_NO_NAME.get())); 424 } 425 426 intValue = i; 427 name = n; 428 message = m; 429 } 430 catch (final LDAPException le) 431 { 432 Debug.debugException(le); 433 434 throw le; 435 } 436 catch (final Exception e) 437 { 438 Debug.debugException(e); 439 440 throw new LDAPException(ResultCode.DECODING_ERROR, 441 ERR_AUTH_FAILURE_REASON_CANNOT_DECODE.get(stringRepresentation, 442 StaticUtils.getExceptionMessage(e)), 443 e); 444 } 445 } 446 447 448 449 /** 450 * Retrieves the integer value for this authentication failure reason. 451 * 452 * @return The integer value for this authentication failure reason. 453 */ 454 public int getIntValue() 455 { 456 return intValue; 457 } 458 459 460 461 /** 462 * Retrieves the name for this authentication failure reason. 463 * 464 * @return The name for this authentication failure reason. 465 */ 466 public String getName() 467 { 468 return name; 469 } 470 471 472 473 /** 474 * Retrieves a human-readable message that provides specific details about 475 * this authentication failure reason. 476 * 477 * @return A human-readable message that provides specific details about this 478 * authentication failure reason, or {@code null} if no message is 479 * available. 480 */ 481 public String getMessage() 482 { 483 return message; 484 } 485 486 487 488 /** 489 * Retrieves a string representation of this authentication failure reason. 490 * 491 * @return A string representation of this authentication failure reason. 492 */ 493 @Override() 494 public String toString() 495 { 496 return stringRepresentation; 497 } 498}