From feb5d90ec016c99712f19c5485cf7633cd38f111 Mon Sep 17 00:00:00 2001
From: matthew_swift <matthew_swift@localhost>
Date: Fri, 23 Mar 2007 14:26:04 +0000
Subject: [PATCH] Merge admin framework from config-prototype-branch onto trunk.

---
 opends/src/server/org/opends/server/extensions/GSSAPISASLMechanismHandler.java |  906 ++++++++++++--------------------------------------------
 1 files changed, 198 insertions(+), 708 deletions(-)

diff --git a/opends/src/server/org/opends/server/extensions/GSSAPISASLMechanismHandler.java b/opends/src/server/org/opends/server/extensions/GSSAPISASLMechanismHandler.java
index f9a7480..aba77e2 100644
--- a/opends/src/server/org/opends/server/extensions/GSSAPISASLMechanismHandler.java
+++ b/opends/src/server/org/opends/server/extensions/GSSAPISASLMechanismHandler.java
@@ -33,18 +33,14 @@
 import java.io.FileWriter;
 import java.net.InetAddress;
 import java.util.ArrayList;
-import java.util.LinkedList;
 import java.util.List;
 
+import org.opends.server.admin.server.ConfigurationChangeListener;
+import org.opends.server.admin.std.server.GSSAPISASLMechanismHandlerCfg;
 import org.opends.server.api.ClientConnection;
-import org.opends.server.api.ConfigurableComponent;
 import org.opends.server.api.IdentityMapper;
 import org.opends.server.api.SASLMechanismHandler;
-import org.opends.server.config.ConfigAttribute;
-import org.opends.server.config.ConfigEntry;
 import org.opends.server.config.ConfigException;
-import org.opends.server.config.DNConfigAttribute;
-import org.opends.server.config.StringConfigAttribute;
 import org.opends.server.core.BindOperation;
 import org.opends.server.core.DirectoryServer;
 import org.opends.server.types.AuthenticationInfo;
@@ -55,7 +51,6 @@
 import org.opends.server.types.InitializationException;
 import org.opends.server.types.ResultCode;
 
-import static org.opends.server.config.ConfigConstants.*;
 import static org.opends.server.loggers.debug.DebugLogger.debugCaught;
 import static org.opends.server.loggers.debug.DebugLogger.debugEnabled;
 import org.opends.server.types.DebugLogLevel;
@@ -71,33 +66,21 @@
  * clients through Kerberos over GSSAPI.
  */
 public class GSSAPISASLMechanismHandler
