diff options
Diffstat (limited to 'pki/base')
30 files changed, 1821 insertions, 268 deletions
diff --git a/pki/base/ca/shared/conf/CS.cfg b/pki/base/ca/shared/conf/CS.cfg index 7d8fd4140..f97af9022 100644 --- a/pki/base/ca/shared/conf/CS.cfg +++ b/pki/base/ca/shared/conf/CS.cfg @@ -638,12 +638,28 @@ cms.version= cmsgateway.enableAdminEnroll=false https.port=8443 http.port=8080 +dbs.enableSerialManagement=false dbs.beginRequestNumber=1 dbs.endRequestNumber=10000000 -dbs.requestNumber.increment=10000000 +dbs.requestIncrement=10000000 +dbs.requestLowWaterMark=2000000 +dbs.requestCloneTransferNumber=10000 +dbs.requestDN=ou=ca, ou=requests +dbs.requestRangeDN=ou=requests, ou=ranges dbs.beginSerialNumber=1 dbs.endSerialNumber=10000000 -dbs.serialNumber.increment=10000000 +dbs.serialIncrement=10000000 +dbs.serialLowWaterMark=2000000 +dbs.serialCloneTransferNumber=10000 +dbs.serialDN=ou=certificateRepository, ou=ca +dbs.serialRangeDN=ou=certificateRepository, ou=ranges +dbs.beginReplicaNumber=1 +dbs.endReplicaNumber=100 +dbs.replicaIncrement=100 +dbs.replicaLowWaterMark=20 +dbs.replicaCloneTransferNumber=5 +dbs.replicaDN=ou=replica +dbs.replicaRangeDN=ou=replica, ou=ranges dbs.ldap=internaldb dbs.newSchemaEntryAdded=true debug.append=true diff --git a/pki/base/ca/shared/conf/db.ldif b/pki/base/ca/shared/conf/db.ldif index 72f5b8e17..ee71cc32f 100644 --- a/pki/base/ca/shared/conf/db.ldif +++ b/pki/base/ca/shared/conf/db.ldif @@ -132,3 +132,32 @@ objectClass: top objectClass: repository ou: ca serialno: 010 + +dn: ou=replica,{rootSuffix} +objectClass: top +objectClass: repository +ou: replica +serialno: 010 +nextRange: 1000 + +dn: ou=ranges,{rootSuffix} +objectClass: top +objectClass: organizationalUnit +ou: ranges + +dn: ou=replica, ou=ranges,{rootSuffix} +objectClass: top +objectClass: organizationalUnit +ou: replica + +dn: ou=requests, ou=ranges,{rootSuffix} +objectClass: top +objectClass: organizationalUnit +ou: requests + +dn: ou=certificateRepository, ou=ranges,{rootSuffix} +objectClass: top +objectClass: organizationalUnit +ou: certificateRepository + + diff --git a/pki/base/ca/shared/conf/schema.ldif b/pki/base/ca/shared/conf/schema.ldif index 7331749ce..823543dcf 100644 --- a/pki/base/ca/shared/conf/schema.ldif +++ b/pki/base/ca/shared/conf/schema.ldif @@ -301,6 +301,21 @@ attributeTypes: ( serialno-oid NAME 'serialno' DESC 'CMS defined attribute' SYNT dn: cn=schema changetype: modify add: attributeTypes +attributeTypes: ( nextRange-oid NAME 'nextRange' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' ) + +dn: cn=schema +changetype: modify +add: attributeTypes +attributeTypes: ( beginRange-oid NAME 'beginRange' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' ) + +dn: cn=schema +changetype: modify +add: attributeTypes +attributeTypes: ( endRange-oid NAME 'endRange' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' ) + +dn: cn=schema +changetype: modify +add: attributeTypes attributeTypes: ( subjectName-oid NAME 'subjectName' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' ) dn: cn=schema @@ -376,7 +391,7 @@ objectClasses: ( CertACLS-oid NAME 'CertACLS' DESC 'CMS defined class' SUP top S dn: cn=schema changetype: modify add: objectClasses -objectClasses: ( repository-oid NAME 'repository' DESC 'CMS defined class' SUP top STRUCTURAL MUST ou MAY ( serialno $ description ) X-ORIGIN 'user defined' ) +objectClasses: ( repository-oid NAME 'repository' DESC 'CMS defined class' SUP top STRUCTURAL MUST ou MAY ( serialno $ description $ nextRange ) X-ORIGIN 'user defined' ) dn: cn=schema changetype: modify @@ -428,4 +443,8 @@ changetype: modify add: objectClasses objectClasses: ( pkiSubsystem-oid NAME 'pkiSubsystem' DESC 'CMS defined class' SUP top STRUCTURAL MUST ( cn $ Host $ SecurePort $ SubsystemName $ Clone ) MAY ( DomainManager ) X-ORIGIN 'user defined' ) +dn: cn=schema +changetype: modify +add: objectClasses +objectClasses: ( pkiRange-oid NAME 'pkiRange' DESC 'CMS defined class' SUP top STRUCTURAL MUST ( cn $ beginRange $ endRange $ Host $ SecurePort ) X-ORIGIN 'user defined' ) diff --git a/pki/base/ca/src/com/netscape/ca/CertificateAuthority.java b/pki/base/ca/src/com/netscape/ca/CertificateAuthority.java index 151b15ccf..4f459ee4a 100644 --- a/pki/base/ca/src/com/netscape/ca/CertificateAuthority.java +++ b/pki/base/ca/src/com/netscape/ca/CertificateAuthority.java @@ -44,6 +44,7 @@ import com.netscape.certsrv.dbs.*; import com.netscape.certsrv.dbs.repository.*; import com.netscape.cmscore.dbs.*; import com.netscape.certsrv.dbs.certdb.*; +import com.netscape.certsrv.dbs.replicadb.*; import com.netscape.certsrv.dbs.crldb.*; import com.netscape.certsrv.dbs.crldb.ICRLRepository; import com.netscape.certsrv.apps.*; @@ -104,6 +105,7 @@ public class CertificateAuthority implements ICertificateAuthority, ICertAuthori protected CertificateRepository mCertRepot = null; protected CRLRepository mCRLRepot = null; + protected ReplicaIDRepository mReplicaRepot = null; protected CertificateChain mCACertChain = null; protected CertificateChain mOCSPCertChain = null; @@ -144,6 +146,7 @@ public class CertificateAuthority implements ICertificateAuthority, ICertAuthori protected static final String PROP_CERT_REPOS_DN = "CertificateRepositoryDN"; protected static final String PROP_REPOS_DN = "RepositoryDN"; + protected static final String PROP_REPLICAID_DN = "dbs.replicadn"; // for the notification listeners @@ -267,21 +270,23 @@ public class CertificateAuthority implements ICertificateAuthority, ICertAuthori // init default CA attributes like cert version, validity. initDefCaAttrs(); + // init web gateway. + initWebGateway(); + + // init request queue and related modules. + CMS.debug("CertificateAuthority init: initRequestQueue"); + initRequestQueue(); + // set certificate status to 10 minutes mCertRepot.setCertStatusUpdateInterval( + mRequestQueue.getRequestRepository(), mConfig.getInteger("certStatusUpdateInterval", 10 * 60), mConfig.getBoolean("listenToCloneModifications", false)); mCertRepot.setConsistencyCheck( mConfig.getBoolean("ConsistencyCheck", false)); mCertRepot.setSkipIfInConsistent( mConfig.getBoolean("SkipIfInConsistent", false)); - - // init web gateway. - initWebGateway(); - - // init request queue and related modules. - CMS.debug("CertificateAuthority init: initRequestQueue"); - initRequestQueue(); + mService.init(config.getSubStore("connector")); initMiscellaneousListeners(); @@ -569,6 +574,17 @@ public class CertificateAuthority implements ICertificateAuthority, ICertAuthori public ICertificateRepository getCertificateRepository() { return mCertRepot; } + + /** + * Retrieves replica repository. + * <P> + * + * @return replica repository + */ + public IReplicaIDRepository getReplicaRepository() { + return mReplicaRepot; + } + /** * Retrieves CRL repository. @@ -1317,6 +1333,15 @@ public class CertificateAuthority implements ICertificateAuthority, ICertAuthori "ou=crlIssuingPoints, ou=" + getId() + ", " + getDBSubsystem().getBaseDN()); CMS.debug("CRL Repot inited"); + + String replicaReposDN = mConfig.getString(PROP_REPLICAID_DN, null); + if (replicaReposDN == null) { + replicaReposDN = "ou=Replica," + getDBSubsystem().getBaseDN(); + } + mReplicaRepot = new ReplicaIDRepository( + DBSubsystem.getInstance(), 1, replicaReposDN); + CMS.debug("Replica Repot inited"); + } /** diff --git a/pki/base/common/src/com/netscape/certsrv/ca/ICertificateAuthority.java b/pki/base/common/src/com/netscape/certsrv/ca/ICertificateAuthority.java index 311a7891b..a828a69bf 100644 --- a/pki/base/common/src/com/netscape/certsrv/ca/ICertificateAuthority.java +++ b/pki/base/common/src/com/netscape/certsrv/ca/ICertificateAuthority.java @@ -34,6 +34,7 @@ import com.netscape.certsrv.security.*; import com.netscape.certsrv.publish.*; import com.netscape.certsrv.dbs.certdb.*; import com.netscape.certsrv.dbs.crldb.*; +import com.netscape.certsrv.dbs.replicadb.*; /** @@ -243,6 +244,13 @@ public interface ICertificateAuthority extends ISubsystem { public ICRLRepository getCRLRepository(); /** + * Retrieves the Replica ID repository. + * + * @return CA's Replica ID repository + */ + public IReplicaIDRepository getReplicaRepository(); + + /** * Retrieves the request in queue listener. * * @return the request in queue listener diff --git a/pki/base/common/src/com/netscape/certsrv/dbs/IDBSubsystem.java b/pki/base/common/src/com/netscape/certsrv/dbs/IDBSubsystem.java index e3914427f..933fd607c 100644 --- a/pki/base/common/src/com/netscape/certsrv/dbs/IDBSubsystem.java +++ b/pki/base/common/src/com/netscape/certsrv/dbs/IDBSubsystem.java @@ -37,6 +37,13 @@ public interface IDBSubsystem extends ISubsystem { public static final String SUB_ID = "dbs"; + + // values for repos + public static final int CERTS = 0; + public static final int REQUESTS = 1; + public static final int REPLICA_ID = 2; + public static final int NUM_REPOS = 3; + /** * Retrieves the base DN. * @@ -85,25 +92,118 @@ public interface IDBSubsystem extends ISubsystem { * Records maximum serial number limit in config file * * @param serial max serial number + * @param repo repo identifier + * @exception EBaseException failed to set + */ + public void setMaxSerialConfig(int repo, String serial) throws EBaseException; + + /** + * Records minimum serial number limit in config file + * + * @param serial min serial number + * @param repo repo identifier + * @exception EBaseException failed to set + */ + public void setMinSerialConfig(int repo, String serial) throws EBaseException; + + /** + * Records maximum serial number limit for the next range in config file + * + * @param serial max serial number + * @param repo repo identifier * @exception EBaseException failed to set */ - public void setMaxSerialConfig(String serial) throws EBaseException; + public void setNextMaxSerialConfig(int repo, String serial) throws EBaseException; + /** + * Records minimum serial number limit for the next range in config file + * + * @param serial min serial number + * @param repo repo identifier + * @exception EBaseException failed to set + */ + public void setNextMinSerialConfig(int repo, String serial) throws EBaseException; - public String getMinSerialConfig(); + /** + * Gets minimum serial number limit in config file + * + * @param repo repo identifier + * @return min serial number + */ + public String getMinSerialConfig(int repo); /** * Gets the maximum serial number limit in config file * + * @param repo repo identifier * @return max serial number */ - public String getMaxSerialConfig(); + public String getMaxSerialConfig(int repo); + /** + * Gets the maximum serial number limit for next range in config file + * + * @param repo repo identifier + * @return max serial number + */ + public String getNextMaxSerialConfig(int repo); - public String getMinRequestConfig(); + /** + * Gets minimum serial number limit for next range in config file + * + * @param repo repo identifier + * @return min serial number + */ + public String getNextMinSerialConfig(int repo); + + /** + * Gets low water mark limit in config file + * + * @param repo repo identifier + * @return low water mark + */ + public String getLowWaterMarkConfig(int repo); - public String getMaxRequestConfig(); + /** + * Gets range increment limit for next range in config file + * + * @param repo repo identifier + * @return range increment + */ + public String getIncrementConfig(int repo); + + /** + * Gets number corresponding to start of next range from database + * + * @param repo repo identifier + * @return start of next range + */ + public String getNextRange(int repo); + /** + * Determines if a range conflict has been observed in database + * + * @param repo repo identifier + * @return true if range conflict, false otherwise + */ + public boolean hasRangeConflict(int repo); + + /** + * Determines if serial number management has been enabled + * + * @param repo repo identifier + * @return true if enabled, false otherwise + */ + public boolean getEnableSerialMgmt(); + + /** + * Sets whether serial number management is enabled for certs + * and requests. + * + * @param value true/false + * @exception EBaseException failed to set + */ + public void setEnableSerialMgmt(boolean value) throws EBaseException; /** * Returns LDAP connection to connection pool. diff --git a/pki/base/common/src/com/netscape/certsrv/dbs/certdb/ICertificateRepository.java b/pki/base/common/src/com/netscape/certsrv/dbs/certdb/ICertificateRepository.java index 3b76bbbf3..4b89650ee 100644 --- a/pki/base/common/src/com/netscape/certsrv/dbs/certdb/ICertificateRepository.java +++ b/pki/base/common/src/com/netscape/certsrv/dbs/certdb/ICertificateRepository.java @@ -76,10 +76,12 @@ public interface ICertificateRepository extends IRepository { /** * Sets certificate status update internal * + * @param requestRepo request repository * @param interval update interval * @param listenToCloneModifications enable listening to clone modifications */ - public void setCertStatusUpdateInterval(int interval, + public void setCertStatusUpdateInterval(IRepository requestRepo, + int interval, boolean listenToCloneModifications); /** diff --git a/pki/base/common/src/com/netscape/certsrv/dbs/replicadb/IReplicaIDRepository.java b/pki/base/common/src/com/netscape/certsrv/dbs/replicadb/IReplicaIDRepository.java new file mode 100644 index 000000000..6448e8d3a --- /dev/null +++ b/pki/base/common/src/com/netscape/certsrv/dbs/replicadb/IReplicaIDRepository.java @@ -0,0 +1,32 @@ +// --- 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.certsrv.dbs.replicadb; + +import com.netscape.certsrv.dbs.*; +import com.netscape.certsrv.dbs.repository.*; + + +/** + * An interface represents a ReplicaID Repository. + * It provides unique managed replica IDs. + * <P> + * + * @version $Revision: 14561 $, $Date: 2008-11-18 10:28:56 -0700 (Tue, 18 Nov 2008) $ + */ +public interface IReplicaIDRepository extends IRepository { +} diff --git a/pki/base/common/src/com/netscape/certsrv/dbs/repository/IRepository.java b/pki/base/common/src/com/netscape/certsrv/dbs/repository/IRepository.java index 15162e77e..aed6a5482 100644 --- a/pki/base/common/src/com/netscape/certsrv/dbs/repository/IRepository.java +++ b/pki/base/common/src/com/netscape/certsrv/dbs/repository/IRepository.java @@ -34,17 +34,59 @@ import com.netscape.certsrv.dbs.*; */ public interface IRepository { - /** - * Retrieves the next serial number, and also increase the - * serial number by one. - * - * @return serial number + /** + * Retrieves the next serial number, and also increase the + * serial number by one. + * + * @return serial number * @exception EBaseException failed to retrieve next serial number - */ - public BigInteger getNextSerialNumber() throws EBaseException; + */ + public BigInteger getNextSerialNumber() throws EBaseException; /** * Resets serial number. */ public void resetSerialNumber(BigInteger serial) throws EBaseException; + + /** + * Retrieves the next serial number without increasing the serial number. + * + * @return serial number + * @exception EBaseException failed to retrieve next serial number + */ + public BigInteger getTheSerialNumber() throws EBaseException; + + /** + * Set the maximum serial number. + * + * @param serial maximum number + * @exception EBaseException failed to set maximum serial number + */ + public void setMaxSerial (String serial) throws EBaseException; + + /** + * Set the maximum serial number in next range. + * + * @param serial maximum number + * @exception EBaseException failed to set maximum serial number in next range + */ + public void setNextMaxSerial(String serial) throws EBaseException; + + /** + * Checks to see if a new range is needed, or if we have reached the end of the + * current range, or if a range conflict has occurred. + * + * @exception EBaseException failed to check next range for conflicts + */ + public void checkRanges() throws EBaseException; + + /** + * Sets whether serial number management is enabled for certs + * and requests. + * + * @param value true/false + * @exception EBaseException failed to set + */ + public void setEnableSerialMgmt(boolean value) throws EBaseException; + } diff --git a/pki/base/common/src/com/netscape/certsrv/kra/IKeyRecoveryAuthority.java b/pki/base/common/src/com/netscape/certsrv/kra/IKeyRecoveryAuthority.java index 40e8831ce..a2174d7cd 100644 --- a/pki/base/common/src/com/netscape/certsrv/kra/IKeyRecoveryAuthority.java +++ b/pki/base/common/src/com/netscape/certsrv/kra/IKeyRecoveryAuthority.java @@ -28,6 +28,7 @@ import com.netscape.certsrv.logging.*; import com.netscape.certsrv.base.*; import com.netscape.certsrv.dbs.*; import com.netscape.certsrv.dbs.keydb.*; +import com.netscape.certsrv.dbs.replicadb.*; import com.netscape.certsrv.request.*; import com.netscape.certsrv.policy.*; import com.netscape.certsrv.security.*; @@ -87,6 +88,13 @@ public interface IKeyRecoveryAuthority extends ISubsystem { public IKeyRepository getKeyRepository(); /** + * Retrieves the Replica ID repository. + * + * @return KRA's Replica ID repository + */ + public IReplicaIDRepository getReplicaRepository(); + + /** * Enables the auto recovery state. Once KRA is in the auto * recovery state, no recovery agents need to be present for * providing credentials. This feature is for enabling diff --git a/pki/base/common/src/com/netscape/certsrv/request/IRequestQueue.java b/pki/base/common/src/com/netscape/certsrv/request/IRequestQueue.java index f37421ffd..cfbea225f 100644 --- a/pki/base/common/src/com/netscape/certsrv/request/IRequestQueue.java +++ b/pki/base/common/src/com/netscape/certsrv/request/IRequestQueue.java @@ -19,6 +19,7 @@ package com.netscape.certsrv.request; import java.math.*; import java.util.Enumeration; +import com.netscape.certsrv.dbs.repository.IRepository; import com.netscape.certsrv.base.EBaseException; @@ -399,4 +400,11 @@ public interface IRequestQueue { * Removes all objects with this repository. */ public void removeAllObjects() throws EBaseException; + + /** + * Gets request repository. + * + * @return request repository + */ + public IRepository getRequestRepository(); } diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/DatabasePanel.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/DatabasePanel.java index 985b5f244..e9523e52b 100644 --- a/pki/base/common/src/com/netscape/cms/servlet/csadmin/DatabasePanel.java +++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/DatabasePanel.java @@ -928,19 +928,6 @@ public class DatabasePanel extends WizardPanelBase { } catch (Exception e) { } - if (select.equals("clone")) { - CMS.debug("Start setting up replication."); - setupReplication(request, context, (secure.equals("on")?"true":"false")); - CMS.debug("Finish setting up replication."); - - try { - CMS.reinit(IDBSubsystem.SUB_ID); - CMS.reinit(IAuthSubsystem.ID); - CMS.reinit(IAuthzSubsystem.ID); - } catch (Exception e) { - } - } - // always populate the index the last try { CMS.debug("Populating local indexes"); @@ -974,6 +961,21 @@ public class DatabasePanel extends WizardPanelBase { CMS.debug("Populating index failure - " + e); } + // setup replication after indexes have been created + if (select.equals("clone")) { + CMS.debug("Start setting up replication."); + setupReplication(request, context, (secure.equals("on")?"true":"false")); + CMS.debug("Finish setting up replication."); + + try { + CMS.reinit(IDBSubsystem.SUB_ID); + CMS.reinit(IAuthSubsystem.ID); + CMS.reinit(IAuthzSubsystem.ID); + } catch (Exception e) { + } + } + + if (hasErr == false) { cs.putBoolean("preop.Database.done", true); try { @@ -1072,8 +1074,11 @@ public class DatabasePanel extends WizardPanelBase { String replicadn = "cn=replica,cn=\""+suffix+"\",cn=mapping tree,cn=config"; CMS.debug("DatabasePanel setupReplication: replicadn="+replicadn); - createReplicationManager(conn1, master1_replicationpwd); - createReplicationManager(conn2, master2_replicationpwd); + String masterBindUser = "Replication Manager " + masterAgreementName; + String cloneBindUser = "Replication Manager " + cloneAgreementName; + + createReplicationManager(conn1, masterBindUser, master1_replicationpwd); + createReplicationManager(conn2, cloneBindUser, master2_replicationpwd); String dir1 = getInstanceDir(conn1); createChangeLog(conn1, dir1 + "/changelogs"); @@ -1081,16 +1086,19 @@ public class DatabasePanel extends WizardPanelBase { String dir2 = getInstanceDir(conn2); createChangeLog(conn2, dir2 + "/changelogs"); - enableReplication(replicadn, conn1, basedn, "1"); - enableReplication(replicadn, conn2, basedn, "2"); + int replicaId = cs.getInteger("dbs.beginReplicaNumber", 1); + + replicaId = enableReplication(replicadn, conn1, masterBindUser, basedn, replicaId); + replicaId = enableReplication(replicadn, conn2, cloneBindUser, basedn, replicaId); + cs.putString("dbs.beginReplicaNumber", Integer.toString(replicaId)); CMS.debug("DatabasePanel setupReplication: Finished enabling replication"); createReplicationAgreement(replicadn, conn1, masterAgreementName, - master2_hostname, master2_port, master2_replicationpwd, basedn); + master2_hostname, master2_port, master2_replicationpwd, basedn, cloneBindUser); createReplicationAgreement(replicadn, conn2, cloneAgreementName, - master1_hostname, master1_port, master1_replicationpwd, basedn); + master1_hostname, master1_port, master1_replicationpwd, basedn, masterBindUser); // initialize consumer initializeConsumer(replicadn, conn1, masterAgreementName); @@ -1170,20 +1178,19 @@ public class DatabasePanel extends WizardPanelBase { return false; } - private void createReplicationManager(LDAPConnection conn, String pwd) + private void createReplicationManager(LDAPConnection conn, String bindUser, String pwd) throws LDAPException { LDAPAttributeSet attrs = null; LDAPEntry entry = null; - String dn = "cn=Replication Manager,cn=config"; + String dn = "cn=" + bindUser + ",cn=config"; try { attrs = new LDAPAttributeSet(); attrs.add(new LDAPAttribute("objectclass", "top")); attrs.add(new LDAPAttribute("objectclass", "person")); attrs.add(new LDAPAttribute("userpassword", pwd)); - attrs.add(new LDAPAttribute("cn", "Replication Manager")); + attrs.add(new LDAPAttribute("cn", bindUser)); attrs.add(new LDAPAttribute("sn", "manager")); - entry = new LDAPEntry("cn=Replication Manager,cn=config", - attrs); + entry = new LDAPEntry(dn, attrs); conn.add(entry); } catch (LDAPException e) { if (e.getLDAPResultCode() == LDAPException.ENTRY_ALREADY_EXISTS) { @@ -1201,7 +1208,7 @@ public class DatabasePanel extends WizardPanelBase { } } - CMS.debug("DatabasePanel createReplicationManager: Successfully create Replication Manager"); + CMS.debug("DatabasePanel createReplicationManager: Successfully created Replication Manager"); } private void createChangeLog(LDAPConnection conn, String dir) @@ -1238,7 +1245,7 @@ public class DatabasePanel extends WizardPanelBase { CMS.debug("DatabasePanel createChangeLog: Successfully create change log entry"); } - private void enableReplication(String replicadn, LDAPConnection conn, String basedn, String id) + private int enableReplication(String replicadn, LDAPConnection conn, String bindUser, String basedn, int id) throws LDAPException { CMS.debug("DatabasePanel enableReplication: replicadn: "+replicadn); LDAPAttributeSet attrs = null; @@ -1251,33 +1258,42 @@ public class DatabasePanel extends WizardPanelBase { attrs.add(new LDAPAttribute("nsDS5ReplicaRoot", basedn)); attrs.add(new LDAPAttribute("nsDS5ReplicaType", "3")); attrs.add(new LDAPAttribute("nsDS5ReplicaBindDN", - "cn=replication manager,cn=config")); + "cn=" + bindUser + ",cn=config")); attrs.add(new LDAPAttribute("cn", "replica")); - attrs.add(new LDAPAttribute("nsDS5ReplicaId", id)); + attrs.add(new LDAPAttribute("nsDS5ReplicaId", Integer.toString(id))); attrs.add(new LDAPAttribute("nsds5flags", "1")); entry = new LDAPEntry(replicadn, attrs); conn.add(entry); } catch (LDAPException e) { if (e.getLDAPResultCode() == LDAPException.ENTRY_ALREADY_EXISTS) { - CMS.debug("DatabasePanel enableReplication: "+replicadn+" has already used"); + /* BZ 470918 -we cant just add the new dn. We need to do a replace instead + * until the DS code is fixed */ + CMS.debug("DatabasePanel enableReplication: "+replicadn+" has already been used"); + try { - conn.delete(replicadn); - conn.add(entry); + entry = conn.read(replicadn); + LDAPAttribute attr = entry.getAttribute("nsDS5ReplicaBindDN"); + attr.addValue( "cn=" + bindUser + ",cn=config"); + LDAPModification mod = new LDAPModification(LDAPModification.REPLACE, attr); + conn.modify(replicadn, mod); } catch (LDAPException ee) { + CMS.debug("DatabasePanel enableReplication: Failed to modify " + +replicadn+" entry. Exception: "+e.toString()); } - return; + return id; } else { CMS.debug("DatabasePanel enableReplication: Failed to create "+replicadn+" entry. Exception: "+e.toString()); - return; + return id; } } CMS.debug("DatabasePanel enableReplication: Successfully create "+replicadn+" entry."); + return id + 1; } private void createReplicationAgreement(String replicadn, LDAPConnection conn, String name, String replicahost, int replicaport, - String replicapwd, String basedn) throws LDAPException { + String replicapwd, String basedn, String bindUser) throws LDAPException { String dn = "cn="+name+","+replicadn; CMS.debug("DatabasePanel createReplicationAgreement: dn: "+dn); LDAPEntry entry = null; @@ -1292,7 +1308,7 @@ public class DatabasePanel extends WizardPanelBase { attrs.add(new LDAPAttribute("nsDS5ReplicaHost", replicahost)); attrs.add(new LDAPAttribute("nsDS5ReplicaPort", ""+replicaport)); attrs.add(new LDAPAttribute("nsDS5ReplicaBindDN", - "cn=replication manager,cn=config")); + "cn=" + bindUser + ",cn=config")); attrs.add(new LDAPAttribute("nsDS5ReplicaBindMethod", "Simple")); attrs.add(new LDAPAttribute("nsds5replicacredentials", replicapwd)); CMS.debug("About to set description attr to " + name); diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/DonePanel.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/DonePanel.java index f6cd67e32..583548257 100644 --- a/pki/base/common/src/com/netscape/cms/servlet/csadmin/DonePanel.java +++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/DonePanel.java @@ -289,6 +289,7 @@ public class DonePanel extends WizardPanelBase { } cs.putString("securitydomain.store", "ldap"); CMS.debug("DonePanel display: finish updating domain info"); + conn.disconnect(); } catch (Exception e) { CMS.debug("DonePanel display: "+e.toString()); } @@ -397,12 +398,30 @@ public class DonePanel extends WizardPanelBase { BigInteger endRequestNum = new BigInteger(endRequestNumStr); BigInteger endSerialNum = new BigInteger(endSerialNumStr); BigInteger oneNum = new BigInteger("1"); - cs.putString("dbs.nextBeginRequestNumber", - endRequestNum.add(oneNum).toString()); - cs.putString("dbs.nextBeginSerialNumber", - endSerialNum.add(oneNum).toString()); + + // update global next range entries + LDAPConnection conn = getLDAPConn(context); + String basedn = cs.getString("internaldb.basedn"); + + String serialdn = ""; + if (type.equals("CA")) { + serialdn = "ou=certificateRepository,ou=" + type.toLowerCase() + "," + basedn; + } else { + serialdn = "ou=keyRepository,ou=" + type.toLowerCase() + "," + basedn; + } + LDAPAttribute attrSerialNextRange = new LDAPAttribute( "nextRange", endSerialNum.add(oneNum).toString()); + LDAPModification serialmod = new LDAPModification( LDAPModification.REPLACE, attrSerialNextRange ); + conn.modify( serialdn, serialmod ); + + String requestdn = "ou=" + type.toLowerCase() + ",ou=requests," + basedn; + LDAPAttribute attrRequestNextRange = new LDAPAttribute( "nextRange", endRequestNum.add(oneNum).toString()); + LDAPModification requestmod = new LDAPModification( LDAPModification.REPLACE, attrRequestNextRange ); + conn.modify( requestdn, requestmod ); + + conn.disconnect(); } catch (Exception e) { - } + CMS.debug("Unable to update global next range numbers: " + e); + } } } diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/RestoreKeyCertPanel.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/RestoreKeyCertPanel.java index dbbe90d27..0cb7feba6 100644 --- a/pki/base/common/src/com/netscape/cms/servlet/csadmin/RestoreKeyCertPanel.java +++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/RestoreKeyCertPanel.java @@ -352,24 +352,15 @@ public class RestoreKeyCertPanel extends WizardPanelBase { String content = ""; if (cstype.equals("ca") || cstype.equals("kra")) { - String increment = config.getString("dbs.requestNumber.increment", ""); - String previncrement = config.getString("dbs.requestNumber.previncrement", ""); - if (!increment.equals(previncrement)) { - content = "type=request&xmlOutput=true&sessionID="+session_id+"&increment="+increment; - CMS.debug("http content=" + content); - updateNumberRange(master_hostname, master_port, true, content, "request", response); - config.putString("dbs.requestNumber.previncrement", increment); - config.commit(false); - } + content = "type=request&xmlOutput=true&sessionID="+session_id; + CMS.debug("http content=" + content); + updateNumberRange(master_hostname, master_port, true, content, "request", response); - previncrement = config.getString("dbs.serialNumber.previncrement", ""); - increment = config.getString("dbs.serialNumber.increment", ""); - if (!increment.equals(previncrement)) { - content = "type=serialNo&xmlOutput=true&sessionID="+session_id+"&increment="+increment; - updateNumberRange(master_hostname, master_port, true, content, "serialNo", response); - config.putString("dbs.serialNumber.previncrement", increment); - config.commit(false); - } + content = "type=serialNo&xmlOutput=true&sessionID="+session_id; + updateNumberRange(master_hostname, master_port, true, content, "serialNo", response); + + content = "type=replicaId&xmlOutput=true&sessionID="+session_id; + updateNumberRange(master_hostname, master_port, true, content, "replicaId", response); } String list = ""; diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/UpdateDomainXML.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/UpdateDomainXML.java index 21cf773c8..2b9f7328b 100644 --- a/pki/base/common/src/com/netscape/cms/servlet/csadmin/UpdateDomainXML.java +++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/UpdateDomainXML.java @@ -199,10 +199,19 @@ public class UpdateDomainXML extends CMSServlet { HttpServletResponse httpResp = cmsReq.getHttpResp(); CMS.debug("UpdateDomainXML process: authentication starts"); - IAuthToken authToken = authenticate(cmsReq); + IAuthToken authToken = null; + try { + authToken = authenticate(cmsReq); + } catch (Exception e) { + log(ILogger.LL_FAILURE, + CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString())); + outputError(httpResp, AUTH_FAILURE, "Error: Not authenticated"); + return; + } if (authToken == null) { CMS.debug("UpdateDomainXML process: authToken is null"); - outputError(httpResp, "Error: not authenticated"); + outputError(httpResp, AUTH_FAILURE, "Error: not authenticated"); + return; } CMS.debug("UpdateDomainXML process: authentication done"); @@ -214,18 +223,19 @@ public class UpdateDomainXML extends CMSServlet { } catch (EAuthzAccessDenied e) { log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString())); - outputError(httpResp, "Error: Not authorized"); + outputError(httpResp, AUTH_FAILURE, "Error: Not authorized"); return; } catch (Exception e) { log(ILogger.LL_FAILURE, CMS.getLogMessage("ADMIN_SRVLT_AUTH_FAILURE", e.toString())); outputError(httpResp, + AUTH_FAILURE, "Error: Encountered problem during authorization."); return; } if (authzToken == null) { CMS.debug("UpdateDomainXML process: authorization error"); - outputError(httpResp, "Error: Not authorized"); + outputError(httpResp, AUTH_FAILURE, "Error: Not authorized"); return; } diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/UpdateNumberRange.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/UpdateNumberRange.java index 9c2ed9123..01126e228 100644 --- a/pki/base/common/src/com/netscape/cms/servlet/csadmin/UpdateNumberRange.java +++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/UpdateNumberRange.java @@ -34,11 +34,14 @@ import com.netscape.certsrv.policy.*; import com.netscape.certsrv.request.IRequest; import com.netscape.certsrv.dbs.*; import com.netscape.certsrv.dbs.certdb.*; +import com.netscape.certsrv.dbs.repository.*; import com.netscape.certsrv.ldap.*; import com.netscape.certsrv.logging.*; import com.netscape.certsrv.apps.CMS; import com.netscape.certsrv.authentication.*; import com.netscape.certsrv.authorization.*; +import com.netscape.certsrv.ca.*; +import com.netscape.certsrv.kra.*; import com.netscape.cms.servlet.*; import com.netscape.cmsutil.xml.*; import org.w3c.dom.*; @@ -115,48 +118,98 @@ public class UpdateNumberRange extends CMSServlet { try { String type = httpReq.getParameter("type"); - String incrementStr = httpReq.getParameter("increment"); - BigInteger increment = new BigInteger(incrementStr); IConfigStore cs = CMS.getConfigStore(); + String cstype = cs.getString("cs.type", ""); BigInteger beginNum = null; BigInteger endNum = null; BigInteger oneNum = new BigInteger("1"); - BigInteger nextNum = null; - if (type.equals("request")) { - String beginNumStr = cs.getString("dbs.nextBeginRequestNumber"); - beginNum = new BigInteger(beginNumStr); - if( beginNum == null ) { - CMS.debug( "UpdateNumberRange::process() - " + - "request beginNum is null!" ); - return; + String endNumConfig = null; + String cloneNumConfig = null; + String nextEndConfig = null; + int radix = 10; + + IRepository repo = null; + if (cstype.equals("KRA")) { + IKeyRecoveryAuthority kra = (IKeyRecoveryAuthority) CMS.getSubsystem( + IKeyRecoveryAuthority.ID); + if (type.equals("request")) { + repo = kra.getRequestQueue().getRequestRepository(); + } else if (type.equals("serialNo")) { + repo = kra.getKeyRepository(); + } else if (type.equals("replicaId")) { + repo = kra.getReplicaRepository(); } - endNum = beginNum.add(increment); - if( endNum == null ) { - CMS.debug( "UpdateNumberRange::process() - " + - "request endNum is null!" ); - return; + } else { // CA + ICertificateAuthority ca = (ICertificateAuthority) CMS.getSubsystem( + ICertificateAuthority.ID); + if (type.equals("request")) { + repo = ca.getRequestQueue().getRequestRepository(); + } else if (type.equals("serialNo")) { + repo = ca.getCertificateRepository(); + } else if (type.equals("replicaId")) { + repo = ca.getReplicaRepository(); } - nextNum = endNum.add(oneNum); - cs.putString("dbs.nextBeginRequestNumber", nextNum.toString()); + } + + if (type.equals("request")) { + radix = 10; + endNumConfig = "dbs.endRequestNumber"; + cloneNumConfig = "dbs.requestCloneTransferNumber"; + nextEndConfig = "dbs.nextEndRequestNumber"; } else if (type.equals("serialNo")) { - String beginNumStr = cs.getString("dbs.nextBeginSerialNumber"); - beginNum = new BigInteger(beginNumStr); - if( beginNum == null ) { - CMS.debug( "UpdateNumberRange::process() - " + - "serialNo beginNum is null!" ); - return; - } - endNum = beginNum.add(increment); - if( endNum == null ) { - CMS.debug( "UpdateNumberRange::process() - " + - "serialNo endNum is null!" ); + radix=16; + endNumConfig = "dbs.endSerialNumber"; + cloneNumConfig = "dbs.serialCloneTransferNumber"; + nextEndConfig = "dbs.nextEndSerialNumber"; + } else if (type.equals("replicaId")) { + radix=10; + endNumConfig = "dbs.endReplicaNumber"; + cloneNumConfig = "dbs.replicaCloneTransferNumber"; + nextEndConfig = "dbs.nextEndReplicaNumber"; + } + + String endNumStr = cs.getString(endNumConfig, ""); + endNum = new BigInteger(endNumStr, radix); + if ( endNum == null ) { + CMS.debug( "UpdateNumberRange::process() - " + + "request endNum is null!" ); + return; + } + + String decrementStr = cs.getString(cloneNumConfig, ""); + BigInteger decrement = new BigInteger(decrementStr, radix); + if (decrement == null) { + CMS.debug("UpdateNumberRange::process() - " + + "request decrement string is null!" ); + return; + } + + beginNum = endNum.subtract(decrement).add(oneNum); + + if (beginNum.compareTo(repo.getTheSerialNumber()) < 0) { + String nextEndNumStr = cs.getString(nextEndConfig, ""); + BigInteger endNum2 = new BigInteger(nextEndNumStr, radix); + if (endNum2 == null) { + CMS.debug("UpdateNumberRange::process() - " + + "Unused requests less than cloneTransferNumber!" ); return; + } else { + CMS.debug("Transferring from the end of on-deck range"); + String newValStr = endNum2.subtract(decrement).toString(radix); + repo.setNextMaxSerial(newValStr); + cs.putString(nextEndConfig, newValStr); + beginNum = endNum2.subtract(decrement).add(oneNum); + endNum = endNum2; } - nextNum = endNum.add(oneNum); - cs.putString("dbs.nextBeginSerialNumber", nextNum.toString()); + } else { + CMS.debug("Transferring from the end of the current range"); + String newValStr = beginNum.subtract(oneNum).toString(radix); + repo.setMaxSerial(newValStr); + cs.putString(endNumConfig, newValStr); } + if( beginNum == null ) { CMS.debug( "UpdateNumberRange::process() - " + "beginNum is null!" ); @@ -169,6 +222,13 @@ public class UpdateNumberRange extends CMSServlet { return; } + // checkRanges for replicaID - we do this each time a replica is created. + // Also enable serial number management in master for certs and requests + if (type.equals("replicaId")) { + repo.checkRanges(); + repo.setEnableSerialMgmt(true); + } + // insert info CMS.debug("UpdateNumberRange: Sending response"); @@ -177,8 +237,8 @@ public class UpdateNumberRange extends CMSServlet { Node root = xmlObj.createRoot("XMLResponse"); xmlObj.addItemToContainer(root, "Status", SUCCESS); - xmlObj.addItemToContainer(root, "beginNumber", beginNum.toString()); - xmlObj.addItemToContainer(root, "endNumber", endNum.toString()); + xmlObj.addItemToContainer(root, "beginNumber", beginNum.toString(radix)); + xmlObj.addItemToContainer(root, "endNumber", endNum.toString(radix)); byte[] cb = xmlObj.toByteArray(); outputResult(httpResp, "application/xml", cb); diff --git a/pki/base/common/src/com/netscape/cms/servlet/csadmin/WizardPanelBase.java b/pki/base/common/src/com/netscape/cms/servlet/csadmin/WizardPanelBase.java index c6c786f55..be00bd73c 100644 --- a/pki/base/common/src/com/netscape/cms/servlet/csadmin/WizardPanelBase.java +++ b/pki/base/common/src/com/netscape/cms/servlet/csadmin/WizardPanelBase.java @@ -726,7 +726,12 @@ public class WizardPanelBase implements IWizardPanel { } else if (type.equals("serialNo")) { cs.putString("dbs.beginSerialNumber", beginNum); cs.putString("dbs.endSerialNumber", endNum); + } else if (type.equals("replicaId")) { + cs.putString("dbs.beginReplicaNumber", beginNum); + cs.putString("dbs.endReplicaNumber", endNum); } + // enable serial number management in clone + cs.putString("dbs.enableSerialManagement", "true"); cs.commit(false); } else if (status.equals(AUTH_FAILURE)) { reloginSecurityDomain(response); diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/CertificateRepository.java b/pki/base/common/src/com/netscape/cmscore/dbs/CertificateRepository.java index 4d84b1fdf..43a520bd5 100644 --- a/pki/base/common/src/com/netscape/cmscore/dbs/CertificateRepository.java +++ b/pki/base/common/src/com/netscape/cmscore/dbs/CertificateRepository.java @@ -213,7 +213,7 @@ public class CertificateRepository extends Repository public CertStatusUpdateThread mCertStatusUpdateThread = null; public RetrieveModificationsThread mRetrieveModificationsThread = null; - public void setCertStatusUpdateInterval(int interval, boolean listenToCloneModifications) { + public void setCertStatusUpdateInterval(IRepository requestRepo, int interval, boolean listenToCloneModifications) { CMS.debug("In setCertStatusUpdateInterval " + interval); if (interval == 0) { CMS.debug("In setCertStatusUpdateInterval interval = 0" + interval); @@ -246,7 +246,7 @@ public class CertificateRepository extends Repository CMS.debug("In setCertStatusUpdateInterval mCertStatusUpdateThread " + mCertStatusUpdateThread); if (mCertStatusUpdateThread == null) { CMS.debug("In setCertStatusUpdateInterval about to create CertStatusUpdateThread "); - mCertStatusUpdateThread = new CertStatusUpdateThread(this, "CertStatusUpdateThread"); + mCertStatusUpdateThread = new CertStatusUpdateThread(this, requestRepo, "CertStatusUpdateThread"); mCertStatusUpdateThread.setInterval(interval); mCertStatusUpdateThread.start(); } else { @@ -1893,14 +1893,16 @@ public class CertificateRepository extends Repository class CertStatusUpdateThread extends Thread { CertificateRepository _cr = null; + IRepository _rr = null; int _interval; - CertStatusUpdateThread(CertificateRepository cr, String name) { + CertStatusUpdateThread(CertificateRepository cr, IRepository rr, String name) { super(name); CMS.debug("new CertStatusUpdateThread"); //setName(name); _cr = cr; + _rr = rr; } public void setInterval(int interval) { @@ -1919,10 +1921,18 @@ class CertStatusUpdateThread extends Thread { CMS.debug("Starting updateCertStatus (entered lock)"); _cr.updateCertStatus(); CMS.debug("updateCertStatus done"); + + CMS.debug("Starting cert checkRanges"); + _cr.checkRanges(); + CMS.debug("cert checkRanges done"); + + CMS.debug("Starting request checkRanges"); + _rr.checkRanges(); + CMS.debug("request checkRanges done"); } } catch (Exception e) { - CMS.debug("updateCertStatus done"); + CMS.debug("updateCertStatus done: " + e.toString()); } try { sleep(_interval * 1000); diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/DBSubsystem.java b/pki/base/common/src/com/netscape/cmscore/dbs/DBSubsystem.java index 30c708446..3038e0026 100644 --- a/pki/base/common/src/com/netscape/cmscore/dbs/DBSubsystem.java +++ b/pki/base/common/src/com/netscape/cmscore/dbs/DBSubsystem.java @@ -59,12 +59,12 @@ public class DBSubsystem implements IDBSubsystem { private DBRegistry mRegistry = null; private String mBaseDN = null; private ISubsystem mOwner = null; + + private Hashtable[] mRepos = null; + private BigInteger mNextSerialConfig = null; - private String mMaxSerialConfig = null; - private String mMinSerialConfig = null; + private boolean mEnableSerialMgmt = false; - private String mMinRequestConfig=null; - private String mMaxRequestConfig=null; private static final String PEOPLE_DN = "ou=people"; private static final String GROUPS_DN = "ou=groups"; private static final String REQUESTS_DN = "ou=requests"; @@ -81,6 +81,7 @@ public class DBSubsystem implements IDBSubsystem { private static final String KRA_DN = "ou=kra"; private static final String KR_DN = "ou=keyRepository, ou=kra"; private static final String KRA_REQUESTS_DN = "ou=kra, ou=requests"; + private static final String REPLICA_DN = "ou=replica"; private static final String PROP_ENABLE_SERIAL_NUMBER_RECOVERY = "enableSerialNumberRecovery"; // This value is only equal to the next Serial number that the CA's @@ -90,17 +91,58 @@ public class DBSubsystem implements IDBSubsystem { private static final String PROP_NEXT_SERIAL_NUMBER = "nextSerialNumber"; private static final String PROP_MIN_SERIAL_NUMBER="beginSerialNumber"; - - private static final String PROP_MAX_SERIAL_NUMBER = - "endSerialNumber"; + private static final String PROP_MAX_SERIAL_NUMBER = "endSerialNumber"; + private static final String PROP_NEXT_MIN_SERIAL_NUMBER="nextBeginSerialNumber"; + private static final String PROP_NEXT_MAX_SERIAL_NUMBER ="nextEndSerialNumber"; + private static final String PROP_SERIAL_LOW_WATER_MARK="serialLowWaterMark"; + private static final String PROP_SERIAL_INCREMENT="serialIncrement"; + private static final String PROP_SERIAL_BASEDN="serialDN"; + private static final String PROP_SERIAL_RANGE_DN="serialRangeDN"; private static final String PROP_MIN_REQUEST_NUMBER="beginRequestNumber"; private static final String PROP_MAX_REQUEST_NUMBER="endRequestNumber"; + private static final String PROP_NEXT_MIN_REQUEST_NUMBER="nextBeginRequestNumber"; + private static final String PROP_NEXT_MAX_REQUEST_NUMBER="nextEndRequestNumber"; + private static final String PROP_REQUEST_LOW_WATER_MARK="requestLowWaterMark"; + private static final String PROP_REQUEST_INCREMENT="requestIncrement"; + private static final String PROP_REQUEST_BASEDN="requestDN"; + private static final String PROP_REQUEST_RANGE_DN="requestRangeDN"; + + private static final String PROP_MIN_REPLICA_NUMBER="beginReplicaNumber"; + private static final String PROP_MAX_REPLICA_NUMBER = "endReplicaNumber"; + private static final String PROP_NEXT_MIN_REPLICA_NUMBER="nextBeginReplicaNumber"; + private static final String PROP_NEXT_MAX_REPLICA_NUMBER ="nextEndReplicaNumber"; + private static final String PROP_REPLICA_LOW_WATER_MARK="replicaLowWaterMark"; + private static final String PROP_REPLICA_INCREMENT="replicaIncrement"; + private static final String PROP_REPLICA_BASEDN="replicaDN"; + private static final String PROP_REPLICA_RANGE_DN="replicaRangeDN"; private static final String PROP_INFINITE_SERIAL_NUMBER = "1000000000"; private static final String PROP_INFINITE_REQUEST_NUMBER = "1000000000"; + private static final String PROP_INFINITE_REPLICA_NUMBER = "1000"; private static final String PROP_BASEDN = "basedn"; private static final String PROP_LDAP = "ldap"; + private static final String PROP_NEXT_RANGE = "nextRange"; + private static final String PROP_ENABLE_SERIAL_MGMT = "enableSerialManagement"; + + // hash keys + private static final String NAME="name"; + private static final String PROP_MIN="min"; + private static final String PROP_MIN_NAME="min_name"; + private static final String PROP_MAX = "max"; + private static final String PROP_MAX_NAME = "max_name"; + private static final String PROP_NEXT_MIN="next_min"; + private static final String PROP_NEXT_MIN_NAME="next_min_name"; + private static final String PROP_NEXT_MAX = "next_max"; + private static final String PROP_NEXT_MAX_NAME = "next_max_name"; + private static final String PROP_LOW_WATER_MARK="lowWaterMark"; + private static final String PROP_LOW_WATER_MARK_NAME="lowWaterMark_name"; + private static final String PROP_INCREMENT = "increment"; + private static final String PROP_INCREMENT_NAME = "increment_name"; + private static final String PROP_RANGE_DN="rangeDN"; + + private static final BigInteger BI_ONE = new BigInteger("1"); + private ILogger mLogger = null; // singleton enforcement @@ -152,6 +194,24 @@ public class DBSubsystem implements IDBSubsystem { } } + public boolean getEnableSerialMgmt() { + return mEnableSerialMgmt; + } + + public void setEnableSerialMgmt(boolean v) + throws EBaseException { + if (v) { + CMS.debug("DBSubsystem: Enabling Serial Number Management"); + } else { + CMS.debug("DBSubsystem: Disabling Serial Number Management"); + } + + mDBConfig.putBoolean(PROP_ENABLE_SERIAL_MGMT, v); + IConfigStore rootStore = getOwner().getConfigStore(); + rootStore.commit(false); + mEnableSerialMgmt = v; + } + public BigInteger getNextSerialConfig() { return mNextSerialConfig; } @@ -165,31 +225,297 @@ public class DBSubsystem implements IDBSubsystem { serial.toString(16)); } - public String getMinSerialConfig() + /** + * Gets minimum serial number limit in config file + * + * @param repo repo identifier + * @return min serial number + */ + public String getMinSerialConfig(int repo) { - return mMinSerialConfig; + return (String) (mRepos[repo]).get(PROP_MIN); } - public String getMaxSerialConfig() { - return mMaxSerialConfig; + + /** + * Gets maximum serial number limit in config file + * + * @param repo repo identifier + * @return max serial number + */ + public String getMaxSerialConfig(int repo) { + return (String) (mRepos[repo]).get(PROP_MAX); } - public String getMinRequestConfig() + /** + * Gets minimum serial number limit in next range in config file + * + * @param repo repo identifier + * @return min serial number in next range + */ + public String getNextMinSerialConfig(int repo) { - return mMinRequestConfig; + String ret = (String) (mRepos[repo]).get(PROP_NEXT_MIN); + if (ret.equals("-1")) { + return null; + } + else { + return ret; + } + } + + /** + * Gets maximum serial number limit in next range in config file + * + * @param repo repo identifier + * @return max serial number in next range + */ + public String getNextMaxSerialConfig(int repo) { + String ret = (String) (mRepos[repo]).get(PROP_NEXT_MAX); + if (ret.equals("-1")) { + return null; + } + else { + return ret; + } + } + + /** + * Gets low water mark limit in config file + * + * @param repo repo identifier + * @return low water mark + */ + public String getLowWaterMarkConfig(int repo) { + return (String) (mRepos[repo]).get(PROP_LOW_WATER_MARK); } - public String getMaxRequestConfig() + /** + * Gets range increment for next range in config file + * + * @param repo repo identifier + * @return range increment + */ + public String getIncrementConfig(int repo) { - return mMaxRequestConfig; + return (String) (mRepos[repo]).get(PROP_INCREMENT); } - public void setMaxSerialConfig(String serial) + /** + * Sets maximum serial number limit in config file + * + * @param repo repo identifier + * @param serial max serial number + * @exception EBaseException failed to set + */ + public void setMaxSerialConfig(int repo, String serial) throws EBaseException { - mLogger.log(ILogger.EV_SYSTEM, ILogger.S_DB, - ILogger.LL_INFO, "DBSubsystem: " + - "Setting max serial number: 0x" + serial); - mDBConfig.putString(PROP_MAX_SERIAL_NUMBER, - serial); + Hashtable h = mRepos[repo]; + CMS.debug("DBSubsystem: Setting max serial number for " + h.get(NAME) + ": " + serial); + + //persist to file + mDBConfig.putString((String) h.get(PROP_MAX_NAME), serial); + IConfigStore rootStore = getOwner().getConfigStore(); + rootStore.commit(false); + + h.put(PROP_MAX, serial); + mRepos[repo] = h; + } + + /** + * Sets minimum serial number limit in config file + * + * @param repo repo identifier + * @param serial min serial number + * @exception EBaseException failed to set + */ + public void setMinSerialConfig(int repo, String serial) + throws EBaseException { + Hashtable h = mRepos[repo]; + CMS.debug("DBSubsystem: Setting min serial number for " + h.get(NAME) + ": " + serial); + + //persist to file + mDBConfig.putString((String) h.get(PROP_MIN_NAME), serial); + IConfigStore rootStore = getOwner().getConfigStore(); + rootStore.commit(false); + + h.put(PROP_MIN, serial); + mRepos[repo] = h; + } + + /** + * Sets maximum serial number limit for next range in config file + * + * @param repo repo identifier + * @param serial max serial number for next range + * @exception EBaseException failed to set + */ + public void setNextMaxSerialConfig(int repo, String serial) + throws EBaseException { + Hashtable h = mRepos[repo]; + if (serial == null) { + CMS.debug("DBSubsystem: Removing next max " + h.get(NAME) + " number"); + mDBConfig.remove((String) h.get(PROP_NEXT_MAX_NAME)); + } else { + CMS.debug("DBSubsystem: Setting next max " + h.get(NAME) + " number: " + serial); + mDBConfig.putString((String) h.get(PROP_NEXT_MAX_NAME), serial); + } + IConfigStore rootStore = getOwner().getConfigStore(); + rootStore.commit(false); + if (serial == null) { + Object o2 = h.remove(PROP_NEXT_MAX); + } else { + h.put(PROP_NEXT_MAX, serial); + } + mRepos[repo] = h; + } + + /** + * Sets minimum serial number limit for next range in config file + * + * @param repo repo identifier + * @param serial min serial number for next range + * @exception EBaseException failed to set + */ + public void setNextMinSerialConfig(int repo, String serial) + throws EBaseException { + Hashtable h = mRepos[repo]; + if (serial == null) { + CMS.debug("DBSubsystem: Removing next min " + h.get(NAME) + " number"); + mDBConfig.remove((String) h.get(PROP_NEXT_MIN_NAME)); + } else { + CMS.debug("DBSubsystem: Setting next min " + h.get(NAME) + " number: " + serial); + mDBConfig.putString((String) h.get(PROP_NEXT_MIN_NAME), serial); + } + IConfigStore rootStore = getOwner().getConfigStore(); + rootStore.commit(false); + if (serial == null) { + Object o2 = h.remove(PROP_NEXT_MIN); + } else { + h.put(PROP_NEXT_MIN, serial); + } + mRepos[repo] = h; + } + + /** + * Gets start of next range from database. + * Increments the nextRange attribute and allocates + * this range to the current instance by creating a pkiRange object. + * + * @param repo repo identifier + * @return start of next range + */ + public String getNextRange(int repo) { + LDAPConnection conn = null; + String nextRange = null; + try { + Hashtable h = mRepos[repo]; + conn = mLdapConnFactory.getConn(); + String dn = (String) h.get(PROP_BASEDN) + "," + mBaseDN; + String rangeDN = (String) h.get(PROP_RANGE_DN) + "," + mBaseDN; + + LDAPEntry entry = conn.read(dn); + LDAPAttribute attr = entry.getAttribute(PROP_NEXT_RANGE); + nextRange = (String) attr.getStringValues().nextElement(); + + BigInteger nextRangeNo = new BigInteger(nextRange); + if (nextRangeNo == null) { + throw new EBaseException("nextRangeNo is null!"); + } + + BigInteger incrementNo = new BigInteger((String) h.get(PROP_INCREMENT)); + if (incrementNo == null) { + throw new EBaseException("incrementNo is null!"); + } + + // To make sure attrNextRange always increments, first delete the current value and then + // increment. Two operations in the same transaction + + LDAPAttribute attrNextRange = new LDAPAttribute(PROP_NEXT_RANGE, nextRangeNo.add(incrementNo).toString()); + LDAPModification [] mods = { + new LDAPModification( LDAPModification.DELETE, attr), + new LDAPModification( LDAPModification.ADD, attrNextRange ) }; + conn.modify( dn, mods ); + + // Add new range object + String endRange = nextRangeNo.add(incrementNo).subtract(BI_ONE).toString(); + LDAPAttributeSet attrs = new LDAPAttributeSet(); + attrs.add(new LDAPAttribute("objectClass", "top")); + attrs.add(new LDAPAttribute("objectClass", "pkiRange")); + attrs.add(new LDAPAttribute("beginRange" , nextRange)); + attrs.add(new LDAPAttribute("endRange" , endRange)); + attrs.add(new LDAPAttribute("cn", nextRange)); + attrs.add(new LDAPAttribute("host", CMS.getEESSLHost())); + attrs.add(new LDAPAttribute("securePort", CMS.getEESSLPort())); + String dn2 = "cn=" + nextRange + "," + rangeDN; + LDAPEntry rangeEntry = new LDAPEntry(dn2, attrs); + conn.add(rangeEntry); + } catch (Exception e) { + CMS.debug("DBSubsystem: getNextRange. Unable to provide next range :" + e); + e.printStackTrace(); + nextRange = null; + } finally { + try { + if ((conn != null) && (mLdapConnFactory!= null)) { + CMS.debug("Releasing ldap connection"); + mLdapConnFactory.returnConn(conn); + } + } + catch (Exception e) { + CMS.debug("Error releasing the ldap connection" + e.toString()); + } + } + return nextRange; + } + + /** + * Determines if a range conflict has been observed in database. + * If so, delete the conflict entry and remove the next range. + * When the next number is requested, if the number of certs is still + * below the low water mark, then a new range will be requested. + * + * @param repo repo identifier + * @return true if range conflict, false otherwise + */ + public boolean hasRangeConflict(int repo) + { + LDAPConnection conn = null; + boolean conflict = false; + try { + String nextRangeStart = getNextMinSerialConfig(repo); + if (nextRangeStart == null) { + return false; + } + Hashtable h = mRepos[repo]; + conn = mLdapConnFactory.getConn(); + String rangedn = (String) h.get(PROP_RANGE_DN) + "," + mBaseDN; + String filter = "(&(nsds5ReplConflict=*)(objectClass=pkiRange)(host= " + + CMS.getEESSLHost() + ")(SecurePort=" + CMS.getEESSLPort() + + ")(beginRange=" + nextRangeStart + "))"; + LDAPSearchResults results = conn.search(rangedn, LDAPv3.SCOPE_SUB, + filter, null, false); + + while (results.hasMoreElements()) { + conflict = true; + LDAPEntry entry = results.next(); + String dn = entry.getDN(); + CMS.debug("Deleting conflict entry:" + dn); + conn.delete(dn); + } + } catch (Exception e) { + CMS.debug("DBSubsystem: hasRangeConflict. Error while checking next range." + e); + e.printStackTrace(); + } finally { + try { + if ((conn != null) && (mLdapConnFactory!= null)) { + CMS.debug("Releasing ldap connection"); + mLdapConnFactory.returnConn(conn); + } + } + catch (Exception e) { + CMS.debug("Error releasing the ldap connection" + e.toString()); + } + } + return conflict; } public ISubsystem getOwner() { @@ -205,8 +531,10 @@ public class DBSubsystem implements IDBSubsystem { public void init(ISubsystem owner, IConfigStore config) throws EBaseException { + mLogger = CMS.getLogger(); mDBConfig = config; + mRepos = new Hashtable[IDBSubsystem.NUM_REPOS]; mConfig = config.getSubStore(PROP_LDAP); IConfigStore tmpConfig = null; @@ -214,46 +542,109 @@ public class DBSubsystem implements IDBSubsystem { mBaseDN = mConfig.getString(PROP_BASEDN, "o=NetscapeCertificateServer"); mOwner = owner; + mNextSerialConfig = new BigInteger(mDBConfig.getString( - PROP_NEXT_SERIAL_NUMBER, "0"), 16); + PROP_NEXT_SERIAL_NUMBER, "0"), 16); - mMinSerialConfig = mDBConfig.getString( - PROP_MIN_SERIAL_NUMBER,null); + mEnableSerialMgmt = mDBConfig.getBoolean(PROP_ENABLE_SERIAL_MGMT, false); - if(mMinSerialConfig == null) - { - mMinSerialConfig = "0"; - } + // populate the certs hash entry + Hashtable certs = new Hashtable(); + certs.put(NAME, "certs"); + certs.put(PROP_BASEDN, mDBConfig.getString(PROP_SERIAL_BASEDN,"")); + certs.put(PROP_RANGE_DN, mDBConfig.getString(PROP_SERIAL_RANGE_DN, "")); + certs.put(PROP_MIN_NAME, PROP_MIN_SERIAL_NUMBER); + certs.put(PROP_MIN, mDBConfig.getString( + PROP_MIN_SERIAL_NUMBER, "0")); - mMaxSerialConfig = mDBConfig.getString( - PROP_MAX_SERIAL_NUMBER,null ); + certs.put(PROP_MAX_NAME, PROP_MAX_SERIAL_NUMBER); + certs.put(PROP_MAX, mDBConfig.getString( + PROP_MAX_SERIAL_NUMBER, PROP_INFINITE_SERIAL_NUMBER)); - if(mMaxSerialConfig == null) - { - mMaxSerialConfig = PROP_INFINITE_SERIAL_NUMBER; - } + certs.put(PROP_NEXT_MIN_NAME, PROP_NEXT_MIN_SERIAL_NUMBER); + certs.put(PROP_NEXT_MIN, mDBConfig.getString( + PROP_NEXT_MIN_SERIAL_NUMBER, "-1")); - CMS.debug("DBSubsystem: mMinSerialConfig: " + mMinSerialConfig + " mMaxSerialConfig: " + mMaxSerialConfig); + certs.put(PROP_NEXT_MAX_NAME, PROP_NEXT_MAX_SERIAL_NUMBER); + certs.put(PROP_NEXT_MAX, mDBConfig.getString( + PROP_NEXT_MAX_SERIAL_NUMBER, "-1")); - mMinRequestConfig = mDBConfig.getString(PROP_MIN_REQUEST_NUMBER,null); + certs.put(PROP_LOW_WATER_MARK_NAME, PROP_SERIAL_LOW_WATER_MARK); + certs.put(PROP_LOW_WATER_MARK, mDBConfig.getString( + PROP_SERIAL_LOW_WATER_MARK, "5000")); - if(mMinRequestConfig == null) - { - CMS.debug("DBSubsystem: missing mMinSerialConfig value!"); - mMinRequestConfig = "0"; - } + certs.put(PROP_INCREMENT_NAME, PROP_SERIAL_INCREMENT); + certs.put(PROP_INCREMENT, mDBConfig.getString( + PROP_SERIAL_INCREMENT, PROP_INFINITE_SERIAL_NUMBER)); - mMaxRequestConfig = mDBConfig.getString(PROP_MAX_REQUEST_NUMBER,null); + mRepos[CERTS]=certs; - if(mMaxRequestConfig == null) - { - CMS.debug("DBSubsystem: missing mMaxSerialConfig value!"); - mMaxRequestConfig = PROP_INFINITE_REQUEST_NUMBER; + // populate the requests hash entry + Hashtable requests = new Hashtable(); + requests.put(NAME, "requests"); + requests.put(PROP_BASEDN, mDBConfig.getString(PROP_REQUEST_BASEDN,"")); + requests.put(PROP_RANGE_DN, mDBConfig.getString(PROP_REQUEST_RANGE_DN, "")); + + requests.put(PROP_MIN_NAME, PROP_MIN_REQUEST_NUMBER); + requests.put(PROP_MIN, mDBConfig.getString( + PROP_MIN_REQUEST_NUMBER, "0")); + + requests.put(PROP_MAX_NAME, PROP_MAX_REQUEST_NUMBER); + requests.put(PROP_MAX, mDBConfig.getString( + PROP_MAX_REQUEST_NUMBER, PROP_INFINITE_REQUEST_NUMBER)); + + requests.put(PROP_NEXT_MIN_NAME, PROP_NEXT_MIN_REQUEST_NUMBER); + requests.put(PROP_NEXT_MIN, mDBConfig.getString( + PROP_NEXT_MIN_REQUEST_NUMBER, "-1")); + + requests.put(PROP_NEXT_MAX_NAME, PROP_NEXT_MAX_REQUEST_NUMBER); + requests.put(PROP_NEXT_MAX, mDBConfig.getString( + PROP_NEXT_MAX_REQUEST_NUMBER, "-1")); + + requests.put(PROP_LOW_WATER_MARK_NAME, PROP_REQUEST_LOW_WATER_MARK); + requests.put(PROP_LOW_WATER_MARK, mDBConfig.getString( + PROP_REQUEST_LOW_WATER_MARK, "5000")); + + requests.put(PROP_INCREMENT_NAME, PROP_REQUEST_INCREMENT); + requests.put(PROP_INCREMENT, mDBConfig.getString( + PROP_REQUEST_INCREMENT, PROP_INFINITE_REQUEST_NUMBER)); + + mRepos[REQUESTS] = requests; + + // populate replica ID hash entry + Hashtable replicaID = new Hashtable(); + replicaID.put(NAME, "requests"); + replicaID.put(PROP_BASEDN, mDBConfig.getString(PROP_REPLICA_BASEDN,"")); + replicaID.put(PROP_RANGE_DN, mDBConfig.getString(PROP_REPLICA_RANGE_DN, "")); + + replicaID.put(PROP_MIN_NAME, PROP_MIN_REPLICA_NUMBER); + replicaID.put(PROP_MIN, mDBConfig.getString( + PROP_MIN_REPLICA_NUMBER, "1")); + + replicaID.put(PROP_MAX_NAME, PROP_MAX_REPLICA_NUMBER); + replicaID.put(PROP_MAX, mDBConfig.getString( + PROP_MAX_REPLICA_NUMBER, PROP_INFINITE_REPLICA_NUMBER)); + + replicaID.put(PROP_NEXT_MIN_NAME, PROP_NEXT_MIN_REPLICA_NUMBER); + replicaID.put(PROP_NEXT_MIN, mDBConfig.getString( + PROP_NEXT_MIN_REPLICA_NUMBER, "-1")); + + replicaID.put(PROP_NEXT_MAX_NAME, PROP_NEXT_MAX_REPLICA_NUMBER); + replicaID.put(PROP_NEXT_MAX, mDBConfig.getString( + PROP_NEXT_MAX_REPLICA_NUMBER, "-1")); + + replicaID.put(PROP_LOW_WATER_MARK_NAME, PROP_REPLICA_LOW_WATER_MARK); + replicaID.put(PROP_LOW_WATER_MARK, mDBConfig.getString( + PROP_REPLICA_LOW_WATER_MARK, "10")); + + replicaID.put(PROP_INCREMENT_NAME, PROP_REPLICA_INCREMENT); + replicaID.put(PROP_INCREMENT, mDBConfig.getString( + PROP_REPLICA_INCREMENT, PROP_INFINITE_REPLICA_NUMBER)); + + mRepos[REPLICA_ID] = replicaID; - } - CMS.debug("DBSubsystem: mMinRequestConfig: " + mMinRequestConfig + " mMaxRequestConfig: " + mMaxRequestConfig); // initialize registry mRegistry = new DBRegistry(); mRegistry.init(this, null); diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/KeyRepository.java b/pki/base/common/src/com/netscape/cmscore/dbs/KeyRepository.java index 099c5bdcd..a631a17a9 100644 --- a/pki/base/common/src/com/netscape/cmscore/dbs/KeyRepository.java +++ b/pki/base/common/src/com/netscape/cmscore/dbs/KeyRepository.java @@ -44,6 +44,7 @@ import com.netscape.cmscore.dbs.*; */ public class KeyRepository extends Repository implements IKeyRepository { + public KeyStatusUpdateThread mKeyStatusUpdateThread = null; protected IDBSubsystem mDBService = null; /** @@ -126,6 +127,30 @@ public class KeyRepository extends Repository implements IKeyRepository { } } + public void setKeyStatusUpdateInterval(IRepository requestRepo, int interval) { + CMS.debug("In setKeyStatusUpdateInterval " + interval); + // don't run the thread if serial management is disabled. + if ((interval == 0) || (!mDBService.getEnableSerialMgmt())) { + CMS.debug("In setKeyStatusUpdateInterval interval = 0" + interval); + if (mKeyStatusUpdateThread != null) { + mKeyStatusUpdateThread.stop(); + } + return; + } + + CMS.debug("In setKeyStatusUpdateInterval mKeyStatusUpdateThread " + mKeyStatusUpdateThread); + if (mKeyStatusUpdateThread == null) { + CMS.debug("In setKeyStatusUpdateInterval about to create KeyStatusUpdateThread "); + mKeyStatusUpdateThread = new KeyStatusUpdateThread(this, requestRepo, "KeyStatusUpdateThread"); + mKeyStatusUpdateThread.setInterval(interval); + mKeyStatusUpdateThread.start(); + } else { + CMS.debug("In setKeyStatusUpdateInterval it thinks the thread is up already "); + mKeyStatusUpdateThread.setInterval(interval); + // dont do anything if we have a thread running already + } + } + public IDBSubsystem getDBSubsystem() { return mDBService; } @@ -472,6 +497,57 @@ CMS.debug("filter= " + filter); return ret ; } + + public void shutdown() { + if (mKeyStatusUpdateThread != null) + mKeyStatusUpdateThread.destroy(); + } + +} + +class KeyStatusUpdateThread extends Thread { + KeyRepository _kr = null; + IRepository _rr = null; + int _interval; + + KeyStatusUpdateThread(KeyRepository kr, IRepository rr, String name) { + super(name); + CMS.debug("new KeyStatusUpdateThread"); + + _kr = kr; + _rr = rr; + } + + public void setInterval(int interval) { + _interval = interval; + } + + public void run() { + CMS.debug("Inside run method of KeyStatusUpdateThread"); + + while (true) { + try { + // block the update while another thread + // (such as the CRL Update) is running + CMS.debug("About to start checkRanges"); + synchronized (_kr.mKeyStatusUpdateThread) { + CMS.debug("Starting key checkRanges"); + _kr.checkRanges(); + CMS.debug("key checkRanges done"); + + CMS.debug("Starting request checkRanges"); + _rr.checkRanges(); + CMS.debug("request checkRanges done"); + } + } catch (Exception e) { + CMS.debug("key checkRanges done"); + } + try { + sleep(_interval * 1000); + } catch (InterruptedException e) { + } + } + } } diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/ReplicaIDRepository.java b/pki/base/common/src/com/netscape/cmscore/dbs/ReplicaIDRepository.java new file mode 100644 index 000000000..026e54a6a --- /dev/null +++ b/pki/base/common/src/com/netscape/cmscore/dbs/ReplicaIDRepository.java @@ -0,0 +1,82 @@ +// --- 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.dbs; + + +import java.math.BigInteger; + +import com.netscape.certsrv.dbs.*; +import com.netscape.certsrv.dbs.replicadb.*; +import com.netscape.certsrv.base.*; +import com.netscape.certsrv.apps.CMS; + +/** + * A class represents a replica repository. It + * creates unique managed replica IDs. + * <P> + * + * @author alee + * @version $Revision: 14561 $, $Date: 2007-05-01 10:28:56 -0700 (Tue, 01 May 2007) $ + */ +public class ReplicaIDRepository extends Repository + implements IReplicaIDRepository { + + private IDBSubsystem mDBService; + private String mBaseDN; + + /** + * Constructs a certificate repository. + */ + public ReplicaIDRepository(IDBSubsystem dbService, int increment, String baseDN) + throws EDBException { + super(dbService, increment, baseDN); + mBaseDN = baseDN; + mDBService = dbService; + } + + + /** + * Returns last serial number in given range + */ + public BigInteger getLastSerialNumberInRange(BigInteger serial_low_bound, BigInteger serial_upper_bound) + throws EBaseException { + CMS.debug("ReplicaIDReposoitory: in getLastSerialNumberInRange: low " + serial_low_bound + " high " + serial_upper_bound); + if(serial_low_bound == null || serial_upper_bound == null || serial_low_bound.compareTo(serial_upper_bound) >= 0 ) { + return null; + } + BigInteger ret = new BigInteger(getMinSerial()); + if ((ret==null) || (ret.compareTo(serial_upper_bound) >0) || (ret.compareTo(serial_low_bound) <0)) { + return null; + } + return ret; + } + + /** + * Retrieves DN of this repository. + */ + public String getDN() { + return mBaseDN; + } + + /** + * Retrieves backend database handle. + */ + public IDBSubsystem getDBSubsystem() { + return mDBService; + } +} diff --git a/pki/base/common/src/com/netscape/cmscore/dbs/Repository.java b/pki/base/common/src/com/netscape/cmscore/dbs/Repository.java index db7cc707d..86c08b40e 100644 --- a/pki/base/common/src/com/netscape/cmscore/dbs/Repository.java +++ b/pki/base/common/src/com/netscape/cmscore/dbs/Repository.java @@ -29,6 +29,8 @@ import com.netscape.certsrv.dbs.repository.*; import com.netscape.certsrv.dbs.certdb.*; import com.netscape.certsrv.apps.CMS; import com.netscape.certsrv.dbs.keydb.*; +import com.netscape.certsrv.dbs.replicadb.*; + /** * A class represents a generic repository. It maintains unique * serial number within repository. @@ -48,6 +50,7 @@ public abstract class Repository implements IRepository { private static final BigInteger BI_ONE = new BigInteger("1"); private BigInteger BI_INCREMENT = null; + private static final BigInteger BI_ZERO = new BigInteger("0"); // (the next serialNo to be issued) - 1 private BigInteger mSerialNo = null; // the serialNo attribute stored in db @@ -55,13 +58,22 @@ public abstract class Repository implements IRepository { private String mMaxSerial = null; private String mMinSerial = null; + private String mNextMaxSerial = null; + private String mNextMinSerial = null; private BigInteger mMinSerialNo = null; private BigInteger mMaxSerialNo = null; + private BigInteger mNextMinSerialNo = null; + private BigInteger mNextMaxSerialNo = null; + + private BigInteger mIncrementNo = null; + private BigInteger mLowWaterMarkNo = null; private IDBSubsystem mDB = null; private String mBaseDN = null; private boolean mInit = false; + private int mRadix = 10; + private int mRepo = -1; private BigInteger mLastSerialNo = null; @@ -121,7 +133,7 @@ public abstract class Repository implements IRepository { * * @return next serial number */ - private BigInteger getSerialNumber() throws EBaseException { + protected BigInteger getSerialNumber() throws EBaseException { IDBSSession s = mDB.createSession(); CMS.debug("Repository: getSerialNumber."); @@ -166,7 +178,7 @@ public abstract class Repository implements IRepository { * * @param num serial number */ - private void setSerialNumber(BigInteger num) throws EBaseException { + protected void setSerialNumber(BigInteger num) throws EBaseException { IDBSSession s = mDB.createSession(); CMS.debug("Repository:setSerialNumber " + num.toString()); @@ -175,17 +187,69 @@ public abstract class Repository implements IRepository { } + /** + * Get the maximum serial number. + * + * @return maximum serial number + */ public String getMaxSerial() { return mMaxSerial; } + /** + * Set the maximum serial number. + * + * @param serial maximum number + * @exception EBaseException failed to set maximum serial number + */ public void setMaxSerial(String serial) throws EBaseException { BigInteger maxSerial = null; - CMS.debug("Repository:setMaxSerial " + serial); + maxSerial = new BigInteger(serial, mRadix); + if (maxSerial != null) { + mMaxSerial = serial; + mMaxSerialNo = maxSerial; + } + } + + /** + * Get the maximum serial number in next range. + * + * @return maximum serial number in next range + */ + public String getNextMaxSerial() { + return mNextMaxSerial; + } + + /** + * Set the maximum serial number in next range + * + * @param serial maximum number in next range + * @exception EBaseException failed to set maximum serial number in next range + */ + public void setNextMaxSerial(String serial) throws EBaseException { + BigInteger maxSerial = null; + CMS.debug("Repository:setNextMaxSerial " + serial); + + maxSerial = new BigInteger(serial, mRadix); + if (maxSerial != null) { + mNextMaxSerial = serial; + mNextMaxSerialNo = maxSerial; + } + return; } + + /** + * Get the minimum serial number. + * + * @return minimum serial number + */ + public String getMinSerial() { + return mMinSerial; + } + /** * init serial number cache @@ -193,47 +257,55 @@ public abstract class Repository implements IRepository { private void initCache() throws EBaseException { mNext = getSerialNumber(); BigInteger serialConfig = new BigInteger("0"); - - int radix = 10; - + mRadix = 10; + CMS.debug("Repository: in InitCache"); - String minSerial = mDB.getMinSerialConfig(); - String maxSerial = mDB.getMaxSerialConfig(); - String minRequest = mDB.getMinRequestConfig(); - String maxRequest = mDB.getMaxRequestConfig(); - - CMS.debug("Repository: minSerial " + minSerial + " maxSerial: " + maxSerial + " minRequest " + minRequest + " maxRequest " + maxRequest); if (this instanceof ICertificateRepository) { - - mMaxSerial = maxSerial; - mMinSerial = minSerial; - radix = 16; CMS.debug("Repository: Instance of Certificate Repository."); - } else { + mRadix = 16; + mRepo = IDBSubsystem.CERTS; + } else if (this instanceof IKeyRepository) { + // Key Repository uses the same configuration parameters as Certificate + // Repository. This is ok because they are on separate subsystems. + CMS.debug("Repository: Instance of Key Repository"); + mRadix = 16; + mRepo = IDBSubsystem.CERTS; + } else if (this instanceof IReplicaIDRepository) { + CMS.debug("Repository: Instance of Replica ID repository"); + mRepo = IDBSubsystem.REPLICA_ID; + } else { + // CRLRepository subclasses this too, but does not use serial number stuff + CMS.debug("Repository: Instance of Request Repository or CRLRepository."); + mRepo = IDBSubsystem.REQUESTS; + } - if(this instanceof IKeyRepository) { + mMinSerial = mDB.getMinSerialConfig(mRepo); + mMaxSerial = mDB.getMaxSerialConfig(mRepo); + mNextMinSerial = mDB.getNextMinSerialConfig(mRepo); + mNextMaxSerial = mDB.getNextMaxSerialConfig(mRepo); + String increment = mDB.getIncrementConfig(mRepo); + String lowWaterMark = mDB.getLowWaterMarkConfig(mRepo); - mMaxSerial = maxSerial; - mMinSerial = minSerial; - radix = 16; - CMS.debug("Repository: Instance of Key Repository."); + CMS.debug("Repository: minSerial " + mMinSerial + " maxSerial: " + mMaxSerial); - } else { // request repository + if(mMinSerial != null) + mMinSerialNo = new BigInteger(mMinSerial,mRadix); - mMaxSerial = maxRequest; - mMinSerial = minRequest; - radix = 10; - CMS.debug("Repository: Instance of Request Repository."); + if(mMaxSerial != null) + mMaxSerialNo = new BigInteger(mMaxSerial,mRadix); - } - } + if(mNextMinSerial != null) + mNextMinSerialNo = new BigInteger(mNextMinSerial,mRadix); - if(mMinSerial != null) - mMinSerialNo = new BigInteger(mMinSerial,radix); + if(mNextMaxSerial != null) + mNextMaxSerialNo = new BigInteger(mNextMaxSerial,mRadix); - if(mMaxSerial != null) - mMaxSerialNo = new BigInteger(mMaxSerial,radix); + if(lowWaterMark != null) + mLowWaterMarkNo = new BigInteger(lowWaterMark,mRadix); + + if(increment != null) + mIncrementNo = new BigInteger(increment,mRadix); BigInteger theSerialNo = null; theSerialNo = getLastSerialNumberInRange(mMinSerialNo,mMaxSerialNo); @@ -278,7 +350,6 @@ public abstract class Repository implements IRepository { // mSerialNo is already set. But just in case CMS.debug("Repository:In setTheSerialNumber " + num.toString()); - if (mLastSerialNo == null) initCache(); @@ -306,6 +377,7 @@ public abstract class Repository implements IRepository { EBaseException { CMS.debug("Repository: in getNextSerialNumber. "); + if (mLastSerialNo == null) { initCache(); @@ -320,10 +392,32 @@ public abstract class Repository implements IRepository { CMS.debug( "Repository::getNextSerialNumber() " + "- mLastSerialNo is null!" ); throw new EBaseException( "mLastSerialNo is null" ); - } else if( mLastSerialNo.compareTo( mMaxSerialNo ) > 0 ) { - mLastSerialNo = mLastSerialNo.subtract(BI_ONE); - throw new EDBException(CMS.getUserMessage("CMS_DBS_LIMIT_REACHED", - mLastSerialNo.toString())); + } + + // check if we have reached the end of the range + // if so, move to next range + if (mLastSerialNo.compareTo( mMaxSerialNo ) > 0 ) { + if (mDB.getEnableSerialMgmt()) { + CMS.debug("Reached the end of the range. Attempting to move to next range"); + mMinSerialNo = mNextMinSerialNo; + mMaxSerialNo = mNextMaxSerialNo; + mLastSerialNo = mMinSerialNo; + mNextMinSerialNo = null; + mNextMaxSerialNo = null; + if ((mMaxSerialNo == null) || (mMinSerialNo == null)) { + throw new EDBException(CMS.getUserMessage("CMS_DBS_LIMIT_REACHED", + mLastSerialNo.toString())); + } + + // persist the changes + mDB.setMinSerialConfig(mRepo, mMinSerialNo.toString()); + mDB.setMaxSerialConfig(mRepo, mMaxSerialNo.toString()); + mDB.setNextMinSerialConfig(mRepo, null); + mDB.setNextMaxSerialConfig(mRepo, null); + } else { + throw new EDBException(CMS.getUserMessage("CMS_DBS_LIMIT_REACHED", + mLastSerialNo.toString())); + } } BigInteger retSerial = new BigInteger(mLastSerialNo.toString()); @@ -332,6 +426,80 @@ public abstract class Repository implements IRepository { return retSerial; } + /** + * Checks to see if a new range is needed, or if we have reached the end of the + * current range, or if a range conflict has occurred. + * + * @exception EBaseException failed to check next range for conflicts + */ + public void checkRanges() throws EBaseException + { + if (!mDB.getEnableSerialMgmt()) { + CMS.debug("Serial Management not enabled. Returning .. "); + return; + } + if (CMS.getEESSLPort() == null) { + CMS.debug("Server not completely started. Returning .."); + return; + } + + if (mLastSerialNo == null) + initCache(); + + BigInteger numsInRange = mMaxSerialNo.subtract(mLastSerialNo); + BigInteger numsInNextRange = null; + BigInteger numsAvail = null; + CMS.debug("Serial numbers left in range: " + numsInRange.toString()); + CMS.debug("Last Serial Number: " + mLastSerialNo.toString()); + if ((mNextMaxSerialNo != null) && (mNextMinSerialNo != null)) { + numsInNextRange = mNextMaxSerialNo.subtract(mNextMinSerialNo); + numsAvail = numsInRange.add(numsInNextRange); + CMS.debug("Serial Numbers in next range: " + numsInNextRange.toString()); + CMS.debug("Serial Numbers available: " + numsAvail.toString()); + } else { + numsAvail = numsInRange; + CMS.debug("Serial Numbers available: " + numsAvail.toString()); + } + + if ((numsAvail.compareTo(mLowWaterMarkNo) < 0) && (!CMS.isPreOpMode()) ) { + CMS.debug("Low water mark reached. Requesting next range"); + mNextMinSerialNo = new BigInteger(mDB.getNextRange(mRepo), mRadix); + if (mNextMinSerialNo == null) { + CMS.debug("Next Range not available"); + } else { + CMS.debug("nNextMinSerialNo has been set to " + mNextMinSerialNo.toString(mRadix)); + mNextMaxSerialNo = mNextMinSerialNo.add(mIncrementNo); + numsAvail = numsAvail.add(mIncrementNo); + mDB.setNextMinSerialConfig(mRepo, mNextMinSerialNo.toString(mRadix)); + mDB.setNextMaxSerialConfig(mRepo, mNextMaxSerialNo.toString(mRadix)); + } + } + + if (numsInRange.compareTo (mLowWaterMarkNo) < 0 ) { + // check for a replication error + CMS.debug("Checking for a range conflict"); + if (mDB.hasRangeConflict(mRepo)) { + CMS.debug("Range Conflict found! Removing next range."); + mNextMaxSerialNo = null; + mNextMinSerialNo= null; + mDB.setNextMinSerialConfig(mRepo, null); + mDB.setNextMaxSerialConfig(mRepo, null); + } + } + } + + /** + * Sets whether serial number management is enabled for certs + * and requests. + * + * @param value true/false + * @exception EBaseException failed to set + */ + public void setEnableSerialMgmt(boolean value) throws EBaseException + { + mDB.setEnableSerialMgmt(value); + } + public abstract BigInteger getLastSerialNumberInRange(BigInteger serial_low_bound, BigInteger serial_upper_bound) throws EBaseException; } diff --git a/pki/base/common/src/com/netscape/cmscore/request/RequestQueue.java b/pki/base/common/src/com/netscape/cmscore/request/RequestQueue.java index 60c476d3e..ff9ceb4f6 100644 --- a/pki/base/common/src/com/netscape/cmscore/request/RequestQueue.java +++ b/pki/base/common/src/com/netscape/cmscore/request/RequestQueue.java @@ -44,6 +44,7 @@ import com.netscape.certsrv.request.IService; import com.netscape.certsrv.request.IRequestList; import com.netscape.certsrv.request.IRequestVirtualList; import com.netscape.cmscore.request.ARequestQueue; +import com.netscape.certsrv.dbs.repository.IRepository; import com.netscape.cmscore.util.Debug; @@ -594,6 +595,13 @@ public class RequestQueue } } + /* + * return request repository + */ + public IRepository getRequestRepository() { + return (IRepository) mRepository; + } + protected String mBaseDN; protected IDBSubsystem mDB; protected RequestRepository mRepository; diff --git a/pki/base/kra/shared/conf/CS.cfg b/pki/base/kra/shared/conf/CS.cfg index 7bd887274..b3ff6d6b8 100644 --- a/pki/base/kra/shared/conf/CS.cfg +++ b/pki/base/kra/shared/conf/CS.cfg @@ -127,12 +127,28 @@ cmc.revokeCert.verify=true cmc.revokeCert.sharedSecret.class=com.netscape.cms.authentication.SharedSecret cmc.sharedSecret.class=com.netscape.cms.authentication.SharedSecret cms.version= +dbs.enableSerialManagement=false dbs.beginRequestNumber=1 dbs.endRequestNumber=10000000 -dbs.requestNumber.increment=10000000 +dbs.requestIncrement=10000000 +dbs.requestLowWaterMark=2000000 +dbs.requestCloneTransferNumber=10000 +dbs.requestDN=ou=kra, ou=requests +dbs.requestRangeDN=ou=requests, ou=ranges dbs.beginSerialNumber=1 dbs.endSerialNumber=10000000 -dbs.serialNumber.increment=10000000 +dbs.serialIncrement=10000000 +dbs.serialLowWaterMark=2000000 +dbs.serialCloneTransferNumber=10000 +dbs.serialDN=ou=keyRepository, ou=kra +dbs.serialRangeDN=ou=keyRepository, ou=ranges +dbs.beginReplicaNumber=1 +dbs.endReplicaNumber=100 +dbs.replicaIncrement=100 +dbs.replicaLowWaterMark=20 +dbs.replicaCloneTransferNumber=5 +dbs.replicaDN=ou=replica +dbs.replicaRangeDN=ou=replica, ou=ranges dbs.ldap=internaldb dbs.newSchemaEntryAdded=true debug.append=true diff --git a/pki/base/kra/shared/conf/db.ldif b/pki/base/kra/shared/conf/db.ldif index 813fc90d1..62e57aaf3 100644 --- a/pki/base/kra/shared/conf/db.ldif +++ b/pki/base/kra/shared/conf/db.ldif @@ -77,3 +77,31 @@ objectclass: top objectclass: repository ou: kra serialno: 010 + +dn: ou=replica,{rootSuffix} +objectClass: top +objectClass: repository +ou: replica +serialno: 010 +nextRange: 1000 + +dn: ou=ranges,{rootSuffix} +objectClass: top +objectClass: organizationalUnit +ou: ranges + +dn: ou=replica, ou=ranges,{rootSuffix} +objectClass: top +objectClass: organizationalUnit +ou: replica + +dn: ou=requests, ou=ranges,{rootSuffix} +objectClass: top +objectClass: organizationalUnit +ou: requests + +dn: ou=keyRepository, ou=ranges,{rootSuffix} +objectClass: top +objectClass: organizationalUnit +ou: certificateRepository + diff --git a/pki/base/kra/shared/conf/schema.ldif b/pki/base/kra/shared/conf/schema.ldif index 4431a2730..823543dcf 100644 --- a/pki/base/kra/shared/conf/schema.ldif +++ b/pki/base/kra/shared/conf/schema.ldif @@ -301,6 +301,21 @@ attributeTypes: ( serialno-oid NAME 'serialno' DESC 'CMS defined attribute' SYNT dn: cn=schema changetype: modify add: attributeTypes +attributeTypes: ( nextRange-oid NAME 'nextRange' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' ) + +dn: cn=schema +changetype: modify +add: attributeTypes +attributeTypes: ( beginRange-oid NAME 'beginRange' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' ) + +dn: cn=schema +changetype: modify +add: attributeTypes +attributeTypes: ( endRange-oid NAME 'endRange' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' ) + +dn: cn=schema +changetype: modify +add: attributeTypes attributeTypes: ( subjectName-oid NAME 'subjectName' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' ) dn: cn=schema @@ -350,13 +365,33 @@ attributeTypes: ( version-oid NAME 'version' DESC 'CMS defined attribute' SYNTAX dn: cn=schema changetype: modify +add: attributeTypes +attributeTypes: ( Clone-oid NAME 'Clone' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-ORIGIN 'user defined' ) + +dn: cn=schema +changetype: modify +add: attributeTypes +attributeTypes: ( DomainManager-oid NAME 'DomainManager' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-ORIGIN 'user defined' ) + +dn: cn=schema +changetype: modify +add: attributeTypes +attributeTypes: ( SecurePort-oid NAME 'SecurePort' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user defined' ) + +dn: cn=schema +changetype: modify +add: attributeTypes +attributeTypes: ( SubsystemName-oid NAME 'SubsystemName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'user defined' ) + +dn: cn=schema +changetype: modify add: objectClasses objectClasses: ( CertACLS-oid NAME 'CertACLS' DESC 'CMS defined class' SUP top STRUCTURAL MUST cn MAY resourceACLS X-ORIGIN 'user defined' ) dn: cn=schema changetype: modify add: objectClasses -objectClasses: ( repository-oid NAME 'repository' DESC 'CMS defined class' SUP top STRUCTURAL MUST ou MAY ( serialno $ description ) X-ORIGIN 'user defined' ) +objectClasses: ( repository-oid NAME 'repository' DESC 'CMS defined class' SUP top STRUCTURAL MUST ou MAY ( serialno $ description $ nextRange ) X-ORIGIN 'user defined' ) dn: cn=schema changetype: modify @@ -392,3 +427,24 @@ dn: cn=schema changetype: modify add: objectClasses objectClasses: ( keyRecord-oid NAME 'keyRecord' DESC 'CMS defined class' SUP top STRUCTURAL MUST cn MAY ( serialno $ dateOfCreate $ dateOfModify $ keyState $ privateKeyData $ ownerName $ keySize $ metaInfo $ dateOfArchival $ dateOfRecovery $ algorithm $ publicKeyFormat $ publicKeyData $ archivedBy ) X-ORIGIN 'user defined' ) + +dn: cn=schema +changetype: modify +add: objectClasses +objectClasses: ( pkiSecurityDomain-oid NAME 'pkiSecurityDomain' DESC 'CMS defined class' SUP top STRUCTURAL MUST ( ou $ name ) X-ORIGIN 'user defined' ) + +dn: cn=schema +changetype: modify +add: objectClasses +objectClasses: ( pkiSecurityGroup-oid NAME 'pkiSecurityGroup' DESC 'CMS defined class' SUP top STRUCTURAL MUST cn X-ORIGIN 'user defined' ) + +dn: cn=schema +changetype: modify +add: objectClasses +objectClasses: ( pkiSubsystem-oid NAME 'pkiSubsystem' DESC 'CMS defined class' SUP top STRUCTURAL MUST ( cn $ Host $ SecurePort $ SubsystemName $ Clone ) MAY ( DomainManager ) X-ORIGIN 'user defined' ) + +dn: cn=schema +changetype: modify +add: objectClasses +objectClasses: ( pkiRange-oid NAME 'pkiRange' DESC 'CMS defined class' SUP top STRUCTURAL MUST ( cn $ beginRange $ endRange $ Host $ SecurePort ) X-ORIGIN 'user defined' ) + diff --git a/pki/base/kra/src/com/netscape/kra/KeyRecoveryAuthority.java b/pki/base/kra/src/com/netscape/kra/KeyRecoveryAuthority.java index 9ca87dd0c..c55a949c0 100644 --- a/pki/base/kra/src/com/netscape/kra/KeyRecoveryAuthority.java +++ b/pki/base/kra/src/com/netscape/kra/KeyRecoveryAuthority.java @@ -35,6 +35,7 @@ import com.netscape.certsrv.base.*; import com.netscape.certsrv.dbs.*; import com.netscape.certsrv.usrgrp.*; import com.netscape.certsrv.dbs.keydb.*; +import com.netscape.certsrv.dbs.replicadb.*; import com.netscape.cmscore.dbs.*; import com.netscape.certsrv.policy.*; import com.netscape.certsrv.kra.*; @@ -73,6 +74,7 @@ public class KeyRecoveryAuthority implements IAuthority, IKeyService, IKeyRecove private static final String PARAM_AGENT = "agent"; private final static String KEY_RESP_NAME = "keyRepository"; + private static final String PROP_REPLICAID_DN = "dbs.replicadn"; private Hashtable mRequestProcessor = new Hashtable(); @@ -89,6 +91,7 @@ public class KeyRecoveryAuthority implements IAuthority, IKeyService, IKeyRecove protected Hashtable mAutoRecovery = new Hashtable(); protected boolean mAutoRecoveryOn = false; protected KeyRepository mKeyDB = null; + protected ReplicaIDRepository mReplicaRepot = null; protected IRequestNotifier mNotify = null; protected IRequestNotifier mPNotify = null; protected ISubsystem mOwner = null; @@ -348,6 +351,11 @@ public class KeyRecoveryAuthority implements IAuthority, IKeyService, IKeyRecove mRequestQueue = reqSub.getRequestQueue(getId(), reqdb_inc, mPolicy, service, mNotify, mPNotify); + // set KeyStatusUpdateInterval to be 10 minutes if serial management is enabled. + mKeyDB.setKeyStatusUpdateInterval( + mRequestQueue.getRequestRepository(), + mConfig.getInteger("keyStatusUpdateInterval", 10 * 60)); + // init request scheduler if configured String schedulerClass = mConfig.getString("requestSchedulerClass", null); @@ -363,6 +371,16 @@ public class KeyRecoveryAuthority implements IAuthority, IKeyService, IKeyRecove } } initNotificationListeners(); + + String replicaReposDN = mConfig.getString(PROP_REPLICAID_DN, null); + if (replicaReposDN == null) { + replicaReposDN = "ou=Replica," + getDBSubsystem().getBaseDN(); + } + + mReplicaRepot = new ReplicaIDRepository( + DBSubsystem.getInstance(), 1, replicaReposDN); + CMS.debug("Replica Repot inited"); + } public CryptoToken getKeygenToken() { @@ -418,6 +436,10 @@ public class KeyRecoveryAuthority implements IAuthority, IKeyService, IKeyRecove mTransportKeyUnit.shutdown(); mStorageKeyUnit.shutdown(); + if (mKeyDB != null) { + mKeyDB.shutdown(); + mKeyDB = null; + } getLogger().log(ILogger.EV_SYSTEM, ILogger.S_KRA, ILogger.LL_INFO, mName.toString() + " is stopped"); mInitialized = false; @@ -1056,6 +1078,17 @@ public class KeyRecoveryAuthority implements IAuthority, IKeyService, IKeyRecove } /** + * Retrieves replica repository. + * <P> + * + * @return replica repository + */ + public IReplicaIDRepository getReplicaRepository() { + return mReplicaRepot; + } + + + /** * Retrieves the DN of this escrow authority. * <P> * diff --git a/pki/base/ocsp/shared/conf/schema.ldif b/pki/base/ocsp/shared/conf/schema.ldif index ec5a1142e..823543dcf 100644 --- a/pki/base/ocsp/shared/conf/schema.ldif +++ b/pki/base/ocsp/shared/conf/schema.ldif @@ -1,8 +1,3 @@ -# --- BEGIN COPYRIGHT BLOCK --- -# Copyright (C) 2006 Red Hat, Inc. -# All rights reserved. -# --- END COPYRIGHT BLOCK --- -# dn: cn=schema changetype: modify add: attributeTypes @@ -306,6 +301,21 @@ attributeTypes: ( serialno-oid NAME 'serialno' DESC 'CMS defined attribute' SYNT dn: cn=schema changetype: modify add: attributeTypes +attributeTypes: ( nextRange-oid NAME 'nextRange' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' ) + +dn: cn=schema +changetype: modify +add: attributeTypes +attributeTypes: ( beginRange-oid NAME 'beginRange' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' ) + +dn: cn=schema +changetype: modify +add: attributeTypes +attributeTypes: ( endRange-oid NAME 'endRange' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' ) + +dn: cn=schema +changetype: modify +add: attributeTypes attributeTypes: ( subjectName-oid NAME 'subjectName' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' ) dn: cn=schema @@ -355,13 +365,33 @@ attributeTypes: ( version-oid NAME 'version' DESC 'CMS defined attribute' SYNTAX dn: cn=schema changetype: modify +add: attributeTypes +attributeTypes: ( Clone-oid NAME 'Clone' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-ORIGIN 'user defined' ) + +dn: cn=schema +changetype: modify +add: attributeTypes +attributeTypes: ( DomainManager-oid NAME 'DomainManager' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-ORIGIN 'user defined' ) + +dn: cn=schema +changetype: modify +add: attributeTypes +attributeTypes: ( SecurePort-oid NAME 'SecurePort' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user defined' ) + +dn: cn=schema +changetype: modify +add: attributeTypes +attributeTypes: ( SubsystemName-oid NAME 'SubsystemName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'user defined' ) + +dn: cn=schema +changetype: modify add: objectClasses objectClasses: ( CertACLS-oid NAME 'CertACLS' DESC 'CMS defined class' SUP top STRUCTURAL MUST cn MAY resourceACLS X-ORIGIN 'user defined' ) dn: cn=schema changetype: modify add: objectClasses -objectClasses: ( repository-oid NAME 'repository' DESC 'CMS defined class' SUP top STRUCTURAL MUST ou MAY ( serialno $ description ) X-ORIGIN 'user defined' ) +objectClasses: ( repository-oid NAME 'repository' DESC 'CMS defined class' SUP top STRUCTURAL MUST ou MAY ( serialno $ description $ nextRange ) X-ORIGIN 'user defined' ) dn: cn=schema changetype: modify @@ -397,3 +427,24 @@ dn: cn=schema changetype: modify add: objectClasses objectClasses: ( keyRecord-oid NAME 'keyRecord' DESC 'CMS defined class' SUP top STRUCTURAL MUST cn MAY ( serialno $ dateOfCreate $ dateOfModify $ keyState $ privateKeyData $ ownerName $ keySize $ metaInfo $ dateOfArchival $ dateOfRecovery $ algorithm $ publicKeyFormat $ publicKeyData $ archivedBy ) X-ORIGIN 'user defined' ) + +dn: cn=schema +changetype: modify +add: objectClasses +objectClasses: ( pkiSecurityDomain-oid NAME 'pkiSecurityDomain' DESC 'CMS defined class' SUP top STRUCTURAL MUST ( ou $ name ) X-ORIGIN 'user defined' ) + +dn: cn=schema +changetype: modify +add: objectClasses +objectClasses: ( pkiSecurityGroup-oid NAME 'pkiSecurityGroup' DESC 'CMS defined class' SUP top STRUCTURAL MUST cn X-ORIGIN 'user defined' ) + +dn: cn=schema +changetype: modify +add: objectClasses +objectClasses: ( pkiSubsystem-oid NAME 'pkiSubsystem' DESC 'CMS defined class' SUP top STRUCTURAL MUST ( cn $ Host $ SecurePort $ SubsystemName $ Clone ) MAY ( DomainManager ) X-ORIGIN 'user defined' ) + +dn: cn=schema +changetype: modify +add: objectClasses +objectClasses: ( pkiRange-oid NAME 'pkiRange' DESC 'CMS defined class' SUP top STRUCTURAL MUST ( cn $ beginRange $ endRange $ Host $ SecurePort ) X-ORIGIN 'user defined' ) + diff --git a/pki/base/silent/src/ca/ConfigureCA.java b/pki/base/silent/src/ca/ConfigureCA.java index 8fc4b10c4..cc1b9d6eb 100644 --- a/pki/base/silent/src/ca/ConfigureCA.java +++ b/pki/base/silent/src/ca/ConfigureCA.java @@ -61,12 +61,19 @@ public class ConfigureCA { public static String domain_uri = "/ca/ee/ca/domain"; public static String ee_uri = "/ca/ee/ca/getBySerial"; public static String pkcs12_uri = "/ca/admin/console/config/savepkcs12"; + public static String sd_login_uri = "/ca/ee/ca/securityDomainLogin"; + public static String sd_get_cookie_uri = "/ca/ee/ca/getCookie"; public static String cs_hostname = null; public static String cs_port = null; public static String client_certdb_dir = null; public static String client_certdb_pwd = null; + public static String sd_hostname = null; + public static String sd_ssl_port = null; + public static String sd_admin_name = null; + public static String sd_admin_password = null; + // Login Panel public static String pin = null; @@ -131,6 +138,11 @@ public class ConfigureCA { public static String ext_csr_file = null; public static String signing_cc = null; + public static boolean clone = false; + public static String clone_uri = null; + public static String clone_p12_passwd = null; + public static String clone_p12_file = null; + public ConfigureCA() {// do nothing :) } @@ -189,16 +201,23 @@ public class ConfigureCA { public boolean DomainPanel() { try { - boolean st = false; HTTPResponse hr = null; ByteArrayInputStream bais = null; ParseXML px = new ParseXML(); String domain_url = "https://" + cs_hostname + ":" + cs_port; + String query_string = null; - String query_string = "sdomainURL=" + URLEncoder.encode(domain_url) - + "&sdomainName=" + URLEncoder.encode(domain_name) - + "&choice=newdomain" + "&p=1" + "&op=next" + "&xml=true"; + if (! clone) { + query_string = "sdomainURL=" + URLEncoder.encode(domain_url) + + "&sdomainName=" + URLEncoder.encode(domain_name) + + "&choice=newdomain" + "&p=1" + "&op=next" + "&xml=true"; + } else { + domain_url = "https://" + sd_hostname + ":" + sd_ssl_port ; + query_string = "sdomainURL=" + URLEncoder.encode(domain_url) + + "&sdomainName=" + + "&choice=existingdomain" + "&p=1" + "&op=next" + "&xml=true"; + } hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string); @@ -219,16 +238,78 @@ public class ConfigureCA { } } + public boolean DisplayCertChainPanel() { + try { + HTTPResponse hr = null; + String query_string = "p=2" + "&op=next" + "&xml=true"; + hr = hc.sslConnect(cs_hostname,cs_port,wizard_uri,query_string); + return true; + } catch (Exception e) { + System.out.println("Exception in DisplayCertChainPanel(): " + e.toString()); + e.printStackTrace(); + return false; + } + } + + public boolean SecurityDomainLoginPanel() { + try { + boolean st = false; + HTTPResponse hr = null; + ByteArrayInputStream bais = null; + ParseXML px = new ParseXML(); + String subca_url = "https://" + cs_hostname + ":" + cs_port + + "/ca/admin/console/config/wizard" + "?p=3&subsystem=CA" ; + + String query_string = "url=" + URLEncoder.encode(subca_url); + + hr = hc.sslConnect(sd_hostname,sd_ssl_port,sd_login_uri,query_string); + + String query_string_1 = "uid=" + sd_admin_name + "&pwd=" + sd_admin_password + + "&url=" + URLEncoder.encode(subca_url) ; + + hr = hc.sslConnect(sd_hostname,sd_ssl_port,sd_get_cookie_uri, + query_string_1); + + // get session id from security domain + + String subca_session_id = hr.getContentValue("header.session_id"); + String subca_url_1 = hr.getContentValue("header.url"); + + System.out.println("SUBCA_SESSION_ID=" + subca_session_id ); + System.out.println("SUBCA_URL=" + subca_url_1 ); + + // use session id to connect back to subCA + + String query_string_2 = "p=3" + "&subsystem=CA" + + "&session_id=" + subca_session_id + "&xml=true" ; + + hr = hc.sslConnect(cs_hostname,cs_port,wizard_uri, query_string_2); + return true; + } catch (Exception e) { + System.out.println("Exception in SecurityDomainLoginPanel(): " + e.toString()); + e.printStackTrace(); + return false; + } + } + public boolean CreateCAPanel() { try { boolean st = false; HTTPResponse hr = null; ByteArrayInputStream bais = null; ParseXML px = new ParseXML(); + String query_string = null; - String query_string = "p=3" + "&op=next" + "&xml=true" - + "&choice=newsubsystem" + "&subsystemName=" - + URLEncoder.encode(subsystem_name); + if (!clone) { + query_string = "p=3" + "&op=next" + "&xml=true" + + "&choice=newsubsystem" + "&subsystemName=" + + URLEncoder.encode(subsystem_name); + } else { + query_string = "p=3" + "&op=next" + "&xml=true" + + "&choice=clonesubsystem" + "&subsystemName=" + + URLEncoder.encode(subsystem_name) + + "&urls=0" + ""; + } hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string); @@ -237,14 +318,17 @@ public class ConfigureCA { px.parse(bais); px.prettyprintxml(); - // hr = null; - // query_string = "p=4" + "&op=next" + "&xml=true"; - // hr = hc.sslConnect(cs_hostname,cs_port,wizard_uri,query_string); - // parse xml - // bais = new ByteArrayInputStream(hr.getHTML().getBytes()); - // px.parse(bais); - // px.prettyprintxml(); + if (clone) { + hr = null; + query_string = "p=4" + "&op=next" + "&xml=true"; + hr = hc.sslConnect(cs_hostname,cs_port,wizard_uri,query_string); + + // parse xml + bais = new ByteArrayInputStream(hr.getHTML().getBytes()); + px.parse(bais); + px.prettyprintxml(); + } return true; } catch (Exception e) { @@ -254,6 +338,31 @@ public class ConfigureCA { } } + public boolean RestoreKeyCertPanel() { + try { + ByteArrayInputStream bais = null; + HTTPResponse hr = null; + ParseXML px = new ParseXML(); + + String query_string = "p=5" + "&op=next" + "&xml=true" + + "&password=" + URLEncoder.encode(clone_p12_passwd) + + "&path=" + URLEncoder.encode(clone_p12_file) + ""; + + hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string); + + // parse xml + bais = new ByteArrayInputStream(hr.getHTML().getBytes()); + px.parse(bais); + px.prettyprintxml(); + return true; + } catch (Exception e) { + System.out.println("Exception in RestoreKeyCertPanel(): " + e.toString()); + e.printStackTrace(); + return false; + } + } + + public boolean HierarchyPanel() { try { boolean st = false; @@ -379,18 +488,27 @@ public class ConfigureCA { ByteArrayInputStream bais = null; ParseXML px = new ParseXML(); ArrayList al = null; - - String query_string = "p=10" + "&op=next" + "&xml=true" - + "&subsystem_custom_size=" + key_size - + "&sslserver_custom_size=" + key_size + "&signing_keytype=" - + key_type + "&keytype=" + key_type + "&choice=custom" - + "&op=next" + "&custom_size=" + key_size - + "&ocsp_signing_keytype=" + key_type + "&subsystem_keytype=" - + key_type + "&ocsp_signing_custom_size=" + key_size - + "&signing_custom_size=" + key_size - + "&ocsp_signing_choice=custom" + "&signing_choice=custom" - + "&subsystem_choice=custom" + "&sslserver_keytype=" + key_type - + "&sslserver_choice=custom" + ""; + String query_string = null; + if (clone) { + query_string = "p=10" + "&op=next" + "&xml=true" + + "&sslserver_custom_size=" + key_size + + "&sslserver_choice=custom" + + "&sslserver_keytype=" + key_type + + "&choice=default" + "&keytype=" + key_type + + "&custom_size=" + key_size + ""; + } else { + query_string = "p=10" + "&op=next" + "&xml=true" + + "&subsystem_custom_size=" + key_size + + "&sslserver_custom_size=" + key_size + "&signing_keytype=" + + key_type + "&keytype=" + key_type + "&choice=custom" + + "&op=next" + "&custom_size=" + key_size + + "&ocsp_signing_keytype=" + key_type + "&subsystem_keytype=" + + key_type + "&ocsp_signing_custom_size=" + key_size + + "&signing_custom_size=" + key_size + + "&ocsp_signing_choice=custom" + "&signing_choice=custom" + + "&subsystem_choice=custom" + "&sslserver_keytype=" + key_type + + "&sslserver_choice=custom" + ""; + } hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string); @@ -439,16 +557,23 @@ public class ConfigureCA { ArrayList req_list = null; ArrayList cert_list = null; ArrayList dn_list = null; + String query_string = null; // use subject names provided as input - String query_string = "p=11" + "&op=next" + "&xml=true" + "&subsystem=" - + URLEncoder.encode(ca_subsystem_cert_subject_name) - + "&ocsp_signing=" - + URLEncoder.encode(ca_ocsp_cert_subject_name) + "&signing=" - + URLEncoder.encode(ca_sign_cert_subject_name) + "&sslserver=" - + URLEncoder.encode(ca_server_cert_subject_name) + "&urls=0" - + ""; + if (!clone) { + query_string = "p=11" + "&op=next" + "&xml=true" + "&subsystem=" + + URLEncoder.encode(ca_subsystem_cert_subject_name) + + "&ocsp_signing=" + + URLEncoder.encode(ca_ocsp_cert_subject_name) + "&signing=" + + URLEncoder.encode(ca_sign_cert_subject_name) + "&sslserver=" + + URLEncoder.encode(ca_server_cert_subject_name) + "&urls=0" + + ""; + } else { + query_string = "p=11" + "&op=next" + "&xml=true" + "&sslserver=" + + URLEncoder.encode(ca_server_cert_subject_name) + "&urls=0" + + ""; + } hr = hc.sslConnect(cs_hostname, cs_port, wizard_uri, query_string); @@ -976,18 +1101,26 @@ public class ConfigureCA { return false; } - /* - // 3. display cert chain panel - boolean disp_st = DisplayChainPanel(); - if(!disp_st) - { - System.out.println("ERROR: ConfigureCA: DisplayChainPanel() failure"); - return false; - } - */ + sleep_time(); + // 3. display cert chain panel and security domain login + if (clone) { + boolean disp_st = DisplayCertChainPanel(); + if(!disp_st) { + System.out.println("ERROR: ConfigureCA: DisplayCertChainPanel() failure"); + return false; + } + + boolean sd_st = SecurityDomainLoginPanel(); + if(! sd_st) + { + System.out.println("ERROR: ConfigureSubCA: SecurityDomainLoginPanel() failure"); + return false; + } + + } sleep_time(); - // 4. display cert chain panel + // 4. display create CA panel boolean disp_cert = CreateCAPanel(); if (!disp_cert) { @@ -995,6 +1128,16 @@ public class ConfigureCA { return false; } + sleep_time(); + // 5. display restore key cert panel + if (clone) { + boolean restore_st = RestoreKeyCertPanel(); + if (!restore_st) { + System.out.println("ERROR: ConfigureCA: RestoreKeyCertPanel() failure"); + return false; + } + } + // 6. Admin user panel // boolean disp_ad = AdminUserPanel(); // if(!disp_ad) @@ -1005,11 +1148,13 @@ public class ConfigureCA { sleep_time(); // 5. hierarchy panel - boolean disp_h = HierarchyPanel(); + if (! clone) { + boolean disp_h = HierarchyPanel(); - if (!disp_h) { - System.out.println("ERROR: ConfigureCA: HierarchyPanel() failure"); - return false; + if (!disp_h) { + System.out.println("ERROR: ConfigureCA: HierarchyPanel() failure"); + return false; + } } // Agent Auth panel @@ -1121,6 +1266,11 @@ public class ConfigureCA { System.out.println("ERROR: ConfigureCA: ImportCACertPanel() failure"); return false; } + + if (clone) { + // no other panels required for clone + return true; + } sleep_time(); @@ -1210,6 +1360,19 @@ public class ConfigureCA { StringHolder x_ext_ca_cert_chain_file = new StringHolder(); StringHolder x_ext_csr_file = new StringHolder(); + //clone parameters + StringHolder x_clone = new StringHolder(); + StringHolder x_clone_uri = new StringHolder(); + StringHolder x_clone_p12_file = new StringHolder(); + StringHolder x_clone_p12_passwd = new StringHolder(); + + //security domain + StringHolder x_sd_hostname = new StringHolder(); + StringHolder x_sd_ssl_port = new StringHolder(); + StringHolder x_sd_admin_name = new StringHolder(); + StringHolder x_sd_admin_password = new StringHolder(); + + // parse the args ArgParser parser = new ArgParser("ConfigureCA"); @@ -1274,6 +1437,19 @@ public class ConfigureCA { parser.addOption("-ext_csr_file %s #File to save the CSR for submission to an external CA", x_ext_csr_file); + parser.addOption("-clone %s #Clone of another CA [true, false]", x_clone); + parser.addOption("-clone_uri %s #URL of Master CA to clone", x_clone_uri); + parser.addOption("-clone_p12_file %s #File containing pk12 keys of Master CA", x_clone_p12_file); + parser.addOption("-clone_p12_password %s #Password for pk12 file", x_clone_p12_passwd); + + parser.addOption ("-sd_hostname %s #Security Domain Hostname", x_sd_hostname); + parser.addOption ("-sd_ssl_port %s #Security Domain SSL port", x_sd_ssl_port); + parser.addOption ("-sd_admin_name %s #Security Domain admin name", + x_sd_admin_name); + parser.addOption ("-sd_admin_password %s #Security Domain admin password", + x_sd_admin_password); + + // and then match the arguments String[] unmatched = null; @@ -1322,6 +1498,9 @@ public class ConfigureCA { subsystem_name = x_subsystem_name.value; external_ca = x_external_ca.value; + if (external_ca == null) { + external_ca = "false"; + } ext_ca_cert_file = x_ext_ca_cert_file.value; ext_ca_cert_chain_file = x_ext_ca_cert_chain_file.value; ext_csr_file = x_ext_csr_file.value; @@ -1329,6 +1508,20 @@ public class ConfigureCA { ext_csr_file = "/tmp/ext_ca.csr"; } + if ((x_clone.value != null) && (x_clone.value.equalsIgnoreCase("true"))) { + clone = true; + } else { + clone = false; + } + clone_uri = x_clone_uri.value; + clone_p12_file = x_clone_p12_file.value; + clone_p12_passwd = x_clone_p12_passwd.value; + + sd_hostname = x_sd_hostname.value; + sd_ssl_port = x_sd_ssl_port.value; + sd_admin_name = x_sd_admin_name.value; + sd_admin_password = x_sd_admin_password.value; + boolean st = ca.ConfigureCAInstance(); if (!st) { diff --git a/pki/base/tks/shared/conf/schema.ldif b/pki/base/tks/shared/conf/schema.ldif index ec5a1142e..823543dcf 100644 --- a/pki/base/tks/shared/conf/schema.ldif +++ b/pki/base/tks/shared/conf/schema.ldif @@ -1,8 +1,3 @@ -# --- BEGIN COPYRIGHT BLOCK --- -# Copyright (C) 2006 Red Hat, Inc. -# All rights reserved. -# --- END COPYRIGHT BLOCK --- -# dn: cn=schema changetype: modify add: attributeTypes @@ -306,6 +301,21 @@ attributeTypes: ( serialno-oid NAME 'serialno' DESC 'CMS defined attribute' SYNT dn: cn=schema changetype: modify add: attributeTypes +attributeTypes: ( nextRange-oid NAME 'nextRange' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' ) + +dn: cn=schema +changetype: modify +add: attributeTypes +attributeTypes: ( beginRange-oid NAME 'beginRange' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' ) + +dn: cn=schema +changetype: modify +add: attributeTypes +attributeTypes: ( endRange-oid NAME 'endRange' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' ) + +dn: cn=schema +changetype: modify +add: attributeTypes attributeTypes: ( subjectName-oid NAME 'subjectName' DESC 'CMS defined attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'user defined' ) dn: cn=schema @@ -355,13 +365,33 @@ attributeTypes: ( version-oid NAME 'version' DESC 'CMS defined attribute' SYNTAX dn: cn=schema changetype: modify +add: attributeTypes +attributeTypes: ( Clone-oid NAME 'Clone' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-ORIGIN 'user defined' ) + +dn: cn=schema +changetype: modify +add: attributeTypes +attributeTypes: ( DomainManager-oid NAME 'DomainManager' SYNTAX 1.3.6.1.4.1.1466.115.121.1.7 SINGLE-VALUE X-ORIGIN 'user defined' ) + +dn: cn=schema +changetype: modify +add: attributeTypes +attributeTypes: ( SecurePort-oid NAME 'SecurePort' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'user defined' ) + +dn: cn=schema +changetype: modify +add: attributeTypes +attributeTypes: ( SubsystemName-oid NAME 'SubsystemName' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'user defined' ) + +dn: cn=schema +changetype: modify add: objectClasses objectClasses: ( CertACLS-oid NAME 'CertACLS' DESC 'CMS defined class' SUP top STRUCTURAL MUST cn MAY resourceACLS X-ORIGIN 'user defined' ) dn: cn=schema changetype: modify add: objectClasses -objectClasses: ( repository-oid NAME 'repository' DESC 'CMS defined class' SUP top STRUCTURAL MUST ou MAY ( serialno $ description ) X-ORIGIN 'user defined' ) +objectClasses: ( repository-oid NAME 'repository' DESC 'CMS defined class' SUP top STRUCTURAL MUST ou MAY ( serialno $ description $ nextRange ) X-ORIGIN 'user defined' ) dn: cn=schema changetype: modify @@ -397,3 +427,24 @@ dn: cn=schema changetype: modify add: objectClasses objectClasses: ( keyRecord-oid NAME 'keyRecord' DESC 'CMS defined class' SUP top STRUCTURAL MUST cn MAY ( serialno $ dateOfCreate $ dateOfModify $ keyState $ privateKeyData $ ownerName $ keySize $ metaInfo $ dateOfArchival $ dateOfRecovery $ algorithm $ publicKeyFormat $ publicKeyData $ archivedBy ) X-ORIGIN 'user defined' ) + +dn: cn=schema +changetype: modify +add: objectClasses +objectClasses: ( pkiSecurityDomain-oid NAME 'pkiSecurityDomain' DESC 'CMS defined class' SUP top STRUCTURAL MUST ( ou $ name ) X-ORIGIN 'user defined' ) + +dn: cn=schema +changetype: modify +add: objectClasses +objectClasses: ( pkiSecurityGroup-oid NAME 'pkiSecurityGroup' DESC 'CMS defined class' SUP top STRUCTURAL MUST cn X-ORIGIN 'user defined' ) + +dn: cn=schema +changetype: modify +add: objectClasses +objectClasses: ( pkiSubsystem-oid NAME 'pkiSubsystem' DESC 'CMS defined class' SUP top STRUCTURAL MUST ( cn $ Host $ SecurePort $ SubsystemName $ Clone ) MAY ( DomainManager ) X-ORIGIN 'user defined' ) + +dn: cn=schema +changetype: modify +add: objectClasses +objectClasses: ( pkiRange-oid NAME 'pkiRange' DESC 'CMS defined class' SUP top STRUCTURAL MUST ( cn $ beginRange $ endRange $ Host $ SecurePort ) X-ORIGIN 'user defined' ) + |