Blame SOURCES/pki-core-Fixed-Number-Range-Depletion-Issue.patch

feffdc
From 93b1ecae5aff7a18e16556f749c8aba5806dc512 Mon Sep 17 00:00:00 2001
feffdc
From: Fraser Tweedale <ftweedal@redhat.com>
feffdc
Date: Wed, 29 Aug 2018 16:55:31 +1000
feffdc
Subject: [PATCH 1/5] getTheSerialNumber: only return null if next range not
feffdc
 available
feffdc
feffdc
When cloning, if the master's current number range has been depleted
feffdc
due to a previous UpdateNumberRange request,
feffdc
Repository.getTheSerialNumber() returns null because the next serial
feffdc
number is out of the current range, but the next range has not been
feffdc
activated yet.  NullPointerException ensues.
feffdc
feffdc
Update getTheSerialNumber() to return the next serial number even
feffdc
when it exceeds the current number range, as long as there is a next
feffdc
range.  If there is no next range, return null (as before).  It is
feffdc
assumed that the next range is non-empty
feffdc
feffdc
Also do a couple of drive-by method extractions to improve
feffdc
readability.
feffdc
feffdc
Part of: https://pagure.io/dogtagpki/issue/3055
feffdc
feffdc
(cherry picked from commit f1615df509053a8f474b82ea6a2fa0883ab06d09)
feffdc
---
feffdc
 .../src/com/netscape/cmscore/dbs/Repository.java   | 61 ++++++++++++++++------
feffdc
 1 file changed, 44 insertions(+), 17 deletions(-)
feffdc
feffdc
diff --git a/base/server/cmscore/src/com/netscape/cmscore/dbs/Repository.java b/base/server/cmscore/src/com/netscape/cmscore/dbs/Repository.java
feffdc
index afe9013..c5120c4 100644
feffdc
--- a/base/server/cmscore/src/com/netscape/cmscore/dbs/Repository.java
feffdc
+++ b/base/server/cmscore/src/com/netscape/cmscore/dbs/Repository.java
feffdc
@@ -317,7 +317,15 @@ public abstract class Repository implements IRepository {
feffdc
     }
feffdc
 
feffdc
     /**
feffdc
-     * get the next serial number in cache
feffdc
+     * Peek at the next serial number in cache (does not consume the
feffdc
+     * number).
feffdc
+     *
feffdc
+     * The returned number is not necessarily the previously emitted
feffdc
+     * serial number plus one, i.e. if we are going to roll into the
feffdc
+     * next range.  This method does not actually switch the range.
feffdc
+     *
feffdc
+     * Returns null if the next number exceeds the current range and
feffdc
+     * there is not a next range.
feffdc
      */
