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  /**
210   * {@inheritDoc}
211   */
212  public DictionaryPasswordValidatorCfgClient createClientConfiguration(
213      ManagedObject<? extends DictionaryPasswordValidatorCfgClient> impl) {
214    return new DictionaryPasswordValidatorCfgClientImpl(impl);
215  }
216
217
218
219  /**
220   * {@inheritDoc}
221   */
222  public DictionaryPasswordValidatorCfg createServerConfiguration(
223      ServerManagedObject<? extends DictionaryPasswordValidatorCfg> impl) {
224    return new DictionaryPasswordValidatorCfgServerImpl(impl);
225  }
226
227
228
229  /**
230   * {@inheritDoc}
231   */
232  public Class<DictionaryPasswordValidatorCfg> getServerConfigurationClass() {
233    return DictionaryPasswordValidatorCfg.class;
234  }
235
236
237
238  /**
239   * Get the "case-sensitive-validation" property definition.
240   * <p>
241   * Indicates whether this password validator is to treat password
242   * characters in a case-sensitive manner.
243   * <p>
244   * If it is set to true, then the validator rejects a password only
245   * if it appears in the dictionary with exactly the same
246   * capitalization as provided by the user.
247   *
248   * @return Returns the "case-sensitive-validation" property definition.
249   */
250  public BooleanPropertyDefinition getCaseSensitiveValidationPropertyDefinition() {
251    return PD_CASE_SENSITIVE_VALIDATION;
252  }
253
254
255
256  /**
257   * Get the "check-substrings" property definition.
258   * <p>
259   * Indicates whether this password validator is to match portions of
260   * the password string against dictionary words.
261   * <p>
262   * If "false" then only match the entire password against words
263   * otherwise ("true") check whether the password contains words.
264   *
265   * @return Returns the "check-substrings" property definition.
266   */
267  public BooleanPropertyDefinition getCheckSubstringsPropertyDefinition() {
268    return PD_CHECK_SUBSTRINGS;
269  }
270
271
272
273  /**
274   * Get the "dictionary-file" property definition.
275   * <p>
276   * Specifies the path to the file containing a list of words that
277   * cannot be used as passwords.
278   * <p>
279   * It should be formatted with one word per line. The value can be
280   * an absolute path or a path that is relative to the OpenDJ instance
281   * root.
282   *
283   * @return Returns the "dictionary-file" property definition.
284   */
285  public StringPropertyDefinition getDictionaryFilePropertyDefinition() {
286    return PD_DICTIONARY_FILE;
287  }
288
289
290
291  /**
292   * Get the "enabled" property definition.
293   * <p>
294   * Indicates whether the password validator is enabled for use.
295   *
296   * @return Returns the "enabled" property definition.
297   */
298  public BooleanPropertyDefinition getEnabledPropertyDefinition() {
299    return PasswordValidatorCfgDefn.getInstance().getEnabledPropertyDefinition();
300  }
301
302
303
304  /**
305   * Get the "java-class" property definition.
306   * <p>
307   * Specifies the fully-qualified name of the Java class that
308   * provides the password validator implementation.
309   *
310   * @return Returns the "java-class" property definition.
311   */
312  public ClassPropertyDefinition getJavaClassPropertyDefinition() {
313    return PD_JAVA_CLASS;
314  }
315
316
317
318  /**
319   * Get the "min-substring-length" property definition.
320   * <p>
321   * Indicates the minimal length of the substring within the password
322   * in case substring checking is enabled.
323   * <p>
324   * If "check-substrings" option is set to true, then this parameter
325   * defines the length of the smallest word which should be used for
326   * substring matching. Use with caution because values below 3 might
327   * disqualify valid passwords.
328   *
329   * @return Returns the "min-substring-length" property definition.
330   */
331  public IntegerPropertyDefinition getMinSubstringLengthPropertyDefinition() {
332    return PD_MIN_SUBSTRING_LENGTH;
333  }
334
335
336
337  /**
338   * Get the "test-reversed-password" property definition.
339   * <p>
340   * Indicates whether this password validator is to test the reversed
341   * value of the provided password as well as the order in which it
342   * was given.
343   * <p>
344   * For example, if the user provides a new password of "password"
345   * and this configuration attribute is set to true, then the value
346   * "drowssap" is also tested against attribute values in the user's
347   * entry.
348   *
349   * @return Returns the "test-reversed-password" property definition.
350   */
351  public BooleanPropertyDefinition getTestReversedPasswordPropertyDefinition() {
352    return PD_TEST_REVERSED_PASSWORD;
353  }
354
355
356
357  /**
358   * Managed object client implementation.
359   */
360  private static class DictionaryPasswordValidatorCfgClientImpl implements
361    DictionaryPasswordValidatorCfgClient {
362
363    // Private implementation.
364    private ManagedObject<? extends DictionaryPasswordValidatorCfgClient> impl;
365
366
367
368    // Private constructor.
369    private DictionaryPasswordValidatorCfgClientImpl(
370        ManagedObject<? extends DictionaryPasswordValidatorCfgClient> impl) {
371      this.impl = impl;
372    }
373
374
375
376    /**
377     * {@inheritDoc}
378     */
379    public boolean isCaseSensitiveValidation() {
380      return impl.getPropertyValue(INSTANCE.getCaseSensitiveValidationPropertyDefinition());
381    }
382
383
384
385    /**
386     * {@inheritDoc}
387     */
388    public void setCaseSensitiveValidation(boolean value) {
389      impl.setPropertyValue(INSTANCE.getCaseSensitiveValidationPropertyDefinition(), value);
390    }
391
392
393
394    /**
395     * {@inheritDoc}
396     */
397    public boolean isCheckSubstrings() {
398      return impl.getPropertyValue(INSTANCE.getCheckSubstringsPropertyDefinition());
399    }
400
401
402
403    /**
404     * {@inheritDoc}
405     */
406    public void setCheckSubstrings(Boolean value) {
407      impl.setPropertyValue(INSTANCE.getCheckSubstringsPropertyDefinition(), value);
408    }
409
410
411
412    /**
413     * {@inheritDoc}
414     */
415    public String getDictionaryFile() {
416      return impl.getPropertyValue(INSTANCE.getDictionaryFilePropertyDefinition());
417    }
418
419
420
421    /**
422     * {@inheritDoc}
423     */
424    public void setDictionaryFile(String value) {
425      impl.setPropertyValue(INSTANCE.getDictionaryFilePropertyDefinition(), value);
426    }
427
428
429
430    /**
431     * {@inheritDoc}
432     */
433    public Boolean isEnabled() {
434      return impl.getPropertyValue(INSTANCE.getEnabledPropertyDefinition());
435    }
436
437
438
439    /**
440     * {@inheritDoc}
441     */
442    public void setEnabled(boolean value) {
443      impl.setPropertyValue(INSTANCE.getEnabledPropertyDefinition(), value);
444    }
445
446
447
448    /**
449     * {@inheritDoc}
450     */
451    public String getJavaClass() {
452      return impl.getPropertyValue(INSTANCE.getJavaClassPropertyDefinition());
453    }
454
455
456
457    /**
458     * {@inheritDoc}
459     */
460    public void setJavaClass(String value) {
461      impl.setPropertyValue(INSTANCE.getJavaClassPropertyDefinition(), value);
462    }
463
464
465
466    /**
467     * {@inheritDoc}
468     */
469    public int getMinSubstringLength() {
470      return impl.getPropertyValue(INSTANCE.getMinSubstringLengthPropertyDefinition());
471    }
472
473
474
475    /**
476     * {@inheritDoc}
477     */
478    public void setMinSubstringLength(Integer value) {
479      impl.setPropertyValue(INSTANCE.getMinSubstringLengthPropertyDefinition(), value);
480    }
481
482
483
484    /**
485     * {@inheritDoc}
486     */
487    public boolean isTestReversedPassword() {
488      return impl.getPropertyValue(INSTANCE.getTestReversedPasswordPropertyDefinition());
489    }
490
491
492
493    /**
494     * {@inheritDoc}
495     */
496    public void setTestReversedPassword(boolean value) {
497      impl.setPropertyValue(INSTANCE.getTestReversedPasswordPropertyDefinition(), value);
498    }
499
500
501
502    /**
503     * {@inheritDoc}
504     */
505    public ManagedObjectDefinition<? extends DictionaryPasswordValidatorCfgClient, ? extends DictionaryPasswordValidatorCfg> definition() {
506      return INSTANCE;
507    }
508
509
510
511    /**
512     * {@inheritDoc}
513     */
514    public PropertyProvider properties() {
515      return impl;
516    }
517
518
519
520    /**
521     * {@inheritDoc}
522     */
523    public void commit() throws ManagedObjectAlreadyExistsException,
524        MissingMandatoryPropertiesException, ConcurrentModificationException,
525        OperationRejectedException, LdapException {
526      impl.commit();
527    }
528
529  }
530
531
532
533  /**
534   * Managed object server implementation.
535   */
536  private static class DictionaryPasswordValidatorCfgServerImpl implements
537    DictionaryPasswordValidatorCfg {
538
539    // Private implementation.
540    private ServerManagedObject<? extends DictionaryPasswordValidatorCfg> impl;
541
542    // The value of the "case-sensitive-validation" property.
543    private final boolean pCaseSensitiveValidation;
544
545    // The value of the "check-substrings" property.
546    private final boolean pCheckSubstrings;
547
548    // The value of the "dictionary-file" property.
549    private final String pDictionaryFile;
550
551    // The value of the "enabled" property.
552    private final boolean pEnabled;
553
554    // The value of the "java-class" property.
555    private final String pJavaClass;
556
557    // The value of the "min-substring-length" property.
558    private final int pMinSubstringLength;
559
560    // The value of the "test-reversed-password" property.
561    private final boolean pTestReversedPassword;
562
563
564
565    // Private constructor.
566    private DictionaryPasswordValidatorCfgServerImpl(ServerManagedObject<? extends DictionaryPasswordValidatorCfg> impl) {
567      this.impl = impl;
568      this.pCaseSensitiveValidation = impl.getPropertyValue(INSTANCE.getCaseSensitiveValidationPropertyDefinition());
569      this.pCheckSubstrings = impl.getPropertyValue(INSTANCE.getCheckSubstringsPropertyDefinition());
570      this.pDictionaryFile = impl.getPropertyValue(INSTANCE.getDictionaryFilePropertyDefinition());
571      this.pEnabled = impl.getPropertyValue(INSTANCE.getEnabledPropertyDefinition());
572      this.pJavaClass = impl.getPropertyValue(INSTANCE.getJavaClassPropertyDefinition());
573      this.pMinSubstringLength = impl.getPropertyValue(INSTANCE.getMinSubstringLengthPropertyDefinition());
574      this.pTestReversedPassword = impl.getPropertyValue(INSTANCE.getTestReversedPasswordPropertyDefinition());
575    }
576
577
578
579    /**
580     * {@inheritDoc}
581     */
582    public void addDictionaryChangeListener(
583        ConfigurationChangeListener<DictionaryPasswordValidatorCfg> listener) {
584      impl.registerChangeListener(listener);
585    }
586
587
588
589    /**
590     * {@inheritDoc}
591     */
592    public void removeDictionaryChangeListener(
593        ConfigurationChangeListener<DictionaryPasswordValidatorCfg> listener) {
594      impl.deregisterChangeListener(listener);
595    }
596    /**
597     * {@inheritDoc}
598     */
599    public void addChangeListener(
600        ConfigurationChangeListener<PasswordValidatorCfg> listener) {
601      impl.registerChangeListener(listener);
602    }
603
604
605
606    /**
607     * {@inheritDoc}
608     */
609    public void removeChangeListener(
610        ConfigurationChangeListener<PasswordValidatorCfg> listener) {
611      impl.deregisterChangeListener(listener);
612    }
613
614
615
616    /**
617     * {@inheritDoc}
618     */
619    public boolean isCaseSensitiveValidation() {
620      return pCaseSensitiveValidation;
621    }
622
623
624
625    /**
626     * {@inheritDoc}
627     */
628    public boolean isCheckSubstrings() {
629      return pCheckSubstrings;
630    }
631
632
633
634    /**
635     * {@inheritDoc}
636     */
637    public String getDictionaryFile() {
638      return pDictionaryFile;
639    }
640
641
642
643    /**
644     * {@inheritDoc}
645     */
646    public boolean isEnabled() {
647      return pEnabled;
648    }
649
650
651
652    /**
653     * {@inheritDoc}
654     */
655    public String getJavaClass() {
656      return pJavaClass;
657    }
658
659
660
661    /**
662     * {@inheritDoc}
663     */
664    public int getMinSubstringLength() {
665      return pMinSubstringLength;
666    }
667
668
669
670    /**
671     * {@inheritDoc}
672     */
673    public boolean isTestReversedPassword() {
674      return pTestReversedPassword;
675    }
676
677
678
679    /**
680     * {@inheritDoc}
681     */
682    public Class<? extends DictionaryPasswordValidatorCfg> configurationClass() {
683      return DictionaryPasswordValidatorCfg.class;
684    }
685
686
687
688    /**
689     * {@inheritDoc}
690     */
691    public DN dn() {
692      return impl.getDN();
693    }
694
695  }
696}