private static void updateAdminConnectorConfiguration(
      ServerDescriptor desc, InitialLdapContext ctx, TopologyCacheFilter cacheFilter)
      throws NamingException {
    SearchControls ctls = new SearchControls();
    ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
    ctls.setReturningAttributes(new String[] {"ds-cfg-listen-port", "objectclass"});
    String filter = "(objectclass=ds-cfg-administration-connector)";

    LdapName jndiName = new LdapName("cn=config");
    NamingEnumeration<SearchResult> listeners = ctx.search(jndiName, filter, ctls);

    try {
      Integer adminConnectorPort = null;

      // we should have a single administration connector
      while (listeners.hasMore()) {
        SearchResult sr = listeners.next();
        String port = getFirstValue(sr, "ds-cfg-listen-port");
        adminConnectorPort = new Integer(port);
      }

      // Even if we have a single port, use an array to be consistent with
      // other protocols.
      ArrayList<Integer> adminPorts = new ArrayList<Integer>();
      ArrayList<Boolean> adminEnabled = new ArrayList<Boolean>();
      if (adminConnectorPort != null) {
        adminPorts.add(adminConnectorPort);
        adminEnabled.add(Boolean.TRUE);
      }
      desc.serverProperties.put(ServerProperty.ADMIN_PORT, adminPorts);
      desc.serverProperties.put(ServerProperty.ADMIN_ENABLED, adminEnabled);
    } finally {
      listeners.close();
    }
  }
  private static void updateLdapConfiguration(
      ServerDescriptor desc, InitialLdapContext ctx, TopologyCacheFilter cacheFilter)
      throws NamingException {
    SearchControls ctls = new SearchControls();
    ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
    ctls.setReturningAttributes(
        new String[] {
          "ds-cfg-enabled",
          "ds-cfg-listen-address",
          "ds-cfg-listen-port",
          "ds-cfg-use-ssl",
          "ds-cfg-allow-start-tls",
          "objectclass"
        });
    String filter = "(objectclass=ds-cfg-ldap-connection-handler)";

    LdapName jndiName = new LdapName("cn=config");
    NamingEnumeration<SearchResult> listeners = ctx.search(jndiName, filter, ctls);

    try {
      ArrayList<Integer> ldapPorts = new ArrayList<Integer>();
      ArrayList<Integer> ldapsPorts = new ArrayList<Integer>();
      ArrayList<Boolean> ldapEnabled = new ArrayList<Boolean>();
      ArrayList<Boolean> ldapsEnabled = new ArrayList<Boolean>();
      ArrayList<Boolean> startTLSEnabled = new ArrayList<Boolean>();

      desc.serverProperties.put(ServerProperty.LDAP_PORT, ldapPorts);
      desc.serverProperties.put(ServerProperty.LDAPS_PORT, ldapsPorts);
      desc.serverProperties.put(ServerProperty.LDAP_ENABLED, ldapEnabled);
      desc.serverProperties.put(ServerProperty.LDAPS_ENABLED, ldapsEnabled);
      desc.serverProperties.put(ServerProperty.STARTTLS_ENABLED, startTLSEnabled);

      while (listeners.hasMore()) {
        SearchResult sr = listeners.next();

        String port = getFirstValue(sr, "ds-cfg-listen-port");

        boolean isSecure = "true".equalsIgnoreCase(getFirstValue(sr, "ds-cfg-use-ssl"));

        boolean enabled = "true".equalsIgnoreCase(getFirstValue(sr, "ds-cfg-enabled"));
        if (isSecure) {
          ldapsPorts.add(new Integer(port));
          ldapsEnabled.add(enabled);
        } else {
          ldapPorts.add(new Integer(port));
          ldapEnabled.add(enabled);
          enabled = "true".equalsIgnoreCase(getFirstValue(sr, "ds-cfg-allow-start-tls"));
          startTLSEnabled.add(enabled);
        }
      }
    } finally {
      listeners.close();
    }
  }
 /**
  * Updates the instance key public-key certificate value of this context from the local truststore
  * of the instance bound by this context. Any current value of the certificate is overwritten. The
  * intent of this method is to retrieve the instance-key public-key certificate when this context
  * is bound to an instance, and cache it for later use in registering the instance into ADS.
  *
  * @param desc The map to update with the instance key-pair public-key certificate.
  * @param ctx The bound server instance.
  * @throws NamingException if unable to retrieve certificate from bound instance.
  */
 private static void updatePublicKeyCertificate(
     ServerDescriptor desc, InitialLdapContext ctx, TopologyCacheFilter filter)
     throws NamingException {
   /* TODO: this DN is declared in some core constants file. Create a constants
   file for the installer and import it into the core. */
   final String dnStr = "ds-cfg-key-id=ads-certificate,cn=ads-truststore";
   final LdapName dn = new LdapName(dnStr);
   for (int i = 0; i < 2; ++i) {
     /* If the entry does not exist in the instance's truststore backend, add
     it (which induces the CryptoManager to create the public-key
     certificate attribute), then repeat the search. */
     try {
       final SearchControls searchControls = new SearchControls();
       searchControls.setSearchScope(SearchControls.OBJECT_SCOPE);
       final String attrIDs[] = {"ds-cfg-public-key-certificate;binary"};
       searchControls.setReturningAttributes(attrIDs);
       final SearchResult certEntry =
           ctx.search(dn, "(objectclass=ds-cfg-instance-key)", searchControls).next();
       final Attribute certAttr = certEntry.getAttributes().get(attrIDs[0]);
       if (null != certAttr) {
         /* attribute ds-cfg-public-key-certificate is a MUST in the schema */
         desc.serverProperties.put(ServerProperty.INSTANCE_PUBLIC_KEY_CERTIFICATE, certAttr.get());
       }
       break;
     } catch (NameNotFoundException x) {
       if (0 == i) {
         /* Poke CryptoManager to initialize truststore. Note the special
         attribute in the request. */
         final Attributes attrs = new BasicAttributes();
         final Attribute oc = new BasicAttribute("objectclass");
         oc.add("top");
         oc.add("ds-cfg-self-signed-cert-request");
         attrs.put(oc);
         ctx.createSubcontext(dn, attrs).close();
       } else {
         throw x;
       }
     }
   }
 }
  /**
   * Returns the values of the ds-base-dn-entry count attributes for the given backend monitor entry
   * using the provided InitialLdapContext.
   *
   * @param ctx the InitialLdapContext to use to update the configuration.
   * @param backendID the id of the backend.
   * @return the values of the ds-base-dn-entry count attribute.
   * @throws NamingException if there was an error.
   */
  private static Set<String> getBaseDNEntryCount(InitialLdapContext ctx, String backendID)
      throws NamingException {
    LinkedHashSet<String> v = new LinkedHashSet<String>();
    SearchControls ctls = new SearchControls();
    ctls.setSearchScope(SearchControls.ONELEVEL_SCOPE);
    ctls.setReturningAttributes(new String[] {"ds-base-dn-entry-count"});
    String filter = "(ds-backend-id=" + backendID + ")";

    LdapName jndiName = new LdapName("cn=monitor");
    NamingEnumeration<SearchResult> listeners = ctx.search(jndiName, filter, ctls);

    try {
      while (listeners.hasMore()) {
        SearchResult sr = listeners.next();

        v.addAll(getValues(sr, "ds-base-dn-entry-count"));
      }
    } finally {
      listeners.close();
    }
    return v;
  }
  private static void updateMiscellaneous(
      ServerDescriptor desc, InitialLdapContext ctx, TopologyCacheFilter cacheFilter)
      throws NamingException {
    SearchControls ctls = new SearchControls();
    ctls.setSearchScope(SearchControls.OBJECT_SCOPE);
    ctls.setReturningAttributes(new String[] {"ds-sync-generation-id"});
    String filter = "(|(objectclass=*)(objectclass=ldapsubentry))";

    LdapName jndiName = new LdapName("cn=schema");
    NamingEnumeration<SearchResult> listeners = ctx.search(jndiName, filter, ctls);

    try {
      while (listeners.hasMore()) {
        SearchResult sr = listeners.next();

        desc.serverProperties.put(
            ServerProperty.SCHEMA_GENERATION_ID, getFirstValue(sr, "ds-sync-generation-id"));
      }
    } finally {
      listeners.close();
    }
  }
 /**
  * Cleans up the contents of the ads truststore.
  *
  * @param ctx the bound instance.
  * @throws NamingException in case an error occurs while updating the instance's ads-truststore
  *     via LDAP.
  */
 public static void cleanAdsTrustStore(InitialLdapContext ctx) throws NamingException {
   try {
     SearchControls sc = new SearchControls();
     sc.setSearchScope(SearchControls.ONELEVEL_SCOPE);
     sc.setReturningAttributes(new String[] {SchemaConstants.NO_ATTRIBUTES});
     NamingEnumeration<SearchResult> ne =
         ctx.search(TRUSTSTORE_DN, "(objectclass=ds-cfg-instance-key)", sc);
     ArrayList<String> dnsToDelete = new ArrayList<String>();
     try {
       while (ne.hasMore()) {
         SearchResult sr = ne.next();
         dnsToDelete.add(sr.getName() + "," + TRUSTSTORE_DN);
       }
     } finally {
       ne.close();
     }
     for (String dn : dnsToDelete) {
       ctx.destroySubcontext(dn);
     }
   } catch (NameNotFoundException nnfe) {
     // Ignore
     LOG.log(Level.WARNING, "Error cleaning truststore: " + nnfe, nnfe);
   }
 }
