Changes to 'refs/tags/389-adminutil-1.1.20'
by Richard Allen Megginson
Changes since the dawn of time:
Mark Reynolds (2):
Ticket 400 - BIND operation result not checked properly in adminutil
Ticket 497 - Console logins fail intermittenly
Nathan Kinder (15):
Fixed parsing of supported emulations in nsarch
Resolves: 213070
Related: 213070
Resolves: 246124
Resolves: 247192
Bug 697106 - (cov#10770) Need to call va_end() after calling va_start()
Bug 697110 - (cov#10757) Remove unused variable in psetRootModAttrList()
Bug 697116 - Need to check if admldapGetISIEDN() returns NULL
Bug 697106 - (cov#10770) Need to call va_end() after calling va_start()
Bug 697641 - Check return value of DER_UTCTimeToAscii()
Bug 697641 - Check if nodeName is NULL before dereferencing
Bug 697641 - Check if pset is NULL before dereferencing
Bug 697641 - Check if valBuf is NULL before dereferencing
Bug 697641 - Check list->name for NULL before dereferencing
Bug 697641 - Check if strchr() returns NULL before dereferencing
Noriko Hosoi (23):
[161407] Fixed the library path for the 64-bit build on Solaris.
libadminutil##.<ext> should not link SSL related ldapsdk libraries.
*** empty log message ***
[172166] Admin Util RPM
[172166] Admin Util build (64-bit)
[172166] Admin Util build (IPF)
[Bug 172166] Admin Util build (IPF)
[Bug 172166] Admin Util build (IPF)
[179394] HP-UX PA-RISC support
[179394] HP-UX IPF/PA-RISC support
upgraded LDAP C SDK: v5.16 -> v5.17
Replaced PL_Free with PR_Free.
[161099] admin passwd in clear text in adm.conf
[172166] Admin Util build (RPM)
[195258] Changes for the internal build
Removed the link arg to link with libCrun.so.1 since there is no C++ code
Resolves: #186280
Resolves: Bug 237356
Fixed a minor bug introduced in the revision 1.6.
Resolves: #191834
bump version to 1.1.16
bump version to 1.1.17
Ticket #47343 - 389-adminutil: Does not support aarch64 in f19 and rawhide
Rich Megginson (64):
change binary directory naming convention to the same one we use with pre-built binary components; remove old crufty Fortezza stuff; general makefile cleanup
Bug(s) fixed: 171799
make PERL5 use perl from PATH on Linux
The correct naming convention for RHEL is
1) Fix moz objdir name for generic linux x86_64
Bug(s) fixed: 186280
Bug: 186280
use new ldapcsdk 6.0.0; upgrade other components
Reviewed by: nhosoi (Thanks!)
Bug(s) fixed: 213788
Bug: 213788
Resolves: bug 234420
Resolves: bug 239475
bump version to 1.1.1
bump version to 1.1.1
add support for -version-number when building shared libs; fix a couple of minor issues brought up in fedora package review
pkgconfig is a requires, not a build requires
final spec fix for fedora
Resolves: bug 235293
Resolves: bug 245208
Resolves: bug 245208
Resolves: bug 245396
bump version to 1.1.2
bump version to 1.1.3
Resolves: bug 250526
Resolves: bug 323381
bump version to 1.1.5
Resolves: bug 245248
bump version to 1.1.6
Resolves: bug 413531
Resolves: bug 454060
the correct function name is admldapSetDirectoryURL
bump version to 1.1.7
Resolves: bug 462411
compiler warning clean up
Resolves: bug 466137
fix compiler warning
bump version to 1.1.8
the 1.1.8 release
Rename adminutil to 389-adminutil
added .gitignore
use icu genrb from path if no icu_bin given or found
Bug 460168 - FedoraDS' adminutil requires non-existent "icu.pc" on non-RH/Fedora OS
remove adminutil.pc.in
bump version to 1.1.10
Bug 614690 - adminutil ICU RB generation can fail
Port adminutil to use openldap
allow building with mozldap again
bump version to 1.1.12
version 1.1.13 - add nss_inc to includes for libadminutil sources
bump version to 1.1.14
Ticket #161 - Review and address latest Coverity issues
Ticket #161 - Review and address latest Coverity issues
Ticket #281 - TLS not working with latest openldap
bump version to 1.1.15
fix mem leak in admldapBuildInfoSSL when there is no password
Ticket #47486 - compiler warnings in adminutil, admin, dsgw
add Eclipse generated files
bump version to 1.1.18
Ticket #47415 "Manage certificates" crashes admin server
fix compiler warnings - enhancements to test ticket 47415
bump version to 1.1.19
Ticket #47680 Upgraded 389-admin rpms and now I can't start dirsrv-admin
bump version to 1.1.20
foxworth (1):
Internal Red Hat CVS project for adminutil: core
10 years
Changes to 'refs/tags/389-adminutil-1.1.19'
by Richard Allen Megginson
Changes since the dawn of time:
Mark Reynolds (2):
Ticket 400 - BIND operation result not checked properly in adminutil
Ticket 497 - Console logins fail intermittenly
Nathan Kinder (15):
Fixed parsing of supported emulations in nsarch
Resolves: 213070
Related: 213070
Resolves: 246124
Resolves: 247192
Bug 697106 - (cov#10770) Need to call va_end() after calling va_start()
Bug 697110 - (cov#10757) Remove unused variable in psetRootModAttrList()
Bug 697116 - Need to check if admldapGetISIEDN() returns NULL
Bug 697106 - (cov#10770) Need to call va_end() after calling va_start()
Bug 697641 - Check return value of DER_UTCTimeToAscii()
Bug 697641 - Check if nodeName is NULL before dereferencing
Bug 697641 - Check if pset is NULL before dereferencing
Bug 697641 - Check if valBuf is NULL before dereferencing
Bug 697641 - Check list->name for NULL before dereferencing
Bug 697641 - Check if strchr() returns NULL before dereferencing
Noriko Hosoi (23):
[161407] Fixed the library path for the 64-bit build on Solaris.
libadminutil##.<ext> should not link SSL related ldapsdk libraries.
*** empty log message ***
[172166] Admin Util RPM
[172166] Admin Util build (64-bit)
[172166] Admin Util build (IPF)
[Bug 172166] Admin Util build (IPF)
[Bug 172166] Admin Util build (IPF)
[179394] HP-UX PA-RISC support
[179394] HP-UX IPF/PA-RISC support
upgraded LDAP C SDK: v5.16 -> v5.17
Replaced PL_Free with PR_Free.
[161099] admin passwd in clear text in adm.conf
[172166] Admin Util build (RPM)
[195258] Changes for the internal build
Removed the link arg to link with libCrun.so.1 since there is no C++ code
Resolves: #186280
Resolves: Bug 237356
Fixed a minor bug introduced in the revision 1.6.
Resolves: #191834
bump version to 1.1.16
bump version to 1.1.17
Ticket #47343 - 389-adminutil: Does not support aarch64 in f19 and rawhide
Rich Megginson (62):
change binary directory naming convention to the same one we use with pre-built binary components; remove old crufty Fortezza stuff; general makefile cleanup
Bug(s) fixed: 171799
make PERL5 use perl from PATH on Linux
The correct naming convention for RHEL is
1) Fix moz objdir name for generic linux x86_64
Bug(s) fixed: 186280
Bug: 186280
use new ldapcsdk 6.0.0; upgrade other components
Reviewed by: nhosoi (Thanks!)
Bug(s) fixed: 213788
Bug: 213788
Resolves: bug 234420
Resolves: bug 239475
bump version to 1.1.1
bump version to 1.1.1
add support for -version-number when building shared libs; fix a couple of minor issues brought up in fedora package review
pkgconfig is a requires, not a build requires
final spec fix for fedora
Resolves: bug 235293
Resolves: bug 245208
Resolves: bug 245208
Resolves: bug 245396
bump version to 1.1.2
bump version to 1.1.3
Resolves: bug 250526
Resolves: bug 323381
bump version to 1.1.5
Resolves: bug 245248
bump version to 1.1.6
Resolves: bug 413531
Resolves: bug 454060
the correct function name is admldapSetDirectoryURL
bump version to 1.1.7
Resolves: bug 462411
compiler warning clean up
Resolves: bug 466137
fix compiler warning
bump version to 1.1.8
the 1.1.8 release
Rename adminutil to 389-adminutil
added .gitignore
use icu genrb from path if no icu_bin given or found
Bug 460168 - FedoraDS' adminutil requires non-existent "icu.pc" on non-RH/Fedora OS
remove adminutil.pc.in
bump version to 1.1.10
Bug 614690 - adminutil ICU RB generation can fail
Port adminutil to use openldap
allow building with mozldap again
bump version to 1.1.12
version 1.1.13 - add nss_inc to includes for libadminutil sources
bump version to 1.1.14
Ticket #161 - Review and address latest Coverity issues
Ticket #161 - Review and address latest Coverity issues
Ticket #281 - TLS not working with latest openldap
bump version to 1.1.15
fix mem leak in admldapBuildInfoSSL when there is no password
Ticket #47486 - compiler warnings in adminutil, admin, dsgw
add Eclipse generated files
bump version to 1.1.18
Ticket #47415 "Manage certificates" crashes admin server
fix compiler warnings - enhancements to test ticket 47415
bump version to 1.1.19
foxworth (1):
Internal Red Hat CVS project for adminutil: core
10 years
2 commits - configure configure.ac include/libadminutil lib/libadminutil
by Richard Allen Megginson
configure | 20 ++++++++++----------
configure.ac | 2 +-
include/libadminutil/admutil-int.h | 1 -
lib/libadminutil/admutil.c | 10 ----------
4 files changed, 11 insertions(+), 22 deletions(-)
New commits:
commit 9b3cfced24ffe6e6ea757415c3d508a9fad6061a
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Wed Mar 19 16:29:18 2014 -0600
bump version to 1.1.20
diff --git a/configure b/configure
index 27ef738..03f518d 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for 389-adminutil 1.1.19.
+# Generated by GNU Autoconf 2.69 for 389-adminutil 1.1.20.
#
# Report bugs to <http://bugzilla.redhat.com/>.
#
@@ -590,8 +590,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='389-adminutil'
PACKAGE_TARNAME='389-adminutil'
-PACKAGE_VERSION='1.1.19'
-PACKAGE_STRING='389-adminutil 1.1.19'
+PACKAGE_VERSION='1.1.20'
+PACKAGE_STRING='389-adminutil 1.1.20'
PACKAGE_BUGREPORT='http://bugzilla.redhat.com/'
PACKAGE_URL=''
@@ -1378,7 +1378,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures 389-adminutil 1.1.19 to adapt to many kinds of systems.
+\`configure' configures 389-adminutil 1.1.20 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1448,7 +1448,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of 389-adminutil 1.1.19:";;
+ short | recursive ) echo "Configuration of 389-adminutil 1.1.20:";;
esac
cat <<\_ACEOF
@@ -1583,7 +1583,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-389-adminutil configure 1.1.19
+389-adminutil configure 1.1.20
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -2173,7 +2173,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by 389-adminutil $as_me 1.1.19, which was
+It was created by 389-adminutil $as_me 1.1.20, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -3000,7 +3000,7 @@ fi
# Define the identity of the package.
PACKAGE='389-adminutil'
- VERSION='1.1.19'
+ VERSION='1.1.20'
cat >>confdefs.h <<_ACEOF
@@ -19147,7 +19147,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by 389-adminutil $as_me 1.1.19, which was
+This file was extended by 389-adminutil $as_me 1.1.20, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -19204,7 +19204,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-389-adminutil config.status 1.1.19
+389-adminutil config.status 1.1.20
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
diff --git a/configure.ac b/configure.ac
index 90f9aaf..d5b72f7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1,7 +1,7 @@
# -*- Autoconf -*-
# Process this file with autoconf to produce a configure script.
AC_PREREQ(2.59)
-AC_INIT([389-adminutil], [1.1.19], [http://bugzilla.redhat.com/])
+AC_INIT([389-adminutil], [1.1.20], [http://bugzilla.redhat.com/])
AM_INIT_AUTOMAKE([1.9 foreign subdir-objects])
AM_MAINTAINER_MODE
AC_CANONICAL_HOST
commit 1c4ea9f993729ece25115953556eccb2fff337de
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Wed Mar 19 16:14:38 2014 -0600
Ticket #47680 Upgraded 389-admin rpms and now I can't start dirsrv-admin
https://fedorahosted.org/389/ticket/47680
Reviewed by: nhosoi (Thanks!)
Branch: master
Fix Description: Get rid of bogus function admldap_ldap_explode.
Platforms tested: RHEL5 x86_64
Flag Day: no
Doc impact: no
diff --git a/include/libadminutil/admutil-int.h b/include/libadminutil/admutil-int.h
index 8048b6d..20992e2 100644
--- a/include/libadminutil/admutil-int.h
+++ b/include/libadminutil/admutil-int.h
@@ -187,7 +187,6 @@ int admutil_ldap_bind(
int *msgidp /* pass in non-NULL for async handling */
);
-char **admldap_ldap_explode( const char *dn, const int notypes, const int nametype );
char **admldap_ldap_explode_dn( const char *dn, const int notypes );
char **admldap_ldap_explode_rdn( const char *rdn, const int notypes );
#endif /* __ADMUTIL_INT_H__ */
diff --git a/lib/libadminutil/admutil.c b/lib/libadminutil/admutil.c
index f296b1f..839ab2d 100644
--- a/lib/libadminutil/admutil.c
+++ b/lib/libadminutil/admutil.c
@@ -2829,16 +2829,6 @@ mozldap_ldap_explode_rdn( const char *rdn, const int notypes )
#endif /* USE_OPENLDAP */
char **
-admldap_ldap_explode( const char *dn, const int notypes, const int nametype )
-{
-#if defined(USE_OPENLDAP)
- return mozldap_ldap_explode(dn, notypes, nametype);
-#else
- return ldap_explode(dn, notypes, nametype);
-#endif
-}
-
-char **
admldap_ldap_explode_dn( const char *dn, const int notypes )
{
#if defined(USE_OPENLDAP)
10 years
Branch '389-ds-base-1.2.11' - ldap/servers
by Mark Reynolds
ldap/servers/slapd/proxyauth.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
New commits:
commit 872b7d906d4d1d2f03f34841beb005a8b222ff03
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Tue Mar 18 16:08:19 2014 -0400
Ticket 47743 - Memory leak with proxy auth control
Description: We were not properly freeing the ber when parsing
the proxy auth DN.
https://fedorahosted.org/389/ticket/47743
Reviewed by: rmeggins(Thanks!)
(cherry picked from commit e4a1de6abf9cf349f89c7b55527e89da258c5fd5)
diff --git a/ldap/servers/slapd/proxyauth.c b/ldap/servers/slapd/proxyauth.c
index 17b6a05..25c9807 100644
--- a/ldap/servers/slapd/proxyauth.c
+++ b/ldap/servers/slapd/proxyauth.c
@@ -154,7 +154,7 @@ parse_LDAPProxyAuth(struct berval *spec_ber, int version, char **errtextp,
END
/* Cleanup */
- if (ber) ber_free(ber, 0);
+ if (ber) ber_free(ber, 1);
if ( LDAP_SUCCESS != lderr)
{
10 years
Branch '389-ds-base-1.3.0' - ldap/servers
by Mark Reynolds
ldap/servers/slapd/proxyauth.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
New commits:
commit fd954a73a69c9daa0ef802ceede4b6ca90771186
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Tue Mar 18 16:08:19 2014 -0400
Ticket 47743 - Memory leak with proxy auth control
Description: We were not properly freeing the ber when parsing
the proxy auth DN.
https://fedorahosted.org/389/ticket/47743
Reviewed by: rmeggins(Thanks!)
(cherry picked from commit e4a1de6abf9cf349f89c7b55527e89da258c5fd5)
diff --git a/ldap/servers/slapd/proxyauth.c b/ldap/servers/slapd/proxyauth.c
index 17b6a05..25c9807 100644
--- a/ldap/servers/slapd/proxyauth.c
+++ b/ldap/servers/slapd/proxyauth.c
@@ -154,7 +154,7 @@ parse_LDAPProxyAuth(struct berval *spec_ber, int version, char **errtextp,
END
/* Cleanup */
- if (ber) ber_free(ber, 0);
+ if (ber) ber_free(ber, 1);
if ( LDAP_SUCCESS != lderr)
{
10 years
Branch '389-ds-base-1.3.1' - ldap/servers
by Mark Reynolds
ldap/servers/slapd/proxyauth.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
New commits:
commit 97ed02930b49e2c4f9be2786bfb8a30c8db5915a
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Tue Mar 18 16:08:19 2014 -0400
Ticket 47743 - Memory leak with proxy auth control
Description: We were not properly freeing the ber when parsing
the proxy auth DN.
https://fedorahosted.org/389/ticket/47743
Reviewed by: rmeggins(Thanks!)
(cherry picked from commit e4a1de6abf9cf349f89c7b55527e89da258c5fd5)
diff --git a/ldap/servers/slapd/proxyauth.c b/ldap/servers/slapd/proxyauth.c
index 58c15d8..f8942f4 100644
--- a/ldap/servers/slapd/proxyauth.c
+++ b/ldap/servers/slapd/proxyauth.c
@@ -156,7 +156,7 @@ parse_LDAPProxyAuth(struct berval *spec_ber, int version, char **errtextp,
END
/* Cleanup */
- if (ber) ber_free(ber, 0);
+ if (ber) ber_free(ber, 1);
if ( LDAP_SUCCESS != lderr)
{
10 years
Branch '389-ds-base-1.3.2' - ldap/servers
by Mark Reynolds
ldap/servers/slapd/proxyauth.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
New commits:
commit cdffb5265e235d43abb1115f18e83a8edef4d135
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Tue Mar 18 16:08:19 2014 -0400
Ticket 47743 - Memory leak with proxy auth control
Description: We were not properly freeing the ber when parsing
the proxy auth DN.
https://fedorahosted.org/389/ticket/47743
Reviewed by: rmeggins(Thanks!)
(cherry picked from commit e4a1de6abf9cf349f89c7b55527e89da258c5fd5)
diff --git a/ldap/servers/slapd/proxyauth.c b/ldap/servers/slapd/proxyauth.c
index 58c15d8..f8942f4 100644
--- a/ldap/servers/slapd/proxyauth.c
+++ b/ldap/servers/slapd/proxyauth.c
@@ -156,7 +156,7 @@ parse_LDAPProxyAuth(struct berval *spec_ber, int version, char **errtextp,
END
/* Cleanup */
- if (ber) ber_free(ber, 0);
+ if (ber) ber_free(ber, 1);
if ( LDAP_SUCCESS != lderr)
{
10 years
ldap/servers
by Mark Reynolds
ldap/servers/slapd/proxyauth.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
New commits:
commit e4a1de6abf9cf349f89c7b55527e89da258c5fd5
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Tue Mar 18 16:08:19 2014 -0400
Ticket 47743 - Memory leak with proxy auth control
Description: We were not properly freeing the ber when parsing
the proxy auth DN.
https://fedorahosted.org/389/ticket/47743
Reviewed by: rmeggins(Thanks!)
diff --git a/ldap/servers/slapd/proxyauth.c b/ldap/servers/slapd/proxyauth.c
index 58c15d8..f8942f4 100644
--- a/ldap/servers/slapd/proxyauth.c
+++ b/ldap/servers/slapd/proxyauth.c
@@ -156,7 +156,7 @@ parse_LDAPProxyAuth(struct berval *spec_ber, int version, char **errtextp,
END
/* Cleanup */
- if (ber) ber_free(ber, 0);
+ if (ber) ber_free(ber, 1);
if ( LDAP_SUCCESS != lderr)
{
10 years
dirsrvtests/tickets ldap/schema ldap/servers
by thierry bordaz
dirsrvtests/tickets/ticket47553_single_aci_test.py | 1187 +++++++++++++++++++++
ldap/schema/01core389.ldif | 1
ldap/servers/plugins/acl/acl.c | 250 +++-
ldap/servers/plugins/acl/acl.h | 47
ldap/servers/plugins/acl/aclanom.c | 40
ldap/servers/plugins/acl/acleffectiverights.c | 7
ldap/servers/plugins/acl/aclparse.c | 117 +-
ldap/servers/plugins/acl/aclplugin.c | 2
ldap/servers/plugins/acl/aclutil.c | 5
ldap/servers/slapd/back-ldbm/ldbm_modrdn.c | 59 -
ldap/servers/slapd/config.c | 17
ldap/servers/slapd/libglobs.c | 33
ldap/servers/slapd/proto-slap.h | 2
ldap/servers/slapd/slap.h | 2
ldap/servers/slapd/slapi-plugin.h | 7
15 files changed, 1678 insertions(+), 98 deletions(-)
New commits:
commit dc17d63368fed59048ea7730dadb89ea623e7bab
Author: Thierry bordaz (tbordaz) <tbordaz(a)redhat.com>
Date: Fri Feb 28 14:24:53 2014 +0100
Ticket 47553: Enhance ACIs to have more control over MODRDN operations
Bug Description:
This is enhancement of the access control related to the MODDN/MODRDN operation.
We need the ability to specify a 'source tree' and a 'destination tree' where MODDN/MODRDN
are allowed/denied.
It is a requirement that 'source' and 'destination' targets can be specified in the same ACI.
Fix Description:
Please refer to http://directory.fedoraproject.org/wiki/Access_control_on_trees_specified....
Mainly:
- parse new aci syntax
- support of new 'moddn' right in aci
- Check 'moddn' right in ldbm_back_modrdn
- filter source/destination when looking for matching ressources
- support of 'moddn' rights in GER control
- new nsslapd-moddn-aci compatibility config flag
- aci logging summary (display source/destination)
- Skip readonly backend
https://fedorahosted.org/389/ticket/47553
Reviewed by: Rich Megginson (Big thanks Rich !!)
Platforms tested: F17
Flag Day: no
Doc impact: yes
diff --git a/dirsrvtests/tickets/ticket47553_single_aci_test.py b/dirsrvtests/tickets/ticket47553_single_aci_test.py
new file mode 100644
index 0000000..87f8bb3
--- /dev/null
+++ b/dirsrvtests/tickets/ticket47553_single_aci_test.py
@@ -0,0 +1,1187 @@
+'''
+Created on Nov 7, 2013
+
+@author: tbordaz
+'''
+import os
+import sys
+import time
+import ldap
+import logging
+import socket
+import time
+import logging
+import pytest
+import re
+from lib389 import DirSrv, Entry, tools
+from lib389.tools import DirSrvTools
+from lib389._constants import *
+from lib389.properties import *
+from constants import *
+from lib389._constants import REPLICAROLE_MASTER
+
+logging.getLogger(__name__).setLevel(logging.DEBUG)
+log = logging.getLogger(__name__)
+
+#
+# important part. We can deploy Master1 and Master2 on different versions
+#
+installation1_prefix = None
+installation2_prefix = None
+
+TEST_REPL_DN = "cn=test_repl, %s" % SUFFIX
+
+STAGING_CN = "staged user"
+PRODUCTION_CN = "accounts"
+EXCEPT_CN = "excepts"
+
+STAGING_DN = "cn=%s,%s" % (STAGING_CN, SUFFIX)
+PRODUCTION_DN = "cn=%s,%s" % (PRODUCTION_CN, SUFFIX)
+PROD_EXCEPT_DN = "cn=%s,%s" % (EXCEPT_CN, PRODUCTION_DN)
+
+STAGING_PATTERN = "cn=%s*,%s" % (STAGING_CN[:2], SUFFIX)
+PRODUCTION_PATTERN = "cn=%s*,%s" % (PRODUCTION_CN[:2], SUFFIX)
+BAD_STAGING_PATTERN = "cn=bad*,%s" % (SUFFIX)
+BAD_PRODUCTION_PATTERN = "cn=bad*,%s" % (SUFFIX)
+
+BIND_CN = "bind_entry"
+BIND_DN = "cn=%s,%s" % (BIND_CN, SUFFIX)
+BIND_PW = "password"
+
+NEW_ACCOUNT = "new_account"
+MAX_ACCOUNTS = 20
+
+CONFIG_MODDN_ACI_ATTR = "nsslapd-moddn-aci"
+
+class TopologyMaster1Master2(object):
+ def __init__(self, master1, master2):
+ master1.open()
+ self.master1 = master1
+
+ master2.open()
+ self.master2 = master2
+
+
+#(a)pytest.fixture(scope="module")
+def topology(request):
+ '''
+ This fixture is used to create a replicated topology for the 'module'.
+ The replicated topology is MASTER1 <-> Master2.
+ At the beginning, It may exists a master2 instance and/or a master2 instance.
+ It may also exists a backup for the master1 and/or the master2.
+
+ Principle:
+ If master1 instance exists:
+ restart it
+ If master2 instance exists:
+ restart it
+ If backup of master1 AND backup of master2 exists:
+ create or rebind to master1
+ create or rebind to master2
+
+ restore master1 from backup
+ restore master2 from backup
+ else:
+ Cleanup everything
+ remove instances
+ remove backups
+ Create instances
+ Initialize replication
+ Create backups
+ '''
+ global installation1_prefix
+ global installation2_prefix
+
+ # allocate master1 on a given deployement
+ master1 = DirSrv(verbose=False)
+ if installation1_prefix:
+ args_instance[SER_DEPLOYED_DIR] = installation1_prefix
+
+ # Args for the master1 instance
+ args_instance[SER_HOST] = HOST_MASTER_1
+ args_instance[SER_PORT] = PORT_MASTER_1
+ args_instance[SER_SERVERID_PROP] = SERVERID_MASTER_1
+ args_master = args_instance.copy()
+ master1.allocate(args_master)
+
+ # allocate master1 on a given deployement
+ master2 = DirSrv(verbose=False)
+ if installation2_prefix:
+ args_instance[SER_DEPLOYED_DIR] = installation2_prefix
+
+ # Args for the consumer instance
+ args_instance[SER_HOST] = HOST_MASTER_2
+ args_instance[SER_PORT] = PORT_MASTER_2
+ args_instance[SER_SERVERID_PROP] = SERVERID_MASTER_2
+ args_master = args_instance.copy()
+ master2.allocate(args_master)
+
+
+ # Get the status of the backups
+ backup_master1 = master1.checkBackupFS()
+ backup_master2 = master2.checkBackupFS()
+
+ # Get the status of the instance and restart it if it exists
+ instance_master1 = master1.exists()
+ if instance_master1:
+ master1.stop(timeout=10)
+ master1.start(timeout=10)
+
+ instance_master2 = master2.exists()
+ if instance_master2:
+ master2.stop(timeout=10)
+ master2.start(timeout=10)
+
+ if backup_master1 and backup_master2:
+ # The backups exist, assuming they are correct
+ # we just re-init the instances with them
+ if not instance_master1:
+ master1.create()
+ # Used to retrieve configuration information (dbdir, confdir...)
+ master1.open()
+
+ if not instance_master2:
+ master2.create()
+ # Used to retrieve configuration information (dbdir, confdir...)
+ master2.open()
+
+ # restore master1 from backup
+ master1.stop(timeout=10)
+ master1.restoreFS(backup_master1)
+ master1.start(timeout=10)
+
+ # restore master2 from backup
+ master2.stop(timeout=10)
+ master2.restoreFS(backup_master2)
+ master2.start(timeout=10)
+ else:
+ # We should be here only in two conditions
+ # - This is the first time a test involve master-consumer
+ # so we need to create everything
+ # - Something weird happened (instance/backup destroyed)
+ # so we discard everything and recreate all
+
+ # Remove all the backups. So even if we have a specific backup file
+ # (e.g backup_master) we clear all backups that an instance my have created
+ if backup_master1:
+ master1.clearBackupFS()
+ if backup_master2:
+ master2.clearBackupFS()
+
+ # Remove all the instances
+ if instance_master1:
+ master1.delete()
+ if instance_master2:
+ master2.delete()
+
+ # Create the instances
+ master1.create()
+ master1.open()
+ master2.create()
+ master2.open()
+
+ #
+ # Now prepare the Master-Consumer topology
+ #
+ # First Enable replication
+ master1.replica.enableReplication(suffix=SUFFIX, role=REPLICAROLE_MASTER, replicaId=REPLICAID_MASTER_1)
+ master2.replica.enableReplication(suffix=SUFFIX, role=REPLICAROLE_MASTER, replicaId=REPLICAID_MASTER_2)
+
+ # Initialize the supplier->consumer
+
+ properties = {RA_NAME: r'meTo_$host:$port',
+ RA_BINDDN: defaultProperties[REPLICATION_BIND_DN],
+ RA_BINDPW: defaultProperties[REPLICATION_BIND_PW],
+ RA_METHOD: defaultProperties[REPLICATION_BIND_METHOD],
+ RA_TRANSPORT_PROT: defaultProperties[REPLICATION_TRANSPORT]}
+ repl_agreement = master1.agreement.create(suffix=SUFFIX, host=master2.host, port=master2.port, properties=properties)
+
+ if not repl_agreement:
+ log.fatal("Fail to create a replica agreement")
+ sys.exit(1)
+
+ log.debug("%s created" % repl_agreement)
+
+ properties = {RA_NAME: r'meTo_$host:$port',
+ RA_BINDDN: defaultProperties[REPLICATION_BIND_DN],
+ RA_BINDPW: defaultProperties[REPLICATION_BIND_PW],
+ RA_METHOD: defaultProperties[REPLICATION_BIND_METHOD],
+ RA_TRANSPORT_PROT: defaultProperties[REPLICATION_TRANSPORT]}
+ master2.agreement.create(suffix=SUFFIX, host=master1.host, port=master1.port, properties=properties)
+
+ master1.agreement.init(SUFFIX, HOST_MASTER_2, PORT_MASTER_2)
+ master1.waitForReplInit(repl_agreement)
+
+ # Check replication is working fine
+ master1.add_s(Entry((TEST_REPL_DN, {
+ 'objectclass': "top person".split(),
+ 'sn': 'test_repl',
+ 'cn': 'test_repl'})))
+ loop = 0
+ while loop <= 10:
+ try:
+ ent = master2.getEntry(TEST_REPL_DN, ldap.SCOPE_BASE, "(objectclass=*)")
+ break
+ except ldap.NO_SUCH_OBJECT:
+ time.sleep(1)
+ loop += 1
+
+ # Time to create the backups
+ master1.stop(timeout=10)
+ master1.backupfile = master1.backupFS()
+ master1.start(timeout=10)
+
+ master2.stop(timeout=10)
+ master2.backupfile = master2.backupFS()
+ master2.start(timeout=10)
+
+ #
+ # Here we have two instances master and consumer
+ # with replication working. Either coming from a backup recovery
+ # or from a fresh (re)init
+ # Time to return the topology
+ return TopologyMaster1Master2(master1, master2)
+
+
+
+def _bind_manager(topology):
+ topology.master1.log.info("Bind as %s " % DN_DM)
+ topology.master1.simple_bind_s(DN_DM, PASSWORD)
+
+def _bind_normal(topology):
+ # bind as bind_entry
+ topology.master1.log.info("Bind as %s" % BIND_DN)
+ topology.master1.simple_bind_s(BIND_DN, BIND_PW)
+
+def _moddn_aci_deny_tree(topology, mod_type=None, target_from=STAGING_DN, target_to=PROD_EXCEPT_DN):
+ '''
+ It denies the access moddn_to in cn=except,cn=accounts,SUFFIX
+ '''
+ assert mod_type != None
+
+ ACI_TARGET_FROM = ""
+ ACI_TARGET_TO = ""
+ if target_from:
+ ACI_TARGET_FROM = "(target_from = \"ldap:///%s\")" % (target_from)
+ if target_to:
+ ACI_TARGET_TO = "(target_to = \"ldap:///%s\")" % (target_to)
+
+ ACI_ALLOW = "(version 3.0; acl \"Deny MODDN to prod_except\"; deny (moddn)"
+ ACI_SUBJECT = " userdn = \"ldap:///%s\";)" % BIND_DN
+ ACI_BODY = ACI_TARGET_TO + ACI_TARGET_FROM + ACI_ALLOW + ACI_SUBJECT
+ mod = [(mod_type, 'aci', ACI_BODY)]
+ #topology.master1.modify_s(SUFFIX, mod)
+ topology.master1.log.info("Add a DENY aci under %s " % PROD_EXCEPT_DN)
+ topology.master1.modify_s(PROD_EXCEPT_DN, mod)
+
+def _moddn_aci_staging_to_production(topology, mod_type=None, target_from=STAGING_DN, target_to=PRODUCTION_DN):
+ assert mod_type != None
+
+
+ ACI_TARGET_FROM = ""
+ ACI_TARGET_TO = ""
+ if target_from:
+ ACI_TARGET_FROM = "(target_from = \"ldap:///%s\")" % (target_from)
+ if target_to:
+ ACI_TARGET_TO = "(target_to = \"ldap:///%s\")" % (target_to)
+
+ ACI_ALLOW = "(version 3.0; acl \"MODDN from staging to production\"; allow (moddn)"
+ ACI_SUBJECT = " userdn = \"ldap:///%s\";)" % BIND_DN
+ ACI_BODY = ACI_TARGET_FROM + ACI_TARGET_TO + ACI_ALLOW + ACI_SUBJECT
+ mod = [(mod_type, 'aci', ACI_BODY)]
+ topology.master1.modify_s(SUFFIX, mod)
+
+def _moddn_aci_from_production_to_staging(topology, mod_type=None):
+ assert mod_type != None
+
+ ACI_TARGET = "(target_from = \"ldap:///%s\") (target_to = \"ldap:///%s\")" % (PRODUCTION_DN, STAGING_DN)
+ ACI_ALLOW = "(version 3.0; acl \"MODDN from production to staging\"; allow (moddn)"
+ ACI_SUBJECT = " userdn = \"ldap:///%s\";)" % BIND_DN
+ ACI_BODY = ACI_TARGET + ACI_ALLOW + ACI_SUBJECT
+ mod = [(mod_type, 'aci', ACI_BODY)]
+ topology.master1.modify_s(SUFFIX, mod)
+
+
+def test_ticket47553_init(topology):
+ """
+ Creates
+ - a staging DIT
+ - a production DIT
+ - add accounts in staging DIT
+ - enable ACL logging (commented for performance reason)
+
+ """
+
+ topology.master1.log.info("\n\n######################### INITIALIZATION ######################\n")
+
+ # entry used to bind with
+ topology.master1.log.info("Add %s" % BIND_DN)
+ topology.master1.add_s(Entry((BIND_DN, {
+ 'objectclass': "top person".split(),
+ 'sn': BIND_CN,
+ 'cn': BIND_CN,
+ 'userpassword': BIND_PW})))
+
+ # DIT for staging
+ topology.master1.log.info("Add %s" % STAGING_DN)
+ topology.master1.add_s(Entry((STAGING_DN, {
+ 'objectclass': "top organizationalRole".split(),
+ 'cn': STAGING_CN,
+ 'description': "staging DIT"})))
+
+ # DIT for production
+ topology.master1.log.info("Add %s" % PRODUCTION_DN)
+ topology.master1.add_s(Entry((PRODUCTION_DN, {
+ 'objectclass': "top organizationalRole".split(),
+ 'cn': PRODUCTION_CN,
+ 'description': "production DIT"})))
+
+ # DIT for production/except
+ topology.master1.log.info("Add %s" % PROD_EXCEPT_DN)
+ topology.master1.add_s(Entry((PROD_EXCEPT_DN, {
+ 'objectclass': "top organizationalRole".split(),
+ 'cn': EXCEPT_CN,
+ 'description': "production except DIT"})))
+
+ # enable acl error logging
+ #mod = [(ldap.MOD_REPLACE, 'nsslapd-errorlog-level', '128')]
+ #topology.master1.modify_s(DN_CONFIG, mod)
+ #topology.master2.modify_s(DN_CONFIG, mod)
+
+
+
+
+
+ # add dummy entries in the staging DIT
+ for cpt in range(MAX_ACCOUNTS):
+ name = "%s%d" % (NEW_ACCOUNT, cpt)
+ topology.master1.add_s(Entry(("cn=%s,%s" % (name, STAGING_DN), {
+ 'objectclass': "top person".split(),
+ 'sn': name,
+ 'cn': name})))
+
+
+def test_ticket47553_add(topology):
+ '''
+ This test case checks that the ADD operation fails (no ADD aci on production)
+ '''
+
+ topology.master1.log.info("\n\n######################### ADD (should fail) ######################\n")
+
+ _bind_normal(topology)
+
+ #
+ # First try to add an entry in production => INSUFFICIENT_ACCESS
+ #
+ try:
+ topology.master1.log.info("Try to add %s" % PRODUCTION_DN)
+ name = "%s%d" % (NEW_ACCOUNT, 0)
+ topology.master1.add_s(Entry(("cn=%s,%s" % (name, PRODUCTION_DN), {
+ 'objectclass': "top person".split(),
+ 'sn': name,
+ 'cn': name})))
+ assert 0 # this is an error, we should not be allowed to add an entry in production
+ except Exception as e:
+ topology.master1.log.info("Exception (expected): %s" % type(e).__name__)
+ assert isinstance(e, ldap.INSUFFICIENT_ACCESS)
+
+def test_ticket47553_delete(topology):
+ '''
+ This test case checks that the DEL operation fails (no 'delete' aci on production)
+ '''
+
+ topology.master1.log.info("\n\n######################### DELETE (should fail) ######################\n")
+
+ _bind_normal(topology)
+ #
+ # Second try to delete an entry in staging => INSUFFICIENT_ACCESS
+ #
+ try:
+ topology.master1.log.info("Try to delete %s" % STAGING_DN)
+ name = "%s%d" % (NEW_ACCOUNT, 0)
+ topology.master1.delete_s("cn=%s,%s" % (name, STAGING_DN))
+ assert 0 # this is an error, we should not be allowed to add an entry in production
+ except Exception as e:
+ topology.master1.log.info("Exception (expected): %s" % type(e).__name__)
+ assert isinstance(e, ldap.INSUFFICIENT_ACCESS)
+
+
+def test_ticket47553_moddn_staging_prod_0(topology):
+ '''
+ This test case MOVE entry NEW_ACCOUNT0 from staging to prod
+ target_to/target_from: equality filter
+ '''
+
+ topology.master1.log.info("\n\n######################### MOVE staging -> Prod (0) ######################\n")
+ _bind_normal(topology)
+
+ old_rdn = "cn=%s0" % NEW_ACCOUNT
+ old_dn = "%s,%s" % (old_rdn, STAGING_DN)
+ new_rdn = old_rdn
+ new_superior = PRODUCTION_DN
+
+ #
+ # Try to rename without the apropriate ACI => INSUFFICIENT_ACCESS
+ #
+ try:
+ topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
+ topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
+ assert 0
+ except AssertionError:
+ topology.master1.log.info("Exception (not really expected exception but that is fine as it fails to rename)")
+ except Exception as e:
+ topology.master1.log.info("Exception (expected): %s" % type(e).__name__)
+ assert isinstance(e, ldap.INSUFFICIENT_ACCESS)
+
+
+ # successfull MOD with the ACI
+ topology.master1.log.info("\n\n######################### MOVE to and from equality filter ######################\n")
+ _bind_manager(topology)
+ _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_ADD, target_from=STAGING_DN, target_to=PRODUCTION_DN)
+ _bind_normal(topology)
+
+ topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
+ topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
+
+ # successfull MOD with the both ACI
+ _bind_manager(topology)
+ _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_DELETE, target_from=STAGING_DN, target_to=PRODUCTION_DN)
+ _bind_normal(topology)
+
+
+def test_ticket47553_moddn_staging_prod_1(topology):
+ '''
+ This test case MOVE entry NEW_ACCOUNT1 from staging to prod
+ target_to/target_from: substring/equality filter
+ '''
+
+ topology.master1.log.info("\n\n######################### MOVE staging -> Prod (1) ######################\n")
+ _bind_normal(topology)
+
+ old_rdn = "cn=%s1" % NEW_ACCOUNT
+ old_dn = "%s,%s" % (old_rdn, STAGING_DN)
+ new_rdn = old_rdn
+ new_superior = PRODUCTION_DN
+
+ #
+ # Try to rename without the apropriate ACI => INSUFFICIENT_ACCESS
+ #
+ try:
+ topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
+ topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
+ assert 0
+ except AssertionError:
+ topology.master1.log.info("Exception (not really expected exception but that is fine as it fails to rename)")
+ except Exception as e:
+ topology.master1.log.info("Exception (expected): %s" % type(e).__name__)
+ assert isinstance(e, ldap.INSUFFICIENT_ACCESS)
+
+
+ # successfull MOD with the ACI
+ topology.master1.log.info("\n\n######################### MOVE to substring/ from equality filter ######################\n")
+ _bind_manager(topology)
+ _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_ADD, target_from=STAGING_DN, target_to=PRODUCTION_PATTERN)
+ _bind_normal(topology)
+
+
+ topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
+ topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
+
+ # successfull MOD with the both ACI
+ _bind_manager(topology)
+ _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_DELETE, target_from=STAGING_DN, target_to=PRODUCTION_PATTERN)
+ _bind_normal(topology)
+
+def test_ticket47553_moddn_staging_prod_2(topology):
+ '''
+ This test case fails to MOVE entry NEW_ACCOUNT2 from staging to prod
+ because of bad pattern
+ '''
+
+ topology.master1.log.info("\n\n######################### MOVE staging -> Prod (2) ######################\n")
+ _bind_normal(topology)
+
+ old_rdn = "cn=%s2" % NEW_ACCOUNT
+ old_dn = "%s,%s" % (old_rdn, STAGING_DN)
+ new_rdn = old_rdn
+ new_superior = PRODUCTION_DN
+
+ #
+ # Try to rename without the apropriate ACI => INSUFFICIENT_ACCESS
+ #
+ try:
+ topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
+ topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
+ assert 0
+ except AssertionError:
+ topology.master1.log.info("Exception (not really expected exception but that is fine as it fails to rename)")
+ except Exception as e:
+ topology.master1.log.info("Exception (expected): %s" % type(e).__name__)
+ assert isinstance(e, ldap.INSUFFICIENT_ACCESS)
+
+
+ # successfull MOD with the ACI
+ topology.master1.log.info("\n\n######################### MOVE to substring (BAD)/ from equality filter ######################\n")
+ _bind_manager(topology)
+ _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_ADD, target_from=STAGING_DN, target_to=BAD_PRODUCTION_PATTERN)
+ _bind_normal(topology)
+
+ try:
+ topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
+ topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
+ except AssertionError:
+ topology.master1.log.info("Exception (not really expected exception but that is fine as it fails to rename)")
+ except Exception as e:
+ topology.master1.log.info("Exception (expected): %s" % type(e).__name__)
+ assert isinstance(e, ldap.INSUFFICIENT_ACCESS)
+
+ # successfull MOD with the both ACI
+ _bind_manager(topology)
+ _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_DELETE, target_from=STAGING_DN, target_to=BAD_PRODUCTION_PATTERN)
+ _bind_normal(topology)
+
+def test_ticket47553_moddn_staging_prod_3(topology):
+ '''
+ This test case MOVE entry NEW_ACCOUNT3 from staging to prod
+ target_to/target_from: equality/substring filter
+ '''
+
+ topology.master1.log.info("\n\n######################### MOVE staging -> Prod (3) ######################\n")
+ _bind_normal(topology)
+
+ old_rdn = "cn=%s3" % NEW_ACCOUNT
+ old_dn = "%s,%s" % (old_rdn, STAGING_DN)
+ new_rdn = old_rdn
+ new_superior = PRODUCTION_DN
+
+ #
+ # Try to rename without the apropriate ACI => INSUFFICIENT_ACCESS
+ #
+ try:
+ topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
+ topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
+ assert 0
+ except AssertionError:
+ topology.master1.log.info("Exception (not really expected exception but that is fine as it fails to rename)")
+ except Exception as e:
+ topology.master1.log.info("Exception (expected): %s" % type(e).__name__)
+ assert isinstance(e, ldap.INSUFFICIENT_ACCESS)
+
+
+ # successfull MOD with the ACI
+ topology.master1.log.info("\n\n######################### MOVE to:equality filter / from substring filter ######################\n")
+ _bind_manager(topology)
+ _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_ADD, target_from=STAGING_PATTERN, target_to=PRODUCTION_DN)
+ _bind_normal(topology)
+
+
+ topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
+ topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
+
+ # successfull MOD with the both ACI
+ _bind_manager(topology)
+ _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_DELETE, target_from=STAGING_PATTERN, target_to=PRODUCTION_DN)
+ _bind_normal(topology)
+
+def test_ticket47553_moddn_staging_prod_4(topology):
+ '''
+ This test case fails to MOVE entry NEW_ACCOUNT4 from staging to prod
+ because of bad pattern
+ '''
+
+ topology.master1.log.info("\n\n######################### MOVE staging -> Prod (4) ######################\n")
+ _bind_normal(topology)
+
+ old_rdn = "cn=%s4" % NEW_ACCOUNT
+ old_dn = "%s,%s" % (old_rdn, STAGING_DN)
+ new_rdn = old_rdn
+ new_superior = PRODUCTION_DN
+
+ #
+ # Try to rename without the apropriate ACI => INSUFFICIENT_ACCESS
+ #
+ try:
+ topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
+ topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
+ assert 0
+ except AssertionError:
+ topology.master1.log.info("Exception (not really expected exception but that is fine as it fails to rename)")
+ except Exception as e:
+ topology.master1.log.info("Exception (expected): %s" % type(e).__name__)
+ assert isinstance(e, ldap.INSUFFICIENT_ACCESS)
+
+
+ # successfull MOD with the ACI
+ topology.master1.log.info("\n\n######################### MOVE to: equality filter/ from: substring (BAD) ######################\n")
+ _bind_manager(topology)
+ _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_ADD, target_from=BAD_STAGING_PATTERN, target_to=PRODUCTION_DN)
+ _bind_normal(topology)
+
+ try:
+ topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
+ topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
+ except AssertionError:
+ topology.master1.log.info("Exception (not really expected exception but that is fine as it fails to rename)")
+ except Exception as e:
+ topology.master1.log.info("Exception (expected): %s" % type(e).__name__)
+ assert isinstance(e, ldap.INSUFFICIENT_ACCESS)
+
+ # successfull MOD with the both ACI
+ _bind_manager(topology)
+ _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_DELETE, target_from=BAD_STAGING_PATTERN, target_to=PRODUCTION_DN)
+ _bind_normal(topology)
+
+def test_ticket47553_moddn_staging_prod_5(topology):
+ '''
+ This test case MOVE entry NEW_ACCOUNT5 from staging to prod
+ target_to/target_from: substring/substring filter
+ '''
+
+ topology.master1.log.info("\n\n######################### MOVE staging -> Prod (5) ######################\n")
+ _bind_normal(topology)
+
+ old_rdn = "cn=%s5" % NEW_ACCOUNT
+ old_dn = "%s,%s" % (old_rdn, STAGING_DN)
+ new_rdn = old_rdn
+ new_superior = PRODUCTION_DN
+
+ #
+ # Try to rename without the apropriate ACI => INSUFFICIENT_ACCESS
+ #
+ try:
+ topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
+ topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
+ assert 0
+ except AssertionError:
+ topology.master1.log.info("Exception (not really expected exception but that is fine as it fails to rename)")
+ except Exception as e:
+ topology.master1.log.info("Exception (expected): %s" % type(e).__name__)
+ assert isinstance(e, ldap.INSUFFICIENT_ACCESS)
+
+
+ # successfull MOD with the ACI
+ topology.master1.log.info("\n\n######################### MOVE to:substring filter / from: substring filter ######################\n")
+ _bind_manager(topology)
+ _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_ADD, target_from=STAGING_PATTERN, target_to=PRODUCTION_PATTERN)
+ _bind_normal(topology)
+
+
+ topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
+ topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
+
+ # successfull MOD with the both ACI
+ _bind_manager(topology)
+ _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_DELETE, target_from=STAGING_PATTERN, target_to=PRODUCTION_PATTERN)
+ _bind_normal(topology)
+
+def test_ticket47553_moddn_staging_prod_6(topology):
+ '''
+ This test case MOVE entry NEW_ACCOUNT6 from staging to prod
+ target_to/target_from: substring/<enmpty> filter
+ '''
+
+ topology.master1.log.info("\n\n######################### MOVE staging -> Prod (6) ######################\n")
+ _bind_normal(topology)
+
+ old_rdn = "cn=%s6" % NEW_ACCOUNT
+ old_dn = "%s,%s" % (old_rdn, STAGING_DN)
+ new_rdn = old_rdn
+ new_superior = PRODUCTION_DN
+
+ #
+ # Try to rename without the apropriate ACI => INSUFFICIENT_ACCESS
+ #
+ try:
+ topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
+ topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
+ assert 0
+ except AssertionError:
+ topology.master1.log.info("Exception (not really expected exception but that is fine as it fails to rename)")
+ except Exception as e:
+ topology.master1.log.info("Exception (expected): %s" % type(e).__name__)
+ assert isinstance(e, ldap.INSUFFICIENT_ACCESS)
+
+
+ # successfull MOD with the ACI
+ topology.master1.log.info("\n\n######################### MOVE to:substring filter / from: empty ######################\n")
+ _bind_manager(topology)
+ _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_ADD, target_from=None, target_to=PRODUCTION_PATTERN)
+ _bind_normal(topology)
+
+
+ topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
+ topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
+
+ # successfull MOD with the both ACI
+ _bind_manager(topology)
+ _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_DELETE, target_from=None, target_to=PRODUCTION_PATTERN)
+ _bind_normal(topology)
+
+def test_ticket47553_moddn_staging_prod_7(topology):
+ '''
+ This test case MOVE entry NEW_ACCOUNT7 from staging to prod
+ target_to/target_from: <empty>/substring filter
+ '''
+
+ topology.master1.log.info("\n\n######################### MOVE staging -> Prod (7) ######################\n")
+ _bind_normal(topology)
+
+ old_rdn = "cn=%s7" % NEW_ACCOUNT
+ old_dn = "%s,%s" % (old_rdn, STAGING_DN)
+ new_rdn = old_rdn
+ new_superior = PRODUCTION_DN
+
+ #
+ # Try to rename without the apropriate ACI => INSUFFICIENT_ACCESS
+ #
+ try:
+ topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
+ topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
+ assert 0
+ except AssertionError:
+ topology.master1.log.info("Exception (not really expected exception but that is fine as it fails to rename)")
+ except Exception as e:
+ topology.master1.log.info("Exception (expected): %s" % type(e).__name__)
+ assert isinstance(e, ldap.INSUFFICIENT_ACCESS)
+
+
+ # successfull MOD with the ACI
+ topology.master1.log.info("\n\n######################### MOVE to: empty/ from: substring filter ######################\n")
+ _bind_manager(topology)
+ _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_ADD, target_from=STAGING_PATTERN, target_to=None)
+ _bind_normal(topology)
+
+
+ topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
+ topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
+
+ # successfull MOD with the both ACI
+ _bind_manager(topology)
+ _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_DELETE, target_from=STAGING_PATTERN, target_to=None)
+ _bind_normal(topology)
+
+
+def test_ticket47553_moddn_staging_prod_8(topology):
+ '''
+ This test case MOVE entry NEW_ACCOUNT8 from staging to prod
+ target_to/target_from: <empty>/<empty> filter
+ '''
+
+ topology.master1.log.info("\n\n######################### MOVE staging -> Prod (8) ######################\n")
+ _bind_normal(topology)
+
+ old_rdn = "cn=%s8" % NEW_ACCOUNT
+ old_dn = "%s,%s" % (old_rdn, STAGING_DN)
+ new_rdn = old_rdn
+ new_superior = PRODUCTION_DN
+
+ #
+ # Try to rename without the apropriate ACI => INSUFFICIENT_ACCESS
+ #
+ try:
+ topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
+ topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
+ assert 0
+ except AssertionError:
+ topology.master1.log.info("Exception (not really expected exception but that is fine as it fails to rename)")
+ except Exception as e:
+ topology.master1.log.info("Exception (expected): %s" % type(e).__name__)
+ assert isinstance(e, ldap.INSUFFICIENT_ACCESS)
+
+
+ # successfull MOD with the ACI
+ topology.master1.log.info("\n\n######################### MOVE to: empty/ from: empty ######################\n")
+ _bind_manager(topology)
+ _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_ADD, target_from=None, target_to=None)
+ _bind_normal(topology)
+
+
+ topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
+ topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
+
+ # successfull MOD with the both ACI
+ _bind_manager(topology)
+ _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_DELETE, target_from=None, target_to=None)
+ _bind_normal(topology)
+
+def test_ticket47553_moddn_staging_prod_9(topology):
+ '''
+ This test case disable the 'moddn' right so a MODDN requires a 'add' right
+ to be successfull.
+ It fails to MOVE entry NEW_ACCOUNT9 from staging to prod.
+ Add a 'add' right to prod.
+ Then it succeeds to MOVE NEW_ACCOUNT9 from staging to prod.
+
+ Then enable the 'moddn' right so a MODDN requires a 'moddn' right
+ It fails to MOVE entry NEW_ACCOUNT10 from staging to prod.
+ Add a 'moddn' right to prod.
+ Then it succeeds to MOVE NEW_ACCOUNT10 from staging to prod.
+ '''
+
+ topology.master1.log.info("\n\n######################### MOVE staging -> Prod (9) ######################\n")
+
+ _bind_normal(topology)
+ old_rdn = "cn=%s9" % NEW_ACCOUNT
+ old_dn = "%s,%s" % (old_rdn, STAGING_DN)
+ new_rdn = old_rdn
+ new_superior = PRODUCTION_DN
+
+ #
+ # Try to rename without the apropriate ACI => INSUFFICIENT_ACCESS
+ #
+ try:
+ topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
+ topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
+ assert 0
+ except AssertionError:
+ topology.master1.log.info("Exception (not really expected exception but that is fine as it fails to rename)")
+ except Exception as e:
+ topology.master1.log.info("Exception (expected): %s" % type(e).__name__)
+ assert isinstance(e, ldap.INSUFFICIENT_ACCESS)
+
+ ############################################
+ # Now do tests with no support of moddn aci
+ ############################################
+ topology.master1.log.info("Disable the moddn right" )
+ _bind_manager(topology)
+ mod = [(ldap.MOD_REPLACE, CONFIG_MODDN_ACI_ATTR, 'off')]
+ topology.master1.modify_s(DN_CONFIG, mod)
+
+ # Add the moddn aci that will not be evaluated because of the config flag
+ topology.master1.log.info("\n\n######################### MOVE to and from equality filter ######################\n")
+ _bind_manager(topology)
+ _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_ADD, target_from=STAGING_DN, target_to=PRODUCTION_DN)
+ _bind_normal(topology)
+
+ # It will fail because it will test the ADD right
+ try:
+ topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
+ topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
+ assert 0
+ except AssertionError:
+ topology.master1.log.info("Exception (not really expected exception but that is fine as it fails to rename)")
+ except Exception as e:
+ topology.master1.log.info("Exception (expected): %s" % type(e).__name__)
+ assert isinstance(e, ldap.INSUFFICIENT_ACCESS)
+
+ # remove the moddn aci
+ _bind_manager(topology)
+ _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_DELETE, target_from=STAGING_DN, target_to=PRODUCTION_DN)
+ _bind_normal(topology)
+
+ #
+ # add the 'add' right to the production DN
+ # Then do a successfull moddn
+ #
+ ACI_ALLOW = "(version 3.0; acl \"ADD rights to allow moddn\"; allow (add)"
+ ACI_SUBJECT = " userdn = \"ldap:///%s\";)" % BIND_DN
+ ACI_BODY = ACI_ALLOW + ACI_SUBJECT
+
+ _bind_manager(topology)
+ mod = [(ldap.MOD_ADD, 'aci', ACI_BODY)]
+ topology.master1.modify_s(PRODUCTION_DN, mod)
+ _bind_normal(topology)
+
+ topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
+ topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
+
+ _bind_manager(topology)
+ mod = [(ldap.MOD_DELETE, 'aci', ACI_BODY)]
+ topology.master1.modify_s(PRODUCTION_DN, mod)
+ _bind_normal(topology)
+
+
+ ############################################
+ # Now do tests with support of moddn aci
+ ############################################
+ topology.master1.log.info("Enable the moddn right" )
+ _bind_manager(topology)
+ mod = [(ldap.MOD_REPLACE, CONFIG_MODDN_ACI_ATTR, 'on')]
+ topology.master1.modify_s(DN_CONFIG, mod)
+
+ topology.master1.log.info("\n\n######################### MOVE staging -> Prod (10) ######################\n")
+
+ _bind_normal(topology)
+ old_rdn = "cn=%s10" % NEW_ACCOUNT
+ old_dn = "%s,%s" % (old_rdn, STAGING_DN)
+ new_rdn = old_rdn
+ new_superior = PRODUCTION_DN
+
+ #
+ # Try to rename without the apropriate ACI => INSUFFICIENT_ACCESS
+ #
+ try:
+ topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
+ topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
+ assert 0
+ except AssertionError:
+ topology.master1.log.info("Exception (not really expected exception but that is fine as it fails to rename)")
+ except Exception as e:
+ topology.master1.log.info("Exception (expected): %s" % type(e).__name__)
+ assert isinstance(e, ldap.INSUFFICIENT_ACCESS)
+
+ #
+ # add the 'add' right to the production DN
+ # Then do a failing moddn
+ #
+ ACI_ALLOW = "(version 3.0; acl \"ADD rights to allow moddn\"; allow (add)"
+ ACI_SUBJECT = " userdn = \"ldap:///%s\";)" % BIND_DN
+ ACI_BODY = ACI_ALLOW + ACI_SUBJECT
+
+ _bind_manager(topology)
+ mod = [(ldap.MOD_ADD, 'aci', ACI_BODY)]
+ topology.master1.modify_s(PRODUCTION_DN, mod)
+ _bind_normal(topology)
+
+ try:
+ topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
+ topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
+ assert 0
+ except AssertionError:
+ topology.master1.log.info("Exception (not really expected exception but that is fine as it fails to rename)")
+ except Exception as e:
+ topology.master1.log.info("Exception (expected): %s" % type(e).__name__)
+ assert isinstance(e, ldap.INSUFFICIENT_ACCESS)
+
+ _bind_manager(topology)
+ mod = [(ldap.MOD_DELETE, 'aci', ACI_BODY)]
+ topology.master1.modify_s(PRODUCTION_DN, mod)
+ _bind_normal(topology)
+
+ # Add the moddn aci that will be evaluated because of the config flag
+ topology.master1.log.info("\n\n######################### MOVE to and from equality filter ######################\n")
+ _bind_manager(topology)
+ _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_ADD, target_from=STAGING_DN, target_to=PRODUCTION_DN)
+ _bind_normal(topology)
+
+ topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
+ topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
+
+ # remove the moddn aci
+ _bind_manager(topology)
+ _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_DELETE, target_from=STAGING_DN, target_to=PRODUCTION_DN)
+ _bind_normal(topology)
+
+def test_ticket47553_moddn_prod_staging(topology):
+ '''
+ This test checks that we can move ACCOUNT11 from staging to prod
+ but not move back ACCOUNT11 from prod to staging
+ '''
+ topology.master1.log.info("\n\n######################### MOVE staging -> Prod (11) ######################\n")
+
+ _bind_normal(topology)
+
+ old_rdn = "cn=%s11" % NEW_ACCOUNT
+ old_dn = "%s,%s" % (old_rdn, STAGING_DN)
+ new_rdn = old_rdn
+ new_superior = PRODUCTION_DN
+
+ #
+ # Try to rename without the apropriate ACI => INSUFFICIENT_ACCESS
+ #
+ try:
+ topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
+ topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
+ assert 0
+ except AssertionError:
+ topology.master1.log.info("Exception (not really expected exception but that is fine as it fails to rename)")
+ except Exception as e:
+ topology.master1.log.info("Exception (expected): %s" % type(e).__name__)
+ assert isinstance(e, ldap.INSUFFICIENT_ACCESS)
+
+
+ # successfull MOD with the ACI
+ topology.master1.log.info("\n\n######################### MOVE to and from equality filter ######################\n")
+ _bind_manager(topology)
+ _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_ADD, target_from=STAGING_DN, target_to=PRODUCTION_DN)
+ _bind_normal(topology)
+
+ topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
+ topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
+
+
+ #
+ # Now check we can not move back the entry to staging
+ old_rdn = "cn=%s11" % NEW_ACCOUNT
+ old_dn = "%s,%s" % (old_rdn, PRODUCTION_DN)
+ new_rdn = old_rdn
+ new_superior = STAGING_DN
+
+ try:
+ topology.master1.log.info("Try to move back MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
+ topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
+ assert 0
+ except AssertionError:
+ topology.master1.log.info("Exception (not really expected exception but that is fine as it fails to rename)")
+ except Exception as e:
+ topology.master1.log.info("Exception (expected): %s" % type(e).__name__)
+ assert isinstance(e, ldap.INSUFFICIENT_ACCESS)
+
+ # successfull MOD with the both ACI
+ _bind_manager(topology)
+ _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_DELETE, target_from=STAGING_DN, target_to=PRODUCTION_DN)
+ _bind_normal(topology)
+
+
+def test_ticket47553_check_repl_M2_to_M1(topology):
+ '''
+ Checks that replication is still working M2->M1, using ACCOUNT12
+ '''
+
+ topology.master1.log.info("Bind as %s (M2)" % DN_DM)
+ topology.master2.simple_bind_s(DN_DM, PASSWORD)
+
+ rdn = "cn=%s12" % NEW_ACCOUNT
+ dn = "%s,%s" % (rdn, STAGING_DN)
+
+ # First wait for the ACCOUNT19 entry being replicated on M2
+ loop = 0
+ while loop <= 10:
+ try:
+ ent = topology.master2.getEntry(dn, ldap.SCOPE_BASE, "(objectclass=*)")
+ break
+ except ldap.NO_SUCH_OBJECT:
+ time.sleep(1)
+ loop += 1
+ assert loop <= 10
+
+
+ attribute = 'description'
+ tested_value = 'Hello world'
+ mod = [(ldap.MOD_ADD, attribute, tested_value)]
+ topology.master1.log.info("Update (M2) %s (%s)" % (dn, attribute))
+ topology.master2.modify_s(dn, mod)
+
+ loop = 0
+ while loop <= 10:
+ ent = topology.master1.getEntry(dn, ldap.SCOPE_BASE, "(objectclass=*)")
+ assert ent != None
+ if ent.hasAttr(attribute) and (ent.getValue(attribute) == tested_value):
+ break
+
+ time.sleep(1)
+ loop += 1
+ assert loop < 10
+ topology.master1.log.info("Update %s (%s) replicated on M1" % (dn, attribute))
+
+def test_ticket47553_moddn_staging_prod_except(topology):
+ '''
+ This test case MOVE entry NEW_ACCOUNT13 from staging to prod
+ but fails to move entry NEW_ACCOUNT14 from staging to prod_except
+ '''
+
+ topology.master1.log.info("\n\n######################### MOVE staging -> Prod (13) ######################\n")
+ _bind_normal(topology)
+
+ old_rdn = "cn=%s13" % NEW_ACCOUNT
+ old_dn = "%s,%s" % (old_rdn, STAGING_DN)
+ new_rdn = old_rdn
+ new_superior = PRODUCTION_DN
+
+ #
+ # Try to rename without the apropriate ACI => INSUFFICIENT_ACCESS
+ #
+ try:
+ topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
+ topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
+ assert 0
+ except AssertionError:
+ topology.master1.log.info("Exception (not really expected exception but that is fine as it fails to rename)")
+ except Exception as e:
+ topology.master1.log.info("Exception (expected): %s" % type(e).__name__)
+ assert isinstance(e, ldap.INSUFFICIENT_ACCESS)
+
+
+ # successfull MOD with the ACI
+ topology.master1.log.info("\n\n######################### MOVE to and from equality filter ######################\n")
+ _bind_manager(topology)
+ _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_ADD, target_from=STAGING_DN, target_to=PRODUCTION_DN)
+ _moddn_aci_deny_tree(topology, mod_type=ldap.MOD_ADD)
+ _bind_normal(topology)
+
+ topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
+ topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
+
+ #
+ # Now try to move an entry under except
+ #
+ topology.master1.log.info("\n\n######################### MOVE staging -> Prod/Except (14) ######################\n")
+ old_rdn = "cn=%s14" % NEW_ACCOUNT
+ old_dn = "%s,%s" % (old_rdn, STAGING_DN)
+ new_rdn = old_rdn
+ new_superior = PROD_EXCEPT_DN
+ try:
+ topology.master1.log.info("Try to MODDN %s -> %s,%s" % (old_dn, new_rdn, new_superior))
+ topology.master1.rename_s(old_dn, new_rdn, newsuperior=new_superior)
+ assert 0
+ except AssertionError:
+ topology.master1.log.info("Exception (not really expected exception but that is fine as it fails to rename)")
+ except Exception as e:
+ topology.master1.log.info("Exception (expected): %s" % type(e).__name__)
+ assert isinstance(e, ldap.INSUFFICIENT_ACCESS)
+
+ # successfull MOD with the both ACI
+ _bind_manager(topology)
+ _moddn_aci_staging_to_production(topology, mod_type=ldap.MOD_DELETE, target_from=STAGING_DN, target_to=PRODUCTION_DN)
+ _moddn_aci_deny_tree(topology, mod_type=ldap.MOD_DELETE)
+ _bind_normal(topology)
+
+def test_ticket47553_final(topology):
+ topology.master1.stop(timeout=10)
+ topology.master2.stop(timeout=10)
+
+def run_isolated():
+ '''
+ run_isolated is used to run these test cases independently of a test scheduler (xunit, py.test..)
+ To run isolated without py.test, you need to
+ - edit this file and comment '@pytest.fixture' line before 'topology' function.
+ - set the installation prefix
+ - run this program
+ '''
+ global installation1_prefix
+ global installation2_prefix
+ installation1_prefix = '/home/tbordaz/install'
+ installation2_prefix = '/home/tbordaz/install'
+
+ topo = topology(True)
+ topo.master1.log.info("\n\n######################### Ticket 47553 ######################\n")
+ test_ticket47553_init(topo)
+
+
+ # Check that without appropriate aci we are not allowed to add/delete
+ test_ticket47553_add(topo)
+ test_ticket47553_delete(topo)
+
+ # tests the ACI as equality/substring filter
+ test_ticket47553_moddn_staging_prod_0(topo)
+ test_ticket47553_moddn_staging_prod_1(topo)
+ test_ticket47553_moddn_staging_prod_2(topo)
+ test_ticket47553_moddn_staging_prod_3(topo)
+ test_ticket47553_moddn_staging_prod_4(topo)
+ test_ticket47553_moddn_staging_prod_5(topo)
+
+ # tests the ACI with undefined 'target_to'/'target_from'
+ test_ticket47553_moddn_staging_prod_6(topo)
+ test_ticket47553_moddn_staging_prod_7(topo)
+ test_ticket47553_moddn_staging_prod_8(topo)
+
+ # Check we can control the behavior with nsslapd-moddn-aci
+ test_ticket47553_moddn_staging_prod_9(topo)
+
+ # Check we can move entry 'from' -> 'to' but not 'to' -> 'from'
+ test_ticket47553_moddn_prod_staging(topo)
+
+ # check replication is still working
+ test_ticket47553_check_repl_M2_to_M1(topo)
+
+ # check DENY rule is working
+ test_ticket47553_moddn_staging_prod_except(topo)
+
+ test_ticket47553_final(topo)
+
+
+
+
+if __name__ == '__main__':
+ run_isolated()
+
diff --git a/ldap/schema/01core389.ldif b/ldap/schema/01core389.ldif
index 5779d30..04043c1 100644
--- a/ldap/schema/01core389.ldif
+++ b/ldap/schema/01core389.ldif
@@ -295,6 +295,7 @@ attributeTypes: ( 2.16.840.1.113730.3.1.2300 NAME 'nsslapd-connection-nocanon' D
attributeTypes: ( 2.16.840.1.113730.3.1.2301 NAME 'nsslapd-plugin-logging' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )
attributeTypes: ( 2.16.840.1.113730.3.1.2302 NAME 'nsslapd-listen-backlog-size' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.27 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )
attributeTypes: ( 2.16.840.1.113730.3.1.2303 NAME 'nsslapd-ignore-time-skew' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )
+attributeTypes: ( 2.16.840.1.113730.3.1.2305 NAME 'nsslapd-moddn-aci' DESC 'Netscape defined attribute type' SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'Netscape Directory Server' )
#
# objectclasses
#
diff --git a/ldap/servers/plugins/acl/acl.c b/ldap/servers/plugins/acl/acl.c
index 3c1db36..f8b854c 100644
--- a/ldap/servers/plugins/acl/acl.c
+++ b/ldap/servers/plugins/acl/acl.c
@@ -282,7 +282,7 @@ acl_access_allowed(
if ( access & (ACLPB_SLAPI_ACL_WRITE_ADD | ACLPB_SLAPI_ACL_WRITE_DEL) ) {
access |= SLAPI_ACL_WRITE;
}
-
+
n_edn = slapi_entry_get_ndn ( e );
e_sdn = slapi_entry_get_sdn ( e );
@@ -290,7 +290,7 @@ acl_access_allowed(
/* No one, even the rootdn should be allowed to write to the database */
/* jcm: ReadOnly only applies to the public backends, the private ones */
/* (the DSEs) should still be writable for configuration. */
- if ( access & ( SLAPI_ACL_WRITE | SLAPI_ACL_ADD | SLAPI_ACL_DELETE )) {
+ if ( access & ( SLAPI_ACL_WRITE | SLAPI_ACL_ADD | SLAPI_ACL_DELETE | SLAPI_ACL_MODDN)) {
int be_readonly, privateBackend;
Slapi_Backend *be;
@@ -351,6 +351,20 @@ acl_access_allowed(
TNF_PROBE_0_DEBUG(acl_aclpbinit_start,"ACL","");
acl_init_aclpb ( pb, aclpb, clientDn, 0 );
TNF_PROBE_0_DEBUG(acl_aclpbinit_end,"ACL","");
+
+ if ( access & SLAPI_ACL_MODDN) {
+ /* with MODDN, the entry 'e' is the destination entry.
+ * This destination entry will be checked against a possible 'target_to'
+ * The source entry will be checked against a possible 'target_from'.
+ * 'e' will be given down to acl_resource_match_aci, so no pb on this side.
+ * For the source entry we need to keep its dn into the aclpb.
+ */
+ entry_address *old_addr;
+ slapi_pblock_get(pb, SLAPI_TARGET_ADDRESS, &old_addr);
+ aclpb->aclpb_moddn_source_sdn = old_addr->sdn;
+
+ }
+
/* Here we mean if "I am trying to add/delete "myself" to a group, etc." We
* basically just want to see if the value matches the DN of the user that
@@ -767,48 +781,95 @@ print_access_control_summary( char *source, int ret_val, char *clientDn,
if ( aclpb->aclpb_authorization_sdn != NULL ) {
- proxy_user =
- (char *)(slapi_sdn_get_ndn(aclpb->aclpb_authorization_sdn)?
- slapi_sdn_get_ndn(aclpb->aclpb_authorization_sdn):
- null_user);
-
- slapi_log_error(loglevel, plugin_name,
- "conn=%" NSPRIu64 " op=%d (%s): %s %s on entry(%s).attr(%s) to proxy (%s)"
- ": %s\n",
- (long long unsigned int)op->o_connid, op->o_opid,
- source,
- access_status,
- right,
- edn,
- attr ? attr: "NULL",
- proxy_user,
- acl_info[0] ? acl_info : access_reason);
+ proxy_user =
+ (char *)(slapi_sdn_get_ndn(aclpb->aclpb_authorization_sdn)?
+ slapi_sdn_get_ndn(aclpb->aclpb_authorization_sdn):
+ null_user);
+ if (strcasecmp(right, access_str_moddn) == 0) {
+ slapi_log_error(loglevel, plugin_name,
+ "conn=%" NSPRIu64 " op=%d (%s): %s %s on entry(%s).attr(%s) [from %s] to proxy (%s)"
+ ": %s\n",
+ (long long unsigned int)op->o_connid, op->o_opid,
+ source,
+ access_status,
+ right,
+ edn,
+ attr ? attr: "NULL",
+ aclpb->aclpb_moddn_source_sdn ? slapi_sdn_get_dn(aclpb->aclpb_moddn_source_sdn) : "NULL", /* from entry - stored in pblock */
+ proxy_user,
+ acl_info[0] ? acl_info : access_reason);
+
+ } else {
+ slapi_log_error(loglevel, plugin_name,
+ "conn=%" NSPRIu64 " op=%d (%s): %s %s on entry(%s).attr(%s) to proxy (%s)"
+ ": %s\n",
+ (long long unsigned int)op->o_connid, op->o_opid,
+ source,
+ access_status,
+ right,
+ edn,
+ attr ? attr: "NULL",
+ proxy_user,
+ acl_info[0] ? acl_info : access_reason);
+ }
} else {
- proxy_user = null_user;
- slapi_log_error(loglevel, plugin_name,
- "conn=%" NSPRIu64 " op=%d (%s): %s %s on entry(%s).attr(%s) to proxy (%s)"
- ": %s\n",
- (long long unsigned int)op->o_connid, op->o_opid,
- source,
- access_status,
- right,
- edn,
- attr ? attr: "NULL",
- proxy_user,
- acl_info[0] ? acl_info : access_reason);
+ proxy_user = null_user;
+ if (strcasecmp(right, access_str_moddn) == 0) {
+ slapi_log_error(loglevel, plugin_name,
+ "conn=%" NSPRIu64 " op=%d (%s): %s %s on entry(%s).attr(%s) [from %s] to proxy (%s)"
+ ": %s\n",
+ (long long unsigned int)op->o_connid, op->o_opid,
+ source,
+ access_status,
+ right,
+ edn,
+ attr ? attr: "NULL",
+ aclpb->aclpb_moddn_source_sdn ? slapi_sdn_get_dn(aclpb->aclpb_moddn_source_sdn) : "NULL", /* from entry - stored in pblock */
+ proxy_user,
+ acl_info[0] ? acl_info : access_reason);
+
+ } else {
+ slapi_log_error(loglevel, plugin_name,
+ "conn=%" NSPRIu64 " op=%d (%s): %s %s on entry(%s).attr(%s) to proxy (%s)"
+ ": %s\n",
+ (long long unsigned int)op->o_connid, op->o_opid,
+ source,
+ access_status,
+ right,
+ edn,
+ attr ? attr: "NULL",
+ proxy_user,
+ acl_info[0] ? acl_info : access_reason);
+ }
}
- } else{
- slapi_log_error(loglevel, plugin_name,
- "conn=%" NSPRIu64 " op=%d (%s): %s %s on entry(%s).attr(%s) to %s"
- ": %s\n",
- (long long unsigned int)op->o_connid, op->o_opid,
- source,
- access_status,
- right,
- edn,
- attr ? attr: "NULL",
- real_user,
- acl_info[0] ? acl_info : access_reason);
+ } else {
+ if (strcasecmp(right, access_str_moddn) == 0) {
+ slapi_log_error(loglevel, plugin_name,
+ "conn=%" NSPRIu64 " op=%d (%s): %s %s on entry(%s).attr(%s) [from %s] to %s"
+ ": %s\n",
+ (long long unsigned int)op->o_connid, op->o_opid,
+ source,
+ access_status,
+ right,
+ edn,
+ attr ? attr: "NULL",
+ aclpb->aclpb_moddn_source_sdn ? slapi_sdn_get_dn(aclpb->aclpb_moddn_source_sdn) : "NULL", /* from entry - stored in pblock */
+ real_user,
+ acl_info[0] ? acl_info : access_reason);
+
+ } else {
+ slapi_log_error(loglevel, plugin_name,
+ "conn=%" NSPRIu64 " op=%d (%s): %s %s on entry(%s).attr(%s) to %s"
+ ": %s\n",
+ (long long unsigned int)op->o_connid, op->o_opid,
+ source,
+ access_status,
+ right,
+ edn,
+ attr ? attr: "NULL",
+ real_user,
+ acl_info[0] ? acl_info : access_reason);
+ }
}
@@ -2006,7 +2067,7 @@ acl__scan_for_acis(Acl_PBlock *aclpb, int *err)
* None.
*
**************************************************************************/
-#define ACL_RIGHTS_TARGETATTR_NOT_NEEDED ( SLAPI_ACL_ADD | SLAPI_ACL_DELETE | SLAPI_ACL_PROXY)
+#define ACL_RIGHTS_TARGETATTR_NOT_NEEDED ( SLAPI_ACL_ADD | SLAPI_ACL_DELETE | SLAPI_ACL_PROXY | SLAPI_ACL_MODDN)
static int
acl__resource_match_aci( Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *a_matched)
{
@@ -2093,7 +2154,108 @@ acl__resource_match_aci( Acl_PBlock *aclpb, aci_t *aci, int skip_attrEval, int *
matches = (dn_matched ? ACL_TRUE: ACL_FALSE);
}
}
-
+
+ /* No need to look further */
+ if (matches == ACL_FALSE) {
+ goto acl__resource_match_aci_EXIT;
+ }
+
+ if ((aci->aci_type & ACI_TARGET_MODDN) && (res_right & SLAPI_ACL_MODDN) && (aclpb->aclpb_curr_entry_sdn)) {
+ char *avaType;
+ struct berval *avaValue;
+ char logbuf[1024];
+
+ /* We are evaluating the moddn permission.
+ * The aci contains target_to and target_from
+ *
+ * target_to filter must be checked against the resource ndn that was stored in
+ * aclpb->aclpb_curr_entry_sdn
+ *
+ * target_from filter must be check against the entry ndn that is in aclpb->aclpb_moddn_source_sdn
+ * (sdn was stored in the pblock)
+ */
+ if (aci->target_to) {
+ f = aci->target_to;
+ dn_matched = ACL_TRUE;
+
+ /* Now check if the filter is a simple or substring filter */
+ if (aci->aci_type & ACI_TARGET_MODDN_TO_PATTERN) {
+ /* This is a filter with substring
+ * e.g. ldap:///uid=*,cn=accounts,dc=example,dc=com
+ */
+ slapi_log_error( SLAPI_LOG_ACL, plugin_name, "moddn target_to substring: %s\n",
+ slapi_filter_to_string(f, logbuf, sizeof(logbuf)));
+ if ((rv = acl_match_substring(f, (char *) res_ndn, 0 /* match suffix */)) != ACL_TRUE) {
+ dn_matched = ACL_FALSE;
+ if (rv == ACL_ERR) {
+ slapi_log_error(SLAPI_LOG_ACL, plugin_name,
+ "acl__resource_match_aci:pattern err\n");
+ matches = ACL_FALSE;
+ goto acl__resource_match_aci_EXIT;
+ }
+ }
+ } else {
+ /* This is a filter without substring
+ * e.g. ldap:///cn=accounts,dc=example,dc=com
+ */
+ slapi_log_error( SLAPI_LOG_ACL, plugin_name, "moddn target_to: %s\n",
+ slapi_filter_to_string(f, logbuf, sizeof(logbuf)));
+ slapi_filter_get_ava(f, &avaType, &avaValue);
+
+ if (!slapi_dn_issuffix(res_ndn, avaValue->bv_val)) {
+ dn_matched = ACL_FALSE;
+ }
+
+ }
+ if (aci->aci_type & ACI_TARGET_NOT) {
+ matches = (dn_matched ? ACL_FALSE : ACL_TRUE);
+ } else {
+ matches = (dn_matched ? ACL_TRUE : ACL_FALSE);
+ }
+ } /* target_to */
+
+ if ((matches == ACL_TRUE) && (aci->target_from) && aclpb->aclpb_moddn_source_sdn) {
+ f = aci->target_from;
+ dn_matched = ACL_TRUE;
+ slapi_filter_get_ava ( f, &avaType, &avaValue );
+
+ /* Now check if the filter is a simple or substring filter */
+ if (aci->aci_type & ACI_TARGET_MODDN_FROM_PATTERN) {
+ /* This is a filter with substring
+ * e.g. ldap:///uid=*,cn=accounts,dc=example,dc=com
+ */
+ slapi_log_error( SLAPI_LOG_ACL, plugin_name, "moddn target_from substring: %s\n",
+ slapi_filter_to_string(f, logbuf, sizeof(logbuf)));
+ if ((rv = acl_match_substring(f, (char *) slapi_sdn_get_dn(aclpb->aclpb_moddn_source_sdn), 0 /* match suffix */)) != ACL_TRUE) {
+ dn_matched = ACL_FALSE;
+ if (rv == ACL_ERR) {
+ slapi_log_error(SLAPI_LOG_ACL, plugin_name,
+ "acl__resource_match_aci:pattern err\n");
+ matches = ACL_FALSE;
+ goto acl__resource_match_aci_EXIT;
+ }
+ }
+
+ } else {
+ /* This is a filter without substring
+ * e.g. ldap:///cn=accounts,dc=example,dc=com
+ */
+ slapi_log_error( SLAPI_LOG_ACL, plugin_name, "moddn target_from: %s\n",
+ slapi_filter_to_string(f, logbuf, sizeof(logbuf)));
+ if (!slapi_dn_issuffix(slapi_sdn_get_dn(aclpb->aclpb_moddn_source_sdn), avaValue->bv_val)) {
+ dn_matched = ACL_FALSE;
+ }
+
+ }
+
+ if (aci->aci_type & ACI_TARGET_NOT) {
+ matches = (dn_matched ? ACL_FALSE : ACL_TRUE);
+ } else {
+ matches = (dn_matched ? ACL_TRUE: ACL_FALSE);
+ }
+ }
+ }
+
/* No need to look further */
if (matches == ACL_FALSE) {
goto acl__resource_match_aci_EXIT;
diff --git a/ldap/servers/plugins/acl/acl.h b/ldap/servers/plugins/acl/acl.h
index 1a05e1f..2631ee9 100644
--- a/ldap/servers/plugins/acl/acl.h
+++ b/ldap/servers/plugins/acl/acl.h
@@ -117,6 +117,8 @@ static char* const aci_targetdn = "target";
static char* const aci_targetattr = "targetattr";
static char* const aci_targetattrfilters = "targattrfilters";
static char* const aci_targetfilter = "targetfilter";
+static char* const aci_target_to = "target_to";
+static char* const aci_target_from = "target_from";
static char* const LDAP_URL_prefix_core = "ldap://";
static char* const LDAPS_URL_prefix_core = "ldaps://";
@@ -132,6 +134,7 @@ static char* const access_str_delete = "delete";
static char* const access_str_add = "add";
static char* const access_str_selfwrite = "selfwrite";
static char* const access_str_proxy = "proxy";
+static char* const access_str_moddn = "moddn";
#define ACL_INIT_ATTR_ARRAY 5
@@ -256,24 +259,27 @@ typedef struct aci {
**
*/
-#define ACI_TARGET_MACRO_DN (int)0x000001
-#define ACI_TARGET_FILTER_MACRO_DN (int)0x000002
-#define ACI_TARGET_DN (int)0x000100 /* target has DN */
-#define ACI_TARGET_ATTR (int)0x000200 /* target is an attr */
-#define ACI_TARGET_PATTERN (int)0x000400 /* target has some patt */
-#define ACI_TARGET_FILTER (int)0x000800 /* target has a filter */
-#define ACI_ACLTXT (int)0x001000 /* ACI has text only */
-#define ACI_TARGET_NOT (int)0x002000 /* it's a != */
-#define ACI_TARGET_ATTR_NOT (int)0x004000 /* It's a != manager */
-#define ACI_TARGET_FILTER_NOT (int)0x008000 /* It's a != filter */
-#define ACI_UNUSED2 (int)0x010000 /* Unused */
-#define ACI_HAS_ALLOW_RULE (int)0x020000 /* allow (...) */
-#define ACI_HAS_DENY_RULE (int)0x040000 /* deny (...) */
-#define ACI_CONTAIN_NOT_USERDN (int)0x080000 /* userdn != blah */
-#define ACI_TARGET_ATTR_ADD_FILTERS (int)0x100000
-#define ACI_TARGET_ATTR_DEL_FILTERS (int)0x200000
-#define ACI_CONTAIN_NOT_GROUPDN (int)0x400000 /* groupdn != blah */
-#define ACI_CONTAIN_NOT_ROLEDN (int)0x800000
+#define ACI_TARGET_MACRO_DN (int)0x0000001
+#define ACI_TARGET_FILTER_MACRO_DN (int)0x0000002
+#define ACI_TARGET_DN (int)0x0000100 /* target has DN */
+#define ACI_TARGET_ATTR (int)0x0000200 /* target is an attr */
+#define ACI_TARGET_PATTERN (int)0x0000400 /* target has some patt */
+#define ACI_TARGET_FILTER (int)0x0000800 /* target has a filter */
+#define ACI_ACLTXT (int)0x0001000 /* ACI has text only */
+#define ACI_TARGET_NOT (int)0x0002000 /* it's a != */
+#define ACI_TARGET_ATTR_NOT (int)0x0004000 /* It's a != manager */
+#define ACI_TARGET_FILTER_NOT (int)0x0008000 /* It's a != filter */
+#define ACI_UNUSED2 (int)0x0010000 /* Unused */
+#define ACI_HAS_ALLOW_RULE (int)0x0020000 /* allow (...) */
+#define ACI_HAS_DENY_RULE (int)0x0040000 /* deny (...) */
+#define ACI_CONTAIN_NOT_USERDN (int)0x0080000 /* userdn != blah */
+#define ACI_TARGET_ATTR_ADD_FILTERS (int)0x0100000
+#define ACI_TARGET_ATTR_DEL_FILTERS (int)0x0200000
+#define ACI_CONTAIN_NOT_GROUPDN (int)0x0400000 /* groupdn != blah */
+#define ACI_CONTAIN_NOT_ROLEDN (int)0x0800000
+#define ACI_TARGET_MODDN (int)0x1000000
+#define ACI_TARGET_MODDN_FROM_PATTERN (int)0x2000000
+#define ACI_TARGET_MODDN_TO_PATTERN (int)0x4000000
int aci_access;
@@ -320,6 +326,8 @@ typedef struct aci {
struct slapi_filter *targetFilter; /* Target has a filter */
Targetattrfilter **targetAttrAddFilters;
Targetattrfilter **targetAttrDelFilters;
+ Slapi_Filter *target_to; /* Target is the destination DN of moddn */
+ Slapi_Filter *target_from; /* Target is the source DN of moddn */
char *aclName; /* ACL name */
struct ACLListHandle *aci_handle; /*handle of the ACL */
aciMacro *aci_macro;
@@ -520,6 +528,9 @@ struct acl_pblock {
Slapi_Entry *aclpb_filter_test_entry; /* Scratch entry */
aci_t *aclpb_curr_aci;
char *aclpb_Evalattr; /* The last attr evaluated */
+
+ /* Source entry (MODDN) */
+ Slapi_DN *aclpb_moddn_source_sdn; /* This is a pointer into the pb, do not free it */
/* Plist and eval info */
ACLEvalHandle_t *aclpb_acleval; /* acleval handle for evaluation */
diff --git a/ldap/servers/plugins/acl/aclanom.c b/ldap/servers/plugins/acl/aclanom.c
index 1e68f22..d46b498 100644
--- a/ldap/servers/plugins/acl/aclanom.c
+++ b/ldap/servers/plugins/acl/aclanom.c
@@ -544,18 +544,36 @@ aclanom_match_profile (Slapi_PBlock *pb, struct acl_pblock *aclpb, Slapi_Entry *
if ( result == LDAP_SUCCESS) {
const char *aci_ndn;
aci_ndn = slapi_sdn_get_ndn (acl_anom_profile->anom_targetinfo[i].anom_target);
-
- slapi_log_error(loglevel, plugin_name,
- "conn=%" NSPRIu64 " op=%d: Allow access on entry(%s).attr(%s) to anonymous: acidn=\"%s\"\n",
- (long long unsigned int)op->o_connid, op->o_opid,
- ndn,
- attr ? attr:"NULL",
- aci_ndn);
+ if (access & SLAPI_ACL_MODDN) {
+ slapi_log_error(loglevel, plugin_name,
+ "conn=%" NSPRIu64 " op=%d: Allow access on entry(%s).attr(%s) (from %s) to anonymous: acidn=\"%s\"\n",
+ (long long unsigned int)op->o_connid, op->o_opid,
+ ndn,
+ attr ? attr:"NULL",
+ aclpb->aclpb_moddn_source_sdn ? slapi_sdn_get_dn(aclpb->aclpb_moddn_source_sdn) : "NULL",
+ aci_ndn);
+
+ } else {
+ slapi_log_error(loglevel, plugin_name,
+ "conn=%" NSPRIu64 " op=%d: Allow access on entry(%s).attr(%s) to anonymous: acidn=\"%s\"\n",
+ (long long unsigned int)op->o_connid, op->o_opid,
+ ndn,
+ attr ? attr:"NULL",
+ aci_ndn);
+ }
} else {
- slapi_log_error(loglevel, plugin_name,
- "conn=%" NSPRIu64 " op=%d: Deny access on entry(%s).attr(%s) to anonymous\n",
- (long long unsigned int)op->o_connid, op->o_opid,
- ndn, attr ? attr:"NULL" );
+ if (access & SLAPI_ACL_MODDN) {
+ slapi_log_error(loglevel, plugin_name,
+ "conn=%" NSPRIu64 " op=%d: Deny access on entry(%s).attr(%s) (from %s) to anonymous\n",
+ (long long unsigned int)op->o_connid, op->o_opid,
+ ndn, attr ? attr:"NULL" ,
+ aclpb->aclpb_moddn_source_sdn ? slapi_sdn_get_dn(aclpb->aclpb_moddn_source_sdn) : "NULL");
+ } else {
+ slapi_log_error(loglevel, plugin_name,
+ "conn=%" NSPRIu64 " op=%d: Deny access on entry(%s).attr(%s) to anonymous\n",
+ (long long unsigned int)op->o_connid, op->o_opid,
+ ndn, attr ? attr:"NULL" );
+ }
}
}
diff --git a/ldap/servers/plugins/acl/acleffectiverights.c b/ldap/servers/plugins/acl/acleffectiverights.c
index dc22451..b9e2055 100644
--- a/ldap/servers/plugins/acl/acleffectiverights.c
+++ b/ldap/servers/plugins/acl/acleffectiverights.c
@@ -481,6 +481,13 @@ _ger_get_entry_rights (
}
slapi_rdn_free ( &rdn );
+ if (acl_access_allowed(gerpb, e, NULL, NULL, SLAPI_ACL_MODDN) == LDAP_SUCCESS) {
+ slapi_log_error (SLAPI_LOG_ACL, plugin_name,
+ "_ger_get_entry_rights: SLAPI_ACL_MODDN %s\n", slapi_entry_get_ndn (e) );
+ /* n - rename e */
+ entryrights |= SLAPI_ACL_MODDN;
+ _append_gerstr(gerstr, gerstrsize, gerstrcap, "n", NULL);
+ }
if ( entryrights == 0 )
{
_append_gerstr(gerstr, gerstrsize, gerstrcap, "none", NULL);
diff --git a/ldap/servers/plugins/acl/aclparse.c b/ldap/servers/plugins/acl/aclparse.c
index 9c26fc7..ae4f2d5 100644
--- a/ldap/servers/plugins/acl/aclparse.c
+++ b/ldap/servers/plugins/acl/aclparse.c
@@ -254,6 +254,9 @@ __aclp__parse_aci(char *str, aci_t *aci_item, char **errbuf)
int targetdnlen = strlen (aci_targetdn);
int tfilterlen = strlen(aci_targetfilter);
int targetattrfilterslen = strlen(aci_targetattrfilters);
+ int target_to_len = strlen(aci_target_to);
+ int target_from_len = strlen(aci_target_from);
+ PRBool is_target_to;
__acl_strip_leading_space( &str );
@@ -348,7 +351,72 @@ __aclp__parse_aci(char *str, aci_t *aci_item, char **errbuf)
/* save the filter string */
aci_item->targetFilterStr = tmpstr;
- } else if (strncmp(str, aci_targetdn, targetdnlen) == 0) {
+ } else if ((strncmp(str, aci_target_to, target_to_len) == 0) || (strncmp(str, aci_target_from, target_from_len) == 0)) {
+ /* This is important to make this test before aci_targetdn
+ * because aci_targetdn also match aci_target_to/aci_target_from
+ * */
+ char *tstr = NULL;
+ size_t LDAP_URL_prefix_len = 0;
+ size_t tmplen = 0;
+
+ /* Keep a copy of the target attr */
+ type = ACI_TARGET_MODDN;
+ if (strncmp(str, aci_target_to, target_to_len) == 0) {
+ if (aci_item->target_to) {
+ return (ACL_SYNTAX_ERR);
+ }
+ is_target_to = PR_TRUE;
+ } else {
+ if (aci_item->target_from) {
+ return (ACL_SYNTAX_ERR);
+ }
+ is_target_to = PR_FALSE;
+ }
+ if ( (s = strstr( str, "!=" )) != NULL ) {
+ type |= ACI_TARGET_NOT;
+ strncpy(s, " ", 1);
+ }
+ if ( (s = strchr( str, '=' )) != NULL ) {
+ value = s + 1;
+ __acl_strip_leading_space(&value);
+ __acl_strip_trailing_space(value);
+ len = strlen ( value );
+ /* strip double quotes */
+ if (*value == '"' && value[len-1] == '"') {
+ value[len-1] = '\0';
+ value++;
+ }
+ __acl_strip_leading_space(&value);
+ } else {
+ return ( ACL_SYNTAX_ERR );
+ }
+ if (0 ==
+ strncasecmp(value, LDAP_URL_prefix, strlen(LDAP_URL_prefix))) {
+ LDAP_URL_prefix_len = strlen(LDAP_URL_prefix);
+ } else if (0 == strncasecmp(value, LDAPS_URL_prefix,
+ strlen(LDAPS_URL_prefix))) {
+ LDAP_URL_prefix_len = strlen(LDAPS_URL_prefix);
+ } else {
+ return ( ACL_SYNTAX_ERR );
+ }
+
+ value += LDAP_URL_prefix_len;
+ rv = slapi_dn_normalize_case_ext(value, 0, &tmpstr, &tmplen);
+ if (rv < 0) {
+ return ACL_SYNTAX_ERR;
+ } else if (rv == 0) { /* value passed in; not null terminated */
+ *(tmpstr + tmplen) = '\0';
+ }
+
+ /* Now prepare the filter */
+ if (strncmp(str, aci_target_to, target_to_len) == 0) {
+ tstr = slapi_ch_smprintf("(%s=%s)", aci_target_to, tmpstr);
+ } else {
+ tstr = slapi_ch_smprintf("(%s=%s)", aci_target_from, tmpstr);
+ }
+ f = slapi_str2filter ( tstr );
+ slapi_ch_free_string ( &tstr );
+ } else if (strncmp(str, aci_targetdn, targetdnlen) == 0) {
char *tstr = NULL;
size_t LDAP_URL_prefix_len = 0;
size_t tmplen = 0;
@@ -407,7 +475,7 @@ __aclp__parse_aci(char *str, aci_t *aci_item, char **errbuf)
f = slapi_str2filter ( tstr );
}
slapi_ch_free_string ( &tstr );
- } else {
+ } else {
/* did start with a 't' but was not a recognsied keyword */
return(ACL_SYNTAX_ERR);
}
@@ -419,7 +487,7 @@ __aclp__parse_aci(char *str, aci_t *aci_item, char **errbuf)
*/
if (f == NULL) {
/* The following types require a filter to have been created */
- if (type & ACI_TARGET_DN)
+ if (type & (ACI_TARGET_DN | ACI_TARGET_MODDN))
return ACL_TARGET_FILTER_ERR;
else if (type & ACI_TARGET_FILTER)
return ACL_TARGETFILTER_ERR;
@@ -427,16 +495,23 @@ __aclp__parse_aci(char *str, aci_t *aci_item, char **errbuf)
int filterChoice;
filterChoice = slapi_filter_get_choice ( f );
- if ( (type & ACI_TARGET_DN) &&
+ if ( (type & (ACI_TARGET_DN | ACI_TARGET_MODDN)) &&
( filterChoice == LDAP_FILTER_PRESENT)) {
slapi_log_error(SLAPI_LOG_ACL, plugin_name,
"acl__parse_aci: Unsupported filter type:%d\n", filterChoice);
return(ACL_SYNTAX_ERR);
} else if (( filterChoice == LDAP_FILTER_SUBSTRINGS) &&
(type & ACI_TARGET_DN)) {
- type &= ~ACI_TARGET_DN;
+ type &= ~ACI_TARGET_DN;
type |= ACI_TARGET_PATTERN;
- }
+ } else if (( filterChoice == LDAP_FILTER_SUBSTRINGS) &&
+ (type & ACI_TARGET_MODDN)) {
+ if (is_target_to) {
+ type |= ACI_TARGET_MODDN_TO_PATTERN;
+ } else {
+ type |= ACI_TARGET_MODDN_FROM_PATTERN;
+ }
+ }
}
if ((type & ACI_TARGET_DN) ||
@@ -459,7 +534,29 @@ __aclp__parse_aci(char *str, aci_t *aci_item, char **errbuf)
} else {
aci_item->targetFilter = f;
}
- }
+ } else if (type & ACI_TARGET_MODDN) {
+ if (is_target_to) {
+ if (aci_item->target_to) {
+ /* There is something already. ERROR */
+ slapi_log_error(SLAPI_LOG_ACL, plugin_name,
+ "Multiple targets (target_to) in the ACL syntax\n");
+ slapi_filter_free(f, 1);
+ return(ACL_SYNTAX_ERR);
+ } else {
+ aci_item->target_to = f;
+ }
+ } else {
+ if (aci_item->target_from) {
+ /* There is something already. ERROR */
+ slapi_log_error(SLAPI_LOG_ACL, plugin_name,
+ "Multiple targets (target_from) in the ACL syntax\n");
+ slapi_filter_free(f, 1);
+ return(ACL_SYNTAX_ERR);
+ } else {
+ aci_item->target_from = f;
+ }
+ }
+ }
break; /* 't' */
default:
/* Here the keyword did not start with 'v' ot 't' so error */
@@ -1346,6 +1443,8 @@ static int get_acl_rights_as_int( char * strValue)
return (SLAPI_ACL_SELF | SLAPI_ACL_WRITE);
else if (strcasecmp (strValue, "all") == 0 )
return SLAPI_ACL_ALL;
+ else if (strcasecmp (strValue, "moddn") == 0)
+ return SLAPI_ACL_MODDN;
else
return -1; /* error */
}
@@ -1389,7 +1488,9 @@ acl_access2str(int access)
return access_str_write;
} else if (access & SLAPI_ACL_PROXY ) {
return access_str_proxy;
- }
+ } else if (access & SLAPI_ACL_MODDN) {
+ return access_str_moddn;
+ }
return NULL;
}
diff --git a/ldap/servers/plugins/acl/aclplugin.c b/ldap/servers/plugins/acl/aclplugin.c
index a5ce149..ce87327 100644
--- a/ldap/servers/plugins/acl/aclplugin.c
+++ b/ldap/servers/plugins/acl/aclplugin.c
@@ -393,7 +393,7 @@ acl_access_allowed_main ( Slapi_PBlock *pb, Slapi_Entry *e, char **attrs,
/* generate the appropriate error message */
if ( ( rc != LDAP_SUCCESS ) && errbuf &&
( ACLPLUGIN_ACCESS_GET_EFFECTIVE_RIGHTS != flags ) &&
- ( access & ( SLAPI_ACL_WRITE | SLAPI_ACL_ADD | SLAPI_ACL_DELETE ))) {
+ ( access & ( SLAPI_ACL_WRITE | SLAPI_ACL_ADD | SLAPI_ACL_DELETE | SLAPI_ACL_MODDN ))) {
char *edn = slapi_entry_get_dn ( e );
diff --git a/ldap/servers/plugins/acl/aclutil.c b/ldap/servers/plugins/acl/aclutil.c
index 1b8bc12..e865a95 100644
--- a/ldap/servers/plugins/acl/aclutil.c
+++ b/ldap/servers/plugins/acl/aclutil.c
@@ -475,7 +475,10 @@ acl_gen_err_msg(int access, char *edn, char *attr, char **errbuf)
} else if ( access & SLAPI_ACL_DELETE ) {
line = PR_smprintf(
"Insufficient 'delete' privilege to delete the entry '%s'.\n",edn);
- }
+ } else if ( access & SLAPI_ACL_MODDN ) {
+ line = PR_smprintf(
+ "Insufficient 'moddn' privilege to move an entry to '%s'.\n",edn);
+ }
aclutil_str_append(errbuf, line );
if (line) {
diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
index 09f1cea..f528b07 100644
--- a/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
+++ b/ldap/servers/slapd/back-ldbm/ldbm_modrdn.c
@@ -121,6 +121,7 @@ ldbm_back_modrdn( Slapi_PBlock *pb )
int opreturn = 0;
int free_modrdn_existing_entry = 0;
int not_an_error = 0;
+ int support_moddn_aci;
/* sdn & parentsdn need to be initialized before "goto *_return" */
slapi_sdn_init(&dn_newdn);
@@ -143,6 +144,11 @@ ldbm_back_modrdn( Slapi_PBlock *pb )
return( -1 );
}
+ /* In case of support of 'moddn' permission in aci, this permission will
+ * be tested rather than the SLAPI_ACL_ADD
+ */
+ support_moddn_aci = config_get_moddn_aci();
+
/* dblayer_txn_init needs to be called before "goto error_return" */
dblayer_txn_init(li,&txn);
/* the calls to perform searches require the parent txn if any
@@ -594,12 +600,22 @@ ldbm_back_modrdn( Slapi_PBlock *pb )
}
else
{
- ldap_result_code= plugin_call_acl_plugin (pb, newparententry->ep_entry, NULL, NULL, SLAPI_ACL_ADD, ACLPLUGIN_ACCESS_DEFAULT, &errbuf );
- if ( ldap_result_code != LDAP_SUCCESS )
- {
- ldap_result_message= errbuf;
- LDAPDebug( LDAP_DEBUG_TRACE, "No access to new superior.\n", 0, 0, 0 );
- goto error_return;
+ if (support_moddn_aci) {
+ /* aci permission requires 'moddn' right to allow a MODDN */
+ ldap_result_code = plugin_call_acl_plugin(pb, newparententry->ep_entry, NULL, NULL, SLAPI_ACL_MODDN, ACLPLUGIN_ACCESS_DEFAULT, &errbuf);
+ if (ldap_result_code != LDAP_SUCCESS) {
+ ldap_result_message = errbuf;
+ LDAPDebug(LDAP_DEBUG_TRACE, "No 'moddn' access to new superior.\n", 0, 0, 0);
+ goto error_return;
+ }
+ } else {
+ /* aci permission requires 'add' right to allow a MODDN (old style) */
+ ldap_result_code = plugin_call_acl_plugin (pb, newparententry->ep_entry, NULL, NULL, SLAPI_ACL_ADD, ACLPLUGIN_ACCESS_DEFAULT, &errbuf );
+ if (ldap_result_code != LDAP_SUCCESS) {
+ ldap_result_message = errbuf;
+ LDAPDebug(LDAP_DEBUG_TRACE, "No 'add' access to new superior.\n", 0, 0, 0);
+ goto error_return;
+ }
}
}
@@ -641,16 +657,33 @@ ldbm_back_modrdn( Slapi_PBlock *pb )
ldap_result_code= LDAP_OPERATIONS_ERROR;
goto error_return;
}
-
+
/* JCMACL - Should be performed before the child check. */
/* JCMACL - Why is the check performed against the copy, rather than the existing entry? */
- ldap_result_code = plugin_call_acl_plugin (pb, ec->ep_entry,
- NULL /*attr*/, NULL /*value*/, SLAPI_ACL_WRITE,
- ACLPLUGIN_ACCESS_MODRDN, &errbuf );
- if ( ldap_result_code != LDAP_SUCCESS )
{
- goto error_return;
- }
+ Slapi_RDN *new_rdn;
+ Slapi_RDN *old_rdn;
+
+ /* Taken from the entry */
+ old_rdn = slapi_entry_get_srdn(ec->ep_entry);
+
+ /* Taken from the request */
+ new_rdn = slapi_rdn_new();
+ slapi_sdn_get_rdn(&dn_newrdn, new_rdn);
+
+ /* Only if we change the RDN value, we need the write access to the entry */
+ if (slapi_rdn_compare(old_rdn, new_rdn)) {
+ ldap_result_code = plugin_call_acl_plugin(pb, ec->ep_entry,
+ NULL /*attr*/, NULL /*value*/, SLAPI_ACL_WRITE,
+ ACLPLUGIN_ACCESS_MODRDN, &errbuf);
+ }
+
+ slapi_rdn_free(&new_rdn);
+
+ if (ldap_result_code != LDAP_SUCCESS) {
+ goto error_return;
+ }
+ }
/* Set the new dn to the copy of the entry */
slapi_entry_set_sdn( ec->ep_entry, &dn_newdn );
diff --git a/ldap/servers/slapd/config.c b/ldap/servers/slapd/config.c
index 3067fdf..deecc66 100644
--- a/ldap/servers/slapd/config.c
+++ b/ldap/servers/slapd/config.c
@@ -225,12 +225,13 @@ slapd_bootstrap_config(const char *configdir)
char syntaxlogging[BUFSIZ];
char plugintracking[BUFSIZ];
char dn_validate_strict[BUFSIZ];
+ char moddn_aci[BUFSIZ];
Slapi_DN plug_dn;
workpath[0] = loglevel[0] = maxdescriptors[0] = '\0';
val[0] = logenabled[0] = schemacheck[0] = syntaxcheck[0] = '\0';
syntaxlogging[0] = _localuser[0] = '\0';
- plugintracking [0] = dn_validate_strict[0] = '\0';
+ plugintracking [0] = dn_validate_strict[0] = moddn_aci[0] ='\0';
/* Convert LDIF to entry structures */
slapi_sdn_init_ndn_byref(&plug_dn, PLUGIN_BASE_DN);
@@ -460,6 +461,20 @@ slapd_bootstrap_config(const char *configdir)
CONFIG_PLUGIN_BINDDN_TRACKING_ATTRIBUTE, errorbuf);
}
}
+
+ /* see if we allow moddn aci */
+ if (!moddn_aci[0] &&
+ entry_has_attr_and_value(e, CONFIG_MODDN_ACI_ATTRIBUTE,
+ moddn_aci, sizeof(moddn_aci)))
+ {
+ if (config_set_moddn_aci(CONFIG_MODDN_ACI_ATTRIBUTE,
+ moddn_aci, errorbuf, CONFIG_APPLY)
+ != LDAP_SUCCESS)
+ {
+ LDAPDebug(LDAP_DEBUG_ANY, "%s: %s: %s\n", configfile,
+ CONFIG_MODDN_ACI_ATTRIBUTE, errorbuf);
+ }
+ }
/* see if we need to enable syntax checking */
if (!syntaxcheck[0] &&
diff --git a/ldap/servers/slapd/libglobs.c b/ldap/servers/slapd/libglobs.c
index 7abc3b0..06bfc92 100644
--- a/ldap/servers/slapd/libglobs.c
+++ b/ldap/servers/slapd/libglobs.c
@@ -243,6 +243,7 @@ slapi_onoff_t init_attrname_exceptions;
slapi_onoff_t init_return_exact_case;
slapi_onoff_t init_result_tweak;
slapi_onoff_t init_plugin_track;
+slapi_onoff_t init_moddn_aci;
slapi_onoff_t init_lastmod;
slapi_onoff_t init_readonly;
slapi_onoff_t init_accesscontrol;
@@ -841,6 +842,11 @@ static struct config_get_and_set {
NULL, 0,
(void**)&global_slapdFrontendConfig.plugin_track,
CONFIG_ON_OFF, NULL, &init_plugin_track},
+ {CONFIG_MODDN_ACI_ATTRIBUTE, config_set_moddn_aci,
+ NULL, 0,
+ (void**)&global_slapdFrontendConfig.moddn_aci,
+ CONFIG_ON_OFF, (ConfigGetFunc)config_get_moddn_aci,
+ &init_moddn_aci},
{CONFIG_ATTRIBUTE_NAME_EXCEPTION_ATTRIBUTE, config_set_attrname_exceptions,
NULL, 0,
(void**)&global_slapdFrontendConfig.attrname_exceptions,
@@ -1424,6 +1430,7 @@ FrontendConfig_init () {
init_schemamod = cfg->schemamod = LDAP_ON;
init_syntaxcheck = cfg->syntaxcheck = LDAP_OFF;
init_plugin_track = cfg->plugin_track = LDAP_OFF;
+ init_moddn_aci = cfg->moddn_aci = LDAP_ON;
init_syntaxlogging = cfg->syntaxlogging = LDAP_OFF;
init_dn_validate_strict = cfg->dn_validate_strict = LDAP_OFF;
init_ds4_compatible_schema = cfg->ds4_compatible_schema = LDAP_OFF;
@@ -3250,6 +3257,20 @@ config_set_plugin_tracking( const char *attrname, char *value, char *errorbuf, i
}
int
+config_set_moddn_aci( const char *attrname, char *value, char *errorbuf, int apply ) {
+ int retVal = LDAP_SUCCESS;
+ slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+
+ retVal = config_set_onoff ( attrname,
+ value,
+ &(slapdFrontendConfig->moddn_aci),
+ errorbuf,
+ apply);
+
+ return retVal;
+}
+
+int
config_set_security( const char *attrname, char *value, char *errorbuf, int apply ) {
int retVal = LDAP_SUCCESS;
slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
@@ -5062,6 +5083,18 @@ config_get_result_tweak() {
}
int
+config_get_moddn_aci() {
+ slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
+ int retVal;
+
+ CFG_ONOFF_LOCK_READ(slapdFrontendConfig);
+ retVal = (int)slapdFrontendConfig->moddn_aci;
+ CFG_ONOFF_UNLOCK_READ(slapdFrontendConfig);
+
+ return retVal;
+}
+
+int
config_get_security() {
slapdFrontendConfig_t *slapdFrontendConfig = getFrontendConfig();
int retVal;
diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h
index 3aa2170..447e1d0 100644
--- a/ldap/servers/slapd/proto-slap.h
+++ b/ldap/servers/slapd/proto-slap.h
@@ -289,6 +289,7 @@ int config_set_pagedsizelimit( const char *attrname, char *value, char *errorbuf
int config_set_lastmod( const char *attrname, char *value, char *errorbuf, int apply );
int config_set_nagle( const char *attrname, char *value, char *errorbuf, int apply );
int config_set_accesscontrol( const char *attrname, char *value, char *errorbuf, int apply );
+int config_set_moddn_aci( const char *attrname, char *value, char *errorbuf, int apply );
int config_set_security( const char *attrname, char *value, char *errorbuf, int apply );
int config_set_readonly( const char *attrname, char *value, char *errorbuf, int apply );
int config_set_schemacheck( const char *attrname, char *value, char *errorbuf, int apply );
@@ -470,6 +471,7 @@ int config_get_nagle();
int config_get_accesscontrol();
int config_get_return_exact_case();
int config_get_result_tweak();
+int config_get_moddn_aci();
int config_get_security();
int config_get_schemacheck();
int config_get_syntaxcheck();
diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h
index 6834181..f2ab9b3 100644
--- a/ldap/servers/slapd/slap.h
+++ b/ldap/servers/slapd/slap.h
@@ -2102,6 +2102,7 @@ typedef struct _slapdEntryPoints {
#define CONFIG_AUDITLOG_LIST_ATTRIBUTE "nsslapd-auditlog-list"
#define CONFIG_REWRITE_RFC1274_ATTRIBUTE "nsslapd-rewrite-rfc1274"
#define CONFIG_PLUGIN_BINDDN_TRACKING_ATTRIBUTE "nsslapd-plugin-binddn-tracking"
+#define CONFIG_MODDN_ACI_ATTRIBUTE "nsslapd-moddn-aci"
#define CONFIG_CONFIG_ATTRIBUTE "nsslapd-config"
#define CONFIG_INSTDIR_ATTRIBUTE "nsslapd-instancedir"
@@ -2257,6 +2258,7 @@ typedef struct _slapdFrontendConfig {
char **include;
char **plugin;
slapi_onoff_t plugin_track;
+ slapi_onoff_t moddn_aci;
struct pw_scheme *pw_storagescheme;
slapi_onoff_t pwpolicy_local;
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
index 2f24251..63baf21 100644
--- a/ldap/servers/slapd/slapi-plugin.h
+++ b/ldap/servers/slapd/slapi-plugin.h
@@ -237,7 +237,12 @@ NSPR_API(PRUint32) PR_fprintf(struct PRFileDesc* fd, const char *fmt, ...)
#define SLAPI_ACL_SELF 0x40
#define SLAPI_ACL_PROXY 0x80
#define SLAPI_ACL_ALL 0x7f
-
+/* Values 0x200 and 0x400 are booked (acl.h) by
+ * ACLPB_SLAPI_ACL_WRITE_ADD
+ * ACLPB_SLAPI_ACL_WRITE_DEL
+ */
+#define SLAPI_ACL_MODDN 0x0800
+
/*
* filter types
10 years
lib/base lib/libaccess
by Mark Reynolds
lib/base/pool.cpp | 10 +++++-----
lib/base/system.cpp | 8 ++++----
lib/libaccess/aclcache.cpp | 4 ++--
3 files changed, 11 insertions(+), 11 deletions(-)
New commits:
commit 07d4b617ffda389f6f9b0b62db255ff0424ad019
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Fri Mar 14 15:57:12 2014 -0400
Revert "Ticket 47700 - Fix compiler warnings"
This patch breaks the build on rawhide.
This reverts commit 9698a97075e04219e103b2693ac5002d33b19486.
diff --git a/lib/base/pool.cpp b/lib/base/pool.cpp
index 3398dad..9ee1b8c 100644
--- a/lib/base/pool.cpp
+++ b/lib/base/pool.cpp
@@ -178,7 +178,7 @@ _create_block(int size)
crit_exit(freelist_lock);
if (((newblock = (block_t *)PERM_MALLOC(sizeof(block_t))) == NULL) ||
((newblock->data = (char *)PERM_MALLOC(bytes)) == NULL)) {
- ereport(LOG_CATASTROPHE, (char *)XP_GetAdminStr(DBT_poolCreateBlockOutOfMemory_));
+ ereport(LOG_CATASTROPHE, "%s", XP_GetAdminStr(DBT_poolCreateBlockOutOfMemory_));
if (newblock)
PERM_FREE(newblock);
return NULL;
@@ -259,7 +259,7 @@ pool_create()
}
if ( (newpool->curr_block =_create_block(BLOCK_SIZE)) == NULL) {
- ereport(LOG_CATASTROPHE, (char *)XP_GetAdminStr(DBT_poolCreateOutOfMemory_));
+ ereport(LOG_CATASTROPHE, "%s", XP_GetAdminStr(DBT_poolCreateOutOfMemory_));
PERM_FREE(newpool);
return NULL;
}
@@ -280,7 +280,7 @@ pool_create()
crit_exit(known_pools_lock);
}
else
- ereport(LOG_CATASTROPHE, (char *)XP_GetAdminStr(DBT_poolCreateOutOfMemory_1));
+ ereport(LOG_CATASTROPHE, "%s", XP_GetAdminStr(DBT_poolCreateOutOfMemory_1));
return (pool_handle_t *)newpool;
}
@@ -386,7 +386,7 @@ pool_malloc(pool_handle_t *pool_handle, size_t size)
*/
blocksize = ( (size + BLOCK_SIZE-1) / BLOCK_SIZE ) * BLOCK_SIZE;
if ( (pool->curr_block = _create_block(blocksize)) == NULL) {
- ereport(LOG_CATASTROPHE, (char *)XP_GetAdminStr(DBT_poolMallocOutOfMemory_));
+ ereport(LOG_CATASTROPHE, "%s", XP_GetAdminStr(DBT_poolMallocOutOfMemory_));
#ifdef POOL_LOCKING
crit_exit(pool->lock);
#endif
@@ -408,7 +408,7 @@ pool_malloc(pool_handle_t *pool_handle, size_t size)
void _pool_free_error()
{
- ereport(LOG_WARN, (char *)XP_GetAdminStr(DBT_freeUsedWherePermFreeShouldHaveB_));
+ ereport(LOG_WARN, "%s", XP_GetAdminStr(DBT_freeUsedWherePermFreeShouldHaveB_));
return;
}
diff --git a/lib/base/system.cpp b/lib/base/system.cpp
index b62a814..287d5a8 100644
--- a/lib/base/system.cpp
+++ b/lib/base/system.cpp
@@ -201,7 +201,7 @@ NSAPI_PUBLIC void *system_realloc_perm(void *ptr, int size)
return ptr;
}
} else {
- ereport(LOG_WARN, (char*)"realloc: attempt to realloc to smaller size");
+ ereport(LOG_WARN, "realloc: attempt to realloc to smaller size");
return realloc(ptr, size);
}
@@ -228,20 +228,20 @@ NSAPI_PUBLIC void system_free_perm(void *ptr)
cptr += sizeof(int);
for (index=0; index<DEBUG_MARGIN; index++)
if (cptr[index] != DEBUG_MARGIN_CHAR) {
- ereport(LOG_CATASTROPHE, (char *)"free: corrupt memory (prebounds overwrite)");
+ ereport(LOG_CATASTROPHE, "free: corrupt memory (prebounds overwrite)");
break;
}
cptr += DEBUG_MARGIN + *length;
for (index=0; index<DEBUG_MARGIN; index++)
if (cptr[index] != DEBUG_MARGIN_CHAR) {
- ereport(LOG_CATASTROPHE, (char *)"free: corrupt memory (prebounds overwrite)");
+ ereport(LOG_CATASTROPHE, "free: corrupt memory (prebounds overwrite)");
break;
}
memset(baseptr, DEBUG_FREE_CHAR, *length + 2*DEBUG_MARGIN+sizeof(int));
} else {
- ereport(LOG_CATASTROPHE, (char *)"free: freeing unallocated memory");
+ ereport(LOG_CATASTROPHE, "free: freeing unallocated memory");
}
free(baseptr);
#else
diff --git a/lib/libaccess/aclcache.cpp b/lib/libaccess/aclcache.cpp
index 42d08aa..52e019b 100644
--- a/lib/libaccess/aclcache.cpp
+++ b/lib/libaccess/aclcache.cpp
@@ -133,8 +133,8 @@ ACL_ListHashInit()
&ACLPermAllocOps,
NULL);
if (ACLListHash == NULL) {
- ereport(LOG_SECURITY, (char *)"Unable to allocate ACL List Hash");
- return;
+ ereport(LOG_SECURITY, "Unable to allocate ACL List Hash\n");
+ return;
}
return;
10 years