From 894bcfabe2aac051adc47d9a2c6b2fcb7421c9d1 Mon Sep 17 00:00:00 2001
From: david_page <david_page@localhost>
Date: Fri, 31 Aug 2007 14:55:07 +0000
Subject: [PATCH] Issue 466 partial

---
 opends/src/ads/org/opends/admin/ads/ADSContext.java       |  126 +++++++++++++++++++++++++++++-------------
 opends/src/ads/org/opends/admin/ads/ServerDescriptor.java |   20 +++---
 2 files changed, 96 insertions(+), 50 deletions(-)

diff --git a/opends/src/ads/org/opends/admin/ads/ADSContext.java b/opends/src/ads/org/opends/admin/ads/ADSContext.java
index fbbbcae..5b76525 100644
--- a/opends/src/ads/org/opends/admin/ads/ADSContext.java
+++ b/opends/src/ads/org/opends/admin/ads/ADSContext.java
@@ -415,45 +415,13 @@
   {
     LdapName dn = makeDNFromServerProperties(serverProperties);
     BasicAttributes attrs = makeAttrsFromServerProperties(serverProperties);
-
-    /* Instance key-pair public-key certificate: generate a key-id attribute
-       for the server entry, then an instance key entry for the key. */
-    LdapName keyDn = null;
-    BasicAttributes keyAttrs = null;
-    if (serverProperties.containsKey(ServerProperty.INSTANCE_KEY_CERT))
-    {
-      String keyID
-              = (String)serverProperties.get(ServerProperty.INSTANCE_KEY_ID);
-      if (null == keyID)
-      {
-        keyID = java.util.UUID.randomUUID().toString();
-      }
-      attrs.put(new BasicAttribute(
-                       ServerProperty.INSTANCE_KEY_ID.getAttributeName(),
-                       keyID));
-
-      String rdnStr = Rdn.escapeValue(keyID);
-      keyDn = nameFromDN(ServerProperty.INSTANCE_KEY_ID.getAttributeName()
-                          + "=" + rdnStr + "," + getInstanceKeysContainerDN());
-      keyAttrs = new BasicAttributes();
-      Attribute oc = new BasicAttribute("objectclass");
-      oc.add("top");
-      oc.add("ds-cfg-instance-key-OID");
-      keyAttrs.put(oc);
-      keyAttrs.put(new BasicAttribute(
-                          ServerProperty.INSTANCE_KEY_ID.getAttributeName(),
-                          rdnStr));
-      keyAttrs.put(new BasicAttribute(
-              ServerProperty.INSTANCE_KEY_CERT.getAttributeName() + ";binary",
-              serverProperties.get(ServerProperty.INSTANCE_KEY_CERT)));
-    }
-
     try
     {
-      DirContext ctx = dirContext.createSubcontext(dn, attrs);
-      ctx.close();
-      ctx = dirContext.createSubcontext(keyDn, keyAttrs);
-      ctx.close();
+      dirContext.createSubcontext(dn, attrs).close();
+      if (serverProperties.containsKey(ServerProperty.INSTANCE_KEY_CERT))
+      {
+        registerInstanceKeyCertificate(serverProperties, dn);
+      }
     }
     catch (NameAlreadyBoundException x)
     {
@@ -494,6 +462,10 @@
       BasicAttributes attrs = makeAttrsFromServerProperties(serverProperties);
       dirContext.modifyAttributes(dn, InitialLdapContext.REPLACE_ATTRIBUTE,
           attrs);
+      if (serverProperties.containsKey(ServerProperty.INSTANCE_KEY_CERT))
+      {
+        registerInstanceKeyCertificate(serverProperties, dn);
+      }
     }
     catch (NameNotFoundException x)
     {
@@ -508,7 +480,9 @@
   }
 
   /**
-   * Method called to unregister a server in the ADS.
+   * Method called to unregister a server in the ADS. Note that the server's
+   * instance key-pair public-key certificate entry (created in registerServer)
+   * is left untouched.
    * @param serverProperties the properties of the server.
    * @throws ADSContextException if the server could not be unregistered.
    */
@@ -1344,7 +1318,7 @@
         }
         else
         {
-          privilegeAtt.add(p.toString());
+          privilegeAtt.add(p);
         }
       }
     }
@@ -2050,4 +2024,78 @@
   {
     return "cn=instance keys," + getAdministrationSuffixDN();
   }
