001/* 002 * CDDL HEADER START 003 * 004 * The contents of this file are subject to the terms of the 005 * Common Development and Distribution License, Version 1.0 only 006 * (the "License"). You may not use this file except in compliance 007 * with the License. 008 * 009 * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt 010 * or http://forgerock.org/license/CDDLv1.0.html. 011 * See the License for the specific language governing permissions 012 * and limitations under the License. 013 * 014 * When distributing Covered Code, include this CDDL HEADER in each 015 * file and include the License file at legal-notices/CDDLv1_0.txt. 016 * If applicable, add the following below this CDDL HEADER, with the 017 * fields enclosed by brackets "[]" replaced with your own identifying 018 * information: 019 * Portions Copyright [yyyy] [name of copyright owner] 020 * 021 * CDDL HEADER END 022 * 023 * 024 * Copyright 2008 Sun Microsystems, Inc. 025 */ 026package org.forgerock.opendj.server.config.meta; 027 028 029 030import org.forgerock.opendj.config.AdministratorAction; 031import org.forgerock.opendj.config.BooleanPropertyDefinition; 032import org.forgerock.opendj.config.ClassPropertyDefinition; 033import org.forgerock.opendj.config.client.ConcurrentModificationException; 034import org.forgerock.opendj.config.client.ManagedObject; 035import org.forgerock.opendj.config.client.MissingMandatoryPropertiesException; 036import org.forgerock.opendj.config.client.OperationRejectedException; 037import org.forgerock.opendj.config.DefaultBehaviorProvider; 038import org.forgerock.opendj.config.DefinedDefaultBehaviorProvider; 039import org.forgerock.opendj.config.IntegerPropertyDefinition; 040import org.forgerock.opendj.config.ManagedObjectAlreadyExistsException; 041import org.forgerock.opendj.config.ManagedObjectDefinition; 042import org.forgerock.opendj.config.PropertyOption; 043import org.forgerock.opendj.config.PropertyProvider; 044import org.forgerock.opendj.config.server.ConfigurationChangeListener; 045import org.forgerock.opendj.config.server.ServerManagedObject; 046import org.forgerock.opendj.config.StringPropertyDefinition; 047import org.forgerock.opendj.config.Tag; 048import org.forgerock.opendj.ldap.DN; 049import org.forgerock.opendj.ldap.LdapException; 050import org.forgerock.opendj.server.config.client.DictionaryPasswordValidatorCfgClient; 051import org.forgerock.opendj.server.config.server.DictionaryPasswordValidatorCfg; 052import org.forgerock.opendj.server.config.server.PasswordValidatorCfg; 053 054 055 056/** 057 * An interface for querying the Dictionary Password Validator managed 058 * object definition meta information. 059 * <p> 060 * The Dictionary Password Validator determines whether a proposed 061 * password is acceptable based on whether the given password value 062 * appears in a provided dictionary file. 063 */ 064public final class DictionaryPasswordValidatorCfgDefn extends ManagedObjectDefinition<DictionaryPasswordValidatorCfgClient, DictionaryPasswordValidatorCfg> { 065 066 /** The singleton configuration definition instance. */ 067 private static final DictionaryPasswordValidatorCfgDefn INSTANCE = new DictionaryPasswordValidatorCfgDefn(); 068 069 070 071 /** The "case-sensitive-validation" property definition. */ 072 private static final BooleanPropertyDefinition PD_CASE_SENSITIVE_VALIDATION; 073 074 075 076 /** The "check-substrings" property definition. */ 077 private static final BooleanPropertyDefinition PD_CHECK_SUBSTRINGS; 078 079 080 081 /** The "dictionary-file" property definition. */ 082 private static final StringPropertyDefinition PD_DICTIONARY_FILE; 083 084 085 086 /** The "java-class" property definition. */ 087 private static final ClassPropertyDefinition PD_JAVA_CLASS; 088 089 090 091 /** The "min-substring-length" property definition. */ 092 private static final IntegerPropertyDefinition PD_MIN_SUBSTRING_LENGTH; 093 094 095 096 /** The "test-reversed-password" property definition. */ 097 private static final BooleanPropertyDefinition PD_TEST_REVERSED_PASSWORD; 098 099 100 101 /** Build the "case-sensitive-validation" property definition. */ 102 static { 103 BooleanPropertyDefinition.Builder builder = BooleanPropertyDefinition.createBuilder(INSTANCE, "case-sensitive-validation"); 104 builder.setOption(PropertyOption.MANDATORY); 105 builder.setAdministratorAction(new AdministratorAction(AdministratorAction.Type.NONE, INSTANCE, "case-sensitive-validation")); 106 DefaultBehaviorProvider<Boolean> provider = new DefinedDefaultBehaviorProvider<Boolean>("false"); 107 builder.setDefaultBehaviorProvider(provider); 108 PD_CASE_SENSITIVE_VALIDATION = builder.getInstance(); 109 INSTANCE.registerPropertyDefinition(PD_CASE_SENSITIVE_VALIDATION); 110 } 111 112 113 114 /** Build the "check-substrings" property definition. */ 115 static { 116 BooleanPropertyDefinition.Builder builder = BooleanPropertyDefinition.createBuilder(INSTANCE, "check-substrings"); 117 builder.setAdministratorAction(new AdministratorAction(AdministratorAction.Type.NONE, INSTANCE, "check-substrings")); 118 DefaultBehaviorProvider<Boolean> provider = new DefinedDefaultBehaviorProvider<Boolean>("true"); 119 builder.setDefaultBehaviorProvider(provider); 120 PD_CHECK_SUBSTRINGS = builder.getInstance(); 121 INSTANCE.registerPropertyDefinition(PD_CHECK_SUBSTRINGS); 122 } 123 124 125 126 /** Build the "dictionary-file" property definition. */ 127 static { 128 StringPropertyDefinition.Builder builder = StringPropertyDefinition.createBuilder(INSTANCE, "dictionary-file"); 129 builder.setOption(PropertyOption.MANDATORY); 130 builder.setAdministratorAction(new AdministratorAction(AdministratorAction.Type.NONE, INSTANCE, "dictionary-file")); 131 DefaultBehaviorProvider<String> provider = new DefinedDefaultBehaviorProvider<String>("For Unix and Linux systems: config/wordlist.txt. For Windows systems: config\\wordlist.txt"); 132 builder.setDefaultBehaviorProvider(provider); 133 builder.setPattern(".*", "FILE"); 134 PD_DICTIONARY_FILE = builder.getInstance(); 135 INSTANCE.registerPropertyDefinition(PD_DICTIONARY_FILE); 136 } 137 138 139 140 /** Build the "java-class" property definition. */ 141 static { 142 ClassPropertyDefinition.Builder builder = ClassPropertyDefinition.createBuilder(INSTANCE, "java-class"); 143 builder.setOption(PropertyOption.MANDATORY); 144 builder.setOption(PropertyOption.ADVANCED); 145 builder.setAdministratorAction(new AdministratorAction(AdministratorAction.Type.COMPONENT_RESTART, INSTANCE, "java-class")); 146 DefaultBehaviorProvider<String> provider = new DefinedDefaultBehaviorProvider<String>("org.opends.server.extensions.DictionaryPasswordValidator"); 147 builder.setDefaultBehaviorProvider(provider); 148 builder.addInstanceOf("org.opends.server.api.PasswordValidator"); 149 PD_JAVA_CLASS = builder.getInstance(); 150 INSTANCE.registerPropertyDefinition(PD_JAVA_CLASS); 151 } 152 153 154 155 /** Build the "min-substring-length" property definition. */ 156 static { 157 IntegerPropertyDefinition.Builder builder = IntegerPropertyDefinition.createBuilder(INSTANCE, "min-substring-length"); 158 builder.setAdministratorAction(new AdministratorAction(AdministratorAction.Type.NONE, INSTANCE, "min-substring-length")); 159 DefaultBehaviorProvider<Integer> provider = new DefinedDefaultBehaviorProvider<Integer>("5"); 160 builder.setDefaultBehaviorProvider(provider); 161 PD_MIN_SUBSTRING_LENGTH = builder.getInstance(); 162 INSTANCE.registerPropertyDefinition(PD_MIN_SUBSTRING_LENGTH); 163 } 164 165 166 167 /** Build the "test-reversed-password" property definition. */ 168 static { 169 BooleanPropertyDefinition.Builder builder = BooleanPropertyDefinition.createBuilder(INSTANCE, "test-reversed-password"); 170 builder.setOption(PropertyOption.MANDATORY); 171 builder.setAdministratorAction(new AdministratorAction(AdministratorAction.Type.NONE, INSTANCE, "test-reversed-password")); 172 DefaultBehaviorProvider<Boolean> provider = new DefinedDefaultBehaviorProvider<Boolean>("true"); 173 builder.setDefaultBehaviorProvider(provider); 174 PD_TEST_REVERSED_PASSWORD = builder.getInstance(); 175 INSTANCE.registerPropertyDefinition(PD_TEST_REVERSED_PASSWORD); 176 } 177 178 179 180 // Register the tags associated with this managed object definition. 181 static { 182 INSTANCE.registerTag(Tag.valueOf("user-management")); 183 } 184 185 186 187 /** 188 * Get the Dictionary Password Validator configuration definition 189 * singleton. 190 * 191 * @return Returns the Dictionary Password Validator configuration 192 * definition singleton. 193 */ 194 public static DictionaryPasswordValidatorCfgDefn getInstance() { 195 return INSTANCE; 196 } 197 198 199 200 /** 201 * Private constructor. 202 */ 203 private DictionaryPasswordValidatorCfgDefn() { 204 super("dictionary-password-validator", PasswordValidatorCfgDefn.getInstance()); 205 } 206 207 208 209 /** {@inheritDoc} */ 210 public DictionaryPasswordValidatorCfgClient createClientConfiguration( 211 ManagedObject<? extends DictionaryPasswordValidatorCfgClient> impl) { 212 return new DictionaryPasswordValidatorCfgClientImpl(impl); 213 } 214 215 216 217 /** {@inheritDoc} */ 218 public DictionaryPasswordValidatorCfg createServerConfiguration( 219 ServerManagedObject<? extends DictionaryPasswordValidatorCfg> impl) { 220 return new DictionaryPasswordValidatorCfgServerImpl(impl); 221 } 222 223 224 225 /** {@inheritDoc} */ 226 public Class<DictionaryPasswordValidatorCfg> getServerConfigurationClass() { 227 return DictionaryPasswordValidatorCfg.class; 228 } 229 230 231 232 /** 233 * Get the "case-sensitive-validation" property definition. 234 * <p> 235 * Indicates whether this password validator is to treat password 236 * characters in a case-sensitive manner. 237 * <p> 238 * If it is set to true, then the validator rejects a password only 239 * if it appears in the dictionary with exactly the same 240 * capitalization as provided by the user. 241 * 242 * @return Returns the "case-sensitive-validation" property definition. 243 */ 244 public BooleanPropertyDefinition getCaseSensitiveValidationPropertyDefinition() { 245 return PD_CASE_SENSITIVE_VALIDATION; 246 } 247 248 249 250 /** 251 * Get the "check-substrings" property definition. 252 * <p> 253 * Indicates whether this password validator is to match portions of 254 * the password string against dictionary words. 255 * <p> 256 * If "false" then only match the entire password against words 257 * otherwise ("true") check whether the password contains words. 258 * 259 * @return Returns the "check-substrings" property definition. 260 */ 261 public BooleanPropertyDefinition getCheckSubstringsPropertyDefinition() { 262 return PD_CHECK_SUBSTRINGS; 263 } 264 265 266 267 /** 268 * Get the "dictionary-file" property definition. 269 * <p> 270 * Specifies the path to the file containing a list of words that 271 * cannot be used as passwords. 272 * <p> 273 * It should be formatted with one word per line. The value can be 274 * an absolute path or a path that is relative to the OpenDJ instance 275 * root. 276 * 277 * @return Returns the "dictionary-file" property definition. 278 */ 279 public StringPropertyDefinition getDictionaryFilePropertyDefinition() { 280 return PD_DICTIONARY_FILE; 281 } 282 283 284 285 /** 286 * Get the "enabled" property definition. 287 * <p> 288 * Indicates whether the password validator is enabled for use. 289 * 290 * @return Returns the "enabled" property definition. 291 */ 292 public BooleanPropertyDefinition getEnabledPropertyDefinition() { 293 return PasswordValidatorCfgDefn.getInstance().getEnabledPropertyDefinition(); 294 } 295 296 297 298 /** 299 * Get the "java-class" property definition. 300 * <p> 301 * Specifies the fully-qualified name of the Java class that 302 * provides the password validator implementation. 303 * 304 * @return Returns the "java-class" property definition. 305 */ 306 public ClassPropertyDefinition getJavaClassPropertyDefinition() { 307 return PD_JAVA_CLASS; 308 } 309 310 311 312 /** 313 * Get the "min-substring-length" property definition. 314 * <p> 315 * Indicates the minimal length of the substring within the password 316 * in case substring checking is enabled. 317 * <p> 318 * If "check-substrings" option is set to true, then this parameter 319 * defines the length of the smallest word which should be used for 320 * substring matching. Use with caution because values below 3 might 321 * disqualify valid passwords. 322 * 323 * @return Returns the "min-substring-length" property definition. 324 */ 325 public IntegerPropertyDefinition getMinSubstringLengthPropertyDefinition() { 326 return PD_MIN_SUBSTRING_LENGTH; 327 } 328 329 330 331 /** 332 * Get the "test-reversed-password" property definition. 333 * <p> 334 * Indicates whether this password validator is to test the reversed 335 * value of the provided password as well as the order in which it 336 * was given. 337 * <p> 338 * For example, if the user provides a new password of "password" 339 * and this configuration attribute is set to true, then the value 340 * "drowssap" is also tested against attribute values in the user's 341 * entry. 342 * 343 * @return Returns the "test-reversed-password" property definition. 344 */ 345 public BooleanPropertyDefinition getTestReversedPasswordPropertyDefinition() { 346 return PD_TEST_REVERSED_PASSWORD; 347 } 348 349 350 351 /** 352 * Managed object client implementation. 353 */ 354 private static class DictionaryPasswordValidatorCfgClientImpl implements 355 DictionaryPasswordValidatorCfgClient { 356 357 /** Private implementation. */ 358 private ManagedObject<? extends DictionaryPasswordValidatorCfgClient> impl; 359 360 361 362 /** Private constructor. */ 363 private DictionaryPasswordValidatorCfgClientImpl( 364 ManagedObject<? extends DictionaryPasswordValidatorCfgClient> impl) { 365 this.impl = impl; 366 } 367 368 369 370 /** {@inheritDoc} */ 371 public boolean isCaseSensitiveValidation() { 372 return impl.getPropertyValue(INSTANCE.getCaseSensitiveValidationPropertyDefinition()); 373 } 374 375 376 377 /** {@inheritDoc} */ 378 public void setCaseSensitiveValidation(boolean value) { 379 impl.setPropertyValue(INSTANCE.getCaseSensitiveValidationPropertyDefinition(), value); 380 } 381 382 383 384 /** {@inheritDoc} */ 385 public boolean isCheckSubstrings() { 386 return impl.getPropertyValue(INSTANCE.getCheckSubstringsPropertyDefinition()); 387 } 388 389 390 391 /** {@inheritDoc} */ 392 public void setCheckSubstrings(Boolean value) { 393 impl.setPropertyValue(INSTANCE.getCheckSubstringsPropertyDefinition(), value); 394 } 395 396 397 398 /** {@inheritDoc} */ 399 public String getDictionaryFile() { 400 return impl.getPropertyValue(INSTANCE.getDictionaryFilePropertyDefinition()); 401 } 402 403 404 405 /** {@inheritDoc} */ 406 public void setDictionaryFile(String value) { 407 impl.setPropertyValue(INSTANCE.getDictionaryFilePropertyDefinition(), value); 408 } 409 410 411 412 /** {@inheritDoc} */ 413 public Boolean isEnabled() { 414 return impl.getPropertyValue(INSTANCE.getEnabledPropertyDefinition()); 415 } 416 417 418 419 /** {@inheritDoc} */ 420 public void setEnabled(boolean value) { 421 impl.setPropertyValue(INSTANCE.getEnabledPropertyDefinition(), value); 422 } 423 424 425 426 /** {@inheritDoc} */ 427 public String getJavaClass() { 428 return impl.getPropertyValue(INSTANCE.getJavaClassPropertyDefinition()); 429 } 430 431 432 433 /** {@inheritDoc} */ 434 public void setJavaClass(String value) { 435 impl.setPropertyValue(INSTANCE.getJavaClassPropertyDefinition(), value); 436 } 437 438 439 440 /** {@inheritDoc} */ 441 public int getMinSubstringLength() { 442 return impl.getPropertyValue(INSTANCE.getMinSubstringLengthPropertyDefinition()); 443 } 444 445 446 447 /** {@inheritDoc} */ 448 public void setMinSubstringLength(Integer value) { 449 impl.setPropertyValue(INSTANCE.getMinSubstringLengthPropertyDefinition(), value); 450 } 451 452 453 454 /** {@inheritDoc} */ 455 public boolean isTestReversedPassword() { 456 return impl.getPropertyValue(INSTANCE.getTestReversedPasswordPropertyDefinition()); 457 } 458 459 460 461 /** {@inheritDoc} */ 462 public void setTestReversedPassword(boolean value) { 463 impl.setPropertyValue(INSTANCE.getTestReversedPasswordPropertyDefinition(), value); 464 } 465 466 467 468 /** {@inheritDoc} */ 469 public ManagedObjectDefinition<? extends DictionaryPasswordValidatorCfgClient, ? extends DictionaryPasswordValidatorCfg> definition() { 470 return INSTANCE; 471 } 472 473 474 475 /** {@inheritDoc} */ 476 public PropertyProvider properties() { 477 return impl; 478 } 479 480 481 482 /** {@inheritDoc} */ 483 public void commit() throws ManagedObjectAlreadyExistsException, 484 MissingMandatoryPropertiesException, ConcurrentModificationException, 485 OperationRejectedException, LdapException { 486 impl.commit(); 487 } 488 489 490 491 /** {@inheritDoc} */ 492 public String toString() { 493 return impl.toString(); 494 } 495 } 496 497 498 499 /** 500 * Managed object server implementation. 501 */ 502 private static class DictionaryPasswordValidatorCfgServerImpl implements 503 DictionaryPasswordValidatorCfg { 504 505 /** Private implementation. */ 506 private ServerManagedObject<? extends DictionaryPasswordValidatorCfg> impl; 507 508 /** The value of the "case-sensitive-validation" property. */ 509 private final boolean pCaseSensitiveValidation; 510 511 /** The value of the "check-substrings" property. */ 512 private final boolean pCheckSubstrings; 513 514 /** The value of the "dictionary-file" property. */ 515 private final String pDictionaryFile; 516 517 /** The value of the "enabled" property. */ 518 private final boolean pEnabled; 519 520 /** The value of the "java-class" property. */ 521 private final String pJavaClass; 522 523 /** The value of the "min-substring-length" property. */ 524 private final int pMinSubstringLength; 525 526 /** The value of the "test-reversed-password" property. */ 527 private final boolean pTestReversedPassword; 528 529 530 531 /** Private constructor. */ 532 private DictionaryPasswordValidatorCfgServerImpl(ServerManagedObject<? extends DictionaryPasswordValidatorCfg> impl) { 533 this.impl = impl; 534 this.pCaseSensitiveValidation = impl.getPropertyValue(INSTANCE.getCaseSensitiveValidationPropertyDefinition()); 535 this.pCheckSubstrings = impl.getPropertyValue(INSTANCE.getCheckSubstringsPropertyDefinition()); 536 this.pDictionaryFile = impl.getPropertyValue(INSTANCE.getDictionaryFilePropertyDefinition()); 537 this.pEnabled = impl.getPropertyValue(INSTANCE.getEnabledPropertyDefinition()); 538 this.pJavaClass = impl.getPropertyValue(INSTANCE.getJavaClassPropertyDefinition()); 539 this.pMinSubstringLength = impl.getPropertyValue(INSTANCE.getMinSubstringLengthPropertyDefinition()); 540 this.pTestReversedPassword = impl.getPropertyValue(INSTANCE.getTestReversedPasswordPropertyDefinition()); 541 } 542 543 544 545 /** {@inheritDoc} */ 546 public void addDictionaryChangeListener( 547 ConfigurationChangeListener<DictionaryPasswordValidatorCfg> listener) { 548 impl.registerChangeListener(listener); 549 } 550 551 552 553 /** {@inheritDoc} */ 554 public void removeDictionaryChangeListener( 555 ConfigurationChangeListener<DictionaryPasswordValidatorCfg> listener) { 556 impl.deregisterChangeListener(listener); 557 } 558 /** {@inheritDoc} */ 559 public void addChangeListener( 560 ConfigurationChangeListener<PasswordValidatorCfg> listener) { 561 impl.registerChangeListener(listener); 562 } 563 564 565 566 /** {@inheritDoc} */ 567 public void removeChangeListener( 568 ConfigurationChangeListener<PasswordValidatorCfg> listener) { 569 impl.deregisterChangeListener(listener); 570 } 571 572 573 574 /** {@inheritDoc} */ 575 public boolean isCaseSensitiveValidation() { 576 return pCaseSensitiveValidation; 577 } 578 579 580 581 /** {@inheritDoc} */ 582 public boolean isCheckSubstrings() { 583 return pCheckSubstrings; 584 } 585 586 587 588 /** {@inheritDoc} */ 589 public String getDictionaryFile() { 590 return pDictionaryFile; 591 } 592 593 594 595 /** {@inheritDoc} */ 596 public boolean isEnabled() { 597 return pEnabled; 598 } 599 600 601 602 /** {@inheritDoc} */ 603 public String getJavaClass() { 604 return pJavaClass; 605 } 606 607 608 609 /** {@inheritDoc} */ 610 public int getMinSubstringLength() { 611 return pMinSubstringLength; 612 } 613 614 615 616 /** {@inheritDoc} */ 617 public boolean isTestReversedPassword() { 618 return pTestReversedPassword; 619 } 620 621 622 623 /** {@inheritDoc} */ 624 public Class<? extends DictionaryPasswordValidatorCfg> configurationClass() { 625 return DictionaryPasswordValidatorCfg.class; 626 } 627 628 629 630 /** {@inheritDoc} */ 631 public DN dn() { 632 return impl.getDN(); 633 } 634 635 636 637 /** {@inheritDoc} */ 638 public String toString() { 639 return impl.toString(); 640 } 641 } 642}