>From 5821f04ec7af44375812b282dbf49d8de8b4b184 Mon Sep 17 00:00:00 2001 From: Fraser Tweedale Date: Thu, 17 Jul 2014 00:24:06 -0400 Subject: [PATCH 06/10] Change ProfileSubsystem to use LDAP database --- .../dogtagpki/server/ca/rest/ProfileService.java | 16 +- .../certsrv/profile/IProfileSubsystem.java | 19 +-- .../cms/servlet/admin/ProfileAdminServlet.java | 30 +--- base/server/cmsbundle/src/UserMessages.properties | 2 + .../com/netscape/cmscore/base/FileConfigStore.java | 4 +- .../netscape/cmscore/profile/ProfileSubsystem.java | 184 ++++++++++++--------- 6 files changed, 114 insertions(+), 141 deletions(-) diff --git a/base/ca/src/org/dogtagpki/server/ca/rest/ProfileService.java b/base/ca/src/org/dogtagpki/server/ca/rest/ProfileService.java index 3b2f8a50ebcd18fe0098b2e92e0300645b904fa3..d3f08b270fd66154da880d47be30ea48716b75bd 100644 --- a/base/ca/src/org/dogtagpki/server/ca/rest/ProfileService.java +++ b/base/ca/src/org/dogtagpki/server/ca/rest/ProfileService.java @@ -18,7 +18,6 @@ package org.dogtagpki.server.ca.rest; -import java.io.File; import java.io.IOException; import java.net.URI; import java.security.Principal; @@ -244,7 +243,7 @@ public class ProfileService extends PKIService implements ProfileResource { data.setAuthenticatorId(profile.getAuthenticatorId()); data.setAuthzAcl(profile.getAuthzAcl()); - data.setClassId(cs.getString(profileId + ".class_id")); + data.setClassId(ps.getProfileClassId(profileId)); data.setDescription(profile.getDescription(getLocale(headers))); data.setEnabled(ps.isProfileEnable(profileId)); data.setEnabledBy(ps.getProfileEnableBy(profileId)); @@ -472,18 +471,13 @@ public class ProfileService extends PKIService implements ProfileResource { auditParams.put("description", data.getDescription()); auditParams.put("visible", Boolean.toString(data.isVisible())); - String config = CMS.getConfigStore().getString("instanceRoot") + "/ca/profiles/ca/" + - profileId + ".cfg"; - File configFile = new File(config); - configFile.createNewFile(); IPluginInfo info = registry.getPluginInfo("profile", data.getClassId()); - profile = ps.createProfile(profileId, data.getClassId(), info.getClassName(), config); + profile = ps.createProfile(profileId, data.getClassId(), info.getClassName()); profile.setName(getLocale(headers), data.getName()); profile.setDescription(getLocale(headers), data.getDescription()); profile.setVisible(data.isVisible()); profile.getConfigStore().commit(false); - ps.createProfileConfig(profileId, data.getClassId(), config); if (profile instanceof IProfileEx) { // populates profile specific plugins such as @@ -504,7 +498,7 @@ public class ProfileService extends PKIService implements ProfileResource { return createCreatedResponse(profileData, profileData.getLink().getHref()); - } catch (EBaseException | IOException e) { + } catch (EBaseException e) { CMS.debug("createProfile: error in creating profile: " + e); e.printStackTrace(); @@ -983,9 +977,7 @@ public class ProfileService extends PKIService implements ProfileResource { "`. Profile must be disabled first."); } - String configFile = CMS.getConfigStore().getString("profile." + profileId + ".config"); - - ps.deleteProfile(profileId, configFile); + ps.deleteProfile(profileId); auditProfileChange( ScopeDef.SC_PROFILE_RULES, diff --git a/base/common/src/com/netscape/certsrv/profile/IProfileSubsystem.java b/base/common/src/com/netscape/certsrv/profile/IProfileSubsystem.java index 3238fb2e686cd3f9aa42dac7997cacd8f7c4c06c..b7071fe7526132d7f9ff1945819f0d1f67c18719 100644 --- a/base/common/src/com/netscape/certsrv/profile/IProfileSubsystem.java +++ b/base/common/src/com/netscape/certsrv/profile/IProfileSubsystem.java @@ -61,33 +61,18 @@ public interface IProfileSubsystem extends ISubsystem { * @param id profile id * @param classid implementation id * @param className class Name - * @param configFile configuration file * @exception EProfileException failed to create profile */ - public IProfile createProfile(String id, String classid, - String className, String configFile) + public IProfile createProfile(String id, String classid, String className) throws EProfileException; /** * Deletes profile. * * @param id profile id - * @param configFile configuration file * @exception EProfileException failed to delete profile */ - public void deleteProfile(String id, String configFile) - throws EProfileException; - - /** - * Creates a new profile configuration file. - * - * @param id profile id - * @param classId implementation id - * @param configPath location to create the configuration file - * @exception failed to create profile - */ - public void createProfileConfig(String id, String classId, - String configPath) throws EProfileException; + public void deleteProfile(String id) throws EProfileException; /** * Enables a profile. diff --git a/base/server/cms/src/com/netscape/cms/servlet/admin/ProfileAdminServlet.java b/base/server/cms/src/com/netscape/cms/servlet/admin/ProfileAdminServlet.java index 3d25b8b71bc7f71a7d579aa6d27bcdc623e49e28..b418baf41a0f84ce5d5ac9da56efd191e1a20316 100644 --- a/base/server/cms/src/com/netscape/cms/servlet/admin/ProfileAdminServlet.java +++ b/base/server/cms/src/com/netscape/cms/servlet/admin/ProfileAdminServlet.java @@ -17,7 +17,6 @@ // --- END COPYRIGHT BLOCK --- package com.netscape.cms.servlet.admin; -import java.io.File; import java.io.IOException; import java.util.Enumeration; import java.util.StringTokenizer; @@ -2290,26 +2289,8 @@ public class ProfileAdminServlet extends AdminServlet { return; } - String config = null; - try { - config = CMS.getConfigStore().getString("profile." + id + ".config"); - } catch (EBaseException e) { - // store a message in the signed audit log file - auditMessage = CMS.getLogMessage( - LOGGING_SIGNED_AUDIT_CONFIG_CERT_PROFILE, - auditSubjectID, - ILogger.FAILURE, - auditParams(req)); - - audit(auditMessage); - - sendResponse(ERROR, null, null, resp); - return; - } - - try { - mProfileSub.deleteProfile(id, config); + mProfileSub.deleteProfile(id); } catch (EProfileException e) { // store a message in the signed audit log file auditMessage = CMS.getLogMessage( @@ -2475,16 +2456,10 @@ public class ProfileAdminServlet extends AdminServlet { IProfile profile = null; - // create configuration file - File configFile = new File(config); - - configFile.createNewFile(); - // create profile try { profile = mProfileSub.createProfile(id, impl, - info.getClassName(), - config); + info.getClassName()); profile.setName(getLocale(req), name); profile.setDescription(getLocale(req), name); if (visible != null && visible.equals("true")) { @@ -2495,7 +2470,6 @@ public class ProfileAdminServlet extends AdminServlet { profile.setAuthenticatorId(auth); profile.getConfigStore().commit(false); - mProfileSub.createProfileConfig(id, impl, config); if (profile instanceof IProfileEx) { // populates profile specific plugins such as // policies, inputs and outputs diff --git a/base/server/cmsbundle/src/UserMessages.properties b/base/server/cmsbundle/src/UserMessages.properties index fe43094e6b2a0531502570bc626da557fc9061ae..cd7fa18bfb1e17bc4ab4aa9e0dac06f815861291 100644 --- a/base/server/cmsbundle/src/UserMessages.properties +++ b/base/server/cmsbundle/src/UserMessages.properties @@ -754,6 +754,8 @@ CMS_PROFILE_CONFIG_KEY_USAGE_EXTENSION_CHECKING=Allow duplicate subject names wi CMS_PROFILE_INTERNAL_ERROR=Profile internal error: {0} CMS_PROFILE_DENY_OPERATION=Not authorized to do this operation. CMS_PROFILE_DELETE_ENABLEPROFILE=Cannot delete enabled profile: {0} +CMS_PROFILE_DELETE_UNKNOWNPROFILE=Cannot delete unknown profile: {0} +CMS_PROFILE_DELETE_DATABASEERROR=Failed to delete profile: {0} CMS_PROFILE_INVALID_REQUEST=Invalid Request CMS_PROFILE_EMPTY_REQUEST_TYPE=Request type is not specified. Check your profile input. CMS_PROFILE_CREATE_POLICY_FAILED=Failed to create profile policy: {0} 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 b77f86d781995e27bb0fe16135fc45a7d6fc4da3..4f8cb2743fdecc354338042a5219a9aaf6e27880 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. *

- * Note that a LdapConfigStore can be implemented so that it reads the configuration stores from the Ldap directory. - *

* * @version $Revision$, $Date$ * @see PropConfigStore 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 27e72352ef22c742b5ea09a180d440d58452dd49..ca0e09b785877da2a98fd2dd54977b8d3ebeaa24 100644 --- a/base/server/cmscore/src/com/netscape/cmscore/profile/ProfileSubsystem.java +++ b/base/server/cmscore/src/com/netscape/cmscore/profile/ProfileSubsystem.java @@ -17,26 +17,30 @@ // --- END COPYRIGHT BLOCK --- package com.netscape.cmscore.profile; -import java.io.File; import java.util.Enumeration; import java.util.Hashtable; -import java.util.StringTokenizer; 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 ProfileSubsystem 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"; @@ -45,9 +49,11 @@ public class ProfileSubsystem implements IProfileSubsystem { private IConfigStore mConfig = null; @SuppressWarnings("unused") private ISubsystem mOwner; - private Vector mProfileIds = new Vector(); - private Hashtable mProfiles = new Hashtable(); - private Hashtable mProfileClassIds = new Hashtable(); + private Vector mProfileIds; + private Hashtable mProfiles; + private Hashtable mProfileClassIds; + + private ILdapConnFactory dbFactory; /** * Retrieves the name of this subsystem. @@ -74,9 +80,20 @@ public class ProfileSubsystem implements IProfileSubsystem { public void init(ISubsystem owner, IConfigStore config) throws EBaseException { CMS.debug("ProfileSubsystem: start init"); + + // (re)init member collections + mProfileIds = new Vector(); + mProfiles = new Hashtable(); + mProfileClassIds = new Hashtable(); + 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; @@ -88,24 +105,46 @@ public class ProfileSubsystem implements IProfileSubsystem { // *.profile2.config=config/profiles/profile2.cfg // read profile id, implementation, and its configuration files - String ids = config.getString(PROP_LIST, ""); - StringTokenizer st = new StringTokenizer(ids, ","); + String basedn = cs.getString("internaldb.basedn"); + String dn = "ou=certificateProfiles,ou=ca," + basedn; + LDAPConnection conn = dbFactory.getConn(); - while (st.hasMoreTokens()) { - String id = st.nextToken(); - IConfigStore subStore = config.getSubStore(id); - String classid = subStore.getString(PROP_CLASS_ID); - IPluginInfo info = registry.getPluginInfo("profile", classid); - if (info == null) { - throw new EBaseException("No plugins for type : profile, with id " + classid); - } - String configPath = subStore.getString(PROP_CONFIG); + String[] attrs = {"cn", "classId"}; + try { + LDAPSearchResults ldapProfiles = conn.search( + dn, LDAPConnection.SCOPE_ONE, "(objectclass=*)", attrs, false); + + while (ldapProfiles.hasMoreElements()) { + String id = ""; + try { + LDAPEntry ldapProfile = ldapProfiles.next(); + + id = (String) + ldapProfile.getAttribute("cn").getStringValues().nextElement(); - CMS.debug("Start Profile Creation - " + id + " " + classid + " " + info.getClassName()); - createProfile(id, classid, info.getClassName(), - configPath); + String classid = (String) + ldapProfile.getAttribute("classId").getStringValues().nextElement(); - CMS.debug("Done Profile Creation - " + id); + 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 ee = getProfileIds(); @@ -120,16 +159,21 @@ public class ProfileSubsystem implements IProfileSubsystem { /** * Creates a profile instance. */ - public IProfile createProfile(String id, String classid, String className, - String configPath) + public IProfile createProfile(String id, String classid, String className) throws EProfileException { - IProfile profile = null; - try { - profile = (IProfile) Class.forName(className).newInstance(); - IConfigStore subStoreConfig = CMS.createFileConfigStore(configPath); + 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("ProfileSubsystem: initing " + className); + IProfile profile = (IProfile) Class.forName(className).newInstance(); profile.setId(id); profile.init(this, subStoreConfig); mProfileIds.addElement(id); @@ -144,63 +188,32 @@ public class ProfileSubsystem implements IProfileSubsystem { return null; } - public void deleteProfile(String id, String configPath) throws EProfileException { - + public void deleteProfile(String id) throws EProfileException { if (isProfileEnable(id)) { throw new EProfileException("CMS_PROFILE_DELETE_ENABLEPROFILE"); } - String ids = ""; + LDAPConnection conn; try { - ids = mConfig.getString(PROP_LIST, ""); - } catch (Exception e) { + conn = dbFactory.getConn(); + } catch (ELdapException e) { + throw new EProfileException("Error acquiring the ldap connection" + e.toString()); } - - StringTokenizer tokenizer = new StringTokenizer(ids, ","); - StringBuffer list = new StringBuffer(); - - while (tokenizer.hasMoreTokens()) { - String element = tokenizer.nextToken(); - - if (!element.equals(id)) { - list.append(element + ","); + try { + conn.delete(createProfileDN(id)); + } catch (LDAPException e) { + throw new EProfileException("CMS_PROFILE_DELETE_DATABASEERROR"); + } finally { + try { + dbFactory.returnConn(conn); + } catch (Exception e) { + throw new EProfileException("Error releasing the ldap connection" + e.toString()); } } - if (list.length() != 0) - list.deleteCharAt(list.length() - 1); - mConfig.putString(PROP_LIST, list.toString()); - mConfig.removeSubStore(id); - File file1 = new File(configPath); - - if (!file1.delete()) { - CMS.debug("ProfileSubsystem: deleteProfile: Cannot delete the configuration file : " + configPath); - } mProfileIds.removeElement(id); mProfiles.remove(id); mProfileClassIds.remove(id); - try { - CMS.getConfigStore().commit(false); - } catch (Exception e) { - } - } - - public void createProfileConfig(String id, String classId, - String configPath) - throws EProfileException { - try { - if (mProfiles.size() > 0) { - mConfig.putString(PROP_LIST, - mConfig.getString(PROP_LIST) + "," + id); - } else { - mConfig.putString(PROP_LIST, id); - } - mConfig.putString(id + "." + PROP_CLASS_ID, classId); - mConfig.putString(id + "." + PROP_CONFIG, configPath); - CMS.getConfigStore().commit(true); - } catch (EBaseException e) { - CMS.debug(e.toString()); - } } /** @@ -231,13 +244,6 @@ public class ProfileSubsystem implements IProfileSubsystem { 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; @@ -326,4 +332,20 @@ public class ProfileSubsystem implements IProfileSubsystem { return false; } } + + /** + * Compute the profile DN given an ID. + */ + private String createProfileDN(String id) throws EProfileException { + if (id == null) { + throw new EProfileException("CMS_PROFILE_DELETE_UNKNOWNPROFILE"); + } + 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; + } } -- 1.9.3