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