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

Ludovic Poitou
28.35.2012 fca1f654fb5fffca329b205a01a3ae791c008dfe
opendj-sdk/opends/src/messages/messages/extension.properties
@@ -1497,7 +1497,7 @@
 filter "%s": response code %d (%s) and error message "%s"
MILD_ERR_LDAP_PTA_INVALID_PORT_NUMBER_606=The configuration of LDAP PTA policy \
 "%s" is invalid because the remote LDAP server address "%s" specifies a port \
 number which is invalid. Port numbers should be greater than 0 and less than 65536
 number which is invalid. Port numbers should be greater than 0 and less than 65536
SEVERE_ERR_LDAP_PTA_PWD_PROPERTY_NOT_SET_607=The configuration of LDAP PTA policy \
 "%s" is invalid because the Java property %s which should contain the mapped \
 search bind password is not set
@@ -1519,4 +1519,28 @@
MILD_ERR_ETAG_VATTR_NOT_SEARCHABLE_614=The %s attribute is not \
 searchable and should not be included in otherwise unindexed search filters
MILD_ERR_PWDEXPTIME_VATTR_NOT_SEARCHABLE_615=The %s attribute is not \
 searchable and should not be included in otherwise unindexed search filters
 searchable and should not be included in otherwise unindexed search filters
SEVERE_ERR_SATUACM_MULTIPLE_SEARCH_MATCHING_ENTRIES_616=The certificate with \
 subject %s mapped to multiple users
MILD_ERR_SATUACM_INEFFICIENT_SEARCH_617=The internal search based on \
 the certificate with subject %s could not be processed efficiently:  %s.  \
 Check the server configuration to ensure that all associated backends are \
 properly configured for these types of searches
MILD_ERR_SATUACM_SEARCH_FAILED_618=An internal failure occurred while \
 attempting to map the certificate with subject %s to a user entry:  %s
SEVERE_ERR_SDTUACM_MULTIPLE_SEARCH_MATCHING_ENTRIES_619=The certificate with \
 subject %s mapped to multiple users
MILD_ERR_SDTUACM_INEFFICIENT_SEARCH_620=The internal search based on \
 the certificate with subject %s could not be processed efficiently:  %s.  \
 Check the server configuration to ensure that all associated backends are \
 properly configured for these types of searches
MILD_ERR_SDTUACM_SEARCH_FAILED_621=An internal failure occurred while \
 attempting to map the certificate with subject %s to a user entry:  %s
SEVERE_ERR_FCM_MULTIPLE_SEARCH_MATCHING_ENTRIES_622=The certificate with \
 fingerprint %s mapped to multiple users
MILD_ERR_FCM_INEFFICIENT_SEARCH_623=The internal search based on \
 the certificate with fingerprint %s could not be processed efficiently:  %s.  \
 Check the server configuration to ensure that all associated backends are \
 properly configured for these types of searches
MILD_ERR_FCM_SEARCH_FAILED_624=An internal failure occurred while \
 attempting to map the certificate with fingerprint %s to a user entry:  %s
opendj-sdk/opends/src/server/org/opends/server/extensions/FingerprintCertificateMapper.java
@@ -23,6 +23,7 @@
 *
 *
 *      Copyright 2007-2008 Sun Microsystems, Inc.
 *      Portions Copyright 2012 ForgeRock AS
 */
package org.opends.server.extensions;
@@ -31,12 +32,9 @@
import java.security.MessageDigest;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.*;
import javax.security.auth.x500.X500Principal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import static org.opends.messages.ExtensionMessages.*;
import org.opends.messages.Message;
import org.opends.server.admin.server.ConfigurationChangeListener;
import org.opends.server.admin.std.server.CertificateMapperCfg;
@@ -46,14 +44,14 @@
import org.opends.server.config.ConfigException;
import org.opends.server.core.DirectoryServer;
import org.opends.server.loggers.ErrorLogger;
import static org.opends.server.loggers.debug.DebugLogger.debugEnabled;
import static org.opends.server.loggers.debug.DebugLogger.getTracer;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.protocols.internal.InternalClientConnection;
import org.opends.server.protocols.internal.InternalSearchOperation;
import org.opends.server.types.*;
import static org.opends.messages.ExtensionMessages.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import static org.opends.server.util.StaticUtils.*;
import static org.opends.server.util.StaticUtils.bytesToColonDelimitedHex;
import static org.opends.server.util.StaticUtils.getExceptionMessage;
@@ -84,6 +82,8 @@
  // The algorithm that will be used to generate the fingerprint.
  private String fingerprintAlgorithm;
  // The set of attributes to return in search result entries.
  private LinkedHashSet<String> requestedAttributes;
  /**
@@ -101,6 +101,7 @@
  /**
   * {@inheritDoc}
   */
  @Override
  public void initializeCertificateMapper(
                   FingerprintCertificateMapperCfg configuration)
         throws ConfigException, InitializationException
