001 /* 002 * CDDL HEADER START 003 * 004 * The contents of this file are subject to the terms of the 005 * Common Development and Distribution License, Version 1.0 only 006 * (the "License"). You may not use this file except in compliance 007 * with the License. 008 * 009 * You can obtain a copy of the license at 010 * trunk/opends/resource/legal-notices/OpenDS.LICENSE 011 * or https://OpenDS.dev.java.net/OpenDS.LICENSE. 012 * See the License for the specific language governing permissions 013 * and limitations under the License. 014 * 015 * When distributing Covered Code, include this CDDL HEADER in each 016 * file and include the License file at 017 * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, 018 * add the following below this CDDL HEADER, with the fields enclosed 019 * by brackets "[]" replaced with your own identifying information: 020 * Portions Copyright [yyyy] [name of copyright owner] 021 * 022 * CDDL HEADER END 023 * 024 * 025 * Copyright 2006-2008 Sun Microsystems, Inc. 026 */ 027 package org.opends.server.core; 028 029 030 031 import java.text.SimpleDateFormat; 032 import java.util.Date; 033 import java.util.Iterator; 034 import java.util.LinkedHashMap; 035 import java.util.LinkedHashSet; 036 import java.util.LinkedList; 037 import java.util.SortedSet; 038 import java.util.TimeZone; 039 import java.util.concurrent.ConcurrentHashMap; 040 import java.util.concurrent.CopyOnWriteArrayList; 041 import java.util.concurrent.CopyOnWriteArraySet; 042 043 import org.opends.messages.Message; 044 import org.opends.server.admin.std.meta.PasswordPolicyCfgDefn; 045 import org.opends.server.admin.std.server.PasswordPolicyCfg; 046 import org.opends.server.admin.std.server.PasswordValidatorCfg; 047 import org.opends.server.api.AccountStatusNotificationHandler; 048 import org.opends.server.api.PasswordGenerator; 049 import org.opends.server.api.PasswordStorageScheme; 050 import org.opends.server.api.PasswordValidator; 051 import org.opends.server.config.ConfigException; 052 import org.opends.server.loggers.debug.DebugTracer; 053 import org.opends.server.protocols.asn1.ASN1OctetString; 054 import org.opends.server.schema.GeneralizedTimeSyntax; 055 import org.opends.server.types.AttributeType; 056 import org.opends.server.types.ByteString; 057 import org.opends.server.types.DebugLogLevel; 058 import org.opends.server.types.DN; 059 import org.opends.server.types.InitializationException; 060 061 import static org.opends.messages.CoreMessages.*; 062 import static org.opends.server.config.ConfigConstants.*; 063 import static org.opends.server.loggers.debug.DebugLogger.*; 064 import static org.opends.server.schema.SchemaConstants.*; 065 import static org.opends.server.util.ServerConstants.*; 066 import static org.opends.server.util.StaticUtils.*; 067 068 069 070 /** 071 * This class defines a data structure that holds information about a Directory 072 * Server password policy. 073 */ 074 public class PasswordPolicy 075 { 076 /** 077 * The tracer object for the debug logger. 078 */ 079 private static final DebugTracer TRACER = getTracer(); 080 081 // The DN of the entry containing the configuration for this password 082 // policy. 083 private final DN configEntryDN; 084 085 // The attribute type that will hold user passwords for this password policy. 086 private final AttributeType passwordAttribute; 087 088 // Indicates whether the attribute type uses the authPassword syntax. 089 private final boolean authPasswordSyntax; 090 091 // Indicates whether a user with an expired password will still be allowed to 092 // change it via the password modify extended operation. 093 private boolean allowExpiredPasswordChanges = 094 DEFAULT_PWPOLICY_ALLOW_EXPIRED_CHANGES; 095 096 // Indicates whether the password attribute will be allowed to have multiple 097 // distinct values. 098 private boolean allowMultiplePasswordValues = 099 DEFAULT_PWPOLICY_ALLOW_MULTIPLE_PW_VALUES; 100 101 // Indicates whether to allow pre-encoded passwords. 102 private boolean allowPreEncodedPasswords = 103 DEFAULT_PWPOLICY_ALLOW_PRE_ENCODED_PASSWORDS; 104 105 // Indicates whether users will be allowed to change their passwords. 106 private boolean allowUserPasswordChanges = 107 DEFAULT_PWPOLICY_ALLOW_USER_CHANGE; 108 109 // Indicates whether to allow a password to expire without ever providing the 110 // user with a notification. 111 private boolean expirePasswordsWithoutWarning = 112 DEFAULT_PWPOLICY_EXPIRE_WITHOUT_WARNING; 113 114 // Indicates whether users must change their passwords the first time they 115 // authenticate after their account is created. 116 private boolean forceChangeOnAdd = 117 DEFAULT_PWPOLICY_FORCE_CHANGE_ON_ADD; 118 119 // Indicates whether a user must change their password after it has been reset 120 // by an administrator. 121 private boolean forceChangeOnReset = 122 DEFAULT_PWPOLICY_FORCE_CHANGE_ON_RESET; 123 124 // Indicates whether a user must provide their current password in order to 125 // use a new password. 126 private boolean requireCurrentPassword = 127 DEFAULT_PWPOLICY_REQUIRE_CURRENT_PASSWORD; 128 129 // Indicates whether users will be required to authenticate using a secure 130 // mechanism. 131 private boolean requireSecureAuthentication = 132 DEFAULT_PWPOLICY_REQUIRE_SECURE_AUTHENTICATION; 133 134 // Indicates whether users will be required to change their passwords using a 135 // secure mechanism. 136 private boolean requireSecurePasswordChanges = 137 DEFAULT_PWPOLICY_REQUIRE_SECURE_PASSWORD_CHANGES; 138 139 // Indicates whether password validation should be performed for 140 // administrative password changes. 141 private boolean skipValidationForAdministrators = 142 DEFAULT_PWPOLICY_SKIP_ADMIN_VALIDATION; 143 144 // The set of account status notification handlers for this password policy. 145 private ConcurrentHashMap<DN, AccountStatusNotificationHandler> 146 notificationHandlers; 147 148 // The set of password validators that will be used with this 149 // password policy. 150 private ConcurrentHashMap<DN, PasswordValidator<?>> passwordValidators; 151 152 // The set of default password storage schemes for this password 153 // policy. 154 private CopyOnWriteArrayList<PasswordStorageScheme> defaultStorageSchemes = 155 new CopyOnWriteArrayList<PasswordStorageScheme>(); 156 { 157 PasswordStorageScheme defaultScheme = 158 DirectoryServer.getPasswordStorageScheme(DEFAULT_PASSWORD_STORAGE_SCHEME); 159 if (defaultScheme != null) defaultStorageSchemes.add(defaultScheme); 160 } 161 162 // The names of the deprecated password storage schemes for this password 163 // policy. 164 private CopyOnWriteArraySet<String> deprecatedStorageSchemes = 165 new CopyOnWriteArraySet<String>(); 166 167 // The DN of the password validator for this password policy. 168 private DN passwordGeneratorDN = null; 169 170 // The password generator for use with this password policy. 171 private PasswordGenerator passwordGenerator = null; 172 173 // The number of grace logins that a user may have. 174 private int graceLoginCount = DEFAULT_PWPOLICY_GRACE_LOGIN_COUNT; 175 176 // The number of passwords to keep in the history. 177 private int historyCount = DEFAULT_PWPOLICY_HISTORY_COUNT; 178 179 // The maximum length of time in seconds to keep passwords in the history. 180 private int historyDuration = DEFAULT_PWPOLICY_HISTORY_DURATION; 181 182 // The maximum length of time in seconds that an account may remain idle 183 // before it is locked out. 184 private int idleLockoutInterval = DEFAULT_PWPOLICY_IDLE_LOCKOUT_INTERVAL; 185 186 // The length of time a user should stay locked out, in seconds. 187 private int lockoutDuration = DEFAULT_PWPOLICY_LOCKOUT_DURATION; 188 189 // The number of authentication failures before an account is locked out. 190 private int lockoutFailureCount = DEFAULT_PWPOLICY_LOCKOUT_FAILURE_COUNT; 191 192 // The length of time that authentication failures should be counted against 193 // a user. 194 private int lockoutFailureExpirationInterval = 195 DEFAULT_PWPOLICY_LOCKOUT_FAILURE_EXPIRATION_INTERVAL; 196 197 // The maximum password age (i.e., expiration interval), in seconds. 198 private int maximumPasswordAge = DEFAULT_PWPOLICY_MAXIMUM_PASSWORD_AGE; 199 200 // The maximum password age for administratively reset passwords, in seconds. 201 private int maximumPasswordResetAge = 202 DEFAULT_PWPOLICY_MAXIMUM_PASSWORD_RESET_AGE; 203 204 // The minimum password age, in seconds. 205 private int minimumPasswordAge = DEFAULT_PWPOLICY_MINIMUM_PASSWORD_AGE; 206 207 // The password expiration warning interval, in seconds. 208 private int warningInterval = DEFAULT_PWPOLICY_WARNING_INTERVAL; 209 210 // The the time by which all users will be required to change their passwords. 211 private long requireChangeByTime = -1L; 212 213 // The attribute type that will hold the last login time. 214 private AttributeType lastLoginTimeAttribute = null; 215 216 // The format string to use when generating the last login time. 217 private String lastLoginTimeFormat = null; 218 219 // The set of previous last login time format strings. 220 private CopyOnWriteArrayList<String> previousLastLoginTimeFormats = 221 new CopyOnWriteArrayList<String>(); 222 223 // The state update failure policy. 224 private PasswordPolicyCfgDefn.StateUpdateFailurePolicy 225 stateUpdateFailurePolicy = 226 PasswordPolicyCfgDefn.StateUpdateFailurePolicy.REACTIVE; 227 228 229 230 /** 231 * Creates a new password policy based on the configuration contained in the 232 * provided configuration entry. Any parameters not included in the provided 233 * configuration entry will be assigned server-wide default values. 234 * 235 * @param configuration The configuration with the information to use to 236 * initialize this password policy. 237 * 238 * @throws ConfigException If the provided entry does not contain a valid 239 * password policy configuration. 240 * 241 * @throws InitializationException If an error occurs while initializing the 242 * password policy that is not related to 243 * the server configuration. 244 */ 245 public PasswordPolicy(PasswordPolicyCfg configuration) 246 throws ConfigException, InitializationException 247 { 248 // Create a list of units and values that we can use to represent time 249 // periods. 250 LinkedHashMap<String,Double> timeUnits = new LinkedHashMap<String,Double>(); 251 timeUnits.put(TIME_UNIT_SECONDS_ABBR, 1D); 252 timeUnits.put(TIME_UNIT_SECONDS_FULL, 1D); 253 timeUnits.put(TIME_UNIT_MINUTES_ABBR, 60D); 254 timeUnits.put(TIME_UNIT_MINUTES_FULL, 60D); 255 timeUnits.put(TIME_UNIT_HOURS_ABBR, (double) (60 * 60)); 256 timeUnits.put(TIME_UNIT_HOURS_FULL, (double) (60 * 60)); 257 timeUnits.put(TIME_UNIT_DAYS_ABBR, (double) (60 * 60 * 24)); 258 timeUnits.put(TIME_UNIT_DAYS_FULL, (double) (60 * 60 * 24)); 259 timeUnits.put(TIME_UNIT_WEEKS_ABBR, (double) (60 * 60 * 24 * 7)); 260 timeUnits.put(TIME_UNIT_WEEKS_FULL, (double) (60 * 60 * 24 * 7)); 261 262 this.configEntryDN = configuration.dn(); 263 264 // Get the password attribute. If specified, it must have either the 265 // user password or auth password syntax. 266 passwordAttribute = configuration.getPasswordAttribute(); 267 String syntaxOID = passwordAttribute.getSyntaxOID(); 268 if (syntaxOID.equals(SYNTAX_AUTH_PASSWORD_OID)) 269 { 270 authPasswordSyntax = true; 271 } 272 else if (syntaxOID.equals(SYNTAX_USER_PASSWORD_OID)) 273 { 274 authPasswordSyntax = false; 275 } 276 else 277 { 278 String syntax = passwordAttribute.getSyntax().getSyntaxName(); 279 if ((syntax == null) || (syntax.length() == 0)) 280 { 281 syntax = syntaxOID; 282 } 283 284 Message message = ERR_PWPOLICY_INVALID_PASSWORD_ATTRIBUTE_SYNTAX. 285 get(String.valueOf(configEntryDN), passwordAttribute.getNameOrOID(), 286 String.valueOf(syntax)); 287 throw new ConfigException(message); 288 } 289 290 291 // Get the default storage schemes. They must all reference valid storage 292 // schemes that support the syntax for the specified password attribute. 293 SortedSet<DN> storageSchemeDNs = 294 configuration.getDefaultPasswordStorageSchemeDNs(); 295 try 296 { 297 LinkedList<PasswordStorageScheme> schemes = 298 new LinkedList<PasswordStorageScheme>(); 299 for (DN configEntryDN : storageSchemeDNs) 300 { 301 PasswordStorageScheme scheme = 302 DirectoryServer.getPasswordStorageScheme(configEntryDN); 303 304 if (this.authPasswordSyntax && 305 (! scheme.supportsAuthPasswordSyntax())) 306 { 307 Message message = ERR_PWPOLICY_SCHEME_DOESNT_SUPPORT_AUTH.get( 308 String.valueOf(configEntryDN), 309 this.passwordAttribute.getNameOrOID()); 310 throw new ConfigException(message); 311 } 312 313 schemes.add(scheme); 314 } 315 316 this.defaultStorageSchemes = 317 new CopyOnWriteArrayList<PasswordStorageScheme>(schemes); 318 } 319 catch (ConfigException ce) 320 { 321 throw ce; 322 } 323 catch (Exception e) 324 { 325 if (debugEnabled()) 326 { 327 TRACER.debugCaught(DebugLogLevel.ERROR, e); 328 } 329 330 Message message = ERR_PWPOLICY_CANNOT_DETERMINE_DEFAULT_STORAGE_SCHEMES. 331 get(String.valueOf(configEntryDN), getExceptionMessage(e)); 332 throw new InitializationException(message, e); 333 } 334 335 336 // Get the names of the deprecated storage schemes. 337 SortedSet<DN> deprecatedStorageSchemeDNs = 338 configuration.getDeprecatedPasswordStorageSchemeDNs(); 339 try 340 { 341 LinkedHashSet<String> newDeprecatedStorageSchemes = 342 new LinkedHashSet<String>(); 343 for (DN schemeDN : deprecatedStorageSchemeDNs) 344 { 345 PasswordStorageScheme scheme = 346 DirectoryServer.getPasswordStorageScheme(schemeDN); 347 if (this.authPasswordSyntax) 348 { 349 if (scheme.supportsAuthPasswordSyntax()) 350 { 351 newDeprecatedStorageSchemes.add( 352 scheme.getAuthPasswordSchemeName()); 353 } 354 else 355 { 356 Message message = ERR_PWPOLICY_DEPRECATED_SCHEME_NOT_AUTH.get( 357 String.valueOf(configEntryDN), 358 String.valueOf(schemeDN)); 359 throw new ConfigException(message); 360 } 361 } 362 else 363 { 364 newDeprecatedStorageSchemes.add( 365 toLowerCase(scheme.getStorageSchemeName())); 366 } 367 } 368 369 this.deprecatedStorageSchemes = 370 new CopyOnWriteArraySet<String>(newDeprecatedStorageSchemes); 371 } 372 catch (Exception e) 373 { 374 if (debugEnabled()) 375 { 376 TRACER.debugCaught(DebugLogLevel.ERROR, e); 377 } 378 379 Message message = 380 ERR_PWPOLICY_CANNOT_DETERMINE_DEPRECATED_STORAGE_SCHEMES. 381 get(String.valueOf(configEntryDN), getExceptionMessage(e)); 382 throw new InitializationException(message, e); 383 } 384 385 386 // Get the password validators. 387 SortedSet<DN> passwordValidators = configuration.getPasswordValidatorDNs(); 388 ConcurrentHashMap<DN, PasswordValidator<?>> validators = 389 new ConcurrentHashMap<DN, PasswordValidator<?>>(); 390 for (DN validatorDN : passwordValidators) 391 { 392 validators.put(validatorDN, 393 DirectoryServer.getPasswordValidator(validatorDN)); 394 } 395 this.passwordValidators = validators; 396 397 398 // Get the status notification handlers. 399 SortedSet<DN> statusNotificationHandlers = 400 configuration.getAccountStatusNotificationHandlerDNs(); 401 ConcurrentHashMap<DN,AccountStatusNotificationHandler> handlers = 402 new ConcurrentHashMap<DN,AccountStatusNotificationHandler>(); 403 for (DN handlerDN : statusNotificationHandlers) 404 { 405 AccountStatusNotificationHandler handler = 406 DirectoryServer.getAccountStatusNotificationHandler(handlerDN); 407 handlers.put(handlerDN, handler); 408 } 409 this.notificationHandlers = handlers; 410 411 412 // Determine whether to allow user password changes. 413 this.allowUserPasswordChanges = configuration.isAllowUserPasswordChanges(); 414 415 // Determine whether to require the current password for user changes. 416 this.requireCurrentPassword = 417 configuration.isPasswordChangeRequiresCurrentPassword(); 418 419 // Determine whether to force password changes on add. 420 this.forceChangeOnAdd = configuration.isForceChangeOnAdd(); 421 422 // Determine whether to force password changes on reset. 423 this.forceChangeOnReset = configuration.isForceChangeOnReset(); 424 425 // Determine whether to validate reset passwords. 426 this.skipValidationForAdministrators = 427 configuration.isSkipValidationForAdministrators(); 428 429 // Get the password generator. 430 DN passGenDN = configuration.getPasswordGeneratorDN() ; 431 if (passGenDN != null) 432 { 433 this.passwordGeneratorDN = passGenDN; 434 this.passwordGenerator = DirectoryServer.getPasswordGenerator(passGenDN); 435 } 436 437 438 // Determine whether to require secure authentication. 439 this.requireSecureAuthentication = 440 configuration.isRequireSecureAuthentication(); 441 442 // Determine whether to require secure password changes. 443 this.requireSecurePasswordChanges = 444 configuration.isRequireSecurePasswordChanges() ; 445 446 // Determine whether to allow multiple password values. 447 this.allowMultiplePasswordValues = 448 configuration.isAllowMultiplePasswordValues(); 449 450 // Determine whether to allow pre-encoded passwords. 451 this.allowPreEncodedPasswords = configuration.isAllowPreEncodedPasswords(); 452 453 // Get the minimum password age. 454 this.minimumPasswordAge = (int) configuration.getMinPasswordAge(); 455 456 // Get the maximum password age. 457 this.maximumPasswordAge = (int) configuration.getMaxPasswordAge(); 458 459 // Get the maximum password reset age. 460 this.maximumPasswordResetAge = (int) configuration 461 .getMaxPasswordResetAge(); 462 463 // Get the warning interval. 464 this.warningInterval = (int) configuration 465 .getPasswordExpirationWarningInterval(); 466 467 // Determine whether to expire passwords without warning. 468 this.expirePasswordsWithoutWarning = configuration 469 .isExpirePasswordsWithoutWarning(); 470 471 // If the expire without warning option is disabled, then there must be a 472 // warning interval. 473 if ((! this.expirePasswordsWithoutWarning()) && 474 (this.getWarningInterval() <= 0)) 475 { 476 Message message = 477 ERR_PWPOLICY_MUST_HAVE_WARNING_IF_NOT_EXPIRE_WITHOUT_WARNING. 478 get(String.valueOf(configEntryDN)); 479 throw new ConfigException(message); 480 } 481 482 // Determine whether to allow user changes for expired passwords. 483 this.allowExpiredPasswordChanges = configuration 484 .isAllowExpiredPasswordChanges(); 485 486 // Get the grace login count. 487 this.graceLoginCount = configuration.getGraceLoginCount(); 488 489 // Get the lockout failure count. 490 this.lockoutFailureCount = configuration.getLockoutFailureCount(); 491 492 // Get the lockout duration. 493 this.lockoutDuration = (int) configuration.getLockoutDuration(); 494 495 // Get the lockout failure expiration interval. 496 this.lockoutFailureExpirationInterval = (int) configuration 497 .getLockoutFailureExpirationInterval(); 498 499 // Get the required change time. 500 String requireChangeBy = configuration.getRequireChangeByTime(); 501 try 502 { 503 if (requireChangeBy != null) 504 { 505 ByteString valueString = new ASN1OctetString(requireChangeBy); 506 507 GeneralizedTimeSyntax syntax = 508 (GeneralizedTimeSyntax) 509 DirectoryServer.getAttributeSyntax(SYNTAX_GENERALIZED_TIME_OID, 510 false); 511 512 if (syntax == null) 513 { 514 this.requireChangeByTime = 515 GeneralizedTimeSyntax.decodeGeneralizedTimeValue(valueString); 516 } 517 else 518 { 519 valueString = 520 syntax.getEqualityMatchingRule().normalizeValue(valueString); 521 this.requireChangeByTime = 522 GeneralizedTimeSyntax.decodeGeneralizedTimeValue(valueString); 523 } 524 } 525 } 526 catch (Exception e) 527 { 528 if (debugEnabled()) 529 { 530 TRACER.debugCaught(DebugLogLevel.ERROR, e); 531 } 532 533 Message message = ERR_PWPOLICY_CANNOT_DETERMINE_REQUIRE_CHANGE_BY_TIME. 534 get(String.valueOf(configEntryDN), getExceptionMessage(e)); 535 throw new InitializationException(message, e); 536 } 537 538 539 // Get the last login time attribute. If specified, it must be defined in 540 // the server schema. It does not need to have a generalized time syntax 541 // because the value that it will store will not necessarily conform to this 542 // format. 543 lastLoginTimeAttribute = configuration.getLastLoginTimeAttribute(); 544 545 546 // Get the last login time format. If specified, it must be a valid format 547 // string. 548 String formatString = configuration.getLastLoginTimeFormat(); 549 try 550 { 551 if (formatString != null) 552 { 553 try 554 { 555 new SimpleDateFormat(formatString); 556 } 557 catch (Exception e) 558 { 559 if (debugEnabled()) 560 { 561 TRACER.debugCaught(DebugLogLevel.ERROR, e); 562 } 563 564 Message message = ERR_PWPOLICY_INVALID_LAST_LOGIN_TIME_FORMAT.get( 565 String.valueOf(configEntryDN), String.valueOf(formatString)); 566 throw new ConfigException(message); 567 } 568 569 this.lastLoginTimeFormat = formatString; 570 } 571 } 572 catch (ConfigException ce) 573 { 574 throw ce; 575 } 576 catch (Exception e) 577 { 578 if (debugEnabled()) 579 { 580 TRACER.debugCaught(DebugLogLevel.ERROR, e); 581 } 582 583 Message message = ERR_PWPOLICY_CANNOT_DETERMINE_LAST_LOGIN_TIME_FORMAT. 584 get(String.valueOf(configEntryDN), getExceptionMessage(e)); 585 throw new InitializationException(message, e); 586 } 587 588 589 // Get the previous last login time formats. If specified, they must all 590 // be valid format strings. 591 SortedSet<String> formatStrings = 592 configuration.getPreviousLastLoginTimeFormat() ; 593 try 594 { 595 if (formatStrings != null) 596 { 597 for (String s : formatStrings) 598 { 599 try 600 { 601 new SimpleDateFormat(s); 602 } 603 catch (Exception e) 604 { 605 if (debugEnabled()) 606 { 607 TRACER.debugCaught(DebugLogLevel.ERROR, e); 608 } 609 610 Message message = 611 ERR_PWPOLICY_INVALID_PREVIOUS_LAST_LOGIN_TIME_FORMAT. 612 get(String.valueOf(configEntryDN), String.valueOf(s)); 613 throw new ConfigException(message); 614 } 615 } 616 617 this.previousLastLoginTimeFormats = 618 new CopyOnWriteArrayList<String>(formatStrings); 619 } 620 } 621 catch (ConfigException ce) 622 { 623 throw ce; 624 } 625 catch (Exception e) 626 { 627 if (debugEnabled()) 628 { 629 TRACER.debugCaught(DebugLogLevel.ERROR, e); 630 } 631 632 Message message = 633 ERR_PWPOLICY_CANNOT_DETERMINE_PREVIOUS_LAST_LOGIN_TIME_FORMAT. 634 get(String.valueOf(configEntryDN), getExceptionMessage(e)); 635 throw new InitializationException(message, e); 636 } 637 638 639 // Get the idle lockout duration. 640 this.idleLockoutInterval = (int) configuration.getIdleLockoutInterval(); 641 642 643 // Get the state update failure policy. 644 this.stateUpdateFailurePolicy = configuration.getStateUpdateFailurePolicy(); 645 646 647 // Get the password history count and duration. 648 this.historyCount = configuration.getPasswordHistoryCount(); 649 this.historyDuration = (int) configuration.getPasswordHistoryDuration(); 650 651 652 /* 653 * Holistic validation. 654 */ 655 656 // Ensure that the password attribute was included in the configuration 657 // entry, since it is required. 658 if (passwordAttribute == null) 659 { 660 Message message = 661 ERR_PWPOLICY_NO_PASSWORD_ATTRIBUTE.get(String.valueOf(configEntryDN)); 662 throw new ConfigException(message); 663 } 664 665 // Ensure that at least one default password storage scheme was included in 666 // the configuration entry, since it is required. 667 if (defaultStorageSchemes.isEmpty()) 668 { 669 Message message = ERR_PWPOLICY_NO_DEFAULT_STORAGE_SCHEMES.get( 670 String.valueOf(configEntryDN)); 671 throw new ConfigException(message); 672 } 673 674 // If both a maximum password age and a warning interval are provided, then 675 // ensure that the warning interval is less than the maximum age. Further, 676 // if a minimum age is specified, then the sum of the minimum age and the 677 // warning interval should be less than the maximum age. 678 if (maximumPasswordAge > 0) 679 { 680 int warnInterval = Math.max(0, warningInterval); 681 if (minimumPasswordAge > 0) 682 { 683 if ((warnInterval + minimumPasswordAge) >= maximumPasswordAge) 684 { 685 Message message = 686 ERR_PWPOLICY_MIN_AGE_PLUS_WARNING_GREATER_THAN_MAX_AGE. 687 get(String.valueOf(configEntryDN)); 688 throw new ConfigException(message); 689 } 690 } 691 else if (warnInterval >= maximumPasswordAge) 692 { 693 Message message = ERR_PWPOLICY_WARNING_INTERVAL_LARGER_THAN_MAX_AGE.get( 694 String.valueOf(configEntryDN)); 695 throw new ConfigException(message); 696 } 697 } 698 } 699 700 701 702 /** 703 * Retrieves the DN of the configuration entry to which this password policy 704 * corresponds. 705 * 706 * @return The DN of the configuration entry. 707 */ 708 public DN getConfigEntryDN() 709 { 710 return configEntryDN; 711 } 712 713 714 715 /** 716 * Retrieves the attribute type used to store the password. 717 * 718 * @return The attribute type used to store the password. 719 */ 720 public AttributeType getPasswordAttribute() 721 { 722 return passwordAttribute; 723 } 724 725 726 727 /** 728 * Indicates whether the associated password attribute uses the auth password 729 * syntax. 730 * 731 * @return <CODE>true</CODE> if the associated password attribute uses the 732 * auth password syntax, or <CODE>false</CODE> if not. 733 */ 734 public boolean usesAuthPasswordSyntax() 735 { 736 return authPasswordSyntax; 737 } 738 739 740 741 /** 742 * Retrieves the default set of password storage schemes that will be used for 743 * this password policy. The returned set should not be modified by the 744 * caller. 745 * 746 * @return The default set of password storage schemes that will be used for 747 * this password policy. 748 */ 749 public CopyOnWriteArrayList<PasswordStorageScheme> getDefaultStorageSchemes() 750 { 751 return defaultStorageSchemes; 752 } 753 754 755 756 /** 757 * Indicates whether the specified storage scheme is a default scheme for this 758 * password policy. 759 * 760 * @param name The name of the password storage scheme for which to make the 761 * determination. 762 * 763 * @return <CODE>true</CODE> if the storage scheme is a default scheme for 764 * this password policy, or <CODE>false</CODE> if not. 765 */ 766 public boolean isDefaultStorageScheme(String name) 767 { 768 CopyOnWriteArrayList<PasswordStorageScheme> defaultSchemes = 769 getDefaultStorageSchemes(); 770 if (defaultSchemes == null) 771 { 772 return false; 773 } 774 775 for (PasswordStorageScheme s : defaultSchemes) 776 { 777 if (authPasswordSyntax) 778 { 779 if (s.getAuthPasswordSchemeName().equalsIgnoreCase(name)) 780 { 781 return true; 782 } 783 } 784 else 785 { 786 if (s.getStorageSchemeName().equalsIgnoreCase(name)) 787 { 788 return true; 789 } 790 } 791 } 792 793 794 return false; 795 } 796 797 798 799 /** 800 * Retrieves the names of the password storage schemes that have been 801 * deprecated. If an authenticating user has one or more of these deprecated 802 * storage schemes in use in their entry, then they will be removed and 803 * replaced with the passwords encoded in the default storage scheme(s). The 804 * returned list should not be altered by the caller. 805 * 806 * @return The names of the password storage schemes that have been 807 * deprecated. 808 */ 809 public CopyOnWriteArraySet<String> getDeprecatedStorageSchemes() 810 { 811 return deprecatedStorageSchemes; 812 } 813 814 815 816 /** 817 * Indicates whether the specified storage scheme is deprecated. 818 * 819 * @param name The name of the password storage scheme for which to make the 820 * determination. 821 * 822 * @return <CODE>true</CODE> if the storage scheme is deprecated, or 823 * <CODE>false</CODE> if not. 824 */ 825 public boolean isDeprecatedStorageScheme(String name) 826 { 827 CopyOnWriteArraySet<String> deprecatedSchemes = 828 getDeprecatedStorageSchemes(); 829 if (deprecatedSchemes == null) 830 { 831 return false; 832 } 833 834 for (String s : deprecatedSchemes) 835 { 836 if (s.equalsIgnoreCase(name)) 837 { 838 return true; 839 } 840 } 841 842 return false; 843 } 844 845 846 847 /** 848 * Retrieves the set of password validators for this password policy. The 849 * returned list should not be altered by the caller. 850 * 851 * @return The set of password validators for this password policy. 852 */ 853 public ConcurrentHashMap<DN, 854 PasswordValidator<? extends PasswordValidatorCfg>> 855 getPasswordValidators() 856 { 857 return passwordValidators; 858 } 859 860 861 862 /** 863 * Retrieves the set of account status notification handlers that should be 864 * used with this password policy. The returned list should not be altered by 865 * the caller. 866 * 867 * @return The set of account status notification handlers that should be 868 * used with this password policy. 869 */ 870 public ConcurrentHashMap<DN,AccountStatusNotificationHandler> 871 getAccountStatusNotificationHandlers() 872 { 873 return notificationHandlers; 874 } 875 876 877 878 /** 879 * Indicates whether end users will be allowed to change their own passwords 880 * (subject to access control restrictions). 881 * 882 * @return <CODE>true</CODE> if users will be allowed to change their own 883 * passwords, or <CODE>false</CODE> if not. 884 */ 885 public boolean allowUserPasswordChanges() 886 { 887 return allowUserPasswordChanges; 888 } 889 890 891 892 /** 893 * Indicates whether the end user must provide their current password (via the 894 * password modify extended operation) in order to set a new password. 895 * 896 * @return <CODE>true</CODE> if the end user must provide their current 897 * password in order to set a new password, or <CODE>false</CODE> if 898 * they will not. 899 */ 900 public boolean requireCurrentPassword() 901 { 902 return requireCurrentPassword; 903 } 904 905 906 907 /** 908 * Indicates whether users will be required to change their passwords as soon 909 * as they authenticate after their accounts have been created. 910 * 911 * @return <CODE>true</CODE> if users will be required to change their 912 * passwords at the initial authentication, or <CODE>false</CODE> if 913 * not. 914 */ 915 public boolean forceChangeOnAdd() 916 { 917 return forceChangeOnAdd; 918 } 919 920 921 922 /** 923 * Indicates whether a user will be required to change their password after it 924 * has been reset by an administrator. 925 * 926 * @return <CODE>true</CODE> if a user will be required to change their 927 * password after it has been reset by an administrator, or 928 * <CODE>false</CODE> if they can continue using that password. 929 */ 930 public boolean forceChangeOnReset() 931 { 932 return forceChangeOnReset; 933 } 934 935 936 937 /** 938 * Indicates whether operations by administrators that specify a new password 939 * for a user (e.g., add, modify, or password modify) will be allowed to 940 * bypass the password validation process that will be required for user 941 * password changes. 942 * 943 * @return <CODE>true</CODE> if administrators will be allowed to bypass the 944 * validation checks, or <CODE>false</CODE> if not. 945 */ 946 public boolean skipValidationForAdministrators() 947 { 948 return skipValidationForAdministrators; 949 } 950 951 952 953 /** 954 * Retrieves the DN of the password validator configuration entry. 955 * 956 * @return The DN of the password validator configuration entry. 957 */ 958 public DN getPasswordGeneratorDN() 959 { 960 return passwordGeneratorDN; 961 } 962 963 964 965 /** 966 * Retrieves the password generator that will be used with this password 967 * policy. 968 * 969 * @return The password generator that will be used with this password 970 * policy, or <CODE>null</CODE> if there is none. 971 */ 972 public PasswordGenerator getPasswordGenerator() 973 { 974 return passwordGenerator; 975 } 976 977 978 979 /** 980 * Retrieves the maximum number of previous passwords to maintain in the 981 * password history. 982 * 983 * @return The maximum number of previous passwords to maintain in the 984 * password history. 985 */ 986 public int getPasswordHistoryCount() 987 { 988 return historyCount; 989 } 990 991 992 993 /** 994 * Retrieves the maximum length of time in seconds that previous passwords 995 * should remain in the password history. 996 * 997 * @return The maximum length of time in seconds that previous passwords 998 * should remain in the password history. 999 */ 1000 public int getPasswordHistoryDuration() 1001 { 1002 return historyDuration; 1003 } 1004 1005 1006 1007 /** 1008 * Indicates whether users with this password policy will be required to 1009 * authenticate in a secure manner that does not expose their password. 1010 * 1011 * @return <CODE>true</CODE> if users with this password policy will be 1012 * required to authenticate in a secure manner that does not expose 1013 * their password, or <CODE>false</CODE> if they may authenticate in 1014 * an insecure manner. 1015 */ 1016 public boolean requireSecureAuthentication() 1017 { 1018 return requireSecureAuthentication; 1019 } 1020 1021 1022 1023 /** 1024 * Indicates whether users with this password policy will be required to 1025 * change their passwords in a secure manner that does not expose the new 1026 * password. 1027 * 1028 * @return <CODE>true</CODE> if users with this password policy will be 1029 * required to change their passwords in a secure manner that does 1030 * not expose the new password, or <CODE>false</CODE> if they may 1031 * change their password in an insecure manner. 1032 */ 1033 public boolean requireSecurePasswordChanges() 1034 { 1035 return requireSecurePasswordChanges; 1036 } 1037 1038 1039 1040 /** 1041 * Indicates whether user entries will be allowed to have multiple distinct 1042 * values in the password attribute. 1043 * 1044 * @return <CODE>true</CODE> if clients will be allowed to have multiple 1045 * distinct password values, or <CODE>false</CODE> if not. 1046 */ 1047 public boolean allowMultiplePasswordValues() 1048 { 1049 return allowMultiplePasswordValues; 1050 } 1051 1052 1053 1054 /** 1055 * Indicates whether clients will be allowed to set pre-encoded passwords that 1056 * are already hashed and therefore cannot be validated for correctness. 1057 * 1058 * @return <CODE>true</CODE> if clients will be allowed to set pre-encoded 1059 * passwords that cannot be validated, or <CODE>false</CODE> if not. 1060 */ 1061 public boolean allowPreEncodedPasswords() 1062 { 1063 return allowPreEncodedPasswords; 1064 } 1065 1066 1067 1068 /** 1069 * Retrieves the minimum password age, which is the minimum length of time in 1070 * seconds that must elapse between user password changes. 1071 * 1072 * @return The minimum password age, which is the minimum length of time in 1073 * seconds that must elapse between user password changes, or zero if 1074 * there is no minimum age. 1075 */ 1076 public int getMinimumPasswordAge() 1077 { 1078 if (minimumPasswordAge <= 0) 1079 { 1080 return 0; 1081 } 1082 1083 return minimumPasswordAge; 1084 } 1085 1086 1087 1088 /** 1089 * Retrieves the maximum length of time in seconds that will be allowed to 1090 * pass between password changes before the password is expired. 1091 * 1092 * @return The maximum length of time in seconds that will be allowed to pass 1093 * between password changes before the password is expired, or zero 1094 * if password expiration should not be used. 1095 */ 1096 public int getMaximumPasswordAge() 1097 { 1098 if (maximumPasswordAge < 0) 1099 { 1100 return 0; 1101 } 1102 1103 return maximumPasswordAge; 1104 } 1105 1106 1107 1108 /** 1109 * Retrieves the maximum length of time in seconds that will be allowed to 1110 * pass after an administrative password reset before that password is 1111 * expired. 1112 * 1113 * @return The maximum length of time in seconds that will be allowed to pass 1114 * after an administrative password reset before that password is 1115 * expired, or zero if there is no limit. 1116 */ 1117 public int getMaximumPasswordResetAge() 1118 { 1119 if (maximumPasswordResetAge < 0) 1120 { 1121 return 0; 1122 } 1123 1124 return maximumPasswordResetAge; 1125 } 1126 1127 1128 1129 /** 1130 * Retrieves the maximum length of time in seconds before the password will 1131 * expire that the user should start receiving warning notifications. 1132 * 1133 * @return The maximum length of time in seconds before the password will 1134 * expire that the user should start receiving warning notifications, 1135 * or zero if no warning should be given. 1136 */ 1137 public int getWarningInterval() 1138 { 1139 if (warningInterval < 0) 1140 { 1141 return 0; 1142 } 1143 1144 return warningInterval; 1145 } 1146 1147 1148 1149 /** 1150 * Indicates whether user passwords will be allowed to expire without the 1151 * user receiving at least one notification during the warning period. 1152 * 1153 * @return <CODE>true</CODE> if user passwords will be allowed to expire 1154 * without the user receiving at least one notification during the 1155 * warning period, or <CODE>false</CODE> if the user will always see 1156 * at least one warning before the password expires. 1157 */ 1158 public boolean expirePasswordsWithoutWarning() 1159 { 1160 return expirePasswordsWithoutWarning; 1161 } 1162 1163 1164 1165 /** 1166 * Indicates whether a user will be allowed to change their password after it 1167 * expires and they have no remaining grace logins (and will not be allowed to 1168 * perform any other operation until the password is changed). 1169 * 1170 * @return <CODE>true</CODE> if a user will be allowed to change their 1171 * password after it expires and they have no remaining grace longs, 1172 * or <CODE>false</CODE> if the account will be completely locked and 1173 * the password must be reset by an administrator. 1174 */ 1175 public boolean allowExpiredPasswordChanges() 1176 { 1177 return allowExpiredPasswordChanges; 1178 } 1179 1180 1181 1182 /** 1183 * Retrieves the maximum number of grace logins that a user will be allowed 1184 * after their password has expired before they are completely locked out. 1185 * 1186 * @return The maximum number of grace logins that a user will be allowed 1187 * after their password has expired before they are completely 1188 * locked out, or zero if no grace logins will be allowed or the 1189 * grace login duration will be in effect instead of a fixed number 1190 * of logins. 1191 */ 1192 public int getGraceLoginCount() 1193 { 1194 if (graceLoginCount < 0) 1195 { 1196 return 0; 1197 } 1198 1199 return graceLoginCount; 1200 } 1201 1202 1203 1204 /** 1205 * Retrieves the maximum number of authentication failures that will be 1206 * allowed before an account is locked out. 1207 * 1208 * @return The maximum number of authentication failures that will be allowed 1209 * before an account is locked out, or zero if no account lockout 1210 * will be in effect. 1211 */ 1212 public int getLockoutFailureCount() 1213 { 1214 if (lockoutFailureCount < 0) 1215 { 1216 return 0; 1217 } 1218 1219 return lockoutFailureCount; 1220 } 1221 1222 1223 1224 /** 1225 * Retrieves the maximum length of time in seconds that an account will be 1226 * locked out due to too many failed authentication attempts. 1227 * 1228 * @return The maximum length of time in seconds that an account will be 1229 * locked out due to too many failed authentication attempts, or 1230 * zero if the account will remain locked until explicitly unlocked 1231 * by an administrator. 1232 */ 1233 public int getLockoutDuration() 1234 { 1235 if (lockoutDuration < 0) 1236 { 1237 return 0; 1238 } 1239 1240 return lockoutDuration; 1241 } 1242 1243 1244 1245 /** 1246 * Retrieves the maximum length of time in seconds that an authentication 1247 * failure will be held against a user before it is removed from the failed 1248 * login count. 1249 * 1250 * @return The maximum length of time in seconds that an authentication 1251 * failure will be held against a user before it is removed from the 1252 * failed login count, or zero if authentication failures will never 1253 * expire. 1254 */ 1255 public int getLockoutFailureExpirationInterval() 1256 { 1257 if (lockoutFailureExpirationInterval < 0) 1258 { 1259 return 0; 1260 } 1261 1262 return lockoutFailureExpirationInterval; 1263 } 1264 1265 1266 1267 /** 1268 * Retrieves the time by which all users will be required to change their 1269 * passwords, expressed in the number of milliseconds since midnight of 1270 * January 1, 1970 (i.e., the zero time for 1271 * <CODE>System.currentTimeMillis()</CODE>). Any passwords not changed before 1272 * this time will automatically enter a state in which they must be changed 1273 * before any other operation will be allowed. 1274 * 1275 * @return The time by which all users will be required to change their 1276 * passwords, or zero if no such constraint is in effect. 1277 */ 1278 public long getRequireChangeByTime() 1279 { 1280 if (requireChangeByTime < 0) 1281 { 1282 return 0; 1283 } 1284 1285 return requireChangeByTime; 1286 } 1287 1288 1289 1290 /** 1291 * Retrieves the attribute type used to store the last login time. 1292 * 1293 * @return The attribute type used to store the last login time, or 1294 * <CODE>null</CODE> if the last login time is not to be maintained. 1295 */ 1296 public AttributeType getLastLoginTimeAttribute() 1297 { 1298 return lastLoginTimeAttribute; 1299 } 1300 1301 1302 1303 /** 1304 * Retrieves the format string that should be used for the last login time. 1305 * 1306 * @return The format string that should be used to for the last login time, 1307 * or <CODE>null</CODE> if the last login time is not to be 1308 * maintained. 1309 */ 1310 public String getLastLoginTimeFormat() 1311 { 1312 return lastLoginTimeFormat; 1313 } 1314 1315 1316 1317 /** 1318 * Retrieves the list of previous last login time formats that might have been 1319 * used for users associated with this password policy. 1320 * 1321 * @return The list of previous last login time formats that might have been 1322 * used for users associated with this password policy. 1323 */ 1324 public CopyOnWriteArrayList<String> getPreviousLastLoginTimeFormats() 1325 { 1326 return previousLastLoginTimeFormats; 1327 } 1328 1329 1330 1331 /** 1332 * Retrieves the maximum length of time in seconds that an account will be 1333 * allowed to remain idle (no authentications performed as the user) before it 1334 * will be locked out. 1335 * 1336 * @return The maximum length of time in seconds that an account will be 1337 * allowed to remain idle before it will be locked out. 1338 */ 1339 public int getIdleLockoutInterval() 1340 { 1341 if (idleLockoutInterval < 0) 1342 { 1343 return 0; 1344 } 1345 1346 return idleLockoutInterval; 1347 } 1348 1349 1350 1351 /** 1352 * Retrieves the state update failure policy for this password policy. 1353 * 1354 * @return The state update failure policy for this password policy. 1355 */ 1356 public PasswordPolicyCfgDefn.StateUpdateFailurePolicy 1357 getStateUpdateFailurePolicy() 1358 { 1359 return stateUpdateFailurePolicy; 1360 } 1361 1362 1363 1364 /** 1365 * Retrieves a string representation of this password policy. 1366 * 1367 * @return A string representation of this password policy. 1368 */ 1369 public String toString() 1370 { 1371 StringBuilder buffer = new StringBuilder(); 1372 toString(buffer); 1373 return buffer.toString(); 1374 } 1375 1376 1377 1378 /** 1379 * Appends a string representation of this password policy to the provided 1380 * buffer. 1381 * 1382 * @param buffer The buffer to which the information should be appended. 1383 */ 1384 public void toString(StringBuilder buffer) 1385 { 1386 buffer.append("Password Attribute: "); 1387 buffer.append(passwordAttribute.getNameOrOID()); 1388 buffer.append(EOL); 1389 1390 buffer.append("Default Password Storage Schemes: "); 1391 if ((defaultStorageSchemes == null) || defaultStorageSchemes.isEmpty()) 1392 { 1393 buffer.append("{none specified}"); 1394 buffer.append(EOL); 1395 } 1396 else 1397 { 1398 Iterator<PasswordStorageScheme> iterator = 1399 defaultStorageSchemes.iterator(); 1400 buffer.append(iterator.next().getStorageSchemeName()); 1401 buffer.append(EOL); 1402 1403 while (iterator.hasNext()) 1404 { 1405 buffer.append(" "); 1406 buffer.append(iterator.next().getStorageSchemeName()); 1407 buffer.append(EOL); 1408 } 1409 } 1410 1411 buffer.append("Deprecated Password Storage Schemes: "); 1412 if ((deprecatedStorageSchemes == null) || 1413 deprecatedStorageSchemes.isEmpty()) 1414 { 1415 buffer.append("{none specified}"); 1416 buffer.append(EOL); 1417 } 1418 else 1419 { 1420 Iterator<String> iterator = deprecatedStorageSchemes.iterator(); 1421 buffer.append(iterator.next()); 1422 buffer.append(EOL); 1423 1424 while (iterator.hasNext()) 1425 { 1426 buffer.append(" "); 1427 buffer.append(iterator.next()); 1428 buffer.append(EOL); 1429 } 1430 } 1431 1432 buffer.append("Allow Multiple Password Values: "); 1433 buffer.append(allowMultiplePasswordValues); 1434 buffer.append(EOL); 1435 1436 buffer.append("Allow Pre-Encoded Passwords: "); 1437 buffer.append(allowPreEncodedPasswords); 1438 buffer.append(EOL); 1439 1440 buffer.append("Allow User Password Changes: "); 1441 buffer.append(allowUserPasswordChanges); 1442 buffer.append(EOL); 1443 1444 buffer.append("Force Password Change on Add: "); 1445 buffer.append(forceChangeOnAdd); 1446 buffer.append(EOL); 1447 1448 buffer.append("Force Password Change on Admin Reset: "); 1449 buffer.append(forceChangeOnReset); 1450 buffer.append(EOL); 1451 1452 buffer.append("Require Current Password: "); 1453 buffer.append(requireCurrentPassword); 1454 buffer.append(EOL); 1455 1456 buffer.append("Require Secure Authentication: "); 1457 buffer.append(requireSecureAuthentication); 1458 buffer.append(EOL); 1459 1460 buffer.append("Require Secure Password Changes: "); 1461 buffer.append(requireSecurePasswordChanges); 1462 buffer.append(EOL); 1463 1464 buffer.append("Lockout Failure Expiration Interval: "); 1465 buffer.append(lockoutFailureExpirationInterval); 1466 buffer.append(" seconds"); 1467 buffer.append(EOL); 1468 1469 buffer.append("Password Validators: "); 1470 if ((passwordValidators == null) || passwordValidators.isEmpty()) 1471 { 1472 buffer.append("{none specified}"); 1473 buffer.append(EOL); 1474 } 1475 else 1476 { 1477 Iterator<DN> iterator = passwordValidators.keySet().iterator(); 1478 iterator.next().toString(buffer); 1479 buffer.append(EOL); 1480 1481 while (iterator.hasNext()) 1482 { 1483 buffer.append(" "); 1484 iterator.next().toString(buffer); 1485 buffer.append(EOL); 1486 } 1487 } 1488 1489 buffer.append("Skip Validation for Administrators: "); 1490 buffer.append(skipValidationForAdministrators); 1491 buffer.append(EOL); 1492 1493 buffer.append("Password Generator: "); 1494 if (passwordGenerator == null) 1495 { 1496 buffer.append("{none specified}"); 1497 } 1498 else 1499 { 1500 passwordGeneratorDN.toString(buffer); 1501 } 1502 buffer.append(EOL); 1503 1504 buffer.append("Account Status Notification Handlers: "); 1505 if ((notificationHandlers == null) || notificationHandlers.isEmpty()) 1506 { 1507 buffer.append("{none specified}"); 1508 buffer.append(EOL); 1509 } 1510 else 1511 { 1512 Iterator<DN> iterator = notificationHandlers.keySet().iterator(); 1513 iterator.next().toString(buffer); 1514 buffer.append(EOL); 1515 1516 while (iterator.hasNext()) 1517 { 1518 buffer.append(" "); 1519 iterator.next().toString(buffer); 1520 buffer.append(EOL); 1521 } 1522 } 1523 1524 buffer.append("Minimum Password Age: "); 1525 buffer.append(minimumPasswordAge); 1526 buffer.append(" seconds"); 1527 buffer.append(EOL); 1528 1529 buffer.append("Maximum Password Age: "); 1530 buffer.append(maximumPasswordAge); 1531 buffer.append(" seconds"); 1532 buffer.append(EOL); 1533 1534 buffer.append("Maximum Password Reset Age: "); 1535 buffer.append(maximumPasswordResetAge); 1536 buffer.append(" seconds"); 1537 buffer.append(EOL); 1538 1539 buffer.append("Expiration Warning Interval: "); 1540 buffer.append(warningInterval); 1541 buffer.append(" seconds"); 1542 buffer.append(EOL); 1543 1544 buffer.append("Expire Passwords Without Warning: "); 1545 buffer.append(expirePasswordsWithoutWarning); 1546 buffer.append(EOL); 1547 1548 buffer.append("Allow Expired Password Changes: "); 1549 buffer.append(allowExpiredPasswordChanges); 1550 buffer.append(EOL); 1551 1552 buffer.append("Grace Login Count: "); 1553 buffer.append(graceLoginCount); 1554 buffer.append(EOL); 1555 1556 buffer.append("Lockout Failure Count: "); 1557 buffer.append(lockoutFailureCount); 1558 buffer.append(EOL); 1559 1560 buffer.append("Lockout Duration: "); 1561 buffer.append(lockoutDuration); 1562 buffer.append(" seconds"); 1563 buffer.append(EOL); 1564 1565 buffer.append("Lockout Count Expiration Interval: "); 1566 buffer.append(lockoutFailureExpirationInterval); 1567 buffer.append(" seconds"); 1568 buffer.append(EOL); 1569 1570 buffer.append("Required Password Change By Time: "); 1571 if (requireChangeByTime <= 0) 1572 { 1573 buffer.append("{none specified}"); 1574 } 1575 else 1576 { 1577 SimpleDateFormat dateFormat = 1578 new SimpleDateFormat(DATE_FORMAT_GENERALIZED_TIME); 1579 dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); 1580 buffer.append(dateFormat.format(new Date(requireChangeByTime))); 1581 } 1582 buffer.append(EOL); 1583 1584 buffer.append("Last Login Time Attribute: "); 1585 if (lastLoginTimeAttribute == null) 1586 { 1587 buffer.append("{none specified}"); 1588 } 1589 else 1590 { 1591 buffer.append(lastLoginTimeAttribute.getNameOrOID()); 1592 } 1593 buffer.append(EOL); 1594 1595 buffer.append("Last Login Time Format: "); 1596 if (lastLoginTimeFormat == null) 1597 { 1598 buffer.append("{none specified}"); 1599 } 1600 else 1601 { 1602 buffer.append(lastLoginTimeFormat); 1603 } 1604 buffer.append(EOL); 1605 1606 buffer.append("Previous Last Login Time Formats: "); 1607 if ((previousLastLoginTimeFormats == null) || 1608 previousLastLoginTimeFormats.isEmpty()) 1609 { 1610 buffer.append("{none specified}"); 1611 buffer.append(EOL); 1612 } 1613 else 1614 { 1615 Iterator<String> iterator = previousLastLoginTimeFormats.iterator(); 1616 1617 buffer.append(iterator.next()); 1618 buffer.append(EOL); 1619 1620 while (iterator.hasNext()) 1621 { 1622 buffer.append(" "); 1623 buffer.append(iterator.next()); 1624 buffer.append(EOL); 1625 } 1626 } 1627 1628 buffer.append("Idle Lockout Interval: "); 1629 buffer.append(idleLockoutInterval); 1630 buffer.append(" seconds"); 1631 buffer.append(EOL); 1632 1633 buffer.append("History Count: "); 1634 buffer.append(historyCount); 1635 buffer.append(EOL); 1636 1637 buffer.append("Update Failure Policy: "); 1638 buffer.append(stateUpdateFailurePolicy.toString()); 1639 buffer.append(EOL); 1640 } 1641 } 1642