summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--install/updates/10-config.update5
-rw-r--r--install/updates/Makefile.am1
-rw-r--r--ipaserver/install/dsinstance.py3
-rw-r--r--ipaserver/ipaldap.py57
4 files changed, 58 insertions, 8 deletions
diff --git a/install/updates/10-config.update b/install/updates/10-config.update
new file mode 100644
index 000000000..ed7033950
--- /dev/null
+++ b/install/updates/10-config.update
@@ -0,0 +1,5 @@
+# Enforce matching SSL certificate host names when 389-ds acts as an SSL
+# client. A restart is necessary for this to take effect, we do one when
+# upgrading.
+dn: cn=config
+only:nsslapd-ssl-check-hostname: on
diff --git a/install/updates/Makefile.am b/install/updates/Makefile.am
index 5765bf17d..c9d1584b8 100644
--- a/install/updates/Makefile.am
+++ b/install/updates/Makefile.am
@@ -5,6 +5,7 @@ app_DATA = \
10-60basev2.update \
10-RFC2307bis.update \
10-RFC4876.update \
+ 10-config.update \
20-aci.update \
20-dna.update \
20-indices.update \
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