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