From 5bfe936a1de392d349c0a32a46480e4f78b1ce6b Mon Sep 17 00:00:00 2001 From: Jack Magne Date: Sun, 12 Apr 2020 12:26:51 -0700 Subject: [PATCH] Fix Bug 1809273 - CRL generation performs an unindexed search. --- base/ca/shared/conf/crlcaissuer.ldif | 15 +++ base/ca/shared/conf/crlcaissuertasks.ldif | 7 ++ base/server/python/pki/server/cli/db.py | 32 +++++- .../deployment/scriptlets/configuration.py | 6 ++ base/server/python/pki/server/subsystem.py | 23 ++++ .../cms/servlet/csadmin/LDAPConfigurator.java | 39 +++++++ .../dogtagpki/server/cli/CADBUpgradeCLI.java | 102 +++++++++++++++++- .../server/cli/SubsystemDBUpgradeCLI.java | 4 +- 8 files changed, 223 insertions(+), 5 deletions(-) create mode 100644 base/ca/shared/conf/crlcaissuer.ldif create mode 100644 base/ca/shared/conf/crlcaissuertasks.ldif diff --git a/base/ca/shared/conf/crlcaissuer.ldif b/base/ca/shared/conf/crlcaissuer.ldif new file mode 100644 index 00000000000..2fec1a0b83a --- /dev/null +++ b/base/ca/shared/conf/crlcaissuer.ldif @@ -0,0 +1,15 @@ +dn: cn=allRevokedCertsByIssuer-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config +objectClass: top +objectClass: vlvSearch +cn: allRevokedCertsByIssuer-{instanceId} +vlvBase: ou=certificateRepository,ou=ca,{rootSuffix} +vlvScope: 1 +vlvFilter: (&(certStatus=REVOKED)(|(!(issuerName=*))(issuerName={caIssuerDN}))) + +dn: cn=allRevokedCertsByIssuer-{instanceId}Index, cn=allRevokedCerts-{instanceId}, cn={database}, cn=ldbm database, cn=plugins, cn=config +objectClass: top +objectClass: vlvIndex +cn: allRevokedCertsByIssuer-{instanceId}Index +vlvSort: serialno +vlvEnabled: 0 +vlvUses: 0 diff --git a/base/ca/shared/conf/crlcaissuertasks.ldif b/base/ca/shared/conf/crlcaissuertasks.ldif new file mode 100644 index 00000000000..888e11338c7 --- /dev/null +++ b/base/ca/shared/conf/crlcaissuertasks.ldif @@ -0,0 +1,7 @@ +dn: cn=index1160589779, cn=index, cn=tasks, cn=config +objectclass: top +objectclass: extensibleObject +cn: index1160589779 +ttl: 10 +nsinstance: {database} +nsindexVLVAttribute: allRevokedCertsByIssuer-{instanceId} diff --git a/base/server/python/pki/server/cli/db.py b/base/server/python/pki/server/cli/db.py index 7e8e7a19af2..8c194ff9e09 100644 --- a/base/server/python/pki/server/cli/db.py +++ b/base/server/python/pki/server/cli/db.py @@ -806,6 +806,19 @@ def print_help(self): print('Usage: pki-server %s-db-upgrade [OPTIONS]' % self.parent.parent.name) print() print(' -i, --instance Instance ID (default: pki-tomcat).') + if self.parent.parent.name == "ca": + print(' --action update-vlv-indexes or:') + print(' fix-missing-issuer-names') + print(' (default: fix-missing-issuer-names)') + print(' --issuer_dn CA signing cert issuer dn') + print(' required only for update-vlv-indexes') + print(' --vlv-file LDIF file with desired vlv indexes') + print(' required only for update-vlv-indexes') + print(' --vlv-tasks-file LDIF file with desired vlv tasks') + print(' required only for update-vlv-indexes') + else: + print(' --action fix-missing-issuer-names') + print(' (default: fix-missing-issuer-names)') print(' --as-current-user Run as current user.') print(' -v, --verbose Run in verbose mode.') print(' --debug Run in debug mode.') @@ -816,7 +829,8 @@ def execute(self, argv): try: opts, _ = getopt.gnu_getopt(argv, 'i:v', [ 'instance=', - 'as-current-user', + 'as-current-user', "action=", "issuer-dn=", + 'vlv-file=', 'vlv-tasks-file=', 'verbose', 'debug', 'help']) except getopt.GetoptError as e: @@ -831,6 +845,7 @@ def execute(self, argv): cmd = [subsystem_name + '-db-upgrade'] for o, a in opts: + logging.info('opt %s', o) if o in ('-i', '--instance'): instance_name = a @@ -849,6 +864,20 @@ def execute(self, argv): self.print_help() sys.exit() + elif o == '--issuer-dn': + logging.info('--issuer-dn') + cmd.extend(['--issuer-dn', a]) + + elif o == '--action': + logging.info('--action') + cmd.extend(['--action', a]) + + elif o == '--vlv-file': + cmd.extend(['--vlv-file', a]) + + elif o == '--vlv-tasks-file': + cmd.extend(['--vlv-tasks-file', a]) + else: logging.error('Invalid option: %s', o) self.print_help() @@ -868,5 +897,4 @@ def execute(self, argv): logging.error('No %s subsystem in instance %s.', subsystem_name.upper(), instance_name) sys.exit(1) - subsystem.run(cmd, as_current_user=as_current_user) diff --git a/base/server/python/pki/server/deployment/scriptlets/configuration.py b/base/server/python/pki/server/deployment/scriptlets/configuration.py index a097a570662..29dec3385f6 100644 --- a/base/server/python/pki/server/deployment/scriptlets/configuration.py +++ b/base/server/python/pki/server/deployment/scriptlets/configuration.py @@ -802,6 +802,12 @@ def spawn(self, deployer): setup_db_manager=setup_db_manager, setup_vlv_indexes=setup_vlv_indexes) + update_crl_vlv_indexes = (subsystem.type == 'CA') + if update_crl_vlv_indexes: + subsystem.update_database( + issuer_dn=deployer.mdict['pki_ca_signing_subject_dn'], + update_crl_vlv_indexes=update_crl_vlv_indexes) + # Start/Restart this Tomcat PKI Process # Optionally prepare to enable a java debugger # (e. g. - 'eclipse'): diff --git a/base/server/python/pki/server/subsystem.py b/base/server/python/pki/server/subsystem.py index 613b98bf792..be9e7f6c80f 100644 --- a/base/server/python/pki/server/subsystem.py +++ b/base/server/python/pki/server/subsystem.py @@ -888,6 +888,29 @@ def init_database( self.run(cmd, as_current_user=as_current_user) + def update_database( + self, + issuer_dn, + update_crl_vlv_indexes=False, + as_current_user=False): + + if self.name != 'ca': + return + cmd = [self.name + '-db-upgrade'] + if update_crl_vlv_indexes: + cmd.extend(['--action', 'update-vlv-indexes']) + cmd.extend(['--vlv-file', 'crlcaissuer.ldif']) + cmd.extend(['--vlv-tasks-file', 'crlcaissuertasks.ldif']) + cmd.extend(['--issuer-dn', issuer_dn]) + + if logger.isEnabledFor(logging.DEBUG): + cmd.append('--debug') + + elif logger.isEnabledFor(logging.INFO): + cmd.append('--verbose') + + self.run(cmd, as_current_user=as_current_user) + def empty_database(self, force=False, as_current_user=False): cmd = [self.name + '-db-empty'] diff --git a/base/server/src/com/netscape/cms/servlet/csadmin/LDAPConfigurator.java b/base/server/src/com/netscape/cms/servlet/csadmin/LDAPConfigurator.java index 1410706613b..2a99425cd59 100644 --- a/base/server/src/com/netscape/cms/servlet/csadmin/LDAPConfigurator.java +++ b/base/server/src/com/netscape/cms/servlet/csadmin/LDAPConfigurator.java @@ -76,6 +76,14 @@ public LDAPConfigurator(LDAPConnection connection, String instanceId, LDAPConfig params.put("dbuser", dbuser); } + public LDAPConfigurator(LDAPConnection connection, String instanceId, String caIssuerDN, LDAPConfig ldapConfig) + throws Exception { + + this(connection,instanceId, ldapConfig); + params.put("caIssuerDN", caIssuerDN); + + } + public LDAPConnection getConnection() { return connection; } @@ -148,6 +156,37 @@ public void createVLVIndexes(String subsystem) throws Exception { importFile("/usr/share/pki/" + subsystem + "/conf/vlv.ldif", true); } + public void createAdditionalVLVIndexes(String subsystem, String vlvLdifFileName) throws Exception { + logger.info("Creating additional VLV indexes in file: ", vlvLdifFileName); + + importFile("/usr/share/pki/" + subsystem + "/conf/" + vlvLdifFileName,true); + } + + public void rebuildAdditionalVLVIndexes(String subsystem, String vlvTasksFileName) throws Exception { + logger.info("Rebuilding Additional VLV indexes in file: ", vlvTasksFileName); + + File file = new File("/usr/share/pki/" + subsystem + "/conf/" + vlvTasksFileName); + File tmpFile = File.createTempFile("pki-" + subsystem + "-reindex-additional", ".ldif"); + + try { + customizeFile(file, tmpFile); + + LDIF ldif = new LDIF(tmpFile.getAbsolutePath()); + LDIFRecord record = ldif.nextRecord(); + if (record == null) + return; + + importLDIFRecord(record, false); + + String dn = record.getDN(); + waitForTask(dn); + + } finally { + tmpFile.delete(); + } + + } + public void rebuildVLVIndexes(String subsystem) throws Exception { logger.info("Rebuilding VLV indexes"); diff --git a/base/server/src/org/dogtagpki/server/cli/CADBUpgradeCLI.java b/base/server/src/org/dogtagpki/server/cli/CADBUpgradeCLI.java index b8e48419a02..b3a7d843978 100644 --- a/base/server/src/org/dogtagpki/server/cli/CADBUpgradeCLI.java +++ b/base/server/src/org/dogtagpki/server/cli/CADBUpgradeCLI.java @@ -18,17 +18,25 @@ package org.dogtagpki.server.cli; +import java.security.cert.CertificateException; + +import org.apache.commons.cli.CommandLine; +import org.apache.commons.cli.Option; +import org.apache.commons.lang.StringUtils; import org.dogtagpki.cli.CLI; import org.mozilla.jss.netscape.security.x509.X509CertImpl; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import com.netscape.certsrv.base.EBaseException; +import com.netscape.cms.servlet.csadmin.LDAPConfigurator; import com.netscape.cmscore.ldapconn.LDAPConfig; import com.netscape.cmscore.ldapconn.LdapBoundConnection; import netscape.ldap.LDAPAttribute; import netscape.ldap.LDAPAttributeSet; import netscape.ldap.LDAPEntry; +import netscape.ldap.LDAPException; import netscape.ldap.LDAPModification; import netscape.ldap.LDAPSearchResults; import netscape.ldap.LDAPv3; @@ -44,13 +52,68 @@ public CADBUpgradeCLI(CLI parent) { super("upgrade", "Upgrade CA database", parent); } - public void upgrade(LDAPConfig ldapConfig, LdapBoundConnection conn) throws Exception { + public void createOptions() { + + Option action = new Option(null, "action", true, "Desired CA database upgrade action"); + action.setArgName("action"); + options.addOption(action); + + + Option issuerDn = new Option(null, "issuer-dn", true, "Optional CA issuer DN"); + issuerDn.setArgName("issuer-dn"); + options.addOption(issuerDn); + + Option vlvFile = new Option(null,"vlv-file",true, "Vlv file to update vlv indexes"); + vlvFile.setArgName("vlv-file"); + options.addOption(vlvFile); + + Option vlvTasksFile = new Option(null,"vlv-tasks-file",true, "Vlv tasks file to update vlv indexes"); + vlvTasksFile.setArgName("vlv-tasks-file"); + options.addOption(vlvTasksFile); + + } + + public void execute(CommandLine cmd) throws Exception { + this.cmd = cmd; + super.execute(cmd); + } + + public void upgrade(String instanceId, LDAPConfig ldapConfig, LdapBoundConnection conn) throws Exception { + + if (cmd.hasOption("action")) { + String caIssuerDn = null; + String actionVal = cmd.getOptionValue("action"); + logger.info("Attempting to execute a specific action: " + actionVal); + + if (cmd.hasOption("issuer-dn")) { + caIssuerDn = cmd.getOptionValue("issuer-dn"); + } + + if ("update-vlv-indexes".equals(actionVal)) { + updateVlvIndexes(instanceId, caIssuerDn, ldapConfig, conn); + return; + } else if ("fix-missing-issuer-names".equals(actionVal)) { + fixMissingIssuerNames(ldapConfig, conn); + return; + } else { + logger.info("Invalid action requested: " + actionVal); + return; + } + } + + //Take default action which is to upgrade the db with missing issuerNames + fixMissingIssuerNames(ldapConfig, conn); + } + + private void fixMissingIssuerNames(LDAPConfig ldapConfig, LdapBoundConnection conn) + throws EBaseException, LDAPException, CertificateException { logger.info("Searching certificates records with missing issuerName"); String baseDN = ldapConfig.getBaseDN(); String certRepoDN = "ou=certificateRepository,ou=ca," + baseDN; + LDAPSearchResults results = conn.search( certRepoDN, LDAPv3.SCOPE_ONE, @@ -79,4 +142,41 @@ public void upgrade(LDAPConfig ldapConfig, LdapBoundConnection conn) throws Exce conn.modify(entry.getDN(), mods); } } + + private void updateVlvIndexes(String instanceId, String caIssuerDn, LDAPConfig ldapConfig, LdapBoundConnection conn) + throws Exception { + + String actionVal = cmd.getOptionValue("action"); + + if (StringUtils.isEmpty(actionVal)) { + logger.info("Invalid number of args for updateVlvIndexes"); + return; + } + + if (!cmd.hasOption("vlv-file")) { + logger.info("Command must have a value for argument vlv-file"); + return; + } + + if (StringUtils.isEmpty(caIssuerDn)) { + logger.info("Command must have a value for argument issuerDN "); + return; + } + + String vlvName = cmd.getOptionValue("vlv-file"); + String vlvTasksName = cmd.getOptionValue("vlv-tasks-file"); + + if (StringUtils.isEmpty(vlvName) || StringUtils.isEmpty(vlvTasksName)) { + logger.info("Command must include vlv-fle and vlv-tasks-file arguments"); + return; + } + + LDAPConfigurator ldapConfigurator = new LDAPConfigurator(conn, instanceId, caIssuerDn, ldapConfig); + + ldapConfigurator.createAdditionalVLVIndexes("ca", vlvName); + ldapConfigurator.rebuildAdditionalVLVIndexes("ca", vlvTasksName); + + } + + private CommandLine cmd = null; } diff --git a/base/server/src/org/dogtagpki/server/cli/SubsystemDBUpgradeCLI.java b/base/server/src/org/dogtagpki/server/cli/SubsystemDBUpgradeCLI.java index 882dbef5dc5..b49c6457268 100644 --- a/base/server/src/org/dogtagpki/server/cli/SubsystemDBUpgradeCLI.java +++ b/base/server/src/org/dogtagpki/server/cli/SubsystemDBUpgradeCLI.java @@ -117,7 +117,7 @@ public void execute(CommandLine cmd) throws Exception { LdapBoundConnection conn = new LdapBoundConnection(socketFactory, connInfo, authInfo); try { - upgrade(ldapConfig, conn); + upgrade(instanceId, ldapConfig, conn); } finally { conn.disconnect(); @@ -126,6 +126,6 @@ public void execute(CommandLine cmd) throws Exception { System.out.println(parent.parent.name.toUpperCase() + " database upgraded"); } - public void upgrade(LDAPConfig ldapConfig, LdapBoundConnection conn) throws Exception { + public void upgrade(String instanceId,LDAPConfig ldapConfig, LdapBoundConnection conn) throws Exception { } }