+
+
+  /**
+   Register instance key-pair public-key certificate provided in
+   serverProperties: generate a key-id attribute if one is not provided (as
+   expected); add an instance key public-key certificate entry for the key
+   certificate; and associate the certificate entry with the server entry via
+   the key ID attribute.
+   @param serverProperties Properties of the server being registered to which
+   the instance key entry belongs.
+   @param serverEntryDn The server's ADS entry DN.
+   @throws NamingException In case some JNDI operation fails.
+   */
+  private void registerInstanceKeyCertificate(
+          Map<ServerProperty, Object> serverProperties,
+          LdapName serverEntryDn) throws NamingException
+  {
+    assert serverProperties.containsKey(ServerProperty.INSTANCE_KEY_CERT);
+    if (! serverProperties.containsKey(ServerProperty.INSTANCE_KEY_CERT)) {
+      return;
+    }
+
+    /* the key ID might be supplied in serverProperties (although, I am unaware
+       of any such case). */
+    String keyID = (String)serverProperties.get(ServerProperty.INSTANCE_KEY_ID);
+
+    /* these attributes are used both to search for an existing certificate
+       entry and, if one does not exist, add a new certificate entry */
+    final BasicAttributes keyAttrs = new BasicAttributes();
+    final Attribute oc = new BasicAttribute("objectclass");
+    oc.add("top"); oc.add("ds-cfg-instance-key");
+    keyAttrs.put(oc);
+    if (null != keyID) {
+      keyAttrs.put(new BasicAttribute(
+              ServerProperty.INSTANCE_KEY_ID.getAttributeName(), keyID));
+    }
+    keyAttrs.put(new BasicAttribute(
+            ServerProperty.INSTANCE_KEY_CERT.getAttributeName() + ";binary",
+            serverProperties.get(ServerProperty.INSTANCE_KEY_CERT)));
+
+    /* search for public-key certificate entry in ADS DIT */
+    final String attrIDs[] = { "ds-cfg-key-id" };
+    final NamingEnumeration<SearchResult> results
+           = dirContext.search(getInstanceKeysContainerDN(), keyAttrs, attrIDs);
+    if (results.hasMore()) {
+      final Attribute keyIdAttr
+              = results.next().getAttributes().get(attrIDs[0]);
+      if (null != keyIdAttr) {
+        /* attribute ds-cfg-key-id is the entry is a MUST in the schema */
+        keyID = (String)keyIdAttr.get();
+      }
+    }
+    else {
+      /* create key ID, if it was not supplied in serverProperties */
+      if (null == keyID) {
+        keyID = java.util.UUID.randomUUID().toString();
+        keyAttrs.put(new BasicAttribute(
+                ServerProperty.INSTANCE_KEY_ID.getAttributeName(), keyID));
+      }
+
+      /* add public-key certificate entry */
+      final LdapName keyDn = new LdapName((new StringBuilder())
+              .append(ServerProperty.INSTANCE_KEY_ID.getAttributeName())
+              .append("=").append(Rdn.escapeValue(keyID)).append(",")
+              .append(getInstanceKeysContainerDN()).toString());
+      dirContext.createSubcontext(keyDn, keyAttrs).close();
+    }
+
+    /* associate server entry with certificate entry via key ID attribute */
+    dirContext.modifyAttributes(serverEntryDn,
+            InitialLdapContext.REPLACE_ATTRIBUTE,
+            (new BasicAttributes(
+                   ServerProperty.INSTANCE_KEY_ID.getAttributeName(), keyID)));
+  }
 }
diff --git a/opends/src/ads/org/opends/admin/ads/ServerDescriptor.java b/opends/src/ads/org/opends/admin/ads/ServerDescriptor.java
index a955024..b69f3a3 100644
--- a/opends/src/ads/org/opends/admin/ads/ServerDescriptor.java
+++ b/opends/src/ads/org/opends/admin/ads/ServerDescriptor.java
@@ -40,7 +40,6 @@
 import javax.naming.directory.Attribute;
 import javax.naming.directory.BasicAttribute;
 import javax.naming.directory.BasicAttributes;
-import javax.naming.directory.DirContext;
 import javax.naming.directory.SearchControls;
 import javax.naming.directory.SearchResult;
 import javax.naming.ldap.InitialLdapContext;
@@ -841,8 +840,7 @@
        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);
-    byte[] localInstanceKeyCertificate = null;
-    for (int i = 0; null == localInstanceKeyCertificate && i < 2 ; ++i ) {
+    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. */
@@ -852,12 +850,15 @@
         final String attrIDs[] = { "ds-cfg-public-key-certificate;binary" };
         sc.setReturningAttributes(attrIDs);
         final SearchResult certEntry
-           = ctx.search(dn, "(objectclass=*)", sc).next();
-        final Attribute certAttr = certEntry.getAttributes().get(
-                                        "ds-cfg-public-key-certificate;binary");
+           = ctx.search(dn, "(objectclass=ds-cfg-instance-key)", sc).next();
+        final Attribute certAttr = certEntry.getAttributes().get(attrIDs[0]);
         if (null != certAttr) {
-          localInstanceKeyCertificate = (byte[])certAttr.get();
+          /* 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) {
@@ -868,16 +869,13 @@
           oc.add("top");
           oc.add("ds-cfg-self-signed-cert-request");
           attrs.put(oc);
-          DirContext pokeCtx = ctx.createSubcontext(dn, attrs);
-          pokeCtx.close();
+          ctx.createSubcontext(dn, attrs).close();
         }
         else {
           throw x;
         }
       }
     }
-    desc.serverProperties.put(ServerProperty.INSTANCE_PUBLIC_KEY_CERTIFICATE,
-            localInstanceKeyCertificate);
   }
 
 

--
Gitblit v1.10.0