Переглянути джерело

Ticket 50933 - Update 2307compat.ldif

Bug Description: This resolves a potential conflict between 60nis.ldif
in freeipa and others with 2307compat, by removing the conflicting
definitions from 2307bis that were included.

Fix Description: By not including these in 2307compat, this means that
sites that rely on the values provided by 2307bis may ALSO need
60nis.ldif to be present. However, these nis values seem like they are
likely very rare in reality, and this also will avoid potential
issues with freeipa. It also is the least disruptive as we don't need
to change an already defined file, and we don't have values where the name
to oid relationship changes.

Fixes: #50933
https://pagure.io/389-ds-base/issue/50933

Author: William Brown <[email protected]>

Review by: tbordaz (Thanks!)
William Brown 5 роки тому
батько
коміт
79d5f2cf36

+ 174 - 0
dirsrvtests/tests/suites/replication/rfc2307compat.py

@@ -0,0 +1,174 @@
+# --- BEGIN COPYRIGHT BLOCK ---
+# Copyright (C) 2020 Red Hat, Inc.
+# Copyright (C) 2020 William Brown <[email protected]>
+# All rights reserved.
+#
+# License: GPL (version 3 or any later version).
+# See LICENSE for details.
+# --- END COPYRIGHT BLOCK ---
+#
+import pytest
+from lib389.replica import Replicas
+from lib389.tasks import *
+from lib389.utils import *
+from lib389.topologies import topology_m2 as topo_m2
+from . import get_repl_entries
+from lib389.idm.user import UserAccount
+from lib389.replica import ReplicationManager
+from lib389._constants import *
+
+pytestmark = pytest.mark.tier0
+
+TEST_ENTRY_NAME = 'mmrepl_test'
+TEST_ENTRY_DN = 'uid={},{}'.format(TEST_ENTRY_NAME, DEFAULT_SUFFIX)
+NEW_SUFFIX_NAME = 'test_repl'
+NEW_SUFFIX = 'o={}'.format(NEW_SUFFIX_NAME)
+NEW_BACKEND = 'repl_base'
+
+DEBUGGING = os.getenv("DEBUGGING", default=False)
+if DEBUGGING:
+    logging.getLogger(__name__).setLevel(logging.DEBUG)
+else:
+    logging.getLogger(__name__).setLevel(logging.INFO)
+log = logging.getLogger(__name__)
+
+pytest.mark.skipif(not os.environ.get('UNSAFE_ACK', False), reason="UNSAFE tests may damage system configuration.")
+def test_rfc2307compat(topo_m2):
+    """ Test to verify if 10rfc2307compat.ldif does not prevent replication of schema
+        - Create 2 masters and a test entry
+        - Move 10rfc2307compat.ldif to be private to M1
+        - Move 10rfc2307.ldif to be private to M2
+        - Add 'objectCategory' to the schema of M1
+        - Force a replication session
+        - Check 'objectCategory' on M1 and M2
+    """
+    m1 = topo_m2.ms["master1"]
+    m2 = topo_m2.ms["master2"]
+
+    m1.config.loglevel(vals=(ErrorLog.DEFAULT, ErrorLog.REPLICA))
+    m2.config.loglevel(vals=(ErrorLog.DEFAULT, ErrorLog.REPLICA))
+
+    m1.add_s(Entry((
+        TEST_ENTRY_DN, {
+            "objectClass": "top",
+            "objectClass": "extensibleObject",
+            'uid': TEST_ENTRY_NAME,
+            'cn': TEST_ENTRY_NAME,
+            'sn': TEST_ENTRY_NAME,
+        }
+    )))
+
+    entries = get_repl_entries(topo_m2, TEST_ENTRY_NAME, ["uid"])
+    assert all(entries), "Entry {} wasn't replicated successfully".format(TEST_ENTRY_DN)
+
+    # Clean the old locations (if any)
+    m1_temp_schema = os.path.join(m1.get_config_dir(), 'schema')
+    m2_temp_schema = os.path.join(m2.get_config_dir(), 'schema')
+    m1_schema = os.path.join(m1.get_data_dir(), 'dirsrv/schema')
+    m1_opt_schema = os.path.join(m1.get_data_dir(), 'dirsrv/data')
+    m1_temp_backup = os.path.join(m1.get_tmp_dir(), 'schema')
+
+    # Does the system schema exist?
+    if os.path.islink(m1_schema):
+        # Then we need to put the m1 schema back.
+        os.unlink(m1_schema)
+        shutil.copytree(m1_temp_backup, m1_schema)
+    if not os.path.exists(m1_temp_backup):
+        shutil.copytree(m1_schema, m1_temp_backup)
+
+    shutil.rmtree(m1_temp_schema, ignore_errors=True)
+    shutil.rmtree(m2_temp_schema, ignore_errors=True)
+
+    # Build a new copy
+    shutil.copytree(m1_schema, m1_temp_schema)
+    shutil.copytree(m1_schema, m2_temp_schema)
+    # Ensure 99user.ldif exists
+    with open(os.path.join(m1_temp_schema, '99user.ldif'), 'w') as f:
+        f.write('dn: cn=schema')
+
+    with open(os.path.join(m2_temp_schema, '99user.ldif'), 'w') as f:
+        f.write('dn: cn=schema')
+
+    # m1 has compat, m2 has legacy.
+    os.unlink(os.path.join(m2_temp_schema, '10rfc2307compat.ldif'))
+    shutil.copy(os.path.join(m1_opt_schema, '10rfc2307.ldif'), m2_temp_schema)
+
+    # Configure the instances
+    # m1.config.replace('nsslapd-schemadir', m1_temp_schema)
+    # m2.config.replace('nsslapd-schemadir', m2_temp_schema)
+
+    # Now mark the system schema as empty.
+    shutil.rmtree(m1_schema)
+    os.symlink('/var/lib/empty', m1_schema)
+
+    print("SETUP COMPLETE -->")
+
+    # Stop all instances
+    m1.stop()
+    m2.stop()
+
+    # udpate the schema on M1 to tag a schemacsn
+    m1.start()
+    objectcategory_attr = '( NAME \'objectCategory\' DESC \'test of objectCategory\' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )'
+    m1.schema.add_schema('attributetypes', [ensure_bytes(objectcategory_attr)])
+
+    # Now start M2 and trigger a replication M1->M2
+    m2.start()
+    m1.modify_s(TEST_ENTRY_DN, [(ldap.MOD_ADD, 'cn', [ensure_bytes('value_m1')])])
+
+    # Now check that objectCategory is in both schema
+    time.sleep(10)
+    ents = m1.search_s("cn=schema", ldap.SCOPE_SUBTREE, 'objectclass=*',['attributetypes'])
+    for value in ents[0].getValues('attributetypes'):
+        if ensure_bytes('objectCategory') in value:
+           log.info("M1: " + str(value))
+           break
+    assert ensure_bytes('objectCategory') in value
+
+    ents = m2.search_s("cn=schema", ldap.SCOPE_SUBTREE, 'objectclass=*',['attributetypes'])
+    for value in ents[0].getValues('attributetypes'):
+        if ensure_bytes('objectCategory') in value:
+           log.info("M2: " + str(value))
+           break
+    assert ensure_bytes('objectCategory') in value
+
+    # Stop m2
+    m2.stop()
+
+    # "Update" it's schema,
+    os.unlink(os.path.join(m2_temp_schema, '10rfc2307.ldif'))
+    shutil.copy(os.path.join(m1_temp_backup, '10rfc2307compat.ldif'), m2_temp_schema)
+
+    # Add some more to m1
+    objectcategory_attr = '( NAME \'objectCategoryX\' DESC \'test of objectCategoryX\' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 )'
+    m1.schema.add_schema('attributetypes', [ensure_bytes(objectcategory_attr)])
+
+    # Start m2.
+    m2.start()
+    m1.modify_s(TEST_ENTRY_DN, [(ldap.MOD_ADD, 'cn', [ensure_bytes('value_m2')])])
+
+    time.sleep(10)
+    ents = m1.search_s("cn=schema", ldap.SCOPE_SUBTREE, 'objectclass=*',['attributetypes'])
+    for value in ents[0].getValues('attributetypes'):
+        if ensure_bytes('objectCategoryX') in value:
+           log.info("M1: " + str(value))
+           break
+    assert ensure_bytes('objectCategoryX') in value
+
+    ents = m2.search_s("cn=schema", ldap.SCOPE_SUBTREE, 'objectclass=*',['attributetypes'])
+    for value in ents[0].getValues('attributetypes'):
+        if ensure_bytes('objectCategoryX') in value:
+           log.info("M2: " + str(value))
+           break
+    assert ensure_bytes('objectCategoryX') in value
+
+    # Success cleanup
+    os.unlink(m1_schema)
+    shutil.copytree(m1_temp_backup, m1_schema)
+
+
+if __name__ == '__main__':
+    # Run isolated
+    # -s for DEBUG mode
+    CURRENT_FILE = os.path.realpath(__file__)
+    pytest.main("-s %s" % CURRENT_FILE)

