emulated ldap enabled improperly handles updates

Bug #1155234 reported by Allan Feid
6
This bug affects 1 person
Affects Status Importance Assigned to Milestone
OpenStack Identity (keystone)
Fix Released
Undecided
Adam Young

Bug Description

When tenant_enabled_emulation is set to true, update operations will fail with:

TYPE_OR_VALUE_EXISTS: {'info': 'modify/add: member: value #0 already exists', 'desc': 'Type or value exists'}

This is because during EnabledEmuMixIn.update, the object is checked for an enabled value. When it is true, the _add_enabled method is called. This does no checking, and assumes you want to add a new member attribute to your LDAP object. Since this is an update operation, it's possible the member attribute for that object already exists. A simple solution is something like:

diff --git a/keystone/common/ldap/core.py b/keystone/common/ldap/core.py
index a8b4fda..2ec675e 100644
--- a/keystone/common/ldap/core.py
+++ b/keystone/common/ldap/core.py
@@ -496,19 +496,21 @@ class EnabledEmuMixIn(BaseLdap):
             return bool(enabled_value)

     def _add_enabled(self, object_id):
- conn = self.get_connection()
- modlist = [(ldap.MOD_ADD,
- 'member',
- [self._id_to_dn(object_id)])]
- try:
- conn.modify_s(self.enabled_emulation_dn, modlist)
- except ldap.NO_SUCH_OBJECT:
- attr_list = [('objectClass', ['groupOfNames']),
- ('member',
- [self._id_to_dn(object_id)])]
- if self.use_dumb_member:
- attr_list[1][1].append(self.dumb_member)
- conn.add_s(self.enabled_emulation_dn, attr_list)
+ enabled_value = self._get_enabled(object_id)
+ if not enabled_value:
+ conn = self.get_connection()
+ modlist = [(ldap.MOD_ADD,
+ 'member',
+ [self._id_to_dn(object_id)])]
+ try:
+ conn.modify_s(self.enabled_emulation_dn, modlist)
+ except ldap.NO_SUCH_OBJECT:
+ attr_list = [('objectClass', ['groupOfNames']),
+ ('member',
+ [self._id_to_dn(object_id)])]
+ if self.use_dumb_member:
+ attr_list[1][1].append(self.dumb_member)
+ conn.add_s(self.enabled_emulation_dn, attr_list)

     def _remove_enabled(self, object_id):
         conn = self.get_connection()

This way modify operation is attempted if the object already exists.

Revision history for this message
Allan Feid (crayz) wrote :

The paste above doesn't seem to have worked with spacing

Revision history for this message
OpenStack Infra (hudson-openstack) wrote : Fix proposed to keystone (master)

Fix proposed to branch: master
Review: https://review.openstack.org/24555

Changed in keystone:
assignee: nobody → Allan Feid (crayz)
status: New → In Progress
Changed in keystone:
assignee: Allan Feid (crayz) → Adam Young (ayoung)
Revision history for this message
OpenStack Infra (hudson-openstack) wrote : Fix merged to keystone (master)

Reviewed: https://review.openstack.org/24555
Committed: http://github.com/openstack/keystone/commit/3353996454b34bf84bcaa6b7a88797f56b913873
Submitter: Jenkins
Branch: master

commit 3353996454b34bf84bcaa6b7a88797f56b913873
Author: Allan Feid <email address hidden>
Date: Fri Mar 15 15:58:26 2013 -0400

    Properly handle emulated ldap enablement

    Prior to this patch, a member attribute will attempt to be added to the enabled
    project even if it already exists. This fails to pass since in LDAP you cannot
    have two of the same member attributes in an object.

    Change-Id: Ic2373b01eb9921fbf5e9ad828628119288821dba
    Fixes: bug #1155234

Changed in keystone:
status: In Progress → Fix Committed
Thierry Carrez (ttx)
Changed in keystone:
milestone: none → grizzly-rc1
status: Fix Committed → Fix Released
Thierry Carrez (ttx)
Changed in keystone:
milestone: grizzly-rc1 → 2013.1
To post a comment you must log in.
This report contains Public information  
Everyone can see this information.

Other bug subscribers

Remote bug watches

Bug watches keep track of this bug in other bug trackers.