From 4a8ab5dbf2ba037b0824d64bb3217ca06671884a Mon Sep 17 00:00:00 2001
From: Pierangelo Masarati <ando@openldap.org>
Date: Mon, 8 Apr 2002 09:43:22 +0000
Subject: [PATCH] Mostly based on patches provided by Hallvard B. Furuseth

ITS#1677 - cast away const warnings
ITS#1678 - unsigned char args to ctype funcs
ITS#1682 - don't redefine ldap_debug
ITS#1683 - uninitialized vars
ITS#1703 - ldo_debug initialization
ITS#1705 - unsigned testing
ITS#1706 - socklen_t args
ITS#1719 - back-tcl update (other cleanups/fixes/improvements; yet untested)
ITS#1724 - integerNormalize/integerFilter/integerIndexer bugs
ITS#1725 - libdes not required

Implement back-null (/dev/null style backend)
Cleanup some misc warnings ("%lu" format, unused/uninitialized vars,
        ambiguous operator precedence)

Kurt, please regenerate configure
---
 clients/tools/ldapwhoami.c             |   1 -
 configure.in                           |  44 ++++-
 doc/man/man5/slapd.access.5            |  17 +-
 doc/man/man5/slapd.conf.5              |  33 +++-
 doc/man/man8/slapd.8                   |   2 +-
 include/ldap_pvt_uc.h                  |   6 +-
 include/portable.h.in                  |   6 +
 include/portable.nt                    |   6 +
 libraries/liblber/bprint.c             |   2 +-
 libraries/libldap/dntest.c             |   4 +-
 libraries/libldap/ftest.c              |   1 -
 libraries/libldap/getdn.c              |   2 +-
 libraries/libldap/ldap-int.h           |   2 +-
 libraries/libldap/os-ip.c              |   6 +-
 libraries/libldap/os-local.c           |   4 +-
 libraries/libldap/tls.c                |   2 +-
 libraries/libldap/url.c                |   4 +-
 libraries/libldap/utf-8.c              |   2 +-
 libraries/libldif/line64.c             |   8 +-
 libraries/liblutil/entropy.c           |   2 +-
 libraries/librewrite/config.c          |   4 +-
 libraries/librewrite/context.c         |   6 +-
 libraries/librewrite/map.c             |   6 +-
 libraries/librewrite/parse.c           |   8 +-
 libraries/librewrite/session.c         |   6 +-
 libraries/librewrite/subst.c           |   2 +-
 libraries/librewrite/var.c             |   4 +-
 servers/slapd/add.c                    |   2 +-
 servers/slapd/back-bdb/cache.c         |   2 +-
 servers/slapd/back-bdb/search.c        |   1 -
 servers/slapd/back-bdb/tools.c         |   2 -
 servers/slapd/back-dnssrv/bind.c       |   2 +-
 servers/slapd/back-dnssrv/config.c     |   1 -
 servers/slapd/back-dnssrv/referral.c   |   4 +-
 servers/slapd/back-dnssrv/search.c     |   4 +-
 servers/slapd/back-ldap/bind.c         |   4 +-
 servers/slapd/back-ldap/config.c       |   7 +-
 servers/slapd/back-ldbm/attribute.c    |   7 +-
 servers/slapd/back-ldbm/modrdn.c       |   1 -
 servers/slapd/back-ldbm/passwd.c       |   2 +-
 servers/slapd/back-meta/search.c       |   1 +
 servers/slapd/back-monitor/README      |  36 +++-
 servers/slapd/back-monitor/backend.c   |   2 +-
 servers/slapd/back-monitor/time.c      |   8 +-
 servers/slapd/back-null/Makefile.in    |  26 +++
 servers/slapd/back-null/README         |  14 ++
 servers/slapd/back-null/external.h     |  33 ++++
 servers/slapd/back-null/null.c         | 236 +++++++++++++++++++++++++
 servers/slapd/back-tcl/README.back-tcl |  30 ++--
 servers/slapd/back-tcl/tcl_abandon.c   |  18 +-
 servers/slapd/back-tcl/tcl_add.c       |  26 +--
 servers/slapd/back-tcl/tcl_back.h      |  21 +--
 servers/slapd/back-tcl/tcl_bind.c      |  23 +--
 servers/slapd/back-tcl/tcl_compare.c   |  33 ++--
 servers/slapd/back-tcl/tcl_config.c    |  21 ++-
 servers/slapd/back-tcl/tcl_delete.c    |  28 +--
 servers/slapd/back-tcl/tcl_init.c      |  42 +++--
 servers/slapd/back-tcl/tcl_modify.c    |  65 ++++---
 servers/slapd/back-tcl/tcl_modrdn.c    |  43 +++--
 servers/slapd/back-tcl/tcl_search.c    |  42 ++---
 servers/slapd/back-tcl/tcl_unbind.c    |  22 +--
 servers/slapd/back-tcl/tcl_util.c      |  39 ++++
 servers/slapd/backend.c                |   6 +
 servers/slapd/bind.c                   |   2 +-
 servers/slapd/charray.c                |   2 +-
 servers/slapd/compare.c                |   6 +-
 servers/slapd/delete.c                 |   2 +-
 servers/slapd/entry.c                  |   2 +-
 servers/slapd/limits.c                 |   4 +-
 servers/slapd/modify.c                 |   2 +-
 servers/slapd/modrdn.c                 |   2 +-
 servers/slapd/schema_init.c            |  70 +++++++-
 servers/slapd/search.c                 |   2 +-
 servers/slapd/tools/slapadd.c          |   3 +-
 servers/slapd/unbind.c                 |   2 +-
 servers/slurpd/ldap_op.c               |   8 +-
 servers/slurpd/ri.c                    |   2 +-
 77 files changed, 876 insertions(+), 277 deletions(-)
 create mode 100644 servers/slapd/back-null/Makefile.in
 create mode 100644 servers/slapd/back-null/README
 create mode 100644 servers/slapd/back-null/external.h
 create mode 100644 servers/slapd/back-null/null.c

diff --git a/clients/tools/ldapwhoami.c b/clients/tools/ldapwhoami.c
index fc7c44cee2..d69e35faa4 100644
--- a/clients/tools/ldapwhoami.c
+++ b/clients/tools/ldapwhoami.c
@@ -93,7 +93,6 @@ main( int argc, char *argv[] )
 	int		use_tls = 0;
 	int		referrals = 0;
 	LDAP	       *ld = NULL;
-	struct berval *bv = NULL;
 
 	int id, code = LDAP_OTHER;
 	LDAPMessage *res;
diff --git a/configure.in b/configure.in
index 68d7e63274..e76123546d 100644
--- a/configure.in
+++ b/configure.in
@@ -199,6 +199,9 @@ OL_ARG_WITH(meta_module,[    --with-meta-module	  module type], static,
 OL_ARG_ENABLE(monitor,[    --enable-monitor	  enable monitor backend], no)dnl
 OL_ARG_WITH(monitor_module,[    --with-monitor-module module type], static,
 	[static dynamic])
+OL_ARG_ENABLE(null,[    --enable-null	  enable null backend], no)dnl
+OL_ARG_WITH(null_module,[    --with-null-module	module type], static,
+	[static dynamic])
 OL_ARG_ENABLE(passwd,[    --enable-passwd	  enable passwd backend], no)dnl
 OL_ARG_WITH(passwd_module,[    --with-passwd-module  module type], static,
 	[static dynamic])
@@ -252,6 +255,9 @@ if test $ol_enable_slapd = no ; then
 	if test $ol_enable_monitor = yes ; then
 		AC_MSG_WARN([slapd disabled, ignoring --enable-monitor argument])
 	fi
+	if test $ol_enable_null = yes ; then
+		AC_MSG_WARN([slapd disabled, ignoring --enable-null argument])
+	fi
 	if test $ol_enable_passwd = yes ; then
 		AC_MSG_WARN([slapd disabled, ignoring --enable-passwd argument])
 	fi
@@ -309,6 +315,9 @@ dnl	fi
 	if test $ol_with_monitor_module != static ; then
 		AC_MSG_WARN([slapd disabled, ignoring --with-monitor-module argument])
 	fi
+	if test $ol_with_null_module != static ; then
+		AC_MSG_WARN([slapd disabled, ignoring --with-null-module argument])
+	fi
 	if test $ol_with_passwd_module != static ; then
 		AC_MSG_WARN([slapd disabled, ignoring --with-passwd-module argument])
 	fi
@@ -338,6 +347,7 @@ dnl	fi
 	ol_enable_ldbm=no
 	ol_enable_meta=no
 	ol_enable_monitor=no
+	ol_enable_null=no
 	ol_enable_passwd=no
 	ol_enable_perl=no
 	ol_enable_shell=no
@@ -361,6 +371,7 @@ dnl	ol_enable_multimaster=no
 	ol_with_ldbm_module=static
 	ol_with_meta_module=static
 	ol_with_monitor_module=static
+	ol_with_null_module=static
 	ol_with_passwd_module=static
 	ol_with_perl_module=static
 	ol_with_shell_module=static
@@ -392,6 +403,7 @@ elif test $ol_enable_ldbm = no ; then
 		$ol_enable_ldap = no -a \
 		$ol_enable_meta = no -a \
 		$ol_enable_monitor = no -a \
+		$ol_enable_null = no -a \
 		$ol_enable_passwd = no -a \
 		$ol_enable_perl = no -a \
 		$ol_enable_shell = no -a \
@@ -506,6 +518,7 @@ BUILD_LDAP=no
 BUILD_LDBM=no
 BUILD_META=no
 BUILD_MONITOR=no
+BUILD_NULL=no
 BUILD_PASSWD=no
 BUILD_PERL=no
 BUILD_SHELL=no
@@ -518,6 +531,7 @@ BUILD_LDAP_DYNAMIC=static
 BUILD_LDBM_DYNAMIC=static
 BUILD_META_DYNAMIC=static
 BUILD_MONITOR_DYNAMIC=static
+BUILD_NULL_DYNAMIC=static
 BUILD_PASSWD_DYNAMIC=static
 BUILD_PERL_DYNAMIC=static
 BUILD_SHELL_DYNAMIC=static
@@ -734,6 +748,7 @@ else
 	ol_with_ldbm_module=static
 	ol_with_meta_module=static
 	ol_with_monitor_module=static
+	ol_with_null_module=static
 	ol_with_passwd_module=static
 	ol_with_perl_module=static
 	ol_with_shell_module=static
@@ -1048,11 +1063,15 @@ if test $ol_with_kerberos = yes -o $ol_with_kerberos = auto \
 				[-l$krb5crypto -lcom_err])
 
 		elif test $krb5_impl = heimdal; then
+			AC_CHECK_LIB(des, main,
+				[krb5crypto=des],
+				[krb5crypto=crypto])
+
 			AC_CHECK_LIB(krb5, main,
 				[have_krb5=yes
-				KRB5_LIBS="-lkrb5 -ldes -lasn1 -lroken -lcom_err"],
+				KRB5_LIBS="-lkrb5 -l$krb5crypto -lasn1 -lroken -lcom_err"],
 				[have_krb5=no],
-				[-ldes -lasn1 -lroken -lcom_err])
+				[-l$krb5crypto -lasn1 -lroken -lcom_err])
 
 			AC_DEFINE(HAVE_HEIMDAL_KERBEROS, 1,
 				[define if you have HEIMDAL Kerberos])
@@ -1097,7 +1116,7 @@ if test $ol_link_krb5 = yes -a \( $ol_with_kerberos = yes -o \
 		elif test $krb5_impl = heimdal; then
 			AC_CHECK_LIB(krb4, main, [have_k425=yes
 				KRB4_LIBS="-lkrb4"], [have_k425=no],
-				[-lkrb5 -ldes -lasn1 -lroken -lcom_err])
+				[-lkrb5 -l$krb5crypto -lasn1 -lroken -lcom_err])
 
 		else
 			have_425=no
@@ -2599,6 +2618,22 @@ if test "$ol_enable_monitor" != no ; then
 	fi
 fi
 
+if test "$ol_enable_null" != no ; then
+	AC_DEFINE(SLAPD_NULL,1,[define to support NULL backend])
+	BUILD_SLAPD=yes
+	BUILD_NULL=yes
+	if test "$ol_with_null_module" != static ; then
+		AC_DEFINE(SLAPD_NULL_DYNAMIC,1,
+			[define to support dynamic NULL backend])
+		BUILD_NULL=mod
+		BUILD_NULL_DYNAMIC=shared
+		SLAPD_MODULES_LIST="$SLAPD_MODULES_LIST -dlopen \$(SLAP_DIR)back-null/back_null.la"
+		SLAPD_DYNAMIC_BACKENDS="$SLAPD_DYNAMIC_BACKENDS back-null"
+	else
+		SLAPD_STATIC_BACKENDS="$SLAPD_STATIC_BACKENDS back-null"
+	fi
+fi
+
 if test "$ol_enable_passwd" != no ; then
 	AC_DEFINE(SLAPD_PASSWD,1,[define to support PASSWD backend])
 	BUILD_SLAPD=yes
@@ -2715,6 +2750,7 @@ AC_SUBST(BUILD_SLAPD)
   AC_SUBST(BUILD_LDBM)
   AC_SUBST(BUILD_META)
   AC_SUBST(BUILD_MONITOR)
+  AC_SUBST(BUILD_NULL)
   AC_SUBST(BUILD_PASSWD)
   AC_SUBST(BUILD_PERL)
   AC_SUBST(BUILD_SHELL)
@@ -2726,6 +2762,7 @@ AC_SUBST(BUILD_SLAPD)
   AC_SUBST(BUILD_LDBM_DYNAMIC)
   AC_SUBST(BUILD_META_DYNAMIC)
   AC_SUBST(BUILD_MONITOR_DYNAMIC)
+  AC_SUBST(BUILD_NULL_DYNAMIC)
   AC_SUBST(BUILD_PASSWD_DYNAMIC)
   AC_SUBST(BUILD_PERL_DYNAMIC)
   AC_SUBST(BUILD_SHELL_DYNAMIC)
@@ -2813,6 +2850,7 @@ servers/slapd/back-ldap/Makefile:build/top.mk:servers/slapd/back-ldap/Makefile.i
 servers/slapd/back-ldbm/Makefile:build/top.mk:servers/slapd/back-ldbm/Makefile.in:build/mod.mk \
 servers/slapd/back-meta/Makefile:build/top.mk:servers/slapd/back-meta/Makefile.in:build/mod.mk \
 servers/slapd/back-monitor/Makefile:build/top.mk:servers/slapd/back-monitor/Makefile.in:build/mod.mk \
+servers/slapd/back-null/Makefile:build/top.mk:servers/slapd/back-null/Makefile.in:build/mod.mk \
 servers/slapd/back-passwd/Makefile:build/top.mk:servers/slapd/back-passwd/Makefile.in:build/mod.mk \
 servers/slapd/back-perl/Makefile:build/top.mk:servers/slapd/back-perl/Makefile.in:build/mod.mk \
 servers/slapd/back-shell/Makefile:build/top.mk:servers/slapd/back-shell/Makefile.in:build/mod.mk \
