|
|
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 |
|