-       extends SASLMechanismHandler
-       implements ConfigurableComponent
+       extends SASLMechanismHandler<GSSAPISASLMechanismHandlerCfg>
+       implements ConfigurationChangeListener<
+                       GSSAPISASLMechanismHandlerCfg>
 {
-
-
-
   // The DN of the configuration entry for this SASL mechanism handler.
   private DN configEntryDN;
 
-  // The DN of the identity mapper configuration entry.
-  private DN identityMapperDN;
+  // The current configuration for this SASL mechanism handler.
+  private GSSAPISASLMechanismHandlerCfg currentConfig;
 
   // The identity mapper that will be used to map the Kerberos principal to a
   // directory user.
   private IdentityMapper identityMapper;
 
-  // The address of the KDC to use for Kerberos authentication.
-  private String kdcAddress;
-
-  // The path to the keytab file to use to obtain the server key.
-  private String keyTabFile;
-
-  // The default realm to use for Kerberos authentication.
-  private String realm;
-
-  // The fully-qualified DNS name to use for the Directory Server system.  This
-  // is factored into the authentication process.
+  // The fully-qualified domain name for the server system.
   private String serverFQDN;
 
 
@@ -110,7 +93,6 @@
   public GSSAPISASLMechanismHandler()
   {
     super();
-
   }
 
 
@@ -119,183 +101,50 @@
    * {@inheritDoc}
    */
   @Override()
-  public void initializeSASLMechanismHandler(ConfigEntry configEntry)
+  public void initializeSASLMechanismHandler(
+                   GSSAPISASLMechanismHandlerCfg configuration)
          throws ConfigException, InitializationException
   {
-    this.configEntryDN = configEntry.getDN();
+    configuration.addGSSAPIChangeListener(this);
+
+    currentConfig = configuration;
+    configEntryDN = configuration.dn();
 
 
     // Get the identity mapper that should be used to find users.
-    int msgID = MSGID_SASLGSSAPI_DESCRIPTION_IDENTITY_MAPPER_DN;
-    DNConfigAttribute mapperStub =
-         new DNConfigAttribute(ATTR_IDMAPPER_DN, getMessage(msgID), true, false,
-                               false);
-    try
+    DN identityMapperDN = configuration.getIdentityMapperDN();
+    identityMapper = DirectoryServer.getIdentityMapper(identityMapperDN);
+    if (identityMapper == null)
     {
-      DNConfigAttribute mapperAttr =
-           (DNConfigAttribute) configEntry.getConfigAttribute(mapperStub);
-      if (mapperAttr == null)
-      {
-        msgID = MSGID_SASLGSSAPI_NO_IDENTITY_MAPPER_ATTR;
-        String message = getMessage(msgID, String.valueOf(configEntryDN));
-        throw new ConfigException(msgID, message);
-      }
-      else
-      {
-        identityMapperDN = mapperAttr.activeValue();
-        identityMapper = DirectoryServer.getIdentityMapper(identityMapperDN);
-        if (identityMapper == null)
-        {
-          msgID = MSGID_SASLGSSAPI_NO_SUCH_IDENTITY_MAPPER;
-          String message = getMessage(msgID, String.valueOf(identityMapperDN),
-                                      String.valueOf(configEntryDN));
-          throw new ConfigException(msgID, message);
-        }
-      }
-    }
-    catch (ConfigException ce)
-    {
-      throw ce;
-    }
-    catch (Exception e)
-    {
-      if (debugEnabled())
-      {
-        debugCaught(DebugLogLevel.ERROR, e);
-      }
-
-      msgID = MSGID_SASLGSSAPI_CANNOT_GET_IDENTITY_MAPPER;
-      String message = getMessage(msgID, String.valueOf(configEntryDN),
-                                  stackTraceToSingleLineString(e));
-      throw new InitializationException(msgID, message, e);
+      int    msgID   = MSGID_SASLGSSAPI_NO_SUCH_IDENTITY_MAPPER;
+      String message = getMessage(msgID, String.valueOf(identityMapperDN),
+                                  String.valueOf(configEntryDN));
+      throw new ConfigException(msgID, message);
     }
 
 
     // Determine the fully-qualified hostname for this system.  It may be
     // provided, but if not, then try to determine it programmatically.
-    msgID = MSGID_SASLGSSAPI_DESCRIPTION_SERVER_FQDN;
-    StringConfigAttribute serverFQDNStub =
-         new StringConfigAttribute(ATTR_SERVER_FQDN, getMessage(msgID), false,
-                                false, false);
-    try
+    serverFQDN = configuration.getServerFqdn();
+    if (serverFQDN == null)
     {
-      StringConfigAttribute serverFQDNAttr =
-           (StringConfigAttribute)
-           configEntry.getConfigAttribute(serverFQDNStub);
-      if (serverFQDNAttr == null)
+      try
       {
-        // No value was provided, so try to figure it out for ourselves.
         serverFQDN = InetAddress.getLocalHost().getCanonicalHostName();
       }
-      else
+      catch (Exception e)
       {
-        serverFQDN = serverFQDNAttr.activeValue();
+        if (debugEnabled())
+        {
+          debugCaught(DebugLogLevel.ERROR, e);
+        }
+
+        int    msgID   = MSGID_SASLGSSAPI_CANNOT_GET_SERVER_FQDN;
+        String message = getMessage(msgID, String.valueOf(configEntryDN),
+                                    stackTraceToSingleLineString(e));
+        throw new InitializationException(msgID, message, e);
       }
     }
-    catch (Exception e)
-    {
-      if (debugEnabled())
-      {
-        debugCaught(DebugLogLevel.ERROR, e);
-      }
-
-      msgID = MSGID_SASLGSSAPI_CANNOT_GET_SERVER_FQDN;
-      String message = getMessage(msgID, String.valueOf(configEntryDN),
-                                  stackTraceToSingleLineString(e));
-      throw new InitializationException(msgID, message, e);
-    }
-
-
-    // Determine the address of the KDC to use.  If it is not provided, then
-    // we'll assume that the underlying OS has a valid config file.
-    kdcAddress = null;
-    msgID = MSGID_SASLGSSAPI_DESCRIPTION_KDC_ADDRESS;
-    StringConfigAttribute kdcStub =
-         new StringConfigAttribute(ATTR_GSSAPI_KDC, getMessage(msgID), false,
-                                   false, false);
-    try
-    {
-      StringConfigAttribute kdcAttr =
-           (StringConfigAttribute) configEntry.getConfigAttribute(kdcStub);
-      if (kdcAttr != null)
-      {
-        kdcAddress = kdcAttr.activeValue();
-        System.setProperty(KRBV_PROPERTY_KDC, kdcAddress);
-      }
-    }
-    catch (Exception e)
-    {
-      if (debugEnabled())
-      {
-        debugCaught(DebugLogLevel.ERROR, e);
-      }
-
-      msgID = MSGID_SASLGSSAPI_CANNOT_GET_KDC_ADDRESS;
-      String message = getMessage(msgID, String.valueOf(configEntryDN),
-                                  stackTraceToSingleLineString(e));
-      throw new InitializationException(msgID, message, e);
-    }
-
-
-    // Determine the default realm to use.  If it is not provided, then we'll
-    // assume that the underlying OS has a valid config file.
-    realm = null;
-    msgID = MSGID_SASLGSSAPI_DESCRIPTION_REALM;
-    StringConfigAttribute realmStub =
-         new StringConfigAttribute(ATTR_GSSAPI_REALM, getMessage(msgID), false,
-                                   false, false);
-    try
-    {
-      StringConfigAttribute realmAttr =
-           (StringConfigAttribute) configEntry.getConfigAttribute(realmStub);
-      if (realmAttr != null)
-      {
-        realm = realmAttr.activeValue();
-        System.setProperty(KRBV_PROPERTY_REALM, realm);
-      }
-    }
-    catch (Exception e)
-    {
-      if (debugEnabled())
-      {
-        debugCaught(DebugLogLevel.ERROR, e);
-      }
-
-      msgID = MSGID_SASLGSSAPI_CANNOT_GET_REALM;
-      String message = getMessage(msgID, String.valueOf(configEntryDN),
-                                  stackTraceToSingleLineString(e));
-      throw new InitializationException(msgID, message, e);
-    }
-
-
-    // Determine the path of the keytab file to use.  If it is not provided,
-    // then we'll let Java use the system default keytab.
-    keyTabFile = null;
-    msgID = MSGID_SASLGSSAPI_DESCRIPTION_KEYTAB_FILE;
-    StringConfigAttribute keyTabStub =
-         new StringConfigAttribute(ATTR_GSSAPI_KEYTAB_FILE, getMessage(msgID),
-                                   false, false, false);
-    try
-    {
-      StringConfigAttribute keyTabAttr =
-           (StringConfigAttribute) configEntry.getConfigAttribute(keyTabStub);
-      if (keyTabAttr != null)
-      {
-        keyTabFile = keyTabAttr.activeValue();
-      }
-    }
-    catch (Exception e)
-    {
-      if (debugEnabled())
-      {
-        debugCaught(DebugLogLevel.ERROR, e);
-      }
-
-      msgID = MSGID_SASLGSSAPI_CANNOT_GET_KEYTAB_FILE;
-      String message = getMessage(msgID, String.valueOf(configEntryDN),
-                                  stackTraceToSingleLineString(e));
-      throw new InitializationException(msgID, message, e);
-    }
 
 
     // Since we're going to be using JAAS behind the scenes, we need to have a
@@ -316,6 +165,7 @@
       w.write("  com.sun.security.auth.module.Krb5LoginModule required " +
               "storeKey=true useKeyTab=true ");
 
+      String keyTabFile = configuration.getKeytab();
       if (keyTabFile != null)
       {
         w.write("keyTab=\"" + keyTabFile + "\" ");
@@ -325,6 +175,8 @@
 
       // FIXME -- Can we get away from hard-coding a protocol here?
       w.write("principal=\"ldap/" + serverFQDN);
+
+      String realm = configuration.getRealm();
       if (realm != null)
       {
         w.write("@" + realm);
@@ -341,7 +193,12 @@
     }
     catch (Exception e)
     {
-      msgID = MSGID_SASLGSSAPI_CANNOT_CREATE_JAAS_CONFIG;
+      if (debugEnabled())
+      {
+        debugCaught(DebugLogLevel.ERROR, e);
+      }
+
+      int    msgID   = MSGID_SASLGSSAPI_CANNOT_CREATE_JAAS_CONFIG;
       String message = getMessage(msgID, stackTraceToSingleLineString(e));
       throw new InitializationException(msgID, message, e);
     }
@@ -351,7 +208,6 @@
 
 
     DirectoryServer.registerSASLMechanismHandler(SASL_MECHANISM_GSSAPI, this);
-    DirectoryServer.registerConfigurableComponent(this);
   }
 
 
@@ -362,7 +218,7 @@
   @Override()
   public void finalizeSASLMechanismHandler()
   {
-    DirectoryServer.deregisterConfigurableComponent(this);
+    currentConfig.removeGSSAPIChangeListener(this);
     DirectoryServer.deregisterSASLMechanismHandler(SASL_MECHANISM_GSSAPI);
   }
 
@@ -489,526 +345,6 @@
 
 
   /**
-   * Retrieves the DN of the configuration entry with which this component is
-   * associated.
-   *
-   * @return  The DN of the configuration entry with which this component is
-   *          associated.
-   */
-  public DN getConfigurableComponentEntryDN()
-  {
-    return configEntryDN;
-  }
-
-
-
-
-  /**
-   * Retrieves the set of configuration attributes that are associated with this
-   * configurable component.
-   *
-   * @return  The set of configuration attributes that are associated with this
-   *          configurable component.
-   */
-  public List<ConfigAttribute> getConfigurationAttributes()
-  {
-    LinkedList<ConfigAttribute> attrList = new LinkedList<ConfigAttribute>();
-
-    int msgID = MSGID_SASLGSSAPI_DESCRIPTION_IDENTITY_MAPPER_DN;
-    attrList.add(new DNConfigAttribute(ATTR_IDMAPPER_DN, getMessage(msgID),
-                                       true, false, false, identityMapperDN));
-
-    msgID = MSGID_SASLGSSAPI_DESCRIPTION_SERVER_FQDN;
-    attrList.add(new StringConfigAttribute(ATTR_SERVER_FQDN, getMessage(msgID),
-                                           false, false, false, serverFQDN));
-
-    msgID = MSGID_SASLGSSAPI_DESCRIPTION_KDC_ADDRESS;
-    attrList.add(new StringConfigAttribute(ATTR_GSSAPI_KDC, getMessage(msgID),
-                                           false, false, false, kdcAddress));
-
-    msgID = MSGID_SASLGSSAPI_DESCRIPTION_REALM;
-    attrList.add(new StringConfigAttribute(ATTR_GSSAPI_REALM, getMessage(msgID),
-                                           false, false, false, realm));
-
-    return attrList;
-  }
-
-
-
-  /**
-   * Indicates whether the provided configuration entry has an acceptable
-   * configuration for this component.  If it does not, then detailed
-   * information about the problem(s) should be added to the provided list.
-   *
-   * @param  configEntry          The configuration entry for which to make the
-   *                              determination.
-   * @param  unacceptableReasons  A list that can be used to hold messages about
-   *                              why the provided entry does not have an
-   *                              acceptable configuration.
-   *
-   * @return  <CODE>true</CODE> if the provided entry has an acceptable
-   *          configuration for this component, or <CODE>false</CODE> if not.
-   */
-  public boolean hasAcceptableConfiguration(ConfigEntry configEntry,
-                                            List<String> unacceptableReasons)
-  {
-    // Look at the identity mapper configuration
-    int msgID = MSGID_SASLGSSAPI_DESCRIPTION_IDENTITY_MAPPER_DN;
-    DNConfigAttribute mapperStub =
-         new DNConfigAttribute(ATTR_IDMAPPER_DN, getMessage(msgID), true, false,
-                               false);
-    try
-    {
-      DNConfigAttribute mapperAttr =
-           (DNConfigAttribute) configEntry.getConfigAttribute(mapperStub);
-      if (mapperAttr == null)
-      {
-        msgID = MSGID_SASLGSSAPI_NO_IDENTITY_MAPPER_ATTR;
-        String message = getMessage(msgID, String.valueOf(configEntryDN));
-        unacceptableReasons.add(message);
-        return false;
-      }
-      else
-      {
-        DN mapperDN = mapperAttr.activeValue();
-        IdentityMapper mapper =
-             DirectoryServer.getIdentityMapper(mapperDN);
-        if (mapper == null)
-        {
-          msgID = MSGID_SASLGSSAPI_NO_SUCH_IDENTITY_MAPPER;
-          String message = getMessage(msgID, String.valueOf(mapperDN),
-                                      String.valueOf(configEntryDN));
-          unacceptableReasons.add(message);
-          return false;
-        }
-      }
-    }
-    catch (Exception e)
-    {
-      if (debugEnabled())
-      {
-        debugCaught(DebugLogLevel.ERROR, e);
-      }
-
-      msgID = MSGID_SASLGSSAPI_CANNOT_GET_IDENTITY_MAPPER;
-      String message = getMessage(msgID, String.valueOf(configEntryDN),
-                                  stackTraceToSingleLineString(e));
-      unacceptableReasons.add(message);
-      return false;
-    }
-
-
-    // Look a the server FQDN configuration.
-    msgID = MSGID_SASLGSSAPI_DESCRIPTION_SERVER_FQDN;
-    StringConfigAttribute serverFQDNStub  =
-         new StringConfigAttribute(ATTR_SERVER_FQDN, getMessage(msgID), false,
-                                   false, false);
-    try
-    {
-      StringConfigAttribute serverFQDNAttr =
-           (StringConfigAttribute)
-           configEntry.getConfigAttribute(serverFQDNStub);
-
-      // FIXME -- Should we try to resolve the value if one is provided?
-    }
-    catch (Exception e)
-    {
-      if (debugEnabled())
-      {
-        debugCaught(DebugLogLevel.ERROR, e);
-      }
-
-      msgID = MSGID_SASLGSSAPI_CANNOT_GET_SERVER_FQDN;
-      unacceptableReasons.add(getMessage(msgID, String.valueOf(configEntryDN),
-                                         stackTraceToSingleLineString(e)));
-      return false;
-    }
-
-
-    // Look at the KDC configuration.
-    msgID = MSGID_SASLGSSAPI_DESCRIPTION_KDC_ADDRESS;
-    StringConfigAttribute kdcStub =
-         new StringConfigAttribute(ATTR_GSSAPI_KDC, getMessage(msgID), false,
-                                   false, false);
-    try
-    {
-      StringConfigAttribute kdcAttr =
-           (StringConfigAttribute) configEntry.getConfigAttribute(kdcStub);
-    }
-    catch (Exception e)
-    {
-      if (debugEnabled())
-      {
-        debugCaught(DebugLogLevel.ERROR, e);
-      }
-
-      msgID = MSGID_SASLGSSAPI_CANNOT_GET_KDC_ADDRESS;
-      unacceptableReasons.add(getMessage(msgID, String.valueOf(configEntryDN),
-                                         stackTraceToSingleLineString(e)));
-      return false;
-    }
-
-
-    // Look at the realm configuration.
-    msgID = MSGID_SASLGSSAPI_DESCRIPTION_REALM;
-    StringConfigAttribute realmStub =
-         new StringConfigAttribute(ATTR_GSSAPI_REALM, getMessage(msgID), false,
-                                   false, false);
-    try
-    {
-      StringConfigAttribute realmAttr =
-           (StringConfigAttribute) configEntry.getConfigAttribute(realmStub);
-    }
-    catch (Exception e)
-    {
-      if (debugEnabled())
-      {
-        debugCaught(DebugLogLevel.ERROR, e);
-      }
-
-      msgID = MSGID_SASLGSSAPI_CANNOT_GET_REALM;
-      unacceptableReasons.add(getMessage(msgID, String.valueOf(configEntryDN),
-                                         stackTraceToSingleLineString(e)));
-      return false;
-    }
-
-
-    // If we've gotten to this point, then everything must be OK.
-    return true;
-  }
-
-
-
-  /**
-   * Makes a best-effort attempt to apply the configuration contained in the
-   * provided entry.  Information about the result of this processing should be
-   * added to the provided message list.  Information should always be added to
-   * this list if a configuration change could not be applied.  If detailed
-   * results are requested, then information about the changes applied
-   * successfully (and optionally about parameters that were not changed) should
-   * also be included.
-   *
-   * @param  configEntry      The entry containing the new configuration to
-   *                          apply for this component.
-   * @param  detailedResults  Indicates whether detailed information about the
-   *                          processing should be added to the list.
-   *
-   * @return  Information about the result of the configuration update.
-   */
-  public ConfigChangeResult applyNewConfiguration(ConfigEntry configEntry,
-                                                  boolean detailedResults)
-  {
-    ResultCode        resultCode          = ResultCode.SUCCESS;
-    boolean           adminActionRequired = false;
-    ArrayList<String> messages            = new ArrayList<String>();
-
-
-    // Look at the identity mapper configuration
-    DN             newIdentityMapperDN = null;
-    IdentityMapper newIdentityMapper   = null;
-    int msgID = MSGID_SASLGSSAPI_DESCRIPTION_IDENTITY_MAPPER_DN;
-    DNConfigAttribute mapperStub =
-         new DNConfigAttribute(ATTR_IDMAPPER_DN, getMessage(msgID), true, false,
-                               false);
-    try
-    {
-      DNConfigAttribute mapperAttr =
-           (DNConfigAttribute) configEntry.getConfigAttribute(mapperStub);
-      if (mapperAttr == null)
-      {
-        msgID = MSGID_SASLGSSAPI_NO_IDENTITY_MAPPER_ATTR;
-        messages.add(getMessage(msgID, String.valueOf(configEntryDN)));
-
-        if (resultCode == ResultCode.SUCCESS)
-        {
-          resultCode = ResultCode.OBJECTCLASS_VIOLATION;
-        }
-      }
-      else
-      {
-        newIdentityMapperDN = mapperAttr.activeValue();
-        newIdentityMapper =
-             DirectoryServer.getIdentityMapper(newIdentityMapperDN);
-        if (newIdentityMapper == null)
-        {
-          msgID = MSGID_SASLGSSAPI_NO_SUCH_IDENTITY_MAPPER;
-          messages.add(getMessage(msgID, String.valueOf(newIdentityMapperDN),
-                                  String.valueOf(configEntryDN)));
-
-          if (resultCode == ResultCode.SUCCESS)
-          {
-            resultCode = ResultCode.CONSTRAINT_VIOLATION;
-          }
-        }
-      }
-    }
-    catch (Exception e)
-    {
-      if (debugEnabled())
-      {
-        debugCaught(DebugLogLevel.ERROR, e);
-      }
-
-      msgID = MSGID_SASLGSSAPI_CANNOT_GET_IDENTITY_MAPPER;
-      messages.add(getMessage(msgID, String.valueOf(configEntryDN),
-                              stackTraceToSingleLineString(e)));
-
-      if (resultCode == ResultCode.SUCCESS)
-      {
-        resultCode = DirectoryServer.getServerErrorResultCode();
-      }
-    }
-
-
-    // Look at the server FQDN configuration.
-    String newServerFQDN = null;
-    msgID = MSGID_SASLGSSAPI_DESCRIPTION_SERVER_FQDN;
-    StringConfigAttribute serverFQDNStub  =
-         new StringConfigAttribute(ATTR_SERVER_FQDN, getMessage(msgID), false,
-                                   false, false);
-    try
-    {
-      StringConfigAttribute serverFQDNAttr =
-           (StringConfigAttribute)
-           configEntry.getConfigAttribute(serverFQDNStub);
-      if (serverFQDNAttr == null)
-      {
-        newServerFQDN = InetAddress.getLocalHost().getCanonicalHostName();
-      }
-      else
-      {
-        newServerFQDN = serverFQDNAttr.pendingValue();
-      }
-    }
-    catch (Exception e)
-    {
-      if (debugEnabled())
-      {
-        debugCaught(DebugLogLevel.ERROR, e);
-      }
-
-      msgID = MSGID_SASLGSSAPI_CANNOT_GET_SERVER_FQDN;
-      messages.add(getMessage(msgID, String.valueOf(configEntryDN),
-                              stackTraceToSingleLineString(e)));
-
-      if (resultCode == ResultCode.SUCCESS)
-      {
-        resultCode = DirectoryServer.getServerErrorResultCode();
-      }
-    }
-
-
-    // Look at the KDC configuration.
-    String newKDC = null;
-    msgID = MSGID_SASLGSSAPI_DESCRIPTION_KDC_ADDRESS;
-    StringConfigAttribute kdcStub =
-         new StringConfigAttribute(ATTR_GSSAPI_KDC, getMessage(msgID), false,
-                                   false, false);
-    try
-    {
-      StringConfigAttribute kdcAttr =
-           (StringConfigAttribute) configEntry.getConfigAttribute(kdcStub);
-      if (kdcAttr != null)
-      {
-        newKDC = kdcAttr.pendingValue();
-      }
-    }
-    catch (Exception e)
-    {
-      if (debugEnabled())
-      {
-        debugCaught(DebugLogLevel.ERROR, e);
-      }
-
-      msgID = MSGID_SASLGSSAPI_CANNOT_GET_KDC_ADDRESS;
-      messages.add(getMessage(msgID, String.valueOf(configEntryDN),
-                              stackTraceToSingleLineString(e)));
-
-      if (resultCode == ResultCode.SUCCESS)
-      {
-        resultCode = DirectoryServer.getServerErrorResultCode();
-      }
-    }
-
-
-    // Look at the realm configuration.
-    String newRealm = null;
-    msgID = MSGID_SASLGSSAPI_DESCRIPTION_REALM;
-    StringConfigAttribute realmStub =
-         new StringConfigAttribute(ATTR_GSSAPI_REALM, getMessage(msgID), false,
-                                   false, false);
-    try
-    {
-      StringConfigAttribute realmAttr =
-           (StringConfigAttribute) configEntry.getConfigAttribute(realmStub);
-      if (realmAttr != null)
-      {
-        newRealm = realmAttr.pendingValue();
-      }
-    }
-    catch (Exception e)
-    {
-      if (debugEnabled())
-      {
-        debugCaught(DebugLogLevel.ERROR, e);
-      }
-
-      msgID = MSGID_SASLGSSAPI_CANNOT_GET_REALM;
-      messages.add(getMessage(msgID, String.valueOf(configEntryDN),
-                              stackTraceToSingleLineString(e)));
-
-      if (resultCode == ResultCode.SUCCESS)
-      {
-        resultCode = DirectoryServer.getServerErrorResultCode();
-      }
-    }
-
-
-    // If everything has been successful, then apply any changes that were made.
-    if (resultCode == ResultCode.SUCCESS)
-    {
-      if (! identityMapperDN.equals(newIdentityMapperDN))
-      {
-        identityMapperDN = newIdentityMapperDN;
-        identityMapper   = newIdentityMapper;
-
-        if (detailedResults)
-        {
-          msgID = MSGID_SASLGSSAPI_UPDATED_IDENTITY_MAPPER;
-          messages.add(getMessage(msgID, String.valueOf(configEntryDN),
-                                  String.valueOf(identityMapperDN)));
-        }
-      }
-
-      if (serverFQDN == null)
-      {
-        if (newServerFQDN != null)
-        {
-          serverFQDN = newServerFQDN;
-
-          if (detailedResults)
-          {
-            msgID = MSGID_SASLGSSAPI_UPDATED_NEW_SERVER_FQDN;
-            messages.add(getMessage(msgID, String.valueOf(configEntryDN),
-                                    String.valueOf(serverFQDN)));
-          }
-        }
-      }
-      else if (newServerFQDN == null)
-      {
-        serverFQDN = null;
-
-        if (detailedResults)
-        {
-          msgID = MSGID_SASLGSSAPI_UPDATED_NO_SERVER_FQDN;
-          messages.add(getMessage(msgID, String.valueOf(configEntryDN)));
-        }
-      }
-      else
-      {
-        if (! serverFQDN.equals(newServerFQDN))
-        {
-          serverFQDN = newServerFQDN;
-
-          if (detailedResults)
-          {
-            msgID = MSGID_SASLGSSAPI_UPDATED_NEW_SERVER_FQDN;
-            messages.add(getMessage(msgID, String.valueOf(configEntryDN),
-                                    String.valueOf(serverFQDN)));
-          }
-        }
-      }
-
-      if (kdcAddress == null)
-      {
-        if (newKDC != null)
-        {
-          kdcAddress = newKDC;
-          System.setProperty(KRBV_PROPERTY_KDC, kdcAddress);
-
-          if (detailedResults)
-          {
-            msgID = MSGID_SASLGSSAPI_UPDATED_KDC;
-            messages.add(getMessage(msgID, String.valueOf(configEntryDN),
-                                    String.valueOf(kdcAddress)));
-          }
-        }
-      }
-      else
-      {
-        if (newKDC == null)
-        {
-          kdcAddress = null;
-          System.clearProperty(KRBV_PROPERTY_KDC);
-
-          if (detailedResults)
-          {
-            msgID = MSGID_SASLGSSAPI_UNSET_KDC;
-            messages.add(getMessage(msgID, String.valueOf(configEntryDN)));
-          }
-        }
-        else if (! kdcAddress.equals(newKDC))
-        {
-          kdcAddress = newKDC;
-          System.setProperty(KRBV_PROPERTY_KDC, kdcAddress);
-
-          if (detailedResults)
-          {
-            msgID = MSGID_SASLGSSAPI_UPDATED_KDC;
-            messages.add(getMessage(msgID, String.valueOf(kdcAddress)));
-          }
-        }
-      }
-
-      if (realm == null)
-      {
-        if (newRealm != null)
-        {
-          realm = newRealm;
-          System.setProperty(KRBV_PROPERTY_REALM, realm);
-
-          if (detailedResults)
-          {
-            msgID = MSGID_SASLGSSAPI_UPDATED_REALM;
-            messages.add(getMessage(msgID, String.valueOf(realm)));
-          }
-        }
-      }
-      else
-      {
-        if (newRealm == null)
-        {
-          realm = null;
-          System.clearProperty(KRBV_PROPERTY_REALM);
-
-          if (detailedResults)
-          {
-            msgID = MSGID_SASLGSSAPI_UNSET_REALM;
-            messages.add(getMessage(msgID));
-          }
-        }
-        else if (! realm.equals(newRealm))
-        {
-          realm = newRealm;
-          System.setProperty(KRBV_PROPERTY_REALM, realm);
-
-          if (detailedResults)
-          {
-            msgID = MSGID_SASLGSSAPI_UPDATED_REALM;
-            messages.add(getMessage(msgID, String.valueOf(realm)));
-          }
-        }
-      }
-    }
-
-
-    // Return the result to the caller.
-    return new ConfigChangeResult(resultCode, adminActionRequired, messages);
-  }
-
-
-
-  /**
    * {@inheritDoc}
    */
   @Override()
@@ -1029,5 +365,159 @@
     // This may be considered a secure mechanism.
     return true;
   }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  public boolean isConfigurationChangeAcceptable(
+                      GSSAPISASLMechanismHandlerCfg configuration,
+                      List<String> unacceptableReasons)
+  {
+    boolean configAcceptable = true;
+
+    // Get the identity mapper that should be used to find users.
+    DN identityMapperDN = configuration.getIdentityMapperDN();
+    IdentityMapper newIdentityMapper =
+         DirectoryServer.getIdentityMapper(identityMapperDN);
+    if (newIdentityMapper == null)
+    {
+      int msgID = MSGID_SASLGSSAPI_NO_SUCH_IDENTITY_MAPPER;
+      unacceptableReasons.add(getMessage(msgID,
+                                         String.valueOf(identityMapperDN),
+                                         String.valueOf(configEntryDN)));
+      configAcceptable = false;
+    }
+
+
+    return configAcceptable;
+  }
+
+
+
+  /**
+   * {@inheritDoc}
+   */
+  public ConfigChangeResult applyConfigurationChange(
+              GSSAPISASLMechanismHandlerCfg configuration)
+  {
+    ResultCode        resultCode          = ResultCode.SUCCESS;
+    boolean           adminActionRequired = false;
+    ArrayList<String> messages            = new ArrayList<String>();
+
+
+    // Get the identity mapper that should be used to find users.
+    DN identityMapperDN = configuration.getIdentityMapperDN();
+    IdentityMapper newIdentityMapper =
+         DirectoryServer.getIdentityMapper(identityMapperDN);
+    if (newIdentityMapper == null)
+    {
+      if (resultCode == ResultCode.SUCCESS)
+      {
+        resultCode = ResultCode.CONSTRAINT_VIOLATION;
+      }
+
+      int msgID = MSGID_SASLGSSAPI_NO_SUCH_IDENTITY_MAPPER;
+      messages.add(getMessage(msgID, String.valueOf(identityMapperDN),
+                              String.valueOf(configEntryDN)));
+    }
+
+
+    // Determine the fully-qualified hostname for this system.  It may be
+    // provided, but if not, then try to determine it programmatically.
+    String newFQDN = configuration.getServerFqdn();
+    if (newFQDN == null)
+    {
+      try
+      {
+        newFQDN = InetAddress.getLocalHost().getCanonicalHostName();
+      }
+      catch (Exception e)
+      {
+        if (debugEnabled())
+        {
+          debugCaught(DebugLogLevel.ERROR, e);
+        }
+
+        if (resultCode == ResultCode.SUCCESS)
+        {
+          resultCode = DirectoryServer.getServerErrorResultCode();
+        }
+
+        int msgID = MSGID_SASLGSSAPI_CANNOT_GET_SERVER_FQDN;
+        messages.add(getMessage(msgID, String.valueOf(configEntryDN),
+                                stackTraceToSingleLineString(e)));
+      }
+    }
+
+
+    if (resultCode == ResultCode.SUCCESS)
+    {
+      String configFileName;
+      try
+      {
+        File tempFile = File.createTempFile("login", "conf");
+        configFileName = tempFile.getAbsolutePath();
+        tempFile.deleteOnExit();
+        BufferedWriter w = new BufferedWriter(new FileWriter(tempFile, false));
+
+        w.write(getClass().getName() + " {");
+        w.newLine();
+
+        w.write("  com.sun.security.auth.module.Krb5LoginModule required " +
+                "storeKey=true useKeyTab=true ");
+
+        String keyTabFile = configuration.getKeytab();
+        if (keyTabFile != null)
+        {
+          w.write("keyTab=\"" + keyTabFile + "\" ");
+        }
+
+        // FIXME -- Should we add the ability to include "debug=true"?
+
+        // FIXME -- Can we get away from hard-coding a protocol here?
+        w.write("principal=\"ldap/" + serverFQDN);
+
+        String realm = configuration.getRealm();
+        if (realm != null)
+        {
+          w.write("@" + realm);
+        }
+        w.write("\";");
+
+        w.newLine();
+
+        w.write("};");
+        w.newLine();
+
+        w.flush();
+        w.close();
+      }
+      catch (Exception e)
+      {
+        if (debugEnabled())
+        {
+          debugCaught(DebugLogLevel.ERROR, e);
+        }
+
+        resultCode = DirectoryServer.getServerErrorResultCode();
+
+        int msgID = MSGID_SASLGSSAPI_CANNOT_CREATE_JAAS_CONFIG;
+        messages.add(getMessage(msgID, stackTraceToSingleLineString(e)));
+
+       return new ConfigChangeResult(resultCode, adminActionRequired, messages);
+      }
+
+      System.setProperty(JAAS_PROPERTY_CONFIG_FILE, configFileName);
+
+      identityMapper = newIdentityMapper;
+      serverFQDN     = newFQDN;
+      currentConfig  = configuration;
+    }
+
+
+   return new ConfigChangeResult(resultCode, adminActionRequired, messages);
+  }
 }
 

--
Gitblit v1.10.0