summaryrefslogtreecommitdiffstats
path: root/ipaserver
diff options
context:
space:
mode:
authorRob Crittenden <rcritten@redhat.com>2011-05-19 22:30:53 -0400
committerRob Crittenden <rcritten@redhat.com>2011-05-20 10:08:11 -0400
commit00abd47de4d3238295cbe5dc30210b913c0f07a1 (patch)
treedb292a22ba7f791f2f28595cc00b800faff34731 /ipaserver
parent7a867102c5c01c8c3c76dbf0147647f2f2f648f6 (diff)
downloadfreeipa-00abd47de4d3238295cbe5dc30210b913c0f07a1.tar.gz
freeipa-00abd47de4d3238295cbe5dc30210b913c0f07a1.tar.xz
freeipa-00abd47de4d3238295cbe5dc30210b913c0f07a1.zip
Enable 389-ds SSL host checking by defauilt
Enforce that the remote hostname matches the remote SSL server certificate when 389-ds operates as an SSL client. Also add an update file to turn this off for existing installations. This also changes the way the ldapupdater modlist is generated to be more like the framework. Single-value attributes are done as replacements and there is a list of force-replacement attributes. ticket 1069
Diffstat (limited to 'ipaserver')
-rw-r--r--ipaserver/install/dsinstance.py3
-rw-r--r--ipaserver/ipaldap.py57
2 files changed, 52 insertions, 8 deletions
diff --git a/ipaserver/install/dsinstance.py b/ipaserver/install/dsinstance.py
index 74243cfc1..229e14282 100644
--- a/ipaserver/install/dsinstance.py
+++ b/ipaserver/install/dsinstance.py
@@ -541,8 +541,7 @@ class DsInstance(service.Service):
+tls_rsa_export1024_with_des_cbc_sha")]
conn.modify_s("cn=encryption,cn=config", mod)
- mod = [(ldap.MOD_ADD, "nsslapd-security", "on"),
- (ldap.MOD_REPLACE, "nsslapd-ssl-check-hostname", "off")]
+ mod = [(ldap.MOD_ADD, "nsslapd-security", "on")]
conn.modify_s("cn=config", mod)
entry = ipaldap.Entry("cn=RSA,cn=encryption,cn=config")
diff --git a/ipaserver/ipaldap.py b/ipaserver/ipaldap.py
index 7df7cceff..cf76d6222 100644
--- a/ipaserver/ipaldap.py
+++ b/ipaserver/ipaldap.py
@@ -247,6 +247,7 @@ class IPAdmin(SimpleLDAPObject):
self.ldapi = ldapi
self.realm = realm
self.suffixes = {}
+ self.schema = None
self.__localinit()
def __lateinit(self):
@@ -497,8 +498,13 @@ class IPAdmin(SimpleLDAPObject):
def generateModList(self, old_entry, new_entry):
"""A mod list generator that computes more precise modification lists
- than the python-ldap version. This version purposely generates no
- REPLACE operations, to deal with multi-user updates more properly."""
+ than the python-ldap version. For single-value attributes always
+ use a REPLACE operation, otherwise use ADD/DEL.
+ """
+
+ # Some attributes, like those in cn=config, need to be replaced
+ # not deleted/added.
+ FORCE_REPLACE_ON_UPDATE_ATTRS = ('nsslapd-ssl-check-hostname',)
modlist = []
old_entry = ipautil.CIDict(old_entry)
@@ -523,16 +529,28 @@ class IPAdmin(SimpleLDAPObject):
adds = list(new_values.difference(old_values))
removes = list(old_values.difference(new_values))
+ if len(adds) == 0 and len(removes) == 0:
+ continue
+
+ is_single_value = self.get_single_value(key)
+ force_replace = False
+ if key in FORCE_REPLACE_ON_UPDATE_ATTRS or is_single_value:
+ force_replace = True
+
# You can't remove schema online. An add will automatically
# replace any existing schema.
if old_entry.get('dn') == 'cn=schema':
if len(adds) > 0:
modlist.append((ldap.MOD_ADD, key, adds))
else:
- if len(removes) > 0:
- modlist.append((ldap.MOD_DELETE, key, removes))
- if len(adds) > 0:
- modlist.append((ldap.MOD_ADD, key, adds))
+ if adds:
+ if force_replace:
+ modlist.append((ldap.MOD_REPLACE, key, adds))
+ else:
+ modlist.append((ldap.MOD_ADD, key, adds))
+ if removes:
+ if not force_replace:
+ modlist.append((ldap.MOD_DELETE, key, removes))
return modlist
@@ -664,6 +682,33 @@ class IPAdmin(SimpleLDAPObject):
else: break
return (done, exitCode)
+ def get_schema(self):
+ """
+ Retrieve cn=schema and convert it into a python-ldap schema
+ object.
+ """
+ if self.schema:
+ return self.schema
+ schema = self.getEntry('cn=schema', ldap.SCOPE_BASE,
+ '(objectclass=*)', ['attributetypes', 'objectclasses'])
+ schema = schema.toDict()
+ self.schema = ldap.schema.SubSchema(schema)
+ return self.schema
+
+ def get_single_value(self, attr):
+ """
+ Check the schema to see if the attribute is single-valued.
+
+ If the attribute is in the schema then returns True/False
+
+ If there is a problem loading the schema or the attribute is
+ not in the schema return None
+ """
+ if not self.schema:
+ self.get_schema()
+ obj = self.schema.get_obj(ldap.schema.AttributeType, attr)
+ return obj and obj.single_value
+
def normalizeDN(dn):
# not great, but will do until we use a newer version of python-ldap
# that has DN utilities