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
010     * trunk/opends/resource/legal-notices/OpenDS.LICENSE
011     * or https://OpenDS.dev.java.net/OpenDS.LICENSE.
012     * See the License for the specific language governing permissions
013     * and limitations under the License.
014     *
015     * When distributing Covered Code, include this CDDL HEADER in each
016     * file and include the License file at
017     * trunk/opends/resource/legal-notices/OpenDS.LICENSE.  If applicable,
018     * add the following below this CDDL HEADER, with the fields enclosed
019     * by brackets "[]" replaced with your own identifying information:
020     *      Portions Copyright [yyyy] [name of copyright owner]
021     *
022     * CDDL HEADER END
023     *
024     *
025     *      Copyright 2006-2008 Sun Microsystems, Inc.
026     */
027    package org.opends.server.plugins;
028    import org.opends.messages.Message;
029    
030    
031    
032    import java.util.ArrayList;
033    import java.util.HashMap;
034    import java.util.HashSet;
035    import java.util.Iterator;
036    import java.util.LinkedHashSet;
037    import java.util.List;
038    import java.util.Set;
039    import java.util.concurrent.CopyOnWriteArrayList;
040    
041    import org.opends.server.admin.server.ConfigurationChangeListener;
042    import org.opends.server.admin.std.meta.PluginCfgDefn;
043    import org.opends.server.admin.std.server.PasswordPolicyImportPluginCfg;
044    import org.opends.server.admin.std.server.PluginCfg;
045    import org.opends.server.api.Backend;
046    import org.opends.server.api.ImportTaskListener;
047    import org.opends.server.api.PasswordStorageScheme;
048    import org.opends.server.api.plugin.DirectoryServerPlugin;
049    import org.opends.server.api.plugin.PluginType;
050    import org.opends.server.api.plugin.PluginResult;
051    import org.opends.server.config.ConfigException;
052    import org.opends.server.core.DirectoryServer;
053    import org.opends.server.core.PasswordPolicy;
054    import org.opends.server.loggers.debug.DebugTracer;
055    import org.opends.server.schema.AuthPasswordSyntax;
056    import org.opends.server.schema.UserPasswordSyntax;
057    import org.opends.server.types.Attribute;
058    import org.opends.server.types.AttributeType;
059    import org.opends.server.types.AttributeValue;
060    import org.opends.server.types.ByteString;
061    import org.opends.server.types.ConfigChangeResult;
062    import org.opends.server.types.DebugLogLevel;
063    import org.opends.server.types.DirectoryException;
064    import org.opends.server.types.DN;
065    import org.opends.server.types.Entry;
066    import org.opends.server.types.LDIFImportConfig;
067    import org.opends.server.types.ResultCode;
068    
069    import static org.opends.server.config.ConfigConstants.*;
070    import static org.opends.server.extensions.ExtensionsConstants.*;
071    import static org.opends.server.loggers.debug.DebugLogger.*;
072    import static org.opends.messages.PluginMessages.*;
073    import static org.opends.server.loggers.ErrorLogger.*;
074    import static org.opends.server.schema.SchemaConstants.*;
075    import static org.opends.server.util.StaticUtils.*;
076    
077    
078    
079    /**
080     * This class implements a Directory Server plugin that performs various
081     * password policy processing during an LDIF import.  In particular, it ensures
082     * that all of the password values are properly encoded before they are stored.
083     */
084    public final class PasswordPolicyImportPlugin
085           extends DirectoryServerPlugin<PasswordPolicyImportPluginCfg>
086           implements ConfigurationChangeListener<PasswordPolicyImportPluginCfg>,
087                      ImportTaskListener
088    {
089      /**
090       * The tracer object for the debug logger.
091       */
092      private static final DebugTracer TRACER = getTracer();
093    
094    
095    
096      // The attribute type used to specify the password policy for an entry.
097      private AttributeType customPolicyAttribute;
098    
099      // The set of attribute types defined in the schema with the auth password
100      // syntax.
101      private AttributeType[] authPasswordTypes;
102    
103      // The set of attribute types defined in the schema with the user password
104      // syntax.
105      private AttributeType[] userPasswordTypes;
106    
107      // The set of password storage schemes to use for the various password
108      // policies defined in the server.
109      private HashMap<DN,PasswordStorageScheme[]> schemesByPolicy;
110    
111      // The default password storage schemes for auth password attributes.
112      private PasswordStorageScheme[] defaultAuthPasswordSchemes;
113    
114      // The default password storage schemes for user password attributes.
115      private PasswordStorageScheme[] defaultUserPasswordSchemes;
116    
117    
118    
119      /**
120       * Creates a new instance of this Directory Server plugin.  Every plugin must
121       * implement a default constructor (it is the only one that will be used to
122       * create plugins defined in the configuration), and every plugin constructor
123       * must call {@code super()} as its first element.
124       */
125      public PasswordPolicyImportPlugin()
126      {
127        super();
128      }
129    
130    
131    
132      /**
133       * {@inheritDoc}
134       */
135      @Override()
136      public final void initializePlugin(Set<PluginType> pluginTypes,
137                             PasswordPolicyImportPluginCfg configuration)
138             throws ConfigException
139      {
140        configuration.addPasswordPolicyImportChangeListener(this);
141    
142        customPolicyAttribute =
143             DirectoryServer.getAttributeType(OP_ATTR_PWPOLICY_POLICY_DN, true);
144    
145    
146        // Make sure that the plugin has been enabled for the appropriate types.
147        for (PluginType t : pluginTypes)
148        {
149          switch (t)
150          {
151            case LDIF_IMPORT:
152              // This is the only acceptable type.
153              break;
154    
155    
156            default:
157              Message message =
158                  ERR_PLUGIN_PWPIMPORT_INVALID_PLUGIN_TYPE.get(t.toString());
159              throw new ConfigException(message);
160          }
161        }
162    
163    
164        // Get the set of default password storage schemes for auth password
165        // attributes.
166        PasswordPolicy defaultPolicy = DirectoryServer.getDefaultPasswordPolicy();
167        Set<DN> authSchemeDNs =
168             configuration.getDefaultAuthPasswordStorageSchemeDNs();
169        if (authSchemeDNs.isEmpty())
170        {
171          if (defaultPolicy.usesAuthPasswordSyntax())
172          {
173            CopyOnWriteArrayList<PasswordStorageScheme> schemeList =
174                 defaultPolicy.getDefaultStorageSchemes();
175            defaultAuthPasswordSchemes =
176                 new PasswordStorageScheme[schemeList.size()];
177            schemeList.toArray(defaultAuthPasswordSchemes);
178          }
179          else
180          {
181            defaultAuthPasswordSchemes = new PasswordStorageScheme[1];
182            defaultAuthPasswordSchemes[0] =
183                 DirectoryServer.getAuthPasswordStorageScheme(
184                      AUTH_PASSWORD_SCHEME_NAME_SALTED_SHA_1);
185            if (defaultAuthPasswordSchemes[0] == null)
186            {
187              Message message = ERR_PLUGIN_PWIMPORT_NO_DEFAULT_AUTH_SCHEMES.get(
188                  AUTH_PASSWORD_SCHEME_NAME_SALTED_SHA_1);
189              throw new ConfigException(message);
190            }
191          }
192        }
193        else
194        {
195          defaultAuthPasswordSchemes =
196               new PasswordStorageScheme[authSchemeDNs.size()];
197          int i=0;
198          for (DN schemeDN : authSchemeDNs)
199          {
200            defaultAuthPasswordSchemes[i] =
201                 DirectoryServer.getPasswordStorageScheme(schemeDN);
202            if (defaultAuthPasswordSchemes[i] == null)
203            {
204              Message message =
205                  ERR_PLUGIN_PWIMPORT_NO_SUCH_DEFAULT_AUTH_SCHEME.get(
206                       String.valueOf(schemeDN));
207              throw new ConfigException(message);
208            }
209            else if (! defaultAuthPasswordSchemes[i].supportsAuthPasswordSyntax())
210            {
211              Message message =
212                  ERR_PLUGIN_PWIMPORT_INVALID_DEFAULT_AUTH_SCHEME.get(
213                       String.valueOf(schemeDN));
214              throw new ConfigException(message);
215            }
216            i++;
217          }
218        }
219    
220    
221        // Get the set of default password storage schemes for user password
222        // attributes.
223        Set<DN> userSchemeDNs =
224             configuration.getDefaultUserPasswordStorageSchemeDNs();
225        if (userSchemeDNs.isEmpty())
226        {
227          if (! defaultPolicy.usesAuthPasswordSyntax())
228          {
229            CopyOnWriteArrayList<PasswordStorageScheme> schemeList =
230                 defaultPolicy.getDefaultStorageSchemes();
231            defaultUserPasswordSchemes =
232                 new PasswordStorageScheme[schemeList.size()];
233            schemeList.toArray(defaultUserPasswordSchemes);
234          }
235          else
236          {
237            defaultUserPasswordSchemes = new PasswordStorageScheme[1];
238            defaultUserPasswordSchemes[0] =
239                 DirectoryServer.getPasswordStorageScheme(
240                      toLowerCase(STORAGE_SCHEME_NAME_SALTED_SHA_1));
241            if (defaultUserPasswordSchemes[0] == null)
242            {
243              Message message = ERR_PLUGIN_PWIMPORT_NO_DEFAULT_USER_SCHEMES.get(
244                  STORAGE_SCHEME_NAME_SALTED_SHA_1);
245              throw new ConfigException(message);
246            }
247          }
248        }
249        else
250        {
251          defaultUserPasswordSchemes =
252               new PasswordStorageScheme[userSchemeDNs.size()];
253          int i=0;
254          for (DN schemeDN : userSchemeDNs)
255          {
256            defaultUserPasswordSchemes[i] =
257                 DirectoryServer.getPasswordStorageScheme(schemeDN);
258            if (defaultUserPasswordSchemes[i] == null)
259            {
260              Message message =
261                  ERR_PLUGIN_PWIMPORT_INVALID_DEFAULT_USER_SCHEME.get(
262                       String.valueOf(schemeDN));
263              throw new ConfigException(message);
264            }
265            i++;
266          }
267        }
268    
269        processImportBegin(null, null);
270      }
271    
272    
273    
274      /**
275       * {@inheritDoc}
276       */
277      public void processImportBegin(Backend backend, LDIFImportConfig config)
278      {
279        // Find the set of attribute types with the auth password and user password
280        // syntax defined in the schema.
281        HashSet<AttributeType> authPWTypes = new HashSet<AttributeType>();
282        HashSet<AttributeType> userPWTypes = new HashSet<AttributeType>();
283        for (AttributeType t : DirectoryServer.getAttributeTypes().values())
284        {
285          if (t.getSyntaxOID().equals(SYNTAX_AUTH_PASSWORD_OID))
286          {
287            authPWTypes.add(t);
288          }
289          else if (t.getSyntaxOID().equals(SYNTAX_USER_PASSWORD_OID))
290          {
291            userPWTypes.add(t);
292          }
293        }
294    
295    
296        // Get the set of password policies defined in the server and get the
297        // attribute types associated with them.
298        HashMap<DN,PasswordStorageScheme[]> schemeMap =
299             new HashMap<DN,PasswordStorageScheme[]>();
300        for (PasswordPolicy p : DirectoryServer.getPasswordPolicies())
301        {
302          CopyOnWriteArrayList<PasswordStorageScheme> schemeList =
303               p.getDefaultStorageSchemes();
304          PasswordStorageScheme[] schemeArray =
305               new PasswordStorageScheme[schemeList.size()];
306          schemeList.toArray(schemeArray);
307          schemeMap.put(p.getConfigEntryDN(), schemeArray);
308        }
309    
310    
311        AttributeType[] authTypesArray = new AttributeType[authPWTypes.size()];
312        AttributeType[] userTypesArray = new AttributeType[userPWTypes.size()];
313        authPWTypes.toArray(authTypesArray);
314        userPWTypes.toArray(userTypesArray);
315    
316        schemesByPolicy   = schemeMap;
317        authPasswordTypes = authTypesArray;
318        userPasswordTypes = userTypesArray;
319      }
320    
321    
322    
323      /**
324       * {@inheritDoc}
325       */
326      public void processImportEnd(Backend backend, LDIFImportConfig config,
327                                   boolean successful)
328      {
329        // No implementation is required.
330      }
331    
332    
333    
334      /**
335       * {@inheritDoc}
336       */
337      @Override()
338      public final PluginResult.ImportLDIF
339                   doLDIFImport(LDIFImportConfig importConfig, Entry entry)
340      {
341        // Create a list that we will use to hold new encoded values.
342        ArrayList<ByteString> encodedValueList = new ArrayList<ByteString>();
343    
344    
345        // See if the entry explicitly states the password policy that it should
346        //  use.  If so, then only use it to perform the encoding.
347        List<Attribute> attrList = entry.getAttribute(customPolicyAttribute);
348        if (attrList != null)
349        {
350          DN policyDN = null;
351          PasswordPolicy policy = null;
352    policyLoop:
353          for (Attribute a : attrList)
354          {
355            for (AttributeValue v : a.getValues())
356            {
357              try
358              {
359                policyDN = DN.decode(v.getValue());
360                policy = DirectoryServer.getPasswordPolicy(policyDN);
361                if (policy == null)
362                {
363                  Message message = WARN_PLUGIN_PWIMPORT_NO_SUCH_POLICY.get(
364                      String.valueOf(entry.getDN()), String.valueOf(policyDN));
365                  logError(message);
366                }
367                break policyLoop;
368              }
369              catch (DirectoryException de)
370              {
371                Message message = WARN_PLUGIN_PWIMPORT_CANNOT_DECODE_POLICY_DN.get(
372                    String.valueOf(entry.getDN()), de.getMessageObject());
373                logError(message);
374                break policyLoop;
375              }
376            }
377          }
378    
379          if (policy != null)
380          {
381            PasswordStorageScheme[] schemes = schemesByPolicy.get(policyDN);
382            if (schemes != null)
383            {
384              attrList = entry.getAttribute(policy.getPasswordAttribute());
385              if (attrList == null)
386              {
387                return PluginResult.ImportLDIF.continueEntryProcessing();
388              }
389    
390              for (Attribute a : attrList)
391              {
392                encodedValueList.clear();
393    
394                LinkedHashSet<AttributeValue> values = a.getValues();
395                Iterator<AttributeValue> iterator = values.iterator();
396                while (iterator.hasNext())
397                {
398                  AttributeValue v = iterator.next();
399                  ByteString value = v.getValue();
400    
401                  if (policy.usesAuthPasswordSyntax())
402                  {
403                    if (! AuthPasswordSyntax.isEncoded(value))
404                    {
405                      try
406                      {
407                        for (PasswordStorageScheme s : schemes)
408                        {
409                          encodedValueList.add(s.encodeAuthPassword(value));
410                        }
411    
412                        iterator.remove();
413                      }
414                      catch (Exception e)
415                      {
416                        if (debugEnabled())
417                        {
418                          TRACER.debugCaught(DebugLogLevel.ERROR, e);
419                        }
420    
421                        Message message =
422                          ERR_PLUGIN_PWPIMPORT_ERROR_ENCODING_PASSWORD.
423                              get(policy.getPasswordAttribute().getNameOrOID(),
424                                  String.valueOf(entry.getDN()),
425                                  stackTraceToSingleLineString(e));
426                        logError(message);
427    
428                        encodedValueList.clear();
429                        break;
430                      }
431                    }
432                  }
433                  else
434                  {
435                    if (! UserPasswordSyntax.isEncoded(value))
436                    {
437                      try
438                      {
439                        for (PasswordStorageScheme s : schemes)
440                        {
441                          encodedValueList.add(s.encodePasswordWithScheme(value));
442                        }
443    
444                        iterator.remove();
445                      }
446                      catch (Exception e)
447                      {
448                        if (debugEnabled())
449                        {
450                          TRACER.debugCaught(DebugLogLevel.ERROR, e);
451                        }
452    
453                        Message message =
454                          ERR_PLUGIN_PWPIMPORT_ERROR_ENCODING_PASSWORD.
455                              get(policy.getPasswordAttribute().getNameOrOID(),
456                                  String.valueOf(entry.getDN()),
457                                  stackTraceToSingleLineString(e));
458                        logError(message);
459    
460                        encodedValueList.clear();
461                        break;
462                      }
463                    }
464                  }
465                }
466    
467                for (ByteString s : encodedValueList)
468                {
469                  values.add(new AttributeValue(policy.getPasswordAttribute(), s));
470                }
471              }
472    
473              return PluginResult.ImportLDIF.continueEntryProcessing();
474            }
475          }
476        }
477    
478    
479        // Iterate through the list of auth password attributes.  If any of them
480        // are present and their values are not encoded, then encode them with all
481        // appropriate schemes.
482        for (AttributeType t : authPasswordTypes)
483        {
484          attrList = entry.getAttribute(t);
485          if ((attrList == null) || attrList.isEmpty())
486          {
487            continue;
488          }
489    
490          for (Attribute a : attrList)
491          {
492            encodedValueList.clear();
493    
494            LinkedHashSet<AttributeValue> values = a.getValues();
495            Iterator<AttributeValue> iterator = values.iterator();
496            while (iterator.hasNext())
497            {
498              AttributeValue v = iterator.next();
499              ByteString value = v.getValue();
500              if (! AuthPasswordSyntax.isEncoded(value))
501              {
502                try
503                {
504                  for (PasswordStorageScheme s : defaultAuthPasswordSchemes)
505                  {
506                    encodedValueList.add(s.encodeAuthPassword(value));
507                  }
508    
509                  iterator.remove();
510                }
511                catch (Exception e)
512                {
513                  if (debugEnabled())
514                  {
515                    TRACER.debugCaught(DebugLogLevel.ERROR, e);
516                  }
517    
518                  Message message = ERR_PLUGIN_PWPIMPORT_ERROR_ENCODING_PASSWORD.
519                      get(t.getNameOrOID(), String.valueOf(entry.getDN()),
520                          stackTraceToSingleLineString(e));
521                  logError(message);
522    
523                  encodedValueList.clear();
524                  break;
525                }
526              }
527            }
528    
529            for (ByteString s : encodedValueList)
530            {
531              values.add(new AttributeValue(t, s));
532            }
533          }
534        }
535    
536    
537        // Iterate through the list of user password attributes.  If any of them
538        // are present and their values are not encoded, then encode them with all
539        // appropriate schemes.
540        for (AttributeType t : userPasswordTypes)
541        {
542          attrList = entry.getAttribute(t);
543          if ((attrList == null) || attrList.isEmpty())
544          {
545            continue;
546          }
547    
548          for (Attribute a : attrList)
549          {
550            encodedValueList.clear();
551    
552            LinkedHashSet<AttributeValue> values = a.getValues();
553            Iterator<AttributeValue> iterator = values.iterator();
554            while (iterator.hasNext())
555            {
556              AttributeValue v = iterator.next();
557              ByteString value = v.getValue();
558              if (! UserPasswordSyntax.isEncoded(value))
559              {
560                try
561                {
562                  for (PasswordStorageScheme s : defaultUserPasswordSchemes)
563                  {
564                    encodedValueList.add(s.encodePasswordWithScheme(value));
565                  }
566    
567                  iterator.remove();
568                }
569                catch (Exception e)
570                {
571                  if (debugEnabled())
572                  {
573                    TRACER.debugCaught(DebugLogLevel.ERROR, e);
574                  }
575    
576                  Message message = ERR_PLUGIN_PWPIMPORT_ERROR_ENCODING_PASSWORD.
577                      get(t.getNameOrOID(), String.valueOf(entry.getDN()),
578                          stackTraceToSingleLineString(e));
579                  logError(message);
580    
581                  encodedValueList.clear();
582                  break;
583                }
584              }
585            }
586    
587            for (ByteString s : encodedValueList)
588            {
589              values.add(new AttributeValue(t, s));
590            }
591          }
592        }
593    
594    
595        return PluginResult.ImportLDIF.continueEntryProcessing();
596      }
597    
598    
599    
600      /**
601       * {@inheritDoc}
602       */
603      @Override()
604      public boolean isConfigurationAcceptable(PluginCfg configuration,
605                                               List<Message> unacceptableReasons)
606      {
607        PasswordPolicyImportPluginCfg config =
608             (PasswordPolicyImportPluginCfg) configuration;
609        return isConfigurationChangeAcceptable(config, unacceptableReasons);
610      }
611    
612    
613    
614      /**
615       * {@inheritDoc}
616       */
617      public boolean isConfigurationChangeAcceptable(
618                          PasswordPolicyImportPluginCfg configuration,
619                          List<Message> unacceptableReasons)
620      {
621        boolean configAcceptable = true;
622    
623        // Ensure that the set of plugin types contains only LDIF import.
624        for (PluginCfgDefn.PluginType pluginType : configuration.getPluginType())
625        {
626          switch (pluginType)
627          {
628            case LDIFIMPORT:
629              // This is the only acceptable type.
630              break;
631    
632    
633            default:
634              Message message = ERR_PLUGIN_PWPIMPORT_INVALID_PLUGIN_TYPE.get(
635                      pluginType.toString());
636              unacceptableReasons.add(message);
637              configAcceptable = false;
638          }
639        }
640    
641    
642        // Get the set of default password storage schemes for auth password
643        // attributes.
644        Set<DN> authSchemeDNs =
645             configuration.getDefaultAuthPasswordStorageSchemeDNs();
646        if (authSchemeDNs.isEmpty())
647        {
648          PasswordStorageScheme[] defaultAuthSchemes = new PasswordStorageScheme[1];
649          defaultAuthSchemes[0] =
650               DirectoryServer.getAuthPasswordStorageScheme(
651                    AUTH_PASSWORD_SCHEME_NAME_SALTED_SHA_1);
652          if (defaultAuthSchemes[0] == null)
653          {
654            Message message = ERR_PLUGIN_PWIMPORT_NO_DEFAULT_AUTH_SCHEMES.get(
655                    AUTH_PASSWORD_SCHEME_NAME_SALTED_SHA_1);
656            unacceptableReasons.add(message);
657            configAcceptable = false;
658          }
659        }
660        else
661        {
662          PasswordStorageScheme[] defaultAuthSchemes =
663               new PasswordStorageScheme[authSchemeDNs.size()];
664          int i=0;
665          for (DN schemeDN : authSchemeDNs)
666          {
667            defaultAuthSchemes[i] =
668                 DirectoryServer.getPasswordStorageScheme(schemeDN);
669            if (defaultAuthSchemes[i] == null)
670            {
671              Message message =
672                  ERR_PLUGIN_PWIMPORT_NO_SUCH_DEFAULT_AUTH_SCHEME.get(
673                       String.valueOf(schemeDN));
674              unacceptableReasons.add(message);
675              configAcceptable = false;
676            }
677            else if (! defaultAuthSchemes[i].supportsAuthPasswordSyntax())
678            {
679              Message message =
680                  ERR_PLUGIN_PWIMPORT_INVALID_DEFAULT_AUTH_SCHEME.get(
681                       String.valueOf(schemeDN));
682              unacceptableReasons.add(message);
683              configAcceptable = false;
684            }
685            i++;
686          }
687        }
688    
689    
690        // Get the set of default password storage schemes for user password
691        // attributes.
692        Set<DN> userSchemeDNs =
693             configuration.getDefaultUserPasswordStorageSchemeDNs();
694        if (userSchemeDNs.isEmpty())
695        {
696          PasswordStorageScheme[] defaultUserSchemes = new PasswordStorageScheme[1];
697          defaultUserSchemes[0] =
698               DirectoryServer.getPasswordStorageScheme(
699                    toLowerCase(STORAGE_SCHEME_NAME_SALTED_SHA_1));
700          if (defaultUserSchemes[0] == null)
701          {
702            Message message = ERR_PLUGIN_PWIMPORT_NO_DEFAULT_USER_SCHEMES.get(
703                    STORAGE_SCHEME_NAME_SALTED_SHA_1);
704            unacceptableReasons.add(message);
705            configAcceptable = false;
706          }
707        }
708        else
709        {
710          PasswordStorageScheme[] defaultUserSchemes =
711               new PasswordStorageScheme[userSchemeDNs.size()];
712          int i=0;
713          for (DN schemeDN : userSchemeDNs)
714          {
715            defaultUserSchemes[i] =
716                 DirectoryServer.getPasswordStorageScheme(schemeDN);
717            if (defaultUserSchemes[i] == null)
718            {
719              Message message = ERR_PLUGIN_PWIMPORT_INVALID_DEFAULT_USER_SCHEME.get(
720                                     String.valueOf(schemeDN));
721              unacceptableReasons.add(message);
722              configAcceptable = false;
723            }
724            i++;
725          }
726        }
727    
728    
729        return configAcceptable;
730      }
731    
732    
733    
734      /**
735       * {@inheritDoc}
736       */
737      public ConfigChangeResult applyConfigurationChange(
738                                     PasswordPolicyImportPluginCfg configuration)
739      {
740        ResultCode        resultCode          = ResultCode.SUCCESS;
741        boolean           adminActionRequired = false;
742        ArrayList<Message> messages            = new ArrayList<Message>();
743    
744    
745        // Get the set of default password storage schemes for auth password
746        // attributes.
747        PasswordPolicy defaultPolicy = DirectoryServer.getDefaultPasswordPolicy();
748        PasswordStorageScheme[] defaultAuthSchemes;
749        Set<DN> authSchemeDNs =
750             configuration.getDefaultAuthPasswordStorageSchemeDNs();
751        if (authSchemeDNs.isEmpty())
752        {
753          if (defaultPolicy.usesAuthPasswordSyntax())
754          {
755            CopyOnWriteArrayList<PasswordStorageScheme> schemeList =
756                 defaultPolicy.getDefaultStorageSchemes();
757            defaultAuthSchemes =
758                 new PasswordStorageScheme[schemeList.size()];
759            schemeList.toArray(defaultAuthSchemes);
760          }
761          else
762          {
763            defaultAuthSchemes = new PasswordStorageScheme[1];
764            defaultAuthSchemes[0] =
765                 DirectoryServer.getAuthPasswordStorageScheme(
766                      AUTH_PASSWORD_SCHEME_NAME_SALTED_SHA_1);
767            if (defaultAuthSchemes[0] == null)
768            {
769              resultCode = DirectoryServer.getServerErrorResultCode();
770    
771              messages.add(ERR_PLUGIN_PWIMPORT_NO_DEFAULT_AUTH_SCHEMES.get(
772                      AUTH_PASSWORD_SCHEME_NAME_SALTED_SHA_1));
773            }
774          }
775        }
776        else
777        {
778          defaultAuthSchemes = new PasswordStorageScheme[authSchemeDNs.size()];
779          int i=0;
780          for (DN schemeDN : authSchemeDNs)
781          {
782            defaultAuthSchemes[i] =
783                 DirectoryServer.getPasswordStorageScheme(schemeDN);
784            if (defaultAuthSchemes[i] == null)
785            {
786              resultCode = DirectoryServer.getServerErrorResultCode();
787    
788              messages.add(
789                   ERR_PLUGIN_PWIMPORT_NO_SUCH_DEFAULT_AUTH_SCHEME.get(
790                        String.valueOf(schemeDN)));
791            }
792            else if (! defaultAuthSchemes[i].supportsAuthPasswordSyntax())
793            {
794              resultCode = DirectoryServer.getServerErrorResultCode();
795    
796              messages.add(
797                   ERR_PLUGIN_PWIMPORT_INVALID_DEFAULT_AUTH_SCHEME.get(
798                        String.valueOf(schemeDN)));
799            }
800            i++;
801          }
802        }
803    
804    
805        // Get the set of default password storage schemes for user password
806        // attributes.
807        PasswordStorageScheme[] defaultUserSchemes;
808        Set<DN> userSchemeDNs =
809             configuration.getDefaultUserPasswordStorageSchemeDNs();
810        if (userSchemeDNs.isEmpty())
811        {
812          if (! defaultPolicy.usesAuthPasswordSyntax())
813          {
814            CopyOnWriteArrayList<PasswordStorageScheme> schemeList =
815                 defaultPolicy.getDefaultStorageSchemes();
816            defaultUserSchemes =
817                 new PasswordStorageScheme[schemeList.size()];
818            schemeList.toArray(defaultUserSchemes);
819          }
820          else
821          {
822            defaultUserSchemes = new PasswordStorageScheme[1];
823            defaultUserSchemes[0] = DirectoryServer.getPasswordStorageScheme(
824                      toLowerCase(STORAGE_SCHEME_NAME_SALTED_SHA_1));
825            if (defaultUserSchemes[0] == null)
826            {
827              resultCode = DirectoryServer.getServerErrorResultCode();
828    
829              messages.add(ERR_PLUGIN_PWIMPORT_NO_DEFAULT_USER_SCHEMES.get(
830                      STORAGE_SCHEME_NAME_SALTED_SHA_1));
831            }
832          }
833        }
834        else
835        {
836          defaultUserSchemes = new PasswordStorageScheme[userSchemeDNs.size()];
837          int i=0;
838          for (DN schemeDN : userSchemeDNs)
839          {
840            defaultUserSchemes[i] =
841                 DirectoryServer.getPasswordStorageScheme(schemeDN);
842            if (defaultUserSchemes[i] == null)
843            {
844              resultCode = DirectoryServer.getServerErrorResultCode();
845    
846              messages.add(ERR_PLUGIN_PWIMPORT_INVALID_DEFAULT_USER_SCHEME.get(
847                                String.valueOf(schemeDN)));
848            }
849            i++;
850          }
851        }
852    
853        if (resultCode == ResultCode.SUCCESS)
854        {
855          defaultAuthPasswordSchemes = defaultAuthSchemes;
856          defaultUserPasswordSchemes = defaultUserSchemes;
857        }
858    
859        return new ConfigChangeResult(resultCode, adminActionRequired, messages);
860      }
861    }
862