mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

Matthew Swift
01.38.2011 f48c58b09661fd595a218ce964e1845306ba940a
Fix OPENDJ-168: Enhance character set password validator to support optional character sets
13 files modified
404 ■■■■■ changed files
opends/resource/schema/02-config.ldif 6 ●●●●● patch | view | raw | blame | history
opends/src/admin/defn/org/opends/server/admin/std/CharacterSetPasswordValidatorConfiguration.xml 38 ●●●●● patch | view | raw | blame | history
opends/src/admin/messages/CharacterSetPasswordValidatorCfgDefn.properties 5 ●●●● patch | view | raw | blame | history
opends/src/messages/messages/extension.properties 11 ●●●●● patch | view | raw | blame | history
opends/src/messages/messages/extension_de.properties 1 ●●●● patch | view | raw | blame | history
opends/src/messages/messages/extension_es.properties 1 ●●●● patch | view | raw | blame | history
opends/src/messages/messages/extension_fr.properties 1 ●●●● patch | view | raw | blame | history
opends/src/messages/messages/extension_ja.properties 1 ●●●● patch | view | raw | blame | history
opends/src/messages/messages/extension_ko.properties 1 ●●●● patch | view | raw | blame | history
opends/src/messages/messages/extension_zh_CN.properties 1 ●●●● patch | view | raw | blame | history
opends/src/messages/messages/extension_zh_TW.properties 1 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/extensions/CharacterSetPasswordValidator.java 97 ●●●●● patch | view | raw | blame | history
opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/CharacterSetPasswordValidatorTestCase.java 240 ●●●●● patch | view | raw | blame | history
opends/resource/schema/02-config.ldif
@@ -2554,6 +2554,11 @@
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
  SINGLE-VALUE
  X-ORIGIN 'OpenDJ Directory Server' )
attributeTypes: ( 1.3.6.1.4.1.36733.2.1.1.5
  NAME 'ds-cfg-min-character-sets'
  SYNTAX 1.3.6.1.4.1.1466.115.121.1.27
  SINGLE-VALUE
  X-ORIGIN 'OpenDJ Directory Server' )
objectClasses: ( 1.3.6.1.4.1.26027.1.2.1
  NAME 'ds-cfg-access-control-handler'
  SUP top
@@ -3511,6 +3516,7 @@
  STRUCTURAL
  MUST ( ds-cfg-character-set $
         ds-cfg-allow-unclassified-characters )
  MAY ds-cfg-min-character-sets
  X-ORIGIN 'OpenDS Directory Server' )
objectClasses: ( 1.3.6.1.4.1.26027.1.2.97
  NAME 'ds-task-rebuild'
opends/src/admin/defn/org/opends/server/admin/std/CharacterSetPasswordValidatorConfiguration.xml
@@ -24,6 +24,7 @@
  !
  !
  !      Copyright 2007-2008 Sun Microsystems, Inc.
  !      Portions copyright 2011 ForgeRock AS
  ! -->
<adm:managed-object name="character-set-password-validator"
  plural-name="character-set-password-validators"
@@ -67,7 +68,8 @@
    </adm:synopsis>
    <adm:description>
      Each value must be an integer (indicating the minimum required
      characters from the set) followed by a colon and the characters to
      characters from the set which may be zero, indicating that the
      character set is optional) followed by a colon and the characters to
      include in that set (for example, "3:abcdefghijklmnopqrstuvwxyz"
      indicates that a user password must contain at least three
      characters from the set of lowercase ASCII letters). Multiple
@@ -103,4 +105,38 @@
      </ldap:attribute>
    </adm:profile>
  </adm:property>
  <adm:property name="min-character-sets" mandatory="false">
    <adm:synopsis>
      Specifies the minimum number of character sets that a password must
      contain.
    </adm:synopsis>
    <adm:description>
      This property should only be used in conjunction with optional character
      sets (those requiring zero characters). Its value must include any
      mandatory character sets (those requiring great than zero characters).
      This is useful in situations where a password must contain characters
      from mandatory character sets, and characters from at least N optional
      character sets. For example, it is quite common to require that a
      password contains at least one non-alphanumeric character as well as
      characters from two alphanumeric character sets (lower-case,
      upper-case, digits). In this case, this property should be set to 3.
    </adm:description>
  <adm:default-behavior>
    <adm:alias>
      <adm:synopsis>
        The password must contain characters from each of the mandatory
        character sets and, if there are optional character sets, at least
        one character from one of the optional character sets.
      </adm:synopsis>
    </adm:alias>
  </adm:default-behavior>
  <adm:syntax>
      <adm:integer />
    </adm:syntax>
    <adm:profile name="ldap">
      <ldap:attribute>
        <ldap:name>ds-cfg-min-character-sets</ldap:name>
      </ldap:attribute>
    </adm:profile>
  </adm:property>
