Skip to content
Commits on Source (53)
......@@ -31,14 +31,18 @@ stamp-h1
.settings
.cache
*.a
*.rsa
*.dirstamp
*.la
*.lo
*.o
*.rso
*.pyc
*.rej
__pycache__
.libs
.deps
Cargo.lock
rpmbuild
rpm/389-ds-base.spec
Makefile
......@@ -216,3 +220,7 @@ wrappers/ds_systemd_ask_password_acl
docs/slapi.doxy
man/man3/
html/
.pytest_cache/
src/lib389/dist/
src/lib389/man/
src/libsds/target/
......@@ -327,6 +327,7 @@ serverincdir = $(includedir)/@serverincdir@
gdbautoloaddir = $(prefixdir)/share/gdb/auto-load$(sbindir)
cockpitdir = $(prefixdir)/share/cockpit@cockpitdir@
metainfodir = $(prefixdir)/share/metainfo/389-console
tmpfiles_d = @tmpfiles_d@
# This has to be hardcoded to /lib - $libdir changes between lib/lib64, but
# sysctl.d is always in /lib.
......@@ -523,7 +524,6 @@ dist_noinst_HEADERS = \
ldap/servers/slapd/getopt_ext.h \
ldap/servers/slapd/getsocketpeer.h \
ldap/servers/slapd/http.h \
ldap/servers/slapd/index_subsys.h \
ldap/servers/slapd/intrinsics.h \
ldap/servers/slapd/log.h \
ldap/servers/slapd/mozldap.h \
......@@ -550,7 +550,6 @@ dist_noinst_HEADERS = \
ldap/servers/slapd/back-ldbm/attrcrypt.h \
ldap/servers/slapd/back-ldbm/back-ldbm.h \
ldap/servers/slapd/back-ldbm/dblayer.h \
ldap/servers/slapd/back-ldbm/idlapi.h \
ldap/servers/slapd/back-ldbm/import.h \
ldap/servers/slapd/back-ldbm/ldbm_config.h \
ldap/servers/slapd/back-ldbm/perfctrs.h \
......@@ -1337,7 +1336,6 @@ libslapd_la_SOURCES = ldap/servers/slapd/add.c \
ldap/servers/slapd/filterentry.c \
ldap/servers/slapd/generation.c \
ldap/servers/slapd/getfilelist.c \
ldap/servers/slapd/index_subsystem.c \
ldap/servers/slapd/ldaputil.c \
ldap/servers/slapd/lenstr.c \
ldap/servers/slapd/libglobs.c \
......@@ -2293,7 +2291,7 @@ fixupcmd = sed \
-e 's,@with_fhs_opt\@,@with_fhs_opt@,g' \
-e 's,@with_selinux\@,@with_selinux@,g' \
-e 's,@with_systemd\@,$(WITH_SYSTEMD),g' \
-e 's,@with_tmpfiles_d\@,@with_tmpfiles_d@,g' \
-e 's,@tmpfiles_d\@,$(tmpfiles_d),g' \
-e 's,@perlexec\@,@perlexec@,g' \
-e 's,@pythonexec\@,@pythonexec@,g' \
-e 's,@sttyexec\@,@sttyexec@,g' \
......
......@@ -10,7 +10,7 @@ vendor="389 Project"
# PACKAGE_VERSION is constructed from these
VERSION_MAJOR=1
VERSION_MINOR=4
VERSION_MAINT=0.20
VERSION_MAINT=0.21
# NOTE: VERSION_PREREL is automatically set for builds made out of a git tree
VERSION_PREREL=
VERSION_DATE=$(date -u +%Y%m%d)
......
......@@ -501,25 +501,6 @@ schemadir=/$PACKAGE_NAME/schema
defaultuser=dirsrv
defaultgroup=dirsrv
if test -z "$with_tmpfiles_d" ; then
if test -d $sysconfdir/tmpfiles.d ; then
with_tmpfiles_d='$(sysconfdir)/tmpfiles.d'
fi
fi
AC_MSG_CHECKING(for --with-tmpfiles-d)
AC_ARG_WITH(tmpfiles-d,
AS_HELP_STRING([--with-tmpfiles-d=PATH],
[system uses tmpfiles.d to handle temp files/dirs (default: $with_tmpfiles_d)])
)
if test "$with_tmpfiles_d" = yes ; then
AC_MSG_ERROR([You must specify --with-tmpfiles-d=/full/path/to/tmpfiles.d directory])
elif test "$with_tmpfiles_d" = no ; then
with_tmpfiles_d=
else
AC_MSG_RESULT([$with_tmpfiles_d])
fi
AC_SUBST(with_tmpfiles_d)
AC_MSG_CHECKING(for --with-perldir)
AC_ARG_WITH([perldir],
AS_HELP_STRING([--with-perldir=PATH],
......
......@@ -20,7 +20,9 @@ if [ "$1" = configure ]; then
chown -R dirsrv:dirsrv /etc/dirsrv/ /var/log/dirsrv/ /var/lib/dirsrv/ > $OUT || true
chmod 750 /etc/dirsrv/ /var/log/dirsrv/ /var/lib/dirsrv/ > $OUT || true
if [ -n "$2" ]; then
# needed only for upgrades from old versions, in newer ones updates are
# handled by ns-slapd itself
if dpkg --compare-versions "$2" lt "1.4.0.9"; then
for inst in $INSTANCES; do
service dirsrv@$inst stop > $OUT 2>&1
done
......
389-ds-base (1.4.0.21-1) UNRELEASED; urgency=medium
* New upstream release.
* Run offline upgrade only when upgrading from versions below 1.4.0.9,
ns-slapd itself handles upgrades in newer versions.
* rules: Actually install the minified javascript files. (Closes:
#913820)
-- Timo Aaltonen <tjaalton@debian.org> Sun, 10 Feb 2019 12:22:29 +0200
389-ds-base (1.4.0.20-3) unstable; urgency=medium
* control: 389-ds-base should depend on the legacy tools for now.
......
......@@ -9,14 +9,7 @@ ifneq (,$(filter $(DEB_HOST_ARCH), armel m68k mips mipsel powerpc powerpcspe sh4
endif
# Keep track of files we don't install
NOT_INSTALLED := \
usr/share/cockpit/389-console/static/bootstrap.min.js \
usr/share/cockpit/389-console/static/c3.min.js \
usr/share/cockpit/389-console/static/d3.min.js \
usr/share/cockpit/389-console/static/jquery.dataTables.min.js \
usr/share/cockpit/389-console/static/jquery.dataTables.select.min.js \
usr/share/cockpit/389-console/static/jstree.min.js \
usr/share/cockpit/389-console/static/moment.min.js
NOT_INSTALLED :=
REALFILE = \
bin/cl-dump.pl \
......
import logging
import pytest
import os
from lib389.utils import ds_is_older
from lib389._constants import *
from lib389.plugins import AutoMembershipPlugin, AutoMembershipDefinitions
from lib389.idm.user import UserAccounts
from lib389.idm.group import Groups
from lib389.topologies import topology_st as topo
# Skip on older versions
pytestmark = pytest.mark.skipif(ds_is_older('1.4.0'), reason="Not implemented")
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.fixture(scope="module")
def automember_fixture(topo, request):
# Create group
groups = []
group_obj = Groups(topo.standalone, DEFAULT_SUFFIX)
groups.append(group_obj.create(properties={'cn': 'testgroup'}))
groups.append(group_obj.create(properties={'cn': 'testgroup2'}))
groups.append(group_obj.create(properties={'cn': 'testgroup3'}))
# Create test user
user_accts = UserAccounts(topo.standalone, DEFAULT_SUFFIX)
user = user_accts.create_test_user()
# Create automember definitions and regex rules
automember_prop = {
'cn': 'testgroup_definition',
'autoMemberScope': DEFAULT_SUFFIX,
'autoMemberFilter': 'objectclass=posixaccount',
'autoMemberDefaultGroup': groups[0].dn,
'autoMemberGroupingAttr': 'member:dn',
}
automembers = AutoMembershipDefinitions(topo.standalone)
auto_def = automembers.create(properties=automember_prop)
auto_def.add_regex_rule("regex1", groups[1].dn, include_regex=['cn=mark.*'])
auto_def.add_regex_rule("regex2", groups[2].dn, include_regex=['cn=simon.*'])
# Enable plugin
automemberplugin = AutoMembershipPlugin(topo.standalone)
automemberplugin.enable()
topo.standalone.restart()
return (user, groups)
def test_mods(automember_fixture, topo):
"""Modify the user so that it is added to the various automember groups
:id: 28a2b070-7f16-4905-8831-c80fa6441693
:setup: Standalone Instance
:steps:
1. Update user that should add it to group[0]
2. Update user that should add it to group[1]
3. Update user that should add it to group[2]
4. Update user that should add it to group[0]
5. Test rebuild task correctly moves user to group[1]
:expectedresults:
1. Success
2. Success
3. Success
4. Success
5. Success
"""
(user, groups) = automember_fixture
# Update user which should go into group[0]
user.replace('cn', 'whatever')
groups[0].is_member(user.dn)
if groups[1].is_member(user.dn):
assert False
if groups[2].is_member(user.dn):
assert False
# Update user0 which should go into group[1]
user.replace('cn', 'mark')
groups[1].is_member(user.dn)
if groups[0].is_member(user.dn):
assert False
if groups[2].is_member(user.dn):
assert False
# Update user which should go into group[2]
user.replace('cn', 'simon')
groups[2].is_member(user.dn)
if groups[0].is_member(user.dn):
assert False
if groups[1].is_member(user.dn):
assert False
# Update user which should go back into group[0] (full circle)
user.replace('cn', 'whatever')
groups[0].is_member(user.dn)
if groups[1].is_member(user.dn):
assert False
if groups[2].is_member(user.dn):
assert False
#
# Test rebuild task. First disable plugin
#
automemberplugin = AutoMembershipPlugin(topo.standalone)
automemberplugin.disable()
topo.standalone.restart()
# Make change that would move the entry from group[0] to group[1]
user.replace('cn', 'mark')
# Enable plugin
automemberplugin.enable()
topo.standalone.restart()
# Run rebuild task
task = automemberplugin.fixup(DEFAULT_SUFFIX, "objectclass=posixaccount")
task.wait()
# Test membership
groups[1].is_member(user.dn)
if groups[0].is_member(user.dn):
assert False
if groups[2].is_member(user.dn):
assert False
# Success
log.info("Test PASSED")
if __name__ == '__main__':
# Run isolated
# -s for DEBUG mode
CURRENT_FILE = os.path.realpath(__file__)
pytest.main(["-s", CURRENT_FILE])
......@@ -798,7 +798,9 @@ def test_basic_ldapagent(topology_st, import_example_ldif):
log.info('test_basic_ldapagent: PASSED')
def test_basic_dse(topology_st, import_example_ldif):
@pytest.mark.skipif(not get_user_is_ds_owner(),
reason="process ownership permission is required")
def test_basic_dse_survives_kill9(topology_st, import_example_ldif):
"""Tests that the dse.ldif is not wiped out after the process is killed (bug 910581)
:id: 10f141da-9b22-443a-885c-87271dcd7a59
......@@ -819,7 +821,9 @@ def test_basic_dse(topology_st, import_example_ldif):
dse_file = topology_st.standalone.confdir + '/dse.ldif'
pid = check_output(['pidof', '-s', 'ns-slapd']).strip()
check_output(['sudo', 'kill', '-9', ensure_str(pid)])
# We can't guarantee we have access to sudo in any environment ... Either
# run py.test with sudo, or as the same user as the dirsrv.
check_output(['kill', '-9', ensure_str(pid)])
if os.path.getsize(dse_file) == 0:
log.fatal('test_basic_dse: dse.ldif\'s content was incorrectly removed!')
assert False
......@@ -1139,6 +1143,56 @@ def test_ticketldbm_audit(topology_st):
assert audit_pattern_found(inst, regex)
def test_dscreate(request):
"""Test that dscreate works, we need this for now until setup-ds.pl is
fully discontinued.
:id: 5bf75c47-a283-430e-a65c-3c5fd8dbadb9
:setup: None
:steps:
1. Create template file for dscreate
2. Create instance using template file
:expectedresults:
1. Should succeeds
2. Should succeeds
"""
template_file = "dssetup.inf"
template_text = """[general]
config_version = 2
full_machine_name = localhost.localdomain
[slapd]
instance_name = test_dscreate
root_dn = cn=directory manager
root_password = someLongPassword_123
[backend-userroot]
suffix = dc=example,dc=com
sample_entries = yes
"""
with open(template_file, "w") as template_fd:
template_fd.write(template_text)
cmd = 'dscreate from-file ' + template_file
try:
subprocess.check_output(cmd, shell=True, stderr=subprocess.STDOUT)
except subprocess.CalledProcessError as e:
log.fatal("dscreate failed! Error ({}) {}".format(e.returncode, e.output))
assert False
def fin():
os.remove(template_file)
try:
subprocess.check_output('dsctl test_dscreate remove --do-it', shell=True)
except subprocess.CalledProcessError as e:
log.fatal("Failed to remove test instance Error ({}) {}".format(e.returncode, e.output))
request.addfinalizer(fin)
if __name__ == '__main__':
# Run isolated
# -s for DEBUG mode
......
......@@ -8,12 +8,69 @@
#
import logging
import pytest
from lib389.utils import *
from lib389.dseldif import DSEldif
from lib389.config import LDBMConfig
from lib389.backend import Backends
from lib389.topologies import topology_st as topo
logging.getLogger(__name__).setLevel(logging.INFO)
log = logging.getLogger(__name__)
CUSTOM_MEM = '9100100100'
# Function to return value of available memory in kb
def get_available_memory():
with open('/proc/meminfo') as file:
for line in file:
if 'MemAvailable' in line:
free_mem_in_kb = line.split()[1]
return int(free_mem_in_kb)
@pytest.mark.skipif(get_available_memory() < (int(CUSTOM_MEM)/1024), reason="available memory is too low")
@pytest.mark.bz1627512
@pytest.mark.ds49618
def test_set_cachememsize_to_custom_value(topo):
"""Test if value nsslapd-cachememsize remains set
at the custom setting of value above 3805132804 bytes
after changing the value to 9100100100 bytes
:id: 8a3efc00-65a9-4ee7-b8ee-e35840991ea9
:setup: Standalone Instance
:steps:
1. Disable in the cn=config,cn=ldbm database,cn=plugins,cn=config:
nsslapd-cache-autosize by setting it to 0
2. Disable in the cn=config,cn=ldbm database,cn=plugins,cn=config:
nsslapd-cache-autosize-split by setting it to 0
3. Restart the instance
4. Set in the cn=UserRoot,cn=ldbm database,cn=plugins,cn=config:
nsslapd-cachememsize: CUSTOM_MEM
:expectedresults:
1. nsslapd-cache-autosize is successfully disabled
2. nsslapd-cache-autosize-split is successfully disabled
3. The instance should be successfully restarted
4. nsslapd-cachememsize is successfully set
"""
config_ldbm = LDBMConfig(topo.standalone)
backends = Backends(topo.standalone)
userroot_ldbm = backends.get("userroot")
log.info("Disabling nsslapd-cache-autosize by setting it to 0")
assert config_ldbm.set('nsslapd-cache-autosize', '0')
log.info("Disabling nsslapd-cache-autosize-split by setting it to 0")
assert config_ldbm.set('nsslapd-cache-autosize-split', '0')
log.info("Restarting instance")
topo.standalone.restart()
log.info("Instance restarted successfully")
log.info("Set nsslapd-cachememsize to value {}".format(CUSTOM_MEM))
assert userroot_ldbm.set('nsslapd-cachememsize', CUSTOM_MEM)
def test_maxbersize_repl(topo):
"""Check that instance starts when nsslapd-errorlog-maxlogsize
......@@ -52,3 +109,4 @@ def test_maxbersize_repl(topo):
inst.start()
log.info("Assert no init_dse_file errors in the error log")
assert not inst.ds_error_log.match('.*ERR - init_dse_file.*')
# --- BEGIN COPYRIGHT BLOCK ---
# Copyright (C) 2018 Red Hat, Inc.
# All rights reserved.
#
# License: GPL (version 3 or any later version).
# See LICENSE for details.
# --- END COPYRIGHT BLOCK ----
import os, shutil, time, pytest, re, pwd, grp
from lib389.tasks import *
from lib389.utils import *
from lib389.topologies import topology_m4 as topo_m4
from lib389.replica import *
from lib389.idm.user import UserAccounts
from lib389.agreement import *
@pytest.fixture(scope="function")
def _cleanupentris(request, topo_m4):
users = UserAccounts(topo_m4.ms["master1"], DEFAULT_SUFFIX)
for i in range(10): users.create_test_user(uid=i)
def fin():
try:
for i in users.list():
i.delete()
except: pass
request.addfinalizer(fin)
def test_verify_trees(topo_m4):
"""
All 4 masters should have consistent data
:id: 01733ef8-e764-11e8-98f3-8c16451d917b
:setup: 4 Instances with replication
:steps:
1. All 4 masters should have consistent data now
:expected results:
1. Should success
"""
# all 4 masters should have consistent data now
repl = ReplicationManager(DEFAULT_SUFFIX)
repl.test_replication(
topo_m4.ms["master1"], topo_m4.ms["master2"], 30
)
repl.test_replication(
topo_m4.ms["master1"], topo_m4.ms["master3"], 30
)
repl.test_replication(
topo_m4.ms["master1"], topo_m4.ms["master4"], 30
)
def test_sync_through_to_all_4_masters(topo_m4, _cleanupentris):
"""
Insert fresh data into Master 2 - about 10 entries
:id: 10917e04-e764-11e8-8367-8c16451d917b
:setup: 4 Instances with replication
:steps:
1. Insert fresh data into M2 - about 100 entries
2. Begin verification process
:expected results:
1. Should success
2. Should success
"""
# Insert fresh data into M2 - about 100 entries
# Wait for a minute for data to sync through to all 4 masters
# Begin verification process
repl = ReplicationManager(DEFAULT_SUFFIX)
repl.test_replication(
topo_m4.ms["master1"], topo_m4.ms["master2"], 30
)
repl.test_replication(
topo_m4.ms["master1"], topo_m4.ms["master3"], 30
)
repl.test_replication(
topo_m4.ms["master1"], topo_m4.ms["master4"], 30
)
def test_modify_some_data_in_m3(topo_m4):
"""
Modify some data in Master 3 , check trees on all 4 masters
:id: 33583ff4-e764-11e8-8491-8c16451d917b
:setup: 4 Instances with replication
:steps:
1. Modify some data in M3 , wait for 20 seconds ,check trees on all 4 masters
:expected results:
1. Should success
"""
# modify some data in M3
# wait for 20 seconds
# check trees on all 4 masters
users = UserAccounts(topo_m4.ms["master3"], DEFAULT_SUFFIX)
repl = ReplicationManager(DEFAULT_SUFFIX)
for i in range(15, 20):
users.create_test_user(uid=i)
time.sleep(1)
for i in range(15, 20):users.list()[19-i].set("description", "description for user{} CHANGED".format(i))
repl.test_replication(
topo_m4.ms["master3"], topo_m4.ms["master1"], 30
)
repl.test_replication(
topo_m4.ms["master3"], topo_m4.ms["master2"], 30
)
repl.test_replication(
topo_m4.ms["master3"], topo_m4.ms["master4"], 30
)
for i in users.list():
i.delete()
def test_delete_a_few_entries_in_m4(topo_m4, _cleanupentris):
"""
Delete a few entries in Master 4 , verify trees.
:id: 6ea94d78-e764-11e8-987f-8c16451d917b
:setup: 4 Instances with replication
:steps:
1. Delete a few entries in M4 ,
2. Wait for 60 seconds for them to propagate,
3. Verify trees
:expected results:
1. Should success
2. Should success
3. Should success
"""
# delete a few entries in M4
# wait for 60 seconds for them to propagate
# verify trees
users = UserAccounts(topo_m4.ms["master1"], DEFAULT_SUFFIX)
repl = ReplicationManager(DEFAULT_SUFFIX)
repl.wait_for_replication(topo_m4.ms["master4"], topo_m4.ms["master1"])
for i in users.list():
i.delete()
repl.test_replication(
topo_m4.ms["master4"], topo_m4.ms["master1"], 30
)
repl.test_replication(
topo_m4.ms["master4"], topo_m4.ms["master2"], 30
)
repl.test_replication(
topo_m4.ms["master4"], topo_m4.ms["master3"], 30
)
def test_replicated_multivalued_entries(topo_m4):
"""
Replicated multivalued entries are ordered the same way on all consumers
:id: 7bf9a34c-e764-11e8-928c-8c16451d917b
:setup: 4 Instances with replication
:steps:
1. Replicated multivalued entries are ordered the same way on all consumers
:expected results:
1. Should success
"""
# This test case checks that replicated multivalued entries are
# ordered the same way on all consumers
users = UserAccounts(topo_m4.ms["master1"], DEFAULT_SUFFIX)
repl = ReplicationManager(DEFAULT_SUFFIX)
user_properties = {
"uid": "test_replicated_multivalued_entries",
"cn": "test_replicated_multivalued_entries",
"sn": "test_replicated_multivalued_entries",
"userpassword": "test_replicated_multivalued_entries",
"uidNumber": "1001",
"gidNumber": "2002",
"homeDirectory": "/home/{}".format("test_replicated_multivalued_entries"),
}
users.create(properties=user_properties)
testuser = users.get("test_replicated_multivalued_entries")
testuser.set("mail", ["test1", "test2", "test3"])
# Now we check the entry on each consumer, making sure the order of the
# multi-valued mail attribute is the same on all server instances
repl.wait_for_replication(topo_m4.ms["master4"], topo_m4.ms["master1"])
assert topo_m4.ms["master1"].search_s("uid=test_replicated_multivalued_entries,ou=People,dc=example,dc=com",
ldap.SCOPE_SUBTREE, '(objectclass=*)', ['mail']) == topo_m4.ms[
"master2"].search_s("uid=test_replicated_multivalued_entries,ou=People,dc=example,dc=com",
ldap.SCOPE_SUBTREE, '(objectclass=*)', ['mail']) == topo_m4.ms["master3"].search_s(
"uid=test_replicated_multivalued_entries,ou=People,dc=example,dc=com", ldap.SCOPE_SUBTREE, '(objectclass=*)',
['mail']) == topo_m4.ms["master4"].search_s(
"uid=test_replicated_multivalued_entries,ou=People,dc=example,dc=com", ldap.SCOPE_SUBTREE, '(objectclass=*)',
['mail'])
@pytest.mark.bz157377
def test_bad_replication_agreement(topo_m4):
"""
Create the bad replication agreement and try to add it
:id: 9cf3daf4-e764-11e8-a132-8c16451d917b
:setup: 4 Instances with replication
:steps:
1. Create the bad replication agreement and try to add it
:expected results:
1. Should not success
"""
# The return code for adding a bad replication agreement to the directory server is now
# correct. Check that the return code is zero ( unsuccessful ). What used to happen is
# the directory server would not give the correct non-zero return code, add the bad replication
# agreement and then core dump.
# Stop the server and backup the dse.ldif so it can be restored later
for inst in topo_m4: inst.stop()
for i in range(1, 5):
if os.path.exists(
topo_m4.ms["master{}".format(i)].confdir
+ "/dse_test_bug157377.ldif"
):
os.remove(
topo_m4.ms["master{}".format(i)].confdir
+ "/dse_test_bug157377.ldif"
)
shutil.copy(
topo_m4.ms["master{}".format(i)].confdir + "/dse.ldif",
topo_m4.ms["master{}".format(i)].confdir
+ "/dse_test_bug157377.ldif",
)
os.chown('{}/dse_test_bug157377.ldif'.format(topo_m4.all_insts.get('master{}'.format(i)).confdir),
pwd.getpwnam('dirsrv').pw_uid, grp.getgrnam('dirsrv').gr_gid)
for i in ["master1", "master2", "master3", "master4"]:
topo_m4.all_insts.get(i).start()
# Create the bad replication agreement and try to add it
# Its a agreement as Missing replica host and port information makes for a bad agreement.
properties = {
"basedn": "cn=Ze_bad_agreeemnt,cn=replica,cn=dc\=example\,dc\=com,cn=mapping tree,cn=config",
"objectclass": ["top", "nsds5replicationagreement"],
"cn": "Ze_bad_agreement",
"nsds5replicabinddn": "{},{}".format("cn=replication manager", "o=fr"),
"nsds5replicabindmethod": "SIMPLE",
"nsds5replicaroot": DEFAULT_SUFFIX,
"description": "Ze_bad_agreement",
"nsds5replicacredentials": "Secret123",
}
for i in ["master1", "master2", "master3", "master4"]:
with pytest.raises(ldap.UNWILLING_TO_PERFORM):
Agreement(topo_m4.all_insts.get("{}".format(i))).create(
properties=properties
)
for inst in topo_m4: inst.stop()
# Now retore the original dse.ldif
for i in range(1, 5):
shutil.copy(
topo_m4.ms["master{}".format(i)].confdir
+ "/dse_test_bug157377.ldif",
topo_m4.ms["master{}".format(i)].confdir + "/dse.ldif",
)
os.chown('{}/dse_test_bug157377.ldif'.format(topo_m4.all_insts.get('master{}'.format(i)).confdir),
pwd.getpwnam('dirsrv').pw_uid, grp.getgrnam('dirsrv').gr_gid)
for inst in topo_m4: inst.start()
@pytest.mark.bz834074
def test_nsds5replicaenabled_verify(topo_m4):
"""
Add the attribute nsds5ReplicaEnabled to cn=config
:id: ba6dd634-e764-11e8-b158-8c16451d917b
:setup: 4 Instances with replication
:steps:
1. Add the attribute nsds5ReplicaEnabled to cn=config
2. Add data
3. Delete data
4. Very the replication
:expected results:
1. Should success
2. Should success
3. Should success
4. Should success
"""
# Add the attribute nsds5ReplicaEnabled to cn=config
# Stop M3 and M4 instances, as not required for this test
repl = ReplicationManager(DEFAULT_SUFFIX)
for i in ["master3", "master4"]:
topo_m4.all_insts.get(i).stop()
# Adding nsds5ReplicaEnabled to M1
topo_m4.ms["master1"].modify_s(
topo_m4.ms["master1"].agreement.list(suffix=DEFAULT_SUFFIX)[0].dn,
[(ldap.MOD_ADD, "nsds5ReplicaEnabled", b"on")],
)
topo_m4.ms["master1"].modify_s(
topo_m4.ms["master1"].agreement.list(suffix=DEFAULT_SUFFIX)[0].dn,
[(ldap.MOD_REPLACE, "nsds5ReplicaEnabled", b"off")],
)
# Adding data to Master1
users = UserAccounts(topo_m4.ms["master1"], DEFAULT_SUFFIX)
user_properties = {
"uid": "test_bug834074",
"cn": "test_bug834074",
"sn": "test_bug834074",
"userpassword": "test_bug834074",
"uidNumber": "1000",
"gidNumber": "2000",
"homeDirectory": "/home/{}".format("test_bug834074"),
}
users.create(properties=user_properties)
test_user_very = users.get("test_bug834074").dn
# No replication no data in Master2
with pytest.raises(Exception):
repl.wait_for_replication(topo_m4.ms["master1"], topo_m4.ms["master2"])
# Replication on
topo_m4.ms["master1"].modify_s(
topo_m4.ms["master1"].agreement.list(suffix=DEFAULT_SUFFIX)[0].dn,
[(ldap.MOD_REPLACE, "nsds5ReplicaEnabled", b"on")],
)
repl.wait_for_replication(topo_m4.ms["master1"], topo_m4.ms["master2"])
# Now data is available on master2
assert len(topo_m4.ms['master2'].search_s(test_user_very, ldap.SCOPE_SUBTREE, 'objectclass=*')) == 1
## Stop replication to master2
topo_m4.ms["master1"].modify_s(
topo_m4.ms["master1"].agreement.list(suffix=DEFAULT_SUFFIX)[0].dn,
[(ldap.MOD_REPLACE, "nsds5ReplicaEnabled", b"off")],
)
# Modify some data in master1
topo_m4.ms["master1"].modrdn_s(test_user_very, 'uid=test_bug834075', 1)
with pytest.raises(Exception):
repl.wait_for_replication(topo_m4.ms["master1"], topo_m4.ms["master2"])
# changes are not replicated in master2
with pytest.raises(Exception): topo_m4.ms['master2'].search_s(
'uid=test_bug834075,ou=People,{}'.format(DEFAULT_SUFFIX), ldap.SCOPE_SUBTREE, 'objectclass=*')
# Turn on the replication
topo_m4.ms["master1"].modify_s(
topo_m4.ms["master1"].agreement.list(suffix=DEFAULT_SUFFIX)[0].dn,
[(ldap.MOD_REPLACE, "nsds5ReplicaEnabled", b"on")],
)
repl.wait_for_replication(topo_m4.ms["master1"], topo_m4.ms["master2"])
# Now same data is available in master2
assert len(
topo_m4.ms['master2'].search_s('uid=test_bug834075,ou=People,{}'.format(DEFAULT_SUFFIX), ldap.SCOPE_SUBTREE,
'objectclass=*')) == 1
# Turn off the replication from master1 to master2
topo_m4.ms["master1"].modify_s(
topo_m4.ms["master1"].agreement.list(suffix=DEFAULT_SUFFIX)[0].dn,
[(ldap.MOD_REPLACE, "nsds5ReplicaEnabled", b"off")],
)
# delete some data in master1
topo_m4.ms["master1"].delete_s(
'uid=test_bug834075,ou=People,{}'.format(DEFAULT_SUFFIX)
)
with pytest.raises(Exception):
repl.wait_for_replication(topo_m4.ms["master1"], topo_m4.ms["master2"])
# deleted data from master1 is still there in master2 as repliaction is off
assert len(
topo_m4.ms['master2'].search_s('uid=test_bug834075,ou=People,{}'.format(DEFAULT_SUFFIX), ldap.SCOPE_SUBTREE,
'objectclass=*')) == 1
topo_m4.ms["master1"].modify_s(
topo_m4.ms["master1"].agreement.list(suffix=DEFAULT_SUFFIX)[0].dn,
[(ldap.MOD_REPLACE, "nsds5ReplicaEnabled", b"on")],
)
repl.wait_for_replication(topo_m4.ms["master1"], topo_m4.ms["master2"])
# After repliction is on same is gone from master2 also.
with pytest.raises(ldap.NO_SUCH_OBJECT):
topo_m4.ms['master2'].search_s('uid=test_bug834075,ou=People,{}'.format(DEFAULT_SUFFIX), ldap.SCOPE_SUBTREE,
'objectclass=*')
with pytest.raises(ldap.OPERATIONS_ERROR):
topo_m4.ms["master1"].modify_s(
topo_m4.ms["master1"]
.agreement.list(suffix=DEFAULT_SUFFIX)[0]
.dn,
[(ldap.MOD_REPLACE, "nsds5ReplicaEnabled", b"invalid")],
)
for i in ["master3", "master4"]:
topo_m4.all_insts.get(i).start()
@pytest.mark.bz830344
def test_create_an_entry_on_the_supplier(topo_m4):
"""
Shut down one instance and create an entry on the supplier
:id: f57538d0-e764-11e8-94fc-8c16451d917b
:setup: standalone
:steps:
1. Shut down one instance and create an entry on the supplier
:expected results:
1. Should not success
"""
# Bug 830344: Shut down one instance and create an entry on the supplier
topo_m4.ms["master1"].stop()
users = UserAccounts(topo_m4.ms["master2"], DEFAULT_SUFFIX)
users.create_test_user(uid=4)
# ldapsearch output
assert \
topo_m4.ms["master2"].search_s('cn=replica,cn="dc=example,dc=com",cn=mapping tree,cn=config', ldap.SCOPE_SUBTREE,
"(objectclass=*)", ["nsds5replicaLastUpdateStatus"], )[1].getValue(
'nsds5replicalastupdatestatus')
topo_m4.ms["master1"].start()
@pytest.mark.bz923502
def test_bob_acceptance_tests(topo_m4):
"""
Run multiple modrdn_s operation on master1
:id: 26eb87f2-e765-11e8-9698-8c16451d917b
:setup: standalone
:steps:
1. Add entry
2. Run multiple modrdn_s operation on master1
3. Check everything is fine.
:expected results:
1. Should success
2. Should success
3. Should success
"""
# Bug description: run BOB acceptance tests...but it may be not systematic
# Testing bug #923502: Crash in MODRDN
users = UserAccounts(topo_m4.ms["master1"], DEFAULT_SUFFIX)
repl = ReplicationManager(DEFAULT_SUFFIX)
users.create_test_user()
users.create_test_user(uid=2)
for _ in range(100):
topo_m4.ms["master1"].modrdn_s("uid=test_user_1000,ou=People,{}".format(DEFAULT_SUFFIX), "uid=userB", 1)
topo_m4.ms["master1"].modrdn_s("uid=userB,ou=People,{}".format(DEFAULT_SUFFIX), "uid=test_user_1000", 1)
repl.wait_for_replication(topo_m4.ms["master1"], topo_m4.ms["master2"])
for i in range(100):
topo_m4.ms["master2"].modrdn_s("uid=test_user_2,ou=People,{}".format(DEFAULT_SUFFIX), "uid=userB", 1)
topo_m4.ms["master2"].modrdn_s("uid=userB,ou=People,{}".format(DEFAULT_SUFFIX), "uid=test_user_2", 1)
assert topo_m4.ms["master1"].status() == True
assert topo_m4.ms["master2"].status() == True
@pytest.mark.bz830335
def test_replica_backup_and_restore(topo_m4):
"""
Test Backup and restore
:id: 5ad1b85c-e765-11e8-9668-8c16451d917b
:setup: standalone
:steps:
1. Add entries
2. Take backup db2ldif on master1
3. Delete entries on master1
4. Restore entries ldif2db
5. Check entries
:expected results:
1. Should success
2. Should success
3. Should success
4. Should success
5. Should success
"""
# Testing bug #830335: Taking a replica backup and Restore on M1 after deleting few entries from M1 nad M2
repl = ReplicationManager(DEFAULT_SUFFIX)
users = UserAccounts(topo_m4.ms["master3"], DEFAULT_SUFFIX)
for i in range(20, 25):
users.create_test_user(uid=i)
time.sleep(1)
repl.wait_for_replication(topo_m4.ms["master1"], topo_m4.ms["master2"])
repl.test_replication(topo_m4.ms["master1"], topo_m4.ms["master2"], 30)
topo_m4.ms["master1"].stop()
topo_m4.ms["master1"].db2ldif(
bename=DEFAULT_BENAME,
suffixes=[DEFAULT_SUFFIX],
excludeSuffixes=[],
encrypt=False,
repl_data=True,
outputfile="/tmp/output_file",
)
topo_m4.ms["master1"].start()
for i in users.list(): topo_m4.ms["master1"].delete_s(i.dn)
repl.wait_for_replication(topo_m4.ms["master1"], topo_m4.ms["master2"])
repl.test_replication(topo_m4.ms["master1"], topo_m4.ms["master2"], 30)
topo_m4.ms["master1"].stop()
topo_m4.ms["master1"].ldif2db(
bename=None,
excludeSuffixes=None,
encrypt=False,
suffixes=[DEFAULT_SUFFIX],
import_file="/tmp/output_file",
)
topo_m4.ms["master1"].start()
for i in range(20, 25):
users.create_test_user(uid=i)
time.sleep(1)
repl.wait_for_replication(topo_m4.ms["master1"], topo_m4.ms["master2"])
repl.test_replication(topo_m4.ms["master1"], topo_m4.ms["master2"], 30)
if __name__ == "__main__":
CURRENT_FILE = os.path.realpath(__file__)
pytest.main("-s -v %s" % CURRENT_FILE)
......@@ -12,7 +12,7 @@ from ldap.controls.ppolicy import PasswordPolicyControl
from lib389.tasks import *
from lib389.utils import *
from lib389.topologies import topology_st
from lib389.idm.user import UserAccounts
from lib389._constants import (DEFAULT_SUFFIX, DN_CONFIG, PASSWORD, DN_DM,
HOST_STANDALONE, PORT_STANDALONE, SERVERID_STANDALONE)
from dateutil.parser import parse as dt_parse
......@@ -20,7 +20,7 @@ import datetime
CONFIG_ATTR = 'passwordSendExpiringTime'
USER_DN = 'uid=tuser,{}'.format(DEFAULT_SUFFIX)
USER_PASSWD = b'secret123'
USER_PASSWD = 'secret123'
logging.getLogger(__name__).setLevel(logging.INFO)
log = logging.getLogger(__name__)
......@@ -537,6 +537,55 @@ def test_with_local_policy(topology_st, global_policy, local_policy):
topology_st.standalone.simple_bind_s(DN_DM, PASSWORD)
@pytest.mark.bz1589144
@pytest.mark.ds50091
def test_search_shadowWarning_when_passwordWarning_is_lower(topology_st, global_policy):
"""Test if value shadowWarning is present with global password policy
when passwordWarning is set with lower value.
:id: c1e82de6-1aa3-42c3-844a-9720172158a3
:setup: Standalone Instance
:steps:
1. Bind as Directory Manager
2. Set global password policy
3. Add test user to instance.
4. Modify passwordWarning to have smaller value than 86400
5. Bind as the new user
6. Search for shadowWarning attribute
7. Rebind as Directory Manager
:expectedresults:
1. Binding should be successful
2. Setting password policy should be successful
3. Adding test user should be successful
4. Modifying passwordWarning should be successful
5. Binding should be successful
6. Attribute shadowWarning should be found
7. Binding should be successful
"""
users = UserAccounts(topology_st.standalone, DEFAULT_SUFFIX)
log.info("Bind as %s" % DN_DM)
assert topology_st.standalone.simple_bind_s(DN_DM, PASSWORD)
log.info("Creating test user")
testuser = users.create_test_user(1004)
testuser.add('objectclass', 'shadowAccount')
testuser.set('userPassword', USER_PASSWD)
log.info("Setting passwordWarning to smaller value than 86400")
assert topology_st.standalone.config.set('passwordWarning', '86399')
log.info("Bind as test user")
assert topology_st.standalone.simple_bind_s(testuser.dn, USER_PASSWD)
log.info("Check if attribute shadowWarning is present")
assert testuser.present('shadowWarning')
log.info("Rebinding as DM")
topology_st.standalone.simple_bind_s(DN_DM, PASSWORD)
if __name__ == '__main__':
# Run isolated
# -s for DEBUG mode
......
# --- BEGIN COPYRIGHT BLOCK ---
# Copyright (C) 2018 Red Hat, Inc.
# All rights reserved.
#
# License: GPL (version 3 or any later version).
# See LICENSE for details.
# --- END COPYRIGHT BLOCK ---
#
import logging
import pytest
from lib389.tasks import *
from lib389.topologies import topology_m2 as topo_m2
from lib389.utils import *
from lib389.replica import *
from lib389._constants import *
from lib389.idm.user import UserAccounts
from lib389.idm.domain import Domain
log = logging.getLogger(__name__)
@pytest.mark.DS47950
def test_nsslapd_plugin_binddn_tracking(topo_m2):
"""
Testing nsslapd-plugin-binddn-tracking does not cause issues around
access control and reconfiguring replication/repl agmt.
:id: f5ba7b64-fe04-11e8-a298-8c16451d917b
:setup: Replication with two masters.
:steps:
1. Turn on bind dn tracking
2. Add two users
3. Add an aci
4. Make modification as user
5. Setup replica and create a repl agmt
6. Modify replica
7. Modify repl agmt
:expectedresults:
1. Should Success.
2. Should Success.
3. Should Success.
4. Should Success.
5. Should Success.
6. Should Success.
7. Should Success.
"""
log.info("Testing Ticket 47950 - Testing nsslapd-plugin-binddn-tracking")
#
# Turn on bind dn tracking
#
topo_m2.ms["master1"].config.replace("nsslapd-plugin-binddn-tracking", "on")
#
# Add two users
#
users = UserAccounts(topo_m2.ms["master1"], DEFAULT_SUFFIX)
test_user_1 = users.create_test_user(uid=1)
test_user_2 = users.create_test_user(uid=2)
test_user_1.set('userPassword', 'password')
test_user_2.set('userPassword', 'password')
#
# Add an aci
#
USER1_DN = users.list()[0].dn
USER2_DN = users.list()[1].dn
acival = (
'(targetattr ="cn")(version 3.0;acl "Test bind dn tracking"'
+ ';allow (all) (userdn = "ldap:///%s");)' % USER1_DN
)
Domain(topo_m2.ms["master1"], DEFAULT_SUFFIX).add("aci", acival)
#
# Make modification as user
#
assert topo_m2.ms["master1"].simple_bind_s(USER1_DN, "password")
test_user_2.replace("cn", "new value")
#
# Setup replica and create a repl agmt
#
repl = ReplicationManager(DEFAULT_SUFFIX)
assert topo_m2.ms["master1"].simple_bind_s(DN_DM, PASSWORD)
repl.test_replication(topo_m2.ms["master1"], topo_m2.ms["master2"], 30)
repl.test_replication(topo_m2.ms["master2"], topo_m2.ms["master1"], 30)
properties = {
"cn": "test_agreement",
"nsDS5ReplicaRoot": "dc=example,dc=com",
"nsDS5ReplicaHost": "localhost.localdomain",
"nsDS5ReplicaPort": "5555",
"nsDS5ReplicaBindDN": "uid=tester",
"nsds5ReplicaCredentials": "password",
"nsDS5ReplicaTransportInfo": "LDAP",
"nsDS5ReplicaBindMethod": "SIMPLE",
}
replicas = Replicas(topo_m2.ms["master1"])
replica = replicas.get(DEFAULT_SUFFIX)
agmts = Agreements(topo_m2.ms["master1"], basedn=replica.dn)
repl_agreement = agmts.create(properties=properties)
#
# modify replica
#
replica.replace("nsDS5ReplicaId", "7")
assert replica.present("nsDS5ReplicaId", "7")
#
# modify repl agmt
#
repl_agreement.replace('nsDS5ReplicaPort', "8888")
assert repl_agreement.present('nsDS5ReplicaPort', "8888")
if __name__ == "__main__":
# Run isolated
# -s for DEBUG mode
CURRENT_FILE = os.path.realpath(__file__)
pytest.main("-s %s" % CURRENT_FILE)
# --- BEGIN COPYRIGHT BLOCK ---
# Copyright (C) 2019 Red Hat, Inc.
# All rights reserved.
#
# License: GPL (version 3 or any later version).
# See LICENSE for details.
# --- END COPYRIGHT BLOCK ---
"""
:Requirement: 389-ds-base: Basic Directory Server Operations
"""
import os
import logging
import ldap
import pytest
from lib389.idm.user import UserAccounts
from lib389.topologies import topology_m2 as topo
from lib389._constants import *
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__)
BINVALUE1 = 'thedeadbeef1'
BINVALUE2 = 'thedeadbeef2'
BINVALUE3 = 'thedeadbeef3'
USER_PROPERTIES = {
'uid': 'state1usr',
'cn': 'state1usr',
'sn': 'state1usr',
'uidNumber': '1001',
'gidNumber': '2001',
'userpassword': PASSWORD,
'homeDirectory': '/home/testuser'
}
def _check_user_oper_attrs(topo, tuser, attr_name, attr_value, oper_type, exp_values, oper_attr):
"""Check if list of operational attributes present for a given entry"""
log.info('Checking if operational attrs vucsn, adcsn and vdcsn present for: {}'.format(tuser))
entry = topo.ms["master1"].search_s(tuser.dn, ldap.SCOPE_BASE, 'objectclass=*',['nscpentrywsi'])
if oper_attr:
for line in str(entry).split('\n'):
if attr_name + ';' in line:
if not 'DELETE' in oper_type:
assert any(attr in line for attr in exp_values) and oper_attr in line
else:
assert 'deleted' in line and oper_attr in line and attr_value in line
@pytest.mark.parametrize("attr_name, attr_value, oper_type, exp_values, oper_attr",
[('description', 'Test1usr1', 'ldap.MOD_ADD', ['Test1usr1'], 'vucsn'),
('description', 'Test1usr2', 'ldap.MOD_ADD', ['Test1usr1',
'Test1usr2'], 'vucsn'),
('description', 'Test1usr3', 'ldap.MOD_ADD',
['Test1usr1', 'Test1usr2', 'Test1usr3'], 'vucsn'),
('description', 'Test1usr4', 'ldap.MOD_REPLACE', ['Test1usr4'],
'adcsn'),
('description', 'Test1usr4', 'ldap.MOD_DELETE', [], 'vdcsn')])
def test_check_desc_attr_state(topo, attr_name, attr_value, oper_type, exp_values, oper_attr):
"""Modify user's description attribute and check if description attribute is
added/modified/deleted and operational attributes vucsn, adcsn and vdcsn are present.
:id: f0830538-02cf-11e9-8be0-8c16451d917b
:setup: Replication with two masters.
:steps: 1. Add user to Master1 without description attribute.
2. Add description attribute to user.
3. Check if only one description attribute exist.
4. Check if operational attribute vucsn exist.
5. Add second description attribute to user.
6. Check if two description attributes exist.
7. Check if operational attribute vucsn exist.
8. Add third description attribute to user.
9. Check if three description attributes exist.
10. Check if operational attribute vucsn exist.
11. Replace description attribute for the user.
12. Check if only one description attribute exist.
13. Check if operational attribute adcsn exist.
14. Delete description attribute for the user.
15. Check if no description attribute exist.
16. Check if no operational attribute vdcsn exist.
:expectedresults:
1. Add user to M1 should PASS.
2. Adding description attribute should PASS
3. Only one description attribute should be present.
4. Vucsn attribute should be present.
5. Adding a new description attribute should PASS
6. Two description attribute should be present.
7. Vucsn attribute should be present.
8. Adding a new description attribute should PASS
9. Three description attribute should be present.
10. Vucsn attribute should be present.
11. Replacing new description attribute should PASS
12. Only one description attribute should be present.
13. Adcsn attribute should be present.
14. Deleting description attribute should PASS
15. No description attribute should be present.
16. Vdcsn attribute should be present.
"""
test_entry = 'state1test'
log.info('Add user: {}'.format(test_entry))
users = UserAccounts(topo.ms['master1'], DEFAULT_SUFFIX)
try:
tuser = users.get(test_entry)
except ldap.NO_SUCH_OBJECT:
USER_PROPERTIES.update(dict.fromkeys(['uid', 'cn'], test_entry))
tuser = users.create(properties=USER_PROPERTIES)
tuser.set(attr_name, attr_value, eval(oper_type))
log.info('Check if list of description attrs present for: {}'.format(test_entry))
assert sorted([i.decode() for i in tuser.get_attr_vals(attr_name)]) == sorted(exp_values)
log.info('Checking for operational attributes')
_check_user_oper_attrs(topo, tuser, attr_name, attr_value, oper_type, exp_values, oper_attr)
@pytest.mark.parametrize("attr_name, attr_value, oper_type, exp_values, oper_attr",
[('cn', 'TestCN1', 'ldap.MOD_ADD', ['TestCN1', 'TestCNusr1'], 'vucsn'),
('cn', 'TestCN2', 'ldap.MOD_ADD', ['TestCN1',
'TestCN2', 'TestCNusr1'], 'vucsn'),
('cn', 'TestnewCN3', 'ldap.MOD_REPLACE', ['TestnewCN3'], 'adcsn'),
('cn', 'TestnewCN3', 'ldap.MOD_DELETE', None, None)])
def test_check_cn_attr_state(topo, attr_name, attr_value, oper_type, exp_values, oper_attr):
"""Modify user's cn attribute and check if cn attribute is added/modified/deleted and
operational attributes vucsn, adcsn and vdcsn are present.
:id: 19614bae-02d0-11e9-a295-8c16451d917b
:setup: Replication with two masters.
:steps: 1. Add user to Master1 with cn attribute.
2. Add a new cn attribute to user.
3. Check if two cn attributes exist.
4. Check if operational attribute vucsn exist for each cn attribute.
5. Add a new cn attribute to user.
6. Check if three cn attributes exist.
7. Check if operational attribute vucsn exist for each cn attribute.
8. Replace cn attribute for the user.
9. Check if only one cn attribute exist.
10. Check if operational attribute adcsn exist.
11. Delete cn attribute from user and check if it fails.
:expectedresults:
1. Add user to M1 should PASS.
2. Adding a new cn attribute should PASS
3. Two cn attribute should be present.
4. Vucsn attribute should be present.
5. Adding a new cn attribute should PASS
6. Three cn attribute should be present.
7. Vucsn attribute should be present.
8. Replacing new cn attribute should PASS
9. Only one cn attribute should be present.
10. Operational attribute adcsn should be present.
11. Deleting cn attribute should fail with ObjectClass violation error.
"""
test_entry = 'TestCNusr1'
log.info('Add user: {}'.format(test_entry))
users = UserAccounts(topo.ms['master1'], DEFAULT_SUFFIX)
try:
tuser = users.get(test_entry)
except ldap.NO_SUCH_OBJECT:
USER_PROPERTIES.update(dict.fromkeys(['uid', 'cn'], test_entry))
tuser = users.create(properties=USER_PROPERTIES)
if 'MOD_DELETE' in oper_type:
with pytest.raises(ldap.OBJECT_CLASS_VIOLATION):
tuser.set(attr_name, attr_value, eval(oper_type))
else:
tuser.set(attr_name, attr_value, eval(oper_type))
log.info('Check if list of cn attrs present for: {}'.format(test_entry))
assert sorted([i.decode() for i in tuser.get_attr_vals(attr_name)]) == sorted(exp_values)
log.info('Checking for operational attributes')
_check_user_oper_attrs(topo, tuser, attr_name, attr_value, oper_type, exp_values, oper_attr)
@pytest.mark.parametrize("attr_name, attr_value, oper_type, exp_values, oper_attr",
[('preferredlanguage', 'Chinese', 'ldap.MOD_REPLACE', ['Chinese'],
'vucsn'),
('preferredlanguage', 'French', 'ldap.MOD_ADD', None, None),
('preferredlanguage', 'German', 'ldap.MOD_REPLACE', ['German'], 'adcsn'),
('preferredlanguage', 'German', 'ldap.MOD_DELETE', [], 'vdcsn')])
def test_check_single_value_attr_state(topo, attr_name, attr_value, oper_type,
exp_values, oper_attr):
"""Modify user's preferredlanguage attribute and check if preferredlanguage attribute is
added/modified/deleted and operational attributes vucsn, adcsn and vdcsn are present.
:id: 22fd645e-02d0-11e9-a9e4-8c16451d917b
:setup: Replication with two masters.
:steps: 1. Add user to Master1 without preferredlanguage attribute.
2. Add a new preferredlanguage attribute to user.
3. Check if one preferredlanguage attributes exist.
4. Check if operational attribute vucsn exist.
5. Add a new preferredlanguage attribute for the user and check if its rejected.
6. Replace preferredlanguage attribute for the user.
7. Check if only one preferredlanguage attribute exist.
8. Check if operational attribute adcsn exist with preferredlanguage.
:expectedresults:
1. Add user to M1 should PASS.
2. Adding a new preferredlanguage attribute should PASS
3. Only one preferredlanguage attribute should be present.
4. Vucsn attribute should be present.
5. Adding a new preferredlanguage should fail with ObjectClass violation error.
6. Replace preferredlanguage should PASS.
7. Only one preferredlanguage attribute should be present.
8. Operational attribute adcsn should be present with preferredlanguage.
"""
test_entry = 'Langusr1'
log.info('Add user: {}'.format(test_entry))
users = UserAccounts(topo.ms['master1'], DEFAULT_SUFFIX)
try:
tuser = users.get(test_entry)
except ldap.NO_SUCH_OBJECT:
USER_PROPERTIES.update(dict.fromkeys(['uid', 'cn'], test_entry))
tuser = users.create(properties=USER_PROPERTIES)
if 'MOD_ADD' in oper_type:
with pytest.raises(ldap.OBJECT_CLASS_VIOLATION):
tuser.set(attr_name, attr_value, eval(oper_type))
else:
tuser.set(attr_name, attr_value, eval(oper_type))
log.info('Check if list of cn attrs present for: {}'.format(test_entry))
assert sorted([i.decode() for i in tuser.get_attr_vals(attr_name)]) == sorted(exp_values)
log.info('Checking for operational attributes')
_check_user_oper_attrs(topo, tuser, attr_name, attr_value, oper_type, exp_values, oper_attr)
@pytest.mark.parametrize("attr_name, attr_value, oper_type, exp_values, oper_attr",
[('roomnumber;office', 'Tower1', 'ldap.MOD_ADD', ['Tower1'], 'vucsn'),
('roomnumber;office', 'Tower2', 'ldap.MOD_ADD', ['Tower1', 'Tower2'],
'vucsn'),
('roomnumber;office', 'Tower3', 'ldap.MOD_ADD', ['Tower1', 'Tower2',
'Tower3'], 'vucsn'),
('roomnumber;office', 'Tower4', 'ldap.MOD_REPLACE', ['Tower4'], 'adcsn'),
('roomnumber;office', 'Tower4', 'ldap.MOD_DELETE', [], 'vucsn')])
def test_check_subtype_attr_state(topo, attr_name, attr_value, oper_type, exp_values, oper_attr):
"""Modify user's roomnumber;office attribute subtype and check if roomnumber;office attribute
is added/modified/deleted and operational attributes vucsn, adcsn and vdcsn are present.
:id: 29ab87a4-02d0-11e9-b104-8c16451d917b
:setup: Replication with two masters.
:steps: 1. Add user to Master1 without roomnumber;office attribute.
2. Add roomnumber;office attribute to user.
3. Check if only one roomnumber;office attribute exist.
4. Check if operational attribute vucsn exist.
5. Add second roomnumber;office attribute to user.
6. Check if two roomnumber;office attributes exist.
7. Check if operational attribute vucsn exist.
8. Add third roomnumber;office attribute to user.
9. Check if three roomnumber;office attributes exist.
10. Check if operational attribute vucsn exist.
11. Replace roomnumber;office attribute for the user.
12. Check if only one roomnumber;office attribute exist.
13. Check if operational attribute adcsn exist.
14. Delete roomnumber;office attribute for the user.
15. Check if no roomnumber;office attribute exist.
16. Check if no operational attribute vdcsn exist.
:expectedresults:
1. Add user to M1 should PASS.
2. Adding roomnumber;office attribute should PASS
3. Only one roomnumber;office attribute should be present.
4. Vucsn attribute should be present.
5. Adding a new roomnumber;office attribute should PASS
6. Two roomnumber;office attribute should be present.
7. Vucsn attribute should be present.
8. Adding a new roomnumber;office attribute should PASS
9. Three roomnumber;office attribute should be present.
10. Vucsn attribute should be present.
11. Replacing new roomnumber;office attribute should PASS
12. Only one roomnumber;office attribute should be present.
13. Adcsn attribute should be present.
14. Deleting roomnumber;office attribute should PASS
15. No roomnumber;office attribute should be present.
16. Vdcsn attribute should be present.
"""
test_entry = 'roomoffice1usr'
log.info('Add user: {}'.format(test_entry))
users = UserAccounts(topo.ms['master1'], DEFAULT_SUFFIX)
try:
tuser = users.get(test_entry)
except ldap.NO_SUCH_OBJECT:
USER_PROPERTIES.update(dict.fromkeys(['uid', 'cn'], test_entry))
tuser = users.create(properties=USER_PROPERTIES)
tuser.set(attr_name, attr_value, eval(oper_type))
log.info('Check if list of roomnumber;office attributes are present for a given entry')
assert sorted([i.decode() for i in tuser.get_attr_vals(attr_name)]) == sorted(exp_values)
log.info('Checking if operational attributes are present for cn')
_check_user_oper_attrs(topo, tuser, attr_name, attr_value, oper_type, exp_values, oper_attr)
@pytest.mark.parametrize("attr_name, attr_value, oper_type, exp_values, oper_attr",
[('jpegphoto', BINVALUE1, 'ldap.MOD_ADD', [BINVALUE1], 'vucsn'),
('jpegphoto', BINVALUE2, 'ldap.MOD_ADD', [BINVALUE1, BINVALUE2],
'vucsn'),
('jpegphoto', BINVALUE3, 'ldap.MOD_ADD', [BINVALUE1, BINVALUE2,
BINVALUE3], 'vucsn'),
('jpegphoto', BINVALUE2, 'ldap.MOD_REPLACE', [BINVALUE2], 'adcsn'),
('jpegphoto', BINVALUE2, 'ldap.MOD_DELETE', [], 'vdcsn')])
def test_check_jpeg_attr_state(topo, attr_name, attr_value, oper_type, exp_values, oper_attr):
"""Modify user's jpegphoto attribute and check if jpegphoto attribute is added/modified/deleted
and operational attributes vucsn, adcsn and vdcsn are present.
:id: 312ac0d0-02d0-11e9-9d34-8c16451d917b
:setup: Replication with two masters.
:steps: 1. Add user to Master1 without jpegphoto attribute.
2. Add jpegphoto attribute to user.
3. Check if only one jpegphoto attribute exist.
4. Check if operational attribute vucsn exist.
5. Add second jpegphoto attribute to user.
6. Check if two jpegphoto attributes exist.
7. Check if operational attribute vucsn exist.
8. Add third jpegphoto attribute to user.
9. Check if three jpegphoto attributes exist.
10. Check if operational attribute vucsn exist.
11. Replace jpegphoto attribute for the user.
12. Check if only one jpegphoto attribute exist.
13. Check if operational attribute adcsn exist.
14. Delete jpegphoto attribute for the user.
15. Check if no jpegphoto attribute exist.
16. Check if no operational attribute vdcsn exist.
:expectedresults:
1. Add user to M1 should PASS.
2. Adding jpegphoto attribute should PASS
3. Only one jpegphoto attribute should be present.
4. Vucsn attribute should be present.
5. Adding a new jpegphoto attribute should PASS
6. Two jpegphoto attribute should be present.
7. Vucsn attribute should be present.
8. Adding a new jpegphoto attribute should PASS
9. Three jpegphoto attribute should be present.
10. Vucsn attribute should be present.
11. Replacing new jpegphoto attribute should PASS
12. Only one jpegphoto attribute should be present.
13. Adcsn attribute should be present.
14. Deleting jpegphoto attribute should PASS
15. No jpegphoto attribute should be present.
16. Vdcsn attribute should be present.
"""
test_entry = 'testJpeg1usr'
log.info('Add user: {}'.format(test_entry))
users = UserAccounts(topo.ms['master1'], DEFAULT_SUFFIX)
try:
tuser = users.get(test_entry)
except ldap.NO_SUCH_OBJECT:
USER_PROPERTIES.update(dict.fromkeys(['uid', 'cn'], test_entry))
tuser = users.create(properties=USER_PROPERTIES)
tuser.set(attr_name, attr_value, eval(oper_type))
log.info('Check if list of jpeg attributes are present for a given entry')
assert sorted([i.decode() for i in tuser.get_attr_vals(attr_name)]) == sorted(exp_values)
log.info('Checking if operational attributes are present for cn')
_check_user_oper_attrs(topo, tuser, attr_name, attr_value, oper_type, exp_values, oper_attr)
if __name__ == "__main__":
# Run isolated
# -s for DEBUG mode
CURRENT_FILE = os.path.realpath(__file__)
pytest.main("-s -v %s" % CURRENT_FILE)
\ No newline at end of file