Exemplo n.º 7
0
  /**
   * Initialize this <code>LoginModule</code>.
   *
   * @param subject the <code>Subject</code> to be authenticated.
   * @param callbackHandler a <code>CallbackHandler</code> to acquire the username and password.
   * @param sharedState shared <code>LoginModule</code> state.
   * @param options options specified in the login <code>Configuration</code> for this particular
   *     <code>LoginModule</code>.
   */
  public void initialize(
      Subject subject,
      CallbackHandler callbackHandler,
      Map<String, ?> sharedState,
      Map<String, ?> options) {

    this.subject = subject;
    this.callbackHandler = callbackHandler;
    this.sharedState = sharedState;
    this.options = options;

    ldapEnvironment = new Hashtable(9);
    ldapEnvironment.put(Context.INITIAL_CONTEXT_FACTORY, "com.sun.jndi.ldap.LdapCtxFactory");

    // Add any JNDI properties to the environment
    Set keys = options.keySet();
    String key;
    for (Iterator i = keys.iterator(); i.hasNext(); ) {
      key = (String) i.next();
      if (key.indexOf(".") > -1) {
        ldapEnvironment.put(key, options.get(key));
      }
    }

    // initialize any configured options

    userProvider = (String) options.get(USER_PROVIDER);
    if (userProvider != null) {
      ldapEnvironment.put(Context.PROVIDER_URL, userProvider);
    }

    authcIdentity = (String) options.get(AUTHC_IDENTITY);
    if (authcIdentity != null && (authcIdentity.indexOf(USERNAME_TOKEN) != -1)) {
      identityMatcher = USERNAME_PATTERN.matcher(authcIdentity);
    }

    userFilter = (String) options.get(USER_FILTER);
    if (userFilter != null) {
      if (userFilter.indexOf(USERNAME_TOKEN) != -1) {
        filterMatcher = USERNAME_PATTERN.matcher(userFilter);
      }
      constraints = new SearchControls();
      constraints.setSearchScope(SearchControls.SUBTREE_SCOPE);
      constraints.setReturningAttributes(new String[0]); // return no attrs
      constraints.setReturningObjFlag(true); // to get the full DN
    }

    authzIdentity = (String) options.get(AUTHZ_IDENTITY);
    if (authzIdentity != null && authzIdentity.startsWith("{") && authzIdentity.endsWith("}")) {
      if (constraints != null) {
        authzIdentityAttr = authzIdentity.substring(1, authzIdentity.length() - 1);
        constraints.setReturningAttributes(new String[] {authzIdentityAttr});
      }
      authzIdentity = null; // set later, from the specified attribute
    }

    // determine mode
    if (authcIdentity != null) {
      if (userFilter != null) {
        authFirst = true; // authentication-first mode
      } else {
        authOnly = true; // authentication-only mode
      }
    }

    if ("false".equalsIgnoreCase((String) options.get("useSSL"))) {
      useSSL = false;
      ldapEnvironment.remove(Context.SECURITY_PROTOCOL);
    } else {
      ldapEnvironment.put(Context.SECURITY_PROTOCOL, "ssl");
    }

    tryFirstPass = "******".equalsIgnoreCase((String) options.get("tryFirstPass"));

    useFirstPass = "******".equalsIgnoreCase((String) options.get("useFirstPass"));

    storePass = "******".equalsIgnoreCase((String) options.get("storePass"));

    clearPass = "******".equalsIgnoreCase((String) options.get("clearPass"));

    debug = "true".equalsIgnoreCase((String) options.get("debug"));

    if (debug) {
      if (authFirst) {
        System.out.println(
            "\t\t[LdapLoginModule] "
                + "authentication-first mode; "
                + (useSSL ? "SSL enabled" : "SSL disabled"));
      } else if (authOnly) {
        System.out.println(
            "\t\t[LdapLoginModule] "
                + "authentication-only mode; "
                + (useSSL ? "SSL enabled" : "SSL disabled"));
      } else {
        System.out.println(
            "\t\t[LdapLoginModule] "
                + "search-first mode; "
                + (useSSL ? "SSL enabled" : "SSL disabled"));
      }
    }
  }
  private static void updateReplication(
      ServerDescriptor desc, InitialLdapContext ctx, TopologyCacheFilter cacheFilter)
      throws NamingException {
    boolean replicationEnabled = false;
    SearchControls ctls = new SearchControls();
    ctls.setSearchScope(SearchControls.OBJECT_SCOPE);
    ctls.setReturningAttributes(new String[] {"ds-cfg-enabled"});
    String filter = "(objectclass=ds-cfg-synchronization-provider)";

    LdapName jndiName =
        new LdapName("cn=Multimaster Synchronization,cn=Synchronization Providers,cn=config");
    NamingEnumeration<SearchResult> syncProviders = null;

    try {
      syncProviders = ctx.search(jndiName, filter, ctls);

      while (syncProviders.hasMore()) {
        SearchResult sr = syncProviders.next();

        if ("true".equalsIgnoreCase(getFirstValue(sr, "ds-cfg-enabled"))) {
          replicationEnabled = true;
        }
      }
    } catch (NameNotFoundException nse) {
      /* ignore */
    } finally {
      if (syncProviders != null) {
        syncProviders.close();
      }
    }
    desc.serverProperties.put(
        ServerProperty.IS_REPLICATION_ENABLED, replicationEnabled ? Boolean.TRUE : Boolean.FALSE);

    Set<String> allReplicationServers = new LinkedHashSet<String>();

    if (cacheFilter.searchBaseDNInformation()) {
      ctls = new SearchControls();
      ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
      ctls.setReturningAttributes(
          new String[] {"ds-cfg-base-dn", "ds-cfg-replication-server", "ds-cfg-server-id"});
      filter = "(objectclass=ds-cfg-replication-domain)";

      jndiName =
          new LdapName("cn=Multimaster Synchronization,cn=Synchronization Providers,cn=config");

      syncProviders = null;
      try {
        syncProviders = ctx.search(jndiName, filter, ctls);

        while (syncProviders.hasMore()) {
          SearchResult sr = syncProviders.next();

          int id = Integer.parseInt(getFirstValue(sr, "ds-cfg-server-id"));
          Set<String> replicationServers = getValues(sr, "ds-cfg-replication-server");
          Set<String> dns = getValues(sr, "ds-cfg-base-dn");
          for (String dn : dns) {
            for (ReplicaDescriptor replica : desc.getReplicas()) {
              if (areDnsEqual(replica.getSuffix().getDN(), dn)) {
                replica.setReplicationId(id);
                // Keep the values of the replication servers in lower case
                // to make use of Sets as String simpler.
                LinkedHashSet<String> repServers = new LinkedHashSet<String>();
                for (String s : replicationServers) {
                  repServers.add(s.toLowerCase());
                }
                replica.setReplicationServers(repServers);
                allReplicationServers.addAll(repServers);
              }
            }
          }
        }
      } catch (NameNotFoundException nse) {
        /* ignore */
      } finally {
        if (syncProviders != null) {
          syncProviders.close();
        }
      }
    }

    ctls = new SearchControls();
    ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
    ctls.setReturningAttributes(
        new String[] {
          "ds-cfg-replication-port", "ds-cfg-replication-server", "ds-cfg-replication-server-id"
        });
    filter = "(objectclass=ds-cfg-replication-server)";

    jndiName =
        new LdapName("cn=Multimaster " + "Synchronization,cn=Synchronization Providers,cn=config");

    desc.serverProperties.put(ServerProperty.IS_REPLICATION_SERVER, Boolean.FALSE);
    NamingEnumeration<SearchResult> entries = null;
    try {
      entries = ctx.search(jndiName, filter, ctls);

      while (entries.hasMore()) {
        SearchResult sr = entries.next();

        desc.serverProperties.put(ServerProperty.IS_REPLICATION_SERVER, Boolean.TRUE);
        String v = getFirstValue(sr, "ds-cfg-replication-port");
        desc.serverProperties.put(ServerProperty.REPLICATION_SERVER_PORT, Integer.parseInt(v));
        v = getFirstValue(sr, "ds-cfg-replication-server-id");
        desc.serverProperties.put(ServerProperty.REPLICATION_SERVER_ID, Integer.parseInt(v));
        Set<String> values = getValues(sr, "ds-cfg-replication-server");
        // Keep the values of the replication servers in lower case
        // to make use of Sets as String simpler.
        LinkedHashSet<String> repServers = new LinkedHashSet<String>();
        for (String s : values) {
          repServers.add(s.toLowerCase());
        }
        allReplicationServers.addAll(repServers);
        desc.serverProperties.put(
            ServerProperty.EXTERNAL_REPLICATION_SERVERS, allReplicationServers);
      }
    } catch (NameNotFoundException nse) {
      /* ignore */
    } finally {
      if (entries != null) {
        entries.close();
      }
    }

    boolean replicationSecure = false;
    if (replicationEnabled) {
      ctls = new SearchControls();
      ctls.setSearchScope(SearchControls.OBJECT_SCOPE);
      ctls.setReturningAttributes(new String[] {"ds-cfg-ssl-encryption"});
      filter = "(objectclass=ds-cfg-crypto-manager)";

      jndiName = new LdapName("cn=Crypto Manager,cn=config");

      entries = ctx.search(jndiName, filter, ctls);

      try {
        while (entries.hasMore()) {
          SearchResult sr = entries.next();

          String v = getFirstValue(sr, "ds-cfg-ssl-encryption");
          replicationSecure = "true".equalsIgnoreCase(v);
        }
      } finally {
        entries.close();
      }
    }
    desc.serverProperties.put(
        ServerProperty.IS_REPLICATION_SECURE, replicationSecure ? Boolean.TRUE : Boolean.FALSE);
  }
  private static void updateReplicas(
      ServerDescriptor desc, InitialLdapContext ctx, TopologyCacheFilter cacheFilter)
      throws NamingException {
    if (!cacheFilter.searchBaseDNInformation()) {
      return;
    }
    SearchControls ctls = new SearchControls();
    ctls.setSearchScope(SearchControls.SUBTREE_SCOPE);
    ctls.setReturningAttributes(new String[] {"ds-cfg-base-dn", "ds-cfg-backend-id"});
    String filter = "(objectclass=ds-cfg-backend)";

    LdapName jndiName = new LdapName("cn=config");
    NamingEnumeration<SearchResult> databases = ctx.search(jndiName, filter, ctls);

    try {
      while (databases.hasMore()) {
        SearchResult sr = databases.next();

        String id = getFirstValue(sr, "ds-cfg-backend-id");

        if (!isConfigBackend(id) || isSchemaBackend(id)) {
          Set<String> baseDns = getValues(sr, "ds-cfg-base-dn");

          Set<String> entries;
          if (cacheFilter.searchMonitoringInformation()) {
            entries = getBaseDNEntryCount(ctx, id);
          } else {
            entries = new HashSet<String>();
          }

          Set<ReplicaDescriptor> replicas = desc.getReplicas();
          for (String baseDn : baseDns) {
            boolean addReplica = cacheFilter.searchAllBaseDNs();
            if (!addReplica) {
              for (String dn : cacheFilter.getBaseDNsToSearch()) {
                addReplica = Utils.areDnsEqual(dn, baseDn);
                if (addReplica) {
                  break;
                }
              }
            }
            if (addReplica) {
              SuffixDescriptor suffix = new SuffixDescriptor();
              suffix.setDN(baseDn);
              ReplicaDescriptor replica = new ReplicaDescriptor();
              replica.setServer(desc);
              replica.setBackendName(id);
              replicas.add(replica);
              HashSet<ReplicaDescriptor> r = new HashSet<ReplicaDescriptor>();
              r.add(replica);
              suffix.setReplicas(r);
              replica.setSuffix(suffix);
              int nEntries = -1;
              for (String s : entries) {
                int index = s.indexOf(" ");
                if (index != -1) {
                  String dn = s.substring(index + 1);
                  if (Utils.areDnsEqual(baseDn, dn)) {
                    try {
                      nEntries = Integer.parseInt(s.substring(0, index));
                    } catch (Throwable t) {
                      /* Ignore */
                    }
                    break;
                  }
                }
              }
              replica.setEntries(nEntries);
            }
          }
          desc.setReplicas(replicas);
        }
      }
    } finally {
      databases.close();
    }
  }