</adm:managed-object>
opends/src/admin/messages/CharacterSetPasswordValidatorCfgDefn.properties
@@ -5,6 +5,9 @@
property.allow-unclassified-characters.synopsis=Indicates whether this password validator allows passwords to contain characters outside of any of the user-defined character sets.
property.allow-unclassified-characters.description=If this is "false", then only those characters in the user-defined character sets may be used in passwords. Any password containing a character not included in any character set will be rejected.
property.character-set.synopsis=Specifies a character set containing characters that a password may contain and a value indicating the minimum number of characters required from that set.
property.character-set.description=Each value must be an integer (indicating the minimum required characters from the set) followed by a colon and the characters to include in that set (for example, "3:abcdefghijklmnopqrstuvwxyz" indicates that a user password must contain at least three characters from the set of lowercase ASCII letters). Multiple character sets can be defined in separate values, although no character can appear in more than one character set.
property.character-set.description=Each value must be an integer (indicating the minimum required characters from the set which may be zero, indicating that the character set is optional) followed by a colon and the characters to include in that set (for example, "3:abcdefghijklmnopqrstuvwxyz" indicates that a user password must contain at least three characters from the set of lowercase ASCII letters). Multiple character sets can be defined in separate values, although no character can appear in more than one character set.
property.enabled.synopsis=Indicates whether the password validator is enabled for use.
property.java-class.synopsis=Specifies the fully-qualified name of the Java class that provides the password validator implementation.
property.min-character-sets.synopsis=Specifies the minimum number of character sets that a password must contain.
property.min-character-sets.description=This property should only be used in conjunction with optional character sets (those requiring zero characters). Its value must include any mandatory character sets (those requiring great than zero characters). This is useful in situations where a password must contain characters from mandatory character sets, and characters from at least N optional character sets. For example, it is quite common to require that a password contains at least one non-alphanumeric character as well as characters from two alphanumeric character sets (lower-case, upper-case, digits). In this case, this property should be set to 3.
property.min-character-sets.default-behavior.alias.synopsis=The password must contain characters from each of the mandatory character sets and, if there are optional character sets, at least one character from one of the optional character sets.
opends/src/messages/messages/extension.properties
@@ -1157,7 +1157,7 @@
 '%s' is invalid because the provided character set is empty
MILD_ERR_CHARSET_VALIDATOR_INVALID_COUNT_468=The provided character set \
 definition '%s' is invalid because the value before the colon must be an \
 integer greater than zero
 integer greater or equal to zero
MILD_ERR_CHARSET_VALIDATOR_DUPLICATE_CHAR_469=The provided character set \
 definition '%s' is invalid because it contains character '%s' which has \
 already been used
@@ -1430,3 +1430,12 @@
 unindexed search filters
MILD_ERR_PWSCHEME_INVALID_BASE64_DECODED_STORED_PASSWORD_578=The password \
value %s has been base64-decoded but is too short to be valid
MILD_ERR_CHARSET_VALIDATOR_MIN_CHAR_SETS_TOO_SMALL_579=The provided minimum \
 required number of character sets '%d' is invalid because it must include \
 all mandatory character sets and at least one optional character set
MILD_ERR_CHARSET_VALIDATOR_MIN_CHAR_SETS_TOO_BIG_580=The provided minimum \
 required number of character sets '%d' is invalid because it is greater than \
 the total number of defined character sets
MILD_ERR_CHARSET_VALIDATOR_TOO_FEW_OPTIONAL_CHAR_SETS_581=The provided \
 password did not contain characters from at least %d of the following \
 character sets: %s
