mirror of https://github.com/OpenIdentityPlatform/OpenDJ.git

Jean-Noel Rouvignac
19.04.2013 5e608e44fafcac466488a3182190ec18ee4624e7
OPENDJ-1149 (CR-2334) Passwords should not be held in memory for the lifetime of a client connection


Note this change does not cater for:
- the bind operations where the password is used to authenticate. The password is held in memory for as long as it takes to complete the bind operation (and the OS flushing the network packets, etc.)
- REST operations where the web container (and the OS network stack) holds a HTTPServletRequest object for as long as it takes to process the request.


AuthenticationInfo.java:
Removed simplePassword and saslCredentials fields + getters (never used) to ensure they are not held for the lifetime of an LDAP connection.
In few methods, reversed conditions to ensure accessed variables are all directly put under a null check.

CollectClientConnectionsFilter.java
Wiped out the password ASAP, even though this is a bit pointless since the password is held by the web container for the lifetime of a REST call, either in the headers or via HTTP basic authentication.

*.java:
Consequence of the changes to AuthenticationInfo ctors.
7 files modified
370 ■■■■ changed files
opends/src/server/org/opends/server/extensions/CRAMMD5SASLMechanismHandler.java 7 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/extensions/ExternalSASLMechanismHandler.java 20 ●●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/protocols/http/CollectClientConnectionsFilter.java 43 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/types/AuthenticationInfo.java 123 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendBindOperation.java 4 ●●●● patch | view | raw | blame | history
opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/MockClientConnection.java 31 ●●●● patch | view | raw | blame | history
opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/NetworkGroupTest.java 142 ●●●● patch | view | raw | blame | history
opends/src/server/org/opends/server/extensions/CRAMMD5SASLMechanismHandler.java
@@ -480,12 +480,9 @@
    // If we've gotten here, then the authentication was successful.
    bindOperation.setResultCode(ResultCode.SUCCESS);
    AuthenticationInfo authInfo =
         new AuthenticationInfo(userEntry, SASL_MECHANISM_CRAM_MD5,
                                clientCredentials,
                                DirectoryServer.isRootDN(userEntry.getDN()));
    AuthenticationInfo authInfo = new AuthenticationInfo(userEntry,
        SASL_MECHANISM_CRAM_MD5, DirectoryServer.isRootDN(userEntry.getDN()));
    bindOperation.setAuthenticationInfo(authInfo);
    return;
  }
opends/src/server/org/opends/server/extensions/ExternalSASLMechanismHandler.java
@@ -23,16 +23,15 @@
 *
 *
 *      Copyright 2006-2009 Sun Microsystems, Inc.
 *      Portions copyright 2013 ForgeRock AS
 */
package org.opends.server.extensions;
import org.opends.messages.Message;
import java.security.cert.Certificate;
import java.util.ArrayList;
import java.util.List;
import org.opends.messages.Message;
import org.opends.server.admin.server.ConfigurationChangeListener;
import org.opends.server.admin.std.server.ExternalSASLMechanismHandlerCfg;
import org.opends.server.admin.std.server.SASLMechanismHandlerCfg;
@@ -42,19 +41,16 @@
import org.opends.server.config.ConfigException;
import org.opends.server.core.BindOperation;
import org.opends.server.core.DirectoryServer;
import static org.opends.server.config.ConfigConstants.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.protocols.ldap.LDAPClientConnection;
import org.opends.server.types.*;
import static org.opends.messages.ExtensionMessages.*;
import static org.opends.messages.ExtensionMessages.*;
import static org.opends.server.config.ConfigConstants.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import static org.opends.server.util.ServerConstants.*;
import static org.opends.server.util.StaticUtils.*;
/**
 * This class provides an implementation of a SASL mechanism that relies on some
 * form of authentication that has already been done outside the LDAP layer.  At
@@ -347,10 +343,8 @@
    }
    AuthenticationInfo authInfo =
         new AuthenticationInfo(userEntry, SASL_MECHANISM_EXTERNAL,
             bindOperation.getSASLCredentials(),
             DirectoryServer.isRootDN(userEntry.getDN()));
    AuthenticationInfo authInfo = new AuthenticationInfo(userEntry,
        SASL_MECHANISM_EXTERNAL, DirectoryServer.isRootDN(userEntry.getDN()));
    bindOperation.setAuthenticationInfo(authInfo);
    bindOperation.setResultCode(ResultCode.SUCCESS);
  }
opends/src/server/org/opends/server/protocols/http/CollectClientConnectionsFilter.java
@@ -26,13 +26,6 @@
 */
