diff options
author | Fraser Tweedale <ftweedal@redhat.com> | 2015-11-30 14:04:08 +1100 |
---|---|---|
committer | Fraser Tweedale <ftweedal@redhat.com> | 2016-01-19 10:48:57 +1100 |
commit | 81af68d3e3b1a89f799693e7f7ecda59f57abfe4 (patch) | |
tree | 87b5e8c56e74d77f6403de27e7a431070372254f /base/server/cmscore/src/com/netscape/cmscore/base | |
parent | 2bd89f148b4b347fc80285ec521d2af0299da746 (diff) | |
download | pki-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.java | 57 |
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); } } |