opends/src/messages/messages/extension_de.properties
@@ -426,7 +426,6 @@
MILD_ERR_CHARSET_VALIDATOR_TOO_FEW_CHARS_FROM_SET_465=Das angegebene Passwort enthielt zu wenige Zeichen aus dem Zeichensatz '%s'.  Benutzerpassw\u00f6rter m\u00fcssen mindestens %d Zeichen aus diesem Zeichensatz enthalten
MILD_ERR_CHARSET_VALIDATOR_NO_COLON_466=Die angegebene Zeichensatzdefinition '%s' ist ung\u00fcltig, weil sie keinen Doppelpunkt zur Trennung von Mindestanzahl und Zeichensatz enth\u00e4lt
MILD_ERR_CHARSET_VALIDATOR_NO_CHARS_467=Die angegebene Zeichensatzdefinition '%s' ist ung\u00fcltig, weil der angegebene Zeichensatz leer ist
MILD_ERR_CHARSET_VALIDATOR_INVALID_COUNT_468=Die angegebene Zeichensatzdefinition '%s' ist ung\u00fcltig, weil der Wert vor dem Doppelpunkt eine Ganzzahl gr\u00f6\u00dfer 0 sein muss
MILD_ERR_CHARSET_VALIDATOR_DUPLICATE_CHAR_469=Die angegebene Zeichensatzdefinition '%s' ist ung\u00fcltig, weil sie das Zeichen '%s' enth\u00e4lt, das bereits verwendet wurde
MILD_ERR_VIRTUAL_STATIC_GROUP_MULTIPLE_TARGETS_470=Die im Eintrag %s definierte virtuelle statische Gruppe enth\u00e4lt mehrere Zielgruppen-DNs, es ist jedoch nur einer zul\u00e4ssig
MILD_ERR_VIRTUAL_STATIC_GROUP_CANNOT_DECODE_TARGET_471= "%s" kann nicht als Ziel-DN f\u00fcr die Gruppe %s entschl\u00fcsselt werden:  %s
opends/src/messages/messages/extension_es.properties
@@ -426,7 +426,6 @@
MILD_ERR_CHARSET_VALIDATOR_TOO_FEW_CHARS_FROM_SET_465=La contrase\u00f1a proporcionada no conten\u00eda suficientes caracteres del conjunto de caracteres '%s'.  El n\u00famero m\u00ednimo de caracteres de dicho conjunto que debe estar presente en las contrase\u00f1as de usuario es %d
MILD_ERR_CHARSET_VALIDATOR_NO_COLON_466=La definici\u00f3n del conjunto de caracteres proporcionada '%s' no es v\u00e1lida porque no contiene un signo de dos puntos que separe el n\u00famero m\u00ednimo del conjunto de caracteres
MILD_ERR_CHARSET_VALIDATOR_NO_CHARS_467=La definici\u00f3n del conjunto de caracteres proporcionada '%s' no es v\u00e1lida porque el conjunto de caracteres proporcionado est\u00e1 vac\u00edo
MILD_ERR_CHARSET_VALIDATOR_INVALID_COUNT_468=La definici\u00f3n del conjunto de caracteres proporcionada '%s' no es v\u00e1lida porque el valor que precede al signo de dos puntos debe ser un n\u00famero entero mayor que cero
MILD_ERR_CHARSET_VALIDATOR_DUPLICATE_CHAR_469=La definici\u00f3n del conjunto de caracteres proporcionada '%s' no es v\u00e1lida porque contiene el car\u00e1cter '%s', el cual ya se ha utilizado
MILD_ERR_VIRTUAL_STATIC_GROUP_MULTIPLE_TARGETS_470=El grupo est\u00e1tico virtual definido en la entrada %s contiene varios ND de grupo de destino, pero s\u00f3lo se permite uno
MILD_ERR_VIRTUAL_STATIC_GROUP_CANNOT_DECODE_TARGET_471=No se puede descodificar "%s" como ND de destino para el grupo %s:  %s
opends/src/messages/messages/extension_fr.properties
@@ -426,7 +426,6 @@
MILD_ERR_CHARSET_VALIDATOR_TOO_FEW_CHARS_FROM_SET_465=Le mot de passe fourni ne contient pas suffisamment de caract\u00e8res du jeu de caract\u00e8res '%s'.  Le nombre minimum de caract\u00e8res de ce jeu dans les mots de passe utilisateur doit \u00eatre %d
MILD_ERR_CHARSET_VALIDATOR_NO_COLON_466=La d\u00e9finition du jeu de caract\u00e8res '%s' fournie n'est pas valide car elle ne contient pas de deux-points pour d\u00e9limiter le nombre minimum du jeu de caract\u00e8res
MILD_ERR_CHARSET_VALIDATOR_NO_CHARS_467=La d\u00e9finition du jeu de caract\u00e8res '%s' fournie n'est pas valide car le jeu fourni est vide
MILD_ERR_CHARSET_VALIDATOR_INVALID_COUNT_468=La d\u00e9finition du jeu de caract\u00e8res '%s' fournie n'est pas valide car la valeur pr\u00e9c\u00e9dant les deux-points doit \u00eatre un entier sup\u00e9rieur \u00e0 z\u00e9ro
MILD_ERR_CHARSET_VALIDATOR_DUPLICATE_CHAR_469=La d\u00e9finition du jeu de caract\u00e8res '%s' fournie n'est pas valide car elle contient le caract\u00e8re '%s' qui a d\u00e9j\u00e0 \u00e9t\u00e9 utilis\u00e9
MILD_ERR_VIRTUAL_STATIC_GROUP_MULTIPLE_TARGETS_470=Le groupe statique virtuel d\u00e9fini dans l'entr\u00e9e %s contient plusieurs DN de groupe cible, alors qu'un seul est autoris\u00e9
MILD_ERR_VIRTUAL_STATIC_GROUP_CANNOT_DECODE_TARGET_471=Impossible de d\u00e9coder "%s" comme DN cible pour le groupe %s\u00a0: %s
opends/src/messages/messages/extension_ja.properties
@@ -426,7 +426,6 @@
MILD_ERR_CHARSET_VALIDATOR_TOO_FEW_CHARS_FROM_SET_465=\u6307\u5b9a\u3055\u308c\u305f\u30d1\u30b9\u30ef\u30fc\u30c9\u306b\u3001\u6587\u5b57\u30bb\u30c3\u30c8 '%s' \u306e\u6587\u5b57\u304c\u5341\u5206\u306b\u542b\u307e\u308c\u3066\u3044\u307e\u305b\u3093\u3067\u3057\u305f\u3002  \u305d\u306e\u6587\u5b57\u30bb\u30c3\u30c8\u304b\u3089\u30e6\u30fc\u30b6\u30fc\u30d1\u30b9\u30ef\u30fc\u30c9\u306b\u542b\u3081\u308b\u5fc5\u8981\u306e\u3042\u308b\u6700\u5c0f\u6587\u5b57\u6570\u306f %d \u3067\u3059
MILD_ERR_CHARSET_VALIDATOR_NO_COLON_466=\u6307\u5b9a\u3055\u308c\u305f\u6587\u5b57\u30bb\u30c3\u30c8\u306e\u5b9a\u7fa9 '%s' \u304c\u7121\u52b9\u3067\u3059\u3002\u6700\u5c0f\u30ab\u30a6\u30f3\u30c8\u3068\u6587\u5b57\u30bb\u30c3\u30c8\u3092\u533a\u5207\u308b\u30b3\u30ed\u30f3\u304c\u542b\u307e\u308c\u3066\u3044\u307e\u305b\u3093
MILD_ERR_CHARSET_VALIDATOR_NO_CHARS_467=\u6307\u5b9a\u3055\u308c\u305f\u6587\u5b57\u30bb\u30c3\u30c8\u306e\u5b9a\u7fa9 '%s' \u304c\u7121\u52b9\u3067\u3059\u3002\u6307\u5b9a\u3055\u308c\u305f\u6587\u5b57\u30bb\u30c3\u30c8\u304c\u7a7a\u3067\u3059
MILD_ERR_CHARSET_VALIDATOR_INVALID_COUNT_468=\u6307\u5b9a\u3055\u308c\u305f\u6587\u5b57\u30bb\u30c3\u30c8\u306e\u5b9a\u7fa9 '%s' \u304c\u7121\u52b9\u3067\u3059\u3002\u30b3\u30ed\u30f3\u306e\u524d\u306e\u5024\u306f 0 \u3088\u308a\u5927\u304d\u3044\u6574\u6570\u306b\u3059\u308b\u5fc5\u8981\u304c\u3042\u308a\u307e\u3059
MILD_ERR_CHARSET_VALIDATOR_DUPLICATE_CHAR_469=\u6307\u5b9a\u3055\u308c\u305f\u6587\u5b57\u30bb\u30c3\u30c8\u306e\u5b9a\u7fa9 '%s' \u304c\u7121\u52b9\u3067\u3059\u3002\u3059\u3067\u306b\u4f7f\u7528\u3055\u308c\u3066\u3044\u308b\u6587\u5b57 '%s' \u304c\u542b\u307e\u308c\u3066\u3044\u307e\u3059
MILD_ERR_VIRTUAL_STATIC_GROUP_MULTIPLE_TARGETS_470=\u30a8\u30f3\u30c8\u30ea %s \u3067\u5b9a\u7fa9\u3055\u308c\u305f\u4eee\u60f3\u30b9\u30bf\u30c6\u30a3\u30c3\u30af\u30b0\u30eb\u30fc\u30d7\u306b\u8907\u6570\u306e\u30bf\u30fc\u30b2\u30c3\u30c8\u30b0\u30eb\u30fc\u30d7 DN \u304c\u542b\u307e\u308c\u3066\u3044\u307e\u3059\u304c\u3001\u5b9a\u7fa9\u3067\u304d\u308b\u306e\u306f 1 \u3064\u3060\u3051\u3067\u3059
MILD_ERR_VIRTUAL_STATIC_GROUP_CANNOT_DECODE_TARGET_471="%s" \u3092\u30b0\u30eb\u30fc\u30d7 %s \u306e\u30bf\u30fc\u30b2\u30c3\u30c8 DN \u3068\u3057\u3066\u5fa9\u53f7\u5316\u3067\u304d\u307e\u305b\u3093:  %s
opends/src/messages/messages/extension_ko.properties
@@ -426,7 +426,6 @@
MILD_ERR_CHARSET_VALIDATOR_TOO_FEW_CHARS_FROM_SET_465=\uc81c\uacf5\ub41c \ube44\ubc00\ubc88\ud638\uc5d0 \ubb38\uc790 \uc9d1\ud569 '%s'\uc758 \ubb38\uc790\uac00 \ucda9\ubd84\ud788 \ud3ec\ud568\ub418\uc5b4 \uc788\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.  \uc0ac\uc6a9\uc790 \ube44\ubc00\ubc88\ud638\uc5d0 \uc0ac\uc6a9\ub418\uc5b4\uc57c \ud558\ub294 \ud574\ub2f9 \uc9d1\ud569\uc758 \ucd5c\uc18c \ubb38\uc790 \uc218\ub294 %d\uc785\ub2c8\ub2e4.
MILD_ERR_CHARSET_VALIDATOR_NO_COLON_466=\uc81c\uacf5\ub41c \ubb38\uc790 \uc9d1\ud569 \uc815\uc758 '%s'\uc740(\ub294) \ubb38\uc790 \uc9d1\ud569\uacfc \ucd5c\uc18c \uac1c\uc218\ub97c \uad6c\ubcc4\ud558\ub294 \ucf5c\ub860\uc744 \ud3ec\ud568\ud558\uc9c0 \uc54a\uae30 \ub54c\ubb38\uc5d0 \uc720\ud6a8\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.
MILD_ERR_CHARSET_VALIDATOR_NO_CHARS_467=\uc81c\uacf5\ub41c \ubb38\uc790 \uc9d1\ud569\uc774 \ube44\uc5b4 \uc788\uae30 \ub54c\ubb38\uc5d0 \uc81c\uacf5\ub41c \ubb38\uc790 \uc9d1\ud569 \uc815\uc758 '%s'\uc740(\ub294) \uc720\ud6a8\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.
MILD_ERR_CHARSET_VALIDATOR_INVALID_COUNT_468=\ucf5c\ub860 \uc55e\uc758 \uac12\uc774 0\ubcf4\ub2e4 \ud070 \uc815\uc218\uc5ec\uc57c \ud558\ubbc0\ub85c \uc81c\uacf5\ub41c \ubb38\uc790 \uc9d1\ud569 \uc815\uc758 '%s'\uc740(\ub294) \uc720\ud6a8\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.
MILD_ERR_CHARSET_VALIDATOR_DUPLICATE_CHAR_469=\uc81c\uacf5\ub41c \ubb38\uc790 \uc9d1\ud569 \uc815\uc758 '%s'\uc740(\ub294) \uc774\ubbf8 \uc0ac\uc6a9\ub41c \ubb38\uc790 '%s'\uc744(\ub97c) \ud3ec\ud568\ud558\uae30 \ub54c\ubb38\uc5d0 \uc720\ud6a8\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4.
MILD_ERR_VIRTUAL_STATIC_GROUP_MULTIPLE_TARGETS_470=\ud56d\ubaa9 %s\uc5d0 \uc815\uc758\ub41c \uac00\uc0c1 \uc815\uc801 \uadf8\ub8f9\uc5d0 \uc5ec\ub7ec \ub300\uc0c1 \uadf8\ub8f9 DN\uc774 \ud3ec\ud568\ub418\uc5b4 \uc788\uc9c0\ub9cc \ud558\ub098\ub9cc \ud5c8\uc6a9\ub429\ub2c8\ub2e4.
MILD_ERR_VIRTUAL_STATIC_GROUP_CANNOT_DECODE_TARGET_471=\u20a9"%s\u20a9"\uc744(\ub97c) \uadf8\ub8f9 %s\uc5d0 \ub300\ud55c \ub300\uc0c1 DN\uc73c\ub85c \ud574\ub3c5\ud560 \uc218 \uc5c6\uc2b5\ub2c8\ub2e4: %s
opends/src/messages/messages/extension_zh_CN.properties
@@ -426,7 +426,6 @@
MILD_ERR_CHARSET_VALIDATOR_TOO_FEW_CHARS_FROM_SET_465=\u63d0\u4f9b\u7684\u5bc6\u7801\u672a\u5305\u542b\u8db3\u591f\u7684\u5b57\u7b26\u96c6 '%s' \u4e2d\u7684\u5b57\u7b26\u3002\u7528\u6237\u5bc6\u7801\u4e2d\u5fc5\u987b\u5305\u542b\u81f3\u5c11 %d \u4e2a\u8be5\u5b57\u7b26\u96c6\u4e2d\u7684\u5b57\u7b26
MILD_ERR_CHARSET_VALIDATOR_NO_COLON_466=\u63d0\u4f9b\u7684\u5b57\u7b26\u96c6\u5b9a\u4e49 '%s' \u65e0\u6548\uff0c\u56e0\u4e3a\u5b83\u4e0d\u5305\u542b\u5c06\u6700\u5c0f\u8ba1\u6570\u4e0e\u5b57\u7b26\u96c6\u9694\u5f00\u7684\u5192\u53f7
MILD_ERR_CHARSET_VALIDATOR_NO_CHARS_467=\u63d0\u4f9b\u7684\u5b57\u7b26\u96c6\u5b9a\u4e49 '%s' \u65e0\u6548\uff0c\u56e0\u4e3a\u63d0\u4f9b\u7684\u5b57\u7b26\u96c6\u4e3a\u7a7a
MILD_ERR_CHARSET_VALIDATOR_INVALID_COUNT_468=\u63d0\u4f9b\u7684\u5b57\u7b26\u96c6\u5b9a\u4e49 '%s' \u65e0\u6548\uff0c\u56e0\u4e3a\u5192\u53f7\u524d\u9762\u7684\u503c\u5fc5\u987b\u4e3a\u5927\u4e8e\u96f6\u7684\u6574\u6570
MILD_ERR_CHARSET_VALIDATOR_DUPLICATE_CHAR_469=\u63d0\u4f9b\u7684\u5b57\u7b26\u96c6\u5b9a\u4e49 '%s' \u65e0\u6548\uff0c\u56e0\u4e3a\u5b83\u5305\u542b\u5df2\u4f7f\u7528\u7684\u5b57\u7b26 '%s'
MILD_ERR_VIRTUAL_STATIC_GROUP_MULTIPLE_TARGETS_470=\u6761\u76ee %s \u4e2d\u5b9a\u4e49\u7684\u865a\u62df\u9759\u6001\u7ec4\u5305\u542b\u591a\u4e2a\u76ee\u6807\u7ec4 DN\uff0c\u4f46\u53ea\u5141\u8bb8\u5305\u542b\u4e00\u4e2a\u76ee\u6807\u7ec4 DN
MILD_ERR_VIRTUAL_STATIC_GROUP_CANNOT_DECODE_TARGET_471=\u65e0\u6cd5\u5c06 "%s" \u89e3\u7801\u4e3a\u7ec4 %s \u7684\u76ee\u6807 DN: %s
opends/src/messages/messages/extension_zh_TW.properties
@@ -426,7 +426,6 @@
MILD_ERR_CHARSET_VALIDATOR_TOO_FEW_CHARS_FROM_SET_465=\u63d0\u4f9b\u7684\u5bc6\u78bc\u672a\u5305\u542b\u4f86\u81ea\u5b57\u5143\u96c6\u300c%s\u300d\u7684\u8db3\u5920\u5b57\u5143\u3002\u8a72\u96c6\u5408\u4e2d\u5fc5\u9808\u51fa\u73fe\u65bc\u4f7f\u7528\u8005\u5bc6\u78bc\u4e2d\u7684\u6700\u5c0f\u5b57\u5143\u6578\u70ba %d
MILD_ERR_CHARSET_VALIDATOR_NO_COLON_466=\u63d0\u4f9b\u7684\u5b57\u5143\u96c6\u5b9a\u7fa9\u300c%s\u300d\u7121\u6548\uff0c\u56e0\u70ba\u5b83\u4e0d\u5305\u542b\u5192\u865f\u4ee5\u9694\u958b\u6700\u5c0f\u8a08\u6578\u8207\u5b57\u5143\u96c6
MILD_ERR_CHARSET_VALIDATOR_NO_CHARS_467=\u63d0\u4f9b\u7684\u5b57\u5143\u96c6\u5b9a\u7fa9\u300c%s\u300d\u7121\u6548\uff0c\u56e0\u70ba\u63d0\u4f9b\u7684\u5b57\u5143\u96c6\u662f\u7a7a\u7684
MILD_ERR_CHARSET_VALIDATOR_INVALID_COUNT_468=\u63d0\u4f9b\u7684\u5b57\u5143\u96c6\u5b9a\u7fa9\u300c%s\u300d\u7121\u6548\uff0c\u56e0\u70ba\u5192\u865f\u524d\u9762\u7684\u503c\u5fc5\u9808\u662f\u5927\u65bc\u96f6\u7684\u6574\u6578
MILD_ERR_CHARSET_VALIDATOR_DUPLICATE_CHAR_469=\u63d0\u4f9b\u7684\u5b57\u5143\u96c6\u5b9a\u7fa9\u300c%s\u300d\u7121\u6548\uff0c\u56e0\u70ba\u5b83\u5305\u542b\u5df2\u4f7f\u7528\u7684\u5b57\u5143\u300c%s\u300d
MILD_ERR_VIRTUAL_STATIC_GROUP_MULTIPLE_TARGETS_470=\u9805\u76ee %s \u4e2d\u5b9a\u7fa9\u7684\u865b\u64ec\u975c\u614b\u7fa4\u7d44\u5305\u542b\u591a\u500b\u76ee\u6a19\u7fa4\u7d44 DN\uff0c\u4f46\u53ea\u5141\u8a31\u4e00\u500b
MILD_ERR_VIRTUAL_STATIC_GROUP_CANNOT_DECODE_TARGET_471=\u7121\u6cd5\u5c07\u300c%s\u300d\u89e3\u78bc\u70ba\u7fa4\u7d44 %s \u7684\u76ee\u6a19 DN: %s
opends/src/server/org/opends/server/extensions/CharacterSetPasswordValidator.java
@@ -23,6 +23,7 @@
 *
 *
 *      Copyright 2008 Sun Microsystems, Inc.
 *      Portions copyright 2011 ForgeRock AS
 */
