summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJan Cholasta <jcholast@redhat.com>2013-01-31 11:56:00 +0100
committerMartin Kosek <mkosek@redhat.com>2013-03-01 16:59:46 +0100
commit8f46ca5dd20f2e69595dfb3bf9ab11d6f978dfbd (patch)
tree2a5771240b2e3f057009a98baa7fdb4dc1fb5224
parentbb36683c8480a68d54ef632daa0a4d6df9802187 (diff)
downloadfreeipa-8f46ca5dd20f2e69595dfb3bf9ab11d6f978dfbd.tar.gz
freeipa-8f46ca5dd20f2e69595dfb3bf9ab11d6f978dfbd.tar.xz
freeipa-8f46ca5dd20f2e69595dfb3bf9ab11d6f978dfbd.zip
Preserve case of attribute names in LDAPEntry.
-rw-r--r--ipalib/plugins/baseldap.py5
-rw-r--r--ipalib/plugins/cert.py8
-rw-r--r--ipalib/plugins/pwpolicy.py6
-rw-r--r--ipaserver/ipaldap.py103
-rw-r--r--tests/test_ipaserver/test_ldap.py10
5 files changed, 97 insertions, 35 deletions
diff --git a/ipalib/plugins/baseldap.py b/ipalib/plugins/baseldap.py
index da89ad6f3..20ae1cbee 100644
--- a/ipalib/plugins/baseldap.py
+++ b/ipalib/plugins/baseldap.py
@@ -230,7 +230,10 @@ def entry_from_entry(entry, newentry):
entry[e] = newentry[e]
def entry_to_dict(entry, **options):
- result = dict(entry)
+ if options.get('raw', False):
+ result = dict(entry)
+ else:
+ result = dict((k.lower(), v) for (k, v) in entry.iteritems())
if options.get('all', False):
result['dn'] = entry.dn
return result
diff --git a/ipalib/plugins/cert.py b/ipalib/plugins/cert.py
index 6b84c7235..a441a92ae 100644
--- a/ipalib/plugins/cert.py
+++ b/ipalib/plugins/cert.py
@@ -346,11 +346,11 @@ class cert_request(VirtualCommand):
# going to add it
try:
if not principal.startswith('host/'):
- service = api.Command['service_show'](principal, all=True, raw=True)['result']
+ service = api.Command['service_show'](principal, all=True)['result']
dn = service['dn']
else:
hostname = get_host_from_principal(principal)
- service = api.Command['host_show'](hostname, all=True, raw=True)['result']
+ service = api.Command['host_show'](hostname, all=True)['result']
dn = service['dn']
except errors.NotFound, e:
if not add:
@@ -375,7 +375,7 @@ class cert_request(VirtualCommand):
for name in subjectaltname:
name = unicode(name)
try:
- hostentry = api.Command['host_show'](name, all=True, raw=True)['result']
+ hostentry = api.Command['host_show'](name, all=True)['result']
hostdn = hostentry['dn']
except errors.NotFound:
# We don't want to issue any certificates referencing
@@ -385,7 +385,7 @@ class cert_request(VirtualCommand):
'subject alt name %s in certificate request') % name)
authprincipal = getattr(context, 'principal')
if authprincipal.startswith("host/"):
- if not hostdn in service.get('managedby', []):
+ if not hostdn in service.get('managedby_host', []):
raise errors.ACIError(info=_(
"Insufficient privilege to create a certificate "
"with subject alt name '%s'.") % name)
diff --git a/ipalib/plugins/pwpolicy.py b/ipalib/plugins/pwpolicy.py
index 5ae07c40d..6c8ad8dbf 100644
--- a/ipalib/plugins/pwpolicy.py
+++ b/ipalib/plugins/pwpolicy.py
@@ -305,12 +305,12 @@ class pwpolicy(LDAPObject):
existing_entry = {}
if not add: # then read existing entry
existing_entry = self.api.Command.pwpolicy_show(keys[-1],
- all=True, raw=True,
+ all=True,
)['result']
if minlife is None and 'krbminpwdlife' in existing_entry:
- minlife = int(existing_entry['krbminpwdlife'][0])
+ minlife = int(existing_entry['krbminpwdlife'][0]) * 3600
if maxlife is None and 'krbmaxpwdlife' in existing_entry:
- maxlife = int(existing_entry['krbmaxpwdlife'][0])
+ maxlife = int(existing_entry['krbmaxpwdlife'][0]) * 86400
if maxlife is not None and minlife is not None:
if minlife > maxlife:
diff --git a/ipaserver/ipaldap.py b/ipaserver/ipaldap.py
index 5904836da..ef0febabe 100644
--- a/ipaserver/ipaldap.py
+++ b/ipaserver/ipaldap.py
@@ -583,7 +583,7 @@ class IPASimpleLDAPObject(object):
# r[0] == r.dn
# r[1] == r.data
class LDAPEntry(dict):
- __slots__ = ('_dn', '_orig')
+ __slots__ = ('_dn', '_names', '_orig')
def __init__(self, _dn=None, _obj=None, **kwargs):
super(LDAPEntry, self).__init__()
@@ -604,6 +604,7 @@ class LDAPEntry(dict):
self._dn = _dn
self._orig = orig
+ self._names = CIDict()
if orig is None:
self.commit()
@@ -630,39 +631,59 @@ class LDAPEntry(dict):
# FIXME: for backwards compatibility only
return self._orig
+ def __repr__(self):
+ return '%s(%r, %s)' % (type(self).__name__, self._dn,
+ super(LDAPEntry, self).__repr__())
+
+ def copy(self):
+ return LDAPEntry(self)
+
+ def commit(self):
+ self._orig = self
+ self._orig = deepcopy(self)
+
def _attr_name(self, name):
if not isinstance(name, basestring):
raise TypeError(
"attribute name must be unicode or str, got %s object %r" % (
name.__class__.__name__, name))
+
if isinstance(name, str):
- name = name.decode('ascii')
- return name.lower()
+ name = name.decode('utf-8')
- def _init_iter(self, _obj, **kwargs):
- _obj = dict(_obj, **kwargs)
- for (k, v) in _obj.iteritems():
- yield (self._attr_name(k), v)
+ return name
- def __repr__(self):
- dict_repr = super(LDAPEntry, self).__repr__()
- return '%s(%s, %s)' % (type(self).__name__, repr(self._dn), dict_repr)
+ def __setitem__(self, name, value):
+ name = self._attr_name(name)
- def copy(self):
- return LDAPEntry(self)
+ if self._names.has_key(name):
+ oldname = self._names[name]
- def commit(self):
- self._orig = self
- self._orig = deepcopy(self)
+ if oldname != name:
+ for (altname, keyname) in self._names.iteritems():
+ if keyname == oldname:
+ self._names[altname] = name
- def __setitem__(self, name, value):
- super(LDAPEntry, self).__setitem__(self._attr_name(name), value)
+ super(LDAPEntry, self).__delitem__(oldname)
+ else:
+ self._names[name] = name
+
+ super(LDAPEntry, self).__setitem__(name, value)
def setdefault(self, name, default):
- return super(LDAPEntry, self).setdefault(self._attr_name(name), default)
+ if name not in self:
+ self[name] = default
+ return self[name]
def update(self, _obj={}, **kwargs):
- super(LDAPEntry, self).update(self._init_iter(_obj, **kwargs))
+ _obj = dict(_obj, **kwargs)
+ for (name, value) in _obj.iteritems():
+ self[name] = value
+
+ def _get_attr_name(self, name):
+ name = self._attr_name(name)
+ name = self._names[name]
+ return name
def __getitem__(self, name):
# for python-ldap tuple compatibility
@@ -671,10 +692,15 @@ class LDAPEntry(dict):
elif name == 1:
return self
- return super(LDAPEntry, self).__getitem__(self._attr_name(name))
+ return super(LDAPEntry, self).__getitem__(self._get_attr_name(name))
def get(self, name, default=None):
- return super(LDAPEntry, self).get(self._attr_name(name), default)
+ try:
+ name = self._get_attr_name(name)
+ except KeyError:
+ return default
+
+ return super(LDAPEntry, self).get(name, default)
def single_value(self, name, default=_missing):
"""Return a single attribute value
@@ -685,7 +711,8 @@ class LDAPEntry(dict):
If the entry is missing and default is not given, raise KeyError.
"""
try:
- values = super(LDAPEntry, self).__getitem__(self._attr_name(name))
+ attr_name = self._get_attr_name(name)
+ values = super(LDAPEntry, self).__getitem__(attr_name)
except KeyError:
if default is _missing:
raise
@@ -697,17 +724,41 @@ class LDAPEntry(dict):
'%s has %s values, one expected' % (name, len(values)))
return values[0]
+ def _del_attr_name(self, name):
+ name = self._get_attr_name(name)
+
+ for (altname, keyname) in self._names.items():
+ if keyname == name:
+ del self._names[altname]
+
+ return name
+
def __delitem__(self, name):
- super(LDAPEntry, self).__delitem__(self._attr_name(name))
+ super(LDAPEntry, self).__delitem__(self._del_attr_name(name))
def pop(self, name, *default):
- return super(LDAPEntry, self).pop(self._attr_name(name), *default)
+ try:
+ name = self._del_attr_name(name)
+ except KeyError:
+ if not default:
+ raise
+
+ return super(LDAPEntry, self).pop(name, *default)
+
+ def popitem(self):
+ name, value = super(LDAPEntry, self).popitem()
+ self._del_attr_name(name)
+ return (name, value)
+
+ def clear(self):
+ super(LDAPEntry, self).clear()
+ self._names.clear()
def __contains__(self, name):
- return super(LDAPEntry, self).__contains__(self._attr_name(name))
+ return self._names.has_key(self._attr_name(name))
def has_key(self, name):
- return super(LDAPEntry, self).has_key(self._attr_name(name))
+ return name in self
# for python-ldap tuple compatibility
def __iter__(self):
diff --git a/tests/test_ipaserver/test_ldap.py b/tests/test_ipaserver/test_ldap.py
index 06d5d4ecc..df777c848 100644
--- a/tests/test_ipaserver/test_ldap.py
+++ b/tests/test_ipaserver/test_ldap.py
@@ -158,18 +158,26 @@ class test_ldap(object):
e = LDAPEntry(dn1, cn=cn1)
assert e.dn is dn1
+ assert u'cn' in e
+ assert u'cn' in e.keys()
assert 'CN' in e
+ assert 'CN' not in e.keys()
assert e['CN'] is cn1
assert e['CN'] is e[u'cn']
e.dn = dn2
assert e.dn is dn2
- e['cn'] = cn2
+ e['CN'] = cn2
+ assert u'cn' in e
+ assert u'cn' not in e.keys()
assert 'CN' in e
+ assert 'CN' in e.keys()
assert e['CN'] is cn2
assert e['CN'] is e[u'cn']
del e['CN']
assert 'CN' not in e
+ assert 'CN' not in e.keys()
assert u'cn' not in e
+ assert u'cn' not in e.keys()