ldap/servers
by Noriko Hosoi
ldap/servers/slapd/pw.c | 58 ++++++++++++++++++++++++++----------------------
1 file changed, 32 insertions(+), 26 deletions(-)
New commits:
commit dd90d19917594e5cad81f90b7a35f220c5230b96
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Mon Jan 11 17:57:28 2016 -0800
Ticket #548 - RFE: Allow AD password sync to update shadowLastChange
Description: Commit 17f3624c19929ffa1d37a567b7a889fd397cca59 for
the this ticket always replaced the shadow attributes before sending
the entry back to the client. It is not just necessary but harmful
since it could cause the conflicts among threads that return same
entries.
https://fedorahosted.org/389/ticket/548
Reviewed by wibrown(a)redhat.com (Thank you, William!!)
diff --git a/ldap/servers/slapd/pw.c b/ldap/servers/slapd/pw.c
index 69756f3..a6574ac 100644
--- a/ldap/servers/slapd/pw.c
+++ b/ldap/servers/slapd/pw.c
@@ -2879,41 +2879,47 @@ add_shadow_ext_password_attrs(Slapi_PBlock *pb, Slapi_Entry *e)
bvals[1] = NULL;
/* shadowMin - the minimum number of days required between password changes. */
- if (pwpolicy->pw_minage > 0) {
- shadowval = pwpolicy->pw_minage / _SEC_PER_DAY;
- } else {
- shadowval = 0;
+ if (!slapi_entry_attr_exists(e, "shadowMin")) {
+ if (pwpolicy->pw_minage > 0) {
+ shadowval = pwpolicy->pw_minage / _SEC_PER_DAY;
+ } else {
+ shadowval = 0;
+ }
+ bv.bv_val = slapi_ch_smprintf("%ld", shadowval);
+ bv.bv_len = strlen(bv.bv_val);
+ slapi_entry_attr_merge(e, "shadowMin", bvals);
+ slapi_ch_free_string(&bv.bv_val);
}
- bv.bv_val = slapi_ch_smprintf("%ld", shadowval);
- bv.bv_len = strlen(bv.bv_val);
- slapi_entry_attr_replace(e, "shadowMin", bvals);
- slapi_ch_free_string(&bv.bv_val);
/* shadowMax - the maximum number of days for which the user password remains valid. */
- if (pwpolicy->pw_maxage > 0) {
- shadowval = pwpolicy->pw_maxage / _SEC_PER_DAY;
- exptime = time_plus_sec(current_time(), pwpolicy->pw_maxage);
- } else {
- shadowval = 99999;
+ if (!slapi_entry_attr_exists(e, "shadowMax")) {
+ if (pwpolicy->pw_maxage > 0) {
+ shadowval = pwpolicy->pw_maxage / _SEC_PER_DAY;
+ exptime = time_plus_sec(current_time(), pwpolicy->pw_maxage);
+ } else {
+ shadowval = 99999;
+ }
+ bv.bv_val = slapi_ch_smprintf("%ld", shadowval);
+ bv.bv_len = strlen(bv.bv_val);
+ slapi_entry_attr_replace(e, "shadowMax", bvals);
+ slapi_ch_free_string(&bv.bv_val);
}
- bv.bv_val = slapi_ch_smprintf("%ld", shadowval);
- bv.bv_len = strlen(bv.bv_val);
- slapi_entry_attr_replace(e, "shadowMax", bvals);
- slapi_ch_free_string(&bv.bv_val);
/* shadowWarning - the number of days of advance warning given to the user before the user password expires. */
- if (pwpolicy->pw_warning > 0) {
- shadowval = pwpolicy->pw_warning / _SEC_PER_DAY;
- } else {
- shadowval = 0;
+ if (!slapi_entry_attr_exists(e, "shadowWarning")) {
+ if (pwpolicy->pw_warning > 0) {
+ shadowval = pwpolicy->pw_warning / _SEC_PER_DAY;
+ } else {
+ shadowval = 0;
+ }
+ bv.bv_val = slapi_ch_smprintf("%ld", shadowval);
+ bv.bv_len = strlen(bv.bv_val);
+ slapi_entry_attr_replace(e, "shadowWarning", bvals);
+ slapi_ch_free_string(&bv.bv_val);
}
- bv.bv_val = slapi_ch_smprintf("%ld", shadowval);
- bv.bv_len = strlen(bv.bv_val);
- slapi_entry_attr_replace(e, "shadowWarning", bvals);
- slapi_ch_free_string(&bv.bv_val);
/* shadowExpire - the date on which the user login will be disabled. */
- if (exptime) {
+ if (exptime && !slapi_entry_attr_exists(e, "shadowExpire")) {
exptime /= _SEC_PER_DAY;
bv.bv_val = slapi_ch_smprintf("%ld", exptime);
bv.bv_len = strlen(bv.bv_val);
8 years, 3 months
ldap/admin
by William Brown
ldap/admin/src/scripts/ds-logpipe.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
New commits:
commit 45c71650fffa818799d607b425d0d453c548acb5
Author: Simon Pichugin <spichugi(a)redhat.com>
Date: Tue Oct 6 11:32:36 2015 +0200
Ticket 48302 - ds-logpipe.py with wrong arguments - python exception in the output
Description: If we execute ds-logpipe.py with wrong arguments,
then instead of proper message we see AttributeError
python exception.
It happens, because "args" list doesn't have join()
function.
This patch sets join() function to the string object
and "args" list to the argument of join() function.
https://fedorahosted.org/389/ticket/48302
Author: Simon Pichugin <spichugi(a)redhat.com>
Reviewed by: nhosoi, wibrown
diff --git a/ldap/admin/src/scripts/ds-logpipe.py b/ldap/admin/src/scripts/ds-logpipe.py
index ca6c27f..4ba4d1b 100644
--- a/ldap/admin/src/scripts/ds-logpipe.py
+++ b/ldap/admin/src/scripts/ds-logpipe.py
@@ -256,7 +256,7 @@ def parse_options():
if len(args) < 1:
parser.error("You must specify the name of the pipe to use")
if len(args) > 1:
- parser.error("error - unhandled command line arguments: %s" % args.join(' '))
+ parser.error("error - unhandled command line arguments: %s" % ' '.join(args))
return options, args[0]
8 years, 3 months
2 commits - Makefile.am Makefile.in rpm/389-ds-base.spec.in
by William Brown
Makefile.am | 12 ++++++++----
Makefile.in | 13 +++++++++----
rpm/389-ds-base.spec.in | 33 +++++++++++++++++----------------
3 files changed, 34 insertions(+), 24 deletions(-)
New commits:
commit 22ec6b2f3d1344dcb729a46bb46bf7233f1ce1ce
Author: William Brown <firstyear(a)redhat.com>
Date: Sat Jan 2 16:22:47 2016 +1000
Ticket 48397 - Fix cwd and rpmsources target
Bug Description: The rpmbuild directory is placed into CWD instead of the build
directory.
The sources for the rpm must be manually downloaded.
Fix Description: Move the rpmbuild directory target to the autotools build
directory.
Add a new make target that, rpmsources that will fetch the required sources.
https://fedorahosted.org/389/ticket/48397
Author: wibrown
Review by: mreynolds
diff --git a/Makefile.am b/Makefile.am
index da09653..213922f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1950,7 +1950,7 @@ git-archive:
# RPM-related tasks
-RPMBUILD ?= $(PWD)/rpmbuild
+RPMBUILD ?= $(abs_builddir)/rpmbuild
rpmroot:
$(MKDIR_P) $(RPMBUILD)/BUILD
@@ -1965,6 +1965,9 @@ rpmbrprep: dist-bzip2 rpmroot
cp $(srcdir)/rpm/389-ds-base-devel.README $(RPMBUILD)/SOURCES
sed -e "s/__VERSION__/$(RPM_VERSION)/" -e "s/__RELEASE__/$(RPM_RELEASE)/" -e "s/__NUNC_STANS_ON__/$(NUNC_STANS_ON)/" < $(abs_builddir)/rpm/389-ds-base.spec > $(RPMBUILD)/SPECS/389-ds-base.spec
+# Requires rpmdevtools. Consider making this a dependancy of rpms.
+rpmsources: rpmbrprep
+ spectool -g -S -C $(RPMBUILD)/SOURCES $(RPMBUILD)/SPECS/389-ds-base.spec
rpms: rpmbrprep
cd $(RPMBUILD); \
diff --git a/Makefile.in b/Makefile.in
index d808112..745d6a8 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -10788,7 +10788,7 @@ git-archive:
# RPM-related tasks
-RPMBUILD ?= $(PWD)/rpmbuild
+RPMBUILD ?= $(abs_builddir)/rpmbuild
rpmroot:
$(MKDIR_P) $(RPMBUILD)/BUILD
@@ -10803,6 +10803,10 @@ rpmbrprep: dist-bzip2 rpmroot
cp $(srcdir)/rpm/389-ds-base-devel.README $(RPMBUILD)/SOURCES
sed -e "s/__VERSION__/$(RPM_VERSION)/" -e "s/__RELEASE__/$(RPM_RELEASE)/" -e "s/__NUNC_STANS_ON__/$(NUNC_STANS_ON)/" < $(abs_builddir)/rpm/389-ds-base.spec > $(RPMBUILD)/SPECS/389-ds-base.spec
+# Requires rpmdevtools. Consider making this a dependancy of rpms.
+rpmsources: rpmbrprep
+ spectool -g -S -C $(RPMBUILD)/SOURCES $(RPMBUILD)/SPECS/389-ds-base.spec
+
rpms: rpmbrprep
cd $(RPMBUILD); \
rpmbuild --define "_topdir $(RPMBUILD)" -ba SPECS/389-ds-base.spec
commit 0eb6f5b9a6f76c507ca8c7febf856713588ee5d0
Author: William Brown <firstyear(a)redhat.com>
Date: Sat Jan 2 09:24:24 2016 +1000
Ticket 48397 - ds make rpms doesn't work in a prefixed build env
Bug Description: if you run a prefixed build, make rpms does not work.
Additionally, rpmbuild throws invalid %if errors with this .spec
Fix Description: This fixes the build paths to work regardless of prefix build
or not. This also fixes the rpm if macros to work, and the missing dirsrvtests
from the dist component of Makefile.am
https://fedorahosted.org/389/ticket/48397
Author: wibrown
Review by: mreynolds
diff --git a/Makefile.am b/Makefile.am
index bca6489..da09653 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -474,6 +474,7 @@ dist_noinst_DATA = \
$(srcdir)/VERSION.sh \
$(srcdir)/wrappers/*.in \
$(srcdir)/wrappers/systemd.template.sysconfig \
+ $(srcdir)/dirsrvtests \
$(NULL)
#------------------------
@@ -1960,9 +1961,9 @@ rpmroot:
rpmbrprep: dist-bzip2 rpmroot
cp $(distdir).tar.bz2 $(RPMBUILD)/SOURCES
- cp $(builddir)/rpm/389-ds-base-git.sh $(RPMBUILD)/SOURCES
- cp $(builddir)/rpm/389-ds-base-devel.README $(RPMBUILD)/SOURCES
- sed -e "s/__VERSION__/$(RPM_VERSION)/" -e "s/__RELEASE__/$(RPM_RELEASE)/" -e "s/__NUNC_STANS_ON__/$(NUNC_STANS_ON)/" < $(builddir)/rpm/389-ds-base.spec > $(RPMBUILD)/SPECS/389-ds-base.spec
+ cp $(srcdir)/rpm/389-ds-base-git.sh $(RPMBUILD)/SOURCES
+ cp $(srcdir)/rpm/389-ds-base-devel.README $(RPMBUILD)/SOURCES
+ sed -e "s/__VERSION__/$(RPM_VERSION)/" -e "s/__RELEASE__/$(RPM_RELEASE)/" -e "s/__NUNC_STANS_ON__/$(NUNC_STANS_ON)/" < $(abs_builddir)/rpm/389-ds-base.spec > $(RPMBUILD)/SPECS/389-ds-base.spec
rpms: rpmbrprep
diff --git a/Makefile.in b/Makefile.in
index c5637ab..d808112 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -1886,6 +1886,7 @@ dist_noinst_DATA = \
$(srcdir)/VERSION.sh \
$(srcdir)/wrappers/*.in \
$(srcdir)/wrappers/systemd.template.sysconfig \
+ $(srcdir)/dirsrvtests \
$(NULL)
@@ -10798,9 +10799,9 @@ rpmroot:
rpmbrprep: dist-bzip2 rpmroot
cp $(distdir).tar.bz2 $(RPMBUILD)/SOURCES
- cp $(builddir)/rpm/389-ds-base-git.sh $(RPMBUILD)/SOURCES
- cp $(builddir)/rpm/389-ds-base-devel.README $(RPMBUILD)/SOURCES
- sed -e "s/__VERSION__/$(RPM_VERSION)/" -e "s/__RELEASE__/$(RPM_RELEASE)/" -e "s/__NUNC_STANS_ON__/$(NUNC_STANS_ON)/" < $(builddir)/rpm/389-ds-base.spec > $(RPMBUILD)/SPECS/389-ds-base.spec
+ cp $(srcdir)/rpm/389-ds-base-git.sh $(RPMBUILD)/SOURCES
+ cp $(srcdir)/rpm/389-ds-base-devel.README $(RPMBUILD)/SOURCES
+ sed -e "s/__VERSION__/$(RPM_VERSION)/" -e "s/__RELEASE__/$(RPM_RELEASE)/" -e "s/__NUNC_STANS_ON__/$(NUNC_STANS_ON)/" < $(abs_builddir)/rpm/389-ds-base.spec > $(RPMBUILD)/SPECS/389-ds-base.spec
rpms: rpmbrprep
cd $(RPMBUILD); \
diff --git a/rpm/389-ds-base.spec.in b/rpm/389-ds-base.spec.in
index 68d7830..7dfa0b5 100644
--- a/rpm/389-ds-base.spec.in
+++ b/rpm/389-ds-base.spec.in
@@ -14,13 +14,13 @@
# nunc-stans only builds on x86_64 for now
# To build without nunc-stans, set use_nunc_stans to 0.
%global use_nunc_stans __NUNC_STANS_ON__
-%if %{use_nunc_stans}
+%if 0%{?use_nunc_stans:1}
%global nunc_stans_ver 0.1.7
%endif
# Are we bundling jemalloc?
%global bundle_jemalloc __BUNDLE_JEMALLOC__
-%if %{bundle_jemalloc}
+%if 0%{?bundle_jemalloc:1}
# The version used in the source tarball
%global jemalloc_ver 3.6.0
%endif
@@ -128,10 +128,10 @@ Source0: http://port389.org/sources/%{name}-%{version}%{?prerel}.tar.bz
Source1: %{name}-git.sh
Source2: %{name}-devel.README
-%if %{bundle_jemalloc}
+%if 0%{?bundle_jemalloc:1}
Source3: http://www.port389.org/binaries/jemalloc-%{jemalloc_ver}.tar.bz2
%endif
-%if %{use_nunc_stans}
+%if 0%{?use_nunc_stans:1}
Source4: https://git.fedorahosted.org/cgit/nunc-stans.git/snapshot/nunc-stans-%{nu...
%endif
@@ -158,12 +158,12 @@ BuildRequires: libdb-devel
BuildRequires: cyrus-sasl-devel
BuildRequires: libicu-devel
BuildRequires: pcre-devel
-%if %{use_nunc_stans}
+%if 0%{?use_nunc_stans:1}
BuildRequires: libtalloc-devel
BuildRequires: libevent-devel
BuildRequires: libtevent-devel
%endif
-%if %{bundle_jemalloc}
+%if 0%{?bundle_jemalloc:1}
BuildRequires: /usr/bin/xsltproc
%ifnarch s390
BuildRequires: valgrind-devel
@@ -208,16 +208,16 @@ The lib389 CI tests that can be run against the Directory Server.
%prep
%setup -q -n %{name}-%{version}%{?prerel}
-%if %{bundle_jemalloc}
+%if 0%{?bundle_jemalloc:1}
%setup -q -n %{name}-%{version}%{?prerel} -T -D -b 3
%endif
-%if %{use_nunc_stans}
+%if 0%{?use_nunc_stans:1}
%setup -q -n %{name}-%{version}%{?prerel} -T -D -b 4
%endif
cp %{SOURCE2} README.devel
%build
-%if %{use_nunc_stans}
+%if 0%{?use_nunc_stans:1}
pushd ../nunc-stans-%{nunc_stans_ver}
%configure --with-fhs --libdir=%{_libdir}/%{pkgname}
make %{?_smp_mflags}
@@ -228,7 +228,7 @@ cp nunc-stans.h include/nunc-stans/nunc-stans.h
popd
%endif
-%if %{bundle_jemalloc}
+%if 0%{?bundle_jemalloc:1}
pushd ../jemalloc-%{jemalloc_ver}
%configure CFLAGS='%{optflags} -msse2' --libdir=%{_libdir}/%{pkgname}
make %{?_smp_mflags}
@@ -262,7 +262,7 @@ make %{?_smp_mflags}
%install
rm -rf $RPM_BUILD_ROOT
-%if %{use_nunc_stans}
+%if 0%{?use_nunc_stans:1}
pushd ../nunc-stans-%{nunc_stans_ver}
make DESTDIR="$RPM_BUILD_ROOT" install
rm -rf $RPM_BUILD_ROOT%{_includedir} $RPM_BUILD_ROOT%{_datadir} \
@@ -270,7 +270,7 @@ rm -rf $RPM_BUILD_ROOT%{_includedir} $RPM_BUILD_ROOT%{_datadir} \
popd
%endif
-%if %{bundle_jemalloc}
+%if 0%{?bundle_jemalloc:1}
pushd ../jemalloc-%{jemalloc_ver}
cp --preserve=links lib/libjemalloc.so* $RPM_BUILD_ROOT%{_libdir}/%{pkgname}
popd
@@ -294,6 +294,7 @@ rm -f $RPM_BUILD_ROOT%{_libdir}/%{pkgname}/plugins/*.la
# make sure perl scripts have a proper shebang
sed -i -e 's|#{{PERL-EXEC}}|#!/usr/bin/perl|' $RPM_BUILD_ROOT%{_datadir}/%{pkgname}/script-templates/template-*.pl
+# Why are we not making this a proper python package?
pushd ../%{name}-%{version}%{?prerel}
cp -r dirsrvtests $RPM_BUILD_ROOT/%{_sysconfdir}/%{pkgname}
find $RPM_BUILD_ROOT/%{_sysconfdir}/%{pkgname}/dirsrvtests -type f -name '*.pyc' -delete
@@ -434,10 +435,10 @@ fi
%doc LICENSE LICENSE.GPLv3+ LICENSE.openssl README.devel
%{_includedir}/%{pkgname}
%{_libdir}/%{pkgname}/libslapd.so
-%if %{use_nunc_stans}
+%if 0%{?use_nunc_stans:1}
%{_libdir}/%{pkgname}/libnunc-stans.so
%endif
-%if %{bundle_jemalloc}
+%if 0%{?bundle_jemalloc:1}
%{_libdir}/%{pkgname}/libjemalloc.so
%endif
%{_libdir}/pkgconfig/*
@@ -448,10 +449,10 @@ fi
%dir %{_libdir}/%{pkgname}
%{_libdir}/%{pkgname}/libslapd.so.*
%{_libdir}/%{pkgname}/libns-dshttpd.so*
-%if %{use_nunc_stans}
+%if 0%{?use_nunc_stans:1}
%{_libdir}/%{pkgname}/libnunc-stans.so*
%endif
-%if %{bundle_jemalloc}
+%if 0%{?bundle_jemalloc:1}
%{_libdir}/%{pkgname}/libjemalloc.so*
%endif
8 years, 3 months
Branch '389-ds-base-1.2.11' - ldap/servers lib/libaccess
by Noriko Hosoi
ldap/servers/plugins/acl/acllas.c | 53 +-
ldap/servers/plugins/replication/repl5_plugins.c | 7
ldap/servers/plugins/replication/windows_private.c | 7
ldap/servers/slapd/ldaputil.c | 90 ++--
ldap/servers/slapd/slapi-plugin.h | 9
lib/libaccess/lasip.cpp | 397 ++++++++++++++++-----
lib/libaccess/lasip.h | 3
7 files changed, 407 insertions(+), 159 deletions(-)
New commits:
commit 44413ce12710f310d377727399abc8f9a870c5eb
Author: Mark Reynolds <mareynol(a)redhat.com>
Date: Wed May 9 16:03:59 2012 -0400
Ticket #196 - RFE: Interpret IPV6 addresses for ACIs, replication, and chaining
Bug Description: replication, chaining, and access control do not hanbdle IPv6 addresses
Fix Description: For replication and chaining, we just needed to put brackets "[]" around
the IP address in the ldap urls. We also need to update
convert_to_openldap_uri(), which is called by slapi_ldap_init_ext().
Access control needed to remove the IPv6 restriction check, and update
libaccess to be IPv6 aware.
https://fedorahosted.org/389/ticket/196
Reviewed by: Norkio!
(cherry picked from commit 4d7d59e756d5dc2dbc04c7ee95759f211795a093)
diff --git a/ldap/servers/plugins/acl/acllas.c b/ldap/servers/plugins/acl/acllas.c
index fc7f185..a0cc53d 100644
--- a/ldap/servers/plugins/acl/acllas.c
+++ b/ldap/servers/plugins/acl/acllas.c
@@ -281,16 +281,12 @@ int
DS_LASIpGetter(NSErr_t *errp, PList_t subject, PList_t resource, PList_t
auth_info, PList_t global_auth, void *arg)
{
+ struct acl_pblock *aclpb = NULL;
+ PRNetAddr *client_praddr = NULL;
+ char ip_str[256];
+ int rv = LAS_EVAL_TRUE;
- struct acl_pblock *aclpb = NULL;
- IPAddr_t ip=0;
- PRNetAddr client_praddr;
- struct in_addr client_addr;
- int rv;
-
-
- rv = ACL_GetAttribute(errp, DS_PROP_ACLPB, (void **)&aclpb,
- subject, resource, auth_info, global_auth);
+ rv = ACL_GetAttribute(errp, DS_PROP_ACLPB, (void **)&aclpb, subject, resource, auth_info, global_auth);
if ( rv != LAS_EVAL_TRUE || ( NULL == aclpb )) {
acl_print_acllib_err(errp, NULL);
slapi_log_error( SLAPI_LOG_ACL, plugin_name,
@@ -298,29 +294,34 @@ DS_LASIpGetter(NSErr_t *errp, PList_t subject, PList_t resource, PList_t
return LAS_EVAL_FAIL;
}
- if ( slapi_pblock_get( aclpb->aclpb_pblock, SLAPI_CONN_CLIENTNETADDR,
- &client_praddr ) != 0 ) {
- slapi_log_error( SLAPI_LOG_FATAL, plugin_name, "Could not get client IP.\n" );
- return( LAS_EVAL_FAIL );
- }
-
- if ( !PR_IsNetAddrType(&client_praddr, PR_IpAddrV4Mapped) ) {
- slapi_log_error( SLAPI_LOG_ACL, plugin_name,
- "Client address is IPv6. ACLs only support IPv4 addresses so far.\n");
+ client_praddr = (PRNetAddr *)slapi_ch_malloc(sizeof(PRNetAddr));
+ if(client_praddr == NULL){
+ slapi_log_error( SLAPI_LOG_FATAL, plugin_name, "DS_LASIpGetter: failed to allocate client_praddr\n");
return( LAS_EVAL_FAIL );
}
-
- client_addr.s_addr = client_praddr.ipv6.ip.pr_s6_addr32[3];
- ip = (IPAddr_t) ntohl( client_addr.s_addr );
- rv = PListInitProp(subject, 0, ACL_ATTR_IP, (void *)ip, NULL);
+ if ( slapi_pblock_get( aclpb->aclpb_pblock, SLAPI_CONN_CLIENTNETADDR, client_praddr ) != 0 ) {
+ slapi_log_error( SLAPI_LOG_FATAL, plugin_name, "DS_LASIpGetter: Could not get client IP.\n" );
+ slapi_ch_free((void **)&client_praddr);
+ return( LAS_EVAL_FAIL );
+ }
- slapi_log_error( SLAPI_LOG_ACL, plugin_name,
- "Returning client ip address '%s'\n",
- (slapi_is_loglevel_set(SLAPI_LOG_ACL) ? inet_ntoa(client_addr) : ""));
+ rv = PListInitProp(subject, 0, ACL_ATTR_IP, (void *)client_praddr, NULL);
+ if (rv < 0) {
+ slapi_log_error ( SLAPI_LOG_ACL, plugin_name, "DS_LASIpGetter: "
+ "Couldn't set the client addr property(%d)\n", rv );
+ slapi_ch_free((void **)&client_praddr);
+ return LAS_EVAL_FAIL;
+ }
+ if( PR_NetAddrToString(client_praddr, ip_str, sizeof(ip_str)) == PR_SUCCESS){
+ slapi_log_error( SLAPI_LOG_ACL, plugin_name, "DS_LASIpGetter: "
+ "Returning client ip address '%s'\n", ip_str);
+ } else {
+ slapi_log_error( SLAPI_LOG_ACL, plugin_name, "DS_LASIpGetter: "
+ "Returning client ip address 'unknown'\n");
+ }
return LAS_EVAL_TRUE;
-
}
/*
diff --git a/ldap/servers/plugins/replication/repl5_plugins.c b/ldap/servers/plugins/replication/repl5_plugins.c
index afb0364..dddbf15 100644
--- a/ldap/servers/plugins/replication/repl5_plugins.c
+++ b/ldap/servers/plugins/replication/repl5_plugins.c
@@ -133,7 +133,12 @@ multimaster_set_local_purl()
}
else
{
- local_purl = slapi_ch_smprintf("ldap://%s:%s", host, port);
+ if(slapi_is_ipv6_addr(host)){
+ /* need to put brackets around the ipv6 address */
+ local_purl = slapi_ch_smprintf("ldap://[%s]:%s", host, port);
+ } else {
+ local_purl = slapi_ch_smprintf("ldap://%s:%s", host, port);
+ }
}
/* slapi_ch_free acceptS NULL pointer */
diff --git a/ldap/servers/plugins/replication/windows_private.c b/ldap/servers/plugins/replication/windows_private.c
index a103cad..4381943 100644
--- a/ldap/servers/plugins/replication/windows_private.c
+++ b/ldap/servers/plugins/replication/windows_private.c
@@ -321,7 +321,12 @@ const char* windows_private_get_purl(const Repl_Agmt *ra)
char *hostname;
hostname = agmt_get_hostname(ra);
- windows_purl = slapi_ch_smprintf("ldap://%s:%d", hostname, agmt_get_port(ra));
+ if(slapi_is_ipv6_addr(hostname)){
+ /* need to put brackets around the ipv6 address */
+ windows_purl = slapi_ch_smprintf("ldap://[%s]:%d", hostname, agmt_get_port(ra));
+ } else {
+ windows_purl = slapi_ch_smprintf("ldap://%s:%d", hostname, agmt_get_port(ra));
+ }
slapi_ch_free_string(&hostname);
return windows_purl;
diff --git a/ldap/servers/slapd/ldaputil.c b/ldap/servers/slapd/ldaputil.c
index 331dd71..4b8c16d 100644
--- a/ldap/servers/slapd/ldaputil.c
+++ b/ldap/servers/slapd/ldaputil.c
@@ -165,55 +165,59 @@ convert_to_openldap_uri(const char *hostname_or_uri, int port, const char *proto
char *my_copy = NULL;
char *start = NULL;
char *iter = NULL;
+ char *ptr = NULL;
char *s = NULL;
const char *brkstr = " ";
+ int done = 0;
if (!hostname_or_uri) {
- return NULL;
+ return NULL;
+ }
+
+ if(slapi_is_ipv6_addr(hostname_or_uri)){
+ /* We need to encapsulate the ipv6 addr with brackets */
+ my_copy = slapi_ch_smprintf("[%s]",hostname_or_uri);
+ } else {
+ my_copy = slapi_ch_strdup(hostname_or_uri);
}
- my_copy = slapi_ch_strdup(hostname_or_uri);
/* see if hostname_or_uri is an ldap uri */
if (!proto && !PL_strncasecmp(my_copy, "ldap", 4)) {
- start = my_copy + 4;
- if ((*start == 's') || (*start == 'i')) {
- start++;
- }
- if (!PL_strncmp(start, "://", 3)) {
- *start = '\0';
- proto = my_copy;
- start += 3;
- } else {
- slapi_log_error(SLAPI_LOG_FATAL, "convert_to_openldap_uri",
- "The given LDAP URI [%s] is not valid\n", hostname_or_uri);
- goto end;
- }
+ start = my_copy + 4;
+ if ((*start == 's') || (*start == 'i')) {
+ start++;
+ }
+ if (!PL_strncmp(start, "://", 3)) {
+ *start = '\0';
+ proto = my_copy;
+ start += 3;
+ } else {
+ slapi_log_error(SLAPI_LOG_FATAL, "convert_to_openldap_uri",
+ "The given LDAP URI [%s] is not valid\n", hostname_or_uri);
+ goto end;
+ }
} else if (!proto) {
- slapi_log_error(SLAPI_LOG_FATAL, "convert_to_openldap_uri",
- "The given LDAP URI [%s] is not valid\n", hostname_or_uri);
- goto end;
+ slapi_log_error(SLAPI_LOG_FATAL, "convert_to_openldap_uri",
+ "The given LDAP URI [%s] is not valid\n", hostname_or_uri);
+ goto end;
} else {
- start = my_copy; /* just assume it's not a uri */
+ start = my_copy; /* just assume it's not a uri */
}
- for (s = ldap_utf8strtok_r(my_copy, brkstr, &iter); s != NULL;
- s = ldap_utf8strtok_r(NULL, brkstr, &iter)) {
- char *ptr;
- int last = 0;
- /* strtok will grab the '/' at the end of the uri, if any,
- so terminate parsing there */
- if ((ptr = strchr(s, '/'))) {
- *ptr = '\0';
- last = 1;
- }
- if (retstr) {
- retstr = PR_sprintf_append(retstr, "/ %s://%s", proto, s);
- } else {
- retstr = PR_smprintf("%s://%s", proto, s);
- }
- if (last) {
- break;
- }
+ for (s = ldap_utf8strtok_r(my_copy, brkstr, &iter); s != NULL; s = ldap_utf8strtok_r(NULL, brkstr, &iter)) {
+ /* strtok will grab the '/' at the end of the uri, if any, so terminate parsing there */
+ if ((ptr = strchr(s, '/'))) {
+ *ptr = '\0';
+ done = 1;
+ }
+ if (retstr) {
+ retstr = PR_sprintf_append(retstr, "/ %s://%s", proto, s);
+ } else {
+ retstr = PR_smprintf("%s://%s", proto, s);
+ }
+ if (done) {
+ break;
+ }
}
/* add the port on the last one */
@@ -2271,3 +2275,15 @@ mozldap_ldap_explode_rdn( const char *rdn, const int notypes )
return( mozldap_ldap_explode( rdn, notypes, LDAP_RDN ) );
}
+int
+slapi_is_ipv6_addr( const char *hostname ){
+ PRNetAddr addr;
+
+ if(PR_StringToNetAddr(hostname, &addr) == PR_SUCCESS &&
+ !PR_IsNetAddrType(&addr, PR_IpAddrV4Mapped) &&
+ addr.raw.family == PR_AF_INET6)
+ {
+ return 1;
+ }
+ return 0;
+}
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
index 35f5ef4..48e8b85 100644
--- a/ldap/servers/slapd/slapi-plugin.h
+++ b/ldap/servers/slapd/slapi-plugin.h
@@ -3019,6 +3019,15 @@ void slapi_rdn_set_rdn(Slapi_RDN *rdn,const Slapi_RDN *fromrdn);
void slapi_rdn_free(Slapi_RDN **rdn);
/**
+ * Checks if the value of ipAddress is a IPv6 address
+ *
+ * \param ipAddress is a string that is either an IPv4 or IPv6 address
+ * \return 1 if address is an IPv6 address
+ * \return 0 if address is an IPv4 address
+ */
+int slapi_is_ipv6_addr( const char *ipAddress);
+
+/**
* Frees and clears the contents of a \c Slapi_RDN structure from memory.
*
* Both the RDN value and the array of split RDNs are freed. Those pointers
diff --git a/lib/libaccess/lasip.cpp b/lib/libaccess/lasip.cpp
index 7f5c01e..e66f48a 100644
--- a/lib/libaccess/lasip.cpp
+++ b/lib/libaccess/lasip.cpp
@@ -60,6 +60,8 @@
#include "aclcache.h"
#include <libaccess/dbtlibaccess.h>
#include <libaccess/aclerror.h>
+#include <prio.h>
+#include "nspr.h"
#define LAS_IP_IS_CONSTANT(x) (((x) == (LASIpTree_t *)LAS_EVAL_TRUE) || ((x) == (LASIpTree_t *)LAS_EVAL_FALSE))
@@ -67,8 +69,9 @@
extern int LASIpGetIp();
#endif
-static int
-LASIpAddPattern(NSErr_t *errp, int netmask, int pattern, LASIpTree_t **treetop);
+static int colonhex_ipv6(char *ipstr, char *netmaskstr, PRIPv6Addr *ipv6, int *netmask);
+static int LASIpAddPattern(NSErr_t *errp, int netmask, int pattern, LASIpTree_t **treetop);
+static int LASIpAddPatternIPv6(NSErr_t *errp, int netmask, PRIPv6Addr *ipv6, LASIpTree_t **treetop);
/* dotdecimal
* Takes netmask and ip strings and returns the numeric values,
@@ -259,68 +262,108 @@ LASIpTreeDealloc(LASIpTree_t *startnode)
* ret code The usual LAS return codes.
*/
static int
-LASIpBuild(NSErr_t *errp, char *attr_name, CmpOp_t comparator, char *attr_pattern, LASIpTree_t **treetop)
+LASIpBuild(NSErr_t *errp, char *attr_name, CmpOp_t comparator, char *attr_pattern, LASIpContext_t *context)
{
unsigned int delimiter; /* length of valid token */
char token[64], token2[64]; /* a single ip[+netmask] */
char *curptr; /* current place in attr_pattern */
- int netmask, ip;
+ int netmask = 0;
+ int ip = 0;
char *plusptr;
- int retcode;
+ int retcode;
- if (NULL == treetop) {
+ if (NULL == context) {
return ACL_RES_ERROR;
}
- /* ip address can be delimited by space, tab, comma, or carriage return
- * only.
+ /*
+ * IP address can be delimited by space, tab, comma, or carriage return only.
*/
curptr = attr_pattern;
do {
delimiter = strcspn(curptr, ", \t");
delimiter = (delimiter <= strlen(curptr)) ? delimiter : strlen(curptr);
strncpy(token, curptr, delimiter);
- if (delimiter >= sizeof(token)) {
+ if (delimiter >= sizeof(token)) {
return LAS_EVAL_INVALID;
- }
+ }
token[delimiter] = '\0';
/* skip all the white space after the token */
- curptr = strpbrk((curptr+delimiter), "1234567890+.*");
-
- /* Is there a netmask? */
- plusptr = strchr(token, '+');
- if (plusptr == NULL) {
- if (curptr && (*curptr == '+')) {
- /* There was a space before (and possibly after) the plus sign*/
- curptr = strpbrk((++curptr), "1234567890.*");
- delimiter = strcspn(curptr, ", \t");
- delimiter = (delimiter <= strlen(curptr)) ? delimiter : strlen(curptr);
- if (delimiter >= sizeof(token2)) {
- return LAS_EVAL_INVALID;
- }
- strncpy(token2, curptr, delimiter);
- token2[delimiter] = '\0';
- retcode = dotdecimal(token, token2, &ip, &netmask);
+ curptr = strpbrk((curptr+delimiter), "1234567890+.*ABCDEFabcdef:/");
+
+ /*
+ * IPv4 addresses do not have ":"
+ */
+ if( strstr(token,":") == NULL ){
+ /* Is there a netmask? */
+ plusptr = strchr(token, '+');
+ if (plusptr == NULL) {
+ if (curptr && (*curptr == '+')) {
+ /* There was a space before (and possibly after) the plus sign*/
+ curptr = strpbrk((++curptr), "1234567890.*");
+ delimiter = strcspn(curptr, ", \t");
+ delimiter = (delimiter <= strlen(curptr)) ? delimiter : strlen(curptr);
+ if (delimiter >= sizeof(token2)) {
+ return LAS_EVAL_INVALID;
+ }
+ strncpy(token2, curptr, delimiter);
+ token2[delimiter] = '\0';
+ retcode = dotdecimal(token, token2, &ip, &netmask);
+ if (retcode)
+ return (retcode);
+ curptr = strpbrk((++curptr), "1234567890+.*");
+ } else {
+ retcode = dotdecimal(token, "255.255.255.255", &ip, &netmask);
+ if (retcode)
+ return (retcode);
+ }
+ } else {
+ /* token is the IP addr string in both cases */
+ *plusptr ='\0'; /* truncate the string */
+ retcode =dotdecimal(token, ++plusptr, &ip, &netmask);
if (retcode)
return (retcode);
- curptr = strpbrk((++curptr), "1234567890+.*");
+ }
+
+ if (LASIpAddPattern(errp, netmask, ip, &context->treetop) != 0)
+ return LAS_EVAL_INVALID;
+ } else {
+ /*
+ * IPv6
+ */
+ PRIPv6Addr ipv6;
+
+ plusptr = strchr(token, '/');
+ if (plusptr == NULL) {
+ if (curptr && (*curptr == '/')) {
+ /* There was a space before (and possibly after) the plus sign */
+ curptr = strpbrk((++curptr), "1234567890.*:ABCDEFabcdef");
+ delimiter = strcspn(curptr, ", \t");
+ delimiter = (delimiter <= strlen(curptr)) ? delimiter : strlen(curptr);
+ strncpy(token2, curptr, delimiter);
+ token2[delimiter] = '\0';
+ retcode = colonhex_ipv6(token, token2, &ipv6, &netmask);
+ if (retcode)
+ return (retcode);
+ curptr = strpbrk((++curptr), "1234567890+.:ABCDEFabcdef*");
+ } else {
+ retcode = colonhex_ipv6(token, "128", &ipv6, &netmask);
+ if (retcode)
+ return (retcode);
+ }
} else {
- retcode =dotdecimal(token, "255.255.255.255", &ip, &netmask);
+ /* token is the IP addr string in both cases */
+ *plusptr ='\0'; /* truncate the string */
+ retcode = colonhex_ipv6(token, ++plusptr, &ipv6, &netmask);
if (retcode)
return (retcode);
}
- } else {
- /* token is the IP addr string in both cases */
- *plusptr ='\0'; /* truncate the string */
- retcode =dotdecimal(token, ++plusptr, &ip, &netmask);
- if (retcode)
- return (retcode);
- }
-
- if (LASIpAddPattern(errp, netmask, ip, treetop) != 0)
- return LAS_EVAL_INVALID;
+ if (LASIpAddPatternIPv6(errp, netmask, &ipv6, &context->treetop_ipv6) != (int)NULL) {
+ return LAS_EVAL_INVALID;
+ }
+ }
} while ((curptr != NULL) && (delimiter != 0));
return 0;
@@ -361,13 +404,15 @@ LASIpAddPattern(NSErr_t *errp, int netmask, int pattern, LASIpTree_t **treetop)
if (*treetop == (LASIpTree_t *)NULL) { /* No tree at all */
curptr = LASIpTreeAllocNode(errp);
if (curptr == NULL) {
- nserrGenerate(errp, ACLERRFAIL, ACLERR5100, ACL_Program, 1, XP_GetAdminStr(DBT_ipLasUnableToAllocateTreeNodeN_));
+ nserrGenerate(errp, ACLERRFAIL, ACLERR5100, ACL_Program, 1,
+ XP_GetAdminStr(DBT_ipLasUnableToAllocateTreeNodeN_));
return ACL_RES_ERROR;
}
*treetop = curptr;
}
- /* Special case if the netmask is 0.
+ /*
+ * Special case if the netmask is 0.
*/
if (stopbit > 31) {
(*treetop)->action[0] = (LASIpTree_t *)LAS_EVAL_TRUE;
@@ -375,24 +420,18 @@ LASIpAddPattern(NSErr_t *errp, int netmask, int pattern, LASIpTree_t **treetop)
return 0;
}
-
/* follow the tree down the pattern path bit by bit until the
* end of the tree is reached (i.e. a constant).
*/
for (curbit=31,curptr=*treetop; curbit >= 0; curbit--) {
-
/* Is the current bit ON? If so set curval to 1 else 0 */
curval = (pattern & (1<<curbit)) ? 1 : 0;
/* Are we done, if so remove the rest of the tree */
if (curbit == stopbit) {
LASIpTreeDealloc(curptr->action[curval]);
- curptr->action[curval] =
- (LASIpTree_t *)LAS_EVAL_TRUE;
-
- /* This is the normal exit point. Most other
- * exits must be due to errors.
- */
+ curptr->action[curval] = (LASIpTree_t *)LAS_EVAL_TRUE;
+ /* This is the normal exit point. Most other exits must be due to errors. */
return 0;
}
@@ -401,7 +440,8 @@ LASIpAddPattern(NSErr_t *errp, int netmask, int pattern, LASIpTree_t **treetop)
newptr = LASIpTreeAllocNode(errp);
if (newptr == NULL) {
LASIpTreeDealloc(*treetop);
- nserrGenerate(errp, ACLERRFAIL, ACLERR5110, ACL_Program, 1, XP_GetAdminStr(DBT_ipLasUnableToAllocateTreeNodeN_1));
+ nserrGenerate(errp, ACLERRFAIL, ACLERR5110, ACL_Program, 1,
+ XP_GetAdminStr(DBT_ipLasUnableToAllocateTreeNodeN_1));
return ACL_RES_ERROR;
}
curptr->action[curval] = newptr;
@@ -451,51 +491,57 @@ int LASIpEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator,
PList_t subject, PList_t resource, PList_t auth_info,
PList_t global_auth)
{
- int bit;
- int value;
- IPAddr_t ip;
- int retcode;
- LASIpTree_t *node;
- LASIpContext_t *context = NULL;
- int rv;
- char ip_str[124];
+ LASIpContext_t *context = NULL;
+ LASIpTree_t *node = NULL;
+ IPAddr_t ip;
+ PRNetAddr *client_addr = NULL;
+ struct in_addr client_inaddr;
+ char ip_str[124];
+ int retcode;
+ int value;
+ int bit;
+ int rc = LAS_EVAL_INVALID;
+ int rv;
*cachable = ACL_INDEF_CACHABLE;
if (strcmp(attr_name, "ip") != 0) {
- nserrGenerate(errp, ACLERRINVAL, ACLERR5200, ACL_Program, 2, XP_GetAdminStr(DBT_lasIpBuildReceivedRequestForAttr_), attr_name);
+ nserrGenerate(errp, ACLERRINVAL, ACLERR5200, ACL_Program, 2,
+ XP_GetAdminStr(DBT_lasIpBuildReceivedRequestForAttr_), attr_name);
return LAS_EVAL_INVALID;
}
if ((comparator != CMP_OP_EQ) && (comparator != CMP_OP_NE)) {
- nserrGenerate(errp, ACLERRINVAL, ACLERR5210, ACL_Program, 2, XP_GetAdminStr(DBT_lasipevalIllegalComparatorDN_), comparator_string(comparator));
+ nserrGenerate(errp, ACLERRINVAL, ACLERR5210, ACL_Program, 2,
+ XP_GetAdminStr(DBT_lasipevalIllegalComparatorDN_), comparator_string(comparator));
return LAS_EVAL_INVALID;
}
- /* GET THE IP ADDR FROM THE SESSION CONTEXT AND STORE IT IN THE
- * VARIABLE ip.
+ /*
+ * Get the IP addr from the session context, and store it in "client_addr
*/
#ifndef UTEST
- rv = ACL_GetAttribute(errp, ACL_ATTR_IP, (void **)&ip,
- subject, resource, auth_info, global_auth);
+ rv = ACL_GetAttribute(errp, ACL_ATTR_IP, (void **)&client_addr, subject, resource, auth_info, global_auth);
if (rv != LAS_EVAL_TRUE) {
if (subject || resource) {
/* Don't ereport if called from ACL_CachableAclList */
- char rv_str[16];
- sprintf(rv_str, "%d", rv);
- nserrGenerate(errp, ACLERRINVAL, ACLERR5220, ACL_Program, 2, XP_GetAdminStr(DBT_lasipevalUnableToGetSessionAddre_), rv_str);
+ char rv_str[16];
+ sprintf(rv_str, "%d", rv);
+ nserrGenerate(errp, ACLERRINVAL, ACLERR5220, ACL_Program, 2,
+ XP_GetAdminStr(DBT_lasipevalUnableToGetSessionAddre_), rv_str);
}
- return LAS_EVAL_FAIL;
+ return LAS_EVAL_FAIL;
}
#else
ip = (IPAddr_t)LASIpGetIp();
#endif
- /* If this is the first time through, build the pattern tree first.
+ /*
+ * If this is the first time through, build the pattern tree first.
*/
if (*LAS_cookie == NULL) {
- if (strcspn(attr_pattern, "0123456789.*,+ \t")) {
+ if (strcspn(attr_pattern, "0123456789.*,+ \tABCDEFabcdef:/")) {
return LAS_EVAL_INVALID;
}
ACL_CritEnter();
@@ -503,13 +549,14 @@ int LASIpEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator,
*LAS_cookie = context =
(LASIpContext_t *)PERM_MALLOC(sizeof(LASIpContext_t));
if (context == NULL) {
- nserrGenerate(errp, ACLERRNOMEM, ACLERR5230, ACL_Program, 1, XP_GetAdminStr(DBT_lasipevalUnableToAllocateContext_));
+ nserrGenerate(errp, ACLERRNOMEM, ACLERR5230, ACL_Program, 1,
+ XP_GetAdminStr(DBT_lasipevalUnableToAllocateContext_));
ACL_CritExit();
return LAS_EVAL_FAIL;
}
context->treetop = NULL;
- retcode = LASIpBuild(errp, attr_name, comparator, attr_pattern,
- &context->treetop);
+ context->treetop_ipv6 = NULL;
+ retcode = LASIpBuild(errp, attr_name, comparator, attr_pattern, context);
if (retcode) {
ACL_CritExit();
return (retcode);
@@ -523,30 +570,194 @@ int LASIpEval(NSErr_t *errp, char *attr_name, CmpOp_t comparator,
context = (LASIpContext *) *LAS_cookie;
ACL_CritExit();
}
+ /*
+ * Check if IP is ipv4/ipv6
+ */
+ if ( PR_IsNetAddrType( client_addr, PR_IpAddrV4Mapped) || client_addr->raw.family == PR_AF_INET ) {
+ /*
+ * IPv4
+ */
+
+ /* Set the appropriate s_addr for ipv4 or ipv4 mapped to ipv6 */
+ if (client_addr->raw.family == PR_AF_INET) {
+ client_inaddr.s_addr = client_addr->inet.ip;
+ } else {
+ client_inaddr.s_addr = client_addr->ipv6.ip._S6_un._S6_u32[3];
+ }
+
+ node = context->treetop;
+ ip = (IPAddr_t)PR_ntohl( client_inaddr.s_addr );
+
+ if(node == NULL){
+ rc = (comparator == CMP_OP_EQ ? LAS_EVAL_FALSE : LAS_EVAL_TRUE);
+ } else {
+ for (bit = 31; bit >= 0; bit--) {
+ value = (ip & (IPAddr_t) (1 << bit)) ? 1 : 0;
+ if (LAS_IP_IS_CONSTANT(node->action[value])){
+ /* Reached a result, so return it */
+ if (comparator == CMP_OP_EQ){
+ rc = (int)(PRSize)node->action[value];
+ break;
+ } else {
+ rc = ((int)(PRSize)node->action[value] == LAS_EVAL_TRUE) ? LAS_EVAL_FALSE : LAS_EVAL_TRUE;
+ break;
+ }
+ } else {
+ /* Move on to the next bit */
+ node = node->action[value];
+ }
+ }
+ }
+ if(rc == LAS_EVAL_INVALID){
+ sprintf(ip_str, "%x", (unsigned int)ip);
+ nserrGenerate(errp, ACLERRINTERNAL, ACLERR5240, ACL_Program, 2,
+ XP_GetAdminStr(DBT_lasipevalReach32BitsWithoutConcl_), ip_str);
+ }
+ } else {
+ /*
+ * IPv6
+ */
+ PRIPv6Addr *ipv6 = &(client_addr->ipv6.ip);
+ LASIpTree_t *node;
+ int bit_position = 15;
+ int field = 0;
+ int addr = 0;
+ int value;
+
+ node = context->treetop_ipv6;
+ if ( node == NULL ) {
+ retcode = (comparator == CMP_OP_EQ ? LAS_EVAL_FALSE : LAS_EVAL_TRUE);
+ } else {
+ addr = PR_ntohs( ipv6->_S6_un._S6_u16[field]);
+ for (bit = 127; bit >= 0 ; bit--, bit_position--) {
+ value = (addr & (1 << bit_position)) ? 1 : 0;
+ if (LAS_IP_IS_CONSTANT(node->action[value])) {
+ /* Reached a result, so return it */
+ if (comparator == CMP_OP_EQ){
+ return(int)(long)node->action[value];
+ } else {
+ return(((int)(long)node->action[value] == LAS_EVAL_TRUE) ? LAS_EVAL_FALSE : LAS_EVAL_TRUE);
+ }
+ } else {
+ node = node->action[value];
+ if ( bit % 16 == 0) {
+ /* Ok, move to the next field in the IPv6 addr: f:f:next:f:f:f:f:f */
+ field++;
+ addr = PR_ntohs( ipv6->_S6_un._S6_u16[field]);
+ bit_position = 15;
+ }
+ }
+ }
+ rc = LAS_EVAL_INVALID;
+ }
+ }
+ return rc;
+}
+
+/*
+ * The ipv6 version of LASIpAddPattern
+ */
+static int
+LASIpAddPatternIPv6(NSErr_t *errp, int netmask, PRIPv6Addr *ipv6, LASIpTree_t **treetop)
+{
+ LASIpTree_t *curptr;
+ LASIpTree_t *newptr;
+ int stopbit;
+ int curbit;
+ int curval;
+ int field = 0; /* (8) 16 bit fields in a IPv6 address: x:x:x:x:x:x:x:x */
+ int addr = 0;
+ int curbit_position = 15; /* 16 bits: 0-15 */
+
+ /* stop at the first 1 in the netmask from low to high */
+ stopbit = 128 - netmask;
- node = context->treetop;
-
- for (bit=31; bit >=0; bit--) {
- value = (ip & (IPAddr_t) (1<<bit)) ? 1 : 0;
- if (LAS_IP_IS_CONSTANT(node->action[value])) {
- /* Reached a result, so return it */
- if (comparator == CMP_OP_EQ)
- return((int)(PRSize)node->action[value]);
- else
- return(((int)(PRSize)node->action[value] ==
- LAS_EVAL_TRUE) ?
- LAS_EVAL_FALSE : LAS_EVAL_TRUE);
-
- } else
- /* Move on to the next bit */
- node = node->action[value];
+ /* Special case if there's no tree. Allocate the first node */
+ if (*treetop == (LASIpTree_t *)NULL) { /* No tree at all */
+ curptr = LASIpTreeAllocNode(errp);
+ if (curptr == NULL) {
+ nserrGenerate(errp, ACLERRFAIL, ACLERR5100, ACL_Program, 1,
+ XP_GetAdminStr(DBT_ipLasUnableToAllocateTreeNodeN_));
+ return ACL_RES_ERROR;
+ }
+ *treetop = curptr;
+ }
+
+ addr = PR_ntohs(ipv6->_S6_un._S6_u16[field]);
+ for (curbit = 127, curptr = *treetop; curbit >= 0; curbit--, curbit_position--){
+ /* Is the current bit ON? If so set curval to 1 else 0 */
+ curval = (addr & (1 << curbit_position)) ? 1 : 0;
+
+ /* Are we done, if so remove the rest of the tree */
+ if (curbit == stopbit) {
+ LASIpTreeDealloc(curptr->action[curval]);
+ curptr->action[curval] = (LASIpTree_t *)LAS_EVAL_TRUE;
+ /* This is the normal exit point. Most other exits must be due to errors. */
+ return 0;
+ }
+
+ /* Oops reached the end - must allocate */
+ if (LAS_IP_IS_CONSTANT(curptr->action[curval])) {
+ newptr = LASIpTreeAllocNode(errp);
+ if (newptr == NULL) {
+ LASIpTreeDealloc(*treetop);
+ nserrGenerate(errp, ACLERRFAIL, ACLERR5110, ACL_Program, 1,
+ XP_GetAdminStr(DBT_ipLasUnableToAllocateTreeNodeN_1));
+ return ACL_RES_ERROR;
+ }
+ curptr->action[curval] = newptr;
+ }
+
+ /* Keep going down the tree */
+ curptr = curptr->action[curval];
+
+ if ( curbit % 16 == 0) {
+ /* Ok, move to the next field in the addr */
+ field++;
+ addr = PR_ntohs(ipv6->_S6_un._S6_u16[field]);
+ curbit_position = 15;
+ }
}
+ return ACL_RES_ERROR;
+}
- /* Cannot reach here. Even a 32 bit mismatch has a conclusion in
- * the pattern tree.
+/*
+ * This is very similar to dotdecimal(), but for ipv6 addresses
+ */
+static int
+colonhex_ipv6(char *ipstr, char *netmaskstr, PRIPv6Addr *ipv6, int *netmask)
+{
+ PRNetAddr addr;
+ /*
+ * Validate netmaskstr - can only be digits
+ */
+ if (strcspn(netmaskstr, "0123456789")){
+ return LAS_EVAL_INVALID;
+ }
+ /*
+ * Validate ipstr - can only have digits, colons, hex chars, and dots
+ */
+ if(strcspn(ipstr, "0123456789:ABCDEFabcdef.")){
+ return LAS_EVAL_INVALID;
+ }
+ /*
+ * validate the netmask - must be between 1 and 128
*/
- sprintf(ip_str, "%x", (unsigned int)ip);
- nserrGenerate(errp, ACLERRINTERNAL, ACLERR5240, ACL_Program, 2, XP_GetAdminStr(DBT_lasipevalReach32BitsWithoutConcl_), ip_str);
- return LAS_EVAL_INVALID;
+ *netmask = atoi(netmaskstr);
+ if(*netmask < 1 || *netmask > 128){
+ return LAS_EVAL_INVALID;
+ }
+ /*
+ * Get the net addr
+ */
+ if (PR_StringToNetAddr(ipstr, &addr) != PR_SUCCESS){
+ return LAS_EVAL_INVALID;
+ }
+ /*
+ * Set the ipv6 addr
+ */
+ *ipv6 = addr.ipv6.ip;
+
+ return 0;
}
diff --git a/lib/libaccess/lasip.h b/lib/libaccess/lasip.h
index c353d9d..c1fe0fc 100644
--- a/lib/libaccess/lasip.h
+++ b/lib/libaccess/lasip.h
@@ -46,5 +46,6 @@ typedef struct LASIpTree {
} LASIpTree_t;
typedef struct LASIpContext {
- LASIpTree_t *treetop; /* Top of the pattern tree */
+ LASIpTree_t *treetop; /* Top of the pattern tree */
+ LASIpTree_t *treetop_ipv6; /* Top of the IPv6 pattern tree */
} LASIpContext_t;
8 years, 3 months
dirsrvtests/tickets
by Noriko Hosoi
dirsrvtests/tickets/ticket48212_test.py | 70 ++++++++++----------------------
1 file changed, 22 insertions(+), 48 deletions(-)
New commits:
commit b31de3346f341509b6ad4e3d109e123eb8ea0443
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Fri Jan 8 14:01:59 2016 -0800
Ticket 48212 - CI test script ticket48212_test.py
Description: Adjusting the the command-line utilities path from
the instance dir to /usr/sbin. The instance dir is not generated
by default since Ticket 47840 - "Description add configure option
to disable instance specific scripts" was committed.
diff --git a/dirsrvtests/tickets/ticket48212_test.py b/dirsrvtests/tickets/ticket48212_test.py
index c3c8c8f..4da6939 100644
--- a/dirsrvtests/tickets/ticket48212_test.py
+++ b/dirsrvtests/tickets/ticket48212_test.py
@@ -9,11 +9,12 @@ from lib389.tools import DirSrvTools
from lib389._constants import *
from lib389.properties import *
from lib389.tasks import *
+from lib389.utils import *
from ldap.controls import SimplePagedResultsControl
log = logging.getLogger(__name__)
-installation_prefix = None
+installation1_prefix = None
MYSUFFIX = 'dc=example,dc=com'
MYSUFFIXBE = 'userRoot'
@@ -25,48 +26,40 @@ class TopologyStandalone(object):
standalone.open()
self.standalone = standalone
-
@pytest.fixture(scope="module")
def topology(request):
- '''
- This fixture is used to standalone topology for the 'module'.
- '''
- global installation_prefix
-
- if installation_prefix:
- args_instance[SER_DEPLOYED_DIR] = installation_prefix
+ global installation1_prefix
+ if installation1_prefix:
+ args_instance[SER_DEPLOYED_DIR] = installation1_prefix
+ # Creating standalone instance ...
standalone = DirSrv(verbose=False)
-
- # Args for the standalone instance
args_instance[SER_HOST] = HOST_STANDALONE
args_instance[SER_PORT] = PORT_STANDALONE
args_instance[SER_SERVERID_PROP] = SERVERID_STANDALONE
+ args_instance[SER_CREATION_SUFFIX] = DEFAULT_SUFFIX
args_standalone = args_instance.copy()
standalone.allocate(args_standalone)
-
- # Get the status of the instance and restart it if it exists
instance_standalone = standalone.exists()
-
- # Remove the instance
if instance_standalone:
standalone.delete()
-
- # Create the instance
standalone.create()
-
- # Used to retrieve configuration information (dbdir, confdir...)
standalone.open()
- # clear the tmp directory
+ # Delete each instance in the end
+ def fin():
+ standalone.delete()
+ request.addfinalizer(fin)
+
+ # Clear out the tmp dir
standalone.clearTmpDir(__file__)
- # Here we have standalone instance up and running
return TopologyStandalone(standalone)
def runDbVerify(topology):
topology.standalone.log.info("\n\n +++++ dbverify +++++\n")
- dbverifyCMD = topology.standalone.sroot + "/slapd-" + topology.standalone.inst + "/dbverify -V"
+ sbin_dir = get_sbin_dir(prefix=topology.standalone.prefix)
+ dbverifyCMD = sbin_dir + "/dbverify -Z " + topology.standalone.inst + " -V"
dbverifyOUT = os.popen(dbverifyCMD, "r")
topology.standalone.log.info("Running %s" % dbverifyCMD)
running = True
@@ -92,7 +85,8 @@ def runDbVerify(topology):
def reindexUidNumber(topology):
topology.standalone.log.info("\n\n +++++ reindex uidnumber +++++\n")
- indexCMD = topology.standalone.sroot + "/slapd-" + topology.standalone.inst + "/db2index.pl -D \"" + DN_DM + "\" -w \"" + PASSWORD + "\" -n " + MYSUFFIXBE + " -t uidnumber"
+ sbin_dir = get_sbin_dir(prefix=topology.standalone.prefix)
+ indexCMD = sbin_dir + "/db2index.pl -Z " + topology.standalone.inst + " -D \"" + DN_DM + "\" -w \"" + PASSWORD + "\" -n " + MYSUFFIXBE + " -t uidnumber"
indexOUT = os.popen(indexCMD, "r")
topology.standalone.log.info("Running %s" % indexCMD)
@@ -118,7 +112,7 @@ def reindexUidNumber(topology):
topology.standalone.log.fatal("%s did not finish" % indexCMD)
assert False
-def test_ticket48212_run(topology):
+def test_ticket48212(topology):
"""
Import posixAccount entries.
Index uidNumber
@@ -180,31 +174,11 @@ def test_ticket48212_run(topology):
runDbVerify(topology)
- topology.standalone.log.info("ticket48212 was successfully verified.")
-
-
-def test_ticket48212_final(topology):
- topology.standalone.delete()
log.info('Testcase PASSED')
-
-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 installation_prefix
- installation_prefix = None
-
- topo = topology(True)
- test_ticket48212_run(topo)
-
- test_ticket48212_final(topo)
-
-
if __name__ == '__main__':
- run_isolated()
+ # Run isolated
+ # -s for DEBUG mode
+ CURRENT_FILE = os.path.realpath(__file__)
+ pytest.main("-s %s" % CURRENT_FILE)
8 years, 3 months
ldap/servers
by Noriko Hosoi
ldap/servers/slapd/tools/ldclt/threadMain.c | 90 ++++++++++++++--------------
1 file changed, 45 insertions(+), 45 deletions(-)
New commits:
commit 005000430e3e43c3048e03da50402a2268def1c4
Author: Noriko Hosoi <nhosoi(a)redhat.com>
Date: Wed Jan 6 14:31:04 2016 -0800
Ticket #48400 - ldclt - segmentation fault error while binding
Descrition: When "-e randombinddn,randombinddnlow=LOW,randombinddnhigh=HIGH"
is given, spaces for bufBaseDN and bufPasswd in the context were not
allocated. The part of the code was enabled only when NEED_FILTER is
set. This patch loosened the condition.
https://fedorahosted.org/389/ticket/48400
Reviewed by wibrown(a)redhat.com (Thank you, William!)
diff --git a/ldap/servers/slapd/tools/ldclt/threadMain.c b/ldap/servers/slapd/tools/ldclt/threadMain.c
index 88353c6..796a8fb 100644
--- a/ldap/servers/slapd/tools/ldclt/threadMain.c
+++ b/ldap/servers/slapd/tools/ldclt/threadMain.c
@@ -890,78 +890,78 @@ threadMain (
}
}
} /*JLS 23-03-01*/
+ } /*JLS 05-03-01*/
- /*
- * Variable base DN ?
- */
- tttctx->bufBaseDN = (char *) malloc (strlen (mctx.baseDN) + 1);
- if (tttctx->bufBaseDN == NULL) /*JLS 06-03-00*/
- { /*JLS 06-03-00*/
+ /*
+ * Variable base DN ?
+ */
+ tttctx->bufBaseDN = (char *) malloc (strlen (mctx.baseDN) + 1);
+ if (tttctx->bufBaseDN == NULL) /*JLS 06-03-00*/
+ { /*JLS 06-03-00*/
printf ("ldclt[%d]: T%03d: cannot malloc(tttctx->bufBaseDN), error=%d (%s)\n",
mctx.pid, tttctx->thrdNum, errno, strerror (errno));
ldcltExit (EXIT_INIT); /*JLS 18-12-00*/
- } /*JLS 06-03-00*/
- if (!(mctx.mode & RANDOM_BASE))
+ } /*JLS 06-03-00*/
+ if (!(mctx.mode & RANDOM_BASE))
strcpy (tttctx->bufBaseDN, mctx.baseDN);
- else
- {
+ else
+ {
tttctx->startBaseDN = strlen (mctx.baseDNHead);
strcpy (tttctx->bufBaseDN, mctx.baseDNHead);
strcpy (&(tttctx->bufBaseDN[tttctx->startBaseDN+mctx.baseDNNbDigit]),
mctx.baseDNTail);
- }
+ }
- /*
- * Variable bind DN ?
- * Do not forget the random bind password below that is activated
- * at the same time as the random bind DN.
- */
- if (mctx.bindDN != NULL) /*JLS 05-03-01*/
- { /*JLS 05-03-01*/
+ /*
+ * Variable bind DN ?
+ * Do not forget the random bind password below that is activated
+ * at the same time as the random bind DN.
+ */
+ if (mctx.bindDN != NULL) /*JLS 05-03-01*/
+ { /*JLS 05-03-01*/
tttctx->bufBindDN = (char *) malloc (strlen (mctx.bindDN) + 1);
if (tttctx->bufBindDN == NULL)
{
- printf ("ldclt[%d]: T%03d: cannot malloc(tttctx->bufBindDN), error=%d (%s)\n",
- mctx.pid, tttctx->thrdNum, errno, strerror (errno));
- ldcltExit (EXIT_INIT);
+ printf ("ldclt[%d]: T%03d: cannot malloc(tttctx->bufBindDN), error=%d (%s)\n",
+ mctx.pid, tttctx->thrdNum, errno, strerror (errno));
+ ldcltExit (EXIT_INIT);
}
if (!(mctx.mode & RANDOM_BINDDN))
- strcpy (tttctx->bufBindDN, mctx.bindDN);
+ strcpy (tttctx->bufBindDN, mctx.bindDN);
else
{
- tttctx->startBindDN = strlen (mctx.bindDNHead);
- strcpy (tttctx->bufBindDN, mctx.bindDNHead);
- strcpy (&(tttctx->bufBindDN[tttctx->startBindDN+mctx.bindDNNbDigit]),
- mctx.bindDNTail);
+ tttctx->startBindDN = strlen (mctx.bindDNHead);
+ strcpy (tttctx->bufBindDN, mctx.bindDNHead);
+ strcpy (&(tttctx->bufBindDN[tttctx->startBindDN+mctx.bindDNNbDigit]),
+ mctx.bindDNTail);
}
- } /*JLS 05-03-01*/
+ } /*JLS 05-03-01*/
- /*
- * Variable bind password ?
- * Remember that the random bind password feature is activated
- * by the same option as the random bind DN, but has here its own
- * code section for the ease of coding.
- */
- if (mctx.passwd != NULL) /*JLS 05-03-01*/
- { /*JLS 05-03-01*/
+ /*
+ * Variable bind password ?
+ * Remember that the random bind password feature is activated
+ * by the same option as the random bind DN, but has here its own
+ * code section for the ease of coding.
+ */
+ if (mctx.passwd != NULL) /*JLS 05-03-01*/
+ { /*JLS 05-03-01*/
tttctx->bufPasswd = (char *) malloc (strlen (mctx.passwd) + 1);
if (tttctx->bufPasswd == NULL)
{
- printf ("ldclt[%d]: T%03d: cannot malloc(tttctx->bufPasswd), error=%d (%s)\n",
- mctx.pid, tttctx->thrdNum, errno, strerror (errno));
- ldcltExit (EXIT_INIT);
+ printf ("ldclt[%d]: T%03d: cannot malloc(tttctx->bufPasswd), error=%d (%s)\n",
+ mctx.pid, tttctx->thrdNum, errno, strerror (errno));
+ ldcltExit (EXIT_INIT);
}
if (!(mctx.mode & RANDOM_BINDDN))
- strcpy (tttctx->bufPasswd, mctx.passwd);
+ strcpy (tttctx->bufPasswd, mctx.passwd);
else
{
- tttctx->startPasswd = strlen (mctx.passwdHead);
- strcpy (tttctx->bufPasswd, mctx.passwdHead);
- strcpy (&(tttctx->bufPasswd[tttctx->startPasswd+mctx.passwdNbDigit]),
- mctx.passwdTail);
+ tttctx->startPasswd = strlen (mctx.passwdHead);
+ strcpy (tttctx->bufPasswd, mctx.passwdHead);
+ strcpy (&(tttctx->bufPasswd[tttctx->startPasswd+mctx.passwdNbDigit]),
+ mctx.passwdTail);
}
- }
- } /*JLS 05-03-01*/
+ }
/*
* Bind DN from a file ?
8 years, 3 months
Branch '389-ds-base-1.3.4' - dirsrvtests/tickets ldap/servers
by Mark Reynolds
dirsrvtests/tickets/ticket48312_test.py | 168 ++++++++++++++++++++++++++++++++
ldap/servers/plugins/mep/mep.c | 18 ++-
ldap/servers/slapd/modrdn.c | 24 ++--
3 files changed, 197 insertions(+), 13 deletions(-)
New commits:
commit 5b7d42e4d11040ab8394e2867787481a79c7453f
Author: Mark Reynolds <mreynolds(a)redhat.com>
Date: Mon Oct 19 12:53:53 2015 -0400
Ticket 48312 - Crash when doing modrdn on managed entry
Bug Description: If performing a modrdn on a managed entry, where the new
rdn begins with a "+", the server will crash. This is
caused by the way MEP creates the new managed entry - where
it uses the rdn attribute value from the attribute,
and not the DN. So in this case the DN rdn value escapes
the "+", but it is not escaped in the rdn attribute in
the entry. Then the internal modrdn setup thinks it
is a multivalued RDN, and the first RDN ends up being null.
This actually generates an error, but we don't return an error
from slapi_rename_internal_set_pb_ext(), and the operation
is not set in the pblock. Then slapi_modrdn_internal_pb()
dereferences the operation struct, and we crash.
Fix Description: Instead when updating the managed entry during the modrdn
get the DN value from the DN(which is already escaped), and
not from the attribute value from the entry(which is not escaped).
Also improved the modrdn code to check for NULL operations
in the pblock, report an error, and not dereference them.
https://fedorahosted.org/389/ticket/48312
Reviewed by: nhosoi(Thanks!)
(cherry picked from commit 6f8c5550733bd7aad116230813ec85975ae7d657)
diff --git a/dirsrvtests/tickets/ticket48312_test.py b/dirsrvtests/tickets/ticket48312_test.py
new file mode 100644
index 0000000..0989279
--- /dev/null
+++ b/dirsrvtests/tickets/ticket48312_test.py
@@ -0,0 +1,168 @@
+import os
+import sys
+import time
+import ldap
+import logging
+import pytest
+from lib389 import DirSrv, Entry, tools, tasks
+from lib389.tools import DirSrvTools
+from lib389._constants import *
+from lib389.properties import *
+from lib389.tasks import *
+from lib389.utils import *
+
+logging.getLogger(__name__).setLevel(logging.DEBUG)
+log = logging.getLogger(__name__)
+
+installation1_prefix = None
+
+
+class TopologyStandalone(object):
+ def __init__(self, standalone):
+ standalone.open()
+ self.standalone = standalone
+
+
+(a)pytest.fixture(scope="module")
+def topology(request):
+ global installation1_prefix
+ if installation1_prefix:
+ args_instance[SER_DEPLOYED_DIR] = installation1_prefix
+
+ # Creating standalone instance ...
+ standalone = DirSrv(verbose=False)
+ args_instance[SER_HOST] = HOST_STANDALONE
+ args_instance[SER_PORT] = PORT_STANDALONE
+ args_instance[SER_SERVERID_PROP] = SERVERID_STANDALONE
+ args_instance[SER_CREATION_SUFFIX] = DEFAULT_SUFFIX
+ args_standalone = args_instance.copy()
+ standalone.allocate(args_standalone)
+ instance_standalone = standalone.exists()
+ if instance_standalone:
+ standalone.delete()
+ standalone.create()
+ standalone.open()
+
+ # Delete each instance in the end
+ def fin():
+ standalone.delete()
+
+ request.addfinalizer(fin)
+
+ # Clear out the tmp dir
+ standalone.clearTmpDir(__file__)
+
+ return TopologyStandalone(standalone)
+
+
+def test_ticket48312(topology):
+ """
+ Configure managed entries plugins(tempalte/definition), then perform a
+ modrdn(deleteoldrdn 1), and make sure the server does not crash.
+ """
+
+ GROUP_OU = 'ou=groups,' + DEFAULT_SUFFIX
+ PEOPLE_OU = 'ou=people,' + DEFAULT_SUFFIX
+ USER_DN = 'uid=user1,ou=people,' + DEFAULT_SUFFIX
+ CONFIG_DN = 'cn=config,cn=' + PLUGIN_MANAGED_ENTRY + ',cn=plugins,cn=config'
+ TEMPLATE_DN = 'cn=MEP Template,' + DEFAULT_SUFFIX
+ USER_NEWRDN = 'uid=\+user1'
+
+ #
+ # First enable dynamic plugins
+ #
+ try:
+ topology.standalone.modify_s(DN_CONFIG, [(ldap.MOD_REPLACE, 'nsslapd-dynamic-plugins', 'on')])
+ except ldap.LDAPError as e:
+ ldap.fatal('Failed to enable dynamic plugin!' + e.message['desc'])
+ assert False
+ topology.standalone.plugins.enable(name=PLUGIN_MANAGED_ENTRY)
+
+ #
+ # Add our org units (they should already exist, but do it just in case)
+ #
+ try:
+ topology.standalone.add_s(Entry((PEOPLE_OU, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'ou': 'people'})))
+ except ldap.ALREADY_EXISTS:
+ pass
+ except ldap.LDAPError as e:
+ log.fatal('test_mep: Failed to add people org unit: error ' + e.message['desc'])
+ assert False
+
+ try:
+ topology.standalone.add_s(Entry((GROUP_OU, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'ou': 'people'})))
+ except ldap.ALREADY_EXISTS:
+ pass
+ except ldap.LDAPError as e:
+ log.fatal('test_mep: Failed to add people org unit: error ' + e.message['desc'])
+ assert False
+
+ #
+ # Add the template entry
+ #
+ try:
+ topology.standalone.add_s(Entry((TEMPLATE_DN, {
+ 'objectclass': 'top mepTemplateEntry extensibleObject'.split(),
+ 'cn': 'MEP Template',
+ 'mepRDNAttr': 'cn',
+ 'mepStaticAttr': ['objectclass: posixGroup', 'objectclass: extensibleObject'],
+ 'mepMappedAttr': ['cn: $uid', 'uid: $cn', 'gidNumber: $uidNumber']
+ })))
+ except ldap.LDAPError as e:
+ log.fatal('test_mep: Failed to add template entry: error ' + e.message['desc'])
+ assert False
+
+ #
+ # Add the definition entry
+ #
+ try:
+ topology.standalone.add_s(Entry((CONFIG_DN, {
+ 'objectclass': 'top extensibleObject'.split(),
+ 'cn': 'config',
+ 'originScope': PEOPLE_OU,
+ 'originFilter': 'objectclass=posixAccount',
+ 'managedBase': GROUP_OU,
+ 'managedTemplate': TEMPLATE_DN
+ })))
+ except ldap.LDAPError as e:
+ log.fatal('test_mep: Failed to add config entry: error ' + e.message['desc'])
+ assert False
+
+ #
+ # Add an entry that meets the MEP scope
+ #
+ try:
+ topology.standalone.add_s(Entry((USER_DN, {
+ 'objectclass': 'top posixAccount extensibleObject'.split(),
+ 'uid': 'user1',
+ 'cn': 'user1',
+ 'uidNumber': '1',
+ 'gidNumber': '1',
+ 'homeDirectory': '/home/user1',
+ 'description': 'uiser description'
+ })))
+ except ldap.LDAPError as e:
+ log.fatal('test_mep: Failed to user1: error ' + e.message['desc'])
+ assert False
+
+ #
+ # Perform a modrdn on USER_DN
+ #
+ try:
+ topology.standalone.rename_s(USER_DN, USER_NEWRDN, delold=1)
+ except ldap.LDAPError as e:
+ log.error('Failed to modrdn: error ' + e.message['desc'])
+ assert False
+
+ log.info('Test complete')
+
+
+if __name__ == '__main__':
+ # Run isolated
+ # -s for DEBUG mode
+ CURRENT_FILE = os.path.realpath(__file__)
+ pytest.main("-s %s" % CURRENT_FILE)
\ No newline at end of file
diff --git a/ldap/servers/plugins/mep/mep.c b/ldap/servers/plugins/mep/mep.c
index 4399851..46acb4b 100644
--- a/ldap/servers/plugins/mep/mep.c
+++ b/ldap/servers/plugins/mep/mep.c
@@ -1309,19 +1309,29 @@ mep_create_managed_entry(struct configEntry *config, Slapi_Entry *origin)
goto done;
} else {
/* Build the DN and set it in the entry. */
- char *dn = NULL;
+ char **rdn_vals = NULL;
char *rdn_val = NULL;
+ char *dn = NULL;
/* If an origin entry was supplied, the RDN value will be
* the mapped value. If no origin entry was supplied, the
* value will be the mapping rule from the template. */
- rdn_val = slapi_entry_attr_get_charptr(managed_entry, rdn_type);
+ if (origin){
+ const char *origin_dn = slapi_entry_get_dn(origin);
+ rdn_vals = slapi_ldap_explode_dn(origin_dn, 1);
+ rdn_val = rdn_vals[0];
+ } else {
+ rdn_val = slapi_entry_attr_get_charptr(managed_entry, rdn_type);
+ }
/* Create the DN using the mapped RDN value
* and the base specified in the config. */
dn = slapi_ch_smprintf("%s=%s,%s", rdn_type, rdn_val, config->managed_base);
-
- slapi_ch_free_string(&rdn_val);
+ if(origin){
+ slapi_ldap_value_free(rdn_vals);
+ } else {
+ slapi_ch_free_string(&rdn_val);
+ }
if (dn != NULL) {
slapi_sdn_set_dn_passin(slapi_entry_get_sdn(managed_entry), dn);
diff --git a/ldap/servers/slapd/modrdn.c b/ldap/servers/slapd/modrdn.c
index 798d3d4..e80e1f9 100644
--- a/ldap/servers/slapd/modrdn.c
+++ b/ldap/servers/slapd/modrdn.c
@@ -338,20 +338,26 @@ slapi_rename_internal_set_pb_ext(Slapi_PBlock *pb,
static int rename_internal_pb (Slapi_PBlock *pb)
{
- LDAPControl **controls;
- Operation *op;
- int opresult = 0;
+ LDAPControl **controls;
+ Operation *op;
+ int opresult = 0;
PR_ASSERT (pb != NULL);
slapi_pblock_get(pb, SLAPI_CONTROLS_ARG, &controls);
-
- slapi_pblock_get(pb, SLAPI_OPERATION, &op);
- op->o_handler_data = &opresult;
- op->o_result_handler = internal_getresult_callback;
+ slapi_pblock_get(pb, SLAPI_OPERATION, &op);
+ if (!op) {
+ opresult = 1;
+ slapi_pblock_set(pb, SLAPI_PLUGIN_INTOP_RESULT, &opresult);
+ slapi_log_error(SLAPI_LOG_FATAL, "rename_internal_pb",
+ "Internal error: pblock was not properly initialized\n");
+ return -1;
+ }
+ op->o_handler_data = &opresult;
+ op->o_result_handler = internal_getresult_callback;
slapi_pblock_set(pb, SLAPI_REQCONTROLS, controls);
-
+
/* set parameters common for all internal operations */
set_common_params (pb);
@@ -359,7 +365,7 @@ static int rename_internal_pb (Slapi_PBlock *pb)
set_config_params (pb);
op_shared_rename (pb, 0 /* not passing ownership of args */ );
-
+
slapi_pblock_set(pb, SLAPI_PLUGIN_INTOP_RESULT, &opresult);
return 0;
8 years, 3 months
dirsrvtests/tmp ldap/servers
by William Brown
ldap/servers/plugins/uiduniq/7bit.c | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
New commits:
commit d07d1b5d63afc0a2875faaca3fa3811799e0e65b
Author: William Brown <firstyear(a)redhat.com>
Date: Wed Dec 23 13:33:56 2015 +1000
Ticket 48395 - ASAN - Use after free in uiduniq 7bit.c
Bug Description: Asan detected a use after free in 7bit.c during a modrdn
operation. This may cause the directory to crash if a specially crafted modrdn
request is made, or may be exploitable in some other way.
Fix Description: We move the issue_error directive before the slapi_entry is
freed, which means that we are using before the free instead.
https://fedorahosted.org/389/ticket/48395
Author: wibrown
Review by: nhosoi (Thank you!)
diff --git a/dirsrvtests/tmp/__init__.py b/dirsrvtests/tmp/__init__.py
deleted file mode 100644
index e69de29..0000000
diff --git a/ldap/servers/plugins/uiduniq/7bit.c b/ldap/servers/plugins/uiduniq/7bit.c
index bb7dc64..fe43f98 100644
--- a/ldap/servers/plugins/uiduniq/7bit.c
+++ b/ldap/servers/plugins/uiduniq/7bit.c
@@ -650,17 +650,20 @@ preop_modrdn(Slapi_PBlock *pb)
}
}
/* don't have to go on if there is a value not 7-bit clean */
- if (result) break;
+ if (result) {
+ /* WB we need to issue the error before we free slapi_entry, else we
+ * are triggering a use after free because we free violated.
+ */
+ issue_error(pb, result, "MODRDN", violated);
+ break;
+ }
+
}
END
/* Clean-up */
if (e) slapi_entry_free(e);
- if (result) {
- issue_error(pb, result, "MODRDN", violated);
- }
-
return (result==LDAP_SUCCESS)?0:-1;
}
8 years, 3 months