package org.opends.server.extensions;
import org.opends.messages.Message;
@@ -41,7 +42,6 @@
import org.opends.server.api.PasswordValidator;
import org.opends.server.config.ConfigException;
import org.opends.server.types.*;
import static org.opends.messages.ExtensionMessages.*;
import org.opends.messages.MessageBuilder;
import static org.opends.server.util.StaticUtils.*;
@@ -155,18 +155,74 @@
      }
    }
    int usedOptionalCharacterSets = 0;
    int optionalCharacterSets = 0;
    int mandatoryCharacterSets = 0;
    for (String characterSet : characterSets.keySet())
    {
      int minimumCount = characterSets.get(characterSet);
      Integer passwordCount = counts.get(characterSet);
      if ((passwordCount == null) || (passwordCount < minimumCount))
      if (minimumCount > 0)
      {
        invalidReason.append(ERR_CHARSET_VALIDATOR_TOO_FEW_CHARS_FROM_SET.get(
                characterSet, minimumCount));
        return false;
        // Mandatory character set.
        mandatoryCharacterSets++;
        if ((passwordCount == null) || (passwordCount < minimumCount))
        {
          invalidReason
              .append(ERR_CHARSET_VALIDATOR_TOO_FEW_CHARS_FROM_SET
                  .get(characterSet, minimumCount));
          return false;
        }
      }
      else
      {
        // Optional character set.
        optionalCharacterSets++;
        if (passwordCount != null)
        {
          usedOptionalCharacterSets++;
        }
      }
    }
    // Check minimum optional character sets are present.
    if (optionalCharacterSets > 0)
    {
      int requiredOptionalCharacterSets;
      if (currentConfig.getMinCharacterSets() == null)
      {
        requiredOptionalCharacterSets = 1;
      }
      else
      {
        requiredOptionalCharacterSets = currentConfig
            .getMinCharacterSets() - mandatoryCharacterSets;
      }
      if (usedOptionalCharacterSets < requiredOptionalCharacterSets)
      {
        StringBuilder builder = new StringBuilder();
        for (String characterSet : characterSets.keySet())
        {
          if (characterSets.get(characterSet) == 0)
          {
            if (builder.length() > 0)
            {
              builder.append(", ");
            }
            builder.append('\'');
            builder.append(characterSet);
            builder.append('\'');
          }
        }
        invalidReason
            .append(ERR_CHARSET_VALIDATOR_TOO_FEW_OPTIONAL_CHAR_SETS
                .get(requiredOptionalCharacterSets,
                    builder.toString()));
        return false;
      }
    }
    // If we've gotten here, then the password is acceptable.
    return true;
