summaryrefslogtreecommitdiffstats
path: root/base/server/cmscore/src/com/netscape/cmscore/base
diff options
context:
space:
mode:
authorFraser Tweedale <ftweedal@redhat.com>2015-11-30 14:04:08 +1100
committerFraser Tweedale <ftweedal@redhat.com>2016-01-19 10:48:57 +1100
commit81af68d3e3b1a89f799693e7f7ecda59f57abfe4 (patch)
tree87b5e8c56e74d77f6403de27e7a431070372254f /base/server/cmscore/src/com/netscape/cmscore/base
parent2bd89f148b4b347fc80285ec521d2af0299da746 (diff)
downloadpki-81af68d3e3b1a89f799693e7f7ecda59f57abfe4.tar.gz
pki-81af68d3e3b1a89f799693e7f7ecda59f57abfe4.tar.xz
pki-81af68d3e3b1a89f799693e7f7ecda59f57abfe4.zip
Avoid profile race conditions by tracking entryUSN
Avoid race conditions in the LDAPProfileSubsystem by tracking the most recently known entryUSN of profiles' LDAP entries. As part of this change, add the commitProfile method to the IProfileSubsystem interface, remove commit behaviour from the enableProfile and disableProfile methods and update ProfileService and ProfileApproveServlet to commit the profile (using the commitProfile method) where needed. Part of: https://fedorahosted.org/pki/ticket/1700
Diffstat (limited to 'base/server/cmscore/src/com/netscape/cmscore/base')
-rw-r--r--base/server/cmscore/src/com/netscape/cmscore/base/LDAPConfigStore.java57
1 files changed, 42 insertions, 15 deletions
diff --git a/base/server/cmscore/src/com/netscape/cmscore/base/LDAPConfigStore.java b/base/server/cmscore/src/com/netscape/cmscore/base/LDAPConfigStore.java
index b7b4ca46e..0b4ff707d 100644
--- a/base/server/cmscore/src/com/netscape/cmscore/base/LDAPConfigStore.java
+++ b/base/server/cmscore/src/com/netscape/cmscore/base/LDAPConfigStore.java
@@ -26,13 +26,17 @@ import java.util.Map;
import netscape.ldap.LDAPAttribute;
import netscape.ldap.LDAPAttributeSet;
import netscape.ldap.LDAPConnection;
+import netscape.ldap.LDAPConstraints;
+import netscape.ldap.LDAPControl;
import netscape.ldap.LDAPEntry;
import netscape.ldap.LDAPException;
import netscape.ldap.LDAPModification;
-import com.netscape.certsrv.base.EBaseException;
import com.netscape.certsrv.base.IConfigStore;
+import com.netscape.certsrv.ldap.ELdapException;
import com.netscape.certsrv.ldap.ILdapConnFactory;
+import com.netscape.cmsutil.ldap.LDAPPostReadControl;
+import com.netscape.cmsutil.ldap.LDAPUtil;
/**
* LDAPConfigStore:
@@ -65,8 +69,6 @@ public class LDAPConfigStore extends PropConfigStore implements IConfigStore {
* @param attr Name of attribute containing config store
* @param createAttrs Set of initial attributes if creating the entry. Should
* contain cn, objectclass and possibly other attributes.
- *
- * @exception EBaseException failed to create file configuration
*/
public LDAPConfigStore(
ILdapConnFactory dbFactory,
@@ -102,7 +104,17 @@ public class LDAPConfigStore extends PropConfigStore implements IConfigStore {
*
* @param createBackup Ignored.
*/
- public void commit(boolean createBackup) throws EBaseException {
+ public void commit(boolean createBackup) throws ELdapException {
+ String[] attrs = {};
+ commitReturn(createBackup, attrs);
+ }
+
+ /**
+ * This version of commit also returns the post-read entry that
+ * the change resulted in.
+ */
+ public LDAPEntry commitReturn(boolean createBackup, String[] attrs)
+ throws ELdapException {
ByteArrayOutputStream data = new ByteArrayOutputStream();
save(data, null);
@@ -110,26 +122,37 @@ public class LDAPConfigStore extends PropConfigStore implements IConfigStore {
LDAPConnection conn = dbFactory.getConn();
+ LDAPConstraints cons = new LDAPConstraints();
+ cons.setServerControls(new LDAPPostReadControl(true, attrs));
+
+ LDAPControl[] responseControls;
+
// first attempt to modify; if modification fails (due
// to no such object), try and add the entry instead.
try {
try {
- commitModify(conn, configAttr);
+ commitModify(conn, configAttr, cons);
} catch (LDAPException e) {
if (e.getLDAPResultCode() == LDAPException.NO_SUCH_OBJECT) {
- commitAdd(conn, configAttr);
+ commitAdd(conn, configAttr, cons);
} else {
throw e;
}
}
+ responseControls = conn.getResponseControls();
} catch (LDAPException e) {
- throw new EBaseException(
+ throw new ELdapException(
"Error writing LDAPConfigStore '"
+ dn + "': " + e.toString()
);
} finally {
dbFactory.returnConn(conn);
}
+
+ LDAPPostReadControl control = (LDAPPostReadControl)
+ LDAPUtil.getControl(LDAPPostReadControl.class, responseControls);
+
+ return control.getEntry();
}
/**
@@ -139,12 +162,14 @@ public class LDAPConfigStore extends PropConfigStore implements IConfigStore {
* @param configAttr Config store attribute.
* @return true on success, false if the entry does not exist.
*/
- private void commitModify(LDAPConnection conn, LDAPAttribute configAttr)
- throws LDAPException
- {
+ private void commitModify(
+ LDAPConnection conn,
+ LDAPAttribute configAttr,
+ LDAPConstraints cons)
+ throws LDAPException {
LDAPModification ldapMod =
new LDAPModification(LDAPModification.REPLACE, configAttr);
- conn.modify(dn, ldapMod);
+ conn.modify(dn, ldapMod, cons);
}
/**
@@ -154,12 +179,14 @@ public class LDAPConfigStore extends PropConfigStore implements IConfigStore {
* @param configAttr Config store attribute.
* @return true on success, false if the entry already exists.
*/
- private void commitAdd(LDAPConnection conn, LDAPAttribute configAttr)
- throws LDAPException
- {
+ private void commitAdd(
+ LDAPConnection conn,
+ LDAPAttribute configAttr,
+ LDAPConstraints cons)
+ throws LDAPException {
LDAPAttributeSet attrSet = new LDAPAttributeSet(createAttrs);
attrSet.add(configAttr);
LDAPEntry ldapEntry = new LDAPEntry(dn, attrSet);
- conn.add(ldapEntry);
+ conn.add(ldapEntry, cons);
}
}