package org.opends.server.protocols.http;
import static org.forgerock.opendj.adapter.server2x.Converters.*;
import static org.opends.messages.ProtocolMessages.*;
import static org.opends.server.loggers.AccessLogger.*;
import static org.opends.server.loggers.ErrorLogger.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import static org.opends.server.util.StaticUtils.*;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
@@ -40,23 +33,14 @@
import java.text.ParseException;
import java.util.Collection;
import javax.servlet.AsyncContext;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import org.forgerock.json.resource.ResourceException;
import org.forgerock.opendj.ldap.Connection;
import org.forgerock.opendj.ldap.DN;
import org.forgerock.opendj.ldap.ErrorResultException;
import org.forgerock.opendj.ldap.*;
import org.forgerock.opendj.ldap.Filter;
import org.forgerock.opendj.ldap.ResultCode;
import org.forgerock.opendj.ldap.ResultHandler;
import org.forgerock.opendj.ldap.requests.BindRequest;
import org.forgerock.opendj.ldap.requests.Requests;
import org.forgerock.opendj.ldap.requests.SearchRequest;
@@ -70,11 +54,17 @@
import org.opends.server.schema.SchemaConstants;
import org.opends.server.types.AddressMask;
import org.opends.server.types.AuthenticationInfo;
import org.opends.server.types.ByteString;
import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.DisconnectReason;
import org.opends.server.util.Base64;
import static org.forgerock.opendj.adapter.server2x.Converters.*;
import static org.opends.messages.ProtocolMessages.*;
import static org.opends.server.loggers.AccessLogger.*;
import static org.opends.server.loggers.ErrorLogger.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import static org.opends.server.util.StaticUtils.*;
/**
 * Servlet {@link Filter} that collects information about client connections.
 */
@@ -96,7 +86,11 @@
    private boolean prettyPrint;
    /** Used for the bind request when credentials are specified. */
    private String userName;
    /** Used for the bind request when credentials are specified. */
    /**
     * Used for the bind request when credentials are specified. For security
     * reasons, the password must be discarded as soon as possible after it's
     * been used.
     */
    private String password;
  }
@@ -144,6 +138,9 @@
        final BindRequest bindRequest =
            Requests.newSimpleBindRequest(bindDN.toString(), ctx.password
                .getBytes(Charset.forName("UTF-8")));
        // We are done with the password at this stage,
        // wipe it from memory for security reasons
        ctx.password = null;
        ctx.connection.bindAsync(bindRequest, null,
            new CallDoFilterResultHandler(ctx, resultEntry));
      }