@@ -194,6 +250,7 @@
  {
    HashMap<String,Integer> characterSets  = new HashMap<String,Integer>();
    HashSet<Character>      usedCharacters = new HashSet<Character>();
    int mandatoryCharacterSets = 0;
    for (String definition : configuration.getCharacterSet())
    {
@@ -220,7 +277,7 @@
        throw new ConfigException(message);
      }
      if (minCount <= 0)
      if (minCount < 0)
      {
        Message message = ERR_CHARSET_VALIDATOR_INVALID_COUNT.get(definition);
        throw new ConfigException(message);
@@ -241,6 +298,34 @@
      }
      characterSets.put(characterSet, minCount);
      if (minCount > 0)
      {
        mandatoryCharacterSets++;
      }
    }
    // Validate min-character-sets if necessary.
    int optionalCharacterSets = characterSets.size()
        - mandatoryCharacterSets;
    if (optionalCharacterSets > 0
        && configuration.getMinCharacterSets() != null)
    {
      int minCharacterSets = configuration.getMinCharacterSets();
      if (minCharacterSets <= mandatoryCharacterSets)
      {
        Message message = ERR_CHARSET_VALIDATOR_MIN_CHAR_SETS_TOO_SMALL
            .get(minCharacterSets);
        throw new ConfigException(message);
      }
      if (minCharacterSets > characterSets.size())
      {
        Message message = ERR_CHARSET_VALIDATOR_MIN_CHAR_SETS_TOO_BIG
            .get(minCharacterSets);
        throw new ConfigException(message);
      }
    }
    return characterSets;
opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/CharacterSetPasswordValidatorTestCase.java
@@ -23,6 +23,7 @@
 *
 *
 *      Copyright 2006-2008 Sun Microsystems, Inc.
 *      Portions copyright 2011 ForgeRock AS
 */
package org.opends.server.extensions;
@@ -125,7 +126,20 @@
         "ds-cfg-character-set: 1:ABCDEFGHIJKLMNOPQRSTUVWXYZ",
         "ds-cfg-character-set: 1:0123456789",
         "ds-cfg-character-set: 1:~!@#$%^&*()-_=+[]{}|;:,.<>/?",
         "ds-cfg-allow-unclassified-characters: false");
         "ds-cfg-allow-unclassified-characters: false",
         "",
         "dn: cn=Character Set,cn=Password Validators,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-validator",
         "objectClass: ds-cfg-character-set-password-validator",
         "cn: Character Set",
         "ds-cfg-java-class: org.opends.server.extensions." +
              "CharacterSetPasswordValidator",
         "ds-cfg-enabled: true",
         "ds-cfg-character-set: 1:abcdefghijklmnopqrstuvwxyz",
         "ds-cfg-character-set: 0:0123456789",
         "ds-cfg-allow-unclassified-characters: true",
         "ds-cfg-min-character-sets: 2");
    Object[][] array = new Object[entries.size()][1];
    for (int i=0; i < array.length; i++)
