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}