opends/resource/config/config.ldif
@@ -1448,7 +1448,9 @@ dn: cn=Default Password Policy,cn=Password Policies,cn=config objectClass: top objectClass: ds-cfg-authentication-policy objectClass: ds-cfg-password-policy ds-cfg-java-class: org.opends.server.core.PasswordPolicyFactory cn: Default Password Policy ds-cfg-password-attribute: userPassword ds-cfg-default-password-storage-scheme: cn=Salted SHA-1,cn=Password Storage Schemes,cn=config @@ -1479,7 +1481,9 @@ dn: cn=Root Password Policy,cn=Password Policies,cn=config objectClass: top objectClass: ds-cfg-authentication-policy objectClass: ds-cfg-password-policy ds-cfg-java-class: org.opends.server.core.PasswordPolicyFactory cn: Root Password Policy ds-cfg-password-attribute: userPassword ds-cfg-default-password-storage-scheme: cn=Salted SHA-512,cn=Password Storage Schemes,cn=config opends/resource/schema/02-config.ldif
@@ -3180,12 +3180,18 @@ MUST ( ds-cfg-password-character-set $ ds-cfg-password-format ) X-ORIGIN 'OpenDS Directory Server' ) objectClasses: ( 1.3.6.1.4.1.26027.1.2.61 NAME 'ds-cfg-password-policy' objectClasses: ( 1.3.6.1.4.1.36733.2.1.2.3 NAME 'ds-cfg-authentication-policy' SUP top STRUCTURAL MUST ( cn $ ds-cfg-password-attribute $ MUST ( cn ) MAY ( ds-cfg-java-class ) X-ORIGIN 'OpenDJ Directory Server' ) objectClasses: ( 1.3.6.1.4.1.26027.1.2.61 NAME 'ds-cfg-password-policy' SUP ds-cfg-authentication-policy STRUCTURAL MUST ( ds-cfg-password-attribute $ ds-cfg-default-password-storage-scheme ) MAY ( ds-cfg-account-status-notification-handler $ ds-cfg-allow-expired-password-changes $ opends/src/admin/defn/org/opends/server/admin/std/AuthenticationPolicyConfiguration.xml
New file @@ -0,0 +1,67 @@ <?xml version="1.0" encoding="UTF-8"?> <!-- ! CDDL HEADER START ! ! The contents of this file are subject to the terms of the ! Common Development and Distribution License, Version 1.0 only ! (the "License"). You may not use this file except in compliance ! with the License. ! ! You can obtain a copy of the license at ! trunk/opends/resource/legal-notices/OpenDS.LICENSE ! or https://OpenDS.dev.java.net/OpenDS.LICENSE. ! See the License for the specific language governing permissions ! and limitations under the License. ! ! When distributing Covered Code, include this CDDL HEADER in each ! file and include the License file at ! trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, ! add the following below this CDDL HEADER, with the fields enclosed ! by brackets "[]" replaced with your own identifying information: ! Portions Copyright [yyyy] [name of copyright owner] ! ! CDDL HEADER END ! ! ! Copyright 2011 ForgeRock AS ! --> <adm:managed-object name="authentication-policy" plural-name="authentication-policies" abstract="true" package="org.opends.server.admin.std" xmlns:adm="http://www.opends.org/admin" xmlns:ldap="http://www.opends.org/admin-ldap"> <adm:synopsis> <adm:user-friendly-plural-name /> define the policies which should be used for authenticating users and managing the password and other account related state. </adm:synopsis> <adm:tag name="user-management" /> <adm:profile name="ldap"> <ldap:object-class> <ldap:name>ds-cfg-authentication-policy</ldap:name> <ldap:superior>top</ldap:superior> </ldap:object-class> </adm:profile> <adm:property name="java-class" mandatory="true"> <adm:synopsis> Specifies the fully-qualified name of the Java class which provides the <adm:user-friendly-name /> implementation. </adm:synopsis> <adm:requires-admin-action> <adm:component-restart /> </adm:requires-admin-action> <adm:syntax> <adm:java-class> <adm:instance-of> org.opends.server.api.AuthenticationPolicyFactory </adm:instance-of> </adm:java-class> </adm:syntax> <adm:profile name="ldap"> <ldap:attribute> <ldap:name>ds-cfg-java-class</ldap:name> </ldap:attribute> </adm:profile> </adm:property> </adm:managed-object> opends/src/admin/defn/org/opends/server/admin/std/GlobalConfiguration.xml
@@ -80,6 +80,13 @@ for users whose entries do not specify an alternate password policy (either via a real or virtual attribute). </adm:synopsis> <adm:description> In addition, the default password policy will be used for providing default parameters for sub-entry based password policies when not provided or supported by the sub-entry itself. This property must reference a password policy and no other type of authentication policy. </adm:description> <adm:syntax> <adm:aggregation relation-name="password-policy" parent-path="/" /> </adm:syntax> opends/src/admin/defn/org/opends/server/admin/std/PasswordPolicyConfiguration.xml
@@ -27,7 +27,9 @@ ! Portions Copyright 2011 ForgeRock AS ! --> <adm:managed-object name="password-policy" plural-name="password-policies" package="org.opends.server.admin.std" plural-name="password-policies" extends="authentication-policy" package="org.opends.server.admin.std" xmlns:adm="http://www.opends.org/admin" xmlns:ldap="http://www.opends.org/admin-ldap"> <adm:synopsis> @@ -35,13 +37,21 @@ define a number of password management rules, as well as requirements for authentication processing. </adm:synopsis> <adm:tag name="user-management" /> <adm:profile name="ldap"> <ldap:object-class> <ldap:name>ds-cfg-password-policy</ldap:name> <ldap:superior>top</ldap:superior> <ldap:superior>ds-cfg-authentication-policy</ldap:superior> </ldap:object-class> </adm:profile> <adm:property-override name="java-class" advanced="true"> <adm:default-behavior> <adm:defined> <adm:value> org.opends.server.core.PasswordPolicyFactory </adm:value> </adm:defined> </adm:default-behavior> </adm:property-override> <adm:property name="password-attribute" mandatory="true"> <adm:synopsis> Specifies the attribute type used to hold user passwords. opends/src/admin/defn/org/opends/server/admin/std/RootConfiguration.xml
@@ -289,8 +289,9 @@ </cli:relation> </adm:profile> </adm:relation> <adm:relation name="password-policy"> <adm:one-to-many /> <adm:relation name="password-policy" managed-object-name="authentication-policy"> <adm:one-to-many plural-name="password-policies" /> <adm:profile name="ldap"> <ldap:rdn-sequence> cn=Password Policies,cn=config opends/src/admin/messages/AuthenticationPolicyCfgDefn.properties
New file @@ -0,0 +1,4 @@ user-friendly-name=Authentication Policy user-friendly-plural-name=Authentication Policies synopsis=Authentication Policies define the policies which should be used for authenticating users and managing the password and other account related state. property.java-class.synopsis=Specifies the fully-qualified name of the Java class which provides the Authentication Policy implementation. opends/src/admin/messages/GlobalCfgDefn.properties
@@ -11,6 +11,7 @@ property.check-schema.synopsis=Indicates whether schema enforcement is active. property.check-schema.description=When schema enforcement is activated, the directory server ensures that all operations result in entries are valid according to the defined server schema. It is strongly recommended that this option be left enabled to prevent the inadvertent addition of invalid data into the server. property.default-password-policy.synopsis=Specifies the name of the password policy that is in effect for users whose entries do not specify an alternate password policy (either via a real or virtual attribute). property.default-password-policy.description=In addition, the default password policy will be used for providing default parameters for sub-entry based password policies when not provided or supported by the sub-entry itself. This property must reference a password policy and no other type of authentication policy. property.disabled-privilege.synopsis=Specifies the name of a privilege that should not be evaluated by the server. property.disabled-privilege.description=If a privilege is disabled, then it is assumed that all clients (including unauthenticated clients) have that privilege. property.disabled-privilege.default-behavior.alias.synopsis=If no values are defined, then the server enforces all privileges. opends/src/admin/messages/PasswordPolicyCfgDefn.properties
@@ -24,6 +24,7 @@ property.grace-login-count.description=A value of 0 indicates that no grace logins are allowed. property.idle-lockout-interval.synopsis=Specifies the maximum length of time that an account may remain idle (that is, the associated user does not authenticate to the server) before that user is locked out. property.idle-lockout-interval.description=The value of this attribute is an integer followed by a unit of seconds, minutes, hours, days, or weeks. A value of 0 seconds indicates that idle accounts are not automatically locked out. This feature is available only if the last login time is maintained. property.java-class.synopsis=Specifies the fully-qualified name of the Java class which provides the Password Policy implementation. property.last-login-time-attribute.synopsis=Specifies the name or OID of the attribute type that is used to hold the last login time for users with the associated password policy. property.last-login-time-attribute.description=This attribute type must be defined in the directory server schema and must either be defined as an operational attribute or must be allowed by the set of objectClasses for all users with the associated password policy. property.last-login-time-format.synopsis=Specifies the format string that is used to generate the last login time value for users with the associated password policy. opends/src/admin/messages/RootCfgDefn.properties
@@ -83,7 +83,7 @@ relation.password-generator.description=The server allows any number of password validators to be defined. This can impose any kinds of restrictions on the characteristics of valid passwords. Therefore, it is not feasible for the server to attempt to generate a password on its own that will meet all the requirements of all the validators. The password generator makes it possible to provide custom logic for creating a new password. relation.password-policy.user-friendly-name=Password Policy relation.password-policy.user-friendly-plural-name=Password Policies relation.password-policy.synopsis=Password Policies define a number of password management rules, as well as requirements for authentication processing. relation.password-policy.synopsis=Authentication Policies define the policies which should be used for authenticating users and managing the password and other account related state. relation.password-storage-scheme.user-friendly-name=Password Storage Scheme relation.password-storage-scheme.user-friendly-plural-name=Password Storage Schemes relation.password-storage-scheme.synopsis=Password Storage Schemes encode new passwords provided by users so that they are stored in an encoded manner. This makes it difficult or impossible for someone to determine the clear-text passwords from the encoded values. opends/src/messages/messages/config.properties
@@ -2163,3 +2163,9 @@ MILD_ERR_CONFIG_CORE_INVALID_MAX_PSEARCH_LIMIT_725=The provided maximum allowed \ simultaneous persistent searches '%d' is invalid. The maximum allowed \ value must be between 0 and '%d' where '%d' is the number of worker threads SEVERE_ERR_CONFIG_PWPOLICY_DEFAULT_POLICY_IS_WRONG_TYPE_726=The configuration \ entry '%s' is currently defined to be the default password policy, however it \ is not a password policy MILD_ERR_CONFIG_PWPOLICY_CANNOT_CHANGE_DEFAULT_POLICY_WRONG_TYPE_727=The \ default password policy value '%s' is invalid because it refers to an \ authentication policy which is not a password policy opends/src/server/org/opends/server/api/AuthenticationPolicy.java
New file @@ -0,0 +1,71 @@ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at * trunk/opends/resource/legal-notices/OpenDS.LICENSE * or https://OpenDS.dev.java.net/OpenDS.LICENSE. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, * add the following below this CDDL HEADER, with the fields enclosed * by brackets "[]" replaced with your own identifying information: * Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * * Copyright 2011 ForgeRock AS. */ package org.opends.server.api; import org.opends.server.types.DN; /** * An abstract authentication policy. */ public abstract class AuthenticationPolicy { /** * Creates a new abstract authentication policy. */ protected AuthenticationPolicy() { // No implementation required. } /** * Returns the name of the configuration entry associated with this * authentication policy. * * @return The name of the configuration entry associated with this * authentication policy. */ public abstract DN getDN(); /** * Performs any necessary work to finalize this authentication policy. * <p> * The default implementation is to do nothing. */ public void finalizeAuthenticationPolicy() { // Do nothing by default. } } opends/src/server/org/opends/server/api/AuthenticationPolicyFactory.java
New file @@ -0,0 +1,86 @@ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at * trunk/opends/resource/legal-notices/OpenDS.LICENSE * or https://OpenDS.dev.java.net/OpenDS.LICENSE. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, * add the following below this CDDL HEADER, with the fields enclosed * by brackets "[]" replaced with your own identifying information: * Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * * Copyright 2011 ForgeRock AS. */ package org.opends.server.api; import java.util.List; import org.opends.messages.Message; import org.opends.server.admin.std.server.AuthenticationPolicyCfg; import org.opends.server.config.ConfigException; import org.opends.server.types.InitializationException; /** * A factory for creating configurable authentication policies. * <p> * All implementations must have a default constructor, i.e. one that does not * require and arguments. * * @param <T> * The type of authentication policy configuration handled by this * factory. */ public interface AuthenticationPolicyFactory<T extends AuthenticationPolicyCfg> { /** * Creates a new authentication policy using the provided configuration. * * @param configuration * The configuration. * @return The new authentication policy configured using the provided * configuration. * @throws ConfigException * If an unrecoverable problem arises during initialization of the * authentication policy as a result of the server configuration. * @throws InitializationException * If a problem occurs during initialization of the authentication * policy. */ AuthenticationPolicy createAuthenticationPolicy(T configuration) throws ConfigException, InitializationException; /** * Indicates whether the provided authentication policy configuration is * acceptable. * * @param configuration * The authentication policy configuration. * @param unacceptableReasons * A list that can be used to hold messages about why the provided * configuration is not acceptable. * @return Returns <code>true</code> if the provided authentication policy * configuration is acceptable, or <code>false</code> if it is not. */ boolean isConfigurationAcceptable(T configuration, List<Message> unacceptableReasons); } opends/src/server/org/opends/server/core/CoreConfigManager.java
@@ -23,6 +23,7 @@ * * * Copyright 2006-2010 Sun Microsystems, Inc. * Portions copyright 2011 ForgeRock AS. */ package org.opends.server.core; import org.opends.messages.Message; @@ -41,6 +42,7 @@ import org.opends.server.admin.std.server.GlobalCfg; import org.opends.server.admin.std.server.RootCfg; import org.opends.server.admin.server.ServerManagementContext; import org.opends.server.api.AuthenticationPolicy; import org.opends.server.config.ConfigException; import org.opends.server.types.*; @@ -413,6 +415,20 @@ } } // Ensure that the default password policy always points to a password // policy and not another type of authentication policy. DN defaultPasswordPolicyDN = configuration.getDefaultPasswordPolicyDN(); AuthenticationPolicy policy = DirectoryServer .getAuthenticationPolicy(defaultPasswordPolicyDN); if (!(policy instanceof PasswordPolicy)) { Message message = ERR_CONFIG_PWPOLICY_CANNOT_CHANGE_DEFAULT_POLICY_WRONG_TYPE .get(configuration.getDefaultPasswordPolicy()); unacceptableReasons.add(message); configAcceptable = false; } return configAcceptable; } opends/src/server/org/opends/server/core/DirectoryServer.java
@@ -23,7 +23,7 @@ * * * Copyright 2006-2010 Sun Microsystems, Inc. * Portions Copyright 2010 ForgeRock AS. * Portions Copyright 2010-2011 ForgeRock AS. */ package org.opends.server.core; @@ -37,30 +37,19 @@ import static org.opends.server.schema.SchemaConstants.*; import static org.opends.server.util.DynamicConstants.*; import static org.opends.server.util.ServerConstants.*; import static org.opends.server.util.StaticUtils.*; import static org.opends.server.util.Validator.*; import static org.opends.server.util.StaticUtils.getExceptionMessage; import static org.opends.server.util.StaticUtils.stackTraceToSingleLineString; import static org.opends.server.util.StaticUtils.toLowerCase; import static org.opends.server.util.Validator.ensureNotNull; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStream; import java.io.PrintStream; import java.io.*; import java.lang.management.ManagementFactory; import java.net.InetAddress; import java.text.DecimalFormat; import java.util.Collections; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Properties; import java.util.Set; import java.util.TreeMap; import java.util.TreeSet; import java.util.*; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArraySet; import java.lang.management.ManagementFactory; import java.util.concurrent.atomic.AtomicInteger; import javax.management.MBeanServer; @@ -72,63 +61,11 @@ import org.opends.server.admin.ClassLoaderProvider; import org.opends.server.admin.server.ServerManagementContext; import org.opends.server.admin.std.meta.GlobalCfgDefn.WorkflowConfigurationMode; import org.opends.server.admin.std.server.AlertHandlerCfg; import org.opends.server.admin.std.server.AttributeSyntaxCfg; import org.opends.server.admin.std.server.ConnectionHandlerCfg; import org.opends.server.admin.std.server.CryptoManagerCfg; import org.opends.server.admin.std.server.DirectoryStringAttributeSyntaxCfg; import org.opends.server.admin.std.server.MonitorProviderCfg; import org.opends.server.admin.std.server.PasswordValidatorCfg; import org.opends.server.admin.std.server.RootCfg; import org.opends.server.admin.std.server.RootDSEBackendCfg; import org.opends.server.admin.std.server.SynchronizationProviderCfg; import org.opends.server.api.AccessControlHandler; import org.opends.server.api.AccountStatusNotificationHandler; import org.opends.server.api.AlertGenerator; import org.opends.server.api.AlertHandler; import org.opends.server.api.ApproximateMatchingRule; import org.opends.server.api.AttributeSyntax; import org.opends.server.api.Backend; import org.opends.server.api.BackendInitializationListener; import org.opends.server.api.BackupTaskListener; import org.opends.server.api.CertificateMapper; import org.opends.server.api.ChangeNotificationListener; import org.opends.server.api.ClientConnection; import org.opends.server.api.CompressedSchema; import org.opends.server.api.ConfigAddListener; import org.opends.server.api.ConfigChangeListener; import org.opends.server.api.ConfigDeleteListener; import org.opends.server.api.ConfigHandler; import org.opends.server.api.ConnectionHandler; import org.opends.server.api.DirectoryServerMBean; import org.opends.server.api.EntryCache; import org.opends.server.api.EqualityMatchingRule; import org.opends.server.api.ExportTaskListener; import org.opends.server.api.ExtendedOperationHandler; import org.opends.server.api.Extension; import org.opends.server.api.IdentityMapper; import org.opends.server.api.ImportTaskListener; import org.opends.server.api.InitializationCompletedListener; import org.opends.server.api.InvokableComponent; import org.opends.server.api.KeyManagerProvider; import org.opends.server.api.MatchingRule; import org.opends.server.api.MatchingRuleFactory; import org.opends.server.api.MonitorProvider; import org.opends.server.api.OrderingMatchingRule; import org.opends.server.api.PasswordGenerator; import org.opends.server.api.PasswordStorageScheme; import org.opends.server.api.PasswordValidator; import org.opends.server.api.RestoreTaskListener; import org.opends.server.api.SASLMechanismHandler; import org.opends.server.api.ServerShutdownListener; import org.opends.server.api.SubstringMatchingRule; import org.opends.server.api.SynchronizationProvider; import org.opends.server.api.TrustManagerProvider; import org.opends.server.api.WorkQueue; import org.opends.server.admin.std.server.*; import org.opends.server.api.*; import org.opends.server.api.plugin.InternalDirectoryServerPlugin; import org.opends.server.api.plugin.PluginResult; import org.opends.server.api.plugin.PluginType; import org.opends.server.api.ExtensibleMatchingRule; import org.opends.server.backends.RootDSEBackend; import org.opends.server.config.ConfigEntry; import org.opends.server.config.ConfigException; @@ -141,11 +78,7 @@ import org.opends.server.crypto.CryptoManagerSync; import org.opends.server.extensions.ConfigFileHandler; import org.opends.server.extensions.JMXAlertHandler; import org.opends.server.loggers.ErrorLogger; import org.opends.server.loggers.RetentionPolicy; import org.opends.server.loggers.RotationPolicy; import org.opends.server.loggers.TextErrorLogPublisher; import org.opends.server.loggers.TextWriter; import org.opends.server.loggers.*; import org.opends.server.loggers.debug.DebugLogger; import org.opends.server.loggers.debug.DebugTracer; import org.opends.server.loggers.debug.TextDebugLogPublisher; @@ -153,89 +86,15 @@ import org.opends.server.monitors.ConnectionHandlerMonitor; import org.opends.server.protocols.internal.InternalClientConnection; import org.opends.server.protocols.internal.InternalConnectionHandler; import org.opends.server.schema.AttributeTypeSyntax; import org.opends.server.schema.BinarySyntax; import org.opends.server.schema.BooleanEqualityMatchingRuleFactory; import org.opends.server.schema.BooleanSyntax; import org.opends.server.schema.CaseExactEqualityMatchingRuleFactory; import org.opends.server.schema.CaseExactIA5EqualityMatchingRuleFactory; import org.opends.server.schema.CaseExactIA5SubstringMatchingRuleFactory; import org.opends.server.schema.CaseExactOrderingMatchingRuleFactory; import org.opends.server.schema.CaseExactSubstringMatchingRuleFactory; import org.opends.server.schema.CaseIgnoreEqualityMatchingRuleFactory; import org.opends.server.schema.CaseIgnoreIA5EqualityMatchingRuleFactory; import org.opends.server.schema.CaseIgnoreIA5SubstringMatchingRuleFactory; import org.opends.server.schema.CaseIgnoreOrderingMatchingRuleFactory; import org.opends.server.schema.CaseIgnoreSubstringMatchingRuleFactory; import org.opends.server.schema.DirectoryStringSyntax; import org.opends.server.schema.DistinguishedNameEqualityMatchingRuleFactory; import org.opends.server.schema.DistinguishedNameSyntax; import org.opends.server.schema.DoubleMetaphoneApproximateMatchingRuleFactory; import org.opends.server.schema.GeneralizedTimeEqualityMatchingRuleFactory; import org.opends.server.schema.GeneralizedTimeOrderingMatchingRuleFactory; import org.opends.server.schema.GeneralizedTimeSyntax; import org.opends.server.schema.IA5StringSyntax; import org.opends.server.schema.IntegerEqualityMatchingRuleFactory; import org.opends.server.schema.IntegerOrderingMatchingRuleFactory; import org.opends.server.schema.IntegerSyntax; import org.opends.server.schema.OIDSyntax; import org.opends.server.schema.ObjectClassSyntax; import org.opends.server.schema.ObjectIdentifierEqualityMatchingRuleFactory; import org.opends.server.schema.OctetStringEqualityMatchingRuleFactory; import org.opends.server.schema.OctetStringOrderingMatchingRuleFactory; import org.opends.server.schema.OctetStringSubstringMatchingRuleFactory; import org.opends.server.schema.TelephoneNumberEqualityMatchingRuleFactory; import org.opends.server.schema.TelephoneNumberSubstringMatchingRuleFactory; import org.opends.server.schema.TelephoneNumberSyntax; import org.opends.server.schema.*; import org.opends.server.servicetag.ServiceTagRegistration; import org.opends.server.tools.ConfigureWindowsService; import org.opends.server.types.AbstractOperation; import org.opends.server.types.AcceptRejectWarn; import org.opends.server.types.AttributeType; import org.opends.server.types.AttributeUsage; import org.opends.server.types.AttributeValue; import org.opends.server.types.BackupConfig; import org.opends.server.types.Control; import org.opends.server.types.DITContentRule; import org.opends.server.types.DITStructureRule; import org.opends.server.types.DN; import org.opends.server.types.DebugLogLevel; import org.opends.server.types.DirectoryEnvironmentConfig; import org.opends.server.types.DirectoryException; import org.opends.server.types.Entry; import org.opends.server.types.HostPort; import org.opends.server.types.InitializationException; import org.opends.server.types.LDIFExportConfig; import org.opends.server.types.LDIFImportConfig; import org.opends.server.types.LockManager; import org.opends.server.types.MatchingRuleUse; import org.opends.server.types.Modification; import org.opends.server.types.NameForm; import org.opends.server.types.ObjectClass; import org.opends.server.types.ObjectClassType; import org.opends.server.types.OperatingSystem; import org.opends.server.types.Privilege; import org.opends.server.types.RestoreConfig; import org.opends.server.types.ResultCode; import org.opends.server.types.Schema; import org.opends.server.types.VirtualAttributeRule; import org.opends.server.types.WritabilityMode; import org.opends.server.util.MultiOutputStream; import org.opends.server.util.RuntimeInformation; import org.opends.server.util.SetupUtils; import org.opends.server.util.StaticUtils; import org.opends.server.util.TimeThread; import org.opends.server.util.Validator; import org.opends.server.util.VersionCompatibilityIssue; import org.opends.server.util.args.ArgumentException; import org.opends.server.util.args.ArgumentParser; import org.opends.server.util.args.BooleanArgument; import org.opends.server.util.args.IntegerArgument; import org.opends.server.util.args.StringArgument; import org.opends.server.types.*; import org.opends.server.util.*; import org.opends.server.util.args.*; import org.opends.server.workflowelement.WorkflowElement; import org.opends.server.workflowelement.WorkflowElementConfigManager; import org.opends.server.workflowelement. localbackend.LocalBackendWorkflowElement; import org.opends.server.workflowelement.localbackend.*; /** @@ -443,10 +302,10 @@ // generator implementation. private ConcurrentHashMap<DN,PasswordGenerator> passwordGenerators; // The set of password policies registered with the Directory Server, as a // mapping between the DN of the associated configuration entry and the policy // implementation. private ConcurrentHashMap<DN,PasswordPolicyConfig> passwordPolicies; // The set of authentication policies registered with the Directory Server, as // a mapping between the DN of the associated configuration entry and the // policy implementation. private ConcurrentHashMap<DN,AuthenticationPolicy> authenticationPolicies; // The set of password validators registered with the Directory Server, as a // mapping between the DN of the associated configuration entry and the @@ -679,10 +538,10 @@ private PasswordGeneratorConfigManager passwordGeneratorConfigManager; // The default password policy for the Directory Server. private PasswordPolicyConfig defaultPasswordPolicyConfig; private PasswordPolicy defaultPasswordPolicy; // The configuration handler used to manage the password policies. private PasswordPolicyConfigManager passwordPolicyConfigManager; // The configuration handler used to manage the authentication policies. private PasswordPolicyConfigManager authenticationPolicyConfigManager; // The configuration handler used to manage the password storage schemes. private PasswordStorageSchemeConfigManager storageSchemeConfigManager; @@ -956,10 +815,10 @@ new ConcurrentHashMap<DN, RetentionPolicy>(); directoryServer.certificateMappers = new ConcurrentHashMap<DN,CertificateMapper>(); directoryServer.passwordPolicies = new ConcurrentHashMap<DN,PasswordPolicyConfig>(); directoryServer.authenticationPolicies = new ConcurrentHashMap<DN,AuthenticationPolicy>(); directoryServer.defaultPasswordPolicyDN = null; directoryServer.defaultPasswordPolicyConfig = null; directoryServer.defaultPasswordPolicy = null; directoryServer.monitorProviders = new ConcurrentHashMap<String, MonitorProvider<? extends MonitorProviderCfg>>(); @@ -1496,8 +1355,8 @@ monitorConfigManager.initializeMonitorProviders(); // Initialize all the password policy components. initializePasswordPolicyComponents(); // Initialize all the authentication policy components. initializeAuthenticationPolicyComponents(); // Load and initialize the user plugins. @@ -2939,17 +2798,17 @@ /** * Initializes the set of password policy components for use by the Directory * Server. * Initializes the set of authentication policy components for use by the * Directory Server. * * @throws ConfigException If there is a configuration problem with any of * the password policy components. * * @throws InitializationException If a problem occurs while initializing * the password policy components that is * not related to the server configuration. * @throws ConfigException * If there is a configuration problem with any of the * authentication policy components. * @throws InitializationException * If a problem occurs while initializing the authentication policy * components that is not related to the server configuration. */ public void initializePasswordPolicyComponents() public void initializeAuthenticationPolicyComponents() throws ConfigException, InitializationException { // Initialize all the password storage schemes. @@ -2974,9 +2833,9 @@ initializeNotificationHandlers(); // Initialize all the password policies. passwordPolicyConfigManager = new PasswordPolicyConfigManager(); passwordPolicyConfigManager.initializePasswordPolicies(); // Initialize all the authentication policies. authenticationPolicyConfigManager = new PasswordPolicyConfigManager(); authenticationPolicyConfigManager.initializeAuthenticationPolicies(); } @@ -5315,106 +5174,104 @@ /** * Retrieves the set of password policies registered with the Directory * Server. The references returned are to the actual password policy objects * currently in use by the directory server and the referenced objects must * not be modified. * Returns an unmodifiable collection containing all of the authentication * policies registered with the Directory Server. The references returned are * to the actual authentication policy objects currently in use by the * directory server and the referenced objects must not be modified. * * @return The set of password policies registered with the Directory Server. * @return The unmodifiable collection containing all of the authentication * policies registered with the Directory Server. */ public static PasswordPolicy[] getPasswordPolicies() public static Collection<AuthenticationPolicy> getAuthenticationPolicies() { // The password policy objects are returned in an array to prevent the // caller from modifying the map structure. PasswordPolicyConfig[] values = directoryServer.passwordPolicies.values() .toArray(new PasswordPolicyConfig[0]); PasswordPolicy[] policies = new PasswordPolicy[values.length]; for( int i = 0 ; i < values.length; ++i) return Collections .unmodifiableCollection(directoryServer.authenticationPolicies.values()); } /** * Retrieves the authentication policy registered for the provided * configuration entry. * * @param configEntryDN * The DN of the configuration entry for which to retrieve the * associated authentication policy. * @return The authentication policy registered for the provided configuration * entry, or <CODE>null</CODE> if there is no such policy. */ public static AuthenticationPolicy getAuthenticationPolicy(DN configEntryDN) { Validator.ensureNotNull(configEntryDN); return directoryServer.authenticationPolicies.get(configEntryDN); } /** * Registers the provided authentication policy with the Directory Server. If * a policy is already registered for the provided configuration entry DN, * then it will be replaced. * * @param configEntryDN * The DN of the configuration entry that defines the authentication * policy. * @param policy * The authentication policy to register with the server. */ public static void registerAuthenticationPolicy(DN configEntryDN, AuthenticationPolicy policy) { Validator.ensureNotNull(configEntryDN, policy); // Ensure default policy is synchronized. synchronized (directoryServer.authenticationPolicies) { policies[i] = values[i].getPolicy(); if (directoryServer.defaultPasswordPolicyDN.equals(configEntryDN)) { // The correct policy type is enforced by the core config manager. directoryServer.defaultPasswordPolicy = (PasswordPolicy) policy; } AuthenticationPolicy oldPolicy = directoryServer.authenticationPolicies .put(configEntryDN, policy); if (oldPolicy != null) { oldPolicy.finalizeAuthenticationPolicy(); } } return policies; } /** * Retrieves the password policy registered for the provided configuration * entry. * Deregisters the provided authentication policy with the Directory Server. * If no such policy is registered, then no action will be taken. * * @param configEntryDN The DN of the configuration entry for which to * retrieve the associated password policy. * * @return The password policy registered for the provided configuration * entry, or <CODE>null</CODE> if there is no such policy. * @param configEntryDN * The DN of the configuration entry that defines the authentication * policy to deregister. */ public static PasswordPolicy getPasswordPolicy(DN configEntryDN) public static void deregisterAuthenticationPolicy(DN configEntryDN) { Validator.ensureNotNull(configEntryDN); PasswordPolicyConfig config = directoryServer.passwordPolicies.get(configEntryDN); return (null == config) ? null : config.getPolicy(); } /** * Retrieves the password policy registered for the provided configuration * entry. * * @param configEntryDN The DN of the configuration entry for which to * retrieve the associated password policy. * * @return The password policy config registered for the provided * configuration entry, or <CODE>null</CODE> if there is * no such policy. */ public static PasswordPolicyConfig getPasswordPolicyConfig(DN configEntryDN) { Validator.ensureNotNull(configEntryDN); return directoryServer.passwordPolicies.get(configEntryDN); } /** * Registers the provided password policy with the Directory Server. If a * policy is already registered for the provided configuration entry DN, then * it will be replaced. * * @param configEntryDN The DN of the configuration entry that defines the * password policy. * @param config The password policy config to register with the * server. */ public static void registerPasswordPolicy(DN configEntryDN, PasswordPolicyConfig config) { Validator.ensureNotNull(configEntryDN, config); directoryServer.passwordPolicies.put(configEntryDN, config); } /** * Deregisters the provided password policy with the Directory Server. If no * such policy is registered, then no action will be taken. * * @param configEntryDN The DN of the configuration entry that defines the * password policy to deregister. */ public static void deregisterPasswordPolicy(DN configEntryDN) { Validator.ensureNotNull(configEntryDN); if (directoryServer.defaultPasswordPolicyDN.equals(configEntryDN)) // Ensure default policy is synchronized. synchronized (directoryServer.authenticationPolicies) { directoryServer.defaultPasswordPolicyConfig = null; } if (directoryServer.defaultPasswordPolicyDN.equals(configEntryDN)) { directoryServer.defaultPasswordPolicy = null; } directoryServer.passwordPolicies.remove(configEntryDN); AuthenticationPolicy oldPolicy = directoryServer.authenticationPolicies .remove(configEntryDN); if (oldPolicy != null) { oldPolicy.finalizeAuthenticationPolicy(); } } } @@ -5428,56 +5285,69 @@ */ public static DN getDefaultPasswordPolicyDN() { return directoryServer.defaultPasswordPolicyDN; synchronized (directoryServer.authenticationPolicies) { return directoryServer.defaultPasswordPolicyDN; } } /** * Specifies the DN of the configuration entry for the default password policy * for the Directory Server. This routine does not check the registered * password policies for the specified DN, since in the case of server * initialization, the password policy entries will not yet have been loaded * from the configuration backend. * Specifies the DN of the configuration entry for the default authentication * policy for the Directory Server. This routine does not check the registered * authentication policies for the specified DN, since in the case of server * initialization, the authentication policy entries will not yet have been * loaded from the configuration backend. * * @param defaultPasswordPolicyDN The DN of the configuration entry for the * default password policy for the Directory * Server. * @param defaultPasswordPolicyDN * The DN of the configuration entry for the default authentication * policy for the Directory Server. */ public static void setDefaultPasswordPolicyDN(DN defaultPasswordPolicyDN) { directoryServer.defaultPasswordPolicyDN = defaultPasswordPolicyDN; directoryServer.defaultPasswordPolicyConfig = null; // Ensure default policy is synchronized. synchronized (directoryServer.authenticationPolicies) { directoryServer.defaultPasswordPolicyDN = defaultPasswordPolicyDN; directoryServer.defaultPasswordPolicy = null; } } /** * Retrieves the default password policy for the Directory Server. This method * is equivalent to invoking <CODE>getPasswordPolicy</CODE> on the DN returned * from <CODE>DirectoryServer.getDefaultPasswordPolicyDN()</CODE>. * Retrieves the default password policy for the Directory Server. This * method is equivalent to invoking <CODE>getAuthenticationPolicy</CODE> on * the DN returned from * <CODE>DirectoryServer.getDefaultPasswordPolicyDN()</CODE>. * * @return The default password policy for the Directory Server. * @return The default password policy for the Directory Server. */ public static PasswordPolicy getDefaultPasswordPolicy() { assert null != directoryServer.passwordPolicies.get( directoryServer.defaultPasswordPolicyDN) : "Internal Error: no default password policy defined." ; if ((directoryServer.defaultPasswordPolicyConfig == null) && (directoryServer.defaultPasswordPolicyDN != null)) // Ensure default policy is synchronized. synchronized (directoryServer.authenticationPolicies) { directoryServer.defaultPasswordPolicyConfig = directoryServer.passwordPolicies.get( directoryServer.defaultPasswordPolicyDN); assert null != directoryServer.authenticationPolicies .get(directoryServer.defaultPasswordPolicyDN) : "Internal Error: no default password policy defined."; if ((directoryServer.defaultPasswordPolicy == null) && (directoryServer.defaultPasswordPolicyDN != null)) { // The correct policy type is enforced by the core config manager. directoryServer.defaultPasswordPolicy = (PasswordPolicy) directoryServer.authenticationPolicies .get(directoryServer.defaultPasswordPolicyDN); } assert directoryServer.authenticationPolicies .get(directoryServer.defaultPasswordPolicyDN) == directoryServer.defaultPasswordPolicy : "Internal Error: inconsistency between defaultPasswordPolicy" + " cache and value in authenticationPolicies map."; return directoryServer.defaultPasswordPolicy; } assert directoryServer.passwordPolicies.get( directoryServer.defaultPasswordPolicyDN) == directoryServer.defaultPasswordPolicyConfig : "Internal Error: inconsistency between defaultPasswordPolicyConfig" + " cache and value in passwordPolicies map."; return directoryServer.defaultPasswordPolicyConfig.getPolicy(); } @@ -8360,15 +8230,16 @@ // Finalize the password policy map. for (DN configEntryDN : directoryServer.passwordPolicies.keySet()) for (DN configEntryDN : directoryServer.authenticationPolicies.keySet()) { DirectoryServer.deregisterPasswordPolicy(configEntryDN); DirectoryServer.deregisterAuthenticationPolicy(configEntryDN); } // Finalize password policies and their config manager. if (directoryServer.passwordPolicyConfigManager != null) if (directoryServer.authenticationPolicyConfigManager != null) { directoryServer.passwordPolicyConfigManager.finalizePasswordPolicies(); directoryServer.authenticationPolicyConfigManager .finalizeAuthenticationPolicies(); } // Finalize the access control handler opends/src/server/org/opends/server/core/PasswordPolicy.java
@@ -23,43 +23,20 @@ * * * Copyright 2006-2010 Sun Microsystems, Inc. * Portions copyright 2011 ForgeRock AS. */ package org.opends.server.core; import java.text.SimpleDateFormat; import java.util.Date; import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedHashSet; import java.util.LinkedList; import java.util.Collection; import java.util.List; import java.util.Set; import java.util.SortedSet; import java.util.TimeZone; import java.util.TreeSet; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArraySet; import org.opends.messages.Message; import org.opends.server.admin.std.meta.PasswordPolicyCfgDefn; import org.opends.server.admin.std.server.PasswordPolicyCfg; import org.opends.server.admin.std.server.PasswordValidatorCfg; import org.opends.server.api.AccountStatusNotificationHandler; import org.opends.server.api.PasswordGenerator; import org.opends.server.api.PasswordStorageScheme; import org.opends.server.api.PasswordValidator; import org.opends.server.config.ConfigException; import org.opends.server.loggers.debug.DebugTracer; import org.opends.server.schema.GeneralizedTimeSyntax; import org.opends.server.types.*; import static org.opends.messages.CoreMessages.*; import static org.opends.server.config.ConfigConstants.*; import static org.opends.server.loggers.debug.DebugLogger.*; import static org.opends.server.schema.SchemaConstants.*; import static org.opends.server.util.ServerConstants.*; import static org.opends.server.util.StaticUtils.*; import org.opends.server.admin.std.meta.PasswordPolicyCfgDefn.*; import org.opends.server.api.*; import org.opends.server.types.AttributeType; @@ -67,661 +44,15 @@ * This class defines a data structure that holds information about a Directory * Server password policy. */ public class PasswordPolicy public abstract class PasswordPolicy extends AuthenticationPolicy { /** * The tracer object for the debug logger. */ private static final DebugTracer TRACER = getTracer(); // The DN of the entry containing the configuration for this password // policy. private final DN configEntryDN; // The attribute type that will hold user passwords for this password policy. private final AttributeType passwordAttribute; // Indicates whether the attribute type uses the authPassword syntax. private final boolean authPasswordSyntax; // Indicates whether a user with an expired password will still be allowed to // change it via the password modify extended operation. private boolean allowExpiredPasswordChanges = DEFAULT_PWPOLICY_ALLOW_EXPIRED_CHANGES; // Indicates whether the password attribute will be allowed to have multiple // distinct values. private boolean allowMultiplePasswordValues = DEFAULT_PWPOLICY_ALLOW_MULTIPLE_PW_VALUES; // Indicates whether to allow pre-encoded passwords. private boolean allowPreEncodedPasswords = DEFAULT_PWPOLICY_ALLOW_PRE_ENCODED_PASSWORDS; // Indicates whether users will be allowed to change their passwords. private boolean allowUserPasswordChanges = DEFAULT_PWPOLICY_ALLOW_USER_CHANGE; // Indicates whether to allow a password to expire without ever providing the // user with a notification. private boolean expirePasswordsWithoutWarning = DEFAULT_PWPOLICY_EXPIRE_WITHOUT_WARNING; // Indicates whether users must change their passwords the first time they // authenticate after their account is created. private boolean forceChangeOnAdd = DEFAULT_PWPOLICY_FORCE_CHANGE_ON_ADD; // Indicates whether a user must change their password after it has been reset // by an administrator. private boolean forceChangeOnReset = DEFAULT_PWPOLICY_FORCE_CHANGE_ON_RESET; // Indicates whether a user must provide their current password in order to // use a new password. private boolean requireCurrentPassword = DEFAULT_PWPOLICY_REQUIRE_CURRENT_PASSWORD; // Indicates whether users will be required to authenticate using a secure // mechanism. private boolean requireSecureAuthentication = DEFAULT_PWPOLICY_REQUIRE_SECURE_AUTHENTICATION; // Indicates whether users will be required to change their passwords using a // secure mechanism. private boolean requireSecurePasswordChanges = DEFAULT_PWPOLICY_REQUIRE_SECURE_PASSWORD_CHANGES; // Indicates whether password validation should be performed for // administrative password changes. private boolean skipValidationForAdministrators = DEFAULT_PWPOLICY_SKIP_ADMIN_VALIDATION; // The set of account status notification handlers for this password policy. private ConcurrentHashMap<DN, AccountStatusNotificationHandler<?>> notificationHandlers; // The set of password validators that will be used with this // password policy. private ConcurrentHashMap<DN, PasswordValidator<?>> passwordValidators; // The set of default password storage schemes for this password // policy. private CopyOnWriteArrayList<PasswordStorageScheme<?>> defaultStorageSchemes = new CopyOnWriteArrayList<PasswordStorageScheme<?>>(); { PasswordStorageScheme<?> defaultScheme = DirectoryServer.getPasswordStorageScheme(DEFAULT_PASSWORD_STORAGE_SCHEME); if (defaultScheme != null) defaultStorageSchemes.add(defaultScheme); } // DNs of password storage schemes for this password policy. private SortedSet<DN> storageSchemeDNs = new TreeSet<DN>(); // The names of the deprecated password storage schemes for this password // policy. private CopyOnWriteArraySet<String> deprecatedStorageSchemes = new CopyOnWriteArraySet<String>(); // DNs of deprecated password storage schemes for this password policy. private SortedSet<DN> deprecatedStorageSchemeDNs = new TreeSet<DN>(); // The DN of the password validator for this password policy. private DN passwordGeneratorDN = null; // The password generator for use with this password policy. private PasswordGenerator<?> passwordGenerator = null; // The number of grace logins that a user may have. private int graceLoginCount = DEFAULT_PWPOLICY_GRACE_LOGIN_COUNT; // The number of passwords to keep in the history. private int historyCount = DEFAULT_PWPOLICY_HISTORY_COUNT; // The maximum length of time in seconds to keep passwords in the history. private int historyDuration = DEFAULT_PWPOLICY_HISTORY_DURATION; // The maximum length of time in seconds that an account may remain idle // before it is locked out. private int idleLockoutInterval = DEFAULT_PWPOLICY_IDLE_LOCKOUT_INTERVAL; // The length of time a user should stay locked out, in seconds. private int lockoutDuration = DEFAULT_PWPOLICY_LOCKOUT_DURATION; // The number of authentication failures before an account is locked out. private int lockoutFailureCount = DEFAULT_PWPOLICY_LOCKOUT_FAILURE_COUNT; // The length of time that authentication failures should be counted against // a user. private int lockoutFailureExpirationInterval = DEFAULT_PWPOLICY_LOCKOUT_FAILURE_EXPIRATION_INTERVAL; // The maximum password age (i.e., expiration interval), in seconds. private int maximumPasswordAge = DEFAULT_PWPOLICY_MAXIMUM_PASSWORD_AGE; // The maximum password age for administratively reset passwords, in seconds. private int maximumPasswordResetAge = DEFAULT_PWPOLICY_MAXIMUM_PASSWORD_RESET_AGE; // The minimum password age, in seconds. private int minimumPasswordAge = DEFAULT_PWPOLICY_MINIMUM_PASSWORD_AGE; // The password expiration warning interval, in seconds. private int warningInterval = DEFAULT_PWPOLICY_WARNING_INTERVAL; // The the time by which all users will be required to change their passwords. private long requireChangeByTime = -1L; // The attribute type that will hold the last login time. private AttributeType lastLoginTimeAttribute = null; // The format string to use when generating the last login time. private String lastLoginTimeFormat = null; // The set of previous last login time format strings. private CopyOnWriteArrayList<String> previousLastLoginTimeFormats = new CopyOnWriteArrayList<String>(); // The state update failure policy. private PasswordPolicyCfgDefn.StateUpdateFailurePolicy stateUpdateFailurePolicy = PasswordPolicyCfgDefn.StateUpdateFailurePolicy.REACTIVE; /** * Creates a new password policy based on the configuration contained in the * provided configuration entry. Any parameters not included in the provided * configuration entry will be assigned server-wide default values. * * @param configuration The configuration with the information to use to * initialize this password policy. * * @throws ConfigException If the provided entry does not contain a valid * password policy configuration. * * @throws InitializationException If an error occurs while initializing the * password policy that is not related to * the server configuration. * Creates a new password policy. */ public PasswordPolicy(PasswordPolicyCfg configuration) throws ConfigException, InitializationException protected PasswordPolicy() { // Create a list of units and values that we can use to represent time // periods. LinkedHashMap<String,Double> timeUnits = new LinkedHashMap<String,Double>(); timeUnits.put(TIME_UNIT_SECONDS_ABBR, 1D); timeUnits.put(TIME_UNIT_SECONDS_FULL, 1D); timeUnits.put(TIME_UNIT_MINUTES_ABBR, 60D); timeUnits.put(TIME_UNIT_MINUTES_FULL, 60D); timeUnits.put(TIME_UNIT_HOURS_ABBR, (double) (60 * 60)); timeUnits.put(TIME_UNIT_HOURS_FULL, (double) (60 * 60)); timeUnits.put(TIME_UNIT_DAYS_ABBR, (double) (60 * 60 * 24)); timeUnits.put(TIME_UNIT_DAYS_FULL, (double) (60 * 60 * 24)); timeUnits.put(TIME_UNIT_WEEKS_ABBR, (double) (60 * 60 * 24 * 7)); timeUnits.put(TIME_UNIT_WEEKS_FULL, (double) (60 * 60 * 24 * 7)); this.configEntryDN = configuration.dn(); // Get the password attribute. If specified, it must have either the // user password or auth password syntax. passwordAttribute = configuration.getPasswordAttribute(); String syntaxOID = passwordAttribute.getSyntaxOID(); if (syntaxOID.equals(SYNTAX_AUTH_PASSWORD_OID)) { authPasswordSyntax = true; } else if (syntaxOID.equals(SYNTAX_USER_PASSWORD_OID)) { authPasswordSyntax = false; } else { String syntax = passwordAttribute.getSyntax().getSyntaxName(); if ((syntax == null) || (syntax.length() == 0)) { syntax = syntaxOID; } Message message = ERR_PWPOLICY_INVALID_PASSWORD_ATTRIBUTE_SYNTAX. get(String.valueOf(configEntryDN), passwordAttribute.getNameOrOID(), String.valueOf(syntax)); throw new ConfigException(message); } // Get the default storage schemes. They must all reference valid storage // schemes that support the syntax for the specified password attribute. storageSchemeDNs = configuration.getDefaultPasswordStorageSchemeDNs(); try { LinkedList<PasswordStorageScheme<?>> schemes = new LinkedList<PasswordStorageScheme<?>>(); for (DN configEntryDN : storageSchemeDNs) { PasswordStorageScheme<?> scheme = DirectoryServer.getPasswordStorageScheme(configEntryDN); if (this.authPasswordSyntax && (! scheme.supportsAuthPasswordSyntax())) { Message message = ERR_PWPOLICY_SCHEME_DOESNT_SUPPORT_AUTH.get( String.valueOf(configEntryDN), this.passwordAttribute.getNameOrOID()); throw new ConfigException(message); } schemes.add(scheme); } this.defaultStorageSchemes = new CopyOnWriteArrayList<PasswordStorageScheme<?>>(schemes); } catch (ConfigException ce) { throw ce; } catch (Exception e) { if (debugEnabled()) { TRACER.debugCaught(DebugLogLevel.ERROR, e); } Message message = ERR_PWPOLICY_CANNOT_DETERMINE_DEFAULT_STORAGE_SCHEMES. get(String.valueOf(configEntryDN), getExceptionMessage(e)); throw new InitializationException(message, e); } // Get the names of the deprecated storage schemes. deprecatedStorageSchemeDNs = configuration.getDeprecatedPasswordStorageSchemeDNs(); try { LinkedHashSet<String> newDeprecatedStorageSchemes = new LinkedHashSet<String>(); for (DN schemeDN : deprecatedStorageSchemeDNs) { PasswordStorageScheme<?> scheme = DirectoryServer.getPasswordStorageScheme(schemeDN); if (this.authPasswordSyntax) { if (scheme.supportsAuthPasswordSyntax()) { newDeprecatedStorageSchemes.add( scheme.getAuthPasswordSchemeName()); } else { Message message = ERR_PWPOLICY_DEPRECATED_SCHEME_NOT_AUTH.get( String.valueOf(configEntryDN), String.valueOf(schemeDN)); throw new ConfigException(message); } } else { newDeprecatedStorageSchemes.add( toLowerCase(scheme.getStorageSchemeName())); } } this.deprecatedStorageSchemes = new CopyOnWriteArraySet<String>(newDeprecatedStorageSchemes); } catch (Exception e) { if (debugEnabled()) { TRACER.debugCaught(DebugLogLevel.ERROR, e); } Message message = ERR_PWPOLICY_CANNOT_DETERMINE_DEPRECATED_STORAGE_SCHEMES. get(String.valueOf(configEntryDN), getExceptionMessage(e)); throw new InitializationException(message, e); } // Get the password validators. SortedSet<DN> passwordValidators = configuration.getPasswordValidatorDNs(); ConcurrentHashMap<DN, PasswordValidator<?>> validators = new ConcurrentHashMap<DN, PasswordValidator<?>>(); for (DN validatorDN : passwordValidators) { validators.put(validatorDN, DirectoryServer.getPasswordValidator(validatorDN)); } this.passwordValidators = validators; // Get the status notification handlers. SortedSet<DN> statusNotificationHandlers = configuration.getAccountStatusNotificationHandlerDNs(); ConcurrentHashMap<DN,AccountStatusNotificationHandler<?>> handlers = new ConcurrentHashMap<DN,AccountStatusNotificationHandler<?>>(); for (DN handlerDN : statusNotificationHandlers) { AccountStatusNotificationHandler<?> handler = DirectoryServer.getAccountStatusNotificationHandler(handlerDN); handlers.put(handlerDN, handler); } this.notificationHandlers = handlers; // Determine whether to allow user password changes. this.allowUserPasswordChanges = configuration.isAllowUserPasswordChanges(); // Determine whether to require the current password for user changes. this.requireCurrentPassword = configuration.isPasswordChangeRequiresCurrentPassword(); // Determine whether to force password changes on add. this.forceChangeOnAdd = configuration.isForceChangeOnAdd(); // Determine whether to force password changes on reset. this.forceChangeOnReset = configuration.isForceChangeOnReset(); // Determine whether to validate reset passwords. this.skipValidationForAdministrators = configuration.isSkipValidationForAdministrators(); // Get the password generator. DN passGenDN = configuration.getPasswordGeneratorDN() ; if (passGenDN != null) { this.passwordGeneratorDN = passGenDN; this.passwordGenerator = DirectoryServer.getPasswordGenerator(passGenDN); } // Determine whether to require secure authentication. this.requireSecureAuthentication = configuration.isRequireSecureAuthentication(); // Determine whether to require secure password changes. this.requireSecurePasswordChanges = configuration.isRequireSecurePasswordChanges() ; // Determine whether to allow multiple password values. this.allowMultiplePasswordValues = configuration.isAllowMultiplePasswordValues(); // Determine whether to allow pre-encoded passwords. this.allowPreEncodedPasswords = configuration.isAllowPreEncodedPasswords(); // Get the minimum password age. this.minimumPasswordAge = (int) configuration.getMinPasswordAge(); // Get the maximum password age. this.maximumPasswordAge = (int) configuration.getMaxPasswordAge(); // Get the maximum password reset age. this.maximumPasswordResetAge = (int) configuration .getMaxPasswordResetAge(); // Get the warning interval. this.warningInterval = (int) configuration .getPasswordExpirationWarningInterval(); // Determine whether to expire passwords without warning. this.expirePasswordsWithoutWarning = configuration .isExpirePasswordsWithoutWarning(); // If the expire without warning option is disabled, then there must be a // warning interval. if ((! this.expirePasswordsWithoutWarning()) && (this.getWarningInterval() <= 0)) { Message message = ERR_PWPOLICY_MUST_HAVE_WARNING_IF_NOT_EXPIRE_WITHOUT_WARNING. get(String.valueOf(configEntryDN)); throw new ConfigException(message); } // Determine whether to allow user changes for expired passwords. this.allowExpiredPasswordChanges = configuration .isAllowExpiredPasswordChanges(); // Get the grace login count. this.graceLoginCount = configuration.getGraceLoginCount(); // Get the lockout failure count. this.lockoutFailureCount = configuration.getLockoutFailureCount(); // Get the lockout duration. this.lockoutDuration = (int) configuration.getLockoutDuration(); // Get the lockout failure expiration interval. this.lockoutFailureExpirationInterval = (int) configuration .getLockoutFailureExpirationInterval(); // Get the required change time. String requireChangeBy = configuration.getRequireChangeByTime(); try { if (requireChangeBy != null) { ByteString valueString = ByteString.valueOf(requireChangeBy); GeneralizedTimeSyntax syntax = (GeneralizedTimeSyntax) DirectoryServer.getAttributeSyntax(SYNTAX_GENERALIZED_TIME_OID, false); if (syntax == null) { this.requireChangeByTime = GeneralizedTimeSyntax.decodeGeneralizedTimeValue(valueString); } else { valueString = syntax.getEqualityMatchingRule().normalizeValue(valueString); this.requireChangeByTime = GeneralizedTimeSyntax.decodeGeneralizedTimeValue(valueString); } } } catch (Exception e) { if (debugEnabled()) { TRACER.debugCaught(DebugLogLevel.ERROR, e); } Message message = ERR_PWPOLICY_CANNOT_DETERMINE_REQUIRE_CHANGE_BY_TIME. get(String.valueOf(configEntryDN), getExceptionMessage(e)); throw new InitializationException(message, e); } // Get the last login time attribute. If specified, it must be defined in // the server schema. It does not need to have a generalized time syntax // because the value that it will store will not necessarily conform to this // format. lastLoginTimeAttribute = configuration.getLastLoginTimeAttribute(); // Get the last login time format. If specified, it must be a valid format // string. String formatString = configuration.getLastLoginTimeFormat(); try { if (formatString != null) { try { new SimpleDateFormat(formatString); } catch (Exception e) { if (debugEnabled()) { TRACER.debugCaught(DebugLogLevel.ERROR, e); } Message message = ERR_PWPOLICY_INVALID_LAST_LOGIN_TIME_FORMAT.get( String.valueOf(configEntryDN), String.valueOf(formatString)); throw new ConfigException(message); } this.lastLoginTimeFormat = formatString; } } catch (ConfigException ce) { throw ce; } catch (Exception e) { if (debugEnabled()) { TRACER.debugCaught(DebugLogLevel.ERROR, e); } Message message = ERR_PWPOLICY_CANNOT_DETERMINE_LAST_LOGIN_TIME_FORMAT. get(String.valueOf(configEntryDN), getExceptionMessage(e)); throw new InitializationException(message, e); } // Get the previous last login time formats. If specified, they must all // be valid format strings. SortedSet<String> formatStrings = configuration.getPreviousLastLoginTimeFormat() ; try { if (formatStrings != null) { for (String s : formatStrings) { try { new SimpleDateFormat(s); } catch (Exception e) { if (debugEnabled()) { TRACER.debugCaught(DebugLogLevel.ERROR, e); } Message message = ERR_PWPOLICY_INVALID_PREVIOUS_LAST_LOGIN_TIME_FORMAT. get(String.valueOf(configEntryDN), String.valueOf(s)); throw new ConfigException(message); } } this.previousLastLoginTimeFormats = new CopyOnWriteArrayList<String>(formatStrings); } } catch (ConfigException ce) { throw ce; } catch (Exception e) { if (debugEnabled()) { TRACER.debugCaught(DebugLogLevel.ERROR, e); } Message message = ERR_PWPOLICY_CANNOT_DETERMINE_PREVIOUS_LAST_LOGIN_TIME_FORMAT. get(String.valueOf(configEntryDN), getExceptionMessage(e)); throw new InitializationException(message, e); } // Get the idle lockout duration. this.idleLockoutInterval = (int) configuration.getIdleLockoutInterval(); // Get the state update failure policy. this.stateUpdateFailurePolicy = configuration.getStateUpdateFailurePolicy(); // Get the password history count and duration. this.historyCount = configuration.getPasswordHistoryCount(); this.historyDuration = (int) configuration.getPasswordHistoryDuration(); /* * Holistic validation. */ // Ensure that the password attribute was included in the configuration // entry, since it is required. if (passwordAttribute == null) { Message message = ERR_PWPOLICY_NO_PASSWORD_ATTRIBUTE.get(String.valueOf(configEntryDN)); throw new ConfigException(message); } // Ensure that at least one default password storage scheme was included in // the configuration entry, since it is required. if (defaultStorageSchemes.isEmpty()) { Message message = ERR_PWPOLICY_NO_DEFAULT_STORAGE_SCHEMES.get( String.valueOf(configEntryDN)); throw new ConfigException(message); } // If both a maximum password age and a warning interval are provided, then // ensure that the warning interval is less than the maximum age. Further, // if a minimum age is specified, then the sum of the minimum age and the // warning interval should be less than the maximum age. if (maximumPasswordAge > 0) { int warnInterval = Math.max(0, warningInterval); if (minimumPasswordAge > 0) { if ((warnInterval + minimumPasswordAge) >= maximumPasswordAge) { Message message = ERR_PWPOLICY_MIN_AGE_PLUS_WARNING_GREATER_THAN_MAX_AGE. get(String.valueOf(configEntryDN)); throw new ConfigException(message); } } else if (warnInterval >= maximumPasswordAge) { Message message = ERR_PWPOLICY_WARNING_INTERVAL_LARGER_THAN_MAX_AGE.get( String.valueOf(configEntryDN)); throw new ConfigException(message); } } } /** * Retrieves the DN of the configuration entry to which this password policy * corresponds. * * @return The DN of the configuration entry. */ public DN getConfigEntryDN() { return configEntryDN; } /** * Retrieves the attribute type used to store the password. * * @return The attribute type used to store the password. */ public AttributeType getPasswordAttribute() { return passwordAttribute; // Nothing to do. } @@ -730,44 +61,41 @@ * Indicates whether the associated password attribute uses the auth password * syntax. * * @return <CODE>true</CODE> if the associated password attribute uses the * auth password syntax, or <CODE>false</CODE> if not. * @return <CODE>true</CODE> if the associated password attribute uses the * auth password syntax, or <CODE>false</CODE> if not. */ public boolean usesAuthPasswordSyntax() { return authPasswordSyntax; } public abstract boolean isAuthPasswordSyntax(); /** * Retrieves the default set of password storage schemes that will be used for * this password policy. The returned set should not be modified by the * this password policy. The returned set should not be modified by the * caller. * * @return The default set of password storage schemes that will be used for * this password policy. * @return The default set of password storage schemes that will be used for * this password policy. */ public CopyOnWriteArrayList<PasswordStorageScheme<?>> getDefaultStorageSchemes() { return defaultStorageSchemes; } public abstract List<PasswordStorageScheme<?>> getDefaultPasswordStorageSchemes(); /** * Retrieves the default set of password storage scheme DNs that will * be used for this password policy. The returned set should not be * modified by the caller. * Gets the "deprecated-password-storage-scheme" property. * <p> * Specifies the names of the password storage schemes that are considered * deprecated for this password policy. * <p> * If a user with this password policy authenticates to the server and * his/her password is encoded with a deprecated scheme, those values are * removed and replaced with values encoded using the default password * storage scheme(s). * * @return The default set of password storage scheme DNs that will * be used for this password policy. * @return Returns an unmodifiable set containing the values of the * "deprecated-password-storage-scheme" property. */ public SortedSet<DN> getDefaultStorageSchemeDNs() { return storageSchemeDNs; } public abstract Set<String> getDeprecatedPasswordStorageSchemes(); @@ -775,226 +103,49 @@ * Indicates whether the specified storage scheme is a default scheme for this * password policy. * * @param name The name of the password storage scheme for which to make the * determination. * * @return <CODE>true</CODE> if the storage scheme is a default scheme for * this password policy, or <CODE>false</CODE> if not. * @param name * The name of the password storage scheme for which to make the * determination. * @return <CODE>true</CODE> if the storage scheme is a default scheme for * this password policy, or <CODE>false</CODE> if not. */ public boolean isDefaultStorageScheme(String name) { CopyOnWriteArrayList<PasswordStorageScheme<?>> defaultSchemes = getDefaultStorageSchemes(); if (defaultSchemes == null) { return false; } for (PasswordStorageScheme<?> s : defaultSchemes) { if (authPasswordSyntax) { if (s.getAuthPasswordSchemeName().equalsIgnoreCase(name)) { return true; } } else { if (s.getStorageSchemeName().equalsIgnoreCase(name)) { return true; } } } return false; } /** * Retrieves the names of the password storage schemes that have been * deprecated. If an authenticating user has one or more of these deprecated * storage schemes in use in their entry, then they will be removed and * replaced with the passwords encoded in the default storage scheme(s). The * returned list should not be altered by the caller. * * @return The names of the password storage schemes that have been * deprecated. */ public CopyOnWriteArraySet<String> getDeprecatedStorageSchemes() { return deprecatedStorageSchemes; } /** * Retrieves DNs of the password storage schemes that have been * deprecated. If an authenticating user has one or more of * these deprecated storage schemes in use in their entry, then * they will be removed and replaced with the passwords encoded * in the default storage scheme(s). The returned set should * not be altered by the caller. * * @return DNs of the password storage schemes that have been * deprecated. */ public SortedSet<DN> getDeprecatedStorageSchemeDNs() { return deprecatedStorageSchemeDNs; } public abstract boolean isDefaultPasswordStorageScheme(String name); /** * Indicates whether the specified storage scheme is deprecated. * * @param name The name of the password storage scheme for which to make the * determination. * * @return <CODE>true</CODE> if the storage scheme is deprecated, or * <CODE>false</CODE> if not. * @param name * The name of the password storage scheme for which to make the * determination. * @return <CODE>true</CODE> if the storage scheme is deprecated, or * <CODE>false</CODE> if not. */ public boolean isDeprecatedStorageScheme(String name) { CopyOnWriteArraySet<String> deprecatedSchemes = getDeprecatedStorageSchemes(); if (deprecatedSchemes == null) { return false; } for (String s : deprecatedSchemes) { if (s.equalsIgnoreCase(name)) { return true; } } return false; } public abstract boolean isDeprecatedPasswordStorageScheme(String name); /** * Retrieves the set of password validators for this password policy. The * Retrieves the set of password validators for this password policy. The * returned list should not be altered by the caller. * * @return The set of password validators for this password policy. * @return The set of password validators for this password policy. */ public ConcurrentHashMap<DN, PasswordValidator<? extends PasswordValidatorCfg>> getPasswordValidators() { return passwordValidators; } public abstract Collection<PasswordValidator<?>> getPasswordValidators(); /** * Retrieves the set of account status notification handlers that should be * used with this password policy. The returned list should not be altered by * used with this password policy. The returned list should not be altered by * the caller. * * @return The set of account status notification handlers that should be * used with this password policy. * @return The set of account status notification handlers that should be used * with this password policy. */ public ConcurrentHashMap<DN,AccountStatusNotificationHandler<?>> getAccountStatusNotificationHandlers() { return notificationHandlers; } /** * Indicates whether end users will be allowed to change their own passwords * (subject to access control restrictions). * * @return <CODE>true</CODE> if users will be allowed to change their own * passwords, or <CODE>false</CODE> if not. */ public boolean allowUserPasswordChanges() { return allowUserPasswordChanges; } /** * Indicates whether the end user must provide their current password (via the * password modify extended operation) in order to set a new password. * * @return <CODE>true</CODE> if the end user must provide their current * password in order to set a new password, or <CODE>false</CODE> if * they will not. */ public boolean requireCurrentPassword() { return requireCurrentPassword; } /** * Indicates whether users will be required to change their passwords as soon * as they authenticate after their accounts have been created. * * @return <CODE>true</CODE> if users will be required to change their * passwords at the initial authentication, or <CODE>false</CODE> if * not. */ public boolean forceChangeOnAdd() { return forceChangeOnAdd; } /** * Indicates whether a user will be required to change their password after it * has been reset by an administrator. * * @return <CODE>true</CODE> if a user will be required to change their * password after it has been reset by an administrator, or * <CODE>false</CODE> if they can continue using that password. */ public boolean forceChangeOnReset() { return forceChangeOnReset; } /** * Indicates whether operations by administrators that specify a new password * for a user (e.g., add, modify, or password modify) will be allowed to * bypass the password validation process that will be required for user * password changes. * * @return <CODE>true</CODE> if administrators will be allowed to bypass the * validation checks, or <CODE>false</CODE> if not. */ public boolean skipValidationForAdministrators() { return skipValidationForAdministrators; } /** * Retrieves the DN of the password validator configuration entry. * * @return The DN of the password validator configuration entry. */ public DN getPasswordGeneratorDN() { return passwordGeneratorDN; } public abstract Collection<AccountStatusNotificationHandler<?>> getAccountStatusNotificationHandlers(); @@ -1002,301 +153,10 @@ * Retrieves the password generator that will be used with this password * policy. * * @return The password generator that will be used with this password * policy, or <CODE>null</CODE> if there is none. * @return The password generator that will be used with this password policy, * or <CODE>null</CODE> if there is none. */ public PasswordGenerator<?> getPasswordGenerator() { return passwordGenerator; } /** * Retrieves the maximum number of previous passwords to maintain in the * password history. * * @return The maximum number of previous passwords to maintain in the * password history. */ public int getPasswordHistoryCount() { return historyCount; } /** * Retrieves the maximum length of time in seconds that previous passwords * should remain in the password history. * * @return The maximum length of time in seconds that previous passwords * should remain in the password history. */ public int getPasswordHistoryDuration() { return historyDuration; } /** * Indicates whether users with this password policy will be required to * authenticate in a secure manner that does not expose their password. * * @return <CODE>true</CODE> if users with this password policy will be * required to authenticate in a secure manner that does not expose * their password, or <CODE>false</CODE> if they may authenticate in * an insecure manner. */ public boolean requireSecureAuthentication() { return requireSecureAuthentication; } /** * Indicates whether users with this password policy will be required to * change their passwords in a secure manner that does not expose the new * password. * * @return <CODE>true</CODE> if users with this password policy will be * required to change their passwords in a secure manner that does * not expose the new password, or <CODE>false</CODE> if they may * change their password in an insecure manner. */ public boolean requireSecurePasswordChanges() { return requireSecurePasswordChanges; } /** * Indicates whether user entries will be allowed to have multiple distinct * values in the password attribute. * * @return <CODE>true</CODE> if clients will be allowed to have multiple * distinct password values, or <CODE>false</CODE> if not. */ public boolean allowMultiplePasswordValues() { return allowMultiplePasswordValues; } /** * Indicates whether clients will be allowed to set pre-encoded passwords that * are already hashed and therefore cannot be validated for correctness. * * @return <CODE>true</CODE> if clients will be allowed to set pre-encoded * passwords that cannot be validated, or <CODE>false</CODE> if not. */ public boolean allowPreEncodedPasswords() { return allowPreEncodedPasswords; } /** * Retrieves the minimum password age, which is the minimum length of time in * seconds that must elapse between user password changes. * * @return The minimum password age, which is the minimum length of time in * seconds that must elapse between user password changes, or zero if * there is no minimum age. */ public int getMinimumPasswordAge() { if (minimumPasswordAge <= 0) { return 0; } return minimumPasswordAge; } /** * Retrieves the maximum length of time in seconds that will be allowed to * pass between password changes before the password is expired. * * @return The maximum length of time in seconds that will be allowed to pass * between password changes before the password is expired, or zero * if password expiration should not be used. */ public int getMaximumPasswordAge() { if (maximumPasswordAge < 0) { return 0; } return maximumPasswordAge; } /** * Retrieves the maximum length of time in seconds that will be allowed to * pass after an administrative password reset before that password is * expired. * * @return The maximum length of time in seconds that will be allowed to pass * after an administrative password reset before that password is * expired, or zero if there is no limit. */ public int getMaximumPasswordResetAge() { if (maximumPasswordResetAge < 0) { return 0; } return maximumPasswordResetAge; } /** * Retrieves the maximum length of time in seconds before the password will * expire that the user should start receiving warning notifications. * * @return The maximum length of time in seconds before the password will * expire that the user should start receiving warning notifications, * or zero if no warning should be given. */ public int getWarningInterval() { if (warningInterval < 0) { return 0; } return warningInterval; } /** * Indicates whether user passwords will be allowed to expire without the * user receiving at least one notification during the warning period. * * @return <CODE>true</CODE> if user passwords will be allowed to expire * without the user receiving at least one notification during the * warning period, or <CODE>false</CODE> if the user will always see * at least one warning before the password expires. */ public boolean expirePasswordsWithoutWarning() { return expirePasswordsWithoutWarning; } /** * Indicates whether a user will be allowed to change their password after it * expires and they have no remaining grace logins (and will not be allowed to * perform any other operation until the password is changed). * * @return <CODE>true</CODE> if a user will be allowed to change their * password after it expires and they have no remaining grace longs, * or <CODE>false</CODE> if the account will be completely locked and * the password must be reset by an administrator. */ public boolean allowExpiredPasswordChanges() { return allowExpiredPasswordChanges; } /** * Retrieves the maximum number of grace logins that a user will be allowed * after their password has expired before they are completely locked out. * * @return The maximum number of grace logins that a user will be allowed * after their password has expired before they are completely * locked out, or zero if no grace logins will be allowed or the * grace login duration will be in effect instead of a fixed number * of logins. */ public int getGraceLoginCount() { if (graceLoginCount < 0) { return 0; } return graceLoginCount; } /** * Retrieves the maximum number of authentication failures that will be * allowed before an account is locked out. * * @return The maximum number of authentication failures that will be allowed * before an account is locked out, or zero if no account lockout * will be in effect. */ public int getLockoutFailureCount() { if (lockoutFailureCount < 0) { return 0; } return lockoutFailureCount; } /** * Retrieves the maximum length of time in seconds that an account will be * locked out due to too many failed authentication attempts. * * @return The maximum length of time in seconds that an account will be * locked out due to too many failed authentication attempts, or * zero if the account will remain locked until explicitly unlocked * by an administrator. */ public int getLockoutDuration() { if (lockoutDuration < 0) { return 0; } return lockoutDuration; } /** * Retrieves the maximum length of time in seconds that an authentication * failure will be held against a user before it is removed from the failed * login count. * * @return The maximum length of time in seconds that an authentication * failure will be held against a user before it is removed from the * failed login count, or zero if authentication failures will never * expire. */ public int getLockoutFailureExpirationInterval() { if (lockoutFailureExpirationInterval < 0) { return 0; } return lockoutFailureExpirationInterval; } public abstract PasswordGenerator<?> getPasswordGenerator(); @@ -1304,375 +164,447 @@ * Retrieves the time by which all users will be required to change their * passwords, expressed in the number of milliseconds since midnight of * January 1, 1970 (i.e., the zero time for * <CODE>System.currentTimeMillis()</CODE>). Any passwords not changed before * <CODE>System.currentTimeMillis()</CODE>). Any passwords not changed before * this time will automatically enter a state in which they must be changed * before any other operation will be allowed. * * @return The time by which all users will be required to change their * passwords, or zero if no such constraint is in effect. * @return The time by which all users will be required to change their * passwords, or zero if no such constraint is in effect. */ public long getRequireChangeByTime() { if (requireChangeByTime < 0) { return 0; } return requireChangeByTime; } public abstract long getRequireChangeByTime(); /** * Retrieves the attribute type used to store the last login time. * Gets the "allow-expired-password-changes" property. * <p> * Indicates whether a user whose password is expired is still allowed to * change that password using the password modify extended operation. * * @return The attribute type used to store the last login time, or * <CODE>null</CODE> if the last login time is not to be maintained. * @return Returns the value of the "allow-expired-password-changes" property. */ public AttributeType getLastLoginTimeAttribute() { return lastLoginTimeAttribute; } public abstract boolean isAllowExpiredPasswordChanges(); /** * Retrieves the format string that should be used for the last login time. * Gets the "allow-multiple-password-values" property. * <p> * Indicates whether user entries can have multiple distinct values for the * password attribute. * <p> * This is potentially dangerous because many mechanisms used to change the * password do not work well with such a configuration. If multiple password * values are allowed, then any of them can be used to authenticate, and they * are all subject to the same policy constraints. * * @return The format string that should be used to for the last login time, * or <CODE>null</CODE> if the last login time is not to be * maintained. * @return Returns the value of the "allow-multiple-password-values" property. */ public String getLastLoginTimeFormat() { return lastLoginTimeFormat; } public abstract boolean isAllowMultiplePasswordValues(); /** * Retrieves the list of previous last login time formats that might have been * used for users associated with this password policy. * Gets the "allow-pre-encoded-passwords" property. * <p> * Indicates whether users can change their passwords by providing a * pre-encoded value. * <p> * This can cause a security risk because the clear-text version of the * password is not known and therefore validation checks cannot be applied to * it. * * @return The list of previous last login time formats that might have been * used for users associated with this password policy. * @return Returns the value of the "allow-pre-encoded-passwords" property. */ public CopyOnWriteArrayList<String> getPreviousLastLoginTimeFormats() { return previousLastLoginTimeFormats; } public abstract boolean isAllowPreEncodedPasswords(); /** * Retrieves the maximum length of time in seconds that an account will be * allowed to remain idle (no authentications performed as the user) before it * will be locked out. * Gets the "allow-user-password-changes" property. * <p> * Indicates whether users can change their own passwords. * <p> * This check is made in addition to access control evaluation. Both must * allow the password change for it to occur. * * @return The maximum length of time in seconds that an account will be * allowed to remain idle before it will be locked out. * @return Returns the value of the "allow-user-password-changes" property. */ public int getIdleLockoutInterval() { if (idleLockoutInterval < 0) { return 0; } return idleLockoutInterval; } public abstract boolean isAllowUserPasswordChanges(); /** * Retrieves the state update failure policy for this password policy. * Gets the "expire-passwords-without-warning" property. * <p> * Indicates whether the directory server allows a user's password to expire * even if that user has never seen an expiration warning notification. * <p> * If this property is true, accounts always expire when the expiration time * arrives. If this property is false or disabled, the user always receives at * least one warning notification, and the password expiration is set to the * warning time plus the warning interval. * * @return The state update failure policy for this password policy. * @return Returns the value of the "expire-passwords-without-warning" * property. */ public PasswordPolicyCfgDefn.StateUpdateFailurePolicy getStateUpdateFailurePolicy() { return stateUpdateFailurePolicy; } public abstract boolean isExpirePasswordsWithoutWarning(); /** * Retrieves a string representation of this password policy. * Gets the "force-change-on-add" property. * <p> * Indicates whether users are forced to change their passwords upon first * authenticating to the directory server after their account has been * created. * * @return A string representation of this password policy. * @return Returns the value of the "force-change-on-add" property. */ public String toString() { StringBuilder buffer = new StringBuilder(); toString(buffer); return buffer.toString(); } public abstract boolean isForceChangeOnAdd(); /** * Appends a string representation of this password policy to the provided * buffer. * Gets the "force-change-on-reset" property. * <p> * Indicates whether users are forced to change their passwords if they are * reset by an administrator. * <p> * For this purpose, anyone with permission to change a given user's password * other than that user is considered an administrator. * * @param buffer The buffer to which the information should be appended. * @return Returns the value of the "force-change-on-reset" property. */ public void toString(StringBuilder buffer) { buffer.append("Password Attribute: "); buffer.append(passwordAttribute.getNameOrOID()); buffer.append(EOL); public abstract boolean isForceChangeOnReset(); buffer.append("Default Password Storage Schemes: "); if ((defaultStorageSchemes == null) || defaultStorageSchemes.isEmpty()) { buffer.append("{none specified}"); buffer.append(EOL); } else { Iterator<PasswordStorageScheme<?>> iterator = defaultStorageSchemes.iterator(); buffer.append(iterator.next().getStorageSchemeName()); buffer.append(EOL); while (iterator.hasNext()) { buffer.append(" "); buffer.append(iterator.next().getStorageSchemeName()); buffer.append(EOL); } } buffer.append("Deprecated Password Storage Schemes: "); if ((deprecatedStorageSchemes == null) || deprecatedStorageSchemes.isEmpty()) { buffer.append("{none specified}"); buffer.append(EOL); } else { Iterator<String> iterator = deprecatedStorageSchemes.iterator(); buffer.append(iterator.next()); buffer.append(EOL); /** * Gets the "grace-login-count" property. * <p> * Specifies the number of grace logins that a user is allowed after the * account has expired to allow that user to choose a new password. * <p> * A value of 0 indicates that no grace logins are allowed. * * @return Returns the value of the "grace-login-count" property. */ public abstract int getGraceLoginCount(); while (iterator.hasNext()) { buffer.append(" "); buffer.append(iterator.next()); buffer.append(EOL); } } buffer.append("Allow Multiple Password Values: "); buffer.append(allowMultiplePasswordValues); buffer.append(EOL); buffer.append("Allow Pre-Encoded Passwords: "); buffer.append(allowPreEncodedPasswords); buffer.append(EOL); /** * Gets the "idle-lockout-interval" property. * <p> * Specifies the maximum length of time that an account may remain idle (that * is, the associated user does not authenticate to the server) before that * user is locked out. * <p> * The value of this attribute is an integer followed by a unit of seconds, * minutes, hours, days, or weeks. A value of 0 seconds indicates that idle * accounts are not automatically locked out. This feature is available only * if the last login time is maintained. * * @return Returns the value of the "idle-lockout-interval" property. */ public abstract long getIdleLockoutInterval(); buffer.append("Allow User Password Changes: "); buffer.append(allowUserPasswordChanges); buffer.append(EOL); buffer.append("Force Password Change on Add: "); buffer.append(forceChangeOnAdd); buffer.append(EOL); buffer.append("Force Password Change on Admin Reset: "); buffer.append(forceChangeOnReset); buffer.append(EOL); /** * Gets the "last-login-time-attribute" property. * <p> * Specifies the name or OID of the attribute type that is used to hold the * last login time for users with the associated password policy. * <p> * This attribute type must be defined in the directory server schema and must * either be defined as an operational attribute or must be allowed by the set * of objectClasses for all users with the associated password policy. * * @return Returns the value of the "last-login-time-attribute" property. */ public abstract AttributeType getLastLoginTimeAttribute(); buffer.append("Require Current Password: "); buffer.append(requireCurrentPassword); buffer.append(EOL); buffer.append("Require Secure Authentication: "); buffer.append(requireSecureAuthentication); buffer.append(EOL); buffer.append("Require Secure Password Changes: "); buffer.append(requireSecurePasswordChanges); buffer.append(EOL); /** * Gets the "last-login-time-format" property. * <p> * Specifies the format string that is used to generate the last login time * value for users with the associated password policy. * <p> * This format string conforms to the syntax described in the API * documentation for the java.text.SimpleDateFormat class. * * @return Returns the value of the "last-login-time-format" property. */ public abstract String getLastLoginTimeFormat(); buffer.append("Lockout Failure Expiration Interval: "); buffer.append(lockoutFailureExpirationInterval); buffer.append(" seconds"); buffer.append(EOL); buffer.append("Password Validators: "); if ((passwordValidators == null) || passwordValidators.isEmpty()) { buffer.append("{none specified}"); buffer.append(EOL); } else { Iterator<DN> iterator = passwordValidators.keySet().iterator(); iterator.next().toString(buffer); buffer.append(EOL); while (iterator.hasNext()) { buffer.append(" "); iterator.next().toString(buffer); buffer.append(EOL); } } /** * Gets the "lockout-duration" property. * <p> * Specifies the length of time that an account is locked after too many * authentication failures. * <p> * The value of this attribute is an integer followed by a unit of seconds, * minutes, hours, days, or weeks. A value of 0 seconds indicates that the * account must remain locked until an administrator resets the password. * * @return Returns the value of the "lockout-duration" property. */ public abstract long getLockoutDuration(); buffer.append("Skip Validation for Administrators: "); buffer.append(skipValidationForAdministrators); buffer.append(EOL); buffer.append("Password Generator: "); if (passwordGenerator == null) { buffer.append("{none specified}"); } else { passwordGeneratorDN.toString(buffer); } buffer.append(EOL); buffer.append("Account Status Notification Handlers: "); if ((notificationHandlers == null) || notificationHandlers.isEmpty()) { buffer.append("{none specified}"); buffer.append(EOL); } else { Iterator<DN> iterator = notificationHandlers.keySet().iterator(); iterator.next().toString(buffer); buffer.append(EOL); /** * Gets the "lockout-failure-count" property. * <p> * Specifies the maximum number of authentication failures that a user is * allowed before the account is locked out. * <p> * A value of 0 indicates that accounts are never locked out due to failed * attempts. * * @return Returns the value of the "lockout-failure-count" property. */ public abstract int getLockoutFailureCount(); while (iterator.hasNext()) { buffer.append(" "); iterator.next().toString(buffer); buffer.append(EOL); } } buffer.append("Minimum Password Age: "); buffer.append(minimumPasswordAge); buffer.append(" seconds"); buffer.append(EOL); buffer.append("Maximum Password Age: "); buffer.append(maximumPasswordAge); buffer.append(" seconds"); buffer.append(EOL); /** * Gets the "lockout-failure-expiration-interval" property. * <p> * Specifies the length of time before an authentication failure is no longer * counted against a user for the purposes of account lockout. * <p> * The value of this attribute is an integer followed by a unit of seconds, * minutes, hours, days, or weeks. A value of 0 seconds indicates that the * authentication failures must never expire. The failure count is always * cleared upon a successful authentication. * * @return Returns the value of the "lockout-failure-expiration-interval" * property. */ public abstract long getLockoutFailureExpirationInterval(); buffer.append("Maximum Password Reset Age: "); buffer.append(maximumPasswordResetAge); buffer.append(" seconds"); buffer.append(EOL); buffer.append("Expiration Warning Interval: "); buffer.append(warningInterval); buffer.append(" seconds"); buffer.append(EOL); buffer.append("Expire Passwords Without Warning: "); buffer.append(expirePasswordsWithoutWarning); buffer.append(EOL); /** * Gets the "max-password-age" property. * <p> * Specifies the maximum length of time that a user can continue using the * same password before it must be changed (that is, the password expiration * interval). * <p> * The value of this attribute is an integer followed by a unit of seconds, * minutes, hours, days, or weeks. A value of 0 seconds disables password * expiration. * * @return Returns the value of the "max-password-age" property. */ public abstract long getMaxPasswordAge(); buffer.append("Allow Expired Password Changes: "); buffer.append(allowExpiredPasswordChanges); buffer.append(EOL); buffer.append("Grace Login Count: "); buffer.append(graceLoginCount); buffer.append(EOL); buffer.append("Lockout Failure Count: "); buffer.append(lockoutFailureCount); buffer.append(EOL); /** * Gets the "max-password-reset-age" property. * <p> * Specifies the maximum length of time that users have to change passwords * after they have been reset by an administrator before they become locked. * <p> * The value of this attribute is an integer followed by a unit of seconds, * minutes, hours, days, or weeks. A value of 0 seconds disables this feature. * * @return Returns the value of the "max-password-reset-age" property. */ public abstract long getMaxPasswordResetAge(); buffer.append("Lockout Duration: "); buffer.append(lockoutDuration); buffer.append(" seconds"); buffer.append(EOL); buffer.append("Lockout Count Expiration Interval: "); buffer.append(lockoutFailureExpirationInterval); buffer.append(" seconds"); buffer.append(EOL); buffer.append("Required Password Change By Time: "); if (requireChangeByTime <= 0) { buffer.append("{none specified}"); } else { SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT_GENERALIZED_TIME); dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); buffer.append(dateFormat.format(new Date(requireChangeByTime))); } buffer.append(EOL); /** * Gets the "min-password-age" property. * <p> * Specifies the minimum length of time after a password change before the * user is allowed to change the password again. * <p> * The value of this attribute is an integer followed by a unit of seconds, * minutes, hours, days, or weeks. This setting can be used to prevent users * from changing their passwords repeatedly over a short period of time to * flush an old password from the history so that it can be re-used. * * @return Returns the value of the "min-password-age" property. */ public abstract long getMinPasswordAge(); buffer.append("Last Login Time Attribute: "); if (lastLoginTimeAttribute == null) { buffer.append("{none specified}"); } else { buffer.append(lastLoginTimeAttribute.getNameOrOID()); } buffer.append(EOL); buffer.append("Last Login Time Format: "); if (lastLoginTimeFormat == null) { buffer.append("{none specified}"); } else { buffer.append(lastLoginTimeFormat); } buffer.append(EOL); buffer.append("Previous Last Login Time Formats: "); if ((previousLastLoginTimeFormats == null) || previousLastLoginTimeFormats.isEmpty()) { buffer.append("{none specified}"); buffer.append(EOL); } else { Iterator<String> iterator = previousLastLoginTimeFormats.iterator(); /** * Gets the "password-attribute" property. * <p> * Specifies the attribute type used to hold user passwords. * <p> * This attribute type must be defined in the server schema, and it must have * either the user password or auth password syntax. * * @return Returns the value of the "password-attribute" property. */ public abstract AttributeType getPasswordAttribute(); buffer.append(iterator.next()); buffer.append(EOL); while (iterator.hasNext()) { buffer.append(" "); buffer.append(iterator.next()); buffer.append(EOL); } } buffer.append("Idle Lockout Interval: "); buffer.append(idleLockoutInterval); buffer.append(" seconds"); buffer.append(EOL); /** * Gets the "password-change-requires-current-password" property. * <p> * Indicates whether user password changes must use the password modify * extended operation and must include the user's current password before the * change is allowed. * * @return Returns the value of the * "password-change-requires-current-password" property. */ public abstract boolean isPasswordChangeRequiresCurrentPassword(); buffer.append("History Count: "); buffer.append(historyCount); buffer.append(EOL); buffer.append("Update Failure Policy: "); buffer.append(stateUpdateFailurePolicy.toString()); buffer.append(EOL); } /** * Gets the "password-expiration-warning-interval" property. * <p> * Specifies the maximum length of time before a user's password actually * expires that the server begins to include warning notifications in bind * responses for that user. * <p> * The value of this attribute is an integer followed by a unit of seconds, * minutes, hours, days, or weeks. A value of 0 seconds disables the warning * interval. * * @return Returns the value of the "password-expiration-warning-interval" * property. */ public abstract long getPasswordExpirationWarningInterval(); /** * Gets the "password-history-count" property. * <p> * Specifies the maximum number of former passwords to maintain in the * password history. * <p> * When choosing a new password, the proposed password is checked to ensure * that it does not match the current password, nor any other password in the * history list. A value of zero indicates that either no password history is * to be maintained (if the password history duration has a value of zero * seconds), or that there is no maximum number of passwords to maintain in * the history (if the password history duration has a value greater than zero * seconds). * * @return Returns the value of the "password-history-count" property. */ public abstract int getPasswordHistoryCount(); /** * Gets the "password-history-duration" property. * <p> * Specifies the maximum length of time that passwords remain in the password * history. * <p> * When choosing a new password, the proposed password is checked to ensure * that it does not match the current password, nor any other password in the * history list. A value of zero seconds indicates that either no password * history is to be maintained (if the password history count has a value of * zero), or that there is no maximum duration for passwords in the history * (if the password history count has a value greater than zero). * * @return Returns the value of the "password-history-duration" property. */ public abstract long getPasswordHistoryDuration(); /** * Gets the "previous-last-login-time-format" property. * <p> * Specifies the format string(s) that might have been used with the last * login time at any point in the past for users associated with the password * policy. * <p> * These values are used to make it possible to parse previous values, but are * not used to set new values. The format strings conform to the syntax * described in the API documentation for the java.text.SimpleDateFormat * class. * * @return Returns an unmodifiable set containing the values of the * "previous-last-login-time-format" property. */ public abstract SortedSet<String> getPreviousLastLoginTimeFormats(); /** * Gets the "require-secure-authentication" property. * <p> * Indicates whether users with the associated password policy are required to * authenticate in a secure manner. * <p> * This might mean either using a secure communication channel between the * client and the server, or using a SASL mechanism that does not expose the * credentials. * * @return Returns the value of the "require-secure-authentication" property. */ public abstract boolean isRequireSecureAuthentication(); /** * Gets the "require-secure-password-changes" property. * <p> * Indicates whether users with the associated password policy are required to * change their password in a secure manner that does not expose the * credentials. * * @return Returns the value of the "require-secure-password-changes" * property. */ public abstract boolean isRequireSecurePasswordChanges(); /** * Gets the "skip-validation-for-administrators" property. * <p> * Indicates whether passwords set by administrators are allowed to bypass the * password validation process that is required for user password changes. * * @return Returns the value of the "skip-validation-for-administrators" * property. */ public abstract boolean isSkipValidationForAdministrators(); /** * Gets the "state-update-failure-policy" property. * <p> * Specifies how the server deals with the inability to update password policy * state information during an authentication attempt. * <p> * In particular, this property can be used to control whether an otherwise * successful bind operation fails if a failure occurs while attempting to * update password policy state information (for example, to clear a record of * previous authentication failures or to update the last login time). It can * also be used to control whether to reject a bind request if it is known * ahead of time that it will not be possible to update the authentication * failure times in the event of an unsuccessful bind attempt (for example, if * the backend writability mode is disabled). * * @return Returns the value of the "state-update-failure-policy" property. */ public abstract StateUpdateFailurePolicy getStateUpdateFailurePolicy(); } opends/src/server/org/opends/server/core/PasswordPolicyConfig.java
File was deleted opends/src/server/org/opends/server/core/PasswordPolicyConfigManager.java
@@ -23,47 +23,50 @@ * * * Copyright 2006-2010 Sun Microsystems, Inc. * Portions copyright 2011 ForgeRock AS. */ package org.opends.server.core; import org.opends.messages.Message; import static org.opends.messages.ConfigMessages.*; import static org.opends.server.loggers.ErrorLogger.logError; import static org.opends.server.loggers.debug.DebugLogger.debugEnabled; import static org.opends.server.loggers.debug.DebugLogger.getTracer; import static org.opends.server.util.StaticUtils.stackTraceToSingleLineString; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; import org.opends.messages.Message; import org.opends.server.admin.ClassPropertyDefinition; import org.opends.server.admin.server.ConfigurationAddListener; import org.opends.server.admin.server.ConfigurationDeleteListener; import org.opends.server.admin.server.ServerManagementContext; import org.opends.server.admin.std.meta.AuthenticationPolicyCfgDefn; import org.opends.server.admin.std.server.AuthenticationPolicyCfg; import org.opends.server.admin.std.server.PasswordPolicyCfg; import org.opends.server.admin.std.server.RootCfg; import org.opends.server.api.AuthenticationPolicy; import org.opends.server.api.AuthenticationPolicyFactory; import org.opends.server.api.SubentryChangeListener; import org.opends.server.config.ConfigException; import org.opends.server.loggers.debug.DebugTracer; import org.opends.server.types.ConfigChangeResult; import org.opends.server.types.DN; import org.opends.server.types.DirectoryException; import org.opends.server.types.Entry; import org.opends.server.types.InitializationException; import org.opends.server.types.ResultCode; import org.opends.server.types.SubEntry; import static org.opends.messages.ConfigMessages.*; import static org.opends.server.util.StaticUtils.*; import static org.opends.server.loggers.debug.DebugLogger.*; import org.opends.server.types.*; /** * This class defines a utility that will be used to manage the set of password * policies defined in the Directory Server. It will initialize the policies * policies defined in the Directory Server. It will initialize the policies * when the server starts, and then will manage any additions or removals while * the server is running. */ public class PasswordPolicyConfigManager implements SubentryChangeListener, ConfigurationAddListener<PasswordPolicyCfg>, ConfigurationDeleteListener<PasswordPolicyCfg> final class PasswordPolicyConfigManager implements SubentryChangeListener, ConfigurationAddListener<AuthenticationPolicyCfg>, ConfigurationDeleteListener<AuthenticationPolicyCfg> { /** * The tracer object for the debug logger. @@ -77,63 +80,30 @@ */ public PasswordPolicyConfigManager() { // Nothing to do. } /** * Creates a password policy configuration object * from password policy subentry. * @param subEntry password policy subentry. * @return password policy configuration. * @throws InitializationException if an error * occurs while parsing subentry into * password policy configuration. */ private PasswordPolicyConfig createPasswordPolicyConfig( SubEntry subEntry) throws InitializationException { try { SubentryPasswordPolicy subentryPolicy = new SubentryPasswordPolicy(subEntry); PasswordPolicy passwordPolicy = new PasswordPolicy(subentryPolicy); PasswordPolicyConfig config = new PasswordPolicyConfig(passwordPolicy); return config; } catch (Exception e) { Message message = ERR_CONFIG_PWPOLICY_INVALID_POLICY_CONFIG. get(String.valueOf(subEntry.getDN()), stackTraceToSingleLineString(e)); throw new InitializationException(message, e); } } /** * Initializes all password policies currently defined in the Directory * Server configuration. This should only be called at Directory Server * Initializes all authentication policies currently defined in the Directory * Server configuration. This should only be called at Directory Server * startup. * * @throws ConfigException If a configuration problem causes the password * policy initialization process to fail. * * @throws InitializationException If a problem occurs while initializing * the password policies that is not * related to the server configuration. * @throws ConfigException * If a configuration problem causes the authentication policy * initialization process to fail. * @throws InitializationException * If a problem occurs while initializing the authentication * policies that is not related to the server configuration. */ public void initializePasswordPolicies() throws ConfigException, InitializationException public void initializeAuthenticationPolicies() throws ConfigException, InitializationException { // Get the root configuration object. ServerManagementContext managementContext = ServerManagementContext.getInstance(); RootCfg rootConfiguration = managementContext.getRootConfiguration(); ServerManagementContext managementContext = ServerManagementContext .getInstance(); RootCfg rootConfiguration = managementContext.getRootConfiguration(); // Register as an add and delete listener with the root configuration so we // can be notified if any password policy entries are added or removed. @@ -141,85 +111,66 @@ rootConfiguration.addPasswordPolicyDeleteListener(this); // First, get the configuration base entry. String[] passwordPoliciesName = rootConfiguration.listPasswordPolicies() ; String[] passwordPolicyNames = rootConfiguration.listPasswordPolicies(); // See if the base entry has any children. If not, then that means that // See if the base entry has any children. If not, then that means that // there are no policies defined, so that's a problem. if (passwordPoliciesName.length == 0) if (passwordPolicyNames.length == 0) { Message message = ERR_CONFIG_PWPOLICY_NO_POLICIES.get(); throw new ConfigException(message); } // Get the DN of the default password policy from the core configuration. if( null == DirectoryServer.getDefaultPasswordPolicyDN()) if (DirectoryServer.getDefaultPasswordPolicyDN() == null) { Message message = ERR_CONFIG_PWPOLICY_NO_DEFAULT_POLICY.get(); throw new ConfigException(message); } // Iterate through the child entries and process them as password policy // configuration entries. for (String passwordPolicyName : passwordPoliciesName) for (String passwordPolicyName : passwordPolicyNames) { PasswordPolicyCfg passwordPolicyConfiguration = rootConfiguration.getPasswordPolicy(passwordPolicyName); try { PasswordPolicy policy = new PasswordPolicy(passwordPolicyConfiguration); PasswordPolicyConfig config = new PasswordPolicyConfig(policy); DirectoryServer.registerPasswordPolicy( passwordPolicyConfiguration.dn(), config); passwordPolicyConfiguration.addChangeListener(config); } catch (ConfigException ce) { Message message = ERR_CONFIG_PWPOLICY_INVALID_POLICY_CONFIG.get( String.valueOf(passwordPolicyConfiguration.dn()), ce.getMessage()); throw new ConfigException(message, ce); } catch (InitializationException ie) { Message message = ERR_CONFIG_PWPOLICY_INVALID_POLICY_CONFIG.get( String.valueOf(passwordPolicyConfiguration.dn()), ie.getMessage()); throw new InitializationException(message, ie); } catch (Exception e) { Message message = ERR_CONFIG_PWPOLICY_INVALID_POLICY_CONFIG. get(String.valueOf(passwordPolicyConfiguration.dn()), stackTraceToSingleLineString(e)); throw new InitializationException(message, e); } AuthenticationPolicyCfg passwordPolicyConfiguration = rootConfiguration .getPasswordPolicy(passwordPolicyName); createAuthenticationPolicy(passwordPolicyConfiguration); } // If the entry specified by the default password policy DN has not been // registered, then fail. if (null == DirectoryServer.getDefaultPasswordPolicy()) { DN defaultPolicyDN = DirectoryServer.getDefaultPasswordPolicyDN(); Message message = ERR_CONFIG_PWPOLICY_MISSING_DEFAULT_POLICY.get( String.valueOf(defaultPolicyDN)); Message message = ERR_CONFIG_PWPOLICY_MISSING_DEFAULT_POLICY.get(String .valueOf(defaultPolicyDN)); throw new ConfigException(message); } // Process and register any password policy subentries. List<SubEntry> pwpSubEntries = DirectoryServer.getSubentryManager().getSubentries(); List<SubEntry> pwpSubEntries = DirectoryServer.getSubentryManager() .getSubentries(); if ((pwpSubEntries != null) && (!pwpSubEntries.isEmpty())) { for (SubEntry subentry : pwpSubEntries) { if (subentry.getEntry().isPasswordPolicySubentry()) { PasswordPolicyConfig config = createPasswordPolicyConfig(subentry); DirectoryServer.registerPasswordPolicy( subentry.getDN(), config); try { PasswordPolicy policy = new SubentryPasswordPolicy(subentry); DirectoryServer.registerAuthenticationPolicy(subentry.getDN(), policy); } catch (Exception e) { // Just log a message instead of failing the server initialization. // This will allow the administrator to fix any problems. Message message = ERR_CONFIG_PWPOLICY_INVALID_POLICY_CONFIG.get( String.valueOf(subentry.getDN()), stackTraceToSingleLineString(e)); logError(message); } } } } @@ -231,14 +182,20 @@ /** * Perform any required finalization tasks for all password policies * currently defined. This should only be called at Directory Server * shutdown. * Perform any required finalization tasks for all authentication policies * currently defined. This should only be called at Directory Server shutdown. */ public void finalizePasswordPolicies() public void finalizeAuthenticationPolicies() { // Deregister this as subentry change listener with SubentryManager. DirectoryServer.getSubentryManager().deregisterChangeListener(this); // Deregister as configuration change listeners. ServerManagementContext managementContext = ServerManagementContext .getInstance(); RootCfg rootConfiguration = managementContext.getRootConfiguration(); rootConfiguration.removePasswordPolicyAddListener(this); rootConfiguration.removePasswordPolicyDeleteListener(this); } @@ -246,43 +203,13 @@ /** * {@inheritDoc} */ public boolean isConfigurationAddAcceptable(PasswordPolicyCfg configuration, List<Message> unacceptableReason) public boolean isConfigurationAddAcceptable( AuthenticationPolicyCfg configuration, List<Message> unacceptableReason) { // See if we can create a password policy from the provided configuration // entry. If so, then it's acceptable. try { new PasswordPolicy(configuration); } catch (ConfigException ce) { Message message = ERR_CONFIG_PWPOLICY_INVALID_POLICY_CONFIG.get( String.valueOf(configuration.dn()), ce.getMessage()); unacceptableReason.add(message); return false; } catch (InitializationException ie) { Message message = ERR_CONFIG_PWPOLICY_INVALID_POLICY_CONFIG.get( String.valueOf(configuration.dn()), ie.getMessage()); unacceptableReason.add(message); return false; } catch (Exception e) { Message message = ERR_CONFIG_PWPOLICY_INVALID_POLICY_CONFIG.get( String.valueOf(configuration.dn()), stackTraceToSingleLineString(e)); unacceptableReason.add(message); return false; } // If we've gotten here, then it is acceptable. return true; // entry. If so, then it's acceptable. return isAuthenticationPolicyConfigurationAcceptable(configuration, unacceptableReason); } @@ -291,49 +218,39 @@ * {@inheritDoc} */ public ConfigChangeResult applyConfigurationAdd( PasswordPolicyCfg configuration) AuthenticationPolicyCfg configuration) { DN configEntryDN = configuration.dn(); ArrayList<Message> messages = new ArrayList<Message>(); // See if we can create a password policy from the provided configuration // entry. If so, then register it with the Directory Server. // entry. If so, then register it with the Directory Server. ArrayList<Message> messages = new ArrayList<Message>(); try { PasswordPolicy policy = new PasswordPolicy(configuration); PasswordPolicyConfig config = new PasswordPolicyConfig(policy); DirectoryServer.registerPasswordPolicy(configEntryDN, config); configuration.addChangeListener(config); createAuthenticationPolicy(configuration); return new ConfigChangeResult(ResultCode.SUCCESS, false, messages); } catch (ConfigException ce) { messages.add(ERR_CONFIG_PWPOLICY_INVALID_POLICY_CONFIG.get( String.valueOf(configuration.dn()), ce.getMessage())); String.valueOf(configuration.dn()), ce.getMessage())); return new ConfigChangeResult(ResultCode.CONSTRAINT_VIOLATION, false, messages); messages); } catch (InitializationException ie) { messages.add(ERR_CONFIG_PWPOLICY_INVALID_POLICY_CONFIG.get( String.valueOf(configuration.dn()), ie.getMessage())); String.valueOf(configuration.dn()), ie.getMessage())); return new ConfigChangeResult(DirectoryServer.getServerErrorResultCode(), false, messages); false, messages); } catch (Exception e) { messages.add(ERR_CONFIG_PWPOLICY_INVALID_POLICY_CONFIG.get( String.valueOf(configuration.dn()), stackTraceToSingleLineString(e))); String.valueOf(configuration.dn()), stackTraceToSingleLineString(e))); return new ConfigChangeResult(DirectoryServer.getServerErrorResultCode(), false, messages); false, messages); } } @@ -343,18 +260,17 @@ * {@inheritDoc} */ public boolean isConfigurationDeleteAcceptable( PasswordPolicyCfg configuration, List<Message> unacceptableReason) AuthenticationPolicyCfg configuration, List<Message> unacceptableReason) { // We'll allow the policy to be removed as long as it isn't the default. // FIXME: something like a referential integrity check is needed to ensure // a policy is not removed when referenced by a user entry (either // a policy is not removed when referenced by a user entry (either // directly or via a virtual attribute). DN defaultPolicyDN = DirectoryServer.getDefaultPasswordPolicyDN(); if ((defaultPolicyDN != null) && defaultPolicyDN.equals(configuration.dn())) if ((defaultPolicyDN != null) && defaultPolicyDN.equals(configuration.dn())) { Message message = WARN_CONFIG_PWPOLICY_CANNOT_DELETE_DEFAULT_POLICY.get( String.valueOf(defaultPolicyDN)); Message message = WARN_CONFIG_PWPOLICY_CANNOT_DELETE_DEFAULT_POLICY .get(String.valueOf(defaultPolicyDN)); unacceptableReason.add(message); return false; } @@ -370,32 +286,25 @@ * {@inheritDoc} */ public ConfigChangeResult applyConfigurationDelete( PasswordPolicyCfg configuration) AuthenticationPolicyCfg configuration) { // We'll allow the policy to be removed as long as it isn't the default. // FIXME: something like a referential integrity check is needed to ensure // a policy is not removed when referenced by a user entry (either // a policy is not removed when referenced by a user entry (either // directly or via a virtual attribute). ArrayList<Message> messages = new ArrayList<Message>(1); DN policyDN = configuration.dn(); DN defaultPolicyDN = DirectoryServer.getDefaultPasswordPolicyDN(); if ((defaultPolicyDN != null) && defaultPolicyDN.equals(policyDN)) { messages.add(WARN_CONFIG_PWPOLICY_CANNOT_DELETE_DEFAULT_POLICY.get( String.valueOf(defaultPolicyDN))); messages.add(WARN_CONFIG_PWPOLICY_CANNOT_DELETE_DEFAULT_POLICY.get(String .valueOf(defaultPolicyDN))); return new ConfigChangeResult(ResultCode.CONSTRAINT_VIOLATION, false, messages); messages); } DirectoryServer.deregisterPasswordPolicy(policyDN); PasswordPolicyConfig config = DirectoryServer.getPasswordPolicyConfig(policyDN); if (config != null) { configuration.removeChangeListener(config); } messages.add(INFO_CONFIG_PWPOLICY_REMOVED_POLICY.get( String.valueOf(policyDN))); DirectoryServer.deregisterAuthenticationPolicy(policyDN); messages.add(INFO_CONFIG_PWPOLICY_REMOVED_POLICY.get(String .valueOf(policyDN))); return new ConfigChangeResult(ResultCode.SUCCESS, false, messages); } @@ -403,85 +312,58 @@ /** * Attempts to parse an entry as password policy * subentry to create a password policy object. * @param entry subentry to parse. * @throws DirectoryException if a problem occurs * while creating a password policy from * given subentry. */ public static void checkSubentryAcceptable(Entry entry) throws DirectoryException { SubEntry subentry = new SubEntry(entry); SubentryPasswordPolicy subentryPolicy = new SubentryPasswordPolicy(subentry); try { new PasswordPolicy(subentryPolicy); } catch (ConfigException ex) { throw new DirectoryException( ResultCode.UNWILLING_TO_PERFORM, ex.getMessageObject()); } catch (InitializationException ex) { throw new DirectoryException( ResultCode.UNWILLING_TO_PERFORM, ex.getMessageObject()); } } /** * {@inheritDoc} */ public void checkSubentryAddAcceptable(Entry entry) throws DirectoryException public void checkSubentryAddAcceptable(Entry entry) throws DirectoryException { if (entry.isPasswordPolicySubentry()) { checkSubentryAcceptable(entry); new SubentryPasswordPolicy(new SubEntry(entry)); } } /** * {@inheritDoc} */ public void checkSubentryDeleteAcceptable(Entry entry) throws DirectoryException throws DirectoryException { // FIXME: something like a referential integrity check is needed to // ensure a policy is not removed when referenced by a user entry ( // either directly or via a virtual attribute). } /** * {@inheritDoc} */ public void checkSubentryModifyAcceptable(Entry oldEntry, Entry newEntry) throws DirectoryException throws DirectoryException { if (newEntry.isPasswordPolicySubentry()) { checkSubentryAcceptable(newEntry); new SubentryPasswordPolicy(new SubEntry(newEntry)); } } /** * {@inheritDoc} */ public void checkSubentryModifyDNAcceptable(Entry oldEntry, Entry newEntry) throws DirectoryException throws DirectoryException { // FIXME: something like a referential integrity check is needed to // ensure a policy is not removed when referenced by a user entry ( // either directly or via a virtual attribute). } /** * {@inheritDoc} */ @@ -491,25 +373,23 @@ { try { SubEntry subentry = new SubEntry(entry); PasswordPolicyConfig config = createPasswordPolicyConfig(subentry); DirectoryServer.registerPasswordPolicy( subentry.getDN(), config); PasswordPolicy policy = new SubentryPasswordPolicy(new SubEntry(entry)); DirectoryServer.registerAuthenticationPolicy(entry.getDN(), policy); } catch (Exception e) { if (debugEnabled()) { TRACER.debugError("Could not create password policy subentry " + "DN %s: %s", entry.getDN().toString(), stackTraceToSingleLineString(e)); + "DN %s: %s", entry.getDN().toString(), stackTraceToSingleLineString(e)); } } } } /** * {@inheritDoc} */ @@ -517,10 +397,12 @@ { if (entry.isPasswordPolicySubentry()) { DirectoryServer.deregisterPasswordPolicy(entry.getDN()); DirectoryServer.deregisterAuthenticationPolicy(entry.getDN()); } } /** * {@inheritDoc} */ @@ -528,32 +410,31 @@ { if (oldEntry.isPasswordPolicySubentry()) { DirectoryServer.deregisterPasswordPolicy(oldEntry.getDN()); DirectoryServer.deregisterAuthenticationPolicy(oldEntry.getDN()); } if (newEntry.isPasswordPolicySubentry()) { try { SubEntry subentry = new SubEntry(newEntry); PasswordPolicyConfig config = createPasswordPolicyConfig(subentry); DirectoryServer.registerPasswordPolicy( subentry.getDN(), config); PasswordPolicy policy = new SubentryPasswordPolicy(new SubEntry( newEntry)); DirectoryServer.registerAuthenticationPolicy(newEntry.getDN(), policy); } catch (Exception e) { if (debugEnabled()) { TRACER.debugError("Could not create password policy subentry " + "DN %s: %s", newEntry.getDN().toString(), stackTraceToSingleLineString(e)); + "DN %s: %s", newEntry.getDN().toString(), stackTraceToSingleLineString(e)); } } } } /** * {@inheritDoc} */ @@ -561,29 +442,176 @@ { if (oldEntry.isPasswordPolicySubentry()) { DirectoryServer.deregisterPasswordPolicy(oldEntry.getDN()); DirectoryServer.deregisterAuthenticationPolicy(oldEntry.getDN()); } if (newEntry.isPasswordPolicySubentry()) { try { SubEntry subentry = new SubEntry(newEntry); PasswordPolicyConfig config = createPasswordPolicyConfig(subentry); DirectoryServer.registerPasswordPolicy( subentry.getDN(), config); PasswordPolicy policy = new SubentryPasswordPolicy(new SubEntry( newEntry)); DirectoryServer.registerAuthenticationPolicy(newEntry.getDN(), policy); } catch (Exception e) { if (debugEnabled()) { TRACER.debugError("Could not create password policy subentry " + "DN %s: %s", newEntry.getDN().toString(), stackTraceToSingleLineString(e)); + "DN %s: %s", newEntry.getDN().toString(), stackTraceToSingleLineString(e)); } } } } // Creates and registers the provided authentication policy // configuration. private static void createAuthenticationPolicy( AuthenticationPolicyCfg policyConfiguration) throws ConfigException, InitializationException { // If this is going to be the default password policy then check the type is // correct. if (policyConfiguration.dn().equals( DirectoryServer.getDefaultPasswordPolicyDN())) { if (!(policyConfiguration instanceof PasswordPolicyCfg)) { Message msg = ERR_CONFIG_PWPOLICY_DEFAULT_POLICY_IS_WRONG_TYPE .get(String.valueOf(policyConfiguration.dn())); throw new ConfigException(msg); } } String className = policyConfiguration.getJavaClass(); AuthenticationPolicyCfgDefn d = AuthenticationPolicyCfgDefn.getInstance(); ClassPropertyDefinition pd = d.getJavaClassPropertyDefinition(); // Load the class and cast it to an authentication policy. Class<?> theClass; AuthenticationPolicyFactory<?> factory; try { theClass = pd.loadClass(className, AuthenticationPolicyFactory.class); factory = (AuthenticationPolicyFactory<?>) theClass.newInstance(); } catch (Exception e) { if (debugEnabled()) { TRACER.debugCaught(DebugLogLevel.ERROR, e); } Message message = ERR_CONFIG_PWPOLICY_INVALID_POLICY_CONFIG.get( String.valueOf(policyConfiguration.dn()), stackTraceToSingleLineString(e)); throw new InitializationException(message, e); } // Perform the necessary initialization for the authentication policy. AuthenticationPolicy policy; try { // Determine the initialization method to use: it must take a // single parameter which is the exact type of the configuration // object. Method method = theClass.getMethod("createAuthenticationPolicy", policyConfiguration.configurationClass()); policy = (AuthenticationPolicy) method.invoke(factory, policyConfiguration); } catch (Exception e) { if (e instanceof InvocationTargetException) { Throwable t = e.getCause(); if (t instanceof InitializationException) { throw (InitializationException) t; } else if (t instanceof ConfigException) { throw (ConfigException) t; } } if (debugEnabled()) { TRACER.debugCaught(DebugLogLevel.ERROR, e); } Message message = ERR_CONFIG_PWPOLICY_INVALID_POLICY_CONFIG.get( String.valueOf(policyConfiguration.dn()), stackTraceToSingleLineString(e)); throw new InitializationException(message, e); } DirectoryServer.registerAuthenticationPolicy(policyConfiguration.dn(), policy); } // Determines whether or not the new authentication policy configuration's // implementation class is acceptable. private static boolean isAuthenticationPolicyConfigurationAcceptable( AuthenticationPolicyCfg policyConfiguration, List<Message> unacceptableReasons) { // If this is going to be the default password policy then check the type is // correct. if (policyConfiguration.dn().equals( DirectoryServer.getDefaultPasswordPolicyDN())) { if (!(policyConfiguration instanceof PasswordPolicyCfg)) { Message msg = ERR_CONFIG_PWPOLICY_DEFAULT_POLICY_IS_WRONG_TYPE .get(String.valueOf(policyConfiguration.dn())); unacceptableReasons.add(msg); return false; } } String className = policyConfiguration.getJavaClass(); AuthenticationPolicyCfgDefn d = AuthenticationPolicyCfgDefn.getInstance(); ClassPropertyDefinition pd = d.getJavaClassPropertyDefinition(); // Validate the configuration. try { // Load the class and cast it to a authentication policy factory. Class<?> theClass; AuthenticationPolicyFactory<?> factory; theClass = pd.loadClass(className, AuthenticationPolicyFactory.class); factory = (AuthenticationPolicyFactory<?>) theClass.newInstance(); // Determine the initialization method to use: it must take a // single parameter which is the exact type of the configuration // object. Method method = theClass.getMethod("isConfigurationAcceptable", AuthenticationPolicyCfg.class, List.class); return (Boolean) method.invoke(factory, policyConfiguration, unacceptableReasons); } catch (Exception e) { if (debugEnabled()) { TRACER.debugCaught(DebugLogLevel.ERROR, e); } unacceptableReasons.add(ERR_CONFIG_PWPOLICY_INVALID_POLICY_CONFIG.get( String.valueOf(policyConfiguration.dn()), stackTraceToSingleLineString(e))); return false; } } } opends/src/server/org/opends/server/core/PasswordPolicyFactory.java
New file @@ -0,0 +1,1250 @@ /* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at * trunk/opends/resource/legal-notices/OpenDS.LICENSE * or https://OpenDS.dev.java.net/OpenDS.LICENSE. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at * trunk/opends/resource/legal-notices/OpenDS.LICENSE. If applicable, * add the following below this CDDL HEADER, with the fields enclosed * by brackets "[]" replaced with your own identifying information: * Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END * * * Copyright 2006-2008 Sun Microsystems, Inc. * Portions copyright 2011 ForgeRock AS. */ package org.opends.server.core; import static org.opends.messages.ConfigMessages.*; import static org.opends.messages.CoreMessages.*; import static org.opends.server.loggers.debug.DebugLogger.debugEnabled; import static org.opends.server.loggers.debug.DebugLogger.getTracer; import static org.opends.server.schema.SchemaConstants.*; import static org.opends.server.util.ServerConstants.*; import static org.opends.server.util.StaticUtils.getExceptionMessage; import static org.opends.server.util.StaticUtils.stackTraceToSingleLineString; import static org.opends.server.util.StaticUtils.toLowerCase; import java.text.SimpleDateFormat; import java.util.*; import org.opends.messages.Message; import org.opends.server.admin.server.ConfigurationChangeListener; import org.opends.server.admin.std.meta.PasswordPolicyCfgDefn.*; import org.opends.server.admin.std.server.PasswordPolicyCfg; import org.opends.server.api.*; import org.opends.server.config.ConfigException; import org.opends.server.loggers.debug.DebugTracer; import org.opends.server.schema.GeneralizedTimeSyntax; import org.opends.server.types.*; /** * This class is the interface between the password policy configurable * component and a password policy state object. When a password policy entry is * added to the configuration, an instance of this class is created and * registered to manage subsequent modification to that configuration entry, * including validating any proposed modification and applying an accepted * modification. */ public final class PasswordPolicyFactory implements AuthenticationPolicyFactory<PasswordPolicyCfg> { /** * The tracer object for the debug logger. */ private static final DebugTracer TRACER = getTracer(); /** * Password policy implementation. */ private static final class PasswordPolicyImpl extends PasswordPolicy implements ConfigurationChangeListener<PasswordPolicyCfg> { /** * The tracer object for the debug logger. */ private static final DebugTracer TRACER = getTracer(); // Current configuration. private PasswordPolicyCfg configuration; // Indicates whether the attribute type uses the authPassword syntax. private boolean authPasswordSyntax; // The set of account status notification handlers for this password policy. private Map<DN, AccountStatusNotificationHandler<?>> notificationHandlers; // The set of password validators that will be used with this // password policy. private Map<DN, PasswordValidator<?>> passwordValidators; // The set of default password storage schemes for this password // policy. private List<PasswordStorageScheme<?>> defaultStorageSchemes; // The names of the deprecated password storage schemes for this password // policy. private Set<String> deprecatedStorageSchemes; // The password generator for use with this password policy. private PasswordGenerator<?> passwordGenerator; // The the time by which all users will be required to change their // passwords. private long requireChangeByTime; /** * {@inheritDoc} */ public void finalizeAuthenticationPolicy() { configuration.removePasswordPolicyChangeListener(this); } /** * {@inheritDoc} */ public ConfigChangeResult applyConfigurationChange( PasswordPolicyCfg configuration) { ArrayList<Message> messages = new ArrayList<Message>(); try { updateConfiguration(configuration, this); return new ConfigChangeResult(ResultCode.SUCCESS, false, messages); } catch (ConfigException ce) { messages.add(ERR_CONFIG_PWPOLICY_INVALID_POLICY_CONFIG.get( String.valueOf(configuration.dn()), ce.getMessage())); return new ConfigChangeResult(ResultCode.CONSTRAINT_VIOLATION, false, messages); } catch (InitializationException ie) { messages.add(ERR_CONFIG_PWPOLICY_INVALID_POLICY_CONFIG.get( String.valueOf(configuration.dn()), ie.getMessage())); return new ConfigChangeResult( DirectoryServer.getServerErrorResultCode(), false, messages); } catch (Exception e) { messages .add(ERR_CONFIG_PWPOLICY_INVALID_POLICY_CONFIG.get( String.valueOf(configuration.dn()), stackTraceToSingleLineString(e))); return new ConfigChangeResult( DirectoryServer.getServerErrorResultCode(), false, messages); } } /** * {@inheritDoc} */ public boolean isConfigurationChangeAcceptable( PasswordPolicyCfg configuration, List<Message> unacceptableReasons) { try { updateConfiguration(configuration, null); } catch (ConfigException ce) { Message message = ERR_CONFIG_PWPOLICY_INVALID_POLICY_CONFIG.get( String.valueOf(configuration.dn()), ce.getMessage()); unacceptableReasons.add(message); return false; } catch (InitializationException ie) { Message message = ERR_CONFIG_PWPOLICY_INVALID_POLICY_CONFIG.get( String.valueOf(configuration.dn()), ie.getMessage()); unacceptableReasons.add(message); return false; } catch (Exception e) { Message message = ERR_CONFIG_PWPOLICY_INVALID_POLICY_CONFIG .get(String.valueOf(configuration.dn()), stackTraceToSingleLineString(e)); unacceptableReasons.add(message); return false; } // If we've gotten here, then it is acceptable. return true; } /** * Creates a new password policy based on the configuration contained in the * provided configuration entry. Any parameters not included in the provided * configuration entry will be assigned server-wide default values. * * @param configuration * The configuration with the information to use to initialize this * password policy. * @throws ConfigException * If the provided entry does not contain a valid password policy * configuration. * @throws InitializationException * If an error occurs while initializing the password policy that * is not related to the server configuration. */ private PasswordPolicyImpl(PasswordPolicyCfg configuration) throws ConfigException, InitializationException { updateConfiguration(configuration, this); } private static void updateConfiguration(PasswordPolicyCfg configuration, PasswordPolicyImpl policy) throws ConfigException, InitializationException { final DN configEntryDN = configuration.dn(); // Get the password attribute. If specified, it must have either the // user password or auth password syntax. final AttributeType passwordAttribute = configuration .getPasswordAttribute(); final String syntaxOID = passwordAttribute.getSyntaxOID(); final boolean authPasswordSyntax; if (syntaxOID.equals(SYNTAX_AUTH_PASSWORD_OID)) { authPasswordSyntax = true; } else if (syntaxOID.equals(SYNTAX_USER_PASSWORD_OID)) { authPasswordSyntax = false; } else { String syntax = passwordAttribute.getSyntax().getSyntaxName(); if ((syntax == null) || (syntax.length() == 0)) { syntax = syntaxOID; } Message message = ERR_PWPOLICY_INVALID_PASSWORD_ATTRIBUTE_SYNTAX.get( String.valueOf(configEntryDN), passwordAttribute.getNameOrOID(), String.valueOf(syntax)); throw new ConfigException(message); } // Get the default storage schemes. They must all reference valid storage // schemes that support the syntax for the specified password attribute. List<PasswordStorageScheme<?>> defaultStorageSchemes = new LinkedList<PasswordStorageScheme<?>>(); for (DN schemeDN : configuration.getDefaultPasswordStorageSchemeDNs()) { PasswordStorageScheme<?> scheme = DirectoryServer .getPasswordStorageScheme(schemeDN); if (authPasswordSyntax && (!scheme.supportsAuthPasswordSyntax())) { Message message = ERR_PWPOLICY_SCHEME_DOESNT_SUPPORT_AUTH.get( String.valueOf(schemeDN), passwordAttribute.getNameOrOID()); throw new ConfigException(message); } defaultStorageSchemes.add(scheme); } // Get the names of the deprecated storage schemes. Set<String> deprecatedStorageSchemes = new LinkedHashSet<String>(); for (DN schemeDN : configuration.getDeprecatedPasswordStorageSchemeDNs()) { PasswordStorageScheme<?> scheme = DirectoryServer .getPasswordStorageScheme(schemeDN); if (authPasswordSyntax) { if (scheme.supportsAuthPasswordSyntax()) { deprecatedStorageSchemes.add(toLowerCase(scheme .getAuthPasswordSchemeName())); } else { Message message = ERR_PWPOLICY_DEPRECATED_SCHEME_NOT_AUTH.get( String.valueOf(configEntryDN), String.valueOf(schemeDN)); throw new ConfigException(message); } } else { deprecatedStorageSchemes.add(toLowerCase(scheme .getStorageSchemeName())); } } // Get the password validators. Map<DN, PasswordValidator<?>> passwordValidators = new HashMap<DN, PasswordValidator<?>>(); for (DN validatorDN : configuration.getPasswordValidatorDNs()) { passwordValidators.put(validatorDN, DirectoryServer.getPasswordValidator(validatorDN)); } // Get the status notification handlers. Map<DN, AccountStatusNotificationHandler<?>> notificationHandlers = new HashMap<DN, AccountStatusNotificationHandler<?>>(); for (DN handlerDN : configuration .getAccountStatusNotificationHandlerDNs()) { AccountStatusNotificationHandler<?> handler = DirectoryServer .getAccountStatusNotificationHandler(handlerDN); notificationHandlers.put(handlerDN, handler); } // Get the password generator. PasswordGenerator<?> passwordGenerator = null; DN passGenDN = configuration.getPasswordGeneratorDN(); if (passGenDN != null) { passwordGenerator = DirectoryServer.getPasswordGenerator(passGenDN); } // If the expire without warning option is disabled, then there must be a // warning interval. if ((!configuration.isExpirePasswordsWithoutWarning()) && (configuration.getPasswordExpirationWarningInterval() <= 0)) { Message message = ERR_PWPOLICY_MUST_HAVE_WARNING_IF_NOT_EXPIRE_WITHOUT_WARNING .get(String.valueOf(configEntryDN)); throw new ConfigException(message); } // Get the required change time. String requireChangeBy = configuration.getRequireChangeByTime(); long requireChangeByTime = 0L; try { if (requireChangeBy != null) { ByteString valueString = ByteString.valueOf(requireChangeBy); GeneralizedTimeSyntax syntax = (GeneralizedTimeSyntax) DirectoryServer .getAttributeSyntax(SYNTAX_GENERALIZED_TIME_OID, false); if (syntax == null) { requireChangeByTime = GeneralizedTimeSyntax .decodeGeneralizedTimeValue(valueString); } else { valueString = syntax.getEqualityMatchingRule().normalizeValue( valueString); requireChangeByTime = GeneralizedTimeSyntax .decodeGeneralizedTimeValue(valueString); } } } catch (Exception e) { if (debugEnabled()) { TRACER.debugCaught(DebugLogLevel.ERROR, e); } Message message = ERR_PWPOLICY_CANNOT_DETERMINE_REQUIRE_CHANGE_BY_TIME .get(String.valueOf(configEntryDN), getExceptionMessage(e)); throw new InitializationException(message, e); } // Get the last login time format. If specified, it must be a valid format // string. String formatString = configuration.getLastLoginTimeFormat(); if (formatString != null) { try { new SimpleDateFormat(formatString); } catch (Exception e) { if (debugEnabled()) { TRACER.debugCaught(DebugLogLevel.ERROR, e); } Message message = ERR_PWPOLICY_INVALID_LAST_LOGIN_TIME_FORMAT.get( String.valueOf(configEntryDN), String.valueOf(formatString)); throw new ConfigException(message); } } // Get the previous last login time formats. If specified, they must all // be valid format strings. SortedSet<String> formatStrings = configuration .getPreviousLastLoginTimeFormat(); if (formatStrings != null) { for (String s : formatStrings) { try { new SimpleDateFormat(s); } catch (Exception e) { if (debugEnabled()) { TRACER.debugCaught(DebugLogLevel.ERROR, e); } Message message = ERR_PWPOLICY_INVALID_PREVIOUS_LAST_LOGIN_TIME_FORMAT .get(String.valueOf(configEntryDN), String.valueOf(s)); throw new ConfigException(message); } } } // If both a maximum password age and a warning interval are provided, // then // ensure that the warning interval is less than the maximum age. Further, // if a minimum age is specified, then the sum of the minimum age and the // warning interval should be less than the maximum age. if (configuration.getMaxPasswordAge() > 0) { long warnInterval = Math.max(0L, configuration.getPasswordExpirationWarningInterval()); if (configuration.getMinPasswordAge() > 0) { if ((warnInterval + configuration.getMinPasswordAge()) >=configuration .getMaxPasswordAge()) { Message message = ERR_PWPOLICY_MIN_AGE_PLUS_WARNING_GREATER_THAN_MAX_AGE .get(String.valueOf(configEntryDN)); throw new ConfigException(message); } } else if (warnInterval >= configuration.getMaxPasswordAge()) { Message message = ERR_PWPOLICY_WARNING_INTERVAL_LARGER_THAN_MAX_AGE .get(String.valueOf(configEntryDN)); throw new ConfigException(message); } } // If we've got this far then the configuration is good and we can commit // the changes if required. if (policy != null) { policy.configuration = configuration; policy.authPasswordSyntax = authPasswordSyntax; policy.defaultStorageSchemes = defaultStorageSchemes; policy.deprecatedStorageSchemes = deprecatedStorageSchemes; policy.notificationHandlers = notificationHandlers; policy.passwordGenerator = passwordGenerator; policy.passwordValidators = passwordValidators; policy.requireChangeByTime = requireChangeByTime; } } /** * {@inheritDoc} */ @Override public boolean isAuthPasswordSyntax() { return authPasswordSyntax; } /** * {@inheritDoc} */ @Override public List<PasswordStorageScheme<?>> getDefaultPasswordStorageSchemes() { return defaultStorageSchemes; } /** * {@inheritDoc} */ public Set<String> getDeprecatedPasswordStorageSchemes() { return deprecatedStorageSchemes; } /** * {@inheritDoc} */ public DN getDN() { return configuration.dn(); } /** * {@inheritDoc} */ @Override public boolean isDefaultPasswordStorageScheme(String name) { for (PasswordStorageScheme<?> s : defaultStorageSchemes) { if (authPasswordSyntax) { if (s.getAuthPasswordSchemeName().equalsIgnoreCase(name)) { return true; } } else { if (s.getStorageSchemeName().equalsIgnoreCase(name)) { return true; } } } return false; } /** * {@inheritDoc} */ @Override public boolean isDeprecatedPasswordStorageScheme(String name) { return deprecatedStorageSchemes.contains(toLowerCase(name)); } /** * {@inheritDoc} */ @Override public Collection<PasswordValidator<?>> getPasswordValidators() { return passwordValidators.values(); } /** * {@inheritDoc} */ @Override public Collection<AccountStatusNotificationHandler<?>> getAccountStatusNotificationHandlers() { return notificationHandlers.values(); } /** * {@inheritDoc} */ @Override public PasswordGenerator<?> getPasswordGenerator() { return passwordGenerator; } /** * {@inheritDoc} */ @Override public long getRequireChangeByTime() { return requireChangeByTime; } /** * Retrieves a string representation of this password policy. * * @return A string representation of this password policy. */ public String toString() { StringBuilder buffer = new StringBuilder(); toString(buffer); return buffer.toString(); } /** * Appends a string representation of this password policy to the provided * buffer. * * @param buffer * The buffer to which the information should be appended. */ public void toString(StringBuilder buffer) { buffer.append("Password Attribute: "); buffer.append(configuration.getPasswordAttribute().getNameOrOID()); buffer.append(EOL); buffer.append("Default Password Storage Schemes: "); if ((defaultStorageSchemes == null) || defaultStorageSchemes.isEmpty()) { buffer.append("{none specified}"); buffer.append(EOL); } else { Iterator<PasswordStorageScheme<?>> iterator = defaultStorageSchemes .iterator(); buffer.append(iterator.next().getStorageSchemeName()); buffer.append(EOL); while (iterator.hasNext()) { buffer.append(" "); buffer.append(iterator.next().getStorageSchemeName()); buffer.append(EOL); } } buffer.append("Deprecated Password Storage Schemes: "); if ((deprecatedStorageSchemes == null) || deprecatedStorageSchemes.isEmpty()) { buffer.append("{none specified}"); buffer.append(EOL); } else { Iterator<String> iterator = deprecatedStorageSchemes.iterator(); buffer.append(iterator.next()); buffer.append(EOL); while (iterator.hasNext()) { buffer.append(" "); buffer.append(iterator.next()); buffer.append(EOL); } } buffer.append("Allow Multiple Password Values: "); buffer.append(configuration.isAllowMultiplePasswordValues()); buffer.append(EOL); buffer.append("Allow Pre-Encoded Passwords: "); buffer.append(configuration.isAllowPreEncodedPasswords()); buffer.append(EOL); buffer.append("Allow User Password Changes: "); buffer.append(configuration.isAllowUserPasswordChanges()); buffer.append(EOL); buffer.append("Force Password Change on Add: "); buffer.append(configuration.isForceChangeOnAdd()); buffer.append(EOL); buffer.append("Force Password Change on Admin Reset: "); buffer.append(configuration.isForceChangeOnReset()); buffer.append(EOL); buffer.append("Require Current Password: "); buffer.append(configuration.isPasswordChangeRequiresCurrentPassword()); buffer.append(EOL); buffer.append("Require Secure Authentication: "); buffer.append(configuration.isRequireSecureAuthentication()); buffer.append(EOL); buffer.append("Require Secure Password Changes: "); buffer.append(configuration.isRequireSecurePasswordChanges()); buffer.append(EOL); buffer.append("Lockout Failure Expiration Interval: "); buffer.append(configuration.getLockoutFailureExpirationInterval()); buffer.append(" seconds"); buffer.append(EOL); buffer.append("Password Validators: "); if ((passwordValidators == null) || passwordValidators.isEmpty()) { buffer.append("{none specified}"); buffer.append(EOL); } else { Iterator<DN> iterator = passwordValidators.keySet().iterator(); iterator.next().toString(buffer); buffer.append(EOL); while (iterator.hasNext()) { buffer.append(" "); iterator.next().toString(buffer); buffer.append(EOL); } } buffer.append("Skip Validation for Administrators: "); buffer.append(configuration.isSkipValidationForAdministrators()); buffer.append(EOL); buffer.append("Password Generator: "); if (passwordGenerator == null) { buffer.append("{none specified}"); } else { configuration.getPasswordGeneratorDN().toString(buffer); } buffer.append(EOL); buffer.append("Account Status Notification Handlers: "); if ((notificationHandlers == null) || notificationHandlers.isEmpty()) { buffer.append("{none specified}"); buffer.append(EOL); } else { Iterator<DN> iterator = notificationHandlers.keySet().iterator(); iterator.next().toString(buffer); buffer.append(EOL); while (iterator.hasNext()) { buffer.append(" "); iterator.next().toString(buffer); buffer.append(EOL); } } buffer.append("Minimum Password Age: "); buffer.append(configuration.getMinPasswordAge()); buffer.append(" seconds"); buffer.append(EOL); buffer.append("Maximum Password Age: "); buffer.append(configuration.getMaxPasswordAge()); buffer.append(" seconds"); buffer.append(EOL); buffer.append("Maximum Password Reset Age: "); buffer.append(configuration.getMaxPasswordResetAge()); buffer.append(" seconds"); buffer.append(EOL); buffer.append("Expiration Warning Interval: "); buffer.append(configuration.getPasswordExpirationWarningInterval()); buffer.append(" seconds"); buffer.append(EOL); buffer.append("Expire Passwords Without Warning: "); buffer.append(configuration.isExpirePasswordsWithoutWarning()); buffer.append(EOL); buffer.append("Allow Expired Password Changes: "); buffer.append(configuration.isAllowExpiredPasswordChanges()); buffer.append(EOL); buffer.append("Grace Login Count: "); buffer.append(configuration.getGraceLoginCount()); buffer.append(EOL); buffer.append("Lockout Failure Count: "); buffer.append(configuration.getLockoutFailureCount()); buffer.append(EOL); buffer.append("Lockout Duration: "); buffer.append(configuration.getLockoutDuration()); buffer.append(" seconds"); buffer.append(EOL); buffer.append("Lockout Count Expiration Interval: "); buffer.append(configuration.getLockoutFailureExpirationInterval()); buffer.append(" seconds"); buffer.append(EOL); buffer.append("Required Password Change By Time: "); if (requireChangeByTime <= 0) { buffer.append("{none specified}"); } else { SimpleDateFormat dateFormat = new SimpleDateFormat( DATE_FORMAT_GENERALIZED_TIME); dateFormat.setTimeZone(TimeZone.getTimeZone("UTC")); buffer.append(dateFormat.format(new Date(requireChangeByTime))); } buffer.append(EOL); buffer.append("Last Login Time Attribute: "); if (configuration.getLastLoginTimeAttribute() == null) { buffer.append("{none specified}"); } else { buffer.append(configuration.getLastLoginTimeAttribute().getNameOrOID()); } buffer.append(EOL); buffer.append("Last Login Time Format: "); if (configuration.getLastLoginTimeFormat() == null) { buffer.append("{none specified}"); } else { buffer.append(configuration.getLastLoginTimeFormat()); } buffer.append(EOL); buffer.append("Previous Last Login Time Formats: "); if ((configuration.getPreviousLastLoginTimeFormat().isEmpty())) { buffer.append("{none specified}"); buffer.append(EOL); } else { Iterator<String> iterator = configuration .getPreviousLastLoginTimeFormat().iterator(); buffer.append(iterator.next()); buffer.append(EOL); while (iterator.hasNext()) { buffer.append(" "); buffer.append(iterator.next()); buffer.append(EOL); } } buffer.append("Idle Lockout Interval: "); buffer.append(configuration.getIdleLockoutInterval()); buffer.append(" seconds"); buffer.append(EOL); buffer.append("History Count: "); buffer.append(configuration.getPasswordHistoryCount()); buffer.append(EOL); buffer.append("Update Failure Policy: "); buffer.append(configuration.getStateUpdateFailurePolicy().toString()); buffer.append(EOL); } /** * {@inheritDoc} */ @Override public boolean isAllowExpiredPasswordChanges() { return configuration.isAllowExpiredPasswordChanges(); } /** * {@inheritDoc} */ @Override public boolean isAllowMultiplePasswordValues() { return configuration.isAllowMultiplePasswordValues(); } /** * {@inheritDoc} */ @Override public boolean isAllowPreEncodedPasswords() { return configuration.isAllowPreEncodedPasswords(); } /** * {@inheritDoc} */ @Override public boolean isAllowUserPasswordChanges() { return configuration.isAllowUserPasswordChanges(); } /** * {@inheritDoc} */ @Override public boolean isExpirePasswordsWithoutWarning() { return configuration.isExpirePasswordsWithoutWarning(); } /** * {@inheritDoc} */ @Override public boolean isForceChangeOnAdd() { return configuration.isForceChangeOnAdd(); } /** * {@inheritDoc} */ @Override public boolean isForceChangeOnReset() { return configuration.isForceChangeOnReset(); } /** * {@inheritDoc} */ @Override public int getGraceLoginCount() { return configuration.getGraceLoginCount(); } /** * {@inheritDoc} */ @Override public long getIdleLockoutInterval() { return configuration.getIdleLockoutInterval(); } /** * {@inheritDoc} */ @Override public AttributeType getLastLoginTimeAttribute() { return configuration.getLastLoginTimeAttribute(); } /** * {@inheritDoc} */ @Override public String getLastLoginTimeFormat() { return configuration.getLastLoginTimeFormat(); } /** * {@inheritDoc} */ @Override public long getLockoutDuration() { return configuration.getLockoutDuration(); } /** * {@inheritDoc} */ @Override public int getLockoutFailureCount() { return configuration.getLockoutFailureCount(); } /** * {@inheritDoc} */ @Override public long getLockoutFailureExpirationInterval() { return configuration.getLockoutFailureExpirationInterval(); } /** * {@inheritDoc} */ @Override public long getMaxPasswordAge() { return configuration.getMaxPasswordAge(); } /** * {@inheritDoc} */ @Override public long getMaxPasswordResetAge() { return configuration.getMaxPasswordResetAge(); } /** * {@inheritDoc} */ @Override public long getMinPasswordAge() { return configuration.getMinPasswordAge(); } /** * {@inheritDoc} */ @Override public AttributeType getPasswordAttribute() { return configuration.getPasswordAttribute(); } /** * {@inheritDoc} */ @Override public boolean isPasswordChangeRequiresCurrentPassword() { return configuration.isPasswordChangeRequiresCurrentPassword(); } /** * {@inheritDoc} */ @Override public long getPasswordExpirationWarningInterval() { return configuration.getPasswordExpirationWarningInterval(); } /** * {@inheritDoc} */ @Override public int getPasswordHistoryCount() { return configuration.getPasswordHistoryCount(); } /** * {@inheritDoc} */ @Override public long getPasswordHistoryDuration() { return configuration.getPasswordHistoryDuration(); } /** * {@inheritDoc} */ @Override public SortedSet<String> getPreviousLastLoginTimeFormats() { return configuration.getPreviousLastLoginTimeFormat(); } /** * {@inheritDoc} */ @Override public boolean isRequireSecureAuthentication() { return configuration.isRequireSecureAuthentication(); } /** * {@inheritDoc} */ @Override public boolean isRequireSecurePasswordChanges() { return configuration.isRequireSecurePasswordChanges(); } /** * {@inheritDoc} */ @Override public boolean isSkipValidationForAdministrators() { return configuration.isSkipValidationForAdministrators(); } /** * {@inheritDoc} */ @Override public StateUpdateFailurePolicy getStateUpdateFailurePolicy() { return configuration.getStateUpdateFailurePolicy(); } } /** * Default constructor instantiated from authentication policy config manager. */ public PasswordPolicyFactory() { // Nothing to do . } /** * {@inheritDoc} */ @Override public PasswordPolicy createAuthenticationPolicy( final PasswordPolicyCfg configuration) throws ConfigException, InitializationException { PasswordPolicyImpl policy = new PasswordPolicyImpl(configuration); configuration.addPasswordPolicyChangeListener(policy); return policy; } /** * {@inheritDoc} */ @Override public boolean isConfigurationAcceptable( final PasswordPolicyCfg configuration, final List<Message> unacceptableReasons) { try { new PasswordPolicyImpl(configuration); } catch (final ConfigException ce) { if (debugEnabled()) { TRACER.debugCaught(DebugLogLevel.ERROR, ce); } unacceptableReasons.add(ce.getMessageObject()); return false; } catch (final InitializationException ie) { if (debugEnabled()) { TRACER.debugCaught(DebugLogLevel.ERROR, ie); } unacceptableReasons.add(ie.getMessageObject()); return false; } // If we made it here, then the configuration is acceptable. return true; } } opends/src/server/org/opends/server/core/PasswordPolicyState.java
@@ -46,7 +46,6 @@ import org.opends.messages.Message; import org.opends.messages.MessageBuilder; import org.opends.server.admin.std.meta.PasswordPolicyCfgDefn; import org.opends.server.admin.std.server.PasswordValidatorCfg; import org.opends.server.api.AccountStatusNotificationHandler; import org.opends.server.api.PasswordGenerator; import org.opends.server.api.PasswordStorageScheme; @@ -73,7 +72,7 @@ * This class provides a data structure for holding password policy state * information for a user account. */ public class PasswordPolicyState public final class PasswordPolicyState { /** * The tracer object for the debug logger. @@ -318,7 +317,8 @@ } } PasswordPolicy policy = DirectoryServer.getPasswordPolicy(subentryDN); PasswordPolicy policy = (PasswordPolicy) DirectoryServer .getAuthenticationPolicy(subentryDN); if (policy == null) { if (debugEnabled()) @@ -364,8 +364,8 @@ { if (subentry.getEntry().isPasswordPolicySubentry()) { PasswordPolicy policy = DirectoryServer.getPasswordPolicy( subentry.getDN()); PasswordPolicy policy = (PasswordPolicy) DirectoryServer .getAuthenticationPolicy(subentry.getDN()); if (policy == null) { // This shouldnt happen but if it does debug log @@ -2093,9 +2093,9 @@ // FIXME: the only getter responsible for a state attribute (pwdReset) that // considers the policy before checking the entry for the presence of the // attribute. if (! (passwordPolicy.allowUserPasswordChanges() && (passwordPolicy.forceChangeOnAdd() || passwordPolicy.forceChangeOnReset()))) if (! (passwordPolicy.isAllowUserPasswordChanges() && (passwordPolicy.isForceChangeOnAdd() || passwordPolicy.isForceChangeOnReset()))) { mustChangePassword = ConditionResult.FALSE; if (debugEnabled()) @@ -2235,7 +2235,7 @@ { // This feature is reponsible for neither a state field nor an entry state // attribute. if (passwordPolicy.getMaximumPasswordResetAge() <= 0) if (passwordPolicy.getMaxPasswordResetAge() <= 0L) { if (debugEnabled()) { @@ -2258,7 +2258,7 @@ } long maxResetTime = passwordChangedTime + (1000L * passwordPolicy.getMaximumPasswordResetAge()); (1000L * passwordPolicy.getMaxPasswordResetAge()); boolean locked = (maxResetTime < currentTime); if (debugEnabled()) @@ -2292,8 +2292,8 @@ boolean checkWarning = false; int maxAge = passwordPolicy.getMaximumPasswordAge(); if (maxAge > 0) long maxAge = passwordPolicy.getMaxPasswordAge(); if (maxAge > 0L) { long expTime = passwordChangedTime + (1000L*maxAge); if (expTime < passwordExpirationTime) @@ -2303,8 +2303,8 @@ } } int maxResetAge = passwordPolicy.getMaximumPasswordResetAge(); if (mustChangePassword() && (maxResetAge > 0)) long maxResetAge = passwordPolicy.getMaxPasswordResetAge(); if (mustChangePassword() && (maxResetAge > 0L)) { long expTime = passwordChangedTime + (1000L*maxResetAge); if (expTime < passwordExpirationTime) @@ -2338,8 +2338,9 @@ { mayUseGraceLogin = ConditionResult.TRUE; int warningInterval = passwordPolicy.getWarningInterval(); if (warningInterval > 0) long warningInterval = passwordPolicy .getPasswordExpirationWarningInterval(); if (warningInterval > 0L) { long shouldWarnTime = passwordExpirationTime - (warningInterval*1000L); @@ -2368,7 +2369,7 @@ isFirstWarning = ConditionResult.TRUE; setWarnedTime(); if (! passwordPolicy.expirePasswordsWithoutWarning()) if (! passwordPolicy.isExpirePasswordsWithoutWarning()) { passwordExpirationTime = currentTime + (warningInterval*1000L); @@ -2378,7 +2379,7 @@ { isFirstWarning = ConditionResult.FALSE; if (! passwordPolicy.expirePasswordsWithoutWarning()) if (! passwordPolicy.isExpirePasswordsWithoutWarning()) { passwordExpirationTime = warnedTime + (warningInterval*1000L); } @@ -2388,7 +2389,7 @@ { // The expiration time has passed, but we may not actually be // expired if the user has not yet seen a warning. if (passwordPolicy.expirePasswordsWithoutWarning()) if (passwordPolicy.isExpirePasswordsWithoutWarning()) { shouldWarn = ConditionResult.FALSE; isFirstWarning = ConditionResult.FALSE; @@ -2496,8 +2497,8 @@ { // This feature is reponsible for neither a state field nor entry state // attribute. int minAge = passwordPolicy.getMinimumPasswordAge(); if (minAge <= 0) long minAge = passwordPolicy.getMinPasswordAge(); if (minAge <= 0L) { // There is no minimum age, so the user isn't in it. if (debugEnabled()) @@ -3167,7 +3168,7 @@ for (Attribute a : attrList) { boolean usesAuthPasswordSyntax = passwordPolicy.usesAuthPasswordSyntax(); boolean usesAuthPasswordSyntax = passwordPolicy.isAuthPasswordSyntax(); for (AttributeValue v : a) { @@ -3265,7 +3266,7 @@ for (Attribute a : attrList) { boolean usesAuthPasswordSyntax = passwordPolicy.usesAuthPasswordSyntax(); boolean usesAuthPasswordSyntax = passwordPolicy.isAuthPasswordSyntax(); for (AttributeValue v : a) { @@ -3362,7 +3363,7 @@ */ public boolean passwordIsPreEncoded(ByteString passwordValue) { if (passwordPolicy.usesAuthPasswordSyntax()) if (passwordPolicy.isAuthPasswordSyntax()) { return AuthPasswordSyntax.isEncoded(passwordValue); } @@ -3389,11 +3390,11 @@ throws DirectoryException { List<PasswordStorageScheme<?>> schemes = passwordPolicy.getDefaultStorageSchemes(); passwordPolicy.getDefaultPasswordStorageSchemes(); List<ByteString> encodedPasswords = new ArrayList<ByteString>(schemes.size()); if (passwordPolicy.usesAuthPasswordSyntax()) if (passwordPolicy.isAuthPasswordSyntax()) { for (PasswordStorageScheme<?> s : schemes) { @@ -3431,38 +3432,23 @@ * <CODE>false</CODE> if it is not. */ public boolean passwordIsAcceptable(Operation operation, Entry userEntry, ByteString newPassword, Set<ByteString> currentPasswords, MessageBuilder invalidReason) ByteString newPassword, Set<ByteString> currentPasswords, MessageBuilder invalidReason) { for (DN validatorDN : passwordPolicy.getPasswordValidators().keySet()) for (PasswordValidator<?> validator : passwordPolicy .getPasswordValidators()) { PasswordValidator<? extends PasswordValidatorCfg> validator = passwordPolicy.getPasswordValidators().get(validatorDN); if (! validator.passwordIsAcceptable(newPassword, currentPasswords, operation, userEntry, invalidReason)) if (!validator.passwordIsAcceptable(newPassword, currentPasswords, operation, userEntry, invalidReason)) { if (debugEnabled()) { TRACER.debugInfo("The password provided for user %s failed " + "the %s password validator.", userDNString, validatorDN.toString()); TRACER.debugInfo("The password provided for user %s failed " + "validation: %s", userDNString, invalidReason.toString()); } return false; } else { if (debugEnabled()) { TRACER.debugInfo("The password provided for user %s passed " + "the %s password validator.", userDNString, validatorDN.toString()); } } } return true; } @@ -3477,7 +3463,7 @@ */ public void handleDeprecatedStorageSchemes(ByteString password) { if (passwordPolicy.getDefaultStorageSchemes().isEmpty()) if (passwordPolicy.getDefaultPasswordStorageSchemes().isEmpty()) { if (debugEnabled()) { @@ -3509,7 +3495,7 @@ LinkedHashSet<AttributeValue> updatedValues = new LinkedHashSet<AttributeValue>(); boolean usesAuthPasswordSyntax = passwordPolicy.usesAuthPasswordSyntax(); boolean usesAuthPasswordSyntax = passwordPolicy.isAuthPasswordSyntax(); for (Attribute a : attrList) { @@ -3561,12 +3547,13 @@ ByteString.valueOf(pwComponents[1].toString())); if (passwordMatches) { if (passwordPolicy.isDefaultStorageScheme(schemeName)) if (passwordPolicy.isDefaultPasswordStorageScheme(schemeName)) { existingDefaultSchemes.add(schemeName); updatedValues.add(v); } else if (passwordPolicy.isDeprecatedStorageScheme(schemeName)) else if (passwordPolicy .isDeprecatedPasswordStorageScheme(schemeName)) { if (debugEnabled()) { @@ -3612,7 +3599,7 @@ LinkedHashSet<AttributeValue> addedValues = new LinkedHashSet<AttributeValue>(); for (PasswordStorageScheme<?> s : passwordPolicy.getDefaultStorageSchemes()) passwordPolicy.getDefaultPasswordStorageSchemes()) { if (! existingDefaultSchemes.contains( toLowerCase(s.getStorageSchemeName()))) @@ -3764,8 +3751,8 @@ } } int historyDuration = passwordPolicy.getPasswordHistoryDuration(); if (historyDuration > 0) long historyDuration = passwordPolicy.getPasswordHistoryDuration(); if (historyDuration > 0L) { long retainDate = currentTime - (1000 * historyDuration); Iterator<Long> iterator = historyMap.keySet().iterator(); @@ -4108,8 +4095,8 @@ // If there is a maximum duration, then get rid of any values that would be // over the duration. int historyDuration = passwordPolicy.getPasswordHistoryDuration(); if (historyDuration > 0) long historyDuration = passwordPolicy.getPasswordHistoryDuration(); if (historyDuration > 0L) { long minAgeToKeep = currentTime - (1000L * historyDuration); Iterator<Long> iterator = historyMap.keySet().iterator(); @@ -4310,12 +4297,7 @@ AccountStatusNotification notification) { Collection<AccountStatusNotificationHandler<?>> handlers = passwordPolicy.getAccountStatusNotificationHandlers().values(); if ((handlers == null) || handlers.isEmpty()) { return; } passwordPolicy.getAccountStatusNotificationHandlers(); for (AccountStatusNotificationHandler<?> handler : handlers) { handler.handleStatusNotification(notification); opends/src/server/org/opends/server/core/SubentryPasswordPolicy.java
@@ -23,48 +23,41 @@ * * * Copyright 2010 Sun Microsystems, Inc. * Portions copyright 2011 ForgeRock AS. */ package org.opends.server.core; import java.util.List; import java.util.Map; import java.util.Set; import java.util.SortedSet; import java.util.TreeSet; import org.opends.messages.Message; import org.opends.server.admin.server.ConfigurationChangeListener; import org.opends.server.admin.std.meta.PasswordPolicyCfgDefn. StateUpdateFailurePolicy; import org.opends.server.admin.std.server.PasswordPolicyCfg; import org.opends.server.loggers.debug.DebugTracer; import org.opends.server.types.Attribute; import org.opends.server.types.AttributeType; import org.opends.server.types.AttributeValue; import org.opends.server.types.DN; import org.opends.server.types.DebugLogLevel; import org.opends.server.types.DirectoryException; import org.opends.server.types.Entry; import org.opends.server.types.ObjectClass; import org.opends.server.types.ResultCode; import org.opends.server.types.SubEntry; import static org.opends.messages.CoreMessages.*; import static org.opends.messages.ConfigMessages.*; import static org.opends.messages.CoreMessages.*; import static org.opends.server.loggers.debug.DebugLogger.*; import static org.opends.server.schema.SchemaConstants.*; import java.util.*; import org.opends.messages.Message; import org.opends.server.admin.std.meta.PasswordPolicyCfgDefn.*; import org.opends.server.api.AccountStatusNotificationHandler; import org.opends.server.api.PasswordGenerator; import org.opends.server.api.PasswordStorageScheme; import org.opends.server.api.PasswordValidator; import org.opends.server.loggers.debug.DebugTracer; import org.opends.server.types.*; /** * This class represents subentry password policy based on * Password Policy for LDAP Directories Internet-Draft. In * order to represent subentry password policies as OpenDS * password policies it performs a mapping of Draft defined * attributes to OpenDS implementation specific attributes. * Any missing attributes are inherited from server default * password policy. This class is also reponsible for any * Draft attributes validation ie making sure that provided * values are acceptable and within the predefined range. * This class represents subentry password policy based on Password Policy for * LDAP Directories Internet-Draft. In order to represent subentry password * policies as OpenDS password policies it performs a mapping of Draft defined * attributes to OpenDS implementation specific attributes. Any missing * attributes are inherited from server default password policy. This class is * also reponsible for any Draft attributes validation ie making sure that * provided values are acceptable and within the predefined range. */ public class SubentryPasswordPolicy implements PasswordPolicyCfg public final class SubentryPasswordPolicy extends PasswordPolicy { /** * The tracer object for the debug logger. @@ -87,127 +80,90 @@ private final String PWD_ATTR_MUSTCHANGE = "pwdmustchange"; private final String PWD_ATTR_ALLOWUSERCHANGE = "pwdallowuserchange"; private final String PWD_ATTR_SAFEMODIFY = "pwdsafemodify"; private final String PWD_ATTR_FAILURECOUNTINTERVAL = "pwdfailurecountinterval"; private final String PWD_ATTR_FAILURECOUNTINTERVAL ="pwdfailurecountinterval"; // Password Policy Subentry DN. private final DN passwordPolicySubentryDN; // The value of the "account-status-notification-handler" property. private final SortedSet<String> pAccountStatusNotificationHandler; // The value of the "allow-expired-password-changes" property. private final boolean pAllowExpiredPasswordChanges; // The value of the "allow-multiple-password-values" property. private final boolean pAllowMultiplePasswordValues; // The value of the "allow-pre-encoded-passwords" property. private final boolean pAllowPreEncodedPasswords; // The value of the "allow-user-password-changes" property. private final boolean pAllowUserPasswordChanges; // The value of the "default-password-storage-scheme" property. private final SortedSet<String> pDefaultPasswordStorageScheme; // The value of the "deprecated-password-storage-scheme" property. private final SortedSet<String> pDeprecatedPasswordStorageScheme; // The value of the "expire-passwords-without-warning" property. private final boolean pExpirePasswordsWithoutWarning; // The value of the "force-change-on-add" property. private final boolean pForceChangeOnAdd; private final Boolean pAllowUserPasswordChanges; // The value of the "force-change-on-reset" property. private final boolean pForceChangeOnReset; private final Boolean pForceChangeOnReset; // The value of the "grace-login-count" property. private final int pGraceLoginCount; // The value of the "idle-lockout-interval" property. private final long pIdleLockoutInterval; // The value of the "last-login-time-attribute" property. private final AttributeType pLastLoginTimeAttribute; // The value of the "last-login-time-format" property. private final String pLastLoginTimeFormat; private final Integer pGraceLoginCount; // The value of the "lockout-duration" property. private final long pLockoutDuration; private final Long pLockoutDuration; // The value of the "lockout-failure-count" property. private final int pLockoutFailureCount; private final Integer pLockoutFailureCount; // The value of the "lockout-failure-expiration-interval" property. private final long pLockoutFailureExpirationInterval; private final Long pLockoutFailureExpirationInterval; // The value of the "max-password-age" property. private final long pMaxPasswordAge; // The value of the "max-password-reset-age" property. private final long pMaxPasswordResetAge; private final Long pMaxPasswordAge; // The value of the "min-password-age" property. private final long pMinPasswordAge; private final Long pMinPasswordAge; // The value of the "password-attribute" property. private final AttributeType pPasswordAttribute; // The value of the "password-change-requires-current-password" property. private final boolean pPasswordChangeRequiresCurrentPassword; private final Boolean pPasswordChangeRequiresCurrentPassword; // The value of the "password-expiration-warning-interval" property. private final long pPasswordExpirationWarningInterval; // The value of the "password-generator" property. private final String pPasswordGenerator; private final Long pPasswordExpirationWarningInterval; // The value of the "password-history-count" property. private final int pPasswordHistoryCount; // The value of the "password-history-duration" property. private final long pPasswordHistoryDuration; // The value of the "password-validator" property. private final SortedSet<String> pPasswordValidator; // The value of the "previous-last-login-time-format" property. private final SortedSet<String> pPreviousLastLoginTimeFormat; // The value of the "require-change-by-time" property. private final String pRequireChangeByTime; // The value of the "require-secure-authentication" property. private final boolean pRequireSecureAuthentication; // The value of the "require-secure-password-changes" property. private final boolean pRequireSecurePasswordChanges; // The value of the "skip-validation-for-administrators" property. private final boolean pSkipValidationForAdministrators; // The value of the "state-update-failure-policy" property. private final StateUpdateFailurePolicy pStateUpdateFailurePolicy; private final Integer pPasswordHistoryCount; // Indicates if the password attribute uses auth password syntax. private final Boolean pAuthPasswordSyntax; // Returns the global default password policy which will be used for deriving // the default properties of sub-entries. private PasswordPolicy getDefaultPasswordPolicy() { return DirectoryServer.getDefaultPasswordPolicy(); } /** * Creates subentry password policy object from the subentry, * parsing and evaluating subentry password policy attributes. * Creates subentry password policy object from the subentry, parsing and * evaluating subentry password policy attributes. * * @param subentry password policy subentry. * @throws DirectoryException If a problem occurs while creating * subentry password policy instance * from given subentry. * @param subentry * password policy subentry. * @throws DirectoryException * If a problem occurs while creating subentry password policy * instance from given subentry. */ public SubentryPasswordPolicy(SubEntry subentry) throws DirectoryException public SubentryPasswordPolicy(SubEntry subentry) throws DirectoryException { // Determine if this is a password policy subentry. ObjectClass pwdPolicyOC = DirectoryServer.getObjectClass(PWD_OC_POLICY); ObjectClass pwdPolicyOC = DirectoryServer.getObjectClass(PWD_OC_POLICY); Entry entry = subentry.getEntry(); Map<ObjectClass, String> objectClasses = entry.getObjectClasses(); if (pwdPolicyOC == null) { Map<ObjectClass, String> objectClasses = entry.getObjectClasses(); if (pwdPolicyOC == null) { // This should not happen -- The server doesn't // have a pwdPolicy objectclass defined. if (debugEnabled()) { TRACER.debugWarning( "No %s objectclass is defined in the server schema.", if (debugEnabled()) { TRACER .debugWarning("No %s objectclass is defined in the server schema.", PWD_OC_POLICY); } for (String ocName : objectClasses.values()) { if (ocName.equalsIgnoreCase(PWD_OC_POLICY)) { for (String ocName : objectClasses.values()) { if (ocName.equalsIgnoreCase(PWD_OC_POLICY)) { break; } } Message message = ERR_PWPOLICY_NO_PWDPOLICY_OC.get( subentry.getDN().toString()); throw new DirectoryException( ResultCode.CONSTRAINT_VIOLATION, message); } else if (!objectClasses.containsKey(pwdPolicyOC)) { Message message = ERR_PWPOLICY_NO_PWDPOLICY_OC.get( subentry.getDN().toString()); throw new DirectoryException( ResultCode.CONSTRAINT_VIOLATION, message); Message message = ERR_PWPOLICY_NO_PWDPOLICY_OC.get(subentry.getDN() .toString()); throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message); } // Get default password policy to derive default // policy values from. PasswordPolicy defaultPasswordPolicy = DirectoryServer.getDefaultPasswordPolicy(); if (defaultPasswordPolicy == null) { throw new DirectoryException(ResultCode.OPERATIONS_ERROR, ERR_CONFIG_PWPOLICY_NO_DEFAULT_POLICY.get()); else if (!objectClasses.containsKey(pwdPolicyOC)) { Message message = ERR_PWPOLICY_NO_PWDPOLICY_OC.get(subentry.getDN() .toString()); throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, message); } // Subentry DN for this password policy. @@ -217,368 +173,383 @@ // If any given attribute is missing or empty set its value // from default Password Policy configuration. AttributeValue value = getAttrValue(entry, PWD_ATTR_ATTRIBUTE); if ((value != null) && (value.toString().length() > 0)) { this.pPasswordAttribute = DirectoryServer.getAttributeType( value.toString().toLowerCase(), false); if (this.pPasswordAttribute == null) { if ((value != null) && (value.toString().length() > 0)) { this.pPasswordAttribute = DirectoryServer.getAttributeType(value .toString().toLowerCase(), false); if (this.pPasswordAttribute == null) { throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, ERR_PWPOLICY_UNDEFINED_PASSWORD_ATTRIBUTE.get( ERR_PWPOLICY_UNDEFINED_PASSWORD_ATTRIBUTE.get( this.passwordPolicySubentryDN.toNormalizedString(), value.toString())); } } else { // This should not normally happen since pwdAttribute // declared as MUST but handle this anyway in case // the schema is not enforced for some reason. this.pPasswordAttribute = defaultPasswordPolicy.getPasswordAttribute(); // Check the syntax. final String syntaxOID = pPasswordAttribute.getSyntaxOID(); if (syntaxOID.equals(SYNTAX_AUTH_PASSWORD_OID)) { pAuthPasswordSyntax = true; } else if (syntaxOID.equals(SYNTAX_USER_PASSWORD_OID)) { pAuthPasswordSyntax = false; } else { String syntax = pPasswordAttribute.getSyntax().getSyntaxName(); if ((syntax == null) || (syntax.length() == 0)) { syntax = syntaxOID; } Message message = ERR_PWPOLICY_INVALID_PASSWORD_ATTRIBUTE_SYNTAX.get( String.valueOf(passwordPolicySubentryDN), pPasswordAttribute.getNameOrOID(), String.valueOf(syntax)); throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message); } } else { this.pPasswordAttribute = null; this.pAuthPasswordSyntax = null; } value = getAttrValue(entry, PWD_ATTR_MINAGE); if ((value != null) && (value.toString().length() > 0)) { try { if ((value != null) && (value.toString().length() > 0)) { try { this.pMinPasswordAge = Long.parseLong(value.toString()); checkIntegerAttr(PWD_ATTR_MINAGE, this.pMinPasswordAge, 0, Integer.MAX_VALUE); } catch (NumberFormatException ne) { throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, ERR_CONFIG_ATTR_INVALID_INT_VALUE.get( PWD_ATTR_MINAGE, value.toString(), ne.getLocalizedMessage())); checkIntegerAttr(PWD_ATTR_MINAGE, this.pMinPasswordAge, 0, Integer.MAX_VALUE); } } else { this.pMinPasswordAge = defaultPasswordPolicy.getMinimumPasswordAge(); catch (NumberFormatException ne) { throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, ERR_CONFIG_ATTR_INVALID_INT_VALUE.get(PWD_ATTR_MINAGE, value.toString(), ne.getLocalizedMessage())); } } else { this.pMinPasswordAge = null; } value = getAttrValue(entry, PWD_ATTR_MAXAGE); if ((value != null) && (value.toString().length() > 0)) { try { if ((value != null) && (value.toString().length() > 0)) { try { this.pMaxPasswordAge = Long.parseLong(value.toString()); checkIntegerAttr(PWD_ATTR_MAXAGE, this.pMaxPasswordAge, 0, Integer.MAX_VALUE); } catch (NumberFormatException ne) { throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, ERR_CONFIG_ATTR_INVALID_INT_VALUE.get( PWD_ATTR_MINAGE, value.toString(), ne.getLocalizedMessage())); checkIntegerAttr(PWD_ATTR_MAXAGE, this.pMaxPasswordAge, 0, Integer.MAX_VALUE); } } else { this.pMaxPasswordAge = defaultPasswordPolicy.getMaximumPasswordAge(); catch (NumberFormatException ne) { throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, ERR_CONFIG_ATTR_INVALID_INT_VALUE.get(PWD_ATTR_MINAGE, value.toString(), ne.getLocalizedMessage())); } } else { this.pMaxPasswordAge = null; } value = getAttrValue(entry, PWD_ATTR_INHISTORY); if ((value != null) && (value.toString().length() > 0)) { try { if ((value != null) && (value.toString().length() > 0)) { try { this.pPasswordHistoryCount = Integer.parseInt(value.toString()); checkIntegerAttr(PWD_ATTR_INHISTORY, this.pPasswordHistoryCount, 0, Integer.MAX_VALUE); } catch (NumberFormatException ne) { throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, ERR_CONFIG_ATTR_INVALID_INT_VALUE.get( PWD_ATTR_MINAGE, value.toString(), ne.getLocalizedMessage())); checkIntegerAttr(PWD_ATTR_INHISTORY, this.pPasswordHistoryCount, 0, Integer.MAX_VALUE); } } else { this.pPasswordHistoryCount = defaultPasswordPolicy.getPasswordHistoryCount(); catch (NumberFormatException ne) { throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, ERR_CONFIG_ATTR_INVALID_INT_VALUE.get(PWD_ATTR_MINAGE, value.toString(), ne.getLocalizedMessage())); } } else { this.pPasswordHistoryCount = null; } // This one is managed via the password validator // so only check if its value is acceptable. value = getAttrValue(entry, PWD_ATTR_CHECKQUALITY); if ((value != null) && (value.toString().length() > 0)) { try { if ((value != null) && (value.toString().length() > 0)) { try { int pwdCheckQuality = Integer.parseInt(value.toString()); checkIntegerAttr(PWD_ATTR_CHECKQUALITY, pwdCheckQuality, 0, 2); } catch (NumberFormatException ne) { checkIntegerAttr(PWD_ATTR_CHECKQUALITY, pwdCheckQuality, 0, 2); } catch (NumberFormatException ne) { throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, ERR_CONFIG_ATTR_INVALID_INT_VALUE.get( PWD_ATTR_MINAGE, value.toString(), ne.getLocalizedMessage())); ERR_CONFIG_ATTR_INVALID_INT_VALUE.get(PWD_ATTR_MINAGE, value.toString(), ne.getLocalizedMessage())); } } // This one is managed via the password validator // so only check if its value is acceptable. value = getAttrValue(entry, PWD_ATTR_MINLENGTH); if ((value != null) && (value.toString().length() > 0)) { try { if ((value != null) && (value.toString().length() > 0)) { try { int pwdMinLength = Integer.parseInt(value.toString()); checkIntegerAttr(PWD_ATTR_MINLENGTH, pwdMinLength, 0, Integer.MAX_VALUE); } catch (NumberFormatException ne) { checkIntegerAttr(PWD_ATTR_MINLENGTH, pwdMinLength, 0,Integer.MAX_VALUE); } catch (NumberFormatException ne) { throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, ERR_CONFIG_ATTR_INVALID_INT_VALUE.get( PWD_ATTR_MINAGE, value.toString(), ne.getLocalizedMessage())); ERR_CONFIG_ATTR_INVALID_INT_VALUE.get(PWD_ATTR_MINAGE, value.toString(), ne.getLocalizedMessage())); } } // This one depends on lockout failure count value // so only check if its value is acceptable. value = getAttrValue(entry, PWD_ATTR_LOCKOUT); if ((value != null) && (value.toString().length() > 0)) { if (value.toString().equalsIgnoreCase(Boolean.TRUE.toString()) || value.toString().equalsIgnoreCase(Boolean.FALSE.toString())) { if ((value != null) && (value.toString().length() > 0)) { if (value.toString().equalsIgnoreCase(Boolean.TRUE.toString()) || value.toString().equalsIgnoreCase(Boolean.FALSE.toString())) { Boolean.parseBoolean(value.toString()); } else { } else { throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, ERR_CONFIG_ATTR_INVALID_BOOLEAN_VALUE.get( PWD_ATTR_MUSTCHANGE, value.toString())); ERR_CONFIG_ATTR_INVALID_BOOLEAN_VALUE.get(PWD_ATTR_MUSTCHANGE, value.toString())); } } value = getAttrValue(entry, PWD_ATTR_EXPIREWARNING); if ((value != null) && (value.toString().length() > 0)) { try { this.pPasswordExpirationWarningInterval = Long.parseLong(value.toString()); if ((value != null) && (value.toString().length() > 0)) { try { this.pPasswordExpirationWarningInterval = Long.parseLong(value .toString()); checkIntegerAttr(PWD_ATTR_EXPIREWARNING, this.pPasswordExpirationWarningInterval, 0, Integer.MAX_VALUE); } catch (NumberFormatException ne) { throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, ERR_CONFIG_ATTR_INVALID_INT_VALUE.get( PWD_ATTR_MINAGE, value.toString(), ne.getLocalizedMessage())); this.pPasswordExpirationWarningInterval, 0, Integer.MAX_VALUE); } } else { this.pPasswordExpirationWarningInterval = defaultPasswordPolicy.getWarningInterval(); catch (NumberFormatException ne) { throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, ERR_CONFIG_ATTR_INVALID_INT_VALUE.get(PWD_ATTR_MINAGE, value.toString(), ne.getLocalizedMessage())); } } else { this.pPasswordExpirationWarningInterval = null; } value = getAttrValue(entry, PWD_ATTR_GRACEAUTHNLIMIT); if ((value != null) && (value.toString().length() > 0)) { try { if ((value != null) && (value.toString().length() > 0)) { try { this.pGraceLoginCount = Integer.parseInt(value.toString()); checkIntegerAttr(PWD_ATTR_GRACEAUTHNLIMIT, this.pGraceLoginCount, 0, Integer.MAX_VALUE); } catch (NumberFormatException ne) { throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, ERR_CONFIG_ATTR_INVALID_INT_VALUE.get( PWD_ATTR_MINAGE, value.toString(), ne.getLocalizedMessage())); checkIntegerAttr(PWD_ATTR_GRACEAUTHNLIMIT, this.pGraceLoginCount, 0, Integer.MAX_VALUE); } } else { this.pGraceLoginCount = defaultPasswordPolicy.getGraceLoginCount(); catch (NumberFormatException ne) { throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, ERR_CONFIG_ATTR_INVALID_INT_VALUE.get(PWD_ATTR_MINAGE, value.toString(), ne.getLocalizedMessage())); } } else { this.pGraceLoginCount = null; } value = getAttrValue(entry, PWD_ATTR_LOCKOUTDURATION); if ((value != null) && (value.toString().length() > 0)) { try { if ((value != null) && (value.toString().length() > 0)) { try { this.pLockoutDuration = Long.parseLong(value.toString()); checkIntegerAttr(PWD_ATTR_LOCKOUTDURATION, this.pLockoutDuration, 0, Integer.MAX_VALUE); } catch (NumberFormatException ne) { throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, ERR_CONFIG_ATTR_INVALID_INT_VALUE.get( PWD_ATTR_MINAGE, value.toString(), ne.getLocalizedMessage())); checkIntegerAttr(PWD_ATTR_LOCKOUTDURATION, this.pLockoutDuration, 0, Integer.MAX_VALUE); } } else { this.pLockoutDuration = defaultPasswordPolicy.getLockoutDuration(); catch (NumberFormatException ne) { throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, ERR_CONFIG_ATTR_INVALID_INT_VALUE.get(PWD_ATTR_MINAGE, value.toString(), ne.getLocalizedMessage())); } } else { this.pLockoutDuration = null; } value = getAttrValue(entry, PWD_ATTR_MAXFAILURE); if ((value != null) && (value.toString().length() > 0)) { try { if ((value != null) && (value.toString().length() > 0)) { try { this.pLockoutFailureCount = Integer.parseInt(value.toString()); checkIntegerAttr(PWD_ATTR_MAXFAILURE, this.pLockoutFailureCount, 0, Integer.MAX_VALUE); } catch (NumberFormatException ne) { throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, ERR_CONFIG_ATTR_INVALID_INT_VALUE.get( PWD_ATTR_MINAGE, value.toString(), ne.getLocalizedMessage())); checkIntegerAttr(PWD_ATTR_MAXFAILURE, this.pLockoutFailureCount, 0, Integer.MAX_VALUE); } } else { this.pLockoutFailureCount = defaultPasswordPolicy.getLockoutFailureCount(); catch (NumberFormatException ne) { throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, ERR_CONFIG_ATTR_INVALID_INT_VALUE.get(PWD_ATTR_MINAGE, value.toString(), ne.getLocalizedMessage())); } } else { this.pLockoutFailureCount = null; } value = getAttrValue(entry, PWD_ATTR_MUSTCHANGE); if ((value != null) && (value.toString().length() > 0)) { if (value.toString().equalsIgnoreCase(Boolean.TRUE.toString()) || value.toString().equalsIgnoreCase(Boolean.FALSE.toString())) { this.pForceChangeOnReset = Boolean.parseBoolean(value.toString()); } else { throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, ERR_CONFIG_ATTR_INVALID_BOOLEAN_VALUE.get( PWD_ATTR_MUSTCHANGE, value.toString())); if ((value != null) && (value.toString().length() > 0)) { if (value.toString().equalsIgnoreCase(Boolean.TRUE.toString()) || value.toString().equalsIgnoreCase(Boolean.FALSE.toString())) { this.pForceChangeOnReset = Boolean.parseBoolean(value.toString()); } } else { this.pForceChangeOnReset = defaultPasswordPolicy.forceChangeOnReset(); else { throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, ERR_CONFIG_ATTR_INVALID_BOOLEAN_VALUE.get(PWD_ATTR_MUSTCHANGE, value.toString())); } } else { this.pForceChangeOnReset = null; } value = getAttrValue(entry, PWD_ATTR_ALLOWUSERCHANGE); if ((value != null) && (value.toString().length() > 0)) { if (value.toString().equalsIgnoreCase(Boolean.TRUE.toString()) || value.toString().equalsIgnoreCase(Boolean.FALSE.toString())) { this.pAllowUserPasswordChanges = Boolean.parseBoolean(value.toString()); } else { throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, ERR_CONFIG_ATTR_INVALID_BOOLEAN_VALUE.get( PWD_ATTR_ALLOWUSERCHANGE, value.toString())); if ((value != null) && (value.toString().length() > 0)) { if (value.toString().equalsIgnoreCase(Boolean.TRUE.toString()) || value.toString().equalsIgnoreCase(Boolean.FALSE.toString())) { this.pAllowUserPasswordChanges = Boolean.parseBoolean(value.toString()); } } else { this.pAllowUserPasswordChanges = defaultPasswordPolicy.allowUserPasswordChanges(); else { throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, ERR_CONFIG_ATTR_INVALID_BOOLEAN_VALUE.get(PWD_ATTR_ALLOWUSERCHANGE, value.toString())); } } else { this.pAllowUserPasswordChanges = null; } value = getAttrValue(entry, PWD_ATTR_SAFEMODIFY); if ((value != null) && (value.toString().length() > 0)) { if (value.toString().equalsIgnoreCase(Boolean.TRUE.toString()) || value.toString().equalsIgnoreCase(Boolean.FALSE.toString())) { this.pPasswordChangeRequiresCurrentPassword = Boolean.parseBoolean(value.toString()); } else { throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, ERR_CONFIG_ATTR_INVALID_BOOLEAN_VALUE.get( PWD_ATTR_SAFEMODIFY, value.toString())); if ((value != null) && (value.toString().length() > 0)) { if (value.toString().equalsIgnoreCase(Boolean.TRUE.toString()) || value.toString().equalsIgnoreCase(Boolean.FALSE.toString())) { this.pPasswordChangeRequiresCurrentPassword = Boolean .parseBoolean(value.toString()); } } else { this.pPasswordChangeRequiresCurrentPassword = defaultPasswordPolicy.requireCurrentPassword(); else { throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, ERR_CONFIG_ATTR_INVALID_BOOLEAN_VALUE.get(PWD_ATTR_SAFEMODIFY, value.toString())); } } else { this.pPasswordChangeRequiresCurrentPassword = null; } value = getAttrValue(entry, PWD_ATTR_FAILURECOUNTINTERVAL); if ((value != null) && (value.toString().length() > 0)) { try { this.pLockoutFailureExpirationInterval = Long.parseLong(value.toString()); if ((value != null) && (value.toString().length() > 0)) { try { this.pLockoutFailureExpirationInterval = Long.parseLong(value .toString()); checkIntegerAttr(PWD_ATTR_FAILURECOUNTINTERVAL, this.pLockoutFailureExpirationInterval, 0, Integer.MAX_VALUE); } catch (NumberFormatException ne) { this.pLockoutFailureExpirationInterval, 0, Integer.MAX_VALUE); } catch (NumberFormatException ne) { throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, ERR_CONFIG_ATTR_INVALID_INT_VALUE.get( ERR_CONFIG_ATTR_INVALID_INT_VALUE.get( PWD_ATTR_FAILURECOUNTINTERVAL, value.toString(), ne.getLocalizedMessage())); } } else { this.pLockoutFailureExpirationInterval = defaultPasswordPolicy.getLockoutFailureExpirationInterval(); } // Get the rest Password Policy attributes from default configuration. SortedSet<String> accountStatusNotificationHandlerSet = new TreeSet<String>(); Set<DN> accountStatusNotificationHandlerDNSet = defaultPasswordPolicy.getAccountStatusNotificationHandlers( ).keySet(); for (DN dn : accountStatusNotificationHandlerDNSet) { accountStatusNotificationHandlerSet.add(dn.toNormalizedString()); else { this.pLockoutFailureExpirationInterval = null; } this.pAccountStatusNotificationHandler = accountStatusNotificationHandlerSet; this.pAllowExpiredPasswordChanges = defaultPasswordPolicy.allowExpiredPasswordChanges(); this.pAllowMultiplePasswordValues = defaultPasswordPolicy.allowMultiplePasswordValues(); this.pAllowPreEncodedPasswords = defaultPasswordPolicy.allowPreEncodedPasswords(); SortedSet<String> passwordStorageSchemeSet = new TreeSet<String>(); for (DN dn : defaultPasswordPolicy.getDefaultStorageSchemeDNs()) { passwordStorageSchemeSet.add(dn.toNormalizedString()); } this.pDefaultPasswordStorageScheme = passwordStorageSchemeSet; SortedSet<String> deprecatedPasswordStorageSchemeSet = new TreeSet<String>(); for (DN dn : defaultPasswordPolicy.getDeprecatedStorageSchemeDNs()) { deprecatedPasswordStorageSchemeSet.add(dn.toNormalizedString()); } this.pDeprecatedPasswordStorageScheme = deprecatedPasswordStorageSchemeSet; this.pExpirePasswordsWithoutWarning = defaultPasswordPolicy.expirePasswordsWithoutWarning(); this.pForceChangeOnAdd = defaultPasswordPolicy.forceChangeOnAdd(); this.pIdleLockoutInterval = defaultPasswordPolicy.getIdleLockoutInterval(); this.pLastLoginTimeAttribute = defaultPasswordPolicy.getLastLoginTimeAttribute(); this.pLastLoginTimeFormat = defaultPasswordPolicy.getLastLoginTimeFormat(); this.pMaxPasswordResetAge = defaultPasswordPolicy.getMaximumPasswordResetAge(); this.pPasswordGenerator = defaultPasswordPolicy.getPasswordGeneratorDN( ).toNormalizedString(); this.pPasswordHistoryDuration = defaultPasswordPolicy.getPasswordHistoryDuration(); SortedSet<String> passwordValidatorSet = new TreeSet<String>(); Set<DN> passwordValidatorDNSet = defaultPasswordPolicy.getPasswordValidators( ).keySet(); for (DN dn : passwordValidatorDNSet) { passwordValidatorSet.add(dn.toNormalizedString()); } this.pPasswordValidator = passwordValidatorSet; this.pPreviousLastLoginTimeFormat = new TreeSet<String>( defaultPasswordPolicy.getPreviousLastLoginTimeFormats()); long requireChangeByTime = defaultPasswordPolicy.getRequireChangeByTime(); if (requireChangeByTime > 0) { this.pRequireChangeByTime = Long.toString(requireChangeByTime); } else { this.pRequireChangeByTime = null; } this.pRequireSecureAuthentication = defaultPasswordPolicy.requireSecureAuthentication(); this.pRequireSecurePasswordChanges = defaultPasswordPolicy.requireSecurePasswordChanges(); this.pSkipValidationForAdministrators = defaultPasswordPolicy.skipValidationForAdministrators(); this.pStateUpdateFailurePolicy = defaultPasswordPolicy.getStateUpdateFailurePolicy(); } /** * Helper method to validate integer values. * @param attrName integer attribute name. * @param attrValue integer value to validate. * @param lowerBound lowest acceptable value. * @param upperBound highest acceptable value. * @throws DirectoryException if the value is out of bounds. * * @param attrName * integer attribute name. * @param attrValue * integer value to validate. * @param lowerBound * lowest acceptable value. * @param upperBound * highest acceptable value. * @throws DirectoryException * if the value is out of bounds. */ private void checkIntegerAttr(String attrName, long attrValue, long lowerBound, long upperBound) throws DirectoryException long lowerBound, long upperBound) throws DirectoryException { if (attrValue < lowerBound) { if (attrValue < lowerBound) { throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, ERR_CONFIG_ATTR_INT_BELOW_LOWER_BOUND.get(attrName, attrValue, lowerBound)); ERR_CONFIG_ATTR_INT_BELOW_LOWER_BOUND.get(attrName, attrValue, lowerBound)); } if (attrValue > upperBound) { if (attrValue > upperBound) { throw new DirectoryException(ResultCode.CONSTRAINT_VIOLATION, ERR_CONFIG_ATTR_INT_ABOVE_UPPER_BOUND.get(attrName, attrValue, upperBound)); ERR_CONFIG_ATTR_INT_ABOVE_UPPER_BOUND.get(attrName, attrValue, upperBound)); } } /** * Helper method to retieve an attribute value from given entry. * @param entry the entry to retrieve an attribute value from. * @param pwdAttrName attribute name to retrieve the value for. * * @param entry * the entry to retrieve an attribute value from. * @param pwdAttrName * attribute name to retrieve the value for. * @return <CODE>AttributeValue</CODE> or <CODE>null</CODE>. */ private AttributeValue getAttrValue(Entry entry, String pwdAttrName) { AttributeType pwdAttrType = DirectoryServer.getAttributeType( pwdAttrName, true); private AttributeValue getAttrValue(Entry entry, String pwdAttrName) { AttributeType pwdAttrType = DirectoryServer.getAttributeType(pwdAttrName, true); List<Attribute> pwdAttrList = entry.getAttribute(pwdAttrType); if ((pwdAttrList != null) && (!pwdAttrList.isEmpty())) { @@ -593,354 +564,391 @@ return null; } /** * {@inheritDoc} */ public void addChangeListener( ConfigurationChangeListener<PasswordPolicyCfg> listener) { // N/A : This is a subentry based configuration object. } /** * {@inheritDoc} */ public void removeChangeListener( ConfigurationChangeListener<PasswordPolicyCfg> listener) { // N/A : This is a subentry based configuration object. public boolean isAllowExpiredPasswordChanges() { return getDefaultPasswordPolicy().isAllowExpiredPasswordChanges(); } /** * {@inheritDoc} */ public SortedSet<String> getAccountStatusNotificationHandler() { return pAccountStatusNotificationHandler; public boolean isAllowMultiplePasswordValues() { return getDefaultPasswordPolicy().isAllowMultiplePasswordValues(); } /** * {@inheritDoc} */ public SortedSet<DN> getAccountStatusNotificationHandlerDNs() { SortedSet<String> values = getAccountStatusNotificationHandler(); SortedSet<DN> dnValues = new TreeSet<DN>(); for (String value : values) { try { dnValues.add(DN.decode(value)); } catch (DirectoryException de) { if (debugEnabled()) { TRACER.debugCaught(DebugLogLevel.ERROR, de); } } } return dnValues; public boolean isAllowPreEncodedPasswords() { return getDefaultPasswordPolicy().isAllowPreEncodedPasswords(); } /** * {@inheritDoc} */ public boolean isAllowExpiredPasswordChanges() { return pAllowExpiredPasswordChanges; public boolean isAllowUserPasswordChanges() { return pAllowUserPasswordChanges != null ? pAllowUserPasswordChanges : getDefaultPasswordPolicy().isAllowUserPasswordChanges(); } /** * {@inheritDoc} */ public boolean isAllowMultiplePasswordValues() { return pAllowMultiplePasswordValues; public boolean isExpirePasswordsWithoutWarning() { return getDefaultPasswordPolicy().isExpirePasswordsWithoutWarning(); } /** * {@inheritDoc} */ public boolean isAllowPreEncodedPasswords() { return pAllowPreEncodedPasswords; public boolean isForceChangeOnAdd() { return getDefaultPasswordPolicy().isForceChangeOnAdd(); } /** * {@inheritDoc} */ public boolean isAllowUserPasswordChanges() { return pAllowUserPasswordChanges; public boolean isForceChangeOnReset() { return pForceChangeOnReset != null ? pForceChangeOnReset : getDefaultPasswordPolicy().isForceChangeOnReset(); } /** * {@inheritDoc} */ public SortedSet<String> getDefaultPasswordStorageScheme() { return pDefaultPasswordStorageScheme; public int getGraceLoginCount() { return pGraceLoginCount != null ? pGraceLoginCount : getDefaultPasswordPolicy().getGraceLoginCount(); } /** * {@inheritDoc} */ public SortedSet<DN> getDefaultPasswordStorageSchemeDNs() { SortedSet<String> values = getDefaultPasswordStorageScheme(); SortedSet<DN> dnValues = new TreeSet<DN>(); for (String value : values) { try { dnValues.add(DN.decode(value)); } catch (DirectoryException de) { if (debugEnabled()) { TRACER.debugCaught(DebugLogLevel.ERROR, de); } } } return dnValues; public long getIdleLockoutInterval() { return getDefaultPasswordPolicy().getIdleLockoutInterval(); } /** * {@inheritDoc} */ public SortedSet<String> getDeprecatedPasswordStorageScheme() { return pDeprecatedPasswordStorageScheme; public AttributeType getLastLoginTimeAttribute() { return getDefaultPasswordPolicy().getLastLoginTimeAttribute(); } /** * {@inheritDoc} */ public SortedSet<DN> getDeprecatedPasswordStorageSchemeDNs() { SortedSet<String> values = getDeprecatedPasswordStorageScheme(); SortedSet<DN> dnValues = new TreeSet<DN>(); for (String value : values) { try { dnValues.add(DN.decode(value)); } catch (DirectoryException de) { if (debugEnabled()) { TRACER.debugCaught(DebugLogLevel.ERROR, de); } } } return dnValues; public String getLastLoginTimeFormat() { return getDefaultPasswordPolicy().getLastLoginTimeFormat(); } /** * {@inheritDoc} */ public boolean isExpirePasswordsWithoutWarning() { return pExpirePasswordsWithoutWarning; public long getLockoutDuration() { return pLockoutDuration != null ? pLockoutDuration : getDefaultPasswordPolicy().getLockoutDuration(); } /** * {@inheritDoc} */ public boolean isForceChangeOnAdd() { return pForceChangeOnAdd; public int getLockoutFailureCount() { return pLockoutFailureCount != null ? pLockoutFailureCount : getDefaultPasswordPolicy().getLockoutFailureCount(); } /** * {@inheritDoc} */ public boolean isForceChangeOnReset() { return pForceChangeOnReset; public long getLockoutFailureExpirationInterval() { return pLockoutFailureExpirationInterval != null ? pLockoutFailureExpirationInterval : getDefaultPasswordPolicy().getLockoutFailureExpirationInterval(); } /** * {@inheritDoc} */ public int getGraceLoginCount() { return pGraceLoginCount; public long getMaxPasswordAge() { return pMaxPasswordAge != null ? pMaxPasswordAge : getDefaultPasswordPolicy().getMaxPasswordAge(); } /** * {@inheritDoc} */ public long getIdleLockoutInterval() { return pIdleLockoutInterval; public long getMaxPasswordResetAge() { return getDefaultPasswordPolicy().getMaxPasswordResetAge(); } /** * {@inheritDoc} */ public AttributeType getLastLoginTimeAttribute() { return pLastLoginTimeAttribute; public long getMinPasswordAge() { return pMinPasswordAge != null ? pMinPasswordAge : getDefaultPasswordPolicy().getMinPasswordAge(); } /** * {@inheritDoc} */ public String getLastLoginTimeFormat() { return pLastLoginTimeFormat; public AttributeType getPasswordAttribute() { return pPasswordAttribute != null ? pPasswordAttribute : getDefaultPasswordPolicy().getPasswordAttribute(); } /** * {@inheritDoc} */ public long getLockoutDuration() { return pLockoutDuration; public boolean isPasswordChangeRequiresCurrentPassword() { return pPasswordChangeRequiresCurrentPassword != null ? pPasswordChangeRequiresCurrentPassword : getDefaultPasswordPolicy().isPasswordChangeRequiresCurrentPassword(); } /** * {@inheritDoc} */ public int getLockoutFailureCount() { return pLockoutFailureCount; public long getPasswordExpirationWarningInterval() { return pPasswordExpirationWarningInterval != null ? pPasswordExpirationWarningInterval : getDefaultPasswordPolicy().getPasswordExpirationWarningInterval(); } /** * {@inheritDoc} */ public long getLockoutFailureExpirationInterval() { return pLockoutFailureExpirationInterval; public int getPasswordHistoryCount() { return pPasswordHistoryCount != null ? pPasswordHistoryCount : getDefaultPasswordPolicy().getPasswordHistoryCount(); } /** * {@inheritDoc} */ public long getMaxPasswordAge() { return pMaxPasswordAge; public long getPasswordHistoryDuration() { return getDefaultPasswordPolicy().getPasswordHistoryDuration(); } /** * {@inheritDoc} */ public long getMaxPasswordResetAge() { return pMaxPasswordResetAge; public SortedSet<String> getPreviousLastLoginTimeFormats() { return getDefaultPasswordPolicy().getPreviousLastLoginTimeFormats(); } /** * {@inheritDoc} */ public long getMinPasswordAge() { return pMinPasswordAge; public long getRequireChangeByTime() { return getDefaultPasswordPolicy().getRequireChangeByTime(); } /** * {@inheritDoc} */ public AttributeType getPasswordAttribute() { return pPasswordAttribute; public boolean isRequireSecureAuthentication() { return getDefaultPasswordPolicy().isRequireSecureAuthentication(); } /** * {@inheritDoc} */ public boolean isPasswordChangeRequiresCurrentPassword() { return pPasswordChangeRequiresCurrentPassword; public boolean isRequireSecurePasswordChanges() { return getDefaultPasswordPolicy().isRequireSecurePasswordChanges(); } /** * {@inheritDoc} */ public long getPasswordExpirationWarningInterval() { return pPasswordExpirationWarningInterval; public boolean isSkipValidationForAdministrators() { return getDefaultPasswordPolicy().isSkipValidationForAdministrators(); } /** * {@inheritDoc} */ public String getPasswordGenerator() { return pPasswordGenerator; public StateUpdateFailurePolicy getStateUpdateFailurePolicy() { return getDefaultPasswordPolicy().getStateUpdateFailurePolicy(); } /** * {@inheritDoc} */ public DN getPasswordGeneratorDN() { String value = getPasswordGenerator(); if (value == null) { return null; } try { return DN.decode(value); } catch (DirectoryException de) { if (debugEnabled()) { TRACER.debugCaught(DebugLogLevel.ERROR, de); } return null; } public boolean isAuthPasswordSyntax() { return pAuthPasswordSyntax != null ? pAuthPasswordSyntax : getDefaultPasswordPolicy().isAuthPasswordSyntax(); } /** * {@inheritDoc} */ public int getPasswordHistoryCount() { return pPasswordHistoryCount; public List<PasswordStorageScheme<?>> getDefaultPasswordStorageSchemes() { return getDefaultPasswordPolicy().getDefaultPasswordStorageSchemes(); } /** * {@inheritDoc} */ public long getPasswordHistoryDuration() { return pPasswordHistoryDuration; public Set<String> getDeprecatedPasswordStorageSchemes() { return getDefaultPasswordPolicy().getDeprecatedPasswordStorageSchemes(); } /** * {@inheritDoc} */ public SortedSet<String> getPasswordValidator() { return pPasswordValidator; } /** * {@inheritDoc} */ public SortedSet<DN> getPasswordValidatorDNs() { SortedSet<String> values = getPasswordValidator(); SortedSet<DN> dnValues = new TreeSet<DN>(); for (String value : values) { try { dnValues.add(DN.decode(value)); } catch (DirectoryException de) { if (debugEnabled()) { TRACER.debugCaught(DebugLogLevel.ERROR, de); } } } return dnValues; } /** * {@inheritDoc} */ public SortedSet<String> getPreviousLastLoginTimeFormat() { return pPreviousLastLoginTimeFormat; } /** * {@inheritDoc} */ public String getRequireChangeByTime() { return pRequireChangeByTime; } /** * {@inheritDoc} */ public boolean isRequireSecureAuthentication() { return pRequireSecureAuthentication; } /** * {@inheritDoc} */ public boolean isRequireSecurePasswordChanges() { return pRequireSecurePasswordChanges; } /** * {@inheritDoc} */ public boolean isSkipValidationForAdministrators() { return pSkipValidationForAdministrators; } /** * {@inheritDoc} */ public StateUpdateFailurePolicy getStateUpdateFailurePolicy() { return pStateUpdateFailurePolicy; } /** * {@inheritDoc} */ public Class<? extends PasswordPolicyCfg> configurationClass() { return PasswordPolicyCfg.class; } /** * {@inheritDoc} */ public DN dn() { public DN getDN() { return passwordPolicySubentryDN; } /** * {@inheritDoc} */ public boolean isDefaultPasswordStorageScheme(String name) { return getDefaultPasswordPolicy().isDefaultPasswordStorageScheme(name); } /** * {@inheritDoc} */ public boolean isDeprecatedPasswordStorageScheme(String name) { return getDefaultPasswordPolicy().isDeprecatedPasswordStorageScheme(name); } /** * {@inheritDoc} */ public Collection<PasswordValidator<?>> getPasswordValidators() { return getDefaultPasswordPolicy().getPasswordValidators(); } /** * {@inheritDoc} */ public Collection<AccountStatusNotificationHandler<?>> getAccountStatusNotificationHandlers() { return getDefaultPasswordPolicy().getAccountStatusNotificationHandlers(); } /** * {@inheritDoc} */ public PasswordGenerator<?> getPasswordGenerator() { return getDefaultPasswordPolicy().getPasswordGenerator(); } } opends/src/server/org/opends/server/extensions/PasswordModifyExtendedOperation.java
@@ -613,7 +613,9 @@ // make sure that's OK. if (oldPassword == null) { if (selfChange && pwPolicyState.getPolicy().requireCurrentPassword()) if (selfChange && pwPolicyState.getPolicy() .isPasswordChangeRequiresCurrentPassword()) { operation.setResultCode(ResultCode.UNWILLING_TO_PERFORM); @@ -635,7 +637,7 @@ } else { if (pwPolicyState.getPolicy().requireSecureAuthentication() && if (pwPolicyState.getPolicy().isRequireSecureAuthentication() && (! operation.getClientConnection().isSecure())) { operation.setResultCode(ResultCode.CONFIDENTIALITY_REQUIRED); @@ -673,7 +675,7 @@ // If it is a self password change and we don't allow that, then reject // the request. if (selfChange && (! pwPolicyState.getPolicy().allowUserPasswordChanges())) (! pwPolicyState.getPolicy().isAllowUserPasswordChanges())) { if (pwPolicyRequested) { @@ -695,7 +697,7 @@ // If we require secure password changes and the connection isn't secure, // then reject the request. if (pwPolicyState.getPolicy().requireSecurePasswordChanges() && if (pwPolicyState.getPolicy().isRequireSecurePasswordChanges() && (! operation.getClientConnection().isSecure())) { @@ -732,7 +734,7 @@ // If the user's password is expired and it's a self-change request, then // see if that's OK. if ((selfChange && pwPolicyState.isPasswordExpired() && (! pwPolicyState.getPolicy().allowExpiredPasswordChanges()))) (! pwPolicyState.getPolicy().isAllowExpiredPasswordChanges()))) { if (pwPolicyRequested) { @@ -798,7 +800,7 @@ // by an internal operation or during synchronization, so we don't // need to check for those cases. isPreEncoded = true; if (! pwPolicyState.getPolicy().allowPreEncodedPasswords()) if (! pwPolicyState.getPolicy().isAllowPreEncodedPasswords()) { operation.setResultCode(ResultCode.UNWILLING_TO_PERFORM); @@ -810,8 +812,9 @@ else { // Run the new password through the set of password validators. if (selfChange || (! pwPolicyState.getPolicy().skipValidationForAdministrators())) if (selfChange || (!pwPolicyState.getPolicy() .isSkipValidationForAdministrators())) { HashSet<ByteString> clearPasswords; if (oldPassword == null) @@ -864,7 +867,7 @@ if (pwPolicyState.isPasswordInHistory(newPassword)) { if (selfChange || (! pwPolicyState.getPolicy(). skipValidationForAdministrators())) isSkipValidationForAdministrators())) { operation.setResultCode(ResultCode.UNWILLING_TO_PERFORM); @@ -923,7 +926,7 @@ Set<AttributeValue> existingValues = pwPolicyState.getPasswordValues(); LinkedHashSet<AttributeValue> deleteValues = new LinkedHashSet<AttributeValue>(existingValues.size()); if (pwPolicyState.getPolicy().usesAuthPasswordSyntax()) if (pwPolicyState.getPolicy().isAuthPasswordSyntax()) { for (AttributeValue v : existingValues) { @@ -1053,7 +1056,7 @@ else { pwPolicyState.setMustChangePassword( pwPolicyState.getPolicy().forceChangeOnReset()); pwPolicyState.getPolicy().isForceChangeOnReset()); } opends/src/server/org/opends/server/extensions/PasswordPolicyStateExtendedOperation.java
@@ -927,7 +927,7 @@ if (returnAll || returnTypes.contains(OP_GET_PASSWORD_POLICY_DN)) { encode(writer, OP_GET_PASSWORD_POLICY_DN, policy.getConfigEntryDN().toString()); policy.getDN().toString()); } if (returnAll || returnTypes.contains(OP_GET_ACCOUNT_DISABLED_STATE)) @@ -1025,14 +1025,15 @@ returnTypes.contains(OP_GET_SECONDS_UNTIL_PASSWORD_EXPIRATION_WARNING)) { String secondsStr; int secondsUntilExp = pwpState.getSecondsUntilExpiration(); long secondsUntilExp = pwpState.getSecondsUntilExpiration(); if (secondsUntilExp < 0) { secondsStr = null; } else { int secondsUntilWarning = secondsUntilExp - policy.getWarningInterval(); long secondsUntilWarning = secondsUntilExp - policy.getPasswordExpirationWarningInterval(); if (secondsUntilWarning <= 0) { secondsStr = "0"; @@ -1124,7 +1125,7 @@ if (returnAll || returnTypes.contains(OP_GET_SECONDS_UNTIL_IDLE_LOCKOUT)) { String secondsStr; int lockoutInterval = policy.getIdleLockoutInterval(); long lockoutInterval = policy.getIdleLockoutInterval(); if (lockoutInterval > 0) { long lastLoginTime = pwpState.getLastLoginTime(); @@ -1167,13 +1168,13 @@ String secondsStr; if (pwpState.mustChangePassword()) { int maxAge = policy.getMaximumPasswordResetAge(); long maxAge = policy.getMaxPasswordResetAge(); if (maxAge > 0) { long currentTime = pwpState.getCurrentTime(); long changedTime = pwpState.getPasswordChangedTime(); int changeAge = (int) ((currentTime - changedTime) / 1000); int timeToLockout = maxAge - changeAge; long timeToLockout = maxAge - changeAge; if (timeToLockout <= 0) { secondsStr = "0"; opends/src/server/org/opends/server/extensions/PasswordPolicySubentryVirtualAttributeProvider.java
@@ -23,6 +23,7 @@ * * * Copyright 2010 Sun Microsystems, Inc. * Portions copyright 2011 ForgeRock AS. */ package org.opends.server.extensions; @@ -136,7 +137,7 @@ { AttributeType dnAttrType = DirectoryServer.getAttributeType( "1.3.6.1.4.1.42.2.27.8.1.23"); DN policyDN = policy.getConfigEntryDN(); DN policyDN = policy.getDN(); AttributeValue value = AttributeValues.create( dnAttrType, policyDN.toString()); valueSet.add(value); opends/src/server/org/opends/server/plugins/PasswordPolicyImportPlugin.java
@@ -23,6 +23,7 @@ * * * Copyright 2006-2010 Sun Microsystems, Inc. * Portions copyright 2011 ForgeRock AS. */ package org.opends.server.plugins; @@ -41,13 +42,13 @@ import java.util.HashSet; import java.util.List; import java.util.Set; import java.util.concurrent.CopyOnWriteArrayList; import org.opends.messages.Message; import org.opends.server.admin.server.ConfigurationChangeListener; import org.opends.server.admin.std.meta.PluginCfgDefn; import org.opends.server.admin.std.server.PasswordPolicyImportPluginCfg; import org.opends.server.admin.std.server.PluginCfg; import org.opends.server.api.AuthenticationPolicy; import org.opends.server.api.Backend; import org.opends.server.api.ImportTaskListener; import org.opends.server.api.PasswordStorageScheme; @@ -57,7 +58,7 @@ import org.opends.server.config.ConfigException; import org.opends.server.core.DirectoryServer; import org.opends.server.core.PasswordPolicy; import org.opends.server.core.PasswordPolicyConfigManager; import org.opends.server.core.SubentryPasswordPolicy; import org.opends.server.loggers.debug.DebugTracer; import org.opends.server.schema.AuthPasswordSyntax; import org.opends.server.schema.UserPasswordSyntax; @@ -156,10 +157,10 @@ configuration.getDefaultAuthPasswordStorageSchemeDNs(); if (authSchemeDNs.isEmpty()) { if (defaultPolicy.usesAuthPasswordSyntax()) if (defaultPolicy.isAuthPasswordSyntax()) { CopyOnWriteArrayList<PasswordStorageScheme<?>> schemeList = defaultPolicy.getDefaultStorageSchemes(); List<PasswordStorageScheme<?>> schemeList = defaultPolicy.getDefaultPasswordStorageSchemes(); defaultAuthPasswordSchemes = new PasswordStorageScheme[schemeList.size()]; schemeList.toArray(defaultAuthPasswordSchemes); @@ -212,10 +213,10 @@ configuration.getDefaultUserPasswordStorageSchemeDNs(); if (userSchemeDNs.isEmpty()) { if (! defaultPolicy.usesAuthPasswordSyntax()) if (! defaultPolicy.isAuthPasswordSyntax()) { CopyOnWriteArrayList<PasswordStorageScheme<?>> schemeList = defaultPolicy.getDefaultStorageSchemes(); List<PasswordStorageScheme<?>> schemeList = defaultPolicy.getDefaultPasswordStorageSchemes(); defaultUserPasswordSchemes = new PasswordStorageScheme[schemeList.size()]; schemeList.toArray(defaultUserPasswordSchemes); @@ -285,14 +286,16 @@ // attribute types associated with them. HashMap<DN,PasswordStorageScheme<?>[]> schemeMap = new HashMap<DN,PasswordStorageScheme<?>[]>(); for (PasswordPolicy p : DirectoryServer.getPasswordPolicies()) for (AuthenticationPolicy ap : DirectoryServer.getAuthenticationPolicies()) { CopyOnWriteArrayList<PasswordStorageScheme<?>> schemeList = p.getDefaultStorageSchemes(); PasswordPolicy p = (PasswordPolicy) ap; List<PasswordStorageScheme<?>> schemeList = p.getDefaultPasswordStorageSchemes(); PasswordStorageScheme<?>[] schemeArray = new PasswordStorageScheme[schemeList.size()]; schemeList.toArray(schemeArray); schemeMap.put(p.getConfigEntryDN(), schemeArray); schemeMap.put(p.getDN(), schemeArray); } @@ -333,7 +336,7 @@ { try { PasswordPolicyConfigManager.checkSubentryAcceptable(entry); new SubentryPasswordPolicy(new SubEntry(entry)); } catch (DirectoryException de) { @@ -362,7 +365,8 @@ try { policyDN = DN.decode(v.getValue()); policy = DirectoryServer.getPasswordPolicy(policyDN); policy = (PasswordPolicy) DirectoryServer .getAuthenticationPolicy(policyDN); if (policy == null) { Message message = WARN_PLUGIN_PWIMPORT_NO_SUCH_POLICY.get( @@ -401,7 +405,7 @@ { ByteString value = v.getValue(); if (policy.usesAuthPasswordSyntax()) if (policy.isAuthPasswordSyntax()) { if (!AuthPasswordSyntax.isEncoded(value)) { @@ -761,10 +765,10 @@ configuration.getDefaultAuthPasswordStorageSchemeDNs(); if (authSchemeDNs.isEmpty()) { if (defaultPolicy.usesAuthPasswordSyntax()) if (defaultPolicy.isAuthPasswordSyntax()) { CopyOnWriteArrayList<PasswordStorageScheme<?>> schemeList = defaultPolicy.getDefaultStorageSchemes(); List<PasswordStorageScheme<?>> schemeList = defaultPolicy.getDefaultPasswordStorageSchemes(); defaultAuthSchemes = new PasswordStorageScheme[schemeList.size()]; schemeList.toArray(defaultAuthSchemes); @@ -820,10 +824,10 @@ configuration.getDefaultUserPasswordStorageSchemeDNs(); if (userSchemeDNs.isEmpty()) { if (! defaultPolicy.usesAuthPasswordSyntax()) if (! defaultPolicy.isAuthPasswordSyntax()) { CopyOnWriteArrayList<PasswordStorageScheme<?>> schemeList = defaultPolicy.getDefaultStorageSchemes(); List<PasswordStorageScheme<?>> schemeList = defaultPolicy.getDefaultPasswordStorageSchemes(); defaultUserSchemes = new PasswordStorageScheme[schemeList.size()]; schemeList.toArray(defaultUserSchemes); opends/src/server/org/opends/server/tools/EncodePassword.java
@@ -23,6 +23,7 @@ * * * Copyright 2006-2010 Sun Microsystems, Inc. * Portions copyright 2011 ForgeRock AS. */ package org.opends.server.tools; @@ -912,7 +913,7 @@ // Initialize the subentry manager. directoryServer.initializeSubentryManager(); //Initialize PWD policy components. directoryServer.initializePasswordPolicyComponents(); directoryServer.initializeAuthenticationPolicyComponents(); //Load the crypto-manager key cache among other things. new CryptoManagerSync(); } catch (InitializationException ie) { opends/src/server/org/opends/server/tools/ImportLDIF.java
@@ -23,6 +23,7 @@ * * * Copyright 2006-2010 Sun Microsystems, Inc. * Portions copyright 2011 ForgeRock AS. */ package org.opends.server.tools; @@ -939,7 +940,7 @@ // Initialize all the password policy information. try { directoryServer.initializePasswordPolicyComponents(); directoryServer.initializeAuthenticationPolicyComponents(); } catch (ConfigException ce) { opends/src/server/org/opends/server/types/AccountStatusNotification.java
@@ -23,6 +23,7 @@ * * * Copyright 2006-2008 Sun Microsystems, Inc. * Portions copyright 2011 ForgeRock AS. */ package org.opends.server.types; @@ -239,13 +240,13 @@ PasswordPolicy policy = pwPolicyState.getPolicy(); ArrayList<String> propList = new ArrayList<String>(1); propList.add(policy.getConfigEntryDN().toString()); propList.add(policy.getDN().toString()); props.put(PASSWORD_POLICY_DN, propList); if (tempLocked) { int secondsUntilUnlock = policy.getLockoutDuration(); if (secondsUntilUnlock > 0) long secondsUntilUnlock = policy.getLockoutDuration(); if (secondsUntilUnlock > 0L) { propList = new ArrayList<String>(1); propList.add(String.valueOf(secondsUntilUnlock)); opends/src/server/org/opends/server/util/StaticUtils.java
@@ -3848,7 +3848,7 @@ * @return The user-friendly representation of the specified number of * seconds. */ public static Message secondsToTimeString(int numSeconds) public static Message secondsToTimeString(long numSeconds) { if (numSeconds < 60) { @@ -3858,25 +3858,25 @@ else if (numSeconds < 3600) { // We can express it in minutes and seconds. int m = numSeconds / 60; int s = numSeconds % 60; long m = numSeconds / 60; long s = numSeconds % 60; return INFO_TIME_IN_MINUTES_SECONDS.get(m, s); } else if (numSeconds < 86400) { // We can express it in hours, minutes, and seconds. int h = numSeconds / 3600; int m = (numSeconds % 3600) / 60; int s = numSeconds % 3600 % 60; long h = numSeconds / 3600; long m = (numSeconds % 3600) / 60; long s = numSeconds % 3600 % 60; return INFO_TIME_IN_HOURS_MINUTES_SECONDS.get(h, m, s); } else { // We can express it in days, hours, minutes, and seconds. int d = numSeconds / 86400; int h = (numSeconds % 86400) / 3600; int m = (numSeconds % 86400 % 3600) / 60; int s = numSeconds % 86400 % 3600 % 60; long d = numSeconds / 86400; long h = (numSeconds % 86400) / 3600; long m = (numSeconds % 86400 % 3600) / 60; long s = numSeconds % 86400 % 3600 % 60; return INFO_TIME_IN_DAYS_HOURS_MINUTES_SECONDS.get(d, h, m, s); } } opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendAddOperation.java
@@ -41,7 +41,6 @@ import java.util.Iterator; import java.util.List; import java.util.Map; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.locks.Lock; import org.opends.messages.Message; @@ -1057,7 +1056,8 @@ de.getMessageObject())); } passwordPolicy = DirectoryServer.getPasswordPolicy(policyDN); passwordPolicy = (PasswordPolicy) DirectoryServer .getAuthenticationPolicy(policyDN); if (passwordPolicy == null) { throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, @@ -1105,7 +1105,7 @@ } if ((!isInternalOperation()) && (!passwordPolicy.allowMultiplePasswordValues()) && (!passwordPolicy.isAllowMultiplePasswordValues()) && (passwordAttr.size() > 1)) { // FIXME -- What if they're pre-encoded and might all be the @@ -1117,8 +1117,8 @@ throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, message); } CopyOnWriteArrayList<PasswordStorageScheme<?>> defaultStorageSchemes = passwordPolicy.getDefaultStorageSchemes(); List<PasswordStorageScheme<?>> defaultStorageSchemes = passwordPolicy.getDefaultPasswordStorageSchemes(); AttributeBuilder builder = new AttributeBuilder(passwordAttr, true); builder.setInitialCapacity(defaultStorageSchemes.size()); for (AttributeValue v : passwordAttr) @@ -1126,12 +1126,12 @@ ByteString value = v.getValue(); // See if the password is pre-encoded. if (passwordPolicy.usesAuthPasswordSyntax()) if (passwordPolicy.isAuthPasswordSyntax()) { if (AuthPasswordSyntax.isEncoded(value)) { if (isInternalOperation() || passwordPolicy.allowPreEncodedPasswords()) passwordPolicy.isAllowPreEncodedPasswords()) { builder.add(v); continue; @@ -1153,7 +1153,7 @@ if (UserPasswordSyntax.isEncoded(value)) { if (isInternalOperation() || passwordPolicy.allowPreEncodedPasswords()) passwordPolicy.isAllowPreEncodedPasswords()) { builder.add(v); continue; @@ -1174,13 +1174,13 @@ // See if the password passes validation. We should only do this if // validation should be performed for administrators. if (! passwordPolicy.skipValidationForAdministrators()) if (! passwordPolicy.isSkipValidationForAdministrators()) { // There are never any current passwords for an add operation. HashSet<ByteString> currentPasswords = new HashSet<ByteString>(0); MessageBuilder invalidReason = new MessageBuilder(); for (PasswordValidator<?> validator : passwordPolicy.getPasswordValidators().values()) passwordPolicy.getPasswordValidators()) { if (! validator.passwordIsAcceptable(value, currentPasswords, this, entry, invalidReason)) @@ -1199,7 +1199,7 @@ // Encode the password. if (passwordPolicy.usesAuthPasswordSyntax()) if (passwordPolicy.isAuthPasswordSyntax()) { for (PasswordStorageScheme<?> s : defaultStorageSchemes) { @@ -1233,7 +1233,7 @@ // If we should force change on add, then set the appropriate flag. if (passwordPolicy.forceChangeOnAdd()) if (passwordPolicy.isForceChangeOnAdd()) { addPWPolicyControl(PasswordPolicyErrorType.CHANGE_AFTER_RESET); opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendBindOperation.java
@@ -23,6 +23,7 @@ * * * Copyright 2008-2010 Sun Microsystems, Inc. * Portions copyright 2011 ForgeRock AS. */ package org.opends.server.workflowelement.localbackend; @@ -963,7 +964,8 @@ // Check to see if the authentication must be done in a secure // manner. If so, then the client connection must be secure. if (policy.requireSecureAuthentication() && (! clientConnection.isSecure())) if (policy.isRequireSecureAuthentication() && (!clientConnection.isSecure())) { if (isSASLBind) { opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendModifyOperation.java
@@ -1136,7 +1136,7 @@ // If it's a self change, then see if that's allowed. if (selfChange && (! pwPolicyState.getPolicy().allowUserPasswordChanges())) (! pwPolicyState.getPolicy().isAllowUserPasswordChanges())) { pwpErrorType = PasswordPolicyErrorType.PASSWORD_MOD_NOT_ALLOWED; throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, @@ -1146,7 +1146,7 @@ // If we require secure password changes, then makes sure it's a // secure communication channel. if (pwPolicyState.getPolicy().requireSecurePasswordChanges() && if (pwPolicyState.getPolicy().isRequireSecurePasswordChanges() && (! clientConnection.isSecure())) { pwpErrorType = PasswordPolicyErrorType.PASSWORD_MOD_NOT_ALLOWED; @@ -1242,7 +1242,7 @@ // If there were multiple password values, then make sure that's // OK. if ((!isInternalOperation()) && (!pwPolicyState.getPolicy().allowMultiplePasswordValues()) && (!pwPolicyState.getPolicy().isAllowMultiplePasswordValues()) && (passwordsToAdd > 1)) { pwpErrorType = PasswordPolicyErrorType.PASSWORD_MOD_NOT_ALLOWED; @@ -1260,7 +1260,7 @@ if (pwPolicyState.passwordIsPreEncoded(v.getValue())) { if ((!isInternalOperation()) && !pwPolicyState.getPolicy().allowPreEncodedPasswords()) && !pwPolicyState.getPolicy().isAllowPreEncodedPasswords()) { pwpErrorType = PasswordPolicyErrorType.INSUFFICIENT_PASSWORD_QUALITY; throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, @@ -1382,7 +1382,7 @@ { for (AttributeValue av : attr) { if (pwPolicyState.getPolicy().usesAuthPasswordSyntax()) if (pwPolicyState.getPolicy().isAuthPasswordSyntax()) { if (AuthPasswordSyntax.isEncoded(av.getValue())) { @@ -1870,7 +1870,7 @@ // If it was a self change, then see if the current password was provided // and handle accordingly. if (selfChange && pwPolicyState.getPolicy().requireCurrentPassword() && pwPolicyState.getPolicy().isPasswordChangeRequiresCurrentPassword() && (! currentPasswordProvided)) { pwpErrorType = PasswordPolicyErrorType.MUST_SUPPLY_OLD_PASSWORD; @@ -1883,7 +1883,7 @@ // If this change would result in multiple password values, then see if // that's OK. if ((numPasswords > 1) && (! pwPolicyState.getPolicy().allowMultiplePasswordValues())) (! pwPolicyState.getPolicy().isAllowMultiplePasswordValues())) { pwpErrorType = PasswordPolicyErrorType.PASSWORD_MOD_NOT_ALLOWED; throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, @@ -1893,7 +1893,7 @@ // If any of the password values should be validated, then do so now. if (selfChange || (! pwPolicyState.getPolicy().skipValidationForAdministrators())) (! pwPolicyState.getPolicy().isSkipValidationForAdministrators())) { if (newPasswords != null) { @@ -1966,7 +1966,7 @@ if (pwPolicyState.isPasswordInHistory(v.getValue())) { if (selfChange || (! pwPolicyState.getPolicy(). skipValidationForAdministrators())) isSkipValidationForAdministrators())) { pwpErrorType = PasswordPolicyErrorType.PASSWORD_IN_HISTORY; throw new DirectoryException(ResultCode.UNWILLING_TO_PERFORM, @@ -1992,8 +1992,8 @@ pwPolicyState.clearGraceLoginTimes(); pwPolicyState.clearWarnedTime(); if (pwPolicyState.getPolicy().forceChangeOnAdd() || pwPolicyState.getPolicy().forceChangeOnReset()) if (pwPolicyState.getPolicy().isForceChangeOnAdd() || pwPolicyState.getPolicy().isForceChangeOnReset()) { if (selfChange) { @@ -2002,13 +2002,13 @@ else { if ((pwpErrorType == null) && pwPolicyState.getPolicy().forceChangeOnReset()) pwPolicyState.getPolicy().isForceChangeOnReset()) { pwpErrorType = PasswordPolicyErrorType.CHANGE_AFTER_RESET; } pwPolicyState.setMustChangePassword( pwPolicyState.getPolicy().forceChangeOnReset()); pwPolicyState.getPolicy().isForceChangeOnReset()); } } opends/tests/staf-tests/functional-tests/shared/data/security/auth_pwd_syntax/admin_add_MD5_policy.ldif
@@ -21,11 +21,14 @@ # CDDL HEADER END # # Copyright 2008 Sun Microsystems, Inc. # Portions copyright 2011 ForgeRock AS. # dn: cn=Sales Password Policy,cn=Password Policies,cn=config objectClass: ds-cfg-authentication-policy objectClass: ds-cfg-password-policy objectClass: top ds-cfg-java-class: org.opends.server.core.PasswordPolicyFactory ds-cfg-skip-validation-for-administrators: false ds-cfg-password-expiration-warning-interval: 5 days ds-cfg-default-password-storage-scheme: cn=Salted MD5,cn=Password Storage Schemes,cn=config opends/tests/staf-tests/functional-tests/shared/data/security/auth_pwd_syntax/admin_add_SHA1_policy.ldif
@@ -21,11 +21,14 @@ # CDDL HEADER END # # Copyright 2008 Sun Microsystems, Inc. # Portions copyright 2011 ForgeRock AS. # dn: cn=Sales Password Policy,cn=Password Policies,cn=config objectClass: ds-cfg-authentication-policy objectClass: ds-cfg-password-policy objectClass: top ds-cfg-java-class: org.opends.server.core.PasswordPolicyFactory ds-cfg-skip-validation-for-administrators: false ds-cfg-password-expiration-warning-interval: 5 days ds-cfg-default-password-storage-scheme: cn=Salted SHA-1,cn=Password Storage Schemes,cn=config opends/tests/staf-tests/functional-tests/shared/data/security/auth_pwd_syntax/admin_add_SHA256_policy.ldif
@@ -21,11 +21,14 @@ # CDDL HEADER END # # Copyright 2008 Sun Microsystems, Inc. # Portions copyright 2011 ForgeRock AS. # dn: cn=Sales Password Policy,cn=Password Policies,cn=config objectClass: ds-cfg-authentication-policy objectClass: ds-cfg-password-policy objectClass: top ds-cfg-java-class: org.opends.server.core.PasswordPolicyFactory ds-cfg-skip-validation-for-administrators: false ds-cfg-password-expiration-warning-interval: 5 days ds-cfg-default-password-storage-scheme: cn=Salted SHA-256,cn=Password Storage Schemes,cn=config opends/tests/staf-tests/functional-tests/shared/data/security/auth_pwd_syntax/admin_add_SHA384_policy.ldif
@@ -21,11 +21,14 @@ # CDDL HEADER END # # Copyright 2008 Sun Microsystems, Inc. # Portions copyright 2011 ForgeRock AS. # dn: cn=Sales Password Policy,cn=Password Policies,cn=config objectClass: ds-cfg-authentication-policy objectClass: ds-cfg-password-policy objectClass: top ds-cfg-java-class: org.opends.server.core.PasswordPolicyFactory ds-cfg-skip-validation-for-administrators: false ds-cfg-password-expiration-warning-interval: 5 days ds-cfg-default-password-storage-scheme: cn=Salted SHA-384,cn=Password Storage Schemes,cn=config opends/tests/staf-tests/functional-tests/shared/data/security/auth_pwd_syntax/admin_add_SHA512_policy.ldif
@@ -21,11 +21,14 @@ # CDDL HEADER END # # Copyright 2008 Sun Microsystems, Inc. # Portions copyright 2011 ForgeRock AS. # dn: cn=Sales Password Policy,cn=Password Policies,cn=config objectClass: ds-cfg-authentication-policy objectClass: ds-cfg-password-policy objectClass: top ds-cfg-java-class: org.opends.server.core.PasswordPolicyFactory ds-cfg-skip-validation-for-administrators: false ds-cfg-password-expiration-warning-interval: 5 days ds-cfg-default-password-storage-scheme: cn=Salted SHA-512,cn=Password Storage Schemes,cn=config opends/tests/staf-tests/functional-tests/testcases/security/pwd_policy/security_mult_pwd_policies.xml
@@ -24,6 +24,7 @@ ! CDDL HEADER END ! ! Copyright 2006-2008 Sun Microsystems, Inc. ! Portions copyright 2011 ForgeRock AS. ! --> <stax> @@ -75,7 +76,7 @@ 'subcommand' : 'create-password-policy' , 'objectType' : 'policy-name' , 'objectName' : 'Sales Password Policy', 'optionsString' : '--set "%s" --set %s' % (msg1,msg2), 'optionsString' : '--type password-policy --set "%s" --set %s' % (msg1,msg2), 'expectedRC' : 0 } </call> opends/tests/unit-tests-testng/resource/config-changes.ldif
@@ -76,8 +76,10 @@ dn: cn=SSHA512 UserPassword Policy,cn=Password Policies,cn=config changetype: add objectClass: top objectClass: ds-cfg-authentication-policy objectClass: ds-cfg-password-policy objectClass: top ds-cfg-java-class: org.opends.server.core.PasswordPolicyFactory cn: SSHA512 UserPassword Policy ds-cfg-password-attribute: userPassword ds-cfg-default-password-storage-scheme: cn=Salted SHA-512,cn=Password Storage Schemes,cn=config @@ -106,8 +108,10 @@ dn: cn=SHA1 AuthPassword Policy,cn=Password Policies,cn=config changetype: add objectClass: top objectClass: ds-cfg-authentication-policy objectClass: ds-cfg-password-policy objectClass: top ds-cfg-java-class: org.opends.server.core.PasswordPolicyFactory cn: SHA1 AuthPassword Policy ds-cfg-password-attribute: authPassword ds-cfg-default-password-storage-scheme: cn=Salted SHA-1,cn=Password Storage Schemes,cn=config @@ -136,8 +140,10 @@ dn: cn=Clear UserPassword Policy,cn=Password Policies,cn=config changetype: add objectClass: top objectClass: ds-cfg-authentication-policy objectClass: ds-cfg-password-policy objectClass: top ds-cfg-java-class: org.opends.server.core.PasswordPolicyFactory cn: Test AuthPassword Policy ds-cfg-password-attribute: userPassword ds-cfg-default-password-storage-scheme: cn=CLEAR,cn=Password Storage Schemes,cn=config opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/ProxyBindTestCase.java
@@ -23,6 +23,7 @@ * * * Copyright 2008-2009 Sun Microsystems, Inc. * Portions copyright 2011 ForgeRock AS. */ /** @@ -79,6 +80,7 @@ "--set", "server-fqdn:localhost"); TestCaseUtils.dsconfig( "create-password-policy", "--type", "password-policy", "--policy-name", pwdPolicy, "--set", "password-attribute:userPassword", "--set", "default-password-storage-scheme: Clear" opends/tests/unit-tests-testng/src/server/org/opends/server/authorization/dseecompat/SSFTestCase.java
@@ -102,6 +102,7 @@ public void setupClass() throws Exception { TestCaseUtils.dsconfig( "create-password-policy", "--type", "password-policy", "--policy-name", pwdPolicy, "--set", "password-attribute:userPassword", "--set", "default-password-storage-scheme: Clear" opends/tests/unit-tests-testng/src/server/org/opends/server/core/PasswordPolicyTestCase.java
@@ -30,8 +30,7 @@ import java.util.List; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArraySet; import java.util.Set; import org.testng.annotations.BeforeClass; import org.testng.annotations.DataProvider; @@ -2181,7 +2180,7 @@ AdminTestCaseUtils.getConfiguration(PasswordPolicyCfgDefn.getInstance(), configEntry.getEntry()); new PasswordPolicy(configuration); new PasswordPolicyFactory().createAuthenticationPolicy(configuration); } @@ -2212,7 +2211,7 @@ { DN dn = DN.decode("cn=SHA1 AuthPassword Policy,cn=Password Policies," + "cn=config"); PasswordPolicy p = DirectoryServer.getPasswordPolicy(dn); PasswordPolicy p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); AttributeType t = p.getPasswordAttribute(); assertEquals(t, DirectoryServer.getAttributeType("authpassword")); } @@ -2227,7 +2226,7 @@ public void testUsesAuthPasswordSyntaxDefault() { PasswordPolicy p = DirectoryServer.getDefaultPasswordPolicy(); assertFalse(p.usesAuthPasswordSyntax()); assertFalse(p.isAuthPasswordSyntax()); } @@ -2244,8 +2243,8 @@ { DN dn = DN.decode("cn=SHA1 AuthPassword Policy,cn=Password Policies," + "cn=config"); PasswordPolicy p = DirectoryServer.getPasswordPolicy(dn); assertTrue(p.usesAuthPasswordSyntax()); PasswordPolicy p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertTrue(p.isAuthPasswordSyntax()); } @@ -2261,8 +2260,8 @@ throws Exception { PasswordPolicy p = DirectoryServer.getDefaultPasswordPolicy(); CopyOnWriteArrayList<PasswordStorageScheme<?>> defaultSchemes = p.getDefaultStorageSchemes(); List<PasswordStorageScheme<?>> defaultSchemes = p.getDefaultPasswordStorageSchemes(); assertNotNull(defaultSchemes); assertFalse(defaultSchemes.isEmpty()); @@ -2272,7 +2271,7 @@ "--set", "default-password-storage-scheme:Base64"); p = DirectoryServer.getDefaultPasswordPolicy(); defaultSchemes = p.getDefaultStorageSchemes(); defaultSchemes = p.getDefaultPasswordStorageSchemes(); assertNotNull(defaultSchemes); assertFalse(defaultSchemes.isEmpty()); @@ -2296,9 +2295,9 @@ { DN dn = DN.decode("cn=SHA1 AuthPassword Policy,cn=Password Policies," + "cn=config"); PasswordPolicy p = DirectoryServer.getPasswordPolicy(dn); CopyOnWriteArrayList<PasswordStorageScheme<?>> defaultSchemes = p.getDefaultStorageSchemes(); PasswordPolicy p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); List<PasswordStorageScheme<?>> defaultSchemes = p.getDefaultPasswordStorageSchemes(); assertNotNull(defaultSchemes); assertFalse(defaultSchemes.isEmpty()); @@ -2307,8 +2306,8 @@ "--policy-name", "SHA1 AuthPassword Policy", "--set", "default-password-storage-scheme:Salted MD5"); p = DirectoryServer.getPasswordPolicy(dn); defaultSchemes = p.getDefaultStorageSchemes(); p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); defaultSchemes = p.getDefaultPasswordStorageSchemes(); assertNotNull(defaultSchemes); assertFalse(defaultSchemes.isEmpty()); @@ -2331,8 +2330,8 @@ throws Exception { PasswordPolicy p = DirectoryServer.getDefaultPasswordPolicy(); assertTrue(p.isDefaultStorageScheme("SSHA")); assertFalse(p.isDefaultStorageScheme("CLEAR")); assertTrue(p.isDefaultPasswordStorageScheme("SSHA")); assertFalse(p.isDefaultPasswordStorageScheme("CLEAR")); TestCaseUtils.dsconfig( "set-password-policy-prop", @@ -2340,8 +2339,8 @@ "--set", "default-password-storage-scheme:BASE64"); p = DirectoryServer.getDefaultPasswordPolicy(); assertTrue(p.isDefaultStorageScheme("BASE64")); assertFalse(p.isDefaultStorageScheme("SSHA")); assertTrue(p.isDefaultPasswordStorageScheme("BASE64")); assertFalse(p.isDefaultPasswordStorageScheme("SSHA")); TestCaseUtils.dsconfig( "set-password-policy-prop", @@ -2363,18 +2362,18 @@ { DN dn = DN.decode("cn=SHA1 AuthPassword Policy,cn=Password Policies," + "cn=config"); PasswordPolicy p = DirectoryServer.getPasswordPolicy(dn); assertTrue(p.isDefaultStorageScheme("SHA1")); assertFalse(p.isDefaultStorageScheme("MD5")); PasswordPolicy p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertTrue(p.isDefaultPasswordStorageScheme("SHA1")); assertFalse(p.isDefaultPasswordStorageScheme("MD5")); TestCaseUtils.dsconfig( "set-password-policy-prop", "--policy-name", "SHA1 AuthPassword Policy", "--set", "default-password-storage-scheme:Salted MD5"); p = DirectoryServer.getPasswordPolicy(dn); assertTrue(p.isDefaultStorageScheme("MD5")); assertFalse(p.isDefaultStorageScheme("SHA1")); p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertTrue(p.isDefaultPasswordStorageScheme("MD5")); assertFalse(p.isDefaultPasswordStorageScheme("SHA1")); TestCaseUtils.dsconfig( "set-password-policy-prop", @@ -2395,8 +2394,8 @@ throws Exception { PasswordPolicy p = DirectoryServer.getDefaultPasswordPolicy(); CopyOnWriteArraySet<String> deprecatedSchemes = p.getDeprecatedStorageSchemes(); Set<String> deprecatedSchemes = p.getDeprecatedPasswordStorageSchemes(); assertNotNull(deprecatedSchemes); assertTrue(deprecatedSchemes.isEmpty()); @@ -2406,7 +2405,7 @@ "--set", "deprecated-password-storage-scheme:BASE64"); p = DirectoryServer.getDefaultPasswordPolicy(); deprecatedSchemes = p.getDeprecatedStorageSchemes(); deprecatedSchemes = p.getDeprecatedPasswordStorageSchemes(); assertNotNull(deprecatedSchemes); assertFalse(deprecatedSchemes.isEmpty()); @@ -2430,9 +2429,9 @@ { DN dn = DN.decode("cn=SHA1 AuthPassword Policy,cn=Password Policies," + "cn=config"); PasswordPolicy p = DirectoryServer.getPasswordPolicy(dn); CopyOnWriteArraySet<String> deprecatedSchemes = p.getDeprecatedStorageSchemes(); PasswordPolicy p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); Set<String> deprecatedSchemes = p.getDeprecatedPasswordStorageSchemes(); assertNotNull(deprecatedSchemes); assertTrue(deprecatedSchemes.isEmpty()); @@ -2441,8 +2440,8 @@ "--policy-name", "SHA1 AuthPassword Policy", "--set", "deprecated-password-storage-scheme:Salted MD5"); p = DirectoryServer.getPasswordPolicy(dn); deprecatedSchemes = p.getDeprecatedStorageSchemes(); p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); deprecatedSchemes = p.getDeprecatedPasswordStorageSchemes(); assertNotNull(deprecatedSchemes); assertFalse(deprecatedSchemes.isEmpty()); @@ -2465,7 +2464,7 @@ throws Exception { PasswordPolicy p = DirectoryServer.getDefaultPasswordPolicy(); assertFalse(p.isDeprecatedStorageScheme("BASE64")); assertFalse(p.isDeprecatedPasswordStorageScheme("BASE64")); TestCaseUtils.dsconfig( "set-password-policy-prop", @@ -2473,7 +2472,7 @@ "--set", "deprecated-password-storage-scheme:BASE64"); p = DirectoryServer.getDefaultPasswordPolicy(); assertTrue(p.isDeprecatedStorageScheme("BASE64")); assertTrue(p.isDeprecatedPasswordStorageScheme("BASE64")); TestCaseUtils.dsconfig( "set-password-policy-prop", @@ -2495,16 +2494,16 @@ { DN dn = DN.decode("cn=SHA1 AuthPassword Policy,cn=Password Policies," + "cn=config"); PasswordPolicy p = DirectoryServer.getPasswordPolicy(dn); assertFalse(p.isDeprecatedStorageScheme("MD5")); PasswordPolicy p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertFalse(p.isDeprecatedPasswordStorageScheme("MD5")); TestCaseUtils.dsconfig( "set-password-policy-prop", "--policy-name", "SHA1 AuthPassword Policy", "--set", "deprecated-password-storage-scheme:Salted MD5"); p = DirectoryServer.getPasswordPolicy(dn); assertTrue(p.isDeprecatedStorageScheme("MD5")); p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertTrue(p.isDeprecatedPasswordStorageScheme("MD5")); TestCaseUtils.dsconfig( "set-password-policy-prop", @@ -2557,7 +2556,7 @@ { DN dn = DN.decode("cn=SHA1 AuthPassword Policy,cn=Password Policies," + "cn=config"); PasswordPolicy p = DirectoryServer.getPasswordPolicy(dn); PasswordPolicy p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertNotNull(p.getPasswordValidators()); assertFalse(p.getPasswordValidators().isEmpty()); @@ -2566,7 +2565,7 @@ "--policy-name", "SHA1 AuthPassword Policy", "--add", "password-validator:Length-Based Password Validator"); p = DirectoryServer.getPasswordPolicy(dn); p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertNotNull(p.getPasswordValidators()); assertFalse(p.getPasswordValidators().isEmpty()); @@ -2621,7 +2620,7 @@ { DN dn = DN.decode("cn=SHA1 AuthPassword Policy,cn=Password Policies," + "cn=config"); PasswordPolicy p = DirectoryServer.getPasswordPolicy(dn); PasswordPolicy p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertNotNull(p.getAccountStatusNotificationHandlers()); assertTrue(p.getAccountStatusNotificationHandlers().isEmpty()); @@ -2630,7 +2629,7 @@ "--policy-name", "SHA1 AuthPassword Policy", "--add", "account-status-notification-handler:Error Log Handler"); p = DirectoryServer.getPasswordPolicy(dn); p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertNotNull(p.getAccountStatusNotificationHandlers()); assertFalse(p.getAccountStatusNotificationHandlers().isEmpty()); @@ -2653,7 +2652,7 @@ throws Exception { PasswordPolicy p = DirectoryServer.getDefaultPasswordPolicy(); assertTrue(p.allowUserPasswordChanges()); assertTrue(p.isAllowUserPasswordChanges()); TestCaseUtils.dsconfig( "set-password-policy-prop", @@ -2661,7 +2660,7 @@ "--set", "allow-user-password-changes:false"); p = DirectoryServer.getDefaultPasswordPolicy(); assertFalse(p.allowUserPasswordChanges()); assertFalse(p.isAllowUserPasswordChanges()); TestCaseUtils.dsconfig( "set-password-policy-prop", @@ -2683,16 +2682,16 @@ { DN dn = DN.decode("cn=SHA1 AuthPassword Policy,cn=Password Policies," + "cn=config"); PasswordPolicy p = DirectoryServer.getPasswordPolicy(dn); assertTrue(p.allowUserPasswordChanges()); PasswordPolicy p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertTrue(p.isAllowUserPasswordChanges()); TestCaseUtils.dsconfig( "set-password-policy-prop", "--policy-name", "SHA1 AuthPassword Policy", "--set", "allow-user-password-changes:false"); p = DirectoryServer.getPasswordPolicy(dn); assertFalse(p.allowUserPasswordChanges()); p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertFalse(p.isAllowUserPasswordChanges()); TestCaseUtils.dsconfig( "set-password-policy-prop", @@ -2713,7 +2712,7 @@ throws Exception { PasswordPolicy p = DirectoryServer.getDefaultPasswordPolicy(); assertFalse(p.requireCurrentPassword()); assertFalse(p.isPasswordChangeRequiresCurrentPassword()); TestCaseUtils.dsconfig( "set-password-policy-prop", @@ -2721,7 +2720,7 @@ "--set", "password-change-requires-current-password:true"); p = DirectoryServer.getDefaultPasswordPolicy(); assertTrue(p.requireCurrentPassword()); assertTrue(p.isPasswordChangeRequiresCurrentPassword()); TestCaseUtils.dsconfig( "set-password-policy-prop", @@ -2743,16 +2742,16 @@ { DN dn = DN.decode("cn=SHA1 AuthPassword Policy,cn=Password Policies," + "cn=config"); PasswordPolicy p = DirectoryServer.getPasswordPolicy(dn); assertFalse(p.requireCurrentPassword()); PasswordPolicy p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertFalse(p.isPasswordChangeRequiresCurrentPassword()); TestCaseUtils.dsconfig( "set-password-policy-prop", "--policy-name", "SHA1 AuthPassword Policy", "--set", "password-change-requires-current-password:true"); p = DirectoryServer.getPasswordPolicy(dn); assertTrue(p.allowUserPasswordChanges()); p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertTrue(p.isAllowUserPasswordChanges()); TestCaseUtils.dsconfig( "set-password-policy-prop", @@ -2773,7 +2772,7 @@ throws Exception { PasswordPolicy p = DirectoryServer.getDefaultPasswordPolicy(); assertFalse(p.forceChangeOnAdd()); assertFalse(p.isForceChangeOnAdd()); TestCaseUtils.dsconfig( "set-password-policy-prop", @@ -2781,7 +2780,7 @@ "--set", "force-change-on-add:true"); p = DirectoryServer.getDefaultPasswordPolicy(); assertTrue(p.forceChangeOnAdd()); assertTrue(p.isForceChangeOnAdd()); TestCaseUtils.dsconfig( "set-password-policy-prop", @@ -2803,16 +2802,16 @@ { DN dn = DN.decode("cn=SHA1 AuthPassword Policy,cn=Password Policies," + "cn=config"); PasswordPolicy p = DirectoryServer.getPasswordPolicy(dn); assertFalse(p.requireCurrentPassword()); PasswordPolicy p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertFalse(p.isPasswordChangeRequiresCurrentPassword()); TestCaseUtils.dsconfig( "set-password-policy-prop", "--policy-name", "SHA1 AuthPassword Policy", "--set", "force-change-on-add:true"); p = DirectoryServer.getPasswordPolicy(dn); assertTrue(p.forceChangeOnAdd()); p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertTrue(p.isForceChangeOnAdd()); TestCaseUtils.dsconfig( "set-password-policy-prop", @@ -2833,7 +2832,7 @@ throws Exception { PasswordPolicy p = DirectoryServer.getDefaultPasswordPolicy(); assertFalse(p.forceChangeOnReset()); assertFalse(p.isForceChangeOnReset()); TestCaseUtils.dsconfig( "set-password-policy-prop", @@ -2841,7 +2840,7 @@ "--set", "force-change-on-reset:true"); p = DirectoryServer.getDefaultPasswordPolicy(); assertTrue(p.forceChangeOnReset()); assertTrue(p.isForceChangeOnReset()); TestCaseUtils.dsconfig( "set-password-policy-prop", @@ -2863,16 +2862,16 @@ { DN dn = DN.decode("cn=SHA1 AuthPassword Policy,cn=Password Policies," + "cn=config"); PasswordPolicy p = DirectoryServer.getPasswordPolicy(dn); assertFalse(p.requireCurrentPassword()); PasswordPolicy p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertFalse(p.isPasswordChangeRequiresCurrentPassword()); TestCaseUtils.dsconfig( "set-password-policy-prop", "--policy-name", "SHA1 AuthPassword Policy", "--set", "force-change-on-reset:true"); p = DirectoryServer.getPasswordPolicy(dn); assertTrue(p.forceChangeOnReset()); p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertTrue(p.isForceChangeOnReset()); TestCaseUtils.dsconfig( "set-password-policy-prop", @@ -2893,7 +2892,7 @@ throws Exception { PasswordPolicy p = DirectoryServer.getDefaultPasswordPolicy(); assertFalse(p.skipValidationForAdministrators()); assertFalse(p.isSkipValidationForAdministrators()); TestCaseUtils.dsconfig( "set-password-policy-prop", @@ -2901,7 +2900,7 @@ "--set", "skip-validation-for-administrators:true"); p = DirectoryServer.getDefaultPasswordPolicy(); assertTrue(p.skipValidationForAdministrators()); assertTrue(p.isSkipValidationForAdministrators()); TestCaseUtils.dsconfig( "set-password-policy-prop", @@ -2923,16 +2922,16 @@ { DN dn = DN.decode("cn=SHA1 AuthPassword Policy,cn=Password Policies," + "cn=config"); PasswordPolicy p = DirectoryServer.getPasswordPolicy(dn); assertFalse(p.skipValidationForAdministrators()); PasswordPolicy p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertFalse(p.isSkipValidationForAdministrators()); TestCaseUtils.dsconfig( "set-password-policy-prop", "--policy-name", "SHA1 AuthPassword Policy", "--set", "skip-validation-for-administrators:true"); p = DirectoryServer.getPasswordPolicy(dn); assertTrue(p.skipValidationForAdministrators()); p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertTrue(p.isSkipValidationForAdministrators()); TestCaseUtils.dsconfig( "set-password-policy-prop", @@ -2983,7 +2982,7 @@ { DN dn = DN.decode("cn=SHA1 AuthPassword Policy,cn=Password Policies," + "cn=config"); PasswordPolicy p = DirectoryServer.getPasswordPolicy(dn); PasswordPolicy p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertNotNull(p.getPasswordGenerator()); TestCaseUtils.dsconfig( @@ -2991,7 +2990,7 @@ "--policy-name", "SHA1 AuthPassword Policy", "--remove", "password-generator:Random Password Generator"); p = DirectoryServer.getPasswordPolicy(dn); p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertNull(p.getPasswordGenerator()); TestCaseUtils.dsconfig( @@ -3043,7 +3042,7 @@ { DN dn = DN.decode("cn=SHA1 AuthPassword Policy,cn=Password Policies," + "cn=config"); PasswordPolicy p = DirectoryServer.getPasswordPolicy(dn); PasswordPolicy p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertNotNull(p.getPasswordGenerator()); TestCaseUtils.dsconfig( @@ -3051,7 +3050,7 @@ "--policy-name", "SHA1 AuthPassword Policy", "--remove", "password-generator:Random Password Generator"); p = DirectoryServer.getPasswordPolicy(dn); p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertNull(p.getPasswordGenerator()); TestCaseUtils.dsconfig( @@ -3073,7 +3072,7 @@ throws Exception { PasswordPolicy p = DirectoryServer.getDefaultPasswordPolicy(); assertFalse(p.requireSecureAuthentication()); assertFalse(p.isRequireSecureAuthentication()); TestCaseUtils.dsconfig( "set-password-policy-prop", @@ -3081,7 +3080,7 @@ "--set", "require-secure-authentication:true"); p = DirectoryServer.getDefaultPasswordPolicy(); assertTrue(p.requireSecureAuthentication()); assertTrue(p.isRequireSecureAuthentication()); TestCaseUtils.dsconfig( "set-password-policy-prop", @@ -3103,16 +3102,16 @@ { DN dn = DN.decode("cn=SHA1 AuthPassword Policy,cn=Password Policies," + "cn=config"); PasswordPolicy p = DirectoryServer.getPasswordPolicy(dn); assertFalse(p.requireSecureAuthentication()); PasswordPolicy p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertFalse(p.isRequireSecureAuthentication()); TestCaseUtils.dsconfig( "set-password-policy-prop", "--policy-name", "SHA1 AuthPassword Policy", "--set", "require-secure-authentication:true"); p = DirectoryServer.getPasswordPolicy(dn); assertTrue(p.requireSecureAuthentication()); p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertTrue(p.isRequireSecureAuthentication()); TestCaseUtils.dsconfig( "set-password-policy-prop", @@ -3133,7 +3132,7 @@ throws Exception { PasswordPolicy p = DirectoryServer.getDefaultPasswordPolicy(); assertFalse(p.requireSecurePasswordChanges()); assertFalse(p.isRequireSecurePasswordChanges()); TestCaseUtils.dsconfig( "set-password-policy-prop", @@ -3141,7 +3140,7 @@ "--set", "require-secure-password-changes:true"); p = DirectoryServer.getDefaultPasswordPolicy(); assertTrue(p.requireSecurePasswordChanges()); assertTrue(p.isRequireSecurePasswordChanges()); TestCaseUtils.dsconfig( "set-password-policy-prop", @@ -3163,16 +3162,16 @@ { DN dn = DN.decode("cn=SHA1 AuthPassword Policy,cn=Password Policies," + "cn=config"); PasswordPolicy p = DirectoryServer.getPasswordPolicy(dn); assertFalse(p.requireSecurePasswordChanges()); PasswordPolicy p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertFalse(p.isRequireSecurePasswordChanges()); TestCaseUtils.dsconfig( "set-password-policy-prop", "--policy-name", "SHA1 AuthPassword Policy", "--set", "require-secure-password-changes:true"); p = DirectoryServer.getPasswordPolicy(dn); assertTrue(p.requireSecurePasswordChanges()); p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertTrue(p.isRequireSecurePasswordChanges()); TestCaseUtils.dsconfig( "set-password-policy-prop", @@ -3193,7 +3192,7 @@ throws Exception { PasswordPolicy p = DirectoryServer.getDefaultPasswordPolicy(); assertFalse(p.allowMultiplePasswordValues()); assertFalse(p.isAllowMultiplePasswordValues()); TestCaseUtils.dsconfig( "set-password-policy-prop", @@ -3201,7 +3200,7 @@ "--set", "allow-multiple-password-values:true"); p = DirectoryServer.getDefaultPasswordPolicy(); assertTrue(p.allowMultiplePasswordValues()); assertTrue(p.isAllowMultiplePasswordValues()); TestCaseUtils.dsconfig( "set-password-policy-prop", @@ -3223,16 +3222,16 @@ { DN dn = DN.decode("cn=SHA1 AuthPassword Policy,cn=Password Policies," + "cn=config"); PasswordPolicy p = DirectoryServer.getPasswordPolicy(dn); assertFalse(p.allowMultiplePasswordValues()); PasswordPolicy p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertFalse(p.isAllowMultiplePasswordValues()); TestCaseUtils.dsconfig( "set-password-policy-prop", "--policy-name", "SHA1 AuthPassword Policy", "--set", "allow-multiple-password-values:true"); p = DirectoryServer.getPasswordPolicy(dn); assertTrue(p.allowMultiplePasswordValues()); p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertTrue(p.isAllowMultiplePasswordValues()); TestCaseUtils.dsconfig( "set-password-policy-prop", @@ -3253,7 +3252,7 @@ throws Exception { PasswordPolicy p = DirectoryServer.getDefaultPasswordPolicy(); assertFalse(p.allowPreEncodedPasswords()); assertFalse(p.isAllowPreEncodedPasswords()); TestCaseUtils.dsconfig( "set-password-policy-prop", @@ -3261,7 +3260,7 @@ "--set", "allow-pre-encoded-passwords:true"); p = DirectoryServer.getDefaultPasswordPolicy(); assertTrue(p.allowPreEncodedPasswords()); assertTrue(p.isAllowPreEncodedPasswords()); TestCaseUtils.dsconfig( "set-password-policy-prop", @@ -3283,16 +3282,16 @@ { DN dn = DN.decode("cn=SHA1 AuthPassword Policy,cn=Password Policies," + "cn=config"); PasswordPolicy p = DirectoryServer.getPasswordPolicy(dn); assertFalse(p.allowPreEncodedPasswords()); PasswordPolicy p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertFalse(p.isAllowPreEncodedPasswords()); TestCaseUtils.dsconfig( "set-password-policy-prop", "--policy-name", "SHA1 AuthPassword Policy", "--set", "allow-pre-encoded-passwords:true"); p = DirectoryServer.getPasswordPolicy(dn); assertTrue(p.allowPreEncodedPasswords()); p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertTrue(p.isAllowPreEncodedPasswords()); TestCaseUtils.dsconfig( "set-password-policy-prop", @@ -3313,7 +3312,7 @@ throws Exception { PasswordPolicy p = DirectoryServer.getDefaultPasswordPolicy(); assertEquals(p.getMinimumPasswordAge(), 0); assertEquals(p.getMinPasswordAge(), 0); TestCaseUtils.dsconfig( "set-password-policy-prop", @@ -3321,7 +3320,7 @@ "--set", "min-password-age:24 hours"); p = DirectoryServer.getDefaultPasswordPolicy(); assertEquals(p.getMinimumPasswordAge(), (24*60*60)); assertEquals(p.getMinPasswordAge(), (24*60*60)); TestCaseUtils.dsconfig( "set-password-policy-prop", @@ -3343,16 +3342,16 @@ { DN dn = DN.decode("cn=SHA1 AuthPassword Policy,cn=Password Policies," + "cn=config"); PasswordPolicy p = DirectoryServer.getPasswordPolicy(dn); assertEquals(p.getMinimumPasswordAge(), 0); PasswordPolicy p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertEquals(p.getMinPasswordAge(), 0); TestCaseUtils.dsconfig( "set-password-policy-prop", "--policy-name", "SHA1 AuthPassword Policy", "--set", "min-password-age:24 hours"); p = DirectoryServer.getPasswordPolicy(dn); assertEquals(p.getMinimumPasswordAge(), (24*60*60)); p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertEquals(p.getMinPasswordAge(), (24*60*60)); TestCaseUtils.dsconfig( "set-password-policy-prop", @@ -3373,7 +3372,7 @@ throws Exception { PasswordPolicy p = DirectoryServer.getDefaultPasswordPolicy(); assertEquals(p.getMaximumPasswordAge(), 0); assertEquals(p.getMaxPasswordAge(), 0); TestCaseUtils.dsconfig( "set-password-policy-prop", @@ -3381,7 +3380,7 @@ "--set", "max-password-age:90 days"); p = DirectoryServer.getDefaultPasswordPolicy(); assertEquals(p.getMaximumPasswordAge(), (90*60*60*24)); assertEquals(p.getMaxPasswordAge(), (90*60*60*24)); TestCaseUtils.dsconfig( "set-password-policy-prop", @@ -3403,16 +3402,16 @@ { DN dn = DN.decode("cn=SHA1 AuthPassword Policy,cn=Password Policies," + "cn=config"); PasswordPolicy p = DirectoryServer.getPasswordPolicy(dn); assertEquals(p.getMaximumPasswordAge(), 0); PasswordPolicy p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertEquals(p.getMaxPasswordAge(), 0); TestCaseUtils.dsconfig( "set-password-policy-prop", "--policy-name", "SHA1 AuthPassword Policy", "--set", "max-password-age:90 days"); p = DirectoryServer.getPasswordPolicy(dn); assertEquals(p.getMaximumPasswordAge(), (90*60*60*24)); p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertEquals(p.getMaxPasswordAge(), (90*60*60*24)); TestCaseUtils.dsconfig( "set-password-policy-prop", @@ -3433,7 +3432,7 @@ throws Exception { PasswordPolicy p = DirectoryServer.getDefaultPasswordPolicy(); assertEquals(p.getMaximumPasswordResetAge(), 0); assertEquals(p.getMaxPasswordResetAge(), 0); TestCaseUtils.dsconfig( "set-password-policy-prop", @@ -3441,7 +3440,7 @@ "--set", "max-password-reset-age:24 hours"); p = DirectoryServer.getDefaultPasswordPolicy(); assertEquals(p.getMaximumPasswordResetAge(), (24*60*60)); assertEquals(p.getMaxPasswordResetAge(), (24*60*60)); TestCaseUtils.dsconfig( "set-password-policy-prop", @@ -3463,16 +3462,16 @@ { DN dn = DN.decode("cn=SHA1 AuthPassword Policy,cn=Password Policies," + "cn=config"); PasswordPolicy p = DirectoryServer.getPasswordPolicy(dn); assertEquals(p.getMaximumPasswordResetAge(), 0); PasswordPolicy p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertEquals(p.getMaxPasswordResetAge(), 0); TestCaseUtils.dsconfig( "set-password-policy-prop", "--policy-name", "SHA1 AuthPassword Policy", "--set", "max-password-reset-age:24 hours"); p = DirectoryServer.getPasswordPolicy(dn); assertEquals(p.getMaximumPasswordResetAge(), (24*60*60)); p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertEquals(p.getMaxPasswordResetAge(), (24*60*60)); TestCaseUtils.dsconfig( "set-password-policy-prop", @@ -3493,7 +3492,7 @@ throws Exception { PasswordPolicy p = DirectoryServer.getDefaultPasswordPolicy(); assertEquals(p.getWarningInterval(), (5*60*60*24)); assertEquals(p.getPasswordExpirationWarningInterval(), (5*60*60*24)); TestCaseUtils.dsconfig( "set-password-policy-prop", @@ -3501,7 +3500,7 @@ "--set", "password-expiration-warning-interval:24 hours"); p = DirectoryServer.getDefaultPasswordPolicy(); assertEquals(p.getWarningInterval(), (24*60*60)); assertEquals(p.getPasswordExpirationWarningInterval(), (24*60*60)); TestCaseUtils.dsconfig( "set-password-policy-prop", @@ -3523,16 +3522,16 @@ { DN dn = DN.decode("cn=SHA1 AuthPassword Policy,cn=Password Policies," + "cn=config"); PasswordPolicy p = DirectoryServer.getPasswordPolicy(dn); assertEquals(p.getWarningInterval(), (5*60*60*24)); PasswordPolicy p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertEquals(p.getPasswordExpirationWarningInterval(), (5*60*60*24)); TestCaseUtils.dsconfig( "set-password-policy-prop", "--policy-name", "SHA1 AuthPassword Policy", "--set", "password-expiration-warning-interval:24 hours"); p = DirectoryServer.getPasswordPolicy(dn); assertEquals(p.getWarningInterval(), (24*60*60)); p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertEquals(p.getPasswordExpirationWarningInterval(), (24*60*60)); TestCaseUtils.dsconfig( "set-password-policy-prop", @@ -3553,7 +3552,7 @@ throws Exception { PasswordPolicy p = DirectoryServer.getDefaultPasswordPolicy(); assertFalse(p.expirePasswordsWithoutWarning()); assertFalse(p.isExpirePasswordsWithoutWarning()); TestCaseUtils.dsconfig( "set-password-policy-prop", @@ -3561,7 +3560,7 @@ "--set", "expire-passwords-without-warning:true"); p = DirectoryServer.getDefaultPasswordPolicy(); assertTrue(p.expirePasswordsWithoutWarning()); assertTrue(p.isExpirePasswordsWithoutWarning()); TestCaseUtils.dsconfig( "set-password-policy-prop", @@ -3583,16 +3582,16 @@ { DN dn = DN.decode("cn=SHA1 AuthPassword Policy,cn=Password Policies," + "cn=config"); PasswordPolicy p = DirectoryServer.getPasswordPolicy(dn); assertFalse(p.expirePasswordsWithoutWarning()); PasswordPolicy p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertFalse(p.isExpirePasswordsWithoutWarning()); TestCaseUtils.dsconfig( "set-password-policy-prop", "--policy-name", "SHA1 AuthPassword Policy", "--set", "expire-passwords-without-warning:true"); p = DirectoryServer.getPasswordPolicy(dn); assertTrue(p.expirePasswordsWithoutWarning()); p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertTrue(p.isExpirePasswordsWithoutWarning()); TestCaseUtils.dsconfig( "set-password-policy-prop", @@ -3613,7 +3612,7 @@ throws Exception { PasswordPolicy p = DirectoryServer.getDefaultPasswordPolicy(); assertFalse(p.allowExpiredPasswordChanges()); assertFalse(p.isAllowExpiredPasswordChanges()); TestCaseUtils.dsconfig( "set-password-policy-prop", @@ -3621,7 +3620,7 @@ "--set", "allow-expired-password-changes:true"); p = DirectoryServer.getDefaultPasswordPolicy(); assertTrue(p.allowExpiredPasswordChanges()); assertTrue(p.isAllowExpiredPasswordChanges()); TestCaseUtils.dsconfig( "set-password-policy-prop", @@ -3643,16 +3642,16 @@ { DN dn = DN.decode("cn=SHA1 AuthPassword Policy,cn=Password Policies," + "cn=config"); PasswordPolicy p = DirectoryServer.getPasswordPolicy(dn); assertFalse(p.allowExpiredPasswordChanges()); PasswordPolicy p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertFalse(p.isAllowExpiredPasswordChanges()); TestCaseUtils.dsconfig( "set-password-policy-prop", "--policy-name", "SHA1 AuthPassword Policy", "--set", "allow-expired-password-changes:true"); p = DirectoryServer.getPasswordPolicy(dn); assertTrue(p.allowExpiredPasswordChanges()); p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertTrue(p.isAllowExpiredPasswordChanges()); TestCaseUtils.dsconfig( "set-password-policy-prop", @@ -3703,7 +3702,7 @@ { DN dn = DN.decode("cn=SHA1 AuthPassword Policy,cn=Password Policies," + "cn=config"); PasswordPolicy p = DirectoryServer.getPasswordPolicy(dn); PasswordPolicy p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertEquals(p.getGraceLoginCount(), 0); TestCaseUtils.dsconfig( @@ -3711,7 +3710,7 @@ "--policy-name", "SHA1 AuthPassword Policy", "--set", "grace-login-count:3"); p = DirectoryServer.getPasswordPolicy(dn); p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertEquals(p.getGraceLoginCount(), 3); TestCaseUtils.dsconfig( @@ -3763,7 +3762,7 @@ { DN dn = DN.decode("cn=SHA1 AuthPassword Policy,cn=Password Policies," + "cn=config"); PasswordPolicy p = DirectoryServer.getPasswordPolicy(dn); PasswordPolicy p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertEquals(p.getLockoutFailureCount(), 0); TestCaseUtils.dsconfig( @@ -3771,7 +3770,7 @@ "--policy-name", "SHA1 AuthPassword Policy", "--set", "lockout-failure-count:3"); p = DirectoryServer.getPasswordPolicy(dn); p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertEquals(p.getLockoutFailureCount(), 3); TestCaseUtils.dsconfig( @@ -3823,7 +3822,7 @@ { DN dn = DN.decode("cn=SHA1 AuthPassword Policy,cn=Password Policies," + "cn=config"); PasswordPolicy p = DirectoryServer.getPasswordPolicy(dn); PasswordPolicy p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertEquals(p.getLockoutDuration(), 0); TestCaseUtils.dsconfig( @@ -3831,7 +3830,7 @@ "--policy-name", "SHA1 AuthPassword Policy", "--set", "lockout-duration:15 minutes"); p = DirectoryServer.getPasswordPolicy(dn); p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertEquals(p.getLockoutDuration(), (15*60)); TestCaseUtils.dsconfig( @@ -3883,7 +3882,7 @@ { DN dn = DN.decode("cn=SHA1 AuthPassword Policy,cn=Password Policies," + "cn=config"); PasswordPolicy p = DirectoryServer.getPasswordPolicy(dn); PasswordPolicy p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertEquals(p.getLockoutFailureExpirationInterval(), 0); TestCaseUtils.dsconfig( @@ -3891,7 +3890,7 @@ "--policy-name", "SHA1 AuthPassword Policy", "--set", "lockout-failure-expiration-interval:10 minutes"); p = DirectoryServer.getPasswordPolicy(dn); p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertEquals(p.getLockoutFailureExpirationInterval(), (10*60)); TestCaseUtils.dsconfig( @@ -3943,7 +3942,7 @@ { DN dn = DN.decode("cn=SHA1 AuthPassword Policy,cn=Password Policies," + "cn=config"); PasswordPolicy p = DirectoryServer.getPasswordPolicy(dn); PasswordPolicy p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertEquals(p.getRequireChangeByTime(), 0); TestCaseUtils.dsconfig( @@ -3951,7 +3950,7 @@ "--policy-name", "SHA1 AuthPassword Policy", "--set", "require-change-by-time:19700101000001Z"); p = DirectoryServer.getPasswordPolicy(dn); p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertEquals(p.getRequireChangeByTime(), 1000); TestCaseUtils.dsconfig( @@ -4003,7 +4002,7 @@ { DN dn = DN.decode("cn=SHA1 AuthPassword Policy,cn=Password Policies," + "cn=config"); PasswordPolicy p = DirectoryServer.getPasswordPolicy(dn); PasswordPolicy p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertNull(p.getLastLoginTimeAttribute()); TestCaseUtils.dsconfig( @@ -4011,7 +4010,7 @@ "--policy-name", "SHA1 AuthPassword Policy", "--set", "last-login-time-attribute:ds-pwp-last-login-time"); p = DirectoryServer.getPasswordPolicy(dn); p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertNotNull(p.getLastLoginTimeAttribute()); TestCaseUtils.dsconfig( @@ -4063,7 +4062,7 @@ { DN dn = DN.decode("cn=SHA1 AuthPassword Policy,cn=Password Policies," + "cn=config"); PasswordPolicy p = DirectoryServer.getPasswordPolicy(dn); PasswordPolicy p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertNull(p.getLastLoginTimeFormat()); TestCaseUtils.dsconfig( @@ -4071,7 +4070,7 @@ "--policy-name", "SHA1 AuthPassword Policy", "--set", "last-login-time-format:yyyyMMdd"); p = DirectoryServer.getPasswordPolicy(dn); p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertEquals(p.getLastLoginTimeFormat(), "yyyyMMdd"); TestCaseUtils.dsconfig( @@ -4125,7 +4124,7 @@ { DN dn = DN.decode("cn=SHA1 AuthPassword Policy,cn=Password Policies," + "cn=config"); PasswordPolicy p = DirectoryServer.getPasswordPolicy(dn); PasswordPolicy p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertNotNull(p.getPreviousLastLoginTimeFormats()); assertTrue(p.getPreviousLastLoginTimeFormats().isEmpty()); @@ -4134,7 +4133,7 @@ "--policy-name", "SHA1 AuthPassword Policy", "--set", "previous-last-login-time-format:yyyyMMdd"); p = DirectoryServer.getPasswordPolicy(dn); p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertNotNull(p.getPreviousLastLoginTimeFormats()); assertFalse(p.getPreviousLastLoginTimeFormats().isEmpty()); @@ -4187,7 +4186,7 @@ { DN dn = DN.decode("cn=SHA1 AuthPassword Policy,cn=Password Policies," + "cn=config"); PasswordPolicy p = DirectoryServer.getPasswordPolicy(dn); PasswordPolicy p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertEquals(p.getIdleLockoutInterval(), 0); TestCaseUtils.dsconfig( @@ -4195,7 +4194,7 @@ "--policy-name", "SHA1 AuthPassword Policy", "--set", "idle-lockout-interval:90 days"); p = DirectoryServer.getPasswordPolicy(dn); p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertEquals(p.getIdleLockoutInterval(), (90*60*60*24)); TestCaseUtils.dsconfig( @@ -4674,10 +4673,6 @@ { PasswordPolicy p = DirectoryServer.getDefaultPasswordPolicy(); assertNotNull(p.toString()); StringBuilder buffer = new StringBuilder(); p.toString(buffer); assertFalse(buffer.length() == 0); } @@ -4694,12 +4689,8 @@ { DN dn = DN.decode("cn=SHA1 AuthPassword Policy,cn=Password Policies," + "cn=config"); PasswordPolicy p = DirectoryServer.getPasswordPolicy(dn); PasswordPolicy p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertNotNull(p.toString()); StringBuilder buffer = new StringBuilder(); p.toString(buffer); assertFalse(buffer.length() == 0); } } opends/tests/unit-tests-testng/src/server/org/opends/server/core/SubentryPasswordPolicyTestCase.java
@@ -23,6 +23,7 @@ * * * Copyright 2010 Sun Microsystems, Inc. * Portions copyright 2011 ForgeRock AS. */ package org.opends.server.core; @@ -275,26 +276,26 @@ assertEquals(addOperation.getResultCode(), ResultCode.SUCCESS); assertNotNull(DirectoryServer.getEntry(policyEntry.getDN())); PasswordPolicy policy = DirectoryServer.getPasswordPolicy( PasswordPolicy policy = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy( DN.decode("cn=Temp Policy," + SUFFIX)); assertNotNull(policy); // Check all pwp attributes for correct values. assertEquals(policy.getLockoutDuration(), 300); assertEquals(policy.getLockoutFailureCount(), 3); assertEquals(policy.forceChangeOnReset(), true); assertEquals(policy.isForceChangeOnReset(), true); assertTrue(policy.getPasswordAttribute( ).getPrimaryName().equalsIgnoreCase( "authPassword")); assertEquals(policy.getMinimumPasswordAge(), 600); assertEquals(policy.getMaximumPasswordAge(), 2147483647); assertEquals(policy.getMinPasswordAge(), 600); assertEquals(policy.getMaxPasswordAge(), 2147483647); assertEquals(policy.getPasswordHistoryCount(), 5); assertEquals(policy.getWarningInterval(), 864000); assertEquals(policy.getPasswordExpirationWarningInterval(), 864000); assertEquals(policy.getGraceLoginCount(), 3); assertEquals(policy.getLockoutFailureExpirationInterval(), 3600); assertEquals(policy.allowUserPasswordChanges(), false); assertEquals(policy.requireCurrentPassword(), true); assertEquals(policy.isAllowUserPasswordChanges(), false); assertEquals(policy.isPasswordChangeRequiresCurrentPassword(), true); // Make sure this policy applies to the test entry // its supposed to target and that its the same @@ -347,7 +348,7 @@ assertTrue(testEntry.hasAttribute(attrType)); assertTrue(testEntry.hasValue(attrType, null, AttributeValues.create(attrType, defaultPolicy.getConfigEntryDN( defaultPolicy.getDN( ).toString()))); // Add new subentry policy with the @@ -397,7 +398,7 @@ assertTrue(testEntry.hasAttribute(attrType)); assertTrue(testEntry.hasValue(attrType, null, AttributeValues.create(attrType, defaultPolicy.getConfigEntryDN( defaultPolicy.getDN( ).toString()))); } } opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/CryptPasswordStorageSchemeTestCase.java
@@ -23,7 +23,7 @@ * * * Copyright 2008 Sun Microsystems, Inc. * Portions Copyright 2010 ForgeRock AS * Portions Copyright 2010-2011 ForgeRock AS. */ package org.opends.server.extensions; @@ -433,8 +433,8 @@ boolean previousValue = false; try { DN dn = DN.decode("cn=Default Password Policy,cn=Password Policies,cn=config"); PasswordPolicy p = DirectoryServer.getPasswordPolicy(dn); previousValue = p.allowPreEncodedPasswords(); PasswordPolicy p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); previousValue = p.isAllowPreEncodedPasswords(); String attr = "ds-cfg-allow-pre-encoded-passwords"; @@ -447,8 +447,8 @@ ModifyOperation modifyOperation = conn.processModify(dn, mods); assertEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS); p = DirectoryServer.getPasswordPolicy(dn); assertEquals(p.allowPreEncodedPasswords(), allowPreencoded); p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertEquals(p.isAllowPreEncodedPasswords(), allowPreencoded); } catch (Exception e) { System.err.println("Failed to set ds-cfg-allow-pre-encoded-passwords " + " to " + allowPreencoded); opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/ErrorLogAccountStatusNotificationHandlerTestCase.java
@@ -23,6 +23,7 @@ * * * Copyright 2006-2008 Sun Microsystems, Inc. * Portions copyright 2011 ForgeRock AS. */ package org.opends.server.extensions; @@ -265,7 +266,7 @@ new HashMap<AccountStatusNotificationProperty,List<String>>(); ArrayList<String> propList = new ArrayList<String>(1); propList.add(policy.getConfigEntryDN().toString()); propList.add(policy.getDN().toString()); notificationProperties.put(PASSWORD_POLICY_DN, propList); opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/PasswordStorageSchemeTestCase.java
@@ -23,7 +23,7 @@ * * * Copyright 2006-2008 Sun Microsystems, Inc. * Portions Copyright 2010 ForgeRock AS. * Portions Copyright 2010-2011 ForgeRock AS. */ package org.opends.server.extensions; @@ -97,7 +97,7 @@ throws Exception { TestCaseUtils.startServer(); if (configDNString != null) { configEntry = DirectoryServer.getConfigEntry(DN.decode(configDNString)); @@ -310,8 +310,8 @@ boolean previousValue = false; try { DN dn = DN.decode("cn=Default Password Policy,cn=Password Policies,cn=config"); PasswordPolicy p = DirectoryServer.getPasswordPolicy(dn); previousValue = p.allowPreEncodedPasswords(); PasswordPolicy p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); previousValue = p.isAllowPreEncodedPasswords(); String attr = "ds-cfg-allow-pre-encoded-passwords"; @@ -324,8 +324,8 @@ ModifyOperation modifyOperation = conn.processModify(dn, mods); assertEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS); p = DirectoryServer.getPasswordPolicy(dn); assertEquals(p.allowPreEncodedPasswords(), allowPreencoded); p = (PasswordPolicy) DirectoryServer.getAuthenticationPolicy(dn); assertEquals(p.isAllowPreEncodedPasswords(), allowPreencoded); } catch (Exception e) { System.err.println("Failed to set ds-cfg-allow-pre-encoded-passwords " + " to " + allowPreencoded); opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/SASLOverTLSTestCase.java
@@ -23,6 +23,7 @@ * * * Copyright 2009 Sun Microsystems, Inc. * Portions copyright 2011 ForgeRock AS. */ package org.opends.server.extensions; @@ -100,6 +101,7 @@ TestCaseUtils.startServer(); TestCaseUtils.dsconfig( "create-password-policy", "--type", "password-policy", "--policy-name", pwdPolicy, "--set", "password-attribute:userPassword", "--set", "default-password-storage-scheme: Clear"