Fix create and user-role-add in LDAP backend

The LDAP backend while generating 'dn' for ldapadd operations
does not add the id attribute in the attributes list
While newer versions of LDAP server support this operatoin,
older ones reported error. Eg. OpenLDAP 2.3

This change set fixes that error by adding the required
attribute in the list to make it compatible with older
LDAP versions

Change-Id: I1ed3f53d325eb280e036fbbf8e83d2e645db53cd
Closes-Bug: #1340041
This commit is contained in:
Varun Mittal 2014-08-27 21:33:58 +05:30 committed by Brant Knudson
parent 641381aec5
commit abd6dce869
3 changed files with 35 additions and 5 deletions

View File

@ -536,7 +536,8 @@ class RoleApi(common_ldap.BaseLdap):
raise Exception(_("Role %s not found") % (role_id,))
attrs = [('objectClass', [self.object_class]),
(self.member_attribute, [user_dn])]
(self.member_attribute, [user_dn]),
(self.id_attr, [role_id])]
if self.use_dumb_member:
attrs[1][1].append(self.dumb_member)

View File

@ -1662,8 +1662,18 @@ class EnabledEmuMixIn(BaseLdap):
enabled_emulation_dn = '%s_enabled_emulation_dn' % self.options_name
self.enabled_emulation_dn = getattr(conf.ldap, enabled_emulation_dn)
if not self.enabled_emulation_dn:
self.enabled_emulation_dn = ('cn=enabled_%ss,%s' %
(self.options_name, self.tree_dn))
naming_attr_name = 'cn'
naming_attr_value = 'enabled_%ss' % self.options_name
sub_vals = (naming_attr_name, naming_attr_value, self.tree_dn)
self.enabled_emulation_dn = '%s=%s,%s' % sub_vals
naming_attr = (naming_attr_name, [naming_attr_value])
else:
# Extract the attribute name and value from the configured DN.
naming_dn = utf8_decode(
ldap.dn.str2dn(utf8_encode(self.enabled_emulation_dn)))
naming_rdn = naming_dn[0][0]
naming_attr = (naming_rdn[0], [naming_rdn[1]])
self.enabled_emulation_naming_attr = naming_attr
def _get_enabled(self, object_id):
dn = self._id_to_dn(object_id)
@ -1688,8 +1698,8 @@ class EnabledEmuMixIn(BaseLdap):
conn.modify_s(self.enabled_emulation_dn, modlist)
except ldap.NO_SUCH_OBJECT:
attr_list = [('objectClass', ['groupOfNames']),
('member',
[self._id_to_dn(object_id)])]
('member', [self._id_to_dn(object_id)]),
self.enabled_emulation_naming_attr]
if self.use_dumb_member:
attr_list[1][1].append(self.dumb_member)
conn.add_s(self.enabled_emulation_dn, attr_list)

View File

@ -247,6 +247,12 @@ class FakeLdap(core.LDAPHandler):
def dn(self, dn):
return core.utf8_decode(dn)
def _dn_to_id_attr(self, dn):
return core.utf8_decode(ldap.dn.str2dn(core.utf8_encode(dn))[0][0][0])
def _dn_to_id_value(self, dn):
return core.utf8_decode(ldap.dn.str2dn(core.utf8_encode(dn))[0][0][1])
def key(self, dn):
return '%s%s' % (self.__prefix, self.dn(dn))
@ -288,12 +294,25 @@ class FakeLdap(core.LDAPHandler):
if server_fail:
raise ldap.SERVER_DOWN
id_attr_in_modlist = False
id_attr = self._dn_to_id_attr(dn)
id_value = self._dn_to_id_value(dn)
# The LDAP API raises a TypeError if attr name is None.
for k, dummy_v in modlist:
if k is None:
raise TypeError('must be string, not None. modlist=%s' %
modlist)
if k == id_attr:
for val in dummy_v:
if core.utf8_decode(val) == id_value:
id_attr_in_modlist = True
if not id_attr_in_modlist:
LOG.debug('id_attribute=%(attr)s missing, attributes=%(attrs)s' %
{'attr': id_attr, 'attrs': modlist})
raise ldap.NAMING_VIOLATION
key = self.key(dn)
LOG.debug('add item: dn=%(dn)s, attrs=%(attrs)s', {
'dn': core.utf8_decode(dn), 'attrs': modlist})