summaryrefslogtreecommitdiffstats
path: root/base/server/cmscore/src
diff options
context:
space:
mode:
authorFraser Tweedale <ftweedal@redhat.com>2014-07-17 00:24:06 -0400
committerFraser Tweedale <frase@frase.id.au>2015-04-07 22:38:10 -0400
commit4785f08b9fa14e2abd60533542d763bdea8082a0 (patch)
tree94ed0549d16ef39e71b8f6d4349055de98ad44b8 /base/server/cmscore/src
parent1b44dcbdac86f5545431be4f47e6d98a743225b8 (diff)
downloadpki-4785f08b9fa14e2abd60533542d763bdea8082a0.tar.gz
pki-4785f08b9fa14e2abd60533542d763bdea8082a0.tar.xz
pki-4785f08b9fa14e2abd60533542d763bdea8082a0.zip
Add LDAPProfileSubsystem to store profiles in LDAP
Add the LDAPProfileSubsystem as another IProfileSubsystem implementation that can be used instead of ProfileSubsystem (which stores profiles on the file system) to store files in LDAP so that changes can be replicated. Extract common behaviour in to new AbstractProfileSubsystem superclass. Also address the minor issue #1220.
Diffstat (limited to 'base/server/cmscore/src')
-rw-r--r--base/server/cmscore/src/com/netscape/cmscore/base/FileConfigStore.java4
-rw-r--r--base/server/cmscore/src/com/netscape/cmscore/profile/AbstractProfileSubsystem.java151
-rw-r--r--base/server/cmscore/src/com/netscape/cmscore/profile/LDAPProfileSubsystem.java228
-rw-r--r--base/server/cmscore/src/com/netscape/cmscore/profile/ProfileSubsystem.java182
4 files changed, 423 insertions, 142 deletions
diff --git a/base/server/cmscore/src/com/netscape/cmscore/base/FileConfigStore.java b/base/server/cmscore/src/com/netscape/cmscore/base/FileConfigStore.java
index b77f86d78..4f8cb2743 100644
--- a/base/server/cmscore/src/com/netscape/cmscore/base/FileConfigStore.java
+++ b/base/server/cmscore/src/com/netscape/cmscore/base/FileConfigStore.java
@@ -33,12 +33,10 @@ import com.netscape.cmsutil.util.Utils;
/**
* FileConfigStore:
- * Extends HashConfigStore with methods to load/save from/to file for
+ * Extends PropConfigStore with methods to load/save from/to file for
* persistent storage. This is a configuration store agent who
* reads data from a file.
* <P>
- * Note that a LdapConfigStore can be implemented so that it reads the configuration stores from the Ldap directory.
- * <P>
*
* @version $Revision$, $Date$
* @see PropConfigStore
diff --git a/base/server/cmscore/src/com/netscape/cmscore/profile/AbstractProfileSubsystem.java b/base/server/cmscore/src/com/netscape/cmscore/profile/AbstractProfileSubsystem.java
new file mode 100644
index 000000000..b7cd503a1
--- /dev/null
+++ b/base/server/cmscore/src/com/netscape/cmscore/profile/AbstractProfileSubsystem.java
@@ -0,0 +1,151 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cmscore.profile;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.profile.IProfileSubsystem;
+
+public abstract class AbstractProfileSubsystem implements IProfileSubsystem {
+ protected static final String PROP_CHECK_OWNER = "checkOwner";
+ protected static final String PROP_ENABLE = "enable";
+ protected static final String PROP_ENABLE_BY = "enableBy";
+
+ protected IConfigStore mConfig = null;
+ @SuppressWarnings("unused")
+ protected ISubsystem mOwner;
+ protected Vector<String> mProfileIds;
+ protected Hashtable<String, IProfile> mProfiles;
+ protected Hashtable<String, String> mProfileClassIds;
+
+ /**
+ * Returns the root configuration storage of this system.
+ * <P>
+ *
+ * @return configuration store of this subsystem
+ */
+ public IConfigStore getConfigStore() {
+ return mConfig;
+ }
+
+ /**
+ * Retrieves the name of this subsystem.
+ */
+ public String getId() {
+ return null;
+ }
+
+ /**
+ * Sets specific to this subsystem.
+ */
+ public void setId(String id) throws EBaseException {
+ }
+
+ public boolean isProfileEnable(String id) {
+ IProfile profile = mProfiles.get(id);
+ String enable = null;
+
+ try {
+ enable = profile.getConfigStore().getString(PROP_ENABLE);
+ } catch (EBaseException e) {
+ }
+ return Boolean.valueOf(enable);
+ }
+
+ public String getProfileEnableBy(String id) {
+ if (!isProfileEnable(id))
+ return null;
+ IProfile profile = mProfiles.get(id);
+ String enableBy = null;
+
+ try {
+ enableBy = profile.getConfigStore().getString(PROP_ENABLE_BY);
+ } catch (EBaseException e) {
+ }
+ return enableBy;
+ }
+
+ /**
+ * Enables a profile for execution.
+ */
+ public void enableProfile(String id, String enableBy)
+ throws EProfileException {
+ IProfile profile = mProfiles.get(id);
+
+ profile.getConfigStore().putString(PROP_ENABLE, "true");
+ profile.getConfigStore().putString(PROP_ENABLE_BY, enableBy);
+ try {
+ profile.getConfigStore().commit(false);
+ } catch (EBaseException e) {
+ }
+ }
+
+ /**
+ * Retrieves a profile by id.
+ */
+ public IProfile getProfile(String id)
+ throws EProfileException {
+ return mProfiles.get(id);
+ }
+
+ /**
+ * Disables a profile for execution.
+ */
+ public void disableProfile(String id)
+ throws EProfileException {
+ IProfile profile = mProfiles.get(id);
+
+ profile.getConfigStore().putString(PROP_ENABLE, "false");
+ try {
+ profile.getConfigStore().commit(false);
+ } catch (EBaseException e) {
+ }
+ }
+
+ public String getProfileClassId(String id) {
+ return mProfileClassIds.get(id);
+ }
+
+ /**
+ * Retrieves a list of profile ids. The return
+ * list is of type String.
+ */
+ public Enumeration<String> getProfileIds() {
+ return mProfileIds.elements();
+ }
+
+ /**
+ * Checks if owner id should be enforced during profile approval.
+ *
+ * @return true if approval should be checked
+ */
+ public boolean checkOwner() {
+ try {
+ return mConfig.getBoolean(PROP_CHECK_OWNER, false);
+ } catch (EBaseException e) {
+ return false;
+ }
+ }
+}
diff --git a/base/server/cmscore/src/com/netscape/cmscore/profile/LDAPProfileSubsystem.java b/base/server/cmscore/src/com/netscape/cmscore/profile/LDAPProfileSubsystem.java
new file mode 100644
index 000000000..3572bd21d
--- /dev/null
+++ b/base/server/cmscore/src/com/netscape/cmscore/profile/LDAPProfileSubsystem.java
@@ -0,0 +1,228 @@
+// --- BEGIN COPYRIGHT BLOCK ---
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation; version 2 of the License.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License along
+// with this program; if not, write to the Free Software Foundation, Inc.,
+// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+//
+// (C) 2007, 2014, 2015 Red Hat, Inc.
+// All rights reserved.
+// --- END COPYRIGHT BLOCK ---
+package com.netscape.cmscore.profile;
+
+import java.util.Enumeration;
+import java.util.Hashtable;
+import java.util.Vector;
+
+import netscape.ldap.LDAPAttribute;
+import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPEntry;
+import netscape.ldap.LDAPException;
+import netscape.ldap.LDAPSearchResults;
+
+import com.netscape.certsrv.apps.CMS;
+import com.netscape.certsrv.base.EBaseException;
+import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.base.ISubsystem;
+import com.netscape.certsrv.ldap.ELdapException;
+import com.netscape.certsrv.ldap.ILdapConnFactory;
+import com.netscape.certsrv.profile.EProfileException;
+import com.netscape.certsrv.profile.IProfile;
+import com.netscape.certsrv.profile.IProfileSubsystem;
+import com.netscape.certsrv.registry.IPluginInfo;
+import com.netscape.certsrv.registry.IPluginRegistry;
+import com.netscape.cmscore.base.LDAPConfigStore;
+
+public class LDAPProfileSubsystem
+ extends AbstractProfileSubsystem
+ implements IProfileSubsystem {
+
+ private String dn;
+ private ILdapConnFactory dbFactory;
+
+ /**
+ * Initializes this subsystem with the given configuration
+ * store.
+ * <P>
+ *
+ * @param owner owner of this subsystem
+ * @param config configuration store
+ * @exception EBaseException failed to initialize
+ */
+ public void init(ISubsystem owner, IConfigStore config)
+ throws EBaseException {
+ CMS.debug("LDAPProfileSubsystem: start init");
+
+ // (re)init member collections
+ mProfileIds = new Vector<String>();
+ mProfiles = new Hashtable<String, IProfile>();
+ mProfileClassIds = new Hashtable<String, String>();
+
+ IPluginRegistry registry = (IPluginRegistry)
+ CMS.getSubsystem(CMS.SUBSYSTEM_REGISTRY);
+
+ IConfigStore cs = CMS.getConfigStore();
+ IConfigStore dbCfg = cs.getSubStore("internaldb");
+ dbFactory = CMS.getLdapBoundConnFactory();
+ dbFactory.init(dbCfg);
+
+ mConfig = config;
+ mOwner = owner;
+
+ // Configuration File Format:
+ // *.list=profile1,profile2
+ // *.profile1.class=com.netscape.cms.profile.common.BasicProfile
+ // *.profile1.config=config/profiles/profile1.cfg
+ // *.profile2.class=com.netscape.cms.profile.common.BasicProfile
+ // *.profile2.config=config/profiles/profile2.cfg
+
+ // read profile id, implementation, and its configuration files
+ String basedn = cs.getString("internaldb.basedn");
+ String dn = "ou=certificateProfiles,ou=ca," + basedn;
+ LDAPConnection conn = dbFactory.getConn();
+
+ String[] attrs = {"cn", "classId"};
+ try {
+ LDAPSearchResults ldapProfiles = conn.search(
+ dn, LDAPConnection.SCOPE_ONE, "(objectclass=*)", attrs, false);
+
+ while (ldapProfiles.hasMoreElements()) {
+ String id = "<unknown>";
+ try {
+ LDAPEntry ldapProfile = ldapProfiles.next();
+
+ id = (String)
+ ldapProfile.getAttribute("cn").getStringValues().nextElement();
+
+ String classid = (String)
+ ldapProfile.getAttribute("classId").getStringValues().nextElement();
+
+ IPluginInfo info = registry.getPluginInfo("profile", classid);
+ if (info == null) {
+ CMS.debug("Error loading profile: No plugins for type : profile, with id " + classid);
+ } else {
+ CMS.debug("Start Profile Creation - " + id + " " + classid + " " + info.getClassName());
+ createProfile(id, classid, info.getClassName());
+ CMS.debug("Done Profile Creation - " + id);
+ }
+ } catch (LDAPException e) {
+ CMS.debug("Error reading profile '" + id + "'; skipping.");
+ }
+ }
+ } catch (LDAPException e) {
+ throw new EBaseException("Error reading profiles: " + e.toString());
+ } finally {
+ try {
+ dbFactory.returnConn(conn);
+ } catch (Exception e) {
+ throw new EProfileException("Error releasing the ldap connection" + e.toString());
+ }
+ }
+
+ Enumeration<String> ee = getProfileIds();
+
+ while (ee.hasMoreElements()) {
+ String id = ee.nextElement();
+
+ CMS.debug("Registered Confirmation - " + id);
+ }
+ }
+
+ /**
+ * Creates a profile instance.
+ */
+ public IProfile createProfile(String id, String classid, String className)
+ throws EProfileException {
+ try {
+ String[] objectClasses = {"top", "certProfile"};
+ LDAPAttribute[] createAttrs = {
+ new LDAPAttribute("objectclass", objectClasses),
+ new LDAPAttribute("cn", id),
+ new LDAPAttribute("classId", classid)
+ };
+
+ IConfigStore subStoreConfig = new LDAPConfigStore(
+ dbFactory, createProfileDN(id), createAttrs, "certProfileConfig");
+
+ CMS.debug("LDAPProfileSubsystem: initing " + className);
+ IProfile profile = (IProfile) Class.forName(className).newInstance();
+ profile.setId(id);
+ profile.init(this, subStoreConfig);
+ mProfileIds.addElement(id);
+ mProfiles.put(id, profile);
+ mProfileClassIds.put(id, classid);
+ return profile;
+ } catch (Exception e) {
+ throw new EProfileException("Error creating or reading profile", e);
+ }
+ }
+
+ public void deleteProfile(String id) throws EProfileException {
+ if (isProfileEnable(id)) {
+ throw new EProfileException("CMS_PROFILE_DELETE_ENABLEPROFILE");
+ }
+
+ LDAPConnection conn;
+ try {
+ conn = dbFactory.getConn();
+ } catch (ELdapException e) {
+ throw new EProfileException("Error acquiring the ldap connection", e);
+ }
+ try {
+ conn.delete(createProfileDN(id));
+ } catch (LDAPException e) {
+ throw new EProfileException("CMS_PROFILE_DELETE_ERROR", e);
+ } finally {
+ try {
+ dbFactory.returnConn(conn);
+ } catch (Exception e) {
+ throw new EProfileException("Error releasing the ldap connection", e);
+ }
+ }
+
+ mProfileIds.removeElement(id);
+ mProfiles.remove(id);
+ mProfileClassIds.remove(id);
+ }
+
+ /**
+ * Notifies this subsystem if owner is in running mode.
+ */
+ public void startup() throws EBaseException {
+ CMS.debug("LDAPProfileSubsystem: startup");
+ }
+
+ /**
+ * Stops this system. The owner may call shutdown
+ * anytime after initialization.
+ * <P>
+ */
+ public void shutdown() {
+ mProfileIds.clear();
+ mProfiles.clear();
+ mProfileClassIds.clear();
+ }
+
+ /**
+ * Compute the profile DN given an ID.
+ */
+ private String createProfileDN(String id) throws EProfileException {
+ if (id == null) {
+ throw new EProfileException("CMS_PROFILE_ID_NOT_FOUND");
+ }
+ String basedn;
+ try {
+ basedn = CMS.getConfigStore().getString("internaldb.basedn");
+ } catch (EBaseException e) {
+ throw new EProfileException("CMS_PROFILE_DELETE_UNKNOWNPROFILE");
+ }
+ return "cn=" + id + ",ou=certificateProfiles,ou=ca," + basedn;
+ }
+}
diff --git a/base/server/cmscore/src/com/netscape/cmscore/profile/ProfileSubsystem.java b/base/server/cmscore/src/com/netscape/cmscore/profile/ProfileSubsystem.java
index 27e72352e..9a7292f2c 100644
--- a/base/server/cmscore/src/com/netscape/cmscore/profile/ProfileSubsystem.java
+++ b/base/server/cmscore/src/com/netscape/cmscore/profile/ProfileSubsystem.java
@@ -33,34 +33,12 @@ import com.netscape.certsrv.profile.IProfileSubsystem;
import com.netscape.certsrv.registry.IPluginInfo;
import com.netscape.certsrv.registry.IPluginRegistry;
-public class ProfileSubsystem implements IProfileSubsystem {
+public class ProfileSubsystem
+ extends AbstractProfileSubsystem
+ implements IProfileSubsystem {
private static final String PROP_LIST = "list";
private static final String PROP_CLASS_ID = "class_id";
private static final String PROP_CONFIG = "config";
- private static final String PROP_CHECK_OWNER = "checkOwner";
-
- private static final String PROP_ENABLE = "enable";
- private static final String PROP_ENABLE_BY = "enableBy";
-
- private IConfigStore mConfig = null;
- @SuppressWarnings("unused")
- private ISubsystem mOwner;
- private Vector<String> mProfileIds = new Vector<String>();
- private Hashtable<String, IProfile> mProfiles = new Hashtable<String, IProfile>();
- private Hashtable<String, String> mProfileClassIds = new Hashtable<String, String>();
-
- /**
- * Retrieves the name of this subsystem.
- */
- public String getId() {
- return null;
- }
-
- /**
- * Sets specific to this subsystem.
- */
- public void setId(String id) throws EBaseException {
- }
/**
* Initializes this subsystem with the given configuration
@@ -77,6 +55,10 @@ public class ProfileSubsystem implements IProfileSubsystem {
IPluginRegistry registry = (IPluginRegistry)
CMS.getSubsystem(CMS.SUBSYSTEM_REGISTRY);
+ mProfileIds = new Vector<String>();
+ mProfiles = new Hashtable<String, IProfile>();
+ mProfileClassIds = new Hashtable<String, String>();
+
mConfig = config;
mOwner = owner;
@@ -102,8 +84,7 @@ public class ProfileSubsystem implements IProfileSubsystem {
String configPath = subStore.getString(PROP_CONFIG);
CMS.debug("Start Profile Creation - " + id + " " + classid + " " + info.getClassName());
- createProfile(id, classid, info.getClassName(),
- configPath);
+ createProfile(id, classid, info.getClassName(), false);
CMS.debug("Done Profile Creation - " + id);
}
@@ -120,14 +101,27 @@ public class ProfileSubsystem implements IProfileSubsystem {
/**
* Creates a profile instance.
*/
- public IProfile createProfile(String id, String classid, String className,
- String configPath)
+ @Override
+ public IProfile createProfile(String id, String classid, String className)
throws EProfileException {
+ return createProfile(id, classid, className, true);
+ }
+
+ private IProfile createProfile(String id, String classid, String className,
+ boolean isNew) throws EProfileException {
IProfile profile = null;
+ String configPath;
+ try {
+ configPath = CMS.getConfigStore().getString("instanceRoot")
+ + "/ca/profiles/ca/" + id + ".cfg";
+ } catch (EBaseException e) {
+ throw new EProfileException("CMS_PROFILE_DELETE_ERROR");
+ }
+
try {
- profile = (IProfile) Class.forName(className).newInstance();
IConfigStore subStoreConfig = CMS.createFileConfigStore(configPath);
+ profile = (IProfile) Class.forName(className).newInstance();
CMS.debug("ProfileSubsystem: initing " + className);
profile.setId(id);
@@ -135,6 +129,8 @@ public class ProfileSubsystem implements IProfileSubsystem {
mProfileIds.addElement(id);
mProfiles.put(id, profile);
mProfileClassIds.put(id, classid);
+ if (isNew)
+ createProfileConfig(id, classid);
return profile;
} catch (Exception e) {
// throw exceptions
@@ -144,7 +140,14 @@ public class ProfileSubsystem implements IProfileSubsystem {
return null;
}
- public void deleteProfile(String id, String configPath) throws EProfileException {
+ public void deleteProfile(String id) throws EProfileException {
+ String configPath;
+ try {
+ configPath = CMS.getConfigStore().getString("instanceRoot")
+ + "/ca/profiles/ca/" + id + ".cfg";
+ } catch (EBaseException e) {
+ throw new EProfileException("CMS_PROFILE_DELETE_ERROR");
+ }
if (isProfileEnable(id)) {
throw new EProfileException("CMS_PROFILE_DELETE_ENABLEPROFILE");
@@ -185,9 +188,16 @@ public class ProfileSubsystem implements IProfileSubsystem {
}
}
- public void createProfileConfig(String id, String classId,
- String configPath)
+ private void createProfileConfig(String id, String classId)
throws EProfileException {
+ String configPath;
+ try {
+ configPath = CMS.getConfigStore().getString("instanceRoot")
+ + "/ca/profiles/ca/" + id + ".cfg";
+ } catch (EBaseException e) {
+ throw new EProfileException("CMS_PROFILE_DELETE_ERROR");
+ }
+
try {
if (mProfiles.size() > 0) {
mConfig.putString(PROP_LIST,
@@ -220,110 +230,4 @@ public class ProfileSubsystem implements IProfileSubsystem {
mProfiles.clear();
mProfileClassIds.clear();
}
-
- /**
- * Returns the root configuration storage of this system.
- * <P>
- *
- * @return configuration store of this subsystem
- */
- public IConfigStore getConfigStore() {
- return mConfig;
- }
-
- /**
- * Adds a profile.
- */
- public void addProfile(String id, IProfile profile)
- throws EProfileException {
- }
-
- public boolean isProfileEnable(String id) {
- IProfile profile = mProfiles.get(id);
- String enable = null;
-
- try {
- enable = profile.getConfigStore().getString(PROP_ENABLE);
- } catch (EBaseException e) {
- }
- if (enable == null || enable.equals("false"))
- return false;
- else
- return true;
- }
-
- public String getProfileEnableBy(String id) {
- if (!isProfileEnable(id))
- return null;
- IProfile profile = mProfiles.get(id);
- String enableBy = null;
-
- try {
- enableBy = profile.getConfigStore().getString(PROP_ENABLE_BY);
- } catch (EBaseException e) {
- }
- return enableBy;
- }
-
- /**
- * Enables a profile for execution.
- */
- public void enableProfile(String id, String enableBy)
- throws EProfileException {
- IProfile profile = mProfiles.get(id);
-
- profile.getConfigStore().putString(PROP_ENABLE, "true");
- profile.getConfigStore().putString(PROP_ENABLE_BY, enableBy);
- try {
- profile.getConfigStore().commit(false);
- } catch (EBaseException e) {
- }
- }
-
- /**
- * Disables a profile for execution.
- */
- public void disableProfile(String id)
- throws EProfileException {
- IProfile profile = mProfiles.get(id);
-
- profile.getConfigStore().putString(PROP_ENABLE, "false");
- try {
- profile.getConfigStore().commit(false);
- } catch (EBaseException e) {
- }
- }
-
- /**
- * Retrieves a profile by id.
- */
- public IProfile getProfile(String id)
- throws EProfileException {
- return mProfiles.get(id);
- }
-
- public String getProfileClassId(String id) {
- return mProfileClassIds.get(id);
- }
-
- /**
- * Retrieves a list of profile ids. The return
- * list is of type String.
- */
- public Enumeration<String> getProfileIds() {
- return mProfileIds.elements();
- }
-
- /**
- * Checks if owner id should be enforced during profile approval.
- *
- * @return true if approval should be checked
- */
- public boolean checkOwner() {
- try {
- return mConfig.getBoolean(PROP_CHECK_OWNER, false);
- } catch (EBaseException e) {
- return false;
- }
- }
}