@@ -180,9 +177,8 @@
    {
      ctx.clientConnection.setAuthUser(ctx.userName);
      final AuthenticationInfo authInfo =
          new AuthenticationInfo(to(resultEntry), to(resultEntry.getName()),
              ByteString.valueOf(ctx.password), false);
      final AuthenticationInfo authInfo = new AuthenticationInfo(
          to(resultEntry), to(resultEntry.getName()), false);
      try
      {
        doFilter(ctx, authInfo);
@@ -455,6 +451,7 @@
    // TODO Use session to reduce hits with search + bind?
    // Use proxied authorization control for session.
    // Security: How can we remove the password held in the request headers?
    if (authConfig.isCustomHeadersAuthenticationSupported())
    {
      final String userName =
opends/src/server/org/opends/server/types/AuthenticationInfo.java
@@ -23,13 +23,12 @@
 *
 *
 *      Copyright 2006-2010 Sun Microsystems, Inc.
 *      Portions copyright 2013 ForgeRock AS
 */
package org.opends.server.types;
import static org.opends.server.util.Validator.*;
/**
 * This class defines a data structure that may be used to store
 * information about an authenticated user.  Note that structures in
@@ -44,41 +43,37 @@
     mayInvoke=true)
public final class AuthenticationInfo
{
  // The password used to authenticate using simple authentication.
  private ByteString simplePassword;
  // Indicates whether this connection is currently authenticated.
  /** Indicates whether this connection is currently authenticated. */
  private boolean isAuthenticated;
  // Indicates whether this connection is authenticated as a root
  // user.
  /** Indicates whether this connection is authenticated as a root user. */
  private boolean isRoot;
  // Indicates whether the user's password must be changed before any
  // other operation will be allowed.
  /**
   * Indicates whether the user's password must be changed before any other
   * operation will be allowed.
   */
  private boolean mustChangePassword;
  // The entry of the user that is currently authenticated.
  /** The entry of the user that is currently authenticated. */
  private Entry authenticationEntry;
  // The entry of the user that will be used as the default
  // authorization identity.
  /**
   * The entry of the user that will be used as the default authorization
   * identity.
   */
  private Entry authorizationEntry;
  // The type of authentication performed on this connection.
  /** The type of authentication performed on this connection. */
  private AuthenticationType authenticationType;
  // The SASL mechanism used to authenticate.
  /** The SASL mechanism used to authenticate. */
  private String saslMechanism;
  // The bind DN used to authenticate using simple authentication.
  /** The bind DN used to authenticate using simple authentication. */
  private DN simpleBindDN;
  // The SASL credentials used to authenticate.
  private ByteString saslCredentials;
  /**
   * Creates a new set of authentication information to be used for
   * unauthenticated clients.
@@ -88,12 +83,10 @@
    isAuthenticated     = false;
    isRoot              = false;
    mustChangePassword  = false;
    simplePassword      = null;
    authenticationType  = null;
    authenticationEntry = null;
    authorizationEntry  = null;
    simpleBindDN        = null;
    saslCredentials     = null;
    saslMechanism       = null;
  }
@@ -118,10 +111,8 @@
    mustChangePassword  = false;
    simpleBindDN        = authenticationEntry != null ?
        authenticationEntry.getDN() : null;
    simplePassword      = null;
    authorizationEntry  = authenticationEntry;
    saslMechanism       = null;
    saslCredentials     = null;
    authenticationType  = AuthenticationType.INTERNAL;
  }
@@ -134,27 +125,21 @@
   *                              {@code null}.
   * @param  simpleBindDN         The bind DN that was used to
   *                              perform the simple authentication.
   * @param  simplePassword       The password that was used to
 *                                perform the simple authentication.
 *                                It must not be {@code null}.
   * @param  isRoot               Indicates whether the authenticated
   */
  public AuthenticationInfo(Entry authenticationEntry,
                            DN simpleBindDN,
                            ByteString simplePassword, boolean isRoot)
  public AuthenticationInfo(Entry authenticationEntry, DN simpleBindDN,
      boolean isRoot)
  {
    ensureNotNull(authenticationEntry, simplePassword);
    ensureNotNull(authenticationEntry);
    this.authenticationEntry = authenticationEntry;
    this.simpleBindDN        = simpleBindDN;
    this.simplePassword      = simplePassword;
    this.isRoot              = isRoot;
    this.isAuthenticated     = true;
    this.mustChangePassword  = false;
    this.authorizationEntry  = authenticationEntry;
    this.saslMechanism       = null;
    this.saslCredentials     = null;
    this.authenticationType  = AuthenticationType.SIMPLE;
  }
@@ -171,15 +156,11 @@
   *                              authenticate.  This must be provided
   *                              in all-uppercase characters and must
   *                              not be {@code null}.
   * @param  saslCredentials      The SASL credentials used to
   *                              authenticate.
   *                              It must not be {@code null}.
   * @param  isRoot               Indicates whether the authenticated
   *                              user is a root user.
   */
  public AuthenticationInfo(Entry authenticationEntry,
                            String saslMechanism,
                            ByteString saslCredentials,
                            boolean isRoot)
  {
    ensureNotNull(authenticationEntry, saslMechanism);
@@ -191,13 +172,8 @@
    this.mustChangePassword = false;
    this.authorizationEntry = authenticationEntry;
    this.simpleBindDN       = null;
    this.simplePassword     = null;
    this.authenticationType = AuthenticationType.SASL;
    this.saslMechanism      = saslMechanism;
    this.saslCredentials    = saslCredentials;
  }
@@ -240,12 +216,8 @@
    this.isAuthenticated    = true;
    this.mustChangePassword = false;
    this.simpleBindDN       = null;
    this.simplePassword     = null;
    this.authenticationType = AuthenticationType.SASL;
    this.saslMechanism      = saslMechanism;
    this.saslCredentials    = saslCredentials;
  }
@@ -349,14 +321,11 @@
   */
  public DN getAuthenticationDN()
  {
    if (authenticationEntry == null)
    {
      return null;
    }
    else
    if (authenticationEntry != null)
    {
      return authenticationEntry.getDN();
    }
    return null;
  }
@@ -369,11 +338,7 @@
   */
  public void setAuthenticationDN(DN dn)
  {
    if (authenticationEntry == null)
    {
      return;
    }
    else
    if (authenticationEntry != null)
    {
      authenticationEntry.setDN(dn);
    }
@@ -408,14 +373,11 @@
   */
  public DN getAuthorizationDN()
  {
    if (authorizationEntry == null)
    {
      return null;
    }
    else
    if (authorizationEntry != null)
    {
      return authorizationEntry.getDN();
    }
    return null;
  }
@@ -429,11 +391,7 @@
   */
  public void setAuthorizationDN(DN dn)
  {
    if (authorizationEntry == null)
    {
      return;
    }
    else
    if (authorizationEntry != null)
    {
      authorizationEntry.setDN(dn);
    }
@@ -457,21 +415,6 @@
  /**
   * Retrieves the password that the client used for simple
   * authentication.
   *
   * @return  The password that the client used for simple
   *          authentication, or {@code null} if the client is not
   *          authenticated using simple authentication.
   */
  public ByteString getSimplePassword()
  {
    return simplePassword;
  }
  /**
   * Indicates whether the client is currently authenticated using the
   * specified SASL mechanism.
   *
@@ -487,23 +430,6 @@
    return this.saslMechanism.equals(saslMechanism);
  }
  /**
   * Retrieves the SASL credentials that the client used for SASL
   * authentication.
   *
   * @return  The SASL credentials that the client used for SASL
   *          authentication, or {@code null} if the client is not
   *          authenticated using SASL authentication.
   */
  public ByteString getSASLCredentials()
  {
    return saslCredentials;
  }
  /**
   * Retrieves a string representation of this authentication info
   * structure.
@@ -592,7 +518,6 @@
  {
    AuthenticationInfo authInfo = new AuthenticationInfo();
    authInfo.simplePassword      = simplePassword;
    authInfo.isAuthenticated     = isAuthenticated;
    authInfo.isRoot              = isRoot;
    authInfo.mustChangePassword  = mustChangePassword;
opends/src/server/org/opends/server/workflowelement/localbackend/LocalBackendBindOperation.java
@@ -551,7 +551,7 @@
                ERR_BIND_REJECTED_LOCKDOWN_MODE.get());
          }
          setAuthenticationInfo(new AuthenticationInfo(userEntry, getBindDN(),
              simplePassword, DirectoryServer.isRootDN(userEntry.getDN())));
              DirectoryServer.isRootDN(userEntry.getDN())));
          // Set resource limits for the authenticated user.
          setResourceLimits(userEntry);
@@ -621,7 +621,7 @@
                ERR_BIND_REJECTED_LOCKDOWN_MODE.get());
          }
          setAuthenticationInfo(new AuthenticationInfo(userEntry, getBindDN(),
              simplePassword, DirectoryServer.isRootDN(userEntry.getDN())));
              DirectoryServer.isRootDN(userEntry.getDN())));
          // Set resource limits for the authenticated user.
          setResourceLimits(userEntry);
opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/MockClientConnection.java
@@ -27,8 +27,6 @@
 */
package org.opends.server.core.networkgroups;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Collection;
@@ -39,20 +37,7 @@
import org.opends.server.api.ConnectionHandler;
import org.opends.server.core.DirectoryServer;
import org.opends.server.core.SearchOperation;
import org.opends.server.types.AuthenticationInfo;
import org.opends.server.types.ByteString;
import org.opends.server.types.CancelRequest;
import org.opends.server.types.CancelResult;
import org.opends.server.types.DN;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.DisconnectReason;
import org.opends.server.types.Entry;
import org.opends.server.types.IntermediateResponse;
import org.opends.server.types.Operation;
import org.opends.server.types.SearchResultEntry;
import org.opends.server.types.SearchResultReference;
import org.opends.server.types.*;
/**
 * A mock connection for connection criteria testing.
@@ -61,16 +46,12 @@
public final class MockClientConnection extends ClientConnection
{
  private final int clientPort;
  private final boolean isSecure;
  private final AuthenticationInfo authInfo;
  /**
   * Creates a new mock client connection.
   *
   *
   * @param clientPort
   *          The client port.
   * @param isSecure
@@ -95,15 +76,11 @@
      break;
    case SIMPLE:
      Entry simpleUser = DirectoryServer.getEntry(bindDN);
      ByteString password = ByteString.valueOf("password");
      this.authInfo =
          new AuthenticationInfo(simpleUser, bindDN, password, true);
      this.authInfo = new AuthenticationInfo(simpleUser, bindDN, true);
      break;
    default: // SASL
      Entry saslUser = DirectoryServer.getEntry(bindDN);
      this.authInfo =
          new AuthenticationInfo(saslUser, "external",
              ByteString.valueOf(bindDN.toNormalizedString()), true);
      this.authInfo = new AuthenticationInfo(saslUser, "external", true);
      break;
    }
  }
opends/tests/unit-tests-testng/src/server/org/opends/server/core/networkgroups/NetworkGroupTest.java
@@ -23,15 +23,10 @@
 *
 *
 *      Copyright 2006-2010 Sun Microsystems, Inc.
 *      Portions copyright 2011 ForgeRock AS.
 *      Portions copyright 2011-2013 ForgeRock AS.
 */
package org.opends.server.core.networkgroups;
import static org.opends.messages.CoreMessages.*;
import static org.opends.server.config.ConfigConstants.*;
import static org.testng.Assert.*;
import java.util.ArrayList;
import java.util.Collections;
@@ -48,10 +43,14 @@
import org.testng.annotations.DataProvider;
import org.testng.annotations.Test;
import static org.opends.messages.CoreMessages.*;
import static org.opends.server.config.ConfigConstants.*;
import static org.testng.Assert.*;
/**
 * This set of tests test the network groups.
 */
@SuppressWarnings("javadoc")
public class NetworkGroupTest extends DirectoryServerTestCase {
  //===========================================================================
  //
@@ -65,8 +64,7 @@
   * @throws Exception if the environment could not be set up.
   */
  @BeforeClass
  public void setUp()
    throws Exception
  public void setUp() throws Exception
  {
    // This test suite depends on having the schema available,
    // so we'll start the server.
@@ -88,8 +86,7 @@
   */
  @DataProvider (name = "DNSet_0")
  public Object[][] initDNSet_0()
    throws Exception
  public Object[][] initDNSet_0() throws Exception
  {
    // Network group ID
    String networkGroupID1 = "networkGroup1";
@@ -100,8 +97,7 @@
    DN dn2 = DN.decode("o=test2");
    // Network group info
    Object[][] myData =
    {
    return new Object[][] {
        // Test1: create a network group with the identifier networkGroupID1
        { networkGroupID1, dn1 },
@@ -112,8 +108,6 @@
        // Test3: create another network group
        { networkGroupID2, dn2 },
    };
    return myData;
  }
@@ -134,8 +128,7 @@
   * @throws Exception  when DN.decode fails
   */
  @DataProvider(name = "DNSet_1")
  public Object[][] initDNSet_1()
    throws Exception
  public Object[][] initDNSet_1() throws Exception
  {
    DN dnRootDSE = DN.decode("");
    DN dnConfig  = DN.decode("cn=config");
@@ -154,8 +147,7 @@
    // child entry under cn=backups.
    // Sets of DNs
    Object[][] myData =
    {
    return new Object[][] {
        { dnRootDSE,  null,                 true,  true,  true },
        { dnConfig,   dnSubordinateConfig,  true,  true,  true },
        { dnMonitor,  dnSubordinateMonitor, true,  true,  true },
@@ -164,8 +156,6 @@
        { dnBackups,  null,                 true,  true,  true },
        { dnDummy,    null,                 false, false, false },
    };
    return myData;
  }
@@ -185,8 +175,7 @@
   */
  @DataProvider (name = "DNSet_2")
  public Object[][] initDNSet_2()
    throws Exception
  public Object[][] initDNSet_2() throws Exception
  {
    // Network group definition
    DN     dn1          = DN.decode("o=test1");
@@ -198,41 +187,26 @@
    DN     unrelatedDN  = DN.decode("o=dummy");
    // Network group info
    Object[][] myData =
    {
    return new Object[][] {
        // Test1: one DN for one workflow
        {
          dn1,
          null,
          null,
          subordinate1,
          null,
          null,
          dn1, null, null,
          subordinate1, null, null,
          unrelatedDN
        },
        // Test2: two DNs for two workflows
        {
          dn1,
          dn2,
          null,
          subordinate1,
          subordinate2,
          null,
          dn1, dn2, null,
          subordinate1, subordinate2, null,
          unrelatedDN
        },
        // Test3: three DNs for three workflows
        {
          dn1,
          dn2,
          dn3,
          subordinate1,
          subordinate2,
          subordinate3,
          dn1, dn2, dn3,
          subordinate1, subordinate2, subordinate3,
          unrelatedDN
        }
    };
    return myData;
  }
@@ -240,8 +214,7 @@
   * Provides information to create a network group with resource limits.
   */
  @DataProvider (name = "DNSet_3")
  public Object[][] initDNSet_3()
    throws Exception
  public Object[][] initDNSet_3() throws Exception
  {
    // Network group definition
    String networkGroupID = "networkGroup1";
@@ -258,8 +231,7 @@
    int minSubstringLength = 4;
    // Network group info
    Object[][] myData =
    {
    return new Object[][] {
        // Test1: one DN for one workflow
        {
          networkGroupID,
@@ -274,7 +246,6 @@
          minSubstringLength
        }
    };
    return myData;
  }
@@ -282,35 +253,23 @@
   * Provides information to create 2 network groups with different priorities.
   */
  @DataProvider (name = "DNSet_4")
  public Object[][] initDNSet_4()
    throws Exception
  public Object[][] initDNSet_4() throws Exception
  {
    String networkGroupID1 = "group1";
    String networkGroupID2 = "group2";
    DN dn1 = DN.decode("o=test1");
    DN dn2 = DN.decode("o=test2");
    Object[][] myData = {
    return new Object[][] {
      {
        networkGroupID1,
        dn1,
        1,
        networkGroupID2,
        dn2,
        2
        networkGroupID1, dn1, 1,
        networkGroupID2, dn2, 2
      },
      {
        networkGroupID1,
        dn1,
        2,
        networkGroupID2,
        dn2,
        1
        networkGroupID1, dn1, 2,
        networkGroupID2, dn2, 1
      }
    };
    return myData;
  }
@@ -320,7 +279,7 @@
  @DataProvider (name = "PrioritySet_0")
  public Object[][] initPrioritySet_0()
  {
    Object[][] myData = {
    return new Object[][] {
      { 1, 2, 3 },
      { 1, 3, 2 },
      { 2, 1, 3 },
@@ -328,8 +287,6 @@
      { 3, 1, 2 },
      { 3, 2, 1 }
    };
    return myData;
  }
@@ -342,33 +299,14 @@
  @DataProvider (name = "BindFilterSet_0")
  public Object[][] initBindFilterSet_0()
  {
    Object[][] myData = {
      {
        "*, cn=Root DNs, cn=config",
        true
      },
      {
        "cn=Dir*, cn=Root DNs, cn=config",
        true
      },
      {
        "cn=*",
        false
      },
      {
        "uid=*",
        false
      },
      {
        "**, cn=config",
        true
      },
      {
        "*, cn=config",
        false
      }
    return new Object[][] {
      { "*, cn=Root DNs, cn=config", true },
      { "cn=Dir*, cn=Root DNs, cn=config", true },
      { "cn=*", false },
      { "uid=*", false },
      { "**, cn=config", true },
      { "*, cn=config", false }
    };
    return myData;
  }
@@ -948,16 +886,14 @@
    // Use simple bind on this connection
    Entry userEntry = DirectoryServer.getEntry(
            DN.decode("cn=Directory Manager, cn=Root DNs, cn=config"));
    ByteString password = ByteString.valueOf("password");
    ClientConnection connection2 = new InternalClientConnection(
          new AuthenticationInfo(userEntry, userEntry.getDN(), password, true));
          new AuthenticationInfo(userEntry, userEntry.getDN(), true));
    ng = NetworkGroup.findMatchingNetworkGroup(connection2);
    assertEquals(ng, networkGroup2);
    // Use SASL on this connection
    ClientConnection connection3 = new InternalClientConnection(
            new AuthenticationInfo(userEntry, "external", ByteString.valueOf(
                "cn=Directory Manager, cn=Root DNs, cn=config"), true));
            new AuthenticationInfo(userEntry, "external", true));
    ng = NetworkGroup.findMatchingNetworkGroup(connection3);
    assertEquals(ng, networkGroup3);
@@ -1000,9 +936,8 @@
    // Use simple bind on this connection
    Entry userEntry = DirectoryServer.getEntry(
            DN.decode("cn=Directory Manager, cn=Root DNs, cn=config"));
    ByteString password = ByteString.valueOf("password");
    ClientConnection connection2 = new InternalClientConnection(
          new AuthenticationInfo(userEntry, userEntry.getDN(), password, true));
          new AuthenticationInfo(userEntry, userEntry.getDN(), true));
    ng = NetworkGroup.findMatchingNetworkGroup(connection2);
    if (match) {
      assertEquals(ng, networkGroup);
@@ -1012,8 +947,7 @@
    // Use SASL on this connection
    ClientConnection connection3 = new InternalClientConnection(
            new AuthenticationInfo(userEntry, "external", ByteString.valueOf(
                "cn=Directory Manager, cn=Root DNs, cn=config"), true));
            new AuthenticationInfo(userEntry, "external", true));
    ng = NetworkGroup.findMatchingNetworkGroup(connection3);
    if (match) {
      assertEquals(ng, networkGroup);