Skip to content
Commits on Source (34)
......@@ -10,7 +10,7 @@ vendor="389 Project"
# PACKAGE_VERSION is constructed from these
VERSION_MAJOR=1
VERSION_MINOR=4
VERSION_MAINT=0.19
VERSION_MAINT=0.20
# NOTE: VERSION_PREREL is automatically set for builds made out of a git tree
VERSION_PREREL=
VERSION_DATE=$(date -u +%Y%m%d)
......
usr/bin/cl-dump
usr/bin/dbgen
usr/bin/infadd
usr/bin/ldif
usr/bin/migratecred
usr/bin/mmldif
usr/bin/repl-monitor
usr/bin/rsearch
usr/lib/*/dirsrv/perl/
usr/sbin/bak2db
usr/sbin/bak2db-online
usr/sbin/cleanallruv
usr/sbin/db2bak
usr/sbin/db2bak-online
usr/sbin/db2index
usr/sbin/db2index-online
usr/sbin/db2ldif
usr/sbin/db2ldif-online
usr/sbin/dbmon.sh
usr/sbin/dn2rdn
usr/sbin/fixup-linkedattrs
usr/sbin/fixup-memberof
usr/sbin/ldif2db
usr/sbin/ldif2db-online
usr/sbin/migrate-ds
usr/sbin/monitor
usr/sbin/ns-accountstatus
usr/sbin/ns-activate
usr/sbin/ns-inactivate
usr/sbin/ns-newpwpolicy
usr/sbin/remove-ds
usr/sbin/restoreconfig
usr/sbin/saveconfig
usr/sbin/schema-reload
usr/sbin/setup-ds
usr/sbin/suffix2instance
usr/sbin/syntax-validate
usr/sbin/upgradednformat
usr/sbin/usn-tombstone-cleanup
usr/sbin/verify-db
usr/share/dirsrv/properties/*.res
usr/share/dirsrv/script-templates
usr/share/dirsrv/updates
usr/share/man/man1/cl-dump.1
usr/share/man/man1/dbgen.1
usr/share/man/man1/infadd.1
usr/share/man/man1/ldif.1
usr/share/man/man1/migratecred.1
usr/share/man/man1/mmldif.1
usr/share/man/man1/repl-monitor.1
usr/share/man/man1/rsearch.1
usr/share/man/man8/bak2db-online.8
usr/share/man/man8/bak2db.8
usr/share/man/man8/cleanallruv.8
usr/share/man/man8/db2bak-online.8
usr/share/man/man8/db2bak.8
usr/share/man/man8/db2index-online.8
usr/share/man/man8/db2index.8
usr/share/man/man8/db2ldif-online.8
usr/share/man/man8/db2ldif.8
usr/share/man/man8/dbmon.sh.8
usr/share/man/man8/dn2rdn.8
usr/share/man/man8/fixup-linkedattrs.8
usr/share/man/man8/fixup-memberof.8
usr/share/man/man8/ldif2db-online.8
usr/share/man/man8/ldif2db.8
usr/share/man/man8/migrate-ds.8
usr/share/man/man8/monitor.8
usr/share/man/man8/ns-accountstatus.8
usr/share/man/man8/ns-activate.8
usr/share/man/man8/ns-inactivate.8
usr/share/man/man8/ns-newpwpolicy.8
usr/share/man/man8/remove-ds.8
usr/share/man/man8/restoreconfig.8
usr/share/man/man8/saveconfig.8
usr/share/man/man8/schema-reload.8
usr/share/man/man8/setup-ds.8
usr/share/man/man8/suffix2instance.8
usr/share/man/man8/syntax-validate.8
usr/share/man/man8/upgradednformat.8
usr/share/man/man8/usn-tombstone-cleanup.8
usr/share/man/man8/verify-db.8
......@@ -6,57 +6,50 @@ etc/systemd/
lib/systemd/system/dirsrv-snmp.service
lib/systemd/system/dirsrv.target
lib/systemd/system/dirsrv@.service
usr/bin/
usr/lib/*/dirsrv/perl/
usr/bin/dbscan
usr/bin/ds-logpipe
usr/bin/ds-replcheck
usr/bin/ldclt
usr/bin/logconv
usr/bin/pwdhash
usr/bin/readnsstate
usr/lib/*/dirsrv/plugins/*.so
usr/lib/*/dirsrv/python/
usr/lib/*/ds_selinux_enabled
usr/lib/*/ds_selinux_port_query
usr/lib/*/ds_systemd_ask_password_acl
usr/lib/sysctl.d/70-dirsrv.conf
usr/sbin/bak2db
usr/sbin/bak2db-online
usr/sbin/cleanallruv
usr/sbin/db2bak
usr/sbin/db2bak-online
usr/sbin/db2index
usr/sbin/db2index-online
usr/sbin/db2ldif
usr/sbin/db2ldif-online
usr/sbin/dbmon.sh
usr/sbin/dbverify
usr/sbin/dn2rdn
usr/sbin/fixup-linkedattrs
usr/sbin/fixup-memberof
usr/sbin/ldap-agent
usr/sbin/ldif2db
usr/sbin/ldif2db-online
usr/sbin/ldif2ldap
usr/sbin/migrate-ds
usr/sbin/monitor
usr/sbin/ns-accountstatus
usr/sbin/ns-activate
usr/sbin/ns-inactivate
usr/sbin/ns-newpwpolicy
usr/sbin/ns-slapd
usr/sbin/remove-ds
usr/sbin/restart-dirsrv
usr/sbin/restoreconfig
usr/sbin/saveconfig
usr/sbin/schema-reload
usr/sbin/setup-ds
usr/sbin/start-dirsrv
usr/sbin/status-dirsrv
usr/sbin/stop-dirsrv
usr/sbin/suffix2instance
usr/sbin/syntax-validate
usr/sbin/upgradedb
usr/sbin/upgradednformat
usr/sbin/usn-tombstone-cleanup
usr/sbin/verify-db
usr/sbin/vlvindex
usr/share/dirsrv/
usr/share/dirsrv/data
usr/share/dirsrv/inf
usr/share/dirsrv/mibs
usr/share/dirsrv/properties/ns-slapd.properties
usr/share/dirsrv/schema
usr/share/gdb/auto-load/usr/sbin/ns-slapd-gdb.py
usr/share/man/man1/*.1
usr/share/man/man1/dbscan.1
usr/share/man/man1/ds-logpipe.1
usr/share/man/man1/ds-replcheck.1
usr/share/man/man1/ldap-agent.1
usr/share/man/man1/ldclt.1
usr/share/man/man1/logconv.1
usr/share/man/man1/pwdhash.1
usr/share/man/man1/readnsstate.1
usr/share/man/man5/*.5
usr/share/man/man8/*.8
usr/share/man/man8/dbverify.8
usr/share/man/man8/ldif2ldap.8
usr/share/man/man8/ns-slapd.8
usr/share/man/man8/restart-dirsrv.8
usr/share/man/man8/start-dirsrv.8
usr/share/man/man8/status-dirsrv.8
usr/share/man/man8/stop-dirsrv.8
usr/share/man/man8/upgradedb.8
usr/share/man/man8/vlvindex.8
389-ds-base (1.4.0.20-1) experimental; urgency=medium
* New upstream release. (Closes: #913821)
* fix-nss-path.diff: Fix includes.
* Build ds* manpages, add missing build-depends.
* Move deprecated tools in a new subpackage.
* control: Add python3-lib389 to 389-ds-base depends.
-- Timo Aaltonen <tjaalton@debian.org> Sun, 13 Jan 2019 21:13:22 +0200
389-ds-base (1.4.0.19-3) unstable; urgency=medium
[ Jelmer Vernooij ]
......
......@@ -29,7 +29,13 @@ Build-Depends:
libsystemd-dev,
pkg-config,
python3-all-dev,
python3-argcomplete,
python3-argparse-manpage,
python3-ldap,
python3-selinux,
python3-sepolicy,
python3-setuptools,
python3-six,
rsync,
zlib1g-dev,
Standards-Version: 4.1.0
......@@ -103,12 +109,10 @@ Depends:
adduser,
acl,
ldap-utils,
libmozilla-ldap-perl,
libnetaddr-ip-perl,
libperl4-corelibs-perl | perl (<< 5.12.3-7),
libsasl2-modules-gssapi-mit,
libsocket-getaddrinfo-perl,
python,
python3-lib389,
python3-selinux,
python3-semanage,
python3-sepolicy,
......@@ -132,6 +136,23 @@ Description: 389 Directory Server suite - server
* on-line, zero downtime update of schema, configuration, and
in-tree Access Control Information.
Package: 389-ds-base-legacy-tools
Architecture: any
Depends:
389-ds-base (= ${binary:Version}),
libmozilla-ldap-perl,
libnetaddr-ip-perl,
libperl4-corelibs-perl | perl (<< 5.12.3-7),
libsocket-getaddrinfo-perl,
${misc:Depends},
${shlibs:Depends},
Conflicts: 389-ds-base (<< 1.4.0.20-1)
Replaces: 389-ds-base (<< 1.4.0.20-1)
Description: Legacy utilities for 389 Directory Server
Legacy (and deprecated) utilities for 389 Directory Server. This includes
the old account management and task scripts. These are deprecated in favour of
the dscreate, dsctl, dsconf and dsidm tools.
Package: python3-lib389
Architecture: all
Depends: ${misc:Depends}, ${python3:Depends},
......
--- a/Makefile.am
+++ b/Makefile.am
@@ -2374,7 +2371,7 @@ git-archive:
# How will we update this to python 3?
lib389: src/lib389/setup.py
- cd $(srcdir)/src/lib389; $(PYTHON) setup.py build ; $(PYTHON) setup.py build_manpages
+ cd $(srcdir)/src/lib389; $(PYTHON) setup.py build ; $(PYTHON) setup.py
lib389-install: lib389
cd $(srcdir)/src/lib389; $(PYTHON) setup.py install --skip-build --force
--- a/src/lib389/setup.py
+++ b/src/lib389/setup.py
@@ -14,7 +14,7 @@
from setuptools import setup, find_packages
from os import path
-from build_manpages import build_manpages
+#from build_manpages import build_manpages
from setuptools.command.build_py import build_py
from setuptools.command.install import install
@@ -66,12 +66,6 @@ setup(
'cli/dscreate',
'cli/dsidm',
]),
- ('/usr/share/man/man8', [
- 'man/dsctl.8',
- 'man/dsconf.8',
- 'man/dscreate.8',
- 'man/dsidm.8',
- ]),
],
install_requires=[
@@ -85,10 +79,4 @@ setup(
'python-ldap',
],
- cmdclass={
- # Dynamically build man pages for cli tools
- 'build_manpages': build_manpages.build_manpages,
- 'build_py': build_manpages.get_build_py_cmd(build_py),
- }
-
)
--- a/include/ldaputil/certmap.h
+++ b/include/ldaputil/certmap.h
@@ -16,7 +16,7 @@
/* What was extcmap.h begins ... */
#include <ldap.h>
-#include <nss3/cert.h>
+#include <nss/cert.h>
#ifndef NSAPI_PUBLIC
#define NSAPI_PUBLIC
--- a/lib/ldaputil/examples/init.c
+++ b/lib/ldaputil/examples/init.c
@@ -15,7 +15,7 @@
#include <stdio.h>
#include <string.h>
#include <ctype.h>
-#include <nss3/cert.h>
+#include <nss/cert.h>
#include "certmap.h" /* Public Certmap API */
#include "plugin.h" /* must define extern "C" functions */
......@@ -4,6 +4,6 @@ fix-obsolete-target.diff
fix-saslpath.diff
fix-systemctl-path.diff
CVE-2017-15135.patch
dont-build-new-manpages.diff
perl-use-move-instead-of-rename.diff
icu_pkg-config.patch
fix-nss-path.diff
......@@ -4,3 +4,7 @@ usr/sbin/dsconf
usr/sbin/dscreate
usr/sbin/dsctl
usr/sbin/dsidm
usr/share/man/man8/dsconf.8
usr/share/man/man8/dscreate.8
usr/share/man/man8/dsctl.8
usr/share/man/man8/dsidm.8
......@@ -38,12 +38,25 @@ REALFILE = \
sbin/syntax-validate.pl \
sbin/usn-tombstone-cleanup.pl \
sbin/verify-db.pl \
share/man/man1/cl-dump.pl.1 \
share/man/man1/dbgen.pl.1 \
share/man/man1/ds-logpipe.py.1 \
share/man/man1/logconv.pl.1 \
share/man/man1/repl-monitor.pl.1 \
share/man/man8/cleanallruv.pl.8 \
share/man/man8/fixup-linkedattrs.pl.8 \
share/man/man8/fixup-memberof.pl.8 \
share/man/man8/migrate-ds.pl.8 \
share/man/man8/ns-accountstatus.pl.8 \
share/man/man8/ns-activate.pl.8 \
share/man/man8/ns-inactivate.pl.8 \
share/man/man8/ns-newpwpolicy.pl.8 \
share/man/man8/setup-ds.pl.8 \
share/man/man8/remove-ds.pl.8
share/man/man8/schema-reload.pl.8 \
share/man/man8/syntax-validate.pl.8 \
share/man/man8/remove-ds.pl.8 \
share/man/man8/usn-tombstone-cleanup.pl.8 \
share/man/man8/verify-db.pl.8
# scripts for handling online servers
REALFILE_ONLINE = \
......@@ -80,7 +93,7 @@ override_dh_auto_configure:
--enable-icu
override_dh_auto_build:
python3 src/lib389/setup.py build
(cd src/lib389 && python3 setup.py build)
dh_auto_build
override_dh_auto_install:
......
......@@ -125,24 +125,48 @@ def replcheck_cmd_list(topo_tls_ldapi):
inst.start()
ds_replcheck_path = os.path.join(m1.ds_paths.bin_dir, 'ds-replcheck')
replcheck_cmd = [[ds_replcheck_path, '-b', DEFAULT_SUFFIX, '-D', DN_DM, '-w', PW_DM, '-l', '1',
'-m', 'ldap://{}:{}'.format(m1.host, m1.port), '--conflict',
replcheck_cmd = [[ds_replcheck_path, 'online', '-b', DEFAULT_SUFFIX, '-D', DN_DM, '-w', PW_DM, '-l', '1',
'-m', 'ldap://{}:{}'.format(m1.host, m1.port), '--conflicts',
'-r', 'ldap://{}:{}'.format(m2.host, m2.port)],
[ds_replcheck_path, '-b', DEFAULT_SUFFIX, '-D', DN_DM, '-w', PW_DM, '-l', '1',
'-m', 'ldaps://{}:{}'.format(m1.host, m1.sslport), '--conflict',
[ds_replcheck_path, 'online', '-b', DEFAULT_SUFFIX, '-D', DN_DM, '-w', PW_DM, '-l', '1',
'-m', 'ldaps://{}:{}'.format(m1.host, m1.sslport), '--conflicts',
'-r', 'ldaps://{}:{}'.format(m2.host, m2.sslport)],
[ds_replcheck_path, '-b', DEFAULT_SUFFIX, '-D', DN_DM, '-w', PW_DM, '-l', '1',
[ds_replcheck_path, 'online', '-b', DEFAULT_SUFFIX, '-D', DN_DM, '-w', PW_DM, '-l', '1',
'-m', 'ldap://{}:{}'.format(m1.host, m1.port), '-Z', m1.get_ssca_dir(),
'-r', 'ldap://{}:{}'.format(m2.host, m2.port), '--conflict'],
[ds_replcheck_path, '-b', DEFAULT_SUFFIX, '-D', DN_DM, '-w', PW_DM, '-l', '1',
'-r', 'ldap://{}:{}'.format(m2.host, m2.port), '--conflicts'],
[ds_replcheck_path, 'online', '-b', DEFAULT_SUFFIX, '-D', DN_DM, '-w', PW_DM, '-l', '1',
'-m', 'ldapi://%2fvar%2frun%2fslapd-{}.socket'.format(m1.serverid), '--conflict',
'-r', 'ldapi://%2fvar%2frun%2fslapd-{}.socket'.format(m2.serverid)],
[ds_replcheck_path, '-b', DEFAULT_SUFFIX, '--conflict',
'-M', '/tmp/export_{}.ldif'.format(m1.serverid),
'-R', '/tmp/export_{}.ldif'.format(m2.serverid)]]
[ds_replcheck_path, 'offline', '-b', DEFAULT_SUFFIX, '--conflicts', '--rid', '1',
'-m', '/tmp/export_{}.ldif'.format(m1.serverid),
'-r', '/tmp/export_{}.ldif'.format(m2.serverid)]]
return replcheck_cmd
def test_state(topo_tls_ldapi):
"""Check "state" report
:id: 1cc6b28b-8a42-45fb-ab50-9552db0ac178
:setup: Two master replication
:steps:
1. Get the replication state value
2. The state value is as expected
:expectedresults:
1. It should be successful
2. It should be successful
"""
m1 = topo_tls_ldapi.ms["master1"]
m2 = topo_tls_ldapi.ms["master2"]
ds_replcheck_path = os.path.join(m1.ds_paths.bin_dir, 'ds-replcheck')
tool_cmd = [ds_replcheck_path, 'state', '-b', DEFAULT_SUFFIX, '-D', DN_DM, '-w', PW_DM,
'-m', 'ldaps://{}:{}'.format(m1.host, m1.sslport),
'-r', 'ldaps://{}:{}'.format(m2.host, m2.sslport)]
result = subprocess.check_output(tool_cmd, encoding='utf-8')
assert (result.rstrip() == "Replication State: Master and Replica are in perfect synchronization")
def test_check_ruv(topo_tls_ldapi):
"""Check that the report has RUV
......
# 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 pytest
import subprocess
import re
from ldap.controls import LDAPControl
from lib389._constants import *
from lib389.tasks import *
from lib389.utils import *
from lib389.topologies import topology_st as topo
from lib389.idm.user import UserAccounts, TEST_USER_PROPERTIES
from lib389.idm.organizationalunit import OrganizationalUnits
from lib389.idm.nscontainer import nsContainers
from lib389.pwpolicy import PwPolicyManager
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__)
OLD_PASSWD = 'password'
NEW_PASSWD = 'newpassword'
SHORT_PASSWD = 'wd'
TESTPEOPLE_OU = "TestPeople_bug834047"
@pytest.fixture(scope="function")
def pwd_policy_setup(topo, request):
"""
Setup to set passwordStorageScheme as CLEAR
passwordHistory to on
passwordStorageScheme to SSHA
passwordHistory off
"""
log.info("Change the pwd storage type to clear and change the password once to refresh it(for the rest of tests")
topo.standalone.config.set('passwordStorageScheme', 'CLEAR')
assert topo.standalone.passwd_s(user_2.dn, OLD_PASSWD, NEW_PASSWD)
topo.standalone.config.set('passwordHistory', 'on')
def fin():
topo.standalone.simple_bind_s(DN_DM, PASSWORD)
topo.standalone.config.set('passwordStorageScheme', 'SSHA')
topo.standalone.config.set('passwordHistory', 'off')
request.addfinalizer(fin)
def test_pwd_modify_with_different_operation(topo):
"""Performing various password modify operation,
make sure that password is actually modified
:id: e36d68a8-0960-48e4-932c-6c2f64abaebc
:setup: Standalone instance and TLS enabled
:steps:
1. Attempt for Password change for an entry that does not exists
2. Attempt for Password change for an entry that exists
3. Attempt for Password change to old for an entry that exists
4. Attempt for Password Change with Binddn as testuser but with wrong old password
5. Attempt for Password Change with Binddn as testuser
6. Attempt for Password Change without giving newpassword
7. Checking password change Operation using a Non-Secure connection
8. Testuser attempts to change password for testuser2(userPassword attribute is Set)
9. Directory Manager attempts to change password for testuser2(userPassword attribute is Set)
10. Create a password syntax policy. Attempt to change to password that violates that policy
11. userPassword mod with control results in ber decode error
:expectedresults:
1. Operation should be successful
2. Operation should be successful
3. Operation should be successful
4. Operation should not be successful
5. Operation should be successful
6. Operation should be successful
7. Operation should not be successful
8. Operation should not be successful
9. Operation should be successful
10. Operation should violates the policy
11. Operation should be successful
"""
topo.standalone.enable_tls()
os.environ["LDAPTLS_CACERTDIR"] = topo.standalone.get_ssca_dir()
users = UserAccounts(topo.standalone, DEFAULT_SUFFIX)
TEST_USER_PROPERTIES['userpassword'] = OLD_PASSWD
global user
user = users.create(properties=TEST_USER_PROPERTIES)
with pytest.raises(ldap.NO_SUCH_OBJECT):
log.info("Attempt for Password change for an entry that does not exists")
assert topo.standalone.passwd_s('uid=testuser1,ou=People,dc=example,dc=com', OLD_PASSWD, NEW_PASSWD)
log.info("Attempt for Password change for an entry that exists")
assert topo.standalone.passwd_s(user.dn, OLD_PASSWD, NEW_PASSWD)
log.info("Attempt for Password change to old for an entry that exists")
assert topo.standalone.passwd_s(user.dn, NEW_PASSWD, OLD_PASSWD)
log.info("Attempt for Password Change with Binddn as testuser but with wrong old password")
topo.standalone.simple_bind_s(user.dn, OLD_PASSWD)
with pytest.raises(ldap.INVALID_CREDENTIALS):
topo.standalone.passwd_s(user.dn, NEW_PASSWD, NEW_PASSWD)
log.info("Attempt for Password Change with Binddn as testuser")
assert topo.standalone.passwd_s(user.dn, OLD_PASSWD, NEW_PASSWD)
log.info("Attempt for Password Change without giving newpassword")
assert topo.standalone.passwd_s(user.dn, None, OLD_PASSWD)
assert user.get_attr_val_utf8('uid') == 'testuser'
log.info("Change password to NEW_PASSWD i.e newpassword")
assert topo.standalone.passwd_s(user.dn, None, NEW_PASSWD)
assert topo.standalone.passwd_s(user.dn, NEW_PASSWD, None)
log.info("Check binding with old/new password")
password = [OLD_PASSWD, NEW_PASSWD]
for pass_val in password:
with pytest.raises(ldap.INVALID_CREDENTIALS):
topo.standalone.simple_bind_s(user.dn, pass_val)
log.info("Change password back to OLD_PASSWD i.e password")
topo.standalone.simple_bind_s(DN_DM, PASSWORD)
assert topo.standalone.passwd_s(user.dn, None, NEW_PASSWD)
log.info("Checking password change Operation using a Non-Secure connection")
conn = ldap.initialize("ldap://%s:%s" % (HOST_STANDALONE, PORT_STANDALONE))
with pytest.raises(ldap.CONFIDENTIALITY_REQUIRED):
conn.passwd_s(user.dn, NEW_PASSWD, OLD_PASSWD)
log.info("Testuser attempts to change password for testuser2(userPassword attribute is Set)")
global user_2
users = UserAccounts(topo.standalone, DEFAULT_SUFFIX)
user_2 = users.create(properties={
'uid': 'testuser2',
'cn': 'testuser2',
'sn': 'testuser2',
'uidNumber': '3000',
'gidNumber': '4000',
'homeDirectory': '/home/testuser2',
'userPassword': OLD_PASSWD
})
topo.standalone.simple_bind_s(user.dn, NEW_PASSWD)
with pytest.raises(ldap.INSUFFICIENT_ACCESS):
assert topo.standalone.passwd_s(user_2.dn, OLD_PASSWD, NEW_PASSWD)
log.info("Directory Manager attempts to change password for testuser2(userPassword attribute is Set)")
topo.standalone.simple_bind_s(DN_DM, PASSWORD)
assert topo.standalone.passwd_s(user_2.dn, OLD_PASSWD, NEW_PASSWD)
log.info("Changing userPassword attribute to Undefined for testuser2")
topo.standalone.modify_s(user_2.dn, [(ldap.MOD_REPLACE, 'userPassword', None)])
log.info("Testuser attempts to change password for testuser2(userPassword attribute is Undefined)")
with pytest.raises(ldap.INSUFFICIENT_ACCESS):
topo.standalone.simple_bind_s(user.dn, NEW_PASSWD)
assert topo.standalone.passwd_s(user_2.dn, None, NEW_PASSWD)
log.info("Directory Manager attempts to change password for testuser2(userPassword attribute is Undefined)")
topo.standalone.simple_bind_s(DN_DM, PASSWORD)
assert topo.standalone.passwd_s(user_2.dn, None, OLD_PASSWD)
log.info("Create a password syntax policy. Attempt to change to password that violates that policy")
topo.standalone.config.set('PasswordCheckSyntax', 'on')
with pytest.raises(ldap.CONSTRAINT_VIOLATION):
assert topo.standalone.passwd_s(user_2.dn, OLD_PASSWD, SHORT_PASSWD)
log.info("Reset password syntax policy")
topo.standalone.config.set('PasswordCheckSyntax', 'off')
log.info("userPassword mod with control results in ber decode error")
topo.standalone.simple_bind_s(DN_DM, PASSWORD)
assert topo.standalone.modify_ext_s(user.dn, [(ldap.MOD_REPLACE, 'userpassword', b'abcdefg')],
serverctrls=[LDAPControl('2.16.840.1.113730.3.4.2', 1, None)])
log.info("Reseting the testuser's password")
topo.standalone.passwd_s(user.dn, 'abcdefg', NEW_PASSWD)
def test_pwd_modify_with_password_policy(topo, pwd_policy_setup):
"""Performing various password modify operation,
with passwordStorageScheme as CLEAR
passwordHistory to on
:id: 200bf0fd-20ab-4dde-849e-54067e98b917
:setup: Standalone instance (TLS enabled) with pwd_policy_setup
:steps:
1. Change the password and check that a new entry has been added to the history
2. Try changing password to one stored in history
3. Change the password several times in a row, and try binding after each change
4. Try to bind using short password
:expectedresults:
1. Operation should be successful
2. Operation should be unsuccessful
3. Operation should be successful
4. Operation should be unsuccessful
"""
log.info("Change the password and check that a new entry has been added to the history")
topo.standalone.passwd_s(user_2.dn, NEW_PASSWD, OLD_PASSWD)
regex = re.search('Z(.+)', user_2.get_attr_val_utf8('passwordhistory'))
assert NEW_PASSWD == regex.group(1)
log.info("Try changing password to one stored in history. Should fail")
with pytest.raises(ldap.CONSTRAINT_VIOLATION):
assert topo.standalone.passwd_s(user_2.dn, OLD_PASSWD, NEW_PASSWD)
log.info("Change the password several times in a row, and try binding after each change")
topo.standalone.passwd_s(user.dn, NEW_PASSWD, OLD_PASSWD)
assert topo.standalone.simple_bind_s(user.dn, OLD_PASSWD)
topo.standalone.passwd_s(user.dn, OLD_PASSWD, SHORT_PASSWD)
assert topo.standalone.simple_bind_s(user.dn, SHORT_PASSWD)
with pytest.raises(ldap.CONSTRAINT_VIOLATION):
topo.standalone.passwd_s(user.dn, SHORT_PASSWD, OLD_PASSWD)
def test_pwd_modify_with_subsuffix(topo):
"""Performing various password modify operation.
:id: 2255b4e6-3546-4ec5-84a5-cd8b3d894ac5
:setup: Standalone instance (TLS enabled)
:steps:
1. Add a new SubSuffix & password policy
2. Add two New users under the SubEntry
3. Change password of uid=test_user0,ou=TestPeople_bug834047,dc=example,dc=com to newpassword
4. Try to delete password- case when password is specified
5. Try to delete password- case when password is not specified
:expectedresults:
1. Operation should be successful
2. Operation should be successful
3. Operation should be successful
4. Operation should be successful
5. Operation should be successful
"""
log.info("Add a new SubSuffix")
ous = OrganizationalUnits(topo.standalone, DEFAULT_SUFFIX)
ou_temp = ous.create(properties={'ou': TESTPEOPLE_OU})
log.info("Add the container & create password policies")
policy = PwPolicyManager(topo.standalone)
policy.create_subtree_policy(ou_temp.dn, properties={
'passwordHistory': 'on',
'passwordInHistory': '6',
'passwordChange': 'on',
'passwordStorageScheme': 'CLEAR'})
log.info("Add two New users under the SubEntry")
user = UserAccounts(topo.standalone, DEFAULT_SUFFIX, rdn='ou=TestPeople_bug834047')
test_user0 = user.create(properties={
'uid': 'test_user0',
'cn': 'test0',
'sn': 'test0',
'uidNumber': '3002',
'gidNumber': '4002',
'homeDirectory': '/home/test_user0',
'userPassword': OLD_PASSWD
})
test_user1 = user.create(properties={
'uid': 'test_user1',
'cn': 'test1',
'sn': 'test1',
'uidNumber': '3003',
'gidNumber': '4003',
'homeDirectory': '/home/test_user3',
'userPassword': OLD_PASSWD
})
log.info(f"Changing password of {test_user0.dn} to newpassword")
topo.standalone.simple_bind_s(test_user0.dn, OLD_PASSWD)
topo.standalone.modify_s(test_user0.dn, [(ldap.MOD_REPLACE, 'userPassword', ensure_bytes(NEW_PASSWD))])
topo.standalone.simple_bind_s(test_user0.dn, NEW_PASSWD)
log.info("Try to delete password- case when password is specified")
topo.standalone.modify_s(test_user0.dn, [(ldap.MOD_DELETE, 'userPassword', ensure_bytes(NEW_PASSWD))])
topo.standalone.simple_bind_s(test_user1.dn, OLD_PASSWD)
log.info("Try to delete password- case when password is not specified")
topo.standalone.modify_s(test_user1.dn, [(ldap.MOD_DELETE, 'userPassword', None)])
if __name__ == '__main__':
# Run isolated
# -s for DEBUG mode
CURRENT_FILE = os.path.realpath(__file__)
pytest.main(["-s", CURRENT_FILE])
# --- BEGIN COPYRIGHT BLOCK ---
# Copyright (C) 2016 Red Hat, Inc.
# All rights reserved.
#
# License: GPL (version 3 or any later version).
# See LICENSE for details.
# --- END COPYRIGHT BLOCK ---
#
'''
Created on Nov 27th, 2018
@author: tbordaz
'''
import logging
import subprocess
import pytest
from lib389 import Entry
from lib389.utils import *
from lib389.plugins import *
from lib389._constants import *
from lib389.topologies import topology_st as topo
def add_user(server, uid, testbase, locality=None, tel=None, title=None):
dn = 'uid=%s,%s' % (uid, testbase)
log.fatal('Adding user (%s): ' % dn)
server.add_s(Entry((dn, {'objectclass': ['top', 'person', 'organizationalPerson', 'inetOrgPerson'],
'cn': 'user_%s' % uid,
'sn': 'user_%s' % uid,
'uid': uid,
'l': locality,
'title': title,
'telephoneNumber': tel,
'description': 'description real'})))
@pytest.mark.ds50053
def test_cos_operational_default(topo):
"""operational-default cosAttribute should not overwrite an existing value
:id: 12fadff9-e14a-4c64-a3ee-51152cb8fcfb
:setup: Standalone Instance
:steps:
1. Create a user entry with attribute 'l' and 'telephonenumber' (real attribute with real value)
2. Create cos that defines 'l' as operational-default (virt. attr. with value != real value)
3. Create cos that defines 'telephone' as default (virt. attr. with value != real value)
4. Check that telephone is retrieved with real value
5. Check that 'l' is retrieved with real value
:expectedresults:
1. should succeed
2. should succeed
3. should succeed
"""
REAL = 'real'
VIRTUAL = 'virtual'
TEL_REAL = '1234 is %s' % REAL
TEL_VIRT = '4321 is %s' % VIRTUAL
LOC_REAL = 'here is %s' % REAL
LOC_VIRT = 'there is %s' % VIRTUAL
TITLE_REAL = 'title is %s' % REAL
inst = topo[0]
PEOPLE = 'ou=people,%s' % SUFFIX
add_user(inst, 'user_0', PEOPLE, locality=LOC_REAL, tel=TEL_REAL, title=TITLE_REAL)
# locality cos operational-default
LOC_COS_TEMPLATE = "cn=locality_template,%s" % PEOPLE
LOC_COS_DEFINITION = "cn=locality_definition,%s" % PEOPLE
inst.add_s(Entry((LOC_COS_TEMPLATE, {
'objectclass': ['top', 'extensibleObject', 'costemplate',
'ldapsubentry'],
'l': LOC_VIRT})))
inst.add_s(Entry((LOC_COS_DEFINITION, {
'objectclass': ['top', 'LdapSubEntry', 'cosSuperDefinition',
'cosPointerDefinition'],
'cosTemplateDn': LOC_COS_TEMPLATE,
'cosAttribute': 'l operational-default'})))
# telephone cos default
TEL_COS_TEMPLATE = "cn=telephone_template,%s" % PEOPLE
TEL_COS_DEFINITION = "cn=telephone_definition,%s" % PEOPLE
inst.add_s(Entry((TEL_COS_TEMPLATE, {
'objectclass': ['top', 'extensibleObject', 'costemplate',
'ldapsubentry'],
'telephonenumber': TEL_VIRT})))
inst.add_s(Entry((TEL_COS_DEFINITION, {
'objectclass': ['top', 'LdapSubEntry', 'cosSuperDefinition',
'cosPointerDefinition'],
'cosTemplateDn': TEL_COS_TEMPLATE,
'cosAttribute': 'telephonenumber default'})))
# seeAlso cos operational
SEEALSO_VIRT = "dc=%s,dc=example,dc=com" % VIRTUAL
SEEALSO_COS_TEMPLATE = "cn=seealso_template,%s" % PEOPLE
SEEALSO_COS_DEFINITION = "cn=seealso_definition,%s" % PEOPLE
inst.add_s(Entry((SEEALSO_COS_TEMPLATE, {
'objectclass': ['top', 'extensibleObject', 'costemplate',
'ldapsubentry'],
'seealso': SEEALSO_VIRT})))
inst.add_s(Entry((SEEALSO_COS_DEFINITION, {
'objectclass': ['top', 'LdapSubEntry', 'cosSuperDefinition',
'cosPointerDefinition'],
'cosTemplateDn': SEEALSO_COS_TEMPLATE,
'cosAttribute': 'seealso operational'})))
# description cos override
DESC_VIRT = "desc is %s" % VIRTUAL
DESC_COS_TEMPLATE = "cn=desc_template,%s" % PEOPLE
DESC_COS_DEFINITION = "cn=desc_definition,%s" % PEOPLE
inst.add_s(Entry((DESC_COS_TEMPLATE, {
'objectclass': ['top', 'extensibleObject', 'costemplate',
'ldapsubentry'],
'description': DESC_VIRT})))
inst.add_s(Entry((DESC_COS_DEFINITION, {
'objectclass': ['top', 'LdapSubEntry', 'cosSuperDefinition',
'cosPointerDefinition'],
'cosTemplateDn': DESC_COS_TEMPLATE,
'cosAttribute': 'description override'})))
# title cos override
TITLE_VIRT = []
for i in range(2):
TITLE_VIRT.append("title is %s %d" % (VIRTUAL, i))
TITLE_COS_TEMPLATE = "cn=title_template,%s" % PEOPLE
TITLE_COS_DEFINITION = "cn=title_definition,%s" % PEOPLE
inst.add_s(Entry((TITLE_COS_TEMPLATE, {
'objectclass': ['top', 'extensibleObject', 'costemplate',
'ldapsubentry'],
'title': TITLE_VIRT})))
inst.add_s(Entry((TITLE_COS_DEFINITION, {
'objectclass': ['top', 'LdapSubEntry', 'cosSuperDefinition',
'cosPointerDefinition'],
'cosTemplateDn': TITLE_COS_TEMPLATE,
'cosAttribute': 'title merge-schemes'})))
# note that the search requests both attributes (it is required for operational*)
ents = inst.search_s(SUFFIX, ldap.SCOPE_SUBTREE, "uid=user_0", ["telephonenumber", "l"])
assert len(ents) == 1
ent = ents[0]
# Check telephonenumber (specifier default) with real value => real
assert ent.hasAttr('telephonenumber')
value = ent.getValue('telephonenumber')
log.info('Returned telephonenumber (exp. real): %s' % value)
log.info('Returned telephonenumber: %d' % value.find(REAL.encode()))
assert value.find(REAL.encode()) != -1
# Check 'locality' (specifier operational-default) with real value => real
assert ent.hasAttr('l')
value = ent.getValue('l')
log.info('Returned l (exp. real): %s ' % value)
log.info('Returned l: %d' % value.find(REAL.encode()))
assert value.find(REAL.encode()) != -1
# Check 'seealso' (specifier operational) without real value => virtual
assert not ent.hasAttr('seealso')
ents = inst.search_s(SUFFIX, ldap.SCOPE_SUBTREE, "uid=user_0", ["seealso"])
assert len(ents) == 1
ent = ents[0]
value = ent.getValue('seealso')
log.info('Returned seealso (exp. virtual): %s' % value)
log.info('Returned seealso: %d' % value.find(VIRTUAL.encode()))
assert value.find(VIRTUAL.encode()) != -1
# Check 'description' (specifier override) with real value => virtual
assert not ent.hasAttr('description')
ents = inst.search_s(SUFFIX, ldap.SCOPE_SUBTREE, "uid=user_0")
assert len(ents) == 1
ent = ents[0]
value = ent.getValue('description')
log.info('Returned description (exp. virtual): %s' % value)
log.info('Returned description: %d' % value.find(VIRTUAL.encode()))
assert value.find(VIRTUAL.encode()) != -1
# Check 'title' (specifier merge-schemes) with real value => real value returned
ents = inst.search_s(SUFFIX, ldap.SCOPE_SUBTREE, "uid=user_0")
assert len(ents) == 1
ent = ents[0]
found_real = False
found_virtual = False
for value in ent.getValues('title'):
log.info('Returned title (exp. real): %s' % value)
if value.find(VIRTUAL.encode()) != -1:
found_virtual = True
if value.find(REAL.encode()) != -1:
found_real = True
assert not found_virtual
assert found_real
# Check 'title ((specifier merge-schemes) without real value => real value returned
ents = inst.search_s(SUFFIX, ldap.SCOPE_SUBTREE, "uid=user_0")
assert len(ents) == 1
inst.modify_s(ents[0].dn,[(ldap.MOD_DELETE, 'title', None)])
inst.restart()
ents = inst.search_s(SUFFIX, ldap.SCOPE_SUBTREE, "uid=user_0")
assert len(ents) == 1
ent = ents[0]
found_real = False
found_virtual = False
count = 0
for value in ent.getValues('title'):
log.info('Returned title(exp. virt): %s' % value)
count = count + 1
if value.find(VIRTUAL.encode()) != -1:
found_virtual = True
if value.find(REAL.encode()) != -1:
found_real = True
assert not found_real
assert found_virtual
assert count == 2
......@@ -33,7 +33,7 @@ RUN dnf install -y 389-ds-base/dist/rpms/*389*.rpm && \
# Create the example setup inf. It's valid for containers!
# Build the instance from the new installer tools.
RUN /usr/sbin/dscreate create-template > /root/ds-setup.inf && /usr/sbin/dscreate -v fromfile /root/ds-setup.inf --containerised
RUN /usr/sbin/dscreate create-template > /root/ds-setup.inf && /usr/sbin/dscreate -v from-file /root/ds-setup.inf --containerised
# Finally add the volumes, they will inherit the contents of these directories.
VOLUME /etc/dirsrv
......
......@@ -16,6 +16,7 @@
/* What was extcmap.h begins ... */
#include <ldap.h>
#include <nss3/cert.h>
#ifndef NSAPI_PUBLIC
#define NSAPI_PUBLIC
......@@ -156,7 +157,7 @@ typedef int (*CertVerifyFn_t)(void *cert, LDAP *ld, void *certmap_info, LDAPMess
* otherwise return LDAPU_CERT_MAP_INITFN_FAILED. The server startup will be
* aborted if the return value is not LDAPU_SUCCESS.
*/
typedef int (*CertMapInitFn_t)(void *certmap_info, const char *issuerName, const char *issuerDN, const char *libname);
typedef int (*CertMapInitFn_t)(void *certmap_info, const char *issuerName, const CERTName *issuerDN, const char *libname);
/*
* Refer to the description of the function ldapu_get_cert_ava_val
......@@ -209,27 +210,30 @@ extern "C" {
NSAPI_PUBLIC int ldapu_cert_to_ldap_entry(void *cert, LDAP *ld, const char *basedn, LDAPMessage **res);
NSAPI_PUBLIC int ldapu_set_cert_mapfn(const char *issuerDN,
NSAPI_PUBLIC int ldapu_set_cert_mapfn(const CERTName *issuerDN,
CertMapFn_t mapfn);
NSAPI_PUBLIC CertMapFn_t ldapu_get_cert_mapfn(const char *issuerDN);
NSAPI_PUBLIC CertMapFn_t ldapu_get_cert_mapfn(const CERTName *issuerDN);
NSAPI_PUBLIC int ldapu_set_cert_searchfn(const char *issuerDN,
NSAPI_PUBLIC int ldapu_set_cert_searchfn(const CERTName *issuerDN,
CertSearchFn_t searchfn);
NSAPI_PUBLIC CertSearchFn_t ldapu_get_cert_searchfn(const char *issuerDN);
NSAPI_PUBLIC CertSearchFn_t ldapu_get_cert_searchfn(const CERTName *issuerDN);
NSAPI_PUBLIC int ldapu_set_cert_verifyfn(const char *issuerDN,
NSAPI_PUBLIC int ldapu_set_cert_verifyfn(const CERTName *issuerDN,
CertVerifyFn_t verifyFn);
NSAPI_PUBLIC CertVerifyFn_t ldapu_get_cert_verifyfn(const char *issuerDN);
NSAPI_PUBLIC CertVerifyFn_t ldapu_get_cert_verifyfn(const CERTName *issuerDN);
NSAPI_PUBLIC int ldapu_get_cert_subject_dn(void *cert, char **subjectDN);
NSAPI_PUBLIC CERTName *ldapu_get_cert_issuer_dn_as_CERTName(CERTCertificate *cert);
NSAPI_PUBLIC int ldapu_get_cert_issuer_dn(void *cert, char **issuerDN);
......@@ -242,7 +246,7 @@ NSAPI_PUBLIC int ldapu_free_cert_ava_val(char **val);
NSAPI_PUBLIC int ldapu_get_cert_der(void *cert, unsigned char **derCert, unsigned int *len);
NSAPI_PUBLIC int ldapu_issuer_certinfo(const char *issuerDN,
NSAPI_PUBLIC int ldapu_issuer_certinfo(const CERTName *issuerDN,
void **certmap_info);
......
......@@ -48,7 +48,7 @@ enum
typedef struct
{
char *issuerName; /* issuer (symbolic/short) name */
char *issuerDN; /* cert issuer's DN */
CERTName *issuerDN; /* cert issuer's DN */
LDAPUPropValList_t *propval; /* pointer to the prop-val pairs list */
CertMapFn_t mapfn; /* cert to ldapdn & filter mapping func */
CertVerifyFn_t verifyfn; /* verify cert function */
......
This diff is collapsed.
......@@ -74,7 +74,6 @@ static void automember_free_regex_rule(struct automemberRegexRule *rule);
static int automember_parse_grouping_attr(char *value, char **grouping_attr, char **grouping_value);
static int automember_update_membership(struct configEntry *config, Slapi_Entry *e, PRFileDesc *ldif_fd);
static int automember_add_member_value(Slapi_Entry *member_e, const char *group_dn, char *grouping_attr, char *grouping_value, PRFileDesc *ldif_fd);
const char *fetch_attr(Slapi_Entry *e, const char *attrname, const char *default_val);
/*
* task functions
......@@ -1927,25 +1926,6 @@ typedef struct _task_data
int scope;
} task_data;
/*
* extract a single value from the entry (as a string) -- if it's not in the
* entry, the default will be returned (which can be NULL).
* you do not need to free anything returned by this.
*/
const char *
fetch_attr(Slapi_Entry *e, const char *attrname, const char *default_val)
{
Slapi_Value *val = NULL;
Slapi_Attr *attr;
if (slapi_entry_attr_find(e, attrname, &attr) != 0) {
return default_val;
}
slapi_attr_first_value(attr, &val);
return slapi_value_get_string(val);
}
static void
automember_task_destructor(Slapi_Task *task)
{
......@@ -2038,17 +2018,17 @@ automember_task_add(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter __attr
/*
* Grab the task params
*/
if ((base_dn = fetch_attr(e, "basedn", 0)) == NULL) {
if ((base_dn = slapi_fetch_attr(e, "basedn", 0)) == NULL) {
*returncode = LDAP_OBJECT_CLASS_VIOLATION;
rv = SLAPI_DSE_CALLBACK_ERROR;
goto out;
}
if ((filter = fetch_attr(e, "filter", 0)) == NULL) {
if ((filter = slapi_fetch_attr(e, "filter", 0)) == NULL) {
*returncode = LDAP_OBJECT_CLASS_VIOLATION;
rv = SLAPI_DSE_CALLBACK_ERROR;
goto out;
}
scope = fetch_attr(e, "scope", "sub");
scope = slapi_fetch_attr(e, "scope", "sub");
/*
* setup our task data
*/
......@@ -2265,22 +2245,22 @@ automember_task_add_export_updates(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry
*returncode = LDAP_SUCCESS;
if ((ldif = fetch_attr(e, "ldif", 0)) == NULL) {
if ((ldif = slapi_fetch_attr(e, "ldif", 0)) == NULL) {
*returncode = LDAP_OBJECT_CLASS_VIOLATION;
rv = SLAPI_DSE_CALLBACK_ERROR;
goto out;
}
if ((base_dn = fetch_attr(e, "basedn", 0)) == NULL) {
if ((base_dn = slapi_fetch_attr(e, "basedn", 0)) == NULL) {
*returncode = LDAP_OBJECT_CLASS_VIOLATION;
rv = SLAPI_DSE_CALLBACK_ERROR;
goto out;
}
if ((filter = fetch_attr(e, "filter", 0)) == NULL) {
if ((filter = slapi_fetch_attr(e, "filter", 0)) == NULL) {
*returncode = LDAP_OBJECT_CLASS_VIOLATION;
rv = SLAPI_DSE_CALLBACK_ERROR;
goto out;
}
scope = fetch_attr(e, "scope", "sub");
scope = slapi_fetch_attr(e, "scope", "sub");
slapi_pblock_get(pb, SLAPI_REQUESTOR_DN, &bind_dn);
......@@ -2473,12 +2453,12 @@ automember_task_add_map_entries(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *e
/*
* Get the params
*/
if ((ldif_in = fetch_attr(e, "ldif_in", 0)) == NULL) {
if ((ldif_in = slapi_fetch_attr(e, "ldif_in", 0)) == NULL) {
*returncode = LDAP_OBJECT_CLASS_VIOLATION;
rv = SLAPI_DSE_CALLBACK_ERROR;
goto out;
}
if ((ldif_out = fetch_attr(e, "ldif_out", 0)) == NULL) {
if ((ldif_out = slapi_fetch_attr(e, "ldif_out", 0)) == NULL) {
*returncode = LDAP_OBJECT_CLASS_VIOLATION;
rv = SLAPI_DSE_CALLBACK_ERROR;
goto out;
......
......@@ -1840,7 +1840,7 @@ cb_instance_add_config_check_callback(Slapi_PBlock *pb __attribute__((unused)),
if ((rc = cb_build_backend_instance_config(inst, e, 0)) != LDAP_SUCCESS) {
slapi_log_err(SLAPI_LOG_ERR, CB_PLUGIN_SUBSYSTEM,
"cb_instance_add_config_check_callback - Can't instantiate chaining backend instance %s.\n", inst->inst_name);
*returncode = rc;
*returncode = LDAP_UNWILLING_TO_PERFORM;
cb_instance_free(inst);
return SLAPI_DSE_CALLBACK_ERROR;
}
......
......@@ -2279,7 +2279,7 @@ cos_cache_query_attr(cos_cache *ptheCache, vattr_context *context, Slapi_Entry *
/* now for the tests */
/* would we be allowed to supply this attribute if we had one? */
if (entry_has_value && !pAttr->attr_override && !pAttr->attr_operational && !pAttr->attr_operational_default) {
if (entry_has_value && !pAttr->attr_override && !pAttr->attr_operational) {
/* answer: no, move on to the next attribute */
attr_index++;
continue;
......