@@ -143,6 +144,12 @@
        ErrorLogger.logError(message);
      }
    }
    // Create the attribute list to include in search requests.  We want to
    // include all user and operational attributes.
    requestedAttributes = new LinkedHashSet<String>(2);
    requestedAttributes.add("*");
    requestedAttributes.add("+");
  }
@@ -150,6 +157,7 @@
  /**
   * {@inheritDoc}
   */
  @Override
  public void finalizeCertificateMapper()
  {
    currentConfig.removeFingerprintChangeListener(this);
@@ -160,12 +168,13 @@
  /**
   * {@inheritDoc}
   */
  @Override
  public Entry mapCertificateToUser(Certificate[] certificateChain)
         throws DirectoryException
  {
    FingerprintCertificateMapperCfg config = currentConfig;
    AttributeType fingerprintAttributeType = config.getFingerprintAttribute();
    String fingerprintAlgorithm = this.fingerprintAlgorithm;
    String theFingerprintAlgorithm = this.fingerprintAlgorithm;
    // Make sure that a peer certificate was provided.
    if ((certificateChain == null) || (certificateChain.length == 0))
@@ -199,7 +208,7 @@
    String fingerprintString;
    try
    {
      MessageDigest digest = MessageDigest.getInstance(fingerprintAlgorithm);
      MessageDigest digest = MessageDigest.getInstance(theFingerprintAlgorithm);
      byte[] fingerprintBytes = digest.digest(peerCertificate.getEncoded());
      fingerprintString = bytesToColonDelimitedHex(fingerprintBytes);
    }
@@ -243,7 +252,47 @@
    for (DN baseDN : baseDNs)
    {
      InternalSearchOperation searchOperation =
           conn.processSearch(baseDN, SearchScope.WHOLE_SUBTREE, filter);
           conn.processSearch(baseDN, SearchScope.WHOLE_SUBTREE,
                              DereferencePolicy.NEVER_DEREF_ALIASES, 1, 10,
                              false, filter, requestedAttributes);
      switch (searchOperation.getResultCode())
      {
        case SUCCESS:
          // This is fine.  No action needed.
          break;
        case NO_SUCH_OBJECT:
          // The search base doesn't exist.  Not an ideal situation, but we'll
          // ignore it.
          break;
        case SIZE_LIMIT_EXCEEDED:
          // Multiple entries matched the filter.  This is not acceptable.
          Message message = ERR_FCM_MULTIPLE_SEARCH_MATCHING_ENTRIES.get(
                        fingerprintString);
          throw new DirectoryException(
                  ResultCode.INVALID_CREDENTIALS, message);
        case TIME_LIMIT_EXCEEDED:
        case ADMIN_LIMIT_EXCEEDED:
          // The search criteria was too inefficient.
          message = ERR_FCM_INEFFICIENT_SEARCH.get(
                         fingerprintString,
                         String.valueOf(searchOperation.getErrorMessage()));
          throw new DirectoryException(searchOperation.getResultCode(),
              message);
        default:
          // Just pass on the failure that was returned for this search.
          message = ERR_FCM_SEARCH_FAILED.get(
                         fingerprintString,
                         String.valueOf(searchOperation.getErrorMessage()));
          throw new DirectoryException(searchOperation.getResultCode(),
              message);
      }
      for (SearchResultEntry entry : searchOperation.getSearchEntries())
      {
        if (userEntry == null)
@@ -285,6 +334,7 @@
  /**
   * {@inheritDoc}
   */
  @Override
  public boolean isConfigurationChangeAcceptable(
                      FingerprintCertificateMapperCfg configuration,
                      List<Message> unacceptableReasons)
@@ -299,6 +349,7 @@
  /**
   * {@inheritDoc}
   */
  @Override
  public ConfigChangeResult applyConfigurationChange(
              FingerprintCertificateMapperCfg configuration)
  {
opendj-sdk/opends/src/server/org/opends/server/extensions/SubjectAttributeToUserAttributeCertificateMapper.java
@@ -23,6 +23,7 @@
 *
 *
 *      Copyright 2007-2008 Sun Microsystems, Inc.
 *      Portions Copyright 2012 ForgeRock AS
 */
package org.opends.server.extensions;
@@ -30,44 +31,26 @@
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.*;
import javax.security.auth.x500.X500Principal;
import java.util.ArrayList;
import java.util.Collection;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import static org.opends.messages.ExtensionMessages.*;
import org.opends.messages.Message;
import org.opends.server.admin.server.ConfigurationChangeListener;
import org.opends.server.admin.std.server.CertificateMapperCfg;
import org.opends.server.admin.std.server.
            SubjectAttributeToUserAttributeCertificateMapperCfg;
import org.opends.server.admin.std.server
    .SubjectAttributeToUserAttributeCertificateMapperCfg;
import org.opends.server.api.Backend;
import org.opends.server.api.CertificateMapper;
import org.opends.server.config.ConfigException;
import org.opends.server.core.DirectoryServer;
import org.opends.server.loggers.ErrorLogger;
import static org.opends.server.loggers.debug.DebugLogger.debugEnabled;
import static org.opends.server.loggers.debug.DebugLogger.getTracer;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.protocols.internal.InternalClientConnection;
import org.opends.server.protocols.internal.InternalSearchOperation;
import org.opends.server.types.DirectoryException;
import org.opends.server.types.AttributeType;
import org.opends.server.types.ConfigChangeResult;
import org.opends.server.types.DebugLogLevel;
import org.opends.server.types.DN;
import org.opends.server.types.Entry;
import org.opends.server.types.IndexType;
import org.opends.server.types.InitializationException;
import org.opends.server.types.RDN;
import org.opends.server.types.ResultCode;
import org.opends.server.types.SearchFilter;
import org.opends.server.types.SearchResultEntry;
import org.opends.server.types.SearchScope;
import static org.opends.messages.ExtensionMessages.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
import static org.opends.server.util.StaticUtils.*;
import org.opends.server.types.*;
import static org.opends.server.util.StaticUtils.toLowerCase;
@@ -99,6 +82,8 @@
  // The current configuration for this certificate mapper.
  private SubjectAttributeToUserAttributeCertificateMapperCfg currentConfig;
  // The set of attributes to return in search result entries.
  private LinkedHashSet<String> requestedAttributes;
  /**
@@ -116,6 +101,7 @@
  /**
   * {@inheritDoc}
   */
  @Override
  public void initializeCertificateMapper(
                   SubjectAttributeToUserAttributeCertificateMapperCfg
                        configuration)
@@ -200,6 +186,12 @@
        }
      }
    }
    // Create the attribute list to include in search requests.  We want to
    // include all user and operational attributes.
    requestedAttributes = new LinkedHashSet<String>(2);
    requestedAttributes.add("*");
    requestedAttributes.add("+");
  }
@@ -207,6 +199,7 @@
  /**
   * {@inheritDoc}
   */
  @Override
  public void finalizeCertificateMapper()
  {
    currentConfig
@@ -218,12 +211,13 @@
  /**
   * {@inheritDoc}
   */
  @Override
  public Entry mapCertificateToUser(Certificate[] certificateChain)
         throws DirectoryException
  {
    SubjectAttributeToUserAttributeCertificateMapperCfg config =
         currentConfig;
    LinkedHashMap<String,AttributeType> attributeMap = this.attributeMap;
    LinkedHashMap<String,AttributeType> theAttributeMap = this.attributeMap;
    // Make sure that a peer certificate was provided.
@@ -277,7 +271,7 @@
      for (int j=0; j < rdn.getNumValues(); j++)
      {
        String lowerName = toLowerCase(rdn.getAttributeName(j));
        AttributeType attrType = attributeMap.get(lowerName);
        AttributeType attrType = theAttributeMap.get(lowerName);
        if (attrType != null)
        {
          filterComps.add(SearchFilter.createEqualityFilter(attrType,
@@ -312,7 +306,47 @@
    for (DN baseDN : baseDNs)
    {
      InternalSearchOperation searchOperation =
           conn.processSearch(baseDN, SearchScope.WHOLE_SUBTREE, filter);
           conn.processSearch(baseDN, SearchScope.WHOLE_SUBTREE,
                              DereferencePolicy.NEVER_DEREF_ALIASES, 1, 10,
                              false, filter, requestedAttributes);
      switch (searchOperation.getResultCode())
      {
        case SUCCESS:
          // This is fine.  No action needed.
          break;
        case NO_SUCH_OBJECT:
          // The search base doesn't exist.  Not an ideal situation, but we'll
          // ignore it.
          break;
        case SIZE_LIMIT_EXCEEDED:
          // Multiple entries matched the filter.  This is not acceptable.
          Message message = ERR_SATUACM_MULTIPLE_SEARCH_MATCHING_ENTRIES.get(
                        String.valueOf(peerDN));
          throw new DirectoryException(
                  ResultCode.INVALID_CREDENTIALS, message);
        case TIME_LIMIT_EXCEEDED:
        case ADMIN_LIMIT_EXCEEDED:
          // The search criteria was too inefficient.
          message = ERR_SATUACM_INEFFICIENT_SEARCH.get(
                         String.valueOf(peerDN),
                         String.valueOf(searchOperation.getErrorMessage()));
          throw new DirectoryException(searchOperation.getResultCode(),
              message);
        default:
          // Just pass on the failure that was returned for this search.
          message = ERR_SATUACM_SEARCH_FAILED.get(
                         String.valueOf(peerDN),
                         String.valueOf(searchOperation.getErrorMessage()));
          throw new DirectoryException(searchOperation.getResultCode(),
              message);
      }
      for (SearchResultEntry entry : searchOperation.getSearchEntries())
      {
        if (userEntry == null)
@@ -354,6 +388,7 @@
  /**
   * {@inheritDoc}
   */
  @Override
  public boolean isConfigurationChangeAcceptable(
              SubjectAttributeToUserAttributeCertificateMapperCfg
                   configuration,
@@ -434,6 +469,7 @@
  /**
   * {@inheritDoc}
   */
  @Override
  public ConfigChangeResult applyConfigurationChange(
              SubjectAttributeToUserAttributeCertificateMapperCfg
                   configuration)
opendj-sdk/opends/src/server/org/opends/server/extensions/SubjectDNToUserAttributeCertificateMapper.java
@@ -23,6 +23,7 @@
 *
 *
 *      Copyright 2007-2008 Sun Microsystems, Inc.
 *      Portions Copyright 2012 ForgeRock AS
 */
package org.opends.server.extensions;
@@ -30,29 +31,29 @@
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import javax.security.auth.x500.X500Principal;
import java.util.Collection;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Set;
import javax.security.auth.x500.X500Principal;
import static org.opends.messages.ExtensionMessages.*;
import org.opends.messages.Message;
import org.opends.server.admin.server.ConfigurationChangeListener;
import org.opends.server.admin.std.server.CertificateMapperCfg;
import org.opends.server.admin.std.server.
            SubjectDNToUserAttributeCertificateMapperCfg;
import org.opends.server.admin.std.server
    .SubjectDNToUserAttributeCertificateMapperCfg;
import org.opends.server.api.Backend;
import org.opends.server.api.CertificateMapper;
import org.opends.server.config.ConfigException;
import org.opends.server.core.DirectoryServer;
import org.opends.server.loggers.ErrorLogger;
import static org.opends.server.loggers.debug.DebugLogger.debugEnabled;
import static org.opends.server.loggers.debug.DebugLogger.getTracer;
import org.opends.server.loggers.debug.DebugTracer;
import org.opends.server.protocols.internal.InternalClientConnection;
import org.opends.server.protocols.internal.InternalSearchOperation;
import org.opends.server.types.*;
import static org.opends.messages.ExtensionMessages.*;
import static org.opends.server.loggers.debug.DebugLogger.*;
/**
@@ -78,6 +79,8 @@
  // The current configuration for this certificate mapper.
  private SubjectDNToUserAttributeCertificateMapperCfg currentConfig;
  // The set of attributes to return in search result entries.
  private LinkedHashSet<String> requestedAttributes;
  /**
@@ -95,6 +98,7 @@
  /**
   * {@inheritDoc}
   */
  @Override
  public void initializeCertificateMapper(
                   SubjectDNToUserAttributeCertificateMapperCfg
                        configuration)
@@ -126,6 +130,12 @@
        ErrorLogger.logError(message);
      }
    }
    // Create the attribute list to include in search requests.  We want to
    // include all user and operational attributes.
    requestedAttributes = new LinkedHashSet<String>(2);
    requestedAttributes.add("*");
    requestedAttributes.add("+");
  }
@@ -133,6 +143,7 @@
  /**
   * {@inheritDoc}
   */
  @Override
  public void finalizeCertificateMapper()
  {
    currentConfig.removeSubjectDNToUserAttributeChangeListener(this);
@@ -143,6 +154,7 @@
  /**
   * {@inheritDoc}
   */
  @Override
  public Entry mapCertificateToUser(Certificate[] certificateChain)
         throws DirectoryException
  {
@@ -205,7 +217,46 @@
    for (DN baseDN : baseDNs)
    {
      InternalSearchOperation searchOperation =
           conn.processSearch(baseDN, SearchScope.WHOLE_SUBTREE, filter);
           conn.processSearch(baseDN, SearchScope.WHOLE_SUBTREE,
                              DereferencePolicy.NEVER_DEREF_ALIASES, 1, 10,
                              false, filter, requestedAttributes);
      switch (searchOperation.getResultCode())
      {
        case SUCCESS:
          // This is fine.  No action needed.
          break;
        case NO_SUCH_OBJECT:
          // The search base doesn't exist.  Not an ideal situation, but we'll
          // ignore it.
          break;
        case SIZE_LIMIT_EXCEEDED:
          // Multiple entries matched the filter.  This is not acceptable.
          Message message = ERR_SDTUACM_MULTIPLE_SEARCH_MATCHING_ENTRIES.get(
                        peerName);
          throw new DirectoryException(
                  ResultCode.INVALID_CREDENTIALS, message);
        case TIME_LIMIT_EXCEEDED:
        case ADMIN_LIMIT_EXCEEDED:
          // The search criteria was too inefficient.
          message = ERR_SDTUACM_INEFFICIENT_SEARCH.get(
                         peerName,
                         String.valueOf(searchOperation.getErrorMessage()));
          throw new DirectoryException(searchOperation.getResultCode(),
              message);
        default:
          // Just pass on the failure that was returned for this search.
          message = ERR_SDTUACM_SEARCH_FAILED.get(
                         peerName,
                         String.valueOf(searchOperation.getErrorMessage()));
          throw new DirectoryException(searchOperation.getResultCode(),
              message);
      }
      for (SearchResultEntry entry : searchOperation.getSearchEntries())
      {
        if (userEntry == null)
@@ -247,6 +298,7 @@
  /**
   * {@inheritDoc}
   */
  @Override
  public boolean isConfigurationChangeAcceptable(
                      SubjectDNToUserAttributeCertificateMapperCfg
                           configuration,
@@ -261,6 +313,7 @@
  /**
   * {@inheritDoc}
   */
  @Override
  public ConfigChangeResult applyConfigurationChange(
              SubjectDNToUserAttributeCertificateMapperCfg
                   configuration)
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/FingerprintCertificateMapperTestCase.java
@@ -23,6 +23,7 @@
 *
 *
 *      Copyright 2008 Sun Microsystems, Inc.
 *      Portions Copyright 2012 ForgeRock AS
 */
package org.opends.server.extensions;
@@ -245,7 +246,7 @@
  /**
   * Tests a successful mapping using the SHA-1 digest algorithm..
   * Tests a successful mapping using the SHA-1 digest algorithm.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
@@ -682,5 +683,66 @@
         conn.processModify(DN.decode(mapperDN), mods);
    assertEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
  }
  /**
   * Tests a successful mapping using the default configuration, and
   * verify that user can do a privileged action (read config).
   * Verification for issue OPENDJ-459.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testPrivilegeWithSuccessfulMappingDefaultConfig()
         throws Exception
  {
    enableMapper();
    try
    {
      TestCaseUtils.initializeTestBackend(true);
      TestCaseUtils.addEntry(
        "dn: uid=test.user,o=test",
        "objectClass: top",
        "objectClass: person",
        "objectClass: organizationalPerson",
        "objectClass: inetOrgPerson",
        "objectClass: ds-certificate-user",
        "uid: test.user",
        "givenName: Test",
        "sn: User",
        "cn: Test User",
        "ds-privilege-name: config-read",
        "ds-certificate-fingerprint: " +
             "07:5A:AB:4B:E1:DD:E3:05:83:C0:FE:5F:A3:E8:1E:EB");
      String keyStorePath = DirectoryServer.getInstanceRoot() + File.separator +
                            "config" + File.separator + "client.keystore";
      String trustStorePath = DirectoryServer.getInstanceRoot() + File.separator +
                              "config" + File.separator + "client.truststore";
      String[] args =
      {
        "--noPropertiesFile",
        "-h", "127.0.0.1",
        "-p", String.valueOf(TestCaseUtils.getServerLdapsPort()),
        "-Z",
        "-K", keyStorePath,
        "-W", "password",
        "-P", trustStorePath,
        "-r",
        "-b", "cn=config",
        "-s", "sub",
        "(objectClass=*)"
      };
      assertEquals(LDAPSearch.mainSearch(args, false, null, System.err), 0);
    }
    finally
    {
      disableMapper();
    }
  }
}
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/SubjectAttributeToUserAttributeCertificateMapperTestCase.java
@@ -23,6 +23,7 @@
 *
 *
 *      Copyright 2008 Sun Microsystems, Inc.
 *      Portions Copyright 2012 ForgeRock AS
 */
package org.opends.server.extensions;
@@ -853,5 +854,64 @@
         conn.processModify(DN.decode(mapperDN), mods);
    assertEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
  }
  /**
   * Tests a successful mapping using the default configuration, and
   * verify that user can do a privileged action (read config).
   * Verification for issue OPENDJ-459.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testPrivilegeWithSuccessfulMappingDefaultConfig()
         throws Exception
  {
    enableMapper();
    try
    {
      TestCaseUtils.initializeTestBackend(true);
      TestCaseUtils.addEntry(
        "dn: uid=test.user,o=test",
        "objectClass: top",
        "objectClass: person",
        "objectClass: organizationalPerson",
        "objectClass: inetOrgPerson",
        "objectClass: ds-certificate-user",
        "uid: test.user",
        "givenName: Test",
        "sn: User",
        "cn: Test User",
        "ds-privilege-name: config-read");
      String keyStorePath = DirectoryServer.getInstanceRoot() + File.separator +
                            "config" + File.separator + "client.keystore";
      String trustStorePath = DirectoryServer.getInstanceRoot() + File.separator +
                              "config" + File.separator + "client.truststore";
      String[] args =
      {
        "--noPropertiesFile",
        "-h", "127.0.0.1",
        "-p", String.valueOf(TestCaseUtils.getServerLdapsPort()),
        "-Z",
        "-K", keyStorePath,
        "-W", "password",
        "-P", trustStorePath,
        "-r",
        "-b", "cn=config",
        "-s", "sub",
        "(objectClass=*)"
      };
      assertEquals(LDAPSearch.mainSearch(args, false, null, System.err), 0);
    }
    finally
    {
      disableMapper();
    }
  }
}
opendj-sdk/opends/tests/unit-tests-testng/src/server/org/opends/server/extensions/SubjectDNToUserAttributeCertificateMapperTestCase.java
@@ -23,6 +23,7 @@
 *
 *
 *      Copyright 2008 Sun Microsystems, Inc.
 *      Portions Copyright 2012 ForgeRock AS
 */
package org.opends.server.extensions;
@@ -713,5 +714,65 @@
         conn.processModify(DN.decode(mapperDN), mods);
    assertEquals(modifyOperation.getResultCode(), ResultCode.SUCCESS);
  }
  /**
   * Tests a successful mapping using the default configuration, and
   * verify that user can do a privileged action (read config).
   * Verification for issue OPENDJ-459.
   *
   * @throws  Exception  If an unexpected problem occurs.
   */
  @Test()
  public void testPrivilegeWithSuccessfulMappingDefaultConfig()
         throws Exception
  {
    enableMapper();
    try
    {
      TestCaseUtils.initializeTestBackend(true);
      TestCaseUtils.addEntry(
        "dn: uid=test.user,o=test",
        "objectClass: top",
        "objectClass: person",
        "objectClass: organizationalPerson",
        "objectClass: inetOrgPerson",
        "objectClass: ds-certificate-user",
        "uid: test.user",
        "givenName: Test",
        "sn: User",
        "cn: Test User",
        "ds-privilege-name: config-read",
        "ds-certificate-subject-dn: CN=Test User, O=Test");
      String keyStorePath = DirectoryServer.getInstanceRoot() + File.separator +
                            "config" + File.separator + "client.keystore";
      String trustStorePath = DirectoryServer.getInstanceRoot() + File.separator +
                              "config" + File.separator + "client.truststore";
      String[] args =
      {
        "--noPropertiesFile",
        "-h", "127.0.0.1",
        "-p", String.valueOf(TestCaseUtils.getServerLdapsPort()),
        "-Z",
        "-K", keyStorePath,
        "-W", "password",
        "-P", trustStorePath,
        "-r",
        "-b", "cn=config",
        "-s", "sub",
        "(objectClass=*)"
      };
      assertEquals(LDAPSearch.mainSearch(args, false, null, System.err), 0);
    }
    finally
    {
      disableMapper();
    }
  }
}