@@ -219,18 +233,6 @@
         "ds-cfg-character-set: noninteger:abcdefghijklmnopqrstuvwxyz",
         "ds-cfg-allow-unclassified-characters: true",
         "",
         // Malformed character set definition -- zero count.
         "dn: cn=Character Set,cn=Password Validators,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-validator",
         "objectClass: ds-cfg-character-set-password-validator",
         "cn: Character Set",
         "ds-cfg-java-class: org.opends.server.extensions." +
              "CharacterSetPasswordValidator",
         "ds-cfg-enabled: true",
         "ds-cfg-character-set: 0:abcdefghijklmnopqrstuvwxyz",
         "ds-cfg-allow-unclassified-characters: true",
         "",
         // Malformed character set definition -- negative count.
         "dn: cn=Character Set,cn=Password Validators,cn=config",
         "objectClass: top",
@@ -280,7 +282,49 @@
              "CharacterSetPasswordValidator",
         "ds-cfg-enabled: true",
         "ds-cfg-character-set: 1:abcdefghijklmnopqrstuvwxyz",
         "ds-cfg-allow-unclassified-characters: malformed");
         "ds-cfg-allow-unclassified-characters: malformed",
         "",
         // Malformed min-character-sets: too low.
         "dn: cn=Character Set,cn=Password Validators,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-validator",
         "objectClass: ds-cfg-character-set-password-validator",
         "cn: Character Set",
         "ds-cfg-java-class: org.opends.server.extensions." +
              "CharacterSetPasswordValidator",
         "ds-cfg-enabled: true",
         "ds-cfg-character-set: 1:abcdefghijklmnopqrstuvwxyz",
         "ds-cfg-character-set: 0:0123456789",
         "ds-cfg-allow-unclassified-characters: true",
         "ds-cfg-min-character-sets: 0",
         "",
         // Malformed min-character-sets: too low.
         "dn: cn=Character Set,cn=Password Validators,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-validator",
         "objectClass: ds-cfg-character-set-password-validator",
         "cn: Character Set",
         "ds-cfg-java-class: org.opends.server.extensions." +
              "CharacterSetPasswordValidator",
         "ds-cfg-enabled: true",
         "ds-cfg-character-set: 1:abcdefghijklmnopqrstuvwxyz",
         "ds-cfg-character-set: 0:0123456789",
         "ds-cfg-allow-unclassified-characters: true",
         "ds-cfg-min-character-sets: 1",
         "",
         // Malformed min-character-sets: too high.
         "dn: cn=Character Set,cn=Password Validators,cn=config",
         "objectClass: top",
         "objectClass: ds-cfg-password-validator",
         "objectClass: ds-cfg-character-set-password-validator",
         "cn: Character Set",
         "ds-cfg-java-class: org.opends.server.extensions." +
              "CharacterSetPasswordValidator",
         "ds-cfg-enabled: true",
         "ds-cfg-character-set: 1:abcdefghijklmnopqrstuvwxyz",
         "ds-cfg-character-set: 0:0123456789",
         "ds-cfg-allow-unclassified-characters: true",
         "ds-cfg-min-character-sets: 3");
    Object[][] array = new Object[entries.size()][1];
    for (int i=0; i < array.length; i++)