feffdc
     public BigInteger getTheSerialNumber() throws EBaseException {
feffdc
 
feffdc
@@ -327,7 +335,7 @@ public abstract class Repository implements IRepository {
feffdc
         BigInteger serial = mLastSerialNo.add(BigInteger.ONE);
feffdc
 
feffdc
         if (mMaxSerialNo != null && serial.compareTo(mMaxSerialNo) > 0)
feffdc
-            return null;
feffdc
+            return hasNextRange() ? mNextMinSerialNo : null;
feffdc
         else
feffdc
             return serial;
feffdc
     }
feffdc
@@ -390,9 +398,13 @@ public abstract class Repository implements IRepository {
feffdc
     }
feffdc
 
feffdc
     /**
feffdc
-     * Checks to see if range needs to be switched.
feffdc
+     * Checks if the given number is in the current range.
feffdc
+     * If it does not exceed the current range, return cleanly.
feffdc
+     * If it exceeds the given range, and there is a next range, switch the range.
feffdc
+     * If it exceeds the given range, and there is not a next range, throw EDBException.
feffdc
      *
feffdc
-     * @exception EBaseException thrown when next range is not allocated
feffdc
+     * @exception EDBException thrown when range switch is needed
feffdc
+     *                           but next range is not allocated
feffdc
      */
feffdc
     protected void checkRange() throws EBaseException
feffdc
     {
feffdc
@@ -413,7 +425,7 @@ public abstract class Repository implements IRepository {
feffdc
 
feffdc
             if (mDB.getEnableSerialMgmt()) {
feffdc
                 CMS.debug("Reached the end of the range.  Attempting to move to next range");
feffdc
-                if ((mNextMinSerialNo == null) || (mNextMaxSerialNo == null)) {
feffdc
+                if (!hasNextRange()) {
feffdc
                     if (rangeLength != null && mCounter.compareTo(rangeLength) < 0) {
feffdc
                         return;
feffdc
                     } else {
feffdc
@@ -421,18 +433,7 @@ public abstract class Repository implements IRepository {
feffdc
                                                                   mLastSerialNo.toString()));
feffdc
                     }
feffdc
                 }
feffdc
-                mMinSerialNo = mNextMinSerialNo;
feffdc
-                mMaxSerialNo = mNextMaxSerialNo;
feffdc
-                mLastSerialNo = mMinSerialNo;
feffdc
-                mNextMinSerialNo  = null;
feffdc
-                mNextMaxSerialNo  = null;
feffdc
-                mCounter = BigInteger.ZERO;
feffdc
-
feffdc
-                // persist the changes
feffdc
-                mDB.setMinSerialConfig(mRepo, mMinSerialNo.toString(mRadix));
feffdc
-                mDB.setMaxSerialConfig(mRepo, mMaxSerialNo.toString(mRadix));
feffdc
-                mDB.setNextMinSerialConfig(mRepo, null);
feffdc
-                mDB.setNextMaxSerialConfig(mRepo, null);
feffdc
+                switchToNextRange();
feffdc
             } else {
feffdc
                 throw new EDBException(CMS.getUserMessage("CMS_DBS_LIMIT_REACHED",
feffdc
                         mLastSerialNo.toString()));
feffdc
@@ -441,6 +442,32 @@ public abstract class Repository implements IRepository {
feffdc
     }
feffdc
 
feffdc
     /**
feffdc
+     * Return true iff there is a next range ready to go.
feffdc
+     */
feffdc
+    private boolean hasNextRange() {
feffdc
+        return (mNextMinSerialNo != null) && (mNextMaxSerialNo != null);
feffdc
+    }
feffdc
+
feffdc
+    /**
feffdc
+     * Switch to the next range and persist the changes.
feffdc
+     */
feffdc
+    private void switchToNextRange()
feffdc
+            throws EBaseException {
feffdc
+        mMinSerialNo = mNextMinSerialNo;
feffdc
+        mMaxSerialNo = mNextMaxSerialNo;
feffdc
+        mLastSerialNo = mMinSerialNo;
feffdc
+        mNextMinSerialNo  = null;
feffdc
+        mNextMaxSerialNo  = null;
feffdc
+        mCounter = BigInteger.ZERO;
feffdc
+
feffdc
+        // persist the changes
feffdc
+        mDB.setMinSerialConfig(mRepo, mMinSerialNo.toString(mRadix));
feffdc
+        mDB.setMaxSerialConfig(mRepo, mMaxSerialNo.toString(mRadix));
feffdc
+        mDB.setNextMinSerialConfig(mRepo, null);
feffdc
+        mDB.setNextMaxSerialConfig(mRepo, null);
feffdc
+    }
feffdc
+
feffdc
+    /**
feffdc
      * Checks to see if a new range is needed, or if we have reached the end of the
feffdc
      * current range, or if a range conflict has occurred.
feffdc
      *
feffdc
-- 
feffdc
1.8.3.1
feffdc
feffdc
feffdc
From 35714763d32425f18a0ac8817aad96c8cfab589b Mon Sep 17 00:00:00 2001
feffdc
From: Fraser Tweedale <ftweedal@redhat.com>
feffdc
Date: Mon, 3 Sep 2018 15:55:35 +1000
feffdc
Subject: [PATCH 2/5] Repository: handle depleted range in initCache()
feffdc
feffdc
Repository.initCache() does not handle the case where the current
feffdc
range has been fully depleted, but the switch to the next range has
feffdc
not occurred yet.  This situation arises when the range has been
feffdc
fully depleted by servicing UpdateNumberRange requests for clones.
feffdc
feffdc
Detect this situation and handle it by switching to the next range
feffdc
(when available).
feffdc
feffdc
Part of: https://pagure.io/dogtagpki/issue/3055
feffdc
feffdc
(cherry picked from commit 2fb3611db5145dbdd5e7e14daaad1470691494f0)
feffdc
---
feffdc
 .../src/com/netscape/cmscore/dbs/Repository.java      | 19 +++++++++++++++++++
feffdc
 1 file changed, 19 insertions(+)
feffdc
feffdc
diff --git a/base/server/cmscore/src/com/netscape/cmscore/dbs/Repository.java b/base/server/cmscore/src/com/netscape/cmscore/dbs/Repository.java
feffdc
index c5120c4..828217c 100644
feffdc
--- a/base/server/cmscore/src/com/netscape/cmscore/dbs/Repository.java
feffdc
+++ b/base/server/cmscore/src/com/netscape/cmscore/dbs/Repository.java
feffdc
@@ -298,6 +298,25 @@ public abstract class Repository implements IRepository {
feffdc
         BigInteger theSerialNo = null;
feffdc
         theSerialNo = getLastSerialNumberInRange(mMinSerialNo, mMaxSerialNo);
feffdc
 
feffdc
+        if (theSerialNo == null) {
feffdc
+            // This arises when range has been depleted by servicing
feffdc
+            // UpdateNumberRange requests for clones.  Attempt to
feffdc
+            // move to next range.
feffdc
+            CMS.debug(
feffdc
+                "Repository: failed to get last serial number in range "
feffdc
+                + mMinSerialNo + ".." + mMaxSerialNo);
feffdc
+
feffdc
+            if (hasNextRange()) {
feffdc
+                CMS.debug("Repository: switching to next range.");
feffdc
+                switchToNextRange();
feffdc
+                CMS.debug("Repository: new range: " + mMinSerialNo + ".." + mMaxSerialNo);
feffdc
+                // try again with updated range
feffdc
+                theSerialNo = getLastSerialNumberInRange(mMinSerialNo, mMaxSerialNo);
feffdc
+            } else {
feffdc
+                CMS.debug("Repository: next range not available.");
feffdc
+            }
feffdc
+        }
feffdc
+
feffdc
         if (theSerialNo != null) {
feffdc
 
feffdc
             mLastSerialNo = new BigInteger(theSerialNo.toString());
feffdc
-- 
feffdc
1.8.3.1
feffdc
feffdc
feffdc
From e1345a22c1d5236754fbeb93b0d3f8f2c447d918 Mon Sep 17 00:00:00 2001
feffdc
From: Fraser Tweedale <ftweedal@redhat.com>
feffdc
Date: Wed, 29 Aug 2018 17:31:34 +1000
feffdc
Subject: [PATCH 3/5] rename method getTheSerialNumber -> peekNextSerialNumber
feffdc
feffdc
Rename Repository.getTheSerialNumber -> peekNextSerialNumber to more
feffdc
accurately reflect what it does: peek at the next serial number
feffdc
without actually consuming it.
feffdc
feffdc
Part of: https://pagure.io/dogtagpki/issue/3055
feffdc
feffdc
(cherry picked from commit 85e356580f64f87c0b01736b71dc3d385db0bcba)
feffdc
---
feffdc
 base/ca/src/com/netscape/ca/CertificateAuthority.java                   | 2 +-
feffdc
 base/common/src/com/netscape/certsrv/dbs/repository/IRepository.java    | 2 +-
feffdc
 .../cms/src/com/netscape/cms/servlet/csadmin/UpdateNumberRange.java     | 2 +-
feffdc
 base/server/cmscore/src/com/netscape/cmscore/dbs/Repository.java        | 2 +-
feffdc
 4 files changed, 4 insertions(+), 4 deletions(-)
feffdc
feffdc
diff --git a/base/ca/src/com/netscape/ca/CertificateAuthority.java b/base/ca/src/com/netscape/ca/CertificateAuthority.java
feffdc
index 0281db0..f414628 100644
feffdc
--- a/base/ca/src/com/netscape/ca/CertificateAuthority.java
feffdc
+++ b/base/ca/src/com/netscape/ca/CertificateAuthority.java
feffdc
@@ -1077,7 +1077,7 @@ public class CertificateAuthority
feffdc
     public String getStartSerial() {
feffdc
         try {
feffdc
             BigInteger serial =
feffdc
-                    mCertRepot.getTheSerialNumber();
feffdc
+                    mCertRepot.peekNextSerialNumber();
feffdc
 
feffdc
             if (serial == null)
feffdc
                 return "";
feffdc
diff --git a/base/common/src/com/netscape/certsrv/dbs/repository/IRepository.java b/base/common/src/com/netscape/certsrv/dbs/repository/IRepository.java
feffdc
index 39744ac..d0b6135 100644
feffdc
--- a/base/common/src/com/netscape/certsrv/dbs/repository/IRepository.java
feffdc
+++ b/base/common/src/com/netscape/certsrv/dbs/repository/IRepository.java
feffdc
@@ -50,7 +50,7 @@ public interface IRepository {
feffdc
      * @return serial number
feffdc
      * @exception EBaseException failed to retrieve next serial number
feffdc
      */
feffdc
-    public BigInteger getTheSerialNumber() throws EBaseException;
feffdc
+    public BigInteger peekNextSerialNumber() throws EBaseException;
feffdc
 
feffdc
     /**
feffdc
      * Set the maximum serial number.
feffdc
diff --git a/base/server/cms/src/com/netscape/cms/servlet/csadmin/UpdateNumberRange.java b/base/server/cms/src/com/netscape/cms/servlet/csadmin/UpdateNumberRange.java
feffdc
index 2586da2..e5b5168 100644
feffdc
--- a/base/server/cms/src/com/netscape/cms/servlet/csadmin/UpdateNumberRange.java
feffdc
+++ b/base/server/cms/src/com/netscape/cms/servlet/csadmin/UpdateNumberRange.java
feffdc
@@ -187,7 +187,7 @@ public class UpdateNumberRange extends CMSServlet {
feffdc
             BigInteger decrement = new BigInteger(decrementStr, radix);
feffdc
             beginNum = endNum.subtract(decrement).add(oneNum);
feffdc
 
feffdc
-            if (beginNum.compareTo(repo.getTheSerialNumber()) < 0) {
feffdc
+            if (beginNum.compareTo(repo.peekNextSerialNumber()) < 0) {
feffdc
                 String nextEndNumStr = cs.getString(nextEndConfig, "");
feffdc
                 BigInteger endNum2 = new BigInteger(nextEndNumStr, radix);
feffdc
                 CMS.debug("Transferring from the end of on-deck range");
feffdc
diff --git a/base/server/cmscore/src/com/netscape/cmscore/dbs/Repository.java b/base/server/cmscore/src/com/netscape/cmscore/dbs/Repository.java
feffdc
index 828217c..55068ea 100644
feffdc
--- a/base/server/cmscore/src/com/netscape/cmscore/dbs/Repository.java
feffdc
+++ b/base/server/cmscore/src/com/netscape/cmscore/dbs/Repository.java
feffdc
@@ -346,7 +346,7 @@ public abstract class Repository implements IRepository {
feffdc
      * Returns null if the next number exceeds the current range and
feffdc
      * there is not a next range.
feffdc
      */
feffdc
-    public BigInteger getTheSerialNumber() throws EBaseException {
feffdc
+    public BigInteger peekNextSerialNumber() throws EBaseException {
feffdc
 
feffdc
         CMS.debug("Repository:In getTheSerialNumber ");
feffdc
         if (mLastSerialNo == null)
feffdc
-- 
feffdc
1.8.3.1
feffdc
feffdc
feffdc
From 26586f3e711f1e238d4692f801dd8de42b88fc53 Mon Sep 17 00:00:00 2001
feffdc
From: Fraser Tweedale <ftweedal@redhat.com>
feffdc
Date: Wed, 29 Aug 2018 21:42:40 +1000
feffdc
Subject: [PATCH 4/5] checkRange: small refactor and add commentary
feffdc
feffdc
Add some commentary about the behaviour and proper usage of
feffdc
Repository.checkRange().  Also perform a small refactor, avoiding
feffdc
a redundant stringify and parse.
feffdc
feffdc
Part of: https://pagure.io/dogtagpki/issue/3055
feffdc
feffdc
(cherry picked from commit 5a606e83719272fb488047b28a9ca7d5ce2ea30b)
feffdc
---
feffdc
 .../src/com/netscape/cmscore/dbs/Repository.java      | 19 +++++++++++++++----
feffdc
 1 file changed, 15 insertions(+), 4 deletions(-)
feffdc
feffdc
diff --git a/base/server/cmscore/src/com/netscape/cmscore/dbs/Repository.java b/base/server/cmscore/src/com/netscape/cmscore/dbs/Repository.java
feffdc
index 55068ea..9bc7e2a 100644
feffdc
--- a/base/server/cmscore/src/com/netscape/cmscore/dbs/Repository.java
feffdc
+++ b/base/server/cmscore/src/com/netscape/cmscore/dbs/Repository.java
feffdc
@@ -406,14 +406,17 @@ public abstract class Repository implements IRepository {
feffdc
             throw new EBaseException("mLastSerialNo is null");
feffdc
         }
feffdc
 
feffdc
+        /* Advance the serial number.  checkRange() will check if it exceeds
feffdc
+         * the current range and, if so, rolls to the next range and resets
feffdc
+         * mLastSerialNo to the start of the new range.  Hence we return
feffdc
+         * mLastSerialNo below, after the call to checkRange().
feffdc
+         */
feffdc
         mLastSerialNo = mLastSerialNo.add(BigInteger.ONE);
feffdc
 
feffdc
         checkRange();
feffdc
 
feffdc
-        BigInteger retSerial = new BigInteger(mLastSerialNo.toString());
feffdc
-
feffdc
-        CMS.debug("Repository: getNextSerialNumber: returning retSerial " + retSerial);
feffdc
-        return retSerial;
feffdc
+        CMS.debug("Repository: getNextSerialNumber: returning " + mLastSerialNo);
feffdc
+        return mLastSerialNo;
feffdc
     }
feffdc
 
feffdc
     /**
feffdc
@@ -422,6 +425,14 @@ public abstract class Repository implements IRepository {
feffdc
      * If it exceeds the given range, and there is a next range, switch the range.
feffdc
      * If it exceeds the given range, and there is not a next range, throw EDBException.
feffdc
      *
feffdc
+     * Precondition: the serial number should already have been advanced.
feffdc
+     * This method will detect that and switch to the next range, including
feffdc
+     * resetting mLastSerialNo to the start of the new (now current) range.
feffdc
+     *
feffdc
+     * Postcondition: the caller should again read mLastSerialNo after
feffdc
+     * calling checkRange(), in case checkRange switched the range and the
feffdc
+     * new range is not adjacent to the current range.
feffdc
+     *
feffdc
      * @exception EDBException thrown when range switch is needed
feffdc
      *                           but next range is not allocated
feffdc
      */
feffdc
-- 
feffdc
1.8.3.1
feffdc
feffdc
feffdc
From 57edb3ee50b3ae634ee31ed643e2bb3a891b80fa Mon Sep 17 00:00:00 2001
feffdc
From: Fraser Tweedale <ftweedal@redhat.com>
feffdc
Date: Wed, 29 Aug 2018 22:22:10 +1000
feffdc
Subject: [PATCH 5/5] Add missing synchronisation for range management
feffdc
feffdc
Several methods in Repository (and CertificateRepository) need
feffdc
synchronisation on the intrisic lock.  Make these methods
feffdc
synchronised.
feffdc
feffdc
Also take the lock in UpdateNumberRange so that no serial numbers
feffdc
can be handed out in other threads between peekNextSerialNumber()
feffdc
and set(Next)?MaxSerial().  Without this synchronisation, it is
feffdc
possible that the master instance will use some of the serial
feffdc
numbers it transfers to the clone.
feffdc
feffdc
Fixes: https://pagure.io/dogtagpki/issue/3055
feffdc
(cherry picked from commit 851a0bdd79c12c627a04cfc376338c1727cd50d9)
feffdc
---
feffdc
 .../cms/servlet/csadmin/UpdateNumberRange.java     | 35 +++++++-----
feffdc
 .../cmscore/dbs/CertificateRepository.java         | 62 ++++++++++------------
feffdc
 .../src/com/netscape/cmscore/dbs/Repository.java   |  6 +--
feffdc
 3 files changed, 53 insertions(+), 50 deletions(-)
feffdc
feffdc
diff --git a/base/server/cms/src/com/netscape/cms/servlet/csadmin/UpdateNumberRange.java b/base/server/cms/src/com/netscape/cms/servlet/csadmin/UpdateNumberRange.java
feffdc
index e5b5168..c2ff7ed 100644
feffdc
--- a/base/server/cms/src/com/netscape/cms/servlet/csadmin/UpdateNumberRange.java
feffdc
+++ b/base/server/cms/src/com/netscape/cms/servlet/csadmin/UpdateNumberRange.java
feffdc
@@ -187,20 +187,27 @@ public class UpdateNumberRange extends CMSServlet {
feffdc
             BigInteger decrement = new BigInteger(decrementStr, radix);
feffdc
             beginNum = endNum.subtract(decrement).add(oneNum);
feffdc
 
feffdc
-            if (beginNum.compareTo(repo.peekNextSerialNumber()) < 0) {
feffdc
-                String nextEndNumStr = cs.getString(nextEndConfig, "");
feffdc
-                BigInteger endNum2 = new BigInteger(nextEndNumStr, radix);
feffdc
-                CMS.debug("Transferring from the end of on-deck range");
feffdc
-                String newValStr = endNum2.subtract(decrement).toString(radix);
feffdc
-                repo.setNextMaxSerial(newValStr);
feffdc
-                cs.putString(nextEndConfig, newValStr);
feffdc
-                beginNum = endNum2.subtract(decrement).add(oneNum);
feffdc
-                endNum = endNum2;
feffdc
-            } else {
feffdc
-                CMS.debug("Transferring from the end of the current range");
feffdc
-                String newValStr = beginNum.subtract(oneNum).toString(radix);
feffdc
-                repo.setMaxSerial(newValStr);
feffdc
-                cs.putString(endNumConfig, newValStr);
feffdc
+            /* We need to synchronise on repo because we peek the next
feffdc
+             * serial number, then set the max serial of the current or
feffdc
+             * next range.  If we don't synchronize, we could end up
feffdc
+             * using serial numbers that were transferred.
feffdc
+             */
feffdc
+            synchronized (repo) {
feffdc
+                if (beginNum.compareTo(repo.peekNextSerialNumber()) < 0) {
feffdc
+                    String nextEndNumStr = cs.getString(nextEndConfig, "");
feffdc
+                    BigInteger endNum2 = new BigInteger(nextEndNumStr, radix);
feffdc
+                    CMS.debug("Transferring from the end of on-deck range");
feffdc
+                    String newValStr = endNum2.subtract(decrement).toString(radix);
feffdc
+                    repo.setNextMaxSerial(newValStr);
feffdc
+                    cs.putString(nextEndConfig, newValStr);
feffdc
+                    beginNum = endNum2.subtract(decrement).add(oneNum);
feffdc
+                    endNum = endNum2;
feffdc
+                } else {
feffdc
+                    CMS.debug("Transferring from the end of the current range");
feffdc
+                    String newValStr = beginNum.subtract(oneNum).toString(radix);
feffdc
+                    repo.setMaxSerial(newValStr);
feffdc
+                    cs.putString(endNumConfig, newValStr);
feffdc
+                }
feffdc
             }
feffdc
 
feffdc
             if (beginNum == null) {
feffdc
diff --git a/base/server/cmscore/src/com/netscape/cmscore/dbs/CertificateRepository.java b/base/server/cmscore/src/com/netscape/cmscore/dbs/CertificateRepository.java
feffdc
index 367917f..94087c8 100644
feffdc
--- a/base/server/cmscore/src/com/netscape/cmscore/dbs/CertificateRepository.java
feffdc
+++ b/base/server/cmscore/src/com/netscape/cmscore/dbs/CertificateRepository.java
feffdc
@@ -251,49 +251,45 @@ public class CertificateRepository extends Repository
feffdc
         return nextSerialNumber;
feffdc
     }
feffdc
 
feffdc
-    private Object nextSerialNumberMonitor = new Object();
feffdc
-
feffdc
-    public BigInteger getNextSerialNumber() throws
feffdc
+    public synchronized BigInteger getNextSerialNumber() throws
feffdc
             EBaseException {
feffdc
 
feffdc
         BigInteger nextSerialNumber = null;
feffdc
         BigInteger randomNumber = null;
feffdc
 
feffdc
-        synchronized (nextSerialNumberMonitor) {
feffdc
-            super.initCacheIfNeeded();
feffdc
-            CMS.debug("CertificateRepository: getNextSerialNumber  mEnableRandomSerialNumbers="+mEnableRandomSerialNumbers);
feffdc
+        super.initCacheIfNeeded();
feffdc
+        CMS.debug("CertificateRepository: getNextSerialNumber  mEnableRandomSerialNumbers="+mEnableRandomSerialNumbers);
feffdc
 
feffdc
-            if (mEnableRandomSerialNumbers) {
feffdc
-                int i = 0;
feffdc
-                do {
feffdc
-                    if (i > 0) {
feffdc
-                        CMS.debug("CertificateRepository: getNextSerialNumber  regenerating serial number");
feffdc
-                    }
feffdc
-                    randomNumber = getRandomNumber();
feffdc
-                    nextSerialNumber = getRandomSerialNumber(randomNumber);
feffdc
-                    nextSerialNumber = checkSerialNumbers(randomNumber, nextSerialNumber);
feffdc
-                    i++;
feffdc
-                } while (nextSerialNumber == null && i < mMaxCollisionRecoveryRegenerations);
feffdc
-
feffdc
-                if (nextSerialNumber == null) {
feffdc
-                    CMS.debug("CertificateRepository: in getNextSerialNumber  nextSerialNumber is null");
feffdc
-                    throw new EBaseException( "nextSerialNumber is null" );
feffdc
+        if (mEnableRandomSerialNumbers) {
feffdc
+            int i = 0;
feffdc
+            do {
feffdc
+                if (i > 0) {
feffdc
+                    CMS.debug("CertificateRepository: getNextSerialNumber  regenerating serial number");
feffdc
                 }
feffdc
+                randomNumber = getRandomNumber();
feffdc
+                nextSerialNumber = getRandomSerialNumber(randomNumber);
feffdc
+                nextSerialNumber = checkSerialNumbers(randomNumber, nextSerialNumber);
feffdc
+                i++;
feffdc
+            } while (nextSerialNumber == null && i < mMaxCollisionRecoveryRegenerations);
feffdc
 
feffdc
-                if (mCounter.compareTo(BigInteger.ZERO) >= 0 &&
feffdc
-                    mMinSerialNo != null && mMaxSerialNo != null &&
feffdc
-                    nextSerialNumber != null &&
feffdc
-                    nextSerialNumber.compareTo(mMinSerialNo) >= 0 &&
feffdc
-                    nextSerialNumber.compareTo(mMaxSerialNo) <= 0) {
feffdc
-                    mCounter = mCounter.add(BigInteger.ONE);
feffdc
-                }
feffdc
-                CMS.debug("CertificateRepository: getNextSerialNumber  nextSerialNumber="+
feffdc
-                          nextSerialNumber+"  mCounter="+mCounter);
feffdc
+            if (nextSerialNumber == null) {
feffdc
+                CMS.debug("CertificateRepository: in getNextSerialNumber  nextSerialNumber is null");
feffdc
+                throw new EBaseException( "nextSerialNumber is null" );
feffdc
+            }
feffdc
 
feffdc
-                super.checkRange();
feffdc
-            } else {
feffdc
-                nextSerialNumber = super.getNextSerialNumber();
feffdc
+            if (mCounter.compareTo(BigInteger.ZERO) >= 0 &&
feffdc
+                mMinSerialNo != null && mMaxSerialNo != null &&
feffdc
+                nextSerialNumber != null &&
feffdc
+                nextSerialNumber.compareTo(mMinSerialNo) >= 0 &&
feffdc
+                nextSerialNumber.compareTo(mMaxSerialNo) <= 0) {
feffdc
+                mCounter = mCounter.add(BigInteger.ONE);
feffdc
             }
feffdc
+            CMS.debug("CertificateRepository: getNextSerialNumber  nextSerialNumber="+
feffdc
+                      nextSerialNumber+"  mCounter="+mCounter);
feffdc
+
feffdc
+            super.checkRange();
feffdc
+        } else {
feffdc
+            nextSerialNumber = super.getNextSerialNumber();
feffdc
         }
feffdc
 
feffdc
         return nextSerialNumber;
feffdc
diff --git a/base/server/cmscore/src/com/netscape/cmscore/dbs/Repository.java b/base/server/cmscore/src/com/netscape/cmscore/dbs/Repository.java
feffdc
index 9bc7e2a..c31d376 100644
feffdc
--- a/base/server/cmscore/src/com/netscape/cmscore/dbs/Repository.java
feffdc
+++ b/base/server/cmscore/src/com/netscape/cmscore/dbs/Repository.java
feffdc
@@ -185,7 +185,7 @@ public abstract class Repository implements IRepository {
feffdc
      * @param serial maximum number
feffdc
      * @exception EBaseException failed to set maximum serial number
feffdc
      */
feffdc
-    public void setMaxSerial(String serial) throws EBaseException {
feffdc
+    public synchronized void setMaxSerial(String serial) throws EBaseException {
feffdc
         BigInteger maxSerial = null;
feffdc
         CMS.debug("Repository:setMaxSerial " + serial);
feffdc
 
feffdc
@@ -211,7 +211,7 @@ public abstract class Repository implements IRepository {
feffdc
      * @param serial maximum number in next range
feffdc
      * @exception EBaseException failed to set maximum serial number in next range
feffdc
      */
feffdc
-    public void setNextMaxSerial(String serial) throws EBaseException {
feffdc
+    public synchronized void setNextMaxSerial(String serial) throws EBaseException {
feffdc
         BigInteger maxSerial = null;
feffdc
         CMS.debug("Repository:setNextMaxSerial " + serial);
feffdc
 
feffdc
@@ -346,7 +346,7 @@ public abstract class Repository implements IRepository {
feffdc
      * Returns null if the next number exceeds the current range and
feffdc
      * there is not a next range.
feffdc
      */
feffdc
-    public BigInteger peekNextSerialNumber() throws EBaseException {
feffdc
+    public synchronized BigInteger peekNextSerialNumber() throws EBaseException {
feffdc
 
feffdc
         CMS.debug("Repository:In getTheSerialNumber ");
feffdc
         if (mLastSerialNo == null)
feffdc
-- 
feffdc
1.8.3.1
feffdc