+ 0 - 66
ldap/schema/10rfc2307compat.ldif

@@ -176,50 +176,6 @@ attributeTypes: (
   SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
   SINGLE-VALUE
   )
-attributeTypes: (
-  1.3.6.1.1.1.1.28 NAME 'nisPublicKey'
-  DESC 'NIS public key'
-  EQUALITY octetStringMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.40
-  SINGLE-VALUE
-  )
-attributeTypes: (
-  1.3.6.1.1.1.1.29 NAME 'nisSecretKey'
-  DESC 'NIS secret key'
-  EQUALITY octetStringMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.40
-  SINGLE-VALUE
-  )
-attributeTypes: (
-  1.3.6.1.1.1.1.30 NAME 'nisDomain'
-  DESC 'NIS domain'
-  EQUALITY caseIgnoreIA5Match
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-  )
-attributeTypes: (
-  1.3.6.1.1.1.1.31 NAME 'automountMapName'
-  DESC 'automount Map Name'
-  EQUALITY caseExactIA5Match
-  SUBSTR caseExactIA5SubstringsMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-  SINGLE-VALUE
-  )
-attributeTypes: (
-  1.3.6.1.1.1.1.32 NAME 'automountKey'
-  DESC 'Automount Key value'
-  EQUALITY caseExactIA5Match
-  SUBSTR caseExactIA5SubstringsMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-  SINGLE-VALUE
-  )
-attributeTypes: (
-  1.3.6.1.1.1.1.33 NAME 'automountInformation'
-  DESC 'Automount information'
-  EQUALITY caseExactIA5Match
-  SUBSTR caseExactIA5SubstringsMatch
-  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
-  SINGLE-VALUE
-  )
 # end of attribute types - beginning of objectclasses
 objectClasses: (
   1.3.6.1.1.1.2.0 NAME 'posixAccount' SUP top AUXILIARY
@@ -324,28 +280,6 @@ objectClasses: (
         seeAlso $ serialNumber'
   MAY ( bootFile $ bootParameter $ cn $ description $ l $ o $ ou $ owner $ seeAlso $ serialNumber )
   )
-objectClasses: (
-  1.3.6.1.1.1.2.14 NAME 'nisKeyObject' SUP top AUXILIARY
-  DESC 'An object with a public and secret key'
-  MUST ( cn $ nisPublicKey $ nisSecretKey )
-  MAY ( uidNumber $ description )
-  )
-objectClasses: (
-  1.3.6.1.1.1.2.15 NAME 'nisDomainObject' SUP top AUXILIARY
-  DESC 'Associates a NIS domain with a naming context'
-  MUST nisDomain
-  )
-objectClasses: (
-  1.3.6.1.1.1.2.16 NAME 'automountMap' SUP top STRUCTURAL
-  MUST ( automountMapName )
-  MAY description
-  )
-objectClasses: (
-  1.3.6.1.1.1.2.17 NAME 'automount' SUP top STRUCTURAL
-  DESC 'Automount information'
-  MUST ( automountKey $ automountInformation )
-  MAY description
-  )
 ## namedObject is needed for groups without members
 objectClasses: (
   1.3.6.1.4.1.5322.13.1.1 NAME 'namedObject' SUP top STRUCTURAL

+ 26 - 13
ldap/schema/60autofs.ldif

@@ -6,7 +6,23 @@ dn: cn=schema
 ################################################################################
 #
 attributeTypes: (
-  1.3.6.1.1.1.1.33 
+  1.3.6.1.1.1.1.31 NAME 'automountMapName'
+  DESC 'automount Map Name'
+  EQUALITY caseExactIA5Match
+  SUBSTR caseExactIA5SubstringsMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+  SINGLE-VALUE
+  )
+attributeTypes: (
+  1.3.6.1.1.1.1.32 NAME 'automountKey'
+  DESC 'Automount Key value'
+  EQUALITY caseExactIA5Match
+  SUBSTR caseExactIA5SubstringsMatch
+  SYNTAX 1.3.6.1.4.1.1466.115.121.1.26
+  SINGLE-VALUE
+  )
+attributeTypes: (
+  1.3.6.1.1.1.1.33
   NAME 'automountInformation'
   DESC 'Information used by the autofs automounter'
   EQUALITY caseExactIA5Match
@@ -18,25 +34,22 @@ attributeTypes: (
 ################################################################################
 #
 objectClasses: (
-  1.3.6.1.1.1.2.17
-  NAME 'automount'
-  DESC 'An entry in an automounter map'
+  1.3.6.1.1.1.2.16
+  NAME 'automountMap'
+  DESC 'An group of related automount objects'
   SUP top
   STRUCTURAL
-  MUST ( cn $ automountInformation )
-  MAY ( description )
+  MAY ( ou $ automountMapName $ description )
   X-ORIGIN 'draft-howard-rfc2307bis'
   )
-#
-################################################################################
-#
 objectClasses: (
-  1.3.6.1.1.1.2.16
-  NAME 'automountMap'
-  DESC 'An group of related automount objects'
+  1.3.6.1.1.1.2.17
+  NAME 'automount'
+  DESC 'An entry in an automounter map'
   SUP top
   STRUCTURAL
-  MUST ( ou )
+  MUST ( automountInformation )
+  MAY ( cn $ description $ automountKey )
   X-ORIGIN 'draft-howard-rfc2307bis'
   )
 #