Skip to content

Commit

Permalink
Ticket 50933 - Update 2307compat.ldif
Browse files Browse the repository at this point in the history
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 <william@blackhats.net.au>

Review by: tbordaz (Thanks!)
  • Loading branch information
Firstyear committed Aug 5, 2020
1 parent b1e4f5f commit 79d5f2c
Show file tree
Hide file tree
Showing 3 changed files with 200 additions and 79 deletions.
174 changes: 174 additions & 0 deletions dirsrvtests/tests/suites/replication/rfc2307compat.py
@@ -0,0 +1,174 @@
# --- BEGIN COPYRIGHT BLOCK ---
# Copyright (C) 2020 Red Hat, Inc.
# Copyright (C) 2020 William Brown <william@blackhats.net.au>
# 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)
66 changes: 0 additions & 66 deletions ldap/schema/10rfc2307compat.ldif
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
39 changes: 26 additions & 13 deletions ldap/schema/60autofs.ldif
Expand Up @@ -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
Expand All @@ -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'
)
#
Expand Down

0 comments on commit 79d5f2c

Please sign in to comment.