diff --git a/doc/man/man5/slapd.access.5 b/doc/man/man5/slapd.access.5
index b2a0cb8df4..87a97f2bc9 100644
--- a/doc/man/man5/slapd.access.5
+++ b/doc/man/man5/slapd.access.5
@@ -139,13 +139,13 @@ It can have the forms
 	users
 	self
 
-	dn[.<dnstyle>]=<pattern>
+	dn[.<dnstyle>[,<modifier>]]=<pattern>
 	dnattr=<attrname>
 	group[/<objectclass>[/<attrname>]]
 		[.<style>]=<pattern>
 	peername[.<style>]=<pattern>
 	sockname[.<style>]=<pattern>
-	domain[.<style>]=<pattern>
+	domain[.<domainstyle>[,<modifier>]]=<pattern>
 	sockurl[.<style>]=<pattern>
 	set[.<style>]=<pattern>
 
@@ -254,7 +254,18 @@ The same
 .B style
 rules for pattern match described for the
 .B group
-case apply.
+case apply. 
+The
+.BR domain 
+clause also allows the
+.B subtree
+style, which succeeds when a fully qualified name exactly matches the
+.BR domain
+pattern, or its trailing part, after a 
+.BR dot ,
+exactly matches the 
+.BR domain
+pattern.
 .LP
 The statement
 .B set=<pattern>
diff --git a/doc/man/man5/slapd.conf.5 b/doc/man/man5/slapd.conf.5
index 6227c02572..049e4c8020 100644
--- a/doc/man/man5/slapd.conf.5
+++ b/doc/man/man5/slapd.conf.5
@@ -277,7 +277,6 @@ and
 .BR timelimit ;
 no limit is set on 
 .BR unchecked .
-This feature is currently exploited by the ldbm backend only.
 .RE
 .TP
 .B loglevel <integer>
@@ -418,6 +417,11 @@ conditions are currently same.
 may be used to require no conditions (useful for clearly globally
 set conditions within a particular database).
 .TP
+.B reverse-lookup on | off
+Enable/disable client name reverse lookup (default is 
+.BR on 
+if compiled with --enable-rlookups).
+.TP
 .B rootDSE <file>
 Specify the name of an LDIF(5) file containing user defined attributes
 for the root DSE.  These attributes are returned in addition to the
@@ -682,10 +686,19 @@ type of backend.
 .B backend <databasetype>
 Mark the beginning of a backend definition. <databasetype>
 should be one of
+.B bdb,
+.B dnssrv,
+.B ldap,
 .B ldbm,
+.B meta,
+.B monitor,
+.B null,
+.B passwd,
+.B perl,
 .B shell,
+.B sql,
 or
-.B passwd
+.B tcl,
 depending on which backend will serve the database.
 
 .SH GENERAL DATABASE OPTIONS
@@ -697,10 +710,18 @@ type of backend.
 Mark the beginning of a new database instance definition. <databasetype>
 should be one of
 .B bdb,
+.B dnssrv,
+.B ldap,
 .B ldbm,
+.B meta,
+.B monitor,
+.B null,
+.B passwd,
+.B perl,
 .B shell,
+.B sql,
 or
-.B passwd
+.B tcl,
 depending on which backend will serve the database.
 .TP
 .B lastmod on | off
@@ -806,7 +827,7 @@ required for each database definition.
 .B subordinate
 Specify that the current backend database is a subordinate of another
 backend database. A subordinate database may have only one suffix. This
-option may bse used to glue multiple databases into a single namingContext.
+option may be used to glue multiple databases into a single namingContext.
 If the suffix of the current database is within the namingContext of a
 superior database, searches against the superior database will be
 propagated to the subordinate as well. All of the databases
@@ -969,6 +990,10 @@ file.
 .B file <filename>
 Specifies an alternate passwd file to use.  The default is
 .B /etc/passwd.
+.SH OTHER DATABASE-SPECIFIC OPTIONS
+Other databases may allow specific configuration options; they will be
+documented separately since most of these databases are very specific
+or experimental.
 .SH EXAMPLE
 "OpenLDAP Administrator's Guide" contains an annotated
 example of a configuration file.
diff --git a/doc/man/man8/slapd.8 b/doc/man/man8/slapd.8
index 209818ad19..2886953084 100644
--- a/doc/man/man8/slapd.8
+++ b/doc/man/man8/slapd.8
@@ -124,7 +124,7 @@ Specifies a chroot "jail" directory.  slapd will
 .BR chdir (2)
 then
 .BR chroot (2)
-to this directory after opening listeners but before any reading
+to this directory after opening listeners but before reading
 any configuration file or initializing any backend.
 .TP
 .BI \-u " user"
diff --git a/include/ldap_pvt_uc.h b/include/ldap_pvt_uc.h
index 1cc84620eb..6a2e4af264 100644
--- a/include/ldap_pvt_uc.h
+++ b/include/ldap_pvt_uc.h
@@ -84,16 +84,16 @@ LDAP_F (char*) ldap_utf8_strtok( char* sp, const char* sep, char **last);
 LDAP_V (const char) ldap_utf8_lentab[128];
 LDAP_V (const char) ldap_utf8_mintab[32];
 
-#define LDAP_UTF8_ISASCII(p) ( !(*(unsigned char *)(p) & 0x80 ) )
+#define LDAP_UTF8_ISASCII(p) ( !(*(const unsigned char *)(p) & 0x80 ) )
 #define LDAP_UTF8_CHARLEN(p) ( LDAP_UTF8_ISASCII(p) \
-	? 1 : ldap_utf8_lentab[*(unsigned char *)(p) ^ 0x80] )
+	? 1 : ldap_utf8_lentab[*(const unsigned char *)(p) ^ 0x80] )
 
 /* This is like CHARLEN but additionally validates to make sure
  * the char used the shortest possible encoding.
  * 'l' is used to temporarily hold the result of CHARLEN.
  */
 #define LDAP_UTF8_CHARLEN2(p, l) ( ( ( l = LDAP_UTF8_CHARLEN( p )) < 3 || \
-	( ldap_utf8_mintab[*(unsigned char *)(p) & 0x1f] & (p)[1] ) ) ? \
+	( ldap_utf8_mintab[*(const unsigned char *)(p) & 0x1f] & (p)[1] ) ) ? \
 	l : 0 )
 
 #define LDAP_UTF8_OFFSET(p) ( LDAP_UTF8_ISASCII(p) \
diff --git a/include/portable.h.in b/include/portable.h.in
index 92ca6c08e6..2e2d7a9c7b 100644
--- a/include/portable.h.in
+++ b/include/portable.h.in
@@ -947,6 +947,12 @@
 /* define to support dynamic cn=Monitor backend */
 #undef SLAPD_MONITOR_DYNAMIC
 
+/* define to support NULL backend */
+#undef SLAPD_NULL
+
+/* define to support dynamic NULL backend */
+#undef SLAPD_NULL_DYNAMIC
+
 /* define to support PASSWD backend */
 #undef SLAPD_PASSWD
 
diff --git a/include/portable.nt b/include/portable.nt
index 7117c22053..921b3dd20e 100644
--- a/include/portable.nt
+++ b/include/portable.nt
@@ -960,6 +960,12 @@
 /* define to support dynamic cn=Monitor backend */
 /* #undef SLAPD_MONITOR_DYNAMIC */
 
+/* define to support NULL backend */
+/* #undef SLAPD_NULL */
+
+/* define to support dynamic NULL backend */
+/* #undef SLAPD_NULL_DYNAMIC */
+
 /* define to support PASSWD backend */
 /* #undef SLAPD_PASSWD */
 
