opends/src/admin/defn/org/opends/server/admin/std/PasswordPolicyConfiguration.xml
New file @@ -0,0 +1,919 @@ <?xml version="1.0" encoding="UTF-8"?> <adm:managed-object name="password-policy" plural-name="password-policys" package="org.opends.server.admin.std" xmlns:adm="http://www.opends.org/admin" xmlns:ldap="http://www.opends.org/admin-ldap"> <adm:synopsis> Define a number of password management rules, as well as requirements for authentication processing. </adm:synopsis> <adm:profile name="ldap"> <ldap:object-class> <ldap:oid>1.3.6.1.4.1.26027.1.2.62</ldap:oid> <ldap:name>ds-cfg-password-policy</ldap:name> <ldap:superior>top</ldap:superior> </ldap:object-class> </adm:profile> <adm:property name="password-attribute" mandatory="true" multi-valued="false"> <adm:synopsis> Specifies the attribute type used to hold user passwords. </adm:synopsis> <adm:description> Specifies the attribute type used to hold user passwords. This attribute type must be defined in the server schema. Changes to this configuration attribute will take effect immediately. </adm:description> <adm:syntax> <adm:oid /> </adm:syntax> <adm:profile name="ldap"> <ldap:attribute> <ldap:oid>1.3.6.1.4.1.26027.1.1.192</ldap:oid> <ldap:name>ds-cfg-password-attribute</ldap:name> </ldap:attribute> </adm:profile> </adm:property> <adm:property name="default-password-storage-scheme" mandatory="true" multi-valued="true"> <adm:synopsis> Specifies the password storage scheme (or set of schemes) that will be used to encode clear-text passwords. </adm:synopsis> <adm:description> Specifies the password storage scheme (or set of schemes) that will be used to encode clear-text passwords. If multiple default storage schemes are defined for a password policy, then the same password will be encoded using all of those schemes. Changes to this configuration attribute will take effect immediately. </adm:description> <adm:syntax> <adm:string /> </adm:syntax> <adm:profile name="ldap"> <ldap:attribute> <ldap:oid>1.3.6.1.4.1.26027.1.1.178</ldap:oid> <ldap:name>ds-cfg-default-password-storage-scheme</ldap:name> </ldap:attribute> </adm:profile> </adm:property> <adm:property name="deprecated-password-storage-scheme" mandatory="false" multi-valued="true"> <adm:synopsis> Specifies the password storage scheme (or set of schemes) that should be considered deprecated. </adm:synopsis> <adm:description> Specifies the password storage scheme (or set of schemes) that should be considered deprecated. If an authenticating user has a password encoded with one of these schemes, those passwords will be removed and replaced with passwords encoded using the default schemes. Changes to this configuration attribute will take effect immediately. </adm:description> <adm:default-behavior> <adm:undefined /> </adm:default-behavior> <adm:syntax> <adm:string /> </adm:syntax> <adm:profile name="ldap"> <ldap:attribute> <ldap:oid>1.3.6.1.4.1.26027.1.1.179</ldap:oid> <ldap:name>ds-cfg-deprecated-password-storage-scheme</ldap:name> </ldap:attribute> </adm:profile> </adm:property> <adm:property name="password-validator-dn" mandatory="false" multi-valued="true"> <adm:synopsis> Specifies the DN(s) of the password validator(s) that should be used with the associated password storage scheme. </adm:synopsis> <adm:description> Specifies the DN(s) of the password validator(s) that should be used with the associated password storage scheme. Changes to this configuration attribute will take effect immediately. </adm:description> <adm:default-behavior> <adm:undefined /> </adm:default-behavior> <adm:syntax> <adm:dn /> </adm:syntax> <adm:profile name="ldap"> <ldap:attribute> <ldap:oid>1.3.6.1.4.1.26027.1.1.195</ldap:oid> <ldap:name>ds-cfg-password-validator-dn</ldap:name> </ldap:attribute> </adm:profile> </adm:property> <adm:property name="account-status-notification-handler-dn" mandatory="false" multi-valued="true"> <adm:synopsis> Specifies the DN(s) of the account status notification handler(s) that should be used with the associated password storage scheme. </adm:synopsis> <adm:description> Specifies the DN(s) of the account status notification handler(s) that should be used with the associated password storage scheme. Changes to this configuration attribute will take effect immediately. </adm:description> <adm:default-behavior> <adm:undefined /> </adm:default-behavior> <adm:syntax> <adm:dn /> </adm:syntax> <adm:profile name="ldap"> <ldap:attribute> <ldap:oid>1.3.6.1.4.1.26027.1.1.174</ldap:oid> <ldap:name> ds-cfg-account-status-notification-handler-dn </ldap:name> </ldap:attribute> </adm:profile> </adm:property> <adm:property name="allow-user-password-changes" mandatory="false" multi-valued="false"> <adm:synopsis> Indicates whether users will be allowed to change their own passwords. </adm:synopsis> <adm:description> Indicates whether users will be allowed to change their own passwords. This check is made in addition to access control evaluation, and therefore both must allow the password change for it to occur. Changes to this configuration attribute will take effect immediately. </adm:description> <adm:default-behavior> <adm:defined> <adm:value>true</adm:value> </adm:defined> </adm:default-behavior> <adm:syntax> <adm:boolean /> </adm:syntax> <adm:profile name="ldap"> <ldap:attribute> <ldap:oid>1.3.6.1.4.1.26027.1.1.177</ldap:oid> <ldap:name>ds-cfg-allow-user-password-changes</ldap:name> </ldap:attribute> </adm:profile> </adm:property> <adm:property name="password-change-requires-current-password" mandatory="false" multi-valued="false"> <adm:synopsis> Indicates whether user password changes will be required to use the password modify extended operation and include the user's current password before the change will be allowed. </adm:synopsis> <adm:description> Indicates whether user password changes will be required to use the password modify extended operation and include the user's current password before the change will be allowed. Changes to this configuration attribute will take effect immediately. </adm:description> <adm:default-behavior> <adm:defined> <adm:value>false</adm:value> </adm:defined> </adm:default-behavior> <adm:syntax> <adm:boolean /> </adm:syntax> <adm:profile name="ldap"> <ldap:attribute> <ldap:oid>1.3.6.1.4.1.26027.1.1.198</ldap:oid> <ldap:name> ds-cfg-password-change-requires-current-password </ldap:name> </ldap:attribute> </adm:profile> </adm:property> <adm:property name="force-change-on-add" mandatory="false" multi-valued="false"> <adm:synopsis> Indicates whether users will be forced to change their passwords upon first authenticating to the Directory Server after their account has been created. </adm:synopsis> <adm:description> Indicates whether users will be forced to change their passwords upon first authenticating to the Directory Server after their account has been created. Changes to this configuration attribute will take effect immediately. </adm:description> <adm:default-behavior> <adm:defined> <adm:value>false</adm:value> </adm:defined> </adm:default-behavior> <adm:syntax> <adm:boolean /> </adm:syntax> <adm:profile name="ldap"> <ldap:attribute> <ldap:oid>1.3.6.1.4.1.26027.1.1.208</ldap:oid> <ldap:name>ds-cfg-force-change-on-add</ldap:name> </ldap:attribute> </adm:profile> </adm:property> <adm:property name="force-change-on-reset" mandatory="false" multi-valued="false"> <adm:synopsis> Indicates whether users will be forced to change their passwords if they are reset by an administrator. </adm:synopsis> <adm:description> Indicates whether users will be forced to change their passwords if they are reset by an administrator. For this purpose, anyone with permission to change a given user's password other than that user will be considered an administrator. Changes to this configuration attribute will take effect immediately. </adm:description> <adm:default-behavior> <adm:defined> <adm:value>false</adm:value> </adm:defined> </adm:default-behavior> <adm:syntax> <adm:boolean /> </adm:syntax> <adm:profile name="ldap"> <ldap:attribute> <ldap:oid>1.3.6.1.4.1.26027.1.1.181</ldap:oid> <ldap:name>ds-cfg-force-change-on-reset</ldap:name> </ldap:attribute> </adm:profile> </adm:property> <adm:property name="skip-validation-for-administrators" mandatory="false" multi-valued="false"> <adm:synopsis> Indicates whether passwords set by administrators will be allowed to bypass the password validation process that will be required for user password changes. </adm:synopsis> <adm:description> Indicates whether passwords set by administrators (in add, modify, or password modify operations) will be allowed to bypass the password validation process that will be required for user password changes. Changes to this configuration attribute will take effect immediately. </adm:description> <adm:default-behavior> <adm:defined> <adm:value>false</adm:value> </adm:defined> </adm:default-behavior> <adm:syntax> <adm:boolean /> </adm:syntax> <adm:profile name="ldap"> <ldap:attribute> <ldap:oid>1.3.6.1.4.1.26027.1.1.201</ldap:oid> <ldap:name>ds-cfg-skip-validation-for-administrators</ldap:name> </ldap:attribute> </adm:profile> </adm:property> <adm:property name="password-generator-dn" mandatory="false" multi-valued="false"> <adm:synopsis> Specifies the DN of the configuration entry that references the password generator for use with the associated password policy. </adm:synopsis> <adm:description> Specifies the DN of the configuration entry that references the password generator for use with the associated password policy. This will be used in conjunction with the password modify extended operation to generate a new password for a user when none was provided in the request. Changes to this configuration attribute will take effect immediately. </adm:description> <adm:default-behavior> <adm:undefined /> </adm:default-behavior> <adm:syntax> <adm:dn /> </adm:syntax> <adm:profile name="ldap"> <ldap:attribute> <ldap:oid>1.3.6.1.4.1.26027.1.1.194</ldap:oid> <ldap:name>ds-cfg-password-generator-dn</ldap:name> </ldap:attribute> </adm:profile> </adm:property> <adm:property name="require-secure-authentication" mandatory="false" multi-valued="false"> <adm:synopsis> Indicates whether users with the associated password policy will be required to authenticate in a secure manner. </adm:synopsis> <adm:description> Indicates whether users with the associated password policy will be required to authenticate in a secure manner. This could mean either using a secure communication channel between the client and the server, or using a SASL mechanism that does not expose the credentials. Changes to this configuration attribute will take effect immediately. </adm:description> <adm:default-behavior> <adm:defined> <adm:value>false</adm:value> </adm:defined> </adm:default-behavior> <adm:syntax> <adm:boolean /> </adm:syntax> <adm:profile name="ldap"> <ldap:attribute> <ldap:oid>1.3.6.1.4.1.26027.1.1.199</ldap:oid> <ldap:name>ds-cfg-require-secure-authentication</ldap:name> </ldap:attribute> </adm:profile> </adm:property> <adm:property name="require-secure-password-changes" mandatory="false" multi-valued="false"> <adm:synopsis> Indicates whether users with the associated password policy will be required to change their password in a secure manner that does not expose the credentials. </adm:synopsis> <adm:description> Indicates whether users with the associated password policy will be required to change their password in a secure manner that does not expose the credentials. Changes to this configuration attribute will take effect immediately. </adm:description> <adm:default-behavior> <adm:defined> <adm:value>false</adm:value> </adm:defined> </adm:default-behavior> <adm:syntax> <adm:boolean /> </adm:syntax> <adm:profile name="ldap"> <ldap:attribute> <ldap:oid>1.3.6.1.4.1.26027.1.1.200</ldap:oid> <ldap:name>ds-cfg-require-secure-password-changes</ldap:name> </ldap:attribute> </adm:profile> </adm:property> <adm:property name="allow-multiple-password-values" mandatory="false" multi-valued="false"> <adm:synopsis> Indicates whether user entries will be allowed to have multiple distinct values for the password attribute. </adm:synopsis> <adm:description> Indicates whether user entries will be allowed to have multiple distinct values for the password attribute. 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 may be used to authenticate, and they will all be subject to the same policy constraints. Changes to this configuration attribute will take effect immediately. </adm:description> <adm:default-behavior> <adm:defined> <adm:value>false</adm:value> </adm:defined> </adm:default-behavior> <adm:syntax> <adm:boolean /> </adm:syntax> <adm:profile name="ldap"> <ldap:attribute> <ldap:oid>1.3.6.1.4.1.26027.1.1.209</ldap:oid> <ldap:name>ds-cfg-allow-multiple-password-values</ldap:name> </ldap:attribute> </adm:profile> </adm:property> <adm:property name="allow-pre-encoded-passwords" mandatory="false" multi-valued="false"> <adm:synopsis> _Indicates whether users will be allowed to change their passwords by providing a pre-encoded value. </adm:synopsis> <adm:description> Indicates whether users will be allowed to change their passwords by providing a pre-encoded value. 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. Changes to this configuration attribute will take effect immediately. </adm:description> <adm:default-behavior> <adm:defined> <adm:value>false</adm:value> </adm:defined> </adm:default-behavior> <adm:syntax> <adm:boolean /> </adm:syntax> <adm:profile name="ldap"> <ldap:attribute> <ldap:oid>1.3.6.1.4.1.26027.1.1.176</ldap:oid> <ldap:name>ds-cfg-allow-pre-encoded-passwords</ldap:name> </ldap:attribute> </adm:profile> </adm:property> <adm:property name="minimum-password-age" mandatory="false" multi-valued="false"> <adm:synopsis> Specifies the minimum length of time that must pass after a password change before the user will be allowed to change the password again. </adm:synopsis> <adm:description> Specifies the minimum length of time that must pass after a password change before the user will be allowed to change the password again. The value of this attribute should be 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 and old password from the history so that it may be re-used. Changes to this configuration attribute will take effect immediately. </adm:description> <adm:default-behavior> <adm:defined> <adm:value>0 seconds</adm:value> </adm:defined> </adm:default-behavior> <adm:syntax> <adm:duration /> </adm:syntax> <adm:profile name="ldap"> <ldap:attribute> <ldap:oid>1.3.6.1.4.1.26027.1.1.191</ldap:oid> <ldap:name>ds-cfg-minimum-password-age</ldap:name> </ldap:attribute> </adm:profile> </adm:property> <adm:property name="maximum-password-age" mandatory="false" multi-valued="false"> <adm:synopsis> Specifies the maximum length of time that a user may continue using the same password before it must be changed. </adm:synopsis> <adm:description> Specifies the maximum length of time that a user may continue using the same password before it must be changed (i.e., the password expiration interval). The value of this attribute should be an integer followed by a unit of seconds, minutes, hours, days, or weeks. A value of 0 seconds will disable password expiration. Changes to this configuration attribute will take effect immediately. </adm:description> <adm:default-behavior> <adm:defined> <adm:value>0 seconds</adm:value> </adm:defined> </adm:default-behavior> <adm:syntax> <adm:duration /> </adm:syntax> <adm:profile name="ldap"> <ldap:attribute> <ldap:oid>1.3.6.1.4.1.26027.1.1.189</ldap:oid> <ldap:name>ds-cfg-maximum-password-age</ldap:name> </ldap:attribute> </adm:profile> </adm:property> <adm:property name="maximum-password-reset-age" mandatory="false" multi-valued="false"> <adm:synopsis> Specifies the maximum length of time that users have to change passwords after they have been reset by an administrator before they become locked. </adm:synopsis> <adm:description> Specifies the maximum length of time that users have to change passwords after they have been reset by an administrator before they become locked. The value of this attribute should be an integer followed by a unit of seconds, minutes, hours, days, or weeks. A value of 0 seconds will disable this feature. Changes to this configuration attribute will take effect immediately. </adm:description> <adm:default-behavior> <adm:defined> <adm:value>0 seconds</adm:value> </adm:defined> </adm:default-behavior> <adm:syntax> <adm:duration /> </adm:syntax> <adm:profile name="ldap"> <ldap:attribute> <ldap:oid>1.3.6.1.4.1.26027.1.1.190</ldap:oid> <ldap:name>ds-cfg-maximum-password-reset-age</ldap:name> </ldap:attribute> </adm:profile> </adm:property> <adm:property name="password-expiration-warning-interval" mandatory="false" multi-valued="false"> <adm:synopsis> Specifies the maximum length of time before a user's password actually expires that the server will begin to include warning notifications in bind responses for that user. </adm:synopsis> <adm:description> Specifies the maximum length of time before a user's password actually expires that the server will begin to include warning notifications in bind responses for that user. The value of this attribute should be an integer followed by a unit of seconds, minutes, hours, days, or weeks. A value of 0 seconds will disable the warning interval. Changes to this configuration attribute will take effect immediately. </adm:description> <adm:default-behavior> <adm:defined> <adm:value>5 days</adm:value> </adm:defined> </adm:default-behavior> <adm:syntax> <adm:duration /> </adm:syntax> <adm:profile name="ldap"> <ldap:attribute> <ldap:oid>1.3.6.1.4.1.26027.1.1.193</ldap:oid> <ldap:name> ds-cfg-password-expiration-warning-interval </ldap:name> </ldap:attribute> </adm:profile> </adm:property> <adm:property name="expire-passwords-without-warning" mandatory="false" multi-valued="false"> <adm:synopsis> Indicates whether the Directory Server should allow a user's password to expire even if that user has never seen an expiration warning notification. </adm:synopsis> <adm:description> Indicates whether the Directory Server should allow a user's password to expire even if that user has never seen an expiration warning notification. If this setting is enabled, then accounts will always be expired when the expiration time arrives. If it is disabled, then the user will always receive at least one warning notification, and the password expiration will be set to the warning time plus the warning interval. Changes to this configuration attribute will take effect immediately. </adm:description> <adm:default-behavior> <adm:defined> <adm:value>false</adm:value> </adm:defined> </adm:default-behavior> <adm:syntax> <adm:boolean /> </adm:syntax> <adm:profile name="ldap"> <ldap:attribute> <ldap:oid>1.3.6.1.4.1.26027.1.1.180</ldap:oid> <ldap:name>ds-cfg-expire-passwords-without-warning</ldap:name> </ldap:attribute> </adm:profile> </adm:property> <adm:property name="allow-expired-password-changes" mandatory="false" multi-valued="false"> <adm:synopsis> Indicates whether a user whose password is expired will still be allowed to change that password using the password modify extended operation. </adm:synopsis> <adm:description> Indicates whether a user whose password is expired will still be allowed to change that password using the password modify extended operation. Changes to this configuration attribute will take effect immediately. </adm:description> <adm:default-behavior> <adm:defined> <adm:value>false</adm:value> </adm:defined> </adm:default-behavior> <adm:syntax> <adm:boolean /> </adm:syntax> <adm:profile name="ldap"> <ldap:attribute> <ldap:oid>1.3.6.1.4.1.26027.1.1.175</ldap:oid> <ldap:name>ds-cfg-allow-expired-password-changes</ldap:name> </ldap:attribute> </adm:profile> </adm:property> <adm:property name="grace-login-count" mandatory="false" multi-valued="false"> <adm:synopsis> Specifies the number of grace logins that a user will be allowed after the account has expired to allow that user to choose a new password. </adm:synopsis> <adm:description> Specifies the number of grace logins that a user will be allowed after the account has expired to allow that user to choose a new password. A value of 0 indicates that no grace logins will be allowed. Changes to this configuration attribute will take effect immediately. </adm:description> <adm:default-behavior> <adm:defined> <adm:value>0</adm:value> </adm:defined> </adm:default-behavior> <adm:syntax> <adm:integer lower-limit="0" upper-limit="2147483647" /> </adm:syntax> <adm:profile name="ldap"> <ldap:attribute> <ldap:oid>1.3.6.1.4.1.26027.1.1.182</ldap:oid> <ldap:name>ds-cfg-grace-login-count</ldap:name> </ldap:attribute> </adm:profile> </adm:property> <adm:property name="lockout-failure-count" mandatory="false" multi-valued="false"> <adm:synopsis> Specifies the maximum number of authentication failures that a user should be allowed before the account is locked out. </adm:synopsis> <adm:description> Specifies the maximum number of authentication failures that a user should be allowed before the account is locked out. A value of 0 indicates that accounts should never be locked out due to failed attempts. changes to this configuration attribute will take effect immediately. </adm:description> <adm:default-behavior> <adm:defined> <adm:value>0</adm:value> </adm:defined> </adm:default-behavior> <adm:syntax> <adm:integer lower-limit="0" upper-limit="2147483647" /> </adm:syntax> <adm:profile name="ldap"> <ldap:attribute> <ldap:oid>1.3.6.1.4.1.26027.1.1.187</ldap:oid> <ldap:name>ds-cfg-lockout-failure-count</ldap:name> </ldap:attribute> </adm:profile> </adm:property> <adm:property name="lockout-duration" mandatory="false" multi-valued="false"> <adm:synopsis> Specifies the length of time that an account should be locked after too many authentication failures. </adm:synopsis> <adm:description> Specifies the length of time that an account should be locked after too many authentication failures. The value of this attribute should be an integer followed by a unit of seconds, minutes, hours, days, or weeks. A value of 0 seconds indicates that the account should remain locked until an administrator resets the password. Changes to this configuration attribute will take effect immediately. </adm:description> <adm:default-behavior> <adm:defined> <adm:value>0 seconds</adm:value> </adm:defined> </adm:default-behavior> <adm:syntax> <adm:duration /> </adm:syntax> <adm:profile name="ldap"> <ldap:attribute> <ldap:oid>1.3.6.1.4.1.26027.1.1.186</ldap:oid> <ldap:name>ds-cfg-lockout-duration</ldap:name> </ldap:attribute> </adm:profile> </adm:property> <adm:property name="lockout-failure-expiration-interval" mandatory="false" multi-valued="false"> <adm:synopsis> pecifies the length of time that should pass before an authentication failure is no longer counted against a user for the purposes of account lockout. </adm:synopsis> <adm:description> Specifies the length of time that should pass before an authentication failure is no longer counted against a user for the purposes of account lockout. The value of this attribute should be an integer followed by a unit of seconds, minutes, hours, days, or weeks. A value of 0 seconds indicates that the authentication failures should never expire. The failure count will always be cleared upon a successful authentication. Changes to this configuration attribute will take effect immediately. </adm:description> <adm:default-behavior> <adm:defined> <adm:value>0 seconds</adm:value> </adm:defined> </adm:default-behavior> <adm:syntax> <adm:duration /> </adm:syntax> <adm:profile name="ldap"> <ldap:attribute> <ldap:oid>1.3.6.1.4.1.26027.1.1.188</ldap:oid> <ldap:name> ds-cfg-lockout-failure-expiration-interval </ldap:name> </ldap:attribute> </adm:profile> </adm:property> <adm:property name="require-change-by-time" mandatory="false" multi-valued="false"> <adm:synopsis> Specifies the time by which all users with the associated password policy must change their passwords. </adm:synopsis> <adm:description> Specifies the time by which all users with the associated password policy must change their passwords. The value should be expressed in a generalized time format. If this time is equal to the current time or is in the past, then all users will be required to change their passwords immediately. The behavior of the server in this mode will be identical to the behavior observed when users are forced to change their passwords after an administrative reset. Changes to this configuration attribute will take effect immediately. </adm:description> <adm:default-behavior> <adm:undefined /> </adm:default-behavior> <adm:syntax> <adm:string /> </adm:syntax> <adm:profile name="ldap"> <ldap:attribute> <ldap:oid>1.3.6.1.4.1.26027.1.1.197</ldap:oid> <ldap:name>ds-cfg-require-change-by-time</ldap:name> </ldap:attribute> </adm:profile> </adm:property> <adm:property name="last-login-time-attribute" mandatory="false" multi-valued="false"> <adm:synopsis> Specifies the name or OID of the attribute type that should be used to hold the last login time for users with the associated password policy. </adm:synopsis> <adm:description> Specifies the name or OID of the attribute type that should be used to hold the last login time for users with the associated password policy. 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. Changes to this configuration attribute will take effect immediately. </adm:description> <adm:default-behavior> <adm:undefined /> </adm:default-behavior> <adm:syntax> <adm:oid /> </adm:syntax> <adm:profile name="ldap"> <ldap:attribute> <ldap:oid>1.3.6.1.4.1.26027.1.1.184</ldap:oid> <ldap:name>ds-cfg-last-login-time-attribute</ldap:name> </ldap:attribute> </adm:profile> </adm:property> <adm:property name="last-login-time-format" mandatory="false" multi-valued="false"> <adm:synopsis> Specifies the format string that should be used to generate the last login time value for users with the associated password policy. </adm:synopsis> <adm:description> Specifies the format string that should be used to generate the last login time value for users with the associated password policy. This format string should conform to the syntax described in the API documentation for the java.text.SimpleDateFormat class. Changes to this configuration attribute will take effect immediately. </adm:description> <adm:default-behavior> <adm:undefined /> </adm:default-behavior> <adm:syntax> <adm:string /> </adm:syntax> <adm:profile name="ldap"> <ldap:attribute> <ldap:oid>1.3.6.1.4.1.26027.1.1.185</ldap:oid> <ldap:name>ds-cfg-last-login-time-format</ldap:name> </ldap:attribute> </adm:profile> </adm:property> <adm:property name="previous-last-login-time-format" mandatory="false" multi-valued="true"> <adm:synopsis> Specifies the format string(s) that may have been used with the last login time at any point in the past for users associated with the password policy. </adm:synopsis> <adm:description> Specifies the format string(s) that may have been used with the last login time at any point in the past for users associated with the password policy. These values are used to make it possible to parse previous values, but will not be used to set new values. These format strings should conform to the syntax described in the API documentation for the java.text.SimpleDateFormat class. Changes to this configuration attribute will take effect immediately. </adm:description> <adm:default-behavior> <adm:undefined /> </adm:default-behavior> <adm:syntax> <adm:string /> </adm:syntax> <adm:profile name="ldap"> <ldap:attribute> <ldap:oid>1.3.6.1.4.1.26027.1.1.196</ldap:oid> <ldap:name>ds-cfg-previous-last-login-time-format</ldap:name> </ldap:attribute> </adm:profile> </adm:property> <adm:property name="idle-lockout-interval" mandatory="false" multi-valued="false"> <adm:synopsis> Specifies the maximum length of time that an account may remain idle (i.e., the associated user does notauthenticate to the server) before that user is locked out. </adm:synopsis> <adm:description> Specifies the maximum length of time that an account may remain idle (i.e., the associated user does notauthenticate to the server) before that user is locked out. The value of this attribute should be an integer followed by a unit of seconds, minutes, hours, days, or weeks. A value of 0 seconds indicates that idle accounts should not automatically be locked out. This feature will only be available if the last login time is maintained. Changes to this configuration attribute will take effect immediately. </adm:description> <adm:default-behavior> <adm:defined> <adm:value>0 seconds</adm:value> </adm:defined> </adm:default-behavior> <adm:syntax> <adm:duration /> </adm:syntax> <adm:profile name="ldap"> <ldap:attribute> <ldap:oid>1.3.6.1.4.1.26027.1.1.183</ldap:oid> <ldap:name>ds-cfg-idle-lockout-interval</ldap:name> </ldap:attribute> </adm:profile> </adm:property> </adm:managed-object> opends/src/admin/defn/org/opends/server/admin/std/RootConfiguration.xml
@@ -116,5 +116,13 @@ </ldap:rdn-sequence> </adm:profile> </adm:relation> <adm:relation name="password-policy"> <adm:one-to-many /> <adm:profile name="ldap"> <ldap:rdn-sequence> cn=Password Policies,cn=config </ldap:rdn-sequence> </adm:profile> </adm:relation> <adm:product-name>OpenDS Directory Server</adm:product-name> </adm:root-managed-object> opends/src/server/org/opends/server/core/DirectoryServer.java
@@ -4932,6 +4932,24 @@ } /** * 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 @@ -4940,14 +4958,13 @@ * * @param configEntryDN The DN of the configuration entry that defines the * password policy. * @param policy The password policy to register with the server. * @param config The password policy config to register with the * server. */ public static void registerPasswordPolicy(DN configEntryDN, PasswordPolicy policy) PasswordPolicyConfig config) { Validator.ensureNotNull(configEntryDN, policy); PasswordPolicyConfig config = new PasswordPolicyConfig(policy); Validator.ensureNotNull(configEntryDN, config); directoryServer.passwordPolicies.put(configEntryDN, config); } @@ -4972,7 +4989,6 @@ PasswordPolicyConfig config = directoryServer.passwordPolicies.remove(configEntryDN); if (null != config) config.finalizePasswordPolicyConfig(); } opends/src/server/org/opends/server/core/PasswordPolicy.java
@@ -33,24 +33,19 @@ import java.util.Iterator; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import java.util.SortedSet; import java.util.TimeZone; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArraySet; 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.BooleanConfigAttribute; import org.opends.server.config.ConfigEntry; import org.opends.server.config.ConfigException; import org.opends.server.config.DNConfigAttribute; import org.opends.server.config.IntegerConfigAttribute; import org.opends.server.config.IntegerWithUnitConfigAttribute; import org.opends.server.config.StringConfigAttribute; import org.opends.server.protocols.asn1.ASN1OctetString; import org.opends.server.schema.GeneralizedTimeSyntax; import org.opends.server.types.AttributeType; @@ -222,7 +217,7 @@ * provided configuration entry. Any parameters not included in the provided * configuration entry will be assigned server-wide default values. * * @param configEntry The configuration entry with the information to use to * @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 @@ -232,7 +227,7 @@ * password policy that is not related to * the server configuration. */ public PasswordPolicy(ConfigEntry configEntry) public PasswordPolicy(PasswordPolicyCfg configuration) throws ConfigException, InitializationException { // Create a list of units and values that we can use to represent time @@ -250,19 +245,15 @@ timeUnits.put(TIME_UNIT_WEEKS_FULL, (double) (60 * 60 * 24 * 7)); this.configEntryDN = configEntry.getDN(); this.configEntryDN = configuration.dn(); int msgID; // Get the password attribute. If specified, it must have either the // user password or auth password syntax. int msgID = MSGID_PWPOLICY_DESCRIPTION_PW_ATTR; StringConfigAttribute pwAttrStub = new StringConfigAttribute(ATTR_PWPOLICY_PASSWORD_ATTRIBUTE, getMessage(msgID), false, false, false); String passwordAttr = configuration.getPasswordAttribute(); try { StringConfigAttribute pwAttrAttr = (StringConfigAttribute) configEntry.getConfigAttribute(pwAttrStub); if (pwAttrAttr == null) if (passwordAttr == null) { this.passwordAttribute = null; this.authPasswordSyntax = false; @@ -273,13 +264,13 @@ } else { String lowerName = toLowerCase(pwAttrAttr.pendingValue()); String lowerName = toLowerCase(passwordAttr); AttributeType pwAttrType = DirectoryServer.getAttributeType(lowerName); if (pwAttrType == null) { msgID = MSGID_PWPOLICY_UNDEFINED_PASSWORD_ATTRIBUTE; String message = getMessage(msgID, String.valueOf(configEntryDN), String.valueOf(pwAttrAttr.pendingValue())); String.valueOf(passwordAttr)); throw new ConfigException(msgID, message); } @@ -304,7 +295,7 @@ msgID = MSGID_PWPOLICY_INVALID_PASSWORD_ATTRIBUTE_SYNTAX; String message = getMessage(msgID, String.valueOf(configEntryDN), String.valueOf(pwAttrAttr.pendingValue()), String.valueOf(passwordAttr), String.valueOf(syntax)); throw new ConfigException(msgID, message); } @@ -330,16 +321,11 @@ // Get the default storage schemes. They must all reference valid storage // schemes that support the syntax for the specified password attribute. msgID = MSGID_PWPOLICY_DESCRIPTION_DEFAULT_STORAGE_SCHEMES; StringConfigAttribute defaultSchemeStub = new StringConfigAttribute(ATTR_PWPOLICY_DEFAULT_SCHEME, getMessage(msgID), false, true, false); SortedSet<String> storageSchemes = configuration.getDefaultPasswordStorageScheme(); try { StringConfigAttribute defaultSchemeAttr = (StringConfigAttribute) configEntry.getConfigAttribute(defaultSchemeStub); if (defaultSchemeAttr == null) if (storageSchemes == null) { msgID = MSGID_PWPOLICY_NO_DEFAULT_STORAGE_SCHEMES; String message = getMessage(msgID, String.valueOf(configEntryDN)); @@ -349,7 +335,7 @@ { LinkedList<PasswordStorageScheme> schemes = new LinkedList<PasswordStorageScheme>(); for (String schemeName : defaultSchemeAttr.pendingValues()) for (String schemeName : storageSchemes) { PasswordStorageScheme scheme; if (this.authPasswordSyntax) @@ -398,20 +384,14 @@ // Get the names of the deprecated storage schemes. msgID = MSGID_PWPOLICY_DESCRIPTION_DEPRECATED_STORAGE_SCHEMES; StringConfigAttribute deprecatedSchemeStub = new StringConfigAttribute(ATTR_PWPOLICY_DEPRECATED_SCHEME, getMessage(msgID), false, true, false); SortedSet<String> deprecatedStorageSchemes = configuration.getDeprecatedPasswordStorageScheme(); try { StringConfigAttribute deprecatedSchemeAttr = (StringConfigAttribute) configEntry.getConfigAttribute(deprecatedSchemeStub); if (deprecatedSchemeAttr != null) if (deprecatedStorageSchemes != null) { this.deprecatedStorageSchemes = new CopyOnWriteArraySet<String>( deprecatedSchemeAttr.pendingValues()); new CopyOnWriteArraySet<String>(deprecatedStorageSchemes); } } catch (Exception e) @@ -429,15 +409,11 @@ // Get the password validators. msgID = MSGID_PWPOLICY_DESCRIPTION_PASSWORD_VALIDATORS; DNConfigAttribute validatorStub = new DNConfigAttribute(ATTR_PWPOLICY_PASSWORD_VALIDATOR, getMessage(msgID), false, true, false); SortedSet<DN> passwordValidators = configuration.getPasswordValidatorDN(); try { DNConfigAttribute validatorAttr = (DNConfigAttribute) configEntry.getConfigAttribute(validatorStub); if (validatorAttr != null) if (passwordValidators != null) { ConcurrentHashMap<DN, PasswordValidator<? extends PasswordValidatorCfg>> @@ -445,7 +421,7 @@ new ConcurrentHashMap<DN, PasswordValidator<? extends PasswordValidatorCfg>>(); for (DN validatorDN : validatorAttr.pendingValues()) for (DN validatorDN : passwordValidators) { PasswordValidator<? extends PasswordValidatorCfg> validator = DirectoryServer.getPasswordValidator(validatorDN); @@ -482,19 +458,15 @@ // Get the status notification handlers. msgID = MSGID_PWPOLICY_DESCRIPTION_NOTIFICATION_HANDLERS; DNConfigAttribute notificationStub = new DNConfigAttribute(ATTR_PWPOLICY_NOTIFICATION_HANDLER, getMessage(msgID), false, true, false); SortedSet<DN> statusNotificationHandlers = configuration.getAccountStatusNotificationHandlerDN(); try { DNConfigAttribute notificationAttr = (DNConfigAttribute) configEntry.getConfigAttribute(notificationStub); if (notificationAttr != null) if (statusNotificationHandlers != null) { ConcurrentHashMap<DN,AccountStatusNotificationHandler> handlers = new ConcurrentHashMap<DN,AccountStatusNotificationHandler>(); for (DN handlerDN : notificationAttr.pendingValues()) for (DN handlerDN : statusNotificationHandlers) { AccountStatusNotificationHandler handler = DirectoryServer.getAccountStatusNotificationHandler(handlerDN); @@ -531,173 +503,39 @@ // Determine whether to allow user password changes. msgID = MSGID_PWPOLICY_DESCRIPTION_ALLOW_USER_PW_CHANGES; BooleanConfigAttribute userChangeStub = new BooleanConfigAttribute(ATTR_PWPOLICY_ALLOW_USER_CHANGE, getMessage(msgID), false); try { BooleanConfigAttribute userChangeAttr = (BooleanConfigAttribute) configEntry.getConfigAttribute(userChangeStub); if (userChangeAttr != null) { this.allowUserPasswordChanges = userChangeAttr.pendingValue(); } } catch (Exception e) { if (debugEnabled()) { debugCaught(DebugLogLevel.ERROR, e); } msgID = MSGID_PWPOLICY_CANNOT_DETERMINE_ALLOW_USER_PW_CHANGES; String message = getMessage(msgID, String.valueOf(configEntryDN), getExceptionMessage(e)); throw new InitializationException(msgID, message, e); } this.allowUserPasswordChanges = configuration.isAllowUserPasswordChanges(); // Determine whether to require the current password for user changes. msgID = MSGID_PWPOLICY_DESCRIPTION_REQUIRE_CURRENT_PW; BooleanConfigAttribute requirePWStub = new BooleanConfigAttribute(ATTR_PWPOLICY_REQUIRE_CURRENT_PASSWORD, getMessage(msgID), false); try { BooleanConfigAttribute requirePWAttr = (BooleanConfigAttribute) configEntry.getConfigAttribute(requirePWStub); if (requirePWAttr != null) { this.requireCurrentPassword = requirePWAttr.pendingValue(); } } catch (Exception e) { if (debugEnabled()) { debugCaught(DebugLogLevel.ERROR, e); } msgID = MSGID_PWPOLICY_CANNOT_DETERMINE_REQUIRE_CURRENT_PW; String message = getMessage(msgID, String.valueOf(configEntryDN), getExceptionMessage(e)); throw new InitializationException(msgID, message, e); } this.requireCurrentPassword = configuration.isPasswordChangeRequiresCurrentPassword(); // Determine whether to force password changes on add. msgID = MSGID_PWPOLICY_DESCRIPTION_FORCE_CHANGE_ON_ADD; BooleanConfigAttribute forceChangeOnAddStub = new BooleanConfigAttribute(ATTR_PWPOLICY_FORCE_CHANGE_ON_ADD, getMessage(msgID), false); try { BooleanConfigAttribute forceChangeOnAddAttr = (BooleanConfigAttribute) configEntry.getConfigAttribute(forceChangeOnAddStub); if (forceChangeOnAddAttr != null) { this.forceChangeOnAdd = forceChangeOnAddAttr.pendingValue(); } } catch (Exception e) { if (debugEnabled()) { debugCaught(DebugLogLevel.ERROR, e); } msgID = MSGID_PWPOLICY_CANNOT_DETERMINE_FORCE_CHANGE_ON_ADD; String message = getMessage(msgID, String.valueOf(configEntryDN), getExceptionMessage(e)); throw new InitializationException(msgID, message, e); } this.forceChangeOnAdd = configuration.isForceChangeOnAdd(); // Determine whether to force password changes on reset. msgID = MSGID_PWPOLICY_DESCRIPTION_FORCE_CHANGE_ON_RESET; BooleanConfigAttribute forceChangeOnResetStub = new BooleanConfigAttribute(ATTR_PWPOLICY_FORCE_CHANGE_ON_RESET, getMessage(msgID), false); try { BooleanConfigAttribute forceChangeAttr = (BooleanConfigAttribute) configEntry.getConfigAttribute(forceChangeOnResetStub); if (forceChangeAttr != null) { this.forceChangeOnReset = forceChangeAttr.pendingValue(); } } catch (Exception e) { if (debugEnabled()) { debugCaught(DebugLogLevel.ERROR, e); } msgID = MSGID_PWPOLICY_CANNOT_DETERMINE_FORCE_CHANGE_ON_RESET; String message = getMessage(msgID, String.valueOf(configEntryDN), getExceptionMessage(e)); throw new InitializationException(msgID, message, e); } this.forceChangeOnReset = configuration.isForceChangeOnReset(); // Determine whether to validate reset passwords. msgID = MSGID_PWPOLICY_DESCRIPTION_SKIP_ADMIN_VALIDATION; BooleanConfigAttribute validateResetStub = new BooleanConfigAttribute(ATTR_PWPOLICY_SKIP_ADMIN_VALIDATION, getMessage(msgID), false); try { BooleanConfigAttribute validateResetAttr = (BooleanConfigAttribute) configEntry.getConfigAttribute(validateResetStub); if (validateResetAttr != null) { this.skipValidationForAdministrators = validateResetAttr.pendingValue(); } } catch (Exception e) { if (debugEnabled()) { debugCaught(DebugLogLevel.ERROR, e); } msgID = MSGID_PWPOLICY_CANNOT_DETERMINE_SKIP_ADMIN_VALIDATION; String message = getMessage(msgID, String.valueOf(configEntryDN), getExceptionMessage(e)); throw new InitializationException(msgID, message, e); } configuration.isSkipValidationForAdministrators(); // Get the password generator. msgID = MSGID_PWPOLICY_DESCRIPTION_PASSWORD_GENERATOR; DNConfigAttribute generatorStub = new DNConfigAttribute(ATTR_PWPOLICY_PASSWORD_GENERATOR, getMessage(msgID), false, false, false); DN passGenDN = configuration.getPasswordGeneratorDN() ; try { DNConfigAttribute generatorAttr = (DNConfigAttribute) configEntry.getConfigAttribute(generatorStub); if (generatorAttr != null) if (passGenDN != null) { PasswordGenerator generator = DirectoryServer.getPasswordGenerator(generatorAttr.pendingValue()); DirectoryServer.getPasswordGenerator(passGenDN); if (generator == null) { msgID = MSGID_PWPOLICY_NO_SUCH_GENERATOR; String message = getMessage(msgID, String.valueOf(configEntryDN), String.valueOf(generatorAttr.pendingValue())); String.valueOf(passGenDN)); throw new ConfigException(msgID, message); } this.passwordGeneratorDN = generatorAttr.pendingValue(); this.passwordGeneratorDN = passGenDN; this.passwordGenerator = generator; } } @@ -720,272 +558,37 @@ // Determine whether to require secure authentication. msgID = MSGID_PWPOLICY_DESCRIPTION_REQUIRE_SECURE_AUTH; BooleanConfigAttribute secureAuthStub = new BooleanConfigAttribute(ATTR_PWPOLICY_REQUIRE_SECURE_AUTHENTICATION, getMessage(msgID), false); try { BooleanConfigAttribute secureAuthAttr = (BooleanConfigAttribute) configEntry.getConfigAttribute(secureAuthStub); if (secureAuthAttr != null) { this.requireSecureAuthentication = secureAuthAttr.pendingValue(); } } catch (Exception e) { if (debugEnabled()) { debugCaught(DebugLogLevel.ERROR, e); } msgID = MSGID_PWPOLICY_CANNOT_DETERMINE_REQUIRE_SECURE_AUTH; String message = getMessage(msgID, String.valueOf(configEntryDN), getExceptionMessage(e)); throw new InitializationException(msgID, message, e); } this.requireSecureAuthentication = configuration.isRequireSecureAuthentication(); // Determine whether to require secure password changes. msgID = MSGID_PWPOLICY_DESCRIPTION_REQUIRE_SECURE_CHANGES; BooleanConfigAttribute secureChangeStub = new BooleanConfigAttribute( ATTR_PWPOLICY_REQUIRE_SECURE_PASSWORD_CHANGES, getMessage(msgID), false); try { BooleanConfigAttribute secureChangeAttr = (BooleanConfigAttribute) configEntry.getConfigAttribute(secureChangeStub); if (secureChangeAttr != null) { this.requireSecurePasswordChanges = secureChangeAttr.pendingValue(); } } catch (Exception e) { if (debugEnabled()) { debugCaught(DebugLogLevel.ERROR, e); } msgID = MSGID_PWPOLICY_CANNOT_DETERMINE_REQUIRE_SECURE_CHANGES; String message = getMessage(msgID, String.valueOf(configEntryDN), getExceptionMessage(e)); throw new InitializationException(msgID, message, e); } this.requireSecurePasswordChanges = configuration.isRequireSecurePasswordChanges() ; // Determine whether to allow multiple password values. msgID = MSGID_PWPOLICY_DESCRIPTION_ALLOW_MULTIPLE_PW_VALUES; BooleanConfigAttribute allowMultiplePWStub = new BooleanConfigAttribute(ATTR_PWPOLICY_ALLOW_MULTIPLE_PW_VALUES, getMessage(msgID), false); try { BooleanConfigAttribute allowMultiplePWAttr = (BooleanConfigAttribute) configEntry.getConfigAttribute(allowMultiplePWStub); if (allowMultiplePWAttr != null) { this.allowMultiplePasswordValues = allowMultiplePWAttr.pendingValue(); } } catch (Exception e) { if (debugEnabled()) { debugCaught(DebugLogLevel.ERROR, e); } msgID = MSGID_PWPOLICY_CANNOT_DETERMINE_ALLOW_MULTIPLE_PW_VALUES; String message = getMessage(msgID, String.valueOf(configEntryDN), getExceptionMessage(e)); throw new InitializationException(msgID, message, e); } this.allowMultiplePasswordValues = configuration.isAllowMultiplePasswordValues(); // Determine whether to allow pre-encoded passwords. msgID = MSGID_PWPOLICY_DESCRIPTION_ALLOW_PREENCODED; BooleanConfigAttribute preEncodedStub = new BooleanConfigAttribute(ATTR_PWPOLICY_ALLOW_PRE_ENCODED_PASSWORDS, getMessage(msgID), false); try { BooleanConfigAttribute preEncodedAttr = (BooleanConfigAttribute) configEntry.getConfigAttribute(preEncodedStub); if (preEncodedAttr != null) { this.allowPreEncodedPasswords = preEncodedAttr.pendingValue(); } } catch (Exception e) { if (debugEnabled()) { debugCaught(DebugLogLevel.ERROR, e); } msgID = MSGID_PWPOLICY_CANNOT_DETERMINE_ALLOW_PREENCODED; String message = getMessage(msgID, String.valueOf(configEntryDN), getExceptionMessage(e)); throw new InitializationException(msgID, message, e); } this.allowPreEncodedPasswords = configuration.isAllowPreEncodedPasswords(); // Get the minimum password age. msgID = MSGID_PWPOLICY_DESCRIPTION_MIN_AGE; IntegerWithUnitConfigAttribute minAgeStub = new IntegerWithUnitConfigAttribute(ATTR_PWPOLICY_MINIMUM_PASSWORD_AGE, getMessage(msgID), false, timeUnits, true, 0, true, Integer.MAX_VALUE); try { IntegerWithUnitConfigAttribute minAgeAttr = (IntegerWithUnitConfigAttribute) configEntry.getConfigAttribute(minAgeStub); if (minAgeAttr != null) { this.minimumPasswordAge = (int) minAgeAttr.pendingCalculatedValue(); } } catch (Exception e) { if (debugEnabled()) { debugCaught(DebugLogLevel.ERROR, e); } msgID = MSGID_PWPOLICY_CANNOT_DETERMINE_MIN_AGE; String message = getMessage(msgID, String.valueOf(configEntryDN), getExceptionMessage(e)); throw new InitializationException(msgID, message, e); } this.minimumPasswordAge = (int) configuration.getMinimumPasswordAge(); // Get the maximum password age. msgID = MSGID_PWPOLICY_DESCRIPTION_MAX_AGE; IntegerWithUnitConfigAttribute maxAgeStub = new IntegerWithUnitConfigAttribute(ATTR_PWPOLICY_MAXIMUM_PASSWORD_AGE, getMessage(msgID), false, timeUnits, true, 0, true, Integer.MAX_VALUE); try { IntegerWithUnitConfigAttribute maxAgeAttr = (IntegerWithUnitConfigAttribute) configEntry.getConfigAttribute(maxAgeStub); if (maxAgeAttr != null) { this.maximumPasswordAge = (int) maxAgeAttr.pendingCalculatedValue(); } } catch (Exception e) { if (debugEnabled()) { debugCaught(DebugLogLevel.ERROR, e); } msgID = MSGID_PWPOLICY_CANNOT_DETERMINE_MAX_AGE; String message = getMessage(msgID, String.valueOf(configEntryDN), getExceptionMessage(e)); throw new InitializationException(msgID, message, e); } this.maximumPasswordAge = (int) configuration.getMaximumPasswordAge(); // Get the maximum password reset age. msgID = MSGID_PWPOLICY_DESCRIPTION_MAX_RESET_AGE; IntegerWithUnitConfigAttribute maxResetStub = new IntegerWithUnitConfigAttribute( ATTR_PWPOLICY_MAXIMUM_PASSWORD_RESET_AGE, getMessage(msgID), false, timeUnits, true, 0, true, Integer.MAX_VALUE); try { IntegerWithUnitConfigAttribute maxResetAttr = (IntegerWithUnitConfigAttribute) configEntry.getConfigAttribute(maxResetStub); if (maxResetAttr != null) { this.maximumPasswordResetAge = (int) maxResetAttr.pendingCalculatedValue(); } } catch (Exception e) { if (debugEnabled()) { debugCaught(DebugLogLevel.ERROR, e); } msgID = MSGID_PWPOLICY_CANNOT_DETERMINE_MAX_RESET_AGE; String message = getMessage(msgID, String.valueOf(configEntryDN), getExceptionMessage(e)); throw new InitializationException(msgID, message, e); } this.maximumPasswordResetAge = (int) configuration .getMaximumPasswordResetAge(); // Get the warning interval. msgID = MSGID_PWPOLICY_DESCRIPTION_WARNING_INTERVAL; IntegerWithUnitConfigAttribute warningStub = new IntegerWithUnitConfigAttribute(ATTR_PWPOLICY_WARNING_INTERVAL, getMessage(msgID), false, timeUnits, true, 0, true, Integer.MAX_VALUE); try { IntegerWithUnitConfigAttribute warningAttr = (IntegerWithUnitConfigAttribute) configEntry.getConfigAttribute(warningStub); if (warningAttr != null) { this.warningInterval = (int) warningAttr.pendingCalculatedValue(); } } catch (Exception e) { if (debugEnabled()) { debugCaught(DebugLogLevel.ERROR, e); } msgID = MSGID_PWPOLICY_CANNOT_DETERMINE_WARNING_INTERVAL; String message = getMessage(msgID, String.valueOf(configEntryDN), getExceptionMessage(e)); throw new InitializationException(msgID, message, e); } this.warningInterval = (int) configuration .getPasswordExpirationWarningInterval(); // Determine whether to expire passwords without warning. msgID = MSGID_PWPOLICY_DESCRIPTION_EXPIRE_WITHOUT_WARNING; BooleanConfigAttribute expireWithoutWarningStub = new BooleanConfigAttribute(ATTR_PWPOLICY_EXPIRE_WITHOUT_WARNING, getMessage(msgID), false); try { BooleanConfigAttribute expireWithoutWarningAttr = (BooleanConfigAttribute) configEntry.getConfigAttribute(expireWithoutWarningStub); if (expireWithoutWarningAttr != null) { this.expirePasswordsWithoutWarning = expireWithoutWarningAttr.pendingValue(); } } catch (Exception e) { if (debugEnabled()) { debugCaught(DebugLogLevel.ERROR, e); } msgID = MSGID_PWPOLICY_CANNOT_DETERMINE_EXPIRE_WITHOUT_WARNING; String message = getMessage(msgID, String.valueOf(configEntryDN), getExceptionMessage(e)); throw new InitializationException(msgID, message, e); } this.expirePasswordsWithoutWarning = configuration .isExpirePasswordsWithoutWarning(); // If the expire without warning option is disabled, then there must be a // warning interval. @@ -997,173 +600,30 @@ throw new ConfigException(msgID, message); } // Determine whether to allow user changes for expired passwords. msgID = MSGID_PWPOLICY_DESCRIPTION_ALLOW_EXPIRED_CHANGES; BooleanConfigAttribute allowExpiredChangesStub = new BooleanConfigAttribute(ATTR_PWPOLICY_ALLOW_EXPIRED_CHANGES, getMessage(msgID), false); try { BooleanConfigAttribute allowExpiredChangesAttr = (BooleanConfigAttribute) configEntry.getConfigAttribute(allowExpiredChangesStub); if (allowExpiredChangesAttr != null) { this.allowExpiredPasswordChanges = allowExpiredChangesAttr.pendingValue(); } } catch (Exception e) { if (debugEnabled()) { debugCaught(DebugLogLevel.ERROR, e); } msgID = MSGID_PWPOLICY_CANNOT_DETERMINE_ALLOW_EXPIRED_CHANGES; String message = getMessage(msgID, String.valueOf(configEntryDN), getExceptionMessage(e)); throw new InitializationException(msgID, message, e); } this.allowExpiredPasswordChanges = configuration .isAllowExpiredPasswordChanges(); // Get the grace login count. msgID = MSGID_PWPOLICY_DESCRIPTION_GRACE_LOGIN_COUNT; IntegerConfigAttribute graceStub = new IntegerConfigAttribute(ATTR_PWPOLICY_GRACE_LOGIN_COUNT, getMessage(msgID), false, false, false, true, 0, true, Integer.MAX_VALUE); try { IntegerConfigAttribute graceAttr = (IntegerConfigAttribute) configEntry.getConfigAttribute(graceStub); if (graceAttr != null) { this.graceLoginCount = graceAttr.pendingIntValue(); } } catch (Exception e) { if (debugEnabled()) { debugCaught(DebugLogLevel.ERROR, e); } msgID = MSGID_PWPOLICY_CANNOT_DETERMINE_GRACE_LOGIN_COUNT; String message = getMessage(msgID, String.valueOf(configEntryDN), getExceptionMessage(e)); throw new InitializationException(msgID, message, e); } this.graceLoginCount = configuration.getGraceLoginCount(); // Get the lockout failure count. msgID = MSGID_PWPOLICY_DESCRIPTION_LOCKOUT_FAILURE_COUNT; IntegerConfigAttribute failureCountStub = new IntegerConfigAttribute(ATTR_PWPOLICY_LOCKOUT_FAILURE_COUNT, getMessage(msgID), false, false, false, true, 0, true, Integer.MAX_VALUE); try { IntegerConfigAttribute failureCountAttr = (IntegerConfigAttribute) configEntry.getConfigAttribute(failureCountStub); if (failureCountAttr != null) { this.lockoutFailureCount = failureCountAttr.pendingIntValue(); } } catch (Exception e) { if (debugEnabled()) { debugCaught(DebugLogLevel.ERROR, e); } msgID = MSGID_PWPOLICY_CANNOT_DETERMINE_LOCKOUT_FAILURE_COUNT; String message = getMessage(msgID, String.valueOf(configEntryDN), getExceptionMessage(e)); throw new InitializationException(msgID, message, e); } this.lockoutFailureCount = configuration.getLockoutFailureCount(); // Get the lockout duration. msgID = MSGID_PWPOLICY_DESCRIPTION_LOCKOUT_DURATION; IntegerWithUnitConfigAttribute lockoutDurationStub = new IntegerWithUnitConfigAttribute(ATTR_PWPOLICY_LOCKOUT_DURATION, getMessage(msgID), false, timeUnits, true, 0, true, Integer.MAX_VALUE); try { IntegerWithUnitConfigAttribute lockoutDurationAttr = (IntegerWithUnitConfigAttribute) configEntry.getConfigAttribute(lockoutDurationStub); if (lockoutDurationAttr != null) { this.lockoutDuration = (int) lockoutDurationAttr.pendingCalculatedValue(); } } catch (Exception e) { if (debugEnabled()) { debugCaught(DebugLogLevel.ERROR, e); } msgID = MSGID_PWPOLICY_CANNOT_DETERMINE_LOCKOUT_DURATION; String message = getMessage(msgID, String.valueOf(configEntryDN), getExceptionMessage(e)); throw new InitializationException(msgID, message, e); } this.lockoutDuration = (int) configuration.getLockoutDuration(); // Get the lockout failure expiration interval. msgID = MSGID_PWPOLICY_DESCRIPTION_FAILURE_EXPIRATION; IntegerWithUnitConfigAttribute failureExpirationStub = new IntegerWithUnitConfigAttribute( ATTR_PWPOLICY_LOCKOUT_FAILURE_EXPIRATION_INTERVAL, getMessage(msgID), false, timeUnits, true, 0, true, Integer.MAX_VALUE); try { IntegerWithUnitConfigAttribute failureExpirationAttr = (IntegerWithUnitConfigAttribute) configEntry.getConfigAttribute(failureExpirationStub); if (failureExpirationAttr != null) { this.lockoutFailureExpirationInterval = (int) failureExpirationAttr.pendingCalculatedValue(); } } catch (Exception e) { if (debugEnabled()) { debugCaught(DebugLogLevel.ERROR, e); } msgID = MSGID_PWPOLICY_CANNOT_DETERMINE_FAILURE_EXPIRATION; String message = getMessage(msgID, String.valueOf(configEntryDN), getExceptionMessage(e)); throw new InitializationException(msgID, message, e); } this.lockoutFailureExpirationInterval = (int) configuration .getLockoutFailureExpirationInterval(); // Get the required change time. msgID = MSGID_PWPOLICY_DESCRIPTION_REQUIRE_CHANGE_BY_TIME; StringConfigAttribute requireChangeByStub = new StringConfigAttribute(ATTR_PWPOLICY_REQUIRE_CHANGE_BY_TIME, getMessage(msgID), false, false, false); String requireChangeBy = configuration.getRequireChangeByTime(); try { StringConfigAttribute requireChangeByAttr = (StringConfigAttribute) configEntry.getConfigAttribute(requireChangeByStub); if (requireChangeByAttr != null) if (requireChangeBy != null) { ByteString valueString = new ASN1OctetString(requireChangeByAttr.pendingValue()); ByteString valueString = new ASN1OctetString(requireChangeBy); GeneralizedTimeSyntax syntax = (GeneralizedTimeSyntax) @@ -1202,25 +662,19 @@ // 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. msgID = MSGID_PWPOLICY_DESCRIPTION_LAST_LOGIN_TIME_ATTR; StringConfigAttribute lastLoginAttrStub = new StringConfigAttribute(ATTR_PWPOLICY_LAST_LOGIN_TIME_ATTRIBUTE, getMessage(msgID), false, false, false); String lastLoginTimeAtt = configuration.getLastLoginTimeAttribute(); try { StringConfigAttribute lastLoginAttrAttr = (StringConfigAttribute) configEntry.getConfigAttribute(lastLoginAttrStub); if (lastLoginAttrAttr != null) if (lastLoginTimeAtt != null) { String lowerName = toLowerCase(lastLoginAttrAttr.pendingValue()); String lowerName = toLowerCase(lastLoginTimeAtt); AttributeType attrType = DirectoryServer.getAttributeType(lowerName); if (attrType == null) { msgID = MSGID_PWPOLICY_UNDEFINED_LAST_LOGIN_TIME_ATTRIBUTE; String message = getMessage(msgID, String.valueOf(configEntryDN), String.valueOf(lastLoginAttrAttr.pendingValue())); String.valueOf(lastLoginTimeAtt)); throw new ConfigException(msgID, message); } @@ -1246,19 +700,11 @@ // Get the last login time format. If specified, it must be a valid format // string. msgID = MSGID_PWPOLICY_DESCRIPTION_LAST_LOGIN_TIME_FORMAT; StringConfigAttribute lastLoginFormatStub = new StringConfigAttribute(ATTR_PWPOLICY_LAST_LOGIN_TIME_FORMAT, getMessage(msgID), false, false, false); String formatString = configuration.getLastLoginTimeFormat(); try { StringConfigAttribute lastLoginFormatAttr = (StringConfigAttribute) configEntry.getConfigAttribute(lastLoginFormatStub); if (lastLoginFormatAttr != null) if (formatString != null) { String formatString = lastLoginFormatAttr.pendingValue(); try { new SimpleDateFormat(formatString); @@ -1299,19 +745,12 @@ // Get the previous last login time formats. If specified, they must all // be valid format strings. msgID = MSGID_PWPOLICY_DESCRIPTION_PREVIOUS_LAST_LOGIN_TIME_FORMAT; StringConfigAttribute previousFormatStub = new StringConfigAttribute( ATTR_PWPOLICY_PREVIOUS_LAST_LOGIN_TIME_FORMAT, getMessage(msgID), false, true, false); SortedSet<String> formatStrings = configuration.getPreviousLastLoginTimeFormat() ; try { StringConfigAttribute previousFormatAttr = (StringConfigAttribute) configEntry.getConfigAttribute(previousFormatStub); if (previousFormatAttr != null) if (formatStrings != null) { List<String> formatStrings = previousFormatAttr.pendingValues(); for (String s : formatStrings) { try @@ -1355,35 +794,7 @@ // Get the idle lockout duration. msgID = MSGID_PWPOLICY_DESCRIPTION_IDLE_LOCKOUT_INTERVAL; IntegerWithUnitConfigAttribute idleIntervalStub = new IntegerWithUnitConfigAttribute(ATTR_PWPOLICY_IDLE_LOCKOUT_INTERVAL, getMessage(msgID), false, timeUnits, true, 0, true, Integer.MAX_VALUE); try { IntegerWithUnitConfigAttribute idleIntervalAttr = (IntegerWithUnitConfigAttribute) configEntry.getConfigAttribute(idleIntervalStub); if (idleIntervalAttr != null) { this.idleLockoutInterval = (int) idleIntervalAttr.pendingCalculatedValue(); } } catch (Exception e) { if (debugEnabled()) { debugCaught(DebugLogLevel.ERROR, e); } msgID = MSGID_PWPOLICY_CANNOT_DETERMINE_IDLE_LOCKOUT_INTERVAL; String message = getMessage(msgID, String.valueOf(configEntryDN), getExceptionMessage(e)); throw new InitializationException(msgID, message, e); } this.idleLockoutInterval = (int) configuration.getIdleLockoutInterval(); /* * Holistic validation. opends/src/server/org/opends/server/core/PasswordPolicyConfig.java
@@ -27,33 +27,20 @@ package org.opends.server.core; import java.util.ArrayList; import java.util.LinkedHashMap; import java.util.LinkedList; import java.util.List; import org.opends.server.api.ConfigurableComponent; import org.opends.server.api.PasswordStorageScheme; import org.opends.server.config.BooleanConfigAttribute; import org.opends.server.config.ConfigAttribute; import org.opends.server.config.ConfigEntry; import org.opends.server.admin.server.ConfigurationChangeListener; import org.opends.server.admin.std.server.PasswordPolicyCfg; import org.opends.server.config.ConfigException; import org.opends.server.config.DNConfigAttribute; import org.opends.server.config.IntegerConfigAttribute; import org.opends.server.config.IntegerWithUnitConfigAttribute; import org.opends.server.config.StringConfigAttribute; import org.opends.server.schema.GeneralizedTimeSyntax; import org.opends.server.types.ConfigChangeResult; import org.opends.server.types.DN; import org.opends.server.types.InitializationException; import org.opends.server.types.ResultCode; import static org.opends.server.config.ConfigConstants.*; import static org.opends.server.loggers.debug.DebugLogger.debugCaught; import static org.opends.server.loggers.debug.DebugLogger.debugEnabled; import org.opends.server.types.DebugLogLevel; import static org.opends.server.messages.CoreMessages.*; import static org.opends.server.messages.MessageHandler.getMessage; import static org.opends.server.util.ServerConstants.*; /** This class is the interface between the password policy configurable component @@ -63,7 +50,7 @@ valiadating any proposed modification and applying an accepted modification. */ public class PasswordPolicyConfig implements ConfigurableComponent implements ConfigurationChangeListener<PasswordPolicyCfg> { /** @@ -85,325 +72,22 @@ public PasswordPolicyConfig(PasswordPolicy policy) { this.currentPolicy = policy; DirectoryServer.registerConfigurableComponent(this); } /** * Finalize a password policy configuration handler. * {@inheritDoc} */ public void finalizePasswordPolicyConfig() public boolean isConfigurationChangeAcceptable( PasswordPolicyCfg configuration, List<String> unacceptableReasons) { DirectoryServer.deregisterConfigurableComponent(this); } /** * Retrieves the DN of the configuration entry with which this component is * associated. * * @return The DN of the configuration entry with which this component is * associated. */ public DN getConfigurableComponentEntryDN() { return currentPolicy.getConfigEntryDN(); } /** * Retrieves the set of configuration attributes that are associated with this * configurable component. * * @return The set of configuration attributes that are associated with this * configurable component. */ public List<ConfigAttribute> getConfigurationAttributes() { // 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)); PasswordPolicy policy = this.currentPolicy; // this field is volatile LinkedList<ConfigAttribute> attrList = new LinkedList<ConfigAttribute>(); int msgID = MSGID_PWPOLICY_DESCRIPTION_PW_ATTR; String pwAttr = (policy.getPasswordAttribute() == null) ? null : policy.getPasswordAttribute().getNameOrOID(); attrList.add(new StringConfigAttribute(ATTR_PWPOLICY_PASSWORD_ATTRIBUTE, getMessage(msgID), false, false, false, pwAttr)); msgID = MSGID_PWPOLICY_DESCRIPTION_DEFAULT_STORAGE_SCHEMES; ArrayList<String> schemes = new ArrayList<String>(); for (PasswordStorageScheme s : policy.getDefaultStorageSchemes()) { schemes.add(s.getStorageSchemeName()); } attrList.add(new StringConfigAttribute(ATTR_PWPOLICY_DEFAULT_SCHEME, getMessage(msgID), false, true, false, schemes)); msgID = MSGID_PWPOLICY_DESCRIPTION_DEPRECATED_STORAGE_SCHEMES; ArrayList<String> deprecatedSchemes = new ArrayList<String>(); deprecatedSchemes.addAll(policy.getDeprecatedStorageSchemes()); attrList.add(new StringConfigAttribute(ATTR_PWPOLICY_DEPRECATED_SCHEME, getMessage(msgID), false, true, false, deprecatedSchemes)); msgID = MSGID_PWPOLICY_DESCRIPTION_PASSWORD_VALIDATORS; ArrayList<DN> validatorDNs = new ArrayList<DN>(); validatorDNs.addAll(policy.getPasswordValidators().keySet()); attrList.add(new DNConfigAttribute(ATTR_PWPOLICY_PASSWORD_VALIDATOR, getMessage(msgID), false, true, false, validatorDNs)); msgID = MSGID_PWPOLICY_DESCRIPTION_NOTIFICATION_HANDLERS; ArrayList<DN> handlerDNs = new ArrayList<DN>(); handlerDNs.addAll(policy.getAccountStatusNotificationHandlers().keySet()); attrList.add(new DNConfigAttribute(ATTR_PWPOLICY_NOTIFICATION_HANDLER, getMessage(msgID), false, true, false, handlerDNs)); msgID = MSGID_PWPOLICY_DESCRIPTION_ALLOW_USER_PW_CHANGES; attrList.add(new BooleanConfigAttribute(ATTR_PWPOLICY_ALLOW_USER_CHANGE, getMessage(msgID), false, policy.allowUserPasswordChanges())); msgID = MSGID_PWPOLICY_DESCRIPTION_REQUIRE_CURRENT_PW; attrList.add(new BooleanConfigAttribute( ATTR_PWPOLICY_REQUIRE_CURRENT_PASSWORD, getMessage(msgID), false, policy.requireCurrentPassword())); msgID = MSGID_PWPOLICY_DESCRIPTION_FORCE_CHANGE_ON_ADD; attrList.add(new BooleanConfigAttribute(ATTR_PWPOLICY_FORCE_CHANGE_ON_ADD, getMessage(msgID), false, policy.forceChangeOnAdd())); msgID = MSGID_PWPOLICY_DESCRIPTION_FORCE_CHANGE_ON_RESET; attrList.add(new BooleanConfigAttribute(ATTR_PWPOLICY_FORCE_CHANGE_ON_RESET, getMessage(msgID), false, policy.forceChangeOnReset())); msgID = MSGID_PWPOLICY_DESCRIPTION_SKIP_ADMIN_VALIDATION; attrList.add(new BooleanConfigAttribute( ATTR_PWPOLICY_SKIP_ADMIN_VALIDATION, getMessage(msgID), false, policy.skipValidationForAdministrators())); msgID = MSGID_PWPOLICY_DESCRIPTION_PASSWORD_GENERATOR; attrList.add(new DNConfigAttribute(ATTR_PWPOLICY_PASSWORD_GENERATOR, getMessage(msgID), false, false, false, policy.getPasswordGeneratorDN())); msgID = MSGID_PWPOLICY_DESCRIPTION_REQUIRE_SECURE_AUTH; attrList.add(new BooleanConfigAttribute( ATTR_PWPOLICY_REQUIRE_SECURE_AUTHENTICATION, getMessage(msgID), false, policy.requireSecureAuthentication())); msgID = MSGID_PWPOLICY_DESCRIPTION_REQUIRE_SECURE_CHANGES; attrList.add(new BooleanConfigAttribute( ATTR_PWPOLICY_REQUIRE_SECURE_PASSWORD_CHANGES, getMessage(msgID), false, policy.requireSecurePasswordChanges())); msgID = MSGID_PWPOLICY_DESCRIPTION_ALLOW_MULTIPLE_PW_VALUES; attrList.add(new BooleanConfigAttribute( ATTR_PWPOLICY_ALLOW_MULTIPLE_PW_VALUES, getMessage(msgID), false, policy.allowMultiplePasswordValues())); msgID = MSGID_PWPOLICY_DESCRIPTION_ALLOW_PREENCODED; attrList.add(new BooleanConfigAttribute( ATTR_PWPOLICY_ALLOW_PRE_ENCODED_PASSWORDS, getMessage(msgID), false, policy.allowPreEncodedPasswords())); msgID = MSGID_PWPOLICY_DESCRIPTION_MIN_AGE; attrList.add(new IntegerWithUnitConfigAttribute( ATTR_PWPOLICY_MINIMUM_PASSWORD_AGE, getMessage(msgID), false, timeUnits, true, 0, true, Integer.MAX_VALUE, policy.getMinimumPasswordAge(), TIME_UNIT_SECONDS_FULL)); msgID = MSGID_PWPOLICY_DESCRIPTION_MAX_AGE; attrList.add(new IntegerWithUnitConfigAttribute( ATTR_PWPOLICY_MAXIMUM_PASSWORD_AGE, getMessage(msgID), false, timeUnits, true, 0, true, Integer.MAX_VALUE, policy.getMaximumPasswordAge(), TIME_UNIT_SECONDS_FULL)); msgID = MSGID_PWPOLICY_DESCRIPTION_MAX_RESET_AGE; attrList.add(new IntegerWithUnitConfigAttribute( ATTR_PWPOLICY_MAXIMUM_PASSWORD_RESET_AGE, getMessage(msgID), false, timeUnits, true, 0, true, Integer.MAX_VALUE, policy.getMaximumPasswordResetAge(), TIME_UNIT_SECONDS_FULL)); msgID = MSGID_PWPOLICY_DESCRIPTION_WARNING_INTERVAL; attrList.add(new IntegerWithUnitConfigAttribute( ATTR_PWPOLICY_WARNING_INTERVAL, getMessage(msgID), false, timeUnits, true, 0, true, Integer.MAX_VALUE, policy.getWarningInterval(), TIME_UNIT_SECONDS_FULL)); msgID = MSGID_PWPOLICY_DESCRIPTION_EXPIRE_WITHOUT_WARNING; attrList.add(new BooleanConfigAttribute( ATTR_PWPOLICY_EXPIRE_WITHOUT_WARNING, getMessage(msgID), false, policy.expirePasswordsWithoutWarning())); msgID = MSGID_PWPOLICY_DESCRIPTION_ALLOW_EXPIRED_CHANGES; attrList.add(new BooleanConfigAttribute( ATTR_PWPOLICY_ALLOW_EXPIRED_CHANGES, getMessage(msgID), false, policy.allowExpiredPasswordChanges())); msgID = MSGID_PWPOLICY_DESCRIPTION_GRACE_LOGIN_COUNT; attrList.add(new IntegerConfigAttribute(ATTR_PWPOLICY_GRACE_LOGIN_COUNT, getMessage(msgID), false, false, false, true, 0, true, Integer.MAX_VALUE, policy.getGraceLoginCount())); msgID = MSGID_PWPOLICY_DESCRIPTION_LOCKOUT_FAILURE_COUNT; attrList.add(new IntegerConfigAttribute(ATTR_PWPOLICY_LOCKOUT_FAILURE_COUNT, getMessage(msgID), false, false, false, true, 0, true, Integer.MAX_VALUE, policy.getLockoutFailureCount())); msgID = MSGID_PWPOLICY_DESCRIPTION_LOCKOUT_DURATION; attrList.add(new IntegerWithUnitConfigAttribute( ATTR_PWPOLICY_LOCKOUT_DURATION, getMessage(msgID), false, timeUnits, true, 0, true, Integer.MAX_VALUE, policy.getLockoutDuration(), TIME_UNIT_SECONDS_FULL)); msgID = MSGID_PWPOLICY_DESCRIPTION_FAILURE_EXPIRATION; attrList.add(new IntegerWithUnitConfigAttribute( ATTR_PWPOLICY_LOCKOUT_FAILURE_EXPIRATION_INTERVAL, getMessage(msgID), false, timeUnits, true, 0, true, Integer.MAX_VALUE, policy.getLockoutFailureExpirationInterval(), TIME_UNIT_SECONDS_FULL)); msgID = MSGID_PWPOLICY_DESCRIPTION_REQUIRE_CHANGE_BY_TIME; String timeStr = null; if (policy.getRequireChangeByTime() > 0) { timeStr = GeneralizedTimeSyntax.createGeneralizedTimeValue( policy.getRequireChangeByTime()).getStringValue(); } attrList.add(new StringConfigAttribute(ATTR_PWPOLICY_REQUIRE_CHANGE_BY_TIME, getMessage(msgID), false, false, false, timeStr)); msgID = MSGID_PWPOLICY_DESCRIPTION_LAST_LOGIN_TIME_ATTR; String loginTimeAttr = (policy.getLastLoginTimeAttribute() == null) ? null : policy.getLastLoginTimeAttribute().getNameOrOID(); attrList.add(new StringConfigAttribute( ATTR_PWPOLICY_LAST_LOGIN_TIME_ATTRIBUTE, getMessage(msgID), false, false, false, loginTimeAttr)); msgID = MSGID_PWPOLICY_DESCRIPTION_LAST_LOGIN_TIME_FORMAT; attrList.add(new StringConfigAttribute(ATTR_PWPOLICY_LAST_LOGIN_TIME_FORMAT, getMessage(msgID), false, false, false, policy.getLastLoginTimeFormat())); msgID = MSGID_PWPOLICY_DESCRIPTION_PREVIOUS_LAST_LOGIN_TIME_FORMAT; ArrayList<String> previousFormats = new ArrayList<String>(); previousFormats.addAll(policy.getPreviousLastLoginTimeFormats()); attrList.add(new StringConfigAttribute( ATTR_PWPOLICY_PREVIOUS_LAST_LOGIN_TIME_FORMAT, getMessage(msgID), false, false, false, previousFormats)); msgID = MSGID_PWPOLICY_DESCRIPTION_IDLE_LOCKOUT_INTERVAL; attrList.add(new IntegerWithUnitConfigAttribute( ATTR_PWPOLICY_IDLE_LOCKOUT_INTERVAL, getMessage(msgID), false, timeUnits, true, 0, true, Integer.MAX_VALUE, policy.getIdleLockoutInterval(), TIME_UNIT_SECONDS_FULL)); return attrList; } /** * Indicates whether the provided configuration entry has an acceptable * configuration for this component. If it does not, then detailed * information about the problem(s) should be added to the provided list. * * @param configEntry The configuration entry for which to make the * determination. * @param unacceptableReasons A list that can be used to hold messages about * why the provided entry does not have an * acceptable configuration. * * @return <CODE>true</CODE> if the provided entry has an acceptable * configuration for this component, or <CODE>false</CODE> if not. */ public boolean hasAcceptableConfiguration(ConfigEntry configEntry, List<String> unacceptableReasons) { assert configEntry.getDN().equals(this.currentPolicy.getConfigEntryDN() ) assert configuration.dn().equals(this.currentPolicy.getConfigEntryDN() ) : "Internal Error: mismatch between DN of configuration entry and" + "DN of current password policy." ; try { new PasswordPolicy(configEntry); new PasswordPolicy(configuration); } catch (ConfigException ce) { @@ -433,25 +117,12 @@ /** * Makes a best-effort attempt to apply the configuration contained in the * provided entry. Information about the result of this processing should be * added to the provided message list. Information should always be added to * this list if a configuration change could not be applied. If detailed * results are requested, then information about the changes applied * successfully (and optionally about parameters that were not changed) should * also be included. * * @param configEntry The entry containing the new configuration to * apply for this component. * @param detailedResults Indicates whether detailed information about the * processing should be added to the list. * * @return Information about the result of the configuration update. * {@inheritDoc} */ public ConfigChangeResult applyNewConfiguration(ConfigEntry configEntry, boolean detailedResults) public ConfigChangeResult applyConfigurationChange( PasswordPolicyCfg configuration) { assert configEntry.getDN().equals(this.currentPolicy.getConfigEntryDN() ) assert configuration.dn().equals(this.currentPolicy.getConfigEntryDN() ) : "Internal Error: mismatch between DN of configuration entry and" + "DN of current password policy." ; @@ -459,7 +130,7 @@ try { p = new PasswordPolicy(configEntry); p = new PasswordPolicy(configuration); } catch (ConfigException ce) { @@ -489,11 +160,8 @@ // If we've made it here, then everything is acceptable. Apply the new // configuration. ArrayList<String> messages = new ArrayList<String>(); if (detailedResults) { int msgID = MSGID_PWPOLICY_UPDATED_POLICY; messages.add(getMessage(msgID, String.valueOf(p.getConfigEntryDN()))); } this.currentPolicy = p; @@ -501,7 +169,6 @@ /*adminActionRequired*/ false, messages); } /** * Retrieves the PasswordPolicy object representing the configuration entry * managed by this object. opends/src/server/org/opends/server/core/PasswordPolicyConfigManager.java
@@ -29,20 +29,19 @@ import java.util.ArrayList; import java.util.List; import org.opends.server.api.ConfigAddListener; import org.opends.server.api.ConfigDeleteListener; import org.opends.server.config.ConfigEntry; 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.server.PasswordPolicyCfg; import org.opends.server.admin.std.server.RootCfg; import org.opends.server.config.ConfigException; import org.opends.server.types.ConfigChangeResult; import org.opends.server.types.DN; import org.opends.server.types.InitializationException; import org.opends.server.types.ResultCode; import static org.opends.server.config.ConfigConstants.*; import static org.opends.server.loggers.debug.DebugLogger.debugCaught; import static org.opends.server.loggers.debug.DebugLogger.debugEnabled; import org.opends.server.types.DebugLogLevel; import static org.opends.server.messages.ConfigMessages.*; import static org.opends.server.messages.MessageHandler.*; import static org.opends.server.util.StaticUtils.*; @@ -56,7 +55,8 @@ * the server is running. */ public class PasswordPolicyConfigManager implements ConfigAddListener, ConfigDeleteListener implements ConfigurationAddListener<PasswordPolicyCfg>, ConfigurationDeleteListener<PasswordPolicyCfg> { @@ -85,44 +85,23 @@ public void initializePasswordPolicies() throws ConfigException, InitializationException { // Get the root configuration object. 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 ploicies entries are added or removed. rootConfiguration.addPasswordPolicyAddListener(this); rootConfiguration.addPasswordPolicyDeleteListener(this); // First, get the configuration base entry. ConfigEntry baseEntry; try { DN policyBase = DN.decode(DN_PWPOLICY_CONFIG_BASE); baseEntry = DirectoryServer.getConfigHandler().getConfigEntry(policyBase); } catch (Exception e) { if (debugEnabled()) { debugCaught(DebugLogLevel.ERROR, e); } int msgID = MSGID_CONFIG_PWPOLICY_CANNOT_GET_BASE; String message = getMessage(msgID, String.valueOf(e)); throw new ConfigException(msgID, message, e); } if (baseEntry == null) { // The password policy base entry does not exist. This is not // acceptable, so throw an exception. int msgID = MSGID_CONFIG_PWPOLICY_BASE_DOES_NOT_EXIST; String message = getMessage(msgID); throw new ConfigException(msgID, message); } // Register add and delete listeners with the policy base entry. We // don't care about modifications to it. baseEntry.registerAddListener(this); baseEntry.registerDeleteListener(this); String[] passwordPoliciesName = rootConfiguration.listPasswordPolicys() ; // 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 (! baseEntry.hasChildren()) if (passwordPoliciesName.length == 0) { int msgID = MSGID_CONFIG_PWPOLICY_NO_POLICIES; String message = getMessage(msgID); @@ -141,31 +120,38 @@ // Iterate through the child entries and process them as password policy // configuration entries. for (ConfigEntry childEntry : baseEntry.getChildren().values()) for (String passwordPolicyName : passwordPoliciesName) { PasswordPolicyCfg passwordPolicyConfiguration = rootConfiguration.getPasswordPolicy(passwordPolicyName); try { PasswordPolicy policy = new PasswordPolicy(childEntry); DirectoryServer.registerPasswordPolicy(childEntry.getDN(), policy); PasswordPolicy policy = new PasswordPolicy(passwordPolicyConfiguration); PasswordPolicyConfig config = new PasswordPolicyConfig(policy); DirectoryServer.registerPasswordPolicy( passwordPolicyConfiguration.dn(), config); passwordPolicyConfiguration.addChangeListener(config); } catch (ConfigException ce) { int msgID = MSGID_CONFIG_PWPOLICY_INVALID_POLICY_CONFIG; String message = getMessage(msgID, String.valueOf(childEntry.getDN()), ce.getMessage()); String message = getMessage(msgID, String .valueOf(passwordPolicyConfiguration.dn()), ce.getMessage()); throw new ConfigException(msgID, message, ce); } catch (InitializationException ie) { int msgID = MSGID_CONFIG_PWPOLICY_INVALID_POLICY_CONFIG; String message = getMessage(msgID, String.valueOf(childEntry.getDN()), ie.getMessage()); String message = getMessage(msgID, String .valueOf(passwordPolicyConfiguration.dn()), ie.getMessage()); throw new InitializationException(msgID, message, ie); } catch (Exception e) { int msgID = MSGID_CONFIG_PWPOLICY_INVALID_POLICY_CONFIG; String message = getMessage(msgID, String.valueOf(childEntry.getDN()), String message = getMessage(msgID, String .valueOf(passwordPolicyConfiguration.dn()), stackTraceToSingleLineString(e)); throw new InitializationException(msgID, message, e); } @@ -186,49 +172,39 @@ /** * Indicates whether the configuration entry that will result from a proposed * add is acceptable to this add listener. * * @param configEntry The configuration entry that will result from * the requested add. * @param unacceptableReason A buffer to which this method can append a * human-readable message explaining why the * proposed entry is not acceptable. * * @return <CODE>true</CODE> if the proposed entry contains an acceptable * configuration, or <CODE>false</CODE> if it does not. * {@inheritDoc} */ public boolean configAddIsAcceptable(ConfigEntry configEntry, StringBuilder unacceptableReason) public boolean isConfigurationAddAcceptable(PasswordPolicyCfg configuration, List<String> unacceptableReason) { // See if we can create a password policy from the provided configuration // entry. If so, then it's acceptable. try { new PasswordPolicy(configEntry); new PasswordPolicy(configuration); } catch (ConfigException ce) { int msgID = MSGID_CONFIG_PWPOLICY_INVALID_POLICY_CONFIG; String message = getMessage(msgID, String.valueOf(configEntry.getDN()), String message = getMessage(msgID, String.valueOf(configuration.dn()), ce.getMessage()); unacceptableReason.append(message); unacceptableReason.add(message); return false; } catch (InitializationException ie) { int msgID = MSGID_CONFIG_PWPOLICY_INVALID_POLICY_CONFIG; String message = getMessage(msgID, String.valueOf(configEntry.getDN()), String message = getMessage(msgID, String.valueOf(configuration.dn()), ie.getMessage()); unacceptableReason.append(message); unacceptableReason.add(message); return false; } catch (Exception e) { int msgID = MSGID_CONFIG_PWPOLICY_INVALID_POLICY_CONFIG; String message = getMessage(msgID, String.valueOf(configEntry.getDN()), String message = getMessage(msgID, String.valueOf(configuration.dn()), stackTraceToSingleLineString(e)); unacceptableReason.append(message); unacceptableReason.add(message); return false; } @@ -240,17 +216,12 @@ /** * Attempts to apply a new configuration based on the provided added entry. * * @param configEntry The new configuration entry that contains the * configuration to apply. * * @return Information about the result of processing the configuration * change. * {@inheritDoc} */ public ConfigChangeResult applyConfigurationAdd(ConfigEntry configEntry) public ConfigChangeResult applyConfigurationAdd( PasswordPolicyCfg configuration) { DN configEntryDN = configEntry.getDN(); DN configEntryDN = configuration.dn(); ArrayList<String> messages = new ArrayList<String>(); @@ -258,14 +229,17 @@ // entry. If so, then register it with the Directory Server. try { PasswordPolicy policy = new PasswordPolicy(configEntry); DirectoryServer.registerPasswordPolicy(configEntryDN, policy); PasswordPolicy policy = new PasswordPolicy(configuration); PasswordPolicyConfig config = new PasswordPolicyConfig(policy); DirectoryServer.registerPasswordPolicy(configEntryDN, config); configuration.addChangeListener(config); return new ConfigChangeResult(ResultCode.SUCCESS, false, messages); } catch (ConfigException ce) { int msgID = MSGID_CONFIG_PWPOLICY_INVALID_POLICY_CONFIG; messages.add(getMessage(msgID, String.valueOf(configEntry.getDN()), messages.add(getMessage(msgID, String.valueOf(configuration.dn()), ce.getMessage())); return new ConfigChangeResult(ResultCode.CONSTRAINT_VIOLATION, false, @@ -274,7 +248,7 @@ catch (InitializationException ie) { int msgID = MSGID_CONFIG_PWPOLICY_INVALID_POLICY_CONFIG; messages.add(getMessage(msgID, String.valueOf(configEntry.getDN()), messages.add(getMessage(msgID, String.valueOf(configuration.dn()), ie.getMessage())); return new ConfigChangeResult(DirectoryServer.getServerErrorResultCode(), @@ -283,7 +257,7 @@ catch (Exception e) { int msgID = MSGID_CONFIG_PWPOLICY_INVALID_POLICY_CONFIG; messages.add(getMessage(msgID, String.valueOf(configEntry.getDN()), messages.add(getMessage(msgID, String.valueOf(configuration.dn()), stackTraceToSingleLineString(e))); return new ConfigChangeResult(DirectoryServer.getServerErrorResultCode(), @@ -294,20 +268,10 @@ /** * Indicates whether it is acceptable to remove the provided configuration * entry. * * @param configEntry The configuration entry that will be removed * from the configuration. * @param unacceptableReason A buffer to which this method can append a * human-readable message explaining why the * proposed delete is not acceptable. * * @return <CODE>true</CODE> if the proposed entry may be removed from the * configuration, or <CODE>false</CODE> if not. * {@inheritDoc} */ public boolean configDeleteIsAcceptable(ConfigEntry configEntry, StringBuilder unacceptableReason) public boolean isConfigurationDeleteAcceptable( PasswordPolicyCfg configuration, List<String> 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 @@ -315,11 +279,11 @@ // directly or via a virtual attribute). DN defaultPolicyDN = DirectoryServer.getDefaultPasswordPolicyDN(); if ((defaultPolicyDN != null) && defaultPolicyDN.equals(configEntry.getDN())) defaultPolicyDN.equals(configuration.dn())) { int msgID = MSGID_CONFIG_PWPOLICY_CANNOT_DELETE_DEFAULT_POLICY; String message = getMessage(msgID, String.valueOf(defaultPolicyDN)); unacceptableReason.append(message); unacceptableReason.add(message); return false; } else @@ -331,21 +295,17 @@ /** * Attempts to apply a new configuration based on the provided deleted entry. * * @param configEntry The new configuration entry that has been deleted. * * @return Information about the result of processing the configuration * change. * {@inheritDoc} */ public ConfigChangeResult applyConfigurationDelete(ConfigEntry configEntry) public ConfigChangeResult applyConfigurationDelete( PasswordPolicyCfg 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 // directly or via a virtual attribute). ArrayList<String> messages = new ArrayList<String>(1); DN policyDN = configEntry.getDN(); DN policyDN = configuration.dn(); DN defaultPolicyDN = DirectoryServer.getDefaultPasswordPolicyDN(); if ((defaultPolicyDN != null) && defaultPolicyDN.equals(policyDN)) { @@ -355,8 +315,13 @@ return new ConfigChangeResult(ResultCode.CONSTRAINT_VIOLATION, false, messages); } DirectoryServer.deregisterPasswordPolicy(policyDN); PasswordPolicyConfig config = DirectoryServer.getPasswordPolicyConfig(policyDN); if (config != null) { configuration.removeChangeListener(config); } int msgID = MSGID_CONFIG_PWPOLICY_REMOVED_POLICY; messages.add(getMessage(msgID, String.valueOf(policyDN))); opends/tests/unit-tests-testng/src/server/org/opends/server/core/PasswordPolicyTestCase.java
@@ -38,6 +38,9 @@ import org.testng.annotations.Test; import org.opends.server.TestCaseUtils; import org.opends.server.admin.server.AdminTestCaseUtils; import org.opends.server.admin.std.meta.PasswordPolicyCfgDefn; import org.opends.server.admin.std.server.PasswordPolicyCfg; import org.opends.server.api.PasswordStorageScheme; import org.opends.server.config.ConfigEntry; import org.opends.server.config.ConfigException; @@ -2111,7 +2114,11 @@ ConfigEntry parentEntry = DirectoryServer.getConfigEntry(parentDN); ConfigEntry configEntry = new ConfigEntry(e, parentEntry); new PasswordPolicy(configEntry); PasswordPolicyCfg configuration = AdminTestCaseUtils.getConfiguration(PasswordPolicyCfgDefn.getInstance(), configEntry.getEntry()); new PasswordPolicy(configuration); }