@@ -479,6 +523,174 @@
        "PaS$w0rD",
        false
      },
      // 1 mandatory, 2 optional, must have at least one optional.
      new Object[]
      {
        TestCaseUtils.makeEntry(
             "dn: cn=Character Set,cn=Password Validators,cn=config",
             "objectClass: top",
             "objectClass: ds-cfg-password-validator",
             "objectClass: ds-cfg-character-set-password-validator",
             "cn: Character Set",
             "ds-cfg-java-class: org.opends.server.extensions." +
                  "CharacterSetPasswordValidator",
             "ds-cfg-enabled: true",
             "ds-cfg-character-set: 0:abcdefghijklmnopqrstuvwxyz",
             "ds-cfg-character-set: 0:ABCDEFGHIJKLMNOPQRSTUVWXYZ",
             "ds-cfg-character-set: 1:0123456789",
             "ds-cfg-min-character-sets: 2",
             "ds-cfg-allow-unclassified-characters: false"),
        "!@#$%",
        false
      },
      // 1 mandatory, 2 optional, must have at least one optional.
      new Object[]
      {
        TestCaseUtils.makeEntry(
             "dn: cn=Character Set,cn=Password Validators,cn=config",
             "objectClass: top",
             "objectClass: ds-cfg-password-validator",
             "objectClass: ds-cfg-character-set-password-validator",
             "cn: Character Set",
             "ds-cfg-java-class: org.opends.server.extensions." +
                  "CharacterSetPasswordValidator",
             "ds-cfg-enabled: true",
             "ds-cfg-character-set: 0:abcdefghijklmnopqrstuvwxyz",
             "ds-cfg-character-set: 0:ABCDEFGHIJKLMNOPQRSTUVWXYZ",
             "ds-cfg-character-set: 1:0123456789",
             "ds-cfg-min-character-sets: 2",
             "ds-cfg-allow-unclassified-characters: false"),
        "0123456",
        false
      },
      // 1 mandatory, 2 optional, must have at least one optional.
      new Object[]
      {
        TestCaseUtils.makeEntry(
             "dn: cn=Character Set,cn=Password Validators,cn=config",
             "objectClass: top",
             "objectClass: ds-cfg-password-validator",
             "objectClass: ds-cfg-character-set-password-validator",
             "cn: Character Set",
             "ds-cfg-java-class: org.opends.server.extensions." +
                  "CharacterSetPasswordValidator",
             "ds-cfg-enabled: true",
             "ds-cfg-character-set: 0:abcdefghijklmnopqrstuvwxyz",
             "ds-cfg-character-set: 0:ABCDEFGHIJKLMNOPQRSTUVWXYZ",
             "ds-cfg-character-set: 1:0123456789",
             "ds-cfg-min-character-sets: 2",
             "ds-cfg-allow-unclassified-characters: false"),
        "abcDEF",
        false
      },
      // 1 mandatory, 2 optional, must have at least one optional.
      new Object[]
      {
        TestCaseUtils.makeEntry(
             "dn: cn=Character Set,cn=Password Validators,cn=config",
             "objectClass: top",
             "objectClass: ds-cfg-password-validator",
             "objectClass: ds-cfg-character-set-password-validator",
             "cn: Character Set",
             "ds-cfg-java-class: org.opends.server.extensions." +
                  "CharacterSetPasswordValidator",
             "ds-cfg-enabled: true",
             "ds-cfg-character-set: 0:abcdefghijklmnopqrstuvwxyz",
             "ds-cfg-character-set: 0:ABCDEFGHIJKLMNOPQRSTUVWXYZ",
             "ds-cfg-character-set: 1:0123456789",
             "ds-cfg-min-character-sets: 2",
             "ds-cfg-allow-unclassified-characters: false"),
        "abc123",
        true
      },
      // 1 mandatory, 2 optional, must have at least one optional.
      new Object[]
      {
        TestCaseUtils.makeEntry(
             "dn: cn=Character Set,cn=Password Validators,cn=config",
             "objectClass: top",
             "objectClass: ds-cfg-password-validator",
             "objectClass: ds-cfg-character-set-password-validator",
             "cn: Character Set",
             "ds-cfg-java-class: org.opends.server.extensions." +
                  "CharacterSetPasswordValidator",
             "ds-cfg-enabled: true",
             "ds-cfg-character-set: 0:abcdefghijklmnopqrstuvwxyz",
             "ds-cfg-character-set: 0:ABCDEFGHIJKLMNOPQRSTUVWXYZ",
             "ds-cfg-character-set: 1:0123456789",
             "ds-cfg-min-character-sets: 2",
             "ds-cfg-allow-unclassified-characters: false"),
        "abc123ABC",
        true
      },
      // 3 optional, must have at least two optional.
      new Object[]
      {
        TestCaseUtils.makeEntry(
             "dn: cn=Character Set,cn=Password Validators,cn=config",
             "objectClass: top",
             "objectClass: ds-cfg-password-validator",
             "objectClass: ds-cfg-character-set-password-validator",
             "cn: Character Set",
             "ds-cfg-java-class: org.opends.server.extensions." +
                  "CharacterSetPasswordValidator",
             "ds-cfg-enabled: true",
             "ds-cfg-character-set: 0:abcdefghijklmnopqrstuvwxyz",
             "ds-cfg-character-set: 0:ABCDEFGHIJKLMNOPQRSTUVWXYZ",
             "ds-cfg-character-set: 0:0123456789",
             "ds-cfg-min-character-sets: 2",
             "ds-cfg-allow-unclassified-characters: false"),
        "abcdef",
        false
      },
      // 3 optional, must have at least two optional.
      new Object[]
      {
        TestCaseUtils.makeEntry(
             "dn: cn=Character Set,cn=Password Validators,cn=config",
             "objectClass: top",
             "objectClass: ds-cfg-password-validator",
             "objectClass: ds-cfg-character-set-password-validator",
             "cn: Character Set",
             "ds-cfg-java-class: org.opends.server.extensions." +
                  "CharacterSetPasswordValidator",
             "ds-cfg-enabled: true",
             "ds-cfg-character-set: 0:abcdefghijklmnopqrstuvwxyz",
             "ds-cfg-character-set: 0:ABCDEFGHIJKLMNOPQRSTUVWXYZ",
             "ds-cfg-character-set: 0:0123456789",
             "ds-cfg-min-character-sets: 2",
             "ds-cfg-allow-unclassified-characters: false"),
        "abc123",
        true
      },
      // 3 optional, must have at least two optional.
      new Object[]
      {
        TestCaseUtils.makeEntry(
             "dn: cn=Character Set,cn=Password Validators,cn=config",
             "objectClass: top",
             "objectClass: ds-cfg-password-validator",
             "objectClass: ds-cfg-character-set-password-validator",
             "cn: Character Set",
             "ds-cfg-java-class: org.opends.server.extensions." +
                  "CharacterSetPasswordValidator",
             "ds-cfg-enabled: true",
             "ds-cfg-character-set: 0:abcdefghijklmnopqrstuvwxyz",
             "ds-cfg-character-set: 0:ABCDEFGHIJKLMNOPQRSTUVWXYZ",
             "ds-cfg-character-set: 0:0123456789",
             "ds-cfg-min-character-sets: 2",
             "ds-cfg-allow-unclassified-characters: false"),
        "abc123ABC",
        true
      },
    };
  }