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