diff --git a/libraries/liblber/bprint.c b/libraries/liblber/bprint.c
index 44f15d5663..a6ae8ce7ed 100644
--- a/libraries/liblber/bprint.c
+++ b/libraries/liblber/bprint.c
@@ -210,7 +210,7 @@ ber_bprint(
 		
 		off = BP_GRAPH + n + ((n >= 8)?1:0);
 
-		if ( isprint( data[i] )) {
+		if ( isprint( (unsigned char) data[i] )) {
 			line[ BP_GRAPH + n ] = data[i];
 		} else {
 			line[ BP_GRAPH + n ] = '.';
diff --git a/libraries/libldap/dntest.c b/libraries/libldap/dntest.c
index caa03212c9..72d3c52feb 100644
--- a/libraries/libldap/dntest.c
+++ b/libraries/libldap/dntest.c
@@ -72,8 +72,8 @@ main( int argc, char *argv[] )
 		size_t len;
 		
 		fgets( buf, sizeof( buf ), stdin );
-		len = strlen( buf ) - 1;
-		if ( len >= 0 && buf[ len ] == '\n' ) {
+		len = strlen( buf );
+		if ( len > 0 && buf[ --len ] == '\n' ) {
 			buf[ len ] = '\0';
 		}
 		strin = buf;
diff --git a/libraries/libldap/ftest.c b/libraries/libldap/ftest.c
index 587c0638bf..f61298992e 100644
--- a/libraries/libldap/ftest.c
+++ b/libraries/libldap/ftest.c
@@ -38,7 +38,6 @@ main( int argc, char *argv[] )
 {
 	int c;
 	int debug=0;
-	char *filter=NULL;
 
     while( (c = getopt( argc, argv, "d:" )) != EOF ) {
 		switch ( c ) {
diff --git a/libraries/libldap/getdn.c b/libraries/libldap/getdn.c
index 4eec0896e8..db9fdb9083 100644
--- a/libraries/libldap/getdn.c
+++ b/libraries/libldap/getdn.c
@@ -1753,7 +1753,7 @@ quotedIA52strval( const char *str, struct berval *val, const char **next, unsign
 	}
 
 	len = endPos - startPos - escapes;
-	assert( len >= 0 );
+	assert( endPos >= startPos + escapes );
 	val->bv_len = len;
 	if ( escapes == 0 ) {
 		val->bv_val = LDAP_STRNDUP( startPos, len );
diff --git a/libraries/libldap/ldap-int.h b/libraries/libldap/ldap-int.h
index baeebd6926..4ad20dd9f4 100644
--- a/libraries/libldap/ldap-int.h
+++ b/libraries/libldap/ldap-int.h
@@ -128,6 +128,7 @@ struct ldapoptions {
 #define LDAP_UNINITIALIZED	0x0
 #define LDAP_INITIALIZED	0x1
 #define LDAP_VALID_SESSION	0x2
+	int   ldo_debug;
 #ifdef LDAP_CONNECTIONLESS
 #define	LDAP_IS_UDP(ld)		((ld)->ld_options.ldo_is_udp)
 	void*			ldo_peer;	/* struct sockaddr* */
@@ -135,7 +136,6 @@ struct ldapoptions {
 	int			ldo_is_udp;
 #endif
 
-	int		ldo_debug;
 	/* per API call timeout */
 	struct timeval		*ldo_tm_api;
 	struct timeval		*ldo_tm_net;
diff --git a/libraries/libldap/os-ip.c b/libraries/libldap/os-ip.c
index 3ebe3e719d..0084743d84 100644
--- a/libraries/libldap/os-ip.c
+++ b/libraries/libldap/os-ip.c
@@ -152,7 +152,7 @@ ldap_pvt_is_socket_ready(LDAP *ld, int s)
 #if defined( notyet ) /* && defined( SO_ERROR ) */
 {
 	int so_errno;
-	int dummy = sizeof(so_errno);
+	socklen_t dummy = sizeof(so_errno);
 	if ( getsockopt( s, SOL_SOCKET, SO_ERROR, &so_errno, &dummy )
 		== AC_SOCKET_ERROR )
 	{
@@ -170,7 +170,7 @@ ldap_pvt_is_socket_ready(LDAP *ld, int s)
 	/* error slippery */
 	struct sockaddr_in sin;
 	char ch;
-	int dummy = sizeof(sin);
+	socklen_t dummy = sizeof(sin);
 	if ( getpeername( s, (struct sockaddr *) &sin, &dummy )
 		== AC_SOCKET_ERROR )
 	{
@@ -344,7 +344,7 @@ ldap_connect_to_host(LDAP *ld, Sockbuf *sb,
 		hints.ai_socktype = socktype;
 
 		snprintf(serv, sizeof serv, "%d", port );
-		if ( err = getaddrinfo(host, serv, &hints, &res) ) {
+		if ( ( err = getaddrinfo(host, serv, &hints, &res) ) ) {
 			osip_debug(ld, "ldap_connect_to_host: getaddrinfo failed: %s\n",
 				AC_GAI_STRERROR(err), 0, 0);
 			return -1;
diff --git a/libraries/libldap/os-local.c b/libraries/libldap/os-local.c
index c5476909ef..8b3da9f228 100644
--- a/libraries/libldap/os-local.c
+++ b/libraries/libldap/os-local.c
@@ -97,7 +97,7 @@ ldap_pvt_is_socket_ready(LDAP *ld, int s)
 #if defined( notyet ) /* && defined( SO_ERROR ) */
 {
 	int so_errno;
-	int dummy = sizeof(so_errno);
+	socklen_t dummy = sizeof(so_errno);
 	if ( getsockopt( s, SOL_SOCKET, SO_ERROR, &so_errno, &dummy )
 		== AC_SOCKET_ERROR )
 	{
@@ -115,7 +115,7 @@ ldap_pvt_is_socket_ready(LDAP *ld, int s)
 	/* error slippery */
 	struct sockaddr_un sa;
 	char ch;
-	int dummy = sizeof(sa);
+	socklen_t dummy = sizeof(sa);
 	if ( getpeername( s, (struct sockaddr *) &sa, &dummy )
 		== AC_SOCKET_ERROR )
 	{
diff --git a/libraries/libldap/tls.c b/libraries/libldap/tls.c
index 2b755120d9..7fcb778c11 100644
--- a/libraries/libldap/tls.c
+++ b/libraries/libldap/tls.c
@@ -906,7 +906,7 @@ ldap_pvt_tls_check_hostname( void *s, const char *name_in )
 	alt = X509V3_EXT_d2i(ex);
 	if (alt)
 	{
-	    int n, len1, len2;
+	    int n, len1, len2 = 0;
 	    char *domain;
 	    GENERAL_NAME *gn;
 	    X509V3_EXT_METHOD *method;
diff --git a/libraries/libldap/url.c b/libraries/libldap/url.c
index 42a595aee5..97059170b7 100644
--- a/libraries/libldap/url.c
+++ b/libraries/libldap/url.c
@@ -891,7 +891,7 @@ ldap_url_parselist (LDAPURLDesc **ludlist, const char *url )
 	if (url == NULL)
 		return LDAP_PARAM_ERROR;
 
-	urls = ldap_str2charray((char *)url, ", ");
+	urls = ldap_str2charray(url, ", ");
 	if (urls == NULL)
 		return LDAP_NO_MEMORY;
 
@@ -928,7 +928,7 @@ ldap_url_parsehosts(
 	if (hosts == NULL)
 		return LDAP_PARAM_ERROR;
 
-	specs = ldap_str2charray((char *)hosts, ", ");
+	specs = ldap_str2charray(hosts, ", ");
 	if (specs == NULL)
 		return LDAP_NO_MEMORY;
 
diff --git a/libraries/libldap/utf-8.c b/libraries/libldap/utf-8.c
index 9000e0a19b..a241a6313c 100644
--- a/libraries/libldap/utf-8.c
+++ b/libraries/libldap/utf-8.c
@@ -86,7 +86,7 @@ int ldap_utf8_charlen( const char * p )
 	if (!(*p & 0x80))
 		return 1;
 
-	return ldap_utf8_lentab[*(unsigned char *)p ^ 0x80];
+	return ldap_utf8_lentab[*(const unsigned char *)p ^ 0x80];
 }
 
 /*
diff --git a/libraries/libldif/line64.c b/libraries/libldif/line64.c
index 6081645129..3f16c95d60 100644
--- a/libraries/libldif/line64.c
+++ b/libraries/libldif/line64.c
@@ -411,8 +411,8 @@ ldif_sput(
 	stop = (const unsigned char *) (val + vlen);
 
 	if ( type == LDIF_PUT_VALUE
-		&& isgraph( val[0] ) && val[0] != ':' && val[0] != '<'
-		&& isgraph( val[vlen-1] )
+		&& isgraph( (unsigned char) val[0] ) && val[0] != ':' && val[0] != '<'
+		&& isgraph( (unsigned char) val[vlen-1] )
 #ifndef LDAP_BINARY_DEBUG
 		&& strstr( name, ";binary" ) == NULL
 #endif
@@ -542,8 +542,8 @@ int ldif_is_not_printable(
 		return -1;
 	}
 
-	if( isgraph( val[0] ) && val[0] != ':' && val[0] != '<' &&
-		isgraph( val[vlen-1] ) )
+	if( isgraph( (unsigned char) val[0] ) && val[0] != ':' && val[0] != '<' &&
+		isgraph( (unsigned char) val[vlen-1] ) )
 	{
 		ber_len_t i;
 
diff --git a/libraries/liblutil/entropy.c b/libraries/liblutil/entropy.c
index 220d15ddac..cd379c6724 100644
--- a/libraries/liblutil/entropy.c
+++ b/libraries/liblutil/entropy.c
@@ -48,7 +48,7 @@ int lutil_entropy( unsigned char *buf, ber_len_t nbytes )
 		close(fd);
 
 		/* should return nbytes */
-		if( rc < nbytes ) return -1;
+		if( rc != nbytes ) return -1;
 
 		return 0;
 	}
diff --git a/libraries/librewrite/config.c b/libraries/librewrite/config.c
index 3e10ac200c..556fd30947 100644
--- a/libraries/librewrite/config.c
+++ b/libraries/librewrite/config.c
@@ -273,8 +273,8 @@ rewrite_builtin_map_cmp(
 {
 	const struct rewrite_builtin_map *m1, *m2;
 
-        m1 = ( struct rewrite_builtin_map * )c1;
-        m2 = ( struct rewrite_builtin_map * )c2;
+        m1 = ( const struct rewrite_builtin_map * )c1;
+        m2 = ( const struct rewrite_builtin_map * )c2;
 
         assert( m1 != NULL );
         assert( m2 != NULL );
diff --git a/libraries/librewrite/context.c b/libraries/librewrite/context.c
index e32eb8a11d..115cca6f1e 100644
--- a/libraries/librewrite/context.c
+++ b/libraries/librewrite/context.c
@@ -36,10 +36,10 @@ rewrite_context_cmp(
 		const void *c2
 )
 {
-	struct rewrite_context *lc1, *lc2;
+	const struct rewrite_context *lc1, *lc2;
 	
-	lc1 = (struct rewrite_context *)c1;
-	lc2 = (struct rewrite_context *)c2;
+	lc1 = (const struct rewrite_context *)c1;
+	lc2 = (const struct rewrite_context *)c2;
 	
 	assert( c1 != NULL );
 	assert( c2 != NULL );
diff --git a/libraries/librewrite/map.c b/libraries/librewrite/map.c
index 816a27edf7..2180d89077 100644
--- a/libraries/librewrite/map.c
+++ b/libraries/librewrite/map.c
@@ -253,7 +253,7 @@ rewrite_map_parse(
 			 * '\' followed by a digit may mark the beginning
 			 * of an old map
 			 */
-			} else if ( isdigit( p[ 1 ] ) && p[ 2 ] == '{' ) {
+			} else if ( isdigit( (unsigned char) p[ 1 ] ) && p[ 2 ] == '{' ) {
 				cnt++;
 				p++;
 			}
@@ -329,12 +329,12 @@ rewrite_map_parse(
 	/*
 	 * Check the syntax of the variable name
 	 */
-	if ( !isalpha( p[ 0 ] ) ) {
+	if ( !isalpha( (unsigned char) p[ 0 ] ) ) {
 		free( s );
 		return NULL;
 	}
 	for ( p++; p[ 0 ] != '\0'; p++ ) {
-		if ( !isalnum( p[ 0 ] ) ) {
+		if ( !isalnum( (unsigned char) p[ 0 ] ) ) {
 			free( s );
 			return NULL;
 		}
diff --git a/libraries/librewrite/parse.c b/libraries/librewrite/parse.c
index 7b65d1897f..a8129c41ae 100644
--- a/libraries/librewrite/parse.c
+++ b/libraries/librewrite/parse.c
@@ -38,7 +38,7 @@ parse_line(
 	int in_quoted_field = 0, cnt = 0;
 	char quote = '\0';
 	
-	for ( p = buf; isspace( p[ 0 ] ); p++ );
+	for ( p = buf; isspace( (unsigned char) p[ 0 ] ); p++ );
 	
 	if ( p[ 0 ] == '#' ) {
 		return 0;
@@ -57,7 +57,7 @@ parse_line(
 					*argc = cnt;
 					return 1;
 				}
-				for ( p++; isspace( p[ 0 ] ); p++ );
+				for ( p++; isspace( (unsigned char) p[ 0 ] ); p++ );
 				begin = p;
 				p--;
 				
@@ -69,7 +69,7 @@ parse_line(
 				in_quoted_field = 1 - in_quoted_field;
 				quote = p[ 0 ];
 			}
-		} else if ( isspace( p[ 0 ] ) && !in_quoted_field ) {
+		} else if ( isspace( (unsigned char) p[ 0 ] ) && !in_quoted_field ) {
 			p[ 0 ] = '\0';
 			argv[ cnt ] = begin;
 
@@ -78,7 +78,7 @@ parse_line(
 				return 1;
 			}
 
-			for ( p++; isspace( p[ 0 ] ); p++ );
+			for ( p++; isspace( (unsigned char) p[ 0 ] ); p++ );
 			begin = p;
 			p--;
 		}
diff --git a/libraries/librewrite/session.c b/libraries/librewrite/session.c
index b372eff5da..fa5c78354a 100644
--- a/libraries/librewrite/session.c
+++ b/libraries/librewrite/session.c
@@ -35,10 +35,10 @@ rewrite_cookie_cmp(
                 const void *c2
 )
 {
-	struct rewrite_session *s1, *s2;
+	const struct rewrite_session *s1, *s2;
 
-	s1 = ( struct rewrite_session * )c1;
-	s2 = ( struct rewrite_session * )c2;
+	s1 = ( const struct rewrite_session * )c1;
+	s2 = ( const struct rewrite_session * )c2;
 
 	assert( s1 != NULL );
 	assert( s2 != NULL );
diff --git a/libraries/librewrite/subst.c b/libraries/librewrite/subst.c
index f84ed44c25..1024517463 100644
--- a/libraries/librewrite/subst.c
+++ b/libraries/librewrite/subst.c
@@ -101,7 +101,7 @@ rewrite_subst_compile(
 		/*
 		 * Substitution pattern
 		 */
-		if ( isdigit( p[ 1 ] ) ) {
+		if ( isdigit( (unsigned char) p[ 1 ] ) ) {
 			int d = p[ 1 ] - '0';
 			struct rewrite_submatch **tmpsm;
 
diff --git a/libraries/librewrite/var.c b/libraries/librewrite/var.c
index ca39ed13db..d4d28ad4b1 100644
--- a/libraries/librewrite/var.c
+++ b/libraries/librewrite/var.c
@@ -37,8 +37,8 @@ rewrite_var_cmp(
 {
 	const struct rewrite_var *v1, *v2;
 
-	v1 = ( struct rewrite_var * )c1;
-	v2 = ( struct rewrite_var * )c2;
+	v1 = ( const struct rewrite_var * )c1;
+	v2 = ( const struct rewrite_var * )c2;
 	
 	assert( v1 != NULL );
 	assert( v2 != NULL );
diff --git a/servers/slapd/add.c b/servers/slapd/add.c
index 5d222c5af0..3c5c66a9dd 100644
--- a/servers/slapd/add.c
+++ b/servers/slapd/add.c
@@ -181,7 +181,7 @@ do_add( Connection *conn, Operation *op )
 		goto done;
 	}
 
-	Statslog( LDAP_DEBUG_STATS, "conn=%ld op=%d ADD dn=\"%s\"\n",
+	Statslog( LDAP_DEBUG_STATS, "conn=%lu op=%lu ADD dn=\"%s\"\n",
 	    op->o_connid, op->o_opid, e->e_dn, 0, 0 );
 
 	if( e->e_nname.bv_len == 0 ) {
diff --git a/servers/slapd/back-bdb/cache.c b/servers/slapd/back-bdb/cache.c
index d63a5b7f60..f26541a57c 100644
--- a/servers/slapd/back-bdb/cache.c
+++ b/servers/slapd/back-bdb/cache.c
@@ -42,7 +42,7 @@ typedef struct bdb_entry_info {
 
 static int	bdb_cache_delete_entry_internal(Cache *cache, Entry *e);
 #ifdef LDAP_DEBUG
-static void	lru_print(Cache *cache);
+static void	bdb_lru_print(Cache *cache);
 #endif
 
 static int
diff --git a/servers/slapd/back-bdb/search.c b/servers/slapd/back-bdb/search.c
index af75427d2a..af5048a4c2 100644
--- a/servers/slapd/back-bdb/search.c
+++ b/servers/slapd/back-bdb/search.c
@@ -600,7 +600,6 @@ static int search_candidates(
 	Filter	af;
 	AttributeAssertion aa_alias;
 #endif
-	struct bdb_info *bdb = (struct bdb_info *) be->be_private;
 
 	/*
 	 * This routine takes as input a filter (user-filter)
diff --git a/servers/slapd/back-bdb/tools.c b/servers/slapd/back-bdb/tools.c
index 6ed8ec343e..0203ef7106 100644
--- a/servers/slapd/back-bdb/tools.c
+++ b/servers/slapd/back-bdb/tools.c
@@ -30,8 +30,6 @@ int bdb_tool_entry_open(
 int bdb_tool_entry_close(
 	BackendDB *be )
 {
-	struct bdb_info *bdb = (struct bdb_info *) be->be_private;
-
 	assert( be != NULL );
 
 	if( key.data ) {
diff --git a/servers/slapd/back-dnssrv/bind.c b/servers/slapd/back-dnssrv/bind.c
index 0ef516b1d9..adb5925148 100644
--- a/servers/slapd/back-dnssrv/bind.c
+++ b/servers/slapd/back-dnssrv/bind.c
@@ -33,7 +33,7 @@ dnssrv_back_bind(
 		
 	if( method == LDAP_AUTH_SIMPLE && cred != NULL && cred->bv_len ) {
 		Statslog( LDAP_DEBUG_STATS,
-		   	"conn=%ld op=%d DNSSRV BIND dn=\"%s\" provided passwd\n",
+		   	"conn=%lu op=%lu DNSSRV BIND dn=\"%s\" provided passwd\n",
 	   		 op->o_connid, op->o_opid,
 			dn->bv_val == NULL ? "" : dn->bv_val , 0, 0 );
 
diff --git a/servers/slapd/back-dnssrv/config.c b/servers/slapd/back-dnssrv/config.c
index e382b17b1f..4bdb093846 100644
--- a/servers/slapd/back-dnssrv/config.c
+++ b/servers/slapd/back-dnssrv/config.c
@@ -24,7 +24,6 @@ dnssrv_back_db_config(
     char	**argv )
 {
 	struct ldapinfo	*li = (struct ldapinfo *) be->be_private;
-	char *port;
 
 	if ( li == NULL ) {
 		fprintf( stderr, "%s: line %d: DNSSRV backend info is null!\n",
diff --git a/servers/slapd/back-dnssrv/referral.c b/servers/slapd/back-dnssrv/referral.c
index 49dbdaf4ae..6d7e240dce 100644
--- a/servers/slapd/back-dnssrv/referral.c
+++ b/servers/slapd/back-dnssrv/referral.c
@@ -56,7 +56,7 @@ dnssrv_back_referrals(
 		domain == NULL ? "" : domain,
 		0 );
 
-	if( rc = ldap_domain2hostlist( domain, &hostlist ) ) {
+	if( ( rc = ldap_domain2hostlist( domain, &hostlist ) ) ) {
 		Debug( LDAP_DEBUG_TRACE,
 			"DNSSRV: domain2hostlist(%s) returned %d\n",
 			domain, rc, 0 );
@@ -90,7 +90,7 @@ dnssrv_back_referrals(
 	}
 
 	Statslog( LDAP_DEBUG_STATS,
-	    "conn=%ld op=%d DNSSRV p=%d dn=\"%s\" url=\"%s\"\n",
+	    "conn=%lu op=%lu DNSSRV p=%d dn=\"%s\" url=\"%s\"\n",
 	    op->o_connid, op->o_opid, op->o_protocol,
 		dn->bv_val, urls[0].bv_val );
 
diff --git a/servers/slapd/back-dnssrv/search.c b/servers/slapd/back-dnssrv/search.c
index a35ab1f446..a619e3c23d 100644
--- a/servers/slapd/back-dnssrv/search.c
+++ b/servers/slapd/back-dnssrv/search.c
@@ -55,7 +55,7 @@ dnssrv_back_search(
 		domain == NULL ? "" : domain,
 		0 );
 
-	if( rc = ldap_domain2hostlist( domain, &hostlist ) ) {
+	if( ( rc = ldap_domain2hostlist( domain, &hostlist ) ) ) {
 		Debug( LDAP_DEBUG_TRACE, "DNSSRV: domain2hostlist returned %d\n",
 			rc, 0, 0 );
 		send_ldap_result( conn, op, LDAP_NO_SUCH_OBJECT,
@@ -91,7 +91,7 @@ dnssrv_back_search(
 	}
 
 	Statslog( LDAP_DEBUG_STATS,
-	    "conn=%ld op=%d DNSSRV p=%d dn=\"%s\" url=\"%s\"\n",
+	    "conn=%lu op=%lu DNSSRV p=%d dn=\"%s\" url=\"%s\"\n",
 	    op->o_connid, op->o_opid, op->o_protocol,
 		dn->bv_len ? dn->bv_val : "", urls[0].bv_val );
 
diff --git a/servers/slapd/back-ldap/bind.c b/servers/slapd/back-ldap/bind.c
index 3031f2e457..064bca788e 100644
--- a/servers/slapd/back-ldap/bind.c
+++ b/servers/slapd/back-ldap/bind.c
@@ -130,8 +130,8 @@ ldap_back_conn_cmp(
 	const void *c2
 	)
 {
-	struct ldapconn *lc1 = (struct ldapconn *)c1;
-        struct ldapconn *lc2 = (struct ldapconn *)c2;
+	const struct ldapconn *lc1 = (const struct ldapconn *)c1;
+	const struct ldapconn *lc2 = (const struct ldapconn *)c2;
 	
 	return ( ( lc1->conn < lc2->conn ) ? -1 : ( ( lc1->conn > lc2-> conn ) ? 1 : 0 ) );
 }
diff --git a/servers/slapd/back-ldap/config.c b/servers/slapd/back-ldap/config.c
index 30d00755c6..87e4fe40a0 100644
--- a/servers/slapd/back-ldap/config.c
+++ b/servers/slapd/back-ldap/config.c
@@ -303,10 +303,11 @@ ldap_back_db_config(
 static char *
 suffix_massage_regexize( const char *s )
 {
-	char *res, *p, *r, *ptr;
+	char *res, *ptr;
+	const char *p, *r;
 	int i;
 
-	for ( i = 0, p = ( char * )s; 
+	for ( i = 0, p = s; 
 			( r = strchr( p, ',' ) ) != NULL; 
 			p = r + 1, i++ )
 		;
@@ -314,7 +315,7 @@ suffix_massage_regexize( const char *s )
 	res = ch_calloc( sizeof( char ), strlen( s ) + 4 + 4*i + 1 );
 
 	ptr = slap_strcopy( res, "(.*)" );
-	for ( i = 0, p = ( char * )s;
+	for ( i = 0, p = s;
 			( r = strchr( p, ',' ) ) != NULL;
 			p = r + 1 , i++ ) {
 		ptr = slap_strncopy( ptr, p, r - p + 1 );
diff --git a/servers/slapd/back-ldbm/attribute.c b/servers/slapd/back-ldbm/attribute.c
index b157293337..eaa8d3e116 100644
--- a/servers/slapd/back-ldbm/attribute.c
+++ b/servers/slapd/back-ldbm/attribute.c
@@ -38,6 +38,7 @@ ldbm_back_attribute(
 	const char *entry_at_name = entry_at->ad_cname.bv_val;
 	struct berval *iv, *jv;
 	AccessControlState acl_state = ACL_STATE_INIT;
+	int nvals = 0;
 
 #ifdef NEW_LOGGING
 	LDAP_LOG(( "backend", LDAP_LEVEL_ARGS,
@@ -179,6 +180,8 @@ ldbm_back_attribute(
 		if( jv->bv_val != NULL ) jv++;
 	}
 
+	nvals = jv - v;
+
 	if( jv == v ) {
 		ch_free( v );
 		*vals = NULL;
@@ -198,11 +201,11 @@ return_results:
 #ifdef NEW_LOGGING
 	LDAP_LOG(( "backend", LDAP_LEVEL_ENTRY,
 		   "ldbm_back_attribute: rc=%d nvals=%d.\n",
-		   rc, jv - v ));
+		   rc, nvals ));
 #else
 	Debug( LDAP_DEBUG_TRACE,
 		"ldbm_back_attribute: rc=%d nvals=%d\n",
-		rc, jv - v, 0 ); 
+		rc, nvals, 0 ); 
 #endif
 
 	return(rc);
diff --git a/servers/slapd/back-ldbm/modrdn.c b/servers/slapd/back-ldbm/modrdn.c
index 36f8e03536..eb5ec10b2e 100644
--- a/servers/slapd/back-ldbm/modrdn.c
+++ b/servers/slapd/back-ldbm/modrdn.c
@@ -53,7 +53,6 @@ ldbm_back_modrdn(
 	Entry		*e, *p = NULL;
 	Entry		*matched;
 	int		isroot = -1;
-	int		rootlock = 0;
 #define CAN_ROLLBACK	-1
 #define MUST_DESTROY	1
 	int		rc = CAN_ROLLBACK;
diff --git a/servers/slapd/back-ldbm/passwd.c b/servers/slapd/back-ldbm/passwd.c
index 8ad0948f09..ae0f245858 100644
--- a/servers/slapd/back-ldbm/passwd.c
+++ b/servers/slapd/back-ldbm/passwd.c
@@ -31,7 +31,7 @@ ldbm_back_exop_passwd(
 )
 {
 	struct ldbminfo *li = (struct ldbminfo *) be->be_private;
-	int rc, locked=0;
+	int rc;
 	Entry *e = NULL;
 	struct berval hash = { 0, NULL };
 
diff --git a/servers/slapd/back-meta/search.c b/servers/slapd/back-meta/search.c
index 2ea04998d7..98754a69e3 100644
--- a/servers/slapd/back-meta/search.c
+++ b/servers/slapd/back-meta/search.c
@@ -76,6 +76,7 @@
 #include "../back-ldap/back-ldap.h"
 #include "back-meta.h"
 #include "ldap_pvt.h"
+#undef ldap_debug	/* silence a warning in ldap-int.h */
 #include "../../../libraries/libldap/ldap-int.h"
 
 static void
diff --git a/servers/slapd/back-monitor/README b/servers/slapd/back-monitor/README
index d98f9d89a1..24216eba7e 100644
--- a/servers/slapd/back-monitor/README
+++ b/servers/slapd/back-monitor/README
@@ -91,13 +91,16 @@ The subsystems are:
 	Read Waiters
 	Write Waiters
 	Log
+	Operations
+	Statistics
+	Time
 
 
 
 LISTENER SUBSYSTEM
 
-Currently empty, it will presumably contain the description of the
-devices the server is currently listening on
+It contains the description of the devices the server is currently 
+listening on
 
 
 
@@ -143,6 +146,8 @@ The main entry is empty; it should contain some statistics on the number
 of connections.
 Dynamic subentries are created for each open connection, with stats on
 the activity on that connection (the format will be detailed later).
+There are two special subentries that show the number of total and
+current connections respectively.
 
 
 
@@ -184,6 +189,33 @@ messages are sent to the syslog device.
 
 
 
+OPERATIONS SUBSYSTEM
+
+It shows some statistics on the operations performed by the server:
+
+	Initiated
+	Completed
+
+
+
+SENT SUBSYSTEM
+
+It shows some statistics on the data sent by the server:
+
+	Bytes
+	PDU
+	Referrals
+	Entries
+
+
+
+TIME SUBSISTEM
+
+It contains two subentries with the start time and the current time 
+of the server.
+
+
+
 NOTES
 
 This document is in a very early stage of maturity and will 
diff --git a/servers/slapd/back-monitor/backend.c b/servers/slapd/back-monitor/backend.c
index a9f324ed49..bd65f90639 100644
--- a/servers/slapd/back-monitor/backend.c
+++ b/servers/slapd/back-monitor/backend.c
@@ -99,7 +99,7 @@ monitor_subsys_backend_init(
 #else
 			Debug( LDAP_DEBUG_ANY,
 				"monitor_subsys_backend_init: "
-				"unable to create entry 'Backend cn=%d,%s'\n%s",
+				"unable to create entry 'cn=Backend %d,%s'\n%s",
 				i, 
 				monitor_subsys[SLAPD_MONITOR_BACKEND].mss_ndn.bv_val,
 				"" );
diff --git a/servers/slapd/back-monitor/time.c b/servers/slapd/back-monitor/time.c
index f01f895bdb..8bd0b8045d 100644
--- a/servers/slapd/back-monitor/time.c
+++ b/servers/slapd/back-monitor/time.c
@@ -41,8 +41,10 @@
 #include "proto-slap.h"
 #include "back-monitor.h"
 
+#ifdef HACK_LOCAL_TIME
 static int
 local_time( const struct tm *ztm, long delta, char *buf, size_t len );
+#endif /* HACK_LOCAL_TIME */
 
 int
 monitor_subsys_time_init(
@@ -236,11 +238,13 @@ monitor_subsys_time_update(
 #ifdef HACK_LOCAL_TIME
 	char		ltmbuf[20];
 	struct tm	*
-#endif
+#endif /* HACK_LOCAL_TIME */
 	time_t		currenttime;
 	Attribute	*a;
+#ifdef HACK_LOCAL_TIME
 	static AttributeDescription	*ad_local = NULL;
 	const char	*text = NULL;
+#endif /* HACK_LOCAL_TIME */
 	ber_len_t	len;
 
 	static int	init_start = 0;
@@ -304,6 +308,7 @@ monitor_subsys_time_update(
 	return( 0 );
 }
 
+#ifdef HACK_LOCAL_TIME
 /*
  * assumes gmtime_mutex is locked
  */
@@ -331,4 +336,5 @@ local_time( const struct tm *ltm, long delta, char *buf, size_t len )
 	
 	return 0;
 }
+#endif /* HACK_LOCAL_TIME */
 
diff --git a/servers/slapd/back-null/Makefile.in b/servers/slapd/back-null/Makefile.in
new file mode 100644
index 0000000000..7fd3a934f6
--- /dev/null
+++ b/servers/slapd/back-null/Makefile.in
@@ -0,0 +1,26 @@
+SRCS = null.c
+OBJS = null.lo
+
+LDAP_INCDIR= ../../../include       
+LDAP_LIBDIR= ../../../libraries
+
+BUILD_OPT = "--enable-null"
+BUILD_MOD = @BUILD_NULL@
+BUILD_MOD_DYNAMIC = @BUILD_NULL_DYNAMIC@
+
+mod_DEFS = -DSLAPD_IMPORT
+MOD_DEFS = $(@BUILD_NULL@_DEFS)
+
+shared_LDAP_LIBS = $(LDAP_LIBPATH) -lldap_r -llber
+NT_LINK_LIBS = -L.. -lslapd $(@BUILD_LIBS_DYNAMIC@_LDAP_LIBS)
+
+LIBBASE = back_null
+
+XINCPATH = -I.. -I$(srcdir)/..
+XDEFS = $(MODULES_CPPFLAGS)
+
+all-local-lib:	../.backend
+
+../.backend: lib$(LIBBASE).a
+	@touch $@
+
diff --git a/servers/slapd/back-null/README b/servers/slapd/back-null/README
new file mode 100644
index 0000000000..a2d8cb11fd
--- /dev/null
+++ b/servers/slapd/back-null/README
@@ -0,0 +1,14 @@
+Null Backend Interface for OpenLDAP
+
+The Null backend is surely the most useful part of slapd:
+- Searches return success but no entries.
+- Compares return compareFalse.
+- Updates return success (unless readonly is on) but do nothing.
+- Binds fail unless the database option "bind on" is given.
+  The "bind" option is "off" by default.
+Inspired by the /dev/null device.
+
+slapd.conf example:
+  database null
+  suffix   "cn=Nothing"
+  bind     on
diff --git a/servers/slapd/back-null/external.h b/servers/slapd/back-null/external.h
new file mode 100644
index 0000000000..8b54f39889
--- /dev/null
+++ b/servers/slapd/back-null/external.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2002 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+#ifndef _NULL_EXTERNAL_H
+#define _NULL_EXTERNAL_H
+
+LDAP_BEGIN_DECL
+
+extern BI_init		null_back_initialize;
+
+extern BI_db_init	null_back_db_init;
+extern BI_db_destroy null_back_db_destroy;
+
+extern BI_db_config	null_back_db_config;
+
+extern BI_op_bind	null_back_bind;
+
+extern BI_op_search	null_back_search;
+
+extern BI_op_compare null_back_compare;
+
+extern BI_op_modify	null_back_modify;
+
+extern BI_op_modrdn	null_back_modrdn;
+
+extern BI_op_add	null_back_add;
+
+extern BI_op_delete	null_back_delete;
+
+LDAP_END_DECL
+
+#endif /* _NULL_EXTERNAL_H */
diff --git a/servers/slapd/back-null/null.c b/servers/slapd/back-null/null.c
new file mode 100644
index 0000000000..8d81277852
--- /dev/null
+++ b/servers/slapd/back-null/null.c
@@ -0,0 +1,236 @@
+/* null.c - the null backend */
+/*
+ * Copyright 2002 The OpenLDAP Foundation, All Rights Reserved.
+ * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
+ */
+
+#include "portable.h"
+
+#include <stdio.h>
+#include <ac/string.h>
+
+#include "slap.h"
+#include "external.h"
+
+struct null_info {
+	int bind_allowed;
+};
+
+int
+null_back_bind(
+	Backend			*be,
+	Connection		*conn,
+	Operation		*op,
+	struct berval	*dn,
+	struct berval	*ndn,
+	int				method,
+	struct berval	*cred,
+	struct berval	*edn
+)
+{
+	struct null_info *ni = (struct null_info *) be->be_private;
+
+	if( ni->bind_allowed )
+		/* front end with send result on success (0) */
+		return 0;
+	send_ldap_result( conn, op, LDAP_INVALID_CREDENTIALS,
+	                  NULL, NULL, NULL, NULL );
+	return LDAP_INVALID_CREDENTIALS;
+}
+
+int
+null_back_add(
+	BackendDB	*be,
+	Connection	*conn,
+	Operation	*op,
+	Entry		*e )
+{
+	send_ldap_result( conn, op, LDAP_SUCCESS, NULL, NULL, NULL, NULL );
+	return 0;
+}
+
+int
+null_back_compare(
+	BackendDB		*be,
+	Connection		*conn,
+	Operation		*op,
+	struct berval	*dn,
+	struct berval	*ndn,
+	AttributeAssertion *ava
+)
+{
+	send_ldap_result( conn, op, LDAP_COMPARE_FALSE, NULL, NULL, NULL, NULL );
+	return 0;
+}
+
+int
+null_back_delete(
+	BackendDB		*be,
+	Connection		*conn,
+	Operation		*op,
+	struct berval	*dn,
+	struct berval	*ndn
+)
+{
+	send_ldap_result( conn, op, LDAP_SUCCESS, NULL, NULL, NULL, NULL );
+	return 0;
+}
+
+int
+null_back_modify(
+	BackendDB		*be,
+	Connection		*conn,
+	Operation		*op,
+	struct berval	*dn,
+	struct berval	*ndn,
+	Modifications	*modlist )
+{
+	send_ldap_result( conn, op, LDAP_SUCCESS, NULL, NULL, NULL, NULL );
+	return 0;
+}
+
+int
+null_back_modrdn(
+	Backend			*be,
+	Connection		*conn,
+	Operation		*op,
+	struct berval	*dn,
+	struct berval	*ndn,
+	struct berval	*newrdn,
+	struct berval	*nnewrdn,
+	int				deleteoldrdn,
+	struct berval	*newSuperior,
+	struct berval	*nnewSuperior )
+{
+	send_ldap_result( conn, op, LDAP_SUCCESS, NULL, NULL, NULL, NULL );
+	return 0;
+}
+
+int
+null_back_search(
+	BackendDB		*be,
+	Connection		*conn,
+	Operation		*op,
+	struct berval	*base,
+	struct berval	*nbase,
+	int				scope,
+	int				deref,
+	int				slimit,
+	int				tlimit,
+	Filter			*filter,
+	struct berval	*filterstr,
+	AttributeName	*attrs,
+	int				attrsonly )
+{
+	send_search_result( conn, op, LDAP_SUCCESS, NULL, NULL, NULL, NULL, 0 );
+	return 1;
+}
+
+
+int
+null_back_db_config(
+	BackendDB	*be,
+	const char	*fname,
+	int			lineno,
+	int			argc,
+	char		**argv )
+{
+	struct null_info *ni = (struct null_info *) be->be_private;
+
+	if ( ni == NULL ) {
+		fprintf( stderr, "%s: line %d: null database info is null!\n",
+			fname, lineno );
+		return 1;
+	}
+
+	/* bind requests allowed */
+	if ( strcasecmp( argv[0], "bind" ) == 0 ) {
+		if ( argc < 2 ) {
+			fprintf( stderr,
+	"%s: line %d: missing <on/off> in \"bind <on/off>\" line\n",
+			         fname, lineno );
+			return 1;
+		}
+		ni->bind_allowed = strcasecmp( argv[1], "off" );
+
+	/* anything else */
+	} else {
+		fprintf( stderr,
+"%s: line %d: unknown directive \"%s\" in null database definition (ignored)\n",
+		         fname, lineno, argv[0] );
+	}
+
+	return 0;
+}
+
+
+int
+null_back_db_init( BackendDB *be )
+{
+	be->be_private = ch_calloc( 1, sizeof(struct null_info) );
+	return 0;
+}
+
+int
+null_back_db_destroy(
+    Backend	*be
+)
+{
+	free( be->be_private );
+	return 0;
+}
+
+
+int
+null_back_initialize(
+    BackendInfo	*bi
+)
+{
+	bi->bi_open = 0;
+	bi->bi_close = 0;
+	bi->bi_config = 0;
+	bi->bi_destroy = 0;
+
+	bi->bi_db_init = null_back_db_init;
+	bi->bi_db_config = null_back_db_config;
+	bi->bi_db_open = 0;
+	bi->bi_db_close = 0;
+	bi->bi_db_destroy = null_back_db_destroy;
+
+	bi->bi_op_bind = null_back_bind;
+	bi->bi_op_unbind = 0;
+	bi->bi_op_search = null_back_search;
+	bi->bi_op_compare = null_back_compare;
+	bi->bi_op_modify = null_back_modify;
+	bi->bi_op_modrdn = null_back_modrdn;
+	bi->bi_op_add = null_back_add;
+	bi->bi_op_delete = null_back_delete;
+	bi->bi_op_abandon = 0;
+
+	bi->bi_extended = 0;
+
+	bi->bi_acl_group = 0;
+	bi->bi_acl_attribute = 0;
+	bi->bi_chk_referrals = 0;
+
+	bi->bi_connection_init = 0;
+	bi->bi_connection_destroy = 0;
+
+	return 0;
+}
+
+#ifdef SLAPD_NULL_DYNAMIC
+int back_null_LTX_init_module(
+	int argc,
+	char *argv[] )
+{
+    BackendInfo bi;
+
+    memset( &bi, '\0', sizeof(bi) );
+    bi.bi_type = "null";
+    bi.bi_init = null_back_initialize;
+
+    backend_add(&bi);
+    return 0;
+}
+#endif /* SLAPD_NULL_DYNAMIC */
diff --git a/servers/slapd/back-tcl/README.back-tcl b/servers/slapd/back-tcl/README.back-tcl
index f3bcef886f..b7b890be56 100644
--- a/servers/slapd/back-tcl/README.back-tcl
+++ b/servers/slapd/back-tcl/README.back-tcl
@@ -11,7 +11,7 @@ suffix          o=Suffix
 # The full path to the tcl script used for this database
 scriptpath      /usr/lib/ldap/database.tcl
 
-# The procs for each ldap function. This similar to how
+# The procs for each ldap function. This is similar to how
 # the shell backend setup works, but these refer to
 # the tcl procs in the 'scriptpath' script that handle them
 search          <proc>
@@ -25,12 +25,12 @@ compare		<proc>
 abandon		<proc>
 
 # This is one of the biggest pluses of using the tcl backend.
-# The realm let's you group several databases to the same interpretor.
+# The realm let's you group several databases to the same interpreter.
 # This basically means they share the same global variables and proc
-# space. So global variables, as well as all the procs are callable
+# space. So global variables, as well as all the procs, are callable
 # between databases. If no tclrealm is specified, it is put into the
 # "default" realm.
-tclrealm        <interpretor name>
+tclrealm        <interpreter name>
 
 
 -----------------------------------------
@@ -42,14 +42,14 @@ abandon { action msgid suffix }
 	action - Always equal to ABANDON
 	msgid  - The msgid of this ldap session
 	suffix - List of suffix(es) associated with the call. Each one is
-		 and entry in a tcl formatted list (surrounded by {}'s)
+		 an entry in a tcl formatted list (surrounded by {}'s)
 
 add { action msgid suffix entry }
 
 	action - Always equal to ADD
 	msgid  - The msgid of this ldap session
 	suffix - List of suffix(es) associated with the call. Each one is
-		 and entry in a tcl formatted list (surrounded by {}'s)
+		 an entry in a tcl formatted list (surrounded by {}'s)
 	entry  - Full entry to add. Each "type: val" is an element in a
 		 tcl formatted list.
 
@@ -58,7 +58,7 @@ bind { action msgid suffix dn method cred_len cred }
 	action   - Always equal to BIND
 	msgid    - The msgid of this ldap session
 	suffix   - List of suffix(es) associated with the call. Each one
-		   is and entry in a tcl formatted list (surrounded by {}'s)
+		   is an entry in a tcl formatted list (surrounded by {}'s)
 	dn       - DN being bound to
 	method   - One of the ldap authentication methods
 	cred_len - Length of cred
@@ -156,25 +156,25 @@ This is best accomplished with this type of tcl code
   lappend ret_val ""
   return $ret_val
 
-The final empty string (item in list) is neccesary to point to the end of
-list. The 'code', 'matched', and 'info' values are not neccesary, and
+The final empty string (item in list) is necessary to point to the end of
+list. The 'code', 'matched', and 'info' values are not necessary, and
 default values are given if not specified. The 'code' value is usually an
 LDAP error in decimal notation from ldap.h. The 'info', may be sent back
 to the client, depending on the function. LDAP uses the value of 'code' to
 indicate whether or not the authentication is acceptible in the bind proc.
 
 The other type of return is for searches. It is similar format to the
-shell backend return (as is most of the syntax here). It's format follows:
+shell backend return (as is most of the syntax here). Its format follows:
 
     {dn: o=Company, c=US} {attr: val} {objectclass: val} {}
     {dn: o=CompanyB, c=US} {attr: val} {objectclass: val} {}
 
 Again, newlines are for visual purposes here. Also note the {} marking the
-end of the entry (same affect as a newline in ldif format). Here is some
+end of the entry (same effect as a newline in ldif format). Here is some
 example code again, showing a full search proc example.
 
-# Note that 'args' let's you lump all possible args into one var, used
-# here for simplicity of exmaple
+# Note that 'args' lets you lump all possible args into one var, used
+# here for simplicity of example
 proc ldap:search { args } {
   # perform some operations
 
@@ -191,7 +191,7 @@ proc ldap:search { args } {
   return $ret_val
 }
 
-NOTE: Newlines in the return value is acceptible in search entries (ie.
+NOTE: Newlines in the return value is acceptable in search entries (i.e.
 when returning base64 encoded binary entries).
 
 
@@ -201,6 +201,6 @@ Synopsis of Builtin Commands and Vars
 
 ldap:debug <msg>
 
-  Allows you to send debug messages through OpenLDAP's native debuging
+  Allows you to send debug messages through OpenLDAP's native debugging
   system, this is sent as a LDAP_DEBUG_ANY and will be logged. Useful for
   debugging scripts or logging bind failures.
diff --git a/servers/slapd/back-tcl/tcl_abandon.c b/servers/slapd/back-tcl/tcl_abandon.c
index 5fcf8c5a28..c416a2b3e0 100644
--- a/servers/slapd/back-tcl/tcl_abandon.c
+++ b/servers/slapd/back-tcl/tcl_abandon.c
@@ -24,22 +24,24 @@ tcl_back_abandon (
 	int msgid
 )
 {
-	char *suf_tcl, *results, *command;
-	int i, code, err = 0;
+	char *results, *command;
+	struct berval suf_tcl;
+	int code, err = 0;
 	struct tclinfo *ti = (struct tclinfo *) be->be_private;
 
-	if (ti->ti_abandon == NULL) {
+	if (ti->ti_abandon.bv_len == 0) {
 		return (-1);
 	}
 
-	for (i = 0; be->be_suffix[i] != NULL; i++);
-	suf_tcl = Tcl_Merge (i, be->be_suffix);
+	if (tcl_merge_bvlist(be->be_suffix, &suf_tcl) == NULL) {
+		return (-1);
+	}
 
-	command = (char *) ch_malloc (strlen (ti->ti_abandon) + strlen (suf_tcl)
+	command = (char *) ch_malloc (ti->ti_abandon.bv_len + suf_tcl.bv_len
 		+ 20);
 	sprintf (command, "%s ABANDON {%ld} {%s}",
-		ti->ti_abandon, op->o_msgid, suf_tcl);
-	Tcl_Free (suf_tcl);
+		ti->ti_abandon.bv_val, (long) op->o_msgid, suf_tcl.bv_val);
+	Tcl_Free (suf_tcl.bv_val);
 
 	ldap_pvt_thread_mutex_lock (&tcl_interpreter_mutex);
 	code = Tcl_GlobalEval (ti->ti_ii->interp, command);
diff --git a/servers/slapd/back-tcl/tcl_add.c b/servers/slapd/back-tcl/tcl_add.c
index e2d324bba6..3fa0d0769c 100644
--- a/servers/slapd/back-tcl/tcl_add.c
+++ b/servers/slapd/back-tcl/tcl_add.c
@@ -24,27 +24,31 @@ tcl_back_add (
 	Entry * e
 )
 {
-	char *command, *suf_tcl, *entrystr, *results;
-	int i, code, err = 0;
+	char *command, *entrystr, *results;
+	struct berval suf_tcl;
+	int code, err = 0;
 	struct tclinfo *ti = (struct tclinfo *) be->be_private;
 
-	if (ti->ti_add == NULL) {
+	if (ti->ti_add.bv_len == 0) {
 		send_ldap_result (conn, op, LDAP_UNWILLING_TO_PERFORM, NULL,
 			"add not implemented", NULL, NULL );
 		return (-1);
 	}
 
-	for (i = 0; be->be_suffix[i] != NULL; i++);
-	suf_tcl = Tcl_Merge (i, be->be_suffix);
+	if (tcl_merge_bvlist (be->be_suffix, &suf_tcl) == NULL) {
+		send_ldap_result (conn, op, LDAP_OPERATIONS_ERROR, NULL,
+			NULL, NULL, NULL );
+		return (-1);
+	}
 
-	entrystr = tcl_clean_entry (e);
+	entrystr = tcl_clean_entry(e);
 
-	command = (char *) ch_malloc (strlen (ti->ti_add) + strlen
-		(suf_tcl) +
-		strlen (entrystr) + 32);
+	command = (char *) ch_malloc (ti->ti_add.bv_len + suf_tcl.bv_len +
+		strlen(entrystr) + 32);
 	sprintf (command, "%s ADD {%ld} {%s} {%s}",
-		ti->ti_add, op->o_msgid, suf_tcl, entrystr);
-	Tcl_Free (suf_tcl);
+		ti->ti_add.bv_val, (long) op->o_msgid, 
+		suf_tcl.bv_val, entrystr);
+	Tcl_Free (suf_tcl.bv_val);
 	free (entrystr);
 
 	ldap_pvt_thread_mutex_lock (&tcl_interpreter_mutex);
diff --git a/servers/slapd/back-tcl/tcl_back.h b/servers/slapd/back-tcl/tcl_back.h
index 4936b77029..63da57236e 100644
--- a/servers/slapd/back-tcl/tcl_back.h
+++ b/servers/slapd/back-tcl/tcl_back.h
@@ -29,21 +29,22 @@ struct i_info {
 extern struct i_info *global_i;
 
 struct tclinfo {
-	char *script_path;
+	struct berval ti_script_path;
 	struct i_info *ti_ii;
-	char *ti_bind;
-	char *ti_unbind;
-	char *ti_search;
-	char *ti_compare;
-	char *ti_modify;
-	char *ti_modrdn;
-	char *ti_add;
-	char *ti_delete;
-	char *ti_abandon;
+	struct berval ti_bind;
+	struct berval ti_unbind;
+	struct berval ti_search;
+	struct berval ti_compare;
+	struct berval ti_modify;
+	struct berval ti_modrdn;
+	struct berval ti_add;
+	struct berval ti_delete;
+	struct berval ti_abandon;
 };
 
 void readtclscript (char *script, Tcl_Interp * my_tcl);
 char *tcl_clean_entry (Entry * e);
+struct berval *tcl_merge_bvlist (struct berval **bvlist, struct berval *out);
 
 int tcl_ldap_debug (
 	ClientData clientData,
diff --git a/servers/slapd/back-tcl/tcl_bind.c b/servers/slapd/back-tcl/tcl_bind.c
index daa89d12c9..f5ade3e752 100644
--- a/servers/slapd/back-tcl/tcl_bind.c
+++ b/servers/slapd/back-tcl/tcl_bind.c
@@ -28,26 +28,29 @@ tcl_back_bind (
 	struct berval *edn
 )
 {
-	char *command, *suf_tcl, *results;
-	int i, code, err = 0;
+	char *command, *results;
+	struct berval suf_tcl;
+	int code, err = 0;
 	struct tclinfo *ti = (struct tclinfo *) be->be_private;
 
-	if (ti->ti_bind == NULL) {
+	if (ti->ti_bind.bv_len == 0) {
 		send_ldap_result (conn, op, LDAP_UNWILLING_TO_PERFORM, NULL,
 			"bind not implemented", NULL, NULL );
 		return (-1);
 	}
 
-	for (i = 0; be->be_suffix[i] != NULL; i++);
-	suf_tcl = Tcl_Merge (i, be->be_suffix);
+	if (tcl_merge_bvlist (be->be_suffix, &suf_tcl) == NULL) {
+		send_ldap_result (conn, op, LDAP_OPERATIONS_ERROR, NULL,
+			NULL, NULL, NULL );
+		return (-1);
+	}
 
-	command = (char *) ch_malloc (strlen (ti->ti_bind) + strlen
-		(suf_tcl) +
+	command = (char *) ch_malloc (ti->ti_bind.bv_len + suf_tcl.bv_len +
 		dn->bv_len + cred->bv_len + 64);
 	sprintf (command, "%s BIND {%ld} {%s} {%s} {%d} {%lu} {%s}",
-		ti->ti_bind, op->o_msgid, suf_tcl, dn->bv_val, method, cred->bv_len,
-		cred->bv_val);
-	Tcl_Free (suf_tcl);
+		ti->ti_bind.bv_val, (long) op->o_msgid, suf_tcl.bv_val, 
+		dn->bv_val, method, cred->bv_len, cred->bv_val);
+	Tcl_Free (suf_tcl.bv_val);
 
 	ldap_pvt_thread_mutex_lock (&tcl_interpreter_mutex);
 	code = Tcl_GlobalEval (ti->ti_ii->interp, command);
diff --git a/servers/slapd/back-tcl/tcl_compare.c b/servers/slapd/back-tcl/tcl_compare.c
index 54341e375a..2f7b522dcf 100644
--- a/servers/slapd/back-tcl/tcl_compare.c
+++ b/servers/slapd/back-tcl/tcl_compare.c
@@ -21,31 +21,36 @@ tcl_back_compare (
 	Backend * be,
 	Connection * conn,
 	Operation * op,
-	const char *dn,
-	const char *ndn,
-	Ava * ava
+	struct berval *dn,
+	struct berval *ndn,
+	AttributeAssertion * ava
 )
 {
-	char *command, *suf_tcl, *results;
-	int i, code, err = 0;
+	char *command, *results;
+	struct berval suf_tcl;
+	int code, err = 0;
 	struct tclinfo *ti = (struct tclinfo *) be->be_private;
 
-	if (ti->ti_compare == NULL) {
+	if (ti->ti_compare.bv_len == 0) {
 		send_ldap_result (conn, op, LDAP_UNWILLING_TO_PERFORM, NULL,
 			"compare not implemented", NULL, NULL );
 		return (-1);
 	}
 
-	for (i = 0; be->be_suffix[i] != NULL; i++);
-	suf_tcl = Tcl_Merge (i, be->be_suffix);
+	if (tcl_merge_bvlist (be->be_suffix, &suf_tcl) == NULL) {
+		send_ldap_result (conn, op, LDAP_OPERATIONS_ERROR, NULL,
+			NULL, NULL, NULL );
+		return (-1);
+	}
 
-	command = (char *) ch_malloc (strlen (ti->ti_compare) +
-		strlen (suf_tcl) + strlen (dn) + strlen (ava->ava_type) +
-		strlen (ava->ava_value.bv_val) + 64);
+	command = (char *) ch_malloc (ti->ti_compare.bv_len +
+		suf_tcl.bv_len + dn->bv_len + ava->aa_desc->ad_cname.bv_len +
+		ava->aa_value.bv_len + 64);
 	sprintf (command, "%s COMPARE {%ld} {%s} {%s} {%s: %s}",
-		ti->ti_compare, op->o_msgid, suf_tcl, dn, ava->ava_type,
-		ava->ava_value.bv_val);
-	Tcl_Free (suf_tcl);
+		ti->ti_compare.bv_val, (long) op->o_msgid, suf_tcl.bv_val, 
+		dn->bv_val,
+		ava->aa_desc->ad_cname.bv_val, ava->aa_value.bv_val);
+	Tcl_Free (suf_tcl.bv_val);
 
 	ldap_pvt_thread_mutex_lock (&tcl_interpreter_mutex);
 	code = Tcl_GlobalEval (ti->ti_ii->interp, command);
diff --git a/servers/slapd/back-tcl/tcl_config.c b/servers/slapd/back-tcl/tcl_config.c
index 64174bca83..f7ceed9a66 100644
--- a/servers/slapd/back-tcl/tcl_config.c
+++ b/servers/slapd/back-tcl/tcl_config.c
@@ -28,7 +28,6 @@ tcl_back_db_config (
 )
 {
 	struct tclinfo *ti = (struct tclinfo *) bd->be_private;
-	int script_loaded = 0;
 
 	if (ti == NULL) {
 		fprintf (stderr,
@@ -48,7 +47,7 @@ tcl_back_db_config (
 				fname, lineno, 0);
 			return (1);
 		}
-		ti->script_path = (char *) ch_strdup (argv[1]);
+		ber_str2bv( argv[1], 0, 1, &ti->ti_script_path );
 
 		/* use local interpreter */
 	} else if (strcasecmp (argv[0], "tclrealm") == 0) {
@@ -90,7 +89,7 @@ tcl_back_db_config (
 				fname, lineno, 0);
 			return (1);
 		}
-		ti->ti_bind = (char *) ch_strdup (argv[1]);
+		ber_str2bv( argv[1], 0, 1, &ti->ti_bind );
 
 		/* proc for unbinds */
 	} else if (strcasecmp (argv[0], "unbind") == 0) {
@@ -100,7 +99,7 @@ tcl_back_db_config (
 				fname, lineno, 0);
 			return (1);
 		}
-		ti->ti_unbind = (char *) ch_strdup (argv[1]);
+		ber_str2bv( argv[1], 0, 1, &ti->ti_unbind );
 
 		/* proc for search */
 	} else if (strcasecmp (argv[0], "search") == 0) {
@@ -110,7 +109,7 @@ tcl_back_db_config (
 				fname, lineno, 0);
 			return (1);
 		}
-		ti->ti_search = (char *) ch_strdup (argv[1]);
+		ber_str2bv( argv[1], 0, 1, &ti->ti_search );
 
 		/* proc for compares */
 	} else if (strcasecmp (argv[0], "compare") == 0) {
@@ -120,7 +119,7 @@ tcl_back_db_config (
 				fname, lineno, 0);
 			return (1);
 		}
-		ti->ti_compare = (char *) ch_strdup (argv[1]);
+		ber_str2bv( argv[1], 0, 1, &ti->ti_compare );
 
 		/* proc for modify */
 	} else if (strcasecmp (argv[0], "modify") == 0) {
@@ -130,7 +129,7 @@ tcl_back_db_config (
 				fname, lineno, 0);
 			return (1);
 		}
-		ti->ti_modify = (char *) ch_strdup (argv[1]);
+		ber_str2bv( argv[1], 0, 1, &ti->ti_modify );
 
 		/* proc for modrdn */
 	} else if (strcasecmp (argv[0], "modrdn") == 0) {
@@ -140,7 +139,7 @@ tcl_back_db_config (
 				fname, lineno, 0);
 			return (1);
 		}
-		ti->ti_modrdn = (char *) ch_strdup (argv[1]);
+		ber_str2bv( argv[1], 0, 1, &ti->ti_modrdn );
 
 		/* proc for add */
 	} else if (strcasecmp (argv[0], "add") == 0) {
@@ -150,7 +149,7 @@ tcl_back_db_config (
 				fname, lineno, 0);
 			return (1);
 		}
-		ti->ti_add = (char *) ch_strdup (argv[1]);
+		ber_str2bv( argv[1], 0, 1, &ti->ti_add );
 
 		/* proc for delete */
 	} else if (strcasecmp (argv[0], "delete") == 0) {
@@ -160,7 +159,7 @@ tcl_back_db_config (
 				fname, lineno, 0);
 			return (1);
 		}
-		ti->ti_delete = (char *) ch_strdup (argv[1]);
+		ber_str2bv( argv[1], 0, 1, &ti->ti_delete );
 
 		/* proc for abandon */
 	} else if (strcasecmp (argv[0], "abandon") == 0) {
@@ -170,7 +169,7 @@ tcl_back_db_config (
 				fname, lineno, 0);
 			return (1);
 		}
-		ti->ti_search = (char *) ch_strdup (argv[1]);
+		ber_str2bv( argv[1], 0, 1, &ti->ti_abandon );
 
 	} else {
 		Debug (LDAP_DEBUG_CONFIG,
diff --git a/servers/slapd/back-tcl/tcl_delete.c b/servers/slapd/back-tcl/tcl_delete.c
index 87c7ed1dba..fe48fb188f 100644
--- a/servers/slapd/back-tcl/tcl_delete.c
+++ b/servers/slapd/back-tcl/tcl_delete.c
@@ -16,32 +16,38 @@
 #include "slap.h"
 #include "tcl_back.h"
 
+int
 tcl_back_delete (
 	Backend * be,
 	Connection * conn,
 	Operation * op,
-	const char *dn,
-	const char *ndn
+	struct berval *dn,
+	struct berval *ndn
 )
 {
-	char *command, *suf_tcl, *results;
-	int i, code, err = 0;
+	char *command, *results;
+	struct berval suf_tcl;
+	int code, err = 0;
 	struct tclinfo *ti = (struct tclinfo *) be->be_private;
 
-	if (ti->ti_delete == NULL) {
+	if (ti->ti_delete.bv_len == 0) {
 		send_ldap_result (conn, op, LDAP_UNWILLING_TO_PERFORM, NULL,
 			"delete not implemented", NULL, NULL );
 		return (-1);
 	}
 
-	for (i = 0; be->be_suffix[i] != NULL; i++);
-	suf_tcl = Tcl_Merge (i, be->be_suffix);
+	if (tcl_merge_bvlist (be->be_suffix, &suf_tcl) == NULL) {
+		send_ldap_result (conn, op, LDAP_OPERATIONS_ERROR, NULL,
+			NULL, NULL, NULL );
+		return (-1);
+	}
 
-	command = (char *) ch_malloc (strlen (ti->ti_delete) + strlen (suf_tcl)
-		+ strlen (dn) + 64);
+	command = (char *) ch_malloc (ti->ti_delete.bv_len + suf_tcl.bv_len
+		+ dn->bv_len + 64);
 	sprintf (command, "%s DELETE {%ld} {%s} {%s}",
-		ti->ti_delete, op->o_msgid, suf_tcl, dn);
-	Tcl_Free (suf_tcl);
+		ti->ti_delete.bv_val, (long) op->o_msgid, suf_tcl.bv_val, 
+		dn->bv_val);
+	Tcl_Free (suf_tcl.bv_val);
 
 	ldap_pvt_thread_mutex_lock (&tcl_interpreter_mutex);
 	code = Tcl_GlobalEval (ti->ti_ii->interp, command);
diff --git a/servers/slapd/back-tcl/tcl_init.c b/servers/slapd/back-tcl/tcl_init.c
index b35f0f750f..2133b6781a 100644
--- a/servers/slapd/back-tcl/tcl_init.c
+++ b/servers/slapd/back-tcl/tcl_init.c
@@ -111,19 +111,39 @@ tcl_back_db_init (
 
 	ti = (struct tclinfo *) ch_calloc (1, sizeof (struct tclinfo));
 
+	ti->ti_script_path.bv_len = 0;
+	ti->ti_script_path.bv_val = NULL;
+
 	/*
 	 * For some reason this causes problems
 	 * specifically set to NULL
 	 */
-	ti->ti_bind = NULL;
-	ti->ti_unbind = NULL;
-	ti->ti_search = NULL;
-	ti->ti_compare = NULL;
-	ti->ti_modify = NULL;
-	ti->ti_modrdn = NULL;
-	ti->ti_add = NULL;
-	ti->ti_delete = NULL;
-	ti->ti_abandon = NULL;
+	ti->ti_bind.bv_len = 0;
+	ti->ti_bind.bv_val = NULL;
+
+	ti->ti_unbind.bv_len = 0;
+	ti->ti_unbind.bv_val = NULL;
+
+	ti->ti_search.bv_len = 0;
+	ti->ti_search.bv_val = NULL;
+
+	ti->ti_compare.bv_len = 0;
+	ti->ti_compare.bv_val = NULL;
+
+	ti->ti_modify.bv_len = 0;
+	ti->ti_modify.bv_val = NULL;
+
+	ti->ti_modrdn.bv_len = 0;
+	ti->ti_modrdn.bv_val = NULL;
+
+	ti->ti_add.bv_len = 0;
+	ti->ti_add.bv_val = NULL;
+
+	ti->ti_delete.bv_len = 0;
+	ti->ti_delete.bv_val = NULL;
+
+	ti->ti_abandon.bv_len = 0;
+	ti->ti_abandon.bv_val = NULL;
 
 	be->be_private = ti;
 
@@ -146,9 +166,9 @@ tcl_back_db_open (
 	ti->ti_ii->count++;
 
 	/* now let's (try to) load the script */
-	readtclscript (ti->script_path, ti->ti_ii->interp);
+	readtclscript (ti->ti_script_path.bv_val, ti->ti_ii->interp);
 
-	/* Intall the debug command */
+	/* install the debug command */
 	Tcl_CreateCommand (ti->ti_ii->interp, "ldap:debug", &tcl_ldap_debug,
 		NULL, NULL);
 
diff --git a/servers/slapd/back-tcl/tcl_modify.c b/servers/slapd/back-tcl/tcl_modify.c
index 00157bf3a1..a140bc3153 100644
--- a/servers/slapd/back-tcl/tcl_modify.c
+++ b/servers/slapd/back-tcl/tcl_modify.c
@@ -21,77 +21,88 @@ tcl_back_modify (
 	Backend * be,
 	Connection * conn,
 	Operation * op,
-	const char *dn,
-	const char *ndn,
-	LDAPModList * modlist
+	struct berval *dn,
+	struct berval *ndn,
+	Modifications * modlist
 )
 {
-	char *command, *suf_tcl, *bp, *tcl_mods, *results;
+	char *command, *bp, *tcl_mods, *results;
+	struct berval suf_tcl;
 	int i, code, err = 0, len, bsize;
 	struct tclinfo *ti = (struct tclinfo *) be->be_private;
 
-	if (ti->ti_modify == NULL) {
+	if (ti->ti_modify.bv_len == 0) {
 		send_ldap_result (conn, op, LDAP_UNWILLING_TO_PERFORM, NULL,
 			"modify not implemented", NULL, NULL );
 		return (-1);
 	}
 
-	for (i = 0; be->be_suffix[i] != NULL; i++);
-	suf_tcl = Tcl_Merge (i, be->be_suffix);
+	if (tcl_merge_bvlist (be->be_suffix, &suf_tcl) == NULL) {
+		send_ldap_result (conn, op, LDAP_OPERATIONS_ERROR, NULL,
+			NULL, NULL, NULL );
+		return (-1);
+	}
 
 	tcl_mods = (char *) ch_malloc (BUFSIZ);
 	tcl_mods[0] = '\0';
 	bsize = BUFSIZ;
 	bp = tcl_mods;
 
-	for (; modlist != NULL; modlist = modlist->ml_next) {
-		LDAPMod *mods = &modlist->ml_mod;
-		char *op = NULL;
+	for (; modlist != NULL; modlist = modlist->sml_next) {
+		Modification *mods = &modlist->sml_mod;
+		const struct berval 
+			op_add = { sizeof("add") - 1, "add" },
+			op_delete = { sizeof("delete") - 1, "delete" },
+			op_replace = { sizeof("replace") - 1, "replace" },
+			*op = NULL;
 
-		switch (mods->mod_op & ~LDAP_MOD_BVALUES) {
+		switch (mods->sm_op & ~LDAP_MOD_BVALUES) {
 		case LDAP_MOD_ADD:
-			op = "add";
+			op = &op_add;
 			break;
 		case LDAP_MOD_DELETE:
-			op = "delete";
+			op = &op_delete;
 			break;
 		case LDAP_MOD_REPLACE:
-			op = "replace";
+			op = &op_replace;
 			break;
+		default:
+			assert(0);
 		}
 
-		len = strlen (mods->mod_type) + strlen (op) + 7;
+		len = mods->sm_type.bv_len + op->bv_len + 7;
 		while (bp + len - tcl_mods > bsize) {
 			bsize += BUFSIZ;
 			tcl_mods = (char *) ch_realloc (tcl_mods, bsize);
 		}
-		sprintf (bp, "{ {%s: %s} ", op, mods->mod_type);
+		sprintf (bp, "{ {%s: %s} ", op->bv_val, mods->sm_type.bv_val);
 		bp += len;
 		for (i = 0;
-			mods->mod_bvalues != NULL && mods->mod_bvalues[i]
+			mods->sm_bvalues != NULL && mods->sm_bvalues[i].bv_val
 			!= NULL;
 			i++) {
-			len = strlen (mods->mod_type) + strlen (
-				mods->mod_bvalues[i]->bv_val) + 5 +
-				(mods->mod_bvalues[i + 1] == NULL ? 2 : 0);
+			len = mods->sm_type.bv_len +
+				mods->sm_bvalues[i].bv_len + 5 +
+				(mods->sm_bvalues[i + 1].bv_val == NULL ? 2 : 0);
 			while (bp + len - tcl_mods > bsize) {
 				bsize += BUFSIZ;
 				tcl_mods = (char *) ch_realloc (tcl_mods, bsize);
 			}
-			sprintf (bp, "{%s: %s} %s", mods->mod_type,
-				mods->mod_bvalues[i]->bv_val,
-				mods->mod_bvalues[i + 1] ==
+			sprintf (bp, "{%s: %s} %s", mods->sm_type.bv_val,
+				mods->sm_bvalues[i].bv_val,
+				mods->sm_bvalues[i + 1].bv_val ==
 				NULL ? "} " : "");
 			bp += len;
 		}
 	}
 
-	command = (char *) ch_malloc (strlen (ti->ti_modify) + strlen (suf_tcl)
-		+ strlen (dn) + strlen (tcl_mods) + 64);
+	command = (char *) ch_malloc (ti->ti_modify.bv_len + suf_tcl.bv_len
+		+ dn->bv_len + strlen (tcl_mods) + 64);
 	/* This space is simply for aesthetics--\  */
 	sprintf (command, "%s MODIFY {%ld} {%s} {%s} { %s}",
-		ti->ti_modify, op->o_msgid, suf_tcl, dn, tcl_mods);
-	Tcl_Free (suf_tcl);
+		ti->ti_modify.bv_val, (long) op->o_msgid, suf_tcl.bv_val, 
+		dn->bv_val, tcl_mods);
+	Tcl_Free (suf_tcl.bv_val);
 	free (tcl_mods);
 
 	ldap_pvt_thread_mutex_lock (&tcl_interpreter_mutex);
diff --git a/servers/slapd/back-tcl/tcl_modrdn.c b/servers/slapd/back-tcl/tcl_modrdn.c
index 360b0d72c4..e3dc71731f 100644
--- a/servers/slapd/back-tcl/tcl_modrdn.c
+++ b/servers/slapd/back-tcl/tcl_modrdn.c
@@ -34,39 +34,48 @@ tcl_back_modrdn (
 	Backend * be,
 	Connection * conn,
 	Operation * op,
-	const char *dn,
-	const char *ndn,
-	const char *newrdn,
+	struct berval *dn,
+	struct berval *ndn,
+	struct berval *newrdn,
+	struct berval *nnewrdn,
 	int deleteoldrdn,
-	const char *newSuperior
+	struct berval *newSuperior,
+	struct berval *nnewSuperior
 )
 {
-	char *command, *suf_tcl, *results;
-	int i, code, err = 0;
+	char *command, *results;
+	struct berval suf_tcl;
+	int code, err = 0;
 	struct tclinfo *ti = (struct tclinfo *) be->be_private;
 
-	if (ti->ti_modrdn == NULL) {
+	if (ti->ti_modrdn.bv_len == 0) {
 		send_ldap_result (conn, op, LDAP_UNWILLING_TO_PERFORM, NULL,
 			"modrdn not implemented", NULL, NULL );
 		return (-1);
 	}
 
-	for (i = 0; be->be_suffix[i] != NULL; i++);
-	suf_tcl = Tcl_Merge (i, be->be_suffix);
+	if (tcl_merge_bvlist (be->be_suffix, &suf_tcl) == NULL) {
+		send_ldap_result (conn, op, LDAP_OPERATIONS_ERROR, NULL,
+			NULL, NULL, NULL );
+		return (-1);
+	}
 
-	command = (char *) ch_malloc (strlen (ti->ti_modrdn) + strlen (suf_tcl)
-		+ strlen (dn) + strlen (newrdn)
-		+ (newSuperior ? strlen(newSuperior) : 0) + 64);
+	command = (char *) ch_malloc (ti->ti_modrdn.bv_len + suf_tcl.bv_len
+		+ dn->bv_len + newrdn->bv_len
+		+ (newSuperior ? newSuperior->bv_len : 0) + 64);
 	if ( newSuperior ) {
 		sprintf (command, "%s MODRDN {%ld} {%s} {%s} {%s} %d {%s}",
-			 ti->ti_add, op->o_msgid, suf_tcl, dn, newrdn,
-			 deleteoldrdn ? 1 : 0, newSuperior );
+			 ti->ti_modrdn.bv_val, (long) op->o_msgid, 
+			 suf_tcl.bv_val, dn->bv_val,
+			 newrdn->bv_val, deleteoldrdn ? 1 : 0, 
+			 newSuperior->bv_val );
 	} else {
 		sprintf (command, "%s MODRDN {%ld} {%s} {%s} {%s} %d",
-			 ti->ti_add, op->o_msgid, suf_tcl, dn, newrdn,
-			 deleteoldrdn ? 1 : 0 );
+			 ti->ti_modrdn.bv_val, (long) op->o_msgid, 
+			 suf_tcl.bv_val, dn->bv_val,
+			 newrdn->bv_val, deleteoldrdn ? 1 : 0 );
 	}	
-	Tcl_Free (suf_tcl);
+	Tcl_Free (suf_tcl.bv_val);
 
 	ldap_pvt_thread_mutex_lock (&tcl_interpreter_mutex);
 	code = Tcl_GlobalEval (ti->ti_ii->interp, command);
diff --git a/servers/slapd/back-tcl/tcl_search.c b/servers/slapd/back-tcl/tcl_search.c
index 0764900d85..b4c886e764 100644
--- a/servers/slapd/back-tcl/tcl_search.c
+++ b/servers/slapd/back-tcl/tcl_search.c
@@ -21,26 +21,25 @@ tcl_back_search (
 	Backend * be,
 	Connection * conn,
 	Operation * op,
-	const char *base,
-	const char *nbase,
+	struct berval *base,
+	struct berval *nbase,
 	int scope,
 	int deref,
 	int sizelimit,
 	int timelimit,
 	Filter * filter,
-	const char *filterstr,
+	struct berval *filterstr,
 	AttributeName *attrs,
 	int attrsonly
 )
 {
-	char *attrs_tcl = NULL, *suf_tcl, *results, *command;
+	char *attrs_tcl = NULL, *results, *command;
+	struct berval suf_tcl;
 	int i, err = 0, code;
 	struct tclinfo *ti = (struct tclinfo *) be->be_private;
-	char **sattrs = NULL;
-	Entry *e;
 	AttributeName *an;
 
-	if (ti->ti_search == NULL) {
+	if (ti->ti_search.bv_len == 0) {
 		send_ldap_result (conn, op, LDAP_UNWILLING_TO_PERFORM, NULL,
 			"search not implemented", NULL, NULL );
 		return (-1);
@@ -48,29 +47,32 @@ tcl_back_search (
 
 	for (i = 0, an = attrs; an && an->an_name.bv_val; an++, i++);
 	if (i > 0) {
-		sattrs = ch_malloc( (i+1) * sizeof(char *));
+		char *sattrs[i+1];
+
 		for (i = 0, an = attrs; an->an_name.bv_val; an++, i++)
 			sattrs[i] = an->an_name.bv_val;
 		sattrs[i] = NULL;
 		attrs_tcl = Tcl_Merge (i, sattrs);
-		free(sattrs);
 	}
 
-	for (i = 0; be->be_suffix[i] != NULL; i++);
-	suf_tcl = Tcl_Merge (i, be->be_suffix);
+	if (tcl_merge_bvlist (be->be_suffix, &suf_tcl) == NULL) {
+		Tcl_Free (attrs_tcl);
+		send_ldap_result (conn, op, LDAP_OPERATIONS_ERROR, NULL,
+			NULL, NULL, NULL );
+		return (-1);
+	}
 
-	command = (char *) ch_malloc (strlen (ti->ti_search) + strlen (suf_tcl)
-		+ strlen (base) + 40 + strlen (filterstr) + (attrs_tcl ==
-			NULL ? 5
-			: strlen (attrs_tcl)) + 72);
+	command = (char *) ch_malloc (ti->ti_search.bv_len + suf_tcl.bv_len
+		+ base->bv_len + 40 + filterstr->bv_len + 
+		(attrs_tcl == NULL ? 5 : strlen (attrs_tcl)) + 72);
 	sprintf (command,
 		"%s SEARCH {%ld} {%s} {%s} {%d} {%d} {%d} {%d} {%s} {%d} {%s}",
-		ti->ti_search, op->o_msgid, suf_tcl, base, scope, deref,
-		sizelimit, timelimit, filterstr, attrsonly ? 1 : 0,
-		attrs_tcl ==
-		NULL ? "{all}" : attrs_tcl);
+		ti->ti_search.bv_val, (long) op->o_msgid, suf_tcl.bv_val, 
+		base->bv_val, scope, deref,
+		sizelimit, timelimit, filterstr->bv_val, attrsonly ? 1 : 0,
+		attrs_tcl == NULL ? "{all}" : attrs_tcl);
 	Tcl_Free (attrs_tcl);
-	Tcl_Free (suf_tcl);
+	Tcl_Free (suf_tcl.bv_val);
 
 	ldap_pvt_thread_mutex_lock (&tcl_interpreter_mutex);
 	code = Tcl_GlobalEval (ti->ti_ii->interp, command);
diff --git a/servers/slapd/back-tcl/tcl_unbind.c b/servers/slapd/back-tcl/tcl_unbind.c
index a4f547751d..70ec08a7fa 100644
--- a/servers/slapd/back-tcl/tcl_unbind.c
+++ b/servers/slapd/back-tcl/tcl_unbind.c
@@ -23,23 +23,25 @@ tcl_back_unbind (
 	Operation * op
 )
 {
-	char *command, *suf_tcl, *results;
-	int i, code, err = 0;
+	char *command, *results;
+	struct berval suf_tcl;
+	int code, err = 0;
 	struct tclinfo *ti = (struct tclinfo *) be->be_private;
 
-	if (ti->ti_unbind == NULL) {
+	if (ti->ti_unbind.bv_len == 0) {
 		return (-1);
 	}
 
-	for (i = 0; be->be_suffix[i] != NULL; i++);
-	suf_tcl = Tcl_Merge (i, be->be_suffix);
+	if (tcl_merge_bvlist (be->be_suffix, &suf_tcl) == NULL) {
+		return (-1);
+	}
 
-	command = (char *) ch_malloc (strlen (ti->ti_unbind) + strlen (suf_tcl)
-		+ strlen (conn->c_dn ? conn->c_dn : "") + 64);
+	command = (char *) ch_malloc (ti->ti_unbind.bv_len + suf_tcl.bv_len
+		+ conn->c_dn.bv_len + 64);
 	sprintf (command, "%s UNBIND {%ld} {%s} {%s}",
-		ti->ti_unbind, op->o_msgid, suf_tcl, conn->c_dn ?
-		conn->c_dn : "");
-	Tcl_Free (suf_tcl);
+		ti->ti_unbind.bv_val, (long) op->o_msgid, suf_tcl.bv_val, 
+		conn->c_dn.bv_val ?  conn->c_dn.bv_val : "");
+	Tcl_Free (suf_tcl.bv_val);
 
 	ldap_pvt_thread_mutex_lock (&tcl_interpreter_mutex);
 	code = Tcl_GlobalEval (ti->ti_ii->interp, command);
diff --git a/servers/slapd/back-tcl/tcl_util.c b/servers/slapd/back-tcl/tcl_util.c
index 85f156aabb..f7cddf0204 100644
--- a/servers/slapd/back-tcl/tcl_util.c
+++ b/servers/slapd/back-tcl/tcl_util.c
@@ -188,3 +188,42 @@ readtclscript (
 		return;
 	}
 }
+
+
+struct berval *
+tcl_merge_bvlist(
+	struct berval **bvlist, struct berval *out)
+{
+	struct berval *ret = NULL;
+	int i;
+
+	if (bvlist == NULL)
+		return NULL;
+
+	if (out == NULL) {
+		ret = (struct berval *)ch_malloc(sizeof(struct berval));
+		if (ret == NULL) {
+			return NULL;
+		}
+	} else {
+		ret = out;
+	}
+
+	ret->bv_len = 0;
+	ret->bv_val = NULL;
+
+	for (i = 0; bvlist[i] != NULL; i++);
+
+	if (i) {
+		char *strlist[i + 1];
+		for (i = 0; bvlist[i] != NULL; i++) {
+			strlist[i] = bvlist[i]->bv_val;
+		}
+		strlist[i] = NULL;
+		ret->bv_val = Tcl_Merge(i, strlist);
+		ret->bv_len = ret->bv_val ? strlen(ret->bv_val) : 0;
+	}
+
+	return ret;
+}
+
diff --git a/servers/slapd/backend.c b/servers/slapd/backend.c
index 07be37e36e..b010528dde 100644
--- a/servers/slapd/backend.c
+++ b/servers/slapd/backend.c
@@ -44,6 +44,9 @@
 #if defined(SLAPD_MONITOR) && !defined(SLAPD_MONITOR_DYNAMIC)
 #include "back-monitor/external.h"
 #endif
+#if defined(SLAPD_NULL) && !defined(SLAPD_NULL_DYNAMIC)
+#include "back-null/external.h"
+#endif
 #if defined(SLAPD_PASSWD) && !defined(SLAPD_PASSWD_DYNAMIC)
 #include "back-passwd/external.h"
 #endif
@@ -82,6 +85,9 @@ static BackendInfo binfo[] = {
 #if defined(SLAPD_MONITOR) && !defined(SLAPD_MONITOR_DYNAMIC)
 	{"monitor",	monitor_back_initialize},
 #endif
+#if defined(SLAPD_NULL) && !defined(SLAPD_NULL_DYNAMIC)
+	{"null",	null_back_initialize},
+#endif
 #if defined(SLAPD_PASSWD) && !defined(SLAPD_PASSWD_DYNAMIC)
 	{"passwd",	passwd_back_initialize},
 #endif
diff --git a/servers/slapd/bind.c b/servers/slapd/bind.c
index 142bf0f7a9..b2b4d32b4a 100644
--- a/servers/slapd/bind.c
+++ b/servers/slapd/bind.c
@@ -191,7 +191,7 @@ do_bind(
 #endif
 	}
 
-	Statslog( LDAP_DEBUG_STATS, "conn=%ld op=%d BIND dn=\"%s\" method=%ld\n",
+	Statslog( LDAP_DEBUG_STATS, "conn=%lu op=%lu BIND dn=\"%s\" method=%ld\n",
 	    op->o_connid, op->o_opid, pdn.bv_val, (unsigned long) method, 0 );
 
 	if ( version < LDAP_VERSION_MIN || version > LDAP_VERSION_MAX ) {
diff --git a/servers/slapd/charray.c b/servers/slapd/charray.c
index 927d7e3ad9..e8c3dbc048 100644
--- a/servers/slapd/charray.c
+++ b/servers/slapd/charray.c
@@ -225,7 +225,7 @@ slap_strcopy(
 	if (!a || !b)
 		return a;
 	
-	while (*a++ = *b++) ;
+	while ((*a++ = *b++)) ;
 	return a-1;
 }
 
diff --git a/servers/slapd/compare.c b/servers/slapd/compare.c
index 87a88e4886..ead4af626e 100644
--- a/servers/slapd/compare.c
+++ b/servers/slapd/compare.c
@@ -155,7 +155,7 @@ do_compare(
 #endif
 
 		Statslog( LDAP_DEBUG_STATS,
-			"conn=%ld op=%d CMP dn=\"%s\" attr=\"%s\"\n",
+			"conn=%lu op=%lu CMP dn=\"%s\" attr=\"%s\"\n",
 			op->o_connid, op->o_opid, pdn.bv_val,
 			ava.aa_desc->ad_cname.bv_val, 0 );
 
@@ -183,7 +183,7 @@ do_compare(
 #endif
 
 		Statslog( LDAP_DEBUG_STATS,
-			"conn=%ld op=%d CMP dn=\"%s\" attr=\"%s\"\n",
+			"conn=%lu op=%lu CMP dn=\"%s\" attr=\"%s\"\n",
 			op->o_connid, op->o_opid, pdn.bv_val,
 			ava.aa_desc->ad_cname.bv_val, 0 );
 
@@ -258,7 +258,7 @@ do_compare(
 	    pdn.bv_val, ava.aa_desc->ad_cname.bv_val, ava.aa_value.bv_val );
 #endif
 
-	Statslog( LDAP_DEBUG_STATS, "conn=%ld op=%d CMP dn=\"%s\" attr=\"%s\"\n",
+	Statslog( LDAP_DEBUG_STATS, "conn=%lu op=%lu CMP dn=\"%s\" attr=\"%s\"\n",
 	    op->o_connid, op->o_opid, pdn.bv_val,
 		ava.aa_desc->ad_cname.bv_val, 0 );
 
diff --git a/servers/slapd/delete.c b/servers/slapd/delete.c
index 5f808303ad..38324be6ea 100644
--- a/servers/slapd/delete.c
+++ b/servers/slapd/delete.c
@@ -118,7 +118,7 @@ do_delete(
 #endif
 	}
 
-	Statslog( LDAP_DEBUG_STATS, "conn=%ld op=%d DEL dn=\"%s\"\n",
+	Statslog( LDAP_DEBUG_STATS, "conn=%lu op=%lu DEL dn=\"%s\"\n",
 		op->o_connid, op->o_opid, pdn.bv_val, 0, 0 );
 
 	manageDSAit = get_manageDSAit( op );
diff --git a/servers/slapd/entry.c b/servers/slapd/entry.c
index 8094a09e8b..48afbf5d9d 100644
--- a/servers/slapd/entry.c
+++ b/servers/slapd/entry.c
@@ -589,7 +589,7 @@ int entry_decode(struct berval *bv, Entry **e)
 	bptr = (BerVarray)x->e_attrs;
 	a = NULL;
 
-	while (i = entry_getlen(&ptr)) {
+	while ((i = entry_getlen(&ptr))) {
 		struct berval bv;
 		bv.bv_len = i;
 		bv.bv_val = ptr;
diff --git a/servers/slapd/limits.c b/servers/slapd/limits.c
index d9088ca8ac..01011a7250 100644
--- a/servers/slapd/limits.c
+++ b/servers/slapd/limits.c
@@ -55,11 +55,11 @@ get_limits(
 				break;
 			}
 
-			d = ndn->bv_len - lm[0]->lm_dn_pat.bv_len;
 			/* ndn shorter than dn_pat */
-			if ( d < 0 ) {
+			if ( ndn->bv_len < lm[0]->lm_dn_pat.bv_len ) {
 				break;
 			}
+			d = ndn->bv_len - lm[0]->lm_dn_pat.bv_len;
 
 			/* allow exact match for SUBTREE only */
 			if ( d == 0 ) {
diff --git a/servers/slapd/modify.c b/servers/slapd/modify.c
index 62a6a6da30..6bb923671b 100644
--- a/servers/slapd/modify.c
+++ b/servers/slapd/modify.c
@@ -278,7 +278,7 @@ do_modify(
 	}
 #endif
 
-	Statslog( LDAP_DEBUG_STATS, "conn=%ld op=%d MOD dn=\"%s\"\n",
+	Statslog( LDAP_DEBUG_STATS, "conn=%lu op=%lu MOD dn=\"%s\"\n",
 	    op->o_connid, op->o_opid, dn.bv_val, 0, 0 );
 
 	manageDSAit = get_manageDSAit( op );
diff --git a/servers/slapd/modrdn.c b/servers/slapd/modrdn.c
index 529cea45d9..eca68cace5 100644
--- a/servers/slapd/modrdn.c
+++ b/servers/slapd/modrdn.c
@@ -270,7 +270,7 @@ do_modrdn(
 		}
 	}
 
-	Statslog( LDAP_DEBUG_STATS, "conn=%ld op=%d MODRDN dn=\"%s\"\n",
+	Statslog( LDAP_DEBUG_STATS, "conn=%lu op=%lu MODRDN dn=\"%s\"\n",
 	    op->o_connid, op->o_opid, pdn.bv_val, 0, 0 );
 
 	manageDSAit = get_manageDSAit( op );
diff --git a/servers/slapd/schema_init.c b/servers/slapd/schema_init.c
index 5e6d7f94eb..8695cd8fe6 100644
--- a/servers/slapd/schema_init.c
+++ b/servers/slapd/schema_init.c
@@ -1844,11 +1844,12 @@ integerNormalize(
 	}
 	else {
 		normalized->bv_len = len+negative;
-		normalized->bv_val = ch_malloc( normalized->bv_len );
+		normalized->bv_val = ch_malloc( normalized->bv_len + 1 );
 		if( negative ) {
 			normalized->bv_val[0] = '-';
 		}
 		AC_MEMCPY( normalized->bv_val + negative, p, len );
+		normalized->bv_val[len+negative] = '\0';
 	}
 
 	return LDAP_SUCCESS;
@@ -1865,19 +1866,45 @@ static int integerIndexer(
 	BerVarray *keysp )
 {
 	int i;
+	size_t slen, mlen;
 	BerVarray keys;
-
-	/* we should have at least one value at this point */
-	assert( values != NULL && values[0].bv_val != NULL );
+	HASH_CONTEXT   HASHcontext;
+	unsigned char	HASHdigest[HASH_BYTES];
+	struct berval digest;
+	digest.bv_val = HASHdigest;
+	digest.bv_len = sizeof(HASHdigest);
 
 	for( i=0; values[i].bv_val != NULL; i++ ) {
-		/* empty -- just count them */
+		/* empty - just count them */
 	}
 
+	/* we should have at least one value at this point */
+	assert( i > 0 );
+
 	keys = ch_malloc( sizeof( struct berval ) * (i+1) );
 
+	slen = syntax->ssyn_oidlen;
+	mlen = mr->smr_oidlen;
+
 	for( i=0; values[i].bv_val != NULL; i++ ) {
-		integerNormalize( syntax, &values[i], &keys[i] );
+		struct berval norm;
+		integerNormalize( syntax, &values[i], &norm );
+
+		HASH_Init( &HASHcontext );
+		if( prefix != NULL && prefix->bv_len > 0 ) {
+			HASH_Update( &HASHcontext,
+				prefix->bv_val, prefix->bv_len );
+		}
+		HASH_Update( &HASHcontext,
+			syntax->ssyn_oid, slen );
+		HASH_Update( &HASHcontext,
+			mr->smr_oid, mlen );
+		HASH_Update( &HASHcontext,
+			norm.bv_val, norm.bv_len );
+		HASH_Final( HASHdigest, &HASHcontext );
+
+		ber_dupbv( &keys[i], &digest );
+		ch_free( norm.bv_val );
 	}
 
 	keys[i].bv_val = NULL;
@@ -1895,13 +1922,40 @@ static int integerFilter(
 	void * assertValue,
 	BerVarray *keysp )
 {
+	size_t slen, mlen;
 	BerVarray keys;
+	HASH_CONTEXT   HASHcontext;
+	unsigned char	HASHdigest[HASH_BYTES];
+	struct berval norm;
+	struct berval digest;
+	digest.bv_val = HASHdigest;
+	digest.bv_len = sizeof(HASHdigest);
+
+	slen = syntax->ssyn_oidlen;
+	mlen = mr->smr_oidlen;
+
+	integerNormalize( syntax, assertValue, &norm );
 
 	keys = ch_malloc( sizeof( struct berval ) * 2 );
-	integerNormalize( syntax, assertValue, &keys[0] );
+
+	HASH_Init( &HASHcontext );
+	if( prefix != NULL && prefix->bv_len > 0 ) {
+		HASH_Update( &HASHcontext,
+			prefix->bv_val, prefix->bv_len );
+	}
+	HASH_Update( &HASHcontext,
+		syntax->ssyn_oid, slen );
+	HASH_Update( &HASHcontext,
+		mr->smr_oid, mlen );
+	HASH_Update( &HASHcontext,
+		norm.bv_val, norm.bv_len );
+	HASH_Final( HASHdigest, &HASHcontext );
+
+	ber_dupbv( &keys[0], &digest );
 	keys[1].bv_val = NULL;
-	*keysp = keys;
+	ch_free( norm.bv_val );
 
+	*keysp = keys;
 	return LDAP_SUCCESS;
 }
 
diff --git a/servers/slapd/search.c b/servers/slapd/search.c
index 6ba03faf3a..c4db3e52e6 100644
--- a/servers/slapd/search.c
+++ b/servers/slapd/search.c
@@ -212,7 +212,7 @@ do_search(
 #endif
 
 	Statslog( LDAP_DEBUG_STATS,
-	    "conn=%ld op=%d SRCH base=\"%s\" scope=%d filter=\"%s\"\n",
+	    "conn=%lu op=%lu SRCH base=\"%s\" scope=%d filter=\"%s\"\n",
 	    op->o_connid, op->o_opid, pbase.bv_val, scope, fstr.bv_val );
 
 	manageDSAit = get_manageDSAit( op );
diff --git a/servers/slapd/tools/slapadd.c b/servers/slapd/tools/slapadd.c
index d3ce99b9d2..ad18fe9c6b 100644
--- a/servers/slapd/tools/slapadd.c
+++ b/servers/slapd/tools/slapadd.c
@@ -115,7 +115,8 @@ main( int argc, char **argv )
 			if( sc == NULL ) {
 				struct berval vals[2];
 
-				int ret = structural_class( oc->a_vals, vals,
+				/* int ret = */ 
+					structural_class( oc->a_vals, vals,
 					NULL, &text, textbuf, textlen );
 
 				if( vals[0].bv_len == 0 ) {
diff --git a/servers/slapd/unbind.c b/servers/slapd/unbind.c
index 0ec5ce8641..40457cfe9a 100644
--- a/servers/slapd/unbind.c
+++ b/servers/slapd/unbind.c
@@ -47,7 +47,7 @@ do_unbind(
 	 *	UnBindRequest ::= NULL
 	 */
 
-	Statslog( LDAP_DEBUG_STATS, "conn=%ld op=%d UNBIND\n", op->o_connid,
+	Statslog( LDAP_DEBUG_STATS, "conn=%lu op=%lu UNBIND\n", op->o_connid,
 	    op->o_opid, 0, 0, 0 );
 
 	/* pass the unbind to all backends */
diff --git a/servers/slurpd/ldap_op.c b/servers/slurpd/ldap_op.c
index 1cff03c8aa..4d676fe452 100644
--- a/servers/slurpd/ldap_op.c
+++ b/servers/slurpd/ldap_op.c
@@ -223,7 +223,7 @@ op_ldap_modify(
     int		state;	/* This code is a simple-minded state machine */
     int		nvals;	/* Number of values we're modifying */
     int		nops;	/* Number of LDAPMod structs in ldmarr */
-    LDAPMod	*ldm, **ldmarr;
+    LDAPMod	*ldm = NULL, **ldmarr;
     int		i, len;
     char	*type, *value;
     int		rc = 0;
@@ -289,6 +289,8 @@ op_ldap_modify(
 		continue;
 	    }
 
+	    assert( ldm );
+
 	    /*
 	     * We should have an attribute: value pair here.
 	     * Construct the mod_bvalues part of the ldapmod struct.
@@ -369,7 +371,7 @@ op_ldap_modrdn(
 	int		lderr = 0;
     int		state = 0;
     int		drdnflag = -1;
-    char	*newrdn;
+    char	*newrdn = NULL;
 	char	*newsup = NULL;
 
     if ( re->re_mods == NULL ) {
@@ -462,6 +464,8 @@ op_ldap_modrdn(
     }
 #endif /* LDAP_DEBUG */
 
+    assert( newrdn );
+
     /* Do the modrdn */
     rc = ldap_rename2_s( ri->ri_ldp, re->re_dn, newrdn, newsup, drdnflag );
 
diff --git a/servers/slurpd/ri.c b/servers/slurpd/ri.c
index aa12a79c0f..a805060a98 100644
--- a/servers/slurpd/ri.c
+++ b/servers/slurpd/ri.c
@@ -48,7 +48,7 @@ Ri_process(
 )
 {
     Rq		*rq = sglob->rq;
-    Re		*re, *new_re;
+    Re		*re = NULL, *new_re = NULL;
     int		rc ;
     char	*errmsg;
 
-- 
GitLab